From 84a3db80b4fd66c6854b3135b5f69b61fd828e62 Mon Sep 17 00:00:00 2001 From: Jens-Heiner Rechtien Date: Mon, 18 Sep 2000 23:08:29 +0000 Subject: initial import --- sw/source/core/attr/calbck.cxx | 642 ++++ sw/source/core/attr/cellatr.cxx | 318 ++ sw/source/core/attr/format.cxx | 677 ++++ sw/source/core/attr/hints.cxx | 299 ++ sw/source/core/attr/makefile.mk | 101 + sw/source/core/attr/swatrset.cxx | 380 +++ sw/source/core/bastyp/bparr.cxx | 634 ++++ sw/source/core/bastyp/breakit.cxx | 109 + sw/source/core/bastyp/calc.cxx | 1841 +++++++++++ sw/source/core/bastyp/index.cxx | 772 +++++ sw/source/core/bastyp/init.cxx | 951 ++++++ sw/source/core/bastyp/makefile.mk | 111 + sw/source/core/bastyp/ring.cxx | 148 + sw/source/core/bastyp/swcache.cxx | 699 ++++ sw/source/core/bastyp/swrect.cxx | 303 ++ sw/source/core/bastyp/swregion.cxx | 293 ++ sw/source/core/bastyp/swtypes.cxx | 270 ++ sw/source/core/bastyp/tabcol.cxx | 127 + sw/source/core/crsr/bookmrk.cxx | 180 ++ sw/source/core/crsr/callnk.cxx | 302 ++ sw/source/core/crsr/callnk.hxx | 88 + sw/source/core/crsr/crbm.cxx | 281 ++ sw/source/core/crsr/crsrsh.cxx | 2831 ++++++++++++++++ sw/source/core/crsr/crstrvl.cxx | 1999 ++++++++++++ sw/source/core/crsr/crstrvl1.cxx | 122 + sw/source/core/crsr/findattr.cxx | 1463 +++++++++ sw/source/core/crsr/findcoll.cxx | 153 + sw/source/core/crsr/findfmt.cxx | 124 + sw/source/core/crsr/findtxt.cxx | 421 +++ sw/source/core/crsr/makefile.mk | 148 + sw/source/core/crsr/pam.cxx | 993 ++++++ sw/source/core/crsr/paminit.cxx | 168 + sw/source/core/crsr/swcrsr.cxx | 1736 ++++++++++ sw/source/core/crsr/trvlcol.cxx | 168 + sw/source/core/crsr/trvlfnfl.cxx | 521 +++ sw/source/core/crsr/trvlreg.cxx | 345 ++ sw/source/core/crsr/trvltbl.cxx | 770 +++++ sw/source/core/crsr/unocrsr.cxx | 290 ++ sw/source/core/crsr/viscrs.cxx | 1078 +++++++ sw/source/core/doc/acmplwrd.cxx | 303 ++ sw/source/core/doc/doc.cxx | 1312 ++++++++ sw/source/core/doc/docbasic.cxx | 314 ++ sw/source/core/doc/docbm.cxx | 1114 +++++++ sw/source/core/doc/docchart.cxx | 489 +++ sw/source/core/doc/doccomp.cxx | 1772 +++++++++++ sw/source/core/doc/doccorr.cxx | 578 ++++ sw/source/core/doc/docdde.cxx | 525 +++ sw/source/core/doc/docdesc.cxx | 1016 ++++++ sw/source/core/doc/docdraw.cxx | 671 ++++ sw/source/core/doc/docedt.cxx | 2252 +++++++++++++ sw/source/core/doc/docfld.cxx | 2880 +++++++++++++++++ sw/source/core/doc/docfly.cxx | 1038 ++++++ sw/source/core/doc/docfmt.cxx | 2167 +++++++++++++ sw/source/core/doc/docftn.cxx | 555 ++++ sw/source/core/doc/docglbl.cxx | 566 ++++ sw/source/core/doc/docglos.cxx | 189 ++ sw/source/core/doc/doclay.cxx | 1924 +++++++++++ sw/source/core/doc/docnew.cxx | 822 +++++ sw/source/core/doc/docnum.cxx | 2187 +++++++++++++ sw/source/core/doc/docredln.cxx | 3218 +++++++++++++++++++ sw/source/core/doc/docsort.cxx | 1060 ++++++ sw/source/core/doc/docstat.cxx | 105 + sw/source/core/doc/doctxm.cxx | 2352 ++++++++++++++ sw/source/core/doc/extinput.cxx | 286 ++ sw/source/core/doc/fmtcol.cxx | 457 +++ sw/source/core/doc/ftnidx.cxx | 480 +++ sw/source/core/doc/gctable.cxx | 521 +++ sw/source/core/doc/htmltbl.cxx | 1943 +++++++++++ sw/source/core/doc/lineinfo.cxx | 182 ++ sw/source/core/doc/makefile.mk | 176 + sw/source/core/doc/notxtfrm.cxx | 1691 ++++++++++ sw/source/core/doc/number.cxx | 1018 ++++++ sw/source/core/doc/poolfmt.cxx | 2767 ++++++++++++++++ sw/source/core/doc/sortopt.cxx | 134 + sw/source/core/doc/swserv.cxx | 419 +++ sw/source/core/doc/tblafmt.cxx | 1055 ++++++ sw/source/core/doc/tblcpy.cxx | 630 ++++ sw/source/core/doc/tblrwcl.cxx | 4508 ++++++++++++++++++++++++++ sw/source/core/doc/visiturl.cxx | 201 ++ sw/source/core/docnode/makefile.mk | 120 + sw/source/core/docnode/ndcopy.cxx | 1260 ++++++++ sw/source/core/docnode/ndindex.cxx | 203 ++ sw/source/core/docnode/ndnotxt.cxx | 184 ++ sw/source/core/docnode/ndnum.cxx | 390 +++ sw/source/core/docnode/ndsect.cxx | 1378 ++++++++ sw/source/core/docnode/ndtbl.cxx | 3824 ++++++++++++++++++++++ sw/source/core/docnode/ndtbl1.cxx | 1478 +++++++++ sw/source/core/docnode/node.cxx | 1840 +++++++++++ sw/source/core/docnode/node2lay.cxx | 422 +++ sw/source/core/docnode/nodes.cxx | 2604 +++++++++++++++ sw/source/core/docnode/section.cxx | 1559 +++++++++ sw/source/core/docnode/swbaslnk.cxx | 850 +++++ sw/source/core/draw/dcontact.cxx | 774 +++++ sw/source/core/draw/dflyobj.cxx | 707 ++++ sw/source/core/draw/dobjfac.cxx | 100 + sw/source/core/draw/dpage.cxx | 375 +++ sw/source/core/draw/drawdoc.cxx | 279 ++ sw/source/core/draw/dview.cxx | 688 ++++ sw/source/core/draw/makefile.mk | 102 + sw/source/core/edit/acorrect.cxx | 628 ++++ sw/source/core/edit/autofmt.cxx | 2770 ++++++++++++++++ sw/source/core/edit/edatmisc.cxx | 234 ++ sw/source/core/edit/edattr.cxx | 444 +++ sw/source/core/edit/eddel.cxx | 466 +++ sw/source/core/edit/edfcol.cxx | 194 ++ sw/source/core/edit/edfld.cxx | 739 +++++ sw/source/core/edit/edfmt.cxx | 277 ++ sw/source/core/edit/edglbldc.cxx | 470 +++ sw/source/core/edit/edglss.cxx | 442 +++ sw/source/core/edit/editsh.cxx | 1111 +++++++ sw/source/core/edit/edlingu.cxx | 961 ++++++ sw/source/core/edit/ednumber.cxx | 714 +++++ sw/source/core/edit/edredln.cxx | 228 ++ sw/source/core/edit/edsect.cxx | 501 +++ sw/source/core/edit/edtab.cxx | 713 +++++ sw/source/core/edit/edtox.cxx | 547 ++++ sw/source/core/edit/edundo.cxx | 312 ++ sw/source/core/edit/edws.cxx | 443 +++ sw/source/core/edit/makefile.mk | 145 + sw/source/core/except/dbgloop.cxx | 201 ++ sw/source/core/except/errhdl.cxx | 196 ++ sw/source/core/except/makefile.mk | 97 + sw/source/core/fields/authfld.cxx | 714 +++++ sw/source/core/fields/cellfml.cxx | 1305 ++++++++ sw/source/core/fields/chpfld.cxx | 297 ++ sw/source/core/fields/dbfld.cxx | 1112 +++++++ sw/source/core/fields/ddefld.cxx | 494 +++ sw/source/core/fields/ddetbl.cxx | 240 ++ sw/source/core/fields/docufld.cxx | 2485 +++++++++++++++ sw/source/core/fields/expfld.cxx | 1309 ++++++++ sw/source/core/fields/fldbas.cxx | 1024 ++++++ sw/source/core/fields/flddat.cxx | 364 +++ sw/source/core/fields/fldlst.cxx | 278 ++ sw/source/core/fields/macrofld.cxx | 226 ++ sw/source/core/fields/makefile.mk | 125 + sw/source/core/fields/reffld.cxx | 898 ++++++ sw/source/core/fields/scrptfld.cxx | 182 ++ sw/source/core/fields/tblcalc.cxx | 280 ++ sw/source/core/fields/usrfld.cxx | 451 +++ sw/source/core/frmedt/fecopy.cxx | 1431 +++++++++ sw/source/core/frmedt/fedesc.cxx | 327 ++ sw/source/core/frmedt/fefly1.cxx | 1869 +++++++++++ sw/source/core/frmedt/feflyole.cxx | 194 ++ sw/source/core/frmedt/feshview.cxx | 2559 +++++++++++++++ sw/source/core/frmedt/fetab.cxx | 1659 ++++++++++ sw/source/core/frmedt/fews.cxx | 1000 ++++++ sw/source/core/frmedt/makefile.mk | 112 + sw/source/core/frmedt/tblsel.cxx | 2593 +++++++++++++++ sw/source/core/graphic/grfatr.cxx | 417 +++ sw/source/core/graphic/makefile.mk | 105 + sw/source/core/graphic/ndgrf.cxx | 2061 ++++++++++++ sw/source/core/inc/acorrect.hxx | 157 + sw/source/core/inc/blink.hxx | 126 + sw/source/core/inc/bodyfrm.hxx | 89 + sw/source/core/inc/cellfrm.hxx | 96 + sw/source/core/inc/cntfrm.hxx | 196 ++ sw/source/core/inc/colfrm.hxx | 83 + sw/source/core/inc/dbg_lay.hxx | 144 + sw/source/core/inc/dbgloop.hxx | 113 + sw/source/core/inc/dflyobj.hxx | 156 + sw/source/core/inc/docfld.hxx | 221 ++ sw/source/core/inc/docsort.hxx | 201 ++ sw/source/core/inc/doctxm.hxx | 176 + sw/source/core/inc/drawdev.hxx | 174 + sw/source/core/inc/drawfont.hxx | 348 ++ sw/source/core/inc/dview.hxx | 119 + sw/source/core/inc/flowfrm.hxx | 216 ++ sw/source/core/inc/flyfrm.hxx | 248 ++ sw/source/core/inc/flyfrms.hxx | 207 ++ sw/source/core/inc/fntcache.hxx | 194 ++ sw/source/core/inc/frame.hxx | 919 ++++++ sw/source/core/inc/frminf.hxx | 119 + sw/source/core/inc/frmtool.hxx | 457 +++ sw/source/core/inc/ftnboss.hxx | 158 + sw/source/core/inc/ftnfrm.hxx | 156 + sw/source/core/inc/hffrm.hxx | 102 + sw/source/core/inc/layact.hxx | 267 ++ sw/source/core/inc/layfrm.hxx | 208 ++ sw/source/core/inc/layouter.hxx | 98 + sw/source/core/inc/makefile.mk | 61 + sw/source/core/inc/mvsave.hxx | 250 ++ sw/source/core/inc/node2lay.hxx | 110 + sw/source/core/inc/noteurl.hxx | 116 + sw/source/core/inc/notxtfrm.hxx | 119 + sw/source/core/inc/pagefrm.hxx | 327 ++ sw/source/core/inc/pamtyp.hxx | 140 + sw/source/core/inc/ptqueue.hxx | 96 + sw/source/core/inc/rootfrm.hxx | 342 ++ sw/source/core/inc/rowfrm.hxx | 112 + sw/source/core/inc/rvp_mark.hxx | 77 + sw/source/core/inc/scrrect.hxx | 158 + sw/source/core/inc/sectfrm.hxx | 197 ++ sw/source/core/inc/swblocks.hxx | 260 ++ sw/source/core/inc/swcache.hxx | 336 ++ sw/source/core/inc/swfntcch.hxx | 133 + sw/source/core/inc/swfont.hxx | 850 +++++ sw/source/core/inc/tabfrm.hxx | 190 ++ sw/source/core/inc/tblrwcl.hxx | 263 ++ sw/source/core/inc/txmsrt.hxx | 243 ++ sw/source/core/inc/txtfrm.hxx | 639 ++++ sw/source/core/inc/txttypes.hxx | 75 + sw/source/core/inc/unoclbck.hxx | 85 + sw/source/core/inc/viewimp.hxx | 269 ++ sw/source/core/inc/visiturl.hxx | 85 + sw/source/core/inc/wrong.hxx | 121 + sw/source/core/layout/atrfrm.cxx | 2519 +++++++++++++++ sw/source/core/layout/calcmove.cxx | 1551 +++++++++ sw/source/core/layout/colfrm.cxx | 469 +++ sw/source/core/layout/dbg_lay.cxx | 813 +++++ sw/source/core/layout/findfrm.cxx | 1116 +++++++ sw/source/core/layout/flowfrm.cxx | 1837 +++++++++++ sw/source/core/layout/fly.cxx | 2202 +++++++++++++ sw/source/core/layout/flycnt.cxx | 1970 ++++++++++++ sw/source/core/layout/flyincnt.cxx | 369 +++ sw/source/core/layout/flylay.cxx | 997 ++++++ sw/source/core/layout/flypos.cxx | 147 + sw/source/core/layout/frmtool.cxx | 3171 ++++++++++++++++++ sw/source/core/layout/ftnfrm.cxx | 2931 +++++++++++++++++ sw/source/core/layout/hffrm.cxx | 438 +++ sw/source/core/layout/layact.cxx | 2741 ++++++++++++++++ sw/source/core/layout/layouter.cxx | 345 ++ sw/source/core/layout/makefile.mk | 175 + sw/source/core/layout/newfrm.cxx | 441 +++ sw/source/core/layout/pagechg.cxx | 1955 ++++++++++++ sw/source/core/layout/pagedesc.cxx | 482 +++ sw/source/core/layout/paintfrm.cxx | 3904 +++++++++++++++++++++++ sw/source/core/layout/sectfrm.cxx | 2483 +++++++++++++++ sw/source/core/layout/ssfrm.cxx | 345 ++ sw/source/core/layout/tabfrm.cxx | 2573 +++++++++++++++ sw/source/core/layout/trvlfrm.cxx | 2075 ++++++++++++ sw/source/core/layout/unusedf.cxx | 122 + sw/source/core/layout/virtoutp.cxx | 247 ++ sw/source/core/layout/virtoutp.hxx | 108 + sw/source/core/layout/wsfrm.cxx | 3113 ++++++++++++++++++ sw/source/core/makefile.mk | 326 ++ sw/source/core/ole/makefile.mk | 93 + sw/source/core/ole/ndole.cxx | 644 ++++ sw/source/core/para/makefile.mk | 93 + sw/source/core/para/paratr.cxx | 349 ++ sw/source/core/sw3io/makefile.mk | 136 + sw/source/core/sw3io/swacorr.cxx | 145 + sw/source/core/swg/makefile.mk | 124 + sw/source/core/swg/swblocks.cxx | 955 ++++++ sw/source/core/text/blink.cxx | 205 ++ sw/source/core/text/frmcrsr.cxx | 1240 +++++++ sw/source/core/text/frmform.cxx | 1919 +++++++++++ sw/source/core/text/frminf.cxx | 409 +++ sw/source/core/text/frmpaint.cxx | 738 +++++ sw/source/core/text/guess.cxx | 492 +++ sw/source/core/text/guess.hxx | 123 + sw/source/core/text/inftxt.cxx | 1176 +++++++ sw/source/core/text/inftxt.hxx | 807 +++++ sw/source/core/text/itradj.cxx | 578 ++++ sw/source/core/text/itratr.cxx | 833 +++++ sw/source/core/text/itratr.hxx | 149 + sw/source/core/text/itrcrsr.cxx | 923 ++++++ sw/source/core/text/itrform2.cxx | 1491 +++++++++ sw/source/core/text/itrform2.hxx | 236 ++ sw/source/core/text/itrpaint.cxx | 548 ++++ sw/source/core/text/itrpaint.hxx | 97 + sw/source/core/text/itrtxt.cxx | 489 +++ sw/source/core/text/itrtxt.hxx | 363 +++ sw/source/core/text/makefile.mk | 185 ++ sw/source/core/text/noteurl.cxx | 129 + sw/source/core/text/pordrop.hxx | 122 + sw/source/core/text/porexp.cxx | 332 ++ sw/source/core/text/porexp.hxx | 131 + sw/source/core/text/porfld.cxx | 854 +++++ sw/source/core/text/porfld.hxx | 240 ++ sw/source/core/text/porfly.cxx | 585 ++++ sw/source/core/text/porfly.hxx | 140 + sw/source/core/text/porftn.hxx | 150 + sw/source/core/text/porglue.cxx | 363 +++ sw/source/core/text/porglue.hxx | 174 + sw/source/core/text/porhyph.hxx | 141 + sw/source/core/text/porlay.cxx | 504 +++ sw/source/core/text/porlay.hxx | 390 +++ sw/source/core/text/porlin.cxx | 405 +++ sw/source/core/text/porlin.hxx | 329 ++ sw/source/core/text/porref.cxx | 139 + sw/source/core/text/porref.hxx | 106 + sw/source/core/text/porrst.cxx | 547 ++++ sw/source/core/text/porrst.hxx | 149 + sw/source/core/text/portab.hxx | 159 + sw/source/core/text/portox.cxx | 140 + sw/source/core/text/portox.hxx | 108 + sw/source/core/text/portxt.cxx | 745 +++++ sw/source/core/text/portxt.hxx | 139 + sw/source/core/text/possiz.hxx | 120 + sw/source/core/text/redlnitr.cxx | 558 ++++ sw/source/core/text/redlnitr.hxx | 150 + sw/source/core/text/txtcache.cxx | 277 ++ sw/source/core/text/txtcache.hxx | 113 + sw/source/core/text/txtcfg.hxx | 209 ++ sw/source/core/text/txtdrop.cxx | 800 +++++ sw/source/core/text/txtfld.cxx | 534 ++++ sw/source/core/text/txtfly.cxx | 1913 +++++++++++ sw/source/core/text/txtfly.hxx | 275 ++ sw/source/core/text/txtfrm.cxx | 1834 +++++++++++ sw/source/core/text/txtftn.cxx | 1542 +++++++++ sw/source/core/text/txthyph.cxx | 910 ++++++ sw/source/core/text/txtinit.cxx | 151 + sw/source/core/text/txtio.cxx | 1134 +++++++ sw/source/core/text/txtpaint.cxx | 144 + sw/source/core/text/txtpaint.hxx | 259 ++ sw/source/core/text/txttab.cxx | 537 ++++ sw/source/core/text/widorp.cxx | 525 +++ sw/source/core/text/widorp.hxx | 125 + sw/source/core/text/wrong.cxx | 370 +++ sw/source/core/tox/makefile.mk | 103 + sw/source/core/tox/tox.cxx | 1261 ++++++++ sw/source/core/tox/txmsrt.cxx | 818 +++++ sw/source/core/txtnode/atrfld.cxx | 376 +++ sw/source/core/txtnode/atrflyin.cxx | 327 ++ sw/source/core/txtnode/atrftn.cxx | 554 ++++ sw/source/core/txtnode/atrref.cxx | 151 + sw/source/core/txtnode/atrtox.cxx | 144 + sw/source/core/txtnode/chrfmt.cxx | 76 + sw/source/core/txtnode/fmtatr1.cxx | 133 + sw/source/core/txtnode/fmtatr2.cxx | 381 +++ sw/source/core/txtnode/fntcache.cxx | 1208 +++++++ sw/source/core/txtnode/fntcap.cxx | 658 ++++ sw/source/core/txtnode/makefile.mk | 145 + sw/source/core/txtnode/ndhints.cxx | 464 +++ sw/source/core/txtnode/ndtxt.cxx | 2738 ++++++++++++++++ sw/source/core/txtnode/swfntcch.cxx | 123 + sw/source/core/txtnode/swfont.cxx | 1103 +++++++ sw/source/core/txtnode/thints.cxx | 2138 +++++++++++++ sw/source/core/txtnode/txatbase.cxx | 130 + sw/source/core/txtnode/txtatr2.cxx | 630 ++++ sw/source/core/txtnode/txtedt.cxx | 1040 ++++++ sw/source/core/undo/docundo.cxx | 807 +++++ sw/source/core/undo/makefile.mk | 135 + sw/source/core/undo/rolbck.cxx | 1488 +++++++++ sw/source/core/undo/unattr.cxx | 1356 ++++++++ sw/source/core/undo/unbkmk.cxx | 225 ++ sw/source/core/undo/undel.cxx | 970 ++++++ sw/source/core/undo/undobj.cxx | 1276 ++++++++ sw/source/core/undo/undobj1.cxx | 778 +++++ sw/source/core/undo/undraw.cxx | 779 +++++ sw/source/core/undo/unfmco.cxx | 202 ++ sw/source/core/undo/unins.cxx | 1214 +++++++ sw/source/core/undo/unmove.cxx | 505 +++ sw/source/core/undo/unnum.cxx | 588 ++++ sw/source/core/undo/unoutl.cxx | 153 + sw/source/core/undo/unovwr.cxx | 407 +++ sw/source/core/undo/unredln.cxx | 579 ++++ sw/source/core/undo/unsect.cxx | 627 ++++ sw/source/core/undo/unsort.cxx | 422 +++ sw/source/core/undo/unspnd.cxx | 380 +++ sw/source/core/undo/untbl.cxx | 3123 ++++++++++++++++++ sw/source/core/undo/untblk.cxx | 489 +++ sw/source/core/unocore/makefile.mk | 152 + sw/source/core/unocore/unobkm.cxx | 431 +++ sw/source/core/unocore/unoclbck.cxx | 230 ++ sw/source/core/unocore/unocoll.cxx | 2408 ++++++++++++++ sw/source/core/unocore/unodraw.cxx | 1420 +++++++++ sw/source/core/unocore/unofield.cxx | 3230 +++++++++++++++++++ sw/source/core/unocore/unoframe.cxx | 2669 ++++++++++++++++ sw/source/core/unocore/unoftn.cxx | 644 ++++ sw/source/core/unocore/unoidx.cxx | 2742 ++++++++++++++++ sw/source/core/unocore/unomap.cxx | 1921 +++++++++++ sw/source/core/unocore/unoobj.cxx | 6024 +++++++++++++++++++++++++++++++++++ sw/source/core/unocore/unoport.cxx | 704 ++++ sw/source/core/unocore/unoprnms.cxx | 529 +++ sw/source/core/unocore/unorefmk.cxx | 496 +++ sw/source/core/unocore/unosect.cxx | 858 +++++ sw/source/core/unocore/unosett.cxx | 2528 +++++++++++++++ sw/source/core/unocore/unosrch.cxx | 889 ++++++ sw/source/core/unocore/unostyle.cxx | 2861 +++++++++++++++++ sw/source/core/unocore/unotbl.cxx | 4783 +++++++++++++++++++++++++++ sw/source/core/unocore/unotext.cxx | 1534 +++++++++ sw/source/core/view/makefile.mk | 111 + sw/source/core/view/scrrect.cxx | 934 ++++++ sw/source/core/view/vdraw.cxx | 606 ++++ sw/source/core/view/viewimp.cxx | 478 +++ sw/source/core/view/viewpg.cxx | 1472 +++++++++ sw/source/core/view/viewsh.cxx | 2154 +++++++++++++ sw/source/core/view/vnew.cxx | 520 +++ sw/source/core/view/vprint.cxx | 1924 +++++++++++ 380 files changed, 291878 insertions(+) create mode 100644 sw/source/core/attr/calbck.cxx create mode 100644 sw/source/core/attr/cellatr.cxx create mode 100644 sw/source/core/attr/format.cxx create mode 100644 sw/source/core/attr/hints.cxx create mode 100644 sw/source/core/attr/makefile.mk create mode 100644 sw/source/core/attr/swatrset.cxx create mode 100644 sw/source/core/bastyp/bparr.cxx create mode 100644 sw/source/core/bastyp/breakit.cxx create mode 100644 sw/source/core/bastyp/calc.cxx create mode 100644 sw/source/core/bastyp/index.cxx create mode 100644 sw/source/core/bastyp/init.cxx create mode 100644 sw/source/core/bastyp/makefile.mk create mode 100644 sw/source/core/bastyp/ring.cxx create mode 100644 sw/source/core/bastyp/swcache.cxx create mode 100644 sw/source/core/bastyp/swrect.cxx create mode 100644 sw/source/core/bastyp/swregion.cxx create mode 100644 sw/source/core/bastyp/swtypes.cxx create mode 100644 sw/source/core/bastyp/tabcol.cxx create mode 100644 sw/source/core/crsr/bookmrk.cxx create mode 100644 sw/source/core/crsr/callnk.cxx create mode 100644 sw/source/core/crsr/callnk.hxx create mode 100644 sw/source/core/crsr/crbm.cxx create mode 100644 sw/source/core/crsr/crsrsh.cxx create mode 100644 sw/source/core/crsr/crstrvl.cxx create mode 100644 sw/source/core/crsr/crstrvl1.cxx create mode 100644 sw/source/core/crsr/findattr.cxx create mode 100644 sw/source/core/crsr/findcoll.cxx create mode 100644 sw/source/core/crsr/findfmt.cxx create mode 100644 sw/source/core/crsr/findtxt.cxx create mode 100644 sw/source/core/crsr/makefile.mk create mode 100644 sw/source/core/crsr/pam.cxx create mode 100644 sw/source/core/crsr/paminit.cxx create mode 100644 sw/source/core/crsr/swcrsr.cxx create mode 100644 sw/source/core/crsr/trvlcol.cxx create mode 100644 sw/source/core/crsr/trvlfnfl.cxx create mode 100644 sw/source/core/crsr/trvlreg.cxx create mode 100644 sw/source/core/crsr/trvltbl.cxx create mode 100644 sw/source/core/crsr/unocrsr.cxx create mode 100644 sw/source/core/crsr/viscrs.cxx create mode 100644 sw/source/core/doc/acmplwrd.cxx create mode 100644 sw/source/core/doc/doc.cxx create mode 100644 sw/source/core/doc/docbasic.cxx create mode 100644 sw/source/core/doc/docbm.cxx create mode 100644 sw/source/core/doc/docchart.cxx create mode 100644 sw/source/core/doc/doccomp.cxx create mode 100644 sw/source/core/doc/doccorr.cxx create mode 100644 sw/source/core/doc/docdde.cxx create mode 100644 sw/source/core/doc/docdesc.cxx create mode 100644 sw/source/core/doc/docdraw.cxx create mode 100644 sw/source/core/doc/docedt.cxx create mode 100644 sw/source/core/doc/docfld.cxx create mode 100644 sw/source/core/doc/docfly.cxx create mode 100644 sw/source/core/doc/docfmt.cxx create mode 100644 sw/source/core/doc/docftn.cxx create mode 100644 sw/source/core/doc/docglbl.cxx create mode 100644 sw/source/core/doc/docglos.cxx create mode 100644 sw/source/core/doc/doclay.cxx create mode 100644 sw/source/core/doc/docnew.cxx create mode 100644 sw/source/core/doc/docnum.cxx create mode 100644 sw/source/core/doc/docredln.cxx create mode 100644 sw/source/core/doc/docsort.cxx create mode 100644 sw/source/core/doc/docstat.cxx create mode 100644 sw/source/core/doc/doctxm.cxx create mode 100644 sw/source/core/doc/extinput.cxx create mode 100644 sw/source/core/doc/fmtcol.cxx create mode 100644 sw/source/core/doc/ftnidx.cxx create mode 100644 sw/source/core/doc/gctable.cxx create mode 100644 sw/source/core/doc/htmltbl.cxx create mode 100644 sw/source/core/doc/lineinfo.cxx create mode 100644 sw/source/core/doc/makefile.mk create mode 100644 sw/source/core/doc/notxtfrm.cxx create mode 100644 sw/source/core/doc/number.cxx create mode 100644 sw/source/core/doc/poolfmt.cxx create mode 100644 sw/source/core/doc/sortopt.cxx create mode 100644 sw/source/core/doc/swserv.cxx create mode 100644 sw/source/core/doc/tblafmt.cxx create mode 100644 sw/source/core/doc/tblcpy.cxx create mode 100644 sw/source/core/doc/tblrwcl.cxx create mode 100644 sw/source/core/doc/visiturl.cxx create mode 100644 sw/source/core/docnode/makefile.mk create mode 100644 sw/source/core/docnode/ndcopy.cxx create mode 100644 sw/source/core/docnode/ndindex.cxx create mode 100644 sw/source/core/docnode/ndnotxt.cxx create mode 100644 sw/source/core/docnode/ndnum.cxx create mode 100644 sw/source/core/docnode/ndsect.cxx create mode 100644 sw/source/core/docnode/ndtbl.cxx create mode 100644 sw/source/core/docnode/ndtbl1.cxx create mode 100644 sw/source/core/docnode/node.cxx create mode 100644 sw/source/core/docnode/node2lay.cxx create mode 100644 sw/source/core/docnode/nodes.cxx create mode 100644 sw/source/core/docnode/section.cxx create mode 100644 sw/source/core/docnode/swbaslnk.cxx create mode 100644 sw/source/core/draw/dcontact.cxx create mode 100644 sw/source/core/draw/dflyobj.cxx create mode 100644 sw/source/core/draw/dobjfac.cxx create mode 100644 sw/source/core/draw/dpage.cxx create mode 100644 sw/source/core/draw/drawdoc.cxx create mode 100644 sw/source/core/draw/dview.cxx create mode 100644 sw/source/core/draw/makefile.mk create mode 100644 sw/source/core/edit/acorrect.cxx create mode 100644 sw/source/core/edit/autofmt.cxx create mode 100644 sw/source/core/edit/edatmisc.cxx create mode 100644 sw/source/core/edit/edattr.cxx create mode 100644 sw/source/core/edit/eddel.cxx create mode 100644 sw/source/core/edit/edfcol.cxx create mode 100644 sw/source/core/edit/edfld.cxx create mode 100644 sw/source/core/edit/edfmt.cxx create mode 100644 sw/source/core/edit/edglbldc.cxx create mode 100644 sw/source/core/edit/edglss.cxx create mode 100644 sw/source/core/edit/editsh.cxx create mode 100644 sw/source/core/edit/edlingu.cxx create mode 100644 sw/source/core/edit/ednumber.cxx create mode 100644 sw/source/core/edit/edredln.cxx create mode 100644 sw/source/core/edit/edsect.cxx create mode 100644 sw/source/core/edit/edtab.cxx create mode 100644 sw/source/core/edit/edtox.cxx create mode 100644 sw/source/core/edit/edundo.cxx create mode 100644 sw/source/core/edit/edws.cxx create mode 100644 sw/source/core/edit/makefile.mk create mode 100644 sw/source/core/except/dbgloop.cxx create mode 100644 sw/source/core/except/errhdl.cxx create mode 100644 sw/source/core/except/makefile.mk create mode 100644 sw/source/core/fields/authfld.cxx create mode 100644 sw/source/core/fields/cellfml.cxx create mode 100644 sw/source/core/fields/chpfld.cxx create mode 100644 sw/source/core/fields/dbfld.cxx create mode 100644 sw/source/core/fields/ddefld.cxx create mode 100644 sw/source/core/fields/ddetbl.cxx create mode 100644 sw/source/core/fields/docufld.cxx create mode 100644 sw/source/core/fields/expfld.cxx create mode 100644 sw/source/core/fields/fldbas.cxx create mode 100644 sw/source/core/fields/flddat.cxx create mode 100644 sw/source/core/fields/fldlst.cxx create mode 100644 sw/source/core/fields/macrofld.cxx create mode 100644 sw/source/core/fields/makefile.mk create mode 100644 sw/source/core/fields/reffld.cxx create mode 100644 sw/source/core/fields/scrptfld.cxx create mode 100644 sw/source/core/fields/tblcalc.cxx create mode 100644 sw/source/core/fields/usrfld.cxx create mode 100644 sw/source/core/frmedt/fecopy.cxx create mode 100644 sw/source/core/frmedt/fedesc.cxx create mode 100644 sw/source/core/frmedt/fefly1.cxx create mode 100644 sw/source/core/frmedt/feflyole.cxx create mode 100644 sw/source/core/frmedt/feshview.cxx create mode 100644 sw/source/core/frmedt/fetab.cxx create mode 100644 sw/source/core/frmedt/fews.cxx create mode 100644 sw/source/core/frmedt/makefile.mk create mode 100644 sw/source/core/frmedt/tblsel.cxx create mode 100644 sw/source/core/graphic/grfatr.cxx create mode 100644 sw/source/core/graphic/makefile.mk create mode 100644 sw/source/core/graphic/ndgrf.cxx create mode 100644 sw/source/core/inc/acorrect.hxx create mode 100644 sw/source/core/inc/blink.hxx create mode 100644 sw/source/core/inc/bodyfrm.hxx create mode 100644 sw/source/core/inc/cellfrm.hxx create mode 100644 sw/source/core/inc/cntfrm.hxx create mode 100644 sw/source/core/inc/colfrm.hxx create mode 100644 sw/source/core/inc/dbg_lay.hxx create mode 100644 sw/source/core/inc/dbgloop.hxx create mode 100644 sw/source/core/inc/dflyobj.hxx create mode 100644 sw/source/core/inc/docfld.hxx create mode 100644 sw/source/core/inc/docsort.hxx create mode 100644 sw/source/core/inc/doctxm.hxx create mode 100644 sw/source/core/inc/drawdev.hxx create mode 100644 sw/source/core/inc/drawfont.hxx create mode 100644 sw/source/core/inc/dview.hxx create mode 100644 sw/source/core/inc/flowfrm.hxx create mode 100644 sw/source/core/inc/flyfrm.hxx create mode 100644 sw/source/core/inc/flyfrms.hxx create mode 100644 sw/source/core/inc/fntcache.hxx create mode 100644 sw/source/core/inc/frame.hxx create mode 100644 sw/source/core/inc/frminf.hxx create mode 100644 sw/source/core/inc/frmtool.hxx create mode 100644 sw/source/core/inc/ftnboss.hxx create mode 100644 sw/source/core/inc/ftnfrm.hxx create mode 100644 sw/source/core/inc/hffrm.hxx create mode 100644 sw/source/core/inc/layact.hxx create mode 100644 sw/source/core/inc/layfrm.hxx create mode 100644 sw/source/core/inc/layouter.hxx create mode 100644 sw/source/core/inc/makefile.mk create mode 100644 sw/source/core/inc/mvsave.hxx create mode 100644 sw/source/core/inc/node2lay.hxx create mode 100644 sw/source/core/inc/noteurl.hxx create mode 100644 sw/source/core/inc/notxtfrm.hxx create mode 100644 sw/source/core/inc/pagefrm.hxx create mode 100644 sw/source/core/inc/pamtyp.hxx create mode 100644 sw/source/core/inc/ptqueue.hxx create mode 100644 sw/source/core/inc/rootfrm.hxx create mode 100644 sw/source/core/inc/rowfrm.hxx create mode 100644 sw/source/core/inc/rvp_mark.hxx create mode 100644 sw/source/core/inc/scrrect.hxx create mode 100644 sw/source/core/inc/sectfrm.hxx create mode 100644 sw/source/core/inc/swblocks.hxx create mode 100644 sw/source/core/inc/swcache.hxx create mode 100644 sw/source/core/inc/swfntcch.hxx create mode 100644 sw/source/core/inc/swfont.hxx create mode 100644 sw/source/core/inc/tabfrm.hxx create mode 100644 sw/source/core/inc/tblrwcl.hxx create mode 100644 sw/source/core/inc/txmsrt.hxx create mode 100644 sw/source/core/inc/txtfrm.hxx create mode 100644 sw/source/core/inc/txttypes.hxx create mode 100644 sw/source/core/inc/unoclbck.hxx create mode 100644 sw/source/core/inc/viewimp.hxx create mode 100644 sw/source/core/inc/visiturl.hxx create mode 100644 sw/source/core/inc/wrong.hxx create mode 100644 sw/source/core/layout/atrfrm.cxx create mode 100644 sw/source/core/layout/calcmove.cxx create mode 100644 sw/source/core/layout/colfrm.cxx create mode 100644 sw/source/core/layout/dbg_lay.cxx create mode 100644 sw/source/core/layout/findfrm.cxx create mode 100644 sw/source/core/layout/flowfrm.cxx create mode 100644 sw/source/core/layout/fly.cxx create mode 100644 sw/source/core/layout/flycnt.cxx create mode 100644 sw/source/core/layout/flyincnt.cxx create mode 100644 sw/source/core/layout/flylay.cxx create mode 100644 sw/source/core/layout/flypos.cxx create mode 100644 sw/source/core/layout/frmtool.cxx create mode 100644 sw/source/core/layout/ftnfrm.cxx create mode 100644 sw/source/core/layout/hffrm.cxx create mode 100644 sw/source/core/layout/layact.cxx create mode 100644 sw/source/core/layout/layouter.cxx create mode 100644 sw/source/core/layout/makefile.mk create mode 100644 sw/source/core/layout/newfrm.cxx create mode 100644 sw/source/core/layout/pagechg.cxx create mode 100644 sw/source/core/layout/pagedesc.cxx create mode 100644 sw/source/core/layout/paintfrm.cxx create mode 100644 sw/source/core/layout/sectfrm.cxx create mode 100644 sw/source/core/layout/ssfrm.cxx create mode 100644 sw/source/core/layout/tabfrm.cxx create mode 100644 sw/source/core/layout/trvlfrm.cxx create mode 100644 sw/source/core/layout/unusedf.cxx create mode 100644 sw/source/core/layout/virtoutp.cxx create mode 100644 sw/source/core/layout/virtoutp.hxx create mode 100644 sw/source/core/layout/wsfrm.cxx create mode 100644 sw/source/core/makefile.mk create mode 100644 sw/source/core/ole/makefile.mk create mode 100644 sw/source/core/ole/ndole.cxx create mode 100644 sw/source/core/para/makefile.mk create mode 100644 sw/source/core/para/paratr.cxx create mode 100644 sw/source/core/sw3io/makefile.mk create mode 100644 sw/source/core/sw3io/swacorr.cxx create mode 100644 sw/source/core/swg/makefile.mk create mode 100644 sw/source/core/swg/swblocks.cxx create mode 100644 sw/source/core/text/blink.cxx create mode 100644 sw/source/core/text/frmcrsr.cxx create mode 100644 sw/source/core/text/frmform.cxx create mode 100644 sw/source/core/text/frminf.cxx create mode 100644 sw/source/core/text/frmpaint.cxx create mode 100644 sw/source/core/text/guess.cxx create mode 100644 sw/source/core/text/guess.hxx create mode 100644 sw/source/core/text/inftxt.cxx create mode 100644 sw/source/core/text/inftxt.hxx create mode 100644 sw/source/core/text/itradj.cxx create mode 100644 sw/source/core/text/itratr.cxx create mode 100644 sw/source/core/text/itratr.hxx create mode 100644 sw/source/core/text/itrcrsr.cxx create mode 100644 sw/source/core/text/itrform2.cxx create mode 100644 sw/source/core/text/itrform2.hxx create mode 100644 sw/source/core/text/itrpaint.cxx create mode 100644 sw/source/core/text/itrpaint.hxx create mode 100644 sw/source/core/text/itrtxt.cxx create mode 100644 sw/source/core/text/itrtxt.hxx create mode 100644 sw/source/core/text/makefile.mk create mode 100644 sw/source/core/text/noteurl.cxx create mode 100644 sw/source/core/text/pordrop.hxx create mode 100644 sw/source/core/text/porexp.cxx create mode 100644 sw/source/core/text/porexp.hxx create mode 100644 sw/source/core/text/porfld.cxx create mode 100644 sw/source/core/text/porfld.hxx create mode 100644 sw/source/core/text/porfly.cxx create mode 100644 sw/source/core/text/porfly.hxx create mode 100644 sw/source/core/text/porftn.hxx create mode 100644 sw/source/core/text/porglue.cxx create mode 100644 sw/source/core/text/porglue.hxx create mode 100644 sw/source/core/text/porhyph.hxx create mode 100644 sw/source/core/text/porlay.cxx create mode 100644 sw/source/core/text/porlay.hxx create mode 100644 sw/source/core/text/porlin.cxx create mode 100644 sw/source/core/text/porlin.hxx create mode 100644 sw/source/core/text/porref.cxx create mode 100644 sw/source/core/text/porref.hxx create mode 100644 sw/source/core/text/porrst.cxx create mode 100644 sw/source/core/text/porrst.hxx create mode 100644 sw/source/core/text/portab.hxx create mode 100644 sw/source/core/text/portox.cxx create mode 100644 sw/source/core/text/portox.hxx create mode 100644 sw/source/core/text/portxt.cxx create mode 100644 sw/source/core/text/portxt.hxx create mode 100644 sw/source/core/text/possiz.hxx create mode 100644 sw/source/core/text/redlnitr.cxx create mode 100644 sw/source/core/text/redlnitr.hxx create mode 100644 sw/source/core/text/txtcache.cxx create mode 100644 sw/source/core/text/txtcache.hxx create mode 100644 sw/source/core/text/txtcfg.hxx create mode 100644 sw/source/core/text/txtdrop.cxx create mode 100644 sw/source/core/text/txtfld.cxx create mode 100644 sw/source/core/text/txtfly.cxx create mode 100644 sw/source/core/text/txtfly.hxx create mode 100644 sw/source/core/text/txtfrm.cxx create mode 100644 sw/source/core/text/txtftn.cxx create mode 100644 sw/source/core/text/txthyph.cxx create mode 100644 sw/source/core/text/txtinit.cxx create mode 100644 sw/source/core/text/txtio.cxx create mode 100644 sw/source/core/text/txtpaint.cxx create mode 100644 sw/source/core/text/txtpaint.hxx create mode 100644 sw/source/core/text/txttab.cxx create mode 100644 sw/source/core/text/widorp.cxx create mode 100644 sw/source/core/text/widorp.hxx create mode 100644 sw/source/core/text/wrong.cxx create mode 100644 sw/source/core/tox/makefile.mk create mode 100644 sw/source/core/tox/tox.cxx create mode 100644 sw/source/core/tox/txmsrt.cxx create mode 100644 sw/source/core/txtnode/atrfld.cxx create mode 100644 sw/source/core/txtnode/atrflyin.cxx create mode 100644 sw/source/core/txtnode/atrftn.cxx create mode 100644 sw/source/core/txtnode/atrref.cxx create mode 100644 sw/source/core/txtnode/atrtox.cxx create mode 100644 sw/source/core/txtnode/chrfmt.cxx create mode 100644 sw/source/core/txtnode/fmtatr1.cxx create mode 100644 sw/source/core/txtnode/fmtatr2.cxx create mode 100644 sw/source/core/txtnode/fntcache.cxx create mode 100644 sw/source/core/txtnode/fntcap.cxx create mode 100644 sw/source/core/txtnode/makefile.mk create mode 100644 sw/source/core/txtnode/ndhints.cxx create mode 100644 sw/source/core/txtnode/ndtxt.cxx create mode 100644 sw/source/core/txtnode/swfntcch.cxx create mode 100644 sw/source/core/txtnode/swfont.cxx create mode 100644 sw/source/core/txtnode/thints.cxx create mode 100644 sw/source/core/txtnode/txatbase.cxx create mode 100644 sw/source/core/txtnode/txtatr2.cxx create mode 100644 sw/source/core/txtnode/txtedt.cxx create mode 100644 sw/source/core/undo/docundo.cxx create mode 100644 sw/source/core/undo/makefile.mk create mode 100644 sw/source/core/undo/rolbck.cxx create mode 100644 sw/source/core/undo/unattr.cxx create mode 100644 sw/source/core/undo/unbkmk.cxx create mode 100644 sw/source/core/undo/undel.cxx create mode 100644 sw/source/core/undo/undobj.cxx create mode 100644 sw/source/core/undo/undobj1.cxx create mode 100644 sw/source/core/undo/undraw.cxx create mode 100644 sw/source/core/undo/unfmco.cxx create mode 100644 sw/source/core/undo/unins.cxx create mode 100644 sw/source/core/undo/unmove.cxx create mode 100644 sw/source/core/undo/unnum.cxx create mode 100644 sw/source/core/undo/unoutl.cxx create mode 100644 sw/source/core/undo/unovwr.cxx create mode 100644 sw/source/core/undo/unredln.cxx create mode 100644 sw/source/core/undo/unsect.cxx create mode 100644 sw/source/core/undo/unsort.cxx create mode 100644 sw/source/core/undo/unspnd.cxx create mode 100644 sw/source/core/undo/untbl.cxx create mode 100644 sw/source/core/undo/untblk.cxx create mode 100644 sw/source/core/unocore/makefile.mk create mode 100644 sw/source/core/unocore/unobkm.cxx create mode 100644 sw/source/core/unocore/unoclbck.cxx create mode 100644 sw/source/core/unocore/unocoll.cxx create mode 100644 sw/source/core/unocore/unodraw.cxx create mode 100644 sw/source/core/unocore/unofield.cxx create mode 100644 sw/source/core/unocore/unoframe.cxx create mode 100644 sw/source/core/unocore/unoftn.cxx create mode 100644 sw/source/core/unocore/unoidx.cxx create mode 100644 sw/source/core/unocore/unomap.cxx create mode 100644 sw/source/core/unocore/unoobj.cxx create mode 100644 sw/source/core/unocore/unoport.cxx create mode 100644 sw/source/core/unocore/unoprnms.cxx create mode 100644 sw/source/core/unocore/unorefmk.cxx create mode 100644 sw/source/core/unocore/unosect.cxx create mode 100644 sw/source/core/unocore/unosett.cxx create mode 100644 sw/source/core/unocore/unosrch.cxx create mode 100644 sw/source/core/unocore/unostyle.cxx create mode 100644 sw/source/core/unocore/unotbl.cxx create mode 100644 sw/source/core/unocore/unotext.cxx create mode 100644 sw/source/core/view/makefile.mk create mode 100644 sw/source/core/view/scrrect.cxx create mode 100644 sw/source/core/view/vdraw.cxx create mode 100644 sw/source/core/view/viewimp.cxx create mode 100644 sw/source/core/view/viewpg.cxx create mode 100644 sw/source/core/view/viewsh.cxx create mode 100644 sw/source/core/view/vnew.cxx create mode 100644 sw/source/core/view/vprint.cxx diff --git a/sw/source/core/attr/calbck.cxx b/sw/source/core/attr/calbck.cxx new file mode 100644 index 000000000000..e8caa63045d5 --- /dev/null +++ b/sw/source/core/attr/calbck.cxx @@ -0,0 +1,642 @@ +/************************************************************************* + * + * $RCSfile: calbck.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:15 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#include "hintids.hxx" // fuer RES_.. +#include "frame.hxx" +#include "errhdl.hxx" +#include "hints.hxx" + +#define ITERATION // iterative SwModify::_Insert-Methode +#include "calbck.hxx" +#include "swcache.hxx" +#include "swfntcch.hxx" + +static SwClientIter* pClientIters = 0; + + +TYPEINIT0(SwClient); //rtti + +/************************************************************************* +|* SwClient::SwClient(SwModify *) +|* +|* Beschreibung callback.doc V1.14 +|* Ersterstellung VB 20.03.91 +|* Letzte Aenderung MA 20. Mar. 95 +*************************************************************************/ + + +SwClient::SwClient(SwModify *pToRegisterIn) + : pLeft( 0 ), pRight( 0 ), pRegisteredIn( 0 ) +{ + bModifyLocked = + bInModify = + bInDocDTOR = + bInCache = FALSE; + bInSwFntCache = FALSE; + + if(pToRegisterIn) + pToRegisterIn->Add(this); +} + +/************************************************************************* +|* SwClient::Modify() +|* +|* Beschreibung callback.doc V1.14 +|* Ersterstellung VB 20.03.91 +|* Letzte Aenderung VB 20.03.91 +*************************************************************************/ + + +void SwClient::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew ) +{ + if( (!pOld || pOld->Which() != RES_OBJECTDYING) ) + return; + + SwPtrMsgPoolItem *pDead = (SwPtrMsgPoolItem *)pOld; + if(pDead->pObject == pRegisteredIn) + { + SwModify *pAbove = (SwModify*)pRegisteredIn->GetRegisteredIn(); + if(pAbove) + { + pAbove->Add(this); + return; + } + pRegisteredIn->Remove(this); + } +} + +/************************************************************************* +|* SwClient::~SwClient() +|* +|* Beschreibung callback.doc V1.14 +|* Ersterstellung VB 20.03.91 +|* Letzte Aenderung MA 25. Jan. 94 +*************************************************************************/ + + +SwClient::~SwClient() +{ + if( pRegisteredIn && pRegisteredIn->GetDepends() ) + pRegisteredIn->Remove( this ); + + ASSERT( !IsModifyLocked(), "Modify destroyed but locked." ); +} + + + // erfrage vom Client Informationen +BOOL SwClient::GetInfo( SfxPoolItem& ) const +{ + return TRUE; // und weiter +} + +/************************************************************************* +|* SwModify::SwModify( SwModify * ) +|* +|* Beschreibung Dokument 1.7 +|* Ersterstellung JP 20.11.90 +|* Letzte Aenderung VB 20.03.91 +*************************************************************************/ + + +SwModify::SwModify( SwModify *pToRegisterIn ) + : SwClient(pToRegisterIn), pRoot( 0 ) +{ +} + +/************************************************************************* +|* SwModify::~SwModify() +|* +|* Beschreibung Dokument 1.7 +|* Ersterstellung JP 20.11.90 +|* Letzte Aenderung JP 15.04.94 +*************************************************************************/ + + + +SwModify::~SwModify() +{ + if ( IsInCache() ) + SwFrm::GetCache().Delete( this ); + + if ( IsInSwFntCache() ) + pSwFontCache->Delete( this ); + + if( pRoot ) + { + if( IsInDocDTOR() ) + { + // alle Clients "logisch" austragen + SwClientIter aIter( *this ); + SwClient* p; + while( 0 != ( p = aIter++ ) ) + p->pRegisteredIn = 0; + + p = aIter.GoRoot(); // wieder ab Root (==Start) anfangen + do { + p->pRegisteredIn = 0; + } while( 0 != ( p = aIter-- ) ); + } + else + { + // verschicke die Nachricht an die abgeleiteten Objekte. + SwPtrMsgPoolItem aDyObject( RES_OBJECTDYING, this ); + Modify( &aDyObject, &aDyObject ); + + // Zwangsummeldung aller derjenigen, die sich nicht ausgetragen + // haben, durch Aufruf von SwClient::Modify() + while( pRoot ) + pRoot->SwClient::Modify(&aDyObject, &aDyObject); + } + } +} + +/************************************************************************* +|* SwModify::Modify( SwHint * pOldValue, SwHint * pNewValue ) +|* +|* Beschreibung Dokument 1.7 +|* Ersterstellung JP 20.11.90 +|* Letzte Aenderung MA 20. Mar. 95 +*************************************************************************/ + + + +void SwModify::Modify( SfxPoolItem* pOldValue, SfxPoolItem* pNewValue ) +{ + + if( !pRoot || IsModifyLocked() ) + return; + + + if ( IsInCache() || IsInSwFntCache() ) + { + const USHORT nWhich = pOldValue ? pOldValue->Which() : + pNewValue ? pNewValue->Which() : 0; + CheckCaching( nWhich ); + } + + LockModify(); + + bInModify = +#ifdef PRODUCT + TRUE +#else + // Modifies von RES_OBJECTDYING sollte kein ASSRT ausloesen + !pOldValue || + (RES_OBJECTDYING != pOldValue->Which() && + RES_REMOVE_UNO_OBJECT != pOldValue->Which()) || + ((SwPtrMsgPoolItem *)pOldValue)->pObject != this +#endif + ; + + SwClientIter aIter( *this ); + SwClient * pLast = aIter.GoStart(); + if( pLast ) // konnte zum Anfang gesprungen werden ?? + do { + pLast->Modify( pOldValue, pNewValue ); + if( !pRoot ) // Baum schon Weg ?? + break; + } while( 0 != ( pLast = aIter++ )); + + bInModify = FALSE; + UnlockModify(); +} + +// erfrage vom Modify Informationen + +BOOL SwModify::GetInfo( SfxPoolItem& rInfo ) const +{ + BOOL bRet = TRUE; // bedeutet weiter zum naechsten + + if( pRoot ) + { + SwClientIter aIter( *(SwModify*)this ); + + SwClient* pLast = aIter.GoStart(); + if( pLast ) + while( 0 != ( bRet = pLast->GetInfo( rInfo )) && + 0 != ( pLast = aIter++ ) ) + ; + } + + return bRet; // und weiter +} + +/************************************************************************* +|* SwModify::Add( SwClient *pDepend ) +|* +|* Beschreibung Dokument 1.7 +|* Ersterstellung JP 20.11.90 +|* Letzte Aenderung JP 14.09.94 +*************************************************************************/ + + + +void SwModify::Add(SwClient *pDepend) +{ + ASSERT( !bInModify, "Client innerhalb des eigenen Modifies einfuegen?" ); + + // nur wenn das hier noch nicht eingetragen ist einfuegen + if(pDepend->pRegisteredIn != this ) + { +#ifndef PRODUCT + SwClientIter* pTmp = pClientIters; + while( pTmp ) + { + ASSERT( &pTmp->rRoot != pRoot, + "Client beim angemeldeten ClientIter einfuegen?" ); + pTmp = pTmp->pNxtIter; + } +#endif + // wenn schon wanders angemeldet, dann dort abmelden + if( pDepend->pRegisteredIn != 0 ) + pDepend->pRegisteredIn->Remove( pDepend ); + + if( !pRoot ) + { + pRoot = pDepend; + pRoot->pLeft = 0; + pRoot->pRight = 0; + } + else + { + // immer hinter die Root haengen + pDepend->pRight = pRoot->pRight; + pRoot->pRight = pDepend; + pDepend->pLeft = pRoot; + if( pDepend->pRight ) + pDepend->pRight->pLeft = pDepend; + } + + pDepend->pRegisteredIn = this; + } + +} + +/************************************************************************* +|* SwModify::_Remove( SwClient *pDepend ) +|* +|* Beschreibung Dokument 1.7 +|* Ersterstellung JP 20.11.90 +|* Letzte Aenderung JP 14.09.94 +*************************************************************************/ + + + +SwClient *SwModify::_Remove(SwClient * pDepend) +{ + ASSERT( !bInModify, "Client innerhalb des eigenen Modifies loeschen?" ); + + // loesche das Object aus der Liste und setze den + // Registrierungs-Pointer zurueck + if( pDepend->pRegisteredIn == this ) + { + register SwClient* pR = pDepend->pRight; + register SwClient* pL = pDepend->pLeft; + if( pRoot == pDepend ) + pRoot = pL ? pL : pR; + + if( pL ) + pL->pRight = pR; + if( pR ) + pR->pLeft = pL; + + // alle Client-Iters updaten + SwClientIter* pTmp = pClientIters; + while( pTmp ) + { + if( pTmp->pAkt == pDepend || pTmp->pDelNext == pDepend ) + pTmp->pDelNext = pR; + pTmp = pTmp->pNxtIter; + } + + pDepend->pLeft = 0; + pDepend->pRight = 0; + } + else + ASSERT( FALSE, "SwModify::Remove(): pDepend nicht gefunden"); + pDepend->pRegisteredIn = 0; + return pDepend; +} + + +/************************************************************************* +|* SwModify::CheckCaching( const USHORT nWhich ) +|* +|* Ersterstellung JP 25.06.95 +|* Letzte Aenderung JP 25.06.95 +*************************************************************************/ + + + +void SwModify::CheckCaching( const USHORT nWhich ) +{ + if( RES_CHRATR_BEGIN <= nWhich && RES_CHRATR_END > nWhich ) + SetInSwFntCache( FALSE ); + else + switch ( nWhich ) + { + case RES_OBJECTDYING: + case RES_FMT_CHG: + case RES_ATTRSET_CHG: + SetInSwFntCache( FALSE ); + + case RES_UL_SPACE: + case RES_LR_SPACE: + case RES_BOX: + case RES_SHADOW: + case RES_FRM_SIZE: + case RES_KEEP: + case RES_BREAK: + if ( IsInCache() ) + { + SwFrm::GetCache().Delete( this ); + SetInCache( FALSE ); + } + break; + } +} + + +// ---------- +// SwDepend +// ---------- + +/************************************************************************* +|* SwDepend::SwDepend(SwClient *pTellHim,SwModify *pDepend) +|* +|* Beschreibung callback.doc V1.14 +|* Ersterstellung VB 20.03.91 +|* Letzte Aenderung VB 20.03.91 +*************************************************************************/ + + +SwDepend::SwDepend(SwClient *pTellHim, SwModify *pDepend) + : SwClient(pDepend) +{ + pToTell = pTellHim; +} + +/************************************************************************* +|* +|* SwDepend::Modify(SwHint *, SwHint *) +|* +|* Beschreibung callback.doc V1.14 +|* Ersterstellung VB 20.03.91 +|* Letzte Aenderung VB 20.03.91 +|* +*************************************************************************/ + + +void SwDepend::Modify( SfxPoolItem *pOldValue, SfxPoolItem *pNewValue ) +{ + if(pNewValue && pNewValue->Which() == RES_OBJECTDYING) + SwClient::Modify(pOldValue,pNewValue); + else if(pToTell) + pToTell->Modify(pOldValue, pNewValue); +} + + + // erfrage vom Modify Informationen +BOOL SwDepend::GetInfo( SfxPoolItem& rInfo ) const +{ + return pToTell ? pToTell->GetInfo( rInfo ) : TRUE; +} + +/********************************************************************/ + + +SwClientIter::SwClientIter( SwModify& rModify ) + : rRoot( rModify ) +{ + // hinten einketten! + pNxtIter = 0; + if( pClientIters ) + { + SwClientIter* pTmp = pClientIters; + while( pTmp->pNxtIter ) + pTmp = pTmp->pNxtIter; + pTmp->pNxtIter = this; + } + else + pClientIters = this; + + pAkt = rRoot.pRoot; + pDelNext = pAkt; +} + + + +SwClientIter::~SwClientIter() +{ + if( pClientIters ) + { + if( pClientIters == this ) + pClientIters = pNxtIter; + else + { + SwClientIter* pTmp = pClientIters; + while( pTmp->pNxtIter != this ) + if( 0 == ( pTmp = pTmp->pNxtIter ) ) + { + ASSERT( this, "wo ist mein Pointer" ); + return ; + } + pTmp->pNxtIter = pNxtIter; + } + } +} + + +#ifndef CFRONT + // Postfix Operator +SwClient* SwClientIter::operator++(int) +{ +// solange der CFRONT Prefix und PostFix nicht unterscheiden kann, immer +// als Prefix-Operator arbeiten. Wenn der CFRONT es kann, muss auch der +// Code entsprechen umgestellt werden !!! + if( pDelNext == pAkt ) + { + pAkt = pAkt->pRight; + pDelNext = pAkt; + } + else + pAkt = pDelNext; + return pAkt; +} +#endif + + + // Prefix Operator +SwClient* SwClientIter::operator++() +{ + if( pDelNext == pAkt ) + { + pAkt = pAkt->pRight; + pDelNext = pAkt; + } + else + pAkt = pDelNext; + return pAkt; +} + + +#ifndef CFRONT + // Postfix Operator +SwClient* SwClientIter::operator--(int) +{ +// solange der CFRONT Prefix und PostFix nicht unterscheiden kann, immer +// als Prefix-Operator arbeiten. Wenn der CFRONT es kann, muss auch der +// Code entsprechen umgestellt werden !!! + if( pDelNext == pAkt ) + pAkt = pAkt->pLeft; + else + pAkt = pDelNext->pLeft; + pDelNext = pAkt; + return pAkt; +} +#endif + + + // Prefix Operator +SwClient* SwClientIter::operator--() +{ + if( pDelNext == pAkt ) + pAkt = pAkt->pLeft; + else + pAkt = pDelNext->pLeft; + pDelNext = pAkt; + return pAkt; +} + + +SwClient* SwClientIter::GoStart() // zum Anfang des Baums +{ + pAkt = rRoot.pRoot; + if( pAkt ) + while( pAkt->pLeft ) + pAkt = pAkt->pLeft; + pDelNext = pAkt; + return pAkt; +} + + +SwClient* SwClientIter::GoEnd() // zum End des Baums +{ + pAkt = pDelNext; + if( !pAkt ) + pAkt = rRoot.pRoot; + if( pAkt ) + while( pAkt->pRight ) + pAkt = pAkt->pRight; + pDelNext = pAkt; + return pAkt; +} + + + +SwClient* SwClientIter::First( TypeId nType ) +{ + aSrchId = nType; + GoStart(); + if( pAkt ) + do { + if( pAkt->IsA( aSrchId ) ) + break; + + if( pDelNext == pAkt ) + { + pAkt = pAkt->pRight; + pDelNext = pAkt; + } + else + pAkt = pDelNext; + + } while( pAkt ); + return pAkt; +} + + +SwClient* SwClientIter::Next() +{ + do { + // erstmal zum naechsten + if( pDelNext == pAkt ) + { + pAkt = pAkt->pRight; + pDelNext = pAkt; + } + else + pAkt = pDelNext; + + if( pAkt && pAkt->IsA( aSrchId ) ) + break; + } while( pAkt ); + return pAkt; +} + + + diff --git a/sw/source/core/attr/cellatr.cxx b/sw/source/core/attr/cellatr.cxx new file mode 100644 index 000000000000..7fd9751247f7 --- /dev/null +++ b/sw/source/core/attr/cellatr.cxx @@ -0,0 +1,318 @@ +/************************************************************************* + * + * $RCSfile: cellatr.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:15 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#include +#ifndef _HINTIDS_HXX +#include // fuer RES_.. +#endif + +#ifndef _CELLATR_HXX +#include +#endif +#ifndef _CALC_HXX +#include +#endif +#ifndef _FORMAT_HXX +#include +#endif +#ifndef _DOC_HXX +#include +#endif +#ifndef _SWTABLE_HXX +#include +#endif +#ifndef _NODE_HXX +#include +#endif +#ifndef _HINTS_HXX +#include +#endif +#ifndef _ROLBCK_HXX +#include +#endif + + + +//TYPEINIT1( SwFmt, SwClient ); //rtti fuer SwFmt + +/************************************************************************* +|* +*************************************************************************/ + + +SwTblBoxNumFormat::SwTblBoxNumFormat( UINT32 nFormat, BOOL bFlag ) + : SfxUInt32Item( RES_BOXATR_FORMAT, nFormat ), bAuto( bFlag ) +{ +} + + +int SwTblBoxNumFormat::operator==( const SfxPoolItem& rAttr ) const +{ + ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" ); + return GetValue() == ((SwTblBoxNumFormat&)rAttr).GetValue() && + bAuto == ((SwTblBoxNumFormat&)rAttr).bAuto; +} + + +SfxPoolItem* SwTblBoxNumFormat::Clone( SfxItemPool* ) const +{ + return new SwTblBoxNumFormat( GetValue(), bAuto ); +} + + +/************************************************************************* +|* +*************************************************************************/ + + + +SwTblBoxFormula::SwTblBoxFormula( const String& rFormula ) + : SfxPoolItem( RES_BOXATR_FORMULA ), + SwTableFormula( rFormula ), + pDefinedIn( 0 ) +{ +} + + +int SwTblBoxFormula::operator==( const SfxPoolItem& rAttr ) const +{ + ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" ); + return GetFormula() == ((SwTblBoxFormula&)rAttr).GetFormula() && + pDefinedIn == ((SwTblBoxFormula&)rAttr).pDefinedIn; +} + + +SfxPoolItem* SwTblBoxFormula::Clone( SfxItemPool* ) const +{ +// auf externe Darstellung umschalten!! + SwTblBoxFormula* pNew = new SwTblBoxFormula( GetFormula() ); + pNew->SwTableFormula::operator=( *this ); + return pNew; +} + + + + // suche den Node, in dem die Formel steht: + // TextFeld -> TextNode, + // BoxAttribut -> BoxStartNode + // !!! MUSS VON JEDER ABLEITUNG UEBERLADEN WERDEN !!! +const SwNode* SwTblBoxFormula::GetNodeOfFormula() const +{ + const SwNode* pRet = 0; + if( pDefinedIn ) + { + SwClient* pBox = SwClientIter( *pDefinedIn ).First( TYPE( SwTableBox )); + if( pBox ) + pRet = ((SwTableBox*)pBox)->GetSttNd(); + } + return pRet; +} + + +SwTableBox* SwTblBoxFormula::GetTableBox() +{ + SwTableBox* pBox = 0; + if( pDefinedIn ) + pBox = (SwTableBox*)SwClientIter( *pDefinedIn ). + First( TYPE( SwTableBox )); + return pBox; +} + + +void SwTblBoxFormula::ChangeState( const SfxPoolItem* pItem ) +{ + if( !pDefinedIn ) + return ; + + SwTableFmlUpdate* pUpdtFld; + if( !pItem || RES_TABLEFML_UPDATE != pItem->Which() ) + { + // setze bei allen das Value-Flag zurueck + ChgValid( FALSE ); + return ; + } + + pUpdtFld = (SwTableFmlUpdate*)pItem; + + // bestimme die Tabelle, in der das Attribut steht + const SwTableNode* pTblNd; + const SwNode* pNd = GetNodeOfFormula(); + if( pNd && &pNd->GetNodes() == &pNd->GetDoc()->GetNodes() && + 0 != ( pTblNd = pNd->FindTableNode() )) + { + switch( pUpdtFld->eFlags ) + { + case TBL_CALC: + // setze das Value-Flag zurueck + // JP 17.06.96: interne Darstellung auf alle Formeln + // (Referenzen auf andere Tabellen!!!) +// if( VF_CMD & pFld->GetFormat() ) +// pFld->PtrToBoxNm( pUpdtFld->pTbl ); +// else + ChgValid( FALSE ); + break; + case TBL_BOXNAME: + // ist es die gesuchte Tabelle ?? + if( &pTblNd->GetTable() == pUpdtFld->pTbl ) + // zur externen Darstellung + PtrToBoxNm( pUpdtFld->pTbl ); + break; + case TBL_BOXPTR: + // zur internen Darstellung + // JP 17.06.96: interne Darstellung auf alle Formeln + // (Referenzen auf andere Tabellen!!!) + BoxNmToPtr( &pTblNd->GetTable() ); + break; + case TBL_RELBOXNAME: + // ist es die gesuchte Tabelle ?? + if( &pTblNd->GetTable() == pUpdtFld->pTbl ) + // zur relativen Darstellung + ToRelBoxNm( pUpdtFld->pTbl ); + break; + + case TBL_SPLITTBL: + if( &pTblNd->GetTable() == pUpdtFld->pTbl ) + { + USHORT nLnPos = SwTableFormula::GetLnPosInTbl( + pTblNd->GetTable(), GetTableBox() ); + pUpdtFld->bBehindSplitLine = USHRT_MAX != nLnPos && + pUpdtFld->nSplitLine <= nLnPos; + } + else + pUpdtFld->bBehindSplitLine = FALSE; + // kein break + case TBL_MERGETBL: + if( pUpdtFld->pHistory ) + { + // fuer die History brauche ich aber die unveraenderte Formel + SwTblBoxFormula aCopy( *this ); + pUpdtFld->bModified = FALSE; + ToSplitMergeBoxNm( *pUpdtFld ); + + if( pUpdtFld->bModified ) + { + // und dann in der externen Darstellung + aCopy.PtrToBoxNm( &pTblNd->GetTable() ); + pUpdtFld->pHistory->Add( &aCopy, &aCopy, + pNd->FindTableBoxStartNode()->GetIndex() ); + } + } + else + ToSplitMergeBoxNm( *pUpdtFld ); + break; + } + } +} + + +void SwTblBoxFormula::Calc( SwTblCalcPara& rCalcPara, double& rValue ) +{ + if( !rCalcPara.rCalc.IsCalcError() ) // ist schon Fehler gesetzt ? + { + // erzeuge aus den BoxNamen die Pointer + BoxNmToPtr( rCalcPara.pTbl ); + String sFml( MakeFormel( rCalcPara )); + if( !rCalcPara.rCalc.IsCalcError() ) + rValue = rCalcPara.rCalc.Calculate( sFml ).GetDouble(); + else + rValue = DBL_MAX; + ChgValid( !rCalcPara.IsStackOverFlow() ); // der Wert ist wieder gueltig + } +} + +/************************************************************************* +|* +*************************************************************************/ + + +SwTblBoxValue::SwTblBoxValue() + : SfxPoolItem( RES_BOXATR_VALUE ), nValue( 0 ) +{ +} + + +SwTblBoxValue::SwTblBoxValue( const double nVal ) + : SfxPoolItem( RES_BOXATR_VALUE ), nValue( nVal ) +{ +} + + +int SwTblBoxValue::operator==( const SfxPoolItem& rAttr ) const +{ + ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" ); + return nValue == ((SwTblBoxValue&)rAttr).nValue; +} + + +SfxPoolItem* SwTblBoxValue::Clone( SfxItemPool* ) const +{ + return new SwTblBoxValue( nValue ); +} + + + + diff --git a/sw/source/core/attr/format.cxx b/sw/source/core/attr/format.cxx new file mode 100644 index 000000000000..336ae85ded36 --- /dev/null +++ b/sw/source/core/attr/format.cxx @@ -0,0 +1,677 @@ +/************************************************************************* + * + * $RCSfile: format.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:15 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _HINTIDS_HXX +#include // fuer RES_.. +#endif +#ifndef _FRAME_HXX +#include // fuer AttrCache +#endif +#ifndef _FORMAT_HXX +#include +#endif + +#ifndef _HINTS_HXX +#include // fuer SwFmtChg +#endif +#ifndef _PARATR_HXX +#include // fuer SwParaFmt - SwHyphenBug +#endif +#ifndef _SWCACHE_HXX +#include +#endif + + +TYPEINIT1( SwFmt, SwClient ); //rtti fuer SwFmt + +/************************************************************************* +|* SwFmt::SwFmt +*************************************************************************/ + + +SwFmt::SwFmt( SwAttrPool& rPool, const sal_Char* pFmtNm, + const USHORT* pWhichRanges, SwFmt *pDrvdFrm, USHORT nFmtWhich ) + : SwModify( pDrvdFrm ), + aSet( rPool, pWhichRanges ), + nPoolFmtId( USHRT_MAX ), + nPoolHelpId( USHRT_MAX ), + nPoolHlpFileId( UCHAR_MAX ), + nFmtId( 0 ), + nWhichId( nFmtWhich ) +{ + aFmtName.AssignAscii( pFmtNm ); + bWritten = bFmtInDTOR = bAutoUpdateFmt = bLayerFmt = FALSE; // LAYER_IMPL + bAutoFmt = TRUE; + + if( pDrvdFrm ) + aSet.SetParent( &pDrvdFrm->aSet ); +} + + +SwFmt::SwFmt( SwAttrPool& rPool, const String &rFmtNm, + const USHORT* pWhichRanges, SwFmt *pDrvdFrm, USHORT nFmtWhich ) + : SwModify( pDrvdFrm ), + aFmtName( rFmtNm ), + aSet( rPool, pWhichRanges ), + nPoolFmtId( USHRT_MAX ), + nPoolHelpId( USHRT_MAX ), + nPoolHlpFileId( UCHAR_MAX ), + nFmtId( 0 ), + nWhichId( nFmtWhich ) +{ + bWritten = bFmtInDTOR = bAutoUpdateFmt = bLayerFmt = FALSE; // LAYER_IMPL + bAutoFmt = TRUE; + + if( pDrvdFrm ) + aSet.SetParent( &pDrvdFrm->aSet ); +} + + +SwFmt::SwFmt( SwAttrPool& rPool, const String &rFmtNm, USHORT nWhich1, + USHORT nWhich2, SwFmt *pDrvdFrm, USHORT nFmtWhich ) + : SwModify( pDrvdFrm ), + aFmtName( rFmtNm ), + aSet( rPool, nWhich1, nWhich2 ), + nPoolFmtId( USHRT_MAX ), + nPoolHelpId( USHRT_MAX ), + nPoolHlpFileId( UCHAR_MAX ), + nFmtId( 0 ), + nWhichId( nFmtWhich ) +{ + bWritten = bFmtInDTOR = bAutoUpdateFmt = bLayerFmt = FALSE; // LAYER_IMPL + bAutoFmt = TRUE; + if( pDrvdFrm ) + aSet.SetParent( &pDrvdFrm->aSet ); +} + + +SwFmt::SwFmt( const SwFmt& rFmt ) + : SwModify( rFmt.DerivedFrom() ), + aFmtName( rFmt.aFmtName ), + aSet( rFmt.aSet ), + nPoolFmtId( rFmt.GetPoolFmtId() ), + nPoolHelpId( rFmt.GetPoolHelpId() ), + nPoolHlpFileId( rFmt.GetPoolHlpFileId() ), + nFmtId( 0 ), + nWhichId( rFmt.nWhichId ) +{ + bWritten = bFmtInDTOR = bLayerFmt = FALSE; // LAYER_IMPL + bAutoFmt = rFmt.bAutoFmt; + bAutoUpdateFmt = rFmt.bAutoUpdateFmt; + + if( rFmt.DerivedFrom() ) + aSet.SetParent( &rFmt.DerivedFrom()->aSet ); + // einige Sonderbehandlungen fuer Attribute + aSet.SetModifyAtAttr( this ); +} + +/************************************************************************* +|* SwFmt &SwFmt::operator=(const SwFmt& aFmt) +|* +|* Beschreibung Dokument 1.14 +|* Ersterstellung JP 22.11.90 +|* Letzte Aenderung JP 05.08.94 +*************************************************************************/ + + +SwFmt &SwFmt::operator=(const SwFmt& rFmt) +{ + nWhichId = rFmt.nWhichId; + nPoolFmtId = rFmt.GetPoolFmtId(); + nPoolHelpId = rFmt.GetPoolHelpId(); + nPoolHlpFileId = rFmt.GetPoolHlpFileId(); + + if ( IsInCache() ) + { + SwFrm::GetCache().Delete( this ); + SetInCache( FALSE ); + } + SetInSwFntCache( FALSE ); + + // kopiere nur das Attribut-Delta Array + SwAttrSet aOld( *aSet.GetPool(), aSet.GetRanges() ), + aNew( *aSet.GetPool(), aSet.GetRanges() ); + aSet.Intersect_BC( rFmt.aSet, &aOld, &aNew ); + aSet.Put_BC( rFmt.aSet, &aOld, &aNew ); + + // einige Sonderbehandlungen fuer Attribute + aSet.SetModifyAtAttr( this ); + + // PoolItem-Attr erzeugen fuers Modify !!! + if( aOld.Count() ) + { + SwAttrSetChg aChgOld( aSet, aOld ); + SwAttrSetChg aChgNew( aSet, aNew ); + Modify( &aChgOld, &aChgNew ); // alle veraenderten werden verschickt + } + + if( pRegisteredIn != rFmt.pRegisteredIn ) + { + if( pRegisteredIn ) + pRegisteredIn->Remove(this); + if(rFmt.pRegisteredIn) + { + rFmt.pRegisteredIn->Add(this); + aSet.SetParent( &rFmt.aSet ); + } + else + aSet.SetParent( 0 ); + } + bAutoFmt = rFmt.bAutoFmt; + bAutoUpdateFmt = rFmt.bAutoUpdateFmt; + return *this; +} + +/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * diese Funktion wird in jedem Copy-Ctor gerufen, damit die + * Attribute kopiert werden. Diese koennen erst kopiert werden, + * wenn die abgeleitet Klasse existiert, denn beim Setzen der + * Attribute wird die Which()-Methode gerufen, die hier in der + * Basis-Klasse auf 0 defaultet ist. + * + * Zusatz: JP 8.4.1994 + * Wird ueber Dokumentgrenzen kopiert, so muss das neue Dokument + * mit angeben werden, in dem this steht. Z.Z. ist das fuers + * DropCaps wichtig, dieses haelt Daten, die tief kopiert werden + * muessen !! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ + + +void SwFmt::CopyAttrs( const SwFmt& rFmt, BOOL bReplace ) +{ + // kopiere nur das Attribut-Delta Array + register SwCharFmt* pDropCharFmt = 0; + + if ( IsInCache() ) + { + SwFrm::GetCache().Delete( this ); + SetInCache( FALSE ); + } + SetInSwFntCache( FALSE ); + + // Sonderbehandlung fuer einige Attribute + SwAttrSet* pChgSet = (SwAttrSet*)&rFmt.aSet; + + if( !bReplace ) // nur die neu, die nicht gesetzt sind ?? + { + if( pChgSet == (SwAttrSet*)&rFmt.aSet ) // Set hier kopieren + pChgSet = new SwAttrSet( rFmt.aSet ); + pChgSet->Differentiate( aSet ); + } + + // kopiere nur das Attribut-Delta Array + if( pChgSet->GetPool() != aSet.GetPool() ) + pChgSet->CopyToModify( *this ); + else + { + SwAttrSet aOld( *aSet.GetPool(), aSet.GetRanges() ), + aNew( *aSet.GetPool(), aSet.GetRanges() ); + + if ( 0 != aSet.Put_BC( *pChgSet, &aOld, &aNew ) ) + { + // einige Sonderbehandlungen fuer Attribute + aSet.SetModifyAtAttr( this ); + + SwAttrSetChg aChgOld( aSet, aOld ); + SwAttrSetChg aChgNew( aSet, aNew ); + Modify( &aChgOld, &aChgNew ); // alle veraenderten werden verschickt + } + } + + if( pChgSet != (SwAttrSet*)&rFmt.aSet ) // Set hier angelegt ? + delete pChgSet; +} + +/************************************************************************* +|* SwFmt::~SwFmt() +|* +|* Beschreibung Dokument 1.14 +|* Ersterstellung JP 22.11.90 +|* Letzte Aenderung JP 14.02.91 +*************************************************************************/ + + +SwFmt::~SwFmt() +{ + /* das passiert bei der ObjectDying Message */ + /* alle Abhaengigen auf DerivedFrom umhaengen */ + if( GetDepends() ) + { + ASSERT(DerivedFrom(), "SwFmt::~SwFmt: Def Abhaengige!" ); + + bFmtInDTOR = TRUE; + + SwFmt *pParentFmt = DerivedFrom(); + while( GetDepends() ) + { + SwFmtChg aOldFmt(this); + SwFmtChg aNewFmt(pParentFmt); + SwClient * pDepend = (SwClient*)GetDepends(); + pParentFmt->Add(pDepend); + pDepend->Modify(&aOldFmt, &aNewFmt); + } + } +} + + +/************************************************************************* +|* void SwFmt::Modify( SfxPoolItem* pOldValue, SfxPoolItem* pNewValue ) +|* +|* Beschreibung Dokument 1.14 +|* Ersterstellung JP 22.11.90 +|* Letzte Aenderung JP 05.08.94 +*************************************************************************/ + + +void SwFmt::Modify( SfxPoolItem* pOldValue, SfxPoolItem* pNewValue ) +{ + BOOL bWeiter = TRUE; // TRUE = Propagierung an die Abhaengigen + + USHORT nWhich = pOldValue ? pOldValue->Which() : + pNewValue ? pNewValue->Which() : 0 ; + switch( nWhich ) + { + case 0: break; // Which-Id von 0 ??? + + case RES_OBJECTDYING : + { + // ist das sterbende Object das "Parent"-Format von diesen Format, + // dann haengt sich dieses Format an den Parent vom Parent + SwFmt * pFmt = (SwFmt *) ((SwPtrMsgPoolItem *)pNewValue)->pObject; + + // nicht umhaengen wenn dieses das oberste Format ist !! + if( pRegisteredIn && pRegisteredIn == pFmt ) + { + if( pFmt->pRegisteredIn ) + { + // wenn Parent, dann im neuen Parent wieder anmelden + pFmt->DerivedFrom()->Add( this ); + aSet.SetParent( &DerivedFrom()->aSet ); + } + else + { + // sonst auf jeden Fall beim sterbenden abmelden + DerivedFrom()->Remove( this ); + aSet.SetParent( 0 ); + } + } + } // OBJECTDYING + break; + + case RES_ATTRSET_CHG: + if( ((SwAttrSetChg*)pOldValue)->GetTheChgdSet() != &aSet ) + { + //nur die weiter geben, die hier nicht gesetzt sind !! + SwAttrSetChg aOld( *(SwAttrSetChg*)pOldValue ); + SwAttrSetChg aNew( *(SwAttrSetChg*)pNewValue ); + + aOld.GetChgSet()->Differentiate( aSet ); + aNew.GetChgSet()->Differentiate( aSet ); + + if( aNew.Count() ) + // keine mehr gesetzt, dann Ende !! + SwModify::Modify( &aOld, &aNew ); + bWeiter = FALSE; + } + break; + case RES_FMT_CHG: + // falls mein Format Parent umgesetzt wird, dann melde ich + // meinen Attrset beim Neuen an. + + // sein eigenes Modify ueberspringen !! + if( ((SwFmtChg*)pOldValue)->pChangedFmt != this && + ((SwFmtChg*)pNewValue)->pChangedFmt == DerivedFrom() ) + { + // den Set an den neuen Parent haengen + aSet.SetParent( DerivedFrom() ? &DerivedFrom()->aSet : 0 ); + } + break; + + case RES_RESET_FMTWRITTEN: + { + // IsWritten-Flag zuruecksetzen. Hint nur an abhanegige + // Formate (und keine Frames) propagieren. + ResetWritten(); + SwClientIter aIter( *this ); + for( SwClient *pClient = aIter.First( TYPE(SwFmt) ); pClient; + pClient = aIter.Next() ) + pClient->Modify( pOldValue, pNewValue ); + + bWeiter = FALSE; + } + break; + + default: + { + // Ist das Attribut in diesem Format definiert, dann auf + // NICHT weiter propagieren !! + if( SFX_ITEM_SET == aSet.GetItemState( nWhich, FALSE )) + { +// wie finde ich heraus, ob nicht ich die Message versende ?? +// aber wer ruft das hier ???? +//ASSERT( FALSE, "Modify ohne Absender verschickt" ); +//JP 11.06.96: DropCaps koennen hierher kommen +ASSERT( RES_PARATR_DROP == nWhich, "Modify ohne Absender verschickt" ); + bWeiter = FALSE; + } + + } // default + } // switch + + if( bWeiter ) + { + // laufe durch alle abhaengigen Formate + SwModify::Modify( pOldValue, pNewValue ); + } + +} + + +BOOL SwFmt::SetDerivedFrom(SwFmt *pDerFrom) +{ + if ( pDerFrom ) + { + // Zyklus? + const SwFmt* pFmt = pDerFrom; + while ( pFmt != 0 ) + { + if ( pFmt == this ) + return FALSE; + + pFmt=pFmt->DerivedFrom(); + } + } + else + { + // Nichts angegeben, Dflt-Format suchen + pDerFrom = this; + while ( pDerFrom->DerivedFrom() ) + pDerFrom = pDerFrom->DerivedFrom(); + } + if ( (pDerFrom == DerivedFrom()) || (pDerFrom == this) ) + return FALSE; + + ASSERT( Which()==pDerFrom->Which() + || ( Which()==RES_CONDTXTFMTCOLL && pDerFrom->Which()==RES_TXTFMTCOLL) + || ( Which()==RES_TXTFMTCOLL && pDerFrom->Which()==RES_CONDTXTFMTCOLL) + || ( Which()==RES_FLYFRMFMT && pDerFrom->Which()==RES_FRMFMT ), + "SetDerivedFrom: Aepfel von Birnen ableiten?"); + + if ( IsInCache() ) + { + SwFrm::GetCache().Delete( this ); + SetInCache( FALSE ); + } + SetInSwFntCache( FALSE ); + + pDerFrom->Add(this); + aSet.SetParent( &pDerFrom->aSet ); + + SwFmtChg aOldFmt(this); + SwFmtChg aNewFmt(this); + Modify( &aOldFmt, &aNewFmt ); + + return TRUE; +} + + +BOOL SwFmt::SetAttr(const SfxPoolItem& rAttr ) +{ + if ( IsInCache() || IsInSwFntCache() ) + { + const USHORT nWhich = rAttr.Which(); + CheckCaching( nWhich ); + } + + // wenn Modify gelockt ist, werden keine Modifies verschickt; + // fuer FrmFmt's immer das Modify verschicken! + BOOL bRet = FALSE; + USHORT nFmtWhich; + if( IsModifyLocked() || (!GetDepends() && + (RES_GRFFMTCOLL == (nFmtWhich = Which()) || + RES_TXTFMTCOLL == nFmtWhich ) ) ) + { + if( 0 != ( bRet = (0 != aSet.Put( rAttr ))) ) + aSet.SetModifyAtAttr( this ); + } + else + { + // kopiere nur das Attribut-Delta Array + SwAttrSet aOld( *aSet.GetPool(), aSet.GetRanges() ), + aNew( *aSet.GetPool(), aSet.GetRanges() ); + + if( 0 != (bRet = aSet.Put_BC( rAttr, &aOld, &aNew ))) + { + // einige Sonderbehandlungen fuer Attribute + aSet.SetModifyAtAttr( this ); + + SwAttrSetChg aChgOld( aSet, aOld ); + SwAttrSetChg aChgNew( aSet, aNew ); + Modify( &aChgOld, &aChgNew ); // alle veraenderten werden verschickt + } + } + return bRet; +} + + +BOOL SwFmt::SetAttr( const SfxItemSet& rSet ) +{ + if( !rSet.Count() ) + return FALSE; + + if ( IsInCache() ) + { + SwFrm::GetCache().Delete( this ); + SetInCache( FALSE ); + } + SetInSwFntCache( FALSE ); + + // wenn Modify gelockt ist, werden keine Modifies verschickt; + // fuer FrmFmt's immer das Modify verschicken! + BOOL bRet = FALSE; + USHORT nFmtWhich; + if( IsModifyLocked() || (!GetDepends() && + (RES_GRFFMTCOLL == (nFmtWhich = Which()) || + RES_TXTFMTCOLL == nFmtWhich ) ) ) + { + if( 0 != ( bRet = (0 != aSet.Put( rSet ))) ) + aSet.SetModifyAtAttr( this ); + } + else + { + SwAttrSet aOld( *aSet.GetPool(), aSet.GetRanges() ), + aNew( *aSet.GetPool(), aSet.GetRanges() ); + if( 0 != ( bRet = aSet.Put_BC( rSet, &aOld, &aNew ) ) ) + { + // einige Sonderbehandlungen fuer Attribute + aSet.SetModifyAtAttr( this ); + SwAttrSetChg aChgOld( aSet, aOld ); + SwAttrSetChg aChgNew( aSet, aNew ); + Modify( &aChgOld, &aChgNew ); // alle veraenderten werden verschickt + } + } + return bRet; +} + +// Nimmt den Hint mit nWhich aus dem Delta-Array + + +BOOL SwFmt::ResetAttr( USHORT nWhich1, USHORT nWhich2 ) +{ + if( !aSet.Count() ) + return FALSE; + + if( !nWhich2 || nWhich2 < nWhich1 ) + nWhich2 = nWhich1; // dann setze auf 1. Id, nur dieses Item + + if ( IsInCache() || IsInSwFntCache() ) + { + for( USHORT n = nWhich1; n < nWhich2; ++n ) + CheckCaching( n ); + } + + // wenn Modify gelockt ist, werden keine Modifies verschickt + if( IsModifyLocked() ) + return 0 != (( nWhich2 == nWhich1 ) + ? aSet.ClearItem( nWhich1 ) + : aSet.ClearItem_BC( nWhich1, nWhich2 )); + + SwAttrSet aOld( *aSet.GetPool(), aSet.GetRanges() ), + aNew( *aSet.GetPool(), aSet.GetRanges() ); + BOOL bRet = 0 != aSet.ClearItem_BC( nWhich1, nWhich2, &aOld, &aNew ); + + if( bRet ) + { + SwAttrSetChg aChgOld( aSet, aOld ); + SwAttrSetChg aChgNew( aSet, aNew ); + Modify( &aChgOld, &aChgNew ); // alle veraenderten werden verschickt + } + return bRet; +} + + + +USHORT SwFmt::ResetAllAttr() +{ + if( !aSet.Count() ) + return 0; + + if ( IsInCache() ) + { + SwFrm::GetCache().Delete( this ); + SetInCache( FALSE ); + } + SetInSwFntCache( FALSE ); + + // wenn Modify gelockt ist, werden keine Modifies verschickt + if( IsModifyLocked() ) + return aSet.ClearItem( 0 ); + + SwAttrSet aOld( *aSet.GetPool(), aSet.GetRanges() ), + aNew( *aSet.GetPool(), aSet.GetRanges() ); + BOOL bRet = 0 != aSet.ClearItem_BC( 0, &aOld, &aNew ); + + if( bRet ) + { + SwAttrSetChg aChgOld( aSet, aOld ); + SwAttrSetChg aChgNew( aSet, aNew ); + Modify( &aChgOld, &aChgNew ); // alle veraenderten werden verschickt + } + return aNew.Count(); +} + + +/************************************************************************* +|* void SwFmt::GetInfo( const SfxPoolItem& ) const +|* +|* Beschreibung +|* Ersterstellung JP 18.04.94 +|* Letzte Aenderung JP 05.08.94 +*************************************************************************/ + + +BOOL SwFmt::GetInfo( SfxPoolItem& rInfo ) const +{ + BOOL bRet = SwModify::GetInfo( rInfo ); + return bRet; +} + + +void SwFmt::DelDiffs( const SfxItemSet& rSet ) +{ + if( !aSet.Count() ) + return; + + if ( IsInCache() ) + { + SwFrm::GetCache().Delete( this ); + SetInCache( FALSE ); + } + SetInSwFntCache( FALSE ); + + // wenn Modify gelockt ist, werden keine Modifies verschickt + if( IsModifyLocked() ) + { + aSet.Intersect( rSet ); + return; + } + + SwAttrSet aOld( *aSet.GetPool(), aSet.GetRanges() ), + aNew( *aSet.GetPool(), aSet.GetRanges() ); + BOOL bRet = 0 != aSet.Intersect_BC( rSet, &aOld, &aNew ); + + if( bRet ) + { + SwAttrSetChg aChgOld( aSet, aOld ); + SwAttrSetChg aChgNew( aSet, aNew ); + Modify( &aChgOld, &aChgNew ); // alle veraenderten werden verschickt + } +} + + + + diff --git a/sw/source/core/attr/hints.cxx b/sw/source/core/attr/hints.cxx new file mode 100644 index 000000000000..9f1ecc4e04cd --- /dev/null +++ b/sw/source/core/attr/hints.cxx @@ -0,0 +1,299 @@ +/************************************************************************* + * + * $RCSfile: hints.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:15 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + + +#ifndef _HINTIDS_HXX +#include +#endif +#ifndef _SWTYPES_HXX +#include +#endif +#ifndef _NDTXT_HXX +#include +#endif +#ifndef _ERRHDL_HXX +#include +#endif +#ifndef _HINTS_HXX +#include +#endif +#ifndef _SWERROR_H +#include +#endif + + + +SwFmtChg::SwFmtChg( SwFmt *pFmt ) + : SwMsgPoolItem( RES_FMT_CHG ), + pChangedFmt( pFmt ) +{} + + +SwInsChr::SwInsChr( xub_StrLen nP ) + : SwMsgPoolItem( RES_INS_CHR ), + nPos( nP ) +{} + + + +SwInsTxt::SwInsTxt( xub_StrLen nP, xub_StrLen nL ) + : SwMsgPoolItem( RES_INS_TXT ), + nPos( nP ), + nLen( nL ) +{} + + + +SwDelChr::SwDelChr( xub_StrLen nP ) + : SwMsgPoolItem( RES_DEL_CHR ), + nPos( nP ) +{} + + + +SwDelTxt::SwDelTxt( xub_StrLen nS, xub_StrLen nL ) + : SwMsgPoolItem( RES_DEL_TXT ), + nStart( nS ), + nLen( nL ) +{} + + + +SwUpdateAttr::SwUpdateAttr( xub_StrLen nS, xub_StrLen nE, USHORT nW ) + : SwMsgPoolItem( RES_UPDATE_ATTR ), + nStart( nS ), + nEnd( nE ), + nWhichAttr( nW ) +{} + + +// SwRefMarkFldUpdate wird verschickt, wenn sich die ReferenzMarkierungen +// Updaten sollen. Um Seiten-/KapitelNummer feststellen zu koennen, muss +// der akt. Frame befragt werden. Dafuer wird das akt. OutputDevice benoetigt. + + +SwRefMarkFldUpdate::SwRefMarkFldUpdate( const OutputDevice* pOutput ) + : SwMsgPoolItem( RES_REFMARKFLD_UPDATE ), + pOut( pOutput ) +{ + ASSERT( pOut, "es muss ein OutputDevice-Pointer gesetzt werden!" ); +} + + +SwDocPosUpdate::SwDocPosUpdate( const SwTwips nDocPos ) + : SwMsgPoolItem( RES_DOCPOS_UPDATE ), + nDocPos(nDocPos) +{} + + + +// SwTableFmlUpdate wird verschickt, wenn sich die Tabelle neu berechnen soll +SwTableFmlUpdate::SwTableFmlUpdate( const SwTable* pNewTbl ) + : SwMsgPoolItem( RES_TABLEFML_UPDATE ), + pTbl( pNewTbl ), pHistory( 0 ), eFlags( TBL_CALC ), + nSplitLine( USHRT_MAX ) +{ + DATA.pDelTbl = 0; + bModified = bBehindSplitLine = FALSE; + ASSERT( pTbl, "es muss ein Table-Pointer gesetzt werden!" ); +} + + +SwAutoFmtGetDocNode::SwAutoFmtGetDocNode( const SwNodes* pNds ) + : SwMsgPoolItem( RES_AUTOFMT_DOCNODE ), + pCntntNode( 0 ), pNodes( pNds ) +{} + + +SwAttrSetChg::SwAttrSetChg( const SwAttrSet& rTheSet, SwAttrSet& rSet ) + : SwMsgPoolItem( RES_ATTRSET_CHG ), + pTheChgdSet( &rTheSet ), + pChgSet( &rSet ), + bDelSet( FALSE ) +{} + + +SwAttrSetChg::SwAttrSetChg( const SwAttrSetChg& rChgSet ) + : SwMsgPoolItem( RES_ATTRSET_CHG ), + pTheChgdSet( rChgSet.pTheChgdSet ), + bDelSet( TRUE ) +{ + pChgSet = new SwAttrSet( *rChgSet.pChgSet ); +} + + +SwAttrSetChg::~SwAttrSetChg() +{ + if( bDelSet ) + delete pChgSet; +} + + +#ifndef PRODUCT + +void SwAttrSetChg::ClearItem( USHORT nWhich ) +{ + ASSERT( bDelSet, "der Set darf nicht veraendert werden!" ); + pChgSet->ClearItem( nWhich ); +} + +#endif + + +SwMsgPoolItem::SwMsgPoolItem( USHORT nWhich ) + : SfxPoolItem( nWhich ) +{} + + +// "Overhead" vom SfxPoolItem +int SwMsgPoolItem::operator==( const SfxPoolItem& ) const +{ + ASSERT( FALSE, "SwMsgPoolItem kennt kein ==" ); + return 0; +} + + +SfxPoolItem* SwMsgPoolItem::Clone( SfxItemPool* ) const +{ + ASSERT( FALSE, "SwMsgPoolItem kennt kein Clone" ); + return 0; +} + +/****************************************************************************** + * hole aus der Default-Attribut Tabelle ueber den Which-Wert + * das entsprechende default Attribut. + * Ist keines vorhanden, returnt ein 0-Pointer !!! + * inline (hintids.hxx) im PRODUCT. + ******************************************************************************/ +#ifndef PRODUCT + + +const SfxPoolItem* GetDfltAttr( USHORT nWhich ) +{ + ASSERT_ID( nWhich < POOLATTR_END && nWhich >= POOLATTR_BEGIN, + ERR_OUTOFSCOPE ); + + SfxPoolItem *pHt = aAttrTab[ nWhich - POOLATTR_BEGIN ]; + ASSERT( pHt, "GetDfltFmtAttr(): Dflt == 0" ); + return pHt; +} + +#endif + + + +SwCondCollCondChg::SwCondCollCondChg( SwFmt *pFmt ) + : SwMsgPoolItem( RES_CONDCOLL_CONDCHG ), pChangedFmt( pFmt ) +{ +} + + +SwVirtPageNumInfo::SwVirtPageNumInfo( const SwPageFrm *pPg ) : + SwMsgPoolItem( RES_VIRTPAGENUM_INFO ), + pPage( 0 ), + pOrigPage( pPg ), + pFrm( 0 ) +{ +} + +SwNumRuleInfo::SwNumRuleInfo( const String& rRuleName ) + : SwMsgPoolItem( RES_GETNUMNODES ), rName( rRuleName ) +{ +} + +void SwNumRuleInfo::AddNode( SwTxtNode& rNd ) +{ + aList.Insert( rNd.GetIndex(), &rNd ); +} + +SwNRuleLowerLevel::SwNRuleLowerLevel( const String& rRuleName, BYTE nSrchLvl ) + : SwMsgPoolItem( RES_GETLOWERNUMLEVEL ), rName( rRuleName ), + nLvl(nSrchLvl) +{ +} + + +SwFindNearestNode::SwFindNearestNode( const SwNode& rNd ) + : SwMsgPoolItem( RES_FINDNEARESTNODE ), pNd( &rNd ), pFnd( 0 ) +{ +} + +void SwFindNearestNode::CheckNode( const SwNode& rNd ) +{ + if( &pNd->GetNodes() == &rNd.GetNodes() ) + { + ULONG nIdx = rNd.GetIndex(); + if( nIdx < pNd->GetIndex() && + ( !pFnd || nIdx > pFnd->GetIndex() ) && + nIdx > rNd.GetNodes().GetEndOfExtras().GetIndex() ) + pFnd = &rNd; + } +} + + + + diff --git a/sw/source/core/attr/makefile.mk b/sw/source/core/attr/makefile.mk new file mode 100644 index 000000000000..b6d3f04314a1 --- /dev/null +++ b/sw/source/core/attr/makefile.mk @@ -0,0 +1,101 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-19 00:08:15 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (the "License"); You may not use this file +# except in compliance with the License. You may obtain a copy of the +# License at http://www.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=sw +TARGET=attr + +AUTOSEG=true + +PROJECTPCH=core_pch +PDBTARGET=core_pch +PROJECTPCHSOURCE=..\core_1st\core_pch + +# --- Settings ----------------------------------------------------- + +.INCLUDE : $(PRJ)$/inc$/swpre.mk +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/inc$/sw.mk + +# --- Files -------------------------------------------------------- + +CXXFILES = \ + calbck.cxx \ + cellatr.cxx \ + format.cxx \ + hints.cxx \ + swatrset.cxx + + + +SLOFILES = \ + $(SLO)$/calbck.obj \ + $(SLO)$/cellatr.obj \ + $(SLO)$/format.obj \ + $(SLO)$/hints.obj \ + $(SLO)$/swatrset.obj + +# --- Tagets ------------------------------------------------------- + +.INCLUDE : target.mk + diff --git a/sw/source/core/attr/swatrset.cxx b/sw/source/core/attr/swatrset.cxx new file mode 100644 index 000000000000..62c783e17d71 --- /dev/null +++ b/sw/source/core/attr/swatrset.cxx @@ -0,0 +1,380 @@ +/************************************************************************* + * + * $RCSfile: swatrset.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:15 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#include + +#ifndef _SVX_COLRITEM_HXX //autogen +#include +#endif +#ifndef _SVX_BRSHITEM_HXX //autogen +#include +#endif +#define ITEMID_LINE SID_ATTR_LINE_STYLE +#ifndef _SVX_BOLNITEM_HXX //autogen +#include +#endif +#ifndef _SVX_BOXITEM_HXX //autogen +#include +#endif +#ifndef _XTABLE_HXX //autogen +#include +#endif +#ifndef _OFF_APP_HXX //autogen +#include +#endif + +#ifndef _FMTPDSC_HXX //autogen +#include +#endif +#ifndef _PAGEDESC_HXX //autogen +#include +#endif +#ifndef _CHARFMT_HXX +#include +#endif +#ifndef _DOC_HXX +#include +#endif +#ifndef _NODE_HXX //autogen +#include +#endif +#ifndef _FORMAT_HXX //autogen +#include +#endif +#ifndef _SWATRSET_HXX +#include +#endif +#ifndef _PARATR_HXX +#include // fuer SetModifyAtAttr +#endif +#ifndef _CELLATR_HXX +#include // fuer SetModifyAtAttr +#endif +#ifndef _CMDID_H +#include +#endif + + +SwAttrPool::SwAttrPool( SwDoc* pD ) + : SfxItemPool( String::CreateFromAscii( + RTL_CONSTASCII_STRINGPARAM( "SWG" )), + POOLATTR_BEGIN, POOLATTR_END-1, + aSlotTab, aAttrTab ), + pDoc( pD ) +{ + SetVersionMap( 1, 1, 60, pVersionMap1 ); + SetVersionMap( 2, 1, 75, pVersionMap2 ); + SetVersionMap( 3, 1, 86, pVersionMap3 ); +} + + +SwAttrSet::SwAttrSet( SwAttrPool& rPool, USHORT nWh1, USHORT nWh2 ) + : SfxItemSet( rPool, nWh1, nWh2 ), pOldSet( 0 ), pNewSet( 0 ) +{ +} + + +SwAttrSet::SwAttrSet( SwAttrPool& rPool, const USHORT* nWhichPairTable ) + : SfxItemSet( rPool, nWhichPairTable ), pOldSet( 0 ), pNewSet( 0 ) +{ +} + + +SwAttrSet::SwAttrSet( const SwAttrSet& rSet ) + : SfxItemSet( rSet ), pOldSet( 0 ), pNewSet( 0 ) +{ +} + + +int SwAttrSet::Put_BC( const SfxPoolItem& rAttr, + SwAttrSet* pOld, SwAttrSet* pNew ) +{ + pNewSet = pNew; + pOldSet = pOld; + int nRet = 0 != SfxItemSet::Put( rAttr ); + pOldSet = pNewSet = 0; + return nRet; +} + + +int SwAttrSet::Put_BC( const SfxItemSet& rSet, + SwAttrSet* pOld, SwAttrSet* pNew ) +{ + pNewSet = pNew; + pOldSet = pOld; + int nRet = 0 != SfxItemSet::Put( rSet ); + pOldSet = pNewSet = 0; + return nRet; +} + + + +USHORT SwAttrSet::ClearItem_BC( USHORT nWhich, + SwAttrSet* pOld, SwAttrSet* pNew ) +{ + pNewSet = pNew; + pOldSet = pOld; + USHORT nRet = SfxItemSet::ClearItem( nWhich ); + pOldSet = pNewSet = 0; + return nRet; +} + + +USHORT SwAttrSet::ClearItem_BC( USHORT nWhich1, USHORT nWhich2, + SwAttrSet* pOld, SwAttrSet* pNew ) +{ + ASSERT( nWhich1 <= nWhich2, "kein gueltiger Bereich" ); + pNewSet = pNew; + pOldSet = pOld; + USHORT nRet = 0; + for( ; nWhich1 <= nWhich2; ++nWhich1 ) + nRet += SfxItemSet::ClearItem( nWhich1 ); + pOldSet = pNewSet = 0; + return nRet; +} + + + +int SwAttrSet::Intersect_BC( const SfxItemSet& rSet, + SwAttrSet* pOld, SwAttrSet* pNew ) +{ + pNewSet = pNew; + pOldSet = pOld; + SfxItemSet::Intersect( rSet ); + pOldSet = pNewSet = 0; + return pNew ? pNew->Count() : ( pOld ? pOld->Count() : 0 ); +} + + +int SwAttrSet::Differentiate_BC( const SfxItemSet& rSet, + SwAttrSet* pOld, SwAttrSet* pNew ) +{ + pNewSet = pNew; + pOldSet = pOld; + SfxItemSet::Differentiate( rSet ); + pOldSet = pNewSet = 0; + return pNew ? pNew->Count() : ( pOld ? pOld->Count() : 0 ); +} + + +int SwAttrSet::MergeValues_BC( const SfxItemSet& rSet, + SwAttrSet* pOld, SwAttrSet* pNew ) +{ + pNewSet = pNew; + pOldSet = pOld; + SfxItemSet::MergeValues( rSet ); + pOldSet = pNewSet = 0; + return pNew ? pNew->Count() : ( pOld ? pOld->Count() : 0 ); +} + + + // Notification-Callback +void SwAttrSet::Changed( const SfxPoolItem& rOld, + const SfxPoolItem& rNew ) +{ + if( pOldSet ) + pOldSet->PutChgd( rOld ); + + if( pNewSet ) + pNewSet->PutChgd( rNew ); +} + + +// ---------------------------------------------------------------- +// Sonderbehandlung fuer einige Attribute +// Setze den Modify-Pointer (alten pDefinedIn) bei folgenden Attributen: +// - SwFmtDropCaps +// - SwFmtPageDesc +// (Wird beim Einfuegen in Formate/Nodes gerufen) +// ---------------------------------------------------------------- +void SwAttrSet::SetModifyAtAttr( const SwModify* pModify ) +{ + const SfxPoolItem* pItem; + if( SFX_ITEM_SET == GetItemState( RES_PAGEDESC, FALSE, &pItem ) && + ((SwFmtPageDesc*)pItem)->GetDefinedIn() != pModify ) + { + ((SwFmtPageDesc*)pItem)->ChgDefinedIn( pModify ); + } + + if( SFX_ITEM_SET == GetItemState( RES_PARATR_NUMRULE, FALSE, &pItem ) && + ((SwNumRuleItem*)pItem)->GetDefinedIn() != pModify ) + { + ((SwNumRuleItem*)pItem)->ChgDefinedIn( pModify ); + } + + if( SFX_ITEM_SET == GetItemState( RES_PARATR_DROP, FALSE, &pItem ) && + ((SwFmtDrop*)pItem)->GetDefinedIn() != pModify ) + { + // CharFormat gesetzt und dann noch in unterschiedlichen + // Attribut Pools, dann muss das CharFormat kopiert werden! + SwCharFmt* pCharFmt; + if( 0 != ( pCharFmt = ((SwFmtDrop*)pItem)->GetCharFmt() ) + && GetPool() != pCharFmt->GetAttrSet().GetPool() ) + { + pCharFmt = GetDoc()->CopyCharFmt( *pCharFmt ); + ((SwFmtDrop*)pItem)->SetCharFmt( pCharFmt ); + } + ((SwFmtDrop*)pItem)->ChgDefinedIn( pModify ); + } + + if( SFX_ITEM_SET == GetItemState( RES_BOXATR_FORMULA, FALSE, &pItem ) && + ((SwTblBoxFormula*)pItem)->GetDefinedIn() != pModify ) + { + ((SwTblBoxFormula*)pItem)->ChgDefinedIn( pModify ); + } +} + + +void SwAttrSet::CopyToModify( SwModify& rMod ) const +{ + // kopiere die Attribute ggfs. ueber Dokumentgrenzen + SwCntntNode* pCNd = PTR_CAST( SwCntntNode, &rMod ); + SwFmt* pFmt = PTR_CAST( SwFmt, &rMod ); + + if( pCNd || pFmt ) + { + if( Count() ) + { + const SfxPoolItem* pItem; + const SwDoc *pSrcDoc = GetDoc(); + SwDoc *pDstDoc = pCNd ? pCNd->GetDoc() : pFmt->GetDoc(); + + // muss die NumRule kopiert werden? + if( pSrcDoc != pDstDoc && SFX_ITEM_SET == GetItemState( + RES_PARATR_NUMRULE, FALSE, &pItem ) ) + { + const String& rNm = ((SwNumRuleItem*)pItem)->GetValue(); + if( rNm.Len() ) + { + SwNumRule* pDestRule = pDstDoc->FindNumRulePtr( rNm ); + if( pDestRule ) + pDestRule->SetInvalidRule( TRUE ); + else + pDstDoc->MakeNumRule( rNm, + pSrcDoc->FindNumRulePtr( rNm ) ); + } + } + + // JP 04.02.99: Task #61467# Seitenvorlagenwechsel mit kopieren + // Gegenueber dem alten Verhalten, sie zu entfernen + const SwPageDesc* pPgDesc; + if( pSrcDoc != pDstDoc && SFX_ITEM_SET == GetItemState( + RES_PAGEDESC, FALSE, &pItem ) && + 0 != ( pPgDesc = ((SwFmtPageDesc*)pItem)->GetPageDesc()) ) + { + SfxItemSet aTmpSet( *this ); + + // JP 09.02.99: und jetzt doch wieder nur entfernen + aTmpSet.ClearItem( RES_PAGEDESC ); + +/************************************************************************* + SwPageDesc* pDstPgDesc = pDstDoc->FindPageDescByName( + pPgDesc->GetName() ); + if( !pDstPgDesc ) + { + // dann kopieren, ansonsten den benutzen + pDstPgDesc = &pDstDoc->_GetPageDesc( pDstDoc->MakePageDesc( + pPgDesc->GetName() )); + pDstDoc->CopyPageDesc( *pPgDesc, *pDstPgDesc ); + } + SwFmtPageDesc aDesc( pDstPgDesc ); + aDesc.SetNumOffset( ((SwFmtPageDesc*)pItem)->GetNumOffset() ); + aTmpSet.Put( aDesc ); +************************************************************************/ + + if( pCNd ) + pCNd->SetAttr( aTmpSet ); + else + pFmt->SetAttr( aTmpSet ); + } + else if( pCNd ) + pCNd->SetAttr( *this ); + else + pFmt->SetAttr( *this ); + } + } +#ifndef PRODUCT + else + ASSERT( !this, "weder Format noch ContentNode - keine Attribute kopiert"); +#endif +} + +// check if ID is InRange of AttrSet-Ids +BOOL IsInRange( const USHORT* pRange, const USHORT nId ) +{ + while( *pRange ) + { + if( *pRange <= nId && nId <= *(pRange+1) ) + return TRUE; + pRange += 2; + } + return FALSE; +} + + + + diff --git a/sw/source/core/bastyp/bparr.cxx b/sw/source/core/bastyp/bparr.cxx new file mode 100644 index 000000000000..f4bea49f78bd --- /dev/null +++ b/sw/source/core/bastyp/bparr.cxx @@ -0,0 +1,634 @@ +/************************************************************************* + * + * $RCSfile: bparr.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:16 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#include +#include +#include "bparr.hxx" + +// die Blockverwaltung waechst/schrumpft immer um 20 Bloecke, das sind dann +// immer ~ 20 * MAXENTRY == 20000 Eintraege +const USHORT nBlockGrowSize = 20; + +#ifdef PRODUCT + +#define CHECKIDX( p, n, i, c ) + +#else + +#define CHECKIDX( p, n, i, c ) CheckIdx( p, n, i, c ); + +void CheckIdx( BlockInfo** ppInf, USHORT nBlock, ULONG nSize, USHORT nCur ) +{ + DBG_ASSERT( !nSize || nCur < nBlock, "BigPtrArray: CurIndex steht falsch" ); + + ULONG nIdx = 0; + for( USHORT nCnt = 0; nCnt < nBlock; ++nCnt, ++ppInf ) + { + nIdx += (*ppInf)->nElem; + // Array mit Luecken darf es nicht geben + DBG_ASSERT( !nCnt || (*(ppInf-1))->nEnd + 1 == (*ppInf)->nStart, + "BigPtrArray: Luecke in der Verwaltung!" ); + } + + DBG_ASSERT( nIdx == nSize, "BigPtrArray: Anzahl ungueltig" ); +} + +#endif + + +BigPtrArray::BigPtrArray() +{ + nBlock = nCur = 0; + nSize = 0; + nMaxBlock = nBlockGrowSize; // == 20 * 1000 Eintraege + ppInf = new BlockInfo* [ nMaxBlock ]; +} + + + +BigPtrArray::~BigPtrArray() +{ + if( nBlock ) + { + BlockInfo** pp = ppInf; + for( USHORT n = 0; n < nBlock; ++n, ++pp ) + { + __DELETE( (*pp)->nElem ) (*pp)->pData; + delete *pp; + } + } + __DELETE( nMaxBlock ) ppInf; +} + +// Einfachst-Implementation, evtl. spaeter mal komplexer +#if 0 +void BigPtrArray::Insert( const ElementPtr* p, ULONG pos, ULONG n ) +{ + while( n-- ) + Insert( *p++, pos++ ); +} +#endif + +// Auch der Move ist schlicht. Optimieren ist hier wg. der +// Stueckelung des Feldes zwecklos! + +void BigPtrArray::Move( ULONG from, ULONG to ) +{ + USHORT cur = Index2Block( from ); + BlockInfo* p = ppInf[ cur ]; + ElementPtr pElem = p->pData[ from - p->nStart ]; + Insert( pElem, to ); // erst einfuegen, dann loeschen !!!! + Remove( ( to < from ) ? ( from + 1 ) : from ); +} + +// das Ende ist EXCLUSIV + + +void BigPtrArray::ForEach( ULONG nStart, ULONG nEnd, + FnForEach fn, void* pArgs ) +{ + if( nEnd > nSize ) + nEnd = nSize; + + if( nStart < nEnd ) + { + USHORT cur = Index2Block( nStart ); + BlockInfo** pp = ppInf + cur; + BlockInfo* p = *pp; + USHORT nElem = USHORT( nStart - p->nStart ); + ElementPtr* pElem = p->pData + nElem; + nElem = p->nElem - nElem; + for(;;) + { + if( !(*fn)( *pElem++, pArgs ) || ++nStart >= nEnd ) + break; + + // naechstes Element + if( !--nElem ) + { + // neuer Block + p = *++pp; + pElem = p->pData; + nElem = p->nElem; + } + } + } +} + + +ElementPtr BigPtrArray::operator[]( ULONG idx ) const +{ + // weil die Funktion eben doch nicht const ist: + DBG_ASSERT( idx < nSize, "operator[]: Index aussserhalb" ); + BigPtrArray* pThis = (BigPtrArray*) this; + USHORT cur = Index2Block( idx ); + BlockInfo* p = ppInf[ cur ]; + pThis->nCur = cur; + return p->pData[ idx - p->nStart ]; +} + +/////////////////////////////////////////////////////////////////////////// + +// private Methoden + +// Suchen des Blocks einer bestimmten Position +// Algorithmus: +// 1. Test, ob der letzte Block der gesuchte Block ist +// 2. Sonderfall: Index = 0? +// 3. Test der Nachbarbloecke + +// 4. Binaere Suche + + + +USHORT BigPtrArray::Index2Block( ULONG pos ) const +{ + // zuletzt verwendeter Block? + BlockInfo* p = ppInf[ nCur ]; + if( p->nStart <= pos && p->nEnd >= pos ) + return nCur; + // Index = 0? + if( !pos ) + return 0; + // Folgeblock? + if( nCur < ( nBlock - 1 ) ) + { + p = ppInf[ nCur+1 ]; + if( p->nStart <= pos && p->nEnd >= pos ) + return nCur+1; + } + // vorangehender Block? + else if( pos < p->nStart && nCur > 0 ) + { + p = ppInf[ nCur-1 ]; + if( p->nStart <= pos && p->nEnd >= pos ) + return nCur-1; + } + // Binaere Suche: + // Diese fuehrt immer zum Erfolg + USHORT lower = 0, upper = nBlock - 1; + USHORT cur = 0; + for(;;) + { + USHORT n = lower + ( upper - lower ) / 2; + cur = ( n == cur ) ? n+1 : n; + p = ppInf[ cur ]; + if( p->nStart <= pos && p->nEnd >= pos ) + return cur; + if( p->nStart > pos ) + upper = cur; + else + lower = cur; + } +} + + +// Update aller Indexbereiche ab einer bestimmten Position + +// pos bezeichnet den letzten korrekten Block + +void BigPtrArray::UpdIndex( USHORT pos ) +{ + BlockInfo** pp = ppInf + pos; + ULONG idx = (*pp)->nEnd + 1; + BlockInfo* p; + while( ++pos < nBlock ) + { + p = *++pp; + p->nStart = idx; + idx += p->nElem; + p->nEnd = idx - 1; + } +} + +// Einrichten eines neuen Blocks an einer bestimmten Position + +// Vorhandene Blocks werden nach hinten verschoben + + + +BlockInfo* BigPtrArray::InsBlock( USHORT pos ) +{ + if( nBlock == nMaxBlock ) + { + // dann sollte wir mal das Array erweitern + BlockInfo** ppNew = new BlockInfo* [ nMaxBlock + nBlockGrowSize ]; + memcpy( ppNew, ppInf, nMaxBlock * sizeof( BlockInfo* )); + __DELETE( nMaxBlock ) ppInf; + nMaxBlock += nBlockGrowSize; + ppInf = ppNew; + } + if( pos != nBlock ) + memmove( ppInf + pos+1, ppInf + pos , + ( nBlock - pos ) * sizeof (BlockInfo*) ); + ++nBlock; + BlockInfo* p = new BlockInfo; + ppInf[ pos ] = p; + + if( pos ) + p->nStart = p->nEnd = ppInf[ pos-1 ]->nEnd + 1; + else + p->nStart = p->nEnd = 0; + p->nEnd--; // keine Elemente + p->nElem = 0; + p->pData = new ElementPtr [ MAXENTRY ]; + p->pBigArr = this; + return p; +} + +void BigPtrArray::BlockDel( USHORT nDel ) +{ + nBlock -= nDel; + if( nMaxBlock - nBlock > nBlockGrowSize ) + { + // dann koennen wir wieder schrumpfen + nDel = (( nBlock / nBlockGrowSize ) + 1 ) * nBlockGrowSize; + BlockInfo** ppNew = new BlockInfo* [ nDel ]; + memcpy( ppNew, ppInf, nBlock * sizeof( BlockInfo* )); + __DELETE( nMaxBlock ) ppInf; + ppInf = ppNew; + nMaxBlock = nDel; + } +} + + +void BigPtrArray::Insert( const ElementPtr& rElem, ULONG pos ) +{ + CHECKIDX( ppInf, nBlock, nSize, nCur ); + + BlockInfo* p; + USHORT cur; + if( !nSize ) + // Sonderfall: erstes Element einfuegen + p = InsBlock( cur = 0 ); + else if( pos == nSize ) + { + // Sonderfall: Einfuegen am Ende + cur = nBlock - 1; + p = ppInf[ cur ]; + if( p->nElem == MAXENTRY ) + // Der letzte Block ist voll, neuen anlegen + p = InsBlock( ++cur ); + } + else + { + // Standardfall: + cur = Index2Block( pos ); + p = ppInf[ cur ]; + } + if( p->nElem == MAXENTRY ) + { + // passt der letzte Eintrag in den naechsten Block? + BlockInfo* q; + if( cur < ( nBlock - 1 ) && ppInf[ cur+1 ]->nElem < MAXENTRY ) + { + q = ppInf[ cur+1 ]; + if( q->nElem ) + { + register int nCount = q->nElem; + register ElementPtr *pFrom = q->pData + nCount, + *pTo = pFrom+1; + while( nCount-- ) + ++( *--pTo = *--pFrom )->nOffset; + } + q->nStart--; + q->nEnd--; + } + else + { + // Wenn er auch nicht in den Folgeblock passt, muss ein + // neuer Block eingefuegt werden + // erst mal bei Bedarf komprimieren + + // wenn mehr als 50% "Luft" im Array ist, dann sollte man mal das + // Compress aufrufen + if( /*nBlock == nMaxBlock &&*/ + nBlock > ( nSize / ( MAXENTRY / 2 ) ) && + cur >= Compress() ) + { + // es wurde vor der akt. Pos etwas verschoben und alle + // Pointer koennen ungueltig sein. Also das Insert + // nochmals aufsetzen + Insert( rElem, pos ); + return ; + } + + q = InsBlock( cur+1 ); + } + + // Eintrag passt nicht mehr. Dann muss Platz gemacht werden + ElementPtr pLast = p->pData[ MAXENTRY-1 ]; + pLast->nOffset = 0; + pLast->pBlock = q; + + q->pData[ 0 ] = pLast; + q->nElem++; + q->nEnd++; + + p->nEnd--; + p->nElem--; + } + // Nun haben wir einen freien Block am Wickel: eintragen + pos -= p->nStart; + DBG_ASSERT( pos < MAXENTRY, "falsche Pos" ); + if( pos != p->nElem ) + { + register int nCount = p->nElem - USHORT(pos); + register ElementPtr *pFrom = p->pData + p->nElem, + *pTo = pFrom + 1; + while( nCount-- ) + ++( *--pTo = *--pFrom )->nOffset; + } + // Element eintragen und Indexe updaten + ((ElementPtr&)rElem)->nOffset = USHORT(pos); + ((ElementPtr&)rElem)->pBlock = p; + p->pData[ pos ] = rElem; + p->nEnd++; + p->nElem++; + nSize++; + if( cur != ( nBlock - 1 ) ) UpdIndex( cur ); + nCur = cur; + + CHECKIDX( ppInf, nBlock, nSize, nCur ); +} + +void BigPtrArray::Remove( ULONG pos, ULONG n ) +{ + CHECKIDX( ppInf, nBlock, nSize, nCur ); + + USHORT nBlkdel = 0; // entfernte Bloecke + USHORT cur = Index2Block( pos ); // aktuelle Blocknr + USHORT nBlk1 = cur; // 1. behandelter Block + USHORT nBlk1del = USHRT_MAX; // 1. entfernter Block + BlockInfo* p = ppInf[ cur ]; + pos -= p->nStart; + ULONG nElem = n; + while( nElem ) + { + USHORT nel = p->nElem - USHORT(pos); + if( ULONG(nel) > nElem ) + nel = USHORT(nElem); + // Eventuell Elemente verschieben + if( ( pos + nel ) < ULONG(p->nElem) ) + { + register ElementPtr *pTo = p->pData + pos, + *pFrom = pTo + nel; + register int nCount = p->nElem - nel - USHORT(pos); + while( nCount-- ) + { + (*pTo++ = *pFrom++)->nOffset -= nel; +// (*pTo++)->nOffset -= nel; + } + } + p->nEnd -= nel; + p->nElem -= nel; + if( !p->nElem ) + { + // eventuell Block ganz entfernen + delete p->pData; + nBlkdel++; + if( USHRT_MAX == nBlk1del ) + nBlk1del = cur; + } + p = ppInf[ ++cur ]; + nElem -= nel; + pos = 0; + } + // Am Ende die Tabelle updaten, falls Bloecke geloescht waren + if( nBlkdel ) + { + // loeschen sollte man immer !! + for( USHORT i = nBlk1del; i < ( nBlk1del + nBlkdel ); i++ ) + delete ppInf[ i ]; + + if( ( nBlk1del + nBlkdel ) < nBlock ) + { + memmove( ppInf + nBlk1del, ppInf + nBlk1del + nBlkdel, + ( nBlock - nBlkdel - nBlk1del ) * sizeof( BlockInfo* ) ); + + // JP 19.07.95: nicht den ersten behandelten, sondern den davor!! + // UpdateIdx updatet nur alle Nachfolgende!! + if( !nBlk1 ) + { + p = ppInf[ 0 ]; + p->nStart = 0; + p->nEnd = p->nElem-1; + } + else + --nBlk1; + } + BlockDel( nBlkdel ); // es wurden Bloecke geloescht + } + + nSize -= n; + if( nBlk1 != ( nBlock - 1 ) && nSize ) + UpdIndex( nBlk1 ); + nCur = nBlk1; + + // wenn mehr als 50% "Luft" im Array ist, dann sollte man mal das + // Compress aufrufen + if( nBlock > ( nSize / ( MAXENTRY / 2 ) ) ) + Compress(); + + CHECKIDX( ppInf, nBlock, nSize, nCur ); +} + + +void BigPtrArray::Replace( ULONG idx, const ElementPtr& rElem) +{ + // weil die Funktion eben doch nicht const ist: + DBG_ASSERT( idx < nSize, "Set: Index aussserhalb" ); + BigPtrArray* pThis = (BigPtrArray*) this; + USHORT cur = Index2Block( idx ); + BlockInfo* p = ppInf[ cur ]; + pThis->nCur = cur; + ((ElementPtr&)rElem)->nOffset = USHORT(idx - p->nStart); + ((ElementPtr&)rElem)->pBlock = p; + p->pData[ idx - p->nStart ] = rElem; +} + + +// Index eines Eintrags heraussuchen +// Dies ist der selbe Code wie in ForEach() mit dem Unterschied, +// dass statt einer Funktion ein Vergleich durchgefuehrt wird. +// Man haette auch ForEach() nehmen koennen, spart aber durch +// den fehlenden Call etwas Zeit. + + +ULONG BigPtrArray::GetIndex + ( const ElementPtr pTest, ULONG nStart, ULONG nEnd ) const +{ + DBG_ASSERT( pTest == pTest->pBlock->pData[ pTest->nOffset ], + "Element nicht im Block" ); + return pTest->pBlock->nStart + pTest->nOffset; +} + +// Array komprimieren + +USHORT BigPtrArray::Compress( short nMax ) +{ + CHECKIDX( ppInf, nBlock, nSize, nCur ); + + // Es wird von vorne nach hinten ueber das InfoBlock Array iteriert. + // Wenn zwischen durch Block gel”scht werden, dann mussen alle + // nachfolgenden verschoben werden. Dazu werden die Pointer pp und qq + // benutzt; wobei pp das "alte" Array, qq das "neue" Array ist. + BlockInfo** pp = ppInf, **qq = pp; + BlockInfo* p; + BlockInfo* pLast; // letzter nicht voller Block + USHORT nLast = 0; // fehlende Elemente + USHORT nBlkdel = 0; // Anzahl der geloeschte Bloecke + USHORT nFirstChgPos = USHRT_MAX; // ab welcher Pos gab es die 1. Aenderung? + + // von Fuell-Prozenten auf uebrige Eintrage umrechnen + nMax = MAXENTRY - (long) MAXENTRY * nMax / 100; + + for( USHORT cur = 0; cur < nBlock; ++cur ) + { + p = *pp++; + USHORT n = p->nElem; + // Testen, ob der noch nicht volle Block so gelassen wird + // dies ist der Fall, wenn der aktuelle Block gesplittet + // werden muesste, der noch nicht volle Block aber bereits + // ueber dem uebergebenen Break-Wert voll ist. In diesem + // Fall wird von einer weiteren Fuellung (die ja wegen dem + // zweifachen memmove() zeitaufwendig ist) abgesehen. + if( nLast && ( n > nLast ) && ( nLast < nMax ) ) + nLast = 0; + if( nLast ) + { + if( USHRT_MAX == nFirstChgPos ) + nFirstChgPos = cur; + + // ein nicht voller Block vorhanden: auffuellen + if( n > nLast ) + n = nLast; + + // Elemente uebertragen, vom akt. in den letzten + register ElementPtr* pElem = pLast->pData + pLast->nElem; + register ElementPtr* pFrom = p->pData; + for( register int nCount = n, nOff = pLast->nElem; + nCount; --nCount, ++pElem ) + *pElem = *pFrom++, + (*pElem)->pBlock = pLast, + (*pElem)->nOffset = nOff++; + + // korrigieren + pLast->nElem += n; + nLast -= n; + p->nElem -= n; + + // Ist der aktuelle Block dadurch leer geworden? + if( !p->nElem ) + { + // dann kann der entfernt werden + delete p->pData; + delete p, p = 0; + ++nBlkdel; + } + else + { + pElem = p->pData, pFrom = pElem + n; + register int nCount = p->nElem; + while( nCount-- ) + { + (*pElem++ = *pFrom++)->nOffset -= n; + } + } + } + + if( p ) // die Blockinfo wurde nicht geloescht + { + *qq++ = p; // dann setze sie an die richtige neue Position + + // eventuell den letzten halbvollen Block festhalten + if( !nLast && p->nElem < MAXENTRY ) + { + pLast = p; + nLast = MAXENTRY - p->nElem; + } + } + } + + // Bloecke geloescht wurden, ggfs. das BlockInfo Array verkuerzen + if( nBlkdel ) + BlockDel( nBlkdel ); + + // Und neu durchindizieren + p = ppInf[ 0 ]; + p->nEnd = p->nElem - 1; + UpdIndex( 0 ); + + if( nCur >= nFirstChgPos ) + nCur = 0; + + CHECKIDX( ppInf, nBlock, nSize, nCur ); + + return nFirstChgPos; +} + + diff --git a/sw/source/core/bastyp/breakit.cxx b/sw/source/core/bastyp/breakit.cxx new file mode 100644 index 000000000000..54f00db8e20a --- /dev/null +++ b/sw/source/core/bastyp/breakit.cxx @@ -0,0 +1,109 @@ +/************************************************************************* + * + * $RCSfile: breakit.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:16 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#include "breakit.hxx" +#include "viewsh.hxx" + +#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_ +#include +#endif + +#ifndef _UNOTOOLS_PROCESSFACTORY_HXX_ +#include +#endif + +#include + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::text; +using namespace ::com::sun::star::linguistic; + + + +SwBreakIt::SwBreakIt() +{ + _GetLocale( LANGUAGE_NONE ); + Reference< XMultiServiceFactory > xMSF = ::utl::getProcessServiceFactory(); + Reference < XInterface > xI = xMSF->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.text.BreakIterator" ) ); + if ( xI.is() ) + { + Any x = xI->queryInterface( ::getCppuType((const Reference< XBreakIterator >*)0) ); + x >>= xBreak; + } +} + +Locale& SwBreakIt::_GetLocale( const LanguageType aLang ) +{ + aLast = aLang; + pLocale = new Locale( SvxCreateLocale( aLast ) ); + return *pLocale; +} + + + + diff --git a/sw/source/core/bastyp/calc.cxx b/sw/source/core/bastyp/calc.cxx new file mode 100644 index 000000000000..88355531b9ea --- /dev/null +++ b/sw/source/core/bastyp/calc.cxx @@ -0,0 +1,1841 @@ +/************************************************************************* + * + * $RCSfile: calc.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:16 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + + +#include +#ifdef MAC +#include +#else +#include +#endif +#include +#include +#include + +#ifndef _HINTIDS_HXX +#include +#endif + +#ifdef WNT +#include +#endif + +#ifndef _INTN_HXX //autogen +#include +#endif +#ifndef _TOOLS_SOLMATH_HXX +#include +#endif +#ifndef _SV_SYSTEM_HXX +#include +#endif +#ifndef _APP_HXX //autogen +#include +#endif +#ifndef _SBA_SBADB_HXX //autogen +#include +#endif +#ifndef _SBA_SBAOBJ_HXX //autogen +#include +#endif +#ifndef _OFF_APP_HXX //autogen +#include +#endif +#ifndef _SVX_ADRITEM_HXX //autogen +#include +#endif +#ifndef _SVX_LANGITEM_HXX +#include +#endif +#ifndef _UNOTOOLS_CHARCLASS_HXX +#include +#endif +#ifndef _UNO_LINGU_HXX +#include +#endif + +#ifndef _DOC_HXX +#include +#endif +#ifndef _VIEWSH_HXX +#include +#endif +#ifndef _DOCSTAT_HXX //autogen +#include +#endif +#ifndef _CALC_HXX +#include +#endif +#ifndef _SHELLRES_HXX +#include +#endif +#ifndef _DBFLD_HXX +#include +#endif +#ifndef _EXPFLD_HXX +#include +#endif +#ifndef _USRFLD_HXX +#include +#endif +#ifndef _DBMGR_HXX +#include +#endif +#ifndef _DOCFLD_HXX +#include +#endif +#ifndef _FINDER_HXX +#include +#endif + + +// tippt sich schneller +#define RESOURCE ViewShell::GetShellRes() + +const sal_Char __FAR_DATA sCalc_Add[] = "add"; +const sal_Char __FAR_DATA sCalc_Sub[] = "sub"; +const sal_Char __FAR_DATA sCalc_Mul[] = "mul"; +const sal_Char __FAR_DATA sCalc_Div[] = "div"; +const sal_Char __FAR_DATA sCalc_Phd[] = "phd"; +const sal_Char __FAR_DATA sCalc_Sqrt[] = "sqrt"; +const sal_Char __FAR_DATA sCalc_Pow[] = "pow"; +const sal_Char __FAR_DATA sCalc_Or[] = "or"; +const sal_Char __FAR_DATA sCalc_Xor[] = "xor"; +const sal_Char __FAR_DATA sCalc_And[] = "and"; +const sal_Char __FAR_DATA sCalc_Not[] = "not"; +const sal_Char __FAR_DATA sCalc_Eq[] = "eq"; +const sal_Char __FAR_DATA sCalc_Neq[] = "neq"; +const sal_Char __FAR_DATA sCalc_Leq[] = "leq"; +const sal_Char __FAR_DATA sCalc_Geq[] = "geq"; +const sal_Char __FAR_DATA sCalc_L[] = "l"; +const sal_Char __FAR_DATA sCalc_G[] = "g"; +const sal_Char __FAR_DATA sCalc_Sum[] = "sum"; +const sal_Char __FAR_DATA sCalc_Mean[] = "mean"; +const sal_Char __FAR_DATA sCalc_Min[] = "min"; +const sal_Char __FAR_DATA sCalc_Max[] = "max"; +const sal_Char __FAR_DATA sCalc_Sin[] = "sin"; +const sal_Char __FAR_DATA sCalc_Cos[] = "cos"; +const sal_Char __FAR_DATA sCalc_Tan[] = "tan"; +const sal_Char __FAR_DATA sCalc_Asin[] = "asin"; +const sal_Char __FAR_DATA sCalc_Acos[] = "acos"; +const sal_Char __FAR_DATA sCalc_Atan[] = "atan"; +const sal_Char __FAR_DATA sCalc_Tdif[] = "timediff"; +const sal_Char __FAR_DATA sCalc_Round[] = "round"; + + + +//!!!!! ACHTUNG - Sortierte Liste aller Operatoren !!!!! +struct _CalcOp +{ + union{ + const sal_Char* pName; + const String* pUName; + }; + SwCalcOper eOp; +}; + +_CalcOp __READONLY_DATA aOpTable[] = { +/* ACOS */ sCalc_Acos, CALC_ACOS, // Arcuscosinus +/* ADD */ sCalc_Add, CALC_PLUS, // Addition +/* AND */ sCalc_And, CALC_AND, // log. und +/* ASIN */ sCalc_Asin, CALC_ASIN, // Arcussinus +/* ATAN */ sCalc_Atan, CALC_ATAN, // Arcustangens +/* COS */ sCalc_Cos, CALC_COS, // Cosinus +/* DIV */ sCalc_Div, CALC_DIV, // Dividieren +/* EQ */ sCalc_Eq, CALC_EQ, // gleich +/* G */ sCalc_G, CALC_GRE, // groesser +/* GEQ */ sCalc_Geq, CALC_GEQ, // groesser gleich +/* L */ sCalc_L, CALC_LES, // kleiner +/* LEQ */ sCalc_Leq, CALC_LEQ, // kleiner gleich +/* MAX */ sCalc_Max, CALC_MAX, // Maximalwert +/* MEAN */ sCalc_Mean, CALC_MEAN, // Mittelwert +/* MIN */ sCalc_Min, CALC_MIN, // Minimalwert +/* MUL */ sCalc_Mul, CALC_MUL, // Multiplizieren +/* NEQ */ sCalc_Neq, CALC_NEQ, // nicht gleich +/* NOT */ sCalc_Not, CALC_NOT, // log. nicht +/* OR */ sCalc_Or, CALC_OR, // log. oder +/* PHD */ sCalc_Phd, CALC_PHD, // Prozent +/* POW */ sCalc_Pow, CALC_POW, // Potenzieren +/* ROUND */ sCalc_Round, CALC_ROUND, // Runden +/* SIN */ sCalc_Sin, CALC_SIN, // Sinus +/* SQRT */ sCalc_Sqrt, CALC_SQRT, // Wurzel +/* SUB */ sCalc_Sub, CALC_MINUS, // Subtraktion +/* SUM */ sCalc_Sum, CALC_SUM, // Summe +/* TAN */ sCalc_Tan, CALC_TAN, // Tangens +/* TIMEDIFF */sCalc_Tdif, CALC_TDIF, // Zeitspanne +/* XOR */ sCalc_Xor, CALC_XOR // log. xoder +}; + +double __READONLY_DATA nRoundVal[] = { + 5.0e+0, 0.5e+0, 0.5e-1, 0.5e-2, 0.5e-3, 0.5e-4, 0.5e-5, 0.5e-6, + 0.5e-7, 0.5e-8, 0.5e-9, 0.5e-10,0.5e-11,0.5e-12,0.5e-13,0.5e-14, + 0.5e-15,0.5e-16 +}; + +double __READONLY_DATA nKorrVal[] = { + 9, 9e-1, 9e-2, 9e-3, 9e-4, 9e-5, 9e-6, 9e-7, 9e-8, + 9e-9, 9e-10, 9e-11, 9e-12, 9e-13, 9e-14 +}; + +extern "C" { +static int +#if defined( WNT ) + __cdecl +#endif +#if defined( ICC ) + _Optlink +#endif + OperatorCompare( const void *pFirst, const void *pSecond) +{ + int nRet = 0; + if( CALC_NAME == ((_CalcOp*)pFirst)->eOp ) + { + if( CALC_NAME == ((_CalcOp*)pSecond)->eOp ) + nRet = ((_CalcOp*)pFirst)->pUName->CompareTo( + *((_CalcOp*)pSecond)->pUName ); + else + nRet = ((_CalcOp*)pFirst)->pUName->CompareToAscii( + ((_CalcOp*)pSecond)->pName ); + } + else + { + if( CALC_NAME == ((_CalcOp*)pSecond)->eOp ) + nRet = -1 * ((_CalcOp*)pSecond)->pUName->CompareToAscii( + ((_CalcOp*)pFirst)->pName ); + else + nRet = strcmp( ((_CalcOp*)pFirst)->pName, + ((_CalcOp*)pSecond)->pName ); + } + return nRet; +} + +}// extern "C" + +_CalcOp* FindOperator( const String& rSrch ) +{ + _CalcOp aSrch; + aSrch.pUName = &rSrch; + aSrch.eOp = CALC_NAME; + + return (_CalcOp*)bsearch( (void*) &aSrch, + (void*) aOpTable, + sizeof( aOpTable ) / sizeof( _CalcOp ), + sizeof( _CalcOp ), + OperatorCompare ); +} + +inline void EatWhite( const String& rStr, xub_StrLen& rPos ) +{ + sal_Unicode c; + while( rPos < rStr.Len() && ( ( c = rStr.GetChar( rPos ) ) == ' ' || + c == '\t' || c == '\x0a' || c == '\x0d' )) + ++rPos; +} + +inline sal_Unicode NextCh( const String& rStr, xub_StrLen& rPos ) +{ + return rPos < rStr.Len() ? rStr.GetChar( rPos++ ) : 0; +} + +//----------------------------------------------------------------------------- + +SwHash* Find( const String& rStr, SwHash** ppTable, USHORT nTblSize, + USHORT* pPos ) +{ + ULONG ii = 0, n; + for( n = 0; n < rStr.Len(); ++n ) + ii = ii << 1 ^ rStr.GetChar( n ); + ii %= nTblSize; + + if( pPos ) + *pPos = (USHORT)ii; + + for( SwHash* pEntry = *(ppTable+ii); pEntry; pEntry = pEntry->pNext ) + if( rStr == pEntry->aStr ) + return pEntry; + return 0; +} + +//----------------------------------------------------------------------------- + +/****************************************************************************** +|* +|* SwCalc::SwCalc( SwDoc* pD ) : +|* +|* Erstellung OK 12-02-93 11:04am +|* Letzte Aenderung JP 03.11.95 +|* +|******************************************************************************/ + +SwCalc::SwCalc( SwDoc& rD ) + : rDoc( rD ), + eError( CALC_NOERR ), + nListPor( 0 ), + aErrExpr( aEmptyStr, SwSbxValue(), 0 ), + pInter( (International*)&Application::GetAppInternational() ), + pCharClass( &GetAppCharClass() ) +{ + aErrExpr.aStr.AssignAscii( "~C_ERR~" ); + memset( VarTable, 0, sizeof(VarTable) ); + LanguageType eLang = ((SvxLanguageItem&)rDoc.GetDefault( + RES_CHRATR_LANGUAGE )).GetLanguage(); + if( pInter->GetFormatLanguage() != eLang ) + { + pInter = new International( eLang ); + pCharClass = new CharClass( SvxCreateLocale( eLang )); + +#ifdef JP_DEBUG + printf( "Language: %d, AppLang: %d, AppFmtLang: %d, Decimal: %c, Thousand: %c\n", + pInter->GetLanguage(), + Application::GetAppInternational().GetLanguage(), + Application::GetAppInternational().GetFormatLanguage(), + pInter->GetNumDecimalSep(), + pInter->GetNumThousandSep() ); +#endif + } + + sCurrSym = pInter->GetCurrSymbol(); + sCurrSym.EraseLeadingChars().EraseTrailingChars(); + pCharClass->toLower( sCurrSym ); + +static sal_Char __READONLY_DATA + sNType0[] = "false", + sNType1[] = "true", + sNType2[] = "pi", + sNType3[] = "e", + sNType4[] = "tables", + sNType5[] = "graf", + sNType6[] = "ole", + sNType7[] = "page", + sNType8[] = "para", + sNType9[] = "word", + sNType10[]= "char", + + sNType11[] = "user_firstname" , + sNType12[] = "user_lastname" , + sNType13[] = "user_initials" , + sNType14[] = "user_company" , + sNType15[] = "user_street" , + sNType16[] = "user_country" , + sNType17[] = "user_zipcode" , + sNType18[] = "user_city" , + sNType19[] = "user_title" , + sNType20[] = "user_position" , + sNType21[] = "user_tel_work" , + sNType22[] = "user_tel_home" , + sNType23[] = "user_fax" , + sNType24[] = "user_email" , + sNType25[] = "user_state" , + sNType26[] = "graph" + ; + +static const sal_Char* __READONLY_DATA sNTypeTab[ 27 ] = +{ + sNType0, sNType1, sNType2, sNType3, sNType4, sNType5, + sNType6, sNType7, sNType8, sNType9, sNType10, sNType11, + sNType12, sNType13, sNType14, sNType15, sNType16, sNType17, + sNType18, sNType19, sNType20, sNType21, sNType22, sNType23, + sNType24, + + // diese sind mit doppelten HashIds + sNType25, sNType26 +}; +static USHORT __READONLY_DATA aHashValue[ 27 ] = +{ + 34, 38, 43, 7, 18, 32, 22, 29, 30, 33, 3, + 28, 24, 40, 9, 11, 26, 45, 4, 23, 36, 44, 19, 5, 1, + // diese sind mit doppelten HashIds + 11, 38 +}; +static AddressToken __READONLY_DATA aAdrToken[ 12 ] = +{ + ADDRESS_COMPANY, ADDRESS_STREET, ADDRESS_COUNTRY, ADDRESS_PLZ, + ADDRESS_CITY, ADDRESS_TITLE, ADDRESS_POSITION, ADDRESS_TEL_COMPANY, + ADDRESS_TEL_PRIVATE, ADDRESS_FAX, ADDRESS_EMAIL, ADDRESS_STATE +}; + +static USHORT SwDocStat::* __READONLY_DATA aDocStat1[ 3 ] = +{ + &SwDocStat::nTbl, &SwDocStat::nGrf, &SwDocStat::nOLE +}; +static ULONG SwDocStat::* __READONLY_DATA aDocStat2[ 4 ] = +{ + &SwDocStat::nPage, &SwDocStat::nPara, + &SwDocStat::nWord, &SwDocStat::nChar +}; + +#if TBLSZ != 47 +#error Alle Hashwerte angepasst? +#endif + + const SwDocStat& rDocStat = rDoc.GetDocStat(); + + SwSbxValue nVal; + String sTmpStr; + for( USHORT n = 0; n < 25; ++n ) + { + sTmpStr.AssignAscii( sNTypeTab[ n ] ); + VarTable[ aHashValue[ n ] ] = new SwCalcExp( sTmpStr, nVal, 0 ); + } + + ((SwCalcExp*)VarTable[ aHashValue[ 0 ] ])->nValue.PutBool( FALSE ); + ((SwCalcExp*)VarTable[ aHashValue[ 1 ] ])->nValue.PutBool( TRUE ); + ((SwCalcExp*)VarTable[ aHashValue[ 2 ] ])->nValue.PutDouble( F_PI ); + ((SwCalcExp*)VarTable[ aHashValue[ 3 ] ])->nValue.PutDouble( 2.7182818284590452354 ); + + for( n = 0; n < 3; ++n ) + ((SwCalcExp*)VarTable[ aHashValue[ n + 4 ] ])->nValue.PutLong( rDocStat.*aDocStat1[ n ] ); + for( n = 0; n < 4; ++n ) + ((SwCalcExp*)VarTable[ aHashValue[ n + 7 ] ])->nValue.PutLong( rDocStat.*aDocStat2[ n ] ); + + SvxAddressItem aAdr( pPathFinder->GetAddress() ); + + ((SwCalcExp*)VarTable[ aHashValue[ 11 ] ])->nValue.PutString( aAdr.GetFirstName() ); + ((SwCalcExp*)VarTable[ aHashValue[ 12 ] ])->nValue.PutString( aAdr.GetName() ); + ((SwCalcExp*)VarTable[ aHashValue[ 13 ] ])->nValue.PutString( aAdr.GetShortName() ); + + for( n = 0; n < 11; ++n ) + ((SwCalcExp*)VarTable[ aHashValue[ n + 14 ] ])->nValue.PutString( + aAdr.GetToken( aAdrToken[ n ] )); + + nVal.PutString( aAdr.GetToken( aAdrToken[ 11 ] )); + sTmpStr.AssignAscii( sNTypeTab[ 25 ] ); + VarTable[ aHashValue[ 25 ] ]->pNext = new SwCalcExp( sTmpStr, nVal, 0 ); + +// at time its better not to use "graph", because then the im-/export have +// to change in all formulas this name. +// nVal.PutLong( rDocStat.*aDocStat1[ 1 ] ); +// VarTable[ aHashValue[ 26 ] ]->pNext = new SwCalcExp( +// sNTypeTab[ 26 ], nVal, 0 ); +} + +/****************************************************************************** +|* +|* SwCalc::~SwCalc() +|* +|* Erstellung OK 12-02-93 11:04am +|* Letzte Aenderung OK 12-02-93 11:04am +|* +|******************************************************************************/ + +SwCalc::~SwCalc() +{ + for( USHORT n = 0; n < TBLSZ; ++n ) + delete VarTable[n]; + if( pInter != (International*)&Application::GetAppInternational() ) + delete pInter; + if( pCharClass != &GetAppCharClass() ) + delete pCharClass; +} + +/****************************************************************************** +|* +|* SwSbxValue SwCalc::Calculate( const String& rStr ) +|* +|* Erstellung OK 12-02-93 11:04am +|* Letzte Aenderung OK 12-02-93 11:04am +|* +|******************************************************************************/ + +SwSbxValue SwCalc::Calculate( const String& rStr ) +{ + eError = CALC_NOERR; + SwSbxValue nResult; + + if( !rStr.Len() ) + return nResult; + + nListPor = 0; + eCurrListOper = CALC_PLUS; // defaulten auf Summe + + sCommand = rStr; + nCommandPos = 0; + + while( (eCurrOper = GetToken()) != CALC_ENDCALC && eError == CALC_NOERR ) + nResult = Expr(); + + if( eError ) + nResult.PutDouble( DBL_MAX ); + +#ifndef PRODUCT + SbxDataType eResDType = nResult.GetType(); + const String& rResStr = nResult.GetString(); +#endif + return nResult; +} + +/****************************************************************************** +|* +|* String SwCalc::GetStrResult( SwSbxValue nValue, BOOL bRound = TRUE ) +|* Beschreibung Der Parameter bRound ist auf TRUE defaultet und darf +|* nur beim errechnen von Tabellenzellen auf FALSE gesetzt +|* werden, damit keine Rundungsfehler beim zusammenstellen +|* der Formel entstehen. +|* Erstellung OK 12-02-93 11:04am +|* Letzte Aenderung JP 19.02.98 +|* +|******************************************************************************/ + +String SwCalc::GetStrResult( const SwSbxValue& rVal, BOOL bRound ) +{ + if( !rVal.IsDouble() ) + return rVal.GetString(); + + return GetStrResult( rVal.GetDouble(), bRound ); +} + + +String SwCalc::GetStrResult( double nValue, BOOL bRound ) +{ + if( nValue >= DBL_MAX ) + switch( eError ) + { + case CALC_SYNTAX : return RESOURCE->aCalc_Syntax; + case CALC_ZERODIV : return RESOURCE->aCalc_ZeroDiv; + case CALC_BRACK : return RESOURCE->aCalc_Brack; + case CALC_POW : return RESOURCE->aCalc_Pow; + case CALC_VARNFND : return RESOURCE->aCalc_VarNFnd; + case CALC_OVERFLOW : return RESOURCE->aCalc_Overflow; + case CALC_WRONGTIME : return RESOURCE->aCalc_WrongTime; + default : return RESOURCE->aCalc_Default; + } + + USHORT nDec = pInter->GetNumDigits(); + String aRetStr; + + SolarMath::DoubleToString( aRetStr, nValue, + 'A', /// 'F' 'E' 'G' 'A' + nDec, /// Nachkommastellen + pInter->GetNumDecimalSep(), /// Dezimalseparator + TRUE ); + +#if 0 + String aLast; + int nExp = 0, + nDigit, + nDecPos, + nDigits = nDec + 1; + + if( !bRound ) + nDigits = nDec = 14; + + if( nValue < 0 ) + { + nValue = -nValue; + aRetStr += '-'; + } + + if (nValue > 0 ) + { + while( nValue < 1 ) + nValue *= 10, --nExp; + while( nValue >= 10 ) + nValue /= 10, ++nExp; + } + nDigits += nExp; + if( nDigits >= 0 && + 9 < int( nValue += nRoundVal[ nDigits > 15 ? 15 : nDigits ] )) + { + nValue = 1; + nExp++; + nDigits++; + } + + if( nExp < 0 ) + { + int nPos; + if( pInter->IsNumLeadingZero() ) + aRetStr += '0'; + aRetStr += pInter->GetNumDecimalSep(); + nPos = -nExp - 1; + if( nDigits <= 0 ) + nPos = nDec; + while( nPos-- ) + aRetStr += '0'; + nDecPos = 0; + } + else + nDecPos = nExp + 1; + if( nDigits > 0 ) + { + short nSep = nDecPos % 3; + BOOL bFirst = TRUE; + if( !nSep ) + nSep = 3; + for( USHORT x = 0 ; ; x++ ) + { + if( x < 15 ) + { + if( 1 == nDigits && x && 14 > x ) + nDigit = (int) floor( nValue + nKorrVal[ 15 - x ] ); + else + nDigit = (int) ( nValue + 1E-15 ); + + if( 9 < nDigit ) + { + ASSERT( !this, "Rundungsfehler" ); + nDigit = 9; + } + if( bFirst ) + aRetStr += (sal_Unicode) ( nDigit + '0' ); + else + aLast += (sal_Unicode) ( nDigit + '0' ); + nValue = ( nValue - nDigit ) * 10; + } + else + { + if( bFirst ) + aRetStr += '0'; + else + aLast += '0'; + } + if(!--nDigits) + break; + + if( nDecPos ) + { + if( !--nDecPos ) + bFirst = FALSE; + if( nDecPos && !--nSep && pInter->IsNumThousandSep() ) + { + nSep = 3; + aRetStr += pInter->GetNumThousandSep(); + } + } + } + } + if( 0L != aLast.ToInt32() ) + { + aRetStr += pInter->GetNumDecimalSep(); + aRetStr += aLast; + } +#endif + return aRetStr; +} + +/****************************************************************************** + * Methode : BOOL SwCalc::ParseTime( USHORT *pHour, USHORT *pMin, USHORT *pSec ) + * Beschreibung: + * Erstellt : OK 09.06.94 11:15 + * Aenderung : JP 03.11.95 + ******************************************************************************/ + +enum TMStatus { TM_START, TM_THSEP, TM_MIN, TM_TMSEP, TM_SEC, + TM_AMPM, TM_END, TM_ERROR }; + +BOOL SwCalc::ParseTime( USHORT *pHour, USHORT *pMin, USHORT *pSec ) +{ + TimeFormat aTMFmt = pInter->GetTimeFormat(); + sal_Unicode ch, cTMSep = pInter->GetTimeSep(); + + EatWhite( sCommand, nCommandPos ); + ch = NextCh( sCommand, nCommandPos ); + + TMStatus eState = TM_START; + while( eState != TM_END && eState != TM_ERROR ) + { + sal_Unicode cNext = 0; + USHORT *pActVal = 0; + switch( eState ) + { + case TM_AMPM : + { + xub_StrLen nStt = --nCommandPos; + BOOL bFnd = FALSE; + String aStr; + const String& rPMStr = pInter->GetTimePM(); + const String& rAMStr = pInter->GetTimeAM(); + while( nCommandPos < sCommand.Len() ) + { + EatWhite( sCommand, nCommandPos ); + aStr += NextCh( sCommand, nCommandPos ); + if( aStr == rPMStr ) + { + if( *pHour <= 12 ) + *pHour += 12; + bFnd =TRUE; + break; + } + if( aStr == rAMStr ) + { + bFnd = TRUE; + break; + } + } + if( !bFnd ) + nCommandPos = nStt; + + // Klammer oder Trenner weglesen ! + EatWhite( sCommand, nCommandPos ); + ch = NextCh( sCommand, nCommandPos ); + if( ch != ')' && ch != cListDelim ) + eState = TM_ERROR; + else + eState = TM_END; + } + break; + + case TM_TMSEP : + if( ch == cTMSep ) + ++((int&)eState); + else + { + if( nCommandPos < sCommand.Len() ) + --nCommandPos; + eState = TM_AMPM; + } + break; + case TM_THSEP : + if( ch == cTMSep ) + ++((int&)eState); + else + { + if( nCommandPos < sCommand.Len() ) + --nCommandPos; + eState = TM_AMPM; + } + break; + + case TM_SEC : if( !pActVal ) pActVal = pSec; + case TM_MIN : if( !pActVal ) pActVal = pMin; + case TM_START : + { + if( ch == '(' || ch == cListDelim ) + break; + if( !pActVal ) + pActVal = pHour; + + USHORT nVal = ( ch - '0' ); + EatWhite( sCommand, nCommandPos ); + cNext = NextCh( sCommand, nCommandPos ); + if( cNext && + pCharClass->isDigit( sCommand, nCommandPos - 1 ) ) + { + if( eState != TM_START || + aTMFmt == HOUR_12 && nVal <= 1 || + aTMFmt == HOUR_24 && nVal <= 2 ) + { + *pActVal = nVal * 10 + ( cNext - '0'); + cNext = 0; + } + else + { + eState = TM_ERROR; + break; + } + } + else + *pActVal += nVal; + ++((int&)eState); + } + break; + } + + if( eState != TM_END ) + { + if( cNext ) + ch = cNext; + else + { + EatWhite( sCommand, nCommandPos ); + ch = NextCh( sCommand, nCommandPos ); + } + } + } + return eState==TM_ERROR? FALSE : TRUE; +} + +/****************************************************************************** +|* +|* SwCalcExp* SwCalc::VarLook( const String& ) +|* +|* Erstellung OK 12-02-93 11:04am +|* Letzte Aenderung JP 15.11.99 +|* +|******************************************************************************/ + +SwCalcExp* SwCalc::VarInsert( const String &rStr ) +{ + String aStr( rStr ); + pCharClass->toLower( aStr ); + return VarLook( aStr, 1 ); +} + +/****************************************************************************** +|* +|* SwCalcExp* SwCalc::VarLook( const String& , USHORT ins ) +|* +|* Erstellung OK 12-02-93 11:04am +|* Letzte Aenderung JP 15.11.99 +|* +|******************************************************************************/ +SwCalcExp* SwCalc::VarLook( const String& rStr, USHORT ins ) +{ + USHORT ii = 0; + + SwHash* pFnd = Find( rStr, VarTable, TBLSZ, &ii ); + + if( !pFnd ) + { + // dann sehen wir mal im Doc nach: + SwHash** ppDocTbl = rDoc.GetUpdtFlds().GetFldTypeTable(); + for( SwHash* pEntry = *(ppDocTbl+ii); pEntry; pEntry = pEntry->pNext ) + if( rStr == pEntry->aStr ) + { + // dann hier zufuegen + pFnd = new SwCalcExp( rStr, SwSbxValue(), + ((SwCalcFldType*)pEntry)->pFldType ); + pFnd->pNext = *(VarTable+ii); + *(VarTable+ii) = pFnd; + break; + } + } + + if( pFnd ) + { + SwCalcExp* pFndExp = (SwCalcExp*)pFnd; + + if( pFndExp->pFldType && pFndExp->pFldType->Which() == RES_USERFLD ) + { + SwUserFieldType* pUFld = (SwUserFieldType*)pFndExp->pFldType; + if( GSE_STRING & pUFld->GetType() ) + pFndExp->nValue.PutString( pUFld->GetContent() ); + else if( !pUFld->IsValid() ) + { + // Die aktuellen Werte sichern . . . + USHORT nOld_ListPor = nListPor; + SwSbxValue nOld_LastLeft = nLastLeft; + SwSbxValue nOld_NumberValue = nNumberValue; + xub_StrLen nOld_CommandPos = nCommandPos; + SwCalcOper eOld_CurrOper = eCurrOper; + SwCalcOper eOld_CurrListOper = eCurrListOper; + + pFndExp->nValue.PutDouble( pUFld->GetValue( *this ) ); + + // . . . und zurueck damit. + nListPor = nOld_ListPor; + nLastLeft = nOld_LastLeft; + nNumberValue = nOld_NumberValue; + nCommandPos = nOld_CommandPos; + eCurrOper = eOld_CurrOper; + eCurrListOper = eOld_CurrListOper; + } + else + pFndExp->nValue.PutDouble( pUFld->GetValue() ); + } + return pFndExp; + } + + // Name(p)=Adress.PLZ oder Adress.DATENSATZNUMMER + // DBSETNUMBERFLD = DatenSATZ-nummernfeld (NICHT "setze Datensatznummer!!!") + String sTmpName( rStr ); + ::ReplacePoint( sTmpName ); + + if( !ins ) + { + SwNewDBMgr *pMgr = rDoc.GetNewDBMgr(); + + // Name(p)=Adress.PLZ oder Adress.DATENSATZNUMMER + // DBSETNUMBERFLD = DatenSATZ-nummernfeld (NICHT "setze Datensatznummer!!!") +#ifdef REPLACE_OFADBMGR + String sDBName(GetDBName( sTmpName )); + String sSourceName(sDBName.GetToken(0, DB_DELIM)); + String sTableName(sDBName.GetToken(0).GetToken(1, DB_DELIM)); + if( pMgr && sSourceName.Len() && sTableName.Len() && + pMgr->OpenDataSource(sSourceName, sTableName)) +#else + String sDBName; + if( pMgr && ( sDBName = GetDBName( sTmpName )).Len() && + pMgr->OpenDB( DBMGR_STD, sDBName, FALSE )) +#endif + { + String sColumnName( GetColumnName( sTmpName )); + ASSERT (sColumnName.Len(), "DB-Spaltenname fehlt!"); + + String sDBNum( SwFieldType::GetTypeStr(TYP_DBSETNUMBERFLD) ); + sDBNum.ToLowerAscii(); + + // Hier nochmal initialisieren, da das nicht mehr in docfld + // fuer Felder != RES_DBFLD geschieht. Z.B. wenn ein Expressionfield + // vor einem DB_Field in einem Dok vorkommt. +#ifdef REPLACE_OFADBMGR + VarChange( sDBNum, pMgr->GetSelectedRecordId(sSourceName, sTableName)); +#else + VarChange( sDBNum, pMgr->GetCurSelectedRecordId(DBMGR_STD)); +#endif + + if( sDBNum.EqualsIgnoreCaseAscii(sColumnName) ) + { +#ifdef REPLACE_OFADBMGR + aErrExpr.nValue.PutLong(long(pMgr->GetSelectedRecordId(sSourceName, sTableName))); +#else + aErrExpr.nValue.PutLong(long(pMgr->GetCurSelectedRecordId(DBMGR_STD))); +#endif + return &aErrExpr; + } + + ULONG nTmpRec = 0; + if( 0 != ( pFnd = Find( sDBNum, VarTable, TBLSZ ) ) ) + nTmpRec = ((SwCalcExp*)pFnd)->nValue.GetULong(); + + String sResult; + double nNumber = DBL_MAX; + +#ifdef REPLACE_OFADBMGR + const SfxPoolItem& rItem = rDoc.GetDefault(RES_CHRATR_LANGUAGE); + LanguageType eLang = ((SvxLanguageItem&)rDoc.GetDefault( + RES_CHRATR_LANGUAGE )).GetLanguage(); + if(LANGUAGE_SYSTEM == eLang) + eLang = ::GetSystemLanguage(); + if(pMgr->GetColumnCnt(sSourceName, sTableName, sColumnName, nTmpRec, (long)eLang, sResult, &nNumber)) +#else + if (pMgr->GetColumnCnt(DBMGR_STD, sColumnName, + pMgr->AbsToRel(DBMGR_STD, nTmpRec), sResult, &nNumber)) +#endif + { + if (nNumber != DBL_MAX) + aErrExpr.nValue.PutDouble( nNumber ); + else + aErrExpr.nValue.PutString( sResult ); + + return &aErrExpr; + } + } + // auf keinen fall eintragen!! + return &aErrExpr; + } + + + SwCalcExp* pNewExp = new SwCalcExp( rStr, SwSbxValue(), 0 ); + pNewExp->pNext = VarTable[ ii ]; + VarTable[ ii ] = pNewExp; + + String sColumnName( GetColumnName( sTmpName )); + ASSERT( sColumnName.Len(), "DB-Spaltenname fehlt!" ); + if( sColumnName.EqualsIgnoreCaseAscii( + SwFieldType::GetTypeStr( TYP_DBSETNUMBERFLD ) )) + { + SwNewDBMgr *pMgr = rDoc.GetNewDBMgr(); +#ifdef REPLACE_OFADBMGR + String sDBName(GetDBName( sTmpName )); + String sSourceName(sDBName.GetToken(0, DB_DELIM)); + String sTableName(sDBName.GetToken(0).GetToken(1, DB_DELIM)); + if( pMgr && sSourceName.Len() && sTableName.Len() && + pMgr->OpenDataSource(sSourceName, sTableName) && + !pMgr->IsInMerge()) + pNewExp->nValue.PutULong( pMgr->GetSelectedRecordId(sSourceName, sTableName)); +#else + + if( pMgr && (sTmpName = GetDBName( sTmpName )).Len() && + pMgr->OpenDB( DBMGR_STD, sTmpName, FALSE ) && + !pMgr->IsInMerge() ) + pNewExp->nValue.PutULong( pMgr->GetCurSelectedRecordId(DBMGR_STD) ); +#endif + } + + return pNewExp; +} + +/****************************************************************************** +|* +|* BOOL SwCalc::VarChange( const String& rStr, const SwSbxValue nValue ) +|* +|* Erstellung OK 12-02-93 11:04am +|* Letzte Aenderung OK 12-02-93 11:04am +|* +|******************************************************************************/ + +void SwCalc::VarChange( const String& rStr, double nValue ) +{ + SwSbxValue aVal( nValue ); + VarChange( rStr, aVal ); +} + +void SwCalc::VarChange( const String& rStr, const SwSbxValue& rValue ) +{ + String aStr( rStr ); + pCharClass->toLower( aStr ); + + USHORT nPos = 0; + SwCalcExp* pFnd = (SwCalcExp*)Find( aStr, VarTable, TBLSZ, &nPos ); + + if( !pFnd ) + { + pFnd = new SwCalcExp( aStr, SwSbxValue( rValue ), 0 ); + pFnd->pNext = VarTable[ nPos ]; + VarTable[ nPos ] = pFnd; + } + else + pFnd->nValue = rValue; +} + +/****************************************************************************** +|* +|* BOOL SwCalc::Push( const void* pPtr ) +|* +|* Erstellung OK 12-02-93 11:05am +|* Letzte Aenderung OK 12-02-93 11:05am +|* +|******************************************************************************/ + +BOOL SwCalc::Push( const VoidPtr pPtr ) +{ + if( USHRT_MAX != aRekurStk.GetPos( pPtr ) ) + return FALSE; + + aRekurStk.Insert( pPtr, aRekurStk.Count() ); + return TRUE; +} + +/****************************************************************************** +|* +|* void SwCalc::Pop( const void* pPtr ) +|* +|* Erstellung OK 12-02-93 11:05am +|* Letzte Aenderung OK 12-02-93 11:05am +|* +|******************************************************************************/ + +void SwCalc::Pop( const VoidPtr pPtr ) +{ + ASSERT( aRekurStk.Count() && aRekurStk.GetPos( pPtr ) == + (aRekurStk.Count() - 1 ), "SwCalc: Pop auf ungueltigen Ptr" ); + + aRekurStk.Remove( aRekurStk.Count() - 1 ); +} + + +/****************************************************************************** +|* +|* SwCalcOper SwCalc::GetToken() +|* +|* Erstellung OK 12-02-93 11:05am +|* Letzte Aenderung JP 03.11.95 +|* +|******************************************************************************/ + +SwCalcOper SwCalc::GetToken() +{ + sal_Unicode ch; + sal_Unicode cTSep = pInter->GetNumThousandSep(), + cDSep = pInter->GetNumDecimalSep(); + + do { + if( 0 == ( ch = NextCh( sCommand, nCommandPos ) ) ) + return eCurrOper = CALC_ENDCALC; + } while ( ch == '\t' || ch == ' ' || ch == cTSep ); + + if( ch == cDSep ) + ch = '.'; + + switch( ch ) + { + case ';': + case '\n': EatWhite( sCommand, nCommandPos ); + eCurrOper = CALC_PRINT; + break; + case '%': + case '^': + case '*': + case '/': + case '+': + case '-': + case '(': + case ')': eCurrOper = SwCalcOper(ch); + break; + + case '=': if( '=' == sCommand.GetChar( nCommandPos ) ) + { + ++nCommandPos; + eCurrOper = CALC_EQ; + } + else + eCurrOper = SwCalcOper(ch); + break; + + case '!': if( '=' == sCommand.GetChar( nCommandPos ) ) + { + ++nCommandPos; + eCurrOper = CALC_NEQ; + } + else + eCurrOper = CALC_NOT; + break; + + case '>': + case '<': eCurrOper = '>' == ch ? CALC_GRE : CALC_LES; + if( '=' == (ch = sCommand.GetChar( nCommandPos ) ) ) + { + ++nCommandPos; + eCurrOper = CALC_GRE == eCurrOper ? CALC_GEQ : CALC_LEQ; + } + else if( ' ' != ch ) + { + eError = CALC_SYNTAX; + eCurrOper = CALC_PRINT; + } + break; + + case cListDelim : + eCurrOper = eCurrListOper; + break; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case ',': + case '.': { + double nVal; + --nCommandPos; // auf das 1. Zeichen zurueck + if( Str2Double( sCommand, nCommandPos, nVal, pInter )) + { + nNumberValue.PutDouble( nVal ); + eCurrOper = CALC_NUMBER; + } + else + { + // fehlerhafte Zahl + eError = CALC_SYNTAX; + eCurrOper = CALC_PRINT; + } + } + break; + + case '[': { + String aStr; + BOOL bIgnore = FALSE; + do { + while( ( ch = NextCh( sCommand, nCommandPos )) + && ch != ']' ) + { + if( !bIgnore && '\\' == ch ) + bIgnore = TRUE; + else if( bIgnore ) + bIgnore = FALSE; + aStr += ch; + } + + if( !bIgnore ) + break; + + aStr.SetChar( aStr.Len() - 1, ch ); + } while( ch ); + + aVarName = aStr; + eCurrOper = CALC_NAME; + } + break; + + case '"': { + xub_StrLen nStt = nCommandPos; + while( ( ch = NextCh( sCommand, nCommandPos )) + && '"' != ch ) + ; + + xub_StrLen nLen = nCommandPos - nStt; + if( '"' == ch ) + --nLen; + nNumberValue.PutString( sCommand.Copy( nStt, nLen )); + eCurrOper = CALC_NUMBER; + } + break; + + default: if( ch && pCharClass->isLetter( sCommand, nCommandPos - 1) + || '_' == ch ) + { + xub_StrLen nStt = nCommandPos-1; + while( 0 != (ch = NextCh( sCommand, nCommandPos )) && + (pCharClass->isLetterNumeric( + sCommand, nCommandPos - 1) || + ch == '_' || ch == '.' ) ) + ; + + if( nCommandPos < sCommand.Len() ) + --nCommandPos; + + String aStr( sCommand.Copy( nStt, nCommandPos-nStt )); + pCharClass->toLower( aStr ); + + + // Currency-Symbol abfangen + if( aStr == sCurrSym ) + return GetToken(); // also nochmal aufrufen + + // Operations abfangen + _CalcOp* pFnd = ::FindOperator( aStr ); + if( pFnd ) + { + switch( ( eCurrOper = ((_CalcOp*)pFnd)->eOp ) ) + { + case CALC_SUM : + case CALC_MEAN : eCurrListOper = CALC_PLUS; + break; + case CALC_MIN : eCurrListOper = CALC_MIN_IN; + break; + case CALC_MAX : eCurrListOper = CALC_MAX_IN; + break; + } + return eCurrOper; + } + aVarName = aStr; + eCurrOper = CALC_NAME; + } + else + { + eError = CALC_SYNTAX; + eCurrOper = CALC_PRINT; + } + break; + } + return eCurrOper; +} + +/****************************************************************************** +|* +|* SwSbxValue SwCalc::Term() +|* +|* Erstellung OK 12-02-93 11:05am +|* Letzte Aenderung JP 16.01.96 +|* +|******************************************************************************/ + +SwSbxValue SwCalc::Term() +{ + SwSbxValue left( Prim() ); + nLastLeft = left; + for(;;) + { + SbxOperator eSbxOper = (SbxOperator)USHRT_MAX; + + switch( eCurrOper ) + { +// wir haben kein Bitweises verodern, oder ? +// case CALC_AND: eSbxOper = SbxAND; break; +// case CALC_OR: eSbxOper = SbxOR; break; +// case CALC_XOR: eSbxOper = SbxXOR; break; + case CALC_AND: { + GetToken(); + BOOL bB = Prim().GetBool(); + left.PutBool( left.GetBool() && bB ); + } + break; + case CALC_OR: { + GetToken(); + BOOL bB = Prim().GetBool(); + left.PutBool( left.GetBool() || bB ); + } + break; + case CALC_XOR: { + GetToken(); + BOOL bR = Prim().GetBool(); + BOOL bL = left.GetBool(); + left.PutBool( (bL && !bR) || (!bL && bR) ); + } + break; + + case CALC_EQ: eSbxOper = SbxEQ; break; + case CALC_NEQ: eSbxOper = SbxNE; break; + case CALC_LEQ: eSbxOper = SbxLE; break; + case CALC_GEQ: eSbxOper = SbxGE; break; + case CALC_GRE: eSbxOper = SbxGT; break; + case CALC_LES: eSbxOper = SbxLT; break; + + case CALC_MUL: eSbxOper = SbxMUL; break; + case CALC_DIV: eSbxOper = SbxDIV; break; + + case CALC_MIN_IN: + { + GetToken(); + SwSbxValue e = Prim(); + left = left.GetDouble() < e.GetDouble() + ? left : e; + } + break; + case CALC_MAX_IN: + { + GetToken(); + SwSbxValue e = Prim(); + left = left.GetDouble() > e.GetDouble() + ? left : e; + } + break; + case CALC_ROUND: + { + GetToken(); + SwSbxValue e = Prim(); + + double fVal = 0; + double fFac = 1; + INT32 nDec = (INT32) floor( e.GetDouble() ); + if( nDec < -20 || nDec > 20 ) + { + eError = CALC_OVERFLOW; + left.Clear(); + return left; + } + fVal = left.GetDouble(); + USHORT i; + if( nDec >= 0) + for (i = 0; i < (USHORT) nDec; ++i ) + fFac *= 10.0; + else + for (i = 0; i < (USHORT) -nDec; ++i ) + fFac /= 10.0; + + fVal *= fFac; + + BOOL bSign; + if (fVal < 0.0) + { + fVal *= -1.0; + bSign = TRUE; + } + else + bSign = FALSE; + + // runden + double fNum = fVal; // find the exponent + int nExp = 0; + if( fNum > 0 ) + { + while( fNum < 1.0 ) fNum *= 10.0, --nExp; + while( fNum >= 10.0 ) fNum /= 10.0, ++nExp; + } + nExp = 15 - nExp; + if( nExp > 15 ) + nExp = 15; + else if( nExp <= 1 ) + nExp = 0; + fVal = floor( fVal+ 0.5 + nRoundVal[ nExp ] ); + + if (bSign) + fVal *= -1.0; + + fVal /= fFac; + + left.PutDouble( fVal ); + } + break; + + /* case CALC_POW: { + GetToken(); +#if defined(MAC) && !defined(__powerc) + long double fraction, integer; +#else + double fraction, integer; +#endif + double right = Prim().GetDouble(), + dleft = left.GetDouble(); + + fraction = modf( right, &integer ); + if( ( dleft < 0.0 && 0.0 != fraction ) || + ( 0.0 == dleft && right < 0.0 ) ) + { + eError = CALC_OVERFLOW; + left.Clear(); + return left; + } + dleft = pow(dleft, right ); + if( dleft == HUGE_VAL ) + { + eError = CALC_POWERR; + left.Clear(); + return left; + } + left.PutDouble( dleft ); + } + break; +*/ + default: return left; + } + + if( USHRT_MAX != (USHORT)eSbxOper ) + { + GetToken(); + if( SbxEQ <= eSbxOper && eSbxOper <= SbxGE ) + left.PutBool( left.Compare( eSbxOper, Prim() )); + else + { + SwSbxValue aRight( Prim() ); + aRight.MakeDouble(); + left.MakeDouble(); + + if( SbxDIV == eSbxOper && !aRight.GetDouble() ) + eError = CALC_ZERODIV; + else + left.Compute( eSbxOper, aRight ); + } + } + } + left.Clear(); + return left; +} + +/****************************************************************************** +|* +|* SwSbxValue SwCalc::Prim() +|* +|* Erstellung OK 12-02-93 11:05am +|* Letzte Aenderung JP 03.11.95 +|* +|******************************************************************************/ + +SwSbxValue SwCalc::Prim() +{ + SwSbxValue nErg; + + double ( +#ifdef WNT + __cdecl +#endif + +#ifdef OS2 + _Optlink +#endif + *pFnc)( double ) = 0; + + BOOL bChkTrig = FALSE, bChkPow = FALSE; + + switch( eCurrOper ) + { + case CALC_SIN: pFnc = &sin; break; + case CALC_COS: pFnc = &cos; break; + case CALC_TAN: pFnc = &tan; break; + case CALC_ATAN: pFnc = &atan; break; + case CALC_ASIN: pFnc = &asin; bChkTrig = TRUE; break; + case CALC_ACOS: pFnc = &acos; bChkTrig = TRUE; break; + + case CALC_NOT: { + GetToken(); + nErg = Prim(); + if( SbxSTRING == nErg.GetType() ) + nErg.PutBool( 0 != nErg.GetString().Len() ); + nErg.Compute( SbxNOT, nErg ); + } + break; + + case CALC_NUMBER: if( GetToken() == CALC_PHD ) + { + double aTmp = nLastLeft.GetDouble(); + aTmp *= nNumberValue.GetDouble(); + aTmp *= 0.01; + nErg.PutDouble( aTmp ); + GetToken(); + } + else if( eCurrOper == CALC_NAME ) + eError = CALC_SYNTAX; + else + { + nErg = nNumberValue; + bChkPow = TRUE; + } + break; + + case CALC_NAME: if( GetToken() == CALC_ASSIGN ) + { + SwCalcExp* n = VarInsert( aVarName ); + GetToken(); + nErg = n->nValue = Expr(); + } + else + { + nErg = VarLook( aVarName )->nValue; + bChkPow = TRUE; + } + break; + + case CALC_MINUS: GetToken(); + nErg.PutDouble( -(Prim().GetDouble()) ); + break; + + case CALC_LP: { + GetToken(); + nErg = Expr(); + if( eCurrOper != CALC_RP ) + eError = CALC_BRACK; + else + GetToken(); + } + break; + + case CALC_TDIF: { + USHORT nH1 = 0, nM1 = 0, nS1 = 0, + nH2 = 0, nM2 = 0, nS2 = 0; + if( !ParseTime( &nH1, &nM1, &nS1 ) || + !ParseTime( &nH2, &nM2, &nS2 ) ) + eError = CALC_WRONGTIME; + GetToken(); + nErg.PutDouble( double( + 3600L * nH2 + 60 * nM2 + nS2 - + 3600L * nH1 - 60 * nM1 - nS1 )); + } + break; + + case CALC_MEAN: { + nListPor = 1; + GetToken(); + nErg = Expr(); + double aTmp = nErg.GetDouble(); + aTmp /= nListPor; + nErg.PutDouble( aTmp ); + } + break; + + case CALC_SQRT: { + GetToken(); + nErg = Prim(); + if( nErg.GetDouble() < 0 ) + eError = CALC_OVERFLOW; + else + nErg.PutDouble( sqrt( nErg.GetDouble() )); + } + break; + + case CALC_SUM: + case CALC_MIN: + case CALC_MAX: GetToken(); + nErg = Expr(); + break; + + case CALC_ENDCALC: nErg.Clear(); + break; + + default: eError = CALC_SYNTAX; + break; + } + + if( pFnc ) + { + GetToken(); + double nVal = Prim().GetDouble(); + if( !bChkTrig || ( nVal > -1 && nVal < 1 ) ) + nErg.PutDouble( (*pFnc)( nVal ) ); + else + eError = CALC_OVERFLOW; + } + + if( bChkPow && eCurrOper == CALC_POW ) + { + double dleft = nErg.GetDouble(); + GetToken(); + double right = Prim().GetDouble(); + +#if defined(MAC) && !defined(__powerc) + long double fraction, integer; +#else + double fraction, integer; +#endif + fraction = modf( right, &integer ); + if( ( dleft < 0.0 && 0.0 != fraction ) || + ( 0.0 == dleft && right < 0.0 ) ) + { + eError = CALC_OVERFLOW; + nErg.Clear(); + } + else + { + dleft = pow(dleft, right ); + if( dleft == HUGE_VAL ) + { + eError = CALC_POWERR; + nErg.Clear(); + } + else + { + nErg.PutDouble( dleft ); +// GetToken(); + } + } + } + + return nErg; +} + +/****************************************************************************** +|* +|* SwSbxValue SwCalc::Expr() +|* +|* Erstellung OK 12-02-93 11:06am +|* Letzte Aenderung JP 03.11.95 +|* +|******************************************************************************/ + +SwSbxValue SwCalc::Expr() +{ + SwSbxValue left = Term(), right; + nLastLeft = left; + for(;;) + switch(eCurrOper) + { + case CALC_PLUS: GetToken(); + // erzeuge zum addieren auf jedenfall einen + // Double-Wert + left.MakeDouble(); + ( right = Term() ).MakeDouble(); + left.Compute( SbxPLUS, right ); + nListPor++; + break; + + case CALC_MINUS: GetToken(); + // erzeuge zum addieren auf jedenfall einen + // Double-Wert + left.MakeDouble(); + ( right = Term() ).MakeDouble(); + left.Compute( SbxMINUS, right ); + break; + + default: return left; + } + left.Clear(); + return left; +} + +//------------------------------------------------------------------------------ + +String SwCalc::GetColumnName(const String& rName) +{ + xub_StrLen nPos = rName.Search(DB_DELIM); + if( STRING_NOTFOUND != nPos ) + { + nPos = rName.Search(DB_DELIM, nPos + 1); + + if( STRING_NOTFOUND != nPos ) + return rName.Copy(nPos + 1); + } + return rName; +} + +//------------------------------------------------------------------------------ + +String SwCalc::GetDBName(const String& rName) +{ + xub_StrLen nPos = rName.Search(DB_DELIM); + if( STRING_NOTFOUND != nPos ) + { + nPos = rName.Search(DB_DELIM, nPos + 1); + + if( STRING_NOTFOUND != nPos ) + return rName.Copy( 0, nPos ); + } + return rDoc.GetDBName(); +} + +//------------------------------------------------------------------------------ + +/****************************************************************************** + * Methode : FASTBOOL SwCalc::Str2Double( double& ) + * Beschreibung: + * Erstellt : OK 07.06.94 12:56 + * Aenderung : JP 27.10.98 + ******************************************************************************/ +FASTBOOL SwCalc::Str2Double( const String& rCommand, xub_StrLen& rCommandPos, + double& rVal, const International* pInter ) +{ + const International* pIntr = pInter; + if( !pIntr ) + { + pIntr = &Application::GetAppInternational(); + if( pIntr->GetFormatLanguage() != System::GetLanguage() ) + pIntr = new International( System::GetLanguage() ); + } + + const xub_Unicode* pEnd; + int nErrno; + rVal = SolarMath::StringToDouble( rCommand.GetBuffer() + rCommandPos, + pIntr->GetNumThousandSep(), + pIntr->GetNumDecimalSep(), + nErrno, &pEnd ); + rCommandPos = pEnd - rCommand.GetBuffer(); + + if( !pInter && pIntr != &Application::GetAppInternational() ) + delete (International*)pIntr; + + return 0 == nErrno; +} + +//------------------------------------------------------------------------------ + +/****************************************************************************** +|* +|* CTOR DTOR der SwHash classes +|* +|* Ersterstellung OK 25.06.93 12:20 +|* Letzte Aenderung OK 25.06.93 12:20 +|* +******************************************************************************/ + +SwHash::SwHash( const String& rStr ) : + aStr( rStr ), + pNext( 0 ) +{} + +SwHash::~SwHash() +{ + if( pNext ) + delete pNext; +} + +void DeleteHashTable( SwHash **ppHashTable, USHORT nCount ) +{ + for ( USHORT i = 0; i < nCount; ++i ) + delete *(ppHashTable+i); + __DELETE(nCount) ppHashTable; +} + +SwCalcExp::SwCalcExp( const String& rStr, const SwSbxValue& rVal, + const SwFieldType* pType ) + : SwHash( rStr ), + nValue( rVal ), + pFldType( pType ) +{ +} + + +SwSbxValue::~SwSbxValue() +{ +} + + +BOOL SwSbxValue::GetBool() const +{ + return SbxSTRING == GetType() ? 0 != GetString().Len() + : SbxValue::GetBool(); +} + +double SwSbxValue::GetDouble() const +{ + double nRet; + if( SbxSTRING == GetType() ) + { + xub_StrLen nStt = 0; + SwCalc::Str2Double( GetString(), nStt, nRet ); + } + else + nRet = SbxValue::GetDouble(); + return nRet; +} + +SwSbxValue& SwSbxValue::MakeDouble() +{ + if( SbxSTRING == GetType() ) + PutDouble( GetDouble() ); + return *this; +} + +#ifdef STANDALONE_HASHCALC + +// dies ist der Beispielcode zu erzeugen der HashValues im CTOR: + +#include + +void main() +{ +static sal_Char + sNType0[] = "false", sNType1[] = "true", sNType2[] = "pi", + sNType3[] = "e", sNType4[] = "tables", sNType5[] = "graf", + sNType6[] = "ole", sNType7[] = "page", sNType8[] = "para", + sNType9[] = "word", sNType10[]= "char", + sNType11[] = "user_company" , sNType12[] = "user_firstname" , + sNType13[] = "user_lastname" , sNType14[] = "user_initials", + sNType15[] = "user_street" , sNType16[] = "user_country" , + sNType17[] = "user_zipcode" , sNType18[] = "user_city" , + sNType19[] = "user_title" , sNType20[] = "user_position" , + sNType21[] = "user_tel_home", sNType22[] = "user_tel_work", + sNType23[] = "user_fax" , sNType24[] = "user_email" , + sNType25[] = "user_state", sNType26[] = "graph" + ; + +static const sal_Char* sNTypeTab[ 27 ] = +{ + sNType0, sNType1, sNType2, sNType3, sNType4, sNType5, + sNType6, sNType7, sNType8, sNType9, sNType10, sNType11, + sNType12, sNType13, sNType14, sNType15, sNType16, sNType17, + sNType18, sNType19, sNType20, sNType21, sNType22, sNType23, + sNType24, sNType25, sNType26 +}; + + const unsigned short nTblSize = 47; + int aArr[ nTblSize ] = { 0 }; + sal_Char ch; + + for( int n = 0; n < 27; ++n ) + { + unsigned long ii = 0; + const sal_Char* pp = sNTypeTab[ n ]; + + while( *pp ) + ii = ii << 1 ^ *pp++; + ii %= nTblSize; + + ch = aArr[ ii ] ? 'X' : ' '; + aArr[ ii ] = 1; + printf( "%-20s -> %3d [%c]\n", sNTypeTab[ n ], ii, ch ); + } +} + +#endif + + + diff --git a/sw/source/core/bastyp/index.cxx b/sw/source/core/bastyp/index.cxx new file mode 100644 index 000000000000..9a7f6017b104 --- /dev/null +++ b/sw/source/core/bastyp/index.cxx @@ -0,0 +1,772 @@ +/************************************************************************* + * + * $RCSfile: index.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:16 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#include // fuer qsort + +#ifndef _SOLAR_H +#include +#endif + +#include "errhdl.hxx" // fuers ASSERT +#include "index.hxx" +#include "error.h" // fuers ASSERT + +#ifndef PRODUCT +int SwIndex::nSerial = 0; +#endif + + +TYPEINIT0(SwIndexReg); // rtti + + +#ifdef CHK + +#define IDX_CHK_ARRAY pArray->ChhkArr(); +#define ARR_CHK_ARRAY ChhkArr(); + + +void SwIndexReg::ChkArr() +{ + ASSERT( (pFirst && pLast) || (!pFirst && !pLast), + "Array falsch Indiziert" ); + + if( !pFirst ) + return; + + xub_StrLen nVal = 0; + const SwIndex* pIdx = pFirst, *pPrev = 0; + ASSERT( !pIdx->pPrev, "Array-pFirst nicht am Anfang" ); + + while( pIdx != pLast ) + { + ASSERT( pIdx->pPrev != pIdx && pIdx->pNext != pIdx, + "Index zeigt auf sich selbst" ) + + ASSERT( pIdx->nIndex >= nVal, "Reihenfolge stimmt nicht" ); + ASSERT( pPrev == pIdx->pPrev, "Verkettung stimmt nicht" ); + pPrev = pIdx; + pIdx = pIdx->pNext; + nVal = pPrev->nIndex; + } +} + +#else // CHK + +#define IDX_CHK_ARRAY +#define ARR_CHK_ARRAY + +#endif // CHK + + + +SwIndex::SwIndex( SwIndexReg* pArr, xub_StrLen nIdx ) + : pArray( pArr ), nIndex( nIdx ), pNext( 0 ), pPrev( 0 ) +{ + if( !pArray ) + { + pArray = SwIndexReg::pEmptyIndexArray; + nIndex = 0; // steht immer auf 0 !!! + } + + if( !pArray->pFirst ) // 1. Index ?? + pArray->pFirst = pArray->pLast = this; + else if( pArray->pMiddle ) + { + if( pArray->pMiddle->nIndex <= nIdx ) + { + if( nIdx > ((pArray->pLast->nIndex - pArray->pMiddle->nIndex) / 2) ) + ChgValue( *pArray->pLast, nIdx ); + else + ChgValue( *pArray->pMiddle, nIdx ); + } + else if( nIdx > ((pArray->pMiddle->nIndex - pArray->pFirst->nIndex) / 2) ) + ChgValue( *pArray->pMiddle, nIdx ); + else + ChgValue( *pArray->pFirst, nIdx ); + } + else if( nIdx > ((pArray->pLast->nIndex - pArray->pFirst->nIndex) / 2) ) + ChgValue( *pArray->pLast, nIdx ); + else + ChgValue( *pArray->pFirst, nIdx ); + +#ifndef PRODUCT + MySerial = ++nSerial; // nur in der nicht PRODUCT-Version +#endif +IDX_CHK_ARRAY +} + + +SwIndex::SwIndex( const SwIndex& rIdx, short nIdx ) + : pArray( rIdx.pArray ), pNext( 0 ), pPrev( 0 ) +{ + ChgValue( rIdx, rIdx.nIndex + nIdx ); + +#ifndef PRODUCT + MySerial = ++nSerial; // nur in der nicht PRODUCT-Version +#endif +IDX_CHK_ARRAY +} + + +SwIndex::SwIndex( const SwIndex& rIdx ) + : pArray( rIdx.pArray ), nIndex( rIdx.nIndex ), pNext( 0 ), pPrev( 0 ) +{ + ChgValue( rIdx, rIdx.nIndex ); +#ifndef PRODUCT + MySerial = ++nSerial; // nur in der nicht PRODUCT-Version +#endif +IDX_CHK_ARRAY +} + + +SwIndex& SwIndex::ChgValue( const SwIndex& rIdx, xub_StrLen nNewValue ) +{ + register SwIndex* pFnd = (SwIndex*)&rIdx; + if( rIdx.nIndex > nNewValue ) // nach vorne versuchen + { + register SwIndex* pPrv; + while( 0 != ( pPrv = pFnd->pPrev ) && pPrv->nIndex > nNewValue ) + pFnd = pPrv; + + if( pFnd != this ) + { + // an alter Position ausketten + // erstmal an alter Position ausketten + if( pPrev ) + pPrev->pNext = pNext; + else if( pArray->pFirst == this ) + pArray->pFirst = pNext; + + if( pNext ) + pNext->pPrev = pPrev; + else if( pArray->pLast == this ) + pArray->pLast = pPrev; + + pNext = pFnd; + pPrev = pFnd->pPrev; + if( pPrev ) + pPrev->pNext = this; + else + pArray->pFirst = this; + pFnd->pPrev = this; + } + } + else if( rIdx.nIndex < nNewValue ) + { + register SwIndex* pNxt; + while( 0 != ( pNxt = pFnd->pNext ) && pNxt->nIndex < nNewValue ) + pFnd = pNxt; + + if( pFnd != this ) + { + // erstmal an alter Position ausketten + if( pPrev ) + pPrev->pNext = pNext; + else if( pArray->pFirst == this ) + pArray->pFirst = pNext; + + if( pNext ) + pNext->pPrev = pPrev; + else if( pArray->pLast == this ) + pArray->pLast = pPrev; + + pPrev = pFnd; + pNext = pFnd->pNext; + if( pNext ) + pNext->pPrev = this; + else + pArray->pLast = this; + pFnd->pNext = this; + } + } + else if( pFnd != this ) + { + // erstmal an alter Position ausketten + if( pPrev ) + pPrev->pNext = pNext; + else if( pArray->pFirst == this ) + pArray->pFirst = pNext; + + if( pNext ) + pNext->pPrev = pPrev; + else if( pArray->pLast == this ) + pArray->pLast = pPrev; + + pPrev = (SwIndex*)&rIdx; + pNext = rIdx.pNext; + pPrev->pNext = this; + + if( !pNext ) // im IndexArray als letzes + pArray->pLast = this; + else + pNext->pPrev = this; + } + pArray = rIdx.pArray; + + if( pArray->pFirst == pNext ) + pArray->pFirst = this; + if( pArray->pLast == pPrev ) + pArray->pLast = this; + + nIndex = nNewValue; + +IDX_CHK_ARRAY + + return *this; } + + +void SwIndex::Remove() +{ + if( !pPrev ) + pArray->pFirst = pNext; + else + pPrev->pNext = pNext; + + if( !pNext ) + pArray->pLast = pPrev; + else + pNext->pPrev = pPrev; + + if( this == pArray->pMiddle ) pArray->pMiddle = pPrev; +IDX_CHK_ARRAY +} + +/************************************************************************* +|* +|* SwIndex & SwIndex::operator=( const SwIndex & aSwIndex ) +|* +|* Beschreibung +|* Ersterstellung JP 07.11.90 +|* Letzte Aenderung JP 07.03.94 +|* +*************************************************************************/ + + +SwIndex& SwIndex::operator=( const SwIndex& rIdx ) +{ + int bEqual; + if( rIdx.pArray != pArray ) // im alten abmelden !! + { + Remove(); + pArray = rIdx.pArray; + pNext = pPrev = 0; + bEqual = FALSE; + } + else + bEqual = rIdx.nIndex == nIndex; + + if( !bEqual ) + ChgValue( rIdx, rIdx.nIndex ); + return *this; +} + +/************************************************************************* +|* +|* SwIndex &SwIndex::Assign +|* +|* Beschreibung +|* Ersterstellung VB 25.03.91 +|* Letzte Aenderung JP 07.03.94 +|* +*************************************************************************/ + + +SwIndex& SwIndex::Assign( SwIndexReg* pArr, xub_StrLen nIdx ) +{ + if( !pArr ) + { + pArr = SwIndexReg::pEmptyIndexArray; + nIdx = 0; // steht immer auf 0 !!! + } + + if( pArr != pArray ) // im alten abmelden !! + { + Remove(); + pArray = pArr; + pNext = pPrev = 0; + if( !pArr->pFirst ) // 1. Index ?? + { + pArr->pFirst = pArr->pLast = this; + nIndex = nIdx; + } + else if( pArray->pMiddle ) + { + if( pArray->pMiddle->nIndex <= nIdx ) + { + if( nIdx > ((pArr->pLast->nIndex - pArr->pMiddle->nIndex) / 2) ) + ChgValue( *pArr->pLast, nIdx ); + else + ChgValue( *pArr->pMiddle, nIdx ); + } + else if( nIdx > ((pArr->pMiddle->nIndex - pArr->pFirst->nIndex) / 2) ) + ChgValue( *pArr->pMiddle, nIdx ); + else + ChgValue( *pArr->pFirst, nIdx ); + } + else if( nIdx > ((pArr->pLast->nIndex - pArr->pFirst->nIndex) / 2) ) + ChgValue( *pArr->pLast, nIdx ); + else + ChgValue( *pArr->pFirst, nIdx ); + } + else if( nIndex != nIdx ) + ChgValue( *this, nIdx ); +IDX_CHK_ARRAY + return *this; +} + + +SwIndexReg::SwIndexReg() + : pFirst( 0 ), pLast( 0 ), pMiddle( 0 ) +{ +} + +#ifndef PRODUCT + + +SwIndexReg::~SwIndexReg() +{ + ASSERT( !pFirst || !pLast, "Es sind noch Indizies angemeldet" ); +} + +#endif + + +void SwIndexReg::Update( const SwIndex& rIdx, xub_StrLen nDiff, BOOL bNeg ) +{ + register SwIndex* pStt = (SwIndex*)&rIdx; + register xub_StrLen nNewVal = rIdx.nIndex; + if( bNeg ) + { + register xub_StrLen nLast = rIdx.GetIndex() + nDiff; + while( pStt && pStt->nIndex == nNewVal ) + { + pStt->nIndex = nNewVal; + pStt = pStt->pPrev; + } + pStt = rIdx.pNext; + while( pStt && pStt->nIndex >= nNewVal && + pStt->nIndex <= nLast ) + { + pStt->nIndex = nNewVal; + pStt = pStt->pNext; + } + while( pStt ) + { + pStt->nIndex -= nDiff; + pStt = pStt->pNext; + } + } + else + { + while( pStt && pStt->nIndex == nNewVal ) + { + pStt->nIndex += nDiff; + pStt = pStt->pPrev; + } + pStt = rIdx.pNext; + while( pStt ) + { + pStt->nIndex += nDiff; + pStt = pStt->pNext; + } + } +ARR_CHK_ARRAY +} + + +/************************************************************************* +|* +|* SwIndex::operator++() +|* +|* Beschreibung +|* Ersterstellung JP 07.11.90 +|* Letzte Aenderung JP 07.03.94 +|* +*************************************************************************/ + +#ifndef PRODUCT + +#ifndef CFRONT + + +xub_StrLen SwIndex::operator++(int) +{ + ASSERT_ID( nIndex < INVALID_INDEX, ERR_OUTOFSCOPE ); + + xub_StrLen nOldIndex = nIndex; + ChgValue( *this, nIndex+1 ); + return nOldIndex; +} + +#endif + + +xub_StrLen SwIndex::operator++() +{ + ASSERT_ID( nIndex < INVALID_INDEX, ERR_OUTOFSCOPE ); + + ChgValue( *this, nIndex+1 ); + return nIndex; +} + +/************************************************************************* +|* +|* SwIndex::operator--() +|* +|* Beschreibung +|* Ersterstellung JP 07.11.90 +|* Letzte Aenderung JP 07.03.94 +|* +*************************************************************************/ + +#ifndef CFRONT + + +xub_StrLen SwIndex::operator--(int) +{ + ASSERT_ID( nIndex, ERR_OUTOFSCOPE ); + + xub_StrLen nOldIndex = nIndex; + ChgValue( *this, nIndex-1 ); + return nOldIndex; +} + +#endif + + +xub_StrLen SwIndex::operator--() +{ + ASSERT_ID( nIndex, ERR_OUTOFSCOPE ); + return ChgValue( *this, nIndex-1 ).nIndex; +} + +/************************************************************************* +|* +|* SwIndex::operator+=( xub_StrLen ) +|* +|* Beschreibung +|* Ersterstellung JP 07.11.90 +|* Letzte Aenderung JP 07.03.94 +|* +*************************************************************************/ + + +xub_StrLen SwIndex::operator+=( xub_StrLen nWert ) +{ + ASSERT_ID( nIndex < INVALID_INDEX - nWert, ERR_OUTOFSCOPE); + return ChgValue( *this, nIndex + nWert ).nIndex; +} + +/************************************************************************* +|* +|* SwIndex::operator-=( xub_StrLen ) +|* +|* Beschreibung +|* Ersterstellung JP 07.11.90 +|* Letzte Aenderung JP 07.03.94 +|* +*************************************************************************/ + + +xub_StrLen SwIndex::operator-=( xub_StrLen nWert ) +{ + ASSERT_ID( nIndex >= nWert, ERR_OUTOFSCOPE ); + return ChgValue( *this, nIndex - nWert ).nIndex; +} + +/************************************************************************* +|* +|* SwIndex::operator+=( const SwIndex & ) +|* +|* Beschreibung +|* Ersterstellung JP 07.11.90 +|* Letzte Aenderung JP 07.03.94 +|* +*************************************************************************/ + + +xub_StrLen SwIndex::operator+=( const SwIndex & rIndex ) +{ + ASSERT_ID( nIndex < INVALID_INDEX - rIndex.nIndex, ERR_OUTOFSCOPE ); + return ChgValue( *this, nIndex + rIndex.nIndex ).nIndex; +} + + +/************************************************************************* +|* +|* SwIndex::operator-=( const SwIndex & ) +|* +|* Beschreibung +|* Ersterstellung JP 07.11.90 +|* Letzte Aenderung JP 07.03.94 +|* +*************************************************************************/ + + +xub_StrLen SwIndex::operator-=( const SwIndex & rIndex ) +{ + ASSERT_ID( nIndex >= rIndex.nIndex, ERR_OUTOFSCOPE ); + return ChgValue( *this, nIndex - rIndex.nIndex ).nIndex; +} + + +/************************************************************************* +|* +|* SwIndex::operator<( const SwIndex & ) +|* +|* Beschreibung +|* Ersterstellung JP 07.11.90 +|* Letzte Aenderung JP 07.03.94 +|* +*************************************************************************/ + + +BOOL SwIndex::operator<( const SwIndex & rIndex ) const +{ + ASSERT( pArray == rIndex.pArray, "Attempt to compare indices into different arrays."); + return nIndex < rIndex.nIndex; +} + +/************************************************************************* +|* +|* SwIndex::operator<=( const SwIndex & ) +|* +|* Beschreibung +|* Ersterstellung JP 07.11.90 +|* Letzte Aenderung JP 04.06.92 +|* +*************************************************************************/ + + +BOOL SwIndex::operator<=( const SwIndex & rIndex ) const +{ + ASSERT( pArray == rIndex.pArray, "Attempt to compare indices into different arrays."); + return nIndex <= rIndex.nIndex; +} + +/************************************************************************* +|* +|* SwIndex::operator>( const SwIndex & ) +|* +|* Beschreibung +|* Ersterstellung JP 07.11.90 +|* Letzte Aenderung JP 04.06.92 +|* +*************************************************************************/ + + +BOOL SwIndex::operator>( const SwIndex & rIndex ) const +{ + ASSERT( pArray == rIndex.pArray, "Attempt to compare indices into different arrays."); + return nIndex > rIndex.nIndex; +} + +/************************************************************************* +|* +|* SwIndex::operator>=( const SwIndex & ) +|* +|* Beschreibung +|* Ersterstellung JP 07.11.90 +|* Letzte Aenderung JP 04.06.92 +|* +*************************************************************************/ + + +BOOL SwIndex::operator>=( const SwIndex & rIndex ) const +{ + ASSERT( pArray == rIndex.pArray, "Attempt to compare indices into different arrays."); + return nIndex >= rIndex.nIndex; +} + +#endif + +/************************************************************************* +|* +|* SwIndex & SwIndex::operator=( xub_StrLen ) +|* +|* Beschreibung +|* Ersterstellung JP 10.12.90 +|* Letzte Aenderung JP 07.03.94 +|* +*************************************************************************/ + +#ifndef PRODUCT + + +SwIndex& SwIndex::operator=( xub_StrLen nWert ) +{ + // Werte kopieren und im neuen Array anmelden + if( nIndex != nWert ) + ChgValue( *this, nWert ); + + return *this; +} + +#endif + + + +void SwIndexReg::MoveIdx( const SwIndex& rOldPos, const SwIndex& rNewPos ) +{ + ASSERT( rOldPos.pArray == rNewPos.pArray, + "stehen in unterschiedlichen Arrays" ); + + SwIndex* pStt = (SwIndex*)&rOldPos, *pEnd = pStt; + SwIndex* pInsPos = (SwIndex*)&rNewPos; + xub_StrLen nOldIndex = rOldPos.nIndex, + nNewIndex = rNewPos.nIndex; + + if( nOldIndex == nNewIndex ) + return; + + while( pInsPos->pPrev && pInsPos->pPrev->nIndex == nNewIndex ) + pInsPos = pInsPos->pPrev; + + if( nNewIndex > nOldIndex ) + --nNewIndex; + + while( pStt->pPrev && pStt->pPrev->nIndex == nOldIndex ) + { + pStt = pStt->pPrev; + pStt->nIndex = nNewIndex; + } + while( pEnd->pNext && pEnd->pNext->nIndex == nOldIndex ) + { + pEnd = pEnd->pNext; + pEnd->nIndex = nNewIndex; + } + + { + for( SwIndex* pTmp = pStt; pTmp != pEnd; pTmp = pTmp->pNext ) + pTmp->nIndex = nNewIndex; + pTmp->nIndex = nNewIndex; + } + + // Ausketten + if( !pStt->pPrev ) + { + pFirst = pEnd->pNext; + pEnd->pNext->pPrev = 0; + } + else + pStt->pPrev->pNext = pEnd->pNext; + + if( !pEnd->pNext ) + { + pLast = pStt->pPrev; + pStt->pPrev->pNext = 0; + } + else + pEnd->pNext->pPrev = pStt->pPrev; + + // wieder einketten + pStt->pPrev = pInsPos->pPrev; + pEnd->pNext = pInsPos; + + if( pInsPos->pPrev ) + pInsPos->pPrev->pNext = pStt; + pInsPos->pPrev = pEnd; + + if( pInsPos == pFirst ) + pFirst = pStt; + + if( nNewIndex < nOldIndex ) // es wurde nach vorne verschoben + { + while( pInsPos && pInsPos->nIndex <= nOldIndex ) + { + ++pInsPos->nIndex; + pInsPos = pInsPos->pNext; + } + } + else // es wurde nach hinten verschoben + { + while( pStt->pPrev && pStt->pPrev->nIndex > nOldIndex ) + { + pStt = pStt->pPrev; + --pStt->nIndex; + } + } +} + +void SwIndexReg::MoveTo( SwIndexReg& rArr ) +{ + if( this != &rArr && pFirst ) + { + SwIndex* pIdx = (SwIndex*)pFirst, *pNext; + while( pIdx ) + { + pNext = pIdx->pNext; + pIdx->Assign( &rArr, pIdx->GetIndex() ); + pIdx = pNext; + } + pFirst = 0, pLast = 0, pMiddle = 0; + } +} + + + + diff --git a/sw/source/core/bastyp/init.cxx b/sw/source/core/bastyp/init.cxx new file mode 100644 index 000000000000..250a868d0e2a --- /dev/null +++ b/sw/source/core/bastyp/init.cxx @@ -0,0 +1,951 @@ +/************************************************************************* + * + * $RCSfile: init.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:16 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#define ITEMID_BOXINFO SID_ATTR_BORDER_INNER + +#ifndef _HINTIDS_HXX +#include +#endif + +#ifndef _GLOBNAME_HXX +#include +#endif +#ifndef _SV_MAPMOD_HXX +#include +#endif +#ifndef _SYSTEM_HXX //autogen +#include +#endif + +#ifndef _XMLOFF_XMLCNITM_HXX +#include +#endif + +#ifndef _SFXMACITEM_HXX //autogen +#include +#endif +#ifndef _SVX_PBINITEM_HXX //autogen +#include +#endif +#ifndef _SVX_KEEPITEM_HXX //autogen +#include +#endif +#ifndef _SVX_NLBKITEM_HXX //autogen +#include +#endif +#ifndef _SVX_HYZNITEM_HXX //autogen +#include +#endif +#ifndef _SVX_PROTITEM_HXX //autogen +#include +#endif +#ifndef _SVX_ULSPITEM_HXX //autogen +#include +#endif +#ifndef _SVX_PRSZITEM_HXX //autogen +#include +#endif +#ifndef _SVX_OPAQITEM_HXX //autogen +#include +#endif +#ifndef _SVX_SHADITEM_HXX //autogen +#include +#endif +#ifndef _SVX_PRNTITEM_HXX //autogen +#include +#endif +#ifndef _SVX_BRKITEM_HXX //autogen +#include +#endif +#ifndef _SVX_TSTPITEM_HXX //autogen +#include +#endif +#ifndef _SVX_LANGITEM_HXX //autogen +#include +#endif +#ifndef _SVX_WRLMITEM_HXX //autogen +#include +#endif +#ifndef _SVX_KERNITEM_HXX //autogen +#include +#endif +#ifndef _SVX_ESCPITEM_HXX //autogen +#include +#endif +#ifndef _SVX_CSCOITEM_HXX //autogen +#include +#endif +#ifndef _SVX_LRSPITEM_HXX //autogen +#include +#endif +#ifndef _SVX_ORPHITEM_HXX //autogen +#include +#endif +#ifndef _SVX_WIDWITEM_HXX //autogen +#include +#endif +#ifndef _SVX_NHYPITEM_HXX //autogen +#include +#endif +#ifndef _SVX_SPLTITEM_HXX //autogen +#include +#endif +#ifndef _SVX_LSPCITEM_HXX //autogen +#include +#endif +#ifndef _SVX_BLNKITEM_HXX //autogen +#include +#endif +#ifndef _SVX_AKRNITEM_HXX //autogen +#include +#endif +#ifndef _SVX_CMAPITEM_HXX //autogen +#include +#endif +#ifndef _SVX_DIALOGS_HRC +#include +#endif +#ifndef _SVXSWAFOPT_HXX +#include +#endif +#ifndef _MySVXACORR_HXX //autogen +#include +#endif +#ifndef _OFF_APP_HXX //autogen +#include +#endif +#ifndef _UNOTOOLS_CHARCLASS_HXX +#include +#endif +#ifndef _UNO_LINGU_HXX +#include +#endif + +#ifndef _FMTHBSH_HXX //autogen +#include +#endif +#ifndef _FMTANCHR_HXX //autogen +#include +#endif +#ifndef _FMTORNT_HXX //autogen +#include +#endif +#ifndef _FMTSRND_HXX //autogen +#include +#endif +#ifndef _FMTFSIZE_HXX //autogen +#include +#endif +#ifndef _FMTFLD_HXX //autogen +#include +#endif +#ifndef _FMTRFMRK_HXX //autogen +#include +#endif +#ifndef _FMTTSPLT_HXX //autogen +#include +#endif +#ifndef _FMTEIRO_HXX //autogen +#include +#endif +#ifndef _FMTCLDS_HXX //autogen +#include +#endif +#ifndef _FMTURL_HXX //autogen +#include +#endif +#ifndef _FMTCNTNT_HXX //autogen +#include +#endif +#ifndef _FMTHDFT_HXX //autogen +#include +#endif +#ifndef _FMTPDSC_HXX //autogen +#include +#endif +#ifndef _FMTFTN_HXX //autogen +#include +#endif +#ifndef _FMTFORDR_HXX //autogen +#include +#endif +#ifndef _FMTFLCNT_HXX //autogen +#include +#endif +#ifndef _FCHRFMT_HXX //autogen +#include +#endif +#ifndef _FMTINFMT_HXX //autogen +#include +#endif +#ifndef _FMTCNCT_HXX //autogen +#include +#endif +#ifndef _FMTLINE_HXX +#include +#endif +#ifndef _FMTFTNTX_HXX +#include +#endif +#ifndef _EDITSH_HXX +#include +#endif +#ifndef _PAM_HXX +#include +#endif +#ifndef _INIT_HXX +#include +#endif +#ifndef _PARATR_HXX +#include +#endif +#ifndef _GRFATR_HXX +#include +#endif +#ifndef _TOX_HXX +#include +#endif +#ifndef _CELLATR_HXX +#include +#endif +#ifndef _TBLAFMT_HXX +#include +#endif +#ifndef _VISCRS_HXX +#include +#endif +#ifndef _FNTCACHE_HXX +#include +#endif +#ifndef _DOC_HXX +#include +#endif +#ifndef _NUMRULE_HXX +#include +#endif +#ifndef _ACMPLWRD_HXX +#include +#endif +#ifndef _FMTCLBL_HXX +#include +#endif +#ifndef _CMDID_H +#include +#endif +#ifndef _BREAKIT_HXX +#include +#endif + +// ! Code for the new GraphicObject +#ifndef USE_GRFOBJECT + +#ifndef _GRFCACHE_HXX +#include +#endif + +#endif + + +extern void _FrmFinit(); +extern void ClearFEShellTabCols(); + +/************************************************************************* +|* einige Bereiche fuer die Set in Collections / Nodes +|*************************************************************************/ + // AttrSet-Range fuer die 2 Break-Attribute +USHORT __FAR_DATA aBreakSetRange[] = { + RES_PAGEDESC, RES_BREAK, + 0 }; + + // AttrSet-Range fuer die TxtFmtColl +USHORT __FAR_DATA aTxtFmtCollSetRange[] = { + RES_FRMATR_BEGIN, RES_FRMATR_END-1, + RES_CHRATR_BEGIN, RES_CHRATR_END-1, + RES_PARATR_BEGIN, RES_PARATR_END-1, + RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1, + 0 +}; + + // AttrSet-Range fuer die GrfFmtColl +USHORT __FAR_DATA aGrfFmtCollSetRange[] = { + RES_FRMATR_BEGIN, RES_FRMATR_END-1, + RES_GRFATR_BEGIN, RES_GRFATR_END-1, + RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1, + 0 +}; + + // AttrSet-Range fuer die TextNode +USHORT __FAR_DATA aTxtNodeSetRange[] = { + RES_FRMATR_BEGIN, RES_FRMATR_END-1, + RES_CHRATR_BEGIN, RES_CHRATR_END-1, + RES_PARATR_BEGIN, RES_PARATR_END-1, + RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1, + 0 +}; + + // AttrSet-Range fuer die NoTxtNode +USHORT __FAR_DATA aNoTxtNodeSetRange[] = { + RES_FRMATR_BEGIN, RES_FRMATR_END-1, + RES_GRFATR_BEGIN, RES_GRFATR_END-1, + RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1, + 0 +}; + +USHORT __FAR_DATA aTableSetRange[] = { + RES_FILL_ORDER, RES_FRM_SIZE, + RES_LR_SPACE, RES_BREAK, + RES_BACKGROUND, RES_SHADOW, + RES_HORI_ORIENT, RES_HORI_ORIENT, + RES_KEEP, RES_KEEP, + RES_LAYOUT_SPLIT, RES_LAYOUT_SPLIT, + RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1, + 0 +}; + +USHORT __FAR_DATA aTableLineSetRange[] = { + RES_FILL_ORDER, RES_FRM_SIZE, + RES_LR_SPACE, RES_UL_SPACE, + RES_BACKGROUND, RES_SHADOW, + RES_PROTECT, RES_PROTECT, + RES_VERT_ORIENT, RES_VERT_ORIENT, + RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1, + 0 +}; + +USHORT __FAR_DATA aTableBoxSetRange[] = { + RES_FILL_ORDER, RES_FRM_SIZE, + RES_LR_SPACE, RES_UL_SPACE, + RES_BACKGROUND, RES_SHADOW, + RES_PROTECT, RES_PROTECT, + RES_VERT_ORIENT, RES_VERT_ORIENT, + RES_BOXATR_BEGIN, RES_BOXATR_END-1, + RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1, + 0 +}; + +// AttrSet-Range fuer die SwFrmFmt +USHORT __FAR_DATA aFrmFmtSetRange[] = { + RES_FRMATR_BEGIN, RES_FRMATR_END-1, + RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1, + 0 +}; + +// AttrSet-Range fuer die SwCharFmt +USHORT __FAR_DATA aCharFmtSetRange[] = { + RES_CHRATR_BEGIN, RES_CHRATR_END-1, + RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1, + 0 +}; + +// AttrSet-Range fuer die SwPageDescFmt +USHORT __FAR_DATA aPgFrmFmtSetRange[] = { + RES_FRMATR_BEGIN, RES_FRMATR_END-1, + RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1, + 0 +}; + +/****************************************************************************** + * lege eine Tabelle fuer einen Zugriff auf die + * Default-Format-Attribute an + ******************************************************************************/ +SwDfltAttrTab __FAR_DATA aAttrTab; + +SfxItemInfo __FAR_DATA aSlotTab[] = +{ + { SID_ATTR_CHAR_CASEMAP, SFX_ITEM_POOLABLE }, // RES_CHRATR_CASEMAP + { SID_ATTR_CHAR_CHARSETCOLOR, SFX_ITEM_POOLABLE }, // RES_CHRATR_CHARSETCOLOR + { SID_ATTR_CHAR_COLOR, SFX_ITEM_POOLABLE }, // RES_CHRATR_COLOR + { SID_ATTR_CHAR_CONTOUR, SFX_ITEM_POOLABLE }, // RES_CHRATR_CONTOUR + { SID_ATTR_CHAR_STRIKEOUT, SFX_ITEM_POOLABLE }, // RES_CHRATR_CROSSEDOUT + { SID_ATTR_CHAR_ESCAPEMENT, SFX_ITEM_POOLABLE }, // RES_CHRATR_ESCAPEMENT + { SID_ATTR_CHAR_FONT, SFX_ITEM_POOLABLE }, // RES_CHRATR_FONT + { SID_ATTR_CHAR_FONTHEIGHT, SFX_ITEM_POOLABLE }, // RES_CHRATR_FONTSIZE + { SID_ATTR_CHAR_KERNING, SFX_ITEM_POOLABLE }, // RES_CHRATR_KERNING + { SID_ATTR_CHAR_LANGUAGE, SFX_ITEM_POOLABLE }, // RES_CHRATR_LANGUAGE + { SID_ATTR_CHAR_POSTURE, SFX_ITEM_POOLABLE }, // RES_CHRATR_POSTURE + { SID_ATTR_CHAR_PROPSIZE, SFX_ITEM_POOLABLE }, // RES_CHRATR_PROPORTIONALFONTSIZE + { SID_ATTR_CHAR_SHADOWED, SFX_ITEM_POOLABLE }, // RES_CHRATR_SHADOWED + { SID_ATTR_CHAR_UNDERLINE, SFX_ITEM_POOLABLE }, // RES_CHRATR_UNDERLINE + { SID_ATTR_CHAR_WEIGHT, SFX_ITEM_POOLABLE }, // RES_CHRATR_WEIGHT + { SID_ATTR_CHAR_WORDLINEMODE, SFX_ITEM_POOLABLE }, // RES_CHRATR_WORDLINEMODE + { SID_ATTR_CHAR_AUTOKERN, SFX_ITEM_POOLABLE }, // RES_CHRATR_AUTOKERN + { SID_ATTR_FLASH, SFX_ITEM_POOLABLE }, // RES_CHRATR_BLINK + { 0, SFX_ITEM_POOLABLE }, // RES_CHRATR_NOLINEBREAK + { 0, SFX_ITEM_POOLABLE }, // RES_CHRATR_NOHYPHEN + { SID_ATTR_BRUSH_CHAR, SFX_ITEM_POOLABLE }, // RES_CHRATR_BACKGROUND + { 0, SFX_ITEM_POOLABLE }, // RES_CHRATR_CJK_FONT + { 0, SFX_ITEM_POOLABLE }, // RES_CHRATR_CJK_FONTSIZE + { 0, SFX_ITEM_POOLABLE }, // RES_CHRATR_CJK_LANGUAGE + { 0, SFX_ITEM_POOLABLE }, // RES_CHRATR_CJK_POSTURE + { 0, SFX_ITEM_POOLABLE }, // RES_CHRATR_CJK_WEIGHT + { 0, SFX_ITEM_POOLABLE }, // RES_CHRATR_CTL_FONT + { 0, SFX_ITEM_POOLABLE }, // RES_CHRATR_CTL_FONTSIZE + { 0, SFX_ITEM_POOLABLE }, // RES_CHRATR_CTL_LANGUAGE + { 0, SFX_ITEM_POOLABLE }, // RES_CHRATR_CTL_POSTURE + { 0, SFX_ITEM_POOLABLE }, // RES_CHRATR_CTL_WEIGHT + { 0, SFX_ITEM_POOLABLE }, // RES_CHRATR_WRITING_DIRECTION + { 0, SFX_ITEM_POOLABLE }, // RES_CHRATR_DUMMY2 + { 0, SFX_ITEM_POOLABLE }, // RES_CHRATR_DUMMY3 + { 0, SFX_ITEM_POOLABLE }, // RES_CHRATR_DUMMY4 + { 0, SFX_ITEM_POOLABLE }, // RES_CHRATR_DUMMY5 + { 0, SFX_ITEM_POOLABLE }, // RES_CHRATR_DUMMY1 + + { FN_TXTATR_INET, 0 }, // RES_TXTATR_INETFMT + { 0, SFX_ITEM_POOLABLE }, // RES_TXTATR_DUMMY4 + { 0, 0 }, // RES_TXTATR_REFMARK + { 0, 0 }, // RES_TXTATR_TOXMARK + { 0, 0 }, // RES_TXTATR_CHARFMT + { 0, SFX_ITEM_POOLABLE }, // RES_TXTATR_TWO_LINES, + { 0, 0 }, // RES_TXTATR_CJK_RUBY, + { 0, SFX_ITEM_POOLABLE }, // RES_TXTATR_UNKNOWN_CONTAINER, + { 0, SFX_ITEM_POOLABLE }, // RES_TXTATR_DUMMY5, + { 0, SFX_ITEM_POOLABLE }, // RES_TXTATR_DUMMY6, + + { 0, 0 }, // RES_TXTATR_FIELD + { 0, 0 }, // RES_TXTATR_FLYCNT + { 0, 0 }, // RES_TXTATR_FTN + { 0, SFX_ITEM_POOLABLE }, // RES_TXTATR_SOFTHYPH + { 0, SFX_ITEM_POOLABLE }, // RES_TXTATR_HARDBLANK + { 0, SFX_ITEM_POOLABLE }, // RES_TXTATR_DUMMY1 + { 0, SFX_ITEM_POOLABLE }, // RES_TXTATR_DUMMY2 + + { SID_ATTR_PARA_LINESPACE, SFX_ITEM_POOLABLE }, // RES_PARATR_LINESPACING + { SID_ATTR_PARA_ADJUST, SFX_ITEM_POOLABLE }, // RES_PARATR_ADJUST + { SID_ATTR_PARA_SPLIT, SFX_ITEM_POOLABLE }, // RES_PARATR_SPLIT + { SID_ATTR_PARA_ORPHANS, SFX_ITEM_POOLABLE }, // RES_PARATR_ORPHANS + { SID_ATTR_PARA_WIDOWS, SFX_ITEM_POOLABLE }, // RES_PARATR_WIDOWS + { SID_ATTR_TABSTOP, SFX_ITEM_POOLABLE }, // RES_PARATR_TABSTOP + { SID_ATTR_PARA_HYPHENZONE, SFX_ITEM_POOLABLE }, // RES_PARATR_HYPHENZONE + { FN_FORMAT_DROPCAPS, 0 }, // RES_PARATR_DROP + { SID_ATTR_PARA_REGISTER, SFX_ITEM_POOLABLE }, // RES_PARATR_REGISTER + { SID_ATTR_PARA_NUMRULE, 0 }, // RES_PARATR_NUMRULE + { 0, SFX_ITEM_POOLABLE }, // RES_PARATR_DUMMY2 + + { 0, SFX_ITEM_POOLABLE }, // RES_FILL_ORDER + { 0, SFX_ITEM_POOLABLE }, // RES_FRM_SIZE + { SID_ATTR_PAGE_PAPERBIN, SFX_ITEM_POOLABLE }, // RES_PAPER_BIN + { SID_ATTR_LRSPACE, SFX_ITEM_POOLABLE }, // RES_LR_SPACE + { SID_ATTR_ULSPACE, SFX_ITEM_POOLABLE }, // RES_UL_SPACE + { 0, 0 }, // RES_PAGEDESC + { SID_ATTR_PARA_PAGEBREAK, SFX_ITEM_POOLABLE }, // RES_BREAK + { 0, 0 }, // RES_CNTNT + { 0, SFX_ITEM_POOLABLE }, // RES_HEADER + { 0, SFX_ITEM_POOLABLE }, // RES_FOOTER + { 0, SFX_ITEM_POOLABLE }, // RES_PRINT + { FN_OPAQUE, SFX_ITEM_POOLABLE }, // RES_OPAQUE + { FN_SET_PROTECT, SFX_ITEM_POOLABLE }, // RES_PROTECT + { FN_SURROUND, SFX_ITEM_POOLABLE }, // RES_SURROUND + { FN_VERT_ORIENT, SFX_ITEM_POOLABLE }, // RES_VERT_ORIENT + { FN_HORI_ORIENT, SFX_ITEM_POOLABLE }, // RES_HORI_ORIENT + { 0, 0 }, // RES_ANCHOR + { SID_ATTR_BRUSH, SFX_ITEM_POOLABLE }, // RES_BACKGROUND + { SID_ATTR_BORDER_OUTER, SFX_ITEM_POOLABLE }, // RES_BOX + { SID_ATTR_BORDER_SHADOW, SFX_ITEM_POOLABLE }, // RES_SHADOW + { SID_ATTR_MACROITEM, SFX_ITEM_POOLABLE }, // RES_FRMMACRO + { FN_ATTR_COLUMNS, SFX_ITEM_POOLABLE }, // RES_COL + { SID_ATTR_PARA_KEEP, SFX_ITEM_POOLABLE }, // RES_KEEP + { 0, SFX_ITEM_POOLABLE }, // RES_URL + { 0, SFX_ITEM_POOLABLE }, // RES_EDIT_IN_READONLY + + { 0, SFX_ITEM_POOLABLE }, // RES_LAYOUT_SPLIT + { 0, 0 }, // RES_CHAIN + { 0, SFX_ITEM_POOLABLE }, // RES_FRMATR_DUMMY2 + { 0, SFX_ITEM_POOLABLE }, // RES_LINENUMBER + { 0, SFX_ITEM_POOLABLE }, // RES_FTN_AT_TXTEND + { 0, SFX_ITEM_POOLABLE }, // RES_END_AT_TXTEND + { 0, SFX_ITEM_POOLABLE }, // RES_COLUMNBALANCE + { 0, SFX_ITEM_POOLABLE }, // RES_FRMATR_DUMMY7 + { 0, SFX_ITEM_POOLABLE }, // RES_FRMATR_DUMMY8 + { 0, SFX_ITEM_POOLABLE }, // RES_FRMATR_DUMMY9 + + { 0, SFX_ITEM_POOLABLE }, // RES_GRFATR_MIRRORGRF + { SID_ATTR_GRAF_CROP, SFX_ITEM_POOLABLE }, // RES_GRFATR_CROPGRF + { 0, SFX_ITEM_POOLABLE }, // RES_GRFATR_ROTATION, + { 0, SFX_ITEM_POOLABLE }, // RES_GRFATR_LUMINANCE, + { 0, SFX_ITEM_POOLABLE }, // RES_GRFATR_CONTRAST, + { 0, SFX_ITEM_POOLABLE }, // RES_GRFATR_CHANNELR, + { 0, SFX_ITEM_POOLABLE }, // RES_GRFATR_CHANNELG, + { 0, SFX_ITEM_POOLABLE }, // RES_GRFATR_CHANNELB, + { 0, SFX_ITEM_POOLABLE }, // RES_GRFATR_GAMMA, + { 0, SFX_ITEM_POOLABLE }, // RES_GRFATR_INVERT, + { 0, SFX_ITEM_POOLABLE }, // RES_GRFATR_TRANSPARENCY, + { 0, SFX_ITEM_POOLABLE }, // RES_GRFATR_DUMMY1, + { 0, SFX_ITEM_POOLABLE }, // RES_GRFATR_DUMMY2, + { 0, SFX_ITEM_POOLABLE }, // RES_GRFATR_DUMMY3, + { 0, SFX_ITEM_POOLABLE }, // RES_GRFATR_DUMMY4, + { 0, SFX_ITEM_POOLABLE }, // RES_GRFATR_DUMMY5, + { 0, SFX_ITEM_POOLABLE }, // RES_GRFATR_DUMMY6, + + { 0, SFX_ITEM_POOLABLE }, // RES_BOXATR_FORMAT + { 0, 0 }, // RES_BOXATR_FORMULA, + { 0, SFX_ITEM_POOLABLE }, // RES_BOXATR_VALUE + + { 0, SFX_ITEM_POOLABLE } // RES_UNKNOWNATR_CONTAINER +}; + + +USHORT* SwAttrPool::pVersionMap1 = 0; +USHORT* SwAttrPool::pVersionMap2 = 0; +USHORT* SwAttrPool::pVersionMap3 = 0; + +// ! Code for the new GraphicObject +#ifndef USE_GRFOBJECT + +SwGraphicCache* SwGraphicCacheObj::pGrfCache = 0; + +#endif + +SwIndexReg* SwIndexReg::pEmptyIndexArray = 0; + +const sal_Char* __FAR_DATA pMarkToTable = "table"; +const sal_Char* __FAR_DATA pMarkToFrame = "frame"; +const sal_Char* __FAR_DATA pMarkToRegion = "region"; +const sal_Char* __FAR_DATA pMarkToText = "text"; +const sal_Char* __FAR_DATA pMarkToOutline = "outline"; +const sal_Char* __FAR_DATA pMarkToGraphic = "graphic"; +const sal_Char* __FAR_DATA pMarkToOLE = "ole"; + +SvPtrarr *pGlobalOLEExcludeList = 0; + +SwAutoCompleteWord* SwDoc::pACmpltWords = 0; + +SwBreakIt* pBreakIt = 0; +CharClass* pAppCharClass = 0; + +/****************************************************************************** + * void _InitCore() + ******************************************************************************/ +class SwDontWrite : public SfxBoolItem +{ +public: + SwDontWrite( USHORT nId ) : SfxBoolItem( nId ) {} + + virtual USHORT GetVersion( USHORT nFFVer ) const; +}; + +USHORT SwDontWrite::GetVersion( USHORT nFFVer ) const +{ return USHRT_MAX; } + + + + +void _InitCore() +{ + SfxPoolItem* pItem; + + // erstmal alle Attribut-Pointer auf 0 setzen + memset( aAttrTab, 0, (POOLATTR_END - POOLATTR_BEGIN) * + sizeof( SfxPoolItem* ) ); + + aAttrTab[ RES_CHRATR_CASEMAP- POOLATTR_BEGIN ] = new SvxCaseMapItem; + aAttrTab[ RES_CHRATR_CHARSETCOLOR- POOLATTR_BEGIN ] = new SvxCharSetColorItem; + aAttrTab[ RES_CHRATR_COLOR- POOLATTR_BEGIN ] = new SvxColorItem; + aAttrTab[ RES_CHRATR_CONTOUR- POOLATTR_BEGIN ] = new SvxContourItem; + aAttrTab[ RES_CHRATR_CROSSEDOUT- POOLATTR_BEGIN ] = new SvxCrossedOutItem; + aAttrTab[ RES_CHRATR_ESCAPEMENT- POOLATTR_BEGIN ] = new SvxEscapementItem; + aAttrTab[ RES_CHRATR_FONT- POOLATTR_BEGIN ] = + new SvxFontItem( FAMILY_ROMAN, + System::GetStandardFont( STDFONT_ROMAN ).GetName(), + aEmptyStr, PITCH_VARIABLE, +/*?? GetSystemCharSet() ->*/ ::gsl_getSystemTextEncoding() ); + + aAttrTab[ RES_CHRATR_FONTSIZE- POOLATTR_BEGIN ] = new SvxFontHeightItem; + aAttrTab[ RES_CHRATR_KERNING- POOLATTR_BEGIN ] = new SvxKerningItem; + aAttrTab[ RES_CHRATR_LANGUAGE- POOLATTR_BEGIN ] = new SvxLanguageItem(LANGUAGE_DONTKNOW); + aAttrTab[ RES_CHRATR_POSTURE- POOLATTR_BEGIN ] = new SvxPostureItem; + aAttrTab[ RES_CHRATR_PROPORTIONALFONTSIZE- POOLATTR_BEGIN ] = new SvxPropSizeItem; + aAttrTab[ RES_CHRATR_SHADOWED- POOLATTR_BEGIN ] = new SvxShadowedItem; + aAttrTab[ RES_CHRATR_UNDERLINE- POOLATTR_BEGIN ] = new SvxUnderlineItem; + aAttrTab[ RES_CHRATR_WEIGHT- POOLATTR_BEGIN ] = new SvxWeightItem; + aAttrTab[ RES_CHRATR_WORDLINEMODE- POOLATTR_BEGIN ] = new SvxWordLineModeItem; + aAttrTab[ RES_CHRATR_AUTOKERN- POOLATTR_BEGIN ] = new SvxAutoKernItem; + aAttrTab[ RES_CHRATR_BLINK - POOLATTR_BEGIN ] + = new SvxBlinkItem( FALSE, RES_CHRATR_BLINK ); + aAttrTab[ RES_CHRATR_NOHYPHEN - POOLATTR_BEGIN ] + = new SvxNoHyphenItem( TRUE, RES_CHRATR_NOHYPHEN ); + aAttrTab[ RES_CHRATR_NOLINEBREAK- POOLATTR_BEGIN ] + = new SvxNoLinebreakItem( TRUE, RES_CHRATR_NOLINEBREAK ); + aAttrTab[ RES_CHRATR_BACKGROUND - POOLATTR_BEGIN ] + = new SvxBrushItem( RES_CHRATR_BACKGROUND ); + + // CJK-Attributes + aAttrTab[ RES_CHRATR_CJK_FONT - POOLATTR_BEGIN ] = new SvxFontItem( + FAMILY_ROMAN, System::GetStandardFont( STDFONT_ROMAN ).GetName(), + aEmptyStr, PITCH_VARIABLE, ::gsl_getSystemTextEncoding(), + RES_CHRATR_CJK_FONT ); + + pItem = new SvxFontHeightItem; + pItem->SetWhich( RES_CHRATR_CJK_FONTSIZE ); + aAttrTab[ RES_CHRATR_CJK_FONTSIZE - POOLATTR_BEGIN ] = pItem; + + pItem = new SvxLanguageItem(LANGUAGE_DONTKNOW); + pItem->SetWhich( RES_CHRATR_CJK_LANGUAGE ); + aAttrTab[ RES_CHRATR_CJK_LANGUAGE - POOLATTR_BEGIN ] = pItem; + + pItem = new SvxPostureItem; + pItem->SetWhich( RES_CHRATR_CJK_POSTURE ); + aAttrTab[ RES_CHRATR_CJK_POSTURE - POOLATTR_BEGIN ] = pItem; + + pItem = new SvxWeightItem; + pItem->SetWhich( RES_CHRATR_CJK_WEIGHT ); + aAttrTab[ RES_CHRATR_CJK_WEIGHT - POOLATTR_BEGIN ] = pItem; + + // CTL-Attributes + aAttrTab[ RES_CHRATR_CTL_FONT - POOLATTR_BEGIN ] = new SvxFontItem( + FAMILY_ROMAN, System::GetStandardFont( STDFONT_ROMAN ).GetName(), + aEmptyStr, PITCH_VARIABLE, ::gsl_getSystemTextEncoding(), + RES_CHRATR_CTL_FONT ); + + pItem = new SvxFontHeightItem; + pItem->SetWhich( RES_CHRATR_CTL_FONTSIZE ); + aAttrTab[ RES_CHRATR_CTL_FONTSIZE - POOLATTR_BEGIN ] = pItem; + + pItem = new SvxLanguageItem(LANGUAGE_DONTKNOW); + pItem->SetWhich( RES_CHRATR_CTL_LANGUAGE ); + aAttrTab[ RES_CHRATR_CTL_LANGUAGE - POOLATTR_BEGIN ] = pItem; + + pItem = new SvxPostureItem; + pItem->SetWhich( RES_CHRATR_CTL_POSTURE ); + aAttrTab[ RES_CHRATR_CTL_POSTURE - POOLATTR_BEGIN ] = pItem; + + pItem = new SvxWeightItem; + pItem->SetWhich( RES_CHRATR_CTL_WEIGHT ); + aAttrTab[ RES_CHRATR_CTL_WEIGHT - POOLATTR_BEGIN ] = pItem; + + aAttrTab[ RES_CHRATR_CTL_WEIGHT - POOLATTR_BEGIN ] = pItem; + + aAttrTab[ RES_CHRATR_WRITING_DIRECTION - POOLATTR_BEGIN ] = + new SfxBoolItem( RES_CHRATR_WRITING_DIRECTION ); + +// CharakterAttr - Dummies + aAttrTab[ RES_CHRATR_DUMMY1 - POOLATTR_BEGIN ] = new SfxBoolItem( RES_CHRATR_DUMMY1 ); + aAttrTab[ RES_CHRATR_DUMMY2 - POOLATTR_BEGIN ] = new SfxBoolItem( RES_CHRATR_DUMMY2 ); + aAttrTab[ RES_CHRATR_DUMMY3 - POOLATTR_BEGIN ] = new SfxBoolItem( RES_CHRATR_DUMMY3 ); + aAttrTab[ RES_CHRATR_DUMMY4 - POOLATTR_BEGIN ] = new SfxBoolItem( RES_CHRATR_DUMMY4 ); + aAttrTab[ RES_CHRATR_DUMMY5 - POOLATTR_BEGIN ] = new SfxBoolItem( RES_CHRATR_DUMMY5 ); +// CharakterAttr - Dummies + +// TextAttr Ende - Dummies + aAttrTab[ RES_TXTATR_DUMMY4 - POOLATTR_BEGIN ] + = new SfxBoolItem( RES_TXTATR_DUMMY4 ); +// TextAttr Ende - Dummies + + aAttrTab[ RES_TXTATR_INETFMT - POOLATTR_BEGIN ] + = new SwFmtINetFmt( aEmptyStr, aEmptyStr ); + aAttrTab[ RES_TXTATR_REFMARK - POOLATTR_BEGIN ] = new SwFmtRefMark( aEmptyStr ); + aAttrTab[ RES_TXTATR_TOXMARK - POOLATTR_BEGIN ] = new SwTOXMark; + aAttrTab[ RES_TXTATR_CHARFMT- POOLATTR_BEGIN ] = new SwFmtCharFmt( 0 ); + + aAttrTab[ RES_TXTATR_TWO_LINES - POOLATTR_BEGIN ] = +//JP 28.07.00: must be changed to the correct attributes!! + new SfxBoolItem( RES_TXTATR_TWO_LINES); + aAttrTab[ RES_TXTATR_CJK_RUBY - POOLATTR_BEGIN ] = +//JP 28.07.00: must be changed to the correct attributes!! + new SfxBoolItem( RES_TXTATR_CJK_RUBY ); + aAttrTab[ RES_TXTATR_UNKNOWN_CONTAINER - POOLATTR_BEGIN ] = + new SvXMLAttrContainerItem( RES_TXTATR_UNKNOWN_CONTAINER ); + + aAttrTab[ RES_TXTATR_FIELD- POOLATTR_BEGIN ] = new SwFmtFld; + aAttrTab[ RES_TXTATR_FLYCNT - POOLATTR_BEGIN ] = new SwFmtFlyCnt( 0 ); + aAttrTab[ RES_TXTATR_FTN - POOLATTR_BEGIN ] = new SwFmtFtn; + aAttrTab[ RES_TXTATR_SOFTHYPH- POOLATTR_BEGIN ] = new SwFmtSoftHyph; + aAttrTab[ RES_TXTATR_HARDBLANK- POOLATTR_BEGIN ] = new SwFmtHardBlank( ' ', FALSE ); + +// TextAttr ohne Ende - Dummies + aAttrTab[ RES_TXTATR_DUMMY1 - POOLATTR_BEGIN ] = new SfxBoolItem( RES_TXTATR_DUMMY1 ); + aAttrTab[ RES_TXTATR_DUMMY2 - POOLATTR_BEGIN ] = new SfxBoolItem( RES_TXTATR_DUMMY2 ); + aAttrTab[ RES_TXTATR_DUMMY5 - POOLATTR_BEGIN ] = new SfxBoolItem( RES_TXTATR_DUMMY5 ); + aAttrTab[ RES_TXTATR_DUMMY6 - POOLATTR_BEGIN ] = new SfxBoolItem( RES_TXTATR_DUMMY6 ); +// TextAttr ohne Ende - Dummies + + aAttrTab[ RES_PARATR_LINESPACING- POOLATTR_BEGIN ] = new SvxLineSpacingItem; + aAttrTab[ RES_PARATR_ADJUST- POOLATTR_BEGIN ] = new SvxAdjustItem; + aAttrTab[ RES_PARATR_SPLIT- POOLATTR_BEGIN ] = new SvxFmtSplitItem; + aAttrTab[ RES_PARATR_WIDOWS- POOLATTR_BEGIN ] = new SvxWidowsItem; + aAttrTab[ RES_PARATR_ORPHANS- POOLATTR_BEGIN ] = new SvxOrphansItem; + aAttrTab[ RES_PARATR_TABSTOP- POOLATTR_BEGIN ] = new + SvxTabStopItem( 1, SVX_TAB_DEFDIST ); + + pItem = new SvxHyphenZoneItem; + ((SvxHyphenZoneItem*)pItem)->GetMaxHyphens() = 0; // Default z.Z. auf 0 + aAttrTab[ RES_PARATR_HYPHENZONE- POOLATTR_BEGIN ] = pItem; + + aAttrTab[ RES_PARATR_DROP- POOLATTR_BEGIN ] = new SwFmtDrop; + aAttrTab[ RES_PARATR_REGISTER - POOLATTR_BEGIN ] = new SwRegisterItem( FALSE ); + aAttrTab[ RES_PARATR_NUMRULE - POOLATTR_BEGIN ] = new SwNumRuleItem( aEmptyStr ); + +// ParaAttr - Dummies + aAttrTab[ RES_PARATR_DUMMY2 - POOLATTR_BEGIN ] = new SfxBoolItem( RES_PARATR_DUMMY2 ); +// ParatAttr - Dummies + + aAttrTab[ RES_FILL_ORDER- POOLATTR_BEGIN ] = new SwFmtFillOrder; + aAttrTab[ RES_FRM_SIZE- POOLATTR_BEGIN ] = new SwFmtFrmSize; + aAttrTab[ RES_PAPER_BIN- POOLATTR_BEGIN ] = new SvxPaperBinItem; + aAttrTab[ RES_LR_SPACE- POOLATTR_BEGIN ] = new SvxLRSpaceItem; + aAttrTab[ RES_UL_SPACE- POOLATTR_BEGIN ] = new SvxULSpaceItem; + aAttrTab[ RES_PAGEDESC- POOLATTR_BEGIN ] = new SwFmtPageDesc; + aAttrTab[ RES_BREAK- POOLATTR_BEGIN ] = new SvxFmtBreakItem; + aAttrTab[ RES_CNTNT- POOLATTR_BEGIN ] = new SwFmtCntnt; + aAttrTab[ RES_HEADER- POOLATTR_BEGIN ] = new SwFmtHeader; + aAttrTab[ RES_FOOTER- POOLATTR_BEGIN ] = new SwFmtFooter; + aAttrTab[ RES_PRINT- POOLATTR_BEGIN ] = new SvxPrintItem; + aAttrTab[ RES_OPAQUE- POOLATTR_BEGIN ] = new SvxOpaqueItem; + aAttrTab[ RES_PROTECT- POOLATTR_BEGIN ] = new SvxProtectItem; + aAttrTab[ RES_SURROUND- POOLATTR_BEGIN ] = new SwFmtSurround; + aAttrTab[ RES_VERT_ORIENT- POOLATTR_BEGIN ] = new SwFmtVertOrient; + aAttrTab[ RES_HORI_ORIENT- POOLATTR_BEGIN ] = new SwFmtHoriOrient; + aAttrTab[ RES_ANCHOR- POOLATTR_BEGIN ] = new SwFmtAnchor; + aAttrTab[ RES_BACKGROUND- POOLATTR_BEGIN ] = new SvxBrushItem; + aAttrTab[ RES_BOX- POOLATTR_BEGIN ] = new SvxBoxItem; + aAttrTab[ RES_SHADOW- POOLATTR_BEGIN ] = new SvxShadowItem; + aAttrTab[ RES_FRMMACRO- POOLATTR_BEGIN ] = new SvxMacroItem; + aAttrTab[ RES_COL- POOLATTR_BEGIN ] = new SwFmtCol; + aAttrTab[ RES_KEEP - POOLATTR_BEGIN ] = new SvxFmtKeepItem( FALSE ); + aAttrTab[ RES_URL - POOLATTR_BEGIN ] = new SwFmtURL(); + aAttrTab[ RES_EDIT_IN_READONLY - POOLATTR_BEGIN ] = new SwFmtEditInReadonly; + aAttrTab[ RES_LAYOUT_SPLIT - POOLATTR_BEGIN ] = new SwFmtLayoutSplit; + aAttrTab[ RES_CHAIN - POOLATTR_BEGIN ] = new SwFmtChain; + aAttrTab[ RES_FRMATR_DUMMY2 - POOLATTR_BEGIN ] = new SfxBoolItem( RES_FRMATR_DUMMY2 ); + aAttrTab[ RES_LINENUMBER - POOLATTR_BEGIN ] = new SwFmtLineNumber; + aAttrTab[ RES_FTN_AT_TXTEND - POOLATTR_BEGIN ] = new SwFmtFtnAtTxtEnd; + aAttrTab[ RES_END_AT_TXTEND - POOLATTR_BEGIN ] = new SwFmtEndAtTxtEnd; + aAttrTab[ RES_COLUMNBALANCE - POOLATTR_BEGIN ] = new SwFmtNoBalancedColumns; + +// FrameAttr - Dummies + aAttrTab[ RES_FRMATR_DUMMY7 - POOLATTR_BEGIN ] = new SfxBoolItem( RES_FRMATR_DUMMY7 ); + aAttrTab[ RES_FRMATR_DUMMY8 - POOLATTR_BEGIN ] = new SfxBoolItem( RES_FRMATR_DUMMY8 ); + aAttrTab[ RES_FRMATR_DUMMY9 - POOLATTR_BEGIN ] = new SfxBoolItem( RES_FRMATR_DUMMY9 ); +// FrameAttr - Dummies + + aAttrTab[ RES_GRFATR_MIRRORGRF- POOLATTR_BEGIN ] = new SwMirrorGrf; + aAttrTab[ RES_GRFATR_CROPGRF- POOLATTR_BEGIN ] = new SwCropGrf; + + aAttrTab[ RES_GRFATR_ROTATION - POOLATTR_BEGIN ] = new SwRotationGrf; + aAttrTab[ RES_GRFATR_LUMINANCE - POOLATTR_BEGIN ] = new SwLuminanceGrf; + aAttrTab[ RES_GRFATR_CONTRAST - POOLATTR_BEGIN ] = new SwContrastGrf; + aAttrTab[ RES_GRFATR_CHANNELR - POOLATTR_BEGIN ] = new SwChannelRGrf; + aAttrTab[ RES_GRFATR_CHANNELG - POOLATTR_BEGIN ] = new SwChannelGGrf; + aAttrTab[ RES_GRFATR_CHANNELB - POOLATTR_BEGIN ] = new SwChannelBGrf; + aAttrTab[ RES_GRFATR_GAMMA - POOLATTR_BEGIN ] = new SwGammaGrf; + aAttrTab[ RES_GRFATR_INVERT - POOLATTR_BEGIN ] = new SwInvertGrf; + aAttrTab[ RES_GRFATR_TRANSPARENCY - POOLATTR_BEGIN ] = new SwTransparencyGrf; + aAttrTab[ RES_GRFATR_DRAWMODE - POOLATTR_BEGIN ] = new SwDrawModeGrf; + +// GraphicAttr - Dummies + aAttrTab[ RES_GRFATR_DUMMY1 - POOLATTR_BEGIN ] = new SfxBoolItem( RES_GRFATR_DUMMY1 ); + aAttrTab[ RES_GRFATR_DUMMY2 - POOLATTR_BEGIN ] = new SfxBoolItem( RES_GRFATR_DUMMY2 ); + aAttrTab[ RES_GRFATR_DUMMY3 - POOLATTR_BEGIN ] = new SfxBoolItem( RES_GRFATR_DUMMY3 ); + aAttrTab[ RES_GRFATR_DUMMY4 - POOLATTR_BEGIN ] = new SfxBoolItem( RES_GRFATR_DUMMY4 ); + aAttrTab[ RES_GRFATR_DUMMY5 - POOLATTR_BEGIN ] = new SfxBoolItem( RES_GRFATR_DUMMY5 ); +// GraphicAttr - Dummies + + aAttrTab[ RES_BOXATR_FORMAT- POOLATTR_BEGIN ] = new SwTblBoxNumFormat; + aAttrTab[ RES_BOXATR_FORMULA- POOLATTR_BEGIN ] = new SwTblBoxFormula( aEmptyStr ); + aAttrTab[ RES_BOXATR_VALUE- POOLATTR_BEGIN ] = new SwTblBoxValue; + + aAttrTab[ RES_UNKNOWNATR_CONTAINER- POOLATTR_BEGIN ] = + new SvXMLAttrContainerItem( RES_UNKNOWNATR_CONTAINER ); + + // 1. Version - neue Attribute: + // - RES_CHRATR_BLINK + // - RES_CHRATR_NOHYPHEN + // - RES_CHRATR_NOLINEBREAK + // - RES_PARATR_REGISTER + // + 2 Dummies fuer die einzelnen "Bereiche" + SwAttrPool::pVersionMap1 = new USHORT[ 60 ]; + for( USHORT i = 1; i <= 17; i++ ) + SwAttrPool::pVersionMap1[ i-1 ] = i; + for ( i = 18; i <= 27; ++i ) + SwAttrPool::pVersionMap1[ i-1 ] = i + 5; + for ( i = 28; i <= 35; ++i ) + SwAttrPool::pVersionMap1[ i-1 ] = i + 7; + for ( i = 36; i <= 58; ++i ) + SwAttrPool::pVersionMap1[ i-1 ] = i + 10; + for ( i = 59; i <= 60; ++i ) + SwAttrPool::pVersionMap1[ i-1 ] = i + 12; + + // 2. Version - neue Attribute: + // 10 Dummies fuer den Frame "Bereich" + SwAttrPool::pVersionMap2 = new USHORT[ 75 ]; + for( i = 1; i <= 70; i++ ) + SwAttrPool::pVersionMap2[ i-1 ] = i; + for ( i = 71; i <= 75; ++i ) + SwAttrPool::pVersionMap2[ i-1 ] = i + 10; + + // 3. Version - neue Attribute: + // neue Attribute und Dummies fuer die CJK-Version + // und neue Grafik-Attribute + SwAttrPool::pVersionMap3 = new USHORT[ 86 ]; + for( i = 1; i <= 21; i++ ) + SwAttrPool::pVersionMap3[ i-1 ] = i; + for ( i = 22; i <= 27; ++i ) + SwAttrPool::pVersionMap3[ i-1 ] = i + 15; + for ( i = 28; i <= 82; ++i ) + SwAttrPool::pVersionMap3[ i-1 ] = i + 20; + for ( i = 83; i <= 86; ++i ) + SwAttrPool::pVersionMap3[ i-1 ] = i + 35; + + pBreakIt = new SwBreakIt(); + pAppCharClass = new CharClass( SvxCreateLocale( LANGUAGE_SYSTEM )); + + _FrmInit(); + _TextInit(); + + SwSelPaintRects::pMapMode = new MapMode; + SwFntObj::pPixMap = new MapMode; + +// ! Code for the new GraphicObject +#ifndef USE_GRFOBJECT + // Grafik-Cache Klasse anlegen + SwGraphicCacheObj::pGrfCache = new SwGraphicCache; + +#endif + + SwIndexReg::pEmptyIndexArray = new SwIndexReg; + + pGlobalOLEExcludeList = new SvPtrarr; + + const SvxSwAutoFmtFlags& rAFlags = OFF_APP()->GetAutoCorrect()->GetSwFlags(); + SwDoc::pACmpltWords = new SwAutoCompleteWord( rAFlags.nAutoCmpltListLen, + rAFlags.nAutoCmpltWordLen ); +} + +/****************************************************************************** + * void _FinitCore() + ******************************************************************************/ + + + +void _FinitCore() +{ + _FrmFinit(); + _TextFinit(); + + delete pBreakIt; + delete pAppCharClass; + +// ! Code for the new GraphicObject +#ifndef USE_GRFOBJECT + + // Grafik-Cache Klasse zerstoeren + delete SwGraphicCacheObj::pGrfCache; + +#endif + + // das default TableAutoFormat zerstoeren + delete SwTableAutoFmt::pDfltBoxAutoFmt; + + delete SwSelPaintRects::pMapMode; + delete SwFntObj::pPixMap; + + delete SwEditShell::pAutoFmtFlags; + delete SwNumRule::pDefBulletFont; + +#ifndef PRODUCT + //Defaultattribut freigeben lassen um asserts zu vermeiden. + if ( aAttrTab[0]->GetRef() ) + SfxItemPool::ReleaseDefaults( aAttrTab, POOLATTR_END-POOLATTR_BEGIN, FALSE); +#endif + + delete SwDoc::pTextNmArray; + delete SwDoc::pListsNmArray; + delete SwDoc::pExtraNmArray; + delete SwDoc::pRegisterNmArray; + delete SwDoc::pDocNmArray; + delete SwDoc::pHTMLNmArray; + delete SwDoc::pFrmFmtNmArray; + delete SwDoc::pChrFmtNmArray; + delete SwDoc::pHTMLChrFmtNmArray; + delete SwDoc::pPageDescNmArray; + delete SwDoc::pNumRuleNmArray; + delete SwDoc::pACmpltWords; + + // loesche alle default-Attribute + SfxPoolItem* pHt; + for( USHORT n = 0; n < POOLATTR_END - POOLATTR_BEGIN; n++ ) + if( 0 != ( pHt = aAttrTab[n] )) + delete pHt; + + ::ClearFEShellTabCols(); + + delete SwIndexReg::pEmptyIndexArray; + delete SwAttrPool::pVersionMap1; + delete SwAttrPool::pVersionMap2; + + for ( USHORT i = 0; i < pGlobalOLEExcludeList->Count(); ++i ) + delete (SvGlobalName*)(*pGlobalOLEExcludeList)[i]; + delete pGlobalOLEExcludeList; +} + +// returns the APP - CharClass instance - used for all ToUpper/ToLower/... +CharClass& GetAppCharClass() +{ + return *pAppCharClass; +} + + + diff --git a/sw/source/core/bastyp/makefile.mk b/sw/source/core/bastyp/makefile.mk new file mode 100644 index 000000000000..29f9edbf1231 --- /dev/null +++ b/sw/source/core/bastyp/makefile.mk @@ -0,0 +1,111 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-19 00:08:16 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (the "License"); You may not use this file +# except in compliance with the License. You may obtain a copy of the +# License at http://www.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=sw +TARGET=bastyp + +PROJECTPCH=core_pch +PDBTARGET=core_pch +PROJECTPCHSOURCE=..\core_1st\core_pch + +AUTOSEG=true + +# --- Settings ----------------------------------------------------- + +.INCLUDE : $(PRJ)$/inc$/swpre.mk +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/inc$/sw.mk + +# --- Files -------------------------------------------------------- + +CXXFILES = \ + bparr.cxx \ + breakit.cxx \ + calc.cxx \ + index.cxx \ + init.cxx \ + ring.cxx \ + swcache.cxx \ + swrect.cxx \ + swregion.cxx \ + swtypes.cxx \ + tabcol.cxx + +SLOFILES = \ + $(SLO)$/bparr.obj \ + $(SLO)$/breakit.obj \ + $(SLO)$/calc.obj \ + $(SLO)$/index.obj \ + $(SLO)$/init.obj \ + $(SLO)$/ring.obj \ + $(SLO)$/swcache.obj \ + $(SLO)$/swrect.obj \ + $(SLO)$/swregion.obj \ + $(SLO)$/swtypes.obj \ + $(SLO)$/tabcol.obj + +# --- Tagets ------------------------------------------------------- + +.INCLUDE : target.mk + diff --git a/sw/source/core/bastyp/ring.cxx b/sw/source/core/bastyp/ring.cxx new file mode 100644 index 000000000000..4e826ae23ee9 --- /dev/null +++ b/sw/source/core/bastyp/ring.cxx @@ -0,0 +1,148 @@ +/************************************************************************* + * + * $RCSfile: ring.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:16 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#include "ring.hxx" + + +/************************************************************************* +|* +|* Ring::Ring() +|* +|* Ersterstellung VB 02.07.91 +|* Letzte Aenderung JP 10.10.97 +|* +*************************************************************************/ + +Ring::Ring( Ring *pObj ) +{ + if( !pObj ) + pNext = this, pPrev = this; + else + { + pNext = pObj; + pPrev = pObj->pPrev; + pObj->pPrev = this; + pPrev->pNext = this; + } +} + +/************************************************************************* +|* +|* Ring::~Ring() +|* +|* Ersterstellung VB 02.07.91 +|* Letzte Aenderung JP 10.10.97 +|* +*************************************************************************/ + +Ring::~Ring() +{ + pNext->pPrev = pPrev; + pPrev->pNext = pNext; +} + +/************************************************************************* +|* +|* Ring::MoveTo +|* +|* Ersterstellung VB 4.3.91 +|* Letzte Aenderung JP 10.10.97 +|* +*************************************************************************/ + +void Ring::MoveTo(Ring *pDestRing) +{ + // loeschen aus dem alten + pNext->pPrev = pPrev; + pPrev->pNext = pNext; + + // im neuen einfuegen + if( pDestRing ) + { + pNext = pDestRing; + pPrev = pDestRing->pPrev; + pDestRing->pPrev = this; + pPrev->pNext = this; + } + else + pNext = pPrev = this; + +} + +void Ring::MoveRingTo(Ring *pDestRing) +{ + // den gesamten Ring in den DestRing einfuegen + Ring* pMyPrev = pPrev; + Ring* pDestPrev = pDestRing->pPrev; + + pMyPrev->pNext = pDestRing; + pDestPrev->pNext = this; + pDestRing->pPrev = pMyPrev; + pPrev = pDestPrev; +} + + diff --git a/sw/source/core/bastyp/swcache.cxx b/sw/source/core/bastyp/swcache.cxx new file mode 100644 index 000000000000..54cc0fea4bae --- /dev/null +++ b/sw/source/core/bastyp/swcache.cxx @@ -0,0 +1,699 @@ +/************************************************************************* + * + * $RCSfile: swcache.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:16 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _TOOLS_DEBUG_HXX //autogen +#include +#endif +#ifndef _STREAM_HXX //autogen +#include +#endif +#ifndef _TOOLS_TEMPFILE_HXX +#include +#endif +#include "errhdl.hxx" +#include "swcache.hxx" + +#ifndef PRODUCT + #include // getenv() + #include // sprintf() +#endif + + +SV_IMPL_PTRARR(SwCacheObjArr,SwCacheObj*); + +#ifdef PRODUCT +#define INCREMENT( nVar ) +#else +#define INCREMENT( nVar ) ++nVar +#endif + +/************************************************************************* +|* +|* SwCache::Check() +|* +|* Ersterstellung MA 23. Mar. 94 +|* Letzte Aenderung MA 23. Mar. 94 +|* +|*************************************************************************/ + +#ifndef PRODUCT + +void SwCache::Check() +{ + if ( !pRealFirst ) + return; + + //Konsistenspruefung. + ASSERT( !pLast->GetNext(), "Last but not last." ); + ASSERT( !pRealFirst->GetPrev(), "First but not first." ); + USHORT nCnt = 0; + BOOL bFirstFound = FALSE; + SwCacheObj *pObj = pRealFirst; + SwCacheObj *pRekursive = pObj; + while ( pObj ) + { + //Das Objekt muss auch auf dem Rueckwaertsweg gefunden werden. + SwCacheObj *pTmp = pLast; + while ( pTmp && pTmp != pObj ) + pTmp = pTmp->GetPrev(); + ASSERT( pTmp, "Objekt not found." ); + + ++nCnt; + if ( pObj == pFirst ) + bFirstFound = TRUE; + if ( !pObj->GetNext() ) + ASSERT( pObj == pLast, "Last not Found." ); + pObj = pObj->GetNext(); + ASSERT( pObj != pRekursive, "Recursion in SwCache." ); + } + ASSERT( bFirstFound, "First not Found." ); + ASSERT( (nCnt + aFreePositions.Count()) == Count(), "Lost Chain." ); + if ( Count() == nCurMax ) + ASSERT( (nCurMax - nCnt) == aFreePositions.Count(), "Lost FreePositions." ); +} +#endif + +#if !defined(PRODUCT) && defined(MADEBUG) +#define CHECK Check(); +#else +#define CHECK +#endif + +/************************************************************************* +|* +|* SwCache::SwCache(), ~SwCache() +|* +|* Ersterstellung MA 15. Mar. 94 +|* Letzte Aenderung MA 15. Mar. 94 +|* +|*************************************************************************/ + + +SwCache::SwCache( const USHORT nInitSize, const USHORT nGrowSize +#ifndef PRODUCT + , const ByteString &rNm +#endif + ) : + SwCacheObjArr( (BYTE)nInitSize, (BYTE)nGrowSize ), + aFreePositions( 5, 5 ), + nMax( nInitSize ), + nCurMax( nInitSize ), + pRealFirst( 0 ), + pFirst( 0 ), + pLast( 0 ) +#ifndef PRODUCT + , aName( rNm ), + nAppend( 0 ), + nInsertFree( 0 ), + nReplace( 0 ), + nGetSuccess( 0 ), + nGetFail( 0 ), + nToTop( 0 ), + nDelete( 0 ), + nGetSeek( 0 ), + nAverageSeekCnt( 0 ), + nFlushCnt( 0 ), + nFlushedObjects( 0 ), + nIncreaseMax( 0 ), + nDecreaseMax( 0 ) +#endif +{ +} + +#ifndef PRODUCT + + + +SwCache::~SwCache() +{ +#ifndef MAC + static USHORT nOpenMode = STREAM_WRITE | STREAM_TRUNC; + String sExt(String::CreateFromAscii("log")); + TempFile aTempFile(String::CreateFromAscii("swcache"), &sExt); + SvFileStream aStream( aTempFile.GetName(), nOpenMode ); + nOpenMode = STREAM_WRITE; + + if( !aStream.GetError() ) + { + aStream.Seek( STREAM_SEEK_TO_END ); + ByteString sOut( aName ); sOut += '\n'; + (( sOut += "Anzahl neuer Eintraege: " ) += nAppend )+= '\n'; + (( sOut += "Anzahl Insert auf freie Plaetze: " ) += nInsertFree )+= '\n'; + (( sOut += "Anzahl Ersetzungen: " ) += nReplace )+= '\n'; + (( sOut += "Anzahl Erfolgreicher Get's: " ) += nGetSuccess )+= '\n'; + (( sOut += "Anzahl Fehlgeschlagener Get's: " ) += nGetFail )+= '\n'; + (( sOut += "Anzahl Umsortierungen (LRU): " ) += nToTop )+= '\n'; + (( sOut += "Anzahl Loeschungen: " ) += nDelete )+= '\n'; + (( sOut += "Anzahl Get's ohne Index: " ) += nGetSeek )+= '\n'; + (( sOut += "Anzahl Seek fuer Get ohne Index: " ) += nAverageSeekCnt )+= '\n'; + (( sOut += "Anzahl Flush-Aufrufe: " ) += nFlushCnt )+= '\n'; + (( sOut += "Anzahl geflush'ter Objekte: " ) += nFlushedObjects )+= '\n'; + (( sOut += "Anzahl Cache-Erweiterungen: " ) += nIncreaseMax )+= '\n'; + (( sOut += "Anzahl Cache-Verkleinerungen: " ) += nDecreaseMax )+= '\n'; + + aStream << sOut.GetBuffer() + << "-------------------------------------------------------" + << endl; + } + Check(); +#endif +} +#endif + +/************************************************************************* +|* +|* SwCache::Flush() +|* +|* Ersterstellung MA 15. Mar. 94 +|* Letzte Aenderung MA 15. Mar. 94 +|* +|*************************************************************************/ + + +void SwCache::Flush( const BYTE nPercent ) +{ + ASSERT( nPercent == 100, "SwCache::Flush() arbeitet nur 100%'ig" ); + + INCREMENT( nFlushCnt ); + SwCacheObj *pObj = pRealFirst; + pRealFirst = pFirst = pLast = 0; + SwCacheObj *pTmp; + while ( pObj ) + { +#ifndef PRODUCT + if ( pObj->IsLocked() ) + { + ASSERT( TRUE, "Flushing locked objects." ); + if ( !pRealFirst ) + { + pRealFirst = pFirst = pLast = pObj; + pTmp = pObj->GetNext(); + pObj->SetNext( 0 ); pObj->SetPrev( 0 ); + pObj = pTmp; + } + else + { pLast->SetNext( pObj ); + pObj->SetPrev( pLast ); + pLast = pObj; + pTmp = pObj->GetNext(); + pObj->SetNext( 0 ); + pObj = pTmp; + } + } + else +#endif + { + pTmp = (SwCacheObj*)pObj; + pObj = pTmp->GetNext(); + aFreePositions.Insert( pTmp->GetCachePos(), aFreePositions.Count() ); + *(pData + pTmp->GetCachePos()) = (void*)0; + delete pTmp; + INCREMENT( nFlushedObjects ); + } + } +} + +/************************************************************************* +|* +|* SwCache::ToTop() +|* +|* Ersterstellung MA 15. Mar. 94 +|* Letzte Aenderung MA 24. Apr. 95 +|* +|*************************************************************************/ + + +void SwCache::ToTop( SwCacheObj *pObj ) +{ + INCREMENT( nToTop ); + + //Objekt aus der LRU-Kette ausschneiden und am Anfang einfuegen. + if ( pRealFirst == pObj ) //pFirst wurde vom Aufrufer geprueft! + { CHECK; + return; + } + + if ( !pRealFirst ) + { //Der erste wird eingetragen. + ASSERT( !pFirst && !pLast, "First not first." ); + pRealFirst = pFirst = pLast = pObj; + CHECK; + return; + } + + //Ausschneiden. + if ( pObj == pLast ) + { + ASSERT( pObj->GetPrev(), "Last but no Prev." ); + pLast = pObj->GetPrev(); + pLast->SetNext( 0 ); + } + else + { + if ( pObj->GetNext() ) + pObj->GetNext()->SetPrev( pObj->GetPrev() ); + if ( pObj->GetPrev() ) + pObj->GetPrev()->SetNext( pObj->GetNext() ); + } + + //Am (virtuellen) Anfang einfuegen. + if ( pRealFirst == pFirst ) + { + pRealFirst->SetPrev( pObj ); + pObj->SetNext( pRealFirst ); + pObj->SetPrev( 0 ); + pRealFirst = pFirst = pObj; + CHECK; + } + else + { + ASSERT( pFirst, "ToTop, First ist not RealFirst an Empty." ); + + if ( pFirst->GetPrev() ) + { + pFirst->GetPrev()->SetNext( pObj ); + pObj->SetPrev( pFirst->GetPrev() ); + } + else + pObj->SetPrev( 0 ); + pFirst->SetPrev( pObj ); + pObj->SetNext( pFirst ); + pFirst = pObj; + CHECK; + } +} + +/************************************************************************* +|* +|* SwCache::Get() +|* +|* Ersterstellung MA 15. Mar. 94 +|* Letzte Aenderung MA 22. Aug. 94 +|* +|*************************************************************************/ + + +SwCacheObj *SwCache::Get( const void *pOwner, const USHORT nIndex, + const BOOL bToTop ) +{ + SwCacheObj *pRet; + if ( 0 != (pRet = nIndex < Count() ? operator[]( nIndex ) : 0) ) + { + if ( !pRet->IsOwner( pOwner ) ) + pRet = 0; + else if ( bToTop && pRet != pFirst ) + ToTop( pRet ); + } + +#ifndef PRODUCT + if ( pRet ) + ++nGetSuccess; + else + ++nGetFail; +#endif + + return pRet; +} + + + +SwCacheObj *SwCache::Get( const void *pOwner, const BOOL bToTop ) +{ + SwCacheObj *pRet = pRealFirst; + while ( pRet && !pRet->IsOwner( pOwner ) ) + { + INCREMENT( nAverageSeekCnt ); + pRet = pRet->GetNext(); + } + + if ( bToTop && pRet && pRet != pFirst ) + ToTop( pRet ); + +#ifndef PRODUCT + if ( pRet ) + ++nGetSuccess; + else + ++nGetFail; + ++nGetSeek; +#endif + return pRet; +} + +/************************************************************************* +|* +|* SwCache::Delete() +|* +|* Ersterstellung MA 15. Mar. 94 +|* Letzte Aenderung MA 15. Mar. 94 +|* +|*************************************************************************/ + + +void SwCache::DeleteObj( SwCacheObj *pObj ) +{ + CHECK; + ASSERT( !pObj->IsLocked(), "SwCache::Delete: Object ist Locked." ); + if ( pObj->IsLocked() ) + return; + + if ( pFirst == pObj ) + { + if ( pFirst->GetNext() ) + pFirst = pFirst->GetNext(); + else + pFirst = pFirst->GetPrev(); + } + if ( pRealFirst == pObj ) + pRealFirst = pRealFirst->GetNext(); + if ( pLast == pObj ) + pLast = pLast->GetPrev(); + if ( pObj->GetPrev() ) + pObj->GetPrev()->SetNext( pObj->GetNext() ); + if ( pObj->GetNext() ) + pObj->GetNext()->SetPrev( pObj->GetPrev() ); + + aFreePositions.Insert( pObj->GetCachePos(), aFreePositions.Count() ); + *(pData + pObj->GetCachePos()) = (void*)0; + delete pObj; + + CHECK; + if ( Count() > nCurMax && + (nCurMax <= (Count() - aFreePositions.Count())) ) + { + //Falls moeglich wieder verkleinern, dazu muessen allerdings ausreichend + //Freie Positionen bereitstehen. + //Unangenehmer Nebeneffekt ist, das die Positionen verschoben werden + //muessen, und die Eigentuemer der Objekte diese wahrscheinlich nicht + //wiederfinden werden. + for ( USHORT i = 0; i < Count(); ++i ) + { + SwCacheObj *pObj = operator[](i); + if ( !pObj ) + { SwCacheObjArr::Remove( i, 1 ); + --i; + } + else + pObj->SetCachePos( i ); + } + aFreePositions.Remove( 0, aFreePositions.Count() ); + } + CHECK; +} + +/* + + +void SwCache::Delete( const void *pOwner, const USHORT nIndex ) +{ + INCREMENT( nDelete ); + SwCacheObj *pObj; + if ( 0 != (pObj = Get( pOwner, nIndex, FALSE )) ) + DeleteObj( pObj ); +} +*/ + + + +void SwCache::Delete( const void *pOwner ) +{ + INCREMENT( nDelete ); + SwCacheObj *pObj; + if ( 0 != (pObj = Get( pOwner, BOOL(FALSE) )) ) + DeleteObj( pObj ); +} + + +/************************************************************************* +|* +|* SwCache::Insert() +|* +|* Ersterstellung MA 15. Mar. 94 +|* Letzte Aenderung MA 20. Sep. 94 +|* +|*************************************************************************/ + + +BOOL SwCache::Insert( SwCacheObj *pNew ) +{ + CHECK; + ASSERT( !pNew->GetPrev() && !pNew->GetNext(), "New but not new." ); + + USHORT nPos;//Wird hinter den if's zum setzen am Obj benutzt. + if ( Count() < nCurMax ) + { + //Es ist noch Platz frei, also einfach einfuegen. + INCREMENT( nAppend ); + nPos = Count(); + SwCacheObjArr::C40_INSERT( SwCacheObj, pNew, nPos ); + } + else if ( aFreePositions.Count() ) + { + //Es exitieren Platzhalter, also den letzten benutzen. + INCREMENT( nInsertFree ); + const USHORT nFreePos = aFreePositions.Count() - 1; + nPos = aFreePositions[ nFreePos ]; + *(pData + nPos) = pNew; + aFreePositions.Remove( nFreePos ); + } + else + { + INCREMENT( nReplace ); + //Der letzte des LRU fliegt raus. + SwCacheObj *pObj = pLast; + + while ( pObj && pObj->IsLocked() ) + pObj = pObj->GetPrev(); + if ( !pObj ) + { + ASSERT( FALSE, "Cache overflow." ); + return FALSE; + } + + nPos = pObj->GetCachePos(); + if ( pObj == pLast ) + { ASSERT( pObj->GetPrev(), "Last but no Prev" ); + pLast = pObj->GetPrev(); + pLast->SetNext( 0 ); + } + else + { + if ( pObj->GetPrev() ) + pObj->GetPrev()->SetNext( pObj->GetNext() ); + if ( pObj->GetNext() ) + pObj->GetNext()->SetPrev( pObj->GetPrev() ); + } + delete pObj; + *(pData + nPos) = pNew; + } + pNew->SetCachePos( nPos ); + + //Anstelle von ToTop, einfach als pFirst einfuegen. +// ToTop( nPos ); + if ( pFirst ) + { + if ( pFirst->GetPrev() ) + { pFirst->GetPrev()->SetNext( pNew ); + pNew->SetPrev( pFirst->GetPrev() ); + } + pFirst->SetPrev( pNew ); + pNew->SetNext( pFirst ); + } + else + { ASSERT( !pLast, "Last but no First." ); + pLast = pNew; + } + if ( pFirst == pRealFirst ) + pRealFirst = pNew; + pFirst = pNew; + + CHECK; + return TRUE; +} + +/************************************************************************* +|* +|* SwCache::SetLRUOfst() +|* +|* Ersterstellung MA 15. Mar. 94 +|* Letzte Aenderung MA 15. Mar. 94 +|* +|*************************************************************************/ + + +void SwCache::SetLRUOfst( const USHORT nOfst ) +{ + if ( !pRealFirst || ((Count() - aFreePositions.Count()) < nOfst) ) + return; + + CHECK; + pFirst = pRealFirst; + for ( USHORT i = 0; i < Count() && i < nOfst; ++i ) + { + if ( pFirst->GetNext() && pFirst->GetNext()->GetNext() ) + pFirst = pFirst->GetNext(); + else + break; + } + CHECK; +} + +/************************************************************************* +|* +|* SwCacheObj::SwCacheObj() +|* +|* Ersterstellung MA 15. Mar. 94 +|* Letzte Aenderung MA 24. Nov. 95 +|* +|*************************************************************************/ + + +SwCacheObj::SwCacheObj( const void *pOwn ) : + nLock( 0 ), + nCachePos( USHRT_MAX ), + pNext( 0 ), + pPrev( 0 ), + pOwner( pOwn ) +{ +} + + + +SwCacheObj::~SwCacheObj() +{ +} + +/************************************************************************* +|* +|* SwCacheObj::SetLock(), Unlock() +|* +|* Ersterstellung MA 15. Mar. 94 +|* Letzte Aenderung MA 15. Mar. 94 +|* +|*************************************************************************/ + +#ifndef PRODUCT + + + +void SwCacheObj::Lock() +{ + ASSERT( nLock < UCHAR_MAX, "To many Locks for CacheObject." ); + ++nLock; +} + + + +void SwCacheObj::Unlock() +{ + ASSERT( nLock, "No more Locks available." ); + --nLock; +} +#endif + +/************************************************************************* +|* +|* SwCacheAccess::Get() +|* +|* Ersterstellung MA 15. Mar. 94 +|* Letzte Aenderung MA 04. Apr. 95 +|* +|*************************************************************************/ + + +void SwCacheAccess::_Get() +{ + ASSERT( !pObj, "SwCacheAcces Obj already available." ); + + pObj = NewObj(); + if ( !rCache.Insert( pObj ) ) + { + delete pObj; + pObj = 0; + } + else + pObj->Lock(); +} + +/************************************************************************* +|* +|* SwCacheAccess::IsAvailable() +|* +|* Ersterstellung MA 23. Mar. 94 +|* Letzte Aenderung MA 23. Mar. 94 +|* +|*************************************************************************/ + + +BOOL SwCacheAccess::IsAvailable() const +{ + return pObj != 0; +} + + + + + diff --git a/sw/source/core/bastyp/swrect.cxx b/sw/source/core/bastyp/swrect.cxx new file mode 100644 index 000000000000..797b78ef5312 --- /dev/null +++ b/sw/source/core/bastyp/swrect.cxx @@ -0,0 +1,303 @@ +/************************************************************************* + * + * $RCSfile: swrect.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:16 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef PRODUCT +#ifndef _STREAM_HXX //autogen +#include +#endif +#endif +#include +#include "swrect.hxx" + + +/************************************************************************* +|* +|* SwRect::SwRect() +|* +|* Ersterstellung MA 02. Feb. 93 +|* Letzte Aenderung MA 05. Sep. 93 +|* +|*************************************************************************/ + + + +SwRect::SwRect( const Rectangle &rRect ) : + nX( rRect.Left() ), + nY( rRect.Top() ) +{ + nWidth = rRect.Right() == RECT_EMPTY ? 0 : + rRect.Right() - rRect.Left() +1; + nHeight = rRect.Bottom() == RECT_EMPTY ? 0 : + rRect.Bottom() - rRect.Top() + 1; +} + +/************************************************************************* +|* +|* SwRect::Center() +|* +|* Ersterstellung MA 27. Jan. 93 +|* Letzte Aenderung MA 27. Jan. 93 +|* +|*************************************************************************/ +Point SwRect::Center() const +{ + return Point( Left() + Width() / 2, + Top() + Height() / 2 ); + +/* Wer ruft schon ein Center auf ein "falsches" Rechteck? + const long nRight = Right(); + const long nBottom= Bottom(); + return Point( min( Left(), nRight ) + long(abs( (nRight - Left())/2) ), + min( Top(), nBottom) + long(abs( (nBottom - Top())/2))); +*/ +} + +/************************************************************************* +|* +|* SwRect::Union() +|* +|* Ersterstellung MA 27. Jan. 93 +|* Letzte Aenderung MA 27. Jan. 93 +|* +|*************************************************************************/ + + + +SwRect& SwRect::Union( const SwRect& rRect ) +{ + if ( Top() > rRect.Top() ) + Top( rRect.Top() ); + if ( Left() > rRect.Left() ) + Left( rRect.Left() ); + register long n = rRect.Right(); + if ( Right() < n ) + Right( n ); + n = rRect.Bottom(); + if ( Bottom() < n ) + Bottom( n ); + return *this; +} +/************************************************************************* +|* +|* SwRect::Intersection(), _Intersection() +|* +|* Ersterstellung MA 27. Jan. 93 +|* Letzte Aenderung MA 05. Sep. 93 +|* +|*************************************************************************/ + + + +SwRect& SwRect::Intersection( const SwRect& rRect ) +{ + //Hat das Teil ueberhaupt Gemeinsamkeiten mit mir? + if ( IsOver( rRect ) ) + { + //Bestimmung der kleineren rechten sowie unteren und + // der groesseren linken sowie oberen Kante. + if ( Left() < rRect.Left() ) + Left( rRect.Left() ); + if ( Top() < rRect.Top() ) + Top( rRect.Top() ); + register long n = rRect.Right(); + if ( Right() > n ) + Right( n ); + n = rRect.Bottom(); + if ( Bottom() > n ) + Bottom( n ); + } + else + //Def.: Bei einer leeren Intersection wird nur die SSize genullt. + nHeight = nWidth = 0; + + return *this; +} + + + +SwRect& SwRect::_Intersection( const SwRect& rRect ) +{ + //Bestimmung der kleineren rechten sowie unteren und + // der groesseren linken sowie oberen Kante. + if ( Left() < rRect.Left() ) + Left( rRect.Left() ); + if ( Top() < rRect.Top() ) + Top( rRect.Top() ); + register long n = rRect.Right(); + if ( Right() > n ) + Right( n ); + n = rRect.Bottom(); + if ( Bottom() > n ) + Bottom( n ); + + return *this; +} +/************************************************************************* +|* +|* SwRect::IsInside() +|* +|* Ersterstellung MA 27. Jan. 93 +|* Letzte Aenderung MA 27. Jan. 93 +|* +|*************************************************************************/ + + + +BOOL SwRect::IsInside( const SwRect& rRect ) const +{ + const long nRight = Right(); + const long nBottom = Bottom(); + const long nrRight = rRect.Right(); + const long nrBottom= rRect.Bottom(); + return (Left() <= rRect.Left()) && (rRect.Left()<= nRight) && + (Left() <= nrRight) && (nrRight <= nRight) && + (Top() <= rRect.Top()) && (rRect.Top() <= nBottom) && + (Top() <= nrBottom) && (nrBottom <= nBottom); +} + + + +BOOL SwRect::IsInside( const Point& rPoint ) const +{ + return (Left() <= rPoint.X()) + && (Top() <= rPoint.Y()) + && (Right() >= rPoint.X()) + && (Bottom()>= rPoint.Y()); +} +/* -----------------------------11.04.00 15:46-------------------------------- + mouse moving of table borders + ---------------------------------------------------------------------------*/ +BOOL SwRect::IsNear( const Point& rPoint, long nTolerance ) const +{ + return IsInside(rPoint) || + (((Left() - nTolerance) <= rPoint.X()) + && ((Top() - nTolerance) <= rPoint.Y()) + && ((Right() + nTolerance) >= rPoint.X()) + && ((Bottom() + nTolerance)>= rPoint.Y())); +} + +/************************************************************************* +|* +|* SwRect::IsOver() +|* +|* Ersterstellung MA 25. Feb. 94 +|* Letzte Aenderung MA 27. Jun. 96 +|* +|*************************************************************************/ + + + +BOOL SwRect::IsOver( const SwRect& rRect ) const +{ + return (Top() <= rRect.Bottom()) + && (Left() <= rRect.Right()) + && (Right() >= rRect.Left()) + && (Bottom()>= rRect.Top()) ? TRUE : FALSE; +} + +/************************************************************************* +|* +|* SwRect::Justify() +|* +|* Ersterstellung MA 10. Oct. 94 +|* Letzte Aenderung MA 23. Oct. 96 +|* +|*************************************************************************/ + + + +void SwRect::Justify() +{ + if ( nHeight < 0 ) + { + nY = nY + nHeight + 1; + nHeight = -nHeight; + } + if ( nWidth < 0 ) + { + nX = nX + nWidth + 1; + nWidth = -nWidth; + } +} + + +#ifndef PRODUCT +/************************************************************************* + * operator<<( ostream&, SwRect&) + *************************************************************************/ + + + +SvStream &operator<<( SvStream &rStream, const SwRect &rRect ) +{ + rStream << '[' << rRect.Top() << '/' << rRect.Left() + << ',' << rRect.Width() << 'x' << rRect.Height() << "] "; + return rStream; +} +#endif + + diff --git a/sw/source/core/bastyp/swregion.cxx b/sw/source/core/bastyp/swregion.cxx new file mode 100644 index 000000000000..6961d8efe354 --- /dev/null +++ b/sw/source/core/bastyp/swregion.cxx @@ -0,0 +1,293 @@ +/************************************************************************* + * + * $RCSfile: swregion.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:16 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + + +#ifndef _DEBUG_HXX //autogen +#include +#endif +#include "swtypes.hxx" +#include "swrect.hxx" +#include "swregion.hxx" + + +SV_IMPL_VARARR( SwRects, SwRect ); + +/************************************************************************* +|* +|* SwRegionRects::SwRegionRects() +|* +|* Ersterstellung MA 28. Oct. 92 +|* Letzte Aenderung MA 01. Feb. 93 +|* +|*************************************************************************/ + +SwRegionRects::SwRegionRects( const SwRect &rStartRect, USHORT nInit, + USHORT nGrow ) : + SwRects( (BYTE)nInit, (BYTE)nGrow ), + aOrigin( rStartRect ) +{ + Insert( aOrigin, 0 ); +} + +/************************************************************************* + * inline InsertRect() + * + * InsertRect() wird nur von operator-=() gerufen. + * Wenn bDel == TRUE ist, dann wird das Rect an der Position nPos mit + * rRect ueberschrieben, ansonsten wird rRect hinten angehaengt. + *************************************************************************/ + +inline void SwRegionRects::InsertRect( const SwRect &rRect, const USHORT nPos, + FASTBOOL &rDel ) +{ + if( rDel ) + { + *(pData+nPos) = rRect; + rDel = FALSE; + } + else + Insert( rRect, Count() ); +} + +/************************************************************************* +|* +|* SwRegionRects::operator-=() +|* +|* Beschreibung Alle Ueberschneidungen der Rechtecke, die sich +|* gerade im Array befinden, mit dem uebergebenen Rechteck werden +|* entfernt. +|* Dazu muessen die vorhandenen Rechtecke entweder aufgeteilt oder +|* geloescht werden. +|* Ersterstellung MA 28. Oct. 92 +|* Letzte Aenderung MA 09. Sep. 93 +|* +|*************************************************************************/ + +void SwRegionRects::operator-=( const SwRect &rRect ) +{ + USHORT nMax = Count(); + for ( USHORT i = 0; i < nMax; ++i ) + { + if ( rRect.IsOver( *(pData+i) ) ) + { + SwRect aTmp( *(pData+i) ); + SwRect aInter( aTmp ); + aInter._Intersection( rRect ); + + // Das erste Rect, das wir inserten wollen, nimmt die + // Stelle von i ein. So ersparen wir uns das Delete(). + FASTBOOL bDel = TRUE; + + //Jetzt aufteilen das Teil: Es sollen diejenigen Rechtecke + //zurueckbleiben, die im alten aber nicht im neuen liegen. + //Sprich alle Rechtecke die im alten aber nicht in der Intersection + //liegen. + long nTmp; + if ( 0 < (nTmp = aInter.Top() - aTmp.Top()) ) + { + const long nOldVal = aTmp.Height(); + aTmp.SSize().Height() = nTmp; + InsertRect( aTmp, i, bDel ); + aTmp.Height( nOldVal ); + } + + aTmp.Top( aInter.Top() + aInter.Height() ); + if ( aTmp.Height() > 0 ) + InsertRect( aTmp, i, bDel ); + + aTmp.Top( aInter.Top() ); + aTmp.Bottom( aInter.Bottom() ); + if ( 0 < (nTmp = aInter.Left() - aTmp.Left()) ) + { + const long nOldVal = aTmp.Width(); + aTmp.Width( nTmp ); + InsertRect( aTmp, i, bDel ); + aTmp.Width( nOldVal ); + } + + aTmp.Left( aInter.Left() + aInter.Width() ); //+1? + if ( aTmp.Width() > 0 ) + InsertRect( aTmp, i, bDel ); + + if( bDel ) + { + Remove( i ); + --i; //Damit wir keinen uebergehen. + --nMax; //Damit wir keinen zuviel verarbeiten. + } + } + } + +} + +/************************************************************************* + * SwRegionRects::Invert() + * + * Bezugspunkt ist aOrigin, das Original-SRectangle. + * Aus Loechern werden Flaechen, aus Flaechen werden Loecher. + * Ein Hinweis: Wenn keine Rects abgezogen wurden, so ist das enthaltene + * Rechteck identisch mit aOrigin. Nach Invert() besteht die Region aus + * einem Null-SRectangle. + *************************************************************************/ + +void SwRegionRects::Invert() +{ + // Nicht besonders elegant und schnell, aber wirkungsvoll: + // Wir legen eine weitere Region an und ziehen alle Flaechen ab, + // die in uns noch uebrig geblieben sind. Danach werden alle + // Werte uebertragen. + + // Um unuetze Speicheranforderungen zu vermeiden versuchen wir die + // iniale Groesse moeglichst brauchbar anzulegen: + // Anzahl der Rechtecke in der Region * 2 + 2 + // plus zwei um den Sonderfall eines einzelnen Loches (macht vier + // Rechtecke im inversen Fall) abzudecken. + + SwRegionRects aInvRegion( aOrigin, Count()*2+2 ); + const SwRect *pDat = GetData(); + for( USHORT i = 0; i < Count(); ++pDat, ++i ) + aInvRegion -= *pDat; + + USHORT nCpy = Count(), nDel = 0; + if( aInvRegion.Count() < Count() ) + { + nDel = Count() - aInvRegion.Count(); + nCpy = aInvRegion.Count(); + } + // alle vorhandenen ueberschreiben + memcpy( pData, aInvRegion.GetData(), nCpy * sizeof( SwRect )); + + if( nCpy < aInvRegion.Count() ) + Insert( &aInvRegion, nCpy, nCpy ); + else if( nDel ) + Remove( nCpy, nDel ); +} +/************************************************************************* +|* +|* SwRegionRects::Compress() +|* +|* Beschreibung Zusammenfassen von benachbarten Rechtecken. +|* Ersterstellung MA 16. Apr. 93 +|* Letzte Aenderung MA 21. Apr. 93 +|* +|*************************************************************************/ +inline SwTwips CalcArea( const SwRect &rRect ) +{ + return rRect.Width() * rRect.Height(); +} + + +#pragma optimize("e",off) +void SwRegionRects::Compress( BOOL bFuzzy ) +{ + for ( int i = 0; i < Count(); ++i ) + { + for ( int j = i+1; j < Count(); ++j ) + { + //Wenn zwei Rechtecke ineinanderliegen, so ist eins davon + //uberfluessig. + if ( (*(pData + i)).IsInside( *(pData + j) ) ) + { + Remove( j, 1 ); + --j; + } + else if ( (*(pData + j)).IsInside( *(pData + i) ) ) + { + *(pData + i) = *(pData + j); + Remove( j, 1 ); + i = -1; + break; + } + else + { + //Wenn zwei Rechtecke dieselbe Flaeche haben wie deren + //Union abzueglich deren Intersection, so ist eines + //davon ueberfluessig. + //Um moeglichst viel zusammenzufassen und in der Folge + //moeglichst wenig einzelne Paints zu haben darf die Flaeche + //der Union ruhig ein bischen groesser sein + //( 9622 * 141.5 = 1361513 ~= ein virtel Zentimeter ueber die + // Breite einer DINA4 Seite) + const long nFuzzy = bFuzzy ? 1361513 : 0; + SwRect aUnion( *(pData + i) );aUnion.Union( *(pData + j) ); + SwRect aInter( *(pData + i) );aInter.Intersection( *(pData + j)); + if ( (::CalcArea( *(pData + i) ) + + ::CalcArea( *(pData + j) ) + nFuzzy) >= + (::CalcArea( aUnion ) - CalcArea( aInter )) ) + { + *(pData + i) = aUnion; + Remove( j, 1 ); + i = -1; + break; + } + } + } + } +} +#pragma optimize("",on) + + diff --git a/sw/source/core/bastyp/swtypes.cxx b/sw/source/core/bastyp/swtypes.cxx new file mode 100644 index 000000000000..68b12f26b21f --- /dev/null +++ b/sw/source/core/bastyp/swtypes.cxx @@ -0,0 +1,270 @@ +/************************************************************************* + * + * $RCSfile: swtypes.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:16 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _SV_WINDOW_HXX //autogen +#include +#endif +#ifndef _SV_GRAPH_HXX //autogen +#include +#endif +#ifndef _OFF_APP_HXX //autogen +#include +#endif +#ifndef _OFA_OSPLCFG_HXX //autogen +#include +#endif + +#ifndef _SFXINIMGR_HXX +#include +#endif +#ifndef _UNOTOOLS_PROCESSFACTORY_HXX_ +#include +#endif +#ifndef _COM_SUN_STAR_LINGUISTIC_XSPELLCHECKER1_HPP_ +#include +#endif +#ifndef _COM_SUN_STAR_LINGUISTIC_XHYPHENATOR_HPP_ +#include +#endif +#ifndef _UNO_LINGU_HXX +#include +#endif +#ifndef _COM_SUN_STAR_LINGUISTIC_XTHESAURUS_HPP_ +#include +#endif +#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_ +#include +#endif +#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_ +#include +#endif + +#ifndef _PAGEFRM_HXX +#include +#endif +#ifndef _SWATRSET_HXX +#include +#endif +#ifndef _FRMFMT_HXX +#include +#endif +#ifndef _FRMTOOL_HXX +#include +#endif +#ifndef _NDTXT_HXX +#include +#endif +#ifndef _UNDOBJ_HXX +#include +#endif +#ifndef _SWTABLE_HXX +#include +#endif +#ifndef _VISCRS_HXX +#include +#endif +#ifndef _FNTCACHE_HXX +#include +#endif +#ifndef _SWFNTCCH_HXX +#include +#endif +#ifndef _HFFRM_HXX +#include +#endif +#ifndef _COLFRM_HXX +#include +#endif +#ifndef _BODYFRM_HXX +#include +#endif +#ifndef _TABFRM_HXX +#include +#endif +#ifndef _TXTFRM_HXX +#include +#endif +#ifndef _SWTBLFMT_HXX +#include +#endif +#ifndef _ROWFRM_HXX +#include +#endif +#ifndef _CELLFRM_HXX +#include +#endif +#ifndef _SECTFRM_HXX +#include +#endif + +// ! Code for the new GraphicObject +#ifndef USE_GRFOBJECT + +#ifndef _GRFCACHE_HXX +#include +#endif + +#endif + +using namespace ::com::sun::star; +using namespace ::utl; + +#ifndef PROFILE +// Code zum Initialisieren von Statics im eigenen Code-Segment +#pragma code_seg( "SWSTATICS" ) +#endif + +ByteString aEmptyByteStr; // Konstante Strings +String aEmptyStr; // Konstante Strings +String aDotStr('.'); // Konstante Strings + +IMPL_FIXEDMEMPOOL_NEWDEL( SwAttrSet, 25, 25 ) +IMPL_FIXEDMEMPOOL_NEWDEL( SwStartNode, 20, 20 ) +IMPL_FIXEDMEMPOOL_NEWDEL( SwEndNode, 20, 20 ) +IMPL_FIXEDMEMPOOL_NEWDEL( SwTableBox, 50, 50 ) +IMPL_FIXEDMEMPOOL_NEWDEL( SwUndoDelete, 10, 10 ) +IMPL_FIXEDMEMPOOL_NEWDEL( SwUndoInsert, 10, 10 ) +IMPL_FIXEDMEMPOOL_NEWDEL( SwPaM, 10, 10 ) +IMPL_FIXEDMEMPOOL_NEWDEL( SwCursor, 10, 10 ) +IMPL_FIXEDMEMPOOL_NEWDEL( SwShellCrsr, 10, 10 ) +IMPL_FIXEDMEMPOOL_NEWDEL( SwTxtNode, 50, 50 ) +IMPL_FIXEDMEMPOOL_NEWDEL( SwpHints, 25, 25 ) +IMPL_FIXEDMEMPOOL_NEWDEL( SwFntObj, 50, 50 ) +IMPL_FIXEDMEMPOOL_NEWDEL( SwFontObj, 50, 50 ) +IMPL_FIXEDMEMPOOL_NEWDEL( SwFrmFmt, 20, 20 ) +IMPL_FIXEDMEMPOOL_NEWDEL( SwFlyFrmFmt, 10, 10 ) +IMPL_FIXEDMEMPOOL_NEWDEL( SwDrawFrmFmt, 10, 10 ) +IMPL_FIXEDMEMPOOL_NEWDEL( SwBorderAttrs, 100, 100 ) +IMPL_FIXEDMEMPOOL_NEWDEL( SwCellFrm, 50, 50 ) +IMPL_FIXEDMEMPOOL_NEWDEL( SwRowFrm, 10, 10 ) +IMPL_FIXEDMEMPOOL_NEWDEL( SwColumnFrm, 40, 40 ) +IMPL_FIXEDMEMPOOL_NEWDEL( SwSectionFrm, 20, 20 ) +IMPL_FIXEDMEMPOOL_NEWDEL( SwTabFrm, 10, 10 ) +IMPL_FIXEDMEMPOOL_NEWDEL( SwPageFrm, 20, 20 ) +IMPL_FIXEDMEMPOOL_NEWDEL( SwBodyFrm, 20, 20 ) +IMPL_FIXEDMEMPOOL_NEWDEL( SwHeaderFrm, 20, 20 ) +IMPL_FIXEDMEMPOOL_NEWDEL( SwFooterFrm, 20, 20 ) +IMPL_FIXEDMEMPOOL_NEWDEL( SwTxtFrm, 50, 50 ) +IMPL_FIXEDMEMPOOL_NEWDEL( SwTableFmt, 10, 10 ) +IMPL_FIXEDMEMPOOL_NEWDEL( SwTableLineFmt, 10, 10 ) +IMPL_FIXEDMEMPOOL_NEWDEL( SwTableBoxFmt, 50, 50 ) + +// ! Code for the new GraphicObject +#ifndef USE_GRFOBJECT + +IMPL_FIXEDMEMPOOL_NEWDEL( SwGraphicCacheObj, 50, 50 ) + +#endif + + +#ifndef PROFILE +#pragma code_seg() +#endif + +Size GetGraphicSizeTwip( const Graphic& rGraphic, OutputDevice* pOutDev ) +{ + const MapMode aMapTwip( MAP_TWIP ); + Size aSize( rGraphic.GetPrefSize() ); + if( MAP_PIXEL == rGraphic.GetPrefMapMode().GetMapUnit() ) + { + if( !pOutDev ) + pOutDev = Application::GetDefaultDevice(); + aSize = pOutDev->PixelToLogic( aSize, aMapTwip ); + } + else + aSize = OutputDevice::LogicToLogic( aSize, + rGraphic.GetPrefMapMode(), aMapTwip ); + return aSize; +} + + +uno::Reference< linguistic::XSpellChecker1 > GetSpellChecker() +{ + return LinguMgr::GetSpellChecker(); +} + +uno::Reference< linguistic::XHyphenator > GetHyphenator() +{ + return LinguMgr::GetHyphenator(); +} + +uno::Reference< linguistic::XThesaurus > GetThesaurus() +{ + return LinguMgr::GetThesaurus(); +} + +uno::Reference< linguistic::XDictionaryList > GetDictionaryList() +{ + return LinguMgr::GetDictionaryList(); +} + +uno::Reference< beans::XPropertySet > GetLinguPropertySet() +{ + return LinguMgr::GetLinguPropertySet(); +} + + diff --git a/sw/source/core/bastyp/tabcol.cxx b/sw/source/core/bastyp/tabcol.cxx new file mode 100644 index 000000000000..2fcd7ae1b04b --- /dev/null +++ b/sw/source/core/bastyp/tabcol.cxx @@ -0,0 +1,127 @@ +/************************************************************************* + * + * $RCSfile: tabcol.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:16 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#include "tabcol.hxx" + +SwTabCols::SwTabCols( USHORT nSize ) + : SvLongs( (BYTE)nSize ), + aHidden( (BYTE)nSize ), + nLeftMin( 0 ), + nLeft( 0 ), + nRight( 0 ), + nRightMax( 0 ) +{ +} + +SwTabCols::SwTabCols( const SwTabCols& rCpy ) + : SvLongs( (BYTE)rCpy.Count(), 1 ), + aHidden( (BYTE)rCpy.Count(), 1 ), + nLeftMin( rCpy.GetLeftMin() ), + nLeft( rCpy.GetLeft() ), + nRight( rCpy.GetRight() ), + nRightMax( rCpy.GetRightMax() ) +{ + Insert( &rCpy, 0 ); + aHidden.Insert( &rCpy.GetHidden(), 0 ); +} + +SwTabCols &SwTabCols::operator=( const SwTabCols& rCpy ) +{ + nLeftMin = rCpy.GetLeftMin(); + nLeft = rCpy.GetLeft(); + nRight = rCpy.GetRight(); + nRightMax= rCpy.GetRightMax(); + + Remove( 0, Count() ); + Insert( &rCpy, 0 ); + + aHidden.Remove( 0, aHidden.Count() ); + aHidden.Insert( &rCpy.GetHidden(), 0 ); + + return *this; +} + +BOOL SwTabCols::operator==( const SwTabCols& rCmp ) const +{ + if ( !(nLeftMin == rCmp.GetLeftMin() && + nLeft == rCmp.GetLeft() && + nRight == rCmp.GetRight() && + nRightMax== rCmp.GetRightMax()&& + Count()== rCmp.Count()) ) + return FALSE; + for ( USHORT i = 0; i < Count(); ++i ) + if ( operator[](i) != rCmp[i] ) + return FALSE; + + for ( i = 0; i < aHidden.Count(); ++i ) + if ( aHidden[i] != rCmp.IsHidden( i ) ) + return FALSE; + + return TRUE; +} + + diff --git a/sw/source/core/crsr/bookmrk.cxx b/sw/source/core/crsr/bookmrk.cxx new file mode 100644 index 000000000000..2e0b19b37603 --- /dev/null +++ b/sw/source/core/crsr/bookmrk.cxx @@ -0,0 +1,180 @@ +/************************************************************************* + * + * $RCSfile: bookmrk.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:16 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#include "swtypes.hxx" +#include "doc.hxx" +#include "pam.hxx" + +#include "bookmrk.hxx" +#include "swserv.hxx" + +#ifndef _ERRHDL_HXX //autogen +#include +#endif + +SO2_IMPL_REF( SwServerObject ) + +TYPEINIT1( SwBookmark, SwModify ); //rtti + + +SwBookmark::SwBookmark(const SwPosition& aPos) + : SwModify( 0 ), + aStartMacro( aEmptyStr, aEmptyStr ), + aEndMacro ( aEmptyStr, aEmptyStr ), + pPos2( 0 ), + eMarkType( BOOKMARK ) +{ + pPos1 = new SwPosition( aPos ); +} + + +SwBookmark::SwBookmark(const SwPosition& aPos, const KeyCode& rCode, + const String& rName, const String& rShortName ) + : SwModify( 0 ), + aStartMacro( aEmptyStr, aEmptyStr ), + aEndMacro ( aEmptyStr, aEmptyStr ), + aCode(rCode), + aName(rName), + aShortName(rShortName), + pPos2( 0 ), + eMarkType( BOOKMARK ) +{ + pPos1 = new SwPosition(aPos); +} + +// Beim Loeschen von Text werden Bookmarks mitgeloescht! + + +SwBookmark::~SwBookmark() +{ + // falls wir noch der DDE-Bookmark sind, dann muss der aus dem + // Clipboard ausgetragen werden. Wird automatisch ueber DataChanged + // ausgeloest. + if( refObj.Is() ) + { + if( DDE_BOOKMARK == eMarkType && refObj->GetSelectorCount() ) + { + SvData aSvData; + refObj->DataChanged( aSvData ); + } + refObj->SetNoServer(); + } + + delete pPos1; + if( pPos2 ) + delete pPos2; +} + +// Vergleiche auf Basis der Dokumentposition + +BOOL SwBookmark::operator<(const SwBookmark &rBM) const +{ + const SwPosition* pThisPos = ( !pPos2 || *pPos1 <= *pPos2 ) ? pPos1 : pPos2; + const SwPosition* pBMPos = ( !rBM.pPos2 || *rBM.pPos1 <= *rBM.pPos2 ) + ? rBM.pPos1 : rBM.pPos2; + + return *pThisPos < *pBMPos; +} + +BOOL SwBookmark::operator==(const SwBookmark &rBM) const +{ + return (this == &rBM); +} + +BOOL SwBookmark::IsEqualPos( const SwBookmark &rBM ) const +{ + const SwPosition* pThisPos = ( !pPos2 || *pPos1 <= *pPos2 ) ? pPos1 : pPos2; + const SwPosition* pBMPos = ( !rBM.pPos2 || *rBM.pPos1 <= *rBM.pPos2 ) + ? rBM.pPos1 : rBM.pPos2; + + return *pThisPos == *pBMPos; +} + +void SwBookmark::SetRefObject( SvPseudoObject* pObj ) +{ + refObj = pObj; +} + + +SwMark::SwMark( const SwPosition& aPos, + const KeyCode& rCode, + const String& rName, + const String& rShortName ) + : SwBookmark( aPos, rCode, rName, rShortName ) +{ + eMarkType = MARK; +} + +SwUNOMark::SwUNOMark( const SwPosition& aPos, + const KeyCode& rCode, + const String& rName, + const String& rShortName ) + : SwBookmark( aPos, rCode, rName, rShortName ) +{ + eMarkType = UNO_BOOKMARK; +} + diff --git a/sw/source/core/crsr/callnk.cxx b/sw/source/core/crsr/callnk.cxx new file mode 100644 index 000000000000..f47953c016c3 --- /dev/null +++ b/sw/source/core/crsr/callnk.cxx @@ -0,0 +1,302 @@ +/************************************************************************* + * + * $RCSfile: callnk.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:16 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _HINTIDS_HXX +#include +#endif + +#ifndef _FMTCNTNT_HXX //autogen +#include +#endif +#ifndef _TXATBASE_HXX //autogen +#include +#endif +#ifndef _FRMATR_HXX +#include +#endif +#ifndef _VISCRS_HXX +#include +#endif +#ifndef _CALLNK_HXX +#include +#endif +#ifndef _CRSRSH_HXX +#include +#endif +#ifndef _DOC_HXX +#include +#endif +#ifndef _FRMFMT_HXX +#include +#endif +#ifndef _TXTFRM_HXX +#include +#endif +#ifndef _NDTXT_HXX +#include +#endif +#ifndef _FLYFRM_HXX +#include +#endif + + +SwCallLink::SwCallLink( SwCrsrShell & rSh, ULONG nAktNode, xub_StrLen nAktCntnt, + BYTE nAktNdTyp, long nLRPos ) + : rShell( rSh ), nNode( nAktNode ), nCntnt( nAktCntnt ), + nNdTyp( nAktNdTyp ), nLeftFrmPos( nLRPos ) +{ +} + + +SwCallLink::SwCallLink( SwCrsrShell & rSh ) + : rShell( rSh ) +{ + // SPoint-Werte vom aktuellen Cursor merken + SwPaM* pCrsr = rShell.IsTableMode() ? rShell.GetTblCrs() : rShell.GetCrsr(); + SwNode& rNd = pCrsr->GetPoint()->nNode.GetNode(); + nNode = rNd.GetIndex(); + nCntnt = pCrsr->GetPoint()->nContent.GetIndex(); + nNdTyp = rNd.GetNodeType(); + + if( ND_TEXTNODE & nNdTyp ) + nLeftFrmPos = SwCallLink::GetFrm( (SwTxtNode&)rNd, nCntnt, + !rShell.ActionPend() ); + else + { + nLeftFrmPos = 0; + + // eine Sonderbehandlung fuer die SwFeShell: diese setzt beim Loeschen + // der Kopf-/Fusszeile, Fussnoten den Cursor auf NULL (Node + Content) + // steht der Cursor auf keinem CntntNode, wird sich das im NdType + // gespeichert. + if( ND_CONTENTNODE & nNdTyp ) + nNdTyp = 0; + } +} + + +SwCallLink::~SwCallLink() +{ + if( !nNdTyp || !rShell.bCallChgLnk ) // siehe ctor + return ; + + // wird ueber Nodes getravellt, Formate ueberpruefen und im neuen + // Node wieder anmelden + SwPaM* pCurCrsr = rShell.IsTableMode() ? rShell.GetTblCrs() : rShell.GetCrsr(); + SwCntntNode * pCNd = pCurCrsr->GetCntntNode(); + if( !pCNd ) + return; + + xub_StrLen nCmp, nAktCntnt = pCurCrsr->GetPoint()->nContent.GetIndex(); + USHORT nNdWhich = pCNd->GetNodeType(); + ULONG nAktNode = pCurCrsr->GetPoint()->nNode.GetIndex(); + + // melde die Shell beim akt. Node als abhaengig an, dadurch koennen + // alle Attribut-Aenderungen ueber den Link weiter gemeldet werden. + pCNd->Add( &rShell ); + + if( nNdTyp != nNdWhich || nNode != nAktNode ) + { + /* immer, wenn zwischen Nodes gesprungen wird, kann es + * vorkommen, das neue Attribute gelten; die Text-Attribute. + * Es muesste also festgestellt werden, welche Attribute + * jetzt gelten; das kann auch gleich der Handler machen + */ + rShell.CallChgLnk(); + } + else if( rShell.aChgLnk.IsSet() && ND_TEXTNODE == nNdWhich && + nCntnt != nAktCntnt ) + { + // nur wenn mit Left/right getravellt, dann Text-Hints pruefen + // und sich nicht der Frame geaendert hat (Spalten!) + if( nLeftFrmPos == SwCallLink::GetFrm( (SwTxtNode&)*pCNd, nAktCntnt, + !rShell.ActionPend() ) && + (( nCmp = nCntnt ) + 1 == nAktCntnt || // Right + nCntnt -1 == ( nCmp = nAktCntnt )) ) // Left + { + if ( ((SwTxtNode*)pCNd)->HasHints() ) + { + if( nCmp == nAktCntnt && pCurCrsr->HasMark() ) // left & Sele + ++nCmp; + + const SwpHints &rHts = ((SwTxtNode*)pCNd)->GetSwpHints(); + USHORT n; + xub_StrLen nStart; + const xub_StrLen *pEnd; + + for( n = 0; n < rHts.Count(); n++ ) + { + const SwTxtAttr* pHt = rHts[ n ]; + pEnd = pHt->GetEnd(); + nStart = *pHt->GetStart(); + + // nur Start oder Start und Ende gleich, dann immer + // beim Ueberlaufen von Start callen + if( ( !pEnd || ( nStart == *pEnd ) ) && + ( nStart == nCntnt || nStart == nAktCntnt) ) + { + rShell.CallChgLnk(); + return; + } + + // hat das Attribut einen Bereich und dieser nicht leer + else if( pEnd && nStart < *pEnd && + // dann teste, ob ueber Start/Ende getravellt wurde + ( nStart == nCmp || + ( pHt->DontExpand() ? nCmp == *pEnd-1 + : nCmp == *pEnd ) )) + { + rShell.CallChgLnk(); + return; + } + nStart = 0; + } + } + } + else + /* wenn mit Home/End/.. mehr als 1 Zeichen getravellt, dann + * immer den ChgLnk rufen, denn es kann hier nicht + * festgestellt werden, was sich geaendert; etwas kann + * veraendert sein. + */ + rShell.CallChgLnk(); + } + + const SwFrm* pFrm; + const SwFlyFrm *pFlyFrm; + if( !rShell.ActionPend() && 0 != ( pFrm = pCNd->GetFrm(0,0,FALSE) ) && + 0 != ( pFlyFrm = pFrm->FindFlyFrm() ) && !rShell.IsTableMode() ) + { + const SwNodeIndex* pIndex = pFlyFrm->GetFmt()->GetCntnt().GetCntntIdx(); + ASSERT( pIndex, "Fly ohne Cntnt" ); + const SwNode& rStNd = pIndex->GetNode(); + + if( rStNd.EndOfSectionNode()->StartOfSectionIndex() > nNode || + nNode > rStNd.EndOfSectionIndex() ) + rShell.GetFlyMacroLnk().Call( (void*)pFlyFrm->GetFmt() ); + } +} + +long SwCallLink::GetFrm( SwTxtNode& rNd, xub_StrLen nCntPos, BOOL bCalcFrm ) +{ + SwTxtFrm* pFrm = (SwTxtFrm*)rNd.GetFrm(0,0,bCalcFrm), *pNext = pFrm; + if ( pFrm && !pFrm->IsHiddenNow() ) + { + if( pFrm->HasFollow() ) + while( 0 != ( pNext = (SwTxtFrm*)pFrm->GetFollow() ) && + nCntPos >= pNext->GetOfst() ) + pFrm = pNext; + + return pFrm->Frm().Left(); + } + return 0; +} + +/*---------------------------------------------------------------------*/ + + +SwChgLinkFlag::SwChgLinkFlag( SwCrsrShell& rShell ) + : rCrsrShell( rShell ), bOldFlag( rShell.bCallChgLnk ), nLeftFrmPos( 0 ) +{ + rCrsrShell.bCallChgLnk = FALSE; + if( bOldFlag && !rCrsrShell.pTblCrsr ) + { + SwNode* pNd = rCrsrShell.pCurCrsr->GetNode(); + if( ND_TEXTNODE & pNd->GetNodeType() ) + nLeftFrmPos = SwCallLink::GetFrm( (SwTxtNode&)*pNd, + rCrsrShell.pCurCrsr->GetPoint()->nContent.GetIndex(), + !rCrsrShell.ActionPend() ); + } +} + + +SwChgLinkFlag::~SwChgLinkFlag() +{ + rCrsrShell.bCallChgLnk = bOldFlag; + if( bOldFlag && !rCrsrShell.pTblCrsr ) + { + // die Spalten Ueberwachung brauchen wir immer!!! + SwNode* pNd = rCrsrShell.pCurCrsr->GetNode(); + if( ND_TEXTNODE & pNd->GetNodeType() && + nLeftFrmPos != SwCallLink::GetFrm( (SwTxtNode&)*pNd, + rCrsrShell.pCurCrsr->GetPoint()->nContent.GetIndex(), + !rCrsrShell.ActionPend() )) + { + /* immer, wenn zwischen Frames gesprungen wird, gelten + * neue Attribute. Es muesste also festgestellt werden, welche + * Attribute jetzt gelten; das kann gleich der Handler machen. + * Diesen direkt rufen !!! + */ + rCrsrShell.aChgLnk.Call( &rCrsrShell ); + rCrsrShell.bChgCallFlag = FALSE; // Flag zuruecksetzen + } + } +} + + + + diff --git a/sw/source/core/crsr/callnk.hxx b/sw/source/core/crsr/callnk.hxx new file mode 100644 index 000000000000..689b047e0fa2 --- /dev/null +++ b/sw/source/core/crsr/callnk.hxx @@ -0,0 +1,88 @@ +/************************************************************************* + * + * $RCSfile: callnk.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:17 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#ifndef _CALLNK_HXX +#define _CALLNK_HXX + +#include + +class SwCrsrShell; +class SwTxtNode; + +class SwCallLink +{ +public: + SwCrsrShell & rShell; + ULONG nNode; + xub_StrLen nCntnt; + BYTE nNdTyp; + long nLeftFrmPos; + + SwCallLink( SwCrsrShell & rSh ); + SwCallLink( SwCrsrShell & rSh, ULONG nAktNode, xub_StrLen nAktCntnt, + BYTE nAktNdTyp, long nLRPos ); + ~SwCallLink(); + + static long GetFrm( SwTxtNode& rNd, xub_StrLen nCntPos, BOOL bCalcFrm ); +}; + + + +#endif // _CALLNK_HXX diff --git a/sw/source/core/crsr/crbm.cxx b/sw/source/core/crsr/crbm.cxx new file mode 100644 index 000000000000..e7e70afb7bb0 --- /dev/null +++ b/sw/source/core/crsr/crbm.cxx @@ -0,0 +1,281 @@ +/************************************************************************* + * + * $RCSfile: crbm.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:17 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#include "doc.hxx" +#include "crsrsh.hxx" +#include "ndtxt.hxx" +#ifndef _DOCARY_HXX +#include +#endif + +#include "bookmrk.hxx" +#include "callnk.hxx" +#include "swcrsr.hxx" + + +/* + * Methoden der SwCrsrShell fuer Bookmark + */ + + +// am CurCrsr.SPoint +FASTBOOL SwCrsrShell::SetBookmark( const KeyCode& rCode, const String& rName, + const String& rShortName, BOOKMARK_TYPE eMark ) +{ + StartAction(); + FASTBOOL bRet = 0 != pDoc->MakeBookmark( *GetCrsr(), rCode, rName, + rShortName, eMark); + EndAction(); + return bRet; +} +// setzt CurCrsr.SPoint + + +FASTBOOL SwCrsrShell::GotoBookmark(USHORT nPos, BOOL bAtStart) +{ + // Crsr-Moves ueberwachen, evt. Link callen + FASTBOOL bRet = TRUE; + SwCallLink aLk( *this ); + + SwBookmark* pBkmk = pDoc->GetBookmarks()[ nPos ]; + SwCursor* pCrsr = GetSwCrsr(); + SwCrsrSaveState aSaveState( *pCrsr ); + + if( pBkmk->GetOtherPos() ) + { + if( bAtStart ) + *pCrsr->GetPoint() = *pBkmk->GetOtherPos() < pBkmk->GetPos() + ? *pBkmk->GetOtherPos() + : pBkmk->GetPos(); + else + *pCrsr->GetPoint() = *pBkmk->GetOtherPos() > pBkmk->GetPos() + ? *pBkmk->GetOtherPos() + : pBkmk->GetPos(); + } + else + *pCrsr->GetPoint() = pBkmk->GetPos(); + + if( pCrsr->IsSelOvr( SELOVER_CHECKNODESSECTION | SELOVER_TOGGLE ) ) + { + pCrsr->DeleteMark(); + pCrsr->RestoreSavePos(); + bRet = FALSE; + } + else + UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); + return bRet; +} + + +FASTBOOL SwCrsrShell::GotoBookmark(USHORT nPos) +{ + // Crsr-Moves ueberwachen, evt. Link callen + FASTBOOL bRet = TRUE; + SwCallLink aLk( *this ); + SwBookmark* pBkmk = pDoc->GetBookmarks()[ nPos ]; + SwCursor* pCrsr = GetSwCrsr(); + SwCrsrSaveState aSaveState( *pCrsr ); + + *pCrsr->GetPoint() = pBkmk->GetPos(); + if( pBkmk->GetOtherPos() ) + { + pCrsr->SetMark(); + *pCrsr->GetMark() = *pBkmk->GetOtherPos(); + if( *pCrsr->GetMark() > *pCrsr->GetPoint() ) + pCrsr->Exchange(); + } + + if( pCrsr->IsSelOvr( SELOVER_CHECKNODESSECTION | SELOVER_TOGGLE ) ) + { + pCrsr->DeleteMark(); + pCrsr->RestoreSavePos(); + bRet = FALSE; + } + else + UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); + return bRet; +} +// TRUE, wenn's noch eine gab + + +FASTBOOL SwCrsrShell::GoNextBookmark() +{ + SwBookmark aBM(*GetCrsr()->GetPoint()); + USHORT nPos; + const SwBookmarks& rBkmks = pDoc->GetBookmarks(); + rBkmks.Seek_Entry( &aBM, &nPos ); + if ( nPos == rBkmks.Count() ) + return FALSE; + + // alle die Inhaltlich auf der gleichen Position stehen, ueberspringen + while( aBM.IsEqualPos( *rBkmks[ nPos ] )) + if( ++nPos == rBkmks.Count() ) + return FALSE; + + while( !GotoBookmark( nPos )) + if( ++nPos == rBkmks.Count() ) + return FALSE; + + return TRUE; +} + + +FASTBOOL SwCrsrShell::GoPrevBookmark() +{ + const SwBookmarks& rBkmks = pDoc->GetBookmarks(); + if ( !rBkmks.Count() ) + return FALSE; + + USHORT nPos; + SwCursor* pCrsr = GetSwCrsr(); + SwBookmark aBM( *pCrsr->GetPoint() ); + rBkmks.Seek_Entry( &aBM, &nPos ); + + const SwBookmark* pBkmk; + // alle die Inhaltlich auf der gleichen Position stehen, ueberspringen + do { + if ( nPos == 0 ) + return FALSE; + } while( aBM < *(pBkmk = rBkmks[--nPos]) || aBM.IsEqualPos( *pBkmk )); + + SwCallLink aLk( *this ); + SwCrsrSaveState aSaveState( *pCrsr ); + + FASTBOOL bRet = FALSE; + do { + pBkmk = rBkmks[ nPos ]; + + *pCrsr->GetPoint() = pBkmk->GetPos(); + if( pBkmk->GetOtherPos() ) + { + pCrsr->SetMark(); + *pCrsr->GetMark() = *pBkmk->GetOtherPos(); + if( *pCrsr->GetMark() < *pCrsr->GetPoint() ) + pCrsr->Exchange(); + } + if( !pCrsr->IsSelOvr( SELOVER_CHECKNODESSECTION | SELOVER_TOGGLE ) ) + { + UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); + bRet = TRUE; + } + + } while( !bRet && nPos-- ); + + if( !bRet ) + { + pCrsr->DeleteMark(); + pCrsr->RestoreSavePos(); + } + + return bRet; +} + + + +USHORT SwCrsrShell::GetBookmarkCnt(BOOL bBkmrk) const +{ + return pDoc->GetBookmarkCnt(bBkmrk); +} + + +SwBookmark& SwCrsrShell::GetBookmark(USHORT nPos, BOOL bBkmrk) +{ + return pDoc->GetBookmark(nPos, bBkmrk); +} + + +void SwCrsrShell::DelBookmark(USHORT nPos) +{ + StartAction(); + pDoc->DelBookmark(nPos); + EndAction(); +} + + +void SwCrsrShell::DelBookmark( const String& rName ) +{ + StartAction(); + pDoc->DelBookmark( rName ); + EndAction(); +} + + +USHORT SwCrsrShell::FindBookmark( const String& rName ) +{ + return pDoc->FindBookmark( rName ); +} + + + // erzeugt einen eindeutigen Namen. Der Name selbst muss vorgegeben + // werden, es wird dann bei gleichen Namen nur durchnumeriert. +void SwCrsrShell::MakeUniqueBookmarkName( String& rName ) +{ + pDoc->MakeUniqueBookmarkName( rName ); +} + + + diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx new file mode 100644 index 000000000000..b7452ccc7411 --- /dev/null +++ b/sw/source/core/crsr/crsrsh.cxx @@ -0,0 +1,2831 @@ +/************************************************************************* + * + * $RCSfile: crsrsh.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:17 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _HINTIDS_HXX +#include +#endif + +#ifndef _SVDMODEL_HXX //autogen +#include +#endif + +#ifndef _DOC_HXX +#include +#endif +#ifndef _ROOTFRM_HXX +#include +#endif +#ifndef _PAGEFRM_HXX +#include +#endif +#ifndef _CNTFRM_HXX +#include +#endif +#ifndef _VIEWIMP_HXX +#include +#endif +#ifndef _ERRHDL_HXX +#include // fuer ASSERT +#endif +#ifndef _PAM_HXX +#include +#endif +#ifndef _NDTXT_HXX +#include +#endif +#ifndef _FLYFRM_HXX +#include +#endif +#ifndef _DVIEW_HXX +#include +#endif +#ifndef _VIEWOPT_HXX +#include +#endif +#ifndef _FRMTOOL_HXX +#include +#endif +#ifndef _CRSRSH_HXX +#include +#endif +#ifndef _TABFRM_HXX +#include +#endif +#ifndef _TXTFRM_HXX +#include +#endif +#ifndef _SWTABLE_HXX +#include +#endif +#ifndef _CALLNK_HXX +#include +#endif +#ifndef _VISCRS_HXX +#include +#endif +#ifndef _SECTION_HXX +#include +#endif +#ifndef _DOCSH_HXX +#include +#endif +#ifndef _SWGLOBDOCSH_HXX //autogen +#include +#endif +#ifndef _PAMTYP_HXX +#include +#endif +#ifndef _MDIEXP_HXX +#include // ...Percent() +#endif +#ifndef _FMTEIRO_HXX //autogen +#include +#endif + +using namespace ::com::sun::star; + +TYPEINIT2(SwCrsrShell,ViewShell,SwModify); + + +// Funktion loescht, alle ueberlappenden Cursor aus einem Cursor-Ring +void CheckRange( SwCursor* ); + +//----------------------------------------------------------------------- + +/* + * Ueberpruefe ob der pCurCrsr in einen schon bestehenden Bereich zeigt. + * Wenn ja, dann hebe den alten Bereich auf. + */ + + +void CheckRange( SwCursor* pCurCrsr ) +{ + const SwPosition *pStt = pCurCrsr->Start(), + *pEnd = pCurCrsr->GetPoint() == pStt ? pCurCrsr->GetMark() : pCurCrsr->GetPoint(); + + SwPaM *pTmpDel = 0, + *pTmp = (SwPaM*)pCurCrsr->GetNext(); + + // durchsuche den gesamten Ring + while( pTmp != pCurCrsr ) + { + const SwPosition *pTmpStt = pTmp->Start(), + *pTmpEnd = pTmp->GetPoint() == pTmpStt ? + pTmp->GetMark() : pTmp->GetPoint(); + if( *pStt <= *pTmpStt ) + { + if( *pEnd > *pTmpStt || + ( *pEnd == *pTmpStt && *pEnd == *pTmpEnd )) + pTmpDel = pTmp; + } + else + if( *pStt < *pTmpEnd ) + pTmpDel = pTmp; + /* + * liegt ein SPoint oder GetMark innerhalb vom Crsr-Bereich + * muss der alte Bereich aufgehoben werden. + * Beim Vergleich ist darauf zu achten, das SPoint nicht mehr zum + * Bereich gehoert ! + */ + pTmp = (SwPaM*)pTmp->GetNext(); + if( pTmpDel ) + { + delete pTmpDel; // hebe alten Bereich auf + pTmpDel = 0; + } + } +} + +// -------------- Methoden von der SwCrsrShell ------------- + +SwPaM * SwCrsrShell::CreateCrsr() +{ + // Innerhalb der Tabellen-SSelection keinen neuen Crsr anlegen + ASSERT( !IsTableMode(), "in Tabellen SSelection" ); + + // neuen Cursor als Kopie vom akt. und in den Ring aufnehmen + // Verkettung zeigt immer auf den zuerst erzeugten, also vorwaerts + SwShellCrsr* pNew = new SwShellCrsr( *pCurCrsr ); + + // hier den akt. Pam nur logisch Hiden, weil sonst die Invertierung + // vom kopierten Pam aufgehoben wird !! + pNew->Insert( pCurCrsr, 0 ); + pCurCrsr->Remove( 0, pCurCrsr->Count() ); + + pCurCrsr->DeleteMark(); + + UpdateCrsr( SwCrsrShell::SCROLLWIN ); +// return pCurCrsr; + return pNew; +} + +// loesche den aktuellen Cursor und der folgende wird zum Aktuellen + + +FASTBOOL SwCrsrShell::DestroyCrsr() +{ + // Innerhalb der Tabellen-SSelection keinen neuen Crsr loeschen + ASSERT( !IsTableMode(), "in Tabellen SSelection" ); + + // ist ueberhaupt ein naechtser vorhanden ? + if(pCurCrsr->GetNext() == pCurCrsr) + return FALSE; + + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, + SwCursor* pNext = (SwCursor*)pCurCrsr->GetNext(); + delete pCurCrsr; + pCurCrsr = (SwShellCrsr*)*pNext; + UpdateCrsr(); + return TRUE; +} + + +// gebe den aktuellen zurueck + +SwPaM* SwCrsrShell::GetCrsr( FASTBOOL bMakeTblCrsr ) const +{ + if( pTblCrsr ) + { + if( bMakeTblCrsr && pTblCrsr->IsCrsrMovedUpdt() ) + { + // geparkte Cursor werden nicht wieder erzeugt + const SwCntntNode* pCNd; + if( pTblCrsr->GetPoint()->nNode.GetIndex() && + pTblCrsr->GetMark()->nNode.GetIndex() && + 0 != ( pCNd = pTblCrsr->GetCntntNode() ) && pCNd->GetFrm() && + 0 != ( pCNd = pTblCrsr->GetCntntNode(FALSE) ) && pCNd->GetFrm()) + { + SwShellTableCrsr* pTC = (SwShellTableCrsr*)pTblCrsr; + GetLayout()->MakeTblCrsrs( *pTC ); + } + } + + if( pTblCrsr->IsChgd() ) + { + SwCrsrShell* pThis = (SwCrsrShell*)this; + pThis->pCurCrsr = (SwShellCrsr*) + *pTblCrsr->MakeBoxSels( pThis->pCurCrsr ); + } + } + return pCurCrsr; +} + + +void SwCrsrShell::StartAction() +{ + if( !ActionPend() ) + { + // fuer das Update des Ribbon-Bars merken + const SwNode& rNd = pCurCrsr->GetPoint()->nNode.GetNode(); + nAktNode = rNd.GetIndex(); + nAktCntnt = pCurCrsr->GetPoint()->nContent.GetIndex(); + nAktNdTyp = rNd.GetNodeType(); + if( ND_TEXTNODE & nAktNdTyp ) + nLeftFrmPos = SwCallLink::GetFrm( (SwTxtNode&)rNd, nAktCntnt, TRUE ); + else + nLeftFrmPos = 0; + } + ViewShell::StartAction(); // zur ViewShell +} + + +void SwCrsrShell::EndAction( const BOOL bIdleEnd ) +{ +/* +//OS: Wird z.B. eine Basic-Action im Hintergrund ausgefuehrt, geht es so nicht + if( !bHasFocus ) + { + // hat die Shell nicht den Focus, dann nur das EndAction an + // die ViewShell weitergeben. + ViewShell::EndAction( bIdleEnd ); + return; + } +*/ + + FASTBOOL bVis = bSVCrsrVis; + + // Idle-Formatierung ? + if( bIdleEnd && Imp()->GetRegion() ) + { + pCurCrsr->Hide(); + +#ifdef SHOW_IDLE_REGION +if( GetWin() ) +{ + GetWin()->Push(); + GetWin()->ChangePen( Pen( Color( COL_YELLOW ))); + for( USHORT n = 0; n < aPntReg.Count(); ++n ) + { + SwRect aIRect( aPntReg[n] ); + GetWin()->DrawRect( aIRect.SVRect() ); + } + GetWin()->Pop(); +} +#endif + + } + + // vor der letzten Action alle invaliden Numerierungen updaten + if( 1 == nStartAction ) + GetDoc()->UpdateNumRule(); + + // Task: 76923: dont show the cursor in the ViewShell::EndAction() - call. + // Only the UpdateCrsr shows the cursor. + BOOL bSavSVCrsrVis = bSVCrsrVis; + bSVCrsrVis = FALSE; + + ViewShell::EndAction( bIdleEnd ); //der ViewShell den Vortritt lassen + + bSVCrsrVis = bSavSVCrsrVis; + + if( ActionPend() ) + { + if( bVis ) // auch SV-Cursor wieder anzeigen + pVisCrsr->Show(); + + // falls noch ein ChgCall vorhanden ist und nur noch die Basic + // Klammerung vorhanden ist, dann rufe ihn. Dadurch wird die interne + // mit der Basic-Klammerung entkoppelt; die Shells werden umgeschaltet + if( !BasicActionPend() ) + { + //JP 12.01.98: Bug #46496# - es muss innerhalb einer BasicAction + // der Cursor geupdatet werden; um z.B. den + // TabellenCursor zu erzeugen. Im UpdateCrsr wird + // das jetzt beruecksichtigt! + UpdateCrsr( SwCrsrShell::CHKRANGE, bIdleEnd ); + + { + // Crsr-Moves ueberwachen, evt. Link callen + // der DTOR ist das interressante!! + SwCallLink aLk( *this, nAktNode, nAktCntnt, (BYTE)nAktNdTyp, + nLeftFrmPos ); + + } + if( bCallChgLnk && bChgCallFlag && aChgLnk.IsSet() ) + { + aChgLnk.Call( this ); + bChgCallFlag = FALSE; // Flag zuruecksetzen + } + } + return; + } + + USHORT nParm = SwCrsrShell::CHKRANGE; + if ( !bIdleEnd ) + nParm |= SwCrsrShell::SCROLLWIN; + UpdateCrsr( nParm, bIdleEnd ); // Cursor-Aenderungen anzeigen + + { + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, + aLk.nNode = nAktNode; // evt. Link callen + aLk.nNdTyp = (BYTE)nAktNdTyp; + aLk.nCntnt = nAktCntnt; + aLk.nLeftFrmPos = nLeftFrmPos; + + if( !nCrsrMove || + ( 1 == nCrsrMove && bInCMvVisportChgd ) ) + ShowCrsrs( bSVCrsrVis ? TRUE : FALSE ); // Cursor & Selektionen wieder anzeigen + } + // falls noch ein ChgCall vorhanden ist, dann rufe ihn + if( bCallChgLnk && bChgCallFlag && aChgLnk.IsSet() ) + { + aChgLnk.Call( this ); + bChgCallFlag = FALSE; // Flag zuruecksetzen + } +} + + +#if !defined( PRODUCT ) + +void SwCrsrShell::SttCrsrMove() +{ + ASSERT( nCrsrMove < USHRT_MAX, "To many nested CrsrMoves." ); + ++nCrsrMove; + StartAction(); +} + +void SwCrsrShell::EndCrsrMove( const BOOL bIdleEnd ) +{ + ASSERT( nCrsrMove, "EndCrsrMove() ohne SttCrsrMove()." ); + EndAction( bIdleEnd ); + if( !--nCrsrMove ) + bInCMvVisportChgd = FALSE; +} + +#endif + + +FASTBOOL SwCrsrShell::LeftRight( BOOL bLeft, USHORT nCnt ) +{ + if( IsTableMode() ) + return bLeft ? GoPrevCell() : GoNextCell(); + + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + FASTBOOL bRet = pCurCrsr->LeftRight( bLeft, nCnt ); + if( bRet ) + UpdateCrsr(); + return bRet; +} + + +FASTBOOL SwCrsrShell::UpDown( BOOL bUp, USHORT nCnt ) +{ + SET_CURR_SHELL( this ); + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + + BOOL bTableMode = IsTableMode(); + SwShellCrsr* pTmpCrsr = bTableMode ? pTblCrsr : pCurCrsr; + + FASTBOOL bRet = pTmpCrsr->UpDown( bUp, nCnt ); + if( bRet ) + { + eMvState = MV_UPDOWN; // Status fuers Crsr-Travelling - GetCrsrOfst + if( !ActionPend() ) + { + CrsrFlag eUpdtMode = SwCrsrShell::SCROLLWIN; + if( !bTableMode ) + eUpdtMode = (CrsrFlag) (eUpdtMode + | SwCrsrShell::UPDOWN | SwCrsrShell::CHKRANGE); + UpdateCrsr( eUpdtMode ); + } + } + return bRet; +} + + +FASTBOOL SwCrsrShell::LRMargin( BOOL bLeft, BOOL bAPI) +{ + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + SET_CURR_SHELL( this ); + eMvState = MV_LEFTMARGIN; // Status fuers Crsr-Travelling - GetCrsrOfst + + BOOL bTableMode = IsTableMode(); + SwShellCrsr* pTmpCrsr = bTableMode ? pTblCrsr : pCurCrsr; + FASTBOOL bRet = pTmpCrsr->LeftRightMargin( bLeft, bAPI ); + if( bRet ) + UpdateCrsr(); + return bRet; +} + +FASTBOOL SwCrsrShell::IsAtLRMargin( BOOL bLeft, BOOL bAPI ) const +{ + SwShellCrsr* pTmpCrsr = IsTableMode() ? pTblCrsr : pCurCrsr; + return pTmpCrsr->IsAtLeftRightMargin( bLeft, bAPI ); +} + + +FASTBOOL SwCrsrShell::SttEndDoc( BOOL bStt ) +{ + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + + FASTBOOL bRet = pCurCrsr->SttEndDoc( bStt ); + if( bRet ) + { + if( bStt ) + pCurCrsr->GetPtPos().Y() = 0; // expl. 0 setzen (TabellenHeader) + + UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); + } + return bRet; +} + + + +FASTBOOL SwCrsrShell::MovePage( SwWhichPage fnWhichPage, SwPosPage fnPosPage ) +{ + FASTBOOL bRet = FALSE; + + // Springe beim Selektieren nie ueber Section-Grenzen !! + if( !pCurCrsr->HasMark() || !pCurCrsr->IsNoCntnt() ) + { + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + SET_CURR_SHELL( this ); + + SwCrsrSaveState aSaveState( *pCurCrsr ); + Point& rPt = pCurCrsr->GetPtPos(); + SwCntntFrm * pFrm = pCurCrsr->GetCntntNode()-> + GetFrm( &rPt, pCurCrsr->GetPoint() ); + if( pFrm && TRUE == ( bRet = GetFrmInPage( pFrm, fnWhichPage, + fnPosPage, pCurCrsr ) ) && + !pCurCrsr->IsSelOvr( SELOVER_TOGGLE | SELOVER_CHANGEPOS )) + UpdateCrsr(); + else + bRet = FALSE; + } + return bRet; +} + + +FASTBOOL SwCrsrShell::MovePara(SwWhichPara fnWhichPara, SwPosPara fnPosPara ) +{ + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + FASTBOOL bRet = pCurCrsr->MovePara( fnWhichPara, fnPosPara ); + if( bRet ) + UpdateCrsr(); + return bRet; +} + + +FASTBOOL SwCrsrShell::MoveSection( SwWhichSection fnWhichSect, + SwPosSection fnPosSect) +{ + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + FASTBOOL bRet = pCurCrsr->MoveSection( fnWhichSect, fnPosSect ); + if( bRet ) + UpdateCrsr(); + return bRet; + +} + + +// Positionieren des Cursors + + +SwFrm* lcl_IsInHeaderFooter( const SwNodeIndex& rIdx, Point& rPt ) +{ + SwFrm* pFrm = 0; + SwCntntNode* pCNd = rIdx.GetNode().GetCntntNode(); + if( pCNd ) + { + pFrm = pCNd->GetFrm( &rPt, 0, FALSE )->GetUpper(); + while( pFrm && !pFrm->IsHeaderFrm() && !pFrm->IsFooterFrm() ) + pFrm = pFrm->IsFlyFrm() ? ((SwFlyFrm*)pFrm)->GetAnchor() + : pFrm->GetUpper(); + } + return pFrm; +} + +FASTBOOL SwCrsrShell::IsInHeaderFooter( FASTBOOL* pbInHeader ) const +{ + SwShellCrsr* pCrsr = IsTableMode() ? pTblCrsr : pCurCrsr; + Point aPt; + SwFrm* pFrm = ::lcl_IsInHeaderFooter( pCurCrsr->GetPoint()->nNode, aPt ); + if( pFrm && pbInHeader ) + *pbInHeader = pFrm->IsHeaderFrm(); + return 0 != pFrm; +} + +int SwCrsrShell::SetCrsr( const Point &rLPt, BOOL bOnlyText ) +{ + SET_CURR_SHELL( this ); + + SwNodes& rNds = GetDoc()->GetNodes(); + SwShellCrsr* pCrsr = IsTableMode() ? pTblCrsr : pCurCrsr; + SwPosition aPos( *pCrsr->GetPoint() ); + Point aPt( rLPt ); + Point & rAktCrsrPt = pCrsr->GetPtPos(); + SwCrsrMoveState aTmpState( IsTableMode() ? MV_TBLSEL : + bOnlyText ? MV_SETONLYTEXT : MV_NONE ); + aTmpState.bSetInReadOnly = IsReadOnlyAvailable(); + + int bRet = CRSR_POSOLD | + ( GetLayout()->GetCrsrOfst( &aPos, aPt, &aTmpState ) + ? 0 : CRSR_POSCHG ); + + if( MV_RIGHTMARGIN == aTmpState.eState ) + eMvState = MV_RIGHTMARGIN; + // steht neu Pos im Header/Footer ? + SwFrm* pFrm = lcl_IsInHeaderFooter( aPos.nNode, aPt ); + if( IsTableMode() && !pFrm && aPos.nNode.GetNode().FindStartNode() == + pCrsr->GetPoint()->nNode.GetNode().FindStartNode() ) + // gleiche Tabellenzelle und nicht im Header/Footer + // -> zurueck + return bRet; + + if( !pCrsr->HasMark() ) + { + // steht an der gleichen Position und wenn im Header/Footer, + // dann im gleichen + if( aPos == *pCrsr->GetPoint() ) + { + if( pFrm ) + { + if( pFrm->Frm().IsInside( rAktCrsrPt )) + return bRet; + } + else if( aPos.nNode.GetNode().IsCntntNode() ) + { + // im gleichen Frame gelandet? + SwFrm* pOld = ((SwCntntNode&)aPos.nNode.GetNode()).GetFrm( + &aCharRect.Pos(), 0, FALSE ); + SwFrm* pNew = ((SwCntntNode&)aPos.nNode.GetNode()).GetFrm( + &aPt, 0, FALSE ); + if( pNew == pOld ) + return bRet; + } + } + } + else + { + // SSelection ueber nicht erlaubte Sections oder wenn im Header/Footer + // dann in verschiedene + if( !CheckNodesRange( aPos.nNode, pCrsr->GetMark()->nNode, TRUE ) + || ( pFrm && !pFrm->Frm().IsInside( pCrsr->GetMkPos() ) )) + return bRet; + + // steht an der gleichen Position und nicht im Header/Footer + if( aPos == *pCrsr->GetPoint() ) + return bRet; + } + + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + SwCrsrSaveState aSaveState( *pCrsr ); + + *pCrsr->GetPoint() = aPos; + rAktCrsrPt = aPt; + + if( !pCrsr->IsSelOvr( SELOVER_CHANGEPOS ) ) + { + UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE); + bRet &= ~CRSR_POSOLD; + } + else if( bOnlyText && !pCurCrsr->HasMark() ) + { + if( FindValidCntntNode( bOnlyText ) ) + { + // Cursor in einen gueltigen Content stellen + if( aPos == *pCrsr->GetPoint() ) + bRet = CRSR_POSOLD; + else + { + UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE ); + bRet &= ~CRSR_POSOLD; + } + } + else + { + // es gibt keinen gueltigen Inhalt -> Cursor verstecken + pVisCrsr->Hide(); // sichtbaren Cursor immer verstecken + eMvState = MV_NONE; // Status fuers Crsr-Travelling + bAllProtect = TRUE; + if( GetDoc()->GetDocShell() ) + { + GetDoc()->GetDocShell()->SetReadOnlyUI( TRUE ); + CallChgLnk(); // UI bescheid sagen! + } + } + } + + return bRet; +} + + +void SwCrsrShell::TblCrsrToCursor() +{ + ASSERT( pTblCrsr, "TblCrsrToCursor: Why?" ); + delete pTblCrsr, pTblCrsr = 0; +} + + +void SwCrsrShell::ClearMark() +{ + // ist ueberhaupt ein GetMark gesetzt ? + if( pTblCrsr ) + { + while( pCurCrsr->GetNext() != pCurCrsr ) + delete pCurCrsr->GetNext(); + pTblCrsr->DeleteMark(); + + if( pCurCrsr->HasMark() ) + { + // falls doch nicht alle Indizies richtig verschoben werden + // (z.B.: Kopf-/Fusszeile loeschen) den Content-Anteil vom + // Mark aufs Nodes-Array setzen + SwPosition& rPos = *pCurCrsr->GetMark(); + rPos.nNode.Assign( pDoc->GetNodes(), 0 ); + rPos.nContent.Assign( 0, 0 ); + pCurCrsr->DeleteMark(); + } + + *pCurCrsr->GetPoint() = *pTblCrsr->GetPoint(); + pCurCrsr->GetPtPos() = pTblCrsr->GetPtPos(); + delete pTblCrsr, pTblCrsr = 0; + pCurCrsr->SwSelPaintRects::Show(); + } + else + { + if( !pCurCrsr->HasMark() ) + return; + // falls doch nicht alle Indizies richtig verschoben werden + // (z.B.: Kopf-/Fusszeile loeschen) den Content-Anteil vom + // Mark aufs Nodes-Array setzen + SwPosition& rPos = *pCurCrsr->GetMark(); + rPos.nNode.Assign( pDoc->GetNodes(), 0 ); + rPos.nContent.Assign( 0, 0 ); + pCurCrsr->DeleteMark(); + if( !nCrsrMove ) + pCurCrsr->SwSelPaintRects::Show(); + } +} + + +void SwCrsrShell::SwapPam() +{ + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + pCurCrsr->Exchange(); +} + + +// suche innerhalb der Selektierten-Bereiche nach einer Selektion, die +// den angebenen SPoint umschliesst +// Ist das Flag bTstOnly gesetzt, dann wird nur getestet, ob dort eine +// SSelection besteht; des akt. Cursr wird nicht umgesetzt! +// Ansonsten wird er auf die gewaehlte SSelection gesetzt. + + +FASTBOOL SwCrsrShell::ChgCurrPam( const Point & rPt, + BOOL bTstOnly, BOOL bTstHit ) +{ + SET_CURR_SHELL( this ); + + // Pruefe ob der SPoint in einer Tabellen-Selektion liegt + if( bTstOnly && pTblCrsr ) + return pTblCrsr->IsInside( rPt ); + + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + // Suche die Position rPt im Dokument + SwPosition aPtPos( *pCurCrsr->GetPoint() ); + Point aPt( rPt ); + + SwCrsrMoveState aTmpState( MV_NONE ); + aTmpState.bSetInReadOnly = IsReadOnlyAvailable(); + if ( !GetLayout()->GetCrsrOfst( &aPtPos, aPt, &aTmpState ) && bTstHit ) + return FALSE; + + // suche in allen Selektionen nach dieser Position + SwShellCrsr* pCmp = (SwShellCrsr*)pCurCrsr; // sicher den Pointer auf Cursor + do { + if( pCmp->HasMark() && + *pCmp->Start() <= aPtPos && *pCmp->End() > aPtPos ) + { + if( bTstOnly || pCurCrsr == pCmp ) // ist der aktuelle. + return TRUE; // return ohne Update + + pCurCrsr = pCmp; + UpdateCrsr(); // Cursor steht schon richtig + return TRUE; + } + } while( pCurCrsr != ( pCmp = (SwShellCrsr*)*((SwCursor*)pCmp->GetNext()) ) ); + return FALSE; +} + + +void SwCrsrShell::KillPams() +{ + // keiner zum loeschen vorhanden? + if( !pTblCrsr && pCurCrsr->GetNext() == pCurCrsr ) + return; + + while( pCurCrsr->GetNext() != pCurCrsr ) + delete pCurCrsr->GetNext(); + + if( pTblCrsr ) + { + // Cursor Ring loeschen + pCurCrsr->DeleteMark(); + *pCurCrsr->GetPoint() = *pTblCrsr->GetPoint(); + pCurCrsr->GetPtPos() = pTblCrsr->GetPtPos(); + delete pTblCrsr, pTblCrsr = 0; + } + UpdateCrsr( SwCrsrShell::SCROLLWIN ); +} + + +int SwCrsrShell::CompareCursor( CrsrCompareType eType ) const +{ + int nRet = 0; + const SwPosition *pFirst = 0, *pSecond = 0; + const SwPaM *pCur = GetCrsr(), *pStk = pCrsrStk; + if( CurrPtCurrMk != eType && pStk ) + { + switch ( eType) + { + case StackPtStackMk: + pFirst = pStk->GetPoint(); + pSecond = pStk->GetMark(); + break; + case StackPtCurrPt: + pFirst = pStk->GetPoint(); + pSecond = pCur->GetPoint(); + break; + case StackPtCurrMk: + pFirst = pStk->GetPoint(); + pSecond = pCur->GetMark(); + break; + case StackMkCurrPt: + pFirst = pStk->GetMark(); + pSecond = pCur->GetPoint(); + break; + case StackMkCurrMk: + pFirst = pStk->GetMark(); + pSecond = pStk->GetMark(); + break; + case CurrPtCurrMk: + pFirst = pCur->GetPoint(); + pSecond = pCur->GetMark(); + break; + } + } + if( !pFirst || !pSecond ) + nRet = INT_MAX; + else if( *pFirst < *pSecond ) + nRet = -1; + else if( *pFirst == *pSecond ) + nRet = 0; + else + nRet = 1; + return nRet; +} + + +FASTBOOL SwCrsrShell::IsSttPara() const +{ return( pCurCrsr->GetPoint()->nContent == 0 ? TRUE : FALSE ); } + + +FASTBOOL SwCrsrShell::IsEndPara() const +{ return( pCurCrsr->GetPoint()->nContent == pCurCrsr->GetCntntNode()->Len() ? TRUE : FALSE ); } + + +FASTBOOL SwCrsrShell::GotoPage( USHORT nPage ) +{ + SET_CURR_SHELL( this ); + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + SwCrsrSaveState aSaveState( *pCurCrsr ); + FASTBOOL bRet = GetLayout()->SetCurrPage( pCurCrsr, nPage ) && + !pCurCrsr->IsSelOvr( SELOVER_TOGGLE | SELOVER_CHANGEPOS ); + if( bRet ) + UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); + return bRet; +} + + +void SwCrsrShell::GetPageNum( USHORT &rnPhyNum, USHORT &rnVirtNum, + BOOL bAtCrsrPos, const BOOL bCalcFrm ) +{ + SET_CURR_SHELL( this ); + // Seitennummer: die erste sichtbare Seite oder die am Cursor + const SwCntntFrm* pCFrm; + const SwPageFrm *pPg = 0; + + if( !bAtCrsrPos || 0 == (pCFrm = GetCurrFrm( bCalcFrm )) || + 0 == (pPg = pCFrm->FindPageFrm()) ) + { + pPg = Imp()->GetFirstVisPage(); + while( pPg && pPg->IsEmptyPage() ) + pPg = (const SwPageFrm *)pPg->GetNext(); + } + // Abfrage auf pPg muss fuer den Sonderfall Writerstart mit + // standard.vor sein. + rnPhyNum = pPg? pPg->GetPhyPageNum() : 1; + rnVirtNum = pPg? pPg->GetVirtPageNum() : 1; +} + + +USHORT SwCrsrShell::GetNextPrevPageNum( BOOL bNext ) +{ + SET_CURR_SHELL( this ); + + // Seitennummer: die erste sichtbare Seite oder die am Cursor + const SwPageFrm *pPg = Imp()->GetFirstVisPage(); + if( pPg ) + { + if( bNext ) + { + // erstmal die sichtbare suchen !! + while( pPg && pPg->IsEmptyPage() ) + pPg = (const SwPageFrm *)pPg->GetNext(); + while( pPg && 0 != (pPg = (const SwPageFrm *)pPg->GetNext() ) && + pPg->IsEmptyPage() ) + ; + } + else + { + while( pPg && 0 != (pPg = (const SwPageFrm *)pPg->GetPrev() ) && + pPg->IsEmptyPage() ) + ; + } + } + // Abfrage auf pPg muss fuer den Sonderfall Writerstart mit + // standard.vor sein. + return pPg ? pPg->GetPhyPageNum() : USHRT_MAX; +} + + +USHORT SwCrsrShell::GetPageCnt() +{ + SET_CURR_SHELL( this ); + // gebe die Anzahl der Seiten zurueck + return GetLayout()->GetPageNum(); +} + +// Gehe zur naechsten SSelection + + +FASTBOOL SwCrsrShell::GoNextCrsr() +{ + // besteht ueberhaupt ein Ring ? + if( pCurCrsr->GetNext() == pCurCrsr ) + return FALSE; + + SET_CURR_SHELL( this ); + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + pCurCrsr = (SwShellCrsr*)*((SwCursor*)pCurCrsr->GetNext()); + + // Bug 24086: auch alle anderen anzeigen + if( !ActionPend() ) + { + UpdateCrsr(); + pCurCrsr->Show(); + } + return TRUE; +} + +// gehe zur vorherigen SSelection + + +FASTBOOL SwCrsrShell::GoPrevCrsr() +{ + // besteht ueberhaupt ein Ring ? + if( pCurCrsr->GetNext() == pCurCrsr ) + return FALSE; + + SET_CURR_SHELL( this ); + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + pCurCrsr = (SwShellCrsr*)*((SwCursor*)pCurCrsr->GetPrev()); + + // Bug 24086: auch alle anderen anzeigen + if( !ActionPend() ) + { + UpdateCrsr(); + pCurCrsr->Show(); + } + + return TRUE; +} + + +void SwCrsrShell::Paint( const Rectangle &rRect) +{ + SET_CURR_SHELL( this ); + + // beim Painten immer alle Cursor ausschalten + SwRect aRect( rRect ); + + FASTBOOL bVis = FALSE; + // ist Cursor sichtbar, dann verstecke den SV-Cursor + if( pVisCrsr->IsVisible() && !aRect.IsOver( aCharRect ) ) //JP 18.06.97: ??? + { + bVis = TRUE; + pVisCrsr->Hide(); + } + + ViewShell::Paint( rRect ); // Bereich neu painten + if( bHasFocus && !bBasicHideCrsr ) + { + SwShellCrsr* pAktCrsr = pTblCrsr ? pTblCrsr : pCurCrsr; +// pAktCrsr->Invalidate( aRect ); + if( !ActionPend() ) + { + // damit nicht rechts/unten die Raender abgeschnitten werden + pAktCrsr->Invalidate( VisArea() ); + pAktCrsr->Show(); + } + else + pAktCrsr->Invalidate( aRect ); + + } + if( bSVCrsrVis && bVis ) // auch SV-Cursor wieder anzeigen + pVisCrsr->Show(); +} + + + +void SwCrsrShell::VisPortChgd( const SwRect & rRect ) +{ + SET_CURR_SHELL( this ); + FASTBOOL bVis; // beim Scrollen immer alle Cursor ausschalten + + // ist Cursor sichtbar, dann verstecke den SV-Cursor + if( TRUE == ( bVis = pVisCrsr->IsVisible() )) + pVisCrsr->Hide(); + + bVisPortChgd = TRUE; + aOldRBPos.X() = VisArea().Right(); + aOldRBPos.Y() = VisArea().Bottom(); + + //Damit es es keine Probleme mit dem SV-Cursor gibt, wird in + //ViewShell::VisPo.. ein Update() auf das Window gerufen. + //Waehrend des Paintens duerfen aber nun wieder keine Selectionen + //angezeigt werden, deshalb wird der Aufruf hier geklammert. + ViewShell::VisPortChgd( rRect ); // Bereich verschieben + +/* + SwRect aRect( rRect ); + if( VisArea().IsOver( aRect ) ) + pCurCrsr->Invalidate( aRect ); +*/ + + if( bSVCrsrVis && bVis ) // auch SV-Cursor wieder anzeigen + pVisCrsr->Show(); + + if( nCrsrMove ) + bInCMvVisportChgd = TRUE; + + bVisPortChgd = FALSE; +} + +// aktualisiere den Crsrs, d.H. setze ihn wieder in den Content. +// Das sollte nur aufgerufen werden, wenn der Cursor z.B. beim +// Loeschen von Rahmen irgendwohin gesetzt wurde. Die Position +// ergibt sich aus seiner aktuellen Position im Layout !! + + +void SwCrsrShell::UpdateCrsrPos() +{ + SET_CURR_SHELL( this ); + ++nStartAction; + Size aOldSz( GetLayout()->Frm().SSize() ); + SwCntntNode *pCNode = pCurCrsr->GetCntntNode(); + SwCntntFrm *pFrm = pCNode ? + pCNode->GetFrm( &pCurCrsr->GetPtPos(), pCurCrsr->GetPoint() ) :0; + if( !pFrm || (pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsHiddenNow()) ) + { + SwCrsrMoveState aTmpState( MV_NONE ); + aTmpState.bSetInReadOnly = IsReadOnlyAvailable(); + GetLayout()->GetCrsrOfst( pCurCrsr->GetPoint(), pCurCrsr->GetPtPos(), + &aTmpState ); + if( pCurCrsr->HasMark()) + pCurCrsr->DeleteMark(); + } + --nStartAction; + if( aOldSz != GetLayout()->Frm().SSize() ) + SizeChgNotify( GetLayout()->Frm().SSize() ); +} + + +BOOL lcl_IsInValueBox( const SwPaM& rCrsr, SwCrsrShell& rShell ) +{ + BOOL bRet = FALSE; + const SwStartNode* pSttNd = rCrsr.GetNode()->FindSttNodeByType( SwTableBoxStartNode ); + if( pSttNd ) + { + const SwFrmFmt* pFmt = pSttNd->FindTableNode()->GetTable(). + GetTblBox( pSttNd->GetIndex() )->GetFrmFmt(); + bRet = SFX_ITEM_SET == pFmt->GetItemState( RES_BOXATR_VALUE ) || + SFX_ITEM_SET == pFmt->GetItemState( RES_BOXATR_FORMULA ); + // der WrtShell bescheid sagen!!! + rShell.NewCoreSelection(); + } + return bRet; +} + +// JP 30.04.99: Bug 65475 - falls Point/Mark in versteckten Bereichen +// stehen, so mussen diese daraus verschoben werden +void lcl_CheckHiddenSection( SwNodeIndex& rIdx ) +{ + const SwSectionNode* pSectNd = rIdx.GetNode().FindSectionNode(); + if( pSectNd && pSectNd->GetSection().IsHiddenFlag() ) + { + SwNodeIndex aTmp( *pSectNd ); + const SwNode* pFrmNd = rIdx.GetNodes().FindPrvNxtFrmNode( + aTmp, pSectNd->EndOfSectionNode() ); + ASSERT( pFrmNd, "keinen Node mit Frames gefunden" ); + rIdx = aTmp; + } +} + +void SwCrsrShell::UpdateCrsr( USHORT eFlags, BOOL bIdleEnd ) +{ + SET_CURR_SHELL( this ); + +#ifdef DEBUG +// pruefe ob die Indizies auch in den richtigen Nodes angemeldet sind +{ + SwShellCrsr* pCmp = (SwShellCrsr*)pCurCrsr; // sicher den Pointer auf Cursor + do { + ASSERT( pCmp->GetPoint()->nContent.GetIdxReg() + == pCmp->GetCntntNode(), "SPoint im falschen Node" ); + ASSERT( pCmp->GetMark()->nContent.GetIdxReg() + == pCmp->GetCntntNode(FALSE), "Mark im falschen Node" ); + FASTBOOL bTst = *pCmp->GetPoint() == *pCmp->GetMark(); + } while( pCurCrsr != ( pCmp = (SwShellCrsr*)*((SwCursor*)pCmp->GetNext() ) )); +} +#endif + + // erfrage den Count fuer die Start-/End-Actions und ob die Shell + // ueberhaupt den Focus hat +// if( ActionPend() /*|| !bHasFocus*/ ) + //JP 12.01.98: Bug #46496# - es muss innerhalb einer BasicAction der + // Cursor geupdatet werden; um z.B. den TabellenCursor zu + // erzeugen. Im EndAction wird jetzt das UpdateCrsr gerufen! + if( ActionPend() && BasicActionPend() ) + { + if ( eFlags & SwCrsrShell::READONLY ) + bIgnoreReadonly = TRUE; + return; // wenn nicht, dann kein Update !! + } + + if ( bIgnoreReadonly ) + { + bIgnoreReadonly = FALSE; + eFlags |= SwCrsrShell::READONLY; + } + + if( eFlags & SwCrsrShell::CHKRANGE ) // alle Cursor-Bewegungen auf + CheckRange( pCurCrsr ); // ueberlappende Bereiche testen + + if( !bIdleEnd ) + CheckTblBoxCntnt(); + + // steht der akt. Crsr in einer Tabelle und in unterschiedlichen Boxen + // (oder ist noch TabellenMode), dann gilt der Tabellen Mode + SwPaM* pTstCrsr = pTblCrsr ? pTblCrsr : pCurCrsr; + if( ( pTstCrsr->HasMark() && + pDoc->IsIdxInTbl( pTstCrsr->GetPoint()->nNode ) && + ( pTblCrsr || + pTstCrsr->GetNode( TRUE )->FindStartNode() != + pTstCrsr->GetNode( FALSE )->FindStartNode() )) + /*|| ( !pTblCrsr && lcl_IsInValueBox( *pTstCrsr, *this ) )*/ ) + { + SwShellCrsr* pITmpCrsr = pTblCrsr ? pTblCrsr : pCurCrsr; + Point aTmpPt( pITmpCrsr->GetPtPos() ); + Point aTmpMk( pITmpCrsr->GetMkPos() ); + SwPosition* pPos = pITmpCrsr->GetPoint(); + + // JP 30.04.99: Bug 65475 - falls Point/Mark in versteckten Bereichen + // stehen, so mussen diese daraus verschoben werden + ::lcl_CheckHiddenSection( pPos->nNode ); + ::lcl_CheckHiddenSection( pITmpCrsr->GetMark()->nNode ); + + SwCntntFrm *pTblFrm = pPos->nNode.GetNode().GetCntntNode()-> + GetFrm( &aTmpPt, pPos ), + *pMarkTblFrm; + ASSERT( pTblFrm, "Tabelle Crsr nicht im Content ??" ); + + SwTabFrm *pTab = pTblFrm->FindTabFrm(), *pMarkTab; + + if( pTab && pTab->GetTable()->IsHeadlineRepeat() && ( + ( pTab->IsFollow() && + ((SwLayoutFrm*)pTab->Lower())->IsAnLower( pTblFrm )) || + ( (pMarkTab = (pMarkTblFrm = pITmpCrsr->GetCntntNode( FALSE ) + ->GetFrm( &aTmpMk, pITmpCrsr->GetMark() ))->FindTabFrm())->IsFollow() && + ((SwLayoutFrm*)pMarkTab->Lower())->IsAnLower( pMarkTblFrm )) )) + { + // in wiederholten Tabellen-Kopfzeilen wollen wir keine + // Tabellen-Selektion !! + pTblFrm = 0; + + SwPosSection fnPosSect = *pPos < *pITmpCrsr->GetMark() + ? fnSectionStart + : fnSectionEnd; + + // dann nur innerhalb der Box selektieren + if( pTblCrsr ) + { + pCurCrsr->SetMark(); + *pCurCrsr->GetMark() = *pTblCrsr->GetMark(); + pCurCrsr->GetMkPos() = pTblCrsr->GetMkPos(); + pTblCrsr->DeleteMark(); + pTblCrsr->SwSelPaintRects::Hide(); + } + + *pCurCrsr->GetPoint() = *pCurCrsr->GetMark(); + (*fnSectionCurr)( *pCurCrsr, fnPosSect ); + } + + // wir wollen wirklich eine Tabellen-Selektion + if( pTab && pTblFrm ) + { + if( !pTblCrsr ) + { + pTblCrsr = new SwShellTableCrsr( *this, + *pCurCrsr->GetMark(), pCurCrsr->GetMkPos(), + *pPos, aTmpPt ); + pCurCrsr->DeleteMark(); + pCurCrsr->SwSelPaintRects::Hide(); + + CheckTblBoxCntnt(); + } + + if( !pTblFrm->GetCharRect( aCharRect, *pTblCrsr->GetPoint() ) ) + { + Point aCentrPt( aCharRect.Center() ); + SwCrsrMoveState aTmpState( MV_NONE ); + aTmpState.bSetInReadOnly = IsReadOnlyAvailable(); + pTblFrm->GetCrsrOfst( pTblCrsr->GetPoint(), aCentrPt, &aTmpState ); + if ( !pTblFrm->GetCharRect( aCharRect, *pTblCrsr->GetPoint() ) ) + ASSERT( !this, "GetCharRect failed." ); + } +// ALIGNRECT( aCharRect ); + + pVisCrsr->Hide(); // sichtbaren Cursor immer verstecken + // Curosr in den sichtbaren Bereich scrollen + if( (eFlags & SwCrsrShell::SCROLLWIN) && + (HasSelection() || eFlags & SwCrsrShell::READONLY || + !IsCrsrReadonly()) ) + { + SwFrm* pBoxFrm = pTblFrm; + while( pBoxFrm && !pBoxFrm->IsCellFrm() ) + pBoxFrm = pBoxFrm->GetUpper(); + if( pBoxFrm ) + MakeVisible( pBoxFrm->Frm() ); + else + MakeVisible( aCharRect ); + } + + // lasse vom Layout die Crsr in den Boxen erzeugen + if( pTblCrsr->IsCrsrMovedUpdt() ) + GetLayout()->MakeTblCrsrs( *pTblCrsr ); + if( bHasFocus && !bBasicHideCrsr ) + pTblCrsr->Show(); + + // Cursor-Points auf die neuen Positionen setzen + pTblCrsr->GetPtPos().X() = aCharRect.Left(); + pTblCrsr->GetPtPos().Y() = aCharRect.Top(); + + if( bSVCrsrVis ) + { + aCrsrHeight.X() = 0; + aCrsrHeight.Y() = aCharRect.Height(); + pVisCrsr->Show(); // wieder anzeigen + } + eMvState = MV_NONE; // Status fuers Crsr-Travelling - GetCrsrOfst + return; + } + } + + if( pTblCrsr ) + { + // Cursor Ring loeschen + while( pCurCrsr->GetNext() != pCurCrsr ) + delete pCurCrsr->GetNext(); + pCurCrsr->DeleteMark(); + *pCurCrsr->GetPoint() = *pTblCrsr->GetPoint(); + pCurCrsr->GetPtPos() = pTblCrsr->GetPtPos(); + delete pTblCrsr, pTblCrsr = 0; + } + + pVisCrsr->Hide(); // sichtbaren Cursor immer verstecken + + // sind wir vielleicht in einer geschuetzten/versteckten Section ? + { + BOOL bChgState = TRUE; + const SwSectionNode* pSectNd = pCurCrsr->GetNode()->FindSectionNode(); + if( pSectNd && ( pSectNd->GetSection().IsHiddenFlag() || + ( !IsReadOnlyAvailable() && + pSectNd->GetSection().IsProtectFlag() && + ( !pDoc->GetDocShell() || + !pDoc->GetDocShell()->IsReadOnly() || bAllProtect )) ) ) + { + if( !FindValidCntntNode( !HasDrawView() || + 0 == Imp()->GetDrawView()->GetMarkList().GetMarkCount())) + { + // alles ist geschuetzt / versteckt -> besonderer Mode + if( bAllProtect && !IsReadOnlyAvailable() && + pSectNd->GetSection().IsProtectFlag() ) + bChgState = FALSE; + else + { + eMvState = MV_NONE; // Status fuers Crsr-Travelling + bAllProtect = TRUE; + if( GetDoc()->GetDocShell() ) + { + GetDoc()->GetDocShell()->SetReadOnlyUI( TRUE ); + CallChgLnk(); // UI bescheid sagen! + } + return; + } + } + } + if( bChgState ) + { + BOOL bWasAllProtect = bAllProtect; + bAllProtect = FALSE; + if( bWasAllProtect && GetDoc()->GetDocShell() && + GetDoc()->GetDocShell()->IsReadOnlyUI() ) + { + GetDoc()->GetDocShell()->SetReadOnlyUI( FALSE ); + CallChgLnk(); // UI bescheid sagen! + } + } + } + + UpdateCrsrPos(); + + + SwRect aOld( aCharRect ); + FASTBOOL bFirst = TRUE; + SwCntntFrm *pFrm; + int nLoopCnt = 100; + + do { + BOOL bAgainst; + do { + bAgainst = FALSE; + pFrm = pCurCrsr->GetCntntNode()->GetFrm( + &pCurCrsr->GetPtPos(), pCurCrsr->GetPoint() ); + // ist der Frm nicht mehr vorhanden, dann muss das gesamte Layout + // erzeugt werden, weil ja mal hier einer vorhanden war !! + if ( !pFrm ) + { + do + { + CalcLayout(); + pFrm = pCurCrsr->GetCntntNode()->GetFrm( + &pCurCrsr->GetPtPos(), pCurCrsr->GetPoint() ); + } while( !pFrm ); + } + else if ( Imp()->IsIdleAction() ) + //Wir stellen sicher, dass anstaendig Formatiert wurde #42224# + pFrm->PrepareCrsr(); + + // im geschuetzten Fly? aber bei Rahmenselektion ignorieren + if( !IsReadOnlyAvailable() && pFrm->IsProtected() && + ( !Imp()->GetDrawView() || + !Imp()->GetDrawView()->GetMarkList().GetMarkCount() ) && + (!pDoc->GetDocShell() || + !pDoc->GetDocShell()->IsReadOnly() || bAllProtect ) ) + { + // dann suche eine gueltige Position + BOOL bChgState = TRUE; + if( !FindValidCntntNode(!HasDrawView() || + 0 == Imp()->GetDrawView()->GetMarkList().GetMarkCount())) + { + // alles ist geschuetzt / versteckt -> besonderer Mode + if( bAllProtect ) + bChgState = FALSE; + else + { + eMvState = MV_NONE; // Status fuers Crsr-Travelling + bAllProtect = TRUE; + if( GetDoc()->GetDocShell() ) + { + GetDoc()->GetDocShell()->SetReadOnlyUI( TRUE ); + CallChgLnk(); // UI bescheid sagen! + } + return; + } + } + + if( bChgState ) + { + BOOL bWasAllProtect = bAllProtect; + bAllProtect = FALSE; + if( bWasAllProtect && GetDoc()->GetDocShell() && + GetDoc()->GetDocShell()->IsReadOnlyUI() ) + { + GetDoc()->GetDocShell()->SetReadOnlyUI( FALSE ); + CallChgLnk(); // UI bescheid sagen! + } + bAllProtect = FALSE; + bAgainst = TRUE; // nochmal den richigen Frm suchen + } + } + } while( bAgainst ); + + if( !( eFlags & SwCrsrShell::NOCALRECT )) + { + SwCrsrMoveState aTmpState( eMvState ); + aTmpState.bSetInReadOnly = IsReadOnlyAvailable(); + aTmpState.bRealHeight = !pCurCrsr->HasMark(); + if( !pFrm->GetCharRect( aCharRect, *pCurCrsr->GetPoint(), &aTmpState ) ) + { + Point& rPt = pCurCrsr->GetPtPos(); + rPt = aCharRect.Center(); + pFrm->GetCrsrOfst( pCurCrsr->GetPoint(), rPt, &aTmpState ); + if ( !pFrm->GetCharRect(aCharRect, *pCurCrsr->GetPoint(), &aTmpState) ) + ASSERT( !this, "GetCharRect failed." ); + } +// ALIGNRECT( aCharRect ); + + if( aTmpState.bRealHeight ) + aCrsrHeight = aTmpState.aRealHeight; + else + { + aCrsrHeight.X() = 0; + aCrsrHeight.Y() = aCharRect.Height(); + } + } + else + { + aCrsrHeight.X() = 0; + aCrsrHeight.Y() = aCharRect.Height(); + } + + if( !bFirst && aOld == aCharRect ) + break; + + // falls das Layout meint, nach dem 100 durchlauf ist man immer noch + // im Fluss, sollte man die akt. Pos. als gegeben hinnehmen! + // siehe Bug: 29658 + if( !--nLoopCnt ) + { + ASSERT( !this, "Endlosschleife? CharRect != OldCharRect "); + break; + } + aOld = aCharRect; + bFirst = FALSE; + + // Cursor-Points auf die neuen Positionen setzen + pCurCrsr->GetPtPos().X() = aCharRect.Left(); + pCurCrsr->GetPtPos().Y() = aCharRect.Top(); + + if( !(eFlags & SwCrsrShell::UPDOWN )) // alte Pos. von Up/Down loeschen + { + pFrm->Calc(); + nUpDownX = aCharRect.Left() - pFrm->Frm().Left(); + } + + // Curosr in den sichtbaren Bereich scrollen + if( bHasFocus && eFlags & SwCrsrShell::SCROLLWIN && + (HasSelection() || eFlags & SwCrsrShell::READONLY || + !IsCrsrReadonly()) ) + { + //JP 30.04.99: damit das EndAction, beim evtuellen Scrollen, den + // SV-Crsr nicht wieder sichtbar macht, wird hier das Flag + // gesichert und zurueckgesetzt. + BOOL bSav = bSVCrsrVis; bSVCrsrVis = FALSE; + MakeSelVisible(); + bSVCrsrVis = bSav; + } + + } while( eFlags & SwCrsrShell::SCROLLWIN ); + + if( !bIdleEnd && bHasFocus && !bBasicHideCrsr ) + pCurCrsr->SwSelPaintRects::Show(); + + //Ggf. gescrollten Bereicht korrigieren (Alignment). + //Nur wenn gescrollt wurde, und wenn keine Selektion existiert. + if( pFrm && Imp()->IsScrolled() && + pCurCrsr->GetNext() == pCurCrsr && !pCurCrsr->HasMark() ) + Imp()->RefreshScrolledArea( aCharRect ); + + + eMvState = MV_NONE; // Status fuers Crsr-Travelling - GetCrsrOfst + + if( bSVCrsrVis ) + pVisCrsr->Show(); // wieder anzeigen +} + + + +// erzeuge eine Kopie vom Cursor und speicher diese im Stack + + +void SwCrsrShell::Push() +{ + pCrsrStk = new SwShellCrsr( *this, *pCurCrsr->GetPoint(), + pCurCrsr->GetPtPos(), pCrsrStk ); + + if( pCurCrsr->HasMark() ) + { + pCrsrStk->SetMark(); + *pCrsrStk->GetMark() = *pCurCrsr->GetMark(); + } +} + +/* + * Loescht einen Cursor (gesteuert durch bOldCrsr) + * - vom Stack oder ( bOldCrsr = TRUE ) + * - den aktuellen und der auf dem Stack stehende wird zum aktuellen + * + * Return: es war auf dem Stack noch einer vorhanden + */ + + +FASTBOOL SwCrsrShell::Pop( BOOL bOldCrsr ) +{ + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + + // noch weitere vorhanden ? + if( 0 == pCrsrStk ) + return FALSE; + + SwShellCrsr *pTmp = 0, *pOldStk = pCrsrStk; + + // der Nachfolger wird der Aktuelle + if( pCrsrStk->GetNext() != pCrsrStk ) + pTmp = (SwShellCrsr*)*((SwCursor*)pCrsrStk->GetNext()); + + if( bOldCrsr ) // loesche vom Stack + delete pCrsrStk; // + + pCrsrStk = pTmp; // neu zuweisen + + if( !bOldCrsr ) + { + SwCrsrSaveState aSaveState( *pCurCrsr ); + + // wurde die sichtbare SSelection nicht veraendert + if( pOldStk->GetPtPos() == pCurCrsr->GetPtPos() || + pOldStk->GetPtPos() == pCurCrsr->GetMkPos() ) + { + // "Selektions-Rechtecke" verschieben + pCurCrsr->Insert( pOldStk, 0 ); + pOldStk->Remove( 0, pOldStk->Count() ); + } + + if( pOldStk->HasMark() ) + { + pCurCrsr->SetMark(); + *pCurCrsr->GetMark() = *pOldStk->GetMark(); + pCurCrsr->GetMkPos() = pOldStk->GetMkPos(); + } + else + // keine Selection also alte aufheben und auf die alte Pos setzen + pCurCrsr->DeleteMark(); + *pCurCrsr->GetPoint() = *pOldStk->GetPoint(); + pCurCrsr->GetPtPos() = pOldStk->GetPtPos(); + delete pOldStk; + + if( !pCurCrsr->IsInProtectTable( TRUE ) && + !pCurCrsr->IsSelOvr( SELOVER_TOGGLE | SELOVER_CHANGEPOS ) ) + UpdateCrsr(); // akt. Cursor Updaten + } + return TRUE; +} + +/* + * Verbinde zwei Cursor miteinander. + * Loesche vom Stack den obersten und setzen dessen GetMark im Aktuellen. + */ + + +void SwCrsrShell::Combine() +{ + // noch weitere vorhanden ? + if( 0 == pCrsrStk ) + return; + + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + SwCrsrSaveState aSaveState( *pCurCrsr ); + if( pCrsrStk->HasMark() ) // nur wenn GetMark gesetzt wurde + { + if( !CheckNodesRange( pCrsrStk->GetMark()->nNode, pCurCrsr->GetPoint()->nNode, TRUE )) + ASSERT( !this, "StackCrsr & akt. Crsr nicht in gleicher Section." ); + + // kopiere das GetMark + if( !pCurCrsr->HasMark() ) + pCurCrsr->SetMark(); + *pCurCrsr->GetMark() = *pCrsrStk->GetMark(); + pCurCrsr->GetMkPos() = pCrsrStk->GetMkPos(); + } + + SwShellCrsr * pTmp = 0; + if( pCrsrStk->GetNext() != pCrsrStk ) + pTmp = (SwShellCrsr*)*((SwCursor*)pCrsrStk->GetNext()); + delete pCrsrStk; + pCrsrStk = pTmp; + if( !pCurCrsr->IsInProtectTable( TRUE ) && + !pCurCrsr->IsSelOvr( SELOVER_TOGGLE | SELOVER_CHANGEPOS ) ) + UpdateCrsr(); // akt. Cursor Updaten +} + + +void SwCrsrShell::HideCrsrs() +{ + if( !bHasFocus || bBasicHideCrsr ) + return; + + // ist Cursor sichtbar, dann verstecke den SV-Cursor + if( pVisCrsr->IsVisible() ) + { + SET_CURR_SHELL( this ); + pVisCrsr->Hide(); + } + // hebe die Invertierung der SSelection auf + SwShellCrsr* pAktCrsr = pTblCrsr ? pTblCrsr : pCurCrsr; + pAktCrsr->Hide(); +} + + + +void SwCrsrShell::ShowCrsrs( BOOL bCrsrVis ) +{ + if( !bHasFocus || bAllProtect || bBasicHideCrsr ) + return; + + SET_CURR_SHELL( this ); + SwShellCrsr* pAktCrsr = pTblCrsr ? pTblCrsr : pCurCrsr; + pAktCrsr->Show(); + + if( bSVCrsrVis && bCrsrVis ) // auch SV-Cursor wieder anzeigen + pVisCrsr->Show(); +} + +// Methoden zum Anzeigen bzw. Verstecken des sichtbaren Text-Cursors + + +void SwCrsrShell::ShowCrsr() +{ + if( !bBasicHideCrsr ) + { + bSVCrsrVis = TRUE; + UpdateCrsr(); + } +} + + +void SwCrsrShell::HideCrsr() +{ + if( !bBasicHideCrsr ) + { + bSVCrsrVis = FALSE; + // evt. die sel. Bereiche aufheben !! + SET_CURR_SHELL( this ); + pVisCrsr->Hide(); + } +} + + +void SwCrsrShell::ShLooseFcs() +{ + if( !bBasicHideCrsr ) + HideCrsrs(); + bHasFocus = FALSE; +} + + +void SwCrsrShell::ShGetFcs( BOOL bUpdate ) +{ + bHasFocus = TRUE; + if( !bBasicHideCrsr && VisArea().Width() ) + { + UpdateCrsr( bUpdate ? SwCrsrShell::CHKRANGE|SwCrsrShell::SCROLLWIN + : SwCrsrShell::CHKRANGE ); + ShowCrsrs( bSVCrsrVis ? TRUE : FALSE ); + } +} + +// gebe den aktuellen Frame, in dem der Cursor steht, zurueck + +#if 0 + +//MA 03. Nov. 95: Die letzten Anwender habe ich gerade aus wrtsh1.cxx entfernt. +// Weil's so kunstvoll aussieht lass ich die Funktion vorlauefig +// hier. + + +Rectangle SwCrsrShell::GetCurrFrmArea() const +{ + //Sitzt der Crsr ueberhaupt auf einem CntntNode? + SET_CURR_SHELL( (ViewShell*)this ); + Rectangle aRet; + SwCntntNode *pNd = GetNode().GetCntntNode(); + if ( pNd ) + { + const USHORT* pST = &nStartAction; + ++(*((USHORT*)pST)); + const Size aOldSz( GetLayout()->Frm().SSize() ); + SwCntntFrm *pFrm = pNd->GetFrm( + &pCurCrsr->GetPtPos(), pCurCrsr->GetPoint() ); + aRet = pFrm->Frm().SVRect(); + --(*((USHORT*)pST)); + if( aOldSz != GetLayout()->Frm().SSize() ) + ((SwCrsrShell*)this)->SizeChgNotify( GetLayout()->Frm().SSize() ); + } + return aRet; +} +#endif + + +SwCntntFrm *SwCrsrShell::GetCurrFrm( const BOOL bCalcFrm ) const +{ + SET_CURR_SHELL( (ViewShell*)this ); + SwCntntFrm *pRet = 0; + SwCntntNode *pNd = pCurCrsr->GetCntntNode(); + if ( pNd ) + { + if ( bCalcFrm ) + { + const USHORT* pST = &nStartAction; + ++(*((USHORT*)pST)); + const Size aOldSz( GetLayout()->Frm().SSize() ); + pRet = pNd->GetFrm( &pCurCrsr->GetPtPos(), pCurCrsr->GetPoint() ); + --(*((USHORT*)pST)); + if( aOldSz != GetLayout()->Frm().SSize() ) + ((SwCrsrShell*)this)->SizeChgNotify( GetLayout()->Frm().SSize() ); + } + else + pRet = pNd->GetFrm( &pCurCrsr->GetPtPos(), pCurCrsr->GetPoint(), FALSE); + } + return pRet; +} + + +// alle Attribut/Format-Aenderungen am akt. Node werden an den +// Link weitergeleitet. + + +void SwCrsrShell::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew ) +{ + USHORT nWhich = pOld ? pOld->Which() + : pNew ? pNew->Which() + : RES_MSG_BEGIN; + if( bCallChgLnk && + ( nWhich < RES_MSG_BEGIN || nWhich >= RES_MSG_END || + nWhich == RES_FMT_CHG || nWhich == RES_UPDATE_ATTR || + nWhich == RES_ATTRSET_CHG )) + // die Messages werden nicht weitergemeldet + //MA 07. Apr. 94 fix(6681): RES_UPDATE_ATTR wird implizit vom + //SwTxtNode::Insert(SwTxtHint*, USHORT) abgesetzt; hier wird reagiert und + //vom Insert brauch nicht mehr die Keule RES_FMT_CHG versandt werden. + CallChgLnk(); + + if( aGrfArrivedLnk.IsSet() && RES_GRAPHIC_ARRIVED == nWhich ) + aGrfArrivedLnk.Call( this ); +} + + +// Abfrage, ob der aktuelle Cursor eine Selektion aufspannt, +// also, ob GetMark gesetzt und SPoint und GetMark unterschiedlich sind. + + +FASTBOOL SwCrsrShell::HasSelection() +{ + SwPaM* pCrsr = IsTableMode() ? pTblCrsr : pCurCrsr; + return( IsTableMode() || ( pCurCrsr->HasMark() && + *pCurCrsr->GetPoint() != *pCrsr->GetMark()) + ? TRUE : FALSE ); +} + + +void SwCrsrShell::CallChgLnk() +{ + // innerhalb von Start-/End-Action kein Call, sondern nur merken, + // das sich etwas geaendert hat. Wird bei EndAction beachtet. + if( BasicActionPend() ) + bChgCallFlag = TRUE; // das Change merken + else if( aChgLnk.IsSet() ) + { + if( bCallChgLnk ) + aChgLnk.Call( this ); + bChgCallFlag = FALSE; // Flag zuruecksetzen + } +} + +// returne den am akt.Cursor selektierten Text eines Nodes. + + +String SwCrsrShell::GetSelTxt() const +{ + String aTxt; + if( pCurCrsr->GetPoint()->nNode.GetIndex() == + pCurCrsr->GetMark()->nNode.GetIndex() ) + { + SwTxtNode* pTxtNd = pCurCrsr->GetNode()->GetTxtNode(); + if( pTxtNd ) + { + xub_StrLen nStt = pCurCrsr->Start()->nContent.GetIndex(); + aTxt = pTxtNd->GetExpandTxt( nStt, + pCurCrsr->End()->nContent.GetIndex() - nStt ); + } + } + return aTxt; +} + +// gebe nur den Text ab der akt. Cursor Position zurueck (bis zum NodeEnde) + + +String SwCrsrShell::GetText() const +{ + String aTxt; + if( pCurCrsr->GetPoint()->nNode.GetIndex() == + pCurCrsr->GetMark()->nNode.GetIndex() ) + { + SwTxtNode* pTxtNd = pCurCrsr->GetNode()->GetTxtNode(); + if( pTxtNd ) + aTxt = pTxtNd->GetTxt().Copy( + pCurCrsr->GetPoint()->nContent.GetIndex() ); + } + return aTxt; +} + +// retrurne die Anzahl der selektierten Zeichen. +// Falls keine Selektion vorliegt entscheided nType was selektiert wird +// bIntrnlChar besagt ob interne Zeichen erhalten bleiben (TRUE) oder +// ob sie expandiert werden (z.B Felder/...) +ULONG SwCrsrShell::GetCharCount( USHORT nType, BOOL bIntrnlChrs ) const +{ + if( IsTableMode() ) + GetCrsr(); + + BOOL bPop = FALSE; + if( !pCurCrsr->HasMark() && pCurCrsr->GetNext() == pCurCrsr ) + { + // dann den Type auswerten, ansonsten ist ein Bereich vorhanden + bPop = TRUE; + SwCrsrShell* pThis = (SwCrsrShell*)this; + pThis->Push(); + switch( nType ) + { + case GETCHARCOUNT_PARA: // Absatz selektieren + { + SwCntntNode* pCNd = pCurCrsr->GetCntntNode(); + if( pCNd ) + { + pCurCrsr->SetMark(); + pCurCrsr->GetMark()->nContent.Assign( pCNd, 0 ); + pCurCrsr->GetPoint()->nContent.Assign( pCNd, pCNd->Len() ); + } + } + break; + + case GETCHARCOUNT_SECTION: // "Section" selektieren + { + pCurCrsr->SetMark(); + GoStartSection( pCurCrsr->GetMark() ); + GoEndSection( pCurCrsr->GetPoint() ); + } + break; + } + } + + USHORT nCrsrCnt = 0; + ULONG nCount = 0; + USHORT nLineOffset = /* Basic zaehlt CRLF als ein Zeichen + LINEEND_CRLF == GetSystemLineEnd() ? 2 : 1*/ 1; + + const SwPaM* pTmp = pCurCrsr; + do { + ++nCrsrCnt; + const SwPosition *pStt = pTmp->Start(), *pEnd = pTmp->End(); + if( *pStt < *pEnd ) + { + ULONG nSttNd = pStt->nNode.GetIndex(), + nEndNd = pEnd->nNode.GetIndex(); + xub_StrLen nSttCnt = pStt->nContent.GetIndex(), + nEndCnt = pEnd->nContent.GetIndex(); + + if( nSttNd != nEndNd ) + { + for( ; nSttNd < nEndNd; ++nSttNd, nSttCnt = 0 ) + { + const SwCntntNode* pCNd = pDoc->GetNodes()[ + nSttNd ]->GetCntntNode(); + if( pCNd ) + { + if( pCNd->IsTxtNode() && !bIntrnlChrs ) + nCount += ((SwTxtNode*)pCNd)->GetExpandTxt( + nSttCnt ).Len(); + else + nCount += pCNd->Len(); + + nCount += nLineOffset; + } + } + } + + if( bIntrnlChrs ) + nCount += nEndCnt - nSttCnt; + else + { + const SwTxtNode* pNd = pDoc->GetNodes()[ nEndNd ]->GetTxtNode(); + if( pNd ) + nCount += pNd->GetExpandTxt( nSttCnt, + nEndCnt - nSttCnt ).Len(); + } + } + } while( pCurCrsr != ( pTmp = (SwPaM*)pTmp->GetNext() ) ); + + // bei TabellenSelektion werden alle Boxen mit CR/LF abgeschlossen + if( IsTableMode() && 1 < nCrsrCnt ) + nCount += nCrsrCnt * nLineOffset; + + if( bPop ) + { + SwCrsrShell* pThis = (SwCrsrShell*)this; + pThis->Pop( FALSE ); + } + + return nCount; +} + + +// hole vom Start/Ende der akt. SSelection das nte Zeichen +sal_Unicode SwCrsrShell::GetChar( BOOL bEnd, long nOffset ) +{ + if( IsTableMode() ) // im TabelleMode nicht moeglich + return 0; + + const SwPosition* pPos = !pCurCrsr->HasMark() ? pCurCrsr->GetPoint() + : bEnd ? pCurCrsr->End() : pCurCrsr->Start(); + SwTxtNode* pTxtNd = pPos->nNode.GetNode().GetTxtNode(); + ASSERT( pTxtNd, "kein TextNode, wie soll ein char returnt werden?" ); + + xub_StrLen nPos = pPos->nContent.GetIndex(); + const String& rStr = pTxtNd->GetTxt(); + sal_Unicode cCh = 0; + + if( ((nPos+nOffset) >= 0 ) && (nPos+nOffset) < rStr.Len() ) + cCh = rStr.GetChar( nPos+nOffset ); + + return cCh; +} + +// erweiter die akt. SSelection am Anfang/Ende um n Zeichen + + +FASTBOOL SwCrsrShell::ExtendSelection( BOOL bEnd, xub_StrLen nCount ) +{ + if( !pCurCrsr->HasMark() || IsTableMode() ) + return FALSE; // keine Selektion + + SwPosition* pPos = bEnd ? pCurCrsr->End() : pCurCrsr->Start(); + SwTxtNode* pTxtNd = pPos->nNode.GetNode().GetTxtNode(); + ASSERT( pTxtNd, "kein TextNode, wie soll erweitert werden?" ); + + xub_StrLen nPos = pPos->nContent.GetIndex(); + if( bEnd ) + { + if( ( nPos + nCount ) <= pTxtNd->GetTxt().Len() ) + nPos += nCount; + else + return FALSE; // nicht mehr moeglich + } + else if( nPos >= nCount ) + nPos -= nCount; + else + return FALSE; // nicht mehr moeglich + + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, + + pPos->nContent = nPos; + UpdateCrsr(); + + return TRUE; +} + +// setze nur den sichtbaren Cursor an die angegebene Dokument-Pos. +// returnt FALSE: wenn der SPoint vom Layout korrigiert wurde. + +FASTBOOL SwCrsrShell::SetVisCrsr( const Point &rPt ) +{ + SET_CURR_SHELL( this ); + Point aPt( rPt ); + SwPosition aPos( *pCurCrsr->GetPoint() ); + SwCrsrMoveState aTmpState( MV_SETONLYTEXT ); + aTmpState.bSetInReadOnly = IsReadOnlyAvailable(); + aTmpState.bRealHeight = TRUE; + + FASTBOOL bRet = GetLayout()->GetCrsrOfst( &aPos, aPt /*, &aTmpState*/ ); + // nur in TextNodes anzeigen !! + SwTxtNode* pTxtNd = aPos.nNode.GetNode().GetTxtNode(); + if( !pTxtNd ) + return FALSE; + + const SwSectionNode* pSectNd = pTxtNd->FindSectionNode(); + if( pSectNd && (pSectNd->GetSection().IsHiddenFlag() || + ( !IsReadOnlyAvailable() && + pSectNd->GetSection().IsProtectFlag())) ) + return FALSE; + + SwCntntFrm *pFrm = pTxtNd->GetFrm( &aPt, &aPos ); + if ( Imp()->IsIdleAction() ) + pFrm->PrepareCrsr(); + SwRect aTmp( aCharRect ); + + + pFrm->GetCharRect( aCharRect, aPos, &aTmpState ); +// ALIGNRECT( aCharRect ); + + if( aTmp == aCharRect && // BUG 10137: bleibt der Cursor auf der + pVisCrsr->IsVisible() ) // Position nicht hidden & showen + return TRUE; + + pVisCrsr->Hide(); // sichtbaren Cursor immer verstecken + if( IsScrollMDI( this, aCharRect )) + { + MakeVisible( aCharRect ); + pCurCrsr->Show(); + } + + // Bug 29584: bei Rahmenselektion ist der Cursor versteckt, aber den + // D&D-Cursor will man trotzdem haben +// if( bSVCrsrVis ) + { + if( aTmpState.bRealHeight ) + aCrsrHeight = aTmpState.aRealHeight; + else + { + aCrsrHeight.X() = 0; + aCrsrHeight.Y() = aCharRect.Height(); + } + + pVisCrsr->SetDragCrsr( TRUE ); + pVisCrsr->Show(); // wieder anzeigen + } + return bRet; +} + +FASTBOOL SwCrsrShell::IsOverReadOnlyPos( const Point& rPt ) const +{ +// SET_CURR_SHELL( this ); + Point aPt( rPt ); + SwPaM aPam( *pCurCrsr->GetPoint() ); + FASTBOOL bRet = GetLayout()->GetCrsrOfst( aPam.GetPoint(), aPt ); + return aPam.HasReadonlySel(); +} + + + // returne die Anzahl der Cursor im Ring (Flag besagt ob man nur + // aufgepspannte haben will - sprich etwas selektiert ist (Basic)) +USHORT SwCrsrShell::GetCrsrCnt( BOOL bAll ) const +{ + Ring* pTmp = GetCrsr()->GetNext(); + USHORT n = (bAll || ( pCurCrsr->HasMark() && + *pCurCrsr->GetPoint() != *pCurCrsr->GetMark())) ? 1 : 0; + while( pTmp != pCurCrsr ) + { + if( bAll || ( ((SwPaM*)pTmp)->HasMark() && + *((SwPaM*)pTmp)->GetPoint() != *((SwPaM*)pTmp)->GetMark())) + ++n; + pTmp = pTmp->GetNext(); + } + return n; +} + + +FASTBOOL SwCrsrShell::IsStartOfDoc() const +{ + if( pCurCrsr->GetPoint()->nContent.GetIndex() ) + return FALSE; + + // Hinter EndOfIcons kommt die Content-Section (EndNd+StNd+CntntNd) + SwNodeIndex aIdx( GetDoc()->GetNodes().GetEndOfExtras(), 2 ); + if( !aIdx.GetNode().IsCntntNode() ) + GetDoc()->GetNodes().GoNext( &aIdx ); + return aIdx == pCurCrsr->GetPoint()->nNode; +} + + +FASTBOOL SwCrsrShell::IsEndOfDoc() const +{ + SwNodeIndex aIdx( GetDoc()->GetNodes().GetEndOfContent(), -1 ); + SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode(); + if( !pCNd ) + pCNd = GetDoc()->GetNodes().GoPrevious( &aIdx ); + + return aIdx == pCurCrsr->GetPoint()->nNode && + pCNd->Len() == pCurCrsr->GetPoint()->nContent.GetIndex(); +} + + +// loesche alle erzeugten Crsr, setze den Tabellen-Crsr und den letzten +// Cursor auf seinen TextNode (oder StartNode?). +// Beim naechsten ::GetCrsr werden sie wieder alle erzeugt +// Wird fuers Drag&Drop / ClipBorad-Paste in Tabellen benoetigt. +FASTBOOL SwCrsrShell::ParkTblCrsr() +{ + if( !pTblCrsr ) + return FALSE; + + pTblCrsr->ParkCrsr(); + + while( pCurCrsr->GetNext() != pCurCrsr ) + delete pCurCrsr->GetNext(); + + // vom Cursor !immer! SPoint und Mark umsetzen + pCurCrsr->SetMark(); + *pCurCrsr->GetMark() = *pCurCrsr->GetPoint() = *pTblCrsr->GetPoint(); + pCurCrsr->DeleteMark(); + + return TRUE; +} + +/*********************************************************************** +#* Class : SwCrsrShell +#* Methode : ParkCrsr +#* Beschreibung: Vernichtet Selektionen und zus. Crsr aller Shell der +#* verbleibende Crsr der Shell wird geparkt. +#* Datum : MA 05. Nov. 92 +#* Update : JP 19.09.97 +#***********************************************************************/ + +void SwCrsrShell::_ParkPams( SwPaM* pDelRg, SwShellCrsr** ppDelRing ) +{ + const SwPosition *pStt = pDelRg->Start(), + *pEnd = pDelRg->GetPoint() == pStt ? pDelRg->GetMark() : pDelRg->GetPoint(); + + SwPaM *pTmpDel = 0, *pTmp = *ppDelRing; + + // durchsuche den gesamten Ring + BOOL bGoNext; + do { + const SwPosition *pTmpStt = pTmp->Start(), + *pTmpEnd = pTmp->GetPoint() == pTmpStt ? + pTmp->GetMark() : pTmp->GetPoint(); + /* + * liegt ein SPoint oder GetMark innerhalb vom Crsr-Bereich + * muss der alte Bereich aufgehoben werden. + * Beim Vergleich ist darauf zu achten, das End() nicht mehr zum + * Bereich gehoert ! + */ + if( *pStt <= *pTmpStt ) + { + if( *pEnd > *pTmpStt || + ( *pEnd == *pTmpStt && *pEnd == *pTmpEnd )) + pTmpDel = pTmp; + } + else + if( *pStt < *pTmpEnd ) + pTmpDel = pTmp; + + bGoNext = TRUE; + if( pTmpDel ) // ist der Pam im Bereich ?? loesche ihn + { + BOOL bDelete = TRUE; + if( *ppDelRing == pTmpDel ) + { + if( *ppDelRing == pCurCrsr ) + { + if( TRUE == ( bDelete = GoNextCrsr() )) + { + bGoNext = FALSE; + pTmp = (SwPaM*)pTmp->GetNext(); + } + } + else + bDelete = FALSE; // StackCrsr nie loeschen !! + } + + if( bDelete ) + delete pTmpDel; // hebe alten Bereich auf + else + { + pTmpDel->GetPoint()->nContent.Assign( 0, 0 ); + pTmpDel->GetPoint()->nNode = 0; + pTmpDel->SetMark(); + pTmpDel->DeleteMark(); + } + pTmpDel = 0; + } + else if( !pTmp->HasMark() ) // sorge auf jedenfall dafuer, das + { // nicht benutzte Indizies beachtet werden! + pTmp->SetMark(); // SPoint liegt nicht im Bereich, + pTmp->DeleteMark(); // aber vielleicht GetMark, also setzen + } + if( bGoNext ) + pTmp = (SwPaM*)pTmp->GetNext(); + } while( !bGoNext || *ppDelRing != pTmp ); +} + +void SwCrsrShell::ParkCrsr( const SwNodeIndex &rIdx ) +{ + SwNode *pNode = &rIdx.GetNode(); + + // erzeuge einen neuen Pam + SwPaM * pNew = new SwPaM( *GetCrsr()->GetPoint() ); + if( pNode->GetStartNode() ) + { + if( ( pNode = pNode->StartOfSectionNode())->IsTableNode() ) + { + // der angegebene Node steht in einer Tabelle, also Parke + // den Crsr auf dem Tabellen-Node (ausserhalb der Tabelle) + pNew->GetPoint()->nNode = *pNode->StartOfSectionNode(); + } + else // also auf dem StartNode selbst. + // Dann immer ueber seinen EndNode den StartNode erfragen !!! + // (StartOfSection vom StartNode ist der Parent !) + pNew->GetPoint()->nNode = *pNode->EndOfSectionNode()->StartOfSectionNode(); + } + else + pNew->GetPoint()->nNode = *pNode->StartOfSectionNode(); + pNew->SetMark(); + pNew->GetPoint()->nNode = *pNode->EndOfSectionNode(); + + //Alle Shells wollen etwas davon haben. + ViewShell *pTmp = this; + do { + if( pTmp->IsA( TYPE( SwCrsrShell ))) + { + SwCrsrShell* pSh = (SwCrsrShell*)pTmp; + if( pSh->pCrsrStk ) + pSh->_ParkPams( pNew, &pSh->pCrsrStk ); + + pSh->_ParkPams( pNew, &pSh->pCurCrsr ); + if( pSh->pTblCrsr ) + { + // setze den Tabellen Cursor immer auf 0, den aktuellen + // immer auf den Anfang der Tabelle + SwPaM* pTCrsr = pSh->GetTblCrs(); + SwNode* pTblNd = pTCrsr->GetPoint()->nNode.GetNode().FindTableNode(); + if ( pTblNd ) + { + pTCrsr->GetPoint()->nContent.Assign( 0, 0 ); + pTCrsr->GetPoint()->nNode = 0; + pTCrsr->SetMark(); + pTCrsr->DeleteMark(); + pSh->pCurCrsr->GetPoint()->nNode = *pTblNd; + } + } + } + } while ( this != (pTmp = (ViewShell*)pTmp->GetNext() )); + delete pNew; +} + +//========================================================================= + +/* + * der Copy-Constructor + * Cursor-Position kopieren, in den Ring eingetragen. + * Alle Ansichten eines Dokumentes stehen im Ring der Shells. + */ + +SwCrsrShell::SwCrsrShell( SwCrsrShell * pShell, Window *pWin ) + : ViewShell( pShell, pWin ), + SwModify( 0 ) +{ + SET_CURR_SHELL( this ); + // Nur die Position vom aktuellen Cursor aus der Copy-Shell uebernehmen + pCurCrsr = new SwShellCrsr( *this, *(pShell->pCurCrsr->GetPoint()) ); + pCurCrsr->GetCntntNode()->Add( this ); + pCrsrStk = 0; + pTblCrsr = 0; + + nBasicActionCnt = 0; + + pBoxIdx = 0; + pBoxPtr = 0; + + /* + * setze die initiale Spalten-Position fuer Up / Down + */ + nCrsrMove = 0; + bAllProtect = bVisPortChgd = bChgCallFlag = bInCMvVisportChgd = + bGCAttr = bIgnoreReadonly = bSelTblCells = bBasicHideCrsr = FALSE; + bCallChgLnk = bHasFocus = bSVCrsrVis = bAutoUpdateCells = TRUE; + bSetCrsrInReadOnly = TRUE; + eMvState = MV_NONE; // Status fuers Crsr-Travelling - GetCrsrOfst + pVisCrsr = new SwVisCrsr( this ); +// UpdateCrsr( 0 ); +} + + +/* + * der normale Constructor + */ + +SwCrsrShell::SwCrsrShell( SwDoc *pDoc, + uno::Reference< linguistic::XSpellChecker1> xSpell, + uno::Reference< linguistic::XHyphenator> xHyph, + Window *pWin, SwRootFrm *pRoot, const SwViewOption *pOpt ) + : ViewShell( pDoc, xSpell, xHyph, pWin, pOpt ), + SwModify( 0 ) +{ + SET_CURR_SHELL( this ); + /* + * Erzeugen des initialen Cursors, wird auf die erste + * Inhaltsposition gesetzt + */ + SwNodes& rNds = pDoc->GetNodes(); + + SwNodeIndex aNodeIdx( *rNds.GetEndOfContent().StartOfSectionNode() ); + SwCntntNode* pCNd = rNds.GoNext( &aNodeIdx ); // gehe zum 1. ContentNode + + pCurCrsr = new SwShellCrsr( *this, SwPosition( aNodeIdx, SwIndex( pCNd, 0 ))); + pCrsrStk = 0; + pTblCrsr = 0; + + nBasicActionCnt = 0; + + pBoxIdx = 0; + pBoxPtr = 0; + + // melde die Shell beim akt. Node als abhaengig an, dadurch koennen alle + // Attribut-Aenderungen ueber den Link weiter gemeldet werden. + pCNd->Add( this ); + + /* + * setze die initiale Spalten-Position fuer Up / Down + */ + nCrsrMove = 0; + bAllProtect = bVisPortChgd = bChgCallFlag = bInCMvVisportChgd = + bGCAttr = bIgnoreReadonly = bSelTblCells = bBasicHideCrsr = FALSE; + bCallChgLnk = bHasFocus = bSVCrsrVis = bAutoUpdateCells = TRUE; + bSetCrsrInReadOnly = TRUE; + eMvState = MV_NONE; // Status fuers Crsr-Travelling - GetCrsrOfst + + pVisCrsr = new SwVisCrsr( this ); +// UpdateCrsr( 0 ); +} + + + +SwCrsrShell::~SwCrsrShell() +{ + // wenn es nicht die letzte View so sollte zu mindest das + // Feld noch geupdatet werden. + if( GetNext() != this ) + CheckTblBoxCntnt( pCurCrsr->GetPoint() ); + else + ClearTblBoxCntnt(); + + delete pVisCrsr; + delete pTblCrsr; + + /* + * Freigabe der Cursor + */ + while(pCurCrsr->GetNext() != pCurCrsr) + delete pCurCrsr->GetNext(); + delete pCurCrsr; + + // Stack freigeben + if( pCrsrStk ) + { + while( pCrsrStk->GetNext() != pCrsrStk ) + delete pCrsrStk->GetNext(); + delete pCrsrStk; + } + + // JP 27.07.98: Bug 54025 - ggfs. den HTML-Parser, der als Client in + // der CursorShell haengt keine Chance geben, sich an den + // TextNode zu haengen. + if( GetRegisteredIn() ) + pRegisteredIn->Remove( this ); +} + + + +//Sollte fuer das Clipboard der WaitPtr geschaltet werden? +//Warten bei TableMode, Mehrfachselektion und mehr als x Selektieren Absaetzen. + +FASTBOOL SwCrsrShell::ShouldWait() const +{ + if ( IsTableMode() || GetCrsrCnt() > 1 ) + return TRUE; + + if( HasDrawView() && GetDrawView()->GetMarkList().GetMarkCount() ) + return TRUE; + + SwPaM* pPam = GetCrsr(); + return pPam->Start()->nNode.GetIndex() + 10 < + pPam->End()->nNode.GetIndex(); +} + + +USHORT SwCrsrShell::UpdateTblSelBoxes() +{ + if( pTblCrsr && ( pTblCrsr->IsChgd() || !pTblCrsr->GetBoxesCount() )) + GetLayout()->MakeTblCrsrs( *pTblCrsr ); + return pTblCrsr ? pTblCrsr->GetBoxesCount() : 0; +} + + +// steht der Curor auf einem "Symbol"-Zeichen +FASTBOOL SwCrsrShell::IsInSymbolFont() const +{ + if( IsTableMode() ) + return FALSE; + + SwPosition* pPos = GetCrsr()->GetPoint(); + SwTxtNode* pTNd = pPos->nNode.GetNode().GetTxtNode(); + if( pTNd ) + return pTNd->IsInSymbolFont( pPos->nContent.GetIndex() ); + return FALSE; +} + + +// zeige das akt. selektierte "Object" an +void SwCrsrShell::MakeSelVisible() +{ + ASSERT( bHasFocus, "kein Focus aber Cursor sichtbar machen?" ); + if( aCrsrHeight.Y() < aCharRect.Height() && aCharRect.Height() > VisArea().Height() ) + { + SwRect aTmp( aCharRect ); + long nDiff = aCharRect.Height() - VisArea().Height(); + if( nDiff < aCrsrHeight.X() ) + aTmp.Top( nDiff + aCharRect.Top() ); + else + { + aTmp.Top( aCrsrHeight.X() + aCharRect.Top() ); + aTmp.Height( aCrsrHeight.Y() ); + } + MakeVisible( aTmp ); + } + else + { + if( aCharRect.HasArea() ) + MakeVisible( aCharRect ); + else + { + SwRect aTmp( aCharRect ); + aTmp.SSize().Height() += 1; aTmp.SSize().Width() += 1; + MakeVisible( aTmp ); + } + } +} + + +// suche eine gueltige ContentPosition (nicht geschuetzt/nicht versteckt) +FASTBOOL SwCrsrShell::FindValidCntntNode( BOOL bOnlyText ) +{ + if( pTblCrsr ) // was soll ich jetzt machen ?? + { + ASSERT( !this, "TabellenSelection nicht aufgehoben!" ); + return FALSE; + } + + //JP 28.10.97: Bug 45129 - im UI-ReadOnly ist alles erlaubt + if( !bAllProtect && GetDoc()->GetDocShell() && + GetDoc()->GetDocShell()->IsReadOnlyUI() ) + return TRUE; + + // dann raus da! + if( pCurCrsr->HasMark() ) + ClearMark(); + + // als erstes mal auf Rahmen abpruefen + SwNodeIndex& rNdIdx = pCurCrsr->GetPoint()->nNode; + ULONG nNdIdx = rNdIdx.GetIndex(); // sichern + SwNodes& rNds = pDoc->GetNodes(); + SwCntntNode* pCNd = rNdIdx.GetNode().GetCntntNode(); + const SwCntntFrm * pFrm; + + if( pCNd && 0 != (pFrm = pCNd->GetFrm(0,pCurCrsr->GetPoint(),FALSE)) && + !IsReadOnlyAvailable() && pFrm->IsProtected() && + nNdIdx < rNds.GetEndOfExtras().GetIndex() ) + { + // geschuetzter Rahmen ueberspringen + SwPaM aPam( *pCurCrsr->GetPoint() ); + aPam.SetMark(); + aPam.GetMark()->nNode = rNds.GetEndOfContent(); + aPam.GetPoint()->nNode = *pCNd->EndOfSectionNode(); + + FASTBOOL bFirst = FALSE; + if( 0 == (pCNd = ::GetNode( aPam, bFirst, fnMoveForward, FALSE ))) + { + aPam.GetMark()->nNode = *rNds.GetEndOfPostIts().StartOfSectionNode(); + pCNd = ::GetNode( aPam, bFirst, fnMoveBackward, FALSE ); + } + + if( !pCNd ) // sollte nie passieren !!! + { + rNdIdx = nNdIdx; // alten Node zurueck + return FALSE; + } + *pCurCrsr->GetPoint() = *aPam.GetPoint(); + } + else if( bOnlyText && pCNd && pCNd->IsNoTxtNode() ) + { + // dann auf den Anfang vom Doc stellen + rNdIdx = pDoc->GetNodes().GetEndOfExtras(); + pCurCrsr->GetPoint()->nContent.Assign( pDoc->GetNodes().GoNext( + &rNdIdx ), 0 ); + nNdIdx = rNdIdx.GetIndex(); + } + + BOOL bOk = TRUE; + + // was ist mit Tabelle? + + // in einem geschuetzten Bereich + const SwSectionNode* pSectNd = rNdIdx.GetNode().FindSectionNode(); + if( pSectNd && ( pSectNd->GetSection().IsHiddenFlag() || + ( !IsReadOnlyAvailable() && + pSectNd->GetSection().IsProtectFlag() )) ) + { + typedef SwCntntNode* (SwNodes:: *FNGoSection)( SwNodeIndex *, int, int ) const; + FNGoSection fnGoSection = &SwNodes::GoNextSection; + + bOk = FALSE; + + for( int nLoopCnt = 0; !bOk && nLoopCnt < 2; ++nLoopCnt ) + { + BOOL bWeiter; + do { + bWeiter = FALSE; + while( 0 != ( pCNd = (rNds.*fnGoSection)( &rNdIdx, + TRUE, !IsReadOnlyAvailable() )) ) + { + // in eine Tabelle verschoben -> pruefe ob die + // vielleicht geschuetzt ist + if( pCNd->FindTableNode() ) + { + SwCallLink aTmp( *this ); + SwCrsrSaveState aSaveState( *pCurCrsr ); + aTmp.nNdTyp = 0; // im DTOR nichts machen! + if( !pCurCrsr->IsInProtectTable( TRUE, TRUE ) ) + { + const SwSectionNode* pSNd = pCNd->FindSectionNode(); + if( !pSNd || !pSNd->GetSection().IsHiddenFlag() + || (!IsReadOnlyAvailable() && + pSNd->GetSection().IsProtectFlag() )) + { + bOk = TRUE; + break; // eine nicht geschuetzte Zelle gef. + } + continue; // dann weiter suchen + } + } + else + { + bOk = TRUE; + break; // eine nicht geschuetzte Zelle gef. + } + } + + if( bOk && rNdIdx.GetIndex() < rNds.GetEndOfExtras().GetIndex() ) + { + // Teste mal auf Fly - kann auch noch geschuetzt sein!! + if( 0 == (pFrm = pCNd->GetFrm(0,0,FALSE)) || + ( !IsReadOnlyAvailable() && pFrm->IsProtected() ) || + ( bOnlyText && pCNd->IsNoTxtNode() ) ) + { + // dann weiter suchen! + bOk = FALSE; + bWeiter = TRUE; + } + } + } while( bWeiter ); + + if( !bOk ) + { + if( !nLoopCnt ) + fnGoSection = &SwNodes::GoPrevSection; + rNdIdx = nNdIdx; + } + } + } + if( bOk ) + { + pCNd = rNdIdx.GetNode().GetCntntNode(); +// USHORT nCntnt = Min( pCNd->Len(), pCurCrsr->GetPoint()->nContent.GetIndex() ); + xub_StrLen nCntnt = rNdIdx.GetIndex() < nNdIdx ? pCNd->Len() : 0; + pCurCrsr->GetPoint()->nContent.Assign( pCNd, nCntnt ); + } + else + { + pCNd = rNdIdx.GetNode().GetCntntNode(); + + // falls Cursor im versteckten Bereich ist, auf jedenfall schon mal + // verschieben!! + if( !pCNd || !pCNd->GetFrm(0,0,FALSE) ) + { + SwCrsrMoveState aTmpState( MV_NONE ); + aTmpState.bSetInReadOnly = IsReadOnlyAvailable(); + GetLayout()->GetCrsrOfst( pCurCrsr->GetPoint(), pCurCrsr->GetPtPos(), + &aTmpState ); + } + } + return bOk; +} + + +void SwCrsrShell::NewCoreSelection() +{ +} + + +FASTBOOL SwCrsrShell::IsCrsrReadonly() const +{ + if ( GetViewOptions()->IsReadonly() ) + { + SwFrm *pFrm = GetCurrFrm( FALSE ); + SwFlyFrm *pFly; + if( pFrm && pFrm->IsInFly() && + (pFly = pFrm->FindFlyFrm())->GetFmt()->GetEditInReadonly().GetValue() && + pFly->Lower() && + !pFly->Lower()->IsNoTxtFrm() && + !GetDrawView()->GetMarkList().GetMarkCount() ) + { + return FALSE; + } + return TRUE; + } + return FALSE; +} + + +// darf der Cursor in ReadOnlyBereiche? +void SwCrsrShell::SetReadOnlyAvailable( BOOL bFlag ) +{ + // im GlobalDoc darf NIE umgeschaltet werden + if( (!GetDoc()->GetDocShell() || + !GetDoc()->GetDocShell()->IsA( SwGlobalDocShell::StaticType() )) && + bFlag != bSetCrsrInReadOnly ) + { + // wenn das Flag ausgeschaltet wird, dann muessen erstmal alle + // Selektionen aufgehoben werden. Denn sonst wird sich darauf + // verlassen, das nichts geschuetztes selektiert ist! + if( !bFlag ) + { + ClearMark(); + } + bSetCrsrInReadOnly = bFlag; + UpdateCrsr(); + } +} + +FASTBOOL SwCrsrShell::HasReadonlySel() const +{ + FASTBOOL bRet = FALSE; + if( IsReadOnlyAvailable() ) + { + if( pTblCrsr ) + bRet = pTblCrsr->HasReadOnlyBoxSel() || + pTblCrsr->HasReadonlySel(); + else + { + const SwPaM* pCrsr = pCurCrsr; + + do { + if( pCrsr->HasReadonlySel() ) + bRet = TRUE; + } while( !bRet && pCurCrsr != ( pCrsr = (SwPaM*)pCrsr->GetNext() )); + } + } + return bRet; +} + +// SwCursor - Methode !!!! +FASTBOOL SwCursor::IsReadOnlyAvailable() const +{ + const SwShellCrsr* pShCrsr = *this; + const SwUnoCrsr* pUnoCrsr = *this; + return pShCrsr ? pShCrsr->GetShell()->IsReadOnlyAvailable() : + pUnoCrsr ? TRUE : FALSE; +} + + +FASTBOOL SwCrsrShell::IsSelFullPara() const +{ + FASTBOOL bRet = FALSE; + + if( pCurCrsr->GetPoint()->nNode.GetIndex() == + pCurCrsr->GetMark()->nNode.GetIndex() && pCurCrsr == pCurCrsr->GetNext() ) + { + xub_StrLen nStt = pCurCrsr->GetPoint()->nContent.GetIndex(), + nEnd = pCurCrsr->GetMark()->nContent.GetIndex(); + if( nStt > nEnd ) + { + xub_StrLen nTmp = nStt; + nStt = nEnd; + nEnd = nTmp; + } + const SwCntntNode* pCNd = pCurCrsr->GetCntntNode(); + bRet = pCNd && !nStt && nEnd == pCNd->Len(); + } + return bRet; +} + +/* */ + + // die Suchfunktionen +ULONG SwCrsrShell::Find( const SearchParam& rParam, + SwDocPositions eStart, SwDocPositions eEnde, + FindRanges eRng, int bReplace ) +{ + if( pTblCrsr ) + GetCrsr(); + delete pTblCrsr, pTblCrsr = 0; + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + ULONG nRet = pCurCrsr->Find( rParam, eStart, eEnde, eRng, bReplace ); + if( nRet ) + UpdateCrsr(); + return nRet; +} + +ULONG SwCrsrShell::Find( const SwTxtFmtColl& rFmtColl, + SwDocPositions eStart, SwDocPositions eEnde, + FindRanges eRng, const SwTxtFmtColl* pReplFmt ) +{ + if( pTblCrsr ) + GetCrsr(); + delete pTblCrsr, pTblCrsr = 0; + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + ULONG nRet = pCurCrsr->Find( rFmtColl, eStart, eEnde, eRng, pReplFmt ); + if( nRet ) + UpdateCrsr(); + return nRet; +} + +ULONG SwCrsrShell::Find( const SfxItemSet& rSet, FASTBOOL bNoCollections, + SwDocPositions eStart, SwDocPositions eEnde, + FindRanges eRng, const SearchParam* pTextPara, + const SfxItemSet* rReplSet ) +{ + if( pTblCrsr ) + GetCrsr(); + delete pTblCrsr, pTblCrsr = 0; + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + ULONG nRet = pCurCrsr->Find( rSet, bNoCollections, eStart, eEnde, + eRng, pTextPara, rReplSet ); + if( nRet ) + UpdateCrsr(); + return nRet; +} + +void SwCrsrShell::SetSelection( const SwPaM& rCrsr ) +{ + StartAction(); + BOOL bFirst = TRUE; + SwPaM* pCrsr = GetCrsr(); + *pCrsr->GetPoint() = *rCrsr.GetPoint(); + if(rCrsr.HasMark()) + { + pCrsr->SetMark(); + *pCrsr->GetMark() = *rCrsr.GetMark(); + } + if((SwPaM*)rCrsr.GetNext() != &rCrsr) + { + const SwPaM *_pStartCrsr = (SwPaM*)rCrsr.GetNext(), *__pStartCrsr = _pStartCrsr; + do + { + SwPaM* pCurCrsr = CreateCrsr(); + *pCurCrsr->GetPoint() = *_pStartCrsr->GetPoint(); + if(_pStartCrsr->HasMark()) + { + pCurCrsr->SetMark(); + *pCurCrsr->GetMark() = *_pStartCrsr->GetMark(); + } + } while( (_pStartCrsr=(SwPaM *)_pStartCrsr->GetNext()) != &rCrsr ); + } + EndAction(); +} + +/* */ + +#if !defined(PRODUCT) || defined(WIN) + +void SwCrsrShell::SetMark() +{ + pCurCrsr->SetMark(); +} + +FASTBOOL SwCrsrShell::HasMark() +{ + return pCurCrsr->HasMark(); +} + +SwCursor* SwCrsrShell::GetSwCrsr( FASTBOOL bMakeTblCrsr ) const +{ + return (SwCursor*)GetCrsr( bMakeTblCrsr ); +} + +// gebe den Stack Cursor zurueck +SwPaM * SwCrsrShell::GetStkCrsr() const { return pCrsrStk; } + +// gebe den TabellenCrsr zurueck +const SwPaM* SwCrsrShell::GetTblCrs() const { return pTblCrsr; } + SwPaM* SwCrsrShell::GetTblCrs() { return pTblCrsr; } + +// Abfrage, ob ueberhaupt eine Selektion existiert, sprich der akt. Cursor +// aufgespannt oder nicht der einzigste ist. + +FASTBOOL SwCrsrShell::IsSelection() const +{ + return IsTableMode() || pCurCrsr->HasMark() || + pCurCrsr->GetNext() != pCurCrsr; +} + +// pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen +const SwTableNode* SwCrsrShell::IsCrsrInTbl( BOOL bIsPtInTbl ) const +{ + return pCurCrsr->GetNode( bIsPtInTbl )->FindTableNode(); +} + + +FASTBOOL SwCrsrShell::IsCrsrPtAtEnd() const +{ + return pCurCrsr->End() == pCurCrsr->GetPoint(); +} + + +Point& SwCrsrShell::GetCrsrDocPos( BOOL bPoint ) const +{ + return bPoint ? pCurCrsr->GetPtPos() : pCurCrsr->GetMkPos(); +} + + +void SwCrsrShell::UnSetVisCrsr() +{ + pVisCrsr->Hide(); + pVisCrsr->SetDragCrsr( FALSE ); +} + + +FASTBOOL SwCrsrShell::IsSelOnePara() const +{ + return pCurCrsr == pCurCrsr->GetNext() && + pCurCrsr->GetPoint()->nNode == + pCurCrsr->GetMark()->nNode; +} + +SwMoveFnCollection* SwCrsrShell::MakeFindRange( + USHORT nStt, USHORT nEnd, SwPaM* pPam ) const +{ + return pCurCrsr->MakeFindRange( (SwDocPositions)nStt, + (SwDocPositions)nEnd, pPam ); +} + +#endif + + + + diff --git a/sw/source/core/crsr/crstrvl.cxx b/sw/source/core/crsr/crstrvl.cxx new file mode 100644 index 000000000000..2d3a56fe263c --- /dev/null +++ b/sw/source/core/crsr/crstrvl.cxx @@ -0,0 +1,1999 @@ +/************************************************************************* + * + * $RCSfile: crstrvl.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:17 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _HINTIDS_HXX +#include +#endif + +#ifndef _SFXITEMITER_HXX //autogen +#include +#endif +#ifndef _SVX_LRSPITEM_HXX //autogen +#include +#endif +#ifndef _SVX_ADJITEM_HXX //autogen +#include +#endif +#ifndef _SVX_BRKITEM_HXX //autogen +#include +#endif + +#ifndef _CRSRSH_HXX +#include +#endif +#ifndef _DOC_HXX +#include +#endif +#ifndef _PAGEFRM_HXX +#include +#endif +#ifndef _CNTFRM_HXX +#include +#endif +#ifndef _ROOTFRM_HXX +#include +#endif +#ifndef _PAM_HXX +#include +#endif +#ifndef _NDTXT_HXX +#include +#endif +#ifndef _FLDBAS_HXX +#include +#endif +#ifndef _HINTS_HXX +#include // SwTxtFld +#endif +#ifndef _SWTABLE_HXX +#include // SwTxtFld +#endif +#ifndef _DOCARY_HXX +#include +#endif +#ifndef _TXTFLD_HXX //autogen +#include +#endif +#ifndef _FMTFLD_HXX //autogen +#include +#endif +#ifndef _TXTFTN_HXX //autogen +#include +#endif +#ifndef _TXTINET_HXX //autogen +#include +#endif +#ifndef _FMTINFMT_HXX //autogen +#include +#endif +#ifndef _TXTTXMRK_HXX //autogen +#include +#endif +#ifndef _FRMFMT_HXX //autogen +#include +#endif +#ifndef _VISCRS_HXX +#include +#endif +#ifndef _CALLNK_HXX +#include +#endif +#ifndef _DOCTXM_HXX +#include +#endif +#ifndef _DOCFLD_HXX +#include +#endif +#ifndef _EXPFLD_HXX +#include +#endif +#ifndef _REFFLD_HXX +#include +#endif +#ifndef _FLDDAT_HXX +#include // SwTxtFld +#endif +#ifndef _CELLATR_HXX +#include +#endif +#ifndef _SWUNDO_HXX +#include +#endif +#ifndef _REDLINE_HXX +#include +#endif +#ifndef _FMTCNTNT_HXX //autogen +#include +#endif +#ifndef _FMTHDFT_HXX //autogen +#include +#endif +#ifndef _PAGEDESC_HXX //autogen +#include +#endif + + +// zum naechsten/vorhergehenden Punkt auf gleicher Ebene +FASTBOOL SwCrsrShell::GotoNextNum() +{ + FASTBOOL bRet = GetDoc()->GotoNextNum( *pCurCrsr->GetPoint() ); + if( bRet ) + { + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, + SwCrsrSaveState aSaveState( *pCurCrsr ); + if( !ActionPend() ) + { + SET_CURR_SHELL( this ); + // dann versuche den Cursor auf die Position zu setzen, + // auf halber Heohe vom Char-SRectangle + Point aPt( pCurCrsr->GetPtPos() ); + SwCntntFrm * pFrm = pCurCrsr->GetCntntNode()->GetFrm( &aPt, + pCurCrsr->GetPoint() ); + pFrm->GetCharRect( aCharRect, *pCurCrsr->GetPoint() ); + aPt.Y() = aCharRect.Center().Y(); + pFrm->Calc(); + aPt.X() = pFrm->Frm().Left() + nUpDownX; + pFrm->GetCrsrOfst( pCurCrsr->GetPoint(), aPt ); + bRet = !pCurCrsr->IsSelOvr( SELOVER_TOGGLE | SELOVER_CHANGEPOS ); + if( bRet ) + UpdateCrsr(SwCrsrShell::UPDOWN | + SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE | + SwCrsrShell::READONLY ); + } + } + return bRet; +} + + +FASTBOOL SwCrsrShell::GotoPrevNum() +{ + FASTBOOL bRet = GetDoc()->GotoPrevNum( *pCurCrsr->GetPoint() ); + if( bRet ) + { + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, + SwCrsrSaveState aSaveState( *pCurCrsr ); + if( !ActionPend() ) + { + SET_CURR_SHELL( this ); + // dann versuche den Cursor auf die Position zu setzen, + // auf halber Heohe vom Char-SRectangle + Point aPt( pCurCrsr->GetPtPos() ); + SwCntntFrm * pFrm = pCurCrsr->GetCntntNode()->GetFrm( &aPt, + pCurCrsr->GetPoint() ); + pFrm->GetCharRect( aCharRect, *pCurCrsr->GetPoint() ); + aPt.Y() = aCharRect.Center().Y(); + pFrm->Calc(); + aPt.X() = pFrm->Frm().Left() + nUpDownX; + pFrm->GetCrsrOfst( pCurCrsr->GetPoint(), aPt ); + bRet = !pCurCrsr->IsSelOvr( SELOVER_TOGGLE | SELOVER_CHANGEPOS ); + if( bRet ) + UpdateCrsr(SwCrsrShell::UPDOWN | + SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE | + SwCrsrShell::READONLY ); + } + } + return bRet; +} + +// springe aus dem Content zum Header + +FASTBOOL SwCrsrShell::GotoHeaderTxt() +{ + const SwFrm* pFrm = GetCurrFrm()->FindPageFrm(); + while( pFrm && !pFrm->IsHeaderFrm() ) + pFrm = pFrm->GetLower(); + // Header gefunden, dann suche den 1.Cntnt-Frame + while( pFrm && !pFrm->IsCntntFrm() ) + pFrm = pFrm->GetLower(); + if( pFrm ) + { + SET_CURR_SHELL( this ); + // hole den Header-Frame + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, + SwCrsrSaveState aSaveState( *pCurCrsr ); + pFrm->Calc(); + Point aPt( pFrm->Frm().Pos() + pFrm->Prt().Pos() ); + pFrm->GetCrsrOfst( pCurCrsr->GetPoint(), aPt ); + if( !pCurCrsr->IsSelOvr() ) + { +#ifdef USED + // wenn wir immer auf der akt. Seite bleiben wollen, dann benutzen. + // zur Zeit immer zur naechst gelegene !! + // diese Seite, diese Fusszeile !! + // diese Seite, diese Kopfzeile !! + pCurCrsr->GetPtPos() = aPt; +#endif + UpdateCrsr(); + } + else + pFrm = 0; + } + return 0 != pFrm; +} + + +// springe aus dem Content zum Footer + +FASTBOOL SwCrsrShell::GotoFooterTxt() +{ + const SwPageFrm* pFrm = GetCurrFrm()->FindPageFrm(); + if( pFrm ) + { + const SwFrm * pLower = pFrm->GetLower(); + while( pLower->GetNext() ) + pLower = pLower->GetNext(); + + while( pLower && !pLower->IsFooterFrm() ) + pLower = pLower->GetLower(); + // Header gefunden, dann suche den 1.Cntnt-Frame + while( pLower && !pLower->IsCntntFrm() ) + pLower = pLower->GetLower(); + + if( pLower ) + { + SET_CURR_SHELL( this ); + // hole eine Position im Footer + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, + SwCrsrSaveState aSaveState( *pCurCrsr ); + pLower->Calc(); + Point aPt( pLower->Frm().Pos() + pLower->Prt().Pos() ); + pLower->GetCrsrOfst( pCurCrsr->GetPoint(), aPt ); + if( !pCurCrsr->IsSelOvr() ) + { +#ifdef USED + // wenn wir immer auf der akt. Seite bleiben wollen, dann benutzen. + // zur Zeit immer zur naechst gelegene !! + // diese Seite, diese Fusszeile !! + pCurCrsr->GetPtPos() = aPt; +#endif + UpdateCrsr(); + } + else + pFrm = 0; + } + else + pFrm = 0; + } + else + pFrm = 0; + return 0 != pFrm; +} + +FASTBOOL SwCrsrShell::SetCrsrInHdFt( USHORT nDescNo, FASTBOOL bInHeader ) +{ + FASTBOOL bRet = FALSE; + SwDoc *pDoc = GetDoc(); + + SET_CURR_SHELL( this ); + + if( USHRT_MAX == nDescNo ) + { + // dann den akt. nehmen + const SwPageFrm* pPage = GetCurrFrm()->FindPageFrm(); + if( pPage ) + for( USHORT i = 0; i < pDoc->GetPageDescCnt(); ++i ) + if( pPage->GetPageDesc() == &pDoc->GetPageDesc( i ) ) + { + nDescNo = i; + break; + } + } + + if( USHRT_MAX != nDescNo && nDescNo < pDoc->GetPageDescCnt() ) + { + //dann teste mal, ob ueberhaupt das Attribut vorhanden ist. + const SwPageDesc& rDesc = pDoc->GetPageDesc( nDescNo ); + const SwFmtCntnt* pCnt = 0; + if( bInHeader ) + { + // gespiegelte Seiten??? erstmal nicht beachten + const SwFmtHeader& rHd = rDesc.GetMaster().GetHeader(); + if( rHd.GetHeaderFmt() ) + pCnt = &rHd.GetHeaderFmt()->GetCntnt(); + } + else + { + const SwFmtFooter& rFt = rDesc.GetMaster().GetFooter(); + if( rFt.GetFooterFmt() ) + pCnt = &rFt.GetFooterFmt()->GetCntnt(); + } + + if( pCnt && pCnt->GetCntntIdx() ) + { + SwNodeIndex aIdx( *pCnt->GetCntntIdx(), 1 ); + SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode(); + if( !pCNd ) + pCNd = pDoc->GetNodes().GoNext( &aIdx ); + + const SwFrm* pFrm; + Point aPt( pCurCrsr->GetPtPos() ); + + if( pCNd && 0 != ( pFrm = pCNd->GetFrm( &aPt, 0, FALSE ) )) + { + // dann kann der Cursor ja auch hinein gesetzt werden + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + SwCrsrSaveState aSaveState( *pCurCrsr ); + + ClearMark(); + + SwPosition& rPos = *pCurCrsr->GetPoint(); + rPos.nNode = *pCNd; + rPos.nContent.Assign( pCNd, 0 ); + + bRet = !pCurCrsr->IsSelOvr(); + if( bRet ) + UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE | + SwCrsrShell::READONLY ); + } + } + } + return bRet; +} + +// springe zum naechsten Verzeichnis + +FASTBOOL SwCrsrShell::GotoNextTOXBase( const String* pName ) +{ + FASTBOOL bRet = FALSE; + + const SwSectionFmts& rFmts = GetDoc()->GetSections(); + SwCntntNode* pFnd = 0; + for( USHORT n = rFmts.Count(); n; ) + { + const SwSection* pSect = rFmts[ --n ]->GetSection(); + const SwSectionNode* pSectNd; + if( TOX_CONTENT_SECTION == pSect->GetType() && + 0 != ( pSectNd = pSect->GetFmt()->GetSectionNode() ) && + pCurCrsr->GetPoint()->nNode < pSectNd->GetIndex() && + ( !pFnd || pFnd->GetIndex() > pSectNd->GetIndex() ) && +// JP 10.12.96: solange wir nur 3 Typen kennen und UI-seitig keine anderen +// einstellbar sind, muss ueber den Titel gesucht werden! +// ( !pName || *pName == ((SwTOXBaseSection*)pSect)->GetTypeName() ) && + ( !pName || *pName == ((SwTOXBaseSection*)pSect)->GetTOXName() ) + ) + { + SwNodeIndex aIdx( *pSectNd, 1 ); + SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode(); + if( !pCNd ) + pCNd = GetDoc()->GetNodes().GoNext( &aIdx ); + const SwCntntFrm* pCFrm; + if( pCNd && + pCNd->EndOfSectionIndex() <= pSectNd->EndOfSectionIndex() && + 0 != ( pCFrm = pCNd->GetFrm() ) && + ( IsReadOnlyAvailable() || !pCFrm->IsProtected() )) + { + pFnd = pCNd; + } + } + } + if( pFnd ) + { + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, + SwCrsrSaveState aSaveState( *pCurCrsr ); + pCurCrsr->GetPoint()->nNode = *pFnd; + pCurCrsr->GetPoint()->nContent.Assign( pFnd, 0 ); + bRet = !pCurCrsr->IsSelOvr(); + if( bRet ) + UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); + } + return bRet; +} + +// springe zum vorherigen Verzeichnis + + +FASTBOOL SwCrsrShell::GotoPrevTOXBase( const String* pName ) +{ + FASTBOOL bRet = FALSE; + + const SwSectionFmts& rFmts = GetDoc()->GetSections(); + SwCntntNode* pFnd = 0; + for( USHORT n = rFmts.Count(); n; ) + { + const SwSection* pSect = rFmts[ --n ]->GetSection(); + const SwSectionNode* pSectNd; + if( TOX_CONTENT_SECTION == pSect->GetType() && + 0 != ( pSectNd = pSect->GetFmt()->GetSectionNode() ) && + pCurCrsr->GetPoint()->nNode > pSectNd->EndOfSectionIndex() && + ( !pFnd || pFnd->GetIndex() < pSectNd->GetIndex() ) && +// JP 10.12.96: solange wir nur 3 Typen kennen und UI-seitig keine anderen +// einstellbar sind, muss ueber den Titel gesucht werden! +// ( !pName || *pName == ((SwTOXBaseSection*)pSect)->GetTypeName() ) && + ( !pName || *pName == ((SwTOXBaseSection*)pSect)->GetTOXName() ) + ) + { + SwNodeIndex aIdx( *pSectNd, 1 ); + SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode(); + if( !pCNd ) + pCNd = GetDoc()->GetNodes().GoNext( &aIdx ); + const SwCntntFrm* pCFrm; + if( pCNd && + pCNd->EndOfSectionIndex() <= pSectNd->EndOfSectionIndex() && + 0 != ( pCFrm = pCNd->GetFrm() ) && + ( IsReadOnlyAvailable() || !pCFrm->IsProtected() )) + { + pFnd = pCNd; + } + } + } + + if( pFnd ) + { + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, + SwCrsrSaveState aSaveState( *pCurCrsr ); + pCurCrsr->GetPoint()->nNode = *pFnd; + pCurCrsr->GetPoint()->nContent.Assign( pFnd, 0 ); + bRet = !pCurCrsr->IsSelOvr(); + if( bRet ) + UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); + } + return bRet; +} + +// springe zum Verzeichnis vom TOXMark + +FASTBOOL SwCrsrShell::GotoTOXMarkBase() +{ + FASTBOOL bRet = FALSE; + + SwTOXMarks aMarks; + USHORT nCnt = GetDoc()->GetCurTOXMark( *pCurCrsr->GetPoint(), aMarks ); + if( nCnt ) + { + // dann nehme den 1. und hole den Verzeichnis-Typ. + // Suche in seiner Abhaengigkeitsliste nach dem eigentlichem + // Verzeichnis + SwModify* pType = (SwModify*)aMarks[0]->GetRegisteredIn(); + SwClientIter aIter( *pType ); + const SwSectionNode* pSectNd; + const SwSectionFmt* pSectFmt; + + for( SwTOXBase* pTOX = + (SwTOXBase*)aIter.First( TYPE( SwTOXBase )); + pTOX; pTOX = (SwTOXBase*)aIter.Next() ) + if( pTOX->ISA( SwTOXBaseSection ) && + 0 != ( pSectFmt = ((SwTOXBaseSection*)pTOX)->GetFmt() ) && + 0 != ( pSectNd = pSectFmt->GetSectionNode() )) + { + SwNodeIndex aIdx( *pSectNd, 1 ); + SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode(); + if( !pCNd ) + pCNd = GetDoc()->GetNodes().GoNext( &aIdx ); + const SwCntntFrm* pCFrm; + if( pCNd && + pCNd->EndOfSectionIndex() < pSectNd->EndOfSectionIndex() && + 0 != ( pCFrm = pCNd->GetFrm() ) && + ( IsReadOnlyAvailable() || !pCFrm->IsProtected() )) + { + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, + SwCrsrSaveState aSaveState( *pCurCrsr ); + pCurCrsr->GetPoint()->nNode = *pCNd; + pCurCrsr->GetPoint()->nContent.Assign( pCNd, 0 ); + bRet = !pCurCrsr->IsInProtectTable() && + !pCurCrsr->IsSelOvr(); + if( bRet ) + UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); + break; + } + } + } + return bRet; +} + + + // springe zur naechsten (vorherigen) Tabellenformel + // optional auch nur zu kaputten Formeln springen +FASTBOOL SwCrsrShell::GotoNxtPrvTblFormula( BOOL bNext, BOOL bOnlyErrors ) +{ + if( IsTableMode() ) + return FALSE; + + FASTBOOL bFnd = FALSE; + SwPosition& rPos = *pCurCrsr->GetPoint(); + + Point aPt; + SwPosition aFndPos( GetDoc()->GetNodes().GetEndOfContent() ); + if( !bNext ) + aFndPos.nNode = 0; + _SetGetExpFld aFndGEF( aFndPos ), aCurGEF( rPos ); + + { + const SwNode* pSttNd = rPos.nNode.GetNode().FindTableBoxStartNode(); + if( pSttNd ) + { + const SwTableBox* pTBox = pSttNd->FindTableNode()->GetTable(). + GetTblBox( pSttNd->GetIndex() ); + if( pTBox ) + aCurGEF = _SetGetExpFld( *pTBox ); + } + } + + if( rPos.nNode < GetDoc()->GetNodes().GetEndOfExtras() ) + // auch beim Einsammeln wird nur der erste Frame benutzt! + aCurGEF.SetBodyPos( *rPos.nNode.GetNode().GetCntntNode()->GetFrm( + &aPt, &rPos, FALSE ) ); + + { + const SfxPoolItem* pItem; + const SwTableBox* pTBox; + USHORT n, nMaxItems = GetDoc()->GetAttrPool().GetItemCount( RES_BOXATR_FORMULA ); + + for( n = 0; n < nMaxItems; ++n ) + if( 0 != (pItem = GetDoc()->GetAttrPool().GetItem( + RES_BOXATR_FORMULA, n ) ) && + 0 != (pTBox = ((SwTblBoxFormula*)pItem)->GetTableBox() ) && + pTBox->GetSttNd() && + pTBox->GetSttNd()->GetNodes().IsDocNodes() && + ( !bOnlyErrors || + !((SwTblBoxFormula*)pItem)->HasValidBoxes() ) ) + { + const SwCntntFrm* pCFrm; + SwNodeIndex aIdx( *pTBox->GetSttNd() ); + const SwCntntNode* pCNd = GetDoc()->GetNodes().GoNext( &aIdx ); + if( pCNd && 0 != ( pCFrm = pCNd->GetFrm( &aPt, 0, FALSE ) ) && + (IsReadOnlyAvailable() || !pCFrm->IsProtected() )) + { + _SetGetExpFld aCmp( *pTBox ); + aCmp.SetBodyPos( *pCFrm ); + + if( bNext ? ( aCurGEF < aCmp && aCmp < aFndGEF ) + : ( aCmp < aCurGEF && aFndGEF < aCmp )) + { + aFndGEF = aCmp; + bFnd = TRUE; + } + } + } + } + + if( bFnd ) + { + SET_CURR_SHELL( this ); + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + SwCrsrSaveState aSaveState( *pCurCrsr ); + + aFndGEF.GetPosOfContent( rPos ); + pCurCrsr->DeleteMark(); + + bFnd = !pCurCrsr->IsSelOvr(); + if( bFnd ) + UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE | + SwCrsrShell::READONLY ); + } + return bFnd; +} + +// springe zum naechsten (vorherigen) Verzeichniseintrag +FASTBOOL SwCrsrShell::GotoNxtPrvTOXMark( BOOL bNext ) +{ + if( IsTableMode() ) + return FALSE; + + FASTBOOL bFnd = FALSE; + SwPosition& rPos = *pCurCrsr->GetPoint(); + + Point aPt; + SwPosition aFndPos( GetDoc()->GetNodes().GetEndOfContent() ); + if( !bNext ) + aFndPos.nNode = 0; + _SetGetExpFld aFndGEF( aFndPos ), aCurGEF( rPos ); + + if( rPos.nNode.GetIndex() < GetDoc()->GetNodes().GetEndOfExtras().GetIndex() ) + // auch beim Einsammeln wird nur der erste Frame benutzt! + aCurGEF.SetBodyPos( *rPos.nNode.GetNode(). + GetCntntNode()->GetFrm( &aPt, &rPos, FALSE ) ); + + { + const SfxPoolItem* pItem; + const SwCntntFrm* pCFrm; + const SwTxtNode* pTxtNd; + const SwTxtTOXMark* pTxtTOX; + USHORT n, nMaxItems = GetDoc()->GetAttrPool().GetItemCount( RES_TXTATR_TOXMARK ); + + for( n = 0; n < nMaxItems; ++n ) + if( 0 != (pItem = GetDoc()->GetAttrPool().GetItem( + RES_TXTATR_TOXMARK, n ) ) && + 0 != (pTxtTOX = ((SwTOXMark*)pItem)->GetTxtTOXMark() ) && + ( pTxtNd = &pTxtTOX->GetTxtNode())->GetNodes().IsDocNodes() && + 0 != ( pCFrm = pTxtNd->GetFrm( &aPt, 0, FALSE )) && + ( IsReadOnlyAvailable() || !pCFrm->IsProtected() )) + { + SwNodeIndex aNdIndex( *pTxtNd ); // UNIX benoetigt dieses Obj. + _SetGetExpFld aCmp( aNdIndex, *pTxtTOX, 0 ); + aCmp.SetBodyPos( *pCFrm ); + + if( bNext ? ( aCurGEF < aCmp && aCmp < aFndGEF ) + : ( aCmp < aCurGEF && aFndGEF < aCmp )) + { + aFndGEF = aCmp; + bFnd = TRUE; + } + } + } + + if( bFnd ) + { + SET_CURR_SHELL( this ); + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + SwCrsrSaveState aSaveState( *pCurCrsr ); + + aFndGEF.GetPosOfContent( rPos ); + + bFnd = !pCurCrsr->IsSelOvr(); + if( bFnd ) + UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE | + SwCrsrShell::READONLY ); + } + return bFnd; +} + +/*-------------------------------------------------------------------- + Beschreibung: Traveling zwischen Markierungen + --------------------------------------------------------------------*/ + +const SwTOXMark& SwCrsrShell::GotoTOXMark( const SwTOXMark& rStart, + SwTOXSearch eDir ) +{ + SET_CURR_SHELL( this ); + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + SwCrsrSaveState aSaveState( *pCurCrsr ); + + const SwTOXMark& rNewMark = GetDoc()->GotoTOXMark( rStart, eDir, + IsReadOnlyAvailable() ); + // Position setzen + SwPosition& rPos = *GetCrsr()->GetPoint(); + rPos.nNode = rNewMark.GetTxtTOXMark()->GetTxtNode(); + rPos.nContent.Assign( rPos.nNode.GetNode().GetCntntNode(), + *rNewMark.GetTxtTOXMark()->GetStart() ); + + if( !pCurCrsr->IsSelOvr() ) + UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE | + SwCrsrShell::READONLY ); + + return rNewMark; +} + +// springe zum naechsten / vorherigen FeldTypen + +void lcl_MakeFldLst( _SetGetExpFlds& rLst, const SwFieldType& rFldType, + USHORT nSubType, BOOL bInReadOnly, + BOOL bChkInpFlag = FALSE ) +{ + // es muss immer der 1. Frame gesucht werden + Point aPt; + SwTxtFld* pTxtFld; + SwClientIter aIter( (SwFieldType&)rFldType ); + BOOL bSubType = nSubType != USHRT_MAX; + for( SwClient* pLast = aIter.First( TYPE( SwFmtFld )); pLast; pLast = aIter.Next() ) + if( 0 != ( pTxtFld = ((SwFmtFld*)pLast)->GetTxtFld() ) && + ( !bChkInpFlag || ((SwSetExpField*)pTxtFld->GetFld().GetFld()) + ->GetInputFlag() ) && + (!bSubType || (((SwFmtFld*)pLast)->GetFld()->GetSubType() + & 0xff ) == nSubType )) + { + SwCntntFrm* pCFrm; + const SwTxtNode& rTxtNode = pTxtFld->GetTxtNode(); + if( 0 != ( pCFrm = rTxtNode.GetFrm( &aPt, 0, FALSE )) && + ( bInReadOnly || !pCFrm->IsProtected() )) + { + _SetGetExpFld* pNew = new _SetGetExpFld( + SwNodeIndex( rTxtNode ), pTxtFld ); + pNew->SetBodyPos( *pCFrm ); + rLst.Insert( pNew ); + } + } +} + + +FASTBOOL SwCrsrShell::MoveFldType( const SwFieldType* pFldType, BOOL bNext, + USHORT nSubType, USHORT nResType ) +{ + // sortierte Liste aller Felder + _SetGetExpFlds aSrtLst( 64 ); + + if (pFldType) + { + if( RES_INPUTFLD != pFldType->Which() && !pFldType->GetDepends() ) + return FALSE; + + // Modify-Object gefunden, trage alle Felder ins Array ein + ::lcl_MakeFldLst( aSrtLst, *pFldType, nSubType, IsReadOnlyAvailable() ); + + if( RES_INPUTFLD == pFldType->Which() ) + { + // es gibt noch versteckte InputFelder in den SetExp. Feldern + const SwFldTypes& rFldTypes = *pDoc->GetFldTypes(); + const USHORT nSize = rFldTypes.Count(); + + // Alle Typen abklappern + for( USHORT i=0; i < nSize; ++i ) + if( RES_SETEXPFLD == ( pFldType = rFldTypes[ i ] )->Which() ) + ::lcl_MakeFldLst( aSrtLst, *pFldType, nSubType, + IsReadOnlyAvailable(), TRUE ); + } + } + else + { + const SwFldTypes& rFldTypes = *pDoc->GetFldTypes(); + const USHORT nSize = rFldTypes.Count(); + + // Alle Typen abklappern + for( USHORT i=0; i < nSize; ++i ) + if( nResType == ( pFldType = rFldTypes[ i ] )->Which() ) + ::lcl_MakeFldLst( aSrtLst, *pFldType, nSubType, + IsReadOnlyAvailable() ); + } + + // keine Felder gefunden? + if( !aSrtLst.Count() ) + return FALSE; + + USHORT nPos; + SwCursor* pCrsr = IsTableMode() ? pTblCrsr : pCurCrsr; + { + // JP 19.08.98: es muss immer ueber das Feld gesucht werden, damit + // auch immer das richtige gefunden wird, wenn welche in + // Rahmen stehen, die in einem Absatz verankert sind, + // in dem ein Feld steht - siehe auch Bug 55247 + const SwPosition& rPos = *pCrsr->GetPoint(); + + SwTxtNode* pTNd = rPos.nNode.GetNode().GetTxtNode(); + ASSERT( pTNd, "Wo ist mein CntntNode?" ); + + SwTxtFld* pTxtFld = (SwTxtFld*)pTNd->GetTxtAttr( rPos.nContent, + RES_TXTATR_FIELD ); + BOOL bDelFld = 0 == pTxtFld; + if( bDelFld ) + { + SwFmtFld* pFmtFld = new SwFmtFld( SwDateTimeField( + (SwDateTimeFieldType*)pDoc->GetSysFldType( RES_DATETIMEFLD ) ) ); + + pTxtFld = new SwTxtFld( *pFmtFld, rPos.nContent.GetIndex() ); + pTxtFld->ChgTxtNode( pTNd ); + } + + _SetGetExpFld aSrch( rPos.nNode, pTxtFld, &rPos.nContent ); + if( rPos.nNode.GetIndex() < pDoc->GetNodes().GetEndOfExtras().GetIndex() ) + { + // auch beim Einsammeln wird nur der erste Frame benutzt! + Point aPt; + aSrch.SetBodyPos( *pTNd->GetFrm( &aPt, &rPos, FALSE ) ); + } + + BOOL bFound = aSrtLst.Seek_Entry( &aSrch, &nPos ); + if( bDelFld ) + { + delete (SwFmtFld*)&pTxtFld->GetAttr(); + delete pTxtFld; + } + + if( bFound ) // stehe auf einem ? + { + if( bNext ) + { + if( ++nPos >= aSrtLst.Count() ) + return FALSE; // schon am Ende + } + else if( !nPos-- ) + return FALSE; // weiter nach vorne geht nicht + } + else if( bNext ? nPos >= aSrtLst.Count() : !nPos--) + return FALSE; + } + const _SetGetExpFld& rFnd = **( aSrtLst.GetData() + nPos ); + + + SET_CURR_SHELL( this ); + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + SwCrsrSaveState aSaveState( *pCrsr ); + + rFnd.GetPosOfContent( *pCrsr->GetPoint() ); + + FASTBOOL bRet = !pCurCrsr->IsSelOvr(); + if( bRet ) + UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); + return bRet; +} + + +FASTBOOL SwCrsrShell::GotoFld( const SwFmtFld& rFld ) +{ + FASTBOOL bRet = FALSE; + if( rFld.GetTxtFld() ) + { + SET_CURR_SHELL( this ); + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + + SwCursor* pCrsr = IsTableMode() ? pTblCrsr : pCurCrsr; + SwCrsrSaveState aSaveState( *pCrsr ); + + SwTxtNode* pTNd = (SwTxtNode*)rFld.GetTxtFld()->GetpTxtNode(); + pCrsr->GetPoint()->nNode = *pTNd; + pCrsr->GetPoint()->nContent.Assign( pTNd, *rFld.GetTxtFld()->GetStart() ); + + bRet = !pCrsr->IsSelOvr(); + if( bRet ) + UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); + } + return bRet; +} + + +void SwCrsrShell::GotoOutline( USHORT nIdx ) +{ + SwCursor* pCrsr = IsTableMode() ? pTblCrsr : pCurCrsr; + + SET_CURR_SHELL( this ); + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + SwCrsrSaveState aSaveState( *pCrsr ); + + const SwNodes& rNds = GetDoc()->GetNodes(); + SwTxtNode* pTxtNd = (SwTxtNode*)rNds.GetOutLineNds()[ nIdx ]->GetTxtNode(); + pCrsr->GetPoint()->nNode = *pTxtNd; + pCrsr->GetPoint()->nContent.Assign( pTxtNd, 0 ); + + if( !pCrsr->IsSelOvr() ) + UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); +} + + +FASTBOOL SwCrsrShell::GotoOutline( const String& rName ) +{ + SwCursor* pCrsr = IsTableMode() ? pTblCrsr : pCurCrsr; + + SET_CURR_SHELL( this ); + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + SwCrsrSaveState aSaveState( *pCrsr ); + + FASTBOOL bRet = FALSE; + if( pDoc->GotoOutline( *pCrsr->GetPoint(), rName ) && !pCrsr->IsSelOvr() ) + { + UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); + bRet = TRUE; + } + return bRet; +} + + + +FASTBOOL SwCrsrShell::GotoNextOutline() // naechster Node mit Outline-Num. +{ + SwCursor* pCrsr = IsTableMode() ? pTblCrsr : pCurCrsr; + const SwNodes& rNds = GetDoc()->GetNodes(); + + SwNode* pNd = pCrsr->GetNode(); + USHORT nPos; + if( rNds.GetOutLineNds().Seek_Entry( pNd, &nPos )) + ++nPos; + + if( nPos == rNds.GetOutLineNds().Count() ) + return FALSE; + + pNd = rNds.GetOutLineNds()[ nPos ]; + + SET_CURR_SHELL( this ); + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + SwCrsrSaveState aSaveState( *pCrsr ); + pCrsr->GetPoint()->nNode = *pNd; + pCrsr->GetPoint()->nContent.Assign( (SwTxtNode*)pNd, 0 ); + + FASTBOOL bRet = !pCrsr->IsSelOvr(); + if( bRet ) + UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); + return bRet; +} + + +FASTBOOL SwCrsrShell::GotoPrevOutline() // vorheriger Node mit Outline-Num. +{ + SwCursor* pCrsr = IsTableMode() ? pTblCrsr : pCurCrsr; + const SwNodes& rNds = GetDoc()->GetNodes(); + + SwNode* pNd = pCrsr->GetNode(); + USHORT nPos; + rNds.GetOutLineNds().Seek_Entry( pNd, &nPos ); + + FASTBOOL bRet = FALSE; + if( nPos ) + { + --nPos; // davor + + pNd = rNds.GetOutLineNds()[ nPos ]; + if( pNd->GetIndex() > pCrsr->GetPoint()->nNode.GetIndex() ) + return FALSE; + + SET_CURR_SHELL( this ); + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + SwCrsrSaveState aSaveState( *pCrsr ); + pCrsr->GetPoint()->nNode = *pNd; + pCrsr->GetPoint()->nContent.Assign( (SwTxtNode*)pNd, 0 ); + + bRet = !pCrsr->IsSelOvr(); + if( bRet ) + UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); + } + return bRet; +} + + + // suche die "Outline-Position" vom vorherigen Outline-Node mit dem + // Level. +USHORT SwCrsrShell::GetOutlinePos( BYTE nLevel ) +{ + SwPaM* pCrsr = IsTableMode() ? pTblCrsr : pCurCrsr; + const SwNodes& rNds = GetDoc()->GetNodes(); + + SwNode* pNd = pCrsr->GetNode(); + USHORT nPos; + if( rNds.GetOutLineNds().Seek_Entry( pNd, &nPos )) + nPos++; // steht auf der Position, fuers while zum Naechsten + + while( nPos-- ) // immer den davor testen ! + { + pNd = rNds.GetOutLineNds()[ nPos ]; + if( ((SwTxtNode*)pNd)->GetTxtColl()->GetOutlineLevel() <= nLevel ) + return nPos; + } + return USHRT_MAX; // davor keiner mehr also Ende +} + + +FASTBOOL SwCrsrShell::MakeOutlineSel( USHORT nSttPos, USHORT nEndPos, + BOOL bWithChilds ) +{ + const SwNodes& rNds = GetDoc()->GetNodes(); + const SwOutlineNodes& rOutlNds = rNds.GetOutLineNds(); + if( !rOutlNds.Count() ) // wie jetzt ??? + return FALSE; + + SET_CURR_SHELL( this ); + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + + if( nSttPos > nEndPos ) // sollte jemand das vertauscht haben? + { + ASSERT( !this, "Start- > Ende-Position im Array" ); + USHORT nTmp = nSttPos; + nSttPos = nEndPos; + nEndPos = nTmp; + } + + SwNode* pSttNd = rOutlNds[ nSttPos ]; + SwNode* pEndNd = rOutlNds[ nEndPos ]; + + if( bWithChilds ) + { + BYTE nLevel = pEndNd->GetTxtNode()->GetTxtColl()->GetOutlineLevel(); + for( ++nEndPos; nEndPos < rOutlNds.Count(); ++nEndPos ) + { + pEndNd = rOutlNds[ nEndPos ]; + BYTE nNxtLevel = pEndNd->GetTxtNode()->GetTxtColl()->GetOutlineLevel(); + if( nNxtLevel <= nLevel ) + break; // EndPos steht jetzt auf dem naechsten + } + } + // ohne Childs, dann aber zumindest auf den naechsten + else if( ++nEndPos < rOutlNds.Count() ) + pEndNd = rOutlNds[ nEndPos ]; + + if( nEndPos == rOutlNds.Count() ) // kein Ende gefunden + pEndNd = &rNds.GetEndOfContent(); + + KillPams(); + + SwCrsrSaveState aSaveState( *pCurCrsr ); + + // Jetzt das Ende ans Ende vom voherigen ContentNode setzen + pCurCrsr->GetPoint()->nNode = *pSttNd; + pCurCrsr->GetPoint()->nContent.Assign( pSttNd->GetCntntNode(), 0 ); + pCurCrsr->SetMark(); + pCurCrsr->GetPoint()->nNode = *pEndNd; + pCurCrsr->Move( fnMoveBackward, fnGoNode ); // ans Ende vom Vorgaenger + + // und schon ist alles selektiert + FASTBOOL bRet = !pCurCrsr->IsSelOvr(); + if( bRet ) + UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); + return bRet; +} + + +// springe zu dieser Refmark +FASTBOOL SwCrsrShell::GotoRefMark( const String& rRefMark, USHORT nSubType, + USHORT nSeqNo ) +{ + SET_CURR_SHELL( this ); + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + SwCrsrSaveState aSaveState( *pCurCrsr ); + + USHORT nPos; + SwTxtNode* pTxtNd = SwGetRefFieldType::FindAnchor( GetDoc(), rRefMark, + nSubType, nSeqNo, &nPos ); + if( pTxtNd ) + { + pCurCrsr->GetPoint()->nNode = *pTxtNd; + pCurCrsr->GetPoint()->nContent.Assign( pTxtNd, nPos ); + + if( !pCurCrsr->IsSelOvr() ) + { + UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); + return TRUE; + } + } + return FALSE; +} + + +FASTBOOL SwCrsrShell::GetContentAtPos( const Point& rPt, + SwContentAtPos& rCntntAtPos, + FASTBOOL bSetCrsr, + SwRect* pFldRect ) +{ + SET_CURR_SHELL( this ); + FASTBOOL bRet = FALSE; + + if( !IsTableMode() ) + { + Point aPt( rPt ); + SwPosition aPos( *pCurCrsr->GetPoint() ); + + SwTxtNode* pTxtNd; + SwCntntFrm *pFrm; + SwTxtAttr* pTxtAttr; + SwCrsrMoveState aTmpState; + aTmpState.bFieldInfo = TRUE; + aTmpState.bExactOnly = !( SwContentAtPos::SW_OUTLINE & + rCntntAtPos.eCntntAtPos ); + aTmpState.bSetInReadOnly = IsReadOnlyAvailable(); + + BOOL bCrsrFoundExact = GetLayout()->GetCrsrOfst( &aPos, aPt, &aTmpState ); + pTxtNd = aPos.nNode.GetNode().GetTxtNode(); + + const SwNodes& rNds = GetDoc()->GetNodes(); + if( pTxtNd && SwContentAtPos::SW_OUTLINE & rCntntAtPos.eCntntAtPos + && rNds.GetOutLineNds().Count() ) + { + const SwTxtNode* pONd = pTxtNd->FindOutlineNodeOfLevel( MAXLEVEL-1); + if( pONd ) + { + rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_OUTLINE; + rCntntAtPos.sStr = pONd->GetExpandTxt( 0, STRING_LEN, TRUE ); + bRet = TRUE; + } + } + else if( bCrsrFoundExact && pTxtNd ) + { + if( !aTmpState.bPosCorr ) + { + if( ( SwContentAtPos::SW_FIELD | SwContentAtPos::SW_CLICKFIELD ) + & rCntntAtPos.eCntntAtPos && !aTmpState.bFtnNoInfo ) + { + pTxtAttr = pTxtNd->GetTxtAttr( aPos.nContent.GetIndex(), + RES_TXTATR_FIELD ); + const SwField* pFld = pTxtAttr + ? pTxtAttr->GetFld().GetFld() + : 0; + if( SwContentAtPos::SW_CLICKFIELD & rCntntAtPos.eCntntAtPos && + pFld && !pFld->HasClickHdl() ) + pFld = 0; + + if( pFld ) + { + if( pFldRect && 0 != ( pFrm = pTxtNd->GetFrm( &aPt ) ) ) + pFrm->GetCharRect( *pFldRect, aPos, &aTmpState ); + + if( bSetCrsr ) + { + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + SwCrsrSaveState aSaveState( *pCurCrsr ); + pCurCrsr->DeleteMark(); + *pCurCrsr->GetPoint() = aPos; + if( pCurCrsr->IsSelOvr() ) + { + // Click-Felder in geschuetzten Bereichen zulassen + // Nur Platzhalter geht nicht! + if( SwContentAtPos::SW_FIELD & rCntntAtPos.eCntntAtPos + || RES_JUMPEDITFLD == pFld->Which() ) + pFld = 0; + } + else + UpdateCrsr(); + } + else if( RES_TABLEFLD == pFld->Which() && + ((SwTblField*)pFld)->IsIntrnlName() ) + { + // erzeuge aus der internen (fuer CORE) + // die externe (fuer UI) Formel + const SwTableNode* pTblNd = pTxtNd->FindTableNode(); + if( pTblNd ) // steht in einer Tabelle + ((SwTblField*)pFld)->PtrToBoxNm( &pTblNd->GetTable() ); + } + } + + if( pFld ) + { + rCntntAtPos.aFnd.pFld = pFld; + rCntntAtPos.pFndTxtAttr = pTxtAttr; + rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_FIELD; + bRet = TRUE; + } + } + + if( !bRet && SwContentAtPos::SW_FTN & rCntntAtPos.eCntntAtPos ) + { + if( aTmpState.bFtnNoInfo ) + { + // stehe ueber dem Zeichen der Fussnote (??) + bRet = TRUE; + if( bSetCrsr ) + { + *pCurCrsr->GetPoint() = aPos; + if( !GotoFtnAnchor() ) + bRet = FALSE; + } + if( bRet ) + rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_FTN; + } + else if( 0 != ( pTxtAttr = pTxtNd->GetTxtAttr( + aPos.nContent.GetIndex(), RES_TXTATR_FTN )) ) + { + bRet = TRUE; + if( bSetCrsr ) + { + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, + SwCrsrSaveState aSaveState( *pCurCrsr ); + pCurCrsr->GetPoint()->nNode = *((SwTxtFtn*)pTxtAttr)->GetStartNode(); + SwCntntNode* pCNd = GetDoc()->GetNodes().GoNextSection( + &pCurCrsr->GetPoint()->nNode, + TRUE, !IsReadOnlyAvailable() ); + + if( pCNd ) + { + pCurCrsr->GetPoint()->nContent.Assign( pCNd, 0 ); + if( pCurCrsr->IsSelOvr( SELOVER_CHECKNODESSECTION | + SELOVER_TOGGLE )) + bRet = FALSE; + else + UpdateCrsr(); + } + else + bRet = FALSE; + } + + if( bRet ) + { + rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_FTN; + rCntntAtPos.pFndTxtAttr = pTxtAttr; + rCntntAtPos.aFnd.pAttr = &pTxtAttr->GetAttr(); + + if( pFldRect && 0 != ( pFrm = pTxtNd->GetFrm( &aPt ) ) ) + pFrm->GetCharRect( *pFldRect, aPos, &aTmpState ); + } + } + } + + if( !bRet && ( SwContentAtPos::SW_TOXMARK | + SwContentAtPos::SW_REFMARK ) & + rCntntAtPos.eCntntAtPos && !aTmpState.bFtnNoInfo ) + { + pTxtAttr = 0; + if( SwContentAtPos::SW_TOXMARK & rCntntAtPos.eCntntAtPos ) + pTxtAttr = pTxtNd->GetTxtAttr( aPos.nContent, + RES_TXTATR_TOXMARK ); + + if( !pTxtAttr && + SwContentAtPos::SW_REFMARK & rCntntAtPos.eCntntAtPos ) + pTxtAttr = pTxtNd->GetTxtAttr( aPos.nContent, + RES_TXTATR_REFMARK ); + + if( pTxtAttr ) + { + bRet = TRUE; + if( bSetCrsr ) + { + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, + SwCrsrSaveState aSaveState( *pCurCrsr ); + pCurCrsr->DeleteMark(); + *pCurCrsr->GetPoint() = aPos; + if( pCurCrsr->IsSelOvr( SELOVER_CHECKNODESSECTION | SELOVER_TOGGLE ) ) + bRet = FALSE; + else + UpdateCrsr(); + } + + if( bRet ) + { + const xub_StrLen* pEnd = pTxtAttr->GetEnd(); + if( pEnd ) + rCntntAtPos.sStr = pTxtNd->GetExpandTxt( + *pTxtAttr->GetStart(), + *pEnd - *pTxtAttr->GetStart(), + FALSE ); + else if( RES_TXTATR_TOXMARK == pTxtAttr->Which()) + rCntntAtPos.sStr = pTxtAttr->GetTOXMark(). + GetAlternativeText(); + + rCntntAtPos.eCntntAtPos = + RES_TXTATR_TOXMARK == pTxtAttr->Which() + ? SwContentAtPos::SW_TOXMARK + : SwContentAtPos::SW_REFMARK; + rCntntAtPos.pFndTxtAttr = pTxtAttr; + rCntntAtPos.aFnd.pAttr = &pTxtAttr->GetAttr(); + + if( pFldRect && 0 != ( pFrm = pTxtNd->GetFrm( &aPt ) ) ) + pFrm->GetCharRect( *pFldRect, aPos, &aTmpState ); + } + } + } + + if( !bRet && SwContentAtPos::SW_INETATTR & rCntntAtPos.eCntntAtPos + && !aTmpState.bFtnNoInfo ) + { + pTxtAttr = pTxtNd->GetTxtAttr( aPos.nContent, + RES_TXTATR_INETFMT ); + // nur INetAttrs mit URLs "erkennen" + if( pTxtAttr && pTxtAttr->GetINetFmt().GetValue().Len() ) + { + bRet = TRUE; + if( bSetCrsr ) + { + SwCrsrSaveState aSaveState( *pCurCrsr ); + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + pCurCrsr->DeleteMark(); + *pCurCrsr->GetPoint() = aPos; + if( pCurCrsr->IsSelOvr(SELOVER_CHECKNODESSECTION | SELOVER_TOGGLE) ) + bRet = FALSE; + else + UpdateCrsr(); + } + if( bRet ) + { + rCntntAtPos.sStr = pTxtNd->GetExpandTxt( + *pTxtAttr->GetStart(), + *pTxtAttr->GetEnd() - *pTxtAttr->GetStart(), + FALSE ); + + rCntntAtPos.aFnd.pAttr = &pTxtAttr->GetAttr(); + rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_INETATTR; + rCntntAtPos.pFndTxtAttr = pTxtAttr; + + if( pFldRect && 0 != ( pFrm = pTxtNd->GetFrm( &aPt ) ) ) + pFrm->GetCharRect( *pFldRect, aPos, &aTmpState ); + } + } + } + + if( !bRet && SwContentAtPos::SW_REDLINE & rCntntAtPos.eCntntAtPos ) + { + const SwRedline* pRedl = GetDoc()->GetRedline( aPos ); + if( pRedl ) + { + rCntntAtPos.aFnd.pRedl = pRedl; + rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_REDLINE; + rCntntAtPos.pFndTxtAttr = 0; + bRet = TRUE; + + if( pFldRect && 0 != ( pFrm = pTxtNd->GetFrm( &aPt ) ) ) + pFrm->GetCharRect( *pFldRect, aPos, &aTmpState ); + } + } + } + + if( !bRet && ( + SwContentAtPos::SW_TABLEBOXFML & rCntntAtPos.eCntntAtPos +#ifndef PRODUCT + || SwContentAtPos::SW_TABLEBOXVALUE & rCntntAtPos.eCntntAtPos +#endif + )) + { + const SwTableNode* pTblNd; + const SwTableBox* pBox; + const SwStartNode* pSttNd = pTxtNd->FindTableBoxStartNode(); + const SfxPoolItem* pItem; + if( pSttNd && 0 != ( pTblNd = pTxtNd->FindTableNode()) && + 0 != ( pBox = pTblNd->GetTable().GetTblBox( + pSttNd->GetIndex() )) && +#ifndef PRODUCT + ( SFX_ITEM_SET == pBox->GetFrmFmt()->GetItemState( + RES_BOXATR_FORMULA, FALSE, &pItem ) || + SFX_ITEM_SET == pBox->GetFrmFmt()->GetItemState( + RES_BOXATR_VALUE, FALSE, &pItem )) +#else + SFX_ITEM_SET == pBox->GetFrmFmt()->GetItemState( + RES_BOXATR_FORMULA, FALSE, &pItem ) +#endif + ) + { + SwFrm* pF = pTxtNd->GetFrm( &aPt ); + if( pF ) + { + // dann aber den CellFrame + pFrm = (SwCntntFrm*)pF; + while( pF && !pF->IsCellFrm() ) + pF = pF->GetUpper(); + } + + // es wurde ein + if( aTmpState.bPosCorr ) + { + if( pF && !pF->Frm().IsInside( aPt )) + pF = 0; + } + else if( !pF ) + pF = pFrm; + + if( pF ) // nur dann ist es gueltig!! + { + // erzeuge aus der internen (fuer CORE) + // die externe (fuer UI) Formel + rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_TABLEBOXFML; +#ifndef PRODUCT + if( RES_BOXATR_VALUE == pItem->Which() ) + rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_TABLEBOXVALUE; + else +#endif + ((SwTblBoxFormula*)pItem)->PtrToBoxNm( &pTblNd->GetTable() ); + + bRet = TRUE; + if( bSetCrsr ) + { + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, + SwCrsrSaveState aSaveState( *pCurCrsr ); + *pCurCrsr->GetPoint() = aPos; + if( pCurCrsr->IsSelOvr( SELOVER_CHECKNODESSECTION | SELOVER_TOGGLE) ) + bRet = FALSE; + else + UpdateCrsr(); + } + + if( bRet ) + { + if( pFldRect ) + { + *pFldRect = pF->Prt(); + *pFldRect += pF->Frm().Pos(); + } + rCntntAtPos.pFndTxtAttr = 0; + rCntntAtPos.aFnd.pAttr = pItem; + } + } + } + } + +#ifndef PRODUCT + if( !bRet && SwContentAtPos::SW_CURR_ATTRS & rCntntAtPos.eCntntAtPos ) + { + xub_StrLen n = aPos.nContent.GetIndex(); + SfxItemSet aSet( GetDoc()->GetAttrPool(), POOLATTR_BEGIN, + POOLATTR_END - 1 ); + if( pTxtNd->GetpSwpHints() ) + { + for( USHORT i = 0; i < pTxtNd->GetSwpHints().Count(); ++i ) + { + const SwTxtAttr* pHt = pTxtNd->GetSwpHints()[i]; + xub_StrLen nAttrStart = *pHt->GetStart(); + if( nAttrStart > n ) // ueber den Bereich hinaus + break; + + if( 0 != pHt->GetEnd() && ( + ( nAttrStart < n && + ( pHt->DontExpand() ? n < *pHt->GetEnd() + : n <= *pHt->GetEnd() )) || + ( n == nAttrStart && + ( nAttrStart == *pHt->GetEnd() || !n ))) ) + { + aSet.Put( pHt->GetAttr() ); + } + } + if( pTxtNd->GetpSwAttrSet() && + pTxtNd->GetSwAttrSet().Count() ) + { + SfxItemSet aFmtSet( pTxtNd->GetSwAttrSet() ); + // aus dem Format-Set alle entfernen, die im TextSet auch gesetzt sind + aFmtSet.Differentiate( aSet ); + // jetzt alle zusammen "mergen" + aSet.Put( aFmtSet ); + } + } + else + pTxtNd->SwCntntNode::GetAttr( aSet ); + + rCntntAtPos.sStr.AssignAscii( + RTL_CONSTASCII_STRINGPARAM( "Pos: (" )); + rCntntAtPos.sStr += String::CreateFromInt32( aPos.nNode.GetIndex()); + rCntntAtPos.sStr += ':'; + rCntntAtPos.sStr += String::CreateFromInt32( aPos.nContent.GetIndex()); + rCntntAtPos.sStr += ')'; + rCntntAtPos.sStr.AppendAscii( + RTL_CONSTASCII_STRINGPARAM( "\nAbs.Vorl.: " )); + rCntntAtPos.sStr += pTxtNd->GetFmtColl()->GetName(); + if( pTxtNd->GetCondFmtColl() ) + rCntntAtPos.sStr.AppendAscii( + RTL_CONSTASCII_STRINGPARAM( "\nBed.Vorl.: " )) + += pTxtNd->GetCondFmtColl()->GetName(); + + if( aSet.Count() ) + { + String sAttrs; + SfxItemIter aIter( aSet ); + const SfxPoolItem* pItem = aIter.FirstItem(); + while( TRUE ) + { + if( !IsInvalidItem( pItem )) + { + String aStr; + GetDoc()->GetAttrPool().GetPresentation( *pItem, + SFX_ITEM_PRESENTATION_COMPLETE, + SFX_MAPUNIT_CM, aStr ); + if( sAttrs.Len() ) + sAttrs.AppendAscii( + RTL_CONSTASCII_STRINGPARAM( ", " )); + sAttrs += aStr; + } + if( aIter.IsAtEnd() ) + break; + pItem = aIter.NextItem(); + } + if( sAttrs.Len() ) + { + if( rCntntAtPos.sStr.Len() ) + rCntntAtPos.sStr += '\n'; + rCntntAtPos.sStr.AppendAscii( + RTL_CONSTASCII_STRINGPARAM( "Attr: " ) ) + += sAttrs; + } + } + bRet = TRUE; + rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_CURR_ATTRS; + } +#endif + } + } + + if( !bRet ) + { + rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_NOTHING; + rCntntAtPos.aFnd.pFld = 0; + } + return bRet; +} + +// befindet sich der Node in einem geschuetzten Bereich? +FASTBOOL SwContentAtPos::IsInProtectSect() const +{ + const SwTxtNode* pNd = 0; + if( pFndTxtAttr ) + { + switch( eCntntAtPos ) + { + case SW_FIELD: + case SW_CLICKFIELD: + pNd = ((SwTxtFld*)pFndTxtAttr)->GetpTxtNode(); + break; + + case SW_FTN: + pNd = &((SwTxtFtn*)pFndTxtAttr)->GetTxtNode(); + break; + + case SW_INETATTR: + pNd = ((SwTxtINetFmt*)pFndTxtAttr)->GetpTxtNode(); + break; + } + } + + const SwCntntFrm* pFrm; + return pNd && ( pNd->IsInProtectSect() || + ( 0 != ( pFrm = pNd->GetFrm(0,0,FALSE)) && + pFrm->IsProtected() )); +} + +FASTBOOL SwCrsrShell::SelectTxtAttr( USHORT nWhich, BOOL bExpand, + const SwTxtAttr* pTxtAttr ) +{ + SET_CURR_SHELL( this ); + FASTBOOL bRet = FALSE; + + if( !IsTableMode() ) + { + SwPosition& rPos = *pCurCrsr->GetPoint(); + if( !pTxtAttr ) + { + SwTxtNode* pTxtNd = rPos.nNode.GetNode().GetTxtNode(); + pTxtAttr = pTxtNd ? pTxtNd->GetTxtAttr( rPos.nContent, + nWhich, bExpand ) : 0; + } + + if( pTxtAttr ) + { + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, + SwCrsrSaveState aSaveState( *pCurCrsr ); + + pCurCrsr->DeleteMark(); + rPos.nContent = *pTxtAttr->GetStart(); + pCurCrsr->SetMark(); + const xub_StrLen* pEnd = pTxtAttr->GetEnd(); + rPos.nContent = pEnd ? *pEnd : *pTxtAttr->GetStart() + 1; + + if( !pCurCrsr->IsSelOvr() ) + { + UpdateCrsr(); + bRet = TRUE; + } + } + } + return bRet; +} + + +FASTBOOL SwCrsrShell::GotoINetAttr( const SwTxtINetFmt& rAttr ) +{ + FASTBOOL bRet = FALSE; + if( rAttr.GetpTxtNode() ) + { + SwCursor* pCrsr = IsTableMode() ? pTblCrsr : pCurCrsr; + + SET_CURR_SHELL( this ); + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + SwCrsrSaveState aSaveState( *pCrsr ); + + pCrsr->GetPoint()->nNode = *rAttr.GetpTxtNode(); + pCrsr->GetPoint()->nContent.Assign( (SwTxtNode*)rAttr.GetpTxtNode(), + *rAttr.GetStart() ); + bRet = !pCrsr->IsSelOvr(); + if( bRet ) + UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); + } + return bRet; +} + + +const SwFmtINetFmt* SwCrsrShell::FindINetAttr( const String& rName ) const +{ + return pDoc->FindINetAttr( rName ); +} + +FASTBOOL SwCrsrShell::GetShadowCrsrPos( const Point& rPt, SwFillMode eFillMode, + SwRect& rRect, SwHoriOrient& rOrient ) +{ + + SET_CURR_SHELL( this ); + FASTBOOL bRet = FALSE; + + if( !IsTableMode() && !HasSelection() && GetDoc()->DoesUndo() ) + { + Point aPt( rPt ); + SwPosition aPos( *pCurCrsr->GetPoint() ); + + SwFillCrsrPos aFPos( eFillMode ); + SwCrsrMoveState aTmpState( &aFPos ); + + if( GetLayout()->GetCrsrOfst( &aPos, aPt, &aTmpState ) && + !aPos.nNode.GetNode().IsProtect()) + { + // Start-Position im geschuetzten Bereich? + rRect = aFPos.aCrsr; + rOrient = aFPos.eOrient; + bRet = TRUE; + } + } + return bRet; +} + +FASTBOOL SwCrsrShell::SetShadowCrsrPos( const Point& rPt, SwFillMode eFillMode ) +{ + SET_CURR_SHELL( this ); + FASTBOOL bRet = FALSE; + + if( !IsTableMode() && !HasSelection() && GetDoc()->DoesUndo() ) + { + Point aPt( rPt ); + SwPosition aPos( *pCurCrsr->GetPoint() ); + + SwFillCrsrPos aFPos( eFillMode ); + SwCrsrMoveState aTmpState( &aFPos ); + + if( GetLayout()->GetCrsrOfst( &aPos, aPt, &aTmpState ) ) + { + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen + StartAction(); + + SwCntntNode* pCNd = aPos.nNode.GetNode().GetCntntNode(); + USHORT nUndoId = UNDO_INS_FROM_SHADOWCRSR; + // Werden nur die Absatzattribute Adjust oder LRSpace gesetzt, + // dann sollte der naechste Aufruf die NICHT wieder entfernen. + if( 0 == aFPos.nParaCnt + aFPos.nColumnCnt && + ( FILL_INDENT == aFPos.eMode || + ( HORI_NONE != aFPos.eOrient && + 0 == aFPos.nTabCnt + aFPos.nSpaceCnt )) && + pCNd && pCNd->Len() ) + nUndoId = 0; + + GetDoc()->StartUndo( nUndoId ); + + SwTxtFmtColl* pNextFmt = 0; + SwTxtNode* pTNd = pCNd->GetTxtNode(); + if( pTNd ) + pNextFmt = &pTNd->GetTxtColl()->GetNextTxtFmtColl(); + + const SwSectionNode* pSectNd = pCNd->FindSectionNode(); + if( pSectNd && aFPos.nParaCnt ) + { + SwNodeIndex aEnd( aPos.nNode, 1 ); + while( aEnd.GetNode().IsEndNode() && + (const SwNode*)&aEnd.GetNode() != + pSectNd->EndOfSectionNode() ) + aEnd++; + + if( aEnd.GetNode().IsEndNode() && + pCNd->Len() == aPos.nContent.GetIndex() ) + aPos.nNode = *pSectNd->EndOfSectionNode(); + } + + for( USHORT n = 0; n < aFPos.nParaCnt + aFPos.nColumnCnt; ++n ) + { + GetDoc()->AppendTxtNode( aPos ); + if( !n && pNextFmt ) + { + *pCurCrsr->GetPoint() = aPos; + GetDoc()->SetTxtFmtColl( *pCurCrsr, pNextFmt, FALSE ); + //JP 04.11.97: erstmal keine Folgevorlage der + // Folgevorlage beachten + // pNextFmt = pNextFmt->GetNextTxtFmtColl(); + } + if( n < aFPos.nColumnCnt ) + { + *pCurCrsr->GetPoint() = aPos; + GetDoc()->Insert( *pCurCrsr, + SvxFmtBreakItem( SVX_BREAK_COLUMN_BEFORE )); + } + } + + *pCurCrsr->GetPoint() = aPos; + switch( aFPos.eMode ) + { + case FILL_INDENT: + if( 0 != (pCNd = aPos.nNode.GetNode().GetCntntNode() )) + { + SfxItemSet aSet( GetDoc()->GetAttrPool(), + RES_LR_SPACE, RES_LR_SPACE, + RES_PARATR_ADJUST, RES_PARATR_ADJUST, + 0 ); + SvxLRSpaceItem aLR( (SvxLRSpaceItem&) + pCNd->GetAttr( RES_LR_SPACE ) ); + aLR.SetTxtLeft( aFPos.nTabCnt ); + aLR.SetTxtFirstLineOfst( 0 ); + aSet.Put( aLR ); + + const SvxAdjustItem& rAdj = (SvxAdjustItem&)pCNd-> + GetAttr( RES_PARATR_ADJUST ); + if( SVX_ADJUST_LEFT != rAdj.GetAdjust() ) + aSet.Put( SvxAdjustItem( SVX_ADJUST_LEFT ) ); + + GetDoc()->Insert( *pCurCrsr, aSet ); + } + else + ASSERT( !this, "wo ist mein CntntNode?" ); + break; + + case FILL_TAB: + case FILL_SPACE: + { + String sInsert; + if( aFPos.nTabCnt ) + sInsert.Fill( aFPos.nTabCnt, '\t' ); + if( aFPos.nSpaceCnt ) + { + String sSpace; + sSpace.Fill( aFPos.nSpaceCnt ); + sInsert += sSpace; + } + if( sInsert.Len() ) + GetDoc()->Insert( *pCurCrsr, sInsert ); + } + // kein break - Ausrichtung muss noch gesetzt werden + case FILL_MARGIN: + if( HORI_NONE != aFPos.eOrient ) + { + SvxAdjustItem aAdj( SVX_ADJUST_LEFT ); + switch( aFPos.eOrient ) + { + case HORI_CENTER: + aAdj.SetAdjust( SVX_ADJUST_CENTER ); + break; + case HORI_RIGHT: + aAdj.SetAdjust( SVX_ADJUST_RIGHT ); + break; + } + GetDoc()->Insert( *pCurCrsr, aAdj ); + } + break; + } + + GetDoc()->EndUndo( nUndoId ); + EndAction(); + + bRet = TRUE; + } + } + return bRet; +} + +const SwRedline* SwCrsrShell::SelNextRedline() +{ + const SwRedline* pFnd = 0; + if( !IsTableMode() ) + { + SET_CURR_SHELL( this ); + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + SwCrsrSaveState aSaveState( *pCurCrsr ); + + pFnd = GetDoc()->SelNextRedline( *pCurCrsr ); + if( pFnd && !pCurCrsr->IsInProtectTable() && !pCurCrsr->IsSelOvr() ) + UpdateCrsr( SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); + else + pFnd = 0; + } + return pFnd; +} + +const SwRedline* SwCrsrShell::SelPrevRedline() +{ + const SwRedline* pFnd = 0; + if( !IsTableMode() ) + { + SET_CURR_SHELL( this ); + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + SwCrsrSaveState aSaveState( *pCurCrsr ); + + pFnd = GetDoc()->SelPrevRedline( *pCurCrsr ); + if( pFnd && !pCurCrsr->IsInProtectTable() && !pCurCrsr->IsSelOvr() ) + UpdateCrsr( SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); + else + pFnd = 0; + } + return pFnd; +} + +const SwRedline* SwCrsrShell::_GotoRedline( USHORT nArrPos, BOOL bSelect ) +{ + const SwRedline* pFnd = 0; + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + SwCrsrSaveState aSaveState( *pCurCrsr ); + + pFnd = GetDoc()->GetRedlineTbl()[ nArrPos ]; + if( pFnd ) + { + *pCurCrsr->GetPoint() = *pFnd->Start(); + + SwCntntNode* pCNd; + SwNodeIndex* pIdx = &pCurCrsr->GetPoint()->nNode; + if( !pIdx->GetNode().IsCntntNode() && + 0 != ( pCNd = GetDoc()->GetNodes().GoNextSection( pIdx, + TRUE, IsReadOnlyAvailable() )) ) + { + if( *pIdx <= pFnd->End()->nNode ) + pCurCrsr->GetPoint()->nContent.Assign( pCNd, 0 ); + else + pFnd = 0; + } + + if( pFnd && bSelect ) + { + pCurCrsr->SetMark(); + if( REDLINE_FMTCOLL == pFnd->GetType() ) + { + pCNd = pIdx->GetNode().GetCntntNode(); + pCurCrsr->GetPoint()->nContent.Assign( pCNd, pCNd->Len() ); + pCurCrsr->GetMark()->nContent.Assign( pCNd, 0 ); + } + else + *pCurCrsr->GetPoint() = *pFnd->End(); + + pIdx = &pCurCrsr->GetPoint()->nNode; + if( !pIdx->GetNode().IsCntntNode() && + 0 != ( pCNd = GetDoc()->GetNodes().GoPrevSection( pIdx, + TRUE, IsReadOnlyAvailable() )) ) + { + if( *pIdx >= pCurCrsr->GetMark()->nNode ) + pCurCrsr->GetPoint()->nContent.Assign( pCNd, pCNd->Len() ); + else + pFnd = 0; + } + } + + if( !pFnd ) + { + pCurCrsr->DeleteMark(); + pCurCrsr->RestoreSavePos(); + } + else if( bSelect && *pCurCrsr->GetMark() == *pCurCrsr->GetPoint() ) + pCurCrsr->DeleteMark(); + + if( pFnd && !pCurCrsr->IsInProtectTable() && !pCurCrsr->IsSelOvr() ) + UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE + | SwCrsrShell::READONLY ); + else + { + pFnd = 0; + if( bSelect ) + pCurCrsr->DeleteMark(); + } + } + return pFnd; +} + +const SwRedline* SwCrsrShell::GotoRedline( USHORT nArrPos, BOOL bSelect ) +{ + const SwRedline* pFnd = 0; + if( !IsTableMode() ) + { + SET_CURR_SHELL( this ); + + const SwRedlineTbl& rTbl = GetDoc()->GetRedlineTbl(); + const SwRedline* pTmp = rTbl[ nArrPos ]; + USHORT nSeqNo = pTmp->GetSeqNo(); + if( nSeqNo && bSelect ) + { + BOOL bCheck = FALSE; + int nLoopCnt = 2; + USHORT nArrSavPos = nArrPos; + + do { + pTmp = _GotoRedline( nArrPos, TRUE ); + + if( !pFnd ) + pFnd = pTmp; + + if( pTmp && bCheck ) + { + // checke auf Ueberlappungen. Das kann durch + // FmtColl-Redlines kommen, die auf den gesamten Absatz + // aus gedehnt werden. + + SwPaM* pCur = pCurCrsr, *pNext = (SwPaM*)pCur->GetNext(); + SwPosition* pCStt = pCur->Start(), *pCEnd = pCur->End(); + while( pCur != pNext ) + { + const SwPosition *pNStt = pNext->Start(), + *pNEnd = pNext->End(); + + BOOL bDel = TRUE; + switch( ::ComparePosition( *pCStt, *pCEnd, + *pNStt, *pNEnd )) + { + case POS_INSIDE: // Pos1 liegt vollstaendig in Pos2 + if( !pCur->HasMark() ) + { + pCur->SetMark(); + *pCur->GetMark() = *pNStt; + } + else + *pCStt = *pNStt; + *pCEnd = *pNEnd; + break; + + case POS_OUTSIDE: // Pos2 liegt vollstaendig in Pos1 + case POS_EQUAL: // Pos1 ist genauso gross wie Pos2 + break; + + case POS_OVERLAP_BEFORE: // Pos1 ueberlappt Pos2 am Anfang + if( !pCur->HasMark() ) + pCur->SetMark(); + *pCEnd = *pNEnd; + break; + case POS_OVERLAP_BEHIND: // Pos1 ueberlappt Pos2 am Ende + if( !pCur->HasMark() ) + { + pCur->SetMark(); + *pCur->GetMark() = *pNStt; + } + else + *pCStt = *pNStt; + break; + + default: + bDel = FALSE; + } + + if( bDel ) + { + // den brauchen wir nicht mehr + SwPaM* pPrev = (SwPaM*)pNext->GetPrev(); + delete pNext; + pNext = pPrev; + } + pNext = (SwPaM*)pNext->GetNext(); + } + } + + USHORT nFndPos = 2 == nLoopCnt + ? rTbl.FindNextOfSeqNo( nArrPos ) + : rTbl.FindPrevOfSeqNo( nArrPos ); + if( USHRT_MAX != nFndPos || + ( 0 != ( --nLoopCnt ) && USHRT_MAX != ( + nFndPos = rTbl.FindPrevOfSeqNo( nArrSavPos ))) ) + { + if( pTmp ) + { + // neuen Cursor erzeugen + CreateCrsr(); + bCheck = TRUE; + } + nArrPos = nFndPos; + } + else + nLoopCnt = 0; + + } while( nLoopCnt ); + } + else + pFnd = _GotoRedline( nArrPos, bSelect ); + } + return pFnd; +} + + + diff --git a/sw/source/core/crsr/crstrvl1.cxx b/sw/source/core/crsr/crstrvl1.cxx new file mode 100644 index 000000000000..4dac2c4374c3 --- /dev/null +++ b/sw/source/core/crsr/crstrvl1.cxx @@ -0,0 +1,122 @@ +/************************************************************************* + * + * $RCSfile: crstrvl1.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:17 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _CRSRSH_HXX +#include +#endif +#ifndef _VISCRS_HXX +#include +#endif +#ifndef _CALLNK_HXX +#include +#endif + +FASTBOOL SwCrsrShell::IsStartWord() const +{ + return pCurCrsr->IsStartWord(); +} +FASTBOOL SwCrsrShell::IsEndWord() const +{ + return pCurCrsr->IsEndWord(); +} +FASTBOOL SwCrsrShell::IsInWord() const +{ + return pCurCrsr->IsInWord(); +} + + +FASTBOOL SwCrsrShell::GoStartWord() +{ + return CallCrsrFN( &SwCursor::GoStartWord ); +} +FASTBOOL SwCrsrShell::GoEndWord() +{ + return CallCrsrFN( &SwCursor::GoEndWord ); +} +FASTBOOL SwCrsrShell::GoNextWord() +{ + return CallCrsrFN( &SwCursor::GoNextWord ); +} +FASTBOOL SwCrsrShell::GoPrevWord() +{ + return CallCrsrFN( &SwCursor::GoPrevWord ); +} +FASTBOOL SwCrsrShell::GoNextSentence() +{ + return CallCrsrFN( &SwCursor::GoNextSentence ); +} +FASTBOOL SwCrsrShell::GoPrevSentence() +{ + return CallCrsrFN( &SwCursor::GoPrevSentence ); +} + +FASTBOOL SwCrsrShell::SelectWord( const Point* pPt ) +{ + return pCurCrsr->SelectWord( pPt ); +} + + diff --git a/sw/source/core/crsr/findattr.cxx b/sw/source/core/crsr/findattr.cxx new file mode 100644 index 000000000000..34e65905851c --- /dev/null +++ b/sw/source/core/crsr/findattr.cxx @@ -0,0 +1,1463 @@ +/************************************************************************* + * + * $RCSfile: findattr.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:17 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _HINTIDS_HXX +#include +#endif + +#ifndef _SV_SVAPP_HXX //autogen wg. Application +#include +#endif +#ifndef _SFXITEMITER_HXX //autogen +#include +#endif +#ifndef _SFX_WHITER_HXX //autogen +#include +#endif + +#ifndef _SVX_BRKITEM_HXX //autogen +#include +#endif +#ifndef _SVX_COLRITEM_HXX //autogen +#include +#endif +#ifndef _SVX_FONTITEM_HXX //autogen +#include +#endif +#ifndef _FMTPDSC_HXX //autogen +#include +#endif +#ifndef _TXATBASE_HXX //autogen +#include +#endif +#ifndef _FCHRFMT_HXX //autogen +#include +#endif +#ifndef _CHARFMT_HXX //autogen +#include +#endif +#ifndef _DOC_HXX +#include +#endif +#ifndef _SWCRSR_HXX +#include +#endif +#ifndef _EDITSH_HXX +#include +#endif +#ifndef _NDTXT_HXX +#include +#endif +#ifndef _PAMTYP_HXX +#include +#endif +#ifndef _SWUNDO_HXX +#include +#endif + + + +SV_DECL_PTRARR_SORT( SwpFmts, SwFmt*, 0, 4 ) +SV_IMPL_PTRARR_SORT( SwpFmts, SwFmt* ) + + // Sonderbehandlung fuer SvxFontItem, nur den Namen vergleichen: +int CmpAttr( const SfxPoolItem& rItem1, const SfxPoolItem& rItem2 ) +{ + switch( rItem1.Which() ) + { + case RES_CHRATR_FONT: + return ((SvxFontItem&)rItem1).GetFamilyName() == + ((SvxFontItem&)rItem2).GetFamilyName(); + + case RES_CHRATR_COLOR: + return ((SvxColorItem&)rItem1).GetValue().IsRGBEqual( + ((SvxColorItem&)rItem2).GetValue() ); + case RES_PAGEDESC: + return ((SwFmtPageDesc&)rItem1).GetNumOffset() == + ((SwFmtPageDesc&)rItem2).GetNumOffset() && + ((SwFmtPageDesc&)rItem1).GetPageDesc() == + ((SwFmtPageDesc&)rItem2).GetPageDesc(); + } + return rItem1 == rItem2; +} + + +const SwTxtAttr* GetFrwrdTxtHint( const SwpHints& rHtsArr, USHORT& rPos, + xub_StrLen nCntntPos ) +{ + while( rPos < rHtsArr.Count() ) + { + const SwTxtAttr *pTxtHt = rHtsArr.GetStart( rPos++ ); + // der Start vom Attribut muss innerhalb des Bereiches liegen !! + if( *pTxtHt->GetStart() >= nCntntPos ) + return pTxtHt; // gueltiges TextAttribut + } + return 0; // kein gueltiges TextAttribut +} + + +const SwTxtAttr* GetBkwrdTxtHint( const SwpHints& rHtsArr, USHORT& rPos, + xub_StrLen nCntntPos ) +{ + while( rPos > 0 ) + { + //Hack mit cast fuer das Update + const SwTxtAttr *pTxtHt = rHtsArr.GetStart( --rPos ); + // der Start vom Attribut muss innerhalb des Bereiches liegen !! + if( *pTxtHt->GetStart() < nCntntPos ) + return pTxtHt; // gueltiges TextAttribut + } + return 0; // kein gueltiges TextAttribut +} + + +void lcl_SetAttrPam( SwPaM & rPam, xub_StrLen nStart, const xub_StrLen* pEnde, + const BOOL bSaveMark ) +{ + xub_StrLen nCntntPos; + if( bSaveMark ) + nCntntPos = rPam.GetMark()->nContent.GetIndex(); + else + nCntntPos = rPam.GetPoint()->nContent.GetIndex(); + FASTBOOL bTstEnde = rPam.GetPoint()->nNode == rPam.GetMark()->nNode; + + SwCntntNode* pCNd = rPam.GetCntntNode(); + rPam.GetPoint()->nContent.Assign( pCNd, nStart ); + rPam.SetMark(); // Point == GetMark + + // Point zeigt auf das Ende vom SuchBereich oder Ende vom Attribut + if( pEnde ) + { + if( bTstEnde && *pEnde > nCntntPos ) + rPam.GetPoint()->nContent = nCntntPos; + else + rPam.GetPoint()->nContent = *pEnde; + } +} + +//------------------ Suche nach einem Text Attribut ----------------------- + +// diese Funktion sucht in einem TextNode nach dem vorgegebenen Attribut. +// Wird es gefunden, dann hat der SwPaM den Bereich der das Attribut +// umspannt, unter Beachtung des Suchbereiches + + +FASTBOOL lcl_Search( const SwTxtNode& rTxtNd, SwPaM& rPam, + const SfxPoolItem& rCmpItem, + SwMoveFn fnMove, BOOL bValue ) +{ + if ( !rTxtNd.HasHints() ) + return FALSE; + const SwTxtAttr *pTxtHt = 0; + FASTBOOL bForward = fnMove == fnMoveForward; + USHORT nPos = bForward ? 0 : rTxtNd.GetSwpHints().Count(); + xub_StrLen nCntntPos = rPam.GetPoint()->nContent.GetIndex(); + + while( 0 != ( pTxtHt=(*fnMove->fnGetHint)(rTxtNd.GetSwpHints(),nPos,nCntntPos))) + if( pTxtHt->Which() == rCmpItem.Which() && + ( !bValue || CmpAttr( pTxtHt->GetAttr(), rCmpItem ))) + { + lcl_SetAttrPam( rPam, *pTxtHt->GetStart(), pTxtHt->GetEnd(), bForward ); + return TRUE; + } + return FALSE; +} + + +//------------------ Suche nach mehren Text Attributen ------------------- + +struct _SwSrchChrAttr +{ + USHORT nWhich; + xub_StrLen nStt, nEnd; + + _SwSrchChrAttr( const SfxPoolItem& rItem, + xub_StrLen nStart, xub_StrLen nAnyEnd ) + : nWhich( rItem.Which() ), nStt( nStart ), nEnd( nAnyEnd ) + {} +}; + +class SwAttrCheckArr +{ + _SwSrchChrAttr *pFndArr, *pStackArr; + xub_StrLen nNdStt, nNdEnd; + USHORT nArrStart, nArrLen; + USHORT nFound, nStackCnt; + SfxItemSet aCmpSet; + BOOL bNoColls; + BOOL bForward; + +public: + SwAttrCheckArr( const SfxItemSet& rSet, int bForward, int bNoCollections ); + ~SwAttrCheckArr(); + + void SetNewSet( const SwTxtNode& rTxtNd, const SwPaM& rPam ); + + // wieviele Attribute ueberhaupt ?? + USHORT Count() const { return aCmpSet.Count(); } + int Found() const { return nFound == aCmpSet.Count(); } + int CheckStack(); + + xub_StrLen Start() const; + xub_StrLen End() const; + + xub_StrLen GetNdStt() const { return nNdStt; } + xub_StrLen GetNdEnd() const { return nNdEnd; } + + int SetAttrFwd( const SwTxtAttr& rAttr ); + int SetAttrBwd( const SwTxtAttr& rAttr ); +}; + + + +SwAttrCheckArr::SwAttrCheckArr( const SfxItemSet& rSet, int bFwd, + int bNoCollections ) + : aCmpSet( *rSet.GetPool(), RES_CHRATR_BEGIN, RES_TXTATR_END-1 ) +{ + aCmpSet.Put( rSet, FALSE ); + bNoColls = bNoCollections; + + bForward = bFwd; + + // Bestimmen den Bereich des Fnd/Stack-Arrays (Min/Max) + SfxItemIter aIter( aCmpSet ); + nArrStart = aCmpSet.GetWhichByPos( aIter.GetFirstPos() ); + nArrLen = aCmpSet.GetWhichByPos( aIter.GetLastPos() ) - nArrStart+1; + + pFndArr = (_SwSrchChrAttr*)new char[ nArrLen * sizeof(_SwSrchChrAttr) ]; + pStackArr = (_SwSrchChrAttr*)new char[ nArrLen * sizeof(_SwSrchChrAttr) ]; +} + + +SwAttrCheckArr::~SwAttrCheckArr() +{ + delete (void*) pFndArr; + delete (void*) pStackArr; +} + + + +#pragma optimize( "e", off ) + +void SwAttrCheckArr::SetNewSet( const SwTxtNode& rTxtNd, const SwPaM& rPam ) +{ + memset( pFndArr, 0, nArrLen * sizeof(_SwSrchChrAttr) ); + memset( pStackArr, 0, nArrLen * sizeof(_SwSrchChrAttr) ); + nFound = 0; + nStackCnt = 0; + + if( bForward ) + { + nNdStt = rPam.GetPoint()->nContent.GetIndex(); + nNdEnd = rPam.GetPoint()->nNode == rPam.GetMark()->nNode + ? rPam.GetMark()->nContent.GetIndex() + : rTxtNd.GetTxt().Len(); + } + else + { + nNdEnd = rPam.GetPoint()->nContent.GetIndex(); + nNdStt = rPam.GetPoint()->nNode == rPam.GetMark()->nNode + ? rPam.GetMark()->nContent.GetIndex() + : 0; + } + + if( bNoColls && !rTxtNd.GetpSwAttrSet() ) + return ; + + const SfxItemSet& rSet = rTxtNd.GetSwAttrSet(); +// if( !rSet.Count() ) +// return; + + SfxItemIter aIter( aCmpSet ); + const SfxPoolItem* pItem = aIter.GetCurItem(); + const SfxPoolItem* pFndItem; + USHORT nWhich; + + while( TRUE ) + { + // nur testen, ob vorhanden ist ? + if( IsInvalidItem( pItem ) ) + { + nWhich = aCmpSet.GetWhichByPos( aIter.GetCurPos() ); + if( RES_TXTATR_END <= nWhich ) + break; // Ende der TextAttribute + + if( SFX_ITEM_SET == rSet.GetItemState( nWhich, !bNoColls, &pFndItem ) + && !CmpAttr( *pFndItem, rSet.GetPool()->GetDefaultItem( nWhich ) )) + { + pFndArr[ nWhich - nArrStart ] = + _SwSrchChrAttr( *pFndItem, nNdStt, nNdEnd ); + nFound++; + } + } + else + { + if( RES_TXTATR_END <= (nWhich = pItem->Which() )) + break; // Ende der TextAttribute + +//JP 27.02.95: wenn nach defaults gesucht wird, dann muss man bis zum Pool +// runter +// if( SFX_ITEM_SET == rSet.GetItemState( nWhich, !bNoColls, &pFndItem ) +// && *pFndItem == *pItem ) + if( CmpAttr( rSet.Get( nWhich, !bNoColls ), *pItem ) ) + { + pFndArr[ nWhich - nArrStart ] = + _SwSrchChrAttr( *pItem, nNdStt, nNdEnd ); + nFound++; + } + } + + if( aIter.IsAtEnd() ) + break; + pItem = aIter.NextItem(); + } +} +#pragma optimize( "", on ) + + +int SwAttrCheckArr::SetAttrFwd( const SwTxtAttr& rAttr ) +{ + _SwSrchChrAttr aTmp( rAttr.GetAttr(), *rAttr.GetStart(), *rAttr.GetAnyEnd() ); + // alle die nicht im Bereich sind -> ignorieren + if( aTmp.nEnd <= nNdStt || aTmp.nStt >= nNdEnd ) + return Found(); + + const SfxPoolItem* pItem; + +// -------------------------------------------------------------- +// Hier wird jetzt ausdruecklich auch in Zeichenvorlagen gesucht +// -------------------------------------------------------------- + USHORT nWhch = rAttr.Which(); + SfxWhichIter* pIter = NULL; + const SfxPoolItem* pTmpItem; + const SwAttrSet* pSet; + if( RES_TXTATR_CHARFMT == nWhch ) + { + if( bNoColls ) + return Found(); + SwCharFmt* pFmt = rAttr.GetCharFmt().GetCharFmt(); + if( pFmt ) + { + pSet = &pFmt->GetAttrSet(); + pIter = new SfxWhichIter( *pSet ); + nWhch = pIter->FirstWhich(); + while( nWhch && + SFX_ITEM_SET != pSet->GetItemState( nWhch, TRUE, &pTmpItem ) ) + nWhch = pIter->NextWhich(); + if( !nWhch ) + pTmpItem = NULL; + } + else + pTmpItem = NULL; + } + else + pTmpItem = &rAttr.GetAttr(); + while( pTmpItem ) + { + SfxItemState eState = aCmpSet.GetItemState( nWhch, FALSE, &pItem ); + if( SFX_ITEM_DONTCARE == eState || SFX_ITEM_SET == eState ) + { + register USHORT n; + _SwSrchChrAttr* pCmp; + + // loesche erstmal alle, die bis zu der Start Position schon wieder + // ungueltig sind: + + _SwSrchChrAttr* pArrPtr; + if( nFound ) + for( pArrPtr = pFndArr, n = 0; n < nArrLen; + ++n, ++pArrPtr ) + if( pArrPtr->nWhich && pArrPtr->nEnd <= aTmp.nStt ) + { + pArrPtr->nWhich = 0; // geloescht + nFound--; + } + + // loesche erstmal alle, die bis zu der Start Position schon wieder + // ungueltig sind. Und verschiebe alle die "offen" sind, heisst ueber + // die Start Position ragen, vom Stack in den FndSet + + if( nStackCnt ) + for( pArrPtr = pStackArr, n=0; n < nArrLen; ++n, ++pArrPtr ) + { + if( !pArrPtr->nWhich ) + continue; + + if( pArrPtr->nEnd <= aTmp.nStt ) + { + pArrPtr->nWhich = 0; // geloescht + if( !--nStackCnt ) + break; + } + else if( pArrPtr->nStt <= aTmp.nStt ) + { + if( ( pCmp = &pFndArr[ n ])->nWhich ) + { + if( pCmp->nEnd < pArrPtr->nEnd ) // erweitern + pCmp->nEnd = pArrPtr->nEnd; + } + else + { + *pCmp = *pArrPtr; + nFound++; + } + pArrPtr->nWhich = 0; + if( !--nStackCnt ) + break; + } + } + + BOOL bContinue = FALSE; + + if( SFX_ITEM_DONTCARE == eState ) + { + // wird Attribut gueltig ? + if( !CmpAttr( aCmpSet.GetPool()->GetDefaultItem( nWhch ), + *pTmpItem )) + { + // suche das Attribut und erweiter es gegebenenfalls + if( !( pCmp = &pFndArr[ nWhch - nArrStart ])->nWhich ) + { + *pCmp = aTmp; // nicht gefunden, eintragen + nFound++; + } + else if( pCmp->nEnd < aTmp.nEnd ) // erweitern ? + pCmp->nEnd = aTmp.nEnd; + + bContinue = TRUE; + } + } + // wird Attribut gueltig ? + else if( CmpAttr( *pItem, *pTmpItem ) ) + { + pFndArr[ nWhch - nArrStart ] = aTmp; + ++nFound; + bContinue = TRUE; + } + + // tja, dann muss es auf den Stack + if( !bContinue && ( pCmp = &pFndArr[ nWhch - nArrStart ])->nWhich ) + { + // vorhanden, auf den Stack. Aber nur wenn es noch grosser ist + if( pCmp->nEnd > aTmp.nEnd ) + { + ASSERT( !pStackArr[ nWhch - nArrStart ].nWhich, + "Stack-Platz ist noch belegt" ); + + // --------- + // JP 22.08.96: nur Ende manipulieren reicht nicht. Bug 30547 + // pCmp->nStt = aTmp.nEnd; + if( aTmp.nStt <= pCmp->nStt ) + pCmp->nStt = aTmp.nEnd; + else + pCmp->nEnd = aTmp.nStt; + // --------- + + pStackArr[ nWhch - nArrStart ] = *pCmp; + nStackCnt++; + } + pCmp->nWhich = 0; + nFound--; + } + } + if( pIter ) + { + nWhch = pIter->NextWhich(); + while( nWhch && + SFX_ITEM_SET != pSet->GetItemState( nWhch, TRUE, &pTmpItem ) ) + nWhch = pIter->NextWhich(); + if( !nWhch ) + break; + } + else + break; + } +// -------------------------------------------------------------- +#ifdef USED + { + SfxItemState eState = aCmpSet.GetItemState( rAttr.Which(), FALSE, &pItem ); + if( SFX_ITEM_DONTCARE != eState && SFX_ITEM_SET != eState ) + return Found(); + + register USHORT n, nWhich = rAttr.Which(); + _SwSrchChrAttr* pCmp; + + // loesche erstmal alle, die bis zu der Start Position schon wieder + // ungueltig sind: + + _SwSrchChrAttr* pArrPtr; + if( nFound ) + for( pArrPtr = pFndArr, n = 0; n < nArrLen; + ++n, ++pArrPtr ) + if( pArrPtr->nWhich && pArrPtr->nEnd <= aTmp.nStt ) + { + pArrPtr->nWhich = 0; // geloescht + nFound--; + } + + // loesche erstmal alle, die bis zu der Start Position schon wieder + // ungueltig sind. Und verschiebe alle die "offen" sind, heisst ueber + // die Start Position ragen, vom Stack in den FndSet + + if( nStackCnt ) + for( pArrPtr = pStackArr, n=0; n < nArrLen; ++n, ++pArrPtr ) + { + if( !pArrPtr->nWhich ) + continue; + + if( pArrPtr->nEnd <= aTmp.nStt ) + { + pArrPtr->nWhich = 0; // geloescht + if( !--nStackCnt ) + break; + } + else if( pArrPtr->nStt <= aTmp.nStt ) + { + if( ( pCmp = &pFndArr[ n ])->nWhich ) + { + if( pCmp->nEnd < pArrPtr->nEnd ) // erweitern + pCmp->nEnd = pArrPtr->nEnd; + } + else + { + *pCmp = *pArrPtr; + nFound++; + } + pArrPtr->nWhich = 0; + if( !--nStackCnt ) + break; + } + } + + + if( SFX_ITEM_DONTCARE == eState ) + { + // wird Attribut gueltig ? + if( !CmpAttr( aCmpSet.GetPool()->GetDefaultItem( nWhich ), + rAttr.GetAttr() )) + { + // suche das Attribut und erweiter es gegebenenfalls + if( !( pCmp = &pFndArr[ nWhich - nArrStart ])->nWhich ) + { + *pCmp = aTmp; // nicht gefunden, eintragen + nFound++; + } + else if( pCmp->nEnd < aTmp.nEnd ) // erweitern ? + pCmp->nEnd = aTmp.nEnd; + + return Found(); + } + } + // wird Attribut gueltig ? + else if( CmpAttr( *pItem, rAttr.GetAttr() ) ) + { + pFndArr[ nWhich - nArrStart ] = aTmp; + return ++nFound == aCmpSet.Count(); + } + + // tja, dann muss es auf den Stack + if( ( pCmp = &pFndArr[ nWhich - nArrStart ])->nWhich ) + { + // vorhanden, auf den Stack. Aber nur wenn es noch grosser ist + if( pCmp->nEnd > aTmp.nEnd ) + { + ASSERT( !pStackArr[ nWhich - nArrStart ].nWhich, + "Stack-Platz ist noch belegt" ); + + // --------- + // JP 22.08.96: nur Ende manipulieren reicht nicht. Bug 30547 + // pCmp->nStt = aTmp.nEnd; + if( aTmp.nStt <= pCmp->nStt ) + pCmp->nStt = aTmp.nEnd; + else + pCmp->nEnd = aTmp.nStt; + // --------- + + pStackArr[ nWhich - nArrStart ] = *pCmp; + nStackCnt++; + } + pCmp->nWhich = 0; + nFound--; + } + } +#endif + return Found(); +} + + +int SwAttrCheckArr::SetAttrBwd( const SwTxtAttr& rAttr ) +{ + _SwSrchChrAttr aTmp( rAttr.GetAttr(), *rAttr.GetStart(), *rAttr.GetAnyEnd() ); + // alle die nicht im Bereich sind -> ignorieren + if( aTmp.nEnd < nNdStt || aTmp.nStt >= nNdEnd ) + return Found(); + + const SfxPoolItem* pItem; +// -------------------------------------------------------------- +// Hier wird jetzt ausdruecklich auch in Zeichenvorlagen gesucht +// -------------------------------------------------------------- + USHORT nWhch = rAttr.Which(); + SfxWhichIter* pIter = NULL; + const SfxPoolItem* pTmpItem; + const SwAttrSet* pSet; + if( RES_TXTATR_CHARFMT == nWhch ) + { + if( bNoColls ) + return Found(); + SwCharFmt* pFmt = rAttr.GetCharFmt().GetCharFmt(); + if( pFmt ) + { + pSet = &pFmt->GetAttrSet(); + pIter = new SfxWhichIter( *pSet ); + nWhch = pIter->FirstWhich(); + while( nWhch && + SFX_ITEM_SET != pSet->GetItemState( nWhch, TRUE, &pTmpItem ) ) + nWhch = pIter->NextWhich(); + if( !nWhch ) + pTmpItem = NULL; + } + else + pTmpItem = NULL; + } + else + pTmpItem = &rAttr.GetAttr(); + while( pTmpItem ) + { + SfxItemState eState = aCmpSet.GetItemState( nWhch, FALSE, &pItem ); + if( SFX_ITEM_DONTCARE == eState || SFX_ITEM_SET == eState ) + { + register USHORT n; + _SwSrchChrAttr* pCmp; + + // loesche erstmal alle, die bis zu der Start Position schon wieder + // ungueltig sind: + + _SwSrchChrAttr* pArrPtr; + if( nFound ) + for( pArrPtr = pFndArr, n = 0; n < nArrLen; ++n, ++pArrPtr ) + if( pArrPtr->nWhich && pArrPtr->nStt >= aTmp.nEnd ) + { + pArrPtr->nWhich = 0; // geloescht + nFound--; + } + + // loesche erstmal alle, die bis zu der Start Position schon wieder + // ungueltig sind. Und verschiebe alle die "offen" sind, heisst ueber + // die Start Position ragen, vom Stack in den FndSet + + if( nStackCnt ) + for( pArrPtr = pStackArr, n = 0; n < nArrLen; ++n, ++pArrPtr ) + { + if( !pArrPtr->nWhich ) + continue; + + if( pArrPtr->nStt >= aTmp.nEnd ) + { + pArrPtr->nWhich = 0; // geloescht + if( !--nStackCnt ) + break; + } + else if( pArrPtr->nEnd >= aTmp.nEnd ) + { + if( ( pCmp = &pFndArr[ n ])->nWhich ) + { + if( pCmp->nStt > pArrPtr->nStt ) // erweitern + pCmp->nStt = pArrPtr->nStt; + } + else + { + *pCmp = *pArrPtr; + nFound++; + } + pArrPtr->nWhich = 0; + if( !--nStackCnt ) + break; + } + } + + BOOL bContinue = FALSE; + if( SFX_ITEM_DONTCARE == eState ) + { + // wird Attribut gueltig ? + if( !CmpAttr( aCmpSet.GetPool()->GetDefaultItem( nWhch ), + *pTmpItem ) ) + { + // suche das Attribut und erweiter es gegebenenfalls + if( !( pCmp = &pFndArr[ nWhch - nArrStart ])->nWhich ) + { + *pCmp = aTmp; // nicht gefunden, eintragen + nFound++; + } + else if( pCmp->nStt > aTmp.nStt ) // erweitern ? + pCmp->nStt = aTmp.nStt; + + bContinue = TRUE; + } + } + // wird Attribut gueltig ? + else if( CmpAttr( *pItem, *pTmpItem )) + { + pFndArr[ nWhch - nArrStart ] = aTmp; + ++nFound; + bContinue = TRUE; + } + + // tja, dann muss es auf den Stack + if( !bContinue && ( pCmp = &pFndArr[ nWhch - nArrStart ])->nWhich ) + { + // vorhanden, auf den Stack. Aber nur wenn es noch grosser ist + if( pCmp->nStt < aTmp.nStt ) + { + ASSERT( !pStackArr[ nWhch - nArrStart ].nWhich, + "Stack-Platz ist noch belegt" ); + +// --------- +// JP 22.08.96: nur Ende manipulieren reicht nicht. Bug 30547 +// pCmp->nEnd = aTmp.nStt; + if( aTmp.nEnd <= pCmp->nEnd ) + pCmp->nEnd = aTmp.nStt; + else + pCmp->nStt = aTmp.nEnd; +// --------- + + pStackArr[ nWhch - nArrStart ] = *pCmp; + nStackCnt++; + } + pCmp->nWhich = 0; + nFound--; + } + } + if( pIter ) + { + nWhch = pIter->NextWhich(); + while( nWhch && + SFX_ITEM_SET != pSet->GetItemState( nWhch, TRUE, &pTmpItem ) ) + nWhch = pIter->NextWhich(); + if( !nWhch ) + break; + } + else + break; + } + return Found(); +} + + +xub_StrLen SwAttrCheckArr::Start() const +{ + xub_StrLen nStart = nNdStt; + _SwSrchChrAttr* pArrPtr = pFndArr; + for( USHORT n = 0; n < nArrLen; ++n, ++pArrPtr ) + if( pArrPtr->nWhich && pArrPtr->nStt > nStart ) + nStart = pArrPtr->nStt; + + return nStart; +} + + +xub_StrLen SwAttrCheckArr::End() const +{ + _SwSrchChrAttr* pArrPtr = pFndArr; + xub_StrLen nEnd = nNdEnd; + for( USHORT n = 0; n < nArrLen; ++n, ++pArrPtr ) + if( pArrPtr->nWhich && pArrPtr->nEnd < nEnd ) + nEnd = pArrPtr->nEnd; + + return nEnd; +} + + +int SwAttrCheckArr::CheckStack() +{ + if( !nStackCnt ) + return FALSE; + + USHORT n; + xub_StrLen nSttPos = Start(), nEndPos = End(); + _SwSrchChrAttr* pArrPtr; + for( pArrPtr = pStackArr, n = 0; n < nArrLen; ++n, ++pArrPtr ) + { + if( !pArrPtr->nWhich ) + continue; + + if( bForward ? pArrPtr->nEnd <= nSttPos : pArrPtr->nStt >= nEndPos ) + { + pArrPtr->nWhich = 0; // geloescht + if( !--nStackCnt ) + return nFound == aCmpSet.Count(); + } + else if( bForward ? pArrPtr->nStt < nEndPos : pArrPtr->nEnd > nSttPos ) + { + // alle die "offen" sind, heisst ueber die Start Position ragen, + // im FndSet setzen + ASSERT( !pFndArr[ n ].nWhich, "Array-Platz ist noch belegt" ); + pFndArr[ n ] = *pArrPtr; + pArrPtr->nWhich = 0; + nFound++; + if( !--nStackCnt ) + return nFound == aCmpSet.Count(); + } + } + return nFound == aCmpSet.Count(); +} + + + +int lcl_SearchForward( const SwTxtNode& rTxtNd, SwAttrCheckArr& rCmpArr, + SwPaM& rPam ) +{ + xub_StrLen nEndPos, nSttPos; + rCmpArr.SetNewSet( rTxtNd, rPam ); + if( !rTxtNd.HasHints() ) + { + if( !rCmpArr.Found() ) + return FALSE; + nEndPos = rCmpArr.GetNdEnd(); + lcl_SetAttrPam( rPam, rCmpArr.GetNdStt(), &nEndPos, TRUE ); + return TRUE; + } + + // dann gehe mal durch das nach "Start" sortierte Array + const SwpHints& rHtArr = rTxtNd.GetSwpHints(); + const SwTxtAttr* pAttr; + USHORT nPos = 0; + + // sollte jetzt schon alles vorhanden sein, dann teste, mit welchem + // das wieder beendet wird. + if( rCmpArr.Found() ) + { + for( ; nPos < rHtArr.Count(); ++nPos ) + if( !rCmpArr.SetAttrFwd( *( pAttr = rHtArr.GetStart( nPos )) ) ) + { + if( rCmpArr.GetNdStt() < *pAttr->GetStart() ) + { + // dann haben wir unser Ende: + lcl_SetAttrPam( rPam, rCmpArr.GetNdStt(), + pAttr->GetStart(), TRUE ); + return TRUE; + } + // ansonsten muessen wir weiter suchen + break; + } + + if( nPos == rHtArr.Count() && rCmpArr.Found() ) + { + // dann haben wir unseren Bereich + nEndPos = rCmpArr.GetNdEnd(); + lcl_SetAttrPam( rPam, rCmpArr.GetNdStt(), &nEndPos, TRUE ); + return TRUE; + } + } + + for( ; nPos < rHtArr.Count(); ++nPos ) + if( rCmpArr.SetAttrFwd( *( pAttr = rHtArr.GetStart( nPos )) ) ) + { + // sollten noch mehr auf der gleichen Position anfangen ?? + // auch die noch mit testen !! + nSttPos = *pAttr->GetStart(); + while( ++nPos < rHtArr.Count() && nSttPos == + *( pAttr = rHtArr.GetStart( nPos ))->GetStart() && + rCmpArr.SetAttrFwd( *pAttr ) ) + ; + if( !rCmpArr.Found() ) + continue; + + // dann haben wir den Bereich zusammen + if( (nSttPos = rCmpArr.Start()) > (nEndPos = rCmpArr.End()) ) + return FALSE; + lcl_SetAttrPam( rPam, nSttPos, &nEndPos, TRUE ); + return TRUE; + } + + if( !rCmpArr.CheckStack() || + (nSttPos = rCmpArr.Start()) > (nEndPos = rCmpArr.End()) ) + return FALSE; + lcl_SetAttrPam( rPam, nSttPos, &nEndPos, TRUE ); + return TRUE; +} + + +int lcl_SearchBackward( const SwTxtNode& rTxtNd, SwAttrCheckArr& rCmpArr, + SwPaM& rPam ) +{ + xub_StrLen nEndPos, nSttPos; + rCmpArr.SetNewSet( rTxtNd, rPam ); + if( !rTxtNd.HasHints() ) + { + if( !rCmpArr.Found() ) + return FALSE; + nEndPos = rCmpArr.GetNdEnd(); + lcl_SetAttrPam( rPam, rCmpArr.GetNdStt(), &nEndPos, FALSE ); + return TRUE; + } + + // dann gehe mal durch das nach "Start" sortierte Array + const SwpHints& rHtArr = rTxtNd.GetSwpHints(); + const SwTxtAttr* pAttr; + USHORT nPos = rHtArr.Count(); + + // sollte jetzt schon alles vorhanden sein, dann teste, mit welchem + // das wieder beendet wird. + if( rCmpArr.Found() ) + { + while( nPos ) + if( !rCmpArr.SetAttrBwd( *( pAttr = rHtArr.GetEnd( --nPos )) ) ) + { + nSttPos = *pAttr->GetAnyEnd(); + if( nSttPos < rCmpArr.GetNdEnd() ) + { + // dann haben wir unser Ende: + nEndPos = rCmpArr.GetNdEnd(); + lcl_SetAttrPam( rPam, nSttPos, &nEndPos, FALSE ); + return TRUE; + } + + // ansonsten muessen wir weiter suchen + break; + } + + if( !nPos && rCmpArr.Found() ) + { + // dann haben wir unseren Bereich + nEndPos = rCmpArr.GetNdEnd(); + lcl_SetAttrPam( rPam, rCmpArr.GetNdStt(), &nEndPos, FALSE ); + return TRUE; + } + } + + while( nPos ) + if( rCmpArr.SetAttrBwd( *( pAttr = rHtArr.GetEnd( --nPos )) ) ) + { + // sollten noch mehr auf der gleichen Position anfangen ?? + // auch die noch mit testen !! + if( nPos ) + { + nEndPos = *pAttr->GetAnyEnd(); + while( --nPos && nEndPos == + *( pAttr = rHtArr.GetEnd( nPos ))->GetAnyEnd() && + rCmpArr.SetAttrBwd( *pAttr ) ) + ; + } + if( !rCmpArr.Found() ) + continue; + + + // dann haben wir den Bereich zusammen + if( (nSttPos = rCmpArr.Start()) > (nEndPos = rCmpArr.End()) ) + return FALSE; + lcl_SetAttrPam( rPam, nSttPos, &nEndPos, FALSE ); + return TRUE; + } + + if( !rCmpArr.CheckStack() || + (nSttPos = rCmpArr.Start()) > (nEndPos = rCmpArr.End()) ) + return FALSE; + lcl_SetAttrPam( rPam, nSttPos, &nEndPos, FALSE ); + return TRUE; +} + + +int lcl_Search( const SwCntntNode& rCNd, SwPaM& rPam, + const SfxItemSet& rCmpSet, BOOL bNoColls ) +{ + // nur die harte Attributierung suchen ? + if( bNoColls && !rCNd.GetpSwAttrSet() ) + return FALSE; + + const SfxItemSet& rNdSet = rCNd.GetSwAttrSet(); + SfxItemIter aIter( rCmpSet ); + const SfxPoolItem* pItem = aIter.GetCurItem(); + const SfxPoolItem* pNdItem; + USHORT nWhich; + + while( TRUE ) + { + // nur testen, ob vorhanden ist ? + if( IsInvalidItem( pItem )) + { + nWhich = rCmpSet.GetWhichByPos( aIter.GetCurPos() ); + if( SFX_ITEM_SET != rNdSet.GetItemState( nWhich, !bNoColls, &pNdItem ) + || CmpAttr( *pNdItem, rNdSet.GetPool()->GetDefaultItem( nWhich ) )) + return FALSE; + } + else + { + nWhich = pItem->Which(); +//JP 27.02.95: wenn nach defaults gesucht wird, dann muss man bis zum Pool +// runter +// if( SFX_ITEM_SET != rNdSet.GetItemState( nWhich, !bNoColls, &pNdItem ) +// || *pNdItem != *pItem ) + if( !CmpAttr( rNdSet.Get( nWhich, !bNoColls ), *pItem )) + return FALSE; + } + + if( aIter.IsAtEnd() ) + break; + pItem = aIter.NextItem(); + } + return TRUE; // wurde gefunden +} + + +FASTBOOL SwPaM::Find( const SfxPoolItem& rAttr, FASTBOOL bValue, SwMoveFn fnMove, + const SwPaM *pRegion, FASTBOOL bInReadOnly ) +{ + // stelle fest welches Attribut gesucht wird: + USHORT nWhich = rAttr.Which(); + int bCharAttr = RES_CHRATR_BEGIN <= nWhich && nWhich < RES_TXTATR_END; + + SwPaM* pPam = MakeRegion( fnMove, pRegion ); + + FASTBOOL bFound = FALSE; + FASTBOOL bFirst = TRUE; + FASTBOOL bSrchForward = fnMove == fnMoveForward; + SwCntntNode * pNode; + const SfxPoolItem* pItem; + SwpFmts aFmtArr; + + // Wenn am Anfang/Ende, aus dem Node moven + if( bSrchForward + ? pPam->GetPoint()->nContent.GetIndex() == pPam->GetCntntNode()->Len() + : !pPam->GetPoint()->nContent.GetIndex() ) + { + if( !(*fnMove->fnNds)( &pPam->GetPoint()->nNode, FALSE )) + { + delete pPam; + return FALSE; + } + SwCntntNode *pNd = pPam->GetCntntNode(); + xub_StrLen nTmpPos = bSrchForward ? 0 : pNd->Len(); + pPam->GetPoint()->nContent.Assign( pNd, nTmpPos ); + } + + while( 0 != ( pNode = ::GetNode( *pPam, bFirst, fnMove, bInReadOnly ) ) ) + { + if( bCharAttr ) + { + if( !pNode->IsTxtNode() ) // CharAttr sind nur in TextNodes + continue; + + if( ((SwTxtNode*)pNode)->HasHints() && + lcl_Search( *(SwTxtNode*)pNode, *pPam, rAttr, fnMove, bValue )) + { + // setze auf die Werte vom Attribut + SetMark(); + *GetPoint() = *pPam->GetPoint(); + *GetMark() = *pPam->GetMark(); + bFound = TRUE; + break; + } + else if( RES_TXTATR_BEGIN < nWhich ) // TextAttribut + continue; // --> also weiter + } + + // keine harte Attributierung, dann pruefe, ob die Vorlage schon + // mal nach dem Attribut befragt wurde + if( !pNode->GetpSwAttrSet() ) + { + const SwFmt* pTmpFmt = pNode->GetFmtColl(); + if( aFmtArr.Count() && aFmtArr.Seek_Entry( pTmpFmt )) + continue; // die Collection wurde schon mal befragt + aFmtArr.Insert( pTmpFmt ); + } + + if( SFX_ITEM_SET == pNode->GetSwAttrSet().GetItemState( nWhich, + TRUE, &pItem ) && ( !bValue || *pItem == rAttr ) ) + { + // FORWARD: Point an das Ende, GetMark zum Anfanf vom Node + // BACKWARD: Point zum Anfang, GetMark an das Ende vom Node + // und immer nach der Logik: inkl. Start, exkl. End !!! + *GetPoint() = *pPam->GetPoint(); + SetMark(); + pNode->MakeEndIndex( &GetPoint()->nContent ); + Move( fnMoveForward, fnGoCntnt ); + bFound = TRUE; + break; + } + } + + // beim rueckwaerts Suchen noch Point und Mark vertauschen + if( bFound && !bSrchForward ) + Exchange(); + + delete pPam; + return bFound; +} + + +typedef int (*FnSearchAttr)( const SwTxtNode&, SwAttrCheckArr&, SwPaM& ); + +FASTBOOL SwPaM::Find( const SfxItemSet& rSet, FASTBOOL bNoColls, SwMoveFn fnMove, + const SwPaM *pRegion, FASTBOOL bInReadOnly ) +{ + SwPaM* pPam = MakeRegion( fnMove, pRegion ); + + FASTBOOL bFound = FALSE; + FASTBOOL bFirst = TRUE; + FASTBOOL bSrchForward = fnMove == fnMoveForward; + SwCntntNode * pNode; + SwpFmts aFmtArr; + + // teste doch mal welche Text/Char-Attribute gesucht werden + SwAttrCheckArr aCmpArr( rSet, bSrchForward, bNoColls ); + SfxItemSet aOtherSet( GetDoc()->GetAttrPool(), + RES_PARATR_BEGIN, RES_GRFATR_END-1 ); + aOtherSet.Put( rSet, FALSE ); // alle Invalid-Items erhalten! + + FnSearchAttr fnSearch = bSrchForward + ? (&::lcl_SearchForward) + : (&::lcl_SearchBackward); + + // Wenn am Anfang/Ende, aus dem Node moven + // Wenn am Anfang/Ende, aus dem Node moven + if( bSrchForward + ? pPam->GetPoint()->nContent.GetIndex() == pPam->GetCntntNode()->Len() + : !pPam->GetPoint()->nContent.GetIndex() ) + { + if( !(*fnMove->fnNds)( &pPam->GetPoint()->nNode, FALSE )) + { + delete pPam; + return FALSE; + } + SwCntntNode *pNd = pPam->GetCntntNode(); + xub_StrLen nTmpPos = bSrchForward ? 0 : pNd->Len(); + pPam->GetPoint()->nContent.Assign( pNd, nTmpPos ); + } + + + while( 0 != ( pNode = ::GetNode( *pPam, bFirst, fnMove, bInReadOnly ) ) ) + { + if( aCmpArr.Count() ) + { + if( !pNode->IsTxtNode() ) // CharAttr sind nur in TextNodes + continue; + + if( (!aOtherSet.Count() || + lcl_Search( *pNode, *pPam, aOtherSet, bNoColls )) && + (*fnSearch)( *(SwTxtNode*)pNode, aCmpArr, *pPam )) + { + // setze auf die Werte vom Attribut + SetMark(); + *GetPoint() = *pPam->GetPoint(); + *GetMark() = *pPam->GetMark(); + bFound = TRUE; + break; + } + continue; // TextAttribute + } + + if( !aOtherSet.Count() ) + continue; + + // keine harte Attributierung, dann pruefe, ob die Vorlage schon + // mal nach dem Attribut befragt wurde + if( !pNode->GetpSwAttrSet() ) + { + const SwFmt* pTmpFmt = pNode->GetFmtColl(); + if( aFmtArr.Count() && aFmtArr.Seek_Entry( pTmpFmt )) + continue; // die Collection wurde schon mal befragt + aFmtArr.Insert( pTmpFmt ); + } + + if( lcl_Search( *pNode, *pPam, aOtherSet, bNoColls )) + { + // FORWARD: Point an das Ende, GetMark zum Anfanf vom Node + // BACKWARD: Point zum Anfang, GetMark an das Ende vom Node + // und immer nach der Logik: inkl. Start, exkl. End !!! + *GetPoint() = *pPam->GetPoint(); + SetMark(); + pNode->MakeEndIndex( &GetPoint()->nContent ); + Move( fnMoveForward, fnGoCntnt ); + bFound = TRUE; + break; + } + } + + // beim rueckwaerts Suchen noch Point und Mark vertauschen + if( bFound && !bSrchForward ) + Exchange(); + + delete pPam; + return bFound; +} + +//------------------ Methoden vom SwCursor --------------------------- + +// Parameter fuer das Suchen vom Attributen +struct SwFindParaAttr : public SwFindParas +{ + BOOL bValue; + const SfxItemSet *pSet, *pReplSet; + const SearchParam *pTxtPara; + SwCursor& rCursor; + SearchText* pSTxt; + + SwFindParaAttr( const SfxItemSet& rSet, BOOL bNoCollection, + const SearchParam* pTextParam, const SfxItemSet* pRSet, + SwCursor& rCrsr ) + : pSet( &rSet ), pReplSet( pRSet ), rCursor( rCrsr ), + bValue( bNoCollection ), pTxtPara( pTextParam ), pSTxt( 0 ) + {} + ~SwFindParaAttr() { delete pSTxt; } + + virtual int Find( SwPaM* , SwMoveFn , const SwPaM*, FASTBOOL bInReadOnly ); + virtual int IsReplaceMode() const; +}; + + +int SwFindParaAttr::Find( SwPaM* pCrsr, SwMoveFn fnMove, const SwPaM* pRegion, + FASTBOOL bInReadOnly ) +{ + // String ersetzen ?? (nur wenn Text angegeben oder nicht attributiert + // gesucht wird) + BOOL bReplaceTxt = pTxtPara && ( pTxtPara->GetReplaceStr().Len() || + !pSet->Count() ); + BOOL bReplaceAttr = pReplSet && pReplSet->Count(); + if( bInReadOnly && (bReplaceAttr || bReplaceTxt )) + bInReadOnly = FALSE; + + // wir suchen nach Attributen, soll zusaetzlich Text gesucht werden ? + { + SwPaM aRegion( *pRegion->GetMark(), *pRegion->GetPoint() ); + SwPaM* pTextRegion = &aRegion; + + while( TRUE ) + { + if( pSet->Count() ) // gibts ueberhaupt Attributierung? + { + // zuerst die Attributierung + if( !pCrsr->Find( *pSet, bValue, fnMove, &aRegion, bInReadOnly ) ) +//JP 17.11.95: was ist mit Attributen in leeren Absaetzen !! +// || *pCrsr->GetMark() == *pCrsr->GetPoint() ) // kein Bereich ?? + return FIND_NOT_FOUND; + + if( !pTxtPara ) + break; // ok, nur Attribute, also gefunden + + pTextRegion = pCrsr; + } + else if( !pTxtPara ) + return FIND_NOT_FOUND; + + // dann darin den Text + if( !pSTxt ) + { + SearchParam aTmp( *pTxtPara ); + aTmp.SetSrchInSelection( TRUE ); + pSTxt = new SearchText( aTmp, Application::GetAppInternational()); + } + // Bug 24665: suche im richtigen Bereich weiter (pTextRegion!) + if( pCrsr->Find( *pTxtPara, *pSTxt, fnMove, pTextRegion, bInReadOnly ) && + *pCrsr->GetMark() != *pCrsr->GetPoint() ) // gefunden ? + break; // also raus + else if( !pSet->Count() ) + return FIND_NOT_FOUND; // nur Text und nicht gefunden + + // und wieder neu aufsetzen, aber eine Position weiter + //JP 04.11.97: Bug 44897 - aber den Mark wieder aufheben, damit + // weiterbewegt werden kann! + { + BOOL bCheckRegion = TRUE; + SwPosition* pPos = pCrsr->GetPoint(); + if( !(*fnMove->fnNd)( &pPos->nNode.GetNode(), &pPos->nContent )) + { + if( (*fnMove->fnNds)( &pPos->nNode, FALSE )) + { + SwCntntNode *pNd = pPos->nNode.GetNode().GetCntntNode(); + xub_StrLen nCPos; + if( fnMove == fnMoveForward ) + nCPos = 0; + else + nCPos = pNd->Len(); + pPos->nContent.Assign( pNd, nCPos ); + } + else + bCheckRegion = FALSE; + } + if( !bCheckRegion || *aRegion.GetPoint() <= *pPos ) + return FIND_NOT_FOUND; // nicht gefunden + } + *aRegion.GetMark() = *pCrsr->GetPoint(); + } + } + + if( bReplaceTxt ) + { + int bRegExp = SearchParam::SRCH_REGEXP == pTxtPara->GetSrchType(); + SwIndex& rSttCntIdx = pCrsr->Start()->nContent; + xub_StrLen nSttCnt = rSttCntIdx.GetIndex(); + + // damit die Region auch verschoben wird, in den Shell-Cursr-Ring + // mit aufnehmen !! + Ring *pPrev; + if( bRegExp ) + { + pPrev = pRegion->GetPrev(); + ((Ring*)pRegion)->MoveRingTo( &rCursor ); + } + + rCursor.GetDoc()->Replace( *pCrsr, pTxtPara->GetReplaceStr(), bRegExp ); + rCursor.SaveTblBoxCntnt( pCrsr->GetPoint() ); + + if( bRegExp ) + { + // und die Region wieder herausnehmen: + Ring *p, *pNext = (Ring*)pRegion; + do { + p = pNext; + pNext = p->GetNext(); + p->MoveTo( (Ring*)pRegion ); + } while( p != pPrev ); + } + rSttCntIdx = nSttCnt; + } + + if( bReplaceAttr ) + { + // --- Ist die Selection noch da ?????? + + // und noch die Attribute setzen +#ifdef OLD + pCrsr->GetDoc()->Insert( *pCrsr, *pReplSet ); +#else + //JP 13.07.95: alle gesuchten Attribute werden, wenn nicht im + // ReplaceSet angegeben, auf Default zurueck gesetzt + + if( !pSet->Count() ) + pCrsr->GetDoc()->Insert( *pCrsr, *pReplSet ); + else + { + SfxItemPool* pPool = pReplSet->GetPool(); + SfxItemSet aSet( *pPool, pReplSet->GetRanges() ); + + SfxItemIter aIter( *pSet ); + const SfxPoolItem* pItem = aIter.GetCurItem(); + while( TRUE ) + { + // alle die nicht gesetzt sind mit Pool-Defaults aufuellen + if( !IsInvalidItem( pItem ) && SFX_ITEM_SET != + pReplSet->GetItemState( pItem->Which(), FALSE )) + aSet.Put( pPool->GetDefaultItem( pItem->Which() )); + + if( aIter.IsAtEnd() ) + break; + pItem = aIter.NextItem(); + } + aSet.Put( *pReplSet ); + pCrsr->GetDoc()->Insert( *pCrsr, aSet ); + } +#endif + return FIND_NO_RING; + } + + else + return FIND_FOUND; +} + + +int SwFindParaAttr::IsReplaceMode() const +{ + return ( pTxtPara && pTxtPara->GetReplaceStr().Len() ) || + ( pReplSet && pReplSet->Count() ); +} + +// Suchen nach Attributen + + +ULONG SwCursor::Find( const SfxItemSet& rSet, FASTBOOL bNoCollections, + SwDocPositions nStart, SwDocPositions nEnde, + FindRanges eFndRngs, + const SearchParam* pTextPara, const SfxItemSet* pReplSet ) +{ + // OLE-Benachrichtigung abschalten !! + SwDoc* pDoc = GetDoc(); + Link aLnk( pDoc->GetOle2Link() ); + pDoc->SetOle2Link( Link() ); + + BOOL bReplace = ( pTextPara && ( pTextPara->GetReplaceStr().Len() || + !rSet.Count() ) ) || + (pReplSet && pReplSet->Count()); + BOOL bSttUndo = pDoc->DoesUndo() && bReplace; + if( bSttUndo ) + pDoc->StartUndo( UNDO_REPLACE ); + + SwFindParaAttr aSwFindParaAttr( rSet, bNoCollections, pTextPara, + pReplSet, *this ); + + ULONG nRet = FindAll(aSwFindParaAttr, nStart, nEnde, eFndRngs ); + pDoc->SetOle2Link( aLnk ); + if( nRet && bReplace ) + pDoc->SetModified(); + + if( bSttUndo ) + pDoc->EndUndo( UNDO_REPLACE ); + + return nRet; +} + + + diff --git a/sw/source/core/crsr/findcoll.cxx b/sw/source/core/crsr/findcoll.cxx new file mode 100644 index 000000000000..21618cbee166 --- /dev/null +++ b/sw/source/core/crsr/findcoll.cxx @@ -0,0 +1,153 @@ +/************************************************************************* + * + * $RCSfile: findcoll.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:17 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _SWCRSR_HXX +#include +#endif +#ifndef _DOC_HXX +#include +#endif +#ifndef _PAMTYP_HXX +#include +#endif +#ifndef _SWUNDO_HXX +#include +#endif + + +//------------------ Methoden der CrsrShell --------------------------- + +// Parameter fuer das Suchen vom FormatCollections +struct SwFindParaFmtColl : public SwFindParas +{ + const SwTxtFmtColl *pFmtColl, *pReplColl; + SwCursor& rCursor; + SwFindParaFmtColl( const SwTxtFmtColl& rFmtColl, + const SwTxtFmtColl* pRpColl, SwCursor& rCrsr ) + : rCursor( rCrsr ), pFmtColl( &rFmtColl ), pReplColl( pRpColl ) + {} + virtual int Find( SwPaM* , SwMoveFn , const SwPaM*, FASTBOOL bInReadOnly ); + virtual int IsReplaceMode() const; +}; + + +int SwFindParaFmtColl::Find( SwPaM* pCrsr, SwMoveFn fnMove, const SwPaM* pRegion, + FASTBOOL bInReadOnly ) +{ + int nRet = FIND_FOUND; + if( bInReadOnly && pReplColl ) + bInReadOnly = FALSE; + + if( !pCrsr->Find( *pFmtColl, fnMove, pRegion, bInReadOnly ) ) + nRet = FIND_NOT_FOUND; + else if( pReplColl ) + { + pCrsr->GetDoc()->SetTxtFmtColl( *pCrsr, (SwTxtFmtColl*)pReplColl ); + nRet = FIND_NO_RING; + } + return nRet; +} + + +int SwFindParaFmtColl::IsReplaceMode() const +{ + return 0 != pReplColl; +} + + +// Suchen nach Format-Collections + + +ULONG SwCursor::Find( const SwTxtFmtColl& rFmtColl, + SwDocPositions nStart, SwDocPositions nEnde, + FindRanges eFndRngs, const SwTxtFmtColl* pReplFmtColl ) +{ + // OLE-Benachrichtigung abschalten !! + SwDoc* pDoc = GetDoc(); + Link aLnk( pDoc->GetOle2Link() ); + pDoc->SetOle2Link( Link() ); + + BOOL bSttUndo = pDoc->DoesUndo() && pReplFmtColl; + if( bSttUndo ) + pDoc->StartUndo( UNDO_REPLACE ); + + SwFindParaFmtColl aSwFindParaFmtColl( rFmtColl, pReplFmtColl, *this ); + + ULONG nRet = FindAll( aSwFindParaFmtColl, nStart, nEnde, eFndRngs ); + pDoc->SetOle2Link( aLnk ); + + if( nRet && pReplFmtColl ) + pDoc->SetModified(); + + if( bSttUndo ) + pDoc->EndUndo( UNDO_REPLACE ); + + return nRet; +} + + + diff --git a/sw/source/core/crsr/findfmt.cxx b/sw/source/core/crsr/findfmt.cxx new file mode 100644 index 000000000000..303bff4974ef --- /dev/null +++ b/sw/source/core/crsr/findfmt.cxx @@ -0,0 +1,124 @@ +/************************************************************************* + * + * $RCSfile: findfmt.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:17 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _DOC_HXX +#include +#endif +#ifndef _PAMTYP_HXX +#include +#endif + + +FASTBOOL SwPaM::Find( const SwFmt& rFmt, SwMoveFn fnMove, + const SwPaM *pRegion, FASTBOOL bInReadOnly ) +{ + FASTBOOL bFound = FALSE; + FASTBOOL bSrchForward = fnMove == fnMoveForward; + SwPaM* pPam = MakeRegion( fnMove, pRegion ); + + // Wenn am Anfang/Ende, aus dem Node moven + if( bSrchForward + ? pPam->GetPoint()->nContent.GetIndex() == pPam->GetCntntNode()->Len() + : !pPam->GetPoint()->nContent.GetIndex() ) + { + if( !(*fnMove->fnNds)( &pPam->GetPoint()->nNode, FALSE )) + { + delete pPam; + return FALSE; + } + SwCntntNode *pNd = pPam->GetPoint()->nNode.GetNode().GetCntntNode(); + xub_StrLen nTmpPos = bSrchForward ? 0 : pNd->Len(); + pPam->GetPoint()->nContent.Assign( pNd, nTmpPos ); + } + + FASTBOOL bFirst = TRUE; + SwCntntNode* pNode; + while( !bFound && + 0 != ( pNode = ::GetNode( *pPam, bFirst, fnMove, bInReadOnly ))) + { + if( 0 != ( bFound = pNode->GetFmtColl() == &rFmt )) + { + // wurde die FormatCollection gefunden, dann handelt es sich auf + // jedenfall um einen SwCntntNode !! + + // FORWARD: SPoint an das Ende, GetMark zum Anfanf vom Node + // BACKWARD: SPoint zum Anfang, GetMark an das Ende vom Node + // und immer nach der Logik: inkl. Start, exkl. End !!! + *GetPoint() = *pPam->GetPoint(); + SetMark(); + pNode->MakeEndIndex( &GetPoint()->nContent ); + GetMark()->nContent = 0; + if( !bSrchForward ) // rueckwaerts Suche? + Exchange(); // SPoint und GetMark tauschen + break; + } + } + delete pPam; + return bFound; +} + + diff --git a/sw/source/core/crsr/findtxt.cxx b/sw/source/core/crsr/findtxt.cxx new file mode 100644 index 000000000000..708c1218a6f1 --- /dev/null +++ b/sw/source/core/crsr/findtxt.cxx @@ -0,0 +1,421 @@ +/************************************************************************* + * + * $RCSfile: findtxt.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:17 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#define _SVSTDARR_ULONGS +#include + +#ifndef _SV_SVAPP_HXX //autogen wg. Application +#include +#endif + +#ifndef _FLDBAS_HXX //autogen +#include +#endif +#ifndef _FMTFLD_HXX //autogen +#include +#endif +#ifndef _TXTATR_HXX //autogen +#include +#endif +#ifndef _TXTFLD_HXX //autogen +#include +#endif +#ifndef _SWCRSR_HXX +#include +#endif +#ifndef _DOC_HXX +#include +#endif +#ifndef _PAMTYP_HXX +#include +#endif +#ifndef _NDTXT_HXX +#include +#endif +#ifndef _SWUNDO_HXX +#include +#endif + +String& lcl_CleanStr( const SwTxtNode& rNd, xub_StrLen nStart, + xub_StrLen& rEnde, SvULongs& rArr, String& rRet ) +{ + rRet = rNd.GetTxt(); + if( rArr.Count() ) + rArr.Remove( 0, rArr.Count() ); + + const SwpHints *pHts = rNd.GetpSwpHints(); + if( pHts ) + { + SvULongs aReplaced; + + for( USHORT n = 0; n < pHts->Count(); ++n ) + { + const SwTxtAttr *pHt = (*pHts)[n]; + + if( pHt->GetEnd() ) // nur Attribute ohne Ende + continue; + + register xub_StrLen nStt = *pHt->GetStart(); + if( nStt < nStart ) + continue; + + const xub_StrLen nAkt = nStt - rArr.Count(); + + //JP 17.05.00: Task 75806 ask for ">=" and not for ">" + if( nAkt >= rEnde ) // uebers Ende hinaus = + break; // das wars + + switch( pHt->Which() ) + { + case RES_TXTATR_FLYCNT: + case RES_TXTATR_FTN: + case RES_TXTATR_FIELD: + case RES_TXTATR_REFMARK: + case RES_TXTATR_TOXMARK: + { +// JP 06.05.98: mit Bug 50100 werden sie als Trenner erwuenscht und nicht +// mehr zum Wort dazu gehoerend. +// MA 23.06.98: mit Bug 51215 sollen sie konsequenterweise auch am +// Satzanfang und -ende ignoriert werden wenn sie Leer sind. +// Dazu werden sie schlicht entfernt. Fuer den Anfang entfernen +// wir sie einfach. +// Fuer das Ende merken wir uns die Ersetzungen und entferenen +// hinterher alle am Stringende (koenten ja 'normale' 0x7f drinstehen + BOOL bEmpty = RES_TXTATR_FIELD != pHt->Which() || + !((SwTxtFld*)pHt)->GetFld().GetFld()->Expand().Len(); + if ( bEmpty && nStart == nAkt ) + { + rArr.Insert( nAkt, rArr.Count() ); + --rEnde; + rRet.Erase( nAkt, 1 ); + } + else + { + if ( bEmpty ) + aReplaced.Insert( nAkt, aReplaced.Count() ); + rRet.SetChar( nAkt, '\x7f' ); + } + } + break; + + case RES_TXTATR_HARDBLANK: + rRet.SetChar( nAkt, ((SwTxtHardBlank*)pHt)->GetChar() ); + break; + default: + { + rArr.Insert( nAkt, rArr.Count() ); + --rEnde; + rRet.Erase( nAkt, 1 ); + } + break; + } + } + for( USHORT i = aReplaced.Count(); i; ) + { + const xub_StrLen nTmp = aReplaced[ --i ]; + if( nTmp == rRet.Len()-1 ) + { + rRet.Erase( nTmp ); + rArr.Insert( nTmp, rArr.Count() ); + --rEnde; + } + } + } + + return rRet; +} + + + +BYTE SwPaM::Find( const SearchParam& rParam, SearchText& rSTxt, + SwMoveFn fnMove, const SwPaM * pRegion, + FASTBOOL bInReadOnly ) +{ + if( !rParam.GetSrchStr().Len() ) + return FALSE; + + SwPaM* pPam = MakeRegion( fnMove, pRegion ); + FASTBOOL bSrchForward = fnMove == fnMoveForward; + SwNodeIndex& rNdIdx = pPam->GetPoint()->nNode; + SwIndex& rCntntIdx = pPam->GetPoint()->nContent; + + // Wenn am Anfang/Ende, aus dem Node moven + // beim leeren Node nicht weiter + if( bSrchForward + ? ( rCntntIdx.GetIndex() == pPam->GetCntntNode()->Len() && + rCntntIdx.GetIndex() ) + : !rCntntIdx.GetIndex() && pPam->GetCntntNode()->Len() ) + { + if( !(*fnMove->fnNds)( &rNdIdx, FALSE )) + { + delete pPam; + return FALSE; + } + SwCntntNode *pNd = rNdIdx.GetNode().GetCntntNode(); + xub_StrLen nTmpPos = bSrchForward ? 0 : pNd->Len(); + rCntntIdx.Assign( pNd, nTmpPos ); + } + + /* + * Ist bFound == TRUE, dann wurde der String gefunden und in + * nStart und nEnde steht der gefundenen String + */ + BOOL bFound = FALSE; + /* + * StartPostion im Text oder Anfangsposition + */ + FASTBOOL bFirst = TRUE; + SwCntntNode * pNode; + String sCleanStr; + SvULongs aFltArr; + + xub_StrLen nStart, nEnde, nTxtLen; + const SwNode* pSttNd = &rNdIdx.GetNode(); + xub_StrLen nSttCnt = rCntntIdx.GetIndex(); + + while( 0 != ( pNode = ::GetNode( *pPam, bFirst, fnMove, bInReadOnly ) )) + { + if( pNode->IsTxtNode() ) + { + nTxtLen = ((SwTxtNode*)pNode)->GetTxt().Len(); + if( rNdIdx == pPam->GetMark()->nNode ) + nEnde = pPam->GetMark()->nContent.GetIndex(); + else + nEnde = bSrchForward ? nTxtLen : 0; + nStart = rCntntIdx.GetIndex(); + + if( bSrchForward ) + lcl_CleanStr( *(SwTxtNode*)pNode, nStart, nEnde, + aFltArr, sCleanStr ); + else + lcl_CleanStr( *(SwTxtNode*)pNode, nEnde, nStart, + aFltArr, sCleanStr ); + + if( (rSTxt.*fnMove->fnSearch)( sCleanStr, &nStart, &nEnde )) + { + // setze den Bereich richtig + *GetPoint() = *pPam->GetPoint(); + SetMark(); + // Start und Ende wieder korrigieren !! + if( aFltArr.Count() ) + { + xub_StrLen n, nNew; + // bei Rueckwaertssuche die Positionen temp. vertauschen + if( !bSrchForward ) { n = nStart; nStart = nEnde; nEnde = n; } + + for( n = 0, nNew = nStart; + n < aFltArr.Count() && aFltArr[ n ] <= nStart; + ++n, ++nNew ) + ; + nStart = nNew; + for( n = 0, nNew = nEnde; + n < aFltArr.Count() && aFltArr[ n ] <= nEnde; + ++n, ++nNew ) + ; + nEnde = nNew; + + // bei Rueckwaertssuche die Positionen temp. vertauschen + if( !bSrchForward ) { n = nStart; nStart = nEnde; nEnde = n; } + } + GetMark()->nContent = nStart; // Startposition setzen + + // kein Bereich selektiert und am Anfng/Ende ? ueber den + // Absatz selektieren + if( (!nStart && !((USHORT)(nEnde+1))) || // fuer 0 und -1 ! + ( nStart > nEnde )) + { + // nicht von der Start Position entfernt + if( pSttNd == &rNdIdx.GetNode() && nSttCnt == nStart + && ( !bSrchForward || nStart || nTxtLen )) + continue; + + GetPoint()->nContent = nStart; + if( ( !nStart || nStart == nTxtLen ) && + !Move( fnMoveForward, fnGoCntnt ) ) + continue; + } + else + { + GetPoint()->nContent = nEnde; + if( !Move( fnMoveForward, fnGoCntnt ) ) + GetPoint()->nContent = nTxtLen; + } + if( SearchParam::SRCH_REGEXP == rParam.GetSrchType() && + 1 < Abs( (int)(GetPoint()->nNode.GetIndex() - GetMark()->nNode.GetIndex()))) + // Fehler: es koennen maximal 2 Nodes selektiert werden !! + continue; + + if( !bSrchForward ) // rueckwaerts Suche? + Exchange(); // Point und Mark tauschen + bFound = TRUE; + break; + } + } + } + delete pPam; + return bFound; +} + + +// Parameter fuers Suchen und Ersetzen von Text +struct SwFindParaText : public SwFindParas +{ + const SearchParam& rParam; + SwCursor& rCursor; + SearchText aSTxt; + BOOL bReplace; + + SwFindParaText( const SearchParam& rPara, int bRepl, SwCursor& rCrsr ) + : rCursor( rCrsr ), bReplace( bRepl ), rParam( rPara ), + aSTxt( rPara, Application::GetAppInternational() ) + {} + virtual int Find( SwPaM* , SwMoveFn , const SwPaM*, FASTBOOL bInReadOnly ); + virtual int IsReplaceMode() const; +}; + + +int SwFindParaText::Find( SwPaM* pCrsr, SwMoveFn fnMove, + const SwPaM* pRegion, FASTBOOL bInReadOnly ) +{ + if( bInReadOnly && bReplace ) + bInReadOnly = FALSE; + + BOOL bFnd = (BOOL)pCrsr->Find( rParam, aSTxt, fnMove, pRegion, bInReadOnly ); + // kein Bereich ?? + if( bFnd && *pCrsr->GetMark() == *pCrsr->GetPoint() ) + return FIND_NOT_FOUND; + + if( bFnd && bReplace ) // String ersetzen ?? + { + // Replace-Methode vom SwDoc benutzen + int bRegExp = SearchParam::SRCH_REGEXP == rParam.GetSrchType(); + SwIndex& rSttCntIdx = pCrsr->Start()->nContent; + xub_StrLen nSttCnt = rSttCntIdx.GetIndex(); + // damit die Region auch verschoben wird, in den Shell-Cursr-Ring + // mit aufnehmen !! + Ring *pPrev; + if( bRegExp ) + { + pPrev = pRegion->GetPrev(); + ((Ring*)pRegion)->MoveRingTo( &rCursor ); + } + + rCursor.GetDoc()->Replace( *pCrsr, rParam.GetReplaceStr(), bRegExp ); + rCursor.SaveTblBoxCntnt( pCrsr->GetPoint() ); + + if( bRegExp ) + { + // und die Region wieder herausnehmen: + Ring *p, *pNext = (Ring*)pRegion; + do { + p = pNext; + pNext = p->GetNext(); + p->MoveTo( (Ring*)pRegion ); + } while( p != pPrev ); + } + rSttCntIdx = nSttCnt; + return FIND_NO_RING; + } + return bFnd ? FIND_FOUND : FIND_NOT_FOUND; +} + + +int SwFindParaText::IsReplaceMode() const +{ + return bReplace; +} + + +ULONG SwCursor::Find( const SearchParam& rParam, + SwDocPositions nStart, SwDocPositions nEnde, + FindRanges eFndRngs, int bReplace ) +{ + // OLE-Benachrichtigung abschalten !! + SwDoc* pDoc = GetDoc(); + Link aLnk( pDoc->GetOle2Link() ); + pDoc->SetOle2Link( Link() ); + + BOOL bSttUndo = pDoc->DoesUndo() && bReplace; + if( bSttUndo ) + pDoc->StartUndo( UNDO_REPLACE ); + + if( rParam.IsSrchInSelection() ) + eFndRngs = (FindRanges)(eFndRngs | FND_IN_SEL); + SwFindParaText aSwFindParaText( rParam, bReplace, *this ); + ULONG nRet = FindAll( aSwFindParaText, nStart, nEnde, eFndRngs ); + pDoc->SetOle2Link( aLnk ); + if( nRet && bReplace ) + pDoc->SetModified(); + + if( bSttUndo ) + pDoc->EndUndo( UNDO_REPLACE ); + + return nRet; +} + + + diff --git a/sw/source/core/crsr/makefile.mk b/sw/source/core/crsr/makefile.mk new file mode 100644 index 000000000000..f73cc8dd09e1 --- /dev/null +++ b/sw/source/core/crsr/makefile.mk @@ -0,0 +1,148 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-19 00:08:17 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (the "License"); You may not use this file +# except in compliance with the License. You may obtain a copy of the +# License at http://www.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=sw +TARGET=crsr + +AUTOSEG=true + +PROJECTPCH=core_pch +PDBTARGET=core_pch +PROJECTPCHSOURCE=..$/core_1st$/core_pch + +# --- Settings ----------------------------------------------------- + +.INCLUDE : $(PRJ)$/inc$/swpre.mk +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/inc$/sw.mk + +.IF "$(mydebug)" != "" +CDEFS+=-Dmydebug +.ENDIF + +# --- Files -------------------------------------------------------- + +CXXFILES = \ + bookmrk.cxx \ + callnk.cxx \ + crbm.cxx \ + crsrsh.cxx \ + crstrvl.cxx \ + crstrvl1.cxx \ + findattr.cxx \ + findcoll.cxx \ + findfmt.cxx \ + findtxt.cxx \ + pam.cxx \ + paminit.cxx \ + swcrsr.cxx \ + trvlcol.cxx \ + trvlfnfl.cxx \ + trvlreg.cxx \ + trvltbl.cxx \ + unocrsr.cxx \ + viscrs.cxx + +.IF "$(GUI)"=="MAC" +CXXFILES += \ + crsrsh1.cxx +.ENDIF +.IF "$(mydebug)" != "" +CXXFILES += \ + pamio.cxx +.ENDIF + +SLOFILES = \ + $(SLO)$/bookmrk.obj \ + $(SLO)$/callnk.obj \ + $(SLO)$/crbm.obj \ + $(SLO)$/crsrsh.obj \ + $(SLO)$/crstrvl.obj \ + $(SLO)$/crstrvl1.obj \ + $(SLO)$/findattr.obj \ + $(SLO)$/findcoll.obj \ + $(SLO)$/findfmt.obj \ + $(SLO)$/findtxt.obj \ + $(SLO)$/pam.obj \ + $(SLO)$/paminit.obj \ + $(SLO)$/swcrsr.obj \ + $(SLO)$/trvlcol.obj \ + $(SLO)$/trvlfnfl.obj \ + $(SLO)$/trvlreg.obj \ + $(SLO)$/trvltbl.obj \ + $(SLO)$/unocrsr.obj \ + $(SLO)$/viscrs.obj + +.IF "$(GUI)"=="MAC" +SLOFILES += \ + $(SLO)$/crsrsh1.obj +.ENDIF +.IF "$(mydebug)" != "" +SLOFILES += \ + $(SLO)$/pamio.obj +.ENDIF + +# --- Tagets ------------------------------------------------------- + +.INCLUDE : target.mk diff --git a/sw/source/core/crsr/pam.cxx b/sw/source/core/crsr/pam.cxx new file mode 100644 index 000000000000..be57513984fe --- /dev/null +++ b/sw/source/core/crsr/pam.cxx @@ -0,0 +1,993 @@ +/************************************************************************* + * + * $RCSfile: pam.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:17 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _HINTIDS_HXX +#include +#endif + +#ifndef _SVX_PROTITEM_HXX //autogen +#include +#endif + +#ifndef _CNTFRM_HXX +#include +#endif +#ifndef _PAGEFRM_HXX +#include +#endif +#ifndef _DOC_HXX +#include +#endif +#ifndef _DOCARY_HXX +#include +#endif +#ifndef _PAM_HXX +#include +#endif +#ifndef _NODE_HXX +#include +#endif +#ifndef _PAMTYP_HXX +#include +#endif +#ifndef _TXTFRM_HXX +#include +#endif +#ifndef _SECTION_HXX +#include +#endif +#ifndef _FMTCNTNT_HXX //autogen +#include +#endif +#ifndef _FRMATR_HXX +#include +#endif +#ifndef _SWTABLE_HXX +#include +#endif + + +// fuer den dummen ?MSC-? Compiler +inline xub_StrLen GetSttOrEnd( BOOL bCondition, const SwCntntNode& rNd ) +{ + return bCondition ? 0 : rNd.Len(); +} + +/************************************************************************* +|* +|* SwPosition +|* +|* Beschreibung PAM.DOC +|* Ersterstellung VB 4.3.91 +|* Letzte Aenderung VB 4.3.91 +|* +*************************************************************************/ + + +SwPosition::SwPosition(const SwPosition &rPos) + : nNode(rPos.nNode),nContent(rPos.nContent) +{ +} + + +SwPosition::SwPosition( const SwNodeIndex &rNode, const SwIndex &rCntnt ) + : nNode( rNode ),nContent( rCntnt ) +{ +} + +SwPosition::SwPosition( const SwNodeIndex &rNode ) + : nNode( rNode ), nContent( 0 ) +{ +} + +SwPosition::SwPosition( const SwNode& rNode ) + : nNode( rNode ), nContent( 0 ) +{ +} + + +SwPosition &SwPosition::operator=(const SwPosition &rPos) +{ + nNode = rPos.nNode; + nContent = rPos.nContent; + return *this; +} + + +FASTBOOL SwPosition::operator<(const SwPosition &rPos) const +{ + if( nNode < rPos.nNode ) + return TRUE; + if( nNode == rPos.nNode ) + return ( nContent < rPos.nContent ); + return FALSE; +} + + +FASTBOOL SwPosition::operator>(const SwPosition &rPos) const +{ + if(nNode > rPos.nNode ) + return TRUE; + if( nNode == rPos.nNode ) + return ( nContent > rPos.nContent ); + return FALSE; +} + + +FASTBOOL SwPosition::operator<=(const SwPosition &rPos) const +{ + if(nNode < rPos.nNode ) + return TRUE; + if( nNode == rPos.nNode ) + return ( nContent <= rPos.nContent ); + return FALSE; +} + + +FASTBOOL SwPosition::operator>=(const SwPosition &rPos) const +{ + if(nNode > rPos.nNode ) + return TRUE; + if( nNode == rPos.nNode ) + return ( nContent >= rPos.nContent ); + return FALSE; +} + + +FASTBOOL SwPosition::operator==(const SwPosition &rPos) const +{ + return + ( ( nNode == rPos.nNode ) && ( nContent == rPos.nContent ) ? + TRUE: FALSE); +} + + +FASTBOOL SwPosition::operator!=(const SwPosition &rPos) const +{ + if( nNode != rPos.nNode ) + return TRUE; + return ( nContent != rPos.nContent ); +} + +SwComparePosition ComparePosition( + const SwPosition& rStt1, const SwPosition& rEnd1, + const SwPosition& rStt2, const SwPosition& rEnd2 ) +{ + SwComparePosition nRet; + if( rStt1 < rStt2 ) + { + if( rEnd1 > rStt2 ) + { + if( rEnd1 >= rEnd2 ) + nRet = POS_OUTSIDE; + else + nRet = POS_OVERLAP_BEFORE; + + } + else + nRet = POS_BEFORE; + } + else if( rEnd2 > rStt1 ) + { + if( rEnd2 >= rEnd1 ) + { + if( rEnd2 == rEnd1 && rStt2 == rStt1 ) + nRet = POS_EQUAL; + else + nRet = POS_INSIDE; + } + else + nRet = POS_OVERLAP_BEHIND; + } + else + nRet = POS_BEHIND; + return nRet; +} + +/* */ + +enum CHKSECTION { Chk_Both, Chk_One, Chk_None }; + + +CHKSECTION lcl_TstIdx( ULONG nSttIdx, ULONG nEndIdx, const SwNode& rEndNd ) +{ + ULONG nStt = rEndNd.StartOfSectionIndex(), nEnd = rEndNd.GetIndex(); + CHKSECTION eSec = nStt < nSttIdx && nEnd >= nSttIdx ? Chk_One : Chk_None; + if( nStt < nEndIdx && nEnd >= nEndIdx ) + return( eSec == Chk_One ? Chk_Both : Chk_One ); + return eSec; +} + + +FASTBOOL lcl_ChkOneRange( CHKSECTION eSec, BOOL bChkSections, + const SwNode& rBaseEnd, ULONG nStt, ULONG nEnd ) +{ + if( eSec != Chk_Both ) + return FALSE; + + if( !bChkSections ) + return TRUE; + + // suche die umspannende Section + const SwNodes& rNds = rBaseEnd.GetNodes(); + const SwNode *pTmp, *pNd = rNds[ nStt ]; + if( !pNd->IsStartNode() ) + pNd = pNd->StartOfSectionNode(); + + if( pNd == rNds[ nEnd ]->StartOfSectionNode() ) + return TRUE; // der gleiche StartNode, die selbe Section + + // steht schon auf einem GrundSection Node ? Fehler !!! + if( !pNd->StartOfSectionIndex() ) + return FALSE; + + while( ( pTmp = pNd->StartOfSectionNode())->EndOfSectionNode() != + &rBaseEnd ) + pNd = pTmp; + + ULONG nSttIdx = pNd->GetIndex(), nEndIdx = pNd->EndOfSectionIndex(); + return nSttIdx <= nStt && nStt <= nEndIdx && + nSttIdx <= nEnd && nEnd <= nEndIdx ? TRUE : FALSE; +} + + +FASTBOOL CheckNodesRange( const SwNodeIndex& rStt, + const SwNodeIndex& rEnd, FASTBOOL bChkSection ) +{ + const SwNodes& rNds = rStt.GetNodes(); + ULONG nStt = rStt.GetIndex(), nEnd = rEnd.GetIndex(); + CHKSECTION eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfContent() ); + if( Chk_None != eSec ) return eSec == Chk_Both ? TRUE : FALSE; + + eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfAutotext() ); + if( Chk_None != eSec ) + return lcl_ChkOneRange( eSec, bChkSection, + rNds.GetEndOfAutotext(), nStt, nEnd ); + + eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfPostIts() ); + if( Chk_None != eSec ) + return lcl_ChkOneRange( eSec, bChkSection, + rNds.GetEndOfPostIts(), nStt, nEnd ); + + eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfInserts() ); + if( Chk_None != eSec ) + return lcl_ChkOneRange( eSec, bChkSection, + rNds.GetEndOfInserts(), nStt, nEnd ); + + eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfRedlines() ); + if( Chk_None != eSec ) + return lcl_ChkOneRange( eSec, bChkSection, + rNds.GetEndOfRedlines(), nStt, nEnd ); + + return FALSE; // liegt irgendwo dazwischen, FEHLER +} + + +FASTBOOL GoNext(SwNode* pNd, SwIndex * pIdx ) +{ + if( pNd->IsCntntNode() ) + return ((SwCntntNode*)pNd)->GoNext( pIdx ); + return FALSE; +} + + +FASTBOOL GoPrevious(SwNode* pNd, SwIndex * pIdx) +{ + if( pNd->IsCntntNode() ) + return ((SwCntntNode*)pNd)->GoPrevious( pIdx ); + return FALSE; +} + + +SwCntntNode* GoNextNds( SwNodeIndex* pIdx, FASTBOOL bChk ) +{ + SwNodeIndex aIdx( *pIdx ); + SwCntntNode* pNd = aIdx.GetNodes().GoNext( &aIdx ); + if( pNd ) + { + if( bChk && 1 != aIdx.GetIndex() - pIdx->GetIndex() && + !CheckNodesRange( *pIdx, aIdx, TRUE ) ) + pNd = 0; + else + *pIdx = aIdx; + } + return pNd; +} + + +SwCntntNode* GoPreviousNds( SwNodeIndex * pIdx, FASTBOOL bChk ) +{ + SwNodeIndex aIdx( *pIdx ); + SwCntntNode* pNd = aIdx.GetNodes().GoPrevious( &aIdx ); + if( pNd ) + { + if( bChk && 1 != pIdx->GetIndex() - aIdx.GetIndex() && + !CheckNodesRange( *pIdx, aIdx, TRUE ) ) + pNd = 0; + else + *pIdx = aIdx; + } + return pNd; +} + +// ---------------------------------------------------------------------- + +/************************************************************************* +|* +|* SwPointAndMark +|* +|* Beschreibung PAM.DOC +|* Ersterstellung VB 4.3.91 +|* Letzte Aenderung JP 6.5.91 +|* +*************************************************************************/ + +SwPaM::SwPaM( const SwPosition& rPos, SwPaM* pRing ) + : aBound1( rPos ), aBound2( rPos ), Ring( pRing ) +{ + pPoint = pMark = &aBound1; +} + +SwPaM::SwPaM( const SwPosition& rMk, const SwPosition& rPt, SwPaM* pRing ) + : aBound1( rMk ), aBound2( rPt ), Ring( pRing ) +{ + pMark = &aBound1; + pPoint = &aBound2; +} + +SwPaM::SwPaM( const SwNodeIndex& rMk, const SwNodeIndex& rPt, + long nMkOffset, long nPtOffset, SwPaM* pRing ) + : aBound1( rMk ), aBound2( rPt ), Ring( pRing ) +{ + if( nMkOffset ) + aBound1.nNode += nMkOffset; + if( nPtOffset ) + aBound2.nNode += nPtOffset; + + aBound1.nContent.Assign( aBound1.nNode.GetNode().GetCntntNode(), 0 ); + aBound2.nContent.Assign( aBound2.nNode.GetNode().GetCntntNode(), 0 ); + pMark = &aBound1; + pPoint = &aBound2; +} + +SwPaM::SwPaM( const SwNode& rMk, const SwNode& rPt, + long nMkOffset, long nPtOffset, SwPaM* pRing ) + : aBound1( rMk ), aBound2( rPt ), Ring( pRing ) +{ + if( nMkOffset ) + aBound1.nNode += nMkOffset; + if( nPtOffset ) + aBound2.nNode += nPtOffset; + + aBound1.nContent.Assign( aBound1.nNode.GetNode().GetCntntNode(), 0 ); + aBound2.nContent.Assign( aBound2.nNode.GetNode().GetCntntNode(), 0 ); + pMark = &aBound1; + pPoint = &aBound2; +} + +SwPaM::SwPaM( const SwNodeIndex& rMk, xub_StrLen nMkCntnt, + const SwNodeIndex& rPt, xub_StrLen nPtCntnt, SwPaM* pRing ) + : aBound1( rMk ), aBound2( rPt ), Ring( pRing ) +{ + aBound1.nContent.Assign( rMk.GetNode().GetCntntNode(), nMkCntnt ); + aBound2.nContent.Assign( rPt.GetNode().GetCntntNode(), nPtCntnt ); + pMark = &aBound1; + pPoint = &aBound2; +} + +SwPaM::SwPaM( const SwNode& rMk, xub_StrLen nMkCntnt, + const SwNode& rPt, xub_StrLen nPtCntnt, SwPaM* pRing ) + : aBound1( rMk ), aBound2( rPt ), Ring( pRing ) +{ + aBound1.nContent.Assign( aBound1.nNode.GetNode().GetCntntNode(), nMkCntnt ); + aBound2.nContent.Assign( aBound2.nNode.GetNode().GetCntntNode(), nPtCntnt ); + pMark = &aBound1; + pPoint = &aBound2; +} + +SwPaM::SwPaM( SwPaM &rPam ) + : aBound1( *(rPam.pPoint) ), aBound2( *(rPam.pMark) ), Ring( &rPam ) +{ + pPoint = &aBound1; + pMark = rPam.HasMark() ? &aBound2 : pPoint; +} + +SwPaM::SwPaM( const SwNode& rNd, xub_StrLen nCntnt, SwPaM* pRing ) + : aBound1( rNd ), aBound2( rNd ), Ring( pRing ) +{ + aBound1.nContent.Assign( aBound1.nNode.GetNode().GetCntntNode(), nCntnt ); + aBound2.nContent = aBound1.nContent; + pPoint = pMark = &aBound1; +} + +SwPaM::SwPaM( const SwNodeIndex& rNd, xub_StrLen nCntnt, SwPaM* pRing ) + : aBound1( rNd ), aBound2( rNd ), Ring( pRing ) +{ + aBound1.nContent.Assign( rNd.GetNode().GetCntntNode(), nCntnt ); + aBound2.nContent = aBound1.nContent; + pPoint = pMark = &aBound1; +} + +SwPaM::~SwPaM() {} + +void SwPaM::SetMark() +{ + if(pPoint == &aBound1) + pMark = &aBound2; + else + pMark = &aBound1; + (*pMark) = (*pPoint); +} + +#ifndef PRODUCT + +void SwPaM::Exchange() +{ + if(pPoint != pMark) + { + SwPosition *pTmp = pPoint; + pPoint = pMark; + pMark = pTmp; + } +} +#endif + + +SwPaM &SwPaM::operator=( SwPaM &rPam ) +{ + MoveTo( &rPam ); + *pPoint = *( rPam.pPoint ); + if( rPam.HasMark() ) + { + SetMark(); + *pMark = *( rPam.pMark ); + } + return *this; +} + +// Bewegen des Cursors + + +FASTBOOL SwPaM::Move( SwMoveFn fnMove, SwGoInDoc fnGo ) +{ + return (*fnGo)( *this, fnMove ); +} + + +/************************************************************************* +|* +|* void SwPaM::MakeRegion( SwMoveFn, SwPaM*, const SwPaM* ) +|* +|* Beschreibung Setzt den 1. SwPaM auf den uebergebenen SwPaM +|* oder setzt auf den Anfang oder Ende vom Document. +|* SPoint bleibt auf der Position stehen, GetMark aendert +|* sich entsprechend ! +|* +|* Parameter SwDirection gibt an, ob an Anfang / Ende +|* SwPaM * der zu setzende Bereich +|* const SwPaM& der enventuell vorgegeben Bereich +|* Return-Werte SwPaM* der entsprehend neu gesetzte Bereich +|* +|* Ersterstellung JP 26.04.91 +|* Letzte Aenderung JP 26.04.91 +|* +*************************************************************************/ + + +SwPaM* SwPaM::MakeRegion( SwMoveFn fnMove, const SwPaM * pOrigRg ) +{ + SwPaM* pPam; + if( pOrigRg == 0 ) + { + pPam = new SwPaM( *pPoint ); + pPam->SetMark(); // setze Anfang fest + pPam->Move( fnMove, fnGoSection); // an Anfang / Ende vom Node + + // stelle SPoint wieder auf alte Position, GetMark auf das "Ende" + pPam->Exchange(); + } + else + { + pPam = new SwPaM( *(SwPaM*)pOrigRg ); // die Suchregion ist vorgegeben + // sorge dafuer, dass SPoint auf dem "echten" StartPunkt steht + // FORWARD --> SPoint immer kleiner als GetMark + // BACKWARD --> SPoint immer groesser als GetMark + if( (pPam->GetMark()->*fnMove->fnCmpOp)( *pPam->GetPoint() ) ) + pPam->Exchange(); + } + return pPam; +} + +USHORT SwPaM::GetPageNum( BOOL bAtPoint, const Point* pLayPos ) +{ + // return die Seitennummer am Cursor + // (fuer Reader + Seitengebundene Rahmen) + const SwCntntFrm* pCFrm; + const SwPageFrm *pPg; + const SwCntntNode *pNd ; + const SwPosition* pPos = bAtPoint ? pPoint : pMark; + + if( 0 != ( pNd = pPos->nNode.GetNode().GetCntntNode() ) && + 0 != ( pCFrm = pNd->GetFrm( pLayPos, pPos, FALSE )) && + 0 != ( pPg = pCFrm->FindPageFrm() )) + return pPg->GetPhyPageNum(); + return 0; +} + +// steht in etwas geschuetztem oder in die Selektion umspannt +// etwas geschuetztes. +FASTBOOL SwPaM::HasReadonlySel() const +{ + FASTBOOL bRet = FALSE; + Point aTmpPt; + const SwCntntNode *pNd; + const SwCntntFrm *pFrm; + + if( 0 != ( pNd = GetPoint()->nNode.GetNode().GetCntntNode() )) + pFrm = pNd->GetFrm( &aTmpPt, GetPoint(), FALSE ); + else + pFrm = 0; + + if( pFrm && pFrm->IsProtected() ) + bRet = TRUE; + else if( pNd ) + { + const SwSectionNode* pSNd = pNd->GetSectionNode(); + if( pSNd && pSNd->GetSection().IsProtectFlag() ) + bRet = TRUE; + } + + if( !bRet && HasMark() && GetPoint()->nNode != GetMark()->nNode ) + { + if( 0 != ( pNd = GetMark()->nNode.GetNode().GetCntntNode() )) + pFrm = pNd->GetFrm( &aTmpPt, GetMark(), FALSE ); + else + pFrm = 0; + + if( pFrm && pFrm->IsProtected() ) + bRet = TRUE; + else if( pNd ) + { + const SwSectionNode* pSNd = pNd->GetSectionNode(); + if( pSNd && pSNd->GetSection().IsProtectFlag() ) + bRet = TRUE; + } + + // oder sollte eine geschuetzte Section innerhalb der + // Selektion liegen? + if( !bRet ) + { + ULONG nSttIdx = GetMark()->nNode.GetIndex(), + nEndIdx = GetPoint()->nNode.GetIndex(); + if( nEndIdx <= nSttIdx ) + { + ULONG nTmp = nSttIdx; + nSttIdx = nEndIdx; + nEndIdx = nTmp; + } + + // wenn ein geschuetzter Bereich zwischen den Nodes stehen soll, + // muss die Selektion selbst schon x Nodes umfassen. + // (TxtNd, SectNd, TxtNd, EndNd, TxtNd ) + if( nSttIdx + 3 < nEndIdx ) + { + const SwSectionFmts& rFmts = GetDoc()->GetSections(); + for( USHORT n = rFmts.Count(); n; ) + { + const SwSectionFmt* pFmt = rFmts[ --n ]; + if( pFmt->GetProtect().IsCntntProtected() ) + { + const SwFmtCntnt& rCntnt = pFmt->GetCntnt(FALSE); + ASSERT( rCntnt.GetCntntIdx(), "wo ist der SectionNode?" ); + ULONG nIdx = rCntnt.GetCntntIdx()->GetIndex(); + if( nSttIdx <= nIdx && nEndIdx >= nIdx ) + { +/* // ist es keine gelinkte Section, dann kann sie auch + // nicht mitselektiert werden + const SwSection& rSect = *pFmt->GetSection(); + if( CONTENT_SECTION == rSect.GetType() ) + { + RestoreSavePos(); + return TRUE; + } +*/ + bRet = TRUE; + break; + } + } + } + +#ifdef CHECK_CELL_READONLY +//JP 22.01.99: bisher wurden Tabelle, die in der Text-Selektion standen +// nicht beachtet. Wollte man das haben, dann muss dieser +// Code freigeschaltet werden + + if( !bRet ) + { + // dann noch ueber alle Tabellen + const SwFrmFmts& rFmts = *GetDoc()->GetTblFrmFmts(); + for( n = rFmts.Count(); n ; ) + { + SwFrmFmt* pFmt = (SwFrmFmt*)rFmts[ --n ]; + const SwTable* pTbl = SwTable::FindTable( pFmt ); + ULONG nIdx = pTbl ? pTbl->GetTabSortBoxes()[0]->GetSttIdx() + : 0; + if( nSttIdx <= nIdx && nEndIdx >= nIdx ) + { + // dann teste mal alle Boxen + const SwTableSortBoxes& rBoxes = pTbl->GetTabSortBoxes(); + + for( USHORT i = rBoxes.Count(); i; ) + if( rBoxes[ --i ]->GetFrmFmt()->GetProtect(). + IsCntntProtected() ) + { + bRet = TRUE; + break; + } + + if( bRet ) + break; + } + } + } +#endif + } + } + } + return bRet; +} + +//-------------------- Suche nach Formaten( FormatNamen ) ----------------- + +// die Funktion gibt in Suchrichtung den folgenden Node zurueck. +// Ist in der Richtung keiner mehr vorhanden oder ist dieser ausserhalb +// des Bereiches, wird ein 0 Pointer returnt. +// Das rbFirst gibt an, ob es man zu erstenmal einen Node holt. Ist das der +// Fall, darf die Position vom Pam nicht veraendert werden! + + +SwCntntNode* GetNode( SwPaM & rPam, FASTBOOL& rbFirst, SwMoveFn fnMove, + FASTBOOL bInReadOnly ) +{ + SwCntntNode * pNd = 0; + SwCntntFrm* pFrm; + if( ((*rPam.GetPoint()).*fnMove->fnCmpOp)( *rPam.GetMark() ) || + ( *rPam.GetPoint() == *rPam.GetMark() && rbFirst ) ) + { + if( rbFirst ) + { + rbFirst = FALSE; + pNd = rPam.GetCntntNode(); + if( pNd && + ( 0 == ( pFrm = pNd->GetFrm()) || + ( !bInReadOnly && pFrm->IsProtected() ) || + (pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsHiddenNow()) ) || + ( !bInReadOnly && pNd->FindSectionNode() && + pNd->FindSectionNode()->GetSection().IsProtect() )) + pNd = 0; + } + + if( !pNd ) // steht Cursor auf keinem ContentNode ? + { + SwPosition aPos( *rPam.GetPoint() ); + FASTBOOL bSrchForward = fnMove == fnMoveForward; + SwNodes& rNodes = aPos.nNode.GetNodes(); + + // zum naechsten / vorherigen ContentNode +// Funktioniert noch alles, wenn die Uerbpruefung vom ueberspringen der +// Sektions herausgenommen wird ?? +// if( (*fnMove->fnNds)( rNodes, &aPos.nNode ) ) + while( TRUE ) + { + pNd = bSrchForward + ? rNodes.GoNextSection( &aPos.nNode, TRUE, !bInReadOnly ) + : rNodes.GoPrevSection( &aPos.nNode, TRUE, !bInReadOnly ); + if( pNd ) + { + aPos.nContent.Assign( pNd, ::GetSttOrEnd( bSrchForward,*pNd )); + // liegt Position immer noch im Bereich ? + if( (aPos.*fnMove->fnCmpOp)( *rPam.GetMark() ) ) + { + // nur in der AutoTextSection koennen Node stehen, die + // nicht angezeigt werden !! + if( 0 == ( pFrm = pNd->GetFrm()) || + ( !bInReadOnly && pFrm->IsProtected() ) || + ( pFrm->IsTxtFrm() && + ((SwTxtFrm*)pFrm)->IsHiddenNow() ) ) + +// rNodes[ rNodes.EndOfAutotext ]->StartOfSection().GetIndex() +// < aPos.nNode.GetIndex() && aPos.nNode.GetIndex() +// < rNodes.EndOfAutotext.GetIndex() && +// 0 == ( pFrm = pNd->GetFrm()) && +// pFrm->IsProtected() ) + { + pNd = 0; + continue; // suche weiter + } + *(SwPosition*)rPam.GetPoint() = aPos; + } + else + pNd = 0; // kein gueltiger Node + break; + } + break; + } + } + } + return pNd; +} + +// ---------------------------------------------------------------------- + +// hier folgen die Move-Methoden ( Foward, Backward; Content, Node, Doc ) + + +void GoStartDoc( SwPosition * pPos ) +{ + SwNodes& rNodes = pPos->nNode.GetNodes(); + pPos->nNode = *rNodes.GetEndOfContent().StartOfSectionNode(); + // es muss immer ein ContentNode gefunden werden !! + SwCntntNode* pCNd = rNodes.GoNext( &pPos->nNode ); + if( pCNd ) + pCNd->MakeStartIndex( &pPos->nContent ); +} + + +void GoEndDoc( SwPosition * pPos ) +{ + SwNodes& rNodes = pPos->nNode.GetNodes(); + pPos->nNode = rNodes.GetEndOfContent(); + SwCntntNode* pCNd = GoPreviousNds( &pPos->nNode, TRUE ); + if( pCNd ) + pCNd->MakeEndIndex( &pPos->nContent ); +} + + +void GoStartSection( SwPosition * pPos ) +{ + // springe zum Anfang der Section + SwNodes& rNodes = pPos->nNode.GetNodes(); + USHORT nLevel = rNodes.GetSectionLevel( pPos->nNode ); + if( pPos->nNode < rNodes.GetEndOfContent().StartOfSectionIndex() ) + nLevel--; + do { rNodes.GoStartOfSection( &pPos->nNode ); } while( nLevel-- ); + + // steht jetzt schon auf einem CntntNode + pPos->nNode.GetNode().GetCntntNode()->MakeStartIndex( &pPos->nContent ); +} + +// gehe an das Ende der akt. Grund-Section + + +void GoEndSection( SwPosition * pPos ) +{ + // springe zum Anfang/Ende der Section + SwNodes& rNodes = pPos->nNode.GetNodes(); + USHORT nLevel = rNodes.GetSectionLevel( pPos->nNode ); + if( pPos->nNode < rNodes.GetEndOfContent().StartOfSectionIndex() ) + nLevel--; + do { rNodes.GoEndOfSection( &pPos->nNode ); } while( nLevel-- ); + + // steht jetzt auf einem EndNode, also zum vorherigen CntntNode + if( GoPreviousNds( &pPos->nNode, TRUE ) ) + pPos->nNode.GetNode().GetCntntNode()->MakeEndIndex( &pPos->nContent ); +} + + + +FASTBOOL GoInDoc( SwPaM & rPam, SwMoveFn fnMove ) +{ + (*fnMove->fnDoc)( rPam.pPoint ); + return TRUE; +} + + +FASTBOOL GoInSection( SwPaM & rPam, SwMoveFn fnMove ) +{ + (*fnMove->fnSections)( (SwPosition*)rPam.GetPoint() ); + return TRUE; +} + + +FASTBOOL GoInNode( SwPaM & rPam, SwMoveFn fnMove ) +{ + SwCntntNode *pNd = (*fnMove->fnNds)( &rPam.pPoint->nNode, TRUE ); + if( pNd ) + rPam.pPoint->nContent.Assign( pNd, + ::GetSttOrEnd( fnMove == fnMoveForward, *pNd ) ); + return 0 != pNd; +} + + +FASTBOOL GoInCntnt( SwPaM & rPam, SwMoveFn fnMove ) +{ + if( (*fnMove->fnNd)( &rPam.pPoint->nNode.GetNode(), &rPam.pPoint->nContent )) + return TRUE; + return GoInNode( rPam, fnMove ); +} + +// --------- Funktionsdefinitionen fuer die SwCrsrShell -------------- + + +FASTBOOL GoPrevPara( SwPaM & rPam, SwPosPara aPosPara ) +{ + if( rPam.Move( fnMoveBackward, fnGoNode ) ) + { + // steht immer auf einem ContentNode ! + SwCntntNode * pNd = rPam.pPoint->nNode.GetNode().GetCntntNode(); + rPam.pPoint->nContent.Assign( pNd, + ::GetSttOrEnd( aPosPara == fnMoveForward, *pNd ) ); + return TRUE; + } + return FALSE; +} + + +FASTBOOL GoCurrPara( SwPaM & rPam, SwPosPara aPosPara ) +{ + SwCntntNode * pNd = rPam.pPoint->nNode.GetNode().GetCntntNode(); + if( pNd ) + { + xub_StrLen nOld = rPam.pPoint->nContent.GetIndex(), + nNew = aPosPara == fnMoveForward ? 0 : pNd->Len(); + // stand er schon auf dem Anfang/Ende dann zum naechsten/vorherigen + if( nOld != nNew ) + { + rPam.pPoint->nContent.Assign( pNd, nNew ); + return TRUE; + } + } + // den Node noch etwas bewegen ( auf den naechsten/vorh. CntntNode) + if( ( aPosPara==fnParaStart && 0 != ( pNd = + GoPreviousNds( &rPam.pPoint->nNode, TRUE ))) || + ( aPosPara==fnParaEnd && 0 != ( pNd = + GoNextNds( &rPam.pPoint->nNode, TRUE ))) ) + { + rPam.pPoint->nContent.Assign( pNd, + ::GetSttOrEnd( aPosPara == fnMoveForward, *pNd )); + return TRUE; + } + return FALSE; +} + + +FASTBOOL GoNextPara( SwPaM & rPam, SwPosPara aPosPara ) +{ + if( rPam.Move( fnMoveForward, fnGoNode ) ) + { + // steht immer auf einem ContentNode ! + SwCntntNode * pNd = rPam.pPoint->nNode.GetNode().GetCntntNode(); + rPam.pPoint->nContent.Assign( pNd, + ::GetSttOrEnd( aPosPara == fnMoveForward, *pNd ) ); + return TRUE; + } + return FALSE; +} + + + +FASTBOOL GoCurrSection( SwPaM & rPam, SwMoveFn fnMove ) +{ + SwPosition aSavePos( *rPam.pPoint ); // eine Vergleichsposition + SwNodes& rNds = aSavePos.nNode.GetNodes(); + (rNds.*fnMove->fnSection)( &rPam.pPoint->nNode ); + SwCntntNode *pNd; + if( 0 == ( pNd = rPam.pPoint->nNode.GetNode().GetCntntNode()) && + 0 == ( pNd = (*fnMove->fnNds)( &rPam.pPoint->nNode, TRUE )) ) + { + *rPam.pPoint = aSavePos; // Cusror nicht veraendern + return FALSE; + } + + rPam.pPoint->nContent.Assign( pNd, + ::GetSttOrEnd( fnMove == fnMoveForward, *pNd ) ); + return aSavePos != *rPam.pPoint; +} + + +FASTBOOL GoNextSection( SwPaM & rPam, SwMoveFn fnMove ) +{ + SwPosition aSavePos( *rPam.pPoint ); // eine Vergleichsposition + SwNodes& rNds = aSavePos.nNode.GetNodes(); + rNds.GoEndOfSection( &rPam.pPoint->nNode ); + + // kein weiterer ContentNode vorhanden ? + if( !GoInCntnt( rPam, fnMoveForward ) ) + { + *rPam.pPoint = aSavePos; // Cusror nicht veraendern + return FALSE; + } + (rNds.*fnMove->fnSection)( &rPam.pPoint->nNode ); + SwCntntNode *pNd = rPam.pPoint->nNode.GetNode().GetCntntNode(); + rPam.pPoint->nContent.Assign( pNd, + ::GetSttOrEnd( fnMove == fnMoveForward, *pNd ) ); + return TRUE; +} + + +FASTBOOL GoPrevSection( SwPaM & rPam, SwMoveFn fnMove ) +{ + SwPosition aSavePos( *rPam.pPoint ); // eine Vergleichsposition + SwNodes& rNds = aSavePos.nNode.GetNodes(); + rNds.GoStartOfSection( &rPam.pPoint->nNode ); + + // kein weiterer ContentNode vorhanden ? + if( !GoInCntnt( rPam, fnMoveBackward )) + { + *rPam.pPoint = aSavePos; // Cusror nicht veraendern + return FALSE; + } + (rNds.*fnMove->fnSection)( &rPam.pPoint->nNode ); + SwCntntNode *pNd = rPam.pPoint->nNode.GetNode().GetCntntNode(); + rPam.pPoint->nContent.Assign( pNd, + ::GetSttOrEnd( fnMove == fnMoveForward, *pNd )); + return TRUE; +} + + + + diff --git a/sw/source/core/crsr/paminit.cxx b/sw/source/core/crsr/paminit.cxx new file mode 100644 index 000000000000..a370da342fbf --- /dev/null +++ b/sw/source/core/crsr/paminit.cxx @@ -0,0 +1,168 @@ +/************************************************************************* + * + * $RCSfile: paminit.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:17 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _PAMTYP_HXX +#include +#endif + + +static SwMoveFnCollection aFwrd = { + /* fnNd */ &GoNext, + /* fnNds */ &GoNextNds, + /* fnDoc */ &GoEndDoc, + /* fnSections */ &GoEndSection, + /* fnCmpOp */ &SwPosition::operator<, + /* fnGetHint */ &GetFrwrdTxtHint, + /* fnSearch */ &SearchText::SearchFrwrd, + /* fnSection */ &SwNodes::GoStartOfSection +}; + +static SwMoveFnCollection aBwrd = { + /* fnNd */ &GoPrevious, + /* fnNds */ &GoPreviousNds, + /* fnDoc */ &GoStartDoc, + /* fnSections */ &GoStartSection, + /* fnCmpOp */ &SwPosition::operator>, + /* fnGetHint */ &GetBkwrdTxtHint, + /* fnSearch */ &SearchText::SearchBkwrd, + /* fnSection */ &SwNodes::GoEndOfSection +}; + +SwGoInDoc fnGoDoc = &GoInDoc; +SwGoInDoc fnGoSection = &GoInSection; +SwGoInDoc fnGoNode = &GoInNode; +SwGoInDoc fnGoCntnt = &GoInCntnt; + +SwWhichPara fnParaPrev = &GoPrevPara; +SwWhichPara fnParaCurr = &GoCurrPara; +SwWhichPara fnParaNext = &GoNextPara; +SwPosPara fnParaStart = &aFwrd; +SwPosPara fnParaEnd = &aBwrd; + +SwWhichSection fnSectionPrev = &GoPrevSection; +SwWhichSection fnSectionCurr = &GoCurrSection; +SwWhichSection fnSectionNext = &GoNextSection; +SwPosSection fnSectionStart = &aFwrd; +SwPosSection fnSectionEnd = &aBwrd; + +// Travelling in Tabellen +FASTBOOL GotoPrevTable( SwPaM&, SwPosTable, FASTBOOL bInReadOnly ); +FASTBOOL GotoCurrTable( SwPaM&, SwPosTable, FASTBOOL bInReadOnly ); +FASTBOOL GotoNextTable( SwPaM&, SwPosTable, FASTBOOL bInReadOnly ); + +SwWhichTable fnTablePrev = &GotoPrevTable; +SwWhichTable fnTableCurr = &GotoCurrTable; +SwWhichTable fnTableNext = &GotoNextTable; +SwPosTable fnTableStart = &aFwrd; +SwPosTable fnTableEnd = &aBwrd; + +// Travelling in Bereichen +FASTBOOL GotoPrevRegion( SwPaM&, SwPosRegion, FASTBOOL bInReadOnly ); +FASTBOOL GotoCurrRegion( SwPaM&, SwPosRegion, FASTBOOL bInReadOnly ); +FASTBOOL GotoCurrRegionAndSkip( SwPaM&, SwPosRegion, FASTBOOL bInReadOnly ); +FASTBOOL GotoNextRegion( SwPaM&, SwPosRegion, FASTBOOL bInReadOnly ); + +SwWhichRegion fnRegionPrev = &GotoPrevRegion; +SwWhichRegion fnRegionCurr = &GotoCurrRegion; +SwWhichRegion fnRegionCurrAndSkip = &GotoCurrRegionAndSkip; +SwWhichRegion fnRegionNext = &GotoNextRegion; +SwPosRegion fnRegionStart = &aFwrd; +SwPosRegion fnRegionEnd = &aBwrd; + +SwMoveFn fnMoveBackward = &aBwrd; +SwMoveFn fnMoveForward = &aFwrd; + + +#ifdef USED + +// JP 30.11.95: +// war fuer die CFRONT-Compiler noetig, jetzt sollte das nicht mehr +// benoetigt werden. + +void _InitPam() +{ + aBwrd.fnNd = &GoPrevious; + aBwrd.fnNds = &GoPreviousNds; + aBwrd.fnDoc = &GoStartDoc; + aBwrd.fnSections= &GoStartSection; + aBwrd.fnCmpOp = &SwPosition::operator>; + aBwrd.fnGetHint = &GetBkwrdTxtHint; + aBwrd.fnSearch = &SearchText::SearchBkwrd; + aBwrd.fnSection = &SwNodes::GoEndOfSection; + + aFwrd.fnNd = &GoNext; + aFwrd.fnNds = &GoNextNds; + aFwrd.fnDoc = &GoEndDoc; + aFwrd.fnSections= &GoEndSection; + aFwrd.fnCmpOp = &SwPosition::operator<; + aFwrd.fnGetHint = &GetFrwrdTxtHint; + aFwrd.fnSearch = &SearchText::SearchFrwrd; + aFwrd.fnSection = &SwNodes::GoStartOfSection; +} +#endif + + diff --git a/sw/source/core/crsr/swcrsr.cxx b/sw/source/core/crsr/swcrsr.cxx new file mode 100644 index 000000000000..183f59597031 --- /dev/null +++ b/sw/source/core/crsr/swcrsr.cxx @@ -0,0 +1,1736 @@ +/************************************************************************* + * + * $RCSfile: swcrsr.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:17 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _HINTIDS_HXX +#include +#endif + +#ifndef _SVX_PROTITEM_HXX //autogen +#include +#endif + +#ifndef _COM_SUN_STAR_TEXT_WORDTYPE_HDL +#include +#endif +#ifndef _COM_SUN_STAR_TEXT_CHARTYPE_HDL +#include +#endif + + +#ifndef _FMTCNTNT_HXX //autogen +#include +#endif +#ifndef _SWTBLFMT_HXX //autogen +#include +#endif +#ifndef _SWCRSR_HXX +#include +#endif +#ifndef _DOC_HXX +#include +#endif +#ifndef _DOCARY_HXX +#include +#endif +#ifndef _NODE_HXX +#include +#endif +#ifndef _NDTXT_HXX +#include +#endif +#ifndef _SECTION_HXX +#include +#endif +#ifndef _SWTABLE_HXX +#include +#endif +#ifndef _CNTFRM_HXX +#include +#endif +#ifndef _ROOTFRM_HXX +#include +#endif +#ifndef _CRSTATE_HXX +#include +#endif +#ifndef _DOCSH_HXX +#include +#endif +#ifndef _FRMATR_HXX +#include +#endif +#ifndef _BREAKIT_HXX +#include +#endif + +#ifndef _MDIEXP_HXX +#include // ...Percent() +#endif +#ifndef _STATSTR_HRC +#include // ResId fuer Statusleiste +#endif + +using namespace ::com::sun::star::text; + +static const USHORT coSrchRplcThreshold = 500; + +struct _PercentHdl +{ + SwDocShell* pDSh; + ULONG nActPos; + BOOL bBack, bNodeIdx; + + _PercentHdl( ULONG nStt, ULONG nEnd, SwDocShell* pSh ) + : pDSh( pSh ) + { + nActPos = nStt; + if( 0 != ( bBack = (nStt > nEnd )) ) + { + ULONG n = nStt; nStt = nEnd; nEnd = n; + } + ::StartProgress( STR_STATSTR_SEARCH, nStt, nEnd, 0 ); + } + + _PercentHdl( const SwPaM& rPam ) + : pDSh( (SwDocShell*)rPam.GetDoc()->GetDocShell() ) + { + ULONG nStt, nEnd; + if( rPam.GetPoint()->nNode == rPam.GetMark()->nNode ) + { + bNodeIdx = FALSE; + nStt = rPam.GetMark()->nContent.GetIndex(); + nEnd = rPam.GetPoint()->nContent.GetIndex(); + } + else + { + nStt = rPam.GetMark()->nNode.GetIndex(); + nEnd = rPam.GetPoint()->nNode.GetIndex(); + } + nActPos = nStt; + if( 0 != ( bBack = (nStt > nEnd )) ) + { + ULONG n = nStt; nStt = nEnd; nEnd = n; + } + ::StartProgress( STR_STATSTR_SEARCH, nStt, nEnd, pDSh ); + } + + ~_PercentHdl() { ::EndProgress( pDSh ); } + + void NextPos( ULONG nPos ) const + { ::SetProgressState( bBack ? nActPos - nPos : nPos, pDSh ); } + + void NextPos( SwPosition& rPos ) const + { + ULONG nPos; + if( bNodeIdx ) + nPos = rPos.nNode.GetIndex(); + else + nPos = rPos.nContent.GetIndex(); + ::SetProgressState( bBack ? nActPos - nPos : nPos, pDSh ); + } +}; + +SwCursor::SwCursor( const SwPosition &rPos, SwPaM* pRing ) + : SwPaM( rPos, pRing ), pSavePos( 0 ) +{ +} + +SwCursor::SwCursor( SwCursor& rCpy ) + : SwPaM( rCpy ), pSavePos( 0 ) +{ +} + +SwCursor::~SwCursor() +{ + while( pSavePos ) + { + _SwCursor_SavePos* pNext = pSavePos->pNext; + delete pSavePos; + pSavePos = pNext; + } +} + +SwCursor* SwCursor::Create( SwPaM* pRing ) const +{ + return new SwCursor( *GetPoint(), pRing ); +} + +SwCursor::operator SwTableCursor* () { return 0; } +SwCursor::operator SwShellCrsr* () { return 0; } +SwCursor::operator SwShellTableCrsr* () { return 0; } +SwCursor::operator SwUnoCrsr* () { return 0; } +SwCursor::operator SwUnoTableCrsr* () { return 0; } + + +// Sicher die aktuelle Position, damit ggfs. auf diese zurueck +// gefallen werden kann. Die SavePos Objekte werden als Stack verwaltet, +// damit das auch alles bei verschachtelten Aufrufen funktioniert. +// Das CreateNewSavePos ist virtual, damit abgeleitete Klassen vom Cursor +// gegebenenfalls eigene SaveObjecte anlegen und in den virtuellen +// Check-Routinen verwenden koennen. + +void SwCursor::SaveState() +{ + _SwCursor_SavePos* pNew = CreateNewSavePos(); + pNew->pNext = pSavePos; + pSavePos = pNew; +} + +void SwCursor::RestoreState() +{ + _SwCursor_SavePos* pDel = pSavePos; + pSavePos = pSavePos->pNext; + delete pDel; +} + +_SwCursor_SavePos* SwCursor::CreateNewSavePos() const +{ + return new _SwCursor_SavePos( *this ); +} + +// stelle fest, ob sich der Point ausserhalb des Content-Bereichs +// vom Nodes-Array befindet +FASTBOOL SwCursor::IsNoCntnt() const +{ + return GetPoint()->nNode.GetIndex() < + GetDoc()->GetNodes().GetEndOfExtras().GetIndex(); +} + + +FASTBOOL SwCursor::IsSelOvr( int eFlags ) +{ + SwTableCursor* pTblCrsr = *this; + SwDoc* pDoc = GetDoc(); + SwNodes& rNds = pDoc->GetNodes(); + + // Bereiche vom Nodes-Array ueberpruefen + if( (SELOVER_CHECKNODESSECTION & eFlags) && pTblCrsr && HasMark() ) + { + SwNodeIndex aOldPos( rNds, pSavePos->nNode ); + if( !CheckNodesRange( aOldPos, GetPoint()->nNode, TRUE )) + { + GetPoint()->nNode = aOldPos; + GetPoint()->nContent.Assign( GetCntntNode(), pSavePos->nCntnt ); + return TRUE; + } + } + +// neu: Bereiche ueberpruefen +// Anfang + if( pSavePos->nNode != GetPoint()->nNode.GetIndex() && + //JP 28.10.97: Bug 45129 - im UI-ReadOnly ist alles erlaubt + ( !pDoc->GetDocShell() || !pDoc->GetDocShell()->IsReadOnlyUI() )) + { + // teste doch mal die neuen Sections: + SwNodeIndex& rPtIdx = GetPoint()->nNode; + const SwSectionNode* pSectNd = rPtIdx.GetNode().FindSectionNode(); + BOOL bCrsrInReadOnly = IsReadOnlyAvailable(); + if( pSectNd && (pSectNd->GetSection().IsHiddenFlag() || + (!bCrsrInReadOnly && pSectNd->GetSection().IsProtectFlag() ))) + { + if( 0 == ( SELOVER_CHANGEPOS & eFlags ) ) + { + // dann wars das schon + RestoreSavePos(); + return TRUE; + } + + // dann setze den Cursor auf die neue Position: + SwNodeIndex aIdx( rPtIdx ); + xub_StrLen nCntntPos = pSavePos->nCntnt; + int bGoNxt = pSavePos->nNode < rPtIdx.GetIndex(); + SwCntntNode* pCNd = bGoNxt + ? rNds.GoNextSection( &rPtIdx, TRUE, !bCrsrInReadOnly ) + : rNds.GoPrevSection( &rPtIdx, TRUE, !bCrsrInReadOnly ); + if( !pCNd && ( SELOVER_ENABLEREVDIREKTION & eFlags )) + { + bGoNxt = !bGoNxt; + pCNd = bGoNxt ? rNds.GoNextSection( &rPtIdx, TRUE, !bCrsrInReadOnly ) + : rNds.GoPrevSection( &rPtIdx, TRUE, !bCrsrInReadOnly ); + } + + int bIsValidPos = 0 != pCNd; + FASTBOOL bValidNodesRange = bIsValidPos && + ::CheckNodesRange( rPtIdx, aIdx, TRUE ); + if( !bValidNodesRange ) + { + rPtIdx = pSavePos->nNode; + if( 0 == ( pCNd = rPtIdx.GetNode().GetCntntNode() ) ) + { + bIsValidPos = FALSE; + nCntntPos = 0; + rPtIdx = aIdx; + if( 0 == ( pCNd = rPtIdx.GetNode().GetCntntNode() ) ) + { + // dann auf den Anfang vom Doc + rPtIdx = rNds.GetEndOfExtras(); + pCNd = rNds.GoNext( &rPtIdx ); + } + } + } + + // ContentIndex noch anmelden: + xub_StrLen nTmpPos = bIsValidPos ? (bGoNxt ? 0 : pCNd->Len()) : nCntntPos; + GetPoint()->nContent.Assign( pCNd, nTmpPos ); + if( !bIsValidPos || !bValidNodesRange || + // sollten wir in einer Tabelle gelandet sein? + IsInProtectTable( TRUE ) ) + return TRUE; + } + + // oder sollte eine geschuetzte Section innerhalb der Selektion liegen? + if( HasMark() && !bCrsrInReadOnly ) + { + ULONG nSttIdx = GetMark()->nNode.GetIndex(), + nEndIdx = GetPoint()->nNode.GetIndex(); + if( nEndIdx <= nSttIdx ) + { + ULONG nTmp = nSttIdx; + nSttIdx = nEndIdx; + nEndIdx = nTmp; + } + + const SwSectionFmts& rFmts = pDoc->GetSections(); + for( USHORT n = 0; n < rFmts.Count(); ++n ) + { + const SwSectionFmt* pFmt = rFmts[n]; + const SvxProtectItem& rProtect = pFmt->GetProtect(); + if( rProtect.IsCntntProtected() ) + { + const SwFmtCntnt& rCntnt = pFmt->GetCntnt(FALSE); + ASSERT( rCntnt.GetCntntIdx(), "wo ist der SectionNode?" ); + ULONG nIdx = rCntnt.GetCntntIdx()->GetIndex(); + if( nSttIdx <= nIdx && nEndIdx >= nIdx ) + { + // ist es keine gelinkte Section, dann kann sie auch + // nicht mitselektiert werden + const SwSection& rSect = *pFmt->GetSection(); + if( CONTENT_SECTION == rSect.GetType() ) + { + RestoreSavePos(); + return TRUE; + } + } + } + } + } + + } +// Ende +// neu: Bereiche ueberpruefen + + const SwNode* pNd = &GetPoint()->nNode.GetNode(); + if( pNd->IsCntntNode() && !((SwCntntNode*)pNd)->GetFrm() && + 0 == (SwUnoCrsr*)*this ) + { + DeleteMark(); + RestoreSavePos(); + return TRUE; // ohne Frames geht gar nichts! + } + + // darf der Cursor in geschuetzen "Nodes" stehen? + if( 0 == ( SELOVER_CHANGEPOS & eFlags ) && !IsAtValidPos() ) + { + DeleteMark(); + RestoreSavePos(); + return TRUE; + } + + if( !HasMark() ) + return FALSE; + + //JP 19.08.98: teste mal auf ungueltige Selektion - sprich ueber + // GrundSections: + if( !::CheckNodesRange( GetMark()->nNode, GetPoint()->nNode, TRUE )) + { + DeleteMark(); + RestoreSavePos(); + return TRUE; // ohne Frames geht gar nichts! + } + + const SwTableNode* pPtNd = pNd->FindTableNode(); + + if( (pNd = &GetMark()->nNode.GetNode())->IsCntntNode() && + !((SwCntntNode*)pNd)->GetFrm() && 0 == (SwUnoCrsr*)*this ) + { + DeleteMark(); + RestoreSavePos(); + return TRUE; // ohne Frames geht gar nichts! + } + + const SwTableNode* pMrkNd = pNd->FindTableNode(); + + // beide in keinem oder beide im gleichen TableNode + if( ( !pMrkNd && !pPtNd ) || pPtNd == pMrkNd ) + return FALSE; + + // in unterschiedlichen Tabellen oder nur Mark in der Tabelle + if( ( pPtNd && pMrkNd ) || pMrkNd ) + { // dann lasse das nicht zu, alte Pos zurueck + RestoreSavePos(); + // Crsr bleibt an der alten Position + return TRUE; + } + + // ACHTUNG: dieses kann nicht im TableMode geschehen !! + if( pPtNd ) // nur Point in Tabelle, dann gehe hinter/vor diese + { + if( SELOVER_CHANGEPOS & eFlags ) + { + FASTBOOL bSelTop = GetPoint()->nNode.GetIndex() < + (( SELOVER_TOGGLE & eFlags ) ? pSavePos->nNode + : GetMark()->nNode.GetIndex()); + + do { + // in Schleife fuer Tabelle hinter Tabelle + ULONG nSEIdx = pPtNd->EndOfSectionIndex(); + ULONG nSttEndTbl = nSEIdx + 1; // dflt. Sel. nach unten + + if( bSelTop ) // Sel. nach oben + nSttEndTbl = rNds[ nSEIdx ]->StartOfSectionIndex() - 1; + + GetPoint()->nNode = nSttEndTbl; + const SwNode* pNd = GetNode(); + if( pNd->IsSectionNode() || ( pNd->IsEndNode() && + pNd->FindStartNode()->IsSectionNode() ) ) + { + // die lassen wir zu: + pNd = bSelTop + ? rNds.GoPrevSection( &GetPoint()->nNode,TRUE,FALSE ) + : rNds.GoNextSection( &GetPoint()->nNode,TRUE,FALSE ); + } + + if( pNd->IsCntntNode() && // ist es ein ContentNode ?? + ::CheckNodesRange( GetMark()->nNode, + GetPoint()->nNode, TRUE )) + { + SwCntntNode* pCNd = (SwCntntNode*)pNd; + xub_StrLen nTmpPos = bSelTop ? pCNd->Len() : 0; + GetPoint()->nContent.Assign( pCNd, nTmpPos ); + return FALSE; + } + if( bSelTop + ? ( !pNd->IsEndNode() || 0 == ( pPtNd = pNd->FindTableNode() )) + : 0 == ( pPtNd = pNd->GetTableNode() )) + break; + } while( TRUE ); + } + + // dann verbleibe auf der alten Position + RestoreSavePos(); + return TRUE; // Crsr bleibt an der alten Position + } + return FALSE; // was bleibt noch ?? +} + +#if defined( UNX ) || defined( MAC ) +#define IDX (*pCellStt) +#else +#define IDX aCellStt +#endif + + +FASTBOOL SwCursor::IsInProtectTable( FASTBOOL bMove, FASTBOOL bChgCrsr ) +{ + // stehe ich in einer Tabelle ?? + SwDoc* pDoc = GetDoc(); + SwCntntNode* pCNd = GetCntntNode(); + if( !pCNd || pSavePos->nNode == GetPoint()->nNode.GetIndex() || + !pCNd->FindTableNode() || + !pCNd->IsProtect() || + IsReadOnlyAvailable() ) + return FALSE; + + if( !bMove ) + { + if( bChgCrsr ) + // dann verbleibe auf der alten Position + RestoreSavePos(); + return TRUE; // Crsr bleibt an der alten Position + } + + // wir stehen in einer geschuetzten TabellenZelle + // von Oben nach Unten Traveln ? + if( pSavePos->nNode < GetPoint()->nNode.GetIndex() ) + { + // suche die naechste "gueltige" Box + + // folgt nach dem EndNode der Zelle ein weiterer StartNode, dann + // gibt es auch eine naechste Zelle +#if defined( UNX ) || defined( MAC ) + SwNodeIndex* pCellStt = new SwNodeIndex( *GetNode()-> + FindTableBoxStartNode()->EndOfSectionNode(), 1 ); +#else + SwNodeIndex aCellStt( *GetNode()->FindTableBoxStartNode()->EndOfSectionNode(), 1 ); +#endif + FASTBOOL bProt = TRUE; +GoNextCell: + do { + if( !IDX.GetNode().IsStartNode() ) + break; + IDX++; + if( 0 == ( pCNd = IDX.GetNode().GetCntntNode() )) + pCNd = IDX.GetNodes().GoNext( &IDX ); + if( 0 == ( bProt = pCNd->IsProtect() )) + break; + IDX.Assign( *pCNd->FindTableBoxStartNode()->EndOfSectionNode(), 1 ); + } while( bProt ); + +SetNextCrsr: + if( !bProt ) // eine freie Zelle gefunden + { + GetPoint()->nNode = IDX; +#if defined( UNX ) || defined( MAC ) + delete pCellStt; +#endif + SwCntntNode* pCNd = GetCntntNode(); + if( pCNd ) + { + GetPoint()->nContent.Assign( pCNd, 0 ); + return FALSE; + } + return IsSelOvr( SELOVER_TOGGLE | SELOVER_CHANGEPOS ); + } + // am Ende der Tabelle, also setze hinter diese + IDX++; // auf den naechsten Node + SwNode* pNd; + if( ( pNd = &IDX.GetNode())->IsEndNode() || HasMark()) + { + // Tabelle allein in einem FlyFrame oder SSelection, + // dann verbleibe auf der alten Position + if( bChgCrsr ) + RestoreSavePos(); +#if defined( UNX ) || defined( MAC ) + delete pCellStt; +#endif + return TRUE; // Crsr bleibt an der alten Position + } + else if( pNd->IsTableNode() && IDX++ ) + goto GoNextCell; + + bProt = FALSE; // Index steht jetzt auf einem ContentNode + goto SetNextCrsr; + } + + // suche die vorherige "gueltige" Box + { + // liegt vor dem StartNode der Zelle ein weiterer EndNode, dann + // gibt es auch eine vorherige Zelle +#if defined( UNX ) || defined( MAC ) + SwNodeIndex* pCellStt = new SwNodeIndex( + *GetNode()->FindTableBoxStartNode(), -1 ); +#else + SwNodeIndex aCellStt( *GetNode()->FindTableBoxStartNode(), -1 ); +#endif + SwNode* pNd; + FASTBOOL bProt = TRUE; +GoPrevCell: + do { + if( !( pNd = &IDX.GetNode())->IsEndNode() ) + break; + IDX.Assign( *pNd->StartOfSectionNode(), +1 ); + if( 0 == ( pCNd = IDX.GetNode().GetCntntNode() )) + pCNd = pNd->GetNodes().GoNext( &IDX ); + if( 0 == ( bProt = pCNd->IsProtect() )) + break; + IDX.Assign( *pNd->FindTableBoxStartNode(), -1 ); + } while( bProt ); + +SetPrevCrsr: + if( !bProt ) // eine freie Zelle gefunden + { + GetPoint()->nNode = IDX; +#if defined( UNX ) || defined( MAC ) + delete pCellStt; +#endif + SwCntntNode* pCNd = GetCntntNode(); + if( pCNd ) + { + GetPoint()->nContent.Assign( pCNd, 0 ); + return FALSE; + } + return IsSelOvr( SELOVER_TOGGLE | SELOVER_CHANGEPOS ); + } + // am Start der Tabelle, also setze vor diese + IDX--; // auf den naechsten Node + if( ( pNd = &IDX.GetNode())->IsStartNode() || HasMark() ) + { + // Tabelle allein in einem FlyFrame oder Selektion, + // dann verbleibe auf der alten Position + if( bChgCrsr ) + RestoreSavePos(); +#if defined( UNX ) || defined( MAC ) + delete pCellStt; +#endif + return TRUE; // Crsr bleibt an der alten Position + } + else if( pNd->StartOfSectionNode()->IsTableNode() && IDX-- ) + goto GoPrevCell; + + bProt = FALSE; // Index steht jetzt auf einem ContentNode + goto SetPrevCrsr; + } + + ASSERT( FALSE, "sollte nie erreicht werden oder??" ); + return FALSE; +} + +// TRUE: an die Position kann der Cursor gesetzt werden +FASTBOOL SwCursor::IsAtValidPos( BOOL bPoint ) const +{ + const SwDoc* pDoc = GetDoc(); + const SwPosition* pPos = bPoint ? GetPoint() : GetMark(); + const SwNode* pNd = &pPos->nNode.GetNode(); + + if( pNd->IsCntntNode() && !((SwCntntNode*)pNd)->GetFrm() && + 0 == (const SwUnoCrsr*)*this ) + return FALSE; + + //JP 28.10.97: Bug 45129 - im UI-ReadOnly ist alles erlaubt + if( !pDoc->GetDocShell() || !pDoc->GetDocShell()->IsReadOnlyUI() ) + return TRUE; + + BOOL bCrsrInReadOnly = IsReadOnlyAvailable(); + if( !bCrsrInReadOnly && pNd->IsProtect() ) + return FALSE; + + const SwSectionNode* pSectNd = pNd->FindSectionNode(); + if( pSectNd && (pSectNd->GetSection().IsHiddenFlag() || + ( !bCrsrInReadOnly && pSectNd->GetSection().IsProtectFlag() ))) + return FALSE; + + return TRUE; +} + +void SwCursor::SaveTblBoxCntnt( const SwPosition* ) {} + +// setze den SRange fuer das Suchen im Dokument +SwMoveFnCollection* SwCursor::MakeFindRange( SwDocPositions nStart, + SwDocPositions nEnd, SwPaM* pRange ) const +{ + pRange->SetMark(); + FillFindPos( nStart, *pRange->GetMark() ); + FillFindPos( nEnd, *pRange->GetPoint() ); + + // bestimme die Richtung, in der zu suchen ist + // ( GetPoint > GetMark -> vorwaerts, sonst rueckwaerts ) + return ( DOCPOS_START == nStart || DOCPOS_OTHERSTART == nStart || + (DOCPOS_CURR == nStart && + (DOCPOS_END == nEnd || DOCPOS_OTHEREND == nEnd ) )) + ? fnMoveForward : fnMoveBackward; +} + + +ULONG lcl_FindSelection( SwFindParas& rParas, SwCursor* pCurCrsr, + SwMoveFn fnMove, SwCursor*& pFndRing, + SwPaM& aRegion, FindRanges eFndRngs, + FASTBOOL bInReadOnly ) +{ + SwDoc* pDoc = pCurCrsr->GetDoc(); + FASTBOOL bDoesUndo = pDoc->DoesUndo(); + int nFndRet = 0; + ULONG nFound = 0; + int bSrchBkwrd = fnMove == fnMoveBackward, bEnde = FALSE; + SwPaM *pTmpCrsr = pCurCrsr, *pSaveCrsr = pCurCrsr; + + // nur beim ShellCrsr einen Prgogressbar erzeugen + BOOL bIsUnoCrsr = 0 != (SwUnoCrsr*)*pCurCrsr; + _PercentHdl* pPHdl = 0; + USHORT nCrsrCnt = 0; + if( FND_IN_SEL & eFndRngs ) + { + while( pCurCrsr != ( pTmpCrsr = (SwPaM*)pTmpCrsr->GetNext() )) + ++nCrsrCnt; + if( nCrsrCnt && !bIsUnoCrsr ) + pPHdl = new _PercentHdl( 0, nCrsrCnt, pDoc->GetDocShell() ); + } + + do { + aRegion.SetMark(); + // egal in welche Richtung, SPoint ist immer groesser als Mark, + // wenn der Suchbereich gueltig ist !! + SwPosition *pSttPos = aRegion.GetMark(), + *pEndPos = aRegion.GetPoint(); + *pSttPos = *pTmpCrsr->Start(); + *pEndPos = *pTmpCrsr->End(); + if( bSrchBkwrd ) + aRegion.Exchange(); + + if( !nCrsrCnt && !pPHdl && !bIsUnoCrsr ) + pPHdl = new _PercentHdl( aRegion ); + + // solange gefunden und nicht auf gleicher Position haengen bleibt + while( *pSttPos <= *pEndPos && + 0 != ( nFndRet = rParas.Find( pCurCrsr, fnMove, + &aRegion, bInReadOnly )) && + ( !pFndRing || + *pFndRing->GetPoint() != *pCurCrsr->GetPoint() || + *pFndRing->GetMark() != *pCurCrsr->GetMark() )) + { + if( !( FIND_NO_RING & nFndRet )) + { + // Bug 24084: Ring richtig herum aufbauen -> gleiche Mimik + // wie beim CreateCrsr !!!! + + SwCursor* pNew = pCurCrsr->Create( pFndRing ); + if( !pFndRing ) + pFndRing = pNew; + + pNew->SetMark(); + *pNew->GetMark() = *pCurCrsr->GetMark(); + } + + ++nFound; + + if( !( eFndRngs & FND_IN_SELALL) ) + { + bEnde = TRUE; + break; + } + + if( coSrchRplcThreshold == nFound && pDoc->DoesUndo() + && rParas.IsReplaceMode() && + pCurCrsr->MaxReplaceArived() ) + { + bEnde = TRUE; + break; + } + + if( bSrchBkwrd ) + // bewege pEndPos vor den gefundenen Bereich + *pEndPos = *pCurCrsr->Start(); + else + // bewege pSttPos hinter den gefundenen Bereich + *pSttPos = *pCurCrsr->End(); + + if( *pSttPos == *pEndPos ) // im Bereich, aber am Ende + break; // fertig + + if( !nCrsrCnt && !bIsUnoCrsr ) + pPHdl->NextPos( *aRegion.GetMark() ); + } + + if( bEnde || !( eFndRngs & ( FND_IN_SELALL | FND_IN_SEL )) ) + break; + + pTmpCrsr = ((SwPaM*)pTmpCrsr->GetNext()); + if( nCrsrCnt && !bIsUnoCrsr ) + pPHdl->NextPos( ++pPHdl->nActPos ); + + } while( pTmpCrsr != pSaveCrsr ); + + if( nFound && !pFndRing ) // falls kein Ring aufgebaut werden soll + pFndRing = pCurCrsr->Create(); + + delete pPHdl; + pDoc->DoUndo( bDoesUndo ); + return nFound; +} + + +int lcl_MakeSelFwrd( const SwNode& rSttNd, const SwNode& rEndNd, + SwPaM& rPam, int bFirst ) +{ + if( rSttNd.GetIndex() + 1 == rEndNd.GetIndex() ) + return FALSE; + + SwNodes& rNds = rPam.GetDoc()->GetNodes(); + rPam.DeleteMark(); + SwCntntNode* pCNd; + if( !bFirst ) + { + rPam.GetPoint()->nNode = rSttNd; + pCNd = rNds.GoNext( &rPam.GetPoint()->nNode ); + if( !pCNd ) + return FALSE; + pCNd->MakeStartIndex( &rPam.GetPoint()->nContent ); + } + else if( rSttNd.GetIndex() > rPam.GetPoint()->nNode.GetIndex() || + rPam.GetPoint()->nNode.GetIndex() >= rEndNd.GetIndex() ) + return FALSE; // steht nicht in dieser Section + + rPam.SetMark(); + rPam.GetPoint()->nNode = rEndNd; + pCNd = rNds.GoPrevious( &rPam.GetPoint()->nNode ); + if( !pCNd ) + return FALSE; + pCNd->MakeEndIndex( &rPam.GetPoint()->nContent ); + + return *rPam.GetMark() < *rPam.GetPoint(); +} + + +int lcl_MakeSelBkwrd( const SwNode& rSttNd, const SwNode& rEndNd, + SwPaM& rPam, int bFirst ) +{ + if( rEndNd.GetIndex() + 1 == rSttNd.GetIndex() ) + return FALSE; + + SwNodes& rNds = rPam.GetDoc()->GetNodes(); + rPam.DeleteMark(); + SwCntntNode* pCNd; + if( !bFirst ) + { + rPam.GetPoint()->nNode = rSttNd; + pCNd = rNds.GoPrevious( &rPam.GetPoint()->nNode ); + if( !pCNd ) + return FALSE; + pCNd->MakeEndIndex( &rPam.GetPoint()->nContent ); + } + else if( rEndNd.GetIndex() > rPam.GetPoint()->nNode.GetIndex() || + rPam.GetPoint()->nNode.GetIndex() >= rSttNd.GetIndex() ) + return FALSE; // steht nicht in dieser Section + + rPam.SetMark(); + rPam.GetPoint()->nNode = rEndNd; + pCNd = rNds.GoNext( &rPam.GetPoint()->nNode ); + if( !pCNd ) + return FALSE; + pCNd->MakeStartIndex( &rPam.GetPoint()->nContent ); + + return *rPam.GetPoint() < *rPam.GetMark(); +} + + +// diese Methode "sucht" fuer alle Anwendungsfaelle, denn in SwFindParas +// steht immer die richtigen Parameter und die entsprechende Find-Methode + +ULONG SwCursor::FindAll( SwFindParas& rParas, + SwDocPositions nStart, SwDocPositions nEnde, + FindRanges eFndRngs ) +{ + SwCrsrSaveState aSaveState( *this ); + + // Region erzeugen, ohne das diese in den Ring aufgenommen wird ! + SwPaM aRegion( *GetPoint() ); + SwMoveFn fnMove = MakeFindRange( nStart, nEnde, &aRegion ); + + ULONG nFound = 0; + int bMvBkwrd = fnMove == fnMoveBackward; + FASTBOOL bInReadOnly = IsReadOnlyAvailable(); + + SwCursor* pFndRing = 0; + SwNodes& rNds = GetDoc()->GetNodes(); + + // suche in Bereichen ? + if( FND_IN_SEL & eFndRngs ) + { + // String nicht im Bereich gefunden, dann erhalte alle Bereiche, + // der Cursor beleibt unveraendert + if( 0 == ( nFound = lcl_FindSelection( rParas, this, fnMove, + pFndRing, aRegion, eFndRngs, + bInReadOnly ) )) + return nFound; + + // der String wurde ein- bis mehrmals gefunden. Das steht alles + // im neuen Crsr-Ring. Darum hebe erstmal den alten Ring auf + while( GetNext() != this ) + delete GetNext(); + + *GetPoint() = *pFndRing->GetPoint(); + SetMark(); + *GetMark() = *pFndRing->GetMark(); + pFndRing->MoveRingTo( this ); + delete pFndRing; + } + else if( FND_IN_OTHER & eFndRngs ) + { + // Cursor als Kopie vom akt. und in den Ring aufnehmen + // Verkettung zeigt immer auf den zuerst erzeugten, also vorwaerts + SwCursor* pSav = Create( this ); // sicher den aktuellen Crsr + + // wenn schon ausserhalb vom Bodytext, suche von der Position, + // ansonsten beginne mit der 1. GrundSection + if( bMvBkwrd + ? lcl_MakeSelBkwrd( rNds.GetEndOfExtras(), + *rNds.GetEndOfPostIts().StartOfSectionNode(), + *this, rNds.GetEndOfExtras().GetIndex() >= + GetPoint()->nNode.GetIndex() ) + : lcl_MakeSelFwrd( *rNds.GetEndOfPostIts().StartOfSectionNode(), + rNds.GetEndOfExtras(), *this, + rNds.GetEndOfExtras().GetIndex() >= + GetPoint()->nNode.GetIndex() )) + { + nFound = lcl_FindSelection( rParas, this, fnMove, pFndRing, + aRegion, eFndRngs, bInReadOnly ); + } + + if( !nFound ) + { + // den alten wieder zurueck + *GetPoint() = *pSav->GetPoint(); + if( pSav->HasMark() ) + { + SetMark(); + *GetMark() = *pSav->GetMark(); + } + else + DeleteMark(); + return 0; + } + + delete pSav; + if( !( FND_IN_SELALL & eFndRngs )) + { + // es sollte nur einer gesucht werden, also fuege in dazu + // egal in welche Richtung, SPoint ist immer groesser als Mark, + // wenn der Suchbereich gueltig ist !! + *GetPoint() = *pFndRing->GetPoint(); + SetMark(); + *GetMark() = *pFndRing->GetMark(); + } + else + { + // es wurde ein- bis mehrmals gefunden. Das steht alles + // im neuen Crsr-Ring. Darum hebe erstmal den alten Ring auf + while( GetNext() != this ) + delete GetNext(); + + *GetPoint() = *pFndRing->GetPoint(); + SetMark(); + *GetMark() = *pFndRing->GetMark(); + pFndRing->MoveRingTo( this ); + } + delete pFndRing; + } + else if( FND_IN_SELALL & eFndRngs ) + { + SwCursor* pSav = Create( this ); // sicher den aktuellen Crsr + + const SwNode* pSttNd = ( FND_IN_BODYONLY & eFndRngs ) + ? rNds.GetEndOfContent().StartOfSectionNode() + : rNds.GetEndOfPostIts().StartOfSectionNode(); + + if( bMvBkwrd + ? lcl_MakeSelBkwrd( rNds.GetEndOfContent(), *pSttNd,*this, FALSE ) + : lcl_MakeSelFwrd( *pSttNd, rNds.GetEndOfContent(), *this, FALSE )) + { + nFound = lcl_FindSelection( rParas, this, fnMove, pFndRing, + aRegion, eFndRngs, bInReadOnly ); + } + + if( !nFound ) + { + // den alten wieder zurueck + *GetPoint() = *pSav->GetPoint(); + if( pSav->HasMark() ) + { + SetMark(); + *GetMark() = *pSav->GetMark(); + } + else + DeleteMark(); + return 0; + } + // es wurde ein- bis mehrmals gefunden. Das steht alles + // im neuen Crsr-Ring. Darum hebe erstmal den alten Ring auf + delete pSav; + + while( GetNext() != this ) + delete GetNext(); + + *GetPoint() = *pFndRing->GetPoint(); + SetMark(); + *GetMark() = *pFndRing->GetMark(); + pFndRing->MoveRingTo( this ); + delete pFndRing; + } + else + { + // ist ein GetMark gesetzt, dann wird bei gefundenem Object + // der GetMark beibehalten !! Dadurch kann ein Bereich mit der Suche + // aufgespannt werden. + SwPosition aMarkPos( *GetMark() ); + int bMarkPos = HasMark() && !eFndRngs; + + if( 0 != (nFound = rParas.Find( this, fnMove, + &aRegion, bInReadOnly ) ? 1 : 0) + && bMarkPos ) + *GetMark() = aMarkPos; + } + + if( nFound && SwCursor::IsSelOvr( SELOVER_TOGGLE | SELOVER_CHANGEPOS ) ) + nFound = 0; + return nFound; +} + + +void SwCursor::FillFindPos( SwDocPositions ePos, SwPosition& rPos ) const +{ + BOOL bIsStart = TRUE; + SwCntntNode* pCNd = 0; + SwNodes& rNds = GetDoc()->GetNodes(); + + switch( ePos ) + { + case DOCPOS_START: + rPos.nNode = *rNds.GetEndOfContent().StartOfSectionNode(); + pCNd = rNds.GoNext( &rPos.nNode ); + break; + + case DOCPOS_END: + rPos.nNode = rNds.GetEndOfContent(); + pCNd = rNds.GoPrevious( &rPos.nNode ); + bIsStart = FALSE; + break; + + case DOCPOS_OTHERSTART: + rPos.nNode = *rNds[ ULONG(0) ]; + pCNd = rNds.GoNext( &rPos.nNode ); + break; + + case DOCPOS_OTHEREND: + rPos.nNode = *rNds.GetEndOfContent().StartOfSectionNode(); + pCNd = rNds.GoPrevious( &rPos.nNode ); + bIsStart = FALSE; + break; + +// case DOCPOS_CURR: + default: + rPos = *GetPoint(); + } + + if( pCNd ) + { + xub_StrLen nCPos = 0; + if( !bIsStart ) + nCPos = pCNd->Len(); + rPos.nContent.Assign( pCNd, nCPos ); + } +} + +FASTBOOL SwCursor::MaxReplaceArived() +{ + return FALSE; +} + +FASTBOOL SwCursor::IsStartWord() const +{ + FASTBOOL bRet = FALSE; + const SwTxtNode* pTxtNd = GetNode()->GetTxtNode(); + if( pTxtNd && pBreakIt->xBreak.is() ) + { + sal_Int32 nPtPos = GetPoint()->nContent.GetIndex(); + bRet = pBreakIt->xBreak->isBeginWord( pTxtNd->GetTxt(), nPtPos, + pBreakIt->GetLocale( pTxtNd->GetLang( nPtPos )), + WordType::ANYWORD_IGNOREWHITESPACES ); + } + return bRet; +} + +FASTBOOL SwCursor::IsEndWord() const +{ + FASTBOOL bRet = FALSE; + const SwTxtNode* pTxtNd = GetNode()->GetTxtNode(); + if( pTxtNd && pBreakIt->xBreak.is() ) + { + sal_Int32 nPtPos = GetPoint()->nContent.GetIndex(); + bRet = pBreakIt->xBreak->isEndWord( pTxtNd->GetTxt(), nPtPos, + pBreakIt->GetLocale( pTxtNd->GetLang( nPtPos ) ), + WordType::ANYWORD_IGNOREWHITESPACES ); + } + return bRet; +} + +FASTBOOL SwCursor::IsInWord() const +{ + return !IsEndWord(); +} + +FASTBOOL SwCursor::GoStartWord() +{ + FASTBOOL bRet = FALSE; + const SwTxtNode* pTxtNd = GetNode()->GetTxtNode(); + if( pTxtNd && pBreakIt->xBreak.is() ) + { + SwCrsrSaveState aSave( *this ); + xub_StrLen nPtPos = GetPoint()->nContent.GetIndex(); + nPtPos = pBreakIt->xBreak->getWordBoundary( + pTxtNd->GetTxt(), nPtPos, + pBreakIt->GetLocale( pTxtNd->GetLang( nPtPos ) ), + WordType::ANYWORD_IGNOREWHITESPACES, + FALSE ).startPos; + + if( 0 <= nPtPos && nPtPos < pTxtNd->GetTxt().Len() ) + { + GetPoint()->nContent = nPtPos; + if( !IsSelOvr() ) + bRet = TRUE; + } + } + return bRet; +} + +FASTBOOL SwCursor::GoEndWord() +{ + FASTBOOL bRet = FALSE; + const SwTxtNode* pTxtNd = GetNode()->GetTxtNode(); + if( pTxtNd && pBreakIt->xBreak.is() ) + { + SwCrsrSaveState aSave( *this ); + xub_StrLen nPtPos = GetPoint()->nContent.GetIndex(); + nPtPos = pBreakIt->xBreak->getWordBoundary( + pTxtNd->GetTxt(), nPtPos, + pBreakIt->GetLocale( pTxtNd->GetLang( nPtPos ) ), + WordType::ANYWORD_IGNOREWHITESPACES, + TRUE ).endPos; + + if( 0 <= nPtPos && nPtPos <= pTxtNd->GetTxt().Len() && + GetPoint()->nContent.GetIndex() != nPtPos ) + { + GetPoint()->nContent = nPtPos; + if( !IsSelOvr() ) + bRet = TRUE; + } + } + return bRet; +} + +FASTBOOL SwCursor::GoNextWord() +{ + FASTBOOL bRet = FALSE; + const SwTxtNode* pTxtNd = GetNode()->GetTxtNode(); + if( pTxtNd && pBreakIt->xBreak.is() ) + { + SwCrsrSaveState aSave( *this ); + xub_StrLen nPtPos = GetPoint()->nContent.GetIndex(); + + nPtPos = pBreakIt->xBreak->nextWord( + pTxtNd->GetTxt(), nPtPos, + pBreakIt->GetLocale( pTxtNd->GetLang( nPtPos ) ), + WordType::ANYWORD_IGNOREWHITESPACES ).startPos; + + if( 0 <= nPtPos && nPtPos < pTxtNd->GetTxt().Len() ) + { + GetPoint()->nContent = nPtPos; + if( !IsSelOvr() ) + bRet = TRUE; + } + } + return bRet; +} + +FASTBOOL SwCursor::GoPrevWord() +{ + FASTBOOL bRet = FALSE; + const SwTxtNode* pTxtNd = GetNode()->GetTxtNode(); + if( pTxtNd && pBreakIt->xBreak.is() ) + { + SwCrsrSaveState aSave( *this ); + xub_StrLen nPtPos = GetPoint()->nContent.GetIndex(); + nPtPos = pBreakIt->xBreak->previousWord( + pTxtNd->GetTxt(), nPtPos, + pBreakIt->GetLocale( pTxtNd->GetLang( nPtPos ) ), + WordType::ANYWORD_IGNOREWHITESPACES ).startPos; + + if( 0 <= nPtPos && nPtPos < pTxtNd->GetTxt().Len() ) + { + GetPoint()->nContent = nPtPos; + if( !IsSelOvr() ) + bRet = TRUE; + } + } + return bRet; +} + +FASTBOOL SwCursor::SelectWord( const Point* pPt ) +{ + SwCrsrSaveState aSave( *this ); + + FASTBOOL bRet = FALSE; + BOOL bForward = TRUE; + DeleteMark(); + SwRootFrm* pLayout; + if( pPt && 0 != (pLayout = GetDoc()->GetRootFrm()) ) + { + // set the cursor to the layout position + Point aPt( *pPt ); + pLayout->GetCrsrOfst( GetPoint(), aPt ); + } + + const SwTxtNode* pTxtNd = GetNode()->GetTxtNode(); + if( pTxtNd && pBreakIt->xBreak.is() ) + { + xub_StrLen nPtPos = GetPoint()->nContent.GetIndex(); + Boundary aBndry( pBreakIt->xBreak->getWordBoundary( + pTxtNd->GetTxt(), nPtPos, + pBreakIt->GetLocale( pTxtNd->GetLang( nPtPos ) ), + WordType::ANY_WORD /*ANYWORD_IGNOREWHITESPACES*/, + bForward )); + + if( aBndry.startPos != aBndry.endPos ) + { + SetMark(); + GetMark()->nContent = aBndry.startPos; + GetPoint()->nContent = aBndry.endPos; + if( !IsSelOvr() ) + bRet = TRUE; + } + } + + if( !bRet ) + RestoreSavePos(); + return bRet; +} + +//----------------------------------------------------------------------------- +FASTBOOL SwCursor::GoSentence( SentenceMoveType eMoveType ) +{ + FASTBOOL bRet = FALSE; + const SwTxtNode* pTxtNd = GetNode()->GetTxtNode(); + if( pTxtNd && pBreakIt->xBreak.is() ) + { + SwCrsrSaveState aSave( *this ); + xub_StrLen nPtPos = GetPoint()->nContent.GetIndex(); + switch ( eMoveType ) + { + case END_SENT: + case NEXT_SENT: + nPtPos = pBreakIt->xBreak->endOfSentence( pTxtNd->GetTxt(), + nPtPos, pBreakIt->GetLocale( + pTxtNd->GetLang( nPtPos ) )); + break; + case START_SENT: + case PREV_SENT: + nPtPos = pBreakIt->xBreak->beginOfSentence( pTxtNd->GetTxt(), + nPtPos, pBreakIt->GetLocale( + pTxtNd->GetLang( nPtPos ) )); + break; + } + + if( 0 <= nPtPos && nPtPos < pTxtNd->GetTxt().Len() ) + { + GetPoint()->nContent = nPtPos; + if( !IsSelOvr() ) + bRet = TRUE; + } + } + return bRet; +} + +FASTBOOL SwCursor::LeftRight( BOOL bLeft, USHORT nCnt ) +{ + SwTableCursor* pTblCrsr = (SwTableCursor*)*this; + if( pTblCrsr ) + return bLeft ? pTblCrsr->GoPrevCell( nCnt ) + : pTblCrsr->GoNextCell( nCnt ); + + // kann der Cursor n-mal weiterverschoben werden ? + SwCrsrSaveState aSave( *this ); + SwMoveFn fnMove = bLeft ? fnMoveBackward : fnMoveForward; + while( nCnt && Move( fnMove, fnGoCntnt ) ) + --nCnt; + return 0 == nCnt && !IsInProtectTable( TRUE ) && + !IsSelOvr( SELOVER_TOGGLE | SELOVER_CHANGEPOS ); +} + + +FASTBOOL SwCursor::UpDown( BOOL bUp, USHORT nCnt, + Point* pPt, long nUpDownX ) +{ + SwTableCursor* pTblCrsr = (SwTableCursor*)*this; + + // vom Tabellen Crsr Point/Mark in der gleichen Box ?? + // dann stelle den Point an den Anfang der Box + if( pTblCrsr && GetNode( TRUE )->FindStartNode() == + GetNode( FALSE )->FindStartNode() && End() != GetPoint() ) + Exchange(); + + FASTBOOL bRet = FALSE; + Point aPt; + if( pPt ) + aPt = *pPt; + SwCntntFrm* pFrm = GetCntntNode()->GetFrm( &aPt, GetPoint() ); + + if( pFrm ) + { + SwCrsrSaveState aSave( *this ); + + if( !pPt ) + { + SwRect aTmpRect; + pFrm->GetCharRect( aTmpRect, *GetPoint() ); + aPt = aTmpRect.Pos(); + nUpDownX = aPt.X() - pFrm->Frm().Left(); + } + + // Bei Fussnoten ist auch die Bewegung in eine andere Fussnote erlaubt. + // aber keine Selection!! + const FASTBOOL bChkRange = pFrm->IsInFtn() && !HasMark() + ? FALSE : TRUE; + const SwPosition aOldPos( *GetPoint() ); + BOOL bInReadOnly = IsReadOnlyAvailable(); + + while( nCnt && + (bUp ? pFrm->UnitUp( this, nUpDownX, bInReadOnly ) + : pFrm->UnitDown( this, nUpDownX, bInReadOnly ) ) && + CheckNodesRange( aOldPos.nNode, GetPoint()->nNode, bChkRange )) + { + pFrm = GetCntntNode()->GetFrm( &aPt, GetPoint() ); + --nCnt; + } + + if( !nCnt && !IsSelOvr( SELOVER_TOGGLE | SELOVER_CHANGEPOS ) ) // die gesamte Anzahl durchlaufen ? + { + if( !pTblCrsr ) + { + // dann versuche den Cursor auf die Position zu setzen, + // auf halber Heohe vom Char-Rectangle + pFrm = GetCntntNode()->GetFrm( &aPt, GetPoint() ); + SwCrsrMoveState eTmpState( MV_UPDOWN ); + eTmpState.bSetInReadOnly = bInReadOnly; + SwRect aTmpRect; + pFrm->GetCharRect( aTmpRect, *GetPoint(), &eTmpState ); + aPt.Y() = aTmpRect.Center().Y(); + pFrm->Calc(); + aPt.X() = pFrm->Frm().Left() + nUpDownX; + pFrm->GetCrsrOfst( GetPoint(), aPt, &eTmpState ); + } + bRet = TRUE; + } + else + *GetPoint() = aOldPos; + } + return bRet; +} + + +FASTBOOL SwCursor::LeftRightMargin( BOOL bLeft, BOOL bAPI ) +{ + Point aPt; + SwCntntFrm * pFrm = GetCntntNode()->GetFrm( &aPt, GetPoint() ); + return pFrm && (bLeft ? pFrm->LeftMargin( this ) + : pFrm->RightMargin( this, bAPI )); +} + +FASTBOOL SwCursor::IsAtLeftRightMargin( BOOL bLeft, BOOL bAPI ) const +{ + FASTBOOL bRet = FALSE; + Point aPt; + SwCntntFrm * pFrm = GetCntntNode()->GetFrm( &aPt, GetPoint() ); + if( pFrm ) + { + SwPaM aPam( *GetPoint() ); + if( !bLeft && aPam.GetPoint()->nContent.GetIndex() ) + aPam.GetPoint()->nContent--; + bRet = (bLeft ? pFrm->LeftMargin( &aPam ) + : pFrm->RightMargin( &aPam, bAPI )) + && *aPam.GetPoint() == *GetPoint(); + } + return bRet; +} + +FASTBOOL SwCursor::SttEndDoc( BOOL bStt ) +{ + SwCrsrSaveState aSave( *this ); + + // Springe beim Selektieren nie ueber Section-Grenzen !! + // kann der Cursor weiterverschoben werden ? + SwMoveFn fnMove = bStt ? fnMoveBackward : fnMoveForward; + FASTBOOL bRet = (!HasMark() || !IsNoCntnt() ) && + Move( fnMove, fnGoDoc ) && + !IsInProtectTable( TRUE ) && + !IsSelOvr( SELOVER_TOGGLE | SELOVER_CHANGEPOS | + SELOVER_ENABLEREVDIREKTION ); + + return bRet; +} + +FASTBOOL SwCursor::GoPrevNextCell( BOOL bNext, USHORT nCnt ) +{ + const SwTableNode* pTblNd = GetPoint()->nNode.GetNode().FindTableNode(); + if( !pTblNd ) + return FALSE; + + // liegt vor dem StartNode der Cell ein weiterer EndNode, dann + // gibt es auch eine vorherige Celle + SwCrsrSaveState aSave( *this ); + SwNodeIndex& rPtIdx = GetPoint()->nNode; + if( bNext ) + { + while( nCnt-- ) + { + SwNodeIndex aCellIdx( *rPtIdx.GetNode().FindTableBoxStartNode()-> + EndOfSectionNode(), 1 ); + if( !aCellIdx.GetNode().IsStartNode() ) + return FALSE; + rPtIdx = aCellIdx; + } + } + else + { + while( nCnt-- ) + { + SwNodeIndex aCellIdx( *rPtIdx.GetNode().FindTableBoxStartNode(),-1); + if( !aCellIdx.GetNode().IsEndNode() ) + return FALSE; + + rPtIdx = *aCellIdx.GetNode().StartOfSectionNode(); + } + } + + rPtIdx++; + if( !rPtIdx.GetNode().IsCntntNode() ) + GetDoc()->GetNodes().GoNextSection( &rPtIdx, TRUE, FALSE ); + GetPoint()->nContent.Assign( GetCntntNode(), 0 ); + + return !IsInProtectTable( TRUE ); +} + +FASTBOOL SwCursor::GotoTable( const String& rName ) +{ + FASTBOOL bRet = FALSE; + // Tabellenselektion oder ueberhaupt Selection ? + // Das ist eine ungueltige Action ! + if( !(SwTableCursor*)*this && !HasMark() ) + { + SwTable* pTmpTbl = SwTable::FindTable( GetDoc()->FindTblFmtByName( rName ) ); + if( pTmpTbl ) + { + // eine Tabelle im normalen NodesArr + SwCrsrSaveState aSave( *this ); + GetPoint()->nNode = *pTmpTbl->GetTabSortBoxes()[ 0 ]-> + GetSttNd()->FindTableNode(); + Move( fnMoveForward, fnGoCntnt ); + bRet = !IsSelOvr(); + } + } + return bRet; +} + +FASTBOOL SwCursor::GotoTblBox( const String& rName ) +{ + FASTBOOL bRet = FALSE; + const SwTableNode* pTblNd = GetPoint()->nNode.GetNode().FindTableNode(); + if( pTblNd ) + { + // erfrage die Box, mit dem Nanen + const SwTableBox* pTblBox = pTblNd->GetTable().GetTblBox( rName ); + if( pTblBox && pTblBox->GetSttNd() && + ( !pTblBox->GetFrmFmt()->GetProtect().IsCntntProtected() || + IsReadOnlyAvailable() ) ) + { + SwCrsrSaveState aSave( *this ); + GetPoint()->nNode = *pTblBox->GetSttNd(); + Move( fnMoveForward, fnGoCntnt ); + bRet = !IsSelOvr(); + } + } + return bRet; +} + +FASTBOOL SwCursor::MovePara(SwWhichPara fnWhichPara, SwPosPara fnPosPara ) +{ + SwCrsrSaveState aSave( *this ); + return (*fnWhichPara)( *this, fnPosPara ) && + !IsInProtectTable( TRUE ) && + !IsSelOvr( SELOVER_TOGGLE | SELOVER_CHANGEPOS ); +} + + +FASTBOOL SwCursor::MoveSection( SwWhichSection fnWhichSect, + SwPosSection fnPosSect) +{ + SwCrsrSaveState aSave( *this ); + return (*fnWhichSect)( *this, fnPosSect ) && + !IsInProtectTable( TRUE ) && + !IsSelOvr( SELOVER_TOGGLE | SELOVER_CHANGEPOS ); +} + +/* + FASTBOOL MoveTable( SwWhichTable, SwPosTable ); + FASTBOOL MoveColumn( SwWhichColumn, SwPosColumn ); + FASTBOOL MoveRegion( SwWhichRegion, SwPosRegion ); +*/ + +void SwCursor::RestoreSavePos() // Point auf die SavePos setzen +{ + if( pSavePos ) + { + GetPoint()->nNode = pSavePos->nNode; + GetPoint()->nContent.Assign( GetCntntNode(), pSavePos->nCntnt ); + } +} + + +/* */ + +SwTableCursor::SwTableCursor( const SwPosition &rPos, SwPaM* pRing ) + : SwCursor( rPos, pRing ) +{ + bParked = FALSE; + bChg = FALSE; + nTblPtNd = 0, nTblMkNd = 0; + nTblPtCnt = 0, nTblMkCnt = 0; +} + +SwTableCursor::~SwTableCursor() {} + +SwTableCursor::operator SwTableCursor* () { return this; } + +BOOL lcl_SeekEntry( const SwSelBoxes& rTmp, const SwStartNode* pSrch, USHORT& rFndPos ) +{ + ULONG nIdx = pSrch->GetIndex(); + + register USHORT nO = rTmp.Count(), nM, nU = 0; + if( nO > 0 ) + { + nO--; + while( nU <= nO ) + { + nM = nU + ( nO - nU ) / 2; + if( rTmp[ nM ]->GetSttNd() == pSrch ) + { + rFndPos = nM; + return TRUE; + } + else if( rTmp[ nM ]->GetSttIdx() < nIdx ) + nU = nM + 1; + else if( nM == 0 ) + return FALSE; + else + nO = nM - 1; + } + } + return FALSE; +} + + +SwCursor* SwTableCursor::MakeBoxSels( SwCursor* pAktCrsr ) +{ + if( bChg ) // ??? + { + if( bParked ) + { + // wieder in den Inhalt schieben + Exchange(); + Move( fnMoveForward ); + Exchange(); + Move( fnMoveForward ); + bParked = FALSE; + } + + bChg = FALSE; + + // temp Kopie anlegen, damit alle Boxen, fuer die schon Cursor + // existieren, entfernt werden koennen. + SwSelBoxes aTmp; + aTmp.Insert( &aSelBoxes ); + + //Jetzt die Alten und die neuen abgleichen. + SwNodes& rNds = pAktCrsr->GetDoc()->GetNodes(); + USHORT nPos; + const SwStartNode* pSttNd; + SwPaM* pCur = pAktCrsr; + do { + BOOL bDel = FALSE; + pSttNd = pCur->GetPoint()->nNode.GetNode().FindTableBoxStartNode(); + if( !pCur->HasMark() || !pSttNd || + pSttNd != pCur->GetMark()->nNode.GetNode().FindTableBoxStartNode() ) + bDel = TRUE; + + else if( lcl_SeekEntry( aTmp, pSttNd, nPos )) + { + SwNodeIndex aIdx( *pSttNd, 1 ); + const SwNode* pNd = &aIdx.GetNode(); + if( !pNd->IsCntntNode() ) + pNd = rNds.GoNextSection( &aIdx, TRUE, FALSE ); + + SwPosition* pPos = pCur->GetMark(); + if( pNd != &pPos->nNode.GetNode() ) + pPos->nNode = *pNd; + pPos->nContent.Assign( (SwCntntNode*)pNd, 0 ); + + aIdx.Assign( *pSttNd->EndOfSectionNode(), - 1 ); + if( !( pNd = &aIdx.GetNode())->IsCntntNode() ) + pNd = rNds.GoPrevSection( &aIdx, TRUE, FALSE ); + + pPos = pCur->GetPoint(); + if( pNd != &pPos->nNode.GetNode() ) + pPos->nNode = *pNd; + pPos->nContent.Assign( (SwCntntNode*)pNd, ((SwCntntNode*)pNd)->Len() ); + + aTmp.Remove( nPos ); + } + else + bDel = TRUE; + + pCur = (SwPaM*)pCur->GetNext(); + if( bDel ) + { + SwPaM* pDel = (SwPaM*)pCur->GetPrev(); +/* +JP 20.07.98: der alte Code geht mit dem UNO-TableCrsr nicht + if( pDel == pAktCrsr ) + { + if( pAktCrsr->GetNext() == pAktCrsr ) + { + pAktCrsr->DeleteMark(); + break; // es gibt nichts mehr zu loeschen! + } + pAktCrsr = (SwCursor*)pDel->GetPrev(); + } + delete pDel; +*/ + + if( pDel == pAktCrsr ) + pAktCrsr->DeleteMark(); + else + delete pDel; + } + } while ( pAktCrsr != pCur ); + + for( nPos = 0; nPos < aTmp.Count(); ++nPos ) + { + pSttNd = aTmp[ nPos ]->GetSttNd(); + + SwNodeIndex aIdx( *pSttNd, 1 ); + const SwNode* pNd = &aIdx.GetNode(); + if( !pNd->IsCntntNode() ) + pNd = rNds.GoNextSection( &aIdx, TRUE, FALSE ); + + SwPaM* pNew; + if( pAktCrsr->GetNext() == pAktCrsr && !pAktCrsr->HasMark() ) + { + pNew = pAktCrsr; + pNew->GetPoint()->nNode = *pNd; + pNew->GetPoint()->nContent.Assign( (SwCntntNode*)pNd, 0 ); + } + else + { + pNew = pAktCrsr->Create( pAktCrsr ); + pNew->GetPoint()->nNode = *pNd; + pNew->GetPoint()->nContent.Assign( (SwCntntNode*)pNd, 0 ); + } + pNew->SetMark(); + + SwPosition* pPos = pNew->GetPoint(); + pPos->nNode.Assign( *pSttNd->EndOfSectionNode(), - 1 ); + if( !( pNd = &pPos->nNode.GetNode())->IsCntntNode() ) + pNd = rNds.GoPrevSection( &pPos->nNode, TRUE, FALSE ); + + pPos->nContent.Assign( (SwCntntNode*)pNd, ((SwCntntNode*)pNd)->Len() ); + } + } + return pAktCrsr; +} + + +void SwTableCursor::InsertBox( const SwTableBox& rTblBox ) +{ + SwTableBox* pBox = (SwTableBox*)&rTblBox; + aSelBoxes.Insert( pBox ); + bChg = TRUE; +} + +FASTBOOL SwTableCursor::IsCrsrMovedUpdt() +{ + if( !IsCrsrMoved() ) + return FALSE; + + nTblMkNd = GetMark()->nNode.GetIndex(); + nTblPtNd = GetPoint()->nNode.GetIndex(); + nTblMkCnt = GetMark()->nContent.GetIndex(); + nTblPtCnt = GetPoint()->nContent.GetIndex(); + return TRUE; +} + + +// Parke den Tabellen-Cursor auf dem StartNode der Boxen. +void SwTableCursor::ParkCrsr() +{ + // Index aus dem TextNode abmelden + SwNode* pNd = &GetPoint()->nNode.GetNode(); + if( !pNd->IsStartNode() ) + pNd = pNd->StartOfSectionNode(); + GetPoint()->nNode = *pNd; + GetPoint()->nContent.Assign( 0, 0 ); + + pNd = &GetMark()->nNode.GetNode(); + if( !pNd->IsStartNode() ) + pNd = pNd->StartOfSectionNode(); + GetMark()->nNode = *pNd; + GetMark()->nContent.Assign( 0, 0 ); + + bChg = TRUE; + bParked = TRUE; +} + + +FASTBOOL SwTableCursor::HasReadOnlyBoxSel() const +{ + FASTBOOL bRet = FALSE; + for( USHORT n = aSelBoxes.Count(); n; ) + if( aSelBoxes[ --n ]->GetFrmFmt()->GetProtect().IsCntntProtected() ) + { + bRet = TRUE; + break; + } + return bRet; +} + + diff --git a/sw/source/core/crsr/trvlcol.cxx b/sw/source/core/crsr/trvlcol.cxx new file mode 100644 index 000000000000..b67fb46a79fc --- /dev/null +++ b/sw/source/core/crsr/trvlcol.cxx @@ -0,0 +1,168 @@ +/************************************************************************* + * + * $RCSfile: trvlcol.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:17 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#include "crsrsh.hxx" +#include "doc.hxx" +#include "layfrm.hxx" +#include "cntfrm.hxx" +#include "swcrsr.hxx" +#include "viscrs.hxx" +#include "callnk.hxx" + + + +SwLayoutFrm* GetCurrColumn( const SwLayoutFrm* pLayFrm ) +{ + while( pLayFrm && !pLayFrm->IsColumnFrm() ) + pLayFrm = pLayFrm->GetUpper(); + return (SwLayoutFrm*)pLayFrm; +} + + +SwLayoutFrm* GetNextColumn( const SwLayoutFrm* pLayFrm ) +{ + SwLayoutFrm* pActCol = GetCurrColumn( pLayFrm ); + return pActCol ? (SwLayoutFrm*)pActCol->GetNext() : 0; +} + + +SwLayoutFrm* GetPrevColumn( const SwLayoutFrm* pLayFrm ) +{ + SwLayoutFrm* pActCol = GetCurrColumn( pLayFrm ); + return pActCol ? (SwLayoutFrm*)pActCol->GetPrev() : 0; +} + + +SwCntntFrm* GetColumnStt( const SwLayoutFrm* pColFrm ) +{ + return pColFrm ? (SwCntntFrm*)pColFrm->ContainsCntnt() : 0; +} + + +SwCntntFrm* GetColumnEnd( const SwLayoutFrm* pColFrm ) +{ + SwCntntFrm *pRet = GetColumnStt( pColFrm ); + if( !pRet ) + return 0; + + SwCntntFrm *pNxt = pRet->GetNextCntntFrm(); + while( pNxt && pColFrm->IsAnLower( pNxt ) ) + { + pRet = pNxt; + pNxt = pNxt->GetNextCntntFrm(); + } + return pRet; +} + + +SwWhichColumn fnColumnPrev = &GetPrevColumn; +SwWhichColumn fnColumnCurr = &GetCurrColumn; +SwWhichColumn fnColumnNext = &GetNextColumn; +SwPosColumn fnColumnStart = &GetColumnStt; +SwPosColumn fnColumnEnd = &GetColumnEnd; + + +FASTBOOL SwCrsrShell::MoveColumn( SwWhichColumn fnWhichCol, SwPosColumn fnPosCol ) +{ + FASTBOOL bRet = FALSE; + if( !pTblCrsr ) + { + SwLayoutFrm* pLayFrm = GetCurrFrm()->GetUpper(); + if( pLayFrm && 0 != ( pLayFrm = (*fnWhichCol)( pLayFrm )) ) + { + SwCntntFrm* pCnt = (*fnPosCol)( pLayFrm ); + if( pCnt ) + { + SET_CURR_SHELL( this ); + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + SwCrsrSaveState aSaveState( *pCurCrsr ); + + pCnt->Calc(); // ??? + + Point aPt( pCnt->Frm().Pos() + pCnt->Prt().Pos() ); + if( fnPosCol == GetColumnEnd ) + { + aPt.X() += pCnt->Prt().Width(); + aPt.Y() += pCnt->Prt().Height(); + } + + pCnt->GetCrsrOfst( pCurCrsr->GetPoint(), aPt ); + + if( !pCurCrsr->IsInProtectTable( TRUE ) && + !pCurCrsr->IsSelOvr() ) + { + UpdateCrsr(); + bRet = TRUE; + } + } + } + } + return bRet; +} + + + diff --git a/sw/source/core/crsr/trvlfnfl.cxx b/sw/source/core/crsr/trvlfnfl.cxx new file mode 100644 index 000000000000..9a77134d8f60 --- /dev/null +++ b/sw/source/core/crsr/trvlfnfl.cxx @@ -0,0 +1,521 @@ +/************************************************************************* + * + * $RCSfile: trvlfnfl.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:17 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _SVDMODEL_HXX //autogen +#include +#endif +#ifndef _SVDPAGE_HXX //autogen +#include +#endif + +#ifndef _CRSRSH_HXX +#include +#endif +#ifndef _DOC_HXX +#include +#endif +#ifndef _PAGEFRM_HXX +#include +#endif +#ifndef _CNTFRM_HXX +#include +#endif +#ifndef _ROOTFRM_HXX +#include +#endif +#ifndef _VIEWIMP_HXX +#include +#endif +#ifndef _SWCRSR_HXX +#include +#endif +#ifndef _DFLYOBJ_HXX +#include +#endif +#ifndef _NDTXT_HXX +#include +#endif +#ifndef _FLYFRM_HXX +#include +#endif +#ifndef _TXTFTN_HXX //autogen +#include +#endif +#ifndef _FTNIDX_HXX //autogen +#include +#endif +#ifndef _VISCRS_HXX +#include +#endif +#ifndef _CALLNK_HXX +#include +#endif + +FASTBOOL SwCrsrShell::CallCrsrFN( FNCrsr fnCrsr ) +{ + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, + SwCursor* pCrsr = pTblCrsr ? pTblCrsr : pCurCrsr; + FASTBOOL bRet = (pCrsr->*fnCrsr)(); + if( bRet ) + UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE | + SwCrsrShell::READONLY ); + return bRet; +} + +FASTBOOL SwCursor::GotoFtnTxt() +{ + // springe aus dem Content zur Fussnote + FASTBOOL bRet = FALSE; + SwTxtAttr *pFtn; + SwTxtNode* pTxtNd = GetPoint()->nNode.GetNode().GetTxtNode(); + + if( pTxtNd && 0 != ( + pFtn = pTxtNd->GetTxtAttr( GetPoint()->nContent, RES_TXTATR_FTN ) )) + { + SwCrsrSaveState aSaveState( *this ); + GetPoint()->nNode = *((SwTxtFtn*)pFtn)->GetStartNode(); + + SwCntntNode* pCNd = GetDoc()->GetNodes().GoNextSection( + &GetPoint()->nNode, + TRUE, !IsReadOnlyAvailable() ); + if( pCNd ) + { + GetPoint()->nContent.Assign( pCNd, 0 ); + bRet = !IsSelOvr( SELOVER_CHECKNODESSECTION | SELOVER_TOGGLE ); + } + } + return bRet; +} + +FASTBOOL SwCrsrShell::GotoFtnTxt() +{ + return CallCrsrFN( &SwCursor::GotoFtnTxt ); +} + + +FASTBOOL SwCursor::GotoFtnAnchor() +{ + // springe aus der Fussnote zum Anker + const SwNode* pSttNd = GetNode()->FindFootnoteStartNode(); + if( pSttNd ) + { + // durchsuche alle Fussnoten im Dokument nach diesem StartIndex + const SwTxtFtn* pTxtFtn; + const SwFtnIdxs& rFtnArr = pSttNd->GetDoc()->GetFtnIdxs(); + for( USHORT n = 0; n < rFtnArr.Count(); ++n ) + if( 0 != ( pTxtFtn = rFtnArr[ n ])->GetStartNode() && + pSttNd == &pTxtFtn->GetStartNode()->GetNode() ) + { + SwCrsrSaveState aSaveState( *this ); + + SwTxtNode& rTNd = (SwTxtNode&)pTxtFtn->GetTxtNode(); + + GetPoint()->nNode = rTNd; + GetPoint()->nContent.Assign( &rTNd, *pTxtFtn->GetStart() ); + + return !IsSelOvr( SELOVER_CHECKNODESSECTION | SELOVER_TOGGLE ); + } + } + return FALSE; +} + +FASTBOOL SwCrsrShell::GotoFtnAnchor() +{ + // springe aus der Fussnote zum Anker + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, + FASTBOOL bRet = pCurCrsr->GotoFtnAnchor(); + if( bRet ) + { + // BUG 5996: Tabellen-Kopfzeile sonderbehandeln + pCurCrsr->GetPtPos() = Point(); + UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE | + SwCrsrShell::READONLY ); + } + return bRet; +} + +inline CmpLE( const SwTxtFtn& rFtn, ULONG nNd, xub_StrLen nCnt ) +{ + ULONG nTNd = rFtn.GetTxtNode().GetIndex(); + return nTNd < nNd || ( nTNd == nNd && *rFtn.GetStart() <= nCnt ); +} +inline CmpL( const SwTxtFtn& rFtn, ULONG nNd, xub_StrLen nCnt ) +{ + ULONG nTNd = rFtn.GetTxtNode().GetIndex(); + return nTNd < nNd || ( nTNd == nNd && *rFtn.GetStart() < nCnt ); +} + +FASTBOOL SwCursor::GotoNextFtnAnchor() +{ + const SwFtnIdxs& rFtnArr = GetDoc()->GetFtnIdxs(); + const SwTxtFtn* pTxtFtn = 0; + USHORT nPos; + + if( rFtnArr.SeekEntry( GetPoint()->nNode, &nPos )) + { + // es gibt eine Fussnote mit dem Index, suche also die + // naechstgelegene + if( nPos < rFtnArr.Count() ) + { + ULONG nNdPos = GetPoint()->nNode.GetIndex(); + xub_StrLen nCntPos = GetPoint()->nContent.GetIndex(); + + pTxtFtn = rFtnArr[ nPos ]; + // suche vorewaerts zur naechsten + if( CmpLE( *pTxtFtn, nNdPos, nCntPos ) ) + { + pTxtFtn = 0; + for( ++nPos; nPos < rFtnArr.Count(); ++nPos ) + { + pTxtFtn = rFtnArr[ nPos ]; + if( !CmpLE( *pTxtFtn, nNdPos, nCntPos ) ) + break; // gefunden + pTxtFtn = 0; + } + } + else if( nPos ) + { + // suche rueckwaerts zur vorherigen + pTxtFtn = 0; + while( nPos ) + { + pTxtFtn = rFtnArr[ --nPos ]; + if( CmpLE( *pTxtFtn, nNdPos, nCntPos ) ) + { + pTxtFtn = rFtnArr[ ++nPos ]; + break; // gefunden + } +// pTxtFtn = 0; + } + } + } + } + else if( nPos < rFtnArr.Count() ) + pTxtFtn = rFtnArr[ nPos ]; + + FASTBOOL bRet = 0 != pTxtFtn; + if( bRet ) + { + SwCrsrSaveState aSaveState( *this ); + + SwTxtNode& rTNd = (SwTxtNode&)pTxtFtn->GetTxtNode(); + GetPoint()->nNode = rTNd; + GetPoint()->nContent.Assign( &rTNd, *pTxtFtn->GetStart() ); + bRet = !IsSelOvr(); + } + return bRet; +} + +FASTBOOL SwCursor::GotoPrevFtnAnchor() +{ + const SwFtnIdxs& rFtnArr = GetDoc()->GetFtnIdxs(); + const SwTxtFtn* pTxtFtn = 0; + USHORT nPos; + + if( rFtnArr.SeekEntry( GetPoint()->nNode, &nPos ) ) + { + // es gibt eine Fussnote mit dem Index, suche also die + // naechstgelegene + ULONG nNdPos = GetPoint()->nNode.GetIndex(); + xub_StrLen nCntPos = GetPoint()->nContent.GetIndex(); + + pTxtFtn = rFtnArr[ nPos ]; + // suche vorwaerts zur naechsten + if( CmpL( *pTxtFtn, nNdPos, nCntPos )) + { + for( ++nPos; nPos < rFtnArr.Count(); ++nPos ) + { + pTxtFtn = rFtnArr[ nPos ]; + if( !CmpL( *pTxtFtn, nNdPos, nCntPos ) ) + { + pTxtFtn = rFtnArr[ nPos-1 ]; + break; + } + } + } + else if( nPos ) + { + // suche rueckwaerts zur vorherigen + pTxtFtn = 0; + while( nPos ) + { + pTxtFtn = rFtnArr[ --nPos ]; + if( CmpL( *pTxtFtn, nNdPos, nCntPos )) + break; // gefunden + pTxtFtn = 0; + } + } + else + pTxtFtn = 0; + } + else if( nPos ) + pTxtFtn = rFtnArr[ nPos-1 ]; + + FASTBOOL bRet = 0 != pTxtFtn; + if( bRet ) + { + SwCrsrSaveState aSaveState( *this ); + + SwTxtNode& rTNd = (SwTxtNode&)pTxtFtn->GetTxtNode(); + GetPoint()->nNode = rTNd; + GetPoint()->nContent.Assign( &rTNd, *pTxtFtn->GetStart() ); + bRet = !IsSelOvr(); + } + return bRet; +} + +FASTBOOL SwCursor::GotoNextFtnCntnt() +{ + SwCrsrSaveState aSaveState( *this ); + + const SwNode* pSttNd = GetNode()->FindFootnoteStartNode(); + if( pSttNd ) + GotoFtnAnchor(); + + SwTxtFtn *pFtn; + SwTxtNode* pTxtNd = GetPoint()->nNode.GetNode().GetTxtNode(); + + if( !pTxtNd || 0 == ( pFtn = (SwTxtFtn*)pTxtNd->GetTxtAttr( + GetPoint()->nContent, RES_TXTATR_FTN ) )) + return GotoNextFtnAnchor(); + + FASTBOOL bRet = FALSE; + const SwFtnIdxs& rFtnArr = GetDoc()->GetFtnIdxs(); + USHORT nPos = rFtnArr.GetPos( pFtn ); + if( nPos < rFtnArr.Count() - 1 ) + { + pFtn = rFtnArr[ nPos + 1 ]; + pTxtNd = (SwTxtNode*)&pFtn->GetTxtNode(); + GetPoint()->nNode = *pTxtNd; + GetPoint()->nContent.Assign( pTxtNd, *pFtn->GetStart() ); + bRet = !IsSelOvr(); + } + return bRet; +} + +FASTBOOL SwCursor::GotoPrevFtnCntnt() +{ + SwCrsrSaveState aSaveState( *this ); + const SwNode* pSttNd = GetNode()->FindFootnoteStartNode(); + if( pSttNd ) + GotoFtnAnchor(); + + SwTxtFtn *pFtn; + SwTxtNode* pTxtNd = GetPoint()->nNode.GetNode().GetTxtNode(); + + if( !pTxtNd || 0 == ( pFtn = (SwTxtFtn*)pTxtNd->GetTxtAttr( + GetPoint()->nContent, RES_TXTATR_FTN ) )) + return GotoPrevFtnAnchor(); + + FASTBOOL bRet = FALSE; + const SwFtnIdxs& rFtnArr = GetDoc()->GetFtnIdxs(); + USHORT nPos = rFtnArr.GetPos( pFtn ); + if( nPos && USHRT_MAX != nPos ) + { + pFtn = rFtnArr[ nPos - 1 ]; + pTxtNd = (SwTxtNode*)&pFtn->GetTxtNode(); + GetPoint()->nNode = *pTxtNd; + GetPoint()->nContent.Assign( pTxtNd, *pFtn->GetStart() ); + bRet = !IsSelOvr(); + } + return bRet; +} + +FASTBOOL SwCrsrShell::GotoNextFtnAnchor() +{ + return CallCrsrFN( &SwCursor::GotoNextFtnAnchor ); +} + +FASTBOOL SwCrsrShell::GotoPrevFtnAnchor() +{ + return CallCrsrFN( &SwCursor::GotoPrevFtnAnchor ); +} + +FASTBOOL SwCrsrShell::GotoNextFtnCntnt() +{ + return CallCrsrFN( &SwCursor::GotoNextFtnCntnt ); +} + +FASTBOOL SwCrsrShell::GotoPrevFtnCntnt() +{ + return CallCrsrFN( &SwCursor::GotoPrevFtnCntnt ); +} + +/* */ + +// springe aus dem Content zum Rahmen + +FASTBOOL SwCrsrShell::GotoFlyTxt() +{ + SET_CURR_SHELL( this ); + + // alle DrawSeiten nach Objekten durchsuchen. + USHORT nMaxPages = GetDoc()->GetDrawModel() ? + GetDoc()->GetDrawModel()->GetPageCount() : 0; + if( !nMaxPages ) + return FALSE; + + const SwFrm* pFrm = GetCurrFrm(); + const SwLayoutFrm *pFndFly = 0; + + Point aPt( pFrm->Frm().Pos() ); + Point aNxtPt( LONG_MAX, LONG_MAX ); + + for( USHORT nPg = 0; nPg < nMaxPages; ++nPg ) + { + SdrPage* pActPage = GetDoc()->GetDrawModel()->GetPage( nPg ); + ASSERT( pActPage, "UUPs, keine Seite im Container" ); + + ULONG nObjs = pActPage->GetObjCount(); + ASSERT( nObjs, "UUPs, was fuer Object auf der Seite" ); + + for( ULONG nObj = 0; nObj < nObjs; ++nObj ) + { + SdrObject *pObj = pActPage->GetObj( nObj ); + ASSERT( pObj , + "UUPs, kein Object" ); + SwVirtFlyDrawObj *pVirt = pObj->IsWriterFlyFrame() ? + (SwVirtFlyDrawObj*)pObj : 0; + if( pVirt && pVirt->GetFlyFrm()->Lower() && + !pVirt->GetFlyFrm()->Lower()->IsNoTxtFrm() ) + { + + // Wie ist die Logik? Alle, die unterhalb des aktuellen Frames + // liegen (alle, die in den Frame hineinragen werden + // nicht beachtet !!) + Point aFlyPos( pVirt->GetFlyFrm()->Frm().Pos() ); + aFlyPos += pVirt->GetFlyFrm()->Prt().Pos(); + if( ( aFlyPos.Y() > aPt.Y() || // alle die unterhalb/daneben liegen, + ( aFlyPos.Y() == aPt.Y() && aFlyPos.X() > aPt.X())) && + ( aFlyPos.Y() < aNxtPt.Y() || // Position kleiner + ( aFlyPos.Y() == aNxtPt.Y() && aFlyPos.X() < aNxtPt.X() )) ) + { + aNxtPt = aFlyPos; + pFndFly = pVirt->GetFlyFrm(); + } + } + } + } + + FASTBOOL bRet = FALSE; + if( pFndFly ) + { + // Calc() ?? + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, + SwCrsrSaveState aSaveState( *pCurCrsr ); + + aPt = pFndFly->Frm().Pos() + pFndFly->Prt().Pos(); + pFndFly->GetCrsrOfst( pCurCrsr->GetPoint(), aPt ); + bRet = !pCurCrsr->IsInProtectTable( TRUE ) && !pCurCrsr->IsSelOvr(); + if( bRet ) + UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE | + SwCrsrShell::READONLY ); + } + return bRet; +} + +// springe aus dem Rahmen zum Anker + + +FASTBOOL SwCrsrShell::GotoFlyAnchor() +{ + SET_CURR_SHELL( this ); + const SwFrm* pFrm = GetCurrFrm(); + do { + pFrm = pFrm->GetUpper(); + } while( pFrm && !pFrm->IsFlyFrm() ); + + if( !pFrm ) // ist kein FlyFrame + return FALSE; + + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, + SwCrsrSaveState aSaveState( *pCurCrsr ); + + // springe in den BodyFrame, der am naechsten vom Fly liegt + SwRect aTmpRect( aCharRect ); + if( !pFrm->Frm().IsInside( aTmpRect )) + aTmpRect = pFrm->Frm(); + Point aPt( aTmpRect.Left(), aTmpRect.Top() + + ( aTmpRect.Bottom() - aTmpRect.Top() ) / 2 ); + aPt.X() = aPt.X() > (pFrm->Frm().Left() + (pFrm->Frm().SSize().Width() / 2 )) + ? pFrm->Frm().Right() + : pFrm->Frm().Left(); + + const SwPageFrm* pPageFrm = pFrm->FindPageFrm(); + const SwCntntFrm* pFndFrm = pPageFrm->GetCntntPos( aPt, FALSE, TRUE ); + pFndFrm->GetCrsrOfst( pCurCrsr->GetPoint(), aPt ); + + FASTBOOL bRet = !pCurCrsr->IsInProtectTable() && !pCurCrsr->IsSelOvr(); + if( bRet ) + UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE | + SwCrsrShell::READONLY ); + return bRet; +} + + + + diff --git a/sw/source/core/crsr/trvlreg.cxx b/sw/source/core/crsr/trvlreg.cxx new file mode 100644 index 000000000000..18d6618a9d63 --- /dev/null +++ b/sw/source/core/crsr/trvlreg.cxx @@ -0,0 +1,345 @@ +/************************************************************************* + * + * $RCSfile: trvlreg.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:17 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _CRSRSH_HXX +#include +#endif +#ifndef _DOC_HXX +#include +#endif +#ifndef _SWCRSR_HXX +#include +#endif +#ifndef _DOCARY_HXX +#include +#endif +#ifndef _FMTCNTNT_HXX //autogen +#include +#endif +#ifndef _VISCRS_HXX +#include +#endif +#ifndef _CALLNK_HXX +#include +#endif +#ifndef _PAMTYP_HXX +#include +#endif +#ifndef _SECTION_HXX +#include +#endif + + + +FASTBOOL GotoPrevRegion( SwPaM& rCurCrsr, SwPosRegion fnPosRegion, + FASTBOOL bInReadOnly ) +{ + SwNodeIndex aIdx( rCurCrsr.GetPoint()->nNode ); + SwSectionNode* pNd = aIdx.GetNode().FindSectionNode(); + if( pNd ) + aIdx.Assign( *pNd, - 1 ); + + do { + while( aIdx.GetIndex() && + 0 == ( pNd = aIdx.GetNode().FindStartNode()->GetSectionNode()) ) + aIdx--; + + if( pNd ) // gibt einen weiteren SectionNode ? + { + if( pNd->GetSection().IsHiddenFlag() || + ( !bInReadOnly && + pNd->GetSection().IsProtectFlag() )) + { + // geschuetzte/versteckte ueberspringen wir + aIdx.Assign( *pNd, - 1 ); + } + else if( fnPosRegion == fnMoveForward ) + { + aIdx = *pNd; + SwCntntNode* pCNd = pNd->GetNodes().GoNextSection( &aIdx, + TRUE, !bInReadOnly ); + if( !pCNd ) + { + aIdx--; + continue; + } + rCurCrsr.GetPoint()->nContent.Assign( pCNd, 0 ); + } + else + { + aIdx = *pNd->EndOfSectionNode(); + SwCntntNode* pCNd = pNd->GetNodes().GoPrevSection( &aIdx, + TRUE, !bInReadOnly ); + if( !pCNd ) + { + aIdx.Assign( *pNd, - 1 ); + continue; + } + rCurCrsr.GetPoint()->nContent.Assign( pCNd, pCNd->Len() ); + } + + rCurCrsr.GetPoint()->nNode = aIdx; + return TRUE; + } + } while( pNd ); + return FALSE; +} + + +FASTBOOL GotoNextRegion( SwPaM& rCurCrsr, SwPosRegion fnPosRegion, + FASTBOOL bInReadOnly ) +{ + SwNodeIndex aIdx( rCurCrsr.GetPoint()->nNode ); + SwSectionNode* pNd = aIdx.GetNode().FindSectionNode(); + if( pNd ) + aIdx.Assign( *pNd->EndOfSectionNode(), - 1 ); + + ULONG nEndCount = aIdx.GetNode().GetNodes().Count()-1; + do { + while( aIdx.GetIndex() < nEndCount && + 0 == ( pNd = aIdx.GetNode().GetSectionNode()) ) + aIdx++; + + if( pNd ) // gibt einen weiteren SectionNode ? + { + if( pNd->GetSection().IsHiddenFlag() || + ( !bInReadOnly && + pNd->GetSection().IsProtectFlag() )) + { + // geschuetzte/versteckte ueberspringen wir + aIdx.Assign( *pNd->EndOfSectionNode(), +1 ); + } + else if( fnPosRegion == fnMoveForward ) + { + aIdx = *pNd; + SwCntntNode* pCNd = pNd->GetNodes().GoNextSection( &aIdx, + TRUE, !bInReadOnly ); + if( !pCNd ) + { + aIdx.Assign( *pNd->EndOfSectionNode(), +1 ); + continue; + } + rCurCrsr.GetPoint()->nContent.Assign( pCNd, 0 ); + } + else + { + aIdx = *pNd->EndOfSectionNode(); + SwCntntNode* pCNd = pNd->GetNodes().GoPrevSection( &aIdx, + TRUE, !bInReadOnly ); + if( !pCNd ) + { + aIdx++; + continue; + } + rCurCrsr.GetPoint()->nContent.Assign( pCNd, pCNd->Len() ); + } + + rCurCrsr.GetPoint()->nNode = aIdx; + return TRUE; + } + } while( pNd ); + return FALSE; +} + + +FASTBOOL GotoCurrRegion( SwPaM& rCurCrsr, SwPosRegion fnPosRegion, + FASTBOOL bInReadOnly ) +{ + SwSectionNode* pNd = rCurCrsr.GetNode()->FindSectionNode(); + if( !pNd ) + return FALSE; + + SwPosition* pPos = rCurCrsr.GetPoint(); + FASTBOOL bMoveBackward = fnPosRegion == fnMoveBackward; + + SwCntntNode* pCNd; + if( bMoveBackward ) + { + SwNodeIndex aIdx( *pNd->EndOfSectionNode() ); + pCNd = pNd->GetNodes().GoPrevSection( &aIdx, TRUE, !bInReadOnly ); + } + else + { + SwNodeIndex aIdx( *pNd ); + pCNd = pNd->GetNodes().GoNextSection( &aIdx, TRUE, !bInReadOnly ); + } + + if( pCNd ) + { + pPos->nNode = *pCNd; + xub_StrLen nTmpPos = bMoveBackward ? pCNd->Len() : 0; + pPos->nContent.Assign( pCNd, nTmpPos ); + } + return 0 != pCNd; +} + + +FASTBOOL GotoCurrRegionAndSkip( SwPaM& rCurCrsr, SwPosRegion fnPosRegion, + FASTBOOL bInReadOnly ) +{ + SwNode* pCurrNd = rCurCrsr.GetNode(); + SwSectionNode* pNd = pCurrNd->FindSectionNode(); + if( !pNd ) + return FALSE; + + SwPosition* pPos = rCurCrsr.GetPoint(); + xub_StrLen nCurrCnt = pPos->nContent.GetIndex(); + FASTBOOL bMoveBackward = fnPosRegion == fnMoveBackward; + + do { + SwCntntNode* pCNd; + if( bMoveBackward ) // ans Ende vom Bereich + { + SwNodeIndex aIdx( *pNd->EndOfSectionNode() ); + pCNd = pNd->GetNodes().GoPrevSection( &aIdx, TRUE, !bInReadOnly ); + if( !pCNd ) + return FALSE; + pPos->nNode = aIdx; + } + else + { + SwNodeIndex aIdx( *pNd ); + pCNd = pNd->GetNodes().GoNextSection( &aIdx, TRUE, !bInReadOnly ); + if( !pCNd ) + return FALSE; + pPos->nNode = aIdx; + } + + xub_StrLen nTmpPos = bMoveBackward ? pCNd->Len() : 0; + pPos->nContent.Assign( pCNd, nTmpPos ); + + if( &pPos->nNode.GetNode() != pCurrNd || + pPos->nContent.GetIndex() != nCurrCnt ) + // es gab eine Veraenderung + return TRUE; + + // dann versuche mal den "Parent" dieser Section + SwSection* pParent = pNd->GetSection().GetParent(); + pNd = pParent ? pParent->GetFmt()->GetSectionNode() : 0; + } while( pNd ); + return FALSE; +} + + + +FASTBOOL SwCursor::MoveRegion( SwWhichRegion fnWhichRegion, SwPosRegion fnPosRegion ) +{ + SwCrsrSaveState aSaveState( *this ); + return !(SwTableCursor*)*this && + (*fnWhichRegion)( *this, fnPosRegion, IsReadOnlyAvailable() ) && + !IsSelOvr() && + ( GetPoint()->nNode.GetIndex() != pSavePos->nNode || + GetPoint()->nContent.GetIndex() != pSavePos->nCntnt ); +} + +FASTBOOL SwCrsrShell::MoveRegion( SwWhichRegion fnWhichRegion, SwPosRegion fnPosRegion ) +{ + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + FASTBOOL bRet = !pTblCrsr && pCurCrsr->MoveRegion( fnWhichRegion, fnPosRegion ); + if( bRet ) + UpdateCrsr(); + return bRet; +} + + +FASTBOOL SwCursor::GotoRegion( const String& rName ) +{ + FASTBOOL bRet = FALSE; + const SwSectionFmts& rFmts = GetDoc()->GetSections(); + for( USHORT n = rFmts.Count(); n; ) + { + const SwSectionFmt* pFmt = rFmts[ --n ]; + const SwNodeIndex* pIdx; + const SwSection* pSect; + if( 0 != ( pSect = pFmt->GetSection() ) && + pSect->GetName() == rName && + 0 != ( pIdx = pFmt->GetCntnt().GetCntntIdx() ) && + pIdx->GetNode().GetNodes().IsDocNodes() ) + { + // ein Bereich im normalen NodesArr + SwCrsrSaveState aSaveState( *this ); + + GetPoint()->nNode = *pIdx; + Move( fnMoveForward, fnGoCntnt ); + bRet = !IsSelOvr(); + } + } + return bRet; +} + +FASTBOOL SwCrsrShell::GotoRegion( const String& rName ) +{ + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, + FASTBOOL bRet = !pTblCrsr && pCurCrsr->GotoRegion( rName ); + if( bRet ) + UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE | + SwCrsrShell::READONLY ); // und den akt. Updaten + return bRet; +} + + + diff --git a/sw/source/core/crsr/trvltbl.cxx b/sw/source/core/crsr/trvltbl.cxx new file mode 100644 index 000000000000..213ad0c0c55e --- /dev/null +++ b/sw/source/core/crsr/trvltbl.cxx @@ -0,0 +1,770 @@ +/************************************************************************* + * + * $RCSfile: trvltbl.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:17 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _HINTIDS_HXX +#include +#endif + +#ifndef _APP_HXX //autogen +#include +#endif +#ifndef _SVX_PROTITEM_HXX //autogen +#include +#endif + +#ifndef _CRSRSH_HXX +#include +#endif +#ifndef _DOC_HXX +#include +#endif +#ifndef _CNTFRM_HXX +#include +#endif +#ifndef _EDITSH_HXX +#include //EndAllAction gibts nur an der EditShell +#endif +#ifndef _PAM_HXX +#include +#endif +#ifndef _SWTABLE_HXX +#include +#endif +#ifndef _DOCARY_HXX +#include +#endif +#ifndef _FRMATR_HXX +#include +#endif +#ifndef _NODE_HXX //autogen +#include +#endif +#ifndef _FRMFMT_HXX //autogen +#include +#endif +#ifndef _VISCRS_HXX +#include +#endif +#ifndef _CALLNK_HXX +#include +#endif +#ifndef _TABFRM_HXX +#include +#endif +#ifndef _NDTXT_HXX +#include +#endif +#ifndef _SHELLRES_HXX +#include +#endif +#ifndef _CELLATR_HXX +#include +#endif +#ifndef _CELLFRM_HXX //autogen +#include +#endif + +// setze Crsr in die naechsten/vorherigen Celle +FASTBOOL SwCrsrShell::GoNextCell( BOOL bAppendLine ) +{ + FASTBOOL bRet = FALSE; + const SwTableNode* pTblNd; + if( IsTableMode() || 0 != ( pTblNd = IsCrsrInTbl() )) + { + SwCursor* pCrsr = pTblCrsr ? pTblCrsr : pCurCrsr; + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, + bRet = TRUE; + + // folgt nach dem EndNode der Cell ein weiterer StartNode, dann + // gibt es auch eine naechste Celle + SwNodeIndex aCellStt( *pCrsr->GetNode()->FindTableBoxStartNode()-> + EndOfSectionNode(), 1 ); + if( !aCellStt.GetNode().IsStartNode() ) + { + if( pCrsr->HasMark() || + (!bAppendLine /*&& IsCrsrReadonly()*/ )) + bRet = FALSE; + else + { + // auf besonderen Wunsch: keine Line mehr vorhanden, dann + // mache doch eine neue: + const SwTableBox* pBox = pTblNd->GetTable().GetTblBox( + pCrsr->GetPoint()->nNode.GetNode(). + StartOfSectionIndex() ); + ASSERT( pBox, "Box steht nicht in dieser Tabelle" ); + SwSelBoxes aBoxes; + + //Das Dokument veraendert sich evtl. ohne Action wuerden die Sichten + //nichts mitbekommen. + ((SwEditShell*)this)->StartAllAction(); + bRet = pDoc->InsertRow( pTblNd->GetTable(). + SelLineFromBox( pBox, aBoxes, FALSE )); + ((SwEditShell*)this)->EndAllAction(); + } + } + if( bRet && 0 != ( bRet = pCrsr->GoNextCell() )) + UpdateCrsr(); // und den akt. Updaten + } + return bRet; +} + + +FASTBOOL SwCrsrShell::GoPrevCell() +{ + FASTBOOL bRet = FALSE; + const SwTableNode* pTblNd; + if( IsTableMode() || 0 != ( pTblNd = IsCrsrInTbl() )) + { + SwCursor* pCrsr = pTblCrsr ? pTblCrsr : pCurCrsr; + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, + bRet = pCrsr->GoPrevCell(); + if( bRet ) + UpdateCrsr(); // und den akt. Updaten + } + return bRet; +} + + +FASTBOOL SwCrsrShell::GotoTblBox( const String& rName ) +{ + SwShellCrsr* pCrsr = pTblCrsr ? pTblCrsr : pCurCrsr; + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, + + FASTBOOL bRet = pCrsr->GotoTblBox( rName ); + if( bRet ) + { + //JP 28.10.97: Bug 45028 - die "oberste" Position setzen fuer + // wiederholte Kopfzeilen + pCrsr->GetPtPos() = Point(); + UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE | + SwCrsrShell::READONLY ); // und den akt. Updaten + } + return bRet; +} + + +FASTBOOL SwCrsrShell::SelTblRow() +{ + // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen + SwFrm *pFrm = GetCurrFrm(); + if( !pFrm->IsInTab() ) + return FALSE; + + const SwTabFrm *pTblFrm = pFrm->ImplFindTabFrm(); + + SET_CURR_SHELL( this ); + + // lasse ueber das Layout die Boxen suchen + Point aPt( pTblFrm->Frm().Left(), pTblFrm->Frm().Right() ); + SwSelBoxes aBoxes; + + SwTblSearchType eType = TBLSEARCH_ROW; + if( !IsReadOnlyAvailable() ) + eType = (SwTblSearchType)(eType | TBLSEARCH_PROTECT); + GetTblSel( *this, aBoxes, eType ); + + if( !aBoxes.Count() ) + return FALSE; + + // noch kein Tabellen-Cursor vorhanden, dann erzeuge einen + if( !pTblCrsr ) + { + pTblCrsr = new SwShellTableCrsr( *this, *pCurCrsr->GetPoint() ); + pCurCrsr->DeleteMark(); + pCurCrsr->SwSelPaintRects::Hide(); + } + +// SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, + pTblCrsr->DeleteMark(); + // dann setze mal Anfang und Ende der Spalte + pTblCrsr->GetPoint()->nNode = *aBoxes[0]->GetSttNd(); + pTblCrsr->Move( fnMoveForward, fnGoCntnt ); + pTblCrsr->SetMark(); + pTblCrsr->GetPoint()->nNode = *aBoxes[aBoxes.Count()-1]->GetSttNd(); + pTblCrsr->Move( fnMoveForward, fnGoCntnt ); + UpdateCrsr(); // und den akt. Updaten + return TRUE; +} + + +FASTBOOL SwCrsrShell::SelTblCol() +{ + SwFrm *pFrm = GetCurrFrm(); + if( !pFrm->IsInTab() ) + return FALSE; + + const SwTabFrm *pTblFrm = pFrm->ImplFindTabFrm(); + + SET_CURR_SHELL( this ); + + // lasse ueber das Layout die Boxen suchen + Point aPt( pTblFrm->Frm().Top(), pTblFrm->Frm().Bottom() ); + SwSelBoxes aBoxes; + SwTblSearchType eType = TBLSEARCH_COL; + if( !IsReadOnlyAvailable() ) + eType = (SwTblSearchType)(eType | TBLSEARCH_PROTECT); + GetTblSel( *this, aBoxes, eType ); + + if( !aBoxes.Count() ) + return FALSE; + + // noch kein Tabellen-Cursor vorhanden, dann erzeuge einen + if( !pTblCrsr ) + { + pTblCrsr = new SwShellTableCrsr( *this, *pCurCrsr->GetPoint() ); + pCurCrsr->DeleteMark(); + pCurCrsr->SwSelPaintRects::Hide(); + } + +// SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, + pTblCrsr->DeleteMark(); + // dann setze mal Anfang und Ende der Spalte + pTblCrsr->GetPoint()->nNode = *aBoxes[0]->GetSttNd(); + pTblCrsr->Move( fnMoveForward, fnGoCntnt ); + pTblCrsr->SetMark(); + pTblCrsr->GetPoint()->nNode = *aBoxes[aBoxes.Count()-1]->GetSttNd(); + pTblCrsr->Move( fnMoveForward, fnGoCntnt ); + UpdateCrsr(); // und den akt. Updaten + return TRUE; +} + + +// suche die naechste nicht geschuetzte Zelle innerhalb der Tabelle +// Parameter: +// rIdx - steht auf dem TabellenNode +// SwDoc - +// return: +// 0 - Idx steht auf/in einer nicht geschuetzten Zelle +// !0 - Node hinter der Tabelle + + +SwNode* lcl_FindNextCell( SwNodeIndex& rIdx, FASTBOOL bInReadOnly ) +{ + // ueberpruefe geschuetzte Zellen + SwCntntFrm* pFrm; + SwNodeIndex aTmp( rIdx, 2 ); // TableNode + StartNode + SwNodes& rNds = aTmp.GetNode().GetNodes(); + SwCntntNode* pCNd = aTmp.GetNode().GetCntntNode(); + if( !pCNd ) + pCNd = rNds.GoNext( &aTmp ); + + if( 0 == ( pFrm = pCNd->GetFrm()) || + (!bInReadOnly && pFrm->IsProtected() )) + { + aTmp.Assign( *pCNd->EndOfSectionNode(), 1 ); + SwNode* pNd; + for( ;; ) + { + if( !( pNd = &aTmp.GetNode())->IsStartNode() ) + return pNd; + aTmp++; + if( 0 == (pCNd = aTmp.GetNode().GetCntntNode()) ) + pCNd = rNds.GoNext( &aTmp ); + + if( 0 != ( pFrm = pCNd->GetFrm()) && + (bInReadOnly || !pFrm->IsProtected() )) + { + rIdx = *pNd; + return 0; // Ok, nicht geschuetzt + } + aTmp.Assign( *pCNd->EndOfSectionNode(), +1 ); + } + } + return 0; +} + +// suche die vorherige nicht geschuetzte Zelle innerhalb der Tabelle +// Parameter: +// rIdx - steht auf dem EndNode der Tabelle +// SwDoc - +// return: +// 0 - Idx steht auf/in einer nicht geschuetzten Zelle +// !0 - Node hinter der Tabelle + + +SwNode* lcl_FindPrevCell( SwNodeIndex& rIdx, FASTBOOL bInReadOnly ) +{ + // ueberpruefe geschuetzte Zellen + SwCntntFrm* pFrm; + SwNodeIndex aTmp( rIdx, -2 ); // TableNode + EndNode + SwNodes& rNds = aTmp.GetNode().GetNodes(); + SwCntntNode* pCNd = aTmp.GetNode().GetCntntNode(); + if( !pCNd ) + pCNd = rNds.GoNext( &aTmp ); + + if( 0 == ( pFrm = pCNd->GetFrm()) || + (!bInReadOnly && pFrm->IsProtected() )) + { + aTmp.Assign( *pCNd->StartOfSectionNode(), -1 ); + SwNode* pNd; + for( ;; ) + { + if( !( pNd = &aTmp.GetNode())->IsEndNode() ) + return pNd; + aTmp--; + if( 0 == (pCNd = aTmp.GetNode().GetCntntNode()) ) + pCNd = rNds.GoPrevious( &aTmp ); + + if( 0 != ( pFrm = pCNd->GetFrm()) && + (bInReadOnly || !pFrm->IsProtected() )) + { + rIdx = *pNd; + return 0; // Ok, nicht geschuetzt + } + aTmp.Assign( *pCNd->StartOfSectionNode(), - 1 ); + } + } + return 0; +} + + + +FASTBOOL GotoPrevTable( SwPaM& rCurCrsr, SwPosTable fnPosTbl, + FASTBOOL bInReadOnly ) +{ + SwNodeIndex aIdx( rCurCrsr.GetPoint()->nNode ); + SwTableNode* pTblNd = aIdx.GetNode().FindTableNode(); + if( pTblNd ) + aIdx.Assign( *pTblNd, - 1 ); + + do { + while( aIdx.GetIndex() && + 0 == ( pTblNd = aIdx.GetNode().FindStartNode()->GetTableNode()) ) + aIdx--; + + if( pTblNd ) // gibt einen weiteren TableNode ? + { + if( fnPosTbl == fnMoveForward ) // an Anfang ? + { + aIdx = *aIdx.GetNode().StartOfSectionNode(); + if( lcl_FindNextCell( aIdx, bInReadOnly )) + { + // Tabelle ueberspringen + aIdx.Assign( *pTblNd, -1 ); + continue; + } + } + else + { + // ueberpruefe geschuetzte Zellen + if( lcl_FindNextCell( aIdx, bInReadOnly )) + { + // Tabelle ueberspringen + aIdx.Assign( *pTblNd, -1 ); + continue; + } + } + rCurCrsr.GetPoint()->nNode = aIdx; + rCurCrsr.Move( fnPosTbl, fnGoCntnt ); + return TRUE; + } + } while( pTblNd ); + + return FALSE; +} + + +FASTBOOL GotoNextTable( SwPaM& rCurCrsr, SwPosTable fnPosTbl, + FASTBOOL bInReadOnly ) +{ + SwNodeIndex aIdx( rCurCrsr.GetPoint()->nNode ); + SwTableNode* pTblNd = aIdx.GetNode().FindTableNode(); + if( pTblNd ) + aIdx.Assign( *pTblNd->EndOfSectionNode(), 1 ); + + ULONG nLastNd = rCurCrsr.GetDoc()->GetNodes().Count() - 1; + do { + while( aIdx.GetIndex() < nLastNd && + 0 == ( pTblNd = aIdx.GetNode().GetTableNode()) ) + aIdx++; + if( pTblNd ) // gibt einen weiteren TableNode ? + { + if( fnPosTbl == fnMoveForward ) // an Anfang ? + { + if( lcl_FindNextCell( aIdx, bInReadOnly )) + { + // Tabelle ueberspringen + aIdx.Assign( *pTblNd->EndOfSectionNode(), + 1 ); + continue; + } + } + else + { + aIdx = *aIdx.GetNode().EndOfSectionNode(); + // ueberpruefe geschuetzte Zellen + if( lcl_FindNextCell( aIdx, bInReadOnly )) + { + // Tabelle ueberspringen + aIdx.Assign( *pTblNd->EndOfSectionNode(), + 1 ); + continue; + } + } + rCurCrsr.GetPoint()->nNode = aIdx; + rCurCrsr.Move( fnPosTbl, fnGoCntnt ); + return TRUE; + } + } while( pTblNd ); + + return FALSE; +} + + +FASTBOOL GotoCurrTable( SwPaM& rCurCrsr, SwPosTable fnPosTbl, + FASTBOOL bInReadOnly ) +{ + SwTableNode* pTblNd = rCurCrsr.GetPoint()->nNode.GetNode().FindTableNode(); + if( !pTblNd ) + return FALSE; + + if( fnPosTbl == fnMoveBackward ) // ans Ende der Tabelle + { + SwNodeIndex aIdx( *pTblNd->EndOfSectionNode() ); + if( lcl_FindPrevCell( aIdx, bInReadOnly )) + return FALSE; + rCurCrsr.GetPoint()->nNode = aIdx; + } + else + { + SwNodeIndex aIdx( *pTblNd ); + if( lcl_FindNextCell( aIdx, bInReadOnly )) + return FALSE; + rCurCrsr.GetPoint()->nNode = aIdx; + } + rCurCrsr.Move( fnPosTbl, fnGoCntnt ); + return TRUE; +} + + +FASTBOOL SwCursor::MoveTable( SwWhichTable fnWhichTbl, SwPosTable fnPosTbl ) +{ + FASTBOOL bRet = FALSE; + SwTableCursor* pTblCrsr = (SwTableCursor*)*this; + + if( pTblCrsr || !HasMark() ) // nur wenn kein Mark oder ein TblCrsr + { + SwCrsrSaveState aSaveState( *this ); + bRet = (*fnWhichTbl)( *this, fnPosTbl, IsReadOnlyAvailable() ) && + !IsSelOvr(); + } + return bRet; +} + +FASTBOOL SwCrsrShell::MoveTable( SwWhichTable fnWhichTbl, SwPosTable fnPosTbl ) +{ + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen + + SwShellCrsr* pCrsr = pTblCrsr ? pTblCrsr : pCurCrsr; + FASTBOOL bCheckPos, bRet; + ULONG nPtNd; + xub_StrLen nPtCnt; + + if( !pTblCrsr && pCurCrsr->HasMark() ) // wenn Mark und kein TblCrsr, + { + // dann auf jedenfall in den Tabellen-Modus schalten + pTblCrsr = new SwShellTableCrsr( *this, *pCurCrsr->GetPoint() ); + pCurCrsr->DeleteMark(); + pCurCrsr->SwSelPaintRects::Hide(); + pTblCrsr->SetMark(); + pCrsr = pTblCrsr; + bCheckPos = FALSE; + } + else + { + bCheckPos = TRUE; + nPtNd = pCrsr->GetPoint()->nNode.GetIndex(); + nPtCnt = pCrsr->GetPoint()->nContent.GetIndex(); + } + + bRet = pCrsr->MoveTable( fnWhichTbl, fnPosTbl ); + + if( bRet ) + { + //JP 28.10.97: Bug 45028 - die "oberste" Position setzen fuer + // wiederholte Kopfzeilen + pCrsr->GetPtPos() = Point(); + + UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); + + if( bCheckPos && + pCrsr->GetPoint()->nNode.GetIndex() == nPtNd && + pCrsr->GetPoint()->nContent.GetIndex() == nPtCnt ) + bRet = FALSE; + } + return bRet; +} + + +FASTBOOL SwCrsrShell::IsTblComplex() const +{ + SwFrm *pFrm = GetCurrFrm( FALSE ); + if ( pFrm && pFrm->IsInTab() ) + return pFrm->FindTabFrm()->GetTable()->IsTblComplex(); + return FALSE; +} + + +FASTBOOL SwCrsrShell::IsTblComplexForChart() const +{ + FASTBOOL bRet = FALSE; + const SwTableNode* pTNd = pCurCrsr->GetPoint()->nNode.GetNode().FindTableNode(); + if( pTNd ) + { + // wir stehen in der Tabelle, dann teste mal, ob die Tabelle oder die + // Selektion ausgeglichen ist. + String sSel; + if( pTblCrsr ) + sSel = GetBoxNms(); + bRet = pTNd->GetTable().IsTblComplexForChart( sSel ); + } + return bRet; +} + +String SwCrsrShell::GetBoxNms() const +{ + String sNm; + const SwPosition* pPos; + SwFrm* pFrm; + + if( IsTableMode() ) + { + pFrm = pTblCrsr->Start()->nNode.GetNode().GetCntntNode()->GetFrm(); + + do { + pFrm = pFrm->GetUpper(); + } while ( pFrm && !pFrm->IsCellFrm() ); + + ASSERT( pFrm, "kein Frame zur Box" ); + sNm = ((SwCellFrm*)pFrm)->GetTabBox()->GetName(); + sNm += ':'; + pPos = pTblCrsr->End(); + } + else + { + const SwTableNode* pTblNd = IsCrsrInTbl(); + if( !pTblNd ) + return sNm; + pPos = GetCrsr()->GetPoint(); + } + + pFrm = pPos->nNode.GetNode().GetCntntNode()->GetFrm(); + + do { + pFrm = pFrm->GetUpper(); + } while ( pFrm && !pFrm->IsCellFrm() ); + + if( pFrm ) + sNm += ((SwCellFrm*)pFrm)->GetTabBox()->GetName(); + + return sNm; +} + + +FASTBOOL SwCrsrShell::GotoTable( const String& rName ) +{ + SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, + FASTBOOL bRet = !pTblCrsr && pCurCrsr->GotoTable( rName ); + if( bRet ) + { + pCurCrsr->GetPtPos() = Point(); + UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE | + SwCrsrShell::READONLY ); // und den akt. Updaten + } + return bRet; +} + + +FASTBOOL SwCrsrShell::CheckTblBoxCntnt( const SwPosition* pPos ) +{ + if( !pBoxIdx || !pBoxPtr || IsSelTblCells() || !IsAutoUpdateCells() ) + return FALSE; + + // ueberpruefe, ob der Box Inhalt mit dem angegebenen Format der Box + // ueber einstimmt. Wenn nicht, setze neu + SwTableBox* pChkBox = 0; + SwStartNode* pSttNd; + if( !pPos ) + { + // gesicherte Position heraus holen. + if( pBoxIdx && pBoxPtr && + 0 != ( pSttNd = pBoxIdx->GetNode().GetStartNode() ) && + SwTableBoxStartNode == pSttNd->GetStartNodeType() && + pBoxPtr == pSttNd->FindTableNode()->GetTable(). + GetTblBox( pBoxIdx->GetIndex() ) ) + pChkBox = pBoxPtr; + } + else if( 0 != ( pSttNd = pPos->nNode.GetNode(). + FindSttNodeByType( SwTableBoxStartNode )) ) + { + pChkBox = pSttNd->FindTableNode()->GetTable().GetTblBox( pSttNd->GetIndex() ); + } + + + // Box mehr als 1 Absatz? + if( pChkBox && pSttNd->GetIndex() + 2 != pSttNd->EndOfSectionIndex() ) + pChkBox = 0; + + // jetzt sollten wir mal die Pointer zerstoeren, bevor eine erneute + // Actionklammerung kommt. + if( !pPos && !pChkBox ) + ClearTblBoxCntnt(); + + // liegt der Cursor nicht mehr in dem Bereich ? + if( pChkBox && !pPos && + ( pCurCrsr->HasMark() || pCurCrsr->GetNext() != pCurCrsr || + pSttNd->GetIndex() + 1 == pCurCrsr->GetPoint()->nNode.GetIndex() )) + pChkBox = 0; + + //JP 12.01.99: hat sich der Inhalt der Box ueberhaupt veraendert? + // Ist wichtig, wenn z.B. Undo nicht den richtigen Inhalt wieder + // herstellen konnte. + if( pChkBox ) + { + const SwTxtNode* pNd = GetDoc()->GetNodes()[ + pSttNd->GetIndex() + 1 ]->GetTxtNode(); + if( !pNd || + ( pNd->GetTxt() == ViewShell::GetShellRes()->aCalc_Error && + SFX_ITEM_SET == pChkBox->GetFrmFmt()-> + GetItemState( RES_BOXATR_FORMULA )) ) + pChkBox = 0; + } + + if( pChkBox ) + { + // jetzt sollten wir mal die Pointer zerstoeren, bevor ein weiterer + // aufruf kommt. + ClearTblBoxCntnt(); + StartAction(); + GetDoc()->ChkBoxNumFmt( *pChkBox, TRUE ); + EndAction(); + } + + return 0 != pChkBox; +} + + +void SwCrsrShell::SaveTblBoxCntnt( const SwPosition* pPos ) +{ + if( IsSelTblCells() || !IsAutoUpdateCells() ) + return ; + + if( !pPos ) + pPos = pCurCrsr->GetPoint(); + + SwStartNode* pSttNd = pPos->nNode.GetNode().FindSttNodeByType( SwTableBoxStartNode ); + + BOOL bCheckBox = FALSE; + if( pSttNd && pBoxIdx ) + { + if( pSttNd == &pBoxIdx->GetNode() ) + pSttNd = 0; // die haben wir schon + else + bCheckBox = TRUE; + } + else + bCheckBox = 0 != pBoxIdx; + + if( bCheckBox ) + { + // pBoxIdx Checken + SwPosition aPos( *pBoxIdx ); + CheckTblBoxCntnt( &aPos ); + } + + if( pSttNd ) + { + pBoxPtr = pSttNd->FindTableNode()->GetTable().GetTblBox( pSttNd->GetIndex() ); + + if( pBoxIdx ) + *pBoxIdx = *pSttNd; + else + pBoxIdx = new SwNodeIndex( *pSttNd ); + } +} + + +void SwCrsrShell::ClearTblBoxCntnt() +{ + delete pBoxIdx, pBoxIdx = 0; + pBoxPtr = 0; +} + +FASTBOOL SwCrsrShell::EndAllTblBoxEdit() +{ + FASTBOOL bRet = FALSE; + ViewShell *pSh = this; + do { + if( pSh->IsA( TYPE( SwCrsrShell ) ) ) + bRet |= ((SwCrsrShell*)pSh)->CheckTblBoxCntnt( + ((SwCrsrShell*)pSh)->pCurCrsr->GetPoint() ); + + } while( this != (pSh = (ViewShell *)pSh->GetNext()) ); + return bRet; +} + + + + diff --git a/sw/source/core/crsr/unocrsr.cxx b/sw/source/core/crsr/unocrsr.cxx new file mode 100644 index 000000000000..bef5a94e0b06 --- /dev/null +++ b/sw/source/core/crsr/unocrsr.cxx @@ -0,0 +1,290 @@ +/************************************************************************* + * + * $RCSfile: unocrsr.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:17 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _UNOCRSR_HXX +#include +#endif +#ifndef _DOC_HXX +#include +#endif +#ifndef _NODE_HXX +#include +#endif +#ifndef _SWTABLE_HXX +#include +#endif +#ifndef _DOCARY_HXX +#include +#endif +#ifndef _ROOTFRM_HXX +#include +#endif + +SV_IMPL_PTRARR( SwUnoCrsrTbl, SwUnoCrsrPtr ) + +IMPL_FIXEDMEMPOOL_NEWDEL( SwUnoCrsr, 10, 10 ) + +SwUnoCrsr::SwUnoCrsr( const SwPosition &rPos, SwPaM* pRing ) + : SwCursor( rPos, pRing ), SwModify( 0 ), + bRemainInSection( TRUE ) +{} + +SwUnoCrsr::SwUnoCrsr( SwUnoCrsr& rICrsr ) + : SwCursor( rICrsr ), SwModify( 0 ), + bRemainInSection( rICrsr.bRemainInSection ) +{} + +SwUnoCrsr::~SwUnoCrsr() +{ + SwDoc* pDoc = GetDoc(); + if( !pDoc->IsInDtor() ) + { + // dann muss der Cursor aus dem Array ausgetragen werden + SwUnoCrsrTbl& rTbl = (SwUnoCrsrTbl&)pDoc->GetUnoCrsrTbl(); + USHORT nDelPos = rTbl.GetPos( this ); + + if( USHRT_MAX != nDelPos ) + rTbl.Remove( nDelPos ); + else + ASSERT( !this, "UNO Cursor nicht mehr im Array" ); + } + + // den gesamten Ring loeschen! + while( GetNext() != this ) + { + Ring* pNxt = GetNext(); + pNxt->MoveTo( 0 ); // ausketten + delete pNxt; // und loeschen + } +} + +SwUnoCrsr::operator SwUnoCrsr* () { return this; } + +/* + +SwCursor* SwUnoCrsr::Create( SwPaM* pRing ) const +{ + return new SwUnoCrsr( *GetPoint(), pRing ); +} + +*/ + +FASTBOOL SwUnoCrsr::IsSelOvr( int eFlags ) +{ + if( bRemainInSection ) + { + SwDoc* pDoc = GetDoc(); + SwNodeIndex aOldIdx( *pDoc->GetNodes()[ GetSavePos()->nNode ] ); + SwNodeIndex& rPtIdx = GetPoint()->nNode; + SwStartNode *pOldSttNd = aOldIdx.GetNode().FindStartNode(), + *pNewSttNd = rPtIdx.GetNode().FindStartNode(); + if( pOldSttNd != pNewSttNd ) + { + BOOL bMoveDown = GetSavePos()->nNode < rPtIdx.GetIndex(); + BOOL bValidPos = FALSE; + if( bMoveDown ) + { + // ist das Ende noch nicht erreicht worden? + while( pOldSttNd->EndOfSectionIndex() > rPtIdx.GetIndex() ) + { + // dann versuche auf die "Ebene" zurueck zukommen + rPtIdx.Assign( *pNewSttNd->EndOfSectionNode(), 1 ); + while( pOldSttNd != rPtIdx.GetNode().FindStartNode() ) + rPtIdx.Assign( *rPtIdx.GetNode().EndOfSectionNode(), 1 ); + + if( !rPtIdx.GetNode().IsCntntNode() && + !pDoc->GetNodes().GoNextSection( &rPtIdx )) + break; + + if( pOldSttNd == + ( pNewSttNd = rPtIdx.GetNode().FindStartNode() )) + { + // das ist die gesuchte Position + bValidPos = TRUE; + break; + } + } + } + else + { + // ist der Start noch nicht erreicht worden? + while( pOldSttNd->GetIndex() < rPtIdx.GetIndex() ) + { + // dann versuche auf die "Ebene" zurueck zukommen + rPtIdx.Assign( *pNewSttNd, -1 ); + while( pOldSttNd != rPtIdx.GetNode().FindStartNode() ) + rPtIdx.Assign( *rPtIdx.GetNode().FindStartNode(), -1 ); + + if( !rPtIdx.GetNode().IsCntntNode() && + !pDoc->GetNodes().GoPrevSection( &rPtIdx )) + break; + + if( pOldSttNd == + ( pNewSttNd = rPtIdx.GetNode().FindStartNode() )) + { + // das ist die gesuchte Position + bValidPos = TRUE; + break; + } + } + } + + if( bValidPos ) + { + SwCntntNode* pCNd = GetCntntNode(); + USHORT nCnt = 0; + if( pCNd && !bMoveDown ) + nCnt = pCNd->Len(); + GetPoint()->nContent.Assign( pCNd, nCnt ); + } + else + { + rPtIdx = GetSavePos()->nNode; + GetPoint()->nContent.Assign( GetCntntNode(), GetSavePos()->nCntnt ); + return TRUE; + } + } + } + return SwCursor::IsSelOvr( eFlags ); +} + + +/* */ + +SwUnoTableCrsr::SwUnoTableCrsr( const SwPosition& rPos ) + : SwTableCursor( rPos ), SwUnoCrsr( rPos ), SwCursor( rPos ), + aTblSel( rPos ) +{ + SetRemainInSection( FALSE ); +} + +SwUnoTableCrsr::~SwUnoTableCrsr() +{ + while( aTblSel.GetNext() != &aTblSel ) + delete aTblSel.GetNext(); // und loeschen +} + +SwUnoTableCrsr::operator SwUnoCrsr* () { return this; } +SwUnoTableCrsr::operator SwTableCursor* () { return this; } +SwUnoTableCrsr::operator SwUnoTableCrsr* () { return this; } + +/* +SwCursor* SwUnoTableCrsr::Create( SwPaM* pRing ) const +{ + return SwUnoCrsr::Create( pRing ); +} +*/ + +FASTBOOL SwUnoTableCrsr::IsSelOvr( int eFlags ) +{ + FASTBOOL bRet = SwUnoCrsr::IsSelOvr( eFlags ); + if( !bRet ) + { + const SwTableNode* pTNd = GetPoint()->nNode.GetNode().FindTableNode(); + bRet = !(pTNd == GetDoc()->GetNodes()[ GetSavePos()->nNode ]-> + FindTableNode() && (!HasMark() || + pTNd == GetMark()->nNode.GetNode().FindTableNode() )); + } + return bRet; +} + +void SwUnoTableCrsr::MakeBoxSels() +{ + const SwCntntNode* pCNd; + if( GetPoint()->nNode.GetIndex() && GetMark()->nNode.GetIndex() && + 0 != ( pCNd = GetCntntNode() ) && pCNd->GetFrm() && + 0 != ( pCNd = GetCntntNode(FALSE) ) && pCNd->GetFrm() ) + GetDoc()->GetRootFrm()->MakeTblCrsrs( *this ); + + if( IsChgd() ) + { + SwTableCursor::MakeBoxSels( &aTblSel ); + if( !GetBoxesCount() ) + { + const SwTableBox* pBox; + const SwNode* pBoxNd = GetPoint()->nNode.GetNode().FindTableBoxStartNode(); + const SwTableNode* pTblNd = pBoxNd ? pBoxNd->FindTableNode() : 0; + if( pTblNd && 0 != ( pBox = pTblNd->GetTable().GetTblBox( pBoxNd->GetIndex() )) ) + InsertBox( *pBox ); + } + } +} + +/* */ + +SwUnoCrsr* SwDoc::CreateUnoCrsr( const SwPosition& rPos, BOOL bTblCrsr ) +{ + SwUnoCrsr* pNew; + if( bTblCrsr ) + pNew = new SwUnoTableCrsr( rPos ); + else + pNew = new SwUnoCrsr( rPos ); + + pUnoCrsrTbl->Insert( pNew, pUnoCrsrTbl->Count() ); + return pNew; +} + diff --git a/sw/source/core/crsr/viscrs.cxx b/sw/source/core/crsr/viscrs.cxx new file mode 100644 index 000000000000..64ad9d5195b9 --- /dev/null +++ b/sw/source/core/crsr/viscrs.cxx @@ -0,0 +1,1078 @@ +/************************************************************************* + * + * $RCSfile: viscrs.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:17 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _SVSTDARR_HXX +#define _SVSTDARR_USHORTS +#include +#endif + +#ifndef _DIALOG_HXX //autogen +#include +#endif +#ifndef _MSGBOX_HXX //autogen +#include +#endif +#ifndef _WRKWIN_HXX //autogen +#include +#endif + +#ifndef _VIEWOPT_HXX //autogen +#include +#endif +#ifndef _FRMTOOL_HXX +#include +#endif +#ifndef _VISCRS_HXX +#include +#endif +#ifndef _CRSRSH_HXX +#include +#endif +#ifndef _DOC_HXX +#include +#endif +#ifndef _PAM_HXX +#include +#endif +#ifndef _NODE_HXX +#include +#endif +#ifndef _SWTABLE_HXX +#include +#endif +#ifndef _VIEWIMP_HXX +#include +#endif +#ifndef _DVIEW_HXX +#include +#endif +#ifndef _ROOTFRM_HXX +#include +#endif +#ifndef _CNTFRM_HXX +#include +#endif +#ifndef _DOCARY_HXX +#include +#endif + +#ifndef _MDIEXP_HXX +#include // GetSearchDialog +#endif +#ifndef _COMCORE_HRC +#include // ResId fuer Abfrage wenn zu Search & Replaces +#endif + + +extern void MA_FASTCALL SwAlignRect( SwRect &rRect, ViewShell *pSh ); +extern void SwCalcPixStatics( OutputDevice *pOut ); + + +//Damit beim ShowCrsr nicht immer wieder die gleiche Size teuer ermittelt +//werden muss, hier statische Member, die beim Wechsel des MapModes +// angepasst werden + +long SwSelPaintRects::nPixPtX = 0; +long SwSelPaintRects::nPixPtY = 0; +MapMode* SwSelPaintRects::pMapMode = 0; + + + +//#define SHOW_BOOKMARKS +//#define SHOW_REDLINES + +#ifdef SHOW_BOOKMARKS + +#ifndef _BOOKMRK_HXX +#include +#endif + +class SwBookmarkRects : public SwSelPaintRects +{ + virtual void Paint( const Rectangle& rRect ); + virtual void FillRects(); + +public: + SwBookmarkRects( const SwCrsrShell& rSh ) : SwSelPaintRects( rSh ) {} +}; + +void SwBookmarkRects::Paint( const Rectangle& rRect ) +{ + Window* pWin = GetShell()->GetWin(); + + RasterOp eOld( pWin->GetRasterOp() ); + BOOL bLCol = pWin->IsLineColor(); + Color aLCol( pWin->GetLineColor() ); + BOOL bFCol = pWin->IsFillColor(); + Color aFCol( pWin->GetFillColor() ); + + pWin->SetRasterOp( ROP_XOR ); + Color aCol( RGB_COLORDATA( 0xF0, 0xC8, 0xF0 ) ^ COL_WHITE ); + pWin->SetFillColor( aCol ); + pWin->SetLineColor( aCol ); + + pWin->DrawRect( rRect ); + + if( bLCol ) pWin->SetLineColor( aLCol ); else pWin->SetLineColor(); + if( bFCol ) pWin->SetFillColor( aFCol ); else pWin->SetFillColor(); + pWin->SetRasterOp( eOld ); +} + +void SwBookmarkRects::FillRects() +{ + SwRegionRects aReg( GetShell()->VisArea() ); + + const SwBookmarks& rBkmkTbl = GetShell()->GetDoc()->GetBookmarks(); + SwShellCrsr* pCrsr = 0; + for( USHORT n = 0; n < rBkmkTbl.Count(); ++n ) + { + const SwBookmark& rBkmk = *rBkmkTbl[ n ]; + if( rBkmk.IsBookMark() && rBkmk.GetOtherPos() ) + { + if( !pCrsr ) + { + pCrsr = new SwShellCrsr( *GetShell(), rBkmk.GetPos() ); + pCrsr->SetMark(); + } + else + *pCrsr->GetPoint() = rBkmk.GetPos(); + *pCrsr->GetMark() = *rBkmk.GetOtherPos(); + pCrsr->FillRects(); + for( USHORT i = 0; i < pCrsr->Count(); ++i ) + aReg -= (*pCrsr)[ i ]; + + pCrsr->Remove( 0, i ); + } + } + if( pCrsr ) delete pCrsr; + + aReg.Invert(); + SwRects::Insert( &aReg, 0 ); +} + +SwBookmarkRects* pBookMarkRects = 0; + +void ShowBookmarks( const SwCrsrShell* pSh, int nAction, const SwRect* pRect = 0 ) +{ + if( !pBookMarkRects && pSh->GetDoc()->GetBookmarks().Count() ) + pBookMarkRects = new SwBookmarkRects( *pSh ); + + if( pBookMarkRects ) + { + switch( nAction ) + { + case 1: pBookMarkRects->Show(); break; + case 2: pBookMarkRects->Hide(); break; + case 3: pBookMarkRects->Invalidate( *pRect ); break; + } + + if( !pBookMarkRects->Count() ) + delete pBookMarkRects, pBookMarkRects = 0; + } +} + +#define SHOWBOOKMARKS1( nAct ) ShowBookmarks( GetShell(),nAct ); +#define SHOWBOOKMARKS2( nAct, pRect ) ShowBookmarks( GetShell(),nAct, pRect ); + +#else + +#define SHOWBOOKMARKS1( nAct ) +#define SHOWBOOKMARKS2( nAct, pRect ) + +#endif + +#ifdef SHOW_REDLINES + +#ifndef _REDLINE_HXX +#include +#endif + +class SwRedlineRects : public SwSelPaintRects +{ + USHORT nMode; + USHORT nNm; + + virtual void Paint( const Rectangle& rRect ); + virtual void FillRects(); + +public: + SwRedlineRects( const SwCrsrShell& rSh, USHORT nName, USHORT n ) + : SwSelPaintRects( rSh ), nMode( n ), nNm( nName ) + {} +}; + +void SwRedlineRects::Paint( const Rectangle& rRect ) +{ + Window* pWin = GetShell()->GetWin(); + + RasterOp eOld( pWin->GetRasterOp() ); + BOOL bLCol = pWin->IsLineColor(); + Color aLCol( pWin->GetLineColor() ); + BOOL bFCol = pWin->IsFillColor(); + Color aFCol( pWin->GetFillColor() ); + + pWin->SetRasterOp( ROP_XOR ); + Color aCol; + + UINT8 nVal = 0xc8 - ( (nMode / 4) * 16 ); + switch( nMode % 4 ) + { + case 0: aCol = RGB_COLORDATA( nVal, nVal, 0xFF ); break; + case 1: aCol = RGB_COLORDATA( 0xFF, 0xc8, nVal ); break; + case 2: aCol = RGB_COLORDATA( nVal, 0xFF, nVal ); break; + case 3: aCol = RGB_COLORDATA( 0xFF, nVal, nVal ); break; + } + aCol = aCol.GetColor() ^ COL_WHITE; + + pWin->SetFillColor( aCol ); + pWin->SetLineColor( aCol ); + + pWin->DrawRect( rRect ); + + if( bLCol ) pWin->SetLineColor( aLCol ); else pWin->SetLineColor(); + if( bFCol ) pWin->SetFillColor( aFCol ); else pWin->SetFillColor(); + pWin->SetRasterOp( eOld ); +} + +void SwRedlineRects::FillRects() +{ + SwRegionRects aReg( GetShell()->VisArea() ); + + const SwRedlineTbl& rTbl = GetShell()->GetDoc()->GetRedlineTbl(); + SwShellCrsr* pCrsr = 0; + for( USHORT n = 0; n < rTbl.Count(); ++n ) + { + const SwRedline& rRed = *rTbl[ n ]; + if( rRed.HasMark() && (nMode % 4 ) == rRed.GetType() && + nNm == rRed.GetAuthor() ) + { + if( !pCrsr ) + { + pCrsr = new SwShellCrsr( *GetShell(), *rRed.GetPoint() ); + pCrsr->SetMark(); + } + else + *pCrsr->GetPoint() = *rRed.GetPoint(); + *pCrsr->GetMark() = *rRed.GetMark(); + pCrsr->FillRects(); + for( USHORT i = 0; i < pCrsr->Count(); ++i ) + aReg -= (*pCrsr)[ i ]; + + pCrsr->Remove( 0, i ); + } + } + if( pCrsr ) delete pCrsr; + + aReg.Invert(); + SwRects::Insert( &aReg, 0 ); +} + +SwRedlineRects* aRedlines[ 10 * 4 ]; +static int bFirstCall = TRUE; + +void ShowRedlines( const SwCrsrShell* pSh, int nAction, const SwRect* pRect = 0 ) +{ + if( bFirstCall ) + { + memset( aRedlines, 0, sizeof(aRedlines)); + bFirstCall = FALSE; + } + + const SwRedlineTbl& rTbl = pSh->GetDoc()->GetRedlineTbl(); + const SwRedlineAuthorTbl& rAuthorTbl = pSh->GetDoc()->GetRedlineAuthorTbl(); + + for( USHORT n = 0; n < rAuthorTbl.Count(); ++n ) + { + for( int i = 0; i < 4; ++i ) + { + SwRedlineRects** ppRedRect = &aRedlines[ n * 4 + i ]; + if( rTbl.Count() && !*ppRedRect ) + *ppRedRect = new SwRedlineRects( *pSh, n, n * 4 + i ); + + if( *ppRedRect ) + { + switch( nAction ) + { + case 1: (*ppRedRect)->Show(); break; + case 2: (*ppRedRect)->Hide(); break; + case 3: (*ppRedRect)->Invalidate( *pRect ); break; + } + + if( !(*ppRedRect)->Count() ) + delete *ppRedRect, *ppRedRect = 0; + } + } + } +} + +#define SHOWREDLINES1( nAct ) ShowRedlines( GetShell(),nAct ); +#define SHOWREDLINES2( nAct, pRect ) ShowRedlines( GetShell(),nAct, pRect ); + +#else + +#define SHOWREDLINES1( nAct ) +#define SHOWREDLINES2( nAct, pRect ) + +#endif + +#ifdef JP_REDLINE + if( GetDoc()->GetRedlineTbl().Count() ) + { + SwRedlineTbl& rRedlineTbl = (SwRedlineTbl&)GetDoc()->GetRedlineTbl(); + for( USHORT i = 0; i < rRedlineTbl.Count(); ++i ) + rRedlineTbl[ i ]->HideRects( *GetShell() ); + } +#endif + +// -------- Ab hier Klassen / Methoden fuer den nicht Text-Cursor ------ + +SwVisCrsr::SwVisCrsr( const SwCrsrShell * pCShell ) + : pCrsrShell( pCShell ) +{ + pCShell->GetWin()->SetCursor( &aTxtCrsr ); + bIsVisible = aTxtCrsr.IsVisible(); + bIsDragCrsr = FALSE; + aTxtCrsr.SetWidth( 0 ); + +#ifdef SW_CRSR_TIMER + bTimerOn = TRUE; + SetTimeout( 50 ); // 50msec Verzoegerung +#endif +} + + + +SwVisCrsr::~SwVisCrsr() +{ +#ifdef SW_CRSR_TIMER + if( bTimerOn ) + Stop(); // Timer stoppen +#endif + + if( bIsVisible && aTxtCrsr.IsVisible() ) + aTxtCrsr.Hide(); + + pCrsrShell->GetWin()->SetCursor( 0 ); +} + + + + +void SwVisCrsr::Show() +{ + if( !bIsVisible ) + { + bIsVisible = TRUE; + + // muss ueberhaupt angezeigt werden ? + if( pCrsrShell->VisArea().IsOver( pCrsrShell->aCharRect ) ) +#ifdef SW_CRSR_TIMER + { + if( bTimerOn ) + Start(); // Timer aufsetzen + else + { + if( IsActive() ) + Stop(); // Timer Stoppen + + _SetPosAndShow(); + } + } +#else + _SetPosAndShow(); +#endif + } +} + + + +void SwVisCrsr::Hide() +{ + if( bIsVisible ) + { + bIsVisible = FALSE; + +#ifdef SW_CRSR_TIMER + if( IsActive() ) + Stop(); // Timer Stoppen +#endif + + if( aTxtCrsr.IsVisible() ) // sollten die Flags nicht gueltig sein? + aTxtCrsr.Hide(); + } +} + +#ifdef SW_CRSR_TIMER + +void __EXPORT SwVisCrsr::Timeout() +{ + ASSERT( !bIsDragCrsr, "Timer vorher abschalten" ); + if( bIsVisible ) + { + if ( !pCrsrShell->GetWin() ) //SwFrmFmt::GetGraphic setzt das Win temp aus! + Start(); + else + _SetPosAndShow(); + } +} + +FASTBOOL SwCrsrShell::ChgCrsrTimerFlag( BOOL bTimerOn ) +{ + return pVisCrsr->ChgTimerFlag( bTimerOn ); +} + + +FASTBOOL SwVisCrsr::ChgTimerFlag( BOOL bFlag ) +{ + register bOld = bTimerOn; + if( !bFlag && bIsVisible && IsActive() ) + { + Stop(); // Timer Stoppen + _SetPosAndShow(); + } + bTimerOn = bFlag; + return bOld; +} + +#endif + + +void SwVisCrsr::_SetPosAndShow() +{ + SwRect aRect( pCrsrShell->aCharRect.Pos(), + Size( 1, pCrsrShell->aCrsrHeight.Y() ) ); + aRect.Pos().Y() += pCrsrShell->aCrsrHeight.X(); + if( aRect.Height() ) + { + ::SwCalcPixStatics( pCrsrShell->GetOut() ); + ::SwAlignRect( aRect, (ViewShell*)pCrsrShell ); + } + aRect.Width( 1 ); + + aTxtCrsr.SetHeight( aRect.Height() ); + aTxtCrsr.SetPos( aRect.Pos() ); + if ( !pCrsrShell->IsCrsrReadonly() ) + { + if ( pCrsrShell->GetDrawView() ) + ((SwDrawView*)pCrsrShell->GetDrawView())->SetAnimationEnabled( + !pCrsrShell->IsSelection() ); + + USHORT nStyle = bIsDragCrsr ? CURSOR_SHADOW : 0; + if( nStyle != aTxtCrsr.GetStyle() ) + { + aTxtCrsr.SetStyle( nStyle ); + aTxtCrsr.SetWindow( bIsDragCrsr ? pCrsrShell->GetWin() : 0 ); + } + + aTxtCrsr.Show(); + } +} + + +/* */ +// ------ Ab hier Klassen / Methoden fuer die Selectionen ------- + +SwSelPaintRects::SwSelPaintRects( const SwCrsrShell& rCSh ) + : SwRects( 0 ), pCShell( &rCSh ) +{ +} + +SwSelPaintRects::~SwSelPaintRects() +{ + Hide(); +} + +void SwSelPaintRects::Hide() +{ + for( USHORT n = 0; n < Count(); ++n ) + Paint( (*this)[n] ); + SwRects::Remove( 0, Count() ); +} + +void SwSelPaintRects::Show() +{ + if( pCShell->GetDrawView() ) + { + SdrView* pView = (SdrView*)pCShell->GetDrawView(); + pView->SetAnimationEnabled( !pCShell->IsSelection() ); + } + + SwRects aTmp; + aTmp.Insert( this, 0 ); // Kopie vom Array + + SwRects::Remove( 0, SwRects::Count() ); + FillRects(); + + if( Count() || aTmp.Count() ) + { + SwRegionRects aReg( pCShell->VisArea() ); + + // suche die neu selektierten Rechtecke heraus + aReg.Remove( 0, aReg.Count() ); + aReg.Insert( this, 0 ); + + for( USHORT n = 0; n < aTmp.Count(); ++n ) + aReg -= aTmp[n]; + + // jetzt sollten in aReg nur noch die neuen Rechtecke vorliegen + for( n = 0; n < aReg.Count(); ++n ) + Paint( aReg[n] ); + + // suche die nicht mehr selektierten Rechtecke heraus + if( aTmp.Count() ) + { + aReg.Remove( 0, aReg.Count() ); + aReg.Insert( &aTmp, 0 ); + + for( n = 0; n < Count(); ++n ) + aReg -= (*this)[n]; + // jetzt sollten in aReg nur noch die alten Rechtecke vorliegen + for( n = 0; n < aReg.Count(); ++n ) + Paint( aReg[n] ); + } + } +} + +void SwSelPaintRects::Invalidate( const SwRect& rRect ) +{ + register USHORT nSz = Count(); + if( !nSz ) + return; + + SwRegionRects aReg( GetShell()->VisArea() ); + aReg.Remove( 0, aReg.Count() ); + aReg.Insert( this, 0 ); + aReg -= rRect; + SwRects::Remove( 0, nSz ); + SwRects::Insert( &aReg, 0 ); + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // Liegt die Selection rechts oder unten ausserhalb des sichtbaren + // Bereiches, so ist diese nie auf eine Pixel rechts/unten aligned. + // Das muss hier erkannt und ggf. das Rechteckt erweitert werden. + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + if( GetShell()->bVisPortChgd && 0 != ( nSz = Count()) ) + { + SwSelPaintRects::Get1PixelInLogic( *GetShell() ); + register SwRect* pRect = (SwRect*)GetData(); + for( ; nSz--; ++pRect ) + { + if( pRect->Right() == GetShell()->aOldRBPos.X() ) + pRect->Right( pRect->Right() + nPixPtX ); + if( pRect->Bottom() == GetShell()->aOldRBPos.Y() ) + pRect->Bottom( pRect->Bottom() + nPixPtY ); + } + } +} + +void SwSelPaintRects::Paint( const Rectangle& rRect ) +{ + GetShell()->GetWin()->Invert( rRect ); +} + +/* + * Rectangle ist in Dokument-Koordianten !! + * pWin != 0 -> auch wirklich malen + * == 0 -> nur testen, ob es gemalt werden kann + */ + +void SwSelPaintRects::Paint( const SwRect& rRect ) +{ + Window* pWin = GetShell()->GetWin(); + const SwRect& rVisArea = GetShell()->VisArea(); + + if( !pWin || rRect.IsEmpty() || !rVisArea.IsOver( rRect ) ) + return; + + Rectangle aPntRect( rRect.SVRect() ); + Rectangle aCalcRect( aPntRect ); + + aPntRect = pWin->LogicToPixel( aPntRect ); + + // falls nach der "Normalisierung" kein Rectangle besteht -> Ende + if( aPntRect.Left() == aPntRect.Right() || + aPntRect.Top() == aPntRect.Bottom() ) + return; + + // damit Linien nicht doppelt invertiert werden, muss jeweis von + // der rechten und unteren Seite ein PIXEL abgezogen werden ! + // Pixel heisst, gleichgueltig, welcher MapMode heute zaehlt ! + + FASTBOOL bChg = FALSE; + FASTBOOL bTstRight = rRect.Right() < rVisArea.Right(); + FASTBOOL bTstBottom = rRect.Bottom() < rVisArea.Bottom(); + + if( bTstBottom || bTstRight ) + { + ++aCalcRect.Bottom(); + ++aCalcRect.Right(); + aCalcRect = pWin->LogicToPixel( aCalcRect ); + + if( bTstBottom && aPntRect.Bottom() == aCalcRect.Bottom() ) + { + --aPntRect.Bottom(); + bChg = TRUE; + } + if( bTstRight && aPntRect.Right() == aCalcRect.Right() ) + { + --aPntRect.Right(); + bChg = TRUE; + } + } + + if( bChg ) + Paint( pWin->PixelToLogic( aPntRect )); + else + Paint( rRect.SVRect() ); +} + + +void SwSelPaintRects::FillRects() +{ +} + +// check current MapMode of the shell and set possibly the static members. +// Optional set the parameters pX, pY +void SwSelPaintRects::Get1PixelInLogic( const ViewShell& rSh, + long* pX, long* pY ) +{ + const Window& rOut = *rSh.GetWin(); + const MapMode& rMM = rOut.GetMapMode(); + if( pMapMode->GetMapUnit() != rMM.GetMapUnit() || + pMapMode->GetScaleX() != rMM.GetScaleX() || + pMapMode->GetScaleY() != rMM.GetScaleY() ) + { + *pMapMode = rMM; + Size aTmp( 1, 1 ); + aTmp = rOut.PixelToLogic( aTmp ); + nPixPtX = aTmp.Width(); + nPixPtY = aTmp.Height(); + } + if( pX ) + *pX = nPixPtX; + if( pY ) + *pY = nPixPtY; +} + + +/* */ + +SwShellCrsr::SwShellCrsr( const SwCrsrShell& rCShell, const SwPosition &rPos ) + : SwCursor( rPos ), SwSelPaintRects( rCShell ), + pPt( SwPaM::GetPoint() ) +{} + + +SwShellCrsr::SwShellCrsr( const SwCrsrShell& rCShell, const SwPosition &rPos, + const Point& rPtPos, SwPaM* pRing ) + : SwCursor( rPos, pRing ), SwSelPaintRects( rCShell ), + pPt( SwPaM::GetPoint() ), aPtPt( rPtPos ), aMkPt( rPtPos ) +{} + + +SwShellCrsr::SwShellCrsr( SwShellCrsr& rICrsr ) + : SwCursor( rICrsr ), SwSelPaintRects( *rICrsr.GetShell() ), + pPt( SwPaM::GetPoint() ), + aPtPt( rICrsr.GetPtPos() ), + aMkPt( rICrsr.GetMkPos() ) +{} + +SwShellCrsr::~SwShellCrsr() {} + +SwShellCrsr::operator SwShellCrsr* () { return this; } + +void SwShellCrsr::SetMark() +{ + if( SwPaM::GetPoint() == pPt ) + aMkPt = aPtPt; + else + aPtPt = aMkPt; + SwPaM::SetMark(); +} + +void SwShellCrsr::FillRects() +{ + // die neuen Rechtecke berechnen + if( HasMark() && + GetPoint()->nNode.GetNode().IsCntntNode() && + GetPoint()->nNode.GetNode().GetCntntNode()->GetFrm() && + (GetMark()->nNode == GetPoint()->nNode || + (GetMark()->nNode.GetNode().IsCntntNode() && + GetMark()->nNode.GetNode().GetCntntNode()->GetFrm() ) )) + GetDoc()->GetRootFrm()->CalcFrmRects( *this, GetShell()->IsTableMode() ); +} + + +void SwShellCrsr::Show() +{ + SwShellCrsr * pTmp = this; + do { + pTmp->SwSelPaintRects::Show(); + } while( this != ( pTmp = (SwShellCrsr*)*(SwCursor*)(pTmp->GetNext() ))); + + SHOWBOOKMARKS1( 1 ) + SHOWREDLINES1( 1 ) +} + + + // Dieses Rechteck wird neu gepaintet, also ist die SSelection in + // dem Bereich ungueltig +void SwShellCrsr::Invalidate( const SwRect& rRect ) +{ + SwShellCrsr * pTmp = this; + do { + pTmp->SwSelPaintRects::Invalidate( rRect ); + } while( this != ( pTmp = (SwShellCrsr*)*(SwCursor*)(pTmp->GetNext() ))); + + SHOWBOOKMARKS2( 3, &rRect ) + SHOWREDLINES2( 3, &rRect ) +} + + +void SwShellCrsr::Hide() +{ + SwShellCrsr * pTmp = this; + do { + pTmp->SwSelPaintRects::Hide(); + } while( this != ( pTmp = (SwShellCrsr*)*(SwCursor*)(pTmp->GetNext() ))); + + SHOWBOOKMARKS1( 2 ) + SHOWREDLINES1( 2 ) +} + +SwCursor* SwShellCrsr::Create( SwPaM* pRing ) const +{ + return new SwShellCrsr( *GetShell(), *GetPoint(), GetPtPos(), pRing ); +} + + +FASTBOOL SwShellCrsr::MaxReplaceArived() +{ + BOOL bRet = FALSE; + short nRet; + Window* pDlg = ::GetSearchDialog(); + if( pDlg ) + { + // alte Actions beenden; die Tabellen-Frames werden angelegt und + // eine SSelection kann erzeugt werden + SvUShorts aArr; + ViewShell *pShell = GetDoc()->GetRootFrm()->GetCurrShell(), + *pSh = pShell; + do { + for( USHORT nActCnt = 0; pSh->ActionPend(); ++nActCnt ) + pSh->EndAction(); + aArr.Insert( nActCnt, aArr.Count() ); + } while( pShell != ( pSh = (ViewShell*)pSh->GetNext() ) ); + + { + nRet = QueryBox( pDlg, SW_RES( MSG_COMCORE_ASKSEARCH )).Execute(); + } + + for( USHORT n = 0; n < aArr.Count(); ++n ) + { + for( USHORT nActCnt = aArr[n]; nActCnt--; ) + pSh->StartAction(); + pSh = (ViewShell*)pSh->GetNext(); + } + } + else + // ansonsten aus dem Basic, und dann auf RET_YES schalten + nRet = RET_YES; + + if( RET_CANCEL == nRet ) + bRet = TRUE; + else if( RET_YES == nRet ) + { + SwDoc* pDoc = GetDoc(); + pDoc->DelAllUndoObj(); + pDoc->DoUndo( FALSE ); + } + return bRet; +} + +void SwShellCrsr::SaveTblBoxCntnt( const SwPosition* pPos ) +{ + ((SwCrsrShell*)GetShell())->SaveTblBoxCntnt( pPos ); +} + +FASTBOOL SwShellCrsr::UpDown( BOOL bUp, USHORT nCnt ) +{ + return SwCursor::UpDown( bUp, nCnt, + &GetPtPos(), GetShell()->GetUpDownX() ); +} + +#ifndef PRODUCT + +// JP 05.03.98: zum Testen des UNO-Crsr Verhaltens hier die Implementierung +// am sichtbaren Cursor + +FASTBOOL SwShellCrsr::IsSelOvr( int eFlags ) +{ +#if 0 + SwDoc* pDoc = GetDoc(); + SwNodeIndex aOldIdx( *pDoc->GetNodes()[ GetSavePos()->nNode ] ); + SwNodeIndex& rPtIdx = GetPoint()->nNode; + SwStartNode *pOldSttNd = aOldIdx.GetNode().FindStartNode(), + *pNewSttNd = rPtIdx.GetNode().FindStartNode(); + if( pOldSttNd != pNewSttNd ) + { + BOOL bMoveDown = GetSavePos()->nNode < rPtIdx.GetIndex(); + BOOL bValidPos = FALSE; + if( bMoveDown ) + { + // ist das Ende noch nicht erreicht worden? + while( pOldSttNd->EndOfSectionIndex() > rPtIdx.GetIndex() ) + { + // dann versuche auf die "Ebene" zurueck zukommen + rPtIdx.Assign( *pNewSttNd->EndOfSectionNode(), 1 ); + while( pOldSttNd != rPtIdx.GetNode().FindStartNode() ) + rPtIdx.Assign( *rPtIdx.GetNode().EndOfSectionNode(), 1 ); + + if( !rPtIdx.GetNode().IsCntntNode() && + !pDoc->GetNodes().GoNextSection( &rPtIdx )) + break; + + if( pOldSttNd == + ( pNewSttNd = rPtIdx.GetNode().FindStartNode() )) + { + // das ist die gesuchte Position + bValidPos = TRUE; + break; + } + } + } + else + { + // ist der Start noch nicht erreicht worden? + while( pOldSttNd->GetIndex() < rPtIdx.GetIndex() ) + { + // dann versuche auf die "Ebene" zurueck zukommen + rPtIdx.Assign( *pNewSttNd, -1 ); + while( pOldSttNd != rPtIdx.GetNode().FindStartNode() ) + rPtIdx.Assign( *rPtIdx.GetNode().FindStartNode(), -1 ); + + if( !rPtIdx.GetNode().IsCntntNode() && + !pDoc->GetNodes().GoPrevSection( &rPtIdx )) + break; + + if( pOldSttNd == + ( pNewSttNd = rPtIdx.GetNode().FindStartNode() )) + { + // das ist die gesuchte Position + bValidPos = TRUE; + break; + } + } + } + + if( bValidPos ) + { + SwCntntNode* pCNd = GetCntntNode(); + xub_StrLen nCnt = 0; + if( pCNd && !bMoveDown ) + nCnt = pCNd->Len(); + GetPoint()->nContent.Assign( pCNd, nCnt ); + } + else + { + rPtIdx = GetSavePos()->nNode; + GetPoint()->nContent.Assign( GetCntntNode(), GetSavePos()->nCntnt ); + return FALSE; + } + } +#endif + return SwCursor::IsSelOvr( eFlags ); +} + +#endif + +// TRUE: an die Position kann der Cursor gesetzt werden +FASTBOOL SwShellCrsr::IsAtValidPos( BOOL bPoint ) const +{ + if( GetShell() && ( GetShell()->IsAllProtect() || + GetShell()->GetViewOptions()->IsReadonly() || + ( GetShell()->Imp()->GetDrawView() && + GetShell()->Imp()->GetDrawView()->GetMarkList().GetMarkCount() ))) + return TRUE; + + return SwCursor::IsAtValidPos( bPoint ); +} + +/* */ + +SwShellTableCrsr::SwShellTableCrsr( const SwCrsrShell& rCrsrSh, + const SwPosition& rPos ) + : SwTableCursor( rPos ), SwShellCrsr( rCrsrSh, rPos ), + SwCursor( rPos ) +{ +} + +SwShellTableCrsr::SwShellTableCrsr( const SwCrsrShell& rCrsrSh, + const SwPosition& rMkPos, const Point& rMkPt, + const SwPosition& rPtPos, const Point& rPtPt ) + : SwTableCursor( rPtPos ), SwShellCrsr( rCrsrSh, rPtPos ), + SwCursor( rPtPos ) +{ + SetMark(); + *GetMark() = rMkPos; + GetMkPos() = rMkPt; + GetPtPos() = rPtPt; +} + +SwShellTableCrsr::~SwShellTableCrsr() {} + +void SwShellTableCrsr::SetMark() { SwShellCrsr::SetMark(); } +SwShellTableCrsr::operator SwShellCrsr* () { return this; } +SwShellTableCrsr::operator SwTableCursor* () { return this; } +SwShellTableCrsr::operator SwShellTableCrsr* () { return this; } + +SwCursor* SwShellTableCrsr::Create( SwPaM* pRing ) const +{ + return SwShellCrsr::Create( pRing ); +} +FASTBOOL SwShellTableCrsr::MaxReplaceArived() +{ + return SwShellCrsr::MaxReplaceArived(); +} +void SwShellTableCrsr::SaveTblBoxCntnt( const SwPosition* pPos ) +{ + SwShellCrsr::SaveTblBoxCntnt( pPos ); +} + + +void SwShellTableCrsr::FillRects() +{ + // die neuen Rechtecke berechnen + // JP 16.01.98: wenn der Cursor noch "geparkt" ist nichts machen!! + if( !aSelBoxes.Count() || bParked || + !GetPoint()->nNode.GetIndex() ) + return; + + SwRegionRects aReg( GetShell()->VisArea() ); + SwNodes& rNds = GetDoc()->GetNodes(); + for( USHORT n = 0; n < aSelBoxes.Count(); ++n ) + { + SwNodeIndex aIdx( *(*(aSelBoxes.GetData() + n ))->GetSttNd() ); + SwCntntNode* pCNd = rNds.GoNextSection( &aIdx, TRUE, FALSE ); + if( !pCNd ) + continue; + + SwFrm* pFrm = pCNd->GetFrm( &GetSttPos() ); + while( pFrm && !pFrm->IsCellFrm() ) + pFrm = pFrm->GetUpper(); + ASSERT( pFrm, "Node nicht in einer Tabelle" ); + if( pFrm && aReg.GetOrigin().IsOver( pFrm->Frm() ) ) + aReg -= pFrm->Frm(); + } + aReg.Invert(); + Insert( &aReg, 0 ); +} + + +// Pruefe, ob sich der SPoint innerhalb der Tabellen-SSelection befindet +FASTBOOL SwShellTableCrsr::IsInside( const Point& rPt ) const +{ + // die neuen Rechtecke berechnen + // JP 16.01.98: wenn der Cursor noch "geparkt" ist nichts machen!! + if( !aSelBoxes.Count() || bParked || + !GetPoint()->nNode.GetIndex() ) + return FALSE; + + SwNodes& rNds = GetDoc()->GetNodes(); + for( USHORT n = 0; n < aSelBoxes.Count(); ++n ) + { + SwNodeIndex aIdx( *(*(aSelBoxes.GetData() + n ))->GetSttNd() ); + SwCntntNode* pCNd = rNds.GoNextSection( &aIdx, TRUE, FALSE ); + if( !pCNd ) + continue; + + SwFrm* pFrm = pCNd->GetFrm( &GetPtPos() ); + while( pFrm && !pFrm->IsCellFrm() ) + pFrm = pFrm->GetUpper(); + ASSERT( pFrm, "Node nicht in einer Tabelle" ); + if( pFrm && pFrm->Frm().IsInside( rPt ) ) + return TRUE; + } + return FALSE; +} + +#ifndef PRODUCT + +// JP 05.03.98: zum Testen des UNO-Crsr Verhaltens hier die Implementierung +// am sichtbaren Cursor +FASTBOOL SwShellTableCrsr::IsSelOvr( int eFlags ) +{ + return SwShellCrsr::IsSelOvr( eFlags ); +} + +#endif + +FASTBOOL SwShellTableCrsr::IsAtValidPos( BOOL bPoint ) const +{ + return SwShellCrsr::IsAtValidPos( bPoint ); +} + diff --git a/sw/source/core/doc/acmplwrd.cxx b/sw/source/core/doc/acmplwrd.cxx new file mode 100644 index 000000000000..b38800120ecc --- /dev/null +++ b/sw/source/core/doc/acmplwrd.cxx @@ -0,0 +1,303 @@ +/************************************************************************* + * + * $RCSfile: acmplwrd.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:15 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + + +#ifndef _HINTIDS_HXX +#include +#endif + +#ifndef _INTN_HXX //autogen +#include +#endif +#ifndef _APP_HXX //autogen +#include +#endif + +#ifndef _ACMPLWRD_HXX //autogen +#include +#endif +#ifndef _DOC_HXX //autogen +#include +#endif +#ifndef _NDINDEX_HXX //autogen +#include +#endif +#ifndef _NODE_HXX //autogen +#include +#endif +#ifndef _DOCARY_HXX +#include +#endif +#ifndef _NDTXT_HXX //autogen +#include +#endif +#ifndef _PAM_HXX //autogen +#include +#endif + + +SwAutoCompleteWord::SwAutoCompleteWord( USHORT nWords, USHORT nMWrdLen ) + : aWordLst( 0, 255 ), aLRULst( 0, 255 ), + nMaxCount( nWords ), + nMinWrdLen( nMWrdLen ), + bLockWordLst( FALSE ) +{ +} + +SwAutoCompleteWord::~SwAutoCompleteWord() +{ +} + +BOOL SwAutoCompleteWord::InsertWord( const String& rWord ) +{ + BOOL bRet = FALSE; + xub_StrLen nWrdLen = rWord.Len(); + while( nWrdLen && '.' == rWord.GetChar( nWrdLen-1 )) + --nWrdLen; + + if( !bLockWordLst && nWrdLen > nMinWrdLen ) + { + StringPtr pNew = new String( rWord, 0, nWrdLen ); + USHORT nInsPos; + if( aWordLst.Insert( pNew, nInsPos ) ) + { + bRet = TRUE; + if( aLRULst.Count() < nMaxCount ) + aLRULst.Insert( pNew, 0 ); + else + { + // der letzte muss entfernt werden + // damit der neue vorne Platz hat + String* pDel = (String*)aLRULst[ nMaxCount - 1 ]; + + void** ppData = (void**)aLRULst.GetData(); + memmove( ppData+1, ppData, (nMaxCount - 1) * sizeof( void* )); + *ppData = pNew; + + aWordLst.Remove( pDel ); + delete pDel; + } + } + else + { + delete pNew; + // dann aber auf jedenfall nach "oben" moven + pNew = aWordLst[ nInsPos ]; + nInsPos = aLRULst.GetPos( (void*)pNew ); + ASSERT( USHRT_MAX != nInsPos, "String nicht gefunden" ); + if( nInsPos ) + { + void** ppData = (void**)aLRULst.GetData(); + memmove( ppData+1, ppData, nInsPos * sizeof( void* ) ); + *ppData = pNew; + } + } + } + return bRet; +} + +BOOL SwAutoCompleteWord::RemoveWord( const String& rWord ) +{ + BOOL bRet = FALSE; + USHORT nPos; + const StringPtr pStr = (StringPtr)&rWord; + if( !bLockWordLst && aWordLst.Seek_Entry( pStr, &nPos )) + { + void* pDel = aWordLst[ nPos ]; + aWordLst.DeleteAndDestroy( nPos ); + + nPos = aLRULst.GetPos( pDel ); + ASSERT( USHRT_MAX != nPos, "String nicht gefunden" ); + aLRULst.Remove( nPos ); + } + return bRet; +} + +BOOL SwAutoCompleteWord::SearchWord( const String& rWord, USHORT* pFndPos ) const +{ + const StringPtr pStr = (StringPtr)&rWord; + return aWordLst.Seek_Entry( pStr, pFndPos ); +} + + +BOOL SwAutoCompleteWord::SetToTop( const String& rWord ) +{ + BOOL bRet = FALSE; + USHORT nPos; + const StringPtr pStr = (StringPtr)&rWord; + if( !bLockWordLst && aWordLst.Seek_Entry( pStr, &nPos )) + { + bRet = TRUE; + void* pTop = aWordLst[ nPos ]; + + nPos = aLRULst.GetPos( pTop ); + ASSERT( USHRT_MAX != nPos, "String nicht gefunden" ); + if( nPos ) + { + void** ppData = (void**)aLRULst.GetData(); + memmove( ppData+1, ppData, nPos * sizeof( void* ) ); + *ppData = pTop; + } + } + return bRet; +} + +void SwAutoCompleteWord::SetMaxCount( USHORT nNewMax ) +{ + if( nNewMax < nMaxCount && aLRULst.Count() > nNewMax ) + { + // dann die unten ueberhaengenden entfernen + while( nNewMax >= aWordLst.Count() ) + { + USHORT nPos = aWordLst.GetPos( (String*)aLRULst[ nNewMax-1 ] ); + ASSERT( USHRT_MAX != nPos, "String nicht gefunden" ); + aWordLst.DeleteAndDestroy( nPos ); + } + aLRULst.Remove( nNewMax-1, aLRULst.Count() - nNewMax ); + } + nMaxCount = nNewMax; +} + +void SwAutoCompleteWord::SetMinWordLen( USHORT n ) +{ + // will man wirklich alle Worte, die kleiner als die neue Min Laenge + // sind entfernen? + // JP 02.02.99 - erstmal nicht. + + // JP 11.03.99 - mal testhalber eingebaut + if( n < nMinWrdLen ) + { + for( USHORT nPos = 0; nPos < aWordLst.Count(); ++nPos ) + if( aWordLst[ nPos ]->Len() < n ) + { + void* pDel = aWordLst[ nPos ]; + aWordLst.DeleteAndDestroy( nPos ); + + USHORT nDelPos = aLRULst.GetPos( pDel ); + ASSERT( USHRT_MAX != nDelPos, "String nicht gefunden" ); + aLRULst.Remove( nDelPos ); + --nPos; + } + } + + nMinWrdLen = n; +} + +BOOL SwAutoCompleteWord::GetRange( const String& rWord, USHORT& rStt, + USHORT& rEnd ) const +{ + const StringPtr pStr = (StringPtr)&rWord; + aWordLst.Seek_Entry( pStr, &rStt ); + rEnd = rStt; + + const International& rInter = Application::GetAppInternational(); + while( rEnd < aWordLst.Count() && COMPARE_EQUAL == +//!!! UNICODE: fehlendes interface +// rInter.Compare( rWord, *aWordLst[ rEnd ]/*, rWord.Len()*/, +// INTN_COMPARE_IGNORECASE ) ) + rWord.CompareIgnoreCaseToAscii( *aWordLst[ rEnd ], rWord.Len() ) ) + ++rEnd; + + return rStt < rEnd; +} + +void SwAutoCompleteWord::CheckChangedList( const SvStringsISortDtor& rNewLst ) +{ + USHORT nMyLen = aWordLst.Count(), nNewLen = rNewLst.Count(); + USHORT nMyPos = 0, nNewPos = 0; + + for( ; nMyPos < nMyLen && nNewPos < nNewLen; ++nMyPos, ++nNewPos ) + { + const StringPtr pStr = rNewLst[ nNewPos ]; + while( aWordLst[ nMyPos ] != pStr ) + { + void* pDel = aWordLst[ nMyPos ]; + aWordLst.DeleteAndDestroy( nMyPos ); + + USHORT nPos = aLRULst.GetPos( pDel ); + ASSERT( USHRT_MAX != nPos, "String nicht gefunden" ); + aLRULst.Remove( nPos ); + if( nMyPos >= --nMyLen ) + break; + } + } + if( nMyPos < nMyLen ) + { + for( ; nNewPos < nMyLen; ++nNewPos ) + { + void* pDel = aWordLst[ nNewPos ]; + USHORT nPos = aLRULst.GetPos( pDel ); + ASSERT( USHRT_MAX != nPos, "String nicht gefunden" ); + aLRULst.Remove( nPos ); + } + aWordLst.DeleteAndDestroy( nMyPos, nMyLen - nMyPos ); + } +} + + + + diff --git a/sw/source/core/doc/doc.cxx b/sw/source/core/doc/doc.cxx new file mode 100644 index 000000000000..6219b077f6e6 --- /dev/null +++ b/sw/source/core/doc/doc.cxx @@ -0,0 +1,1312 @@ +/************************************************************************* + * + * $RCSfile: doc.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:15 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _HINTIDS_HXX +#include +#endif + +#ifndef _URLOBJ_HXX //autogen +#include +#endif +#ifndef _SV_POLY_HXX //autogen +#include +#endif +#ifndef _PSEUDO_HXX //autogen +#include +#endif +#ifndef _IPOBJ_HXX //autogen +#include +#endif +#ifndef _WORDSEL_HXX //autogen +#include +#endif +#ifndef _SFXDOCINF_HXX //autogen +#include +#endif +#ifndef _SVX_KEEPITEM_HXX //autogen +#include +#endif +#ifndef _SVX_CSCOITEM_HXX //autogen +#include +#endif +#ifndef _SVX_BRKITEM_HXX //autogen +#include +#endif +#ifndef _SVXLINKMGR_HXX +#include +#endif +#ifndef _TEXTCONV_HXX //autogen +#include +#endif +#ifndef SMDLL0_HXX //autogen +#include +#endif + +#ifndef _SWMODULE_HXX //autogen +#include +#endif +#ifndef _FMTPDSC_HXX //autogen +#include +#endif +#ifndef _FMTANCHR_HXX //autogen +#include +#endif +#ifndef _FMTRFMRK_HXX //autogen +#include +#endif +#ifndef _FMTINFMT_HXX //autogen +#include +#endif +#ifndef _FMTFLD_HXX //autogen +#include +#endif +#ifndef _TXTFLD_HXX //autogen +#include +#endif +#ifndef _TXTINET_HXX //autogen +#include +#endif +#ifndef _TXTRFMRK_HXX //autogen +#include +#endif +#ifndef _FRMATR_HXX +#include +#endif +#ifndef _LINKENUM_HXX +#include +#endif +#ifndef _DOC_HXX +#include +#endif +#ifndef _ERRHDL_HXX +#include +#endif +#ifndef _PAGEFRM_HXX +#include +#endif +#ifndef _ROOTFRM_HXX +#include +#endif +#ifndef _SWTABLE_HXX +#include +#endif +#ifndef _PAM_HXX +#include +#endif +#ifndef _NDTXT_HXX +#include +#endif +#ifndef _FLDBAS_HXX +#include +#endif +#ifndef _SWUNDO_HXX +#include // fuer die UndoIds +#endif +#ifndef _UNDOBJ_HXX +#include +#endif +#ifndef _PAGEDESC_HXX +#include //DTor +#endif +#ifndef _HINTS_HXX +#include +#endif +#ifndef _NDOLE_HXX +#include +#endif +#ifndef _NDGRF_HXX +#include +#endif +#ifndef _ROLBCK_HXX +#include // Undo-Attr +#endif +#ifndef _BOOKMRK_HXX +#include // fuer die Bookmarks +#endif +#ifndef _DOCTXM_HXX +#include // fuer die Verzeichnisse +#endif +#ifndef _GRFATR_HXX +#include +#endif +#ifndef _POOLFMT_HXX +#include // PoolVorlagen-Id's +#endif +#ifndef _MVSAVE_HXX +#include // fuer Server-Funktionalitaet +#endif +#ifndef _WRONG_HXX +#include // fuer OnlineSpell-Invalidierung +#endif +#ifndef _ACORRECT_HXX +#include // Autokorrektur +#endif +#ifndef _SECTION_HXX +#include // +#endif +#ifndef _MDIEXP_HXX +#include // Statusanzeige +#endif +#ifndef _DOCSTAT_HXX +#include +#endif +#ifndef _DOCARY_HXX +#include +#endif +#ifndef _REDLINE_HXX +#include +#endif +#ifndef _FLDUPDE_HXX +#include +#endif + +#ifndef _STATSTR_HRC +#include // StatLine-String +#endif + +class _GrfToOleUndo : public SwClient +{ +public: + String aAlternateText; + SwUndoReRead* pSaveObj; + PolyPolygon *pContour; + + _GrfToOleUndo( SwUndoReRead* pObj, SwGrfNode &rNd ); + TYPEINFO(); + + // wird der Parent geloescht, dann loeschen wir uns selbst + virtual void Modify( SfxPoolItem *pOld, SfxPoolItem *pNew); +}; + + +// Seiten-Deskriptoren +SV_IMPL_PTRARR(SwPageDescs,SwPageDescPtr); +// Autoren +// IMPL_PTRREGARR_NOTL(Authors,Author) USED? +// Verzeichnisse +SV_IMPL_PTRARR( SwTOXTypes, SwTOXTypePtr ) +// FeldTypen +SV_IMPL_PTRARR( SwFldTypes, SwFldTypePtr) + +TYPEINIT1( _GrfToOleUndo, SwClient ); + + +_GrfToOleUndo::_GrfToOleUndo( SwUndoReRead* pObj, SwGrfNode &rNd ) : + SwClient( 0 ), + pSaveObj( pObj ), + aAlternateText( rNd.GetAlternateText() ), + pContour( rNd.HasContour() ? new PolyPolygon( *rNd.HasContour() ) : 0 ) +{ +} + +/* + * Dokumenteditieren (Doc-SS) zum Fuellen des Dokuments + * durch den RTF Parser und fuer die EditShell. + */ +void SwDoc::ChgDBName(const String& rNewName) +{ + if( !aDBName.Equals( rNewName ) ) + { + aDBName = rNewName; + SetModified(); + } + GetSysFldType(RES_DBNAMEFLD)->UpdateFlds(); +} + +BOOL SwDoc::SplitNode( const SwPosition &rPos, BOOL bChkTableStart ) +{ + SwCntntNode *pNode = rPos.nNode.GetNode().GetCntntNode(); + if(0 == pNode) + return FALSE; + + { + // Bug 26675: DataChanged vorm loeschen verschicken, dann bekommt + // man noch mit, welche Objecte sich im Bereich befinden. + // Danach koennen sie vor/hinter der Position befinden. + SwDataChanged aTmp( this, rPos, 0 ); + } + + SwUndoSplitNode* pUndo = 0; + if ( DoesUndo() ) + { + ClearRedo(); + // einfuegen vom Undo-Object, z.Z. nur beim TextNode + if( pNode->IsTxtNode() ) + AppendUndo( pUndo = new SwUndoSplitNode( this, rPos, bChkTableStart )); + } + + //JP 28.01.97: Sonderfall fuer SplitNode am Tabellenanfang: + // steht die am Doc/Fly/Footer/..-Anfang oder direkt + // hinter einer Tabelle, dann fuege davor + // einen Absatz ein + if( bChkTableStart && !rPos.nContent.GetIndex() && pNode->IsTxtNode() ) + { + ULONG nPrevPos = rPos.nNode.GetIndex() - 1; + const SwTableNode* pTblNd; + const SwNode* pNd = GetNodes()[ nPrevPos ]; + if( pNd->IsStartNode() && + SwTableBoxStartNode == ((SwStartNode*)pNd)->GetStartNodeType() && + 0 != ( pTblNd = GetNodes()[ --nPrevPos ]->GetTableNode() ) && + ((( pNd = GetNodes()[ --nPrevPos ])->IsStartNode() && + SwTableBoxStartNode != ((SwStartNode*)pNd)->GetStartNodeType() ) + || ( pNd->IsEndNode() && pNd->FindStartNode()->IsTableNode() ) + || pNd->IsCntntNode() )) + { + if( pNd->IsCntntNode() ) + { + //JP 30.04.99 Bug 65660: + // ausserhalb des normalen BodyBereiches gibt es keine + // Seitenumbrueche, also ist das hier kein gueltige + // Bedingung fuers einfuegen eines Absatzes + if( nPrevPos < GetNodes().GetEndOfExtras().GetIndex() ) + pNd = 0; + else + { + // Dann nur, wenn die Tabelle Umbrueche traegt! + const SwFrmFmt* pFrmFmt = pTblNd->GetTable().GetFrmFmt(); + if( SFX_ITEM_SET != pFrmFmt->GetItemState(RES_PAGEDESC, FALSE) && + SFX_ITEM_SET != pFrmFmt->GetItemState( RES_BREAK, FALSE ) ) + pNd = 0; + } + } + + if( pNd ) + { + SwTxtNode* pTxtNd = GetNodes().MakeTxtNode( + SwNodeIndex( *pTblNd ), + GetTxtCollFromPool( RES_POOLCOLL_TEXT )); + if( pTxtNd ) + { + ((SwPosition&)rPos).nNode = pTblNd->GetIndex()-1; + ((SwPosition&)rPos).nContent.Assign( pTxtNd, 0 ); + + // nur im BodyBereich den SeitenUmbruch/-Vorlage umhaengem + if( nPrevPos > GetNodes().GetEndOfExtras().GetIndex() ) + { + SwFrmFmt* pFrmFmt = pTblNd->GetTable().GetFrmFmt(); + const SfxPoolItem *pItem; + if( SFX_ITEM_SET == pFrmFmt->GetItemState( RES_PAGEDESC, + FALSE, &pItem ) ) + { + pTxtNd->SwCntntNode::SetAttr( *pItem ); + pFrmFmt->ResetAttr( RES_PAGEDESC ); + } + if( SFX_ITEM_SET == pFrmFmt->GetItemState( RES_BREAK, + FALSE, &pItem ) ) + { + pTxtNd->SwCntntNode::SetAttr( *pItem ); + pFrmFmt->ResetAttr( RES_BREAK ); + } + } + + if( pUndo ) + pUndo->SetTblFlag(); + SetModified(); + return TRUE; + } + } + } + } + + SvULongs aBkmkArr( 15, 15 ); + _SaveCntntIdx( this, rPos.nNode.GetIndex(), rPos.nContent.GetIndex(), + aBkmkArr, SAVEFLY_SPLIT ); + if( 0 != ( pNode = pNode->SplitNode( rPos ) )) + { + // verschiebe noch alle Bookmarks/TOXMarks/FlyAtCnt + if( aBkmkArr.Count() ) + _RestoreCntntIdx( this, aBkmkArr, rPos.nNode.GetIndex()-1, 0, TRUE ); + + if( IsRedlineOn() || (!IsIgnoreRedline() && pRedlineTbl->Count() )) + { + SwPaM aPam( rPos ); + aPam.SetMark(); + aPam.Move( fnMoveBackward ); + if( IsRedlineOn() ) + AppendRedline( new SwRedline( REDLINE_INSERT, aPam )); + else + SplitRedline( aPam ); + } + } + + SetModified(); + return TRUE; +} + +BOOL SwDoc::AppendTxtNode( SwPosition& rPos ) +{ + /* + * Neuen Node vor EndOfContent erzeugen. + */ + SwTxtNode *pCurNode = GetNodes()[ rPos.nNode ]->GetTxtNode(); + if( !pCurNode ) + { + // dann kann ja einer angelegt werden! + SwNodeIndex aIdx( rPos.nNode, 1 ); + pCurNode = GetNodes().MakeTxtNode( aIdx, + GetTxtCollFromPool( RES_POOLCOLL_STANDARD )); + } + else + pCurNode = (SwTxtNode*)pCurNode->AppendNode( rPos ); + + rPos.nNode++; + rPos.nContent.Assign( pCurNode, 0 ); + + if( DoesUndo() ) + { + ClearRedo(); + AppendUndo( new SwUndoInsert( rPos.nNode )); + } + + if( IsRedlineOn() || (!IsIgnoreRedline() && pRedlineTbl->Count() )) + { + SwPaM aPam( rPos ); + aPam.SetMark(); + aPam.Move( fnMoveBackward ); + if( IsRedlineOn() ) + AppendRedline( new SwRedline( REDLINE_INSERT, aPam )); + else + SplitRedline( aPam ); + } + + SetModified(); + return TRUE; +} + +BOOL SwDoc::Insert( const SwPaM &rRg, const String &rStr, BOOL bHintExpand ) +{ + if( DoesUndo() ) + ClearRedo(); + + const SwPosition* pPos = rRg.GetPoint(); + + if( pACEWord ) // Aufnahme in die Autokorrektur + { + if( 1 == rStr.Len() && pACEWord->IsDeleted() ) + pACEWord->CheckChar( *pPos, rStr.GetChar( 0 ) ); + delete pACEWord, pACEWord = 0; + } + + SwTxtNode *pNode = pPos->nNode.GetNode().GetTxtNode(); + if(!pNode) + return FALSE; + + const USHORT nInsMode = bHintExpand ? INS_EMPTYEXPAND + : INS_NOHINTEXPAND; + SwDataChanged aTmp( rRg, 0 ); + + if( !DoesUndo() || !DoesGroupUndo() ) + { + pNode->Insert( rStr, pPos->nContent, nInsMode ); + + if( DoesUndo() ) + AppendUndo( new SwUndoInsert( pPos->nNode, + pPos->nContent.GetIndex(), rStr.Len() )); + } + else + { // ist Undo und Gruppierung eingeschaltet, ist alles anders ! + USHORT nUndoSize = pUndos->Count(); + xub_StrLen nInsPos = pPos->nContent.GetIndex(); + SwUndoInsert * pUndo; + if( 0 == nUndoSize || UNDO_INSERT != + ( pUndo = (SwUndoInsert*)(*pUndos)[ --nUndoSize ])->GetId() || + !pUndo->CanGrouping( *pPos )) + { + pUndo = new SwUndoInsert( pPos->nNode, nInsPos, 0, + !WordSelection::IsNormalChar( rStr.GetChar( 0 )) ); + AppendUndo( pUndo ); + } + + for( xub_StrLen i = 0; i < rStr.Len(); ++i ) + { + nInsPos++; + // wenn CanGrouping() TRUE returnt, ist schon alles erledigt + if( !pUndo->CanGrouping( rStr.GetChar( i ) )) + { + pUndo = new SwUndoInsert( pPos->nNode, nInsPos, 1, + !WordSelection::IsNormalChar( rStr.GetChar( i )) ); + AppendUndo( pUndo ); + } + } + pNode->Insert( rStr, pPos->nContent, nInsMode ); + } + + if( IsRedlineOn() || (!IsIgnoreRedline() && pRedlineTbl->Count() )) + { + SwPaM aPam( pPos->nNode, aTmp.GetCntnt(), + pPos->nNode, pPos->nContent.GetIndex()); + if( IsRedlineOn() ) + AppendRedline( new SwRedline( REDLINE_INSERT, aPam )); + else + SplitRedline( aPam ); + } + + SetModified(); + return TRUE; +} + +SwFlyFrmFmt* SwDoc::_InsNoTxtNode( const SwPosition& rPos, SwNoTxtNode* pNode, + const SfxItemSet* pFlyAttrSet, + const SfxItemSet* pGrfAttrSet, + SwFrmFmt* pFrmFmt) +{ + SwFlyFrmFmt *pFmt = 0; + if( pNode ) + { + pFmt = _MakeFlySection( rPos, *pNode, FLY_AT_CNTNT, + pFlyAttrSet, pFrmFmt ); + if( pGrfAttrSet ) + pNode->SetAttr( *pGrfAttrSet ); + } + return pFmt; +} + +SwFlyFrmFmt* SwDoc::Insert( const SwPaM &rRg, + const String& rGrfName, + const String& rFltName, + const Graphic* pGraphic, + const SfxItemSet* pFlyAttrSet, + const SfxItemSet* pGrfAttrSet, + SwFrmFmt* pFrmFmt ) +{ + if( !pFrmFmt ) + pFrmFmt = GetFrmFmtFromPool( RES_POOLFRM_GRAPHIC ); + return _InsNoTxtNode( *rRg.GetPoint(), GetNodes().MakeGrfNode( + SwNodeIndex( GetNodes().GetEndOfAutotext() ), + rGrfName, rFltName, pGraphic, + pDfltGrfFmtColl ), + pFlyAttrSet, pGrfAttrSet, pFrmFmt ); +} + +SwFlyFrmFmt* SwDoc::Insert(const SwPaM &rRg, SvInPlaceObject *pObj, + const SfxItemSet* pFlyAttrSet, + const SfxItemSet* pGrfAttrSet, + SwFrmFmt* pFrmFmt ) +{ + if( !pFrmFmt ) + { + USHORT nId = RES_POOLFRM_OLE; + + FASTBOOL bMath = SmModuleDummy::HasID( *pObj->GetSvFactory() ); + if ( !bMath && pObj->IsLink() ) + { + SvGlobalName aCLSID; + ULONG lDummy; + String aDummy; + // Source CLSID erfragen + pObj->SvPseudoObject::FillClass( &aCLSID, &lDummy, &aDummy, &aDummy, &aDummy); + if( SmModuleDummy::HasID( aCLSID ) ) + { + //zuletzt vom StarMath-Server bearbeitet + bMath = TRUE; + } + } + if ( bMath ) + nId = RES_POOLFRM_FORMEL; + + pFrmFmt = GetFrmFmtFromPool( nId ); + } + return _InsNoTxtNode( *rRg.GetPoint(), GetNodes().MakeOLENode( + SwNodeIndex( GetNodes().GetEndOfAutotext() ), + pObj, + pDfltGrfFmtColl ), + pFlyAttrSet, pGrfAttrSet, + pFrmFmt ); +} + +void SwDoc::GrfToOle( const SwPaM &rRg, SvInPlaceObject * pObj ) +{ + // haben wir ueberhaupt eine Grafik an der Hand ?? + SwNodeIndex& rNdIdx = (SwNodeIndex&)rRg.GetPoint()->nNode; + SwGrfNode* pGrfNd = rNdIdx.GetNode().GetGrfNode(); + if( !pGrfNd ) + return; + + _GrfToOleUndo* pSaveForUndo = 0; + if( DoesUndo() ) + pSaveForUndo = new _GrfToOleUndo( new SwUndoReRead( rRg, *pGrfNd ), *pGrfNd); + + SwOLENode* pOLENd = GetNodes().MakeOLENode( rNdIdx, pObj, + (SwGrfFmtColl*)pGrfNd->GetFmtColl(), + pGrfNd->GetpSwAttrSet() ); + + pGrfNd->MakeFrms( *pOLENd ); + + if( pSaveForUndo ) + pOLENd->Add( pSaveForUndo ); + + ((SwPaM&)rRg).GetPoint()->nContent.Assign( pOLENd, 0 ); + GetNodes().DelNodes( rNdIdx, 1 ); + rNdIdx--; +} + +void SwDoc::OleToGrf( const SwPaM &rRg, const Graphic *pGrf ) +{ + // haben wir ueberhaupt eine Ole an der Hand ?? + SwNodeIndex& rNdIdx = (SwNodeIndex&)rRg.GetPoint()->nNode; + SwOLENode* pOleNd = rNdIdx.GetNode().GetOLENode(); + if( !pOleNd ) + return; + + SwGrfNode* pGrfNd = GetNodes().MakeGrfNode( rNdIdx, aEmptyStr, aEmptyStr, + pGrf, + (SwGrfFmtColl*)pOleNd->GetFmtColl(), + pOleNd->GetpSwAttrSet() ); + + pOleNd->MakeFrms( *pGrfNd ); + + // dann suche doch mal nach unserem angehaengten Client fuers Undo + { + SwClientIter aIter( *pOleNd ); + SwClient* pGTO = aIter.First(TYPE( _GrfToOleUndo )); + if( pGTO ) + { + SwUndoReRead* pUndo = ((_GrfToOleUndo*)pGTO)->pSaveObj; + pGrfNd->SetAlternateText( ((_GrfToOleUndo*)pGTO)->aAlternateText ); + pGrfNd->SetContour( ((_GrfToOleUndo*)pGTO)->pContour ); + if( DoesUndo() ) + AppendUndo( pUndo ); + else + delete pUndo; // Undo wurde abgeschaltet + delete pGTO; + } + } + + ((SwPaM&)rRg).GetPoint()->nContent.Assign( pGrfNd, 0 ); + GetNodes().DelNodes( rNdIdx, 1 ); + rNdIdx--; +} + +String SwDoc::GetCurWord( SwPaM& rPaM ) +{ + SwTxtNode *pNd = rPaM.GetNode()->GetTxtNode(); + if( pNd ) + return pNd->GetCurWord(rPaM.GetPoint()->nContent.GetIndex()); + return aEmptyStr; +} + + +/************************************************************************* +|* SwDoc::GetFldType() +|* Beschreibung: liefert den am Doc eingerichteten Feldtypen zurueck +*************************************************************************/ + +SwFieldType *SwDoc::GetSysFldType( const USHORT eWhich ) const +{ + for( register int i = 0; i < INIT_FLDTYPES; i++ ) + if( eWhich == (*pFldTypes)[i]->Which() ) + return (*pFldTypes)[i]; + return 0; +} + +//----- Macro --------------------------------------------------------- + +BOOL SwDoc::HasGlobalMacro( USHORT nEvent ) const +{ + return pMacroTable->IsKeyValid(nEvent); +} + +const SvxMacro& SwDoc::GetGlobalMacro( USHORT nEvent ) const +{ + ASSERT(pMacroTable->IsKeyValid(nEvent), "Get fuer nicht ex. Macro"); + return *(pMacroTable->Get(nEvent)); +} + +void SwDoc::SetGlobalMacro( USHORT nEvent, const SvxMacro& rMacro ) +{ + SvxMacro *pMacro; + SetModified(); + if ( 0 != (pMacro=pMacroTable->Get(nEvent)) ) + { + delete pMacro; + pMacroTable->Replace(nEvent, new SvxMacro(rMacro)); + return; + } + pMacroTable->Insert(nEvent, new SvxMacro(rMacro)); +} + +BOOL SwDoc::DelGlobalMacro(USHORT nEvent) +{ + SetModified(); + SvxMacro *pMacro = pMacroTable->Remove(nEvent); + delete pMacro; + return (pMacro != 0); +} + +/************************************************************************* + * void SetDocStat( const SwDocStat& rStat ); + *************************************************************************/ + +void SwDoc::SetDocStat( const SwDocStat& rStat ) +{ + *pDocStat = rStat; +} + +/************************************************************************* + * void UpdateDocStat( const SwDocStat& rStat ); + *************************************************************************/ + +void SwDoc::UpdateDocStat( SwDocStat& rStat, USHORT nNumPages ) +{ + if( rStat.bModified ) + { + const String& rWordDelim = SW_MOD()->GetDocStatWordDelim(); + + rStat.Reset(); + rStat.nPara = 0; // Default ist auf 1 !! + SwNode* pNd; + + for( ULONG n = GetNodes().Count(); n; ) + switch( ( pNd = GetNodes()[ --n ])->GetNodeType() ) + { + case ND_TEXTNODE: + { + const String& rStr = ((SwTxtNode*)pNd)->GetTxt(); + if( rStr.Len() ) + { + int bInWord = FALSE; + USHORT nSpChar = 0; + for( xub_StrLen l = 0; l < rStr.Len(); ++l ) + { + sal_Unicode b = rStr.GetChar( l ); + switch( b ) + { + case CH_TXTATR_BREAKWORD: + ++nSpChar; + if( bInWord ) + { + ++rStat.nWord; + bInWord = FALSE; + } + break; + + case CH_TXTATR_INWORD: + ++nSpChar; + break; + + case 0x0A: + ++nSpChar; + if( bInWord ) + { + ++rStat.nWord; + bInWord = FALSE; + } + break; + + default: + if( STRING_NOTFOUND == rWordDelim.Search( b )) + bInWord = TRUE; + else if( bInWord ) + { + ++rStat.nWord; + bInWord = FALSE; + } + } + } + if( bInWord ) + ++rStat.nWord; + rStat.nChar += rStr.Len() - nSpChar; + } + ++rStat.nPara; + } + break; + + case ND_TABLENODE: ++rStat.nTbl; break; + case ND_GRFNODE: ++rStat.nGrf; break; + case ND_OLENODE: ++rStat.nOLE; break; + case ND_SECTIONNODE: break; + } + + rStat.nPage = nNumPages; + rStat.bModified = FALSE; + SetDocStat( rStat ); + // event. Stat. Felder Updaten + SwFieldType *pType = GetSysFldType(RES_DOCSTATFLD); + pType->UpdateFlds(); + } +} + +// Dokument - Info + +void SwDoc::DocInfoChgd( const SfxDocumentInfo& rInfo ) +{ + delete pSwgInfo; + pSwgInfo = new SfxDocumentInfo(rInfo); + + GetSysFldType( RES_DOCINFOFLD )->UpdateFlds(); + GetSysFldType( RES_TEMPLNAMEFLD )->UpdateFlds(); + SetModified(); +} + + // returne zum Namen die im Doc gesetzte Referenz +const SwFmtRefMark* SwDoc::GetRefMark( const String& rName ) const +{ + const SfxPoolItem* pItem; + USHORT nMaxItems = GetAttrPool().GetItemCount( RES_TXTATR_REFMARK ); + for( USHORT n = 0; n < nMaxItems; ++n ) + { + if( 0 == (pItem = GetAttrPool().GetItem( RES_TXTATR_REFMARK, n ) )) + continue; + + const SwFmtRefMark* pFmtRef = (SwFmtRefMark*)pItem; + const SwTxtRefMark* pTxtRef = pFmtRef->GetTxtRefMark(); + if( pTxtRef && &pTxtRef->GetTxtNode().GetNodes() == &GetNodes() && + rName.Equals( pFmtRef->GetRefName() ) ) + return pFmtRef; + } + return 0; +} + + // returne die RefMark per Index - fuer Uno +const SwFmtRefMark* SwDoc::GetRefMark( USHORT nIndex ) const +{ + const SfxPoolItem* pItem; + const SwTxtRefMark* pTxtRef; + const SwFmtRefMark* pRet = 0; + + USHORT nMaxItems = GetAttrPool().GetItemCount( RES_TXTATR_REFMARK ); + USHORT nCount = 0; + for( USHORT n = 0; n < nMaxItems; ++n ) + if( 0 != (pItem = GetAttrPool().GetItem( RES_TXTATR_REFMARK, n )) && + 0 != (pTxtRef = ((SwFmtRefMark*)pItem)->GetTxtRefMark()) && + &pTxtRef->GetTxtNode().GetNodes() == &GetNodes() ) + { + if(nCount == nIndex) + { + pRet = (SwFmtRefMark*)pItem; + break; + } + nCount++; + } + return pRet; +} + + // returne die Namen aller im Doc gesetzten Referenzen + //JP 24.06.96: Ist der ArrayPointer 0 dann returne nur, ob im Doc. eine + // RefMark gesetzt ist + // OS 25.06.96: ab jetzt wird immer die Anzahl der Referenzen returnt +USHORT SwDoc::GetRefMarks( SvStringsDtor* pNames ) const +{ + const SfxPoolItem* pItem; + const SwTxtRefMark* pTxtRef; + + USHORT nMaxItems = GetAttrPool().GetItemCount( RES_TXTATR_REFMARK ); + USHORT nCount = 0; + for( USHORT n = 0; n < nMaxItems; ++n ) + if( 0 != (pItem = GetAttrPool().GetItem( RES_TXTATR_REFMARK, n )) && + 0 != (pTxtRef = ((SwFmtRefMark*)pItem)->GetTxtRefMark()) && + &pTxtRef->GetTxtNode().GetNodes() == &GetNodes() ) + { + if( pNames ) + { + String* pTmp = new String( ((SwFmtRefMark*)pItem)->GetRefName() ); + pNames->Insert( pTmp, nCount ); + } + nCount ++; + } + + return nCount; +} + +void SwDoc::SetModified() +{ + // dem Link wird der Status returnt, wie die Flags waren und werden + // Bit 0: -> alter Zustand + // Bit 1: -> neuer Zustand + long nCall = bModified ? 3 : 2; + bModified = TRUE; + pDocStat->bModified = TRUE; + if( aOle2Link.IsSet() ) + { + bInCallModified = TRUE; + aOle2Link.Call( (void*)nCall ); + bInCallModified = FALSE; + } + + if( pACEWord && !pACEWord->IsDeleted() ) + delete pACEWord, pACEWord = 0; +} + +void SwDoc::ResetModified() +{ + // dem Link wird der Status returnt, wie die Flags waren und werden + // Bit 0: -> alter Zustand + // Bit 1: -> neuer Zustand + long nCall = bModified ? 1 : 0; + bModified = FALSE; + nUndoSavePos = nUndoPos; + if( nCall && aOle2Link.IsSet() ) + { + bInCallModified = TRUE; + aOle2Link.Call( (void*)nCall ); + bInCallModified = FALSE; + } +} + + +void SwDoc::ReRead( SwPaM& rPam, const String& rGrfName, + const String& rFltName, const Graphic* pGraphic ) +{ + SwGrfNode *pGrfNd; + if( ( !rPam.HasMark() + || rPam.GetPoint()->nNode.GetIndex() == rPam.GetMark()->nNode.GetIndex() ) + && 0 != ( pGrfNd = rPam.GetPoint()->nNode.GetNode().GetGrfNode() ) ) + { + if( DoesUndo() ) + { + ClearRedo(); + AppendUndo( new SwUndoReRead( rPam, *pGrfNd ) ); + } + + // Weil nicht bekannt ist, ob sich die Grafik spiegeln laesst, + // immer das SpiegelungsAttribut zuruecksetzen + if( RES_DONT_MIRROR_GRF != pGrfNd->GetSwAttrSet(). + GetMirrorGrf().GetValue() ) + pGrfNd->SetAttr( SwMirrorGrf() ); + + pGrfNd->ReRead( rGrfName, rFltName, pGraphic, TRUE ); + SetModified(); + } +} + + // wird der Parent geloescht, dann loeschen wir uns selbst +void _GrfToOleUndo::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew ) +{ + if( !pOld ) + pOld = pNew; + if( pOld && RES_OBJECTDYING == pOld->Which() && + ((SwPtrMsgPoolItem *)pOld)->pObject == (void*)GetRegisteredIn() ) + { + delete pSaveObj; + delete this; + } +} + +BOOL lcl_SpellAgain( const SwNodePtr& rpNd, void* pArgs ) +{ + SwTxtNode *pTxtNode = (SwTxtNode*)rpNd->GetTxtNode(); + BOOL bOnlyWrong = *(BOOL*)pArgs; + if( pTxtNode ) + { + if( bOnlyWrong ) + { + if( pTxtNode->GetWrong() && + pTxtNode->GetWrong()->InvalidateWrong() ) + pTxtNode->SetWrongDirty( TRUE ); + } + else + { + pTxtNode->SetWrongDirty( TRUE ); + if( pTxtNode->GetWrong() ) + pTxtNode->GetWrong()->SetInvalid( 0, STRING_LEN ); + } + } + return TRUE; +} + +/************************************************************************* + * SwDoc::SpellItAgainSam( BOOL bInvalid, BOOL bOnlyWrong ) + * + * stoesst das Spelling im Idle-Handler wieder an. + * Wird bInvalid als TRUE uebergeben, so werden zusaetzlich die WrongListen + * an allen Nodes invalidiert und auf allen Seiten das SpellInvalid-Flag + * gesetzt. + * Mit bOnlyWrong kann man dann steuern, ob nur die Bereiche mit falschen + * Woertern oder die kompletten Bereiche neu ueberprueft werden muessen. + ************************************************************************/ + +void SwDoc::SpellItAgainSam( BOOL bInvalid, BOOL bOnlyWrong ) +{ + ASSERT( GetRootFrm(), "SpellAgain: Where's my RootFrm?" ); + if( bInvalid ) + { + SwPageFrm *pPage = (SwPageFrm*)GetRootFrm()->Lower(); + while ( pPage ) + { + pPage->InvalidateSpelling(); + pPage = (SwPageFrm*)pPage->GetNext(); + } + GetNodes().ForEach( lcl_SpellAgain, &bOnlyWrong ); + } + GetRootFrm()->SetIdleFlags(); +} + +void SwDoc::InvalidateAutoCompleteFlag() +{ + if( GetRootFrm() ) + { + SwPageFrm *pPage = (SwPageFrm*)GetRootFrm()->Lower(); + while ( pPage ) + { + pPage->InvalidateAutoCompleteWords(); + pPage = (SwPageFrm*)pPage->GetNext(); + } + for( ULONG nNd = 1, nCnt = GetNodes().Count(); nNd < nCnt; ++nNd ) + GetNodes()[ nNd ]->SetAutoCompleteWordDirty( TRUE ); + GetRootFrm()->SetIdleFlags(); + } +} + +const SwFmtINetFmt* SwDoc::FindINetAttr( const String& rName ) const +{ + const SwFmtINetFmt* pItem; + const SwTxtINetFmt* pTxtAttr; + const SwTxtNode* pTxtNd; + USHORT n, nMaxItems = GetAttrPool().GetItemCount( RES_TXTATR_INETFMT ); + for( n = 0; n < nMaxItems; ++n ) + if( 0 != (pItem = (SwFmtINetFmt*)GetAttrPool().GetItem( + RES_TXTATR_INETFMT, n ) ) && + pItem->GetName().Equals( rName ) && + 0 != ( pTxtAttr = pItem->GetTxtINetFmt()) && + 0 != ( pTxtNd = pTxtAttr->GetpTxtNode() ) && + &pTxtNd->GetNodes() == &GetNodes() ) + { + return pItem; + } + + return 0; +} + +void SwDoc::Summary( SwDoc* pExtDoc, BYTE nLevel, BYTE nPara, BOOL bImpress ) +{ + const SwOutlineNodes& rOutNds = GetNodes().GetOutLineNds(); + if( pExtDoc && rOutNds.Count() ) + { + USHORT i; + ::StartProgress( STR_STATSTR_SUMMARY, 0, rOutNds.Count(), GetDocShell() ); + SwNodeIndex aEndOfDoc( pExtDoc->GetNodes().GetEndOfContent(), -1 ); + for( i = 0; i < rOutNds.Count(); ++i ) + { + ::SetProgressState( i, GetDocShell() ); + ULONG nIndex = rOutNds[ i ]->GetIndex(); + BYTE nLvl = ((SwTxtNode*)GetNodes()[ nIndex ])->GetTxtColl() + ->GetOutlineLevel(); + if( nLvl > nLevel ) + continue; + USHORT nEndOfs = 1; + BYTE nWish = nPara; + ULONG nNextOutNd = i + 1 < rOutNds.Count() ? + rOutNds[ i + 1 ]->GetIndex() : GetNodes().Count(); + BOOL bKeep = FALSE; + while( ( nWish || bKeep ) && nIndex + nEndOfs < nNextOutNd && + GetNodes()[ nIndex + nEndOfs ]->IsTxtNode() ) + { + SwTxtNode* pTxtNode = (SwTxtNode*)GetNodes()[ nIndex+nEndOfs ]; + if( pTxtNode->GetTxt().Len() && nWish ) + --nWish; + bKeep = pTxtNode->GetSwAttrSet().GetKeep().GetValue(); + ++nEndOfs; + } + + SwNodeRange aRange( *rOutNds[ i ], 0, *rOutNds[ i ], nEndOfs ); + GetNodes()._Copy( aRange, aEndOfDoc ); + } + const SwTxtFmtColls *pColl = pExtDoc->GetTxtFmtColls(); + for( i = 0; i < pColl->Count(); ++i ) + (*pColl)[ i ]->ResetAttr( RES_PAGEDESC, RES_BREAK ); + SwNodeIndex aIndx( pExtDoc->GetNodes().GetEndOfExtras() ); + ++aEndOfDoc; + while( aIndx < aEndOfDoc ) + { + SwNode *pNode; + BOOL bDelete = FALSE; + if( (pNode = &aIndx.GetNode())->IsTxtNode() ) + { + SwTxtNode *pNd = (SwTxtNode*)pNode; + if( pNd->HasSwAttrSet() ) + pNd->ResetAttr( RES_PAGEDESC, RES_BREAK ); + if( bImpress ) + { + SwTxtFmtColl* pColl = pNd->GetTxtColl(); + USHORT nHeadLine = pColl->GetOutlineLevel()==NO_NUMBERING ? + RES_POOLCOLL_HEADLINE2 : RES_POOLCOLL_HEADLINE1; + pColl = pExtDoc->GetTxtCollFromPool( nHeadLine ); + pNd->ChgFmtColl( pColl ); + } + if( !pNd->Len() && + pNd->StartOfSectionIndex()+2 < pNd->EndOfSectionIndex() ) + { + bDelete = TRUE; + pExtDoc->GetNodes().Delete( aIndx ); + } + } + if( !bDelete ) + ++aIndx; + } + ::EndProgress( GetDocShell() ); + } +} + + // loesche den nicht sichtbaren Content aus dem Document, wie z.B.: + // versteckte Bereiche, versteckte Absaetze +BOOL SwDoc::RemoveInvisibleContent() +{ + BOOL bRet = FALSE; + StartUndo( UIUNDO_DELETE_INVISIBLECNTNT ); + + { + SwTxtNode* pTxtNd; + SwClientIter aIter( *GetSysFldType( RES_HIDDENPARAFLD ) ); + for( SwFmtFld* pFmtFld = (SwFmtFld*)aIter.First( TYPE( SwFmtFld )); + pFmtFld; pFmtFld = (SwFmtFld*)aIter.Next() ) + if( pFmtFld->GetTxtFld() && + 0 != ( pTxtNd = (SwTxtNode*)pFmtFld->GetTxtFld()->GetpTxtNode() ) && + pTxtNd->GetpSwpHints() && !pTxtNd->GetpSwpHints()->IsVisible() && + &pTxtNd->GetNodes() == &GetNodes() ) + { + bRet = TRUE; + // ein versteckter Absatz -> entfernen oder Inhalt loeschen? + SwPaM aPam( *pTxtNd, 0, *pTxtNd, pTxtNd->GetTxt().Len() ); + + if( 2 != pTxtNd->EndOfSectionIndex() - + pTxtNd->StartOfSectionIndex() ) + { + aPam.DeleteMark(); + DelFullPara( aPam ); + } + else + Delete( aPam ); + } + } + + { + // dann noch alle versteckten Bereiche loeschen/leeren + SwSectionFmts aSectFmts; + SwSectionFmts& rSectFmts = GetSections(); + for( USHORT n = rSectFmts.Count(); n; ) + { + SwSectionFmt* pSectFmt = rSectFmts[ --n ]; + SwSection* pSect = pSectFmt->GetSection(); + if( pSect->CalcHiddenFlag() ) + { + SwSection* pParent = pSect, *pTmp; + while( 0 != (pTmp = pParent->GetParent() )) + { + if( pTmp->IsHiddenFlag() ) + pSect = pTmp; + pParent = pTmp; + } + + if( USHRT_MAX == aSectFmts.GetPos( pSect->GetFmt() ) ) + aSectFmts.Insert( pSect->GetFmt(), 0 ); + } + if( pSect->GetCondition().Len() ) + { + SwSection aSect( pSect->GetType(), pSect->GetName() ); + aSect = *pSect; + aSect.SetCondition( aEmptyStr ); + aSect.SetHidden( FALSE ); + ChgSection( n, aSect ); + } + } + + if( 0 != ( n = aSectFmts.Count() )) + { + while( n ) + { + SwSectionFmt* pSectFmt = aSectFmts[ --n ]; + SwSectionNode* pSectNd = pSectFmt->GetSectionNode(); + if( pSectNd ) + { + bRet = TRUE; + SwPaM aPam( *pSectNd ); + + if( pSectNd->FindStartNode()->StartOfSectionIndex() == + pSectNd->GetIndex() - 1 && + pSectNd->FindStartNode()->EndOfSectionIndex() == + pSectNd->EndOfSectionIndex() + 1 ) + { + // nur den Inhalt loeschen + SwCntntNode* pCNd = GetNodes().GoNext( + &aPam.GetPoint()->nNode ); + aPam.GetPoint()->nContent.Assign( pCNd, 0 ); + aPam.SetMark(); + aPam.GetPoint()->nNode = *pSectNd->EndOfSectionNode(); + pCNd = GetNodes().GoPrevious( + &aPam.GetPoint()->nNode ); + aPam.GetPoint()->nContent.Assign( pCNd, pCNd->Len() ); + + Delete( aPam ); + } + else + { + // die gesamte Section loeschen + aPam.SetMark(); + aPam.GetPoint()->nNode = *pSectNd->EndOfSectionNode(); + DelFullPara( aPam ); + } + + } + } + aSectFmts.Remove( 0, aSectFmts.Count() ); + } + } + + if( bRet ) + SetModified(); + EndUndo( UIUNDO_DELETE_INVISIBLECNTNT ); + return bRet; +} + +struct ImplCastStruct : public SvAdviseSink +{ + void CallClose() { Closed(); } +}; + + // embedded alle lokalen Links (Bereiche/Grafiken) +BOOL SwDoc::EmbedAllLinks() +{ + BOOL bRet = FALSE; + SvxLinkManager& rLnkMgr = GetLinkManager(); + const SvBaseLinks& rLnks = rLnkMgr.GetLinks(); + if( rLnks.Count() ) + { + BOOL bDoesUndo = DoesUndo(); + DoUndo( FALSE ); + + for( USHORT n = 0; n < rLnks.Count(); ++n ) + { + SvBaseLink* pLnk = &(*rLnks[ n ]); + if( pLnk && + ( OBJECT_CLIENT_GRF == pLnk->GetObjType() || + OBJECT_CLIENT_FILE == pLnk->GetObjType() ) && + pLnk->ISA( SwBaseLink ) ) + { + SvBaseLinkRef xLink = pLnk; + USHORT nCount = rLnks.Count(); + + String sFName; + rLnkMgr.GetDisplayNames( *xLink, 0, &sFName, 0, 0 ); + + INetURLObject aURL( sFName ); + if( INET_PROT_FILE == aURL.GetProtocol() || + INET_PROT_CID == aURL.GetProtocol() ) + { + // dem Link sagen, das er aufgeloest wird! + ((ImplCastStruct*)&xLink)->CallClose(); + + // falls einer vergessen hat sich auszutragen + if( xLink.Is() ) + rLnkMgr.Remove( *xLink ); + + if( nCount != rLnks.Count() + 1 ) + n = 0; // wieder von vorne anfangen, es wurden + // mehrere Links entfernt + bRet = TRUE; + } + } + } + + DelAllUndoObj(); + DoUndo( bDoesUndo ); + SetModified(); + } + return bRet; +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +BOOL SwDoc::IsInsTblFormatNum() const +{ + return SW_MOD()->IsInsTblFormatNum(IsHTMLMode()); +} + +BOOL SwDoc::IsInsTblChangeNumFormat() const +{ + return SW_MOD()->IsInsTblChangeNumFormat(IsHTMLMode()); +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +BOOL SwDoc::IsInsTblAlignNum() const +{ + return SW_MOD()->IsInsTblAlignNum(IsHTMLMode()); +} + + +USHORT SwDoc::GetLinkUpdMode() const +{ + USHORT nRet = nLinkUpdMode; + if( GLOBALSETTING == nRet ) + nRet = SW_MOD()->GetLinkUpdMode(IsHTMLMode()); + return nRet; +} + +USHORT SwDoc::GetFldUpdateFlags() const +{ + USHORT nRet = nFldUpdMode; + if( AUTOUPD_GLOBALSETTING == nRet ) + nRet = SW_MOD()->GetFldUpdateFlags(IsHTMLMode()); + return nRet; +} + + + diff --git a/sw/source/core/doc/docbasic.cxx b/sw/source/core/doc/docbasic.cxx new file mode 100644 index 000000000000..f7e22600613f --- /dev/null +++ b/sw/source/core/doc/docbasic.cxx @@ -0,0 +1,314 @@ +/************************************************************************* + * + * $RCSfile: docbasic.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:15 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _HINTIDS_HXX +#include +#endif + +#ifndef _RTL_USTRING_HXX //autogen +#include +#endif +#ifndef _IMAP_HXX //autogen +#include +#endif +#ifndef _GOODIES_IMAPOBJ_HXX +#include +#endif +#ifndef _SBXCLASS_HXX +#include +#endif +#ifndef _SBXCORE_HXX +#include +#endif +#ifndef __SBX_SBXVALUE +#include +#endif +#ifndef _SFXINIMGR_HXX +#include +#endif +#ifndef _SVCONFIG_HXX +#include +#endif +#ifndef _OFF_APP_HXX //autogen +#include +#endif + +#ifndef _FRMFMT_HXX //autogen +#include +#endif +#ifndef _FMTINFMT_HXX //autogen +#include +#endif +#ifndef _FMTURL_HXX //autogen +#include +#endif +#ifndef _FRMATR_HXX +#include +#endif +#ifndef _DOCARY_HXX +#include +#endif +#ifndef _DOC_HXX +#include +#endif +#ifndef _DOCSH_HXX +#include +#endif +#ifndef _SWEVENT_HXX +#include +#endif + +using namespace ::com::sun::star::uno; +using namespace ::rtl; + +Sequence *lcl_docbasic_convertArgs( SbxArray& rArgs ) +{ + Sequence *pRet = 0; + +#if 0 + switch( nEvent ) + { + case SW_EVENT_FRM_KEYINPUT_ALPHA: + case SW_EVENT_FRM_KEYINPUT_NOALPHA: + case SW_EVENT_FRM_MOVE: + case SW_EVENT_FRM_RESIZE: + } +#endif + + USHORT nCount = rArgs.Count(); + if( nCount > 1 ) + { + nCount--; + pRet = new Sequence( nCount ); + Any *pUnoArgs = pRet->getArray(); + for( USHORT i=0; iGetType() ) + { + case SbxSTRING: + pUnoArgs[i] <<= OUString( pVar->GetString() ); + break; + case SbxCHAR: + pUnoArgs[i] <<= (sal_Int16)pVar->GetChar() ; + break; + case SbxUSHORT: + pUnoArgs[i] <<= (sal_Int16)pVar->GetUShort(); + break; + case SbxLONG: + pUnoArgs[i] <<= (sal_Int32)pVar->GetLong(); + break; + default: + pUnoArgs[i].setValue(0, ::getVoidCppuType()); + break; + } + } + } + + return pRet; +} + +BOOL SwDoc::ExecMacro( const SvxMacro& rMacro, String* pRet, SbxArray* pArgs ) +{ + ErrCode eErr = 0; + switch( rMacro.GetScriptType() ) + { + case STARBASIC: + { + SbxBaseRef aRef; + SbxValue* pRetValue = new SbxValue; + aRef = pRetValue; + eErr = pDocShell->CallBasic( rMacro.GetMacName(), + rMacro.GetLibName(), + 0, pArgs, pRet ? pRetValue : 0 ); + + if( pRet && SbxNULL < pRetValue->GetType() && + SbxVOID != pRetValue->GetType() ) + // gueltiger Wert, also setzen + *pRet = pRetValue->GetString(); + } + break; + case JAVASCRIPT: + // ignore JavaScript calls + break; + case EXTENDED_STYPE: + { + Sequence *pUnoArgs = 0; + Reference xThis; + if( pArgs ) + pUnoArgs = lcl_docbasic_convertArgs( *pArgs ); + eErr = pDocShell->CallScript( rMacro.GetLanguage(), + rMacro.GetMacName(), + xThis, + pUnoArgs ); + delete pUnoArgs; + } + break; + } + + return 0 == eErr; +} + + + +USHORT SwDoc::CallEvent( USHORT nEvent, const SwCallMouseEvent& rCallEvent, + BOOL bCheckPtr, SbxArray* pArgs, const Link* pCallBack ) +{ + if( !pDocShell ) // ohne DocShell geht das nicht! + return 0; + + USHORT nRet = 0; + const SvxMacroTableDtor* pTbl = 0; + switch( rCallEvent.eType ) + { + case EVENT_OBJECT_INETATTR: + if( bCheckPtr ) + { + const SfxPoolItem* pItem; + USHORT n, nMaxItems = GetAttrPool().GetItemCount( RES_TXTATR_INETFMT ); + for( n = 0; n < nMaxItems; ++n ) + if( 0 != (pItem = GetAttrPool().GetItem( RES_TXTATR_INETFMT, n ) ) + && rCallEvent.PTR.pINetAttr == pItem ) + { + bCheckPtr = FALSE; // als Flag missbrauchen + break; + } + } + if( !bCheckPtr ) + pTbl = rCallEvent.PTR.pINetAttr->GetMacroTbl(); + break; + + case EVENT_OBJECT_URLITEM: + case EVENT_OBJECT_IMAGE: + { + const SwFrmFmtPtr pFmt = (SwFrmFmtPtr)rCallEvent.PTR.pFmt; + if( bCheckPtr ) + { + USHORT nPos = GetSpzFrmFmts()->GetPos( pFmt ); + if( USHRT_MAX != nPos ) + bCheckPtr = FALSE; // als Flag missbrauchen + } + if( !bCheckPtr ) + pTbl = &pFmt->GetMacro().GetMacroTable(); + } + break; + + case EVENT_OBJECT_IMAGEMAP: + { + const IMapObject* pIMapObj = rCallEvent.PTR.IMAP.pIMapObj; + if( bCheckPtr ) + { + const SwFrmFmtPtr pFmt = (SwFrmFmtPtr)rCallEvent.PTR.IMAP.pFmt; + USHORT nPos = GetSpzFrmFmts()->GetPos( pFmt ); + const ImageMap* pIMap; + if( USHRT_MAX != nPos && + 0 != (pIMap = pFmt->GetURL().GetMap()) ) + { + for( nPos = pIMap->GetIMapObjectCount(); nPos; ) + if( pIMapObj == pIMap->GetIMapObject( --nPos )) + { + bCheckPtr = FALSE; // als Flag missbrauchen + break; + } + } + } + if( !bCheckPtr ) + pTbl = &pIMapObj->GetMacroTable(); + } + break; + } + + if( pTbl ) + { + nRet = 0x1; + if( pTbl->IsKeyValid( nEvent ) ) + { + const SvxMacro& rMacro = *pTbl->Get( nEvent ); + if( STARBASIC == rMacro.GetScriptType() ) + { + nRet += 0 == pDocShell->CallBasic( rMacro.GetMacName(), + rMacro.GetLibName(), 0, pArgs ) ? 1 : 0; + } + else if( EXTENDED_STYPE == rMacro.GetScriptType() ) + { + Sequence *pUnoArgs = 0; + Reference xThis; + if( pArgs ) + pUnoArgs = lcl_docbasic_convertArgs( *pArgs ); + nRet += 0 == pDocShell->CallScript( rMacro.GetLanguage(), + rMacro.GetMacName(), xThis, pUnoArgs ); + delete pUnoArgs; + } + // JavaScript calls are ignored + } + } + return nRet; +} + + + + diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx new file mode 100644 index 000000000000..ae698be77ae5 --- /dev/null +++ b/sw/source/core/doc/docbm.cxx @@ -0,0 +1,1114 @@ +/************************************************************************* + * + * $RCSfile: docbm.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:15 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#include +#ifndef _SVXLINKMGR_HXX +#include +#endif + +#ifndef _FMTANCHR_HXX //autogen +#include +#endif +#ifndef _FRMFMT_HXX //autogen +#include +#endif +#ifndef _NODE_HXX //autogen +#include +#endif +#ifndef _DOC_HXX +#include +#endif +#ifndef _ERRHDL_HXX +#include +#endif +#ifndef _CNTFRM_HXX +#include +#endif +#ifndef _DCONTACT_HXX +#include +#endif +#ifndef _BOOKMRK_HXX +#include +#endif +#ifndef _UNDOBJ_HXX +#include +#endif +#ifndef _PAM_HXX +#include +#endif +#ifndef _MVSAVE_HXX +#include +#endif +#ifndef _SWSERV_HXX +#include +#endif +#ifndef _REDLINE_HXX +#include +#endif +#ifndef _DOCARY_HXX +#include +#endif +#ifndef _EDITSH_HXX +#include +#endif +#ifndef _UNOCRSR_HXX +#include +#endif +#ifndef _VISCRS_HXX +#include +#endif + + +SV_IMPL_OP_PTRARR_SORT(SwBookmarks, SwBookmarkPtr) +SO2_IMPL_REF( SwServerObject ) + +#define PCURCRSR (_pCurrCrsr) +#define FOREACHPAM_START(pSttCrsr) \ + {\ + SwPaM *_pStartCrsr = pSttCrsr, *_pCurrCrsr = pSttCrsr; \ + do { + +#define FOREACHPAM_END() \ + } while( (_pCurrCrsr=(SwPaM *)_pCurrCrsr->GetNext()) != _pStartCrsr ); \ + } +#define PCURSH ((SwCrsrShell*)_pStartShell) +#define FOREACHSHELL_START( pEShell ) \ + {\ + register ViewShell *_pStartShell = pEShell; \ + do { \ + if( _pStartShell->IsA( TYPE( SwCrsrShell )) ) \ + { + +#define FOREACHSHELL_END( pEShell ) \ + } \ + } while((_pStartShell=(ViewShell*)_pStartShell->GetNext())!= pEShell ); \ + } + + +SwBookmark* SwDoc::MakeBookmark( const SwPaM& rPaM, const KeyCode& rCode, + const String& rName, const String& rShortName, + BOOKMARK_TYPE eMark ) +{ + SwBookmark *pBM; + if( MARK == eMark ) + pBM = new SwMark( *rPaM.GetPoint(), rCode, rName, rShortName ); + else if( BOOKMARK == eMark ) + { + pBM = new SwBookmark(*rPaM.GetPoint(), rCode, rName, rShortName); + if( rPaM.HasMark() ) + pBM->pPos2 = new SwPosition( *rPaM.GetMark() ); + } + else + { + pBM = new SwUNOMark(*rPaM.GetPoint(), rCode, rName, rShortName); + if( rPaM.HasMark() ) + pBM->pPos2 = new SwPosition( *rPaM.GetMark() ); + } + + if( !pBookmarkTbl->Insert( pBM ) ) + delete pBM, pBM = 0; + else + { + if( BOOKMARK == eMark && DoesUndo() ) + { + ClearRedo(); + AppendUndo( new SwUndoInsBookmark( *pBM )); + } + if(UNO_BOOKMARK != eMark) + SetModified(); + } + return pBM; +} + +void SwDoc::DelBookmark(USHORT nPos) +{ + SwBookmark *pBM = (*pBookmarkTbl)[nPos]; + if( DoesUndo() && !pBM->IsUNOMark()) + { + ClearRedo(); + AppendUndo( new SwUndoDelBookmark( *pBM )); + } + SetModified(); + pBookmarkTbl->Remove(nPos); + + SwServerObject* pServObj = pBM->GetObject(); + if( pServObj ) // dann aus der Liste entfernen + GetLinkManager().RemoveServer( pServObj ); + + delete pBM; +} + +void SwDoc::DelBookmark( const String& rName ) +{ + USHORT nFnd = FindBookmark( rName ); + if( USHRT_MAX != nFnd ) + DelBookmark( nFnd ); +} + +USHORT SwDoc::FindBookmark( const String& rName ) +{ + ASSERT( rName.Len(), "wo ist der Name?" ); + for( USHORT n = pBookmarkTbl->Count(); n ; ) + if( rName.Equals( (*pBookmarkTbl)[ --n ]->GetName() ) ) + return n; + return USHRT_MAX; +} + +// Zur Vereinfachung gibt es auch den direkten Zugriff +// auf die "echten" Bookmarks + +USHORT SwDoc::GetBookmarkCnt(BOOL bBkmrk) const +{ + USHORT nRet = pBookmarkTbl->Count(); + if(bBkmrk) + { + for( USHORT i = nRet; i; --i ) + { + if(!(*pBookmarkTbl)[i - 1]->IsBookMark()) + nRet--; + } + } + return nRet; +} + + +SwBookmark& SwDoc::GetBookmark(USHORT nPos, BOOL bBkmrk) +{ + if( bBkmrk ) + { + USHORT nCount = pBookmarkTbl->Count(); + USHORT i = 0; + do { + if(!(*pBookmarkTbl)[i]->IsBookMark()) + nPos++; + + i++; + } + while( i < nPos || !(*pBookmarkTbl)[nPos]->IsBookMark() ); + } + return *(*pBookmarkTbl)[nPos]; +} + + + // erzeugt einen eindeutigen Namen. Der Name selbst muss vorgegeben + // werden, es wird dann bei gleichen Namen nur durchnumeriert. +void SwDoc::MakeUniqueBookmarkName( String& rNm ) +{ + ASSERT( rNm.Len(), "es sollte ein Name vorgegeben werden!" ); + + // wir erzeugen uns eine temp. Bookmark + String sTmp; + USHORT nCnt = 0, n; + USHORT nBookCnt = pBookmarkTbl->Count(); + do { + sTmp = rNm; + sTmp += String::CreateFromInt32( ++nCnt ); + for( n = 0; n < nBookCnt; ++n ) + if( (*pBookmarkTbl)[ n ]->GetName().Equals( sTmp )) + break; + } while( n < nBookCnt ); + rNm = sTmp; +} + +/* */ + +SaveBookmark::SaveBookmark( int eType, const SwBookmark& rBkmk, + const SwNodeIndex & rMvPos, + const SwIndex* pIdx ) + : aName( rBkmk.GetName() ), aShortName( rBkmk.GetShortName() ), + aCode( rBkmk.GetKeyCode() ), eBkmkType( (SaveBookmarkType)eType ) +{ + nNode1 = rBkmk.GetPos().nNode.GetIndex(); + nCntnt1 = rBkmk.GetPos().nContent.GetIndex(); + + if( BKMK_POS & eBkmkType ) + { + nNode1 -= rMvPos.GetIndex(); + if( pIdx && !nNode1 ) + nCntnt1 -= pIdx->GetIndex(); + } + + if( rBkmk.GetOtherPos() ) + { + nNode2 = rBkmk.GetOtherPos()->nNode.GetIndex(); + nCntnt2 = rBkmk.GetOtherPos()->nContent.GetIndex(); + + if( BKMK_POS_OTHER & eBkmkType ) + { + nNode2 -= rMvPos.GetIndex(); + if( pIdx && !nNode2 ) + nCntnt2 -= pIdx->GetIndex(); + } + } + else + nNode2 = ULONG_MAX, nCntnt2 = STRING_NOTFOUND; +} + +void SaveBookmark::SetInDoc( SwDoc* pDoc, const SwNodeIndex& rNewPos, + const SwIndex* pIdx ) +{ + SwPaM aPam( rNewPos.GetNode() ); + if( pIdx ) + aPam.GetPoint()->nContent = *pIdx; + + if( ULONG_MAX != nNode2 ) + { + aPam.SetMark(); + + if( BKMK_POS_OTHER & eBkmkType ) + { + aPam.GetMark()->nNode += nNode2; + if( pIdx && !nNode2 ) + aPam.GetMark()->nContent += nCntnt2; + else + aPam.GetMark()->nContent.Assign( aPam.GetCntntNode( FALSE ), + nCntnt2 ); + } + else + { + aPam.GetMark()->nNode = nNode2; + aPam.GetMark()->nContent.Assign( aPam.GetCntntNode( FALSE ), + nCntnt2 ); + } + } + + if( BKMK_POS & eBkmkType ) + { + aPam.GetPoint()->nNode += nNode1; + + if( pIdx && !nNode1 ) + aPam.GetPoint()->nContent += nCntnt1; + else + aPam.GetPoint()->nContent.Assign( aPam.GetCntntNode(), nCntnt1 ); + } + else + { + aPam.GetPoint()->nNode = nNode1; + aPam.GetPoint()->nContent.Assign( aPam.GetCntntNode(), nCntnt1 ); + } + + if( !aPam.HasMark() || + CheckNodesRange( aPam.GetPoint()->nNode, aPam.GetMark()->nNode, TRUE )) + pDoc->MakeBookmark( aPam, aCode, aName, aShortName ); +} + + +inline int GreaterThan( const SwPosition& rPos, const SwNodeIndex& rNdIdx, + const SwIndex* pIdx ) +{ + return pIdx ? ( rPos.nNode > rNdIdx || ( rPos.nNode == rNdIdx && + rPos.nContent >= pIdx->GetIndex() )) + : rPos.nNode >= rNdIdx; +} +inline int Lower( const SwPosition& rPos, const SwNodeIndex& rNdIdx, + const SwIndex* pIdx ) +{ + return rPos.nNode < rNdIdx || ( pIdx && rPos.nNode == rNdIdx && + rPos.nContent < pIdx->GetIndex() ); +} +inline int Greater( const SwPosition& rPos, const SwNodeIndex& rNdIdx, + const SwIndex* pIdx ) +{ + return rPos.nNode > rNdIdx || ( pIdx && rPos.nNode == rNdIdx && + rPos.nContent > pIdx->GetIndex() ); +} + +void _DelBookmarks( const SwNodeIndex& rStt, const SwNodeIndex& rEnd, + SaveBookmarks* pSaveBkmk, + const SwIndex* pSttIdx, const SwIndex* pEndIdx ) +{ + // kein gueltiger Bereich ?? + if( rStt.GetIndex() > rEnd.GetIndex() || ( rStt == rEnd && + (!pSttIdx || pSttIdx->GetIndex() >= pEndIdx->GetIndex())) ) + return; + + // kopiere alle Bookmarks, die im Move Bereich stehen in ein + // Array, das alle Angaben auf die Position als Offset speichert. + // Die neue Zuordung erfolgt nach dem Moven. + SwDoc* pDoc = rStt.GetNode().GetDoc(); + const SwBookmarks& rBkmks = pDoc->GetBookmarks(); + for( USHORT nCnt = 0; nCnt < rBkmks.Count(); ++nCnt ) + { + // liegt auf der Position ?? + int eType = BKMK_POS_NONE; + SwBookmark* pBkmk = rBkmks[ nCnt ]; + if( GreaterThan( pBkmk->GetPos(), rStt, pSttIdx ) && + Lower( pBkmk->GetPos(), rEnd, pEndIdx )) + eType = BKMK_POS; + if( pBkmk->GetOtherPos() && + GreaterThan( *pBkmk->GetOtherPos(), rStt, pSttIdx ) && + Lower( *pBkmk->GetOtherPos(), rEnd, pEndIdx )) + eType |= BKMK_POS_OTHER; + + if( BKMK_POS_NONE == eType ) // auf zum naechsten + continue; + + if( pSaveBkmk ) + { + // Besonderheit: komplett eingeschlossen? dann mitnehmen + if( pEndIdx && (BKMK_POS_OTHER | BKMK_POS) != eType && + ( ( BKMK_POS_OTHER & eType && + pBkmk->GetPos().nNode == rEnd && + pBkmk->GetPos().nContent == *pEndIdx ) || + ( BKMK_POS & eType && pBkmk->GetOtherPos() && + pBkmk->GetOtherPos()->nNode == rEnd && + pBkmk->GetOtherPos()->nContent == *pEndIdx ) ) ) + eType = BKMK_POS_OTHER | BKMK_POS; + + SaveBookmark * pSBkmk = new SaveBookmark( eType, *pBkmk, rStt, pSttIdx ); + pSaveBkmk->C40_INSERT( SaveBookmark, pSBkmk, pSaveBkmk->Count() ); + pDoc->DelBookmark( nCnt-- ); + } + else if( (BKMK_POS_OTHER | BKMK_POS ) == eType || + ( BKMK_POS == eType && !pBkmk->GetOtherPos() ) ) + pDoc->DelBookmark( nCnt-- ); + else + { + SwPosition* pPos = (SwPosition*)(BKMK_POS & eType + ? &pBkmk->GetPos() + : pBkmk->GetOtherPos()); + pPos->nNode = rEnd; + if( pEndIdx ) + pPos->nContent = *pEndIdx; + else + { + SwCntntNode* pCNd = pPos->nNode.GetNode().GetCntntNode(); + BOOL bStt = TRUE; + if( !pCNd && 0 == ( pCNd = pDoc->GetNodes().GoNext( &pPos->nNode )) ) + { + bStt = FALSE; + pPos->nNode = rStt; + if( 0 == ( pCNd = pDoc->GetNodes().GoPrevious( &pPos->nNode )) ) + { + pPos->nNode = BKMK_POS == eType + ? pBkmk->GetOtherPos()->nNode + : pBkmk->GetPos().nNode; + pCNd = pPos->nNode.GetNode().GetCntntNode(); + } + } + xub_StrLen nTmp = bStt ? 0 : pCNd->Len(); + pPos->nContent.Assign( pCNd, nTmp ); + } + + // keine ungueltigen Selektionen zulassen! + if( pBkmk->GetOtherPos() && + pBkmk->GetOtherPos()->nNode.GetNode().FindTableBoxStartNode() != + pBkmk->GetPos().nNode.GetNode().FindTableBoxStartNode() ) + { + SwPaM aPam( pPos == pBkmk->GetOtherPos() + ? pBkmk->GetPos() : *pBkmk->GetOtherPos() ); + String sNm( pBkmk->GetName() ), sShortNm( pBkmk->GetShortName() ); + KeyCode aKCode( pBkmk->GetKeyCode() ); + + pDoc->DelBookmark( nCnt-- ); + pDoc->MakeBookmark( aPam, aKCode, sNm, sShortNm, BOOKMARK ); + } + } + } + + // kopiere alle Redlines, die im Move Bereich stehen in ein + // Array, das alle Angaben auf die Position als Offset speichert. + // Die neue Zuordung erfolgt nach dem Moven. + SwRedlineTbl& rTbl = (SwRedlineTbl&)pDoc->GetRedlineTbl(); + for( nCnt = 0; nCnt < rTbl.Count(); ++nCnt ) + { + // liegt auf der Position ?? + int eType = BKMK_POS_NONE; + SwRedline* pRedl = rTbl[ nCnt ]; + + SwPosition *pRStt = &pRedl->GetBound(TRUE), + *pREnd = &pRedl->GetBound(FALSE); + if( *pRStt > *pREnd ) + { + SwPosition *pTmp = pRStt; pRStt = pREnd, pREnd = pTmp; + } + + if( Greater( *pRStt, rStt, pSttIdx ) && Lower( *pRStt, rEnd, pEndIdx )) + { + pRStt->nNode = rEnd; + if( pEndIdx ) + pRStt->nContent = *pEndIdx; + else + { + BOOL bStt = TRUE; + SwCntntNode* pCNd = pRStt->nNode.GetNode().GetCntntNode(); + if( !pCNd && 0 == ( pCNd = pDoc->GetNodes().GoNext( &pRStt->nNode )) ) + { + bStt = FALSE; + pRStt->nNode = rStt; + if( 0 == ( pCNd = pDoc->GetNodes().GoPrevious( &pRStt->nNode )) ) + { + pRStt->nNode = pREnd->nNode; + pCNd = pRStt->nNode.GetNode().GetCntntNode(); + } + } + xub_StrLen nTmp = bStt ? 0 : pCNd->Len(); + pRStt->nContent.Assign( pCNd, nTmp ); + } + } + if( Greater( *pREnd, rStt, pSttIdx ) && Lower( *pREnd, rEnd, pEndIdx )) + { + pREnd->nNode = rStt; + if( pSttIdx ) + pREnd->nContent = *pSttIdx; + else + { + BOOL bStt = FALSE; + SwCntntNode* pCNd = pREnd->nNode.GetNode().GetCntntNode(); + if( !pCNd && 0 == ( pCNd = pDoc->GetNodes().GoPrevious( &pREnd->nNode )) ) + { + bStt = TRUE; + pREnd->nNode = rEnd; + if( 0 == ( pCNd = pDoc->GetNodes().GoNext( &pREnd->nNode )) ) + { + pREnd->nNode = pRStt->nNode; + pCNd = pREnd->nNode.GetNode().GetCntntNode(); + } + } + xub_StrLen nTmp = bStt ? 0 : pCNd->Len(); + pREnd->nContent.Assign( pCNd, nTmp ); + } + } + } +} + +/* */ + + +// Aufbau vom Array: 2 longs, +// 1. Long enthaelt Type und Position im DocArray, +// 2. die ContentPosition +// +// CntntType -- +// 0x8000 = Bookmark Pos1 +// 0x8001 = Bookmark Pos2 +// 0x2000 = Absatzgebundener Rahmen +// 0x2001 = Auto-Absatzgebundener Rahmen, der umgehaengt werden soll +// 0x1000 = Redline Mark +// 0x1001 = Redline Point +// 0x0800 = Crsr aus der CrsrShell Mark +// 0x0801 = Crsr aus der CrsrShell Point +// 0x0400 = UnoCrsr Mark +// 0x0401 = UnoCrsr Point +// + +class _SwSaveTypeCountContent +{ + union { + struct { USHORT nType, nCount; } TC; + ULONG nTypeCount; + } TYPECOUNT; + xub_StrLen nContent; + +public: + _SwSaveTypeCountContent() { TYPECOUNT.nTypeCount = 0; nContent = 0; } + _SwSaveTypeCountContent( USHORT nType ) + { + SetTypeAndCount( nType, 0 ); + nContent = 0; + } + _SwSaveTypeCountContent( const SvULongs& rArr, USHORT& rPos ) + { + TYPECOUNT.nTypeCount = rArr[ rPos++ ]; + nContent = rArr[ rPos++ ]; + } + void Add( SvULongs& rArr ) + { + rArr.Insert( TYPECOUNT.nTypeCount, rArr.Count() ); + rArr.Insert( nContent, rArr.Count() ); + } + + void SetType( USHORT n ) { TYPECOUNT.TC.nType = n; } + USHORT GetType() const { return TYPECOUNT.TC.nType; } + void IncType() { ++TYPECOUNT.TC.nType; } + void DecType() { --TYPECOUNT.TC.nType; } + + void SetCount( USHORT n ) { TYPECOUNT.TC.nCount = n; } + USHORT GetCount() const { return TYPECOUNT.TC.nCount; } + USHORT IncCount() { return ++TYPECOUNT.TC.nCount; } + USHORT DecCount() { return --TYPECOUNT.TC.nCount; } + + void SetTypeAndCount( USHORT nT, USHORT nC ) + { TYPECOUNT.TC.nCount = nC; TYPECOUNT.TC.nType = nT; } + + void SetContent( xub_StrLen n ) { nContent = n; } + xub_StrLen GetContent() const { return nContent; } +}; + + +void _ChkPaM( SvULongs& rSaveArr, ULONG nNode, xub_StrLen nCntnt, + const SwPaM& rPam, _SwSaveTypeCountContent& rSave, + BOOL bChkSelDirection ) +{ + // SelektionsRichtung beachten + BOOL bBound1IsStart = !bChkSelDirection ? TRUE : + ( *rPam.GetPoint() < *rPam.GetMark() + ? rPam.GetPoint() == &rPam.GetBound() + : rPam.GetMark() == &rPam.GetBound()); + + const SwPosition* pPos = &rPam.GetBound( TRUE ); + if( pPos->nNode.GetIndex() == nNode && + ( bBound1IsStart ? pPos->nContent.GetIndex() < nCntnt + : pPos->nContent.GetIndex() <= nCntnt )) + { + rSave.SetContent( pPos->nContent.GetIndex() ); + rSave.Add( rSaveArr ); + } + + pPos = &rPam.GetBound( FALSE ); + if( pPos->nNode.GetIndex() == nNode && + ( (bBound1IsStart && bChkSelDirection) + ? pPos->nContent.GetIndex() <= nCntnt + : pPos->nContent.GetIndex() < nCntnt )) + { + rSave.SetContent( pPos->nContent.GetIndex() ); + rSave.IncType(); + rSave.Add( rSaveArr ); + rSave.DecType(); + } +} + + +void _SaveCntntIdx( SwDoc* pDoc, ULONG nNode, xub_StrLen nCntnt, + SvULongs& rSaveArr, BYTE nSaveFly ) +{ + // 1. Bookmarks + _SwSaveTypeCountContent aSave; + aSave.SetTypeAndCount( 0x8000, 0 ); + + const SwBookmarks& rBkmks = pDoc->GetBookmarks(); + for( ; aSave.GetCount() < rBkmks.Count(); aSave.IncCount() ) + { + const SwBookmark* pBkmk = rBkmks[ aSave.GetCount() ]; + if( pBkmk->GetPos().nNode.GetIndex() == nNode && + pBkmk->GetPos().nContent.GetIndex() < nCntnt ) + { + aSave.SetContent( pBkmk->GetPos().nContent.GetIndex() ); + aSave.Add( rSaveArr ); + } + + if( pBkmk->GetOtherPos() && pBkmk->GetOtherPos()->nNode.GetIndex() == + nNode && pBkmk->GetOtherPos()->nContent.GetIndex() < nCntnt ) + { + aSave.SetContent( pBkmk->GetOtherPos()->nContent.GetIndex() ); + aSave.IncType(); + aSave.Add( rSaveArr ); + aSave.DecType(); + } + } + + // 2. Redlines + aSave.SetTypeAndCount( 0x1000, 0 ); + const SwRedlineTbl& rRedlTbl = pDoc->GetRedlineTbl(); + for( ; aSave.GetCount() < rRedlTbl.Count(); aSave.IncCount() ) + { + const SwRedline* pRdl = rRedlTbl[ aSave.GetCount() ]; + if( pRdl->GetPoint()->nNode.GetIndex() == nNode && + pRdl->GetPoint()->nContent.GetIndex() < nCntnt ) + { + aSave.SetContent( pRdl->GetPoint()->nContent.GetIndex() ); + aSave.IncType(); + aSave.Add( rSaveArr ); + aSave.DecType(); + } + + if( pRdl->HasMark() && + pRdl->GetMark()->nNode.GetIndex() == nNode && + pRdl->GetMark()->nContent.GetIndex() < nCntnt ) + { + aSave.SetContent( pRdl->GetMark()->nContent.GetIndex() ); + aSave.Add( rSaveArr ); + } + } + + // 4. Absatzgebundene Objekte + { + SwCntntNode *pNode = pDoc->GetNodes()[nNode]->GetCntntNode(); + if( pNode ) + { + const SwPosition* pAPos; + + SwFrm* pFrm = pNode->GetFrm(); +#ifdef DEBUG + static BOOL bViaDoc = FALSE; + if( bViaDoc ) + pFrm = NULL; +#endif + if( pFrm ) // gibt es ein Layout? Dann ist etwas billiger... + { + if( pFrm->GetDrawObjs() ) + { + const SwDrawObjs& rDObj = *pFrm->GetDrawObjs(); + for( USHORT n = rDObj.Count(); n; ) + { + SdrObject *pObj = rDObj[ --n ]; + SwFrmFmt* pFmt = ((SwContact*)GetUserCall(pObj))->GetFmt(); + const SwFmtAnchor& rAnchor = pFmt->GetAnchor(); + if( ( ( nSaveFly && FLY_AT_CNTNT == rAnchor.GetAnchorId() ) || + FLY_AUTO_CNTNT == rAnchor.GetAnchorId() ) && + ( 0 != ( pAPos = rAnchor.GetCntntAnchor() ) ) ) + { + aSave.SetType( 0x2000 ); + aSave.SetContent( pAPos->nContent.GetIndex() ); + + ASSERT( nNode == pAPos->nNode.GetIndex(), + "_SaveCntntIdx: Wrong Node-Index" ); + if( FLY_AUTO_CNTNT == rAnchor.GetAnchorId() ) + { + if( nCntnt <= aSave.GetContent() ) + { + if( SAVEFLY_SPLIT == nSaveFly ) + aSave.IncType(); // = 0x2001; + else + continue; + } + } + aSave.SetCount( pDoc->GetSpzFrmFmts()->Count() ); + while( aSave.GetCount() && + pFmt != (*pDoc->GetSpzFrmFmts())[ + aSave.DecCount() ] ) + ; // nothing + ASSERT( pFmt == (*pDoc->GetSpzFrmFmts())[ + aSave.GetCount() ], + "_SaveCntntIdx: Lost FrameFormat" ); + aSave.Add( rSaveArr ); + } + } + } + } + else // Schade, kein Layout, dann ist es eben etwas teurer... + { + for( aSave.SetCount( pDoc->GetSpzFrmFmts()->Count() ); + aSave.GetCount() ; ) + { + SwFrmFmt* pFrmFmt = (*pDoc->GetSpzFrmFmts())[ + aSave.DecCount() ]; + if ( RES_FLYFRMFMT != pFrmFmt->Which() && + RES_DRAWFRMFMT != pFrmFmt->Which() ) + continue; + + const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor(); + if( ( FLY_AT_CNTNT == rAnchor.GetAnchorId() || + FLY_AUTO_CNTNT == rAnchor.GetAnchorId() ) && + 0 != ( pAPos = rAnchor.GetCntntAnchor()) && + nNode == pAPos->nNode.GetIndex() ) + { + aSave.SetType( 0x2000 ); + aSave.SetContent( pAPos->nContent.GetIndex() ); + if( FLY_AUTO_CNTNT == rAnchor.GetAnchorId() ) + { + if( nCntnt <= aSave.GetContent() ) + { + if( SAVEFLY_SPLIT == nSaveFly ) + aSave.IncType(); // = 0x2001; + else + continue; + } + } + aSave.Add( rSaveArr ); + } + } + } + } + } + // 5. CrsrShell + { + SwCrsrShell* pShell = pDoc->GetEditShell(); + if( pShell ) + { + aSave.SetTypeAndCount( 0x800, 0 ); + FOREACHSHELL_START( pShell ) + register SwPaM *_pStkCrsr = PCURSH->GetStkCrsr(); + if( _pStkCrsr ) + do { + ::_ChkPaM( rSaveArr, nNode, nCntnt, *_pStkCrsr, + aSave, FALSE ); + aSave.IncCount(); + } while ( (_pStkCrsr != 0 ) && + ((_pStkCrsr=(SwPaM *)_pStkCrsr->GetNext()) != PCURSH->GetStkCrsr()) ); + + FOREACHPAM_START( PCURSH->_GetCrsr() ) + ::_ChkPaM( rSaveArr, nNode, nCntnt, *PCURCRSR, + aSave, FALSE ); + aSave.IncCount(); + FOREACHPAM_END() + + FOREACHSHELL_END( pShell ) + } + } + // 6. UnoCrsr + { + aSave.SetTypeAndCount( 0x400, 0 ); + register const SwUnoCrsrTbl& rTbl = pDoc->GetUnoCrsrTbl(); + for( USHORT n = 0; n < rTbl.Count(); ++n ) + { + FOREACHPAM_START( rTbl[ n ] ) + ::_ChkPaM( rSaveArr, nNode, nCntnt, *PCURCRSR, aSave, FALSE ); + aSave.IncCount(); + FOREACHPAM_END() + + SwUnoTableCrsr* pUnoTblCrsr = (SwUnoTableCrsr*)*rTbl[ n ]; + if( pUnoTblCrsr ) + { + FOREACHPAM_START( &pUnoTblCrsr->GetSelRing() ) + ::_ChkPaM( rSaveArr, nNode, nCntnt, *PCURCRSR, aSave, FALSE ); + aSave.IncCount(); + FOREACHPAM_END() + } + } + } +} + + +void _RestoreCntntIdx( SwDoc* pDoc, SvULongs& rSaveArr, + ULONG nNode, xub_StrLen nOffset, BOOL bAuto ) +{ + SwCntntNode* pCNd = pDoc->GetNodes()[ nNode ]->GetCntntNode(); + const SwBookmarks& rBkmks = pDoc->GetBookmarks(); + const SwRedlineTbl& rRedlTbl = pDoc->GetRedlineTbl(); + SwSpzFrmFmts* pSpz = pDoc->GetSpzFrmFmts(); + USHORT n = 0; + while( n < rSaveArr.Count() ) + { + _SwSaveTypeCountContent aSave( rSaveArr, n ); + SwPosition* pPos = 0; + switch( aSave.GetType() ) + { + case 0x8000: + pPos = (SwPosition*)&rBkmks[ aSave.GetCount() ]->GetPos(); + break; + case 0x8001: + pPos = (SwPosition*)rBkmks[ aSave.GetCount() ]->GetOtherPos(); + break; + case 0x1001: + pPos = (SwPosition*)rRedlTbl[ aSave.GetCount() ]->GetPoint(); + break; + case 0x1000: + pPos = (SwPosition*)rRedlTbl[ aSave.GetCount() ]->GetMark(); + break; + case 0x2000: + { + SwFrmFmt *pFrmFmt = (*pSpz)[ aSave.GetCount() ]; + const SwFmtAnchor& rFlyAnchor = pFrmFmt->GetAnchor(); + if( rFlyAnchor.GetCntntAnchor() ) + { + SwFmtAnchor aNew( rFlyAnchor ); + SwPosition aNewPos( *rFlyAnchor.GetCntntAnchor() ); + aNewPos.nNode = *pCNd; + if( FLY_AUTO_CNTNT == rFlyAnchor.GetAnchorId() ) + aNewPos.nContent.Assign( pCNd, + aSave.GetContent() + nOffset ); + else + aNewPos.nContent.Assign( 0, 0 ); + aNew.SetAnchor( &aNewPos ); + pFrmFmt->SetAttr( aNew ); + } + } + break; + case 0x2001: + if( bAuto ) + { + SwFrmFmt *pFrmFmt = (*pSpz)[ aSave.GetCount() ]; + SfxPoolItem *pAnchor = (SfxPoolItem*)&pFrmFmt->GetAnchor(); + pFrmFmt->SwModify::Modify( pAnchor, pAnchor ); + } + break; + + case 0x0800: + case 0x0801: + { + USHORT nCnt = 0; + SwCrsrShell* pShell = pDoc->GetEditShell(); + if( pShell ) + { + FOREACHSHELL_START( pShell ) + register SwPaM *_pStkCrsr = PCURSH->GetStkCrsr(); + if( _pStkCrsr ) + do { + if( aSave.GetCount() == nCnt ) + { + pPos = &_pStkCrsr->GetBound( 0x0800 == + aSave.GetType() ); + break; + } + ++nCnt; + } while ( (_pStkCrsr != 0 ) && + ((_pStkCrsr=(SwPaM *)_pStkCrsr->GetNext()) != PCURSH->GetStkCrsr()) ); + + if( pPos ) + break; + + FOREACHPAM_START( PCURSH->_GetCrsr() ) + if( aSave.GetCount() == nCnt ) + { + pPos = &PCURCRSR->GetBound( 0x0800 == + aSave.GetType() ); + break; + } + ++nCnt; + FOREACHPAM_END() + if( pPos ) + break; + + FOREACHSHELL_END( pShell ) + } + } + break; + + case 0x0400: + case 0x0401: + { + USHORT nCnt = 0; + register const SwUnoCrsrTbl& rTbl = pDoc->GetUnoCrsrTbl(); + for( USHORT i = 0; i < rTbl.Count(); ++i ) + { + FOREACHPAM_START( rTbl[ i ] ) + if( aSave.GetCount() == nCnt ) + { + pPos = &PCURCRSR->GetBound( 0x0400 == + aSave.GetType() ); + break; + } + ++nCnt; + FOREACHPAM_END() + if( pPos ) + break; + + SwUnoTableCrsr* pUnoTblCrsr = (SwUnoTableCrsr*)*rTbl[ i ]; + if( pUnoTblCrsr ) + { + FOREACHPAM_START( &pUnoTblCrsr->GetSelRing() ) + if( aSave.GetCount() == nCnt ) + { + pPos = &PCURCRSR->GetBound( 0x0400 == + aSave.GetType() ); + break; + } + ++nCnt; + FOREACHPAM_END() + } + if( pPos ) + break; + } + } + break; + } + + if( pPos ) + { + pPos->nNode = *pCNd; + pPos->nContent.Assign( pCNd, aSave.GetContent() + nOffset ); + } + } +} + +void _RestoreCntntIdx( SvULongs& rSaveArr, const SwNode& rNd, + xub_StrLen nLen, xub_StrLen nChkLen ) +{ + const SwDoc* pDoc = rNd.GetDoc(); + const SwBookmarks& rBkmks = pDoc->GetBookmarks(); + const SwRedlineTbl& rRedlTbl = pDoc->GetRedlineTbl(); + const SwSpzFrmFmts* pSpz = pDoc->GetSpzFrmFmts(); + SwCntntNode* pCNd = (SwCntntNode*)rNd.GetCntntNode(); + + USHORT n = 0; + while( n < rSaveArr.Count() ) + { + _SwSaveTypeCountContent aSave( rSaveArr, n ); + if( aSave.GetContent() >= nChkLen ) + rSaveArr[ n + 1 ] -= nChkLen; + else + { + SwPosition* pPos = 0; + switch( aSave.GetType() ) + { + case 0x8000: + pPos = (SwPosition*)&rBkmks[ aSave.GetCount() ]->GetPos(); + break; + case 0x8001: + pPos = (SwPosition*)rBkmks[ aSave.GetCount() ]->GetOtherPos(); + break; + case 0x1001: + pPos = (SwPosition*)rRedlTbl[ aSave.GetCount() ]->GetPoint(); + break; + case 0x1000: + pPos = (SwPosition*)rRedlTbl[ aSave.GetCount() ]->GetMark(); + break; + case 0x2000: + case 0x2001: + { + SwFrmFmt *pFrmFmt = (*pSpz)[ aSave.GetCount() ]; + const SwFmtAnchor& rFlyAnchor = pFrmFmt->GetAnchor(); + if( rFlyAnchor.GetCntntAnchor() ) + { + SwFmtAnchor aNew( rFlyAnchor ); + SwPosition aNewPos( *rFlyAnchor.GetCntntAnchor() ); + aNewPos.nNode = rNd; + if( FLY_AUTO_CNTNT == rFlyAnchor.GetAnchorId() ) + aNewPos.nContent.Assign( pCNd, Min( + aSave.GetContent(), nLen ) ); + else + aNewPos.nContent.Assign( 0, 0 ); + aNew.SetAnchor( &aNewPos ); + pFrmFmt->SetAttr( aNew ); + } + } + break; + + case 0x0800: + case 0x0801: + { + USHORT nCnt = 0; + SwCrsrShell* pShell = pDoc->GetEditShell(); + if( pShell ) + { + FOREACHSHELL_START( pShell ) + register SwPaM *_pStkCrsr = PCURSH->GetStkCrsr(); + if( _pStkCrsr ) + do { + if( aSave.GetCount() == nCnt ) + { + pPos = &_pStkCrsr->GetBound( 0x0800 == + aSave.GetType() ); + break; + } + ++nCnt; + } while ( (_pStkCrsr != 0 ) && + ((_pStkCrsr=(SwPaM *)_pStkCrsr->GetNext()) != PCURSH->GetStkCrsr()) ); + + if( pPos ) + break; + + FOREACHPAM_START( PCURSH->_GetCrsr() ) + if( aSave.GetCount() == nCnt ) + { + pPos = &PCURCRSR->GetBound( 0x0800 == + aSave.GetType() ); + break; + } + ++nCnt; + FOREACHPAM_END() + if( pPos ) + break; + + FOREACHSHELL_END( pShell ) + } + } + break; + + case 0x0400: + case 0x0401: + { + USHORT nCnt = 0; + register const SwUnoCrsrTbl& rTbl = pDoc->GetUnoCrsrTbl(); + for( USHORT i = 0; i < rTbl.Count(); ++i ) + { + FOREACHPAM_START( rTbl[ i ] ) + if( aSave.GetCount() == nCnt ) + { + pPos = &PCURCRSR->GetBound( 0x0400 == + aSave.GetType() ); + break; + } + ++nCnt; + FOREACHPAM_END() + if( pPos ) + break; + + SwUnoTableCrsr* pUnoTblCrsr = (SwUnoTableCrsr*)*rTbl[ i ]; + if( pUnoTblCrsr ) + { + FOREACHPAM_START( &pUnoTblCrsr->GetSelRing() ) + if( aSave.GetCount() == nCnt ) + { + pPos = &PCURCRSR->GetBound( 0x0400 == + aSave.GetType() ); + break; + } + ++nCnt; + FOREACHPAM_END() + } + if( pPos ) + break; + } + } + break; + } + + if( pPos ) + { + pPos->nNode = rNd; + pPos->nContent.Assign( pCNd, Min( aSave.GetContent(), nLen ) ); + } + + rSaveArr.Remove( n, 2 ); + n -= 2; + } + } +} + + diff --git a/sw/source/core/doc/docchart.cxx b/sw/source/core/doc/docchart.cxx new file mode 100644 index 000000000000..eeafdaeaa1dd --- /dev/null +++ b/sw/source/core/doc/docchart.cxx @@ -0,0 +1,489 @@ +/************************************************************************* + * + * $RCSfile: docchart.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:15 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#include + +#ifndef _HINTIDS_HXX +#include +#endif + +#ifndef _IPOBJ_HXX //autogen +#include +#endif +#ifndef _SCH_DLL_HXX +#include +#endif +#ifndef _SCH_MEMCHRT_HXX +#include +#endif + +#ifndef _DOC_HXX +#include +#endif +#ifndef _DOCARY_HXX +#include +#endif +#ifndef _NDINDEX_HXX //autogen +#include +#endif +#ifndef _SWTABLE_HXX +#include +#endif +#ifndef _NDTXT_HXX //autogen +#include +#endif +#ifndef _CALC_HXX +#include +#endif +#ifndef _FRMFMT_HXX //autogen +#include +#endif +#ifndef _CELLFML_HXX //autogen +#include +#endif +#ifndef _VIEWSH_HXX +#include +#endif +#ifndef _NDOLE_HXX //autogen +#include +#endif +#ifndef _CALBCK_HXX //autogen +#include +#endif +#ifndef _CNTFRM_HXX //autogen +#include +#endif +#ifndef _SWTBLFMT_HXX //autogen +#include +#endif +#ifndef _TBLSEL_HXX +#include +#endif +#ifndef _CELLATR_HXX //autogen wg. SwTblBoxNumFormat +#include +#endif + + +SchMemChart *SwTable::UpdateData( SchMemChart* pData, + const String* pSelection ) const +{ + SwCalc aCalc( *GetFrmFmt()->GetDoc() ); + SwTblCalcPara aCalcPara( aCalc, *this ); + String aSelection; + + // worauf bezieht sich das Chart? + if( pData && pData->SomeData1().Len() ) + aSelection = pData->SomeData1(); + else if( pSelection ) + aSelection = *pSelection; + + SwChartLines aLines; + if( !IsTblComplexForChart( aSelection, &aLines )) + { + USHORT nLines = aLines.Count(), nBoxes = aLines[0]->Count(); + + if( !pData ) + { + //JP 08.02.99: als default wird mit Spalten/Zeilenueberschrift + // eingefuegt, deshalb das -1 + pData = SchDLL::NewMemChart( nBoxes-1, nLines-1 ); + pData->SetSubTitle( aEmptyStr ); + pData->SetXAxisTitle( aEmptyStr ); + pData->SetYAxisTitle( aEmptyStr ); + pData->SetZAxisTitle( aEmptyStr ); + } + + if( !pData->SomeData1().Len() ) + { + pData->SomeData2().AssignAscii( RTL_CONSTASCII_STRINGPARAM("11") ); + + //Den Title nur beim erzeugen setzen. Hinterher darf der Titel nicht + //mehr angepasst werden, weil der Anwender diesen evtl. Geaendert hat. + pData->SetMainTitle( GetFrmFmt()->GetName() ); + + // dann mal den Namen setzen: + const SwTableBox* pBox = (*aLines[0])[ 0 ]; + + String &rStr = pData->SomeData1(); + rStr.Assign( '<' ).Append( pBox->GetName() ).Append( ':' ); + + pBox = (*aLines[ nLines - 1 ])[ nBoxes - 1 ]; + rStr.Append( pBox->GetName() ).Append( '>' ); + } + + USHORT nRowStt = 0, nColStt = 0; + if( pData->SomeData2().Len() ) + { + if( '1' == pData->SomeData2().GetChar( 0 )) + ++nRowStt; + if( '1' == pData->SomeData2().GetChar( 1 )) + ++nColStt; + } + + if( (nBoxes - nColStt) > pData->GetColCount() ) + pData->InsertCols( 0, (nBoxes - nColStt) - pData->GetColCount() ); + else if( (nBoxes - nColStt) < pData->GetColCount() ) + pData->RemoveCols( 0, pData->GetColCount() - (nBoxes - nColStt) ); + + if( (nLines - nRowStt) > pData->GetRowCount() ) + pData->InsertRows( 0, (nLines - nRowStt) - pData->GetRowCount() ); + else if( (nLines - nRowStt) < pData->GetRowCount() ) + pData->RemoveRows( 0, pData->GetRowCount() - (nLines - nRowStt) ); + + + ASSERT( pData->GetRowCount() >= (nLines - nRowStt ) && + pData->GetColCount() >= (nBoxes - nColStt ), + "Die Struktur fuers Chart ist zu klein,\n" + "es wird irgendwo in den Speicher geschrieben!" ); + + // Row-Texte setzen + USHORT n; + if( nRowStt ) + for( n = nColStt; n < nBoxes; ++n ) + { + const SwTableBox *pBox = (*aLines[ 0 ])[ n ]; + ASSERT( pBox->GetSttNd(), "Box without SttIdx" ); + SwNodeIndex aIdx( *pBox->GetSttNd(), 1 ); + const SwTxtNode* pTNd = aIdx.GetNode().GetTxtNode(); + if( !pTNd ) + pTNd = aIdx.GetNodes().GoNextSection( &aIdx, TRUE, FALSE ) + ->GetTxtNode(); + + pData->SetColText( n - nColStt, pTNd->GetExpandTxt() ); + } + else + { + String aText; + for( n = nColStt; n < nBoxes; ++n ) + { + SchDLL::GetDefaultForColumnText( *pData, n - nColStt, aText ); + pData->SetColText( n - nColStt, aText ); + } + } + + // Col-Texte setzen + if( nColStt ) + for( n = nRowStt; n < nLines; ++n ) + { + const SwTableBox *pBox = (*aLines[ n ])[ 0 ]; + ASSERT( pBox->GetSttNd(), "Box without SttIdx" ); + SwNodeIndex aIdx( *pBox->GetSttNd(), 1 ); + const SwTxtNode* pTNd = aIdx.GetNode().GetTxtNode(); + if( !pTNd ) + pTNd = aIdx.GetNodes().GoNextSection( &aIdx, TRUE, FALSE ) + ->GetTxtNode(); + + pData->SetRowText( n - nRowStt, pTNd->GetExpandTxt() ); + } + else + { + String aText; + for( n = nRowStt; n < nLines; ++n ) + { + SchDLL::GetDefaultForRowText( *pData, n - nRowStt, aText ); + pData->SetRowText( n - nRowStt, aText ); + } + } + + // und dann fehlen nur noch die Daten + const SwTblBoxNumFormat& rDfltNumFmt = *(SwTblBoxNumFormat*) + GetDfltAttr( RES_BOXATR_FORMAT ); + pData->SetNumberFormatter( GetFrmFmt()->GetDoc()->GetNumberFormatter()); + int bFirstRow = TRUE; + for( n = nRowStt; n < nLines; ++n ) + { + for( USHORT i = nColStt; i < nBoxes; ++i ) + { + const SwTableBox* pBox = (*aLines[ n ])[ i ]; + ASSERT( pBox->GetSttNd(), "Box without SttIdx" ); + SwNodeIndex aIdx( *pBox->GetSttNd(), 1 ); + const SwTxtNode* pTNd = aIdx.GetNode().GetTxtNode(); + if( !pTNd ) + pTNd = aIdx.GetNodes().GoNextSection( &aIdx, TRUE, FALSE ) + ->GetTxtNode(); + + pData->SetData( short( i - nColStt ), + short( n - nRowStt ), + pTNd->GetTxt().Len() + ? pBox->GetValue( aCalcPara ) + : DBL_MIN ); + + if( i == nColStt || bFirstRow ) + { + // first box of row set the numberformat + const SwTblBoxNumFormat& rNumFmt = pBox->GetFrmFmt()-> + GetTblBoxNumFmt(); + if( rNumFmt != rDfltNumFmt ) + { + pData->SetNumFormatIdCol( i, rNumFmt.GetValue() ); + if( bFirstRow ) + pData->SetNumFormatIdRow( n, rNumFmt.GetValue() ); + } + } + + } + bFirstRow = FALSE; + } + } + else if( pData ) + { + if( pData->GetColCount() ) + pData->RemoveCols( 0, pData->GetColCount() ); + if( pData->GetRowCount() ) + pData->RemoveRows( 0, pData->GetRowCount() ); + } + + return pData; +} + +BOOL SwTable::IsTblComplexForChart( const String& rSelection, + SwChartLines* pGetCLines ) const +{ + const SwTableBox* pSttBox, *pEndBox; + if( 2 < rSelection.Len() ) + { + // spitze Klammern am Anfang & Ende enfernen + String sBox( rSelection ); + if( '<' == sBox.GetChar( 0 ) ) sBox.Erase( 0, 1 ); + if( '>' == sBox.GetChar( sBox.Len()-1 ) ) sBox.Erase( sBox.Len()-1 ); + + xub_StrLen nTrenner = sBox.Search( ':' ); + ASSERT( STRING_NOTFOUND != nTrenner, "keine gueltige Selektion" ); + + pSttBox = GetTblBox( sBox.Copy( 0, nTrenner )); + pEndBox = GetTblBox( sBox.Copy( nTrenner+1 )); + } + else + { + const SwTableLines* pLns = &GetTabLines(); + pSttBox = (*pLns)[ 0 ]->GetTabBoxes()[ 0 ]; + while( !pSttBox->GetSttNd() ) + // bis zur Content Box! + pSttBox = pSttBox->GetTabLines()[ 0 ]->GetTabBoxes()[ 0 ]; + + const SwTableBoxes* pBoxes = &(*pLns)[ pLns->Count()-1 ]->GetTabBoxes(); + pEndBox = (*pBoxes)[ pBoxes->Count()-1 ]; + while( !pEndBox->GetSttNd() ) + { + // bis zur Content Box! + pLns = &pEndBox->GetTabLines(); + pBoxes = &(*pLns)[ pLns->Count()-1 ]->GetTabBoxes(); + pEndBox = (*pBoxes)[ pBoxes->Count()-1 ]; + } + } + + return !pSttBox || !pEndBox || !::ChkChartSel( *pSttBox->GetSttNd(), + *pEndBox->GetSttNd(), pGetCLines ); +} + + + +IMPL_LINK( SwDoc, DoUpdateAllCharts, Timer *, pTimer ) +{ + ViewShell* pVSh; + GetEditShell( &pVSh ); + if( pVSh ) + { + const SwFrmFmts& rTblFmts = *GetTblFrmFmts(); + for( USHORT n = 0; n < rTblFmts.Count(); ++n ) + { + SwTable* pTmpTbl; + const SwTableNode* pTblNd; + SwFrmFmt* pFmt = rTblFmts[ n ]; + + if( 0 != ( pTmpTbl = SwTable::FindTable( pFmt ) ) && + 0 != ( pTblNd = pTmpTbl->GetTableNode() ) && + pTblNd->GetNodes().IsDocNodes() ) + { + _UpdateCharts( *pTmpTbl, *pVSh ); + } + } + } + return 0; +} + +void SwDoc::_UpdateCharts( const SwTable& rTbl, ViewShell& rVSh ) const +{ + String aName( rTbl.GetFrmFmt()->GetName() ); + SwOLENode *pONd; + SwStartNode *pStNd; + SwNodeIndex aIdx( *GetNodes().GetEndOfAutotext().StartOfSectionNode(), 1 ); + while( 0 != (pStNd = aIdx.GetNode().GetStartNode()) ) + { + aIdx++; + SwFrm* pFrm; + if( 0 != ( pONd = aIdx.GetNode().GetOLENode() ) && + aName.Equals( pONd->GetChartTblName() ) && + 0 != ( pFrm = pONd->GetFrm() ) ) + { + SwOLEObj& rOObj = pONd->GetOLEObj(); + + SchMemChart *pData = SchDLL::GetChartData( rOObj.GetOleRef() ); + FASTBOOL bDelData = 0 == pData; + + ASSERT( pData, "UpdateChart ohne irgendwelche Daten?" ); + pData = rTbl.UpdateData( pData ); + + if( !rTbl.IsTblComplexForChart( pData->SomeData1() ) ) + { + SchDLL::Update( rOObj.GetOleRef(), pData, rVSh.GetWin() ); + + SwClientIter aIter( *pONd ); + for( pFrm = (SwFrm*)aIter.First( TYPE(SwFrm) ); pFrm; + pFrm = (SwFrm*)aIter.Next() ) + { + if( pFrm->Frm().HasArea() ) + rVSh.InvalidateWindows( pFrm->Frm() ); + } + } + + if ( bDelData ) + delete pData; + } + aIdx.Assign( *pStNd->EndOfSectionNode(), + 1 ); + } +} + +void SwDoc::UpdateCharts( const String &rName ) const +{ + SwTable* pTmpTbl = SwTable::FindTable( FindTblFmtByName( rName ) ); + if( pTmpTbl ) + { + ViewShell* pVSh; + GetEditShell( &pVSh ); + + if( pVSh ) + _UpdateCharts( *pTmpTbl, *pVSh ); + } +} + +void SwDoc::SetTableName( SwFrmFmt& rTblFmt, const String &rNewName ) +{ + const String aOldName( rTblFmt.GetName() ); + + BOOL bNameFound = 0 == rNewName.Len(); + if( !bNameFound ) + { + SwFrmFmt* pFmt; + const SwFrmFmts& rTbl = *GetTblFrmFmts(); + for( USHORT i = rTbl.Count(); i; ) + if( !( pFmt = rTbl[ --i ] )->IsDefault() && + pFmt->GetName() == rNewName && IsUsed( *pFmt ) ) + { + bNameFound = TRUE; + break; + } + } + + if( !bNameFound ) + rTblFmt.SetName( rNewName ); + else + rTblFmt.SetName( GetUniqueTblName() ); + + SwStartNode *pStNd; + SwNodeIndex aIdx( *GetNodes().GetEndOfAutotext().StartOfSectionNode(), 1 ); + while ( 0 != (pStNd = aIdx.GetNode().GetStartNode()) ) + { + aIdx++; + SwOLENode *pNd = aIdx.GetNode().GetOLENode(); + if( pNd && aOldName == pNd->GetChartTblName() ) + { + pNd->SetChartTblName( rNewName ); + + SwOLEObj& rOObj = pNd->GetOLEObj(); + SchMemChart *pData = SchDLL::GetChartData( rOObj.GetOleRef() ); + if( pData ) + { + ViewShell* pVSh; + GetEditShell( &pVSh ); + + if( aOldName == pData->GetMainTitle() ) + { + pData->SetMainTitle( rNewName ); + if( pVSh ) + SchDLL::Update( rOObj.GetOleRef(), pData, pVSh->GetWin() ); + } + + if( pVSh ) + { + SwFrm *pFrm; + SwClientIter aIter( *pNd ); + for( pFrm = (SwFrm*)aIter.First( TYPE(SwFrm) ); pFrm; + pFrm = (SwFrm*)aIter.Next() ) + { + if( pFrm->Frm().HasArea() ) + pVSh->InvalidateWindows( pFrm->Frm() ); + } + } + } + } + aIdx.Assign( *pStNd->EndOfSectionNode(), + 1 ); + } + SetModified(); +} + + diff --git a/sw/source/core/doc/doccomp.cxx b/sw/source/core/doc/doccomp.cxx new file mode 100644 index 000000000000..d5be2965a921 --- /dev/null +++ b/sw/source/core/doc/doccomp.cxx @@ -0,0 +1,1772 @@ +/************************************************************************* + * + * $RCSfile: doccomp.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:15 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _HINTIDS_HXX +#include +#endif + +#ifndef _SV_FONTTYPE_HXX //autogen +#include +#endif +#ifndef _SVX_CRSDITEM_HXX //autogen +#include +#endif +#ifndef _SVX_COLRITEM_HXX //autogen +#include +#endif +#ifndef _SVX_BOXITEM_HXX //autogen +#include +#endif +#ifndef _SVX_UDLNITEM_HXX //autogen +#include +#endif + +#ifdef JP_DUMP +#include +#ifndef _STREAM_HXX //autogen +#include +#endif +#endif + +#ifndef _DOC_HXX +#include +#endif +#ifndef _DOCARY_HXX +#include +#endif +#ifndef _PAM_HXX +#include +#endif +#ifndef _NDTXT_HXX +#include +#endif +#ifndef _NDINDEX_HXX +#include +#endif +#ifndef _REDLINE_HXX +#include +#endif +#ifndef _REDLENUM_HXX +#include +#endif +#ifndef _UNDOBJ_HXX +#include +#endif +#ifndef _LIST_HXX +#include +#endif + + + +class CompareLine +{ +public: + CompareLine() {} + virtual ~CompareLine(); + + virtual ULONG GetHashValue() const = 0; + virtual BOOL Compare( const CompareLine& rLine ) const = 0; +}; + +DECLARE_LIST( CompareList, CompareLine* ) + +class CompareData +{ + ULONG* pIndex; + BOOL* pChangedFlag; + +protected: + CompareList aLines; + ULONG nSttLineNum; + + // Anfang und Ende beschneiden und alle anderen in das + // LinesArray setzen + virtual void CheckRanges( CompareData& ) = 0; + +public: + CompareData(); + virtual ~CompareData(); + + // gibt es unterschiede? + BOOL HasDiffs( const CompareData& rData ) const; + + // startet das Vergleichen und Erzeugen der Unterschiede zweier + // Dokumente + void CompareLines( CompareData& rData ); + // lasse die Unterschiede anzeigen - ruft die beiden Methoden + // ShowInsert / ShowDelete. Diese bekommen die Start und EndLine-Nummer + // uebergeben. Die Abbildung auf den tatsaechline Inhalt muss die + // Ableitung uebernehmen! + ULONG ShowDiffs( const CompareData& rData ); + + virtual void ShowInsert( ULONG nStt, ULONG nEnd ); + virtual void ShowDelete( const CompareData& rData, ULONG nStt, + ULONG nEnd, ULONG nInsPos ); + virtual void CheckForChangesInLine( const CompareData& rData, + ULONG& nStt, ULONG& nEnd, + ULONG& nThisStt, ULONG& nThisEnd ); + + // Eindeutigen Index fuer eine Line setzen. Gleiche Lines haben den + // selben Index; auch in den anderen CompareData! + void SetIndex( ULONG nLine, ULONG nIndex ); + ULONG GetIndex( ULONG nLine ) const + { return nLine < aLines.Count() ? pIndex[ nLine ] : 0; } + + // setze/erfrage ob eine Zeile veraendert ist + void SetChanged( ULONG nLine, BOOL bFlag = TRUE ); + BOOL GetChanged( ULONG nLine ) const + { + return (pChangedFlag && nLine < aLines.Count()) + ? pChangedFlag[ nLine ] + : 0; + } + + ULONG GetLineCount() const { return aLines.Count(); } + ULONG GetLineOffset() const { return nSttLineNum; } + const CompareLine* GetLine( ULONG nLine ) const + { return aLines.GetObject( nLine ); } + void InsertLine( CompareLine* pLine ) + { aLines.Insert( pLine, LIST_APPEND ); } + +#ifdef JP_DUMP + // zum Debuggen! + virtual void Dump(); +#endif +}; + +class Hash +{ + struct _HashData + { + ULONG nNext, nHash; + const CompareLine* pLine; + + _HashData() + : nNext( 0 ), nHash( 0 ), pLine(0) {} + }; + + ULONG* pHashArr; + _HashData* pDataArr; + ULONG nCount, nPrime; + +public: + Hash( ULONG nSize ); + ~Hash(); + + void CalcHashValue( CompareData& rData ); + + ULONG GetCount() const { return nCount; } +}; + +class Compare +{ +public: + class MovedData + { + ULONG* pIndex; + ULONG* pLineNum; + ULONG nCount; + + public: + MovedData( CompareData& rData, sal_Char* pDiscard ); + ~MovedData(); + + ULONG GetIndex( ULONG n ) const { return pIndex[ n ]; } + ULONG GetLineNum( ULONG n ) const { return pLineNum[ n ]; } + ULONG GetCount() const { return nCount; } + }; + +private: + // Suche die verschobenen Lines + class CompareSequence + { + CompareData &rData1, &rData2; + const MovedData &rMoved1, &rMoved2; + long *pMemory, *pFDiag, *pBDiag; + + void Compare( ULONG nStt1, ULONG nEnd1, ULONG nStt2, ULONG nEnd2 ); + ULONG CheckDiag( ULONG nStt1, ULONG nEnd1, + ULONG nStt2, ULONG nEnd2, ULONG* pCost ); + public: + CompareSequence( CompareData& rData1, CompareData& rData2, + const MovedData& rD1, const MovedData& rD2 ); + ~CompareSequence(); + }; + + + static void CountDifference( const CompareData& rData, ULONG* pCounts ); + static void SetDiscard( const CompareData& rData, + sal_Char* pDiscard, ULONG* pCounts ); + static void CheckDiscard( ULONG nLen, sal_Char* pDiscard ); + static ULONG SetChangedFlag( CompareData& rData, sal_Char* pDiscard, int bFirst ); + static void ShiftBoundaries( CompareData& rData1, CompareData& rData2 ); + +public: + Compare( ULONG nDiff, CompareData& rData1, CompareData& rData2 ); +}; + +// ==================================================================== + +CompareLine::~CompareLine() {} + +// ---------------------------------------------------------------------- + +CompareData::CompareData() + : nSttLineNum( 0 ), pIndex( 0 ), pChangedFlag( 0 ) +{ +} + +CompareData::~CompareData() +{ + delete pIndex; + delete pChangedFlag; +} + +void CompareData::SetIndex( ULONG nLine, ULONG nIndex ) +{ + if( !pIndex ) + { + pIndex = new ULONG[ aLines.Count() ]; + memset( pIndex, 0, aLines.Count() * sizeof( ULONG ) ); + } + if( nLine < aLines.Count() ) + pIndex[ nLine ] = nIndex; +} + +#ifdef JP_DUMP +void CompareData::Dump() +{ +} +#endif + +void CompareData::SetChanged( ULONG nLine, BOOL bFlag ) +{ + if( !pChangedFlag ) + { + pChangedFlag = new BOOL[ aLines.Count() +1 ]; + memset( pChangedFlag, 0, aLines.Count() +1 * sizeof( BOOL ) ); + } + if( nLine < aLines.Count() ) + pChangedFlag[ nLine ] = bFlag; +} + +void CompareData::CompareLines( CompareData& rData ) +{ + CheckRanges( rData ); + + ULONG nDifferent; + { + Hash aH( GetLineCount() + rData.GetLineCount() + 1 ); + aH.CalcHashValue( *this ); + aH.CalcHashValue( rData ); + nDifferent = aH.GetCount(); + } + { + Compare aComp( nDifferent, *this, rData ); + } +} + +ULONG CompareData::ShowDiffs( const CompareData& rData ) +{ + ULONG nLen1 = rData.GetLineCount(), nLen2 = GetLineCount(); + ULONG nStt1 = 0, nStt2 = 0; + ULONG nCnt = 0; + + while( nStt1 < nLen1 || nStt2 < nLen2 ) + { + if( rData.GetChanged( nStt1 ) || GetChanged( nStt2 ) ) + { + 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; + } + ++nStt1, ++nStt2; + } + return nCnt; +} + +BOOL CompareData::HasDiffs( const CompareData& rData ) const +{ + BOOL bRet = FALSE; + ULONG nLen1 = rData.GetLineCount(), nLen2 = GetLineCount(); + ULONG nStt1 = 0, nStt2 = 0; + + while( nStt1 < nLen1 || nStt2 < nLen2 ) + { + if( rData.GetChanged( nStt1 ) || GetChanged( nStt2 ) ) + { + bRet = TRUE; + break; + } + ++nStt1, ++nStt2; + } + return bRet; +} + +void CompareData::ShowInsert( ULONG nStt, ULONG nEnd ) +{ +} + +void CompareData::ShowDelete( const CompareData& rData, ULONG nStt, + ULONG nEnd, ULONG nInsPos ) +{ +} + +void CompareData::CheckForChangesInLine( const CompareData& , + ULONG&, ULONG&, ULONG&, ULONG& ) +{ +} + +// ---------------------------------------------------------------------- + +Hash::Hash( ULONG nSize ) + : nCount( 1 ) +{ + +static const ULONG primes[] = +{ + 509, + 1021, + 2039, + 4093, + 8191, + 16381, + 32749, + 65521, + 131071, + 262139, + 524287, + 1048573, + 2097143, + 4194301, + 8388593, + 16777213, + 33554393, + 67108859, /* Preposterously large . . . */ + 134217689, + 268435399, + 536870909, + 1073741789, + 2147483647, + 0 +}; + + pDataArr = new _HashData[ nSize ]; + pDataArr[0].nNext = 0; + pDataArr[0].nHash = 0, + pDataArr[0].pLine = 0; + + for( int i = 0; primes[i] < nSize / 3; i++) + if( !primes[i] ) + { + pHashArr = 0; + return; + } + nPrime = primes[ i ]; + pHashArr = new ULONG[ nPrime ]; + memset( pHashArr, 0, nPrime * sizeof( ULONG ) ); +} + +Hash::~Hash() +{ + delete pHashArr; + delete pDataArr; +} + +void Hash::CalcHashValue( CompareData& rData ) +{ + if( pHashArr ) + { + for( ULONG n = 0; n < rData.GetLineCount(); ++n ) + { + const CompareLine* pLine = rData.GetLine( n ); + ASSERT( pLine, "wo ist die Line?" ); + ULONG nH = pLine->GetHashValue(); + + ULONG* pFound = &pHashArr[ nH % nPrime ]; + for( ULONG i = *pFound; ; i = pDataArr[i].nNext ) + if( !i ) + { + i = nCount++; + pDataArr[i].nNext = *pFound; + pDataArr[i].nHash = nH; + pDataArr[i].pLine = pLine; + *pFound = i; + break; + } + else if( pDataArr[i].nHash == nH && + pDataArr[i].pLine->Compare( *pLine )) + break; + + rData.SetIndex( n, i ); + } + } +} + +// ---------------------------------------------------------------------- + +Compare::Compare( ULONG nDiff, CompareData& rData1, CompareData& rData2 ) +{ + MovedData *pMD1, *pMD2; + // Suche die unterschiedlichen Lines + { + sal_Char* pDiscard1 = new sal_Char[ rData1.GetLineCount() ]; + sal_Char* pDiscard2 = new sal_Char[ rData2.GetLineCount() ]; + + ULONG* pCount1 = new ULONG[ nDiff ]; + ULONG* pCount2 = new ULONG[ nDiff ]; + memset( pCount1, 0, nDiff * sizeof( ULONG )); + memset( pCount2, 0, nDiff * sizeof( ULONG )); + + // stelle fest, welche Indizies in den CompareData mehrfach vergeben wurden + CountDifference( rData1, pCount1 ); + CountDifference( rData2, pCount2 ); + + // alle die jetzt nur einmal vorhanden sind, sind eingefuegt oder + // geloescht worden. Alle die im anderen auch vorhanden sind, sind + // verschoben worden + SetDiscard( rData1, pDiscard1, pCount2 ); + SetDiscard( rData2, pDiscard2, pCount1 ); + + // die Arrays koennen wir wieder vergessen + delete pCount1; delete pCount2; + + CheckDiscard( rData1.GetLineCount(), pDiscard1 ); + CheckDiscard( rData2.GetLineCount(), pDiscard2 ); + + pMD1 = new MovedData( rData1, pDiscard1 ); + pMD2 = new MovedData( rData2, pDiscard2 ); + + // die Arrays koennen wir wieder vergessen + delete pDiscard1; delete pDiscard2; + } + + { + CompareSequence aTmp( rData1, rData2, *pMD1, *pMD2 ); + } + + ShiftBoundaries( rData1, rData2 ); + + delete pMD1; + delete pMD2; +} + + + +void Compare::CountDifference( const CompareData& rData, ULONG* pCounts ) +{ + ULONG nLen = rData.GetLineCount(); + for( ULONG n = 0; n < nLen; ++n ) + { + ULONG nIdx = rData.GetIndex( n ); + ++pCounts[ nIdx ]; + } +} + +void Compare::SetDiscard( const CompareData& rData, + sal_Char* pDiscard, ULONG* pCounts ) +{ + ULONG nLen = rData.GetLineCount(); + + // berechne Max in Abhanegigkeit zur LineAnzahl + USHORT nMax = 5; + for( ULONG n = nLen / 64; ( n = n >> 2 ) > 0; ) + nMax <<= 1; + + for( n = 0; n < nLen; ++n ) + { + ULONG nIdx = rData.GetIndex( n ); + if( nIdx ) + { + nIdx = pCounts[ nIdx ]; + pDiscard[ n ] = !nIdx ? 1 : nIdx > nMax ? 2 : 0; + } + else + pDiscard[ n ] = 0; + } +} + +void Compare::CheckDiscard( ULONG nLen, sal_Char* pDiscard ) +{ + for( ULONG n = 0; n < nLen; ++n ) + { + if( 2 == pDiscard[ n ] ) + pDiscard[n] = 0; + else if( pDiscard[ n ] ) + { + register ULONG j; + ULONG length; + ULONG provisional = 0; + + /* Find end of this run of discardable lines. + Count how many are provisionally discardable. */ + for (j = n; j < nLen; j++) + { + if( !pDiscard[j] ) + break; + if( 2 == pDiscard[j] ) + ++provisional; + } + + /* Cancel provisional discards at end, and shrink the run. */ + while( j > n && 2 == pDiscard[j - 1] ) + pDiscard[ --j ] = 0, --provisional; + + /* Now we have the length of a run of discardable lines + whose first and last are not provisional. */ + length = j - n; + + /* If 1/4 of the lines in the run are provisional, + cancel discarding of all provisional lines in the run. */ + if (provisional * 4 > length) + { + while (j > n) + if (pDiscard[--j] == 2) + pDiscard[j] = 0; + } + else + { + register ULONG consec; + ULONG minimum = 1; + ULONG tem = length / 4; + + /* MINIMUM is approximate square root of LENGTH/4. + A subrun of two or more provisionals can stand + when LENGTH is at least 16. + A subrun of 4 or more can stand when LENGTH >= 64. */ + while ((tem = tem >> 2) > 0) + minimum *= 2; + minimum++; + + /* Cancel any subrun of MINIMUM or more provisionals + within the larger run. */ + for (j = 0, consec = 0; j < length; j++) + if (pDiscard[n + j] != 2) + consec = 0; + else if (minimum == ++consec) + /* Back up to start of subrun, to cancel it all. */ + j -= consec; + else if (minimum < consec) + pDiscard[n + j] = 0; + + /* Scan from beginning of run + until we find 3 or more nonprovisionals in a row + or until the first nonprovisional at least 8 lines in. + Until that point, cancel any provisionals. */ + for (j = 0, consec = 0; j < length; j++) + { + if (j >= 8 && pDiscard[n + j] == 1) + break; + if (pDiscard[n + j] == 2) + consec = 0, pDiscard[n + j] = 0; + else if (pDiscard[n + j] == 0) + consec = 0; + else + consec++; + if (consec == 3) + break; + } + + /* I advances to the last line of the run. */ + n += length - 1; + + /* Same thing, from end. */ + for (j = 0, consec = 0; j < length; j++) + { + if (j >= 8 && pDiscard[n - j] == 1) + break; + if (pDiscard[n - j] == 2) + consec = 0, pDiscard[n - j] = 0; + else if (pDiscard[n - j] == 0) + consec = 0; + else + consec++; + if (consec == 3) + break; + } + } + } + } +} + +// ---------------------------------------------------------------------- + +Compare::MovedData::MovedData( CompareData& rData, sal_Char* pDiscard ) + : pIndex( 0 ), pLineNum( 0 ), nCount( 0 ) +{ + ULONG nLen = rData.GetLineCount(); + for( ULONG n = 0; n < nLen; ++n ) + if( pDiscard[ n ] ) + rData.SetChanged( n ); + else + ++nCount; + + if( nCount ) + { + pIndex = new ULONG[ nCount ]; + pLineNum = new ULONG[ nCount ]; + + for( n = 0, nCount = 0; n < nLen; ++n ) + if( !pDiscard[ n ] ) + { + pIndex[ nCount ] = rData.GetIndex( n ); + pLineNum[ nCount++ ] = n; + } + } +} + +Compare::MovedData::~MovedData() +{ + delete pIndex; + delete pLineNum; +} + +// ---------------------------------------------------------------------- + + // Suche die verschobenen Lines +Compare::CompareSequence::CompareSequence( + CompareData& rD1, CompareData& rD2, + const MovedData& rMD1, const MovedData& rMD2 ) + : rData1( rD1 ), rData2( rD2 ), rMoved1( rMD1 ), rMoved2( rMD2 ) +{ + ULONG nSize = rMD1.GetCount() + rMD2.GetCount() + 3; + pMemory = new long[ nSize * 2 ]; + pFDiag = pMemory + ( rMD2.GetCount() + 1 ); + pBDiag = pMemory + ( nSize + rMD2.GetCount() + 1 ); + +#ifdef JP_DUMP + rD1.Dump(), rD2.Dump(); +#endif + Compare( 0, rMD1.GetCount(), 0, rMD2.GetCount() ); +} + +Compare::CompareSequence::~CompareSequence() +{ + delete pMemory; +} + +void Compare::CompareSequence::Compare( ULONG nStt1, ULONG nEnd1, + ULONG nStt2, ULONG nEnd2 ) +{ + /* Slide down the bottom initial diagonal. */ + while( nStt1 < nEnd1 && nStt2 < nEnd2 && + rMoved1.GetIndex( nStt1 ) == rMoved2.GetIndex( nStt2 )) + ++nStt1, ++nStt2; + + /* Slide up the top initial diagonal. */ + while( nEnd1 > nStt1 && nEnd2 > nStt2 && + rMoved1.GetIndex( nEnd1 - 1 ) == rMoved2.GetIndex( nEnd2 - 1 )) + --nEnd1, --nEnd2; + + /* Handle simple cases. */ + if( nStt1 == nEnd1 ) + while( nStt2 < nEnd2 ) + rData2.SetChanged( rMoved2.GetLineNum( nStt2++ )); + + else if (nStt2 == nEnd2) + while (nStt1 < nEnd1) + rData1.SetChanged( rMoved1.GetLineNum( nStt1++ )); + + else + { + ULONG c, d, b; + + /* Find a point of correspondence in the middle of the files. */ + + d = CheckDiag( nStt1, nEnd1, nStt2, nEnd2, &c ); + b = pBDiag[ d ]; + + if( 1 != c ) + { + /* Use that point to split this problem into two subproblems. */ + Compare( nStt1, b, nStt2, b - d ); + /* This used to use f instead of b, + but that is incorrect! + It is not necessarily the case that diagonal d + has a snake from b to f. */ + Compare( b, nEnd1, b - d, nEnd2 ); + } + } +} + +ULONG Compare::CompareSequence::CheckDiag( ULONG nStt1, ULONG nEnd1, + ULONG nStt2, ULONG nEnd2, ULONG* pCost ) +{ + const long dmin = nStt1 - nEnd2; /* Minimum valid diagonal. */ + const long dmax = nEnd1 - nStt2; /* Maximum valid diagonal. */ + const long fmid = nStt1 - nStt2; /* Center diagonal of top-down search. */ + const long bmid = nEnd1 - nEnd2; /* Center diagonal of bottom-up search. */ + + long fmin = fmid, fmax = fmid; /* Limits of top-down search. */ + long bmin = bmid, bmax = bmid; /* Limits of bottom-up search. */ + + long c; /* Cost. */ + long odd = (fmid - bmid) & 1; /* True if southeast corner is on an odd + diagonal with respect to the northwest. */ + + pFDiag[fmid] = nStt1; + pBDiag[bmid] = nEnd1; + + for (c = 1;; ++c) + { + long d; /* Active diagonal. */ + long big_snake = 0; + + /* Extend the top-down search by an edit step in each diagonal. */ + fmin > dmin ? pFDiag[--fmin - 1] = -1 : ++fmin; + fmax < dmax ? pFDiag[++fmax + 1] = -1 : --fmax; + for (d = fmax; d >= fmin; d -= 2) + { + long x, y, oldx, tlo = pFDiag[d - 1], thi = pFDiag[d + 1]; + + if (tlo >= thi) + x = tlo + 1; + else + x = thi; + oldx = x; + y = x - d; + while( ULONG(x) < nEnd1 && ULONG(y) < nEnd2 && + rMoved1.GetIndex( x ) == rMoved2.GetIndex( y )) + ++x, ++y; + if (x - oldx > 20) + big_snake = 1; + pFDiag[d] = x; + if( odd && bmin <= d && d <= bmax && pBDiag[d] <= pFDiag[d] ) + { + *pCost = 2 * c - 1; + return d; + } + } + + /* Similar extend the bottom-up search. */ + bmin > dmin ? pBDiag[--bmin - 1] = INT_MAX : ++bmin; + bmax < dmax ? pBDiag[++bmax + 1] = INT_MAX : --bmax; + for (d = bmax; d >= bmin; d -= 2) + { + long x, y, oldx, tlo = pBDiag[d - 1], thi = pBDiag[d + 1]; + + if (tlo < thi) + x = tlo; + else + x = thi - 1; + oldx = x; + y = x - d; + while( ULONG(x) > nStt1 && ULONG(y) > nStt2 && + rMoved1.GetIndex( x - 1 ) == rMoved2.GetIndex( y - 1 )) + --x, --y; + if (oldx - x > 20) + big_snake = 1; + pBDiag[d] = x; + if (!odd && fmin <= d && d <= fmax && pBDiag[d] <= pFDiag[d]) + { + *pCost = 2 * c; + return d; + } + } + } +} + +void Compare::ShiftBoundaries( CompareData& rData1, CompareData& rData2 ) +{ + for( int i = 0; i < 2; ++i ) + { + CompareData* pData = &rData1; + CompareData* pOtherData = &rData2; + + ULONG i = 0; + ULONG j = 0; + ULONG i_end = pData->GetLineCount(); + ULONG preceding = ULONG_MAX; + ULONG other_preceding = ULONG_MAX; + + while (1) + { + ULONG start, other_start; + + /* Scan forwards to find beginning of another run of changes. + Also keep track of the corresponding point in the other file. */ + + while( i < i_end && !pData->GetChanged( i ) ) + { + while( pOtherData->GetChanged( j++ )) + /* Non-corresponding lines in the other file + will count as the preceding batch of changes. */ + other_preceding = j; + i++; + } + + if (i == i_end) + break; + + start = i; + other_start = j; + + while (1) + { + /* Now find the end of this run of changes. */ + + while( pData->GetChanged( ++i )) + ; + + /* If the first changed line matches the following unchanged one, + and this run does not follow right after a previous run, + and there are no lines deleted from the other file here, + then classify the first changed line as unchanged + and the following line as changed in its place. */ + + /* You might ask, how could this run follow right after another? + Only because the previous run was shifted here. */ + + if( i != i_end && + pData->GetIndex( start ) == pData->GetIndex( i ) && + !pOtherData->GetChanged( j ) && + !( start == preceding || other_start == other_preceding )) + { + pData->SetChanged( start++, 0 ); + pData->SetChanged( i ); + /* Since one line-that-matches is now before this run + instead of after, we must advance in the other file + to keep in synch. */ + ++j; + } + else + break; + } + + preceding = i; + other_preceding = j; + } + + pData = &rData2; + pOtherData = &rData1; + } +} + +/* */ + +inline ULONG NextIdx( const SwNode* pNd ) +{ + if( pNd->IsStartNode() ) + pNd = pNd->EndOfSectionNode(); + return pNd->GetIndex() + 1; +} + +inline ULONG PrevIdx( const SwNode* pNd ) +{ + if( pNd->IsEndNode() ) + pNd = pNd->StartOfSectionNode(); + return pNd->GetIndex() - 1; +} + +class SwCompareLine : public CompareLine +{ + const SwNode& rNode; +public: + SwCompareLine( const SwNode& rNd ); + virtual ~SwCompareLine(); + + virtual ULONG GetHashValue() const; + virtual BOOL Compare( const CompareLine& rLine ) const; + + static ULONG GetTxtNodeHashValue( const SwTxtNode& rNd, ULONG nVal ); + static BOOL CompareNode( const SwNode& rDstNd, const SwNode& rSrcNd ); + static BOOL CompareTxtNd( const SwTxtNode& rDstNd, + const SwTxtNode& rSrcNd ); + + BOOL ChangesInLine( const SwCompareLine& rLine, + SwPaM *& rpInsRing, SwPaM*& rpDelRing ) const; + + const SwNode& GetNode() const { return rNode; } + + const SwNode& GetEndNode() const; + + // fuers Debugging! + String GetText() const; +}; + +class SwCompareData : public CompareData +{ + SwDoc& rDoc; + SwPaM *pInsRing, *pDelRing; + + virtual void CheckRanges( CompareData& ); + virtual void ShowInsert( ULONG nStt, ULONG nEnd ); + virtual void ShowDelete( const CompareData& rData, ULONG nStt, + ULONG nEnd, ULONG nInsPos ); + + virtual void CheckForChangesInLine( const CompareData& rData, + ULONG& nStt, ULONG& nEnd, + ULONG& nThisStt, ULONG& nThisEnd ); + +public: + SwCompareData( SwDoc& rD ) : rDoc( rD ), pInsRing(0), pDelRing(0) {} + virtual ~SwCompareData(); + + void SetRedlinesToDoc(); + +#ifdef JP_DUMP + // zum Debuggen! + virtual void Dump(); +#endif +}; + +// ---------------------------------------------------------------- + +SwCompareLine::SwCompareLine( const SwNode& rNd ) + : rNode( rNd ) +{ +} + +SwCompareLine::~SwCompareLine() +{ +} + +ULONG SwCompareLine::GetHashValue() const +{ + ULONG nRet = 0; + switch( rNode.GetNodeType() ) + { + case ND_TEXTNODE: + nRet = GetTxtNodeHashValue( (SwTxtNode&)rNode, nRet ); + break; + + case ND_TABLENODE: + { + const SwNode* pEndNd = rNode.EndOfSectionNode(); + SwNodeIndex aIdx( rNode ); + while( &aIdx.GetNode() != pEndNd ) + { + if( aIdx.GetNode().IsTxtNode() ) + nRet = GetTxtNodeHashValue( (SwTxtNode&)aIdx.GetNode(), nRet ); + aIdx++; + } + } + break; + + case ND_SECTIONNODE: + // sollte nie auftauchen (oder?) + break; + + case ND_GRFNODE: + case ND_OLENODE: + // feste Id ? sollte aber nie auftauchen + break; + } + return nRet; +} + +const SwNode& SwCompareLine::GetEndNode() const +{ + const SwNode* pNd = &rNode; + switch( rNode.GetNodeType() ) + { + case ND_TABLENODE: + pNd = rNode.EndOfSectionNode(); + break; + + case ND_SECTIONNODE: + // sollte nie auftauchen (oder?) + break; + } + return *pNd; +} + +BOOL SwCompareLine::Compare( const CompareLine& rLine ) const +{ + return CompareNode( rNode, ((SwCompareLine&)rLine).rNode ); +} + +BOOL SwCompareLine::CompareNode( const SwNode& rDstNd, const SwNode& rSrcNd ) +{ + BOOL bRet = FALSE; + + switch( ( rSrcNd.GetNodeType() * 256 ) + rDstNd.GetNodeType() ) + { + case ( ND_TEXTNODE * 256 ) + ND_TEXTNODE: + bRet = CompareTxtNd( (SwTxtNode&)rDstNd, (SwTxtNode&)rSrcNd ); + break; + + case ( ND_TABLENODE * 256 ) + ND_TABLENODE: + { + const SwTableNode& rTSrcNd = (SwTableNode&)rSrcNd; + const SwTableNode& rTDstNd = (SwTableNode&)rDstNd; + + bRet = ( rTSrcNd.EndOfSectionIndex() - rTSrcNd.GetIndex() ) == + ( rTDstNd.EndOfSectionIndex() - rTDstNd.GetIndex() ); + } + break; + + case ( ND_SECTIONNODE * 256 ) + ND_SECTIONNODE: + { + const SwSectionNode& rSSrcNd = (SwSectionNode&)rSrcNd; + const SwSectionNode& rSDstNd = (SwSectionNode&)rDstNd; + + bRet = ( rSSrcNd.EndOfSectionIndex() - rSSrcNd.GetIndex() ) == + ( rSDstNd.EndOfSectionIndex() - rSDstNd.GetIndex() ); + } + break; + + case ( ND_ENDNODE * 256 ) + ND_ENDNODE: + if( rSrcNd.FindStartNode()->IsTableNode() && + rDstNd.FindStartNode()->IsTableNode() ) + { + + } + else if( rSrcNd.FindStartNode()->IsTableNode() && + rDstNd.FindStartNode()->IsTableNode() ) + { + } + break; + } + return bRet; +} + +String SwCompareLine::GetText() const +{ + String sRet; + switch( rNode.GetNodeType() ) + { + case ND_TEXTNODE: + sRet = ((SwTxtNode&)rNode).GetExpandTxt(); + break; + + case ND_TABLENODE: + { + const SwNode* pEndNd = rNode.EndOfSectionNode(); + SwNodeIndex aIdx( rNode ); + while( &aIdx.GetNode() != pEndNd ) + { + if( aIdx.GetNode().IsTxtNode() ) + { + if( sRet.Len() ) + sRet.Append( '\n' ); + sRet.Append( ((SwTxtNode&)rNode).GetExpandTxt() ); + } + aIdx++; + } + sRet.InsertAscii( "Tabelle: ", 0 ); + } + break; + + case ND_SECTIONNODE: + sRet.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "Section - Node:" )); + break; + + case ND_GRFNODE: + sRet.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "Grafik - Node:" )); + break; + case ND_OLENODE: + sRet.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "OLE - Node:" )); + break; + } + return sRet; +} + +ULONG SwCompareLine::GetTxtNodeHashValue( const SwTxtNode& rNd, ULONG nVal ) +{ + String sStr( rNd.GetExpandTxt() ); + for( xub_StrLen n = 0; n < sStr.Len(); ++n ) + ( nVal <<= 1 ) += sStr.GetChar( n ); + return nVal; +} + +BOOL SwCompareLine::CompareTxtNd( const SwTxtNode& rDstNd, + const SwTxtNode& rSrcNd ) +{ + BOOL bRet = FALSE; + // erstmal ganz einfach! + if( rDstNd.GetTxt() == rSrcNd.GetTxt() ) + { + // der Text ist gleich, aber sind die "Sonderattribute" (0xFF) auch + // dieselben?? + bRet = TRUE; + } + return bRet; +} + +BOOL SwCompareLine::ChangesInLine( const SwCompareLine& rLine, + SwPaM *& rpInsRing, SwPaM*& rpDelRing ) const +{ + BOOL bRet = FALSE; + if( ND_TEXTNODE == rNode.GetNodeType() && + ND_TEXTNODE == rLine.GetNode().GetNodeType() ) + { + SwTxtNode& rDestNd = *(SwTxtNode*)rNode.GetTxtNode(); + const SwTxtNode& rSrcNd = *rLine.GetNode().GetTxtNode(); + + xub_StrLen nDEnd = rDestNd.GetTxt().Len(), nSEnd = rSrcNd.GetTxt().Len(); + for( xub_StrLen nStt = 0, nEnd = Min( nDEnd, nSEnd ); + nStt < nEnd; ++nStt ) + if( rDestNd.GetTxt().GetChar( nStt ) != + rSrcNd.GetTxt().GetChar( nStt ) ) + break; + + while( nStt < nDEnd && nStt < nSEnd ) + { + --nDEnd, --nSEnd; + if( rDestNd.GetTxt().GetChar( nDEnd ) != + rSrcNd.GetTxt().GetChar( nSEnd ) ) + { + ++nDEnd, ++nSEnd; + break; + } + } + + if( nStt || !nDEnd || !nSEnd || nDEnd < rDestNd.GetTxt().Len() || + nSEnd < rSrcNd.GetTxt().Len() ) + { + // 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 ) + { + SwPaM* pTmp = new SwPaM( *aPam.GetPoint(), rpInsRing ); + if( !rpInsRing ) + rpInsRing = pTmp; + + pTmp->SetMark(); + pTmp->GetMark()->nContent = nStt; + } + + if( nStt != nSEnd ) + { + { + 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 ); + if( !rpDelRing ) + rpDelRing = pTmp; + + pTmp->SetMark(); + pTmp->GetMark()->nContent = nDEnd; + + if( rpInsRing ) + { + SwPaM* pCorr = (SwPaM*)rpInsRing->GetPrev(); + if( *pCorr->GetPoint() == *pTmp->GetPoint() ) + *pCorr->GetPoint() = *pTmp->GetMark(); + } + } + bRet = TRUE; + } + } + return bRet; +} + +// ---------------------------------------------------------------- + +SwCompareData::~SwCompareData() +{ + if( pDelRing ) + { + while( pDelRing->GetNext() != pDelRing ) + delete pDelRing->GetNext(); + delete pDelRing; + } + if( pInsRing ) + { + while( pInsRing->GetNext() != pInsRing ) + delete pInsRing->GetNext(); + delete pInsRing; + } +} + +void SwCompareData::CheckRanges( CompareData& rData ) +{ + const SwNodes& rSrcNds = ((SwCompareData&)rData).rDoc.GetNodes(); + const SwNodes& rDstNds = rDoc.GetNodes(); + + const SwNode& rSrcEndNd = rSrcNds.GetEndOfContent(); + const SwNode& rDstEndNd = rDstNds.GetEndOfContent(); + + SwNodeIndex aSrcIdx( *rSrcEndNd.FindStartNode(), 1 ); + SwNodeIndex aDstIdx( *rDstEndNd.FindStartNode(), 1 ); + + ULONG nSrcSttIdx = aSrcIdx.GetIndex(); + ULONG nSrcEndIdx = rSrcEndNd.GetIndex(); + + ULONG nDstSttIdx = aDstIdx.GetIndex(); + ULONG nDstEndIdx = rDstEndNd.GetIndex(); + + while( nSrcSttIdx < nSrcEndIdx && nDstSttIdx < nDstEndIdx ) + { + const SwNode* pSrcNd = rSrcNds[ nSrcSttIdx ]; + const SwNode* pDstNd = rDstNds[ nDstSttIdx ]; + if( !SwCompareLine::CompareNode( *pSrcNd, *pDstNd )) + break; + + nSrcSttIdx = NextIdx( pSrcNd ); + nDstSttIdx = NextIdx( pDstNd ); + } + + --nSrcEndIdx; + --nDstEndIdx; + while( nSrcSttIdx < nSrcEndIdx && nDstSttIdx < nDstEndIdx ) + { + const SwNode* pSrcNd = rSrcNds[ nSrcEndIdx ]; + const SwNode* pDstNd = rDstNds[ nDstEndIdx ]; + if( !SwCompareLine::CompareNode( *pSrcNd, *pDstNd )) + break; + + nSrcEndIdx = PrevIdx( pSrcNd ); + nDstEndIdx = PrevIdx( pDstNd ); + } + + while( nSrcSttIdx <= nSrcEndIdx ) + { + const SwNode* pNd = rSrcNds[ nSrcSttIdx ]; + rData.InsertLine( new SwCompareLine( *pNd ) ); + nSrcSttIdx = NextIdx( pNd ); + } + + while( nDstSttIdx <= nDstEndIdx ) + { + const SwNode* pNd = rDstNds[ nDstSttIdx ]; + InsertLine( new SwCompareLine( *pNd ) ); + nDstSttIdx = NextIdx( pNd ); + } +} + + +void SwCompareData::ShowInsert( ULONG nStt, ULONG nEnd ) +{ + SwPaM* pTmp = new SwPaM( ((SwCompareLine*)GetLine( nStt ))->GetNode(), 0, + ((SwCompareLine*)GetLine( nEnd-1 ))->GetEndNode(), 0, + pInsRing ); + if( !pInsRing ) + pInsRing = pTmp; + +// vom Anfang des 1. Absatzes (1. Buchstabe) bis +// zum letzten Absatz (letzter Buchstabe!) + pTmp->GetPoint()->nNode++; + pTmp->GetPoint()->nContent.Assign( pTmp->GetCntntNode(), 0 ); +} + +void SwCompareData::ShowDelete( const CompareData& rData, ULONG nStt, + ULONG nEnd, ULONG nInsPos ) +{ + SwNodeRange aRg( + ((SwCompareLine*)rData.GetLine( nStt ))->GetNode(), 0, + ((SwCompareLine*)rData.GetLine( nEnd-1 ))->GetEndNode(), 1 ); + + USHORT nOffset = 0; + const CompareLine* pLine; + if( GetLineCount() == nInsPos ) + { + pLine = GetLine( nInsPos-1 ); + nOffset = 1; + } + else + pLine = GetLine( nInsPos ); + + const SwNode* pLineNd; + if( pLine ) + pLineNd = &((SwCompareLine*)pLine)->GetNode(); + else + { + pLineNd = &rDoc.GetNodes().GetEndOfContent(); + nOffset = 0; + } + + SwNodeIndex aInsPos( *pLineNd, nOffset ); + SwNodeIndex aSavePos( aInsPos, -1 ); + + ((SwCompareData&)rData).rDoc.CopyWithFlyInFly( aRg, aInsPos ); + + aSavePos++; + + SwPaM* pTmp = new SwPaM( aSavePos.GetNode(), aInsPos.GetNode(), 0, 0, + pDelRing ); + if( !pDelRing ) + pDelRing = pTmp; + + if( pInsRing ) + { + SwPaM* pCorr = (SwPaM*)pInsRing->GetPrev(); + if( *pCorr->GetPoint() == *pTmp->GetPoint() ) + *pCorr->GetPoint() = *pTmp->GetMark(); + } +} + +void SwCompareData::CheckForChangesInLine( const CompareData& rData, + ULONG& rStt, ULONG& rEnd, + ULONG& rThisStt, ULONG& rThisEnd ) +{ + while( rStt < rEnd && rThisStt < rThisEnd ) + { + SwCompareLine* pDstLn = (SwCompareLine*)GetLine( rThisStt ); + SwCompareLine* pSrcLn = (SwCompareLine*)rData.GetLine( rStt ); + if( !pDstLn->ChangesInLine( *pSrcLn, pInsRing, pDelRing ) ) + break; + + ++rStt; + ++rThisStt; + } +} + +void SwCompareData::SetRedlinesToDoc() +{ + SwPaM* pTmp = pDelRing; + if( pTmp ) + do { + rDoc.DeleteRedline( *pTmp, FALSE ); + + if( rDoc.DoesUndo() ) + rDoc.AppendUndo( new SwUndoCompDoc( *pTmp, FALSE )); + rDoc.AppendRedline( new SwRedline( REDLINE_DELETE, *pTmp ) ); + + } while( pDelRing != ( pTmp = (SwPaM*)pTmp->GetNext() )); + + pTmp = pInsRing; + if( pTmp ) + { + // zusammenhaengende zusammenfassen + if( pTmp->GetNext() != pInsRing ) + { + const SwCntntNode* pCNd; + do { + SwPosition& rSttEnd = *pTmp->End(), + & rEndStt = *((SwPaM*)pTmp->GetNext())->Start(); + if( rSttEnd == rEndStt || + (!rEndStt.nContent.GetIndex() && + rEndStt.nNode.GetIndex() - 1 == rSttEnd.nNode.GetIndex() && + 0 != ( pCNd = rSttEnd.nNode.GetNode().GetCntntNode() ) + ? rSttEnd.nContent.GetIndex() == pCNd->Len() + : 0 )) + { + if( pTmp->GetNext() == pInsRing ) + { + // liegen hintereinander also zusammen fassen + rEndStt = *pTmp->Start(); + delete pTmp; + pTmp = pInsRing; + } + else + { + // liegen hintereinander also zusammen fassen + rSttEnd = *((SwPaM*)pTmp->GetNext())->End(); + delete pTmp->GetNext(); + } + } + else + pTmp = (SwPaM*)pTmp->GetNext(); + } while( pInsRing != pTmp ); + } + + do { + if( rDoc.AppendRedline( new SwRedline( REDLINE_INSERT, *pTmp )) && + rDoc.DoesUndo() ) + rDoc.AppendUndo( new SwUndoCompDoc( *pTmp, TRUE )); + } while( pInsRing != ( pTmp = (SwPaM*)pTmp->GetNext() )); + } +} + +#ifdef JP_DUMP +void SwCompareData::Dump() +{ + static int nFirst = 1; + SvFileStream aStrm( "d:\\tmp\\compare.dmp", nFirst + ? STREAM_WRITE | STREAM_TRUNC + : STREAM_WRITE | STREAM_NOCREATE ); + if( !nFirst ) + aStrm.Seek( STREAM_SEEK_TO_END ); + + nFirst = 0; + + aStrm << "\n"; + ULONG nLCount = aLines.Count(); + for( ULONG n = 0; n < nLCount; ++n ) + { + SwCompareLine* pLine = (SwCompareLine*)GetLine( n ); + String sTxt( pLine->GetText() ); + char sBuffer[ 20 ]; + sprintf( sBuffer, "[%4ld][%3ld][%1d]", + pLine->GetNode().GetIndex(), + GetIndex( n ), GetChanged( n ) ); + ( aStrm << sBuffer ).WriteByteString( sTxt ) << '\n'; + } +} + +#endif + +/* */ + + + + // returnt (?die Anzahl der Unterschiede?) ob etwas unterschiedlich ist +long SwDoc::CompareDoc( const SwDoc& rDoc ) +{ + if( &rDoc == this ) + return 0; + + long nRet = 0; + + StartUndo(); + + SwDoc& rSrcDoc = (SwDoc&)rDoc; + BOOL bSrcModified = rSrcDoc.IsModified(); + + SwRedlineMode eSrcRedlMode = rSrcDoc.GetRedlineMode(); + rSrcDoc.SetRedlineMode( REDLINE_SHOW_INSERT ); + SetRedlineMode( REDLINE_ON | REDLINE_SHOW_INSERT ); + + SwCompareData aD0( rSrcDoc ); + SwCompareData aD1( *this ); + + aD1.CompareLines( aD0 ); + + nRet = aD1.ShowDiffs( aD0 ); + + if( nRet ) + { + SetRedlineMode( REDLINE_ON | REDLINE_SHOW_INSERT | REDLINE_SHOW_DELETE ); + aD1.SetRedlinesToDoc(); + } + +#ifdef JP_DUMP + aD0.Dump(), aD1.Dump(); +#endif + + rSrcDoc.SetRedlineMode( eSrcRedlMode ); + SetRedlineMode( REDLINE_SHOW_INSERT | REDLINE_SHOW_DELETE ); + + if( !bSrcModified ) + rSrcDoc.ResetModified(); + + EndUndo(); + + return nRet; +} + + +typedef void (SwDoc::*FNInsUndo)( SwUndo* ); + +class _SaveMergeRedlines : public Ring +{ + const SwRedline* pSrcRedl; + SwRedline* pDestRedl; +public: + _SaveMergeRedlines( const SwNode& rDstNd, + const SwRedline& rSrcRedl, Ring* pRing ); + USHORT InsertRedline( FNInsUndo pFn ); + + SwRedline* GetDestRedline() { return pDestRedl; } +}; + +_SaveMergeRedlines::_SaveMergeRedlines( const SwNode& rDstNd, + const SwRedline& rSrcRedl, Ring* pRing ) + : Ring( pRing ), pSrcRedl( &rSrcRedl ) +{ + SwPosition aPos( rDstNd ); + + const SwPosition* pStt = rSrcRedl.Start(); + if( rDstNd.IsCntntNode() ) + aPos.nContent.Assign( ((SwCntntNode*)&rDstNd), pStt->nContent.GetIndex() ); + pDestRedl = new SwRedline( rSrcRedl.GetRedlineData(), aPos ); + + if( REDLINE_DELETE == pDestRedl->GetType() ) + { + // den Bereich als geloescht kennzeichnen + const SwPosition* pEnd = pStt == rSrcRedl.GetPoint() + ? rSrcRedl.GetMark() + : rSrcRedl.GetPoint(); + + pDestRedl->SetMark(); + pDestRedl->GetPoint()->nNode += pEnd->nNode.GetIndex() - + pStt->nNode.GetIndex(); + pDestRedl->GetPoint()->nContent.Assign( pDestRedl->GetCntntNode(), + pEnd->nContent.GetIndex() ); + } +} + +USHORT _SaveMergeRedlines::InsertRedline( FNInsUndo pFn ) +{ + USHORT nIns = 0; + SwDoc* pDoc = pDestRedl->GetDoc(); + + if( REDLINE_INSERT == pDestRedl->GetType() ) + { + // der Teil wurde eingefuegt, also kopiere ihn aus dem SourceDoc + BOOL bUndo = pDoc->DoesUndo(); + pDoc->DoUndo( FALSE ); + + SwNodeIndex aSaveNd( pDestRedl->GetPoint()->nNode, -1 ); + xub_StrLen nSaveCnt = pDestRedl->GetPoint()->nContent.GetIndex(); + + SwRedlineMode eOld = pDoc->GetRedlineMode(); + pDoc->SetRedlineMode_intern( eOld | REDLINE_IGNORE ); + + pSrcRedl->GetDoc()->Copy( *(SwPaM*)pSrcRedl, *pDestRedl->GetPoint() ); + + pDoc->SetRedlineMode_intern( eOld ); + pDoc->DoUndo( bUndo ); + + pDestRedl->SetMark(); + aSaveNd++; + pDestRedl->GetMark()->nNode = aSaveNd; + pDestRedl->GetMark()->nContent.Assign( aSaveNd.GetNode().GetCntntNode(), + nSaveCnt ); + + SwPaM* pPrev = ((_SaveMergeRedlines*)GetPrev())->pDestRedl; + if( pPrev && *pPrev->GetPoint() == *pDestRedl->GetPoint() ) + *pPrev->GetPoint() == *pDestRedl->GetMark(); + + } + else + { + //JP 21.09.98: Bug 55909 + // falls im Doc auf gleicher Pos aber schon ein geloeschter oder + // eingefuegter ist, dann muss dieser gesplittet werden! + SwPosition* pDStt = pDestRedl->GetMark(), + * pDEnd = pDestRedl->GetPoint(); + USHORT n = 0; + + // zur StartPos das erste Redline suchen + if( !pDoc->GetRedline( *pDStt, &n ) && n ) + --n; + + const SwRedlineTbl& rRedlineTbl = pDoc->GetRedlineTbl(); + for( ; n < rRedlineTbl.Count(); ++n ) + { + SwRedline* pRedl = rRedlineTbl[ n ]; + SwPosition* pRStt = pRedl->Start(), + * pREnd = pRStt == pRedl->GetPoint() ? pRedl->GetMark() + : pRedl->GetPoint(); + if( REDLINE_DELETE == pRedl->GetType() || + REDLINE_INSERT == pRedl->GetType() ) + { + SwComparePosition eCmpPos = ComparePosition( *pDStt, *pDEnd, *pRStt, *pREnd ); + switch( eCmpPos ) + { + case POS_BEHIND: + break; + + case POS_INSIDE: + case POS_EQUAL: + delete pDestRedl, pDestRedl = 0; + // break; -> kein break !!!! + + case POS_BEFORE: + n = rRedlineTbl.Count(); + break; + + case POS_OUTSIDE: + { + SwRedline* pCpyRedl = new SwRedline( + pDestRedl->GetRedlineData(), *pDStt ); + pCpyRedl->SetMark(); + *pCpyRedl->GetPoint() = *pRStt; + + SwUndoCompDoc* pUndo = pDoc->DoesUndo() + ? new SwUndoCompDoc( *pCpyRedl ) : 0; + if( pDoc->AppendRedline( pCpyRedl ) ) + { + ++nIns; + if( pUndo ) + (pDoc->*pFn)( pUndo ); + } + else + delete pUndo; + + *pDStt = *pREnd; + + // dann solle man neu anfangen + n = USHRT_MAX; + } + break; + + case POS_OVERLAP_BEFORE: + *pDEnd = *pRStt; + break; + + case POS_OVERLAP_BEHIND: + *pDStt = *pREnd; + break; + } + } + else if( *pDEnd <= *pRStt ) + break; + } + + } + + if( pDestRedl ) + { + SwUndoCompDoc* pUndo = pDoc->DoesUndo() ? new SwUndoCompDoc( *pDestRedl ) : 0; + if( pDoc->AppendRedline( pDestRedl ) ) + { + ++nIns; + if( pUndo ) + (pDoc->*pFn)( pUndo ); + } + else + delete pUndo; + } + return nIns; +} + +// merge zweier Dokumente +long SwDoc::MergeDoc( const SwDoc& rDoc ) +{ + if( &rDoc == this ) + return 0; + + long nRet = 0; + + StartUndo(); + + SwDoc& rSrcDoc = (SwDoc&)rDoc; + BOOL bSrcModified = rSrcDoc.IsModified(); + + SwRedlineMode eSrcRedlMode = rSrcDoc.GetRedlineMode(); + rSrcDoc.SetRedlineMode( REDLINE_SHOW_DELETE ); + SetRedlineMode( REDLINE_SHOW_DELETE ); + + SwCompareData aD0( rSrcDoc ); + SwCompareData aD1( *this ); + + aD1.CompareLines( aD0 ); + + if( !aD1.HasDiffs( aD0 ) ) + { + // jetzt wollen wir alle Redlines aus dem SourceDoc zu uns bekommen + + // suche alle Insert - Redlines aus dem SourceDoc und bestimme + // deren Position im DestDoc + _SaveMergeRedlines* pRing = 0; + const SwRedlineTbl& rSrcRedlTbl = rSrcDoc.GetRedlineTbl(); + ULONG nEndOfExtra = rSrcDoc.GetNodes().GetEndOfExtras().GetIndex(); + ULONG nMyEndOfExtra = GetNodes().GetEndOfExtras().GetIndex(); + for( USHORT n = 0; n < rSrcRedlTbl.Count(); ++n ) + { + const SwRedline* pRedl = rSrcRedlTbl[ n ]; + ULONG nNd = pRedl->GetPoint()->nNode.GetIndex(); + SwRedlineType eType = pRedl->GetType(); + if( nEndOfExtra < nNd && + ( REDLINE_INSERT == eType || REDLINE_DELETE == eType )) + { + const SwNode* pDstNd = GetNodes()[ + nMyEndOfExtra + nNd - nEndOfExtra ]; + + // Position gefunden. Dann muss im DestDoc auch + // in der Line das Redline eingefuegt werden + _SaveMergeRedlines* pTmp = new _SaveMergeRedlines( + *pDstNd, *pRedl, pRing ); + if( !pRing ) + pRing = pTmp; + } + } + + if( pRing ) + { + // dann alle ins DestDoc ueber nehmen + rSrcDoc.SetRedlineMode( REDLINE_SHOW_INSERT | REDLINE_SHOW_DELETE ); + SetRedlineMode( REDLINE_ON | REDLINE_SHOW_INSERT | REDLINE_SHOW_DELETE ); + _SaveMergeRedlines* pTmp = pRing; + + do { + nRet += pTmp->InsertRedline( &SwDoc::AppendUndo ); + } while( pRing != ( pTmp = (_SaveMergeRedlines*)pTmp->GetNext() )); + + while( pRing != pRing->GetNext() ) + delete pRing->GetNext(); + delete pRing; + } + } + + rSrcDoc.SetRedlineMode( eSrcRedlMode ); + if( !bSrcModified ) + rSrcDoc.ResetModified(); + + SetRedlineMode( REDLINE_SHOW_INSERT | REDLINE_SHOW_DELETE ); + + EndUndo(); + + return nRet; +} + + diff --git a/sw/source/core/doc/doccorr.cxx b/sw/source/core/doc/doccorr.cxx new file mode 100644 index 000000000000..5995c40d3d85 --- /dev/null +++ b/sw/source/core/doc/doccorr.cxx @@ -0,0 +1,578 @@ +/************************************************************************* + * + * $RCSfile: doccorr.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:15 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _DOC_HXX +#include +#endif +#ifndef _NODE_HXX +#include +#endif +#ifndef _ROOTFRM_HXX +#include +#endif +#ifndef _EDITSH_HXX +#include +#endif +#ifndef _VISCRS_HXX +#include +#endif +#ifndef _PAM_HXX +#include +#endif +#ifndef _BOOKMRK_HXX +#include +#endif +#ifndef _REDLINE_HXX +#include +#endif +#ifndef _MVSAVE_HXX +#include +#endif +#ifndef _DOCARY_HXX +#include +#endif +#ifndef _UNOCRSR_HXX +#include +#endif + + +/* */ + +/* + * MACROS um ueber alle CrsrShells zu iterieren + */ +#define PCURSH ((SwCrsrShell*)_pStartShell) +#define FOREACHSHELL_START( pEShell ) \ + {\ + register ViewShell *_pStartShell = pEShell; \ + do { \ + if( _pStartShell->IsA( TYPE( SwCrsrShell )) ) \ + { + +#define FOREACHSHELL_END( pEShell ) \ + } \ + } while((_pStartShell=(ViewShell*)_pStartShell->GetNext())!= pEShell ); \ + } + +#define PCURCRSR (_pCurrCrsr) +#define FOREACHPAM_START(pSttCrsr) \ + {\ + SwPaM *_pStartCrsr = pSttCrsr, *_pCurrCrsr = pSttCrsr; \ + do { + +#define FOREACHPAM_END() \ + } while( (_pCurrCrsr=(SwPaM *)_pCurrCrsr->GetNext()) != _pStartCrsr ); \ + } + +/* */ + +#define _PaMCorrAbs1( pPam ) \ + for( int nb = 0; nb < 2; ++nb ) \ + if( &((pPam)->GetBound( BOOL(nb) ).nNode.GetNode()) == pOldNode ) \ + { \ + (pPam)->GetBound( BOOL(nb) ) = aNewPos; \ + (pPam)->GetBound( BOOL(nb) ).nContent += nOffset; \ + } + + + +void PaMCorrAbs( const SwNodeIndex &rOldNode, + const SwPosition &rNewPos, + const xub_StrLen nOffset) +{ + const SwNode* pOldNode = &rOldNode.GetNode(); + const SwPosition aNewPos( rNewPos ); + const SwDoc* pDoc = pOldNode->GetDoc(); + SwCrsrShell* pShell = pDoc->GetEditShell(); + + if( pShell ) + { + FOREACHSHELL_START( pShell ) + register SwPaM *_pStkCrsr = PCURSH->GetStkCrsr(); + // Alle ueberfluessigen Crsr sind vom Stack, oder ?? + // ASSERT( !_pStkCrsr, "Es stehen noch Crsr auf dem CrsrStack" ); + if( _pStkCrsr ) + do { + _PaMCorrAbs1( _pStkCrsr ) + } while ( (_pStkCrsr != 0 ) && + ((_pStkCrsr=(SwPaM *)_pStkCrsr->GetNext()) != PCURSH->GetStkCrsr()) ); + + FOREACHPAM_START( PCURSH->_GetCrsr() ) + _PaMCorrAbs1( PCURCRSR ) + FOREACHPAM_END() + + if( PCURSH->IsTableMode() ) + _PaMCorrAbs1( PCURSH->GetTblCrs() ) + + FOREACHSHELL_END( pShell ) + } + + { + register SwUnoCrsrTbl& rTbl = (SwUnoCrsrTbl&)pDoc->GetUnoCrsrTbl(); + for( USHORT n = 0; n < rTbl.Count(); ++n ) + { + FOREACHPAM_START( rTbl[ n ] ) + _PaMCorrAbs1( PCURCRSR ) + FOREACHPAM_END() + + SwUnoTableCrsr* pUnoTblCrsr = (SwUnoTableCrsr*)*rTbl[ n ]; + if( pUnoTblCrsr ) + { + FOREACHPAM_START( &pUnoTblCrsr->GetSelRing() ) + _PaMCorrAbs1( PCURCRSR ) + FOREACHPAM_END() + } + } + } +} + + +void SwCrsrShell::PaMCorrAbs( const SwNodeIndex &rOldNode, + const SwPosition &rNewPos, + const xub_StrLen nOffset ) +{ + // alle Verzeichnisse/Bookmarks/.. verschieben. + GetDoc()->CorrAbs( rOldNode, rNewPos, nOffset ); + ::PaMCorrAbs( rOldNode, rNewPos, nOffset ); +} + +void SwDoc::CorrAbs( const SwNodeIndex& rOldNode, + const SwPosition& rNewPos, + const xub_StrLen nOffset, + BOOL bMoveCrsr ) +{ + const SwNode* pOldNode = &rOldNode.GetNode(); + SwPosition aNewPos( rNewPos ); + + { // erstmal die Bookmark korrigieren + register SwBookmarks& rBkmks = *pBookmarkTbl; + register SwBookmark* pBkmk; + for( USHORT n = 0; n < rBkmks.Count(); ++n ) + { + // liegt auf der Position ?? + int bChgd = 0; + if( &( pBkmk = (SwBookmark*)rBkmks[ n ])->pPos1->nNode.GetNode() == pOldNode ) + { + *pBkmk->pPos1 = aNewPos; + pBkmk->pPos1->nContent += nOffset; + bChgd = 1; + } + if( pBkmk->pPos2 && &pBkmk->pPos2->nNode.GetNode() == pOldNode ) + { + *pBkmk->pPos2 = aNewPos; + pBkmk->pPos2->nContent += nOffset; + bChgd = 2; + } + // ungueltige Selektion? Dann die Klammerung aufheben + if( bChgd && pBkmk->pPos2 && + pBkmk->pPos2->nNode.GetNode().FindTableBoxStartNode() != + pBkmk->pPos1->nNode.GetNode().FindTableBoxStartNode() ) + { + if( 1 == bChgd ) + *pBkmk->pPos1 = *pBkmk->pPos2; + delete pBkmk->pPos2, pBkmk->pPos2 = 0; + if( pBkmk->IsServer() ) + pBkmk->SetRefObject( 0 ); + // die Sortierung muss aufrecht erhalten bleiben! + rBkmks.Remove( n-- ); + rBkmks.Insert( pBkmk ); + } + } + } + { // dann die Redlines korrigieren + register SwRedlineTbl& rTbl = *pRedlineTbl; + for( USHORT n = 0; n < rTbl.Count(); ++n ) + { + // liegt auf der Position ?? + _PaMCorrAbs1( rTbl[ n ] ) + } + } + + if( bMoveCrsr ) + ::PaMCorrAbs( rOldNode, rNewPos, nOffset ); +} + +/* */ + +#define _PaMCorrAbs2( pPam ) \ + for( int nb = 0; nb < 2; ++nb ) \ + if( (pPam)->GetBound( BOOL(nb) ).nNode >= nSttNode && \ + (pPam)->GetBound( BOOL(nb) ).nNode <= nEndNode ) \ + (pPam)->GetBound( BOOL(nb) ) = aNewPos; + + + +void PaMCorrAbs( const SwNodeIndex &rStartNode, + const SwNodeIndex &rEndNode, + const SwPosition &rNewPos ) +{ + const ULONG nSttNode = rStartNode.GetIndex(); + const ULONG nEndNode = rEndNode.GetIndex(); + const SwPosition aNewPos( rNewPos ); + SwDoc* pDoc = rStartNode.GetNode().GetDoc(); + + SwCrsrShell* pShell = pDoc->GetEditShell(); + if( pShell ) + { + FOREACHSHELL_START( pShell ) + register SwPaM *_pStkCrsr = PCURSH->GetStkCrsr(); + // Alle ueberfluessigen Crsr sind vom Stack, oder ?? + // ASSERT( !_pStkCrsr, "Es stehen noch Crsr auf dem CrsrStack" ); + if( _pStkCrsr ) + do { + _PaMCorrAbs2( _pStkCrsr ) + } while ( (_pStkCrsr != 0 ) && + ((_pStkCrsr=(SwPaM *)_pStkCrsr->GetNext()) != PCURSH->GetStkCrsr()) ); + + FOREACHPAM_START( PCURSH->_GetCrsr() ) + _PaMCorrAbs2( PCURCRSR ) + FOREACHPAM_END() + + if( PCURSH->IsTableMode() ) + _PaMCorrAbs2( PCURSH->GetTblCrs() ) + + FOREACHSHELL_END( pShell ) + } + + { + register SwUnoCrsrTbl& rTbl = (SwUnoCrsrTbl&)pDoc->GetUnoCrsrTbl(); + for( USHORT n = 0; n < rTbl.Count(); ++n ) + { + FOREACHPAM_START( rTbl[ n ] ) + _PaMCorrAbs2( PCURCRSR ) + FOREACHPAM_END() + + SwUnoTableCrsr* pUnoTblCrsr = (SwUnoTableCrsr*)*rTbl[ n ]; + if( pUnoTblCrsr ) + { + FOREACHPAM_START( &pUnoTblCrsr->GetSelRing() ) + _PaMCorrAbs2( PCURCRSR ) + FOREACHPAM_END() + } + } + } +} + + +void SwCrsrShell::PaMCorrAbs( const SwNodeIndex &rStartNode, + const SwNodeIndex &rEndNode, + const SwPosition &rNewPos ) +{ + // alle Verzeichnisse/Bookmarks/.. verschieben. + GetDoc()->CorrAbs( rStartNode, rEndNode, rNewPos ); + ::PaMCorrAbs( rStartNode, rEndNode, rNewPos ); +} + +void SwDoc::CorrAbs( const SwNodeIndex& rStartNode, + const SwNodeIndex& rEndNode, + const SwPosition& rNewPos, + BOOL bMoveCrsr ) +{ + const ULONG nSttNode = rStartNode.GetIndex(); + const ULONG nEndNode = rEndNode.GetIndex(); + SwPosition aNewPos( rNewPos ); + +// if( !DoesUndo() ) + // erstmal die Bookmarks/Redlines korrigieren + _DelBookmarks( rStartNode, rEndNode ); + + if( bMoveCrsr ) + ::PaMCorrAbs( rStartNode, rEndNode, rNewPos ); +} + + +/* */ + +#define _PaMCorrAbs3( pPam ) \ + for( int nb = 0; nb < 2; ++nb ) \ + if( aStart <= (pPam)->GetBound( BOOL(nb) ) && \ + (pPam)->GetBound( BOOL(nb) ) <= aEnd ) \ + (pPam)->GetBound( BOOL(nb) ) = aNewPos; + +void PaMCorrAbs( const SwPaM& rRange, + const SwPosition& rNewPos ) +{ + SwPosition aStart( *rRange.Start() ); + SwPosition aEnd( *rRange.End() ); + SwPosition aNewPos( rNewPos ); + SwDoc* pDoc = aStart.nNode.GetNode().GetDoc(); + SwCrsrShell* pShell = pDoc->GetEditShell(); + + if( pShell ) + { + FOREACHSHELL_START( pShell ) + register SwPaM *_pStkCrsr = PCURSH->GetStkCrsr(); + // Alle ueberfluessigen Crsr sind vom Stack, oder ?? + // ASSERT( !_pStkCrsr, "Es stehen noch Crsr auf dem CrsrStack" ); + if( _pStkCrsr ) + do { + _PaMCorrAbs3( _pStkCrsr ) + } while ( (_pStkCrsr != 0 ) && + ((_pStkCrsr=(SwPaM *)_pStkCrsr->GetNext()) != PCURSH->GetStkCrsr()) ); + + FOREACHPAM_START( PCURSH->_GetCrsr() ) + _PaMCorrAbs3( PCURCRSR ) + FOREACHPAM_END() + + if( PCURSH->IsTableMode() ) + _PaMCorrAbs3( PCURSH->GetTblCrs() ) + + FOREACHSHELL_END( pShell ) + } + { + register SwUnoCrsrTbl& rTbl = (SwUnoCrsrTbl&)pDoc->GetUnoCrsrTbl(); + for( USHORT n = 0; n < rTbl.Count(); ++n ) + { + FOREACHPAM_START( rTbl[ n ] ) + _PaMCorrAbs3( PCURCRSR ) + FOREACHPAM_END() + + SwUnoTableCrsr* pUnoTblCrsr = (SwUnoTableCrsr*)*rTbl[ n ]; + if( pUnoTblCrsr ) + { + FOREACHPAM_START( &pUnoTblCrsr->GetSelRing() ) + _PaMCorrAbs3( PCURCRSR ) + FOREACHPAM_END() + } + } + } +} + + +void SwDoc::CorrAbs( const SwPaM& rRange, + const SwPosition& rNewPos, + BOOL bMoveCrsr ) +{ + SwPosition aStart( *rRange.Start() ); + SwPosition aEnd( *rRange.End() ); + SwPosition aNewPos( rNewPos ); + +// if( !DoesUndo() ) + // erstmal die Bookmarks/Redlines korrigieren + _DelBookmarks( aStart.nNode, aEnd.nNode, 0, + &aStart.nContent, &aEnd.nContent ); + if( bMoveCrsr ) + ::PaMCorrAbs( rRange, rNewPos ); +} + + +/* */ + +#define _PaMCorrRel1( pPam ) \ + for( int nb = 0; nb < 2; ++nb ) \ + if( &((pPam)->GetBound( BOOL(nb) ).nNode.GetNode()) == pOldNode ) \ + { \ + (pPam)->GetBound( BOOL(nb) ).nNode = aNewPos.nNode; \ + (pPam)->GetBound( BOOL(nb) ).nContent.Assign( (SwIndexReg*) \ + aNewPos.nContent.GetIdxReg(), \ + nCntIdx + (pPam)->GetBound( BOOL(nb) ).nContent. \ + GetIndex() ); \ + } + + + +void PaMCorrRel( const SwNodeIndex &rOldNode, + const SwPosition &rNewPos, + const xub_StrLen nOffset ) +{ + const SwNode* pOldNode = &rOldNode.GetNode(); + SwPosition aNewPos( rNewPos ); + const SwDoc* pDoc = pOldNode->GetDoc(); + + xub_StrLen nCntIdx = rNewPos.nContent.GetIndex() + nOffset; + + SwCrsrShell* pShell = pDoc->GetEditShell(); + if( pShell ) + { + FOREACHSHELL_START( pShell ) + register SwPaM *_pStkCrsr = PCURSH->GetStkCrsr(); + // Alle ueberfluessigen Crsr sind vom Stack, oder ?? + // ASSERT( !_pStkCrsr, "Es stehen noch Crsr auf dem CrsrStack" ); + if( _pStkCrsr ) + do { + _PaMCorrRel1( _pStkCrsr ) + } while ( (_pStkCrsr != 0 ) && + ((_pStkCrsr=(SwPaM *)_pStkCrsr->GetNext()) != PCURSH->GetStkCrsr()) ); + + FOREACHPAM_START( PCURSH->_GetCrsr() ) + _PaMCorrRel1( PCURCRSR ) + FOREACHPAM_END() + + if( PCURSH->IsTableMode() ) + _PaMCorrRel1( PCURSH->GetTblCrs() ) + + FOREACHSHELL_END( pShell ) + } + { + register SwUnoCrsrTbl& rTbl = (SwUnoCrsrTbl&)pDoc->GetUnoCrsrTbl(); + for( USHORT n = 0; n < rTbl.Count(); ++n ) + { + FOREACHPAM_START( rTbl[ n ] ) + _PaMCorrRel1( PCURCRSR ) + FOREACHPAM_END() + + SwUnoTableCrsr* pUnoTblCrsr = (SwUnoTableCrsr*)*rTbl[ n ]; + if( pUnoTblCrsr ) + { + FOREACHPAM_START( &pUnoTblCrsr->GetSelRing() ) + _PaMCorrRel1( PCURCRSR ) + FOREACHPAM_END() + } + } + } +} + +void SwDoc::CorrRel( const SwNodeIndex& rOldNode, + const SwPosition& rNewPos, + const xub_StrLen nOffset, + BOOL bMoveCrsr ) +{ + const SwNode* pOldNode = &rOldNode.GetNode(); + SwPosition aNewPos( rNewPos ); + xub_StrLen nCntIdx = aNewPos.nContent.GetIndex() + nOffset; + + { // erstmal die Bookmark korrigieren + register SwBookmarks& rBkmks = *pBookmarkTbl; + register SwBookmark* pBkmk; + for( USHORT n = 0; n < rBkmks.Count(); ++n ) + { + // liegt auf der Position ?? + int bChgd = FALSE; + if( &( pBkmk = (SwBookmark*)rBkmks[ n ])->pPos1->nNode.GetNode() + == pOldNode ) + { + pBkmk->pPos1->nNode = aNewPos.nNode; + pBkmk->pPos1->nContent.Assign( (SwIndexReg*) + aNewPos.nContent.GetIdxReg(), + nCntIdx + pBkmk->pPos1->nContent.GetIndex() ); + bChgd = 1; + } + if( pBkmk->pPos2 && &pBkmk->pPos2->nNode.GetNode() == pOldNode ) + { + pBkmk->pPos2->nNode = aNewPos.nNode; + pBkmk->pPos2->nContent.Assign( (SwIndexReg*) + aNewPos.nContent.GetIdxReg(), + nCntIdx + pBkmk->pPos2->nContent.GetIndex() ); + bChgd = 2; + } + // ungueltige Selektion? Dann die Klammerung aufheben + if( bChgd && pBkmk->pPos2 && + pBkmk->pPos2->nNode.GetNode().FindTableBoxStartNode() != + pBkmk->pPos1->nNode.GetNode().FindTableBoxStartNode() ) + { + if( 1 == bChgd ) + *pBkmk->pPos1 = *pBkmk->pPos2; + delete pBkmk->pPos2, pBkmk->pPos2 = 0; + if( pBkmk->IsServer() ) + pBkmk->SetRefObject( 0 ); + + // die Sortierung muss aufrecht erhalten bleiben! + rBkmks.Remove( n-- ); + rBkmks.Insert( pBkmk ); + } + } + } + { // dann die Redlines korrigieren + register SwRedlineTbl& rTbl = *pRedlineTbl; + for( USHORT n = 0; n < rTbl.Count(); ++n ) + { + // liegt auf der Position ?? + _PaMCorrRel1( rTbl[ n ] ) + } + } + + if( bMoveCrsr ) + ::PaMCorrAbs( rOldNode, rNewPos, nOffset ); +} + + +/* */ + +SwEditShell* SwDoc::GetEditShell( ViewShell** ppSh ) const +{ + // Layout und OLE-Shells sollten vorhanden sein! + if( pLayout && pLayout->GetCurrShell() ) + { + register ViewShell *pSh = pLayout->GetCurrShell(), *pVSh = pSh; + if( ppSh ) + *ppSh = pSh; + + // wir suchen uns eine EditShell, falls diese existiert + do { + if( pSh->IsA( TYPE( SwEditShell ) ) ) + return (SwEditShell*)pSh; + + } while( pVSh != ( pSh = (ViewShell*)pSh->GetNext() )); + } + else if( ppSh ) + *ppSh = 0; + + return 0; +} + + + diff --git a/sw/source/core/doc/docdde.cxx b/sw/source/core/doc/docdde.cxx new file mode 100644 index 000000000000..414ac8b86bb1 --- /dev/null +++ b/sw/source/core/doc/docdde.cxx @@ -0,0 +1,525 @@ +/************************************************************************* + * + * $RCSfile: docdde.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:15 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#include + +#ifndef _INTN_HXX //autogen +#include +#endif +#ifndef _APP_HXX //autogen +#include +#endif +#ifndef _URLOBJ_HXX +#include +#endif + +#ifndef _LINKNAME_HXX //autogen +#include +#endif +#ifndef SO2_DECL_SVLINKNAME_DEFINED +#define SO2_DECL_SVLINKNAME_DEFINED +SO2_DECL_REF(SvLinkName) +#endif +#define _SVSTDARR_STRINGS +#include +#ifndef _SVXLINKMGR_HXX +#include // LinkManager +#endif +#ifndef _UNOTOOLS_CHARCLASS_HXX +#include +#endif + +#ifndef _FMTCNTNT_HXX //autogen +#include +#endif +#ifndef _DOC_HXX +#include +#endif +#ifndef _SWSERV_HXX +#include // fuer Server-Funktionalitaet +#endif +#ifndef _BOOKMRK_HXX +#include // fuer die Bookmarks +#endif +#ifndef _SECTION_HXX +#include // fuer SwSectionFmt +#endif +#ifndef _SWTABLE_HXX +#include // fuer SwTable +#endif +#ifndef _NODE_HXX +#include +#endif +#ifndef _NDTXT_HXX +#include +#endif +#ifndef _PAM_HXX +#include +#endif +#ifndef _DOCARY_HXX +#include +#endif + +SO2_IMPL_REF( SwServerObject ) + +struct _FindItem +{ + const String& rItem; + SwBookmark* pBkmk; + SwTableNode* pTblNd; + SwSectionNode* pSectNd; + + _FindItem( const String& rS ) + : rItem( rS ), pBkmk( 0 ), pTblNd( 0 ), pSectNd( 0 ) + {} + + void ClearObj() + { + if( pBkmk ) + pBkmk->SetRefObject( 0 ); + else if( pSectNd ) + pSectNd->GetSection().SetRefObject( 0 ); + else if( pTblNd ) + pTblNd->GetTable().SetRefObject( 0 ); + } +}; + + +BOOL lcl_FindBookmark( const SwBookmarkPtr& rpBkmk, void* pArgs ) +{ + BOOL bRet = TRUE; + String sNm( GetAppCharClass().lower( rpBkmk->GetName() )); + if( sNm.Equals( ((_FindItem*)pArgs)->rItem ) ) + { + ((_FindItem*)pArgs)->pBkmk = rpBkmk; + bRet = FALSE; + } + + return bRet; +} + + + +BOOL lcl_FindSection( const SwSectionFmtPtr& rpSectFmt, void* pArgs ) +{ + SwSection* pSect = rpSectFmt->GetSection(); + if( pSect ) + { + String sNm( GetAppCharClass().lower( pSect->GetName() )); + if( sNm.Equals( ((_FindItem*)pArgs)->rItem )) + { + // gefunden, als erfrage die Daten + const SwNodeIndex* pIdx; + if( 0 != (pIdx = rpSectFmt->GetCntnt().GetCntntIdx() ) && + &rpSectFmt->GetDoc()->GetNodes() == &pIdx->GetNodes() ) + { + // eine Tabelle im normalen NodesArr + ((_FindItem*)pArgs)->pSectNd = pIdx->GetNode().GetSectionNode(); + return FALSE; + } +//nein!! // sollte der Namen schon passen, der Rest aber nicht, dann haben wir + // sie nicht. Die Namen sind immer eindeutig. + } + } + return TRUE; // dann weiter +} + + + +BOOL lcl_FindTable( const SwFrmFmtPtr& rpTableFmt, void* pArgs ) +{ + String sNm( GetAppCharClass().lower( rpTableFmt->GetName() )); + if( sNm.Equals( ((_FindItem*)pArgs)->rItem )) + { + SwTable* pTmpTbl; + SwTableBox* pFBox; + if( 0 != ( pTmpTbl = SwTable::FindTable( rpTableFmt ) ) && + 0 != ( pFBox = pTmpTbl->GetTabSortBoxes()[0] ) && + pFBox->GetSttNd() && + &rpTableFmt->GetDoc()->GetNodes() == &pFBox->GetSttNd()->GetNodes() ) + { + // eine Tabelle im normalen NodesArr + ((_FindItem*)pArgs)->pTblNd = (SwTableNode*) + pFBox->GetSttNd()->FindTableNode(); + return FALSE; + } +//nein! // sollte der Namen schon passen, der Rest aber nicht, dann haben wir + // sie nicht. Die Namen sind immer eindeutig. + } + return TRUE; // dann weiter +} + + + +BOOL SwDoc::GetData( const String& rItem, SvData& rData ) const +{ + // haben wir ueberhaupt das Item vorraetig? + String sItem( GetAppCharClass().lower( rItem )); + _FindItem aPara( sItem ); + ((SwBookmarks&)*pBookmarkTbl).ForEach( 0, pBookmarkTbl->Count(), + lcl_FindBookmark, &aPara ); + if( aPara.pBkmk ) + { + // gefunden, als erfrage die Daten + return SwServerObject( *aPara.pBkmk ).GetData( &rData ); + } + + ((SwSectionFmts&)*pSectionFmtTbl).ForEach( 0, pSectionFmtTbl->Count(), + lcl_FindSection, &aPara ); + if( aPara.pSectNd ) + { + // gefunden, als erfrage die Daten + return SwServerObject( *aPara.pSectNd ).GetData( &rData ); + } + + ((SwFrmFmts*)pTblFrmFmtTbl)->ForEach( 0, pTblFrmFmtTbl->Count(), + lcl_FindTable, &aPara ); + if( aPara.pTblNd ) + { + return SwServerObject( *aPara.pTblNd ).GetData( &rData ); + } + + return FALSE; +} + + + +BOOL SwDoc::ChangeData( const String& rItem, const SvData& rData ) +{ + // haben wir ueberhaupt das Item vorraetig? + String sItem( GetAppCharClass().lower( rItem )); + _FindItem aPara( sItem ); + pBookmarkTbl->ForEach( 0, pBookmarkTbl->Count(), lcl_FindBookmark, &aPara ); + if( aPara.pBkmk ) + { + // gefunden, als erfrage die Daten + return SwServerObject( *aPara.pBkmk ).ChangeData( (SvData&)rData ); + } + + pSectionFmtTbl->ForEach( 0, pSectionFmtTbl->Count(), lcl_FindSection, &aPara ); + if( aPara.pSectNd ) + { + // gefunden, als erfrage die Daten + return SwServerObject( *aPara.pSectNd ).ChangeData( (SvData&)rData ); + } + + pTblFrmFmtTbl->ForEach( 0, pTblFrmFmtTbl->Count(), lcl_FindTable, &aPara ); + if( aPara.pTblNd ) + { + return SwServerObject( *aPara.pTblNd ).ChangeData( (SvData&)rData ); + } + + return FALSE; +} + + + +SvPseudoObject* SwDoc::CreateHotLink( const String& rItem ) +{ + // haben wir ueberhaupt das Item vorraetig? + String sItem( GetAppCharClass().lower( rItem )); + _FindItem aPara( sItem ); + + SwServerObject* pObj; + + do { // middle check Loop + ((SwBookmarks&)*pBookmarkTbl).ForEach( 0, pBookmarkTbl->Count(), + lcl_FindBookmark, &aPara ); + if( aPara.pBkmk && aPara.pBkmk->GetOtherPos() ) + { + // gefunden, also Hotlink einrichten + // sollten wir schon einer sein? + if( 0 == (pObj = aPara.pBkmk->GetObject()) ) + { + pObj = new SwServerObject( *aPara.pBkmk ); + aPara.pBkmk->SetRefObject( pObj ); + } + else if( pObj->GetSelectorCount() ) + return pObj; + break; + } + + ((SwSectionFmts&)*pSectionFmtTbl).ForEach( 0, pSectionFmtTbl->Count(), + lcl_FindSection, &aPara ); + if( aPara.pSectNd ) + { + // gefunden, also Hotlink einrichten + // sollten wir schon einer sein? + if( 0 == (pObj = aPara.pSectNd->GetSection().GetObject()) ) + { + pObj = new SwServerObject( *aPara.pSectNd ); + aPara.pSectNd->GetSection().SetRefObject( pObj ); + } + else if( pObj->GetSelectorCount() ) + return pObj; + break; + } + + ((SwFrmFmts*)pTblFrmFmtTbl)->ForEach( 0, pTblFrmFmtTbl->Count(), + lcl_FindTable, &aPara ); + if( aPara.pTblNd ) + { + // gefunden, also Hotlink einrichten + // sollten wir schon einer sein? + if( 0 == (pObj = aPara.pTblNd->GetTable().GetObject()) ) + { + pObj = new SwServerObject( *aPara.pTblNd ); + aPara.pTblNd->GetTable().SetRefObject( pObj ); + } + else if( pObj->GetSelectorCount() ) + return pObj; + break; + } + // bis hierhin, also nicht vorhanden + return 0; + } while( FALSE ); + + // neu angelegt also ab in die Verwaltung + GetLinkManager().InsertServer( pObj ); + return pObj; +} + + + +BOOL SwDoc::SelectServerObj( const String& rStr, SwPaM*& rpPam, + SwNodeRange*& rpRange ) const +{ + // haben wir ueberhaupt das Item vorraetig? + rpPam = 0; + rpRange = 0; + + String sItem( INetURLObject::decode( rStr, INET_HEX_ESCAPE, + INetURLObject::DECODE_WITH_CHARSET, + RTL_TEXTENCODING_UTF8 )); + + xub_StrLen nPos = sItem.Search( cMarkSeperator ); + + const CharClass& rCC = GetAppCharClass(); + + // Erweiterung fuer die Bereiche, nicht nur Bookmarks/Bereiche linken, + // sondern auch Rahmen(Text!), Tabellen, Gliederungen: + if( STRING_NOTFOUND != nPos ) + { + BOOL bWeiter = FALSE; + String sName( sItem.Copy( 0, nPos ) ); + String sCmp( sItem.Copy( nPos + 1 )); + rCC.toLower( sItem ); + + _FindItem aPara( sName ); + + if( sCmp.EqualsAscii( pMarkToTable ) ) + { + rCC.toLower( sName ); + ((SwFrmFmts*)pTblFrmFmtTbl)->ForEach( 0, pTblFrmFmtTbl->Count(), + lcl_FindTable, &aPara ); + if( aPara.pTblNd ) + { + rpRange = new SwNodeRange( *aPara.pTblNd, 0, + *aPara.pTblNd->EndOfSectionNode(), 1 ); + return TRUE; + } + } + else if( sCmp.EqualsAscii( pMarkToFrame ) ) + { + SwNodeIndex* pIdx; + SwNode* pNd; + const SwFlyFrmFmt* pFlyFmt = FindFlyByName( sName ); + if( pFlyFmt && + 0 != ( pIdx = (SwNodeIndex*)pFlyFmt->GetCntnt().GetCntntIdx() ) && + !( pNd = &pIdx->GetNode())->IsNoTxtNode() ) + { + rpRange = new SwNodeRange( *pNd, 1, *pNd->EndOfSectionNode() ); + return TRUE; + } + } + else if( sCmp.EqualsAscii( pMarkToRegion ) ) + { + sItem = sName; // wird unten behandelt ! + bWeiter = TRUE; + } + else if( sCmp.EqualsAscii( pMarkToOutline ) ) + { + SwPosition aPos( SwNodeIndex( (SwNodes&)GetNodes() )); + if( GotoOutline( aPos, sName )) + { + SwNode* pNd = &aPos.nNode.GetNode(); + BYTE nLvl = pNd->GetTxtNode()->GetTxtColl()->GetOutlineLevel(); + + const SwOutlineNodes& rOutlNds = GetNodes().GetOutLineNds(); + USHORT nPos; + rOutlNds.Seek_Entry( pNd, &nPos ); + rpRange = new SwNodeRange( aPos.nNode, 0, aPos.nNode ); + + // dann suche jetzt noch das Ende vom Bereich + for( ++nPos; + nPos < rOutlNds.Count() && + nLvl < rOutlNds[ nPos ]->GetTxtNode()-> + GetTxtColl()->GetOutlineLevel(); + ++nPos ) + ; // es gibt keinen Block + + if( nPos < rOutlNds.Count() ) + rpRange->aEnd = *rOutlNds[ nPos ]; + else + rpRange->aEnd = GetNodes().GetEndOfContent(); + return TRUE; + } + } + + if( !bWeiter ) + return FALSE; + } + + // alte "Mechanik" + rCC.toLower( sItem ); + _FindItem aPara( sItem ); + if( pBookmarkTbl->Count() ) + { + ((SwBookmarks&)*pBookmarkTbl).ForEach( 0, pBookmarkTbl->Count(), + lcl_FindBookmark, &aPara ); + if( aPara.pBkmk ) + { + // gefunden, also erzeuge einen Bereich + if( aPara.pBkmk->GetOtherPos() ) + // ein aufgespannter Bereich + rpPam = new SwPaM( aPara.pBkmk->GetPos(), + *aPara.pBkmk->GetOtherPos() ); + return 0 != rpPam; + } + } + + if( pSectionFmtTbl->Count() ) + { + ((SwSectionFmts&)*pSectionFmtTbl).ForEach( 0, pSectionFmtTbl->Count(), + lcl_FindSection, &aPara ); + if( aPara.pSectNd ) + { + rpRange = new SwNodeRange( *aPara.pSectNd, 1, + *aPara.pSectNd->EndOfSectionNode() ); + return TRUE; + + } + } + return FALSE; +} + + + +extern "C" { + int +#if defined( WNT ) + __cdecl +#endif +#if defined( ICC ) + _Optlink +#endif + lcl_ServerNamesCmpNm( const void *pFirst, const void *pSecond) + { + const StringPtr pF = *(StringPtr*)pFirst; + const StringPtr pS = *(StringPtr*)pSecond; + ASSERT( pF && pS, "ungueltige Strings" ); + StringCompare eCmp = pF->CompareTo( *pS ); + return eCmp == COMPARE_EQUAL ? 0 + : eCmp == COMPARE_LESS ? 1 : -1; + } +} + + +USHORT SwDoc::GetServerObjects( SvStrings& rStrArr ) const +{ + USHORT n; + for( n = pBookmarkTbl->Count(); n; ) + { + SwBookmark* pBkmk = (*pBookmarkTbl)[ --n ]; + if( pBkmk->IsBookMark() && pBkmk->GetOtherPos() ) + { + String* pNew = new String( pBkmk->GetName() ); + rStrArr.Insert( pNew, rStrArr.Count() ); + } + } + + for( n = pSectionFmtTbl->Count(); n; ) + { + SwSectionFmt* pFmt = (*pSectionFmtTbl)[ --n ]; + if( pFmt->IsInNodesArr() ) + { + String* pNew = new String( pFmt->GetName() ); + rStrArr.Insert( pNew, rStrArr.Count() ); + } + } + + // und nochmal nach Namen sortieren: + if( 0 != ( n = rStrArr.Count() ) ) + qsort( (void*)rStrArr.GetData(), n, sizeof( StringPtr ), + lcl_ServerNamesCmpNm ); + + return n; +} + + + + diff --git a/sw/source/core/doc/docdesc.cxx b/sw/source/core/doc/docdesc.cxx new file mode 100644 index 000000000000..2cedfa0f7100 --- /dev/null +++ b/sw/source/core/doc/docdesc.cxx @@ -0,0 +1,1016 @@ +/************************************************************************* + * + * $RCSfile: docdesc.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:15 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _HINTIDS_HXX +#include +#endif +#ifndef _SFX_PRINTER_HXX //autogen +#include +#endif +#ifndef _SVDMODEL_HXX //autogen +#include +#endif +#ifndef _SVX_ULSPITEM_HXX //autogen +#include +#endif +#ifndef _SVX_LRSPITEM_HXX //autogen +#include +#endif +#ifndef _SVX_PAPERINF_HXX //autogen +#include +#endif +#ifndef _URLOBJ_HXX //autogen +#include +#endif +#ifndef _SFXDOCFILE_HXX //autogen +#include +#endif +#ifndef _GLOBNAME_HXX //autogen +#include +#endif + +#ifndef _FMTFSIZE_HXX //autogen +#include +#endif +#ifndef _FMTHDFT_HXX //autogen +#include +#endif +#ifndef _FMTCNTNT_HXX //autogen +#include +#endif +#ifndef _FMTPDSC_HXX //autogen +#include +#endif +#ifndef _FTNINFO_HXX //autogen +#include +#endif +#ifndef _FESH_HXX //autogen +#include +#endif +#ifndef _NDOLE_HXX //autogen +#include +#endif +#ifndef _MDIEXP_HXX +#include +#endif +#ifndef _SWTYPES_HXX +#include +#endif +#ifndef _DOC_HXX +#include +#endif +#ifndef _DOCARY_HXX +#include +#endif +#ifndef _PAGEFRM_HXX +#include //Fuer DelPageDesc +#endif +#ifndef _ROOTFRM_HXX +#include //Fuer DelPageDesc +#endif +#ifndef _HINTS_HXX +#include +#endif +#ifndef _NDTXT_HXX +#include +#endif +#ifndef _FRMTOOL_HXX +#include +#endif +#ifndef _PAGEDESC_HXX +#include +#endif +#ifndef _POOLFMT_HXX +#include +#endif +#ifndef _DOCSH_HXX +#include +#endif +#ifndef _NDINDEX_HXX +#include +#endif +#ifndef _FTNIDX_HXX +#include +#endif +#ifndef _FMTFTN_HXX +#include +#endif +#ifndef _TXTFTN_HXX +#include +#endif +#ifndef _FNTCACHE_HXX +#include +#endif +#ifndef _VIEWSH_HXX +#include +#endif +#ifndef _VIEWOPT_HXX +#include +#endif +#ifndef _FLDBAS_HXX +#include +#endif +#ifndef _SWWAIT_HXX +#include +#endif + +#ifndef _STATSTR_HRC +#include +#endif + +void lcl_DefaultPageFmt( SwFrmFmt &rFmt1, SwFrmFmt &rFmt2, SfxPrinter *pPrt, + BOOL bCheck ) +{ + //Einstellung von Seitengroesse und Seitenraendern. Dazu wird + //der Default-Printer benutzt. + //Die Physikalische Seitengroesse ist die des Printers + //oder DIN-A4 wenn der Printer eine Groesse von 0 liefert. + //Der Seitenrand ergibt sich aus der Seitengroesse, der Output- + //SSize des Printers und einem Offset der die linke obere Ecke + //der Output-SSize relativ zur Physikalischen Pagesize angibt. + //Wenn der Offset 0 ist, werden eingestellt. + //!!!Die Seitengroesse wird hier im Attribut eingestellt, + //dies wird im Ctor des SwPageFrm beachtet. + + SvxLRSpaceItem aLR; + SvxULSpaceItem aUL; + SwFmtFrmSize aFrmSize( ATT_FIX_SIZE ); + BOOL bSetFmt1 = TRUE, + bSetFmt2 = TRUE; + if ( pPrt ) + { + if ( bCheck ) + { + const SwFmtFrmSize &rFrmSize = rFmt1.GetFrmSize(); + const SwFmtFrmSize &rFrmSize2 = rFmt2.GetFrmSize(); + bSetFmt1 = LONG_MAX == rFrmSize.GetWidth() || + LONG_MAX == rFrmSize.GetHeight(); + bSetFmt2 = LONG_MAX == rFrmSize2.GetWidth() || + LONG_MAX == rFrmSize2.GetHeight(); + if ( !bSetFmt1 && !bSetFmt2 ) + return; + } + + //Seitengrosse + //fuer das Erfragen von SV, ob ein Drucker angeschlossen ist, + //werden die SV'ler noch eine Methode anbieten. + const Size aPhysSize( SvxPaperInfo::GetPaperSize( (Printer*)pPrt )); + + //if ( aPhysSize.Width() <= 0 ) + // aPhysSize.Width() = lA4Width; + //if ( aPhysSize.Height() <= 0 ) + // aPhysSize.Height() = lA4Height; + aFrmSize.SetSize( aPhysSize ); + + //Raender + Size aOutSize; + Point aOffst( pPrt->GetPageOffset() ); + + //Auf Default-Raender vorbereiten. + //Raender haben eine defaultmaessige Mindestgroesse. + //wenn der Drucker einen groesseren Rand vorgibt, so + //ist mir dass auch recht. + International aInternational; + long nMinTopBottom, nMinLeftRight; + if ( MEASURE_METRIC == aInternational.GetMeasurementSystem() ) + nMinTopBottom = nMinLeftRight = 1134; //2 Zentimeter + else + { + nMinTopBottom = 1440; //al la WW: 1Inch + nMinLeftRight = 1800; // 1,25 Inch + } + + if ( aOffst.X() < nMinLeftRight ) + aOffst.X() = nMinLeftRight; + if ( aOffst.Y() < nMinTopBottom ) + aOffst.Y() = nMinTopBottom; + aOutSize.Width() = aPhysSize.Width() - ( 2 * aOffst.X() ); + aOutSize.Height() = aPhysSize.Height() - ( 2 * aOffst.Y() ); + + //Raender einstellen. + aUL.SetUpper( USHORT(aOffst.Y()) ); + aUL.SetLower( USHORT(aPhysSize.Height() - aOutSize.Height() - aOffst.Y())); + aLR.SetRight( USHORT(aOffst.X()) ); + aLR.SetLeft( USHORT(aPhysSize.Width() - aOutSize.Width() - aOffst.X())); + } + else + { + aFrmSize.SetWidth( LONG_MAX ); + aFrmSize.SetHeight( LONG_MAX ); + aUL.SetUpper( 0 ); + aUL.SetLower( 0 ); + aLR.SetRight( 0 ); + aLR.SetLeft( 0 ); + } + if ( bSetFmt1 ) + { + rFmt1.SetAttr( aFrmSize ); + rFmt1.SetAttr( aLR ); + rFmt1.SetAttr( aUL ); + } + if ( bSetFmt2 ) + { + rFmt2.SetAttr( aFrmSize ); + rFmt2.SetAttr( aLR ); + rFmt2.SetAttr( aUL ); + } +} + +/************************************************************************* +|* +|* SwDoc::ChgPageDesc() +|* +|* Ersterstellung MA 25. Jan. 93 +|* Letzte Aenderung MA 01. Mar. 95 +|* +|*************************************************************************/ + +void lcl_DescSetAttr( const SwFrmFmt &rSource, SwFrmFmt &rDest, + const BOOL bPage = TRUE ) +{ +/////////////// !!!!!!!!!!!!!!!! +//JP 03.03.99: +// eigentlich sollte hier das Intersect von ItemSet benutzt werden, aber das +// funktioniert nicht richtig, wenn man unterschiedliche WhichRanges hat. +/////////////// !!!!!!!!!!!!!!!! + //Die interressanten Attribute uebernehmen. + USHORT __READONLY_DATA aIdArr[] = { RES_FRM_SIZE, RES_UL_SPACE, + RES_BACKGROUND, RES_SHADOW, + RES_COL, RES_COL, 0 }; + const SfxPoolItem* pItem; + for( USHORT n = 0; aIdArr[ n ]; n += 2 ) + { + for( USHORT nId = aIdArr[ n ]; nId <= aIdArr[ n+1]; ++nId ) + { + if( bPage || ( RES_COL != nId && RES_PAPER_BIN != nId )) + { + if( SFX_ITEM_SET == rSource.GetItemState( nId, FALSE, &pItem )) + rDest.SetAttr( *pItem ); + else + rDest.ResetAttr( nId ); + } + } + } + + // auch Pool-, Hilfe-Id's uebertragen + rDest.SetPoolFmtId( rSource.GetPoolFmtId() ); + rDest.SetPoolHelpId( rSource.GetPoolHelpId() ); + rDest.SetPoolHlpFileId( rSource.GetPoolHlpFileId() ); +} + + +void SwDoc::ChgPageDesc( USHORT i, const SwPageDesc &rChged ) +{ + ASSERT( i < aPageDescs.Count(), "PageDescs ueberindiziert." ); + + SwPageDesc *pDesc = aPageDescs[i]; + + //Als erstes wird ggf. gespiegelt. + if ( rChged.GetUseOn() == PD_MIRROR ) + ((SwPageDesc&)rChged).Mirror(); + else + //sonst Werte aus Master nach Left uebertragen. + ::lcl_DescSetAttr( ((SwPageDesc&)rChged).GetMaster(), + ((SwPageDesc&)rChged).GetLeft() ); + + //NumType uebernehmen. + if( rChged.GetNumType().eType != pDesc->GetNumType().eType ) + { + pDesc->SetNumType( rChged.GetNumType() ); + // JP 30.03.99: Bug 64121 - den Seitennummernfeldern bescheid sagen, + // das sich das Num-Format geaendert hat + GetSysFldType( RES_PAGENUMBERFLD )->UpdateFlds(); + GetSysFldType( RES_REFPAGEGETFLD )->UpdateFlds(); + + // Wenn sich die Numerierungsart geaendert hat, koennte es QuoVadis/ + // ErgoSum-Texte geben, die sich auf eine geaenderte Seite beziehen, + // deshalb werden die Fussnoten invalidiert + SwFtnIdxs& rFtnIdxs = GetFtnIdxs(); + for( USHORT nPos = 0; nPos < rFtnIdxs.Count(); ++nPos ) + { + SwTxtFtn *pTxtFtn = rFtnIdxs[ nPos ]; + const SwFmtFtn &rFtn = pTxtFtn->GetFtn(); + pTxtFtn->SetNumber( rFtn.GetNumber(), &rFtn.GetNumStr()); + } + } + + //Orientierung uebernehmen + pDesc->SetLandscape( rChged.GetLandscape() ); + + //Header abgleichen. + const SwFmtHeader &rHead = rChged.GetMaster().GetHeader(); + if( DoesUndo() ) + { + // hat sich an den Nodes etwas veraendert ? + //JP erstmal ein Hack, solange keine Headers/Footers Undofaehig sind + const SwFmtHeader &rOldHead = pDesc->GetMaster().GetHeader(); + if( rHead.IsActive() != rOldHead.IsActive() || + rChged.IsHeaderShared() != pDesc->IsHeaderShared() ) + { + // erstmal werden alle Undo - Objecte geloescht. + ClearRedo(); + DelAllUndoObj(); + } + } + pDesc->GetMaster().SetAttr( rHead ); + if ( rChged.IsHeaderShared() || !rHead.IsActive() ) + { + //Left teilt sich den Header mit dem Master. + pDesc->GetLeft().SetAttr( pDesc->GetMaster().GetHeader() ); + } + else if ( rHead.IsActive() ) + { //Left bekommt einen eigenen Header verpasst wenn das Format nicht + //bereits einen hat. + //Wenn er bereits einen hat und dieser auf die gleiche Section + //wie der Rechte zeigt, so muss er einen eigenen bekommen. Der + //Inhalt wird sinnigerweise kopiert. + const SwFmtHeader &rLeftHead = pDesc->GetLeft().GetHeader(); + if ( !rLeftHead.IsActive() ) + { + SwFmtHeader aHead( MakeLayoutFmt( RND_STD_HEADERL ) ); + pDesc->GetLeft().SetAttr( aHead ); + //Weitere Attribute (Raender, Umrandung...) uebernehmen. + ::lcl_DescSetAttr( *rHead.GetHeaderFmt(), *aHead.GetHeaderFmt(), FALSE); + } + else + { + const SwFrmFmt *pRight = rHead.GetHeaderFmt(); + const SwFmtCntnt &aRCnt = pRight->GetCntnt(); + const SwFmtCntnt &aLCnt = rLeftHead.GetHeaderFmt()->GetCntnt(); + if ( (*aRCnt.GetCntntIdx()) == (*aLCnt.GetCntntIdx()) ) + { + SwFrmFmt *pFmt = new SwFrmFmt( GetAttrPool(), "Header", + GetDfltFrmFmt() ); + ::lcl_DescSetAttr( *pRight, *pFmt, FALSE ); + //Der Bereich auf den das rechte Kopfattribut zeigt wird + //kopiert und der Index auf den StartNode in das linke + //Kopfattribut gehaengt. + SwNodeIndex aTmp( GetNodes().GetEndOfAutotext() ); + SwStartNode* pSttNd = GetNodes().MakeEmptySection( aTmp, SwHeaderStartNode ); + SwNodeRange aRange( aRCnt.GetCntntIdx()->GetNode(), 0, + *aRCnt.GetCntntIdx()->GetNode().EndOfSectionNode() ); + aTmp = *pSttNd->EndOfSectionNode(); + GetNodes()._Copy( aRange, aTmp, FALSE ); + + pFmt->SetAttr( SwFmtCntnt( pSttNd ) ); + pDesc->GetLeft().SetAttr( SwFmtHeader( pFmt ) ); + } + else + ::lcl_DescSetAttr( *pRight, + *(SwFrmFmt*)rLeftHead.GetHeaderFmt(), FALSE ); + + } + } + pDesc->ChgHeaderShare( rChged.IsHeaderShared() ); + + //Footer abgleichen. + const SwFmtFooter &rFoot = rChged.GetMaster().GetFooter(); + if( DoesUndo() ) + { + // hat sich an den Nodes etwas veraendert ? + //JP erstmal ein Hack, solange keine Headers/Footers Undofaehig sind + const SwFmtFooter &rOldFoot = pDesc->GetMaster().GetFooter(); + if( rFoot.IsActive() != rOldFoot.IsActive() || + rChged.IsFooterShared() != pDesc->IsFooterShared() ) + { + // erstmal werden alle Undo - Objecte geloescht. + ClearRedo(); + DelAllUndoObj(); + } + } + pDesc->GetMaster().SetAttr( rFoot ); + if ( rChged.IsFooterShared() || !rFoot.IsActive() ) + //Left teilt sich den Header mit dem Master. + pDesc->GetLeft().SetAttr( pDesc->GetMaster().GetFooter() ); + else if ( rFoot.IsActive() ) + { //Left bekommt einen eigenen Footer verpasst wenn das Format nicht + //bereits einen hat. + //Wenn er bereits einen hat und dieser auf die gleiche Section + //wie der Rechte zeigt, so muss er einen eigenen bekommen. Der + //Inhalt wird sinnigerweise kopiert. + const SwFmtFooter &rLeftFoot = pDesc->GetLeft().GetFooter(); + if ( !rLeftFoot.IsActive() ) + { + SwFmtFooter aFoot( MakeLayoutFmt( RND_STD_FOOTER ) ); + pDesc->GetLeft().SetAttr( aFoot ); + //Weitere Attribute (Raender, Umrandung...) uebernehmen. + ::lcl_DescSetAttr( *rFoot.GetFooterFmt(), *aFoot.GetFooterFmt(), FALSE); + } + else + { + const SwFrmFmt *pRight = rFoot.GetFooterFmt(); + const SwFmtCntnt &aRCnt = pRight->GetCntnt(); + const SwFmtCntnt &aLCnt = rLeftFoot.GetFooterFmt()->GetCntnt(); + if ( (*aRCnt.GetCntntIdx()) == (*aLCnt.GetCntntIdx()) ) + { + SwFrmFmt *pFmt = new SwFrmFmt( GetAttrPool(), "Footer", + GetDfltFrmFmt() ); + ::lcl_DescSetAttr( *pRight, *pFmt, FALSE ); + //Der Bereich auf den das rechte Kopfattribut zeigt wird + //kopiert und der Index auf den StartNode in das linke + //Kopfattribut gehaengt. + SwNodeIndex aTmp( GetNodes().GetEndOfAutotext() ); + SwStartNode* pSttNd = GetNodes().MakeEmptySection( aTmp, SwFooterStartNode ); + SwNodeRange aRange( aRCnt.GetCntntIdx()->GetNode(), 0, + *aRCnt.GetCntntIdx()->GetNode().EndOfSectionNode() ); + aTmp = *pSttNd->EndOfSectionNode(); + GetNodes()._Copy( aRange, aTmp, FALSE ); + + pFmt->SetAttr( SwFmtCntnt( pSttNd ) ); + pDesc->GetLeft().SetAttr( SwFmtFooter( pFmt ) ); + } + else + ::lcl_DescSetAttr( *pRight, + *(SwFrmFmt*)rLeftFoot.GetFooterFmt(), FALSE ); + } + } + pDesc->ChgFooterShare( rChged.IsFooterShared() ); + + if ( pDesc->GetName() != rChged.GetName() ) + pDesc->SetName( rChged.GetName() ); + + // Dadurch wird ein RegisterChange ausgeloest, wenn notwendig + pDesc->SetRegisterFmtColl( rChged.GetRegisterFmtColl() ); + + //Wenn sich das UseOn oder der Follow aendern muessen die + //Absaetze das erfahren. + BOOL bUseOn = FALSE; + BOOL bFollow = FALSE; + if ( pDesc->GetUseOn() != rChged.GetUseOn() ) + { pDesc->SetUseOn( rChged.GetUseOn() ); + bUseOn = TRUE; + } + if ( pDesc->GetFollow() != rChged.GetFollow() ) + { if ( rChged.GetFollow() == &rChged ) + { if ( pDesc->GetFollow() != pDesc ) + { pDesc->SetFollow( pDesc ); + bFollow = TRUE; + } + } + else + { pDesc->SetFollow( rChged.pFollow ); + bFollow = TRUE; + } + } + + if ( (bUseOn || bFollow) && GetRootFrm() ) + //Layot benachrichtigen! + GetRootFrm()->CheckPageDescs( (SwPageFrm*)GetRootFrm()->Lower() ); + + //Jetzt noch die Seiten-Attribute uebernehmen. + ::lcl_DescSetAttr( rChged.GetMaster(), pDesc->GetMaster() ); + ::lcl_DescSetAttr( rChged.GetLeft(), pDesc->GetLeft() ); + + //Wenn sich FussnotenInfo veraendert, so werden die Seiten + //angetriggert. + if( !(pDesc->GetFtnInfo() == rChged.GetFtnInfo()) ) + { + pDesc->SetFtnInfo( rChged.GetFtnInfo() ); + SwMsgPoolItem aInfo( RES_PAGEDESC_FTNINFO ); + { + SwClientIter aIter( pDesc->GetMaster() ); + for( SwClient* pLast = aIter.First(TYPE(SwFrm)); pLast; + pLast = aIter.Next() ) + pLast->Modify( &aInfo, 0 ); + } + { + SwClientIter aIter( pDesc->GetLeft() ); + for( SwClient* pLast = aIter.First(TYPE(SwFrm)); pLast; + pLast = aIter.Next() ) + pLast->Modify( &aInfo, 0 ); + } + } + SetModified(); +} + +/************************************************************************* +|* +|* SwDoc::DelPageDesc() +|* +|* Beschreibung Alle Descriptoren, deren Follow auf den zu loeschenden +|* zeigen muessen angepasst werden. +|* Ersterstellung MA 25. Jan. 93 +|* Letzte Aenderung JP 04.09.95 +|* +|*************************************************************************/ + +void lcl_RemoveFrms( SwFrmFmt& rFmt, FASTBOOL& rbFtnsRemoved ) +{ + SwClientIter aIter( rFmt ); + SwFrm *pFrm; + for( pFrm = (SwFrm*)aIter.First(TYPE(SwFrm)); pFrm; + pFrm = (SwFrm*)aIter.Next() ) + if ( !rbFtnsRemoved && pFrm->IsPageFrm() && + ((SwPageFrm*)pFrm)->IsFtnPage() ) + { + rFmt.GetDoc()->GetRootFrm()->RemoveFtns( 0, FALSE, TRUE ); + rbFtnsRemoved = TRUE; + } + else + { + pFrm->Cut(); + delete pFrm; + } +} + + +void SwDoc::DelPageDesc( USHORT i ) +{ + ASSERT( i < aPageDescs.Count(), "PageDescs ueberindiziert." ); + ASSERT( i != 0, "Default Pagedesc loeschen is nicht." ); + if ( i == 0 ) + return; + + SwPageDesc *pDel = aPageDescs[i]; + + SwFmtPageDesc aDfltDesc( aPageDescs[0] ); + SwClientIter aIter( *pDel ); + SwClient* pLast; + while( 0 != ( pLast = aIter.GoRoot() )) + { + if( pLast->ISA( SwFmtPageDesc ) ) + { + const SwModify* pMod = ((SwFmtPageDesc*)pLast)->GetDefinedIn(); + if ( pMod ) + { + if( pMod->ISA( SwCntntNode ) ) + ((SwCntntNode*)pMod)->SetAttr( aDfltDesc ); + else if( pMod->ISA( SwFmt )) + ((SwFmt*)pMod)->SetAttr( aDfltDesc ); + else + { + ASSERT( !this, "was ist das fuer ein Mofify-Obj?" ); + aPageDescs[0]->Add( pLast ); + } + } + else //Es kann noch eine Undo-Kopie existieren + aPageDescs[0]->Add( pLast ); + } + + BOOL bFtnInf = FALSE; + if ( TRUE == (bFtnInf = pLast == pFtnInfo->GetPageDescDep()) || + pLast == pEndNoteInfo->GetPageDescDep() ) + { + aPageDescs[0]->Add( pLast ); + if ( GetRootFrm() ) + GetRootFrm()->CheckFtnPageDescs( !bFtnInf ); + } + } + + for ( USHORT j = 0; j < aPageDescs.Count(); ++j ) + { + if ( aPageDescs[j]->GetFollow() == pDel ) + { + aPageDescs[j]->SetFollow( 0 ); + //Clients des PageDesc sind die Attribute, denen sagen wir bescheid. + //die Attribute wiederum reichen die Meldung an die Absaetze weiter. + + //Layot benachrichtigen! + if( GetRootFrm() ) // ist nicht immer vorhanden!! (Orginizer) + GetRootFrm()->CheckPageDescs( (SwPageFrm*)GetRootFrm()->Lower() ); + } + } + + if( GetRootFrm() ) // ist nicht immer vorhanden!! (Orginizer) + { + //Wenn jetzt noch irgendwelche Seiten auf die FrmFmt'e (Master und Left) + //Zeigen (z.B. irgendwelche Fussnotenseiten), so muessen die Seiten + //vernichtet werden. + + // Wenn wir auf Endnotenseiten stossen, schmeissen wir alle Fussnoten weg, + // anders kann die Reihenfolge der Seiten (FollowsPageDescs usw.) + // nicht garantiert werden. + FASTBOOL bFtnsRemoved = FALSE; + + ::lcl_RemoveFrms( pDel->GetMaster(), bFtnsRemoved ); + ::lcl_RemoveFrms( pDel->GetLeft(), bFtnsRemoved ); + } + + aPageDescs.Remove( i ); + delete pDel; + SetModified(); +} + +/************************************************************************* +|* +|* SwDoc::MakePageDesc() +|* +|* Ersterstellung MA 25. Jan. 93 +|* Letzte Aenderung MA 20. Aug. 93 +|* +|*************************************************************************/ + +USHORT SwDoc::MakePageDesc( const String &rName, const SwPageDesc *pCpy) +{ + SwPageDesc *pNew; + if( pCpy ) + { + pNew = new SwPageDesc( *pCpy ); + pNew->SetName( rName ); + if( rName != pCpy->GetName() ) + { + pNew->SetPoolFmtId( USHRT_MAX ); + pNew->SetPoolHelpId( USHRT_MAX ); + pNew->SetPoolHlpFileId( UCHAR_MAX ); + } + } + else + { + pNew = new SwPageDesc( rName, GetDfltFrmFmt(), this ); + //Default-Seitenformat einstellen. + ::lcl_DefaultPageFmt( pNew->GetMaster(), pNew->GetLeft(), GetPrt(), FALSE ); + if( GetPrt() ) + pNew->SetLandscape( ORIENTATION_LANDSCAPE == + GetPrt()->GetOrientation() ); + } + aPageDescs.Insert( pNew, aPageDescs.Count() ); + SetModified(); + return (aPageDescs.Count()-1); +} + +SwPageDesc* SwDoc::FindPageDescByName( const String& rName, USHORT* pPos ) const +{ + SwPageDesc* pRet = 0; + if( pPos ) *pPos = USHRT_MAX; + + for( USHORT n = 0, nEnd = aPageDescs.Count(); n < nEnd; ++n ) + if( aPageDescs[ n ]->GetName() == rName ) + { + pRet = aPageDescs[ n ]; + if( pPos ) + *pPos = n; + break; + } + return pRet; +} + +/****************************************************************************** + * Methode : void SwDoc::SetPrt( SfxPrinter *pP ) + * Beschreibung: + * Erstellt : OK 27.10.94 10:20 + * Aenderung : MA 26. Mar. 98 + ******************************************************************************/ + +void SwDoc::PrtDataChanged() +{ +//!!!!!!!! Bei Aenderungen hier bitte ggf. InJobSetup im Sw3io mitpflegen + + SwWait *pWait = 0; + BOOL bEndAction = FALSE; + + if( GetDocShell() ) + GetDocShell()->UpdateFontList(); + + BOOL bDraw = TRUE; + if ( GetRootFrm() ) + { + ViewShell *pSh = GetRootFrm()->GetCurrShell(); + if( !IsBrowseMode() || ( pSh && pSh->GetViewOptions()->IsPrtFormat() ) ) + { + if ( GetDocShell() ) + pWait = new SwWait( *GetDocShell(), TRUE ); + + GetRootFrm()->StartAllAction(); + bEndAction = TRUE; + + bDraw = FALSE; + if( pDrawModel ) + pDrawModel->SetRefDevice( pPrt ); + + pFntCache->Flush(); + GetRootFrm()->InvalidateAllCntnt(); + + if ( pSh ) + { + do + { pSh->InitPrt( pPrt ); + pSh = (ViewShell*)pSh->GetNext(); + } while ( pSh != GetRootFrm()->GetCurrShell() ); + } + + } + } + if ( bDraw && pDrawModel && pPrt && pPrt != pDrawModel->GetRefDevice() ) + pDrawModel->SetRefDevice( pPrt ); + + PrtOLENotify( TRUE ); + + if ( bEndAction ) + GetRootFrm()->EndAllAction(); + delete pWait; +} + +//Zur Laufzeit sammeln wir die GlobalNames der Server, die keine +//Benachrichtigung zu Druckerwechseln wuenschen. Dadurch sparen wir +//das Laden vieler Objekte (gluecklicherweise werden obendrein alle +//Fremdobjekte unter einer ID abgebuildet). Init und DeInit vom Array +//ist in init.cxx zu finden. +extern SvPtrarr *pGlobalOLEExcludeList; + +void SwDoc::PrtOLENotify( BOOL bAll ) +{ + SwFEShell *pShell = 0; + if ( GetRootFrm() && GetRootFrm()->GetCurrShell() ) + { + ViewShell *pSh = GetRootFrm()->GetCurrShell(); + if ( !pSh->ISA(SwFEShell) ) + do + { pSh = (ViewShell*)pSh->GetNext(); + } while ( !pSh->ISA(SwFEShell) && + pSh != GetRootFrm()->GetCurrShell() ); + + if ( pSh->ISA(SwFEShell) ) + pShell = (SwFEShell*)pSh; + } + if ( !pShell ) + { + //Das hat ohne Shell und damit ohne Client keinen Sinn, weil nur darueber + //die Kommunikation bezueglich der Groessenaenderung implementiert ist. + //Da wir keine Shell haben, merken wir uns diesen unguenstigen + //Zustand am Dokument, dies wird dann beim Erzeugen der ersten Shell + //nachgeholt. + bOLEPrtNotifyPending = TRUE; + if ( bAll ) + bAllOLENotify = TRUE; + } + else + { + if ( bAllOLENotify ) + bAll = TRUE; + + bOLEPrtNotifyPending = bAllOLENotify = FALSE; + + + SwOLENodes *pNodes = 0; + SwClientIter aIter( *(SwModify*)GetDfltGrfFmtColl() ); + for( SwCntntNode* pNd = (SwCntntNode*)aIter.First( TYPE( SwCntntNode ) ); + pNd; + pNd = (SwCntntNode*)aIter.Next() ) + { + SwOLENode *pONd; + if ( 0 != (pONd = pNd->GetOLENode()) && + (bAll || pONd->IsOLESizeInvalid()) ) + { + if ( !pNodes ) + pNodes = new SwOLENodes; + pNodes->Insert( pONd, pNodes->Count() ); + } + } + + if ( pNodes ) + { + ::StartProgress( STR_STATSTR_SWGPRTOLENOTIFY, + 0, pNodes->Count(), GetDocShell()); + GetRootFrm()->StartAllAction(); + + for( USHORT i = 0; i < pNodes->Count(); ++i ) + { + ::SetProgressState( i, GetDocShell() ); + + SwOLENode* pOLENd = (*pNodes)[i]; + pOLENd->SetOLESizeInvalid( FALSE ); + + //Ersteinmal die Infos laden und festellen ob das Teil nicht + //schon in der Exclude-Liste steht + SvGlobalName aName; + + if ( !pOLENd->GetOLEObj().IsOleRef() ) //Noch nicht geladen + { + String sBaseURL( INetURLObject::GetBaseURL() ); + const SfxMedium *pMedium; + if( 0 != (pMedium = GetDocShell()->GetMedium()) && + pMedium->GetName() != sBaseURL ) + INetURLObject::SetBaseURL( pMedium->GetName() ); + SvInfoObjectRef xInfo = GetPersist()->Find( pOLENd->GetOLEObj().GetName() ); + if ( xInfo.Is() ) //Muss normalerweise gefunden werden + aName = xInfo->GetClassName(); + INetURLObject::SetBaseURL( sBaseURL ); + } + else + aName = pOLENd->GetOLEObj().GetOleRef()->GetClassName(); + + BOOL bFound = FALSE; + for ( USHORT i = 0; + i < pGlobalOLEExcludeList->Count() && !bFound; + ++i ) + { + bFound = *(SvGlobalName*)(*pGlobalOLEExcludeList)[i] == + aName; + } + if ( bFound ) + continue; + + //Kennen wir nicht, also muss das Objekt geladen werden. + //Wenn es keine Benachrichtigung wuenscht + SvEmbeddedObjectRef xRef( (SvInPlaceObject*) pOLENd->GetOLEObj().GetOleRef() ); + if ( xRef ) //Kaputt? + { + if ( SVOBJ_MISCSTATUS_RESIZEONPRINTERCHANGE & xRef->GetMiscStatus()) + { + if ( pOLENd->GetFrm() ) + { + xRef->OnDocumentPrinterChanged( pPrt ); + pShell->CalcAndSetScale( xRef );//Client erzeugen lassen. + } + else + pOLENd->SetOLESizeInvalid( TRUE ); + } + else + pGlobalOLEExcludeList->Insert( + new SvGlobalName( xRef->GetClassName()), + pGlobalOLEExcludeList->Count() ); + } + } + delete pNodes; + GetRootFrm()->EndAllAction(); + ::EndProgress( GetDocShell() ); + } + } +} + +void SwDoc::SetPrt( SfxPrinter *pP ) +{ + ASSERT( pP, "Kein Drucker !" ); + + const BOOL bInitPageDesc = pPrt == 0; + + if ((ULONG) pP != (ULONG) pPrt) + { + delete pPrt; + pPrt = pP; + PrtDataChanged(); + } + + if( bInitPageDesc ) + { + // JP 17.04.97: Bug 38924 - falls noch kein Drucker gesetzt war + // und der PageDesc nicht eingelesen wurde + // -> passe an den Drucker an + if( pPrt && LONG_MAX == _GetPageDesc( 0 ).GetMaster().GetFrmSize().GetWidth() ) + _GetPageDesc( 0 ).SetLandscape( ORIENTATION_LANDSCAPE == + pPrt->GetOrientation() ); + + //Ggf. Standard Seitenformat anhand des Druckers einstellen. + //lcl_DefaultPageFmt() merkt ob ein Reader das Fmt veraendert hat. + + //MA 11. Mar. 97: Das sollten wir fuer alle Formate tun, weil die + //Werte auf LONG_MAX initalisiert sind (spaetes anlegen des Druckers) + //und die Reader u.U. "unfertige" Formate stehenlassen. + for ( USHORT i = 0; i < GetPageDescCnt(); ++i ) + { + ::lcl_DefaultPageFmt( _GetPageDesc( i ).GetMaster(), + _GetPageDesc( i ).GetLeft(), + pPrt, TRUE ); + } + } +} + +/* + * Kleiner Hack; + * +const SwPageDesc& SwDoc::GetPageDesc( USHORT i ) const +{ + if( !i && !aPageDescs.Count() ) // noch keiner vorhanden? + ((SwDoc*)this)->InitPageDescs(); //Default PageDescriptor + return *aPageDescs[i]; +} + +SwPageDesc& SwDoc::_GetPageDesc( USHORT i ) const +{ + if( !i && !aPageDescs.Count() ) // noch keiner vorhanden? + ((SwDoc*)this)->InitPageDescs(); //Default PageDescriptor + return *aPageDescs[i]; +} +*/ + + + +IMPL_LINK( SwDoc, DoUpdateModifiedOLE, Timer *, pTimer ) +{ + SwFEShell* pSh = (SwFEShell*)GetEditShell(); + if( pSh ) + { + bOLEPrtNotifyPending = bAllOLENotify = FALSE; + + SwOLENodes aOLENodes; + SwClientIter aIter( *(SwModify*)GetDfltGrfFmtColl() ); + for( SwCntntNode* pNd = (SwCntntNode*)aIter.First( TYPE( SwCntntNode ) ); + pNd; + pNd = (SwCntntNode*)aIter.Next() ) + { + SwOLENode *pONd = pNd->GetOLENode(); + if( pONd && pONd->IsOLESizeInvalid() ) + { + aOLENodes.Insert( pONd, aOLENodes.Count() ); + } + } + + if( aOLENodes.Count() ) + { + ::StartProgress( STR_STATSTR_SWGPRTOLENOTIFY, + 0, aOLENodes.Count(), GetDocShell()); + GetRootFrm()->StartAllAction(); + SwMsgPoolItem aMsgHint( RES_UPDATE_ATTR ); + + for( USHORT i = 0; i < aOLENodes.Count(); ++i ) + { + ::SetProgressState( i, GetDocShell() ); + + SwOLENode* pOLENd = aOLENodes[i]; + pOLENd->SetOLESizeInvalid( FALSE ); + + //Kennen wir nicht, also muss das Objekt geladen werden. + //Wenn es keine Benachrichtigung wuenscht + SvEmbeddedObjectRef xRef( (SvInPlaceObject*) + pOLENd->GetOLEObj().GetOleRef() ); + if( xRef ) //Kaputt? + { + if( SVOBJ_MISCSTATUS_RESIZEONPRINTERCHANGE & + xRef->GetMiscStatus() ) + { + if( pOLENd->GetFrm() ) + { + xRef->OnDocumentPrinterChanged( pPrt ); + pSh->CalcAndSetScale( xRef );//Client erzeugen lassen. + } + else + pOLENd->SetOLESizeInvalid( TRUE ); + } + // repaint it + pOLENd->Modify( &aMsgHint, &aMsgHint ); + } + } + GetRootFrm()->EndAllAction(); + ::EndProgress( GetDocShell() ); + } + } + return 0; +} + + + + diff --git a/sw/source/core/doc/docdraw.cxx b/sw/source/core/doc/docdraw.cxx new file mode 100644 index 000000000000..8de7deb68c94 --- /dev/null +++ b/sw/source/core/doc/docdraw.cxx @@ -0,0 +1,671 @@ +/************************************************************************* + * + * $RCSfile: docdraw.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:15 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _HINTIDS_HXX +#include +#endif + +#ifndef _OUTDEV_HXX //autogen +#include +#endif +#ifndef _SFX_PRINTER_HXX //autogen +#include +#endif +#ifndef _EEITEM_HXX +#include +#endif +#ifndef _SVX_FLDITEM_HXX //autogen +#define ITEMID_FIELD EE_FEATURE_FIELD +#include +#endif +#ifndef _MyEDITENG_HXX //autogen +#include +#endif +#ifndef _SVDOUTL_HXX +#include +#endif +#ifndef _SVX_COLRITEM_HXX //autogen +#include +#endif +#ifndef _SVDPAGE_HXX //autogen +#include +#endif +#ifndef _SVDOGRP_HXX //autogen +#include +#endif +#ifndef _SVX_LANGITEM_HXX +#include +#endif + +#ifndef _UNO_LINGU_HXX +#include +#endif +#ifndef _OFF_APP_HXX //autogen +#include +#endif + +#ifndef _SVDOMEAS_HXX +#include +#endif +#ifndef _SVDPOOL_HXX //autogen +#include +#endif + +#ifndef _FMTANCHR_HXX //autogen +#include +#endif +#ifndef _CHARATR_HXX +#include +#endif +#ifndef _FRMFMT_HXX //autogen +#include +#endif +#ifndef _CHARFMT_HXX //autogen +#include +#endif +#ifndef _VIEWIMP_HXX //autogen +#include +#endif +#ifndef _SWHINTS_HXX +#include +#endif +#ifndef _DOC_HXX +#include +#endif +#ifndef _DOCSH_HXX +#include +#endif +#ifndef _ROOTFRM_HXX +#include //Damit der RootDtor gerufen wird. +#endif +#ifndef _FRAME_HXX +#include +#endif +#ifndef _POOLFMT_HXX +#include +#endif +#ifndef _VIEWSH_HXX +#include // fuer MakeDrawView +#endif +#ifndef _DRAWDOC_HXX +#include +#endif +#ifndef _UNDOBJ_HXX +#include +#endif +#ifndef _SWUNDO_HXX +#include // fuer die UndoIds +#endif +#ifndef _DCONTACT_HXX +#include +#endif +#ifndef _DVIEW_HXX +#include +#endif +#ifndef _MVSAVE_HXX +#include +#endif +#ifndef _FLYFRM_HXX +#include +#endif +#ifndef _DFLYOBJ_HXX +#include +#endif + +using namespace ::com::sun::star; + + +SV_IMPL_VARARR_SORT( _ZSortFlys, _ZSortFly ) + +/************************************************************************* +|* +|* SwDoc::GroupSelection / SwDoc::UnGroupSelection +|* +|* Ersterstellung JP 21.08.95 +|* Letzte Aenderung JP 21.08.95 +|* +|*************************************************************************/ + +SwDrawContact* SwDoc::GroupSelection( SdrView& rDrawView ) +{ + const SdrMarkList &rMrkList = rDrawView.GetMarkList(); + SwDrawFrmFmt *pFmt; + SdrObject *pObj = rMrkList.GetMark( 0 )->GetObj(); + BOOL bNoGroup = ( 0 == pObj->GetUpGroup() ); + if( bNoGroup ) + { + //Ankerattribut aufheben. + SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj); + const SwFmtAnchor aAnch( pContact->GetFmt()->GetAnchor() ); + //Ankerpos des ersten, um die Objekte zu synchronisieren. + Point aAnchPos( pObj->GetAnchorPos() ); + + SwUndoDrawGroup* pUndo = !DoesUndo() ? 0 : new SwUndoDrawGroup( + (USHORT)rMrkList.GetMarkCount() ); + + //ContactObjekte und Formate vernichten. + for( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i ) + { + pObj = rMrkList.GetMark( i )->GetObj(); + SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj); + + //Ankerpos und Relpos synchronisieren, damit die Position der + //Objekte erhalten bleibt. + const Point aAbs( pContact->GetAnchor()->Frm().Pos() + + pObj->GetRelativePos() ); + + pFmt = (SwDrawFrmFmt*)pContact->GetFmt(); + //loescht sich selbst! + pContact->Changed(*pObj, SDRUSERCALL_DELETE, pObj->GetBoundRect() ); + pObj->SetUserCall( 0 ); + + if( pUndo ) + pUndo->AddObj( i, pFmt, pObj ); + else + DelFrmFmt( pFmt ); + + pObj->NbcSetRelativePos( aAbs - aAnchPos ); + pObj->NbcSetAnchorPos( aAnchPos ); + } + + pFmt = MakeDrawFrmFmt( String::CreateFromAscii( + RTL_CONSTASCII_STRINGPARAM( "DrawObject" )), + GetDfltFrmFmt() ); + pFmt->SetAttr( aAnch ); + + if( pUndo ) + { + pUndo->SetGroupFmt( pFmt ); + ClearRedo(); + AppendUndo( pUndo ); + } + } + else if( DoesUndo() ) + ClearRedo(); + + rDrawView.GroupMarked(); + ASSERT( rMrkList.GetMarkCount() == 1, "GroupMarked more or none groups." ); + SwDrawContact *pNewContact = 0; + if( bNoGroup ) + { + pNewContact = new SwDrawContact( pFmt, rMrkList.GetMark( 0 )->GetObj() ); + pNewContact->ConnectToLayout(); + } + return pNewContact; +} + + +void SwDoc::UnGroupSelection( SdrView& rDrawView ) +{ + int bUndo = DoesUndo(); + if( bUndo ) + ClearRedo(); + const SdrMarkList &rMrkList = rDrawView.GetMarkList(); + if( rMrkList.GetMarkCount() ) + { + SdrObject *pObj = rMrkList.GetMark( 0 )->GetObj(); + if( !pObj->GetUpGroup() ) + { + String sDrwFmtNm( String::CreateFromAscii( + RTL_CONSTASCII_STRINGPARAM("DrawObject" ))); + for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i ) + { + SdrObject *pObj = rMrkList.GetMark( i )->GetObj(); + if ( pObj->IsA( TYPE(SdrObjGroup) ) ) + { + SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj); + SwFmtAnchor aAnch( pContact->GetFmt()->GetAnchor() ); + SdrObjList *pLst = ((SdrObjGroup*)pObj)->GetSubList(); + + SwUndoDrawUnGroup* pUndo = 0; + if( bUndo ) + { + pUndo = new SwUndoDrawUnGroup( (SdrObjGroup*)pObj ); + AppendUndo( pUndo ); + } + + for ( USHORT i2 = 0; i2 < pLst->GetObjCount(); ++i2 ) + { + SdrObject *pSubObj = pLst->GetObj( i2 ); + SwDrawFrmFmt *pFmt = MakeDrawFrmFmt( sDrwFmtNm, + GetDfltFrmFmt() ); + pFmt->SetAttr( aAnch ); + SwDrawContact *pContact = new SwDrawContact( pFmt, pSubObj ); + pContact->ConnectToLayout(); + + if( bUndo ) + pUndo->AddObj( i2, pFmt ); + } + } + } + } + } + rDrawView.UnGroupMarked(); +} + +/************************************************************************* +|* +|* SwDoc::DeleteSelection() +|* +|* Ersterstellung MA 14. Nov. 95 +|* Letzte Aenderung MA 14. Nov. 95 +|* +|*************************************************************************/ + +BOOL SwDoc::DeleteSelection( SwDrawView& rDrawView ) +{ + BOOL bCallBase = FALSE; + const SdrMarkList &rMrkList = rDrawView.GetMarkList(); + if( rMrkList.GetMarkCount() ) + { + StartUndo(); + USHORT i; + FASTBOOL bDelMarked = TRUE; + + if( 1 == rMrkList.GetMarkCount() ) + { + SdrObject *pObj = rMrkList.GetMark( 0 )->GetObj(); + if( pObj->IsWriterFlyFrame() ) + { + SwFlyFrmFmt* pFrmFmt = (SwFlyFrmFmt*) + ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->GetFmt(); + if( pFrmFmt ) + { +#if 0 +// JP 28.09.98: erstmal wuerde ich NEIN sagen. +// muss das sein ???? + // ggfs. die CrsrPosition umsetzen + SwCrsrShell* pCShell = PTR_CAST( SwCrsrShell, + rDrawView.Imp().GetShell() ); + if( pCShell ) + { + SwRect& rChrRect = (SwRect&)pCShell->GetCharRect(); + SwFlyFrm* pFly = pFrmFmt->GetFrm( &rChrRect.Pos(), FALSE ); + + if( pFly && pFly->IsFlyInCntFrm() ) + { + rChrRect = pFly->Frm(); + pCShell->GetCrsrDocPos() = rChrRect.Pos(); + } + } +// muss das sein ???? +#endif + DelLayoutFmt( pFrmFmt ); + bDelMarked = FALSE; + } + } + } + + for( i = 0; i < rMrkList.GetMarkCount(); ++i ) + { + SdrObject *pObj = rMrkList.GetMark( i )->GetObj(); + if( !pObj->IsWriterFlyFrame() ) + { + SwDrawContact *pC = (SwDrawContact*)GetUserCall(pObj); + SwDrawFrmFmt *pFrmFmt = (SwDrawFrmFmt*)pC->GetFmt(); + if( pFrmFmt && + FLY_IN_CNTNT == pFrmFmt->GetAnchor().GetAnchorId() ) + { + rDrawView.MarkObj( pObj, rDrawView.Imp().GetPageView(), TRUE ); + --i; + DelLayoutFmt( pFrmFmt ); + } + } + } + + if( rMrkList.GetMarkCount() && bDelMarked ) + { + SdrObject *pObj = rMrkList.GetMark( 0 )->GetObj(); + if( !pObj->GetUpGroup() ) + { + SwUndoDrawDelete* pUndo = !DoesUndo() ? 0 + : new SwUndoDrawDelete( (USHORT)rMrkList.GetMarkCount() ); + + //ContactObjekte vernichten, Formate sicherstellen. + for( i = 0; i < rMrkList.GetMarkCount(); ++i ) + { + pObj = rMrkList.GetMark( i )->GetObj(); + SwDrawContact *pContact = (SwDrawContact*)pObj->GetUserCall(); + if( pContact ) // natuerlich nicht bei gruppierten Objekten + { + SwDrawFrmFmt *pFmt = (SwDrawFrmFmt*)pContact->GetFmt(); + //loescht sich selbst! + pContact->Changed(*pObj, SDRUSERCALL_DELETE, pObj->GetBoundRect() ); + pObj->SetUserCall( 0 ); + + if( pUndo ) + pUndo->AddObj( i, pFmt, pObj ); + else + DelFrmFmt( pFmt ); + } + } + + if( pUndo ) + AppendUndo( pUndo ); + } + bCallBase = TRUE; + } + SetModified(); + + EndUndo(); + } + + return bCallBase; +} + +/************************************************************************* +|* +|* SwDoc::DeleteSelection() +|* +|* Ersterstellung JP 11.01.96 +|* Letzte Aenderung JP 11.01.96 +|* +|*************************************************************************/ + +_ZSortFly::_ZSortFly( const SwFrmFmt* pFrmFmt, const SwFmtAnchor* pFlyAn, + UINT32 nArrOrdNum ) + : pFmt( pFrmFmt ), pAnchor( pFlyAn ), nOrdNum( nArrOrdNum ) +{ + if( pFmt->GetDoc()->GetRootFrm() ) + { + SwClientIter aIter( (SwFmt&)*pFmt ); + if( RES_FLYFRMFMT == pFmt->Which() ) + { + // Schauen, ob es ein SdrObject dafuer gibt + if( aIter.First( TYPE( SwFlyFrm) ) ) + nOrdNum = ((SwFlyFrm*)aIter())->GetVirtDrawObj()->GetOrdNum(); + } + else if( RES_DRAWFRMFMT == pFmt->Which() ) + { + // Schauen, ob es ein SdrObject dafuer gibt + if( aIter.First( TYPE(SwDrawContact) ) ) + nOrdNum = ((SwDrawContact*)aIter())->GetMaster()->GetOrdNum(); + } + else + ASSERT( !this, "was ist das fuer ein Format?" ); + } +} + +/*************************************************************************/ +// Wird auch vom Sw3-Reader gerufen, wenn ein Fehler beim Einlesen +// des Drawing Layers auftrat. In diesem Fall wird der Layer komplett +// neu aufgebaut. + + +void SwDoc::InitDrawModel() +{ + //!!Achtung im sw3-Reader (sw3imp.cxx) gibt es aehnlichen Code, der + //mitgepfelgt werden muss. + if ( pDrawModel ) + ReleaseDrawModel(); + + //DrawPool und EditEnginePool anlegen, diese gehoeren uns und werden + //dem Drawing nur mitgegeben. Im ReleaseDrawModel werden die Pools wieder + //zerstoert. + // 17.2.99: for Bug 73110 - for loading the drawing items. This must + // be loaded without RefCounts! + SfxItemPool *pSdrPool = new SdrItemPool( &aAttrPool, SDRATTR_START, + SDRATTR_END, FALSE ); + SfxItemPool *pEEgPool = EditEngine::CreatePool( FALSE ); + pSdrPool->SetSecondaryPool( pEEgPool ); + aAttrPool.FreezeIdRanges(); + + //Das SdrModel gehoert dem Dokument, wir haben immer zwei Layer und eine + //Seite. + pDrawModel = new SwDrawDocument( this ); + + String sLayerNm; + sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("Hell" )); + nHell = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID(); + + sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("Heaven" )); + nHeaven = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID(); + + sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("Controls" )); + nControls = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID(); + + pDrawModel->InsertPage( pDrawModel->AllocPage( FALSE ) ); + SdrOutliner& rOutliner = pDrawModel->GetDrawOutliner(); + uno::Reference< linguistic::XSpellChecker1> xSpell = OFF_APP()->GetSpellChecker(); + rOutliner.SetSpeller( xSpell ); + rOutliner.SetHyphenator( ::GetHyphenator() ); + const SfxPoolItem& rItem = GetDefault(RES_CHRATR_LANGUAGE); + rOutliner.SetDefaultLanguage(((const SvxLanguageItem&)rItem).GetLanguage()); + + SetCalcFieldValueHdl(&rOutliner); + SetCalcFieldValueHdl(&pDrawModel->GetHitTestOutliner()); + + //JP 16.07.98: Bug 50193 - Linkmanager am Model setzen, damit + // dort ggfs. verlinkte Grafiken eingefuegt werden koennen + //JP 28.01.99: der WinWord Import benoetigt ihn auch + pDrawModel->SetLinkManager( &GetLinkManager() ); + + if( pPrt ) + pDrawModel->SetRefDevice( pPrt ); + pDrawModel->SetNotifyUndoActionHdl( LINK( this, SwDoc, AddDrawUndo )); + if ( pLayout ) + { + pLayout->SetDrawPage( pDrawModel->GetPage( 0 ) ); + pLayout->GetDrawPage()->SetSize( pLayout->Frm().SSize() ); + } +} + +/*************************************************************************/ + + +void SwDoc::ReleaseDrawModel() +{ + if ( pDrawModel ) + { + //!!Den code im sw3io fuer Einfuegen Dokument mitpflegen!! + + delete pDrawModel; pDrawModel = 0; + SfxItemPool *pSdrPool = aAttrPool.GetSecondaryPool(); + + ASSERT( pSdrPool, "missing Pool" ); + SfxItemPool *pEEgPool = pSdrPool->GetSecondaryPool(); + ASSERT( !pEEgPool->GetSecondaryPool(), "i don't accept additional pools"); + pSdrPool->Delete(); //Erst die Items vernichten lassen, + //dann erst die Verkettung loesen + aAttrPool.SetSecondaryPool( 0 ); //Der ist ein muss! + pSdrPool->SetSecondaryPool( 0 ); //Der ist sicherer + delete pSdrPool; + delete pEEgPool; + } +} + +/*************************************************************************/ + + +SdrModel* SwDoc::_MakeDrawModel() +{ + ASSERT( !pDrawModel, "_MakeDrawModel: Why?" ); + InitDrawModel(); + if ( pLayout && pLayout->GetCurrShell() ) + { + ViewShell* pTmp = pLayout->GetCurrShell(); + do + { + pTmp->MakeDrawView(); + pTmp = (ViewShell*) pTmp->GetNext(); + } while ( pTmp != pLayout->GetCurrShell() ); + + //Broadcast, damit die FormShell mit der DrawView verbunden werden kann + if( GetDocShell() ) + { + SfxSimpleHint aHnt( SW_BROADCAST_DRAWVIEWS_CREATED ); + GetDocShell()->Broadcast( aHnt ); + } + } + return pDrawModel; +} + +/*************************************************************************/ + +void SwDoc::DrawNotifyUndoHdl() +{ + pDrawModel->SetNotifyUndoActionHdl( Link() ); +} + +/*************************************************************************/ + +void SwDoc::DrawSetRefDevice() +{ + pDrawModel->SetRefDevice( pPrt ); +} + +/*************************************************************************/ +/* +/* Am Outliner Link auf Methode fuer Felddarstellung in Editobjekten setzen +/* +/*************************************************************************/ + +void SwDoc::SetCalcFieldValueHdl(Outliner* pOutliner) +{ + pOutliner->SetCalcFieldValueHdl(LINK(this, SwDoc, CalcFieldValueHdl)); +} + +/************************************************************************* +|* +|* Felder bzw URLs im Outliner erkennen und Darstellung festlegen +|* +\************************************************************************/ + +IMPL_LINK(SwDoc, CalcFieldValueHdl, EditFieldInfo*, pInfo) +{ + if (pInfo) + { + const SvxFieldItem& rField = pInfo->GetField(); + const SvxFieldData* pField = rField.GetField(); + + if (pField && pField->ISA(SvxDateField)) + { + /****************************************************************** + * Date-Field + ******************************************************************/ + pInfo->SetRepresentation( + ((const SvxDateField*) pField)->GetFormatted(LANGUAGE_SYSTEM, + LANGUAGE_SYSTEM) ); + } + else if (pField && pField->ISA(SvxURLField)) + { + /****************************************************************** + * URL-Field + ******************************************************************/ + + switch ( ((const SvxURLField*) pField)->GetFormat() ) + { + case SVXURLFORMAT_APPDEFAULT: //!!! einstellbar an App??? + case SVXURLFORMAT_REPR: + { + pInfo->SetRepresentation( + ((const SvxURLField*)pField)->GetRepresentation()); + } + break; + + case SVXURLFORMAT_URL: + { + pInfo->SetRepresentation( + ((const SvxURLField*)pField)->GetURL()); + } + break; + } + + USHORT nChrFmt; + + if (IsVisitedURL(((const SvxURLField*)pField)->GetURL())) + nChrFmt = RES_POOLCHR_INET_VISIT; + else + nChrFmt = RES_POOLCHR_INET_NORMAL; + + SwFmt *pFmt = GetCharFmtFromPool(nChrFmt); + + Color aColor(COL_LIGHTBLUE); + if (pFmt) + aColor = pFmt->GetColor().GetValue(); + + pInfo->SetTxtColor(aColor); + } + else if (pField && pField->ISA(SdrMeasureField)) + { + /****************************************************************** + * Measure-Field + ******************************************************************/ + pInfo->ClearFldColor(); + } + else + { + DBG_ERROR("unbekannter Feldbefehl"); + pInfo->SetRepresentation( String( '?' ) ); + } + } + + return(0); +} + + + diff --git a/sw/source/core/doc/docedt.cxx b/sw/source/core/doc/docedt.cxx new file mode 100644 index 000000000000..b763615f8a24 --- /dev/null +++ b/sw/source/core/doc/docedt.cxx @@ -0,0 +1,2252 @@ +/************************************************************************* + * + * $RCSfile: docedt.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:15 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#include // fuer strchr() + +#ifndef _HINTIDS_HXX +#include +#endif + +#ifndef _SOUND_HXX //autogen +#include +#endif +#ifndef _WORDSEL_HXX //autogen +#include +#endif +#ifndef _SVX_CSCOITEM_HXX //autogen +#include +#endif +#ifndef _SVX_BRKITEM_HXX //autogen +#include +#endif +#ifndef _LINGU_LNGPROPS_HHX_ +#include +#endif +#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_ +#include +#endif + +#ifndef _FMTANCHR_HXX //autogen +#include +#endif +#ifndef _FMTCNTNT_HXX //autogen +#include +#endif +#ifndef _FMTPDSC_HXX //autogen +#include +#endif +#ifndef _TXTFTN_HXX //autogen +#include +#endif +#ifndef _ACORRECT_HXX +#include // Autokorrektur +#endif +#ifndef _BOOKMRK_HXX +#include // fuer SwBookmark +#endif +#ifndef _CNTFRM_HXX +#include // fuers Spell +#endif +#ifndef _CRSRSH_HXX +#include +#endif +#ifndef _CRSTATE_HXX +#include +#endif +#ifndef _DOC_HXX +#include +#endif +#ifndef _DOCARY_HXX +#include +#endif +#ifndef _DOCTXM_HXX +#include // beim Move: Verzeichnisse korrigieren +#endif +#ifndef _FTNIDX_HXX +#include +#endif +#ifndef _FTNINFO_HXX +#include +#endif +#ifndef _HINTS_HXX +#include +#endif +#ifndef _MDIEXP_HXX +#include // Statusanzeige +#endif +#ifndef _MVSAVE_HXX +#include // Strukturen zum Sichern beim Move/Delete +#endif +#ifndef _NDTXT_HXX +#include +#endif +#ifndef _NODE_HXX +#include +#endif +#ifndef _PAM_HXX +#include +#endif +#ifndef _REDLINE_HXX +#include +#endif +#ifndef _ROOTFRM_HXX +#include // fuers UpdateFtn +#endif +#ifndef _SECTION_HXX +#include +#endif +#ifndef _SPLARGS_HXX +#include // fuer Spell +#endif +#ifndef _SWTABLE_HXX +#include +#endif +#ifndef _SWUNDO_HXX +#include // fuer die UndoIds +#endif +#ifndef _TXTFRM_HXX +#include +#endif +#ifndef _UNDOBJ_HXX +#include +#endif + + +using namespace ::com::sun::star; +using namespace ::rtl; +//using namespace ::utl; + +#define S2U(rString) OUString::createFromAscii(rString) + + +struct _SaveRedline +{ + SwRedline* pRedl; + sal_uInt32 nStt, nEnd; + xub_StrLen nSttCnt, nEndCnt; + + _SaveRedline( SwRedline* pR, const SwNodeIndex& rSttIdx ) + : pRedl( pR ) + { + const SwPosition* pStt = pR->Start(), + * pEnd = pR->GetMark() == pStt ? pR->GetPoint() : pR->GetMark(); + sal_uInt32 nSttIdx = rSttIdx.GetIndex(); + nStt = pStt->nNode.GetIndex() - nSttIdx; + nSttCnt = pStt->nContent.GetIndex(); + if( pR->HasMark() ) + { + nEnd = pEnd->nNode.GetIndex() - nSttIdx; + nEndCnt = pEnd->nContent.GetIndex(); + } + + pRedl->GetPoint()->nNode = 0; + pRedl->GetPoint()->nContent.Assign( 0, 0 ); + pRedl->GetMark()->nNode = 0; + pRedl->GetMark()->nContent.Assign( 0, 0 ); + } + + void SetPos( sal_uInt32 nInsPos ) + { + pRedl->GetPoint()->nNode = nInsPos + nStt; + pRedl->GetPoint()->nContent.Assign( pRedl->GetCntntNode(), nSttCnt ); + if( pRedl->HasMark() ) + { + pRedl->GetMark()->nNode = nInsPos + nEnd; + pRedl->GetMark()->nContent.Assign( pRedl->GetCntntNode(sal_False), nEndCnt ); + } + } +}; + +SV_DECL_PTRARR_DEL( _SaveRedlines, _SaveRedline*, 0, 4 ) + +SV_IMPL_VARARR( _SaveFlyArr, _SaveFly ) +SV_IMPL_PTRARR( SaveBookmarks, SaveBookmark* ) +SV_IMPL_PTRARR( _SaveRedlines, _SaveRedline* ) + +sal_Bool lcl_MayOverwrite( const SwTxtNode *pNode, const xub_StrLen nPos ) +{ + sal_Bool bRet = sal_True; + const SwTxtAttr *pHt; + sal_Unicode cChr = pNode->GetTxt().GetChar( nPos ); + if( ( CH_TXTATR_BREAKWORD == cChr || CH_TXTATR_INWORD == cChr ) && + 0 != (pHt = pNode->GetTxtAttr( nPos )) ) + switch( pHt->Which() ) + { + case RES_TXTATR_FLYCNT: + case RES_TXTATR_FTN: + case RES_TXTATR_FIELD: + case RES_TXTATR_REFMARK: + case RES_TXTATR_TOXMARK: + bRet = sal_False; + break; + } + return bRet; +} + +void lcl_SkipAttr( const SwTxtNode *pNode, SwIndex &rIdx, xub_StrLen &rStart ) +{ + if( !lcl_MayOverwrite( pNode, rStart ) ) + { + // ueberspringe alle SonderAttribute + do { + // "Beep" bei jedem ausgelassenen + Sound::Beep(SOUND_ERROR); + rIdx++; + } while( (rStart = rIdx.GetIndex()) < pNode->GetTxt().Len() + && !lcl_MayOverwrite(pNode, rStart) ); + } +} + +// ----------------------------------------------------------------- + +void _RestFlyInRange( _SaveFlyArr & rArr, const SwNodeIndex& rSttIdx ) +{ + SwPosition aPos( rSttIdx ); + for( sal_uInt16 n = 0; n < rArr.Count(); ++n ) + { + // neuen Anker anlegen + _SaveFly& rSave = rArr[n]; + SwFrmFmt* pFmt = rSave.pFrmFmt; + aPos.nNode = rSttIdx.GetIndex() + rSave.nNdDiff; + aPos.nContent.Assign( 0, 0 ); + SwFmtAnchor aAnchor( pFmt->GetAnchor() ); + aAnchor.SetAnchor( &aPos ); + pFmt->GetDoc()->GetSpzFrmFmts()->Insert( + pFmt, pFmt->GetDoc()->GetSpzFrmFmts()->Count() ); + pFmt->SetAttr( aAnchor ); + SwCntntNode* pCNd = aPos.nNode.GetNode().GetCntntNode(); + if( pCNd && pCNd->GetFrm( 0, 0, sal_False ) ) + pFmt->MakeFrms(); + } +} + +void _SaveFlyInRange( const SwNodeRange& rRg, _SaveFlyArr& rArr ) +{ + SwFrmFmt* pFmt; + const SwFmtAnchor* pAnchor; + const SwPosition* pAPos; + SwSpzFrmFmts& rFmts = *rRg.aStart.GetNode().GetDoc()->GetSpzFrmFmts(); + for( sal_uInt16 n = 0; n < rFmts.Count(); ++n ) + { + pFmt = (SwFrmFmt*)rFmts[n]; + pAnchor = &pFmt->GetAnchor(); + if( ( FLY_AT_CNTNT == pAnchor->GetAnchorId() || + FLY_AUTO_CNTNT == pAnchor->GetAnchorId() ) && + 0 != ( pAPos = pAnchor->GetCntntAnchor() ) && + rRg.aStart <= pAPos->nNode && pAPos->nNode < rRg.aEnd ) + { + ASSERT( pAnchor->GetAnchorId() != FLY_AUTO_CNTNT, "FLY-AUTO-Baustelle!" ); + _SaveFly aSave( pAPos->nNode.GetIndex() - + rRg.aStart.GetIndex(), pFmt ); + rArr.Insert( aSave, rArr.Count()); + pFmt->DelFrms(); + rFmts.Remove( n--, 1 ); + } + } +} + +void _SaveFlyInRange( const SwPaM& rPam, const SwNodeIndex& rInsPos, + _SaveFlyArr& rArr, sal_Bool bMoveAllFlys ) +{ + SwSpzFrmFmts& rFmts = *rPam.GetPoint()->nNode.GetNode().GetDoc()->GetSpzFrmFmts(); + SwFrmFmt* pFmt; + const SwFmtAnchor* pAnchor; + + const SwPosition* pPos = rPam.Start(); + const SwNodeIndex& rSttNdIdx = pPos->nNode; + short nSttOff = (!bMoveAllFlys && rSttNdIdx.GetNode().IsCntntNode() && + pPos->nContent.GetIndex()) ? 1 : 0; + + pPos = rPam.GetPoint() == pPos ? rPam.GetMark() : rPam.GetPoint(); + const SwNodeIndex& rEndNdIdx = pPos->nNode; + short nOff = ( bMoveAllFlys || ( rEndNdIdx.GetNode().IsCntntNode() && + pPos->nContent == rEndNdIdx.GetNode().GetCntntNode()->Len() )) + ? 0 : 1; + + const SwPosition* pAPos; + const SwNodeIndex* pCntntIdx; + + for( sal_uInt16 n = 0; n < rFmts.Count(); ++n ) + { + sal_Bool bInsPos = sal_False; + pFmt = (SwFrmFmt*)rFmts[n]; + pAnchor = &pFmt->GetAnchor(); + if( ( FLY_AT_CNTNT == pAnchor->GetAnchorId() || + FLY_AUTO_CNTNT == pAnchor->GetAnchorId() ) && + 0 != ( pAPos = pAnchor->GetCntntAnchor() ) && + // nicht verschieben, wenn die InsPos im CntntBereich vom Fly ist + ( 0 == ( pCntntIdx = pFmt->GetCntnt().GetCntntIdx() ) || + !( *pCntntIdx < rInsPos && + rInsPos < pCntntIdx->GetNode().EndOfSectionIndex() )) ) + { + ASSERT( pAnchor->GetAnchorId() != FLY_AUTO_CNTNT, "FLY-AUTO-Baustelle!" ); + if( !bMoveAllFlys && rEndNdIdx == pAPos->nNode ) + { + // wenn nur teil vom EndNode oder der EndNode und SttNode + // identisch sind, chaos::Anchor nicht anfassen + if( rSttNdIdx != pAPos->nNode ) + { + // Anker nur an Anfang/Ende haengen + SwPosition aPos( rSttNdIdx ); + SwFmtAnchor aAnchor( *pAnchor ); + aAnchor.SetAnchor( &aPos ); + pFmt->SetAttr( aAnchor ); +// ((SwFmtAnchor*)pAnchor)->SetAnchor( &aPos ); + } + } + else if( ( rSttNdIdx.GetIndex() + nSttOff <= pAPos->nNode.GetIndex() + && pAPos->nNode.GetIndex() <= rEndNdIdx.GetIndex() - nOff ) || + 0 != ( bInsPos = rInsPos == pAPos->nNode )) + + { + _SaveFly aSave( bInsPos ? 0 : pAPos->nNode.GetIndex() - + rSttNdIdx.GetIndex(), pFmt ); + rArr.Insert( aSave, rArr.Count()); + pFmt->DelFrms(); + rFmts.Remove( n--, 1 ); + } + } + } +} + +// ----------------------------------------------------------------- + +// loesche und verschiebe alle "Fly's am Absatz", die in der SSelection +// liegen. Steht am SPoint ein Fly, wird dieser auf den Mark verschoben. + +void DelFlyInRange( const SwNodeIndex& rMkNdIdx, + const SwNodeIndex& rPtNdIdx ) +{ + const sal_Bool bDelFwrd = rMkNdIdx.GetIndex() <= rPtNdIdx.GetIndex(); + + SwDoc* pDoc = rMkNdIdx.GetNode().GetDoc(); + SwSpzFrmFmts& rTbl = *pDoc->GetSpzFrmFmts(); + const SwPosition* pAPos; + for ( sal_uInt16 i = rTbl.Count(); i; ) + { + SwFrmFmt *pFmt = rTbl[--i]; + const SwFmtAnchor &rAnch = pFmt->GetAnchor(); + if( ( rAnch.GetAnchorId() == FLY_AT_CNTNT || + rAnch.GetAnchorId() == FLY_AUTO_CNTNT ) && + 0 != ( pAPos = rAnch.GetCntntAnchor() ) && + ( bDelFwrd + ? rMkNdIdx < pAPos->nNode && pAPos->nNode <= rPtNdIdx + : rPtNdIdx <= pAPos->nNode && pAPos->nNode < rMkNdIdx )) + { + ASSERT( rAnch.GetAnchorId() != FLY_AUTO_CNTNT, "FLY-AUTO-Baustelle!" ); + // nur den Anker verchieben ?? + if( rPtNdIdx == pAPos->nNode ) + { + SwFmtAnchor aAnch( pFmt->GetAnchor() ); + SwPosition aPos( rMkNdIdx ); + aAnch.SetAnchor( &aPos ); + pFmt->SetAttr( aAnch ); + } + else + { + // wird der Fly geloescht muss auch im seinem Inhalt alle + // Flys geloescht werden !! + const SwFmtCntnt &rCntnt = pFmt->GetCntnt(); + if( rCntnt.GetCntntIdx() ) + { + DelFlyInRange( *rCntnt.GetCntntIdx(), + SwNodeIndex( *rCntnt.GetCntntIdx()-> + GetNode().EndOfSectionNode() )); + // Position kann sich verschoben haben ! + if( i > rTbl.Count() ) + i = rTbl.Count(); + else if( pFmt != rTbl[i] ) + i = rTbl.GetPos( pFmt ); + } + + pDoc->DelLayoutFmt( pFmt ); +// i++; // keinen auslassen + } + } + } +} + + +int lcl_SaveFtn( const SwNodeIndex& rSttNd, const SwNodeIndex& rEndNd, + const SwNodeIndex& rInsPos, + SwFtnIdxs& rFtnArr, SwFtnIdxs& rSaveArr, + const SwIndex* pSttCnt = 0, const SwIndex* pEndCnt = 0 ) +{ + int bUpdateFtn = sal_False; + if( rFtnArr.Count() ) + { + const SwNodes& rNds = rInsPos.GetNodes(); + int bDelFtn = rInsPos.GetIndex() < rNds.GetEndOfAutotext().GetIndex() && + rSttNd.GetIndex() >= rNds.GetEndOfAutotext().GetIndex(); + int bSaveFtn = !bDelFtn && + rInsPos.GetIndex() >= rNds.GetEndOfExtras().GetIndex(); + + sal_uInt16 nPos; + rFtnArr.SeekEntry( rSttNd, &nPos ); + SwTxtFtn* pSrch; + const SwNode* pFtnNd; + + // loesche/sicher erstmal alle, die dahinter stehen + while( nPos < rFtnArr.Count() && ( pFtnNd = + &( pSrch = rFtnArr[ nPos ] )->GetTxtNode())->GetIndex() + <= rEndNd.GetIndex() ) + { + xub_StrLen nFtnSttIdx = *pSrch->GetStart(); + if( ( pEndCnt && pSttCnt ) + ? (( &rSttNd.GetNode() == pFtnNd && + pSttCnt->GetIndex() > nFtnSttIdx) || + ( &rEndNd.GetNode() == pFtnNd && + nFtnSttIdx >= pEndCnt->GetIndex() )) + : ( &rEndNd.GetNode() == pFtnNd )) + { + ++nPos; // weiter suchen + } + else + { + // dann weg damit + if( bDelFtn ) + { + SwTxtNode& rTxtNd = (SwTxtNode&)pSrch->GetTxtNode(); + SwIndex aIdx( &rTxtNd, nFtnSttIdx ); + rTxtNd.Erase( aIdx, 1 ); + } + else + { + pSrch->DelFrms(); + rFtnArr.Remove( nPos ); + if( bSaveFtn ) + rSaveArr.Insert( pSrch ); + } + bUpdateFtn = sal_True; + } + } + + while( nPos-- && ( pFtnNd = &( pSrch = rFtnArr[ nPos ] )-> + GetTxtNode())->GetIndex() >= rSttNd.GetIndex() ) + { + xub_StrLen nFtnSttIdx = *pSrch->GetStart(); + if( !pEndCnt || !pSttCnt || + !( (( &rSttNd.GetNode() == pFtnNd && + pSttCnt->GetIndex() > nFtnSttIdx ) || + ( &rEndNd.GetNode() == pFtnNd && + nFtnSttIdx >= pEndCnt->GetIndex() )) )) + { + if( bDelFtn ) + { + // dann weg damit + SwTxtNode& rTxtNd = (SwTxtNode&)pSrch->GetTxtNode(); + SwIndex aIdx( &rTxtNd, nFtnSttIdx ); + rTxtNd.Erase( aIdx, 1 ); + } + else + { + pSrch->DelFrms(); + rFtnArr.Remove( nPos ); + if( bSaveFtn ) + rSaveArr.Insert( pSrch ); + } + bUpdateFtn = sal_True; + } + } + } + return bUpdateFtn; +} + +void lcl_SaveRedlines( const SwNodeRange& rRg, _SaveRedlines& rArr ) +{ + SwDoc* pDoc = rRg.aStart.GetNode().GetDoc(); + sal_uInt16 nRedlPos; + SwPosition aSrchPos( rRg.aStart ); aSrchPos.nNode--; + aSrchPos.nContent.Assign( aSrchPos.nNode.GetNode().GetCntntNode(), 0 ); + if( pDoc->GetRedline( aSrchPos, &nRedlPos ) && nRedlPos ) + --nRedlPos; + else if( nRedlPos >= pDoc->GetRedlineTbl().Count() ) + return ; + + SwRedlineMode eOld = pDoc->GetRedlineMode(); + pDoc->SetRedlineMode_intern( ( eOld & ~REDLINE_IGNORE) | REDLINE_ON ); + SwRedlineTbl& rRedlTbl = (SwRedlineTbl&)pDoc->GetRedlineTbl(); + + do { + SwRedline* pTmp = rRedlTbl[ nRedlPos ]; + + const SwPosition* pRStt = pTmp->Start(), + * pREnd = pTmp->GetMark() == pRStt + ? pTmp->GetPoint() : pTmp->GetMark(); + + if( pRStt->nNode < rRg.aStart ) + { + if( pREnd->nNode > rRg.aStart && pREnd->nNode < rRg.aEnd ) + { + // Kopie erzeugen und Ende vom Original ans Ende des + // MoveBereiches setzen. Die Kopie wird mit verschoben + SwRedline* pNewRedl = new SwRedline( *pTmp ); + SwPosition* pTmpPos = pNewRedl->Start(); + pTmpPos->nNode = rRg.aStart; + pTmpPos->nContent.Assign( + pTmpPos->nNode.GetNode().GetCntntNode(), 0 ); + + _SaveRedline* pSave = new _SaveRedline( pNewRedl, rRg.aStart ); +// rArr.Insert( pSave, rArr.Count() ); + rArr.C40_INSERT( _SaveRedline, pSave, rArr.Count() ); + + pTmpPos = pTmp->End(); + pTmpPos->nNode = rRg.aEnd; + pTmpPos->nContent.Assign( + pTmpPos->nNode.GetNode().GetCntntNode(), 0 ); + } + else if( pREnd->nNode == rRg.aStart ) + { + SwPosition* pTmpPos = pTmp->End(); + pTmpPos->nNode = rRg.aEnd; + pTmpPos->nContent.Assign( + pTmpPos->nNode.GetNode().GetCntntNode(), 0 ); + } + } + else if( pRStt->nNode < rRg.aEnd ) + { + rRedlTbl.Remove( nRedlPos-- ); + if( pREnd->nNode < rRg.aEnd || + ( pREnd->nNode == rRg.aEnd && !pREnd->nContent.GetIndex()) ) + { + // gesamt verschieben + _SaveRedline* pSave = new _SaveRedline( pTmp, rRg.aStart ); +// rArr.Insert( pSave, rArr.Count() ); + rArr.C40_INSERT( _SaveRedline, pSave, rArr.Count() ); + } + else + { + // aufsplitten + SwRedline* pNewRedl = new SwRedline( *pTmp ); + SwPosition* pTmpPos = pNewRedl->End(); + pTmpPos->nNode = rRg.aEnd; + pTmpPos->nContent.Assign( + pTmpPos->nNode.GetNode().GetCntntNode(), 0 ); + + _SaveRedline* pSave = new _SaveRedline( pNewRedl, rRg.aStart ); +// rArr.Insert( pSave, rArr.Count() ); + rArr.C40_INSERT( _SaveRedline, pSave, rArr.Count() ); + + pTmpPos = pTmp->Start(); + pTmpPos->nNode = rRg.aEnd; + pTmpPos->nContent.Assign( + pTmpPos->nNode.GetNode().GetCntntNode(), 0 ); + pDoc->AppendRedline( pTmp ); + } + } + else + break; + + } while( ++nRedlPos < pDoc->GetRedlineTbl().Count() ); + pDoc->SetRedlineMode_intern( eOld ); +} + +void lcl_RestoreRedlines( SwDoc* pDoc, sal_uInt32 nInsPos, _SaveRedlines& rArr ) +{ + SwRedlineMode eOld = pDoc->GetRedlineMode(); + pDoc->SetRedlineMode_intern( ( eOld & ~REDLINE_IGNORE) | REDLINE_ON ); + + for( sal_uInt16 n = 0; n < rArr.Count(); ++n ) + { + _SaveRedline* pSave = rArr[ n ]; + pSave->SetPos( nInsPos ); + pDoc->AppendRedline( pSave->pRedl ); + } + + pDoc->SetRedlineMode_intern( eOld ); +} + +// ------------------------------------------------------------------------ + +_SaveRedlEndPosForRestore::_SaveRedlEndPosForRestore( const SwNodeIndex& rInsIdx ) + : pSavArr( 0 ), pSavIdx( 0 ) +{ + SwNode& rNd = rInsIdx.GetNode(); + SwDoc* pDest = rNd.GetDoc(); + if( pDest->GetRedlineTbl().Count() ) + { + sal_uInt16 nFndPos; + const SwPosition* pEnd; + SwPosition aSrcPos( rInsIdx, SwIndex( rNd.GetCntntNode(), 0 )); + const SwRedline* pRedl = pDest->GetRedline( aSrcPos, &nFndPos ); + while( nFndPos-- && *( pEnd = ( pRedl = + pDest->GetRedlineTbl()[ nFndPos ] )->End() ) == aSrcPos && + *pRedl->Start() != aSrcPos ) + { + if( !pSavArr ) + { + pSavArr = new SvPtrarr( 2, 2 ); + pSavIdx = new SwNodeIndex( rInsIdx, -1 ); + } + void* p = (void*)pEnd; + pSavArr->Insert( p, pSavArr->Count() ); + } + } +} + +_SaveRedlEndPosForRestore::~_SaveRedlEndPosForRestore() +{ + if( pSavArr ) + { + delete pSavArr; + delete pSavIdx; + } +} + +void _SaveRedlEndPosForRestore::_Restore() +{ + (*pSavIdx)++; + SwPosition aPos( *pSavIdx, SwIndex( pSavIdx->GetNode().GetCntntNode(), 0 )); + for( sal_uInt16 n = pSavArr->Count(); n; ) + *((SwPosition*)pSavArr->GetObject( --n )) = aPos; +} + + +// ------------------------------------------------------------------------ + +// Loeschen einer vollstaendigen Section des NodesArray. +// Der uebergebene Node steht irgendwo in der gewuenschten Section +void SwDoc::DeleteSection( SwNode *pNode ) +{ + ASSERT( pNode, "Kein Node uebergeben." ); + SwStartNode* pSttNd = pNode->IsStartNode() ? (SwStartNode*)pNode + : pNode->StartOfSectionNode(); + SwNodeIndex aSttIdx( *pSttNd ), aEndIdx( *pNode->EndOfSectionNode() ); + + // dann loesche mal alle Fly's, text::Bookmarks, ... + DelFlyInRange( aSttIdx, aEndIdx ); + DeleteRedline( *pSttNd ); + _DelBookmarks( aSttIdx, aEndIdx ); + + { + // alle Crsr/StkCrsr/UnoCrsr aus dem Loeschbereich verschieben + SwNodeIndex aMvStt( aSttIdx, 1 ); + CorrAbs( aMvStt, aEndIdx, SwPosition( aSttIdx ), sal_True ); + } + + GetNodes().DelNodes( aSttIdx, aEndIdx.GetIndex() - aSttIdx.GetIndex() + 1 ); +} + + + +/************************************************************************* +|* SwDoc::Insert(char) +|* Beschreibung Zeichen einfuegen +*************************************************************************/ + +sal_Bool SwDoc::Insert( const SwPaM &rRg, sal_Unicode c ) +{ + if( DoesUndo() ) + ClearRedo(); + + const SwPosition & rPos = *rRg.GetPoint(); + + if( pACEWord ) // Aufnahme in die Autokorrektur + { + if( pACEWord->IsDeleted() ) + pACEWord->CheckChar( rPos, c ); + delete pACEWord, pACEWord = 0; + } + SwTxtNode *pNode = rPos.nNode.GetNode().GetTxtNode(); + if(!pNode) + return sal_False; + sal_Bool bInsOneChar = sal_True; + + SwDataChanged aTmp( rRg, 0 ); + + pNode->Insert( c, rPos.nContent ); + + if ( DoesUndo() ) + { + sal_uInt16 nUndoSize = pUndos->Count(); + SwUndo * pUndo; + if( DoesGroupUndo() && bInsOneChar && nUndoSize-- && + UNDO_INSERT == ( pUndo = (*pUndos)[ nUndoSize ])->GetId() && + ((SwUndoInsert*)pUndo)->CanGrouping( rPos, c )) + ; // wenn CanGrouping() sal_True returnt, ist schon alles erledigt + else + AppendUndo( new SwUndoInsert( rPos.nNode, + rPos.nContent.GetIndex(), 1, + !WordSelection::IsNormalChar( c ) )); + } + + if( IsRedlineOn() || (!IsIgnoreRedline() && pRedlineTbl->Count() )) + { + SwPaM aPam( rPos.nNode, rPos.nContent.GetIndex() - 1, + rPos.nNode, rPos.nContent.GetIndex() ); + if( IsRedlineOn() ) + AppendRedline( new SwRedline( REDLINE_INSERT, aPam )); + else + SplitRedline( aPam ); + } + + SetModified(); + return sal_True; +} + + +/************************************************************************* +|* SwDoc::Overwrite(char) +|* Beschreibung Zeichen ueberschreiben +*************************************************************************/ + +sal_Bool SwDoc::Overwrite( const SwPaM &rRg, sal_Unicode c ) +{ + SwPosition& rPt = *(SwPosition*)rRg.GetPoint(); + if( pACEWord ) // Aufnahme in die Autokorrektur + { + pACEWord->CheckChar( rPt, c ); + delete pACEWord, pACEWord = 0; + } + + SwTxtNode *pNode = rPt.nNode.GetNode().GetTxtNode(); + if(!pNode) + return sal_False; + + sal_uInt16 nOldAttrCnt = pNode->GetpSwpHints() + ? pNode->GetpSwpHints()->Count() : 0; + SwDataChanged aTmp( rRg, 0 ); + SwIndex& rIdx = rPt.nContent; + xub_StrLen nStart = rIdx.GetIndex(); + + // hinter das Zeichen (zum aufspannen der Attribute !!) + if( nStart < pNode->GetTxt().Len() ) + lcl_SkipAttr( pNode, rIdx, nStart ); + + if( DoesUndo() ) + { + ClearRedo(); + sal_uInt16 nUndoSize = pUndos->Count(); + SwUndo * pUndo; + if( DoesGroupUndo() && nUndoSize-- && + UNDO_OVERWRITE == ( pUndo = (*pUndos)[ nUndoSize ])->GetId() && + ((SwUndoOverwrite*)pUndo)->CanGrouping( this, rPt, c )) + ;// wenn CanGrouping() sal_True returnt, ist schon alles erledigt + else + AppendUndo( new SwUndoOverwrite( this, rPt, c )); + } + else + { + // hinter das Zeichen (zum aufspannen der Attribute !!) + if( nStart < pNode->GetTxt().Len() ) + rIdx++; + pNode->Insert( c, rIdx ); + if( nStart+1 < rIdx.GetIndex() ) + { + rIdx = nStart; + pNode->Erase( rIdx, 1 ); + rIdx++; + } + } + + sal_uInt16 nNewAttrCnt = pNode->GetpSwpHints() + ? pNode->GetpSwpHints()->Count() : 0; + if( nOldAttrCnt != nNewAttrCnt ) + { + SwUpdateAttr aHint( 0, 0, 0 ); + SwClientIter aIter( *pNode ); + SwClient* pGTO = aIter.First(TYPE( SwCrsrShell )); + while( pGTO ) + { + pGTO->Modify( 0, &aHint ); + pGTO = aIter.Next(); + } + } + + if( !DoesUndo() && !IsIgnoreRedline() && GetRedlineTbl().Count() ) + { + SwPaM aPam( rPt.nNode, nStart, rPt.nNode, rPt.nContent.GetIndex() ); + DeleteRedline( aPam ); + } + else if( IsRedlineOn() ) + { + SwPaM aPam( rPt.nNode, nStart, rPt.nNode, rPt.nContent.GetIndex() ); + AppendRedline( new SwRedline( REDLINE_INSERT, aPam )); + } + + SetModified(); + return sal_True; +} + +sal_Bool SwDoc::Overwrite( const SwPaM &rRg, const String &rStr ) +{ + SwPosition& rPt = *(SwPosition*)rRg.GetPoint(); + if( pACEWord ) // Aufnahme in die Autokorrektur + { + if( 1 == rStr.Len() ) + pACEWord->CheckChar( rPt, rStr.GetChar( 0 ) ); + delete pACEWord, pACEWord = 0; + } + + SwTxtNode *pNode = rPt.nNode.GetNode().GetTxtNode(); + if(!pNode) + return sal_False; + + if( DoesUndo() ) + ClearRedo(); + + sal_uInt16 nOldAttrCnt = pNode->GetpSwpHints() + ? pNode->GetpSwpHints()->Count() : 0; + SwDataChanged aTmp( rRg, 0 ); + SwIndex& rIdx = rPt.nContent; + xub_StrLen nStart; + + sal_uInt16 nUndoSize = pUndos->Count(); + SwUndo * pUndo; + sal_Unicode c; + String aStr; + + for( xub_StrLen nCnt = 0; nCnt < rStr.Len(); ++nCnt ) + { + // hinter das Zeichen (zum aufspannen der Attribute !!) + if( (nStart = rIdx.GetIndex()) < pNode->GetTxt().Len() ) + lcl_SkipAttr( pNode, rIdx, nStart ); + c = rStr.GetChar( nCnt ); + if( DoesUndo() ) + { + if( DoesGroupUndo() && nUndoSize && + UNDO_OVERWRITE == ( pUndo = (*pUndos)[ nUndoSize-1 ])->GetId() && + ((SwUndoOverwrite*)pUndo)->CanGrouping( this, rPt, c )) + ;// wenn CanGrouping() sal_True returnt, ist schon alles erledigt + else + { + AppendUndo( new SwUndoOverwrite( this, rPt, c )); + nUndoSize = pUndos->Count(); + } + } + else + { + // hinter das Zeichen (zum Aufspannen der Attribute !!) + if( nStart < pNode->GetTxt().Len() ) + rIdx++; + pNode->Insert( c, rIdx ); + if( nStart+1 < rIdx.GetIndex() ) + { + rIdx = nStart; + pNode->Erase( rIdx, 1 ); + rIdx++; + } + } + } + + sal_uInt16 nNewAttrCnt = pNode->GetpSwpHints() + ? pNode->GetpSwpHints()->Count() : 0; + if( nOldAttrCnt != nNewAttrCnt ) + { + SwUpdateAttr aHint( 0, 0, 0 ); + SwClientIter aIter( *pNode ); + SwClient* pGTO = aIter.First(TYPE( SwCrsrShell )); + while( pGTO ) + { + pGTO->Modify( 0, &aHint ); + pGTO = aIter.Next(); + } + } + + if( !DoesUndo() && !IsIgnoreRedline() && GetRedlineTbl().Count() ) + { + SwPaM aPam( rPt.nNode, nStart, rPt.nNode, rPt.nContent.GetIndex() ); + DeleteRedline( aPam ); + } + else if( IsRedlineOn() ) + { + SwPaM aPam( rPt.nNode, nStart, rPt.nNode, rPt.nContent.GetIndex() ); + AppendRedline( new SwRedline( REDLINE_INSERT, aPam )); + } + + SetModified(); + return sal_True; +} + + +sal_Bool SwDoc::MoveAndJoin( SwPaM& rPaM, SwPosition& rPos, SwMoveFlags eMvFlags ) +{ + SwNodeIndex aIdx( rPaM.Start()->nNode ); + sal_Bool bJoinTxt = aIdx.GetNode().IsTxtNode(); + sal_Bool bOneNode = rPaM.GetPoint()->nNode == rPaM.GetMark()->nNode; + aIdx--; // vor den Move Bereich !! + + sal_Bool bRet = Move( rPaM, rPos, eMvFlags ); + if( bRet && !bOneNode ) + { + if( bJoinTxt ) + aIdx++; + SwTxtNode * pTxtNd = aIdx.GetNode().GetTxtNode(); + SwNodeIndex aNxtIdx( aIdx ); + if( pTxtNd && pTxtNd->CanJoinNext( &aNxtIdx ) ) + { + { // Block wegen SwIndex in den Node !! + CorrRel( aNxtIdx, SwPosition( aIdx, SwIndex( pTxtNd, + pTxtNd->GetTxt().Len() ) ), 0, sal_True ); + } + pTxtNd->JoinNext(); + } + } + return bRet; +} + +sal_Bool SwDoc::Move( SwPaM& rPaM, SwPosition& rPos, SwMoveFlags eMvFlags ) +{ + // keine Moves-Abfangen + const SwPosition *pStt = rPaM.Start(), *pEnd = rPaM.End(); + if( !rPaM.HasMark() || *pStt >= *pEnd || (*pStt <= rPos && rPos < *pEnd)) + return sal_False; + + // sicher die absatzgebundenen Flys, damit sie verschoben werden koennen. + _SaveFlyArr aSaveFlyArr; + _SaveFlyInRange( rPaM, rPos.nNode, aSaveFlyArr, DOC_MOVEALLFLYS & eMvFlags ); + + int bUpdateFtn = sal_False; + SwFtnIdxs aTmpFntIdx; + + // falls Undo eingeschaltet, erzeuge das UndoMove-Objekt + SwUndoMove * pUndoMove = 0; + if( DoesUndo() ) + { + ClearRedo(); + pUndoMove = new SwUndoMove( rPaM, rPos ); + } + else + { + bUpdateFtn = lcl_SaveFtn( pStt->nNode, pEnd->nNode, rPos.nNode, + GetFtnIdxs(), aTmpFntIdx, + &pStt->nContent, &pEnd->nContent ); + } + + sal_Bool bSplit = sal_False; + SwPaM * pSavePam = new SwPaM( rPos, rPos ); + + // stelle den SPoint an den Anfang vom Bereich (Definition) + if( rPaM.GetPoint() == pEnd ) + rPaM.Exchange(); + + // in der EditShell wird nach dem Move ein JoinNext erzeugt, wenn + // vor und nach dem Move ein Text-Node steht. + SwTxtNode* pSrcNd = rPaM.GetPoint()->nNode.GetNode().GetTxtNode(); + sal_Bool bCorrSavePam = pSrcNd && pStt->nNode != pEnd->nNode; + + // werden ein oder mehr TextNodes bewegt, so wird + // im SwNodes::Move ein SplitNode erzeugt. Dieser Updated aber nicht + // den Cursor. Um das zu verhindern, wird hier ein TextNode angelegt, + // um die Updaterei der Indizies zu erhalten. Nach dem Move wird + // evt. der Node geloescht. + + SwTxtNode * pTNd = rPos.nNode.GetNode().GetTxtNode(); + if( pTNd && rPaM.GetPoint()->nNode != rPaM.GetMark()->nNode && + ( rPos.nContent.GetIndex() || ( pTNd->Len() && bCorrSavePam )) ) + { + bSplit = sal_True; + xub_StrLen nMkCntnt = rPaM.GetMark()->nContent.GetIndex(); + + SvULongs aBkmkArr( 15, 15 ); + _SaveCntntIdx( this, rPos.nNode.GetIndex(), rPos.nContent.GetIndex(), + aBkmkArr, SAVEFLY_SPLIT ); + + pTNd = (SwTxtNode*)pTNd->SplitNode( rPos ); + + if( aBkmkArr.Count() ) + _RestoreCntntIdx( this, aBkmkArr, rPos.nNode.GetIndex()-1, 0, sal_True ); + + // jetzt noch den Pam berichtigen !! + if( rPos.nNode == rPaM.GetMark()->nNode ) + { + rPaM.GetMark()->nNode = rPos.nNode.GetIndex()-1; + rPaM.GetMark()->nContent.Assign( pTNd, nMkCntnt ); + } + } + + // setze den Pam um einen "Inhalt" zurueck; dadurch steht er immer + // ausserhalb des manipulierten Bereiches. Falls kein Inhalt mehr vor- + // handen, dann auf den StartNode (es ist immer einer vorhanden !!!) + sal_Bool bNullCntnt = !pSavePam->Move( fnMoveBackward, fnGoCntnt ); + if( bNullCntnt ) + pSavePam->GetPoint()->nNode--; + + // kopiere alle Bookmarks, die im Move Bereich stehen in ein + // Array, das alle Angaben auf die Position als Offset speichert. + // Die neue Zuordung erfolgt nach dem Moven. + SaveBookmarks aSaveBkmk; + _DelBookmarks( pStt->nNode, pEnd->nNode, &aSaveBkmk, + &pStt->nContent, &pEnd->nContent ); + + // falls durch die vorherigen Loeschungen (z.B. der Fussnoten) kein + // Bereich mehr existiert, ist das immernoch ein gueltiger Move! + if( *rPaM.GetPoint() != *rPaM.GetMark() ) + { + // jetzt kommt das eigentliche Verschieben + GetNodes().Move( rPaM, rPos, GetNodes() ); + + if( rPaM.HasMark() ) // es wurde kein Move ausgefuehrt !! + { + delete pSavePam; + delete pUndoMove; + return sal_False; // Nach einem Move() ist der GetMark geloescht + } + } + else + rPaM.DeleteMark(); + + ASSERT( *pSavePam->GetMark() == rPos, + "PaM wurde nicht verschoben, am Anfang/Ende keine ContentNodes?" ); + *pSavePam->GetMark() = rPos; + + rPaM.SetMark(); // um den neuen Bereich eine Sel. aufspannen + pTNd = pSavePam->GetNode()->GetTxtNode(); + if( DoesUndo() ) + { + // korrigiere erstmal den Content vom SavePam + if( bNullCntnt ) + pSavePam->GetPoint()->nContent = 0; + + // die Methode SwEditShell::Move() fuegt nach dem Move den Text-Node + // zusammen, in dem der rPaM steht. Wurde der Inhalt nach hinten + // geschoben und liegt der SPoint vom SavePam im naechsten Node, so + // muss beim Speichern vom Undo-Object das beachtet werden !! + SwTxtNode * pPamTxtNd; + + // wird ans SwUndoMove weitergegeben, das dann beim Undo JoinNext + // aufruft. (falls es hier nicht moeglich ist). + sal_Bool bJoin = bSplit && pTNd; + bCorrSavePam = bCorrSavePam && + 0 != ( pPamTxtNd = rPaM.GetNode()->GetTxtNode() ) + && pPamTxtNd->CanJoinNext() + && *rPaM.GetPoint() <= *pSavePam->GetPoint(); + + // muessen am SavePam 2 Nodes zusammengefasst werden ?? + if( bJoin && pTNd->CanJoinNext() ) + { + pTNd->JoinNext(); + // kein temp. sdbcx::Index bei && + // es sollten wohl nur die Indexwerte verglichen werden. + if( bCorrSavePam && rPaM.GetPoint()->nNode.GetIndex()+1 == + pSavePam->GetPoint()->nNode.GetIndex() ) + pSavePam->GetPoint()->nContent += pPamTxtNd->Len(); + bJoin = sal_False; + } +// else if( !bCorrSavePam && !pSavePam->Move( fnMoveForward, fnGoCntnt )) + else if( !pSavePam->Move( fnMoveForward, fnGoCntnt )) + pSavePam->GetPoint()->nNode++; + + // zwischen SPoint und GetMark steht jetzt der neu eingefuegte Bereich + pUndoMove->SetDestRange( *pSavePam, *rPaM.GetPoint(), + bJoin, bCorrSavePam ); + AppendUndo( pUndoMove ); + } + else + { + // muessen am SavePam 2 Nodes zusammengefasst werden ?? + if( bSplit && pTNd ) + { + if( pTNd->CanJoinNext()) + pTNd->JoinNext(); + } + if( bNullCntnt ) + { + pSavePam->GetPoint()->nNode++; + pSavePam->GetPoint()->nContent.Assign( pSavePam->GetCntntNode(), 0 ); + } + else + pSavePam->Move( fnMoveForward, fnGoCntnt ); + } + + // setze jetzt wieder die text::Bookmarks in das Dokument + *rPaM.GetMark() = *pSavePam->Start(); + for( sal_uInt16 n = 0; n < aSaveBkmk.Count(); ++n ) + aSaveBkmk[n]->SetInDoc( this, rPaM.GetMark()->nNode, + &rPaM.GetMark()->nContent ); + *rPaM.GetPoint() = *pSavePam->End(); + delete pSavePam; + + // verschiebe die Flys an die neue Position + _RestFlyInRange( aSaveFlyArr, rPaM.Start()->nNode ); + + if( bUpdateFtn ) + { + if( aTmpFntIdx.Count() ) + { + GetFtnIdxs().Insert( &aTmpFntIdx ); + aTmpFntIdx.Remove( sal_uInt16( 0 ), aTmpFntIdx.Count() ); + } + + GetFtnIdxs().UpdateAllFtn(); + } + + SetModified(); + return sal_True; +} + +sal_Bool SwDoc::Move( SwNodeRange& rRange, SwNodeIndex& rPos, SwMoveFlags eMvFlags ) +{ + // bewegt alle Nodes an die neue Position. Dabei werden die + // text::Bookmarks mit verschoben !! (zur Zeit ohne Undo) + + // falls durchs Move Fussnoten in den Sonderbereich kommen sollten, + // dann entferne sie jetzt. + //JP 13.07.95: + // ansonsten bei allen Fussnoten, die verschoben werden, die Frames + // loeschen und nach dem Move wieder aufbauen lassen (Fussnoten koennen + // die Seite wechseln). Zusaetzlich muss natuerlich die Sortierung + // der FtnIdx-Array wieder korrigiert werden. + + int bUpdateFtn = sal_False; + SwFtnIdxs aTmpFntIdx; + + SwUndoMove* pUndo = 0; + if( (DOC_CREATEUNDOOBJ & eMvFlags ) && DoesUndo() ) + pUndo = new SwUndoMove( this, rRange, rPos ); + else + bUpdateFtn = lcl_SaveFtn( rRange.aStart, rRange.aEnd, rPos, + GetFtnIdxs(), aTmpFntIdx ); + + _SaveRedlines aSaveRedl( 0, 4 ); + SvPtrarr aSavRedlInsPosArr( 0, 4 ); + if( DOC_MOVEREDLINES & eMvFlags && GetRedlineTbl().Count() ) + { + lcl_SaveRedlines( rRange, aSaveRedl ); + + // suche alle Redlines, die an der InsPos aufhoeren. Diese muessen + // nach dem Move wieder an die "alte" Position verschoben werden + sal_uInt16 nRedlPos = GetRedlinePos( rPos.GetNode() ); + if( USHRT_MAX != nRedlPos ) + { + const SwPosition *pRStt, *pREnd; + do { + SwRedline* pTmp = GetRedlineTbl()[ nRedlPos ]; + pRStt = pTmp->Start(); + pREnd = pTmp->End(); + if( pREnd->nNode == rPos && pRStt->nNode < rPos ) + { + void* p = pTmp; + aSavRedlInsPosArr.Insert( p, aSavRedlInsPosArr.Count() ); + } + } while( pRStt->nNode < rPos && ++nRedlPos < GetRedlineTbl().Count()); + } + } + + // kopiere alle Bookmarks, die im Move Bereich stehen in ein + // Array, das alle Angaben auf die Position als Offset speichert. + // Die neue Zuordung erfolgt nach dem Moven. + SaveBookmarks aSaveBkmk; + _DelBookmarks( rRange.aStart, rRange.aEnd, &aSaveBkmk ); + + // sicher die absatzgebundenen Flys, damit verschoben werden koennen. + _SaveFlyArr aSaveFlyArr; + if( GetSpzFrmFmts()->Count() ) + _SaveFlyInRange( rRange, aSaveFlyArr ); + + // vor die Position setzen, damit er nicht weitergeschoben wird + SwNodeIndex aIdx( rPos, -1 ); + + SwNodeIndex* pSaveInsPos = 0; + if( pUndo ) + pSaveInsPos = new SwNodeIndex( rRange.aStart, -1 ); + + // verschiebe die Nodes + if( GetNodes()._MoveNodes( rRange, GetNodes(), rPos ) ) + { + aIdx++; // wieder auf alte Position + if( pSaveInsPos ) + (*pSaveInsPos)++; + } + else + { + aIdx = rRange.aStart; + delete pUndo, pUndo = 0; + } + + // verschiebe die Flys an die neue Position + if( aSaveFlyArr.Count() ) + _RestFlyInRange( aSaveFlyArr, aIdx ); + + // setze jetzt wieder die text::Bookmarks in das Dokument + for( sal_uInt16 nCnt = 0; nCnt < aSaveBkmk.Count(); ++nCnt ) + aSaveBkmk[nCnt]->SetInDoc( this, aIdx ); + + if( aSavRedlInsPosArr.Count() ) + { + SwNode* pNewNd = &aIdx.GetNode(); + for( sal_uInt16 n = 0; n < aSavRedlInsPosArr.Count(); ++n ) + { + SwRedline* pTmp = (SwRedline*)aSavRedlInsPosArr[ n ]; + if( USHRT_MAX != GetRedlineTbl().GetPos( pTmp ) ) + { + SwPosition* pEnd = pTmp->End(); + pEnd->nNode = aIdx; + pEnd->nContent.Assign( pNewNd->GetCntntNode(), 0 ); + } + } + } + + if( aSaveRedl.Count() ) + lcl_RestoreRedlines( this, aIdx.GetIndex(), aSaveRedl ); + + if( pUndo ) + { + ClearRedo(); + pUndo->SetDestRange( aIdx, rPos, *pSaveInsPos ); + AppendUndo( pUndo ); + } + + if( pSaveInsPos ) + delete pSaveInsPos; + + if( bUpdateFtn ) + { + if( aTmpFntIdx.Count() ) + { + GetFtnIdxs().Insert( &aTmpFntIdx ); + aTmpFntIdx.Remove( sal_uInt16( 0 ), aTmpFntIdx.Count() ); + } + + GetFtnIdxs().UpdateAllFtn(); + } + + SetModified(); + return sal_True; +} + +void lcl_GetJoinFlags( SwPaM& rPam, sal_Bool& rJoinTxt, sal_Bool& rJoinPrev ) +{ + if( rPam.GetPoint()->nNode != rPam.GetMark()->nNode ) + { + const SwPosition* pStt = rPam.Start(), *pEnd = rPam.End(); + SwTxtNode* pTxtNd = pStt->nNode.GetNode().GetTxtNode(); + rJoinTxt = 0 != pTxtNd; + + if( rJoinTxt && pStt == rPam.GetPoint() && + 0 != ( pTxtNd = pEnd->nNode.GetNode().GetTxtNode() ) && + pTxtNd->GetTxt().Len() == pEnd->nContent.GetIndex() ) + { + rPam.Exchange(); + rJoinPrev = sal_False; + } + else + rJoinPrev = rJoinTxt && rPam.GetPoint() == pStt; + } + else + rJoinTxt = sal_False, rJoinPrev = sal_False; +} + +void lcl_JoinText( SwPaM& rPam, sal_Bool bJoinPrev ) +{ + SwNodeIndex aIdx( rPam.GetPoint()->nNode ); + SwTxtNode *pTxtNd = aIdx.GetNode().GetTxtNode(); + SwNodeIndex aOldIdx( aIdx ); + SwTxtNode *pOldTxtNd = pTxtNd; + + if( pTxtNd && pTxtNd->CanJoinNext( &aIdx ) ) + { + SwDoc* pDoc = rPam.GetDoc(); + if( bJoinPrev ) + { + { + // falls PageBreaks geloescht / gesetzt werden, darf das + // nicht in die Undo-History aufgenommen werden !! + // (das loeschen vom Node geht auch am Undo vorbei !!!) + sal_Bool bDoUndo = pDoc->DoesUndo(); + pDoc->DoUndo( sal_False ); + + /* PageBreaks, PageDesc, ColumnBreaks */ + // Sollte an der Logik zum Kopieren der PageBreak's ... + // etwas geaendert werden, muss es auch im SwUndoDelete + // geandert werden. Dort wird sich das AUTO-PageBreak + // aus dem GetMarkNode kopiert.!!! + + /* Der GetMarkNode */ + if( ( pTxtNd = aIdx.GetNode().GetTxtNode())->GetpSwAttrSet() ) + { + const SfxPoolItem* pItem; + if( SFX_ITEM_SET == pTxtNd->GetpSwAttrSet()->GetItemState( + RES_BREAK, sal_False, &pItem ) ) + pTxtNd->ResetAttr( RES_BREAK ); + if( pTxtNd->GetpSwAttrSet() && + SFX_ITEM_SET == pTxtNd->GetpSwAttrSet()->GetItemState( + RES_PAGEDESC, sal_False, &pItem ) ) + pTxtNd->ResetAttr( RES_PAGEDESC ); + } + + /* Der PointNode */ + if( pOldTxtNd->GetpSwAttrSet() ) + { + const SfxPoolItem* pItem; + SfxItemSet aSet( pDoc->GetAttrPool(), aBreakSetRange ); + SfxItemSet* pSet = pOldTxtNd->GetpSwAttrSet(); + if( SFX_ITEM_SET == pSet->GetItemState( RES_BREAK, + sal_False, &pItem ) ) + aSet.Put( *pItem ); + if( SFX_ITEM_SET == pSet->GetItemState( RES_PAGEDESC, + sal_False, &pItem ) ) + aSet.Put( *pItem ); + if( aSet.Count() ) + pTxtNd->SwCntntNode::SetAttr( aSet ); + } + pOldTxtNd->FmtToTxtAttr( pTxtNd ); + + SvULongs aBkmkArr( 15, 15 ); + ::_SaveCntntIdx( pDoc, aOldIdx.GetIndex(), + pOldTxtNd->Len(), aBkmkArr ); + + SwIndex aAlphaIdx(pTxtNd); + pOldTxtNd->Cut( pTxtNd, aAlphaIdx, SwIndex(pOldTxtNd), + pOldTxtNd->Len() ); + SwPosition aAlphaPos( aIdx, aAlphaIdx ); + pDoc->CorrRel( rPam.GetPoint()->nNode, aAlphaPos, 0, sal_True ); + + // verschiebe noch alle Bookmarks/TOXMarks + if( aBkmkArr.Count() ) + ::_RestoreCntntIdx( pDoc, aBkmkArr, aIdx.GetIndex() ); + + pDoc->DoUndo( bDoUndo ); + + // falls der uebergebene PaM nicht im Crsr-Ring steht, + // gesondert behandeln (z.B. Aufruf aus dem Auto-Format) + if( pOldTxtNd == rPam.GetBound( sal_True ).nContent.GetIdxReg() ) + rPam.GetBound( sal_True ) = aAlphaPos; + if( pOldTxtNd == rPam.GetBound( sal_False ).nContent.GetIdxReg() ) + rPam.GetBound( sal_False ) = aAlphaPos; + } + // jetzt nur noch den Node loeschen + pDoc->GetNodes().Delete( aOldIdx, 1 ); + } + else + { + SwTxtNode* pDelNd = aIdx.GetNode().GetTxtNode(); + if( pTxtNd->Len() ) + pDelNd->FmtToTxtAttr( pTxtNd ); + else if( pDelNd->GetpSwAttrSet() ) + { + // nur die Zeichenattribute kopieren + SfxItemSet aTmpSet( pDoc->GetAttrPool(), aCharFmtSetRange ); + aTmpSet.Put( *pDelNd->GetpSwAttrSet() ); + pTxtNd->SwCntntNode::SetAttr( aTmpSet ); + } + + pDoc->CorrRel( aIdx, *rPam.GetPoint(), 0, sal_True ); + pTxtNd->JoinNext(); + } + } +} + +sal_Bool SwDoc::DeleteAndJoin( SwPaM & rPam ) +{ + if( IsRedlineOn() ) + { + sal_uInt16 nUndoSize = 0; + SwUndoRedlineDelete* pUndo = 0; + SwRedlineMode eOld = GetRedlineMode(); + if( DoesUndo() ) + { + ClearRedo(); + +//JP 06.01.98: MUSS noch optimiert werden!!! +SetRedlineMode( REDLINE_ON | REDLINE_SHOW_INSERT | REDLINE_SHOW_DELETE ); + + nUndoSize = pUndos->Count(); + StartUndo(); + AppendUndo( pUndo = new SwUndoRedlineDelete( rPam, UNDO_DELETE )); + } + AppendRedline( new SwRedline( REDLINE_DELETE, rPam )); + SetModified(); + + if( pUndo ) + { + EndUndo(); + SwUndo* pPrevUndo; + if( nUndoSize && DoesGroupUndo() && + nUndoSize + 1 == pUndos->Count() && + UNDO_REDLINE == ( pPrevUndo = (*pUndos)[ nUndoSize-1 ])->GetId() && + UNDO_DELETE == ((SwUndoRedline*)pPrevUndo)->GetUserId() && + ((SwUndoRedlineDelete*)pPrevUndo)->CanGrouping( *pUndo )) + { + DoUndo( sal_False ); + pUndos->DeleteAndDestroy( nUndoSize, 1 ); + --nUndoPos, --nUndoCnt; + DoUndo( sal_True ); + } +//JP 06.01.98: MUSS noch optimiert werden!!! +SetRedlineMode( eOld ); + } + return sal_True; + } + + sal_Bool bJoinTxt, bJoinPrev; + lcl_GetJoinFlags( rPam, bJoinTxt, bJoinPrev ); + + { + // dann eine Kopie vom Cursor erzeugen um alle Pams aus den + // anderen Sichten aus dem Loeschbereich zu verschieben + // ABER NICHT SICH SELBST !! + SwPaM aDelPam( *rPam.GetMark(), *rPam.GetPoint() ); + ::PaMCorrAbs( aDelPam, *aDelPam.GetPoint() ); + + if( !Delete( aDelPam ) ) + return sal_False; + + *rPam.GetPoint() = *aDelPam.GetPoint(); + } + + if( bJoinTxt ) + lcl_JoinText( rPam, bJoinPrev ); + + return sal_True; +} + +sal_Bool SwDoc::Delete( SwPaM & rPam ) +{ + SwPosition *pStt = (SwPosition*)rPam.Start(), *pEnd = (SwPosition*)rPam.End(); + + if( !rPam.HasMark() || *pStt >= *pEnd ) + return sal_False; + + if( pACEWord ) + { + // ggfs. das gesicherte Word fuer die Ausnahme + if( pACEWord->IsDeleted() || pStt->nNode != pEnd->nNode || + pStt->nContent.GetIndex() + 1 != pEnd->nContent.GetIndex() || + !pACEWord->CheckDelChar( *pStt )) + delete pACEWord, pACEWord = 0; + } + + { + // loesche alle leeren TextHints an der Mark-Position + SwTxtNode* pTxtNd = rPam.GetMark()->nNode.GetNode().GetTxtNode(); + SwpHints* pHts; + if( pTxtNd && 0 != ( pHts = pTxtNd->GetpSwpHints()) && pHts->Count() ) + { + const xub_StrLen *pEndIdx; + xub_StrLen nMkCntPos = rPam.GetMark()->nContent.GetIndex(); + for( sal_uInt16 n = pHts->Count(); n; ) + { + const SwTxtAttr* pAttr = (*pHts)[ --n ]; + if( nMkCntPos > *pAttr->GetStart() ) + break; + + if( nMkCntPos == *pAttr->GetStart() && + 0 != (pEndIdx = pAttr->GetEnd()) && + *pEndIdx == *pAttr->GetStart() ) + pTxtNd->DestroyAttr( pHts->Cut( n ) ); + } + } + } + + { + // Bug 26675: DataChanged vorm loeschen verschicken, dann bekommt + // man noch mit, welche Objecte sich im Bereich befinden. + // Danach koennen sie vor/hinter der Position befinden. + SwDataChanged aTmp( rPam, 0 ); + } + + + if( DoesUndo() ) + { + ClearRedo(); + sal_uInt16 nUndoSize = pUndos->Count(); + SwUndo * pUndo; + if( DoesGroupUndo() && nUndoSize-- && + UNDO_DELETE == ( pUndo = (*pUndos)[ nUndoSize ])->GetId() && + ((SwUndoDelete*)pUndo)->CanGrouping( this, rPam )) + ;// wenn CanGrouping() sal_True returnt, ist schon alles erledigt + else + AppendUndo( new SwUndoDelete( rPam ) ); + + SetModified(); + return sal_True; + } + + if( !IsIgnoreRedline() && GetRedlineTbl().Count() ) + DeleteRedline( rPam ); + + // loesche und verschiebe erstmal alle "Fly's am Absatz", die in der + // SSelection liegen + DelFlyInRange( rPam.GetMark()->nNode, rPam.GetPoint()->nNode ); + _DelBookmarks( pStt->nNode, pEnd->nNode, 0, + &pStt->nContent, &pEnd->nContent ); + + SwNodeIndex aSttIdx( pStt->nNode ); + SwCntntNode * pCNd = aSttIdx.GetNode().GetCntntNode(); + + do { // middle checked loop! + if( pCNd ) + { + if( pCNd->GetTxtNode() ) + { + // verschiebe jetzt noch den Inhalt in den neuen Node + sal_Bool bOneNd = pStt->nNode == pEnd->nNode; + xub_StrLen nLen = ( bOneNd ? pEnd->nContent.GetIndex() + : pCNd->Len() ) + - pStt->nContent.GetIndex(); + + // falls schon leer, dann nicht noch aufrufen + if( nLen ) + ((SwTxtNode*)pCNd)->Erase( pStt->nContent, nLen ); + + if( bOneNd ) // das wars schon + break; + + aSttIdx++; + } + else + { + // damit beim loeschen keine Indizies mehr angemeldet sind, + // wird hier der SwPaM aus dem Content entfernt !! + pStt->nContent.Assign( 0, 0 ); + } + } + + sal_uInt32 nEnde = pEnd->nNode.GetIndex(); + pCNd = pEnd->nNode.GetNode().GetCntntNode(); + if( pCNd ) + { + if( pCNd->GetTxtNode() ) + { + // falls schon leer, dann nicht noch aufrufen + if( pEnd->nContent.GetIndex() ) + { + SwIndex aIdx( pCNd, 0 ); + ((SwTxtNode*)pCNd)->Erase( aIdx, pEnd->nContent.GetIndex() ); + } + nEnde--; + } + else + { + // damit beim Loeschen keine Indizies mehr angemeldet sind, + // wird hier der SwPaM aus dem Content entfernt !! + pEnd->nContent.Assign( 0, 0 ); + nEnde--; + } + } + + nEnde++; + if( aSttIdx != nEnde ) + { + // loesche jetzt die Nodes in das NodesArary + GetNodes().Delete( aSttIdx, nEnde - aSttIdx.GetIndex() ); + } + + // falls der Node geloescht wurde, in dem der Cursor stand, so + // muss der Content im akt. Content angemeldet werden !!! + pStt->nContent.Assign( pStt->nNode.GetNode().GetCntntNode(), + pStt->nContent.GetIndex() ); + + // der PaM wird korrigiert, denn falls ueber Nodegrenzen geloescht + // wurde, so stehen sie in unterschieden Nodes. Auch die Selektion + // wird aufgehoben ! + *pEnd = *pStt; + rPam.DeleteMark(); + + } while( sal_False ); + + if( !IsIgnoreRedline() && GetRedlineTbl().Count() ) + CompressRedlines(); + SetModified(); + return sal_True; +} + + +uno::Reference< uno::XInterface > SwDoc::Spell( SwPaM& rPaM, + uno::Reference< linguistic::XSpellChecker1 > &xSpeller, + sal_uInt16* pPageCnt, sal_uInt16* pPageSt ) const +{ + SwPosition* pSttPos = rPaM.Start(), *pEndPos = rPaM.End(); + uno::Reference< beans::XPropertySet > xProp( ::GetLinguPropertySet() ); + sal_Bool bReverse = xProp.is() ? + *(sal_Bool*)xProp->getPropertyValue( S2U(UPN_IS_WRAP_REVERSE) ).getValue() : sal_False; + + SwSpellArgs aSpellArg( xSpeller, + pSttPos->nNode.GetNode().GetTxtNode(), pSttPos->nContent, + pEndPos->nNode.GetNode().GetTxtNode(), pEndPos->nContent ); + + sal_uInt32 nCurrNd = pSttPos->nNode.GetIndex(); + sal_uInt32 nEndNd = pEndPos->nNode.GetIndex(); + + if( nCurrNd <= nEndNd ) + { + SwCntntFrm* pCntFrm; + sal_uInt32 nCount = nEndNd - nCurrNd; + if( bReverse ) + { + nCurrNd = nEndNd; + nEndNd = nCurrNd - nCount; + } + sal_Bool bGoOn = sal_True; + while( bGoOn ) + { + SwNode* pNd = GetNodes()[ nCurrNd ]; + switch( pNd->GetNodeType() ) + { + case ND_TEXTNODE: + if( 0 != ( pCntFrm = ((SwTxtNode*)pNd)->GetFrm()) ) + { + // geschutze Cellen/Flys ueberspringen, ausgeblendete + //ebenfalls + if( pCntFrm->IsProtected() ) + { + nCurrNd = bReverse ? pNd->StartOfSectionIndex() + : pNd->EndOfSectionIndex(); + } + else if( !((SwTxtFrm*)pCntFrm)->IsHiddenNow() ) + { + if( pPageCnt && *pPageCnt && pPageSt ) + { + sal_uInt16 nPageNr = pCntFrm->GetPhyPageNum(); + if( !*pPageSt ) + { + *pPageSt = nPageNr; + if( *pPageCnt < *pPageSt ) + *pPageCnt = *pPageSt; + } + long nStat; + if( nPageNr >= *pPageSt ) + nStat = bReverse ? + *pPageCnt - nPageNr + *pPageSt + 1 : + nPageNr - *pPageSt + 1; + else + nStat = bReverse ? + *pPageSt - nPageNr + 1 : + nPageNr + *pPageCnt - *pPageSt + 1; + ::SetProgressState( nStat, (SwDocShell*)GetDocShell() ); + } + if( ((SwTxtNode*)pNd)->Spell( &aSpellArg ) ) + { + // Abbrechen und Position merken + pSttPos->nNode = nCurrNd; + pEndPos->nNode = nCurrNd; + nCurrNd = nEndNd; + } + } + } + break; + case ND_SECTIONNODE: + if( !bReverse && + ( ((SwSectionNode*)pNd)->GetSection().IsProtect() || + ((SwSectionNode*)pNd)->GetSection().IsHidden() ) ) + nCurrNd = pNd->EndOfSectionIndex(); + break; + case ND_ENDNODE: + { + SwNode* pTmp; + if( bReverse && 0 != (pTmp = pNd->StartOfSectionNode() ) && + ND_SECTIONNODE == pTmp->GetNodeType() && + ( ((SwSectionNode*)pTmp)->GetSection().IsProtect() || + ((SwSectionNode*)pTmp)->GetSection().IsHidden() ) ) + nCurrNd = pNd->StartOfSectionIndex(); + break; + } + } + + if( bReverse ) + { + bGoOn = nCurrNd > nEndNd; + if( bGoOn ) + --nCurrNd; + } + else + { + bGoOn = nCurrNd < nEndNd; + ++nCurrNd; + } + } + } + return aSpellArg.xSpellAlt; +} + +class SwHyphArgs : public SwInterHyphInfo +{ + const SwNode *pStart; + const SwNode *pEnd; + SwNode *pNode; + sal_uInt16 *pPageCnt; + sal_uInt16 *pPageSt; + + sal_uInt32 nNode; + xub_StrLen nPamStart; + xub_StrLen nPamLen; + +public: + SwHyphArgs( const SwPaM *pPam, const Point &rPoint, + sal_uInt16* pPageCount, sal_uInt16* pPageStart ); + void SetPam( SwPaM *pPam ) const; + inline void SetNode( SwNode *pNew ) { pNode = pNew; } + inline const SwNode *GetNode() const { return pNode; } + inline void SetRange( const SwNode *pNew ); + inline void NextNode() { ++nNode; } + inline sal_uInt16 *GetPageCnt() { return pPageCnt; } + inline sal_uInt16 *GetPageSt() { return pPageSt; } +}; + +SwHyphArgs::SwHyphArgs( const SwPaM *pPam, const Point &rCrsrPos, + sal_uInt16* pPageCount, sal_uInt16* pPageStart ) + : SwInterHyphInfo( rCrsrPos ), pNode(0), + pPageCnt( pPageCount ), pPageSt( pPageStart ) +{ + // Folgende Bedingungen muessen eingehalten werden: + // 1) es gibt mindestens eine Selektion + // 2) SPoint() == Start() + ASSERT( pPam->HasMark(), "SwDoc::Hyphenate: blowing in the wind"); + ASSERT( *pPam->GetPoint() <= *pPam->GetMark(), + "SwDoc::Hyphenate: New York, New York"); + + const SwNodes &rNds = pPam->GetDoc()->GetNodes(); + const SwPosition *pPoint = pPam->GetPoint(); + nNode = pPoint->nNode.GetIndex(); + + // Start einstellen + pStart = pPoint->nNode.GetNode().GetTxtNode(); + nPamStart = pPoint->nContent.GetIndex(); + + // Ende und Laenge einstellen. + const SwPosition *pMark = pPam->GetMark(); + pEnd = pMark->nNode.GetNode().GetTxtNode(); + nPamLen = pMark->nContent.GetIndex(); + if( pPoint->nNode == pMark->nNode ) + nPamLen -= pPoint->nContent.GetIndex(); +} + +inline void SwHyphArgs::SetRange( const SwNode *pNew ) +{ + nStart = pStart == pNew ? nPamStart : 0; + nLen = pEnd == pNew ? nPamLen : STRING_NOTFOUND; +} + +void SwHyphArgs::SetPam( SwPaM *pPam ) const +{ + if( !pNode ) + *pPam->GetPoint() = *pPam->GetMark(); + else + { + pPam->GetPoint()->nNode = nNode; + pPam->GetPoint()->nContent.Assign( pNode->GetCntntNode(), nWordStart ); + pPam->GetMark()->nNode = nNode; + pPam->GetMark()->nContent.Assign( pNode->GetCntntNode(), + nWordStart + nWordLen ); + ASSERT( nNode == pNode->GetIndex(), + "SwHyphArgs::SetPam: Pam desaster" ); + } +} + +// liefert sal_True zurueck, wenn es weitergehen soll. +sal_Bool lcl_HyphenateNode( const SwNodePtr& rpNd, void* pArgs ) +{ + // Hyphenate liefert sal_True zurueck, wenn eine Trennstelle anliegt + // und stellt pPam ein. + SwTxtNode *pNode = rpNd->GetTxtNode(); + SwHyphArgs *pHyphArgs = (SwHyphArgs*)pArgs; + if( pNode ) + { + SwCntntFrm* pCntFrm = pNode->GetFrm(); + if( pCntFrm && !((SwTxtFrm*)pCntFrm)->IsHiddenNow() ) + { + sal_uInt16 *pPageSt = pHyphArgs->GetPageSt(); + sal_uInt16 *pPageCnt = pHyphArgs->GetPageCnt(); + if( pPageCnt && *pPageCnt && pPageSt ) + { + sal_uInt16 nPageNr = pCntFrm->GetPhyPageNum(); + if( !*pPageSt ) + { + *pPageSt = nPageNr; + if( *pPageCnt < *pPageSt ) + *pPageCnt = *pPageSt; + } + long nStat = nPageNr >= *pPageSt ? nPageNr - *pPageSt + 1 + : nPageNr + *pPageCnt - *pPageSt + 1; + ::SetProgressState( nStat, (SwDocShell*)pNode->GetDoc()->GetDocShell() ); + } + pHyphArgs->SetRange( rpNd ); + if( pNode->Hyphenate( *pHyphArgs ) ) + { + pHyphArgs->SetNode( rpNd ); + return sal_False; + } + } + } + pHyphArgs->NextNode(); + return sal_True; +} + +uno::Reference< linguistic::XHyphenatedWord > SwDoc::Hyphenate( + SwPaM *pPam, const Point &rCrsrPos, + sal_uInt16* pPageCnt, sal_uInt16* pPageSt ) +{ + ASSERT(this == pPam->GetDoc(), "SwDoc::Hyphenate: strangers in the night"); + + if( *pPam->GetPoint() > *pPam->GetMark() ) + pPam->Exchange(); + + SwHyphArgs aHyphArg( pPam, rCrsrPos, pPageCnt, pPageSt ); + SwNodeIndex aTmpIdx( pPam->GetMark()->nNode, 1 ); + GetNodes().ForEach( pPam->GetPoint()->nNode, aTmpIdx, + lcl_HyphenateNode, &aHyphArg ); + aHyphArg.SetPam( pPam ); + return aHyphArg.GetHyphWord(); // will be set by lcl_HyphenateNode +} + +void ReplaceTabsStr( String& rStr, const String& rSrch, const String& rRepl ) +{ + xub_StrLen nPos = 0; + while( STRING_NOTFOUND != ( nPos = rStr.Search( rSrch, nPos )) ) + { + // wurde das escaped? + if( nPos && '\\' == rStr.GetChar( nPos-1 )) + { + // noch nicht am Ende ?? + rStr.Erase( nPos-1, 1 ); // den \\ noch loeschen + if( nPos >= rStr.Len() ) + break; + } + else + { + rStr.Erase( nPos, rSrch.Len() ); + rStr.Insert( rRepl, nPos ); + nPos += rRepl.Len(); + } + } +} + +sal_Bool lcl_GetTokenToParaBreak( String& rStr, String& rRet, sal_Bool bRegExpRplc ) +{ + sal_Bool bRet = sal_False; + if( bRegExpRplc ) + { + xub_StrLen nPos = 0; + String sPara( String::CreateFromAscii( + RTL_CONSTASCII_STRINGPARAM( "\\n" ))); + while( STRING_NOTFOUND != ( nPos = rStr.Search( sPara, nPos )) ) + { + // wurde das escaped? + if( nPos && '\\' == rStr.GetChar( nPos-1 )) + { + if( ++nPos >= rStr.Len() ) + break; + } + else + { + rRet = rStr.Copy( 0, nPos ); + rStr.Erase( 0, nPos + sPara.Len() ); + bRet = sal_True; + break; + } + } + } + if( !bRet ) + { + rRet = rStr; + rStr.Erase(); + } + return bRet; +} + +sal_Bool SwDoc::Replace( SwPaM& rPam, const String& rStr, sal_Bool bRegExpRplc ) +{ + if( !rPam.HasMark() || *rPam.GetPoint() == *rPam.GetMark() ) + return sal_False; + + sal_Bool bJoinTxt, bJoinPrev; + lcl_GetJoinFlags( rPam, bJoinTxt, bJoinPrev ); + + { + // dann eine Kopie vom Cursor erzeugen um alle Pams aus den + // anderen Sichten aus dem Loeschbereich zu verschieben + // ABER NICHT SICH SELBST !! + SwPaM aDelPam( *rPam.GetMark(), *rPam.GetPoint() ); + ::PaMCorrAbs( aDelPam, *aDelPam.GetPoint() ); + + SwPosition *pStt = (SwPosition*)aDelPam.Start(), + *pEnd = (SwPosition*)aDelPam.End(); + ASSERT( pStt->nNode == pEnd->nNode || + ( pStt->nNode.GetIndex() + 1 == pEnd->nNode.GetIndex() && + !pEnd->nContent.GetIndex() ), + "Point & Mark zeigen auf verschiedene Nodes" ); + sal_Bool bOneNode = pStt->nNode == pEnd->nNode; + + // eigenes Undo ???? + String sRepl( rStr ); + SwTxtNode* pTxtNd = pStt->nNode.GetNode().GetTxtNode(); + xub_StrLen nStt = pStt->nContent.GetIndex(), + nEnd = bOneNode ? pEnd->nContent.GetIndex() + : pTxtNd->GetTxt().Len(); + if( bRegExpRplc ) // regulaer suchen ?? + { + String sFndStr( pTxtNd->GetTxt().Copy( nStt, nEnd - nStt )); + +//JP 31.03.99: was ist, wenn im gefundenem anderer Inhalt als Text ist, +// wie z.B. Rahmen, Felder, Fussnoten, ... ??? +// Die aktuelle Implementierung entfernt diese Inhalte einfach. +// Eigentlich muss der Inhalt immer kopiert werden! + sFndStr.EraseAllChars( CH_TXTATR_BREAKWORD ); + sFndStr.EraseAllChars( CH_TXTATR_INWORD ); + + String sTmp( String::CreateFromAscii( + RTL_CONSTASCII_STRINGPARAM( "\\t" ))); + ReplaceTabsStr( sRepl, String( '&' ), sFndStr ); + ReplaceTabsStr( sRepl, sTmp, String( '\t' ) ); + } + + SwDataChanged aTmp( aDelPam, 0 ); + + if( IsRedlineOn() ) + { + SwRedlineMode eOld = GetRedlineMode(); + if( DoesUndo() ) + { + StartUndo(); + + // Bug 68584 - if any Redline will change (split!) the node + String sNm; sNm = String::CreateFromInt32( (long)&aDelPam ); + SwBookmark* pBkmk = MakeBookmark( aDelPam, + KeyCode(), sNm, sNm, UNO_BOOKMARK ); + +//JP 06.01.98: MUSS noch optimiert werden!!! +SetRedlineMode( REDLINE_ON | REDLINE_SHOW_INSERT | REDLINE_SHOW_DELETE ); + + *aDelPam.GetPoint() = pBkmk->GetPos(); + *aDelPam.GetMark() = *pBkmk->GetOtherPos(); + DelBookmark( GetBookmarks().GetPos( pBkmk )); + pStt = aDelPam.Start(); + pTxtNd = pStt->nNode.GetNode().GetTxtNode(); + nStt = pStt->nContent.GetIndex(); + } + + if( sRepl.Len() ) + { + // Attribute des 1. Zeichens ueber den ReplaceText setzen + SfxItemSet aSet( GetAttrPool(), + RES_CHRATR_BEGIN, RES_TXTATR_WITHEND_END - 1, + RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1, + 0 ); + pTxtNd->GetAttr( aSet, nStt+1, nStt+1 ); + + aSet.ClearItem( RES_TXTATR_REFMARK ); + aSet.ClearItem( RES_TXTATR_TOXMARK ); + + if( aDelPam.GetPoint() != aDelPam.End() ) + aDelPam.Exchange(); + + // das Ende merken + SwNodeIndex aPtNd( aDelPam.GetPoint()->nNode, -1 ); + xub_StrLen nPtCnt = aDelPam.GetPoint()->nContent.GetIndex(); + + sal_Bool bFirst = sal_True; + String sIns; + while( lcl_GetTokenToParaBreak( sRepl, sIns, bRegExpRplc )) + { + Insert( aDelPam, sIns ); + if( bFirst ) + { + SwNodeIndex aMkNd( aDelPam.GetMark()->nNode, -1 ); + xub_StrLen nMkCnt = aDelPam.GetMark()->nContent.GetIndex(); + + SplitNode( *aDelPam.GetPoint() ); + + aMkNd++; + aDelPam.GetMark()->nNode = aMkNd; + aDelPam.GetMark()->nContent.Assign( + aMkNd.GetNode().GetCntntNode(), nMkCnt ); + bFirst = sal_False; + } + else + SplitNode( *aDelPam.GetPoint() ); + } + if( sIns.Len() ) + Insert( aDelPam, sIns ); + + SwPaM aTmpRange( *aDelPam.GetPoint() ); + aTmpRange.SetMark(); + + aPtNd++; + aDelPam.GetPoint()->nNode = aPtNd; + aDelPam.GetPoint()->nContent.Assign( aPtNd.GetNode().GetCntntNode(), + nPtCnt); + *aTmpRange.GetMark() = *aDelPam.GetPoint(); + + RstTxtAttr( aTmpRange ); + Insert( aTmpRange, aSet ); + } + + if( DoesUndo() ) + AppendUndo( new SwUndoRedlineDelete( aDelPam, UNDO_REPLACE )); + AppendRedline( new SwRedline( REDLINE_DELETE, aDelPam )); + + if( DoesUndo() ) + { + EndUndo(); + + // Bug 68584 - if any Redline will change (split!) the node + String sNm; sNm = String::CreateFromInt32( (long)&aDelPam ); + SwBookmark* pBkmk = MakeBookmark( aDelPam, + KeyCode(), sNm, sNm, UNO_BOOKMARK ); + + SwIndex& rIdx = aDelPam.GetPoint()->nContent; + rIdx.Assign( 0, 0 ); + aDelPam.GetMark()->nContent = rIdx; + rPam.GetPoint()->nNode = 0; + rPam.GetPoint()->nContent = rIdx; + *rPam.GetMark() = *rPam.GetPoint(); +//JP 06.01.98: MUSS noch optimiert werden!!! +SetRedlineMode( eOld ); + + *rPam.GetPoint() = pBkmk->GetPos(); + *rPam.GetMark() = *pBkmk->GetOtherPos(); + DelBookmark( GetBookmarks().GetPos( pBkmk )); + } + bJoinTxt = sal_False; + } + else + { + if( !IsIgnoreRedline() && GetRedlineTbl().Count() ) + DeleteRedline( aDelPam ); + + SwUndoReplace* pUndoRpl = 0; + if( DoesUndo() ) + { + ClearRedo(); + SwUndo* pU; + + if( !pUndos->Count() || + UNDO_REPLACE != ( pU = (*pUndos)[ pUndos->Count()-1 ])->GetId() || + ( pUndoRpl = (SwUndoReplace*)pU )->IsFull() ) + { + pUndoRpl = new SwUndoReplace(); + AppendUndo( pUndoRpl ); + } + pUndoRpl->AddEntry( aDelPam, sRepl, bRegExpRplc ); + DoUndo( sal_False ); + } + + if( aDelPam.GetPoint() != pStt ) + aDelPam.Exchange(); + + SwNodeIndex aPtNd( pStt->nNode, -1 ); + xub_StrLen nPtCnt = pStt->nContent.GetIndex(); + + // die Werte nochmal setzen, falls schohn Rahmen oder Fussnoten + // auf dem Text entfernt wurden! + nStt = nPtCnt; + nEnd = bOneNode ? pEnd->nContent.GetIndex() + : pTxtNd->GetTxt().Len(); + + sal_Bool bFirst = sal_True; + String sIns; + while( lcl_GetTokenToParaBreak( sRepl, sIns, bRegExpRplc )) + { + if( !bFirst || nStt == pTxtNd->GetTxt().Len() ) + Insert( aDelPam, sIns ); + else if( nStt < nEnd || sIns.Len() ) + pTxtNd->Replace( pStt->nContent, nEnd - nStt, sIns ); + SplitNode( *pStt ); + bFirst = sal_False; + } + + if( bFirst || sIns.Len() ) + { + if( !bFirst || nStt == pTxtNd->GetTxt().Len() ) + Insert( aDelPam, sIns ); + else if( nStt < nEnd || sIns.Len() ) + pTxtNd->Replace( pStt->nContent, nEnd - nStt, sIns ); + } + + *rPam.GetMark() = *aDelPam.GetMark(); + + aPtNd++; + rPam.GetMark()->nNode = aPtNd; + rPam.GetMark()->nContent.Assign( aPtNd.GetNode().GetCntntNode(), + nPtCnt ); + if( bJoinTxt ) + rPam.Move( fnMoveBackward ); + + if( pUndoRpl ) + { + pUndoRpl->SetEntryEnd( rPam ); + DoUndo( sal_True ); + } + } + } + + if( bJoinTxt ) + lcl_JoinText( rPam, bJoinPrev ); + + SetModified(); + return sal_True; +} + + // speicher die akt. Werte fuer die automatische Aufnahme von Ausnahmen + // in die Autokorrektur +void SwDoc::SetAutoCorrExceptWord( SwAutoCorrExceptWord* pNew ) +{ + if( pACEWord && pNew != pACEWord ) + delete pACEWord; + pACEWord = pNew; +} + +sal_Bool SwDoc::DelFullPara( SwPaM& rPam ) +{ + const SwPosition &rStt = *rPam.Start(), &rEnd = *rPam.End(); + const SwNode* pNd = &rStt.nNode.GetNode(); + sal_uInt32 nSectDiff = pNd->FindStartNode()->EndOfSectionIndex() - + pNd->StartOfSectionIndex(); + sal_uInt32 nNodeDiff = rEnd.nNode.GetIndex() - rStt.nNode.GetIndex(); + + if( nSectDiff-2 <= nNodeDiff || IsRedlineOn() ) + return sal_False; + + // harte SeitenUmbrueche am nachfolgenden Node verschieben + sal_Bool bSavePageBreak = sal_False, bSavePageDesc = sal_False; + sal_uInt32 nNextNd = rEnd.nNode.GetIndex() + 1; + SwTableNode* pTblNd = GetNodes()[ nNextNd ]->GetTableNode(); + if( pTblNd && pNd->IsCntntNode() ) + { + SwFrmFmt* pTableFmt = pTblNd->GetTable().GetFrmFmt(); +//JP 24.08.98: will man wirklich den PageDesc/Break vom +// nachfolgen Absatz ueberbuegeln? +// const SwAttrSet& rAttrSet = pTableFmt->GetAttrSet(); +// if( SFX_ITEM_SET != rAttrSet.GetItemState( RES_PAGEDESC ) && +// SFX_ITEM_SET != rAttrSet.GetItemState( RES_BREAK )) + { + const SfxPoolItem *pItem; + const SfxItemSet* pSet = ((SwCntntNode*)pNd)->GetpSwAttrSet(); + if( pSet && SFX_ITEM_SET == pSet->GetItemState( RES_PAGEDESC, + sal_False, &pItem ) ) + { + pTableFmt->SetAttr( *pItem ); + bSavePageDesc = sal_True; + } + + if( pSet && SFX_ITEM_SET == pSet->GetItemState( RES_BREAK, + sal_False, &pItem ) ) + { + pTableFmt->SetAttr( *pItem ); + bSavePageBreak = sal_True; + } + } + } + + sal_Bool bDoesUndo = DoesUndo(); + if( bDoesUndo ) + { + if( !rPam.HasMark() ) + rPam.SetMark(); + else if( rPam.GetPoint() == &rStt ) + rPam.Exchange(); + rPam.GetPoint()->nNode++; + + rPam.GetPoint()->nContent.Assign( 0, 0 ); + rPam.GetMark()->nContent.Assign( 0, 0 ); + + ClearRedo(); + SwUndoDelete* pUndo = new SwUndoDelete( rPam, sal_True ); + pUndo->SetPgBrkFlags( bSavePageBreak, bSavePageDesc ); + AppendUndo( pUndo ); + } + else + { + SwNodeRange aRg( rStt.nNode, rEnd.nNode ); + if( rPam.GetPoint() != &rEnd ) + rPam.Exchange(); + + // versuche hinters Ende zu verschieben + if( !rPam.Move( fnMoveForward, fnGoNode ) ) + { + // na gut, dann an den Anfang + rPam.Exchange(); + if( !rPam.Move( fnMoveBackward, fnGoNode )) + { + ASSERT( sal_False, "kein Node mehr vorhanden" ); + return sal_False; + } + } + // text::Bookmarks usw. verschieben + CorrAbs( aRg.aStart, aRg.aEnd, *rPam.GetPoint(), sal_True ); + + // was ist mit Fly's ?? + { + // stehen noch FlyFrames rum, loesche auch diese + const SwPosition* pAPos; + for( sal_uInt16 n = 0; n < GetSpzFrmFmts()->Count(); ++n ) + { + SwFrmFmt* pFly = (*GetSpzFrmFmts())[n]; + const SwFmtAnchor* pAnchor = &pFly->GetAnchor(); + if( ( FLY_AT_CNTNT == pAnchor->GetAnchorId() || + FLY_AUTO_CNTNT == pAnchor->GetAnchorId() ) && + 0 != ( pAPos = pAnchor->GetCntntAnchor() ) && + aRg.aStart <= pAPos->nNode && pAPos->nNode <= aRg.aEnd ) + { + DelLayoutFmt( pFly ); + --n; + } + } + } + + rPam.GetPoint()->nContent.Assign( 0, 0 ); + rPam.GetMark()->nContent.Assign( 0, 0 ); + GetNodes().Delete( aRg.aStart, nNodeDiff+1 ); + } + rPam.DeleteMark(); + SetModified(); + return sal_True; +} + + + diff --git a/sw/source/core/doc/docfld.cxx b/sw/source/core/doc/docfld.cxx new file mode 100644 index 000000000000..a592d0f6f141 --- /dev/null +++ b/sw/source/core/doc/docfld.cxx @@ -0,0 +1,2880 @@ +/************************************************************************* + * + * $RCSfile: docfld.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:15 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _HINTIDS_HXX +#include +#endif + +#include +#include + +#ifndef _DATETIME_HXX //autogen +#include +#endif +#ifndef _SVSTDARR_HXX +#define _SVSTDARR_ULONGS +#include +#endif +#ifndef _APP_HXX //autogen +#include +#endif +#ifndef _APP_HXX //autogen +#include +#endif +#ifndef _SO2REF_HXX //autogen +#include +#endif +#ifndef _UNOTOOLS_CHARCLASS_HXX +#include +#endif + +#ifndef _DOC_HXX +#include +#endif +#ifndef _CNTFRM_HXX +#include +#endif +#ifndef _PAM_HXX +#include +#endif +#ifndef _NDTXT_HXX +#include +#endif +#ifndef _HINTS_HXX +#include +#endif +#ifndef _SWTABLE_HXX +#include +#endif +#ifndef _CALC_HXX +#include +#endif +#ifndef _ERRHDL_HXX +#include +#endif +#ifndef _TXTFLD_HXX //autogen +#include +#endif +#ifndef _FMTFLD_HXX //autogen +#include +#endif +#ifndef _TOX_HXX +#include +#endif +#ifndef _TXTTXMRK_HXX //autogen +#include +#endif +#ifndef _DOCFLD_HXX +#include // fuer Expression-Felder +#endif +#ifndef _DOCUFLD_HXX +#include +#endif +#ifndef _DDEFLD_HXX +#include +#endif +#ifndef _USRFLD_HXX +#include +#endif +#ifndef _EXPFLD_HXX +#include +#endif +#ifndef _DBFLD_HXX +#include +#endif +#ifndef _FLDDAT_HXX +#include +#endif +#ifndef _CHPFLD_HXX +#include +#endif +#ifndef _REFFLD_HXX +#include +#endif +#ifndef _DBMGR_HXX +#include +#endif +#ifndef _SECTION_HXX +#include +#endif +#ifndef _CELLATR_HXX +#include +#endif +#ifndef _DOCARY_HXX +#include +#endif +#ifndef _AUTHFLD_HXX +#include +#endif + +#ifndef _POOLFMT_HRC +#include // fuer InitFldTypes +#endif + + +#ifndef SO2_DECL_SVLINKNAME_DEFINED +#define SO2_DECL_SVLINKNAME_DEFINED +SO2_DECL_REF(SvLinkName) +#endif + +extern BOOL IsFrameBehind( const SwTxtNode& rMyNd, USHORT nMySttPos, + const SwTxtNode& rBehindNd, USHORT nSttPos ); + +SV_IMPL_OP_PTRARR_SORT( _SetGetExpFlds, _SetGetExpFldPtr ) + + +#ifdef UNX +#define DBNAME_COMPARE 0 +#define DBNAME_LOWER(s) s +#else +#define DBNAME_COMPARE INTN_COMPARE_IGNORECASE +#define DBNAME_LOWER(s) rCC.lower( s ) +#endif + +/*-------------------------------------------------------------------- + Beschreibung: Feldtypen einfuegen + --------------------------------------------------------------------*/ +/* + * Implementierung der Feldfunktionen am Doc + * Return immer einen gueltigen Pointer auf den Typ. Wenn er also neu + * zugefuegt oder schon vorhanden ist. + */ + +SwFieldType* SwDoc::InsertFldType(const SwFieldType &rFldTyp) +{ + USHORT nSize = pFldTypes->Count(), + nFldWhich = rFldTyp.Which(); + + USHORT i = INIT_FLDTYPES; + + switch( nFldWhich ) + { + case RES_SETEXPFLD: + //JP 29.01.96: SequenceFelder beginnen aber bei INIT_FLDTYPES - 3!! + // Sonst gibt es doppelte Nummernkreise!! + //MIB 14.03.95: Ab sofort verlaesst sich auch der SW3-Reader + //beim Aufbau der String-Pools und beim Einlesen von SetExp-Feldern + //hierauf + if( GSE_SEQ & ((SwSetExpFieldType&)rFldTyp).GetType() ) + i -= INIT_SEQ_FLDTYPES; + // kein break; + case RES_DBFLD: + case RES_USERFLD: + case RES_DDEFLD: + { + String sFldNm( rFldTyp.GetName() ); + const CharClass& rCC = GetAppCharClass(); + rCC.toLower( sFldNm ); + + for( ; i < nSize; ++i ) + if( nFldWhich == (*pFldTypes)[i]->Which() ) + { + String sCmpStr( (*pFldTypes)[i]->GetName() ); + rCC.toLower( sCmpStr ); + if( sCmpStr.Equals( sFldNm )) + return (*pFldTypes)[i]; + } + } + break; + + case RES_AUTHORITY: + for( ; i < nSize; ++i ) + if( nFldWhich == (*pFldTypes)[i]->Which() ) + return (*pFldTypes)[i]; + break; + + default: + for( i = 0; i < nSize; ++i ) + if( nFldWhich == (*pFldTypes)[i]->Which() ) + return (*pFldTypes)[i]; + } + + SwFieldType* pNew = rFldTyp.Copy(); + switch( nFldWhich ) + { + case RES_DDEFLD: + ((SwDDEFieldType*)pNew)->SetDoc( this ); + break; + + case RES_DBFLD: + case RES_TABLEFLD: + case RES_DATETIMEFLD: + case RES_GETEXPFLD: + ((SwValueFieldType*)pNew)->SetDoc( this ); + break; + + case RES_USERFLD: + case RES_SETEXPFLD: + ((SwValueFieldType*)pNew)->SetDoc( this ); + // JP 29.07.96: opt. FeldListe fuer den Calculator vorbereiten: + pUpdtFlds->InsertFldType( *pNew ); + break; + case RES_AUTHORITY : + ((SwAuthorityFieldType*)pNew)->SetDoc( this ); + break; + } + + pFldTypes->Insert( pNew, nSize ); + SetModified(); + + return (*pFldTypes)[ nSize ]; +} + +void SwDoc::InsDeletedFldType( SwFieldType& rFldTyp ) +{ + // der FeldTyp wurde als geloescht gekennzeichnet und aus dem + // Array entfernt. Nun muss man nach diesem wieder suchen. + // - Ist der nicht vorhanden, dann kann er eingefuegt werden. + // - Wird genau der gleiche Typ gefunden, dann muss der geloeschte + // einen anderen Namen erhalten. + + USHORT nSize = pFldTypes->Count(), nFldWhich = rFldTyp.Which(); + USHORT i = INIT_FLDTYPES; + + ASSERT( RES_SETEXPFLD == nFldWhich || + RES_USERFLD == nFldWhich || + RES_DDEFLD == nFldWhich, "Falscher FeldTyp" ); + + const CharClass& rCC = GetAppCharClass(); + const String& rFldNm = rFldTyp.GetName(); + String sLowerFldNm( rCC.lower( rFldNm )); + SwFieldType* pFnd; + + for( ; i < nSize; ++i ) + if( nFldWhich == (pFnd = (*pFldTypes)[i])->Which() && + sLowerFldNm.Equals( rCC.lower( pFnd->GetName() )) ) + { + // neuen Namen suchen + USHORT nNum = 1; + do { + String sSrch( sLowerFldNm ); + sSrch.Append( String::CreateFromInt32( nNum )); + for( i = INIT_FLDTYPES; i < nSize; ++i ) + if( nFldWhich == (pFnd = (*pFldTypes)[i])->Which() && + sSrch.Equals( rCC.lower( pFnd->GetName() ) )) + break; + + if( i >= nSize ) // nicht gefunden + { + ((String&)rFldNm).Append( String::CreateFromInt32( nNum )); + break; // raus aus der While-Schleife + } + ++nNum; + } while( TRUE ); + break; + } + + // nicht gefunden, also eintragen und Flag loeschen + pFldTypes->Insert( &rFldTyp, nSize ); + switch( nFldWhich ) + { + case RES_SETEXPFLD: + ((SwSetExpFieldType&)rFldTyp).SetDeleted( FALSE ); + break; + case RES_USERFLD: + ((SwUserFieldType&)rFldTyp).SetDeleted( FALSE ); + break; + case RES_DDEFLD: + ((SwDDEFieldType&)rFldTyp).SetDeleted( FALSE ); + break; + } +} + +/*-------------------------------------------------------------------- + Beschreibung: Feldtypen loeschen + --------------------------------------------------------------------*/ + +void SwDoc::RemoveFldType(USHORT nFld) +{ + ASSERT( INIT_FLDTYPES <= nFld, "keine InitFields loeschen" ); + /* + * Abheangige Felder vorhanden -> ErrRaise + */ + USHORT nSize = pFldTypes->Count(); + if(nFld < nSize) + { + SwFieldType* pTmp = (*pFldTypes)[nFld]; + + // JP 29.07.96: opt. FeldListe fuer den Calculator vorbereiten: + USHORT nWhich = pTmp->Which(); + switch( nWhich ) + { + case RES_SETEXPFLD: + case RES_USERFLD: + pUpdtFlds->RemoveFldType( *pTmp ); + // kein break; + case RES_DDEFLD: + if( pTmp->GetDepends() && !IsUsed( *pTmp ) ) + { + if( RES_SETEXPFLD == nWhich ) + ((SwSetExpFieldType*)pTmp)->SetDeleted( TRUE ); + else if( RES_USERFLD == nWhich ) + ((SwUserFieldType*)pTmp)->SetDeleted( TRUE ); + else + ((SwDDEFieldType*)pTmp)->SetDeleted( TRUE ); + nWhich = 0; + } + break; + } + + if( nWhich ) + { + ASSERT( !pTmp->GetDepends(), "Abhaengige vorh.!" ); + // Feldtype loschen + delete pTmp; + } + pFldTypes->Remove( nFld ); + SetModified(); + } +} + +/*-------------------------------------------------------------------- + Beschreibung: Den ersten Typen mit ResId und Namen finden + --------------------------------------------------------------------*/ + +SwFieldType* SwDoc::GetFldType( USHORT nResId, const String& rName ) const +{ + USHORT nSize = pFldTypes->Count(), i = 0; + const CharClass& rCC = GetAppCharClass(); + + String aTmp2( rName ); + rCC.toLower( aTmp2 ); + + switch( nResId ) + { + case RES_SETEXPFLD: + //JP 29.01.96: SequenceFelder beginnen aber bei INIT_FLDTYPES - 3!! + // Sonst gibt es doppelte Nummernkreise!! + //MIB 14.03.95: Ab sofort verlaesst sich auch der SW3-Reader + //beim Aufbau der String-Pools und beim Einlesen von SetExp-Feldern + //hierauf + i = INIT_FLDTYPES - INIT_SEQ_FLDTYPES; + break; + + case RES_DBFLD: + case RES_USERFLD: + case RES_DDEFLD: + case RES_AUTHORITY: + i = INIT_FLDTYPES; + break; + } + + SwFieldType* pRet = 0; + for( ; i < nSize; ++i ) + { + SwFieldType* pFldType = (*pFldTypes)[i]; + if( nResId == pFldType->Which() ) + { + String aTmp( pFldType->GetName() ); + rCC.toLower( aTmp ); + + if( aTmp2.Equals( aTmp )) + { + pRet = pFldType; + break; + } + } + } + return pRet; +} + + +/************************************************************************* +|* SwDoc::UpdateFlds() +|* Beschreibung Felder updaten +*************************************************************************/ +/* + * Alle sollen neu evaluiert werden. + */ + +void SwDoc::UpdateFlds( SfxPoolItem *pNewHt, BOOL bCloseDB ) +{ + // Modify() fuer jeden Feldtypen rufen, + // abhaengige SwTxtFld werden benachrichtigt ... + + for( USHORT i=0; i < pFldTypes->Count(); ++i) + { + switch( (*pFldTypes)[i]->Which() ) + { + // Tabellen-Felder als vorletztes Updaten + // Referenzen als letztes Updaten + case RES_GETREFFLD: + case RES_TABLEFLD: + case RES_DBFLD: + case RES_JUMPEDITFLD: + case RES_REFPAGESETFLD: // werden nie expandiert! + break; + + case RES_DDEFLD: + { + if( !pNewHt ) + { + SwMsgPoolItem aUpdateDDE( RES_UPDATEDDETBL ); + (*pFldTypes)[i]->Modify( 0, &aUpdateDDE ); + } + else + (*pFldTypes)[i]->Modify( 0, pNewHt ); + break; + } + case RES_GETEXPFLD: + case RES_SETEXPFLD: + case RES_HIDDENTXTFLD: + case RES_HIDDENPARAFLD: + // Expression-Felder werden gesondert behandelt + if( !pNewHt ) + break; + default: + (*pFldTypes)[i]->Modify( 0, pNewHt ); + } + } + + if( !IsExpFldsLocked() ) + UpdateExpFlds( 0, FALSE ); // Expression-Felder Updaten + + // Tabellen + UpdateTblFlds(pNewHt); + + // Referenzen + UpdateRefFlds(pNewHt); + + if( bCloseDB ) + GetNewDBMgr()->CloseAll(); + + // Nur bei KomplettUpdate evaluieren + SetModified(); +} + +/****************************************************************************** + * void SwDoc::UpdateUsrFlds() + ******************************************************************************/ + +void SwDoc::UpdateUsrFlds() +{ + SwCalc* pCalc = 0; + const SwFieldType* pFldType; + for( USHORT i = INIT_FLDTYPES; i < pFldTypes->Count(); ++i ) + if( RES_USERFLD == ( pFldType = (*pFldTypes)[i] )->Which() ) + { + if( !pCalc ) + pCalc = new SwCalc( *this ); + ((SwUserFieldType*)pFldType)->GetValue( *pCalc ); + } + + if( pCalc ) + { + delete pCalc; + SetModified(); + } +} + +/*-------------------------------------------------------------------- + Beschreibung: Referenzfelder und TableFelder erneuern + --------------------------------------------------------------------*/ + +void SwDoc::UpdateRefFlds( SfxPoolItem* pHt ) +{ + SwFieldType* pFldType; + for( USHORT i = 0; i < pFldTypes->Count(); ++i ) + if( RES_GETREFFLD == ( pFldType = (*pFldTypes)[i] )->Which() ) + pFldType->Modify( 0, pHt ); +} + +void SwDoc::UpdateTblFlds( SfxPoolItem* pHt ) +{ + ASSERT( !pHt || RES_TABLEFML_UPDATE == pHt->Which(), + "Was ist das fuer ein MessageItem?" ); + + SwFieldType* pFldType; + for( USHORT i = 0; i < pFldTypes->Count(); ++i ) + { + if( RES_TABLEFLD == ( pFldType = (*pFldTypes)[i] )->Which() ) + { + SwTableFmlUpdate* pUpdtFld = 0; + if( pHt && RES_TABLEFML_UPDATE == pHt->Which() ) + pUpdtFld = (SwTableFmlUpdate*)pHt; + + SwClientIter aIter( *pFldType ); + for( SwFmtFld* pFmtFld = (SwFmtFld*)aIter.First( TYPE( SwFmtFld )); + pFmtFld; pFmtFld = (SwFmtFld*)aIter.Next() ) + if( pFmtFld->GetTxtFld() ) + { + SwTblField* pFld = (SwTblField*)pFmtFld->GetFld(); + + if( pUpdtFld ) + { + // bestimme Tabelle, in der das Feld steht + const SwTableNode* pTblNd; + const SwTxtNode& rTxtNd = pFmtFld->GetTxtFld()->GetTxtNode(); + if( !rTxtNd.GetNodes().IsDocNodes() || + 0 == ( pTblNd = rTxtNd.FindTableNode() ) ) + continue; + + switch( pUpdtFld->eFlags ) + { + case TBL_CALC: + // setze das Value-Flag zurueck + // JP 17.06.96: interne Darstellung auf alle Formeln + // (Referenzen auf andere Tabellen!!!) + if( SUB_CMD & pFld->GetSubType() ) + pFld->PtrToBoxNm( pUpdtFld->pTbl ); + else + pFld->ChgValid( FALSE ); + break; + case TBL_BOXNAME: + // ist es die gesuchte Tabelle ?? + if( &pTblNd->GetTable() == pUpdtFld->pTbl ) + // zur externen Darstellung + pFld->PtrToBoxNm( pUpdtFld->pTbl ); + break; + case TBL_BOXPTR: + // zur internen Darstellung + // JP 17.06.96: interne Darstellung auf alle Formeln + // (Referenzen auf andere Tabellen!!!) + pFld->BoxNmToPtr( pUpdtFld->pTbl ); + break; + case TBL_RELBOXNAME: + // ist es die gesuchte Tabelle ?? + if( &pTblNd->GetTable() == pUpdtFld->pTbl ) + // zur relativen Darstellung + pFld->ToRelBoxNm( pUpdtFld->pTbl ); + break; + } + } + else + // setze bei allen das Value-Flag zurueck + pFld->ChgValid( FALSE ); + } + + break; + } + pFldType = 0; + } + + // und dann noch alle Tabellen Box Formeln abklappern + const SfxPoolItem* pItem; + USHORT nMaxItems = GetAttrPool().GetItemCount( RES_BOXATR_FORMULA ); + for( i = 0; i < nMaxItems; ++i ) + if( 0 != (pItem = GetAttrPool().GetItem( RES_BOXATR_FORMULA, i ) ) && + ((SwTblBoxFormula*)pItem)->GetDefinedIn() ) + { + ((SwTblBoxFormula*)pItem)->ChangeState( pHt ); + } + + + // alle Felder/Boxen sind jetzt invalide, also kann das Rechnen anfangen + if( pHt && ( RES_TABLEFML_UPDATE != pHt->Which() || + TBL_CALC != ((SwTableFmlUpdate*)pHt)->eFlags )) + return ; + + SwCalc* pCalc = 0; + + if( pFldType ) + { + SwClient* pLast; + SwClientIter aIter( *pFldType ); + // dann rechne mal schoen + // JP 27.03.97: Beim Berechnen am Ende anfangen - weil neue + // Felder immer am Anfang der Modifykette eingefuegt + // werden. Beim Import haben wir damit eine bessere/ + // schnellere Berechnung bei "Kettenformeln" + if( 0 != ( pLast = aIter.GoEnd() )) + do { + SwFmtFld* pFmtFld = (SwFmtFld*)pLast; + SwTblField* pFld; + if( !pFmtFld->GetTxtFld() || (SUB_CMD & + (pFld = (SwTblField*)pFmtFld->GetFld())->GetSubType() )) + continue; + + // muss neu berechnet werden (und ist keine textuelle Anzeige) + if( !pFld->IsValid() ) + { + // bestimme Tabelle, in der das Feld steht + const SwTxtNode& rTxtNd = pFmtFld->GetTxtFld()->GetTxtNode(); + if( !rTxtNd.GetNodes().IsDocNodes() ) + continue; + const SwTableNode* pTblNd = rTxtNd.FindTableNode(); + if( !pTblNd ) + continue; + + // falls dieses Feld nicht in der zu updatenden + // Tabelle steht, ueberspringen !! + if( pHt && &pTblNd->GetTable() != + ((SwTableFmlUpdate*)pHt)->pTbl ) + continue; + + if( !pCalc ) + pCalc = new SwCalc( *this ); + + // bestimme die Werte aller SetExpresion Felder, die + // bis zur Tabelle gueltig sind + SwFrm* pFrm = 0; + if( pTblNd->GetIndex() < GetNodes().GetEndOfExtras().GetIndex() ) + { + // steht im Sonderbereich, wird teuer !! + Point aPt; // den im Layout 1. Frame returnen - Tab.Kopfzeile !! + pFrm = rTxtNd.GetFrm( &aPt ); + if( pFrm ) + { + SwPosition aPos( *pTblNd ); + if( GetBodyTxtNode( *this, aPos, *pFrm ) ) + FldsToCalc( *pCalc, _SetGetExpFld( + aPos.nNode, pFmtFld->GetTxtFld(), + &aPos.nContent )); + else + pFrm = 0; + } + } + if( !pFrm ) + { + // einen Index fuers bestimmen vom TextNode anlegen + SwNodeIndex aIdx( rTxtNd ); + FldsToCalc( *pCalc, + _SetGetExpFld( aIdx, pFmtFld->GetTxtFld() )); + } + + SwTblCalcPara aPara( *pCalc, pTblNd->GetTable() ); + pFld->CalcField( aPara ); + if( aPara.IsStackOverFlow() ) + { + if( aPara.CalcWithStackOverflow() ) + pFld->CalcField( aPara ); +#ifndef PRODUCT + else + { + // mind. ein ASSERT + ASSERT( !this, "die Kettenformel konnte nicht errechnet werden" ); + } +#endif + } + pCalc->SetCalcError( CALC_NOERR ); + } + pFmtFld->Modify( 0, pHt ); + } while( 0 != ( pLast = aIter-- )); + } + + // dann berechene noch die Formeln an den Boxen + for( i = 0; i < nMaxItems; ++i ) + if( 0 != (pItem = GetAttrPool().GetItem( RES_BOXATR_FORMULA, i ) ) && + ((SwTblBoxFormula*)pItem)->GetDefinedIn() && + !((SwTblBoxFormula*)pItem)->IsValid() ) + { + SwTblBoxFormula* pFml = (SwTblBoxFormula*)pItem; + SwTableBox* pBox = pFml->GetTableBox(); + if( pBox && pBox->GetSttNd() && + pBox->GetSttNd()->GetNodes().IsDocNodes() ) + { + const SwTableNode* pTblNd = pBox->GetSttNd()->FindTableNode(); + if( !pHt || &pTblNd->GetTable() == + ((SwTableFmlUpdate*)pHt)->pTbl ) + { + double nValue; + if( !pCalc ) + pCalc = new SwCalc( *this ); + + // bestimme die Werte aller SetExpresion Felder, die + // bis zur Tabelle gueltig sind + SwFrm* pFrm = 0; + if( pTblNd->GetIndex() < GetNodes().GetEndOfExtras().GetIndex() ) + { + // steht im Sonderbereich, wird teuer !! + Point aPt; // den im Layout 1. Frame returnen - Tab.Kopfzeile !! + SwNodeIndex aCNdIdx( *pTblNd, +2 ); + SwCntntNode* pCNd = aCNdIdx.GetNode().GetCntntNode(); + if( !pCNd ) + pCNd = GetNodes().GoNext( &aCNdIdx ); + + if( pCNd && 0 != (pFrm = pCNd->GetFrm( &aPt )) ) + { + SwPosition aPos( *pCNd ); + if( GetBodyTxtNode( *this, aPos, *pFrm ) ) + FldsToCalc( *pCalc, _SetGetExpFld( aPos.nNode )); + else + pFrm = 0; + } + } + if( !pFrm ) + { + // einen Index fuers bestimmen vom TextNode anlegen + SwNodeIndex aIdx( *pTblNd ); + FldsToCalc( *pCalc, _SetGetExpFld( aIdx )); + } + + SwTblCalcPara aPara( *pCalc, pTblNd->GetTable() ); + pFml->Calc( aPara, nValue ); + + if( aPara.IsStackOverFlow() ) + { + if( aPara.CalcWithStackOverflow() ) + pFml->Calc( aPara, nValue ); +#ifndef PRODUCT + else + { + // mind. ein ASSERT + ASSERT( !this, "die Kettenformel konnte nicht errechnet werden" ); + } +#endif + } + + SwFrmFmt* pFmt = pBox->ClaimFrmFmt(); + SfxItemSet aTmp( GetAttrPool(), + RES_BOXATR_BEGIN,RES_BOXATR_END-1 ); + + if( pCalc->IsCalcError() ) + nValue = DBL_MAX; + aTmp.Put( SwTblBoxValue( nValue )); + if( SFX_ITEM_SET != pFmt->GetItemState( RES_BOXATR_FORMAT )) + aTmp.Put( SwTblBoxNumFormat( 0 )); + pFmt->SetAttr( aTmp ); + + pCalc->SetCalcError( CALC_NOERR ); + } + } + } + + if( pCalc ) + delete pCalc; +} + +void SwDoc::UpdatePageFlds( SfxPoolItem* pMsgHnt ) +{ + SwFieldType* pFldType; + for( USHORT i = 0; i < INIT_FLDTYPES; ++i ) + switch( ( pFldType = (*pFldTypes)[ i ] )->Which() ) + { + case RES_PAGENUMBERFLD: + case RES_CHAPTERFLD: + case RES_GETEXPFLD: + case RES_REFPAGEGETFLD: + pFldType->Modify( 0, pMsgHnt ); + break; + case RES_DOCSTATFLD: + pFldType->Modify( 0, 0 ); + break; + } + SetNewFldLst(); +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +// ---- Loesche alle nicht referenzierten FeldTypen eines Dokumentes -- +void SwDoc::GCFieldTypes() +{ + for( register USHORT n = pFldTypes->Count(); n > INIT_FLDTYPES; ) + if( !(*pFldTypes)[ --n ]->GetDepends() ) + RemoveFldType( n ); +} + + +//---------------------------------------------------------------------- + +// der StartIndex kann optional mit angegeben werden (z.B. wenn dieser +// zuvor schon mal erfragt wurde - ist sonst eine virtuelle Methode !!) + +_SetGetExpFld::_SetGetExpFld( const SwNodeIndex& rNdIdx, const SwTxtFld* pFld, + const SwIndex* pIdx ) +{ + eSetGetExpFldType = TEXTFIELD; + CNTNT.pTxtFld = pFld; + nNode = rNdIdx.GetIndex(); + if( pIdx ) + nCntnt = pIdx->GetIndex(); + else if( pFld ) + nCntnt = *pFld->GetStart(); + else + nCntnt = 0; +} + + //Erweiterung fuer Sections: + // diese haben immer als Content-Position 0xffff !! + // Auf dieser steht nie ein Feld, maximal bis STRING_MAXLEN moeglich +_SetGetExpFld::_SetGetExpFld( const SwSectionNode& rSectNd, + const SwPosition* pPos ) +{ + eSetGetExpFldType = SECTIONNODE; + CNTNT.pSection = &rSectNd.GetSection(); + + if( pPos ) + { + nNode = pPos->nNode.GetIndex(); + nCntnt = pPos->nContent.GetIndex(); + } + else + { + nNode = rSectNd.GetIndex(); + nCntnt = 0; + } +} + +_SetGetExpFld::_SetGetExpFld( const SwTableBox& rTBox, const SwPosition* pPos ) +{ + eSetGetExpFldType = TABLEBOX; + CNTNT.pTBox = &rTBox; + + if( pPos ) + { + nNode = pPos->nNode.GetIndex(); + nCntnt = pPos->nContent.GetIndex(); + } + else + { + nNode = 0; + nCntnt = 0; + if( rTBox.GetSttNd() ) + { + SwNodeIndex aIdx( *rTBox.GetSttNd() ); + const SwCntntNode* pNd = aIdx.GetNode().GetNodes().GoNext( &aIdx ); + if( pNd ) + nNode = pNd->GetIndex(); + } + } +} + +_SetGetExpFld::_SetGetExpFld( const SwNodeIndex& rNdIdx, + const SwTxtTOXMark& rTOX, + const SwIndex* pIdx ) +{ + eSetGetExpFldType = TEXTTOXMARK; + CNTNT.pTxtTOX = &rTOX; + nNode = rNdIdx.GetIndex(); + if( pIdx ) + nCntnt = pIdx->GetIndex(); + else + nCntnt = *rTOX.GetStart(); +} + +_SetGetExpFld::_SetGetExpFld( const SwPosition& rPos ) +{ + eSetGetExpFldType = CRSRPOS; + CNTNT.pPos = &rPos; + nNode = rPos.nNode.GetIndex(); + nCntnt = rPos.nContent.GetIndex(); +} + +void _SetGetExpFld::GetPos( SwPosition& rPos ) const +{ + rPos.nNode = nNode; + rPos.nContent.Assign( rPos.nNode.GetNode().GetCntntNode(), nCntnt ); +} + +void _SetGetExpFld::GetPosOfContent( SwPosition& rPos ) const +{ + const SwNode* pNd = GetNodeFromCntnt(); + if( pNd ) + pNd = pNd->GetCntntNode(); + + if( pNd ) + { + rPos.nNode = *pNd; + rPos.nContent.Assign( (SwCntntNode*)pNd,GetCntPosFromCntnt() ); + } + else + { + rPos.nNode = nNode; + rPos.nContent.Assign( rPos.nNode.GetNode().GetCntntNode(), nCntnt ); + } +} + +void _SetGetExpFld::SetBodyPos( const SwCntntFrm& rFrm ) +{ + if( !rFrm.IsInDocBody() ) + { + SwNodeIndex aIdx( *rFrm.GetNode() ); + SwDoc& rDoc = *aIdx.GetNodes().GetDoc(); + SwPosition aPos( aIdx ); +#ifndef PRODUCT + ASSERT( ::GetBodyTxtNode( rDoc, aPos, rFrm ), "wo steht das Feld" ); +#else + ::GetBodyTxtNode( rDoc, aPos, rFrm ); +#endif + nNode = aPos.nNode.GetIndex(); + nCntnt = aPos.nContent.GetIndex(); + } +} + +BOOL _SetGetExpFld::operator<( const _SetGetExpFld& rFld ) const +{ + if( nNode < rFld.nNode || ( nNode == rFld.nNode && nCntnt < rFld.nCntnt )) + return TRUE; + else if( nNode != rFld.nNode || nCntnt != rFld.nCntnt ) + return FALSE; + + const SwNode *pFirst = GetNodeFromCntnt(), + *pNext = rFld.GetNodeFromCntnt(); + + // Position gleich: nur weiter wenn beide FeldPointer besetzt sind !! + if( !pFirst || !pNext ) + return FALSE; + + // gleiche Section ?? + if( pFirst->StartOfSectionNode() != pNext->StartOfSectionNode() ) + { + // sollte einer in der Tabelle stehen ? + const SwNode *pFirstStt, *pNextStt; + const SwTableNode* pTblNd = pFirst->FindTableNode(); + if( pTblNd ) + pFirstStt = pTblNd->StartOfSectionNode(); + else + pFirstStt = pFirst->StartOfSectionNode(); + + if( 0 != ( pTblNd = pNext->FindTableNode() ) ) + pNextStt = pTblNd->StartOfSectionNode(); + else + pNextStt = pNext->StartOfSectionNode(); + + if( pFirstStt != pNextStt ) + { + if( pFirst->IsTxtNode() && pNext->IsTxtNode() && + ( pFirst->FindFlyStartNode() || pNext->FindFlyStartNode() )) + { + return ::IsFrameBehind( *(SwTxtNode*)pNext, nCntnt, + *(SwTxtNode*)pFirst, nCntnt ); + } + return pFirstStt->GetIndex() < pNextStt->GetIndex(); + } + } + + // ist gleiche Section, dann Feld im gleichen Node ? + if( pFirst != pNext ) + return pFirst->GetIndex() < pNext->GetIndex(); + + // gleicher Node in der Section, dann Position im Node + return GetCntPosFromCntnt() < rFld.GetCntPosFromCntnt(); +} + +const SwNode* _SetGetExpFld::GetNodeFromCntnt() const +{ + const SwNode* pRet = 0; + if( CNTNT.pTxtFld ) + switch( eSetGetExpFldType ) + { + case TEXTFIELD: + pRet = &CNTNT.pTxtFld->GetTxtNode(); + break; + + case SECTIONNODE: + pRet = CNTNT.pSection->GetFmt()->GetSectionNode(); + break; + + case CRSRPOS: + pRet = &CNTNT.pPos->nNode.GetNode(); + break; + + case TEXTTOXMARK: + pRet = &CNTNT.pTxtTOX->GetTxtNode(); + break; + + case TABLEBOX: + if( CNTNT.pTBox->GetSttNd() ) + { + SwNodeIndex aIdx( *CNTNT.pTBox->GetSttNd() ); + pRet = aIdx.GetNode().GetNodes().GoNext( &aIdx ); + } + break; + } + return pRet; +} + +USHORT _SetGetExpFld::GetCntPosFromCntnt() const +{ + USHORT nRet = 0; + if( CNTNT.pTxtFld ) + switch( eSetGetExpFldType ) + { + case TEXTFIELD: + nRet = *CNTNT.pTxtFld->GetStart(); + break; + case CRSRPOS: + nRet = CNTNT.pPos->nContent.GetIndex(); + break; + case TEXTTOXMARK: + nRet = *CNTNT.pTxtTOX->GetStart(); + break; + } + return nRet; +} + +_HashStr::_HashStr( const String& rName, const String& rText, + _HashStr* pNxt ) + : SwHash( rName ), aSetStr( rText ) +{ + pNext = pNxt; +} + +// suche nach dem Namen, ist er vorhanden, returne seinen String, sonst +// einen LeerString +void LookString( SwHash** ppTbl, USHORT nSize, const String& rName, + String& rRet, USHORT* pPos ) +{ + rRet = rName; + rRet.EraseLeadingChars().EraseTrailingChars(); + SwHash* pFnd = Find( rRet, ppTbl, nSize, pPos ); + if( pFnd ) + rRet = ((_HashStr*)pFnd)->aSetStr; + else + rRet.Erase(); +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +String lcl_GetDBVarName( SwDoc& rDoc, SwDBNameInfField& rDBFld ) +{ + String sDBNumNm( rDBFld.GetDBName( &rDoc )); + + if( sDBNumNm != rDoc.GetDBName() ) + sDBNumNm += DB_DELIM; + else + sDBNumNm.Erase(); + + sDBNumNm += SwFieldType::GetTypeStr(TYP_DBSETNUMBERFLD); + + return sDBNumNm; +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +void lcl_CalcFld( SwDoc& rDoc, SwCalc& rCalc, const _SetGetExpFld& rSGEFld, + SwNewDBMgr* pMgr ) +{ + const SwTxtFld* pTxtFld = rSGEFld.GetFld(); + if( !pTxtFld ) + return ; + + const SwField* pFld = pTxtFld->GetFld().GetFld(); + const USHORT nFldWhich = pFld->GetTyp()->Which(); + + if( RES_SETEXPFLD == nFldWhich ) + { + SwSbxValue aValue; + if( GSE_EXPR & pFld->GetSubType() ) + aValue.PutDouble( ((SwSetExpField*)pFld)->GetValue() ); + else + // Erweiterung fuers Rechnen mit Strings + aValue.PutString( ((SwSetExpField*)pFld)->GetExpStr() ); + + // setze im Calculator den neuen Wert + rCalc.VarChange( pFld->GetTyp()->GetName(), aValue ); + } + else if( pMgr ) + { + switch( nFldWhich ) + { + case RES_DBNUMSETFLD: + { + SwDBNumSetField* pDBFld = (SwDBNumSetField*)pFld; + +#ifdef REPLACE_OFADBMGR + String sDBName(pDBFld->GetDBName(&rDoc)); + String sSourceName(sDBName.GetToken(0, DB_DELIM)); + String sTableName(sDBName.GetToken(0).GetToken(1, DB_DELIM)); + + if( pDBFld->IsCondValid() && + pMgr->OpenDataSource( sSourceName, sTableName )) +#else + if( pMgr->OpenDB( DBMGR_STD, pDBFld->GetDBName(&rDoc)) && + pDBFld->IsCondValid() ) +#endif + rCalc.VarChange( lcl_GetDBVarName( rDoc, *pDBFld), + pDBFld->GetFormat() ); + } + break; + case RES_DBNEXTSETFLD: + { + SwDBNextSetField* pDBFld = (SwDBNextSetField*)pFld; +#ifdef REPLACE_OFADBMGR + String sDBName(pDBFld->GetDBName(&rDoc)); + String sSourceName(sDBName.GetToken(0, DB_DELIM)); + String sTableName(sDBName.GetToken(0).GetToken(1, DB_DELIM)); + if( !pDBFld->IsCondValid() || + !pMgr->OpenDataSource( sSourceName, sTableName )) +#else + if( !pMgr->OpenDB( DBMGR_STD, pDBFld->GetDBName(&rDoc)) || + !pDBFld->IsCondValid() ) +#endif + break; + + String sDBNumNm(lcl_GetDBVarName( rDoc, *pDBFld)); + SwCalcExp* pExp = rCalc.VarLook( sDBNumNm ); + if( pExp ) + rCalc.VarChange( sDBNumNm, pExp->nValue.GetLong() + 1 ); + } + break; + + } + } +} + +void SwDoc::FldsToCalc( SwCalc& rCalc, const _SetGetExpFld& rToThisFld ) +{ + // erzeuge die Sortierteliste aller SetFelder + pUpdtFlds->MakeFldList( *this, bNewFldLst, GETFLD_CALC ); + bNewFldLst = FALSE; + + SwNewDBMgr* pMgr = GetNewDBMgr(); +#ifdef REPLACE_OFADBMGR + pMgr->CloseAll(FALSE); +#else + pMgr->SetAllDirty(DBMGR_STD); +#endif + + if( pUpdtFlds->GetSortLst()->Count() ) + { + USHORT nLast; + _SetGetExpFld* pFld = (_SetGetExpFld*)&rToThisFld; + if( pUpdtFlds->GetSortLst()->Seek_Entry( pFld, &nLast ) ) + ++nLast; + + const _SetGetExpFldPtr* ppSortLst = pUpdtFlds->GetSortLst()->GetData(); + for( USHORT n = 0; n < nLast; ++n, ++ppSortLst ) + lcl_CalcFld( *this, rCalc, **ppSortLst, pMgr ); + } + +#ifdef REPLACE_OFADBMGR + pMgr->CloseAll(FALSE); +#else + pMgr->SetAllDirty(DBMGR_STD, FALSE); +#endif +} + +void SwDoc::FldsToCalc( SwCalc& rCalc, ULONG nLastNd, USHORT nLastCnt ) +{ + // erzeuge die Sortierteliste aller SetFelder + pUpdtFlds->MakeFldList( *this, bNewFldLst, GETFLD_CALC ); + bNewFldLst = FALSE; + + SwNewDBMgr* pMgr = GetNewDBMgr(); +#ifdef REPLACE_OFADBMGR + pMgr->CloseAll(FALSE); +#else + pMgr->SetAllDirty(DBMGR_STD); +#endif + + const _SetGetExpFldPtr* ppSortLst = pUpdtFlds->GetSortLst()->GetData(); + for( USHORT n = pUpdtFlds->GetSortLst()->Count(); + n && ((*ppSortLst)->GetNode() < nLastNd || ((*ppSortLst)->GetNode() + == nLastNd && (*ppSortLst)->GetCntnt() <= nLastCnt )); + --n, ++ppSortLst ) + lcl_CalcFld( *this, rCalc, **ppSortLst, pMgr ); + +#ifdef REPLACE_OFADBMGR + pMgr->CloseAll(FALSE); +#else + pMgr->SetAllDirty(DBMGR_STD, FALSE); +#endif +} + +void SwDoc::FldsToExpand( SwHash**& ppHashTbl, USHORT& rTblSize, + const _SetGetExpFld& rToThisFld ) +{ + // erzeuge die Sortierteliste aller SetFelder + pUpdtFlds->MakeFldList( *this, bNewFldLst, GETFLD_EXPAND ); + bNewFldLst = FALSE; + + // HashTabelle fuer alle String Ersetzungen, wird "one the fly" gefuellt + // (versuche eine "ungerade"-Zahl zu erzeugen) + rTblSize = (( pUpdtFlds->GetSortLst()->Count() / 7 ) + 1 ) * 7; + ppHashTbl = new SwHash*[ rTblSize ]; + memset( ppHashTbl, 0, sizeof( _HashStr* ) * rTblSize ); + + USHORT nLast; + { + _SetGetExpFld* pTmp = (_SetGetExpFld*)&rToThisFld; + if( pUpdtFlds->GetSortLst()->Seek_Entry( pTmp, &nLast ) ) + ++nLast; + } + + USHORT nPos; + SwHash* pFnd; + String aNew; + const _SetGetExpFldPtr* ppSortLst = pUpdtFlds->GetSortLst()->GetData(); + for( ; nLast; --nLast, ++ppSortLst ) + { + const SwTxtFld* pTxtFld = (*ppSortLst)->GetFld(); + if( !pTxtFld ) + continue; + + const SwField* pFld = pTxtFld->GetFld().GetFld(); + switch( pFld->GetTyp()->Which() ) + { + case RES_SETEXPFLD: + if( GSE_STRING & pFld->GetSubType() ) + { + // setze in der HashTabelle den neuen Wert + // ist die "Formel" ein Feld ?? + SwSetExpField* pSFld = (SwSetExpField*)pFld; + LookString( ppHashTbl, rTblSize, pSFld->GetFormula(), aNew ); + + if( !aNew.Len() ) // nichts gefunden, dann ist + aNew = pSFld->GetFormula(); // die Formel der neue Wert + + // suche den Namen vom Feld + aNew = ((SwSetExpFieldType*)pSFld->GetTyp())->GetSetRefName(); + // Eintrag vorhanden ? + pFnd = Find( aNew, ppHashTbl, rTblSize, &nPos ); + if( pFnd ) + // Eintrag in der HashTabelle aendern + ((_HashStr*)pFnd)->aSetStr = pSFld->GetExpStr(); + else + // neuen Eintrag einfuegen + *(ppHashTbl + nPos ) = new _HashStr( aNew, + pSFld->GetExpStr(), (_HashStr*)*(ppHashTbl + nPos) ); + } + break; + case RES_DBFLD: + { + const String& rName = pFld->GetTyp()->GetName(); + + // Eintrag in den HashTable eintragen + // Eintrag vorhanden ? + pFnd = Find( rName, ppHashTbl, rTblSize, &nPos ); + if( pFnd ) + // Eintrag in der HashTabelle aendern + ((_HashStr*)pFnd)->aSetStr = pFld->Expand(); + else + // neuen Eintrag einfuegen + *(ppHashTbl + nPos ) = new _HashStr( rName, + pFld->Expand(), (_HashStr*)*(ppHashTbl + nPos)); + } + break; + } + } +} + + +void SwDoc::UpdateExpFlds( SwTxtFld* pUpdtFld, BOOL bUpdRefFlds ) +{ + if( IsExpFldsLocked() ) + return; + + BOOL bOldInUpdateFlds = pUpdtFlds->IsInUpdateFlds(); + pUpdtFlds->SetInUpdateFlds( TRUE ); + + pUpdtFlds->MakeFldList( *this, TRUE, GETFLD_ALL ); + bNewFldLst = FALSE; + + if( !pUpdtFlds->GetSortLst()->Count() ) + { + if( bUpdRefFlds ) + UpdateRefFlds(); + + pUpdtFlds->SetInUpdateFlds( bOldInUpdateFlds ); + pUpdtFlds->SetFieldsDirty( FALSE ); + return ; + } + + USHORT nWhich, n; + + // HashTabelle fuer alle String Ersetzungen, wird "one the fly" gefuellt + // (versuche eine "ungerade"-Zahl zu erzeugen) + USHORT nStrFmtCnt = (( pFldTypes->Count() / 7 ) + 1 ) * 7; + SwHash** pHashStrTbl = new SwHash*[ nStrFmtCnt ]; + memset( pHashStrTbl, 0, sizeof( _HashStr* ) * nStrFmtCnt ); + + { + const SwFieldType* pFldType; + // gesondert behandeln: + for( n = pFldTypes->Count(); n; ) + switch( ( pFldType = (*pFldTypes)[ --n ] )->Which() ) + { + case RES_USERFLD: + { + // Eintrag vorhanden ? + USHORT nPos; + const String& rNm = pFldType->GetName(); + String sExpand(((SwUserFieldType*)pFldType)->Expand(GSE_STRING, 0, 0)); + SwHash* pFnd = Find( rNm, pHashStrTbl, nStrFmtCnt, &nPos ); + if( pFnd ) + // Eintrag in der HashTabelle aendern ?? + ((_HashStr*)pFnd)->aSetStr = sExpand; + else + // neuen Eintrag einfuegen + *(pHashStrTbl + nPos ) = new _HashStr( rNm, sExpand, + (_HashStr*)*(pHashStrTbl + nPos) ); + } + break; + case RES_SETEXPFLD: + ((SwSetExpFieldType*)pFldType)->SetOutlineChgNd( 0 ); + break; + } + } + + // Ok, das Array ist soweit mit allen Feldern gefuellt, dann rechne mal + SwCalc aCalc( *this ); + + String sDBNumNm( SwFieldType::GetTypeStr( TYP_DBSETNUMBERFLD ) ); + + // aktuelle Datensatznummer schon vorher einstellen + SwNewDBMgr* pMgr = GetNewDBMgr(); +#ifdef REPLACE_OFADBMGR + pMgr->CloseAll(FALSE); +#else + pMgr->SetAllDirty(DBMGR_STD); +#endif +/* + if(pMgr && pMgr->OpenDB(DBMGR_STD, GetDBDesc(), FALSE)) + { + if(!pMgr->IsInMerge() ) + pMgr->ToFirstSelectedRecord(DBMGR_STD); + + aCalc.VarChange( sDBNumNm, pMgr->GetCurSelectedRecordId(DBMGR_STD)); + } +*/ + + String aNew; + const _SetGetExpFldPtr* ppSortLst = pUpdtFlds->GetSortLst()->GetData(); + for( n = pUpdtFlds->GetSortLst()->Count(); n; --n, ++ppSortLst ) + { + SwSection* pSect = (SwSection*)(*ppSortLst)->GetSection(); + if( pSect ) + { + //!SECTION + +// if( pGFld->IsInBodyTxt() ) + pSect->SetCondHidden( aCalc.Calculate( + pSect->GetCondition() ).GetBool() ); + continue; + } + + SwTxtFld* pTxtFld = (SwTxtFld*)(*ppSortLst)->GetFld(); + if( !pTxtFld ) + { + ASSERT( !this, "was ist es denn nun" ); + continue; + } + + SwFmtFld* pFmtFld = (SwFmtFld*)&pTxtFld->GetFld(); + SwField* pFld = pFmtFld->GetFld(); + + switch( nWhich = pFld->GetTyp()->Which() ) + { + case RES_HIDDENTXTFLD: + { + SwHiddenTxtField* pHFld = (SwHiddenTxtField*)pFld; + pHFld->SetValue( !aCalc.Calculate( pHFld->GetPar1() ).GetBool()); + // Feld Evaluieren + pHFld->Evaluate(this); + } + break; + case RES_HIDDENPARAFLD: + { + SwHiddenParaField* pHPFld = (SwHiddenParaField*)pFld; + pHPFld->SetHidden( aCalc.Calculate( pHPFld->GetPar1() ).GetBool()); + } + break; + case RES_DBSETNUMBERFLD: + { + ((SwDBSetNumberField*)pFld)->Evaluate(this); + aCalc.VarChange( sDBNumNm, ((SwDBSetNumberField*)pFld)->GetSetNumber()); + } + break; + case RES_DBNEXTSETFLD: + case RES_DBNUMSETFLD: + UpdateDBNumFlds( *(SwDBNameInfField*)pFld, aCalc ); + break; + case RES_DBFLD: + { + // Feld Evaluieren + ((SwDBField*)pFld)->Evaluate(); + +#ifdef REPLACE_OFADBMGR + String sDBName(((SwDBField*)pFld)->GetDBName()); + String sSourceName(sDBName.GetToken(0, DB_DELIM)); + String sTableName(sDBName.GetToken(0).GetToken(1, DB_DELIM)); + + if( pMgr->OpenDataSource( sSourceName, sTableName )) + aCalc.VarChange( sDBNumNm, pMgr->GetSelectedRecordId(sSourceName, sTableName)); +#else + if(pMgr->OpenDB(DBMGR_STD, ((SwDBField*)pFld)->GetDBName())) + aCalc.VarChange( sDBNumNm, pMgr->GetCurSelectedRecordId(DBMGR_STD) ); +#endif + + const String& rName = pFld->GetTyp()->GetName(); + + // Wert fuer den Calculator setzen +//JP 10.02.96: GetValue macht hier doch keinen Sinn +// ((SwDBField*)pFld)->GetValue(); + +//!OK aCalc.VarChange(aName, ((SwDBField*)pFld)->GetValue(aCalc)); + + // Eintrag in den HashTable eintragen + // Eintrag vorhanden ? + USHORT nPos; + SwHash* pFnd = Find( rName, pHashStrTbl, nStrFmtCnt, &nPos ); + if( pFnd ) + // Eintrag in der HashTabelle aendern + ((_HashStr*)pFnd)->aSetStr = pFld->Expand(); + else + // neuen Eintrag einfuegen + *(pHashStrTbl + nPos ) = new _HashStr( rName, + pFld->Expand(), (_HashStr*)*(pHashStrTbl + nPos)); + } + break; + case RES_GETEXPFLD: + case RES_SETEXPFLD: + { + if( GSE_STRING & pFld->GetSubType() ) // String Ersetzung + { + if( RES_GETEXPFLD == nWhich ) + { + SwGetExpField* pGFld = (SwGetExpField*)pFld; + + if( (!pUpdtFld || pUpdtFld == pTxtFld ) + && pGFld->IsInBodyTxt() ) + { + LookString( pHashStrTbl, nStrFmtCnt, + pGFld->GetFormula(), aNew ); + pGFld->ChgExpStr( aNew ); + } + } + else + { + SwSetExpField* pSFld = (SwSetExpField*)pFld; + // ist die "Formel" ein Feld ?? + LookString( pHashStrTbl, nStrFmtCnt, + pSFld->GetFormula(), aNew ); + + if( !aNew.Len() ) // nichts gefunden, dann ist die + aNew = pSFld->GetFormula(); // Formel der neue Wert + + // nur ein spezielles FeldUpdaten ? + if( !pUpdtFld || pUpdtFld == pTxtFld ) + pSFld->ChgExpStr( aNew ); + + // suche den Namen vom Feld + aNew = ((SwSetExpFieldType*)pSFld->GetTyp())->GetSetRefName(); + // Eintrag vorhanden ? + USHORT nPos; + SwHash* pFnd = Find( aNew, pHashStrTbl, nStrFmtCnt, &nPos ); + if( pFnd ) + // Eintrag in der HashTabelle aendern + ((_HashStr*)pFnd)->aSetStr = pSFld->GetExpStr(); + else + // neuen Eintrag einfuegen + *(pHashStrTbl + nPos ) = pFnd = new _HashStr( aNew, + pSFld->GetExpStr(), + (_HashStr*)*(pHashStrTbl + nPos) ); + + // Erweiterung fuers Rechnen mit Strings + SwSbxValue aValue; + aValue.PutString( ((_HashStr*)pFnd)->aSetStr ); + aCalc.VarChange( aNew, aValue ); + } + } + else // Formel neu berechnen + { + if( RES_GETEXPFLD == nWhich ) + { + SwGetExpField* pGFld = (SwGetExpField*)pFld; + + if( (!pUpdtFld || pUpdtFld == pTxtFld ) + && pGFld->IsInBodyTxt() ) + { + pGFld->SetValue(aCalc.Calculate( + pGFld->GetFormula() ).GetDouble() ); + } + } + else + { + SwSetExpField* pSFld = (SwSetExpField*)pFld; + SwSetExpFieldType* pSFldTyp = (SwSetExpFieldType*)pFld->GetTyp(); + aNew = pSFldTyp->GetName(); + + SwNode* pSeqNd = 0; + + if( pSFld->IsSequenceFld() ) + { + BYTE nLvl = pSFldTyp->GetOutlineLvl(); + if( MAXLEVEL > nLvl ) + { + // dann teste, ob die Nummer neu aufsetzen muss + pSeqNd = GetNodes()[ (*ppSortLst)->GetNode() ]; + + const SwTxtNode* pOutlNd = pSeqNd-> + FindOutlineNodeOfLevel( nLvl ); + if( pSFldTyp->GetOutlineChgNd() != pOutlNd ) + { + pSFldTyp->SetOutlineChgNd( pOutlNd ); + aCalc.VarChange( aNew, 0 ); + } + } + } + + aNew += '='; + aNew += pSFld->GetFormula(); + + double nErg = aCalc.Calculate( aNew ).GetDouble(); + // nur ein spezielles Feld updaten ? + if( !pUpdtFld || pUpdtFld == pTxtFld ) + { + pSFld->SetValue( nErg ); + + if( pSeqNd ) + pSFldTyp->SetChapter( *pSFld, *pSeqNd ); + } + } + } + } + } // switch + + pFmtFld->Modify( 0, 0 ); // Formatierung anstossen + + if( pUpdtFld == pTxtFld ) // sollte nur dieses geupdatet werden + { + if( RES_GETEXPFLD == nWhich || // nur GetFeld oder + RES_HIDDENTXTFLD == nWhich || // HiddenTxt? + RES_HIDDENPARAFLD == nWhich) // HiddenParaFld? + break; // beenden + pUpdtFld = 0; // ab jetzt alle Updaten + } + } + +#ifdef REPLACE_OFADBMGR + pMgr->CloseAll(FALSE); +#else + pMgr->SetAllDirty(DBMGR_STD, FALSE); +#endif + // HashTabelle wieder loeschen + ::DeleteHashTable( pHashStrTbl, nStrFmtCnt ); + + // Referenzfelder updaten + if( bUpdRefFlds ) + UpdateRefFlds(); + + pUpdtFlds->SetInUpdateFlds( bOldInUpdateFlds ); + pUpdtFlds->SetFieldsDirty( FALSE ); +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +void SwDoc::UpdateDBNumFlds( SwDBNameInfField& rDBFld, SwCalc& rCalc ) +{ + SwNewDBMgr* pMgr = GetNewDBMgr(); + + USHORT nFldType = rDBFld.Which(); + + BOOL bPar1 = rCalc.Calculate( rDBFld.GetPar1() ).GetBool(); + + if( RES_DBNEXTSETFLD == nFldType ) + ((SwDBNextSetField&)rDBFld).SetCondValid( bPar1 ); + else + ((SwDBNumSetField&)rDBFld).SetCondValid( bPar1 ); + + if( rDBFld.GetRealDBName().Len() ) + { + // Eine bestimmte Datenbank bearbeiten + if( RES_DBNEXTSETFLD == nFldType ) + ((SwDBNextSetField&)rDBFld).Evaluate(this); + else + ((SwDBNumSetField&)rDBFld).Evaluate(this); + + String sDBName( rDBFld.GetDBName(this) ); + +#ifdef REPLACE_OFADBMGR + String sSourceName(sDBName.GetToken(0, DB_DELIM)); + String sTableName(sDBName.GetToken(0).GetToken(1, DB_DELIM)); + + if( pMgr->OpenDataSource( sSourceName, sTableName )) + rCalc.VarChange( lcl_GetDBVarName( *this, rDBFld), + pMgr->GetSelectedRecordId(sSourceName, sTableName) ); +#else + if( pMgr->OpenDB( DBMGR_STD, sDBName )) + rCalc.VarChange( lcl_GetDBVarName( *this, rDBFld), + pMgr->GetCurSelectedRecordId( DBMGR_STD ) ); +#endif + } + else + { +#ifdef REPLACE_OFADBMGR + DBG_ERROR("TODO: what should happen with unnamed DBFields?") +#else + // Alle Datenbanken bearbeiten + OfaDBParam* pParam = pMgr->GetFirstDBData(DBMGR_STD); +// why that? - the name must be empty +// String sOldFldName( rDBFld.GetRealDBName() ); + + while (pParam) + { + if (pParam->HasConnection()) + { + rDBFld.SetDBName( pParam->GetSymDBName() ); + + if( RES_DBNEXTSETFLD == nFldType ) + ((SwDBNextSetField&)rDBFld).Evaluate(this); + else + ((SwDBNumSetField&)rDBFld).Evaluate(this); + + rCalc.VarChange( lcl_GetDBVarName( *this, rDBFld ), + pMgr->GetCurSelectedRecordId( DBMGR_STD ) ); + } + pParam = pMgr->GetNextDBData(); + } + rDBFld.SetDBName(aEmptyStr); +#endif + } +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +void SwDoc::_InitFieldTypes() // wird vom CTOR gerufen!! +{ + // Feldtypen + USHORT nFldType = 0; + pFldTypes->Insert( new SwDateTimeFieldType(this), nFldType++ ); + pFldTypes->Insert( new SwChapterFieldType, nFldType++ ); + pFldTypes->Insert( new SwPageNumberFieldType, nFldType++ ); + pFldTypes->Insert( new SwAuthorFieldType(this),nFldType++ ); + pFldTypes->Insert( new SwFileNameFieldType(this), nFldType++ ); + pFldTypes->Insert( new SwDBNameFieldType(this), nFldType++); + pFldTypes->Insert( new SwGetExpFieldType(this), nFldType++ ); + pFldTypes->Insert( new SwGetRefFieldType( this ), nFldType++ ); + pFldTypes->Insert( new SwHiddenTxtFieldType, nFldType++ ); + pFldTypes->Insert( new SwPostItFieldType, nFldType++ ); + pFldTypes->Insert( new SwDocStatFieldType(this), nFldType++); + pFldTypes->Insert( new SwDocInfoFieldType(this), nFldType++); + pFldTypes->Insert( new SwInputFieldType( this ), nFldType++ ); + pFldTypes->Insert( new SwTblFieldType( this ), nFldType++); + pFldTypes->Insert( new SwMacroFieldType(this), nFldType++ ); + pFldTypes->Insert( new SwHiddenParaFieldType, nFldType++ ); + pFldTypes->Insert( new SwDBNextSetFieldType, nFldType++ ); + pFldTypes->Insert( new SwDBNumSetFieldType, nFldType++ ); + pFldTypes->Insert( new SwDBSetNumberFieldType, nFldType++ ); + pFldTypes->Insert( new SwTemplNameFieldType(this), nFldType++); + pFldTypes->Insert( new SwTemplNameFieldType(this),nFldType++); + pFldTypes->Insert( new SwExtUserFieldType, nFldType++ ); + pFldTypes->Insert( new SwRefPageSetFieldType, nFldType++ ); + pFldTypes->Insert( new SwRefPageGetFieldType( this ), nFldType++ ); + pFldTypes->Insert( new SwJumpEditFieldType( this ), nFldType++ ); + pFldTypes->Insert( new SwScriptFieldType( this ), nFldType++ ); + + // Types muessen am Ende stehen !! + // Im InsertFldType wird davon ausgegangen !!!! + // MIB 14.04.95: Im Sw3StringPool::Setup (sw3imp.cxx) und + // lcl_sw3io_InSetExpField (sw3field.cxx) jetzt auch + pFldTypes->Insert( new SwSetExpFieldType(this, + SW_RESSTR(STR_POOLCOLL_LABEL_ABB), GSE_SEQ), nFldType++); + pFldTypes->Insert( new SwSetExpFieldType(this, + SW_RESSTR(STR_POOLCOLL_LABEL_TABLE), GSE_SEQ),nFldType++); + pFldTypes->Insert( new SwSetExpFieldType(this, + SW_RESSTR(STR_POOLCOLL_LABEL_FRAME), GSE_SEQ),nFldType++); + pFldTypes->Insert( new SwSetExpFieldType(this, + SW_RESSTR(STR_POOLCOLL_LABEL_DRAWING), GSE_SEQ),nFldType++); + + ASSERT( nFldType == INIT_FLDTYPES, "Bad initsize: SwFldTypes" ); +} + +void SwDoc::InsDelFldInFldLst( BOOL bIns, const SwTxtFld& rFld ) +{ + if( !bNewFldLst || !IsInDtor() ) + pUpdtFlds->InsDelFldInFldLst( bIns, rFld ); +} + +String SwDoc::GetDBName() +{ +#ifdef REPLACE_OFADBMGR + return GetDBDesc(); +#else + return GetNewDBMgr()->ExtractDBName( GetDBDesc() ); +#endif +} + +const String& SwDoc::GetDBDesc() +{ + if (!aDBName.Len()) + aDBName = GetNewDBMgr()->GetAddressDBName(); + return aDBName; +} + +void SwDoc::SetInitDBFields( BOOL b ) +{ + GetNewDBMgr()->SetInitDBFields( b ); +} + +/*-------------------------------------------------------------------- + Beschreibung: Alle von Feldern verwendete Datenbanken herausfinden + --------------------------------------------------------------------*/ + +void SwDoc::GetAllUsedDB( SvStringsDtor& rDBNameList, + const SvStringsDtor* pAllDBNames ) +{ + USHORT n; + SvStringsDtor aUsedDBNames; + SvStringsDtor aAllDBNames; + + if( !pAllDBNames ) + { + GetAllDBNames( aAllDBNames ); + pAllDBNames = &aAllDBNames; + } + + SwSectionFmts& rArr = GetSections(); + for( n = rArr.Count(); n; ) + { + SwSection* pSect = rArr[ --n ]->GetSection(); + + if( pSect ) + { + String aCond( pSect->GetCondition() ); + AddUsedDBToList( rDBNameList, FindUsedDBs( *pAllDBNames, + aCond, aUsedDBNames ) ); + aUsedDBNames.DeleteAndDestroy( 0, aUsedDBNames.Count() ); + } + } + + const SfxPoolItem* pItem; + USHORT nMaxItems = GetAttrPool().GetItemCount( RES_TXTATR_FIELD ); + for( n = 0; n < nMaxItems; ++n ) + { + if( 0 == (pItem = GetAttrPool().GetItem( RES_TXTATR_FIELD, n ) )) + continue; + + const SwFmtFld* pFmtFld = (SwFmtFld*)pItem; + const SwTxtFld* pTxtFld = pFmtFld->GetTxtFld(); + if( !pTxtFld || !pTxtFld->GetTxtNode().GetNodes().IsDocNodes() ) + continue; + + const SwField* pFld = pFmtFld->GetFld(); + switch( pFld->GetTyp()->Which() ) + { + case RES_DBFLD: + AddUsedDBToList( rDBNameList, + ((SwDBField*)pFld)->GetDBName() ); + break; + + case RES_DBSETNUMBERFLD: + case RES_DBNAMEFLD: + AddUsedDBToList( rDBNameList, + ((SwDBNameInfField*)pFld)->GetRealDBName() ); + break; + + case RES_DBNUMSETFLD: + case RES_DBNEXTSETFLD: + AddUsedDBToList( rDBNameList, + ((SwDBNameInfField*)pFld)->GetRealDBName() ); + // kein break // JP: ist das so richtig ?? + + case RES_HIDDENTXTFLD: + case RES_HIDDENPARAFLD: + AddUsedDBToList(rDBNameList, FindUsedDBs( *pAllDBNames, + pFld->GetPar1(), aUsedDBNames )); + aUsedDBNames.DeleteAndDestroy( 0, aUsedDBNames.Count() ); + break; + + case RES_SETEXPFLD: + case RES_GETEXPFLD: + case RES_TABLEFLD: + AddUsedDBToList(rDBNameList, FindUsedDBs( *pAllDBNames, + pFld->GetFormula(), aUsedDBNames )); + aUsedDBNames.DeleteAndDestroy( 0, aUsedDBNames.Count() ); + break; + } + } +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +void SwDoc::GetAllDBNames( SvStringsDtor& rAllDBNames ) +{ + SwNewDBMgr* pMgr = GetNewDBMgr(); + +#ifdef REPLACE_OFADBMGR + const SwDSParamArr& rArr = pMgr->GetDSParamArray(); + for(USHORT i = 0; i < rArr.Count(); i++) + { + SwDSParam* pParam = rArr[i]; + String* pStr = new String( pParam->sDataSource ); + (*pStr) += DB_DELIM; + (*pStr) += pParam->sTableOrQuery; + rAllDBNames.Insert( pStr, rAllDBNames.Count() ); + } +#else + OfaDBParam* pParam = pMgr->GetFirstDBData(DBMGR_STD); + + while( pParam ) + { + if( pParam->GetSymDBName().Len() ) + { + String* pStr = new String( pParam->GetSymDBName() ); +#ifndef UNX + GetAppCharClass().toUpper( *pStr ); +#endif + rAllDBNames.Insert( pStr, rAllDBNames.Count() ); + } + pParam = pMgr->GetNextDBData(); + } +#endif +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +SvStringsDtor& SwDoc::FindUsedDBs( const SvStringsDtor& rAllDBNames, + const String& rFormel, + SvStringsDtor& rUsedDBNames ) +{ + const CharClass& rCC = GetAppCharClass(); + String sFormel( rFormel); +#ifndef UNX + rCC.toUpper( sFormel ); +#endif + + xub_StrLen nPos; + for (USHORT i = 0; i < rAllDBNames.Count(); ++i ) + { + const String* pStr = rAllDBNames.GetObject(i); + + if( STRING_NOTFOUND != (nPos = sFormel.Search( *pStr )) && + sFormel.GetChar( nPos + pStr->Len() ) == '.' && + (!nPos || !rCC.isLetterNumeric( sFormel, nPos - 1 ))) + { + // Tabellenname suchen + xub_StrLen nEndPos; + nPos += pStr->Len() + 1; + if( STRING_NOTFOUND != (nEndPos = sFormel.Search('.', nPos)) ) + { + String* pDBNm = new String( *pStr ); + pDBNm->Append( DB_DELIM ); + pDBNm->Append( sFormel.Copy( nPos, nEndPos - nPos )); + rUsedDBNames.Insert( pDBNm, rUsedDBNames.Count() ); + } + } + } + return rUsedDBNames; +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +void SwDoc::AddUsedDBToList( SvStringsDtor& rDBNameList, + const SvStringsDtor& rUsedDBNames ) +{ + for (USHORT i = 0; i < rUsedDBNames.Count(); i++) + AddUsedDBToList( rDBNameList, *rUsedDBNames.GetObject(i) ); +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +void SwDoc::AddUsedDBToList( SvStringsDtor& rDBNameList, const String& rDBName) +{ + if( !rDBName.Len() ) + return; + + const CharClass& rCC = GetAppCharClass(); + String sLowerDBName( DBNAME_LOWER( rDBName )); + +#ifdef REPLACE_OFADBMGR + for (USHORT i = 0; i < rDBNameList.Count(); i++) + if( sLowerDBName.Equals( DBNAME_LOWER( + rDBNameList.GetObject(i)->GetToken(0) ))) + return; + + const SwDSParam* pParam = GetNewDBMgr()->CreateDSData(rDBName); + String* pNew = new String( rDBName ); + rDBNameList.Insert( pNew, rDBNameList.Count() ); +#else + for (USHORT i = 0; i < rDBNameList.Count(); i++) + if( sLowerDBName.Equals( DBNAME_LOWER( + GetNewDBMgr()->ExtractDBName( *rDBNameList.GetObject(i) ) ))) + return; + OfaDBParam& rParam = GetNewDBMgr()->GetDBData( DBMGR_STD, &rDBName ); + String* pNew = new String( rParam.GetDBName() ); + if( !pNew->Len() ) + *pNew = rParam.GetSymDBName(); + rDBNameList.Insert( pNew, rDBNameList.Count() ); +#endif +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +BOOL SwDoc::RenameUserFields( const String& rOldName, const String& rNewName ) +{ + USHORT n; + BOOL bRet = FALSE; + String sFormel; + + SwSectionFmts& rArr = GetSections(); + for( n = rArr.Count(); n; ) + { + SwSection* pSect = rArr[ --n ]->GetSection(); + + if( pSect ) + { + sFormel = pSect->GetCondition(); + RenameUserFld( rOldName, rNewName, sFormel ); + pSect->SetCondition( sFormel ); + } + } + + const SfxPoolItem* pItem; + USHORT nMaxItems = GetAttrPool().GetItemCount( RES_TXTATR_FIELD ); + const CharClass& rCC = GetAppCharClass(); + String sLowerOldName( rCC.lower( rOldName )); + + for( n = 0; n < nMaxItems; ++n ) + { + if( 0 == (pItem = GetAttrPool().GetItem( RES_TXTATR_FIELD, n ) )) + continue; + + SwFmtFld* pFmtFld = (SwFmtFld*)pItem; + SwTxtFld* pTxtFld = pFmtFld->GetTxtFld(); + if( !pTxtFld || !pTxtFld->GetTxtNode().GetNodes().IsDocNodes() ) + continue; + + SwField* pFld = pFmtFld->GetFld(); + BOOL bExpand = FALSE; + + switch( pFld->GetTyp()->Which() ) + { + case RES_USERFLD: + if( sLowerOldName.Equals( rCC.lower( pFld->GetTyp()->GetName() ))) + { + SwUserFieldType* pOldTyp = (SwUserFieldType*)pFld->GetTyp(); + + SwUserFieldType* pTyp = (SwUserFieldType*)InsertFldType( + SwUserFieldType(this, rNewName)); + + pTyp->SetContent(pOldTyp->GetContent()); + pTyp->SetType(pOldTyp->GetType()); + pTyp->Add(pFmtFld); // Feld auf neuen Typ umhaengen + pFld->ChgTyp(pTyp); + + bExpand = TRUE; + } + break; + + case RES_DBNUMSETFLD: + case RES_DBNEXTSETFLD: + case RES_HIDDENTXTFLD: + case RES_HIDDENPARAFLD: + sFormel = pFld->GetPar1(); + RenameUserFld( rOldName, rNewName, sFormel ); + pFld->SetPar1( sFormel ); + bExpand = TRUE; + break; + + case RES_SETEXPFLD: + if( sLowerOldName.Equals( rCC.lower( pFld->GetTyp()->GetName() ))) + { + SwSetExpFieldType* pOldTyp = (SwSetExpFieldType*)pFld->GetTyp(); + + SwSetExpFieldType* pTyp = (SwSetExpFieldType*)InsertFldType( + SwSetExpFieldType(this, rNewName, pOldTyp->GetType())); + pTyp->Add( pFmtFld ); // Feld auf neuen Typ umhaengen + pFld->ChgTyp( pTyp ); + + bExpand = TRUE; + } + // Kein break!!! + + case RES_GETEXPFLD: + case RES_TABLEFLD: + sFormel = pFld->GetFormula(); + RenameUserFld( rOldName, rNewName, sFormel ); + pFld->SetPar2( sFormel ); + bExpand = TRUE; + break; + } + + if( bExpand ) + { + pTxtFld->ExpandAlways(); + bRet = TRUE; + } + } + SetModified(); + + return bRet; +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +void SwDoc::RenameUserFld( const String& rOldName, const String& rNewName, + String& rFormel ) +{ + const CharClass& rCC = GetAppCharClass(); + + String sFormel( rCC.upper( rFormel )); + String sOldName( rCC.upper( rOldName )); + xub_StrLen nPos; + + if( !FindOperator( rOldName ) && + !sOldName.Equals( rCC.upper( rNewName ) ) ) + { + nPos = 0; + + while ((nPos = sFormel.Search(sOldName, nPos)) != STRING_NOTFOUND) + { + if(!nPos || !rCC.isLetterNumeric( sFormel, nPos - 1 )) + { + rFormel.Erase( nPos, rOldName.Len() ); + rFormel.Insert( rNewName, nPos ); + sFormel = rCC.upper( rFormel ); + } + } + } +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +void SwDoc::ChangeDBFields( const SvStringsDtor& rOldNames, + const String& rNewName ) +{ + String sFormel; + USHORT n; + + SwSectionFmts& rArr = GetSections(); + for( n = rArr.Count(); n; ) + { + SwSection* pSect = rArr[ --n ]->GetSection(); + + if( pSect ) + { + sFormel = pSect->GetCondition(); + ReplaceUsedDBs( rOldNames, rNewName, sFormel); + pSect->SetCondition(sFormel); + } + } + + const SfxPoolItem* pItem; + USHORT nMaxItems = GetAttrPool().GetItemCount( RES_TXTATR_FIELD ); + + for( n = 0; n < nMaxItems; ++n ) + { + if( 0 == (pItem = GetAttrPool().GetItem( RES_TXTATR_FIELD, n ) )) + continue; + + SwFmtFld* pFmtFld = (SwFmtFld*)pItem; + SwTxtFld* pTxtFld = pFmtFld->GetTxtFld(); + if( !pTxtFld || !pTxtFld->GetTxtNode().GetNodes().IsDocNodes() ) + continue; + + SwField* pFld = pFmtFld->GetFld(); + BOOL bExpand = FALSE; + + switch( pFld->GetTyp()->Which() ) + { + case RES_DBFLD: + if( IsNameInArray( rOldNames, ((SwDBField*)pFld)->GetDBName())) + { + SwDBFieldType* pOldTyp = (SwDBFieldType*)pFld->GetTyp(); + + SwDBFieldType* pTyp = (SwDBFieldType*)InsertFldType( + SwDBFieldType(this, pOldTyp->GetColumnName(), rNewName)); + + pTyp->Add(pFmtFld); // Feld auf neuen Typ umhaengen + pFld->ChgTyp(pTyp); + + ((SwDBField*)pFld)->ClearInitialized(); + ((SwDBField*)pFld)->InitContent(); + + bExpand = TRUE; + } + break; + + case RES_DBSETNUMBERFLD: + case RES_DBNAMEFLD: + if( IsNameInArray( rOldNames, + ((SwDBNameInfField*)pFld)->GetRealDBName())) + { + ((SwDBNameInfField*)pFld)->SetDBName(rNewName); + bExpand = TRUE; + } + break; + + case RES_DBNUMSETFLD: + case RES_DBNEXTSETFLD: + if( IsNameInArray( rOldNames, + ((SwDBNameInfField*)pFld)->GetRealDBName())) + { + ((SwDBNameInfField*)pFld)->SetDBName(rNewName); + bExpand = TRUE; + } + // kein break; + case RES_HIDDENTXTFLD: + case RES_HIDDENPARAFLD: + sFormel = pFld->GetPar1(); + ReplaceUsedDBs( rOldNames, rNewName, sFormel); + pFld->SetPar1( sFormel ); + bExpand = TRUE; + break; + + case RES_SETEXPFLD: + case RES_GETEXPFLD: + case RES_TABLEFLD: + sFormel = pFld->GetFormula(); + ReplaceUsedDBs( rOldNames, rNewName, sFormel); + pFld->SetPar2( sFormel ); + bExpand = TRUE; + break; + } + + if (bExpand) + pTxtFld->ExpandAlways(); + } + SetModified(); +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +void SwDoc::ReplaceUsedDBs( const SvStringsDtor& rUsedDBNames, + const String& rNewName, String& rFormel ) +{ + const CharClass& rCC = GetAppCharClass(); + String sFormel(rFormel); + String sNewName( rNewName ); + sNewName.SearchAndReplace( DB_DELIM, '.'); + String sUpperNewNm( sNewName ); +#ifdef REPLACE_OFADBMGR +#else +#ifndef UNX + rCC.toUpper( sFormel ); + rCC.toUpper( sUpperNewNm ); +#endif +#endif + + + for( USHORT i = 0; i < rUsedDBNames.Count(); ++i ) + { + String sDBName( *rUsedDBNames.GetObject( i ) ); + +#ifdef REPLACE_OFADBMGR +#else +#ifndef UNX + rCC.toUpper( sDBName ); +#endif +#endif + + sDBName.SearchAndReplace( DB_DELIM, '.'); + if( sDBName.Equals( sUpperNewNm )) + { + xub_StrLen nPos = 0; + + while ((nPos = sFormel.Search(sDBName, nPos)) != STRING_NOTFOUND) + { + if( sFormel.GetChar( nPos + sDBName.Len() ) == '.' && + (!nPos || !rCC.isLetterNumeric( sFormel, nPos - 1 ))) + { + rFormel.Erase( nPos, sDBName.Len() ); + rFormel.Insert( sNewName, nPos ); + sFormel = rFormel; +#ifdef REPLACE_OFADBMGR +#else +#ifndef UNX + rCC.toUpper( sFormel ); +#endif +#endif + } + } + } + } +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +BOOL SwDoc::IsNameInArray( const SvStringsDtor& rArr, const String& rName ) +{ + const CharClass& rCC = GetAppCharClass(); + String sLowerName( DBNAME_LOWER( rName )); + for( USHORT i = 0; i < rArr.Count(); ++i ) + if( sLowerName.Equals( DBNAME_LOWER( *rArr[ i ] )) ) + return TRUE; + return FALSE; +} + +void SwDoc::SetFixFields( BOOL bOnlyTimeDate, const DateTime* pNewDateTime ) +{ + BOOL bIsModified = IsModified(); + + ULONG nDate, nTime; + if( pNewDateTime ) + { + nDate = pNewDateTime->GetDate(); + nTime = pNewDateTime->GetTime(); + } + else + { + nDate = Date().GetDate(); + nTime = Time().GetTime(); + } + + USHORT aTypes[5] = { + /*0*/ RES_DOCINFOFLD, + /*1*/ RES_AUTHORFLD, + /*2*/ RES_EXTUSERFLD, + /*3*/ RES_FILENAMEFLD, + /*4*/ RES_DATETIMEFLD }; // MUSS am Ende stehen!! + + USHORT nStt = bOnlyTimeDate ? 4 : 0; + + for( ; nStt < 5; ++nStt ) + { + SwFieldType* pFldType = GetSysFldType( aTypes[ nStt ] ); + SwClientIter aDocInfIter( *pFldType ); + + for( SwFmtFld* pFld = (SwFmtFld*)aDocInfIter.First( TYPE( SwFmtFld )); + pFld; pFld = (SwFmtFld*)aDocInfIter.Next() ) + { + if( pFld && pFld->GetTxtFld() ) + { + BOOL bChgd = FALSE; + switch( aTypes[ nStt ] ) + { + case RES_DOCINFOFLD: + if( ((SwDocInfoField*)pFld->GetFld())->IsFixed() ) + { + bChgd = TRUE; + SwDocInfoField* pDocInfFld = (SwDocInfoField*)pFld->GetFld(); + pDocInfFld->SetExpansion( ((SwDocInfoFieldType*) + pDocInfFld->GetTyp())->Expand( + pDocInfFld->GetSubType(), + pDocInfFld->GetFormat(), + pDocInfFld->GetLanguage() ) ); + } + break; + + case RES_AUTHORFLD: + if( ((SwAuthorField*)pFld->GetFld())->IsFixed() ) + { + bChgd = TRUE; + SwAuthorField* pAuthorFld = (SwAuthorField*)pFld->GetFld(); + pAuthorFld->SetExpansion( ((SwAuthorFieldType*) + pAuthorFld->GetTyp())->Expand( + pAuthorFld->GetFormat() ) ); + } + break; + + case RES_EXTUSERFLD: + if( ((SwExtUserField*)pFld->GetFld())->IsFixed() ) + { + bChgd = TRUE; + SwExtUserField* pExtUserFld = (SwExtUserField*)pFld->GetFld(); + pExtUserFld->SetExpansion( ((SwExtUserFieldType*) + pExtUserFld->GetTyp())->Expand( + pExtUserFld->GetSubType(), + pExtUserFld->GetFormat())); + } + break; + + case RES_DATETIMEFLD: + if( ((SwDateTimeField*)pFld->GetFld())->IsFixed() ) + { + bChgd = TRUE; + ((SwDateTimeField*)pFld->GetFld())->SetDateTime( + nDate, nTime ); + } + break; + + case RES_FILENAMEFLD: + if( ((SwFileNameField*)pFld->GetFld())->IsFixed() ) + { + bChgd = TRUE; + SwFileNameField* pFileNameFld = + (SwFileNameField*)pFld->GetFld(); + pFileNameFld->SetExpansion( ((SwFileNameFieldType*) + pFileNameFld->GetTyp())->Expand( + pFileNameFld->GetFormat() ) ); + } + break; + } + + // Formatierung anstossen + if( bChgd ) + pFld->Modify( 0, 0 ); + } + } + } + + if( !bIsModified ) + ResetModified(); +} + +BOOL SwDoc::SetFieldsDirty( BOOL b, const SwNode* pChk, ULONG nLen ) +{ + // teste ggfs. mal, ob die angegbenen Nodes ueberhaupt Felder beinhalten. + // wenn nicht, braucht das Flag nicht veraendert werden. + BOOL bFldsFnd = FALSE; + if( b && pChk && !GetUpdtFlds().IsFieldsDirty() && !IsInDtor() + // ?? was ist mit Undo, da will man es doch auch haben !! + /*&& &pChk->GetNodes() == &GetNodes()*/ ) + { + b = FALSE; + if( !nLen ) + ++nLen; + ULONG nStt = pChk->GetIndex(); + const SwNodes& rNds = pChk->GetNodes(); + while( nLen-- ) + { + const SwTxtNode* pTNd = rNds[ nStt++ ]->GetTxtNode(); + if( pTNd ) + { + if( pTNd->GetFmtColl() && + MAXLEVEL > pTNd->GetTxtColl()->GetOutlineLevel() ) + // Kapitelfelder aktualisieren + b = TRUE; + else if( pTNd->GetpSwpHints() && pTNd->GetSwpHints().Count() ) + for( USHORT n = 0, nEnd = pTNd->GetSwpHints().Count(); + n < nEnd; ++n ) + { + const SwTxtAttr* pAttr = pTNd->GetSwpHints()[ n ]; + if( RES_TXTATR_FIELD == pAttr->Which() ) + { + b = TRUE; + break; + } + } + + if( b ) + break; + } + } + bFldsFnd = b; + } + GetUpdtFlds().SetFieldsDirty( b ); + return bFldsFnd; +} +/* -----------------------------21.12.99 12:55-------------------------------- + + ---------------------------------------------------------------------------*/ +void SwDoc::ChangeAuthorityData( const SwAuthEntry* pNewData ) +{ + const USHORT nSize = pFldTypes->Count(); + + for( USHORT i = INIT_FLDTYPES; i < nSize; ++i ) + { + SwFieldType* pFldType = (*pFldTypes)[i]; + if( RES_AUTHORITY == pFldType->Which() ) + { + SwAuthorityFieldType* pAuthType = (SwAuthorityFieldType*)pFldType; + pAuthType->ChangeEntryContent(pNewData); + break; + } + } + +} +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +void SwDocUpdtFld::InsDelFldInFldLst( BOOL bIns, const SwTxtFld& rFld ) +{ + USHORT nWhich = rFld.GetFld().GetFld()->GetTyp()->Which(); + switch( nWhich ) + { + case RES_DBFLD: + case RES_SETEXPFLD: + case RES_HIDDENPARAFLD: + case RES_HIDDENTXTFLD: + case RES_DBNUMSETFLD: + case RES_DBNEXTSETFLD: + case RES_DBSETNUMBERFLD: + case RES_GETEXPFLD: + break; // diese muessen ein-/ausgetragen werden! + + default: + return; + } + + SetFieldsDirty( TRUE ); + if( !pFldSortLst ) + { + if( !bIns ) // keine Liste vorhanden und loeschen + return; // dann nichts tun + pFldSortLst = new _SetGetExpFlds( 64, 16 ); + } + + if( bIns ) // neu einfuegen: + GetBodyNode( rFld, nWhich ); + else + { + // ueber den pTxtFld Pointer suchen. Ist zwar eine Sortierte + // Liste, aber nach Node-Positionen sortiert. Bis dieser + // bestimmt ist, ist das Suchen nach dem Pointer schon fertig + for( USHORT n = 0; n < pFldSortLst->Count(); ++n ) + if( &rFld == (*pFldSortLst)[ n ]->GetPointer() ) + pFldSortLst->DeleteAndDestroy( n--, 1 ); + // ein Feld kann mehrfach vorhanden sein! + } +} + +void SwDocUpdtFld::_MakeFldList( SwDoc& rDoc, int eGetMode ) +{ + // neue Version: gehe ueber alle Felder vom Attribut-Pool + if( pFldSortLst ) + delete pFldSortLst; + pFldSortLst = new _SetGetExpFlds( 64, 16 ); + + // zuerst die Bereiche einsammeln. Alle die ueber Bedingung + // gehiddet sind, wieder mit Frames versorgen, damit die darin + // enthaltenen Felder richtig einsortiert werden!!! + { + // damit die Frames richtig angelegt werden, muessen sie in der + // Reihenfolgen von oben nach unten expandiert werden + SvULongs aTmpArr; + SwSectionFmts& rArr = rDoc.GetSections(); + SwSectionNode* pSectNd; + USHORT nArrStt = 0; + ULONG nSttCntnt = rDoc.GetNodes().GetEndOfExtras().GetIndex(); + for( USHORT n = rArr.Count(); n; ) + { + SwSection* pSect = rArr[ --n ]->GetSection(); + if( pSect->IsHidden() && pSect->GetCondition().Len() && + 0 != ( pSectNd = pSect->GetFmt()->GetSectionNode() )) + { + ULONG nIdx = pSectNd->GetIndex(); + for( USHORT i = 0; + i < aTmpArr.Count() && aTmpArr[ i ] < nIdx; + ++i ) + ; + aTmpArr.Insert( nIdx, i ); + if( nIdx < nSttCntnt ) + ++nArrStt; + } + } + + // erst alle anzeigen, damit die Frames vorhanden sind. Mit deren + // Position wird das BodyAnchor ermittelt. + // Dafuer erst den ContentBereich, dann die Sonderbereiche!!! + for( n = nArrStt; n < aTmpArr.Count(); ++n ) + { + pSectNd = rDoc.GetNodes()[ aTmpArr[ n ] ]->GetSectionNode(); + ASSERT( pSectNd, "Wo ist mein SectionNode" ); + pSectNd->GetSection().SetCondHidden( FALSE ); + } + for( n = 0; n < nArrStt; ++n ) + { + pSectNd = rDoc.GetNodes()[ aTmpArr[ n ] ]->GetSectionNode(); + ASSERT( pSectNd, "Wo ist mein SectionNode" ); + pSectNd->GetSection().SetCondHidden( FALSE ); + } + + // so, erst jetzt alle sortiert in die Liste eintragen + for( n = 0; n < aTmpArr.Count(); ++n ) + GetBodyNode( *rDoc.GetNodes()[ aTmpArr[ n ] ]->GetSectionNode() ); + } + + String sTrue( String::CreateFromAscii( + RTL_CONSTASCII_STRINGPARAM( "TRUE" ))), + sFalse( String::CreateFromAscii( + RTL_CONSTASCII_STRINGPARAM( "FALSE" ))); + + BOOL bIsDBMgr = 0 != rDoc.GetNewDBMgr(); + USHORT nWhich, n; + const String* pFormel = 0; + const SfxPoolItem* pItem; + USHORT nMaxItems = rDoc.GetAttrPool().GetItemCount( RES_TXTATR_FIELD ); + for( n = 0; n < nMaxItems; ++n ) + { + if( 0 == (pItem = rDoc.GetAttrPool().GetItem( RES_TXTATR_FIELD, n ) )) + continue; + + const SwFmtFld* pFmtFld = (SwFmtFld*)pItem; + const SwTxtFld* pTxtFld = pFmtFld->GetTxtFld(); + if( !pTxtFld || !pTxtFld->GetTxtNode().GetNodes().IsDocNodes() ) + continue; + + const SwField* pFld = pFmtFld->GetFld(); + switch( nWhich = pFld->GetTyp()->Which() ) + { + case RES_DBSETNUMBERFLD: + case RES_GETEXPFLD: + if( GETFLD_ALL == eGetMode ) + pFormel = &sTrue; + break; + + case RES_DBFLD: + if( GETFLD_EXPAND & eGetMode ) + pFormel = &sTrue; + break; + + case RES_SETEXPFLD: + if( ( GSE_STRING & pFld->GetSubType() + ? GETFLD_EXPAND : GETFLD_CALC ) + & eGetMode ) + pFormel = &sTrue; + break; + + case RES_HIDDENPARAFLD: + if( GETFLD_ALL == eGetMode ) + { + pFormel = &pFld->GetPar1(); + if( !pFormel->Len() || pFormel->Equals( sFalse )) + ((SwHiddenParaField*)pFld)->SetHidden( FALSE ); + else if( pFormel->Equals( sTrue )) + ((SwHiddenParaField*)pFld)->SetHidden( TRUE ); + else + break; + + pFormel = 0; + // Formatierung anstossen + ((SwFmtFld*)pFmtFld)->Modify( 0, 0 ); + } + break; + + case RES_HIDDENTXTFLD: + if( GETFLD_ALL == eGetMode ) + { + pFormel = &pFld->GetPar1(); + if( !pFormel->Len() || pFormel->Equals( sFalse )) + ((SwHiddenTxtField*)pFld)->SetValue( TRUE ); + else if( pFormel->Equals( sTrue )) + ((SwHiddenTxtField*)pFld)->SetValue( FALSE ); + else + break; + + pFormel = 0; + + // Feld Evaluieren + ((SwHiddenTxtField*)pFld)->Evaluate(&rDoc); + // Formatierung anstossen + ((SwFmtFld*)pFmtFld)->Modify( 0, 0 ); + } + break; + + case RES_DBNUMSETFLD: + { +#ifdef REPLACE_OFADBMGR + String sDBName(((SwDBNumSetField*)pFld)->GetDBName(&rDoc)); + String sSourceName(sDBName.GetToken(0, DB_DELIM)); + String sTableName(sDBName.GetToken(0).GetToken(1, DB_DELIM)); + + if( bIsDBMgr && + rDoc.GetNewDBMgr()->OpenDataSource( sSourceName, sTableName )&& + GETFLD_ALL == eGetMode || + ( GETFLD_CALC & eGetMode && + ((SwDBNumSetField*)pFld)->IsCondValid())) +#else + if( bIsDBMgr && rDoc.GetNewDBMgr()->OpenDB(DBMGR_STD, + ((SwDBNumSetField*)pFld)->GetDBName(&rDoc)) && + GETFLD_ALL == eGetMode || + ( GETFLD_CALC & eGetMode && + ((SwDBNumSetField*)pFld)->IsCondValid() )) +#endif + pFormel = &pFld->GetPar1(); + } + break; + case RES_DBNEXTSETFLD: + { +#ifdef REPLACE_OFADBMGR + String sDBName(((SwDBNextSetField*)pFld)->GetDBName(&rDoc)); + String sSourceName(sDBName.GetToken(0, DB_DELIM)); + String sTableName(sDBName.GetToken(0).GetToken(1, DB_DELIM)); + + if( bIsDBMgr && + rDoc.GetNewDBMgr()->OpenDataSource( sSourceName, sTableName )&& + GETFLD_ALL == eGetMode || + ( GETFLD_CALC & eGetMode && + ((SwDBNextSetField*)pFld)->IsCondValid() )) +#else + if( bIsDBMgr && rDoc.GetNewDBMgr()->OpenDB(DBMGR_STD, + ((SwDBNextSetField*)pFld)->GetDBName(&rDoc)) && + GETFLD_ALL == eGetMode || + ( GETFLD_CALC & eGetMode && + ((SwDBNextSetField*)pFld)->IsCondValid() )) +#endif + pFormel = &pFld->GetPar1(); + } + break; + } + + if( pFormel && pFormel->Len() ) + { + GetBodyNode( *pTxtFld, nWhich ); + pFormel = 0; + } + } + nFldLstGetMode = eGetMode; + nNodes = rDoc.GetNodes().Count(); + +#ifdef JP_DEBUG + { + SvFileStream sOut( "f:\\x.x", STREAM_STD_WRITE ); + sOut.Seek( STREAM_SEEK_TO_END ); + sOut << "------------------" << endl; + const _SetGetExpFldPtr* pSortLst = pFldSortLst->GetData(); + for( USHORT n = pFldSortLst->Count(); n; --n, ++pSortLst ) + { + String sStr( (*pSortLst)->GetNode() ); + sStr += "\t, "; + sStr += (*pSortLst)->GetCntnt(); + sStr += "\tNode: "; + sStr += (*pSortLst)->GetFld()->GetTxtNode().StartOfSectionIndex(); + sStr += "\tPos: "; + sStr += *(*pSortLst)->GetFld()->GetStart(); + sStr += "\tType: "; + sStr += (*pSortLst)->GetFld()->GetFld().GetFld()->GetTyp()->Which(); + + sOut << sStr.GetStr() << endl; + } + } +#endif + // JP_DEBUG +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +void SwDocUpdtFld::GetBodyNode( const SwTxtFld& rTFld, USHORT nFldWhich ) +{ + const SwTxtNode& rTxtNd = rTFld.GetTxtNode(); + const SwDoc& rDoc = *rTxtNd.GetDoc(); + + // immer den ersten !! (in Tab-Headline, Kopf-/Fuss ) + Point aPt; + const SwCntntFrm* pFrm = rTxtNd.GetFrm( &aPt, 0, FALSE ); + + _SetGetExpFld* pNew; + BOOL bIsInBody = FALSE; + + if( !pFrm || pFrm->IsInDocBody() ) + { + // einen Index fuers bestimmen vom TextNode anlegen + SwNodeIndex aIdx( rTxtNd ); + bIsInBody = rDoc.GetNodes().GetEndOfExtras().GetIndex() < aIdx.GetIndex(); + pNew = new _SetGetExpFld( aIdx, &rTFld ); + } + else + { + // einen Index fuers bestimmen vom TextNode anlegen + SwPosition aPos( rDoc.GetNodes().GetEndOfPostIts() ); +#ifndef PRODUCT + ASSERT( GetBodyTxtNode( rDoc, aPos, *pFrm ), "wo steht das Feld" ); +#else + GetBodyTxtNode( rDoc, aPos, *pFrm ); +#endif + pNew = new _SetGetExpFld( aPos.nNode, &rTFld, &aPos.nContent ); + } + + // bei GetExp.-/DB.-Felder immer das BodyTxtFlag setzen + if( RES_GETEXPFLD == nFldWhich ) + { + SwGetExpField* pGetFld = (SwGetExpField*)rTFld.GetFld().GetFld(); + pGetFld->ChgBodyTxtFlag( bIsInBody ); + } + else if( RES_DBFLD == nFldWhich ) + { + SwDBField* pDBFld = (SwDBField*)rTFld.GetFld().GetFld(); + pDBFld->ChgBodyTxtFlag( bIsInBody ); + } + + if( !pFldSortLst->Insert( pNew )) + delete pNew; +} + +void SwDocUpdtFld::GetBodyNode( const SwSectionNode& rSectNd ) +{ + const SwDoc& rDoc = *rSectNd.GetDoc(); + _SetGetExpFld* pNew = 0; + + if( rSectNd.GetIndex() < rDoc.GetNodes().GetEndOfExtras().GetIndex() ) + { + do { // middle check loop + + // dann muessen wir uns mal den Anker besorgen! + // einen Index fuers bestimmen vom TextNode anlegen + SwPosition aPos( rSectNd ); + SwCntntNode* pCNd = rDoc.GetNodes().GoNext( &aPos.nNode ); // zum naechsten ContentNode + + if( !pCNd || !pCNd->IsTxtNode() ) + break; + + // immer den ersten !! (in Tab-Headline, Kopf-/Fuss ) + Point aPt; + const SwCntntFrm* pFrm = pCNd->GetFrm( &aPt, 0, FALSE ); + if( !pFrm ) + break; + +#ifndef PRODUCT + ASSERT( GetBodyTxtNode( rDoc, aPos, *pFrm ), "wo steht das Feld" ); +#else + GetBodyTxtNode( rDoc, aPos, *pFrm ); +#endif + pNew = new _SetGetExpFld( rSectNd, &aPos ); + + } while( FALSE ); + } + + if( !pNew ) + pNew = new _SetGetExpFld( rSectNd ); + + if( !pFldSortLst->Insert( pNew )) + delete pNew; +} + +void SwDocUpdtFld::InsertFldType( const SwFieldType& rType ) +{ + String sFldName; + switch( rType.Which() ) + { + case RES_USERFLD : + sFldName = ((SwUserFieldType&)rType).GetName(); + break; + case RES_SETEXPFLD: + sFldName = ((SwSetExpFieldType&)rType).GetName(); + break; + default: + ASSERT( !this, "kein gueltiger FeldTyp" ); + } + + if( sFldName.Len() ) + { + SetFieldsDirty( TRUE ); + // suchen und aus der HashTabelle entfernen + GetAppCharClass().toLower( sFldName ); + USHORT n; + + SwHash* pFnd = Find( sFldName, GetFldTypeTable(), TBLSZ, &n ); + + if( !pFnd ) + { + SwCalcFldType* pNew = new SwCalcFldType( sFldName, &rType ); + pNew->pNext = aFldTypeTable[ n ]; + aFldTypeTable[ n ] = pNew; + } + } +} + +void SwDocUpdtFld::RemoveFldType( const SwFieldType& rType ) +{ + String sFldName; + switch( rType.Which() ) + { + case RES_USERFLD : + sFldName = ((SwUserFieldType&)rType).GetName(); + break; + case RES_SETEXPFLD: + sFldName = ((SwSetExpFieldType&)rType).GetName(); + break; + } + + if( sFldName.Len() ) + { + SetFieldsDirty( TRUE ); + // suchen und aus der HashTabelle entfernen + GetAppCharClass().toLower( sFldName ); + USHORT n; + + SwHash* pFnd = Find( sFldName, GetFldTypeTable(), TBLSZ, &n ); + if( pFnd ) + { + if( aFldTypeTable[ n ] == pFnd ) + aFldTypeTable[ n ] = (SwCalcFldType*)pFnd->pNext; + else + { + SwHash* pPrev = aFldTypeTable[ n ]; + while( pPrev->pNext != pFnd ) + pPrev = pPrev->pNext; + pPrev->pNext = pFnd->pNext; + } + pFnd->pNext = 0; + delete pFnd; + } + } +} + +SwDocUpdtFld::SwDocUpdtFld() + : pFldSortLst( 0 ), nFldLstGetMode( 0 ), nFldUpdtPos( LONG_MAX ) +{ + bInUpdateFlds = bFldsDirty = FALSE; + memset( aFldTypeTable, 0, sizeof( aFldTypeTable ) ); +} + +SwDocUpdtFld::~SwDocUpdtFld() +{ + delete pFldSortLst; + + for( USHORT n = 0; n < TBLSZ; ++n ) + delete aFldTypeTable[n]; +} + + + + diff --git a/sw/source/core/doc/docfly.cxx b/sw/source/core/doc/docfly.cxx new file mode 100644 index 000000000000..aaa08001d397 --- /dev/null +++ b/sw/source/core/doc/docfly.cxx @@ -0,0 +1,1038 @@ +/************************************************************************* + * + * $RCSfile: docfly.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:15 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _HINTIDS_HXX +#include +#endif + +#ifndef _SFXITEMITER_HXX //autogen +#include +#endif +#ifndef _SVDOBJ_HXX //autogen +#include +#endif +#ifndef _SVDPAGE_HXX //autogen +#include +#endif +#ifndef _SVDMODEL_HXX //autogen +#include +#endif +#ifndef _SVDCAPT_HXX //autogen +#include +#endif +#ifndef _SVDMARK_HXX //autogen +#include +#endif + +#ifndef _FMTFSIZE_HXX //autogen +#include +#endif +#ifndef _FMTORNT_HXX //autogen +#include +#endif +#ifndef _FMTSRND_HXX //autogen +#include +#endif +#ifndef _DCONTACT_HXX //autogen +#include +#endif + +#include +#ifndef _DOC_HXX //autogen +#include +#endif +#ifndef _NDINDEX_HXX //autogen +#include +#endif +#ifndef _NODE_HXX //autogen +#include +#endif +#ifndef _DOCARY_HXX +#include +#endif +#ifndef _FMTCNTNT_HXX //autogen +#include +#endif +#ifndef _FMTANCHR_HXX //autogen +#include +#endif +#ifndef _TXTFLCNT_HXX //autogen +#include +#endif +#ifndef _FMTFLCNT_HXX //autogen +#include +#endif +#ifndef _FMTORNT_HXX //autogen +#include +#endif +#ifndef _TXTFRM_HXX //autogen +#include +#endif +#ifndef _PAGEFRM_HXX //autogen +#include +#endif +#ifndef _ROOTFRM_HXX //autogen +#include +#endif +#ifndef _FLYFRMS_HXX //autogen +#include +#endif +#ifndef _FRMTOOL_HXX //autogen +#include +#endif +#ifndef _FRMFMT_HXX //autogen +#include +#endif +#ifndef _NDTXT_HXX //autogen +#include +#endif +#ifndef _PAM_HXX //autogen +#include +#endif +#ifndef _TBLSEL_HXX //autogen +#include +#endif +#ifndef _SWUNDO_HXX //autogen +#include +#endif +#ifndef _SWTABLE_HXX //autogen +#include +#endif +#ifndef _CRSTATE_HXX +#include +#endif +#ifndef _UNDOBJ_HXX //autogen +#include +#endif +#ifndef _FMTCNCT_HXX //autogen +#include +#endif + +extern USHORT GetHtmlMode( const SwDocShell* ); + +/*-----------------17.02.98 08:35------------------- + +--------------------------------------------------*/ +USHORT SwDoc::GetFlyCount(FlyCntType eType ) const +{ + const SwSpzFrmFmts& rFmts = *GetSpzFrmFmts(); + USHORT nSize = rFmts.Count(); + USHORT nCount = 0; + const SwNodeIndex* pIdx; + for ( USHORT i = 0; i < nSize; i++) + { + const SwFrmFmt* pFlyFmt = rFmts[ i ]; + if( RES_FLYFRMFMT == pFlyFmt->Which() + && 0 != ( pIdx = pFlyFmt->GetCntnt().GetCntntIdx() ) + && pIdx->GetNodes().IsDocNodes() + ) + { + const SwNode* pNd = GetNodes()[ pIdx->GetIndex() + 1 ]; + + switch( eType ) + { + case FLYCNTTYPE_FRM: + if(!pNd->IsNoTxtNode()) + nCount++; + break; + + case FLYCNTTYPE_GRF: + if( pNd->IsGrfNode() ) + nCount++; + break; + + case FLYCNTTYPE_OLE: + if(pNd->IsOLENode()) + nCount++; + break; + + default: + nCount++; + } + } + } + return nCount; +} + +/*-----------------17.02.98 08:35------------------- + +--------------------------------------------------*/ +SwFrmFmt* SwDoc::GetFlyNum( USHORT nIdx, FlyCntType eType ) +{ + SwSpzFrmFmts& rFmts = *GetSpzFrmFmts(); + SwFrmFmt* pRetFmt = 0; + USHORT nSize = rFmts.Count(); + const SwNodeIndex* pIdx; + USHORT nCount = 0; + for( USHORT i = 0; !pRetFmt && i < nSize; ++i ) + { + SwFrmFmt* pFlyFmt = rFmts[ i ]; + if( RES_FLYFRMFMT == pFlyFmt->Which() + && 0 != ( pIdx = pFlyFmt->GetCntnt().GetCntntIdx() ) + && pIdx->GetNodes().IsDocNodes() + ) + { + const SwNode* pNd = GetNodes()[ pIdx->GetIndex() + 1 ]; + switch( eType ) + { + case FLYCNTTYPE_FRM: + if( !pNd->IsNoTxtNode() && nIdx == nCount++) + pRetFmt = pFlyFmt; + break; + case FLYCNTTYPE_GRF: + if(pNd->IsGrfNode() && nIdx == nCount++ ) + pRetFmt = pFlyFmt; + break; + case FLYCNTTYPE_OLE: + if(pNd->IsOLENode() && nIdx == nCount++) + pRetFmt = pFlyFmt; + break; + default: + if(nIdx == nCount++) + pRetFmt = pFlyFmt; + } + } + } + return pRetFmt; +} + +/* */ + +/*********************************************************************** +#* Class : SwDoc +#* Methode : SetFlyFrmAnchor +#* Beschreibung: Das Ankerattribut des FlyFrms aendert sich. +#* Datum : MA 01. Feb. 94 +#* Update : JP 09.03.98 +#***********************************************************************/ + +Point lcl_FindAnchorLayPos( SwDoc& rDoc, const SwFmtAnchor& rAnch, + const SwFrmFmt* pFlyFmt ) +{ + Point aRet; + if( rDoc.GetRootFrm() ) + switch( rAnch.GetAnchorId() ) + { + case FLY_IN_CNTNT: + if( pFlyFmt && rAnch.GetCntntAnchor() ) + { + const SwFrm* pOld = ((SwFlyFrmFmt*)pFlyFmt)->GetFrm( &aRet, FALSE ); + if( pOld ) + aRet = pOld->Frm().Pos(); + } + break; + + case FLY_AT_CNTNT: + case FLY_AUTO_CNTNT: // LAYER_IMPL + if( rAnch.GetCntntAnchor() ) + { + const SwPosition *pPos = rAnch.GetCntntAnchor(); + const SwCntntNode* pNd = pPos->nNode.GetNode().GetCntntNode(); + const SwFrm* pOld = pNd ? pNd->GetFrm( &aRet, 0, FALSE ) : 0; + if( pOld ) + aRet = pOld->Frm().Pos(); + } + break; + + case FLY_AT_FLY: // LAYER_IMPL + if( rAnch.GetCntntAnchor() ) + { + const SwFlyFrmFmt* pFmt = (SwFlyFrmFmt*)rAnch.GetCntntAnchor()-> + nNode.GetNode().GetFlyFmt(); + const SwFrm* pOld = pFmt ? pFmt->GetFrm( &aRet, FALSE ) : 0; + if( pOld ) + aRet = pOld->Frm().Pos(); + } + break; + + case FLY_PAGE: + { + USHORT nPgNum = rAnch.GetPageNum(); + const SwPageFrm *pPage = (SwPageFrm*)rDoc.GetRootFrm()->Lower(); + for( USHORT i = 1; (i <= nPgNum) && pPage; ++i, + pPage = (const SwPageFrm*)pPage->GetNext() ) + if( i == nPgNum ) + { + aRet = pPage->Frm().Pos(); + break; + } + } + break; + } + return aRet; +} + +BOOL SwDoc::SetFlyFrmAnchor( SwFrmFmt& rFmt, SfxItemSet& rSet, BOOL bNewFrms ) +{ + //Ankerwechsel sind fast immer in alle 'Richtungen' erlaubt. + //Ausnahme: Absatz- bzw. Zeichengebundene Rahmen duerfen wenn sie in + //Kopf-/Fusszeilen stehen nicht Seitengebunden werden. + const SwFmtAnchor &rOldAnch = rFmt.GetAnchor(); + const RndStdIds nOld = rOldAnch.GetAnchorId(); + + SwFmtAnchor aNewAnch( (SwFmtAnchor&)rSet.Get( RES_ANCHOR ) ); + RndStdIds nNew = aNewAnch.GetAnchorId(); + + if( nOld == nNew ) + return FALSE; + + // ist der neue ein gueltiger Anker? + if( !aNewAnch.GetCntntAnchor() && (FLY_AT_FLY == nNew || + FLY_AT_CNTNT == nNew || FLY_IN_CNTNT == nNew || + FLY_AUTO_CNTNT == nNew )) + return FALSE; + +#ifndef PRODUCT + if( nNew == FLY_PAGE && + (FLY_AT_CNTNT==nOld || FLY_AUTO_CNTNT==nOld || FLY_IN_CNTNT==nOld ) && + IsInHeaderFooter( rOldAnch.GetCntntAnchor()->nNode ) ) + ASSERT( !this, "Unerlaubter Ankerwechsel in Head/Foot." ); +#endif + + Point aOldAnchorPos( ::lcl_FindAnchorLayPos( *this, rOldAnch, &rFmt )); + Point aNewAnchorPos( ::lcl_FindAnchorLayPos( *this, aNewAnch, 0 )); + + //Die alten Frms vernichten. Dabei werden die Views implizit gehidet und + //doppeltes hiden waere so eine art Show! + rFmt.DelFrms(); + + if( FLY_IN_CNTNT == nOld ) + { + //Bei InCntnt's wird es spannend: Das TxtAttribut muss vernichtet + //werden. Leider reisst dies neben den Frms auch noch das Format mit + //in sein Grab. Um dass zu unterbinden loesen wir vorher die + //Verbindung zwischen Attribut und Format. + const SwPosition *pPos = rOldAnch.GetCntntAnchor(); + SwTxtNode *pTxtNode = pPos->nNode.GetNode().GetTxtNode(); + ASSERT( pTxtNode->HasHints(), "Missing FlyInCnt-Hint." ); + const xub_StrLen nIdx = pPos->nContent.GetIndex(); + SwTxtAttr * pHnt = pTxtNode->GetTxtAttr( nIdx, RES_TXTATR_FLYCNT ); +#ifndef PRODUCT + ASSERT( pHnt && pHnt->Which() == RES_TXTATR_FLYCNT, + "Missing FlyInCnt-Hint." ); + ASSERT( pHnt && pHnt->GetFlyCnt().GetFrmFmt() == &rFmt, + "Wrong TxtFlyCnt-Hint." ); +#endif + ((SwFmtFlyCnt&)pHnt->GetFlyCnt()).SetFlyFmt(); + + //Die Verbindung ist geloest, jetzt muss noch das Attribut vernichtet + //werden. + pTxtNode->Delete( RES_TXTATR_FLYCNT, nIdx, nIdx ); + } + + //Endlich kann das Attribut gesetzt werden. Es muss das erste Attribut + //sein; Undo depends on it! + rFmt.SetAttr( aNewAnch ); + + //Positionskorrekturen + const SfxPoolItem* pItem; + switch( nNew ) + { + case FLY_IN_CNTNT: + //Wenn keine Positionsattribute hereinkommen, dann muss dafuer + //gesorgt werden, das keine unerlaubte automatische Ausrichtung + //bleibt. + { + const SwPosition *pPos = aNewAnch.GetCntntAnchor(); + SwTxtNode *pNd = pPos->nNode.GetNode().GetTxtNode(); + ASSERT( pNd, "Crsr steht nicht auf TxtNode." ); + + pNd->Insert( SwFmtFlyCnt( (SwFlyFrmFmt*)&rFmt ), + pPos->nContent.GetIndex(), 0 ); + } + + if( SFX_ITEM_SET != rSet.GetItemState( RES_VERT_ORIENT, FALSE, &pItem )) + { + SwFmtVertOrient aOldV( rFmt.GetVertOrient() ); + BOOL bSet = TRUE; + switch( aOldV.GetVertOrient() ) + { + case VERT_LINE_TOP: aOldV.SetVertOrient( VERT_TOP ); break; + case VERT_LINE_CENTER: aOldV.SetVertOrient( VERT_CENTER); break; + case VERT_LINE_BOTTOM: aOldV.SetVertOrient( VERT_BOTTOM); break; + case VERT_NONE: aOldV.SetVertOrient( VERT_CENTER); break; + default: + bSet = FALSE; + } + if( bSet ) + rSet.Put( aOldV ); + } + break; + + case FLY_AT_CNTNT: + case FLY_AUTO_CNTNT: // LAYER_IMPL + case FLY_AT_FLY: // LAYER_IMPL + case FLY_PAGE: + { + //Wenn keine Positionsattribute hereinschneien korrigieren wir + //die Position so, dass die Dokumentkoordinaten des Flys erhalten + //bleiben. + //Chg: Wenn sich in den Positionsattributen lediglich die + //Ausrichtung veraendert (FRAME vs. PRTAREA), dann wird die + //Position ebenfalls korrigiert. + if( SFX_ITEM_SET != rSet.GetItemState( RES_HORI_ORIENT, FALSE, &pItem )) + pItem = 0; + + SwFmtHoriOrient aOldH( rFmt.GetHoriOrient() ); + + if( HORI_NONE == aOldH.GetHoriOrient() && ( !pItem || + aOldH.GetPos() == ((SwFmtHoriOrient*)pItem)->GetPos() )) + { + SwTwips nPos = FLY_IN_CNTNT == nOld ? 0 : aOldH.GetPos(); + nPos += aOldAnchorPos.X() - aNewAnchorPos.X(); + + if( pItem ) + { + SwFmtHoriOrient* pH = (SwFmtHoriOrient*)pItem; + aOldH.SetHoriOrient( pH->GetHoriOrient() ); + aOldH.SetRelationOrient( pH->GetRelationOrient() ); + } + aOldH.SetPos( nPos ); + rSet.Put( aOldH ); + } + + if( SFX_ITEM_SET != rSet.GetItemState( RES_VERT_ORIENT, FALSE, &pItem )) + pItem = 0; + SwFmtVertOrient aOldV( rFmt.GetVertOrient() ); + + if( HORI_NONE == aOldV.GetVertOrient() && (!pItem || + aOldV.GetPos() == ((SwFmtVertOrient*)pItem)->GetPos() ) ) + { + SwTwips nPos = FLY_IN_CNTNT == nOld ? 0 : aOldV.GetPos(); + nPos += aOldAnchorPos.Y() - aNewAnchorPos.Y(); + if( pItem ) + { + SwFmtVertOrient* pV = (SwFmtVertOrient*)pItem; + aOldV.SetVertOrient( pV->GetVertOrient() ); + aOldV.SetRelationOrient( pV->GetRelationOrient() ); + } + aOldV.SetPos( nPos ); + rSet.Put( aOldV ); + } + } + break; + } + + if( bNewFrms ) + rFmt.MakeFrms(); + + return TRUE; +} + +BOOL SwDoc::SetFlyFrmAttr( SwFrmFmt& rFlyFmt, SfxItemSet& rSet ) +{ + if( !rSet.Count() ) + return FALSE; + + _UndoFmtAttr* pSaveUndo = 0; + if( DoesUndo() ) + { + ClearRedo(); + pSaveUndo = new _UndoFmtAttr( rFlyFmt ); + } + + //Ist das Ankerattribut dabei? Falls ja ueberlassen wir die Verarbeitung + //desselben einer Spezialmethode. Sie Returnt TRUE wenn der Fly neu + //erzeugt werden muss (z.B. weil ein Wechsel des FlyTyps vorliegt). + BOOL bMakeFrms = SFX_ITEM_SET == rSet.GetItemState( RES_ANCHOR, FALSE ) && + SetFlyFrmAnchor( rFlyFmt, rSet, FALSE ); + + const SfxPoolItem* pItem; + SfxItemIter aIter( rSet ); + SfxItemSet aTmpSet( GetAttrPool(), aFrmFmtSetRange ); + USHORT nWhich = aIter.GetCurItem()->Which(); + do { + switch( nWhich ) + { + case RES_FILL_ORDER: + case RES_BREAK: + case RES_PAGEDESC: + case RES_CNTNT: + case RES_FOOTER: + ASSERT( !this, ":-) Unbekanntes Attribut fuer Fly." ); + // kein break; + case RES_CHAIN: + rSet.ClearItem( nWhich ); + // kein break; + case RES_ANCHOR: + break; + + default: + if( !IsInvalidItem( aIter.GetCurItem() ) && ( SFX_ITEM_SET != + rFlyFmt.GetAttrSet().GetItemState( nWhich, TRUE, &pItem ) || + *pItem != *aIter.GetCurItem() )) + aTmpSet.Put( *aIter.GetCurItem() ); + break; + } + + if( aIter.IsAtEnd() ) + break; + + } while( 0 != ( nWhich = aIter.NextItem()->Which() ) ); + + if( aTmpSet.Count() ) + rFlyFmt.SetAttr( aTmpSet ); + + if( bMakeFrms ) + rFlyFmt.MakeFrms(); + + if( pSaveUndo ) + { + if( pSaveUndo->pUndo ) + AppendUndo( pSaveUndo->pUndo ); + delete pSaveUndo; + } + + SetModified(); + + return aTmpSet.Count() || bMakeFrms; +} + + +/*************************************************************************** + * Methode : BOOL SwDoc::SetFrmFmtToFly( SwFlyFrm&, SwFrmFmt& ) + * Beschreibung: + * Erstellt : OK 14.04.94 15:40 + * Aenderung : JP 23.04.98 + ***************************************************************************/ + +BOOL SwDoc::SetFrmFmtToFly( SwFrmFmt& rFmt, SwFrmFmt& rNewFmt, + SfxItemSet* pSet, BOOL bKeepOrient ) +{ + BOOL bChgAnchor = FALSE, bFrmSz = FALSE; + + const SwFmtFrmSize aFrmSz( rFmt.GetFrmSize() ); + const SwFmtVertOrient aVert( rFmt.GetVertOrient() ); + const SwFmtHoriOrient aHori( rFmt.GetHoriOrient() ); + + SwUndoSetFlyFmt* pUndo = 0; + if( DoesUndo() ) + { + ClearRedo(); + AppendUndo( pUndo = new SwUndoSetFlyFmt( rFmt, rNewFmt ) ); + } + + //Erstmal die Spalten setzen, sonst gibts nix als Aerger mit dem + //Set/Reset/Abgleich usw. + const SfxPoolItem* pItem; + if( SFX_ITEM_SET != rNewFmt.GetAttrSet().GetItemState( RES_COL )) + rFmt.ResetAttr( RES_COL ); + + if( rFmt.DerivedFrom() != &rNewFmt ) + { + rFmt.SetDerivedFrom( &rNewFmt ); + + // 1. wenn nicht automatisch -> ignorieren, sonst -> wech + // 2. wech damit, MB! + if( SFX_ITEM_SET == rNewFmt.GetAttrSet().GetItemState( RES_FRM_SIZE, FALSE )) + { + rFmt.ResetAttr( RES_FRM_SIZE ); + bFrmSz = TRUE; + } + + const SfxItemSet* pAsk = pSet; + if( !pAsk ) pAsk = &rNewFmt.GetAttrSet(); + if( SFX_ITEM_SET == pAsk->GetItemState( RES_ANCHOR, FALSE, &pItem ) + && ((SwFmtAnchor*)pItem)->GetAnchorId() != + rFmt.GetAnchor().GetAnchorId() ) + { + if( pUndo ) + DoUndo( FALSE ); + + if( pSet ) + bChgAnchor = SetFlyFrmAnchor( rFmt, *pSet, FALSE ); + else + { + //JP 23.04.98: muss den FlyFmt-Range haben, denn im SetFlyFrmAnchor + // werden Attribute in diesen gesetzt! + SfxItemSet aFlySet( *rNewFmt.GetAttrSet().GetPool(), + rNewFmt.GetAttrSet().GetRanges() ); + aFlySet.Put( *pItem ); + bChgAnchor = SetFlyFrmAnchor( rFmt, aFlySet, FALSE ); + } + + if( pUndo ) + DoUndo( TRUE ); + } + } + + //Hori und Vert nur dann resetten, wenn in der Vorlage eine + //automatische Ausrichtung eingestellt ist, anderfalls den alten Wert + //wieder hineinstopfen. + //JP 09.06.98: beim Update der RahmenVorlage sollte der Fly NICHT + // seine Orientierng verlieren (diese wird nicht geupdatet!) + if( !bKeepOrient ) + { + const SwFmtVertOrient &rVert = rNewFmt.GetVertOrient(); + if ( VERT_NONE != rVert.GetVertOrient() ) + rFmt.ResetAttr( RES_VERT_ORIENT ); + else + rFmt.SetAttr( aVert ); + + const SwFmtHoriOrient &rHori = rNewFmt.GetHoriOrient(); + if ( HORI_NONE != rHori.GetHoriOrient() ) + rFmt.ResetAttr( RES_HORI_ORIENT ); + else + rFmt.SetAttr( aHori ); + } + + rFmt.ResetAttr( RES_PRINT, RES_SURROUND ); + rFmt.ResetAttr( RES_LR_SPACE, RES_UL_SPACE ); + rFmt.ResetAttr( RES_BACKGROUND, RES_COL ); + rFmt.ResetAttr( RES_URL, RES_EDIT_IN_READONLY ); + + if( !bFrmSz ) + rFmt.SetAttr( aFrmSz ); + + if( bChgAnchor ) + rFmt.MakeFrms(); + + if( pUndo ) + rFmt.Remove( pUndo ); + + SetModified(); + return bChgAnchor; +} + +void SwDoc::GetGrfNms( const SwFlyFrmFmt& rFmt, String* pGrfName, + String* pFltName ) const +{ + SwNodeIndex aIdx( *rFmt.GetCntnt().GetCntntIdx(), 1 ); + const SwGrfNode* pGrfNd = aIdx.GetNode().GetGrfNode(); + if( pGrfNd && pGrfNd->IsLinkedFile() ) + pGrfNd->GetFileFilterNms( pGrfName, pFltName ); +} + +/************************************************************************* +|* +|* SwDoc::ChgAnchor() +|* +|* Ersterstellung MA 10. Jan. 95 +|* Letzte Aenderung JP 08.07.98 +|* +*************************************************************************/ + +BOOL SwDoc::ChgAnchor( const SdrMarkList& rMrkList, int eAnchorId, + BOOL bSameOnly, BOOL bPosCorr ) +{ + ASSERT( GetRootFrm(), "Ohne Layout geht gar nichts" ); + + if( !rMrkList.GetMarkCount() || + rMrkList.GetMark( 0 )->GetObj()->GetUpGroup() ) + return FALSE; // Kein Ankerwechsel innerhalb von Gruppen + + StartUndo( UNDO_INSATTR ); + + BOOL bUnmark = FALSE; + for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i ) + { + SdrObject *pObj = rMrkList.GetMark( i )->GetObj(); + if ( !pObj->IsWriterFlyFrame() ) + { + SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj); + + const SwFrm *pOldAnch = pContact->GetAnchor(); + const SwFrm *pNewAnch = pOldAnch; + + BOOL bChanges = TRUE; + xub_StrLen nIndx = STRING_NOTFOUND; + SwTxtNode *pTxtNode; + int nOld = pContact->GetFmt()->GetAnchor().GetAnchorId(); + if( !bSameOnly && FLY_IN_CNTNT == nOld ) + { + const SwPosition *pPos = + pContact->GetFmt()->GetAnchor().GetCntntAnchor(); + pTxtNode = pPos->nNode.GetNode().GetTxtNode(); + ASSERT( pTxtNode->HasHints(), "Missing FlyInCnt-Hint." ); + nIndx = pPos->nContent.GetIndex(); + if( !pOldAnch ) + { + pContact->ConnectToLayout(); + pOldAnch = pContact->GetAnchor(); + } + pOldAnch->Calc(); + pObj->ImpSetAnchorPos( pOldAnch->Frm().Pos() ); + } + + if ( bSameOnly ) + eAnchorId = nOld; + + bChanges = FLY_IN_CNTNT != eAnchorId; + SwFmtAnchor aNewAnch( (RndStdIds)eAnchorId ); + const Point aPt( pObj->GetAnchorPos() + pObj->GetRelativePos() ); + + switch ( eAnchorId ) + { + case FLY_AT_CNTNT: + case FLY_AUTO_CNTNT: + pNewAnch = ::FindAnchor( pOldAnch, aPt, TRUE ); + if( pNewAnch->IsProtected() ) + pNewAnch = 0; + else + { + SwPosition aPos( *((SwCntntFrm*)pNewAnch)->GetNode() ); + aNewAnch.SetType( (RndStdIds)eAnchorId ); + aNewAnch.SetAnchor( &aPos ); + } + break; + + case FLY_AT_FLY: // LAYER_IMPL + { + //Ausgehend von der linken oberen Ecke des Fly den + //dichtesten SwFlyFrm suchen. + SwFrm *pTxtFrm; + { + SwCrsrMoveState aState( MV_SETONLYTEXT ); + SwPosition aPos( GetNodes() ); + Point aPoint( aPt ); + aPoint.X() -= 1; + GetRootFrm()->GetCrsrOfst( &aPos, aPoint, &aState ); + pTxtFrm = aPos.nNode.GetNode(). + GetCntntNode()->GetFrm( 0, 0, FALSE ); + } + const SwFrm *pTmp = ::FindAnchor( pTxtFrm, aPt ); + pNewAnch = pTmp->FindFlyFrm(); + if( pNewAnch && !pNewAnch->IsProtected() ) + { + const SwFrmFmt *pTmpFmt = ((SwFlyFrm*)pNewAnch)->GetFmt(); + const SwFmtCntnt& rCntnt = pTmpFmt->GetCntnt(); + SwPosition aPos( *rCntnt.GetCntntIdx() ); + aNewAnch.SetAnchor( &aPos ); + break; + } + + aNewAnch.SetType( FLY_PAGE ); + // no break + } + case FLY_PAGE: + { + pNewAnch = GetRootFrm()->Lower(); + while ( pNewAnch && !pNewAnch->Frm().IsInside( aPt ) ) + pNewAnch = pNewAnch->GetNext(); + if ( !pNewAnch ) + continue; + + aNewAnch.SetPageNum( ((SwPageFrm*)pNewAnch)->GetPhyPageNum()); + } + break; + case FLY_IN_CNTNT: + if( bSameOnly ) // Positions/Groessenaenderung + { + SwDrawFrmFmt *pFmt = (SwDrawFrmFmt*)pContact->GetFmt(); + const SwFmtVertOrient &rVert = pFmt->GetVertOrient(); + Point aRelPos = pObj->GetRelativePos(); + if ( rVert.GetPos() != aRelPos.Y() || + VERT_NONE != rVert.GetVertOrient() ) + { + SwFmtVertOrient aVert( rVert ); + aVert.SetVertOrient( VERT_NONE ); + aVert.SetPos( aRelPos.Y() ); + SetAttr( aVert, *pFmt ); + } + else + { + if( !pOldAnch ) + { + pContact->ConnectToLayout(); + pOldAnch = pContact->GetAnchor(); + } + ((SwTxtFrm*)pOldAnch)->Prepare(); + } + } + else // Ankerwechsel + { + pNewAnch = ::FindAnchor( pOldAnch, aPt, TRUE ); + if( pNewAnch->IsProtected() ) + { + pNewAnch = 0; + break; + } + + bUnmark = ( 0 != i ); + Point aPoint( aPt ); + aPoint.X() -= 1; // nicht im DrawObj landen!! + aNewAnch.SetType( FLY_IN_CNTNT ); + SwPosition aPos( *((SwCntntFrm*)pNewAnch)->GetNode() ); + if ( pNewAnch->Frm().IsInside( aPoint ) ) + { + // es muss ein TextNode gefunden werden, denn nur dort + // ist ein inhaltsgebundenes DrawObjekt zu verankern + SwCrsrMoveState aState( MV_SETONLYTEXT ); + GetRootFrm()->GetCrsrOfst( &aPos, aPoint, &aState ); + } + else + { + SwCntntNode &rCNd = (SwCntntNode&) + *((SwCntntFrm*)pNewAnch)->GetNode(); + if ( pNewAnch->Frm().Bottom() < aPt.Y() ) + rCNd.MakeStartIndex( &aPos.nContent ); + else + rCNd.MakeEndIndex( &aPos.nContent ); + } + aNewAnch.SetAnchor( &aPos ); + SetAttr( aNewAnch, *pContact->GetFmt() ); + SwTxtNode *pNd = aPos.nNode.GetNode().GetTxtNode(); + ASSERT( pNd, "Crsr steht nicht auf TxtNode." ); + + pNd->Insert( SwFmtFlyCnt( pContact->GetFmt() ), + aPos.nContent.GetIndex(), 0 ); + } + break; + default: + ASSERT( !this, "unexpected AnchorId." ); + } + + if( bChanges && pNewAnch ) + { + SetAttr( aNewAnch, *pContact->GetFmt() ); + if( bPosCorr ) + { + const Point aTmpRel( aPt - pNewAnch->Frm().Pos() ); + pObj->NbcSetRelativePos( aTmpRel ); + } +#ifndef PRODUCT + const Point aIstA( pObj->GetAnchorPos() ); + ASSERT( aIstA == pNewAnch->Frm().Pos(), + "ChgAnchor: Wrong Anchor-Pos." ); +#endif + } + + if ( pNewAnch && STRING_NOTFOUND != nIndx ) + { + //Bei InCntnt's wird es spannend: Das TxtAttribut muss vernichtet + //werden. Leider reisst dies neben den Frms auch noch das Format mit + //in sein Grab. Um dass zu unterbinden loesen wir vorher die + //Verbindung zwischen Attribut und Format. + SwTxtAttr *pHnt = pTxtNode->GetTxtAttr( nIndx, RES_TXTATR_FLYCNT ); + ((SwFmtFlyCnt&)pHnt->GetFlyCnt()).SetFlyFmt(); + + //Die Verbindung ist geloest, jetzt muss noch das Attribut vernichtet + //werden. + pTxtNode->Delete( RES_TXTATR_FLYCNT, nIndx, nIndx ); + } + } + } + + EndUndo( UNDO_END ); + SetModified(); + + return bUnmark; +} + + +/* -----------------23.07.98 13:56------------------- + * + * --------------------------------------------------*/ +int SwDoc::Chainable( const SwFrmFmt &rSource, const SwFrmFmt &rDest ) +{ + //Die Source darf noch keinen Follow haben. + const SwFmtChain &rOldChain = rSource.GetChain(); + if ( rOldChain.GetNext() ) + return SW_CHAIN_SOURCE_CHAINED; + + //Ziel darf natuerlich nicht gleich Source sein und es + //darf keine geschlossene Kette entstehen. + const SwFrmFmt *pFmt = &rDest; + do + { if ( pFmt == &rSource ) + return SW_CHAIN_SELF; + pFmt = pFmt->GetChain().GetNext(); + + } while ( pFmt ); + + + SwFlyFrm *pFly = ((SwFlyFrmFmt&)rDest).GetFrm(); + + //Auch eine Verkettung von Innen nach aussen oder von aussen + //nach innen ist nicht zulaessig. + SwClientIter aIter( (SwFrmFmt&)rSource ); + SwFlyFrm *pSFly = (SwFlyFrm*)aIter.First( TYPE(SwFlyFrm) ); + if ( rDest.IsLowerOf( rSource ) || + rSource .IsLowerOf( rDest ) ) + return SW_CHAIN_SELF; + + //Das Ziel darf noch keinen Master haben. + const SwFmtChain &rChain = pFly->GetFmt()->GetChain(); + if ( rChain.GetPrev() ) + return SW_CHAIN_IS_IN_CHAIN; + + //Das Ziel muss leer sein. + SwCntntFrm *pCnt = pFly->ContainsCntnt(); + + if ( pCnt && !pCnt->IsTxtFrm() ) + return SW_CHAIN_NOT_FOUND; + + if ( pCnt && (pCnt->FindNext() || + pCnt->IsInTab() || + pCnt->IsInSct() || + pCnt->IsInFtn() || + pCnt->GetDrawObjs() || + ((SwTxtFrm*)pCnt)->GetTxt().Len() + )) + return SW_CHAIN_NOT_EMPTY; + + //Auf die richtige Area muessen wir auch noch einen Blick werfen. + //Beide Flys muessen im selben Bereich (Body, Head/Foot, Fly) sitzen + //Wenn die Source nicht der selektierte Rahmen ist, so reicht es + //Wenn ein passender gefunden wird (Der Wunsch kann z.B. von der API + //kommen). + const USHORT nFrmType = FRM_FLY | FRM_HEADER | FRM_FOOTER | + FRM_ROOT | FRM_FTN; + SwFrm *pRef1 = pFly->GetAnchor(); + while ( !(pRef1->GetType() & nFrmType) ) + pRef1 = pRef1->GetUpper(); + + SwFlyFrm *pSourceFly = ((SwFlyFrmFmt&)rSource).GetFrm(); + if ( pSourceFly && &rSource != pSourceFly->GetFmt() ) + pSourceFly = 0; + SwClientIter aIter2( (SwFrmFmt&)rSource ); + SwFlyFrm *pCompare = pSourceFly ? pSourceFly + : (SwFlyFrm*)aIter2.First( TYPE(SwFlyFrm) ); + BOOL bAllowed = FALSE; + while ( !bAllowed && pCompare ) + { + SwFrm *pRef2 = pCompare->GetAnchor(); + while ( !(pRef2->GetType() & nFrmType) ) + pRef2 = pRef2->GetUpper(); + if ( pRef1 == pRef2 ) + bAllowed = TRUE; + else + pCompare = pSourceFly ? 0 : (SwFlyFrm*)aIter2.Next(); + } + if ( !bAllowed ) + return SW_CHAIN_WRONG_AREA; + + return SW_CHAIN_OK; +} +/* -----------------23.07.98 13:56------------------- + * + * --------------------------------------------------*/ +int SwDoc::Chain( SwFrmFmt &rSource, const SwFrmFmt &rDest ) +{ + int nErr = Chainable( rSource, rDest ); + if ( !nErr ) + { + StartUndo( UNDO_CHAINE ); + + SwFlyFrmFmt& rDestFmt = (SwFlyFrmFmt&)rDest; + SwFlyFrm* pFly = rDestFmt.GetFrm(); + + //Follow an den Master haengen. + SwFmtChain aChain = rDestFmt.GetChain(); + aChain.SetPrev( &(SwFlyFrmFmt&)rSource ); + SetAttr( aChain, rDestFmt ); + + SfxItemSet aSet( GetAttrPool(), RES_FRM_SIZE, RES_FRM_SIZE, + RES_CHAIN, RES_CHAIN, 0 ); + + //Follow an den Master haengen. + aChain.SetPrev( &(SwFlyFrmFmt&)rSource ); + SetAttr( aChain, rDestFmt ); + + //Master an den Follow haengen und dafuer sorgen, dass der Master + //eine fixierte Hoehe hat. + aChain = rSource.GetChain(); + aChain.SetNext( &rDestFmt ); + aSet.Put( aChain ); + + SwFmtFrmSize aSize( rSource.GetFrmSize() ); + if ( aSize.GetSizeType() != ATT_FIX_SIZE ) + { + SwClientIter aIter( rSource ); + SwFlyFrm *pFly = (SwFlyFrm*)aIter.First( TYPE(SwFlyFrm) ); + if ( pFly ) + aSize.SetHeight( pFly->Frm().Height() ); + aSize.SetSizeType( ATT_FIX_SIZE ); + aSet.Put( aSize ); + } + SetAttr( aSet, rSource ); + + EndUndo( UNDO_CHAINE ); + } + return nErr; +} +/* -----------------23.07.98 13:56------------------- + * + * --------------------------------------------------*/ +void SwDoc::Unchain( SwFrmFmt &rFmt ) +{ + SwFmtChain aChain( rFmt.GetChain() ); + if ( aChain.GetNext() ) + { + StartUndo( UNDO_UNCHAIN ); + SwFrmFmt *pFollow = aChain.GetNext(); + aChain.SetNext( 0 ); + SetAttr( aChain, rFmt ); + aChain = pFollow->GetChain(); + aChain.SetPrev( 0 ); + SetAttr( aChain, *pFollow ); + EndUndo( UNDO_UNCHAIN ); + } +} + + + diff --git a/sw/source/core/doc/docfmt.cxx b/sw/source/core/doc/docfmt.cxx new file mode 100644 index 000000000000..b27bde397ed2 --- /dev/null +++ b/sw/source/core/doc/docfmt.cxx @@ -0,0 +1,2167 @@ +/************************************************************************* + * + * $RCSfile: docfmt.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:15 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#define _ZFORLIST_DECLARE_TABLE +#define _SVSTDARR_USHORTSSORT +#define _SVSTDARR_USHORTS + +#ifndef _HINTIDS_HXX +#include +#endif + +#ifndef _SFXITEMITER_HXX //autogen +#include +#endif +#ifndef _SO2REF_HXX //autogen +#include +#endif +#ifndef SO2_DECL_SVLINKNAME_DEFINED +#define SO2_DECL_SVLINKNAME_DEFINED +SO2_DECL_REF(SvLinkName) +#endif +#ifndef _SFXAPP_HXX +#include +#endif +#ifndef _OFA_MISCCFG_HXX +#include +#endif +#ifndef _SVX_TSTPITEM_HXX //autogen +#include +#endif +#ifndef _SVX_LRSPITEM_HXX //autogen +#include +#endif +#ifndef _SVX_BRKITEM_HXX //autogen +#include +#endif +#ifndef _SFX_WHITER_HXX //autogen +#include +#endif +#ifndef _WORDSEL_HXX //autogen +#include +#endif +#ifndef _ZFORLIST_HXX //autogen +#define _ZFORLIST_DECLARE_TABLE +#include +#endif + +#ifndef _FMTPDSC_HXX //autogen +#include +#endif +#ifndef _FMTHDFT_HXX //autogen +#include +#endif +#ifndef _FMTCNTNT_HXX //autogen +#include +#endif +#ifndef _FRMATR_HXX +#include +#endif +#ifndef _DOC_HXX +#include +#endif +#ifndef _ROOTFRM_HXX +#include +#endif +#ifndef _PAGEFRM_HXX +#include +#endif +#ifndef _HINTS_HXX +#include // fuer SwHyphenBug (in SetDefault) +#endif +#ifndef _NDTXT_HXX +#include +#endif +#ifndef _PAM_HXX +#include +#endif +#ifndef _UNDOBJ_HXX +#include +#endif +#ifndef _NDGRF_HXX +#include +#endif +#ifndef _PAGEDESC_HXX +#include // Fuer Sonderbehandlung in InsFrmFmt +#endif +#ifndef _ROLBCK_HXX +#include // Undo-Attr +#endif +#ifndef _MVSAVE_HXX +#include // servieren: Veraenderungen erkennen +#endif +#ifndef _TXATBASE_HXX +#include +#endif +#ifndef _SWTABLE_HXX +#include +#endif +#ifndef _SWTBLFMT_HXX +#include +#endif +#ifndef _CHARFMT_HXX +#include +#endif +#ifndef _DOCARY_HXX +#include +#endif +#ifndef _NUMRULE_HXX +#include +#endif +#ifndef _PARATR_HXX +#include +#endif +#ifndef _REDLINE_HXX +#include +#endif +#ifndef _REFFLD_HXX //autogen +#include +#endif +#ifndef _TXTINET_HXX //autogen +#include +#endif +#ifndef _FMTINFMT_HXX //autogen +#include +#endif + + +SV_IMPL_PTRARR(SwFrmFmts,SwFrmFmtPtr) +SV_IMPL_PTRARR(SwCharFmts,SwCharFmtPtr) + +//Spezifische Frameformate (Rahmen) +SV_IMPL_PTRARR(SwSpzFrmFmts,SwFrmFmtPtr) + +/* + * interne Funktionen + */ + +BOOL SetTxtFmtCollNext( const SwTxtFmtCollPtr& rpTxtColl, void* pArgs ) +{ + SwTxtFmtColl *pDel = (SwTxtFmtColl*) pArgs; + if ( &rpTxtColl->GetNextTxtFmtColl() == pDel ) + { + rpTxtColl->SetNextTxtFmtColl( *rpTxtColl ); + } + return TRUE; +} + +/* + * Zuruecksetzen der harten Formatierung fuer Text + */ + +// Uebergabeparameter fuer _Rst und lcl_SetTxtFmtColl +struct ParaRstFmt +{ + SwFmtColl* pFmtColl; + SwHistory* pHistory; + const SwPosition *pSttNd, *pEndNd; + const SfxItemSet* pDelSet; + USHORT nWhich; + BOOL bReset, bResetAll, bInclRefToxMark; + + ParaRstFmt( const SwPosition* pStt, const SwPosition* pEnd, + SwHistory* pHst, USHORT nWhch = 0, const SfxItemSet* pSet = 0 ) + : pSttNd( pStt ), pEndNd( pEnd ), pHistory( pHst ), nWhich( nWhch ), + pDelSet( pSet ), bResetAll( TRUE ), pFmtColl( 0 ), + bInclRefToxMark( FALSE ) + {} + + ParaRstFmt( SwHistory* pHst ) + : pSttNd( 0 ), pEndNd( 0 ), pHistory( pHst ), nWhich( 0 ), + pDelSet( 0 ), bResetAll( TRUE ), pFmtColl( 0 ), + bInclRefToxMark( FALSE ) + {} +}; + +/* in pArgs steht die ChrFmtTablle vom Dokument + * (wird bei Selectionen am Start/Ende und bei keiner SSelection benoetigt) + */ + +BOOL lcl_RstTxtAttr( const SwNodePtr& rpNd, void* pArgs ) +{ + ParaRstFmt* pPara = (ParaRstFmt*)pArgs; + SwTxtNode * pTxtNode = (SwTxtNode*)rpNd->GetTxtNode(); + if( pTxtNode && pTxtNode->GetpSwpHints() ) + { + SwIndex aSt( pTxtNode, 0 ); + USHORT nEnd = pTxtNode->Len(); + + if( &pPara->pSttNd->nNode.GetNode() == pTxtNode && + pPara->pSttNd->nContent.GetIndex() ) + aSt = pPara->pSttNd->nContent.GetIndex(); + + if( &pPara->pEndNd->nNode.GetNode() == rpNd ) + nEnd = pPara->pEndNd->nContent.GetIndex(); + + if( pPara->pHistory ) + { + // fuers Undo alle Attribute sichern + SwRegHistory aRHst( *pTxtNode, pPara->pHistory ); + pTxtNode->GetpSwpHints()->Register( &aRHst ); + pTxtNode->RstAttr( aSt, nEnd - aSt.GetIndex(), pPara->nWhich, + pPara->pDelSet, pPara->bInclRefToxMark ); + if( pTxtNode->GetpSwpHints() ) + pTxtNode->GetpSwpHints()->DeRegister(); + } + else + pTxtNode->RstAttr( aSt, nEnd - aSt.GetIndex(), pPara->nWhich, + pPara->pDelSet, pPara->bInclRefToxMark ); + } + return TRUE; +} + +BOOL lcl_RstAttr( const SwNodePtr& rpNd, void* pArgs ) +{ + ParaRstFmt* pPara = (ParaRstFmt*)pArgs; + SwCntntNode* pNode = (SwCntntNode*)rpNd->GetCntntNode(); + if( pNode && pNode->GetpSwAttrSet() ) + { + // das erhalten der Break-Attribute und der NumRule kommt nicht ins Undo + BOOL bLocked = pNode->IsModifyLocked(); + pNode->LockModify(); + SwDoc* pDoc = pNode->GetDoc(); + + SfxItemSet aSet( pDoc->GetAttrPool(), + RES_PAGEDESC, RES_BREAK, + RES_PARATR_NUMRULE, RES_PARATR_NUMRULE, + RES_LR_SPACE, RES_LR_SPACE, + 0 ); + SwAttrSet* pSet = pNode->GetpSwAttrSet(); + + USHORT __READONLY_DATA aSavIds[ 3 ] = { RES_PAGEDESC, RES_BREAK, + RES_PARATR_NUMRULE }; + + const SfxPoolItem* pItem; + for( USHORT n = 0; n < 3; ++n ) + if( SFX_ITEM_SET == pSet->GetItemState( aSavIds[n], FALSE, &pItem ) + && ( RES_PARATR_NUMRULE != aSavIds[n] || + ((SwNumRuleItem*)pItem)->GetValue().Len() )) + { + aSet.Put( *pItem ); + pSet->ClearItem( aSavIds[n] ); + } + + if( !bLocked ) + pNode->UnlockModify(); + + if( pPara ) + { + SwRegHistory aRegH( pNode, *pNode, pPara->pHistory ); + + if( pPara->pDelSet && pPara->pDelSet->Count() ) + { + SfxItemIter aIter( *pPara->pDelSet ); + pItem = aIter.FirstItem(); + while( TRUE ) + { + pNode->ResetAttr( pItem->Which() ); + if( aIter.IsAtEnd() ) + break; + pItem = aIter.NextItem(); + } + } + else if( pPara->bResetAll ) + pNode->ResetAllAttr(); + else + pNode->ResetAttr( RES_PARATR_BEGIN, POOLATTR_END - 1 ); + } + else + pNode->ResetAllAttr(); + + if( aSet.Count() ) + { + pNode->LockModify(); + pNode->SetAttr( aSet ); + + if( !bLocked ) + pNode->UnlockModify(); + } + } + return TRUE; +} + +void SwDoc::RstTxtAttr(const SwPaM &rRg, BOOL bInclRefToxMark ) +{ + SwHistory* pHst = 0; + SwDataChanged aTmp( rRg, 0 ); + if( DoesUndo() ) + { + ClearRedo(); + SwUndoRstAttr* pUndo = new SwUndoRstAttr( rRg, RES_CHRFMT ); + pHst = pUndo->GetHistory(); + AppendUndo( pUndo ); + } + const SwPosition *pStt = rRg.Start(), *pEnd = rRg.End(); + ParaRstFmt aPara( pStt, pEnd, pHst ); + aPara.bInclRefToxMark = bInclRefToxMark; + GetNodes().ForEach( pStt->nNode.GetIndex(), pEnd->nNode.GetIndex()+1, + lcl_RstTxtAttr, &aPara ); + SetModified(); +} + +void SwDoc::ResetAttr( const SwPaM &rRg, BOOL bTxtAttr, + const SvUShortsSort* pAttrs ) +{ + SwPaM* pPam = (SwPaM*)&rRg; + BOOL bStopAttr = FALSE; + if( !bTxtAttr && pAttrs && pAttrs->Count() && + RES_TXTATR_END > (*pAttrs)[ 0 ] ) + bTxtAttr = TRUE; + + if( !rRg.HasMark() ) + { + SwTxtNode* pTxtNd = rRg.GetPoint()->nNode.GetNode().GetTxtNode(); + if( !pTxtNd ) + return ; + + pPam = new SwPaM( *rRg.GetPoint() ); + + SwIndex& rSt = pPam->GetPoint()->nContent; + USHORT nMkPos, nPtPos = rSt.GetIndex(); + const String& rStr = pTxtNd->GetTxt(); + + // JP 22.08.96: Sonderfall: steht der Crsr in einem URL-Attribut + // dann wird dessen Bereich genommen + const SwTxtAttr* pURLAttr; + if( pTxtNd->HasHints() && + 0 != ( pURLAttr = pTxtNd->GetTxtAttr( rSt, RES_TXTATR_INETFMT )) + && pURLAttr->GetINetFmt().GetValue().Len() ) + { + nMkPos = *pURLAttr->GetStart(); + nPtPos = *pURLAttr->GetEnd(); + } + else if( WordSelection::IsInWord( rStr, nPtPos ) && + !WordSelection::IsStartWord( rStr, nPtPos ) && + !WordSelection::IsEndWord( rStr, nPtPos ) && + USHRT_MAX != ( nMkPos = WordSelection::GoStartWord( rStr, nPtPos )) && + USHRT_MAX != ( nPtPos = WordSelection::GoEndWord( rStr, nPtPos )) ) + ; + else + { + nPtPos = nMkPos = rSt.GetIndex(); + if( bTxtAttr ) + pTxtNd->DontExpandFmt( rSt, TRUE ); + } + + rSt = nMkPos; + pPam->SetMark(); + pPam->GetPoint()->nContent = nPtPos; + } + + SwDataChanged aTmp( *pPam, 0 ); + SwHistory* pHst = 0; + if( DoesUndo() ) + { + ClearRedo(); + SwUndoRstAttr* pUndo = new SwUndoRstAttr( rRg, + bTxtAttr ? RES_CONDTXTFMTCOLL : RES_TXTFMTCOLL ); + if( pAttrs && pAttrs->Count() ) + pUndo->SetAttrs( *pAttrs ); + pHst = pUndo->GetHistory(); + AppendUndo( pUndo ); + } + + const SwPosition *pStt = pPam->Start(), *pEnd = pPam->End(); + ParaRstFmt aPara( pStt, pEnd, pHst ); + + SfxItemSet aDelSet( GetAttrPool(), aTxtNodeSetRange ); + if( pAttrs && pAttrs->Count() ) + { + for( USHORT n = pAttrs->Count(); n; ) + if( POOLATTR_END > (*pAttrs)[ --n ] ) + aDelSet.Put( *GetDfltAttr( (*pAttrs)[ n ] )); + + if( aDelSet.Count() ) + aPara.pDelSet = &aDelSet; + } + + BOOL bAdd = TRUE; + SwNodeIndex aTmpStt( pStt->nNode ); + SwNodeIndex aTmpEnd( pEnd->nNode ); + if( pStt->nContent.GetIndex() ) // nur ein Teil + { + // dann spaeter aufsetzen und alle CharFmtAttr -> TxtFmtAttr + SwTxtNode* pTNd = aTmpStt.GetNode().GetTxtNode(); + if( pTNd && pTNd->GetpSwAttrSet() && pTNd->GetpSwAttrSet()->Count() ) + { + SfxItemIter aIter( *pTNd->GetpSwAttrSet() ); + const SfxPoolItem* pItem = aIter.GetCurItem(); + while( TRUE ) + { + if( IsInRange( aCharFmtSetRange, pItem->Which() )) + { + SwTxtAttr* pTAttr = pTNd->MakeTxtAttr( *pItem, 0, + pTNd->GetTxt().Len() ); + if( !pTNd->pSwpHints ) + pTNd->pSwpHints = new SwpHints; + pTNd->pSwpHints->SwpHintsArr::Insert( pTAttr ); + + if( pHst ) + { + SwRegHistory aRegH( pTNd, *pTNd, pHst ); + pTNd->ResetAttr( pItem->Which() ); + pHst->Add( pTAttr, aTmpStt.GetIndex(), TRUE ); + } + else + pTNd->ResetAttr( pItem->Which() ); + } + if( aIter.IsAtEnd() ) + break; + pItem = aIter.NextItem(); + } + } + + aTmpStt++; + } + if( pEnd->nContent.GetIndex() == pEnd->nNode.GetNode().GetCntntNode()->Len() ) + // dann spaeter aufsetzen und alle CharFmtAttr -> TxtFmtAttr + aTmpEnd++, bAdd = FALSE; + else if( pStt->nNode != pEnd->nNode || !pStt->nContent.GetIndex() ) + { + SwTxtNode* pTNd = aTmpEnd.GetNode().GetTxtNode(); + if( pTNd && pTNd->GetpSwAttrSet() && pTNd->GetpSwAttrSet()->Count() ) + { + SfxItemIter aIter( *pTNd->GetpSwAttrSet() ); + const SfxPoolItem* pItem = aIter.GetCurItem(); + while( TRUE ) + { + if( IsInRange( aCharFmtSetRange, pItem->Which() )) + { + SwTxtAttr* pTAttr = pTNd->MakeTxtAttr( *pItem, 0, + pTNd->GetTxt().Len() ); + if( !pTNd->pSwpHints ) + pTNd->pSwpHints = new SwpHints; + pTNd->pSwpHints->SwpHintsArr::Insert( pTAttr ); + if( pHst ) + { + SwRegHistory aRegH( pTNd, *pTNd, pHst ); + pTNd->ResetAttr( pItem->Which() ); + pHst->Add( pTAttr, aTmpEnd.GetIndex(), TRUE ); + } + else + pTNd->ResetAttr( pItem->Which() ); + } + if( aIter.IsAtEnd() ) + break; + pItem = aIter.NextItem(); + } + } + } + + if( aTmpStt < aTmpEnd ) + GetNodes().ForEach( pStt->nNode, aTmpEnd, lcl_RstAttr, &aPara ); + else if( !rRg.HasMark() ) + { + aPara.bResetAll = FALSE; + ::lcl_RstAttr( aNodes[ pStt->nNode ], &aPara ); + aPara.bResetAll = TRUE; + } + + if( bTxtAttr ) + { + if( bAdd ) + aTmpEnd++; + GetNodes().ForEach( pStt->nNode, aTmpEnd, lcl_RstTxtAttr, &aPara ); + } + + if( pPam != &rRg ) + delete pPam; + + SetModified(); +} + + + +// Einfuegen der Hints nach Inhaltsformen; +// wird in SwDoc::Insert(..., SwFmtHint &rHt) benutzt + +BOOL InsAttr( SwDoc *pDoc, const SwPaM &rRg, const SfxItemSet& rChgSet, + USHORT nFlags, SwUndoAttr* pUndo ) +{ + // teil die Sets auf (fuer Selektion in Nodes) + SfxItemSet aCharSet( pDoc->GetAttrPool(), + RES_CHRATR_BEGIN, RES_CHRATR_END-1, + RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT, + RES_TXTATR_INETFMT, RES_TXTATR_INETFMT, + RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1, + 0 ); + SfxItemSet aOtherSet( pDoc->GetAttrPool(), + RES_PARATR_BEGIN, RES_PARATR_END-1, + RES_FRMATR_BEGIN, RES_FRMATR_END-1, + RES_GRFATR_BEGIN, RES_GRFATR_END-1, + 0 ); + + aCharSet.Put( rChgSet ); + aOtherSet.Put( rChgSet ); + + SwHistory* pHistory = pUndo ? pUndo->GetHistory() : 0; + BOOL bRet = FALSE; + const SwPosition *pStt = rRg.Start(), *pEnd = rRg.End(); + SwCntntNode* pNode = pStt->nNode.GetNode().GetCntntNode(); + + if( pNode && pNode->IsTxtNode() ) + { + const SwIndex& rSt = pStt->nContent; + + // Attribute ohne Ende haben keinen Bereich + { + SfxItemSet aTxtSet( pDoc->GetAttrPool(), + RES_TXTATR_NOEND_BEGIN, RES_TXTATR_NOEND_END-1 ); + aTxtSet.Put( rChgSet ); + if( aTxtSet.Count() ) + { + SwRegHistory( (SwTxtNode*)pNode, aTxtSet, rSt.GetIndex(), + rSt.GetIndex(), nFlags, pHistory ); + bRet = TRUE; + + if( pDoc->IsRedlineOn() || (!pDoc->IsIgnoreRedline() && + pDoc->GetRedlineTbl().Count() )) + { + SwPaM aPam( pStt->nNode, pStt->nContent.GetIndex()-1, + pStt->nNode, pStt->nContent.GetIndex() ); + + if( pUndo ) + pUndo->SaveRedlineData( aPam, TRUE ); + + if( pDoc->IsRedlineOn() ) + pDoc->AppendRedline( new SwRedline( REDLINE_INSERT, aPam )); + else + pDoc->SplitRedline( aPam ); + } + } + } + + // TextAttribute mit Ende expandieren nie ihren Bereich + { + // CharFnt wird gesondert behandelt !!! + // JP 22.08.96: URL-Attribute auch!! + SfxItemSet aTxtSet( pDoc->GetAttrPool(), + RES_TXTATR_DUMMY4, + // RES_TXTATR_REFMARK, + RES_TXTATR_TOXMARK ); + + aTxtSet.Put( rChgSet ); + if( aTxtSet.Count() ) + { + USHORT nInsCnt = rSt.GetIndex(); + USHORT nEnd = pStt->nNode == pEnd->nNode + ? pEnd->nContent.GetIndex() + : pNode->Len(); + SwRegHistory( (SwTxtNode*)pNode, aTxtSet, nInsCnt, + nEnd, nFlags, pHistory ); + bRet = TRUE; + + if( pDoc->IsRedlineOn() || (!pDoc->IsIgnoreRedline() && + pDoc->GetRedlineTbl().Count() ) ) + { + // wurde Text-Inhalt eingefuegt? (RefMark/TOXMarks ohne Ende) + BOOL bTxtIns = nInsCnt != rSt.GetIndex(); + // wurde Inhalt eingefuegt oder ueber die Selektion gesetzt? + SwPaM aPam( pStt->nNode, bTxtIns ? nInsCnt + 1 : nEnd, + pStt->nNode, nInsCnt ); + if( pUndo ) + pUndo->SaveRedlineData( aPam, bTxtIns ); + + if( pDoc->IsRedlineOn() ) + pDoc->AppendRedline( new SwRedline( bTxtIns + ? REDLINE_INSERT : REDLINE_FORMAT, aPam )); + else if( bTxtIns ) + pDoc->SplitRedline( aPam ); + } + } + } + } + + // bei PageDesc's, die am Node gesetzt werden, muss immer das + // Auto-Flag gesetzt werden!! + const SvxLRSpaceItem* pLRSpace = 0; + if( aOtherSet.Count() ) + { + SwTableNode* pTblNd; + const SwFmtPageDesc* pDesc; + if( SFX_ITEM_SET == aOtherSet.GetItemState( RES_PAGEDESC, + FALSE, (const SfxPoolItem**)&pDesc )) + { + if( pNode ) + { + // Auto-Flag setzen, nur in Vorlagen ist ohne Auto ! + SwFmtPageDesc aNew( *pDesc ); + // Bug 38479: AutoFlag wird jetzt in der WrtShell gesetzt + // aNew.SetAuto(); + + // Tabellen kennen jetzt auch Umbrueche + if( 0 != ( pTblNd = pNode->FindTableNode() ) ) + { + // dann am Tabellen Format setzen + SwFrmFmt* pFmt = pTblNd->GetTable().GetFrmFmt(); + SwRegHistory aRegH( pFmt, *pTblNd, pHistory ); + pFmt->SetAttr( aNew ); + } + else + { + SwRegHistory aRegH( pNode, *pNode, pHistory ); + pNode->SetAttr( aNew ); + } + } + aOtherSet.ClearItem( RES_PAGEDESC ); + if( !aOtherSet.Count() ) + return TRUE; + } + + // Tabellen kennen jetzt auch Umbrueche + const SvxFmtBreakItem* pBreak; + if( pNode && 0 != (pTblNd = pNode->FindTableNode() ) && + SFX_ITEM_SET == aOtherSet.GetItemState( RES_BREAK, + FALSE, (const SfxPoolItem**)&pBreak ) ) + { + // dann am Tabellen Format setzen + SwFrmFmt* pFmt = pTblNd->GetTable().GetFrmFmt(); + SwRegHistory aRegH( pFmt, *pTblNd, pHistory ); + pFmt->SetAttr( *pBreak ); + + aOtherSet.ClearItem( RES_BREAK ); + if( !aOtherSet.Count() ) + return TRUE; + } + + // fuer Sonderbehandlung von LR-Space innerhalb einer Numerierung !!! + aOtherSet.GetItemState( RES_LR_SPACE, FALSE, + (const SfxPoolItem**)&pLRSpace ); + + { + // wenns eine PoolNumRule ist, diese ggfs. anlegen + const SwNumRuleItem* pRule; + USHORT nPoolId; + if( SFX_ITEM_SET == aOtherSet.GetItemState( RES_PARATR_NUMRULE, + FALSE, (const SfxPoolItem**)&pRule ) && + !pDoc->FindNumRulePtr( pRule->GetValue() ) && + USHRT_MAX != (nPoolId = pDoc->GetPoolId( pRule->GetValue(), + GET_POOLID_NUMRULE )) ) + pDoc->GetNumRuleFromPool( nPoolId ); + } + + } + + if( !rRg.HasMark() ) // kein Bereich + { + if( !pNode ) + return bRet; + + if( pNode->IsTxtNode() && aCharSet.Count() ) + { + SwTxtNode* pTxtNd = (SwTxtNode*)pNode; + const SwIndex& rSt = pStt->nContent; + USHORT nMkPos, nPtPos = rSt.GetIndex(); + const String& rStr = pTxtNd->GetTxt(); + + // JP 22.08.96: Sonderfall: steht der Crsr in einem URL-Attribut + // dann wird dessen Bereich genommen + const SwTxtAttr* pURLAttr; + if( pTxtNd->HasHints() && + 0 != ( pURLAttr = pTxtNd->GetTxtAttr( rSt, RES_TXTATR_INETFMT )) + && pURLAttr->GetINetFmt().GetValue().Len() ) + { + nMkPos = *pURLAttr->GetStart(); + nPtPos = *pURLAttr->GetEnd(); + } + else if( WordSelection::IsInWord( rStr, nPtPos ) && + !WordSelection::IsStartWord( rStr, nPtPos ) && + !WordSelection::IsEndWord( rStr, nPtPos ) && + USHRT_MAX != ( nMkPos = WordSelection::GoStartWord( rStr, nPtPos )) && + USHRT_MAX != ( nPtPos = WordSelection::GoEndWord( rStr, nPtPos )) ) + ; + else + nPtPos = nMkPos = rSt.GetIndex(); + + // erstmal die zu ueberschreibenden Attribute aus dem + // SwpHintsArray entfernen, wenn die Selektion den gesamten + // Absatz umspannt. (Diese Attribute werden als FormatAttr. + // eingefuegt und verdraengen nie die TextAttr.!) + if( !(nFlags & SETATTR_DONTREPLACE ) && + pTxtNd->HasHints() && !nMkPos && nPtPos == rStr.Len() ) + { + SwIndex aSt( pTxtNd ); + if( pHistory ) + { + // fuers Undo alle Attribute sichern + SwRegHistory aRHst( *pTxtNd, pHistory ); + pTxtNd->GetpSwpHints()->Register( &aRHst ); + pTxtNd->RstAttr( aSt, nPtPos, 0, &aCharSet ); + if( pTxtNd->GetpSwpHints() ) + pTxtNd->GetpSwpHints()->DeRegister(); + } + else + pTxtNd->RstAttr( aSt, nPtPos, 0, &aCharSet ); + } + + // eintragen des Attributes im Node erledigt die SwRegHistory !! + SwRegHistory( (SwTxtNode*)pNode, aCharSet, + nMkPos, nPtPos, nFlags, pHistory ); + bRet = TRUE; + + if( pDoc->IsRedlineOn() ) + { + SwPaM aPam( *pNode, nMkPos, *pNode, nPtPos ); + + if( pUndo ) + pUndo->SaveRedlineData( aPam, FALSE ); + pDoc->AppendRedline( new SwRedline( REDLINE_FORMAT, aPam )); + } + } + if( aOtherSet.Count() ) + { + SwRegHistory aRegH( pNode, *pNode, pHistory ); + pNode->SetAttr( aOtherSet ); + bRet = TRUE; + } + return bRet; + } + + if( pDoc->IsRedlineOn() && aCharSet.Count() ) + { + if( pUndo ) + pUndo->SaveRedlineData( rRg, FALSE ); + pDoc->AppendRedline( new SwRedline( REDLINE_FORMAT, rRg )); + } + + /* jetzt wenn Bereich */ + ULONG nNodes = 0; + + SwNodeIndex aSt( pDoc->GetNodes() ); + SwNodeIndex aEnd( pDoc->GetNodes() ); + SwIndex aCntEnd( pEnd->nContent ); + + if( pNode ) + { + USHORT nLen = pNode->Len(); + if( pStt->nNode != pEnd->nNode ) + aCntEnd.Assign( pNode, nLen ); + + if( pStt->nContent.GetIndex() != 0 || aCntEnd.GetIndex() != nLen ) + { + // eintragen des Attributes im Node erledigt die SwRegHistory !! + if( pNode->IsTxtNode() && aCharSet.Count() ) + { + SwRegHistory( (SwTxtNode*)pNode, aCharSet, + pStt->nContent.GetIndex(), aCntEnd.GetIndex(), + nFlags, pHistory ); + } + + if( aOtherSet.Count() ) + { + SwRegHistory aRegH( pNode, *pNode, pHistory ); + pNode->SetAttr( aOtherSet ); + } + + // lediglich Selektion in einem Node. + if( pStt->nNode == pEnd->nNode ) + return TRUE; + ++nNodes; + aSt.Assign( pStt->nNode.GetNode(), +1 ); + } + else + aSt = pStt->nNode; + aCntEnd = pEnd->nContent; // aEnd wurde veraendert !! + } + else + aSt.Assign( pStt->nNode.GetNode(), +1 ); + + // aSt zeigt jetzt auf den ersten vollen Node + + /* + * die Selektion umfasst mehr als einen Node + */ + if( pStt->nNode < pEnd->nNode ) + { + pNode = pEnd->nNode.GetNode().GetCntntNode(); + if(pNode) + { + USHORT nLen = pNode->Len(); + if( aCntEnd.GetIndex() != nLen ) + { + // eintragen des Attributes im Node erledigt die SwRegHistory !! + if( pNode->IsTxtNode() && aCharSet.Count() ) + { + SwRegHistory( (SwTxtNode*)pNode, aCharSet, + 0, aCntEnd.GetIndex(), nFlags, pHistory ); + } + + if( aOtherSet.Count() ) + { + SwRegHistory aRegH( pNode, *pNode, pHistory ); + pNode->SetAttr( aOtherSet ); + } + + ++nNodes; + aEnd = pEnd->nNode; + } + else + aEnd.Assign( pEnd->nNode.GetNode(), +1 ); + } + else + aEnd = pEnd->nNode; + } + else + aEnd.Assign( pEnd->nNode.GetNode(), +1 ); + + // aEnd zeigt jetzt HINTER den letzten voll Node + + /* Bearbeitung der vollstaendig selektierten Nodes. */ +// alle Attribute aus dem Set zuruecksetzen !! + if( aCharSet.Count() && !( SETATTR_DONTREPLACE & nFlags ) ) + { + + ParaRstFmt aPara( pStt, pEnd, pHistory, 0, &aCharSet ); + pDoc->GetNodes().ForEach( aSt, aEnd, lcl_RstTxtAttr, &aPara ); + } + +#ifdef USED +//JP 30.10.96: siehe unten + // sollte ueber mehrere Nodes das SwFmtChrFmt gesetzt werden ?? + const SfxPoolItem* pChrFmtItem = 0; + aCharSet.GetItemState( RES_TXTATR_CHARFMT, FALSE, &pChrFmtItem ); +#endif + BOOL bCreateSwpHints = + SFX_ITEM_SET == aCharSet.GetItemState( RES_TXTATR_CHARFMT, FALSE ) || + SFX_ITEM_SET == aCharSet.GetItemState( RES_TXTATR_INETFMT, FALSE ); + + for(; aSt < aEnd; aSt++ ) + { + pNode = aSt.GetNode().GetCntntNode(); + if( !pNode ) + continue; + + SwTxtNode* pTNd = pNode->GetTxtNode(); + if( pHistory ) + { + SwRegHistory aRegH( pNode, *pNode, pHistory ); + SwpHints *pSwpHints; + +#ifdef USED +//JP 30.10.96: Das loeschen der Zeichen erledigt schon das SwpHints-Array +// Warum dann hier doppelt? +// !! Ausserdem ist die Sonderbehandlung fuer die +// !! Zeichenvorlage/INetAttribut falsch + + // loesche alle Text-Attribute, die durch den Set "ersetzt" werden + if( pTNd && 0 != ( pSwpHints = pTNd->GetpSwpHints() ) && + pSwpHints->Count() ) + { + pSwpHints->Register( &aRegH ); + + for( USHORT n = pSwpHints->Count(); n; ) + { + SwTxtAttr* pAttr = pSwpHints->GetHt( --n ); + if( !pAttr->GetEnd() || RES_CHRATR_END <= pAttr->Which() ) + continue; + if( pChrFmtItem || SFX_ITEM_SET == + aCharSet.GetItemState( pAttr->Which() ) ) + { + pTNd->Delete( pAttr, TRUE ); + if( !pTNd->GetpSwpHints() ) + { + pSwpHints = 0; + break; + } + } + } + if( pSwpHints ) + pSwpHints->DeRegister(); + } +#endif + if( pTNd && aCharSet.Count() ) + { + pSwpHints = bCreateSwpHints ? &pTNd->GetOrCreateSwpHints() + : pTNd->GetpSwpHints(); + if( pSwpHints ) + pSwpHints->Register( &aRegH ); + + pTNd->SetAttr( aCharSet, 0, pTNd->GetTxt().Len(), nFlags ); + if( pSwpHints ) + pSwpHints->DeRegister(); + } + if( aOtherSet.Count() ) + pNode->SetAttr( aOtherSet ); + } + else + { + if( pTNd && aCharSet.Count() ) + pTNd->SetAttr( aCharSet, 0, pTNd->GetTxt().Len(), nFlags ); + if( aOtherSet.Count() ) + pNode->SetAttr( aOtherSet ); + } + ++nNodes; + } + + return nNodes != 0; +} + + +BOOL SwDoc::Insert( const SwPaM &rRg, const SfxPoolItem &rHt, USHORT nFlags ) +{ + SwDataChanged aTmp( rRg, 0 ); + BOOL bRet; + SwUndoAttr* pUndoAttr = 0; + if( DoesUndo() ) + { + ClearRedo(); + pUndoAttr = new SwUndoAttr( rRg, rHt, nFlags ); + } + + SfxItemSet aSet( GetAttrPool(), rHt.Which(), rHt.Which() ); + aSet.Put( rHt ); + bRet = InsAttr( this, rRg, aSet, nFlags, pUndoAttr ); + +/* if( INSATTR_DONTEXPAND & nFlags ) + { + USHORT nWhich = rHt.Which(); + const SwPosition* pPos = rRg.End(); + SwTxtNode* pTxtNd = GetNodes()[ pPos->nNode ]->GetTxtNode(); + SwpHints* pHts; + if( pTxtNd && 0 != ( pHts = pTxtNd->GetpSwpHints()) ) + { + USHORT nPos = pHts->GetEndCount(); + while( nPos ) + { + SwTxtAttr *pTmp = pHts->GetEnd( --nPos ); + USHORT *pEnd = pTmp->GetEnd(); + if( !pEnd || *pEnd > nEnd ) + continue; + if( nEnd != *pEnd ) + nPos = 0; + else if( nWhich == pTmp->Which() ) + pTmp->SetDontExpand( TRUE ); + } + } + } +*/ + if( DoesUndo() ) + AppendUndo( pUndoAttr ); + + if( bRet ) + SetModified(); + return bRet; +} + +BOOL SwDoc::Insert( const SwPaM &rRg, const SfxItemSet &rSet, USHORT nFlags ) +{ + SwDataChanged aTmp( rRg, 0 ); + SwUndoAttr* pUndoAttr = 0; + if( DoesUndo() ) + { + ClearRedo(); + pUndoAttr = new SwUndoAttr( rRg, rSet ); + } + + BOOL bRet = InsAttr( this, rRg, rSet, nFlags, pUndoAttr ); + + if( DoesUndo() ) + AppendUndo( pUndoAttr ); + + if( bRet ) + SetModified(); + return bRet; +} + + + // Setze das Attribut im angegebenen Format. Ist Undo aktiv, wird + // das alte in die Undo-History aufgenommen +void SwDoc::SetAttr( const SfxPoolItem& rAttr, SwFmt& rFmt ) +{ + SfxItemSet aSet( GetAttrPool(), rAttr.Which(), rAttr.Which() ); + aSet.Put( rAttr ); + SetAttr( aSet, rFmt ); +} + + + // Setze das Attribut im angegebenen Format. Ist Undo aktiv, wird + // das alte in die Undo-History aufgenommen +void SwDoc::SetAttr( const SfxItemSet& rSet, SwFmt& rFmt ) +{ + if( DoesUndo() ) + { + ClearRedo(); + _UndoFmtAttr aTmp( rFmt ); + rFmt.SetAttr( rSet ); + if( aTmp.pUndo ) + AppendUndo( aTmp.pUndo ); + } + else + rFmt.SetAttr( rSet ); + SetModified(); +} + +int lcl_SetNewDefTabStops( SwTwips nOldWidth, SwTwips nNewWidth, + SvxTabStopItem& rChgTabStop ) +{ + // dann aender bei allen TabStop die default's auf den neuen Wert + // !!! Achtung: hier wird immer auf dem PoolAttribut gearbeitet, + // damit nicht in allen Sets die gleiche Berechnung + // auf dem gleichen TabStop (gepoolt!) vorgenommen + // wird. Als Modify wird ein FmtChg verschickt. + + USHORT nOldCnt = rChgTabStop.Count(); + if( !nOldCnt || nOldWidth == nNewWidth ) + return FALSE; + + // suche den Anfang der Defaults + SvxTabStop* pTabs = ((SvxTabStop*)rChgTabStop.GetStart()) + + (nOldCnt-1); + for( USHORT n = nOldCnt; n ; --n, --pTabs ) + if( SVX_TAB_ADJUST_DEFAULT != pTabs->GetAdjustment() ) + break; + ++n; + if( n < nOldCnt ) // die DefTabStops loeschen + rChgTabStop.Remove( n, nOldCnt - n ); + return TRUE; +} + + // Setze das Attribut als neues default Attribut in diesem Dokument. + // Ist Undo aktiv, wird das alte in die Undo-History aufgenommen +void SwDoc::SetDefault( const SfxPoolItem& rAttr ) +{ + SfxItemSet aSet( GetAttrPool(), rAttr.Which(), rAttr.Which() ); + aSet.Put( rAttr ); + SetDefault( aSet ); +} + +void SwDoc::SetDefault( const SfxItemSet& rSet ) +{ + if( !rSet.Count() ) + return; + + SwModify aCallMod( 0 ); + SwAttrSet aOld( GetAttrPool(), rSet.GetRanges() ), + aNew( GetAttrPool(), rSet.GetRanges() ); + SfxItemIter aIter( rSet ); + register USHORT nWhich; + const SfxPoolItem* pItem = aIter.GetCurItem(); + while( TRUE ) + { + nWhich = pItem->Which(); + aOld.Put( GetAttrPool().GetDefaultItem( nWhich ) ); + GetAttrPool().SetPoolDefaultItem( *pItem ); + aNew.Put( GetAttrPool().GetDefaultItem( nWhich ) ); + + if( RES_CHRATR_BEGIN <= nWhich && RES_TXTATR_END > nWhich ) + { + aCallMod.Add( pDfltTxtFmtColl ); + aCallMod.Add( pDfltCharFmt ); + } + else if( RES_PARATR_BEGIN <= nWhich && RES_PARATR_END > nWhich ) + aCallMod.Add( pDfltTxtFmtColl ); + else if( RES_GRFATR_BEGIN <= nWhich && RES_GRFATR_END > nWhich ) + aCallMod.Add( pDfltGrfFmtColl ); + else if( RES_FRMATR_BEGIN <= nWhich && RES_FRMATR_END > nWhich ) + { + aCallMod.Add( pDfltGrfFmtColl ); + aCallMod.Add( pDfltTxtFmtColl ); + aCallMod.Add( pDfltFrmFmt ); + } + else if( RES_BOXATR_BEGIN <= nWhich && RES_BOXATR_END > nWhich ) + aCallMod.Add( pDfltFrmFmt ); + if( aIter.IsAtEnd() ) + break; + pItem = aIter.NextItem(); + } + + if( aNew.Count() && aCallMod.GetDepends() ) + { + if( DoesUndo() ) + { + ClearRedo(); + AppendUndo( new SwUndoDefaultAttr( aOld ) ); + } + + const SfxPoolItem* pItem; + if( aNew.GetItemState( RES_PARATR_TABSTOP, FALSE, &pItem ) && + ((SvxTabStopItem*)pItem)->Count() ) + { + // TabStop-Aenderungen behandeln wir erstmal anders: + // dann aender bei allen TabStop die dafault's auf den neuen Wert + // !!! Achtung: hier wird immer auf dem PoolAttribut gearbeitet, + // damit nicht in allen Sets die gleiche Berechnung + // auf dem gleichen TabStop (gepoolt!) vorgenommen + // wird. Als Modify wird ein FmtChg verschickt. + SwTwips nNewWidth = (*(SvxTabStopItem*)pItem)[ 0 ].GetTabPos(), + nOldWidth = ((SvxTabStopItem&)aOld.Get(RES_PARATR_TABSTOP))[ 0 ].GetTabPos(); + + int bChg = FALSE; + USHORT nMaxItems = GetAttrPool().GetItemCount( RES_PARATR_TABSTOP ); + for( USHORT n = 0; n < nMaxItems; ++n ) + if( 0 != (pItem = GetAttrPool().GetItem( RES_PARATR_TABSTOP, n ) )) + bChg |= lcl_SetNewDefTabStops( nOldWidth, nNewWidth, + *(SvxTabStopItem*)pItem ); + + aNew.ClearItem( RES_PARATR_TABSTOP ); + aOld.ClearItem( RES_PARATR_TABSTOP ); + if( bChg ) + { + SwFmtChg aChgFmt( pDfltCharFmt ); + // dann sage mal den Frames bescheid + aCallMod.Modify( &aChgFmt, &aChgFmt ); + } + } + } + + if( aNew.Count() && aCallMod.GetDepends() ) + { + SwAttrSetChg aChgOld( aOld, aOld ); + SwAttrSetChg aChgNew( aNew, aNew ); + aCallMod.Modify( &aChgOld, &aChgNew ); // alle veraenderten werden verschickt + } + + // und die default-Formate wieder beim Object austragen + SwClient* pDep; + while( 0 != ( pDep = (SwClient*)aCallMod.GetDepends()) ) + aCallMod.Remove( pDep ); + + SetModified(); +} + + // Erfrage das Default Attribut in diesem Dokument. +const SfxPoolItem& SwDoc::GetDefault( USHORT nFmtHint ) const +{ + return GetAttrPool().GetDefaultItem( nFmtHint ); +} + +/* + * Loeschen der Formate + */ +void SwDoc::DelCharFmt(USHORT nFmt) +{ + pCharFmtTbl->DeleteAndDestroy(nFmt); + SetModified(); +} + +void SwDoc::DelCharFmt( SwCharFmt *pFmt ) +{ + USHORT nFmt = pCharFmtTbl->GetPos( pFmt ); + ASSERT( USHRT_MAX != nFmt, "Fmt not found," ); + DelCharFmt( nFmt ); +} + +void SwDoc::DelFrmFmt( SwFrmFmt *pFmt ) +{ + if( pFmt->ISA( SwTableBoxFmt ) || pFmt->ISA( SwTableLineFmt )) + { + ASSERT( !this, "Format steht nicht mehr im DocArray, " + "kann per delete geloescht werden" ); + delete pFmt; + } + else + { + //Das Format muss in einem der beiden Arrays stehen, in welchem + //werden wir schon merken. + USHORT nPos; + if ( USHRT_MAX != ( nPos = pFrmFmtTbl->GetPos( pFmt )) ) + pFrmFmtTbl->DeleteAndDestroy( nPos ); + else + { + nPos = GetSpzFrmFmts()->GetPos( pFmt ); + ASSERT( nPos != USHRT_MAX, "FrmFmt not found." ); + if( USHRT_MAX != nPos ) + GetSpzFrmFmts()->DeleteAndDestroy( nPos ); + } + } +} + +void SwDoc::DelTblFrmFmt( SwTableFmt *pFmt ) +{ + USHORT nPos = pTblFrmFmtTbl->GetPos( pFmt ); + ASSERT( USHRT_MAX != nPos, "Fmt not found," ); + pTblFrmFmtTbl->DeleteAndDestroy( nPos ); +} + +/* + * Erzeugen der Formate + */ +SwFlyFrmFmt *SwDoc::MakeFlyFrmFmt( const String &rFmtName, + SwFrmFmt *pDerivedFrom ) +{ + SwFlyFrmFmt *pFmt = new SwFlyFrmFmt( GetAttrPool(), rFmtName, pDerivedFrom ); + GetSpzFrmFmts()->Insert(pFmt, GetSpzFrmFmts()->Count()); + SetModified(); + return pFmt; +} + +SwDrawFrmFmt *SwDoc::MakeDrawFrmFmt( const String &rFmtName, + SwFrmFmt *pDerivedFrom ) +{ + SwDrawFrmFmt *pFmt = new SwDrawFrmFmt( GetAttrPool(), rFmtName, pDerivedFrom); + GetSpzFrmFmts()->Insert(pFmt,GetSpzFrmFmts()->Count()); + SetModified(); + return pFmt; +} + + +USHORT SwDoc::GetTblFrmFmtCount(BOOL bUsed) const +{ + USHORT nCount = pTblFrmFmtTbl->Count(); + if(bUsed) + { + SwAutoFmtGetDocNode aGetHt( &aNodes ); + for ( USHORT i = nCount; i; ) + { + if((*pTblFrmFmtTbl)[--i]->GetInfo( aGetHt )) + --nCount; + } + } + return nCount; +} + + +SwFrmFmt& SwDoc::GetTblFrmFmt(USHORT nFmt, BOOL bUsed ) const +{ + USHORT nRemoved = 0; + if(bUsed) + { + SwAutoFmtGetDocNode aGetHt( &aNodes ); + for ( USHORT i = 0; i <= nFmt; i++ ) + { + while ( (*pTblFrmFmtTbl)[ i + nRemoved]->GetInfo( aGetHt )) + { + nRemoved++; + } + } + } + return *((*pTblFrmFmtTbl)[nRemoved + nFmt]); +} + +SwTableFmt* SwDoc::MakeTblFrmFmt( const String &rFmtName, + SwFrmFmt *pDerivedFrom ) +{ + SwTableFmt* pFmt = new SwTableFmt( GetAttrPool(), rFmtName, pDerivedFrom ); + pTblFrmFmtTbl->Insert( pFmt, pTblFrmFmtTbl->Count() ); + SetModified(); + return pFmt; +} + +SwFrmFmt *SwDoc::MakeFrmFmt(const String &rFmtName, + SwFrmFmt *pDerivedFrom) +{ + SwFrmFmt *pFmt = new SwFrmFmt( GetAttrPool(), rFmtName, pDerivedFrom ); + pFrmFmtTbl->Insert( pFmt, pFrmFmtTbl->Count()); + SetModified(); + return pFmt; +} + +SwCharFmt *SwDoc::MakeCharFmt( const String &rFmtName, + SwCharFmt *pDerivedFrom) +{ + SwCharFmt *pFmt = new SwCharFmt( GetAttrPool(), rFmtName, pDerivedFrom ); + pCharFmtTbl->Insert( pFmt, pCharFmtTbl->Count() ); + pFmt->SetAuto( FALSE ); + SetModified(); + return pFmt; +} + + +/* + * Erzeugen der FormatCollections + */ +// TXT + +SwTxtFmtColl* SwDoc::MakeTxtFmtColl( const String &rFmtName, + SwTxtFmtColl *pDerivedFrom) +{ + SwTxtFmtColl *pFmtColl = new SwTxtFmtColl( GetAttrPool(), rFmtName, + pDerivedFrom ); + pTxtFmtCollTbl->Insert(pFmtColl, pTxtFmtCollTbl->Count()); + pFmtColl->SetAuto( FALSE ); + SetModified(); + return pFmtColl; +} + +//FEATURE::CONDCOLL +SwConditionTxtFmtColl* SwDoc::MakeCondTxtFmtColl( const String &rFmtName, + SwTxtFmtColl *pDerivedFrom ) +{ + SwConditionTxtFmtColl*pFmtColl = new SwConditionTxtFmtColl( GetAttrPool(), + rFmtName, pDerivedFrom ); + pTxtFmtCollTbl->Insert(pFmtColl, pTxtFmtCollTbl->Count()); + pFmtColl->SetAuto( FALSE ); + SetModified(); + return pFmtColl; +} +//FEATURE::CONDCOLL + +// GRF + +SwGrfFmtColl* SwDoc::MakeGrfFmtColl( const String &rFmtName, + SwGrfFmtColl *pDerivedFrom ) +{ + SwGrfFmtColl *pFmtColl = new SwGrfFmtColl( GetAttrPool(), rFmtName, + pDerivedFrom ); + pGrfFmtCollTbl->Insert( pFmtColl, pGrfFmtCollTbl->Count() ); + pFmtColl->SetAuto( FALSE ); + SetModified(); + return pFmtColl; +} + +void SwDoc::DelTxtFmtColl(USHORT nFmtColl) +{ + ASSERT( nFmtColl, "Remove fuer Coll 0." ); + + // Wer hat die zu loeschende als Next + SwTxtFmtColl *pDel = (*pTxtFmtCollTbl)[nFmtColl]; + if( pDfltTxtFmtColl == pDel ) + return; // default nie loeschen !! + // Die FmtColl austragen + pTxtFmtCollTbl->Remove(nFmtColl); + // Next korrigieren + pTxtFmtCollTbl->ForEach( 1, pTxtFmtCollTbl->Count(), + &SetTxtFmtCollNext, pDel ); + delete pDel; + SetModified(); +} + +void SwDoc::DelTxtFmtColl( SwTxtFmtColl *pColl ) +{ + USHORT nFmt = pTxtFmtCollTbl->GetPos( pColl ); + ASSERT( USHRT_MAX != nFmt, "Collection not found," ); + DelTxtFmtColl( nFmt ); +} + +void SwDoc::DelGrfFmtColl(USHORT nFmtColl) +{ + ASSERT( nFmtColl, "Remove fuer Coll 0." ); + + // Wer hat die zu loeschende als Next + SwGrfFmtColl *pDel = (*pGrfFmtCollTbl)[nFmtColl]; + if( pDfltGrfFmtColl == pDel ) + return; // default nie loeschen !! + // Die FmtColl austragen + pGrfFmtCollTbl->Remove(nFmtColl); + delete pDel; + SetModified(); +} + +void SwDoc::DelGrfFmtColl( SwGrfFmtColl *pColl ) +{ + USHORT nFmt = pGrfFmtCollTbl->GetPos( pColl ); + ASSERT( USHRT_MAX != nFmt, "Collection not found," ); + DelGrfFmtColl( nFmt ); +} + +BOOL lcl_SetTxtFmtColl( const SwNodePtr& rpNode, void* pArgs ) +{ + // ParaSetFmtColl * pPara = (ParaSetFmtColl*)pArgs; + SwCntntNode* pCNd = (SwCntntNode*)rpNode->GetTxtNode(); + if( pCNd ) + { + ParaRstFmt* pPara = (ParaRstFmt*)pArgs; + if ( pPara->bReset ) + lcl_RstAttr( pCNd, pPara ); + + // erst in die History aufnehmen, damit ggfs. alte Daten + // gesichert werden koennen + if( pPara->pHistory ) + pPara->pHistory->Add( pCNd->GetFmtColl(), pCNd->GetIndex(), + ND_TEXTNODE ); + + pCNd->ChgFmtColl( pPara->pFmtColl ); + pPara->nWhich++; + } + return TRUE; +} + +BOOL SwDoc::SetTxtFmtColl(const SwPaM &rRg, SwTxtFmtColl *pFmt, BOOL bReset) +{ + SwDataChanged aTmp( rRg, 0 ); + const SwPosition *pStt = rRg.Start(), *pEnd = rRg.End(); + SwHistory* pHst = 0; + BOOL bRet = TRUE; + if( DoesUndo() ) + { + ClearRedo(); + SwUndoFmtColl* pUndo = new SwUndoFmtColl( rRg, pFmt ); + pHst = pUndo->GetHistory(); + AppendUndo( pUndo ); + } + + if( rRg.HasMark() ) + { + ParaRstFmt aPara( pStt, pEnd, pHst ); + aPara.pFmtColl = pFmt; + aPara.bReset = bReset; + GetNodes().ForEach( pStt->nNode.GetIndex(), pEnd->nNode.GetIndex()+1, + lcl_SetTxtFmtColl, &aPara ); + if( !aPara.nWhich ) + bRet = FALSE; // keinen gueltigen Node gefunden + } + else + { + // ein enzelner Node: + SwCntntNode* pCNd = rRg.GetPoint()->nNode.GetNode().GetCntntNode(); + if( pCNd ) + { + if( bReset && pCNd->GetpSwAttrSet() ) + { + ParaRstFmt aPara( pHst ); + aPara.pFmtColl = pFmt; + lcl_RstAttr( pCNd, &aPara ); + } + + // erst in die History aufnehmen, damit ggfs. alte Daten + // gesichert werden koennen + if( pHst ) + pHst->Add( pCNd->GetFmtColl(), pCNd->GetIndex(), ND_TEXTNODE ); + pCNd->ChgFmtColl( pFmt ); + } + else + bRet = FALSE; + } + + if( bRet ) + SetModified(); + return bRet; +} + + +// ---- Kopiere die Formate in sich selbst (SwDoc) ---------------------- + +SwFmt* SwDoc::CopyFmt( const SwFmt& rFmt, + const SvPtrarr& rFmtArr, + FNCopyFmt fnCopyFmt, const SwFmt& rDfltFmt ) +{ + // kein-Autoformat || default Format || Collection-Format + // dann suche danach. + if( !rFmt.IsAuto() || !rFmt.GetRegisteredIn() ) + for( USHORT n = 0; n < rFmtArr.Count(); n++ ) + { + // ist die Vorlage schon im Doc vorhanden ?? + if( ((SwFmt*)rFmtArr[n])->GetName().Equals( rFmt.GetName() )) + return (SwFmt*)rFmtArr[n]; + } + + // suche erstmal nach dem "Parent" + SwFmt* pParent = (SwFmt*)&rDfltFmt; + if( rFmt.DerivedFrom() && pParent != rFmt.DerivedFrom() ) + pParent = CopyFmt( *rFmt.DerivedFrom(), rFmtArr, + fnCopyFmt, rDfltFmt ); + + // erzeuge das Format und kopiere die Attribute + SwFmt* pNewFmt = (this->*fnCopyFmt)( rFmt.GetName(), pParent ); + pNewFmt->SetAuto( rFmt.IsAuto() ); + pNewFmt->CopyAttrs( rFmt, TRUE ); // kopiere Attribute + + pNewFmt->SetPoolFmtId( rFmt.GetPoolFmtId() ); + pNewFmt->SetPoolHelpId( rFmt.GetPoolHelpId() ); + + // HelpFile-Id immer auf dflt setzen !! + pNewFmt->SetPoolHlpFileId( UCHAR_MAX ); + + return pNewFmt; +} + +// ---- kopiere das Frame-Format -------- +SwFrmFmt* SwDoc::CopyFrmFmt( const SwFrmFmt& rFmt ) +{ + return (SwFrmFmt*)CopyFmt( rFmt, *GetFrmFmts(), + (FNCopyFmt)&SwDoc::MakeFrmFmt, + *GetDfltFrmFmt() ); +} + +// ---- kopiere das Char-Format -------- +SwCharFmt* SwDoc::CopyCharFmt( const SwCharFmt& rFmt ) +{ + return (SwCharFmt*)CopyFmt( rFmt, *GetCharFmts(), + (FNCopyFmt)&SwDoc::MakeCharFmt, + *GetDfltCharFmt() ); +} + + +// --- Kopiere TextNodes ---- + +SwTxtFmtColl* SwDoc::CopyTxtColl( const SwTxtFmtColl& rColl ) +{ + SwTxtFmtColl* pNewColl = FindTxtFmtCollByName( rColl.GetName() ); + if( pNewColl ) + return pNewColl; + + // suche erstmal nach dem "Parent" + SwTxtFmtColl* pParent = pDfltTxtFmtColl; + if( pParent != rColl.DerivedFrom() ) + pParent = CopyTxtColl( *(SwTxtFmtColl*)rColl.DerivedFrom() ); + + +//FEATURE::CONDCOLL + if( RES_CONDTXTFMTCOLL == rColl.Which() ) + { + pNewColl = new SwConditionTxtFmtColl( GetAttrPool(), rColl.GetName(), + pParent); + pTxtFmtCollTbl->Insert( pNewColl, pTxtFmtCollTbl->Count() ); + pNewColl->SetAuto( FALSE ); + SetModified(); + + // Kopiere noch die Bedingungen + ((SwConditionTxtFmtColl*)pNewColl)->SetConditions( + ((SwConditionTxtFmtColl&)rColl).GetCondColls() ); + } + else +//FEATURE::CONDCOLL + pNewColl = MakeTxtFmtColl( rColl.GetName(), pParent ); + + // kopiere jetzt noch die Auto-Formate oder kopiere die Attribute + pNewColl->CopyAttrs( rColl, TRUE ); + + // setze noch den Outline-Level + if( NO_NUMBERING != rColl.GetOutlineLevel() ) + pNewColl->SetOutlineLevel( rColl.GetOutlineLevel() ); + + pNewColl->SetPoolFmtId( rColl.GetPoolFmtId() ); + pNewColl->SetPoolHelpId( rColl.GetPoolHelpId() ); + + // HelpFile-Id immer auf dflt setzen !! + pNewColl->SetPoolHlpFileId( UCHAR_MAX ); + + if( &rColl.GetNextTxtFmtColl() != &rColl ) + pNewColl->SetNextTxtFmtColl( *CopyTxtColl( rColl.GetNextTxtFmtColl() )); + + // ggfs. die NumRule erzeugen + if( this != rColl.GetDoc() ) + { + const SfxPoolItem* pItem; + if( SFX_ITEM_SET == pNewColl->GetItemState( RES_PARATR_NUMRULE, + FALSE, &pItem )) + { + const SwNumRule* pRule; + const String& rName = ((SwNumRuleItem*)pItem)->GetValue(); + if( rName.Len() && + 0 != ( pRule = rColl.GetDoc()->FindNumRulePtr( rName )) && + !pRule->IsAutoRule() ) + { + SwNumRule* pDestRule = FindNumRulePtr( rName ); + if( pDestRule ) + pDestRule->SetInvalidRule( TRUE ); + else + MakeNumRule( rName, pRule ); + } + } + } + return pNewColl; +} + +// --- Kopiere GrafikNodes ---- + +SwGrfFmtColl* SwDoc::CopyGrfColl( const SwGrfFmtColl& rColl ) +{ + SwGrfFmtColl* pNewColl = FindGrfFmtCollByName( rColl.GetName() ); + if( pNewColl ) + return pNewColl; + + // suche erstmal nach dem "Parent" + SwGrfFmtColl* pParent = pDfltGrfFmtColl; + if( pParent != rColl.DerivedFrom() ) + pParent = CopyGrfColl( *(SwGrfFmtColl*)rColl.DerivedFrom() ); + + // falls nicht, so kopiere sie + pNewColl = MakeGrfFmtColl( rColl.GetName(), pParent ); + + // noch die Attribute kopieren + pNewColl->CopyAttrs( rColl ); + + pNewColl->SetPoolFmtId( rColl.GetPoolFmtId() ); + pNewColl->SetPoolHelpId( rColl.GetPoolHelpId() ); + + // HelpFile-Id immer auf dflt setzen !! + pNewColl->SetPoolHlpFileId( UCHAR_MAX ); + + return pNewColl; +} + +SwPageDesc* lcl_FindPageDesc( const SwPageDescs& rArr, const String& rName ) +{ + for( USHORT n = rArr.Count(); n; ) + { + SwPageDesc* pDesc = rArr[ --n ]; + if( pDesc->GetName() == rName ) + return pDesc; + } + return 0; +} + +void SwDoc::CopyFmtArr( const SvPtrarr& rSourceArr, + SvPtrarr& rDestArr, + FNCopyFmt fnCopyFmt, + SwFmt& rDfltFmt ) +{ + USHORT nSrc; + SwFmt* pSrc, *pDest; + + // 1. Schritt alle Formate anlegen (das 0. ueberspringen - Default!) + for( nSrc = rSourceArr.Count(); nSrc > 1; ) + { + pSrc = (SwFmt*)rSourceArr[ --nSrc ]; + if( pSrc->IsDefault() || pSrc->IsAuto() ) + continue; + + if( 0 == FindFmtByName( rDestArr, pSrc->GetName() ) ) + { + if( RES_CONDTXTFMTCOLL == pSrc->Which() ) + MakeCondTxtFmtColl( pSrc->GetName(), (SwTxtFmtColl*)&rDfltFmt ); + else + (this->*fnCopyFmt)( pSrc->GetName(), &rDfltFmt ); + } + } + + // 2. Schritt alle Attribute kopieren, richtige Parents setzen + for( nSrc = rSourceArr.Count(); nSrc > 1; ) + { + pSrc = (SwFmt*)rSourceArr[ --nSrc ]; + if( pSrc->IsDefault() || pSrc->IsAuto() ) + continue; + + pDest = FindFmtByName( rDestArr, pSrc->GetName() ); + pDest->SetAuto( FALSE ); +// pDest->ResetAllAttr(); +// pDest->CopyAttrs( *pSrc, TRUE ); // kopiere Attribute +//JP 19.02.96: ist so wohl optimaler - loest ggfs. kein Modify aus! + pDest->DelDiffs( *pSrc ); + pDest->SetAttr( pSrc->GetAttrSet() ); // kopiere Attribute + + //JP 18.08.98: Bug 55115 - PageDescAttribute in diesem Fall doch + // kopieren + const SfxPoolItem* pItem; + if( &GetAttrPool() != pSrc->GetAttrSet().GetPool() && + SFX_ITEM_SET == pSrc->GetAttrSet().GetItemState( + RES_PAGEDESC, FALSE, &pItem ) && + ((SwFmtPageDesc*)pItem)->GetPageDesc() ) + { + SwFmtPageDesc aDesc( *(SwFmtPageDesc*)pItem ); + const String& rNm = aDesc.GetPageDesc()->GetName(); + SwPageDesc* pDesc = ::lcl_FindPageDesc( aPageDescs, rNm ); + if( !pDesc ) + pDesc = aPageDescs[ MakePageDesc( rNm ) ]; + pDesc->Add( &aDesc ); + pDest->SetAttr( aDesc ); + } + + pDest->SetPoolFmtId( pSrc->GetPoolFmtId() ); + pDest->SetPoolHelpId( pSrc->GetPoolHelpId() ); + + // HelpFile-Id immer auf dflt setzen !! + pDest->SetPoolHlpFileId( UCHAR_MAX ); + + if( pSrc->DerivedFrom() ) + pDest->SetDerivedFrom( FindFmtByName( rDestArr, + pSrc->DerivedFrom()->GetName() ) ); + if( RES_TXTFMTCOLL == pSrc->Which() || + RES_CONDTXTFMTCOLL == pSrc->Which() ) + { + SwTxtFmtColl* pSrcColl = (SwTxtFmtColl*)pSrc, + * pDstColl = (SwTxtFmtColl*)pDest; + if( &pSrcColl->GetNextTxtFmtColl() != pSrcColl ) + pDstColl->SetNextTxtFmtColl( *(SwTxtFmtColl*)FindFmtByName( + rDestArr, pSrcColl->GetNextTxtFmtColl().GetName() ) ); + + // setze noch den Outline-Level + if( NO_NUMBERING != pSrcColl->GetOutlineLevel() ) + pDstColl->SetOutlineLevel( pSrcColl->GetOutlineLevel() ); + +//FEATURE::CONDCOLL + if( RES_CONDTXTFMTCOLL == pSrc->Which() ) + // Kopiere noch die Bedingungen + // aber erst die alten loeschen! + ((SwConditionTxtFmtColl*)pDstColl)->SetConditions( + ((SwConditionTxtFmtColl*)pSrc)->GetCondColls() ); +//FEATURE::CONDCOLL + } + } +} + +void SwDoc::_CopyPageDescHeaderFooter( BOOL bCpyHeader, + const SwFrmFmt& rSrcFmt, SwFrmFmt& rDestFmt ) +{ + // jetzt noch Header-/Footer-Attribute richtig behandeln + // Contenten Nodes Dokumentuebergreifend kopieren! + USHORT nAttr = bCpyHeader ? RES_HEADER : RES_FOOTER; + const SfxPoolItem* pItem; + if( SFX_ITEM_SET != rSrcFmt.GetAttrSet().GetItemState( nAttr, FALSE, &pItem )) + return ; + + // Im Header steht noch der Verweis auf das Format aus dem + // anderen Document!! + SfxPoolItem* pNewItem = pItem->Clone(); + + SwFrmFmt* pOldFmt; + if( bCpyHeader ) + pOldFmt = ((SwFmtHeader*)pNewItem)->GetHeaderFmt(); + else + pOldFmt = ((SwFmtFooter*)pNewItem)->GetFooterFmt(); + + if( pOldFmt ) + { + SwFrmFmt* pNewFmt = new SwFrmFmt( GetAttrPool(), "CpyDesc", + GetDfltFrmFmt() ); + pNewFmt->CopyAttrs( *pOldFmt, TRUE ); + + if( SFX_ITEM_SET == pNewFmt->GetAttrSet().GetItemState( + RES_CNTNT, FALSE, &pItem )) + { + SwFmtCntnt* pCntnt = (SwFmtCntnt*)pItem; + if( pCntnt->GetCntntIdx() ) + { + SwNodeIndex aTmpIdx( GetNodes().GetEndOfAutotext() ); + const SwNodes& rSrcNds = rSrcFmt.GetDoc()->GetNodes(); + SwStartNode* pSttNd = GetNodes().MakeEmptySection( aTmpIdx, + bCpyHeader + ? SwHeaderStartNode + : SwFooterStartNode ); + const SwNode& rCSttNd = pCntnt->GetCntntIdx()->GetNode(); + SwNodeRange aRg( rCSttNd, 0, *rCSttNd.EndOfSectionNode() ); + aTmpIdx = *pSttNd->EndOfSectionNode(); + rSrcNds._Copy( aRg, aTmpIdx ); + aTmpIdx = *pSttNd; + rSrcFmt.GetDoc()->_CopyFlyInFly( aRg, aTmpIdx ); + pNewFmt->SetAttr( SwFmtCntnt( pSttNd )); + } + else + pNewFmt->ResetAttr( RES_CNTNT ); + } + if( bCpyHeader ) + pNewFmt->Add( (SwFmtHeader*)pNewItem ); + else + pNewFmt->Add( (SwFmtFooter*)pNewItem ); + rDestFmt.SetAttr( *pNewItem ); + } + delete pNewItem; +} + +void SwDoc::CopyPageDesc( const SwPageDesc& rSrcDesc, SwPageDesc& rDstDesc, + BOOL bCopyPoolIds ) +{ + FASTBOOL bNotifyLayout = FALSE; + + rDstDesc.SetLandscape( rSrcDesc.GetLandscape() ); + rDstDesc.SetNumType( rSrcDesc.GetNumType() ); + if( rDstDesc.ReadUseOn() != rSrcDesc.ReadUseOn() ) + { + rDstDesc.WriteUseOn( rSrcDesc.ReadUseOn() ); + bNotifyLayout = TRUE; + } + + if( bCopyPoolIds ) + { + rDstDesc.SetPoolFmtId( rSrcDesc.GetPoolFmtId() ); + rDstDesc.SetPoolHelpId( rSrcDesc.GetPoolHelpId() ); + // HelpFile-Id immer auf dflt setzen !! + rDstDesc.SetPoolHlpFileId( UCHAR_MAX ); + } + + if( rSrcDesc.GetFollow() != &rSrcDesc ) + { + SwPageDesc* pFollow = ::lcl_FindPageDesc( aPageDescs, + rSrcDesc.GetFollow()->GetName() ); + if( !pFollow ) + { + // dann mal kopieren + USHORT nPos = MakePageDesc( rSrcDesc.GetFollow()->GetName() ); + pFollow = aPageDescs[ nPos ]; + CopyPageDesc( *rSrcDesc.GetFollow(), *pFollow ); + } + rDstDesc.SetFollow( pFollow ); + bNotifyLayout = TRUE; + } + + // die Header/Footer-Attribute werden gesondert kopiert, die Content- + // Sections muessen vollstaendig mitgenommen werden! + { + SfxItemSet aAttrSet( rSrcDesc.GetMaster().GetAttrSet() ); + aAttrSet.ClearItem( RES_HEADER ); + aAttrSet.ClearItem( RES_FOOTER ); + + rDstDesc.GetMaster().DelDiffs( aAttrSet ); + rDstDesc.GetMaster().SetAttr( aAttrSet ); + + aAttrSet.ClearItem(); + aAttrSet.Put( rSrcDesc.GetLeft().GetAttrSet() ); + aAttrSet.ClearItem( RES_HEADER ); + aAttrSet.ClearItem( RES_FOOTER ); + + rDstDesc.GetLeft().DelDiffs( aAttrSet ); + rDstDesc.GetLeft().SetAttr( aAttrSet ); + } + + CopyHeader( rSrcDesc.GetMaster(), rDstDesc.GetMaster() ); + CopyFooter( rSrcDesc.GetMaster(), rDstDesc.GetMaster() ); + if( !rDstDesc.IsHeaderShared() ) + CopyHeader( rSrcDesc.GetLeft(), rDstDesc.GetLeft() ); + else + rDstDesc.GetLeft().SetAttr( rDstDesc.GetMaster().GetHeader() ); + + if( !rDstDesc.IsFooterShared() ) + CopyFooter( rSrcDesc.GetLeft(), rDstDesc.GetLeft() ); + else + rDstDesc.GetLeft().SetAttr( rDstDesc.GetMaster().GetFooter() ); + + if( bNotifyLayout && GetRootFrm() ) + //Layot benachrichtigen! + GetRootFrm()->CheckPageDescs( (SwPageFrm*)GetRootFrm()->Lower() ); + + //Wenn sich FussnotenInfo veraendert, so werden die Seiten + //angetriggert. + if( !(rDstDesc.GetFtnInfo() == rSrcDesc.GetFtnInfo()) ) + { + rDstDesc.SetFtnInfo( rSrcDesc.GetFtnInfo() ); + SwMsgPoolItem aInfo( RES_PAGEDESC_FTNINFO ); + { + SwClientIter aIter( rDstDesc.GetMaster() ); + for( SwClient* pLast = aIter.First(TYPE(SwFrm)); pLast; + pLast = aIter.Next() ) + pLast->Modify( &aInfo, 0 ); + } + { + SwClientIter aIter( rDstDesc.GetLeft() ); + for( SwClient* pLast = aIter.First(TYPE(SwFrm)); pLast; + pLast = aIter.Next() ) + pLast->Modify( &aInfo, 0 ); + } + } +} + +void SwDoc::ReplaceStyles( SwDoc& rSource ) +{ + BOOL bIsUndo = DoesUndo(); + DoUndo( FALSE ); + + CopyFmtArr( *rSource.pCharFmtTbl, *pCharFmtTbl, + (FNCopyFmt)&SwDoc::MakeCharFmt, *pDfltCharFmt ); + CopyFmtArr( *rSource.pFrmFmtTbl, *pFrmFmtTbl, + (FNCopyFmt)&SwDoc::MakeFrmFmt, *pDfltFrmFmt ); + CopyFmtArr( *rSource.pTxtFmtCollTbl, *pTxtFmtCollTbl, + (FNCopyFmt)&SwDoc::MakeTxtFmtColl, *pDfltTxtFmtColl ); + + // und jetzt noch die Seiten-Vorlagen + USHORT nCnt = rSource.aPageDescs.Count(); + if( nCnt ) + { + // ein anderes Doc -> Numberformatter muessen gemergt werden + SwTblNumFmtMerge aTNFM( rSource, *this ); + + // 1. Schritt alle Formate anlegen (das 0. ueberspringen - Default!) + while( nCnt ) + { + SwPageDesc *pSrc = rSource.aPageDescs[ --nCnt ]; + if( 0 == ::lcl_FindPageDesc( aPageDescs, pSrc->GetName() ) ) + MakePageDesc( pSrc->GetName() ); + } + + // 2. Schritt alle Attribute kopieren, richtige Parents setzen + for( nCnt = rSource.aPageDescs.Count(); nCnt; ) + { + SwPageDesc *pSrc = rSource.aPageDescs[ --nCnt ]; + CopyPageDesc( *pSrc, *::lcl_FindPageDesc( aPageDescs, pSrc->GetName() )); + } + } + + //JP 08.04.99: und dann sind da noch die Numerierungs-Vorlagen + nCnt = rSource.GetNumRuleTbl().Count(); + if( nCnt ) + { + const SwNumRuleTbl& rArr = rSource.GetNumRuleTbl(); + for( USHORT n = 0; n < nCnt; ++n ) + { + const SwNumRule& rR = *rArr[ n ]; + if( !rR.IsAutoRule() ) + { + SwNumRule* pNew = FindNumRulePtr( rR.GetName()); + if( pNew ) + pNew->CopyNumRule( this, rR ); + else + MakeNumRule( rR.GetName(), &rR ); + } + } + } + + if( bIsUndo ) + { + // es wurde am Nodes-Array gedreht! + ClearRedo(); + DelAllUndoObj(); + } + + SetModified(); + DoUndo( bIsUndo ); +} + +SwFmt* SwDoc::FindFmtByName( const SvPtrarr& rFmtArr, + const String& rName ) const +{ + SwFmt* pFnd = 0; + for( USHORT n = 0; n < rFmtArr.Count(); n++ ) + { + // ist die Vorlage schon im Doc vorhanden ?? + if( ((SwFmt*)rFmtArr[n])->GetName() == rName ) + { + pFnd = (SwFmt*)rFmtArr[n]; + break; + } + } + return pFnd; +} + +void SwDoc::MoveLeftMargin( const SwPaM& rPam, BOOL bRight, BOOL bModulus ) +{ + SwHistory* pHistory = 0; + if( DoesUndo() ) + { + ClearRedo(); + SwUndoMoveLeftMargin* pUndo = new SwUndoMoveLeftMargin( rPam, bRight, + bModulus ); + pHistory = pUndo->GetHistory(); + AppendUndo( pUndo ); + } + + const SvxTabStopItem& rTabItem = (SvxTabStopItem&)GetDefault( RES_PARATR_TABSTOP ); + USHORT nDefDist = rTabItem.Count() ? rTabItem[0].GetTabPos() : 1134; + const SwPosition &rStt = *rPam.Start(), &rEnd = *rPam.End(); + SwNodeIndex aIdx( rStt.nNode ); + while( aIdx <= rEnd.nNode ) + { + SwTxtNode* pTNd = aIdx.GetNode().GetTxtNode(); + if( pTNd ) + { + SvxLRSpaceItem aLS( (SvxLRSpaceItem&)pTNd->SwCntntNode::GetAttr( + RES_LR_SPACE ) ); + USHORT nNext = aLS.GetTxtLeft(); + if( bModulus ) + nNext = ( nNext / nDefDist ) * nDefDist; + + if( bRight ) + nNext += nDefDist; + else if( nNext ) + { + if( !bModulus && nDefDist > nNext ) + nNext = 0; + else + nNext -= nDefDist; + } + aLS.SetTxtLeft( nNext ); + + SwRegHistory aRegH( pTNd, *pTNd, pHistory ); + pTNd->SwCntntNode::SetAttr( aLS ); + } + aIdx++; + } + SetModified(); +} + +BOOL SwDoc::DontExpandFmt( const SwPosition& rPos, BOOL bFlag ) +{ + BOOL bRet = FALSE; + SwTxtNode* pTxtNd = rPos.nNode.GetNode().GetTxtNode(); + if( pTxtNd ) + { + bRet = pTxtNd->DontExpandFmt( rPos.nContent, bFlag ); + if( bRet && DoesUndo() ) + { + ClearRedo(); + AppendUndo( new SwUndoDontExpandFmt( rPos )); + } + } + return bRet; +} + +SwTableBoxFmt* SwDoc::MakeTableBoxFmt() +{ + SwTableBoxFmt* pFmt = new SwTableBoxFmt( GetAttrPool(), aEmptyStr, + pDfltFrmFmt ); + SetModified(); + return pFmt; +} + +SwTableLineFmt* SwDoc::MakeTableLineFmt() +{ + SwTableLineFmt* pFmt = new SwTableLineFmt( GetAttrPool(), aEmptyStr, + pDfltFrmFmt ); + SetModified(); + return pFmt; +} + +void SwDoc::_CreateNumberFormatter() +{ + ASSERT( !pNumberFormatter, "ist doch schon vorhanden" ); + + + LanguageType eLang = LANGUAGE_SYSTEM; //System::GetLanguage(); +/* ((const SvxLanguageItem&)GetAttrPool(). + GetDefaultItem( RES_CHRATR_LANGUAGE )).GetLanguage(); +*/ + pNumberFormatter = new SvNumberFormatter( eLang ); + pNumberFormatter->SetEvalDateFormat( NF_EVALDATEFORMAT_FORMAT_INTL ); + pNumberFormatter->SetYear2000(SFX_APP()->GetMiscConfig()->GetYear2000()); + +} + +SwTblNumFmtMerge::SwTblNumFmtMerge( const SwDoc& rSrc, SwDoc& rDest ) + : pNFmt( 0 ) +{ + // ein anderes Doc -> Numberformatter muessen gemergt werden + SvNumberFormatter* pN; + if( &rSrc != &rDest && 0 != ( pN = ((SwDoc&)rSrc).GetNumberFormatter( FALSE ) )) + ( pNFmt = rDest.GetNumberFormatter( TRUE ))->MergeFormatter( *pN ); + + if( &rSrc != &rDest ) + ((SwGetRefFieldType*)rSrc.GetSysFldType( RES_GETREFFLD ))-> + MergeWithOtherDoc( rDest ); +} + +SwTblNumFmtMerge::~SwTblNumFmtMerge() +{ + if( pNFmt ) + pNFmt->ClearMergeTable(); +} + + +void SwDoc::SetTxtFmtCollByAutoFmt( const SwPosition& rPos, USHORT nPoolId, + const SfxItemSet* pSet ) +{ + SwPaM aPam( rPos ); + SwTxtNode* pTNd = rPos.nNode.GetNode().GetTxtNode(); + + if( bIsAutoFmtRedline && pTNd ) + { + // dann das Redline Object anlegen + const SwTxtFmtColl& rColl = *pTNd->GetTxtColl(); + SwRedline* pRedl = new SwRedline( REDLINE_FMTCOLL, aPam ); + pRedl->SetMark(); + + // interressant sind nur die Items, die vom Set NICHT wieder + // in den Node gesetzt werden. Also muss man die Differenz nehmen + SwRedlineExtraData_FmtColl aExtraData( rColl.GetName(), + rColl.GetPoolFmtId() ); + if( pSet && pTNd->GetpSwAttrSet() ) + { + SfxItemSet aTmp( *pTNd->GetpSwAttrSet() ); + aTmp.Differentiate( *pSet ); + // das Adjust Item behalten wir extra + const SfxPoolItem* pItem; + if( SFX_ITEM_SET == pTNd->GetpSwAttrSet()->GetItemState( + RES_PARATR_ADJUST, FALSE, &pItem )) + aTmp.Put( *pItem ); + aExtraData.SetItemSet( aTmp ); + } + pRedl->SetExtraData( &aExtraData ); + +// !!!!!!!!! Undo fehlt noch !!!!!!!!!!!!!!!!!! + AppendRedline( pRedl ); + } + + SetTxtFmtColl( aPam, GetTxtCollFromPool( nPoolId ) ); + + if( pSet && pTNd && pSet->Count() ) + { + aPam.SetMark(); + aPam.GetMark()->nContent.Assign( pTNd, pTNd->GetTxt().Len() ); + Insert( aPam, *pSet ); + } +} + +void SwDoc::SetFmtItemByAutoFmt( const SwPaM& rPam, const SfxPoolItem& rItem ) +{ + SwTxtNode* pTNd = rPam.GetPoint()->nNode.GetNode().GetTxtNode(); + + SwRedlineMode eOld = GetRedlineMode(); + + if( bIsAutoFmtRedline && pTNd ) + { + // dann das Redline Object anlegen + SwRedline* pRedl = new SwRedline( REDLINE_FORMAT, rPam ); + if( !pRedl->HasMark() ) + pRedl->SetMark(); + + // interressant sind nur die Items, die vom Set NICHT wieder + // in den Node gesetzt werden. Also muss man die Differenz nehmen + SwRedlineExtraData_Format aExtraData( rItem.Which() ); + +/* + if( pSet && pTNd->GetpSwAttrSet() ) + { + SfxItemSet aTmp( *pTNd->GetpSwAttrSet() ); + aTmp.Differentiate( *pSet ); + // das Adjust Item behalten wir extra + const SfxPoolItem* pItem; + if( SFX_ITEM_SET == pTNd->GetpSwAttrSet()->GetItemState( + RES_PARATR_ADJUST, FALSE, &pItem )) + aTmp.Put( *pItem ); + aExtraData.SetItemSet( aTmp ); + } +*/ + pRedl->SetExtraData( &aExtraData ); + +// !!!!!!!!! Undo fehlt noch !!!!!!!!!!!!!!!!!! + AppendRedline( pRedl ); + + SetRedlineMode_intern( eOld | REDLINE_IGNORE ); + } + + Insert( rPam, rItem, SETATTR_DONTEXPAND ); + SetRedlineMode_intern( eOld ); +} + diff --git a/sw/source/core/doc/docftn.cxx b/sw/source/core/doc/docftn.cxx new file mode 100644 index 000000000000..bf9d977f22fd --- /dev/null +++ b/sw/source/core/doc/docftn.cxx @@ -0,0 +1,555 @@ +/************************************************************************* + * + * $RCSfile: docftn.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:15 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _FTNIDX_HXX //autogen +#include +#endif +#ifndef _ROOTFRM_HXX //autogen +#include +#endif +#ifndef _TXTFTN_HXX //autogen +#include +#endif +#ifndef _FMTFTN_HXX //autogen +#include +#endif +#ifndef _PAM_HXX //autogen +#include +#endif +#ifndef _PAGEDESC_HXX //autogen +#include +#endif +#ifndef _CHARFMT_HXX //autogen +#include +#endif +#ifndef _UNDOBJ_HXX +#include +#endif +#ifndef _ROLBCK_HXX +#include +#endif +#ifndef _DOC_HXX +#include +#endif +#ifndef _FMTCOL_HXX +#include +#endif +#ifndef _NDTXT_HXX +#include +#endif +#ifndef _POOLFMT_HXX +#include +#endif +#ifndef _FTNINFO_HXX +#include +#endif +#ifndef _HINTS_HXX +#include +#endif + + +/*********************** SwFtnInfo ***************************/ + +SwEndNoteInfo& SwEndNoteInfo::operator=(const SwEndNoteInfo& rInfo) +{ + if( rInfo.GetFtnTxtColl() ) + rInfo.GetFtnTxtColl()->Add(this); + else if ( pRegisteredIn) + pRegisteredIn->Remove(this); + + if ( rInfo.aPageDescDep.GetRegisteredIn() ) + ((SwModify*)rInfo.aPageDescDep.GetRegisteredIn())->Add( &aPageDescDep ); + else if ( aPageDescDep.GetRegisteredIn() ) + ((SwModify*)aPageDescDep.GetRegisteredIn())->Remove( &aPageDescDep ); + + if ( rInfo.aCharFmtDep.GetRegisteredIn() ) + ((SwModify*)rInfo.aCharFmtDep.GetRegisteredIn())->Add( &aCharFmtDep ); + else if ( aCharFmtDep.GetRegisteredIn() ) + ((SwModify*)aCharFmtDep.GetRegisteredIn())->Remove( &aCharFmtDep ); + + if ( rInfo.aAnchorCharFmtDep.GetRegisteredIn() ) + ((SwModify*)rInfo.aAnchorCharFmtDep.GetRegisteredIn())->Add( + &aAnchorCharFmtDep ); + else if( aAnchorCharFmtDep.GetRegisteredIn() ) + ((SwModify*)aAnchorCharFmtDep.GetRegisteredIn())->Remove( + &aAnchorCharFmtDep ); + + aFmt = rInfo.aFmt; + nFtnOffset = rInfo.nFtnOffset; + bEndNote = rInfo.bEndNote; + sPrefix = rInfo.sPrefix; + sSuffix = rInfo.sSuffix; + return *this; +} + + +BOOL SwEndNoteInfo::operator==( const SwEndNoteInfo& rInfo ) const +{ + return aPageDescDep.GetRegisteredIn() == + rInfo.aPageDescDep.GetRegisteredIn() && + aCharFmtDep.GetRegisteredIn() == + rInfo.aCharFmtDep.GetRegisteredIn() && + aAnchorCharFmtDep.GetRegisteredIn() == + rInfo.aAnchorCharFmtDep.GetRegisteredIn() && + GetFtnTxtColl() == rInfo.GetFtnTxtColl() && + aFmt.eType == rInfo.aFmt.eType && + nFtnOffset == rInfo.nFtnOffset && + bEndNote == rInfo.bEndNote && + sPrefix == rInfo.sPrefix && + sSuffix == rInfo.sSuffix; +} + + +SwEndNoteInfo::SwEndNoteInfo(const SwEndNoteInfo& rInfo) : + SwClient( rInfo.GetFtnTxtColl() ), + aPageDescDep( this, 0 ), + aCharFmtDep( this, 0 ), + aAnchorCharFmtDep( this, 0 ), + aFmt( rInfo.aFmt ), + nFtnOffset( rInfo.nFtnOffset ), + sPrefix( rInfo.sPrefix ), + sSuffix( rInfo.sSuffix ), + bEndNote( TRUE ) +{ + if( rInfo.GetPageDescDep()->GetRegisteredIn() ) + ((SwModify*)rInfo.GetPageDescDep()->GetRegisteredIn())->Add( &aPageDescDep ); + + if( rInfo.aCharFmtDep.GetRegisteredIn() ) + ((SwModify*)rInfo.aCharFmtDep.GetRegisteredIn())->Add( &aCharFmtDep ); + + if( rInfo.aAnchorCharFmtDep.GetRegisteredIn() ) + ((SwModify*)rInfo.aAnchorCharFmtDep.GetRegisteredIn())->Add( + &aAnchorCharFmtDep ); +} + +SwEndNoteInfo::SwEndNoteInfo(SwTxtFmtColl *pFmt) : + SwClient(pFmt), + aPageDescDep( this, 0 ), + aCharFmtDep( this, 0 ), + aAnchorCharFmtDep( this, 0 ), + nFtnOffset( 0 ), + bEndNote( TRUE ) +{ + aFmt.eType = SVX_NUM_ROMAN_LOWER; +} + +SwPageDesc *SwEndNoteInfo::GetPageDesc( SwDoc &rDoc ) const +{ + if ( !aPageDescDep.GetRegisteredIn() ) + { + SwPageDesc *pDesc = rDoc.GetPageDescFromPool( bEndNote + ? RES_POOLPAGE_ENDNOTE + : RES_POOLPAGE_FOOTNOTE ); + pDesc->Add( &((SwClient&)aPageDescDep) ); + } + return (SwPageDesc*)aPageDescDep.GetRegisteredIn(); +} + +void SwEndNoteInfo::ChgPageDesc( SwPageDesc *pDesc ) +{ + pDesc->Add( &((SwClient&)aPageDescDep) ); +} + +void SwEndNoteInfo::SetFtnTxtColl(SwTxtFmtColl& rFmt) +{ + rFmt.Add(this); +} + +SwCharFmt* SwEndNoteInfo::GetCharFmt(SwDoc &rDoc) const +{ + if ( !aCharFmtDep.GetRegisteredIn() ) + { + SwCharFmt* pFmt = rDoc.GetCharFmtFromPool( bEndNote + ? RES_POOLCHR_ENDNOTE + : RES_POOLCHR_FOOTNOTE ); + pFmt->Add( &((SwClient&)aCharFmtDep) ); + } + return (SwCharFmt*)aCharFmtDep.GetRegisteredIn(); +} + +void SwEndNoteInfo::SetCharFmt( SwCharFmt* pChFmt ) +{ + DBG_ASSERT(pChFmt, "kein CharFmt?") + pChFmt->Add( &((SwClient&)aCharFmtDep) ); +} + +SwCharFmt* SwEndNoteInfo::GetAnchorCharFmt(SwDoc &rDoc) const +{ + if( !aAnchorCharFmtDep.GetRegisteredIn() ) + { + SwCharFmt* pFmt = rDoc.GetCharFmtFromPool( bEndNote + ? RES_POOLCHR_ENDNOTE_ANCHOR + : RES_POOLCHR_FOOTNOTE_ANCHOR ); + pFmt->Add( &((SwClient&)aAnchorCharFmtDep) ); + } + return (SwCharFmt*)aAnchorCharFmtDep.GetRegisteredIn(); +} + +void SwEndNoteInfo::SetAnchorCharFmt( SwCharFmt* pChFmt ) +{ + DBG_ASSERT(pChFmt, "kein CharFmt?") + pChFmt->Add( &((SwClient&)aAnchorCharFmtDep) ); +} + +void SwEndNoteInfo::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew ) +{ + USHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0 ; + + if( RES_ATTRSET_CHG == nWhich || + RES_FMT_CHG == nWhich ) + { + SwDoc* pDoc; + if( aCharFmtDep.GetRegisteredIn() ) + pDoc = ((SwCharFmt*)aCharFmtDep.GetRegisteredIn())->GetDoc(); + else + pDoc = ((SwCharFmt*)aAnchorCharFmtDep.GetRegisteredIn())->GetDoc(); + SwFtnIdxs& rFtnIdxs = pDoc->GetFtnIdxs(); + for( USHORT nPos = 0; nPos < rFtnIdxs.Count(); ++nPos ) + { + SwTxtFtn *pTxtFtn = rFtnIdxs[ nPos ]; + const SwFmtFtn &rFtn = pTxtFtn->GetFtn(); + if ( rFtn.IsEndNote() == bEndNote) + pTxtFtn->SetNumber( rFtn.GetNumber(), &rFtn.GetNumStr()); + } + } + else + SwClient::Modify( pOld, pNew ); +} + +SwFtnInfo& SwFtnInfo::operator=(const SwFtnInfo& rInfo) +{ + SwEndNoteInfo::operator=(rInfo); + aQuoVadis = rInfo.aQuoVadis; + aErgoSum = rInfo.aErgoSum; + ePos = rInfo.ePos; + eNum = rInfo.eNum; + return *this; +} + + +BOOL SwFtnInfo::operator==( const SwFtnInfo& rInfo ) const +{ + return ePos == rInfo.ePos && + eNum == rInfo.eNum && + SwEndNoteInfo::operator==(rInfo) && + aQuoVadis == rInfo.aQuoVadis && + aErgoSum == rInfo.aErgoSum; +} + + +SwFtnInfo::SwFtnInfo(const SwFtnInfo& rInfo) : + SwEndNoteInfo( rInfo ), + aQuoVadis( rInfo.aQuoVadis ), + aErgoSum( rInfo.aErgoSum ), + ePos( rInfo.ePos ), + eNum( rInfo.eNum ) +{ + bEndNote = FALSE; +} + +SwFtnInfo::SwFtnInfo(SwTxtFmtColl *pFmt) : + SwEndNoteInfo( pFmt ), + eNum( FTNNUM_DOC ), + ePos( FTNPOS_PAGE ) +{ + aFmt.eType = SVX_NUM_ARABIC; + bEndNote = FALSE; +} + +/*********************** SwDoc ***************************/ + + +void SwDoc::SetFtnInfo(const SwFtnInfo& rInfo) +{ + if( !(GetFtnInfo() == rInfo) ) + { + const SwFtnInfo &rOld = GetFtnInfo(); + + if( DoesUndo() ) + { + ClearRedo(); + AppendUndo( new SwUndoFtnInfo( rOld ) ); + } + + FASTBOOL bPageNum = rInfo.eNum == FTNNUM_PAGE && + rOld.eNum != FTNNUM_PAGE; + FASTBOOL bFtnPos = rInfo.ePos != rOld.ePos; + FASTBOOL bFtnDesc = rOld.ePos == FTNPOS_CHAPTER && + rInfo.GetPageDesc( *this ) != rOld.GetPageDesc( *this ); + FASTBOOL bExtra = rInfo.aQuoVadis != rOld.aQuoVadis || + rInfo.aErgoSum != rOld.aErgoSum || + rInfo.aFmt.eType != rOld.aFmt.eType || + rInfo.GetPrefix() != rOld.GetPrefix() || + rInfo.GetSuffix() != rOld.GetSuffix(); + SwCharFmt *pOldChrFmt = rOld.GetCharFmt( *this ), + *pNewChrFmt = rInfo.GetCharFmt( *this ); + FASTBOOL bFtnChrFmts = pOldChrFmt != pNewChrFmt; + + *pFtnInfo = rInfo; + + if ( GetRootFrm() ) + { + if ( bFtnPos ) + GetRootFrm()->RemoveFtns(); + else + { + GetRootFrm()->UpdateFtnNums(); + if ( bFtnDesc ) + GetRootFrm()->CheckFtnPageDescs( FALSE ); + if ( bExtra ) + { + //Fuer die Benachrichtung bezueglich ErgoSum usw. sparen wir uns + //extra-Code und nutzen die vorhandenen Wege. + SwFtnIdxs& rFtnIdxs = GetFtnIdxs(); + for( USHORT nPos = 0; nPos < rFtnIdxs.Count(); ++nPos ) + { + SwTxtFtn *pTxtFtn = rFtnIdxs[ nPos ]; + const SwFmtFtn &rFtn = pTxtFtn->GetFtn(); + if ( !rFtn.IsEndNote() ) + pTxtFtn->SetNumber( rFtn.GetNumber(), &rFtn.GetNumStr()); + } + } + } + } + if( FTNNUM_PAGE != rInfo.eNum ) + GetFtnIdxs().UpdateAllFtn(); + else if( bFtnChrFmts ) + { + SwFmtChg aOld( pOldChrFmt ); + SwFmtChg aNew( pNewChrFmt ); + pFtnInfo->Modify( &aOld, &aNew ); + } + + UpdateRefFlds(); + + SetModified(); + } +} + +void SwDoc::SetEndNoteInfo(const SwEndNoteInfo& rInfo) +{ + if( !(GetEndNoteInfo() == rInfo) ) + { + if( DoesUndo() ) + { + ClearRedo(); + AppendUndo( new SwUndoEndNoteInfo( GetEndNoteInfo() ) ); + } + + FASTBOOL bNumChg = rInfo.nFtnOffset != GetEndNoteInfo().nFtnOffset; + FASTBOOL bExtra = !bNumChg && + rInfo.aFmt.eType != GetEndNoteInfo().aFmt.eType|| + rInfo.GetPrefix() != GetEndNoteInfo().GetPrefix() || + rInfo.GetSuffix() != GetEndNoteInfo().GetSuffix(); + FASTBOOL bFtnDesc = rInfo.GetPageDesc( *this ) != + GetEndNoteInfo().GetPageDesc( *this ); + SwCharFmt *pOldChrFmt = GetEndNoteInfo().GetCharFmt( *this ), + *pNewChrFmt = rInfo.GetCharFmt( *this ); + FASTBOOL bFtnChrFmts = pOldChrFmt != pNewChrFmt; + + *pEndNoteInfo = rInfo; + + if ( GetRootFrm() ) + { + if ( bFtnDesc ) + GetRootFrm()->CheckFtnPageDescs( TRUE ); + if ( bExtra ) + { + //Fuer die Benachrichtung bezueglich ErgoSum usw. sparen wir uns + //extra-Code und nutzen die vorhandenen Wege. + SwFtnIdxs& rFtnIdxs = GetFtnIdxs(); + for( USHORT nPos = 0; nPos < rFtnIdxs.Count(); ++nPos ) + { + SwTxtFtn *pTxtFtn = rFtnIdxs[ nPos ]; + const SwFmtFtn &rFtn = pTxtFtn->GetFtn(); + if ( rFtn.IsEndNote() ) + pTxtFtn->SetNumber( rFtn.GetNumber(), &rFtn.GetNumStr()); + } + } + } + if( bNumChg ) + GetFtnIdxs().UpdateAllFtn(); + else if( bFtnChrFmts ) + { + SwFmtChg aOld( pOldChrFmt ); + SwFmtChg aNew( pNewChrFmt ); + pEndNoteInfo->Modify( &aOld, &aNew ); + } + + UpdateRefFlds(); + SetModified(); + } +} + + +BOOL SwDoc::SetCurFtn( const SwPaM& rPam, const String& rNumStr, + USHORT nNumber, BOOL bIsEndNote ) +{ + SwFtnIdxs& rFtnArr = GetFtnIdxs(); + + const SwPosition* pStt = rPam.Start(), *pEnd = rPam.End(); + const ULONG nSttNd = pStt->nNode.GetIndex(); + const xub_StrLen nSttCnt = pStt->nContent.GetIndex(); + const ULONG nEndNd = pEnd->nNode.GetIndex(); + const xub_StrLen nEndCnt = pEnd->nContent.GetIndex(); + + USHORT nPos; + rFtnArr.SeekEntry( pStt->nNode, &nPos ); + + SwUndoChgFtn* pUndo = 0; + if( DoesUndo() ) + { + ClearRedo(); + pUndo = new SwUndoChgFtn( rPam, rNumStr, nNumber, bIsEndNote ); + } + + SwTxtFtn* pTxtFtn; + ULONG nIdx; + BOOL bChg = FALSE; + BOOL bTypeChgd = FALSE; + USHORT n = nPos; // sichern + while( nPos < rFtnArr.Count() && + (( nIdx = _SwTxtFtn_GetIndex((pTxtFtn = rFtnArr[ nPos++ ] ))) + < nEndNd || ( nIdx == nEndNd && + nEndCnt >= *pTxtFtn->GetStart() )) ) + if( nIdx > nSttNd || ( nIdx == nSttNd && + nSttCnt <= *pTxtFtn->GetStart() ) ) + { + const SwFmtFtn& rFtn = pTxtFtn->GetFtn(); + if( /*rFtn.GetNumber() != nNumber ||*/ + rFtn.GetNumStr() != rNumStr || + rFtn.IsEndNote() != bIsEndNote ) + { + bChg = TRUE; + if( pUndo ) + pUndo->GetHistory()->Add( *pTxtFtn ); + + pTxtFtn->SetNumber( nNumber, &rNumStr ); + if( rFtn.IsEndNote() != bIsEndNote ) + { + ((SwFmtFtn&)rFtn).SetEndNote( bIsEndNote ); + bTypeChgd = TRUE; + pTxtFtn->CheckCondColl(); + } + } + } + + nPos = n; // nach vorne gibt es auch noch welche ! + while( nPos && + (( nIdx = _SwTxtFtn_GetIndex((pTxtFtn = rFtnArr[ --nPos ] ))) + > nSttNd || ( nIdx == nSttNd && + nSttCnt <= *pTxtFtn->GetStart() )) ) + if( nIdx < nEndNd || ( nIdx == nEndNd && + nEndCnt >= *pTxtFtn->GetStart() ) ) + { + const SwFmtFtn& rFtn = pTxtFtn->GetFtn(); + if( /*rFtn.GetNumber() != nNumber ||*/ + rFtn.GetNumStr() != rNumStr || + rFtn.IsEndNote() != bIsEndNote ) + { + bChg = TRUE; + if( pUndo ) + pUndo->GetHistory()->Add( *pTxtFtn ); + + pTxtFtn->SetNumber( nNumber, &rNumStr ); + if( rFtn.IsEndNote() != bIsEndNote ) + { + ((SwFmtFtn&)rFtn).SetEndNote( bIsEndNote ); + bTypeChgd = TRUE; + pTxtFtn->CheckCondColl(); + } + } + } + + // wer muss angestossen werden ?? + if( bChg ) + { + if( pUndo ) + { + ClearRedo(); + AppendUndo( pUndo ); + } + + if ( bTypeChgd ) + rFtnArr.UpdateAllFtn(); + if( FTNNUM_PAGE != GetFtnInfo().eNum ) + { + if ( !bTypeChgd ) + rFtnArr.UpdateAllFtn(); + } + else if( GetRootFrm() ) + GetRootFrm()->UpdateFtnNums(); + } + else + delete pUndo; + return bChg; +} + + + + + diff --git a/sw/source/core/doc/docglbl.cxx b/sw/source/core/doc/docglbl.cxx new file mode 100644 index 000000000000..0bcd032ce34a --- /dev/null +++ b/sw/source/core/doc/docglbl.cxx @@ -0,0 +1,566 @@ +/************************************************************************* + * + * $RCSfile: docglbl.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:15 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _HINTIDS_HXX +#include +#endif + +#ifndef _TOOLS_TEMPFILE_HXX +#include +#endif +#ifndef SVTOOLS_URIHELPER_HXX +#include +#endif +#ifndef _URLOBJ_HXX //autogen +#include +#endif +#ifndef _SFXAPP_HXX //autogen +#include +#endif +#ifndef _SFXDOCINF_HXX //autogen +#include +#endif +#ifndef _SFXDOCFILE_HXX //autogen +#include +#endif +#ifndef _SFX_DOCFILT_HACK_HXX //autogen +#include +#endif +#ifndef _FMTINFMT_HXX //autogen +#include +#endif +#ifndef _FMTANCHR_HXX //autogen +#include +#endif +#ifndef _DOC_HXX +#include +#endif +#ifndef _DOCARY_HXX +#include +#endif +#ifndef _PAM_HXX +#include +#endif +#ifndef _NDTXT_HXX +#include +#endif +#ifndef _DOCSH_HXX +#include +#endif +#ifndef _GLOBDOC_HXX +#include +#endif +#ifndef _SHELLIO_HXX +#include +#endif +#ifndef _SWUNDO_HXX +#include // fuer die UndoIds +#endif +#ifndef _SECTION_HXX +#include +#endif +#ifndef _DOCTXM_HXX +#include +#endif +#ifndef _POOLFMT_HXX +#include +#endif + +enum SwSplitDocType +{ + SPLITDOC_TO_GLOBALDOC, + SPLITDOC_TO_HTML +}; + +BOOL SwDoc::GenerateGlobalDoc( const String& rPath, + const SwTxtFmtColl* pSplitColl ) +{ + return SplitDoc( SPLITDOC_TO_GLOBALDOC, rPath, pSplitColl ); +} + +BOOL SwDoc::GenerateHTMLDoc( const String& rPath, + const SwTxtFmtColl* pSplitColl ) +{ +#ifdef JP_TEST + if( !pSplitColl ) + { + BYTE nLvl = 1; + const SwTxtFmtColls& rFmtColls =*GetTxtFmtColls(); + for( USHORT n = rFmtColls.Count(); n; ) + if( nLvl == rFmtColls[ --n ]->GetOutlineLevel() ) + { + pSplitColl = rFmtColls[ n ]; + break; + } + + if( !pSplitColl ) + pSplitColl = GetTxtCollFromPool( RES_POOLCOLL_HEADLINE2 ); + } +#endif + + return SplitDoc( SPLITDOC_TO_HTML, rPath, pSplitColl ); +} + +BOOL SwDoc::SplitDoc( USHORT eDocType, const String& rPath, + const SwTxtFmtColl* pSplitColl ) +{ + // ueber alle Node der Vorlage Iterieren und dafuer einzelne + // Dokumente erzeugen und in diesem gegen + // - gelinkte Bereiche (GlobalDoc) + // - Links (HTML) + // austauschen. + // Am Ende wird dieses Doc als GlobalDoc/HTML-Doc gespreichert. + if( !pDocShell || !pDocShell->GetMedium() || + ( SPLITDOC_TO_GLOBALDOC == eDocType && IsGlobalDoc() ) ) + return FALSE; + + USHORT nOutl = 0; + SwOutlineNodes* pOutlNds = (SwOutlineNodes*)&GetNodes().GetOutLineNds(); + SwNodePtr pSttNd; + + if( pSplitColl ) + { + // wenn keine OutlineNumerierung ist, dann benutze eigenes Array + // und sammel die Nodes zusammen. + if( NO_NUMBERING == pSplitColl->GetOutlineLevel() ) + { + pOutlNds = new SwOutlineNodes( 8, 8 ); + SwClientIter aIter( *(SwModify*)pSplitColl ); + for( SwTxtNode* pTNd = (SwTxtNode*)aIter.First( TYPE( SwTxtNode )); + pTNd; pTNd = (SwTxtNode*)aIter.Next() ) + if( pTNd->GetNodes().IsDocNodes() ) + pOutlNds->Insert( pTNd ); + + if( !pOutlNds->Count() ) + { + delete pOutlNds; + return FALSE; + } + } + } + else + { + // dann suche die Gliederungs - Vorlage, der 1. Ebene + const SwTxtFmtColls& rFmtColls =*GetTxtFmtColls(); + for( USHORT n = rFmtColls.Count(); n; ) + if( !rFmtColls[ --n ]->GetOutlineLevel() ) + { + pSplitColl = rFmtColls[ n ]; + break; + } + + if( !pSplitColl ) + return FALSE; + } + + SfxMedium* pDstMed = new SfxMedium( rPath, STREAM_STD_READWRITE, TRUE ); + + const SfxFilter* pFilter; + switch( eDocType ) + { + case SPLITDOC_TO_HTML: + pFilter = SwIoSystem::GetFilterOfFormat( String::CreateFromAscii( + RTL_CONSTASCII_STRINGPARAM( "HTML" ))); + if( pFilter ) + pDstMed->GetOutStream(); + break; + + default: +// case SPLITDOC_TO_GLOBALDOC: + pFilter = SwIoSystem::GetFilterOfFormat( String::CreateFromAscii( + FILTER_SW5 )); + if( pFilter ) + pDstMed->GetStorage(); + eDocType = SPLITDOC_TO_GLOBALDOC; + break; + } + + if( !pFilter ) + { + delete pDstMed; + return FALSE; + } + + // Undo/Redline aufjedenfall abschalten + DoUndo( FALSE ); + SetRedlineMode_intern( GetRedlineMode() & ~REDLINE_ON ); + + String sExt( pFilter->GetSuffixes().GetToken(0, ',') ); + if( !sExt.Len() ) + sExt.AssignAscii( "sdw" ); + + INetURLObject aEntry(rPath); + String sLeading(aEntry.GetBase()); + aEntry.removeSegment(); + String sPath = aEntry.GetMainURL(); + TempFile aTemp(sLeading,&sExt,&sPath ); + aTemp.EnableKillingFile(); + + DateTime aTmplDate; + { + Time a2Min( 0 ); a2Min.SetMin( 2 ); + aTmplDate += a2Min; + } + + + // alle Ungueltigen ueberspringen + while( nOutl < pOutlNds->Count() && + pOutlNds->GetObject( nOutl )->GetIndex() < GetNodes().GetEndOfExtras().GetIndex() ) + ++nOutl; + + do { + pSttNd = 0; + + SwNodePtr pNd; + for( ; nOutl < pOutlNds->Count(); ++nOutl ) + if( ( pNd = pOutlNds->GetObject( nOutl ))->GetTxtNode()-> + GetTxtColl() == pSplitColl && + !pNd->FindTableNode() ) + { + pSttNd = pNd; + break; + } + + if( pSttNd ) + { + SwNodePtr pEndNd = 0; + for( ++nOutl; nOutl < pOutlNds->Count(); ++nOutl ) + { + pNd = pOutlNds->GetObject( nOutl ); + SwTxtFmtColl* pTColl = pNd->GetTxtNode()->GetTxtColl(); + + if( ( pTColl == pSplitColl || + ( NO_NUMBERING != pSplitColl->GetOutlineLevel() && + pTColl->GetOutlineLevel() < + pSplitColl->GetOutlineLevel() )) && + !pNd->FindTableNode() ) + { + pEndNd = pNd; + break; + } + } + SwNodeIndex aEndIdx( pEndNd ? *pEndNd + : GetNodes().GetEndOfContent() ); + +#ifdef OLD_TOX_BASE_RING + // sollte in dem Bereich Verzeichnisse sein, dann endet die + // Section beim 1. Verzeichnis + if( pTOXBaseRing ) + { + SwTOXBaseRing *pTOXRng = pTOXBaseRing; + do { + const SwNodeIndex& rSttIdx = pTOXRng->Start()->nNode; + if( rSttIdx.GetNode().GetNodes().IsDocNodes() && + ( pSttNd->GetIndex() <= rSttIdx.GetIndex() && + rSttIdx < aEndIdx )) + aEndIdx = rSttIdx; + } while( pTOXBaseRing != ( pTOXRng = (SwTOXBaseRing*)pTOXRng->GetNext() ) ); + } +#endif + + // die Nodes komplett rausschreiben + String sFileName; + if( pSttNd->GetIndex() + 1 < aEndIdx.GetIndex() ) + { + SfxObjectShellRef xDocSh( new SwDocShell( SFX_CREATE_MODE_INTERNAL )); + if( xDocSh->DoInitNew( 0 ) ) + { + SwDoc* pDoc = ((SwDocShell*)(&xDocSh))->GetDoc(); + + // die Vorlage ist das GlobalDoc + SfxDocumentInfo aDocInfo( *pDoc->GetInfo() ); + aDocInfo.SetTemplateName( aEmptyStr ); + aDocInfo.SetTemplateDate( aTmplDate ); + aDocInfo.SetTemplateFileName( rPath ); + //JP 14.06.99: Set the text of the "split para" as title + // from the new doc. Is the current doc has + // a title, insert it at begin. + String sTitle( aDocInfo.GetTitle() ); + if( sTitle.Len() ) + sTitle.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ": " )); + sTitle += ((SwTxtNode*)pSttNd)->GetExpandTxt(); + aDocInfo.SetTitle( sTitle ); + pDoc->SetInfo( aDocInfo ); + + // Vorlagen ersetzen + pDoc->ReplaceStyles( *this ); + + // KapitelNumerierung uebernehmen + if( pOutlineRule ) + pDoc->SetOutlineNumRule( *pOutlineRule ); + + SwNodeRange aRg( *pSttNd, 0, aEndIdx.GetNode() ); + SwNodeIndex aTmpIdx( pDoc->GetNodes().GetEndOfContent() ); + GetNodes()._Copy( aRg, aTmpIdx, FALSE ); + + // den initialen TextNode loeschen + SwNodeIndex aIdx( pDoc->GetNodes().GetEndOfExtras(), 2 ); + if( aIdx.GetIndex() + 1 != + pDoc->GetNodes().GetEndOfContent().GetIndex() ) + pDoc->GetNodes().Delete( aIdx, 1 ); + + // alle Flys in dem Bereich + _CopyFlyInFly( aRg, aIdx ); + + + // und noch alle Bookmarks + // ????? + + INetURLObject aEntry2(rPath); + String sLeading(aEntry2.GetBase()); + aEntry2.removeSegment(); + String sPath = aEntry2.GetMainURL(); + TempFile aTempFile2(sLeading,&sExt,&sPath ); + sFileName = aTempFile2.GetName(); + SfxMedium* pDstMed = new SfxMedium( sFileName, + STREAM_STD_READWRITE, TRUE ); + pDstMed->SetFilter( pFilter ); + + // fuer den HTML-Filter mussen wir aber ein Layout + // haben, damit Textrahmen/Controls/OLE-Objecte korrekt + // als Grafik exportiert werden koennen. + if( SPLITDOC_TO_HTML == eDocType && + pDoc->GetSpzFrmFmts()->Count() ) + { + /* SfxViewFrame* pFrame = */ + SFX_APP()->CreateViewFrame( *xDocSh, 0, TRUE ); + } + xDocSh->DoSaveAs( *pDstMed ); + xDocSh->DoSaveCompleted( pDstMed ); + + // beim Fehler wird keine FileLinkSection eingefuegt + if( xDocSh->GetError() ) + sFileName.Erase(); + } + xDocSh->DoClose(); + } + + // dann koennen ja die Bereiche eingefuegt werden + if( sFileName.Len() ) + { + switch( eDocType ) + { + case SPLITDOC_TO_HTML: + { + // loesche alle Nodes im Bereich und setze im "Start- + // Node" den Link auf das gespeicherte Doc + ULONG nNodeDiff = aEndIdx.GetIndex() - + pSttNd->GetIndex() - 1; + if( nNodeDiff ) + { + SwPaM aTmp( *pSttNd, aEndIdx.GetNode(), 1, -1 ); + aTmp.GetPoint()->nContent.Assign( 0, 0 ); + aTmp.GetMark()->nContent.Assign( 0, 0 ); + SwNodeIndex aSIdx( aTmp.GetMark()->nNode ); + SwNodeIndex aEIdx( aTmp.GetPoint()->nNode ); + + // versuche hinters Ende zu verschieben + if( !aTmp.Move( fnMoveForward, fnGoNode ) ) + { + // na gut, dann an den Anfang + aTmp.Exchange(); + if( !aTmp.Move( fnMoveBackward, fnGoNode )) + { + ASSERT( FALSE, "kein Node mehr vorhanden" ); + } + } + // Bookmarks usw. verschieben + CorrAbs( aSIdx, aEIdx, *aTmp.GetPoint(), TRUE); + + // stehen noch FlyFrames rum, loesche auch diese + const SwPosition* pAPos; + for( USHORT n = 0; n < GetSpzFrmFmts()->Count(); ++n ) + { + SwFrmFmt* pFly = (*GetSpzFrmFmts())[n]; + const SwFmtAnchor* pAnchor = &pFly->GetAnchor(); + if( ( FLY_AT_CNTNT == pAnchor->GetAnchorId() || + FLY_AUTO_CNTNT == pAnchor->GetAnchorId() ) && + 0 != ( pAPos = pAnchor->GetCntntAnchor() ) && + aSIdx <= pAPos->nNode && + pAPos->nNode < aEIdx ) + { + DelLayoutFmt( pFly ); + --n; + } + } + + GetNodes().Delete( aSIdx, nNodeDiff ); + } + + // dann setze im StartNode noch den Link: + SwFmtINetFmt aINet( URIHelper::SmartRelToAbs( + sFileName ), aEmptyStr ); + SwTxtNode* pTNd = (SwTxtNode*)pSttNd; + pTNd->Insert( aINet, 0, pTNd->GetTxt().Len() ); + + // wenn der nicht mehr gefunden wird, kann das nur + // ein Bug sein! + if( !pOutlNds->Seek_Entry( pSttNd, &nOutl )) + pSttNd = 0; + ++nOutl; + } + break; + + default: + { + String sNm( INetURLObject( sFileName ).GetName() ); + SwSection aSect( FILE_LINK_SECTION, + GetUniqueSectionName( &sNm )); + SwSectionFmt* pFmt = MakeSectionFmt( 0 ); + aSect.SetLinkFileName( + URIHelper::SmartRelToAbs( sFileName ) ); + aSect.SetProtect(); + + aEndIdx--; // im InsertSection ist Ende inclusive + while( aEndIdx.GetNode().IsStartNode() ) + aEndIdx--; + + // JP 06.07.99 - Bug 67361 - is any Section ends or + // starts in the new sectionrange, they must end or + // start before or behind the range! + SwSectionNode* pSectNd = pSttNd->FindSectionNode(); + while( pSectNd && pSectNd->EndOfSectionIndex() + <= aEndIdx.GetIndex() ) + { + const SwNode* pSectEnd = pSectNd->EndOfSectionNode(); + if( pSectNd->GetIndex() + 1 == + pSttNd->GetIndex() ) + { + BOOL bMvIdx = aEndIdx == *pSectEnd; + DelSectionFmt( pSectNd->GetSection().GetFmt() ); + if( bMvIdx ) + aEndIdx--; + } + else + { + SwNodeRange aRg( *pSttNd, *pSectEnd ); + SwNodeIndex aIdx( *pSectEnd, 1 ); + GetNodes()._MoveNodes( aRg, GetNodes(), aIdx ); + } + pSectNd = pSttNd->FindSectionNode(); + } + + pSectNd = aEndIdx.GetNode().FindSectionNode(); + while( pSectNd && pSectNd->GetIndex() > + pSttNd->GetIndex() ) + { + SwNodeRange aRg( *pSectNd, 1, aEndIdx, 1 ); + SwNodeIndex aIdx( *pSectNd ); + GetNodes()._MoveNodes( aRg, GetNodes(), aIdx ); + + pSectNd = pSttNd->FindSectionNode(); + } + + pSectNd = GetNodes().InsertSection( + SwNodeIndex( *pSttNd ), + *pFmt, aSect, &aEndIdx, FALSE ); + pSectNd->GetSection().CreateLink( CREATE_CONNECT ); + } + break; + } + } + } + } while( pSttNd ); + +// if( pOutlNds != (SwOutlineNodes*)&GetNodes().GetOutLineNds(); + if( pOutlNds != &GetNodes().GetOutLineNds() ) + delete pOutlNds; + + if( SPLITDOC_TO_GLOBALDOC == eDocType ) + { + // dann das Globaldoc speichern + SetGlobalDoc( TRUE ); + SetGlblDocSaveLinks( FALSE ); + } + else if( IsGlobalDoc() && SPLITDOC_TO_HTML == eDocType ) + { + // dann alles verbliebenen Bereiche aufheben + while( GetSections().Count() ) + DelSectionFmt( GetSections()[ 0 ] ); + } + + pDstMed->SetFilter( pFilter ); + GetDocShell()->DoSaveAs( *pDstMed ); + GetDocShell()->DoSaveCompleted( pDstMed ); + + // richtige Class setzen, es soll ja ein GlobalDocument sein! + if( SPLITDOC_TO_GLOBALDOC == eDocType && + !GetDocShell()->GetError() ) + { + SfxObjectShellRef xDocSh( new SwGlobalDocShell( SFX_CREATE_MODE_INTERNAL )); + SvGlobalName aClassName; + ULONG nClipFormat; + String aAppName, aLongUserName, aUserName; + xDocSh->FillClass( &aClassName, &nClipFormat, &aAppName, &aLongUserName, + &aUserName ); + pDstMed->GetStorage()->SetClass( aClassName, nClipFormat, aUserName ); + } + + return !GetDocShell()->GetError(); +} + + diff --git a/sw/source/core/doc/docglos.cxx b/sw/source/core/doc/docglos.cxx new file mode 100644 index 000000000000..e851f653b45b --- /dev/null +++ b/sw/source/core/doc/docglos.cxx @@ -0,0 +1,189 @@ +/************************************************************************* + * + * $RCSfile: docglos.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:15 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _DOC_HXX +#include +#endif +#ifndef _SHELLIO_HXX +#include +#endif +#ifndef _PAM_HXX +#include +#endif +#ifndef _SWUNDO_HXX +#include +#endif +#ifndef _NDTXT_HXX +#include +#endif +#ifndef _ACORRECT_HXX +#include +#endif +#ifndef _CRSRSH_HXX +#include +#endif + +/* -----------------22.07.99 11:47------------------- + Description: inserts an AutoText block + --------------------------------------------------*/ +BOOL SwDoc::InsertGlossary( SwTextBlocks& rBlock, const String& rEntry, + SwPaM& rPaM, SwCrsrShell* pShell ) +{ + BOOL bRet = FALSE; + USHORT nIdx = rBlock.GetIndex( rEntry ); + if( (USHORT) -1 != nIdx ) + { + // Bug #70238# ask the TextOnly-Flag before BeginGetDoc, because + // the method closed the Storage! + BOOL bSav_IsInsGlossary = bInsOnlyTxtGlssry; + bInsOnlyTxtGlssry = rBlock.IsOnlyTextBlock( nIdx ); + + if( rBlock.BeginGetDoc( nIdx ) ) + { + SwDoc* pGDoc = rBlock.GetDoc(); + + // alle FixFelder aktualisieren. Dann aber auch mit der + // richtigen DocInfo! + pGDoc->SetInfo( *GetInfo() ); + pGDoc->SetFixFields(); + + //StartAllAction(); + LockExpFlds(); + + SwNodeIndex aStt( pGDoc->GetNodes().GetEndOfExtras(), 1 ); + SwCntntNode* pCntntNd = pGDoc->GetNodes().GoNext( &aStt ); + const SwTableNode* pTblNd = pCntntNd->FindTableNode(); + SwPaM aCpyPam( pTblNd ? *(SwNode*)pTblNd : *(SwNode*)pCntntNd ); + aCpyPam.SetMark(); + + // dann bis zum Ende vom Nodes Array + aCpyPam.GetPoint()->nNode = pGDoc->GetNodes().GetEndOfContent().GetIndex()-1; + pCntntNd = aCpyPam.GetCntntNode(); + aCpyPam.GetPoint()->nContent.Assign( pCntntNd, pCntntNd->Len() ); + + // steht nur eine Tabelle im Autotext? Dann kopiere ggfs. + // Tabelle in Tabelle + BOOL bChkTblInTbl = pTblNd && + !aCpyPam.GetPoint()->nContent.GetIndex() && + pTblNd->EndOfSectionIndex() + 1 == + aCpyPam.GetPoint()->nNode.GetIndex(); + + StartUndo( UNDO_INSGLOSSARY ); + SwPaM *_pStartCrsr = &rPaM, *__pStartCrsr = _pStartCrsr; + do { + + const SwTxtNode* pTNd; + SwPosition& rInsPos = *_pStartCrsr->GetPoint(); + SwStartNode* pBoxSttNd = (SwStartNode*)rInsPos.nNode.GetNode(). + FindTableBoxStartNode(); + + // nur wenn die Box keinen Inhalt hat + if( bChkTblInTbl && pBoxSttNd && + 2 == pBoxSttNd->EndOfSectionIndex() - pBoxSttNd->GetIndex() + && 0 != ( pTNd = GetNodes()[ pBoxSttNd->GetIndex() + 1] + ->GetTxtNode() ) && !pTNd->GetTxt().Len() ) + { + CopyTblInTbl( pTblNd->GetTable(), + pBoxSttNd->FindTableNode()->GetTable(), + SwNodeIndex( *pBoxSttNd )); + } + else + { + if( pBoxSttNd && 2 == pBoxSttNd->EndOfSectionIndex() - + pBoxSttNd->GetIndex() && + aCpyPam.GetPoint()->nNode != aCpyPam.GetMark()->nNode ) + { + // es wird mehr als 1 Node in die akt. Box kopiert. + // Dann muessen die BoxAttribute aber entfernt werden. + ClearBoxNumAttrs( rInsPos.nNode ); + } + + SwDontExpandItem aACD; + aACD.SaveDontExpandItems( rInsPos ); + + pGDoc->Copy( aCpyPam, rInsPos ); + + aACD.RestoreDontExpandItems( rInsPos ); + if( pShell ) + pShell->SaveTblBoxCntnt( &rInsPos ); + } + } while( (_pStartCrsr=(SwPaM *)_pStartCrsr->GetNext()) != + __pStartCrsr ); + EndUndo( UNDO_INSGLOSSARY ); + + UnlockExpFlds(); + if( !IsExpFldsLocked() ) + UpdateExpFlds(); + bRet = TRUE; + } + bInsOnlyTxtGlssry = bSav_IsInsGlossary; + } + rBlock.EndGetDoc(); + return bRet; +} + + diff --git a/sw/source/core/doc/doclay.cxx b/sw/source/core/doc/doclay.cxx new file mode 100644 index 000000000000..996cd5d61665 --- /dev/null +++ b/sw/source/core/doc/doclay.cxx @@ -0,0 +1,1924 @@ +/************************************************************************* + * + * $RCSfile: doclay.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:15 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#define ITEMID_BOXINFO SID_ATTR_BORDER_INNER +#ifndef _HINTIDS_HXX +#include +#endif + +#ifndef _SFX_PROGRESS_HXX //autogen +#include +#endif +#ifndef _SVDMODEL_HXX //autogen +#include +#endif +#ifndef _SVDPAGE_HXX //autogen +#include +#endif +#ifndef _SVX_KEEPITEM_HXX //autogen +#include +#endif +#ifndef _SVX_ULSPITEM_HXX //autogen +#include +#endif +#ifndef _SVX_LRSPITEM_HXX //autogen +#include +#endif +#ifndef _SVX_BOXITEM_HXX //autogen +#include +#endif +#ifndef _SVX_SHADITEM_HXX //autogen +#include +#endif +#ifndef _SVX_PROTITEM_HXX //autogen +#include +#endif +#ifndef _SVX_OPAQITEM_HXX //autogen +#include +#endif +#ifndef _SVX_PRNTITEM_HXX //autogen +#include +#endif +#ifndef _SVX_FMGLOB_HXX +#include +#endif +#ifndef _SVDOUNO_HXX //autogen +#include +#endif +#ifndef _SVX_FMPAGE_HXX +#include +#endif +#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_ +#include +#endif + +#ifndef _ERRHDL_HXX +#include +#endif +#ifndef _FRMATR_HXX +#include +#endif +#ifndef _TXATBASE_HXX //autogen +#include +#endif +#ifndef _FMTFLD_HXX //autogen +#include +#endif +#ifndef _FMTORNT_HXX //autogen +#include +#endif +#ifndef _FMTCNTNT_HXX //autogen +#include +#endif +#ifndef _FMTANCHR_HXX //autogen +#include +#endif +#ifndef _FMTFSIZE_HXX //autogen +#include +#endif +#ifndef _FMTSRND_HXX //autogen +#include +#endif +#ifndef _FMTFLCNT_HXX //autogen +#include +#endif +#ifndef _FRMCNCT_HXX //autogen +#include +#endif +#ifndef _FRMFMT_HXX //autogen +#include +#endif +#ifndef _DCONTACT_HXX //autogen +#include +#endif +#ifndef _TXTFLCNT_HXX //autogen +#include +#endif +#ifndef _DOCFLD_HXX +#include // fuer Expression-Felder +#endif +#ifndef _PAM_HXX +#include +#endif +#ifndef _NDTXT_HXX +#include +#endif +#ifndef _NDNOTXT_HXX +#include +#endif +#ifndef _NDOLE_HXX +#include +#endif +#ifndef _DOC_HXX +#include +#endif +#ifndef _ROOTFRM_HXX +#include +#endif +#ifndef _PAGEFRM_HXX +#include +#endif +#ifndef _CNTFRM_HXX +#include +#endif +#ifndef _FLYFRM_HXX +#include +#endif +#ifndef _FESH_HXX +#include +#endif +#ifndef _DOCSH_HXX +#include +#endif +#ifndef _DFLYOBJ_HXX +#include +#endif +#ifndef _DCONTACT_HXX +#include +#endif +#ifndef _SWUNDO_HXX +#include +#endif +#ifndef _FLYPOS_HXX +#include +#endif +#ifndef _UNDOBJ_HXX +#include +#endif +#ifndef _EXPFLD_HXX +#include // InsertLabel +#endif +#ifndef _POOLFMT_HXX +#include // PoolVorlagen-Id's +#endif +#ifndef _DOCARY_HXX +#include +#endif +#ifndef _SWTABLE_HXX +#include +#endif +#ifndef _TBLSEL_HXX +#include +#endif +#ifndef _VIEWOPT_HXX +#include +#endif +#ifndef _FLDUPDE_HXX +#include +#endif +#ifndef _TXTFTN_HXX //autogen +#include +#endif +#ifndef _FTNIDX_HXX //autogen +#include +#endif + +#ifndef _COMCORE_HRC +#include // STR-ResId's +#endif + +using namespace ::com::sun::star; +using namespace ::rtl; + +#define DEF_FLY_WIDTH 2268 //Defaultbreite fuer FlyFrms (2268 == 4cm) + +/************************************************************************* +|* +|* SwDoc::MakeLayoutFmt() +|* +|* Beschreibung Erzeugt ein neues Format das in seinen Einstellungen +|* Defaultmaessig zu dem Request passt. Das Format wird in das +|* entsprechende Formate-Array gestellt. +|* Wenn bereits ein passendes Format existiert, so wird dies +|* zurueckgeliefert. +|* Ersterstellung MA 22. Sep. 92 +|* Letzte Aenderung JP 08.05.98 +|* +|*************************************************************************/ + +SwFrmFmt *SwDoc::MakeLayoutFmt( RndStdIds eRequest, SwFrmFmt* pFrmFmt, + const SfxItemSet* pSet ) +{ + SwFrmFmt *pFmt = 0; + const sal_Bool bMod = IsModified(); + sal_Bool bHeader = sal_False; + + switch ( eRequest ) + { + case RND_STD_HEADER: + case RND_STD_HEADERL: + case RND_STD_HEADERR: + { + bHeader = sal_True; + // kein break, es geht unten weiter + } + case RND_STD_FOOTER: + case RND_STD_FOOTERL: + case RND_STD_FOOTERR: + { + +//JP erstmal ein Hack, solange keine Flys/Headers/Footers Undofaehig sind +if( DoesUndo() ) + DelAllUndoObj(); + + pFmt = new SwFrmFmt( GetAttrPool(), + (bHeader ? "Header" : "Footer"), + GetDfltFrmFmt() ); + + SwNodeIndex aTmpIdx( GetNodes().GetEndOfAutotext() ); + SwStartNode* pSttNd = GetNodes().MakeTextSection( aTmpIdx, + bHeader ? SwHeaderStartNode : SwFooterStartNode, + GetTxtCollFromPool( + bHeader + ? ( eRequest == RND_STD_HEADERL + ? RES_POOLCOLL_HEADERL + : eRequest == RND_STD_HEADERR + ? RES_POOLCOLL_HEADERR + : RES_POOLCOLL_HEADER ) + : ( eRequest == RND_STD_FOOTERL + ? RES_POOLCOLL_FOOTERL + : eRequest == RND_STD_FOOTERR + ? RES_POOLCOLL_FOOTERR + : RES_POOLCOLL_FOOTER ) + ) ); + pFmt->SetAttr( SwFmtCntnt( pSttNd )); + + if( pSet ) // noch ein paar Attribute setzen ? + pFmt->SetAttr( *pSet ); + +// JP: warum zuruecksetzen ??? Doc. ist doch veraendert ??? +// bei den Fly auf jedenfall verkehrt !! + if ( !bMod ) + ResetModified(); + } + break; + + case RND_DRAW_OBJECT: + { + pFmt = MakeDrawFrmFmt( aEmptyStr, GetDfltFrmFmt() ); + if( pSet ) // noch ein paar Attribute setzen ? + pFmt->SetAttr( *pSet ); + + if( DoesUndo() ) + { + ClearRedo(); + AppendUndo( new SwUndoInsLayFmt( pFmt )); + } + } + break; + +#ifndef PRODUCT + case FLY_PAGE: + case FLY_AUTO_CNTNT: + case FLY_AT_FLY: + case FLY_AT_CNTNT: + case FLY_IN_CNTNT: + ASSERT( !this, + "neue Schnittstelle benutzen: SwDoc::MakeFlySection!" ); + break; +#endif + + default: + ASSERT( !this, + "Layoutformat mit ungueltigem Request angefordert." ); + + } + return pFmt; +} +/************************************************************************* +|* +|* SwDoc::DelLayoutFmt() +|* +|* Beschreibung Loescht das angegebene Format, der Inhalt wird mit +|* geloescht. +|* Ersterstellung MA 23. Sep. 92 +|* Letzte Aenderung MA 05. Feb. 93 +|* +|*************************************************************************/ + +void SwDoc::DelLayoutFmt( SwFrmFmt *pFmt ) +{ + //Verkettung von Rahmen muss ggf. zusammengefuehrt werden. + //Bevor die Frames vernichtet werden, damit die Inhalte der Rahmen + //ggf. entsprechend gerichtet werden. + const SwFmtChain &rChain = pFmt->GetChain(); + if ( rChain.GetPrev() ) + { + SwFmtChain aChain( rChain.GetPrev()->GetChain() ); + aChain.SetNext( rChain.GetNext() ); + SetAttr( aChain, *rChain.GetPrev() ); + } + if ( rChain.GetNext() ) + { + SwFmtChain aChain( rChain.GetNext()->GetChain() ); + aChain.SetPrev( rChain.GetPrev() ); + SetAttr( aChain, *rChain.GetNext() ); + } + + const SwNodeIndex* pCntIdx = pFmt->GetCntnt().GetCntntIdx(); + if( pCntIdx ) + { + //Verbindung abbauen, falls es sich um ein OLE-Objekt handelt. + SwOLENode* pOLENd = GetNodes()[ pCntIdx->GetIndex()+1 ]->GetOLENode(); + if( pOLENd && pOLENd->GetOLEObj().IsOleRef() ) + pOLENd->GetOLEObj().GetOleRef()->DoClose(); + } + + //Frms vernichten. + pFmt->DelFrms(); + + // erstmal sind nur Fly's Undofaehig + const sal_uInt16 nWh = pFmt->Which(); + if( DoesUndo() && (RES_FLYFRMFMT == nWh || RES_DRAWFRMFMT == nWh) ) + { + // erstmal werden alle Undo - Objecte geloescht. + ClearRedo(); + AppendUndo( new SwUndoDelLayFmt( pFmt )); + } + else + { + //Inhalt Loeschen. + if( pCntIdx ) + { + +//JP erstmal ein Hack, solange keine Headers/Footers Undofaehig sind +if( DoesUndo() ) + DelAllUndoObj(); + + SwNode *pNode = &pCntIdx->GetNode(); + ((SwFmtCntnt&)pFmt->GetAttr( RES_CNTNT )).SetNewCntntIdx( 0 ); + DeleteSection( pNode ); + } + + // ggfs. bei Zeichengebundenen Flys das Zeichen loeschen + const SwFmtAnchor& rAnchor = pFmt->GetAnchor(); + if( FLY_IN_CNTNT == rAnchor.GetAnchorId() && rAnchor.GetCntntAnchor()) + { + const SwPosition* pPos = rAnchor.GetCntntAnchor(); + SwTxtNode *pTxtNd = pPos->nNode.GetNode().GetTxtNode(); + SwTxtFlyCnt* pAttr; + + // Attribut steht noch im TextNode, loeschen + if( pTxtNd && 0 != ( pAttr = ((SwTxtFlyCnt*)pTxtNd->GetTxtAttr( + pPos->nContent.GetIndex() ))) && + pAttr->GetFlyCnt().GetFrmFmt() == pFmt ) + { + // Pointer auf 0, nicht loeschen + ((SwFmtFlyCnt&)pAttr->GetFlyCnt()).SetFlyFmt(); + SwIndex aIdx( pPos->nContent ); + pTxtNd->Erase( aIdx, 1 ); + } + } + + DelFrmFmt( pFmt ); + } + SetModified(); +} + +/************************************************************************* +|* +|* SwDoc::CopyLayoutFmt() +|* +|* Beschreibung Kopiert das angegebene Format pSrc in pDest und +|* returnt pDest. Wenn es noch kein pDest gibt, wird +|* eins angelegt. +|* JP: steht das Source Format in einem anderen +|* Dokument, so kopiere auch dann noch richtig !! +|* Vom chaos::Anchor-Attribut wird die Position immer +|* auf 0 gesetzt !!! +|* +|* Ersterstellung BP 18.12.92 +|* Letzte Aenderung MA 17. Jul. 96 +|* +|*************************************************************************/ + +SwFrmFmt *SwDoc::CopyLayoutFmt( const SwFrmFmt& rSource, + const SwFmtAnchor& rNewAnchor, + sal_Bool bSetTxtFlyAtt, sal_Bool bMakeFrms ) +{ + SwDoc* pSrcDoc = (SwDoc*)rSource.GetDoc(); + + const sal_Bool bFly = RES_FLYFRMFMT == rSource.Which(); + + //DrawObjecte duerfen niemals in Kopf-/Fusszeilen landen. + // JP 31.05.96: die Zeichengebundenen muessen spaeter abgeprueft werden. + // Und zwar wenn sie in den ZielNode eingefuegt werden; + // erst dann ist der richtige Anker gueltig !!!! + if( !bFly && + ( FLY_AT_CNTNT == rNewAnchor.GetAnchorId() || + FLY_AT_FLY == rNewAnchor.GetAnchorId() || + FLY_AUTO_CNTNT == rNewAnchor.GetAnchorId() ) && + rNewAnchor.GetCntntAnchor() && + IsInHeaderFooter( rNewAnchor.GetCntntAnchor()->nNode ) ) + return 0; + + SwFrmFmt* pDest = GetDfltFrmFmt(); + if( rSource.GetRegisteredIn() != pSrcDoc->GetDfltFrmFmt() ) + pDest = CopyFrmFmt( *(SwFrmFmt*)rSource.GetRegisteredIn() ); + if( bFly ) + pDest = MakeFlyFrmFmt( rSource.GetName(), pDest ); + else + pDest = MakeDrawFrmFmt( aEmptyStr, pDest ); + + // alle anderen/neue Attribute kopieren. + pDest->CopyAttrs( rSource ); + + //Chains werden nicht kopiert. + pDest->ResetAttr( RES_CHAIN ); + + if( bFly ) + { + //Der Inhalt wird dupliziert. + const SwNode& rCSttNd = rSource.GetCntnt().GetCntntIdx()->GetNode(); + SwNodeRange aRg( rCSttNd, 1, *rCSttNd.EndOfSectionNode() ); + + SwNodeIndex aIdx( GetNodes().GetEndOfAutotext() ); + SwStartNode* pSttNd = GetNodes().MakeEmptySection( aIdx, SwFlyStartNode ); + + // erst den chaos::Anchor/CntntIndex setzen, innerhalb des Kopierens + // auf die Werte zugegriffen werden kann (DrawFmt in Kopf-/Fusszeilen) + aIdx = *pSttNd; + SwFmtCntnt aAttr( rSource.GetCntnt() ); + aAttr.SetNewCntntIdx( &aIdx ); + pDest->SetAttr( aAttr ); + pDest->SetAttr( rNewAnchor ); + + if( !bCopyIsMove || this != pSrcDoc ) + { + if( bInReading ) + pDest->SetName( aEmptyStr ); + else + { + // Teste erstmal ob der Name schon vergeben ist. + // Wenn ja -> neuen generieren + sal_Int8 nNdTyp = aRg.aStart.GetNode().GetNodeType(); + + String sOld( pDest->GetName() ); + pDest->SetName( aEmptyStr ); + if( FindFlyByName( sOld, nNdTyp ) ) // einen gefunden + switch( nNdTyp ) + { + case ND_GRFNODE: sOld = GetUniqueGrfName(); break; + case ND_OLENODE: sOld = GetUniqueOLEName(); break; + default: sOld = GetUniqueFrameName(); break; + } + + pDest->SetName( sOld ); + } + } + + if( DoesUndo() ) + { + ClearRedo(); + AppendUndo( new SwUndoInsLayFmt( pDest )); + } + + // sorge dafuer das auch Fly's in Fly's kopiert werden + aIdx = *pSttNd->EndOfSectionNode(); + pSrcDoc->CopyWithFlyInFly( aRg, aIdx, sal_False, sal_True, sal_True ); + } + else + { + ASSERT( RES_DRAWFRMFMT == rSource.Which(), "Weder Fly noch Draw." ); + SwDrawContact *pContact = (SwDrawContact *)rSource.FindContactObj(); + + pContact = new SwDrawContact( (SwDrawFrmFmt*)pDest, + CloneSdrObj( *pContact->GetMaster(), + bCopyIsMove && this == pSrcDoc ) ); + + if( pDest->GetAnchor() == rNewAnchor ) + pContact->ConnectToLayout( &rNewAnchor ); + else + pDest->SetAttr( rNewAnchor ); + + if( DoesUndo() ) + { + ClearRedo(); + AppendUndo( new SwUndoInsLayFmt( pDest )); + } + } + + if( bSetTxtFlyAtt && FLY_IN_CNTNT == rNewAnchor.GetAnchorId() ) + { + SwPosition* pPos = (SwPosition*)rNewAnchor.GetCntntAnchor(); + pPos->nNode.GetNode().GetTxtNode()->Insert(SwFmtFlyCnt( pDest ), + pPos->nContent.GetIndex(), 0 ); + } + + if( bMakeFrms ) + pDest->MakeFrms(); + + return pDest; +} + +SdrObject* SwDoc::CloneSdrObj( const SdrObject& rObj, sal_Bool bMoveWithinDoc, + sal_Bool bInsInPage ) +{ + SdrPage *pPg = MakeDrawModel()->GetPage( 0 ); + if( !pPg ) + { + pPg = GetDrawModel()->AllocPage( sal_False ); + GetDrawModel()->InsertPage( pPg ); + } + + SdrObject *pObj = rObj.Clone(); + if( bMoveWithinDoc && FmFormInventor == pObj->GetObjInventor() ) + { + // bei Controls muss der Name erhalten bleiben + uno::Reference< awt::XControlModel > xModel = ((SdrUnoObj*)pObj)->GetUnoControlModel(); + sal_Bool bModel = xModel.is(); + uno::Any aVal; + uno::Reference< beans::XPropertySet > xSet(xModel, uno::UNO_QUERY); + OUString sName( rtl::OUString::createFromAscii("Name") ); + if( xSet.is() ) + aVal = xSet->getPropertyValue( sName ); + if( bInsInPage ) + pPg->InsertObject( pObj ); + if( xSet.is() ) + xSet->setPropertyValue( sName, aVal ); + } + else if( bInsInPage ) + pPg->InsertObject( pObj ); + + pObj->SetLayer( rObj.GetLayer() ); + return pObj; +} + +SwFlyFrmFmt* SwDoc::_MakeFlySection( const SwPosition& rAnchPos, + const SwCntntNode& rNode, + RndStdIds eRequestId, + const SfxItemSet* pFlySet, + SwFrmFmt* pFrmFmt ) +{ + if( !pFrmFmt ) + pFrmFmt = GetFrmFmtFromPool( RES_POOLFRM_FRAME ); + + String sName; + if( !bInReading ) + switch( rNode.GetNodeType() ) + { + case ND_GRFNODE: sName = GetUniqueGrfName(); break; + case ND_OLENODE: sName = GetUniqueOLEName(); break; + default: sName = GetUniqueFrameName(); break; + } + SwFlyFrmFmt* pFmt = MakeFlyFrmFmt( sName, pFrmFmt ); + + //Inhalt erzeugen und mit dem Format verbinden. + //CntntNode erzeugen und in die Autotextsection stellen + SwNodeRange aRange( GetNodes().GetEndOfAutotext(), -1, + GetNodes().GetEndOfAutotext() ); + GetNodes().SectionDown( &aRange, SwFlyStartNode ); + + pFmt->SetAttr( SwFmtCntnt( rNode.StartOfSectionNode() )); + + + const SwFmtAnchor* pAnchor = 0; + if( pFlySet ) + { + pFlySet->GetItemState( RES_ANCHOR, sal_False, + (const SfxPoolItem**)&pAnchor ); + if( SFX_ITEM_SET == pFlySet->GetItemState( RES_CNTNT, sal_False )) + { + SfxItemSet aTmpSet( *pFlySet ); + aTmpSet.ClearItem( RES_CNTNT ); + pFmt->SetAttr( aTmpSet ); + } + else + pFmt->SetAttr( *pFlySet ); + } + + // Anker noch nicht gesetzt ? + RndStdIds eAnchorId = pAnchor ? pAnchor->GetAnchorId() + : pFmt->GetAnchor().GetAnchorId(); + if( !pAnchor || + (FLY_PAGE != pAnchor->GetAnchorId() && + //Nur Page und nicht: +// FLY_AT_CNTNT == pAnchor->GetAnchorId() || +// FLY_IN_CNTNT == pAnchor->GetAnchorId() || +// FLY_AT_FLY == pAnchor->GetAnchorId() || +// FLY_AUTO_CNTNT == pAnchor->GetAnchorId() ) && + !pAnchor->GetCntntAnchor() )) + { + // dann setze ihn, wird im Undo gebraucht + SwFmtAnchor aAnch( pFmt->GetAnchor() ); + if( pAnchor && FLY_AT_FLY == pAnchor->GetAnchorId() ) + { + SwPosition aPos( *rAnchPos.nNode.GetNode().FindFlyStartNode() ); + aAnch.SetAnchor( &aPos ); + eAnchorId = FLY_AT_FLY; + } + else + { + if( eRequestId != aAnch.GetAnchorId() && + SFX_ITEM_SET != pFmt->GetItemState( RES_ANCHOR, sal_True ) ) + aAnch.SetType( eRequestId ); + + eAnchorId = aAnch.GetAnchorId(); + if ( FLY_PAGE != eAnchorId ) + //Nur Page und nicht: +// if( FLY_AT_CNTNT == eAnchorId || FLY_IN_CNTNT == eAnchorId || +// FLY_AT_FLY == eAnchorId || FLY_AUTO_CNTNT == eAnchorId ) + aAnch.SetAnchor( &rAnchPos ); + } + pFmt->SetAttr( aAnch ); + } + else + eAnchorId = pFmt->GetAnchor().GetAnchorId(); + + if( FLY_IN_CNTNT == eAnchorId ) + { + xub_StrLen nStt = rAnchPos.nContent.GetIndex(); + rAnchPos.nNode.GetNode().GetTxtNode()->Insert( + SwFmtFlyCnt( pFmt ), nStt, nStt ); + } + + if( SFX_ITEM_SET != pFmt->GetAttrSet().GetItemState( RES_FRM_SIZE )) + { + SwFmtFrmSize aFmtSize( ATT_VAR_SIZE, 0, DEF_FLY_WIDTH ); + const SwNoTxtNode* pNoTxtNode = rNode.GetNoTxtNode(); + if( pNoTxtNode ) + { + //Groesse einstellen. + Size aSize( pNoTxtNode->GetTwipSize() ); + if( MINFLY > aSize.Width() ) + aSize.Width() = DEF_FLY_WIDTH; + aFmtSize.SetWidth( aSize.Width() ); + if( aSize.Height() ) + { + aFmtSize.SetHeight( aSize.Height() ); + aFmtSize.SetSizeType( ATT_FIX_SIZE ); + } + } + pFmt->SetAttr( aFmtSize ); + } + + // Frames anlegen + if( GetRootFrm() ) + pFmt->MakeFrms(); // ??? + + if( DoesUndo() ) + { + ClearRedo(); + AppendUndo( new SwUndoInsLayFmt( pFmt )); + } + + SetModified(); + return pFmt; +} + +SwFlyFrmFmt* SwDoc::MakeFlySection( RndStdIds eAnchorType, + const SwPosition* pAnchorPos, + const SfxItemSet* pFlySet, + SwFrmFmt* pFrmFmt ) +{ + SwFlyFrmFmt* pFmt = 0; + sal_Bool bCallMake = sal_True; + if( !pAnchorPos && FLY_PAGE != eAnchorType ) + { + const SwFmtAnchor* pAnch; + if( (pFlySet && SFX_ITEM_SET == pFlySet->GetItemState( + RES_ANCHOR, sal_False, (const SfxPoolItem**)&pAnch )) || + ( pFrmFmt && SFX_ITEM_SET == pFrmFmt->GetItemState( + RES_ANCHOR, sal_True, (const SfxPoolItem**)&pAnch )) ) + { + if( FLY_PAGE != pAnch->GetAnchorId() && + 0 == ( pAnchorPos = pAnch->GetCntntAnchor() ) ) + bCallMake = sal_False; + } + } + + if( bCallMake ) + { + if( !pFrmFmt ) + pFrmFmt = GetFrmFmtFromPool( RES_POOLFRM_FRAME ); + + sal_uInt16 nCollId = IsHTMLMode() ? RES_POOLCOLL_TEXT : RES_POOLCOLL_FRAME; + pFmt = _MakeFlySection( *pAnchorPos, *GetNodes().MakeTxtNode( + SwNodeIndex( GetNodes().GetEndOfAutotext() ), + GetTxtCollFromPool( nCollId ) ), + eAnchorType, pFlySet, pFrmFmt ); + } + return pFmt; +} + +SwFlyFrmFmt* SwDoc::MakeFlyAndMove( const SwPaM& rPam, const SfxItemSet& rSet, + const SwSelBoxes* pSelBoxes, + SwFrmFmt *pParent ) +{ + SwFmtAnchor& rAnch = (SwFmtAnchor&)rSet.Get( RES_ANCHOR ); + + StartUndo( UNDO_INSLAYFMT ); + + SwFlyFrmFmt* pFmt = MakeFlySection( rAnch.GetAnchorId(), rPam.GetPoint(), + &rSet, pParent ); + + // Wenn Inhalt selektiert ist, so wird dieser jetzt zum Inhalt des + // neuen Rahmen. Sprich er wird in die entspr. Sektion des NodesArr + //gemoved. + + if( pFmt ) + { + do { // middle check loop + const SwFmtCntnt &rCntnt = pFmt->GetCntnt(); + ASSERT( rCntnt.GetCntntIdx(), "Kein Inhalt vorbereitet." ); + SwNodeIndex aIndex( *(rCntnt.GetCntntIdx()), 1 ); + SwCntntNode *pNode = aIndex.GetNode().GetCntntNode(); + + // ACHTUNG: nicht einen Index auf dem Stack erzeugen, sonst + // kann der CntntnNode am Ende nicht geloscht werden !! + SwPosition aPos( aIndex ); + aPos.nContent.Assign( pNode, 0 ); + + if( pSelBoxes && pSelBoxes->Count() ) + { + // Tabellenselection + // kopiere Teile aus einer Tabelle: lege eine Tabelle mit der + // Breite der Originalen an und move (kopiere/loesche) die + // selektierten Boxen. Die Groessen werden prozentual + // korrigiert. + + SwTableNode* pTblNd = (SwTableNode*)(*pSelBoxes)[0]-> + GetSttNd()->FindTableNode(); + if( !pTblNd ) + break; + + SwTable& rTbl = pTblNd->GetTable(); + + // ist die gesamte Tabelle selektiert ? + if( pSelBoxes->Count() == rTbl.GetTabSortBoxes().Count() ) + { + // verschiebe die gesamte Tabelle + SwNodeRange aRg( *pTblNd, 0, *pTblNd->EndOfSectionNode(), 1 ); + + // wird die gesamte Tabelle verschoben und steht diese + // in einem FlyFrame, dann erzeuge dahinter einen neuen + // TextNode. Dadurch bleibt dieser Fly erhalten ! + if( aRg.aEnd.GetNode().IsEndNode() ) + GetNodes().MakeTxtNode( aRg.aStart, + (SwTxtFmtColl*)GetDfltTxtFmtColl() ); + + Move( aRg, aPos.nNode ); + } + else + { + rTbl.MakeCopy( this, aPos, *pSelBoxes ); + rTbl.DeleteSel( this, *pSelBoxes ); + } + + // wenn Tabelle im Rahmen, dann ohne nachfolgenden TextNode + aIndex = rCntnt.GetCntntIdx()->GetNode().EndOfSectionIndex() - 1; + ASSERT( aIndex.GetNode().GetTxtNode(), + "hier sollte ein TextNode stehen" ); + aPos.nContent.Assign( 0, 0 ); // Index abmelden !! + GetNodes().Delete( aIndex, 1 ); + +//JP erstmal ein Hack, solange keine Flys/Headers/Footers Undofaehig sind +if( DoesUndo() ) // werden erstmal alle Undo - Objecte geloescht. + DelAllUndoObj(); + + } + else + { + // alle Pams verschieben + SwPaM* pTmp = (SwPaM*)&rPam; + do { + if( pTmp->HasMark() && + *pTmp->GetPoint() != *pTmp->GetMark() ) + MoveAndJoin( *pTmp, aPos ); + } while( &rPam != ( pTmp = (SwPaM*)pTmp->GetNext() ) ); + } + } while( sal_False ); + } + + SetModified(); + + EndUndo( UNDO_INSLAYFMT ); + + return pFmt; +} + + + //Einfuegen eines DrawObjectes. Das Object muss bereits im DrawModel + // angemeldet sein. +SwDrawFrmFmt* SwDoc::Insert( const SwPaM &rRg, + SdrObject& rDrawObj, + const SfxItemSet* pFlyAttrSet, + SwFrmFmt* pDefFmt ) +{ + SwDrawFrmFmt *pFmt = MakeDrawFrmFmt( aEmptyStr, + pDefFmt ? pDefFmt : GetDfltFrmFmt() ); + + const SwFmtAnchor* pAnchor = 0; + if( pFlyAttrSet ) + { + pFlyAttrSet->GetItemState( RES_ANCHOR, sal_False, + (const SfxPoolItem**)&pAnchor ); + pFmt->SetAttr( *pFlyAttrSet ); + } + + RndStdIds eAnchorId = pAnchor ? pAnchor->GetAnchorId() + : pFmt->GetAnchor().GetAnchorId(); + + // Anker noch nicht gesetzt ? + // DrawObjecte duerfen niemals in Kopf-/Fusszeilen landen. + sal_Bool bIsAtCntnt = FLY_PAGE != eAnchorId; +// FLY_AT_CNTNT == eAnchorId || FLY_IN_CNTNT == eAnchorId || +// FLY_AT_FLY == eAnchorId || FLY_AUTO_CNTNT == eAnchorId; + + const SwNodeIndex* pChkIdx = 0; + if( !pAnchor ) + pChkIdx = &rRg.GetPoint()->nNode; + else if( bIsAtCntnt ) + pChkIdx = pAnchor->GetCntntAnchor() + ? &pAnchor->GetCntntAnchor()->nNode + : &rRg.GetPoint()->nNode; + + if( pChkIdx && IsInHeaderFooter( *pChkIdx ) ) + pFmt->SetAttr( SwFmtAnchor( eAnchorId = FLY_PAGE ) ); + else if( !pAnchor || (bIsAtCntnt && !pAnchor->GetCntntAnchor() )) + { + // dann setze ihn, wird im Undo gebraucht + SwFmtAnchor aAnch( pAnchor ? *pAnchor : pFmt->GetAnchor() ); + eAnchorId = aAnch.GetAnchorId(); + if( FLY_AT_FLY == eAnchorId ) + { + SwPosition aPos( *rRg.GetNode()->FindFlyStartNode() ); + aAnch.SetAnchor( &aPos ); + } + else + { + aAnch.SetAnchor( rRg.GetPoint() ); + if( FLY_PAGE == eAnchorId ) + { + eAnchorId = rDrawObj.ISA( SdrUnoObj ) + ? FLY_IN_CNTNT : FLY_AT_CNTNT; + aAnch.SetType( eAnchorId ); + } + } + pFmt->SetAttr( aAnch ); + } + + // bei als Zeichen gebundenen Draws das Attribut im Absatz setzen + if( FLY_IN_CNTNT == eAnchorId ) + { + xub_StrLen nStt = rRg.GetPoint()->nContent.GetIndex(); + rRg.GetPoint()->nNode.GetNode().GetTxtNode()->Insert( + SwFmtFlyCnt( pFmt ), nStt, nStt ); + } + + new SwDrawContact( pFmt, &rDrawObj ); + + // ggfs. Frames anlegen + if( GetRootFrm() ) + pFmt->MakeFrms(); + + if( DoesUndo() ) + { + ClearRedo(); + AppendUndo( new SwUndoInsLayFmt( pFmt )); + } + + SetModified(); + return pFmt; +} + +/************************************************************************* +|* +|* SwDoc::GetAllFlyFmts +|* +|* Ersterstellung MA 14. Jul. 93 +|* Letzte Aenderung MD 23. Feb. 95 +|* +|*************************************************************************/ + +/*sal_Bool TstFlyRange( const SwPaM* pPam, sal_uInt32 nFlyPos ) +{ + sal_Bool bOk = sal_False; + const SwPaM* pTmp = pPam; + do { + bOk = pTmp->Start()->nNode.GetIndex() < nFlyPos && + pTmp->End()->nNode.GetIndex() > nFlyPos; + } while( !bOk && pPam != ( pTmp = (const SwPaM*)pTmp->GetNext() )); + return bOk; +} +*/ +/* -----------------------------04.04.00 10:55-------------------------------- + paragraph frames - o.k. if the PaM includes the paragraph from the beginning + to the beginning of the next paragraph at least + frames at character - o.k. if the pam start at least at the same position + as the frame + ---------------------------------------------------------------------------*/ +sal_Bool TstFlyRange( const SwPaM* pPam, const SwPosition* pFlyPos, + RndStdIds nAnchorId ) +{ + sal_Bool bOk = FALSE; + const SwPaM* pTmp = pPam; + do { + const sal_uInt32 nFlyIndex = pFlyPos->nNode.GetIndex(); + const SwPosition* pPaMStart = pTmp->Start(); + const SwPosition* pPaMEnd = pTmp->End(); + const sal_uInt32 nPamStartIndex = pPaMStart->nNode.GetIndex(); + const sal_uInt32 nPamEndIndex = pPaMEnd->nNode.GetIndex(); + if(FLY_AT_CNTNT == nAnchorId) + bOk = (nPamStartIndex < nFlyIndex && nPamEndIndex > nFlyIndex) || + (((nPamStartIndex == nFlyIndex) && (pPaMStart->nContent.GetIndex() == 0)) && + (nPamEndIndex > nFlyIndex)); + else + { + xub_StrLen nFlyContentIndex = pFlyPos->nContent.GetIndex(); + xub_StrLen nPamEndContentIndex = pPaMEnd->nContent.GetIndex(); + bOk = (nPamStartIndex < nFlyIndex && + (( nPamEndIndex > nFlyIndex )|| + ((nPamEndIndex == nFlyIndex) && + (nPamEndContentIndex = nFlyContentIndex))) ) + || + (((nPamStartIndex == nFlyIndex) && + (pPaMStart->nContent.GetIndex() <= nFlyContentIndex)) && + (nPamEndIndex > nFlyIndex) || + (nPamEndContentIndex > nFlyContentIndex )); + } + + } while( !bOk && pPam != ( pTmp = (const SwPaM*)pTmp->GetNext() )); + return bOk; +} + + +void SwDoc::GetAllFlyFmts( SwPosFlyFrms& rPosFlyFmts, + const SwPaM* pCmpRange, sal_Bool bDrawAlso ) const +{ + SwPosFlyFrm *pFPos = 0; + const SwPosition* pAPos; + SwFrmFmt *pFly; + + // erstmal alle Absatzgebundenen einsammeln + for( sal_uInt16 n = 0; n < GetSpzFrmFmts()->Count(); ++n ) + { + pFly = (*GetSpzFrmFmts())[ n ]; + sal_Bool bDrawFmt = bDrawAlso ? RES_DRAWFRMFMT == pFly->Which() : sal_False; + sal_Bool bFlyFmt = RES_FLYFRMFMT == pFly->Which(); + if( bFlyFmt || bDrawFmt ) + { + const SwFmtAnchor& rAnchor = pFly->GetAnchor(); + if( ( FLY_AT_CNTNT == rAnchor.GetAnchorId() || + FLY_AT_FLY == rAnchor.GetAnchorId() || + FLY_AUTO_CNTNT == rAnchor.GetAnchorId() ) && + 0 != ( pAPos = rAnchor.GetCntntAnchor()) ) + { + if( pCmpRange && + !TstFlyRange( pCmpRange, pAPos, rAnchor.GetAnchorId() )) + continue; // kein gueltiger FlyFrame + pFPos = new SwPosFlyFrm( pAPos->nNode, pFly, rPosFlyFmts.Count() ); + rPosFlyFmts.Insert( pFPos ); + } + } + } + + // kein Layout oder nur ein Teil, dann wars das + // Seitenbezogen Flys nur, wenn vollstaendig "gewuenscht" wird ! + if( !GetRootFrm() || pCmpRange ) + return; + + pFPos = 0; + SwPageFrm *pPage = (SwPageFrm*)GetRootFrm()->GetLower(); + while( pPage ) + { + if( pPage->GetSortedObjs() ) + { + SwSortDrawObjs &rObjs = *pPage->GetSortedObjs(); + for( sal_uInt16 i = 0; i < rObjs.Count(); ++i) + { + SdrObject *pO = rObjs[i]; + SwVirtFlyDrawObj *pObj = pO->IsWriterFlyFrame() ? + (SwVirtFlyDrawObj*)pO : 0; + if( pObj ) + pFly = pObj->GetFlyFrm()->GetFmt(); + else if ( bDrawAlso ) + pFly = ::FindFrmFmt( rObjs[i] ); + else + continue; + + const SwFmtAnchor& rAnchor = pFly->GetAnchor(); + if( FLY_AT_CNTNT != rAnchor.GetAnchorId() && + FLY_AT_FLY != rAnchor.GetAnchorId() && + FLY_AUTO_CNTNT != rAnchor.GetAnchorId() ) + { + const SwCntntFrm * pCntntFrm = pPage->FindFirstBodyCntnt(); + if ( !pCntntFrm ) + { + //Oops! Eine leere Seite. Damit der Rahmen nicht ganz + //verlorengeht (RTF) suchen wir schnell den letzen + //Cntnt der vor der Seite steht. + SwPageFrm *pPrv = (SwPageFrm*)pPage->GetPrev(); + while ( !pCntntFrm && pPrv ) + { + pCntntFrm = pPrv->FindFirstBodyCntnt(); + pPrv = (SwPageFrm*)pPrv->GetPrev(); + } + } + if ( pCntntFrm ) + { + SwNodeIndex aIdx( *pCntntFrm->GetNode() ); + pFPos = new SwPosFlyFrm( aIdx, pFly, rPosFlyFmts.Count() ); + } + } + if ( pFPos ) + { + rPosFlyFmts.Insert( pFPos ); + pFPos = 0; + } + } + } + pPage = (SwPageFrm*)pPage->GetNext(); + } +} + +/************************************************************************* +|* +|* SwDoc::InsertLabel() +|* +|* Ersterstellung MA 11. Feb. 94 +|* Letzte Aenderung MA 12. Nov. 97 +|* +|*************************************************************************/ + +void lcl_CpyAttr( SfxItemSet &rNewSet, const SfxItemSet &rOldSet, sal_uInt16 nWhich ) +{ + const SfxPoolItem *pItem; + if ( SFX_ITEM_SET == (rOldSet.GetItemState( nWhich, sal_False, &pItem))) + rNewSet.Put( *pItem ); +} + + +SwFlyFrmFmt* SwDoc::InsertLabel( const SwLabelType eType, const String &rTxt, + const sal_Bool bBefore, const sal_uInt16 nId, const sal_uInt32 nNdIdx, + const sal_Bool bCpyBrd ) +{ + sal_Bool bWasUndo = DoesUndo(); + SwUndoInsertLabel* pUndo = 0; + if( bWasUndo ) + { + ClearRedo(); + pUndo = new SwUndoInsertLabel( eType, rTxt, bBefore, nId, bCpyBrd ); + DoUndo( sal_False ); + } + + sal_Bool bTable = sal_False; //Um etwas Code zu sparen. + + //Erstmal das Feld bauen, weil ueber den Namen die TxtColl besorgt werden + //muss + ASSERT( nId < GetFldTypes()->Count(), "FldType ueberindiziert." ); + SwFieldType *pType = (*GetFldTypes())[nId]; + ASSERT( pType->Which() == RES_SETEXPFLD, "Falsche Id fuer Label" ); + SwSetExpField aFld( (SwSetExpFieldType*)pType, aEmptyStr, SVX_NUM_ARABIC); + + SwTxtFmtColl *pColl = 0; + for( sal_uInt16 i = pTxtFmtCollTbl->Count(); i; ) + { + if( (*pTxtFmtCollTbl)[ --i ]->GetName() == pType->GetName() ) + { + pColl = (*pTxtFmtCollTbl)[i]; + break; + } + } + if( !pColl ) + { + ASSERT( !this, "TxtCollection fuer Label nicht gefunden." ); + pColl = GetTxtCollFromPool( RES_POOLCOLL_TEXT ); + } + + SwTxtNode *pNew = 0; + SwFlyFrmFmt* pNewFmt = 0; + + switch ( eType ) + { + case LTYPE_TABLE: + bTable = sal_True; + /* Kein Break hier */ + case LTYPE_FLY: + //Am Anfang/Ende der Fly-Section den entsprechenden Node mit Feld + //einfuegen (Frame wird automatisch erzeugt). + { + SwStartNode *pSttNd = GetNodes()[nNdIdx]->GetStartNode(); + ASSERT( pSttNd, "Kein StartNode in InsertLabel." ); + sal_uInt32 nNode; + if( bBefore ) + { + nNode = pSttNd->GetIndex(); + if( !bTable ) + ++nNode; + } + else + { + nNode = pSttNd->EndOfSectionIndex(); + if( bTable ) + ++nNode; + } + + if( pUndo ) + pUndo->SetNodePos( nNode ); + + //Node fuer Beschriftungsabsatz erzeugen. + SwNodeIndex aIdx( GetNodes(), nNode ); + pNew = GetNodes().MakeTxtNode( aIdx, pColl ); + } + break; + + case LTYPE_OBJECT: + { + //Rahmen zerstoeren, neuen Rahmen einfuegen, entsprechenden + // Node mit Feld in den neuen Rahmen, den alten Rahmen mit + // dem Object (Grafik/Ole) absatzgebunden in den neuen Rahmen, + // Frames erzeugen. + + //Erstmal das Format zum Fly besorgen und das Layout entkoppeln. + SwFrmFmt *pOldFmt = GetNodes()[nNdIdx]->GetFlyFmt(); + ASSERT( pOldFmt, "Format des Fly nicht gefunden." ); + pOldFmt->DelFrms(); + + SfxItemSet* pNewSet = pOldFmt->GetAttrSet().Clone( sal_False ); + + pNewFmt = MakeFlyFrmFmt( GetUniqueFrameName(), + GetFrmFmtFromPool( RES_POOLFRM_FRAME )); + + //Diejenigen Attribute uebertragen die auch gesetzt sind, + //andere sollen weiterhin aus den Vorlagen gueltig werden. + lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_PRINT ); + lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_OPAQUE ); + lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_PROTECT ); + lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_SURROUND ); + lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_VERT_ORIENT ); + lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_HORI_ORIENT ); + lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_LR_SPACE ); + lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_UL_SPACE ); + if( bCpyBrd ) + { + // JP 07.07.99: Bug 67029 - if at Grafik no BoxItem but + // in the new Format is any, then set the + // default item in the new Set. Because + // the Size of the Grafik have never been + // changed! + const SfxPoolItem *pItem; + if( SFX_ITEM_SET == pOldFmt->GetAttrSet(). + GetItemState( RES_BOX, sal_True, &pItem )) + pNewSet->Put( *pItem ); + else if( SFX_ITEM_SET == pNewFmt->GetAttrSet(). + GetItemState( RES_BOX, sal_True )) + pNewSet->Put( *GetDfltAttr( RES_BOX ) ); + + if( SFX_ITEM_SET == pOldFmt->GetAttrSet(). + GetItemState( RES_SHADOW, sal_True, &pItem )) + pNewSet->Put( *pItem ); + else if( SFX_ITEM_SET == pNewFmt->GetAttrSet(). + GetItemState( RES_SHADOW, sal_True )) + pNewSet->Put( *GetDfltAttr( RES_SHADOW ) ); + } + else + { + //Die Attribute hart setzen, weil sie sonst aus der + // Vorlage kommen koenten und dann passt die + // Grossenberechnung nicht mehr. + pNewSet->Put( SvxBoxItem() ); + pNewSet->Put( SvxShadowItem() ); + } + + //Anker immer uebertragen, ist sowieso ein hartes Attribut. + pNewSet->Put( pOldFmt->GetAnchor() ); + + //In der Hoehe soll der neue Varabel sein! + SwFmtFrmSize aFrmSize( pOldFmt->GetFrmSize() ); + aFrmSize.SetSizeType( ATT_MIN_SIZE ); + pNewSet->Put( aFrmSize ); + + SwStartNode* pSttNd = GetNodes().MakeTextSection( + SwNodeIndex( GetNodes().GetEndOfAutotext() ), + SwFlyStartNode, pColl ); + pNewSet->Put( SwFmtCntnt( pSttNd )); + + pNewFmt->SetAttr( *pNewSet ); + + //Bei InCntnt's wird es spannend: Das TxtAttribut muss + //vernichtet werden. Leider reisst dies neben den Frms auch + //noch das Format mit in sein Grab. Um dass zu unterbinden + //loesen wir vorher die Verbindung zwischen Attribut und Format. + + const SwFmtAnchor& rAnchor = pNewFmt->GetAnchor(); + if( FLY_IN_CNTNT == rAnchor.GetAnchorId() ) + { + const SwPosition *pPos = rAnchor.GetCntntAnchor(); + SwTxtNode *pTxtNode = pPos->nNode.GetNode().GetTxtNode(); + ASSERT( pTxtNode->HasHints(), "Missing FlyInCnt-Hint." ); + const xub_StrLen nIdx = pPos->nContent.GetIndex(); + SwTxtAttr *pHnt = pTxtNode->GetTxtAttr( nIdx, RES_TXTATR_FLYCNT ); + +#ifndef PRODUCT + ASSERT( pHnt && pHnt->Which() == RES_TXTATR_FLYCNT, + "Missing FlyInCnt-Hint." ); + ASSERT( pHnt && ((SwFmtFlyCnt&)pHnt->GetFlyCnt()). + GetFrmFmt() == pOldFmt, + "Wrong TxtFlyCnt-Hint." ); +#endif + ((SwFmtFlyCnt&)pHnt->GetFlyCnt()).SetFlyFmt( pNewFmt ); + } + + + //Der Alte soll keinen Umlauf haben, und er soll oben/mittig + //ausgerichtet sein. + //Ausserdem soll die Breite 100% betragen und bei Aenderungen + //Die Hoehe mit anpassen. + pNewSet->ClearItem(); + + pNewSet->Put( SwFmtSurround( SURROUND_NONE ) ); + pNewSet->Put( SwFmtVertOrient( VERT_TOP ) ); + pNewSet->Put( SwFmtHoriOrient( HORI_CENTER ) ); + + aFrmSize = pOldFmt->GetFrmSize(); + aFrmSize.SetWidthPercent( 100 ); + aFrmSize.SetHeightPercent( 255 ); + pNewSet->Put( aFrmSize ); + + //Die Attribute setzen wir hart, weil sie sonst aus der Vorlage + //kommen koenten und dann passt die Grossenberechnung nicht mehr. + if( bCpyBrd ) + { + pNewSet->Put( SvxBoxItem() ); + pNewSet->Put( SvxShadowItem() ); + } + pNewSet->Put( SvxLRSpaceItem() ); + pNewSet->Put( SvxULSpaceItem() ); + + //Der Alte ist absatzgebunden, und zwar am Absatz im neuen. + SwFmtAnchor aAnch( FLY_AT_CNTNT ); + SwNodeIndex aAnchIdx( *pNewFmt->GetCntnt().GetCntntIdx(), 1 ); + pNew = aAnchIdx.GetNode().GetTxtNode(); + SwPosition aPos( aAnchIdx ); + aAnch.SetAnchor( &aPos ); + pNewSet->Put( aAnch ); + + if( pUndo ) + pUndo->SetFlys( *pOldFmt, *pNewSet, *pNewFmt ); + else + pOldFmt->SetAttr( *pNewSet ); + + delete pNewSet; + + //Nun nur noch die Flys erzeugen lassen. Das ueberlassen + //wir vorhanden Methoden (insb. fuer InCntFlys etwas aufwendig). + pNewFmt->MakeFrms(); + } + break; + + default: + ASSERT( !this, "Neuer LabelType?." ); + } + ASSERT( pNew, "No Label inserted" ); + + if( pNew ) + { + //String aufbereiten + String aTxt( aFld.GetTyp()->GetName() ); + aTxt += ' '; + xub_StrLen nIdx = aTxt.Len(); + aTxt += rTxt; + + //String einfuegen + SwIndex aIdx( pNew, 0 ); + pNew->Insert( aTxt, aIdx ); + + //Feld einfuegen + pNew->Insert( SwFmtFld( aFld ), nIdx, nIdx ); + + if ( bTable ) + { + if ( bBefore ) + { + if ( !pNew->GetSwAttrSet().GetKeep().GetValue() ) + pNew->SwCntntNode::SetAttr( SvxFmtKeepItem( sal_True ) ); + } + else + { + SwTableNode *pNd = GetNodes()[nNdIdx]->GetStartNode()->GetTableNode(); + SwTable &rTbl = pNd->GetTable(); + if ( !rTbl.GetFrmFmt()->GetKeep().GetValue() ) + rTbl.GetFrmFmt()->SetAttr( SvxFmtKeepItem( sal_True ) ); + if ( pUndo ) + pUndo->SetUndoKeep(); + } + } + } + + if( pUndo ) + AppendUndo( pUndo ); + else + DelAllUndoObj(); + DoUndo( bWasUndo ); + + return pNewFmt; +} + +/************************************************************************* +|* +|* SwDoc::InsertDrawLabel() +|* +|* Ersterstellung MIB 7. Dez. 98 +|* Letzte Aenderung MIB 7. Dez. 98 +|* +|*************************************************************************/ + +SwFlyFrmFmt* SwDoc::InsertDrawLabel( const String &rTxt, + const sal_uInt16 nId, + SdrObject& rSdrObj ) +{ + + SwDrawContact *pContact = (SwDrawContact*)GetUserCall( &rSdrObj ); + ASSERT( RES_DRAWFRMFMT == pContact->GetFmt()->Which(), + "Kein DrawFrmFmt" ); + if( !pContact ) + return 0; + + SwDrawFrmFmt *pOldFmt = (SwDrawFrmFmt *)pContact->GetFmt(); + if( !pOldFmt ) + return 0; + + sal_Bool bWasUndo = DoesUndo(); + sal_Bool bWasNoDrawUndo = IsNoDrawUndoObj(); + SwUndoInsertLabel* pUndo = 0; + if( bWasUndo ) + { + ClearRedo(); + pUndo = new SwUndoInsertLabel( LTYPE_DRAW, rTxt, sal_False, nId, sal_False ); + DoUndo( sal_False ); + SetNoDrawUndoObj( sal_True ); + } + + // Erstmal das Feld bauen, weil ueber den Namen die TxtColl besorgt + // werden muss + ASSERT( nId < GetFldTypes()->Count(), "FldType ueberindiziert." ); + SwFieldType *pType = (*GetFldTypes())[nId]; + ASSERT( pType->Which() == RES_SETEXPFLD, "Falsche Id fuer Label" ); + SwSetExpField aFld( (SwSetExpFieldType*)pType, aEmptyStr, + SVX_NUM_ARABIC); + + SwTxtFmtColl *pColl = FindTxtFmtCollByName( pType->GetName() ); + if( !pColl ) + { + ASSERT( !this, "TxtCollection fuer Label nicht gefunden." ); + pColl = GetTxtCollFromPool( RES_POOLCOLL_TEXT ); + } + + SwTxtNode *pNew = 0; + SwFlyFrmFmt *pNewFmt = 0; + + // Rahmen zerstoeren, neuen Rahmen einfuegen, entsprechenden + // Node mit Feld in den neuen Rahmen, den alten Rahmen mit + // dem Object (Grafik/Ole) absatzgebunden in den neuen Rahmen, + // Frames erzeugen. + + pOldFmt->DelFrms(); + + //Bei InCntnt's wird es spannend: Das TxtAttribut muss + //vernichtet werden. Leider reisst dies neben den Frms auch + //noch das Format mit in sein Grab. Um dass zu unterbinden + //loesen wir vorher die Verbindung zwischen Attribut und Format. + SfxItemSet* pNewSet = pOldFmt->GetAttrSet().Clone( sal_False ); + + // Ggf. Groesse und Position des Rahmens schuetzen + if ( rSdrObj.IsMoveProtect() || rSdrObj.IsResizeProtect() ) + { + SvxProtectItem aProtect; + aProtect.SetCntntProtect( sal_False ); + aProtect.SetPosProtect( rSdrObj.IsMoveProtect() ); + aProtect.SetSizeProtect( rSdrObj.IsResizeProtect() ); + pNewSet->Put( aProtect ); + } + + // Umlauf uebernehmen + lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_SURROUND ); + + // Den Rahmen ggf. in den Hintergrund schicken. + sal_Int8 nLayerId = rSdrObj.GetLayer(); + if ( GetHellId() != nLayerId ) + { + SvxOpaqueItem aOpaque; + aOpaque.SetValue( sal_True ); + pNewSet->Put( aOpaque ); + } + + // Position uebernehmen + Point aPoint( rSdrObj.GetRelativePos() ); + SwFmtVertOrient aVert( aPoint.B(), VERT_NONE, FRAME ); + SwFmtHoriOrient aHori( aPoint.A(), HORI_NONE, FRAME ); + pNewSet->Put( aVert ); + pNewSet->Put( aHori ); + + pNewSet->Put( pOldFmt->GetAnchor() ); + + //In der Hoehe soll der neue Varabel sein! + Size aSz( rSdrObj.GetBoundRect().GetSize() ); + SwFmtFrmSize aFrmSize( ATT_MIN_SIZE, aSz.Width(), aSz.Height() ); + pNewSet->Put( aFrmSize ); + + // Abstaende auf den neuen Rahmen uebertragen. Eine Umrandung + // gibt es beu Zeichen-Objekten nicht, also muss sie geloescht + // werden. + // MA: Falsch sie wird nicht gesetzt, denn die aus der Vorlage + // soll ruhig wirksam werden + pNewSet->Put( pOldFmt->GetLRSpace() ); + pNewSet->Put( pOldFmt->GetULSpace() ); + + SwStartNode* pSttNd = GetNodes().MakeTextSection( + SwNodeIndex( GetNodes().GetEndOfAutotext() ), + SwFlyStartNode, pColl ); + + pNewFmt = MakeFlyFrmFmt( GetUniqueFrameName(), + GetFrmFmtFromPool( RES_POOLFRM_FRAME )); + + // JP 28.10.99: Bug 69487 - set border and shadow to default if the + // template contains any. + if( SFX_ITEM_SET == pNewFmt->GetAttrSet().GetItemState( RES_BOX, sal_True )) + pNewSet->Put( *GetDfltAttr( RES_BOX ) ); + + if( SFX_ITEM_SET == pNewFmt->GetAttrSet().GetItemState(RES_SHADOW,sal_True)) + pNewSet->Put( *GetDfltAttr( RES_SHADOW ) ); + + pNewFmt->SetAttr( SwFmtCntnt( pSttNd )); + pNewFmt->SetAttr( *pNewSet ); + + const SwFmtAnchor& rAnchor = pNewFmt->GetAnchor(); + if( FLY_IN_CNTNT == rAnchor.GetAnchorId() ) + { + const SwPosition *pPos = rAnchor.GetCntntAnchor(); + SwTxtNode *pTxtNode = pPos->nNode.GetNode().GetTxtNode(); + ASSERT( pTxtNode->HasHints(), "Missing FlyInCnt-Hint." ); + const xub_StrLen nIdx = pPos->nContent.GetIndex(); + SwTxtAttr *pHnt = pTxtNode->GetTxtAttr( nIdx, RES_TXTATR_FLYCNT ); + +#ifndef PRODUCT + ASSERT( pHnt && pHnt->Which() == RES_TXTATR_FLYCNT, + "Missing FlyInCnt-Hint." ); + ASSERT( pHnt && ((SwFmtFlyCnt&)pHnt->GetFlyCnt()). + GetFrmFmt() == (SwFrmFmt*)pOldFmt, + "Wrong TxtFlyCnt-Hint." ); +#endif + ((SwFmtFlyCnt&)pHnt->GetFlyCnt()).SetFlyFmt( pNewFmt ); + } + + + //Der Alte soll keinen Umlauf haben, und er soll oben/mittig + //ausgerichtet sein. + pNewSet->ClearItem(); + + pNewSet->Put( SwFmtSurround( SURROUND_NONE ) ); + if( nLayerId == GetHellId() ) + rSdrObj.SetLayer( GetHeavenId() ); + pNewSet->Put( SvxLRSpaceItem() ); + pNewSet->Put( SvxULSpaceItem() ); + + rSdrObj.SetRelativePos( Point(0,0) ); + + //Der Alte ist absatzgebunden, und zwar am Absatz im neuen. + SwFmtAnchor aAnch( FLY_AT_CNTNT ); + SwNodeIndex aAnchIdx( *pNewFmt->GetCntnt().GetCntntIdx(), 1 ); + pNew = aAnchIdx.GetNode().GetTxtNode(); + SwPosition aPos( aAnchIdx ); + aAnch.SetAnchor( &aPos ); + pNewSet->Put( aAnch ); + + if( pUndo ) + { + pUndo->SetFlys( *pOldFmt, *pNewSet, *pNewFmt ); + pUndo->SetDrawObj( aPoint, nLayerId ); + } + else + pOldFmt->SetAttr( *pNewSet ); + + delete pNewSet; + + //Nun nur noch die Flys erzeugen lassen. Das ueberlassen + //wir vorhanden Methoden (insb. fuer InCntFlys etwas aufwendig). + pNewFmt->MakeFrms(); + + ASSERT( pNew, "No Label inserted" ); + + if( pNew ) + { + //String aufbereiten + String aTxt( aFld.GetTyp()->GetName() ); + aTxt += ' '; + xub_StrLen nIdx = aTxt.Len(); + aTxt += rTxt; + + //String einfuegen + SwIndex aIdx( pNew, 0 ); + pNew->Insert( aTxt, aIdx ); + + //Feld einfuegen + pNew->Insert( SwFmtFld( aFld ), nIdx, nIdx ); + } + + if( pUndo ) + { + AppendUndo( pUndo ); + SetNoDrawUndoObj( bWasNoDrawUndo ); + } + else + DelAllUndoObj(); + DoUndo( bWasUndo ); + + return pNewFmt; +} + +/************************************************************************* +|* +|* SwDoc::DoIdleJobs() +|* +|* Ersterstellung OK 30.03.94 +|* Letzte Aenderung MA 09. Jun. 95 +|* +|*************************************************************************/ + +IMPL_LINK( SwDoc, DoIdleJobs, Timer *, pTimer ) +{ + if( !SfxProgress::GetActiveProgress( pDocShell ) && + GetRootFrm() && GetRootFrm()->GetCurrShell() ) + { + ViewShell *pSh, *pStartSh; + pSh = pStartSh = GetRootFrm()->GetCurrShell(); + do { + if( pSh->ActionPend() ) + return 0; + pSh = (ViewShell*)pSh->GetNext(); + } while( pSh != pStartSh ); + + sal_uInt16 nFldUpdFlag; + if( GetRootFrm()->IsIdleFormat() ) + GetRootFrm()->GetCurrShell()->LayoutIdle(); + else if( ( AUTOUPD_FIELD_ONLY == ( nFldUpdFlag = GetFldUpdateFlags() ) + || AUTOUPD_FIELD_AND_CHARTS == nFldUpdFlag ) && + GetUpdtFlds().IsFieldsDirty() && + !GetUpdtFlds().IsInUpdateFlds() && + !IsExpFldsLocked() + // das umschalten der Feldname fuehrt zu keinem Update der + // Felder, also der "Hintergrund-Update" immer erfolgen + /* && !pStartSh->GetViewOptions()->IsFldName()*/ ) + { + // chaos::Action-Klammerung! + GetUpdtFlds().SetInUpdateFlds( sal_True ); + + GetRootFrm()->StartAllAction(); + + GetSysFldType( RES_CHAPTERFLD )->Modify( 0, 0 ); // KapitelFld + UpdateExpFlds( 0, sal_False ); // Expression-Felder Updaten + UpdateTblFlds(); // Tabellen + UpdateRefFlds(); // Referenzen + + if( AUTOUPD_FIELD_AND_CHARTS == nFldUpdFlag ) + aChartTimer.Start(); + + GetRootFrm()->EndAllAction(); + + GetUpdtFlds().SetInUpdateFlds( sal_False ); + GetUpdtFlds().SetFieldsDirty( sal_False ); + } + } + return 0; +} + +IMPL_STATIC_LINK( SwDoc, BackgroundDone, SvxBrushItem*, EMPTYARG ) +{ + ViewShell *pSh, *pStartSh; + pSh = pStartSh = pThis->GetRootFrm()->GetCurrShell(); + if( pStartSh ) + do { + if( pSh->GetWin() ) + { + //Fuer Repaint mir virtuellen Device sorgen. + pSh->LockPaint(); + pSh->UnlockPaint( sal_True ); + } + pSh = (ViewShell*)pSh->GetNext(); + } while( pSh != pStartSh ); + return 0; +} + +String lcl_GetUniqueFlyName( const SwDoc* pDoc, sal_uInt16 nDefStrId ) +{ + ResId aId( nDefStrId, pSwResMgr ); + String aName( aId ); + xub_StrLen nNmLen = aName.Len(); + + const SwSpzFrmFmts& rFmts = *pDoc->GetSpzFrmFmts(); + + sal_uInt16 nNum, nTmp, nFlagSize = ( rFmts.Count() / 8 ) +2; + sal_uInt8* pSetFlags = new sal_uInt8[ nFlagSize ]; + memset( pSetFlags, 0, nFlagSize ); + + for( sal_uInt16 n = 0; n < rFmts.Count(); ++n ) + { + const SwFrmFmt* pFlyFmt = rFmts[ n ]; + if( RES_FLYFRMFMT == pFlyFmt->Which() && + pFlyFmt->GetName().Match( aName ) == nNmLen ) + { + // Nummer bestimmen und das Flag setzen + nNum = pFlyFmt->GetName().Copy( nNmLen ).ToInt32(); + if( nNum-- && nNum < rFmts.Count() ) + pSetFlags[ nNum / 8 ] |= (0x01 << ( nNum & 0x07 )); + } + } + + // alle Nummern entsprechend geflag, also bestimme die richtige Nummer + nNum = rFmts.Count(); + for( n = 0; n < nFlagSize; ++n ) + if( 0xff != ( nTmp = pSetFlags[ n ] )) + { + // also die Nummer bestimmen + nNum = n * 8; + while( nTmp & 1 ) + ++nNum, nTmp >>= 1; + break; + } + + __DELETE( nFlagSize ) pSetFlags; + return aName += String::CreateFromInt32( ++nNum ); +} + +String SwDoc::GetUniqueGrfName() const +{ + return ::lcl_GetUniqueFlyName( this, STR_GRAPHIC_DEFNAME ); +} + +String SwDoc::GetUniqueOLEName() const +{ + return ::lcl_GetUniqueFlyName( this, STR_OBJECT_DEFNAME ); +} + +String SwDoc::GetUniqueFrameName() const +{ + return ::lcl_GetUniqueFlyName( this, STR_FRAME_DEFNAME ); +} + +const SwFlyFrmFmt* SwDoc::FindFlyByName( const String& rName, sal_Int8 nNdTyp ) const +{ + const SwSpzFrmFmts& rFmts = *GetSpzFrmFmts(); + for( sal_uInt16 n = rFmts.Count(); n; ) + { + const SwFrmFmt* pFlyFmt = rFmts[ --n ]; + const SwNodeIndex* pIdx; + if( RES_FLYFRMFMT == pFlyFmt->Which() && pFlyFmt->GetName() == rName && + 0 != ( pIdx = pFlyFmt->GetCntnt().GetCntntIdx() ) && + pIdx->GetNode().GetNodes().IsDocNodes() ) + { + if( nNdTyp ) + { + // dann noch auf den richtigen Node-Typ abfragen + const SwNode* pNd = GetNodes()[ pIdx->GetIndex()+1 ]; + if( nNdTyp == ND_TEXTNODE + ? !pNd->IsNoTxtNode() + : nNdTyp == pNd->GetNodeType() ) + return (SwFlyFrmFmt*)pFlyFmt; + } + else + return (SwFlyFrmFmt*)pFlyFmt; + } + } + return 0; +} + +void SwDoc::SetFlyName( SwFlyFrmFmt& rFmt, const String& rName ) +{ + String sName( rName ); + if( !rName.Len() || FindFlyByName( rName ) ) + { + sal_uInt16 nTyp = STR_FRAME_DEFNAME; + const SwNodeIndex* pIdx = rFmt.GetCntnt().GetCntntIdx(); + if( pIdx && pIdx->GetNode().GetNodes().IsDocNodes() ) + switch( GetNodes()[ pIdx->GetIndex() + 1 ]->GetNodeType() ) + { + case ND_GRFNODE: nTyp = STR_GRAPHIC_DEFNAME; break; + case ND_OLENODE: nTyp = STR_OBJECT_DEFNAME; break; + } + sName = ::lcl_GetUniqueFlyName( this, nTyp ); + } + rFmt.SetName( sName ); +} + +void SwDoc::SetAllUniqueFlyNames() +{ + sal_uInt16 n, nFlyNum = 0, nGrfNum = 0, nOLENum = 0; + + ResId nFrmId( STR_FRAME_DEFNAME, pSwResMgr ), + nGrfId( STR_GRAPHIC_DEFNAME, pSwResMgr ), + nOLEId( STR_OBJECT_DEFNAME, pSwResMgr ); + String sFlyNm( nFrmId ); + String sGrfNm( nGrfId ); + String sOLENm( nOLEId ); + + if( 255 < ( n = GetSpzFrmFmts()->Count() )) + n = 255; + SwSpzFrmFmts aArr( (sal_Int8)n, 10 ); + SwFrmFmtPtr pFlyFmt; + sal_Bool bLoadedFlag = sal_True; // noch etwas fuers Layout + + for( n = GetSpzFrmFmts()->Count(); n; ) + { + if( RES_FLYFRMFMT == (pFlyFmt = (*GetSpzFrmFmts())[ --n ])->Which() ) + { + sal_uInt16 *pNum = 0; + xub_StrLen nLen; + const String& rNm = pFlyFmt->GetName(); + if( rNm.Len() ) + { + if( rNm.Match( sGrfNm ) == ( nLen = sGrfNm.Len() )) + pNum = &nGrfNum; + else if( rNm.Match( sFlyNm ) == ( nLen = sFlyNm.Len() )) + pNum = &nFlyNum; + else if( rNm.Match( sOLENm ) == ( nLen = sOLENm.Len() )) + pNum = &nOLENum; + + if( pNum && *pNum < ( nLen = rNm.Copy( nLen ).ToInt32() )) + *pNum = nLen; + } + else + // das wollen wir nachher setzen + aArr.Insert( pFlyFmt, aArr.Count() ); + + } + if( bLoadedFlag ) + { + const SwFmtAnchor& rAnchor = pFlyFmt->GetAnchor(); + if( ( FLY_PAGE == rAnchor.GetAnchorId() && + rAnchor.GetCntntAnchor() ) || + // oder werden DrawObjecte rel. zu irgendetwas ausgerichtet? + ( RES_DRAWFRMFMT == pFlyFmt->Which() && ( + SFX_ITEM_SET == pFlyFmt->GetItemState( + RES_VERT_ORIENT )|| + SFX_ITEM_SET == pFlyFmt->GetItemState( + RES_HORI_ORIENT ))) ) + bLoadedFlag = sal_False; + } + } + + const SwNodeIndex* pIdx; + + for( n = aArr.Count(); n; ) + if( 0 != ( pIdx = ( pFlyFmt = aArr[ --n ])->GetCntnt().GetCntntIdx() ) + && pIdx->GetNode().GetNodes().IsDocNodes() ) + { + sal_uInt16 nNum; + String sNm; + switch( GetNodes()[ pIdx->GetIndex() + 1 ]->GetNodeType() ) + { + case ND_GRFNODE: + sNm = sGrfNm; + nNum = ++nGrfNum; + break; + case ND_OLENODE: + sNm = sOLENm; + nNum = ++nOLENum; + break; + default: + sNm = sFlyNm; + nNum = ++nFlyNum; + break; + } + pFlyFmt->SetName( sNm += String::CreateFromInt32( nNum )); + } + aArr.Remove( 0, aArr.Count() ); + + if( GetFtnIdxs().Count() ) + { + SwTxtFtn::SetUniqueSeqRefNo( *this ); + SwNodeIndex aTmp( GetNodes() ); + GetFtnIdxs().UpdateFtn( aTmp ); + } + + // neues Document und keine seitengebundenen Rahmen/DrawObjecte gefunden, + // die an einem Node verankert sind. + if( bLoadedFlag ) + SetLoaded( sal_True ); +} + +sal_Bool SwDoc::IsInHeaderFooter( const SwNodeIndex& rIdx ) const +{ + // gibt es ein Layout, dann ueber das laufen!! + // (Das kann dann auch Fly in Fly in Kopfzeile !) + // MIB 9.2.98: Wird auch vom sw3io benutzt, um festzustellen, ob sich + // ein Redline-Objekt in einer Kopf- oder Fusszeile befindet. Da + // Redlines auch an Start- und Endnodes haengen, muss der Index nicht + // unbedingt der eines Content-Nodes sein. + SwNode* pNd = &rIdx.GetNode(); + if( pNd->IsCntntNode() && pLayout ) + { + SwFrm *pFrm = pNd->GetCntntNode()->GetFrm(); + if( pFrm ) + { + SwFrm *pUp = pFrm->GetUpper(); + while ( pUp && !pUp->IsHeaderFrm() && !pUp->IsFooterFrm() ) + { + if ( pUp->IsFlyFrm() ) + pUp = ((SwFlyFrm*)pUp)->GetAnchor(); + pUp = pUp->GetUpper(); + } + if ( pUp ) + return sal_True; + + return sal_False; + } + } + + + const SwNode* pFlyNd = pNd->FindFlyStartNode(); + while( pFlyNd ) + { + // dann ueber den Anker nach oben "hangeln" + for( sal_uInt16 n = 0; n < GetSpzFrmFmts()->Count(); ++n ) + { + const SwFrmFmt* pFmt = (*GetSpzFrmFmts())[ n ]; + const SwNodeIndex* pIdx = pFmt->GetCntnt().GetCntntIdx(); + if( pIdx && pFlyNd == &pIdx->GetNode() ) + { + const SwFmtAnchor& rAnchor = pFmt->GetAnchor(); + if( FLY_PAGE == rAnchor.GetAnchorId() || + !rAnchor.GetCntntAnchor() ) + return sal_False; + + pNd = &rAnchor.GetCntntAnchor()->nNode.GetNode(); + pFlyNd = pNd->FindFlyStartNode(); + break; + } + } + if( n >= GetSpzFrmFmts()->Count() ) + { + ASSERT( bInReading, "Fly-Section aber kein Format gefunden" ); + return sal_False; + } + } + + return 0 != pNd->FindHeaderStartNode() || + 0 != pNd->FindFooterStartNode(); +} + + diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx new file mode 100644 index 000000000000..1973d6b33bcc --- /dev/null +++ b/sw/source/core/doc/docnew.cxx @@ -0,0 +1,822 @@ +/************************************************************************* + * + * $RCSfile: docnew.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:15 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#define ROLBCK_HISTORY_ONLY // Der Kampf gegen die CLOOK's + +#ifndef _SFX_PRINTER_HXX //autogen +#include +#endif +#ifndef _SFXDOCINF_HXX //autogen +#include +#endif +#ifndef _SFXMACITEM_HXX //autogen +#include +#endif +#ifndef _SVX_SVXIDS_HRC +#include +#endif +#ifndef _SVXLINKMGR_HXX +#include +#endif +#ifndef _ZFORLIST_HXX //autogen +#include +#endif + + +#ifndef _FMTCNTNT_HXX //autogen +#include +#endif +#ifndef _FMTANCHR_HXX //autogen +#include +#endif +#ifndef _FMTFSIZE_HXX //autogen +#include +#endif +#ifndef _FMTFORDR_HXX //autogen +#include +#endif +#ifndef _PVPRTDAT_HXX +#include +#endif + +#ifndef _DOC_HXX +#include +#endif +#ifndef _ROOTFRM_HXX +#include //Damit der RootDtor gerufen wird. +#endif +#ifndef _LAYOUTER_HXX +#include +#endif +#ifndef _ERRHDL_HXX +#include +#endif +#ifndef _PAGEDESC_HXX +#include //Damit die PageDescs zerstoert werden koennen. +#endif +#ifndef _NDTXT_HXX +#include +#endif +#ifndef _DOCFLD_HXX +#include +#endif +#ifndef _FTNINFO_HXX +#include +#endif +#ifndef _FTNIDX_HXX +#include +#endif +#ifndef _DOCSTAT_HXX +#include +#endif +#ifndef _CHARFMT_HXX +#include +#endif +#ifndef _FRMFMT_HXX +#include +#endif +#ifndef _ROLBCK_HXX +#include // Undo-Attr, SwHistory +#endif +#ifndef _POOLFMT_HXX +#include // fuer die Pool-Vorlage +#endif +#ifndef _DBMGR_HXX +#include +#endif +#ifndef _DOCSH_HXX +#include +#endif +#ifndef _ACORRECT_HXX +#include // fuer die autom. Aufnahme von Ausnahmen +#endif +#ifndef _VISITURL_HXX +#include // fuer die URL-Change Benachrichtigung +#endif +#ifndef _DOCARY_HXX +#include +#endif +#ifndef _FMTCOL_HXX +#include +#endif +#ifndef _NUMRULE_HXX +#include +#endif +#ifndef _LINEINFO_HXX +#include +#endif +#ifndef _DRAWDOC_HXX +#include +#endif +#ifndef _LINKENUM_HXX +#include +#endif +#ifndef _FLDUPDE_HXX +#include +#endif +#ifndef _EXTINPUT_HXX +#include +#endif +#ifndef _VIEWSH_HXX +#include +#endif +#ifndef _DOCTXM_HXX +#include +#endif +#ifndef _SHELLRES_HXX +#include +#endif +#ifndef _UNOCLBCK_HXX +#include +#endif + +#ifndef _CMDID_H +#include // fuer den dflt - Printer in SetJob +#endif + +const sal_Char __FAR_DATA sFrmFmtStr[] = "Frameformat"; +const sal_Char __FAR_DATA sEmptyPageStr[] = "Empty Page"; +const sal_Char __FAR_DATA sColumnCntStr[] = "Columncontainer"; +const sal_Char __FAR_DATA sCharFmtStr[] = "Zeichenformat"; +const sal_Char __FAR_DATA sTxtCollStr[] = "Textformatvorlage"; +const sal_Char __FAR_DATA sGrfCollStr[] = "Graphikformatvorlage"; + +SV_IMPL_PTRARR( SwNumRuleTbl, SwNumRulePtr) +SV_IMPL_PTRARR( SwTxtFmtColls, SwTxtFmtCollPtr) +SV_IMPL_PTRARR( SwGrfFmtColls, SwGrfFmtCollPtr) + + +/* + * interne Funktionen + */ + + + +BOOL lcl_DelFmtIndizes( const SwFrmFmtPtr& rpFmt, void* ) +{ + SwFmtCntnt &rFmtCntnt = (SwFmtCntnt&)rpFmt->GetCntnt(); + if ( rFmtCntnt.GetCntntIdx() ) + rFmtCntnt.SetNewCntntIdx( 0 ); + SwFmtAnchor &rFmtAnchor = (SwFmtAnchor&)rpFmt->GetAnchor(); + if ( rFmtAnchor.GetCntntAnchor() ) + rFmtAnchor.SetAnchor( 0 ); + return TRUE; +} + +/* + * exportierte Methoden + */ + + + +SwDoc::SwDoc() : + aAttrPool( this ), + aNodes( this ), + aUndoNodes( this ), + pFrmFmtTbl( new SwFrmFmts() ), + pCharFmtTbl( new SwCharFmts() ), + pSpzFrmFmtTbl( new SwSpzFrmFmts() ), + pTblFrmFmtTbl( new SwFrmFmts() ), + pDfltFrmFmt( new SwFrmFmt( aAttrPool, sFrmFmtStr, 0 ) ), + pEmptyPageFmt( new SwFrmFmt( aAttrPool, sEmptyPageStr, pDfltFrmFmt ) ), + pColumnContFmt( new SwFrmFmt( aAttrPool, sColumnCntStr, pDfltFrmFmt ) ), + pDfltCharFmt( new SwCharFmt( aAttrPool, sCharFmtStr, 0 ) ), + pDfltTxtFmtColl( new SwTxtFmtColl( aAttrPool, sTxtCollStr ) ), + pTxtFmtCollTbl( new SwTxtFmtColls() ), + pDfltGrfFmtColl( new SwGrfFmtColl( aAttrPool, sGrfCollStr ) ), + pGrfFmtCollTbl( new SwGrfFmtColls() ), + pSectionFmtTbl( new SwSectionFmts() ), + pFldTypes( new SwFldTypes() ), + pBookmarkTbl( new SwBookmarks() ), + pTOXTypes( new SwTOXTypes() ), + pDefTOXBases( new SwDefTOXBase_Impl() ), + nLinkCt( 0 ), + pGlossaryDoc( 0 ), + nUndoPos( 0 ), + nUndoSavePos( 0 ), + nUndoCnt( 0 ), + nUndoSttEnd( 0 ), + pOutlineRule( 0 ), + pLayout( 0 ), // Rootframe des spezifischen Layouts. + pPrt( 0 ), + pUndos( new SwUndos( 0, 20 ) ), + pExtInputRing( 0 ), + pLayouter( 0 ), + nLockExpFld( 0 ), + pDocShell( 0 ), + pDrawModel( 0 ), + pUpdtFlds( new SwDocUpdtFld() ), + pLinkMgr( new SvxLinkManager( 0 ) ), + pSwgInfo( 0 ), + pDocShRef( 0 ), + pACEWord( 0 ), + pURLStateChgd( 0 ), + pNumberFormatter( 0 ), + pFtnInfo( new SwFtnInfo ), + pEndNoteInfo( new SwEndNoteInfo ), + pLineNumberInfo( new SwLineNumberInfo ), + pFtnIdxs( new SwFtnIdxs ), + pDocStat( new SwDocStat ), + pNumRuleTbl( new SwNumRuleTbl ), + eRedlineMode( SwRedlineMode(REDLINE_SHOW_INSERT | REDLINE_SHOW_DELETE) ), + pRedlineTbl( new SwRedlineTbl ), + pUnoCrsrTbl( new SwUnoCrsrTbl ), + pPgPViewPrtData( 0 ), + pAutoFmtRedlnComment( 0 ), + pUnoCallBack(new SwUnoCallBack(0)), + nAutoFmtRedlnCommentNo( 0 ), + n32Dummy1( 0 ), n32Dummy2( 0 ), n8Dummy1( 0 ), n8Dummy2( 0 ), + nLinkUpdMode( GLOBALSETTING ), + nFldUpdMode( AUTOUPD_GLOBALSETTING ) +{ + bGlossDoc = + bModified = + bDtor = + bUndo = + bPageNums = + bLoaded = + bUpdateExpFld = + bNewDoc = + bCopyIsMove = + bNoDrawUndoObj = + bBrowseMode = + bInReading = + bUpdateTOX = + bInLoadAsynchron = + bHTMLMode = + bHeadInBrowse = + bFootInBrowse = + bInCallModified = + bIsGlobalDoc = + bGlblDocSaveLinks = + bIsLabelDoc = + bIsAutoFmtRedline = + bOLEPrtNotifyPending = + bAllOLENotify = + bIsRedlineMove = + bInsOnlyTxtGlssry = + bContains_MSVBasic = + FALSE; + + bGroupUndo = + bNewFldLst = + bVisibleLinks = + bFrmBeepEnabled = + bPurgeOLE = + TRUE; + + pMacroTable = new SvxMacroTableDtor; + + /* + * Defaultformate und DefaultFormatsammlungen (FmtColl) + * werden an der Position 0 in das jeweilige Array eingetragen. + * Die Formate der FmtColls sind von den Defaultformaten + * abgeleitet und stehen auch in der Liste. + */ + /* Formate */ + pFrmFmtTbl->Insert(pDfltFrmFmt, 0 ); + pCharFmtTbl->Insert(pDfltCharFmt, 0 ); + + /* FmtColls */ + // TXT + pTxtFmtCollTbl->Insert(pDfltTxtFmtColl, 0 ); + // aFtnInfo.SetFtnTxtColl(aDfltTxtFmtColl); // jetzt oben in der Liste + // GRF + pGrfFmtCollTbl->Insert(pDfltGrfFmtColl, 0 ); + + // PageDesc, EmptyPageFmt und ColumnFmt anlegen + if ( !aPageDescs.Count() ) + GetPageDescFromPool( RES_POOLPAGE_STANDARD ); + + //Leere Seite Einstellen. + pEmptyPageFmt->SetAttr( SwFmtFrmSize( ATT_FIX_SIZE ) ); + //BodyFmt fuer Spalten Einstellen. + pColumnContFmt->SetAttr( SwFmtFillOrder( ATT_LEFT_TO_RIGHT ) ); + + _InitFieldTypes(); + + // lege (fuer die Filter) eine Default-OullineNumRule an + pOutlineRule = new SwNumRule( String::CreateFromAscii( + SwNumRule::GetOutlineRuleName() ), + OUTLINE_RULE ); + + new SwTxtNode( SwNodeIndex( aUndoNodes.GetEndOfContent() ), pDfltTxtFmtColl ); + new SwTxtNode( SwNodeIndex( aNodes.GetEndOfContent() ), + GetTxtCollFromPool( RES_POOLCOLL_STANDARD )); + + // den eigenen IdleTimer setzen + aIdleTimer.SetTimeout( 600 ); + aIdleTimer.SetTimeoutHdl( LINK(this, SwDoc, DoIdleJobs) ); + aIdleTimer.Start(); + + // den CharTimer setzen + aChartTimer.SetTimeout( 2000 ); + aChartTimer.SetTimeoutHdl( LINK( this, SwDoc, DoUpdateAllCharts )); + + aOLEModifiedTimer.SetTimeout( 1000 ); + aOLEModifiedTimer.SetTimeoutHdl( LINK( this, SwDoc, DoUpdateModifiedOLE )); + + // DBMgr anlegen + pNewDBMgr = new SwNewDBMgr; + + // create TOXTypes + ShellResource* pShellRes = ViewShell::GetShellRes(); + + SwTOXType * pNew = new SwTOXType(TOX_CONTENT, pShellRes->aTOXContentName ); + pTOXTypes->Insert( pNew, pTOXTypes->Count() ); + pNew = new SwTOXType(TOX_INDEX, pShellRes->aTOXIndexName ); + pTOXTypes->Insert( pNew, pTOXTypes->Count() ); + pNew = new SwTOXType(TOX_USER, pShellRes->aTOXUserName ); + pTOXTypes->Insert( pNew, pTOXTypes->Count() ); + pNew = new SwTOXType(TOX_ILLUSTRATIONS, pShellRes->aTOXIllustrationsName ); + pTOXTypes->Insert( pNew, pTOXTypes->Count() ); + pNew = new SwTOXType(TOX_OBJECTS, pShellRes->aTOXObjectsName ); + pTOXTypes->Insert( pNew, pTOXTypes->Count() ); + pNew = new SwTOXType(TOX_TABLES, pShellRes->aTOXTablesName ); + pTOXTypes->Insert( pNew, pTOXTypes->Count() ); + pNew = new SwTOXType(TOX_AUTHORITIES, pShellRes->aTOXAuthoritiesName ); + pTOXTypes->Insert( pNew, pTOXTypes->Count() ); + + ResetModified(); +} + +/* + * Besonderheiten: an der Position 0 des Arrays der Formate und + * der GDI-Objekte befindet sich ein Member der Klasse SwDoc. + * Dieser darf also keinesfalls durch delete geloescht + * werden!!!!!!!!!! + */ + + +SwDoc::~SwDoc() +{ + aIdleTimer.Stop(); // den Idltimer abschalten + + delete pUnoCallBack; + delete pURLStateChgd; + + delete pLayouter; + + // Undo-Benachrichtigung vom Draw abschalten + if( pDrawModel ) + { + DrawNotifyUndoHdl(); + ClrContourCache(); + } + + delete pPgPViewPrtData; + + bUndo = FALSE; // immer das Undo abschalten !! + // damit die Fussnotenattribute die Fussnotennodes in Frieden lassen. + bDtor = TRUE; + + DELETEZ( pLayout ); + DELETEZ( pOutlineRule ); + + delete pRedlineTbl; + delete pUnoCrsrTbl; + delete pAutoFmtRedlnComment; + + if( pUpdtFlds ) + delete pUpdtFlds; + + if( pACEWord ) + delete pACEWord; + + // die BaseLinks freigeben. + { + for( USHORT n = pLinkMgr->GetServers().Count(); n; ) + ((SvPseudoObject*)pLinkMgr->GetServers()[ --n ])->Closed(); + + if( pLinkMgr->GetLinks().Count() ) + pLinkMgr->Remove( 0, pLinkMgr->GetLinks().Count() ); + } + + // die KapitelNummern / Nummern muessen vor den Vorlage geloescht werden + // ansonsten wird noch staendig geupdatet !!! + aNodes.pOutlineNds->Remove( USHORT(0), aNodes.pOutlineNds->Count() ); + aUndoNodes.pOutlineNds->Remove( USHORT(0), aUndoNodes.pOutlineNds->Count() ); + + pFtnIdxs->Remove( USHORT(0), pFtnIdxs->Count() ); + + pUndos->DeleteAndDestroy( 0, pUndos->Count() ); //Es koennen in den Attributen noch + //noch indizes angemeldet sein. + + // in den BookMarks sind Indizies auf den Content. Diese muessen vorm + // loesche der Nodes geloescht werden. + pBookmarkTbl->DeleteAndDestroy( 0, pBookmarkTbl->Count() ); + DELETEZ( pMacroTable ); + + if( pExtInputRing ) + { + Ring* pTmp = pExtInputRing; + pExtInputRing = 0; + while( pTmp->GetNext() != pTmp ) + delete pTmp->GetNext(); + delete pTmp; + } + +//JP: alt - loeschen ohne Flag ist teuer; Modify wird verschickt! +// aTOXTypes.DeleteAndDestroy( 0, aTOXTypes.Count() ); + { + for( USHORT n = pTOXTypes->Count(); n; ) + { + (*pTOXTypes)[ --n ]->SetInDocDTOR(); + delete (*pTOXTypes)[ n ]; + } + pTOXTypes->Remove( 0, pTOXTypes->Count() ); + } + delete pDefTOXBases; + + //Im einen oder anderen FrmFormat koennen noch Indizes angemeldet sein, + //Diese muessen spaetestens jetzt zerstoert werden. + pFrmFmtTbl->ForEach( &lcl_DelFmtIndizes, this ); + pSpzFrmFmtTbl->ForEach( &lcl_DelFmtIndizes, this ); + ((SwFrmFmts&)*pSectionFmtTbl).ForEach( &lcl_DelFmtIndizes, this ); + + //Die Formate, die hier hinter stehen sind von den DefaultFormaten + //abhaengig. Erst nach dem Loeschen der FmtIndizes weil der Inhalt von + //Kopf-/Fussbereichen geloescht wird. Wenn dort noch Indizes von Flys + //angemeldet sind gibts was an die Ohren. + aPageDescs.DeleteAndDestroy( 0, aPageDescs.Count() ); + + // Inhaltssections loeschen + // nicht erst durch den SwNodes-DTOR, damit Formate + // keine Abhaengigen mehr haben. + aNodes.DelNodes( SwNodeIndex( aNodes ), aNodes.Count() ); + aUndoNodes.DelNodes( SwNodeIndex( aUndoNodes ), aUndoNodes.Count() ); + + // Formate loeschen, spaeter mal permanent machen. + + // Delete fuer Collections + // damit die Abhaengigen wech sind + SwTxtFmtColl *pFtnColl = pFtnInfo->GetFtnTxtColl(); + if ( pFtnColl ) pFtnColl->Remove(pFtnInfo); + pFtnColl = pEndNoteInfo->GetFtnTxtColl(); + if ( pFtnColl ) pFtnColl->Remove(pEndNoteInfo); + + ASSERT( pDfltTxtFmtColl == (*pTxtFmtCollTbl)[0], + "Default-Text-Collection muss immer am Anfang stehen" ); + + // JP 27.01.98: opt.: ausgehend davon, das Standard als 2. im Array + // steht, sollte das als letztes geloescht werden, damit + // die ganze Umhaengerei der Formate vermieden wird! + if( 2 < pTxtFmtCollTbl->Count() ) + pTxtFmtCollTbl->DeleteAndDestroy( 2, pTxtFmtCollTbl->Count()-2 ); + pTxtFmtCollTbl->DeleteAndDestroy( 1, pTxtFmtCollTbl->Count()-1 ); + delete pTxtFmtCollTbl; + + ASSERT( pDfltGrfFmtColl == (*pGrfFmtCollTbl)[0], + "Default-Grf-Collection muss immer am Anfang stehen" ); + + pGrfFmtCollTbl->DeleteAndDestroy( 1, pGrfFmtCollTbl->Count()-1 ); +// ergibt sich automatisch - kein _DEL Array! +// pGrfFmtCollTbl->Remove( 0, n ); + delete pGrfFmtCollTbl; + + /* + * Defaultformate und DefaultFormatsammlungen (FmtColl) + * sind an der Position 0 der jeweiligen Arrays eingetragen. + * Damit sie nicht vom DTOR der Array's zum 2.mal geloescht werden, + * nehme sie aus dem Array. + */ + pFrmFmtTbl->Remove( 0 ); + pCharFmtTbl->Remove( 0 ); + + // Delete fuer pPrt + if( pPrt ) + DELETEZ( pPrt ); + + if( pSwgInfo ) + DELETEZ( pSwgInfo ); + + if (pNewDBMgr) + DELETEZ(pNewDBMgr); + + // Alle Flys muessen vor dem Drawing Model zerstoert werden, + // da Flys noch DrawContacts enthalten koennen, wenn wegen + // eines Lesefehlers kein Layout aufgebaut wurde. + pSpzFrmFmtTbl->DeleteAndDestroy( 0, pSpzFrmFmtTbl->Count() ); + + //Erst jetzt das Model zerstoeren, die Zeichenobjekte - die ja auch + //im Undo herumlungern - wollen noch ihre Attribute beim Model entfernen. + //Ausserdem koennen vorher noch DrawContacts existieren. + ReleaseDrawModel(); + //JP 28.01.99: DrawModel vorm LinkManager zerstoeren, da am DrawModel + // dieser immer gesetzt ist. + DELETEZ( pLinkMgr ); + + //Tables vor dem loeschen der Defaults leeren, sonst GPF wegen Def-Abhaengigen. + //Die Arrays sollten (wegen includes) bei Gelegenheit auch zu Pointern werden. + delete pFrmFmtTbl; + delete pSpzFrmFmtTbl; + delete pCharFmtTbl; + delete pSectionFmtTbl; + delete pTblFrmFmtTbl; + delete pDfltTxtFmtColl; + delete pDfltGrfFmtColl; + delete pNumRuleTbl; + + delete pBookmarkTbl; + delete pNumberFormatter; + delete pFtnInfo; + delete pEndNoteInfo; + delete pLineNumberInfo; + delete pFtnIdxs; + delete pFldTypes; + delete pTOXTypes; + delete pUndos; + delete pDocStat; + delete pEmptyPageFmt; + delete pColumnContFmt; + delete pDfltCharFmt; + delete pDfltFrmFmt; +} + + +//--------------------------------------------------- + + +void SwDoc::SetJobsetup( const JobSetup &rJobSetup ) +{ + BOOL bCheckPageDescs = 0 == pPrt; + BOOL bDataChanged = FALSE; + + if ( pPrt ) + { + if ( pPrt->GetName() == rJobSetup.GetPrinterName() ) + { + if ( pPrt->GetJobSetup() != rJobSetup ) + { + pPrt->SetJobSetup( rJobSetup ); + bDataChanged = TRUE; + } + } + else + delete pPrt, pPrt = 0; + } + + if( !pPrt ) + { + //Das ItemSet wird vom Sfx geloescht! + SfxItemSet *pSet = new SfxItemSet( aAttrPool, + FN_PARAM_ADDPRINTER, FN_PARAM_ADDPRINTER, + SID_HTML_MODE, SID_HTML_MODE, + SID_PRINTER_NOTFOUND_WARN, SID_PRINTER_NOTFOUND_WARN, + SID_PRINTER_CHANGESTODOC, SID_PRINTER_CHANGESTODOC, + 0 ); + SfxPrinter *p = new SfxPrinter( pSet, rJobSetup ); + if ( bCheckPageDescs ) + SetPrt( p ); + else + { + pPrt = p; + bDataChanged = TRUE; + } + } + if ( bDataChanged ) + PrtDataChanged(); +} + +//--------------------------------------------------- + + + +const JobSetup* SwDoc::GetJobsetup() const +{ + return pPrt ? &pPrt->GetJobSetup() : 0; +} + +//--------------------------------------------------- + +SfxPrinter* SwDoc::_GetPrt() const +{ + ASSERT( !pPrt, "Don't use _GetPrt(), use GetPrt()!" ); + // wir erzeugen einen default SfxPrinter. + // Das ItemSet wird vom Sfx geloescht! + SfxItemSet *pSet = new SfxItemSet( ((SwDoc*)this)->GetAttrPool(), + FN_PARAM_ADDPRINTER, FN_PARAM_ADDPRINTER, + SID_HTML_MODE, SID_HTML_MODE, + SID_PRINTER_NOTFOUND_WARN, SID_PRINTER_NOTFOUND_WARN, + SID_PRINTER_CHANGESTODOC, SID_PRINTER_CHANGESTODOC, + 0 ); + SfxPrinter *pNewPrt = new SfxPrinter( pSet ); + ((SwDoc*)this)->SetPrt( pNewPrt ); + return pPrt; +} + + +//--------------------------------------------------- + + +void SwDoc::SetDocShell( SwDocShell* pDSh ) +{ + if( pDocShell != pDSh ) + { + pDocShell = pDSh; + pLinkMgr->SetCacheContainer( pDocShell ); + //JP 27.08.98: Bug 55570 - DocShell Pointer auch am DrawModel setzen + if( pDrawModel ) + ((SwDrawDocument*)pDrawModel)->SetObjectShell( pDocShell ); + } +} + + +// Convenience-Methode, um uebermaessige Includes von docsh.hxx +// zu vermeiden + + + +SvStorage* SwDoc::GetDocStorage() +{ + if( pDocShell ) + return pDocShell->GetStorage(); + if( pLinkMgr->GetCacheContainer() ) + return pLinkMgr->GetCacheContainer()->GetStorage(); + return NULL; +} + + + +SvPersist* SwDoc::GetPersist() const +{ + return pDocShell ? pDocShell : pLinkMgr->GetCacheContainer(); +} + + + +void SwDoc::SetPersist( SvPersist* pPersist ) +{ + if( !pDocShell ) + { + ASSERT( ( !pPersist && pLinkMgr->GetCacheContainer() ) || + ( pPersist && !pLinkMgr->GetCacheContainer() ), + "doppeltes setzen von Persist-Pointer?" ) + pLinkMgr->SetCacheContainer( pPersist ); + } +#ifndef PRODUCT + else + ASSERT( !this, "DocShell existiert schon!" ) +#endif +} + + + +const SfxDocumentInfo* SwDoc::GetInfo() +{ + if( !pSwgInfo ) + // Pointer-Members initialisieren + pSwgInfo = new SfxDocumentInfo; + return pSwgInfo; +} + +void SwDoc::ClearDoc() +{ + bUndo = FALSE; // immer das Undo abschalten !! + + // Undo-Benachrichtigung vom Draw abschalten + if( pDrawModel ) + { + DrawNotifyUndoHdl(); + ClrContourCache(); + } + + // stehen noch FlyFrames rum, loesche auch diese + for( USHORT n = 0; n < GetSpzFrmFmts()->Count(); ++n ) + DelLayoutFmt( (*pSpzFrmFmtTbl)[n] ); + + pRedlineTbl->DeleteAndDestroy( 0, pRedlineTbl->Count() ); + + if( pACEWord ) + delete pACEWord; + + // in den BookMarks sind Indizies auf den Content. Diese muessen vorm + // loesche der Nodes geloescht werden. + pBookmarkTbl->DeleteAndDestroy( 0, pBookmarkTbl->Count() ); + pTOXTypes->DeleteAndDestroy( 0, pTOXTypes->Count() ); + aPageDescs.DeleteAndDestroy( 0, aPageDescs.Count() ); + + pNumRuleTbl->DeleteAndDestroy( 0, pNumRuleTbl->Count() ); + + SwNodeIndex aSttIdx( *GetNodes().GetEndOfContent().StartOfSectionNode(), 1 ); + // den ersten immer wieder neu anlegen (ohne Attribute/Vorlagen/...) + SwTxtNode* pFirstNd = GetNodes().MakeTxtNode( aSttIdx, pDfltTxtFmtColl ); + GetNodes().Delete( aSttIdx, + GetNodes().GetEndOfContent().GetIndex() - aSttIdx.GetIndex() ); + + // Delete fuer Collections + // damit die Abhaengigen wech sind + SwTxtFmtColl* pFtnColl = pFtnInfo->GetFtnTxtColl(); + if( pFtnColl ) pFtnColl->Remove( pFtnInfo ); + pFtnColl = pEndNoteInfo->GetFtnTxtColl(); + if( pFtnColl ) pFtnColl->Remove( pEndNoteInfo ); + + // JP 27.01.98: opt.: ausgehend davon, das Standard als 2. im Array + // steht, sollte das als letztes geloescht werden, damit + // die ganze Umhaengerei der Formate vermieden wird! + if( 2 < pTxtFmtCollTbl->Count() ) + pTxtFmtCollTbl->DeleteAndDestroy( 2, pTxtFmtCollTbl->Count()-2 ); + pTxtFmtCollTbl->DeleteAndDestroy( 1, pTxtFmtCollTbl->Count()-1 ); + pGrfFmtCollTbl->DeleteAndDestroy( 1, pGrfFmtCollTbl->Count()-1 ); + pFrmFmtTbl->DeleteAndDestroy( 1, pFrmFmtTbl->Count()-1 ); + pCharFmtTbl->DeleteAndDestroy( 1, pCharFmtTbl->Count()-1 ); + + ReleaseDrawModel(); + + pFldTypes->DeleteAndDestroy( INIT_FLDTYPES, + pFldTypes->Count() - INIT_FLDTYPES ); + + delete pNumberFormatter, pNumberFormatter = 0; + + GetPageDescFromPool( RES_POOLPAGE_STANDARD ); + pFirstNd->ChgFmtColl( GetTxtCollFromPool( RES_POOLCOLL_STANDARD )); +} + +void SwDoc::SetPreViewPrtData( const SwPagePreViewPrtData* pNew ) +{ + if( pNew ) + { + if( pPgPViewPrtData ) + *pPgPViewPrtData = *pNew; + else + pPgPViewPrtData = new SwPagePreViewPrtData( *pNew ); + } + else if( pPgPViewPrtData ) + DELETEZ( pPgPViewPrtData ); + SetModified(); +} +/* -----------------------------06.01.00 14:03-------------------------------- + + ---------------------------------------------------------------------------*/ +SwModify* SwDoc::GetUnoCallBack() const +{ + return pUnoCallBack; +} + + + + diff --git a/sw/source/core/doc/docnum.cxx b/sw/source/core/doc/docnum.cxx new file mode 100644 index 000000000000..2acec5103e42 --- /dev/null +++ b/sw/source/core/doc/docnum.cxx @@ -0,0 +1,2187 @@ +/************************************************************************* + * + * $RCSfile: docnum.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:15 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _HINTIDS_HXX +#include +#endif + +#ifndef _DATE_HXX //autogen +#include +#endif +#ifndef _TIME_HXX //autogen +#include +#endif +#ifndef _TOOLS_RESID_HXX //autogen +#include +#endif +#ifndef _URLOBJ_HXX +#include +#endif +#ifndef _SVX_LRSPITEM_HXX //autogen +#include +#endif + +#ifndef _FTNINFO_HXX //autogen +#include +#endif +#ifndef _FTNIDX_HXX //autogen +#include +#endif +#ifndef _DOC_HXX +#include +#endif +#ifndef _PAM_HXX +#include +#endif +#ifndef _NDTXT_HXX +#include +#endif +#ifndef _NUMRULE_HXX +#include +#endif +#ifndef _DOCTXM_HXX +#include // pTOXBaseRing +#endif +#ifndef _POOLFMT_HXX +#include +#endif +#ifndef _UNDOBJ_HXX +#include +#endif +#ifndef _SWUNDO_HXX +#include +#endif +#ifndef _ROLBCK_HXX +#include +#endif +#ifndef _PARATR_HXX +#include +#endif +#ifndef _DOCARY_HXX +#include +#endif +#ifndef _MVSAVE_HXX +#include +#endif +#ifndef _HINTS_HXX +#include +#endif +#ifndef _TXTFRM_HXX +#include +#endif +#ifndef _HINTS_HXX +#include +#endif +#ifndef _PAMTYP_HXX +#include +#endif +#ifndef _REDLINE_HXX +#include +#endif +#ifndef _COMCORE_HRC +#include +#endif + + +inline BYTE GetUpperLvlChg( BYTE nCurLvl, BYTE nLevel, USHORT nMask ) +{ + if( 1 < nLevel ) + { + if( nCurLvl + 1 >= nLevel ) + nCurLvl -= nLevel - 1; + else + nCurLvl = 0; + } + return (nMask - 1) & ~(( 1 << nCurLvl ) - 1); +} + +void SwDoc::SetOutlineNumRule( const SwNumRule& rRule ) +{ + USHORT nChkLevel = 0, nChgFmtLevel = 0; + if( pOutlineRule ) + { + USHORT nMask = 1; + for( BYTE n = 0; n < MAXLEVEL; ++n, nMask <<= 1 ) + { + const SwNumFmt& rOld = pOutlineRule->Get( n ), + & rNew = rRule.Get( n ); + if( rOld != rNew ) + { + nChgFmtLevel |= nMask; + if( rOld.GetAbsLSpace() != rNew.GetAbsLSpace() || + rOld.GetFirstLineOffset() != rNew.GetFirstLineOffset() ) + nChkLevel |= nMask; + } + else if( SVX_NUM_NUMBER_NONE > rNew.eType && 1 < rNew.GetUpperLevel() && + 0 != (nChgFmtLevel & GetUpperLvlChg( n, + rNew.GetUpperLevel(), nMask )) ) + nChgFmtLevel |= nMask; + } + (*pOutlineRule) = rRule; + } + else + { + nChgFmtLevel = nChkLevel = 0xffff; + pOutlineRule = new SwNumRule( rRule ); + } + pOutlineRule->SetRuleType( OUTLINE_RULE ); + pOutlineRule->SetName( String::CreateFromAscii( + SwNumRule::GetOutlineRuleName() )); + + // teste ob die evt. gesetzen CharFormate in diesem Document + // definiert sind + pOutlineRule->CheckCharFmts( this ); + + // losche aus dem Array alle Nodes, die ohne Outline Nummerierung sind + SwOutlineNodes& rArr = (SwOutlineNodes&)GetNodes().GetOutLineNds(); + { + SwNodeNum aNoNum( NO_NUMBERING ); + for( USHORT n = 0; n < rArr.Count(); ++n ) + { + SwTxtNode* pTxtNd = rArr[n]->GetTxtNode(); + if( pTxtNd && NO_NUMBERING == pTxtNd->GetTxtColl()->GetOutlineLevel() ) + { + pTxtNd->UpdateOutlineNum( aNoNum ); + rArr.Remove( n-- ); + } + } + } + + // suche alle Nodes, die neu aufgenommen werden muessen !! + // (eigentlich koennte das auch per Modify am die Nodes propagiert + // werden !! ) + ULONG nStt = GetNodes().GetEndOfContent().StartOfSectionIndex(); + for( USHORT n = 0; n < pTxtFmtCollTbl->Count(); ++n ) + { + SwTxtFmtColl* pColl = (*pTxtFmtCollTbl)[ n ]; + BYTE nLevel = pColl->GetOutlineLevel(); + if( NO_NUMBERING != nLevel ) + { +#ifndef NUM_RELSPACE + // JP 08.07.98: Einzuege aus der Outline uebernehmen. + // ??Aber nur wenn sie veraendert wurden?? + if( ( nLevel = GetRealLevel( nLevel )) < MAXLEVEL + /*&& 0 != (nChkLevel & (1 << nLevel ))*/ ) + { + SvxLRSpaceItem aLR( (SvxLRSpaceItem&)pColl->GetAttr( RES_LR_SPACE ) ); + const SwNumFmt& rNFmt = pOutlineRule->Get( nLevel ); + + // ohne Nummer immer ohne FirstLineOffset!!!! + short nFOfst; + if( pColl->GetOutlineLevel() & NO_NUMLEVEL ) + nFOfst = 0; + else + nFOfst = rNFmt.GetFirstLineOffset(); + + if( aLR.GetTxtLeft() != rNFmt.GetAbsLSpace() || + aLR.GetTxtFirstLineOfst() != nFOfst ) + { + aLR.SetTxtFirstLineOfstValue( nFOfst ); + aLR.SetTxtLeft( rNFmt.GetAbsLSpace() ); + + pColl->SetAttr( aLR ); + } + } +#endif + SwClientIter aIter( *pColl ); + for( SwTxtNode* pNd = (SwTxtNode*)aIter.First( TYPE( SwTxtNode )); + pNd; pNd = (SwTxtNode*)aIter.Next() ) + if( pNd->GetNodes().IsDocNodes() && nStt < pNd->GetIndex() ) + rArr.Insert( pNd ); + } + } + + for( n = 0; n < rArr.Count(); ++n ) + { + SwTxtNode* pNd = rArr[ n ]->GetTxtNode(); + ASSERT( pNd, "was ist das fuer ein Node?" ); + if( ( 1 << (pNd->GetTxtColl()->GetOutlineLevel() & ~NO_NUMLEVEL ) + & nChgFmtLevel )) + pNd->NumRuleChgd(); + } + GetNodes().UpdateOutlineNodes(); // update der Nummern + + // gibt es Fussnoten && gilt Kapitelweises Nummerieren, dann updaten + if( GetFtnIdxs().Count() && FTNNUM_CHAPTER == GetFtnInfo().eNum ) + GetFtnIdxs().UpdateAllFtn(); + + UpdateExpFlds(); + + SetModified(); +} + + + + // Hoch-/Runterstufen +BOOL SwDoc::OutlineUpDown( const SwPaM& rPam, short nOffset ) +{ + if( !GetNodes().GetOutLineNds().Count() || !nOffset ) + return FALSE; + + // den Bereich feststellen + const SwOutlineNodes& rOutlNds = GetNodes().GetOutLineNds(); + const SwNodePtr pSttNd = (SwNodePtr)&rPam.Start()->nNode.GetNode(); + const SwNodePtr pEndNd = (SwNodePtr)&rPam.End()->nNode.GetNode(); + USHORT nSttPos, nEndPos; + + if( !rOutlNds.Seek_Entry( pSttNd, &nSttPos ) && + !nSttPos-- ) + // wir stehen in keiner "Outline-Section" + return FALSE; + + if( rOutlNds.Seek_Entry( pEndNd, &nEndPos ) ) + ++nEndPos; + + + // jetzt haben wir unseren Bereich im OutlineNodes-Array + // dann prufe ersmal, ob nicht unterebenen aufgehoben werden + // (Stufung ueber die Grenzen) + register USHORT n; + if( 0 <= nOffset ) // nach unten + { + for( n = nSttPos; n < nEndPos; ++n ) + if( rOutlNds[ n ]->GetTxtNode()->GetTxtColl()-> + GetOutlineLevel() + nOffset >= MAXLEVEL ) + return FALSE; + } + else + for( n = nSttPos; n < nEndPos; ++n ) + if( rOutlNds[ n ]->GetTxtNode()->GetTxtColl()-> + GetOutlineLevel() < -nOffset ) + return FALSE; + + // so, dann koennen wir: + // 1. Vorlagen-Array anlegen + SwTxtFmtColl* aCollArr[ MAXLEVEL ]; + memset( aCollArr, 0, sizeof( SwTxtFmtColl* ) * MAXLEVEL ); + + for( n = 0; n < pTxtFmtCollTbl->Count(); ++n ) + { + BYTE nLevel = (*pTxtFmtCollTbl)[ n ]->GetOutlineLevel(); + if( nLevel < MAXLEVEL ) + aCollArr[ nLevel ] = (*pTxtFmtCollTbl)[ n ]; + } + for( n = 0; n < MAXLEVEL; ++n ) + if( !aCollArr[ n ] ) + aCollArr[ n ] = GetTxtCollFromPool( RES_POOLCOLL_HEADLINE1 + n ); + + if( DoesUndo() ) + { + ClearRedo(); + AppendUndo( new SwUndoOutlineLeftRight( rPam, nOffset ) ); + } + + // 2. allen Nodes die neue Vorlage zuweisen + for( n = nSttPos; n < nEndPos; ++n ) + { + SwTxtNode* pTxtNd = rOutlNds[ n ]->GetTxtNode(); + SwTxtFmtColl* pColl = pTxtNd->GetTxtColl(); + pColl = aCollArr[ pColl->GetOutlineLevel() + nOffset ]; + pColl = (SwTxtFmtColl*)pTxtNd->ChgFmtColl( pColl ); + // Undo ??? + } + + SetModified(); + return TRUE; +} + + + + // Hoch-/Runter - Verschieben ! +BOOL SwDoc::MoveOutlinePara( const SwPaM& rPam, short nOffset ) +{ + // kein Verschiebung in den Sonderbereichen + const SwPosition& rStt = *rPam.Start(), + & rEnd = &rStt == rPam.GetPoint() ? *rPam.GetMark() + : *rPam.GetPoint(); + if( !GetNodes().GetOutLineNds().Count() || !nOffset || + rStt.nNode.GetIndex() < aNodes.GetEndOfExtras().GetIndex() || + rEnd.nNode.GetIndex() < aNodes.GetEndOfExtras().GetIndex() ) + return FALSE; + + USHORT nAktPos = 0; + SwNodeIndex aSttRg( rStt.nNode ), aEndRg( rEnd.nNode ); + + // nach vorne -> vom Start erfragen + // nach hinten -> vom End erfragen + if( 0 > nOffset ) // nach vorne + { + SwNode* pSrch = &aSttRg.GetNode(); + if( !GetNodes().GetOutLineNds().Seek_Entry( pSrch, &nAktPos ) ) + { + if( !nAktPos-- ) + // wir stehen in keiner "Outline-Section" + return FALSE; + + // dann sollten wir den Start korrigieren !!! + aSttRg = *GetNodes().GetOutLineNds()[ nAktPos ]; + } + + pSrch = &aEndRg.GetNode(); + USHORT nTmp; + if( GetNodes().GetOutLineNds().Seek_Entry( pSrch, &nTmp )) + // wenn die Selection in einem OutlineNode endet, diesen noch + // mitnehmen + aEndRg++; + else + { + aEndRg = nTmp < GetNodes().GetOutLineNds().Count() + ? *GetNodes().GetOutLineNds()[ nTmp ] + : GetNodes().GetEndOfContent(); + } + + if( aEndRg == aSttRg ) + // kein Bereich, dann machen wir uns einen + aEndRg++; + } + // nach hinten + else + { + SwNode* pSrch = &aEndRg.GetNode(); + if( GetNodes().GetOutLineNds().Seek_Entry( pSrch, &nAktPos ) ) + ++nAktPos; + + aEndRg = nAktPos < GetNodes().GetOutLineNds().Count() + ? *GetNodes().GetOutLineNds()[ nAktPos ] + : GetNodes().GetEndOfContent(); + + pSrch = &aSttRg.GetNode(); + USHORT nTmp; + if( !GetNodes().GetOutLineNds().Seek_Entry( pSrch, &nTmp ) ) + { + if( --nTmp ) + aSttRg = *GetNodes().GetOutLineNds()[ nTmp ]; + else + aSttRg = *GetNodes().GetEndOfContent().StartOfSectionNode(); + } + } + // neue Position errechnen: + const SwNode* pNd; + if( nOffset < 0 && nAktPos < USHORT(-nOffset) ) + pNd = GetNodes().GetEndOfContent().StartOfSectionNode(); + else if( nAktPos + nOffset >= GetNodes().GetOutLineNds().Count() ) + pNd = &GetNodes().GetEndOfContent(); + else + pNd = GetNodes().GetOutLineNds()[ nAktPos + nOffset ]; + + ULONG nNewPos = pNd->GetIndex(); + + ASSERT( aSttRg.GetIndex() > nNewPos || nNewPos >= aEndRg.GetIndex(), + "Position liegt im MoveBereich" ); + + // wurde ein Position in den Sonderbereichen errechnet, dann + // setze die Position auf den Dokumentanfang. + // Sollten da Bereiche oder Tabellen stehen, so werden sie nach + // hinten verschoben. + nNewPos = Max( nNewPos, aNodes.GetEndOfExtras().GetIndex() + 2 ); + + long nOffs = nNewPos - ( 0 < nOffset ? aEndRg.GetIndex() : aSttRg.GetIndex()); + SwPaM aPam( aSttRg, aEndRg, 0, -1 ); + return MoveParagraph( aPam, nOffs, TRUE ); +} + + +USHORT lcl_FindOutlineName( const SwNodes& rNds, const String& rName, + BOOL bExact ) +{ + USHORT nSavePos = USHRT_MAX; + const SwOutlineNodes& rOutlNds = rNds.GetOutLineNds(); + String sName( INetURLObject::createFragment( rName ) ); + for( USHORT n = 0; n < rOutlNds.Count(); ++n ) + { + SwTxtNode* pTxtNd = rOutlNds[ n ]->GetTxtNode(); + String sTxt( INetURLObject::createFragment( pTxtNd->GetExpandTxt() )); + if( sTxt.Equals( rName ) ) + { + // "exact" gefunden, setze Pos auf den Node + nSavePos = n; + break; + } + else if( !bExact && USHRT_MAX == nSavePos && + COMPARE_EQUAL == sTxt.CompareTo( rName, rName.Len()) ) + { + // dann vielleicht nur den den 1.Teil vom Text gefunden + nSavePos = n; + } + } + + return nSavePos; +} + + + +USHORT lcl_FindOutlineNum( const SwNodes& rNds, String& rName ) +{ + // Gueltig Nummern sind (immer nur Offsets!!!): + // ([Nummer]+\.)+ (als regulaerer Ausdruck!) + // (Nummer gefolgt von Punkt, zum 5 Wiederholungen) + // also: "1.1.", "1.", "1.1.1." + xub_StrLen nPos = 0; + String sNum = rName.GetToken( 0, '.', nPos ); + if( STRING_NOTFOUND == nPos ) + return USHRT_MAX; // ungueltige Nummer!!! + + USHORT nLevelVal[ MAXLEVEL ]; // Nummern aller Levels + memset( nLevelVal, 0, MAXLEVEL * sizeof( nLevelVal[0] )); + BYTE nLevel = 0; + String sName( rName ); + + while( STRING_NOTFOUND != nPos ) + { + USHORT nVal = 0; + sal_Unicode c; + for( USHORT n = 0; n < sNum.Len(); ++n ) + if( '0' <= ( c = sNum.GetChar( n )) && c <= '9' ) + { + nVal *= 10; nVal += c - '0'; + } + else if( nLevel ) + break; // "fast" gueltige Nummer + else + return USHRT_MAX; // ungueltige Nummer!!! + + if( MAXLEVEL > nLevel ) + nLevelVal[ nLevel++ ] = nVal; + + sName.Erase( 0, nPos ); + nPos = 0; + sNum = sName.GetToken( 0, '.', nPos ); + } + + rName = sName; // das ist der nachfolgende Text. + + // alle Levels gelesen, dann suche mal im Document nach dieser + // Gliederung: + const SwOutlineNodes& rOutlNds = rNds.GetOutLineNds(); + // OS: ohne OutlineNodes lohnt die Suche nicht + // und man spart sich einen Absturz #42958# + if(!rOutlNds.Count()) + return USHRT_MAX; + SwTxtNode* pNd; + nPos = 0; + BOOL bNextPos = FALSE; + for( BYTE n = 0; n < nLevel; ++n ) + { + USHORT nOff = nLevelVal[ n ]; + if( nOff ) + { + USHORT nLastPos = nPos; + if( bNextPos ) + ++nPos; + bNextPos = FALSE; + for( ; nPos < rOutlNds.Count(); ++nPos ) + { + pNd = rOutlNds[ nPos ]->GetTxtNode(); + BYTE nLvl = pNd->GetTxtColl()->GetOutlineLevel(); + if( nLvl == n ) + { + nLastPos = nPos; + if( !--nOff ) + { + bNextPos = TRUE; // auf jedenfall mit dem nachsten weiter + break; + } + } + else if( nLvl < n ) // nicht ueber den Level hinaus + { + nPos = nLastPos; + break; + } + } + if( nPos >= rOutlNds.Count() ) + { + if( !n ) // auf oberster Ebene muss die + return USHRT_MAX; // Nummer gefunden werden + nPos = nLastPos; + } + } + else if( nPos+1 < rOutlNds.Count() ) + { + pNd = rOutlNds[ nPos+1 ]->GetTxtNode(); + if( n < pNd->GetTxtColl()->GetOutlineLevel() ) + ++nPos; + } + } + + // jetzt sollte im nPos die richtige Position fuer den OutlineLevel + // stehen: + return nPos; +} + + // zu diesem Gliederungspunkt + + + // JP 13.06.96: + // im Namen kann eine Nummer oder/und der Text stehen. + // zuerst wird ueber die Nummer versucht den richtigen Eintrag zu finden. + // Gibt es diesen, dann wird ueber den Text verglichen, od es der + // gewuenschte ist. Ist das nicht der Fall, wird noch mal nur ueber den + // Text gesucht. Wird dieser gefunden ist es der Eintrag. Ansonsten der, + // der ueber die Nummer gefunden wurde. + // Ist keine Nummer angegeben, dann nur den Text suchen. + +BOOL SwDoc::GotoOutline( SwPosition& rPos, const String& rName ) const +{ + if( rName.Len() ) + { + const SwOutlineNodes& rOutlNds = GetNodes().GetOutLineNds(); + + // 1. Schritt: ueber die Nummer: + String sName( rName ); + USHORT nFndPos = ::lcl_FindOutlineNum( GetNodes(), sName ); + if( USHRT_MAX != nFndPos ) + { + SwTxtNode* pNd = rOutlNds[ nFndPos ]->GetTxtNode(); + String sTxt( pNd->GetExpandTxt() ); + if( sTxt.Equals( sName ) ) + { + USHORT nTmp = ::lcl_FindOutlineName( GetNodes(), sName, TRUE ); + if( USHRT_MAX != nTmp ) // ueber den Namen gefunden + { + nFndPos = nTmp; + pNd = rOutlNds[ nFndPos ]->GetTxtNode(); + } + } + rPos.nNode = *pNd; + rPos.nContent.Assign( pNd, 0 ); + return TRUE; + } + + nFndPos = ::lcl_FindOutlineName( GetNodes(), rName, FALSE ); + if( USHRT_MAX != nFndPos ) + { + SwTxtNode* pNd = rOutlNds[ nFndPos ]->GetTxtNode(); + rPos.nNode = *pNd; + rPos.nContent.Assign( pNd, 0 ); + return TRUE; + } + } + return FALSE; +} + +void SwDoc::SetOutlineLSpace( BYTE nLevel, short nFirstLnOfst, USHORT nLSpace ) +{ + if( MAXLEVEL >= nLevel ) + { + const SwNumFmt& rNFmt = pOutlineRule->Get( nLevel ); + if( nLSpace != rNFmt.GetAbsLSpace() || + nFirstLnOfst != rNFmt.GetFirstLineOffset() ) + { + SwNumFmt aFmt( rNFmt ); + aFmt.SetAbsLSpace( nLSpace ); + aFmt.SetFirstLineOffset( nFirstLnOfst ); + pOutlineRule->Set( nLevel, aFmt ); + } + } +} + +/* */ + +// --- Nummerierung ----------------------------------------- + +void SwNumRuleInfo::MakeList( SwDoc& rDoc ) +{ + SwModify* pMod; + const SfxPoolItem* pItem; + USHORT i, nMaxItems = rDoc.GetAttrPool().GetItemCount( RES_PARATR_NUMRULE); + for( i = 0; i < nMaxItems; ++i ) + if( 0 != (pItem = rDoc.GetAttrPool().GetItem( RES_PARATR_NUMRULE, i ) ) && + 0 != ( pMod = (SwModify*)((SwNumRuleItem*)pItem)->GetDefinedIn()) && + ((SwNumRuleItem*)pItem)->GetValue().Len() && + ((SwNumRuleItem*)pItem)->GetValue() == rName ) + { + if( pMod->IsA( TYPE( SwFmt )) ) + pMod->GetInfo( *this ); + else if( ((SwTxtNode*)pMod)->GetNodes().IsDocNodes() ) + AddNode( *(SwTxtNode*)pMod ); + } +} + + +void lcl_ChgNumRule( SwDoc& rDoc, const SwNumRule& rRule, SwHistory* pHist, + SwNumRuleInfo* pRuleInfo = 0 ) +{ + SwNumRule* pOld = rDoc.FindNumRulePtr( rRule.GetName() ); + ASSERT( pOld, "ohne die alte NumRule geht gar nichts" ); + + USHORT nChkLevel = 0, nChgFmtLevel = 0, nMask = 1; + + for( BYTE n = 0; n < MAXLEVEL; ++n, nMask <<= 1 ) + { + const SwNumFmt& rOldFmt = pOld->Get( n ), + & rNewFmt = rRule.Get( n ); + + if( rOldFmt != rNewFmt ) + { + nChgFmtLevel |= nMask; + if( rOldFmt.GetAbsLSpace() != rNewFmt.GetAbsLSpace() || + rOldFmt.GetFirstLineOffset() != rNewFmt.GetFirstLineOffset() ) + nChkLevel |= nMask; + } + else if( SVX_NUM_NUMBER_NONE > rNewFmt.eType && 1 < rNewFmt.GetUpperLevel() && + 0 != (nChgFmtLevel & GetUpperLvlChg( n, rNewFmt.GetUpperLevel(),nMask )) ) + nChgFmtLevel |= nMask; + } + + if( !nChgFmtLevel ) // es wurde nichts veraendert? + { + pOld->CheckCharFmts( &rDoc ); + pOld->SetContinusNum( rRule.IsContinusNum() ); + return ; + } + + SwNumRuleInfo* pUpd; + if( !pRuleInfo ) + { + pUpd = new SwNumRuleInfo( rRule.GetName() ); + pUpd->MakeList( rDoc ); + } + else + pUpd = pRuleInfo; + + BYTE nLvl; + for( ULONG nFirst = 0, nLast = pUpd->GetList().Count(); + nFirst < nLast; ++nFirst ) + { + SwTxtNode* pTxtNd = pUpd->GetList().GetObject( nFirst ); + if( pTxtNd->GetNum() && ( nLvl = (~NO_NUMLEVEL & + pTxtNd->GetNum()->GetLevel() ) ) < MAXLEVEL ) + { + if( nChgFmtLevel & ( 1 << nLvl )) + { + pTxtNd->NumRuleChgd(); + +#ifndef NUM_RELSPACE + if( nChkLevel && (nChkLevel & ( 1 << nLvl )) && + pOld->IsRuleLSpace( *pTxtNd ) ) + pTxtNd->SetNumLSpace( TRUE ); + + if( pHist ) + { + const SfxPoolItem& rItem = + pTxtNd->SwCntntNode::GetAttr( RES_LR_SPACE ); + pHist->Add( &rItem, &rItem, pTxtNd->GetIndex() ); + } +#endif + } + } + } + + for( n = 0; n < MAXLEVEL; ++n ) + if( nChgFmtLevel & ( 1 << n )) + pOld->Set( n, rRule.GetNumFmt( n )); + + pOld->CheckCharFmts( &rDoc ); + pOld->SetInvalidRule( TRUE ); + pOld->SetContinusNum( rRule.IsContinusNum() ); + + if( !pRuleInfo ) + delete pUpd; +} + +void SwDoc::SetNumRule( const SwPaM& rPam, const SwNumRule& rRule, + BOOL bSetAbsLSpace ) +{ + SwUndoInsNum* pUndo; + if( DoesUndo() ) + { + ClearRedo(); + StartUndo( UNDO_START ); // Klammerung fuer die Attribute! + AppendUndo( pUndo = new SwUndoInsNum( rPam, rRule ) ); + } + else + pUndo = 0; + + ULONG nPamPos = rPam.Start()->nNode.GetIndex(); + BOOL bSetItem = TRUE; + SwNumRule* pNew = FindNumRulePtr( rRule.GetName() ); + if( !pNew ) + pNew = (*pNumRuleTbl)[ MakeNumRule( rRule.GetName(), &rRule ) ]; + else if( rRule.IsAutoRule() && !(*pNew == rRule) ) + { + // die Rule existiert schon, wurde aber veraendert. Dann muss hier + // entschieden werden, in wie weit eine neue erzeugt wird oder + // die aktuelle geupdatet wird. + + // neue erzeugen wenn: + // - der Pam einen Bereich hat + // - Nodes existieren, die mit der Rule neu Starten + + if( rPam.HasMark() ) + pNew = (*pNumRuleTbl)[ MakeNumRule( rRule.GetName(), &rRule ) ]; + else + { + SwNumRuleInfo aUpd( rRule.GetName() ); + aUpd.MakeList( *this ); + + // Position suchen und bestimme ob ein Node davor oder dahinter + // einen Start erzwingt + SwTxtNode* pTxtNd; + ULONG nFndPos, nFirst, nLast; + + if( TABLE_ENTRY_NOTFOUND != aUpd.GetList().SearchKey( nPamPos, &nFndPos )) + ++nFndPos; + + for( nLast = nFndPos; nLast < aUpd.GetList().Count(); ++nLast ) + if( ( pTxtNd = aUpd.GetList().GetObject( nLast ))->GetNum() && + pTxtNd->GetNum()->IsStart() ) + break; + for( nFirst = nFndPos; nFirst; ) + if( ( pTxtNd = aUpd.GetList().GetObject( --nFirst ))->GetNum() && + pTxtNd->GetNum()->IsStart() ) + break; + + bSetItem = FALSE; + nPamPos = ULONG_MAX; + if( !pNew->IsAutoRule() || nFirst || nLast != aUpd.GetList().Count() ) + { + // dann neue Numerierung ueber diesen Bereich + // definieren und den Start am Anfang/Ende zurueck setzen + pTxtNd = aUpd.GetList().GetObject( nFirst ); + if( pTxtNd->GetNum()->IsStart() ) + { + ((SwNodeNum*)pTxtNd->GetNum())->SetStart( FALSE ); + if( pUndo ) + pUndo->SetSttNum( pTxtNd->GetIndex() ); + } + + SwHistory* pHist = pUndo ? pUndo->GetHistory() : 0; +#ifndef NUM_RELSPACE + if( pHist ) + { + // die LRSpaces muessen zuerst gesichert werden + for( ULONG n = nFirst; n < nLast; ++n ) + { + pTxtNd = aUpd.GetList().GetObject( n ); + SfxPoolItem* pItem = (SfxPoolItem*) + &pTxtNd->SwCntntNode::GetAttr( RES_LR_SPACE ); + pHist->Add( pItem, pItem, pTxtNd->GetIndex() ); + } + pUndo->SetLRSpaceEndPos(); + } +#endif + SwRegHistory aRegH( pHist ); + SwNumRule* pOld = pNew; + pNew = (*pNumRuleTbl)[ MakeNumRule( rRule.GetName(), &rRule ) ]; + + USHORT nChgFmtLevel = 0; + for( BYTE n = 0; n < MAXLEVEL; ++n ) + { + const SwNumFmt& rOldFmt = pOld->Get( n ), + & rNewFmt = rRule.Get( n ); + + if( rOldFmt.GetAbsLSpace() != rNewFmt.GetAbsLSpace() || + rOldFmt.GetFirstLineOffset() != rNewFmt.GetFirstLineOffset() ) + nChgFmtLevel |= ( 1 << n ); + } + + SwNumRuleItem aRule( pNew->GetName() ); + for( ; nFirst < nLast; ++nFirst ) + { + pTxtNd = aUpd.GetList().GetObject( nFirst ); + + aRegH.RegisterInModify( pTxtNd, *pTxtNd ); + +#ifndef NUM_RELSPACE + BYTE nLvl = !pTxtNd->GetNum() ? NO_NUMBERING + : pTxtNd->GetNum()->GetLevel() & ~NO_NUMLEVEL; + if( nLvl < MAXLEVEL && (nChgFmtLevel & ( 1 << nLvl )) && + pOld->IsRuleLSpace( *pTxtNd ) ) + pTxtNd->SetNumLSpace( TRUE ); +#endif + + pTxtNd->SwCntntNode::SetAttr( aRule ); + pTxtNd->NumRuleChgd(); + } + } + else + { + // dann nur die Rule Updaten + SwHistory* pHist = 0; + if( pUndo ) + { + pUndo->SaveOldNumRule( *pNew ); + pHist = pUndo->GetHistory(); + } + ::lcl_ChgNumRule( *this, rRule, pHist, &aUpd ); + if( pUndo ) + pUndo->SetLRSpaceEndPos(); + } + } + } + + if( bSetItem ) + { +#ifndef NUM_RELSPACE + if( pUndo ) + { + SwHistory* pHist = pUndo->GetHistory(); + SwCntntNode* pCNd; + for( ULONG n = nPamPos, nEndPos = rPam.End()->nNode.GetIndex(); + n <= nEndPos; ++n ) + if( 0 != ( pCNd = GetNodes()[ n ]->GetCntntNode() )) + { + const SfxPoolItem& rItem = pCNd->GetAttr( RES_LR_SPACE ); + pHist->Add( &rItem, &rItem, n ); + } + pUndo->SetLRSpaceEndPos(); + } +#endif + Insert( rPam, SwNumRuleItem( pNew->GetName() ) ); + } + UpdateNumRule( pNew->GetName(), nPamPos ); + + EndUndo( UNDO_END ); + + SetModified(); +} + +void SwDoc::SetNumRuleStart( const SwPosition& rPos, BOOL bFlag ) +{ + SwTxtNode* pTxtNd = rPos.nNode.GetNode().GetTxtNode(); + const SwNumRule* pRule; + if( pTxtNd && pTxtNd->GetNum() && 0 != ( pRule = pTxtNd->GetNumRule() ) + && bFlag != pTxtNd->GetNum()->IsStart()) + { + if( DoesUndo() ) + { + ClearRedo(); + AppendUndo( new SwUndoNumRuleStart( rPos, bFlag )); + } + SwNodeNum aNum( *pTxtNd->GetNum() ); + aNum.SetStart( bFlag ); + pTxtNd->UpdateNum( aNum ); + UpdateNumRule( pRule->GetName(), + bFlag ? rPos.nNode.GetIndex() : ULONG_MAX ); + SetModified(); + } +} + +void SwDoc::SetNodeNumStart( const SwPosition& rPos, USHORT nStt ) +{ + SwTxtNode* pTxtNd = rPos.nNode.GetNode().GetTxtNode(); + const SwNumRule* pRule; + if( pTxtNd && pTxtNd->GetNum() && 0 != ( pRule = pTxtNd->GetNumRule() ) + && nStt != pTxtNd->GetNum()->GetSetValue() ) + { + if( DoesUndo() ) + { + ClearRedo(); + AppendUndo( new SwUndoNumRuleStart( rPos, nStt )); + } + SwNodeNum aNum( *pTxtNd->GetNum() ); + aNum.SetSetValue( nStt ); + pTxtNd->UpdateNum( aNum ); + UpdateNumRule( pRule->GetName(), USHRT_MAX != nStt + ? rPos.nNode.GetIndex() : ULONG_MAX ); + SetModified(); + } +} + + // loeschen geht nur, wenn die Rule niemand benutzt! +BOOL SwDoc::DelNumRule( const String& rName ) +{ + USHORT nPos = FindNumRule( rName ); + if( USHRT_MAX != nPos && !IsUsed( *(*pNumRuleTbl)[ nPos ] )) + { + pNumRuleTbl->DeleteAndDestroy( nPos ); + SetModified(); + return TRUE; + } + return FALSE; +} + +void SwDoc::ChgNumRuleFmts( const SwNumRule& rRule ) +{ + SwNumRule* pRule = FindNumRulePtr( rRule.GetName() ); + if( pRule ) + { + SwUndoInsNum* pUndo = 0; + SwHistory* pHistory = 0; + if( DoesUndo() && pRule->IsAutoRule() ) + { + ClearRedo(); + pUndo = new SwUndoInsNum( *pRule, rRule ); + pHistory = pUndo->GetHistory(); + AppendUndo( pUndo ); + } + ::lcl_ChgNumRule( *this, rRule, pHistory ); + + if( pUndo ) + pUndo->SetLRSpaceEndPos(); + + SetModified(); + } +} + +void SwDoc::StopNumRuleAnimations( OutputDevice* pOut ) +{ + for( USHORT n = GetNumRuleTbl().Count(); n; ) + { + SwNumRuleInfo aUpd( GetNumRuleTbl()[ --n ]->GetName() ); + aUpd.MakeList( *this ); + + for( ULONG nFirst = 0, nLast = aUpd.GetList().Count(); + nFirst < nLast; ++nFirst ) + { + SwTxtNode* pTNd = aUpd.GetList().GetObject( nFirst ); + + SwClientIter aIter( *pTNd ); + for( SwFrm* pFrm = (SwFrm*)aIter.First( TYPE(SwFrm) ); + pFrm; pFrm = (SwFrm*)aIter.Next() ) + if( ((SwTxtFrm*)pFrm)->HasAnimation() ) + ((SwTxtFrm*)pFrm)->StopAnimation( pOut ); + } + } +} + +BOOL SwDoc::ReplaceNumRule( const SwPosition& rPos, + const String& rOldRule, const String& rNewRule ) +{ + BOOL bRet = FALSE; + SwNumRule *pOldRule = FindNumRulePtr( rOldRule ), + *pNewRule = FindNumRulePtr( rNewRule ); + if( pOldRule && pNewRule && pOldRule != pNewRule ) + { + SwUndoInsNum* pUndo = 0; + if( DoesUndo() ) + { + ClearRedo(); + StartUndo( UNDO_START ); // Klammerung fuer die Attribute! + AppendUndo( pUndo = new SwUndoInsNum( rPos, *pNewRule, rOldRule ) ); + } + + SwNumRuleInfo aUpd( rOldRule ); + aUpd.MakeList( *this ); + + // Position suchen und bestimme ob ein Node davor oder dahinter + // einen Start erzwingt + SwTxtNode* pTxtNd; + ULONG nFndPos, nFirst, nLast; + + if( TABLE_ENTRY_NOTFOUND != aUpd.GetList().SearchKey( + rPos.nNode.GetIndex(), &nFndPos )) + ++nFndPos; + + for( nLast = nFndPos; nLast < aUpd.GetList().Count(); ++nLast ) + if( ( pTxtNd = aUpd.GetList().GetObject( nLast ))->GetNum() && + pTxtNd->GetNum()->IsStart() ) + break; + for( nFirst = nFndPos; nFirst; ) + if( ( pTxtNd = aUpd.GetList().GetObject( --nFirst ))->GetNum() && + pTxtNd->GetNum()->IsStart() ) + break; + + // dann neue Numerierung ueber diesen Bereich + // definieren und den Start am Anfang/Ende zurueck setzen + pTxtNd = aUpd.GetList().GetObject( nFirst ); + if( pTxtNd->GetNum()->IsStart() ) + { + ((SwNodeNum*)pTxtNd->GetNum())->SetStart( FALSE ); + if( pUndo ) + pUndo->SetSttNum( pTxtNd->GetIndex() ); + } + + SwRegHistory aRegH( pUndo ? pUndo->GetHistory() : 0 ); + USHORT nChgFmtLevel = 0; + for( BYTE n = 0; n < MAXLEVEL; ++n ) + { + const SwNumFmt& rOldFmt = pOldRule->Get( n ), + & rNewFmt = pNewRule->Get( n ); + + if( rOldFmt.GetAbsLSpace() != rNewFmt.GetAbsLSpace() || + rOldFmt.GetFirstLineOffset() != rNewFmt.GetFirstLineOffset() ) + nChgFmtLevel |= ( 1 << n ); + } + + SwNumRuleItem aRule( rNewRule ); + for( ; nFirst < nLast; ++nFirst ) + { + pTxtNd = aUpd.GetList().GetObject( nFirst ); + + aRegH.RegisterInModify( pTxtNd, *pTxtNd ); + +#ifndef NUM_RELSPACE + BYTE nLvl = !pTxtNd->GetNum() ? NO_NUMBERING + : pTxtNd->GetNum()->GetLevel() & ~NO_NUMLEVEL; + if( nLvl < MAXLEVEL && (nChgFmtLevel & ( 1 << nLvl )) && + pOldRule->IsRuleLSpace( *pTxtNd ) ) + pTxtNd->SetNumLSpace( TRUE ); +#endif + + pTxtNd->SwCntntNode::SetAttr( aRule ); + pTxtNd->NumRuleChgd(); + } + EndUndo( UNDO_END ); + SetModified(); + } + return bRet; +} + +BOOL SwDoc::NoNum( const SwPaM& rPam ) +{ +#if 0 +// Vielleich koennte man die Funktion auch so definieren: +// den Bereich auf nicht Nummeriert setzen - sprich NO_NUMLEVEL. +// + ULONG nStt = rPam.GetPoint()->nNode.GetIndex(), + nEnd = rPam.GetMark()->nNode.GetIndex(); + if( nStt > nEnd ) + { + ULONG nTmp = nStt; nStt = nEnd; nEnd = nTmp; + } + + const SfxPoolItem* pItem; + const String* pName; + String sNumRule; + for( ; nStt <= nEnd; ++nStt ) + { + SwTxtNode* pTNd = GetNodes()[ nStt ]->GetTxtNode(); + if( pTNd && 0 != ( pItem = pTNd->GetNoCondAttr( + RES_PARATR_NUMRULE, TRUE ) ) && + ( pName = &((SwNumRuleItem*)pItem)->GetValue())->Len() ) + { + SwNodeNum aNum; + if( pTNd->GetNum() ) + aNum = *pTNd->GetNum(); + aNum.SetLevel( aNum.GetLevel() | NO_NUMLEVEL ); + pTNd->UpdateNum( aNum ); + + if( *pName != sNumRule ) + { + sNumRule = *pName; + SwNumRule* pRule = FindNumRulePtr( *pName ); + pRule->SetInvalidRule( TRUE ); + } + } + } + + // dann noch alle Updaten + UpdateNumRule(); + + // irgendetwas wurde geupdatet + return 0 != n; +#else + + BOOL bRet = SplitNode( *rPam.GetPoint() ); + // ist ueberhaupt Nummerierung im Spiel ? + if( bRet ) + { + // NoNum setzen und Upaten + const SwNodeIndex& rIdx = rPam.GetPoint()->nNode; + SwTxtNode* pNd = rIdx.GetNode().GetTxtNode(); + const SwNodeNum* pNum = pNd->GetNum(); + const SwNumRule* pRule = pNd->GetNumRule(); + if( pNum && pRule ) + { + SwNodeNum aNum( *pNum ); + aNum.SetLevel( aNum.GetLevel() | NO_NUMLEVEL ); + pNd->UpdateNum( aNum ); +#ifndef NUM_RELSPACE + pNd->SetNumLSpace( TRUE ); +#endif + UpdateNumRule( pRule->GetName(), rIdx.GetIndex() ); + SetModified(); + } + else + bRet = FALSE; // keine Nummerierung , ?? oder immer TRUE ?? + } + return bRet; + +#endif +} + +BOOL SwDoc::DelNumRules( const SwPaM& rPam ) +{ + ULONG nStt = rPam.GetPoint()->nNode.GetIndex(), + nEnd = rPam.GetMark()->nNode.GetIndex(); + if( nStt > nEnd ) + { + ULONG nTmp = nStt; nStt = nEnd; nEnd = nTmp; + } + + SwUndoDelNum* pUndo; + if( DoesUndo() ) + { + ClearRedo(); + AppendUndo( pUndo = new SwUndoDelNum( rPam ) ); + } + else + pUndo = 0; + + SwRegHistory aRegH( pUndo ? pUndo->GetHistory() : 0 ); + + SwNumRuleItem aEmptyRule( aEmptyStr ); + SvxLRSpaceItem aLRSpace; + String sNumRule; + const SfxPoolItem* pItem; + const String* pName; + SwNumRule* pRule; + const SwNode* pOutlNd = 0; + for( ; nStt <= nEnd; ++nStt ) + { + SwTxtNode* pTNd = GetNodes()[ nStt ]->GetTxtNode(); + if( pTNd && 0 != ( pItem = pTNd->GetNoCondAttr( + RES_PARATR_NUMRULE, TRUE ) ) && + ( pName = &((SwNumRuleItem*)pItem)->GetValue())->Len() ) + { + if( *pName != sNumRule ) + { + sNumRule = *pName; + pRule = FindNumRulePtr( *pName ); + pRule->SetInvalidRule( TRUE ); + } + + // fuers Undo - Attribut Aenderungen merken + aRegH.RegisterInModify( pTNd, *pTNd ); + + BOOL bResetNumRule = FALSE; + const SwAttrSet* pAttrSet = pTNd->GetpSwAttrSet(); +#ifndef NUM_RELSPACE + BYTE nLvl; + const SvxLRSpaceItem* pLRSpace; + if( pAttrSet && SFX_ITEM_SET == pAttrSet->GetItemState( + RES_LR_SPACE, FALSE, (const SfxPoolItem**)&pLRSpace ) && + ( !pTNd->GetNum() || + (( nLvl = (~NO_NUMLEVEL & pTNd->GetNum()->GetLevel() )) < + MAXLEVEL && ( pRule->Get( nLvl ).GetAbsLSpace() + == pLRSpace->GetTxtLeft() )) )) + { + if( pLRSpace->GetRight() ) + { + aLRSpace.SetRight( pLRSpace->GetRight() ); + pTNd->SwCntntNode::SetAttr( aLRSpace ); + } + else + { + pTNd->SwCntntNode::ResetAttr( RES_LR_SPACE ); + pAttrSet = pTNd->GetpSwAttrSet(); + } + bResetNumRule = TRUE; + } +#endif + if( pUndo ) + pUndo->AddNode( *pTNd, bResetNumRule ); + + // kommt die Rule vom Node, dann Reseten, sonst auf leer setzen + if( pAttrSet && SFX_ITEM_SET == pAttrSet->GetItemState( + RES_PARATR_NUMRULE, FALSE )) + pTNd->SwCntntNode::ResetAttr( RES_PARATR_NUMRULE ); + else + pTNd->SwCntntNode::SetAttr( aEmptyRule ); + + pTNd->UpdateNum( SwNodeNum( NO_NUMBERING )); + + if( RES_CONDTXTFMTCOLL == pTNd->GetFmtColl()->Which() ) + pTNd->ChkCondColl(); + else if( !pOutlNd && NO_NUMBERING != + ((SwTxtFmtColl*)pTNd->GetFmtColl())->GetOutlineLevel() ) + pOutlNd = pTNd; + } + } + + // dann noch alle Updaten + UpdateNumRule(); + + if( pOutlNd ) + GetNodes().UpdtOutlineIdx( *pOutlNd ); + + // irgendetwas wurde geupdatet + return 0 != sNumRule.Len(); +} + + + // zum naechsten/vorhergehenden Punkt auf gleicher Ebene + +BOOL lcl_IsNumOk( BYTE nSrchNum, BYTE& rLower, BYTE& rUpper, + BOOL bOverUpper, BYTE nNumber ) +{ + register BOOL bRet = FALSE; + if( nNumber < MAXLEVEL ) // keine Nummerierung ueberspringen + { + if( bOverUpper ? nSrchNum == nNumber : nSrchNum >= nNumber ) + bRet = TRUE; + else if( nNumber > rLower ) + rLower = nNumber; + else if( nNumber < rUpper ) + rUpper = nNumber; + } + else if( nNumber & NO_NUMLEVEL ) + { + nNumber &= ~NO_NUMLEVEL; + if( bOverUpper ? FALSE : nSrchNum > nNumber ) + bRet = TRUE; + else if( nNumber > rLower ) + rLower = nNumber; + else if( nNumber < rUpper ) + rUpper = nNumber; + } + return bRet; +} + +BOOL lcl_IsValidPrevNextNumNode( const SwNodeIndex& rIdx ) +{ + BOOL bRet = FALSE; + const SwNode& rNd = rIdx.GetNode(); + switch( rNd.GetNodeType() ) + { + case ND_ENDNODE: + bRet = SwTableBoxStartNode == rNd.FindStartNode()->GetStartNodeType() || + rNd.FindStartNode()->IsSectionNode(); + break; + + case ND_STARTNODE: + bRet = SwTableBoxStartNode == ((SwStartNode&)rNd).GetStartNodeType(); + break; + + case ND_SECTIONNODE: // der ist erlaubt, also weiter + bRet = TRUE; + break; + } + return bRet; +} + +BOOL lcl_GotoNextPrevNum( SwPosition& rPos, BOOL bNext, + BOOL bOverUpper, BYTE* pUpper, BYTE* pLower ) +{ + const SwTxtNode* pNd = rPos.nNode.GetNode().GetTxtNode(); + const SwNumRule* pRule; + if( !pNd || 0 == ( pRule = pNd->GetNumRule() ) || !pNd->GetNum() ) + return FALSE; + + register BYTE nTmpNum = pNd->GetNum()->GetLevel(), + nSrchNum = nTmpNum & ~NO_NUMLEVEL; + + SwNodeIndex aIdx( rPos.nNode ); + if( nTmpNum & NO_NUMLEVEL ) + { + // falls gerade mal NO_NUMLEVEL an ist, so such den vorherigen Node + // mit Nummerierung + BOOL bError = FALSE; + do { + aIdx--; + if( aIdx.GetNode().IsTxtNode() ) + { + pNd = aIdx.GetNode().GetTxtNode(); + if( pNd->GetNum() && pRule == pNd->GetNumRule() ) + { + nTmpNum = pNd->GetNum()->GetLevel(); + if( !( nTmpNum & NO_NUMLEVEL && + (( nTmpNum & ~NO_NUMLEVEL ) >= nSrchNum )) ) + break; // gefunden + } + else + bError = TRUE; + } + else + bError = !lcl_IsValidPrevNextNumNode( aIdx ); + + } while( !bError ); + if( bError ) + return FALSE; + } + + BYTE nLower = nSrchNum, nUpper = nSrchNum; + BOOL bRet = FALSE; + + const SwTxtNode* pLast; + if( bNext ) + aIdx++, pLast = pNd; + else + aIdx--, pLast = 0; + + while( bNext ? ( aIdx.GetIndex() < aIdx.GetNodes().Count() - 1 ) + : aIdx.GetIndex() ) + { + if( aIdx.GetNode().IsTxtNode() ) + { + pNd = aIdx.GetNode().GetTxtNode(); + if( pNd->GetNum() && pRule == pNd->GetNumRule() ) + { + if( ::lcl_IsNumOk( nSrchNum, nLower, nUpper, bOverUpper, + pNd->GetNum()->GetLevel() )) + { + rPos.nNode = aIdx; + rPos.nContent.Assign( (SwTxtNode*)pNd, 0 ); + bRet = TRUE; + break; + } + else + pLast = pNd; + } + else + break; + } + else if( !lcl_IsValidPrevNextNumNode( aIdx )) + break; + + if( bNext ) + aIdx++; + else + aIdx--; + } + + if( !bRet && !bOverUpper && pLast ) // nicht ueber hoehere Nummmern, aber bis Ende + { + if( bNext ) + { + rPos.nNode = aIdx; + if( aIdx.GetNode().IsCntntNode() ) + rPos.nContent.Assign( aIdx.GetNode().GetCntntNode(), 0 ); + } + else + { + rPos.nNode.Assign( *pLast ); + rPos.nContent.Assign( (SwTxtNode*)pLast, 0 ); + } + bRet = TRUE; + } + + if( bRet ) + { + if( pUpper ) + *pUpper = nUpper; + if( pLower ) + *pLower = nLower; + } + return bRet; +} + +BOOL SwDoc::GotoNextNum( SwPosition& rPos, BOOL bOverUpper, + BYTE* pUpper, BYTE* pLower ) +{ + return ::lcl_GotoNextPrevNum( rPos, TRUE, bOverUpper, pUpper, pLower ); +} + + + +BOOL SwDoc::GotoPrevNum( SwPosition& rPos, BOOL bOverUpper, + BYTE* pUpper, BYTE* pLower ) +{ + return ::lcl_GotoNextPrevNum( rPos, FALSE, bOverUpper, pUpper, pLower ); +} + +BOOL SwDoc::NumUpDown( const SwPaM& rPam, BOOL bDown ) +{ + ULONG nStt = rPam.GetPoint()->nNode.GetIndex(), + nEnd = rPam.GetMark()->nNode.GetIndex(); + if( nStt > nEnd ) + { + ULONG nTmp = nStt; nStt = nEnd; nEnd = nTmp; + } + + char nDiff = bDown ? 1 : -1; + if( DoesUndo() ) + { + ClearRedo(); + AppendUndo( new SwUndoNumUpDown( rPam, nDiff ) ); + } + + BOOL bRet = FALSE; + String sNumRule; + const SfxPoolItem* pItem; + const String* pName; + for( ; nStt <= nEnd; ++nStt ) + { + SwTxtNode* pTNd = GetNodes()[ nStt ]->GetTxtNode(); + if( pTNd && 0 != ( pItem = pTNd->GetNoCondAttr( + RES_PARATR_NUMRULE, TRUE ) ) && + ( pName = &((SwNumRuleItem*)pItem)->GetValue())->Len() ) + { + BYTE nLevel = pTNd->GetNum()->GetLevel(); + if( ( -1 == nDiff && 0 < ( nLevel & ~NO_NUMLEVEL )) || + ( 1 == nDiff && MAXLEVEL - 1 > ( nLevel & ~NO_NUMLEVEL ) ) ) + { + nLevel += nDiff; + SwNodeNum aNum( *pTNd->GetNum() ); + aNum.SetLevel( nLevel ); + + pTNd->UpdateNum( aNum ); +#ifndef NUM_RELSPACE + pTNd->SetNumLSpace( TRUE ); +#endif + if( *pName != sNumRule ) + { + sNumRule = *pName; + SwNumRule* pRule = FindNumRulePtr( *pName ); + pRule->SetInvalidRule( TRUE ); + } + bRet = TRUE; + } + } + } + + if( bRet ) + { + UpdateNumRule(); + SetModified(); + } + return bRet; +} + +BOOL SwDoc::MoveParagraph( const SwPaM& rPam, long nOffset, BOOL bIsOutlMv ) +{ + const SwPosition *pStt = rPam.Start(), *pEnd = rPam.End(); + + ULONG nStIdx = pStt->nNode.GetIndex(); + ULONG nEndIdx = pEnd->nNode.GetIndex(); + ULONG nInStIdx, nInEndIdx; + long nOffs = nOffset; + if( nOffset > 0 ) + { + nInEndIdx = nEndIdx; + nEndIdx += nOffset; + ++nOffs; + } + else + { + nInEndIdx = nStIdx - 1; + nStIdx += nOffset; + } + nInStIdx = nInEndIdx + 1; + // Folgende Absatzbloecke sollen vertauscht werden: + // [ nStIdx, nInEndIdx ] mit [ nInStIdx, nEndIdx ] + + SwNode *pStartNd = GetNodes()[ nStIdx ]; + SwNode *pEndNd = GetNodes()[ nEndIdx ]; + if( !pStartNd->IsCntntNode() || !pEndNd->IsCntntNode() ) + return FALSE; + + pStartNd = pStartNd->FindStartNode(); + pEndNd = pEndNd->FindStartNode(); + // Es muss sich alles in einem Bereich abspielen + if( pStartNd != pEndNd ) + return FALSE; + + // auf Redlining testen - darf die Selektion ueberhaupt verschoben + // werden? + if( !IsIgnoreRedline() ) + { + USHORT nRedlPos = GetRedlinePos( pStt->nNode.GetNode(), REDLINE_DELETE ); + if( USHRT_MAX != nRedlPos ) + { + SwPosition aStPos( *pStt ), aEndPos( *pEnd ); + aStPos.nContent = 0; + SwCntntNode* pCNd = pEnd->nNode.GetNode().GetCntntNode(); + aEndPos.nContent = pCNd ? pCNd->Len() : 1; + BOOL bCheckDel = TRUE; + + // es existiert fuer den Bereich irgendein Redline-Delete-Object + for( ; nRedlPos < GetRedlineTbl().Count(); ++nRedlPos ) + { + const SwRedline* pTmp = GetRedlineTbl()[ nRedlPos ]; + if( !bCheckDel || REDLINE_DELETE == pTmp->GetType() ) + { + const SwPosition *pRStt = pTmp->Start(), *pREnd = pTmp->End(); + switch( ComparePosition( *pRStt, *pREnd, aStPos, aEndPos )) + { + case POS_BEHIND: // Pos1 liegt hinter Pos2 + nRedlPos = GetRedlineTbl().Count(); + break; + + case POS_BEFORE: // Pos1 liegt vor Pos2 + break; + case POS_INSIDE: // Pos1 liegt vollstaendig in Pos2 + // ist erlaubt, aber checke dann alle nachfolgenden + // auf Ueberlappungen + bCheckDel = FALSE; + break; + + case POS_OUTSIDE: // Pos2 liegt vollstaendig in Pos1 + case POS_EQUAL: // Pos1 ist genauso gross wie Pos2 + case POS_OVERLAP_BEFORE: // Pos1 ueberlappt Pos2 am Anfang + case POS_OVERLAP_BEHIND: // Pos1 ueberlappt Pos2 am Ende + return FALSE; + } + } + } + } + } + + { + // DataChanged vorm verschieben verschicken, dann bekommt + // man noch mit, welche Objecte sich im Bereich befinden. + // Danach koennen sie vor/hinter der Position befinden. + SwDataChanged aTmp( rPam, 0 ); + } + + SwNodeIndex aIdx( nOffset > 0 ? pEnd->nNode : pStt->nNode, nOffs ); + SwNodeRange aMvRg( pStt->nNode, 0, pEnd->nNode, +1 ); + + SwRedline* pOwnRedl = 0; + if( IsRedlineOn() ) + { + // wenn der Bereich komplett im eigenen Redline liegt, kann es + // verschoben werden! + USHORT nRedlPos = GetRedlinePos( pStt->nNode.GetNode(), REDLINE_INSERT ); + if( USHRT_MAX != nRedlPos ) + { + SwRedline* pTmp = GetRedlineTbl()[ nRedlPos ]; + const SwPosition *pRStt = pTmp->Start(), *pREnd = pTmp->End(); + SwRedline aTmpRedl( REDLINE_INSERT, rPam ); + const SwCntntNode* pCEndNd = pEnd->nNode.GetNode().GetCntntNode(); + // liegt komplett im Bereich, und ist auch der eigene Redline? + if( aTmpRedl.IsOwnRedline( *pTmp ) && + (pRStt->nNode < pStt->nNode || + (pRStt->nNode == pStt->nNode && !pRStt->nContent.GetIndex()) ) && + (pEnd->nNode < pREnd->nNode || + (pEnd->nNode == pREnd->nNode && + pCEndNd ? pREnd->nContent.GetIndex() == pCEndNd->Len() + : !pREnd->nContent.GetIndex() )) ) + { + pOwnRedl = pTmp; + if( nRedlPos + 1 < GetRedlineTbl().Count() ) + { + pTmp = GetRedlineTbl()[ nRedlPos+1 ]; + if( *pTmp->Start() == *pREnd ) + // dann doch nicht! + pOwnRedl = 0; + } + + if( pOwnRedl && + !( pRStt->nNode <= aIdx && aIdx <= pREnd->nNode )) + { + // nicht in sich selbst, dann auch nicht moven + pOwnRedl = 0; + } + } + } + + if( !pOwnRedl ) + { + StartUndo( UNDO_START ); + + // zuerst das Insert, dann das Loeschen + SwPosition aInsPos( aIdx ); + aInsPos.nContent.Assign( aIdx.GetNode().GetCntntNode(), 0 ); + + SwPaM aPam( pStt->nNode, aMvRg.aEnd ); + + SwPaM& rOrigPam = (SwPaM&)rPam; + rOrigPam.DeleteMark(); + rOrigPam.GetPoint()->nNode = aIdx.GetIndex() - 1; + + BOOL bDelLastPara = !aInsPos.nNode.GetNode().IsCntntNode(); + + Copy( aPam, aInsPos ); + if( bDelLastPara ) + { + // dann muss der letzte leere Node wieder entfernt werden + aIdx = aInsPos.nNode; + SwCntntNode* pCNd = GetNodes().GoPrevious( &aInsPos.nNode ); + xub_StrLen nCLen = 0; if( pCNd ) nCLen = pCNd->Len(); + aInsPos.nContent.Assign( pCNd, nCLen ); + + // alle die im zu loeschenden Node stehen, mussen auf den + // naechsten umgestezt werden + SwPosition* pPos; + for( USHORT n = 0; n < GetRedlineTbl().Count(); ++n ) + { + SwRedline* pTmp = GetRedlineTbl()[ n ]; + if( ( pPos = &pTmp->GetBound(TRUE))->nNode == aIdx ) + { + pPos->nNode++; + pPos->nContent.Assign( pPos->nNode.GetNode().GetCntntNode(),0); + } + if( ( pPos = &pTmp->GetBound(FALSE))->nNode == aIdx ) + { + pPos->nNode++; + pPos->nContent.Assign( pPos->nNode.GetNode().GetCntntNode(),0); + } + } + CorrRel( aIdx, aInsPos, 0, FALSE ); + + pCNd->JoinNext(); + } + + rOrigPam.GetPoint()->nNode++; + rOrigPam.GetPoint()->nContent.Assign( rOrigPam.GetCntntNode(), 0 ); + + SwRedlineMode eOld = GetRedlineMode(); + if( DoesUndo() ) + { +//JP 06.01.98: MUSS noch optimiert werden!!! +SetRedlineMode( REDLINE_ON | REDLINE_SHOW_INSERT | REDLINE_SHOW_DELETE ); + AppendUndo( new SwUndoRedlineDelete( aPam, UNDO_DELETE )); + } + AppendRedline( new SwRedline( REDLINE_DELETE, aPam )); + +//JP 06.01.98: MUSS noch optimiert werden!!! +SetRedlineMode( eOld ); + EndUndo( UNDO_END ); + SetModified(); + return TRUE; + } + } + + if( !pOwnRedl && !IsIgnoreRedline() && GetRedlineTbl().Count() ) + { + SplitRedline( SwPaM( aIdx )); + } + + ULONG nRedlSttNd, nRedlEndNd; + if( pOwnRedl ) + { + const SwPosition *pRStt = pOwnRedl->Start(), *pREnd = pOwnRedl->End(); + nRedlSttNd = pRStt->nNode.GetIndex(); + nRedlEndNd = pREnd->nNode.GetIndex(); + } + + SwUndoMoveNum* pUndo = 0; + if( DoesUndo() ) + pUndo = new SwUndoMoveNum( rPam, nOffset, bIsOutlMv ); + + + Move( aMvRg, aIdx, DOC_MOVEREDLINES ); + + if( pUndo ) + { + ClearRedo(); + pUndo->SetStartNode( rPam.Start()->nNode.GetIndex() ); + AppendUndo( pUndo ); + } + + if( pOwnRedl ) + { + SwPosition *pRStt = pOwnRedl->Start(), *pREnd = pOwnRedl->End(); + if( pRStt->nNode.GetIndex() != nRedlSttNd ) + { + pRStt->nNode = nRedlSttNd; + pRStt->nContent.Assign( pRStt->nNode.GetNode().GetCntntNode(),0); + } + if( pREnd->nNode.GetIndex() != nRedlEndNd ) + { + pREnd->nNode = nRedlEndNd; + SwCntntNode* pCNd = pREnd->nNode.GetNode().GetCntntNode(); + xub_StrLen nL = 0; if( pCNd ) nL = pCNd->Len(); + pREnd->nContent.Assign( pCNd, nL ); + } + } + + SetModified(); + return TRUE; +} + +BOOL SwDoc::NumOrNoNum( const SwNodeIndex& rIdx, BOOL bDel, BOOL bOutline ) +{ + BOOL bRet = FALSE; + const SwNodeNum* pNum; + const SfxPoolItem* pItem; + const SwNumRule* pRule; + SwTxtNode* pTNd = rIdx.GetNode().GetTxtNode(); + + if( pTNd && + ( bOutline + ? (NO_NUMBERING != pTNd->GetTxtColl()->GetOutlineLevel() && + 0 != ( pNum = pTNd->GetOutlineNum()) && + 0 != ( pRule = GetOutlineNumRule()) ) + : ( 0 != (pItem = pTNd->GetNoCondAttr(RES_PARATR_NUMRULE,TRUE)) && + ((SwNumRuleItem*)pItem)->GetValue().Len() && + 0 != ( pNum = pTNd->GetNum()) && + 0 != ( pRule = FindNumRulePtr( + ((SwNumRuleItem*)pItem)->GetValue() )) )) && + (bDel ? 0 != ( pNum->GetLevel() & NO_NUMLEVEL ) + : 0 == ( pNum->GetLevel() & NO_NUMLEVEL ) ) && + SVX_NUM_NUMBER_NONE != pRule->Get( GetRealLevel(pNum->GetLevel()) ).eType ) + { + if( DoesUndo() ) + { + ClearRedo(); + AppendUndo( new SwUndoNumOrNoNum( rIdx, bDel, bOutline ) ); + } + SwNodeNum aNum( *pNum ); + if( bDel ) + aNum.SetLevel( aNum.GetLevel() & ~NO_NUMLEVEL ); + else + aNum.SetLevel( aNum.GetLevel() | NO_NUMLEVEL ); + + if( bOutline ) + { + pTNd->UpdateOutlineNum( aNum ); + GetNodes().UpdtOutlineIdx( *pTNd ); + } + else + { + pTNd->UpdateNum( aNum ); +#ifndef NUM_RELSPACE + pTNd->SetNumLSpace( TRUE ); +#endif + ((SwNumRule*)pRule)->SetInvalidRule( TRUE ); + UpdateNumRule( pRule->GetName(), rIdx.GetIndex() ); + } + bRet = TRUE; + SetModified(); + } + return bRet; +} + +SwNumRule* SwDoc::GetCurrNumRule( const SwPosition& rPos ) const +{ + SwNumRule* pRet = 0; + const SfxPoolItem* pItem; + SwTxtNode* pTNd = rPos.nNode.GetNode().GetTxtNode(); + + if( pTNd && 0 != ( pItem = pTNd->GetNoCondAttr( RES_PARATR_NUMRULE, TRUE ) ) && + ((SwNumRuleItem*)pItem)->GetValue().Len() ) + pRet = FindNumRulePtr( ((SwNumRuleItem*)pItem)->GetValue() ); + return pRet; +} + +USHORT SwDoc::FindNumRule( const String& rName ) const +{ + for( USHORT n = pNumRuleTbl->Count(); n; ) + if( (*pNumRuleTbl)[ --n ]->GetName() == rName ) + return n; +/* +//JP 20.11.97: sollte man im Find neue Rule anlegen?? + erstmal nicht + USHORT nPoolId = GetPoolId( rName, GET_POOLID_NUMRULE ); + if( USHRT_MAX != nPoolId ) + { + SwDoc* pThis = (SwDoc*)this; + SwNumRule* pR = pThis->GetNumRuleFromPool( nPoolId ); + for( n = pNumRuleTbl->Count(); n; ) + if( (*pNumRuleTbl)[ --n ] == pR ) + return n; + } +*/ + return USHRT_MAX; +} + +SwNumRule* SwDoc::FindNumRulePtr( const String& rName ) const +{ + for( USHORT n = pNumRuleTbl->Count(); n; ) + if( (*pNumRuleTbl)[ --n ]->GetName() == rName ) + return (*pNumRuleTbl)[ n ]; + +/* +//JP 20.11.97: sollte man im Find neue Rule anlegen?? + erstmal nicht + USHORT nPoolId = GetPoolId( rName, GET_POOLID_NUMRULE ); + if( USHRT_MAX != nPoolId ) + { + SwDoc* pThis = (SwDoc*)this; + return pThis->GetNumRuleFromPool( nPoolId ); + } +*/ + return 0; +} + +USHORT SwDoc::MakeNumRule( const String &rName, const SwNumRule* pCpy ) +{ + SwNumRule* pNew; + if( pCpy ) + { + pNew = new SwNumRule( *pCpy ); + pNew->SetName( GetUniqueNumRuleName( &rName )); + if( pNew->GetName() != rName ) + { + pNew->SetPoolFmtId( USHRT_MAX ); + pNew->SetPoolHelpId( USHRT_MAX ); + pNew->SetPoolHlpFileId( UCHAR_MAX ); + } + pNew->CheckCharFmts( this ); + } + else + pNew = new SwNumRule( GetUniqueNumRuleName( &rName ) ); + USHORT nRet = pNumRuleTbl->Count(); + pNumRuleTbl->Insert( pNew, nRet ); + return nRet; +} + +String SwDoc::GetUniqueNumRuleName( const String* pChkStr, BOOL bAutoNum ) const +{ + String aName; + if( bAutoNum ) + { + long n = Time().GetTime(); + n += Date().GetDate(); + aName = String::CreateFromInt32( n ); + if( pChkStr && !pChkStr->Len() ) + pChkStr = 0; + } + else if( pChkStr && pChkStr->Len() ) + aName = *pChkStr; + else + { + pChkStr = 0; + aName = SW_RESSTR( STR_NUMRULE_DEFNAME ); + } + + USHORT nNum, nTmp, nFlagSize = ( pNumRuleTbl->Count() / 8 ) +2; + BYTE* pSetFlags = new BYTE[ nFlagSize ]; + memset( pSetFlags, 0, nFlagSize ); + + xub_StrLen nNmLen = aName.Len(); + if( !bAutoNum && pChkStr ) + { + while( nNmLen-- && '0' <= aName.GetChar( nNmLen ) && + '9' >= aName.GetChar( nNmLen ) ) + ; //nop + + if( ++nNmLen < aName.Len() ) + { + aName.Erase( nNmLen ); + pChkStr = 0; + } + } + + const SwNumRule* pNumRule; + for( USHORT n = 0; n < pNumRuleTbl->Count(); ++n ) + if( 0 != ( pNumRule = (*pNumRuleTbl)[ n ] ) ) + { + const String& rNm = pNumRule->GetName(); + if( rNm.Match( aName ) == nNmLen ) + { + // Nummer bestimmen und das Flag setzen + nNum = rNm.Copy( nNmLen ).ToInt32(); + if( nNum-- && nNum < pNumRuleTbl->Count() ) + pSetFlags[ nNum / 8 ] |= (0x01 << ( nNum & 0x07 )); + } + if( pChkStr && pChkStr->Equals( rNm ) ) + pChkStr = 0; + } + + if( !pChkStr ) + { + // alle Nummern entsprechend geflag, also bestimme die richtige Nummer + nNum = pNumRuleTbl->Count(); + for( n = 0; n < nFlagSize; ++n ) + if( 0xff != ( nTmp = pSetFlags[ n ] )) + { + // also die Nummer bestimmen + nNum = n * 8; + while( nTmp & 1 ) + ++nNum, nTmp >>= 1; + break; + } + + } + __DELETE( nFlagSize ) pSetFlags; + if( pChkStr && pChkStr->Len() ) + return *pChkStr; + return aName += String::CreateFromInt32( ++nNum ); +} + +const SwNode* lcl_FindBaseNode( const SwNode& rNd ) +{ + const SwNodes& rNds = rNd.GetNodes(); + ULONG nNdIdx = rNd.GetIndex(); + if( nNdIdx > rNds.GetEndOfExtras().GetIndex() ) + return rNds.GetEndOfContent().FindStartNode(); + + const SwNode* pSttNd = rNds[ ULONG(0) ]->FindStartNode(); + const SwNode* pNd = rNd.FindStartNode(); + while( pSttNd != pNd->FindStartNode()->FindStartNode() ) + pNd = pNd->FindStartNode(); + return pNd; +} + + +void SwDoc::UpdateNumRule() +{ + SwNumRuleTbl& rNmTbl = GetNumRuleTbl(); + for( USHORT n = 0; n < rNmTbl.Count(); ++n ) + if( rNmTbl[ n ]->IsInvalidRule() ) + UpdateNumRule( rNmTbl[ n ]->GetName(), ULONG_MAX ); +} + +void SwDoc::UpdateNumRule( const String& rName, ULONG nUpdPos ) +{ + SwNumRuleInfo aUpd( rName ); + aUpd.MakeList( *this ); + + if( ULONG_MAX == nUpdPos ) + nUpdPos = 0; + else + aUpd.GetList().SearchKey( nUpdPos, &nUpdPos ); + + SwNumRule* pRule = FindNumRulePtr( rName ); + if( nUpdPos < aUpd.GetList().Count() ) + { + USHORT nInitLevels = USHRT_MAX; // Bitfeld fuer die Levels! + // TRUE: starte mit NumFmt Start + USHORT nNumVal = 0; + SwNodeNum aNum( 0 ); + + if( pRule->IsContinusNum() ) + nNumVal = pRule->Get( 0 ).GetStartValue(); + + SwTxtNode* pStt = aUpd.GetList().GetObject( nUpdPos ); + SwTxtNode* pPrev = nUpdPos ? aUpd.GetList().GetObject( nUpdPos-1 ) : 0; + const SwNode* pBaseNd = lcl_FindBaseNode( *pStt ); + if( pPrev && lcl_FindBaseNode( *pPrev ) == pBaseNd ) + { + if( pPrev->GetNum() ) + { + const SwNodeNum* pPrevNdNum = pPrev->GetNum(); + if( pPrevNdNum->GetLevel() & NO_NUMLEVEL ) + { + BYTE nSrchLvl = GetRealLevel( pPrevNdNum->GetLevel() ); + pPrevNdNum = 0; + ULONG nArrPos = nUpdPos-1; + while( nArrPos-- ) + { + pPrev = aUpd.GetList().GetObject( nArrPos ); + if( lcl_FindBaseNode( *pPrev ) != pBaseNd ) + break; + + if( 0 != ( pPrevNdNum = pPrev->GetNum() )) + { + // uebergeordnete Ebene + if( nSrchLvl > (pPrevNdNum->GetLevel() &~ NO_NUMLEVEL)) + { + pPrevNdNum = 0; + break; + } + // gleiche Ebene und kein NO_NUMLEVEL + if( nSrchLvl == (pPrevNdNum->GetLevel() &~ NO_NUMLEVEL) + && !( pPrevNdNum->GetLevel() & NO_NUMLEVEL )) + break; + + pPrevNdNum = 0; + } + } + } + + if( pPrevNdNum ) + { + aNum = *pPrevNdNum; + aNum.SetStart( FALSE ); + aNum.SetSetValue( USHRT_MAX ); + } + } + nInitLevels = 0; + nNumVal = aNum.GetLevelVal()[ GetRealLevel( aNum.GetLevel() ) ]; + } + + const SwNode* pOutlNd = 0; + for( ; nUpdPos < aUpd.GetList().Count(); ++nUpdPos ) + { + pStt = aUpd.GetList().GetObject( nUpdPos ); + + const SwNode* pTmpBaseNd = lcl_FindBaseNode( *pStt ); + if( pTmpBaseNd != pBaseNd ) + { + aNum.SetLevel( 0 ); + memset( aNum.GetLevelVal(), 0, + (MAXLEVEL) * sizeof( aNum.GetLevelVal()[0]) ); + pBaseNd = pTmpBaseNd; + } + + BYTE nLevel = aNum.GetLevel(); + BYTE nNdOldLvl = MAXLEVEL; + if( pStt->GetNum() ) + { + if( NO_NUMBERING != pStt->GetNum()->GetLevel() ) + nNdOldLvl = nLevel = pStt->GetNum()->GetLevel(); + if( pStt->GetNum()->IsStart() ) + { + aNum.SetStart( TRUE ); + memset( aNum.GetLevelVal(), 0, + (MAXLEVEL) * sizeof( aNum.GetLevelVal()[0]) ); + if( pRule->IsContinusNum() ) + { + nNumVal = pRule->Get( 0 ).GetStartValue(); + nInitLevels |= 1; + } + else + nInitLevels |= ( 1 << GetRealLevel( nLevel )); + } + else if( USHRT_MAX != pStt->GetNum()->GetSetValue() ) + aNum.SetSetValue( nNumVal = pStt->GetNum()->GetSetValue() ); + } + + if( NO_NUMLEVEL & nLevel ) // NoNum mit Ebene + { + BYTE nPrevLvl = GetRealLevel( aNum.GetLevel() ), + nCurrLvl = GetRealLevel( nLevel ); + + if( nPrevLvl < nCurrLvl ) + { + if( !(nInitLevels & ( 1 << nPrevLvl )) ) + ++nPrevLvl; + for( ; nPrevLvl < nCurrLvl; ++nPrevLvl ) + nInitLevels |= ( 1 << nPrevLvl ); + } + + aNum.SetLevel( nLevel ); + pStt->UpdateNum( aNum ); + } + else if( NO_NUM != nLevel ) + { + // beim Format mit Bitmap die Graphicen schon mal anfordern + const SwNumFmt* pNumFmt = pRule->GetNumFmt( GetRealLevel( nLevel )); + if( pNumFmt && SVX_NUM_BITMAP == pNumFmt->eType ) + pNumFmt->GetGraphic(); + + if( pRule->IsContinusNum() ) + { + if( !(nInitLevels & 1) && + !( pNumFmt && (SVX_NUM_CHAR_SPECIAL == pNumFmt->eType || + SVX_NUM_BITMAP == pNumFmt->eType || + SVX_NUM_NUMBER_NONE == pNumFmt->eType ))) + ++nNumVal; + aNum.GetLevelVal()[ nLevel ] = nNumVal; + } + else + { + BYTE nPrevLvl = GetRealLevel( aNum.GetLevel() ); + if( nPrevLvl < nLevel ) + { + // Erfrage wie geloescht werden soll: + // z.B von Stufe 0 -> 1: 1 -> 0.1 ; wenn nStart = 1 + // aber Stufe 1 -> 2: 1.1 -> 1.1.1 !!, nur 0.1 -> 0.0.1 + if( !(nInitLevels & ( 1 << nPrevLvl )) ) + ++nPrevLvl; + + for( int ii = nPrevLvl; ii < nLevel; ++ii ) + { + nInitLevels &= ~( 1 << ii ); + aNum.GetLevelVal()[ ii ] = + pRule->Get( ii ).GetStartValue(); + } + aNum.GetLevelVal()[ nLevel ] = + USHRT_MAX == aNum.GetSetValue() + ? pRule->Get( nLevel ).GetStartValue() + : aNum.GetSetValue(); + } + else if( USHRT_MAX != aNum.GetSetValue() ) + aNum.GetLevelVal()[ nLevel ] = aNum.GetSetValue(); + else if( nInitLevels & ( 1 << nLevel )) + aNum.GetLevelVal()[ nLevel ] = + pRule->Get( nLevel ).GetStartValue(); + else + aNum.GetLevelVal()[ nLevel ]++; + } + nInitLevels &= ~( 1 << nLevel ); + aNum.SetLevel( nLevel ); + + pStt->UpdateNum( aNum ); + } + +//FEATURE::CONDCOLL + BOOL bCheck = TRUE; + if( RES_CONDTXTFMTCOLL == pStt->GetFmtColl()->Which() ) + { +// SwFmtColl* pChgColl = pStt->GetCondFmtColl(); + pStt->ChkCondColl(); +/* +//JP 19.11.97: +// setzen der bedingten Vorlage aendert nichts an den Einzuegen, die bleiben +// als harte vorhanden + if( pStt->GetCondFmtColl() ) + { + // es gab eine Aenderung -> harte Einzuege entfernen + if( pChgColl != pStt->GetCondFmtColl() ) + pStt->ResetAttr( RES_LR_SPACE ); + bCheck = FALSE; + } +*/ + } + else if( !pOutlNd && NO_NUMBERING != + ((SwTxtFmtColl*)pStt->GetFmtColl())->GetOutlineLevel() ) + pOutlNd = pStt; + +//FEATURE::CONDCOLL + +#ifndef NUM_RELSPACE + // hat sich eine Level - Aenderung ergeben, so setze jetzt die + // gueltigen Einzuege + if( bCheck && ( nLevel != nNdOldLvl || pStt->IsSetNumLSpace()) + && GetRealLevel( nLevel ) < MAXLEVEL ) + { + SvxLRSpaceItem aLR( ((SvxLRSpaceItem&)pStt->SwCntntNode::GetAttr( + RES_LR_SPACE )) ); + + const SwNumFmt& rNFmt = pRule->Get( GetRealLevel( nLevel )); + + // ohne Nummer immer ohne FirstLineOffset!!!! + short nFOfst = rNFmt.GetFirstLineOffset(); + if( nLevel & NO_NUMLEVEL ) nFOfst = 0; + aLR.SetTxtFirstLineOfstValue( nFOfst ); + aLR.SetTxtLeft( rNFmt.GetAbsLSpace() ); + + pStt->SwCntntNode::SetAttr( aLR ); + } + // Flag immer loeschen! + pStt->SetNumLSpace( FALSE ); +#endif + aNum.SetStart( FALSE ); + aNum.SetSetValue( USHRT_MAX ); + } + if( pOutlNd ) + GetNodes().UpdtOutlineIdx( *pOutlNd ); + } + + ASSERT( pRule, "die NumRule sollte schon vorhanden sein!" ); + if( pRule ) + pRule->SetInvalidRule( FALSE ); +} + + + diff --git a/sw/source/core/doc/docredln.cxx b/sw/source/core/doc/docredln.cxx new file mode 100644 index 000000000000..a1b1583d0930 --- /dev/null +++ b/sw/source/core/doc/docredln.cxx @@ -0,0 +1,3218 @@ +/************************************************************************* + * + * $RCSfile: docredln.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:15 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _HINTIDS_HXX +#include +#endif + +#ifndef _SHL_HXX +#include +#endif +#ifndef _SFXINIMGR_HXX //autogen +#include +#endif +#ifndef _SFXAPP_HXX //autogen +#include +#endif +#ifndef _SVX_COLRITEM_HXX //autogen +#include +#endif +#ifndef _SVX_UDLNITEM_HXX //autogen +#include +#endif +#ifndef _SVX_CRSDITEM_HXX //autogen +#include +#endif +#ifndef _SWMODULE_HXX +#include +#endif +#ifndef _DOC_HXX +#include +#endif +#ifndef _DOCARY_HXX +#include +#endif +#ifndef _NDARR_HXX +#include +#endif +#ifndef _NDTXT_HXX +#include +#endif +#ifndef _REDLINE_HXX +#include +#endif +#ifndef _SWUNDO_HXX +#include +#endif +#ifndef _UNDOBJ_HXX +#include +#endif +#ifndef _HINTS_HXX +#include +#endif +#ifndef _PAMTYP_HXX +#include +#endif +#ifndef _POOLFMT_HXX +#include +#endif +#ifndef _VIEWSH_HXX +#include +#endif +#ifndef _ROOTFRM_HXX +#include +#endif + +#ifdef PRODUCT + + #define _CHECK_REDLINE( pDoc ) + +#else + + void lcl_CheckRedline( const SwDoc* pDoc ) + { + const SwRedlineTbl& rTbl = pDoc->GetRedlineTbl(); + for( USHORT n = 1; n < rTbl.Count(); ++n ) + { + const SwRedline* pPrev = rTbl[ n-1 ], *pCur = rTbl[ n ]; + if( *pPrev->Start() > *pCur->Start() ) + { + ASSERT( pDoc, "falche Reihenfolge" ); + } + } + } + + #define _CHECK_REDLINE( pDoc ) lcl_CheckRedline( pDoc ); + +#endif + +SV_IMPL_OP_PTRARR_SORT( _SwRedlineTbl, SwRedlinePtr ) + +void SwDoc::SetRedlineMode( USHORT eMode ) +{ + if( eRedlineMode != eMode ) + { + if( (REDLINE_SHOW_MASK & eRedlineMode) != (REDLINE_SHOW_MASK & eMode) + || 0 == (REDLINE_SHOW_MASK & eMode) ) + { + // und dann alles verstecken, anzeigen + void (SwRedline::*pFnc)( USHORT ) = 0; + + switch( REDLINE_SHOW_MASK & eMode ) + { + case REDLINE_SHOW_INSERT | REDLINE_SHOW_DELETE: + pFnc = &SwRedline::Show; + break; + case REDLINE_SHOW_INSERT: + pFnc = &SwRedline::Hide; + break; + case REDLINE_SHOW_DELETE: + pFnc = &SwRedline::ShowOriginal; + break; + + default: + pFnc = &SwRedline::Hide; + eMode |= REDLINE_SHOW_INSERT; + break; + } + + _CHECK_REDLINE( this ) + + if( pFnc ) + for( USHORT nLoop = 1; nLoop <= 2; ++nLoop ) + for( USHORT i = 0; i < pRedlineTbl->Count(); ++i ) + ((*pRedlineTbl)[ i ]->*pFnc)( nLoop ); + _CHECK_REDLINE( this ) + } + eRedlineMode = (SwRedlineMode)eMode; + } +} + +inline BOOL IsPrevPos( const SwPosition rPos1, const SwPosition rPos2 ) +{ + const SwCntntNode* pCNd; + return !rPos2.nContent.GetIndex() && + rPos2.nNode.GetIndex() - 1 == rPos1.nNode.GetIndex() && + 0 != ( pCNd = rPos1.nNode.GetNode().GetCntntNode() ) + ? rPos1.nContent.GetIndex() == pCNd->Len() + : 0; +} + +/* + +Text heisst, nicht von Redline "verseuchter" Text. + +Verhalten von Insert-Redline: + - im Text - Redline Object einfuegen + - im InsertRedline (eigenes) - ignorieren, bestehendes wird + aufgespannt + - im InsertRedline (andere) - Insert Redline aufsplitten + Redline Object einfuegen + - in DeleteRedline - Delete Redline aufsplitten oder + am Ende/Anfang verschieben + +Verhalten von Delete-Redline: + - im Text - Redline Object einfuegen + - im DeleteRedline (eigenes/andere) - ignorieren + - im InsertRedline (eigenes) - ignorieren, Zeichen aber loeschen + - im InsertRedline (andere) - Insert Redline aufsplitten + Redline Object einfuegen + - Ueberlappung von Text und - Text in eigenen Insert loeschen, + eigenem Insert im andereren Text aufspannen (bis + zum Insert! + - Ueberlappung von Text und - Redline Object einfuegen, der + anderem Insert andere Insert wird vom Delete + ueberlappt +*/ + +BOOL SwDoc::AppendRedline( SwRedline* pNewRedl, BOOL bCallDelete ) +{ + _CHECK_REDLINE( this ) + + if( IsRedlineOn() && !IsShowOriginal( eRedlineMode ) && + pNewRedl->GetAuthorString().Len() ) + { + pNewRedl->InvalidateRange(); + + if( bIsAutoFmtRedline ) + { + pNewRedl->SetAutoFmtFlag(); + if( pAutoFmtRedlnComment && pAutoFmtRedlnComment->Len() ) + { + pNewRedl->SetComment( *pAutoFmtRedlnComment ); + pNewRedl->SetSeqNo( nAutoFmtRedlnCommentNo ); + } + } + + BOOL bCompress = FALSE; + SwPosition* pStt = pNewRedl->Start(), + * pEnd = pStt == pNewRedl->GetPoint() ? pNewRedl->GetMark() + : pNewRedl->GetPoint(); + USHORT n = 0; + // zur StartPos das erste Redline suchen + if( !GetRedline( *pStt, &n ) && n ) + --n; + + for( ; pNewRedl && n < pRedlineTbl->Count(); ++n ) + { + SwRedline* pRedl = (*pRedlineTbl)[ n ]; + SwPosition* pRStt = pRedl->Start(), + * pREnd = pRStt == pRedl->GetPoint() ? pRedl->GetMark() + : pRedl->GetPoint(); + + SwComparePosition eCmpPos = ComparePosition( *pStt, *pEnd, *pRStt, *pREnd ); + + switch( pNewRedl->GetType() ) + { + case REDLINE_INSERT: + switch( pRedl->GetType() ) + { + case REDLINE_INSERT: + if( pRedl->IsOwnRedline( *pNewRedl ) ) + { + // ggfs. verschmelzen? + if( POS_BEHIND == eCmpPos && + pRedl->CanCombine( *pNewRedl ) && + ( *pStt == *pREnd || + IsPrevPos( *pREnd, *pStt )) && + ( n+1 >= pRedlineTbl->Count() || + *(*pRedlineTbl)[ n+1 ]->Start() != *pREnd )) + { + pRedl->SetEnd( *pEnd, pREnd ); + if( !pRedl->HasValidRange() ) + { + // neu einsortieren + pRedlineTbl->Remove( n ); + pRedlineTbl->Insert( pRedl ); + } + } + else if( POS_BEFORE == eCmpPos && + pRedl->CanCombine( *pNewRedl ) && + ( *pEnd == *pRStt || + IsPrevPos( *pEnd, *pRStt )) && + ( !n || + *(*pRedlineTbl)[ n-1 ]->End() != *pRStt )) + { + pRedl->SetStart( *pStt, pRStt ); + // neu einsortieren + pRedlineTbl->Remove( n ); + pRedlineTbl->Insert( pRedl ); + } + else if( POS_INSIDE != eCmpPos && POS_EQUAL != eCmpPos) + break; + + delete pNewRedl, pNewRedl = 0; + bCompress = TRUE; + } + else if( POS_INSIDE == eCmpPos ) + { + // aufsplitten + if( *pEnd != *pREnd ) + { + SwRedline* pCpy = new SwRedline( *pRedl ); + pCpy->SetStart( *pEnd ); + pRedlineTbl->Insert( pCpy ); + } + pRedl->SetEnd( *pStt, pREnd ); + if( !pRedl->HasValidRange() ) + { + // neu einsortieren + pRedlineTbl->Remove( n ); + pRedlineTbl->Insert( pRedl ); + } + } + break; + case REDLINE_DELETE: + if( POS_INSIDE == eCmpPos ) + { + // aufsplitten + SwRedline* pCpy = new SwRedline( *pRedl ); + pCpy->SetStart( *pEnd ); + pRedlineTbl->Insert( pCpy ); + pRedl->SetEnd( *pStt, pREnd ); + if( !pRedl->HasValidRange() ) + { + // neu einsortieren + pRedlineTbl->Remove( n ); + pRedlineTbl->Insert( pRedl, n ); + } + } + break; + case REDLINE_FORMAT: + switch( eCmpPos ) + { + case POS_OVERLAP_BEFORE: + pRedl->SetStart( *pEnd, pRStt ); + // neu einsortieren + pRedlineTbl->Remove( n ); + pRedlineTbl->Insert( pRedl, n ); + break; + + case POS_OVERLAP_BEHIND: + pRedl->SetEnd( *pStt, pREnd ); + break; + + case POS_EQUAL: + case POS_OUTSIDE: + // ueberlappt den akt. komplett oder hat gleiche + // Ausdehung, dann muss der alte geloescht werden + pRedlineTbl->DeleteAndDestroy( n-- ); + break; + + case POS_INSIDE: + // ueberlappt den akt. komplett, dann muss + // der neue gesplittet oder verkuertzt werden + if( *pEnd != *pREnd ) + { + SwRedline* pNew = new SwRedline( *pRedl ); + pNew->SetStart( *pEnd ); + pRedl->SetEnd( *pStt, pREnd ); + AppendRedline( pNew, bCallDelete ); + n = (USHORT)-1; // neu Aufsetzen + } + else + pRedl->SetEnd( *pStt, pREnd ); + break; + } + break; + + } + break; + + case REDLINE_DELETE: + switch( pRedl->GetType() ) + { + case REDLINE_DELETE: + switch( eCmpPos ) + { + case POS_OUTSIDE: + { + // ueberlappt den akt. komplett + // dann muss der neue gesplittet werden + SwRedline* pNew = new SwRedline( *pNewRedl ); + pNew->SetStart( *pREnd ); + pNewRedl->SetEnd( *pRStt, pEnd ); + AppendRedline( pNew, bCallDelete ); + n = (USHORT)-1; // neu Aufsetzen + } + break; + + case POS_INSIDE: + case POS_EQUAL: + delete pNewRedl, pNewRedl = 0; + bCompress = TRUE; + break; + + case POS_OVERLAP_BEFORE: + case POS_OVERLAP_BEHIND: + if( pRedl->IsOwnRedline( *pNewRedl ) && +// 1 == pRedl->GetStackCount() && + pRedl->CanCombine( *pNewRedl )) + { + // dann kann das zusammengefasst werden, sprich + // der neue deckt das schon ab. + if( POS_OVERLAP_BEHIND == eCmpPos ) + pNewRedl->SetStart( *pRStt, pStt ); + else + pNewRedl->SetEnd( *pREnd, pEnd ); + pRedlineTbl->DeleteAndDestroy( n-- ); + } + else if( POS_OVERLAP_BEHIND == eCmpPos ) + pNewRedl->SetStart( *pREnd, pStt ); + else + pNewRedl->SetEnd( *pRStt, pEnd ); + break; + case POS_BEFORE: + case POS_BEHIND: + if( pRedl->IsOwnRedline( *pNewRedl ) && +// 1 == pRedl->GetStackCount() && + pRedl->CanCombine( *pNewRedl ) && + (POS_BEHIND == eCmpPos ? *pREnd == *pStt + : *pRStt == *pEnd )) + { + if( IsHideChanges( eRedlineMode )) + { + // dann erstmal sichtbar machen, bevor + // die zusammengefasst werden koennen! + // Damit pNew auch beim Verschieben der + // Indizies behandelt wird, erstmal + // temporaer einfuegen + pRedlineTbl->SavePtrInArr( pNewRedl ); + pRedl->Show(); + pRedlineTbl->Remove( pRedlineTbl->GetPos(pNewRedl )); + pRStt = pRedl->Start(); + pREnd = pRedl->End(); + } + + // dann kann das zusammengefasst werden, sprich + // der neue deckt das schon ab. + if( POS_BEHIND == eCmpPos ) + pNewRedl->SetStart( *pRStt, pStt ); + else + pNewRedl->SetEnd( *pREnd, pEnd ); + pRedlineTbl->DeleteAndDestroy( n-- ); + } + break; + } + break; + + case REDLINE_INSERT: + if( pRedl->IsOwnRedline( *pNewRedl ) ) + { + SwRedlineMode eOld = eRedlineMode; +// auf NONE setzen, damit das Delete::Redo die RedlineDaten wieder richtig +// zusammen fasst! Der ShowMode muss erhalten bleiben! + eRedlineMode = (SwRedlineMode)(eOld & ~(REDLINE_ON | REDLINE_IGNORE)); + switch( eCmpPos ) + { + case POS_EQUAL: + bCompress = TRUE; + pRedlineTbl->DeleteAndDestroy( n-- ); + // kein break! + + case POS_INSIDE: + if( bCallDelete ) + { + eRedlineMode = (SwRedlineMode) + (eRedlineMode | REDLINE_IGNOREDELETE_REDLINES); + DeleteAndJoin( *pNewRedl ); + bCompress = TRUE; + } + delete pNewRedl, pNewRedl = 0; + break; + + case POS_OUTSIDE: + { + pRedlineTbl->Remove( n-- ); + // damit pNew auch beim Verschieben der Indizies + // behandelt wird, erstmal temp. einfuegen + if( bCallDelete ) + { + pRedlineTbl->SavePtrInArr( pNewRedl ); + DeleteAndJoin( *pRedl ); + USHORT nFnd = pRedlineTbl->GetPos(pNewRedl ); + if( USHRT_MAX != nFnd ) + pRedlineTbl->Remove( nFnd ); + else + pNewRedl = 0; + } + delete pRedl; + } + break; + + case POS_OVERLAP_BEFORE: + { + SwPaM aPam( *pRStt, *pEnd ); + + if( *pEnd == *pREnd ) + pRedlineTbl->DeleteAndDestroy( n-- ); + else + { + pRedl->SetStart( *pEnd, pRStt ); + // neu einsortieren + pRedlineTbl->Remove( n ); + pRedlineTbl->Insert( pRedl, n ); + } + + if( bCallDelete ) + { + // damit pNew auch beim Verschieben der Indizies + // behandelt wird, erstmal temp. einfuegen + pRedlineTbl->SavePtrInArr( pNewRedl ); + DeleteAndJoin( aPam ); + USHORT nFnd = pRedlineTbl->GetPos(pNewRedl ); + if( USHRT_MAX != nFnd ) + pRedlineTbl->Remove( nFnd ); + else + pNewRedl = 0; + n = (USHORT)-1; // neu Aufsetzen + } + } + break; + + case POS_OVERLAP_BEHIND: + { + SwPaM aPam( *pStt, *pREnd ); + + if( *pStt == *pRStt ) + pRedlineTbl->DeleteAndDestroy( n-- ); + else + pRedl->SetEnd( *pStt, pREnd ); + + if( bCallDelete ) + { + // damit pNew auch beim Verschieben der Indizies + // behandelt wird, erstmal temp. einfuegen + pRedlineTbl->SavePtrInArr( pNewRedl ); + DeleteAndJoin( aPam ); + USHORT nFnd = pRedlineTbl->GetPos(pNewRedl ); + if( USHRT_MAX != nFnd ) + pRedlineTbl->Remove( nFnd ); + else + pNewRedl = 0; + n = (USHORT)-1; // neu Aufsetzen + } + } + break; + } + + eRedlineMode = eOld; + } + else + { + SwRedline* pNew = 0; + switch( eCmpPos ) + { + case POS_EQUAL: + { + pRedl->PushData( *pNewRedl ); + delete pNewRedl, pNewRedl = 0; + if( IsHideChanges( eRedlineMode )) + pRedl->Hide(); + bCompress = TRUE; + } + break; + + case POS_INSIDE: + { + pNewRedl->PushData( *pRedl, FALSE ); + if( *pRStt == *pStt ) + { + pRedl->SetStart( *pEnd, pRStt ); + // neu einsortieren + pRedlineTbl->Remove( n ); + pRedlineTbl->Insert( pRedl, n ); + } + else + { + if( *pREnd == *pEnd ) + pRedl->SetEnd( *pStt, pREnd ); + else + { + pNew = new SwRedline( *pRedl ); + pNew->SetStart( *pEnd ); + pRedl->SetEnd( *pStt, pREnd ); + } + if( !pRedl->HasValidRange() ) + { + // neu einsortieren + pRedlineTbl->Remove( n ); + pRedlineTbl->Insert( pRedl, n ); + } + } + } + break; + + case POS_OUTSIDE: + { + pNew = new SwRedline( *pNewRedl ); + pRedl->PushData( *pNewRedl ); + + pNew->SetEnd( *pRStt ); + pNewRedl->SetStart( *pREnd, pStt ); + bCompress = TRUE; + } + break; + + case POS_OVERLAP_BEFORE: + { + if( *pEnd == *pREnd ) + { + pRedl->PushData( *pNewRedl ); + pNewRedl->SetEnd( *pRStt, pEnd ); + if( IsHideChanges( eRedlineMode )) + { + pRedlineTbl->SavePtrInArr( pNewRedl ); + pRedl->Hide(); + pRedlineTbl->Remove( + pRedlineTbl->GetPos(pNewRedl )); + } + } + else + { + pNew = new SwRedline( *pRedl ); + pNew->PushData( *pNewRedl ); + pNew->SetEnd( *pEnd ); + pNewRedl->SetEnd( *pRStt, pEnd ); + pRedl->SetStart( *pNew->End(), pRStt ) ; + // neu einsortieren + pRedlineTbl->Remove( n ); + pRedlineTbl->Insert( pRedl ); + } + } + break; + + case POS_OVERLAP_BEHIND: + { + if( *pStt == *pRStt ) + { + pRedl->PushData( *pNewRedl ); + pNewRedl->SetStart( *pREnd, pStt ); + if( IsHideChanges( eRedlineMode )) + { + pRedlineTbl->SavePtrInArr( pNewRedl ); + pRedl->Hide(); + pRedlineTbl->Remove( + pRedlineTbl->GetPos(pNewRedl )); + } + } + else + { + pNew = new SwRedline( *pRedl ); + pNew->PushData( *pNewRedl ); + pNew->SetStart( *pStt ); + pNewRedl->SetStart( *pREnd, pStt ); + pRedl->SetEnd( *pNew->Start(), pREnd ); + if( !pRedl->HasValidRange() ) + { + // neu einsortieren + pRedlineTbl->Remove( n ); + pRedlineTbl->Insert( pRedl ); + } + } + } + break; + } + if( pNew ) + { + AppendRedline( pNew, bCallDelete ); + n = (USHORT)-1; // neu Aufsetzen + } + } + break; + + case REDLINE_FORMAT: + switch( eCmpPos ) + { + case POS_OVERLAP_BEFORE: + pRedl->SetStart( *pEnd, pRStt ); + // neu einsortieren + pRedlineTbl->Remove( n ); + pRedlineTbl->Insert( pRedl, n ); + break; + + case POS_OVERLAP_BEHIND: + pRedl->SetEnd( *pStt, pREnd ); + break; + + case POS_EQUAL: + case POS_OUTSIDE: + // ueberlappt den akt. komplett oder hat gleiche + // Ausdehung, dann muss der alte geloescht werden + pRedlineTbl->DeleteAndDestroy( n-- ); + break; + + case POS_INSIDE: + // ueberlappt den akt. komplett, dann muss + // der neue gesplittet oder verkuertzt werden + if( *pEnd != *pREnd ) + { + SwRedline* pNew = new SwRedline( *pRedl ); + pNew->SetStart( *pEnd ); + pRedl->SetEnd( *pStt, pREnd ); + AppendRedline( pNew, bCallDelete ); + n = (USHORT)-1; // neu Aufsetzen + } + else + pRedl->SetEnd( *pStt, pREnd ); + break; + } + break; + } + break; + + case REDLINE_FORMAT: + switch( pRedl->GetType() ) + { + case REDLINE_INSERT: + case REDLINE_DELETE: + switch( eCmpPos ) + { + case POS_OVERLAP_BEFORE: + pNewRedl->SetEnd( *pRStt, pEnd ); + break; + + case POS_OVERLAP_BEHIND: + pNewRedl->SetStart( *pREnd, pStt ); + break; + + case POS_EQUAL: + case POS_INSIDE: + delete pNewRedl, pNewRedl = 0; + break; + + case POS_OUTSIDE: + // ueberlappt den akt. komplett, dann muss + // der neue gesplittet oder verkuertzt werden + if( *pEnd != *pREnd ) + { + SwRedline* pNew = new SwRedline( *pNewRedl ); + pNew->SetStart( *pREnd ); + pNewRedl->SetEnd( *pRStt, pEnd ); + AppendRedline( pNew, bCallDelete ); + n = (USHORT)-1; // neu Aufsetzen + } + else + pNewRedl->SetEnd( *pRStt, pEnd ); + break; + } + break; + + case REDLINE_FORMAT: + switch( eCmpPos ) + { + case POS_OUTSIDE: + case POS_EQUAL: + { + // ueberlappt den akt. komplett oder hat gleiche + // Ausdehung, dann muss der alte geloescht werden + pRedlineTbl->DeleteAndDestroy( n-- ); + } + break; + + case POS_INSIDE: + if( pRedl->IsOwnRedline( *pNewRedl ) && + pRedl->CanCombine( *pNewRedl )) + // ein eigenes kann komplett ignoriert werden + delete pNewRedl, pNewRedl = 0; + + else if( *pREnd == *pEnd ) + // ansonsten nur den akt. verkuerzen + pRedl->SetEnd( *pStt, pREnd ); + else if( *pRStt == *pStt ) + { + // ansonsten nur den akt. verkuerzen + pRedl->SetStart( *pEnd, pRStt ); + // neu einsortieren + pRedlineTbl->Remove( n ); + pRedlineTbl->Insert( pRedl, n ); + } + else + { + // liegt komplett im akt. + // dann muss der gesplittet werden + SwRedline* pNew = new SwRedline( *pRedl ); + pNew->SetStart( *pEnd ); + pRedl->SetEnd( *pStt, pREnd ); + AppendRedline( pNew, bCallDelete ); + n = (USHORT)-1; // neu Aufsetzen + } + break; + + case POS_OVERLAP_BEFORE: + case POS_OVERLAP_BEHIND: + if( pRedl->IsOwnRedline( *pNewRedl ) && + pRedl->CanCombine( *pNewRedl )) + { + // dann kann das zusammengefasst werden, sprich + // der neue deckt das schon ab. + if( POS_OVERLAP_BEHIND == eCmpPos ) + pNewRedl->SetStart( *pRStt, pStt ); + else + pNewRedl->SetEnd( *pREnd, pEnd ); + pRedlineTbl->DeleteAndDestroy( n-- ); + } + else if( POS_OVERLAP_BEHIND == eCmpPos ) + pNewRedl->SetStart( *pREnd, pStt ); + else + pNewRedl->SetEnd( *pRStt, pEnd ); + break; + case POS_BEFORE: + if( pRedl->IsOwnRedline( *pNewRedl ) && + pRedl->CanCombine( *pNewRedl ) && + *pRStt == *pEnd && n && + *(*pRedlineTbl)[ n-1 ]->End() < *pStt ) + { + // dann kann das zusammengefasst werden, sprich + // der neue deckt das schon ab. + pNewRedl->SetEnd( *pREnd, pEnd ); + pRedlineTbl->DeleteAndDestroy( n-- ); + } + break; + case POS_BEHIND: + if( pRedl->IsOwnRedline( *pNewRedl ) && + pRedl->CanCombine( *pNewRedl ) && + *pREnd == *pStt && n+1 < pRedlineTbl->Count() && + *(*pRedlineTbl)[ n+1 ]->Start() < *pEnd ) + { + // dann kann das zusammengefasst werden, sprich + // der neue deckt das schon ab. + pNewRedl->SetStart( *pRStt, pStt ); + pRedlineTbl->DeleteAndDestroy( n-- ); + } + break; + } + break; + } + break; + + + case REDLINE_FMTCOLL: + // wie soll das verhalten sein???? + // erstmal so einfuegen + break; + } + } + + if( pNewRedl ) + pRedlineTbl->Insert( pNewRedl ); + + if( bCompress ) + CompressRedlines(); + } + else + { + if( bCallDelete && REDLINE_DELETE == pNewRedl->GetType() ) + { + SwRedlineMode eOld = eRedlineMode; +// auf NONE setzen, damit das Delete::Redo die RedlineDaten wieder richtig +// zusammen fasst! Der ShowMode muss erhalten bleiben! + eRedlineMode = (SwRedlineMode)(eOld & ~(REDLINE_ON | REDLINE_IGNORE)); + DeleteAndJoin( *pNewRedl ); + eRedlineMode = eOld; + } + delete pNewRedl, pNewRedl = 0; + } + _CHECK_REDLINE( this ) + + return 0 != pNewRedl; +} + +void SwDoc::CompressRedlines() +{ + _CHECK_REDLINE( this ) + + void (SwRedline::*pFnc)(USHORT) = 0; + switch( REDLINE_SHOW_MASK & eRedlineMode ) + { + case REDLINE_SHOW_INSERT | REDLINE_SHOW_DELETE: + pFnc = &SwRedline::Show; + break; + case REDLINE_SHOW_INSERT: + pFnc = &SwRedline::Hide; + break; + } + + // versuche gleiche zusammenzufassen + for( USHORT n = 1; n < pRedlineTbl->Count(); ++n ) + { + SwRedline* pPrev = (*pRedlineTbl)[ n-1 ], + * pCur = (*pRedlineTbl)[ n ]; + const SwPosition* pPrevStt = pPrev->Start(), + * pPrevEnd = pPrevStt == pPrev->GetPoint() + ? pPrev->GetMark() : pPrev->GetPoint(); + const SwPosition* pCurStt = pCur->Start(), + * pCurEnd = pCurStt == pCur->GetPoint() + ? pCur->GetMark() : pCur->GetPoint(); + if( *pPrevEnd == *pCurStt && pPrev->CanCombine( *pCur ) && + pPrevStt->nNode.GetNode().FindStartNode() == + pCurEnd->nNode.GetNode().FindStartNode() && + !pCurEnd->nNode.GetNode().FindStartNode()->IsTableNode() ) + { + // dann koennen die zusammen gefasst werden + pPrev->Show(); + pCur->Show(); + + pPrev->SetEnd( *pCur->End() ); + pRedlineTbl->DeleteAndDestroy( n ); + --n; + if( pFnc ) + (pPrev->*pFnc)(0); + } + } + _CHECK_REDLINE( this ) +} + +BOOL SwDoc::SplitRedline( const SwPaM& rRange ) +{ + BOOL bChg = FALSE; + USHORT n = 0; + const SwPosition* pStt = rRange.Start(), + * pEnd = pStt == rRange.GetPoint() ? rRange.GetMark() + : rRange.GetPoint(); + GetRedline( *pStt, &n ); + for( ; n < pRedlineTbl->Count() ; ++n ) + { + SwRedline* pTmp = (*pRedlineTbl)[ n ]; + SwPosition* pTStt = pTmp->Start(), + * pTEnd = pTStt == pTmp->GetPoint() ? pTmp->GetMark() + : pTmp->GetPoint(); + if( *pTStt <= *pStt && *pStt <= *pTEnd && + *pTStt <= *pEnd && *pEnd <= *pTEnd ) + { + bChg = TRUE; + int nn = 0; + if( *pStt == *pTStt ) + nn += 1; + if( *pEnd == *pTEnd ) + nn += 2; + + SwRedline* pNew = 0; + switch( nn ) + { + case 0: + pNew = new SwRedline( *pTmp ); + pTmp->SetEnd( *pStt, pTEnd ); + pNew->SetStart( *pEnd ); + break; + + case 1: + *pTStt = *pEnd; + break; + + case 2: + *pTEnd = *pStt; + break; + + case 3: + pTmp->InvalidateRange(); + pRedlineTbl->DeleteAndDestroy( n-- ); + pTmp = 0; + break; + } + if( pTmp && !pTmp->HasValidRange() ) + { + // neu einsortieren + pRedlineTbl->Remove( n ); + pRedlineTbl->Insert( pTmp, n ); + } + if( pNew ) + pRedlineTbl->Insert( pNew, n ); + } + else if( *pEnd < *pTStt ) + break; + } + return bChg; +} + +BOOL SwDoc::DeleteRedline( const SwPaM& rRange, BOOL bSaveInUndo, + USHORT nDelType ) +{ + if( REDLINE_IGNOREDELETE_REDLINES & eRedlineMode || + !rRange.HasMark() || *rRange.GetMark() == *rRange.GetPoint() ) + return FALSE; + + BOOL bChg = FALSE; + + if( bSaveInUndo && DoesUndo() ) + { + SwUndoRedline* pUndo = new SwUndoRedline( UNDO_REDLINE, rRange ); + if( pUndo->GetRedlSaveCount() ) + { + ClearRedo(); + AppendUndo( pUndo ); + } + else + delete pUndo; + } + + const SwPosition* pStt = rRange.Start(), + * pEnd = pStt == rRange.GetPoint() ? rRange.GetMark() + : rRange.GetPoint(); + USHORT n = 0; + GetRedline( *pStt, &n ); + for( ; n < pRedlineTbl->Count() ; ++n ) + { + SwRedline* pRedl = (*pRedlineTbl)[ n ]; + if( USHRT_MAX != nDelType && nDelType != pRedl->GetType() ) + continue; + + SwPosition* pRStt = pRedl->Start(), + * pREnd = pRStt == pRedl->GetPoint() ? pRedl->GetMark() + : pRedl->GetPoint(); + BOOL bDel = FALSE; + switch( ComparePosition( *pStt, *pEnd, *pRStt, *pREnd ) ) + { + case POS_EQUAL: + case POS_OUTSIDE: + bDel = TRUE; + break; + + case POS_OVERLAP_BEFORE: + if( *pEnd == *pREnd ) + bDel = TRUE; + else + { + pRedl->InvalidateRange(); + pRedl->SetStart( *pEnd, pRStt ); + // neu einsortieren + pRedlineTbl->Remove( n ); + pRedlineTbl->Insert( pRedl ); + --n; + } + break; + + case POS_OVERLAP_BEHIND: + if( *pStt == *pRStt ) + bDel = TRUE; + else + { + pRedl->InvalidateRange(); + pRedl->SetEnd( *pStt, pREnd ); + if( !pRedl->HasValidRange() ) + { + // neu einsortieren + pRedlineTbl->Remove( n ); + pRedlineTbl->Insert( pRedl ); + --n; + } + } + break; + + case POS_INSIDE: + { + // der muss gesplittet werden + pRedl->InvalidateRange(); + if( *pRStt == *pStt ) + { + pRedl->SetStart( *pEnd, pRStt ); + // neu einsortieren + pRedlineTbl->Remove( n ); + pRedlineTbl->Insert( pRedl ); + --n; + } + else + { + SwRedline* pCpy; + if( *pREnd != *pEnd ) + { + pCpy = new SwRedline( *pRedl ); + pCpy->SetStart( *pEnd ); + } + else + pCpy = 0; + pRedl->SetEnd( *pStt, pREnd ); + if( !pRedl->HasValidRange() ) + { + // neu einsortieren + pRedlineTbl->Remove( pRedlineTbl->GetPos( pRedl )); + pRedlineTbl->Insert( pRedl ); + --n; + } + if( pCpy ) + pRedlineTbl->Insert( pCpy ); + } + } + break; + + case POS_BEFORE: + n = pRedlineTbl->Count(); + break; + } + + if( bDel ) + { + pRedl->InvalidateRange(); + pRedlineTbl->DeleteAndDestroy( n-- ); + bChg = TRUE; + } + } + + if( bChg ) + SetModified(); + + return bChg; +} + +BOOL SwDoc::DeleteRedline( const SwStartNode& rNode, BOOL bSaveInUndo, + USHORT nDelType ) +{ + return DeleteRedline( SwPaM( *rNode.EndOfSectionNode(), rNode ), + bSaveInUndo, nDelType ); +} + +void SwDoc::DeleteRedline( USHORT nPos ) +{ + SwRedline* pTmp = (*pRedlineTbl)[ nPos ]; + pTmp->InvalidateRange(); + pRedlineTbl->DeleteAndDestroy( nPos ); +} + +USHORT SwDoc::GetRedlinePos( const SwNode& rNd, USHORT nType ) const +{ + const ULONG nNdIdx = rNd.GetIndex(); + for( USHORT n = 0; n < pRedlineTbl->Count() ; ++n ) + { + const SwRedline* pTmp = (*pRedlineTbl)[ n ]; + ULONG nPt = pTmp->GetPoint()->nNode.GetIndex(), + nMk = pTmp->GetMark()->nNode.GetIndex(); + if( nPt < nMk ) { long nTmp = nMk; nMk = nPt; nPt = nTmp; } + + if( ( USHRT_MAX == nType || nType == pTmp->GetType()) && + nMk <= nNdIdx && nNdIdx <= nPt ) + return n; + + if( nMk > nNdIdx ) + break; + } + return USHRT_MAX; +} + +const SwRedline* SwDoc::GetRedline( const SwPosition& rPos, + USHORT* pFndPos ) const +{ + register USHORT nO = pRedlineTbl->Count(), nM, nU = 0; + if( nO > 0 ) + { + nO--; + while( nU <= nO ) + { + nM = nU + ( nO - nU ) / 2; + const SwRedline* pRedl = (*pRedlineTbl)[ nM ]; + const SwPosition* pStt = pRedl->Start(); + const SwPosition* pEnd = pStt == pRedl->GetPoint() + ? pRedl->GetMark() + : pRedl->GetPoint(); + if( pEnd == pStt + ? *pStt == rPos + : ( *pStt <= rPos && rPos < *pEnd ) ) + { + while( nM && *pStt == *(*pRedlineTbl)[ nM - 1 ]->Start() ) + { + --nM; + pRedl = (*pRedlineTbl)[ nM ]; + } + + if( pFndPos ) + *pFndPos = nM; + return pRedl; + } + else if( *pEnd <= rPos ) + nU = nM + 1; + else if( nM == 0 ) + { + if( pFndPos ) + *pFndPos = nU; + return 0; + } + else + nO = nM - 1; + } + } + if( pFndPos ) + *pFndPos = nU; + return 0; +} + +typedef BOOL (*Fn_AcceptReject)( SwRedlineTbl& rArr, USHORT& rPos, + BOOL bCallDelete, + const SwPosition* pSttRng, + const SwPosition* pEndRng); + +BOOL lcl_AcceptRedline( SwRedlineTbl& rArr, USHORT& rPos, + BOOL bCallDelete, + const SwPosition* pSttRng = 0, + const SwPosition* pEndRng = 0 ) +{ + BOOL bRet = TRUE; + SwRedline* pRedl = rArr[ rPos ]; + SwPosition *pRStt = 0, *pREnd = 0; + SwComparePosition eCmp = POS_OUTSIDE; + if( pSttRng && pEndRng ) + { + pRStt = pRedl->Start(); + pREnd = pRedl->End(); + eCmp = ComparePosition( *pSttRng, *pEndRng, *pRStt, *pREnd ); + } + + pRedl->InvalidateRange(); + + switch( pRedl->GetType() ) + { + case REDLINE_INSERT: + case REDLINE_FORMAT: + { + BOOL bCheck = FALSE, bReplace = FALSE; + switch( eCmp ) + { + case POS_INSIDE: + if( *pSttRng == *pRStt ) + pRedl->SetStart( *pEndRng, pRStt ); + else + { + if( *pEndRng != *pREnd ) + { + // aufsplitten + SwRedline* pNew = new SwRedline( *pRedl ); + pNew->SetStart( *pEndRng ); + rArr.Insert( pNew ); ++rPos; + } + pRedl->SetEnd( *pSttRng, pREnd ); + bCheck = TRUE; + } + break; + + case POS_OVERLAP_BEFORE: + pRedl->SetStart( *pEndRng, pRStt ); + bReplace = TRUE; + break; + + case POS_OVERLAP_BEHIND: + pRedl->SetEnd( *pSttRng, pREnd ); + bCheck = TRUE; + break; + + case POS_OUTSIDE: + case POS_EQUAL: + rArr.DeleteAndDestroy( rPos-- ); + break; + + default: + bRet = FALSE; + } + + if( bReplace || ( bCheck && !pRedl->HasValidRange() )) + { + // neu einsortieren + rArr.Remove( rArr.GetPos( pRedl )); + rArr.Insert( pRedl ); + } + } + break; + case REDLINE_DELETE: + { + SwDoc& rDoc = *pRedl->GetDoc(); + const SwPosition *pDelStt = 0, *pDelEnd = 0; + BOOL bDelRedl = FALSE; + switch( eCmp ) + { + case POS_INSIDE: + if( bCallDelete ) + { + pDelStt = pSttRng; + pDelEnd = pEndRng; + } + break; + + case POS_OVERLAP_BEFORE: + if( bCallDelete ) + { + pDelStt = pRStt; + pDelEnd = pEndRng; + } + break; + case POS_OVERLAP_BEHIND: + if( bCallDelete ) + { + pDelStt = pREnd; + pDelEnd = pSttRng; + } + break; + + case POS_OUTSIDE: + case POS_EQUAL: + { + rArr.Remove( rPos-- ); + bDelRedl = TRUE; + if( bCallDelete ) + { + pDelStt = pRedl->Start(); + pDelEnd = pRedl->End(); + } + } + break; + default: + bRet = FALSE; + } + + if( pDelStt && pDelEnd ) + { + SwPaM aPam( *pDelStt, *pDelEnd ); + + if( bDelRedl ) + delete pRedl; + + SwRedlineMode eOld = rDoc.GetRedlineMode(); + rDoc.SetRedlineMode_intern( eOld & ~(REDLINE_ON | REDLINE_IGNORE) ); + rDoc.DeleteAndJoin( aPam ); + rDoc.SetRedlineMode_intern( eOld ); + } + else if( bDelRedl ) + delete pRedl; + } + break; + + case REDLINE_FMTCOLL: + rArr.DeleteAndDestroy( rPos-- ); + break; + + default: + bRet = FALSE; + } + return bRet; +} + +BOOL lcl_RejectRedline( SwRedlineTbl& rArr, USHORT& rPos, + BOOL bCallDelete, + const SwPosition* pSttRng = 0, + const SwPosition* pEndRng = 0 ) +{ + BOOL bRet = TRUE; + SwRedline* pRedl = rArr[ rPos ]; + SwPosition *pRStt = 0, *pREnd = 0; + SwComparePosition eCmp = POS_OUTSIDE; + if( pSttRng && pEndRng ) + { + pRStt = pRedl->Start(); + pREnd = pRedl->End(); + eCmp = ComparePosition( *pSttRng, *pEndRng, *pRStt, *pREnd ); + } + + pRedl->InvalidateRange(); + + switch( pRedl->GetType() ) + { + case REDLINE_INSERT: + { + SwDoc& rDoc = *pRedl->GetDoc(); + const SwPosition *pDelStt = 0, *pDelEnd = 0; + BOOL bDelRedl = FALSE; + switch( eCmp ) + { + case POS_INSIDE: + if( bCallDelete ) + { + pDelStt = pSttRng; + pDelEnd = pEndRng; + } + break; + + case POS_OVERLAP_BEFORE: + if( bCallDelete ) + { + pDelStt = pRStt; + pDelEnd = pEndRng; + } + break; + case POS_OVERLAP_BEHIND: + if( bCallDelete ) + { + pDelStt = pREnd; + pDelEnd = pSttRng; + } + break; + case POS_OUTSIDE: + case POS_EQUAL: + { + // dann den Bereich wieder loeschen + rArr.Remove( rPos-- ); + bDelRedl = TRUE; + if( bCallDelete ) + { + pDelStt = pRedl->Start(); + pDelEnd = pRedl->End(); + } + } + break; + + default: + bRet = FALSE; + } + if( pDelStt && pDelEnd ) + { + SwPaM aPam( *pDelStt, *pDelEnd ); + + if( bDelRedl ) + delete pRedl; + + SwRedlineMode eOld = rDoc.GetRedlineMode(); + rDoc.SetRedlineMode_intern( eOld & ~(REDLINE_ON | REDLINE_IGNORE) ); + rDoc.DeleteAndJoin( aPam ); + rDoc.SetRedlineMode_intern( eOld ); + } + else if( bDelRedl ) + delete pRedl; + } + break; + case REDLINE_DELETE: + { + SwRedline* pNew = 0; + BOOL bCheck = FALSE, bReplace = FALSE; + + switch( eCmp ) + { + case POS_INSIDE: + { + if( 1 < pRedl->GetStackCount() ) + { + pNew = new SwRedline( *pRedl ); + pNew->PopData(); + } + if( *pSttRng == *pRStt ) + { + pRedl->SetStart( *pEndRng, pRStt ); + bReplace = TRUE; + if( pNew ) + pNew->SetEnd( *pEndRng ); + } + else + { + if( *pEndRng != *pREnd ) + { + // aufsplitten + SwRedline* pCpy = new SwRedline( *pRedl ); + pCpy->SetStart( *pEndRng ); + rArr.Insert( pCpy ); ++rPos; + if( pNew ) + pNew->SetEnd( *pEndRng ); + } + + pRedl->SetEnd( *pSttRng, pREnd ); + bCheck = TRUE; + if( pNew ) + pNew->SetStart( *pSttRng ); + } + } + break; + + case POS_OVERLAP_BEFORE: + if( 1 < pRedl->GetStackCount() ) + { + pNew = new SwRedline( *pRedl ); + pNew->PopData(); + } + pRedl->SetStart( *pEndRng, pRStt ); + bReplace = TRUE; + if( pNew ) + pNew->SetEnd( *pEndRng ); + break; + + case POS_OVERLAP_BEHIND: + if( 1 < pRedl->GetStackCount() ) + { + pNew = new SwRedline( *pRedl ); + pNew->PopData(); + } + pRedl->SetEnd( *pSttRng, pREnd ); + bCheck = TRUE; + if( pNew ) + pNew->SetStart( *pSttRng ); + break; + + case POS_OUTSIDE: + case POS_EQUAL: + if( !pRedl->PopData() ) + // das RedlineObject loeschen reicht + rArr.DeleteAndDestroy( rPos-- ); + break; + + default: + bRet = FALSE; + } + + if( pNew ) + { + rArr.Insert( pNew ); ++rPos; + } + + if( bReplace || ( bCheck && !pRedl->HasValidRange() )) + { + // neu einsortieren + rArr.Remove( rArr.GetPos( pRedl )); + rArr.Insert( pRedl ); + } + } + break; + + case REDLINE_FORMAT: + case REDLINE_FMTCOLL: + { + if( pRedl->GetExtraData() ) + pRedl->GetExtraData()->Reject( *pRedl ); + rArr.DeleteAndDestroy( rPos-- ); + } + break; + + default: + bRet = FALSE; + } + return bRet; +} + + +const SwRedline* lcl_FindCurrRedline( const SwPosition& rSttPos, + USHORT& rPos, + BOOL bNext = TRUE ) +{ + const SwRedline* pFnd = 0; + const SwRedlineTbl& rArr = rSttPos.nNode.GetNode().GetDoc()->GetRedlineTbl(); + for( ; rPos < rArr.Count() ; ++rPos ) + { + const SwRedline* pTmp = rArr[ rPos ]; + if( pTmp->HasMark() && pTmp->IsVisible() ) + { + const SwPosition* pRStt = pTmp->Start(), + * pREnd = pRStt == pTmp->GetPoint() ? pTmp->GetMark() + : pTmp->GetPoint(); + if( bNext ? *pRStt <= rSttPos : *pRStt < rSttPos ) + { + if( bNext ? *pREnd > rSttPos : *pREnd >= rSttPos ) + { + pFnd = pTmp; + break; + } + } + else + break; + } + } + return pFnd; +} + + +BOOL lcl_AcceptRejectRedl( Fn_AcceptReject fn_AcceptReject, + SwRedlineTbl& rArr, BOOL bCallDelete, + const SwPaM& rPam ) +{ + BOOL bRet = FALSE; + USHORT n = 0; + const SwPosition* pStt = rPam.Start(), + * pEnd = pStt == rPam.GetPoint() ? rPam.GetMark() + : rPam.GetPoint(); + const SwRedline* pFnd = lcl_FindCurrRedline( *pStt, n, TRUE ); + if( pFnd && // neu ein Teil davon? + ( *pFnd->Start() != *pStt || *pFnd->End() > *pEnd )) + { + // dann nur die TeilSelektion aufheben + if( (*fn_AcceptReject)( rArr, n, bCallDelete, pStt, pEnd )) + bRet = TRUE; + ++n; + } + + for( ; n < rArr.Count(); ++n ) + { + SwRedline* pTmp = rArr[ n ]; + if( pTmp->HasMark() && pTmp->IsVisible() ) + { + if( *pTmp->End() <= *pEnd ) + { + if( (*fn_AcceptReject)( rArr, n, bCallDelete, 0, 0 )) + bRet = TRUE; + } + else + { + if( *pTmp->Start() < *pEnd ) + { + // dann nur in der TeilSelektion aufheben + if( (*fn_AcceptReject)( rArr, n, bCallDelete, pStt, pEnd )) + bRet = TRUE; + } + break; + } + } + } + return bRet; +} + +void lcl_AdjustRedlineRange( SwPaM& rPam ) +{ + // die Selektion steht nur im ContentBereich. Wenn es aber Redlines + // davor oder dahinter auf nicht ContentNodes stehen, dann erweiter die + // die Selection auf diese + SwPosition* pStt = rPam.Start(), + * pEnd = pStt == rPam.GetPoint() ? rPam.GetMark() + : rPam.GetPoint(); + SwDoc* pDoc = rPam.GetDoc(); + if( !pStt->nContent.GetIndex() && + !pDoc->GetNodes()[ pStt->nNode.GetIndex() - 1 ]->IsCntntNode() ) + { + const SwRedline* pRedl = pDoc->GetRedline( *pStt ); + if( pRedl ) + { + const SwPosition* pRStt = pRedl->Start(); + if( !pRStt->nContent.GetIndex() && pRStt->nNode.GetIndex() == + pStt->nNode.GetIndex() - 1 ) + *pStt = *pRStt; + } + } + if( pEnd->nNode.GetNode().IsCntntNode() && + !pDoc->GetNodes()[ pEnd->nNode.GetIndex() + 1 ]->IsCntntNode() && + pEnd->nContent.GetIndex() == pEnd->nNode.GetNode().GetCntntNode()->Len() ) + { + const SwRedline* pRedl = pDoc->GetRedline( *pEnd ); + if( pRedl ) + { + const SwPosition* pREnd = pRedl->End(); + if( !pREnd->nContent.GetIndex() && pREnd->nNode.GetIndex() == + pEnd->nNode.GetIndex() + 1 ) + *pEnd = *pREnd; + } + } +} + + +BOOL SwDoc::AcceptRedline( USHORT nPos, BOOL bCallDelete ) +{ + BOOL bRet = FALSE; + + // aufjedenfall auf sichtbar umschalten + if( (REDLINE_SHOW_INSERT | REDLINE_SHOW_DELETE) != + (REDLINE_SHOW_MASK & eRedlineMode) ) + SetRedlineMode( REDLINE_SHOW_INSERT | REDLINE_SHOW_DELETE | eRedlineMode ); + + SwRedline* pTmp = (*pRedlineTbl)[ nPos ]; + if( pTmp->HasMark() && pTmp->IsVisible() ) + { + if( DoesUndo() ) + StartUndo( UNDO_ACCEPT_REDLINE ); + + int nLoopCnt = 2; + USHORT nSeqNo = pTmp->GetSeqNo(); + + do { + + if( DoesUndo() ) + AppendUndo( new SwUndoAcceptRedline( *pTmp )); + + bRet |= lcl_AcceptRedline( *pRedlineTbl, nPos, bCallDelete ); + + if( nSeqNo ) + { + if( USHRT_MAX == nPos ) + nPos = 0; + USHORT nFndPos = 2 == nLoopCnt + ? pRedlineTbl->FindNextSeqNo( nSeqNo, nPos ) + : pRedlineTbl->FindPrevSeqNo( nSeqNo, nPos ); + if( USHRT_MAX != nFndPos || ( 0 != ( --nLoopCnt ) && + USHRT_MAX != ( nFndPos = + pRedlineTbl->FindPrevSeqNo( nSeqNo, nPos ))) ) + pTmp = (*pRedlineTbl)[ nPos = nFndPos ]; + else + nLoopCnt = 0; + } + else + nLoopCnt = 0; + + } while( nLoopCnt ); + + if( bRet ) + { + CompressRedlines(); + SetModified(); + } + + if( DoesUndo() ) + EndUndo( UNDO_ACCEPT_REDLINE ); + } + return bRet; +} + +BOOL SwDoc::AcceptRedline( const SwPaM& rPam, BOOL bCallDelete ) +{ + // aufjedenfall auf sichtbar umschalten + if( (REDLINE_SHOW_INSERT | REDLINE_SHOW_DELETE) != + (REDLINE_SHOW_MASK & eRedlineMode) ) + SetRedlineMode( REDLINE_SHOW_INSERT | REDLINE_SHOW_DELETE | eRedlineMode ); + + // die Selektion steht nur im ContentBereich. Wenn es aber Redlines + // davor oder dahinter auf nicht ContentNodes stehen, dann erweiter die + // die Selection auf diese + SwPaM aPam( *rPam.GetMark(), *rPam.GetPoint() ); + lcl_AdjustRedlineRange( aPam ); + + if( DoesUndo() ) + { + StartUndo( UNDO_ACCEPT_REDLINE ); + AppendUndo( new SwUndoAcceptRedline( aPam )); + } + + BOOL bRet = lcl_AcceptRejectRedl( lcl_AcceptRedline, *pRedlineTbl, + bCallDelete, aPam ); + if( bRet ) + { + CompressRedlines(); + SetModified(); + } + if( DoesUndo() ) + EndUndo( UNDO_ACCEPT_REDLINE ); + return bRet; +} + +BOOL SwDoc::RejectRedline( USHORT nPos, BOOL bCallDelete ) +{ + BOOL bRet = FALSE; + + // aufjedenfall auf sichtbar umschalten + if( (REDLINE_SHOW_INSERT | REDLINE_SHOW_DELETE) != + (REDLINE_SHOW_MASK & eRedlineMode) ) + SetRedlineMode( REDLINE_SHOW_INSERT | REDLINE_SHOW_DELETE | eRedlineMode ); + + SwRedline* pTmp = (*pRedlineTbl)[ nPos ]; + if( pTmp->HasMark() && pTmp->IsVisible() ) + { + if( DoesUndo() ) + StartUndo( UNDO_REJECT_REDLINE ); + + int nLoopCnt = 2; + USHORT nSeqNo = pTmp->GetSeqNo(); + + do { + + if( DoesUndo() ) + AppendUndo( new SwUndoRejectRedline( *pTmp )); + + bRet |= lcl_RejectRedline( *pRedlineTbl, nPos, bCallDelete ); + + if( nSeqNo ) + { + if( USHRT_MAX == nPos ) + nPos = 0; + USHORT nFndPos = 2 == nLoopCnt + ? pRedlineTbl->FindNextSeqNo( nSeqNo, nPos ) + : pRedlineTbl->FindPrevSeqNo( nSeqNo, nPos ); + if( USHRT_MAX != nFndPos || ( 0 != ( --nLoopCnt ) && + USHRT_MAX != ( nFndPos = + pRedlineTbl->FindPrevSeqNo( nSeqNo, nPos ))) ) + pTmp = (*pRedlineTbl)[ nPos = nFndPos ]; + else + nLoopCnt = 0; + } + else + nLoopCnt = 0; + + } while( nLoopCnt ); + + if( bRet ) + { + CompressRedlines(); + SetModified(); + } + + if( DoesUndo() ) + EndUndo( UNDO_REJECT_REDLINE ); + } + return bRet; +} + +BOOL SwDoc::RejectRedline( const SwPaM& rPam, BOOL bCallDelete ) +{ + // aufjedenfall auf sichtbar umschalten + if( (REDLINE_SHOW_INSERT | REDLINE_SHOW_DELETE) != + (REDLINE_SHOW_MASK & eRedlineMode) ) + SetRedlineMode( REDLINE_SHOW_INSERT | REDLINE_SHOW_DELETE | eRedlineMode ); + + // die Selektion steht nur im ContentBereich. Wenn es aber Redlines + // davor oder dahinter auf nicht ContentNodes stehen, dann erweiter die + // die Selection auf diese + SwPaM aPam( *rPam.GetMark(), *rPam.GetPoint() ); + lcl_AdjustRedlineRange( aPam ); + + if( DoesUndo() ) + { + StartUndo( UNDO_REJECT_REDLINE ); + AppendUndo( new SwUndoRejectRedline( aPam )); + } + + BOOL bRet = lcl_AcceptRejectRedl( lcl_RejectRedline, *pRedlineTbl, + bCallDelete, aPam ); + if( bRet ) + { + CompressRedlines(); + SetModified(); + } + if( DoesUndo() ) + EndUndo( UNDO_REJECT_REDLINE ); + return bRet; +} + +const SwRedline* SwDoc::SelNextRedline( SwPaM& rPam ) const +{ + rPam.DeleteMark(); + rPam.SetMark(); + + SwPosition& rSttPos = *rPam.GetPoint(); + SwPosition aSavePos( rSttPos ); + BOOL bRestart; + + // sollte die StartPos auf dem letzen gueligen ContentNode stehen, + // dann aufjedenfall das naechste Redline nehmen + USHORT n = 0; + const SwRedline* pFnd = lcl_FindCurrRedline( rSttPos, n, TRUE ); + if( pFnd ) + { + const SwPosition* pEnd = pFnd->End(); + if( !pEnd->nNode.GetNode().IsCntntNode() ) + { + SwNodeIndex aTmp( pEnd->nNode ); + SwCntntNode* pCNd = GetNodes().GoPrevSection( &aTmp ); + if( !pCNd || ( aTmp == rSttPos.nNode && + pCNd->Len() == rSttPos.nContent.GetIndex() )) + pFnd = 0; + } + if( pFnd ) + rSttPos = *pFnd->End(); + } + + do { + bRestart = FALSE; + + for( ; !pFnd && n < pRedlineTbl->Count(); ++n ) + { + pFnd = (*pRedlineTbl)[ n ]; + if( pFnd->HasMark() && pFnd->IsVisible() ) + { + *rPam.GetMark() = *pFnd->Start(); + rSttPos = *pFnd->End(); + break; + } + else + pFnd = 0; + } + + if( pFnd ) + { + // alle vom gleichen Typ und Author, die hinter einander liegen + // zu einer Selektion zusammenfassen. + const SwPosition* pPrevEnd = pFnd->End(); + while( ++n < pRedlineTbl->Count() ) + { + const SwRedline* pTmp = (*pRedlineTbl)[ n ]; + if( pTmp->HasMark() && pTmp->IsVisible() ) + { + const SwPosition *pRStt; + if( pFnd->GetType() == pTmp->GetType() && + pFnd->GetAuthor() == pTmp->GetAuthor() && + ( *pPrevEnd == *( pRStt = pTmp->Start() ) || + IsPrevPos( *pPrevEnd, *pRStt )) ) + { + pPrevEnd = pTmp->End(); + rSttPos = *pPrevEnd; + } + else + break; + } + } + } + + if( pFnd ) + { + const SwRedline* pSaveFnd = pFnd; + + SwCntntNode* pCNd; + SwNodeIndex* pIdx = &rPam.GetMark()->nNode; + if( !pIdx->GetNode().IsCntntNode() && + 0 != ( pCNd = GetNodes().GoNextSection( pIdx )) ) + { + if( *pIdx <= rPam.GetPoint()->nNode ) + rPam.GetMark()->nContent.Assign( pCNd, 0 ); + else + pFnd = 0; + } + + if( pFnd ) + { + pIdx = &rPam.GetPoint()->nNode; + if( !pIdx->GetNode().IsCntntNode() && + 0 != ( pCNd = GetNodes().GoPrevSection( pIdx )) ) + { + if( *pIdx >= rPam.GetMark()->nNode ) + rPam.GetPoint()->nContent.Assign( pCNd, pCNd->Len() ); + else + pFnd = 0; + } + } + + if( !pFnd || *rPam.GetMark() == *rPam.GetPoint() ) + { + if( n < pRedlineTbl->Count() ) + { + bRestart = TRUE; + *rPam.GetPoint() = *pSaveFnd->End(); + } + else + { + rPam.DeleteMark(); + *rPam.GetPoint() = aSavePos; + } + pFnd = 0; + } + } + } while( bRestart ); + + return pFnd; +} + +const SwRedline* SwDoc::SelPrevRedline( SwPaM& rPam ) const +{ + rPam.DeleteMark(); + rPam.SetMark(); + + SwPosition& rSttPos = *rPam.GetPoint(); + SwPosition aSavePos( rSttPos ); + BOOL bRestart; + + // sollte die StartPos auf dem ersten gueligen ContentNode stehen, + // dann aufjedenfall das vorherige Redline nehmen + USHORT n = 0; + const SwRedline* pFnd = lcl_FindCurrRedline( rSttPos, n, FALSE ); + if( pFnd ) + { + const SwPosition* pStt = pFnd->Start(); + if( !pStt->nNode.GetNode().IsCntntNode() ) + { + SwNodeIndex aTmp( pStt->nNode ); + SwCntntNode* pCNd = GetNodes().GoNextSection( &aTmp ); + if( !pCNd || ( aTmp == rSttPos.nNode && + !rSttPos.nContent.GetIndex() )) + pFnd = 0; + } + if( pFnd ) + rSttPos = *pFnd->Start(); + } + + do { + bRestart = FALSE; + + while( !pFnd && 0 < n ) + { + pFnd = (*pRedlineTbl)[ --n ]; + if( pFnd->HasMark() && pFnd->IsVisible() ) + { + *rPam.GetMark() = *pFnd->End(); + rSttPos = *pFnd->Start(); + } + else + pFnd = 0; + } + + if( pFnd ) + { + // alle vom gleichen Typ und Author, die hinter einander liegen + // zu einer Selektion zusammenfassen. + const SwPosition* pNextStt = pFnd->Start(); + while( 0 < n ) + { + const SwRedline* pTmp = (*pRedlineTbl)[ --n ]; + if( pTmp->HasMark() && pTmp->IsVisible() ) + { + const SwPosition *pREnd; + if( pFnd->GetType() == pTmp->GetType() && + pFnd->GetAuthor() == pTmp->GetAuthor() && + ( *pNextStt == *( pREnd = pTmp->End() ) || + IsPrevPos( *pREnd, *pNextStt )) ) + { + pNextStt = pTmp->Start(); + rSttPos = *pNextStt; + } + else + { + ++n; + break; + } + } + } + } + + if( pFnd ) + { + const SwRedline* pSaveFnd = pFnd; + + SwCntntNode* pCNd; + SwNodeIndex* pIdx = &rPam.GetMark()->nNode; + if( !pIdx->GetNode().IsCntntNode() && + 0 != ( pCNd = GetNodes().GoPrevSection( pIdx )) ) + { + if( *pIdx >= rPam.GetPoint()->nNode ) + rPam.GetMark()->nContent.Assign( pCNd, pCNd->Len() ); + else + pFnd = 0; + } + + if( pFnd ) + { + pIdx = &rPam.GetPoint()->nNode; + if( !pIdx->GetNode().IsCntntNode() && + 0 != ( pCNd = GetNodes().GoNextSection( pIdx )) ) + { + if( *pIdx <= rPam.GetMark()->nNode ) + rPam.GetPoint()->nContent.Assign( pCNd, 0 ); + else + pFnd = 0; + } + } + + if( !pFnd || *rPam.GetMark() == *rPam.GetPoint() ) + { + if( n ) + { + bRestart = TRUE; + *rPam.GetPoint() = *pSaveFnd->Start(); + } + else + { + rPam.DeleteMark(); + *rPam.GetPoint() = aSavePos; + } + pFnd = 0; + } + } + } while( bRestart ); + + return pFnd; +} + +// Kommentar am Redline setzen +BOOL SwDoc::SetRedlineComment( const SwPaM& rPaM, const String& rS ) +{ + BOOL bRet = FALSE; + const SwPosition* pStt = rPaM.Start(), + * pEnd = pStt == rPaM.GetPoint() ? rPaM.GetMark() + : rPaM.GetPoint(); + USHORT n = 0; + if( lcl_FindCurrRedline( *pStt, n, TRUE ) ) + { + for( ; n < pRedlineTbl->Count(); ++n ) + { + bRet = TRUE; + SwRedline* pTmp = (*pRedlineTbl)[ n ]; + if( pStt != pEnd && *pTmp->Start() > *pEnd ) + break; + + pTmp->SetComment( rS ); + if( *pTmp->End() >= *pEnd ) + break; + } + } + if( bRet ) + SetModified(); + + return bRet; +} + +// legt gebenenfalls einen neuen Author an +USHORT SwDoc::GetRedlineAuthor() +{ + return SW_MOD()->GetRedlineAuthor(); +} + + // fuer die Reader usw. - neuen Author in die Tabelle eintragen +USHORT SwDoc::InsertRedlineAuthor( const String& rNew ) +{ + return SW_MOD()->InsertRedlineAuthor(rNew); +} + +void SwDoc::UpdateRedlineAttr() +{ + const SwRedlineTbl& rTbl = GetRedlineTbl(); + for( USHORT n = 0; n < rTbl.Count(); ++n ) + { + SwRedline* pRedl = rTbl[ n ]; + if( pRedl->IsVisible() ) + pRedl->InvalidateRange(); + } +} + + // setze Kommentar-Text fuers Redline, das dann per AppendRedline + // hereinkommt. Wird vom Autoformat benutzt. 0-Pointer setzt den Modus + // wieder zurueck. Pointer wird nicht kopiert, muss also gueltig bleiben! +void SwDoc::SetAutoFmtRedlineComment( const String* pTxt, USHORT nSeqNo ) +{ + bIsAutoFmtRedline = 0 != pTxt; + if( pTxt ) + { + if( !pAutoFmtRedlnComment ) + pAutoFmtRedlnComment = new String( *pTxt ); + else + *pAutoFmtRedlnComment = *pTxt; + } + else if( pAutoFmtRedlnComment ) + delete pAutoFmtRedlnComment, pAutoFmtRedlnComment = 0; + + nAutoFmtRedlnCommentNo = nSeqNo; +} + +/* */ + +BOOL SwRedlineTbl::Insert( SwRedlinePtr& p, BOOL bIns ) +{ + BOOL bRet = FALSE; + if( p->HasValidRange() ) + { + bRet = _SwRedlineTbl::Insert( p ); + p->CallDisplayFunc(); + } + else if( bIns ) + bRet = InsertWithValidRanges( p ); + else + { + ASSERT( !this, "Redline: falscher Bereich" ); + } + return bRet; +} + +BOOL SwRedlineTbl::Insert( SwRedlinePtr& p, USHORT& rP, BOOL bIns ) +{ + BOOL bRet = FALSE; + if( p->HasValidRange() ) + { + bRet = _SwRedlineTbl::Insert( p, rP ); + p->CallDisplayFunc(); + } + else if( bIns ) + bRet = InsertWithValidRanges( p, &rP ); + else + { + ASSERT( !this, "Redline: falscher Bereich" ); + } + return bRet; +} + +BOOL SwRedlineTbl::InsertWithValidRanges( SwRedlinePtr& p, USHORT* pInsPos ) +{ + // erzeuge aus den Selektion gueltige "Teilbereiche". + BOOL bAnyIns = FALSE; + SwPosition* pStt = p->Start(), + * pEnd = pStt == p->GetPoint() ? p->GetMark() : p->GetPoint(); + SwPosition aNewStt( *pStt ); + SwNodes& rNds = aNewStt.nNode.GetNodes(); + SwCntntNode* pC; + + if( !aNewStt.nNode.GetNode().IsCntntNode() ) + { + pC = rNds.GoNext( &aNewStt.nNode ); + if( pC ) + aNewStt.nContent.Assign( pC, 0 ); + else + aNewStt.nNode = rNds.GetEndOfContent(); + } + + SwRedline* pNew = 0; + USHORT nInsPos; + + if( aNewStt < *pEnd ) + do { + if( !pNew ) + pNew = new SwRedline( p->GetRedlineData(), aNewStt ); + else + { + pNew->DeleteMark(); + *pNew->GetPoint() = aNewStt; + } + + pNew->SetMark(); + GoEndSection( pNew->GetPoint() ); + if( *pNew->GetPoint() > *pEnd ) + { + BOOL bWeiter = TRUE; + pC = 0; + if( aNewStt.nNode != pEnd->nNode ) + do { + SwNode& rCurNd = aNewStt.nNode.GetNode(); + if( rCurNd.IsStartNode() ) + { + if( rCurNd.EndOfSectionIndex() < pEnd->nNode.GetIndex() ) + aNewStt.nNode = *rCurNd.EndOfSectionNode(); + else + break; + } + else if( rCurNd.IsCntntNode() ) + pC = rCurNd.GetCntntNode(); + aNewStt.nNode++; + } while( aNewStt.nNode.GetIndex() < pEnd->nNode.GetIndex() ); + + if( aNewStt.nNode == pEnd->nNode ) + aNewStt.nContent = pEnd->nContent; + else if( pC ) + { + aNewStt.nNode = *pC; + aNewStt.nContent.Assign( pC, pC->Len() ); + } + + if( aNewStt <= *pEnd ) + *pNew->GetPoint() = aNewStt; + } + else + aNewStt = *pNew->GetPoint(); + + if( *pNew->GetPoint() != *pNew->GetMark() && + _SwRedlineTbl::Insert( pNew, nInsPos ) ) + { + pNew->CallDisplayFunc(); + bAnyIns = TRUE; + pNew = 0; + if( pInsPos && *pInsPos < nInsPos ) + *pInsPos = nInsPos; + } + + if( aNewStt >= *pEnd || + 0 == (pC = rNds.GoNext( &aNewStt.nNode )) ) + break; + + aNewStt.nContent.Assign( pC, 0 ); + + } while( aNewStt < *pEnd ); + + delete pNew; + delete p, p = 0; + return bAnyIns; +} + +void SwRedlineTbl::Remove( USHORT nP, USHORT nL ) +{ + SwDoc* pDoc = 0; + if( !nP && nL && nL == _SwRedlineTbl::Count() ) + pDoc = _SwRedlineTbl::GetObject( 0 )->GetDoc(); + + _SwRedlineTbl::Remove( nP, nL ); + + ViewShell* pSh; + if( pDoc && !pDoc->IsInDtor() && pDoc->GetRootFrm() && + 0 != ( pSh = pDoc->GetRootFrm()->GetCurrShell()) ) + pSh->InvalidateWindows( SwRect( 0, 0, LONG_MAX, LONG_MAX ) ); +} + +void SwRedlineTbl::DeleteAndDestroy( USHORT nP, USHORT nL ) +{ + SwDoc* pDoc = 0; + if( !nP && nL && nL == _SwRedlineTbl::Count() ) + pDoc = _SwRedlineTbl::GetObject( 0 )->GetDoc(); + + _SwRedlineTbl::DeleteAndDestroy( nP, nL ); + + ViewShell* pSh; + if( pDoc && !pDoc->IsInDtor() && pDoc->GetRootFrm() && + 0 != ( pSh = pDoc->GetRootFrm()->GetCurrShell()) ) + pSh->InvalidateWindows( SwRect( 0, 0, LONG_MAX, LONG_MAX ) ); +} + +// suche den naechsten oder vorherigen Redline mit dergleichen Seq.No +// Mit dem Lookahead kann die Suche eingeschraenkt werden. 0 oder +// USHRT_MAX suchen im gesamten Array. +USHORT SwRedlineTbl::FindNextOfSeqNo( USHORT nSttPos, USHORT nLookahead ) const +{ +#if 0 + USHORT nRet = USHRT_MAX, nEnd, + nSeqNo = _SwRedlineTbl::GetObject( nSttPos )->GetSeqNo(); + if( nSeqNo ) + { + nEnd = _SwRedlineTbl::Count(); + if( nLookahead && USHRT_MAX != nLookahead && + nSttPos + nLookahead < _SwRedlineTbl::Count() ) + nEnd = nSttPos + nLookahead; + + while( ++nSttPos < nEnd ) + if( nSeqNo == _SwRedlineTbl::GetObject( nSttPos )->GetSeqNo() ) + { + nRet = nSttPos; + break; + } + } + return nRet; +#else + return nSttPos + 1 < _SwRedlineTbl::Count() + ? FindNextSeqNo( _SwRedlineTbl::GetObject( nSttPos ) + ->GetSeqNo(), nSttPos+1, nLookahead ) + : USHRT_MAX; +#endif +} + +USHORT SwRedlineTbl::FindPrevOfSeqNo( USHORT nSttPos, USHORT nLookahead ) const +{ +#if 0 + USHORT nRet = USHRT_MAX, nEnd, + nSeqNo = _SwRedlineTbl::GetObject( nSttPos )->GetSeqNo(); + if( nSeqNo ) + { + nEnd = 0; + if( nLookahead && USHRT_MAX != nLookahead && nSttPos > nLookahead ) + nEnd = nSttPos - nLookahead; + + while( nSttPos-- > nEnd ) + if( nSeqNo == _SwRedlineTbl::GetObject( nSttPos )->GetSeqNo() ) + { + nRet = nSttPos; + break; + } + } + return nRet; +#else + return nSttPos ? FindPrevSeqNo( _SwRedlineTbl::GetObject( + nSttPos )->GetSeqNo(), + nSttPos-1, nLookahead ) + : USHRT_MAX; +#endif +} + +USHORT SwRedlineTbl::FindNextSeqNo( USHORT nSeqNo, USHORT nSttPos, + USHORT nLookahead ) const +{ + USHORT nRet = USHRT_MAX, nEnd; + if( nSeqNo && nSttPos < _SwRedlineTbl::Count() ) + { + nEnd = _SwRedlineTbl::Count(); + if( nLookahead && USHRT_MAX != nLookahead && + nSttPos + nLookahead < _SwRedlineTbl::Count() ) + nEnd = nSttPos + nLookahead; + + for( ; nSttPos < nEnd; ++nSttPos ) + if( nSeqNo == _SwRedlineTbl::GetObject( nSttPos )->GetSeqNo() ) + { + nRet = nSttPos; + break; + } + } + return nRet; +} + +USHORT SwRedlineTbl::FindPrevSeqNo( USHORT nSeqNo, USHORT nSttPos, + USHORT nLookahead ) const +{ + USHORT nRet = USHRT_MAX, nEnd; + if( nSeqNo && nSttPos < _SwRedlineTbl::Count() ) + { + nEnd = 0; + if( nLookahead && USHRT_MAX != nLookahead && nSttPos > nLookahead ) + nEnd = nSttPos - nLookahead; + + ++nSttPos; + while( nSttPos > nEnd ) + if( nSeqNo == _SwRedlineTbl::GetObject( --nSttPos )->GetSeqNo() ) + { + nRet = nSttPos; + break; + } + } + return nRet; +} + +/* */ + +SwRedlineExtraData::~SwRedlineExtraData() +{ +} + +void SwRedlineExtraData::Accept( SwPaM& ) const +{ +} + +void SwRedlineExtraData::Reject( SwPaM& ) const +{ +} + +int SwRedlineExtraData::operator == ( const SwRedlineExtraData& ) const +{ + return FALSE; +} + + +SwRedlineExtraData_FmtColl::SwRedlineExtraData_FmtColl( const String& rColl, + USHORT nPoolFmtId, + const SfxItemSet* pItemSet ) + : sFmtNm( rColl ), nPoolId( nPoolFmtId ), pSet( 0 ) +{ + if( pItemSet && pItemSet->Count() ) + pSet = new SfxItemSet( *pItemSet ); +} + +SwRedlineExtraData_FmtColl::~SwRedlineExtraData_FmtColl() +{ + delete pSet; +} + +SwRedlineExtraData* SwRedlineExtraData_FmtColl::CreateNew() const +{ + return new SwRedlineExtraData_FmtColl( sFmtNm, nPoolId, pSet ); +} + +void SwRedlineExtraData_FmtColl::Reject( SwPaM& rPam ) const +{ + SwDoc* pDoc = rPam.GetDoc(); + +// was ist mit Undo ? ist das abgeschaltet ?? + SwTxtFmtColl* pColl = USHRT_MAX == nPoolId + ? pDoc->FindTxtFmtCollByName( sFmtNm ) + : pDoc->GetTxtCollFromPool( nPoolId ); + if( pColl ) + pDoc->SetTxtFmtColl( rPam, pColl, FALSE ); + + if( pSet ) + { + rPam.SetMark(); + SwPosition& rMark = *rPam.GetMark(); + SwTxtNode* pTNd = rMark.nNode.GetNode().GetTxtNode(); + if( pTNd ) + { + rMark.nContent.Assign( pTNd, pTNd->GetTxt().Len() ); + + if( pTNd->GetpSwAttrSet() ) + { + // nur die setzen, die nicht mehr vorhanden sind. Andere + // koennen jetzt veraendert drin stehen, aber die werden + // nicht angefasst. + SfxItemSet aTmp( *pSet ); + aTmp.Differentiate( *pTNd->GetpSwAttrSet() ); + pDoc->Insert( rPam, aTmp ); + } + else + pDoc->Insert( rPam, *pSet ); + } + rPam.DeleteMark(); + } +} + +int SwRedlineExtraData_FmtColl::operator == ( const SwRedlineExtraData& r) const +{ + const SwRedlineExtraData_FmtColl& rCmp = (SwRedlineExtraData_FmtColl&)r; + return sFmtNm == rCmp.sFmtNm && nPoolId == rCmp.nPoolId && + ( ( !pSet && !rCmp.pSet ) || + ( pSet && rCmp.pSet && *pSet == *rCmp.pSet ) ); +} + +void SwRedlineExtraData_FmtColl::SetItemSet( const SfxItemSet& rSet ) +{ + delete pSet; + if( rSet.Count() ) + pSet = new SfxItemSet( rSet ); + else + pSet = 0; +} + + +SwRedlineExtraData_Format::SwRedlineExtraData_Format( USHORT nW ) + : nWhich( nW ) +{ +} + + +SwRedlineExtraData* SwRedlineExtraData_Format::CreateNew() const +{ + return new SwRedlineExtraData_Format( nWhich ); +} + +void SwRedlineExtraData_Format::Reject( SwPaM& rPam ) const +{ + SwDoc* pDoc = rPam.GetDoc(); + + SwRedlineMode eOld = pDoc->GetRedlineMode(); + pDoc->SetRedlineMode_intern( eOld & ~(REDLINE_ON | REDLINE_IGNORE) ); + + // eigentlich muesste hier das Attribut zurueck gesetzt werden!!! + pDoc->Insert( rPam, *GetDfltAttr( nWhich ), SETATTR_DONTEXPAND ); + + pDoc->SetRedlineMode_intern( eOld ); +} + +int SwRedlineExtraData_Format::operator == ( const SwRedlineExtraData& rCmp ) const +{ + return nWhich == ((SwRedlineExtraData_Format&)rCmp).nWhich; +} + +/* */ + +SwRedlineData::SwRedlineData( SwRedlineType eT, USHORT nAut ) + : eType( eT ), pNext( 0 ), nAuthor( nAut ), pExtraData( 0 ), nSeqNo( 0 ) +{ + aStamp.SetSec( 0 ); + aStamp.Set100Sec( 0 ); +} + +SwRedlineData::SwRedlineData( const SwRedlineData& rCpy, BOOL bCpyNext ) + : nAuthor( rCpy.nAuthor ), eType( rCpy.eType ), aStamp( rCpy.aStamp ), + sComment( rCpy.sComment ), nSeqNo( rCpy.nSeqNo ), + pExtraData( rCpy.pExtraData ? rCpy.pExtraData->CreateNew() : 0 ), + pNext( (bCpyNext && rCpy.pNext) ? new SwRedlineData( *rCpy.pNext ) : 0 ) +{ +} + + // fuer sw3io: pNext geht in eigenen Besitz ueber! +SwRedlineData::SwRedlineData( SwRedlineType eT, USHORT nAut, const DateTime& rDT, + const String& rCmnt, SwRedlineData *pNxt, + SwRedlineExtraData* pData ) + : eType( eT ), pNext( pNxt ), nAuthor( nAut ), aStamp( rDT ), + sComment( rCmnt ), pExtraData( pData ), nSeqNo( 0 ) +{ +} + +SwRedlineData::~SwRedlineData() +{ + delete pExtraData; + delete pNext; +} + + // ExtraData wird kopiert, der Pointer geht also NICHT in den Besitz + // des RedlineObjectes! +void SwRedlineData::SetExtraData( const SwRedlineExtraData* pData ) +{ + delete pExtraData; + + if( pData ) + pExtraData = pData->CreateNew(); + else + pExtraData = 0; +} + +/* */ + +SwRedline::SwRedline( SwRedlineType eTyp, const SwPaM& rPam ) + : SwPaM( *rPam.GetMark(), *rPam.GetPoint() ), + pCntntSect( 0 ), + pRedlineData( new SwRedlineData( eTyp, GetDoc()->GetRedlineAuthor() ) ) +{ + bDelLastPara = bIsLastParaDelete = FALSE; + bIsVisible = TRUE; + if( !rPam.HasMark() ) + DeleteMark(); +} + +SwRedline::SwRedline( SwRedlineType eTyp, const SwPosition& rPos ) + : SwPaM( rPos ), + pCntntSect( 0 ), + pRedlineData( new SwRedlineData( eTyp, GetDoc()->GetRedlineAuthor() ) ) +{ + bDelLastPara = bIsLastParaDelete = FALSE; + bIsVisible = TRUE; +} + +SwRedline::SwRedline( const SwRedlineData& rData, const SwPaM& rPam ) + : SwPaM( *rPam.GetMark(), *rPam.GetPoint() ), + pCntntSect( 0 ), + pRedlineData( new SwRedlineData( rData )) +{ + bDelLastPara = bIsLastParaDelete = FALSE; + bIsVisible = TRUE; + if( !rPam.HasMark() ) + DeleteMark(); +} + +SwRedline::SwRedline( const SwRedlineData& rData, const SwPosition& rPos ) + : SwPaM( rPos ), + pCntntSect( 0 ), + pRedlineData( new SwRedlineData( rData )) +{ + bDelLastPara = bIsLastParaDelete = FALSE; + bIsVisible = TRUE; +} + +SwRedline::SwRedline( const SwRedline& rCpy ) + : SwPaM( *rCpy.GetMark(), *rCpy.GetPoint() ), + pCntntSect( 0 ), + pRedlineData( new SwRedlineData( *rCpy.pRedlineData )) +{ + bDelLastPara = bIsLastParaDelete = FALSE; + bIsVisible = TRUE; + if( !rCpy.HasMark() ) + DeleteMark(); +} + +SwRedline::~SwRedline() +{ + if( pCntntSect ) + { + // dann den Content Bereich loeschen + if( !GetDoc()->IsInDtor() ) + GetDoc()->DeleteSection( &pCntntSect->GetNode() ); + delete pCntntSect; + } + delete pRedlineData; +} + +// liegt eine gueltige Selektion vor? +BOOL SwRedline::HasValidRange() const +{ + const SwNode* pPtNd = &GetPoint()->nNode.GetNode(), + * pMkNd = &GetMark()->nNode.GetNode(); + if( pPtNd->FindStartNode() == pMkNd->FindStartNode() && + !pPtNd->FindStartNode()->IsTableNode() ) + return TRUE; +/* + if( ( pPtNd->IsStartNode() && pMkNd->IsEndNode() && + pMkNd->FindStartNode() == pPtNd ) || + ( pMkNd->IsStartNode() && pPtNd->IsEndNode() && + pPtNd->FindStartNode() == pMkNd ) ) + return TRUE; +*/ + return FALSE; +} + +void SwRedline::CallDisplayFunc( USHORT nLoop ) +{ + switch( REDLINE_SHOW_MASK & GetDoc()->GetRedlineMode() ) + { + case REDLINE_SHOW_INSERT | REDLINE_SHOW_DELETE: + Show( nLoop ); + break; + case REDLINE_SHOW_INSERT: + Hide( nLoop ); + break; + case REDLINE_SHOW_DELETE: + ShowOriginal( nLoop ); + break; + } +} + +void SwRedline::Show( USHORT nLoop ) +{ + if( 1 <= nLoop ) + { + SwDoc* pDoc = GetDoc(); + SwRedlineMode eOld = pDoc->GetRedlineMode(); + pDoc->SetRedlineMode_intern( eOld | REDLINE_IGNORE ); + BOOL bUndo = pDoc->DoesUndo(); + pDoc->DoUndo( FALSE ); + + switch( GetType() ) + { + case REDLINE_INSERT: // Inhalt wurde eingefuegt + bIsVisible = TRUE; + MoveFromSection(); + break; + + case REDLINE_DELETE: // Inhalt wurde geloescht + bIsVisible = TRUE; + MoveFromSection(); + break; + + case REDLINE_FORMAT: // Attributierung wurde angewendet + case REDLINE_TABLE: // TabellenStruktur wurde veraendert + InvalidateRange(); + break; + } + pDoc->SetRedlineMode_intern( eOld ); + pDoc->DoUndo( bUndo ); + } +} + +void SwRedline::Hide( USHORT nLoop ) +{ + SwDoc* pDoc = GetDoc(); + SwRedlineMode eOld = pDoc->GetRedlineMode(); + pDoc->SetRedlineMode_intern( eOld | REDLINE_IGNORE ); + BOOL bUndo = pDoc->DoesUndo(); + pDoc->DoUndo( FALSE ); + + switch( GetType() ) + { + case REDLINE_INSERT: // Inhalt wurde eingefuegt + bIsVisible = TRUE; + if( 1 <= nLoop ) + MoveFromSection(); + break; + + case REDLINE_DELETE: // Inhalt wurde geloescht + bIsVisible = FALSE; + switch( nLoop ) + { + case 0: MoveToSection(); break; + case 1: CopyToSection(); break; + case 2: DelCopyOfSection(); break; + } + break; + + case REDLINE_FORMAT: // Attributierung wurde angewendet + case REDLINE_TABLE: // TabellenStruktur wurde veraendert + if( 1 <= nLoop ) + InvalidateRange(); + break; + } + pDoc->SetRedlineMode_intern( eOld ); + pDoc->DoUndo( bUndo ); +} + +void SwRedline::ShowOriginal( USHORT nLoop ) +{ + SwDoc* pDoc = GetDoc(); + SwRedlineMode eOld = pDoc->GetRedlineMode(); + pDoc->SetRedlineMode_intern( eOld | REDLINE_IGNORE ); + BOOL bUndo = pDoc->DoesUndo(); + pDoc->DoUndo( FALSE ); + + // bestimme den Type, ist der erste auf Stack + for( SwRedlineData* pCur = pRedlineData; pCur->pNext; ) + pCur = pCur->pNext; + + switch( pCur->eType ) + { + case REDLINE_INSERT: // Inhalt wurde eingefuegt + bIsVisible = FALSE; + switch( nLoop ) + { + case 0: MoveToSection(); break; + case 1: CopyToSection(); break; + case 2: DelCopyOfSection(); break; + } + break; + + case REDLINE_DELETE: // Inhalt wurde geloescht + bIsVisible = TRUE; + if( 1 <= nLoop ) + MoveFromSection(); + break; + + case REDLINE_FORMAT: // Attributierung wurde angewendet + case REDLINE_TABLE: // TabellenStruktur wurde veraendert + if( 1 <= nLoop ) + InvalidateRange(); + break; + } + pDoc->SetRedlineMode_intern( eOld ); + pDoc->DoUndo( bUndo ); +} + + +void SwRedline::InvalidateRange() // das Layout anstossen +{ + ULONG nSttNd = GetMark()->nNode.GetIndex(), + nEndNd = GetPoint()->nNode.GetIndex(); + USHORT nSttCnt = GetMark()->nContent.GetIndex(), + nEndCnt = GetPoint()->nContent.GetIndex(); + + if( nSttNd > nEndNd || ( nSttNd == nEndNd && nSttCnt > nEndCnt )) + { + ULONG nTmp = nSttNd; nSttNd = nEndNd; nEndNd = nTmp; + nTmp = nSttCnt; nSttCnt = nEndCnt; nEndCnt = (USHORT)nTmp; + } + + SwUpdateAttr aHt( 0, 0, RES_FMT_CHG ); + SwNodes& rNds = GetDoc()->GetNodes(); + SwNode* pNd; + for( ULONG n = nSttNd; n <= nEndNd; ++n ) + if( ND_TEXTNODE == ( pNd = rNds[ n ] )->GetNodeType() ) + { + aHt.nStart = n == nSttNd ? nSttCnt : 0; + aHt.nEnd = n == nEndNd ? nEndCnt : ((SwTxtNode*)pNd)->GetTxt().Len(); + ((SwTxtNode*)pNd)->Modify( &aHt, &aHt ); + } +} + +void SwRedline::MoveToSection() +{ + if( !pCntntSect ) + { + const SwPosition* pStt = Start(), + * pEnd = pStt == GetPoint() ? GetMark() : GetPoint(); + + SwDoc* pDoc = GetDoc(); + SwPaM aPam( *pStt, *pEnd ); + SwCntntNode* pCSttNd = pStt->nNode.GetNode().GetCntntNode(); + SwCntntNode* pCEndNd = pEnd->nNode.GetNode().GetCntntNode(); + + BOOL bNoLastPara = FALSE; + + if( !pCSttNd ) + { + // damit die Indizies der anderen Redlines nicht mitverschoben + // werden, diese aufs Ende setzen (ist exclusive). + const SwRedlineTbl& rTbl = pDoc->GetRedlineTbl(); + for( USHORT n = 0; n < rTbl.Count(); ++n ) + { + SwRedline* pRedl = rTbl[ n ]; + if( pRedl->GetBound(TRUE) == *pStt ) + pRedl->GetBound(TRUE) = *pEnd; + if( pRedl->GetBound(FALSE) == *pStt ) + pRedl->GetBound(FALSE) = *pEnd; + } + } + + SwStartNode* pSttNd; + SwNodes& rNds = pDoc->GetNodes(); + if( pCSttNd || pCEndNd ) + { + SwTxtFmtColl* pColl = (pCSttNd && pCSttNd->IsTxtNode() ) + ? ((SwTxtNode*)pCSttNd)->GetTxtColl() + : (pCEndNd && pCEndNd->IsTxtNode() ) + ? ((SwTxtNode*)pCEndNd)->GetTxtColl() + : pDoc->GetTxtCollFromPool( + RES_POOLCOLL_STANDARD ); + + pSttNd = rNds.MakeTextSection( SwNodeIndex( rNds.GetEndOfRedlines() ), + SwNormalStartNode, pColl ); + SwTxtNode* pTxtNd = rNds[ pSttNd->GetIndex() + 1 ]->GetTxtNode(); + + SwNodeIndex aNdIdx( *pTxtNd ); + SwPosition aPos( aNdIdx, SwIndex( pTxtNd )); + if( pCSttNd && pCEndNd ) + pDoc->MoveAndJoin( aPam, aPos ); + else + { + if( pCSttNd && !pCEndNd ) + bDelLastPara = TRUE; + pDoc->Move( aPam, aPos ); + } + } + else + { + pSttNd = rNds.MakeEmptySection( SwNodeIndex( rNds.GetEndOfRedlines() ), + SwNormalStartNode ); + + SwPosition aPos( *pSttNd->EndOfSectionNode() ); + pDoc->Move( aPam, aPos ); + } + pCntntSect = new SwNodeIndex( *pSttNd ); + + if( pStt == GetPoint() ) + Exchange(); + + DeleteMark(); + } + else + InvalidateRange(); +} + +void SwRedline::CopyToSection() +{ + if( !pCntntSect ) + { + const SwPosition* pStt = Start(), + * pEnd = pStt == GetPoint() ? GetMark() : GetPoint(); + + SwCntntNode* pCSttNd = pStt->nNode.GetNode().GetCntntNode(); + SwCntntNode* pCEndNd = pEnd->nNode.GetNode().GetCntntNode(); + + SwStartNode* pSttNd; + SwDoc* pDoc = GetDoc(); + SwNodes& rNds = pDoc->GetNodes(); + + BOOL bSaveCopyFlag = pDoc->IsCopyIsMove(), + bSaveRdlMoveFlg = pDoc->IsRedlineMove(); + pDoc->SetCopyIsMove( TRUE ); + pDoc->SetRedlineMove( TRUE ); + + if( pCSttNd ) + { + SwTxtFmtColl* pColl = (pCSttNd && pCSttNd->IsTxtNode() ) + ? ((SwTxtNode*)pCSttNd)->GetTxtColl() + : pDoc->GetTxtCollFromPool( + RES_POOLCOLL_STANDARD ); + + pSttNd = rNds.MakeTextSection( SwNodeIndex( rNds.GetEndOfRedlines() ), + SwNormalStartNode, pColl ); + + SwNodeIndex aNdIdx( *pSttNd, 1 ); + SwTxtNode* pTxtNd = aNdIdx.GetNode().GetTxtNode(); + SwPosition aPos( aNdIdx, SwIndex( pTxtNd )); + pDoc->Copy( *this, aPos ); + + // JP 08.10.98: die Vorlage vom EndNode ggfs. mit uebernehmen + // - ist im Doc::Copy nicht erwuenscht + if( pCEndNd && pCEndNd != pCSttNd ) + { + SwCntntNode* pDestNd = aPos.nNode.GetNode().GetCntntNode(); + if( pDestNd ) + { + if( pDestNd->IsTxtNode() && pCEndNd->IsTxtNode() ) + ((SwTxtNode*)pCEndNd)->CopyCollFmt( + *(SwTxtNode*)pDestNd ); + else + pDestNd->ChgFmtColl( pCEndNd->GetFmtColl() ); + } + } + } + else + { + pSttNd = rNds.MakeEmptySection( SwNodeIndex( rNds.GetEndOfRedlines() ), + SwNormalStartNode ); + + if( pCEndNd ) + { + SwPosition aPos( *pSttNd->EndOfSectionNode() ); + pDoc->Copy( *this, aPos ); + } + else + { + SwNodeIndex aInsPos( *pSttNd->EndOfSectionNode() ); + SwNodeRange aRg( pStt->nNode, 0, pEnd->nNode, 1 ); + pDoc->CopyWithFlyInFly( aRg, aInsPos ); + } + } + pCntntSect = new SwNodeIndex( *pSttNd ); + + pDoc->SetCopyIsMove( bSaveCopyFlag ); + pDoc->SetRedlineMove( bSaveRdlMoveFlg ); + } +} + +void SwRedline::DelCopyOfSection() +{ + if( pCntntSect ) + { + const SwPosition* pStt = Start(), + * pEnd = pStt == GetPoint() ? GetMark() : GetPoint(); + + SwDoc* pDoc = GetDoc(); + SwPaM aPam( *pStt, *pEnd ); + SwCntntNode* pCSttNd = pStt->nNode.GetNode().GetCntntNode(); + SwCntntNode* pCEndNd = pEnd->nNode.GetNode().GetCntntNode(); + + if( !pCSttNd ) + { + // damit die Indizies der anderen Redlines nicht mitverschoben + // werden, diese aufs Ende setzen (ist exclusive). + const SwRedlineTbl& rTbl = pDoc->GetRedlineTbl(); + for( USHORT n = 0; n < rTbl.Count(); ++n ) + { + SwRedline* pRedl = rTbl[ n ]; + if( pRedl->GetBound(TRUE) == *pStt ) + pRedl->GetBound(TRUE) = *pEnd; + if( pRedl->GetBound(FALSE) == *pStt ) + pRedl->GetBound(FALSE) = *pEnd; + } + } + + SwNodes& rNds = pDoc->GetNodes(); + if( pCSttNd && pCEndNd ) + pDoc->DeleteAndJoin( aPam ); + else if( pCSttNd || pCEndNd ) + { + if( pCSttNd && !pCEndNd ) + bDelLastPara = TRUE; + pDoc->Delete( aPam ); + + if( bDelLastPara ) + { + SvPtrarr aBehindArr( 16, 16 ); + const SwRedlineTbl& rTbl = pDoc->GetRedlineTbl(); + USHORT n = rTbl.GetPos( this ); + for( BOOL bBreak = FALSE; !bBreak && n < rTbl.Count(); ++n ) + { + bBreak = TRUE; + if( rTbl[ n ]->GetBound(TRUE) == *pEnd ) + { + void* pTmp = &rTbl[ n ]->GetBound(TRUE); + aBehindArr.Insert( pTmp, aBehindArr.Count()); + bBreak = FALSE; + } + if( rTbl[ n ]->GetBound(FALSE) == *pEnd ) + { + void* pTmp = &rTbl[ n ]->GetBound(FALSE); + aBehindArr.Insert( pTmp, aBehindArr.Count() ); + bBreak = FALSE; + } + } + + SwPosition aEnd( *pEnd ); + + aPam.GetPoint()->nContent.Assign( 0, 0 ); + aPam.GetMark()->nContent.Assign( 0, 0 ); + aPam.DeleteMark(); + pDoc->DelFullPara( aPam ); + + for( n = 0; n < aBehindArr.Count(); ++n ) + *(SwPosition*)aBehindArr[ n ] = aEnd; + } + } + else + pDoc->Delete( aPam ); + + if( pStt == GetPoint() ) + Exchange(); + + DeleteMark(); + } +} + +void SwRedline::MoveFromSection() +{ + if( pCntntSect ) + { + SwDoc* pDoc = GetDoc(); + const SwRedlineTbl& rTbl = pDoc->GetRedlineTbl(); + SvPtrarr aBeforeArr( 16, 16 ), aBehindArr( 16, 16 ); + USHORT nMyPos = rTbl.GetPos( this ); + ASSERT( this, "this nicht im Array?" ); + register BOOL bBreak = FALSE; + + for( USHORT n = nMyPos+1; !bBreak && n < rTbl.Count(); ++n ) + { + bBreak = TRUE; + if( rTbl[ n ]->GetBound(TRUE) == *GetPoint() ) + { + void* pTmp = &rTbl[ n ]->GetBound(TRUE); + aBehindArr.Insert( pTmp, aBehindArr.Count()); + bBreak = FALSE; + } + if( rTbl[ n ]->GetBound(FALSE) == *GetPoint() ) + { + void* pTmp = &rTbl[ n ]->GetBound(FALSE); + aBehindArr.Insert( pTmp, aBehindArr.Count() ); + bBreak = FALSE; + } + } + for( bBreak = FALSE, n = nMyPos; !bBreak && n ; ) + { + --n; + bBreak = TRUE; + if( rTbl[ n ]->GetBound(TRUE) == *GetPoint() ) + { + void* pTmp = &rTbl[ n ]->GetBound(TRUE); + aBeforeArr.Insert( pTmp, aBeforeArr.Count() ); + bBreak = FALSE; + } + if( rTbl[ n ]->GetBound(FALSE) == *GetPoint() ) + { + void* pTmp = &rTbl[ n ]->GetBound(FALSE); + aBeforeArr.Insert( pTmp, aBeforeArr.Count() ); + bBreak = FALSE; + } + } + + { + BOOL bAddFlag = TRUE; + SwPaM aPam( pCntntSect->GetNode(), + *pCntntSect->GetNode().EndOfSectionNode(), 1, + ( bDelLastPara ? -2 : -1 ) ); + SwCntntNode* pCNd = aPam.GetCntntNode(); + if( pCNd ) + aPam.GetPoint()->nContent.Assign( pCNd, pCNd->Len() ); + else + aPam.GetPoint()->nNode++; + + SwFmtColl* pColl = pCNd && aPam.GetPoint()->nNode != + aPam.GetMark()->nNode + ? pCNd->GetFmtColl() : 0; + + SwNodeIndex aNdIdx( GetPoint()->nNode, -1 ); + USHORT nPos = GetPoint()->nContent.GetIndex(); + + SwPosition aPos( *GetPoint() ); + pDoc->Move( aPam, aPos, DOC_MOVEALLFLYS ); + SetMark(); + *GetPoint() = aPos; + GetMark()->nNode = aNdIdx.GetIndex() + 1; + pCNd = GetMark()->nNode.GetNode().GetCntntNode(); + GetMark()->nContent.Assign( pCNd, nPos ); + + if( bDelLastPara ) + { + GetPoint()->nNode++; + GetPoint()->nContent.Assign( pCNd = GetCntntNode(), 0 ); + bDelLastPara = FALSE; + } + else if( pColl ) + pCNd = GetCntntNode(); + + if( pColl && pCNd ) + pCNd->ChgFmtColl( pColl ); + } + pDoc->DeleteSection( &pCntntSect->GetNode() ); + delete pCntntSect, pCntntSect = 0; + + for( n = 0; n < aBeforeArr.Count(); ++n ) + *(SwPosition*)aBeforeArr[ n ] = *GetMark(); + for( n = 0; n < aBehindArr.Count(); ++n ) + *(SwPosition*)aBehindArr[ n ] = *GetPoint(); + } + else + InvalidateRange(); +} + +// fuers Undo +void SwRedline::SetContentIdx( const SwNodeIndex* pIdx ) +{ + if( pIdx && !pCntntSect ) + { + pCntntSect = new SwNodeIndex( *pIdx ); + bIsVisible = FALSE; + } + else if( !pIdx && pCntntSect ) + { + delete pCntntSect, pCntntSect = 0; + bIsVisible = FALSE; + } +#ifndef PRODUCT + else + ASSERT( !this, "das ist keine gueltige Operation" ); +#endif +} + +BOOL SwRedline::CanCombine( const SwRedline& rRedl ) const +{ + return IsVisible() && rRedl.IsVisible() && + pRedlineData->CanCombine( *rRedl.pRedlineData ); +} + +void SwRedline::PushData( const SwRedline& rRedl, BOOL bOwnAsNext ) +{ +// SwRedlineData* pNew = new SwRedlineData( rRedl.GetType(), +// rRedl.GetAuthor() ); + SwRedlineData* pNew = new SwRedlineData( *rRedl.pRedlineData, FALSE ); + if( bOwnAsNext ) + { + pNew->pNext = pRedlineData; + pRedlineData = pNew; + } + else + { + pNew->pNext = pRedlineData->pNext; + pRedlineData->pNext = pNew; + } +} + +BOOL SwRedline::PopData() +{ + if( !pRedlineData->pNext ) + return FALSE; + SwRedlineData* pCur = pRedlineData; + pRedlineData = pCur->pNext; + pCur->pNext = 0; + delete pCur; + return TRUE; +} + +USHORT SwRedline::GetStackCount() const +{ + USHORT nRet = 1; + for( SwRedlineData* pCur = pRedlineData; pCur->pNext; ++nRet ) + pCur = pCur->pNext; + return nRet; +} + +USHORT SwRedline::GetAuthor( USHORT nPos ) const +{ + for( SwRedlineData* pCur = pRedlineData; nPos && pCur->pNext; --nPos ) + pCur = pCur->pNext; + ASSERT( !nPos, "Pos angabe ist zu gross" ); + return pCur->nAuthor; +} + +const String& SwRedline::GetAuthorString( USHORT nPos ) const +{ + for( SwRedlineData* pCur = pRedlineData; nPos && pCur->pNext; --nPos ) + pCur = pCur->pNext; + ASSERT( !nPos, "Pos angabe ist zu gross" ); + return SW_MOD()->GetRedlineAuthor(pCur->nAuthor); +} + +const DateTime& SwRedline::GetTimeStamp( USHORT nPos ) const +{ + for( SwRedlineData* pCur = pRedlineData; nPos && pCur->pNext; --nPos ) + pCur = pCur->pNext; + ASSERT( !nPos, "Pos angabe ist zu gross" ); + return pCur->aStamp; +} + +SwRedlineType SwRedline::GetRealType( USHORT nPos ) const +{ + for( SwRedlineData* pCur = pRedlineData; nPos && pCur->pNext; --nPos ) + pCur = pCur->pNext; + ASSERT( !nPos, "Pos angabe ist zu gross" ); + return pCur->eType; +} + +const String& SwRedline::GetComment( USHORT nPos ) const +{ + for( SwRedlineData* pCur = pRedlineData; nPos && pCur->pNext; --nPos ) + pCur = pCur->pNext; + ASSERT( !nPos, "Pos angabe ist zu gross" ); + return pCur->sComment; +} + +int SwRedline::operator==( const SwRedline& rCmp ) const +{ + return this == &rCmp; +} + +int SwRedline::operator<( const SwRedline& rCmp ) const +{ + BOOL bLower = *Start() < *rCmp.Start(); + if( !bLower && *Start() == *rCmp.Start() && !HasMark() ) + bLower = TRUE; + return bLower; +} + + + + diff --git a/sw/source/core/doc/docsort.cxx b/sw/source/core/doc/docsort.cxx new file mode 100644 index 000000000000..f0414cc11b6a --- /dev/null +++ b/sw/source/core/doc/docsort.cxx @@ -0,0 +1,1060 @@ +/************************************************************************* + * + * $RCSfile: docsort.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:15 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _HINTIDS_HXX +#include +#endif + +#ifndef _APP_HXX //autogen +#include +#endif +#ifndef _SYSTEM_HXX //autogen +#include +#endif +#ifndef _INTN_HXX //autogen +#include +#endif +#ifndef _DOCARY_HXX +#include +#endif +#ifndef _SVX_LANGITEM_HXX //autogen +#include +#endif + +#ifndef _FMTANCHR_HXX //autogen +#include +#endif +#ifndef _FRMFMT_HXX //autogen +#include +#endif +#ifndef _DOC_HXX +#include +#endif +#ifndef _NODE_HXX +#include +#endif +#ifndef _PAM_HXX +#include +#endif +#ifndef _NDTXT_HXX +#include +#endif +#ifndef _SWTABLE_HXX +#include +#endif +#ifndef _SWUNDO_HXX +#include +#endif +#ifndef _SORTOPT_HXX +#include +#endif +#ifndef _DOCSORT_HXX +#include +#endif +#ifndef _UNDOBJ_HXX +#include +#endif +#ifndef _TBLSEL_HXX +#include +#endif +#ifndef _HINTS_HXX +#include +#endif +#ifndef _CELLATR_HXX +#include +#endif +#ifndef _REDLINE_HXX +#include +#endif + +#ifdef DEBUG +//nur zum debugen +#ifndef _CELLATR_HXX +#include +#endif +#endif + +SwSortOptions* SwSortElement::pOptions = 0; +SwDoc* SwSortElement::pDoc = 0; +const FlatFndBox* SwSortElement::pBox = 0; +International* SwSortElement::pIntl = 0; + +SV_IMPL_OP_PTRARR_SORT( SwSortElements, SwSortElementPtr ); + + +/*-------------------------------------------------------------------- + Beschreibung: Ein Sortierelement fuers Sort konstruieren + --------------------------------------------------------------------*/ + + +void SwSortElement::Init( SwDoc* pD, const SwSortOptions& rOpt, + FlatFndBox* pFltBx ) +{ + ASSERT( !pDoc && !pOptions && !pBox, "wer hat das Finit vergessen?" ); + pDoc = pD; + pOptions = new SwSortOptions( rOpt ); + pBox = pFltBx; + pIntl = (International*)&Application::GetAppInternational(); + LanguageType eLang = ((const SvxLanguageItem&)pDoc->GetAttrPool(). + GetDefaultItem(RES_CHRATR_LANGUAGE )).GetLanguage(); + + if( !( eLang == ::GetSystemLanguage() && + LANGUAGE_SYSTEM == pIntl->GetLanguage() ) && + eLang != pIntl->GetLanguage() ) + pIntl = new International( eLang ); +} + + +void SwSortElement::Finit() +{ + delete pOptions, pOptions = 0; + pDoc = 0; + pBox = 0; + + if( pIntl != &Application::GetAppInternational() ) + delete pIntl; + pIntl = 0; +} + + +SwSortElement::~SwSortElement() +{ +} + + +double SwSortElement::StrToDouble( const String& rStr ) const +{ + String aStr( rStr ); + sal_Unicode cTSep = pIntl->GetNumThousandSep(); + sal_Unicode cDSep = pIntl->GetNumDecimalSep(); + register sal_Unicode c; + + for( xub_StrLen i = 0; i < aStr.Len(); ++i ) + if( cTSep == ( c = aStr.GetChar( i ) ) ) + aStr.Erase( i--, 1 ); + else if( cDSep == c || ',' == c ) + aStr.SetChar( i, '.' ); + + return aStr.ToDouble(); +} + +/*-------------------------------------------------------------------- + Beschreibung: Operatoren zum Vergleichen + --------------------------------------------------------------------*/ + + +BOOL SwSortElement::operator==(const SwSortElement& rCmp) +{ + return FALSE; +} + +/*-------------------------------------------------------------------- + Beschreibung: Kleiner-Operator fuers sortieren + --------------------------------------------------------------------*/ + + +BOOL SwSortElement::operator<(const SwSortElement& rCmp) +{ + + // der eigentliche Vergleich + // + for(USHORT nKey = 0; nKey < pOptions->aKeys.Count(); ++nKey) + { + const SwSortElement *pOrig, *pCmp; + + const SwSortKey* pSrtKey = pOptions->aKeys[ nKey ]; + if( pSrtKey->eSortOrder == SRT_ASCENDING ) + pOrig = this, pCmp = &rCmp; + else + pOrig = &rCmp, pCmp = this; + + if( SRT_NUMERIC == pSrtKey->eSortKeyType ) + { + double n1 = pOrig->GetValue( nKey ); + double n2 = pCmp->GetValue( nKey ); + + if( n1 == n2 ) + continue; + + return n1 < n2; + } + else + { + StringCompare eCmp = pIntl->Compare( pOrig->GetKey( nKey ), + pCmp->GetKey( nKey )); + if( COMPARE_EQUAL == eCmp ) + continue; + + return COMPARE_LESS == eCmp; + } + } + return FALSE; +} + +double SwSortElement::GetValue( USHORT nKey ) const +{ + return StrToDouble( GetKey( nKey )); +} + +/*-------------------------------------------------------------------- + Beschreibung: SortierElemente fuer Text + --------------------------------------------------------------------*/ + + +SwSortTxtElement::SwSortTxtElement( const SwNodeIndex& rPos ) + : aPos( rPos ), + nOrg( rPos.GetIndex() ) +{ +} + + +SwSortTxtElement::~SwSortTxtElement() +{ +} + + +/*-------------------------------------------------------------------- + Beschreibung: Key ermitteln + --------------------------------------------------------------------*/ + + +String SwSortTxtElement::GetKey(USHORT nId) const +{ + SwTxtNode* pTxtNd = aPos.GetNode().GetTxtNode(); + if( !pTxtNd ) + return aEmptyStr; + + // fuer TextNodes + const String& rStr = pTxtNd->GetTxt(); + + sal_Unicode nDeli = pOptions->nDeli; + USHORT nDCount = pOptions->aKeys[nId]->nColumnId, i = 1; + xub_StrLen nStart = 0; + + // Den Delimitter suchen + while( nStart != STRING_NOTFOUND && i < nDCount) + if( STRING_NOTFOUND != ( nStart = rStr.Search( nDeli, nStart ) ) ) + { + nStart++; + i++; + } + + // naechsten Delimitter gefunden oder Ende des Strings und Kopieren + xub_StrLen nEnd = rStr.Search( nDeli, nStart+1 ); + return rStr.Copy( nStart, nEnd-nStart ); +} + + +/*-------------------------------------------------------------------- + Beschreibung: Sortier-Elemente fuer Tabellen + --------------------------------------------------------------------*/ + +SwSortBoxElement::SwSortBoxElement( USHORT nRC ) + : nRow( nRC ) +{ +} + + +SwSortBoxElement::~SwSortBoxElement() +{ +} + +/*-------------------------------------------------------------------- + Beschreibung: Schluessel zu einer Zelle ermitteln + --------------------------------------------------------------------*/ + + +String SwSortBoxElement::GetKey(USHORT nKey) const +{ + const _FndBox* pFndBox; + USHORT nCol = pOptions->aKeys[nKey]->nColumnId-1; + + if( SRT_ROWS == pOptions->eDirection ) + pFndBox = pBox->GetBox(nCol, nRow); // Zeilen sortieren + else + pFndBox = pBox->GetBox(nRow, nCol); // Spalten sortieren + + // Den Text rausfieseln + String aRetStr; + if( pFndBox ) + { // StartNode holen und ueberlesen + const SwTableBox* pBox = pFndBox->GetBox(); + ASSERT(pBox, "Keine atomare Box"); + + if( pBox->GetSttNd() ) + { + // ueber alle TextNodes der Box + const SwNode *pNd = 0, *pEndNd = pBox->GetSttNd()->EndOfSectionNode(); + for( ULONG nIdx = pBox->GetSttIdx() + 1; pNd != pEndNd; ++nIdx ) + if( ( pNd = pDoc->GetNodes()[ nIdx ])->IsTxtNode() ) + aRetStr += ((SwTxtNode*)pNd)->GetTxt(); + } + } + return aRetStr; +} + +double SwSortBoxElement::GetValue( USHORT nKey ) const +{ + const _FndBox* pFndBox; + USHORT nCol = pOptions->aKeys[nKey]->nColumnId-1; + + if( SRT_ROWS == pOptions->eDirection ) + pFndBox = pBox->GetBox(nCol, nRow); // Zeilen sortieren + else + pFndBox = pBox->GetBox(nRow, nCol); // Spalten sortieren + + double aVal; + if( pFndBox ) + aVal = pFndBox->GetBox()->GetFrmFmt()->GetTblBoxValue().GetValue(); + else + aVal = 0; + + return aVal; +} + +/*-------------------------------------------------------------------- + Beschreibung: Text sortieren im Document + --------------------------------------------------------------------*/ + + +BOOL SwDoc::SortText(const SwPaM& rPaM, const SwSortOptions& rOpt) +{ + // pruefen ob Rahmen im Text + const SwPosition *pStart = rPaM.Start(), *pEnd = rPaM.End(); + // Index auf den Start der Selektion + + SwFrmFmt* pFmt; + const SwFmtAnchor* pAnchor; + const SwPosition* pAPos; + + for( USHORT n = 0; n < GetSpzFrmFmts()->Count(); ++n ) + { + pFmt = (SwFrmFmt*)(*GetSpzFrmFmts())[n]; + pAnchor = &pFmt->GetAnchor(); + + if( FLY_AT_CNTNT == pAnchor->GetAnchorId() && + 0 != (pAPos = pAnchor->GetCntntAnchor() ) && + pStart->nNode <= pAPos->nNode && pAPos->nNode <= pEnd->nNode ) + return FALSE; + } + + // pruefe ob nur TextNodes in der Selection liegen + { + register ULONG nStart = pStart->nNode.GetIndex(), + nEnd = pEnd->nNode.GetIndex(); + while( nStart <= nEnd ) + // Iterieren ueber einen selektierten Bereich + if( !GetNodes()[ nStart++ ]->IsTxtNode() ) + return FALSE; + } + + BOOL bUndo = DoesUndo(); + if( bUndo ) + StartUndo( UNDO_START ); + + SwPaM* pRedlPam = 0; + SwUndoRedlineSort* pRedlUndo = 0; + SwUndoSort* pUndoSort = 0; + + if( IsRedlineOn() || (!IsIgnoreRedline() && pRedlineTbl->Count() )) + { + pRedlPam = new SwPaM( pStart->nNode, pEnd->nNode, -1, 1 ); + SwCntntNode* pCNd = pRedlPam->GetCntntNode( FALSE ); + if( pCNd ) + pRedlPam->GetMark()->nContent = pCNd->Len(); + + if( IsRedlineOn() && !IsShowOriginal( GetRedlineMode() ) ) + { + if( bUndo ) + { + pRedlUndo = new SwUndoRedlineSort( rPaM, rOpt ); + DoUndo( FALSE ); + } + // erst den Bereich kopieren, dann + SwNodeIndex aEndIdx( pEnd->nNode, 1 ); + SwNodeRange aRg( pStart->nNode, aEndIdx ); + GetNodes()._Copy( aRg, aEndIdx ); + + // Bereich neu ist von pEnd->nNode+1 bis aEndIdx + DeleteRedline( *pRedlPam ); + + pRedlPam->GetMark()->nNode.Assign( pEnd->nNode.GetNode(), 1 ); + pCNd = pRedlPam->GetCntntNode( FALSE ); + pRedlPam->GetMark()->nContent.Assign( pCNd, 0 ); + + pRedlPam->GetPoint()->nNode.Assign( aEndIdx.GetNode() ); + pCNd = pRedlPam->GetCntntNode( TRUE ); + xub_StrLen nCLen = 0; + if( !pCNd && + 0 != (pCNd = GetNodes()[ aEndIdx.GetIndex()-1 ]->GetCntntNode())) + { + nCLen = pCNd->Len(); + pRedlPam->GetPoint()->nNode.Assign( *pCNd ); + } + pRedlPam->GetPoint()->nContent.Assign( pCNd, nCLen ); + + if( pRedlUndo ) + pRedlUndo->SetValues( rPaM ); + } + else + { + DeleteRedline( *pRedlPam ); + delete pRedlPam, pRedlPam = 0; + } + } + + SwNodeIndex aStart(pStart->nNode); + SwSortElement::Init( this, rOpt ); + SwSortElements aSortArr; + while( aStart <= pEnd->nNode ) + { + // Iterieren ueber einen selektierten Bereich + SwSortTxtElement* pSE = new SwSortTxtElement( aStart ); + aSortArr.Insert(pSE); + aStart++; + } + + // Und jetzt der Akt: Verschieben von Nodes und immer schoen auf UNDO + // achten + // + ULONG nBeg = pStart->nNode.GetIndex(), nEnd = aStart.GetIndex(); + SwNodeRange aRg( aStart, aStart ); + + if( bUndo && !pRedlUndo ) + AppendUndo( pUndoSort = new SwUndoSort( rPaM, rOpt ) ); + + DoUndo( FALSE ); + + for( n = 0; n < aSortArr.Count(); ++n ) + { + SwSortTxtElement* pBox = (SwSortTxtElement*)aSortArr[n]; + aStart = nBeg + n; + aRg.aStart = pBox->aPos.GetIndex(); + aRg.aEnd = aRg.aStart.GetIndex() + 1; + + // Nodes verschieben + Move( aRg, aStart ); + + // Undo Verschiebungen einpflegen + if(pUndoSort) + pUndoSort->Insert(pBox->nOrg, nBeg + n); + } + // Alle Elemente aus dem SortArray loeschen + aSortArr.DeleteAndDestroy(0, aSortArr.Count()); + SwSortElement::Finit(); + + if( pRedlPam ) + { + if( pRedlUndo ) + { + pRedlUndo->SetSaveRange( *pRedlPam ); + AppendUndo( pRedlUndo ); + } + + // nBeg ist der Start vom sortierten Bereich + SwNodeIndex aSttIdx( GetNodes(), nBeg ); + + // der Kopierte Bereich ist das Geloeschte + AppendRedline( new SwRedline( REDLINE_DELETE, *pRedlPam )); + + // das sortierte ist das Eingefuegte + pRedlPam->GetPoint()->nNode = aSttIdx; + SwCntntNode* pCNd = aSttIdx.GetNode().GetCntntNode(); + pRedlPam->GetPoint()->nContent.Assign( pCNd, 0 ); + + AppendRedline( new SwRedline( REDLINE_INSERT, *pRedlPam )); + + if( pRedlUndo ) + pRedlUndo->SetOffset( aSttIdx ); + + delete pRedlPam, pRedlPam = 0; + } + DoUndo( bUndo ); + if( bUndo ) + EndUndo( UNDO_END ); + + return TRUE; +} + +/*-------------------------------------------------------------------- + Beschreibung: Tabelle sortieren im Document + --------------------------------------------------------------------*/ + +BOOL SwDoc::SortTbl(const SwSelBoxes& rBoxes, const SwSortOptions& rOpt) +{ + // uebers SwDoc fuer Undo !! + ASSERT( rBoxes.Count(), "keine gueltige Box-Liste" ); + SwTableNode* pTblNd = (SwTableNode*)rBoxes[0]->GetSttNd()->FindTableNode(); + if( !pTblNd ) + return FALSE; + + // Auf gehts sortieren + // suche alle Boxen / Lines + _FndBox aFndBox( 0, 0 ); + { + _FndPara aPara( rBoxes, &aFndBox ); + pTblNd->GetTable().GetTabLines().ForEach( &_FndLineCopyCol, &aPara );; + } + + if(!aFndBox.GetLines().Count()) + return FALSE; + + if( !IsIgnoreRedline() && GetRedlineTbl().Count() ) + DeleteRedline( *pTblNd ); + + USHORT nStart = 0; + if(pTblNd->GetTable().IsHeadlineRepeat() && rOpt.eDirection == SRT_ROWS) + { + // Das ist die Kopfzeile + SwTableLine * pHeadLine = pTblNd->GetTable().GetTabLines()[0]; + + // Oberste seleketierte Zeile + _FndLines& rLines = aFndBox.GetLines(); + + while(nStart < rLines.Count() ) + { + // Verschachtelung durch Split Merge beachten, + // die oberste rausholen + SwTableLine* pLine = rLines[nStart]->GetLine(); + while ( pLine->GetUpper() ) + pLine = pLine->GetUpper()->GetUpper(); + + if( pLine == pHeadLine) + nStart++; + else + break; + } + // Alle selektierten in der HeaderLine ? -> kein Offset + if(nStart == rLines.Count()) + nStart = 0; + } + + // umschalten auf relative Formeln + SwTableFmlUpdate aMsgHnt( &pTblNd->GetTable() ); + aMsgHnt.eFlags = TBL_RELBOXNAME; + UpdateTblFlds( &aMsgHnt ); + + // Tabelle als flache Array-Struktur + FlatFndBox aFlatBox(this, aFndBox); + + if(!aFlatBox.IsSymmetric()) + return FALSE; + + // MIB 9.7.97: HTML-Layout loeschen + pTblNd->GetTable().SetHTMLTableLayout( 0 ); + + // loesche die Frames der Tabelle + pTblNd->DelFrms(); + // und dann noch fuers Chart die Daten sichern + aFndBox.SaveChartData( pTblNd->GetTable() ); + + // Redo loeschen bevor Undo + BOOL bUndo = DoesUndo(); + SwUndoSort* pUndoSort = 0; + if(bUndo) + { + ClearRedo(); + pUndoSort = new SwUndoSort( rBoxes[0]->GetSttIdx(), + rBoxes[rBoxes.Count()-1]->GetSttIdx(), + *pTblNd, rOpt, aFlatBox.HasItemSets() ); + AppendUndo(pUndoSort); + DoUndo(FALSE); + } + + // SchluesselElemente einsortieren + USHORT nCount = (rOpt.eDirection == SRT_ROWS) ? + aFlatBox.GetRows() : aFlatBox.GetCols(); + + // SortList nach Schluessel sortieren + SwSortElement::Init( this, rOpt, &aFlatBox ); + SwSortElements aSortList; + + // wenn die HeaderLine wiederholt wird und die + // Zeilen sortiert werden 1.Zeile nicht mitsortieren + + for(USHORT i=nStart; i < nCount; ++i) + { + SwSortBoxElement* pEle = new SwSortBoxElement( i ); + aSortList.Insert(pEle); + } + + SwNodeIndex aBehindIdx( *pTblNd->EndOfSectionNode()); + GetNodes().GoNext( &aBehindIdx ); // Index in Cntnt, hinter der Tabelle + + // nach Sortierung verschieben + SwMovedBoxes aMovedList; + for(i=0; i < aSortList.Count(); ++i) + { + SwSortBoxElement* pBox = (SwSortBoxElement*)aSortList[i]; + if(rOpt.eDirection == SRT_ROWS) + MoveRow(this, aFlatBox, pBox->nRow, i + nStart, aMovedList, pUndoSort); + else + MoveCol(this, aFlatBox, pBox->nRow, i + nStart, aMovedList, pUndoSort); + } + + // Neue Frames erzeugen + pTblNd->MakeFrms( &aBehindIdx ); + aFndBox.RestoreChartData( pTblNd->GetTable() ); + + // Alle Elemente aus dem SortArray loeschen + aSortList.DeleteAndDestroy( 0, aSortList.Count() ); + SwSortElement::Finit(); + + // Undo wieder aktivieren + DoUndo(bUndo); + + SetModified(); + return TRUE; +} + +/*-------------------------------------------------------------------- + Beschreibung: Zeilenweise verschieben + --------------------------------------------------------------------*/ + + +void MoveRow(SwDoc* pDoc, const FlatFndBox& rBox, USHORT nS, USHORT nT, + SwMovedBoxes& rMovedList, SwUndoSort* pUD) +{ + for( USHORT i=0; i < rBox.GetCols(); ++i ) + { // Alte Zellen-Pos bestimmen und merken + const _FndBox* pSource = rBox.GetBox(i, nS); + + // neue Zellen-Pos + const _FndBox* pTarget = rBox.GetBox(i, nT); + + const SwTableBox* pT = pTarget->GetBox(); + const SwTableBox* pS = pSource->GetBox(); + + BOOL bMoved = rMovedList.GetPos(pT) != USHRT_MAX; + + // und verschieben + MoveCell(pDoc, pS, pT, bMoved, pUD); + + rMovedList.Insert(pS, rMovedList.Count() ); + + if( pS != pT ) + { + SwFrmFmt* pTFmt = (SwFrmFmt*)pT->GetFrmFmt(); + const SfxItemSet* pSSet = rBox.GetItemSet( i, nS ); + + if( pSSet || + SFX_ITEM_SET == pTFmt->GetItemState( RES_BOXATR_FORMAT ) || + SFX_ITEM_SET == pTFmt->GetItemState( RES_BOXATR_FORMULA ) || + SFX_ITEM_SET == pTFmt->GetItemState( RES_BOXATR_VALUE ) ) + { + pTFmt = ((SwTableBox*)pT)->ClaimFrmFmt(); + pTFmt->LockModify(); + if( pTFmt->ResetAttr( RES_BOXATR_FORMAT, RES_BOXATR_VALUE ) ) + pTFmt->ResetAttr( RES_VERT_ORIENT ); + + if( pSSet ) + pTFmt->SetAttr( *pSSet ); + pTFmt->UnlockModify(); + } + } + } +} + +/*-------------------------------------------------------------------- + Beschreibung: Spaltenweise verschieben + --------------------------------------------------------------------*/ + + +void MoveCol(SwDoc* pDoc, const FlatFndBox& rBox, USHORT nS, USHORT nT, + SwMovedBoxes& rMovedList, SwUndoSort* pUD) +{ + for(USHORT i=0; i < rBox.GetRows(); ++i) + { // Alte Zellen-Pos bestimmen und merken + const _FndBox* pSource = rBox.GetBox(nS, i); + + // neue Zellen-Pos + const _FndBox* pTarget = rBox.GetBox(nT, i); + + // und verschieben + const SwTableBox* pT = pTarget->GetBox(); + const SwTableBox* pS = pSource->GetBox(); + + // und verschieben + BOOL bMoved = rMovedList.GetPos(pT) != USHRT_MAX; + MoveCell(pDoc, pS, pT, bMoved, pUD); + + rMovedList.Insert(pS, rMovedList.Count() ); + + if( pS != pT ) + { + SwFrmFmt* pTFmt = (SwFrmFmt*)pT->GetFrmFmt(); + const SfxItemSet* pSSet = rBox.GetItemSet( nS, i ); + + if( pSSet || + SFX_ITEM_SET == pTFmt->GetItemState( RES_BOXATR_FORMAT ) || + SFX_ITEM_SET == pTFmt->GetItemState( RES_BOXATR_FORMULA ) || + SFX_ITEM_SET == pTFmt->GetItemState( RES_BOXATR_VALUE ) ) + { + pTFmt = ((SwTableBox*)pT)->ClaimFrmFmt(); + pTFmt->LockModify(); + if( pTFmt->ResetAttr( RES_BOXATR_FORMAT, RES_BOXATR_VALUE ) ) + pTFmt->ResetAttr( RES_VERT_ORIENT ); + + if( pSSet ) + pTFmt->SetAttr( *pSSet ); + pTFmt->UnlockModify(); + } + } + } +} + +/*-------------------------------------------------------------------- + Beschreibung: Eine einzelne Zelle verschieben + --------------------------------------------------------------------*/ + + +void MoveCell(SwDoc* pDoc, const SwTableBox* pSource, const SwTableBox* pTar, + BOOL bMovedBefore, SwUndoSort* pUD) +{ + ASSERT(pSource && pTar,"Fehlende Quelle oder Ziel"); + + if(pSource == pTar) + return; + + if(pUD) + pUD->Insert( pSource->GetName(), pTar->GetName() ); + + // Pam Quelle auf den ersten ContentNode setzen + SwNodeRange aRg( *pSource->GetSttNd(), 0, *pSource->GetSttNd() ); + SwNode* pNd = pDoc->GetNodes().GoNext( &aRg.aStart ); + + // wurde die Zelle (Source) nicht verschoben + // -> einen Leer-Node einfuegen und den Rest verschieben + // ansonsten steht der Mark auf dem ersten Content-Node + if( pNd->StartOfSectionNode() == pSource->GetSttNd() ) + pNd = pDoc->GetNodes().MakeTxtNode( aRg.aStart, + (SwTxtFmtColl*)pDoc->GetDfltTxtFmtColl() ); + aRg.aEnd = *pNd->EndOfSectionNode(); + + // Ist das Ziel leer(1 leerer Node vorhanden) + // -> diesen loeschen und move + // Ziel + SwNodeIndex aTar( *pTar->GetSttNd() ); + pNd = pDoc->GetNodes().GoNext( &aTar ); // naechsten ContentNode + ULONG nCount = pNd->EndOfSectionIndex() - pNd->StartOfSectionIndex(); + + BOOL bDelFirst = FALSE; + if( nCount == 2 ) + { + ASSERT( pNd->GetCntntNode(), "Kein ContentNode"); + bDelFirst = !pNd->GetCntntNode()->Len() && bMovedBefore; + } + + if(!bDelFirst) + { // Es besteht schon Inhalt -> alter I n h a l t Section Down + SwNodeRange aRgTar( aTar.GetNode(), 0, *pNd->EndOfSectionNode() ); + pDoc->GetNodes().SectionDown( &aRgTar ); + } + + // Einfuegen der Source + SwNodeIndex aIns( *pTar->GetSttNd()->EndOfSectionNode() ); + pDoc->Move( aRg, aIns ); + + // Falls erster Node leer -> weg damit + if(bDelFirst) + pDoc->GetNodes().Delete( aTar, 1 ); +} + +/*-------------------------------------------------------------------- + Beschreibung: Zweidimensionales Array aus FndBoxes generieren + --------------------------------------------------------------------*/ + + +FlatFndBox::FlatFndBox(SwDoc* pDocPtr, const _FndBox& rBox) : + pDoc(pDocPtr), + pArr(0), + ppItemSets( 0 ), + rBoxRef(rBox), + nRow(0), + nCol(0) +{ // Ist das Array symmetrisch + if((bSym = CheckLineSymmetry(rBoxRef)) != 0) + { + // Spalten/Reihen-Anzahl ermitteln + nCols = GetColCount(rBoxRef); + nRows = GetRowCount(rBoxRef); + + // lineares Array anlegen + pArr = new _FndBoxPtr[ nRows * nCols ]; + _FndBox** ppTmp = (_FndBox**)pArr; + memset( ppTmp, 0, sizeof(_FndBoxPtr) * nRows * nCols ); + + + FillFlat( rBoxRef ); + } +} + + +FlatFndBox::~FlatFndBox() +{ + _FndBox** ppTmp = (_FndBox**)pArr; + __DELETE(nRows * nCols * sizeof(_FndBoxPtr)) ppTmp; + + if( ppItemSets ) + __DELETE(nRows * nCols * sizeof(SfxItemSet*)) ppItemSets; +} + +/*-------------------------------------------------------------------- + Beschreibung: Alle Lines einer Box muessen gleichviel Boxen haben + --------------------------------------------------------------------*/ + + +BOOL FlatFndBox::CheckLineSymmetry(const _FndBox& rBox) +{ + const _FndLines& rLines = rBox.GetLines(); + USHORT nBoxes; + + // UeberLines iterieren + for(USHORT i=0; i < rLines.Count(); ++i) + { // Die Boxen einer Line + _FndLine* pLn = rLines[i]; + const _FndBoxes& rBoxes = pLn->GetBoxes(); + + // Anzahl der Boxen aller Lines ungleich -> keine Symmetrie + if( i && nBoxes != rBoxes.Count()) + return FALSE; + + nBoxes = rBoxes.Count(); + if( !CheckBoxSymmetry( *pLn ) ) + return FALSE; + } + return TRUE; +} + +/*-------------------------------------------------------------------- + Beschreibung: Box auf Symmetrie pruefen + Alle Boxen einer Line muessen gleichviele Lines haben + --------------------------------------------------------------------*/ + + +BOOL FlatFndBox::CheckBoxSymmetry(const _FndLine& rLn) +{ + const _FndBoxes& rBoxes = rLn.GetBoxes(); + USHORT nLines; + + // Ueber Boxes iterieren + for(USHORT i=0; i < rBoxes.Count(); ++i) + { // Die Boxen einer Line + _FndBox* pBox = rBoxes[i]; + const _FndLines& rLines = pBox->GetLines(); + + // Anzahl der Boxen aller Lines ungleich -> keine Symmetrie + if( i && nLines != rLines.Count() ) + return FALSE; + + nLines = rLines.Count(); + if( nLines && !CheckLineSymmetry( *pBox ) ) + return FALSE; + } + return TRUE; +} + +/*-------------------------------------------------------------------- + Beschreibung: max Anzahl der Spalten (Boxes) + --------------------------------------------------------------------*/ + + +USHORT FlatFndBox::GetColCount(const _FndBox& rBox) +{ + const _FndLines& rLines = rBox.GetLines(); + // Ueber Lines iterieren + if( !rLines.Count() ) + return 1; + + USHORT nSum = 0; + for( USHORT i=0; i < rLines.Count(); ++i ) + { + // Die Boxen einer Line + USHORT nCount = 0; + const _FndBoxes& rBoxes = rLines[i]->GetBoxes(); + for( USHORT j=0; j < rBoxes.Count(); ++j ) + // Rekursiv wirder ueber die Lines Iterieren + nCount += rBoxes[j]->GetLines().Count() + ? GetColCount(*rBoxes[j]) : 1; + + if( nSum < nCount ) + nSum = nCount; + } + return nSum; +} + +/*-------------------------------------------------------------------- + Beschreibung: max Anzahl der Zeilen (Lines) + --------------------------------------------------------------------*/ + + +USHORT FlatFndBox::GetRowCount(const _FndBox& rBox) +{ + const _FndLines& rLines = rBox.GetLines(); + if( !rLines.Count() ) + return 1; + + USHORT nLines = 0; + for(USHORT i=0; i < rLines.Count(); ++i) + { // Die Boxen einer Line + const _FndBoxes& rBoxes = rLines[i]->GetBoxes(); + USHORT nLn = 1; + for(USHORT j=0; j < rBoxes.Count(); ++j) + if( rBoxes[j]->GetLines().Count() ) + // Rekursiv ueber die Lines Iterieren + nLn = Max(GetRowCount(*rBoxes[j]), nLn); + + nLines += nLn; + } + return nLines; +} + +/*-------------------------------------------------------------------- + Beschreibung: lineares Array aus atomaren FndBoxes erzeugen + --------------------------------------------------------------------*/ + + +void FlatFndBox::FillFlat(const _FndBox& rBox, BOOL bLastBox) +{ + BOOL bModRow = FALSE; + const _FndLines& rLines = rBox.GetLines(); + + // Ueber Lines iterieren + USHORT nOldRow = nRow; + for( USHORT i=0; i < rLines.Count(); ++i ) + { + // Die Boxen einer Line + const _FndBoxes& rBoxes = rLines[i]->GetBoxes(); + USHORT nOldCol = nCol; + for( USHORT j = 0; j < rBoxes.Count(); ++j ) + { + // Die Box pruefen ob es eine atomare Box ist + const _FndBox* pBox = rBoxes[ j ]; + + if( !pBox->GetLines().Count() ) + { + // peichern + USHORT nOff = nRow * nCols + nCol; + *(pArr + nOff) = pBox; + + // sicher die Formel/Format/Value Werte + const SwFrmFmt* pFmt = pBox->GetBox()->GetFrmFmt(); + if( SFX_ITEM_SET == pFmt->GetItemState( RES_BOXATR_FORMAT ) || + SFX_ITEM_SET == pFmt->GetItemState( RES_BOXATR_FORMULA ) || + SFX_ITEM_SET == pFmt->GetItemState( RES_BOXATR_VALUE ) ) + { + SfxItemSet* pSet = new SfxItemSet( pDoc->GetAttrPool(), + RES_BOXATR_FORMAT, RES_BOXATR_VALUE, + RES_VERT_ORIENT, RES_VERT_ORIENT, 0 ); + pSet->Put( pFmt->GetAttrSet() ); + if( !ppItemSets ) + { + ppItemSets = new SfxItemSet*[ nRows * nCols ]; + memset( ppItemSets, 0, sizeof(SfxItemSet*) * nRows * nCols ); + } + *(ppItemSets + nOff ) = pSet; + } + + bModRow = TRUE; + } + else + { + // Rekursiv wieder ueber die Lines einer Box Iterieren + FillFlat( *pBox, ( j == rBoxes.Count()-1 ) ); + } + nCol++; + } + if(bModRow) + nRow++; + nCol = nOldCol; + } + if(!bLastBox) + nRow = nOldRow; +} + +/*-------------------------------------------------------------------- + Beschreibung: Zugriff auf eine bestimmte Zelle + --------------------------------------------------------------------*/ + + +const _FndBox* FlatFndBox::GetBox(USHORT nCol, USHORT nRow) const +{ + USHORT nOff = nRow * nCols + nCol; + const _FndBox* pTmp = *(pArr + nOff); + + ASSERT(nCol < nCols && nRow < nRows && pTmp, "unzulaessiger Array-Zugriff"); + return pTmp; +} + +const SfxItemSet* FlatFndBox::GetItemSet(USHORT nCol, USHORT nRow) const +{ + ASSERT( !ppItemSets || ( nCol < nCols && nRow < nRows), "unzulaessiger Array-Zugriff"); + + return ppItemSets ? *(ppItemSets + (nRow * nCols + nCol )) : 0; +} + + diff --git a/sw/source/core/doc/docstat.cxx b/sw/source/core/doc/docstat.cxx new file mode 100644 index 000000000000..518dc4e6c3c9 --- /dev/null +++ b/sw/source/core/doc/docstat.cxx @@ -0,0 +1,105 @@ +/************************************************************************* + * + * $RCSfile: docstat.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:15 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _DOCSTAT_HXX +#include +#endif + + +/************************************************************************ + * SwDocStat::SwDocStat() + ************************************************************************/ + +SwDocStat::SwDocStat() : + nTbl(0), + nGrf(0), + nOLE(0), + nPage(1), + nPara(1), + nWord(0), + nChar(0), + bModified(TRUE), + pInternStat(0) +{} + +/************************************************************************ + * void SwDocStat::Reset() + ************************************************************************/ + +void SwDocStat::Reset() +{ + nTbl = 0; + nGrf = 0; + nOLE = 0; + nPage = 1; + nPara = 1; + nWord = 0; + nChar = 0; + bModified = TRUE; + pInternStat = 0; +} + diff --git a/sw/source/core/doc/doctxm.cxx b/sw/source/core/doc/doctxm.cxx new file mode 100644 index 000000000000..0ff1cfd0c572 --- /dev/null +++ b/sw/source/core/doc/doctxm.cxx @@ -0,0 +1,2352 @@ +/************************************************************************* + * + * $RCSfile: doctxm.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:15 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#include + +#ifndef _HINTIDS_HXX +#include +#endif + +#ifndef _APP_HXX +#include +#endif +#ifndef _SYSTEM_HXX +#include +#endif +#define _SVSTDARR_STRINGSSORT +#include +#ifndef _SVX_LANGITEM_HXX +#include +#endif +#ifndef _SVX_BRKITEM_HXX +#include +#endif +#ifndef _SVX_TSPTITEM_HXX +#include +#endif +#ifndef _SVX_LRSPITEM_HXX +#include +#endif +#ifndef SMDLL0_HXX +#include +#endif +#ifndef SC_SCDLL_HXX +#include +#endif +#ifndef _SIM_SIMDLL0_HXX +#include +#endif +#ifndef _SCHDLL0_HXX +#include +#endif +#ifndef _SDDLL_HXX +#include +#endif + +#ifndef _SWDOCSH_HXX +#include +#endif +#ifndef _NDOLE_HXX +#include +#endif +#ifndef _TXTTXMRK_HXX +#include +#endif +#ifndef _FMTINFMT_HXX +#include +#endif +#ifndef _FMTPDSC_HXX +#include +#endif +#ifndef _FRMFMT_HXX +#include +#endif +#ifndef _FMTFSIZE_HXX +#include +#endif +#ifndef _FRMATR_HXX +#include +#endif +#ifndef _PAGEDESC_HXX +#include +#endif +#ifndef _DOC_HXX +#include +#endif +#ifndef _PAGEFRM_HXX +#include +#endif +#ifndef _NDTXT_HXX +#include +#endif +#ifndef _SWTABLE_HXX +#include +#endif +#ifndef _HINTS_HXX +#include +#endif +#ifndef _DOCTXM_HXX +#include +#endif +#ifndef _TXMSRT_HXX +#include +#endif +#ifndef _ROLBCK_HXX +#include +#endif +#ifndef _POOLFMT_HXX +#include +#endif +#ifndef _TXTFRM_HXX +#include +#endif +#ifndef _ROOTFRM_HXX +#include +#endif +#ifndef _UNDOBJ_HXX +#include +#endif +#ifndef _SWUNDO_HXX +#include +#endif +#ifndef _MDIEXP_HXX +#include +#endif +#ifndef _DOCARY_HXX +#include +#endif +#ifndef _CHARFMT_HXX +#include +#endif +#ifndef _FCHRFMT_HXX +#include +#endif +#ifndef _FLDBAS_HXX +#include +#endif +#ifndef _FMTFLD_HXX +#include +#endif +#ifndef _TXTFLD_HXX +#include +#endif +#ifndef _EXPFLD_HXX +#include +#endif +#ifndef _CHPFLD_HXX +#include +#endif +#ifndef _MVSAVE_HXX +#include +#endif +#ifndef _NODE2LAY_HXX +#include +#endif + + +const sal_Unicode cNumRepl = '@'; +const sal_Unicode cEndPageNum = '~'; +const sal_Char __FAR_DATA sPageDeli[] = ", "; + +SV_IMPL_PTRARR(SwTOXSortTabBases, SwTOXSortTabBasePtr) + +TYPEINIT2( SwTOXBaseSection, SwTOXBase, SwSection ); // fuers RTTI + +struct LinkStruct +{ + SwFmtINetFmt aINetFmt; + xub_StrLen nStartTextPos, nEndTextPos; + + LinkStruct( const String& rURL, xub_StrLen nStart, xub_StrLen nEnd ) + : aINetFmt( rURL, aEmptyStr), + nStartTextPos( nStart), + nEndTextPos(nEnd) {} +}; + +typedef LinkStruct* LinkStructPtr; +SV_DECL_PTRARR(LinkStructArr, LinkStructPtr, 0, 5 ); +SV_IMPL_PTRARR(LinkStructArr, LinkStructPtr) + +USHORT SwDoc::GetTOIKeys( SwTOIKeyType eTyp, SvStringsSort& rArr ) const +{ + if( rArr.Count() ) + rArr.Remove( USHORT(0), rArr.Count() ); + + // dann mal ueber den Pool und alle Primary oder Secondary heraussuchen + const SwTxtTOXMark* pMark; + const SfxPoolItem* pItem; + USHORT i, nMaxItems = GetAttrPool().GetItemCount( RES_TXTATR_TOXMARK ); + for( i = 0; i < nMaxItems; ++i ) + if( 0 != (pItem = GetAttrPool().GetItem( RES_TXTATR_TOXMARK, i ) ) && + TOX_INDEX == ((SwTOXMark*)pItem)->GetTOXType()->GetType() && + 0 != ( pMark = ((SwTOXMark*)pItem)->GetTxtTOXMark() ) && + pMark->GetpTxtNd() && + pMark->GetpTxtNd()->GetNodes().IsDocNodes() ) + { + const String* pStr; + if( TOI_PRIMARY == eTyp ) + pStr = &((SwTOXMark*)pItem)->GetPrimaryKey(); + else + pStr = &((SwTOXMark*)pItem)->GetSecondaryKey(); + + if( pStr->Len() ) + rArr.Insert( (StringPtr)pStr ); + } + + return rArr.Count(); +} + +/*-------------------------------------------------------------------- + Beschreibung: aktuelle Verzeichnismarkierungen ermitteln + --------------------------------------------------------------------*/ + + +USHORT SwDoc::GetCurTOXMark( const SwPosition& rPos, + SwTOXMarks& rArr ) const +{ + // suche an der Position rPos nach allen SwTOXMark's + SwTxtNode* pTxtNd = GetNodes()[ rPos.nNode ]->GetTxtNode(); + // kein TextNode oder kein HintsArray vorhanden ?? + if( !pTxtNd || !pTxtNd->GetpSwpHints() ) + return 0; + + const SwpHints & rHts = *pTxtNd->GetpSwpHints(); + const SwTxtAttr* pHt; + xub_StrLen nSttIdx; + const xub_StrLen *pEndIdx; + + xub_StrLen nAktPos = rPos.nContent.GetIndex(); + + for( USHORT n = 0; n < rHts.Count(); ++n ) + { + if( RES_TXTATR_TOXMARK != (pHt = rHts[n])->Which() ) + continue; + if( ( nSttIdx = *pHt->GetStart() ) < nAktPos ) + { + // pruefe Ende mit ab + if( 0 == ( pEndIdx = pHt->GetEnd() ) || + *pEndIdx <= nAktPos ) + continue; // weiter suchen + } + else if( nSttIdx > nAktPos ) + // ist Start vom Hint groesser als rPos, dann abbrechen. Denn + // die Attribute sind nach Start sortiert ! + break; + + const SwTOXMark* pTMark = &pHt->GetTOXMark(); + rArr.Insert( pTMark, rArr.Count() ); + } + return rArr.Count(); +} + +/*-------------------------------------------------------------------- + Beschreibung: Marke loeschen + --------------------------------------------------------------------*/ + +void SwDoc::Delete( SwTOXMark* pTOXMark ) +{ + // hole den TextNode und + SwTxtTOXMark* pTxtTOXMark = pTOXMark->GetTxtTOXMark(); + ASSERT( pTxtTOXMark, "Kein TxtTOXMark, kann nicht geloescht werden" ); + + SwTxtNode& rTxtNd = (SwTxtNode&)pTxtTOXMark->GetTxtNode(); + ASSERT( rTxtNd.GetpSwpHints(), "kann nicht geloescht werden" ); + + if( DoesUndo() ) + { + // fuers Undo die Attribute sichern + ClearRedo(); + SwUndoRstAttr* pUndo = new SwUndoRstAttr( *this, SwPosition( rTxtNd, + SwIndex( &rTxtNd, *pTxtTOXMark->GetStart() ) ), + RES_TXTATR_TOXMARK ); + AppendUndo( pUndo ); + + SwRegHistory aRHst( rTxtNd, pUndo->GetHistory() ); + rTxtNd.GetpSwpHints()->Register( &aRHst ); + rTxtNd.Delete( pTxtTOXMark, TRUE ); + if( rTxtNd.GetpSwpHints() ) + rTxtNd.GetpSwpHints()->DeRegister(); + } + else + rTxtNd.Delete( pTxtTOXMark, TRUE ); + SetModified(); +} + +/*-------------------------------------------------------------------- + Beschreibung: Traveln zwischen TOXMarks + --------------------------------------------------------------------*/ + +class CompareNodeCntnt +{ + ULONG nNode; + xub_StrLen nCntnt; +public: + CompareNodeCntnt( ULONG nNd, xub_StrLen nCnt ) + : nNode( nNd ), nCntnt( nCnt ) {} + + int operator==( const CompareNodeCntnt& rCmp ) + { return nNode == rCmp.nNode && nCntnt == rCmp.nCntnt; } + int operator!=( const CompareNodeCntnt& rCmp ) + { return nNode != rCmp.nNode || nCntnt != rCmp.nCntnt; } + int operator< ( const CompareNodeCntnt& rCmp ) + { return nNode < rCmp.nNode || + ( nNode == rCmp.nNode && nCntnt < rCmp.nCntnt); } + int operator<=( const CompareNodeCntnt& rCmp ) + { return nNode < rCmp.nNode || + ( nNode == rCmp.nNode && nCntnt <= rCmp.nCntnt); } + int operator> ( const CompareNodeCntnt& rCmp ) + { return nNode > rCmp.nNode || + ( nNode == rCmp.nNode && nCntnt > rCmp.nCntnt); } + int operator>=( const CompareNodeCntnt& rCmp ) + { return nNode > rCmp.nNode || + ( nNode == rCmp.nNode && nCntnt >= rCmp.nCntnt); } +}; + +const SwTOXMark& SwDoc::GotoTOXMark( const SwTOXMark& rCurTOXMark, + SwTOXSearch eDir, BOOL bInReadOnly ) +{ + const SwTxtTOXMark* pMark = rCurTOXMark.GetTxtTOXMark(); + ASSERT(pMark, "pMark==0 Ungueltige TxtTOXMark"); + + const SwTxtNode *pTOXSrc = pMark->GetpTxtNd(); + + CompareNodeCntnt aAbsIdx( pTOXSrc->GetIndex(), *pMark->GetStart() ); + CompareNodeCntnt aPrevPos( 0, 0 ); + CompareNodeCntnt aNextPos( ULONG_MAX, STRING_NOTFOUND ); + CompareNodeCntnt aMax( 0, 0 ); + CompareNodeCntnt aMin( ULONG_MAX, STRING_NOTFOUND ); + + const SwTOXMark* pNew = 0; + const SwTOXMark* pMax = &rCurTOXMark; + const SwTOXMark* pMin = &rCurTOXMark; + + const SwModify* pType = rCurTOXMark.GetRegisteredIn(); + SwClientIter aIter( *(SwModify*)pType ); + + const SwTOXMark* pTOXMark; + const SwCntntFrm* pCFrm; + Point aPt; + for( pTOXMark = (SwTOXMark*)aIter.First( TYPE( SwTOXMark )); pTOXMark; + pTOXMark = (SwTOXMark*)aIter.Next() ) + { + if( pTOXMark != &rCurTOXMark && + 0 != ( pMark = pTOXMark->GetTxtTOXMark()) && + 0 != ( pTOXSrc = pMark->GetpTxtNd() ) && + 0 != ( pCFrm = pTOXSrc->GetFrm( &aPt, 0, FALSE )) && + ( bInReadOnly || !pCFrm->IsProtected() )) + { + CompareNodeCntnt aAbsNew( pTOXSrc->GetIndex(), *pMark->GetStart() ); + switch( eDir ) + { + //Die untenstehenden etwas komplizierter ausgefallen Ausdruecke + //dienen dazu auch ueber Eintraege auf der selben (!) Position + //traveln zu koennen. Wenn einer Zeit hat mag er sie mal + //optimieren. + + case TOX_SAME_PRV: + if( pTOXMark->GetText() != rCurTOXMark.GetText() ) + break; + /* no break here */ + case TOX_PRV: + if ( (aAbsNew < aAbsIdx && aAbsNew > aPrevPos && + aPrevPos != aAbsIdx && aAbsNew != aAbsIdx ) || + (aAbsIdx == aAbsNew && + (ULONG(&rCurTOXMark) > ULONG(pTOXMark) && + (!pNew || + (pNew && (aPrevPos < aAbsIdx || + ULONG(pNew) < ULONG(pTOXMark)))))) || + (aPrevPos == aAbsNew && aAbsIdx != aAbsNew && + ULONG(pTOXMark) > ULONG(pNew)) ) + { + pNew = pTOXMark; + aPrevPos = aAbsNew; + if ( aAbsNew >= aMax ) + { + aMax = aAbsNew; + pMax = pTOXMark; + } + } + break; + + case TOX_SAME_NXT: + if( pTOXMark->GetText() != rCurTOXMark.GetText() ) + break; + /* no break here */ + case TOX_NXT: + if ( (aAbsNew > aAbsIdx && aAbsNew < aNextPos && + aNextPos != aAbsIdx && aAbsNew != aAbsIdx ) || + (aAbsIdx == aAbsNew && + (ULONG(&rCurTOXMark) < ULONG(pTOXMark) && + (!pNew || + (pNew && (aNextPos > aAbsIdx || + ULONG(pNew) > ULONG(pTOXMark)))))) || + (aNextPos == aAbsNew && aAbsIdx != aAbsNew && + ULONG(pTOXMark) < ULONG(pNew)) ) + { + pNew = pTOXMark; + aNextPos = aAbsNew; + if ( aAbsNew <= aMin ) + { + aMin = aAbsNew; + pMin = pTOXMark; + } + } + break; + } + } + } + + + // kein Nachfolger wurde gefunden + // Min oder Max benutzen + if(!pNew) + { + switch(eDir) + { + case TOX_PRV: + case TOX_SAME_PRV: + pNew = pMax; + break; + case TOX_NXT: + case TOX_SAME_NXT: + pNew = pMin; + break; + default: + pNew = &rCurTOXMark; + } + } + return *pNew; +} + +/* */ + +const SwTOXBaseSection* SwDoc::InsertTableOf( const SwPosition& rPos, + const SwTOXBase& rTOX, + const SfxItemSet* pSet, + BOOL bExpand ) +{ + StartUndo( UNDO_INSTOX ); + + SwTOXBaseSection* pNew = new SwTOXBaseSection( rTOX ); + String sSectNm( rTOX.GetTOXName() ); + sSectNm = GetUniqueTOXBaseName( *rTOX.GetTOXType(), &sSectNm ); + pNew->SetTOXName(sSectNm); + pNew->SwSection::SetName(sSectNm); + SwPaM aPam( rPos ); + SwSection* pSect = Insert( aPam, *pNew, pSet, FALSE ); + if( pSect ) + { + SwSectionNode* pSectNd = pSect->GetFmt()->GetSectionNode(); + SwSection* pCl = pNew; + pSect->GetFmt()->Add( pCl ); + pSectNd->SetNewSection( pNew ); + + if( bExpand ) + pNew->Update(); + } + else + delete pNew, pNew = 0; + + EndUndo( UNDO_INSTOX ); + + return pNew; +} + + + +const SwTOXBaseSection* SwDoc::InsertTableOf( ULONG nSttNd, ULONG nEndNd, + const SwTOXBase& rTOX, + const SfxItemSet* pSet ) +{ + // check for recursiv TOX + SwNode* pNd = GetNodes()[ nSttNd ]; + SwSectionNode* pSectNd = pNd->FindSectionNode(); + while( pSectNd ) + { + SectionType eT = pSectNd->GetSection().GetType(); + if( TOX_HEADER_SECTION == eT || TOX_CONTENT_SECTION == eT ) + return 0; + pSectNd = pSectNd->FindStartNode()->FindSectionNode(); + } + + // create SectionNode around the Nodes + SwTOXBaseSection* pNew = new SwTOXBaseSection( rTOX ); + + String sSectNm( rTOX.GetTOXName() ); + sSectNm = GetUniqueTOXBaseName(*rTOX.GetTOXType(), &sSectNm); + pNew->SetTOXName(sSectNm); + pNew->SwSection::SetName(sSectNm); + + SwNodeIndex aStt( GetNodes(), nSttNd ), aEnd( GetNodes(), nEndNd ); + SwSectionFmt* pFmt = MakeSectionFmt( 0 ); + if(pSet) + pFmt->SetAttr(*pSet); + +// --aEnd; // im InsertSection ist Ende inclusive + + pSectNd = GetNodes().InsertSection( aStt, *pFmt, *pNew, &aEnd ); + if( pSectNd ) + { + SwSection* pCl = pNew; + pFmt->Add( pCl ); + pSectNd->SetNewSection( pNew ); + } + else + { + delete pNew, pNew = 0; + DelSectionFmt( pFmt ); + } + + return pNew; +} + +/*-------------------------------------------------------------------- + Beschreibung: Aktuelles Verzeichnis ermitteln + --------------------------------------------------------------------*/ + +const SwTOXBase* SwDoc::GetCurTOX( const SwPosition& rPos ) const +{ + const SwNode& rNd = rPos.nNode.GetNode(); + const SwSectionNode* pSectNd = rNd.FindSectionNode(); + while( pSectNd ) + { + SectionType eT = pSectNd->GetSection().GetType(); + if( TOX_CONTENT_SECTION == eT ) + { + ASSERT( pSectNd->GetSection().ISA( SwTOXBaseSection ), + "keine TOXBaseSection!" ); + SwTOXBaseSection& rTOXSect = (SwTOXBaseSection&) + pSectNd->GetSection(); + return &rTOXSect; + } + pSectNd = pSectNd->FindStartNode()->FindSectionNode(); + } + return 0; +} +/* -----------------01.09.99 16:01------------------- + + --------------------------------------------------*/ +const SwAttrSet& SwDoc::GetTOXBaseAttrSet(const SwTOXBase& rTOXBase) const +{ + ASSERT( rTOXBase.ISA( SwTOXBaseSection ), "no TOXBaseSection!" ); + const SwTOXBaseSection& rTOXSect = (const SwTOXBaseSection&)rTOXBase; + SwSectionFmt* pFmt = rTOXSect.GetFmt(); + ASSERT( pFmt, "invalid TOXBaseSection!" ); + return pFmt->GetAttrSet(); +} +/* -----------------02.09.99 07:48------------------- + + --------------------------------------------------*/ +const SwTOXBase* SwDoc::GetDefaultTOXBase( TOXTypes eTyp, BOOL bCreate ) +{ + SwTOXBase** prBase; + switch(eTyp) + { + case TOX_CONTENT: prBase = &pDefTOXBases->pContBase; break; + case TOX_INDEX: prBase = &pDefTOXBases->pIdxBase; break; + case TOX_USER: prBase = &pDefTOXBases->pUserBase; break; + case TOX_TABLES: prBase = &pDefTOXBases->pTblBase; break; + case TOX_OBJECTS: prBase = &pDefTOXBases->pObjBase; break; + case TOX_ILLUSTRATIONS: prBase = &pDefTOXBases->pIllBase; break; + case TOX_AUTHORITIES: prBase = &pDefTOXBases->pAuthBase; break; + } + if(!(*prBase) && bCreate) + { + SwForm aForm(eTyp); + const SwTOXType* pType = GetTOXType(eTyp, 0); + (*prBase) = new SwTOXBase(pType, aForm, 0, pType->GetTypeName()); + } + return (*prBase); +} +/* -----------------02.09.99 08:06------------------- + + --------------------------------------------------*/ +void SwDoc::SetDefaultTOXBase(const SwTOXBase& rBase) +{ + SwTOXBase** prBase; + switch(rBase.GetType()) + { + case TOX_CONTENT: prBase = &pDefTOXBases->pContBase; break; + case TOX_INDEX: prBase = &pDefTOXBases->pIdxBase; break; + case TOX_USER: prBase = &pDefTOXBases->pUserBase; break; + case TOX_TABLES: prBase = &pDefTOXBases->pTblBase; break; + case TOX_OBJECTS: prBase = &pDefTOXBases->pObjBase; break; + case TOX_ILLUSTRATIONS: prBase = &pDefTOXBases->pIllBase; break; + case TOX_AUTHORITIES: prBase = &pDefTOXBases->pAuthBase; break; + } + if(*prBase) + delete (*prBase); + (*prBase) = new SwTOXBase(rBase); +} + +/*-------------------------------------------------------------------- + Beschreibung: Verzeichnis loeschen + --------------------------------------------------------------------*/ + + +BOOL SwDoc::DeleteTOX( const SwTOXBase& rTOXBase, BOOL bDelNodes ) +{ + // its only delete the TOX, not the nodes + BOOL bRet = FALSE; + ASSERT( rTOXBase.ISA( SwTOXBaseSection ), "keine TOXBaseSection!" ); + + const SwTOXBaseSection& rTOXSect = (const SwTOXBaseSection&)rTOXBase; + SwSectionFmt* pFmt = rTOXSect.GetFmt(); + if( pFmt ) + { + StartUndo( UNDO_CLEARTOXRANGE ); + + if( !bDelNodes ) + { + SwSections aArr( 0, 4 ); + USHORT nCnt = pFmt->GetChildSections( aArr, SORTSECT_NOT, FALSE ); + for( USHORT n = 0; n < nCnt; ++n ) + { + SwSection* pSect = aArr[ n ]; + if( TOX_HEADER_SECTION == pSect->GetType() ) + { + DelSectionFmt( pSect->GetFmt(), bDelNodes ); + } + } + } + DelSectionFmt( pFmt, bDelNodes ); + + EndUndo( UNDO_CLEARTOXRANGE ); + bRet = TRUE; + } + return bRet; +} + +/*-------------------------------------------------------------------- + Beschreibung: Verzeichnistypen verwalten + --------------------------------------------------------------------*/ + +USHORT SwDoc::GetTOXTypeCount(TOXTypes eTyp) const +{ + const SwTOXTypePtr * ppTTypes = pTOXTypes->GetData(); + USHORT nCnt = 0; + for( USHORT n = 0; n < pTOXTypes->Count(); ++n, ++ppTTypes ) + if( eTyp == (*ppTTypes)->GetType() ) + ++nCnt; + return nCnt; +} +/*-------------------------------------------------------------------- + + --------------------------------------------------------------------*/ +const SwTOXType* SwDoc::GetTOXType( TOXTypes eTyp, USHORT nId ) const +{ + const SwTOXTypePtr * ppTTypes = pTOXTypes->GetData(); + USHORT nCnt = 0; + for( USHORT n = 0; n < pTOXTypes->Count(); ++n, ++ppTTypes ) + if( eTyp == (*ppTTypes)->GetType() && nCnt++ == nId ) + return (*ppTTypes); + return 0; +} + +#ifdef USED + + +BOOL SwDoc::DeleteTOXType(TOXTypes eTyp, USHORT nId) +{ + // was passiert mit den Abhaengigen ?? + // - alle Marken und alle Verzeichnisse aus dem Text loeschen ?? + SwTOXType* pTOXTyp = (SwTOXType*)GetTOXType( eTyp, nId ); + + ASSERT( !pTOXTyp->GetDepends(), "noch Marken/Verzeichnisse am Typ" ); + delete pTOXTyp; // ??? + + return TRUE; +} + +#endif + +/*-------------------------------------------------------------------- + + --------------------------------------------------------------------*/ +const SwTOXType* SwDoc::InsertTOXType( const SwTOXType& rTyp ) +{ + SwTOXType * pNew = new SwTOXType( rTyp ); + pTOXTypes->Insert( pNew, pTOXTypes->Count() ); + return pNew; +} +/*-------------------------------------------------------------------- + + --------------------------------------------------------------------*/ +String SwDoc::GetUniqueTOXBaseName( const SwTOXType& rType, + const String* pChkStr ) const +{ + if(pChkStr && !pChkStr->Len()) + pChkStr = 0; + String aName( rType.GetTypeName() ); + xub_StrLen nNmLen = aName.Len(); + + USHORT nNum, nTmp, nFlagSize = ( pSectionFmtTbl->Count() / 8 ) +2; + BYTE* pSetFlags = new BYTE[ nFlagSize ]; + memset( pSetFlags, 0, nFlagSize ); + + const SwSectionNode* pSectNd; + const SwSection* pSect; + for( USHORT n = 0; n < pSectionFmtTbl->Count(); ++n ) + if( 0 != ( pSectNd = (*pSectionFmtTbl)[ n ]->GetSectionNode( FALSE ) )&& + TOX_CONTENT_SECTION == (pSect = &pSectNd->GetSection())->GetType()) + { + const String& rNm = pSect->GetName(); + if( rNm.Match( aName ) == nNmLen ) + { + // Nummer bestimmen und das Flag setzen + nNum = rNm.Copy( nNmLen ).ToInt32(); + if( nNum-- && nNum < pSectionFmtTbl->Count() ) + pSetFlags[ nNum / 8 ] |= (0x01 << ( nNum & 0x07 )); + } + if( pChkStr && pChkStr->Equals( rNm ) ) + pChkStr = 0; + } + + if( !pChkStr ) + { + // alle Nummern entsprechend geflag, also bestimme die richtige Nummer + nNum = pSectionFmtTbl->Count(); + for( n = 0; n < nFlagSize; ++n ) + if( 0xff != ( nTmp = pSetFlags[ n ] )) + { + // also die Nummer bestimmen + nNum = n * 8; + while( nTmp & 1 ) + ++nNum, nTmp >>= 1; + break; + } + } + __DELETE( nFlagSize ) pSetFlags; + if( pChkStr ) + return *pChkStr; + return aName += String::CreateFromInt32( ++nNum ); +} + +/*-------------------------------------------------------------------- + + --------------------------------------------------------------------*/ +BOOL SwDoc::SetTOXBaseName(const SwTOXBase& rTOXBase, const String& rName) +{ + ASSERT( rTOXBase.ISA( SwTOXBaseSection ), + "keine TOXBaseSection!" ); + SwTOXBaseSection* pTOX = (SwTOXBaseSection*)&rTOXBase; + + String sTmp = GetUniqueTOXBaseName(*rTOXBase.GetTOXType(), &rName); + BOOL bRet = sTmp == rName; + if(bRet) + { + pTOX->SetTOXName(rName); + pTOX->SwTOXBaseSection::SetName(rName); + SetModified(); + } + return bRet; +} +/*-------------------------------------------------------------------- + + --------------------------------------------------------------------*/ +void SwDoc::SetTOXBaseProtection(const SwTOXBase& rTOXBase, BOOL bProtect) +{ + ASSERT( rTOXBase.ISA( SwTOXBaseSection ), + "keine TOXBaseSection!" ); + SwTOXBaseSection* pTOX = (SwTOXBaseSection*)&rTOXBase; + if(bProtect != pTOX->IsProtected()) + { + pTOX->SetProtect(bProtect); + pTOX->SetProtected(bProtect); + SetModified(); + } +} + + +/* */ + +const SwTxtNode* lcl_FindChapterNode( const SwNode& rNd, BYTE nLvl = 0 ) +{ + const SwNode* pNd = &rNd; + if( pNd->GetNodes().GetEndOfExtras().GetIndex() > pNd->GetIndex() ) + { + // then find the "Anchor" (Body) position + Point aPt; + SwNode2Layout aNode2Layout( *pNd, pNd->GetIndex() ); + const SwFrm* pFrm = aNode2Layout.GetFrm( &aPt, 0, FALSE ); + + if( pFrm ) + { + SwPosition aPos( *pNd ); + pNd = GetBodyTxtNode( *pNd->GetDoc(), aPos, *pFrm ); + ASSERT( pNd, "wo steht der Absatz" ); + } + } + return pNd ? pNd->FindOutlineNodeOfLevel( nLvl ) : 0; +} + + +/*-------------------------------------------------------------------- + Beschreibung: Verzeichnis-Klasse + --------------------------------------------------------------------*/ + +SwTOXBaseSection::SwTOXBaseSection( const SwTOXBase& rBase ) + : SwTOXBase( rBase ), SwSection( TOX_CONTENT_SECTION, aEmptyStr ) +{ + SetProtect( rBase.IsProtected() ); + SwSection::SetName( GetTOXName() ); +} + + +SwTOXBaseSection::~SwTOXBaseSection() +{ +} + + +BOOL SwTOXBaseSection::SetPosAtStartEnd( SwPosition& rPos, BOOL bAtStart ) const +{ + BOOL bRet = FALSE; + const SwSectionNode* pSectNd = GetFmt()->GetSectionNode(); + if( pSectNd ) + { + SwCntntNode* pCNd; + xub_StrLen nC = 0; + if( bAtStart ) + { + rPos.nNode = *pSectNd; + pCNd = pSectNd->GetDoc()->GetNodes().GoNext( &rPos.nNode ); + } + else + { + rPos.nNode = *pSectNd->EndOfSectionNode(); + pCNd = pSectNd->GetDoc()->GetNodes().GoPrevious( &rPos.nNode ); + if( pCNd ) nC = pCNd->Len(); + } + rPos.nContent.Assign( pCNd, nC ); + bRet = TRUE; + } + return bRet; +} + +/*-------------------------------------------------------------------- + Beschreibung: Verzeichnisinhalt zusammensammeln + --------------------------------------------------------------------*/ + +void SwTOXBaseSection::Update(const SfxItemSet* pAttr) +{ + const SwSectionNode* pSectNd; + if( !SwTOXBase::GetRegisteredIn()->GetDepends() || + !GetFmt() || 0 == (pSectNd = GetFmt()->GetSectionNode() ) || + !pSectNd->GetNodes().IsDocNodes() || + IsHiddenFlag() ) + return; + + if(pAttr) + GetFmt()->SetAttr(*pAttr); + + SwDoc* pDoc = (SwDoc*)pSectNd->GetDoc(); + pDoc->SetModified(); + + // get current Language + const International* pIntl = &Application::GetAppInternational(); + LanguageType eLang = ((const SvxLanguageItem&)pDoc->GetAttrPool(). + GetDefaultItem(RES_CHRATR_LANGUAGE )).GetLanguage(); + + if( !( eLang == ::GetSystemLanguage() && + LANGUAGE_SYSTEM == pIntl->GetLanguage() ) && + eLang != pIntl->GetLanguage() ) + pIntl = new International( eLang ); + + aSortArr.DeleteAndDestroy( 0, aSortArr.Count() ); + + // find the first layout node for this TOX, if it only find the content + // in his own chapter + const SwTxtNode* pOwnChapterNode = IsFromChapter() + ? ::lcl_FindChapterNode( *pSectNd, 0 ) + : 0; + + SwNode2Layout aN2L( *pSectNd ); + ((SwSectionNode*)pSectNd)->DelFrms(); + + // remove old content an insert one empty textnode (to hold the layout!) + SwTxtNode* pFirstEmptyNd; + { + pDoc->DeleteRedline( *pSectNd ); + + SwNodeIndex aSttIdx( *pSectNd, +1 ); + SwNodeIndex aEndIdx( *pSectNd->EndOfSectionNode() ); + pFirstEmptyNd = pDoc->GetNodes().MakeTxtNode( aEndIdx, + pDoc->GetTxtCollFromPool( RES_POOLCOLL_TEXT ) ); + + { + // Task 70995 - save and restore PageDesc and Break Attributes + SwNodeIndex aNxtIdx( aSttIdx ); + const SwCntntNode* pCNd = aNxtIdx.GetNode().GetCntntNode(); + if( !pCNd ) + pCNd = pDoc->GetNodes().GoNext( &aNxtIdx ); + if( pCNd->GetpSwAttrSet() ) + { + SfxItemSet aBrkSet( pDoc->GetAttrPool(), aBreakSetRange ); + aBrkSet.Put( *pCNd->GetpSwAttrSet() ); + if( aBrkSet.Count() ) + pFirstEmptyNd->SwCntntNode::SetAttr( aBrkSet ); + } + } + aEndIdx--; + SwPosition aPos( aEndIdx, SwIndex( pFirstEmptyNd, 0 )); + pDoc->CorrAbs( aSttIdx, aEndIdx, aPos, TRUE ); + + // delete all before + DelFlyInRange( aSttIdx, aEndIdx ); + _DelBookmarks( aSttIdx, aEndIdx ); + + pDoc->GetNodes().Delete( aSttIdx, aEndIdx.GetIndex() - aSttIdx.GetIndex() ); + + } + + // + // insert title of TOX + if( GetTitle().Len() ) + { + // then insert the headline section + SwNodeIndex aIdx( *pSectNd, +1 ); + + SwTxtNode* pHeadNd = pDoc->GetNodes().MakeTxtNode( aIdx, + GetTxtFmtColl( FORM_TITLE ) ); + pHeadNd->Insert( GetTitle(), SwIndex( pHeadNd )); + + String sNm( GetTOXName() ); +// ??Resource +sNm.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "_Head" )); + + SwSection aSect( TOX_HEADER_SECTION, sNm ); + + SwNodeIndex aStt( *pHeadNd ); aIdx--; + SwSectionFmt* pSectFmt = pDoc->MakeSectionFmt( 0 ); + pDoc->GetNodes().InsertSection( aStt, *pSectFmt, aSect, &aIdx, + TRUE, FALSE ); + } + + // jetzt waere ein prima Zeitpunkt, um die Numerierung zu updaten + pDoc->UpdateNumRule(); + + if( GetCreateType() & TOX_MARK ) + UpdateMarks( *pIntl, pOwnChapterNode ); + + if( GetCreateType() & TOX_OUTLINELEVEL ) + UpdateOutline( pOwnChapterNode ); + + if( GetCreateType() & TOX_TEMPLATE ) + UpdateTemplate( pOwnChapterNode ); + + if( GetCreateType() & TOX_OLE || + TOX_OBJECTS == SwTOXBase::GetType()) + UpdateCntnt( TOX_OLE, pOwnChapterNode ); + + if( GetCreateType() & TOX_TABLE || + (TOX_TABLES == SwTOXBase::GetType() && IsFromObjectNames()) ) + UpdateTable( pOwnChapterNode ); + + if( GetCreateType() & TOX_GRAPHIC || + (TOX_ILLUSTRATIONS == SwTOXBase::GetType() && IsFromObjectNames())) + UpdateCntnt( TOX_GRAPHIC, pOwnChapterNode ); + + if( GetSequenceName().Len() && !IsFromObjectNames() && + (TOX_TABLES == SwTOXBase::GetType() || + TOX_ILLUSTRATIONS == SwTOXBase::GetType() ) ) + UpdateSequence( pOwnChapterNode ); + + if( GetCreateType() & TOX_FRAME ) + UpdateCntnt( TOX_FRAME, pOwnChapterNode ); + + if(TOX_AUTHORITIES == SwTOXBase::GetType()) + UpdateAuthorities( pOwnChapterNode, *pIntl ); + + // Bei Bedarf Alphadelimitter einfuegen (nur bei Stichwoertern) + // + if( TOX_INDEX == SwTOXBase::GetType() && + ( GetOptions() & TOI_ALPHA_DELIMITTER ) ) + InsertAlphaDelimitter( *pIntl ); + + // sortierte Liste aller Verzeichnismarken und Verzeichnisbereiche + void* p = 0; + String* pStr = 0; + USHORT nCnt = 0, nFormMax = GetTOXForm().GetFormMax(); + SvStringsDtor aStrArr( (BYTE)nFormMax ); + SvPtrarr aCollArr( (BYTE)nFormMax ); + for( ; nCnt < nFormMax; ++nCnt ) + { + aCollArr.Insert( p, nCnt ); + aStrArr.Insert( pStr, nCnt ); + } + + SwNodeIndex aInsPos( *pFirstEmptyNd, 1 ); + for( nCnt = 0; nCnt < aSortArr.Count(); ++nCnt ) + { + ::SetProgressState( 0, pDoc->GetDocShell() ); + + // setze den Text in das Verzeichniss + USHORT nLvl = aSortArr[ nCnt ]->GetLevel(); + SwTxtFmtColl* pColl = (SwTxtFmtColl*)aCollArr[ nLvl ]; + if( !pColl ) + { + pColl = GetTxtFmtColl( nLvl ); + aCollArr.Remove( nLvl ); + p = pColl; + aCollArr.Insert( p , nLvl ); + } + + // Generierung: dynamische TabStops setzen + SwTxtNode* pTOXNd = pDoc->GetNodes().MakeTxtNode( aInsPos , pColl ); + aSortArr[ nCnt ]->pTOXNd = pTOXNd; + + // Generierung: Form auswerten und Platzhalter + // fuer die Seitennummer eintragen + //if it is a TOX_INDEX and the SwForm IsCommaSeparated() + // then a range of entries must be generated into one paragraph + USHORT nRange = 1; + if(TOX_INDEX == SwTOXBase::GetType() && + GetTOXForm().IsCommaSeparated() && + aSortArr[nCnt]->GetType() == TOX_SORT_INDEX) + { + const SwTOXMark& rMark = aSortArr[nCnt]->pTxtMark->GetTOXMark(); + const String sPrimKey = rMark.GetPrimaryKey(); + const String sSecKey = rMark.GetSecondaryKey(); + const SwTOXMark* pNextMark = 0; + while(aSortArr.Count() > (nCnt + nRange)&& + aSortArr[nCnt + nRange]->GetType() == TOX_SORT_INDEX && + 0 != (pNextMark = &(aSortArr[nCnt + nRange]->pTxtMark->GetTOXMark())) && + pNextMark->GetPrimaryKey() == sPrimKey && + pNextMark->GetSecondaryKey() == sSecKey) + nRange++; + } + GenerateText( nCnt, nRange, aStrArr ); + nCnt += nRange - 1; + } + + // delete the first dummy node and remove all Cursor into the prev node + aInsPos = *pFirstEmptyNd; + { + SwPaM aCorPam( *pFirstEmptyNd ); + aCorPam.GetPoint()->nContent.Assign( pFirstEmptyNd, 0 ); + if( !aCorPam.Move( fnMoveForward ) ) + aCorPam.Move( fnMoveBackward ); + SwNodeIndex aEndIdx( aInsPos, 1 ); + pDoc->CorrAbs( aInsPos, aEndIdx, *aCorPam.GetPoint(), TRUE ); + + // Task 70995 - save and restore PageDesc and Break Attributes + if( pFirstEmptyNd->GetpSwAttrSet() ) + { + if( GetTitle().Len() ) + aEndIdx = *pSectNd; + else + aEndIdx = *pFirstEmptyNd; + SwCntntNode* pCNd = pDoc->GetNodes().GoNext( &aEndIdx ); + pCNd->SetAttr( *pFirstEmptyNd->GetpSwAttrSet() ); + } + } + + // now create the new Frames + ULONG nIdx = pSectNd->GetIndex(); + // don't delete if index is empty + if(nIdx + 2 < pSectNd->EndOfSectionIndex()) + pDoc->GetNodes().Delete( aInsPos, 1 ); + + aN2L.RestoreUpperFrms( pDoc->GetNodes(), nIdx, nIdx + 1 ); + SwFrm::CheckPageDescs( (SwPageFrm*)pDoc->GetRootFrm()->Lower() ); + + SetProtect( SwTOXBase::IsProtected() ); + + // ggfs. noch die International Klasse loeschen + if( pIntl != &Application::GetAppInternational() ) + delete (International*)pIntl; +} + +/*-------------------------------------------------------------------- + Beschreibung: AlphaDelimitter einfuegen + --------------------------------------------------------------------*/ + + +void SwTOXBaseSection::InsertAlphaDelimitter( const International& rIntl ) +{ + SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); + sal_Unicode nDeli, nLastDeli = 0; + USHORT i = 0; + while( i < aSortArr.Count() ) + { + ::SetProgressState( 0, pDoc->GetDocShell() ); + + USHORT nLevel = aSortArr[i]->GetLevel(); + + // Alpha-Delimitter ueberlesen + if( nLevel == FORM_ALPHA_DELIMITTER ) + continue; + + nDeli = rIntl.GetIndexChar( aSortArr[i]->GetTxt() ); + + // Delimitter schon vorhanden ?? + if( nDeli && nLastDeli != nDeli ) + { + // alle kleiner Blank wollen wir nicht haben -> sind Sonderzeichen + if( ' ' <= nDeli ) + { + SwTOXCustom* pCst = new SwTOXCustom(nDeli, FORM_ALPHA_DELIMITTER, + rIntl ); + aSortArr.Insert(pCst, i++); + } + nLastDeli = nDeli; + } + + // Skippen bis gleibhes oder kleineres Level erreicht ist + do { + i++; + } while (i < aSortArr.Count() && aSortArr[i]->GetLevel() > nLevel); + } +} + +/*-------------------------------------------------------------------- + Beschreibung: Template auswerten + --------------------------------------------------------------------*/ + +SwTxtFmtColl* SwTOXBaseSection::GetTxtFmtColl( USHORT nLevel ) +{ + SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); + const String& rName = GetTOXForm().GetTemplate( nLevel ); + SwTxtFmtColl* pColl = rName.Len() ? pDoc->FindTxtFmtCollByName(rName) :0; + if( !pColl ) + { + USHORT nPoolFmt; + const TOXTypes eType = SwTOXBase::GetType(); + switch( eType ) + { + case TOX_INDEX: nPoolFmt = RES_POOLCOLL_TOX_IDXH; break; + case TOX_USER: + if( nLevel < 6 ) + nPoolFmt = RES_POOLCOLL_TOX_USERH; + else + nPoolFmt = RES_POOLCOLL_TOX_USER6 - 6; + break; + break; + case TOX_ILLUSTRATIONS: nPoolFmt = RES_POOLCOLL_TOX_ILLUSH; break; + case TOX_OBJECTS: nPoolFmt = RES_POOLCOLL_TOX_OBJECTH; break; + case TOX_TABLES: nPoolFmt = RES_POOLCOLL_TOX_TABLESH; break; + case TOX_AUTHORITIES: nPoolFmt = RES_POOLCOLL_TOX_AUTHORITIESH; break; + + case TOX_CONTENT: + // im Content Bereich gibt es einen Sprung! + if( nLevel < 6 ) + nPoolFmt = RES_POOLCOLL_TOX_CNTNTH; + else + nPoolFmt = RES_POOLCOLL_TOX_CNTNT6 - 6; + break; + } + + if(eType == TOX_AUTHORITIES && nLevel) + nPoolFmt = nPoolFmt + 1; + else if(eType == TOX_INDEX && nLevel) + { + //pool: Level 1,2,3, Delimiter + //SwForm: Delimiter, Level 1,2,3 + nPoolFmt += 1 == nLevel ? nLevel + 3 : nLevel - 1; + } + else + nPoolFmt += nLevel; + pColl = pDoc->GetTxtCollFromPool( nPoolFmt ); + } + return pColl; +} + + +/*-------------------------------------------------------------------- + Beschreibung: Aus Markierungen erzeugen + --------------------------------------------------------------------*/ + +void SwTOXBaseSection::UpdateMarks( const International& rIntl, + const SwTxtNode* pOwnChapterNode ) +{ + const SwModify* pType = SwTOXBase::GetRegisteredIn(); + if( !pType->GetDepends() ) + return; + + SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); + TOXTypes eTOXTyp = GetTOXType()->GetType(); + SwClientIter aIter( *(SwModify*)pType ); + + SwTxtTOXMark* pTxtMark; + SwTOXMark* pMark; + for( pMark = (SwTOXMark*)aIter.First( TYPE( SwTOXMark )); pMark; + pMark = (SwTOXMark*)aIter.Next() ) + { + ::SetProgressState( 0, pDoc->GetDocShell() ); + + if( pMark->GetTOXType()->GetType() == eTOXTyp && + 0 != ( pTxtMark = pMark->GetTxtTOXMark() ) ) + { + const SwTxtNode* pTOXSrc = pTxtMark->GetpTxtNd(); + // nur TOXMarks einfuegen die im Doc stehen + // nicht die, die im UNDO stehen + // + // if selected use marks from the same chapter only + if( pTOXSrc->GetNodes().IsDocNodes() && + pTOXSrc->GetTxt().Len() && pTOXSrc->GetDepends() && + pTOXSrc->GetFrm() && + (!IsFromChapter() || + ::lcl_FindChapterNode( *pTOXSrc, 0 ) == pOwnChapterNode )) + { + SwTOXSortTabBase* pBase = 0; + if(TOX_INDEX == eTOXTyp) + { + // Stichwortverzeichnismarkierung + pBase = new SwTOXIndex( *pTOXSrc, pTxtMark, + GetOptions(), FORM_ENTRY, rIntl ); + InsertSorted(pBase); + if(GetOptions() & TOI_KEY_AS_ENTRY && + pTxtMark->GetTOXMark().GetPrimaryKey().Len()) + { + pBase = new SwTOXIndex( *pTOXSrc, pTxtMark, + GetOptions(), FORM_PRIMARY_KEY, rIntl ); + InsertSorted(pBase); + if(pTxtMark->GetTOXMark().GetSecondaryKey().Len()) + { + pBase = new SwTOXIndex( *pTOXSrc, pTxtMark, + GetOptions(), FORM_SECONDARY_KEY, rIntl ); + InsertSorted(pBase); + } + } + } + else if( TOX_USER == eTOXTyp || + pMark->GetLevel() <= GetLevel()) + { // Inhaltsberzeichnismarkierung + // also used for user marks + pBase = new SwTOXContent( *pTOXSrc, pTxtMark, rIntl ); + InsertSorted(pBase); + } + } + } + } +} + + +/*-------------------------------------------------------------------- + Beschreibung: Verzeichnisinhalt aus Gliederungsebene generieren + --------------------------------------------------------------------*/ + + +void SwTOXBaseSection::UpdateOutline( const SwTxtNode* pOwnChapterNode ) +{ + SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); + SwNodes& rNds = pDoc->GetNodes(); + + const SwOutlineNodes& rOutlNds = rNds.GetOutLineNds(); + for( USHORT n = 0; n < rOutlNds.Count(); ++n ) + { + ::SetProgressState( 0, pDoc->GetDocShell() ); + SwTxtNode* pTxtNd = rOutlNds[ n ]->GetTxtNode(); + if( pTxtNd && pTxtNd->Len() && pTxtNd->GetDepends() && + USHORT(pTxtNd->GetTxtColl()->GetOutlineLevel()+1) <= GetLevel() && + pTxtNd->GetFrm() && + ( !IsFromChapter() || + ::lcl_FindChapterNode( *pTxtNd, 0 ) == pOwnChapterNode )) + { + SwTOXPara * pNew = new SwTOXPara( *pTxtNd, TOX_TEMPLATE ); + InsertSorted( pNew ); + } + } +} + +/*-------------------------------------------------------------------- + Beschreibung: Verzeichnisinhalt aus Vorlagenbereichen generieren + --------------------------------------------------------------------*/ + +void SwTOXBaseSection::UpdateTemplate( const SwTxtNode* pOwnChapterNode ) +{ + SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); + for(USHORT i = 0; i < MAXLEVEL; i++) + { + String sTmpStyleNames = GetStyleNames(i); + USHORT nTokenCount = sTmpStyleNames.GetTokenCount(TOX_STYLE_DELIMITER); + for( USHORT nStyle = 0; nStyle < nTokenCount; ++nStyle ) + { + SwTxtFmtColl* pColl = pDoc->FindTxtFmtCollByName( + sTmpStyleNames.GetToken( nStyle, + TOX_STYLE_DELIMITER )); + //TODO: no outline Collections in content indexes if OutlineLevels are already included + if( !pColl || + ( TOX_CONTENT == SwTOXBase::GetType() && + GetCreateType() & TOX_OUTLINELEVEL && + NO_NUMBERING != pColl->GetOutlineLevel() ) ) + continue; + + SwClientIter aIter( *pColl ); + SwTxtNode* pTxtNd = (SwTxtNode*)aIter.First( TYPE( SwTxtNode )); + for( ; pTxtNd; pTxtNd = (SwTxtNode*)aIter.Next() ) + { + ::SetProgressState( 0, pDoc->GetDocShell() ); + + if( pTxtNd->GetTxt().Len() && pTxtNd->GetFrm() && + pTxtNd->GetNodes().IsDocNodes() && + ( !IsFromChapter() || pOwnChapterNode == + ::lcl_FindChapterNode( *pTxtNd, 0 ) ) ) + { + SwTOXPara * pNew = new SwTOXPara( *pTxtNd, TOX_TEMPLATE, i + 1 ); + InsertSorted(pNew); + } + } + } + } +} + +/* -----------------14.07.99 09:59------------------- + Description: generate content from sequence fields + --------------------------------------------------*/ +void SwTOXBaseSection::UpdateSequence( const SwTxtNode* pOwnChapterNode ) +{ + SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); + SwFieldType* pSeqFld = pDoc->GetFldType(RES_SETEXPFLD, GetSequenceName()); + if(!pSeqFld) + return; + + SwClientIter aIter( *pSeqFld ); + SwFmtFld* pFmtFld = (SwFmtFld*)aIter.First( TYPE( SwFmtFld )); + for( ; pFmtFld; pFmtFld = (SwFmtFld*)aIter.Next() ) + { + const SwTxtFld* pTxtFld = pFmtFld->GetTxtFld(); + const SwTxtNode& rTxtNode = pTxtFld->GetTxtNode(); + ::SetProgressState( 0, pDoc->GetDocShell() ); + + if( rTxtNode.GetTxt().Len() && rTxtNode.GetFrm() && + rTxtNode.GetNodes().IsDocNodes() && + ( !IsFromChapter() || + ::lcl_FindChapterNode( rTxtNode, 0 ) == pOwnChapterNode ) ) + { + SwTOXPara * pNew = new SwTOXPara( rTxtNode, TOX_SEQUENCE, 1 ); + //set indexes if the number or the reference text are to be displayed + if( GetCaptionDisplay() == CAPTION_TEXT ) + { + pNew->SetStartIndex( + SwGetExpField::GetReferenceTextPos( *pFmtFld, *pDoc )); + } + else if(GetCaptionDisplay() == CAPTION_NUMBER) + { + pNew->SetEndIndex(*pTxtFld->GetStart() + 1); + } + InsertSorted(pNew); + } + } +} +/* -----------------15.09.99 14:18------------------- + + --------------------------------------------------*/ +void SwTOXBaseSection::UpdateAuthorities( const SwTxtNode* pOwnChapterNode, + const International& rIntl ) +{ + SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); + SwFieldType* pAuthFld = pDoc->GetFldType(RES_AUTHORITY, aEmptyStr); + if(!pAuthFld) + return; + + SwClientIter aIter( *pAuthFld ); + SwFmtFld* pFmtFld = (SwFmtFld*)aIter.First( TYPE( SwFmtFld )); + for( ; pFmtFld; pFmtFld = (SwFmtFld*)aIter.Next() ) + { + const SwTxtFld* pTxtFld = pFmtFld->GetTxtFld(); + //undo + if(!pTxtFld) + continue; + const SwTxtNode& rTxtNode = pTxtFld->GetTxtNode(); + ::SetProgressState( 0, pDoc->GetDocShell() ); + +// const SwTxtNode* pChapterCompareNode = 0; + + if( rTxtNode.GetTxt().Len() && rTxtNode.GetFrm() && + rTxtNode.GetNodes().IsDocNodes() /*&& + (!IsFromChapter() || pChapterCompareNode == pOwnChapterNode) */) + { + SwTOXAuthority* pNew = new SwTOXAuthority( rTxtNode, *pFmtFld, rIntl ); + + InsertSorted(pNew); + } + } +} + +/*-------------------------------------------------------------------- + Beschreibung: Verzeichnisinhalt aus Inhaltsformen generieren + OLE, Grafik, Frame + Achtung: Spezielle Section ! + --------------------------------------------------------------------*/ +/* + nPos = pNd->GetIndex(); + if( nPos < pNd->GetNodes().GetEndOfExtras().GetIndex() ) + { + // dann die "Anker" (Body) Position holen. + Point aPt; + const SwCntntFrm* pFrm = pNd->GetFrm( &aPt, 0, FALSE ); + if( pFrm ) + { + SwPosition aPos( *pNd ); + SwDoc* pDoc = (SwDoc*)pNd->GetDoc(); +#ifndef PRODUCT + ASSERT( GetBodyTxtNode( pDoc, aPos, pFrm ), + "wo steht der Absatz" ); +#else + GetBodyTxtNode( pDoc, aPos, pFrm ); +#endif + nPos = aPos.nNode.GetIndex(); + nCntPos = aPos.nContent.GetIndex(); + } + } + + + + */ +void SwTOXBaseSection::UpdateCntnt( SwTOXElement eType, + const SwTxtNode* pOwnChapterNode ) +{ + SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); + SwNodes& rNds = pDoc->GetNodes(); + // auf den 1. Node der 1. Section + ULONG nIdx = rNds.GetEndOfAutotext().StartOfSectionIndex() + 2, + nEndIdx = rNds.GetEndOfAutotext().GetIndex(); + + while( nIdx < nEndIdx ) + { + ::SetProgressState( 0, pDoc->GetDocShell() ); + + SwNode* pNd = rNds[ nIdx ]; + SwCntntNode* pCNd = 0; + switch( eType ) + { + case TOX_FRAME: + if( !pNd->IsNoTxtNode() ) + { + pCNd = pNd->GetCntntNode(); + if( !pCNd ) + { + SwNodeIndex aTmp( *pNd ); + pCNd = rNds.GoNext( &aTmp ); + } + } + break; + case TOX_GRAPHIC: + if( pNd->IsGrfNode() ) + pCNd = (SwCntntNode*)pNd; + break; + case TOX_OLE: + if( pNd->IsOLENode() ) + { + BOOL bInclude = FALSE; + if(TOX_OBJECTS == SwTOXBase::GetType()) + { + SwOLENode* pOLENode = pNd->GetOLENode(); + long nOLEOptions = GetOLEOptions(); + // + const SwOLEObj& rOLEObj = pOLENode->GetOLEObj(); + + if ( pOLENode->GetOLEObj().IsOleRef() ) //Noch nicht geladen + { + BOOL bMath = SmModuleDummy::HasID( + *pOLENode->GetOLEObj().GetOleRef()->GetSvFactory()); + BOOL bChart = SchModuleDummy::HasID( + *pOLENode->GetOLEObj().GetOleRef()->GetSvFactory()); + BOOL bImage = SimModuleDummy::HasID( + *pOLENode->GetOLEObj().GetOleRef()->GetSvFactory()); + BOOL bCalc = ScModuleDummy::HasID( + *pOLENode->GetOLEObj().GetOleRef()->GetSvFactory()); + BOOL bDrawImage = SdModuleDummy::HasID( + *pOLENode->GetOLEObj().GetOleRef()->GetSvFactory()); + if( + (nOLEOptions & TOO_MATH) && bMath || + (nOLEOptions & TOO_CHART)&& bChart || + (nOLEOptions & TOO_IMAGE) && bImage || + (nOLEOptions & TOO_CALC) && bCalc || + (nOLEOptions & TOO_DRAW_IMPRESS) && bDrawImage || + (nOLEOptions & TOO_OTHER) && + !bMath && !bChart && !bImage && !bCalc && !bDrawImage) + bInclude = TRUE; + } + else + { + DBG_ERROR("OLE-object nicht geladen?") + } + } + else + bInclude = TRUE; + if(bInclude) + pCNd = (SwCntntNode*)pNd; + } + break; + } + + if( pCNd ) + { + //find node in body text + Point aPt; + const SwCntntFrm* pFrm = pCNd->GetFrm( &aPt, 0, FALSE ); + USHORT nSetLevel = USHRT_MAX; + + if( IsLevelFromChapter() ) + { + const SwTxtNode* pOutlNd = ::lcl_FindChapterNode( *pCNd, + MAXLEVEL - 1 ); + if( pOutlNd ) + { + USHORT nTmp = pOutlNd->GetTxtColl()->GetOutlineLevel(); + if( nTmp < NO_NUMBERING ) + nSetLevel = nTmp + 1; + } + } + + if( pCNd->GetFrm() && ( !IsFromChapter() || + ::lcl_FindChapterNode( *pCNd, 0 ) == pOwnChapterNode )) + { + SwTOXPara * pNew = new SwTOXPara( *pCNd, eType, + USHRT_MAX != nSetLevel ? nSetLevel : FORM_ALPHA_DELIMITTER ); + InsertSorted( pNew ); + } + } + + nIdx = pNd->FindStartNode()->EndOfSectionIndex() + 2; // 2 == End-/StartNode + } +} + +/*-------------------------------------------------------------------- + Beschreibung: Tabelleneintraege zusammensuchen + --------------------------------------------------------------------*/ + +void SwTOXBaseSection::UpdateTable( const SwTxtNode* pOwnChapterNode ) +{ + SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); + SwNodes& rNds = pDoc->GetNodes(); + const SwFrmFmts& rArr = *pDoc->GetTblFrmFmts(); + + for( USHORT n = 0; n < rArr.Count(); ++n ) + { + ::SetProgressState( 0, pDoc->GetDocShell() ); + + SwTable* pTmpTbl = SwTable::FindTable( rArr[ n ] ); + SwTableBox* pFBox; + if( pTmpTbl && 0 != (pFBox = pTmpTbl->GetTabSortBoxes()[0] ) && + pFBox->GetSttNd() && pFBox->GetSttNd()->GetNodes().IsDocNodes() ) + { + const SwTableNode* pTblNd = pFBox->GetSttNd()->FindTableNode(); + SwNodeIndex aCntntIdx( *pTblNd, 1 ); + + SwCntntNode* pCNd; + while( 0 != ( pCNd = rNds.GoNext( &aCntntIdx ) ) && + aCntntIdx.GetIndex() < pTblNd->EndOfSectionIndex() ) + { + if( pCNd->GetFrm() && (!IsFromChapter() || + ::lcl_FindChapterNode( *pCNd, 0 ) == pOwnChapterNode )) + { + SwTOXTable * pNew = new SwTOXTable( *pCNd ); + if( IsLevelFromChapter() ) + { + const SwTxtNode* pOutlNd = + ::lcl_FindChapterNode( *pCNd, MAXLEVEL - 1 ); + if( pOutlNd ) + { + USHORT nTmp = pOutlNd->GetTxtColl()->GetOutlineLevel(); + if( nTmp < NO_NUMBERING ) + pNew->SetLevel( nTmp + 1 ); + } + } + InsertSorted(pNew); + break; + } + } + } + } +} + +/*-------------------------------------------------------------------- + Beschreibung: String generieren anhand der Form + SonderZeichen 0-31 und 255 entfernen + --------------------------------------------------------------------*/ + +String lcl_GetNumString( const SwTOXSortTabBase& rBase ) +{ + String sRet; + + if( !rBase.pTxtMark && rBase.aTOXSources.Count() > 0 ) + { // nur wenn es keine Marke ist + const SwTxtNode* pNd = rBase.aTOXSources[0].pNd->GetTxtNode(); + if( pNd ) + { + const SwNodeNum* pNum; + const SwNumRule* pRule; + + if( (( 0 != ( pNum = pNd->GetNum() ) && + 0 != ( pRule = pNd->GetNumRule() )) || + ( 0 != ( pNum = pNd->GetOutlineNum() ) && + 0 != ( pRule = pNd->GetDoc()->GetOutlineNumRule() ) ) ) && + pNum->GetLevel() < MAXLEVEL ) + sRet = pRule->MakeNumString( *pNum ); + } + } + return sRet; +} + +void SwTOXBaseSection::GenerateText( USHORT nArrayIdx, USHORT nCount, + SvStringsDtor& rTabForms ) +{ + LinkStructArr aLinkArr; + SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); + ::SetProgressState( 0, pDoc->GetDocShell() ); + + //pTOXNd is only set at the first mark + SwTxtNode* pTOXNd = (SwTxtNode*)aSortArr[nArrayIdx]->pTOXNd; + String& rTxt = (String&)pTOXNd->GetTxt(); + rTxt.Erase(); + for(USHORT nIndex = nArrayIdx; nIndex < nArrayIdx + nCount; nIndex++) + { + if(nIndex > nArrayIdx) + rTxt.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ", " )); // comma separation + // String mit dem Pattern aus der Form initialisieren + const SwTOXSortTabBase& rBase = *aSortArr[nIndex]; + USHORT nLvl = rBase.GetLevel(); + ASSERT( nLvl < GetTOXForm().GetFormMax(), "ungueltiges FORM_LEVEL"); + + SvxTabStopItem aTStops( 0, 0 ); + xub_StrLen nLinkStartPosition = STRING_NOTFOUND; + String sURL; + // create an enumerator + SwFormTokenEnumerator aTokenEnum = GetTOXForm().CreateTokenEnumerator(nLvl); + // remove text from node + while(aTokenEnum.HasNextToken()) + { + SwFormToken aToken = aTokenEnum.GetNextToken(); + xub_StrLen nStartCharStyle = rTxt.Len(); + switch( aToken.eTokenType ) + { + case TOKEN_ENTRY_NO: + // fuer Inhaltsverzeichnis Numerierung + rTxt.Insert( lcl_GetNumString( rBase )); + break; + + case TOKEN_ENTRY_TEXT: + { + SwIndex aIdx( pTOXNd, rTxt.Len() ); + rBase.FillText( *pTOXNd, aIdx ); + } + break; + + case TOKEN_ENTRY: + { + // fuer Inhaltsverzeichnis Numerierung + rTxt.Insert( lcl_GetNumString( rBase )); + + SwIndex aIdx( pTOXNd, rTxt.Len() ); + rBase.FillText( *pTOXNd, aIdx ); + } + break; + + case TOKEN_TAB_STOP: + rTxt.Append('\t'); + // + if(SVX_TAB_ADJUST_END > aToken.eTabAlign) + { + const SvxLRSpaceItem& rLR = (SvxLRSpaceItem&)pTOXNd-> + SwCntntNode::GetAttr( RES_LR_SPACE ); + + long nTabPosition = aToken.nTabStopPosition; + if( !GetTOXForm().IsRelTabPos() && rLR.GetTxtLeft() ) + nTabPosition -= rLR.GetTxtLeft(); + aTStops.Insert( SvxTabStop( nTabPosition, + SVX_TAB_ADJUST_LEFT, + cDfltDecimalChar, + aToken.cTabFillChar )); + } + else + { + const SwPageDesc* pPageDesc = ((SwFmtPageDesc&)pTOXNd-> + SwCntntNode::GetAttr( RES_PAGEDESC )).GetPageDesc(); + + BOOL bCallFindRect = TRUE; + long nRightMargin; + if( pPageDesc ) + { + const SwFrm* pFrm = pTOXNd->GetFrm( 0, 0, TRUE ); + if( !pFrm || 0 == ( pFrm = pFrm->FindPageFrm() ) || + pPageDesc != ((SwPageFrm*)pFrm)->GetPageDesc() ) + // dann muss man ueber den PageDesc gehen + bCallFindRect = FALSE; + } + + SwRect aNdRect; + if( bCallFindRect ) + aNdRect = pTOXNd->FindLayoutRect( TRUE ); + + if( aNdRect.IsEmpty() ) + { + // dann hilft alles nichts, wir muessen ueber die Seiten- + // vorlage gehen. + if( !pPageDesc && + 0 == (pPageDesc = pTOXNd->FindPageDesc( FALSE ) ) ) + pPageDesc = &pDoc->GetPageDesc( 0 ); + + const SwFrmFmt& rPgDscFmt = pPageDesc->GetMaster(); + nRightMargin = rPgDscFmt.GetFrmSize().GetWidth() - + rPgDscFmt.GetLRSpace().GetLeft() - + rPgDscFmt.GetLRSpace().GetRight(); + } + else + nRightMargin = aNdRect.Width(); + aTStops.Insert( SvxTabStop( nRightMargin,SVX_TAB_ADJUST_RIGHT, + cDfltDecimalChar, + aToken.cTabFillChar )); + } + break; + + case TOKEN_TEXT: + rTxt.Append( aToken.sText ); + break; + + case TOKEN_PAGE_NUMS: + // Platzhalter fuer Seitennummer(n) es wird nur der erste beachtet + // + { + // Die Anzahl der gleichen Eintrage bestimmt die Seitennummern-Pattern + // + USHORT nSize = rBase.aTOXSources.Count(); + if( nSize > 0 ) + { + String aInsStr( cNumRepl ); + for(USHORT i=1; i < nSize; ++i) + { + aInsStr.AppendAscii( sPageDeli ); + aInsStr += cNumRepl; + } + aInsStr += cEndPageNum; + rTxt.Append( aInsStr ); + } +// // Tab entfernen, wenn keine Seitennummer +// else if( rTxt.Len() && '\t' == rTxt.GetChar( rTxt.Len() - 1 )) +// rTxt.Erase( rTxt.Len()-1, 1 ); + } + break; + + case TOKEN_CHAPTER_INFO: + { + // ein bischen trickreich: suche irgend einen Frame + const SwTOXSource* pTOXSource = 0; + if(rBase.aTOXSources.Count()) + pTOXSource = &rBase.aTOXSources[0]; + if( pTOXSource && pTOXSource->pNd && pTOXSource->pNd->IsTxtNode() ) + { + const SwCntntFrm* pFrm = pTOXSource->pNd->GetFrm(); + if( pFrm ) + { + SwChapterFieldType aFldTyp; + SwChapterField aFld( &aFldTyp, aToken.nChapterFormat ); + aFld.SetLevel( MAXLEVEL - 1 ); + aFld.ChangeExpansion( pFrm, (SwTxtNode*)pTOXSource->pNd, TRUE ); + + if(CF_NUMBER == aToken.nChapterFormat) + rTxt.Insert(aFld.GetNumber()); + else if(CF_NUM_TITLE == aToken.nChapterFormat) + { + rTxt += aFld.GetNumber(); + rTxt += ' '; + rTxt += aFld.GetTitle(); + } + else if(CF_TITLE == aToken.nChapterFormat) + rTxt += aFld.GetTitle(); + } + } + } + break; + + case TOKEN_LINK_START: + nLinkStartPosition = rTxt.Len(); + break; + + case TOKEN_LINK_END: + //TODO: only paired start/end tokens are valid + if( STRING_NOTFOUND != nLinkStartPosition) + { + SwIndex aIdx( pTOXNd, nLinkStartPosition ); + //pTOXNd->Erase( aIdx, SwForm::nFormLinkSttLen ); + xub_StrLen nEnd = rTxt.Len(); + + if( !sURL.Len() ) + { + sURL = rBase.GetURL(); + if( !sURL.Len() ) + break; + } + aLinkArr.Insert( new LinkStruct(sURL, nLinkStartPosition, + nEnd), aLinkArr.Count() ); + nLinkStartPosition = STRING_NOTFOUND; + } + break; + + case TOKEN_AUTHORITY: + { + ToxAuthorityField eField = (ToxAuthorityField)aToken.nAuthorityField; + SwIndex aIdx( pTOXNd, rTxt.Len() ); + rBase.FillText( *pTOXNd, aIdx, eField ); + } + break; + } + + if( aToken.sCharStyleName.Len() ) + { + SwCharFmt* pCharFmt; + if( USHRT_MAX != aToken.nPoolId ) + pCharFmt = pDoc->GetCharFmtFromPool( aToken.nPoolId ); + else + pCharFmt = pDoc->FindCharFmtByName( aToken.sCharStyleName); + + if(pCharFmt) + pTOXNd->Insert( SwFmtCharFmt( pCharFmt ), nStartCharStyle, + rTxt.Len(), SETATTR_DONTEXPAND ); + } + } + pTOXNd->SwCntntNode::SetAttr( aTStops ); + } + + if(aLinkArr.Count()) + for(USHORT i = 0; i < aLinkArr.Count(); ++i ) + { + LinkStruct* pTmp = aLinkArr.GetObject(i); + pTOXNd->Insert( pTmp->aINetFmt, pTmp->nStartTextPos, + pTmp->nEndTextPos); + } +} + +/*-------------------------------------------------------------------- + Beschreibung: Seitennummer errechnen und nach dem Formatieren + eintragen + --------------------------------------------------------------------*/ + +void SwTOXBaseSection::UpdatePageNum() +{ + // die aktuellen Seitennummern ins Verzeichnis eintragen + SwPageFrm* pAktPage = 0; + USHORT nPage = 0; + SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); + for( USHORT nCnt = 0; nCnt < aSortArr.Count(); ++nCnt ) + { + // Schleife ueber alle SourceNodes + SvUShorts aNums; //Die Seitennummern + SvPtrarr aDescs; //Die PageDescriptoren passend zu den Seitennummern. + SvUShorts* pMainNums = 0; // contains page numbers of main entries + + // process run in lines + USHORT nRange = 0; + if(GetTOXForm().IsCommaSeparated() && + aSortArr[nCnt]->GetType() == TOX_SORT_INDEX) + { + const SwTOXMark& rMark = aSortArr[nCnt]->pTxtMark->GetTOXMark(); + const String sPrimKey = rMark.GetPrimaryKey(); + const String sSecKey = rMark.GetSecondaryKey(); + const SwTOXMark* pNextMark = 0; + while(aSortArr.Count() > (nCnt + nRange)&& + aSortArr[nCnt + nRange]->GetType() == TOX_SORT_INDEX && + 0 != (pNextMark = &(aSortArr[nCnt + nRange]->pTxtMark->GetTOXMark())) && + pNextMark->GetPrimaryKey() == sPrimKey && + pNextMark->GetSecondaryKey() == sSecKey) + nRange++; + } + else + nRange = 1; + + for(USHORT nRunInEntry = nCnt; nRunInEntry < nCnt + nRange; nRunInEntry++) + { + SwTOXSortTabBase* pSortBase = aSortArr[nRunInEntry]; + USHORT nSize = pSortBase->aTOXSources.Count(); + for( USHORT j = 0; j < nSize; ++j ) + { + ::SetProgressState( 0, pDoc->GetDocShell() ); + + SwTOXSource& rTOXSource = pSortBase->aTOXSources[j]; + if( rTOXSource.pNd ) + { + SwCntntFrm* pFrm = rTOXSource.pNd->GetFrm(); + ASSERT( pFrm, "TOX, no Frame found" ); + if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->HasFollow() ) + { + // dann suche den richtigen heraus + SwTxtFrm* pNext = (SwTxtFrm*)pFrm; + while( 0 != ( pNext = (SwTxtFrm*)pFrm->GetFollow() ) + && rTOXSource.nPos >= pNext->GetOfst() ) + pFrm = pNext; + } + + SwPageFrm* pTmpPage = pFrm->FindPageFrm(); + if( pTmpPage != pAktPage ) + { + nPage = pTmpPage->GetVirtPageNum(); + pAktPage = pTmpPage; + } + + // sortiert einfuegen + for( USHORT i = 0; i < aNums.Count() && aNums[i] < nPage; ++i ) + ; + + if( i >= aNums.Count() || aNums[ i ] != nPage ) + { + aNums.Insert( nPage, i ); + aDescs.Insert( (void*)pAktPage->GetPageDesc(), i ); + } + // is it a main entry? + if(TOX_SORT_INDEX == pSortBase->GetType() && + rTOXSource.bMainEntry) + { + if(!pMainNums) + pMainNums = new SvUShorts; + pMainNums->Insert(nPage, pMainNums->Count()); + } + } + } + // einfuegen der Seitennummer in den Verzeichnis-Text-Node + const SwTOXSortTabBase* pBase = aSortArr[ nCnt ]; + if(pBase->pTOXNd) + { + const SwTxtNode* pTxtNd = pBase->pTOXNd->GetTxtNode(); + ASSERT( pTxtNd, "kein TextNode, falsches Verzeichnis" ); + + _UpdatePageNum( (SwTxtNode*)pTxtNd, aNums, aDescs, pMainNums ); + } + DELETEZ(pMainNums); + aNums.Remove(0, aNums.Count()); + } + } + // nach dem Setzen der richtigen Seitennummer, das Mapping-Array + // wieder loeschen !! + aSortArr.DeleteAndDestroy( 0, aSortArr.Count() ); +} + + +/*-------------------------------------------------------------------- + Beschreibung: Austausch der Seitennummer-Platzhalter + --------------------------------------------------------------------*/ + +// search for the page no in the array of main entry page numbers +BOOL lcl_HasMainEntry( const SvUShorts* pMainEntryNums, USHORT nToFind ) +{ + for(USHORT i = 0; pMainEntryNums && i < pMainEntryNums->Count(); ++i) + if(nToFind == (*pMainEntryNums)[i]) + return TRUE; + return FALSE; +} + +void SwTOXBaseSection::_UpdatePageNum( SwTxtNode* pNd, + const SvUShorts& rNums, + const SvPtrarr & rDescs, + const SvUShorts* pMainEntryNums) +{ + //collect starts end ends of main entry character style + SvUShorts* pCharStyleIdx = pMainEntryNums ? new SvUShorts : 0; + + String sSrchStr( cNumRepl ); sSrchStr.AppendAscii( sPageDeli ) += cNumRepl; + xub_StrLen nStartPos = pNd->GetTxt().Search( sSrchStr ); + ( sSrchStr = cNumRepl ) += cEndPageNum; + xub_StrLen nEndPos = pNd->GetTxt().Search( sSrchStr ); + + if( STRING_NOTFOUND == nEndPos || !rNums.Count() ) + return; + + if( STRING_NOTFOUND == nStartPos || nStartPos > nEndPos) + nStartPos = nEndPos; + + USHORT nOld = rNums[0], + nBeg = nOld, + nCount = 0; + String aNumStr( SwNumType( ((SwPageDesc*)rDescs[0])->GetNumType() ). + GetNumStr( nBeg ) ); + if( pCharStyleIdx && lcl_HasMainEntry( pMainEntryNums, nBeg )) + { + USHORT nTemp = 0; + pCharStyleIdx->Insert( nTemp, pCharStyleIdx->Count()); + } + + // Platzhalter loeschen + SwIndex aPos(pNd, nStartPos); + const SwFmtCharFmt* pPageNoCharFmt = 0; + SwpHints* pHints = pNd->GetpSwpHints(); + if(pHints) + for(USHORT nHintIdx = 0; nHintIdx < pHints->GetStartCount(); nHintIdx++) + { + SwTxtAttr* pAttr = pHints->GetStart(nHintIdx); + xub_StrLen nTmpEnd = pAttr->GetEnd() ? *pAttr->GetEnd() : 0; + if( nStartPos >= *pAttr->GetStart() && + (nStartPos + 2) <= nTmpEnd && + pAttr->Which() == RES_TXTATR_CHARFMT) + { + pPageNoCharFmt = &pAttr->GetCharFmt(); + break; + } + } + pNd->Erase(aPos, nEndPos - nStartPos + 2); + + for(USHORT i = 1; i < rNums.Count(); ++i) + { + SwNumType aType( ((SwPageDesc*)rDescs[i])->GetNumType() ); + if( TOX_INDEX == SwTOXBase::GetType() ) + { // Zusammenfassen f. ff. + // Alle folgenden aufaddieren + // break up if main entry starts or ends and + // insert a char style index + BOOL bMainEntryChanges = lcl_HasMainEntry(pMainEntryNums, nOld) + != lcl_HasMainEntry(pMainEntryNums, rNums[i]); + + if(nOld == rNums[i]-1 && !bMainEntryChanges && + 0 != (GetOptions() & (TOI_FF|TOI_DASH))) + nCount++; + else + { + // ff. f. alten Wert flushen + if(GetOptions() & TOI_FF) + { + if ( nCount >= 1 ) + { + FollowingText eText = nCount > 1 ? FOLLOWTEXT_PAGES + : FOLLOWTEXT_PAGE; + aNumStr += Application::GetAppInternational(). + GetFollowingText( eText ); + } + } + else + { + if(nCount >= 2 ) + aNumStr += '-'; + else if(nCount == 1 ) + aNumStr.AppendAscii( sPageDeli ); +//#58127# Wenn nCount == 0, dann steht die einzige Seitenzahl schon im aNumStr! + if(nCount) + aNumStr += aType.GetNumStr( nBeg + nCount ); + } + + // neuen String anlegen + nBeg = rNums[i]; + aNumStr.AppendAscii( sPageDeli ); + //the change of the character style must apply after sPageDeli is appended + if(pCharStyleIdx && bMainEntryChanges) + pCharStyleIdx->Insert(aNumStr.Len(), + pCharStyleIdx->Count()); + aNumStr += aType.GetNumStr( nBeg ); + nCount = 0; + } + nOld = rNums[i]; + } + else + { // Alle Nummern eintragen + aNumStr += aType.GetNumStr( USHORT(rNums[i]) ); + if(i != (rNums.Count()-1)) + aNumStr.AppendAscii( sPageDeli ); + } + } + // Bei Ende und ff. alten Wert flushen + if( TOX_INDEX == SwTOXBase::GetType() ) + { + if(GetOptions() & TOI_FF) + { + if( nCount >= 1 ) + { + FollowingText eText = nCount > 1 ? FOLLOWTEXT_PAGES + : FOLLOWTEXT_PAGE; + aNumStr += Application::GetAppInternational(). + GetFollowingText( eText ); + } + } + else + { + if(nCount >= 2) + aNumStr +='-'; + else if(nCount == 1) + aNumStr.AppendAscii( sPageDeli ); +//#58127# Wenn nCount == 0, dann steht die einzige Seitenzahl schon im aNumStr! + if(nCount) + aNumStr += SwNumType( ((SwPageDesc*)rDescs[i-1])-> + GetNumType() ).GetNumStr( nBeg+nCount ); + } + } + pNd->Insert( aNumStr, aPos, INS_EMPTYEXPAND ); + if(pPageNoCharFmt) + { + SwDoc* pDoc = pNd->GetDoc(); + SwFmtCharFmt aCharFmt(pPageNoCharFmt->GetCharFmt()); + pNd->Insert(aCharFmt, nStartPos, nStartPos + aNumStr.Len(), SETATTR_DONTEXPAND); + } + + //now the main entries should get there character style + if(pCharStyleIdx && pCharStyleIdx->Count() && GetMainEntryCharStyle().Len()) + { + // eventually the last index must me appended + if(pCharStyleIdx->Count()&0x01) + pCharStyleIdx->Insert(aNumStr.Len(), pCharStyleIdx->Count()); + + //search by name + SwDoc* pDoc = pNd->GetDoc(); + USHORT nPoolId = pDoc->GetPoolId( GetMainEntryCharStyle(), GET_POOLID_CHRFMT ); + SwCharFmt* pCharFmt = 0; + if(USHRT_MAX != nPoolId) + pCharFmt = pDoc->GetCharFmtFromPool(nPoolId); + else + pCharFmt = pDoc->FindCharFmtByName( GetMainEntryCharStyle() ); + if(!pCharFmt) + pCharFmt = pDoc->MakeCharFmt(GetMainEntryCharStyle(), 0); + + //find the page numbers in aNumStr and set the character style + xub_StrLen nOffset = pNd->GetTxt().Len() - aNumStr.Len(); + SwFmtCharFmt aCharFmt(pCharFmt); + for(USHORT i = 0; i < pCharStyleIdx->Count(); i += 2) + { + xub_StrLen nStartIdx = (*pCharStyleIdx)[i] + nOffset; + xub_StrLen nEndIdx = (*pCharStyleIdx)[i + 1] + nOffset; + pNd->Insert(aCharFmt, nStartIdx, nEndIdx, SETATTR_DONTEXPAND); + } + + } + delete pCharStyleIdx; +} + + +/*-------------------------------------------------------------------- + Beschreibung: Sortiert einfuegen in das SortArr + --------------------------------------------------------------------*/ + +void SwTOXBaseSection::InsertSorted(SwTOXSortTabBase* pNew) +{ + Range aRange(0, aSortArr.Count()); + if( TOX_INDEX == SwTOXBase::GetType() && pNew->pTxtMark ) + { + const SwTOXMark& rMark = pNew->pTxtMark->GetTOXMark(); + // Schluessel auswerten + // Den Bereich ermitteln, in dem einzufuegen ist + if( 0 == (GetOptions() & TOI_KEY_AS_ENTRY) && + rMark.GetPrimaryKey().Len() ) + { + aRange = GetKeyRange( rMark.GetPrimaryKey(), FORM_PRIMARY_KEY, + aRange, *pNew->pIntl ); + if( rMark.GetSecondaryKey().Len() ) + aRange = GetKeyRange( rMark.GetSecondaryKey(), FORM_SECONDARY_KEY, + aRange, *pNew->pIntl ); + } + } + // Pos suchen und einfuegen + // + for(short i = (short)aRange.Min(); i < (short)aRange.Max(); ++i) + { // nur auf gleicher Ebene pruefen + // + SwTOXSortTabBase* pOld = aSortArr[i]; + if(*pOld == *pNew) + { + if(TOX_AUTHORITIES == SwTOXBase::GetType()) + { + //only the first occurence in the document + //has to be in the array + if(*pOld < *pNew) + { + delete pNew; + } + else + { + // remove the old content + aSortArr.DeleteAndDestroy( i, 1 ); + aSortArr.Insert(pNew, i ); + } + return; + } + else + { + // Eigener Eintrag fuer Doppelte oder Keywords + // + if( pOld->GetType() == TOX_SORT_CUSTOM && + pNew->GetOptions() & TOI_KEY_AS_ENTRY) + continue; + + if(!(pNew->GetOptions() & TOI_SAME_ENTRY)) + { // Eigener Eintrag + aSortArr.Insert(pNew, i ); + return; + } + // Eintrag schon vorhanden in Referenzliste aufnehmen + pOld->aTOXSources.Insert( pNew->aTOXSources[0], + pOld->aTOXSources.Count() ); + + delete pNew; + return; + } + } + if(*pNew < *pOld) + break; + } + // SubLevel Skippen + while( TOX_INDEX == SwTOXBase::GetType() && i < aRange.Max() && + aSortArr[i]->GetLevel() > pNew->GetLevel() ) + i++; + + // An Position i wird eingefuegt + aSortArr.Insert(pNew, i ); +} + +/*-------------------------------------------------------------------- + Beschreibung: Schluessel-Bereich suchen und evtl einfuegen + --------------------------------------------------------------------*/ + +Range SwTOXBaseSection::GetKeyRange(const String& rStr, + USHORT nLevel, + const Range& rRange, + const International& rIntl ) +{ + String sToCompare(rStr); + if(0 != (TOI_INITIAL_CAPS & GetOptions())) + sToCompare.SetChar(0, rIntl.Upper(sToCompare.GetChar(0))); + + ASSERT(rRange.Min() >= 0 && rRange.Max() >= 0, "Min Max < 0"); + + const USHORT nMin = (USHORT)rRange.Min(); + const USHORT nMax = (USHORT)rRange.Max(); + + USHORT nOptions = GetOptions(); + USHORT nCmpFlags = (nOptions & TOI_SAME_ENTRY) && 0 == (nOptions & TOI_CASE_SENSITIVE) + ? INTN_COMPARE_IGNORECASE : 0; + for(USHORT i = nMin; i < nMax; ++i) + { + SwTOXSortTabBase* pBase = aSortArr[i]; + String aTmp = pBase->GetTxt(); + if( rIntl.CompareEqual( aTmp, sToCompare, nCmpFlags ) && + pBase->GetLevel() == nLevel && + pBase->GetType() == TOX_SORT_CUSTOM) + break; + } + if(i == nMax) + { // Falls nicht vorhanden erzeugen und einfuegen + // + SwTOXCustom* pKey = new SwTOXCustom( sToCompare, nLevel, rIntl ); + for(i = nMin; i < nMax; ++i) + { + if(nLevel == aSortArr[i]->GetLevel() && *pKey < *(aSortArr[i])) + break; + } + aSortArr.Insert(pKey, i ); + } + USHORT nStart = i+1; + USHORT nEnd = aSortArr.Count(); + + // Ende des Bereiches suchen + for(i = nStart; i < aSortArr.Count(); ++i) + { + if(aSortArr[i]->GetLevel() <= nLevel) + { nEnd = i; + break; + } + } + return Range(nStart, nEnd); +} + + +BOOL SwTOXBase::IsTOXBaseInReadonly() const +{ + const SwTOXBaseSection *pSect = PTR_CAST(SwTOXBaseSection, this); + BOOL bRet = FALSE; + const SwSectionNode* pSectNode; + if(pSect && pSect->GetFmt() && + 0 != (pSectNode = pSect->GetFmt()->GetSectionNode())) + { + const SwDocShell* pDocSh; + bRet = (0 != (pDocSh = pSectNode->GetDoc()->GetDocShell()) && + pDocSh->IsReadOnly()) || + (0 != (pSectNode = pSectNode->FindStartNode()->FindSectionNode())&& + pSectNode->GetSection().IsProtectFlag()); + + } + return bRet; +} +/* -----------------17.08.99 13:29------------------- + + --------------------------------------------------*/ +const SfxItemSet* SwTOXBase::GetAttrSet() const +{ + const SwTOXBaseSection *pSect = PTR_CAST(SwTOXBaseSection, this); + if(pSect && pSect->GetFmt()) + return &pSect->GetFmt()->GetAttrSet(); + return 0; +} + +void SwTOXBase::SetAttrSet( const SfxItemSet& rSet ) +{ + SwTOXBaseSection *pSect = PTR_CAST(SwTOXBaseSection, this); + if( pSect && pSect->GetFmt() ) + pSect->GetFmt()->SetAttr( rSet ); +} + +BOOL SwTOXBase::GetInfo( SfxPoolItem& rInfo ) const +{ + switch( rInfo.Which() ) + { + case RES_CONTENT_VISIBLE: + { + SwTOXBaseSection *pSect = PTR_CAST(SwTOXBaseSection, this); + if( pSect && pSect->GetFmt() ) + pSect->GetFmt()->GetInfo( rInfo ); + } + return FALSE; + } + return TRUE; +} + +/* */ + + diff --git a/sw/source/core/doc/extinput.cxx b/sw/source/core/doc/extinput.cxx new file mode 100644 index 000000000000..79dd3f5a058c --- /dev/null +++ b/sw/source/core/doc/extinput.cxx @@ -0,0 +1,286 @@ +/************************************************************************* + * + * $RCSfile: extinput.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:15 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _HINTIDS_HXX +#include +#endif + +#ifndef _SV_KEYCODES_HXX +#include +#endif +#ifndef _VCL_CMDEVT_HXX +#include +#endif +#ifndef _EXTINPUT_HXX +#include +#endif +#ifndef _DOC_HXX +#include +#endif +#ifndef _INDEX_HXX +#include +#endif +#ifndef _NDTXT_HXX +#include +#endif +#ifndef _TXTFRM_HXX +#include +#endif +#ifndef _HINTS_HXX +#include +#endif + + +SwExtTextInput::SwExtTextInput( const SwPaM& rPam, Ring* pRing ) + : SwPaM( *rPam.GetPoint(), (SwPaM*)pRing ), bInsText( TRUE ) +{ +} + +SwExtTextInput::~SwExtTextInput() +{ + SwTxtNode* pTNd = GetPoint()->nNode.GetNode().GetTxtNode(); + if( pTNd ) + { + xub_StrLen nEndCnt = GetPoint()->nContent.GetIndex(), + nSttCnt = GetMark()->nContent.GetIndex(); + if( nEndCnt != nSttCnt ) + { + if( nEndCnt < nSttCnt ) + { + xub_StrLen n = nEndCnt; nEndCnt = nSttCnt; nSttCnt = n; + } + + // damit Undo / Redlining usw. richtig funktioniert, + // muss ueber die Doc-Schnittstellen gegangen werden !!! + SwIndex aIdx( pTNd, nSttCnt ); + String sTxt( pTNd->GetTxt().Copy( nSttCnt, nEndCnt - nSttCnt )); + pTNd->Erase( aIdx, nEndCnt - nSttCnt ); + + if( bInsText ) + GetDoc()->Insert( *this, sTxt ); + } + } +} + +void SwExtTextInput::SetInputData( const CommandExtTextInputData& rData ) +{ + SwTxtNode* pTNd = GetPoint()->nNode.GetNode().GetTxtNode(); + if( pTNd ) + { + xub_StrLen nEndCnt = GetPoint()->nContent.GetIndex(), + nSttCnt = GetMark()->nContent.GetIndex(); + if( nEndCnt < nSttCnt ) + { + xub_StrLen n = nEndCnt; nEndCnt = nSttCnt; nSttCnt = n; + } + SwIndex aIdx( pTNd, nSttCnt ); + + if( nSttCnt < nEndCnt ) + pTNd->Erase( aIdx, nEndCnt - nSttCnt ); + + pTNd->Insert( rData.GetText(), aIdx ); + + SetMark(); + GetPoint()->nContent = nSttCnt; + + if( aAttrs.Count() ) + aAttrs.Remove( 0, aAttrs.Count() ); + if( rData.GetTextAttr() ) + aAttrs.Insert( rData.GetTextAttr(), rData.GetText().Len(), 0 ); + } +} + +Rectangle* SwExtTextInput::GetPosInputData( + const CommandExtTextInputPosData& rFill, + const Point* pLayPos ) const +{ + Rectangle* pRet = 0; + SwTxtNode* pTNd = GetPoint()->nNode.GetNode().GetTxtNode(); + if( pTNd ) + { + Point aPt; + if( pLayPos ) + aPt = *pLayPos; + + const SwCntntFrm* pFrm = pTNd->GetFrm( &aPt, 0, FALSE ); + if( pFrm ) + { + xub_StrLen nEndCnt = GetPoint()->nContent.GetIndex(), + nSttCnt = GetMark()->nContent.GetIndex(); + if( nEndCnt < nSttCnt ) + { + xub_StrLen n = nEndCnt; nEndCnt = nSttCnt; nSttCnt = n; + } + + xub_StrLen nLen = rFill.GetChars(); + pRet = new Rectangle[ nLen ]; + + SwPosition aPos( *GetPoint() ); + SwRect aRect; + for( xub_StrLen n = rFill.GetFirstPos(); n < nLen; ++n ) + { + aPos.nContent = nSttCnt + n; + pFrm->GetCharRect( aRect, aPos ); + pRet[ n ] = aRect.SVRect(); + } + } + } + return pRet; +} + +void SwExtTextInput::SetFontForPos( USHORT nPos, Font& rFont ) +{ +} + +void SwExtTextInput::InvalidateRange() // das Layout anstossen +{ + ULONG nSttNd = GetMark()->nNode.GetIndex(), + nEndNd = GetPoint()->nNode.GetIndex(); + xub_StrLen nSttCnt = GetMark()->nContent.GetIndex(), + nEndCnt = GetPoint()->nContent.GetIndex(); + + if( nSttNd > nEndNd || ( nSttNd == nEndNd && nSttCnt > nEndCnt )) + { + ULONG nTmp = nSttNd; nSttNd = nEndNd; nEndNd = nTmp; + nTmp = nSttCnt; nSttCnt = nEndCnt; nEndCnt = (xub_StrLen)nTmp; + } + + SwUpdateAttr aHt( 0, 0, RES_FMT_CHG ); + SwNodes& rNds = GetDoc()->GetNodes(); + SwNode* pNd; + for( ULONG n = nSttNd; n <= nEndNd; ++n ) + if( ND_TEXTNODE == ( pNd = rNds[ n ] )->GetNodeType() ) + { + aHt.nStart = n == nSttNd ? nSttCnt : 0; + aHt.nEnd = n == nEndNd ? nEndCnt : ((SwTxtNode*)pNd)->GetTxt().Len(); + ((SwTxtNode*)pNd)->Modify( &aHt, &aHt ); + } +} + + +// die Doc Schnittstellen: + +SwExtTextInput* SwDoc::CreateExtTextInput( const SwPaM& rPam ) +{ + SwExtTextInput* pNew = new SwExtTextInput( rPam, pExtInputRing ); + if( !pExtInputRing ) + pExtInputRing = pNew; + pNew->SetMark(); + return pNew; +} + +void SwDoc::DeleteExtTextInput( SwExtTextInput* pDel ) +{ + if( pDel == pExtInputRing ) + { + if( pDel->GetNext() != pExtInputRing ) + pExtInputRing = (SwPaM*)pDel->GetNext(); + else + pExtInputRing = 0; + } + // das Layout benachrichtigen + if( pDel->HasMark() ) + { + } + delete pDel; +} + +SwExtTextInput* SwDoc::GetExtTextInput( const SwNode& rNd, + xub_StrLen nCntntPos ) const +{ + SwExtTextInput* pRet = 0; + if( pExtInputRing ) + { + ULONG nNdIdx = rNd.GetIndex(); + SwExtTextInput* pTmp = (SwExtTextInput*)pExtInputRing; + do { + ULONG nPt = pTmp->GetPoint()->nNode.GetIndex(), + nMk = pTmp->GetMark()->nNode.GetIndex(); + xub_StrLen nPtCnt = pTmp->GetPoint()->nContent.GetIndex(), + nMkCnt = pTmp->GetMark()->nContent.GetIndex(); + + if( nPt < nMk || ( nPt == nMk && nPtCnt < nMkCnt )) + { + ULONG nTmp = nMk; nMk = nPt; nPt = nTmp; + nTmp = nMkCnt; nMkCnt = nPtCnt; nPtCnt = (xub_StrLen)nTmp; + } + + if( nMk <= nNdIdx && nNdIdx <= nPt && + ( STRING_NOTFOUND == nCntntPos || + ( nMkCnt <= nCntntPos && nCntntPos <= nPtCnt ))) + { + pRet = pTmp; + break; + } + } while( pExtInputRing != (pTmp = (SwExtTextInput*)pExtInputRing ) ); + } + return pRet; +} + + + + diff --git a/sw/source/core/doc/fmtcol.cxx b/sw/source/core/doc/fmtcol.cxx new file mode 100644 index 000000000000..b5d7e6c7d6f7 --- /dev/null +++ b/sw/source/core/doc/fmtcol.cxx @@ -0,0 +1,457 @@ +/************************************************************************* + * + * $RCSfile: fmtcol.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:15 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _HINTIDS_HXX +#include +#endif + +#ifndef _SVX_ULSPITEM_HXX //autogen +#include +#endif +#ifndef _SVX_LRSPITEM_HXX //autogen +#include +#endif +#ifndef _SVX_FHGTITEM_HXX //autogen +#include +#endif + +#ifndef _DOC_HXX +#include // fuer GetAttrPool +#endif +#ifndef _ERRHDL_HXX +#include +#endif +#ifndef _FMTCOL_HXX +#include +#endif +#ifndef _HINTS_HXX +#include +#endif +#ifndef _CALC_HXX +#include +#endif +#ifndef _NODE_HXX +#include +#endif + + +TYPEINIT1( SwTxtFmtColl, SwFmtColl ); +TYPEINIT1( SwGrfFmtColl, SwFmtColl ); +TYPEINIT1( SwConditionTxtFmtColl, SwTxtFmtColl ); +TYPEINIT1( SwCollCondition, SwClient ); + +SV_IMPL_PTRARR( SwFmtCollConditions, SwCollConditionPtr ); + + +/* + * SwTxtFmtColl TXT + */ + +void SwTxtFmtColl::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew ) +{ + if( GetDoc()->IsInDtor() ) + { + SwFmtColl::Modify( pOld, pNew ); + return; + } + + int bNewParent = FALSE; + SvxULSpaceItem *pNewULSpace = 0, *pOldULSpace = 0; + SvxLRSpaceItem *pNewLRSpace = 0, *pOldLRSpace = 0; + SvxFontHeightItem *pNewFSize = 0, *pOldFSize = 0; + SwAttrSetChg *pNewChgSet = 0, *pOldChgSet = 0; + + switch( pOld ? pOld->Which() : pNew ? pNew->Which() : 0 ) + { + case RES_ATTRSET_CHG: + // nur neu berechnen, wenn nicht wir der "Versender" sind !!! + pNewChgSet = (SwAttrSetChg*)pNew; + pOldChgSet = (SwAttrSetChg*)pOld; + pNewChgSet->GetChgSet()->GetItemState( + RES_LR_SPACE, FALSE, (const SfxPoolItem**)&pNewLRSpace ); + pNewChgSet->GetChgSet()->GetItemState( + RES_UL_SPACE, FALSE, (const SfxPoolItem**)&pNewULSpace ); + pNewChgSet->GetChgSet()->GetItemState( + RES_CHRATR_FONTSIZE, FALSE, (const SfxPoolItem**)&pNewFSize ); + break; + + case RES_FMT_CHG: + if( GetAttrSet().GetParent() ) + { + const SfxItemSet* pParent = GetAttrSet().GetParent(); + pNewLRSpace = (SvxLRSpaceItem*)&pParent->Get( RES_LR_SPACE ); + pNewULSpace = (SvxULSpaceItem*)&pParent->Get( RES_UL_SPACE ); + pNewFSize = (SvxFontHeightItem*)&pParent->Get( RES_CHRATR_FONTSIZE ); + bNewParent = TRUE; + } + break; + + case RES_LR_SPACE: + pNewLRSpace = (SvxLRSpaceItem*)pNew; + break; + case RES_UL_SPACE: + pNewULSpace = (SvxULSpaceItem*)pNew; + break; + case RES_CHRATR_FONTSIZE: + pNewFSize = (SvxFontHeightItem*)pNew; + break; + } + + int bWeiter = TRUE; + + // dann pruefe doch mal gegen die eigenen Attribute + if( pNewLRSpace && SFX_ITEM_SET == GetItemState( RES_LR_SPACE, FALSE, + (const SfxPoolItem**)&pOldLRSpace )) + { + int bChg = FALSE; + if( pOldLRSpace != pNewLRSpace ) // verhinder Rekursion (SetAttr!!) + { + SvxLRSpaceItem aNew( *pOldLRSpace ); + // wir hatten eine relative Angabe -> neu berechnen + if( 100 != aNew.GetPropLeft() ) + { + long nTmp = aNew.GetLeft(); // alten zum Vergleichen + aNew.SetLeft( pNewLRSpace->GetLeft(), aNew.GetPropLeft() ); + bChg |= nTmp != aNew.GetLeft(); + } + // wir hatten eine relative Angabe -> neu berechnen + if( 100 != aNew.GetPropRight() ) + { + long nTmp = aNew.GetRight(); // alten zum Vergleichen + aNew.SetRight( pNewLRSpace->GetRight(), aNew.GetPropRight() ); + bChg |= nTmp != aNew.GetRight(); + } + // wir hatten eine relative Angabe -> neu berechnen + if( 100 != aNew.GetPropTxtFirstLineOfst() ) + { + short nTmp = aNew.GetTxtFirstLineOfst(); // alten zum Vergleichen + aNew.SetTxtFirstLineOfst( pNewLRSpace->GetTxtFirstLineOfst(), + aNew.GetPropTxtFirstLineOfst() ); + bChg |= nTmp != aNew.GetTxtFirstLineOfst(); + } + if( bChg ) + { + SetAttr( aNew ); + bWeiter = 0 != pOldChgSet || bNewParent; + } + // bei uns absolut gesetzt -> nicht weiter propagieren, es sei + // denn es wird bei uns gesetzt! + else if( pNewChgSet ) + bWeiter = pNewChgSet->GetTheChgdSet() == &GetAttrSet(); + } + +#ifndef NUM_RELSPACE + if( !bChg && pOldLRSpace == pNewLRSpace && + // pNewChgSet->GetTheChgdSet() == &aSet && + GetOutlineLevel() < MAXLEVEL ) + { + // dann muss der Wert in die OutlineRule uebertragen werden + GetDoc()->SetOutlineLSpace( GetOutlineLevel(), + pOldLRSpace->GetTxtFirstLineOfst(), + pOldLRSpace->GetTxtLeft() ); + } +#endif + } + + if( pNewULSpace && SFX_ITEM_SET == GetItemState( + RES_UL_SPACE, FALSE, (const SfxPoolItem**)&pOldULSpace ) && + pOldULSpace != pNewULSpace ) // verhinder Rekursion (SetAttr!!) + { + SvxULSpaceItem aNew( *pOldULSpace ); + int bChg = FALSE; + // wir hatten eine relative Angabe -> neu berechnen + if( 100 != aNew.GetPropUpper() ) + { + USHORT nTmp = aNew.GetUpper(); // alten zum Vergleichen + aNew.SetUpper( pNewULSpace->GetUpper(), aNew.GetPropUpper() ); + bChg |= nTmp != aNew.GetUpper(); + } + // wir hatten eine relative Angabe -> neu berechnen + if( 100 != aNew.GetPropLower() ) + { + USHORT nTmp = aNew.GetLower(); // alten zum Vergleichen + aNew.SetLower( pNewULSpace->GetLower(), aNew.GetPropLower() ); + bChg |= nTmp != aNew.GetLower(); + } + if( bChg ) + { + SetAttr( aNew ); + bWeiter = 0 != pOldChgSet || bNewParent; + } + // bei uns absolut gesetzt -> nicht weiter propagieren, es sei + // denn es wird bei uns gesetzt! + else if( pNewChgSet ) + bWeiter = pNewChgSet->GetTheChgdSet() == &GetAttrSet(); + } + + if( pNewFSize && SFX_ITEM_SET == GetItemState( + RES_CHRATR_FONTSIZE, FALSE, (const SfxPoolItem**)&pOldFSize ) && + pOldFSize != pNewFSize ) // verhinder Rekursion (SetAttr!!) + { + if( 100 == pOldFSize->GetProp() && + SFX_MAPUNIT_RELATIVE == pOldFSize->GetPropUnit() ) + { + // bei uns absolut gesetzt -> nicht weiter propagieren, es sei + // denn es wird bei uns gesetzt! + if( pNewChgSet ) + bWeiter = pNewChgSet->GetTheChgdSet() == &GetAttrSet(); + } + else + { + // wir hatten eine relative Angabe -> neu berechnen + UINT32 nTmp = pOldFSize->GetHeight(); // alten zum Vergleichen + SvxFontHeightItem aNew; + aNew.SetHeight( pNewFSize->GetHeight(), pOldFSize->GetProp(), + pOldFSize->GetPropUnit() ); + if( nTmp != aNew.GetHeight() ) + { + SetAttr( aNew ); + bWeiter = 0 != pOldChgSet || bNewParent; + } + // bei uns absolut gesetzt -> nicht weiter propagieren, es sei + // denn es wird bei uns gesetzt! + else if( pNewChgSet ) + bWeiter = pNewChgSet->GetTheChgdSet() == &GetAttrSet(); + } + } + + if( bWeiter ) + SwFmtColl::Modify( pOld, pNew ); +} + +BOOL SwTxtFmtColl::IsAtDocNodeSet() const +{ + SwClientIter aIter( *(SwModify*)this ); + const SwNodes& rNds = GetDoc()->GetNodes(); + for( SwClient* pC = aIter.First(TYPE(SwCntntNode)); pC; pC = aIter.Next() ) + if( &((SwCntntNode*)pC)->GetNodes() == &rNds ) + return TRUE; + + return FALSE; +} + +//FEATURE::CONDCOLL + +SwCollCondition::SwCollCondition( SwTxtFmtColl* pColl, ULONG nMasterCond, + ULONG nSubCond ) + : SwClient( pColl ), nCondition( nMasterCond ) +{ + aSubCondition.nSubCondition = nSubCond; +} + + +SwCollCondition::SwCollCondition( SwTxtFmtColl* pColl, ULONG nMasterCond, + const String& rSubExp ) + : SwClient( pColl ), nCondition( nMasterCond ) +{ + if( USRFLD_EXPRESSION & nCondition ) + aSubCondition.pFldExpression = new String( rSubExp ); + else + aSubCondition.nSubCondition = 0; +} + + +SwCollCondition::SwCollCondition( const SwCollCondition& rCopy ) + : SwClient( (SwModify*)rCopy.GetRegisteredIn() ), nCondition( rCopy.nCondition ) +{ + if( USRFLD_EXPRESSION & rCopy.nCondition ) + aSubCondition.pFldExpression = new String( *rCopy.GetFldExpression() ); + else + aSubCondition.nSubCondition = rCopy.aSubCondition.nSubCondition; +} + + +SwCollCondition::~SwCollCondition() +{ + if( USRFLD_EXPRESSION & nCondition ) + delete aSubCondition.pFldExpression; +} + + +int SwCollCondition::operator==( const SwCollCondition& rCmp ) const +{ + int nRet = 0; + if( nCondition == rCmp.nCondition ) + { + if( USRFLD_EXPRESSION & nCondition ) + { + // in der SubCondition steht die Expression fuer das UserFeld + const String* pTmp = aSubCondition.pFldExpression; + if( !pTmp ) + pTmp = rCmp.aSubCondition.pFldExpression; + if( pTmp ) + { + SwTxtFmtColl* pColl = GetTxtFmtColl(); + if( !pColl ) + pColl = rCmp.GetTxtFmtColl(); + + if( pColl ) + { + SwCalc aCalc( *pColl->GetDoc() ); + nRet = 0 != aCalc.Calculate( *pTmp ).GetBool(); + } + } + } + else if( aSubCondition.nSubCondition == + rCmp.aSubCondition.nSubCondition ) + nRet = 1; + } + return nRet; +} + + +void SwCollCondition::SetCondition( ULONG nCond, ULONG nSubCond ) +{ + if( USRFLD_EXPRESSION & nCondition ) + delete aSubCondition.pFldExpression; + nCondition = nCond; + aSubCondition.nSubCondition = nSubCond; +} + + +SwConditionTxtFmtColl::~SwConditionTxtFmtColl() +{ +} + +#ifdef USED + // zum "abfischen" von Aenderungen +void SwConditionTxtFmtColl::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew ) +{ + SwTxtFmtColl::Modify( pOld, pNew ); +} +#endif + + +const SwCollCondition* SwConditionTxtFmtColl::HasCondition( + const SwCollCondition& rCond ) const +{ + const SwCollCondition* pFnd = 0; + for( USHORT n = 0; n < aCondColls.Count(); ++n ) + if( *( pFnd = aCondColls[ n ]) == rCond ) + break; + + return n < aCondColls.Count() ? pFnd : 0; +} + + +void SwConditionTxtFmtColl::InsertCondition( const SwCollCondition& rCond ) +{ + for( USHORT n = 0; n < aCondColls.Count(); ++n ) + if( *aCondColls[ n ] == rCond ) + { + aCondColls.DeleteAndDestroy( n ); + break; + } + + // nicht gefunden -> als einfuegen + SwCollCondition* pNew = new SwCollCondition( rCond ); + aCondColls.Insert( pNew, aCondColls.Count() ); +} + + +BOOL SwConditionTxtFmtColl::RemoveCondition( const SwCollCondition& rCond ) +{ + BOOL bRet = FALSE; + for( USHORT n = 0; n < aCondColls.Count(); ++n ) + if( *aCondColls[ n ] == rCond ) + { + aCondColls.DeleteAndDestroy( n ); + bRet = TRUE; + } + + return bRet; +} + +void SwConditionTxtFmtColl::SetConditions( const SwFmtCollConditions& rCndClls ) +{ + // Kopiere noch die Bedingungen + // aber erst die alten loeschen! + if( aCondColls.Count() ) + aCondColls.DeleteAndDestroy( 0, aCondColls.Count() ); + SwDoc& rDoc = *GetDoc(); + for( USHORT n = 0; n < rCndClls.Count(); ++n ) + { + SwCollCondition* pFnd = rCndClls[ n ]; + SwTxtFmtColl* pTmpColl = pFnd->GetTxtFmtColl() + ? rDoc.CopyTxtColl( *pFnd->GetTxtFmtColl() ) + : 0; + SwCollCondition* pNew; + if( USRFLD_EXPRESSION & pFnd->GetCondition() ) + pNew = new SwCollCondition( pTmpColl, pFnd->GetCondition(), + *pFnd->GetFldExpression() ); + else + pNew = new SwCollCondition( pTmpColl, pFnd->GetCondition(), + pFnd->GetSubCondition() ); + aCondColls.Insert( pNew, n ); + } +} + +//FEATURE::CONDCOLL + + + + diff --git a/sw/source/core/doc/ftnidx.cxx b/sw/source/core/doc/ftnidx.cxx new file mode 100644 index 000000000000..aa4c5cb57c78 --- /dev/null +++ b/sw/source/core/doc/ftnidx.cxx @@ -0,0 +1,480 @@ +/************************************************************************* + * + * $RCSfile: ftnidx.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:16 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _TXTFTN_HXX +#include +#endif +#ifndef _FMTFTN_HXX +#include +#endif +#ifndef _FTNINFO_HXX +#include +#endif +#ifndef _DOC_HXX +#include +#endif +#ifndef _FTNIDX_HXX +#include +#endif +#ifndef _NDTXT_HXX +#include +#endif +#ifndef _FMTCOL_HXX +#include +#endif +#ifndef _NDINDEX_HXX +#include +#endif +#ifndef _SECTION_HXX +#include +#endif +#ifndef _FMTFTNTX_HXX +#include +#endif +#ifndef _ROOTFRM_HXX +#include +#endif + + +_SV_IMPL_SORTAR_ALG( _SwFtnIdxs, SwTxtFtnPtr ) +BOOL _SwFtnIdxs::Seek_Entry( const SwTxtFtnPtr rSrch, USHORT* pFndPos ) const +{ + ULONG nIdx = _SwTxtFtn_GetIndex( rSrch ); + xub_StrLen nCntIdx = *rSrch->GetStart(); + + register USHORT nO = Count(), nM, nU = 0; + if( nO > 0 ) + { + nO--; + while( nU <= nO ) + { + nM = nU + ( nO - nU ) / 2; + ULONG nFndIdx = _SwTxtFtn_GetIndex( (*this)[ nM ] ); + if( nFndIdx == nIdx && *(*this)[ nM ]->GetStart() == nCntIdx ) + { + if( pFndPos ) + *pFndPos = nM; + return TRUE; + } + else if( nFndIdx < nIdx || + (nFndIdx == nIdx && *(*this)[ nM ]->GetStart() < nCntIdx )) + nU = nM + 1; + else if( nM == 0 ) + { + if( pFndPos ) + *pFndPos = nU; + return FALSE; + } + else + nO = nM - 1; + } + } + if( pFndPos ) + *pFndPos = nU; + return FALSE; +} + + +void SwFtnIdxs::UpdateFtn( SwNodeIndex& rStt ) +{ + if( !Count() ) + return; + + // besorge erstmal das Nodes-Array ueber den StartIndex der ersten Fussnote + SwDoc* pDoc = rStt.GetNode().GetDoc(); + if( pDoc->IsInReading() ) + return ; + SwTxtFtn* pTxtFtn; + + const SwEndNoteInfo& rEndInfo = pDoc->GetEndNoteInfo(); + const SwFtnInfo& rFtnInfo = pDoc->GetFtnInfo(); + + //Fuer normale Fussnoten werden Chapter- und Dokumentweise Nummerierung + //getrennt behandelt. Fuer Endnoten gibt es nur die Dokumentweise + //Nummerierung. + if( FTNNUM_CHAPTER == rFtnInfo.eNum ) + { + const SwOutlineNodes& rOutlNds = pDoc->GetNodes().GetOutLineNds(); + const SwNode* pCapStt = &pDoc->GetNodes().GetEndOfExtras(); + ULONG nCapEnd = pDoc->GetNodes().GetEndOfContent().GetIndex(); + if( rOutlNds.Count() ) + { + // suche den Start des Kapitels, in den rStt steht. + for( USHORT n = 0; n < rOutlNds.Count(); ++n ) + if( rOutlNds[ n ]->GetIndex() > rStt.GetIndex() ) + break; // gefunden + else if( !rOutlNds[ n ]->GetTxtNode()->GetTxtColl()->GetOutlineLevel() ) + pCapStt = rOutlNds[ n ]; // Start eines neuen Kapitels + // dann suche jetzt noch das Ende vom Bereich + for( ; n < rOutlNds.Count(); ++n ) + if( !rOutlNds[ n ]->GetTxtNode()->GetTxtColl()->GetOutlineLevel() ) + { + nCapEnd = rOutlNds[ n ]->GetIndex(); // Ende des gefundenen Kapitels + break; + } + } + + USHORT nPos, nFtnNo = 1; + if( SeekEntry( *pCapStt, &nPos ) && nPos ) + { + // gehe nach vorne bis der Index nicht mehr gleich ist + const SwNode* pCmpNd = &rStt.GetNode(); + while( nPos && pCmpNd == &((*this)[ --nPos ]->GetTxtNode()) ) + ; + ++nPos; + } + + if( nPos == Count() ) // nichts gefunden + return; + + if( !rOutlNds.Count() ) + nFtnNo = nPos+1; + + for( ; nPos < Count(); ++nPos ) + { + pTxtFtn = (*this)[ nPos ]; + if( pTxtFtn->GetTxtNode().GetIndex() >= nCapEnd ) + break; + + const SwFmtFtn &rFtn = pTxtFtn->GetFtn(); + if( !rFtn.GetNumStr().Len() && !rFtn.IsEndNote() && + !SwUpdFtnEndNtAtEnd::FindSectNdWithEndAttr( *pTxtFtn )) + pTxtFtn->SetNumber( rFtnInfo.nFtnOffset + nFtnNo++, + &rFtn.GetNumStr() ); + } + } + + SwUpdFtnEndNtAtEnd aNumArr; + + // BOOL, damit hier auch bei Chapter-Einstellung die Endnoten + // durchlaufen. + const FASTBOOL bEndNoteOnly = FTNNUM_DOC != rFtnInfo.eNum; + + USHORT nPos, nFtnNo = 1, nEndNo = 1; + ULONG nUpdNdIdx = rStt.GetIndex(); + for( nPos = 0; nPos < Count(); ++nPos ) + { + pTxtFtn = (*this)[ nPos ]; + if( nUpdNdIdx <= pTxtFtn->GetTxtNode().GetIndex() ) + break; + + const SwFmtFtn &rFtn = pTxtFtn->GetFtn(); + if( !rFtn.GetNumStr().Len() ) + { + if( !aNumArr.ChkNumber( *pTxtFtn ) ) + { + if( pTxtFtn->GetFtn().IsEndNote() ) + nEndNo++; + else + nFtnNo++; + } + } + } + + // ab nPos bei allen FootNotes die Array-Nummer setzen + for( ; nPos < Count(); ++nPos ) + { + pTxtFtn = (*this)[ nPos ]; + const SwFmtFtn &rFtn = pTxtFtn->GetFtn(); + if( !rFtn.GetNumStr().Len() ) + { + USHORT nSectNo = aNumArr.ChkNumber( *pTxtFtn ); + if( !nSectNo && ( rFtn.IsEndNote() || !bEndNoteOnly )) + nSectNo = rFtn.IsEndNote() + ? rEndInfo.nFtnOffset + nEndNo++ + : rFtnInfo.nFtnOffset + nFtnNo++; + + if( nSectNo ) + { + if( rFtn.IsEndNote() ) + pTxtFtn->SetNumber( nSectNo, &rFtn.GetNumStr() ); + else + pTxtFtn->SetNumber( nSectNo, &rFtn.GetNumStr() ); + } + } + } + // Pageweise wird vom MA erfuellt !! +} + + +void SwFtnIdxs::UpdateAllFtn() +{ + if( !Count() ) + return; + + // besorge erstmal das Nodes-Array ueber den StartIndex der + // ersten Fussnote + SwDoc* pDoc = (SwDoc*) (*this)[ 0 ]->GetTxtNode().GetDoc(); + SwTxtFtn* pTxtFtn; + const SwEndNoteInfo& rEndInfo = pDoc->GetEndNoteInfo(); + const SwFtnInfo& rFtnInfo = pDoc->GetFtnInfo(); + + SwUpdFtnEndNtAtEnd aNumArr; + + //Fuer normale Fussnoten werden Chapter- und Dokumentweise Nummerierung + //getrennt behandelt. Fuer Endnoten gibt es nur die Dokumentweise + //Nummerierung. + if( FTNNUM_CHAPTER == rFtnInfo.eNum ) + { + const SwOutlineNodes& rOutlNds = pDoc->GetNodes().GetOutLineNds(); + USHORT nNo = 1, // Nummer fuer die Fussnoten + nFtnIdx = 0; // Index in das FtnIdx-Array + for( USHORT n = 0; n < rOutlNds.Count(); ++n ) + { + if( !rOutlNds[ n ]->GetTxtNode()->GetTxtColl()->GetOutlineLevel() ) + { + ULONG nCapStt = rOutlNds[ n ]->GetIndex(); // Start eines neuen Kapitels + for( ; nFtnIdx < Count(); ++nFtnIdx ) + { + pTxtFtn = (*this)[ nFtnIdx ]; + if( pTxtFtn->GetTxtNode().GetIndex() >= nCapStt ) + break; + + // Endnoten nur Dokumentweise + const SwFmtFtn &rFtn = pTxtFtn->GetFtn(); + if( !rFtn.IsEndNote() && !rFtn.GetNumStr().Len() && + !SwUpdFtnEndNtAtEnd::FindSectNdWithEndAttr( *pTxtFtn )) + pTxtFtn->SetNumber( rFtnInfo.nFtnOffset + nNo++, + &rFtn.GetNumStr() ); + } + if( nFtnIdx >= Count() ) + break; // ok alles geupdatet + nNo = 1; + } + } + + for( nNo = 1; nFtnIdx < Count(); ++nFtnIdx ) + { + //Endnoten nur Dokumentweise + pTxtFtn = (*this)[ nFtnIdx ]; + const SwFmtFtn &rFtn = pTxtFtn->GetFtn(); + if( !rFtn.IsEndNote() && !rFtn.GetNumStr().Len() && + !SwUpdFtnEndNtAtEnd::FindSectNdWithEndAttr( *pTxtFtn )) + pTxtFtn->SetNumber( rFtnInfo.nFtnOffset + nNo++, + &rFtn.GetNumStr() ); + } + + } + + // BOOL, damit hier auch bei Chapter-Einstellung die Endnoten + // durchlaufen. + const FASTBOOL bEndNoteOnly = FTNNUM_DOC != rFtnInfo.eNum; + USHORT nFtnNo = 0, nEndNo = 0; + for( USHORT nPos = 0; nPos < Count(); ++nPos ) + { + pTxtFtn = (*this)[ nPos ]; + const SwFmtFtn &rFtn = pTxtFtn->GetFtn(); + if( !rFtn.GetNumStr().Len() ) + { + USHORT nSectNo = aNumArr.ChkNumber( *pTxtFtn ); + if( !nSectNo && ( rFtn.IsEndNote() || !bEndNoteOnly )) + nSectNo = rFtn.IsEndNote() + ? rEndInfo.nFtnOffset + (++nEndNo) + : rFtnInfo.nFtnOffset + (++nFtnNo); + + if( nSectNo ) + { + if( rFtn.IsEndNote() ) + pTxtFtn->SetNumber( nSectNo, &rFtn.GetNumStr() ); + else + pTxtFtn->SetNumber( nSectNo, &rFtn.GetNumStr() ); + } + } + } + + if( pDoc->GetRootFrm() && FTNNUM_PAGE == rFtnInfo.eNum ) + pDoc->GetRootFrm()->UpdateFtnNums(); +} + +void SwFtnIdxs::UpdateFtnInSections() +{ + if( !Count() ) + return; + + // besorge erstmal das Nodes-Array ueber den StartIndex der + // ersten Fussnote + SwDoc* pDoc = (SwDoc*) (*this)[ 0 ]->GetTxtNode().GetDoc(); + SwTxtFtn* pTxtFtn; + SwUpdFtnEndNtAtEnd aNumArr; + for( USHORT nPos = 0; nPos < Count(); ++nPos ) + { + pTxtFtn = (*this)[ nPos ]; + const SwFmtFtn &rFtn = pTxtFtn->GetFtn(); + if( !rFtn.GetNumStr().Len() ) + { + USHORT nSectNo = aNumArr.ChkNumber( *pTxtFtn ); + if( nSectNo ) + { + if( rFtn.IsEndNote() ) + pTxtFtn->SetNumber( nSectNo, &rFtn.GetNumStr() ); + else + pTxtFtn->SetNumber( nSectNo, &rFtn.GetNumStr() ); + } + } + } +} + +SwTxtFtn* SwFtnIdxs::SeekEntry( const SwNodeIndex& rPos, USHORT* pFndPos ) const +{ + ULONG nIdx = rPos.GetIndex(); + + register USHORT nO = Count(), nM, nU = 0; + if( nO > 0 ) + { + nO--; + while( nU <= nO ) + { + nM = nU + ( nO - nU ) / 2; + ULONG nNdIdx = _SwTxtFtn_GetIndex( (*this)[ nM ] ); + if( nNdIdx == nIdx ) + { + if( pFndPos ) + *pFndPos = nM; + return (*this)[ nM ]; + } + else if( nNdIdx < nIdx ) + nU = nM + 1; + else if( nM == 0 ) + { + if( pFndPos ) + *pFndPos = nU; + return 0; + } + else + nO = nM - 1; + } + } + if( pFndPos ) + *pFndPos = nU; + return 0; +} + +/* */ + +const SwSectionNode* SwUpdFtnEndNtAtEnd::FindSectNdWithEndAttr( + const SwTxtFtn& rTxtFtn ) +{ + USHORT nWh = rTxtFtn.GetFtn().IsEndNote() ? RES_END_AT_TXTEND + : RES_FTN_AT_TXTEND; + USHORT nVal; + const SwSectionNode* pNd = rTxtFtn.GetTxtNode().FindSectionNode(); + while( pNd && FTNEND_ATTXTEND_OWNNUMSEQ != ( nVal = + ((const SwFmtFtnAtTxtEnd&)pNd->GetSection().GetFmt()-> + GetAttr( nWh, TRUE )).GetValue() ) && + FTNEND_ATTXTEND_OWNNUMANDFMT != nVal ) + pNd = pNd->FindStartNode()->FindSectionNode(); + + return pNd; +} + +USHORT SwUpdFtnEndNtAtEnd::GetNumber( const SwTxtFtn& rTxtFtn, + const SwSectionNode& rNd ) +{ + USHORT nRet = 0, nWh; + SvPtrarr* pArr; + SvUShorts* pNum; + if( rTxtFtn.GetFtn().IsEndNote() ) + { + pArr = &aEndSects; + pNum = &aEndNums; + nWh = RES_END_AT_TXTEND; + } + else + { + pArr = &aFtnSects; + pNum = &aFtnNums; + nWh = RES_FTN_AT_TXTEND; + } + void* pNd = (void*)&rNd; + + for( USHORT n = pArr->Count(); n; ) + if( pArr->GetObject( --n ) == pNd ) + { + nRet = ++pNum->GetObject( n ); + break; + } + + if( !nRet ) + { + pArr->Insert( pNd, pArr->Count() ); + nRet = ((SwFmtFtnEndAtTxtEnd&)rNd.GetSection().GetFmt()-> + GetAttr( nWh )).GetOffset(); + ++nRet; + pNum->Insert( nRet, pNum->Count() ); + } + return nRet; +} + +USHORT SwUpdFtnEndNtAtEnd::ChkNumber( const SwTxtFtn& rTxtFtn ) +{ + const SwSectionNode* pSectNd = FindSectNdWithEndAttr( rTxtFtn ); + return pSectNd ? GetNumber( rTxtFtn, *pSectNd ) : 0; +} + + + + diff --git a/sw/source/core/doc/gctable.cxx b/sw/source/core/doc/gctable.cxx new file mode 100644 index 000000000000..ed0efdbf55d9 --- /dev/null +++ b/sw/source/core/doc/gctable.cxx @@ -0,0 +1,521 @@ +/************************************************************************* + * + * $RCSfile: gctable.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:16 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef _HINTIDS_HXX +#include +#endif + +#ifndef _SVX_BOXITEM_HXX //autogen +#include +#endif + +#ifndef _TBLRWCL_HXX +#include +#endif +#ifndef _SWTBLFMT_HXX +#include +#endif + + +inline const SvxBorderLine* GetLineTB( const SvxBoxItem* pBox, BOOL bTop ) +{ + return bTop ? pBox->GetTop() : pBox->GetBottom(); +} + + +BOOL _SwGCBorder_BoxBrd::CheckLeftBorderOfFormat( const SwFrmFmt& rFmt ) +{ + const SvxBorderLine* pBrd; + const SfxPoolItem* pItem; + if( SFX_ITEM_SET == rFmt.GetItemState( RES_BOX, TRUE, &pItem ) && + 0 != ( pBrd = ((SvxBoxItem*)pItem)->GetLeft() ) ) + { + if( *pBrdLn == *pBrd ) + bAnyBorderFnd = TRUE; + return TRUE; + } + return FALSE; +} + + + +BOOL lcl_GCBorder_ChkBoxBrd_L( const SwTableLine*& rpLine, void* pPara ) +{ + const SwTableBox* pBox = rpLine->GetTabBoxes()[ 0 ]; + return lcl_GCBorder_ChkBoxBrd_B( pBox, pPara ); +} + +BOOL lcl_GCBorder_ChkBoxBrd_B( const SwTableBox*& rpBox, void* pPara ) +{ + BOOL bRet = TRUE; + if( rpBox->GetTabLines().Count() ) + { + for( USHORT n = 0, nLines = rpBox->GetTabLines().Count(); + n < nLines && bRet; ++n ) + { + const SwTableLine* pLine = rpBox->GetTabLines()[ n ]; + bRet = lcl_GCBorder_ChkBoxBrd_L( pLine, pPara ); + } + } + else + { + _SwGCBorder_BoxBrd* pBPara = (_SwGCBorder_BoxBrd*)pPara; + bRet = pBPara->CheckLeftBorderOfFormat( *rpBox->GetFrmFmt() ); + } + return bRet; +} + +BOOL lcl_GCBorder_GetLastBox_L( const SwTableLine*& rpLine, void* pPara ) +{ + const SwTableBoxes& rBoxes = rpLine->GetTabBoxes(); + const SwTableBox* pBox = rBoxes[ rBoxes.Count()-1 ]; + ::lcl_GCBorder_GetLastBox_B( pBox, pPara ); + return TRUE; +} + +BOOL lcl_GCBorder_GetLastBox_B( const SwTableBox*& rpBox, void* pPara ) +{ + SwTableLines& rLines = (SwTableLines&)rpBox->GetTabLines(); + if( rLines.Count() ) + rLines.ForEach( &lcl_GCBorder_GetLastBox_L, pPara ); + else + ((SwTableBoxes*)pPara)->Insert( rpBox, ((SwTableBoxes*)pPara)->Count() ); + return TRUE; +} + +// suche das "Ende" der vorgegebene BorderLine. Returnt wird die "Layout"Pos! +USHORT lcl_FindEndPosOfBorder( const SwCollectTblLineBoxes& rCollTLB, + const SvxBorderLine& rBrdLn, USHORT& rStt, BOOL bTop ) +{ + USHORT nPos, nLastPos = 0; + for( USHORT nEnd = rCollTLB.Count(); rStt < nEnd; ++rStt ) + { + const SfxPoolItem* pItem; + const SvxBorderLine* pBrd; + const SwTableBox& rBox = rCollTLB.GetBox( rStt, &nPos ); + + if( SFX_ITEM_SET != rBox.GetFrmFmt()->GetItemState(RES_BOX,TRUE, &pItem ) + || 0 == ( pBrd = GetLineTB( (SvxBoxItem*)pItem, bTop )) + || !( *pBrd == rBrdLn )) + break; + nLastPos = nPos; + } + return nLastPos; +} + +inline const SvxBorderLine* lcl_GCBorder_GetBorder( const SwTableBox& rBox, + BOOL bTop, + const SfxPoolItem** ppItem ) +{ + return SFX_ITEM_SET == rBox.GetFrmFmt()->GetItemState( RES_BOX, TRUE, ppItem ) + ? GetLineTB( (SvxBoxItem*)*ppItem, bTop ) + : 0; +} + +void lcl_GCBorder_DelBorder( const SwCollectTblLineBoxes& rCollTLB, + USHORT& rStt, BOOL bTop, + const SvxBorderLine& rLine, + const SfxPoolItem* pItem, + USHORT nEndPos, + SwShareBoxFmts* pShareFmts ) +{ + SwTableBox* pBox = (SwTableBox*)&rCollTLB.GetBox( rStt ); + USHORT nNextPos; + const SvxBorderLine* pLn = &rLine; + + do { + if( pLn && *pLn == rLine ) + { + SvxBoxItem aBox( *(SvxBoxItem*)pItem ); + if( bTop ) + aBox.SetLine( 0, BOX_LINE_TOP ); + else + aBox.SetLine( 0, BOX_LINE_BOTTOM ); + + if( pShareFmts ) + pShareFmts->SetAttr( *pBox, aBox ); + else + pBox->ClaimFrmFmt()->SetAttr( aBox ); + } + + if( ++rStt >= rCollTLB.Count() ) + break; + + pBox = (SwTableBox*)&rCollTLB.GetBox( rStt, &nNextPos ); + if( nNextPos > nEndPos ) + break; + + pLn = lcl_GCBorder_GetBorder( *pBox, bTop, &pItem ); + + } while( TRUE ); +} + + +BOOL lcl_GC_Line_Border( const SwTableLine*& rpLine, void* pPara ) +{ + _SwGCLineBorder* pGCPara = (_SwGCLineBorder*)pPara; + + // zuerst die rechte Kante mit der linken Kante der naechsten Box + // innerhalb dieser Line + { + _SwGCBorder_BoxBrd aBPara; + const SvxBorderLine* pBrd; + const SfxPoolItem* pItem; + const SwTableBoxes& rBoxes = rpLine->GetTabBoxes(); + for( USHORT n = 0, nBoxes = rBoxes.Count() - 1; n < nBoxes; ++n ) + { + SwTableBoxes aBoxes; + { + const SwTableBox* pBox = rBoxes[ n ]; + if( pBox->GetSttNd() ) + aBoxes.Insert( pBox, 0 ); + else + lcl_GCBorder_GetLastBox_B( pBox, &aBoxes ); + } + + SwTableBox* pBox; + for( USHORT i = aBoxes.Count(); i; ) + if( SFX_ITEM_SET == (pBox = aBoxes[ --i ])->GetFrmFmt()-> + GetItemState( RES_BOX, TRUE, &pItem ) && + 0 != ( pBrd = ((SvxBoxItem*)pItem)->GetRight() ) ) + { + aBPara.SetBorder( *pBrd ); + const SwTableBox* pNextBox = rBoxes[n+1]; + if( lcl_GCBorder_ChkBoxBrd_B( pNextBox, &aBPara ) && + aBPara.IsAnyBorderFound() ) + { + SvxBoxItem aBox( *(SvxBoxItem*)pItem ); + aBox.SetLine( 0, BOX_LINE_RIGHT ); + if( pGCPara->pShareFmts ) + pGCPara->pShareFmts->SetAttr( *pBox, aBox ); + else + pBox->ClaimFrmFmt()->SetAttr( aBox ); + } + } + + aBoxes.Remove( 0, aBoxes.Count() ); + } + } + + // und jetzt die eigene untere Kante mit der nachfolgenden oberen Kante + if( !pGCPara->IsLastLine() ) + { + SwCollectTblLineBoxes aBottom( FALSE ); + SwCollectTblLineBoxes aTop( TRUE ); + + ::lcl_Line_CollectBox( rpLine, &aBottom ); + + const SwTableLine* pNextLine = (*pGCPara->pLines)[ pGCPara->nLinePos+1 ]; + ::lcl_Line_CollectBox( pNextLine, &aTop ); + + // dann entferne mal alle "doppelten" gleichen Lines + USHORT nBtmPos, nTopPos, + nSttBtm = 0, nSttTop = 0, + nEndBtm = aBottom.Count(), nEndTop = aTop.Count(); + + const SwTableBox *pBtmBox = &aBottom.GetBox( nSttBtm++, &nBtmPos ), + *pTopBox = &aTop.GetBox( nSttTop++, &nTopPos ); + const SfxPoolItem *pBtmItem, *pTopItem; + const SvxBorderLine *pBtmLine, *pTopLine; + BOOL bGetTopItem = TRUE, bGetBtmItem = TRUE; + + do { + if( bGetBtmItem ) + pBtmLine = lcl_GCBorder_GetBorder( *pBtmBox, FALSE, &pBtmItem ); + if( bGetTopItem ) + pTopLine = lcl_GCBorder_GetBorder( *pTopBox, TRUE, &pTopItem ); + + if( pTopLine && pBtmLine && *pTopLine == *pBtmLine ) + { + // dann kann einer entfernt werden, aber welche? + USHORT nSavSttBtm = nSttBtm, nSavSttTop = nSttTop; + USHORT nBtmEndPos = ::lcl_FindEndPosOfBorder( aBottom, + *pTopLine, nSttBtm, FALSE ); + if( !nBtmEndPos ) nBtmEndPos = nBtmPos; + USHORT nTopEndPos = ::lcl_FindEndPosOfBorder( aTop, + *pTopLine, nSttTop, TRUE ); + if( !nTopEndPos ) nTopEndPos = nTopPos; + + + if( nTopEndPos <= nBtmEndPos ) + { + // dann die TopBorder bis zur BottomEndPos loeschen + nSttTop = nSavSttTop; + if( nTopPos <= nBtmEndPos ) + lcl_GCBorder_DelBorder( aTop, --nSttTop, TRUE, + *pBtmLine, pTopItem, nBtmEndPos, + pGCPara->pShareFmts ); + else + nSttBtm = nSavSttBtm; + } + else + { + // sonst die BottomBorder bis zur TopEndPos loeschen + nSttBtm = nSavSttBtm; + if( nBtmPos <= nTopEndPos ) + lcl_GCBorder_DelBorder( aBottom, --nSttBtm, FALSE, + *pTopLine, pBtmItem, nTopEndPos, + pGCPara->pShareFmts ); + else + nSttTop = nSavSttTop; + } + nTopPos = nBtmPos; + } + + if( nTopPos == nBtmPos ) + { + if( nSttBtm >= nEndBtm || nSttTop >= nEndTop ) + break; + + pBtmBox = &aBottom.GetBox( nSttBtm++, &nBtmPos ); + pTopBox = &aTop.GetBox( nSttTop++, &nTopPos ); + bGetTopItem = bGetBtmItem = TRUE; + } + else if( nTopPos < nBtmPos ) + { + if( nSttTop >= nEndTop ) + break; + pTopBox = &aTop.GetBox( nSttTop++, &nTopPos ); + bGetTopItem = TRUE; + bGetBtmItem = FALSE; + } + else + { + if( nSttBtm >= nEndBtm ) + break; + pBtmBox = &aBottom.GetBox( nSttBtm++, &nBtmPos ); + bGetTopItem = FALSE; + bGetBtmItem = TRUE; + } + + } while( TRUE ); + } + + ((SwTableLine*)rpLine)->GetTabBoxes().ForEach( &lcl_GC_Box_Border, pPara ); + + ++pGCPara->nLinePos; + + return TRUE; +} + + +BOOL lcl_GC_Box_Border( const SwTableBox*& rpBox, void* pPara ) +{ + if( rpBox->GetTabLines().Count() ) + { + _SwGCLineBorder aPara( *rpBox ); + aPara.pShareFmts = ((_SwGCLineBorder*)pPara)->pShareFmts; + ((SwTableBox*)rpBox)->GetTabLines().ForEach( &lcl_GC_Line_Border, &aPara ); + } + return TRUE; +} + + +void SwTable::GCBorderLines() +{ + // alle doppleten Borderlines benachbarter Tabellen-Content-Boxen + // entfernen. Und zwar wird versucht, die Struktur unserer default + // Border wiederherzustellen, die wie folgt aussieht: + // + // +-- +--+ + // | | | + // +-- +--+ + // + // | | | + // +-- +--+ + + SwShareBoxFmts aShareFmts; + _SwGCLineBorder aPara( *this ); + aPara.pShareFmts = &aShareFmts; + GetTabLines().ForEach( &lcl_GC_Line_Border, &aPara ); +} + + +/* */ + +struct _GCLinePara +{ + SwTableLines* pLns; + SwShareBoxFmts* pShareFmts; + + _GCLinePara( SwTableLines& rLns, _GCLinePara* pPara = 0 ) + : pLns( &rLns ), pShareFmts( pPara ? pPara->pShareFmts : 0 ) + {} +}; + +BOOL lcl_MergeGCBox( const SwTableBox*& rpTblBox, void* pPara ) +{ + SwTableBox*& rpBox = (SwTableBox*&)rpTblBox; + USHORT n, nLen = rpBox->GetTabLines().Count(); + if( nLen ) + { + // ACHTUNG: die Anzahl der Lines kann sich aendern! + _GCLinePara aPara( rpBox->GetTabLines(), (_GCLinePara*)pPara ); + for( n = 0; n < rpBox->GetTabLines().Count() && + lcl_MergeGCLine( *(rpBox->GetTabLines().GetData() + n), &aPara ); + ++n ) + ; + + if( 1 == rpBox->GetTabLines().Count() ) + { + // Box mit einer Line, dann verschiebe alle Boxen der Line + // hinter diese Box in der Parent-Line und loesche diese Box + SwTableLine* pInsLine = rpBox->GetUpper(); + SwTableLine* pCpyLine = rpBox->GetTabLines()[0]; + USHORT nInsPos = pInsLine->GetTabBoxes().C40_GETPOS( SwTableBox, rpBox ); + for( n = 0; n < pCpyLine->GetTabBoxes().Count(); ++n ) + pCpyLine->GetTabBoxes()[n]->SetUpper( pInsLine ); + + pInsLine->GetTabBoxes().Insert( &pCpyLine->GetTabBoxes(), nInsPos+1 ); + pCpyLine->GetTabBoxes().Remove( 0, n ); + // loesche alte die Box mit der Line + pInsLine->GetTabBoxes().DeleteAndDestroy( nInsPos ); + + return FALSE; // neu aufsetzen + } + } + return TRUE; +} + +BOOL lcl_MergeGCLine( const SwTableLine*& rpLine, void* pPara ) +{ + SwTableLine* pLn = (SwTableLine*)rpLine; + USHORT nLen = pLn->GetTabBoxes().Count(); + if( nLen ) + { + _GCLinePara* pGCPara = (_GCLinePara*)pPara; + while( 1 == nLen ) + { + // es gibt eine Box mit Lines + SwTableBox* pBox = pLn->GetTabBoxes()[0]; + if( !pBox->GetTabLines().Count() ) + break; + + SwTableLine* pLine = pBox->GetTabLines()[0]; + + // pLine wird zu der aktuellen, also der rpLine, + // die restlichen werden ins LinesArray hinter der akt. + // verschoben. + // Das LinesArray ist im pPara! + nLen = pBox->GetTabLines().Count(); + + SwTableLines& rLns = *pGCPara->pLns; + const SwTableLine* pTmp = pLn; + USHORT nInsPos = rLns.GetPos( pTmp ); + ASSERT( USHRT_MAX != nInsPos, "Line nicht gefunden!" ); + + SwTableBox* pUpper = pLn->GetUpper(); + + rLns.Remove( nInsPos, 1 ); // die Line dem aus Array loeschen + rLns.Insert( &pBox->GetTabLines(), nInsPos ); + + // JP 31.03.99: Bug 60000 - die Attribute der zu loeschenden + // Line an die "eingefuegten" uebertragen + const SfxPoolItem* pItem; + if( SFX_ITEM_SET == pLn->GetFrmFmt()->GetItemState( + RES_BACKGROUND, TRUE, &pItem )) + { + SwTableLines& rBoxLns = pBox->GetTabLines(); + for( USHORT nLns = 0; nLns < nLen; ++nLns ) + if( SFX_ITEM_SET != rBoxLns[ nLns ]->GetFrmFmt()-> + GetItemState( RES_BACKGROUND, TRUE )) + pGCPara->pShareFmts->SetAttr( *rBoxLns[ nLns ], *pItem ); + } + + pBox->GetTabLines().Remove( 0, nLen ); // Lines aus Array loeschen + + delete pLn; + + // Abhaengigkeit neu setzen + while( nLen-- ) + rLns[ nInsPos++ ]->SetUpper( pUpper ); + + pLn = pLine; // und neu setzen + nLen = pLn->GetTabBoxes().Count(); + } + + // ACHTUNG: die Anzahl der Boxen kann sich aendern! + for( nLen = 0; nLen < pLn->GetTabBoxes().Count(); ++nLen ) + if( !lcl_MergeGCBox( *(pLn->GetTabBoxes().GetData() + nLen ), pPara )) + --nLen; + } + return TRUE; +} + + // Struktur ein wenig aufraeumen +void SwTable::GCLines() +{ + // ACHTUNG: die Anzahl der Lines kann sich aendern! + _GCLinePara aPara( GetTabLines() ); + SwShareBoxFmts aShareFmts; + aPara.pShareFmts = &aShareFmts; + for( USHORT n = 0; n < GetTabLines().Count() && + lcl_MergeGCLine( *(GetTabLines().GetData() + n ), &aPara ); ++n ) + ; +} + + diff --git a/sw/source/core/doc/htmltbl.cxx b/sw/source/core/doc/htmltbl.cxx new file mode 100644 index 000000000000..574b5b8dfbe0 --- /dev/null +++ b/sw/source/core/doc/htmltbl.cxx @@ -0,0 +1,1943 @@ +/************************************************************************* + * + * $RCSfile: htmltbl.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-19 00:08:16 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PRECOMPILED +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +#include "hintids.hxx" + +//#define TEST_DELAYED_RESIZE + +#ifdef TEST_DELAYED_RESIZE +#ifndef _SV_SOUND_HXX //autogen +#include +#endif +#endif +#ifndef _WRKWIN_HXX //autogen +#include +#endif +#ifndef _APP_HXX //autogen +#include +#endif +#ifndef _SOT_STORAGE_HXX //autogen +#include +#endif + +#ifndef _FMTORNT_HXX //autogen +#include +#endif +#ifndef _FMTFSIZE_HXX //autogen +#include +#endif +#ifndef _FRMFMT_HXX //autogen +#include +#endif +#ifndef _DOCARY_HXX +#include +#endif +#include "ndtxt.hxx" +#include "doc.hxx" +#include "swtable.hxx" +#include "rootfrm.hxx" +#include "docsh.hxx" +#include "flyfrm.hxx" +#include "poolfmt.hxx" +#include "viewsh.hxx" +#include "tabfrm.hxx" + +#include "htmltbl.hxx" +#include "ndindex.hxx" + +#define COLFUZZY 20 +#define MAX_TABWIDTH (USHRT_MAX - 2001) + + +/* */ + +class SwHTMLTableLayoutConstraints +{ + USHORT nRow; // Start-Zeile + USHORT nCol; // Start-Spalte + USHORT nColSpan; // COLSPAN der Zelle + + SwHTMLTableLayoutConstraints *pNext; // die naechste Bedingung + + ULONG nMinNoAlign, nMaxNoAlign; // Zwischenergebnisse AL-Pass 1 + +public: + + SwHTMLTableLayoutConstraints( ULONG nMin, ULONG nMax, USHORT nRow, + USHORT nCol, USHORT nColSp ); + ~SwHTMLTableLayoutConstraints(); + + ULONG GetMinNoAlign() const { return nMinNoAlign; } + ULONG GetMaxNoAlign() const { return nMaxNoAlign; } + + SwHTMLTableLayoutConstraints *InsertNext( SwHTMLTableLayoutConstraints *pNxt ); + SwHTMLTableLayoutConstraints* GetNext() const { return pNext; } + + USHORT GetRow() const { return nRow; } + + USHORT GetColSpan() const { return nColSpan; } + USHORT GetColumn() const { return nCol; } +}; + +/* */ + +SwHTMLTableLayoutCnts::SwHTMLTableLayoutCnts( const SwStartNode *pSttNd, + SwHTMLTableLayout* pTab, + BOOL bNoBrTag, + SwHTMLTableLayoutCnts* pNxt ) : + pNext( pNxt ), pBox( 0 ), pTable( pTab ), pStartNode( pSttNd ), + nWidthSet( 0 ), nPass1Done( 0 ), bNoBreakTag( bNoBrTag ) +{} + +SwHTMLTableLayoutCnts::~SwHTMLTableLayoutCnts() +{ + delete pNext; + delete pTable; +} + +const SwStartNode *SwHTMLTableLayoutCnts::GetStartNode() const +{ + return pBox ? pBox->GetSttNd() : pStartNode; +} + + +/* */ + +SwHTMLTableLayoutCell::SwHTMLTableLayoutCell( SwHTMLTableLayoutCnts *pCnts, + USHORT nRSpan, USHORT nCSpan, + USHORT nWidth, BOOL bPrcWidth, + BOOL bNWrapOpt ) : + pContents( pCnts ), + nRowSpan( nRSpan ), nColSpan( nCSpan ), + nWidthOption( nWidth ), bPrcWidthOption( bPrcWidth ), + bNoWrapOption( bNWrapOpt ) +{} + +SwHTMLTableLayoutCell::~SwHTMLTableLayoutCell() +{ + if( nRowSpan==1 && nColSpan==1 ) + { + delete pContents; + } +} + +/* */ + +SwHTMLTableLayoutColumn::SwHTMLTableLayoutColumn( USHORT nWidth, + BOOL bRelWidth, + BOOL bLBorder ) : + nMinNoAlign(MINLAY), nMaxNoAlign(MINLAY), nAbsMinNoAlign(MINLAY), + nMin(0), nMax(0), + nAbsColWidth(0), nRelColWidth(0), + nWidthOption( nWidth ), bRelWidthOption( bRelWidth ), + bLeftBorder( bLBorder ) +{} + + +/* */ + +SwHTMLTableLayoutConstraints::SwHTMLTableLayoutConstraints( + ULONG nMin, ULONG nMax, USHORT nRw, USHORT nColumn, USHORT nColSp ): + nMinNoAlign( nMin ), nMaxNoAlign( nMax ), + nRow( nRw ), nCol( nColumn ), nColSpan( nColSp ), + pNext( 0 ) +{} + +SwHTMLTableLayoutConstraints::~SwHTMLTableLayoutConstraints() +{ + delete pNext; +} + +SwHTMLTableLayoutConstraints *SwHTMLTableLayoutConstraints::InsertNext( + SwHTMLTableLayoutConstraints *pNxt ) +{ + SwHTMLTableLayoutConstraints *pPrev = 0; + SwHTMLTableLayoutConstraints *pConstr = this; + while( pConstr ) + { + if( pConstr->GetRow() > pNxt->GetRow() || + pConstr->GetColumn() > pNxt->GetColumn() ) + break; + pPrev = pConstr; + pConstr = pConstr->GetNext(); + } + + if( pPrev ) + { + pNxt->pNext = pPrev->GetNext(); + pPrev->pNext = pNxt; + pConstr = this; + } + else + { + pNxt->pNext = this; + pConstr = pNxt; + } + + return pConstr; +} + +/* */ + +typedef SwHTMLTableLayoutColumn *SwHTMLTableLayoutColumnPtr; +typedef SwHTMLTableLayoutCell *SwHTMLTableLayoutCellPtr; + +SwHTMLTableLayout::SwHTMLTableLayout( + const SwTable * pSwTbl, + USHORT nRws, USHORT nCls, BOOL bColsOpt, BOOL bColTgs, + USHORT nWdth, BOOL bPrcWdth, USHORT nBorderOpt, + USHORT nCellPad, USHORT nCellSp, SvxAdjust eAdjust, + USHORT nLMargin, USHORT nRMargin, + USHORT nBWidth, USHORT nLeftBWidth, + USHORT nRightBWidth, + USHORT nInhLeftBWidth, USHORT nInhRightBWidth ) : + aColumns( new SwHTMLTableLayoutColumnPtr[nCls] ), + aCells( new SwHTMLTableLayoutCellPtr[nRws*nCls] ), + pSwTable( pSwTbl ), pLeftFillerBox( 0 ), pRightFillerBox( 0 ), + nMin( 0 ), nMax( 0 ), + nRows( nRws ), nCols( nCls ), + nLeftMargin( nLMargin ), nRightMargin( nRMargin ), + nCellPadding( nCellPad ), nCellSpacing( nCellSp ), nBorder( nBorderOpt ), + nBorderWidth( nBWidth ), + nLeftBorderWidth( nLeftBWidth ), nRightBorderWidth( nRightBWidth ), + nInhLeftBorderWidth( nInhLeftBWidth ), + nInhRightBorderWidth( nInhRightBWidth ), + nRelLeftFill( 0 ), nRelRightFill( 0 ), + nInhAbsLeftSpace( 0 ), nInhAbsRightSpace( 0 ), + nRelTabWidth( 0 ), nWidthOption( nWdth ), + nDelayedResizeAbsAvail( 0 ), nLastResizeAbsAvail( 0 ), + nPass1Done( 0 ), nWidthSet( 0 ), eTableAdjust( eAdjust ), + bColsOption( bColsOpt ), bColTags( bColTgs ), + bPrcWidthOption( bPrcWdth ), bUseRelWidth( FALSE ), + bMustResize( TRUE ), bExportable( TRUE ), bBordersChanged( FALSE ), + bMustNotResize( FALSE ), bMustNotRecalc( FALSE ) +{ + aResizeTimer.SetTimeoutHdl( STATIC_LINK( this, SwHTMLTableLayout, + DelayedResize_Impl ) ); +} + +SwHTMLTableLayout::~SwHTMLTableLayout() +{ + for( USHORT i=0; iHasLeftBorder() ) + { + nBWidth = nCol==0 ? nLeftBorderWidth : nBorderWidth; + } + if( nCol==0 && nInhLeftBorderWidth > nBWidth ) + { + nBWidth = nInhLeftBorderWidth; + } + + return nBWidth; +} + +USHORT SwHTMLTableLayout::GetRightBorderWidth( USHORT nCol, USHORT nColSpan ) const +{ + USHORT nBWidth = 0; + + if( nCol+nColSpan==nCols ) + { + nBWidth = nInhRightBorderWidth > nRightBorderWidth + ? nInhRightBorderWidth + : nRightBorderWidth; + } + + return nBWidth; +} +#endif + +// Die Breiten der Umrandung werden zunaechst wie in Netscape berechnet: +// Aussere Umrandung: BORDER + CELLSPACING + CELLPADDING +// Innere Umrandung: CELLSPACING + CELLPADDING +// Allerdings wird die Breite der Umrandung im SW trotzdem beachtet, wenn +// bSwBorders gesetzt ist, damit nicht faellschlich umgebrochen wird. +// MIB 27.6.97: Dabei muss auch der Abstand zum Inhalt berueckichtigt werden, +// und zwar auch dann, wenn wenn nur die gegenueberliegende Seite +// eine Umrandung hat. +USHORT SwHTMLTableLayout::GetLeftCellSpace( USHORT nCol, USHORT nColSpan, + BOOL bSwBorders ) const +{ + USHORT nSpace = nCellSpacing + nCellPadding; + + if( nCol == 0 ) + { + nSpace += nBorder; + + if( bSwBorders && nSpace < nLeftBorderWidth ) + nSpace = nLeftBorderWidth; + } + else if( bSwBorders ) + { + if( GetColumn(nCol)->HasLeftBorder() ) + { + if( nSpace < nBorderWidth ) + nSpace = nBorderWidth; + } + else if( nCol+nColSpan == nCols && nRightBorderWidth && + nSpace < MIN_BORDER_DIST ) + { + ASSERT( !nCellPadding, "GetLeftCellSpace: CELLPADDING!=0" ); + // Wenn die Gegenueberliegende Seite umrandet ist muessen + // wir zumindest den minimalen Abstand zum Inhalt + // beruecksichtigen. (Koennte man zusaetzlich auch an + // nCellPadding festmachen.) + nSpace = MIN_BORDER_DIST; + } + } + + return nSpace; +} + +USHORT SwHTMLTableLayout::GetRightCellSpace( USHORT nCol, USHORT nColSpan, + BOOL bSwBorders ) const +{ + USHORT nSpace = nCellPadding; + + if( nCol+nColSpan == nCols ) + { + nSpace += nBorder + nCellSpacing; + if( bSwBorders && nSpace < nRightBorderWidth ) + nSpace = nRightBorderWidth; + } + else if( bSwBorders && GetColumn(nCol)->HasLeftBorder() && + nSpace < MIN_BORDER_DIST ) + { + ASSERT( !nCellPadding, "GetRightCellSpace: CELLPADDING!=0" ); + // Wenn die Gegenueberliegende Seite umrandet ist muessen + // wir zumindest den minimalen Abstand zum Inhalt + // beruecksichtigen. (Koennte man zusaetzlich auch an + // nCellPadding festmachen.) + nSpace = MIN_BORDER_DIST; + } + + return nSpace; +} + +void SwHTMLTableLayout::AddBorderWidth( ULONG &rMin, ULONG &rMax, + ULONG &rAbsMin, + USHORT nCol, USHORT nColSpan, + BOOL bSwBorders ) const +{ + ULONG nAdd = GetLeftCellSpace( nCol, nColSpan, bSwBorders ) + + GetRightCellSpace( nCol, nColSpan, bSwBorders ); + + rMin += nAdd; + rMax += nAdd; + rAbsMin += nAdd; + +#if 0 + // Diese Breiten-Berchnung orientiert sich an den SW-Umrandungen!!! + USHORT nBDist = nCellPadding; + + // linke Umrandung beruecksichtigen + USHORT nBorderWidth = GetLeftBorderWidth( nCol ); + if( nBorderWidth ) + { + rMin += nBorderWidth; + rMax += nBorderWidth; + rAbsMin += nBorderWidth; + if( !nBDist ) + nBDist = MIN_BORDER_DIST; + } + + // rechte Umrandung beruecksichtigen + nBorderWidth = GetRightBorderWidth( nCol, nColSpan ); + if( nBorderWidth ) + { + rMin += nBorderWidth; + rMax += nBorderWidth; + rAbsMin += nBorderWidth; + if( !nBDist ) + nBDist = MIN_BORDER_DIST; + } + + // Abstand zum Inhalt beruecksichtigen + rMin += 2*nBDist; + rMax += 2*nBDist; + rAbsMin += 2*nBDist; +#endif +} + +void SwHTMLTableLayout::SetBoxWidth( SwTableBox *pBox, USHORT nCol, + USHORT nColSpan ) const +{ + SwFrmFmt *pFrmFmt = pBox->GetFrmFmt(); + + // die Breite der Box berechnen + SwTwips nFrmWidth = 0; + while( nColSpan-- ) + nFrmWidth += GetColumn( nCol++ )->GetRelColWidth(); + + // und neu setzen + + pFrmFmt->SetAttr( SwFmtFrmSize( ATT_VAR_SIZE, nFrmWidth, 0 )); +} + +void SwHTMLTableLayout::GetAvail( USHORT nCol, USHORT nColSpan, + USHORT& rAbsAvail, USHORT& rRelAvail ) const +{ + rAbsAvail = 0; + rRelAvail = 0; + for( USHORT i=nCol; iGetAbsColWidth(); + rRelAvail += pColumn->GetRelColWidth(); + } + +#if 0 + rAbsSpace = GetLeftBorderWidth( nCol ) + + GetRightBorderWidth( nCol, nColSpan ) + + 2*nCellPadding; +#endif +} + +USHORT SwHTMLTableLayout::GetBrowseWidthByVisArea( const SwDoc& rDoc ) +{ + ViewShell *pVSh = 0; + rDoc.GetEditShell( &pVSh ); + if( pVSh ) + { + return (USHORT)( pVSh->VisArea().Width() - + 2*pVSh->GetOut()->PixelToLogic( pVSh->GetBrowseBorder() ).Width() ); + } + + return 0; +} + +USHORT SwHTMLTableLayout::GetBrowseWidth( const SwDoc& rDoc ) +{ + // Wenn ein Layout da ist, koennen wir die Breite dort herholen. + const SwRootFrm *pRootFrm = rDoc.GetRootFrm(); + if( pRootFrm ) + { + const SwFrm *pPageFrm = pRootFrm->GetLower(); + if( pPageFrm ) + return (USHORT)pPageFrm->Prt().Width(); + } + + // Sonst versuchen wir es ueber die ViewShell + USHORT nWidth = GetBrowseWidthByVisArea( rDoc ); + if( !nWidth ) + { + // Und wenn das auch nicht geht, gibt es noch die ActualSize an der + // DocShell. + if( rDoc.GetDocShell() && GetpApp() && GetpApp()->GetDefaultDevice() ) + { + nWidth = (USHORT)Application::GetDefaultDevice() + ->PixelToLogic( rDoc.GetDocShell()->GetActualSize(), + MapMode( MAP_TWIP ) ).Width(); + + ASSERT( nWidth, "GetActualSize liefert 0" ); + } +#ifndef PRODUCT + else + { + // und wenn das auch nicht klappt, gibt es zur Zeit keine Breite + ASSERT( nWidth, "Nix da um eine Browse-Breite zu berechnen" ); + } +#endif + } + return nWidth; +} + +USHORT SwHTMLTableLayout::GetBrowseWidthByTabFrm( + const SwTabFrm& rTabFrm ) const +{ + SwTwips nWidth = 0; + + const SwFrm *pUpper = rTabFrm.GetUpper(); + if( MayBeInFlyFrame() && pUpper->IsFlyFrm() && + ((const SwFlyFrm *)pUpper)->GetAnchor() ) + { + // Wenn die Tabelle in einem selbst angelegten Rahmen steht, dann ist + // die Breite Ankers und nicht die Breite Rahmens von Bedeutung. + // Bei Absatz-gebundenen Rahmen werden Absatz-Einzuege nicht beachtet. + const SwFrm *pAnchor = ((const SwFlyFrm *)pUpper)->GetAnchor(); + if( pAnchor->IsTxtFrm() ) + nWidth = pAnchor->Frm().Width(); + else + nWidth = pAnchor->Prt().Width(); + } + else + { + nWidth = pUpper->Prt().Width(); + } + + SwTwips nUpperDummy = 0; + long nRightOffset = 0, + nLeftOffset = 0; + rTabFrm.CalcFlyOffsets( nUpperDummy, nLeftOffset, nRightOffset ); + nWidth -= (nLeftOffset + nRightOffset); + + return nWidth < USHRT_MAX ? nWidth : USHRT_MAX; +} + +USHORT SwHTMLTableLayout::GetBrowseWidthByTable( const SwDoc& rDoc ) const +{ + USHORT nBrowseWidth = 0; + SwClientIter aIter( *(SwModify*)pSwTable->GetFrmFmt() ); + SwClient* pCli = aIter.First( TYPE( SwTabFrm )); + if( pCli ) + { + nBrowseWidth = GetBrowseWidthByTabFrm( *(SwTabFrm*)pCli ); + } + else + { + nBrowseWidth = SwHTMLTableLayout::GetBrowseWidth( rDoc ); + } + + return nBrowseWidth; +} + +const SwStartNode *SwHTMLTableLayout::GetAnyBoxStartNode() const +{ + const SwStartNode *pBoxSttNd; + + const SwTableBox* pBox = pSwTable->GetTabLines()[0]->GetTabBoxes()[0]; + while( 0 == (pBoxSttNd = pBox->GetSttNd()) ) + { + ASSERT( pBox->GetTabLines().Count() > 0, + "Box ohne Start-Node und Lines" ); + ASSERT( pBox->GetTabLines()[0]->GetTabBoxes().Count() > 0, + "Line ohne Boxen" ); + pBox = pBox->GetTabLines()[0]->GetTabBoxes()[0]; + } + + return pBoxSttNd; +} + +SwFrmFmt *SwHTMLTableLayout::FindFlyFrmFmt() const +{ + const SwTableNode *pTblNd = GetAnyBoxStartNode()->FindTableNode(); + ASSERT( pTblNd, "Kein Table-Node?" ); + return pTblNd->GetFlyFmt(); +} + +void lcl_GetMinMaxSize( ULONG& rMinNoAlignCnts, ULONG& rMaxNoAlignCnts, + ULONG& rAbsMinNoAlignCnts, +#ifdef FIX41370 + BOOL& rHR, +#endif + SwTxtNode *pTxtNd, ULONG nIdx, BOOL bNoBreak ) +{ + pTxtNd->GetMinMaxSize( nIdx, rMinNoAlignCnts, rMaxNoAlignCnts, + rAbsMinNoAlignCnts ); + ASSERT( rAbsMinNoAlignCnts <= rMinNoAlignCnts, + "GetMinMaxSize: absmin > min" ); + ASSERT( rMinNoAlignCnts <= rMaxNoAlignCnts, + "GetMinMaxSize: max > min" ); + + //Bei einen
-Absatz entspricht die maximale Breite der
+    // minimalen breite
+    const SwFmtColl *pColl = &pTxtNd->GetAnyFmtColl();
+    while( pColl && !pColl->IsDefault() &&
+            (USER_FMT & pColl->GetPoolFmtId()) )
+    {
+        pColl = (const SwFmtColl *)pColl->DerivedFrom();
+    }
+
+    //  in der gesamten Zelle bezieht sich auf Text, aber nicht
+    // auf Tabellen. Netscape beruecksichtigt dies nur fuer Grafiken.
+    if( (pColl && RES_POOLCOLL_HTML_PRE==pColl->GetPoolFmtId()) || bNoBreak )
+    {
+        rMinNoAlignCnts = rMaxNoAlignCnts;
+        rAbsMinNoAlignCnts = rMaxNoAlignCnts;
+    }
+#ifdef FIX41370
+    else if( pColl && RES_POOLCOLL_HTML_HR==pColl->GetPoolFmtId() )
+    {
+        rHR |= !pTxtNd->GetpSwAttrSet() ||
+                SFX_ITEM_SET != pTxtNd->GetpSwAttrSet()
+                                      ->GetItemState( RES_LR_SPACE, FALSE );
+    }
+#endif
+}
+
+void SwHTMLTableLayout::AutoLayoutPass1()
+{
+    nPass1Done++;
+
+    ClearPass1Info();
+
+    BOOL bFixRelWidths = FALSE;
+    USHORT i;
+
+    SwHTMLTableLayoutConstraints *pConstraints = 0;
+
+    for( i=0; iClearPass1Info( !HasColTags() );
+        USHORT nMinColSpan = USHRT_MAX; // Spaltenzahl, auf die sich dir
+                                        // berechnete Breite bezieht
+        USHORT nColSkip = USHRT_MAX;    // Wie viele Spalten muessen
+                                        // uebersprungen werden
+
+        for( USHORT j=0; jGetContents();
+
+            // fix #31488#: Zum Ermitteln der naechsten zu berechnenden
+            // Spalte muessen alle Zeilen herangezogen werden
+            USHORT nColSpan = pCell->GetColSpan();
+            if( nColSpan < nColSkip )
+                nColSkip = nColSpan;
+
+            if( !pCnts || (pCnts && !pCnts->IsPass1Done(nPass1Done)) )
+            {
+                // die Zelle ist leer oder ihr Inhalt wurde nich nicht
+                // bearbeitet
+                if( nColSpan < nMinColSpan )
+                    nMinColSpan = nColSpan;
+
+                ULONG nMinNoAlignCell = 0;
+                ULONG nMaxNoAlignCell = 0;
+                ULONG nAbsMinNoAlignCell = 0;
+                ULONG nMaxTableCell = 0;
+                ULONG nAbsMinTableCell = 0;
+#ifdef FIX41370
+                BOOL bHR = FALSE;
+#endif
+
+                while( pCnts )
+                {
+                    const SwStartNode *pSttNd = pCnts->GetStartNode();
+                    if( pSttNd )
+                    {
+                        const SwDoc *pDoc = pSttNd->GetDoc();
+                        ULONG nIdx = pSttNd->GetIndex();
+                        while( !(pDoc->GetNodes()[nIdx])->IsEndNode() )
+                        {
+                            SwTxtNode *pTxtNd = (pDoc->GetNodes()[nIdx])->GetTxtNode();
+                            if( pTxtNd )
+                            {
+                                ULONG nMinNoAlignCnts;
+                                ULONG nMaxNoAlignCnts;
+                                ULONG nAbsMinNoAlignCnts;
+
+                                lcl_GetMinMaxSize( nMinNoAlignCnts,
+                                                   nMaxNoAlignCnts,
+                                                   nAbsMinNoAlignCnts,
+#ifdef FIX41370
+                                                   bHR,
+#endif
+                                                   pTxtNd, nIdx,
+                                                   pCnts->HasNoBreakTag() );
+
+                                if( nMinNoAlignCnts > nMinNoAlignCell )
+                                    nMinNoAlignCell = nMinNoAlignCnts;
+                                if( nMaxNoAlignCnts > nMaxNoAlignCell )
+                                    nMaxNoAlignCell = nMaxNoAlignCnts;
+                                if( nAbsMinNoAlignCnts > nAbsMinNoAlignCell )
+                                    nAbsMinNoAlignCell = nAbsMinNoAlignCnts;
+                            }
+                            nIdx++;
+                        }
+                    }
+                    else
+                    {
+                        SwHTMLTableLayout *pChild = pCnts->GetTable();
+                        pChild->AutoLayoutPass1();
+                        ULONG nMaxTableCnts = pChild->nMax;
+                        ULONG nAbsMinTableCnts = pChild->nMin;
+
+                        // Eine feste Tabellen-Breite wird als Minimum
+                        // und Maximum gleichzeitig uebernommen
+                        if( !pChild->bPrcWidthOption && pChild->nWidthOption )
+                        {
+                            ULONG nTabWidth = pChild->nWidthOption;
+                            if( nTabWidth >= nAbsMinTableCnts  )
+                            {
+                                nMaxTableCnts = nTabWidth;
+                                nAbsMinTableCnts = nTabWidth;
+                            }
+                            else
+                            {
+                                nMaxTableCnts = nAbsMinTableCnts;
+                            }
+                        }
+
+                        if( nMaxTableCnts > nMaxTableCell )
+                            nMaxTableCell = nMaxTableCnts;
+                        if( nAbsMinTableCnts > nAbsMinTableCell )
+                            nAbsMinTableCell = nAbsMinTableCnts;
+                    }
+                    pCnts->SetPass1Done( nPass1Done );
+                    pCnts = pCnts->GetNext();
+                }
+
+// War frueher hinter AddBorderWidth
+                // Wenn die Breite einer Tabelle in der Zelle breiter ist als
+                // das, was wir fuer sonstigen Inhalt berechnet haben, mussen
+                // wir die Breite der Tabelle nutzen
+                if( nMaxTableCell > nMaxNoAlignCell )
+                    nMaxNoAlignCell = nMaxTableCell;
+                if( nAbsMinTableCell > nAbsMinNoAlignCell )
+                {
+                    nAbsMinNoAlignCell = nAbsMinTableCell;
+                    if( nMinNoAlignCell < nAbsMinNoAlignCell )
+                        nMinNoAlignCell = nAbsMinNoAlignCell;
+                    if( nMaxNoAlignCell < nMinNoAlignCell )
+                        nMaxNoAlignCell = nMinNoAlignCell;
+                }
+// War frueher hinter AddBorderWidth
+
+                BOOL bRelWidth = pCell->IsPrcWidthOption();
+                USHORT nWidth = pCell->GetWidthOption();
+
+                // Eine NOWRAP-Option bezieht sich auf Text und auf
+                // Tabellen, wird aber bei fester Zellenbreite
+                // nicht uebernommen. Stattdessen wirkt die angegebene
+                // Zellenbreite wie eine Mindestbreite.
+                if( pCell->HasNoWrapOption() )
+                {
+                    if( nWidth==0 || bRelWidth )
+                    {
+                        nMinNoAlignCell = nMaxNoAlignCell;
+                        nAbsMinNoAlignCell = nMaxNoAlignCell;
+                    }
+                    else
+                    {
+                        if( nWidth>nMinNoAlignCell )
+                            nMinNoAlignCell = nWidth;
+                        if( nWidth>nAbsMinNoAlignCell )
+                            nAbsMinNoAlignCell = nWidth;
+                    }
+                }
+#ifdef FIX41370
+                else if( bHR && nWidth>0 && !bRelWidth )
+                {
+                    // Ein kleiner Hack, um einen Bug in Netscape 4.0
+                    // nachzubilden (siehe #41370#). Wenn eine Zelle eine
+                    // fixe Breite besitzt und gleichzeitig ein HR, wird
+                    // sie nie schmaler als die angegebene Breite.
+                    // (Genaugenomen scheint die Zelle nie schmaler zu werden
+                    // als die HR-Linie, denn wenn man fuer die Linie eine
+                    // Breite angibt, die breiter ist als die der Zelle, dann
+                    // wird die Zelle so breit wie die Linie. Das bekommen wir
+                    // natuerlich nicht hin.)
+                    if( nWidth>nMinNoAlignCell )
+                        nMinNoAlignCell = nWidth;
+                    if( nWidth>nAbsMinNoAlignCell )
+                        nAbsMinNoAlignCell = nWidth;
+                }
+#endif
+
+                // Mindestbreite fuer Inhalt einhalten
+                if( nMinNoAlignCell < MINLAY )
+                    nMinNoAlignCell = MINLAY;
+                if( nMaxNoAlignCell < MINLAY )
+                    nMaxNoAlignCell = MINLAY;
+                if( nAbsMinNoAlignCell < MINLAY )
+                    nAbsMinNoAlignCell = MINLAY;
+
+                // Umrandung und Abstand zum Inhalt beachten.
+                AddBorderWidth( nMinNoAlignCell, nMaxNoAlignCell,
+                                nAbsMinNoAlignCell, i, nColSpan );
+
+                if( 1==nColSpan )
+                {
+                    // die Werte direkt uebernehmen
+                    pColumn->MergeMinMaxNoAlign( nMinNoAlignCell,
+                                                 nMaxNoAlignCell,
+                                                 nAbsMinNoAlignCell );
+
+                    // bei den WIDTH angaben gewinnt die breiteste
+                    if( !HasColTags() )
+                        pColumn->MergeCellWidthOption( nWidth, bRelWidth );
+                }
+                else
+                {
+                    // die Angaben erst am Ende, und zwar zeilenweise von
+                    // links nach rechts bearbeiten
+
+                    // Wann welche Werte wie uebernommen werden ist weiter
+                    // unten erklaert.
+                    if( !HasColTags() && nWidth && !bRelWidth )
+                    {
+                        ULONG nAbsWidth = nWidth, nDummy = 0, nDummy2 = 0;
+                        AddBorderWidth( nAbsWidth, nDummy, nDummy2,
+                                        i, nColSpan, FALSE );
+
+                        if( nAbsWidth >= nMinNoAlignCell )
+                        {
+                            nMaxNoAlignCell = nAbsWidth;
+                            if( HasColsOption() )
+                                nMinNoAlignCell = nAbsWidth;
+                        }
+                        else if( nAbsWidth >= nAbsMinNoAlignCell )
+                        {
+                            nMaxNoAlignCell = nAbsWidth;
+                            nMinNoAlignCell = nAbsWidth;
+                        }
+                        else
+                        {
+                            nMaxNoAlignCell = nAbsMinNoAlignCell;
+                            nMinNoAlignCell = nAbsMinNoAlignCell;
+                        }
+                    }
+                    else if( HasColsOption() || HasColTags() )
+                        nMinNoAlignCell = nAbsMinNoAlignCell;
+
+                    SwHTMLTableLayoutConstraints *pConstr =
+                        new SwHTMLTableLayoutConstraints( nMinNoAlignCell,
+                            nMaxNoAlignCell, j, i, nColSpan );
+                    if( pConstraints )
+                        pConstraints = pConstraints->InsertNext( pConstr );
+                    else
+                        pConstraints = pConstr;
+                }
+            }
+        }
+
+        ASSERT( nMinColSpan>0 && nColSkip>0 && nColSkip <= nMinColSpan,
+                "Layout Pass 1: Da werden Spalten vergessen!" );
+        ASSERT( nMinColSpan!=USHRT_MAX,
+                "Layout Pass 1: unnoetiger Schleifendurchlauf oder Bug" );
+
+        if( 1==nMinColSpan )
+        {
+            // es gibt Zellen mit COLSPAN 1 und demnach auch sinnvolle
+            // Werte in pColumn
+
+            // Werte anhand folgender Tabelle (Netscape 4.0 pv 3) uebernehmen:
+            //
+            // WIDTH:           kein COLS       COLS
+            //
+            // keine            min = min       min = absmin
+            //                  max = max       max = max
+            //
+            // >= min           min = min       min = width
+            //                  max = width     max = width
+            //
+            // >= absmin        min = wdith(*)  min = width
+            //                  max = width     max = width
+            //
+            // < absmin         min = absmin    min = absmin
+            //                  max = absmin    max = absmin
+            //
+            // (*) Netscape benutzt hier die Mindestbreite ohne einen
+            //     Umbruch vor der letzten Grafik. Haben wir (noch?) nicht,
+            //     also belassen wir es bei width.^
+
+            if( pColumn->GetWidthOption() && !pColumn->IsRelWidthOption() )
+            {
+                // absolute Breiten als Minimal- und Maximalbreite
+                // uebernehmen.
+                ULONG nAbsWidth = pColumn->GetWidthOption();
+                ULONG nDummy = 0, nDummy2 = 0;
+                AddBorderWidth( nAbsWidth, nDummy, nDummy2, i, 1, FALSE );
+
+                if( nAbsWidth >= pColumn->GetMinNoAlign() )
+                {
+                    pColumn->SetMinMax( HasColsOption() ? nAbsWidth
+                                                   : pColumn->GetMinNoAlign(),
+                                        nAbsWidth );
+                }
+                else if( nAbsWidth >= pColumn->GetAbsMinNoAlign() )
+                {
+                    pColumn->SetMinMax( nAbsWidth, nAbsWidth );
+                }
+                else
+                {
+                    pColumn->SetMinMax( pColumn->GetAbsMinNoAlign(),
+                                        pColumn->GetAbsMinNoAlign() );
+                }
+            }
+            else
+            {
+                pColumn->SetMinMax( HasColsOption() ? pColumn->GetAbsMinNoAlign()
+                                               : pColumn->GetMinNoAlign(),
+                                    pColumn->GetMaxNoAlign() );
+            }
+        }
+        else if( USHRT_MAX!=nMinColSpan )
+        {
+            // kann irgendwas !=0 sein, weil es durch die Constraints
+            // angepasst wird.
+            pColumn->SetMinMax( MINLAY, MINLAY );
+
+            // die naechsten Spalten muessen nicht bearbeitet werden
+            i += (nColSkip-1);
+        }
+
+        nMin += pColumn->GetMin();
+        nMax += pColumn->GetMax();
+        bFixRelWidths |= pColumn->IsRelWidthOption();
+    }
+
+    // jetzt noch die Constrains verarbeiten
+    SwHTMLTableLayoutConstraints *pConstr = pConstraints;
+    while( pConstr )
+    {
+        // Erstmal muss die Breite analog zu den den Spaltenbreiten
+        // aufbereitet werden
+        USHORT nCol = pConstr->GetColumn();
+        USHORT nColSpan = pConstr->GetColSpan();
+        ULONG nConstrMin = pConstr->GetMinNoAlign();
+        ULONG nConstrMax = pConstr->GetMaxNoAlign();
+
+        // jetzt holen wir uns die bisherige Breite der ueberspannten
+        // Spalten
+        ULONG nColsMin = 0;
+        ULONG nColsMax = 0;
+        for( USHORT i=nCol; iGetMin();
+            nColsMax += pColumn->GetMax();
+        }
+
+        if( nColsMin nColsMax )
+            {
+                // Anteilig anhand der Mindestbreiten
+                USHORT nEndCol = nCol+nColSpan;
+                ULONG nDiff = nMinD;
+                for( USHORT i=nCol; iGetMin();
+                    ULONG nColMax = pColumn->GetMax();
+
+                    nMin -= nColMin;
+                    ULONG nAdd = i= nAdd, "Ooops: nDiff stimmt nicht mehr" );
+                    nDiff -= nAdd;
+
+                    if( nColMax < nColMin )
+                    {
+                        nMax -= nColMax;
+                        nColsMax -= nColMax;
+                        nColMax = nColMin;
+                        nMax += nColMax;
+                        nColsMax += nColMax;
+                    }
+
+                    pColumn->SetMinMax( nColMin, nColMax );
+                }
+            }
+            else
+            {
+                // Anteilig anhand der Differenz zwischen Max und Min
+                for( USHORT i=nCol; iGetMax()-pColumn->GetMin();
+                    if( nMinD < nDiff )
+                        nDiff = nMinD;
+
+                    pColumn->AddToMin( nDiff );
+
+                    ASSERT( pColumn->GetMax() >= pColumn->GetMin(),
+                            "Wieso ist die SPalte auf einmal zu schmal?" )
+
+                    nMin += nDiff;
+                    nMinD -= nDiff;
+                }
+            }
+        }
+
+        if( !HasColTags() && nColsMaxGetMax();
+
+                pColumn->AddToMax( (pColumn->GetMax() * nMaxD) / nColsMax );
+
+                nMax += pColumn->GetMax();
+            }
+        }
+
+        pConstr = pConstr->GetNext();
+    }
+
+
+    if( bFixRelWidths )
+    {
+        if( HasColTags() )
+        {
+            // Zum Anpassen der relativen Breiten werden im 1. Schritt die
+            // Minmalbreiten aller anzupassenden Zellen jeweils mit der
+            // relativen Breite einer Spalte multipliziert. Dadurch stimmen
+            // dann die Breitenverhaeltnisse der Spalten untereinander.
+            // Ausserdem wird der Faktor berechnet, um den die Zelle dadurch
+            // breiter gworden ist als die Minmalbreite.
+            // Im 2. Schritt werden dann die berechneten Breiten durch diesen
+            // Faktor geteilt. Dadurch bleibt die Breite (nimd.) einer Zelle
+            // erhalten und dient als Ausgangsbasis fuer die andern Breiten.
+            // Es werden auch hier nur die Maximalbreiten beeinflusst!
+
+            ULONG nAbsMin = 0;  // absolte Min-Breite alter Spalten mit
+                                // relativer Breite
+            ULONG nRel = 0;     // Summe der relativen Breiten aller Spalten
+            for( i=0; iIsRelWidthOption() && pColumn->GetWidthOption() )
+                {
+                    nAbsMin += pColumn->GetMin();
+                    nRel += pColumn->GetWidthOption();
+                }
+            }
+
+            ULONG nQuot = ULONG_MAX;
+            for( i=0; iIsRelWidthOption() )
+                {
+                    nMax -= pColumn->GetMax();
+                    if( pColumn->GetWidthOption() && pColumn->GetMin() )
+                    {
+                        pColumn->SetMax( nAbsMin * pColumn->GetWidthOption() );
+                        ULONG nColQuot = pColumn->GetMax() / pColumn->GetMin();
+                        if( nColQuotIsRelWidthOption() )
+                {
+                    if( pColumn->GetWidthOption() )
+                        pColumn->SetMax( pColumn->GetMax() / nQuot );
+                    else
+                        pColumn->SetMax( pColumn->GetMin() );
+                    ASSERT( pColumn->GetMax() >= pColumn->GetMin(),
+                            "Maximale Spaltenbreite kleiner als Minimale" );
+                    nMax += pColumn->GetMax();
+                }
+            }
+        }
+        else
+        {
+            USHORT nRel = 0;        // Summe der relativen Breiten aller Spalten
+            USHORT nRelCols = 0;    // Anzahl Spalten mit relativer Angabe
+            ULONG nRelMax = 0;      // Anteil am Maximum dieser Spalten
+            for( i=0; i100%" );
+                SwHTMLTableLayoutColumn *pColumn = GetColumn( i );
+                if( pColumn->IsRelWidthOption() && pColumn->GetWidthOption() )
+                {
+                    // Sicherstellen, dass die relativen breiten nicht
+                    // ueber 100% landen
+                    USHORT nColWidth = pColumn->GetWidthOption();
+                    if( nRel+nColWidth > 100 )
+                    {
+                        nColWidth = 100 - nRel;
+                        pColumn->SetWidthOption( nColWidth, TRUE, FALSE );
+                    }
+                    nRelMax += pColumn->GetMax();
+                    nRel += nColWidth;
+                    nRelCols++;
+                }
+                else if( !pColumn->GetMin() )
+                {
+                    // Die Spalte ist leer (wurde also auschliesslich
+                    // durch COLSPAN erzeugt) und darf deshalb auch
+                    // keine %-Breite zugewiesen bekommen.
+                    nRelCols++;
+                }
+            }
+
+            // Eventuell noch vorhandene Prozente werden auf die Spalten ohne
+            // eine Breiten-Angabe verteilt. Wie in Netscape werden die
+            // verbleibenden Prozente enstprechend der Verhaeltnisse
+            // der Maximalbreiten der in Frage kommenden Spalten
+            // untereinander verteilt.
+            // ??? Wie beruecksichtigen bei den Maximalbreiten auch Spalten
+            // mit fester Breite. Ist das richtig???
+            if( nRel < 100 && nRelCols < nCols )
+            {
+                USHORT nRelLeft = 100 - nRel;
+                ULONG nFixMax = nMax - nRelMax;
+                for( i=0; iIsRelWidthOption() &&
+                        !pColumn->GetWidthOption() &&
+                        pColumn->GetMin() )
+                    {
+                        // den Rest bekommt die naechste Spalte
+                        USHORT nColWidth =
+                            (USHORT)((pColumn->GetMax() * nRelLeft) / nFixMax);
+                        pColumn->SetWidthOption( nColWidth, TRUE, FALSE );
+                    }
+                }
+            }
+
+            // nun die Maximalbreiten entsprechend anpassen
+            ULONG nQuotMax = ULONG_MAX;
+            ULONG nOldMax = nMax;
+            nMax = 0;
+            for( i=0; iIsRelWidthOption() && pColumn->GetWidthOption() )
+                {
+                    ULONG nNewMax;
+                    ULONG nColQuotMax;
+                    if( !nWidthOption )
+                    {
+                        nNewMax = nOldMax * pColumn->GetWidthOption();
+                        nColQuotMax = nNewMax / pColumn->GetMax();
+                    }
+                    else
+                    {
+                        nNewMax = nMin * pColumn->GetWidthOption();
+                        nColQuotMax = nNewMax / pColumn->GetMin();
+                    }
+                    pColumn->SetMax( nNewMax );
+                    if( nColQuotMax < nQuotMax )
+                        nQuotMax = nColQuotMax;
+                }
+                else if( HasColsOption() || nWidthOption ||
+                         (pColumn->IsRelWidthOption() &&
+                          !pColumn->GetWidthOption()) )
+                    pColumn->SetMax( pColumn->GetMin() );
+            }
+            // und durch den Quotienten teilen
+            ASSERT( nQuotMax!=ULONG_MAX, "Wo sind die relativen Spalten geblieben?" );
+            for( i=0; iIsRelWidthOption() && pColumn->GetWidthOption() )
+                {
+                    if( pColumn->GetWidthOption() )
+                    {
+                        pColumn->SetMax( pColumn->GetMax() / nQuotMax );
+                        ASSERT( pColumn->GetMax() >= pColumn->GetMin(),
+                                "Minimalbreite ein Spalte Groesser Maximum" );
+                        if( pColumn->GetMax() < pColumn->GetMin() )
+                            pColumn->SetMax( pColumn->GetMin() );
+                    }
+                }
+                nMax += pColumn->GetMax();
+            }
+        }
+    }
+
+    delete pConstraints;
+}
+
+// nAbsAvail ist der verfuegbare Platz in TWIPS.
+// nRelAvail ist der auf USHRT_MAX bezogene verfuegbare Platz oder 0
+// nAbsSpace ist der Anteil von nAbsAvail, der durch der umgebende Zelle
+//           fur die Umrandung und den Abstand zum Inhalt reserviert ist.
+void SwHTMLTableLayout::AutoLayoutPass2( USHORT nAbsAvail, USHORT nRelAvail,
+                                         USHORT nAbsLeftSpace,
+                                         USHORT nAbsRightSpace,
+                                         USHORT nParentInhAbsSpace )
+{
+    // Erstmal fuehren wie jede Menge Plausibilaets-Test durch
+
+    // Eine abolute zur Verfuegung stehende Breite muss immer uebergeben
+    // werden.
+    ASSERT( nAbsAvail, "AutoLayout Pass 2: Keine absolute Breite gegeben" );
+
+    // Eine realtive zur Verfuegung stehende Breite darf nur und muss fuer
+    // Tabellen in Tabellen uebergeben
+    ASSERT( IsTopTable() == (nRelAvail==0),
+            "AutoLayout Pass 2: Rel. Breite bei Tab in Tab oder umgekehrt" );
+
+    // Die Minimalbreite der Tabelle darf natuerlich nie groesser sein
+    // als das die Maximalbreite.
+    ASSERT( nMin<=nMax, "AutoLayout Pass2: nMin > nMax" );
+
+    // Die verfuegbare Breite, fuer die die Tabelle berechnet wurde, merken.
+    // (Dies ist ein guter Ort, denn hier kommer wir bei der Erstberechnung
+    // der Tabelle aus dem Parser und bei jedem _Resize-Aufruf vorbei.)
+    nLastResizeAbsAvail = nAbsAvail;
+
+    // Schritt 1: Der verfuegbar Platz wird an linke/rechte Raender,
+    // vorhandene Filler-Zellen und Abstande angepasst
+
+    // Abstand zum Inhalt und Unrandung
+    USHORT nAbsLeftFill = 0, nAbsRightFill = 0;
+    if( !IsTopTable() &&
+        GetMin() + nAbsLeftSpace + nAbsRightSpace <= nAbsAvail )
+    {
+        nAbsLeftFill = nAbsLeftSpace;
+        nAbsRightFill = nAbsRightSpace;
+    }
+
+    // Linker und rechter Abstand
+    if( nLeftMargin || nRightMargin )
+    {
+        if( IsTopTable() )
+        {
+            // fuer die Top-Table beruecksichtigen wir die Raender immer,
+            // den die Minimalbreite der Tabelle wird hier nie unterschritten
+            nAbsAvail -= (nLeftMargin + nRightMargin);
+        }
+        else if( GetMin() + nLeftMargin + nRightMargin <= nAbsAvail )
+        {
+            // sonst beruecksichtigen wir die Raender nur, wenn auch Platz
+            // fuer sie da ist (nMin ist hier bereits berechnet!)
+            nAbsLeftFill += nLeftMargin;
+            nAbsRightFill += nRightMargin;
+        }
+    }
+
+    // Filler-Zellen
+    if( !IsTopTable() )
+    {
+        if( pLeftFillerBox && nAbsLeftFill0 || nAbsRightFill) )
+    {
+        ULONG nAbsLeftFillL = nAbsLeftFill, nAbsRightFillL = nAbsRightFill;
+
+        nRelLeftFill = (USHORT)((nAbsLeftFillL * nRelAvail) / nAbsAvail);
+        nRelRightFill = (USHORT)((nAbsRightFillL * nRelAvail) / nAbsAvail);
+
+        nAbsAvail -= (nAbsLeftFill + nAbsRightFill);
+        if( nRelAvail )
+            nRelAvail -= (nRelLeftFill + nRelRightFill);
+    }
+
+
+    // Schritt 2: Die absolute Tabellenbreite wird berechnet.
+    USHORT nAbsTabWidth = 0;
+    bUseRelWidth = FALSE;
+    if( nWidthOption )
+    {
+        if( bPrcWidthOption )
+        {
+            ASSERT( nWidthOption<=100, "Prozentangabe zu gross" );
+            if( nWidthOption > 100 )
+                nWidthOption = 100;
+
+            // Die absolute Breite entspricht den angegeben Prozent der
+            // zur Verfuegung stehenden Breite.
+            // Top-Tabellen bekommen nur eine relative Breite, wenn der
+            // verfuegbare Platz *echt groesser* ist als die Minimalbreite.
+            // ACHTUNG: Das "echte groesser" ist noetig, weil der Wechsel
+            // von einer relativen Breite zu einer absoluten Breite durch
+            // Resize sonst zu einer Endlosschleife fuehrt.
+            // Weil bei Tabellen in Rahmen kein Resize aufgerufen wird,
+            // wenn der Rahmen eine nicht-relative Breite besitzt, koennen
+            // wir da solche Spielchen nicht spielen
+            // MIB 19.2.98: Wegen fix #47394# spielen wir solche Spielchen
+            // jetzt doch. Dort war eine Grafik in einer 1%-breiten
+            // Tabelle und hat da natuerlich nicht hineingepasst.
+            nAbsTabWidth = (USHORT)( ((ULONG)nAbsAvail * nWidthOption) / 100 );
+            if( IsTopTable() &&
+                ( /*MayBeInFlyFrame() ||*/ (ULONG)nAbsTabWidth > nMin ) )
+            {
+                nRelAvail = USHRT_MAX;
+                bUseRelWidth = TRUE;
+            }
+        }
+        else
+        {
+            nAbsTabWidth = nWidthOption;
+            if( nAbsTabWidth > MAX_TABWIDTH )
+                nAbsTabWidth = MAX_TABWIDTH;
+
+            // Tabellen in Tabellen duerfen niemals breiter werden als der
+            // verfuegbare Platz.
+            if( !IsTopTable() && nAbsTabWidth > nAbsAvail )
+                nAbsTabWidth = nAbsAvail;
+        }
+    }
+
+    ASSERT( IsTopTable() || nAbsTabWidth<=nAbsAvail,
+            "AutoLayout Pass2: nAbsTabWidth > nAbsAvail fuer Tab in Tab" );
+    ASSERT( !nRelAvail || nAbsTabWidth<=nAbsAvail,
+            "AutoLayout Pass2: nAbsTabWidth > nAbsAvail fuer relative Breite" );
+
+    // Catch fuer die beiden Asserts von oben (man weiss ja nie!)
+    if( (!IsTopTable() || nRelAvail>0) && nAbsTabWidth>nAbsAvail )
+        nAbsTabWidth = nAbsAvail;
+
+
+    // Schritt 3: Bestimmen der Spaltenbreiten und ggf. auch der
+    // absoluten und relativen Tabellenbreiten.
+    if( (!IsTopTable() && nMin > (ULONG)nAbsAvail) ||
+        nMin > MAX_TABWIDTH )
+    {
+        // Wenn
+        // - das Minumum einer inneren Tabelle groesser ist als der
+        //   verfuegbare Platz, oder
+        // - das Minumum einer Top-Table groesser ist als USHRT_MAX
+        // muss die Tabelle an den verfuegbaren Platz bzw. USHRT_MAX
+        // abgepasst werden. Dabei bleiben die Verhaeltnisse der Breiten
+        // untereinander erhalten.
+
+        nAbsTabWidth = IsTopTable() ? MAX_TABWIDTH : nAbsAvail;
+        nRelTabWidth = (nRelAvail ? nRelAvail : nAbsTabWidth );
+
+        USHORT nAbs = 0, nRel = 0;
+        SwHTMLTableLayoutColumn *pColumn;
+        for( USHORT i=0; iGetMin();
+            if( nColMin <= USHRT_MAX )
+            {
+                pColumn->SetAbsColWidth(
+                    (USHORT)((nColMin * nAbsTabWidth) / nMin) );
+                pColumn->SetRelColWidth(
+                    (USHORT)((nColMin * nRelTabWidth) / nMin) );
+            }
+            else
+            {
+                double nColMinD = nColMin;
+                pColumn->SetAbsColWidth(
+                    (USHORT)((nColMinD * nAbsTabWidth) / nMin) );
+                pColumn->SetRelColWidth(
+                    (USHORT)((nColMinD * nRelTabWidth) / nMin) );
+            }
+
+            nAbs += (USHORT)pColumn->GetAbsColWidth();
+            nRel += (USHORT)pColumn->GetRelColWidth();
+        }
+        pColumn = GetColumn( nCols-1 );
+        pColumn->SetAbsColWidth( nAbsTabWidth - nAbs );
+        pColumn->SetRelColWidth( nRelTabWidth - nRel );
+    }
+    else if( nMax <= (ULONG)(nAbsTabWidth ? nAbsTabWidth : nAbsAvail) )
+    {
+        // Wenn
+        // - die Tabelle eine fixe Breite besitzt und das Maximum der
+        //   Tabelle kleiner ist, oder
+        // - das Maximum kleiner ist als der verfuegbare Platz
+        // kann das Maximum direkt uebernommen werden bzw. die Tabelle nur
+        // unter Beruecksichtigung des Maxumums an die fixe Breite
+        // angepasst werden.
+
+        // Keine fixe Breite, dann das Maximum nehmen.
+        if( !nAbsTabWidth )
+            nAbsTabWidth = (USHORT)nMax;
+
+        // Eine Top-Table darf auch beriter werden als der verfuegbare Platz.
+        if( nAbsTabWidth > nAbsAvail )
+        {
+            ASSERT( IsTopTable(),
+                    "Tabelle in Tabelle soll breiter werden als umgebende Zelle" );
+            nAbsAvail = nAbsTabWidth;
+        }
+
+        // Nur den Anteil der relativen Breite verwenden, der auch fuer
+        // die absolute Breite verwendet wuerde.
+        ULONG nAbsTabWidthL = nAbsTabWidth;
+        nRelTabWidth =
+            ( nRelAvail ? (USHORT)((nAbsTabWidthL * nRelAvail) / nAbsAvail)
+                        : nAbsTabWidth );
+
+        // Gibt es Spalten mit und Spalten ohne %-Angabe?
+        ULONG nFixMax = nMax;
+        for( USHORT i=0; iIsRelWidthOption() && pColumn->GetWidthOption()>0 )
+                nFixMax -= pColumn->GetMax();
+        }
+
+        if( nFixMax > 0 && nFixMax < nMax )
+        {
+            // ja, dann den zu verteilenden Platz nur auf die Spalten
+            // mit %-Angabe verteilen.
+
+            // In diesem (und nur in diesem) Fall gibt es Spalten,
+            // die ihre Maximalbreite genau einhalten, also weder
+            // schmaler noch breiter werden. Beim zurueckrechnen der
+            // absoluten Breite aus der relativen Breite kann es
+            // zu Rundungsfehlern kommen (bug #45598#). Um die auszugeleichen
+            // werden zuerst die fixen Breiten entsprechend korrigiert
+            // eingestellt und erst danach die relativen.
+
+            USHORT nAbs = 0, nRel = 0;
+            USHORT nFixedCols = 0;
+            for( USHORT i=0; iIsRelWidthOption() || !pColumn->GetWidthOption() )
+                {
+                    // Die Spalte behaelt ihre Breite bei.
+                    nFixedCols++;
+                    ULONG nColMax = pColumn->GetMax();
+                    pColumn->SetAbsColWidth( (USHORT)nColMax );
+
+                    ULONG nRelColWidth =
+                        (nColMax * nRelTabWidth) / nAbsTabWidth;
+                    ULONG nChkWidth =
+                        (nRelColWidth * nAbsTabWidth) / nRelTabWidth;
+                    if( nChkWidth < nColMax )
+                        nRelColWidth++;
+                    else if( nChkWidth > nColMax )
+                        nRelColWidth--;
+                    pColumn->SetRelColWidth( (USHORT)nRelColWidth );
+
+                    nAbs += (USHORT)nColMax;
+                    nRel += (USHORT)nRelColWidth;
+                }
+            }
+
+            // Zu verteilende Anteile des Maximums und der relativen und
+            // absoluten Breiten. nFixMax entspricht an dieser Stelle
+            // nAbs, so dass man gleich nFixMax haette nehmen koennen.
+            // Der Code ist so aber verstaendlicher.
+            ASSERT( nFixMax == nAbs, "Zwei Schleifen, zwei Summen?" )
+            ULONG nDistMax = nMax - nFixMax;
+            USHORT nDistAbsTabWidth = nAbsTabWidth - nAbs;
+            USHORT nDistRelTabWidth = nRelTabWidth - nRel;
+
+            for( i=0; iIsRelWidthOption() && pColumn->GetWidthOption() > 0 )
+                {
+                    // Die Spalte wird anteilig breiter.
+                    nFixedCols++;
+                    if( nFixedCols == nCols )
+                    {
+                        pColumn->SetAbsColWidth( nAbsTabWidth-nAbs );
+                        pColumn->SetRelColWidth( nRelTabWidth-nRel );
+                    }
+                    else
+                    {
+                        ULONG nColMax = pColumn->GetMax();
+                        pColumn->SetAbsColWidth(
+                            (USHORT)((nColMax * nDistAbsTabWidth) / nDistMax) );
+                        pColumn->SetRelColWidth(
+                            (USHORT)((nColMax * nDistRelTabWidth) / nDistMax) );
+                    }
+                    nAbs += pColumn->GetAbsColWidth();
+                    nRel += pColumn->GetRelColWidth();
+                }
+            }
+            ASSERT( nCols==nFixedCols, "Spalte vergessen!" );
+        }
+        else
+        {
+            // nein, dann den zu verteilenden Platz auf alle Spalten
+            // gleichmaessig vertilen.
+            for( USHORT i=0; iGetMax();
+                GetColumn( i )->SetAbsColWidth(
+                    (USHORT)((nColMax * nAbsTabWidth) / nMax) );
+                GetColumn( i )->SetRelColWidth(
+                    (USHORT)((nColMax * nRelTabWidth) / nMax) );
+            }
+        }
+    }
+    else
+    {
+        // den ueber die Minimalbreite herausgehenden Platz entsprechend
+        // den einzelnen Spalten anteilig zuschlagen
+        if( !nAbsTabWidth )
+            nAbsTabWidth = nAbsAvail;
+        if( nAbsTabWidth < nMin )
+            nAbsTabWidth = (USHORT)nMin;
+
+        if( nAbsTabWidth > nAbsAvail )
+        {
+            ASSERT( IsTopTable(),
+                    "Tabelle in Tabelle soll breiter werden als Platz da ist" );
+            nAbsAvail = nAbsTabWidth;
+        }
+
+        ULONG nAbsTabWidthL = nAbsTabWidth;
+        nRelTabWidth =
+            ( nRelAvail ? (USHORT)((nAbsTabWidthL * nRelAvail) / nAbsAvail)
+                        : nAbsTabWidth );
+        double nW = nAbsTabWidth - nMin;
+        double nD = (nMax==nMin ? 1 : nMax-nMin);
+        USHORT nAbs = 0, nRel = 0;
+        for( USHORT i=0; iGetMax() - GetColumn( i )->GetMin();
+            ULONG nAbsColWidth = GetColumn( i )->GetMin() + (ULONG)((nd*nW)/nD);
+            ULONG nRelColWidth = nRelAvail
+                                    ? (nAbsColWidth * nRelTabWidth) / nAbsTabWidth
+                                    : nAbsColWidth;
+
+            GetColumn( i )->SetAbsColWidth( (USHORT)nAbsColWidth );
+            GetColumn( i )->SetRelColWidth( (USHORT)nRelColWidth );
+            nAbs += (USHORT)nAbsColWidth;
+            nRel += (USHORT)nRelColWidth;
+        }
+        GetColumn( nCols-1 )->SetAbsColWidth( nAbsTabWidth - nAbs );
+        GetColumn( nCols-1 )->SetRelColWidth( nRelTabWidth - nRel );
+
+    }
+
+    // Schritt 4: Fuer Tabellen in Tabellen kann es links und/oder rechts
+    // noch Ausgleichzellen geben. Deren Breite wird jetzt berechnet.
+    nInhAbsLeftSpace = 0;
+    nInhAbsRightSpace = 0;
+    if( !IsTopTable() && (nRelLeftFill>0 || nRelRightFill>0 ||
+                          nAbsTabWidth0,
+                "Fuer linke Filler-Box ist keine Breite da!" );
+        ASSERT( !pRightFillerBox || nRelRightFill>0,
+                "Fuer rechte Filler-Box ist keine Breite da!" );
+
+        // Filler-Breiten werden auf die ausseren Spalten geschlagen, wenn
+        // es nach dem ersten Durchlauf keine Boxen fuer sie gibt (nWidth>0)
+        // oder ihre Breite zu klein wuerde oder wenn es COL-Tags gibt und
+        // die Filler-Breite der Umrandung-Breite entspricht (dann haben wir
+        // die Tabelle wahrscheinlich selbst exportiert)
+        if( nRelLeftFill && !pLeftFillerBox &&
+            ( nWidthSet>0 || nAbsLeftFillSetAbsColWidth( pColumn->GetAbsColWidth()+nAbsLeftFill );
+            pColumn->SetRelColWidth( pColumn->GetRelColWidth()+nRelLeftFill );
+            nRelLeftFill = 0;
+            nInhAbsLeftSpace = nAbsLeftSpace + nParentInhAbsLeftSpace;
+        }
+        if( nRelRightFill && !pRightFillerBox &&
+            ( nWidthSet>0 || nAbsRightFillSetAbsColWidth( pColumn->GetAbsColWidth()+nAbsRightFill );
+            pColumn->SetRelColWidth( pColumn->GetRelColWidth()+nRelRightFill );
+            nRelRightFill = 0;
+            nInhAbsRightSpace = nAbsRightSpace + nParentInhAbsRightSpace;
+        }
+    }
+}
+
+BOOL lcl_ResizeLine( const SwTableLine*& rpLine, void* pPara );
+
+BOOL lcl_ResizeBox( const SwTableBox*& rpBox, void* pPara )
+{
+    USHORT *pWidth = (USHORT *)pPara;
+
+    if( !rpBox->GetSttNd() )
+    {
+        USHORT nWidth = 0;
+        ((SwTableBox *)rpBox)->GetTabLines().ForEach( &lcl_ResizeLine, &nWidth );
+        rpBox->GetFrmFmt()->SetAttr( SwFmtFrmSize( ATT_VAR_SIZE, nWidth, 0 ));
+        *pWidth += nWidth;
+    }
+    else
+    {
+        *pWidth += (USHORT)rpBox->GetFrmFmt()->GetFrmSize().GetSize().Width();
+    }
+
+    return TRUE;
+}
+
+BOOL lcl_ResizeLine( const SwTableLine*& rpLine, void* pPara )
+{
+    USHORT *pWidth = (USHORT *)pPara;
+#ifndef PRODUCT
+    USHORT nOldWidth = *pWidth;
+#endif;
+    *pWidth = 0;
+    ((SwTableLine *)rpLine)->GetTabBoxes().ForEach( &lcl_ResizeBox, pWidth );
+
+#ifndef PRODUCT
+    ASSERT( !nOldWidth || Abs(*pWidth-nOldWidth) < COLFUZZY,
+            "Zeilen einer Box sind unterschiedlich lang" );
+#endif;
+
+    return TRUE;
+}
+
+void SwHTMLTableLayout::SetWidths( BOOL bCallPass2, USHORT nAbsAvail,
+                                   USHORT nRelAvail, USHORT nAbsLeftSpace,
+                                   USHORT nAbsRightSpace,
+                                   USHORT nParentInhAbsSpace )
+{
+    // SetWidth muss am Ende einmal mehr fuer jede Zelle durchlaufen
+    // worden sein.
+    nWidthSet++;
+
+    // Schritt 0: Wenn noetig, wird hier noch der Pass2 des Layout-Alogithmus
+    // aufgerufen.
+    if( bCallPass2 )
+        AutoLayoutPass2( nAbsAvail, nRelAvail, nAbsLeftSpace, nAbsRightSpace,
+                         nParentInhAbsSpace );
+
+    // Schritt 1: Setzten der neuen Breite an allen Content-Boxen.
+    // Da die Boxen nichts von der HTML-Tabellen-Struktur wissen, wird
+    // ueber die HTML-Tabellen-Struktur iteriert. Fuer Tabellen in Tabellen
+    // in Tabellen wird rekursiv SetWidth aufgerufen.
+    for( USHORT i=0; iGetContents();
+            while( pCntnts && !pCntnts->IsWidthSet(nWidthSet) )
+            {
+                SwTableBox *pBox = pCntnts->GetTableBox();
+                if( pBox )
+                {
+                    SetBoxWidth( pBox, j, pCell->GetColSpan() );
+                }
+                else
+                {
+                    USHORT nAbs = 0, nRel = 0, nLSpace = 0, nRSpace = 0,
+                           nInhSpace = 0;
+                    if( bCallPass2 )
+                    {
+                        USHORT nColSpan = pCell->GetColSpan();
+                        GetAvail( j, nColSpan, nAbs, nRel );
+                        nLSpace = GetLeftCellSpace( j, nColSpan );
+                        nRSpace = GetRightCellSpace( j, nColSpan );
+                        nInhSpace = GetInhCellSpace( j, nColSpan );
+                    }
+                    pCntnts->GetTable()->SetWidths( bCallPass2, nAbs, nRel,
+                                                    nLSpace, nRSpace,
+                                                    nInhSpace );
+                }
+
+                pCntnts->SetWidthSet( nWidthSet );
+                pCntnts = pCntnts->GetNext();
+            }
+        }
+    }
+
+    // Schritt 2: Wenn eine Top-Tabelle vorliegt, werden jetzt die Formate
+    // der Nicht-Content-Boxen angepasst. Da diese aufgrund der
+    // Garbage-Collection in der HTML-Tabelle nicht bekannt sind, muessen
+    // wir hier ueber die Tabelle iterieren. Bei der Gelegenheit wird auch
+    // das Tabellen-Frameformat angepasst. Fuer Tabellen in Tabellen werden
+    // stattdessen die Breiten der Filler-Zellen gesetzt.
+    if( IsTopTable() )
+    {
+        USHORT nCalcTabWidth = 0;
+        ((SwTable *)pSwTable)->GetTabLines().ForEach( &lcl_ResizeLine,
+                                                      &nCalcTabWidth );
+        ASSERT( Abs( nRelTabWidth-nCalcTabWidth ) < COLFUZZY,
+                "Tabellebreite stimmt nicht mit Zeilenbreite ueberein." );
+
+        // Beim Anpassen des Tabellen-Formats dieses locken, weil sonst
+        // die Boxformate erneut angepasst werden. Ausserdem muss eine
+        // evtl. vorhandene %-Angabe in jedem Fall erhalten bleiben.
+        SwFrmFmt *pFrmFmt = pSwTable->GetFrmFmt();
+        ((SwTable *)pSwTable)->LockModify();
+        SwFmtFrmSize aFrmSize( pFrmFmt->GetFrmSize() );
+        aFrmSize.SetWidth( nRelTabWidth );
+        BOOL bRel = bUseRelWidth &&
+                    HORI_FULL!=pFrmFmt->GetHoriOrient().GetHoriOrient();
+        aFrmSize.SetWidthPercent( (BYTE)(bRel ? nWidthOption : 0) );
+        pFrmFmt->SetAttr( aFrmSize );
+        ((SwTable *)pSwTable)->UnlockModify();
+
+        // Wenn die Tabelle in einem Rahmen steht, muss auch noch dessen
+        // breite angepasst werden.
+        if( MayBeInFlyFrame() )
+        {
+            SwFrmFmt *pFlyFrmFmt = FindFlyFrmFmt();
+            if( pFlyFrmFmt )
+            {
+                SwFmtFrmSize aFlyFrmSize( ATT_VAR_SIZE, nRelTabWidth, MINLAY );
+
+                if( bUseRelWidth )
+                {
+                    // Bei %-Angaben wird die Breite auf das Minimum gesetzt.
+                    aFlyFrmSize.SetWidth(  nMin > USHRT_MAX ? USHRT_MAX
+                                                            : nMin );
+                    aFlyFrmSize.SetWidthPercent( (BYTE)nWidthOption );
+                }
+                pFlyFrmFmt->SetAttr( aFlyFrmSize );
+            }
+        }
+
+#ifndef PRODUCT
+        {
+            // steht im tblrwcl.cxx
+            extern void _CheckBoxWidth( const SwTableLine&, SwTwips );
+
+            // checke doch mal ob die Tabellen korrekte Breiten haben
+            SwTwips nSize = pSwTable->GetFrmFmt()->GetFrmSize().GetWidth();
+            const SwTableLines& rLines = pSwTable->GetTabLines();
+            for( USHORT n = 0; n < rLines.Count(); ++n  )
+                _CheckBoxWidth( *rLines[ n ], nSize );
+        }
+#endif
+
+    }
+    else
+    {
+        if( pLeftFillerBox )
+        {
+            pLeftFillerBox->GetFrmFmt()->SetAttr(
+                SwFmtFrmSize( ATT_VAR_SIZE, nRelLeftFill, 0 ));
+        }
+        if( pRightFillerBox )
+        {
+            pRightFillerBox->GetFrmFmt()->SetAttr(
+                SwFmtFrmSize( ATT_VAR_SIZE, nRelRightFill, 0 ));
+        }
+    }
+}
+
+void SwHTMLTableLayout::_Resize( USHORT nAbsAvail, BOOL bRecalc )
+{
+    // Wenn bRecalc gestzt ist, hat sich am Inhalt der Tabelle etwas
+    // geaendert. Es muss dann der erste Pass noch einmal durchgefuehrt
+    // werden.
+    if( bRecalc )
+        AutoLayoutPass1();
+
+    SwRootFrm *pRoot = (SwRootFrm*)GetDoc()->GetRootFrm();
+    if ( pRoot && pRoot->IsCallbackActionEnabled() )
+        pRoot->StartAllAction();
+
+    // Sonst koennen die Breiten gesetzt werden, wobei zuvor aber jewils
+    // noch der Pass 2 laufen muss.
+    SetWidths( TRUE, nAbsAvail );
+
+    if ( pRoot && pRoot->IsCallbackActionEnabled() )
+        pRoot->EndAllAction( TRUE );    //True per VirDev (Browsen ruhiger)
+}
+
+IMPL_STATIC_LINK( SwHTMLTableLayout, DelayedResize_Impl, void*, EMPTYARG )
+{
+#ifdef TEST_DELAYED_RESIZE
+    Sound::Beep( SOUND_WARNING );
+#endif
+    pThis->aResizeTimer.Stop();
+    pThis->_Resize( pThis->nDelayedResizeAbsAvail,
+                    pThis->bDelayedResizeRecalc );
+
+    return 0;
+}
+
+
+BOOL SwHTMLTableLayout::Resize( USHORT nAbsAvail, BOOL bRecalc,
+                                BOOL bForce, ULONG nDelay )
+{
+    ASSERT( IsTopTable(), "Resize darf nur an Top-Tabellen aufgerufen werden" );
+
+    // Darf die Tabelle uberhaupt Resized werden oder soll sie es trotzdem?
+    if( bMustNotResize && !bForce )
+        return FALSE;
+
+    // Darf ein Recalc der Tabelle durchgefuehrt werden?
+    if( bMustNotRecalc && !bForce )
+        bRecalc = FALSE;
+
+    const SwDoc *pDoc = GetDoc();
+
+    // Wenn es ein Layout gibt, wurde evtl. die Groesse der Root-Frames
+    // und nicht die der VisArea uebergeben. Wenn wir nicht in einem Rahmen
+    // stehen, muss die Tabelle allerdings fuer die VisArea berechnet werden,
+    // weil sond die Umschaltung von relativ nach absolut nicht funktioniert.
+    if( pDoc->GetRootFrm() && pDoc->IsBrowseMode() )
+    {
+        USHORT nVisAreaWidth = GetBrowseWidthByVisArea( *pDoc );
+        if( nVisAreaWidth < nAbsAvail && !FindFlyFrmFmt() )
+            nAbsAvail = nVisAreaWidth;
+    }
+
+    if( nDelay==0 && aResizeTimer.IsActive() )
+    {
+        // Wenn beim Aufruf eines synchronen Resize noch ein asynchrones
+        // Resize aussteht, dann werden nur die neuen Werte uebernommen.
+
+        bRecalc |= bDelayedResizeRecalc;
+        nDelayedResizeAbsAvail = nAbsAvail;
+        return FALSE;
+    }
+
+    // Optimierung:
+    // Wenn die Minima/Maxima nicht neu berechnet werden sollen und
+    // - die Breite der Tabelle nie neu berechnet werden muss, oder
+    // - die Tabelle schon fuer die uebergebene Breite berechnet wurde, oder
+    // - der verfuegbare Platz kleiner oder gleich der Minimalbreite ist
+    //   und die Tabelle bereits die Minimalbreite besitzt, oder
+    // - der verfuegbare Platz groesser ist als die Maximalbreite und
+    //   die Tabelle bereits die Maximalbreite besitzt
+    // wird sich an der Tabelle nichts aendern.
+    if( !bRecalc && ( !bMustResize ||
+                      (nLastResizeAbsAvail==nAbsAvail) ||
+                      (nAbsAvail<=nMin && nRelTabWidth==nMin) ||
+                      (!bPrcWidthOption && nAbsAvail>=nMax && nRelTabWidth==nMax) ) )
+        return FALSE;
+
+    if( nDelay==HTMLTABLE_RESIZE_NOW )
+    {
+        if( aResizeTimer.IsActive() )
+            aResizeTimer.Stop();
+        _Resize( nAbsAvail, bRecalc );
+    }
+    else if( nDelay > 0 )
+    {
+        nDelayedResizeAbsAvail = nAbsAvail;
+        bDelayedResizeRecalc = bRecalc;
+        aResizeTimer.SetTimeout( nDelay );
+        aResizeTimer.Start();
+#ifdef TEST_DELAYED_RESIZE
+        Sound::Beep( SOUND_DEFAULT );
+#endif
+    }
+    else
+    {
+        _Resize( nAbsAvail, bRecalc );
+    }
+
+    return TRUE;
+}
+
+void SwHTMLTableLayout::BordersChanged( USHORT nAbsAvail, BOOL bRecalc )
+{
+    bBordersChanged = TRUE;
+
+    Resize( nAbsAvail, bRecalc );
+}
+
+
diff --git a/sw/source/core/doc/lineinfo.cxx b/sw/source/core/doc/lineinfo.cxx
new file mode 100644
index 000000000000..87219f156245
--- /dev/null
+++ b/sw/source/core/doc/lineinfo.cxx
@@ -0,0 +1,182 @@
+/*************************************************************************
+ *
+ *  $RCSfile: lineinfo.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:16 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "doc.hxx"
+#include "lineinfo.hxx"
+#include "charfmt.hxx"
+#include "poolfmt.hxx"
+#include "rootfrm.hxx"
+#include "viewsh.hxx"
+
+void SwDoc::SetLineNumberInfo( const SwLineNumberInfo &rNew )
+{
+    if ( GetRootFrm() &&
+         (rNew.IsCountBlankLines() != pLineNumberInfo->IsCountBlankLines() ||
+          rNew.IsRestartEachPage() != pLineNumberInfo->IsRestartEachPage()) )
+    {
+        GetRootFrm()->StartAllAction();
+        GetRootFrm()->InvalidateAllCntnt( INV_LINENUM );
+        GetRootFrm()->EndAllAction();
+    }
+    *pLineNumberInfo = rNew;
+    SetModified();
+}
+
+SwLineNumberInfo::SwLineNumberInfo() :
+    nPosFromLeft( MM50 ),
+    nCountBy( 5 ),
+    nDividerCountBy( 3 ),
+    ePos( LINENUMBER_POS_LEFT ),
+    bPaintLineNumbers( FALSE ),
+    bCountBlankLines( TRUE ),
+    bCountInFlys( FALSE ),
+    bRestartEachPage( FALSE )
+{
+}
+
+SwLineNumberInfo::SwLineNumberInfo(const SwLineNumberInfo &rCpy ) :
+    aType( rCpy.GetNumType() ),
+    aDivider( rCpy.GetDivider() ),
+    nPosFromLeft( rCpy.GetPosFromLeft() ),
+    nCountBy( rCpy.GetCountBy() ),
+    nDividerCountBy( rCpy.GetDividerCountBy() ),
+    ePos( rCpy.GetPos() ),
+    bPaintLineNumbers( rCpy.IsPaintLineNumbers() ),
+    bCountBlankLines( rCpy.IsCountBlankLines() ),
+    bCountInFlys( rCpy.IsCountInFlys() ),
+    bRestartEachPage( rCpy.IsRestartEachPage() )
+{
+    if ( rCpy.GetRegisteredIn() )
+        ((SwModify*)rCpy.GetRegisteredIn())->Add( this );
+}
+
+SwLineNumberInfo& SwLineNumberInfo::operator=(const SwLineNumberInfo &rCpy)
+{
+    if ( rCpy.GetRegisteredIn() )
+        ((SwModify*)rCpy.GetRegisteredIn())->Add( this );
+    else if ( GetRegisteredIn() )
+        pRegisteredIn->Remove( this );
+
+    aType = rCpy.GetNumType();
+    aDivider = rCpy.GetDivider();
+    nPosFromLeft = rCpy.GetPosFromLeft();
+    nCountBy = rCpy.GetCountBy();
+    nDividerCountBy = rCpy.GetDividerCountBy();
+    ePos = rCpy.GetPos();
+    bPaintLineNumbers = rCpy.IsPaintLineNumbers();
+    bCountBlankLines = rCpy.IsCountBlankLines();
+    bCountInFlys = rCpy.IsCountInFlys();
+    bRestartEachPage = rCpy.IsRestartEachPage();
+
+    return *this;
+}
+
+BOOL SwLineNumberInfo::operator==( const SwLineNumberInfo& rInf ) const
+{
+    return  GetRegisteredIn() == rInf.GetRegisteredIn() &&
+            aType.eType == rInf.GetNumType().eType &&
+            aDivider == rInf.GetDivider() &&
+            nPosFromLeft == rInf.GetPosFromLeft() &&
+            nCountBy == rInf.GetCountBy() &&
+            nDividerCountBy == rInf.GetDividerCountBy() &&
+            ePos == rInf.GetPos() &&
+            bPaintLineNumbers == rInf.IsPaintLineNumbers() &&
+            bCountBlankLines == rInf.IsCountBlankLines() &&
+            bCountInFlys == rInf.IsCountInFlys() &&
+            bRestartEachPage == rInf.IsRestartEachPage();
+}
+
+
+SwCharFmt* SwLineNumberInfo::GetCharFmt(SwDoc &rDoc) const
+{
+    if ( !GetRegisteredIn() )
+    {
+        SwCharFmt* pFmt = rDoc.GetCharFmtFromPool( RES_POOLCHR_LINENUM );
+        pFmt->Add( (SwClient*)this );
+    }
+    return (SwCharFmt*)GetRegisteredIn();
+}
+
+void SwLineNumberInfo::SetCharFmt( SwCharFmt *pChFmt )
+{
+    ASSERT( pChFmt, "SetCharFmt, 0 is not a valid pointer" );
+    pChFmt->Add( this );
+}
+
+void SwLineNumberInfo::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew )
+{
+    SwClient::Modify( pOld, pNew );
+    SwDoc *pDoc = ((SwCharFmt*)GetRegisteredIn())->GetDoc();
+    SwRootFrm* pRoot = pDoc->GetRootFrm();
+    if( pRoot && pRoot->GetCurrShell() )
+    {
+        pRoot->StartAllAction();
+        pRoot->GetCurrShell()->AddPaintRect( pRoot->Frm() );
+        pRoot->EndAllAction();
+    }
+}
+
diff --git a/sw/source/core/doc/makefile.mk b/sw/source/core/doc/makefile.mk
new file mode 100644
index 000000000000..7129e91f7ca0
--- /dev/null
+++ b/sw/source/core/doc/makefile.mk
@@ -0,0 +1,176 @@
+#*************************************************************************
+#
+#   $RCSfile: makefile.mk,v $
+#
+#   $Revision: 1.1.1.1 $
+#
+#   last change: $Author: hr $ $Date: 2000-09-19 00:08:16 $
+#
+#   The Contents of this file are made available subject to the terms of
+#   either of the following licenses
+#
+#          - GNU Lesser General Public License Version 2.1
+#          - Sun Industry Standards Source License Version 1.1
+#
+#   Sun Microsystems Inc., October, 2000
+#
+#   GNU Lesser General Public License Version 2.1
+#   =============================================
+#   Copyright 2000 by Sun Microsystems, Inc.
+#   901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+#   This library is free software; you can redistribute it and/or
+#   modify it under the terms of the GNU Lesser General Public
+#   License version 2.1, as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   Lesser General Public License for more details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+#   License along with this library; if not, write to the Free Software
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+#   MA  02111-1307  USA
+#
+#
+#   Sun Industry Standards Source License Version 1.1
+#   =================================================
+#   The contents of this file are subject to the Sun Industry Standards
+#   Source License Version 1.1 (the "License"); You may not use this file
+#   except in compliance with the License. You may obtain a copy of the
+#   License at http://www.openoffice.org/license.html.
+#
+#   Software provided under this License is provided on an "AS IS" basis,
+#   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+#   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+#   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+#   See the License for the specific provisions governing your rights and
+#   obligations concerning the Software.
+#
+#   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+#   Copyright: 2000 by Sun Microsystems, Inc.
+#
+#   All Rights Reserved.
+#
+#   Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sw
+TARGET=doc
+
+AUTOSEG=true
+
+PROJECTPCH=core_pch
+PDBTARGET=core_pch
+PROJECTPCHSOURCE=..$/core_1st$/core_pch
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE :	$(PRJ)$/inc$/swpre.mk
+.INCLUDE :	settings.mk
+.INCLUDE :	$(PRJ)$/inc$/sw.mk
+
+.IF "$(GUI)$(COM)" == "WINMSC"
+LIBFLAGS=/NOI /NOE /PAGE:512
+.ENDIF
+
+
+
+# --- Files --------------------------------------------------------
+
+CXXFILES = \
+        acmplwrd.cxx \
+        doc.cxx \
+        docbasic.cxx \
+        docbm.cxx \
+        docchart.cxx \
+        doccomp.cxx \
+        doccorr.cxx \
+        docdde.cxx \
+        docdesc.cxx \
+        docdraw.cxx \
+        docedt.cxx \
+        docfld.cxx \
+        docfly.cxx \
+        docfmt.cxx \
+        docftn.cxx \
+        docglbl.cxx \
+        docglos.cxx \
+        doclay.cxx \
+        docnew.cxx \
+        docnum.cxx \
+        docredln.cxx \
+        docsort.cxx \
+        docstat.cxx \
+        doctxm.cxx \
+        extinput.cxx \
+        fmtcol.cxx \
+        ftnidx.cxx \
+        gctable.cxx \
+        lineinfo.cxx \
+        notxtfrm.cxx \
+        number.cxx \
+        poolfmt.cxx \
+        sortopt.cxx \
+        swserv.cxx \
+        swtable.cxx \
+        tblafmt.cxx \
+        tblcpy.cxx \
+        tblrwcl.cxx \
+        visiturl.cxx \
+        htmltbl.cxx
+
+
+SLOFILES =	\
+        $(SLO)$/acmplwrd.obj \
+        $(SLO)$/doc.obj \
+        $(SLO)$/docbasic.obj \
+        $(SLO)$/docbm.obj \
+        $(SLO)$/docchart.obj \
+        $(SLO)$/doccomp.obj \
+        $(SLO)$/doccorr.obj \
+        $(SLO)$/docdde.obj \
+        $(SLO)$/docdesc.obj \
+        $(SLO)$/docdraw.obj \
+        $(SLO)$/docedt.obj \
+        $(SLO)$/docfld.obj \
+        $(SLO)$/docfly.obj \
+        $(SLO)$/docfmt.obj \
+        $(SLO)$/docftn.obj \
+        $(SLO)$/doclay.obj \
+        $(SLO)$/docglbl.obj \
+        $(SLO)$/docglos.obj \
+        $(SLO)$/docnew.obj \
+        $(SLO)$/docnum.obj \
+        $(SLO)$/docredln.obj \
+        $(SLO)$/docsort.obj \
+        $(SLO)$/docstat.obj \
+        $(SLO)$/doctxm.obj \
+        $(SLO)$/extinput.obj \
+        $(SLO)$/fmtcol.obj \
+        $(SLO)$/ftnidx.obj \
+        $(SLO)$/gctable.obj \
+        $(SLO)$/lineinfo.obj \
+        $(SLO)$/notxtfrm.obj \
+        $(SLO)$/number.obj \
+        $(SLO)$/poolfmt.obj \
+        $(SLO)$/sortopt.obj \
+        $(SLO)$/swserv.obj \
+        $(SLO)$/swtable.obj \
+        $(SLO)$/tblafmt.obj \
+        $(SLO)$/tblcpy.obj \
+        $(SLO)$/tblrwcl.obj \
+        $(SLO)$/visiturl.obj \
+        $(SLO)$/htmltbl.obj
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE :	target.mk
+
diff --git a/sw/source/core/doc/notxtfrm.cxx b/sw/source/core/doc/notxtfrm.cxx
new file mode 100644
index 000000000000..9f6603822719
--- /dev/null
+++ b/sw/source/core/doc/notxtfrm.cxx
@@ -0,0 +1,1691 @@
+/*************************************************************************
+ *
+ *  $RCSfile: notxtfrm.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:16 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _URLOBJ_HXX //autogen
+#include 
+#endif
+#ifndef _SV_PRINT_HXX
+#include 
+#endif
+#ifndef _SV_VIRDEV_HXX //autogen
+#include 
+#endif
+#ifndef _SV_POLY_HXX
+#include 
+#endif
+
+#ifndef _GOODIES_IMAPOBJ_HXX
+#include 
+#endif
+#ifndef _IMAP_HXX //autogen
+#include 
+#endif
+#ifndef SVTOOLS_URIHELPER_HXX
+#include 
+#endif
+#ifndef _IPOBJ_HXX //autogen
+#include 
+#endif
+#ifndef _IPENV_HXX //autogen
+#include 
+#endif
+#ifndef _SOERR_HXX //autogen
+#include 
+#endif
+#ifndef _SFX_PROGRESS_HXX //autogen
+#include 
+#endif
+#ifndef _SFXDOCFILE_HXX //autogen
+#include 
+#endif
+#ifndef _SFX_PRINTER_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_UDLNITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_COLRITEM_HXX //autogen
+#include 
+#endif
+#ifndef _XOUTBMP_HXX //autogen
+#include 
+#endif
+
+#ifndef _FMTURL_HXX
+#include 
+#endif
+#ifndef _FMTSRND_HXX
+#include 
+#endif
+#ifndef _FRMFMT_HXX
+#include 
+#endif
+#ifndef _SWRECT_HXX
+#include 
+#endif
+#ifndef _FESH_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _FLYFRM_HXX
+#include 
+#endif
+#ifndef _FRMTOOL_HXX
+#include 
+#endif
+#ifndef _VIEWOPT_HXX
+#include 
+#endif
+#ifndef _VIEWIMP_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _HINTS_HXX
+#include 
+#endif
+#ifndef _ROOTFRM_HXX
+#include 
+#endif
+#ifndef _DFLYOBJ_HXX
+#include 
+#endif
+#ifndef _PAGEFRM_HXX
+#include 
+#endif
+#ifndef _NOTXTFRM_HXX
+#include 
+#endif
+#ifndef _GRFATR_HXX
+#include 
+#endif
+#ifndef _CHARATR_HXX
+#include 
+#endif
+#ifndef _FMTORNT_HXX
+#include 
+#endif
+#ifndef _NDNOTXT_HXX
+#include 
+#endif
+#ifndef _NDGRF_HXX
+#include 
+#endif
+#ifndef _NDOLE_HXX
+#include 
+#endif
+#ifndef _SWREGION_HXX
+#include 
+#endif
+#ifndef _POOLFMT_HXX
+#include 
+#endif
+#ifndef _FRMSH_HXX
+#include 
+#endif
+
+#ifndef _MDIEXP_HXX
+#include 
+#endif
+#ifndef _SWWAIT_HXX
+#include 
+#endif
+#ifndef _COMCORE_HRC
+#include 
+#endif
+
+#define DEFTEXTSIZE  12
+
+//Zum asynchronen (erstmaligem) anfordern von Grafiken
+class SwRequestGraphic : public SwClient
+{
+    Timer aTimer;
+    ViewShell* pSh;
+public:
+    SwRequestGraphic( ViewShell& rVSh, SwGrfNode& rNd );
+    virtual void Modify( SfxPoolItem *pOld, SfxPoolItem *pNew );
+    DECL_STATIC_LINK( SwRequestGraphic, RequestGraphic, void *);
+};
+
+
+extern void ClrContourCache( const SdrObject *pObj ); // TxtFly.Cxx
+
+
+inline BOOL GetRealURL( const SwGrfNode& rNd, String& rTxt )
+{
+    BOOL bRet = rNd.GetFileFilterNms( &rTxt, 0 );
+    if( bRet )
+        rTxt = URIHelper::removePassword( rTxt, INetURLObject::WAS_ENCODED,
+                                           INetURLObject::DECODE_WITH_CHARSET );
+    return bRet;
+}
+
+SwRequestGraphic::SwRequestGraphic( ViewShell& rVSh, SwGrfNode& rNd )
+    : SwClient( &rNd ), pSh( &rVSh )
+{
+    aTimer.SetTimeout( 1 );
+    aTimer.SetTimeoutHdl( STATIC_LINK( this, SwRequestGraphic, RequestGraphic ) );
+    aTimer.Start();
+}
+
+
+void SwRequestGraphic::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew )
+{
+    if( pOld && RES_OBJECTDYING == pOld->Which() &&
+        ((SwPtrMsgPoolItem *)pOld)->pObject == pRegisteredIn )
+    {
+        pRegisteredIn->Remove( this );
+        aTimer.Stop();
+        delete this;
+    }
+}
+
+
+IMPL_STATIC_LINK( SwRequestGraphic, RequestGraphic, void*, EMPTYARG )
+{
+    if ( pThis->GetRegisteredIn() && GRAPHIC_DEFAULT ==
+        ((SwGrfNode*)pThis->GetRegisteredIn())->GetGrf().GetType() )
+    {
+        SwGrfNode* pGrfNd = (SwGrfNode*)pThis->GetRegisteredIn();
+        ViewShell* pVSh, *pTmpSh;
+        pGrfNd->GetDoc()->GetEditShell( &pVSh );
+        if( pVSh )
+        {
+            pTmpSh = pVSh;
+            // existiert die Shell noch?
+            do {
+                if( pThis->pSh == pTmpSh )
+                {
+                    CurrShell aTmp( pTmpSh );
+                    pGrfNd->SetTransferPriority( SFX_TFPRIO_VISIBLE_HIGHRES_GRAPHIC );
+                    pGrfNd->SwapIn();
+                }
+            } while( pVSh != ( pTmpSh = (ViewShell*)pTmpSh->GetNext()) );
+        }
+    }
+    delete pThis;
+    return 0;
+}
+
+
+void lcl_PaintReplacement( const SwRect &rRect, const String &rText,
+                           const ViewShell &rSh, const SwNoTxtFrm *pFrm,
+                           FASTBOOL bDefect )
+{
+    static Font *pFont = 0;
+    if ( !pFont )
+    {
+        pFont = new Font();
+        pFont->SetWeight( WEIGHT_BOLD );
+        pFont->SetStyleName( aEmptyStr );
+        pFont->SetName( String::CreateFromAscii(
+                            RTL_CONSTASCII_STRINGPARAM( "Helvetica" )));
+        pFont->SetFamily( FAMILY_SWISS );
+        pFont->SetTransparent( TRUE );
+    }
+
+    Color aCol( COL_RED );
+    FontUnderline eUnderline = UNDERLINE_NONE;
+    const SwFmtURL &rURL = pFrm->FindFlyFrm()->GetFmt()->GetURL();
+    if( rURL.GetURL().Len() || rURL.GetMap() )
+    {
+        FASTBOOL bVisited = FALSE;
+        if ( rURL.GetMap() )
+        {
+            ImageMap *pMap = (ImageMap*)rURL.GetMap();
+            for( USHORT i = 0; i < pMap->GetIMapObjectCount(); i++ )
+            {
+                IMapObject *pObj = pMap->GetIMapObject( i );
+                if( rSh.GetDoc()->IsVisitedURL( pObj->GetURL() ) )
+                {
+                    bVisited = TRUE;
+                    break;
+                }
+            }
+        }
+        else if ( rURL.GetURL().Len() )
+            bVisited = rSh.GetDoc()->IsVisitedURL( rURL.GetURL() );
+
+        SwFmt *pFmt = rSh.GetDoc()->GetFmtFromPool( bVisited ?
+                RES_POOLCHR_INET_VISIT : RES_POOLCHR_INET_NORMAL );
+        aCol = pFmt->GetColor().GetValue();
+        eUnderline = pFmt->GetUnderline().GetUnderline();
+    }
+
+    pFont->SetUnderline( eUnderline );
+    pFont->SetColor( aCol );
+
+    const Bitmap& rBmp = SwNoTxtFrm::GetBitmap( bDefect );
+    ((Graphic*)0)->Draw( rSh.GetOut(), rText, *pFont, rBmp,
+                         rRect.Pos(), rRect.SSize() );
+}
+
+const Bitmap& SwNoTxtFrm::GetBitmap( BOOL bErrorBmp )
+{
+    Bitmap** ppRet;
+    USHORT nResId;
+    if( bErrorBmp )
+    {
+        ppRet = &pErrorBmp;
+        nResId = RID_GRAPHIC_ERRORBMP;
+    }
+    else
+    {
+        ppRet = &pReplaceBmp;
+        nResId = RID_GRAPHIC_REPLACEBMP;
+    }
+
+    if( !*ppRet )
+        *ppRet = new Bitmap( SW_RES( nResId ) );
+    return **ppRet;
+}
+
+/*************************************************************************
+|*
+|*    SwGrfFrm::SwGrfFrm(ViewShell * const,SwGrfNode *)
+|*
+|*    Beschreibung
+|*    Ersterstellung    JP 05.03.91
+|*    Letzte Aenderung  MA 03. Mar. 93
+|*
+*************************************************************************/
+
+
+SwNoTxtFrm::SwNoTxtFrm(SwNoTxtNode * const pNode)
+    : SwCntntFrm(pNode)
+{
+    InitCtor();
+}
+
+// Initialisierung: z.Zt. Eintragen des Frames im Cache
+
+
+void SwNoTxtFrm::InitCtor()
+{
+    nType = FRM_NOTXT;
+    // Das Gewicht der Grafik ist 0, wenn sie noch nicht
+    // gelesen ist, < 0, wenn ein Lesefehler auftrat und
+    // Ersatzdarstellung angewendet werden musste und >0,
+    // wenn sie zur Verfuegung steht.
+    nWeight = 0;
+}
+
+/*************************************************************************
+|*
+|*    SwNoTxtNode::MakeFrm()
+|*
+|*    Beschreibung
+|*    Ersterstellung    JP 05.03.91
+|*    Letzte Aenderung  MA 03. Mar. 93
+|*
+*************************************************************************/
+
+
+SwCntntFrm *SwNoTxtNode::MakeFrm()
+{
+    return new SwNoTxtFrm(this);
+}
+
+/*************************************************************************
+|*
+|*    SwNoTxtFrm::~SwNoTxtFrm()
+|*
+|*    Beschreibung
+|*    Ersterstellung    JP 05.03.91
+|*    Letzte Aenderung  MA 30. Apr. 96
+|*
+*************************************************************************/
+
+SwNoTxtFrm::~SwNoTxtFrm()
+{
+    StopAnimation();
+}
+
+/*************************************************************************
+|*
+|*    void SwNoTxtFrm::Modify( SwHint * pOld, SwHint * pNew )
+|*
+|*    Beschreibung
+|*    Ersterstellung    JP 05.03.91
+|*    Letzte Aenderung  JP 05.03.91
+|*
+*************************************************************************/
+
+void SetOutDev( ViewShell *pSh, OutputDevice *pOut )
+{
+    pSh->pOut = pOut;
+}
+
+
+
+
+void lcl_ClearArea( const SwFrm &rFrm,
+                    OutputDevice &rOut, const SwRect& rPtArea,
+                    const SwRect &rGrfArea, BOOL bIsOLE )
+{
+    SwRegionRects aRegion( rPtArea, 4, 4 );
+    aRegion -= rGrfArea;
+
+    if ( aRegion.Count() )
+    {
+        const SvxBrushItem *pItem; const Color *pCol; SwRect aOrigRect;
+        if ( rFrm.GetBackgroundBrush( pItem, pCol, aOrigRect, FALSE ) )
+            for( USHORT i = 0; i < aRegion.Count(); ++i )
+                ::DrawGraphic( pItem, &rOut, aOrigRect, aRegion[i] );
+        else
+        {
+            rOut.Push( PUSH_FILLCOLOR );
+            rOut.SetFillColor( rFrm.GetShell()->Imp()->GetRetoucheColor());
+            for( USHORT i = 0; i < aRegion.Count(); ++i )
+                rOut.DrawRect( aRegion[i].SVRect() );
+            rOut.Pop();
+        }
+
+        // JP 24.08.96: wann wird dieser Code durchlaufen??
+        //              Dann sollte fuer das OLE-Object noch zu implementieren
+        ASSERT( !bIsOLE, "was ist noch zu Painten??" )
+    }
+/*  else if( bIsOLE )
+    {
+        // JP 24.08.96: Bug 29381 - OLE-Objecte koenne transparent sein.
+        //                          (z.B. Metafile). Es soll aber ein weisser
+        //                          Hintergrund hinter den OLE-Object sein!
+        Pen aOldPen( rOut.GetPen() );
+        Brush aOldBr( rOut.GetFillInBrush() );
+        Color aCol( COL_WHITE );
+        rOut.SetPen( Pen( aCol ));
+        rOut.SetFillInBrush( Brush( aCol ));
+
+        rOut.DrawRect( rPtArea.SVRect() );
+
+        rOut.SetPen( aOldPen );
+        rOut.SetFillInBrush( aOldBr );
+    }
+*/
+}
+
+/*************************************************************************
+|*
+|*    void SwNoTxtFrm::Paint()
+|*
+|*    Beschreibung
+|*    Ersterstellung    JP 05.03.91
+|*    Letzte Aenderung  MA 10. Jan. 97
+|*
+*************************************************************************/
+
+void SwNoTxtFrm::Paint( const SwRect &rRect ) const
+{
+    if ( Frm().IsEmpty() )
+        return;
+
+    const ViewShell* pSh = GetShell();
+    if( !pSh->GetViewOptions()->IsGraphic() )
+    {
+        StopAnimation();
+        if ( pSh->GetWin() )
+        {
+            const SwNoTxtNode* pNd = GetNode()->GetNoTxtNode();
+            String aTxt( pNd->GetAlternateText() );
+            if ( !aTxt.Len() && pNd->IsGrfNode() )
+                GetRealURL( *(SwGrfNode*)pNd, aTxt );
+            if( !aTxt.Len() )
+                aTxt = FindFlyFrm()->GetFmt()->GetName();
+            lcl_PaintReplacement( Frm(), aTxt, *pSh, this, FALSE );
+        }
+        return;
+    }
+
+    if ( pSh->Imp()->IsPaintInScroll() && pSh->GetWin() && rRect != Frm() &&
+         HasAnimation() )
+    {
+        pSh->GetWin()->Invalidate( Frm().SVRect() );
+        return;
+    }
+
+
+    SfxProgress::EnterLock(); //Keine Progress-Reschedules im Paint (SwapIn)
+
+    OutputDevice *pOut = pSh->GetOut();
+    pOut->Push();
+    BOOL bClip = TRUE;
+    PolyPolygon aPoly;
+    if ( (!pOut->GetConnectMetaFile() || pOut->GetOutDevType() == OUTDEV_PRINTER) &&
+         FindFlyFrm()->GetContour( aPoly ) )
+    {
+        pOut->SetClipRegion( aPoly );
+        bClip = FALSE;
+    }
+
+    SwRect aOrigPaint( rRect );
+    if ( HasAnimation() && pSh->GetWin() )
+    {
+        aOrigPaint = Frm(); aOrigPaint += Prt().Pos();
+    }
+
+    SwRect aGrfArea( Frm() );
+    SwRect aPaintArea( aGrfArea );
+    aPaintArea._Intersection( aOrigPaint );
+
+    // Crop und Mirror berechnen.
+    SwRect aPaintGrfArea( aGrfArea );
+    ((SwNoTxtFrm*)this)->GetGrfArea( aPaintGrfArea, &aGrfArea );
+
+    SwRect aNormal( aPaintGrfArea );
+    aNormal.Justify(); //Normalisiertes Rechteck fuer die Vergleiche
+
+    BOOL bIsOleNode = GetNode()->IsOLENode();
+    if( aPaintArea.IsOver( aNormal ) )
+    {
+        // berechne die 4 zu loeschenden Rechtecke
+        if( pSh->GetWin() )
+        {
+            const SwGrfNode* pGrfNd = GetNode()->GetGrfNode();
+            SwRect aTmpRect;
+            if( !pGrfNd || !(
+                pGrfNd->IsTransparent() ||
+                pGrfNd->IsAnimated() ||
+                0 != pGrfNd->GetFrmFmt()->GetTransparencyGrf().GetValue() ))
+                aTmpRect = aNormal;
+
+            ::lcl_ClearArea( *this, *pSh->GetOut(), aPaintArea, aTmpRect,
+                            bIsOleNode );
+        }
+
+        // in der Schnittmenge vom PaintBereich und der Bitmap liegt
+        // der absolut sichtbare Bereich vom Frame
+        aPaintArea._Intersection( aNormal );
+
+        if ( bClip )
+            pOut->IntersectClipRegion( aPaintArea.SVRect() );
+        PaintPicture( pOut, aGrfArea, aPaintGrfArea );
+    }
+    else
+        // wenn nicht sichtbar, loesche einfach den angegebenen Bereich
+        lcl_ClearArea( *this, *pSh->GetOut(), aPaintArea, SwRect(),
+                        bIsOleNode );
+
+    pOut->Pop();
+    SfxProgress::LeaveLock();
+}
+
+
+
+
+/*************************************************************************
+|*
+|*    void lcl_CalcRect( Point & aPt, Size & aDim,
+|*                   USHORT nMirror )
+|*
+|*    Beschreibung      Errechne die Position und die Groesse der Grafik im
+|*                      Frame, entsprechen der aktuellen Grafik-Attribute
+|*
+|*    Parameter         Point&  die Position im Frame  ( auch Return-Wert )
+|*                      Size&   die Groesse der Grafik ( auch Return-Wert )
+|*                      MirrorGrf   akt. Spiegelungs-Attribut
+|*    Ersterstellung    JP 04.03.91
+|*    Letzte Aenderung  JP 31.08.94
+|*
+*************************************************************************/
+
+
+void lcl_CalcRect( Point& rPt, Size& rDim, USHORT nMirror )
+{
+    if( nMirror == RES_MIRROR_GRF_VERT || nMirror == RES_MIRROR_GRF_BOTH )
+    {
+        rPt.X() += rDim.Width() -1;
+        rDim.Width() = -rDim.Width();
+    }
+
+    if( nMirror == RES_MIRROR_GRF_HOR || nMirror == RES_MIRROR_GRF_BOTH )
+    {
+        rPt.Y() += rDim.Height() -1;
+        rDim.Height() = -rDim.Height();
+    }
+}
+
+
+/*************************************************************************
+|*
+|*    void SwNoTxtFrm::GetGrfArea()
+|*
+|*    Beschreibung      Errechne die Position und die Groesse der Bitmap
+|*                      innerhalb des uebergebenem Rechtecks.
+|*
+|*    Ersterstellung    JP 03.09.91
+|*    Letzte Aenderung  MA 11. Oct. 94
+|*
+*************************************************************************/
+
+void SwNoTxtFrm::GetGrfArea( SwRect &rRect, SwRect* pOrigRect,
+                             BOOL bMirror ) const
+{
+    //In rRect wird das sichbare Rechteck der Grafik gesteckt.
+    //In pOrigRect werden Pos+Size der Gesamtgrafik gesteck.
+
+    const SwAttrSet& rAttrSet = GetNode()->GetSwAttrSet();
+    const SwCropGrf& rCrop = rAttrSet.GetCropGrf();
+
+    //Grafik wird vom Node eingelesen falls notwendig. Kann aber schiefgehen.
+    long nLeftCrop, nRightCrop, nTopCrop, nBottomCrop;
+    Size aOrigSz( ((SwNoTxtNode*)GetNode())->GetTwipSize() );
+    if ( !aOrigSz.Width() )
+    {
+        aOrigSz.Width() = Prt().Width();
+        nLeftCrop  = -rCrop.GetLeft();
+        nRightCrop = -rCrop.GetRight();
+    }
+    else
+    {
+        nLeftCrop = Max( aOrigSz.Width() -
+                            (rCrop.GetRight() + rCrop.GetLeft()), long(1) );
+        const double nScale = double(Prt().Width())  / double(nLeftCrop);
+        nLeftCrop  = long(nScale * -rCrop.GetLeft() );
+        nRightCrop = long(nScale * -rCrop.GetRight() );
+    }
+
+    if( !aOrigSz.Height() )
+    {
+        aOrigSz.Height() = Prt().Height();
+        nTopCrop   = -rCrop.GetTop();
+        nBottomCrop= -rCrop.GetBottom();
+    }
+    else
+    {
+        nTopCrop = Max( aOrigSz.Height() - (rCrop.GetTop() + rCrop.GetBottom()), long(1) );
+        const double nScale = double(Prt().Height()) / double(nTopCrop);
+        nTopCrop   = long(nScale * -rCrop.GetTop() );
+        nBottomCrop= long(nScale * -rCrop.GetBottom() );
+    }
+
+    Size  aVisSz( Prt().SSize() );
+    Size  aGrfSz( aVisSz );
+    Point aVisPt( Frm().Pos() + Prt().Pos() );
+    Point aGrfPt( aVisPt );
+
+    //Erst das 'sichtbare' Rect einstellen.
+    if ( nLeftCrop > 0 )
+    {
+        aVisPt.X()  += nLeftCrop;
+        aVisSz.Width() -= nLeftCrop;
+    }
+    if ( nTopCrop > 0 )
+    {
+        aVisPt.Y()   += nTopCrop;
+        aVisSz.Height() -= nTopCrop;
+    }
+    if ( nRightCrop > 0 )
+        aVisSz.Width() -= nRightCrop;
+    if ( nBottomCrop > 0 )
+        aVisSz.Height() -= nBottomCrop;
+
+    rRect.Pos  ( aVisPt );
+    rRect.SSize( aVisSz );
+
+    //Ggf. Die Gesamtgrafik berechnen
+    if ( pOrigRect )
+    {
+        Size aTmpSz( aGrfSz );
+        aGrfPt.X()    += nLeftCrop;
+        aTmpSz.Width() -= nLeftCrop + nRightCrop;
+        aGrfPt.Y()      += nTopCrop;
+        aTmpSz.Height()-= nTopCrop + nBottomCrop;
+
+        pOrigRect->Pos  ( aGrfPt );
+        pOrigRect->SSize( aTmpSz );
+    }
+}
+
+/*************************************************************************
+|*
+|*    Size SwNoTxtFrm::GetSize()
+|*
+|*    Beschreibung      Gebe die Groesse des umgebenen FLys und
+|*                      damit die der Grafik zurueck.
+|*    Ersterstellung    JP 04.03.91
+|*    Letzte Aenderung  JP 31.08.94
+|*
+*************************************************************************/
+
+
+const Size& SwNoTxtFrm::GetSize() const
+{
+    // gebe die Groesse des Frames zurueck
+    const SwFrm *pFly = FindFlyFrm();
+    if( !pFly )
+        pFly = this;
+    return pFly->Prt().SSize();
+}
+
+/*************************************************************************
+|*
+|*    SwNoTxtFrm::MakeAll()
+|*
+|*    Ersterstellung    MA 29. Nov. 96
+|*    Letzte Aenderung  MA 29. Nov. 96
+|*
+*************************************************************************/
+
+
+void SwNoTxtFrm::MakeAll()
+{
+    SwCntntNotify aNotify( this );
+    SwBorderAttrAccess aAccess( SwFrm::GetCache(), this );
+    const SwBorderAttrs &rAttrs = *aAccess.Get();
+
+    while ( !bValidPos || !bValidSize || !bValidPrtArea )
+    {
+        MakePos();
+
+        if ( !bValidSize )
+            Frm().Width( GetUpper()->Prt().Width() );
+
+        MakePrtArea( rAttrs );
+
+        if ( !bValidSize )
+        {   bValidSize = TRUE;
+            Format();
+        }
+    }
+}
+
+/*************************************************************************
+|*
+|*    SwNoTxtFrm::Format()
+|*
+|*    Beschreibung      Errechne die Groesse der Bitmap, wenn noetig
+|*    Ersterstellung    JP 11.03.91
+|*    Letzte Aenderung  MA 13. Mar. 96
+|*
+*************************************************************************/
+
+
+void SwNoTxtFrm::Format( const SwBorderAttrs * )
+{
+    const Size aNewSize( GetSize() );
+
+    // hat sich die Hoehe geaendert?
+    SwTwips nChgHght = (SwTwips)(aNewSize.Height() - Prt().Height());
+    const SzPtr pVar = pVARSIZE;
+    if( nChgHght > 0)
+        Grow( nChgHght, pVar );
+    else if( nChgHght < 0)
+        Shrink( Min(Prt().Height(), -nChgHght), pVar );
+}
+
+/*************************************************************************
+|*
+|*    SwNoTxtFrm::GetCharRect()
+|*
+|*    Beschreibung
+|*    Ersterstellung    SS 29-Apr-1991
+|*    Letzte Aenderung  MA 10. Oct. 94
+|*
+|*************************************************************************/
+
+
+BOOL SwNoTxtFrm::GetCharRect( SwRect &rRect, const SwPosition& rPos,
+                              SwCrsrMoveState *pCMS ) const
+{
+    if ( &rPos.nNode.GetNode() != (SwNode*)GetNode() )
+        return FALSE;
+
+    Calc();
+    SwRect aFrameRect( Frm() );
+    rRect = aFrameRect;
+    ((SwNoTxtFrm*)this)->GetGrfArea( rRect );
+
+    rRect.Justify();
+
+    // liegt die Bitmap ueberhaupt im sichtbaren Berich ?
+    if( !aFrameRect.IsOver( rRect ) )
+    {
+        // wenn nicht dann steht der Cursor auf dem Frame
+        rRect = aFrameRect;
+        rRect.Width( 1 );
+    }
+    else
+        rRect._Intersection( aFrameRect );
+
+    if ( pCMS )
+    {
+        if ( pCMS->bRealHeight )
+        {
+            pCMS->aRealHeight.Y() = rRect.Height();
+            pCMS->aRealHeight.X() = 0;
+        }
+    }
+
+    return TRUE;
+}
+
+
+BOOL SwNoTxtFrm::GetCrsrOfst(SwPosition* pPos, Point& aPoint,
+                            const SwCrsrMoveState* ) const
+{
+    SwCntntNode* pCNd = (SwCntntNode*)GetNode();
+    pPos->nNode = *pCNd;
+    pPos->nContent.Assign( pCNd, 0 );
+    return TRUE;
+}
+
+/*  */
+// Code for the new GraphicObject
+#ifdef USE_GRFOBJECT
+
+#define CLEARCACHE( pNd ) {\
+    (pNd)->GetGrfObj().ReleaseFromCache();\
+    SwFlyFrm* pFly = FindFlyFrm();\
+    if( pFly && pFly->GetFmt()->GetSurround().IsContour() )\
+    {\
+        ClrContourCache( pFly->GetVirtDrawObj() );\
+        pFly->NotifyBackground( FindPageFrm(), Prt(), PREP_FLY_ATTR_CHG );\
+    }\
+}
+
+void SwNoTxtFrm::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew )
+{
+    USHORT nWhich = pNew ? pNew->Which() : pOld ? pOld->Which() : 0;
+
+    if ( RES_GRAPHIC_PIECE_ARRIVED != nWhich &&
+         RES_GRAPHIC_ARRIVED != nWhich &&
+         RES_GRF_REREAD_AND_INCACHE != nWhich )
+        SwCntntFrm::Modify( pOld, pNew );
+
+    FASTBOOL bCompletePaint = TRUE;
+
+    switch( nWhich )
+    {
+    case RES_OBJECTDYING:
+        break;
+
+    case RES_GRF_REREAD_AND_INCACHE:
+        if( ND_GRFNODE == GetNode()->GetNodeType() )
+        {
+            bCompletePaint = FALSE;
+            SwGrfNode* pNd = (SwGrfNode*) GetNode();
+
+            ViewShell *pVSh = 0;
+            pNd->GetDoc()->GetEditShell( &pVSh );
+            if( pVSh )
+            {
+                GraphicAttr aAttr;
+                if( pNd->GetGrfObj().IsCached( pVSh->GetOut(), Point(),
+                            Prt().SSize(), &pNd->GetGraphicAttr( aAttr, this ) ))
+                {
+                    ViewShell *pSh = pVSh;
+                    do {
+                        SET_CURR_SHELL( pSh );
+                        if( pSh->GetWin() )
+                        {
+                            if( pSh->IsPreView() )
+                                ::RepaintPagePreview( pSh, Frm().SVRect() );
+                            else
+                                pSh->GetWin()->Invalidate( Frm().SVRect() );
+                        }
+                    } while( pVSh != (pSh = (ViewShell*)pSh->GetNext() ));
+                }
+                else
+                    pNd->SwapIn();
+            }
+        }
+        break;
+
+    case RES_UPDATE_ATTR:
+    case RES_FMT_CHG:
+        CLEARCACHE( (SwGrfNode*) GetNode() )
+        break;
+
+    case RES_ATTRSET_CHG:
+        {
+            for( USHORT n = RES_GRFATR_BEGIN; n < RES_GRFATR_END; ++n )
+                if( SFX_ITEM_SET == ((SwAttrSetChg*)pOld)->GetChgSet()->
+                                GetItemState( n, FALSE ))
+                {
+                    CLEARCACHE( (SwGrfNode*) GetNode() )
+                    break;
+                }
+            if( RES_GRFATR_END == n )           // not found
+                return ;
+        }
+        break;
+
+    case RES_GRAPHIC_PIECE_ARRIVED:
+    case RES_GRAPHIC_ARRIVED:
+        if ( GetNode()->GetNodeType() == ND_GRFNODE )
+        {
+            bCompletePaint = FALSE;
+            SwGrfNode* pNd = (SwGrfNode*) GetNode();
+
+            CLEARCACHE( pNd )
+
+            SwRect aRect( Frm() );
+
+            ViewShell *pVSh = 0;
+            pNd->GetDoc()->GetEditShell( &pVSh );
+            if( !pVSh )
+                break;
+
+            ViewShell *pSh = pVSh;
+            do {
+                SET_CURR_SHELL( pSh );
+                if( pSh->IsPreView() )
+                {
+                    if( pSh->GetWin() )
+                        ::RepaintPagePreview( pSh, aRect );
+                }
+                else if ( pSh->VisArea().IsOver( aRect ) &&
+                     OUTDEV_WINDOW == pSh->GetOut()->GetOutDevType() )
+                {
+                    const GraphicObject& rGrfObj = pNd->GetGrfObj();
+                    BOOL bSizeUnequal;
+                    if( rGrfObj.IsAnimated() )
+                        pSh->GetWin()->Invalidate( aRect.SVRect() );
+                    else if ( rGrfObj.IsTransparent() ||
+                              (bSizeUnequal = (Frm().SSize() != Prt().SSize())))
+                    {
+                        if ( bSizeUnequal )
+                        {
+                            //Wieder mal die Umrandungen...
+                            aRect.Pos().X() = Max( long(0),
+                                            (long)(aRect.Left() - 20) );
+                            aRect.Pos().Y() = Max( long(0),
+                                            (long)(aRect.Top()  - 20) );
+                            aRect.SSize().Width() += 40;
+                            aRect.SSize().Height() += 40;
+                        }
+                        //virtuelles device erzeugen und einstellen.
+                        OutputDevice *pOld = pSh->GetOut();
+                        VirtualDevice *pVout = new VirtualDevice( *pOld );
+                        MapMode aMapMode( pOld->GetMapMode() );
+                        pVout->SetMapMode( aMapMode );
+                        if( pVout->SetOutputSize( aRect.SSize() ) )
+                        {
+//                          pVout->SetPen( pOld->GetPen() );
+                            pVout->SetLineColor(pOld->GetLineColor());
+//                          pVout->SetFillInBrush( pOld->GetFillInBrush() );
+                            pVout->SetFillColor(pOld->GetFillColor());
+                            Point aOrigin( aRect.Pos() );
+                            aOrigin.X() = -aOrigin.X(); aOrigin.Y() = -aOrigin.Y();
+                            aMapMode.SetOrigin( aOrigin );
+                            pVout->SetMapMode( aMapMode );
+                            ::SetOutDev( pSh, pVout );
+                            pSh->GetLayout()->Paint( aRect );
+                            pOld->DrawOutDev( aRect.Pos(), aRect.SSize(),
+                                              aRect.Pos(), aRect.SSize(), *pVout );
+                            ::SetOutDev( pSh, pOld );
+                        }
+                        else
+                            pSh->Paint( aRect.SVRect() );
+                        delete pVout;
+                    }
+                    else
+                    {
+                        aRect = Prt(); aRect += Frm().Pos();
+                        Paint( aRect );
+                    }
+                }
+
+                pSh = (ViewShell *)pSh->GetNext();
+            } while( pSh != pVSh );
+        }
+        break;
+
+    default:
+        if( !pNew || RES_GRFATR_BEGIN > nWhich || nWhich >= RES_GRFATR_END )
+            return;
+    }
+
+    if( bCompletePaint )
+    {
+        InvalidatePrt();
+        SetCompletePaint();
+    }
+}
+
+// Ausgabe der Grafik. Hier wird entweder eine QuickDraw-Bmp oder
+// eine Grafik vorausgesetzt. Ist nichts davon vorhanden, wird
+// eine Ersatzdarstellung ausgegeben.
+
+void SwNoTxtFrm::PaintPicture( OutputDevice* pOut, const SwRect &rGrfArea,
+                               const SwRect &rPaintGrfArea ) const
+{
+    ViewShell* pShell = GetShell();
+    const FASTBOOL bPrn = pOut == pShell->GetPrt() ||
+                          pOut->GetConnectMetaFile();
+
+    SwNoTxtNode& rNoTNd = *(SwNoTxtNode*)GetNode();
+    SwGrfNode* pGrfNd = rNoTNd.GetGrfNode();
+    SwOLENode* pOLENd = rNoTNd.GetOLENode();
+
+    if( pGrfNd )
+    {
+        FASTBOOL bForceSwap = FALSE, bContinue = TRUE;
+        pGrfNd->SetFrameInPaint( TRUE );
+        GraphicObject& rGrfObj = pGrfNd->GetGrfObj();
+
+        GraphicAttr aGrfAttr;
+        pGrfNd->GetGraphicAttr( aGrfAttr, this );
+
+        if( !bPrn )
+        {
+            if( GRAPHIC_DEFAULT == rGrfObj.GetType() &&
+                pGrfNd->IsLinkedFile() )
+            {
+                Size aTmpSz;
+                SvPseudoObject* pGrfObj = pGrfNd->GetLink()->GetObj();
+                if( !pGrfObj ||
+                    ERRCODE_SO_FALSE == pGrfObj->GetUpToDateStatus() ||
+                    !(aTmpSz = pGrfNd->GetTwipSize()).Width() ||
+                    !aTmpSz.Height() || !pGrfNd->GetAutoFmtLvl() )
+                {
+                    pGrfNd->SetAutoFmtLvl( 1 );
+                    new SwRequestGraphic( *GetShell(), *pGrfNd );//zerstoert sich selbst!
+                }
+                String aTxt( pGrfNd->GetAlternateText() );
+                if ( !aTxt.Len() )
+                    GetRealURL( *pGrfNd, aTxt );
+                ::lcl_PaintReplacement( rGrfArea, aTxt, *pShell, this, FALSE );
+                bContinue = FALSE;
+            }
+            else if( rGrfObj.IsCached( pOut, rGrfArea.Pos(),
+                                    rGrfArea.SSize(), &aGrfAttr ))
+            {
+                rGrfObj.Draw( pOut, rGrfArea.Pos(), rGrfArea.SSize(),
+                                &aGrfAttr );
+                bForceSwap = TRUE;
+                bContinue = FALSE;
+            }
+        }
+
+        if( bContinue )
+        {
+            const FASTBOOL bSwapped = rGrfObj.IsSwappedOut();
+            const FASTBOOL bSwappedIn = pGrfNd->SwapIn( bPrn );
+            if( bSwappedIn && rGrfObj.GetGraphic().IsSupportedGraphic())
+            {
+                const FASTBOOL bAnimate = rGrfObj.IsAnimated() &&
+                                            !pShell->IsPreView();
+                if( bAnimate &&
+                    FindFlyFrm() != ::GetFlyFromMarked( 0, pShell ))
+                {
+                    OutputDevice* pVout;
+                    if( pOut == pShell->GetOut() && SwRootFrm::FlushVout() )
+                        pVout = pOut, pOut = pShell->GetOut();
+                    else if( pShell->GetWin() &&
+                             OUTDEV_VIRDEV == pOut->GetOutDevType() )
+                        pVout = pOut, pOut = pShell->GetWin();
+                    else
+                        pVout = 0;
+
+                    ASSERT( OUTDEV_VIRDEV != pOut->GetOutDevType(),
+                            "pOut sollte kein virtuelles Device sein" );
+                    rGrfObj.StartAnimation( pOut, rGrfArea.Pos(),
+                                        rGrfArea.SSize(), long(this),
+                                        0, GRFMGR_DRAW_STANDARD, pVout );
+                }
+                else
+                    rGrfObj.Draw( pOut, rGrfArea.Pos(), rGrfArea.SSize(),
+                                    &aGrfAttr );
+            }
+            else
+            {
+                USHORT nResId = 0;
+                if( bSwappedIn )
+                {
+                    if( GRAPHIC_NONE == rGrfObj.GetType() )
+                        nResId = STR_COMCORE_READERROR;
+                    else if ( !rGrfObj.GetGraphic().IsSupportedGraphic() )
+                        nResId = STR_COMCORE_CANT_SHOW;
+                }
+                ((SwNoTxtFrm*)this)->nWeight = -1;
+                String aText;
+                if ( !nResId &&
+                    !(aText = pGrfNd->GetAlternateText()).Len() &&
+                     (!GetRealURL( *pGrfNd, aText ) || !aText.Len()))
+                {
+                    nResId = STR_COMCORE_READERROR;
+                }
+                if ( nResId )
+                    aText = SW_RESSTR( nResId );
+
+                ::lcl_PaintReplacement( rGrfArea, aText, *pShell, this, TRUE );
+            }
+
+            //Beim Drucken duerfen wir nicht die Grafiken sammeln...
+            if( bSwapped && bPrn )
+                bForceSwap = TRUE;
+        }
+        pGrfNd->SetFrameInPaint( FALSE );
+        if( bForceSwap )
+            pGrfNd->SwapOut();
+    }
+    else if( pOLENd )
+    {
+        SvInPlaceObjectRef xRef( pOLENd->GetOLEObj().GetOleRef() );
+
+        // Im BrowseModus gibt es nicht unbedingt einen Drucker und
+        // damit kein JobSetup, also legen wir eines an ...
+        JobSetup* pJobSetup = (JobSetup*)pOLENd->GetDoc()->GetJobsetup();
+        FASTBOOL bDummyJobSetup = 0 == pJobSetup;
+        if( bDummyJobSetup )
+            pJobSetup = new JobSetup();
+        xRef->DoDraw( pOut, rGrfArea.Pos(), rGrfArea.SSize(), *pJobSetup );
+        if( bDummyJobSetup )
+            delete pJobSetup;  // ... und raeumen wieder auf.
+
+        //Objecte mit die beim Sichtbarwerden aktiviert werden wollen
+        //werden jetzt Connected (Aktivieren wird vom Sfx erledigt).
+        if( !bPrn && ((SVOBJ_MISCSTATUS_ACTIVATEWHENVISIBLE|
+            SVOBJ_MISCSTATUS_ALWAYSACTIVATE) & xRef->GetMiscStatus()) &&
+            pShell->ISA( SwCrsrShell ))
+        {
+            const SwFlyFrm *pFly = FindFlyFrm();
+            ASSERT( pFly, "OLE not in FlyFrm" );
+            ((SwFEShell*)pShell)->ConnectObj( xRef, pFly->Prt(), pFly->Frm());
+        }
+    }
+}
+
+
+BOOL SwNoTxtFrm::IsTransparent() const
+{
+    const ViewShell* pSh = GetShell();
+    if ( !pSh || !pSh->GetViewOptions()->IsGraphic() )
+        return TRUE;
+
+    const SwGrfNode *pNd;
+    if( 0 != (pNd = GetNode()->GetGrfNode()) )
+        return pNd->IsTransparent();
+
+    //#29381# OLE sind immer Transparent.
+    return TRUE;
+}
+
+
+void SwNoTxtFrm::StopAnimation( OutputDevice* pOut ) const
+{
+    //animierte Grafiken anhalten
+    SwGrfNode* pGrfNd = (SwGrfNode*)GetNode()->GetGrfNode();
+    if( pGrfNd && pGrfNd->IsAnimated() )
+        pGrfNd->GetGrfObj().StopAnimation( pOut, long(this) );
+}
+
+
+BOOL SwNoTxtFrm::HasAnimation() const
+{
+    const SwGrfNode* pGrfNd = GetNode()->GetGrfNode();
+    return pGrfNd && pGrfNd->IsAnimated();
+}
+
+/*  */
+#else
+// USE_GRFOBJECT
+
+#ifndef _GRFCACHE_HXX
+#include 
+#endif
+
+#define CLEARCACHE( pNd ) {\
+    ( pNd )->ClearQBmpCache();\
+    SwFlyFrm* pFly = FindFlyFrm();\
+    if( pFly && pFly->GetFmt()->GetSurround().IsContour() )\
+    {\
+        ClrContourCache( pFly->GetVirtDrawObj() );\
+        pFly->NotifyBackground( FindPageFrm(), Prt(), PREP_FLY_ATTR_CHG );\
+    }\
+}
+
+void SwNoTxtFrm::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew )
+{
+    USHORT nWhich = pNew ? pNew->Which() : pOld ? pOld->Which() : 0;
+
+    if ( RES_GRAPHIC_PIECE_ARRIVED != nWhich &&
+         RES_GRAPHIC_ARRIVED != nWhich &&
+         RES_GRF_REREAD_AND_INCACHE != nWhich )
+        SwCntntFrm::Modify( pOld, pNew );
+
+    FASTBOOL bCompletePaint = TRUE;
+
+    switch( nWhich )
+    {
+    case RES_OBJECTDYING:
+        break;
+
+    case RES_UPDATE_ATTR:
+    case RES_FMT_CHG:
+        CLEARCACHE( (SwGrfNode*) GetNode() )
+        break;
+
+    case RES_GRF_REREAD_AND_INCACHE:
+        if ( GetNode()->GetNodeType() == ND_GRFNODE )
+        {
+            bCompletePaint = FALSE;
+            SwGrfNode* pNd = (SwGrfNode*) GetNode();
+
+            ViewShell *pVSh = 0;
+            pNd->GetDoc()->GetEditShell( &pVSh );
+            if( pVSh )
+            {
+                SwGraphicAccess aGrfAcc( *pNd, Prt().SSize(),
+                                        pVSh->GetOut()->GetMapMode() );
+                if( aGrfAcc.IsAvailable() )
+                {
+                    ViewShell *pSh = pVSh;
+                    do {
+                        SET_CURR_SHELL( pSh );
+                        if( pSh->GetWin() )
+                        {
+                            if( pSh->IsPreView() )
+                                ::RepaintPagePreview( pSh, Frm().SVRect() );
+                            else
+                                pSh->GetWin()->Invalidate( Frm().SVRect() );
+                        }
+                    } while( pVSh != (pSh = (ViewShell*)pSh->GetNext() ));
+                }
+                else
+                    pNd->SwapIn();
+            }
+        }
+        break;
+
+    case RES_ATTRSET_CHG:
+        if ( SFX_ITEM_SET == ((SwAttrSetChg*)pOld)->GetChgSet()->GetItemState( RES_GRFATR_MIRRORGRF, FALSE )||
+             SFX_ITEM_SET == ((SwAttrSetChg*)pOld)->GetChgSet()->GetItemState( RES_GRFATR_CROPGRF, FALSE ))
+        {
+            CLEARCACHE( (SwGrfNode*) GetNode() )
+            break;
+        }
+        else
+            return;
+
+    case RES_GRAPHIC_PIECE_ARRIVED:
+    case RES_GRAPHIC_ARRIVED:
+        if ( GetNode()->GetNodeType() == ND_GRFNODE )
+        {
+            bCompletePaint = FALSE;
+            SwGrfNode* pNd = (SwGrfNode*) GetNode();
+
+            CLEARCACHE( pNd )
+
+            SwRect aRect( Frm() );
+
+            ViewShell *pVSh = 0;
+            pNd->GetDoc()->GetEditShell( &pVSh );
+            if( !pVSh )
+                break;
+
+            ViewShell *pSh = pVSh;
+            do {
+                SET_CURR_SHELL( pSh );
+                if( pSh->IsPreView() )
+                {
+                    if( pSh->GetWin() )
+                        ::RepaintPagePreview( pSh, aRect );
+                }
+                else if ( pSh->VisArea().IsOver( aRect ) &&
+                     OUTDEV_WINDOW == pSh->GetOut()->GetOutDevType() )
+                {
+                    Graphic& rGrf = (Graphic&) pNd->GetGrf();
+                    BOOL bSizeUnequal;
+                    if ( rGrf.IsAnimated() )
+                        pSh->GetWin()->Invalidate( aRect.SVRect() );
+                    else if ( rGrf.IsTransparent() ||
+                              (bSizeUnequal = (Frm().SSize() != Prt().SSize())))
+                    {
+                        if ( bSizeUnequal )
+                        {
+                            //Wieder mal die Umrandungen...
+                            aRect.Pos().X() = Max( long(0),
+                                            (long)(aRect.Left() - 20) );
+                            aRect.Pos().Y() = Max( long(0),
+                                            (long)(aRect.Top()  - 20) );
+                            aRect.SSize().Width() += 40;
+                            aRect.SSize().Height() += 40;
+                        }
+                        //virtuelles device erzeugen und einstellen.
+                        OutputDevice *pOld = pSh->GetOut();
+                        VirtualDevice *pVout = new VirtualDevice( *pOld );
+                        MapMode aMapMode( pOld->GetMapMode() );
+                        pVout->SetMapMode( aMapMode );
+                        if( pVout->SetOutputSize( aRect.SSize() ) )
+                        {
+//                          pVout->SetPen( pOld->GetPen() );
+//                          pVout->SetFillInBrush( pOld->GetFillInBrush() );
+                            pVout->SetLineColor(pOld->GetLineColor());
+                            pVout->SetFillColor(pOld->GetFillColor());
+                            Point aOrigin( aRect.Pos() );
+                            aOrigin.X() = -aOrigin.X(); aOrigin.Y() = -aOrigin.Y();
+                            aMapMode.SetOrigin( aOrigin );
+                            pVout->SetMapMode( aMapMode );
+                            ::SetOutDev( pSh, pVout );
+                            pSh->GetLayout()->Paint( aRect );
+                            pOld->DrawOutDev( aRect.Pos(), aRect.SSize(),
+                                              aRect.Pos(), aRect.SSize(), *pVout );
+                            ::SetOutDev( pSh, pOld );
+                        }
+                        else
+                            pSh->Paint( aRect.SVRect() );
+                        delete pVout;
+                    }
+                    else
+                    {
+                        aRect = Prt(); aRect += Frm().Pos();
+                        Paint( aRect );
+                    }
+                }
+
+                pSh = (ViewShell *)pSh->GetNext();
+            } while( pSh != pVSh );
+        }
+        break;
+
+    default:
+        if( !pNew || RES_GRFATR_BEGIN > nWhich || nWhich >= RES_GRFATR_END )
+            return;
+    }
+
+    if( bCompletePaint )
+    {
+        InvalidatePrt();
+        SetCompletePaint();
+    }
+}
+
+#pragma optimize("t",off)
+
+
+void SwNoTxtFrm::PaintCntnt( OutputDevice* pOut, const SwRect& rGrfArea,
+                             const SwRect &rPaintGrfArea ) const
+{
+    switch( GetNode()->GetNodeType() )
+    {
+    case ND_GRFNODE:
+        {
+            const ViewShell *pSh = GetShell();
+            FASTBOOL bForceSwap = FALSE;
+
+            SwGrfNode* pNd = (SwGrfNode*) GetNode()->GetGrfNode();
+            Graphic & rGrf = (Graphic&) pNd->GetGrf();
+
+            pNd->SetFrameInPaint( TRUE );
+
+            BOOL bPrn = pOut == (Printer*)pSh->GetPrt() ||
+                        pOut->GetConnectMetaFile();
+            BOOL bPaintPicture = TRUE;
+
+            if( !bPrn && !rGrf.IsAnimated() && pNd->IsGrafikArrived() )
+            {
+                Size aSize( rPaintGrfArea.SSize() );
+                // Muss die QuickDraw-Bitmap neu aufgebaut werden?
+                MapMode aCurMapMode( pOut->GetMapMode() );  // Hallo MAC
+                SwGraphicAccess* pGrfAcc = new SwGraphicAccess( *pNd, aSize,
+                                                                aCurMapMode );
+                SwGraphicCacheObj* pGrfObj = 0;
+
+                if( GRAPHIC_DEFAULT == rGrf.GetType() )
+                {
+                    if( pGrfAcc->IsAvailable() )
+                        pGrfObj = pGrfAcc->Get();       // alle klar
+                    else if( pNd->IsLinkedFile() )
+                    {
+                        SvPseudoObject* pLnkObj = pNd->GetLink()->GetObj();
+                        if( pLnkObj && ERRCODE_SO_FALSE != pLnkObj->GetUpToDateStatus() )
+                        {
+                            Size aSz( pNd->GetTwipSize() );
+                            if( aSz.Width() && aSz.Height() )
+                                rGrf.Clear();
+                        }
+                    }
+                }
+
+                if( GRAPHIC_DEFAULT != rGrf.GetType() )
+                {
+                    pNd->SetAutoFmtLvl( 0 );
+                    if( !pGrfAcc->IsAvailable() )
+                        pGrfAcc->DeleteNoQBmps();
+                    pGrfObj = pGrfAcc->Get();
+
+                    if( !pGrfObj->IsQBmp( aSize, aCurMapMode ) )
+                    {
+                        delete pGrfAcc, pGrfAcc = 0;
+                        pGrfObj = 0;
+                        short nRes = pNd->SwapIn();
+
+                        //Kann sein, dass es erst jetzt eine DefaultGraphic
+                        //geworden ist;
+                        //JP 18.10.96: oder eine Animierte reingeswappt wurde!
+                        if ( GRAPHIC_DEFAULT != rGrf.GetType() &&
+                             !rGrf.IsAnimated() )
+                        {
+                            if( nRes < 0 )
+                            {
+                                // Durch das Swappen muss ein kompletter Repaint
+                                // ausgeloest werden, wir koennen hier also abbrechen
+                                if( nWeight < 0 )
+                                {
+                                    SwRect aTmp( rPaintGrfArea );
+                                    aTmp.Justify();
+                                    pSh->GetWin()->Invalidate( aTmp.SVRect() );
+                                    pNd->SetFrameInPaint( FALSE );
+                                    break;
+                                }
+                                else
+                                    nRes = 1;
+                            }
+
+                            if( nRes )
+                                ((SwNoTxtFrm*)this)->nWeight = 1;
+
+                            pGrfAcc = new SwGraphicAccess( *pNd, aSize, aCurMapMode );
+                            pGrfObj = pGrfAcc->Get();
+                            pGrfObj->ClearQBmp();
+
+                            if ( nRes && rGrf.IsSupportedGraphic() )
+                            {
+                                Size aSizePixel( pOut->LogicToPixel( aSize ) );
+                                ULONG nArea = (ULONG)Abs(aSizePixel.Width()) *
+                                              (ULONG)Abs(aSizePixel.Height());
+                                ULONG nColors = pOut->GetColorCount();
+                                if( nColors <= 16 )
+                                    nArea /= 2;
+                                else
+                                if( nColors > 65536 )
+                                    nArea *= 4;
+                                nArea *= 2;
+
+                                if( rGrf.GetType() != GRAPHIC_BITMAP ||
+                                    (nArea < 2000000 && rGrf.GetType() == GRAPHIC_BITMAP) )
+                                {
+                                    SwWait *pWait = pNd->GetDoc()->IsBrowseMode()
+                                        ? 0
+                                        : new SwWait( *pNd->GetDoc()->GetDocShell(), FALSE );
+
+                                    // QuickDraw-Bitmap erzeugen
+                                    Point aPos( rPaintGrfArea.Pos() );
+                                    aPos -= rGrfArea.Pos();
+
+                                    pGrfObj->SetQBmp( XOutBitmap::CreateQuickDrawBitmapEx(
+                                                      rGrf, *pOut, aCurMapMode,
+                                                      rGrfArea.SSize(), aPos, aSize ),
+                                                      aSize, aCurMapMode );
+                                    delete pWait;
+                                    // Hinterher kann die Grafik wieder wech
+                                    // (wir haben ja die Bitmap)
+                                    bForceSwap = 0 != pGrfObj->GetQuickBmp();
+                                }
+                            }
+                        }
+                    }
+                }
+
+                if( pGrfObj && pGrfObj->GetQuickBmp() )
+                {
+                    bPaintPicture = FALSE;
+                    //QuickDrawBitmap hat die richtige Size!
+                    SwRect aTmp( rPaintGrfArea );
+                    aTmp.Justify();
+                    XOutBitmap::DrawQuickDrawBitmapEx( pOut, aTmp.Pos(),
+                                            aTmp.SSize(), *pGrfObj->GetQuickBmp() );
+                }
+                delete pGrfAcc;
+            }
+
+            if( bPaintPicture )
+            {
+                if ( !bPrn )
+                    SwGraphicCacheObj::GetCache()->StartTimer();
+                PaintPicture( pOut, rGrfArea, rPaintGrfArea );
+            }
+
+            pNd->SetFrameInPaint( FALSE );
+
+            // Erst hier rausswappen, damit der User schon was zu
+            // bewundern hat!
+            if( bForceSwap )
+                pNd->SwapOut();
+            break;
+        }
+    case ND_OLENODE:
+        PaintPicture( pOut, rGrfArea, rPaintGrfArea );
+        break;
+    }
+}
+
+#pragma optimize("",on)
+
+// Ausgabe der Grafik. Hier wird entweder eine QuickDraw-Bmp oder
+// eine Grafik vorausgesetzt. Ist nichts davon vorhanden, wird
+// eine Ersatzdarstellung ausgegeben.
+
+void SwNoTxtFrm::PaintPicture( OutputDevice* pOut, const SwRect &rGrfArea,
+                               const SwRect &rPaintGrfArea ) const
+{
+    const ViewShell* pShell = GetShell();
+    const FASTBOOL bPrn = pOut == (Printer*)pShell->GetPrt() ||
+                          pOut->GetConnectMetaFile();
+
+    switch( GetNode()->GetNodeType() )
+    {
+    case ND_GRFNODE:
+        {
+            SwGrfNode* pNd = (SwGrfNode*) GetNode();
+            Graphic& rGrf = (Graphic&) pNd->GetGrf();
+            if( !bPrn && GRAPHIC_DEFAULT == rGrf.GetType() &&
+                pNd->IsLinkedFile() )
+            {
+                Size aTmpSz;
+                SvPseudoObject* pGrfObj = pNd->GetLink()->GetObj();
+                if( !pGrfObj ||
+                    ERRCODE_SO_FALSE == pGrfObj->GetUpToDateStatus() ||
+                    !(aTmpSz = pNd->GetTwipSize()).Width() ||
+                    !aTmpSz.Height() || !pNd->GetAutoFmtLvl() )
+                {
+                    pNd->SetAutoFmtLvl( 1 );
+                    new SwRequestGraphic( *GetShell(), *pNd );//zerstoert sich selbst!
+                }
+                String aTxt( pNd->GetAlternateText() );
+                if ( !aTxt.Len() )
+                    GetRealURL( *pNd, aTxt );
+                ::lcl_PaintReplacement( rGrfArea, aTxt, *pShell, this, FALSE );
+                break;
+            }
+
+            const FASTBOOL bSwapped = rGrf.IsSwapOut();
+            const FASTBOOL bSwappedIn = pNd->SwapIn( bPrn );
+            if( bSwappedIn && rGrf.IsSupportedGraphic() )
+            {
+                const FASTBOOL bAnimate = rGrf.IsAnimated() && !pShell->IsPreView();
+                if( bAnimate && FindFlyFrm() != ::GetFlyFromMarked(0,GetShell()))
+                {
+                    OutputDevice* pVout;
+                    if( pOut == pShell->GetOut() && SwRootFrm::FlushVout() )
+                        pVout = pOut, pOut = pShell->GetOut();
+                    else if( pShell->GetWin() &&
+                             OUTDEV_VIRDEV == pOut->GetOutDevType() )
+                        pVout = pOut, pOut = pShell->GetWin();
+                    else
+                        pVout = 0;
+                    ASSERT( OUTDEV_VIRDEV != pOut->GetOutDevType(),
+                            "pOut sollte kein virtuelles Device sein" );
+                    rGrf.StartAnimation( pOut, rGrfArea.Pos(), rGrfArea.SSize(),
+                                         long(this), pVout );
+                }
+                else
+                    rGrf.Draw( pOut, rGrfArea.Pos(), rGrfArea.SSize() );
+            }
+            else
+            {
+                USHORT nResId = 0;
+                if ( bSwappedIn )
+                {
+                    if ( rGrf.GetType() == GRAPHIC_NONE )
+                        nResId = STR_COMCORE_READERROR;
+                    else if ( !rGrf.IsSupportedGraphic() )
+                        nResId = STR_COMCORE_CANT_SHOW;
+                }
+                ((SwNoTxtFrm*)this)->nWeight = -1;
+                String aText;
+                if ( !nResId &&
+                    !(aText = pNd->GetAlternateText()).Len() &&
+                     (!GetRealURL( *pNd, aText ) || !aText.Len()))
+                {
+                    nResId = STR_COMCORE_READERROR;
+                }
+                if ( nResId )
+                    aText = SW_RESSTR( nResId );
+
+                ::lcl_PaintReplacement( rGrfArea, aText, *pShell, this, TRUE );
+            }
+            //Beim Drucken duerfen wir nicht die Grafiken sammeln...
+            if( bSwapped && bPrn )
+                pNd->SwapOut();
+        }
+        break;
+
+    case ND_OLENODE:
+        {
+            SwOLENode* pNd = (SwOLENode*) GetNode();
+            SvInPlaceObjectRef xRef( pNd->GetOLEObj().GetOleRef() );
+
+            // Im BrowseModus gibt es nicht unbedingt einen Drucker und
+            // damit kein JobSetup, also legen wir eines an ...
+            JobSetup* pJobSetup = (JobSetup*)pNd->GetDoc()->GetJobsetup();
+            BOOL bDummyJobSetup = NULL == pJobSetup;
+            if( bDummyJobSetup )
+                pJobSetup = new JobSetup();
+            xRef->DoDraw(pOut, rGrfArea.Pos(), rGrfArea.SSize(),*pJobSetup);
+            if( bDummyJobSetup )
+                delete pJobSetup;  // ... und raeumen wieder auf.
+
+            //Objecte mit die beim Sichtbarwerden aktiviert werden wollen
+            //werden jetzt Connected (Aktivieren wird vom Sfx erledigt).
+            if( !bPrn &&
+                ((SVOBJ_MISCSTATUS_ACTIVATEWHENVISIBLE|SVOBJ_MISCSTATUS_ALWAYSACTIVATE) &
+                            xRef->GetMiscStatus()) &&
+                pShell->ISA( SwCrsrShell ))
+            {
+                const SwFlyFrm *pFly = FindFlyFrm();
+                ASSERT( pFly, "OLE not in FlyFrm" );
+                ((SwFEShell*)pShell)->ConnectObj( xRef, pFly->Prt(),
+                                                    pFly->Frm());
+            }
+        }
+        break;
+    }
+}
+
+
+BOOL SwNoTxtFrm::IsTransparent() const
+{
+    const ViewShell* pSh = GetShell();
+    if ( !pSh || !pSh->GetViewOptions()->IsGraphic() )
+        return TRUE;
+
+    const SwGrfNode *pNd;
+    if( 0 != (pNd = GetNode()->GetGrfNode()) )
+        return pNd->IsTransparent();
+
+    //#29381# OLE sind immer Transparent.
+    return TRUE;
+}
+
+
+void SwNoTxtFrm::StopAnimation( OutputDevice* pOut ) const
+{
+    //animierte Grafiken anhalten
+    if ( GetNode()->GetNodeType() == ND_GRFNODE )
+    {
+        Graphic& rGrf = (Graphic&)GetNode()->GetGrfNode()->GetGrf();
+        if ( rGrf.IsAnimated() )
+            rGrf.StopAnimation( pOut, long(this) );
+    }
+}
+
+
+BOOL SwNoTxtFrm::HasAnimation() const
+{
+    if ( GetNode()->GetNodeType() == ND_GRFNODE )
+    {
+        Graphic& rGrf = (Graphic&)GetNode()->GetGrfNode()->GetGrf();
+        return rGrf.IsAnimated();
+    }
+    return FALSE;
+}
+
+#endif
+// USE_GRFOBJECT
+
+
+
diff --git a/sw/source/core/doc/number.cxx b/sw/source/core/doc/number.cxx
new file mode 100644
index 000000000000..5e501646e369
--- /dev/null
+++ b/sw/source/core/doc/number.cxx
@@ -0,0 +1,1018 @@
+/*************************************************************************
+ *
+ *  $RCSfile: number.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:16 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#include 
+
+#ifndef _SV_FONT_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BRSHITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_NUMITEM_HXX //autogen
+#include 
+#endif
+#ifndef _FMTORNT_HXX //autogen
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _CHARFMT_HXX
+#include 
+#endif
+#ifndef _PARATR_HXX
+#include 
+#endif
+#ifndef _FRMFMT_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _HINTS_HXX
+#include 
+#endif
+#ifndef _NUMRULE_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _DOCSH_HXX
+#include 
+#endif
+
+
+USHORT SwNumRule::nRefCount = 0;
+SwNumFmt* SwNumRule::aBaseFmts[ RULE_END ][ MAXLEVEL ] = {
+    0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0 };
+
+Font* SwNumRule::pDefBulletFont = 0;
+sal_Char* SwNumRule::pDefOutlineName = "Outline";
+
+USHORT SwNumRule::aDefNumIndents[ MAXLEVEL ] = {
+//cm:   0,5  1,0  1,5  2,0   2,5   3,0   3,5   4,0   4,5   5,0
+        283, 567, 850, 1134, 1417, 1701, 1984, 2268, 2551, 2835
+};
+
+#if defined UNX
+
+#if defined GCC
+extern const sal_Char __FAR_DATA sBulletFntName[];
+const sal_Char __FAR_DATA sBulletFntName[] = "starbats";
+#else
+extern const sal_Char __FAR_DATA sBulletFntName[] = "starbats";
+#endif
+
+#else
+extern const sal_Char __FAR_DATA sBulletFntName[] = "StarBats";
+#endif
+
+
+// Methoden fuer die Klassen aus NUMRULE.HXX
+
+SwNumFmt::SwNumFmt()
+    : SwClient( 0 ),
+    pBulletFont( 0 ),
+    cBullet( cBulletChar ),
+    eNumAdjust( SVX_ADJUST_LEFT ),
+    nLSpace( 0 ),
+    nAbsLSpace( 0 ),
+    nFirstLineOffset( 0 ),
+    nCharTextOffset( 0 ),
+    nStart( 0 ),
+    pGrfBrush( 0 ), pVertOrient( 0 )
+{
+    nInclUpperLevel = MAXLEVEL;
+    bRelLSpace = FALSE;
+}
+
+
+SwNumFmt::SwNumFmt( const SwNumFmt& rNumFmt )
+    : SwClient( rNumFmt.pRegisteredIn ), SwNumType( rNumFmt ),
+    cBullet( rNumFmt.cBullet ),
+    pBulletFont( 0 ),
+    eNumAdjust( rNumFmt.eNumAdjust ),
+    nLSpace( rNumFmt.nLSpace ),
+    nAbsLSpace( rNumFmt.nAbsLSpace ),
+    nFirstLineOffset( rNumFmt.nFirstLineOffset ),
+    nCharTextOffset( rNumFmt.nCharTextOffset ),
+    nStart( rNumFmt.nStart ),
+    aPrefix( rNumFmt.aPrefix ),
+    aPostfix( rNumFmt.aPostfix ),
+    pGrfBrush( 0 ), pVertOrient( 0 )
+{
+    SetBulletFont(rNumFmt.GetBulletFont());
+    nInclUpperLevel = rNumFmt.nInclUpperLevel;
+    bRelLSpace = rNumFmt.bRelLSpace;
+
+    SetGrfBrush( rNumFmt.GetGrfBrush(), &rNumFmt.GetGrfSize(),
+                rNumFmt.GetGrfOrient() );
+}
+
+
+SwNumFmt::~SwNumFmt()
+{
+    delete pBulletFont;
+    delete pGrfBrush;
+    delete pVertOrient;
+}
+
+
+void SwNumFmt::SetBulletFont(const Font* pFont)
+{
+    if( pBulletFont )
+    {
+        if( pFont )
+            *pBulletFont = *pFont;
+        else
+            delete pBulletFont, pBulletFont = 0;
+    }
+    else if( pFont )
+        pBulletFont = new Font( *pFont );
+}
+
+
+void SwNumFmt::SetGrfBrush( const SvxBrushItem* pGrfBr, const Size* pSz,
+                            const SwFmtVertOrient* pVOrient )
+{
+    if( pGrfBr )
+    {
+        if( pGrfBrush )
+        {
+            if( !( *pGrfBrush == *pGrfBr ) )
+            {
+                delete pGrfBrush;
+                pGrfBrush = (SvxBrushItem*)pGrfBr->Clone();
+            }
+        }
+        else
+            pGrfBrush = (SvxBrushItem*)pGrfBr->Clone();
+
+        if( pVertOrient != pVOrient )
+        {
+            if(pVertOrient)
+                delete pVertOrient;
+
+            pVertOrient = pVOrient ? (SwFmtVertOrient*)pVOrient->Clone() : 0;
+        }
+        if( pSz )
+            aGrfSize = *pSz;
+        else
+            aGrfSize.Width() = aGrfSize.Height() = 0;
+
+        pGrfBrush->SetDoneLink( STATIC_LINK( this, SwNumFmt, GraphicArrived) );
+    }
+    else
+    {
+        delete pGrfBrush, pGrfBrush = 0;
+        delete pVertOrient, pVertOrient = 0;
+        aGrfSize.Width() = aGrfSize.Height() = 0;
+    }
+}
+
+
+SwNumFmt& SwNumFmt::operator=( const SwNumFmt& rNumFmt )
+{
+    cBullet = rNumFmt.cBullet;
+    eType = rNumFmt.eType;
+    nInclUpperLevel = rNumFmt.nInclUpperLevel;
+    bRelLSpace = rNumFmt.bRelLSpace;
+
+    eNumAdjust = rNumFmt.eNumAdjust;
+    nLSpace = rNumFmt.nLSpace;
+    nAbsLSpace = rNumFmt.nAbsLSpace;
+    nFirstLineOffset = rNumFmt.nFirstLineOffset;
+    nCharTextOffset = rNumFmt.nCharTextOffset;
+    nStart = rNumFmt.nStart;
+    aPrefix = rNumFmt.aPrefix;
+    aPostfix = rNumFmt.aPostfix;
+
+    SetBulletFont(rNumFmt.GetBulletFont());
+    if( rNumFmt.GetRegisteredIn() )
+        rNumFmt.pRegisteredIn->Add( this );
+    else if( GetRegisteredIn() )
+        pRegisteredIn->Remove( this );
+
+    SetGrfBrush( rNumFmt.GetGrfBrush(), &rNumFmt.GetGrfSize(),
+                rNumFmt.GetGrfOrient() );
+
+    return *this;
+}
+
+
+BOOL SwNumFmt::operator==( const SwNumFmt& rNumFmt ) const
+{
+    BOOL bRet = (
+        eType == rNumFmt.eType &&
+        nInclUpperLevel == rNumFmt.nInclUpperLevel &&
+        bRelLSpace == rNumFmt.bRelLSpace &&
+        eNumAdjust == rNumFmt.eNumAdjust &&
+        nLSpace == rNumFmt.nLSpace &&
+        nAbsLSpace == rNumFmt.nAbsLSpace &&
+        nFirstLineOffset == rNumFmt.nFirstLineOffset &&
+        nCharTextOffset == rNumFmt.nCharTextOffset &&
+        nStart == rNumFmt.nStart &&
+        aPrefix == rNumFmt.aPrefix &&
+        aPostfix == rNumFmt.aPostfix &&
+        pRegisteredIn == rNumFmt.pRegisteredIn);
+
+        if( bRet )
+        {
+            switch( eType )
+            {
+            case SVX_NUM_CHAR_SPECIAL:
+
+                if( cBullet != rNumFmt.cBullet ||
+                    ( pBulletFont
+                        ? ( !rNumFmt.GetBulletFont() ||
+                            *pBulletFont != *rNumFmt.GetBulletFont() )
+                        : 0 != rNumFmt.GetBulletFont() ) )
+                    bRet = FALSE;
+                break;
+
+            case SVX_NUM_BITMAP:
+
+                if( aGrfSize != rNumFmt.aGrfSize ||
+                    ( pGrfBrush
+                        ? ( !rNumFmt.pGrfBrush ||
+                                *pGrfBrush != *rNumFmt.pGrfBrush )
+                        : 0 != rNumFmt.pGrfBrush ) ||
+                    ( pVertOrient
+                        ? ( !rNumFmt.pVertOrient ||
+                                *pVertOrient != *rNumFmt.pVertOrient )
+                        : 0 != rNumFmt.pVertOrient ) )
+                    bRet = FALSE;
+                break;
+            }
+        }
+    return bRet;
+}
+
+
+void SwNumFmt::SetCharFmt( SwCharFmt* pChFmt )
+{
+    if( pChFmt )
+        pChFmt->Add( this );
+    else if( GetRegisteredIn() )
+        pRegisteredIn->Remove( this );
+}
+
+
+void SwNumFmt::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew )
+{
+    // dann suche mal in dem Doc nach dem NumRules-Object, in dem dieses
+    // NumFormat gesetzt ist. Das Format muss es nicht geben!
+    const SwCharFmt* pFmt = 0;
+    switch( pOld ? pOld->Which() : pNew ? pNew->Which() : 0 )
+    {
+    case RES_ATTRSET_CHG:
+    case RES_FMT_CHG:
+        pFmt = GetCharFmt();
+        break;
+    }
+
+    if( pFmt && !pFmt->GetDoc()->IsInDtor() )
+        UpdateNumNodes( (SwDoc*)pFmt->GetDoc() );
+    else
+        SwClient::Modify( pOld, pNew );
+}
+
+
+void SwNumFmt::SetGraphic( const String& rName )
+{
+    if( pGrfBrush && *pGrfBrush->GetGraphicLink() == rName )
+        return ;
+
+    delete pGrfBrush;
+
+    pGrfBrush = new SvxBrushItem( rName, aEmptyStr, GPOS_AREA );
+    pGrfBrush->SetDoneLink( STATIC_LINK( this, SwNumFmt, GraphicArrived) );
+    if( !pVertOrient )
+        pVertOrient = new SwFmtVertOrient( 0, VERT_TOP );
+
+    aGrfSize.Width() = aGrfSize.Height() = 0;
+}
+
+
+IMPL_STATIC_LINK( SwNumFmt, GraphicArrived, void *, EMPTYARG )
+{
+    // ggfs. die GrfSize setzen:
+    if( !pThis->aGrfSize.Width() || !pThis->aGrfSize.Height() )
+    {
+        const Graphic* pGrf = pThis->pGrfBrush->GetGraphic();
+        if( pGrf )
+            pThis->aGrfSize = ::GetGraphicSizeTwip( *pGrf, 0 );
+    }
+
+    if( pThis->GetCharFmt() )
+        pThis->UpdateNumNodes( (SwDoc*)pThis->GetCharFmt()->GetDoc() );
+
+    return 0;
+}
+
+inline void lcl_SetRuleChgd( SwTxtNode& rNd, BYTE nLevel )
+{
+    if( rNd.GetNum() &&
+        (~NO_NUMLEVEL & rNd.GetNum()->GetLevel() ) == nLevel )
+        rNd.NumRuleChgd();
+}
+
+void SwNumFmt::UpdateNumNodes( SwDoc* pDoc )
+{
+    BOOL bDocIsModified = pDoc->IsModified();
+    BOOL bFnd = FALSE;
+    const SwNumRule* pRule;
+    for( USHORT n = pDoc->GetNumRuleTbl().Count(); !bFnd && n; )
+    {
+        pRule = pDoc->GetNumRuleTbl()[ --n ];
+        for( BYTE i = 0; i < MAXLEVEL; ++i )
+            if( pRule->GetNumFmt( i ) == this )
+            {
+                const String& rRuleNm = pRule->GetName();
+
+                SwModify* pMod;
+                const SfxPoolItem* pItem;
+                USHORT k, nMaxItems = pDoc->GetAttrPool().GetItemCount(
+                                                    RES_PARATR_NUMRULE );
+                for( k = 0; k < nMaxItems; ++k )
+                    if( 0 != (pItem = pDoc->GetAttrPool().GetItem(
+                        RES_PARATR_NUMRULE, k ) ) &&
+                        0 != ( pMod = (SwModify*)((SwNumRuleItem*)pItem)->
+                                GetDefinedIn()) &&
+                        ((SwNumRuleItem*)pItem)->GetValue() == rRuleNm )
+                    {
+                        if( pMod->IsA( TYPE( SwFmt )) )
+                        {
+                            SwNumRuleInfo aInfo( rRuleNm );
+                            pMod->GetInfo( aInfo );
+
+                            for( ULONG nFirst = 0, nLast = aInfo.GetList().Count();
+                                nFirst < nLast; ++nFirst )
+                                lcl_SetRuleChgd(
+                                    *aInfo.GetList().GetObject( nFirst ), i );
+                        }
+                        else if( ((SwTxtNode*)pMod)->GetNodes().IsDocNodes() )
+                            lcl_SetRuleChgd( *(SwTxtNode*)pMod, i );
+                    }
+                bFnd = TRUE;
+                break;
+            }
+    }
+
+    if( !bFnd )
+    {
+        pRule = pDoc->GetOutlineNumRule();
+        for( BYTE i = 0; i < MAXLEVEL; ++i )
+            if( pRule->GetNumFmt( i ) == this )
+            {
+                ULONG nStt = pDoc->GetNodes().GetEndOfContent().StartOfSectionIndex();
+                const SwTxtFmtColls& rColls = *pDoc->GetTxtFmtColls();
+                for( USHORT n = 1; n < rColls.Count(); ++n )
+                {
+                    const SwTxtFmtColl* pColl = rColls[ n ];
+                    if( i == pColl->GetOutlineLevel() )
+                    {
+                        SwClientIter aIter( *(SwTxtFmtColl*)pColl );
+                        for( SwTxtNode* pNd = (SwTxtNode*)aIter.First( TYPE( SwTxtNode ));
+                                pNd; pNd = (SwTxtNode*)aIter.Next() )
+                            if( pNd->GetNodes().IsDocNodes() &&
+                                                    nStt < pNd->GetIndex() &&
+                                pNd->GetOutlineNum() && i == (~NO_NUMLEVEL &
+                                pNd->GetOutlineNum()->GetLevel() ) )
+                                    pNd->NumRuleChgd();
+                        break;
+                    }
+                }
+
+                bFnd = TRUE;
+                break;
+            }
+    }
+
+    if( bFnd && !bDocIsModified )
+        pDoc->ResetModified();
+}
+
+// Graphic ggfs. reinswappen
+const Graphic* SwNumFmt::GetGraphic() const
+{
+    const Graphic* pGrf = 0;
+    if( pGrfBrush && GetCharFmt() )
+        pGrf = pGrfBrush->GetGraphic( GetCharFmt()->GetDoc()->GetDocShell() );
+    return pGrf;
+}
+
+
+/*  */
+
+void SwNumType::GetRomanStr( ULONG nNo, String& rStr ) const
+{
+    nNo %= 4000;            // mehr kann nicht dargestellt werden
+//      i, ii, iii, iv, v, vi, vii, vii, viii, ix
+//                          (Dummy),1000,500,100,50,10,5,1
+    const sal_Char *cRomanArr = SVX_NUM_ROMAN_UPPER == eType
+                        ? "MDCLXVI--"   // +2 Dummy-Eintraege !!
+                        : "mdclxvi--";  // +2 Dummy-Eintraege !!
+
+    USHORT nMask = 1000;
+    while( nMask )
+    {
+        BYTE nZahl = BYTE(nNo / nMask);
+        BYTE nDiff = 1;
+        nNo %= nMask;
+
+        if( 5 < nZahl )
+        {
+            if( nZahl < 9 )
+                rStr += *(cRomanArr-1);
+            ++nDiff;
+            nZahl -= 5;
+        }
+        switch( nZahl )
+        {
+        case 3:     { rStr += *cRomanArr; }
+        case 2:     { rStr += *cRomanArr; }
+        case 1:     { rStr += *cRomanArr; }
+                    break;
+
+        case 4:     {
+                        rStr += *cRomanArr;
+                        rStr += *(cRomanArr-nDiff);
+                    }
+                    break;
+        case 5:     { rStr += *(cRomanArr-nDiff); }
+                    break;
+        }
+
+        nMask /= 10;            // zur naechsten Dekade
+        cRomanArr += 2;
+    }
+}
+
+
+void SwNumType::GetCharStr( ULONG nNo, String& rStr ) const
+{
+    ASSERT( nNo, "0 ist eine ungueltige Nummer !!" );
+
+    const ULONG coDiff = 'Z' - 'A' +1;
+    char cAdd = (SVX_NUM_CHARS_UPPER_LETTER == eType ? 'A' : 'a') - 1;
+    ULONG nCalc;
+
+    do {
+        nCalc = nNo % coDiff;
+        if( !nCalc )
+            nCalc = coDiff;
+        rStr.Insert( (sal_Unicode)(cAdd + nCalc ), 0 );
+        nNo -= nCalc;
+        if( nNo )
+            nNo /= coDiff;
+    } while( nNo );
+}
+
+void SwNumType::GetCharStrN( ULONG nNo, String& rStr ) const
+{
+    ASSERT( nNo, "0 ist eine ungueltige Nummer !!" );
+
+    const ULONG coDiff = 'Z' - 'A' +1;
+    sal_Unicode cChar = --nNo % coDiff;
+    if( SVX_NUM_CHARS_UPPER_LETTER_N == eType )
+        cChar += 'A';
+    else
+        cChar += 'a';
+
+    rStr.Fill( (nNo / coDiff) + 1, cChar );
+}
+
+
+String SwNumType::GetNumStr( ULONG nNo ) const
+{
+    String aTmpStr;
+    if( nNo )
+    {
+        switch( eType )
+        {
+        case SVX_NUM_CHARS_UPPER_LETTER:
+        case SVX_NUM_CHARS_LOWER_LETTER:
+            GetCharStr( nNo, aTmpStr );
+            break;
+
+        case SVX_NUM_CHARS_UPPER_LETTER_N:
+        case SVX_NUM_CHARS_LOWER_LETTER_N:
+            GetCharStrN( nNo, aTmpStr );
+            break;
+
+        case SVX_NUM_ROMAN_UPPER:
+        case SVX_NUM_ROMAN_LOWER:
+            GetRomanStr( nNo, aTmpStr );
+            break;
+
+        case SVX_NUM_CHAR_SPECIAL:      //JP 06.12.99: this types dont have
+        case SVX_NUM_BITMAP:            // any number, so return emptystr
+        case SVX_NUM_NUMBER_NONE:       //  Bug: 70527
+            break;
+
+//      case ARABIC:    ist jetzt default
+        default:
+            aTmpStr = String::CreateFromInt32( nNo );
+            break;
+        }
+    }
+    else
+        aTmpStr = '0';
+    return aTmpStr;
+}
+
+/*  */
+
+BOOL SwNodeNum::operator==( const SwNodeNum& rNum ) const
+{
+    return nMyLevel == rNum.nMyLevel &&
+           nSetValue == rNum.nSetValue &&
+           bStartNum == rNum.bStartNum &&
+           ( nMyLevel >= MAXLEVEL ||
+             0 == memcmp( nLevelVal, rNum.nLevelVal,
+                        sizeof( USHORT ) * (nMyLevel+1) ));
+}
+
+SwNumRule::SwNumRule( const String& rNm, SwNumRuleType eType, BOOL bAutoFlg )
+    : eRuleType( eType ),
+    sName( rNm ),
+    bAutoRuleFlag( bAutoFlg ),
+    bInvalidRuleFlag( TRUE ),
+    bContinusNum( FALSE ),
+    bAbsSpaces( FALSE ),
+    nPoolFmtId( USHRT_MAX ),
+    nPoolHelpId( USHRT_MAX ),
+    nPoolHlpFileId( UCHAR_MAX )
+{
+    if( !nRefCount++ )          // zum erstmal, also initialisiern
+    {
+        SwNumFmt* pFmt;
+        // Nummerierung:
+        for( int n = 0; n < MAXLEVEL; ++n )
+        {
+            pFmt = new SwNumFmt;
+            pFmt->SetUpperLevel( 1 );
+//          pFmt->SetRelLSpace( TRUE );
+            pFmt->SetRelLSpace( FALSE );
+            pFmt->SetStartValue( 1 );
+            pFmt->SetLSpace( lNumIndent );
+            pFmt->SetAbsLSpace( SwNumRule::GetNumIndent( n ) );
+            pFmt->SetFirstLineOffset( lNumFirstLineOffset );
+            pFmt->SetPostfix( aDotStr );
+            SwNumRule::aBaseFmts[ NUM_RULE ][ n ] = pFmt;
+        }
+
+        // Gliederung:
+        for( n = 0; n < MAXLEVEL; ++n )
+        {
+            pFmt = new SwNumFmt;
+//JP 18.01.96: heute soll es mal wieder vollstaendig numeriert werden
+//JP 10.03.96: und nun mal wieder nicht
+            pFmt->eType = SVX_NUM_NUMBER_NONE;
+//            pFmt->eType = ARABIC;
+            pFmt->SetStartValue( 1 );
+            SwNumRule::aBaseFmts[ OUTLINE_RULE ][ n ] = pFmt;
+        }
+    }
+    memset( aFmts, 0, sizeof( aFmts ));
+    ASSERT( sName.Len(), "NumRule ohne Namen!" );
+}
+
+SwNumRule::SwNumRule( const SwNumRule& rNumRule )
+    : eRuleType( rNumRule.eRuleType ),
+    sName( rNumRule.sName ),
+    bAutoRuleFlag( rNumRule.bAutoRuleFlag ),
+    bInvalidRuleFlag( TRUE ),
+    bContinusNum( rNumRule.bContinusNum ),
+    bAbsSpaces( rNumRule.bAbsSpaces ),
+    nPoolFmtId( rNumRule.GetPoolFmtId() ),
+    nPoolHelpId( rNumRule.GetPoolHelpId() ),
+    nPoolHlpFileId( rNumRule.GetPoolHlpFileId() )
+{
+    ++nRefCount;
+    memset( aFmts, 0, sizeof( aFmts ));
+    for( USHORT n = 0; n < MAXLEVEL; ++n )
+        if( rNumRule.aFmts[ n ] )
+            Set( n, *rNumRule.aFmts[ n ] );
+}
+
+SwNumRule::~SwNumRule()
+{
+    for( USHORT n = 0; n < MAXLEVEL; ++n )
+        delete aFmts[ n ];
+
+    if( !--nRefCount )          // der letzte macht die Tuer zu
+    {
+            // Nummerierung:
+            SwNumFmt** ppFmts = (SwNumFmt**)SwNumRule::aBaseFmts;
+            for( int n = 0; n < MAXLEVEL; ++n, ++ppFmts )
+                delete *ppFmts, *ppFmts = 0;
+
+            // Gliederung:
+            for( n = 0; n < MAXLEVEL; ++n, ++ppFmts )
+                delete *ppFmts, *ppFmts = 0;
+    }
+}
+
+
+void SwNumRule::_MakeDefBulletFont()
+{
+    pDefBulletFont = new Font( String::CreateFromAscii( sBulletFntName ),
+                                aEmptyStr, Size( 0, 14 ) );
+    pDefBulletFont->SetCharSet( RTL_TEXTENCODING_SYMBOL );
+    pDefBulletFont->SetFamily( FAMILY_DONTKNOW );
+    pDefBulletFont->SetPitch( PITCH_DONTKNOW );
+    pDefBulletFont->SetWeight( WEIGHT_DONTKNOW );
+    pDefBulletFont->SetTransparent( TRUE );
+}
+
+
+void SwNumRule::CheckCharFmts( SwDoc* pDoc )
+{
+    SwCharFmt* pFmt;
+    for( BYTE n = 0; n < MAXLEVEL; ++n )
+        if( aFmts[ n ] && 0 != ( pFmt = aFmts[ n ]->GetCharFmt() ) &&
+            pFmt->GetDoc() != pDoc )
+        {
+            // dann kopieren!
+            SwNumFmt* pNew = new SwNumFmt( *aFmts[ n ] );
+            pNew->SetCharFmt( pDoc->CopyCharFmt( *pFmt ) );
+            delete aFmts[ n ];
+            aFmts[ n ] = pNew;
+        }
+}
+
+    // setzt Num oder NoNum fuer den Level am TextNode UND setzt die
+    // richtige Attributierung
+
+BOOL SwNumRule::IsRuleLSpace( SwTxtNode& rNd ) const
+{
+    const SfxPoolItem* pItem;
+    BYTE nLvl;
+    const SwAttrSet* pASet = rNd.GetpSwAttrSet();
+    BOOL bRet = rNd.GetNum() && pASet && SFX_ITEM_SET == pASet->GetItemState(
+                RES_LR_SPACE, FALSE, &pItem ) && ( nLvl = (~NO_NUMLEVEL &
+                rNd.GetNum()->GetLevel() )) < MAXLEVEL &&
+                Get( nLvl ).GetAbsLSpace() == ((SvxLRSpaceItem*)pItem)->GetTxtLeft();
+
+    return bRet;
+}
+
+SwNumRule& SwNumRule::operator=( const SwNumRule& rNumRule )
+{
+    if( this != &rNumRule )
+    {
+        for( USHORT n = 0; n < MAXLEVEL; ++n )
+            Set( n, rNumRule.aFmts[ n ] );
+
+        eRuleType = rNumRule.eRuleType;
+        sName = rNumRule.sName;
+        bAutoRuleFlag = rNumRule.bAutoRuleFlag;
+        bInvalidRuleFlag = TRUE;
+        bContinusNum = rNumRule.bContinusNum;
+        bAbsSpaces = rNumRule.bAbsSpaces;
+        nPoolFmtId = rNumRule.GetPoolFmtId();
+        nPoolHelpId = rNumRule.GetPoolHelpId();
+        nPoolHlpFileId = rNumRule.GetPoolHlpFileId();
+    }
+    return *this;
+}
+
+
+BOOL SwNumRule::operator==( const SwNumRule& rRule ) const
+{
+    BOOL bRet = eRuleType == rRule.eRuleType &&
+                sName == rRule.sName &&
+                bAutoRuleFlag == rRule.bAutoRuleFlag &&
+                bContinusNum == rRule.bContinusNum &&
+                bAbsSpaces == rRule.bAbsSpaces &&
+                nPoolFmtId == rRule.GetPoolFmtId() &&
+                nPoolHelpId == rRule.GetPoolHelpId() &&
+                nPoolHlpFileId == rRule.GetPoolHlpFileId();
+    if( bRet )
+    {
+        for( BYTE n = 0; n < MAXLEVEL; ++n )
+            if( !( rRule.Get( n ) == Get( n ) ))
+            {
+                bRet = FALSE;
+                break;
+            }
+    }
+    return bRet;
+}
+
+
+void SwNumRule::Set( USHORT i, const SwNumFmt& rNumFmt )
+{
+    if( !aFmts[ i ] || !(rNumFmt == Get( i )) )
+    {
+        delete aFmts[ i ];
+        aFmts[ i ] = new SwNumFmt( rNumFmt );
+        bInvalidRuleFlag = TRUE;
+    }
+}
+
+void SwNumRule::Set( USHORT i, const SwNumFmt* pNumFmt )
+{
+    SwNumFmt* pOld = aFmts[ i ];
+    if( !pOld )
+    {
+        if( pNumFmt )
+        {
+            aFmts[ i ] = new SwNumFmt( *pNumFmt );
+            bInvalidRuleFlag = TRUE;
+        }
+    }
+    else if( !pNumFmt )
+        delete pOld, aFmts[ i ] = 0, bInvalidRuleFlag = TRUE;
+    else if( *pOld != *pNumFmt )
+        *pOld = *pNumFmt, bInvalidRuleFlag = TRUE;
+}
+
+
+String SwNumRule::MakeNumString( const SwNodeNum& rNum, BOOL bInclStrings,
+                                BOOL bOnlyArabic ) const
+{
+    String aStr;
+    if( NO_NUM > rNum.GetLevel() && !( NO_NUMLEVEL & rNum.GetLevel() ) )
+    {
+        const SwNumFmt& rMyNFmt = Get( rNum.GetLevel() );
+        if( SVX_NUM_NUMBER_NONE != rMyNFmt.eType )
+        {
+            BYTE i = rNum.GetLevel();
+
+            if( !IsContinusNum() &&
+                rMyNFmt.IsInclUpperLevel() )        // nur der eigene Level ?
+            {
+                BYTE n = rMyNFmt.GetUpperLevel();
+                if( 1 < n )
+                {
+                    if( i+1 >= n )
+                        i -= n - 1;
+                    else
+                        i = 0;
+                }
+            }
+
+            for( ; i <= rNum.GetLevel(); ++i )
+            {
+                const SwNumFmt& rNFmt = Get( i );
+                if( SVX_NUM_NUMBER_NONE == rNFmt.eType )
+                {
+    // Soll aus 1.1.1 --> 2. NoNum --> 1..1 oder 1.1 ??
+    //                 if( i != rNum.nMyLevel )
+    //                    aStr += aDotStr;
+                    continue;
+                }
+
+                if( rNum.GetLevelVal()[ i ] )
+                {
+                    if( bOnlyArabic )
+                        aStr += String::CreateFromInt32( rNum.GetLevelVal()[ i ] );
+                    else
+                        aStr += rNFmt.GetNumStr( rNum.GetLevelVal()[ i ] );
+                }
+                else
+                    aStr += '0';        // alle 0-Level sind eine 0
+                if( i != rNum.GetLevel() && aStr.Len() )
+                    aStr += aDotStr;
+            }
+        }
+
+        //JP 14.12.99: the type dont have any number, so dont append
+        //              the Post-/Prefix String
+        if( bInclStrings && !bOnlyArabic &&
+            SVX_NUM_CHAR_SPECIAL != rMyNFmt.eType &&
+            SVX_NUM_BITMAP != rMyNFmt.eType )
+        {
+            aStr.Insert( rMyNFmt.GetPrefix(), 0 );
+            aStr += rMyNFmt.GetPostfix();
+        }
+    }
+    return aStr;
+}
+
+//  ----- Copy-Methode vom SwNumRule ------
+
+    // eine Art Copy-Constructor, damit die Num-Formate auch an den
+    // richtigen CharFormaten eines Dokumentes haengen !!
+    // (Kopiert die NumFormate und returnt sich selbst)
+
+SwNumRule& SwNumRule::CopyNumRule( SwDoc* pDoc, const SwNumRule& rNumRule )
+{
+    for( USHORT n = 0; n < MAXLEVEL; ++n )
+    {
+        Set( n, rNumRule.aFmts[ n ] );
+        if( aFmts[ n ] && aFmts[ n ]->GetCharFmt() &&
+            USHRT_MAX == pDoc->GetCharFmts()->GetPos( aFmts[n]->GetCharFmt() ))
+            // ueber unterschiedliche Dokumente kopieren, dann
+            // kopiere das entsprechende Char-Format ins neue
+            // Dokument.
+            aFmts[n]->SetCharFmt( pDoc->CopyCharFmt( *aFmts[n]->
+                                        GetCharFmt() ) );
+    }
+    eRuleType = rNumRule.eRuleType;
+    sName = rNumRule.sName;
+    bAutoRuleFlag = rNumRule.bAutoRuleFlag;
+    nPoolFmtId = rNumRule.GetPoolFmtId();
+    nPoolHelpId = rNumRule.GetPoolHelpId();
+    nPoolHlpFileId = rNumRule.GetPoolHlpFileId();
+    bInvalidRuleFlag = TRUE;
+    return *this;
+}
+/* -----------------30.10.98 08:40-------------------
+ *
+ * --------------------------------------------------*/
+SwNumFmt::SwNumFmt(const SvxNumberFormat& rNumFmt, SwDoc* pDoc) :
+    pBulletFont( 0 ),
+    pGrfBrush( 0 ),
+    pVertOrient( 0 )
+{
+    cBullet = rNumFmt.GetBulletChar();
+    eType = rNumFmt.GetNumType();
+    nInclUpperLevel = rNumFmt.GetIncludeUpperLevels();
+    bRelLSpace = FALSE;
+
+    eNumAdjust = rNumFmt.GetNumAdjust();
+    nLSpace = rNumFmt.GetLSpace();
+    nAbsLSpace = rNumFmt.GetAbsLSpace();
+    nFirstLineOffset = rNumFmt.GetFirstLineOffset();
+    nCharTextOffset = rNumFmt.GetCharTextDistance();
+    nStart = rNumFmt.GetStart();
+    aPrefix = rNumFmt.GetPrefix();
+    aPostfix = rNumFmt.GetSuffix();
+
+    SetBulletFont(rNumFmt.GetBulletFont());
+    if( rNumFmt.GetCharFmt().Len() )
+    {
+        SwCharFmt* pCFmt = pDoc->FindCharFmtByName( rNumFmt.GetCharFmt() );
+        if( !pCFmt )
+        {
+            USHORT nId = pDoc->GetPoolId( rNumFmt.GetCharFmt(),
+                                            GET_POOLID_CHRFMT );
+            pCFmt = nId != USHRT_MAX
+                        ? pDoc->GetCharFmtFromPool( nId )
+                        : pDoc->MakeCharFmt( rNumFmt.GetCharFmt(), 0 );
+        }
+        pCFmt->Add( this );
+    }
+    else if( GetRegisteredIn() )
+        pRegisteredIn->Remove( this );
+
+    SwVertOrient eOrient = (SwVertOrient)(USHORT) rNumFmt.GetVertOrient();
+    SwFmtVertOrient aOrient(0, eOrient);
+    Size aTmpSize(rNumFmt.GetGraphicSize());
+    SetGrfBrush( rNumFmt.GetBrush(), &aTmpSize,
+                &aOrient );
+
+}
+/* -----------------30.10.98 12:36-------------------
+ *
+ * --------------------------------------------------*/
+SvxNumberFormat SwNumFmt::MakeSvxFormat() const
+{
+    SvxNumberFormat aRet(eType);
+    aRet.SetNumAdjust(eNumAdjust);
+    aRet.SetIncludeUpperLevels(nInclUpperLevel);
+    aRet.SetStart(nStart);
+    aRet.SetBulletChar(cBullet);
+    aRet.SetFirstLineOffset(nFirstLineOffset);
+    aRet.SetAbsLSpace(nAbsLSpace);
+    aRet.SetLSpace(nLSpace);
+    aRet.SetPrefix(aPrefix);
+    aRet.SetSuffix(aPostfix);
+    if( GetCharFmt() )
+        aRet.SetCharFmt( GetCharFmt()->GetName() );
+    aRet.SetCharTextDistance(nCharTextOffset);
+
+    SvxFrameVertOrient eOrient = SVX_VERT_NONE;
+    if(pVertOrient)
+        eOrient = (SvxFrameVertOrient)(USHORT)pVertOrient->GetVertOrient();
+    aRet.SetGraphicBrush( pGrfBrush, &aGrfSize, &eOrient);
+
+    aRet.SetBulletFont(pBulletFont);
+    return aRet;
+}
+
+/* -----------------30.10.98 08:33-------------------
+ *
+ * --------------------------------------------------*/
+void SwNumRule::SetSvxRule(const SvxNumRule& rNumRule, SwDoc* pDoc)
+{
+    for( USHORT n = 0; n < MAXLEVEL; ++n )
+    {
+        const SvxNumberFormat* pSvxFmt = rNumRule.Get(n);
+        delete aFmts[n];
+        aFmts[n] = pSvxFmt ? new SwNumFmt(*pSvxFmt, pDoc) : 0;
+    }
+
+//  eRuleType = rNumRule.eRuleType;
+//  sName = rNumRule.sName;
+//  bAutoRuleFlag = rNumRule.bAutoRuleFlag;
+    bInvalidRuleFlag = TRUE;
+    bContinusNum = rNumRule.IsContinuousNumbering();
+//!!!   bAbsSpaces = rNumRule.IsAbsSpaces();
+}
+/* -----------------30.10.98 08:33-------------------
+ *
+ * --------------------------------------------------*/
+SvxNumRule SwNumRule::MakeSvxNumRule() const
+{
+    SvxNumRule aRule(NUM_CONTINUOUS|NUM_CHAR_TEXT_DISTANCE|NUM_CHAR_STYLE|
+                        NUM_ENABLE_LINKED_BMP|NUM_ENABLE_EMBEDDED_BMP,
+                        MAXLEVEL,
+                        eRuleType ==
+                            NUM_RULE ?
+                                SVX_RULETYPE_NUMBERING :
+                                    SVX_RULETYPE_OUTLINE_NUMBERING );
+    aRule.SetContinuousNumbering(bContinusNum);
+//!!!   aRule.SetAbsSpaces( bAbsSpaces );
+    for( USHORT n = 0; n < MAXLEVEL; ++n )
+    {
+        const SwNumFmt rNumFmt = Get(n);
+        SvxNumberFormat aSvxFormat = rNumFmt.MakeSvxFormat();
+        aRule.SetLevel(n, aSvxFormat, aFmts[n] != 0);
+    }
+    return aRule;
+}
+
+
+
diff --git a/sw/source/core/doc/poolfmt.cxx b/sw/source/core/doc/poolfmt.cxx
new file mode 100644
index 000000000000..fd2db4294f68
--- /dev/null
+++ b/sw/source/core/doc/poolfmt.cxx
@@ -0,0 +1,2767 @@
+/*************************************************************************
+ *
+ *  $RCSfile: poolfmt.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:16 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#define ITEMID_BOXINFO      SID_ATTR_BORDER_INNER
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+
+#ifndef _SYSTEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _SVX_PAPERINF_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_WGHTITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_FONTITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_FHGTITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_TSTPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_ULSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_ADJITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_POSTITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_KEEPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_OPAQITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BOXITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_CMAPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_UDLNITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_COLRITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_PROTITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_PAPERINF_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_ESCPITEM_HXX
+#include 
+#endif
+
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _FMTORNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTSRND_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFSIZE_HXX //autogen
+#include 
+#endif
+#ifndef _POOLFMT_HXX
+#include 
+#endif
+#ifndef _PARATR_HXX
+#include 
+#endif
+#ifndef _PAGEDESC_HXX
+#include 
+#endif
+#ifndef _HINTS_HXX
+#include 
+#endif
+#ifndef _FRMTOOL_HXX
+#include 
+#endif
+#ifndef _CHARFMT_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _FMTCOL_HXX
+#include 
+#endif
+#ifndef _NUMRULE_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef SW_FMTLINE_HXX
+#include 
+#endif
+
+#ifndef _POOLFMT_HRC
+#include 
+#endif
+
+const USHORT PT_3   =  3 * 20;      //  3 pt
+const USHORT PT_6   =  6 * 20;      //  6 pt
+const USHORT PT_7   =  7 * 20;      //  6 pt
+const USHORT PT_8   =  8 * 20;      //  8 pt
+const USHORT PT_9   =  9 * 20;      //  9 pt
+const USHORT PT_10  = 10 * 20;      // 10 pt
+const USHORT PT_11  = 11 * 20;      // 11 pt
+const USHORT PT_12  = 12 * 20;      // 12 pt
+const USHORT PT_14  = 14 * 20;      // 14 pt
+const USHORT PT_16  = 16 * 20;      // 16 pt
+const USHORT PT_18  = 18 * 20;      // 18 pt
+const USHORT PT_22  = 22 * 20;      // 22 pt
+const USHORT PT_24  = 24 * 20;      // 22 pt
+
+#define CM_1  0         // 1 centimeter     or 1/2 inch
+#define CM_05 1         // 0.5 centimeter   or 1/4 inch
+#define CM_01 2         // 0.1 centimeter   or 1/20 inch
+
+inline USHORT GetMetricVal( int n )
+{
+#ifdef USE_MEASUREMENT
+    USHORT nVal = MEASURE_METRIC == Application::GetAppInternational().
+                                        GetMeasurementSystem()
+                    ? 567       // 1 cm
+                    : 770;      // 1/2 Inch
+#else
+    USHORT nVal = 567;      // 1 cm
+#endif
+
+    if( CM_01 == n )
+        nVal /= 10;
+    else if( CM_05 == n )
+        nVal /= 2;
+    return nVal;
+}
+
+//const USHORT HTML_PARSPACE = ((CM_05 * 7) / 10);
+#define HTML_PARSPACE   GetMetricVal( CM_05 )
+
+static const sal_Char __FAR_DATA sKomma[] = ", ";
+
+static const USHORT aHeadlineSizes[ 2 * MAXLEVEL ] = {
+//  PT_16, PT_14, PT_14, PT_12, PT_12,          // normal
+//JP 10.12.96: jetzt soll alles prozentual sein:
+    115, 100, 100, 85, 85,
+    75,   75,  75, 75, 75,  // normal
+//  PT_22, PT_16, PT_12, PT_11, PT_9            // HTML-Mode
+    PT_24, PT_18, PT_14, PT_12, PT_10,
+    PT_7, PT_7, PT_7, PT_7, PT_7            // HTML-Mode
+};
+
+// Array fuer alle Pool-Vorlagen-Name:
+SvStringsDtor   *SwDoc::pTextNmArray = 0,
+                *SwDoc::pListsNmArray = 0,
+                *SwDoc::pExtraNmArray = 0,
+                *SwDoc::pRegisterNmArray = 0,
+                *SwDoc::pDocNmArray = 0,
+                *SwDoc::pHTMLNmArray = 0,
+                *SwDoc::pFrmFmtNmArray = 0,
+                *SwDoc::pChrFmtNmArray = 0,
+                *SwDoc::pHTMLChrFmtNmArray = 0,
+                *SwDoc::pPageDescNmArray = 0,
+                *SwDoc::pNumRuleNmArray = 0;
+
+
+
+
+long lcl_GetRightMargin( SwDoc& rDoc )
+{
+    // sorge dafuer, dass die Druckereinstellungen in die Standard-
+    // Seitenvorlage uebernommen wurden.
+    long nLeft, nRight, nWidth;
+    const SfxPrinter* pPrt = rDoc.GetPrt( !rDoc.IsInReading() );
+    if( !pPrt )
+    {
+        SvxPaper ePaper;
+// JP 26.05.99: so gibts einen GPF -> warum???
+//      if( MEASURE_METRIC == Application::GetAppInternational().
+//                                  GetMeasurementSystem() )
+        International aInter;
+        if( MEASURE_METRIC == aInter.GetMeasurementSystem() )
+        {
+            ePaper = SVX_PAPER_A4;
+            nLeft = nRight = 1134;  //2 Zentimeter
+        }
+        else
+        {
+            ePaper = SVX_PAPER_LEGAL;
+            nLeft = nRight = 1800;  // 1,25 Inch
+        }
+
+        nWidth = SvxPaperInfo::GetPaperSize( ePaper ).Width();
+    }
+    else
+    {
+        const SwFrmFmt& rPgDscFmt = rDoc.GetPageDesc( 0 ).GetMaster();
+        const SvxLRSpaceItem& rLR = rPgDscFmt.GetLRSpace();
+        nLeft = rLR.GetLeft();
+        nRight = rLR.GetRight();
+        nWidth = rPgDscFmt.GetFrmSize().GetWidth();
+    }
+    return nWidth - nLeft - nRight;
+}
+
+void lcl_SetHeadline( SwDoc* pDoc, SwTxtFmtColl* pColl,
+                        SfxItemSet& rSet,
+                        USHORT nOutLvlBits, BYTE nLevel, BOOL bItalic )
+{
+    rSet.Put( SvxWeightItem( WEIGHT_BOLD ) );
+    if( pDoc->IsHTMLMode() )
+        rSet.Put( SvxFontHeightItem( aHeadlineSizes[ MAXLEVEL + nLevel ] ));
+    else
+        rSet.Put( SvxFontHeightItem( PT_14, aHeadlineSizes[ nLevel ] ));
+
+    if( bItalic && !pDoc->IsHTMLMode() )
+        rSet.Put( SvxPostureItem( ITALIC_NORMAL ) );
+
+    if( pDoc->IsHTMLMode() )
+    {
+        rSet.Put( SvxFontItem( FAMILY_ROMAN, String::CreateFromAscii(
+#if defined(OW) || defined (MTF) || defined(UNX)
+                            RTL_CONSTASCII_STRINGPARAM("times")
+#elif defined(WNT) || defined(WIN) || defined (PM20)
+                            RTL_CONSTASCII_STRINGPARAM("Times New Roman")
+#elif defined(MAC)
+                            RTL_CONSTASCII_STRINGPARAM("Times")
+#else
+#error Defaultfont fuer diese Plattform?
+#endif
+                            ), aEmptyStr, PITCH_VARIABLE,
+/*?? GetSystemCharSet() ->*/    ::gsl_getSystemTextEncoding() ));   // Font
+    }
+
+    if( pColl )
+    {
+        if( !( nOutLvlBits & ( 1 << nLevel )) )
+        {
+            pColl->SetOutlineLevel( nLevel );
+            if( !pDoc->IsHTMLMode() )
+            {
+                const SwNumFmt& rNFmt = pDoc->GetOutlineNumRule()->Get( nLevel );
+                if( rNFmt.GetAbsLSpace() || rNFmt.GetFirstLineOffset() )
+                {
+                    SvxLRSpaceItem aLR( (SvxLRSpaceItem&)pColl->GetAttr( RES_LR_SPACE ) );
+                    aLR.SetTxtFirstLineOfstValue( rNFmt.GetFirstLineOffset() );
+                    aLR.SetTxtLeft( rNFmt.GetAbsLSpace() );
+                    pColl->SetAttr( aLR );
+                }
+            }
+        }
+        pColl->SetNextTxtFmtColl( *pDoc->GetTxtCollFromPool(
+                                        RES_POOLCOLL_TEXT ));
+    }
+}
+
+
+
+void lcl_SetRegister( SwDoc* pDoc, SfxItemSet& rSet, USHORT nFact,
+                        BOOL bHeader, BOOL bTab )
+{
+    SvxLRSpaceItem aLR;
+    USHORT nLeft = nFact ? GetMetricVal( CM_05 ) * nFact : 0;
+    aLR.SetTxtLeft( nLeft );
+
+    rSet.Put( aLR );
+    if( bHeader )
+    {
+        rSet.Put( SvxWeightItem( WEIGHT_BOLD ) );
+        rSet.Put( SvxFontHeightItem( PT_16 ) );
+    }
+    if( bTab )
+    {
+        long nRightMargin = lcl_GetRightMargin( *pDoc );
+        SvxTabStopItem aTStops( 0, 0 );
+        aTStops.Insert( SvxTabStop( nRightMargin - nLeft,
+                                    SVX_TAB_ADJUST_RIGHT,
+                                    cDfltDecimalChar, '.' ));
+        rSet.Put( aTStops );
+    }
+}
+
+
+
+void lcl_SetNumBul( SwDoc* pDoc, SwTxtFmtColl* pColl,
+                        SfxItemSet& rSet,
+                        USHORT nNxt, SwTwips nEZ, SwTwips nLeft,
+                        SwTwips nUpper, SwTwips nLower )
+{
+
+    SvxLRSpaceItem aLR; SvxULSpaceItem aUL;
+    aLR.SetTxtFirstLineOfst( USHORT(nEZ) ); aLR.SetTxtLeft( USHORT(nLeft) );
+    aUL.SetUpper( USHORT(nUpper) ); aUL.SetLower( USHORT(nLower) );
+    rSet.Put( aLR );
+    rSet.Put( aUL );
+
+    if( !pColl )
+        pColl->SetNextTxtFmtColl( *pDoc->GetTxtCollFromPool( nNxt ));
+}
+
+
+
+    // Gebe die "Auto-Collection" mit der Id zurueck. Existiert
+    // sie noch nicht, dann erzeuge sie
+    // Ist der String-Pointer definiert, dann erfrage nur die
+    // Beschreibung der Attribute, !! es legt keine Vorlage an !!
+
+SwTxtFmtColl* SwDoc::GetTxtCollFromPool( USHORT nId, String* pDesc,
+    SfxItemPresentation ePres, SfxMapUnit eCoreMetric, SfxMapUnit ePresMetric )
+{
+    ASSERT(
+        (RES_POOLCOLL_TEXT_BEGIN <= nId && nId < RES_POOLCOLL_TEXT_END) ||
+        (RES_POOLCOLL_LISTS_BEGIN <= nId && nId < RES_POOLCOLL_LISTS_END) ||
+        (RES_POOLCOLL_EXTRA_BEGIN <= nId && nId < RES_POOLCOLL_EXTRA_END) ||
+        (RES_POOLCOLL_REGISTER_BEGIN <= nId && nId < RES_POOLCOLL_REGISTER_END) ||
+        (RES_POOLCOLL_DOC_BEGIN <= nId && nId < RES_POOLCOLL_DOC_END) ||
+        (RES_POOLCOLL_HTML_BEGIN <= nId && nId < RES_POOLCOLL_HTML_END),
+            "Falsche AutoFormat-Id" );
+
+    SwTxtFmtColl* pNewColl;
+    USHORT nOutLvlBits = 0;
+    for( USHORT n = 0; n < pTxtFmtCollTbl->Count(); ++n )
+    {
+        if( nId == ( pNewColl = (*pTxtFmtCollTbl)[ n ] )->GetPoolFmtId() )
+        {
+            if( pDesc )
+                pNewColl->GetPresentation( ePres, eCoreMetric,
+                                           ePresMetric, *pDesc );
+            return pNewColl;
+        }
+        if( !pDesc && pNewColl->GetOutlineLevel() < MAXLEVEL )
+            nOutLvlBits |= ( 1 << pNewColl->GetOutlineLevel() );
+    }
+
+    // bis hierher nicht gefunden -> neu anlegen
+    USHORT nResId = 0;
+    if( RES_POOLCOLL_TEXT_BEGIN <= nId && nId < RES_POOLCOLL_TEXT_END )
+        nResId = RC_POOLCOLL_TEXT_BEGIN - RES_POOLCOLL_TEXT_BEGIN;
+    else if (RES_POOLCOLL_LISTS_BEGIN <= nId && nId < RES_POOLCOLL_LISTS_END)
+        nResId = RC_POOLCOLL_LISTS_BEGIN - RES_POOLCOLL_LISTS_BEGIN;
+    else if (RES_POOLCOLL_EXTRA_BEGIN <= nId && nId < RES_POOLCOLL_EXTRA_END)
+        nResId = RC_POOLCOLL_EXTRA_BEGIN - RES_POOLCOLL_EXTRA_BEGIN;
+    else if (RES_POOLCOLL_REGISTER_BEGIN <= nId && nId < RES_POOLCOLL_REGISTER_END)
+        nResId = RC_POOLCOLL_REGISTER_BEGIN - RES_POOLCOLL_REGISTER_BEGIN;
+    else if (RES_POOLCOLL_DOC_BEGIN <= nId && nId < RES_POOLCOLL_DOC_END)
+        nResId = RC_POOLCOLL_DOC_BEGIN - RES_POOLCOLL_DOC_BEGIN;
+    else if (RES_POOLCOLL_HTML_BEGIN <= nId && nId < RES_POOLCOLL_HTML_END)
+        nResId = RC_POOLCOLL_HTML_BEGIN - RES_POOLCOLL_HTML_BEGIN;
+
+    ASSERT( nResId, "Ungueltige Pool-ID" );
+    if( !nResId )
+        return GetTxtCollFromPool( RES_POOLCOLL_STANDARD, pDesc, ePres,
+                                    eCoreMetric, ePresMetric );
+
+    ResId aResId( nResId + nId, pSwResMgr );
+    String aNm( aResId );
+
+    // ein Set fuer alle zusetzenden Attribute
+    SwAttrSet aSet( GetAttrPool(), aTxtFmtCollSetRange );
+    USHORT nParent = GetPoolParent( nId );
+    if( pDesc )
+    {
+        pNewColl = 0;
+        if( nParent )
+            *pDesc = SW_RESSTR( nResId + nParent );
+        else
+            *pDesc = aEmptyStr;
+    }
+    else
+    {
+
+//FEATURE::CONDCOLL
+        if(::IsConditionalByPoolId( nId ))
+            pNewColl = new SwConditionTxtFmtColl( GetAttrPool(), aNm, !nParent
+                                                ? pDfltTxtFmtColl
+                                                : GetTxtCollFromPool( nParent ));
+        else
+//FEATURE::CONDCOLL
+        pNewColl = new SwTxtFmtColl( GetAttrPool(), aNm, !nParent
+                                            ? pDfltTxtFmtColl
+                                            : GetTxtCollFromPool( nParent ));
+        pNewColl->SetPoolFmtId( nId );
+        pTxtFmtCollTbl->Insert( pNewColl, pTxtFmtCollTbl->Count() );
+    }
+
+    switch( nId )
+    {
+    // allgemeine Inhaltsformen
+    case RES_POOLCOLL_STANDARD:
+        break;
+
+    case RES_POOLCOLL_TEXT:                 // Textkoerper
+        {
+            SvxULSpaceItem aUL( 0, PT_6 );
+            if( IsHTMLMode() ) aUL.SetLower( HTML_PARSPACE );
+            aSet.Put( aUL );
+        }
+        break;
+    case RES_POOLCOLL_TEXT_IDENT:           // Textkoerper Einzug
+        {
+            SvxLRSpaceItem aLR;
+            aLR.SetTxtFirstLineOfst( GetMetricVal( CM_05 ));
+            aSet.Put( aLR );
+        }
+        break;
+    case RES_POOLCOLL_TEXT_NEGIDENT:        // Textkoerper neg. Einzug
+        {
+            SvxLRSpaceItem aLR;
+            aLR.SetTxtFirstLineOfst( -(short)GetMetricVal( CM_05 ));
+            aLR.SetTxtLeft( GetMetricVal( CM_1 ));
+            SvxTabStopItem aTStops;     aTStops.Insert( SvxTabStop( 0 ));
+
+            aSet.Put( aLR );
+            aSet.Put( aTStops );
+        }
+        break;
+    case RES_POOLCOLL_TEXT_MOVE:            // Textkoerper Einrueckung
+        {
+            SvxLRSpaceItem aLR;
+            aLR.SetTxtLeft( GetMetricVal( CM_05 ));
+            aSet.Put( aLR );
+        }
+        break;
+
+    case RES_POOLCOLL_CONFRONTATION:    // Textkoerper Gegenueberstellung
+        {
+            SvxLRSpaceItem aLR;
+            aLR.SetTxtFirstLineOfst( - short( GetMetricVal( CM_1 ) * 4 +
+                                              GetMetricVal( CM_05)) );
+            aLR.SetTxtLeft( GetMetricVal( CM_1 ) * 5 );
+            SvxTabStopItem aTStops;     aTStops.Insert( SvxTabStop( 0 ));
+
+            aSet.Put( aLR );
+            aSet.Put( aTStops );
+        }
+        break;
+    case RES_POOLCOLL_MARGINAL:         // Textkoerper maginalie
+        {
+            SvxLRSpaceItem aLR;
+            aLR.SetTxtLeft( GetMetricVal( CM_1 ) * 4 );
+            aSet.Put( aLR );
+        }
+        break;
+
+    case RES_POOLCOLL_HEADLINE_BASE:            // Basis Ueberschrift
+        {
+            SvxFontItem aFont( FAMILY_SWISS, String::CreateFromAscii(
+#if defined(OW) || defined (MTF) || defined(UNX)
+                    RTL_CONSTASCII_STRINGPARAM("helvetica")
+#elif defined(WNT) || defined(WIN)
+                    RTL_CONSTASCII_STRINGPARAM("Arial")
+#elif defined(MAC) || defined(PM20)
+                    RTL_CONSTASCII_STRINGPARAM("Helvetica")
+#else
+#error Defaultfont fuer diese Plattform?
+#endif
+                    ), aEmptyStr, PITCH_VARIABLE,
+/*?? GetSystemCharSet() ->*/    ::gsl_getSystemTextEncoding()); // Font
+
+            SvxFontHeightItem aFntSize( PT_14 );
+            SvxULSpaceItem aUL( PT_12, PT_6 );
+            if( IsHTMLMode() ) aUL.SetLower( HTML_PARSPACE );
+            aSet.Put( SvxFmtKeepItem( TRUE ));
+
+            if( !pDesc )
+                pNewColl->SetNextTxtFmtColl( *GetTxtCollFromPool(
+                                                RES_POOLCOLL_TEXT ));
+
+            aSet.Put( aUL );
+            aSet.Put( aFntSize );
+            aSet.Put( aFont );
+        }
+        break;
+
+    case RES_POOLCOLL_NUMBUL_BASE:          // Basis Numerierung/Aufzaehlung
+        break;
+
+    case RES_POOLCOLL_GREETING:             // Grussformel
+    case RES_POOLCOLL_REGISTER_BASE:        // Basis Verzeichnisse
+    case RES_POOLCOLL_SIGNATURE:            // Unterschrift
+    case RES_POOLCOLL_TABLE:                // Tabelle-Inhalt
+        {
+            SwFmtLineNumber aLN; aLN.SetCountLines( FALSE );
+            aSet.Put( aLN );
+        }
+        break;
+
+    case RES_POOLCOLL_HEADLINE1:        // Ueberschrift 1
+        lcl_SetHeadline( this, pNewColl, aSet, nOutLvlBits, 0, FALSE );
+        break;
+    case RES_POOLCOLL_HEADLINE2:        // Ueberschrift 2
+        lcl_SetHeadline( this, pNewColl, aSet, nOutLvlBits, 1, TRUE );
+        break;
+    case RES_POOLCOLL_HEADLINE3:        // Ueberschrift 3
+        lcl_SetHeadline( this, pNewColl, aSet, nOutLvlBits, 2, FALSE );
+        break;
+    case RES_POOLCOLL_HEADLINE4:        // Ueberschrift 4
+        lcl_SetHeadline( this, pNewColl, aSet, nOutLvlBits, 3, TRUE );
+        break;
+    case RES_POOLCOLL_HEADLINE5:        // Ueberschrift 5
+        lcl_SetHeadline( this, pNewColl, aSet, nOutLvlBits, 4, FALSE );
+        break;
+    case RES_POOLCOLL_HEADLINE6:        // Ueberschrift 6
+        lcl_SetHeadline( this, pNewColl, aSet, nOutLvlBits, 5, FALSE );
+        break;
+    case RES_POOLCOLL_HEADLINE7:        // Ueberschrift 7
+        lcl_SetHeadline( this, pNewColl, aSet, nOutLvlBits, 6, FALSE );
+        break;
+    case RES_POOLCOLL_HEADLINE8:        // Ueberschrift 8
+        lcl_SetHeadline( this, pNewColl, aSet, nOutLvlBits, 7, FALSE );
+        break;
+    case RES_POOLCOLL_HEADLINE9:        // Ueberschrift 9
+        lcl_SetHeadline( this, pNewColl, aSet, nOutLvlBits, 8, FALSE );
+        break;
+    case RES_POOLCOLL_HEADLINE10:       // Ueberschrift 10
+        lcl_SetHeadline( this, pNewColl, aSet, nOutLvlBits, 9, FALSE );
+        break;
+
+
+    // Sonderbereiche:
+    // Kopfzeilen
+    case RES_POOLCOLL_HEADER:
+    case RES_POOLCOLL_HEADERL:
+    case RES_POOLCOLL_HEADERR:
+    // Fusszeilen
+    case RES_POOLCOLL_FOOTER:
+    case RES_POOLCOLL_FOOTERL:
+    case RES_POOLCOLL_FOOTERR:
+        {
+            SwFmtLineNumber aLN; aLN.SetCountLines( FALSE );
+            aSet.Put( aLN );
+
+            long nRightMargin = lcl_GetRightMargin( *this );
+
+            SvxTabStopItem aTStops( 0, 0 );
+            aTStops.Insert( SvxTabStop( nRightMargin / 2, SVX_TAB_ADJUST_CENTER ) );
+            aTStops.Insert( SvxTabStop( nRightMargin, SVX_TAB_ADJUST_RIGHT ) );
+
+            aSet.Put( aTStops );
+        }
+        break;
+
+    case RES_POOLCOLL_TABLE_HDLN:
+        {
+            aSet.Put( SvxWeightItem( WEIGHT_BOLD ) );
+            if( !IsHTMLMode() )
+                aSet.Put( SvxPostureItem( ITALIC_NORMAL ) );
+            aSet.Put( SvxAdjustItem( SVX_ADJUST_CENTER ) );
+            SwFmtLineNumber aLN; aLN.SetCountLines( FALSE );
+            aSet.Put( aLN );
+        }
+        break;
+
+    case RES_POOLCOLL_FOOTNOTE:             // Fussnote
+    case RES_POOLCOLL_ENDNOTE:
+        {
+            SvxLRSpaceItem aLR;
+            aLR.SetTxtFirstLineOfst( -(short)GetMetricVal( CM_05 ));
+            aLR.SetTxtLeft( GetMetricVal( CM_05 ));
+            aSet.Put( SvxFontHeightItem( PT_10 ) );
+            aSet.Put( aLR );
+            SwFmtLineNumber aLN; aLN.SetCountLines( FALSE );
+            aSet.Put( aLN );
+        }
+        break;
+
+    case RES_POOLCOLL_LABEL:                // Beschriftung-Basis
+        {
+            SvxULSpaceItem aUL; aUL.SetUpper( PT_6 ); aUL.SetLower( PT_6 );
+            aSet.Put( aUL );
+            aSet.Put( SvxPostureItem( ITALIC_NORMAL ) );
+            aSet.Put( SvxFontHeightItem( PT_10 ) );
+            SwFmtLineNumber aLN; aLN.SetCountLines( FALSE );
+            aSet.Put( aLN );
+        }
+        break;
+
+    case RES_POOLCOLL_FRAME:                // Rahmen Inhalt
+    case RES_POOLCOLL_LABEL_ABB:            // Beschriftung-Abbildung
+    case RES_POOLCOLL_LABEL_TABLE:          // Beschriftung-Tabelle
+    case RES_POOLCOLL_LABEL_FRAME:          // Beschriftung-Rahmen
+    case RES_POOLCOLL_LABEL_DRAWING:        // Beschriftung-Zeichnung
+        break;
+
+    case RES_POOLCOLL_JAKETADRESS:          // UmschlagAdresse
+        {
+            SvxULSpaceItem aUL; aUL.SetLower( PT_3 );
+            aSet.Put( aUL );
+            SwFmtLineNumber aLN; aLN.SetCountLines( FALSE );
+            aSet.Put( aLN );
+        }
+        break;
+
+    case RES_POOLCOLL_SENDADRESS:           // AbsenderAdresse
+        {
+            if( IsHTMLMode() )
+                aSet.Put( SvxPostureItem(ITALIC_NORMAL) );
+            else
+            {
+                SvxULSpaceItem aUL; aUL.SetLower( PT_3 );
+                aSet.Put( aUL );
+            }
+            SwFmtLineNumber aLN; aLN.SetCountLines( FALSE );
+            aSet.Put( aLN );
+        }
+        break;
+
+    // Benutzer-Verzeichnisse:
+    case RES_POOLCOLL_TOX_USERH:            // Header
+        lcl_SetRegister( this, aSet, 0, TRUE, FALSE );
+        {
+            SwFmtLineNumber aLN; aLN.SetCountLines( FALSE );
+            aSet.Put( aLN );
+        }
+        break;
+    case RES_POOLCOLL_TOX_USER1:            // 1. Ebene
+        lcl_SetRegister( this, aSet, 0, FALSE, TRUE );
+        break;
+    case RES_POOLCOLL_TOX_USER2:            // 2. Ebene
+        lcl_SetRegister( this, aSet, 1, FALSE, TRUE );
+        break;
+    case RES_POOLCOLL_TOX_USER3:            // 3. Ebene
+        lcl_SetRegister( this, aSet, 2, FALSE, TRUE );
+        break;
+    case RES_POOLCOLL_TOX_USER4:            // 4. Ebene
+        lcl_SetRegister( this, aSet, 3, FALSE, TRUE );
+        break;
+    case RES_POOLCOLL_TOX_USER5:            // 5. Ebene
+        lcl_SetRegister( this, aSet, 4, FALSE, TRUE );
+        break;
+    case RES_POOLCOLL_TOX_USER6:            // 6. Ebene
+        lcl_SetRegister( this, aSet, 5, FALSE, TRUE );
+        break;
+    case RES_POOLCOLL_TOX_USER7:            // 7. Ebene
+        lcl_SetRegister( this, aSet, 6, FALSE, TRUE );
+        break;
+    case RES_POOLCOLL_TOX_USER8:            // 8. Ebene
+        lcl_SetRegister( this, aSet, 7, FALSE, TRUE );
+        break;
+    case RES_POOLCOLL_TOX_USER9:            // 9. Ebene
+        lcl_SetRegister( this, aSet, 8, FALSE, TRUE );
+        break;
+    case RES_POOLCOLL_TOX_USER10:           // 10. Ebene
+        lcl_SetRegister( this, aSet, 9, FALSE, TRUE );
+        break;
+
+    // Index-Verzeichnisse
+    case RES_POOLCOLL_TOX_IDXH:         // Header
+        lcl_SetRegister( this, aSet, 0, TRUE, FALSE );
+        {
+            SwFmtLineNumber aLN; aLN.SetCountLines( FALSE );
+            aSet.Put( aLN );
+        }
+        break;
+    case RES_POOLCOLL_TOX_IDX1:         // 1. Ebene
+        lcl_SetRegister( this, aSet, 0, FALSE, FALSE );
+        break;
+    case RES_POOLCOLL_TOX_IDX2:         // 2. Ebene
+        lcl_SetRegister( this, aSet, 1, FALSE, FALSE );
+        break;
+    case RES_POOLCOLL_TOX_IDX3:         // 3. Ebene
+        lcl_SetRegister( this, aSet, 2, FALSE, FALSE );
+        break;
+    case RES_POOLCOLL_TOX_IDXBREAK:     // Trenner
+        lcl_SetRegister( this, aSet, 0, FALSE, FALSE );
+        break;
+
+    // Inhalts-Verzeichnisse
+    case RES_POOLCOLL_TOX_CNTNTH:       // Header
+        lcl_SetRegister( this, aSet, 0, TRUE, FALSE );
+        {
+            SwFmtLineNumber aLN; aLN.SetCountLines( FALSE );
+            aSet.Put( aLN );
+        }
+        break;
+    case RES_POOLCOLL_TOX_CNTNT1:       // 1. Ebene
+        lcl_SetRegister( this, aSet, 0, FALSE, TRUE );
+        break;
+    case RES_POOLCOLL_TOX_CNTNT2:       // 2. Ebene
+        lcl_SetRegister( this, aSet, 1, FALSE, TRUE );
+        break;
+    case RES_POOLCOLL_TOX_CNTNT3:       // 3. Ebene
+        lcl_SetRegister( this, aSet, 2, FALSE, TRUE );
+        break;
+    case RES_POOLCOLL_TOX_CNTNT4:       // 4. Ebene
+        lcl_SetRegister( this, aSet, 3, FALSE, TRUE );
+        break;
+    case RES_POOLCOLL_TOX_CNTNT5:       // 5. Ebene
+        lcl_SetRegister( this, aSet, 4, FALSE, TRUE );
+        break;
+    case RES_POOLCOLL_TOX_CNTNT6:       // 6. Ebene
+        lcl_SetRegister( this, aSet, 5, FALSE, TRUE );
+        break;
+    case RES_POOLCOLL_TOX_CNTNT7:       // 7. Ebene
+        lcl_SetRegister( this, aSet, 6, FALSE, TRUE );
+        break;
+    case RES_POOLCOLL_TOX_CNTNT8:       // 8. Ebene
+        lcl_SetRegister( this, aSet, 7, FALSE, TRUE );
+        break;
+    case RES_POOLCOLL_TOX_CNTNT9:       // 9. Ebene
+        lcl_SetRegister( this, aSet, 8, FALSE, TRUE );
+        break;
+    case RES_POOLCOLL_TOX_CNTNT10:      // 10. Ebene
+        lcl_SetRegister( this, aSet, 9, FALSE, TRUE );
+        break;
+
+    case RES_POOLCOLL_TOX_ILLUSH:
+    case RES_POOLCOLL_TOX_OBJECTH:
+    case RES_POOLCOLL_TOX_TABLESH:
+    case RES_POOLCOLL_TOX_AUTHORITIESH:
+        lcl_SetRegister( this, aSet, 0, TRUE, FALSE );
+        {
+            SwFmtLineNumber aLN; aLN.SetCountLines( FALSE );
+            aSet.Put( aLN );
+        }
+        break;
+    case RES_POOLCOLL_TOX_ILLUS1:
+    case RES_POOLCOLL_TOX_OBJECT1:
+    case RES_POOLCOLL_TOX_TABLES1:
+    case RES_POOLCOLL_TOX_AUTHORITIES1:
+        lcl_SetRegister( this, aSet, 0, FALSE, TRUE );
+    break;
+
+
+
+    case RES_POOLCOLL_NUM_LEVEL1S:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_NUM_LEVEL1,
+                        lNumFirstLineOffset, SwNumRule::GetNumIndent( 0 ),
+                        PT_12, PT_6 );
+        break;
+    case RES_POOLCOLL_NUM_LEVEL1:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_NUM_LEVEL1,
+                        lNumFirstLineOffset, SwNumRule::GetNumIndent( 0 ),
+                        0, PT_6 );
+        break;
+    case RES_POOLCOLL_NUM_LEVEL1E:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_NUM_LEVEL1,
+                        lNumFirstLineOffset, SwNumRule::GetNumIndent( 0 ),
+                        0, PT_12 );
+        break;
+    case RES_POOLCOLL_NUM_NONUM1:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_NUM_NONUM1,
+                        0, SwNumRule::GetNumIndent( 0 ), 0, PT_6 );
+        break;
+    case RES_POOLCOLL_NUM_LEVEL2S:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_NUM_LEVEL2,
+                        lNumFirstLineOffset, SwNumRule::GetNumIndent( 1 ),
+                        PT_12, PT_6 );
+        break;
+    case RES_POOLCOLL_NUM_LEVEL2:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_NUM_LEVEL2,
+                        lNumFirstLineOffset, SwNumRule::GetNumIndent( 1 ),
+                        0, PT_6 );
+        break;
+    case RES_POOLCOLL_NUM_LEVEL2E:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_NUM_LEVEL2,
+                        lNumFirstLineOffset, SwNumRule::GetNumIndent( 1 ),
+                        0, PT_12 );
+        break;
+    case RES_POOLCOLL_NUM_NONUM2:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_NUM_NONUM2,
+                        0, SwNumRule::GetNumIndent( 1 ), 0, PT_6 );
+        break;
+    case RES_POOLCOLL_NUM_LEVEL3S:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_NUM_LEVEL3,
+                        lNumFirstLineOffset, SwNumRule::GetNumIndent( 2 ),
+                        PT_12, PT_6 );
+        break;
+    case RES_POOLCOLL_NUM_LEVEL3:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_NUM_LEVEL3,
+                        lNumFirstLineOffset, SwNumRule::GetNumIndent( 2 ),
+                        0, PT_6 );
+        break;
+    case RES_POOLCOLL_NUM_LEVEL3E:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_NUM_LEVEL3,
+                        lNumFirstLineOffset, SwNumRule::GetNumIndent( 2 ),
+                        0, PT_12 );
+        break;
+    case RES_POOLCOLL_NUM_NONUM3:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_NUM_NONUM3,
+                        0, SwNumRule::GetNumIndent( 2 ), 0, PT_6 );
+        break;
+    case RES_POOLCOLL_NUM_LEVEL4S:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_NUM_LEVEL4,
+                        lNumFirstLineOffset, SwNumRule::GetNumIndent( 3 ),
+                        PT_12, PT_6 );
+        break;
+    case RES_POOLCOLL_NUM_LEVEL4:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_NUM_LEVEL4,
+                        lNumFirstLineOffset, SwNumRule::GetNumIndent( 3 ),
+                        0, PT_6 );
+        break;
+    case RES_POOLCOLL_NUM_LEVEL4E:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_NUM_LEVEL4,
+                        lNumFirstLineOffset, SwNumRule::GetNumIndent( 3 ),
+                        0, PT_12 );
+        break;
+    case RES_POOLCOLL_NUM_NONUM4:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_NUM_NONUM4,
+                        0, SwNumRule::GetNumIndent( 3 ), 0, PT_6 );
+        break;
+    case RES_POOLCOLL_NUM_LEVEL5S:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_NUM_LEVEL5,
+                        lNumFirstLineOffset, SwNumRule::GetNumIndent( 4 ),
+                        PT_12, PT_6 );
+        break;
+    case RES_POOLCOLL_NUM_LEVEL5:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_NUM_LEVEL5,
+                        lNumFirstLineOffset, SwNumRule::GetNumIndent( 4 ),
+                        0, PT_6 );
+        break;
+    case RES_POOLCOLL_NUM_LEVEL5E:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_NUM_LEVEL5,
+                        lNumFirstLineOffset, SwNumRule::GetNumIndent( 4 ),
+                        0, PT_12 );
+        break;
+    case RES_POOLCOLL_NUM_NONUM5:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_NUM_NONUM5,
+                        0, SwNumRule::GetNumIndent( 4 ), 0, PT_6 );
+        break;
+
+    case RES_POOLCOLL_BUL_LEVEL1S:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_BUL_LEVEL1,
+                        lBullFirstLineOffset, SwNumRule::GetBullIndent( 0 ),
+                        PT_12, PT_6 );
+        break;
+    case RES_POOLCOLL_BUL_LEVEL1:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_BUL_LEVEL1,
+                        lBullFirstLineOffset, SwNumRule::GetBullIndent( 0 ),
+                        0, PT_6 );
+        break;
+    case RES_POOLCOLL_BUL_LEVEL1E:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_BUL_LEVEL1,
+                        lBullFirstLineOffset, SwNumRule::GetBullIndent( 0 ),
+                        0, PT_12 );
+        break;
+    case RES_POOLCOLL_BUL_NONUM1:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_BUL_NONUM1,
+                        0, SwNumRule::GetBullIndent( 0 ), 0, PT_6 );
+        break;
+    case RES_POOLCOLL_BUL_LEVEL2S:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_BUL_LEVEL2,
+                        lBullFirstLineOffset, SwNumRule::GetBullIndent( 1 ),
+                        PT_12, PT_6 );
+        break;
+    case RES_POOLCOLL_BUL_LEVEL2:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_BUL_LEVEL2,
+                        lBullFirstLineOffset, SwNumRule::GetBullIndent( 1 ),
+                        0, PT_6 );
+        break;
+    case RES_POOLCOLL_BUL_LEVEL2E:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_BUL_LEVEL2,
+                        lBullFirstLineOffset, SwNumRule::GetBullIndent( 1 ),
+                        0, PT_12 );
+        break;
+    case RES_POOLCOLL_BUL_NONUM2:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_BUL_NONUM2,
+                        0, SwNumRule::GetBullIndent( 1 ), 0, PT_6 );
+        break;
+    case RES_POOLCOLL_BUL_LEVEL3S:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_BUL_LEVEL3,
+                        lBullFirstLineOffset, SwNumRule::GetBullIndent( 2 ),
+                        PT_12, PT_6 );
+        break;
+    case RES_POOLCOLL_BUL_LEVEL3:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_BUL_LEVEL3,
+                        lBullFirstLineOffset, SwNumRule::GetBullIndent( 2 ),
+                        0, PT_6 );
+        break;
+    case RES_POOLCOLL_BUL_LEVEL3E:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_BUL_LEVEL3,
+                        lBullFirstLineOffset, SwNumRule::GetBullIndent( 2 ),
+                        0, PT_12 );
+        break;
+    case RES_POOLCOLL_BUL_NONUM3:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_BUL_NONUM3,
+                        0, SwNumRule::GetBullIndent( 2 ), 0, PT_6 );
+        break;
+    case RES_POOLCOLL_BUL_LEVEL4S:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_BUL_LEVEL4,
+                        lBullFirstLineOffset, SwNumRule::GetBullIndent( 3 ),
+                        PT_12, PT_6 );
+        break;
+    case RES_POOLCOLL_BUL_LEVEL4:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_BUL_LEVEL4,
+                        lBullFirstLineOffset, SwNumRule::GetBullIndent( 3 ),
+                        0, PT_6 );
+        break;
+    case RES_POOLCOLL_BUL_LEVEL4E:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_BUL_LEVEL4,
+                        lBullFirstLineOffset, SwNumRule::GetBullIndent( 3 ),
+                        0, PT_12 );
+        break;
+    case RES_POOLCOLL_BUL_NONUM4:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_BUL_NONUM4,
+                        0, SwNumRule::GetBullIndent( 3 ), 0, PT_6 );
+        break;
+    case RES_POOLCOLL_BUL_LEVEL5S:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_BUL_LEVEL5,
+                        lBullFirstLineOffset, SwNumRule::GetBullIndent( 4 ),
+                        PT_12, PT_6 );
+        break;
+    case RES_POOLCOLL_BUL_LEVEL5:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_BUL_LEVEL5,
+                        lBullFirstLineOffset, SwNumRule::GetBullIndent( 4 ),
+                        0, PT_6 );
+        break;
+    case RES_POOLCOLL_BUL_LEVEL5E:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_BUL_LEVEL5,
+                        lBullFirstLineOffset, SwNumRule::GetBullIndent( 4 ),
+                        0, PT_12 );
+        break;
+    case RES_POOLCOLL_BUL_NONUM5:
+        lcl_SetNumBul( this, pNewColl, aSet, RES_POOLCOLL_BUL_NONUM5,
+                        0, SwNumRule::GetBullIndent( 4 ), 0, PT_6 );
+        break;
+
+    case RES_POOLCOLL_DOC_TITEL:            // Doc. Titel
+        {
+            aSet.Put( SvxWeightItem( WEIGHT_BOLD ) );
+            aSet.Put( SvxFontHeightItem( PT_18 ) );
+            aSet.Put( SvxAdjustItem( SVX_ADJUST_CENTER ) );
+
+            if( !pDesc )
+                pNewColl->SetNextTxtFmtColl( *GetTxtCollFromPool(
+                                                RES_POOLCOLL_DOC_SUBTITEL ));
+        }
+        break;
+
+    case RES_POOLCOLL_DOC_SUBTITEL:         // Doc. UnterTitel
+        {
+            aSet.Put( SvxPostureItem( ITALIC_NORMAL ));
+            aSet.Put( SvxFontHeightItem( PT_14 ));
+            aSet.Put( SvxAdjustItem( SVX_ADJUST_CENTER ));
+
+            if( !pDesc )
+                pNewColl->SetNextTxtFmtColl( *GetTxtCollFromPool(
+                                                RES_POOLCOLL_TEXT ));
+        }
+        break;
+
+    case RES_POOLCOLL_HTML_BLOCKQUOTE:
+        {
+            SvxLRSpaceItem aLR;
+            aLR.SetLeft( GetMetricVal( CM_1 ));
+            aLR.SetRight( GetMetricVal( CM_1 ));
+            aSet.Put( aLR );
+//          aSet.Put( SvxAdjustItem( SVX_ADJUST_BLOCK ) );
+            SvxULSpaceItem aUL;
+            if( !pDesc )
+                aUL = pNewColl->GetULSpace();
+            aUL.SetLower( HTML_PARSPACE );
+            aSet.Put( aUL);
+        }
+        break;
+
+    case RES_POOLCOLL_HTML_PRE:
+        {
+            aSet.Put( SvxFontItem( FAMILY_ROMAN,
+                        System::GetStandardFont( STDFONT_FIXED ).GetName(),
+                        aEmptyStr,PITCH_FIXED,
+/*?? GetSystemCharSet() ->*/    ::gsl_getSystemTextEncoding() ));   // Font
+
+// WORKAROUND: PRE auf 10pt setzten
+            aSet.Put( SvxFontHeightItem(PT_10) );
+// WORKAROUND: PRE auf 10pt setzten
+
+            // der untere Absatz-Abstand wird explizit gesetzt (macht
+            // die harte Attributierung einfacher)
+            SvxULSpaceItem aULSpaceItem;
+            if( !pDesc )
+                aULSpaceItem = pNewColl->GetULSpace();
+            aULSpaceItem.SetLower( 0 );
+            aSet.Put( aULSpaceItem );
+        }
+        break;
+
+    case RES_POOLCOLL_HTML_HR:
+        {
+            SvxBoxItem aBox;
+            Color aColor( COL_GRAY );
+            SvxBorderLine aNew( &aColor, DEF_DOUBLE_LINE0_OUT,
+                                         DEF_DOUBLE_LINE0_IN,
+                                         DEF_DOUBLE_LINE0_DIST );
+            aBox.SetLine( &aNew, BOX_LINE_BOTTOM );
+
+            aSet.Put( aBox );
+            aSet.Put( SvxFontHeightItem(120) );
+
+            SvxULSpaceItem aUL;
+            if( !pDesc )
+            {
+                pNewColl->SetNextTxtFmtColl( *GetTxtCollFromPool(
+                                                RES_POOLCOLL_TEXT ));
+                aUL = pNewColl->GetULSpace();
+            }
+            aUL.SetLower( HTML_PARSPACE );
+            aSet.Put( aUL);
+            SwFmtLineNumber aLN; aLN.SetCountLines( FALSE );
+            aSet.Put( aLN );
+        }
+        break;
+
+    case RES_POOLCOLL_HTML_DD:
+        {
+            SvxLRSpaceItem aLR;
+            if( !pDesc )
+                aLR = pNewColl->GetLRSpace();
+            // es wird um 1cm eingerueckt. Die IDs liegen immer 2 auseinander!
+            aLR.SetLeft( GetMetricVal( CM_1 ));
+            aSet.Put( aLR );
+        }
+        break;
+    case RES_POOLCOLL_HTML_DT:
+        {
+            SvxLRSpaceItem aLR;
+            if( !pDesc )
+            {
+                pNewColl->SetNextTxtFmtColl( *GetTxtCollFromPool(
+                                                    RES_POOLCOLL_HTML_DD ));
+                aLR = pNewColl->GetLRSpace();
+            }
+            // es wird um 0cm eingerueckt. Die IDs liegen immer 2 auseinander!
+            aLR.SetLeft( 0 );
+            aSet.Put( aLR );
+        }
+        break;
+    }
+
+    if( aSet.Count() )
+    {
+        if( pDesc )
+        {
+            String aStr;
+            aSet.GetPresentation( ePres, eCoreMetric, ePresMetric, aStr );
+            pDesc->AppendAscii( sKomma );
+            *pDesc += aStr;
+        }
+        else
+        {
+            pNewColl->SetAttr( aSet );
+            // JP 31.08.95: erzeugen einer PoolVorlage ist keine Modifikation
+            //              (Bug: 18545)
+            // SetModified();
+        }
+    }
+    return pNewColl;
+}
+
+
+
+    // pruefe, ob diese "Auto-Collection" in Dokument schon/noch
+    // benutzt wird
+BOOL SwDoc::IsPoolTxtCollUsed( USHORT nId ) const
+{
+    ASSERT(
+        (RES_POOLCOLL_TEXT_BEGIN <= nId && nId < RES_POOLCOLL_TEXT_END) ||
+        (RES_POOLCOLL_LISTS_BEGIN <= nId && nId < RES_POOLCOLL_LISTS_END) ||
+        (RES_POOLCOLL_EXTRA_BEGIN <= nId && nId < RES_POOLCOLL_EXTRA_END) ||
+        (RES_POOLCOLL_REGISTER_BEGIN <= nId && nId < RES_POOLCOLL_REGISTER_END) ||
+        (RES_POOLCOLL_DOC_BEGIN <= nId && nId < RES_POOLCOLL_DOC_END) ||
+        (RES_POOLCOLL_HTML_BEGIN <= nId && nId < RES_POOLCOLL_HTML_END),
+            "Falsche AutoFormat-Id" );
+
+    SwTxtFmtColl* pNewColl;
+    BOOL bFnd = FALSE;
+    for( USHORT n = 0; !bFnd && n < pTxtFmtCollTbl->Count(); ++n )
+        if( nId == ( pNewColl = (*pTxtFmtCollTbl)[ n ] )->GetPoolFmtId() )
+            bFnd = TRUE;
+
+    if( !bFnd || !pNewColl->GetDepends() )
+        return FALSE;
+
+    SwAutoFmtGetDocNode aGetHt( &aNodes );
+    return !pNewColl->GetInfo( aGetHt );
+}
+
+
+
+USHORT lcl_CheckAutoFmtId( USHORT nId )
+{
+    if( RES_POOLCHR_BEGIN <= nId && nId < RES_POOLCHR_END )
+        return RES_POOL_CHRFMT;
+    if( RES_POOLFRM_BEGIN <= nId && nId < RES_POOLFRM_END )
+        return RES_POOL_FRMFMT;
+    if( (RES_POOLCOLL_TEXT_BEGIN <= nId && nId < RES_POOLCOLL_TEXT_END) ||
+        (RES_POOLCOLL_LISTS_BEGIN <= nId && nId < RES_POOLCOLL_LISTS_END) ||
+        (RES_POOLCOLL_EXTRA_BEGIN <= nId && nId < RES_POOLCOLL_EXTRA_END) ||
+        (RES_POOLCOLL_REGISTER_BEGIN <= nId && nId < RES_POOLCOLL_REGISTER_END) ||
+        (RES_POOLCOLL_DOC_BEGIN <= nId && nId < RES_POOLCOLL_DOC_END) ||
+        (RES_POOLCOLL_HTML_BEGIN <= nId && nId < RES_POOLCOLL_HTML_END) )
+        return RES_POOL_TXTCOLL;
+
+    ASSERT( FALSE, "ungueltige Id" );
+    return 0;
+}
+
+
+    // Gebe das "Auto[matische]-Format" mit der Id zurueck. Existiert
+    // es noch nicht, dann erzeuge es
+
+typedef SwFmt* (SwDoc::*FnMakeFmt)( const String &, SwFmt * );
+SwFmt* SwDoc::GetFmtFromPool( USHORT nId, String* pDesc,
+    SfxItemPresentation ePres, SfxMapUnit eCoreMetric, SfxMapUnit ePresMetric )
+{
+    SwFmt *pNewFmt, *pDeriveFmt;
+
+    SvPtrarr* pArray[ 2 ];
+    USHORT nArrCnt = 1, nRCId = 0;
+    FnMakeFmt fnMkFmt;
+    USHORT* pWhichRange = 0;
+
+    switch( nId & (COLL_GET_RANGE_BITS + POOLGRP_NOCOLLID) )
+    {
+    case POOLGRP_CHARFMT:
+        {
+            pArray[0] = pCharFmtTbl;
+            pDeriveFmt = pDfltCharFmt;
+            fnMkFmt= (FnMakeFmt)&SwDoc::MakeCharFmt;
+
+            if( nId > RES_POOLCHR_NORMAL_END )
+                nRCId = RC_POOLCHRFMT_HTML_BEGIN - RES_POOLCHR_HTML_BEGIN;
+            else
+                nRCId = RC_POOLCHRFMT_BEGIN - RES_POOLCHR_BEGIN;
+            pWhichRange =  aCharFmtSetRange;
+
+            // Fehlerfall: unbekanntes Format, aber CharFormat
+            //          -> returne das erste
+            if( RES_POOLCHR_BEGIN > nId || nId >= RES_POOLCHR_END )
+            {
+                ASSERT( !this, "ungueltige Id" );
+                nId = RES_POOLCHR_BEGIN;
+            }
+        }
+        break;
+    case POOLGRP_FRAMEFMT:
+        {
+            pArray[0] = pFrmFmtTbl;
+            pArray[1] = pSpzFrmFmtTbl;
+            pDeriveFmt = pDfltFrmFmt;
+            fnMkFmt= (FnMakeFmt)&SwDoc::MakeFrmFmt;
+            nArrCnt = 2;
+            nRCId = RC_POOLFRMFMT_BEGIN - RES_POOLFRM_BEGIN;
+            pWhichRange = aFrmFmtSetRange;
+
+            // Fehlerfall: unbekanntes Format, aber FrameFormat
+            //          -> returne das erste
+            if( RES_POOLFRM_BEGIN > nId || nId >= RES_POOLFRM_END )
+            {
+                ASSERT( !this, "ungueltige Id" );
+                nId = RES_POOLFRM_BEGIN;
+            }
+        }
+        break;
+
+    default:
+        // Fehlerfall, unbekanntes Format
+        ASSERT( nId, "ungueltige Id" );
+        return 0;
+    }
+    ASSERT( nRCId, "ungueltige Id" );
+
+    while( nArrCnt-- )
+        for( USHORT n = 0; n < (*pArray[nArrCnt]).Count(); ++n )
+            if( nId == ( pNewFmt = (SwFmt*)(*pArray[ nArrCnt ] )[ n ] )->
+                    GetPoolFmtId() )
+            {
+                if( pDesc )
+                    pNewFmt->GetPresentation( ePres, eCoreMetric,
+                                              ePresMetric, *pDesc );
+                return pNewFmt;
+            }
+
+    ResId aResId( nRCId + nId, pSwResMgr );
+    String aNm( aResId );
+    SwAttrSet aSet( GetAttrPool(), pWhichRange );
+
+    if( pDesc )
+    {
+        pNewFmt = 0;
+//      *pDesc = aEmptyStr; // oder den Namen ?? aNm;
+        *pDesc = aNm;
+    }
+    else
+    {
+        BOOL bIsModified = IsModified();
+        pNewFmt = (this->*fnMkFmt)( aNm, pDeriveFmt );
+        if( !bIsModified )
+            ResetModified();
+        pNewFmt->SetPoolFmtId( nId );
+        pNewFmt->SetAuto( FALSE );      // kein Auto-Format
+    }
+
+    switch( nId )
+    {
+    case RES_POOLCHR_FOOTNOTE:              // Fussnote
+    case RES_POOLCHR_PAGENO:                // Seiten/Feld
+    case RES_POOLCHR_LABEL:                 // Beschriftung
+    case RES_POOLCHR_DROPCAPS:              // Initialien
+    case RES_POOLCHR_NUM_LEVEL:             // Aufzaehlungszeichen
+    case RES_POOLCHR_TOXJUMP:               // Verzeichnissprung
+    case RES_POOLCHR_ENDNOTE:               // Endnote
+    case RES_POOLCHR_LINENUM:               // Zeilennummerierung
+        break;
+
+    case RES_POOLCHR_ENDNOTE_ANCHOR:        // Endnotenanker
+    case RES_POOLCHR_FOOTNOTE_ANCHOR:       // Fussnotenanker
+        {
+            aSet.Put( SvxEscapementItem( DFLT_ESC_AUTO_SUPER, 58 ) );
+        }
+        break;
+
+    case RES_POOLCHR_BUL_LEVEL:             // Aufzaehlungszeichen
+        {
+            const Font& rBulletFont = SwNumRule::GetDefBulletFont();
+            aSet.Put( SvxFontItem( rBulletFont.GetFamily(),
+                        rBulletFont.GetName(), rBulletFont.GetStyleName(),
+                        rBulletFont.GetPitch(), rBulletFont.GetCharSet() ));
+            aSet.Put( SvxFontHeightItem( PT_9 ));
+        }
+        break;
+
+    case RES_POOLCHR_INET_NORMAL:
+        {
+            Color aCol( COL_BLUE );
+            aSet.Put( SvxColorItem( aCol ) );
+            aSet.Put( SvxUnderlineItem( UNDERLINE_SINGLE ) );
+        }
+        break;
+    case RES_POOLCHR_INET_VISIT:
+        {
+            Color aCol( COL_RED );
+            aSet.Put( SvxColorItem( aCol ) );
+            aSet.Put( SvxUnderlineItem( UNDERLINE_SINGLE ) );
+        }
+        break;
+    case RES_POOLCHR_JUMPEDIT:
+        {
+            Color aCol( COL_CYAN );
+            aSet.Put( SvxColorItem( aCol ) );
+            aSet.Put( SvxUnderlineItem( UNDERLINE_DOTTED ) );
+            aSet.Put( SvxCaseMapItem( SVX_CASEMAP_KAPITAELCHEN ) );
+        }
+        break;
+
+    case RES_POOLCHR_HTML_EMPHASIS:
+    case RES_POOLCHR_HTML_CITIATION:
+    case RES_POOLCHR_HTML_VARIABLE:
+        {
+            aSet.Put( SvxPostureItem( ITALIC_NORMAL ) );
+        }
+        break;
+
+    case RES_POOLCHR_IDX_MAIN_ENTRY:
+    case RES_POOLCHR_HTML_STRONG:
+        {
+            aSet.Put( SvxWeightItem( WEIGHT_BOLD ));
+        }
+        break;
+
+    case RES_POOLCHR_HTML_CODE:
+    case RES_POOLCHR_HTML_SAMPLE:
+    case RES_POOLCHR_HTML_KEYBOARD:
+    case RES_POOLCHR_HTML_TELETYPE:
+        {
+            aSet.Put( SvxFontItem( FAMILY_ROMAN,
+                        System::GetStandardFont( STDFONT_FIXED ).GetName(),
+                        aEmptyStr,PITCH_FIXED,
+/*?? GetSystemCharSet() ->*/    ::gsl_getSystemTextEncoding()));    // Font
+        }
+        break;
+
+//nichts besonderes
+//  case RES_POOLCHR_HTML_DEFINSTANCE:
+//          break;
+
+
+    case RES_POOLFRM_FRAME:
+        {
+            if ( IsBrowseMode() )
+            {
+                aSet.Put( SwFmtAnchor( FLY_IN_CNTNT ));
+                aSet.Put( SwFmtVertOrient( 0, VERT_LINE_CENTER, PRTAREA ) );
+                aSet.Put( SwFmtSurround( SURROUND_NONE ) );
+            }
+            else
+            {
+                aSet.Put( SwFmtAnchor( FLY_AT_CNTNT ));
+                aSet.Put( SwFmtSurround( SURROUND_PARALLEL ) );
+                aSet.Put( SwFmtHoriOrient( 0, HORI_CENTER, PRTAREA ) );
+                aSet.Put( SwFmtVertOrient( 0, VERT_TOP, PRTAREA ) );
+                Color aCol( COL_BLACK );
+                SvxBorderLine aLine( &aCol, DEF_LINE_WIDTH_0 );
+                SvxBoxItem aBox;
+                aBox.SetLine( &aLine, BOX_LINE_TOP );
+                aBox.SetLine( &aLine, BOX_LINE_BOTTOM );
+                aBox.SetLine( &aLine, BOX_LINE_LEFT );
+                aBox.SetLine( &aLine, BOX_LINE_RIGHT );
+                aBox.SetDistance( 85 );
+                aSet.Put( aBox );
+                aSet.Put( SvxLRSpaceItem( 114, 114 ) );
+                aSet.Put( SvxULSpaceItem( 114, 114 ) );
+            }
+        }
+        break;
+    case RES_POOLFRM_GRAPHIC:
+    case RES_POOLFRM_OLE:
+        {
+            aSet.Put( SwFmtAnchor( FLY_AT_CNTNT ));
+            aSet.Put( SwFmtHoriOrient( 0, HORI_CENTER, FRAME ));
+            aSet.Put( SwFmtVertOrient( 0, VERT_TOP, FRAME ));
+            aSet.Put( SwFmtSurround( SURROUND_NONE ));
+        }
+        break;
+    case RES_POOLFRM_FORMEL:
+        {
+            aSet.Put( SwFmtAnchor( FLY_IN_CNTNT ) );
+            aSet.Put( SwFmtVertOrient( 0, VERT_CHAR_CENTER, FRAME ) );
+            aSet.Put( SvxLRSpaceItem( 114, 114 ) );
+        }
+        break;
+    case RES_POOLFRM_MARGINAL:
+        {
+            aSet.Put( SwFmtAnchor( FLY_AT_CNTNT ));
+            aSet.Put( SwFmtHoriOrient( 0, HORI_LEFT, FRAME ));
+            aSet.Put( SwFmtVertOrient( 0, VERT_TOP, FRAME ));
+            aSet.Put( SwFmtSurround( SURROUND_PARALLEL ));
+            // Breite 3.5 centimeter vorgegeben, als Hoehe nur den
+            // min. Wert benutzen
+            aSet.Put( SwFmtFrmSize( ATT_MIN_SIZE,
+                    GetMetricVal( CM_1 ) * 3 + GetMetricVal( CM_05 ),
+                    MM50 ));
+        }
+        break;
+    case RES_POOLFRM_WATERSIGN:
+        {
+            aSet.Put( SwFmtAnchor( FLY_PAGE ));
+            aSet.Put( SwFmtHoriOrient( 0, HORI_CENTER, FRAME ));
+            aSet.Put( SwFmtVertOrient( 0, VERT_CENTER, FRAME ));
+            aSet.Put( SvxOpaqueItem( FALSE ));
+            aSet.Put( SwFmtSurround( SURROUND_THROUGHT ));
+        }
+        break;
+
+    case RES_POOLFRM_LABEL:
+        {
+            aSet.Put( SwFmtAnchor( FLY_IN_CNTNT ) );
+            aSet.Put( SwFmtVertOrient( 0, VERT_TOP, FRAME ) );
+            aSet.Put( SvxLRSpaceItem( 114, 114 ) );
+
+            SvxProtectItem aProtect;
+            aProtect.SetSizeProtect( TRUE );
+            aProtect.SetPosProtect( TRUE );
+            aSet.Put( aProtect );
+
+            if( !pDesc )
+                pNewFmt->SetAutoUpdateFmt( TRUE );
+        }
+        break;
+    }
+    if( aSet.Count() )
+    {
+        if( pDesc )
+        {
+            String aStr;
+            aSet.GetPresentation( ePres, eCoreMetric, ePresMetric, aStr );
+            pDesc->AppendAscii( sKomma );
+            *pDesc += aStr;
+        }
+        else
+        {
+            pNewFmt->SetAttr( aSet );
+            // JP 31.08.95: erzeugen einer PoolVorlage ist keine Modifikation
+            //              (Bug: 18545)
+            // SetModified();
+        }
+    }
+    return pNewFmt;
+}
+
+
+
+    // pruefe, ob diese "Auto-Collection" in Dokument schon/noch
+    // benutzt wird
+BOOL SwDoc::IsPoolFmtUsed( USHORT nId ) const
+{
+    SwFmt *pNewFmt;
+    const SvPtrarr* pArray[ 2 ];
+    USHORT nArrCnt = 1;
+    BOOL bFnd = TRUE;
+
+    if( RES_POOLCHR_BEGIN <= nId && nId < RES_POOLCHR_END )
+    {
+        pArray[0] = pCharFmtTbl;
+    }
+    if( RES_POOLFRM_BEGIN <= nId && nId < RES_POOLFRM_END )
+    {
+        pArray[0] = pFrmFmtTbl;
+        pArray[1] = pSpzFrmFmtTbl;
+        nArrCnt = 2;
+    }
+    else
+    {
+        ASSERT( FALSE, "ungueltige Id" );
+        bFnd = FALSE;
+    }
+
+    if( bFnd )
+    {
+        bFnd = FALSE;
+        while( nArrCnt-- && !bFnd )
+            for( USHORT n = 0; !bFnd && n < (*pArray[nArrCnt]).Count(); ++n )
+                if( nId == ( pNewFmt = (SwFmt*)(*pArray[ nArrCnt ] )[ n ] )->
+                        GetPoolFmtId() )
+                    bFnd = TRUE;
+    }
+
+    // nicht gefunden oder keine Abhaengigen ?
+    if( bFnd && pNewFmt->GetDepends() )
+    {
+        // dann teste mal, ob es abhaengige ContentNodes im Nodes Array gibt
+        // (auch indirekte fuer Format-Ableitung! )
+        SwAutoFmtGetDocNode aGetHt( &aNodes );
+        bFnd = !pNewFmt->GetInfo( aGetHt );
+    }
+    else
+        bFnd = FALSE;
+
+    return bFnd;
+}
+
+
+
+void lcl_GetStdPgSize( SwDoc* pDoc, SfxItemSet& rSet )
+{
+    SwPageDesc* pStdPgDsc = pDoc->GetPageDescFromPool( RES_POOLPAGE_STANDARD );
+    SwFmtFrmSize aFrmSz( pStdPgDsc->GetMaster().GetFrmSize() );
+    if( pStdPgDsc->GetLandscape() )
+    {
+        SwTwips nTmp = aFrmSz.GetHeight();
+        aFrmSz.SetHeight( aFrmSz.GetWidth() );
+        aFrmSz.SetWidth( nTmp );
+    }
+    rSet.Put( aFrmSz );
+}
+
+
+
+SwPageDesc* SwDoc::GetPageDescFromPool( USHORT nId, String* pDesc,
+    SfxItemPresentation ePres, SfxMapUnit eCoreMetric, SfxMapUnit ePresMetric )
+{
+    ASSERT( RES_POOLPAGE_BEGIN <= nId && nId < RES_POOLPAGE_END,
+            "Falsche AutoFormat-Id" );
+
+    SwPageDesc *pNewPgDsc;
+    for( USHORT n = 0; n < aPageDescs.Count(); ++n )
+        if( nId == ( pNewPgDsc = aPageDescs[ n ] )->GetPoolFmtId() )
+        {
+            if( pDesc )
+                pNewPgDsc->GetPresentation( ePres, eCoreMetric,
+                                            ePresMetric, *pDesc );
+            return pNewPgDsc;
+        }
+
+    // Fehlerfall: unbekannte Poolvorlage
+    if( RES_POOLPAGE_BEGIN > nId ||  nId >= RES_POOLPAGE_END )
+    {
+        ASSERT( !this, "ungueltige Id" );
+        nId = RES_POOLPAGE_BEGIN;
+    }
+
+    ResId aResId( RC_POOLPAGEDESC_BEGIN + nId - RES_POOLPAGE_BEGIN, pSwResMgr );
+    String aNm( aResId );
+    if( pDesc )
+    {
+        pNewPgDsc = 0;
+//      *pDesc = aEmptyStr; // oder den Namen ?? aNm;
+        *pDesc = aNm;
+    }
+    else
+    {
+        BOOL bIsModified = IsModified();
+        n = MakePageDesc( aNm );
+        pNewPgDsc = aPageDescs[ n ];
+        pNewPgDsc->SetPoolFmtId( nId );
+        if( !bIsModified )
+            ResetModified();
+    }
+
+
+    SvxLRSpaceItem aLR;
+    aLR.SetLeft( GetMetricVal( CM_1 ) * 2 );
+    aLR.SetRight( aLR.GetLeft() );
+    SvxULSpaceItem aUL;
+    aUL.SetUpper( aLR.GetLeft() );
+    aUL.SetLower( aLR.GetLeft() );
+
+    SwAttrSet aSet( GetAttrPool(), aPgFrmFmtSetRange );
+    BOOL bSetLeft = TRUE;
+
+    switch( nId )
+    {
+    case RES_POOLPAGE_STANDARD:             // Standard-Seite
+        {
+            aSet.Put( aLR );
+            aSet.Put( aUL );
+            if( pNewPgDsc )
+                pNewPgDsc->SetUseOn( PD_ALL );
+        }
+        break;
+
+    case RES_POOLPAGE_FIRST:                // Erste Seite
+    case RES_POOLPAGE_REGISTER:             // Verzeichnis
+        {
+            lcl_GetStdPgSize( this, aSet );
+            aSet.Put( aLR );
+            aSet.Put( aUL );
+            if( pNewPgDsc )
+            {
+                pNewPgDsc->SetUseOn( PD_ALL );
+                if( RES_POOLPAGE_FIRST == nId )
+                    pNewPgDsc->SetFollow( GetPageDescFromPool( RES_POOLPAGE_STANDARD ));
+            }
+        }
+        break;
+
+    case RES_POOLPAGE_LEFT:                 // Linke Seite
+        {
+            lcl_GetStdPgSize( this, aSet );
+            aSet.Put( aLR );
+            aSet.Put( aUL );
+            bSetLeft = FALSE;
+            if( pNewPgDsc )
+                pNewPgDsc->SetUseOn( PD_LEFT );
+        }
+        break;
+    case RES_POOLPAGE_RIGHT:                // Rechte Seite
+        {
+            lcl_GetStdPgSize( this, aSet );
+            aSet.Put( aLR );
+            aSet.Put( aUL );
+            bSetLeft = FALSE;
+            if( pNewPgDsc )
+                pNewPgDsc->SetUseOn( PD_RIGHT );
+        }
+        break;
+
+    case RES_POOLPAGE_JAKET:                // Umschlag
+        {
+            aLR.SetLeft( 0 ); aLR.SetRight( 0 );
+            aUL.SetUpper( 0 ); aUL.SetLower( 0 );
+            Size aPSize( SvxPaperInfo::GetPaperSize( SVX_PAPER_C65 ) );
+            LandscapeSwap( aPSize );
+            aSet.Put( SwFmtFrmSize( ATT_FIX_SIZE, aPSize.Width(), aPSize.Height() ));
+            aSet.Put( aLR );
+            aSet.Put( aUL );
+
+            if( pNewPgDsc )
+            {
+                pNewPgDsc->SetUseOn( PD_ALL );
+                pNewPgDsc->SetLandscape( TRUE );
+            }
+        }
+        break;
+
+    case RES_POOLPAGE_HTML:             // HTML
+        {
+            aLR.SetRight( GetMetricVal( CM_1 ));
+            aUL.SetUpper( aLR.GetRight() );
+            aUL.SetLower( aLR.GetRight() );
+            Size aPSize( SvxPaperInfo::GetPaperSize( SVX_PAPER_A4 ) );
+            aSet.Put( SwFmtFrmSize( ATT_FIX_SIZE, aPSize.Width(), aPSize.Height() ));
+            aSet.Put( aLR );
+            aSet.Put( aUL );
+
+            if( pNewPgDsc )
+                pNewPgDsc->SetUseOn( PD_ALL );
+        }
+        break;
+    case RES_POOLPAGE_FOOTNOTE:
+    case RES_POOLPAGE_ENDNOTE:
+        {
+            lcl_GetStdPgSize( this, aSet );
+            aSet.Put( aLR );
+            aSet.Put( aUL );
+            if( pNewPgDsc )
+                pNewPgDsc->SetUseOn( PD_ALL );
+            SwPageFtnInfo aInf( pNewPgDsc->GetFtnInfo() );
+            aInf.SetLineWidth( 0 );
+            aInf.SetTopDist( 0 );
+            aInf.SetBottomDist( 0 );
+            pNewPgDsc->SetFtnInfo( aInf );
+        }
+        break;
+    }
+
+    if( aSet.Count() )
+    {
+        if( pDesc )
+        {
+            String aStr;
+            aSet.GetPresentation( ePres, eCoreMetric, ePresMetric, aStr );
+            pDesc->AppendAscii( sKomma );
+            *pDesc += aStr;
+        }
+        else
+        {
+            if( bSetLeft )
+                pNewPgDsc->GetLeft().SetAttr( aSet );
+            pNewPgDsc->GetMaster().SetAttr( aSet );
+            // JP 31.08.95: erzeugen einer PoolVorlage ist keine Modifikation
+            //              (Bug: 18545)
+            // SetModified();
+        }
+    }
+    return pNewPgDsc;
+}
+
+SwNumRule* SwDoc::GetNumRuleFromPool( USHORT nId, String* pDesc,
+    SfxItemPresentation ePres, SfxMapUnit eCoreMetric, SfxMapUnit ePresMetric )
+{
+    ASSERT( RES_POOLNUMRULE_BEGIN <= nId && nId < RES_POOLNUMRULE_END,
+            "Falsche AutoFormat-Id" );
+
+    SwNumRule* pNewRule;
+    for( USHORT n = 0; n < GetNumRuleTbl().Count(); ++n )
+        if( nId == ( pNewRule = GetNumRuleTbl()[ n ] )->GetPoolFmtId() )
+        {
+            if( pDesc )
+                *pDesc = pNewRule->GetName();
+            return pNewRule;
+        }
+
+    // Fehlerfall: unbekannte Poolvorlage
+    if( RES_POOLNUMRULE_BEGIN > nId ||  nId >= RES_POOLNUMRULE_END )
+    {
+        ASSERT( !this, "ungueltige Id" );
+        nId = RES_POOLNUMRULE_BEGIN;
+    }
+
+    ResId aResId( RC_POOLNUMRULE_BEGIN + nId - RES_POOLNUMRULE_BEGIN, pSwResMgr );
+    String aNm( aResId );
+
+    SwCharFmt *pNumCFmt = 0, *pBullCFmt = 0;
+
+    if( pDesc )
+    {
+        pNewRule = new SwNumRule( aNm );
+        *pDesc = aNm;
+    }
+    else
+    {
+        BOOL bIsModified = IsModified();
+        n = MakeNumRule( aNm );
+        pNewRule = GetNumRuleTbl()[ n ];
+        pNewRule->SetPoolFmtId( nId );
+        pNewRule->SetAutoRule( FALSE );
+
+        if( RES_POOLNUMRULE_NUM1 <= nId && nId <= RES_POOLNUMRULE_NUM5 )
+            pNumCFmt = GetCharFmtFromPool( RES_POOLCHR_NUM_LEVEL );
+
+        if( ( RES_POOLNUMRULE_BUL1 <= nId && nId <= RES_POOLNUMRULE_BUL5 ) ||
+            RES_POOLNUMRULE_NUM5 == nId )
+            pBullCFmt = GetCharFmtFromPool( RES_POOLCHR_NUM_LEVEL );
+
+        if( !bIsModified )
+            ResetModified();
+    }
+
+    switch( nId )
+    {
+    case RES_POOLNUMRULE_NUM1:
+        {
+            SwNumFmt aFmt;
+            aFmt.eType = SVX_NUM_ARABIC;
+            aFmt.SetCharFmt( pNumCFmt );
+            aFmt.SetStartValue( 1 );
+            aFmt.SetUpperLevel( 1 );
+            aFmt.SetPostfix( aDotStr );
+
+            static const USHORT aAbsSpace[ MAXLEVEL ] =
+                {
+//              cm: 0,5  1,0  1,5  2,0   2,5   3,0   3,5   4,0   4,5   5,0
+                    283, 567, 850, 1134, 1417, 1701, 1984, 2268, 2551, 2835
+                };
+#ifdef USE_MEASUREMENT
+            static const USHORT aAbsSpaceInch[ MAXLEVEL ] =
+                {
+                    283, 567, 850, 1134, 1417, 1701, 1984, 2268, 2551, 2835
+                };
+            const USHORT* pArr = MEASURE_METRIC == Application::
+                                GetAppInternational().GetMeasurementSystem()
+                                    ? aAbsSpace
+                                    : aAbsSpaceInch;
+#else
+            const USHORT* pArr = aAbsSpace;
+#endif
+
+            aFmt.SetFirstLineOffset( - (*pArr) );
+            for( n = 0; n < MAXLEVEL; ++n, ++pArr )
+            {
+                aFmt.SetAbsLSpace( *pArr );
+                pNewRule->Set( n, aFmt );
+            }
+        }
+        break;
+
+    case RES_POOLNUMRULE_NUM2:
+        {
+            static const USHORT aAbsSpace[ MAXLEVEL ] =
+                {
+                    283,  283,  567,  709,      // 0.50, 0.50, 1.00, 1.25
+                    850, 1021, 1304, 1474,      // 1.50, 1.80, 2.30, 2.60
+                   1588, 1758                   // 2.80, 3.10
+                };
+
+#ifdef USE_MEASUREMENT
+            static const USHORT aAbsSpaceInch[ MAXLEVEL ] =
+                {
+                    385,  385,  770,  963,
+                   1155, 1386, 1771, 2002,
+                   2156, 2387
+                };
+
+            const USHORT* pArr = MEASURE_METRIC == Application::
+                                GetAppInternational().GetMeasurementSystem()
+                                    ? aAbsSpace
+                                    : aAbsSpaceInch;
+#else
+            const USHORT* pArr = aAbsSpace;
+#endif
+            SwNumFmt aFmt;
+            aFmt.eType = SVX_NUM_ARABIC;
+            aFmt.SetCharFmt( pNumCFmt );
+            aFmt.SetUpperLevel( 1 );
+            USHORT nSpace = 0;
+            for( n = 0; n < MAXLEVEL; ++n )
+            {
+                aFmt.SetAbsLSpace( nSpace += pArr[ n ] );
+                aFmt.SetFirstLineOffset( - pArr[ n ] );
+                aFmt.SetStartValue( n+1 );
+                pNewRule->Set( n, aFmt );
+            }
+        }
+        break;
+    case RES_POOLNUMRULE_NUM3:
+        {
+            SwNumFmt aFmt;
+            aFmt.eType = SVX_NUM_ARABIC;
+            aFmt.SetCharFmt( pNumCFmt );
+            aFmt.SetUpperLevel( 1 );
+            USHORT nOffs = GetMetricVal( CM_1 ) * 3;
+            aFmt.SetFirstLineOffset( - nOffs );
+
+            for( n = 0; n < MAXLEVEL; ++n )
+            {
+                aFmt.SetAbsLSpace( (n+1) * nOffs );
+                aFmt.SetStartValue( n+1 );
+                pNewRule->Set( n, aFmt );
+            }
+        }
+        break;
+    case RES_POOLNUMRULE_NUM4:
+        {
+            SwNumFmt aFmt;
+            aFmt.eType = SVX_NUM_ROMAN_UPPER;
+            aFmt.SetCharFmt( pNumCFmt );
+            aFmt.SetUpperLevel( 1 );
+            aFmt.SetPostfix( aDotStr );
+
+            static const USHORT aAbsSpace[ MAXLEVEL ] =
+                {
+//              cm: 0,5  1,0  1,5  2,0   2,5   3,0   3,5   4,0   4,5   5,0
+                    283, 567, 850, 1134, 1417, 1701, 1984, 2268, 2551, 2835
+                };
+#ifdef USE_MEASUREMENT
+            static const USHORT aAbsSpaceInch[ MAXLEVEL ] =
+                {
+                    283, 567, 850, 1134, 1417, 1701, 1984, 2268, 2551, 2835
+                };
+            const USHORT* pArr = MEASURE_METRIC == Application::
+                                GetAppInternational().GetMeasurementSystem()
+                                    ? aAbsSpace
+                                    : aAbsSpaceInch;
+#else
+            const USHORT* pArr = aAbsSpace;
+#endif
+
+            aFmt.SetFirstLineOffset( - (*pArr) );
+            for( n = 0; n < MAXLEVEL; ++n, ++pArr )
+            {
+                aFmt.SetStartValue( n + 1 );
+                aFmt.SetAbsLSpace( *pArr );
+                pNewRule->Set( n, aFmt );
+            }
+        }
+        break;
+    case RES_POOLNUMRULE_NUM5:
+        {
+            // [ First, LSpace ]
+            static const USHORT aAbsSpace0to2[] =
+                {
+                    227,  227,      // 0.40, 0.40,
+                    369,  624,      // 0.65, 1.10,
+                    255,  879       // 0.45, 1.55
+                };
+            static const USHORT aAbsSpaceInch0to2[] =
+                {
+                    308,  308,
+                    501,  847,
+                    347, 1194
+                };
+
+#ifdef USE_MEASUREMENT
+            const USHORT* pArr0to2 = MEASURE_METRIC == Application::
+                            GetAppInternational().GetMeasurementSystem()
+                                ? aAbsSpace0to2
+                                : aAbsSpaceInch0to2;
+#else
+            const USHORT* pArr0to2 = aAbsSpace0to2;
+#endif
+            SwNumFmt aFmt;
+            aFmt.eType = SVX_NUM_ARABIC;
+            aFmt.SetStartValue( 1 );
+            aFmt.SetUpperLevel( 1 );
+            aFmt.SetPostfix( aDotStr );
+            aFmt.SetFirstLineOffset( -pArr0to2[0] );    // == 0.40 cm
+            aFmt.SetAbsLSpace( pArr0to2[1] );           // == 0.40 cm
+
+            aFmt.SetCharFmt( pNumCFmt );
+            pNewRule->Set( 0, aFmt );
+
+            aFmt.SetUpperLevel( 2 );
+            aFmt.SetStartValue( 2 );
+            aFmt.SetFirstLineOffset( -pArr0to2[2] );    // == 0.65 cm
+            aFmt.SetAbsLSpace( pArr0to2[3] );           // == 1.10 cm
+            pNewRule->Set( 1, aFmt );
+
+            aFmt.eType = SVX_NUM_CHARS_LOWER_LETTER;
+            aFmt.SetPostfix( ')');
+            aFmt.SetUpperLevel( 1 );
+            aFmt.SetStartValue( 3 );
+            aFmt.SetFirstLineOffset( - pArr0to2[4] );   // == 0.45cm
+            aFmt.SetAbsLSpace( pArr0to2[5] );           // == 1.55 cm
+            pNewRule->Set( 2, aFmt );
+
+
+            aFmt.eType = SVX_NUM_CHAR_SPECIAL;
+            aFmt.SetCharFmt( pBullCFmt );
+            aFmt.SetBulletFont(  &SwNumRule::GetDefBulletFont() );
+            aFmt.SetBulletChar( cBulletChar );
+            USHORT nOffs = GetMetricVal( CM_01 ) * 4,
+                   nOffs2 = GetMetricVal( CM_1 ) * 2;
+
+            aFmt.SetFirstLineOffset( - nOffs );
+            aFmt.SetPostfix( aEmptyStr );
+            for( n = 3; n < MAXLEVEL; ++n )
+            {
+                aFmt.SetStartValue( n+1 );
+                aFmt.SetAbsLSpace( nOffs2 + ((n-3) * nOffs) );
+                pNewRule->Set( n, aFmt );
+            }
+        }
+        break;
+
+    case RES_POOLNUMRULE_BUL1:
+        {
+            SwNumFmt aFmt;
+            aFmt.eType = SVX_NUM_CHAR_SPECIAL;
+            aFmt.SetCharFmt( pBullCFmt );
+            aFmt.SetStartValue( 1 );
+            aFmt.SetUpperLevel( 1 );
+            aFmt.SetBulletFont( &SwNumRule::GetDefBulletFont() );
+            aFmt.SetBulletChar( cBulletChar );
+
+            static const USHORT aAbsSpace[ MAXLEVEL ] =
+                {
+//              cm: 0,4  0,8  1,2  1,6  2,0   2,4   2,8   3,2   3,6   4,0
+                    227, 454, 680, 907, 1134, 1361, 1587, 1814, 2041, 2268
+                };
+#ifdef USE_MEASUREMENT
+            static const USHORT aAbsSpaceInch[ MAXLEVEL ] =
+                {
+                    227, 454, 680, 907, 1134, 1361, 1587, 1814, 2041, 2268
+                };
+            const USHORT* pArr = MEASURE_METRIC == Application::
+                                GetAppInternational().GetMeasurementSystem()
+                                    ? aAbsSpace
+                                    : aAbsSpaceInch;
+#else
+            const USHORT* pArr = aAbsSpace;
+#endif
+
+            aFmt.SetFirstLineOffset( - (*pArr) );
+            for( n = 0; n < MAXLEVEL; ++n, ++pArr )
+            {
+                aFmt.SetAbsLSpace( *pArr );
+                pNewRule->Set( n, aFmt );
+            }
+        }
+        break;
+    case RES_POOLNUMRULE_BUL2:
+        {
+            SwNumFmt aFmt;
+            aFmt.eType = SVX_NUM_CHAR_SPECIAL;
+            aFmt.SetCharFmt( pBullCFmt );
+            aFmt.SetStartValue( 1 );
+            aFmt.SetUpperLevel( 1 );
+            aFmt.SetBulletFont(  &SwNumRule::GetDefBulletFont() );
+            aFmt.SetBulletChar( 0xF000 + 150 );
+
+            static const USHORT aAbsSpace[ MAXLEVEL ] =
+                {
+//              cm: 0,3  0,6  0,9  1,2  1,5  1,8   2,1   2,4   2,7   3,0
+                    170, 340, 510, 680, 850, 1020, 1191, 1361, 1531, 1701
+                };
+#ifdef USE_MEASUREMENT
+            static const USHORT aAbsSpaceInch[ MAXLEVEL ] =
+                {
+                    170, 340, 510, 680, 850, 1020, 1191, 1361, 1531, 1701
+                };
+            const USHORT* pArr = MEASURE_METRIC == Application::
+                                GetAppInternational().GetMeasurementSystem()
+                                    ? aAbsSpace
+                                    : aAbsSpaceInch;
+#else
+            const USHORT* pArr = aAbsSpace;
+#endif
+
+            aFmt.SetFirstLineOffset( - (*pArr) );
+            for( n = 0; n < MAXLEVEL; ++n, ++pArr )
+            {
+                aFmt.SetAbsLSpace( *pArr );
+                pNewRule->Set( n, aFmt );
+            }
+        }
+        break;
+    case RES_POOLNUMRULE_BUL3:
+        {
+            SwNumFmt aFmt;
+            aFmt.eType = SVX_NUM_CHAR_SPECIAL;
+            aFmt.SetCharFmt( pBullCFmt );
+            aFmt.SetStartValue( 1 );
+            aFmt.SetUpperLevel( 1 );
+            aFmt.SetBulletFont(  &SwNumRule::GetDefBulletFont() );
+            USHORT nOffs = GetMetricVal( CM_01 ) * 4;
+            aFmt.SetFirstLineOffset( - nOffs );
+
+            for( n = 0; n < MAXLEVEL; ++n )
+            {
+                aFmt.SetBulletChar( 0xF000 + ( n & 1 ? 37 : 52 ) );
+                aFmt.SetAbsLSpace( ((n & 1) +1) * nOffs );
+                pNewRule->Set( n, aFmt );
+            }
+        }
+        break;
+    case RES_POOLNUMRULE_BUL4:
+        {
+            SwNumFmt aFmt;
+            aFmt.eType = SVX_NUM_CHAR_SPECIAL;
+            aFmt.SetCharFmt( pBullCFmt );
+            aFmt.SetStartValue( 1 );
+            aFmt.SetUpperLevel( 1 );
+            aFmt.SetBulletFont(  &SwNumRule::GetDefBulletFont() );
+
+            static const USHORT aAbsSpace[ MAXLEVEL ] =
+                {
+//              cm: 0,4  0,8  1,2  1,6  2,0   2,4   2,8   3,2   3,6   4,0
+                    227, 454, 680, 907, 1134, 1361, 1587, 1814, 2041, 2268
+                };
+#ifdef USE_MEASUREMENT
+            static const USHORT aAbsSpaceInch[ MAXLEVEL ] =
+                {
+                    227, 454, 680, 907, 1134, 1361, 1587, 1814, 2041, 2268
+                };
+            const USHORT* pArr = MEASURE_METRIC == Application::
+                                GetAppInternational().GetMeasurementSystem()
+                                    ? aAbsSpace
+                                    : aAbsSpaceInch;
+#else
+            const USHORT* pArr = aAbsSpace;
+#endif
+
+            aFmt.SetFirstLineOffset( - (*pArr) );
+            for( n = 0; n < MAXLEVEL; ++n, ++pArr )
+            {
+                switch( n )
+                {
+                case 0:     aFmt.SetBulletChar( 0xF000 + 47 );  break;
+                case 1:     aFmt.SetBulletChar( 0xF000 + 48 );  break;
+                default:    aFmt.SetBulletChar( 0xF000 + 45 );  break;
+                }
+                aFmt.SetAbsLSpace( *pArr );
+                pNewRule->Set( n, aFmt );
+            }
+        }
+        break;
+    case RES_POOLNUMRULE_BUL5:
+        {
+            SwNumFmt aFmt;
+            aFmt.eType = SVX_NUM_CHAR_SPECIAL;
+            aFmt.SetCharFmt( pBullCFmt );
+            aFmt.SetStartValue( 1 );
+            aFmt.SetUpperLevel( 1 );
+            aFmt.SetBulletChar( 0xF000 + 79 );
+            aFmt.SetBulletFont(  &SwNumRule::GetDefBulletFont() );
+
+            static const USHORT aAbsSpace[ MAXLEVEL ] =
+                {
+//              cm: 0,4  0,8  1,2  1,6  2,0   2,4   2,8   3,2   3,6   4,0
+                    227, 454, 680, 907, 1134, 1361, 1587, 1814, 2041, 2268
+                };
+#ifdef USE_MEASUREMENT
+            static const USHORT aAbsSpaceInch[ MAXLEVEL ] =
+                {
+                    227, 454, 680, 907, 1134, 1361, 1587, 1814, 2041, 2268
+                };
+            const USHORT* pArr = MEASURE_METRIC == Application::
+                                GetAppInternational().GetMeasurementSystem()
+                                    ? aAbsSpace
+                                    : aAbsSpaceInch;
+#else
+            const USHORT* pArr = aAbsSpace;
+#endif
+
+            aFmt.SetFirstLineOffset( - (*pArr) );
+            for( n = 0; n < MAXLEVEL; ++n, ++pArr )
+            {
+                aFmt.SetAbsLSpace( *pArr );
+                pNewRule->Set( n, aFmt );
+            }
+        }
+        break;
+    }
+
+    if( pDesc )
+    {
+//JP 25.02.98: wie soll die Beschreibung sein??
+//      String aStr;
+//      aSet.GetPresentation( ePres, eCoreMetric, ePresMetric, aStr );
+//      *pDesc += sKomma;
+//      *pDesc += aStr;
+
+        delete pNewRule, pNewRule = 0;
+    }
+
+    return pNewRule;
+}
+
+
+
+    // pruefe, ob diese "Auto-Collection" in Dokument schon/noch
+    // benutzt wird
+BOOL SwDoc::IsPoolPageDescUsed( USHORT nId ) const
+{
+    ASSERT( RES_POOLPAGE_BEGIN <= nId && nId < RES_POOLPAGE_END,
+            "Falsche AutoFormat-Id" );
+    SwPageDesc *pNewPgDsc;
+    BOOL bFnd = FALSE;
+    for( USHORT n = 0; !bFnd && n < aPageDescs.Count(); ++n )
+        if( nId == ( pNewPgDsc = aPageDescs[ n ] )->GetPoolFmtId() )
+            bFnd = TRUE;
+
+    // nicht gefunden oder keine Abhaengigen ?
+    if( !bFnd || !pNewPgDsc->GetDepends() )     // ??????
+        return FALSE;
+
+    // dann teste mal, ob es abhaengige ContentNodes im Nodes Array gibt
+    // (auch indirekte fuer Format-Ableitung! )
+    SwAutoFmtGetDocNode aGetHt( &aNodes );
+    return !pNewPgDsc->GetInfo( aGetHt );
+}
+
+    // pruefe, ob diese "Auto-Collection" in Dokument schon/noch
+    // benutzt wird
+BOOL SwDoc::IsPoolNumRuleUsed( USHORT nId ) const
+{
+    ASSERT( RES_POOLNUMRULE_BEGIN <= nId && nId < RES_POOLNUMRULE_END,
+            "Falsche AutoFormat-Id" );
+    SwNumRule *pNewRule;
+    BOOL bUsed = FALSE;
+    for( USHORT n = 0; n < GetNumRuleTbl().Count(); ++n )
+        if( nId == ( pNewRule = GetNumRuleTbl()[ n ] )->GetPoolFmtId() )
+        {
+            bUsed = IsUsed( *pNewRule );
+            break;
+        }
+    return bUsed;
+}
+
+
+
+// erfrage ob die Absatz-/Zeichen-/Rahmen-/Seiten - Vorlage benutzt wird
+BOOL SwDoc::IsUsed( const SwModify& rModify ) const
+{
+    // dann teste mal, ob es abhaengige ContentNodes im Nodes Array gibt
+    // (auch indirekte fuer Format-Ableitung! )
+    SwAutoFmtGetDocNode aGetHt( &aNodes );
+    return !rModify.GetInfo( aGetHt );
+}
+
+// erfrage ob die NumRule benutzt wird
+BOOL SwDoc::IsUsed( const SwNumRule& rRule ) const
+{
+    // dann teste mal, ob es abhaengige ContentNodes im Nodes Array gibt
+    // (auch indirekte fuer Format-Ableitung! )
+    BOOL bUsed = FALSE;
+    SwAutoFmtGetDocNode aGetHt( &aNodes );
+    SwModify* pMod;
+    const SfxPoolItem* pItem;
+    USHORT i, nMaxItems = GetAttrPool().GetItemCount( RES_PARATR_NUMRULE);
+    for( i = 0; i < nMaxItems; ++i )
+        if( 0 != (pItem = GetAttrPool().GetItem( RES_PARATR_NUMRULE, i ) ) &&
+            0 != ( pMod = (SwModify*)((SwNumRuleItem*)pItem)->GetDefinedIn()) &&
+            ((SwNumRuleItem*)pItem)->GetValue().Len() &&
+            ((SwNumRuleItem*)pItem)->GetValue() == rRule.GetName() )
+        {
+            if( pMod->IsA( TYPE( SwFmt )) )
+            {
+                bUsed = !pMod->GetInfo( aGetHt );
+                if( bUsed )
+                    break;
+            }
+            else if( ((SwTxtNode*)pMod)->GetNodes().IsDocNodes() )
+            {
+                bUsed = TRUE;
+                break;
+            }
+        }
+
+    return bUsed;
+}
+
+
+// erfrage zu einer PoolId den Namen
+String& GetDocPoolNm( USHORT nId, String& rFillNm )
+{
+    return SwDoc::GetPoolNm( nId, rFillNm );
+}
+
+// erfrage zu einer PoolId den Namen
+String& SwDoc::GetPoolNm( USHORT nId, String& rFillNm )
+{
+    USHORT nRC = 0, nStt = 0, nEnd = 0;
+    SvStringsDtor** ppStrArr = 0;
+
+    switch( (USER_FMT | COLL_GET_RANGE_BITS | POOLGRP_NOCOLLID) & nId )
+    {
+    case COLL_TEXT_BITS:
+        if( RES_POOLCOLL_TEXT_BEGIN <= nId && nId < RES_POOLCOLL_TEXT_END )
+        {
+            ppStrArr = &SwDoc::pTextNmArray;
+            nRC = RC_POOLCOLL_TEXT_BEGIN;
+            nStt = RES_POOLCOLL_TEXT_BEGIN;
+            nEnd = RES_POOLCOLL_TEXT_END;
+        }
+        break;
+    case COLL_LISTS_BITS:
+        if( RES_POOLCOLL_LISTS_BEGIN <= nId && nId < RES_POOLCOLL_LISTS_END )
+        {
+            ppStrArr = &SwDoc::pListsNmArray;
+            nRC = RC_POOLCOLL_LISTS_BEGIN;
+            nStt = RES_POOLCOLL_LISTS_BEGIN;
+            nEnd = RES_POOLCOLL_LISTS_END;
+        }
+        break;
+    case COLL_EXTRA_BITS:
+        if( RES_POOLCOLL_EXTRA_BEGIN <= nId && nId < RES_POOLCOLL_EXTRA_END )
+        {
+            ppStrArr = &SwDoc::pExtraNmArray;
+            nRC = RC_POOLCOLL_EXTRA_BEGIN;
+            nStt = RES_POOLCOLL_EXTRA_BEGIN;
+            nEnd = RES_POOLCOLL_EXTRA_END;
+        }
+        break;
+    case COLL_REGISTER_BITS:
+        if( RES_POOLCOLL_REGISTER_BEGIN <= nId && nId < RES_POOLCOLL_REGISTER_END )
+        {
+            ppStrArr = &SwDoc::pRegisterNmArray;
+            nRC = RC_POOLCOLL_REGISTER_BEGIN;
+            nStt = RES_POOLCOLL_REGISTER_BEGIN;
+            nEnd = RES_POOLCOLL_REGISTER_END;
+        }
+        break;
+    case COLL_DOC_BITS:
+        if( RES_POOLCOLL_DOC_BEGIN <= nId && nId < RES_POOLCOLL_DOC_END )
+        {
+            ppStrArr = &SwDoc::pDocNmArray;
+            nRC = RC_POOLCOLL_DOC_BEGIN;
+            nStt = RES_POOLCOLL_DOC_BEGIN;
+            nEnd = RES_POOLCOLL_DOC_END;
+        }
+        break;
+    case COLL_HTML_BITS:
+        if( RES_POOLCOLL_HTML_BEGIN <= nId && nId < RES_POOLCOLL_HTML_END )
+        {
+            ppStrArr = &SwDoc::pHTMLNmArray;
+            nRC = RC_POOLCOLL_HTML_BEGIN;
+            nStt = RES_POOLCOLL_HTML_BEGIN;
+            nEnd = RES_POOLCOLL_HTML_END;
+        }
+        break;
+    case POOLGRP_CHARFMT:
+        if( RES_POOLCHR_NORMAL_BEGIN <= nId && nId < RES_POOLCHR_NORMAL_END )
+        {
+            ppStrArr = &SwDoc::pChrFmtNmArray;
+            nRC = RC_POOLCHRFMT_BEGIN;
+            nStt = RES_POOLCHR_NORMAL_BEGIN;
+            nEnd = RES_POOLCHR_NORMAL_END;
+        }
+        else if( RES_POOLCHR_HTML_BEGIN <= nId && nId < RES_POOLCHR_HTML_END )
+        {
+            ppStrArr = &SwDoc::pHTMLChrFmtNmArray;
+            nRC = RC_POOLCHRFMT_HTML_BEGIN;
+            nStt = RES_POOLCHR_HTML_BEGIN;
+            nEnd = RES_POOLCHR_HTML_END;
+        }
+        break;
+    case POOLGRP_FRAMEFMT:
+        if( RES_POOLFRM_BEGIN <= nId && nId < RES_POOLFRM_END )
+        {
+            ppStrArr = &SwDoc::pFrmFmtNmArray;
+            nRC = RC_POOLFRMFMT_BEGIN;
+            nStt = RES_POOLFRM_BEGIN;
+            nEnd = RES_POOLFRM_END;
+        }
+        break;
+    case POOLGRP_PAGEDESC:
+        if( RES_POOLPAGE_BEGIN <= nId && nId < RES_POOLPAGE_END )
+        {
+            ppStrArr = &SwDoc::pPageDescNmArray;
+            nRC = RC_POOLPAGEDESC_BEGIN;
+            nStt = RES_POOLPAGE_BEGIN;
+            nEnd = RES_POOLPAGE_END;
+        }
+        break;
+    case POOLGRP_NUMRULE:
+        if( RES_POOLNUMRULE_BEGIN <= nId && nId < RES_POOLNUMRULE_END )
+        {
+            ppStrArr = &SwDoc::pNumRuleNmArray;
+            nRC = RC_POOLNUMRULE_BEGIN;
+            nStt = RES_POOLNUMRULE_BEGIN;
+            nEnd = RES_POOLNUMRULE_END;
+        }
+        break;
+    }
+
+    if( ppStrArr )
+    {
+        if( !*ppStrArr )
+            SwDoc::NewNmArray( *ppStrArr, nRC, (nRC - nStt + nEnd ));
+        rFillNm = * (*ppStrArr)->operator[]( nId - nStt );
+    }
+//JP 13.04.95: soll der Name geloescht werden?
+//              erstmal bleibt er erhalten
+//  else
+//      rFillNm.Erase();
+    return rFillNm;
+}
+
+
+
+
+    // loeche die nicht mehr benutzten Pattern-Namen aus dem Array.
+    // alle nicht mehr referenzierten Namen werden durch 0-Pointer
+    // ersetzt. Diese Positionen koennen wieder vergeben werden.
+void SwDoc::ReOrgPatternHelpIds()
+{
+#if defined( MAC ) || defined( UNX )
+    const SvPtrarr* pFmtArray[ 3 ];
+    pFmtArray[ 0 ] = pCharFmtTbl;       pFmtArray[ 1 ] = pFrmFmtTbl;
+    pFmtArray[ 2 ] = pSpzFrmFmtTbl;
+#else
+    const SvPtrarr* pFmtArray[ 3 ] = {
+        pCharFmtTbl,        pFrmFmtTbl,     pSpzFrmFmtTbl
+        };
+#endif
+
+
+    USHORT i, n, nFmt;
+    for( n = 0; n < aPatternNms.Count(); ++n )
+    {
+        BOOL bFnd = FALSE;
+        // suche im Absatz-Vorlagen Array
+        for( nFmt = 0; !bFnd && nFmt < pTxtFmtCollTbl->Count(); ++nFmt )
+            if( n == (*pTxtFmtCollTbl)[ nFmt ]->GetPoolHlpFileId() )
+                bFnd = TRUE;
+
+        // suche im Format-Vorlagen Array
+        for( i = 0; !bFnd && i < 3; ++i )
+        {
+            const SvPtrarr* pArr = *(pFmtArray + i);
+            for( nFmt = 0; !bFnd && nFmt < pArr->Count(); ++nFmt )
+                if( n == ((SwFmt*)(*pArr)[ nFmt ])->GetPoolHlpFileId() )
+                    bFnd = TRUE;
+        }
+        // suche im Format-Vorlagen Array
+        for( nFmt = 0; !bFnd && nFmt < aPageDescs.Count(); ++nFmt )
+            if( n == aPageDescs[ nFmt ]->GetPoolHlpFileId() )
+                bFnd = TRUE;
+
+        if( !bFnd )
+        {
+            // losche den alten String, setze die Position auf 0
+            aPatternNms.DeleteAndDestroy( n+1 );
+            String* pNull = 0;
+            aPatternNms.Insert( pNull, n );
+        }
+    }
+}
+
+
+
+    // Suche die Position vom Vorlagen-Namen. Ist nicht vorhanden
+    // dann fuege neu ein
+USHORT SwDoc::SetDocPattern( const String& rPatternName )
+{
+    ASSERT( rPatternName.Len(), "kein Dokument-Vorlagenname" );
+
+    USHORT nNewPos = aPatternNms.Count();
+    for( USHORT n = 0; n < aPatternNms.Count(); ++n )
+        if( !aPatternNms[n] )
+        {
+            if( nNewPos == aPatternNms.Count() )
+                nNewPos = n;
+        }
+        else if( rPatternName == *aPatternNms[n] )
+            return n;
+
+    if( nNewPos < aPatternNms.Count() )
+        aPatternNms.Remove( nNewPos );      // Platz wieder frei machen
+
+    String* pNewNm = new String( rPatternName );
+    aPatternNms.Insert( pNewNm, nNewPos );
+    SetModified();
+    return nNewPos;
+}
+
+        // ist der Name ein Pool-Vorlagen-Name, returne seine ID,
+        // sonst USHRT_MAX
+
+
+// falls mit gechacht werden soll:
+USHORT lcl_ChkNm( USHORT nStt, USHORT nEnd, USHORT nResStt,
+                    const String& rName, SvStringsDtor*& pArray )
+{
+    USHORT n, i;
+    if( !pArray )
+    {
+        USHORT nFnd = 0;
+        pArray = new SvStringsDtor( BYTE(nEnd - nStt), 1 );
+        for( n = nStt, i = 0; n < nEnd; ++n, ++i )
+        {
+            const ResId rRId( nResStt + i, pSwResMgr );
+            String* pStr = new String( rRId );
+            pArray->Insert( pStr, i );
+            if( !nFnd && *pStr == rName )
+                nFnd = n;
+        }
+        return nFnd ? nFnd : USHRT_MAX;
+    }
+
+    for( n = nStt, i = 0; n < nEnd; ++n, ++i )
+        if( *(*pArray)[i] == rName )
+            return n;
+
+    return USHRT_MAX;
+}
+
+
+
+USHORT SwDoc::GetPoolId( const String& rName,
+                        SwGetPoolIdFromName eFlags ) const
+{
+    USHORT nId;
+    if( GET_POOLID_TXTCOLL & eFlags )
+    {
+        if( USHRT_MAX != ( nId = lcl_ChkNm( RES_POOLCOLL_TEXT_BEGIN,
+                RES_POOLCOLL_TEXT_END, RC_POOLCOLL_TEXT_BEGIN, rName,
+                SwDoc::pTextNmArray )))
+            return nId;
+        if( USHRT_MAX != ( nId = lcl_ChkNm( RES_POOLCOLL_LISTS_BEGIN,
+                RES_POOLCOLL_LISTS_END, RC_POOLCOLL_LISTS_BEGIN, rName,
+                SwDoc::pListsNmArray )))
+            return nId;
+        if( USHRT_MAX != ( nId = lcl_ChkNm( RES_POOLCOLL_EXTRA_BEGIN,
+                RES_POOLCOLL_EXTRA_END, RC_POOLCOLL_EXTRA_BEGIN, rName,
+                SwDoc::pExtraNmArray )))
+            return nId;
+        if( USHRT_MAX != ( nId = lcl_ChkNm( RES_POOLCOLL_REGISTER_BEGIN,
+                RES_POOLCOLL_REGISTER_END, RC_POOLCOLL_REGISTER_BEGIN, rName,
+                SwDoc::pRegisterNmArray )))
+            return nId;
+        if( USHRT_MAX != ( nId = lcl_ChkNm( RES_POOLCOLL_DOC_BEGIN,
+                RES_POOLCOLL_DOC_END, RC_POOLCOLL_DOC_BEGIN, rName,
+                SwDoc::pDocNmArray )))
+            return nId;
+        if( USHRT_MAX != ( nId = lcl_ChkNm( RES_POOLCOLL_HTML_BEGIN,
+                RES_POOLCOLL_HTML_END, RC_POOLCOLL_HTML_BEGIN, rName,
+                SwDoc::pHTMLNmArray )))
+            return nId;
+    }
+
+    if( GET_POOLID_CHRFMT & eFlags )
+    {
+        if( USHRT_MAX != ( nId = lcl_ChkNm( RES_POOLCHR_NORMAL_BEGIN,
+                RES_POOLCHR_NORMAL_END, RC_POOLCHRFMT_BEGIN, rName,
+                SwDoc::pChrFmtNmArray )))
+            return nId;
+        if( USHRT_MAX != ( nId = lcl_ChkNm( RES_POOLCHR_HTML_BEGIN,
+                RES_POOLCHR_HTML_END, RC_POOLCHRFMT_HTML_BEGIN, rName,
+                SwDoc::pHTMLChrFmtNmArray )))
+            return nId;
+    }
+    if( GET_POOLID_FRMFMT & eFlags &&
+        USHRT_MAX != ( nId = lcl_ChkNm( RES_POOLFRM_BEGIN,
+                RES_POOLFRM_END, RC_POOLFRMFMT_BEGIN, rName,
+                SwDoc::pFrmFmtNmArray )))
+            return nId;
+
+    if( GET_POOLID_PAGEDESC & eFlags &&
+        USHRT_MAX != ( nId = lcl_ChkNm( RES_POOLPAGE_BEGIN,
+                RES_POOLPAGE_END, RC_POOLPAGEDESC_BEGIN, rName,
+                SwDoc::pPageDescNmArray )))
+            return nId;
+
+    if( GET_POOLID_NUMRULE & eFlags &&
+        USHRT_MAX != ( nId = lcl_ChkNm( RES_POOLNUMRULE_BEGIN,
+                RES_POOLNUMRULE_END, RC_POOLNUMRULE_BEGIN, rName,
+                SwDoc::pNumRuleNmArray )))
+            return nId;
+
+    return USHRT_MAX;
+}
+
+
+
+
+
+SvStringsDtor* SwDoc::NewNmArray( SvStringsDtor*& pNmArray, USHORT nStt, USHORT nEnd )
+{
+    if( !pNmArray )
+    {
+        pNmArray = new SvStringsDtor( BYTE(nEnd - nStt), 1 );
+        while( nStt < nEnd )
+        {
+            const ResId rRId( nStt, pSwResMgr );
+            String* pStr = new String( rRId );
+            pNmArray->Insert( pStr, pNmArray->Count() );
+            ++nStt;
+        }
+    }
+    return pNmArray;
+}
+
+
+
+SvStringsDtor* SwDoc::NewTextNmArray() const
+{
+    return NewNmArray( pTextNmArray, RC_POOLCOLL_TEXT_BEGIN,
+            ( RC_POOLCOLL_TEXT_BEGIN +
+                    (RES_POOLCOLL_TEXT_END - RES_POOLCOLL_TEXT_BEGIN )) );
+}
+
+
+
+SvStringsDtor* SwDoc::NewListsNmArray() const
+{
+    return NewNmArray( pListsNmArray, RC_POOLCOLL_LISTS_BEGIN,
+            ( RC_POOLCOLL_LISTS_BEGIN +
+                    (RES_POOLCOLL_LISTS_END - RES_POOLCOLL_LISTS_BEGIN )) );
+}
+
+
+
+SvStringsDtor* SwDoc::NewExtraNmArray() const
+{
+    return NewNmArray( pExtraNmArray, RC_POOLCOLL_EXTRA_BEGIN,
+                ( RC_POOLCOLL_EXTRA_BEGIN +
+                    (RES_POOLCOLL_EXTRA_END - RES_POOLCOLL_EXTRA_BEGIN )) );
+}
+
+
+
+SvStringsDtor* SwDoc::NewRegisterNmArray() const
+{
+    return NewNmArray( pRegisterNmArray, RC_POOLCOLL_REGISTER_BEGIN,
+            ( RC_POOLCOLL_REGISTER_BEGIN +
+                (RES_POOLCOLL_REGISTER_END - RES_POOLCOLL_REGISTER_BEGIN )) );
+}
+
+
+
+SvStringsDtor* SwDoc::NewDocNmArray() const
+{
+    return NewNmArray( pDocNmArray, RC_POOLCOLL_DOC_BEGIN,
+                    ( RC_POOLCOLL_DOC_BEGIN +
+                        (RES_POOLCOLL_DOC_END - RES_POOLCOLL_DOC_BEGIN )) );
+}
+
+
+
+SvStringsDtor* SwDoc::NewHTMLNmArray() const
+{
+    return NewNmArray( pHTMLNmArray, RC_POOLCOLL_HTML_BEGIN,
+                    ( RC_POOLCOLL_HTML_BEGIN +
+                        (RES_POOLCOLL_HTML_END - RES_POOLCOLL_HTML_BEGIN )) );
+}
+
+
+
+SvStringsDtor* SwDoc::NewFrmFmtNmArray() const
+{
+    return NewNmArray( pFrmFmtNmArray, RC_POOLFRMFMT_BEGIN,
+                    ( RC_POOLFRMFMT_BEGIN +
+                        (RES_POOLFRM_END - RES_POOLFRM_BEGIN )) );
+}
+
+
+
+
+SvStringsDtor* SwDoc::NewChrFmtNmArray() const
+{
+    return NewNmArray( pChrFmtNmArray, RC_POOLCHRFMT_BEGIN,
+            ( RC_POOLCHRFMT_BEGIN +
+                    (RES_POOLCHR_NORMAL_END - RES_POOLCHR_NORMAL_BEGIN )) );
+}
+
+
+
+SvStringsDtor* SwDoc::NewHTMLChrFmtNmArray() const
+{
+    return NewNmArray( pHTMLChrFmtNmArray, RC_POOLCHRFMT_HTML_BEGIN,
+            ( RC_POOLCHRFMT_HTML_BEGIN +
+                    (RES_POOLCHR_HTML_END - RES_POOLCHR_HTML_BEGIN )) );
+}
+
+
+
+SvStringsDtor* SwDoc::NewPageDescNmArray() const
+{
+    return NewNmArray( pPageDescNmArray, RC_POOLPAGEDESC_BEGIN,
+            ( RC_POOLPAGEDESC_BEGIN +
+                    (RES_POOLPAGE_END - RES_POOLPAGE_BEGIN )) );
+}
+
+SvStringsDtor* SwDoc::NewNumRuleNmArray() const
+{
+    return NewNmArray( pNumRuleNmArray, RC_POOLNUMRULE_BEGIN,
+            ( RC_POOLNUMRULE_BEGIN +
+                    (RES_POOLNUMRULE_END - RES_POOLNUMRULE_BEGIN )) );
+}
+
+
+
+USHORT GetPoolParent( USHORT nId )
+{
+    USHORT nRet = USHRT_MAX;
+    if( POOLGRP_NOCOLLID & nId )        // 1 == Formate / 0 == Collections
+    {
+        switch( ( COLL_GET_RANGE_BITS | POOLGRP_NOCOLLID ) & nId )
+        {
+        case POOLGRP_CHARFMT:
+        case POOLGRP_FRAMEFMT:
+            nRet = 0;           // vom default abgeleitet
+            break;
+        case POOLGRP_PAGEDESC:
+        case POOLGRP_NUMRULE:
+            break;              // es gibt keine Ableitung
+        }
+    }
+    else
+    {
+        switch( COLL_GET_RANGE_BITS & nId )
+        {
+        case COLL_TEXT_BITS:
+            switch( nId )
+            {
+            case RES_POOLCOLL_STANDARD:
+                    nRet = 0;                                   break;
+            case RES_POOLCOLL_TEXT_IDENT:
+            case RES_POOLCOLL_TEXT_NEGIDENT:
+            case RES_POOLCOLL_TEXT_MOVE:
+            case RES_POOLCOLL_CONFRONTATION:
+            case RES_POOLCOLL_MARGINAL:
+                    nRet = RES_POOLCOLL_TEXT;                   break;
+
+            case RES_POOLCOLL_TEXT:
+            case RES_POOLCOLL_GREETING:
+            case RES_POOLCOLL_SIGNATURE:
+            case RES_POOLCOLL_HEADLINE_BASE:
+                    nRet = RES_POOLCOLL_STANDARD;               break;
+
+            case RES_POOLCOLL_HEADLINE1:
+            case RES_POOLCOLL_HEADLINE2:
+            case RES_POOLCOLL_HEADLINE3:
+            case RES_POOLCOLL_HEADLINE4:
+            case RES_POOLCOLL_HEADLINE5:
+            case RES_POOLCOLL_HEADLINE6:
+            case RES_POOLCOLL_HEADLINE7:
+            case RES_POOLCOLL_HEADLINE8:
+            case RES_POOLCOLL_HEADLINE9:
+            case RES_POOLCOLL_HEADLINE10:
+                    nRet = RES_POOLCOLL_HEADLINE_BASE;          break;
+            }
+            break;
+
+        case COLL_LISTS_BITS:
+            switch( nId )
+            {
+            case RES_POOLCOLL_NUMBUL_BASE:
+                    nRet = RES_POOLCOLL_TEXT;                   break;
+
+            default:
+                nRet = RES_POOLCOLL_NUMBUL_BASE;                break;
+            }
+            break;
+
+        case COLL_EXTRA_BITS:
+            switch( nId )
+            {
+            case RES_POOLCOLL_FRAME:
+            case RES_POOLCOLL_TABLE:
+                    nRet = RES_POOLCOLL_TEXT;                   break;
+
+            case RES_POOLCOLL_TABLE_HDLN:
+                    nRet = RES_POOLCOLL_TABLE;                  break;
+
+            case RES_POOLCOLL_FOOTNOTE:
+            case RES_POOLCOLL_ENDNOTE:
+            case RES_POOLCOLL_JAKETADRESS:
+            case RES_POOLCOLL_SENDADRESS:
+            case RES_POOLCOLL_HEADER:
+            case RES_POOLCOLL_HEADERL:
+            case RES_POOLCOLL_HEADERR:
+            case RES_POOLCOLL_FOOTER:
+            case RES_POOLCOLL_FOOTERL:
+            case RES_POOLCOLL_FOOTERR:
+            case RES_POOLCOLL_LABEL:
+                    nRet = RES_POOLCOLL_STANDARD;               break;
+
+            case RES_POOLCOLL_LABEL_ABB:
+            case RES_POOLCOLL_LABEL_TABLE:
+            case RES_POOLCOLL_LABEL_FRAME:
+            case RES_POOLCOLL_LABEL_DRAWING:
+                    nRet = RES_POOLCOLL_LABEL;                  break;
+            }
+            break;
+
+        case COLL_REGISTER_BITS:
+            switch( nId )
+            {
+            case RES_POOLCOLL_REGISTER_BASE:
+                    nRet = RES_POOLCOLL_STANDARD;               break;
+
+            case RES_POOLCOLL_TOX_USERH:
+            case RES_POOLCOLL_TOX_CNTNTH:
+            case RES_POOLCOLL_TOX_IDXH:
+            case RES_POOLCOLL_TOX_ILLUSH:
+            case RES_POOLCOLL_TOX_OBJECTH:
+            case RES_POOLCOLL_TOX_TABLESH:
+            case RES_POOLCOLL_TOX_AUTHORITIESH:
+                    nRet = RES_POOLCOLL_HEADLINE_BASE;          break;
+
+            default:
+                    nRet = RES_POOLCOLL_REGISTER_BASE;          break;
+            }
+            break;
+
+        case COLL_DOC_BITS:
+            nRet = RES_POOLCOLL_HEADLINE_BASE;
+            break;
+
+        case COLL_HTML_BITS:
+            nRet = RES_POOLCOLL_STANDARD;
+            break;
+        }
+    }
+
+    return nRet;
+}
+
+
diff --git a/sw/source/core/doc/sortopt.cxx b/sw/source/core/doc/sortopt.cxx
new file mode 100644
index 000000000000..25b34bf95418
--- /dev/null
+++ b/sw/source/core/doc/sortopt.cxx
@@ -0,0 +1,134 @@
+/*************************************************************************
+ *
+ *  $RCSfile: sortopt.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:16 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _TOOLS_DEBUG_HXX //autogen
+#include 
+#endif
+#include "sortopt.hxx"
+
+
+SV_IMPL_PTRARR(SwSortKeys, SwSortKey*)
+
+/*--------------------------------------------------------------------
+    Beschreibung:   Sortier-Schluessel
+ --------------------------------------------------------------------*/
+
+SwSortKey::SwSortKey() :
+    eSortKeyType(SRT_APLHANUM),
+    eSortOrder(SRT_ASCENDING),
+    nColumnId(0)
+{
+}
+
+
+SwSortKey::SwSortKey(USHORT nId, SwSortKeyType eTyp, SwSortOrder eOrder) :
+    eSortOrder(eOrder),
+    eSortKeyType(eTyp),
+    nColumnId(nId)
+{
+}
+
+
+SwSortKey::SwSortKey(const SwSortKey& rOld) :
+    eSortOrder(rOld.eSortOrder),
+    eSortKeyType(rOld.eSortKeyType),
+    nColumnId(rOld.nColumnId)
+{
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Sortieroptionen fuers Sortieren
+ --------------------------------------------------------------------*/
+
+
+SwSortOptions::SwSortOptions() :
+    eDirection(SRT_ROWS),
+    nDeli(9),
+    bTable(FALSE)
+{
+}
+
+
+SwSortOptions::SwSortOptions(const SwSortOptions& rOpt) :
+    eDirection(rOpt.eDirection),
+    nDeli(rOpt.nDeli),
+    bTable(rOpt.bTable)
+{
+    for(USHORT i=0; i < rOpt.aKeys.Count(); ++i)
+    {   SwSortKey* pNew = new SwSortKey(*rOpt.aKeys[i]);
+        aKeys.C40_INSERT( SwSortKey, pNew, aKeys.Count());
+    }
+}
+
+
+SwSortOptions::~SwSortOptions()
+{
+    aKeys.DeleteAndDestroy(0, aKeys.Count());
+}
+
+
+
diff --git a/sw/source/core/doc/swserv.cxx b/sw/source/core/doc/swserv.cxx
new file mode 100644
index 000000000000..72b54367e834
--- /dev/null
+++ b/sw/source/core/doc/swserv.cxx
@@ -0,0 +1,419 @@
+/*************************************************************************
+ *
+ *  $RCSfile: swserv.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:16 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _SVSTOR_HXX //autogen
+#include 
+#endif
+#ifndef _SVXLINKMGR_HXX
+#include 
+#endif
+
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _SWTYPES_HXX
+#include 
+#endif
+#ifndef _SWSERV_HXX
+#include 
+#endif
+#ifndef _SWBASLNK_HXX
+#include 
+#endif
+#ifndef _MVSAVE_HXX
+#include 
+#endif
+#ifndef _BOOKMRK_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _NODE_HXX
+#include 
+#endif
+#ifndef _SHELLIO_HXX
+#include 
+#endif
+
+#ifndef _SWERROR_H
+#include 
+#endif
+
+
+SO2_IMPL_REF( SwServerObject )
+
+
+SwServerObject::~SwServerObject()
+{
+}
+
+
+BOOL SwServerObject::GetData( SvData* pData )
+{
+    BOOL bRet = FALSE;
+    WriterRef xWrt;
+    switch( pData->GetFormat() )
+    {
+    case FORMAT_STRING:
+        ::GetASCWriter( aEmptyStr, xWrt );
+        break;
+
+    case FORMAT_RTF:
+        ::GetRTFWriter( aEmptyStr, xWrt );
+        break;
+    }
+
+    if( !xWrt.Is() )
+        return FALSE;
+
+    SwPaM* pPam = 0;
+    switch( eType )
+    {
+    case BOOKMARK_SERVER:
+        if( CNTNT_TYPE.pBkmk->GetOtherPos() )
+        {
+            // Bereich aufspannen
+            pPam = new SwPaM( CNTNT_TYPE.pBkmk->GetPos(),
+                            *CNTNT_TYPE.pBkmk->GetOtherPos() );
+        }
+        break;
+
+    case TABLE_SERVER:
+        pPam = new SwPaM( *CNTNT_TYPE.pTblNd,
+                         *CNTNT_TYPE.pTblNd->EndOfSectionNode() );
+        break;
+
+    case SECTION_SERVER:
+        {
+            pPam = new SwPaM( SwPosition( *CNTNT_TYPE.pSectNd ) );
+            pPam->Move( fnMoveForward );
+            pPam->SetMark();
+            pPam->GetPoint()->nNode = *CNTNT_TYPE.pSectNd->EndOfSectionNode();
+            pPam->Move( fnMoveBackward );
+        }
+        break;
+    }
+
+    if( pPam )
+    {
+        // Stream anlegen
+        SvStorageStreamRef aStrm = new SvStorageStream( aEmptyStr );
+        SwWriter aWrt( *aStrm, *pPam, FALSE );
+        if( !IsError( aWrt.Write( xWrt )) )
+        {
+            *aStrm << '\0';     // fuers SvData bei mit 0 terminieren
+            aStrm->Seek( STREAM_SEEK_TO_BEGIN );
+            pData->SetData( aStrm );
+            bRet = TRUE;
+        }
+
+        delete pPam;
+    }
+    return bRet;
+}
+
+
+BOOL SwServerObject::ChangeData( SvData& rData )        // neue Daten setzen
+{
+    // erstmal gibst nichts
+    return FALSE;
+}
+
+
+void SwServerObject::SendDataChanged( const SwPosition& rPos )
+{
+    // ist an unseren Aenderungen jemand interessiert ?
+    if( GetSelectorCount() )
+    {
+        int bCall = FALSE;
+        const SwStartNode* pNd = 0;
+        switch( eType )
+        {
+        case BOOKMARK_SERVER:
+            if( CNTNT_TYPE.pBkmk->GetOtherPos() )
+            {
+                SwBookmark& rBkmk = *CNTNT_TYPE.pBkmk;
+                bCall = rBkmk.GetPos() < *rBkmk.GetOtherPos()
+                    ? ( rBkmk.GetPos() <= rPos && rPos < *rBkmk.GetOtherPos() )
+                    : ( *rBkmk.GetOtherPos() <= rPos && rPos < rBkmk.GetPos() );
+            }
+            break;
+
+        case TABLE_SERVER:      pNd = CNTNT_TYPE.pTblNd;    break;
+        case SECTION_SERVER:    pNd = CNTNT_TYPE.pSectNd;   break;
+        }
+        if( pNd )
+        {
+            register ULONG nNd = rPos.nNode.GetIndex();
+            bCall = pNd->GetIndex() < nNd && nNd < pNd->EndOfSectionIndex();
+        }
+
+        if( bCall )
+        {
+            // Recursionen erkennen und flaggen
+            IsLinkInServer( 0 );
+            SvData aSvData;
+            DataChanged( aSvData );
+        }
+    }
+    // sonst melden wir uns ab !!
+// ????? JP 27.06.95: geht das so ????
+//  else
+//      Closed();
+}
+
+
+void SwServerObject::SendDataChanged( const SwPaM& rRange )
+{
+    // ist an unseren Aenderungen jemand interessiert ?
+    if( GetSelectorCount() )
+    {
+        int bCall = FALSE;
+        const SwStartNode* pNd = 0;
+        const SwPosition* pStt = rRange.Start(), *pEnd = rRange.End();
+        switch( eType )
+        {
+        case BOOKMARK_SERVER:
+            if( CNTNT_TYPE.pBkmk->GetOtherPos() )
+            {
+                SwBookmark& rBkmk = *CNTNT_TYPE.pBkmk;
+                const SwPosition* pBkStt = &rBkmk.GetPos(),
+                                * pBkEnd = rBkmk.GetOtherPos();
+                if( *pBkStt > *pBkEnd )
+                {
+                    const SwPosition* pTmp = pBkStt;
+                    pBkStt = pBkEnd;
+                    pBkEnd = pTmp;
+                }
+                bCall = *pStt <= *pBkEnd && *pEnd > *pBkStt;
+            }
+            break;
+
+        case TABLE_SERVER:      pNd = CNTNT_TYPE.pTblNd;    break;
+        case SECTION_SERVER:    pNd = CNTNT_TYPE.pSectNd;   break;
+        }
+        if( pNd )
+        {
+            // liegt der Start-Bereich im Node Bereich ?
+            bCall = pStt->nNode.GetIndex() <  pNd->EndOfSectionIndex() &&
+                    pEnd->nNode.GetIndex() >= pNd->GetIndex();
+        }
+
+        if( bCall )
+        {
+            // Recursionen erkennen und flaggen
+            IsLinkInServer( 0 );
+            SvData aSvData;
+            DataChanged( aSvData );
+        }
+    }
+    // sonst melden wir uns ab !!
+// ????? JP 27.06.95: geht das so ????
+//  else
+//      Closed();
+}
+
+
+BOOL SwServerObject::IsLinkInServer( const SwBaseLink* pChkLnk ) const
+{
+    ULONG nSttNd = 0, nEndNd = 0;
+    xub_StrLen nStt, nEnd;
+    const SwNode* pNd = 0;
+    const SwNodes* pNds = 0;
+
+    switch( eType )
+    {
+    case BOOKMARK_SERVER:
+        if( CNTNT_TYPE.pBkmk->GetOtherPos() )
+        {
+            SwBookmark& rBkmk = *CNTNT_TYPE.pBkmk;
+            const SwPosition* pStt = &rBkmk.GetPos(),
+                            * pEnd = rBkmk.GetOtherPos();
+            if( *pStt > *pEnd )
+            {
+                const SwPosition* pTmp = pStt;
+                pStt = pEnd;
+                pEnd = pTmp;
+            }
+
+            nSttNd = pStt->nNode.GetIndex();
+            nStt = pStt->nContent.GetIndex();
+            nEndNd = pEnd->nNode.GetIndex();
+            nEnd = pEnd->nContent.GetIndex();
+            pNds = &pStt->nNode.GetNodes();
+        }
+        break;
+
+    case TABLE_SERVER:      pNd = CNTNT_TYPE.pTblNd;    break;
+    case SECTION_SERVER:    pNd = CNTNT_TYPE.pSectNd;   break;
+
+    case SECTION_SERVER+1:
+        return TRUE;
+    }
+
+    if( pNd )
+    {
+        nSttNd = pNd->GetIndex();
+        nEndNd = pNd->EndOfSectionIndex();
+        nStt = 0, nEnd = USHRT_MAX;
+        pNds = &pNd->GetNodes();
+    }
+
+    if( nSttNd && nEndNd )
+    {
+        // LinkManager besorgen:
+        const SvBaseLinks& rLnks = pNds->GetDoc()->GetLinkManager().GetLinks();
+
+// um Rekursionen zu Verhindern: ServerType umsetzen!
+SwServerObject::ServerModes eSave = eType;
+if( !pChkLnk )
+// sowas sollte man nicht tun, wer weiss schon, wie gross ein enum ist
+// ICC nimmt keinen int
+// #41723#
+//  *((int*)&eType) = SECTION_SERVER+1;
+    ((SwServerObject*)this)->eType = NONE_SERVER;
+        for( USHORT n = rLnks.Count(); n; )
+        {
+            const SvBaseLink* pLnk = &(*rLnks[ --n ]);
+            if( pLnk && OBJECT_CLIENT_GRF != pLnk->GetObjType() &&
+                pLnk->ISA( SwBaseLink ) &&
+                !((SwBaseLink*)pLnk)->IsNoDataFlag() &&
+                ((SwBaseLink*)pLnk)->IsInRange( nSttNd, nEndNd, nStt, nEnd ))
+            {
+                if( pChkLnk )
+                {
+                    if( pLnk == pChkLnk ||
+                        ((SwBaseLink*)pLnk)->IsRecursion( pChkLnk ) )
+                        return TRUE;
+                }
+                else if( ((SwBaseLink*)pLnk)->IsRecursion( (SwBaseLink*)pLnk ) )
+                    ((SwBaseLink*)pLnk)->SetNoDataFlag();
+            }
+        }
+if( !pChkLnk )
+    //  *((int*)&eType) = eSave;
+    ((SwServerObject*)this)->eType = eSave;
+    }
+
+    return FALSE;
+}
+
+/*  */
+
+
+SwDataChanged::SwDataChanged( const SwPaM& rPam, USHORT nTyp )
+    : pPam( &rPam ), nType( nTyp ), pDoc( rPam.GetDoc() ), pPos( 0 )
+{
+    nNode = rPam.GetPoint()->nNode.GetIndex();
+    nCntnt = rPam.GetPoint()->nContent.GetIndex();
+}
+
+
+SwDataChanged::SwDataChanged( SwDoc* pDoc, const SwPosition& rPos, USHORT nTyp )
+    : pPam( 0 ), nType( nTyp ), pDoc( pDoc ), pPos( &rPos )
+{
+    nNode = rPos.nNode.GetIndex();
+    nCntnt = rPos.nContent.GetIndex();
+}
+
+
+SwDataChanged::~SwDataChanged()
+{
+    // JP 09.04.96: nur wenn das Layout vorhanden ist ( also waehrend der
+    //              Eingabe)
+    if( pDoc->GetRootFrm() )
+    {
+        const SvPseudoObjects& rServers = pDoc->GetLinkManager().GetServers();
+
+        for( USHORT nCnt = rServers.Count(); nCnt; )
+        {
+            SwServerObjectRef refObj( (SwServerObject*)rServers[ --nCnt ] );
+            // noch jemand am Object interessiert ?
+            if( refObj->GetSelectorCount() )
+            {
+                if( pPos )
+                    refObj->SendDataChanged( *pPos );
+                else
+                    refObj->SendDataChanged( *pPam );
+            }
+
+            // sollte jetzt gar keine Verbindung mehr bestehen
+            if( !refObj->GetSelectorCount() )
+            {
+                // dann raus aus der Liste (Object bleibt aber bestehen!)
+                // falls es noch da ist !!
+                if( nCnt < rServers.Count() && &refObj == rServers[ nCnt ] )
+                    pDoc->GetLinkManager().RemoveServer( nCnt, 1 );
+            }
+        }
+    }
+}
+
+
+
+
diff --git a/sw/source/core/doc/tblafmt.cxx b/sw/source/core/doc/tblafmt.cxx
new file mode 100644
index 000000000000..721780d49f16
--- /dev/null
+++ b/sw/source/core/doc/tblafmt.cxx
@@ -0,0 +1,1055 @@
+/*************************************************************************
+ *
+ *  $RCSfile: tblafmt.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:16 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#define ITEMID_BOXINFO      SID_ATTR_BORDER_INNER
+
+
+#ifndef _TOOLS_RESID_HXX
+#include 
+#endif
+#ifndef _STREAM_HXX //autogen
+#include 
+#endif
+#ifndef _SHL_HXX
+#include 
+#endif
+#ifndef _SV_SVAPP_HXX
+#include 
+#endif
+#ifndef _SFXDOCFILE_HXX
+#include 
+#endif
+#ifndef SVTOOLS_URIHELPER_HXX
+#include 
+#endif
+#ifndef _ZFORLIST_HXX //autogen
+#include 
+#endif
+#ifndef _ZFORMAT_HXX //autogen
+#include 
+#endif
+#ifndef _SFX_INIMGR_HXX
+#include 
+#endif
+#ifndef _SFXAPP_HXX
+#include 
+#endif
+#ifndef _SVX_DIALMGR_HXX
+#include 
+#endif
+#ifndef _SVX_DIALOGS_HRC
+#include 
+#endif
+
+#define READ_OLDVERS        // erstmal noch alte Versionen lesen
+
+#ifndef _SWTYPES_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _POOLFMT_HXX
+#include 
+#endif
+#ifndef _TBLAFMT_HXX
+#include 
+#endif
+#ifndef _CELLATR_HXX
+#include 
+#endif
+#ifndef _FINDER_HXX
+#include 
+#endif
+
+
+// bis SO5PF
+const USHORT AUTOFORMAT_ID_X        = 9501;
+const USHORT AUTOFORMAT_ID_358      = 9601;
+const USHORT AUTOFORMAT_DATA_ID_X   = 9502;
+
+// ab SO5
+//! in nachfolgenden Versionen muss der Betrag dieser IDs groesser sein
+const USHORT AUTOFORMAT_ID_504      = 9801;
+const USHORT AUTOFORMAT_DATA_ID_504 = 9802;
+
+const USHORT AUTOFORMAT_ID_552      = 9901;
+const USHORT AUTOFORMAT_DATA_ID_552 = 9902;
+
+// aktuelle Version
+const USHORT AUTOFORMAT_ID          = AUTOFORMAT_ID_552;
+const USHORT AUTOFORMAT_DATA_ID     = AUTOFORMAT_DATA_ID_552;
+
+
+#ifdef READ_OLDVERS
+const USHORT AUTOFORMAT_OLD_ID      = 8201;
+const USHORT AUTOFORMAT_OLD_ID1     = 8301;
+const USHORT AUTOFORMAT_OLD_DATA_ID = 8202;
+#endif
+
+
+SwBoxAutoFmt* SwTableAutoFmt::pDfltBoxAutoFmt = 0;
+
+#define sAutoTblFmtName "autotbl.fmt"
+
+// SwTable Auto-Format-Tabelle
+SV_IMPL_PTRARR( _SwTableAutoFmtTbl, SwTableAutoFmt* )
+
+
+//  Struct mit Versionsnummern der Items
+
+struct SwAfVersions
+{
+public:
+    USHORT nFontVersion;
+    USHORT nFontHeightVersion;
+    USHORT nWeightVersion;
+    USHORT nPostureVersion;
+    USHORT nUnderlineVersion;
+    USHORT nCrossedOutVersion;
+    USHORT nContourVersion;
+    USHORT nShadowedVersion;
+    USHORT nColorVersion;
+    USHORT nBoxVersion;
+    USHORT nBrushVersion;
+
+    USHORT nAdjustVersion;
+
+    USHORT nHorJustifyVersion;
+    USHORT nVerJustifyVersion;
+    USHORT nOrientationVersion;
+    USHORT nMarginVersion;
+    USHORT nBoolVersion;
+    USHORT nInt32Version;
+    USHORT nRotateModeVersion;
+
+    USHORT nNumFmtVersion;
+
+    SwAfVersions();
+    void Load( SvStream& rStream, USHORT nVer );
+};
+
+SwAfVersions::SwAfVersions() :
+    nFontVersion(0),
+    nFontHeightVersion(0),
+    nWeightVersion(0),
+    nPostureVersion(0),
+    nUnderlineVersion(0),
+    nCrossedOutVersion(0),
+    nContourVersion(0),
+    nShadowedVersion(0),
+    nColorVersion(0),
+    nBoxVersion(0),
+    nBrushVersion(0),
+    nAdjustVersion(0),
+    nHorJustifyVersion(0),
+    nVerJustifyVersion(0),
+    nOrientationVersion(0),
+    nMarginVersion(0),
+    nBoolVersion(0),
+    nInt32Version(0),
+    nRotateModeVersion(0),
+    nNumFmtVersion(0)
+{
+}
+
+void SwAfVersions::Load( SvStream& rStream, USHORT nVer )
+{
+    rStream >> nFontVersion;
+    rStream >> nFontHeightVersion;
+    rStream >> nWeightVersion;
+    rStream >> nPostureVersion;
+    rStream >> nUnderlineVersion;
+    rStream >> nCrossedOutVersion;
+    rStream >> nContourVersion;
+    rStream >> nShadowedVersion;
+    rStream >> nColorVersion;
+    rStream >> nBoxVersion;
+    rStream >> nBrushVersion;
+    rStream >> nAdjustVersion;
+    rStream >> nHorJustifyVersion;
+    rStream >> nVerJustifyVersion;
+    rStream >> nOrientationVersion;
+    rStream >> nMarginVersion;
+    rStream >> nBoolVersion;
+    if ( nVer >= AUTOFORMAT_ID_504 )
+    {
+        rStream >> nInt32Version;
+        rStream >> nRotateModeVersion;
+    }
+    rStream >> nNumFmtVersion;
+}
+
+//  ---------------------------------------------------------------------------
+
+SwBoxAutoFmt::SwBoxAutoFmt()
+    : aFont( *(SvxFontItem*)GetDfltAttr( RES_CHRATR_FONT ) ),
+    aRotateMode( SVX_ROTATE_MODE_STANDARD, 0 )
+{
+    eSysLanguage = eNumFmtLanguage = ::GetSystemLanguage();
+    aBox.SetDistance( 55 );
+}
+
+
+SwBoxAutoFmt::SwBoxAutoFmt( const SwBoxAutoFmt& rNew )
+    : aFont( rNew.aFont ),
+    aHeight( rNew.aHeight ),
+    aWeight( rNew.aWeight ),
+    aPosture( rNew.aPosture ),
+    aUnderline( rNew.aUnderline ),
+    aCrossedOut( rNew.aCrossedOut ),
+    aContour( rNew.aContour ),
+    aShadowed( rNew.aShadowed ),
+    aColor( rNew.aColor ),
+    aAdjust( rNew.aAdjust ),
+    aBox( rNew.aBox ),
+    aBackground( rNew.aBackground ),
+    aHorJustify( rNew.aHorJustify ),
+    aVerJustify( rNew.aVerJustify ),
+    aOrientation( rNew.aOrientation ),
+    aMargin( rNew.aMargin ),
+    aLinebreak( rNew.aLinebreak ),
+    aRotateAngle( rNew.aRotateAngle ),
+    aRotateMode( rNew.aRotateMode ),
+    sNumFmtString( rNew.sNumFmtString ),
+    eSysLanguage( rNew.eSysLanguage ),
+    eNumFmtLanguage( rNew.eNumFmtLanguage )
+{
+}
+
+
+SwBoxAutoFmt::~SwBoxAutoFmt()
+{
+}
+
+#if USED
+
+int SwBoxAutoFmt::operator==( const SwBoxAutoFmt& rCmp ) const
+{
+    return  aFont == rCmp.aFont &&
+            aHeight == rCmp.aHeight &&
+            aWeight == rCmp.aWeight &&
+            aPosture == rCmp.aPosture &&
+            aUnderline == rCmp.aUnderline &&
+            aCrossedOut == rCmp.aCrossedOut &&
+            aContour == rCmp.aContour &&
+            aShadowed == rCmp.aShadowed &&
+            aColor == rCmp.aColor &&
+            aAdjust == rCmp.aAdjust &&
+            aBox == rCmp.aBox &&
+            aBackground == rCmp.aBackground;
+}
+#endif
+
+
+SwBoxAutoFmt& SwBoxAutoFmt::operator=( const SwBoxAutoFmt& rNew )
+{
+    aFont = rNew.aFont;
+    aHeight = rNew.aHeight;
+    aWeight = rNew.aWeight;
+    aPosture = rNew.aPosture;
+    aUnderline = rNew.aUnderline;
+    aCrossedOut = rNew.aCrossedOut;
+    aContour = rNew.aContour;
+    aShadowed = rNew.aShadowed;
+    aColor = rNew.aColor;
+    SetAdjust( rNew.aAdjust );
+    aBox = rNew.aBox;
+    aBackground = rNew.aBackground;
+
+    aHorJustify = rNew.aHorJustify;
+    aVerJustify = rNew.aVerJustify;
+    aOrientation = rNew.aOrientation;
+    aMargin = rNew.aMargin;
+    aLinebreak.SetValue( rNew.aLinebreak.GetValue() );
+    aRotateAngle.SetValue( rNew.aRotateAngle.GetValue() );
+    aRotateMode.SetValue( rNew.aRotateMode.GetValue() );
+
+    sNumFmtString = rNew.sNumFmtString;
+    eSysLanguage = rNew.eSysLanguage;
+    eNumFmtLanguage = rNew.eNumFmtLanguage;
+
+    return *this;
+}
+
+
+#define READ( aItem, aItemType, nVers )\
+    pNew = aItem.Create(rStream, nVers ); \
+    aItem = *(aItemType*)pNew; \
+    delete pNew;
+
+BOOL SwBoxAutoFmt::Load( SvStream& rStream, const SwAfVersions& rVersions, USHORT nVer )
+{
+    SfxPoolItem* pNew;
+    READ( aFont,        SvxFontItem         , rVersions.nFontVersion)
+
+    if( rStream.GetStreamCharSet() == aFont.GetCharSet() )
+        aFont.GetCharSet() = ::gsl_getSystemTextEncoding();
+
+    READ( aHeight,      SvxFontHeightItem   , rVersions.nFontHeightVersion)
+    READ( aWeight,      SvxWeightItem       , rVersions.nWeightVersion)
+    READ( aPosture,     SvxPostureItem      , rVersions.nPostureVersion)
+    READ( aUnderline,   SvxUnderlineItem    , rVersions.nUnderlineVersion)
+    READ( aCrossedOut,  SvxCrossedOutItem   , rVersions.nCrossedOutVersion)
+    READ( aContour,     SvxContourItem      , rVersions.nContourVersion)
+    READ( aShadowed,    SvxShadowedItem     , rVersions.nShadowedVersion)
+    READ( aColor,       SvxColorItem        , rVersions.nColorVersion)
+
+    READ( aBox,         SvxBoxItem          , rVersions.nBoxVersion)
+    READ( aBackground,  SvxBrushItem        , rVersions.nBrushVersion)
+
+    pNew = aAdjust.Create(rStream, rVersions.nAdjustVersion );
+    SetAdjust( *(SvxAdjustItem*)pNew );
+    delete pNew;
+
+    READ( aHorJustify,  SvxHorJustifyItem   , rVersions.nHorJustifyVersion)
+    READ( aVerJustify,  SvxVerJustifyItem   , rVersions.nVerJustifyVersion)
+    READ( aOrientation, SvxOrientationItem  , rVersions.nOrientationVersion)
+    READ( aMargin,      SvxMarginItem       , rVersions.nMarginVersion)
+
+    pNew = aLinebreak.Create(rStream, rVersions.nBoolVersion );
+    aLinebreak.SetValue( ((SfxBoolItem*)pNew)->GetValue() );
+    delete pNew;
+
+    if ( nVer >= AUTOFORMAT_DATA_ID_504 )
+    {
+        pNew = aRotateAngle.Create( rStream, rVersions.nInt32Version );
+        aRotateAngle.SetValue( ((SfxInt32Item*)pNew)->GetValue() );
+        delete pNew;
+        pNew = aRotateMode.Create( rStream, rVersions.nRotateModeVersion );
+        aRotateMode.SetValue( ((SvxRotateModeItem*)pNew)->GetValue() );
+        delete pNew;
+    }
+
+    if( 0 == rVersions.nNumFmtVersion )
+    {
+        USHORT eSys, eLge;
+        rStream.ReadByteString( sNumFmtString, rStream.GetStreamCharSet() )
+                >> eSys >> eLge;
+        eSysLanguage = (LanguageType) eSys;
+        eNumFmtLanguage = (LanguageType) eLge;
+        if ( eSysLanguage == LANGUAGE_SYSTEM )      // von alten Versionen (Calc)
+            eSysLanguage = ::GetSystemLanguage();
+    }
+
+    return 0 == rStream.GetError();
+}
+
+#ifdef READ_OLDVERS
+
+BOOL SwBoxAutoFmt::LoadOld( SvStream& rStream, USHORT aLoadVer[] )
+{
+    SfxPoolItem* pNew;
+    READ( aFont,        SvxFontItem         , 0)
+
+    if( rStream.GetStreamCharSet() == aFont.GetCharSet() )
+        aFont.GetCharSet() = ::gsl_getSystemTextEncoding();
+
+    READ( aHeight,      SvxFontHeightItem   , 1)
+    READ( aWeight,      SvxWeightItem       , 2)
+    READ( aPosture,     SvxPostureItem      , 3)
+    READ( aUnderline,   SvxUnderlineItem    , 4)
+    READ( aCrossedOut,  SvxCrossedOutItem   , 5)
+    READ( aContour,     SvxContourItem      , 6)
+    READ( aShadowed,    SvxShadowedItem     , 7)
+    READ( aColor,       SvxColorItem        , 8)
+
+    pNew = aAdjust.Create(rStream, aLoadVer[ 9 ] );
+    SetAdjust( *(SvxAdjustItem*)pNew );
+    delete pNew;
+
+    READ( aBox,         SvxBoxItem          , 10)
+    READ( aBackground,  SvxBrushItem        , 11)
+
+    return 0 == rStream.GetError();
+}
+
+#endif
+
+
+BOOL SwBoxAutoFmt::Save( SvStream& rStream ) const
+{
+    aFont.Store( rStream, aFont.GetVersion(SOFFICE_FILEFORMAT_40)  );
+    aHeight.Store( rStream, aHeight.GetVersion(SOFFICE_FILEFORMAT_40) );
+    aWeight.Store( rStream, aWeight.GetVersion(SOFFICE_FILEFORMAT_40) );
+    aPosture.Store( rStream, aPosture.GetVersion(SOFFICE_FILEFORMAT_40) );
+    aUnderline.Store( rStream, aUnderline.GetVersion(SOFFICE_FILEFORMAT_40) );
+    aCrossedOut.Store( rStream, aCrossedOut.GetVersion(SOFFICE_FILEFORMAT_40) );
+    aContour.Store( rStream, aContour.GetVersion(SOFFICE_FILEFORMAT_40) );
+    aShadowed.Store( rStream, aShadowed.GetVersion(SOFFICE_FILEFORMAT_40) );
+    aColor.Store( rStream, aColor.GetVersion(SOFFICE_FILEFORMAT_40) );
+    aBox.Store( rStream, aBox.GetVersion(SOFFICE_FILEFORMAT_40) );
+    aBackground.Store( rStream, aBackground.GetVersion(SOFFICE_FILEFORMAT_40) );
+
+    aAdjust.Store( rStream, aAdjust.GetVersion(SOFFICE_FILEFORMAT_40) );
+
+    aHorJustify.Store( rStream, aHorJustify.GetVersion(SOFFICE_FILEFORMAT_40) );
+    aVerJustify.Store( rStream, aVerJustify.GetVersion(SOFFICE_FILEFORMAT_40) );
+    aOrientation.Store( rStream, aOrientation.GetVersion(SOFFICE_FILEFORMAT_40) );
+    aMargin.Store( rStream, aMargin.GetVersion(SOFFICE_FILEFORMAT_40) );
+    aLinebreak.Store( rStream, aLinebreak.GetVersion(SOFFICE_FILEFORMAT_40) );
+    // Calc Rotation ab SO5
+    aRotateAngle.Store( rStream, aRotateAngle.GetVersion(SOFFICE_FILEFORMAT_40) );
+    aRotateMode.Store( rStream, aRotateMode.GetVersion(SOFFICE_FILEFORMAT_40) );
+
+    rStream.WriteByteString( sNumFmtString, rStream.GetStreamCharSet() )
+        << (USHORT)eSysLanguage << (USHORT)eNumFmtLanguage;
+
+    return 0 == rStream.GetError();
+}
+
+
+BOOL SwBoxAutoFmt::SaveVerionNo( SvStream& rStream ) const
+{
+    rStream << aFont.GetVersion( SOFFICE_FILEFORMAT_40 );
+    rStream << aHeight.GetVersion( SOFFICE_FILEFORMAT_40 );
+    rStream << aWeight.GetVersion( SOFFICE_FILEFORMAT_40 );
+    rStream << aPosture.GetVersion( SOFFICE_FILEFORMAT_40 );
+    rStream << aUnderline.GetVersion( SOFFICE_FILEFORMAT_40 );
+    rStream << aCrossedOut.GetVersion( SOFFICE_FILEFORMAT_40 );
+    rStream << aContour.GetVersion( SOFFICE_FILEFORMAT_40 );
+    rStream << aShadowed.GetVersion( SOFFICE_FILEFORMAT_40 );
+    rStream << aColor.GetVersion( SOFFICE_FILEFORMAT_40 );
+    rStream << aBox.GetVersion( SOFFICE_FILEFORMAT_40 );
+    rStream << aBackground.GetVersion( SOFFICE_FILEFORMAT_40 );
+
+    rStream << aAdjust.GetVersion( SOFFICE_FILEFORMAT_40 );
+
+    rStream << aHorJustify.GetVersion( SOFFICE_FILEFORMAT_40 );
+    rStream << aVerJustify.GetVersion( SOFFICE_FILEFORMAT_40 );
+    rStream << aOrientation.GetVersion( SOFFICE_FILEFORMAT_40 );
+    rStream << aMargin.GetVersion( SOFFICE_FILEFORMAT_40 );
+    rStream << aLinebreak.GetVersion( SOFFICE_FILEFORMAT_40 );
+    rStream << aRotateAngle.GetVersion( SOFFICE_FILEFORMAT_40 );
+    rStream << aRotateMode.GetVersion( SOFFICE_FILEFORMAT_40 );
+
+    rStream << (USHORT)0;       // NumberFormat
+
+    return 0 == rStream.GetError();
+}
+
+/*  */
+
+
+SwTableAutoFmt::SwTableAutoFmt( const String& rName )
+    : aName( rName ), nStrResId( USHRT_MAX )
+{
+    bInclFont = TRUE;
+    bInclJustify = TRUE;
+    bInclFrame = TRUE;
+    bInclBackground = TRUE;
+    bInclValueFormat = TRUE;
+    bInclWidthHeight = TRUE;
+
+    memset( aBoxAutoFmt, 0, sizeof( aBoxAutoFmt ) );
+}
+
+
+SwTableAutoFmt::SwTableAutoFmt( const SwTableAutoFmt& rNew )
+{
+    for( BYTE n = 0; n < 16; ++n )
+        aBoxAutoFmt[ n ] = 0;
+    *this = rNew;
+}
+
+SwTableAutoFmt& SwTableAutoFmt::operator=( const SwTableAutoFmt& rNew )
+{
+    for( BYTE n = 0; n < 16; ++n )
+    {
+        if( aBoxAutoFmt[ n ] )
+            delete aBoxAutoFmt[ n ];
+
+        SwBoxAutoFmt* pFmt = rNew.aBoxAutoFmt[ n ];
+        if( pFmt )      // ist gesetzt -> kopieren
+            aBoxAutoFmt[ n ] = new SwBoxAutoFmt( *pFmt );
+        else            // sonst default
+            aBoxAutoFmt[ n ] = 0;
+    }
+
+    aName = rNew.aName;
+    nStrResId = rNew.nStrResId;
+    bInclFont = rNew.bInclFont;
+    bInclJustify = rNew.bInclJustify;
+    bInclFrame = rNew.bInclFrame;
+    bInclBackground = rNew.bInclBackground;
+    bInclValueFormat = rNew.bInclValueFormat;
+    bInclWidthHeight = rNew.bInclWidthHeight;
+
+    return *this;
+}
+
+
+SwTableAutoFmt::~SwTableAutoFmt()
+{
+    SwBoxAutoFmt** ppFmt = aBoxAutoFmt;
+    for( BYTE n = 0; n < 16; ++n, ++ppFmt )
+        if( *ppFmt )
+            delete *ppFmt;
+}
+
+
+void SwTableAutoFmt::SetBoxFmt( const SwBoxAutoFmt& rNew, BYTE nPos )
+{
+    ASSERT( 0 <= nPos && nPos < 16, "falscher Bereich" );
+
+    SwBoxAutoFmt* pFmt = aBoxAutoFmt[ nPos ];
+    if( pFmt )      // ist gesetzt -> kopieren
+        *aBoxAutoFmt[ nPos ] = rNew;
+    else            // sonst neu setzen
+        aBoxAutoFmt[ nPos ] = new SwBoxAutoFmt( rNew );
+}
+
+
+const SwBoxAutoFmt& SwTableAutoFmt::GetBoxFmt( BYTE nPos ) const
+{
+    ASSERT( 0 <= nPos && nPos < 16, "falscher Bereich" );
+
+    SwBoxAutoFmt* pFmt = aBoxAutoFmt[ nPos ];
+    if( pFmt )      // ist gesetzt -> kopieren
+        return *pFmt;
+    else            // sonst den default returnen
+    {
+        // falls noch nicht vorhanden:
+        if( !pDfltBoxAutoFmt )
+            pDfltBoxAutoFmt = new SwBoxAutoFmt;
+        return *pDfltBoxAutoFmt;
+    }
+}
+
+
+
+SwBoxAutoFmt& SwTableAutoFmt::UpdateFromSet( BYTE nPos,
+                                            const SfxItemSet& rSet,
+                                            UpdateFlags eFlags,
+                                            SvNumberFormatter* pNFmtr )
+{
+    ASSERT( 0 <= nPos && nPos < 16, "falscher Bereich" );
+
+    SwBoxAutoFmt* pFmt = aBoxAutoFmt[ nPos ];
+    if( !pFmt )     // ist gesetzt -> kopieren
+    {
+        pFmt = new SwBoxAutoFmt;
+        aBoxAutoFmt[ nPos ] = pFmt;
+    }
+
+    if( UPDATE_CHAR & eFlags )
+    {
+        pFmt->SetFont( (SvxFontItem&)rSet.Get( RES_CHRATR_FONT ) );
+        pFmt->SetHeight( (SvxFontHeightItem&)rSet.Get( RES_CHRATR_FONTSIZE ) );
+        pFmt->SetWeight( (SvxWeightItem&)rSet.Get( RES_CHRATR_WEIGHT ) );
+        pFmt->SetPosture( (SvxPostureItem&)rSet.Get( RES_CHRATR_POSTURE ) );
+        pFmt->SetUnderline( (SvxUnderlineItem&)rSet.Get( RES_CHRATR_UNDERLINE ) );
+        pFmt->SetCrossedOut( (SvxCrossedOutItem&)rSet.Get( RES_CHRATR_CROSSEDOUT ) );
+        pFmt->SetContour( (SvxContourItem&)rSet.Get( RES_CHRATR_CONTOUR ) );
+        pFmt->SetShadowed( (SvxShadowedItem&)rSet.Get( RES_CHRATR_SHADOWED ) );
+        pFmt->SetColor( (SvxColorItem&)rSet.Get( RES_CHRATR_COLOR ) );
+        pFmt->SetAdjust( (SvxAdjustItem&)rSet.Get( RES_PARATR_ADJUST ) );
+    }
+    if( UPDATE_BOX & eFlags )
+    {
+        pFmt->SetBox( (SvxBoxItem&)rSet.Get( RES_BOX ) );
+        pFmt->SetBackground( (SvxBrushItem&)rSet.Get( RES_BACKGROUND ) );
+
+        const SwTblBoxNumFormat* pNumFmtItem;
+        const SvNumberformat* pNumFormat = 0;
+        if( SFX_ITEM_SET == rSet.GetItemState( RES_BOXATR_FORMAT, TRUE,
+            (const SfxPoolItem**)&pNumFmtItem ) && pNFmtr &&
+            0 != (pNumFormat = pNFmtr->GetEntry( pNumFmtItem->GetValue() )) )
+            pFmt->SetValueFormat( ((SvNumberformat*)pNumFormat)->GetFormatstring(),
+                                    pNumFormat->GetLanguage(),
+                                    ::GetSystemLanguage() );
+        else
+        {
+            // defaulten
+            pFmt->SetValueFormat( aEmptyStr, LANGUAGE_SYSTEM,
+                                    ::GetSystemLanguage() );
+        }
+    }
+    // den Rest koennen wir nicht, StarCalc spezifisch
+
+    return *pFmt;
+}
+
+
+void SwTableAutoFmt::UpdateToSet( BYTE nPos, SfxItemSet& rSet,
+                UpdateFlags eFlags, SvNumberFormatter* pNFmtr ) const
+{
+    const SwBoxAutoFmt& rChg = GetBoxFmt( nPos );
+
+    if( UPDATE_CHAR & eFlags )
+    {
+        if( IsFont() )
+        {
+            rSet.Put( rChg.GetFont() );
+            rSet.Put( rChg.GetHeight() );
+            rSet.Put( rChg.GetWeight() );
+            rSet.Put( rChg.GetPosture() );
+            rSet.Put( rChg.GetUnderline() );
+            rSet.Put( rChg.GetCrossedOut() );
+            rSet.Put( rChg.GetContour() );
+            rSet.Put( rChg.GetShadowed() );
+            rSet.Put( rChg.GetColor() );
+        }
+        if( IsJustify() )
+            rSet.Put( rChg.GetAdjust() );
+    }
+
+    if( UPDATE_BOX & eFlags )
+    {
+        if( IsFrame() )
+            rSet.Put( rChg.GetBox() );
+        if( IsBackground() )
+            rSet.Put( rChg.GetBackground() );
+
+        if( IsValueFormat() && pNFmtr )
+        {
+            String sFmt; LanguageType eLng, eSys;
+            rChg.GetValueFormat( sFmt, eLng, eSys );
+            if( sFmt.Len() )
+            {
+                ULONG nKey = 0;
+                if ( eLng == LANGUAGE_SYSTEM && eSys != ::GetSystemLanguage() )
+                {
+                    //  #53381# wenn System beim Speichern etwas anderes war,
+                    //  muss konvertiert werden (geht nur mit eingebauten Formaten)
+                    ULONG nOrig = pNFmtr->GetEntryKey( sFmt, eSys );
+                    if ( nOrig != NUMBERFORMAT_ENTRY_NOT_FOUND )
+                        nKey = pNFmtr->GetFormatForLanguageIfBuiltIn( nOrig,
+                                        ::GetSystemLanguage() );
+                }
+                else    // sonst einfach suchen oder anlegen
+                {
+                    nKey = pNFmtr->GetEntryKey( sFmt, eLng );
+                    if( NUMBERFORMAT_ENTRY_NOT_FOUND == nKey )
+                    {
+                        xub_StrLen nCheckPos;
+                        short nType;
+                        pNFmtr->PutEntry( sFmt, nCheckPos, nType, nKey, eLng );
+                    }
+                }
+                rSet.Put( SwTblBoxNumFormat( nKey ));
+            }
+            else
+                rSet.ClearItem( RES_BOXATR_FORMAT );
+        }
+    }
+
+    // den Rest koennen wir nicht, StarCalc spezifisch
+}
+
+
+BOOL SwTableAutoFmt::Load( SvStream& rStream, const SwAfVersions& rVersions )
+{
+    BOOL    bRet = TRUE;
+    USHORT  nVal = 0;
+    rStream >> nVal;
+    bRet = 0 == rStream.GetError();
+
+    if( bRet && (nVal == AUTOFORMAT_DATA_ID_X ||
+            (AUTOFORMAT_DATA_ID_504 <= nVal && nVal <= AUTOFORMAT_DATA_ID)) )
+    {
+        BOOL b;
+        rStream.ReadByteString( aName, rStream.GetStreamCharSet() );
+        if( AUTOFORMAT_DATA_ID_552 <= nVal )
+        {
+            rStream >> nStrResId;
+            USHORT nId = RID_SVXSTR_TBLAFMT_BEGIN + nStrResId;
+            if( RID_SVXSTR_TBLAFMT_BEGIN <= nId &&
+                nId < RID_SVXSTR_TBLAFMT_END )
+            {
+                aName = SVX_RESSTR( nId );
+            }
+            else
+                nStrResId = USHRT_MAX;
+        }
+        rStream >> b; bInclFont = b;
+        rStream >> b; bInclJustify = b;
+        rStream >> b; bInclFrame = b;
+        rStream >> b; bInclBackground = b;
+        rStream >> b; bInclValueFormat = b;
+        rStream >> b; bInclWidthHeight = b;
+
+        bRet = 0 == rStream.GetError();
+
+        for( BYTE i = 0; i < 16; ++i )
+        {
+            SwBoxAutoFmt* pFmt = new SwBoxAutoFmt;
+            bRet = pFmt->Load( rStream, rVersions, nVal );
+            if( bRet )
+                aBoxAutoFmt[ i ] = pFmt;
+            else
+            {
+                delete pFmt;
+                break;
+            }
+        }
+    }
+    return bRet;
+}
+
+#ifdef READ_OLDVERS
+
+BOOL SwTableAutoFmt::LoadOld( SvStream& rStream, USHORT aLoadVer[] )
+{
+    BOOL    bRet = TRUE;
+    USHORT  nVal = 0;
+    rStream >> nVal;
+    bRet = 0 == rStream.GetError();
+
+    if( bRet && ( AUTOFORMAT_OLD_DATA_ID == nVal ))
+    {
+        BOOL b;
+        rStream.ReadByteString( aName, rStream.GetStreamCharSet() );
+        rStream >> b; bInclFont = b;
+        rStream >> b; bInclJustify = b;
+        rStream >> b; bInclFrame = b;
+        rStream >> b; bInclBackground = b;
+        bRet = (rStream.GetError() == 0);
+
+        for( int i = 0; i < 16; i++)
+        {
+            SwBoxAutoFmt* pFmt = new SwBoxAutoFmt;
+            bRet = pFmt->LoadOld( rStream, aLoadVer );
+            if( bRet )
+                aBoxAutoFmt[ i ] = pFmt;
+            else
+            {
+                delete pFmt;
+                break;
+            }
+        }
+    }
+    return bRet;
+}
+#endif
+
+
+BOOL SwTableAutoFmt::Save( SvStream& rStream ) const
+{
+    USHORT nVal = AUTOFORMAT_DATA_ID;
+    BOOL b;
+    rStream << nVal;
+    rStream.WriteByteString( aName, rStream.GetStreamCharSet() );
+    if( USHRT_MAX == nStrResId && 0 != SFX_INIMANAGER()->Get(
+            SFX_GROUP_WORKINGSET_IMPL, String::CreateFromAscii(
+            RTL_CONSTASCII_STRINGPARAM("SaveTableAutoFmtNameId" ))).ToInt32())
+    {
+        // check Name for ResId
+        for( USHORT nId = RID_SVXSTR_TBLAFMT_BEGIN;
+                    RID_SVXSTR_TBLAFMT_END > nId; ++nId )
+        {
+            String s( SVX_RES( nId ) );
+            if( s == aName )
+            {
+                SwTableAutoFmt* pThis = (SwTableAutoFmt*)this;
+                pThis->nStrResId = nId - RID_SVXSTR_TBLAFMT_BEGIN;
+                break;
+            }
+        }
+    }
+
+    rStream << nStrResId;
+    rStream << ( b = bInclFont );
+    rStream << ( b = bInclJustify );
+    rStream << ( b = bInclFrame );
+    rStream << ( b = bInclBackground );
+    rStream << ( b = bInclValueFormat );
+    rStream << ( b = bInclWidthHeight );
+
+    BOOL bRet = 0 == rStream.GetError();
+
+    for( int i = 0; bRet && i < 16; ++i )
+    {
+        SwBoxAutoFmt* pFmt = aBoxAutoFmt[ i ];
+        if( !pFmt )     // nicht gesetzt -> default schreiben
+        {
+            // falls noch nicht vorhanden:
+            if( !pDfltBoxAutoFmt )
+                pDfltBoxAutoFmt = new SwBoxAutoFmt;
+            pFmt = pDfltBoxAutoFmt;
+        }
+        bRet = pFmt->Save( rStream );
+    }
+    return bRet;
+}
+
+
+SwTableAutoFmtTbl::SwTableAutoFmtTbl()
+{
+    String sNm;
+    SwTableAutoFmt* pNew = new SwTableAutoFmt(
+                            SwDoc::GetPoolNm( RES_POOLCOLL_STANDARD, sNm ) );
+
+    SwBoxAutoFmt aNew;
+
+    BYTE i;
+
+    Color aColor( COL_BLUE );
+    SvxBrushItem aBrushItem( aColor );
+    aNew.SetBackground( aBrushItem );
+    aNew.SetColor( Color( COL_WHITE ));
+
+    for( i = 0; i < 4; ++i )
+        pNew->SetBoxFmt( aNew, i );
+
+    // 70% Grau
+    aBrushItem.SetColor( RGB_COLORDATA( 0x4d, 0x4d, 0x4d ) );
+    aNew.SetBackground( aBrushItem );
+    for( i = 4; i <= 12; i += 4 )
+        pNew->SetBoxFmt( aNew, i );
+
+    // 20% Grau
+    aBrushItem.SetColor( RGB_COLORDATA( 0xcc, 0xcc, 0xcc ) );
+    aNew.SetBackground( aBrushItem );
+    aColor.SetColor( COL_BLACK );
+    aNew.SetColor( aColor );
+    for( i = 7; i <= 15; i += 4 )
+        pNew->SetBoxFmt( aNew, i );
+    for( i = 13; i <= 14; ++i )
+        pNew->SetBoxFmt( aNew, i );
+
+    aBrushItem.SetColor( Color( COL_WHITE ) );
+    aNew.SetBackground( aBrushItem );
+    for( i = 5; i <= 6; ++i )
+        pNew->SetBoxFmt( aNew, i );
+    for( i = 9; i <= 10; ++i )
+        pNew->SetBoxFmt( aNew, i );
+
+
+    SvxBoxItem aBox;
+    aBox.SetDistance( 55 );
+    SvxBorderLine aLn( &aColor, DEF_LINE_WIDTH_0 );
+    aBox.SetLine( &aLn, BOX_LINE_LEFT );
+    aBox.SetLine( &aLn, BOX_LINE_BOTTOM );
+
+    for( i = 0; i <= 15; ++i )
+    {
+        aBox.SetLine( i <= 3 ? &aLn : 0, BOX_LINE_TOP );
+        aBox.SetLine( (3 == ( i & 3 )) ? &aLn : 0, BOX_LINE_RIGHT );
+        ((SwBoxAutoFmt&)pNew->GetBoxFmt( i )).SetBox( aBox );
+    }
+
+    Insert( pNew, Count() );
+}
+
+BOOL SwTableAutoFmtTbl::Load()
+{
+    BOOL bRet = FALSE;
+    String sNm( String::CreateFromAscii(
+                RTL_CONSTASCII_STRINGPARAM( sAutoTblFmtName )));
+    if( SFX_INIMANAGER()->SearchFile( sNm, SFX_KEY_USERCONFIG_PATH ))
+    {
+        SvFileStream aStream( sNm, STREAM_STD_READ );
+        bRet = Load( aStream );
+    }
+    else
+        bRet = FALSE;
+    return bRet;
+}
+
+BOOL SwTableAutoFmtTbl::Save() const
+{
+    String sNm( URIHelper::SmartRelToAbs(SFX_INIMANAGER()->Get( SFX_KEY_USERCONFIG_PATH )));
+    sNm += INET_PATH_TOKEN;
+    sNm.AppendAscii( RTL_CONSTASCII_STRINGPARAM( sAutoTblFmtName ));
+    SfxMedium aStream(sNm, STREAM_STD_WRITE, TRUE );
+    return Save( *aStream.GetOutStream() );
+}
+
+BOOL SwTableAutoFmtTbl::Load( SvStream& rStream )
+{
+    BOOL bRet = 0 == rStream.GetError();
+    if (bRet)
+    {
+        // Achtung hier muss ein allgemeiner Header gelesen werden
+        USHORT nVal = 0;
+        rStream >> nVal;
+        bRet = 0 == rStream.GetError();
+
+        if( bRet )
+        {
+            SwAfVersions aVersions;
+
+            if( nVal == AUTOFORMAT_ID_358 ||
+                    (AUTOFORMAT_ID_504 <= nVal && nVal <= AUTOFORMAT_ID) )
+            {
+                UINT16 nFileVers = SOFFICE_FILEFORMAT_40;
+                BYTE nChrSet, nCnt;
+                long nPos = rStream.Tell();
+                rStream >> nCnt >> nChrSet;
+//              if( 4 <= nCnt )
+//                  rStream >> nFileVers;
+                if( rStream.Tell() != ULONG(nPos + nCnt) )
+                {
+                    ASSERT( !this, "Der Header enthaelt mehr/neuere Daten" );
+                    rStream.Seek( nPos + nCnt );
+                }
+                rStream.SetStreamCharSet( (CharSet)nChrSet );
+                rStream.SetVersion( nFileVers );
+            }
+
+            if( nVal == AUTOFORMAT_ID_358 || nVal == AUTOFORMAT_ID_X ||
+                    (AUTOFORMAT_ID_504 <= nVal && nVal <= AUTOFORMAT_ID) )
+            {
+                aVersions.Load( rStream, nVal );        // Item-Versionen
+
+                SwTableAutoFmt* pNew;
+                USHORT nAnz = 0;
+                rStream >> nAnz;
+
+                bRet = 0 == rStream.GetError();
+
+                for( USHORT i = 0; i < nAnz; ++i )
+                {
+                    pNew = new SwTableAutoFmt( aEmptyStr );
+                    bRet = pNew->Load( rStream, aVersions );
+                    if( bRet )
+                    {
+                        Insert( pNew, Count() );
+                    }
+                    else
+                    {
+                        delete pNew;
+                        break;
+                    }
+                }
+            }
+#ifdef READ_OLDVERS
+            else if( AUTOFORMAT_OLD_ID == nVal || AUTOFORMAT_OLD_ID1 == nVal )
+            {
+                SwTableAutoFmt* pNew;
+                USHORT nAnz = 0;
+                rStream >> nAnz;
+
+                USHORT aArr[ 12 ];
+                memset( aArr, 0, 12 * sizeof( USHORT ) );
+                if( AUTOFORMAT_OLD_ID1 == nVal )
+                    for( USHORT n = 0; n < 12; ++n )
+                        rStream >> aArr[ n ];
+
+                bRet = 0 == rStream.GetError();
+
+                for( USHORT i = 0; i < nAnz; ++i )
+                {
+                    pNew = new SwTableAutoFmt( aEmptyStr );
+                    bRet = pNew->LoadOld( rStream, aArr );
+                    if( bRet )
+                    {
+                        Insert( pNew, Count() );
+                    }
+                    else
+                    {
+                        delete pNew;
+                        break;
+                    }
+                }
+            }
+#endif
+        }
+    }
+    return bRet;
+}
+
+
+BOOL SwTableAutoFmtTbl::Save( SvStream& rStream ) const
+{
+    BOOL bRet = 0 == rStream.GetError();
+    if (bRet)
+    {
+        rStream.SetVersion( SOFFICE_FILEFORMAT_40 );
+
+        // Achtung hier muss ein allgemeiner Header gespeichert werden
+        USHORT nVal = AUTOFORMAT_ID;
+        rStream << nVal
+                << (BYTE)2      // Anzahl von Zeichen des Headers incl. diesem
+                << (BYTE)GetStoreCharSet( ::gsl_getSystemTextEncoding(),
+                                              SOFFICE_FILEFORMAT_40 );
+//              << (BYTE)4      // Anzahl von Zeichen des Headers incl. diesem
+//              << (BYTE)::GetSystemCharSet()
+//              << (UNIT16)SOFFICE_FILEFORMAT_NOW;
+        bRet = 0 == rStream.GetError();
+
+        //-----------------------------------------------------------
+        // die VersionsNummer fuer alle Attribute schreiben
+        (*this)[ 0 ]->GetBoxFmt( 0 ).SaveVerionNo( rStream );
+
+        rStream << (USHORT)(Count() - 1);
+        bRet = 0 == rStream.GetError();
+
+        for( USHORT i = 1; bRet && i < Count(); ++i )
+        {
+            SwTableAutoFmt* pFmt = (*this)[ i ];
+            bRet = pFmt->Save( rStream );
+        }
+    }
+    rStream.Flush();
+    return bRet;
+}
+
+
+
diff --git a/sw/source/core/doc/tblcpy.cxx b/sw/source/core/doc/tblcpy.cxx
new file mode 100644
index 000000000000..5b8367359c00
--- /dev/null
+++ b/sw/source/core/doc/tblcpy.cxx
@@ -0,0 +1,630 @@
+/*************************************************************************
+ *
+ *  $RCSfile: tblcpy.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:16 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#define _ZFORLIST_DECLARE_TABLE
+#ifndef _ZFORLIST_HXX //autogen
+#include 
+#endif
+
+#ifndef _FRMFMT_HXX //autogen
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _CNTFRM_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _SWTABLE_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _FLDBAS_HXX
+#include 
+#endif
+#ifndef _TBLSEL_HXX
+#include 
+#endif
+#ifndef _HINTS_HXX
+#include 
+#endif
+#ifndef _TABFRM_HXX
+#include 
+#endif
+#ifndef _POOLFMT_HXX
+#include 
+#endif
+#ifndef _CELLATR_HXX
+#include 
+#endif
+#ifndef _MVSAVE_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _FMTANCHR_HXX
+#include 
+#endif
+#ifndef _UNDOBJ_HXX
+#include 
+#endif
+
+
+BOOL _FndCntntLine( const SwTableLine*& rpLine, void* pPara );
+BOOL _FndCntntBox( const SwTableBox*& rpBox, void* pPara );
+
+
+// ---------------------------------------------------------------
+
+// kopiere die Tabelle in diese.
+//  Kopiere alle Boxen einer Line in entsprechenden Boxen. Der alte Inhalt
+//  wird dabei geloescht.
+//  Ist keine mehr vorhanden, kommt der restliche Inhalt in die letzte
+//  Box einer "GrundLine".
+//  Ist auch keine Line mehr vorhanden, -> auch in die letzte Box
+//  einer "GrundLine"
+
+
+void lcl_CpyBox( const SwTable& rCpyTbl, const SwTableBox* pCpyBox,
+                    SwTable& rDstTbl, SwTableBox* pDstBox,
+                    BOOL bDelCntnt, SwUndoTblCpyTbl* pUndo )
+{
+    ASSERT( pCpyBox->GetSttNd() && pDstBox->GetSttNd(),
+            "Keine inhaltstragende Box" );
+
+    SwDoc* pCpyDoc = rCpyTbl.GetFrmFmt()->GetDoc();
+    SwDoc* pDoc = rDstTbl.GetFrmFmt()->GetDoc();
+
+    // kopiere erst den neuen und loeschen dann den alten Inhalt
+    // (keine leeren Section erzeugen; werden sonst geloescht!)
+    SwNodeRange aRg( *pCpyBox->GetSttNd(), 1,
+                    *pCpyBox->GetSttNd()->EndOfSectionNode() );
+
+    SwNodeIndex aInsIdx( *pDstBox->GetSttNd(), bDelCntnt ? 1 :
+                        pDstBox->GetSttNd()->EndOfSectionIndex() -
+                        pDstBox->GetSttIdx() );
+
+    if( pUndo )
+        pUndo->AddBoxBefore( *pDstBox, bDelCntnt );
+
+    BOOL bUndo = pDoc->DoesUndo();
+    pDoc->DoUndo( FALSE );
+
+    SwNodeIndex aSavePos( aInsIdx, -1 );
+    pCpyDoc->CopyWithFlyInFly( aRg, aInsIdx, FALSE );
+    aSavePos++;
+
+    SwTableLine* pLine = pDstBox->GetUpper();
+    while( pLine->GetUpper() )
+        pLine = pLine->GetUpper()->GetUpper();
+
+    BOOL bReplaceColl = TRUE;
+    if( bDelCntnt )
+    {
+        // zuerst die Fly loeschen, dann die entsprechenden Nodes
+        SwNodeIndex aEndNdIdx( *aInsIdx.GetNode().EndOfSectionNode() );
+
+            // Bookmarks usw. verschieben
+        {
+            SwPosition aMvPos( aInsIdx );
+            SwCntntNode* pCNd = pDoc->GetNodes().GoPrevious( &aMvPos.nNode );
+            aMvPos.nContent.Assign( pCNd, pCNd->Len() );
+            pDoc->CorrAbs( aInsIdx, aEndNdIdx, aMvPos, /*TRUE*/FALSE );
+        }
+
+        // stehen noch FlyFrames rum, loesche auch diese
+        const SwPosition* pAPos;
+        for( USHORT n = 0; n < pDoc->GetSpzFrmFmts()->Count(); ++n )
+        {
+            SwFrmFmt* pFly = (*pDoc->GetSpzFrmFmts())[n];
+            const SwFmtAnchor* pAnchor = &pFly->GetAnchor();
+            if( ( FLY_AT_CNTNT == pAnchor->GetAnchorId() ||
+                    FLY_AUTO_CNTNT == pAnchor->GetAnchorId() ) &&
+                0 != ( pAPos = pAnchor->GetCntntAnchor() ) &&
+                aInsIdx <= pAPos->nNode && pAPos->nNode <= aEndNdIdx )
+            {
+                pDoc->DelLayoutFmt( pFly );
+            }
+        }
+
+        // ist DestBox eine Headline-Box und hat Tabellen-Vorlage gesetzt,
+        // dann NICHT die TabellenHeadline-Vorlage automatisch setzen
+        if( 1 < rDstTbl.GetTabLines().Count() &&
+            pLine == rDstTbl.GetTabLines()[0] )
+        {
+            SwCntntNode* pCNd = aInsIdx.GetNode().GetCntntNode();
+            if( !pCNd )
+            {
+                SwNodeIndex aTmp( aInsIdx );
+                pCNd = pDoc->GetNodes().GoNext( &aTmp );
+            }
+
+            if( pCNd &&
+                /*RES_POOLCOLL_TABLE == */
+                RES_POOLCOLL_TABLE_HDLN !=
+                    pCNd->GetFmtColl()->GetPoolFmtId() )
+                bReplaceColl = FALSE;
+        }
+
+        pDoc->GetNodes().Delete( aInsIdx, aEndNdIdx.GetIndex() - aInsIdx.GetIndex() );
+    }
+
+    if( pUndo )
+        pUndo->AddBoxAfter( *pDstBox, bDelCntnt );
+
+    // Ueberschrift
+    SwTxtNode* pTxtNd = pDoc->GetNodes()[ aSavePos ]->GetTxtNode();
+    if( pTxtNd )
+    {
+        USHORT nPoolId = pTxtNd->GetTxtColl()->GetPoolFmtId();
+        if( bReplaceColl &&
+            (( 1 < rDstTbl.GetTabLines().Count() &&
+                pLine == rDstTbl.GetTabLines()[0] )
+                // gilt noch die Tabellen-Inhalt ??
+                ? RES_POOLCOLL_TABLE == nPoolId
+                : RES_POOLCOLL_TABLE_HDLN == nPoolId ) )
+        {
+            SwTxtFmtColl* pColl = pDoc->GetTxtCollFromPool(
+                                    RES_POOLCOLL_TABLE == nPoolId
+                                        ? RES_POOLCOLL_TABLE_HDLN
+                                        : RES_POOLCOLL_TABLE );
+            if( pColl )         // Vorlage umsetzen
+            {
+                SwPaM aPam( aSavePos );
+                aPam.SetMark();
+                aPam.Move( fnMoveForward, fnGoSection );
+                pDoc->SetTxtFmtColl( aPam, pColl );
+            }
+        }
+
+        // loesche die akt. Formel/Format/Value Werte
+        if( SFX_ITEM_SET == pDstBox->GetFrmFmt()->GetItemState( RES_BOXATR_FORMAT ) ||
+            SFX_ITEM_SET == pDstBox->GetFrmFmt()->GetItemState( RES_BOXATR_FORMULA ) ||
+            SFX_ITEM_SET == pDstBox->GetFrmFmt()->GetItemState( RES_BOXATR_VALUE ) )
+        {
+            pDstBox->ClaimFrmFmt()->ResetAttr( RES_BOXATR_FORMAT,
+                                                 RES_BOXATR_VALUE );
+        }
+
+        // kopiere die TabellenBoxAttribute - Formel/Format/Value
+        SfxItemSet aBoxAttrSet( pCpyDoc->GetAttrPool(), RES_BOXATR_FORMAT,
+                                                        RES_BOXATR_VALUE );
+        aBoxAttrSet.Put( pCpyBox->GetFrmFmt()->GetAttrSet() );
+        if( aBoxAttrSet.Count() )
+        {
+            const SfxPoolItem* pItem;
+            SvNumberFormatter* pN = pDoc->GetNumberFormatter( FALSE );
+            if( pN && pN->HasMergeFmtTbl() && SFX_ITEM_SET == aBoxAttrSet.
+                GetItemState( RES_BOXATR_FORMAT, FALSE, &pItem ) )
+            {
+                ULONG nOldIdx = ((SwTblBoxNumFormat*)pItem)->GetValue();
+                ULONG nNewIdx = pN->GetMergeFmtIndex( nOldIdx );
+                if( nNewIdx != nOldIdx )
+                    aBoxAttrSet.Put( SwTblBoxNumFormat( nNewIdx ));
+            }
+            pDstBox->ClaimFrmFmt()->SetAttr( aBoxAttrSet );
+        }
+    }
+
+    pDoc->DoUndo( bUndo );
+}
+
+// ---------------------------------------------------------------
+
+// kopiere die Tabelle in diese.
+//  Kopiere alle Boxen einer Line in entsprechenden Boxen. Der alte Inhalt
+//  wird dabei geloescht.
+//  Ist keine mehr vorhanden, kommt der restliche Inhalt in die letzte
+//  Box einer "GrundLine".
+//  Ist auch keine Line mehr vorhanden, -> auch in die letzte Box
+//  einer "GrundLine"
+
+
+BOOL SwTable::InsTable( const SwTable& rCpyTbl, const SwNodeIndex& rSttBox,
+                        SwUndoTblCpyTbl* pUndo )
+{
+    SetHTMLTableLayout( 0 );    // MIB 9.7.97: HTML-Layout loeschen
+
+    SwDoc* pDoc = GetFrmFmt()->GetDoc();
+
+    SwTableNode* pTblNd = pDoc->IsIdxInTbl( rSttBox );
+
+    // suche erstmal die Box, in die kopiert werden soll:
+    SwTableBox* pMyBox = (SwTableBox*)GetTblBox(
+            rSttBox.GetNode().FindTableBoxStartNode()->GetIndex() );
+
+    ASSERT( pMyBox, "Index steht nicht in dieser Tabelle in einer Box" );
+
+    // loesche erstmal die Frames der Tabelle
+    _FndBox aFndBox( 0, 0 );
+    aFndBox.DelFrms( pTblNd->GetTable() );
+
+    SwDoc* pCpyDoc = rCpyTbl.GetFrmFmt()->GetDoc();
+
+    {
+        // Tabellen-Formeln in die relative Darstellung umwandeln
+        SwTableFmlUpdate aMsgHnt( &rCpyTbl );
+        aMsgHnt.eFlags = TBL_RELBOXNAME;
+        pCpyDoc->UpdateTblFlds( &aMsgHnt );
+    }
+
+    SwTblNumFmtMerge aTNFM( *pCpyDoc, *pDoc );
+
+    BOOL bDelCntnt = TRUE;
+    const SwTableBox* pTmp;
+
+    for( USHORT nLines = 0; nLines < rCpyTbl.GetTabLines().Count(); ++nLines )
+    {
+        // hole die erste Box von der Copy-Line
+        const SwTableBox* pCpyBox = rCpyTbl.GetTabLines()[nLines]
+                                    ->GetTabBoxes()[0];
+        while( pCpyBox->GetTabLines().Count() )
+            pCpyBox = pCpyBox->GetTabLines()[0]->GetTabBoxes()[0];
+
+        do {
+            // kopiere erst den neuen und loeschen dann den alten Inhalt
+            // (keine leeren Section erzeugen, werden sonst geloescht!)
+            lcl_CpyBox( rCpyTbl, pCpyBox, *this, pMyBox, bDelCntnt, pUndo );
+
+            if( 0 == (pTmp = pCpyBox->FindNextBox( rCpyTbl, pCpyBox, FALSE )))
+                break;      // es folgt keine weitere Box mehr
+            pCpyBox = pTmp;
+
+            if( 0 == ( pTmp = pMyBox->FindNextBox( *this, pMyBox, FALSE )))
+                bDelCntnt = FALSE;  // kein Platz mehr ??
+            else
+                pMyBox = (SwTableBox*)pTmp;
+
+        } while( TRUE );
+
+        // suche die oberste Line
+        SwTableLine* pNxtLine = pMyBox->GetUpper();
+        while( pNxtLine->GetUpper() )
+            pNxtLine = pNxtLine->GetUpper()->GetUpper();
+        USHORT nPos = GetTabLines().C40_GETPOS( SwTableLine, pNxtLine );
+        // gibt es eine naechste ??
+        if( nPos + 1 >= GetTabLines().Count() )
+            bDelCntnt = FALSE;      // es gibt keine, alles in die letzte Box
+        else
+        {
+            // suche die naechste "Inhaltstragende Box"
+            pNxtLine = GetTabLines()[ nPos+1 ];
+            pMyBox = pNxtLine->GetTabBoxes()[0];
+            while( pMyBox->GetTabLines().Count() )
+                pMyBox = pMyBox->GetTabLines()[0]->GetTabBoxes()[0];
+            bDelCntnt = TRUE;
+        }
+    }
+
+    aFndBox.MakeFrms( pTblNd->GetTable() );     // erzeuge die Frames neu
+    return TRUE;
+}
+
+
+BOOL SwTable::InsTable( const SwTable& rCpyTbl, const SwSelBoxes& rSelBoxes,
+                        SwUndoTblCpyTbl* pUndo )
+{
+    ASSERT( !rCpyTbl.IsTblComplex() && rSelBoxes.Count(),
+            "Tabelle ist zu komplex" );
+
+    SetHTMLTableLayout( 0 );    // MIB 9.7.97: HTML-Layout loeschen
+
+    SwDoc* pDoc = GetFrmFmt()->GetDoc();
+    SwDoc* pCpyDoc = rCpyTbl.GetFrmFmt()->GetDoc();
+
+    SwTblNumFmtMerge aTNFM( *pCpyDoc, *pDoc );
+
+    SwTableBox *pTmpBox, *pSttBox = (SwTableBox*)rSelBoxes[0];
+
+    USHORT nLn, nBx;
+    _FndLine *pFLine, *pInsFLine = 0;
+    _FndBox aFndBox( 0, 0 );
+    // suche alle Boxen / Lines
+    {
+        _FndPara aPara( rSelBoxes, &aFndBox );
+        ((SwTableLines&)GetTabLines()).ForEach( &_FndLineCopyCol, &aPara );
+    }
+
+    // JP 06.09.96: Sonderfall - eine Box in der Tabelle -> in alle
+    //              selektierten Boxen kopieren!
+    if( 1 != rCpyTbl.GetTabSortBoxes().Count() )
+    {
+        SwTableLine* pSttLine = pSttBox->GetUpper();
+        USHORT nSttBox = pSttLine->GetTabBoxes().C40_GETPOS( SwTableBox, pSttBox );
+        USHORT nSttLine = GetTabLines().C40_GETPOS( SwTableLine, pSttLine );
+        _FndBox* pFndBox;
+
+        USHORT nFndCnt = aFndBox.GetLines().Count();
+        if( !nFndCnt )
+            return FALSE;
+
+        // teste ob genug Platz fuer die einzelnen Lines und Boxen ist:
+        USHORT nTstLns = 0;
+        pFLine = aFndBox.GetLines()[ 0 ];
+        pSttLine = pFLine->GetLine();
+        nSttLine = GetTabLines().C40_GETPOS( SwTableLine, pSttLine );
+        // sind ueberhaupt soviele Zeilen vorhanden
+        if( 1 == nFndCnt )
+        {
+            // in der Tabelle noch genug Platz ??
+            if( (GetTabLines().Count() - nSttLine ) <
+                rCpyTbl.GetTabLines().Count() )
+            {
+                // sollte nicht mehr soviele Lines vorhanden sein, dann
+                // teste, ob man durch einfuegen neuer zum Ziel kommt. Aber
+                // nur wenn die SSelection eine Box umfasst !!
+                if( 1 < rSelBoxes.Count() )
+                    return FALSE;
+
+                USHORT nNewLns = rCpyTbl.GetTabLines().Count() -
+                                (GetTabLines().Count() - nSttLine );
+
+                // Dann teste mal ob die Anzahl der Boxen fuer die Lines reicht
+                SwTableLine* pLastLn = GetTabLines()[ GetTabLines().Count()-1 ];
+
+                pSttBox = pFLine->GetBoxes()[0]->GetBox();
+                nSttBox = pFLine->GetLine()->GetTabBoxes().C40_GETPOS( SwTableBox, pSttBox );
+                for( USHORT n = rCpyTbl.GetTabLines().Count() - nNewLns;
+                        n < rCpyTbl.GetTabLines().Count(); ++n )
+                {
+                    SwTableLine* pCpyLn = rCpyTbl.GetTabLines()[ n ];
+
+                    if( pLastLn->GetTabBoxes().Count() < nSttBox ||
+                        ( pLastLn->GetTabBoxes().Count() - nSttBox ) <
+                            pCpyLn->GetTabBoxes().Count() )
+                        return FALSE;
+
+                    // Test auf Verschachtelungen
+                    for( nBx = 0; nBx < pCpyLn->GetTabBoxes().Count(); ++nBx )
+                        if( !( pTmpBox = pLastLn->GetTabBoxes()[ nSttBox + nBx ])
+                                    ->GetSttNd() )
+                            return FALSE;
+                }
+                // es ist also Platz fuer das zu kopierende vorhanden, also
+                // fuege entsprechend neue Zeilen ein.
+                SwTableBox* pInsBox = pLastLn->GetTabBoxes()[ nSttBox ];
+                ASSERT( pInsBox && pInsBox->GetSttNd(),
+                    "kein CntntBox oder steht nicht in dieser Tabelle" );
+                SwSelBoxes aBoxes;
+
+                if( pUndo
+                    ? !pUndo->InsertRow( *this, SelLineFromBox( pInsBox,
+                                aBoxes, TRUE ), nNewLns )
+                    : !InsertRow( pDoc, SelLineFromBox( pInsBox,
+                                aBoxes, TRUE ), nNewLns, TRUE ) )
+                    return FALSE;
+            }
+
+            nTstLns = rCpyTbl.GetTabLines().Count();        // soviele Kopieren
+        }
+        else if( 0 == (nFndCnt % rCpyTbl.GetTabLines().Count()) )
+            nTstLns = nFndCnt;
+        else
+            return FALSE;       // kein Platz fuer die Zeilen
+
+        for( nLn = 0; nLn < nTstLns; ++nLn )
+        {
+            // Zeilen sind genug vorhanden, dann ueberpruefe die Boxen
+            // je Zeile
+            pFLine = aFndBox.GetLines()[ nLn % nFndCnt ];
+            SwTableLine* pLine = pFLine->GetLine();
+            pSttBox = pFLine->GetBoxes()[0]->GetBox();
+            nSttBox = pLine->GetTabBoxes().C40_GETPOS( SwTableBox, pSttBox );
+            if( nLn >= nFndCnt )
+            {
+                // es sind im ClipBoard mehr Zeilen als selectiert wurden
+                pInsFLine = new _FndLine( GetTabLines()[ nSttLine + nLn ],
+                                        &aFndBox );
+                pLine = pInsFLine->GetLine();
+            }
+            SwTableLine* pCpyLn = rCpyTbl.GetTabLines()[ nLn %
+                                        rCpyTbl.GetTabLines().Count() ];
+
+            // zu wenig Zeilen selektiert ?
+            if( pInsFLine )
+            {
+                // eine neue Zeile wird in die FndBox eingefuegt,
+                if( pLine->GetTabBoxes().Count() < nSttBox ||
+                    ( pLine->GetTabBoxes().Count() - nSttBox ) <
+                    pFLine->GetBoxes().Count() )
+                    return FALSE;
+
+                // Test auf Verschachtelungen
+                for( nBx = 0; nBx < pFLine->GetBoxes().Count(); ++nBx )
+                {
+                    if( !( pTmpBox = pLine->GetTabBoxes()[ nSttBox + nBx ])
+                        ->GetSttNd() )
+                        return FALSE;
+                    // wenn Ok, fuege die Box in die FndLine zu
+                    pFndBox = new _FndBox( pTmpBox, pInsFLine );
+                    pInsFLine->GetBoxes().C40_INSERT( _FndBox, pFndBox, nBx );
+                }
+                aFndBox.GetLines().C40_INSERT( _FndLine, pInsFLine, nLn );
+            }
+            else if( pFLine->GetBoxes().Count() == 1 )
+            {
+                if( pLine->GetTabBoxes().Count() < nSttBox  ||
+                    ( pLine->GetTabBoxes().Count() - nSttBox ) <
+                    pCpyLn->GetTabBoxes().Count() )
+                    return FALSE;
+
+                // Test auf Verschachtelungen
+                for( nBx = 0; nBx < pCpyLn->GetTabBoxes().Count(); ++nBx )
+                {
+                    if( !( pTmpBox = pLine->GetTabBoxes()[ nSttBox + nBx ])
+                        ->GetSttNd() )
+                        return FALSE;
+                    // wenn Ok, fuege die Box in die FndLine zu
+                    if( nBx == pFLine->GetBoxes().Count() )
+                    {
+                        pFndBox = new _FndBox( pTmpBox, pFLine );
+                        pFLine->GetBoxes().C40_INSERT( _FndBox, pFndBox, nBx );
+                    }
+                }
+            }
+            else
+            {
+                // ueberpruefe die selektierten Boxen mit denen im Clipboard
+                // (n-Fach)
+                if( 0 != ( pFLine->GetBoxes().Count() %
+                            pCpyLn->GetTabBoxes().Count() ))
+                    return FALSE;
+
+                // Test auf Verschachtelungen
+                for( nBx = 0; nBx < pFLine->GetBoxes().Count(); ++nBx )
+                    if( !pFLine->GetBoxes()[ nBx ]->GetBox()->GetSttNd() )
+                        return FALSE;
+            }
+        }
+
+        if( !aFndBox.GetLines().Count() )
+            return FALSE;
+    }
+
+    {
+        // Tabellen-Formeln in die relative Darstellung umwandeln
+        SwTableFmlUpdate aMsgHnt( &rCpyTbl );
+        aMsgHnt.eFlags = TBL_RELBOXNAME;
+        pCpyDoc->UpdateTblFlds( &aMsgHnt );
+    }
+
+    // loesche die Frames
+    aFndBox.SetTableLines( *this );
+    aFndBox.DelFrms( *this );
+
+    if( 1 == rCpyTbl.GetTabSortBoxes().Count() )
+    {
+        SwTableBox *pTmpBox = rCpyTbl.GetTabSortBoxes()[0];
+        for( USHORT n = 0; n < rSelBoxes.Count(); ++n )
+            lcl_CpyBox( rCpyTbl, pTmpBox, *this,
+                        (SwTableBox*)rSelBoxes[n], TRUE, pUndo );
+    }
+    else
+        for( nLn = 0; nLn < aFndBox.GetLines().Count(); ++nLn )
+        {
+            pFLine = aFndBox.GetLines()[ nLn ];
+            SwTableLine* pCpyLn = rCpyTbl.GetTabLines()[
+                                nLn % rCpyTbl.GetTabLines().Count() ];
+            for( nBx = 0; nBx < pFLine->GetBoxes().Count(); ++nBx )
+            {
+                // Kopiere in pMyBox die pCpyBox
+                lcl_CpyBox( rCpyTbl, pCpyLn->GetTabBoxes()[
+                            nBx % pCpyLn->GetTabBoxes().Count() ],
+                    *this, pFLine->GetBoxes()[ nBx ]->GetBox(), TRUE, pUndo );
+            }
+        }
+
+    aFndBox.MakeFrms( *this );
+    return TRUE;
+}
+
+
+
+BOOL _FndCntntBox( const SwTableBox*& rpBox, void* pPara )
+{
+    SwTableBox* pBox = (SwTableBox*)rpBox;
+    if( rpBox->GetTabLines().Count() )
+        pBox->GetTabLines().ForEach( &_FndCntntLine, pPara );
+    else
+        ((SwSelBoxes*)pPara)->Insert( pBox );
+    return TRUE;
+}
+
+
+BOOL _FndCntntLine( const SwTableLine*& rpLine, void* pPara )
+{
+    ((SwTableLine*)rpLine)->GetTabBoxes().ForEach( &_FndCntntBox, pPara );
+    return TRUE;
+}
+
+
+// suche alle Inhaltstragenden-Boxen dieser Box
+SwSelBoxes& SwTable::SelLineFromBox( const SwTableBox* pBox,
+                                    SwSelBoxes& rBoxes, BOOL bToTop ) const
+{
+    SwTableLine* pLine = (SwTableLine*)pBox->GetUpper();
+    if( bToTop )
+        while( pLine->GetUpper() )
+            pLine = pLine->GetUpper()->GetUpper();
+
+    // alle alten loeschen
+    rBoxes.Remove( USHORT(0), rBoxes.Count() );
+    pLine->GetTabBoxes().ForEach( &_FndCntntBox, &rBoxes );
+    return rBoxes;
+}
+
+
diff --git a/sw/source/core/doc/tblrwcl.cxx b/sw/source/core/doc/tblrwcl.cxx
new file mode 100644
index 000000000000..0d48e3c2ca7d
--- /dev/null
+++ b/sw/source/core/doc/tblrwcl.cxx
@@ -0,0 +1,4508 @@
+/*************************************************************************
+ *
+ *  $RCSfile: tblrwcl.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:16 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#define _ZFORLIST_DECLARE_TABLE
+#define ITEMID_BOXINFO      SID_ATTR_BORDER_INNER
+
+#ifndef _SVX_BRSHITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_PROTITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BOXITEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _FMTFSIZE_HXX //autogen
+#include 
+#endif
+#ifndef _FMTORNT_HXX //autogen
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _CNTFRM_HXX
+#include 
+#endif
+#ifndef _TABFRM_HXX //autogen
+#include 
+#endif
+#ifndef _FRMTOOL_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _SWTABLE_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _TBLSEL_HXX
+#include 
+#endif
+#ifndef _FLDBAS_HXX
+#include 
+#endif
+#ifndef _HINTS_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include 
+#endif
+#ifndef _TABFRM_HXX
+#include 
+#endif
+#ifndef _ROWFRM_HXX
+#include 
+#endif
+#ifndef _DDEFLD_HXX
+#include 
+#endif
+#ifndef _UNDOBJ_HXX
+#include 
+#endif
+#ifndef _TABFRM_HXX
+#include 
+#endif
+#ifndef _CELLATR_HXX
+#include 
+#endif
+#ifndef _MVSAVE_HXX
+#include 
+#endif
+#ifndef _SWTBLFMT_HXX
+#include 
+#endif
+#ifndef _SWDDETBL_HXX
+#include 
+#endif
+#ifndef _POOLFMT_HXX
+#include 
+#endif
+#ifndef _TBLRWCL_HXX
+#include 
+#endif
+
+#define COLFUZZY 20
+
+typedef SwTableLine* SwTableLinePtr;
+SV_DECL_PTRARR_SORT( SwSortTableLines, SwTableLinePtr, 16, 16 );
+SV_IMPL_PTRARR_SORT( SwSortTableLines, SwTableLinePtr );
+
+SV_IMPL_PTRARR( _SwShareBoxFmts, SwShareBoxFmt* )
+
+// fuers setzen der Frame-Formate an den Boxen reicht es, das aktuelle
+// im Array zu suchen. Ist es vorhanden, so gebe das neue zurueck
+struct _CpyTabFrm
+{
+    union {
+        SwTableBoxFmt *pFrmFmt;     // fuer CopyCol
+        SwTwips nSize;              // fuer DelCol
+    } Value;
+    SwTableBoxFmt *pNewFrmFmt;
+
+    _CpyTabFrm( SwTableBoxFmt* pAktFrmFmt ) : pNewFrmFmt( 0 )
+    {   Value.pFrmFmt = pAktFrmFmt; }
+
+    _CpyTabFrm& operator=( const _CpyTabFrm& );
+
+    BOOL operator==( const _CpyTabFrm& rCpyTabFrm )
+        { return  (ULONG)Value.nSize == (ULONG)rCpyTabFrm.Value.nSize; }
+    BOOL operator<( const _CpyTabFrm& rCpyTabFrm )
+        { return  (ULONG)Value.nSize < (ULONG)rCpyTabFrm.Value.nSize; }
+};
+
+struct CR_SetBoxWidth
+{
+    SwSelBoxes aBoxes;
+    SwSortTableLines aLines;
+    SvUShorts aLinesWidth;
+    SwShareBoxFmts aShareFmts;
+    SwTableNode* pTblNd;
+    SwUndoTblNdsChg* pUndo;
+    SwTwips nDiff, nSide, nMaxSize, nLowerDiff;
+    USHORT nMode, nTblWidth, nRemainWidth, nBoxWidth;
+    BOOL bBigger, bLeft, bSplittBox, bAnyBoxFnd;
+
+    CR_SetBoxWidth( USHORT eType, SwTwips nDif, SwTwips nSid, SwTwips nTblW,
+                    SwTwips nMax, SwTableNode* pTNd )
+        : nDiff( nDif ), nSide( nSid ), nMaxSize( nMax ),
+        nTblWidth( (USHORT)nTblW ), nRemainWidth( 0 ),
+        nLowerDiff( 0 ), bAnyBoxFnd( FALSE ),
+        pTblNd( pTNd ), bSplittBox( FALSE ), nBoxWidth( 0 )
+    {
+        bLeft = WH_COL_LEFT == ( eType & 0xff ) ||
+                WH_CELL_LEFT == ( eType & 0xff );
+        bBigger = 0 != (eType & WH_FLAG_BIGGER );
+        nMode = pTblNd->GetTable().GetTblChgMode();
+    }
+    CR_SetBoxWidth( const CR_SetBoxWidth& rCpy )
+        : nDiff( rCpy.nDiff ), nMode( rCpy.nMode ),
+        nSide( rCpy.nSide ), bBigger( rCpy.bBigger ), bLeft( rCpy.bLeft ),
+        bSplittBox( rCpy.bSplittBox ), bAnyBoxFnd( rCpy.bAnyBoxFnd ),
+        nTblWidth( rCpy.nTblWidth ), nRemainWidth( rCpy.nRemainWidth ),
+        pTblNd( rCpy.pTblNd ), nMaxSize( rCpy.nMaxSize ), nLowerDiff( 0 ),
+        pUndo( rCpy.pUndo ), nBoxWidth( nBoxWidth )
+    {
+        aLines.Insert( &rCpy.aLines );
+        aLinesWidth.Insert( &rCpy.aLinesWidth, 0 );
+    }
+
+    SwUndoTblNdsChg* CreateUndo( USHORT nUndoType )
+    {
+        return pUndo = new SwUndoTblNdsChg( nUndoType, aBoxes, *pTblNd );
+    }
+
+    void LoopClear()
+    {
+        nLowerDiff = 0; nRemainWidth = 0;
+    }
+
+    void AddBoxWidth( const SwTableBox& rBox, USHORT nWidth )
+    {
+        SwTableLinePtr p = (SwTableLine*)rBox.GetUpper();
+        USHORT nFndPos;
+        if( aLines.Insert( p, nFndPos ))
+            aLinesWidth.Insert( nWidth, nFndPos );
+        else
+            aLinesWidth[ nFndPos ] += nWidth;
+    }
+
+    USHORT GetBoxWidth( const SwTableLine& rLn ) const
+    {
+        SwTableLinePtr p = (SwTableLine*)&rLn;
+        USHORT nFndPos;
+        if( aLines.Seek_Entry( p, &nFndPos ) )
+            nFndPos = aLinesWidth[ nFndPos ];
+        else
+            nFndPos = 0;
+        return nFndPos;
+    }
+};
+
+BOOL lcl_SetSelBoxWidth( SwTableLine* pLine, CR_SetBoxWidth& rParam,
+                         SwTwips nDist, BOOL bCheck );
+BOOL lcl_SetOtherBoxWidth( SwTableLine* pLine, CR_SetBoxWidth& rParam,
+                                SwTwips nDist, BOOL bCheck );
+BOOL lcl_InsSelBox( SwTableLine* pLine, CR_SetBoxWidth& rParam,
+                                SwTwips nDist, BOOL bCheck );
+BOOL lcl_InsOtherBox( SwTableLine* pLine, CR_SetBoxWidth& rParam,
+                                SwTwips nDist, BOOL bCheck );
+BOOL lcl_DelSelBox( SwTableLine* pLine, CR_SetBoxWidth& rParam,
+                                SwTwips nDist, BOOL bCheck );
+BOOL lcl_DelOtherBox( SwTableLine* pLine, CR_SetBoxWidth& rParam,
+                                SwTwips nDist, BOOL bCheck );
+
+typedef BOOL (*FN_lcl_SetBoxWidth)(SwTableLine*, CR_SetBoxWidth&, SwTwips, BOOL );
+
+#if !defined( PRODUCT ) || defined( JP_DEBUG )
+
+void _CheckBoxWidth( const SwTableLine& rLine, SwTwips nSize );
+
+#define CHECKBOXWIDTH                                           \
+    {                                                           \
+        SwTwips nSize = GetFrmFmt()->GetFrmSize().GetWidth();   \
+        for( USHORT n = 0; n < aLines.Count(); ++n  )           \
+            ::_CheckBoxWidth( *aLines[ n ], nSize );            \
+    }
+
+#else
+
+#define CHECKBOXWIDTH
+
+#endif
+
+
+struct CR_SetLineHeight
+{
+    SwSelBoxes aBoxes;
+    SwShareBoxFmts aShareFmts;
+    SwTableNode* pTblNd;
+    SwUndoTblNdsChg* pUndo;
+    SwTwips nMaxSpace, nMaxHeight;
+    USHORT nMode, nLines;
+    BOOL bBigger, bTop, bSplittBox, bAnyBoxFnd;
+
+    CR_SetLineHeight( USHORT eType, SwTableNode* pTNd )
+        : nMaxSpace( 0 ), nLines( 0 ), nMaxHeight( 0 ),
+        bAnyBoxFnd( FALSE ), bSplittBox( FALSE ) ,
+        pTblNd( pTNd ), pUndo( 0 )
+    {
+        bTop = WH_ROW_TOP == ( eType & 0xff ) || WH_CELL_TOP == ( eType & 0xff );
+        bBigger = 0 != (eType & WH_FLAG_BIGGER );
+        if( eType & WH_FLAG_INSDEL )
+            bBigger = !bBigger;
+        BOOL bTst = (0 != (eType & WH_FLAG_BIGGER )) ^ (0 != ( eType & WH_FLAG_INSDEL ));
+        nMode = pTblNd->GetTable().GetTblChgMode();
+    }
+    CR_SetLineHeight( const CR_SetLineHeight& rCpy )
+        : nMode( rCpy.nMode ), nMaxSpace( rCpy.nMaxSpace ),
+        bBigger( rCpy.bBigger ), bTop( rCpy.bTop ),
+        bSplittBox( rCpy.bSplittBox ), bAnyBoxFnd( rCpy.bAnyBoxFnd ),
+        pTblNd( rCpy.pTblNd ), nLines( rCpy.nLines ),
+        nMaxHeight( rCpy.nMaxHeight ),
+        pUndo( rCpy.pUndo )
+    {}
+
+    SwUndoTblNdsChg* CreateUndo( USHORT nUndoType )
+    {
+        return pUndo = new SwUndoTblNdsChg( nUndoType, aBoxes, *pTblNd );
+    }
+};
+
+BOOL lcl_SetSelLineHeight( SwTableLine* pLine, CR_SetLineHeight& rParam,
+                         SwTwips nDist, BOOL bCheck );
+BOOL lcl_SetOtherLineHeight( SwTableLine* pLine, CR_SetLineHeight& rParam,
+                                SwTwips nDist, BOOL bCheck );
+BOOL lcl_InsDelSelLine( SwTableLine* pLine, CR_SetLineHeight& rParam,
+                                SwTwips nDist, BOOL bCheck );
+
+typedef BOOL (*FN_lcl_SetLineHeight)(SwTableLine*, CR_SetLineHeight&, SwTwips, BOOL );
+
+_CpyTabFrm& _CpyTabFrm::operator=( const _CpyTabFrm& rCpyTabFrm )
+{
+    pNewFrmFmt = rCpyTabFrm.pNewFrmFmt;
+    Value = rCpyTabFrm.Value;
+    return *this;
+}
+
+SV_DECL_VARARR_SORT( _CpyTabFrms, _CpyTabFrm, 0, 50 )
+SV_IMPL_VARARR_SORT( _CpyTabFrms, _CpyTabFrm )
+
+void lcl_DelCpyTabFrmFmts( _CpyTabFrm& rArr );
+
+// ---------------------------------------------------------------
+
+struct _CpyPara
+{
+    SwDoc* pDoc;
+    SwTableNode* pTblNd;
+    _CpyTabFrms& rTabFrmArr;
+    SwTableLine* pInsLine;
+    SwTableBox* pInsBox;
+    ULONG nOldSize, nNewSize;           // zum Korrigieren der Size-Attribute
+    USHORT nCpyCnt, nInsPos;
+    BYTE nDelBorderFlag;
+    BOOL bCpyCntnt;
+
+    _CpyPara( SwTableNode* pNd, USHORT nCopies, _CpyTabFrms& rFrmArr,
+                BOOL bCopyContent = TRUE )
+        : pDoc( pNd->GetDoc() ), pTblNd( pNd ), nCpyCnt(nCopies), rTabFrmArr(rFrmArr),
+        pInsLine(0), pInsBox(0), nInsPos(0), nNewSize(0), nOldSize(0),
+        bCpyCntnt( bCopyContent ), nDelBorderFlag( 0 )
+        {}
+    _CpyPara( const _CpyPara& rPara, SwTableLine* pLine )
+        : pDoc(rPara.pDoc), pTblNd(rPara.pTblNd), nCpyCnt(rPara.nCpyCnt),
+        rTabFrmArr(rPara.rTabFrmArr), pInsLine(pLine), pInsBox(rPara.pInsBox),
+        nInsPos(0), nNewSize(rPara.nNewSize), nOldSize(0),
+        bCpyCntnt( rPara.bCpyCntnt ), nDelBorderFlag( rPara.nDelBorderFlag )
+        {}
+    _CpyPara( const _CpyPara& rPara, SwTableBox* pBox )
+        : pDoc(rPara.pDoc), pTblNd(rPara.pTblNd), nCpyCnt(rPara.nCpyCnt),
+        rTabFrmArr(rPara.rTabFrmArr), pInsLine(rPara.pInsLine), pInsBox(pBox),
+        nInsPos(0), nNewSize(rPara.nNewSize),nOldSize(rPara.nOldSize),
+        bCpyCntnt( rPara.bCpyCntnt ), nDelBorderFlag( rPara.nDelBorderFlag )
+        {}
+    void SetBoxWidth( SwTableBox* pBox );
+};
+
+
+BOOL lcl_CopyCol( const _FndBox*& rpFndBox, void* pPara )
+{
+    _CpyPara* pCpyPara = (_CpyPara*)pPara;
+
+    // suche das FrmFmt im Array aller Frame-Formate
+    SwTableBox* pBox = (SwTableBox*)rpFndBox->GetBox();
+    _CpyTabFrm aFindFrm( (SwTableBoxFmt*)pBox->GetFrmFmt() );
+
+    USHORT nFndPos;
+    if( pCpyPara->nCpyCnt )
+    {
+        if( !pCpyPara->rTabFrmArr.Seek_Entry( aFindFrm, &nFndPos ))
+        {
+            // fuer das verschachtelte Kopieren sicher auch das neue Format
+            // als alt.
+            SwTableBoxFmt* pNewFmt = (SwTableBoxFmt*)pBox->ClaimFrmFmt();
+
+            // suche die selektierten Boxen in der Line:
+            _FndLine* pCmpLine;
+            SwFmtFrmSize aFrmSz( pNewFmt->GetFrmSize() );
+            if( pBox->GetTabLines().Count() &&
+                ( pCmpLine = rpFndBox->GetLines()[ 0 ])->GetBoxes().Count()
+                    != pCmpLine->GetLine()->GetTabBoxes().Count() )
+            {
+                // die erste Line sollte reichen
+                _FndBoxes& rFndBoxes = pCmpLine->GetBoxes();
+                long nSz = 0;
+                for( USHORT n = rFndBoxes.Count(); n; )
+                    nSz += rFndBoxes[ --n ]->GetBox()->GetFrmFmt()->GetFrmSize().GetWidth();
+                aFrmSz.SetWidth( aFrmSz.GetWidth() -
+                                            nSz / ( pCpyPara->nCpyCnt + 1 ) );
+                pNewFmt->SetAttr( aFrmSz );
+                aFrmSz.SetWidth( nSz / ( pCpyPara->nCpyCnt + 1 ) );
+
+                // fuer die neue Box ein neues Format mit der Groesse anlegen!
+                aFindFrm.pNewFrmFmt = (SwTableBoxFmt*)pNewFmt->GetDoc()->
+                                            MakeTableLineFmt();
+                *aFindFrm.pNewFrmFmt = *pNewFmt;
+                aFindFrm.pNewFrmFmt->SetAttr( aFrmSz );
+            }
+            else
+            {
+                aFrmSz.SetWidth( aFrmSz.GetWidth() / ( pCpyPara->nCpyCnt + 1 ) );
+                pNewFmt->SetAttr( aFrmSz );
+
+                aFindFrm.pNewFrmFmt = pNewFmt;
+                pCpyPara->rTabFrmArr.Insert( aFindFrm );
+                aFindFrm.Value.pFrmFmt = pNewFmt;
+                pCpyPara->rTabFrmArr.Insert( aFindFrm );
+            }
+        }
+        else
+        {
+            aFindFrm = pCpyPara->rTabFrmArr[ nFndPos ];
+//          aFindFrm.pNewFrmFmt->Add( pBox );
+            pBox->ChgFrmFmt( (SwTableBoxFmt*)aFindFrm.pNewFrmFmt );
+        }
+    }
+    else
+    {
+        if( pCpyPara->nDelBorderFlag &&
+            pCpyPara->rTabFrmArr.Seek_Entry( aFindFrm, &nFndPos ))
+            aFindFrm = pCpyPara->rTabFrmArr[ nFndPos ];
+        else
+            aFindFrm.pNewFrmFmt = (SwTableBoxFmt*)pBox->GetFrmFmt();
+    }
+
+    if( rpFndBox->GetLines().Count() )
+    {
+        pBox = new SwTableBox( aFindFrm.pNewFrmFmt,
+                    rpFndBox->GetLines().Count(), pCpyPara->pInsLine );
+        pCpyPara->pInsLine->GetTabBoxes().C40_INSERT( SwTableBox, pBox, pCpyPara->nInsPos++);
+        _CpyPara aPara( *pCpyPara, pBox );
+        aPara.nDelBorderFlag &= 7;
+
+        ((_FndBox*)rpFndBox)->GetLines().ForEach( &lcl_CopyRow, &aPara );
+    }
+    else
+    {
+        ::_InsTblBox( pCpyPara->pDoc, pCpyPara->pTblNd, pCpyPara->pInsLine,
+                    aFindFrm.pNewFrmFmt, pBox, pCpyPara->nInsPos++ );
+
+        const _FndBoxes& rFndBxs = rpFndBox->GetUpper()->GetBoxes();
+        if( 8 > pCpyPara->nDelBorderFlag
+                ? pCpyPara->nDelBorderFlag
+                : rpFndBox == rFndBxs[ rFndBxs.Count() - 1 ] )
+        {
+            const SvxBoxItem& rBoxItem = pBox->GetFrmFmt()->GetBox();
+            if( 8 > pCpyPara->nDelBorderFlag
+                    ? rBoxItem.GetTop()
+                    : rBoxItem.GetRight() )
+            {
+                aFindFrm.Value.pFrmFmt = (SwTableBoxFmt*)pBox->GetFrmFmt();
+
+                SvxBoxItem aNew( rBoxItem );
+                if( 8 > pCpyPara->nDelBorderFlag )
+                    aNew.SetLine( 0, BOX_LINE_TOP );
+                else
+                    aNew.SetLine( 0, BOX_LINE_RIGHT );
+
+                if( 1 == pCpyPara->nDelBorderFlag ||
+                    8 == pCpyPara->nDelBorderFlag )
+                {
+                    // es wird dahinter kopiert, bei allen Boxen die
+                    // TopBorderLine loeschen
+                    pBox = pCpyPara->pInsLine->GetTabBoxes()[
+                                            pCpyPara->nInsPos - 1 ];
+                }
+
+                aFindFrm.pNewFrmFmt = (SwTableBoxFmt*)pBox->GetFrmFmt();
+
+                // ansonsten wird davor kopiert und die erste Line behaelt
+                // die TopLine und an der originalen wird sie entfernt
+                pBox->ClaimFrmFmt()->SetAttr( aNew );
+
+                if( !pCpyPara->nCpyCnt )
+                    pCpyPara->rTabFrmArr.Insert( aFindFrm );
+            }
+        }
+    }
+    return TRUE;
+}
+
+BOOL lcl_CopyRow( const _FndLine*& rpFndLine, void* pPara )
+{
+    _CpyPara* pCpyPara = (_CpyPara*)pPara;
+    SwTableLine* pNewLine = new SwTableLine(
+                            (SwTableLineFmt*)rpFndLine->GetLine()->GetFrmFmt(),
+                        rpFndLine->GetBoxes().Count(), pCpyPara->pInsBox );
+    if( pCpyPara->pInsBox )
+    {
+        pCpyPara->pInsBox->GetTabLines().C40_INSERT( SwTableLine, pNewLine, pCpyPara->nInsPos++ );
+    }
+    else
+    {
+        pCpyPara->pTblNd->GetTable().GetTabLines().C40_INSERT( SwTableLine, pNewLine,
+                                                pCpyPara->nInsPos++ );
+    }
+
+    _CpyPara aPara( *pCpyPara, pNewLine );
+    ((_FndLine*)rpFndLine)->GetBoxes().ForEach( &lcl_CopyCol, &aPara );
+
+    pCpyPara->nDelBorderFlag &= 0xf8;
+    return TRUE;
+}
+
+//-----------------------------------------------------------
+
+void lcl_InsCol( _FndLine* pFndLn, _CpyPara& rCpyPara, USHORT nCpyCnt,
+                BOOL bBehind )
+{
+    // Bug 29124: nicht nur in den Grundlines kopieren. Wenns geht, so weit
+    //              runter wie moeglich.
+    _FndBox* pFBox;
+    if( 1 == pFndLn->GetBoxes().Count() &&
+        !( pFBox = pFndLn->GetBoxes()[ 0 ] )->GetBox()->GetSttNd() )
+    {
+        // eine Box mit mehreren Lines, also in diese Lines einfuegen
+        for( USHORT n = 0; n < pFBox->GetLines().Count(); ++n )
+            lcl_InsCol( pFBox->GetLines()[ n ], rCpyPara, nCpyCnt, bBehind );
+    }
+    else
+    {
+        rCpyPara.pInsLine = pFndLn->GetLine();
+        SwTableBox* pBox = pFndLn->GetBoxes()[ bBehind ?
+                    pFndLn->GetBoxes().Count()-1 : 0 ]->GetBox();
+        rCpyPara.nInsPos = pFndLn->GetLine()->GetTabBoxes().C40_GETPOS( SwTableBox, pBox );
+        USHORT nBoxPos = rCpyPara.nInsPos;
+        if( bBehind )
+            ++rCpyPara.nInsPos;
+
+        for( USHORT n = 0; n < nCpyCnt; ++n )
+        {
+            if( n + 1 == nCpyCnt && bBehind )
+                rCpyPara.nDelBorderFlag = 9;
+            else
+                rCpyPara.nDelBorderFlag = 8;
+            pFndLn->GetBoxes().ForEach( &lcl_CopyCol, &rCpyPara );
+        }
+    }
+}
+
+
+BOOL SwTable::InsertCol( SwDoc* pDoc, const SwSelBoxes& rBoxes,
+                        USHORT nCnt, BOOL bBehind )
+{
+    ASSERT( pDoc && rBoxes.Count() && nCnt, "keine gueltige Box-Liste" );
+    SwTableNode* pTblNd = (SwTableNode*)rBoxes[0]->GetSttNd()->FindTableNode();
+    if( !pTblNd )
+        return FALSE;
+
+    // suche alle Boxen / Lines
+    _FndBox aFndBox( 0, 0 );
+    {
+        _FndPara aPara( rBoxes, &aFndBox );
+        GetTabLines().ForEach( &_FndLineCopyCol, &aPara );
+    }
+    if( !aFndBox.GetLines().Count() )
+        return FALSE;
+
+    SetHTMLTableLayout( 0 );    // MIB 9.7.97: HTML-Layout loeschen
+
+    //Lines fuer das Layout-Update herausuchen.
+    aFndBox.SetTableLines( *this );
+    aFndBox.DelFrms( *this );
+    aFndBox.SaveChartData( *this );
+
+    _CpyTabFrms aTabFrmArr;
+    _CpyPara aCpyPara( pTblNd, nCnt, aTabFrmArr );
+
+    for( USHORT n = 0; n < aFndBox.GetLines().Count(); ++n )
+        lcl_InsCol( aFndBox.GetLines()[ n ], aCpyPara, nCnt, bBehind );
+
+    // dann raeume die Struktur dieser Line noch mal auf, generell alle
+    GCLines();
+
+    //Layout updaten
+    aFndBox.MakeFrms( *this );
+    aFndBox.RestoreChartData( *this );
+    CHECKBOXWIDTH
+    return TRUE;
+}
+
+
+BOOL SwTable::InsertRow( SwDoc* pDoc, const SwSelBoxes& rBoxes,
+                        USHORT nCnt, BOOL bBehind )
+{
+    ASSERT( pDoc && rBoxes.Count() && nCnt, "keine gueltige Box-Liste" );
+    SwTableNode* pTblNd = (SwTableNode*)rBoxes[0]->GetSttNd()->FindTableNode();
+    if( !pTblNd )
+        return FALSE;
+
+    // suche alle Boxen / Lines
+    _FndBox aFndBox( 0, 0 );
+    {
+        _FndPara aPara( rBoxes, &aFndBox );
+        GetTabLines().ForEach( &_FndLineCopyCol, &aPara );
+    }
+    if( !aFndBox.GetLines().Count() )
+        return FALSE;
+
+    SetHTMLTableLayout( 0 );    // MIB 9.7.97: HTML-Layout loeschen
+
+    _FndBox* pFndBox = &aFndBox;
+    {
+        _FndLine* pFndLine;
+        while( 1 == pFndBox->GetLines().Count() &&
+                1 == ( pFndLine = pFndBox->GetLines()[ 0 ])->GetBoxes().Count() )
+        {
+            // nicht zu weit runter, eine Line mit Boxen muss nachbleiben!!
+            _FndBox* pTmpBox = pFndLine->GetBoxes()[ 0 ];
+            if( pTmpBox->GetLines().Count() )
+                pFndBox = pTmpBox;
+            else
+                break;
+        }
+    }
+
+    //Lines fuer das Layout-Update herausuchen.
+    const FASTBOOL bLayout = 0 != SwClientIter( *GetFrmFmt() ).First( TYPE(SwTabFrm) );
+    if ( bLayout )
+    {
+        aFndBox.SetTableLines( *this );
+        if( pFndBox != &aFndBox )
+            aFndBox.DelFrms( *this );
+        aFndBox.SaveChartData( *this );
+    }
+
+    _CpyTabFrms aTabFrmArr;
+    _CpyPara aCpyPara( pTblNd, 0, aTabFrmArr );
+
+    SwTableLine* pLine = pFndBox->GetLines()[ bBehind ?
+                    pFndBox->GetLines().Count()-1 : 0 ]->GetLine();
+    if( &aFndBox == pFndBox )
+        aCpyPara.nInsPos = GetTabLines().C40_GETPOS( SwTableLine, pLine );
+    else
+    {
+        aCpyPara.pInsBox = pFndBox->GetBox();
+        aCpyPara.nInsPos = pFndBox->GetBox()->GetTabLines().C40_GETPOS( SwTableLine, pLine );
+    }
+
+    USHORT nLinePos = aCpyPara.nInsPos;
+    if( bBehind )
+    {
+        ++aCpyPara.nInsPos;
+        aCpyPara.nDelBorderFlag = 1;
+    }
+    else
+        aCpyPara.nDelBorderFlag = 2;
+
+    for( USHORT nCpyCnt = 0; nCpyCnt < nCnt; ++nCpyCnt )
+    {
+        if( bBehind )
+            aCpyPara.nDelBorderFlag = 1;
+        pFndBox->GetLines().ForEach( &lcl_CopyRow, &aCpyPara );
+    }
+
+    // dann raeume die Struktur dieser Line noch mal auf, generell alle
+    if( !pDoc->IsInReading() )
+        GCLines();
+
+    //Layout updaten
+    if ( bLayout )
+    {
+        if( pFndBox != &aFndBox )
+            aFndBox.MakeFrms( *this );
+        else
+            aFndBox.MakeNewFrms( *this, nCnt, bBehind );
+        aFndBox.RestoreChartData( *this );
+    }
+    CHECKBOXWIDTH
+    return TRUE;
+}
+
+BOOL _FndBoxAppendRowLine( const SwTableLine*& rpLine, void* pPara );
+
+BOOL _FndBoxAppendRowBox( const SwTableBox*& rpBox, void* pPara )
+{
+    _FndPara* pFndPara = (_FndPara*)pPara;
+    _FndBox* pFndBox = new _FndBox( (SwTableBox*)rpBox, pFndPara->pFndLine );
+    if( rpBox->GetTabLines().Count() )
+    {
+        _FndPara aPara( *pFndPara, pFndBox );
+        pFndBox->GetBox()->GetTabLines().ForEach( &_FndBoxAppendRowLine, &aPara );
+        if( !pFndBox->GetLines().Count() )
+            delete pFndBox;
+    }
+    else
+        pFndPara->pFndLine->GetBoxes().C40_INSERT( _FndBox, pFndBox,
+                        pFndPara->pFndLine->GetBoxes().Count() );
+    return TRUE;
+}
+
+BOOL _FndBoxAppendRowLine( const SwTableLine*& rpLine, void* pPara )
+{
+    _FndPara* pFndPara = (_FndPara*)pPara;
+    _FndLine* pFndLine = new _FndLine( (SwTableLine*)rpLine, pFndPara->pFndBox );
+    _FndPara aPara( *pFndPara, pFndLine );
+    pFndLine->GetLine()->GetTabBoxes().ForEach( &_FndBoxAppendRowBox, &aPara );
+    if( pFndLine->GetBoxes().Count() )
+    {
+        pFndPara->pFndBox->GetLines().C40_INSERT( _FndLine, pFndLine,
+                pFndPara->pFndBox->GetLines().Count() );
+    }
+    else
+        delete pFndLine;
+    return TRUE;
+}
+
+
+BOOL SwTable::AppendRow( SwDoc* pDoc, USHORT nCnt )
+{
+    SwTableNode* pTblNd = (SwTableNode*)aSortCntBoxes[0]->GetSttNd()->FindTableNode();
+    if( !pTblNd )
+        return FALSE;
+
+    // suche alle Boxen / Lines
+    _FndBox aFndBox( 0, 0 );
+    {
+        const SwTableLine* pLLine = GetTabLines()[ GetTabLines().Count()-1 ];
+
+        const SwSelBoxes* pBxs = 0;     // Dummy !!!
+        _FndPara aPara( *pBxs, &aFndBox );
+
+        _FndBoxAppendRowLine( pLLine, &aPara );
+    }
+    if( !aFndBox.GetLines().Count() )
+        return FALSE;
+
+    SetHTMLTableLayout( 0 );    // MIB 9.7.97: HTML-Layout loeschen
+
+    //Lines fuer das Layout-Update herausuchen.
+    const FASTBOOL bLayout = 0 != SwClientIter( *GetFrmFmt() ).First( TYPE(SwTabFrm) );
+    if( bLayout )
+    {
+        aFndBox.SetTableLines( *this );
+        aFndBox.SaveChartData( *this );
+    }
+
+    _CpyTabFrms aTabFrmArr;
+    _CpyPara aCpyPara( pTblNd, 0, aTabFrmArr );
+    aCpyPara.nInsPos = GetTabLines().Count();
+    aCpyPara.nDelBorderFlag = 1;
+
+    for( USHORT nCpyCnt = 0; nCpyCnt < nCnt; ++nCpyCnt )
+    {
+        aCpyPara.nDelBorderFlag = 1;
+        aFndBox.GetLines().ForEach( &lcl_CopyRow, &aCpyPara );
+    }
+
+    // dann raeume die Struktur dieser Line noch mal auf, generell alle
+    if( !pDoc->IsInReading() )
+        GCLines();
+
+    //Layout updaten
+    if ( bLayout )
+    {
+        aFndBox.MakeNewFrms( *this, nCnt, TRUE );
+        aFndBox.RestoreChartData( *this );
+    }
+    CHECKBOXWIDTH
+    return TRUE;
+}
+
+
+void lcl_LastBoxSetWidth( SwTableBoxes &rBoxes, const long nOffset,
+                            SwShareBoxFmts& rShareFmts );
+
+void lcl_LastBoxSetWidthLine( SwTableLines &rLines, const long nOffset,
+                                SwShareBoxFmts& rShareFmts )
+{
+    for ( USHORT i = 0; i < rLines.Count(); ++i )
+        ::lcl_LastBoxSetWidth( rLines[i]->GetTabBoxes(), nOffset, rShareFmts) ;
+}
+
+void lcl_LastBoxSetWidth( SwTableBoxes &rBoxes, const long nOffset,
+                            SwShareBoxFmts& rShareFmts )
+{
+    SwTableBox& rBox = *rBoxes[ rBoxes.Count() - 1 ];
+    if( !rBox.GetSttNd() )
+        ::lcl_LastBoxSetWidthLine( rBox.GetTabLines(), nOffset, rShareFmts );
+
+    //Die Box anpassen
+    SwFrmFmt *pBoxFmt = rBox.GetFrmFmt();
+    SwFmtFrmSize aNew( pBoxFmt->GetFrmSize() );
+    aNew.SetWidth( aNew.GetWidth() + nOffset );
+    SwFrmFmt *pFmt = rShareFmts.GetFormat( *pBoxFmt, aNew );
+    if( pFmt )
+        rBox.ChgFrmFmt( (SwTableBoxFmt*)pFmt );
+    else
+    {
+        pFmt = rBox.ClaimFrmFmt();
+
+        pFmt->LockModify();
+        pFmt->SetAttr( aNew );
+        pFmt->UnlockModify();
+
+        rShareFmts.AddFormat( *pBoxFmt, *pFmt );
+    }
+}
+
+void _DeleteBox( SwTable& rTbl, SwTableBox* pBox, SwUndo* pUndo,
+                BOOL bCalcNewSize, const BOOL bCorrBorder,
+                SwShareBoxFmts* pShareFmts )
+{
+    do {
+        SwTwips nBoxSz = bCalcNewSize ?
+                pBox->GetFrmFmt()->GetFrmSize().GetWidth() : 0;
+        SwTableLine* pLine = pBox->GetUpper();
+        SwTableBoxes& rTblBoxes = pLine->GetTabBoxes();
+        USHORT nDelPos = rTblBoxes.C40_GETPOS( SwTableBox, pBox );
+        SwTableBox* pUpperBox = pBox->GetUpper()->GetUpper();
+
+        // Sonderbehandlung fuer Umrandung:
+        if( bCorrBorder && 1 < rTblBoxes.Count() )
+        {
+            BOOL bChgd = FALSE;
+            const SvxBoxItem& rBoxItem = pBox->GetFrmFmt()->GetBox();
+
+            if( rBoxItem.GetLeft() || rBoxItem.GetRight() )
+            {
+                //JP 02.04.97:  1.Teil fuer Bug 36271
+                // zuerst die linken/rechten Kanten
+                if( nDelPos + 1 < rTblBoxes.Count() )
+                {
+                    SwTableBox* pNxtBox = rTblBoxes[ nDelPos + 1 ];
+                    const SvxBoxItem& rNxtBoxItem = pNxtBox->GetFrmFmt()->GetBox();
+
+                    SwTableBox* pPrvBox = nDelPos ? rTblBoxes[ nDelPos - 1 ] : 0;
+
+                    if( pNxtBox->GetSttNd() && !rNxtBoxItem.GetLeft() &&
+                        ( !pPrvBox || !pPrvBox->GetFrmFmt()->GetBox().GetRight()) )
+                    {
+                        SvxBoxItem aTmp( rNxtBoxItem );
+                        aTmp.SetLine( rBoxItem.GetLeft() ? rBoxItem.GetLeft()
+                                                         : rBoxItem.GetRight(),
+                                                            BOX_LINE_LEFT );
+                        if( pShareFmts )
+                            pShareFmts->SetAttr( *pNxtBox, aTmp );
+                        else
+                            pNxtBox->ClaimFrmFmt()->SetAttr( aTmp );
+                        bChgd = TRUE;
+                    }
+                }
+                if( !bChgd && nDelPos )
+                {
+                    SwTableBox* pPrvBox = rTblBoxes[ nDelPos - 1 ];
+                    const SvxBoxItem& rPrvBoxItem = pPrvBox->GetFrmFmt()->GetBox();
+
+                    SwTableBox* pNxtBox = nDelPos + 1 < rTblBoxes.Count()
+                                            ? rTblBoxes[ nDelPos + 1 ] : 0;
+
+                    if( pPrvBox->GetSttNd() && !rPrvBoxItem.GetRight() &&
+                        ( !pNxtBox || !pNxtBox->GetFrmFmt()->GetBox().GetLeft()) )
+                    {
+                        SvxBoxItem aTmp( rPrvBoxItem );
+                        aTmp.SetLine( rBoxItem.GetLeft() ? rBoxItem.GetLeft()
+                                                         : rBoxItem.GetRight(),
+                                                            BOX_LINE_RIGHT );
+                        if( pShareFmts )
+                            pShareFmts->SetAttr( *pPrvBox, aTmp );
+                        else
+                            pPrvBox->ClaimFrmFmt()->SetAttr( aTmp );
+                    }
+                }
+            }
+
+        }
+
+        // erst die Box, dann die Nodes loeschen!!
+        SwStartNode* pSttNd = (SwStartNode*)pBox->GetSttNd();
+        if( pShareFmts )
+            pShareFmts->RemoveFormat( *rTblBoxes[ nDelPos ]->GetFrmFmt() );
+        rTblBoxes.DeleteAndDestroy( nDelPos );
+
+        if( pSttNd )
+        {
+            // ist das UndoObject zum speichern der Section vorbereitet?
+            if( pUndo && UNDO_TABLE_DELBOX == pUndo->GetId() )
+                ((SwUndoTblNdsChg*)pUndo)->SaveSection( pSttNd );
+            else
+                pSttNd->GetDoc()->DeleteSection( pSttNd );
+        }
+
+        // auch die Zeile noch loeschen ??
+        if( rTblBoxes.Count() )
+        {
+            // dann passe noch die Frame-SSize an
+            if( nDelPos == rTblBoxes.Count() )
+                --nDelPos;
+            pBox = rTblBoxes[nDelPos];
+            if( bCalcNewSize )
+            {
+                SwFmtFrmSize aNew( pBox->GetFrmFmt()->GetFrmSize() );
+                aNew.SetWidth( aNew.GetWidth() + nBoxSz );
+                if( pShareFmts )
+                    pShareFmts->SetSize( *pBox, aNew );
+                else
+                    pBox->ClaimFrmFmt()->SetAttr( aNew );
+
+                if( !pBox->GetSttNd() )
+                {
+                    // dann muss es auch rekursiv in allen Zeilen, in allen
+                    // Zellen erfolgen!
+                    SwShareBoxFmts aShareFmts;
+                    ::lcl_LastBoxSetWidthLine( pBox->GetTabLines(), nBoxSz,
+                                                pShareFmts ? *pShareFmts
+                                                           : aShareFmts );
+                }
+            }
+            break;      // nichts mehr loeschen
+        }
+        // loesche die Line aus Tabelle/Box
+        if( !pUpperBox )
+        {
+            // dann loesche auch noch die Line aus der Tabelle
+            nDelPos = rTbl.GetTabLines().C40_GETPOS( SwTableLine, pLine );
+            if( pShareFmts )
+                pShareFmts->RemoveFormat( *rTbl.GetTabLines()[ nDelPos ]->GetFrmFmt() );
+            rTbl.GetTabLines().DeleteAndDestroy( nDelPos );
+            break;      // mehr kann nicht geloescht werden
+        }
+
+        // dann loesche auch noch die Line
+        pBox = pUpperBox;
+        nDelPos = pBox->GetTabLines().C40_GETPOS( SwTableLine, pLine );
+        if( pShareFmts )
+            pShareFmts->RemoveFormat( *pBox->GetTabLines()[ nDelPos ]->GetFrmFmt() );
+        pBox->GetTabLines().DeleteAndDestroy( nDelPos );
+    } while( !pBox->GetTabLines().Count() );
+}
+
+SwTableBox* lcl_FndNxtPrvDelBox( const SwTableLines& rTblLns,
+                                SwTwips nBoxStt, SwTwips nBoxWidth,
+                                USHORT nLinePos, BOOL bNxt,
+                                SwSelBoxes* pAllDelBoxes, USHORT* pCurPos )
+{
+    SwTableBox* pFndBox = 0;
+    do {
+        if( bNxt )
+            ++nLinePos;
+        else
+            --nLinePos;
+        SwTableLine* pLine = rTblLns[ nLinePos ];
+        SwTwips nFndBoxWidth, nFndWidth = nBoxStt + nBoxWidth;
+        USHORT nBoxCnt = pLine->GetTabBoxes().Count();
+
+        for( USHORT n = 0; 0 < nFndWidth && n < nBoxCnt; ++n )
+        {
+            pFndBox = pLine->GetTabBoxes()[ n ];
+            nFndWidth -= (nFndBoxWidth = pFndBox->GetFrmFmt()->
+                                        GetFrmSize().GetWidth());
+        }
+
+        // suche die erste ContentBox
+        while( !pFndBox->GetSttNd() )
+        {
+            const SwTableLines& rLowLns = pFndBox->GetTabLines();
+            if( bNxt )
+                pFndBox = rLowLns[ 0 ]->GetTabBoxes()[ 0 ];
+            else
+                pFndBox = rLowLns[ rLowLns.Count() - 1 ]->GetTabBoxes()[ 0 ];
+        }
+
+        if( Abs( nFndWidth ) > COLFUZZY ||
+            Abs( nBoxWidth - nFndBoxWidth ) > COLFUZZY )
+            pFndBox = 0;
+        else if( pAllDelBoxes )
+        {
+            // falls der Vorganger auch geloscht wird, ist nicht zu tun
+            USHORT nFndPos;
+            if( !pAllDelBoxes->Seek_Entry( pFndBox, &nFndPos ) )
+                break;
+
+            // sonst noch mal weitersuchen
+            // Die Box muessen wir aber nicht nochmal abpruefen
+            pFndBox = 0;
+            if( nFndPos <= *pCurPos )
+                --*pCurPos;
+            pAllDelBoxes->Remove( nFndPos );
+        }
+    } while( bNxt ? ( nLinePos + 1 < rTblLns.Count() ) : nLinePos );
+    return pFndBox;
+}
+
+void lcl_SaveUpperLowerBorder( SwTable& rTbl, const SwTableBox& rBox,
+                                SwShareBoxFmts& rShareFmts,
+                                SwSelBoxes* pAllDelBoxes = 0,
+                                USHORT* pCurPos = 0 )
+{
+//JP 16.04.97:  2.Teil fuer Bug 36271
+    BOOL bChgd = FALSE;
+    const SwTableLine* pLine = rBox.GetUpper();
+    const SwTableBoxes& rTblBoxes = pLine->GetTabBoxes();
+    const SwTableBox* pUpperBox = &rBox;
+    USHORT nDelPos = rTblBoxes.C40_GETPOS( SwTableBox, pUpperBox );
+    pUpperBox = rBox.GetUpper()->GetUpper();
+    const SvxBoxItem& rBoxItem = rBox.GetFrmFmt()->GetBox();
+
+    // dann die unteren/oberen Kanten
+    if( rBoxItem.GetTop() || rBoxItem.GetBottom() )
+    {
+        bChgd = FALSE;
+        const SwTableLines* pTblLns;
+        if( pUpperBox )
+            pTblLns = &pUpperBox->GetTabLines();
+        else
+            pTblLns = &rTbl.GetTabLines();
+
+        USHORT nLnPos = pTblLns->GetPos( pLine );
+
+        // bestimme die Attr.Position der akt. zu loeschenden Box
+        // und suche dann in der unteren / oberen Line die entspr.
+        // Gegenstuecke
+        SwTwips nBoxStt = 0;
+        for( USHORT n = 0; n < nDelPos; ++n )
+            nBoxStt += rTblBoxes[ n ]->GetFrmFmt()->GetFrmSize().GetWidth();
+        SwTwips nBoxWidth = rBox.GetFrmFmt()->GetFrmSize().GetWidth();
+
+        SwTableBox *pPrvBox = 0, *pNxtBox = 0;
+        if( nLnPos )        // Vorgaenger?
+            pPrvBox = ::lcl_FndNxtPrvDelBox( *pTblLns, nBoxStt, nBoxWidth,
+                                nLnPos, FALSE, pAllDelBoxes, pCurPos );
+
+        if( nLnPos + 1 < pTblLns->Count() )     // Nachfolger?
+            pNxtBox = ::lcl_FndNxtPrvDelBox( *pTblLns, nBoxStt, nBoxWidth,
+                                nLnPos, TRUE, pAllDelBoxes, pCurPos );
+
+        if( pNxtBox && pNxtBox->GetSttNd() )
+        {
+            const SvxBoxItem& rNxtBoxItem = pNxtBox->GetFrmFmt()->GetBox();
+            if( !rNxtBoxItem.GetTop() && ( !pPrvBox ||
+                !pPrvBox->GetFrmFmt()->GetBox().GetBottom()) )
+            {
+                SvxBoxItem aTmp( rNxtBoxItem );
+                aTmp.SetLine( rBoxItem.GetTop() ? rBoxItem.GetTop()
+                                                : rBoxItem.GetBottom(),
+                                                BOX_LINE_TOP );
+                rShareFmts.SetAttr( *pNxtBox, aTmp );
+                bChgd = TRUE;
+            }
+        }
+        if( !bChgd && pPrvBox && pPrvBox->GetSttNd() )
+        {
+            const SvxBoxItem& rPrvBoxItem = pPrvBox->GetFrmFmt()->GetBox();
+            if( !rPrvBoxItem.GetTop() && ( !pNxtBox ||
+                !pNxtBox->GetFrmFmt()->GetBox().GetTop()) )
+            {
+                SvxBoxItem aTmp( rPrvBoxItem );
+                aTmp.SetLine( rBoxItem.GetTop() ? rBoxItem.GetTop()
+                                                : rBoxItem.GetBottom(),
+                                                BOX_LINE_BOTTOM );
+                rShareFmts.SetAttr( *pPrvBox, aTmp );
+            }
+        }
+
+    }
+}
+
+
+BOOL SwTable::DeleteSel( SwDoc* pDoc, const SwSelBoxes& rBoxes, SwUndo* pUndo,
+                         const BOOL bDelMakeFrms, const BOOL bCorrBorder )
+{
+    ASSERT( pDoc && rBoxes.Count(), "keine gueltigen Werte" );
+    SwTableNode* pTblNd = (SwTableNode*)rBoxes[0]->GetSttNd()->FindTableNode();
+    if( !pTblNd )
+        return FALSE;
+
+    // es darf nie die gesamte Tabelle geloescht werden
+    SwNodes& rNds = pDoc->GetNodes();
+    if( rBoxes[0]->GetSttIdx()-1 == pTblNd->GetIndex() &&
+        rBoxes[rBoxes.Count()-1]->GetSttNd()->EndOfSectionIndex()+1
+        == pTblNd->EndOfSectionIndex() )
+        return FALSE;
+
+    SetHTMLTableLayout( 0 );    // MIB 9.7.97: HTML-Layout loeschen
+
+    //Lines fuer das Layout-Update herausuchen.
+    _FndBox aFndBox( 0, 0 );
+    if ( bDelMakeFrms )
+    {
+        aFndBox.SetTableLines( rBoxes, *this );
+        aFndBox.DelFrms( *this );
+    }
+    aFndBox.SaveChartData( *this );
+
+    SwShareBoxFmts aShareFmts;
+
+    // erst die Umrandung umsetzen, dann loeschen
+    if( bCorrBorder )
+    {
+        SwSelBoxes aBoxes;
+        aBoxes.Insert( &rBoxes );
+        for( USHORT n = 0; n < aBoxes.Count(); ++n )
+            ::lcl_SaveUpperLowerBorder( *this, *rBoxes[ n ], aShareFmts,
+                                        &aBoxes, &n );
+    }
+
+    for( USHORT n = 0; n < rBoxes.Count(); ++n )
+        _DeleteBox( *this, rBoxes[n], pUndo, TRUE, bCorrBorder, &aShareFmts );
+
+    // dann raeume die Struktur aller Lines auf
+    GCLines();
+
+    if( bDelMakeFrms && aFndBox.AreLinesToRestore( *this ) )
+        aFndBox.MakeFrms( *this );
+    aFndBox.RestoreChartData( *this );
+    return TRUE;
+}
+
+
+// ---------------------------------------------------------------
+
+BOOL SwTable::SplitRow( SwDoc* pDoc, const SwSelBoxes& rBoxes, USHORT nCnt )
+{
+    ASSERT( pDoc && rBoxes.Count() && nCnt, "keine gueltigen Werte" );
+    SwTableNode* pTblNd = (SwTableNode*)rBoxes[0]->GetSttNd()->FindTableNode();
+    if( !pTblNd )
+        return FALSE;
+
+    SetHTMLTableLayout( 0 );    // MIB 9.7.97: HTML-Layout loeschen
+
+    //Lines fuer das Layout-Update herausuchen.
+    _FndBox aFndBox( 0, 0 );
+    aFndBox.SetTableLines( rBoxes, *this );
+    aFndBox.DelFrms( *this );
+    aFndBox.SaveChartData( *this );
+
+    for( USHORT n = 0; n < rBoxes.Count(); ++n )
+    {
+        SwTableBox* pSelBox = *( rBoxes.GetData() + n );
+        ASSERT( pSelBox, "Box steht nicht in der Tabelle" );
+
+        // dann fuege in die Box nCnt neue Zeilen ein
+        SwTableLine* pInsLine = pSelBox->GetUpper();
+        SwTableBoxFmt* pFrmFmt = (SwTableBoxFmt*)pSelBox->GetFrmFmt();
+
+        // Hoehe der Line beachten, gegebenenfalls neu setzen
+        SwFmtFrmSize aFSz( pInsLine->GetFrmFmt()->GetFrmSize() );
+        BOOL bChgLineSz = 0 != aFSz.GetHeight();
+        if( bChgLineSz )
+            aFSz.SetHeight( aFSz.GetHeight() / (nCnt + 1) );
+
+        SwTableBox* pNewBox = new SwTableBox( pFrmFmt, nCnt, pInsLine );
+        USHORT nBoxPos = pInsLine->GetTabBoxes().C40_GETPOS( SwTableBox, pSelBox );
+        pInsLine->GetTabBoxes().Remove( nBoxPos );  // alte loeschen
+        pInsLine->GetTabBoxes().C40_INSERT( SwTableBox, pNewBox, nBoxPos );
+
+        // Hintergrund- / Rand Attribut loeschen
+        SwTableBox* pLastBox = pSelBox;         // zum verteilen der TextNodes !!
+        // sollte Bereiche in der Box stehen, dann bleibt sie so bestehen
+        // !! FALLS DAS GEAENDERT WIRD MUSS DAS UNDO ANGEPASST WERDEN !!!
+        BOOL bMoveNodes = TRUE;
+        {
+            ULONG nSttNd = pLastBox->GetSttIdx() + 1,
+                    nEndNd = pLastBox->GetSttNd()->EndOfSectionIndex();
+            while( nSttNd < nEndNd )
+                if( !pDoc->GetNodes()[ nSttNd++ ]->IsTxtNode() )
+                {
+                    bMoveNodes = FALSE;
+                    break;
+                }
+        }
+
+        SwTableBoxFmt* pCpyBoxFrmFmt = (SwTableBoxFmt*)pSelBox->GetFrmFmt();
+        BOOL bChkBorder = 0 != pCpyBoxFrmFmt->GetBox().GetTop();
+        if( bChkBorder )
+            pCpyBoxFrmFmt = (SwTableBoxFmt*)pSelBox->ClaimFrmFmt();
+
+        for( USHORT i = 0; i <= nCnt; ++i )
+        {
+            // also erstmal eine neue Linie in der neuen Box
+            SwTableLine* pNewLine = new SwTableLine(
+                    (SwTableLineFmt*)pInsLine->GetFrmFmt(), 1, pNewBox );
+            if( bChgLineSz )
+            {
+                pNewLine->ClaimFrmFmt()->SetAttr( aFSz );
+            }
+
+            pNewBox->GetTabLines().C40_INSERT( SwTableLine, pNewLine, i );
+            // dann eine neue Box in der Line
+            if( !i )        // haenge die originale Box ein
+            {
+                pSelBox->SetUpper( pNewLine );
+                pNewLine->GetTabBoxes().C40_INSERT( SwTableBox, pSelBox, 0 );
+            }
+            else
+            {
+                ::_InsTblBox( pDoc, pTblNd, pNewLine, pCpyBoxFrmFmt,
+                                pLastBox, 0 );
+
+                if( bChkBorder )
+                {
+                    pCpyBoxFrmFmt = (SwTableBoxFmt*)pNewLine->GetTabBoxes()[ 0 ]->ClaimFrmFmt();
+                    SvxBoxItem aTmp( pCpyBoxFrmFmt->GetBox() );
+                    aTmp.SetLine( 0, BOX_LINE_TOP );
+                    pCpyBoxFrmFmt->SetAttr( aTmp );
+                    bChkBorder = FALSE;
+                }
+
+                if( bMoveNodes )
+                {
+                    const SwNode* pEndNd = pLastBox->GetSttNd()->EndOfSectionNode();
+                    if( pLastBox->GetSttIdx()+2 != pEndNd->GetIndex() )
+                    {
+                        // TextNodes verschieben
+                        SwNodeRange aRg( *pLastBox->GetSttNd(), +2, *pEndNd );
+                        pLastBox = pNewLine->GetTabBoxes()[0];  // neu setzen
+                        SwNodeIndex aInsPos( *pLastBox->GetSttNd(), 1 );
+                        pDoc->GetNodes()._MoveNodes(aRg, pDoc->GetNodes(), aInsPos, FALSE);
+                        pDoc->GetNodes().Delete( aInsPos, 1 ); // den leeren noch loeschen
+                    }
+                }
+            }
+        }
+        // in Boxen mit Lines darf es nur noch Size/Fillorder geben
+        pFrmFmt = (SwTableBoxFmt*)pNewBox->ClaimFrmFmt();
+        pFrmFmt->ResetAttr( RES_LR_SPACE, RES_FRMATR_END - 1 );
+        pFrmFmt->ResetAttr( RES_BOXATR_BEGIN, RES_BOXATR_END - 1 );
+    }
+
+    //Layout updaten
+    aFndBox.MakeFrms( *this );
+    aFndBox.RestoreChartData( *this );
+    CHECKBOXWIDTH
+    return TRUE;
+}
+
+BOOL SwTable::SplitCol( SwDoc* pDoc, const SwSelBoxes& rBoxes, USHORT nCnt )
+{
+    ASSERT( pDoc && rBoxes.Count() && nCnt, "keine gueltigen Werte" );
+    SwTableNode* pTblNd = (SwTableNode*)rBoxes[0]->GetSttNd()->FindTableNode();
+    if( !pTblNd )
+        return FALSE;
+
+    SetHTMLTableLayout( 0 );    // MIB 9.7.97: HTML-Layout loeschen
+
+    //Lines fuer das Layout-Update herausuchen.
+    _FndBox aFndBox( 0, 0 );
+    aFndBox.SetTableLines( rBoxes, *this );
+    aFndBox.DelFrms( *this );
+    aFndBox.SaveChartData( *this );
+
+    _CpyTabFrms aFrmArr;
+    SvPtrarr aLastBoxArr;
+    USHORT nFndPos;
+    for( USHORT n = 0; n < rBoxes.Count(); ++n )
+    {
+        SwTableBox* pSelBox = *( rBoxes.GetData() + n );
+        ASSERT( pSelBox, "Box steht nicht in der Tabelle" );
+
+        // dann teile die Box nCnt in nCnt Boxen
+        SwTableLine* pInsLine = pSelBox->GetUpper();
+        USHORT nBoxPos = pInsLine->GetTabBoxes().C40_GETPOS( SwTableBox, pSelBox );
+
+        // suche das FrmFmt im Array aller Frame-Formate
+        SwTableBoxFmt* pLastBoxFmt;
+        _CpyTabFrm aFindFrm( (SwTableBoxFmt*)pSelBox->GetFrmFmt() );
+        if( !aFrmArr.Seek_Entry( aFindFrm, &nFndPos ))
+        {
+            // aender das FrmFmt
+            aFindFrm.pNewFrmFmt = (SwTableBoxFmt*)pSelBox->ClaimFrmFmt();
+            SwTwips nBoxSz = aFindFrm.pNewFrmFmt->GetFrmSize().GetWidth();
+            SwTwips nNewBoxSz = nBoxSz / ( nCnt + 1 );
+            aFindFrm.pNewFrmFmt->SetAttr( SwFmtFrmSize( ATT_VAR_SIZE,
+                                                        nNewBoxSz, 0 ) );
+            aFrmArr.Insert( aFindFrm );
+
+            pLastBoxFmt = aFindFrm.pNewFrmFmt;
+            if( nBoxSz != ( nNewBoxSz * (nCnt + 1)))
+            {
+                // es bleibt ein Rest, also muss fuer die letzte Box ein
+                // eigenes Format definiert werden
+                pLastBoxFmt = new SwTableBoxFmt( *aFindFrm.pNewFrmFmt );
+                pLastBoxFmt->SetAttr( SwFmtFrmSize( ATT_VAR_SIZE,
+                                nBoxSz - ( nNewBoxSz * nCnt ), 0 ) );
+            }
+            void* p = pLastBoxFmt;
+            aLastBoxArr.Insert( p, nFndPos );
+        }
+        else
+        {
+            aFindFrm = aFrmArr[ nFndPos ];
+            pSelBox->ChgFrmFmt( (SwTableBoxFmt*)aFindFrm.pNewFrmFmt );
+            pLastBoxFmt = (SwTableBoxFmt*)aLastBoxArr[ nFndPos ];
+        }
+
+        // dann fuege mal an der Position die neuen Boxen ein
+        for( USHORT i = 1; i < nCnt; ++i )
+            ::_InsTblBox( pDoc, pTblNd, pInsLine, aFindFrm.pNewFrmFmt,
+                        pSelBox, nBoxPos + i ); // dahinter einfuegen
+
+        ::_InsTblBox( pDoc, pTblNd, pInsLine, pLastBoxFmt,
+                    pSelBox, nBoxPos + nCnt );  // dahinter einfuegen
+
+        // Sonderbehandlung fuer die Umrandung:
+        const SvxBoxItem& rBoxItem = aFindFrm.pNewFrmFmt->GetBox();
+        if( rBoxItem.GetRight() )
+        {
+            pInsLine->GetTabBoxes()[ nBoxPos + nCnt ]->ClaimFrmFmt();
+
+            SvxBoxItem aTmp( rBoxItem );
+            aTmp.SetLine( 0, BOX_LINE_RIGHT );
+            aFindFrm.pNewFrmFmt->SetAttr( aTmp );
+
+            // und dann das Format aus dem "cache" entfernen
+            for( USHORT i = aFrmArr.Count(); i; )
+            {
+                const _CpyTabFrm& rCTF = aFrmArr[ --i ];
+                if( rCTF.pNewFrmFmt == aFindFrm.pNewFrmFmt ||
+                    rCTF.Value.pFrmFmt == aFindFrm.pNewFrmFmt )
+                {
+                    aFrmArr.Remove( i );
+                    aLastBoxArr.Remove( i );
+                }
+            }
+        }
+    }
+
+    //Layout updaten
+    aFndBox.MakeFrms( *this );
+    aFndBox.RestoreChartData( *this );
+    CHECKBOXWIDTH
+    return TRUE;
+}
+
+// ---------------------------------------------------------------
+
+/*
+    ----------------------- >> MERGE << ------------------------
+     Algorythmus:
+        ist in der _FndBox nur eine Line angegeben, nehme die Line
+        und teste die Anzahl der Boxen
+        - ist mehr als 1 Box angegeben, so wird auf Boxenebene zusammen-
+            gefasst, d.H. die neue Box wird so Breit wie die alten.
+            - Alle Lines die ueber/unter dem Bereich liegen werden in die
+            Box als Line + Box mit Lines eingefuegt
+            - Alle Lines die vor/hinter dem Bereich liegen werden in
+            die Boxen Left/Right eingetragen
+
+    ----------------------- >> MERGE << ------------------------
+*/
+
+void lcl_CpyLines( USHORT nStt, USHORT nEnd,
+                                SwTableLines& rLines,
+                                SwTableBox* pInsBox,
+                                USHORT nPos = USHRT_MAX )
+{
+    for( USHORT n = nStt; n < nEnd; ++n )
+        rLines[n]->SetUpper( pInsBox );
+    if( USHRT_MAX == nPos )
+        nPos = pInsBox->GetTabLines().Count();
+    pInsBox->GetTabLines().Insert( &rLines, nPos, nStt, nEnd );
+    rLines.Remove( nStt, nEnd - nStt );
+}
+
+void lcl_CpyBoxes( USHORT nStt, USHORT nEnd,
+                                SwTableBoxes& rBoxes,
+                                SwTableLine* pInsLine,
+                                USHORT nPos = USHRT_MAX )
+{
+    for( USHORT n = nStt; n < nEnd; ++n )
+        rBoxes[n]->SetUpper( pInsLine );
+    if( USHRT_MAX == nPos )
+        nPos = pInsLine->GetTabBoxes().Count();
+    pInsLine->GetTabBoxes().Insert( &rBoxes, nPos, nStt, nEnd );
+    rBoxes.Remove( nStt, nEnd - nStt );
+}
+
+void lcl_CalcWidth( SwTableBox* pBox )
+{
+    // Annahme: jede Line in der Box ist gleich gross
+    SwFrmFmt* pFmt = pBox->ClaimFrmFmt();
+    ASSERT( pBox->GetTabLines().Count(), "Box hat keine Lines" );
+
+    SwTableLine* pLine = pBox->GetTabLines()[0];
+    ASSERT( pLine, "Box steht in keiner Line" );
+
+    long nWidth = 0;
+    for( USHORT n = 0; n < pLine->GetTabBoxes().Count(); ++n )
+        nWidth += pLine->GetTabBoxes()[n]->GetFrmFmt()->GetFrmSize().GetWidth();
+
+    pFmt->SetAttr( SwFmtFrmSize( ATT_VAR_SIZE, nWidth, 0 ));
+
+    // in Boxen mit Lines darf es nur noch Size/Fillorder geben
+    pFmt->ResetAttr( RES_LR_SPACE, RES_FRMATR_END - 1 );
+    pFmt->ResetAttr( RES_BOXATR_BEGIN, RES_BOXATR_END - 1 );
+}
+
+
+
+struct _InsULPara
+{
+    SwTableNode* pTblNd;
+    SwTableLine* pInsLine;
+    SwTableBox* pInsBox;
+    BOOL bUL_LR : 1;        // Upper-Lower(TRUE) oder Left-Right(FALSE) ?
+    BOOL bUL : 1;           // Upper-Left(TRUE) oder Lower-Right(FALSE) ?
+
+    SwTableBox* pLeftBox;
+    SwTableBox* pRightBox;
+    SwTableBox* pMergeBox;
+
+    _InsULPara( SwTableNode* pTNd, BOOL bUpperLower, BOOL bUpper,
+                SwTableBox* pLeft, SwTableBox* pMerge, SwTableBox* pRight,
+                SwTableLine* pLine=0, SwTableBox* pBox=0 )
+        : pTblNd( pTNd ), pInsLine( pLine ), pInsBox( pBox ),
+        pLeftBox( pLeft ), pMergeBox( pMerge ), pRightBox( pRight )
+        {   bUL_LR = bUpperLower; bUL = bUpper; }
+
+    void SetLeft( SwTableBox* pBox=0 )
+        { bUL_LR = FALSE;   bUL = TRUE; if( pBox ) pInsBox = pBox; }
+    void SetRight( SwTableBox* pBox=0 )
+        { bUL_LR = FALSE;   bUL = FALSE; if( pBox ) pInsBox = pBox; }
+    void SetUpper( SwTableLine* pLine=0 )
+        { bUL_LR = TRUE;    bUL = TRUE;  if( pLine ) pInsLine = pLine; }
+    void SetLower( SwTableLine* pLine=0 )
+        { bUL_LR = TRUE;    bUL = FALSE; if( pLine ) pInsLine = pLine; }
+};
+
+
+BOOL lcl_Merge_MoveBox( const _FndBox*& rpFndBox, void* pPara )
+{
+    _InsULPara* pULPara = (_InsULPara*)pPara;
+    SwTableBoxes* pBoxes;
+
+    USHORT nStt = 0, nEnd = rpFndBox->GetLines().Count();
+    USHORT nInsPos = USHRT_MAX;
+    if( !pULPara->bUL_LR )  // Left/Right
+    {
+        USHORT nPos;
+        SwTableBox* pFndBox = (SwTableBox*)rpFndBox->GetBox();
+        pBoxes = &pFndBox->GetUpper()->GetTabBoxes();
+        if( pULPara->bUL )  // Left ?
+        {
+            // gibt es noch davor Boxen, dann move sie
+            if( 0 != ( nPos = pBoxes->C40_GETPOS( SwTableBox, pFndBox )) )
+                lcl_CpyBoxes( 0, nPos, *pBoxes, pULPara->pInsLine );
+        }
+        else                // Right
+            // gibt es noch dahinter Boxen, dann move sie
+            if( (nPos = pBoxes->C40_GETPOS( SwTableBox, pFndBox )) +1 < pBoxes->Count() )
+            {
+                nInsPos = pULPara->pInsLine->GetTabBoxes().Count();
+                lcl_CpyBoxes( nPos+1, pBoxes->Count(),
+                                    *pBoxes, pULPara->pInsLine );
+            }
+    }
+    // Upper/Lower und gehts noch tiefer ??
+    else if( rpFndBox->GetLines().Count() )
+    {
+        // suche nur die Line, ab der Verschoben werden muss
+        nStt = pULPara->bUL ? 0 : rpFndBox->GetLines().Count()-1;
+        nEnd = nStt+1;
+    }
+
+    pBoxes = &pULPara->pInsLine->GetTabBoxes();
+
+    // geht es noch eine weitere Stufe runter?
+    if( rpFndBox->GetBox()->GetTabLines().Count() )
+    {
+        SwTableBox* pBox = new SwTableBox(
+                (SwTableBoxFmt*)rpFndBox->GetBox()->GetFrmFmt(), 0, pULPara->pInsLine );
+        _InsULPara aPara( *pULPara );
+        aPara.pInsBox = pBox;
+        ((_FndBox*)rpFndBox)->GetLines().ForEach( nStt, nEnd,
+                                                &lcl_Merge_MoveLine, &aPara );
+        if( pBox->GetTabLines().Count() )
+        {
+            if( USHRT_MAX == nInsPos )
+                nInsPos = pBoxes->Count();
+            pBoxes->C40_INSERT( SwTableBox, pBox, nInsPos );
+            lcl_CalcWidth( pBox );      // bereche die Breite der Box
+        }
+        else
+            delete pBox;
+    }
+    return TRUE;
+}
+
+BOOL lcl_Merge_MoveLine( const _FndLine*& rpFndLine, void* pPara )
+{
+    _InsULPara* pULPara = (_InsULPara*)pPara;
+    SwTableLines* pLines;
+
+    USHORT nStt = 0, nEnd = rpFndLine->GetBoxes().Count();
+    USHORT nInsPos = USHRT_MAX;
+    if( pULPara->bUL_LR )   // UpperLower ?
+    {
+        USHORT nPos;
+        SwTableLine* pFndLn = (SwTableLine*)rpFndLine->GetLine();
+        pLines = pFndLn->GetUpper() ?
+                        &pFndLn->GetUpper()->GetTabLines() :
+                        &pULPara->pTblNd->GetTable().GetTabLines();
+
+        SwTableBox* pLBx = rpFndLine->GetBoxes()[0]->GetBox();
+        SwTableBox* pRBx = rpFndLine->GetBoxes()[
+                            rpFndLine->GetBoxes().Count()-1]->GetBox();
+        USHORT nLeft = pFndLn->GetTabBoxes().C40_GETPOS( SwTableBox, pLBx );
+        USHORT nRight = pFndLn->GetTabBoxes().C40_GETPOS( SwTableBox, pRBx );
+
+//      if( ( nLeft && nRight+1 < pFndLn->GetTabBoxes().Count() ) ||
+//          ( !nLeft && nRight+1 >= pFndLn->GetTabBoxes().Count() ) )
+        if( !nLeft || nRight == pFndLn->GetTabBoxes().Count() )
+        {
+            if( pULPara->bUL )  // Upper ?
+            {
+                // gibt es noch davor Zeilen, dann move sie
+                if( 0 != ( nPos = pLines->C40_GETPOS( SwTableLine, pFndLn )) )
+                    lcl_CpyLines( 0, nPos, *pLines, pULPara->pInsBox );
+            }
+            else
+                // gibt es noch dahinter Zeilen, dann move sie
+                if( (nPos = pLines->C40_GETPOS( SwTableLine, pFndLn )) +1 < pLines->Count() )
+                {
+                    nInsPos = pULPara->pInsBox->GetTabLines().Count();
+                    lcl_CpyLines( nPos+1, pLines->Count(), *pLines,
+                                        pULPara->pInsBox );
+                }
+        }
+        else if( nLeft )
+        {
+            // es gibt links noch weitere Boxen, also setze Left-
+            // und Merge-Box in eine Box und Line, fuege davor/dahinter
+            // eine Line mit Box ein, in die die oberen/unteren Lines
+            // eingefuegt werden
+            SwTableLine* pInsLine = pULPara->pLeftBox->GetUpper();
+            SwTableBox* pLMBox = new SwTableBox(
+                (SwTableBoxFmt*)pULPara->pLeftBox->GetFrmFmt(), 0, pInsLine );
+            SwTableLine* pLMLn = new SwTableLine(
+                        (SwTableLineFmt*)pInsLine->GetFrmFmt(), 2, pLMBox );
+            pLMLn->ClaimFrmFmt()->ResetAttr( RES_FRM_SIZE );
+
+            pLMBox->GetTabLines().C40_INSERT( SwTableLine, pLMLn, 0 );
+
+            lcl_CpyBoxes( 0, 2, pInsLine->GetTabBoxes(), pLMLn );
+
+            pInsLine->GetTabBoxes().C40_INSERT( SwTableBox, pLMBox, 0 );
+
+            if( pULPara->bUL )  // Upper ?
+            {
+                // gibt es noch davor Zeilen, dann move sie
+                if( 0 != ( nPos = pLines->C40_GETPOS( SwTableLine, pFndLn )) )
+                    lcl_CpyLines( 0, nPos, *pLines, pLMBox, 0 );
+            }
+            else
+                // gibt es noch dahinter Zeilen, dann move sie
+                if( (nPos = pLines->C40_GETPOS( SwTableLine, pFndLn )) +1 < pLines->Count() )
+                    lcl_CpyLines( nPos+1, pLines->Count(), *pLines,
+                                        pLMBox );
+            lcl_CalcWidth( pLMBox );        // bereche die Breite der Box
+        }
+        else if( nRight+1 < pFndLn->GetTabBoxes().Count() )
+        {
+            // es gibt rechts noch weitere Boxen, also setze Right-
+            // und Merge-Box in eine Box und Line, fuege davor/dahinter
+            // eine Line mit Box ein, in die die oberen/unteren Lines
+            // eingefuegt werden
+            SwTableLine* pInsLine = pULPara->pRightBox->GetUpper();
+            SwTableBox* pRMBox;
+            if( pULPara->pLeftBox->GetUpper() == pInsLine )
+            {
+                pRMBox = new SwTableBox(
+                    (SwTableBoxFmt*)pULPara->pRightBox->GetFrmFmt(), 0, pInsLine );
+                SwTableLine* pRMLn = new SwTableLine(
+                    (SwTableLineFmt*)pInsLine->GetFrmFmt(), 2, pRMBox );
+                pRMLn->ClaimFrmFmt()->ResetAttr( RES_FRM_SIZE );
+                pRMBox->GetTabLines().C40_INSERT( SwTableLine, pRMLn, 0 );
+
+                lcl_CpyBoxes( 1, 3, pInsLine->GetTabBoxes(), pRMLn );
+
+                pInsLine->GetTabBoxes().C40_INSERT( SwTableBox, pRMBox, 0 );
+            }
+            else
+            {
+                // Left und Merge wurden schon zusammengefuegt, also move
+                // Right auch mit in die Line
+
+                pInsLine = pULPara->pLeftBox->GetUpper();
+                USHORT nMvPos = pULPara->pRightBox->GetUpper()->GetTabBoxes().
+                                    C40_GETPOS( SwTableBox, pULPara->pRightBox );
+                lcl_CpyBoxes( nMvPos, nMvPos+1,
+                            pULPara->pRightBox->GetUpper()->GetTabBoxes(),
+                            pInsLine );
+                pRMBox = pInsLine->GetUpper();
+
+                // sind schon Lines vorhanden, dann muessen diese in eine
+                // neue Line und Box
+                nMvPos = pRMBox->GetTabLines().C40_GETPOS( SwTableLine, pInsLine );
+                if( pULPara->bUL ? nMvPos
+                                : nMvPos+1 < pRMBox->GetTabLines().Count() )
+                {
+                    // alle Lines zu einer neuen Line und Box zusammenfassen
+                    SwTableLine* pNewLn = new SwTableLine(
+                        (SwTableLineFmt*)pInsLine->GetFrmFmt(), 1, pRMBox );
+                    pNewLn->ClaimFrmFmt()->ResetAttr( RES_FRM_SIZE );
+                    pRMBox->GetTabLines().C40_INSERT( SwTableLine, pNewLn,
+                            pULPara->bUL ? nMvPos : nMvPos+1 );
+                    pRMBox = new SwTableBox( (SwTableBoxFmt*)pRMBox->GetFrmFmt(), 0, pNewLn );
+                    pNewLn->GetTabBoxes().C40_INSERT( SwTableBox, pRMBox, 0 );
+
+                    USHORT nPos1, nPos2;
+                    if( pULPara->bUL )
+                        nPos1 = 0,
+                        nPos2 = nMvPos;
+                    else
+                        nPos1 = nMvPos+2,
+                        nPos2 = pNewLn->GetUpper()->GetTabLines().Count();
+
+                    lcl_CpyLines( nPos1, nPos2,
+                                pNewLn->GetUpper()->GetTabLines(), pRMBox );
+                    lcl_CalcWidth( pRMBox );        // bereche die Breite der Box
+
+                    pRMBox = new SwTableBox( (SwTableBoxFmt*)pRMBox->GetFrmFmt(), 0, pNewLn );
+                    pNewLn->GetTabBoxes().C40_INSERT( SwTableBox, pRMBox,
+                                    pNewLn->GetTabBoxes().Count() );
+                }
+            }
+            if( pULPara->bUL )  // Upper ?
+            {
+                // gibt es noch davor Zeilen, dann move sie
+                if( 0 != ( nPos = pLines->C40_GETPOS( SwTableLine, pFndLn )) )
+                    lcl_CpyLines( 0, nPos, *pLines, pRMBox, 0 );
+            }
+            else
+                // gibt es noch dahinter Zeilen, dann move sie
+                if( (nPos = pLines->C40_GETPOS( SwTableLine, pFndLn )) +1 < pLines->Count() )
+                    lcl_CpyLines( nPos+1, pLines->Count(), *pLines,
+                                        pRMBox );
+            lcl_CalcWidth( pRMBox );        // bereche die Breite der Box
+        }
+        else
+            ASSERT( FALSE , "Was denn nun" );
+    }
+    // Left/Right
+    else
+    {
+        // suche nur die Line, ab der Verschoben werden muss
+        nStt = pULPara->bUL ? 0 : rpFndLine->GetBoxes().Count()-1;
+        nEnd = nStt+1;
+    }
+    pLines = &pULPara->pInsBox->GetTabLines();
+
+    SwTableLine* pNewLine = new SwTableLine(
+        (SwTableLineFmt*)rpFndLine->GetLine()->GetFrmFmt(), 0, pULPara->pInsBox );
+    _InsULPara aPara( *pULPara );       // kopieren
+    aPara.pInsLine = pNewLine;
+    ((_FndLine*)rpFndLine)->GetBoxes().ForEach( nStt, nEnd,
+                                                &lcl_Merge_MoveBox, &aPara );
+    if( pNewLine->GetTabBoxes().Count() )
+    {
+        if( USHRT_MAX == nInsPos )
+            nInsPos = pLines->Count();
+        pLines->C40_INSERT( SwTableLine, pNewLine, nInsPos );
+    }
+    else
+        delete pNewLine;
+
+    return TRUE;
+}
+
+
+BOOL SwTable::Merge( SwDoc* pDoc, const SwSelBoxes& rBoxes,
+                    SwTableBox* pMergeBox, SwUndoTblMerge* pUndo )
+{
+    ASSERT( pDoc && rBoxes.Count() && pMergeBox, "keine gueltigen Werte" );
+    SwTableNode* pTblNd = (SwTableNode*)rBoxes[0]->GetSttNd()->FindTableNode();
+    if( !pTblNd )
+        return FALSE;
+
+    // suche alle Boxen / Lines
+    _FndBox aFndBox( 0, 0 );
+    {
+        _FndPara aPara( rBoxes, &aFndBox );
+        GetTabLines().ForEach( &_FndLineCopyCol, &aPara );
+    }
+    if( !aFndBox.GetLines().Count() )
+        return FALSE;
+
+    SetHTMLTableLayout( 0 );    // MIB 9.7.97: HTML-Layout loeschen
+
+    if( pUndo )
+        pUndo->SetSelBoxes( rBoxes );
+
+    //Lines fuer das Layout-Update herausuchen.
+    aFndBox.SetTableLines( *this );
+    aFndBox.DelFrms( *this );
+    aFndBox.SaveChartData( *this );
+
+    _FndBox* pFndBox = &aFndBox;
+    while( 1 == pFndBox->GetLines().Count() &&
+            1 == pFndBox->GetLines()[0]->GetBoxes().Count() )
+        pFndBox = pFndBox->GetLines()[0]->GetBoxes()[0];
+
+    SwTableLine* pInsLine = new SwTableLine(
+                (SwTableLineFmt*)pFndBox->GetLines()[0]->GetLine()->GetFrmFmt(), 0,
+                !pFndBox->GetUpper() ? 0 : pFndBox->GetBox() );
+    pInsLine->ClaimFrmFmt()->ResetAttr( RES_FRM_SIZE );
+
+    // trage die neue Line ein
+    SwTableLines* pLines =  pFndBox->GetUpper() ?
+                  &pFndBox->GetBox()->GetTabLines() :  &GetTabLines();
+
+    SwTableLine* pNewLine = pFndBox->GetLines()[0]->GetLine();
+    USHORT nInsPos = pLines->C40_GETPOS( SwTableLine, pNewLine );
+    pLines->C40_INSERT( SwTableLine, pInsLine, nInsPos );
+
+    SwTableBox* pLeft = new SwTableBox( (SwTableBoxFmt*)pMergeBox->GetFrmFmt(), 0, pInsLine );
+    SwTableBox* pRight = new SwTableBox( (SwTableBoxFmt*)pMergeBox->GetFrmFmt(), 0, pInsLine );
+    pMergeBox->SetUpper( pInsLine );
+    pInsLine->GetTabBoxes().C40_INSERT( SwTableBox, pLeft, 0 );
+    pLeft->ClaimFrmFmt();
+    pInsLine->GetTabBoxes().C40_INSERT( SwTableBox, pMergeBox, 1 );
+    pInsLine->GetTabBoxes().C40_INSERT( SwTableBox, pRight, 2 );
+    pRight->ClaimFrmFmt();
+
+    // in diese kommen alle Lines, die ueber dem selektierten Bereich stehen
+    // Sie bilden also eine Upper/Lower Line
+    _InsULPara aPara( pTblNd, TRUE, TRUE, pLeft, pMergeBox, pRight, pInsLine );
+
+    // move die oben/unten ueberhaengenden Lines vom selektierten Bereich
+    pFndBox->GetLines()[0]->GetBoxes().ForEach( &lcl_Merge_MoveBox,
+                                                &aPara );
+    aPara.SetLower( pInsLine );
+    USHORT nEnd = pFndBox->GetLines().Count()-1;
+    pFndBox->GetLines()[nEnd]->GetBoxes().ForEach( &lcl_Merge_MoveBox,
+                                                    &aPara );
+
+    // move die links/rechts hereinreichenden Boxen vom selektierten Bereich
+    aPara.SetLeft( pLeft );
+    pFndBox->GetLines().ForEach( &lcl_Merge_MoveLine, &aPara );
+
+    aPara.SetRight( pRight );
+    pFndBox->GetLines().ForEach( &lcl_Merge_MoveLine, &aPara );
+
+    if( !pLeft->GetTabLines().Count() )
+        _DeleteBox( *this, pLeft, 0, FALSE, FALSE );
+    else
+    {
+        lcl_CalcWidth( pLeft );     // bereche die Breite der Box
+        if( pUndo && pLeft->GetSttNd() )
+            pUndo->AddNewBox( pLeft->GetSttIdx() );
+    }
+    if( !pRight->GetTabLines().Count() )
+        _DeleteBox( *this, pRight, 0, FALSE, FALSE );
+    else
+    {
+        lcl_CalcWidth( pRight );        // bereche die Breite der Box
+        if( pUndo && pRight->GetSttNd() )
+            pUndo->AddNewBox( pRight->GetSttIdx() );
+    }
+
+    DeleteSel( pDoc, rBoxes, 0, FALSE, FALSE );
+
+    // dann raeume die Struktur dieser Line noch mal auf:
+    // generell alle Aufraeumen
+    GCLines();
+
+    GetTabLines()[0]->GetTabBoxes().ForEach( &lcl_BoxSetHeadCondColl, 0 );
+
+    aFndBox.MakeFrms( *this );
+    aFndBox.RestoreChartData( *this );
+    CHECKBOXWIDTH
+    return TRUE;
+}
+
+// ---------------------------------------------------------------
+
+USHORT lcl_GetBoxOffset( const _FndBox& rBox )
+{
+    // suche die erste Box
+    const _FndBox* pFirstBox = &rBox;
+    while( pFirstBox->GetLines().Count() )
+        pFirstBox = pFirstBox->GetLines()[ 0 ]->GetBoxes()[ 0 ];
+
+    USHORT nRet = 0;
+    // dann ueber die Lines nach oben die Position bestimmen
+    const SwTableBox* pBox = pFirstBox->GetBox();
+    do {
+        const SwTableBoxes& rBoxes = pBox->GetUpper()->GetTabBoxes();
+        const SwTableBox* pCmp;
+        for( USHORT n = 0; pBox != ( pCmp = rBoxes[ n ] ); ++n )
+            nRet += (USHORT) pCmp->GetFrmFmt()->GetFrmSize().GetWidth();
+        pBox = pBox->GetUpper()->GetUpper();
+    } while( pBox );
+    return nRet;
+}
+
+USHORT lcl_GetLineWidth( const _FndLine& rLine )
+{
+    USHORT nRet = 0;
+    for( USHORT n = rLine.GetBoxes().Count(); n; )
+        nRet += (USHORT)rLine.GetBoxes()[ --n ]->GetBox()->GetFrmFmt()
+                        ->GetFrmSize().GetWidth();
+    return nRet;
+}
+
+BOOL lcl_CopyBoxToDoc( const _FndBox*& rpFndBox, void* pPara )
+{
+    _CpyPara* pCpyPara = (_CpyPara*)pPara;
+
+    // Berechne die neue Size
+    ULONG nSize = pCpyPara->nNewSize;
+    nSize *= rpFndBox->GetBox()->GetFrmFmt()->GetFrmSize().GetWidth();
+    nSize /= pCpyPara->nOldSize;
+
+    // suche das Frame-Format in der Liste aller Frame-Formate
+    _CpyTabFrm aFindFrm( (SwTableBoxFmt*)rpFndBox->GetBox()->GetFrmFmt() );
+
+    SwFmtFrmSize aFrmSz;
+    USHORT nFndPos;
+    if( !pCpyPara->rTabFrmArr.Seek_Entry( aFindFrm, &nFndPos ) ||
+        ( aFrmSz = ( aFindFrm = pCpyPara->rTabFrmArr[ nFndPos ]).pNewFrmFmt->
+            GetFrmSize()).GetWidth() != (SwTwips)nSize )
+    {
+        // es ist noch nicht vorhanden, also kopiere es
+        aFindFrm.pNewFrmFmt = pCpyPara->pDoc->MakeTableBoxFmt();
+        aFindFrm.pNewFrmFmt->CopyAttrs( *rpFndBox->GetBox()->GetFrmFmt() );
+        if( !pCpyPara->bCpyCntnt )
+            aFindFrm.pNewFrmFmt->ResetAttr(  RES_BOXATR_FORMULA, RES_BOXATR_VALUE );
+        aFrmSz.SetWidth( nSize );
+        aFindFrm.pNewFrmFmt->SetAttr( aFrmSz );
+        pCpyPara->rTabFrmArr.Insert( aFindFrm );
+    }
+
+    SwTableBox* pBox;
+    if( rpFndBox->GetLines().Count() )
+    {
+        pBox = new SwTableBox( aFindFrm.pNewFrmFmt,
+                    rpFndBox->GetLines().Count(), pCpyPara->pInsLine );
+        pCpyPara->pInsLine->GetTabBoxes().C40_INSERT( SwTableBox, pBox, pCpyPara->nInsPos++ );
+        _CpyPara aPara( *pCpyPara, pBox );
+        aPara.nNewSize = nSize;     // hole die Groesse
+        ((_FndBox*)rpFndBox)->GetLines().ForEach( &lcl_CopyLineToDoc, &aPara );
+    }
+    else
+    {
+        // erzeuge eine leere Box
+        pCpyPara->pDoc->GetNodes().InsBoxen( pCpyPara->pTblNd, pCpyPara->pInsLine,
+                        aFindFrm.pNewFrmFmt,
+                        (SwTxtFmtColl*)pCpyPara->pDoc->GetDfltTxtFmtColl(),
+                        0, pCpyPara->nInsPos );
+
+        if( pCpyPara->bCpyCntnt )
+        {
+            // dann kopiere mal den Inhalt in diese leere Box
+            pBox = pCpyPara->pInsLine->GetTabBoxes()[ pCpyPara->nInsPos ];
+
+            // der Inhalt kopiert wird, dann koennen auch Formeln&Values
+            // kopiert werden.
+            {
+                SfxItemSet aBoxAttrSet( pCpyPara->pDoc->GetAttrPool(),
+                                        RES_BOXATR_FORMAT, RES_BOXATR_VALUE );
+                aBoxAttrSet.Put( rpFndBox->GetBox()->GetFrmFmt()->GetAttrSet() );
+                if( aBoxAttrSet.Count() )
+                {
+                    const SfxPoolItem* pItem;
+                    SvNumberFormatter* pN = pCpyPara->pDoc->GetNumberFormatter( FALSE );
+                    if( pN && pN->HasMergeFmtTbl() && SFX_ITEM_SET == aBoxAttrSet.
+                        GetItemState( RES_BOXATR_FORMAT, FALSE, &pItem ) )
+                    {
+                        ULONG nOldIdx = ((SwTblBoxNumFormat*)pItem)->GetValue();
+                        ULONG nNewIdx = pN->GetMergeFmtIndex( nOldIdx );
+                        if( nNewIdx != nOldIdx )
+                            aBoxAttrSet.Put( SwTblBoxNumFormat( nNewIdx ));
+                    }
+                    pBox->ClaimFrmFmt()->SetAttr( aBoxAttrSet );
+                }
+            }
+            SwDoc* pFromDoc = rpFndBox->GetBox()->GetFrmFmt()->GetDoc();
+            SwNodeRange aCpyRg( *rpFndBox->GetBox()->GetSttNd(), 1,
+                        *rpFndBox->GetBox()->GetSttNd()->EndOfSectionNode() );
+            SwNodeIndex aInsIdx( *pBox->GetSttNd(), 1 );
+
+            pFromDoc->CopyWithFlyInFly( aCpyRg, aInsIdx, FALSE );
+            // den initialen TextNode loeschen
+            pCpyPara->pDoc->GetNodes().Delete( aInsIdx, 1 );
+        }
+        ++pCpyPara->nInsPos;
+    }
+    return TRUE;
+}
+
+BOOL lcl_CopyLineToDoc( const _FndLine*& rpFndLine, void* pPara )
+{
+    _CpyPara* pCpyPara = (_CpyPara*)pPara;
+
+    // suche das Format in der Liste aller Formate
+    _CpyTabFrm aFindFrm( (SwTableBoxFmt*)rpFndLine->GetLine()->GetFrmFmt() );
+    USHORT nFndPos;
+    if( !pCpyPara->rTabFrmArr.Seek_Entry( aFindFrm, &nFndPos ))
+    {
+        // es ist noch nicht vorhanden, also kopiere es
+        aFindFrm.pNewFrmFmt = (SwTableBoxFmt*)pCpyPara->pDoc->MakeTableLineFmt();
+        aFindFrm.pNewFrmFmt->CopyAttrs( *rpFndLine->GetLine()->GetFrmFmt() );
+        pCpyPara->rTabFrmArr.Insert( aFindFrm );
+    }
+    else
+        aFindFrm = pCpyPara->rTabFrmArr[ nFndPos ];
+
+    SwTableLine* pNewLine = new SwTableLine( (SwTableLineFmt*)aFindFrm.pNewFrmFmt,
+                        rpFndLine->GetBoxes().Count(), pCpyPara->pInsBox );
+    if( pCpyPara->pInsBox )
+    {
+        pCpyPara->pInsBox->GetTabLines().C40_INSERT( SwTableLine, pNewLine, pCpyPara->nInsPos++ );
+    }
+    else
+    {
+        pCpyPara->pTblNd->GetTable().GetTabLines().C40_INSERT( SwTableLine, pNewLine,
+                            pCpyPara->nInsPos++ );
+    }
+
+    _CpyPara aPara( *pCpyPara, pNewLine );
+
+    // berechne die neue Size der Boxen einer Line
+    if( rpFndLine->GetBoxes().Count() ==
+                    rpFndLine->GetLine()->GetTabBoxes().Count() )
+    {
+        // hole die Size vom Parent
+        const SwFrmFmt* pFmt;
+
+        if( rpFndLine->GetLine()->GetUpper() )
+            pFmt = rpFndLine->GetLine()->GetUpper()->GetFrmFmt();
+        else
+            pFmt = pCpyPara->pTblNd->GetTable().GetFrmFmt();
+        aPara.nOldSize = pFmt->GetFrmSize().GetWidth();
+    }
+    else
+        // errechne sie
+        for( USHORT n = 0; n < rpFndLine->GetBoxes().Count(); ++n )
+            aPara.nOldSize += rpFndLine->GetBoxes()[n]
+                        ->GetBox()->GetFrmFmt()->GetFrmSize().GetWidth();
+
+    ((_FndLine*)rpFndLine)->GetBoxes().ForEach( &lcl_CopyBoxToDoc, &aPara );
+    return TRUE;
+}
+
+BOOL SwTable::CopyHeadlineIntoTable( SwTableNode& rTblNd )
+{
+    // suche alle Boxen / Lines
+    SwSelBoxes aSelBoxes;
+    SwTableBox* pBox = GetTabSortBoxes()[ 0 ];
+    pBox = GetTblBox( pBox->GetSttNd()->FindStartNode()->GetIndex() + 1 );
+    SelLineFromBox( pBox, aSelBoxes, TRUE );
+
+    _FndBox aFndBox( 0, 0 );
+    {
+        _FndPara aPara( aSelBoxes, &aFndBox );
+        ((SwTableLines&)GetTabLines()).ForEach( &_FndLineCopyCol, &aPara );
+    }
+    if( !aFndBox.GetLines().Count() )
+        return FALSE;
+
+    {
+        // Tabellen-Formeln in die relative Darstellung umwandeln
+        SwTableFmlUpdate aMsgHnt( this );
+        aMsgHnt.eFlags = TBL_RELBOXNAME;
+        GetFrmFmt()->GetDoc()->UpdateTblFlds( &aMsgHnt );
+    }
+
+    _CpyTabFrms aCpyFmt;
+    _CpyPara aPara( &rTblNd, 1, aCpyFmt, TRUE );
+    aPara.nNewSize = aPara.nOldSize = rTblNd.GetTable().GetFrmFmt()->GetFrmSize().GetWidth();
+    // dann kopiere mal
+    aFndBox.GetLines().ForEach( &lcl_CopyLineToDoc, &aPara );
+
+    return TRUE;
+}
+
+BOOL SwTable::MakeCopy( SwDoc* pInsDoc, const SwPosition& rPos,
+                        const SwSelBoxes& rSelBoxes, BOOL bCpyNds,
+                        BOOL bCpyName ) const
+{
+    // suche alle Boxen / Lines
+    _FndBox aFndBox( 0, 0 );
+    {
+        _FndPara aPara( rSelBoxes, &aFndBox );
+        ((SwTableLines&)GetTabLines()).ForEach( &_FndLineCopyCol, &aPara );
+    }
+    if( !aFndBox.GetLines().Count() )
+        return FALSE;
+
+    // erst die Poolvorlagen fuer die Tabelle kopieren, damit die dann
+    // wirklich kopiert und damit die gueltigen Werte haben.
+    SwDoc* pSrcDoc = GetFrmFmt()->GetDoc();
+    if( pSrcDoc != pInsDoc )
+    {
+        pInsDoc->CopyTxtColl( *pSrcDoc->GetTxtCollFromPool( RES_POOLCOLL_TABLE ) );
+        pInsDoc->CopyTxtColl( *pSrcDoc->GetTxtCollFromPool( RES_POOLCOLL_TABLE_HDLN ) );
+    }
+
+    SwTable* pNewTbl = (SwTable*)pInsDoc->InsertTable( rPos, 1, 1,
+                    GetFrmFmt()->GetHoriOrient().GetHoriOrient() );
+    if( !pNewTbl )
+        return FALSE;
+
+    SwNodeIndex aIdx( rPos.nNode, -1 );
+    SwTableNode* pTblNd = aIdx.GetNode().FindTableNode();
+    aIdx++;
+    ASSERT( pTblNd, "wo ist denn nun der TableNode?" );
+
+    pTblNd->GetTable().SetHeadlineRepeat( IsHeadlineRepeat() );
+
+    if( IS_TYPE( SwDDETable, this ))
+    {
+        // es wird eine DDE-Tabelle kopiert
+        // ist im neuen Dokument ueberhaupt der FeldTyp vorhanden ?
+        SwFieldType* pFldType = pInsDoc->InsertFldType(
+                                    *((SwDDETable*)this)->GetDDEFldType() );
+        ASSERT( pFldType, "unbekannter FieldType" );
+
+        // tauschen am Node den Tabellen-Pointer aus
+        pNewTbl = new SwDDETable( *pNewTbl,
+                                 (SwDDEFieldType*)pFldType );
+        pTblNd->SetNewTable( pNewTbl, FALSE );
+    }
+
+    pNewTbl->GetFrmFmt()->CopyAttrs( *GetFrmFmt() );
+    pNewTbl->SetTblChgMode( GetTblChgMode() );
+
+    //Vernichten der Frms die bereits angelegt wurden.
+    pTblNd->DelFrms();
+
+    {
+        // Tabellen-Formeln in die relative Darstellung umwandeln
+        SwTableFmlUpdate aMsgHnt( this );
+        aMsgHnt.eFlags = TBL_RELBOXNAME;
+        pSrcDoc->UpdateTblFlds( &aMsgHnt );
+    }
+
+    SwTblNumFmtMerge aTNFM( *pSrcDoc, *pInsDoc );
+
+    // Namen auch kopieren oder neuen eindeutigen erzeugen
+    if( bCpyName )
+        pNewTbl->GetFrmFmt()->SetName( GetFrmFmt()->GetName() );
+
+    _CpyTabFrms aCpyFmt;
+    _CpyPara aPara( pTblNd, 1, aCpyFmt, bCpyNds );
+    aPara.nNewSize = aPara.nOldSize = GetFrmFmt()->GetFrmSize().GetWidth();
+    // dann kopiere mal
+    aFndBox.GetLines().ForEach( &lcl_CopyLineToDoc, &aPara );
+
+    // dann setze oben und unten noch die "richtigen" Raender:
+    {
+        _FndLine* pFndLn = aFndBox.GetLines()[ 0 ];
+        SwTableLine* pLn = pFndLn->GetLine();
+        const SwTableLine* pTmp = pLn;
+        USHORT nLnPos = GetTabLines().GetPos( pTmp );
+        if( USHRT_MAX != nLnPos && nLnPos )
+        {
+            // es gibt eine Line davor
+            SwCollectTblLineBoxes aLnPara( FALSE, HEADLINE_BORDERCOPY );
+
+            pLn = GetTabLines()[ nLnPos - 1 ];
+            pLn->GetTabBoxes().ForEach( &lcl_Box_CollectBox, &aLnPara );
+
+            if( aLnPara.Resize( lcl_GetBoxOffset( aFndBox ),
+                                lcl_GetLineWidth( *pFndLn )) )
+            {
+                aLnPara.SetValues( TRUE );
+                pLn = pNewTbl->GetTabLines()[ 0 ];
+                pLn->GetTabBoxes().ForEach( &lcl_BoxSetSplitBoxFmts, &aLnPara );
+            }
+        }
+
+        pFndLn = aFndBox.GetLines()[ aFndBox.GetLines().Count() -1 ];
+        pLn = pFndLn->GetLine();
+        pTmp = pLn;
+        nLnPos = GetTabLines().GetPos( pTmp );
+        if( nLnPos < GetTabLines().Count() - 1 )
+        {
+            // es gibt eine Line dahinter
+            SwCollectTblLineBoxes aLnPara( TRUE, HEADLINE_BORDERCOPY );
+
+            pLn = GetTabLines()[ nLnPos + 1 ];
+            pLn->GetTabBoxes().ForEach( &lcl_Box_CollectBox, &aLnPara );
+
+            if( aLnPara.Resize( lcl_GetBoxOffset( aFndBox ),
+                                lcl_GetLineWidth( *pFndLn )) )
+            {
+                aLnPara.SetValues( FALSE );
+                pLn = pNewTbl->GetTabLines()[ pNewTbl->GetTabLines().Count()-1 ];
+                pLn->GetTabBoxes().ForEach( &lcl_BoxSetSplitBoxFmts, &aLnPara );
+            }
+        }
+    }
+
+    // die initiale Box muss noch geloescht werden
+    _DeleteBox( *pNewTbl, pNewTbl->GetTabLines()[
+                pNewTbl->GetTabLines().Count() - 1 ]->GetTabBoxes()[0],
+                0, FALSE, FALSE );
+
+    // Mal kurz aufraeumen:
+    pNewTbl->GCLines();
+
+    pTblNd->MakeFrms( &aIdx );  // erzeuge die Frames neu
+    return TRUE;
+}
+
+
+
+// ---------------------------------------------------------------
+
+// suche ab dieser Line nach der naechsten Box mit Inhalt
+SwTableBox* SwTableLine::FindNextBox( const SwTable& rTbl,
+                     const SwTableBox* pSrchBox, BOOL bOvrTblLns ) const
+{
+    const SwTableLine* pLine = this;            // fuer M800
+    SwTableBox* pBox;
+    USHORT nFndPos;
+    if( GetTabBoxes().Count() && pSrchBox &&
+        USHRT_MAX != ( nFndPos = GetTabBoxes().GetPos( pSrchBox )) &&
+        nFndPos + 1 != GetTabBoxes().Count() )
+    {
+        pBox = GetTabBoxes()[ nFndPos + 1 ];
+        while( pBox->GetTabLines().Count() )
+            pBox = pBox->GetTabLines()[0]->GetTabBoxes()[0];
+        return pBox;
+    }
+
+    if( GetUpper() )
+    {
+        nFndPos = GetUpper()->GetTabLines().GetPos( pLine );
+        ASSERT( USHRT_MAX != nFndPos, "Line nicht in der Tabelle" );
+        // gibts eine weitere Line
+        if( nFndPos+1 >= GetUpper()->GetTabLines().Count() )
+            return GetUpper()->GetUpper()->FindNextBox( rTbl, GetUpper(), bOvrTblLns );
+        pLine = GetUpper()->GetTabLines()[nFndPos+1];
+    }
+    else if( bOvrTblLns )       // ueber die "GrundLines" einer Tabelle ?
+    {
+        // suche in der Tabelle nach der naechsten Line
+        nFndPos = rTbl.GetTabLines().GetPos( pLine );
+        if( nFndPos + 1 >= rTbl.GetTabLines().Count() )
+            return 0;           // es gibt keine weitere Box mehr
+
+        pLine = rTbl.GetTabLines()[ nFndPos+1 ];
+    }
+    else
+        return 0;
+
+    if( pLine->GetTabBoxes().Count() )
+    {
+        pBox = pLine->GetTabBoxes()[0];
+        while( pBox->GetTabLines().Count() )
+            pBox = pBox->GetTabLines()[0]->GetTabBoxes()[0];
+        return pBox;
+    }
+    return pLine->FindNextBox( rTbl, 0, bOvrTblLns );
+}
+
+// suche ab dieser Line nach der vorherigen Box
+SwTableBox* SwTableLine::FindPreviousBox( const SwTable& rTbl,
+                         const SwTableBox* pSrchBox, BOOL bOvrTblLns ) const
+{
+    const SwTableLine* pLine = this;            // fuer M800
+    SwTableBox* pBox;
+    USHORT nFndPos;
+    if( GetTabBoxes().Count() && pSrchBox &&
+        USHRT_MAX != ( nFndPos = GetTabBoxes().GetPos( pSrchBox )) &&
+        nFndPos )
+    {
+        pBox = GetTabBoxes()[ nFndPos - 1 ];
+        while( pBox->GetTabLines().Count() )
+        {
+            pLine = pBox->GetTabLines()[pBox->GetTabLines().Count()-1];
+            pBox = pLine->GetTabBoxes()[pLine->GetTabBoxes().Count()-1];
+        }
+        return pBox;
+    }
+
+    if( GetUpper() )
+    {
+        nFndPos = GetUpper()->GetTabLines().GetPos( pLine );
+        ASSERT( USHRT_MAX != nFndPos, "Line nicht in der Tabelle" );
+        // gibts eine weitere Line
+        if( !nFndPos )
+            return GetUpper()->GetUpper()->FindPreviousBox( rTbl, GetUpper(), bOvrTblLns );
+        pLine = GetUpper()->GetTabLines()[nFndPos-1];
+    }
+    else if( bOvrTblLns )       // ueber die "GrundLines" einer Tabelle ?
+    {
+        // suche in der Tabelle nach der naechsten Line
+        nFndPos = rTbl.GetTabLines().GetPos( pLine );
+        if( !nFndPos )
+            return 0;           // es gibt keine weitere Box mehr
+
+        pLine = rTbl.GetTabLines()[ nFndPos-1 ];
+    }
+    else
+        return 0;
+
+    if( pLine->GetTabBoxes().Count() )
+    {
+        pBox = pLine->GetTabBoxes()[pLine->GetTabBoxes().Count()-1];
+        while( pBox->GetTabLines().Count() )
+        {
+            pLine = pBox->GetTabLines()[pBox->GetTabLines().Count()-1];
+            pBox = pLine->GetTabBoxes()[pLine->GetTabBoxes().Count()-1];
+        }
+        return pBox;
+    }
+    return pLine->FindPreviousBox( rTbl, 0, bOvrTblLns );
+}
+
+// suche ab dieser Line nach der naechsten Box mit Inhalt
+SwTableBox* SwTableBox::FindNextBox( const SwTable& rTbl,
+                         const SwTableBox* pSrchBox, BOOL bOvrTblLns ) const
+{
+    if( !pSrchBox  && !GetTabLines().Count() )
+        return (SwTableBox*)this;
+    return GetUpper()->FindNextBox( rTbl, pSrchBox ? pSrchBox : this,
+                                        bOvrTblLns );
+
+}
+
+// suche ab dieser Line nach der naechsten Box mit Inhalt
+SwTableBox* SwTableBox::FindPreviousBox( const SwTable& rTbl,
+                         const SwTableBox* pSrchBox, BOOL bOvrTblLns ) const
+{
+    if( !pSrchBox && !GetTabLines().Count() )
+        return (SwTableBox*)this;
+    return GetUpper()->FindPreviousBox( rTbl, pSrchBox ? pSrchBox : this,
+                                        bOvrTblLns );
+}
+
+
+BOOL lcl_BoxSetHeadCondColl( const SwTableBox*& rpBox, void* pPara )
+{
+    // in der HeadLine sind die Absaetze mit BedingtenVorlage anzupassen
+    const SwStartNode* pSttNd = rpBox->GetSttNd();
+    if( pSttNd )
+        pSttNd->CheckSectionCondColl();
+    else
+        ((SwTableBox*)rpBox)->GetTabLines().ForEach( &lcl_LineSetHeadCondColl, 0 );
+    return TRUE;
+}
+
+BOOL lcl_LineSetHeadCondColl( const SwTableLine*& rpLine, void* pPara )
+{
+    ((SwTableLine*)rpLine)->GetTabBoxes().ForEach( &lcl_BoxSetHeadCondColl, 0 );
+    return TRUE;
+}
+
+/*  */
+
+#pragma optimize( "", off )
+
+SwTwips lcl_GetDistance( SwTableBox* pBox, BOOL bLeft )
+{
+    BOOL bFirst = TRUE;
+    SwTwips nRet = 0;
+    SwTableLine* pLine;
+    while( pBox && 0 != ( pLine = pBox->GetUpper() ) )
+    {
+        USHORT nStt = 0, nPos = pLine->GetTabBoxes().C40_GETPOS( SwTableBox, pBox );
+
+        if( bFirst && !bLeft )
+            ++nPos;
+        bFirst = FALSE;
+
+        while( nStt < nPos )
+            nRet += pLine->GetTabBoxes()[ nStt++ ]->GetFrmFmt()
+                            ->GetFrmSize().GetWidth();
+        pBox = pLine->GetUpper();
+    }
+    return nRet;
+}
+
+//#pragma optimize( "", on )
+
+BOOL lcl_SetSelBoxWidth( SwTableLine* pLine, CR_SetBoxWidth& rParam,
+                         SwTwips nDist, BOOL bCheck )
+{
+    SwTableBoxes& rBoxes = pLine->GetTabBoxes();
+    for( USHORT n = 0; n < rBoxes.Count(); ++n )
+    {
+        SwTableBox* pBox = rBoxes[ n ];
+        SwFrmFmt* pFmt = pBox->GetFrmFmt();
+        const SwFmtFrmSize& rSz = pFmt->GetFrmSize();
+        SwTwips nWidth = rSz.GetWidth();
+        BOOL bGreaterBox;
+
+        if( bCheck )
+        {
+            for( USHORT i = 0; i < pBox->GetTabLines().Count(); ++i )
+                if( !::lcl_SetSelBoxWidth( pBox->GetTabLines()[ i ], rParam,
+                                            nDist, TRUE ))
+                    return FALSE;
+
+
+            // dann noch mal alle "ContentBoxen" sammeln
+            if( !rParam.bBigger &&
+                ( Abs( nDist + (( rParam.nMode && rParam.bLeft ) ? 0 : nWidth )
+                    - rParam.nSide ) < COLFUZZY ) ||
+                 ( 0 != ( bGreaterBox = TBLFIX_CHGABS != rParam.nMode &&
+                    ( nDist + ( rParam.bLeft ? 0 : nWidth ) ) >= rParam.nSide)) )
+            {
+                rParam.bAnyBoxFnd = TRUE;
+                SwTwips nLowerDiff;
+                if( bGreaterBox && TBLFIX_CHGPROP == rParam.nMode )
+                {
+                    // die "anderen Boxen" wurden angepasst,
+                    // also sich um diesen Betrag aendern
+                    nLowerDiff = (nDist + ( rParam.bLeft ? 0 : nWidth ) ) - rParam.nSide;
+                    nLowerDiff *= rParam.nDiff;
+                    nLowerDiff /= rParam.nMaxSize;
+                    nLowerDiff = rParam.nDiff - nLowerDiff;
+                }
+                else
+                    nLowerDiff = rParam.nDiff;
+
+                if( nWidth < nLowerDiff || nWidth - nLowerDiff < MINLAY )
+                    return FALSE;
+            }
+        }
+        else
+        {
+            SwTwips nLowerDiff = 0, nOldLower = rParam.nLowerDiff;
+            for( USHORT i = 0; i < pBox->GetTabLines().Count(); ++i )
+            {
+                rParam.nLowerDiff = 0;
+                lcl_SetSelBoxWidth( pBox->GetTabLines()[ i ], rParam, nDist, FALSE );
+
+                if( nLowerDiff < rParam.nLowerDiff )
+                    nLowerDiff = rParam.nLowerDiff;
+            }
+            rParam.nLowerDiff = nOldLower;
+
+
+            if( nLowerDiff ||
+                ( Abs( nDist + ( (rParam.nMode && rParam.bLeft) ? 0 : nWidth )
+                            - rParam.nSide ) < COLFUZZY ) ||
+                 ( 0 != ( bGreaterBox = !nOldLower && TBLFIX_CHGABS != rParam.nMode &&
+                    ( nDist + ( rParam.bLeft ? 0 : nWidth ) ) >= rParam.nSide)) )
+            {
+                // in dieser Spalte ist der Cursor - also verkleinern / vergroessern
+                SwFmtFrmSize aNew( rSz );
+
+                if( !nLowerDiff )
+                {
+                    if( bGreaterBox && TBLFIX_CHGPROP == rParam.nMode )
+                    {
+                        // die "anderen Boxen" wurden angepasst,
+                        // also sich um diesen Betrag aendern
+                        nLowerDiff = (nDist + ( rParam.bLeft ? 0 : nWidth ) ) - rParam.nSide;
+                        nLowerDiff *= rParam.nDiff;
+                        nLowerDiff /= rParam.nMaxSize;
+                        nLowerDiff = rParam.nDiff - nLowerDiff;
+                    }
+                    else
+                        nLowerDiff = rParam.nDiff;
+                }
+
+                rParam.nLowerDiff += nLowerDiff;
+
+                if( rParam.bBigger )
+                    aNew.SetWidth( nWidth + nLowerDiff );
+                else
+                    aNew.SetWidth( nWidth - nLowerDiff );
+                rParam.aShareFmts.SetSize( *pBox, aNew );
+                break;
+            }
+        }
+
+        if( rParam.bLeft && rParam.nMode && nDist >= rParam.nSide )
+            break;
+
+        nDist += nWidth;
+
+        // wenns groesser wird, dann wars das
+        if( ( TBLFIX_CHGABS == rParam.nMode || !rParam.bLeft ) &&
+                nDist >= rParam.nSide )
+            break;
+    }
+    return TRUE;
+}
+
+BOOL lcl_SetOtherBoxWidth( SwTableLine* pLine, CR_SetBoxWidth& rParam,
+                                SwTwips nDist, BOOL bCheck )
+{
+    SwTableBoxes& rBoxes = pLine->GetTabBoxes();
+    for( USHORT n = 0; n < rBoxes.Count(); ++n )
+    {
+        SwTableBox* pBox = rBoxes[ n ];
+        SwFrmFmt* pFmt = pBox->GetFrmFmt();
+        const SwFmtFrmSize& rSz = pFmt->GetFrmSize();
+        SwTwips nWidth = rSz.GetWidth();
+
+        if( bCheck )
+        {
+            for( USHORT i = 0; i < pBox->GetTabLines().Count(); ++i )
+                if( !::lcl_SetOtherBoxWidth( pBox->GetTabLines()[ i ],
+                                                    rParam, nDist, TRUE ))
+                    return FALSE;
+
+            if( rParam.bBigger && ( TBLFIX_CHGABS == rParam.nMode
+                    ? Abs( nDist - rParam.nSide ) < COLFUZZY
+                    : ( rParam.bLeft ? nDist < rParam.nSide - COLFUZZY
+                                     : nDist >= rParam.nSide - COLFUZZY )) )
+            {
+                rParam.bAnyBoxFnd = TRUE;
+                SwTwips nDiff;
+                if( TBLFIX_CHGPROP == rParam.nMode )        // Tabelle fix, proport.
+                {
+                    // relativ berechnen
+                    nDiff = nWidth;
+                    nDiff *= rParam.nDiff;
+                    nDiff /= rParam.nMaxSize;
+                }
+                else
+                    nDiff = rParam.nDiff;
+
+                if( nWidth < nDiff || nWidth - nDiff < MINLAY )
+                    return FALSE;
+            }
+        }
+        else
+        {
+            SwTwips nLowerDiff = 0, nOldLower = rParam.nLowerDiff;
+            for( USHORT i = 0; i < pBox->GetTabLines().Count(); ++i )
+            {
+                rParam.nLowerDiff = 0;
+                lcl_SetOtherBoxWidth( pBox->GetTabLines()[ i ], rParam,
+                                            nDist, FALSE );
+
+                if( nLowerDiff < rParam.nLowerDiff )
+                    nLowerDiff = rParam.nLowerDiff;
+            }
+            rParam.nLowerDiff = nOldLower;
+
+            if( nLowerDiff ||
+                ( TBLFIX_CHGABS == rParam.nMode
+                        ? Abs( nDist - rParam.nSide ) < COLFUZZY
+                        : ( rParam.bLeft ? nDist < rParam.nSide - COLFUZZY
+                                         : nDist >= rParam.nSide - COLFUZZY)
+                 ) )
+            {
+                SwFmtFrmSize aNew( rSz );
+
+                if( !nLowerDiff )
+                {
+                    if( TBLFIX_CHGPROP == rParam.nMode )        // Tabelle fix, proport.
+                    {
+                        // relativ berechnen
+                        nLowerDiff = nWidth;
+                        nLowerDiff *= rParam.nDiff;
+                        nLowerDiff /= rParam.nMaxSize;
+                    }
+                    else
+                        nLowerDiff = rParam.nDiff;
+                }
+
+                rParam.nLowerDiff += nLowerDiff;
+
+                if( rParam.bBigger )
+                    aNew.SetWidth( nWidth - nLowerDiff );
+                else
+                    aNew.SetWidth( nWidth + nLowerDiff );
+
+                rParam.aShareFmts.SetSize( *pBox, aNew );
+            }
+        }
+
+        nDist += nWidth;
+        if( ( TBLFIX_CHGABS == rParam.nMode || rParam.bLeft ) &&
+            nDist > rParam.nSide )
+            break;
+    }
+    return TRUE;
+}
+
+/**/
+
+//#pragma optimize( "", off )
+
+BOOL lcl_InsSelBox( SwTableLine* pLine, CR_SetBoxWidth& rParam,
+                            SwTwips nDist, BOOL bCheck )
+{
+    SwTableBoxes& rBoxes = pLine->GetTabBoxes();
+    USHORT n, nCmp;
+    for( n = 0; n < rBoxes.Count(); ++n )
+    {
+        SwTableBox* pBox = rBoxes[ n ];
+        SwTableBoxFmt* pFmt = (SwTableBoxFmt*)pBox->GetFrmFmt();
+        const SwFmtFrmSize& rSz = pFmt->GetFrmSize();
+        SwTwips nWidth = rSz.GetWidth();
+
+        if( bCheck )
+        {
+            for( USHORT i = 0; i < pBox->GetTabLines().Count(); ++i )
+                if( !::lcl_InsSelBox( pBox->GetTabLines()[ i ], rParam,
+                                            nDist, TRUE ))
+                    return FALSE;
+
+            // dann noch mal alle "ContentBoxen" sammeln
+            if( Abs( nDist + ( rParam.bLeft ? 0 : nWidth )
+                    - rParam.nSide ) < COLFUZZY )
+                nCmp = 1;
+            else if( nDist + ( rParam.bLeft ? 0 : nWidth/2 ) > rParam.nSide )
+                nCmp = 2;
+            else
+                nCmp = 0;
+
+            if( nCmp )
+            {
+                rParam.bAnyBoxFnd = TRUE;
+                if( pFmt->GetProtect().IsCntntProtected() )
+                    return FALSE;
+
+                if( rParam.bSplittBox &&
+                    nWidth - rParam.nDiff <= COLFUZZY +
+                        ( 567 / 2 /* min. 0,5 cm Platz lassen*/) )
+                    return FALSE;
+
+                if( pBox->GetSttNd() )
+                    rParam.aBoxes.Insert( pBox );
+
+                break;
+            }
+        }
+        else
+        {
+            SwTwips nLowerDiff = 0, nOldLower = rParam.nLowerDiff;
+            for( USHORT i = 0; i < pBox->GetTabLines().Count(); ++i )
+            {
+                rParam.nLowerDiff = 0;
+                lcl_InsSelBox( pBox->GetTabLines()[ i ], rParam, nDist, FALSE );
+
+                if( nLowerDiff < rParam.nLowerDiff )
+                    nLowerDiff = rParam.nLowerDiff;
+            }
+            rParam.nLowerDiff = nOldLower;
+
+            if( nLowerDiff )
+                nCmp = 1;
+            else if( Abs( nDist + ( rParam.bLeft ? 0 : nWidth )
+                                - rParam.nSide ) < COLFUZZY )
+                nCmp = 2;
+            else if( nDist + nWidth / 2 > rParam.nSide )
+                nCmp = 3;
+            else
+                nCmp = 0;
+
+            if( nCmp )
+            {
+                // in dieser Spalte ist der Cursor - also verkleinern / vergroessern
+                if( 1 == nCmp )
+                {
+                    if( !rParam.bSplittBox )
+                    {
+                        // die akt. Box auf
+                        SwFmtFrmSize aNew( rSz );
+                        aNew.SetWidth( nWidth + rParam.nDiff );
+                        rParam.aShareFmts.SetSize( *pBox, aNew );
+                    }
+                }
+                else
+                {
+                    ASSERT( pBox->GetSttNd(), "Das muss eine EndBox sein!");
+
+                    if( !rParam.bLeft && 3 != nCmp )
+                        ++n;
+
+                    ::_InsTblBox( pFmt->GetDoc(), rParam.pTblNd,
+                                        pLine, pFmt, pBox, n );
+
+                    SwTableBox* pNewBox = rBoxes[ n ];
+                    SwFmtFrmSize aNew( rSz );
+                    aNew.SetWidth( rParam.nDiff );
+                    rParam.aShareFmts.SetSize( *pNewBox, aNew );
+
+                    // Sonderfall: kein Platz in den anderen Boxen
+                    //              aber in der Zelle
+                    if( rParam.bSplittBox )
+                    {
+                        // die akt. Box auf
+                        SwFmtFrmSize aNew( rSz );
+                        aNew.SetWidth( nWidth - rParam.nDiff );
+                        rParam.aShareFmts.SetSize( *pBox, aNew );
+                    }
+
+                    // Sonderbehandlung fuer Umrandung die Rechte muss
+                    // entfernt werden
+                    {
+                        const SvxBoxItem& rBoxItem = pBox->GetFrmFmt()->GetBox();
+                        if( rBoxItem.GetRight() )
+                        {
+                            SvxBoxItem aTmp( rBoxItem );
+                            aTmp.SetLine( 0, BOX_LINE_RIGHT );
+                            rParam.aShareFmts.SetAttr( rParam.bLeft
+                                                            ? *pNewBox
+                                                            : *pBox, aTmp );
+                        }
+                    }
+                }
+
+                rParam.nLowerDiff = rParam.nDiff;
+                break;
+            }
+        }
+
+        if( rParam.bLeft && rParam.nMode && nDist >= rParam.nSide )
+            break;
+
+        nDist += nWidth;
+    }
+    return TRUE;
+}
+//#pragma optimize( "", on )
+
+BOOL lcl_InsOtherBox( SwTableLine* pLine, CR_SetBoxWidth& rParam,
+                                SwTwips nDist, BOOL bCheck )
+{
+    // Sonderfall: kein Platz in den anderen Boxen aber in der Zelle
+    if( rParam.bSplittBox )
+        return TRUE;
+
+    SwTableBoxes& rBoxes = pLine->GetTabBoxes();
+    USHORT n;
+
+    // Tabelle fix, proport.
+    if( !rParam.nRemainWidth && TBLFIX_CHGPROP == rParam.nMode )
+    {
+        // dann die richtige Breite suchen, auf die sich die relative
+        // Breitenanpassung bezieht.
+        SwTwips nTmpDist = nDist;
+        for( n = 0; n < rBoxes.Count(); ++n )
+        {
+            SwTwips nWidth = rBoxes[ n ]->GetFrmFmt()->GetFrmSize().GetWidth();
+            if( (nTmpDist + nWidth / 2 ) > rParam.nSide )
+            {
+                rParam.nRemainWidth = rParam.bLeft
+                                        ? USHORT(nTmpDist)
+                                        : USHORT(rParam.nTblWidth - nTmpDist);
+                break;
+            }
+            nTmpDist += nWidth;
+        }
+    }
+
+    for( n = 0; n < rBoxes.Count(); ++n )
+    {
+        SwTableBox* pBox = rBoxes[ n ];
+        SwFrmFmt* pFmt = pBox->GetFrmFmt();
+        const SwFmtFrmSize& rSz = pFmt->GetFrmSize();
+        SwTwips nWidth = rSz.GetWidth();
+
+        if( bCheck )
+        {
+            for( USHORT i = 0; i < pBox->GetTabLines().Count(); ++i )
+                if( !::lcl_InsOtherBox( pBox->GetTabLines()[ i ],
+                                                    rParam, nDist, TRUE ))
+                    return FALSE;
+
+            if(
+                rParam.bLeft ? ((nDist + nWidth / 2 ) <= rParam.nSide &&
+                                (TBLFIX_CHGABS != rParam.nMode ||
+                                n < rBoxes.Count() &&
+                                (nDist + nWidth + rBoxes[ n+1 ]->
+                                    GetFrmFmt()->GetFrmSize().GetWidth() / 2)
+                                  > rParam.nSide ))
+                             : (nDist + nWidth / 2 ) > rParam.nSide
+                )
+            {
+                rParam.bAnyBoxFnd = TRUE;
+                SwTwips nDiff;
+                if( TBLFIX_CHGPROP == rParam.nMode )        // Tabelle fix, proport.
+                {
+                    // relativ berechnen
+                    nDiff = nWidth;
+                    nDiff *= rParam.nDiff;
+                    nDiff /= rParam.nRemainWidth;
+
+                    if( nWidth < nDiff || nWidth - nDiff < MINLAY )
+                        return FALSE;
+                }
+                else
+                {
+                    nDiff = rParam.nDiff;
+
+                    // teste ob die linke oder rechte Box gross genug
+                    // ist, um den Platz abzugeben!
+                    // es wird davor oder dahinter eine Box eingefuegt!
+                    SwTwips nTmpWidth = nWidth;
+                    if( rParam.bLeft && pBox->GetUpper()->GetUpper() )
+                    {
+                        const SwTableBox* pTmpBox = pBox;
+                        USHORT nBoxPos = n;
+                        while( !nBoxPos && pTmpBox->GetUpper()->GetUpper() )
+                        {
+                            pTmpBox = pTmpBox->GetUpper()->GetUpper();
+                            nBoxPos = pTmpBox->GetUpper()->GetTabBoxes().GetPos( pTmpBox );
+                        }
+//                      if( nBoxPos )
+                            nTmpWidth = pTmpBox->GetFrmFmt()->GetFrmSize().GetWidth();
+//                      else
+//                          nTmpWidth = 0;
+                    }
+
+                    if( nTmpWidth < nDiff || nTmpWidth - nDiff < MINLAY )
+                        return FALSE;
+                    break;
+                }
+            }
+        }
+        else
+        {
+            SwTwips nLowerDiff = 0, nOldLower = rParam.nLowerDiff;
+            for( USHORT i = 0; i < pBox->GetTabLines().Count(); ++i )
+            {
+                rParam.nLowerDiff = 0;
+                lcl_InsOtherBox( pBox->GetTabLines()[ i ], rParam,
+                                        nDist, FALSE );
+
+                if( nLowerDiff < rParam.nLowerDiff )
+                    nLowerDiff = rParam.nLowerDiff;
+            }
+            rParam.nLowerDiff = nOldLower;
+
+            if( nLowerDiff ||
+                (rParam.bLeft ? ((nDist + nWidth / 2 ) <= rParam.nSide &&
+                                (TBLFIX_CHGABS != rParam.nMode ||
+                                n < rBoxes.Count() &&
+                                (nDist + nWidth + rBoxes[ n+1 ]->
+                                    GetFrmFmt()->GetFrmSize().GetWidth() / 2)
+                                  > rParam.nSide ))
+                              : (nDist + nWidth / 2 ) > rParam.nSide ))
+            {
+                if( !nLowerDiff )
+                {
+                    if( TBLFIX_CHGPROP == rParam.nMode )        // Tabelle fix, proport.
+                    {
+                        // relativ berechnen
+                        nLowerDiff = nWidth;
+                        nLowerDiff *= rParam.nDiff;
+                        nLowerDiff /= rParam.nRemainWidth;
+                    }
+                    else
+                        nLowerDiff = rParam.nDiff;
+                }
+
+                SwFmtFrmSize aNew( rSz );
+                rParam.nLowerDiff += nLowerDiff;
+
+                if( rParam.bBigger )
+                    aNew.SetWidth( nWidth - nLowerDiff );
+                else
+                    aNew.SetWidth( nWidth + nLowerDiff );
+                rParam.aShareFmts.SetSize( *pBox, aNew );
+
+                if( TBLFIX_CHGABS == rParam.nMode )
+                    break;
+            }
+        }
+
+        nDist += nWidth;
+    }
+    return TRUE;
+}
+
+
+// das Ergebnis des Positions Vergleiches
+//  POS_BEFORE,             // Box liegt davor
+//  POS_BEHIND,             // Box liegt dahinter
+//  POS_INSIDE,             // Box liegt vollstaendig in Start/End
+//  POS_OUTSIDE,            // Box ueberlappt Start/End vollstaendig
+//  POS_EQUAL,              // Box und Start/End sind gleich
+//  POS_OVERLAP_BEFORE,     // Box ueberlappt den Start
+//  POS_OVERLAP_BEHIND      // Box ueberlappt das Ende
+
+SwComparePosition _CheckBoxInRange( USHORT nStt, USHORT nEnd,
+                                    USHORT nBoxStt, USHORT nBoxEnd )
+{
+// COLFUZZY noch beachten!!
+    SwComparePosition nRet;
+    if( nBoxStt + COLFUZZY < nStt )
+    {
+        if( nBoxEnd > nStt + COLFUZZY )
+        {
+            if( nBoxEnd >= nEnd + COLFUZZY )
+                nRet = POS_OUTSIDE;
+            else
+                nRet = POS_OVERLAP_BEFORE;
+        }
+        else
+            nRet = POS_BEFORE;
+    }
+    else if( nEnd > nBoxStt + COLFUZZY )
+    {
+        if( nEnd + COLFUZZY >= nBoxEnd )
+        {
+            if( COLFUZZY > Abs( long(nEnd) - long(nBoxEnd) ) &&
+                COLFUZZY > Abs( long(nStt) - long(nBoxStt) ) )
+                nRet = POS_EQUAL;
+            else
+                nRet = POS_INSIDE;
+        }
+        else
+            nRet = POS_OVERLAP_BEHIND;
+    }
+    else
+        nRet = POS_BEHIND;
+
+    return nRet;
+}
+
+void lcl_DelSelBox_CorrLowers( SwTableLine& rLine, CR_SetBoxWidth& rParam,
+                                SwTwips nWidth )
+{
+    // 1. Schritt die eigene Breite feststellen
+    SwTableBoxes& rBoxes = rLine.GetTabBoxes();
+    SwTwips nBoxWidth = 0;
+
+    for( USHORT n = rBoxes.Count(); n; )
+        nBoxWidth += rBoxes[ --n ]->GetFrmFmt()->GetFrmSize().GetWidth();
+
+    if( COLFUZZY < Abs( nWidth - nBoxWidth ))
+    {
+        //  sie muessen also angepasst werden
+        for( n = rBoxes.Count(); n; )
+        {
+            SwTableBox* pBox = rBoxes[ --n ];
+            SwFmtFrmSize aNew( pBox->GetFrmFmt()->GetFrmSize() );
+            long nDiff = aNew.GetWidth();
+            nDiff *= nWidth;
+            nDiff /= nBoxWidth;
+            aNew.SetWidth( nDiff );
+
+            rParam.aShareFmts.SetSize( *pBox, aNew );
+
+            if( !pBox->GetSttNd() )
+            {
+                // hat selbst auch Lower, also auch die anpassen
+                for( USHORT i = pBox->GetTabLines().Count(); i; )
+                    ::lcl_DelSelBox_CorrLowers( *pBox->GetTabLines()[ --i ],
+                                                rParam, nDiff  );
+            }
+        }
+    }
+}
+
+void lcl_ChgBoxSize( SwTableBox& rBox, CR_SetBoxWidth& rParam,
+                    const SwFmtFrmSize& rOldSz,
+                    USHORT& rDelWidth, SwTwips nDist )
+{
+    long nDiff;
+    BOOL bSetSize = FALSE;
+
+    switch( rParam.nMode )
+    {
+    case TBLFIX_CHGABS:     // Tabelle feste Breite, den Nachbar andern
+        nDiff = rDelWidth + rParam.nLowerDiff;
+        bSetSize = TRUE;
+        break;
+
+    case TBLFIX_CHGPROP:    // Tabelle feste Breite, alle Nachbarn aendern
+        if( !rParam.nRemainWidth )
+        {
+            // dann kurz berechnen:
+            if( rParam.bLeft )
+                rParam.nRemainWidth = USHORT(nDist);
+            else
+                rParam.nRemainWidth = USHORT(rParam.nTblWidth - nDist);
+        }
+
+        // relativ berechnen
+        nDiff = rOldSz.GetWidth();
+        nDiff *= rDelWidth + rParam.nLowerDiff;
+        nDiff /= rParam.nRemainWidth;
+
+        bSetSize = TRUE;
+        break;
+
+    case TBLVAR_CHGABS:     // Tabelle variable, alle Nachbarn aendern
+        if( COLFUZZY < Abs( rParam.nBoxWidth -
+                            ( rDelWidth + rParam.nLowerDiff )))
+        {
+            nDiff = rDelWidth + rParam.nLowerDiff - rParam.nBoxWidth;
+            if( 0 < nDiff )
+                rDelWidth -= USHORT(nDiff);
+            else
+                rDelWidth += USHORT(-nDiff);
+            bSetSize = TRUE;
+        }
+        break;
+    }
+
+    if( bSetSize )
+    {
+        SwFmtFrmSize aNew( rOldSz );
+        aNew.SetWidth( aNew.GetWidth() + nDiff );
+        rParam.aShareFmts.SetSize( rBox, aNew );
+
+        // dann leider nochmals die Lower anpassen
+        for( USHORT i = rBox.GetTabLines().Count(); i; )
+            ::lcl_DelSelBox_CorrLowers( *rBox.GetTabLines()[ --i ], rParam,
+                                            aNew.GetWidth() );
+    }
+}
+
+BOOL lcl_DeleteBox_Rekursiv( CR_SetBoxWidth& rParam, SwTableBox& rBox,
+                            BOOL bCheck )
+{
+    BOOL bRet = TRUE;
+    if( rBox.GetSttNd() )
+    {
+        if( bCheck )
+        {
+            rParam.bAnyBoxFnd = TRUE;
+            if( rBox.GetFrmFmt()->GetProtect().IsCntntProtected() )
+                bRet = FALSE;
+            else
+            {
+                SwTableBox* pBox = &rBox;
+                rParam.aBoxes.Insert( pBox );
+            }
+        }
+        else
+            ::_DeleteBox( rParam.pTblNd->GetTable(), &rBox,
+                            rParam.pUndo, FALSE, TRUE, &rParam.aShareFmts );
+    }
+    else
+    {
+        // die muessen leider alle sequentiel ueber die
+        // Contentboxen geloescht werden
+        for( USHORT i = rBox.GetTabLines().Count(); i; )
+        {
+            SwTableLine& rLine = *rBox.GetTabLines()[ --i ];
+            for( USHORT n = rLine.GetTabBoxes().Count(); n; )
+                if( !::lcl_DeleteBox_Rekursiv( rParam,
+                                *rLine.GetTabBoxes()[ --n ], bCheck ))
+                    return FALSE;
+        }
+    }
+    return bRet;
+}
+
+BOOL lcl_DelSelBox( SwTableLine* pLine, CR_SetBoxWidth& rParam,
+                    SwTwips nDist, BOOL bCheck )
+{
+    SwTableBoxes& rBoxes = pLine->GetTabBoxes();
+    USHORT n, nCntEnd, nBoxChkStt, nBoxChkEnd, nDelWidth = 0;
+    if( rParam.bLeft )
+    {
+        n = rBoxes.Count();
+        nCntEnd = 0;
+        nBoxChkStt = (USHORT)rParam.nSide;
+        nBoxChkEnd = rParam.nSide + rParam.nBoxWidth;
+    }
+    else
+    {
+        n = 0;
+        nCntEnd = rBoxes.Count();
+        nBoxChkStt = rParam.nSide - rParam.nBoxWidth;
+        nBoxChkEnd = (USHORT)rParam.nSide;
+    }
+
+
+    while( n != nCntEnd )
+    {
+        SwTableBox* pBox;
+        if( rParam.bLeft )
+            pBox = rBoxes[ --n ];
+        else
+            pBox = rBoxes[ n++ ];
+
+        SwFrmFmt* pFmt = pBox->GetFrmFmt();
+        const SwFmtFrmSize& rSz = pFmt->GetFrmSize();
+        long nWidth = rSz.GetWidth();
+        BOOL bDelBox = FALSE, bChgLowers = FALSE;
+
+        // die Boxenbreite testen und entpsrechend reagieren
+        SwComparePosition ePosType = ::_CheckBoxInRange(
+                            nBoxChkStt, nBoxChkEnd,
+                            USHORT(rParam.bLeft ? nDist - nWidth : nDist),
+                            USHORT(rParam.bLeft ? nDist : nDist + nWidth));
+
+        switch( ePosType )
+        {
+        case POS_BEFORE:
+            if( bCheck )
+            {
+                if( rParam.bLeft )
+                    return TRUE;
+            }
+            else if( rParam.bLeft )
+            {
+                ::lcl_ChgBoxSize( *pBox, rParam, rSz, nDelWidth, nDist );
+                if( TBLFIX_CHGABS == rParam.nMode )
+                    n = nCntEnd;
+            }
+            break;
+
+        case POS_BEHIND:
+            if( bCheck )
+            {
+                if( !rParam.bLeft )
+                    return TRUE;
+            }
+            else if( !rParam.bLeft )
+            {
+                ::lcl_ChgBoxSize( *pBox, rParam, rSz, nDelWidth, nDist );
+                if( TBLFIX_CHGABS == rParam.nMode )
+                    n = nCntEnd;
+            }
+            break;
+
+        case POS_OUTSIDE:           // Box ueberlappt Start/End vollstaendig
+        case POS_INSIDE:            // Box liegt vollstaendig in Start/End
+        case POS_EQUAL:             // Box und Start/End sind gleich
+            bDelBox = TRUE;
+            break;
+
+        case POS_OVERLAP_BEFORE:     // Box ueberlappt den Start
+            if( nBoxChkStt <= ( nDist + (rParam.bLeft ? - nWidth / 2
+                                                      : nWidth / 2 )))
+            {
+                if( !pBox->GetSttNd() )
+                    bChgLowers = TRUE;
+                else
+                    bDelBox = TRUE;
+            }
+            else if( !bCheck && rParam.bLeft )
+            {
+                if( !pBox->GetSttNd() )
+                    bChgLowers = TRUE;
+                else
+                {
+                    ::lcl_ChgBoxSize( *pBox, rParam, rSz, nDelWidth, nDist );
+                    if( TBLFIX_CHGABS == rParam.nMode )
+                        n = nCntEnd;
+                }
+            }
+            break;
+
+        case POS_OVERLAP_BEHIND:     // Box ueberlappt das Ende
+            // JP 10.02.99:
+            // generell loeschen oder wie beim OVERLAP_Before nur die, die
+            // bis zur Haelfte in die "Loesch-"Box reicht ???
+            if( !pBox->GetSttNd() )
+                bChgLowers = TRUE;
+            else
+                bDelBox = TRUE;
+            break;
+        }
+
+        if( bDelBox )
+        {
+            nDelWidth += USHORT(nWidth);
+            if( bCheck )
+            {
+                // die letzte/erste Box kann nur bei Tbl-Var geloescht werden,
+                // wenn diese so gross ist, wie die Aenderung an der Tabelle
+                if( (( TBLVAR_CHGABS != rParam.nMode ||
+                        nDelWidth != rParam.nBoxWidth ) &&
+                     COLFUZZY > Abs( rParam.bLeft
+                                    ? nWidth - nDist
+                                    : (nDist + nWidth - rParam.nTblWidth )))
+                    || !::lcl_DeleteBox_Rekursiv( rParam, *pBox, bCheck ) )
+                    return FALSE;
+
+                if( pFmt->GetProtect().IsCntntProtected() )
+                    return FALSE;
+            }
+            else
+            {
+                ::lcl_DeleteBox_Rekursiv( rParam, *pBox, bCheck );
+
+                if( !rParam.bLeft )
+                    --n, --nCntEnd;
+            }
+        }
+        else if( bChgLowers )
+        {
+            BOOL bFirst = TRUE, bCorrLowers = FALSE;
+            long nLowerDiff = 0;
+            long nOldLower = rParam.nLowerDiff;
+            USHORT nOldRemain = rParam.nRemainWidth;
+
+            for( USHORT i = pBox->GetTabLines().Count(); i; )
+            {
+                rParam.nLowerDiff = nDelWidth + nOldLower;
+                rParam.nRemainWidth = nOldRemain;
+                SwTableLine* pLine = pBox->GetTabLines()[ --i ];
+                if( !::lcl_DelSelBox( pLine, rParam, nDist, bCheck ))
+                    return FALSE;
+
+                // gibt es die Box und die darin enthaltenen Lines noch??
+                if( n < rBoxes.Count() &&
+                    pBox == rBoxes[ rParam.bLeft ? n : n-1 ] &&
+                    i < pBox->GetTabLines().Count() &&
+                    pLine == pBox->GetTabLines()[ i ] )
+                {
+                    if( !bFirst && !bCorrLowers &&
+                        COLFUZZY < Abs( nLowerDiff - rParam.nLowerDiff ) )
+                        bCorrLowers = TRUE;
+
+                    // die groesste "loesch" Breite entscheidet, aber nur wenn
+                    // nicht die gesamte Line geloescht wurde
+                    if( nLowerDiff < rParam.nLowerDiff )
+                        nLowerDiff = rParam.nLowerDiff;
+
+                    bFirst = FALSE;
+                }
+            }
+            rParam.nLowerDiff = nOldLower;
+            rParam.nRemainWidth = nOldRemain;
+
+            // wurden alle Boxen geloescht? Dann ist die DelBreite natuerlich
+            // die Boxenbreite
+            if( !nLowerDiff )
+                nLowerDiff = nWidth;
+
+            // DelBreite anpassen!!
+            nDelWidth += USHORT(nLowerDiff);
+
+            if( !bCheck )
+            {
+                // wurde die Box schon entfernt?
+                if( n > rBoxes.Count() ||
+                    pBox != rBoxes[ ( rParam.bLeft ? n : n-1 ) ] )
+                {
+                    // dann beim Loeschen nach rechts die Laufvar. anpassen
+                    if( !rParam.bLeft )
+                        --n, --nCntEnd;
+                }
+                else
+                {
+                    // sonst muss die Groesse der Box angepasst werden
+                    SwFmtFrmSize aNew( rSz );
+                    BOOL bCorrRel = FALSE;
+
+                    if( TBLVAR_CHGABS != rParam.nMode )
+                    {
+                        switch( ePosType )
+                        {
+                        case POS_OVERLAP_BEFORE:    // Box ueberlappt den Start
+                            if( TBLFIX_CHGPROP == rParam.nMode )
+                                bCorrRel = rParam.bLeft;
+                            else if( rParam.bLeft ) // TBLFIX_CHGABS
+                            {
+                                nLowerDiff = nLowerDiff - nDelWidth;
+                                bCorrLowers = TRUE;
+                                n = nCntEnd;
+                            }
+                            break;
+
+                        case POS_OVERLAP_BEHIND:    // Box ueberlappt das Ende
+                            if( TBLFIX_CHGPROP == rParam.nMode )
+                                bCorrRel = !rParam.bLeft;
+                            else if( !rParam.bLeft )    // TBLFIX_CHGABS
+                            {
+                                nLowerDiff = nLowerDiff - nDelWidth;
+                                bCorrLowers = TRUE;
+                                n = nCntEnd;
+                            }
+                            break;
+
+                        default:
+                            ASSERT( !pBox, "hier sollte man nie hinkommen" );
+                            break;
+                        }
+                    }
+
+                    if( bCorrRel )
+                    {
+                        if( !rParam.nRemainWidth )
+                        {
+                            // dann kurz berechnen:
+                            if( rParam.bLeft )
+                                rParam.nRemainWidth = USHORT(nDist - nLowerDiff);
+                            else
+                                rParam.nRemainWidth = USHORT(rParam.nTblWidth - nDist
+                                                                - nLowerDiff );
+                        }
+
+                        long nDiff = aNew.GetWidth() - nLowerDiff;
+                        nDiff *= nDelWidth + rParam.nLowerDiff;
+                        nDiff /= rParam.nRemainWidth;
+
+                        aNew.SetWidth( aNew.GetWidth() - nLowerDiff + nDiff );
+                    }
+                    else
+                        aNew.SetWidth( aNew.GetWidth() - nLowerDiff );
+                    rParam.aShareFmts.SetSize( *pBox, aNew );
+
+                    if( bCorrLowers )
+                    {
+                        // dann leider nochmals die Lower anpassen
+                        for( i = pBox->GetTabLines().Count(); i; )
+                            ::lcl_DelSelBox_CorrLowers( *pBox->
+                                GetTabLines()[ --i ], rParam, aNew.GetWidth() );
+                    }
+                }
+            }
+        }
+
+        if( rParam.bLeft )
+            nDist -= nWidth;
+        else
+            nDist += nWidth;
+    }
+    rParam.nLowerDiff = nDelWidth;
+    return TRUE;
+}
+
+// Dummy Funktion fuer die Methode SetColWidth
+BOOL lcl_DelOtherBox( SwTableLine* , CR_SetBoxWidth& , SwTwips , BOOL )
+{
+    return TRUE;
+}
+
+/**/
+
+void lcl_AjustLines( SwTableLine* pLine, CR_SetBoxWidth& rParam )
+{
+    SwTableBoxes& rBoxes = pLine->GetTabBoxes();
+    for( USHORT n = 0; n < rBoxes.Count(); ++n )
+    {
+        SwTableBox* pBox = rBoxes[ n ];
+
+        SwFmtFrmSize aSz( pBox->GetFrmFmt()->GetFrmSize() );
+        SwTwips nWidth = aSz.GetWidth();
+        nWidth *= rParam.nDiff;
+        nWidth /= rParam.nMaxSize;
+        aSz.SetWidth( nWidth );
+        rParam.aShareFmts.SetSize( *pBox, aSz );
+
+        for( USHORT i = 0; i < pBox->GetTabLines().Count(); ++i )
+            ::lcl_AjustLines( pBox->GetTabLines()[ i ], rParam );
+    }
+}
+
+#if !defined( PRODUCT ) || defined( JP_DEBUG )
+
+void _CheckBoxWidth( const SwTableLine& rLine, SwTwips nSize )
+{
+    const SwTableBoxes& rBoxes = rLine.GetTabBoxes();
+
+    SwTwips nAktSize = 0;
+    // checke doch mal ob die Tabellen korrekte Breiten haben
+    for( USHORT n = 0; n < rBoxes.Count(); ++n  )
+    {
+        const SwTableBox* pBox = rBoxes[ n ];
+        SwTwips nBoxW = pBox->GetFrmFmt()->GetFrmSize().GetWidth();
+        nAktSize += nBoxW;
+
+        for( USHORT i = 0; i < pBox->GetTabLines().Count(); ++i )
+            _CheckBoxWidth( *pBox->GetTabLines()[ i ], nBoxW );
+    }
+
+    if( Abs( nAktSize - nSize ) > ( COLFUZZY * rBoxes.Count() ) )
+    {
+        DBG_ERROR( "Boxen der Line zu klein/gross" );
+#if defined( WNT ) && defined( JP_DEBUG )
+        __asm int 3;
+#endif
+    }
+}
+
+#endif
+
+_FndBox* lcl_SaveInsDelData( CR_SetBoxWidth& rParam, SwUndo** ppUndo,
+                                SwTableSortBoxes& rTmpLst, SwTwips nDistStt )
+{
+    // suche alle Boxen / Lines
+    SwTable& rTbl = rParam.pTblNd->GetTable();
+
+    if( !rParam.aBoxes.Count() )
+    {
+        // erstmal die Boxen besorgen !
+        if( rParam.bBigger )
+            for( USHORT n = 0; n < rTbl.GetTabLines().Count(); ++n )
+                ::lcl_DelSelBox( rTbl.GetTabLines()[ n ], rParam, nDistStt, TRUE );
+        else
+            for( USHORT n = 0; n < rTbl.GetTabLines().Count(); ++n )
+                ::lcl_InsSelBox( rTbl.GetTabLines()[ n ], rParam, nDistStt, TRUE );
+    }
+
+    // loeschen der gesamten Tabelle verhindern
+    if( rParam.bBigger && rParam.aBoxes.Count() ==
+        rTbl.GetTabSortBoxes().Count() )
+        return 0;
+
+    _FndBox* pFndBox = new _FndBox( 0, 0 );
+    if( rParam.bBigger )
+        pFndBox->SetTableLines( rParam.aBoxes, rTbl );
+    else
+    {
+        _FndPara aPara( rParam.aBoxes, pFndBox );
+        rTbl.GetTabLines().ForEach( &_FndLineCopyCol, &aPara );
+        ASSERT( pFndBox->GetLines().Count(), "Wo sind die Boxen" );
+        pFndBox->SetTableLines( rTbl );
+
+        if( ppUndo )
+            rTmpLst.Insert( &rTbl.GetTabSortBoxes(), 0, rTbl.GetTabSortBoxes().Count() );
+    }
+
+    //Lines fuer das Layout-Update herausuchen.
+    pFndBox->DelFrms( rTbl );
+    pFndBox->SaveChartData( rTbl );
+
+    return pFndBox;
+}
+
+BOOL SwTable::SetColWidth( SwTableBox& rAktBox, USHORT eType,
+                        SwTwips nAbsDiff, SwTwips nRelDiff, SwUndo** ppUndo )
+{
+    SetHTMLTableLayout( 0 );    // MIB 9.7.97: HTML-Layout loeschen
+
+    const SwFmtFrmSize& rSz = GetFrmFmt()->GetFrmSize();
+    const SvxLRSpaceItem& rLR = GetFrmFmt()->GetLRSpace();
+
+    _FndBox* pFndBox = 0;                   // fuers Einfuegen/Loeschen
+    SwTableSortBoxes aTmpLst( 0, 5 );       // fuers Undo
+    BOOL bBigger,
+        bRet = FALSE,
+        bLeft = WH_COL_LEFT == ( eType & 0xff ) ||
+                WH_CELL_LEFT == ( eType & 0xff ),
+        bInsDel = 0 != (eType & WH_FLAG_INSDEL );
+    USHORT n;
+    ULONG nBoxIdx = rAktBox.GetSttIdx();
+
+    // bestimme die akt. Kante der Box
+    // wird nur fuer die Breitenmanipulation benoetigt!
+    SwTwips nDist = ::lcl_GetDistance( &rAktBox, bLeft ), nDistStt = 0;
+    CR_SetBoxWidth aParam( eType, nRelDiff, nDist, rSz.GetWidth(),
+                            bLeft ? nDist : rSz.GetWidth() - nDist,
+                            (SwTableNode*)rAktBox.GetSttNd()->FindTableNode() );
+    bBigger = aParam.bBigger;
+
+    FN_lcl_SetBoxWidth fnSelBox, fnOtherBox;
+    if( bInsDel )
+    {
+        if( bBigger )
+        {
+            fnSelBox = lcl_DelSelBox;
+            fnOtherBox = lcl_DelOtherBox;
+            aParam.nBoxWidth = (USHORT)rAktBox.GetFrmFmt()->GetFrmSize().GetWidth();
+            if( bLeft )
+                nDistStt = rSz.GetWidth();
+        }
+        else
+        {
+            fnSelBox = lcl_InsSelBox;
+            fnOtherBox = lcl_InsOtherBox;
+        }
+    }
+    else
+    {
+        fnSelBox = lcl_SetSelBoxWidth;
+        fnOtherBox = lcl_SetOtherBoxWidth;
+    }
+
+
+    switch( eType & 0xff )
+    {
+    case WH_COL_RIGHT:
+    case WH_COL_LEFT:
+        if( TBLVAR_CHGABS == eTblChgMode )
+        {
+            if( bInsDel )
+                bBigger = !bBigger;
+
+            // erstmal testen, ob ueberhaupt Platz ist
+            BOOL bChgLRSpace = TRUE;
+            if( bBigger )
+            {
+                if( GetFrmFmt()->GetDoc()->IsBrowseMode() &&
+                    !rSz.GetWidthPercent() )
+                {
+                    bRet = rSz.GetWidth() < USHRT_MAX - nRelDiff;
+                    bChgLRSpace = bLeft ? rLR.GetLeft() >= nAbsDiff
+                                        : rLR.GetRight() >= nAbsDiff;
+                }
+                else
+                    bRet = bLeft ? rLR.GetLeft() >= nAbsDiff
+                                 : rLR.GetRight() >= nAbsDiff;
+
+                if( !bRet && bInsDel &&
+                    // auf der anderen Seite Platz?
+                    ( bLeft ? rLR.GetRight() >= nAbsDiff
+                            : rLR.GetLeft() >= nAbsDiff ))
+                {
+                    bRet = TRUE; bLeft = !bLeft;
+                }
+
+                if( !bRet )
+                {
+                    // dann sich selbst rekursiv aufrufen; nur mit
+                    // einem anderen Mode -> proprotional
+                    TblChgMode eOld = eTblChgMode;
+                    eTblChgMode = TBLFIX_CHGPROP;
+
+                    bRet = SetColWidth( rAktBox, eType, nAbsDiff, nRelDiff,
+                                        ppUndo );
+                    eTblChgMode = eOld;
+                    return bRet;
+                }
+            }
+            else
+            {
+                bRet = TRUE;
+                for( n = 0; n < aLines.Count(); ++n )
+                {
+                    aParam.LoopClear();
+                    if( !(*fnSelBox)( aLines[ n ], aParam, nDistStt, TRUE ))
+                    {
+                        bRet = FALSE;
+                        break;
+                    }
+                }
+            }
+
+            if( bRet )
+            {
+                if( bInsDel )
+                {
+                    pFndBox = ::lcl_SaveInsDelData( aParam, ppUndo,
+                                                    aTmpLst, nDistStt );
+                    if( aParam.bBigger && aParam.aBoxes.Count() ==
+                                    aSortCntBoxes.Count() )
+                    {
+                        // dies gesamte Tabelle soll geloescht werden!!
+                        GetFrmFmt()->GetDoc()->DeleteRowCol( aParam.aBoxes );
+                        return FALSE;
+                    }
+
+                    if( ppUndo )
+                        *ppUndo = aParam.CreateUndo(
+                                        aParam.bBigger ? UNDO_TABLE_DELBOX
+                                                       : UNDO_TABLE_INSCOL );
+                }
+                else if( ppUndo )
+                    *ppUndo = new SwUndoAttrTbl( *aParam.pTblNd, TRUE );
+
+                long nFrmWidth = LONG_MAX;
+                LockModify();
+                SwFmtFrmSize aSz( rSz );
+                SvxLRSpaceItem aLR( rLR );
+                if( bBigger )
+                {
+                    // falls die Tabelle keinen Platz zum Wachsen hat, dann
+                    // muessen wir welchen schaffen!
+                    if( aSz.GetWidth() + nRelDiff > USHRT_MAX )
+                    {
+                        // dann mal herunterbrechen auf USHRT_MAX / 2
+                        CR_SetBoxWidth aTmpPara( 0, aSz.GetWidth() / 2,
+                                        0, aSz.GetWidth(), aSz.GetWidth(), aParam.pTblNd );
+                        for( USHORT n = 0; n < aLines.Count(); ++n )
+                            ::lcl_AjustLines( aLines[ n ], aTmpPara );
+                        aSz.SetWidth( aSz.GetWidth() / 2 );
+                        aParam.nDiff = nRelDiff /= 2;
+                        aParam.nSide /= 2;
+                        aParam.nMaxSize /= 2;
+                    }
+
+                    if( bLeft )
+                        aLR.SetLeft( USHORT( aLR.GetLeft() - nAbsDiff ) );
+                    else
+                        aLR.SetRight( USHORT( aLR.GetRight() - nAbsDiff ) );
+                }
+                else if( bLeft )
+                    aLR.SetLeft( USHORT( aLR.GetLeft() + nAbsDiff ) );
+                else
+                    aLR.SetRight( USHORT( aLR.GetRight() + nAbsDiff ) );
+
+                if( bChgLRSpace )
+                    GetFrmFmt()->SetAttr( aLR );
+                const SwFmtHoriOrient& rHOri = GetFrmFmt()->GetHoriOrient();
+                if( HORI_FULL == rHOri.GetHoriOrient() ||
+                    (HORI_LEFT == rHOri.GetHoriOrient() && aLR.GetLeft()) ||
+                    (HORI_RIGHT == rHOri.GetHoriOrient() && aLR.GetRight()))
+                {
+                    SwFmtHoriOrient aHOri( rHOri );
+                    aHOri.SetHoriOrient( HORI_NONE );
+                    GetFrmFmt()->SetAttr( aHOri );
+
+                    // sollte die Tabelle noch auf relativen Werten
+                    // (USHRT_MAX) stehen dann muss es jetzt auf absolute
+                    // umgerechnet werden. Bug 61494
+                    if( GetFrmFmt()->GetDoc()->IsBrowseMode() &&
+                        !rSz.GetWidthPercent() )
+                    {
+                        SwTabFrm* pTabFrm = (SwTabFrm*)SwClientIter(
+                                    *GetFrmFmt() ).First( TYPE( SwTabFrm ));
+                        if( pTabFrm &&
+                            pTabFrm->Prt().Width() != rSz.GetWidth() )
+                        {
+                            nFrmWidth = pTabFrm->Prt().Width();
+                            if( bBigger )
+                                nFrmWidth += nAbsDiff;
+                            else
+                                nFrmWidth -= nAbsDiff;
+                        }
+                    }
+                }
+
+                if( bBigger )
+                    aSz.SetWidth( aSz.GetWidth() + nRelDiff );
+                else
+                    aSz.SetWidth( aSz.GetWidth() - nRelDiff );
+
+                if( rSz.GetWidthPercent() )
+                    aSz.SetWidthPercent( ( aSz.GetWidth() * 100 ) /
+                        ( aSz.GetWidth() + aLR.GetRight() + aLR.GetLeft()));
+
+                GetFrmFmt()->SetAttr( aSz );
+                aParam.nTblWidth = USHORT( aSz.GetWidth() );
+
+                UnlockModify();
+
+                for( n = aLines.Count(); n; )
+                {
+                    --n;
+                    aParam.LoopClear();
+                    (*fnSelBox)( aLines[ n ], aParam, nDistStt, FALSE );
+                }
+
+                // sollte die Tabelle noch auf relativen Werten
+                // (USHRT_MAX) stehen dann muss es jetzt auf absolute
+                // umgerechnet werden. Bug 61494
+                if( LONG_MAX != nFrmWidth )
+                {
+                    SwFmtFrmSize aAbsSz( aSz );
+                    aAbsSz.SetWidth( nFrmWidth );
+                    GetFrmFmt()->SetAttr( aAbsSz );
+                }
+            }
+        }
+        else if( bInsDel ||
+                ( bLeft ? nDist : Abs( rSz.GetWidth() - nDist ) > COLFUZZY ) )
+        {
+            bRet = TRUE;
+            if( bLeft && TBLFIX_CHGABS == eTblChgMode && !bInsDel )
+                aParam.bBigger = !bBigger;
+
+            // erstmal testen, ob ueberhaupt Platz ist
+            if( bInsDel )
+            {
+                if( aParam.bBigger )
+                {
+                    for( n = 0; n < aLines.Count(); ++n )
+                    {
+                        aParam.LoopClear();
+                        if( !(*fnSelBox)( aLines[ n ], aParam, nDistStt, TRUE ))
+                        {
+                            bRet = FALSE;
+                            break;
+                        }
+                    }
+                }
+                else
+                {
+                    if( 0 != ( bRet = bLeft ? nDist
+                                            : ( rSz.GetWidth() - nDist )
+                        > COLFUZZY ) )
+                    {
+                        for( n = 0; n < aLines.Count(); ++n )
+                        {
+                            aParam.LoopClear();
+                            if( !(*fnOtherBox)( aLines[ n ], aParam, 0, TRUE ))
+                            {
+                                bRet = FALSE;
+                                break;
+                            }
+                        }
+                        if( bRet && !aParam.bAnyBoxFnd )
+                            bRet = FALSE;
+                    }
+
+                    if( !bRet && rAktBox.GetFrmFmt()->GetFrmSize().GetWidth()
+                        - nRelDiff > COLFUZZY +
+                            ( 567 / 2 /* min. 0,5 cm Platz lassen*/) )
+                    {
+                        // dann den Platz von der akt. Zelle nehmen
+                        aParam.bSplittBox = TRUE;
+                        // aber das muss auch mal getestet werden!
+                        bRet = TRUE;
+
+                        for( n = 0; n < aLines.Count(); ++n )
+                        {
+                            aParam.LoopClear();
+                            if( !(*fnSelBox)( aLines[ n ], aParam, nDistStt, TRUE ))
+                            {
+                                bRet = FALSE;
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+            else if( aParam.bBigger )
+            {
+                for( n = 0; n < aLines.Count(); ++n )
+                {
+                    aParam.LoopClear();
+                    if( !(*fnOtherBox)( aLines[ n ], aParam, 0, TRUE ))
+                    {
+                        bRet = FALSE;
+                        break;
+                    }
+                }
+            }
+            else
+            {
+                for( n = 0; n < aLines.Count(); ++n )
+                {
+                    aParam.LoopClear();
+                    if( !(*fnSelBox)( aLines[ n ], aParam, nDistStt, TRUE ))
+                    {
+                        bRet = FALSE;
+                        break;
+                    }
+                }
+            }
+
+            // wenn ja, dann setzen
+            if( bRet )
+            {
+                CR_SetBoxWidth aParam1( aParam );
+                if( bInsDel )
+                {
+                    aParam1.bBigger = !aParam.bBigger;
+                    pFndBox = ::lcl_SaveInsDelData( aParam, ppUndo,
+                                                    aTmpLst, nDistStt );
+                    if( ppUndo )
+                        *ppUndo = aParam.CreateUndo(
+                                        aParam.bBigger ? UNDO_TABLE_DELBOX
+                                                       : UNDO_TABLE_INSCOL );
+                }
+                else if( ppUndo )
+                    *ppUndo = new SwUndoAttrTbl( *aParam.pTblNd, TRUE );
+
+                if( bInsDel
+                    ? ( TBLFIX_CHGABS == eTblChgMode ? bLeft : bLeft )
+                    : ( TBLFIX_CHGABS != eTblChgMode && bLeft ) )
+                {
+                    for( n = aLines.Count(); n; )
+                    {
+                        --n;
+                        aParam.LoopClear();
+                        aParam1.LoopClear();
+                        (*fnSelBox)( aLines[ n ], aParam, nDistStt, FALSE );
+                        (*fnOtherBox)( aLines[ n ], aParam1, nDistStt, FALSE );
+                    }
+                }
+                else
+                    for( n = aLines.Count(); n; )
+                    {
+                        --n;
+                        aParam.LoopClear();
+                        aParam1.LoopClear();
+                        (*fnOtherBox)( aLines[ n ], aParam1, nDistStt, FALSE );
+                        (*fnSelBox)( aLines[ n ], aParam, nDistStt, FALSE );
+                    }
+            }
+        }
+        break;
+
+    case WH_CELL_RIGHT:
+    case WH_CELL_LEFT:
+        if( TBLVAR_CHGABS == eTblChgMode )
+        {
+            // dann sich selbst rekursiv aufrufen; nur mit
+            // einem anderen Mode -> Nachbarn
+            TblChgMode eOld = eTblChgMode;
+            eTblChgMode = TBLFIX_CHGABS;
+
+            bRet = SetColWidth( rAktBox, eType, nAbsDiff, nRelDiff,
+                                ppUndo );
+            eTblChgMode = eOld;
+            return bRet;
+        }
+        else if( bInsDel || ( bLeft ? nDist
+                                    : (rSz.GetWidth() - nDist) > COLFUZZY ))
+        {
+            if( bLeft && TBLFIX_CHGABS == eTblChgMode && !bInsDel )
+                aParam.bBigger = !bBigger;
+
+            // erstmal testen, ob ueberhaupt Platz ist
+            SwTableBox* pBox = &rAktBox;
+            SwTableLine* pLine = rAktBox.GetUpper();
+            while( pLine->GetUpper() )
+            {
+                USHORT nPos = pLine->GetTabBoxes().C40_GETPOS( SwTableBox, pBox );
+                if( bLeft ? nPos : nPos + 1 != pLine->GetTabBoxes().Count() )
+                    break;
+
+                pBox = pLine->GetUpper();
+                pLine = pBox->GetUpper();
+            }
+
+            if( pLine->GetUpper() )
+            {
+                // dann muss die Distanz wieder korriegiert werden!
+                aParam.nSide -= ::lcl_GetDistance( pLine->GetUpper(), TRUE );
+
+                if( bLeft )
+                    aParam.nMaxSize = aParam.nSide;
+                else
+                    aParam.nMaxSize = pLine->GetUpper()->GetFrmFmt()->
+                                    GetFrmSize().GetWidth() - aParam.nSide;
+            }
+
+            // erstmal testen, ob ueberhaupt Platz ist
+            if( bInsDel )
+            {
+                if( 0 != ( bRet = bLeft ? nDist
+                                : ( rSz.GetWidth() - nDist ) > COLFUZZY ) &&
+                    !aParam.bBigger )
+                {
+                    bRet = (*fnOtherBox)( pLine, aParam, 0, TRUE );
+                    if( bRet && !aParam.bAnyBoxFnd )
+                        bRet = FALSE;
+                }
+
+                if( !bRet && !aParam.bBigger && rAktBox.GetFrmFmt()->
+                    GetFrmSize().GetWidth() - nRelDiff > COLFUZZY +
+                        ( 567 / 2 /* min. 0,5 cm Platz lassen*/) )
+                {
+                    // dann den Platz von der akt. Zelle nehmen
+                    aParam.bSplittBox = TRUE;
+                    bRet = TRUE;
+                }
+            }
+            else
+            {
+                FN_lcl_SetBoxWidth fnTmp = aParam.bBigger ? fnOtherBox : fnSelBox;
+                bRet = (*fnTmp)( pLine, aParam, nDistStt, TRUE );
+            }
+
+            // wenn ja, dann setzen
+            if( bRet )
+            {
+                CR_SetBoxWidth aParam1( aParam );
+                if( bInsDel )
+                {
+                    aParam1.bBigger = !aParam.bBigger;
+                    pFndBox = ::lcl_SaveInsDelData( aParam, ppUndo, aTmpLst, nDistStt );
+                    if( ppUndo )
+                        *ppUndo = aParam.CreateUndo(
+                                        aParam.bBigger ? UNDO_TABLE_DELBOX
+                                                       : UNDO_TABLE_INSCOL );
+                }
+                else if( ppUndo )
+                    *ppUndo = new SwUndoAttrTbl( *aParam.pTblNd, TRUE );
+
+                if( bInsDel
+                    ? ( TBLFIX_CHGABS == eTblChgMode ? (bBigger && bLeft) : bLeft )
+                    : ( TBLFIX_CHGABS != eTblChgMode && bLeft ) )
+                {
+                    (*fnSelBox)( pLine, aParam, nDistStt, FALSE );
+                    (*fnOtherBox)( pLine, aParam1, nDistStt, FALSE );
+                }
+                else
+                {
+                    (*fnOtherBox)( pLine, aParam1, nDistStt, FALSE );
+                    (*fnSelBox)( pLine, aParam, nDistStt, FALSE );
+                }
+            }
+        }
+        break;
+
+    }
+
+    if( pFndBox )
+    {
+        // dann raeume die Struktur aller Lines auf
+        GCLines();
+
+        //Layout updaten
+        if( !bBigger || pFndBox->AreLinesToRestore( *this ) )
+            pFndBox->MakeFrms( *this );
+        pFndBox->RestoreChartData( *this );
+        delete pFndBox;
+
+        if( ppUndo && *ppUndo )
+        {
+            aParam.pUndo->SetColWidthParam( nBoxIdx, eTblChgMode, eType,
+                                            nAbsDiff, nRelDiff );
+            if( !aParam.bBigger )
+                aParam.pUndo->SaveNewBoxes( *aParam.pTblNd, aTmpLst );
+        }
+    }
+
+    if( bRet )
+    {
+        CHECKBOXWIDTH
+    }
+
+    return bRet;
+}
+#pragma optimize( "", on )
+
+/*  */
+
+SwRowFrm* GetRowFrm( SwTableLine& rLine )
+{
+    SwClientIter aIter( *rLine.GetFrmFmt() );
+    for( SwClient* pFrm = aIter.First( TYPE( SwRowFrm )); pFrm;
+            pFrm = aIter.Next() )
+        if( ((SwRowFrm*)pFrm)->GetTabLine() == &rLine )
+            return (SwRowFrm*)pFrm;
+    return 0;
+}
+
+_FndBox* lcl_SaveInsDelData( CR_SetLineHeight& rParam, SwUndo** ppUndo,
+                                SwTableSortBoxes& rTmpLst )
+{
+    // suche alle Boxen / Lines
+    SwTable& rTbl = rParam.pTblNd->GetTable();
+
+    ASSERT( rParam.aBoxes.Count(), "ohne Boxen ist nichts zu machen!" );
+
+    // loeschen der gesamten Tabelle verhindern
+    if( !rParam.bBigger && rParam.aBoxes.Count() ==
+        rTbl.GetTabSortBoxes().Count() )
+        return 0;
+
+    _FndBox* pFndBox = new _FndBox( 0, 0 );
+    if( !rParam.bBigger )
+        pFndBox->SetTableLines( rParam.aBoxes, rTbl );
+    else
+    {
+        _FndPara aPara( rParam.aBoxes, pFndBox );
+        rTbl.GetTabLines().ForEach( &_FndLineCopyCol, &aPara );
+        ASSERT( pFndBox->GetLines().Count(), "Wo sind die Boxen" );
+        pFndBox->SetTableLines( rTbl );
+
+        if( ppUndo )
+            rTmpLst.Insert( &rTbl.GetTabSortBoxes(), 0, rTbl.GetTabSortBoxes().Count() );
+    }
+
+    //Lines fuer das Layout-Update heraussuchen.
+    pFndBox->DelFrms( rTbl );
+    pFndBox->SaveChartData( rTbl );
+
+    return pFndBox;
+}
+
+void SetLineHeight( SwTableLine& rLine, SwTwips nOldHeight, SwTwips nNewHeight,
+                    BOOL bMinSize )
+{
+    SwLayoutFrm* pLineFrm = GetRowFrm( rLine );
+    ASSERT( pLineFrm, "wo ist der Frm von der SwTableLine?" );
+
+    SwFrmFmt* pFmt = rLine.ClaimFrmFmt();
+
+    SwTwips nMyNewH, nMyOldH = pLineFrm->Frm().Height();
+    if( !nOldHeight )                       // die BaseLine und absolut
+        nMyNewH = nMyOldH + nNewHeight;
+    else
+    {
+        // moeglichst genau rechnen
+        Fraction aTmp( nMyOldH );
+        aTmp *= Fraction( nNewHeight, nOldHeight );
+        aTmp += Fraction( 1, 2 );       // ggfs. aufrunden
+        nMyNewH = aTmp;
+    }
+
+    SwFrmSize eSize = ATT_MIN_SIZE;
+    if( !bMinSize &&
+        nMyOldH - nMyNewH > CalcRowRstHeight( pLineFrm ) )
+        eSize = ATT_FIX_SIZE;
+
+    pFmt->SetAttr( SwFmtFrmSize( eSize, 0, nMyNewH ) );
+
+    // erst alle inneren anpassen
+    SwTableBoxes& rBoxes = rLine.GetTabBoxes();
+    for( USHORT n = 0; n < rBoxes.Count(); ++n )
+    {
+        SwTableBox& rBox = *rBoxes[ n ];
+        for( USHORT i = 0; i < rBox.GetTabLines().Count(); ++i )
+            SetLineHeight( *rBox.GetTabLines()[ i ], nMyOldH, nMyNewH, bMinSize );
+    }
+}
+
+BOOL lcl_SetSelLineHeight( SwTableLine* pLine, CR_SetLineHeight& rParam,
+                             SwTwips nDist, BOOL bCheck )
+{
+    BOOL bRet = TRUE;
+    if( !bCheck )
+    {
+        // Zeilenhoehe einstellen
+        SetLineHeight( *pLine, 0, rParam.bBigger ? nDist : -nDist,
+                        rParam.bBigger );
+    }
+    else if( !rParam.bBigger )
+    {
+        // anhand der alten Size die neue relative errechnen
+        SwLayoutFrm* pLineFrm = GetRowFrm( *pLine );
+        ASSERT( pLineFrm, "wo ist der Frm von der SwTableLine?" );
+        SwTwips nRstHeight = CalcRowRstHeight( pLineFrm );
+        if( nRstHeight < nDist )
+            bRet = FALSE;
+    }
+    return bRet;
+}
+
+BOOL lcl_SetOtherLineHeight( SwTableLine* pLine, CR_SetLineHeight& rParam,
+                                SwTwips nDist, BOOL bCheck )
+{
+    BOOL bRet = TRUE;
+    if( bCheck )
+    {
+        if( rParam.bBigger )
+        {
+            // anhand der alten Size die neue relative errechnen
+            SwLayoutFrm* pLineFrm = GetRowFrm( *pLine );
+            ASSERT( pLineFrm, "wo ist der Frm von der SwTableLine?" );
+
+            if( TBLFIX_CHGPROP == rParam.nMode )
+            {
+                nDist *= pLineFrm->Frm().Height();
+                nDist /= rParam.nMaxHeight;
+            }
+            bRet = nDist <= CalcRowRstHeight( pLineFrm );
+        }
+    }
+    else
+    {
+        // Zeilenhoehe einstellen
+        // pLine ist die nachfolgende / vorhergehende -> also anpassen
+        if( TBLFIX_CHGPROP == rParam.nMode )
+        {
+            SwLayoutFrm* pLineFrm = GetRowFrm( *pLine );
+            ASSERT( pLineFrm, "wo ist der Frm von der SwTableLine?" );
+
+            // aus der alten Size die neue relative errechnen
+            // Wird die selektierte Box groesser ueber den MaxSpace anpassen,
+            // sonst ueber die MaxHeight
+            if( 1 /*!rParam.bBigger*/ )
+            {
+                nDist *= pLineFrm->Frm().Height();
+                nDist /= rParam.nMaxHeight;
+            }
+            else
+            {
+                // aus der alten Size die neue relative errechnen
+                nDist *= CalcRowRstHeight( pLineFrm );
+                nDist /= rParam.nMaxSpace;
+            }
+        }
+        SetLineHeight( *pLine, 0, rParam.bBigger ? -nDist : nDist,
+                        !rParam.bBigger );
+    }
+    return bRet;
+}
+
+BOOL lcl_InsDelSelLine( SwTableLine* pLine, CR_SetLineHeight& rParam,
+                            SwTwips nDist, BOOL bCheck )
+{
+    BOOL bRet = TRUE;
+    if( !bCheck )
+    {
+        SwTableBoxes& rBoxes = pLine->GetTabBoxes();
+        SwDoc* pDoc = pLine->GetFrmFmt()->GetDoc();
+        if( !rParam.bBigger )
+        {
+            for( USHORT n = rBoxes.Count(); n; )
+                ::lcl_SaveUpperLowerBorder( rParam.pTblNd->GetTable(),
+                                                    *rBoxes[ --n ],
+                                                    rParam.aShareFmts );
+            for( n = rBoxes.Count(); n; )
+                ::_DeleteBox( rParam.pTblNd->GetTable(),
+                                    rBoxes[ --n ], rParam.pUndo, FALSE,
+                                    FALSE, &rParam.aShareFmts );
+        }
+        else
+        {
+            // Zeile einfuegen
+            SwTableLine* pNewLine = new SwTableLine( (SwTableLineFmt*)pLine->GetFrmFmt(),
+                                        rBoxes.Count(), pLine->GetUpper() );
+            SwTableLines* pLines;
+            if( pLine->GetUpper() )
+                pLines = &pLine->GetUpper()->GetTabLines();
+            else
+                pLines = &rParam.pTblNd->GetTable().GetTabLines();
+            USHORT nPos = pLines->C40_GETPOS( SwTableLine, pLine );
+            if( !rParam.bTop )
+                ++nPos;
+            pLines->C40_INSERT( SwTableLine, pNewLine, nPos );
+
+            SwFrmFmt* pNewFmt = pNewLine->ClaimFrmFmt();
+            pNewFmt->SetAttr( SwFmtFrmSize( ATT_MIN_SIZE, 0, nDist ) );
+
+            // und noch mal die Anzahl Boxen erzeugen
+            SwTableBoxes& rNewBoxes = pNewLine->GetTabBoxes();
+            for( USHORT n = 0; n < rBoxes.Count(); ++n )
+            {
+                SwTwips nWidth = 0;
+                SwTableBox* pOld = rBoxes[ n ];
+                if( !pOld->GetSttNd() )
+                {
+                    // keine normale "Content"-Box also auf die 1. naechste
+                    // Box zurueckfallen
+                    nWidth = pOld->GetFrmFmt()->GetFrmSize().GetWidth();
+                    while( !pOld->GetSttNd() )
+                        pOld = pOld->GetTabLines()[ 0 ]->GetTabBoxes()[ 0 ];
+                }
+                ::_InsTblBox( pDoc, rParam.pTblNd, pNewLine,
+                                    (SwTableBoxFmt*)pOld->GetFrmFmt(), pOld, n );
+
+                // Sonderbehandlung fuer Umrandung die Obere muss
+                // entfernt werden
+                const SvxBoxItem& rBoxItem = pOld->GetFrmFmt()->GetBox();
+                if( rBoxItem.GetTop() )
+                {
+                    SvxBoxItem aTmp( rBoxItem );
+                    aTmp.SetLine( 0, BOX_LINE_TOP );
+                    rParam.aShareFmts.SetAttr( rParam.bTop
+                                                ? *pOld
+                                                : *rNewBoxes[ n ], aTmp );
+                }
+
+                if( nWidth )
+                    rParam.aShareFmts.SetAttr( *rNewBoxes[ n ],
+                                SwFmtFrmSize( ATT_FIX_SIZE, nWidth, 0 ) );
+            }
+        }
+    }
+    else
+    {
+        // Boxen einsammeln!
+        SwTableBoxes& rBoxes = pLine->GetTabBoxes();
+        for( USHORT n = rBoxes.Count(); n; )
+        {
+            SwTableBox* pBox = rBoxes[ --n ];
+            if( pBox->GetFrmFmt()->GetProtect().IsCntntProtected() )
+                return FALSE;
+
+            if( pBox->GetSttNd() )
+                rParam.aBoxes.Insert( pBox );
+            else
+            {
+                for( USHORT i = pBox->GetTabLines().Count(); i; )
+                    lcl_InsDelSelLine( pBox->GetTabLines()[ --i ],
+                                        rParam, 0, TRUE );
+            }
+        }
+    }
+    return bRet;
+}
+
+BOOL SwTable::SetRowHeight( SwTableBox& rAktBox, USHORT eType,
+                        SwTwips nAbsDiff, SwTwips nRelDiff,SwUndo** ppUndo )
+{
+    SwTableLine* pLine = rAktBox.GetUpper();
+
+    SwTableLine* pBaseLine = pLine;
+    while( pBaseLine->GetUpper() )
+        pBaseLine = pBaseLine->GetUpper()->GetUpper();
+
+    _FndBox* pFndBox = 0;                   // fuers Einfuegen/Loeschen
+    SwTableSortBoxes aTmpLst( 0, 5 );       // fuers Undo
+    BOOL bBigger,
+        bRet = FALSE,
+        bTop = WH_ROW_TOP == ( eType & 0xff ) ||
+                WH_CELL_TOP == ( eType & 0xff ),
+        bInsDel = 0 != (eType & WH_FLAG_INSDEL );
+    USHORT n, nBaseLinePos = GetTabLines().C40_GETPOS( SwTableLine, pBaseLine );
+    ULONG nBoxIdx = rAktBox.GetSttIdx();
+
+    CR_SetLineHeight aParam( eType,
+                        (SwTableNode*)rAktBox.GetSttNd()->FindTableNode() );
+    bBigger = aParam.bBigger;
+
+    FN_lcl_SetLineHeight fnSelLine, fnOtherLine = lcl_SetOtherLineHeight;
+    if( bInsDel )
+        fnSelLine = lcl_InsDelSelLine;
+    else
+        fnSelLine = lcl_SetSelLineHeight;
+
+    SwTableLines* pLines = &aLines;
+
+    // wie kommt man an die Hoehen heran?
+    switch( eType & 0xff )
+    {
+    case WH_CELL_TOP:
+    case WH_CELL_BOTTOM:
+        if( pLine == pBaseLine )
+            break;  // dann geht es nicht!
+
+        // ist eine verschachtelte Line (Box!)
+        pLines = &pLine->GetUpper()->GetTabLines();
+        nBaseLinePos = pLines->C40_GETPOS( SwTableLine, pLine );
+        pBaseLine = pLine;
+        // kein break!
+
+    case WH_ROW_TOP:
+    case WH_ROW_BOTTOM:
+        {
+            if( bInsDel && !bBigger )       // um wieviel wird es Hoeher?
+            {
+                nAbsDiff = GetRowFrm( *pBaseLine )->Frm().Height();
+            }
+
+            if( TBLVAR_CHGABS == eTblChgMode )
+            {
+                // erstmal testen, ob ueberhaupt Platz ist
+                if( bBigger )
+                {
+                    bRet = TRUE;
+// was ist mit Top, was ist mit Tabelle im Rahmen oder in Kopf-/Fusszeile
+// mit fester Hoehe ??
+                    if( !bRet )
+                    {
+                        // dann sich selbst rekursiv aufrufen; nur mit
+                        // einem anderen Mode -> proprotional
+                        TblChgMode eOld = eTblChgMode;
+                        eTblChgMode = TBLFIX_CHGPROP;
+
+                        bRet = SetRowHeight( rAktBox, eType, nAbsDiff,
+                                            nRelDiff, ppUndo );
+
+                        eTblChgMode = eOld;
+                        return bRet;
+                    }
+                }
+                else
+                    bRet = (*fnSelLine)( (*pLines)[ nBaseLinePos ], aParam,
+                                        nAbsDiff, TRUE );
+
+                if( bRet )
+                {
+                    if( bInsDel )
+                    {
+                        if( !aParam.aBoxes.Count() )
+                            ::lcl_InsDelSelLine( (*pLines)[ nBaseLinePos ],
+                                                    aParam, 0, TRUE );
+
+                        pFndBox = ::lcl_SaveInsDelData( aParam, ppUndo, aTmpLst );
+                        if( ppUndo )
+                            *ppUndo = aParam.CreateUndo(
+                                        bBigger ? UNDO_TABLE_INSROW
+                                                : UNDO_TABLE_DELBOX );
+                    }
+                    else if( ppUndo )
+                        *ppUndo = new SwUndoAttrTbl( *aParam.pTblNd, TRUE );
+
+                    (*fnSelLine)( (*pLines)[ nBaseLinePos ], aParam,
+                                    nAbsDiff, FALSE );
+                }
+            }
+            else
+            {
+                bRet = TRUE;
+                USHORT nStt, nEnd;
+                if( bTop )
+                    nStt = 0, nEnd = nBaseLinePos;
+                else
+                    nStt = nBaseLinePos + 1, nEnd = pLines->Count();
+
+                // die akt. Hoehe der Lines besorgen
+                if( TBLFIX_CHGPROP == eTblChgMode )
+                {
+                    for( n = nStt; n < nEnd; ++n )
+                    {
+                        SwLayoutFrm* pLineFrm = GetRowFrm( *(*pLines)[ n ] );
+                        ASSERT( pLineFrm, "wo ist der Frm von der SwTableLine?" );
+                        aParam.nMaxSpace += CalcRowRstHeight( pLineFrm );
+                        aParam.nMaxHeight += pLineFrm->Frm().Height();
+                    }
+                    if( bBigger && aParam.nMaxSpace < nAbsDiff )
+                        bRet = FALSE;
+                }
+                else
+                {
+                    if( bTop ? nEnd : nStt < nEnd  )
+                    {
+                        if( bTop )
+                            nStt = nEnd - 1;
+                        else
+                            nEnd = nStt + 1;
+                    }
+                    else
+                        bRet = FALSE;
+                }
+
+                if( bRet )
+                {
+                    if( bBigger )
+                    {
+                        for( n = nStt; n < nEnd; ++n )
+                        {
+                            if( !(*fnOtherLine)( (*pLines)[ n ], aParam,
+                                                    nAbsDiff, TRUE ))
+                            {
+                                bRet = FALSE;
+                                break;
+                            }
+                        }
+                    }
+                    else
+                        bRet = (*fnSelLine)( (*pLines)[ nBaseLinePos ], aParam,
+                                                nAbsDiff, TRUE );
+                }
+
+                if( bRet )
+                {
+                    // dann mal anpassen
+                    if( bInsDel )
+                    {
+                        if( !aParam.aBoxes.Count() )
+                            ::lcl_InsDelSelLine( (*pLines)[ nBaseLinePos ],
+                                                    aParam, 0, TRUE );
+                        pFndBox = ::lcl_SaveInsDelData( aParam, ppUndo, aTmpLst );
+                        if( ppUndo )
+                            *ppUndo = aParam.CreateUndo(
+                                        bBigger ? UNDO_TABLE_INSROW
+                                                : UNDO_TABLE_DELBOX );
+                    }
+                    else if( ppUndo )
+                        *ppUndo = new SwUndoAttrTbl( *aParam.pTblNd, TRUE );
+
+                    CR_SetLineHeight aParam1( aParam );
+                    if( TBLFIX_CHGPROP == eTblChgMode && !bBigger &&
+                        !aParam.nMaxSpace )
+                    {
+                        // dann muss der gesamte Platz auf alle Lines
+                        // gleichmaessig verteilt werden. Dafuer wird die
+                        // Anzahl benoetigt
+                        aParam1.nLines = nEnd - nStt;
+                    }
+
+                    if( bTop )
+                    {
+                        (*fnSelLine)( (*pLines)[ nBaseLinePos ], aParam,
+                                        nAbsDiff, FALSE );
+                        for( n = nStt; n < nEnd; ++n )
+                            (*fnOtherLine)( (*pLines)[ n ], aParam1,
+                                            nAbsDiff, FALSE );
+                    }
+                    else
+                    {
+                        for( n = nStt; n < nEnd; ++n )
+                            (*fnOtherLine)( (*pLines)[ n ], aParam1,
+                                            nAbsDiff, FALSE );
+                        (*fnSelLine)( (*pLines)[ nBaseLinePos ], aParam,
+                                        nAbsDiff, FALSE );
+                    }
+                }
+                else
+                {
+                    // dann sich selbst rekursiv aufrufen; nur mit
+                    // einem anderen Mode -> proprotional
+                    TblChgMode eOld = eTblChgMode;
+                    eTblChgMode = TBLVAR_CHGABS;
+
+                    bRet = SetRowHeight( rAktBox, eType, nAbsDiff,
+                                        nRelDiff, ppUndo );
+
+                    eTblChgMode = eOld;
+                    pFndBox = 0;
+                }
+            }
+        }
+        break;
+    }
+
+    if( pFndBox )
+    {
+        // dann raeume die Struktur aller Lines auf
+        GCLines();
+
+        //Layout updaten
+        if( bBigger || pFndBox->AreLinesToRestore( *this ) )
+            pFndBox->MakeFrms( *this );
+        pFndBox->RestoreChartData( *this );
+        delete pFndBox;
+
+        if( ppUndo && *ppUndo )
+        {
+            aParam.pUndo->SetColWidthParam( nBoxIdx, eTblChgMode, eType,
+                                            nAbsDiff, nRelDiff );
+            if( bBigger )
+                aParam.pUndo->SaveNewBoxes( *aParam.pTblNd, aTmpLst );
+        }
+    }
+
+    return bRet;
+}
+
+/*  */
+
+SwFrmFmt* SwShareBoxFmt::GetFormat( long nWidth ) const
+{
+    SwFrmFmt *pRet = 0, *pTmp;
+    for( USHORT n = aNewFmts.Count(); n; )
+        if( ( pTmp = (SwFrmFmt*)aNewFmts[ --n ])->GetFrmSize().GetWidth()
+                == nWidth )
+        {
+            pRet = pTmp;
+            break;
+        }
+    return pRet;
+}
+
+SwFrmFmt* SwShareBoxFmt::GetFormat( const SfxPoolItem& rItem ) const
+{
+    const SfxPoolItem* pItem;
+    USHORT nWhich = rItem.Which();
+    SwFrmFmt *pRet = 0, *pTmp;
+    const SfxPoolItem& rFrmSz = pOldFmt->GetAttr( RES_FRM_SIZE, FALSE );
+    for( USHORT n = aNewFmts.Count(); n; )
+        if( SFX_ITEM_SET == ( pTmp = (SwFrmFmt*)aNewFmts[ --n ])->
+            GetItemState( nWhich, FALSE, &pItem ) && *pItem == rItem &&
+            pTmp->GetAttr( RES_FRM_SIZE, FALSE ) == rFrmSz )
+        {
+            pRet = pTmp;
+            break;
+        }
+    return pRet;
+}
+
+void SwShareBoxFmt::AddFormat( const SwFrmFmt& rNew )
+{
+    void* pFmt = (void*)&rNew;
+    aNewFmts.Insert( pFmt, aNewFmts.Count() );
+}
+
+FASTBOOL SwShareBoxFmt::RemoveFormat( const SwFrmFmt& rFmt )
+{
+    // returnt TRUE, wenn geloescht werden kann
+    if( pOldFmt == &rFmt )
+        return TRUE;
+
+    void* p = (void*)&rFmt;
+    USHORT nFnd = aNewFmts.GetPos( p );
+    if( USHRT_MAX != nFnd )
+        aNewFmts.Remove( nFnd );
+    return 0 == aNewFmts.Count();
+}
+
+SwShareBoxFmts::~SwShareBoxFmts()
+{
+}
+
+SwFrmFmt* SwShareBoxFmts::GetFormat( const SwFrmFmt& rFmt, long nWidth ) const
+{
+    USHORT nPos;
+    return Seek_Entry( rFmt, &nPos )
+                    ? aShareArr[ nPos ]->GetFormat( nWidth )
+                    : 0;
+}
+SwFrmFmt* SwShareBoxFmts::GetFormat( const SwFrmFmt& rFmt,
+                                     const SfxPoolItem& rItem ) const
+{
+    USHORT nPos;
+    return Seek_Entry( rFmt, &nPos )
+                    ? aShareArr[ nPos ]->GetFormat( rItem )
+                    : 0;
+}
+
+void SwShareBoxFmts::AddFormat( const SwFrmFmt& rOld, const SwFrmFmt& rNew )
+{
+    // wenn das Format nicht geshared ist, braucht es auch nicht in die
+    // Liste aufgenommen werden. Denn es gibt keinen 2. der es sucht.
+//leider werden auch die CellFrms gefunden
+//  if( !rOld.IsLastDepend() )
+    {
+        USHORT nPos;
+        SwShareBoxFmt* pEntry;
+        if( !Seek_Entry( rOld, &nPos ))
+        {
+            pEntry = new SwShareBoxFmt( rOld );
+            aShareArr.C40_INSERT( SwShareBoxFmt, pEntry, nPos );
+        }
+        else
+            pEntry = aShareArr[ nPos ];
+
+        pEntry->AddFormat( rNew );
+    }
+}
+void SwShareBoxFmts::ChangeFrmFmt( SwTableBox* pBox, SwTableLine* pLn,
+                                    SwFrmFmt& rFmt )
+{
+    SwClient aCl;
+    SwFrmFmt* pOld = 0;
+    if( pBox )
+    {
+        pOld = pBox->GetFrmFmt();
+        pOld->Add( &aCl );
+        pBox->ChgFrmFmt( (SwTableBoxFmt*)&rFmt );
+    }
+    else if( pLn )
+    {
+        pOld = pLn->GetFrmFmt();
+        pOld->Add( &aCl );
+        pLn->ChgFrmFmt( (SwTableLineFmt*)&rFmt );
+    }
+    if( pOld && pOld->IsLastDepend() )
+    {
+        RemoveFormat( *pOld );
+        delete pOld;
+    }
+}
+
+void SwShareBoxFmts::SetSize( SwTableBox& rBox, const SwFmtFrmSize& rSz )
+{
+    SwFrmFmt *pBoxFmt = rBox.GetFrmFmt(),
+             *pRet = GetFormat( *pBoxFmt, rSz.GetWidth() );
+    if( pRet )
+        ChangeFrmFmt( &rBox, 0, *pRet );
+    else
+    {
+        pRet = rBox.ClaimFrmFmt();
+        pRet->SetAttr( rSz );
+        AddFormat( *pBoxFmt, *pRet );
+    }
+}
+
+void SwShareBoxFmts::SetAttr( SwTableBox& rBox, const SfxPoolItem& rItem )
+{
+    SwFrmFmt *pBoxFmt = rBox.GetFrmFmt(),
+             *pRet = GetFormat( *pBoxFmt, rItem );
+    if( pRet )
+        ChangeFrmFmt( &rBox, 0, *pRet );
+    else
+    {
+        pRet = rBox.ClaimFrmFmt();
+        pRet->SetAttr( rItem );
+        AddFormat( *pBoxFmt, *pRet );
+    }
+}
+
+void SwShareBoxFmts::SetAttr( SwTableLine& rLine, const SfxPoolItem& rItem )
+{
+    SwFrmFmt *pLineFmt = rLine.GetFrmFmt(),
+             *pRet = GetFormat( *pLineFmt, rItem );
+    if( pRet )
+        ChangeFrmFmt( 0, &rLine, *pRet );
+    else
+    {
+        pRet = rLine.ClaimFrmFmt();
+        pRet->SetAttr( rItem );
+        AddFormat( *pLineFmt, *pRet );
+    }
+}
+
+void SwShareBoxFmts::RemoveFormat( const SwFrmFmt& rFmt )
+{
+    for( USHORT i = aShareArr.Count(); i; )
+        if( aShareArr[ --i ]->RemoveFormat( rFmt ))
+            aShareArr.DeleteAndDestroy( i );
+}
+
+BOOL SwShareBoxFmts::Seek_Entry( const SwFrmFmt& rFmt, USHORT* pPos ) const
+{
+    ULONG nIdx = (ULONG)&rFmt;
+    register USHORT nO = aShareArr.Count(), nM, nU = 0;
+    if( nO > 0 )
+    {
+        nO--;
+        while( nU <= nO )
+        {
+            nM = nU + ( nO - nU ) / 2;
+            ULONG nFmt = (ULONG)&aShareArr[ nM ]->GetOldFormat();
+            if( nFmt == nIdx )
+            {
+                if( pPos )
+                    *pPos = nM;
+                return TRUE;
+            }
+            else if( nFmt < nIdx )
+                nU = nM + 1;
+            else if( nM == 0 )
+            {
+                if( pPos )
+                    *pPos = nU;
+                return FALSE;
+            }
+            else
+                nO = nM - 1;
+        }
+    }
+    if( pPos )
+        *pPos = nU;
+    return FALSE;
+}
+
+
diff --git a/sw/source/core/doc/visiturl.cxx b/sw/source/core/doc/visiturl.cxx
new file mode 100644
index 000000000000..27d314c3789b
--- /dev/null
+++ b/sw/source/core/doc/visiturl.cxx
@@ -0,0 +1,201 @@
+/*************************************************************************
+ *
+ *  $RCSfile: visiturl.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:16 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+
+#ifndef _SFXDOCFILE_HXX //autogen
+#include 
+#endif
+#ifndef _INETHIST_HXX //autogen
+#include 
+#endif
+#ifndef _URLOBJ_HXX //autogen
+#include 
+#endif
+
+#ifndef _FMTINFMT_HXX //autogen
+#include 
+#endif
+#ifndef _TXTINET_HXX //autogen
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _VISITURL_HXX
+#include 
+#endif
+#ifndef _HINTS_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _EDITSH_HXX
+#include 
+#endif
+#ifndef _DOCSH_HXX
+#include 
+#endif
+
+
+SwURLStateChanged::SwURLStateChanged( const SwDoc* pD )
+    : pDoc( pD )
+{
+    StartListening( *INetURLHistory::GetOrCreate() );
+}
+
+SwURLStateChanged::~SwURLStateChanged()
+{
+    EndListening( *INetURLHistory::GetOrCreate() );
+}
+
+void SwURLStateChanged::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+    if( rHint.ISA( INetURLHistoryHint ) && pDoc->GetRootFrm() )
+    {
+        // diese URL wurde veraendert:
+        const INetURLObject* pIURL = ((INetURLHistoryHint&)rHint).GetObject();
+        String sURL( pIURL->GetMainURL() ), sBkmk;
+
+        SwEditShell* pESh = pDoc->GetEditShell();
+
+        if( pDoc->GetDocShell() && pDoc->GetDocShell()->GetMedium() &&
+            // falls das unser Doc ist, kann es auch lokale Spruenge geben!
+            sURL == pDoc->GetDocShell()->GetMedium()->GetName() )
+            (sBkmk = pIURL->GetMark()).Insert( INET_MARK_TOKEN, 0 );
+
+        BOOL bAction = FALSE, bUnLockView = FALSE;
+        const SwFmtINetFmt* pItem;
+        const SwTxtINetFmt* pTxtAttr;
+        const SwTxtNode* pTxtNd;
+        USHORT n, nMaxItems = pDoc->GetAttrPool().GetItemCount( RES_TXTATR_INETFMT );
+        for( n = 0; n < nMaxItems; ++n )
+            if( 0 != (pItem = (SwFmtINetFmt*)pDoc->GetAttrPool().GetItem(
+                RES_TXTATR_INETFMT, n ) ) &&
+                ( pItem->GetValue() == sURL ||
+                    ( sBkmk.Len() && pItem->GetValue() == sBkmk )) &&
+                0 != ( pTxtAttr = pItem->GetTxtINetFmt()) &&
+                0 != ( pTxtNd = pTxtAttr->GetpTxtNode() ) )
+            {
+                if( !bAction && pESh )
+                {
+                    pESh->StartAllAction();
+                    bAction = TRUE;
+                    bUnLockView = !pESh->IsViewLocked();
+                    pESh->LockView( TRUE );
+                }
+                ((SwTxtINetFmt*)pTxtAttr)->SetValidVis( FALSE );
+                const SwTxtAttr* pAttr = pTxtAttr;
+                SwUpdateAttr aUpdateAttr( *pAttr->GetStart(),
+                                          *pAttr->GetEnd(),
+                                          RES_FMT_CHG );
+                ((SwTxtNode*)pTxtNd)->SwCntntNode::Modify( &aUpdateAttr,
+                                                            &aUpdateAttr );
+            }
+
+        if( bAction )
+            pESh->EndAllAction();
+         if( bUnLockView )
+             pESh->LockView( FALSE );
+    }
+}
+
+    // erfrage ob die URL besucht war. Uebers Doc, falls nur ein Bookmark
+    // angegeben ist. Dann muss der Doc. Name davor gesetzt werden!
+BOOL SwDoc::IsVisitedURL( const String& rURL ) const
+{
+#ifdef DEBUG
+    static long nTmp = 0;
+    ++nTmp;
+#endif
+
+    BOOL bRet = FALSE;
+    if( rURL.Len() )
+    {
+        INetURLHistory *pHist = INetURLHistory::GetOrCreate();
+        if( '#' == rURL.GetChar( 0 ) && pDocShell && pDocShell->GetMedium() )
+        {
+            INetURLObject aIObj( pDocShell->GetMedium()->GetURLObject() );
+            aIObj.SetMark( rURL.Copy( 1 ) );
+            bRet = pHist->QueryUrl( aIObj );
+        }
+        else
+            bRet = pHist->QueryUrl( rURL );
+
+        // dann  wollen wird auch ueber Statusaenderungen in der History
+        // informiert werden!
+        if( !pURLStateChgd )
+        {
+            SwDoc* pD = (SwDoc*)this;
+            pD->pURLStateChgd = new SwURLStateChanged( this );
+        }
+    }
+    return bRet;
+}
+
+
+
diff --git a/sw/source/core/docnode/makefile.mk b/sw/source/core/docnode/makefile.mk
new file mode 100644
index 000000000000..6ccba3864443
--- /dev/null
+++ b/sw/source/core/docnode/makefile.mk
@@ -0,0 +1,120 @@
+#*************************************************************************
+#
+#   $RCSfile: makefile.mk,v $
+#
+#   $Revision: 1.1.1.1 $
+#
+#   last change: $Author: hr $ $Date: 2000-09-19 00:08:17 $
+#
+#   The Contents of this file are made available subject to the terms of
+#   either of the following licenses
+#
+#          - GNU Lesser General Public License Version 2.1
+#          - Sun Industry Standards Source License Version 1.1
+#
+#   Sun Microsystems Inc., October, 2000
+#
+#   GNU Lesser General Public License Version 2.1
+#   =============================================
+#   Copyright 2000 by Sun Microsystems, Inc.
+#   901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+#   This library is free software; you can redistribute it and/or
+#   modify it under the terms of the GNU Lesser General Public
+#   License version 2.1, as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   Lesser General Public License for more details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+#   License along with this library; if not, write to the Free Software
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+#   MA  02111-1307  USA
+#
+#
+#   Sun Industry Standards Source License Version 1.1
+#   =================================================
+#   The contents of this file are subject to the Sun Industry Standards
+#   Source License Version 1.1 (the "License"); You may not use this file
+#   except in compliance with the License. You may obtain a copy of the
+#   License at http://www.openoffice.org/license.html.
+#
+#   Software provided under this License is provided on an "AS IS" basis,
+#   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+#   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+#   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+#   See the License for the specific provisions governing your rights and
+#   obligations concerning the Software.
+#
+#   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+#   Copyright: 2000 by Sun Microsystems, Inc.
+#
+#   All Rights Reserved.
+#
+#   Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sw
+TARGET=docnode
+
+AUTOSEG=true
+
+PROJECTPCH=core_pch
+PDBTARGET=core_pch
+PROJECTPCHSOURCE=..$/core_1st$/core_pch
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE :	$(PRJ)$/inc$/swpre.mk
+.INCLUDE :	settings.mk
+.INCLUDE :	$(PRJ)$/inc$/sw.mk
+
+.IF "$(GUI)$(COM)" == "WINMSC"
+LIBFLAGS=/NOI /NOE /PAGE:512
+.ENDIF
+
+
+# --- Files --------------------------------------------------------
+
+CXXFILES = \
+        ndindex.cxx \
+        ndcopy.cxx \
+        ndnotxt.cxx \
+        ndnum.cxx \
+        ndsect.cxx \
+        ndtbl.cxx \
+        ndtbl1.cxx \
+        node.cxx \
+        node2lay.cxx \
+        nodes.cxx \
+        section.cxx \
+        swbaslnk.cxx
+
+
+
+SLOFILES =	\
+        $(SLO)$/ndindex.obj \
+        $(SLO)$/ndcopy.obj \
+        $(SLO)$/ndnotxt.obj \
+        $(SLO)$/ndnum.obj \
+        $(SLO)$/ndsect.obj \
+        $(SLO)$/ndtbl.obj \
+        $(SLO)$/ndtbl1.obj \
+        $(SLO)$/node.obj \
+        $(SLO)$/node2lay.obj \
+        $(SLO)$/nodes.obj \
+        $(SLO)$/section.obj \
+        $(SLO)$/swbaslnk.obj
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE :	target.mk
+
diff --git a/sw/source/core/docnode/ndcopy.cxx b/sw/source/core/docnode/ndcopy.cxx
new file mode 100644
index 000000000000..c61ff4bcb3ed
--- /dev/null
+++ b/sw/source/core/docnode/ndcopy.cxx
@@ -0,0 +1,1260 @@
+/*************************************************************************
+ *
+ *  $RCSfile: ndcopy.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:17 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#define _ZFORLIST_DECLARE_TABLE
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+
+#ifndef _SVX_BRKITEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _FMTPDSC_HXX //autogen
+#include 
+#endif
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _FMTCNTNT_HXX //autogen
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _FMTCOL_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _FLDBAS_HXX
+#include 
+#endif
+#ifndef _SWTABLE_HXX
+#include 
+#endif
+#ifndef _DDEFLD_HXX
+#include 
+#endif
+#ifndef _UNDOBJ_HXX
+#include 
+#endif
+#ifndef _NUMRULE_HXX
+#include 
+#endif
+#ifndef _BOOKMRK_HXX
+#include 
+#endif
+#ifndef _MVSAVE_HXX
+#include 
+#endif
+#ifndef _CELLATR_HXX
+#include 
+#endif
+#ifndef _SWTBLFMT_HXX
+#include 
+#endif
+#ifndef _SWDDETBL_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _NDINDEX_HXX
+#include 
+#endif
+#ifndef _FMTCNCT_HXX
+#include 
+#endif
+#ifndef _REDLINE_HXX
+#include 
+#endif
+#ifndef _PARATR_HXX
+#include 
+#endif
+#ifndef _PAGEDESC_HXX
+#include 
+#endif
+#ifndef _POOLFMT_HXX
+#include 
+#endif
+
+
+// Struktur fuer das Mappen von alten und neuen Frame-Formaten an den
+// Boxen und Lines einer Tabelle
+
+struct _MapTblFrmFmt
+{
+    const SwFrmFmt *pOld, *pNew;
+    _MapTblFrmFmt( const SwFrmFmt *pOldFmt, const SwFrmFmt*pNewFmt )
+        : pOld( pOldFmt ), pNew( pNewFmt )
+    {}
+};
+
+SV_DECL_VARARR( _MapTblFrmFmts, _MapTblFrmFmt, 0, 10 );
+SV_IMPL_VARARR( _MapTblFrmFmts, _MapTblFrmFmt );
+
+SwCntntNode* SwTxtNode::MakeCopy( SwDoc* pDoc, const SwNodeIndex& rIdx ) const
+{
+    // the Copy-Textnode is the Node with the Text, the Copy-Attrnode is the
+    // node with the collection and hard attributes. Normally ist the same
+    // node, but if insert a glossary without formatting, then the Attrnode
+    // is the prev node of the destionation position in dest. document.
+    SwTxtNode* pCpyTxtNd = (SwTxtNode*)this;
+    SwTxtNode* pCpyAttrNd = pCpyTxtNd;
+
+    // kopiere die Formate in das andere Dokument:
+    SwTxtFmtColl* pColl = 0;
+    if( pDoc->IsInsOnlyTextGlossary() )
+    {
+        SwNodeIndex aIdx( rIdx, -1 );
+        if( aIdx.GetNode().IsTxtNode() )
+        {
+            pCpyAttrNd = aIdx.GetNode().GetTxtNode();
+            pColl = &pCpyAttrNd->GetTxtColl()->GetNextTxtFmtColl();
+        }
+    }
+    if( !pColl )
+        pColl = pDoc->CopyTxtColl( *GetTxtColl() );
+
+    SwTxtNode* pTxtNd = pDoc->GetNodes().MakeTxtNode( rIdx, pColl );
+
+    // kopiere Attribute/Text
+    if( !pCpyAttrNd->GetpSwAttrSet() )
+        // wurde ein AttrSet fuer die Numerierung angelegt, so loesche diesen!
+        pTxtNd->ResetAllAttr();
+
+    // if Copy-Textnode unequal to Copy-Attrnode, then copy first
+    // the attributes into the new Node.
+    if( pCpyAttrNd != pCpyTxtNd )
+    {
+        pCpyAttrNd->CopyAttr( pTxtNd, 0, 0 );
+        if( pCpyAttrNd->GetpSwAttrSet() )
+        {
+            SwAttrSet aSet( *pCpyAttrNd->GetpSwAttrSet() );
+            aSet.ClearItem( RES_PAGEDESC );
+            aSet.ClearItem( RES_BREAK );
+            aSet.CopyToModify( *pTxtNd );
+        }
+    }
+
+        // ??? reicht das ??? was ist mit PostIts/Feldern/FeldTypen ???
+    pCpyTxtNd->Copy( pTxtNd, SwIndex( pCpyTxtNd ), pCpyTxtNd->GetTxt().Len() );
+
+    if( pCpyAttrNd->GetNum() )
+        pTxtNd->UpdateNum( *pCpyAttrNd->GetNum() );
+
+//FEATURE::CONDCOLL
+    if( RES_CONDTXTFMTCOLL == pColl->Which() )
+        pTxtNd->ChkCondColl();
+//FEATURE::CONDCOLL
+
+    return pTxtNd;
+}
+
+
+BOOL lcl_SrchNew( const _MapTblFrmFmt& rMap, void * pPara )
+{
+    if( rMap.pOld != *(const SwFrmFmt**)pPara )
+        return TRUE;
+    *((const SwFrmFmt**)pPara) = rMap.pNew;
+    return FALSE;       // abbrechen, Pointer gefunden
+}
+
+
+struct _CopyTable
+{
+    SwDoc* pDoc;
+    ULONG nOldTblSttIdx;
+    _MapTblFrmFmts& rMapArr;
+    SwTableLine* pInsLine;
+    SwTableBox* pInsBox;
+    SwTableNode *pTblNd;
+    const SwTable *pOldTable;
+
+    _CopyTable( SwDoc* pDc, _MapTblFrmFmts& rArr, ULONG nOldStt,
+                SwTableNode& rTblNd, const SwTable* pOldTbl )
+        : pDoc(pDc), pTblNd(&rTblNd), nOldTblSttIdx(nOldStt),
+        rMapArr(rArr), pOldTable( pOldTbl ), pInsLine(0), pInsBox(0)
+    {}
+};
+
+BOOL lcl_CopyTblBox( const SwTableBox*& rpBox, void* pPara );
+
+BOOL lcl_CopyTblLine( const SwTableLine*& rpLine, void* pPara );
+
+BOOL lcl_CopyTblBox( const SwTableBox*& rpBox, void* pPara )
+{
+    _CopyTable* pCT = (_CopyTable*)pPara;
+
+    SwTableBoxFmt* pBoxFmt = (SwTableBoxFmt*)rpBox->GetFrmFmt();
+    pCT->rMapArr.ForEach( lcl_SrchNew, &pBoxFmt );
+    if( pBoxFmt == rpBox->GetFrmFmt() ) // ein neues anlegen ??
+    {
+        const SfxPoolItem* pItem;
+        if( SFX_ITEM_SET == pBoxFmt->GetItemState( RES_BOXATR_FORMULA, FALSE,
+            &pItem ) && ((SwTblBoxFormula*)pItem)->IsIntrnlName() )
+        {
+            ((SwTblBoxFormula*)pItem)->PtrToBoxNm( pCT->pOldTable );
+        }
+
+        pBoxFmt = pCT->pDoc->MakeTableBoxFmt();
+        pBoxFmt->CopyAttrs( *rpBox->GetFrmFmt() );
+
+        if( rpBox->GetSttIdx() )
+        {
+            SvNumberFormatter* pN = pCT->pDoc->GetNumberFormatter( FALSE );
+            if( pN && pN->HasMergeFmtTbl() && SFX_ITEM_SET == pBoxFmt->
+                GetItemState( RES_BOXATR_FORMAT, FALSE, &pItem ) )
+            {
+                ULONG nOldIdx = ((SwTblBoxNumFormat*)pItem)->GetValue();
+                ULONG nNewIdx = pN->GetMergeFmtIndex( nOldIdx );
+                if( nNewIdx != nOldIdx )
+                    pBoxFmt->SetAttr( SwTblBoxNumFormat( nNewIdx ));
+
+            }
+        }
+
+        pCT->rMapArr.Insert( _MapTblFrmFmt( rpBox->GetFrmFmt(), pBoxFmt ),
+                                pCT->rMapArr.Count() );
+    }
+
+    USHORT nLines = rpBox->GetTabLines().Count();
+    SwTableBox* pNewBox;
+    if( nLines )
+        pNewBox = new SwTableBox( pBoxFmt, nLines, pCT->pInsLine );
+    else
+    {
+        SwNodeIndex aNewIdx( *pCT->pTblNd,
+                            rpBox->GetSttIdx() - pCT->nOldTblSttIdx );
+        ASSERT( aNewIdx.GetNode().IsStartNode(), "Index nicht auf einem StartNode" );
+        pNewBox = new SwTableBox( pBoxFmt, aNewIdx, pCT->pInsLine );
+    }
+
+    pCT->pInsLine->GetTabBoxes().C40_INSERT( SwTableBox, pNewBox,
+                    pCT->pInsLine->GetTabBoxes().Count() );
+
+    if( nLines )
+    {
+        _CopyTable aPara( *pCT );
+        aPara.pInsBox = pNewBox;
+        ((SwTableBox*)rpBox)->GetTabLines().ForEach( &lcl_CopyTblLine, &aPara );
+    }
+    else if( pNewBox->IsInHeadline( &pCT->pTblNd->GetTable() ))
+        // in der HeadLine sind die Absaetze mit BedingtenVorlage anzupassen
+        pNewBox->GetSttNd()->CheckSectionCondColl();
+    return TRUE;
+}
+
+BOOL lcl_CopyTblLine( const SwTableLine*& rpLine, void* pPara )
+{
+    _CopyTable* pCT = (_CopyTable*)pPara;
+    SwTableLineFmt* pLineFmt = (SwTableLineFmt*)rpLine->GetFrmFmt();
+    pCT->rMapArr.ForEach( lcl_SrchNew, &pLineFmt );
+    if( pLineFmt == rpLine->GetFrmFmt() )   // ein neues anlegen ??
+    {
+        pLineFmt = pCT->pDoc->MakeTableLineFmt();
+        pLineFmt->CopyAttrs( *rpLine->GetFrmFmt() );
+        pCT->rMapArr.Insert( _MapTblFrmFmt( rpLine->GetFrmFmt(), pLineFmt ),
+                                pCT->rMapArr.Count());
+    }
+    SwTableLine* pNewLine = new SwTableLine( pLineFmt,
+                            rpLine->GetTabBoxes().Count(), pCT->pInsBox );
+    // die neue Zeile in die Tabelle eintragen
+    if( pCT->pInsBox )
+    {
+        pCT->pInsBox->GetTabLines().C40_INSERT( SwTableLine, pNewLine,
+                pCT->pInsBox->GetTabLines().Count() );
+    }
+    else
+    {
+        pCT->pTblNd->GetTable().GetTabLines().C40_INSERT( SwTableLine, pNewLine,
+                pCT->pTblNd->GetTable().GetTabLines().Count() );
+    }
+    pCT->pInsLine = pNewLine;
+    ((SwTableLine*)rpLine)->GetTabBoxes().ForEach( &lcl_CopyTblBox, pCT );
+    return TRUE;
+}
+
+SwTableNode* SwTableNode::MakeCopy( SwDoc* pDoc, const SwNodeIndex& rIdx ) const
+{
+    // in welchen Array steht ich denn Nodes, UndoNodes ??
+    SwNodes& rNds = (SwNodes&)GetNodes();
+
+    if( pDoc->IsIdxInTbl( rIdx ) )
+        // zur Zeit keine Tabelle in Tabelle kopieren unterstuetzen
+        // (sprich: Text + Tabelle + Text )
+        return 0;
+
+    {
+        // nicht in Fussnoten kopieren !!
+/*
+!! Mal ohne Frames
+        SwCntntNode* pCNd = pDoc->GetNodes()[ rIdx ]->GetCntntNode();
+        SwFrm* pFrm;
+        if( (pCNd && 0 != ( pFrm = pCNd->GetFrm()))
+                ? pFrm->FindFtnFrm()
+                : rIdx < pDoc->GetNodes().EndOfInserts &&
+                    pDoc->GetNodes()[pDoc->GetNodes().EndOfInserts]->StartOfSection()
+                    < rIdx )
+*/
+        if( rIdx < pDoc->GetNodes().GetEndOfInserts().GetIndex() &&
+            rIdx >= pDoc->GetNodes().GetEndOfInserts().StartOfSectionIndex() )
+            return 0;
+    }
+
+    // das TableFrmFmt kopieren
+    String sTblName( GetTable().GetFrmFmt()->GetName() );
+    if( !pDoc->IsCopyIsMove() )
+    {
+        const SwFrmFmts& rTblFmts = *pDoc->GetTblFrmFmts();
+        for( USHORT n = rTblFmts.Count(); n; )
+            if( rTblFmts[ --n ]->GetName() == sTblName )
+            {
+                sTblName = pDoc->GetUniqueTblName();
+                break;
+            }
+    }
+
+    SwFrmFmt* pTblFmt = pDoc->MakeTblFrmFmt( sTblName, pDoc->GetDfltFrmFmt() );
+    pTblFmt->CopyAttrs( *GetTable().GetFrmFmt() );
+    SwTableNode* pTblNd = new SwTableNode( rIdx );
+    SwEndNode* pEndNd = new SwEndNode( rIdx, *pTblNd );
+    SwNodeIndex aInsPos( *pEndNd );
+
+    SwTable& rTbl = (SwTable&)pTblNd->GetTable();
+    pTblFmt->Add( &rTbl );      // das Frame-Format setzen
+
+    rTbl.SetHeadlineRepeat( GetTable().IsHeadlineRepeat() );
+    rTbl.SetTblChgMode( GetTable().GetTblChgMode() );
+
+    SwDDEFieldType* pDDEType = 0;
+    if( IS_TYPE( SwDDETable, &GetTable() ))
+    {
+        // es wird eine DDE-Tabelle kopiert
+        // ist im neuen Dokument ueberhaupt der FeldTyp vorhanden ?
+        pDDEType = ((SwDDETable&)GetTable()).GetDDEFldType();
+        if( pDDEType->IsDeleted() )
+            pDoc->InsDeletedFldType( *pDDEType );
+        else
+            pDDEType = (SwDDEFieldType*)pDoc->InsertFldType( *pDDEType );
+        ASSERT( pDDEType, "unbekannter FieldType" );
+
+        // tauschen am Node den Tabellen-Pointer aus
+        SwDDETable* pNewTable = new SwDDETable( pTblNd->GetTable(), pDDEType );
+        pTblNd->SetNewTable( pNewTable, FALSE );
+    }
+    // dann kopiere erstmal den Inhalt der Tabelle, die Zuordnung der
+    // Boxen/Lines und das anlegen der Frames erfolgt spaeter
+    SwNodeRange aRg( *this, +1, *EndOfSectionNode() );  // (wo stehe in denn nun ??)
+    rNds._Copy( aRg, aInsPos, FALSE );
+
+    // Sonderbehandlung fuer eine einzelne Box
+    if( 1 == GetTable().GetTabSortBoxes().Count() )
+    {
+        aRg.aStart.Assign( *pTblNd, 1 );
+        aRg.aEnd.Assign( *pTblNd->EndOfSectionNode() );
+        pDoc->GetNodes().SectionDown( &aRg, SwTableBoxStartNode );
+    }
+
+    // loesche alle Frames vom kopierten Bereich, diese werden beim
+    // erzeugen des TableFrames angelegt !
+    pTblNd->DelFrms();
+
+    _MapTblFrmFmts aMapArr;
+    _CopyTable aPara( pDoc, aMapArr, GetIndex(), *pTblNd, &GetTable() );
+
+    ((SwTable&)GetTable()).GetTabLines().ForEach( &lcl_CopyTblLine, &aPara );
+
+    if( pDDEType && pDoc->GetRootFrm() )
+        pDDEType->IncRefCnt();
+
+    return pTblNd;
+}
+
+void SwTxtNode::CopyCollFmt( SwTxtNode& rDestNd )
+{
+    // kopiere die Formate in das andere Dokument:
+
+    // Sonderbehandlung fuer PageBreak/PageDesc/ColBrk
+    SwDoc* pDestDoc = rDestNd.GetDoc();
+    SwAttrSet aPgBrkSet( pDestDoc->GetAttrPool(), aBreakSetRange );
+    SwAttrSet* pSet;
+
+    if( 0 != ( pSet = rDestNd.GetpSwAttrSet() ) )
+    {
+        // Sonderbehandlung fuer unsere Break-Attribute
+        const SfxPoolItem* pAttr;
+        if( SFX_ITEM_SET == pSet->GetItemState( RES_BREAK, FALSE, &pAttr ) )
+            aPgBrkSet.Put( *pAttr );
+
+        if( SFX_ITEM_SET == pSet->GetItemState( RES_PAGEDESC, FALSE, &pAttr ) )
+            aPgBrkSet.Put( *pAttr );
+    }
+
+    rDestNd.ChgFmtColl( pDestDoc->CopyTxtColl( *GetTxtColl() ));
+    if( 0 != ( pSet = GetpSwAttrSet() ) )
+        pSet->CopyToModify( rDestNd );
+
+    if( aPgBrkSet.Count() )
+        rDestNd.SwCntntNode::SetAttr( aPgBrkSet );
+}
+
+
+//  ----- Copy-Methode vom SwDoc ------
+
+    // verhinder das Kopieren in Fly's, die im Bereich verankert sind.
+BOOL lcl_ChkFlyFly( SwDoc* pDoc, ULONG nSttNd, ULONG nEndNd,
+                        ULONG nInsNd )
+{
+    const SwFrmFmt* pFmt;
+    const SwFmtAnchor* pAnchor;
+    const SwPosition* pAPos;
+    const SwSpzFrmFmts& rFrmFmtTbl = *pDoc->GetSpzFrmFmts();
+
+    for( USHORT n = 0; n < rFrmFmtTbl.Count(); ++n )
+    {
+        pFmt = rFrmFmtTbl[n];
+        pAnchor = &pFmt->GetAnchor();
+        if( 0 != ( pAPos = pAnchor->GetCntntAnchor()) &&
+            ( FLY_IN_CNTNT == pAnchor->GetAnchorId() ||
+              FLY_AUTO_CNTNT == pAnchor->GetAnchorId() ||
+              FLY_AT_FLY == pAnchor->GetAnchorId() ||
+              FLY_AT_CNTNT == pAnchor->GetAnchorId() ) &&
+            nSttNd <= pAPos->nNode.GetIndex() &&
+            pAPos->nNode.GetIndex() < nEndNd )
+        {
+            const SwFmtCntnt& rCntnt = pFmt->GetCntnt();
+            SwStartNode* pSNd;
+            if( !rCntnt.GetCntntIdx() ||
+                0 == ( pSNd = rCntnt.GetCntntIdx()->GetNode().GetStartNode() ))
+                continue;
+
+            if( pSNd->GetIndex() < nInsNd &&
+                nInsNd < pSNd->EndOfSectionIndex() )
+                return TRUE;        // nicht kopieren !!
+
+            if( lcl_ChkFlyFly( pDoc, pSNd->GetIndex(),
+                        pSNd->EndOfSectionIndex(), nInsNd ) )
+                return TRUE;        // nicht kopieren !!
+        }
+    }
+
+    return FALSE;
+}
+
+void lcl_SetCpyPos( const SwPosition& rOrigPos,
+                    const SwPosition& rOrigStt,
+                    const SwPosition& rCpyStt,
+                    SwPosition& rChgPos )
+{
+    ULONG nNdOff = rOrigPos.nNode.GetIndex();
+    nNdOff -= rOrigStt.nNode.GetIndex();
+    xub_StrLen nCntntPos = rOrigPos.nContent.GetIndex();
+
+    if( nNdOff )
+        rChgPos.nNode = nNdOff + rCpyStt.nNode.GetIndex();
+    else
+    {
+        // dann nur den Content anpassen
+        if( nCntntPos > rOrigStt.nContent.GetIndex() )
+            nCntntPos -= rOrigStt.nContent.GetIndex();
+        else
+            nCntntPos = 0;
+        nCntntPos += rCpyStt.nContent.GetIndex();
+    }
+    rChgPos.nContent.Assign( rChgPos.nNode.GetNode().GetCntntNode(), nCntntPos );
+}
+
+void lcl_CopyBookmarks( const SwPaM& rPam, SwPaM& rCpyPam )
+{
+    const SwDoc* pSrcDoc = rPam.GetDoc();
+    SwDoc* pDestDoc =  rCpyPam.GetDoc();
+    BOOL bDoesUndo = pDestDoc->DoesUndo();
+    pDestDoc->DoUndo( FALSE );
+
+    const SwPosition &rStt = *rPam.Start(), &rEnd = *rPam.End();
+    SwPosition* pCpyStt = rCpyPam.Start();
+
+    const SwBookmark* pBkmk;
+    for( USHORT nCnt = pSrcDoc->GetBookmarks().Count(); nCnt; )
+    {
+        // liegt auf der Position ??
+        if( ( pBkmk = pSrcDoc->GetBookmarks()[ --nCnt ])->GetPos() < rStt
+            || pBkmk->GetPos() >= rEnd )
+            continue;
+
+        int bHasOtherPos = 0 != pBkmk->GetOtherPos();
+        if( bHasOtherPos && ( *pBkmk->GetOtherPos() < rStt ||
+            *pBkmk->GetOtherPos() >= rEnd ) )
+            continue;
+
+        SwPaM aTmpPam( *pCpyStt );
+        lcl_SetCpyPos( pBkmk->GetPos(), rStt, *pCpyStt, *aTmpPam.GetPoint() );
+        if( bHasOtherPos )
+        {
+            aTmpPam.SetMark();
+            lcl_SetCpyPos( *pBkmk->GetOtherPos(), rStt, *pCpyStt,
+                            *aTmpPam.GetMark() );
+        }
+
+        String sNewNm( pBkmk->GetName() );
+        if( !pDestDoc->IsCopyIsMove() &&
+            USHRT_MAX != pDestDoc->FindBookmark( sNewNm ) )
+            pDestDoc->MakeUniqueBookmarkName( sNewNm );
+        pDestDoc->MakeBookmark( aTmpPam, pBkmk->GetKeyCode(), sNewNm,
+                                pBkmk->GetShortName() );
+    }
+    pDestDoc->DoUndo( bDoesUndo );
+}
+
+void lcl_DeleteRedlines( const SwPaM& rPam, SwPaM& rCpyPam )
+{
+    const SwDoc* pSrcDoc = rPam.GetDoc();
+    const SwRedlineTbl& rTbl = pSrcDoc->GetRedlineTbl();
+    if( rTbl.Count() )
+    {
+        SwDoc* pDestDoc = rCpyPam.GetDoc();
+        SwPosition* pCpyStt = rCpyPam.Start(), *pCpyEnd = rCpyPam.End();
+        SwPaM* pDelPam = 0;
+        const SwPosition *pStt = rPam.Start(), *pEnd = rPam.End();
+        USHORT n = 0;
+        pSrcDoc->GetRedline( *pStt, &n );
+        for( ; n < rTbl.Count(); ++n )
+        {
+            const SwRedline* pRedl = rTbl[ n ];
+            if( REDLINE_DELETE == pRedl->GetType() && pRedl->IsVisible() )
+            {
+                const SwPosition *pRStt = pRedl->Start(), *pREnd = pRedl->End();
+
+                SwComparePosition eCmpPos = ComparePosition( *pStt, *pEnd, *pRStt, *pREnd );
+                switch( eCmpPos )
+                {
+                case POS_BEFORE:                // Pos1 liegt vor Pos2
+                    break;
+
+                case POS_BEHIND:                // Pos1 liegt hinter Pos2
+                    n = rTbl.Count();
+                    break;
+
+                default:
+                    {
+                        pDelPam = new SwPaM( *pCpyStt, pDelPam );
+                        if( *pStt < *pRStt )
+                            lcl_SetCpyPos( *pRStt, *pStt, *pCpyStt,
+                                            *pDelPam->GetPoint() );
+                        pDelPam->SetMark();
+
+                        if( *pEnd < *pREnd )
+                            *pDelPam->GetPoint() = *pCpyEnd;
+                        else
+                            lcl_SetCpyPos( *pREnd, *pStt, *pCpyStt,
+                                            *pDelPam->GetPoint() );
+                    }
+                }
+            }
+        }
+
+        if( pDelPam )
+        {
+            SwRedlineMode eOld = pDestDoc->GetRedlineMode();
+            pDestDoc->SetRedlineMode_intern( eOld | REDLINE_IGNORE );
+
+            BOOL bDoesUndo = pDestDoc->DoesUndo();
+            pDestDoc->DoUndo( FALSE );
+
+            do {
+                pDestDoc->DeleteAndJoin( *(SwPaM*)pDelPam->GetNext() );
+                if( pDelPam->GetNext() == pDelPam )
+                    break;
+                delete pDelPam->GetNext();
+            } while( TRUE );
+            delete pDelPam;
+
+            pDestDoc->DoUndo( bDoesUndo );
+            pDestDoc->SetRedlineMode_intern( eOld );
+        }
+    }
+}
+
+void lcl_DeleteRedlines( const SwNodeRange& rRg, SwNodeRange& rCpyRg )
+{
+    SwDoc* pSrcDoc = rRg.aStart.GetNode().GetDoc();
+    if( pSrcDoc->GetRedlineTbl().Count() )
+    {
+        SwPaM aRgTmp( rRg.aStart, rRg.aEnd );
+        SwPaM aCpyTmp( rCpyRg.aStart, rCpyRg.aEnd );
+        lcl_DeleteRedlines( aRgTmp, aCpyTmp );
+    }
+}
+
+// Kopieren eines Bereiches im oder in ein anderes Dokument !
+
+BOOL SwDoc::Copy( SwPaM& rPam, SwPosition& rPos ) const
+{
+    const SwPosition *pStt = rPam.Start(), *pEnd = rPam.End();
+    // kein Copy abfangen.
+    if( !rPam.HasMark() || *pStt >= *pEnd )
+        return FALSE;
+
+    SwDoc* pDoc = rPos.nNode.GetNode().GetDoc();
+
+    // verhinder das Kopieren in Fly's, die im Bereich verankert sind.
+    if( pDoc == this )
+    {
+        // Start-/EndNode noch korrigieren
+        ULONG nStt = pStt->nNode.GetIndex(),
+                nEnd = pEnd->nNode.GetIndex(),
+                nDiff = nEnd - nStt +1;
+        SwNode* pNd = GetNodes()[ nStt ];
+        if( pNd->IsCntntNode() && pStt->nContent.GetIndex() )
+            ++nStt, --nDiff;
+        if( (pNd = GetNodes()[ nEnd ])->IsCntntNode() &&
+            ((SwCntntNode*)pNd)->Len() != pEnd->nContent.GetIndex() )
+            --nEnd, --nDiff;
+        if( nDiff &&
+            lcl_ChkFlyFly( pDoc, nStt, nEnd, rPos.nNode.GetIndex() ) )
+            return FALSE;
+    }
+
+    SwPaM* pRedlineRange = 0;
+    if( pDoc->IsRedlineOn() ||
+        (!pDoc->IsIgnoreRedline() && pDoc->GetRedlineTbl().Count() ) )
+        pRedlineRange = new SwPaM( rPos );
+
+    SwRedlineMode eOld = pDoc->GetRedlineMode();
+
+    BOOL bRet = FALSE;
+
+    if( pDoc && pDoc != this )
+        bRet = _Copy( rPam, rPos, TRUE, pRedlineRange );    // nur normales Kopieren
+
+    // Copy in sich selbst (ueber mehrere Nodes wird hier gesondert
+    // behandelt; in einem TextNode wird normal behandelt)
+    else if( ! ( *pStt <= rPos && rPos < *pEnd &&
+            ( pStt->nNode != pEnd->nNode ||
+              !pStt->nNode.GetNode().IsTxtNode() )) )
+        bRet = _Copy( rPam, rPos, TRUE, pRedlineRange );    // nur normales Kopieren
+
+    else
+    {
+        ASSERT( this == pDoc, " falscher Copy-Zweig!" );
+        pDoc->SetRedlineMode_intern( eOld | REDLINE_IGNORE );
+
+        BOOL bDoUndo = pDoc->DoesUndo();
+        pDoc->DoUndo( FALSE );  // Auf jedenfall Undo abschalten
+        // dann kopiere den Bereich im unteren DokumentBereich,
+        // (mit Start/End-Nodes geklammert) und verschiebe diese
+        // dann an die gewuenschte Stelle.
+
+        SwUndoCpyDoc* pUndo;
+        SwPaM aPam( rPos );         // UndoBereich sichern
+        if( bDoUndo )
+        {
+            pDoc->ClearRedo();
+            pUndo = new SwUndoCpyDoc( aPam );
+        }
+
+        SwStartNode* pSttNd = pDoc->GetNodes().MakeEmptySection(
+                                SwNodeIndex( GetNodes().GetEndOfAutotext() ));
+        aPam.GetPoint()->nNode = *pSttNd->EndOfSectionNode();
+        pDoc->_Copy( rPam, *aPam.GetPoint(), FALSE );       // kopieren ohne Frames
+
+        aPam.GetPoint()->nNode = pDoc->GetNodes().GetEndOfAutotext();
+        aPam.SetMark();
+        SwCntntNode* pNode = pDoc->GetNodes().GoPrevious( &aPam.GetMark()->nNode );
+        pNode->MakeEndIndex( &aPam.GetMark()->nContent );
+
+        aPam.GetPoint()->nNode = *aPam.GetNode()->StartOfSectionNode();
+        pNode = pDoc->GetNodes().GoNext( &aPam.GetPoint()->nNode );
+        pNode->MakeStartIndex( &aPam.GetPoint()->nContent );
+        pDoc->Move( aPam, rPos );               // auf gewuenschte Position moven
+
+        pNode = aPam.GetCntntNode();
+        *aPam.GetPoint() = rPos;        // Cursor umsetzen fuers Undo !
+        aPam.SetMark();                 // auch den Mark umsetzen !!
+        aPam.DeleteMark();              // aber keinen Bereich makieren !!
+        pDoc->DeleteSection( pNode );           // Bereich wieder loeschen
+
+        // falls Undo eingeschaltet ist, so speicher den eingefuegten Bereich
+        pDoc->DoUndo( bDoUndo );
+        if( bDoUndo )
+        {
+            pUndo->SetInsertRange( aPam );
+            pDoc->AppendUndo( pUndo );
+        }
+
+        if( pRedlineRange )
+        {
+            pRedlineRange->SetMark();
+            *pRedlineRange->GetPoint() = *aPam.GetPoint();
+            *pRedlineRange->GetMark() = *aPam.GetMark();
+        }
+
+        pDoc->SetModified();
+        bRet = TRUE;
+    }
+
+    pDoc->SetRedlineMode_intern( eOld );
+    if( pRedlineRange )
+    {
+        if( pDoc->IsRedlineOn() )
+            pDoc->AppendRedline( new SwRedline( REDLINE_INSERT, *pRedlineRange ));
+        else
+            pDoc->SplitRedline( *pRedlineRange );
+        delete pRedlineRange;
+    }
+
+    return bRet;
+}
+
+// Kopieren eines Bereiches im oder in ein anderes Dokument !
+// Die Position darf nicht im Bereich liegen !!
+
+BOOL SwDoc::_Copy( SwPaM& rPam, SwPosition& rPos,
+                    BOOL bMakeNewFrms, SwPaM* pCpyRange ) const
+{
+    SwDoc* pDoc = rPos.nNode.GetNode().GetDoc();
+
+    SwPosition *pStt = rPam.Start(), *pEnd = rPam.End();
+    // kein Copy abfangen.
+    if( !rPam.HasMark() || *pStt >= *pEnd ||
+        ( pDoc == this && *pStt <= rPos && rPos < *pEnd ))
+        return FALSE;
+
+    BOOL bEndEqualIns = pDoc == this && rPos == *pEnd;
+
+    // falls Undo eingeschaltet, erzeuge das UndoCopy-Objekt
+    SwUndoCpyDoc* pUndo;
+    SwPaM aCpyPam( rPos );
+
+    SwTblNumFmtMerge aTNFM( *this, *pDoc );
+
+    if( pDoc->DoesUndo() )
+    {
+        pDoc->ClearRedo();
+        pUndo = new SwUndoCpyDoc( aCpyPam );
+        pDoc->AppendUndo( pUndo );
+    }
+
+    SwRedlineMode eOld = pDoc->GetRedlineMode();
+    pDoc->SetRedlineMode_intern( eOld | REDLINE_IGNORE );
+
+
+    // bewege den Pam von der Insert-Position ein zurueck, dadurch wird
+    // die Position nicht "verschoben"
+    aCpyPam.SetMark();
+    BOOL bCanMoveBack = aCpyPam.Move( fnMoveBackward, fnGoCntnt );
+    if( !bCanMoveBack )
+        aCpyPam.GetPoint()->nNode--;
+
+    SwNodeRange aRg( pStt->nNode, pEnd->nNode );
+    SwNodeIndex aInsPos( rPos.nNode );
+    BOOL bOneNode = pStt->nNode == pEnd->nNode;
+    SwTxtNode* pSttNd = pStt->nNode.GetNode().GetTxtNode();
+    SwTxtNode* pEndNd = pEnd->nNode.GetNode().GetTxtNode();
+    SwTxtNode* pDestNd = aInsPos.GetNode().GetTxtNode();
+    BOOL bCopyCollFmt = !pDoc->IsInsOnlyTextGlossary() && (
+                        ( pDestNd && !pDestNd->GetTxt().Len() ) ||
+                        ( !bOneNode && !rPos.nContent.GetIndex() ));
+    BOOL bCopyBookmarks = TRUE;
+
+    // Block, damit aus diesem gesprungen werden kann !!
+    do {
+        if( pSttNd )
+        {
+            // den Anfang nicht komplett kopieren ?
+            if( !bCopyCollFmt || pStt->nContent.GetIndex() )
+            {
+                SwIndex aDestIdx( rPos.nContent );
+                BOOL bCopyOk = FALSE;
+                if( !pDestNd )
+                {
+                    if( pStt->nContent.GetIndex() || bOneNode )
+                        pDestNd = pDoc->GetNodes().MakeTxtNode( aInsPos,
+                            pDoc->GetTxtCollFromPool(RES_POOLCOLL_STANDARD));
+                    else
+                    {
+                        pDestNd = (SwTxtNode*)pSttNd->MakeCopy( pDoc, aInsPos );
+                        bCopyOk = TRUE;
+                    }
+                    aDestIdx.Assign( pDestNd, 0 );
+                    bCopyCollFmt = TRUE;
+                }
+                else if( !bOneNode )
+                {
+                    BYTE nNumLevel = !pDestNd->GetNum() ? 0
+                                            : pDestNd->GetNum()->GetLevel();
+
+                    xub_StrLen nCntntEnd = pEnd->nContent.GetIndex();
+                    BOOL bDoesUndo = pDoc->DoesUndo();
+                    pDoc->DoUndo( FALSE );
+                    pDoc->SplitNode( rPos );
+                    pDoc->DoUndo( bDoesUndo );
+
+                    // Nummerierung korrigieren, SplitNode erzeugt immer einen
+                    // neuen Level
+                    if( NO_NUMLEVEL & nNumLevel )
+                        pDestNd->UpdateNum( SwNodeNum( nNumLevel ));
+
+                    if( bCanMoveBack && rPos == *aCpyPam.GetPoint() )
+                    {
+                        // nach dem SplitNode, den CpyPam wieder richtig aufspannen
+                        aCpyPam.Move( fnMoveBackward, fnGoCntnt );
+                        aCpyPam.Move( fnMoveBackward, fnGoCntnt );
+                    }
+
+                    pDestNd = pDoc->GetNodes()[ aInsPos.GetIndex()-1 ]->GetTxtNode();
+                    aDestIdx.Assign( pDestNd, pDestNd->GetTxt().Len() );
+
+                    // korrigiere den Bereich wieder !!
+                    if( bEndEqualIns )
+                    {
+                        BOOL bChg = pEnd != rPam.GetPoint();
+                        if( bChg )
+                            rPam.Exchange();
+                        rPam.Move( fnMoveBackward, fnGoCntnt );
+                        if( bChg )
+                            rPam.Exchange();
+
+                        aRg.aEnd = pEnd->nNode;
+                    }
+                    else if( rPos == *pEnd )        // Wurde das Ende auch verschoben
+                    {
+                        pEnd->nNode--;
+                        pEnd->nContent.Assign( pDestNd, nCntntEnd );
+                        aRg.aEnd = pEnd->nNode;
+                        pEndNd = pEnd->nNode.GetNode().GetTxtNode();
+                    }
+                }
+
+                if( !bCopyOk )
+                {
+                    xub_StrLen nCpyLen = ( bOneNode ? pEnd->nContent.GetIndex()
+                                            : pSttNd->GetTxt().Len() )
+                                    - pStt->nContent.GetIndex();
+                    pSttNd->Copy( pDestNd, aDestIdx, pStt->nContent, nCpyLen );
+                    if( bEndEqualIns )
+                        pEnd->nContent -= nCpyLen;
+                }
+
+                if( bOneNode )
+                {
+                    // ist der DestinationNode leer, kopiere die Vorlage mit
+                    if( bCopyCollFmt )
+                    {
+                        pSttNd->CopyCollFmt( *pDestNd );
+                        if( pSttNd->GetNum() )
+                            pDestNd->UpdateNum( *pSttNd->GetNum() );
+                    }
+                    break;
+                }
+                aRg.aStart++;
+            }
+        }
+        else if( pDestNd )
+        {
+            if( rPos.nContent.GetIndex() == pDestNd->Len() )
+                aInsPos++;
+            else if( rPos.nContent.GetIndex() )
+            {
+                // splitte den TextNode, bei dem Eingefuegt wird.
+                BYTE nNumLevel = !pDestNd->GetNum() ? 0
+                                        : pDestNd->GetNum()->GetLevel();
+
+                xub_StrLen nCntntEnd = pEnd->nContent.GetIndex();
+                BOOL bDoesUndo = pDoc->DoesUndo();
+                pDoc->DoUndo( FALSE );
+                pDoc->SplitNode( rPos );
+                pDoc->DoUndo( bDoesUndo );
+
+                // Nummerierung korrigieren, SplitNode erzeugt immer einen
+                // neuen Level
+                if( NO_NUMLEVEL & nNumLevel )
+                    pDestNd->UpdateNum( SwNodeNum( nNumLevel ));
+
+                if( bCanMoveBack && rPos == *aCpyPam.GetPoint() )
+                {
+                    // nach dem SplitNode, den CpyPam wieder richtig aufspannen
+                    aCpyPam.Move( fnMoveBackward, fnGoCntnt );
+                    aCpyPam.Move( fnMoveBackward, fnGoCntnt );
+                }
+
+                // korrigiere den Bereich wieder !!
+                if( bEndEqualIns )
+                    aRg.aEnd--;
+                else if( rPos == *pEnd )        // Wurde das Ende auch verschoben
+                {
+                    rPos.nNode-=2;
+                    rPos.nContent.Assign( rPos.nNode.GetNode().GetCntntNode(),
+                                            nCntntEnd );
+                    rPos.nNode++;
+                    aRg.aEnd--;
+                }
+            }
+        }
+
+        pDestNd = aInsPos.GetNode().GetTxtNode();
+        if( pEndNd )
+        {
+            SwIndex aDestIdx( rPos.nContent );
+            if( !pDestNd )
+            {
+                pDestNd = pDoc->GetNodes().MakeTxtNode( aInsPos,
+                            pDoc->GetTxtCollFromPool(RES_POOLCOLL_STANDARD));
+                aDestIdx.Assign( pDestNd, 0  );
+                aInsPos--;
+            }
+
+            BOOL bEmptyDestNd = 0 == pDestNd->GetTxt().Len();
+            pEndNd->Copy( pDestNd, aDestIdx, SwIndex( pEndNd ),
+                            pEnd->nContent.GetIndex() );
+
+            // auch alle FormatVorlagen kopieren
+            if( bCopyCollFmt && ( bOneNode || bEmptyDestNd ))
+            {
+                pEndNd->CopyCollFmt( *pDestNd );
+                if( pEndNd->GetNum() )
+                    pDestNd->UpdateNum( *pEndNd->GetNum() );
+            }
+        }
+
+        int bHasRange = aRg.aStart != aRg.aEnd;
+
+        SfxItemSet aBrkSet( pDoc->GetAttrPool(), aBreakSetRange );
+        if( bHasRange && pSttNd && bCopyCollFmt && pDestNd->GetpSwAttrSet() )
+        {
+            aBrkSet.Put( *pDestNd->GetpSwAttrSet() );
+            if( SFX_ITEM_SET == aBrkSet.GetItemState( RES_BREAK, FALSE ) )
+                pDestNd->ResetAttr( RES_BREAK );
+            if( SFX_ITEM_SET == aBrkSet.GetItemState( RES_PAGEDESC, FALSE ) )
+                pDestNd->ResetAttr( RES_PAGEDESC );
+        }
+
+        SwNodeIndex aSavePos( aInsPos, bHasRange ? -1 : 0 );
+        if( bHasRange )
+        {
+            CopyWithFlyInFly( aRg, aInsPos, bMakeNewFrms, FALSE );
+            aSavePos++;
+            bCopyBookmarks = FALSE;
+        }
+
+        // harte Umbrueche wieder in den ersten Node setzen
+        if( aBrkSet.Count() && 0 != ( pDestNd = pDoc->GetNodes()[
+                aCpyPam.GetPoint()->nNode.GetIndex()+1 ]->GetTxtNode() ) )
+        {
+            pDestNd->SwCntntNode::SetAttr( aBrkSet );
+        }
+
+    } while( FALSE );
+
+    // Position ummelden ( falls verschoben / im anderen Node )
+    rPos.nContent.Assign( rPos.nNode.GetNode().GetCntntNode(),
+                            rPos.nContent.GetIndex() );
+
+    if( rPos.nNode != aInsPos )
+    {
+        aCpyPam.GetMark()->nNode = aInsPos;
+        aCpyPam.GetMark()->nContent.Assign( aCpyPam.GetCntntNode(FALSE), 0 );
+        rPos = *aCpyPam.GetMark();
+    }
+    else
+        *aCpyPam.GetMark() = rPos;
+
+
+#ifndef PPC
+    aCpyPam.Move( fnMoveForward, bCanMoveBack ? fnGoCntnt : fnGoNode );
+#else
+    /*
+     * All das wegen dem PPC, der leider ein kleines Problem mit Funktions -
+     * pointer und tenaeren Ausdruecken hat.
+     * Wer diese Zeilen nach MAERZ 94 sieht sage mir das bitte.
+     * OK 19.01.94 18:16
+     */
+    if( bCanMoveBack )
+        aCpyPam.Move( fnMoveForward, fnGoCntnt );
+    else
+        aCpyPam.Move( fnMoveForward, fnGoNode );
+#endif
+
+
+    aCpyPam.Exchange();
+
+    // dann kopiere noch alle Bookmarks
+    if( bCopyBookmarks && GetBookmarks().Count() )
+        lcl_CopyBookmarks( rPam, aCpyPam );
+
+    if( REDLINE_DELETE_REDLINES & eOld )
+        lcl_DeleteRedlines( rPam, aCpyPam );
+
+    // falls Undo eingeschaltet ist, so speicher den eingefuegten Bereich
+    if( pDoc->DoesUndo() )
+        pUndo->SetInsertRange( aCpyPam, TRUE, 0 != pSttNd );
+
+    if( pCpyRange )
+    {
+        pCpyRange->SetMark();
+        *pCpyRange->GetPoint() = *aCpyPam.GetPoint();
+        *pCpyRange->GetMark() = *aCpyPam.GetMark();
+    }
+    pDoc->SetRedlineMode_intern( eOld );
+    pDoc->SetModified();
+    return TRUE;
+}
+
+
+//  ----- Copy-Methode vom SwDoc - "kopiere Fly's in Fly's" ------
+
+void SwDoc::CopyWithFlyInFly( const SwNodeRange& rRg,
+                            const SwNodeIndex& rInsPos, BOOL bMakeNewFrms,
+                            BOOL bDelRedlines, BOOL bCopyFlyAtFly ) const
+{
+    SwDoc* pDest = rInsPos.GetNode().GetDoc();
+
+    _SaveRedlEndPosForRestore aRedlRest( rInsPos );
+
+    SwNodeIndex aSavePos( rInsPos, -1 );
+    GetNodes()._CopyNodes( rRg, rInsPos, bMakeNewFrms, TRUE );
+    aSavePos++;
+
+    aRedlRest.Restore();
+
+#ifndef PRODUCT
+    {
+        //JP 17.06.99: Bug 66973 - check count only if the selection is in
+        //              the same (or no) section. Becaus not full selected
+        //              section are not copied.
+        const SwSectionNode* pSSectNd = rRg.aStart.GetNode().FindSectionNode();
+        SwNodeIndex aTmpI( rRg.aEnd, -1 );
+        const SwSectionNode* pESectNd = aTmpI.GetNode().FindSectionNode();
+        if( pSSectNd == pESectNd &&
+            !rRg.aStart.GetNode().IsSectionNode() &&
+            !aTmpI.GetNode().IsEndNode() )
+        {
+            ASSERT( ( rInsPos.GetIndex() - aSavePos.GetIndex() ) ==
+                    rRg.aEnd.GetIndex() - rRg.aStart.GetIndex(),
+                    "Es wurden zu wenig Nodes kopiert!" )
+        }
+    }
+#endif
+
+    // Undo abschalten
+    BOOL bUndo = pDest->DoesUndo();
+    pDest->DoUndo( FALSE );
+    _CopyFlyInFly( rRg, aSavePos, bCopyFlyAtFly );
+    pDest->DoUndo( bUndo );
+
+    SwNodeRange aCpyRange( aSavePos, rInsPos );
+
+    // dann kopiere noch alle Bookmarks
+    if( GetBookmarks().Count() )
+    {
+        SwPaM aRgTmp( rRg.aStart, rRg.aEnd );
+        SwPaM aCpyTmp( aCpyRange.aStart, aCpyRange.aEnd );
+
+        lcl_CopyBookmarks( aRgTmp, aCpyTmp );
+    }
+
+    if( bDelRedlines && ( REDLINE_DELETE_REDLINES & pDest->GetRedlineMode() ))
+        lcl_DeleteRedlines( rRg, aCpyRange );
+
+    pDest->GetNodes()._DelDummyNodes( aCpyRange );
+}
+
+void lcl_ChainFmts( SwFlyFrmFmt *pSrc, SwFlyFrmFmt *pDest )
+{
+    SwFmtChain aSrc( pSrc->GetChain() );
+    if ( !aSrc.GetNext() )
+    {
+        aSrc.SetNext( pDest );
+        pSrc->SetAttr( aSrc );
+    }
+    SwFmtChain aDest( pDest->GetChain() );
+    if ( !aDest.GetPrev() )
+    {
+        aDest.SetPrev( pSrc );
+        pDest->SetAttr( aDest );
+    }
+}
+
+void SwDoc::_CopyFlyInFly( const SwNodeRange& rRg, const SwNodeIndex& rSttIdx,
+                            BOOL bCopyFlyAtFly ) const
+{
+    // Bug 22727: suche erst mal alle Flys zusammen, sortiere sie entsprechend
+    //            ihrer Ordnungsnummer und kopiere sie erst dann. Damit wird
+    //            die Ordnungsnummer (wird nur im DrawModel verwaltet)
+    //            beibehalten.
+    SwDoc* pDest = rSttIdx.GetNode().GetDoc();
+    _ZSortFlys aArr;
+    USHORT nArrLen = GetSpzFrmFmts()->Count();
+    for( USHORT n = 0; n < nArrLen; ++n )
+    {
+        const SwFrmFmt* pFmt = (*GetSpzFrmFmts())[n];
+        const SwFmtAnchor* pAnchor = &pFmt->GetAnchor();
+        const SwPosition* pAPos;
+        if ( ( pAnchor->GetAnchorId() == FLY_AT_CNTNT ||
+               pAnchor->GetAnchorId() == FLY_AT_FLY ||
+               pAnchor->GetAnchorId() == FLY_AUTO_CNTNT ) &&
+             0 != ( pAPos = pAnchor->GetCntntAnchor()) &&
+             (( bCopyFlyAtFly && FLY_AT_FLY == pAnchor->GetAnchorId() )
+                    ? rRg.aStart <= pAPos->nNode.GetIndex() + 1
+                    : ( IsRedlineMove()
+                            ? rRg.aStart < pAPos->nNode
+                            : rRg.aStart <= pAPos->nNode )) &&
+             pAPos->nNode < rRg.aEnd )
+        {
+            aArr.Insert( _ZSortFly( pFmt, pAnchor, nArrLen + aArr.Count() ));
+        }
+    }
+
+    //Alle kopierten (also die neu erzeugten) Rahmen in ein weiteres Array
+    //stopfen. Dort sizten sie passend zu den Originalen, damit hinterher
+    //die Chains entsprechend aufgebaut werden koennen.
+    SvPtrarr aNewArr( 10, 10 );
+
+    for( n = 0; n < aArr.Count(); ++n )
+    {
+        // neuen Anker anlegen
+        const _ZSortFly& rZSortFly = aArr[ n ];
+        SwFmtAnchor aAnchor( *rZSortFly.GetAnchor() );
+        SwPosition *pNewPos = (SwPosition*)aAnchor.GetCntntAnchor();
+        long nOffset = pNewPos->nNode.GetIndex() -
+                            rRg.aStart.GetIndex();
+        SwNodeIndex aIdx( rSttIdx, nOffset );
+        pNewPos->nNode = aIdx;
+        // die am Zeichen Flys wieder ans das vorgegebene Zeichen setzen
+        if( FLY_AUTO_CNTNT == aAnchor.GetAnchorId() &&
+            aIdx.GetNode().IsTxtNode() )
+            pNewPos->nContent.Assign( (SwTxtNode*)&aIdx.GetNode(),
+                                        pNewPos->nContent.GetIndex() );
+        else
+            pNewPos->nContent.Assign( 0, 0 );
+
+        // ueberpruefe Rekursion: Inhalt in "seinen eigenen" Frame
+        // kopieren. Dann nicht kopieren
+        FASTBOOL bMakeCpy = TRUE;
+        if( pDest == this )
+        {
+            const SwFmtCntnt& rCntnt = rZSortFly.GetFmt()->GetCntnt();
+            const SwStartNode* pSNd;
+            if( rCntnt.GetCntntIdx() &&
+                0 != ( pSNd = rCntnt.GetCntntIdx()->GetNode().GetStartNode() ) &&
+                pSNd->GetIndex() < rSttIdx.GetIndex() &&
+                rSttIdx.GetIndex() < pSNd->EndOfSectionIndex() )
+            {
+                bMakeCpy = FALSE;
+                aArr.Remove( n, 1 );
+                --n;
+            }
+        }
+
+        // Format kopieren und den neuen Anker setzen
+        if( bMakeCpy )
+            aNewArr.Insert( pDest->CopyLayoutFmt( *rZSortFly.GetFmt(),
+                        aAnchor, FALSE, TRUE/*FALSE*/ ), aNewArr.Count() );
+    }
+
+    //Alle chains, die im Original vorhanden sind, soweit wie moeglich wieder
+    //aufbauen.
+    ASSERT( aArr.Count() == aNewArr.Count(), "Missing new Flys" );
+    if ( aArr.Count() == aNewArr.Count() )
+    {
+        for ( n = 0; n < aArr.Count(); ++n )
+        {
+            const SwFrmFmt *pFmt = aArr[n].GetFmt();
+            const SwFmtChain &rChain = pFmt->GetChain();
+            int nCnt = 0 != rChain.GetPrev();
+            nCnt += rChain.GetNext() ? 1: 0;
+            for ( USHORT k = 0; nCnt && k < aArr.Count(); ++k )
+            {
+                const _ZSortFly &rTmp = aArr[k];
+                const SwFrmFmt *pTmp = rTmp.GetFmt();
+                if ( rChain.GetPrev() == pTmp )
+                {
+                    ::lcl_ChainFmts( (SwFlyFrmFmt*)aNewArr[k],
+                                     (SwFlyFrmFmt*)aNewArr[n] );
+                    --nCnt;
+                }
+                else if ( rChain.GetNext() == pTmp )
+                {
+                    ::lcl_ChainFmts( (SwFlyFrmFmt*)aNewArr[n],
+                                     (SwFlyFrmFmt*)aNewArr[k] );
+                    --nCnt;
+                }
+            }
+        }
+    }
+}
+
+
+
+
diff --git a/sw/source/core/docnode/ndindex.cxx b/sw/source/core/docnode/ndindex.cxx
new file mode 100644
index 000000000000..893c1519de94
--- /dev/null
+++ b/sw/source/core/docnode/ndindex.cxx
@@ -0,0 +1,203 @@
+/*************************************************************************
+ *
+ *  $RCSfile: ndindex.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:17 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "errhdl.hxx"           // fuers ASSERT
+#include "error.h"              // fuers ASSERT
+#include "ndindex.hxx"
+
+#ifndef PRODUCT
+int SwNodeIndex::nSerial = 0;
+#endif
+
+
+SwNodeRange::SwNodeRange( const SwNodeIndex &rS, const SwNodeIndex &rE )
+    : aStart( rS ), aEnd( rE )
+{}
+
+SwNodeRange::SwNodeRange( const SwNodeRange &rRange )
+    : aStart( rRange.aStart ), aEnd( rRange.aEnd )
+{}
+
+SwNodeRange::SwNodeRange( SwNodes& rNds, ULONG nSttIdx, ULONG nEndIdx )
+    : aStart( rNds, nSttIdx ), aEnd( rNds, nEndIdx )
+{}
+
+
+SwNodeRange::SwNodeRange( const SwNodeIndex& rS, long nSttDiff,
+                          const SwNodeIndex& rE, long nEndDiff )
+    : aStart( rS, nSttDiff ), aEnd( rE, nEndDiff )
+{}
+
+SwNodeRange::SwNodeRange( const SwNode& rS, long nSttDiff,
+                          const SwNode& rE, long nEndDiff )
+    : aStart( rS, nSttDiff ), aEnd( rE, nEndDiff )
+{}
+
+
+SwNodeIndex::SwNodeIndex( SwNodes& rNds, ULONG nIdx )
+    : pNd( rNds[ nIdx ] ), pNext( 0 ), pPrev( 0 )
+{
+    rNds.RegisterIndex( *this );
+
+#ifndef PRODUCT
+    MySerial = ++nSerial;       // nur in der nicht PRODUCT-Version
+#endif
+}
+
+
+SwNodeIndex::SwNodeIndex( const SwNodeIndex& rIdx, long nDiff )
+    : pNext( 0 ), pPrev( 0 )
+{
+    if( nDiff )
+        pNd = rIdx.GetNodes()[ rIdx.GetIndex() + nDiff ];
+    else
+        pNd = rIdx.pNd;
+
+    pNd->GetNodes().RegisterIndex( *this );
+#ifndef PRODUCT
+    MySerial = ++nSerial;       // nur in der nicht PRODUCT-Version
+#endif
+}
+
+
+SwNodeIndex::SwNodeIndex( const SwNode& rNd, long nDiff )
+    : pNext( 0 ), pPrev( 0 )
+{
+    if( nDiff )
+        pNd = rNd.GetNodes()[ rNd.GetIndex() + nDiff ];
+    else
+        pNd = (SwNode*)&rNd;
+
+    pNd->GetNodes().RegisterIndex( *this );
+#ifndef PRODUCT
+    MySerial = ++nSerial;       // nur in der nicht PRODUCT-Version
+#endif
+}
+
+
+void SwNodeIndex::Remove()
+{
+    pNd->GetNodes().DeRegisterIndex( *this );
+}
+
+SwNodeIndex& SwNodeIndex::operator=( const SwNodeIndex& rIdx )
+{
+    if( &pNd->GetNodes() != &rIdx.pNd->GetNodes() )
+    {
+        pNd->GetNodes().DeRegisterIndex( *this );
+        pNd = rIdx.pNd;
+        pNd->GetNodes().RegisterIndex( *this );
+    }
+    else
+        pNd = rIdx.pNd;
+    return *this;
+}
+
+SwNodeIndex& SwNodeIndex::operator=( const SwNode& rNd )
+{
+    if( &pNd->GetNodes() != &rNd.GetNodes() )
+    {
+        pNd->GetNodes().DeRegisterIndex( *this );
+        pNd = (SwNode*)&rNd;
+        pNd->GetNodes().RegisterIndex( *this );
+    }
+    else
+        pNd = (SwNode*)&rNd;
+    return *this;
+}
+
+SwNodeIndex& SwNodeIndex::Assign( SwNodes& rNds, ULONG nIdx )
+{
+    if( &pNd->GetNodes() != &rNds )
+    {
+        pNd->GetNodes().DeRegisterIndex( *this );
+        pNd = rNds[ nIdx ];
+        pNd->GetNodes().RegisterIndex( *this );
+    }
+    else
+        pNd = rNds[ nIdx ];
+    return *this;
+}
+
+SwNodeIndex& SwNodeIndex::Assign( const SwNode& rNd, long nOffset )
+{
+    if( &pNd->GetNodes() != &rNd.GetNodes() )
+    {
+        pNd->GetNodes().DeRegisterIndex( *this );
+        pNd = (SwNode*)&rNd;
+        pNd->GetNodes().RegisterIndex( *this );
+    }
+    else
+        pNd = (SwNode*)&rNd;
+
+    if( nOffset )
+        pNd = pNd->GetNodes()[ pNd->GetIndex() + nOffset ];
+
+    return *this;
+}
+
+
diff --git a/sw/source/core/docnode/ndnotxt.cxx b/sw/source/core/docnode/ndnotxt.cxx
new file mode 100644
index 000000000000..fb03f7d3399d
--- /dev/null
+++ b/sw/source/core/docnode/ndnotxt.cxx
@@ -0,0 +1,184 @@
+/*************************************************************************
+ *
+ *  $RCSfile: ndnotxt.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:17 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "hintids.hxx"
+
+#ifndef _IPOBJ_HXX //autogen
+#include 
+#endif
+#ifndef _SV_POLY_HXX //autogen
+#include 
+#endif
+#ifndef _CONTDLG_HXX_ //autogen
+#include 
+#endif
+
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#include "doc.hxx"
+#include "fmtcol.hxx"
+#include "ndnotxt.hxx"
+#include "ndgrf.hxx"
+#include "ndole.hxx"
+#include "ndindex.hxx"
+
+
+SwNoTxtNode::SwNoTxtNode( const SwNodeIndex & rWhere,
+                  const BYTE nNdType,
+                  SwGrfFmtColl *pGrfColl,
+                  SwAttrSet* pAutoAttr ) :
+    SwCntntNode( rWhere, nNdType, pGrfColl ),
+    pContour( 0 )
+{
+    // soll eine Harte-Attributierung gesetzt werden?
+    if( pAutoAttr )
+        SetAttr( *pAutoAttr );
+}
+
+
+SwNoTxtNode::~SwNoTxtNode()
+{
+    delete pContour;
+}
+
+
+// erzeugt fuer alle Ableitungen einen AttrSet mit Bereichen
+// fuer Frame- und Grafik-Attributen
+void SwNoTxtNode::NewAttrSet( SwAttrPool& rPool )
+{
+    ASSERT( !pAttrSet, "AttrSet ist doch gesetzt" );
+    pAttrSet = new SwAttrSet( rPool, aNoTxtNodeSetRange );
+    pAttrSet->SetParent( &GetFmtColl()->GetAttrSet() );
+}
+
+// Dummies fuer das Laden/Speichern von persistenten Daten
+// bei Grafiken und OLE-Objekten
+
+
+BOOL SwNoTxtNode::RestorePersistentData()
+{
+    return TRUE;
+}
+
+
+BOOL SwNoTxtNode::SavePersistentData()
+{
+    return TRUE;
+}
+
+
+void SwNoTxtNode::SetContour( const PolyPolygon *pPoly )
+{
+    delete pContour;
+    if ( pPoly )
+        pContour = new PolyPolygon( *pPoly );
+    else
+        pContour = 0;
+}
+
+
+void SwNoTxtNode::CreateContour()
+{
+    ASSERT( !pContour, "Contour available." );
+    pContour = new PolyPolygon( SvxContourDlg::CreateAutoContour( GetGraphic() ) );
+}
+
+
+void SwNoTxtNode::GetContour( PolyPolygon &rPoly ) const
+{
+    ASSERT( pContour, "Contour not available." );
+    rPoly = *pContour;
+}
+
+
+Graphic SwNoTxtNode::GetGraphic() const
+{
+    Graphic aRet;
+    if ( GetGrfNode() )
+    {
+        ((SwGrfNode*)this)->SwapIn( TRUE );
+        aRet = ((SwGrfNode*)this)->GetGrf();
+    }
+    else
+    {
+        ASSERT( GetOLENode(), "new type of Node?" );
+        SvInPlaceObjectRef xObj( ((SwOLENode*)this)->GetOLEObj().GetOleRef() );
+
+        SvData aData( FORMAT_GDIMETAFILE );
+        if ( xObj->GetData( &aData ) )
+        {
+            GDIMetaFile *pPtr;
+            if ( aData.GetData( &pPtr, TRANSFER_REFERENCE ) )
+                aRet = *pPtr;
+        }
+    }
+    return aRet;
+}
+
+
+
diff --git a/sw/source/core/docnode/ndnum.cxx b/sw/source/core/docnode/ndnum.cxx
new file mode 100644
index 000000000000..2721b9a60ca4
--- /dev/null
+++ b/sw/source/core/docnode/ndnum.cxx
@@ -0,0 +1,390 @@
+/*************************************************************************
+ *
+ *  $RCSfile: ndnum.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:17 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _NODE_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _NUMRULE_HXX
+#include 
+#endif
+#ifndef _FLDBAS_HXX
+#include            // UpdateFlds der KapitelNummerierung
+#endif
+
+
+//-------------------------------------------------------
+// Gliederung
+
+struct _OutlinePara
+{
+    SwNodeNum aNum;
+    const SwNodes& rNds;
+    BYTE nMin, nNewLevel;
+    BOOL bInitNum;
+
+    _OutlinePara( const SwNodes& rNodes, USHORT nSttPos, BYTE nOld, BYTE nNew );
+    BOOL UpdateOutline( SwTxtNode& rTxtNd );
+};
+
+_SV_IMPL_SORTAR_ALG( SwOutlineNodes, SwNodePtr )
+BOOL SwOutlineNodes::Seek_Entry( const SwNodePtr rSrch, USHORT* pFndPos ) const
+{
+    ULONG nIdx = rSrch->GetIndex();
+
+    register USHORT nO = Count(), nM, nU = 0;
+    if( nO > 0 )
+    {
+//JP 17.03.98: aufgrund des Bug 48592 - wo unter anderem nach Undo/Redo
+//              Nodes aus dem falschen NodesArray im OutlineArray standen,
+//              jetzt mal einen Check eingebaut.
+#ifndef PRODUCT
+        {
+            for( register USHORT n = 1; n < nO; ++n )
+                if( &(*this)[ n-1 ]->GetNodes() !=
+                    &(*this)[ n ]->GetNodes() )
+                {
+                    ASSERT( !this, "Node im falschen Outline-Array" );
+                }
+        }
+#endif
+
+        nO--;
+        while( nU <= nO )
+        {
+            nM = nU + ( nO - nU ) / 2;
+            if( (*this)[ nM ] == rSrch )
+            {
+                if( pFndPos )
+                    *pFndPos = nM;
+                return TRUE;
+            }
+            else if( (*this)[ nM ]->GetIndex() < nIdx )
+                nU = nM + 1;
+            else if( nM == 0 )
+            {
+                if( pFndPos )
+                    *pFndPos = nU;
+                return FALSE;
+            }
+            else
+                nO = nM - 1;
+        }
+    }
+    if( pFndPos )
+        *pFndPos = nU;
+    return FALSE;
+}
+
+
+_OutlinePara::_OutlinePara( const SwNodes& rNodes, USHORT nSttPos,
+                            BYTE nOld, BYTE nNew )
+    : rNds( rNodes ),
+    aNum( NO_NUM > nNew ? nNew : 0 ),
+    nMin( Min( nOld, nNew )),
+    bInitNum( 0 == nSttPos ),
+    nNewLevel( nNew )
+{
+    // hole vom Vorgaenger die aktuelle Nummerierung
+    SwNode* pNd;
+    ULONG nEndOfExtras = rNds.GetEndOfExtras().GetIndex();
+    if( nSttPos &&
+        ( pNd = rNds.GetOutLineNds()[ --nSttPos ])->GetIndex() > nEndOfExtras
+         && ((SwTxtNode*)pNd)->GetOutlineNum() )
+    {
+        const SwNodeNum* pNum = ((SwTxtNode*)pNd)->GetOutlineNum();
+#ifdef TASK_59308
+        if( pNum->GetLevel() & NO_NUMLEVEL )
+        {
+            // dann suche den mit richtigem Level:
+            BYTE nSrchLvl = aNum.GetLevel();
+            pNum = 0;
+            while( nSttPos-- )
+            {
+                if( ( pNd = rNds.GetOutLineNds()[ nSttPos ])->
+                    GetIndex() < nEndOfExtras )
+                    break;
+
+                if( 0 != ( pNum = ((SwTxtNode*)pNd)->GetOutlineNum() ))
+                {
+                    // uebergeordnete Ebene
+                    if( nSrchLvl > (pNum->GetLevel() &~ NO_NUMLEVEL ))
+                    {
+                        pNum = 0;
+                        break;
+                    }
+                    // gleiche Ebene und kein NO_NUMLEVEL
+                    if( nSrchLvl == (pNum->GetLevel() &~ NO_NUMLEVEL)
+                        && !( pNum->GetLevel() & NO_NUMLEVEL ))
+                        break;
+
+                    pNum = 0;
+                }
+            }
+        }
+
+#endif
+        if( pNum )
+        {
+            aNum = *pNum;
+            aNum.SetStart( FALSE );
+            aNum.SetSetValue( USHRT_MAX );
+        }
+
+        if( aNum.GetLevel()+1 < MAXLEVEL )
+            memset( aNum.GetLevelVal() + (aNum.GetLevel()+1), 0,
+                    (MAXLEVEL - (aNum.GetLevel()+1)) * sizeof(aNum.GetLevelVal()[0]) );
+    }
+    else
+        bInitNum = TRUE;
+}
+
+
+
+BOOL _OutlinePara::UpdateOutline( SwTxtNode& rTxtNd )
+{
+    // alle die ausserhalb des Fliesstextes liegen, NO_NUM zuweisen.
+    if( rTxtNd.GetIndex() < rNds.GetEndOfExtras().GetIndex() )
+    {
+        BYTE nTmpLevel = aNum.GetLevel();
+        aNum.SetLevel( NO_NUM );
+        rTxtNd.UpdateOutlineNum( aNum );
+        aNum.SetLevel( nTmpLevel );
+        return TRUE;
+    }
+
+    BYTE nLevel = rTxtNd.GetTxtColl()->GetOutlineLevel();
+    BOOL bRet = !(nMin > nLevel);
+    if( bRet )
+    {
+        // existierte am Node schon eine Nummerierung ??
+        // dann erfrage den "User definierten Wert"
+        USHORT nSetValue;
+        const SwNumRule* pOutlRule = rTxtNd.GetDoc()->GetOutlineNumRule();
+        const SwNodeNum* pOutlNum = rTxtNd.GetOutlineNum();
+
+#ifdef TASK_59308
+        if( pOutlNum && ( pOutlNum->GetLevel() & NO_NUMLEVEL ) &&
+            GetRealLevel( pOutlNum->GetLevel() ) == nLevel )
+        {
+            // diesen nicht mit numerieren
+            BYTE nTmpLevel = aNum.GetLevel();
+            aNum.SetLevel( pOutlNum->GetLevel() );
+            rTxtNd.UpdateOutlineNum( aNum );
+            aNum.SetLevel( nTmpLevel );
+            return TRUE;
+        }
+#endif
+
+        if( aNum.GetLevel() < nLevel && NO_NUM > nNewLevel )
+        {
+            if( aNum.GetLevel()+1 < MAXLEVEL )
+                memset( aNum.GetLevelVal() + (aNum.GetLevel()+1), 0,
+                        (MAXLEVEL - ( aNum.GetLevel()+1 )) *
+                            sizeof( aNum.GetLevelVal()[0]));
+            nSetValue = pOutlRule->Get( nLevel ).GetStartValue();
+        }
+        else if( bInitNum )
+        {
+            nSetValue= pOutlRule->Get( nLevel ).GetStartValue();
+            bInitNum = FALSE;
+        }
+        else
+            nSetValue = aNum.GetLevelVal()[ nLevel ] + 1;
+
+         // alle unter dem neuen Level liegenden auf 0 setzen
+        if( aNum.GetLevel() > nLevel && nLevel+1 < MAXLEVEL
+            /* ??? && NO_NUM > nNewLevel */ )
+            memset( aNum.GetLevelVal() + (nLevel+1), 0,
+                    (MAXLEVEL - ( nLevel+1 )) * sizeof(aNum.GetLevelVal()[0]) );
+
+        if( pOutlNum && USHRT_MAX != pOutlNum->GetSetValue() )
+            aNum.SetSetValue( nSetValue = pOutlNum->GetSetValue() );
+
+        aNum.GetLevelVal()[ nLevel ] = nSetValue;
+        aNum.SetLevel( nLevel );
+        rTxtNd.UpdateOutlineNum( aNum );
+        aNum.SetSetValue( USHRT_MAX );
+    }
+    return bRet;
+}
+
+
+
+BOOL lcl_UpdateOutline( const SwNodePtr& rpNd, void* pPara )
+{
+    _OutlinePara* pOutlPara = (_OutlinePara*)pPara;
+    SwTxtNode* pTxtNd = rpNd->GetTxtNode();
+    ASSERT( pTxtNd, "kein TextNode als OutlineNode !" );
+
+    return pOutlPara->UpdateOutline( *pTxtNd );
+}
+
+
+
+
+void SwNodes::UpdateOutlineNode( const SwNode& rNd, BYTE nOldLevel,
+                                BYTE nNewLevel )
+{
+    const SwNodePtr pSrch = (SwNodePtr)&rNd;
+    USHORT nSttPos;
+    BOOL bSeekIdx = pOutlineNds->Seek_Entry( pSrch, &nSttPos );
+
+    if( NO_NUMBERING == nOldLevel )         // neuen Level einfuegen
+    {
+        // nicht vorhanden, also einfuegen
+        ASSERT( !bSeekIdx, "Der Node ist schon als OutlineNode vorhanden" );
+
+        //JP 12.03.99: 63293 - Nodes vom RedlineBereich NIE aufnehmen
+        ULONG nNd = rNd.GetIndex();
+        if( nNd < GetEndOfRedlines().GetIndex() &&
+            nNd > GetEndOfRedlines().FindStartNode()->GetIndex() )
+            return ;
+
+        // jetzt noch alle nachfolgende Outline-Nodes updaten
+        pOutlineNds->Insert( pSrch );
+        if( NO_NUM <= nNewLevel )
+            return;     // keine Nummerierung dann kein Update
+    }
+    else if( NO_NUMBERING == nNewLevel )    // Level entfernen
+    {
+        if( !bSeekIdx )
+            return;
+
+        // jetzt noch alle nachfolgende Outline-Nodes updaten
+        pOutlineNds->Remove( nSttPos );
+        if( NO_NUM <= nOldLevel )
+            return;     // keine Nummerierung dann kein Update
+    }
+    else if( !bSeekIdx )        // Update und Index nicht gefunden ??
+        return ;
+
+    _OutlinePara aPara( *this, nSttPos, nOldLevel, nNewLevel );
+    pOutlineNds->ForEach( nSttPos, pOutlineNds->Count(),
+                        lcl_UpdateOutline, &aPara );
+
+//FEATURE::CONDCOLL
+    {
+        SwCntntNode* pCNd;
+        ULONG nSttNd = rNd.GetIndex();
+        if( NO_NUMBERING != nNewLevel )
+            ++nSttPos;
+
+        ULONG nChkCount = ( nSttPos < pOutlineNds->Count()
+                                ? (*pOutlineNds)[ nSttPos ]->GetIndex()
+                                : GetEndOfContent().GetIndex()  )
+                            - nSttNd;
+        for( ; nChkCount--; ++nSttNd )
+            if( 0 != (pCNd = (*this)[ nSttNd ]->GetCntntNode() ) &&
+                RES_CONDTXTFMTCOLL == pCNd->GetFmtColl()->Which() )
+                pCNd->ChkCondColl();
+    }
+//FEATURE::CONDCOLL
+
+    // die Gliederungs-Felder Updaten
+    GetDoc()->GetSysFldType( RES_CHAPTERFLD )->UpdateFlds();
+}
+
+
+
+void SwNodes::UpdtOutlineIdx( const SwNode& rNd )
+{
+    if( !pOutlineNds->Count() )     // keine OutlineNodes vorhanden ?
+        return;
+
+    const SwNodePtr pSrch = (SwNodePtr)&rNd;
+    USHORT nPos;
+    pOutlineNds->Seek_Entry( pSrch, &nPos );
+    if( nPos == pOutlineNds->Count() )      // keine zum Updaten vorhanden ?
+        return;
+
+    if( nPos )
+        --nPos;
+
+    if( !GetDoc()->IsInDtor() && IsDocNodes() )
+        UpdateOutlineNode( *(*pOutlineNds)[ nPos ], 0, 0 );
+}
+
+
+
+void SwNodes::UpdateOutlineNodes()
+{
+    if( pOutlineNds->Count() )      // OutlineNodes vorhanden ?
+        UpdateOutlineNode( *(*pOutlineNds)[ 0 ], 0, 0 );
+}
+
+
+
+
diff --git a/sw/source/core/docnode/ndsect.cxx b/sw/source/core/docnode/ndsect.cxx
new file mode 100644
index 000000000000..d3ce4dec727e
--- /dev/null
+++ b/sw/source/core/docnode/ndsect.cxx
@@ -0,0 +1,1378 @@
+/*************************************************************************
+ *
+ *  $RCSfile: ndsect.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:17 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _SVXLINKMGR_HXX
+#include 
+#endif
+#ifndef _SFXITEMITER_HXX //autogen
+#include 
+#endif
+
+#ifndef _FMTCNTNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFTN_HXX //autogen
+#include 
+#endif
+#ifndef _FMTCLDS_HXX //autogen
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _ROOTFRM_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _SECTION_HXX
+#include 
+#endif
+#ifndef _UNDOBJ_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include 
+#endif
+#ifndef _CALC_HXX
+#include 
+#endif
+#ifndef _SWTABLE_HXX
+#include 
+#endif
+#ifndef _SWSERV_HXX
+#include 
+#endif
+#ifndef _FRMFMT_HXX
+#include 
+#endif
+#ifndef _FTNIDX_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _NDINDEX_HXX
+#include 
+#endif
+#ifndef _REDLINE_HXX
+#include 
+#endif
+#ifndef _SECTFRM_HXX
+#include 
+#endif
+#ifndef _PAGEFRM_HXX
+#include 
+#endif
+#ifndef _CNTFRM_HXX
+#include 
+#endif
+#ifndef _NODE2LAY_HXX
+#include 
+#endif
+#ifndef _DOCTXM_HXX
+#include 
+#endif
+#ifndef _FMTFTNTX_HXX
+#include 
+#endif
+#ifndef _HINTS_HXX
+#include 
+#endif
+
+#ifndef _COMCORE_HRC
+#include 
+#endif
+
+SO2_IMPL_REF( SwServerObject )
+
+int lcl_IsInSameTblBox( SwNodes& rNds, const SwNode& rNd,
+                            const SwNodeIndex& rIdx2 )
+{
+    const SwTableNode* pTblNd = rNd.FindTableNode();
+    if( !pTblNd )
+        return TRUE;
+
+    // dann suche den StartNode der Box
+    const SwTableSortBoxes& rSortBoxes = pTblNd->GetTable().GetTabSortBoxes();
+    ULONG nIdx = rNd.GetIndex();
+    for( USHORT n = 0; n < rSortBoxes.Count(); ++n )
+    {
+        const SwStartNode* pNd = rSortBoxes[ n ]->GetSttNd();
+        if( pNd->GetIndex() < nIdx &&
+            nIdx < pNd->EndOfSectionIndex() )
+        {
+            // dann muss der andere Index in derselben Section liegen
+            nIdx = rIdx2.GetIndex();
+            return pNd->GetIndex() < nIdx && nIdx < pNd->EndOfSectionIndex();
+        }
+    }
+    return TRUE;
+}
+
+void lcl_CheckEmptyLayFrm( SwNodes& rNds, SwSection& rSect,
+                        const SwNode& rStt, const SwNode& rEnd )
+{
+    SwNodeIndex aIdx( rStt );
+    if( !rNds.GoPrevSection( &aIdx, TRUE, FALSE ) ||
+        !CheckNodesRange( rStt, aIdx, TRUE ) ||
+        !lcl_IsInSameTblBox( rNds, rStt, aIdx ))
+    {
+        aIdx = rEnd;
+        if( !rNds.GoNextSection( &aIdx, TRUE, FALSE ) ||
+            !CheckNodesRange( rEnd, aIdx, TRUE ) ||
+            !lcl_IsInSameTblBox( rNds, rEnd, aIdx ))
+            rSect.SetHidden( FALSE );
+    }
+}
+
+SwSection* SwDoc::Insert( const SwPaM& rRange, const SwSection& rNew,
+                            const SfxItemSet* pAttr, BOOL bUpdate )
+{
+    const SwNode* pPrvNd = 0;
+    USHORT nRegionRet = 0;
+    if( rRange.HasMark() &&
+        0 == ( nRegionRet = IsInsRegionAvailable( rRange, &pPrvNd ) ))
+    {
+        ASSERT( !this, "Selection ueber verschiedene Sections" );
+        return 0;
+    }
+
+    // Teste ob das gesamte Dokument versteckt werden soll,
+    // koennen wir zur Zeit nicht !!!!
+    if( rNew.IsHidden() && rRange.HasMark() )
+    {
+        const SwPosition *pStt = rRange.Start(), *pEnd = rRange.End();
+        if( !pStt->nContent.GetIndex() &&
+            pEnd->nNode.GetNode().GetCntntNode()->Len() ==
+            pEnd->nContent.GetIndex() )
+
+            ::lcl_CheckEmptyLayFrm( GetNodes(), (SwSection&)rNew,
+                                    pStt->nNode.GetNode(),
+                                    pEnd->nNode.GetNode() );
+    }
+
+    SwUndoInsSection* pUndoInsSect = 0;
+    if( DoesUndo() )
+    {
+        ClearRedo();
+        pUndoInsSect = new SwUndoInsSection( rRange, rNew, pAttr );
+        AppendUndo( pUndoInsSect );
+        DoUndo( FALSE );
+    }
+
+    SwSectionFmt* pFmt = MakeSectionFmt( 0 );
+    if( pAttr )
+        pFmt->SetAttr( *pAttr );
+
+    SwSectionNode* pNewSectNode = 0;
+
+    SwRedlineMode eOld = GetRedlineMode();
+    SetRedlineMode_intern( (eOld & ~REDLINE_SHOW_MASK) | REDLINE_IGNORE );
+
+    if( rRange.HasMark() )
+    {
+        SwPosition *pSttPos = (SwPosition*)rRange.Start(),
+                    *pEndPos = (SwPosition*)rRange.End();
+        if( pPrvNd && 3 == nRegionRet )
+        {
+            ASSERT( pPrvNd, "der SectionNode fehlt" );
+            SwNodeIndex aStt( pSttPos->nNode ), aEnd( pEndPos->nNode, +1 );
+            while( pPrvNd != aStt.GetNode().FindStartNode() )
+                aStt--;
+            while( pPrvNd != aEnd.GetNode().FindStartNode() )
+                aEnd++;
+
+            --aEnd;     // im InsertSection ist Ende inclusive
+            pNewSectNode = GetNodes().InsertSection( aStt, *pFmt, rNew, &aEnd );
+        }
+        else
+        {
+            if( pUndoInsSect )
+            {
+                SwTxtNode* pTNd;
+                if( !( pPrvNd && 1 == nRegionRet ) &&
+                    pSttPos->nContent.GetIndex() &&
+                    0 != ( pTNd = pSttPos->nNode.GetNode().GetTxtNode() ))
+                    pUndoInsSect->SaveSplitNode( pTNd, TRUE );
+
+                if( !( pPrvNd && 2 == nRegionRet ) &&
+                    0 != ( pTNd = pEndPos->nNode.GetNode().GetTxtNode() ) &&
+                    pTNd->GetTxt().Len() != pEndPos->nContent.GetIndex() )
+                    pUndoInsSect->SaveSplitNode( pTNd, FALSE );
+            }
+
+            const SwCntntNode* pCNd;
+            if( pPrvNd && 1 == nRegionRet )
+            {
+                pSttPos->nNode.Assign( *pPrvNd );
+                pSttPos->nContent.Assign( pSttPos->nNode.GetNode().GetCntntNode(), 0 );
+            }
+            else if( pSttPos->nContent.GetIndex() )
+                SplitNode( *pSttPos );
+
+            if( pPrvNd && 2 == nRegionRet )
+            {
+                pEndPos->nNode.Assign( *pPrvNd );
+                pEndPos->nContent.Assign( pEndPos->nNode.GetNode().GetCntntNode(), 0 );
+            }
+            else
+            {
+                pCNd = pEndPos->nNode.GetNode().GetCntntNode();
+                if( pCNd && pCNd->Len() != pEndPos->nContent.GetIndex() )
+                {
+                    xub_StrLen nCntnt = pSttPos->nContent.GetIndex();
+                    SplitNode( *pEndPos );
+
+                    SwTxtNode* pTNd;
+                    if( pEndPos->nNode.GetIndex() == pSttPos->nNode.GetIndex() )
+                    {
+                        pSttPos->nNode--;
+                        pEndPos->nNode--;
+                        pTNd = pSttPos->nNode.GetNode().GetTxtNode();
+                        pSttPos->nContent.Assign( pTNd, nCntnt );
+                    }
+                    else
+                    {
+                        // wieder ans Ende vom vorherigen setzen
+                        pEndPos->nNode--;
+                        pTNd = pEndPos->nNode.GetNode().GetTxtNode();
+                    }
+                    if( pTNd ) nCntnt = pTNd->GetTxt().Len(); else nCntnt = 0;
+                    pEndPos->nContent.Assign( pTNd, nCntnt );
+                }
+            }
+            pNewSectNode = GetNodes().InsertSection( pSttPos->nNode, *pFmt, rNew,
+                                                    &pEndPos->nNode );
+        }
+    }
+    else
+    {
+        const SwPosition* pPos = rRange.GetPoint();
+        const SwCntntNode* pCNd = pPos->nNode.GetNode().GetCntntNode();
+        if( !pPos->nContent.GetIndex() )
+        {
+            pNewSectNode = GetNodes().InsertSection( pPos->nNode, *pFmt, rNew, 0, TRUE );
+        }
+        else if( pPos->nContent.GetIndex() == pCNd->Len() )
+        {
+            pNewSectNode = GetNodes().InsertSection( pPos->nNode, *pFmt, rNew, 0, FALSE );
+        }
+        else
+        {
+            if( pUndoInsSect && pCNd->IsTxtNode() )
+                pUndoInsSect->SaveSplitNode( (SwTxtNode*)pCNd, TRUE );
+            SplitNode( *pPos );
+            pNewSectNode = GetNodes().InsertSection( pPos->nNode, *pFmt, rNew, 0, TRUE );
+        }
+    }
+
+//FEATURE::CONDCOLL
+    pNewSectNode->CheckSectionCondColl();
+//FEATURE::CONDCOLL
+
+    SetRedlineMode_intern( eOld );
+
+    if( IsRedlineOn() || (!IsIgnoreRedline() && pRedlineTbl->Count() ))
+    {
+        SwPaM aPam( *pNewSectNode->EndOfSectionNode(), *pNewSectNode, 1 );
+        if( IsRedlineOn() )
+            AppendRedline( new SwRedline( REDLINE_INSERT, aPam ));
+        else
+            SplitRedline( aPam );
+    }
+
+    // ist eine Condition gesetzt
+    if( rNew.IsHidden() && rNew.GetCondition().Len() )
+    {
+        // dann berechne bis zu dieser Position
+        SwCalc aCalc( *this );
+        FldsToCalc( aCalc, pNewSectNode->GetIndex() );
+        SwSection& rNewSect = pNewSectNode->GetSection();
+        rNewSect.SetCondHidden( aCalc.Calculate( rNewSect.GetCondition() ).GetBool() );
+    }
+
+    BOOL bUpdateFtn = FALSE;
+    if( GetFtnIdxs().Count() && pAttr )
+    {
+        USHORT nVal = ((SwFmtFtnAtTxtEnd&)pAttr->Get(
+                                            RES_FTN_AT_TXTEND )).GetValue();
+           if( ( FTNEND_ATTXTEND_OWNNUMSEQ == nVal ||
+              FTNEND_ATTXTEND_OWNNUMANDFMT == nVal ) ||
+            ( FTNEND_ATTXTEND_OWNNUMSEQ == ( nVal = ((SwFmtEndAtTxtEnd&)
+                            pAttr->Get( RES_END_AT_TXTEND )).GetValue() ) ||
+              FTNEND_ATTXTEND_OWNNUMANDFMT == nVal ))
+            bUpdateFtn = TRUE;
+    }
+
+    if( pUndoInsSect )
+    {
+        pUndoInsSect->SetSectNdPos( pNewSectNode->GetIndex() );
+        pUndoInsSect->SetUpdtFtnFlag( bUpdateFtn );
+        DoUndo( TRUE );
+    }
+
+    if( rNew.IsLinkType() )
+        pNewSectNode->GetSection().CreateLink( bUpdate ? CREATE_UPDATE : CREATE_CONNECT );
+
+    if( bUpdateFtn )
+        GetFtnIdxs().UpdateFtn( SwNodeIndex( *pNewSectNode ));
+
+    SetModified();
+    return &pNewSectNode->GetSection();
+}
+
+USHORT SwDoc::IsInsRegionAvailable( const SwPaM& rRange,
+                                const SwNode** ppSttNd ) const
+{
+    USHORT nRet = 1;
+    if( rRange.HasMark() )
+    {
+        // teste ob es sich um eine gueltige Selektion handelt
+        const SwPosition* pStt = rRange.Start(),
+                        * pEnd = rRange.End();
+
+        const SwCntntNode* pCNd = pEnd->nNode.GetNode().GetCntntNode();
+        const SwNode* pNd = &pStt->nNode.GetNode();
+        const SwSectionNode* pSectNd = pNd->FindSectionNode();
+        const SwSectionNode* pEndSectNd = pCNd->FindSectionNode();
+        if( pSectNd && pEndSectNd && pSectNd != pCNd->FindSectionNode() )
+        {
+            // versuche eine umschliessende Section zu erzeugen
+            // Aber, nur wenn der Start am Sectionanfang und das Ende am
+            // Section Ende liegt!
+            nRet = 0;
+            if( !pStt->nContent.GetIndex() && pSectNd->GetIndex()
+                == pStt->nNode.GetIndex() - 1 && pEnd->nContent.GetIndex() ==
+                pCNd->Len() )
+            {
+                SwNodeIndex aIdx( pStt->nNode, -1 );
+                ULONG nCmp = pEnd->nNode.GetIndex();
+                const SwStartNode* pPrvNd;
+                const SwEndNode* pNxtNd;
+                while( 0 != ( pPrvNd = (pNd = &aIdx.GetNode())->GetSectionNode() ) &&
+                    !( aIdx.GetIndex() < nCmp &&
+                        nCmp < pPrvNd->EndOfSectionIndex() ) )
+                {
+                    aIdx--;
+                }
+                if( !pPrvNd )
+                    pPrvNd = pNd->IsStartNode() ? (SwStartNode*)pNd
+                                                : pNd->FindStartNode();
+
+                aIdx = pEnd->nNode.GetIndex() + 1;
+                nCmp = pStt->nNode.GetIndex();
+                while( 0 != ( pNxtNd = (pNd = &aIdx.GetNode())->GetEndNode() ) &&
+                    pNxtNd->FindStartNode()->IsSectionNode() &&
+                    !( pNxtNd->StartOfSectionIndex() < nCmp &&
+                        nCmp < aIdx.GetIndex() ) )
+                {
+                    aIdx++;
+                }
+                if( !pNxtNd )
+                    pNxtNd = pNd->EndOfSectionNode();
+
+                if( pPrvNd && pNxtNd && pPrvNd == pNxtNd->FindStartNode() )
+                {
+                    nRet = 3;
+
+                    if( ppSttNd )
+                        *ppSttNd = pPrvNd;
+                }
+            }
+        }
+        else if( !pSectNd && pEndSectNd )
+        {
+            // versuche eine umschliessende Section zu erzeugen
+            // Aber, nur wenn das Ende am Section Ende liegt!
+            nRet = 0;
+            if( pEnd->nContent.GetIndex() == pCNd->Len() )
+            {
+                SwNodeIndex aIdx( pEnd->nNode, 1 );
+                if( aIdx.GetNode().IsEndNode() &&
+                        0 != aIdx.GetNode().FindSectionNode() )
+                {
+                    do {
+                        aIdx++;
+                    } while( aIdx.GetNode().IsEndNode() &&
+                                0 != aIdx.GetNode().FindSectionNode() );
+//                  if( !aIdx.GetNode().IsEndNode() )
+                    {
+                        nRet = 2;
+                        if( ppSttNd )
+                        {
+                            aIdx--;
+                            *ppSttNd = &aIdx.GetNode();
+                        }
+                    }
+                }
+            }
+        }
+        else if( pSectNd && !pEndSectNd )
+        {
+            // versuche eine umschliessende Section zu erzeugen
+            // Aber, nur wenn der Start am Section Anfang liegt!
+            nRet = 0;
+            if( !pStt->nContent.GetIndex() )
+            {
+                SwNodeIndex aIdx( pStt->nNode, -1 );
+                if( aIdx.GetNode().IsSectionNode() )
+                {
+                    do {
+                        aIdx--;
+                    } while( aIdx.GetNode().IsSectionNode() );
+                    if( !aIdx.GetNode().IsSectionNode() )
+                    {
+                        nRet = 1;
+                        if( ppSttNd )
+                        {
+                            aIdx++;
+                            *ppSttNd = &aIdx.GetNode();
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return nRet;
+}
+
+SwSection* SwDoc::GetCurrSection( const SwPosition& rPos ) const
+{
+    const SwSectionNode* pSectNd = rPos.nNode.GetNode().FindSectionNode();
+    if( pSectNd )
+        return (SwSection*)&pSectNd->GetSection();
+    return 0;
+}
+
+SwSectionFmt* SwDoc::MakeSectionFmt( SwSectionFmt *pDerivedFrom )
+{
+    if( !pDerivedFrom )
+        pDerivedFrom = (SwSectionFmt*)pDfltFrmFmt;
+    SwSectionFmt* pNew = new SwSectionFmt( pDerivedFrom, this );
+    pSectionFmtTbl->Insert( pNew, pSectionFmtTbl->Count() );
+    return pNew;
+}
+
+void SwDoc::DelSectionFmt( SwSectionFmt *pFmt, BOOL bDelNodes )
+{
+    USHORT nPos = pSectionFmtTbl->GetPos( pFmt );
+    if( USHRT_MAX != nPos )
+    {
+        const SwNodeIndex* pIdx = pFmt->GetCntnt( FALSE ).GetCntntIdx();
+        const SfxPoolItem* pFtnEndAtTxtEnd;
+        if( SFX_ITEM_SET != pFmt->GetItemState(
+                            RES_FTN_AT_TXTEND, TRUE, &pFtnEndAtTxtEnd ) ||
+            SFX_ITEM_SET != pFmt->GetItemState(
+                            RES_END_AT_TXTEND, TRUE, &pFtnEndAtTxtEnd ))
+            pFtnEndAtTxtEnd = 0;
+
+        const SwSectionNode* pSectNd;
+
+        if( DoesUndo() )
+        {
+            ClearRedo();
+            if( bDelNodes && pIdx && &GetNodes() == &pIdx->GetNodes() &&
+                0 != (pSectNd = pIdx->GetNode().GetSectionNode() ))
+            {
+                SwNodeIndex aUpdIdx( *pIdx );
+                ClearRedo();
+                SwPaM aPaM( *pSectNd->EndOfSectionNode(), *pSectNd );
+                AppendUndo( new SwUndoDelete( aPaM ));
+                if( pFtnEndAtTxtEnd )
+                    GetFtnIdxs().UpdateFtn( aUpdIdx );
+                SetModified();
+                return ;
+            }
+            AppendUndo( new SwUndoDelSection( *pFmt ) );
+        }
+        else if( bDelNodes && pIdx && &GetNodes() == &pIdx->GetNodes() &&
+                0 != (pSectNd = pIdx->GetNode().GetSectionNode() ))
+        {
+            SwNodeIndex aUpdIdx( *pIdx );
+            DeleteSection( (SwNode*)pSectNd );
+            if( pFtnEndAtTxtEnd )
+                GetFtnIdxs().UpdateFtn( aUpdIdx );
+            SetModified();
+            return ;
+        }
+
+        {
+            SwPtrMsgPoolItem aMsgHint( RES_REMOVE_UNO_OBJECT, pFmt );
+            pFmt->Modify( &aMsgHint, &aMsgHint );
+        }
+
+        // ACHTUNG: erst aus dem Array entfernen und dann loeschen.
+        //          Der Section-DTOR versucht selbst noch sein Format
+        //          zu loeschen!
+        pSectionFmtTbl->Remove( nPos );
+//FEATURE::CONDCOLL
+        ULONG nCnt = 0, nSttNd = 0;
+        if( pIdx && &GetNodes() == &pIdx->GetNodes() &&
+            0 != (pSectNd = pIdx->GetNode().GetSectionNode() ))
+        {
+            nSttNd = pSectNd->GetIndex();
+            nCnt = pSectNd->EndOfSectionIndex() - nSttNd - 1;
+        }
+//FEATURE::CONDCOLL
+
+        delete pFmt;
+
+        if( nSttNd && pFtnEndAtTxtEnd )
+        {
+            SwNodeIndex aUpdIdx( GetNodes(), nSttNd );
+            GetFtnIdxs().UpdateFtn( aUpdIdx );
+        }
+
+//FEATURE::CONDCOLL
+        SwCntntNode* pCNd;
+        for( ; nCnt--; ++nSttNd )
+            if( 0 != (pCNd = GetNodes()[ nSttNd ]->GetCntntNode() ) &&
+                RES_CONDTXTFMTCOLL == pCNd->GetFmtColl()->Which() )
+                pCNd->ChkCondColl();
+//FEATURE::CONDCOLL
+    }
+    SetModified();
+}
+
+void SwDoc::ChgSection( USHORT nPos, const SwSection& rSect,
+                        const SfxItemSet* pAttr )
+{
+    SwSectionFmt* pFmt = (*pSectionFmtTbl)[ nPos ];
+    SwSection* pSection = pFmt->GetSection();
+
+    if( *pSection == rSect )
+    {
+        // die Attribute ueberpruefen
+        BOOL bOnlyAttrChg = FALSE;
+        if( pAttr && pAttr->Count() )
+        {
+            SfxItemIter aIter( *pAttr );
+            USHORT nWhich = aIter.GetCurItem()->Which();
+            while( TRUE )
+            {
+                if( pFmt->GetAttr( nWhich ) != *aIter.GetCurItem() )
+                {
+                    bOnlyAttrChg = TRUE;
+                    break;
+                }
+
+                if( aIter.IsAtEnd() )
+                    break;
+                nWhich = aIter.NextItem()->Which();
+            }
+        }
+
+        if( bOnlyAttrChg )
+        {
+            if( DoesUndo() )
+            {
+                ClearRedo();
+                AppendUndo( new SwUndoChgSection( *pFmt, TRUE ) );
+            }
+            pFmt->SetAttr( *pAttr );
+            SetModified();
+        }
+        return;
+    }
+
+    // Teste ob eine gesamte Content-Section (Dokument/TabellenBox/Fly)
+    // versteckt werden soll, koennen wir zur Zeit nicht !!!!
+    const SwNodeIndex* pIdx = 0;
+    {
+        const SwSectionNode* pSectNd;
+        if( rSect.IsHidden() && 0 != (pIdx = pFmt->GetCntnt().GetCntntIdx() )
+            && 0 != (pSectNd = pIdx->GetNode().GetSectionNode() ) )
+        {
+            ::lcl_CheckEmptyLayFrm( GetNodes(), (SwSection&)rSect,
+                                *pSectNd, *pSectNd->EndOfSectionNode() );
+        }
+    }
+
+
+    if( DoesUndo() )
+    {
+        ClearRedo();
+        AppendUndo( new SwUndoChgSection( *pFmt, FALSE ) );
+    }
+
+    // #56167# Der LinkFileName koennte auch nur aus Separatoren bestehen
+    String sCompareString = cTokenSeperator;
+    sCompareString += cTokenSeperator;
+    BOOL bUpdate = ( !pSection->IsLinkType() && rSect.IsLinkType() ) ||
+                        ( rSect.GetLinkFileName().Len() &&
+                            rSect.GetLinkFileName() != sCompareString &&
+                            rSect.GetLinkFileName() !=
+                            pSection->GetLinkFileName());
+
+    String sSectName( rSect.GetName() );
+    if( sSectName != pSection->GetName() )
+        GetUniqueSectionName( &sSectName );
+    else
+        sSectName.Erase();
+
+    *pSection = rSect;
+
+    if( pAttr )
+        pSection->GetFmt()->SetAttr( *pAttr );
+
+    if( sSectName.Len() )
+        pSection->SetName( sSectName );
+
+    // ist eine Condition gesetzt
+    if( pSection->IsHidden() && pSection->GetCondition().Len() )
+    {
+        // dann berechne bis zu dieser Position
+        SwCalc aCalc( *this );
+        if( !pIdx )
+            pIdx = pFmt->GetCntnt().GetCntntIdx();
+        FldsToCalc( aCalc, pIdx->GetIndex() );
+        pSection->SetCondHidden( aCalc.Calculate( pSection->GetCondition() ).GetBool() );
+    }
+
+    if( bUpdate )
+        pSection->CreateLink( CREATE_UPDATE );
+    else if( !pSection->IsLinkType() && pSection->IsConnected() )
+    {
+        pSection->Disconnect();
+        GetLinkManager().Remove( pSection->GetBaseLink() );
+    }
+
+    SetModified();
+}
+
+void SwDoc::ChgSectionPasswd( const String& sNew )
+{
+    if( DoesUndo() )
+    {
+        ClearRedo();
+        AppendUndo( new SwUndoChgSectPsswd( sSectionPasswd ) );
+    }
+
+    sSectionPasswd = sNew;
+    SetModified();
+}
+
+/* -----------------19.02.99 09:31-------------------
+ * LockFrms wurde im InsertSection genutzt, um zu verhindern, dass
+ * SectionFrms durch das DelFrms zerstoert werden. Dies ist durch
+ * den Destroy-Listen-Mechanismus ueberfluessig geworden.
+ * Falls diese Methode doch noch einmal reanimiert wird, bietet es
+ * sich vielleicht an, beim Entlocken die SectionFrms auf Inhalt zu
+ * pruefen und dann ggf. zur Zerstoerung anzumelden.
+ * --------------------------------------------------*/
+
+// und dann waren da noch die Fussnoten:
+void lcl_DeleteFtn( SwSectionNode *pNd, ULONG nStt, ULONG nEnd )
+{
+    SwFtnIdxs& rFtnArr = pNd->GetDoc()->GetFtnIdxs();
+    if( rFtnArr.Count() )
+    {
+        USHORT nPos;
+        rFtnArr.SeekEntry( SwNodeIndex( *pNd ), &nPos );
+        SwTxtFtn* pSrch;
+
+        // loesche erstmal alle, die dahinter stehen
+        while( nPos < rFtnArr.Count() &&
+            _SwTxtFtn_GetIndex( (pSrch = rFtnArr[ nPos ]) ) <= nEnd )
+        {
+            // Werden die Nodes nicht geloescht mussen sie bei den Seiten
+            // abmeldet (Frms loeschen) werden, denn sonst bleiben sie
+            // stehen (Undo loescht sie nicht!)
+            pSrch->DelFrms();
+            ++nPos;
+        }
+
+        while( nPos-- &&
+            _SwTxtFtn_GetIndex( (pSrch = rFtnArr[ nPos ]) ) >= nStt )
+        {
+            // Werden die Nodes nicht geloescht mussen sie bei den Seiten
+            // abmeldet (Frms loeschen) werden, denn sonst bleiben sie
+            // stehen (Undo loescht sie nicht!)
+            pSrch->DelFrms();
+        }
+    }
+}
+
+inline BOOL lcl_IsTOXSection( const SwSection& rSection )
+{
+    return TOX_CONTENT_SECTION == rSection.GetType() ||
+            TOX_HEADER_SECTION == rSection.GetType();
+}
+
+SwSectionNode* SwNodes::InsertSection( const SwNodeIndex& rNdIdx,
+                                SwSectionFmt& rSectionFmt,
+                                const SwSection& rSection,
+                                const SwNodeIndex* pEnde,
+                                BOOL bInsAtStart, BOOL bCreateFrms )
+{
+    SwNodeIndex aInsPos( rNdIdx );
+    if( !pEnde )        // kein Bereich also neue Section davor/hinter anlegen
+    {
+        if( bInsAtStart )
+        {
+            if( !lcl_IsTOXSection( rSection ))
+            {
+                do {
+                    aInsPos--;
+                } while( aInsPos.GetNode().IsSectionNode() );
+                aInsPos++;
+            }
+        }
+        else
+        {
+            SwNode* pNd;
+            aInsPos++;
+            if( !lcl_IsTOXSection( rSection ))
+                while( aInsPos.GetIndex() < Count() - 1 &&
+                        ( pNd = &aInsPos.GetNode())->IsEndNode() &&
+                        pNd->FindStartNode()->IsSectionNode())
+                    aInsPos++;
+        }
+    }
+
+    SwSectionNode* pSectNd = new SwSectionNode( aInsPos, rSectionFmt );
+    if( pEnde )
+    {
+        // Sonderfall fuer die Reader/Writer
+        if( &pEnde->GetNode() != &GetEndOfContent() )
+            aInsPos = pEnde->GetIndex()+1;
+    }
+    else
+    {
+        SwTxtNode* pCpyTNd = rNdIdx.GetNode().GetTxtNode();
+        if( pCpyTNd )
+        {
+            SwTxtNode* pTNd = new SwTxtNode( aInsPos, pCpyTNd->GetTxtColl() );
+            if( pCpyTNd->GetpSwAttrSet() )
+            {
+                // Task 70955 - move PageDesc/Break to the first Node of the
+                //              section
+                const SfxItemSet& rSet = *pCpyTNd->GetpSwAttrSet();
+                if( SFX_ITEM_SET == rSet.GetItemState( RES_BREAK ) ||
+                    SFX_ITEM_SET == rSet.GetItemState( RES_PAGEDESC ))
+                {
+                    SfxItemSet aSet( rSet );
+                    if( bInsAtStart )
+                        pCpyTNd->ResetAttr( RES_PAGEDESC, RES_BREAK );
+                    else
+                    {
+                        aSet.ClearItem( RES_PAGEDESC );
+                        aSet.ClearItem( RES_BREAK );
+                    }
+                    pTNd->SwCntntNode::SetAttr( aSet );
+                }
+                else
+                    pTNd->SwCntntNode::SetAttr( rSet );
+            }
+            // den Frame anlegen nicht vergessen !!
+            pCpyTNd->MakeFrms( *pTNd );
+        }
+        else
+            new SwTxtNode( aInsPos, (SwTxtFmtColl*)GetDoc()->GetDfltTxtFmtColl() );
+    }
+    SwEndNode* pEndNd = new SwEndNode( aInsPos, *pSectNd );
+
+    pSectNd->GetSection() = rSection;
+    SwSectionFmt* pSectFmt = pSectNd->GetSection().GetFmt();
+
+    // Hier bietet sich als Optimierung an, vorhandene Frames nicht zu
+    // zerstoeren und wieder neu anzulegen, sondern nur umzuhaengen.
+    BOOL bInsFrm = bCreateFrms && !pSectNd->GetSection().IsHidden() &&
+                   GetDoc()->GetRootFrm();
+    SwNode2Layout *pNode2Layout = NULL;
+    if( bInsFrm )
+    {
+        SwNodeIndex aTmp( *pSectNd );
+        if( !pSectNd->GetNodes().FindPrvNxtFrmNode( aTmp, pSectNd->EndOfSectionNode() ) )
+            // dann sammel mal alle Uppers ein
+            pNode2Layout = new SwNode2Layout( *pSectNd );
+    }
+
+    // jetzt noch bei allen im Bereich den richtigen StartNode setzen
+    ULONG nEnde = pSectNd->EndOfSectionIndex();
+    ULONG nStart = pSectNd->GetIndex()+1;
+    ULONG nSkipIdx = ULONG_MAX;
+    for( ULONG n = nStart; n < nEnde; ++n )
+    {
+        SwNode* pNd = (*this)[n];
+
+        //JP 30.04.99: Bug 65644 - alle in der NodeSection liegenden
+        //              Sections unter die neue haengen
+        if( ULONG_MAX == nSkipIdx )
+            pNd->pStartOfSection = pSectNd;
+        else if( n >= nSkipIdx )
+            nSkipIdx = ULONG_MAX;
+
+        if( pNd->IsStartNode() )
+        {
+            // die Verschachtelung der Formate herstellen!
+            if( pNd->IsSectionNode() )
+            {
+                ((SwSectionNode*)pNd)->GetSection().GetFmt()->
+                                    SetDerivedFrom( pSectFmt );
+                ((SwSectionNode*)pNd)->DelFrms();
+                n = pNd->EndOfSectionIndex();
+            }
+            else
+            {
+                if( pNd->IsTableNode() )
+                    ((SwTableNode*)pNd)->DelFrms();
+
+                if( ULONG_MAX == nSkipIdx )
+                    nSkipIdx = pNd->EndOfSectionIndex();
+            }
+        }
+        else if( pNd->IsCntntNode() )
+            ((SwCntntNode*)pNd)->DelFrms();
+    }
+
+    lcl_DeleteFtn( pSectNd, nStart, nEnde );
+
+    if( bInsFrm )
+    {
+        if( pNode2Layout )
+        {
+            ULONG nIdx = pSectNd->GetIndex();
+            pNode2Layout->RestoreUpperFrms( pSectNd->GetNodes(), nIdx, nIdx + 1 );
+            delete pNode2Layout;
+        }
+        else
+            pSectNd->MakeFrms( &aInsPos );
+    }
+
+    return pSectNd;
+}
+
+SwSectionNode* SwNode::FindSectionNode()
+{
+    if( IsSectionNode() )
+        return GetSectionNode();
+    SwStartNode* pTmp = pStartOfSection;
+    while( !pTmp->IsSectionNode() && pTmp->GetIndex() )
+#if defined( ALPHA ) && defined( UNX )
+        pTmp = ((SwNode*)pTmp)->pStartOfSection;
+#else
+        pTmp = pTmp->pStartOfSection;
+#endif
+    return pTmp->GetSectionNode();
+}
+
+
+//---------
+// SwSectionNode
+//---------
+
+SwSectionNode::SwSectionNode( const SwNodeIndex& rIdx, SwSectionFmt& rFmt )
+    : SwStartNode( rIdx, ND_SECTIONNODE )
+{
+    SwSectionNode* pParent = FindStartNode()->FindSectionNode();
+    if( pParent )
+    {
+        // das Format beim richtigen Parent anmelden.
+        rFmt.SetDerivedFrom( pParent->GetSection().GetFmt() );
+    }
+    pSection = new SwSection( CONTENT_SECTION, rFmt.GetName(), &rFmt );
+
+    // jetzt noch die Verbindung von Format zum Node setzen
+    // Modify unterdruecken, interresiert keinen
+    rFmt.LockModify();
+    rFmt.SetAttr( SwFmtCntnt( this ) );
+    rFmt.UnlockModify();
+}
+
+//Hier werden ueberfluessige SectionFrms entfernt
+SwFrm* SwClearDummies( SwFrm* pFrm )
+{
+    SwFrm* pTmp = pFrm;
+    while( pTmp )
+    {
+        ASSERT( !pTmp->GetUpper(), "SwClearDummies: No Upper allowed!" );
+        if( pTmp->IsSctFrm() )
+        {
+            SwSectionFrm* pSectFrm = (SwSectionFrm*)pFrm;
+            pTmp = pTmp->GetNext();
+            if( !pSectFrm->GetLower() )
+            {
+                if( pSectFrm->GetPrev() )
+                    pSectFrm->GetPrev()->pNext = pTmp;
+                else
+                    pFrm = pTmp;
+                if( pTmp )
+                    pTmp->pPrev = pSectFrm->GetPrev();
+                delete pSectFrm;
+            }
+        }
+        else
+            pTmp = pTmp->GetNext();
+    }
+    return pFrm;
+}
+
+SwSectionNode::~SwSectionNode()
+{
+    {
+        SwClientIter aIter( *(pSection->GetFmt()) );
+        SwClient *pLast = aIter.GoStart();
+        while ( pLast )
+        {
+            if ( pLast->IsA( TYPE(SwFrm) ) )
+            {
+                SwSectionFrm *pSectFrm = (SwSectionFrm*)pLast;
+                SwSectionFrm::MoveCntntAndDelete( pSectFrm, TRUE );
+                pLast = aIter.GoStart();
+            }
+            else
+                pLast = aIter++;
+        }
+    }
+    SwDoc* pDoc = GetDoc();
+
+    SwSectionFmt* pFmt = pSection->GetFmt();
+    if( pFmt )
+    {
+        // das Attribut entfernen, weil die Section ihr Format loescht
+        // und falls das Cntnt-Attribut vorhanden ist, die Section aufhebt.
+        pFmt->LockModify();
+        pFmt->ResetAttr( RES_CNTNT );
+        pFmt->UnlockModify();
+    }
+
+    BOOL bUndo = pDoc->DoesUndo();
+    // verhinder beim Loeschen aus der Undo/Redo-History einen rekursiven Aufruf
+    if( bUndo && &pDoc->GetNodes() != &GetNodes() )
+        pDoc->DoUndo( FALSE );
+    DELETEZ( pSection );
+    pDoc->DoUndo( bUndo );
+}
+
+// setze ein neues SectionObject. Erstmal nur gedacht fuer die
+// neuen VerzeichnisSections. Der geht ueber in den Besitz des Nodes!
+void SwSectionNode::SetNewSection( SwSection* pNewSection )
+{
+    ASSERT( pNewSection, "ohne Pointer geht hier nichts" );
+    if( pNewSection )
+    {
+        SwNode2Layout aN2L( *this );
+
+        // einige Flags sollten ueber nommen werden!
+        pNewSection->bProtectFlag = pSection->bProtectFlag;
+        pNewSection->bHiddenFlag = pSection->bHiddenFlag;
+        pNewSection->bHidden = pSection->bHidden;
+        pNewSection->bCondHiddenFlag = pSection->bCondHiddenFlag;
+
+        // The section frame contains a pointer to the section. That for,
+        // the frame must be destroyed before deleting the section.
+        DelFrms();
+
+        delete pSection;
+        pSection = pNewSection;
+
+        ULONG nIdx = GetIndex();
+        aN2L.RestoreUpperFrms( GetNodes(), nIdx, nIdx + 1 );
+    }
+}
+
+SwFrm *SwSectionNode::MakeFrm()
+{
+    pSection->bHiddenFlag = FALSE;
+    return new SwSectionFrm( *pSection );
+}
+
+//Methode erzeugt fuer den vorhergehenden Node alle Ansichten vom
+//Dokument. Die erzeugten Contentframes werden in das entsprechende
+//Layout gehaengt.
+void SwSectionNode::MakeFrms(const SwNodeIndex & rIdx )
+{
+    // also nehme meinen nachfolgenden oder vorhergehenden ContentFrame:
+    SwNodes& rNds = GetNodes();
+    if( rNds.IsDocNodes() && rNds.GetDoc()->GetRootFrm() )
+    {
+        if( GetSection().IsHidden() || IsCntntHidden() )
+        {
+            SwNodeIndex aIdx( *EndOfSectionNode() );
+            SwCntntNode* pCNd = rNds.GoNextSection( &aIdx, TRUE, FALSE );
+            if( !pCNd )
+            {
+                aIdx = *this;
+                if( 0 == ( pCNd = rNds.GoPrevSection( &aIdx, TRUE, FALSE )) )
+                    return ;
+            }
+            pCNd = rNds[ aIdx ]->GetCntntNode();
+            pCNd->MakeFrms( (SwCntntNode&)rIdx.GetNode() );
+        }
+        else
+        {
+            SwNode2Layout aNode2Layout( *this, rIdx.GetIndex() );
+            SwFrm *pFrm, *pNew;
+            while( 0 != (pFrm = aNode2Layout.NextFrm()) )
+            {
+                ASSERT( pFrm->IsSctFrm(), "Depend von Section keine Section." );
+                pNew = rIdx.GetNode().GetCntntNode()->MakeFrm();
+
+                SwSectionNode *pS = rIdx.GetNode().FindSectionNode();
+                // if the node is in a section, the sectionframe now
+                // has to be created..
+                if( pS )
+                {
+                    SwSectionFrm *pSct = new SwSectionFrm( pS->GetSection() );
+                    SwLayoutFrm* pUp = pSct;
+                    while( pUp->Lower() )  // for columned sections
+                    {
+                        ASSERT( pUp->Lower()->IsLayoutFrm(),"Who's in there?" );
+                        pUp = (SwLayoutFrm*)pUp->Lower();
+                    }
+                    pNew->Paste( pUp, NULL );
+                    pNew = pSct;
+                }
+
+                // wird ein Node vorher oder nachher mit Frames versehen
+                if ( rIdx < GetIndex() )
+                    // der neue liegt vor mir
+                    pNew->Paste( pFrm->GetUpper(), pFrm );
+                else
+                    // der neue liegt hinter mir
+                    pNew->Paste( pFrm->GetUpper(), pFrm->GetNext() );
+            }
+        }
+    }
+}
+
+//Fuer jedes vorkommen im Layout einen SectionFrm anlegen und vor den
+//entsprechenden CntntFrm pasten.
+
+void SwSectionNode::MakeFrms( SwNodeIndex* pIdxBehind, SwNodeIndex* pEndIdx )
+{
+    ASSERT( pIdxBehind, "kein Index" );
+    SwNodes& rNds = GetNodes();
+    SwDoc* pDoc = rNds.GetDoc();
+
+    *pIdxBehind = *this;
+
+    pSection->bHiddenFlag = TRUE;
+
+    if( rNds.IsDocNodes() )
+    {
+        SwNodeIndex *pEnd = pEndIdx ? pEndIdx :
+                            new SwNodeIndex( *EndOfSectionNode(), 1 );
+        ::MakeFrms( pDoc, *pIdxBehind, *pEnd );
+        if( !pEndIdx )
+            delete pEnd;
+    }
+
+}
+
+void SwSectionNode::DelFrms()
+{
+    ULONG nStt = GetIndex()+1, nEnd = EndOfSectionIndex();
+    if( nStt >= nEnd )
+    {
+        // unser Flag muessen wir noch aktualisieren
+        // pSection->bHiddenFlag = TRUE;
+        return ;
+    }
+
+    SwNodes& rNds = GetNodes();
+    pSection->GetFmt()->DelFrms();
+
+    // unser Flag muessen wir noch aktualisieren
+    pSection->bHiddenFlag = TRUE;
+
+    // Bug 30582: falls der Bereich in Fly oder TabellenBox ist, dann
+    //              kann er nur "gehiddet" werden, wenn weiterer Content
+    //              vorhanden ist, der "Frames" haelt. Sonst hat der
+    //              Fly/TblBox-Frame keinen Lower !!!
+    {
+        SwNodeIndex aIdx( *this );
+        if( !rNds.GoPrevSection( &aIdx, TRUE, FALSE ) ||
+            !CheckNodesRange( *this, aIdx, TRUE ) ||
+            !lcl_IsInSameTblBox( rNds, *this, aIdx ))
+        {
+            aIdx = *EndOfSectionNode();
+            if( !rNds.GoNextSection( &aIdx, TRUE, FALSE ) ||
+                !CheckNodesRange( *EndOfSectionNode(), aIdx, TRUE ) ||
+                !lcl_IsInSameTblBox( rNds, *EndOfSectionNode(), aIdx ))
+                pSection->bHiddenFlag = FALSE;
+        }
+    }
+}
+
+SwSectionNode* SwSectionNode::MakeCopy( SwDoc* pDoc, const SwNodeIndex& rIdx ) const
+{
+    // in welchen Array steht ich denn: Nodes, UndoNodes ??
+    const SwNodes& rNds = GetNodes();
+
+    // das SectionFrmFmt kopieren
+    SwSectionFmt* pSectFmt = pDoc->MakeSectionFmt( 0 );
+    pSectFmt->CopyAttrs( *GetSection().GetFmt() );
+
+    SwSectionNode* pSectNd = new SwSectionNode( rIdx, *pSectFmt );
+    SwEndNode* pEndNd = new SwEndNode( rIdx, *pSectNd );
+    SwNodeIndex aInsPos( *pEndNd );
+
+    // Werte uebertragen
+    SwSection* pNewSect = pSectNd->pSection;
+
+    switch( GetSection().GetType() )
+    {
+    case TOX_CONTENT_SECTION:
+        {
+            ASSERT( GetSection().ISA( SwTOXBaseSection ), "keine TOXBaseSection!" );
+            SwTOXBaseSection& rTOXSect = (SwTOXBaseSection&)GetSection();
+            SwTOXBase aTmp( rTOXSect, pDoc );
+
+            SwTOXBaseSection* pNew = new SwTOXBaseSection( aTmp );
+
+            pNewSect = pNew;
+            pSectFmt->Add( pNewSect );
+            pSectNd->SetNewSection( pNew );
+        }
+        break;
+
+    default:
+        // beim Move den Namen beibehalten
+        if( rNds.GetDoc() == pDoc && pDoc->IsCopyIsMove() )
+            pNewSect->SetName( GetSection().GetName() );
+        else
+            pNewSect->SetName( pDoc->GetUniqueSectionName(
+                                        &GetSection().GetName() ) );
+        break;
+    }
+
+
+    pNewSect->SetType( GetSection().GetType() );
+    pNewSect->SetCondition( GetSection().GetCondition() );
+    pNewSect->SetLinkFileName( GetSection().GetLinkFileName() );
+    if( !pNewSect->IsHiddenFlag() && GetSection().IsHidden() )
+        pNewSect->SetHidden( TRUE );
+    if( !pNewSect->IsProtectFlag() && GetSection().IsProtect() )
+        pNewSect->SetProtect( TRUE );
+
+    SwNodeRange aRg( *this, +1, *EndOfSectionNode() );  // (wo stehe in denn nun ??)
+    rNds._Copy( aRg, aInsPos, FALSE );
+
+    // loesche alle Frames vom kopierten Bereich, diese werden beim
+    // erzeugen des SectionFrames angelegt !
+    pSectNd->DelFrms();
+
+    // dann kopiere auch noch die Links/Server
+    if( pNewSect->IsLinkType() )        // den Link eintragen
+        pNewSect->CreateLink( pDoc->GetRootFrm() ? CREATE_CONNECT
+                                                 : CREATE_NONE );
+
+    // falls als Server aus dem Undo kopiert wird, wieder eintragen
+    if( pSection->IsServer() && pDoc->GetUndoNds() == &rNds )
+    {
+        pNewSect->SetRefObject( pSection->GetObject() );
+        pDoc->GetLinkManager().InsertServer( pNewSect->GetObject() );
+    }
+
+    return pSectNd;
+}
+
+BOOL SwSectionNode::IsCntntHidden() const
+{
+    ASSERT( !pSection->IsHidden(), "That's simple: Hidden Section => Hidden Content" );
+    SwNodeIndex aTmp( *this, 1 );
+    ULONG nEnd = EndOfSectionIndex();
+    while( aTmp < nEnd )
+    {
+        if( aTmp.GetNode().IsSectionNode() )
+        {
+            const SwSection& rSect = ((SwSectionNode&)aTmp.GetNode()).GetSection();
+            if( rSect.IsHiddenFlag() )
+                // dann diese Section ueberspringen
+                aTmp = *aTmp.GetNode().EndOfSectionNode();
+        }
+        else
+        {
+            if( aTmp.GetNode().IsCntntNode() || aTmp.GetNode().IsTableNode() )
+                return FALSE; // Nicht versteckter Inhalt wurde gefunden
+            ASSERT( aTmp.GetNode().IsEndNode(), "EndNode expected" );
+        }
+        aTmp++;
+    }
+    return TRUE; // Alles versteckt
+}
+
+
+void SwSectionNode::NodesArrChgd()
+{
+    SwSectionFmt* pFmt = pSection->GetFmt();
+    if( pFmt )
+    {
+        SwNodes& rNds = GetNodes();
+        SwDoc* pDoc = pFmt->GetDoc();
+
+        if( !rNds.IsDocNodes() )
+        {
+            SwPtrMsgPoolItem aMsgHint( RES_REMOVE_UNO_OBJECT, pFmt );
+            pFmt->Modify( &aMsgHint, &aMsgHint );
+        }
+
+        pFmt->LockModify();
+        pFmt->SetAttr( SwFmtCntnt( this ));
+        pFmt->UnlockModify();
+
+        SwSectionNode* pSectNd = FindStartNode()->FindSectionNode();
+        // set the correct parent from the new section
+        pFmt->SetDerivedFrom( pSectNd ? pSectNd->GetSection().GetFmt()
+                                      : pDoc->GetDfltFrmFmt() );
+
+        // jetzt noch bei allen im Bereich den richtigen StartNode setzen
+        ULONG nStart = GetIndex()+1, nEnde = EndOfSectionIndex();
+        for( ULONG n = nStart; n < nEnde; ++n )
+            // die Verschachtelung der Formate herstellen!
+            if( 0 != ( pSectNd = rNds[ n ]->GetSectionNode() ) )
+            {
+                pSectNd->GetSection().GetFmt()->SetDerivedFrom( pFmt );
+                n = pSectNd->EndOfSectionIndex();
+            }
+
+        // verschieben vom Nodes- ins UndoNodes-Array?
+        if( rNds.IsDocNodes() )
+        {
+            ASSERT( pDoc == GetDoc(),
+                    "verschieben in unterschiedliche Documente?" );
+            if( pSection->IsLinkType() )        // den Link austragen
+                pSection->CreateLink( pDoc->GetRootFrm() ? CREATE_CONNECT
+                                                         : CREATE_NONE );
+
+            if( pSection->IsServer() )                  // als Server austragen
+                pDoc->GetLinkManager().InsertServer( pSection->GetObject() );
+        }
+        else
+        {
+            if( CONTENT_SECTION != pSection->GetType() )        // den Link austragen
+                pDoc->GetLinkManager().Remove( pSection->GetBaseLink() );
+
+            if( pSection->IsServer() )                  // als Server austragen
+                pDoc->GetLinkManager().RemoveServer( pSection->GetObject() );
+        }
+    }
+}
+
+
+String SwDoc::GetUniqueSectionName( const String* pChkStr ) const
+{
+    ResId aId( STR_REGION_DEFNAME, pSwResMgr );
+    String aName( aId );
+    xub_StrLen nNmLen = aName.Len();
+
+    USHORT nNum, nTmp, nFlagSize = ( pSectionFmtTbl->Count() / 8 ) +2;
+    BYTE* pSetFlags = new BYTE[ nFlagSize ];
+    memset( pSetFlags, 0, nFlagSize );
+
+    const SwSectionNode* pSectNd;
+    for( USHORT n = 0; n < pSectionFmtTbl->Count(); ++n )
+        if( 0 != ( pSectNd = (*pSectionFmtTbl)[ n ]->GetSectionNode( FALSE ) ))
+        {
+            const String& rNm = pSectNd->GetSection().GetName();
+            if( rNm.Match( aName ) == nNmLen )
+            {
+                // Nummer bestimmen und das Flag setzen
+                nNum = rNm.Copy( nNmLen ).ToInt32();
+                if( nNum-- && nNum < pSectionFmtTbl->Count() )
+                    pSetFlags[ nNum / 8 ] |= (0x01 << ( nNum & 0x07 ));
+            }
+            if( pChkStr && pChkStr->Equals( rNm ) )
+                pChkStr = 0;
+        }
+
+    if( !pChkStr )
+    {
+        // alle Nummern entsprechend geflag, also bestimme die richtige Nummer
+        nNum = pSectionFmtTbl->Count();
+        for( n = 0; n < nFlagSize; ++n )
+            if( 0xff != ( nTmp = pSetFlags[ n ] ))
+            {
+                // also die Nummer bestimmen
+                nNum = n * 8;
+                while( nTmp & 1 )
+                    ++nNum, nTmp >>= 1;
+                break;
+            }
+
+    }
+    __DELETE( nFlagSize ) pSetFlags;
+    if( pChkStr )
+        return *pChkStr;
+    return aName += String::CreateFromInt32( ++nNum );
+}
+
+
diff --git a/sw/source/core/docnode/ndtbl.cxx b/sw/source/core/docnode/ndtbl.cxx
new file mode 100644
index 000000000000..d4c6dbcc2fe0
--- /dev/null
+++ b/sw/source/core/docnode/ndtbl.cxx
@@ -0,0 +1,3824 @@
+/*************************************************************************
+ *
+ *  $RCSfile: ndtbl.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:17 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#define ITEMID_BOXINFO      SID_ATTR_BORDER_INNER
+#ifdef WTC
+#define private public
+#endif
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BRKITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_PROTITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BOXITEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _FMTFSIZE_HXX //autogen
+#include 
+#endif
+#ifndef _FMTORNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFORDR_HXX //autogen
+#include 
+#endif
+#ifndef _FMTPDSC_HXX //autogen
+#include 
+#endif
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _FMTLSPLT_HXX
+#include 
+#endif
+#ifndef _FRMATR_HXX
+#include 
+#endif
+#ifndef _CHARATR_HXX
+#include 
+#endif
+#ifndef _CELLFRM_HXX //autogen
+#include 
+#endif
+#ifndef _TABCOL_HXX //autogen
+#include 
+#endif
+
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _CNTFRM_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _SWCRSR_HXX
+#include 
+#endif
+#ifndef _VISCRS_HXX
+#include 
+#endif
+#ifndef _SWTABLE_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _HINTS_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include 
+#endif
+#ifndef _TBLSEL_HXX
+#include 
+#endif
+#ifndef _FLDBAS_HXX
+#include 
+#endif
+#ifndef _POOLFMT_HXX
+#include 
+#endif
+#ifndef _TABFRM_HXX
+#include 
+#endif
+#ifndef _UNDOBJ_HXX
+#include 
+#endif
+#ifndef _TBLAFMT_HXX
+#include 
+#endif
+#ifndef _SWCACHE_HXX
+#include 
+#endif
+#ifndef _DDEFLD_HXX
+#include 
+#endif
+#ifndef _FRMINF_HXX
+#include 
+#endif
+#ifndef _CELLATR_HXX
+#include 
+#endif
+#ifndef _SWTBLFMT_HXX
+#include 
+#endif
+#ifndef _SWDDETBL_HXX
+#include 
+#endif
+#ifndef _MVSAVE_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _NDINDEX_HXX
+#include 
+#endif
+#ifndef _REDLINE_HXX
+#include 
+#endif
+#ifndef _ROLBCK_HXX
+#include 
+#endif
+#ifndef _TBLRWCL_HXX
+#include 
+#endif
+#ifndef _EDITSH_HXX
+#include 
+#endif
+#ifndef _TXTFRM_HXX
+#include 
+#endif
+#ifndef _FTNFRM_HXX
+#include 
+#endif
+#ifndef _ITABENUM_HXX
+#include 
+#endif
+#ifndef _SECTION_HXX //autogen
+#include 
+#endif
+#ifndef _FRMTOOL_HXX //autogen
+#include 
+#endif
+
+#ifndef _NODE2LAY_HXX
+#include 
+#endif
+
+#ifndef _COMCORE_HRC
+#include 
+#endif
+
+#ifdef LINUX
+#ifndef _TABCOL_HXX
+#include 
+#endif
+#endif
+
+const sal_Unicode T2T_PARA = 0x0a;
+
+extern void ClearFEShellTabCols();
+
+// steht im gctable.cxx
+extern BOOL lcl_GC_Line_Border( const SwTableLine*& , void* pPara );
+
+class lcl_DelRedlines
+{
+    SwDoc* pDoc;
+public:
+    lcl_DelRedlines( const SwTableNode& rNd )
+        : pDoc( (SwDoc*)rNd.GetNodes().GetDoc() )
+    {
+        pDoc->StartUndo();
+        if( !pDoc->IsIgnoreRedline() && pDoc->GetRedlineTbl().Count() )
+            pDoc->DeleteRedline( rNd );
+    }
+    lcl_DelRedlines( SwPaM& rPam )
+        : pDoc( rPam.GetDoc() )
+    {
+        pDoc->StartUndo();
+        if( !pDoc->IsIgnoreRedline() && pDoc->GetRedlineTbl().Count() )
+            pDoc->DeleteRedline( rPam );
+    }
+
+    ~lcl_DelRedlines() { pDoc->EndUndo(); }
+};
+
+
+void lcl_SetDfltBoxAttr( SwFrmFmt& rFmt, BYTE nId )
+{
+    BOOL bTop = FALSE, bBottom = FALSE, bLeft = FALSE, bRight = FALSE;
+    switch ( nId )
+    {
+    case 0: bTop = bBottom = bLeft = TRUE;          break;
+    case 1: bTop = bBottom = bLeft = bRight = TRUE; break;
+    case 2: bBottom = bLeft = TRUE;                 break;
+    case 3: bBottom = bLeft = bRight = TRUE;        break;
+    }
+
+    const BOOL bHTML = rFmt.GetDoc()->IsHTMLMode();
+    Color aCol( bHTML ? COL_GRAY : COL_BLACK );
+    SvxBorderLine aLine( &aCol, DEF_LINE_WIDTH_0 );
+    if ( bHTML )
+    {
+        aLine.SetOutWidth( DEF_DOUBLE_LINE7_OUT );
+        aLine.SetInWidth ( DEF_DOUBLE_LINE7_IN  );
+        aLine.SetDistance( DEF_DOUBLE_LINE7_DIST);
+    }
+    SvxBoxItem aBox; aBox.SetDistance( 55 );
+    if ( bTop )
+        aBox.SetLine( &aLine, BOX_LINE_TOP );
+    if ( bBottom )
+        aBox.SetLine( &aLine, BOX_LINE_BOTTOM );
+    if ( bLeft )
+        aBox.SetLine( &aLine, BOX_LINE_LEFT );
+    if ( bRight )
+        aBox.SetLine( &aLine, BOX_LINE_RIGHT );
+    rFmt.SetAttr( aBox );
+}
+
+void lcl_SetDfltBoxAttr( SwTableBox& rBox, SvPtrarr &rBoxFmtArr, BYTE nId,
+                            const SwTableAutoFmt* pAutoFmt = 0 )
+{
+    SvPtrarr* pArr = (SvPtrarr*)rBoxFmtArr[ nId ];
+    if( !pArr )
+    {
+        pArr = new SvPtrarr;
+        rBoxFmtArr.Replace( pArr, nId );
+    }
+
+    SwTableBoxFmt* pNewBoxFmt = 0;
+    SwFrmFmt* pBoxFmt = rBox.GetFrmFmt();
+    for( USHORT n = 0; n < pArr->Count(); n += 2 )
+        if( pArr->GetObject( n ) == pBoxFmt )
+        {
+            pNewBoxFmt = (SwTableBoxFmt*)pArr->GetObject( n + 1 );
+            break;
+        }
+
+    if( !pNewBoxFmt )
+    {
+        SwDoc* pDoc = pBoxFmt->GetDoc();
+        // das Format ist also nicht vorhanden, also neu erzeugen
+        pNewBoxFmt = pDoc->MakeTableBoxFmt();
+        pNewBoxFmt->SetAttr( pBoxFmt->GetAttrSet().Get( RES_FRM_SIZE ) );
+
+        if( pAutoFmt )
+            pAutoFmt->UpdateToSet( nId, (SfxItemSet&)pNewBoxFmt->GetAttrSet(),
+                                    SwTableAutoFmt::UPDATE_BOX,
+                                    pDoc->GetNumberFormatter( TRUE ) );
+        else
+            ::lcl_SetDfltBoxAttr( *pNewBoxFmt, nId );
+
+        void* p = pBoxFmt;
+        pArr->Insert( p, pArr->Count() );
+        p = pNewBoxFmt;
+        pArr->Insert( p, pArr->Count() );
+    }
+    rBox.ChgFrmFmt( pNewBoxFmt );
+}
+
+SwTableBoxFmt *lcl_CreateDfltBoxFmt( SwDoc &rDoc, SvPtrarr &rBoxFmtArr,
+                                    USHORT nCols, BYTE nId )
+{
+    if ( !rBoxFmtArr[nId] )
+    {
+        SwTableBoxFmt* pBoxFmt = rDoc.MakeTableBoxFmt();
+        if( USHRT_MAX != nCols )
+            pBoxFmt->SetAttr( SwFmtFrmSize( ATT_VAR_SIZE,
+                                            USHRT_MAX / nCols, 0 ));
+        ::lcl_SetDfltBoxAttr( *pBoxFmt, nId );
+        rBoxFmtArr.Replace( pBoxFmt, nId );
+    }
+    return (SwTableBoxFmt*)rBoxFmtArr[nId];
+}
+
+SwTableBoxFmt *lcl_CreateAFmtBoxFmt( SwDoc &rDoc, SvPtrarr &rBoxFmtArr,
+                                    const SwTableAutoFmt& rAutoFmt,
+                                    USHORT nCols, BYTE nId )
+{
+    if( !rBoxFmtArr[nId] )
+    {
+        SwTableBoxFmt* pBoxFmt = rDoc.MakeTableBoxFmt();
+        rAutoFmt.UpdateToSet( nId, (SfxItemSet&)pBoxFmt->GetAttrSet(),
+                                SwTableAutoFmt::UPDATE_BOX,
+                                rDoc.GetNumberFormatter( TRUE ) );
+        if( USHRT_MAX != nCols )
+            pBoxFmt->SetAttr( SwFmtFrmSize( ATT_VAR_SIZE,
+                                            USHRT_MAX / nCols, 0 ));
+        rBoxFmtArr.Replace( pBoxFmt, nId );
+    }
+    return (SwTableBoxFmt*)rBoxFmtArr[nId];
+}
+
+SwTableNode* SwDoc::IsIdxInTbl(const SwNodeIndex& rIdx)
+{
+    SwTableNode* pTableNd = 0;
+    ULONG nIndex = rIdx.GetIndex();
+    do {
+        SwNode* pNd = (SwNode*)GetNodes()[ nIndex ]->StartOfSectionNode();
+        if( 0 != ( pTableNd = pNd->GetTableNode() ) )
+            break;
+
+        nIndex = pNd->GetIndex();
+    } while ( nIndex );
+    return pTableNd;
+}
+
+
+// --------------- einfuegen einer neuen Box --------------
+
+    // fuege in der Line, vor der InsPos eine neue Box ein.
+
+BOOL SwNodes::InsBoxen( SwTableNode* pTblNd,
+                        SwTableLine* pLine,
+                        SwTableBoxFmt* pBoxFmt,
+                        SwTxtFmtColl* pTxtColl,
+                        SwAttrSet* pAutoAttr,
+                        USHORT nInsPos,
+                        USHORT nCnt )
+{
+    if( !nCnt )
+        return FALSE;
+    ASSERT( pLine, "keine gueltige Zeile" );
+
+    // Index hinter die letzte Box der Line
+    ULONG nIdxPos;
+    SwTableBox *pPrvBox = 0, *pNxtBox = 0;
+    if( pLine->GetTabBoxes().Count() )
+    {
+        if( nInsPos < pLine->GetTabBoxes().Count() )
+        {
+            if( 0 == (pPrvBox = pLine->FindPreviousBox( pTblNd->GetTable(),
+                            pLine->GetTabBoxes()[ nInsPos ] )))
+                pPrvBox = pLine->FindPreviousBox( pTblNd->GetTable() );
+        }
+        else if( 0 == ( pNxtBox = pLine->FindNextBox( pTblNd->GetTable(),
+                            pLine->GetTabBoxes()[ nInsPos-1 ] )))
+                pNxtBox = pLine->FindNextBox( pTblNd->GetTable() );
+    }
+    else if( 0 == ( pNxtBox = pLine->FindNextBox( pTblNd->GetTable() )))
+        pPrvBox = pLine->FindPreviousBox( pTblNd->GetTable() );
+
+    if( !pPrvBox && !pNxtBox )
+    {
+        BOOL bSetIdxPos = TRUE;
+        if( pTblNd->GetTable().GetTabLines().Count() && !nInsPos )
+        {
+            const SwTableLine* pTblLn = pLine;
+            while( pTblLn->GetUpper() )
+                pTblLn = pTblLn->GetUpper()->GetUpper();
+
+            if( pTblNd->GetTable().GetTabLines()[ 0 ] == pTblLn )
+            {
+                // also vor die erste Box der Tabelle
+                while( ( pNxtBox = pLine->GetTabBoxes()[0])->GetTabLines().Count() )
+                    pLine = pNxtBox->GetTabLines()[0];
+                nIdxPos = pNxtBox->GetSttIdx();
+                bSetIdxPos = FALSE;
+            }
+        }
+        if( bSetIdxPos )
+            // Tabelle ohne irgendeinen Inhalt oder am Ende, also vors Ende
+            nIdxPos = pTblNd->EndOfSectionIndex();
+    }
+    else if( pNxtBox )          // es gibt einen Nachfolger
+        nIdxPos = pNxtBox->GetSttIdx();
+    else                        // es gibt einen Vorgaenger
+        nIdxPos = pPrvBox->GetSttNd()->EndOfSectionIndex() + 1;
+
+    SwNodeIndex aEndIdx( *this, nIdxPos );
+    for( USHORT n = 0; n < nCnt; ++n )
+    {
+        SwStartNode* pSttNd = new SwStartNode( aEndIdx, ND_STARTNODE,
+                                                SwTableBoxStartNode );
+        pSttNd->pStartOfSection = pTblNd;
+        SwEndNode* pEndNd = new SwEndNode( aEndIdx, *pSttNd );
+
+        pPrvBox = new SwTableBox( pBoxFmt, *pSttNd, pLine );
+        pLine->GetTabBoxes().C40_INSERT( SwTableBox, pPrvBox, nInsPos + n );
+
+        if( NO_NUMBERING == pTxtColl->GetOutlineLevel()
+//FEATURE::CONDCOLL
+            && RES_CONDTXTFMTCOLL != pTxtColl->Which()
+//FEATURE::CONDCOLL
+        )
+            new SwTxtNode( SwNodeIndex( *pSttNd->EndOfSectionNode() ),
+                                pTxtColl, pAutoAttr );
+        else
+        {
+            // Outline-Numerierung richtig behandeln !!!
+            SwTxtNode* pTNd = new SwTxtNode(
+                            SwNodeIndex( *pSttNd->EndOfSectionNode() ),
+                            (SwTxtFmtColl*)GetDoc()->GetDfltTxtFmtColl(),
+                            pAutoAttr );
+            pTNd->ChgFmtColl( pTxtColl );
+        }
+    }
+    return TRUE;
+}
+
+// --------------- einfuegen einer neuen Tabelle --------------
+
+const SwTable* SwDoc::InsertTable( const SwPosition& rPos, USHORT nRows,
+                                    USHORT nCols, SwHoriOrient eAdjust,
+                                    USHORT nInsTblFlags,
+                                    const SwTableAutoFmt* pTAFmt,
+                                    const SvUShorts* pColArr )
+{
+    ASSERT( nRows, "Tabelle ohne Zeile?" );
+    ASSERT( nCols, "Tabelle ohne Spalten?" );
+
+    {
+        // nicht in Fussnoten kopieren !!
+        if( rPos.nNode < GetNodes().GetEndOfInserts().GetIndex() &&
+            rPos.nNode >= GetNodes().GetEndOfInserts().StartOfSectionIndex() )
+            return 0;
+
+        // sollte das ColumnArray die falsche Anzahl haben wird es ignoriert!
+        if( pColArr &&
+            (nCols + ( HORI_NONE == eAdjust ? 2 : 1 )) != pColArr->Count() )
+            pColArr = 0;
+    }
+
+    if( DoesUndo() )
+    {
+        ClearRedo();
+        AppendUndo( new SwUndoInsTbl( rPos, nCols, nRows, eAdjust,
+                                        nInsTblFlags, pTAFmt, pColArr ));
+    }
+
+    // fuege erstmal die Nodes ein
+    // hole das Auto-Format fuer die Tabelle
+    SwTxtFmtColl *pBodyColl = GetTxtCollFromPool( RES_POOLCOLL_TABLE ),
+                 *pHeadColl = pBodyColl;
+
+    BOOL bDfltBorders = nInsTblFlags & DEFAULT_BORDER;
+
+    if( (nInsTblFlags & HEADLINE) && (1 != nRows || !bDfltBorders) )
+        pHeadColl = GetTxtCollFromPool( RES_POOLCOLL_TABLE_HDLN );
+
+    SwTableNode *pTblNd = GetNodes().InsertTable( rPos.nNode, nCols,
+                                                pBodyColl, nRows, pHeadColl );
+
+    // dann erstelle die Box/Line/Table-Struktur
+    SwTableLineFmt* pLineFmt = MakeTableLineFmt();
+    SwTableFmt* pTableFmt = MakeTblFrmFmt( GetUniqueTblName(), GetDfltFrmFmt() );
+
+    //Orientation am Fmt der Table setzen
+    pTableFmt->SetAttr( SwFmtHoriOrient( 0, eAdjust ) );
+    // alle Zeilen haben die Fill-Order von links nach rechts !
+    pLineFmt->SetAttr( SwFmtFillOrder( ATT_LEFT_TO_RIGHT ));
+
+    // die Tabelle bekommt USHRT_MAX als default SSize
+    SwTwips nWidth = USHRT_MAX;
+    if( pColArr )
+    {
+        USHORT nSttPos = (*pColArr)[ 0 ];
+        USHORT nLastPos = (*pColArr)[ USHORT(pColArr->Count()-1)];
+        if( HORI_NONE == eAdjust )
+        {
+            USHORT nFrmWidth = nLastPos;
+            nLastPos = (*pColArr)[ USHORT(pColArr->Count()-2)];
+            pTableFmt->SetAttr( SvxLRSpaceItem( nSttPos, nFrmWidth - nLastPos ) );
+        }
+        nWidth = nLastPos - nSttPos;
+    }
+    pTableFmt->SetAttr( SwFmtFrmSize( ATT_VAR_SIZE, nWidth ));
+    if( !(nInsTblFlags & SPLIT_LAYOUT) )
+        pTableFmt->SetAttr( SwFmtLayoutSplit( FALSE ));
+
+    // verschiebe ggfs. die harten PageDesc/PageBreak Attribute:
+    SwCntntNode* pNextNd = GetNodes()[ pTblNd->EndOfSectionIndex()+1 ]
+                            ->GetCntntNode();
+    if( pNextNd && pNextNd->GetpSwAttrSet() )
+    {
+        SwAttrSet* pNdSet = pNextNd->GetpSwAttrSet();
+        const SfxPoolItem *pItem;
+        if( SFX_ITEM_SET == pNdSet->GetItemState( RES_PAGEDESC, FALSE,
+            &pItem ) )
+        {
+            pTableFmt->SetAttr( *pItem );
+            pNextNd->ResetAttr( RES_PAGEDESC );
+            pNdSet = pNextNd->GetpSwAttrSet();
+        }
+        if( pNdSet && SFX_ITEM_SET == pNdSet->GetItemState( RES_BREAK, FALSE,
+             &pItem ) )
+        {
+            pTableFmt->SetAttr( *pItem );
+            pNextNd->ResetAttr( RES_BREAK );
+        }
+    }
+
+    SwTable * pNdTbl = &pTblNd->GetTable();
+    pTableFmt->Add( pNdTbl );       // das Frame-Format setzen
+
+    pNdTbl->SetHeadlineRepeat( HEADLINE_REPEAT == (nInsTblFlags & HEADLINE_REPEAT) );
+
+    SvPtrarr aBoxFmtArr( 0, 16 );
+    SwTableBoxFmt* pBoxFmt = 0;
+    if( !bDfltBorders && !pTAFmt )
+    {
+        pBoxFmt = MakeTableBoxFmt();
+        pBoxFmt->SetAttr( SwFmtFrmSize( ATT_VAR_SIZE, USHRT_MAX / nCols, 0 ));
+    }
+    else
+    {
+        const USHORT nBoxArrLen = pTAFmt ? 16 : 4;
+        for( USHORT i = 0; i < nBoxArrLen; ++i )
+            aBoxFmtArr.Insert( (void*)0, i );
+    }
+    SfxItemSet aCharSet( GetAttrPool(), RES_CHRATR_BEGIN, RES_PARATR_END-1 );
+
+    SwNodeIndex aNdIdx( *pTblNd, 1 );   // auf den ersten Box-StartNode
+    SwTableLines& rLines = pNdTbl->GetTabLines();
+    for( USHORT n = 0; n < nRows; ++n )
+    {
+        SwTableLine* pLine = new SwTableLine( pLineFmt, nCols, 0 );
+        rLines.C40_INSERT( SwTableLine, pLine, n );
+        SwTableBoxes& rBoxes = pLine->GetTabBoxes();
+        for( USHORT i = 0; i < nCols; ++i )
+        {
+            SwTableBoxFmt *pBoxF;
+            if( pTAFmt )
+            {
+                BYTE nId = !n ? 0 : (( n+1 == nRows )
+                                        ? 12 : (4 * (1 + ((n-1) & 1 ))));
+                nId += !i ? 0 : ( i+1 == nCols ? 3 : (1 + ((i-1) & 1)));
+                pBoxF = ::lcl_CreateAFmtBoxFmt( *this, aBoxFmtArr, *pTAFmt,
+                                                nCols, nId );
+
+                // ggfs. noch die Absatz/ZeichenAttribute setzen
+                if( pTAFmt->IsFont() || pTAFmt->IsJustify() )
+                {
+                    aCharSet.ClearItem();
+                    pTAFmt->UpdateToSet( nId, aCharSet,
+                                        SwTableAutoFmt::UPDATE_CHAR, 0 );
+                    if( aCharSet.Count() )
+                        GetNodes()[ aNdIdx.GetIndex()+1 ]->GetCntntNode()->
+                            SetAttr( aCharSet );
+                }
+            }
+            else if( bDfltBorders )
+            {
+                BYTE nBoxId = (i < nCols - 1 ? 0 : 1) + (n ? 2 : 0 );
+                pBoxF = ::lcl_CreateDfltBoxFmt( *this, aBoxFmtArr, nCols, nBoxId);
+            }
+            else
+                pBoxF = pBoxFmt;
+
+            // fuer AutoFormat bei der Eingabe: beim Einfuegen der Tabelle
+            // werden gleich die Spalten gesetzt. Im Array stehen die
+            // Positionen der Spalten!! (nicht deren Breite!)
+            if( pColArr )
+            {
+                nWidth = (*pColArr)[ USHORT(i + 1) ] - (*pColArr)[ i ];
+                if( pBoxF->GetFrmSize().GetWidth() != nWidth )
+                {
+                    if( pBoxF->GetDepends() )       // neues Format erzeugen!
+                    {
+                        SwTableBoxFmt *pNewFmt = MakeTableBoxFmt();
+                        *pNewFmt = *pBoxF;
+                        pBoxF = pNewFmt;
+                    }
+                    pBoxF->SetAttr( SwFmtFrmSize( ATT_VAR_SIZE, nWidth ));
+                }
+            }
+
+            SwTableBox *pBox = new SwTableBox( pBoxF, aNdIdx, pLine);
+            rBoxes.C40_INSERT( SwTableBox, pBox, i );
+            aNdIdx += 3;        // StartNode, TextNode, EndNode  == 3 Nodes
+        }
+    }
+    // und Frms einfuegen.
+    GetNodes().GoNext( &aNdIdx );      // zum naechsten ContentNode
+    pTblNd->MakeFrms( &aNdIdx );
+
+    if( IsRedlineOn() || (!IsIgnoreRedline() && pRedlineTbl->Count() ))
+    {
+        SwPaM aPam( *pTblNd->EndOfSectionNode(), *pTblNd, 1 );
+        if( IsRedlineOn() )
+            AppendRedline( new SwRedline( REDLINE_INSERT, aPam ));
+        else
+            SplitRedline( aPam );
+    }
+
+    SetModified();
+    return pNdTbl;
+}
+
+SwTableNode* SwNodes::InsertTable( const SwNodeIndex& rNdIdx,
+                                    USHORT nBoxes,
+                                    SwTxtFmtColl* pCntntTxtColl,
+                                    USHORT nLines,
+                                    SwTxtFmtColl* pHeadlineTxtColl )
+{
+    if( !nBoxes )
+        return 0;
+
+    // wenn Lines angegeben, erzeuge die Matrix aus Lines & Boxen
+    if( !pHeadlineTxtColl || !nLines )
+        pHeadlineTxtColl = pCntntTxtColl;
+
+    SwTableNode * pTblNd = new SwTableNode( rNdIdx );
+    SwEndNode* pEndNd = new SwEndNode( rNdIdx, *pTblNd );
+
+    if( !nLines )       // fuer die FOR-Schleife
+        ++nLines;
+
+    SwNodeIndex aIdx( *pEndNd );
+    register SwTxtFmtColl* pTxtColl = pHeadlineTxtColl;
+    for( register USHORT nL = 0; nL < nLines; ++nL )
+    {
+        for( register USHORT nB = 0; nB < nBoxes; ++nB )
+        {
+            SwStartNode* pSttNd = new SwStartNode( aIdx, ND_STARTNODE,
+                                                    SwTableBoxStartNode );
+            pSttNd->pStartOfSection = pTblNd;
+            new SwTxtNode( aIdx, pTxtColl );
+            new SwEndNode( aIdx, *pSttNd );
+        }
+        pTxtColl = pCntntTxtColl;
+    }
+    return pTblNd;
+}
+
+
+//---------------- Text -> Tabelle -----------------------
+
+const SwTable* SwDoc::TextToTable( const SwPaM& rRange, sal_Unicode cCh,
+                                    SwHoriOrient eAdjust,
+                                    USHORT nInsTblFlags,
+                                    const SwTableAutoFmt* pTAFmt )
+{
+    // pruefe ob in der Selection eine Tabelle liegt
+    const SwPosition *pStt = rRange.Start(), *pEnd = rRange.End();
+    {
+        ULONG nCnt = pStt->nNode.GetIndex();
+        for( ; nCnt <= pEnd->nNode.GetIndex(); ++nCnt )
+            if( !GetNodes()[ nCnt ]->IsTxtNode() )
+                return 0;
+    }
+
+    SwPaM aOriginal( *pStt, *pEnd );
+    pStt = aOriginal.GetMark();
+    pEnd = aOriginal.GetPoint();
+
+    lcl_DelRedlines aDelRedl( aOriginal );
+
+    SwUndoTxtToTbl* pUndo = 0;
+    if( DoesUndo() )
+    {
+        StartUndo( UNDO_TEXTTOTABLE );
+        pUndo = new SwUndoTxtToTbl( aOriginal, cCh, eAdjust, nInsTblFlags, pTAFmt );
+        AppendUndo( pUndo );
+
+        // das Splitten vom TextNode nicht in die Undohistory aufnehmen
+        DoUndo( FALSE );
+    }
+
+    // die Bookmarks loeschen und die Cursor der CrsrShell verschieben
+    _DelBookmarks( pStt->nNode, pEnd->nNode, 0,
+                    &pStt->nContent, &pEnd->nContent );
+    ::PaMCorrAbs( aOriginal, *pEnd );
+
+    // sorge dafuer, das der Bereich auf Node-Grenzen liegt
+    SwNodeRange aRg( pStt->nNode, pEnd->nNode );
+    if( pStt->nContent.GetIndex() )
+        SplitNode( *pStt );
+
+    BOOL bEndCntnt = 0 != pEnd->nContent.GetIndex();
+    // nicht splitten am Ende der Zeile (aber am Ende vom Doc!!)
+    if( bEndCntnt )
+    {
+        if( pEnd->nNode.GetNode().GetCntntNode()->Len() != pEnd->nContent.GetIndex()
+            || pEnd->nNode.GetIndex() >= GetNodes().GetEndOfContent().GetIndex()-1 )
+        {
+            SplitNode( *pEnd );
+            ((SwNodeIndex&)pEnd->nNode)--;
+            ((SwIndex&)pEnd->nContent).Assign(
+                                pEnd->nNode.GetNode().GetCntntNode(), 0 );
+            // ein Node und am Ende ??
+            if( pStt->nNode.GetIndex() >= pEnd->nNode.GetIndex() )
+                aRg.aStart--;
+        }
+        else
+            aRg.aEnd++;
+    }
+
+
+    if( aRg.aEnd.GetIndex() == aRg.aStart.GetIndex() )
+    {
+        ASSERT( FALSE, "Kein Bereich" );
+        aRg.aEnd++;
+    }
+
+    // Wir gehen jetzt immer ueber die Upper, um die Tabelle einzufuegen:
+    SwNode2Layout aNode2Layout( aRg.aStart.GetNode() );
+
+    DoUndo( 0 != pUndo );
+
+    // dann erstelle die Box/Line/Table-Struktur
+    SwTableBoxFmt* pBoxFmt = MakeTableBoxFmt();
+    SwTableLineFmt* pLineFmt = MakeTableLineFmt();
+    SwTableFmt* pTableFmt = MakeTblFrmFmt( GetUniqueTblName(), GetDfltFrmFmt() );
+
+    // alle Zeilen haben die Fill-Order von links nach rechts !
+    pLineFmt->SetAttr( SwFmtFillOrder( ATT_LEFT_TO_RIGHT ));
+    // die Tabelle bekommt USHRT_MAX als default SSize
+    pTableFmt->SetAttr( SwFmtFrmSize( ATT_VAR_SIZE, USHRT_MAX ));
+    if( !(nInsTblFlags & SPLIT_LAYOUT) )
+        pTableFmt->SetAttr( SwFmtLayoutSplit( FALSE ));
+
+    SwTableNode* pTblNd = GetNodes().TextToTable( aRg, cCh, pTableFmt,
+                                    pLineFmt, pBoxFmt,
+                                GetTxtCollFromPool( RES_POOLCOLL_STANDARD ),
+                                pUndo );
+
+    SwTable * pNdTbl = &pTblNd->GetTable();
+    ASSERT( pNdTbl, "kein Tabellen-Node angelegt."  )
+
+    pNdTbl->SetHeadlineRepeat( HEADLINE_REPEAT == (nInsTblFlags & HEADLINE_REPEAT) );
+
+    BOOL bUseBoxFmt = FALSE;
+    if( !pBoxFmt->GetDepends() )
+    {
+        // die Formate an den Boxen haben schon die richtige Size, es darf
+        // also nur noch die richtige Umrandung/AutoFmt gesetzt werden.
+        bUseBoxFmt = TRUE;
+        pTableFmt->SetAttr( pBoxFmt->GetFrmSize() );
+        delete pBoxFmt;
+        eAdjust = HORI_NONE;
+    }
+
+    //Orientation am Fmt der Table setzen
+    pTableFmt->SetAttr( SwFmtHoriOrient( 0, eAdjust ) );
+    pTableFmt->Add( pNdTbl );       // das Frame-Format setzen
+
+    if( pTAFmt || (nInsTblFlags & DEFAULT_BORDER) )
+    {
+        SwTableBoxFmt* pBoxFmt = 0;
+
+        BYTE nBoxArrLen = pTAFmt ? 16 : 4;
+        SvPtrarr aBoxFmtArr( nBoxArrLen, 0 );
+        {
+            for( BYTE i = 0; i < nBoxArrLen; ++i )
+                aBoxFmtArr.Insert( (void*)0, i );
+        }
+
+        SfxItemSet aCharSet( GetAttrPool(), RES_CHRATR_BEGIN, RES_PARATR_END-1 );
+        SwHistory* pHistory = pUndo ? &pUndo->GetHistory() : 0;
+
+        SwTableBoxFmt *pBoxF;
+        SwTableLines& rLines = pNdTbl->GetTabLines();
+        USHORT nRows = rLines.Count();
+        for( USHORT n = 0; n < nRows; ++n )
+        {
+            SwTableBoxes& rBoxes = rLines[ n ]->GetTabBoxes();
+            USHORT nCols = rBoxes.Count();
+            for( USHORT i = 0; i < nCols; ++i )
+            {
+                SwTableBox* pBox = rBoxes[ i ];
+                BOOL bChgSz = FALSE;
+
+                if( pTAFmt )
+                {
+                    BYTE nId = !n ? 0 : (( n+1 == nRows )
+                                            ? 12 : (4 * (1 + ((n-1) & 1 ))));
+                    nId += !i ? 0 : ( i+1 == nCols ? 3 : (1 + ((i-1) & 1)));
+                    if( bUseBoxFmt )
+                        ::lcl_SetDfltBoxAttr( *pBox, aBoxFmtArr, nId, pTAFmt );
+                    else
+                    {
+                        bChgSz = 0 == aBoxFmtArr[ nId ];
+                        pBoxF = ::lcl_CreateAFmtBoxFmt( *this, aBoxFmtArr,
+                                                *pTAFmt, USHRT_MAX, nId );
+                    }
+
+                    // ggfs. noch die Absatz/ZeichenAttribute setzen
+                    if( pTAFmt->IsFont() || pTAFmt->IsJustify() )
+                    {
+                        aCharSet.ClearItem();
+                        pTAFmt->UpdateToSet( nId, aCharSet,
+                                            SwTableAutoFmt::UPDATE_CHAR, 0 );
+                        if( aCharSet.Count() )
+                        {
+                            ULONG nSttNd = pBox->GetSttIdx()+1;
+                            ULONG nEndNd = pBox->GetSttNd()->EndOfSectionIndex();
+                            for( ; nSttNd < nEndNd; ++nSttNd )
+                            {
+                                SwCntntNode* pNd = GetNodes()[ nSttNd ]->GetCntntNode();
+                                if( pNd )
+                                {
+                                    if( pHistory )
+                                    {
+                                        SwRegHistory aReg( pNd, *pNd, pHistory );
+                                        pNd->SetAttr( aCharSet );
+                                    }
+                                    else
+                                        pNd->SetAttr( aCharSet );
+                                }
+                            }
+                        }
+                    }
+                }
+                else
+                {
+                    BYTE nId = (i < nCols - 1 ? 0 : 1) + (n ? 2 : 0 );
+                    if( bUseBoxFmt )
+                        ::lcl_SetDfltBoxAttr( *pBox, aBoxFmtArr, nId );
+                    else
+                    {
+                        bChgSz = 0 == aBoxFmtArr[ nId ];
+                        pBoxF = ::lcl_CreateDfltBoxFmt( *this, aBoxFmtArr,
+                                                        USHRT_MAX, nId );
+                    }
+                }
+
+                if( !bUseBoxFmt )
+                {
+                    if( bChgSz )
+                        pBoxF->SetAttr( pBox->GetFrmFmt()->GetFrmSize() );
+                    pBox->ChgFrmFmt( pBoxF );
+                }
+            }
+        }
+
+        if( bUseBoxFmt )
+        {
+            for( BYTE i = 0; i < nBoxArrLen; ++i )
+            {
+                SvPtrarr* pArr = (SvPtrarr*)aBoxFmtArr[ i ];
+                delete pArr;
+            }
+        }
+    }
+
+    // JP 03.04.97: Inhalt der Boxen auf Zahlen abpruefen
+    if( IsInsTblFormatNum() )
+    {
+        for( USHORT nBoxes = pNdTbl->GetTabSortBoxes().Count(); nBoxes; )
+            ChkBoxNumFmt( *pNdTbl->GetTabSortBoxes()[ --nBoxes ], FALSE );
+    }
+
+    ULONG nIdx = pTblNd->GetIndex();
+    aNode2Layout.RestoreUpperFrms( GetNodes(), nIdx, nIdx + 1 );
+
+    {
+        SwPaM& rTmp = (SwPaM&)rRange;   // Point immer an den Anfang
+        rTmp.DeleteMark();
+        rTmp.GetPoint()->nNode = *pTblNd;
+        SwCntntNode* pCNd = GetNodes().GoNext( &rTmp.GetPoint()->nNode );
+        rTmp.GetPoint()->nContent.Assign( pCNd, 0 );
+    }
+
+    if( pUndo )
+        EndUndo( UNDO_TEXTTOTABLE );
+
+    SetModified();
+    SetFieldsDirty( TRUE );
+    return pNdTbl;
+}
+
+SwTableNode* SwNodes::TextToTable( const SwNodeRange& rRange, sal_Unicode cCh,
+                                    SwTableFmt* pTblFmt,
+                                    SwTableLineFmt* pLineFmt,
+                                    SwTableBoxFmt* pBoxFmt,
+                                    SwTxtFmtColl* pTxtColl,
+                                    SwUndoTxtToTbl* pUndo )
+{
+    if( rRange.aStart >= rRange.aEnd )
+        return 0;
+
+    SwTableNode * pTblNd = new SwTableNode( rRange.aStart );
+    SwEndNode* pEndNd = new SwEndNode( rRange.aEnd, *pTblNd );
+
+    SwDoc* pDoc = GetDoc();
+    SvUShorts aPosArr( 0, 16 );
+    SwTable * pTable = &pTblNd->GetTable();
+    SwTableLine* pLine;
+    SwTableBox* pBox;
+    USHORT nBoxes, nLines, nMaxBoxes = 0;
+
+    SwHistory* pHistory = pUndo ? &pUndo->GetHistory() : 0;
+
+    SwNodeIndex aSttIdx( *pTblNd, 1 );
+    SwNodeIndex aEndIdx( rRange.aEnd, -1 );
+    for( nLines = 0, nBoxes = 0;
+        aSttIdx.GetIndex() < aEndIdx.GetIndex();
+        aSttIdx += 2, nLines++, nBoxes = 0 )
+    {
+        SwTxtNode* pTxtNd = aSttIdx.GetNode().GetTxtNode();
+        ASSERT( pTxtNd, "nur TextNodes in der Tabelle aufnehmen" );
+
+        if( !nLines && 0x0b == cCh )
+        {
+            cCh = 0x09;
+
+            // JP 28.10.96: vom 1. Node die Positionen des Trenners besorgen,
+            //              damit die Boxen entsprechend eingestellt werden
+            SwTxtFrmInfo aFInfo( (SwTxtFrm*)pTxtNd->GetFrm() );
+            if( aFInfo.IsOneLine() )        // nur dann sinnvoll!
+            {
+                const sal_Unicode* pTxt = pTxtNd->GetTxt().GetBuffer();
+                for( xub_StrLen nChPos = 0; *pTxt; ++nChPos, ++pTxt )
+                    if( *pTxt == cCh )
+                        aPosArr.Insert( aFInfo.GetCharPos( nChPos, FALSE ),
+                                        aPosArr.Count() );
+
+                aPosArr.Insert( /*aFInfo.GetFrm()->Frm().Left() +*/
+                                aFInfo.GetFrm()->Prt().Right(),
+                                aPosArr.Count() );
+            }
+        }
+
+        // die alten Frames loeschen, es werden neue erzeugt
+        pTxtNd->DelFrms();
+
+        // PageBreaks/PageDesc/ColBreak rausschmeissen.
+        SwAttrSet* pSet = pTxtNd->GetpSwAttrSet();
+        if( pSet )
+        {
+// das entfernen der PageBreaks erst nach dem erzeugen der Tabelle
+// erfolgen, denn sonst stehen sie falsch in der History !!!
+//          SwRegHistory aRegH( pTxtNd, *pTxtNd, pHistory );
+            const SfxPoolItem* pItem;
+            if( SFX_ITEM_SET == pSet->GetItemState( RES_BREAK, FALSE, &pItem ) )
+            {
+                if( !nLines )
+                    pTblFmt->SetAttr( *pItem );
+                pTxtNd->SwCntntNode::ResetAttr( RES_BREAK );
+                pSet = pTxtNd->GetpSwAttrSet();
+            }
+
+            if( pSet && SFX_ITEM_SET == pSet->GetItemState(
+                RES_PAGEDESC, FALSE, &pItem ) &&
+                ((SwFmtPageDesc*)pItem)->GetPageDesc() )
+            {
+                if( !nLines )
+                    pTblFmt->SetAttr( *pItem );
+                pTxtNd->SwCntntNode::ResetAttr( RES_PAGEDESC );
+            }
+        }
+
+        // setze den bei allen TextNode in der Tabelle den TableNode
+        // als StartNode
+        pTxtNd->pStartOfSection = pTblNd;
+
+        pLine = new SwTableLine( pLineFmt, 1, 0 );
+        pTable->GetTabLines().C40_INSERT( SwTableLine, pLine, nLines );
+
+        SwStartNode* pSttNd;
+        SwPosition aCntPos( aSttIdx, SwIndex( pTxtNd ));
+
+        SvULongs aBkmkArr( 15, 15 );
+        _SaveCntntIdx( pDoc, aSttIdx.GetIndex(), pTxtNd->GetTxt().Len(), aBkmkArr );
+
+        const sal_Unicode* pTxt = pTxtNd->GetTxt().GetBuffer();
+
+        if( T2T_PARA != cCh )
+            for( xub_StrLen nChPos = 0; *pTxt; ++nChPos, ++pTxt )
+                if( *pTxt == cCh )
+                {
+                    aCntPos.nContent = nChPos;
+                    SwCntntNode* pNewNd = pTxtNd->SplitNode( aCntPos );
+
+                    if( aBkmkArr.Count() )
+                        _RestoreCntntIdx( aBkmkArr, *pNewNd, nChPos,
+                                            nChPos + 1 );
+
+                    // Trennzeichen loeschen und SuchString korrigieren
+                    pTxtNd->Erase( aCntPos.nContent, 1 );
+                    pTxt = pTxtNd->GetTxt().GetBuffer();
+                    nChPos = 0;
+
+                    // setze bei allen TextNodes in der Tabelle den TableNode
+                    // als StartNode
+                    const SwNodeIndex aTmpIdx( aCntPos.nNode, -1 );
+                    pSttNd = new SwStartNode( aTmpIdx, ND_STARTNODE,
+                                                SwTableBoxStartNode );
+                    new SwEndNode( aCntPos.nNode, *pSttNd );
+                    pNewNd->pStartOfSection = pSttNd;
+
+                    // Section der Box zuweisen
+                    pBox = new SwTableBox( pBoxFmt, *pSttNd, pLine );
+                    pLine->GetTabBoxes().C40_INSERT( SwTableBox, pBox, nBoxes++ );
+                }
+
+        // und jetzt den letzten Teil-String
+        if( aBkmkArr.Count() )
+            _RestoreCntntIdx( aBkmkArr, *pTxtNd, pTxtNd->GetTxt().Len(),
+                                pTxtNd->GetTxt().Len()+1 );
+
+        pSttNd = new SwStartNode( aCntPos.nNode, ND_STARTNODE, SwTableBoxStartNode );
+        const SwNodeIndex aTmpIdx( aCntPos.nNode, 1 );
+        new SwEndNode( aTmpIdx, *pSttNd  );
+        pTxtNd->pStartOfSection = pSttNd;
+
+        pBox = new SwTableBox( pBoxFmt, *pSttNd, pLine );
+        pLine->GetTabBoxes().C40_INSERT( SwTableBox, pBox, nBoxes++ );
+        if( nMaxBoxes < nBoxes )
+            nMaxBoxes = nBoxes;
+    }
+
+    // die Tabelle ausgleichen, leere Sections einfuegen
+    for( USHORT n = 0; n < pTable->GetTabLines().Count(); ++n )
+    {
+        SwTableLine* pLine = pTable->GetTabLines()[ n ];
+        if( nMaxBoxes != ( nBoxes = pLine->GetTabBoxes().Count() ))
+        {
+            InsBoxen( pTblNd, pLine, pBoxFmt, pTxtColl, 0,
+                        nBoxes, nMaxBoxes - nBoxes );
+
+            if( pUndo )
+                for( USHORT i = nBoxes; i < nMaxBoxes; ++i )
+                    pUndo->AddFillBox( *pLine->GetTabBoxes()[ i ] );
+
+            // fehlen der 1. Line Boxen, dann kann man das Breiten Array
+            // vergessen!
+            if( !n )
+                aPosArr.Remove( 0, aPosArr.Count() );
+        }
+    }
+
+    if( aPosArr.Count() )
+    {
+        SwTableLines& rLns = pTable->GetTabLines();
+        USHORT nLastPos = 0;
+        for( n = 0; n < aPosArr.Count(); ++n )
+        {
+            SwTableBoxFmt *pNewFmt = pDoc->MakeTableBoxFmt();
+            pNewFmt->SetAttr( SwFmtFrmSize( ATT_VAR_SIZE,
+                                                aPosArr[ n ] - nLastPos ));
+            for( USHORT nLines = 0; nLines < rLns.Count(); ++nLines )
+                //JP 24.06.98: hier muss ein Add erfolgen, da das BoxFormat
+                //              von der rufenden Methode noch gebraucht wird!
+                pNewFmt->Add( rLns[ nLines ]->GetTabBoxes()[ n ] );
+
+            nLastPos = aPosArr[ n ];
+        }
+
+        // damit die Tabelle die richtige Groesse bekommt, im BoxFormat die
+        // Groesse nach "oben" transportieren.
+        ASSERT( !pBoxFmt->GetDepends(), "wer ist in dem Format noch angemeldet" );
+        pBoxFmt->SetAttr( SwFmtFrmSize( ATT_VAR_SIZE, nLastPos ));
+    }
+    else
+        pBoxFmt->SetAttr( SwFmtFrmSize( ATT_VAR_SIZE, USHRT_MAX / nMaxBoxes ));
+
+    // das wars doch wohl ??
+    return pTblNd;
+}
+
+//---------------- Tabelle -> Text -----------------------
+
+
+BOOL SwDoc::TableToText( const SwTableNode* pTblNd, sal_Unicode cCh )
+{
+    if( !pTblNd )
+        return FALSE;
+
+    lcl_DelRedlines aDelRedl( *pTblNd );
+
+    SwNodeRange aRg( *pTblNd, 0, *pTblNd->EndOfSectionNode() );
+    SwUndoTblToTxt* pUndo = 0;
+    SwNodeRange* pUndoRg = 0;
+    if( DoesUndo() )
+    {
+        ClearRedo();
+        pUndoRg = new SwNodeRange( aRg.aStart, -1, aRg.aEnd, +1 );
+        pUndo = new SwUndoTblToTxt( pTblNd->GetTable(), cCh );
+    }
+
+    SwTableFmlUpdate aMsgHnt( &pTblNd->GetTable() );
+    aMsgHnt.eFlags = TBL_BOXNAME;
+    UpdateTblFlds( &aMsgHnt );
+
+    BOOL bRet = GetNodes().TableToText( aRg, cCh, pUndo );
+    if( pUndoRg )
+    {
+        pUndoRg->aStart++;
+        pUndoRg->aEnd--;
+        pUndo->SetRange( *pUndoRg );
+        AppendUndo( pUndo );
+        delete pUndoRg;
+    }
+
+    if( bRet )
+        SetModified();
+
+    return bRet;
+}
+
+// -- benutze die ForEach Methode vom PtrArray um aus einer Tabelle wieder
+//      Text zuerzeugen. (Die Boxen koennen auch noch Lines enthalten !!)
+struct _DelTabPara
+{
+    SwTxtNode* pLastNd;
+    SwNodes& rNds;
+    SwUndoTblToTxt* pUndo;
+    sal_Unicode cCh;
+
+    _DelTabPara( SwNodes& rNodes, sal_Unicode cChar, SwUndoTblToTxt* pU ) :
+        rNds( rNodes ), pLastNd(0), cCh( cChar ), pUndo( pU ) {}
+    _DelTabPara( const _DelTabPara& rPara ) :
+        rNds( rPara.rNds ), cCh( rPara.cCh ), pLastNd(rPara.pLastNd),
+        pUndo( rPara.pUndo ) {}
+};
+
+// forward deklarieren damit sich die Lines und Boxen rekursiv aufrufen
+// koennen.
+BOOL lcl_DelBox( const SwTableBox*&, void *pPara );
+
+BOOL lcl_DelLine( const SwTableLine*& rpLine, void* pPara )
+{
+    ASSERT( pPara, "die Parameter fehlen" );
+    _DelTabPara aPara( *(_DelTabPara*)pPara );
+    ((SwTableLine*&)rpLine)->GetTabBoxes().ForEach( &lcl_DelBox, &aPara );
+    if( rpLine->GetUpper() )        // gibt es noch eine uebergeordnete Box ??
+        // dann gebe den letzten TextNode zurueck
+        ((_DelTabPara*)pPara)->pLastNd = aPara.pLastNd;
+    return TRUE;
+}
+
+
+BOOL lcl_DelBox( const SwTableBox*& rpBox, void* pPara )
+{
+    ASSERT( pPara, "die Parameter fehlen" );
+
+    // loesche erstmal die Lines der Box
+    _DelTabPara* pDelPara = (_DelTabPara*)pPara;
+    if( rpBox->GetTabLines().Count() )
+        ((SwTableBox*&)rpBox)->GetTabLines().ForEach( &lcl_DelLine, pDelPara );
+    else
+    {
+        SwDoc* pDoc = pDelPara->rNds.GetDoc();
+        SwNodeRange aDelRg( *rpBox->GetSttNd(), 0,
+                            *rpBox->GetSttNd()->EndOfSectionNode() );
+        // loesche die Section
+        pDelPara->rNds.SectionUp( &aDelRg );
+        const SwTxtNode* pCurTxtNd;
+        if( T2T_PARA != pDelPara->cCh && pDelPara->pLastNd &&
+            0 != ( pCurTxtNd = aDelRg.aStart.GetNode().GetTxtNode() ))
+        {
+            // den Trenner einfuegen
+            SwIndex aCntIdx( pDelPara->pLastNd, pDelPara->pLastNd->GetTxt().Len());
+            pDelPara->pLastNd->Insert( pDelPara->cCh, aCntIdx );
+            // verbinde den akt. TextNode mit dem aus der vorherigen Box
+            aDelRg.aStart--;
+            ULONG nNdIdx = aDelRg.aStart.GetIndex();
+            if( pDelPara->pLastNd == &aDelRg.aStart.GetNode() )
+            {
+                if( pDelPara->pUndo )
+                    pDelPara->pUndo->AddBoxPos( *pDoc, nNdIdx,
+                                                aCntIdx.GetIndex() );
+
+                SvULongs aBkmkArr( 4, 4 );
+                xub_StrLen nOldTxtLen = aCntIdx.GetIndex();
+                _SaveCntntIdx( pDoc, nNdIdx + 1, pCurTxtNd->GetTxt().Len(),
+                                aBkmkArr );
+
+                pDelPara->pLastNd->JoinNext();
+
+                if( aBkmkArr.Count() )
+                    _RestoreCntntIdx( pDoc, aBkmkArr,
+                                        pDelPara->pLastNd->GetIndex(),
+                                        nOldTxtLen );
+            }
+            else if( pDelPara->pUndo )
+                pDelPara->pUndo->AddBoxPos( *pDoc, nNdIdx );
+        }
+        else if( pDelPara->pUndo )
+            pDelPara->pUndo->AddBoxPos( *pDoc, aDelRg.aStart.GetIndex() );
+        aDelRg.aEnd--;
+        pDelPara->pLastNd = aDelRg.aEnd.GetNode().GetTxtNode();
+
+        //JP 03.04.97: die Ausrichtung der ZahlenFormatierung auf
+        //              keinen Fall uebernehmen
+        if( pDelPara->pLastNd && pDelPara->pLastNd->GetpSwAttrSet() )
+            pDelPara->pLastNd->ResetAttr( RES_PARATR_ADJUST );
+    }
+    return TRUE;
+}
+
+
+BOOL SwNodes::TableToText( const SwNodeRange& rRange, sal_Unicode cCh,
+                            SwUndoTblToTxt* pUndo )
+{
+    // ist eine Tabelle selektiert ?
+    SwTableNode* pTblNd;
+    if( rRange.aStart.GetIndex() >= rRange.aEnd.GetIndex() ||
+        0 == ( pTblNd = (*this)[ rRange.aStart ]->GetTableNode()) ||
+        &rRange.aEnd.GetNode() != pTblNd->EndOfSectionNode() )
+        return FALSE;
+
+    // stand die Tabelle ganz alleine in einer Section ?
+    // dann ueber den Upper der Tabelle die Frames anlegen
+    SwNode2Layout* pNode2Layout = 0;
+    SwNodeIndex aFrmIdx( rRange.aStart );
+    SwNode* pFrmNd = FindPrvNxtFrmNode( aFrmIdx, &rRange.aEnd.GetNode() );
+    if( !pFrmNd )
+        // dann sammel mal alle Uppers ein
+        pNode2Layout = new SwNode2Layout( *pTblNd );
+
+    // loesche schon mal die Frames
+    pTblNd->DelFrms();
+
+    // dann "loeschen" die Tabellen und fasse alle Lines/Boxen zusammen
+    _DelTabPara aDelPara( *this, cCh, pUndo );
+    pTblNd->pTable->GetTabLines().ForEach( &lcl_DelLine, &aDelPara );
+
+    // jetzt ist aus jeder TableLine ein TextNode mit dem entsprechenden
+    // Trenner erzeugt worden. Es braucht nur noch die Table-Section
+    // geloescht und fuer die neuen TextNode die Frames erzeugt werden.
+    SwNodeRange aDelRg( rRange.aStart, rRange.aEnd );
+
+    // JP 14.01.97: hat die Tabelle PageDesc-/Break-Attribute? Dann in den
+    //              ersten TextNode uebernehmen
+    {
+// was ist mit UNDO???
+        const SfxItemSet& rTblSet = pTblNd->pTable->GetFrmFmt()->GetAttrSet();
+        const SfxPoolItem *pBreak, *pDesc;
+        if( SFX_ITEM_SET != rTblSet.GetItemState( RES_PAGEDESC, FALSE, &pDesc ))
+            pDesc = 0;
+        if( SFX_ITEM_SET != rTblSet.GetItemState( RES_BREAK, FALSE, &pBreak ))
+            pBreak = 0;
+
+        if( pBreak || pDesc )
+        {
+            SwNodeIndex aIdx( *pTblNd  );
+            SwCntntNode* pCNd = GoNext( &aIdx );
+            if( pBreak )
+                pCNd->SetAttr( *pBreak );
+            if( pDesc )
+                pCNd->SetAttr( *pDesc );
+        }
+    }
+
+    SectionUp( &aDelRg );       // loesche die Section und damit die Tabelle
+    if( !pFrmNd )
+    {
+        pNode2Layout->RestoreUpperFrms( *this,
+                        aDelRg.aStart.GetIndex(), aDelRg.aEnd.GetIndex() );
+        delete pNode2Layout;
+    }
+    else
+    {
+        SwCntntNode *pCNd;
+        SwSectionNode *pSNd;
+        ULONG nStt = aDelRg.aStart.GetIndex(), nEnd = aDelRg.aEnd.GetIndex();
+        while( aDelRg.aStart.GetIndex() < nEnd )
+        {
+            if( 0 != ( pCNd = aDelRg.aStart.GetNode().GetCntntNode()))
+            {
+                if( pFrmNd->IsCntntNode() )
+                    ((SwCntntNode*)pFrmNd)->MakeFrms( *pCNd );
+                else if( pFrmNd->IsTableNode() )
+                    ((SwTableNode*)pFrmNd)->MakeFrms( aDelRg.aStart );
+                else if( pFrmNd->IsSectionNode() )
+                    ((SwSectionNode*)pFrmNd)->MakeFrms( aDelRg.aStart );
+                pFrmNd = pCNd;
+            }
+            else if( 0 != ( pSNd = aDelRg.aStart.GetNode().GetSectionNode()))
+            {
+                if( !pSNd->GetSection().IsHidden() && !pSNd->IsCntntHidden() )
+                {
+                    pSNd->MakeFrms( &aFrmIdx, &aDelRg.aEnd );
+                    pFrmNd = pSNd;
+                    break;
+                }
+                aDelRg.aStart = *pSNd->EndOfSectionNode();
+            }
+            aDelRg.aStart++;
+        }
+
+        const SwSpzFrmFmts& rFlyArr = *GetDoc()->GetSpzFrmFmts();
+        const SwPosition* pAPos;
+        for( USHORT n = 0; n < rFlyArr.Count(); ++n )
+        {
+            SwFrmFmt* pFmt = (SwFrmFmt*)rFlyArr[n];
+            const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
+            if( ( FLY_AT_CNTNT == rAnchor.GetAnchorId() ||
+                  FLY_AUTO_CNTNT == rAnchor.GetAnchorId() ) &&
+                0 != ( pAPos = rAnchor.GetCntntAnchor() ) &&
+                nStt <= pAPos->nNode.GetIndex() &&
+                pAPos->nNode.GetIndex() < nEnd )
+                pFmt->MakeFrms();
+        }
+    }
+    return TRUE;
+}
+
+
+// ----- einfuegen von Spalten/Zeilen ------------------------
+
+BOOL SwDoc::InsertCol( const SwCursor& rCursor, USHORT nCnt, BOOL bBehind )
+{
+    if( !::CheckSplitCells( rCursor, nCnt + 1, TBLSEARCH_COL ) )
+        return FALSE;
+
+    // lasse ueber das Layout die Boxen suchen
+    SwSelBoxes aBoxes;
+    ::GetTblSel( rCursor, aBoxes, TBLSEARCH_COL );
+
+    BOOL bRet = FALSE;
+    if( aBoxes.Count() )
+        bRet = InsertCol( aBoxes, nCnt, bBehind );
+    return bRet;
+}
+
+BOOL SwDoc::InsertCol( const SwSelBoxes& rBoxes, USHORT nCnt, BOOL bBehind )
+{
+    // uebers SwDoc fuer Undo !!
+    ASSERT( rBoxes.Count(), "keine gueltige Box-Liste" );
+    SwTableNode* pTblNd = (SwTableNode*)rBoxes[0]->GetSttNd()->FindTableNode();
+    if( !pTblNd )
+        return FALSE;
+
+    SwTable& rTbl = pTblNd->GetTable();
+    if( rTbl.ISA( SwDDETable ))
+        return FALSE;
+
+    lcl_DelRedlines aDelRedl( *pTblNd );
+
+    SwTableSortBoxes aTmpLst( 0, 5 );
+    SwUndoTblNdsChg* pUndo = 0;
+    if( DoesUndo() )
+    {
+        DoUndo( FALSE );
+        pUndo = new SwUndoTblNdsChg( UNDO_TABLE_INSCOL, rBoxes, *pTblNd, nCnt, bBehind );
+        aTmpLst.Insert( &rTbl.GetTabSortBoxes(), 0, rTbl.GetTabSortBoxes().Count() );
+    }
+
+    SwTableFmlUpdate aMsgHnt( &rTbl );
+    aMsgHnt.eFlags = TBL_BOXPTR;
+    UpdateTblFlds( &aMsgHnt );
+
+    BOOL bRet = rTbl.InsertCol( this, rBoxes, nCnt, bBehind );
+    if( bRet )
+    {
+        SetModified();
+        ::ClearFEShellTabCols();
+        SetFieldsDirty( TRUE );
+    }
+
+    if( pUndo )
+    {
+        DoUndo( TRUE );
+        if( bRet )
+        {
+            ClearRedo();
+            pUndo->SaveNewBoxes( *pTblNd, aTmpLst );
+            AppendUndo( pUndo );
+        }
+        else
+            delete pUndo;
+    }
+    return bRet;
+}
+
+BOOL SwDoc::InsertRow( const SwCursor& rCursor, USHORT nCnt, BOOL bBehind )
+{
+    // lasse ueber das Layout die Boxen suchen
+    SwSelBoxes aBoxes;
+    GetTblSel( rCursor, aBoxes, TBLSEARCH_ROW );
+
+    BOOL bRet = FALSE;
+    if( aBoxes.Count() )
+        bRet = InsertRow( aBoxes, nCnt, bBehind );
+    return bRet;
+}
+
+BOOL SwDoc::InsertRow( const SwSelBoxes& rBoxes, USHORT nCnt, BOOL bBehind )
+{
+    // uebers SwDoc fuer Undo !!
+    ASSERT( rBoxes.Count(), "keine gueltige Box-Liste" );
+    SwTableNode* pTblNd = (SwTableNode*)rBoxes[0]->GetSttNd()->FindTableNode();
+    if( !pTblNd )
+        return FALSE;
+
+    SwTable& rTbl = pTblNd->GetTable();
+    if( rTbl.ISA( SwDDETable ))
+        return FALSE;
+
+    lcl_DelRedlines aDelRedl( *pTblNd );
+
+    SwTableSortBoxes aTmpLst( 0, 5 );
+    SwUndoTblNdsChg* pUndo = 0;
+    if( DoesUndo() )
+    {
+        DoUndo( FALSE );
+        pUndo = new SwUndoTblNdsChg( UNDO_TABLE_INSROW,rBoxes, *pTblNd,
+                                        nCnt, bBehind );
+        aTmpLst.Insert( &rTbl.GetTabSortBoxes(), 0, rTbl.GetTabSortBoxes().Count() );
+    }
+
+    SwTableFmlUpdate aMsgHnt( &rTbl );
+    aMsgHnt.eFlags = TBL_BOXPTR;
+    UpdateTblFlds( &aMsgHnt );
+
+    BOOL bRet = rTbl.InsertRow( this, rBoxes, nCnt, bBehind );
+    if( bRet )
+    {
+        SetModified();
+        ::ClearFEShellTabCols();
+        SetFieldsDirty( TRUE );
+    }
+
+    if( pUndo )
+    {
+        DoUndo( TRUE );
+        if( bRet )
+        {
+            ClearRedo();
+            pUndo->SaveNewBoxes( *pTblNd, aTmpLst );
+            AppendUndo( pUndo );
+        }
+        else
+            delete pUndo;
+    }
+    return bRet;
+
+}
+
+// ----- loeschen von Spalten/Zeilen ------------------------
+
+BOOL SwDoc::DeleteRow( const SwCursor& rCursor )
+{
+    // lasse ueber das Layout die Boxen suchen
+    SwSelBoxes aBoxes;
+    GetTblSel( rCursor, aBoxes, TBLSEARCH_ROW );
+    if( ::HasProtectedCells( aBoxes ))
+        return FALSE;
+
+    // die Crsr aus dem Loeschbereich entfernen.
+    // Der Cursor steht danach:
+    //  - es folgt noch eine Zeile, in dieser
+    //  - vorher steht noch eine Zeile, in dieser
+    //  - sonst immer dahinter
+    {
+        SwTableNode* pTblNd = rCursor.GetNode()->FindTableNode();
+
+        if( pTblNd->GetTable().ISA( SwDDETable ))
+            return FALSE;
+
+        // suche alle Boxen / Lines
+        _FndBox aFndBox( 0, 0 );
+        {
+            _FndPara aPara( aBoxes, &aFndBox );
+            pTblNd->GetTable().GetTabLines().ForEach( &_FndLineCopyCol, &aPara );
+        }
+
+        if( !aFndBox.GetLines().Count() )
+            return FALSE;
+
+        SwEditShell* pESh = GetEditShell();
+        if( pESh )
+        {
+            pESh->KillPams();
+            // JP: eigentlich sollte man ueber alle Shells iterieren!!
+        }
+
+        _FndBox* pFndBox = &aFndBox;
+        while( 1 == pFndBox->GetLines().Count() &&
+                1 == pFndBox->GetLines()[0]->GetBoxes().Count() )
+        {
+            _FndBox* pTmp = pFndBox->GetLines()[0]->GetBoxes()[0];
+            if( pTmp->GetBox()->GetSttNd() )
+                break;      // das ist sonst zu weit
+            pFndBox = pTmp;
+        }
+
+        SwTableLine* pDelLine = pFndBox->GetLines()[
+                        pFndBox->GetLines().Count()-1 ]->GetLine();
+        SwTableBox* pDelBox = pDelLine->GetTabBoxes()[
+                            pDelLine->GetTabBoxes().Count() - 1 ];
+        while( !pDelBox->GetSttNd() )
+        {
+            SwTableLine* pLn = pDelBox->GetTabLines()[
+                        pDelBox->GetTabLines().Count()-1 ];
+            pDelBox = pLn->GetTabBoxes()[ pLn->GetTabBoxes().Count() - 1 ];
+        }
+        SwTableBox* pNextBox = pDelLine->FindNextBox( pTblNd->GetTable(),
+                                                        pDelBox, TRUE );
+        while( pNextBox &&
+                pNextBox->GetFrmFmt()->GetProtect().IsCntntProtected() )
+            pNextBox = pNextBox->FindNextBox( pTblNd->GetTable(), pNextBox );
+
+        if( !pNextBox )         // keine nachfolgende? dann die vorhergehende
+        {
+            pDelLine = pFndBox->GetLines()[ 0 ]->GetLine();
+            pDelBox = pDelLine->GetTabBoxes()[ 0 ];
+            while( !pDelBox->GetSttNd() )
+                pDelBox = pDelBox->GetTabLines()[0]->GetTabBoxes()[0];
+            pNextBox = pDelLine->FindPreviousBox( pTblNd->GetTable(),
+                                                        pDelBox, TRUE );
+            while( pNextBox &&
+                    pNextBox->GetFrmFmt()->GetProtect().IsCntntProtected() )
+                pNextBox = pNextBox->FindPreviousBox( pTblNd->GetTable(), pNextBox );
+        }
+
+        ULONG nIdx;
+        if( pNextBox )      // dann den Cursor hier hinein
+            nIdx = pNextBox->GetSttIdx() + 1;
+        else                // ansonsten hinter die Tabelle
+            nIdx = pTblNd->EndOfSectionIndex() + 1;
+
+        SwNodeIndex aIdx( GetNodes(), nIdx );
+        SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
+        if( !pCNd )
+            pCNd = GetNodes().GoNext( &aIdx );
+
+        if( pCNd )
+        {
+            // die Cursor von der Shell oder den uebergebenen Cursor aendern?
+            SwPaM* pPam = (SwPaM*)&rCursor;
+            pPam->GetPoint()->nNode = aIdx;
+            pPam->GetPoint()->nContent.Assign( pCNd, 0 );
+            pPam->SetMark();            // beide wollen etwas davon haben
+            pPam->DeleteMark();
+        }
+    }
+
+    // dann loesche doch die Zeilen
+    return DeleteRowCol( aBoxes );
+}
+
+BOOL SwDoc::DeleteCol( const SwCursor& rCursor )
+{
+    // lasse ueber das Layout die Boxen suchen
+    SwSelBoxes aBoxes;
+    GetTblSel( rCursor, aBoxes, TBLSEARCH_COL );
+    if( ::HasProtectedCells( aBoxes ))
+        return FALSE;
+
+    // die Crsr muessen noch aus dem Loesch Bereich entfernt
+    // werden. Setze sie immer hinter/auf die Tabelle; ueber die
+    // Dokument-Position werden sie dann immer an die alte Position gesetzt.
+    SwEditShell* pESh = GetEditShell();
+    if( pESh )
+    {
+        const SwNode* pNd = rCursor.GetNode()->FindTableBoxStartNode();
+        pESh->ParkCrsr( SwNodeIndex( *pNd ) );
+    }
+
+    // dann loesche doch die Spalten
+    return DeleteRowCol( aBoxes );
+}
+
+BOOL SwDoc::DeleteRowCol( const SwSelBoxes& rBoxes )
+{
+    if( ::HasProtectedCells( rBoxes ))
+        return FALSE;
+
+    // uebers SwDoc fuer Undo !!
+    ASSERT( rBoxes.Count(), "keine gueltige Box-Liste" );
+    SwTableNode* pTblNd = (SwTableNode*)rBoxes[0]->GetSttNd()->FindTableNode();
+    if( !pTblNd )
+        return FALSE;
+
+    if( pTblNd->GetTable().ISA( SwDDETable ))
+        return FALSE;
+
+    ::ClearFEShellTabCols();
+
+    lcl_DelRedlines aDelRedl( *pTblNd );
+
+    // soll die gesamte Tabelle geloescht werden ??
+    const ULONG nTmpIdx1 = pTblNd->GetIndex();
+    const ULONG nTmpIdx2 = rBoxes[ rBoxes.Count()-1 ]->GetSttNd()->
+                                EndOfSectionIndex()+1;
+    if( pTblNd->GetTable().GetTabSortBoxes().Count() == rBoxes.Count() &&
+        rBoxes[0]->GetSttIdx()-1 == nTmpIdx1 &&
+        nTmpIdx2 == pTblNd->EndOfSectionIndex() )
+    {
+        BOOL bNewTxtNd = FALSE;
+        // steht diese auch noch alleine in einem FlyFrame ?
+        SwNodeIndex aIdx( *pTblNd, -1 );
+        const SwStartNode* pSttNd = aIdx.GetNode().GetStartNode();
+        if( pSttNd )
+        {
+            const ULONG nTblEnd = pTblNd->EndOfSectionIndex() + 1;
+            const ULONG nSectEnd = pSttNd->EndOfSectionIndex();
+            if( nTblEnd == nSectEnd )
+            {
+                if( SwFlyStartNode == pSttNd->GetStartNodeType() )
+                {
+                    SwFrmFmt* pFmt = pSttNd->GetFlyFmt();
+                    if( pFmt )
+                    {
+                        // Ok, das ist das gesuchte FlyFormat
+                        DelLayoutFmt( pFmt );
+                        return TRUE;
+                    }
+                }
+                // kein Fly ?? also Kopf- oder Fusszeile: dann immer einen
+                // TextNode ueberig lassen.
+                // Undo koennen wir dann vergessen !!
+                bNewTxtNd = TRUE;
+            }
+        }
+
+        // kein Fly ?? also Kopf- oder Fusszeile: dann immer einen
+        // TextNode ueberig lassen.
+        aIdx++;
+        if( DoesUndo() )
+        {
+            ClearRedo();
+            SwPaM aPaM( *pTblNd->EndOfSectionNode(), aIdx.GetNode() );
+
+            if( bNewTxtNd )
+            {
+                const SwNodeIndex aTmpIdx( *pTblNd->EndOfSectionNode(), 1 );
+                GetNodes().MakeTxtNode( aTmpIdx,
+                            GetTxtCollFromPool( RES_POOLCOLL_STANDARD ) );
+            }
+
+            // harte SeitenUmbrueche am nachfolgenden Node verschieben
+            BOOL bSavePageBreak = FALSE, bSavePageDesc = FALSE;
+            ULONG nNextNd = pTblNd->EndOfSectionIndex()+1;
+            SwCntntNode* pNextNd = GetNodes()[ nNextNd ]->GetCntntNode();
+            if( pNextNd )
+            {
+//JP 24.08.98: will man wirklich den PageDesc/Break vom
+//              nachfolgen Absatz ueberbuegeln?
+//              const SwAttrSet& rAttrSet = pNextNd->GetSwAttrSet();
+//              if( SFX_ITEM_SET != rAttrSet.GetItemState( RES_PAGEDESC ) &&
+//                  SFX_ITEM_SET != rAttrSet.GetItemState( RES_BREAK ))
+                {
+                    SwFrmFmt* pTableFmt = pTblNd->GetTable().GetFrmFmt();
+                    const SfxPoolItem *pItem;
+                    if( SFX_ITEM_SET == pTableFmt->GetItemState( RES_PAGEDESC,
+                        FALSE, &pItem ) )
+                    {
+                        pNextNd->SetAttr( *pItem );
+                        bSavePageDesc = TRUE;
+                    }
+
+                    if( SFX_ITEM_SET == pTableFmt->GetItemState( RES_BREAK,
+                        FALSE, &pItem ) )
+                    {
+                        pNextNd->SetAttr( *pItem );
+                        bSavePageBreak = TRUE;
+                    }
+                }
+            }
+            SwUndoDelete* pUndo = new SwUndoDelete( aPaM );
+            if( bNewTxtNd )
+                pUndo->SetTblDelLastNd();
+            pUndo->SetPgBrkFlags( bSavePageBreak, bSavePageDesc );
+            AppendUndo( pUndo );
+        }
+        else
+        {
+            if( bNewTxtNd )
+            {
+                const SwNodeIndex aTmpIdx( *pTblNd->EndOfSectionNode(), 1 );
+                GetNodes().MakeTxtNode( aTmpIdx,
+                            GetTxtCollFromPool( RES_POOLCOLL_STANDARD ) );
+            }
+            // harte SeitenUmbrueche am nachfolgenden Node verschieben
+            SwCntntNode* pNextNd = GetNodes()[ pTblNd->EndOfSectionIndex()+1 ]->GetCntntNode();
+            if( pNextNd )
+            {
+                SwFrmFmt* pTableFmt = pTblNd->GetTable().GetFrmFmt();
+                const SfxPoolItem *pItem;
+                if( SFX_ITEM_SET == pTableFmt->GetItemState( RES_PAGEDESC,
+                    FALSE, &pItem ) )
+                    pNextNd->SetAttr( *pItem );
+
+                if( SFX_ITEM_SET == pTableFmt->GetItemState( RES_BREAK,
+                    FALSE, &pItem ) )
+                    pNextNd->SetAttr( *pItem );
+            }
+
+            pTblNd->DelFrms();
+            DeleteSection( pTblNd );
+        }
+        SetModified();
+        SetFieldsDirty( TRUE );
+        return TRUE;
+    }
+
+    SwUndoTblNdsChg* pUndo = 0;
+    if( DoesUndo() )
+    {
+        DoUndo( FALSE );
+        pUndo = new SwUndoTblNdsChg( UNDO_TABLE_DELBOX, rBoxes, *pTblNd, 0, FALSE );
+    }
+
+    SwTableFmlUpdate aMsgHnt( &pTblNd->GetTable() );
+    aMsgHnt.eFlags = TBL_BOXPTR;
+    UpdateTblFlds( &aMsgHnt );
+
+    BOOL bRet = pTblNd->GetTable().DeleteSel( this, rBoxes, pUndo, TRUE );
+    if( bRet )
+    {
+        SetModified();
+        SetFieldsDirty( TRUE );
+    }
+
+    if( pUndo )
+    {
+        DoUndo( TRUE );
+        if( bRet )
+        {
+            ClearRedo();
+            AppendUndo( pUndo );
+        }
+        else
+            delete pUndo;
+    }
+
+    return bRet;
+}
+
+
+// ---------- teilen / zusammenfassen von Boxen in der Tabelle --------
+
+BOOL SwDoc::SplitTbl( const SwSelBoxes& rBoxes, BOOL bVert, USHORT nCnt )
+{
+    // uebers SwDoc fuer Undo !!
+    ASSERT( rBoxes.Count() && nCnt, "keine gueltige Box-Liste" );
+    SwTableNode* pTblNd = (SwTableNode*)rBoxes[0]->GetSttNd()->FindTableNode();
+    if( !pTblNd )
+        return FALSE;
+
+    SwTable& rTbl = pTblNd->GetTable();
+    if( rTbl.ISA( SwDDETable ))
+        return FALSE;
+
+    lcl_DelRedlines aDelRedl( *pTblNd );
+
+    SvULongs aNdsCnts;
+    SwTableSortBoxes aTmpLst( 0, 5 );
+    SwUndoTblNdsChg* pUndo = 0;
+    if( DoesUndo() )
+    {
+        DoUndo( FALSE );
+        pUndo = new SwUndoTblNdsChg( UNDO_TABLE_SPLIT, rBoxes, *pTblNd, nCnt, bVert );
+        aTmpLst.Insert( &rTbl.GetTabSortBoxes(), 0, rTbl.GetTabSortBoxes().Count() );
+        if( !bVert )
+        {
+            for( USHORT n = 0; n < rBoxes.Count(); ++n )
+            {
+                const SwStartNode* pSttNd = rBoxes[ n ]->GetSttNd();
+                aNdsCnts.Insert( pSttNd->EndOfSectionIndex() -
+                                 pSttNd->GetIndex(), n );
+            }
+        }
+    }
+
+    SwTableFmlUpdate aMsgHnt( &rTbl );
+    aMsgHnt.eFlags = TBL_BOXPTR;
+    UpdateTblFlds( &aMsgHnt );
+
+    BOOL bRet;
+    if( bVert )
+        bRet = rTbl.SplitCol( this, rBoxes, nCnt );
+    else
+        bRet = rTbl.SplitRow( this, rBoxes, nCnt );
+
+    if( bRet )
+    {
+        SetModified();
+        SetFieldsDirty( TRUE );
+    }
+
+    if( pUndo )
+    {
+        DoUndo( TRUE );
+        if( bRet )
+        {
+            ClearRedo();
+            if( bVert )
+                pUndo->SaveNewBoxes( *pTblNd, aTmpLst );
+            else
+                pUndo->SaveNewBoxes( *pTblNd, aTmpLst, rBoxes, aNdsCnts );
+            AppendUndo( pUndo );
+        }
+        else
+            delete pUndo;
+    }
+
+    return bRet;
+}
+
+
+USHORT SwDoc::MergeTbl( SwPaM& rPam )
+{
+    // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen
+    SwTableNode* pTblNd = rPam.GetNode()->FindTableNode();
+    if( !pTblNd || pTblNd->GetTable().ISA( SwDDETable ))
+        return TBLMERGE_NOSELECTION;
+
+    USHORT nRet = ::CheckMergeSel( rPam );
+    if( TBLMERGE_OK != nRet )
+        return nRet;
+
+    nRet = TBLMERGE_NOSELECTION;
+
+    StartUndo();
+    if( !IsIgnoreRedline() && GetRedlineTbl().Count() )
+        DeleteRedline( *pTblNd );
+    SwRedlineMode eOld = GetRedlineMode();
+    SetRedlineMode_intern( eOld | REDLINE_IGNORE );
+
+    SwUndoTblMerge* pUndo = 0;
+    if( DoesUndo() )
+        pUndo = new SwUndoTblMerge( rPam );
+
+    // lasse ueber das Layout die Boxen suchen
+    SwSelBoxes aBoxes;
+    SwTableBox* pMergeBox;
+    ::GetMergeSel( rPam, aBoxes, &pMergeBox, pUndo );
+
+    if( 2 > aBoxes.Count() )        // keine gueltigen Boxen gefunden
+    {
+        SetRedlineMode_intern( eOld );
+        if( pUndo )
+        {
+            delete pUndo;
+            if( UNDO_REDLINE == GetUndoIds() )
+            {
+                SwUndoRedline* pU = (SwUndoRedline*)RemoveLastUndo( UNDO_REDLINE );
+                if( pU->GetRedlSaveCount() )
+                {
+                    SwUndoIter aUndoIter( &rPam, UNDO_REDLINE );
+                    pU->Undo( aUndoIter );
+                }
+                delete pU;
+            }
+        }
+    }
+    else
+    {
+        // die PaMs muessen noch aus dem Loesch Bereich entfernt
+        // werden. Setze sie immer hinter/auf die Tabelle; ueber die
+        // Dokument-Position werden sie dann immer an die alte Position gesetzt.
+        // Erstmal einen Index auf die Parkposition merken, denn nach GetMergeSel
+        // komme ich nicht mehr dran.
+        {
+            rPam.DeleteMark();
+            rPam.GetPoint()->nNode = *pMergeBox->GetSttNd();
+            rPam.GetPoint()->nContent.Assign( 0, 0 );
+            rPam.SetMark();
+            rPam.DeleteMark();
+
+            SwPaM* pTmp = &rPam;
+            while( &rPam != ( pTmp = (SwPaM*)pTmp->GetNext() ))
+                for( int i = 0; i < 2; ++i )
+                    pTmp->GetBound( (BOOL)i ) = *rPam.GetPoint();
+        }
+
+        // dann fuege sie zusammen
+        SwTableFmlUpdate aMsgHnt( &pTblNd->GetTable() );
+        aMsgHnt.eFlags = TBL_BOXPTR;
+        UpdateTblFlds( &aMsgHnt );
+
+        if( pTblNd->GetTable().Merge( this, aBoxes, pMergeBox, pUndo ))
+        {
+            nRet = TBLMERGE_OK;
+            SetModified();
+            SetFieldsDirty( TRUE );
+            if( pUndo )
+                AppendUndo( pUndo );
+        }
+        else if( pUndo )
+            delete pUndo;
+
+        rPam.GetPoint()->nNode = *pMergeBox->GetSttNd();
+        rPam.Move();
+
+        ::ClearFEShellTabCols();
+        SetRedlineMode_intern( eOld );
+    }
+    EndUndo();
+    return nRet;
+}
+
+
+
+// -------------------------------------------------------
+
+//---------
+// SwTableNode
+//---------
+
+SwTableNode::SwTableNode( const SwNodeIndex& rIdx )
+    : SwStartNode( rIdx, ND_TABLENODE )
+{
+    pTable = new SwTable( 0 );
+}
+
+SwTableNode::~SwTableNode()
+{
+    DelFrms();
+    delete pTable;
+}
+
+SwTabFrm *SwTableNode::MakeFrm()
+{
+    return new SwTabFrm( *pTable );
+}
+
+//Methode erzeugt fuer den vorhergehenden Node alle Ansichten vom
+//Dokument. Die erzeugten Contentframes werden in das entsprechende
+//Layout gehaengt.
+void SwTableNode::MakeFrms(const SwNodeIndex & rIdx )
+{
+    if( !GetTable().GetFrmFmt()->GetDepends())//gibt es ueberhaupt Frames ??
+        return;
+
+    SwFrm *pFrm, *pNew;
+    SwCntntNode * pNode = rIdx.GetNode().GetCntntNode();
+
+    ASSERT( pNode, "Kein Contentnode oder Copy-Node und neuer Node identisch.");
+
+    BOOL bBefore = rIdx < GetIndex();
+
+    SwNode2Layout aNode2Layout( *this, rIdx.GetIndex() );
+
+    while( 0 != (pFrm = aNode2Layout.NextFrm()) )
+    {
+        pNew = pNode->MakeFrm();
+        // wird ein Node vorher oder nachher mit Frames versehen
+        if ( bBefore )
+            // der neue liegt vor mir
+            pNew->Paste( pFrm->GetUpper(), pFrm );
+        else
+            // der neue liegt hinter mir
+            pNew->Paste( pFrm->GetUpper(), pFrm->GetNext() );
+    }
+}
+
+//Fuer jede Shell einen TblFrm anlegen und vor den entsprechenden
+//CntntFrm pasten.
+
+void SwTableNode::MakeFrms( SwNodeIndex* pIdxBehind )
+{
+    ASSERT( pIdxBehind, "kein Index" );
+    *pIdxBehind = *this;
+    SwNode *pNd = GetNodes().FindPrvNxtFrmNode( *pIdxBehind, EndOfSectionNode() );
+    if( !pNd )
+        return ;
+
+    // liegt der gefundene ContentNode vor oder hinter der Tabelle ?
+    BOOL bBehind = EndOfSectionIndex() < pIdxBehind->GetIndex();
+
+    SwFrm *pFrm, *pNew;
+
+    SwNode2Layout aNode2Layout( *pNd, GetIndex() );
+    while( 0 != (pFrm = aNode2Layout.NextFrm()) )
+    {
+        pNew = MakeFrm();
+        pNew->Paste( pFrm->GetUpper(),  bBehind ? pFrm : pFrm->GetNext() );
+        ((SwTabFrm*)pNew)->RegistFlys();
+    }
+}
+
+void SwTableNode::DelFrms()
+{
+    //Erstmal die TabFrms ausschneiden und deleten, die Columns und Rows
+    //nehmen sie mit in's Grab.
+    //Die TabFrms haengen am FrmFmt des SwTable.
+    //Sie muessen etwas umstaendlich zerstort werden, damit die Master
+    //die Follows mit in's Grab nehmen.
+
+    SwClientIter aIter( *(pTable->GetFrmFmt()) );
+    SwClient *pLast = aIter.GoStart();
+    while ( pLast )
+    {
+        BOOL bAgain = FALSE;
+        if ( pLast->IsA( TYPE(SwFrm) ) )
+        {
+            SwTabFrm *pFrm = (SwTabFrm*)pLast;
+            if ( !pFrm->IsFollow() )
+            {
+                while ( pFrm->HasFollow() )
+                    pFrm->JoinAndDelFollows();
+                pFrm->Cut();
+                delete pFrm;
+                bAgain = TRUE;
+            }
+        }
+        pLast = bAgain ? aIter.GoStart() : aIter++;
+    }
+}
+
+
+void SwTableNode::SetNewTable( SwTable* pNewTable, BOOL bNewFrames )
+{
+    DelFrms();
+    delete pTable;
+    pTable = pNewTable;
+    if( bNewFrames )
+    {
+        SwNodeIndex aIdx( *EndOfSectionNode());
+        GetNodes().GoNext( &aIdx );
+        MakeFrms( &aIdx );
+    }
+}
+
+    // setze das TabelleAttribut Undo auf:
+void SwDoc::AppendUndoForAttrTable( const SwTable& rTbl )
+{
+    if( DoesUndo() )
+    {
+        ClearRedo();
+        AppendUndo( new SwUndoAttrTbl( *rTbl.GetTableNode() ));
+    }
+}
+
+void SwDoc::GetTabCols( SwTabCols &rFill, const SwCursor* pCrsr,
+                        const SwCellFrm* pBoxFrm ) const
+{
+    const SwTableBox* pBox;
+    SwTabFrm *pTab;
+
+    if( pBoxFrm )
+    {
+        pTab = ((SwFrm*)pBoxFrm)->ImplFindTabFrm();
+        pBox = pBoxFrm->GetTabBox();
+    }
+    else if( pCrsr )
+    {
+        const SwCntntNode* pCNd = pCrsr->GetCntntNode();
+        if( !pCNd )
+            return ;
+
+        Point aPt;
+        const SwShellCrsr *pShCrsr = *pCrsr;
+        if( pShCrsr )
+            aPt = pShCrsr->GetPtPos();
+
+        const SwFrm* pTmpFrm = pCNd->GetFrm( &aPt, 0, FALSE );
+        do {
+            pTmpFrm = pTmpFrm->GetUpper();
+        } while ( !pTmpFrm->IsCellFrm() );
+
+        pBoxFrm = (SwCellFrm*)pTmpFrm;
+        pTab = ((SwFrm*)pBoxFrm)->ImplFindTabFrm();
+        pBox = pBoxFrm->GetTabBox();
+    }
+    else if( !pCrsr && !pBoxFrm )
+    {
+        ASSERT( !this, "einer von beiden muss angegeben werden!" );
+        return ;
+    }
+
+    //Fix-Punkte setzen, LeftMin in Dokumentkoordinaten die anderen relativ.
+    rFill.SetLeftMin ( (USHORT)pTab->Frm().Left() );
+    rFill.SetLeft    ( pTab->Prt().Left() );
+    rFill.SetRight   ( pTab->Prt().Right());
+    rFill.SetRightMax( (USHORT)pTab->Frm().Right() - rFill.GetLeftMin() );
+
+    pTab->GetTable()->GetTabCols( rFill, pBox );
+}
+
+void SwDoc::SetTabCols( const SwTabCols &rNew, BOOL bCurRowOnly,
+                        const SwCursor* pCrsr, const SwCellFrm* pBoxFrm )
+{
+    const SwTableBox* pBox;
+    SwTabFrm *pTab;
+
+    if( pBoxFrm )
+    {
+        pTab = ((SwFrm*)pBoxFrm)->ImplFindTabFrm();
+        pBox = pBoxFrm->GetTabBox();
+    }
+    else if( pCrsr )
+    {
+        const SwCntntNode* pCNd = pCrsr->GetCntntNode();
+        if( !pCNd )
+            return ;
+
+        Point aPt;
+        const SwShellCrsr *pShCrsr = *pCrsr;
+        if( pShCrsr )
+            aPt = pShCrsr->GetPtPos();
+
+        const SwFrm* pTmpFrm = pCNd->GetFrm( &aPt, 0, FALSE );
+        do {
+            pTmpFrm = pTmpFrm->GetUpper();
+        } while ( !pTmpFrm->IsCellFrm() );
+
+        pBoxFrm = (SwCellFrm*)pTmpFrm;
+        pTab = ((SwFrm*)pBoxFrm)->ImplFindTabFrm();
+        pBox = pBoxFrm->GetTabBox();
+    }
+    else if( !pCrsr && !pBoxFrm )
+    {
+        ASSERT( !this, "einer von beiden muss angegeben werden!" );
+        return ;
+    }
+
+    // sollte die Tabelle noch auf relativen Werten (USHRT_MAX) stehen
+    // dann muss es jetzt auf absolute umgerechnet werden.
+    SwTable& rTab = *pTab->GetTable();
+    const SwFmtFrmSize& rTblFrmSz = rTab.GetFrmFmt()->GetFrmSize();
+    if( //HORI_NONE == pTab->GetFmt()->GetHoriOrient().GetHoriOrient() &&
+        pTab->Prt().Width() != rTblFrmSz.GetWidth() )
+    {
+        SwFmtFrmSize aSz( rTblFrmSz );
+        aSz.SetWidth( pTab->Prt().Width() );
+        rTab.GetFrmFmt()->SetAttr( aSz );
+    }
+
+    SwTabCols aOld( rNew.Count() );
+
+    //Fix-Punkte setzen, LeftMin in Dokumentkoordinaten die anderen relativ.
+    aOld.SetLeftMin ( (USHORT)pTab->Frm().Left() );
+    aOld.SetLeft    ( pTab->Prt().Left() );
+    aOld.SetRight   ( pTab->Prt().Right());
+    aOld.SetRightMax( (USHORT)pTab->Frm().Right() - aOld.GetLeftMin() );
+
+/*  if( DoesUndo() )
+    {
+        ClearRedo();
+        AppendUndo( new SwUndoAttrTbl(
+                *rTab.GetTableNode(),
+                TRUE ));
+    }
+
+    rTab.SetTabCols( rNew, aOld, pBox, bCurRowOnly );
+
+    SetModified();*/
+    SetTabCols(rTab, rNew, aOld, pBox, bCurRowOnly );
+    ::ClearFEShellTabCols();
+}
+
+/* -----------------18.07.98 11:45-------------------
+ *  Direktzugriff fuer UNO
+ * --------------------------------------------------*/
+void SwDoc::SetTabCols(SwTable& rTab, const SwTabCols &rNew, SwTabCols &rOld,
+                                const SwTableBox *pStart, BOOL bCurRowOnly )
+{
+    if( DoesUndo() )
+    {
+        ClearRedo();
+        AppendUndo( new SwUndoAttrTbl( *rTab.GetTableNode(), TRUE ));
+    }
+    rTab.SetTabCols( rNew, rOld, pStart, bCurRowOnly );
+    SetModified();
+}
+
+void SwDoc::SetHeadlineRepeat( SwTable &rTable, BOOL bSet )
+{
+    if( bSet == rTable.IsHeadlineRepeat() )
+        return;
+
+    if( DoesUndo() )
+    {
+        ClearRedo();
+        AppendUndo( new SwUndoTblHeadline( rTable, !bSet ) );
+    }
+
+    rTable.SetHeadlineRepeat( bSet );
+    SwMsgPoolItem aChg( RES_TBLHEADLINECHG );
+    rTable.GetFrmFmt()->Modify( &aChg, &aChg );
+    SetModified();
+}
+
+
+
+// Splittet eine Tabelle in der Grund-Zeile, in der der Index steht.
+// Alle GrundZeilen dahinter wandern in eine neue Tabelle/-Node.
+// Ist das Flag bCalcNewSize auf TRUE, wird fuer beide neuen Tabellen
+// die neue Size aus dem Max der Boxen errechnet; vorrausgesetzt,
+// die Size ist "absolut" gesetzt (USHRT_MAX)
+
+void SwCollectTblLineBoxes::AddToUndoHistory( const SwCntntNode& rNd )
+{
+    if( pHst )
+        pHst->Add( rNd.GetFmtColl(), rNd.GetIndex(), ND_TEXTNODE );
+}
+
+void SwCollectTblLineBoxes::AddBox( const SwTableBox& rBox )
+{
+    aPosArr.Insert( nWidth, aPosArr.Count() );
+    SwTableBox* p = (SwTableBox*)&rBox;
+    aBoxes.Insert( p, aBoxes.Count() );
+    nWidth += (USHORT)rBox.GetFrmFmt()->GetFrmSize().GetWidth();
+}
+
+const SwTableBox* SwCollectTblLineBoxes::GetBoxOfPos( const SwTableBox& rBox )
+{
+    const SwTableBox* pRet = 0;
+    if( aPosArr.Count() )
+    {
+        for( USHORT n = 0; n < aPosArr.Count(); ++n )
+            if( aPosArr[ n ] == nWidth )
+                break;
+            else if( aPosArr[ n ] > nWidth )
+            {
+                if( n )
+                    --n;
+                break;
+            }
+
+        if( n >= aPosArr.Count() )
+            --n;
+
+        nWidth += (USHORT)rBox.GetFrmFmt()->GetFrmSize().GetWidth();
+        pRet = aBoxes[ n ];
+    }
+    return pRet;
+}
+
+FASTBOOL SwCollectTblLineBoxes::Resize( USHORT nOffset, USHORT nOldWidth )
+{
+    if( aPosArr.Count() )
+    {
+        for( USHORT n = 0; n < aPosArr.Count(); ++n )
+            if( aPosArr[ n ] == nOffset )
+                break;
+            else if( aPosArr[ n ] > nOffset )
+            {
+                if( n )
+                    --n;
+                break;
+            }
+
+        aPosArr.Remove( 0, n );
+        aBoxes.Remove( 0, n );
+
+        // dann die Positionen der neuen Size anpassen
+        for( n = 0; n < aPosArr.Count(); ++n )
+        {
+            ULONG nSize = nWidth;
+            nSize *= ( aPosArr[ n ] - nOffset );
+            nSize /= nOldWidth;
+            aPosArr[ n ] = USHORT( nSize );
+        }
+    }
+    return 0 != aPosArr.Count();
+}
+
+BOOL lcl_Line_CollectBox( const SwTableLine*& rpLine, void* pPara )
+{
+    SwCollectTblLineBoxes* pSplPara = (SwCollectTblLineBoxes*)pPara;
+    if( pSplPara->IsGetValues() )
+        ((SwTableLine*)rpLine)->GetTabBoxes().ForEach( &lcl_Box_CollectBox, pPara );
+    else
+        ((SwTableLine*)rpLine)->GetTabBoxes().ForEach( &lcl_BoxSetSplitBoxFmts, pPara );
+    return TRUE;
+}
+
+BOOL lcl_Box_CollectBox( const SwTableBox*& rpBox, void* pPara )
+{
+    SwCollectTblLineBoxes* pSplPara = (SwCollectTblLineBoxes*)pPara;
+    USHORT nLen = rpBox->GetTabLines().Count();
+    if( nLen )
+    {
+        // dann mit der richtigen Line weitermachen
+        if( pSplPara->IsGetFromTop() )
+            nLen = 0;
+        else
+            --nLen;
+
+        const SwTableLine* pLn = rpBox->GetTabLines()[ nLen ];
+        lcl_Line_CollectBox( pLn, pPara );
+    }
+    else
+        pSplPara->AddBox( *rpBox );
+    return TRUE;
+}
+
+BOOL lcl_BoxSetSplitBoxFmts( const SwTableBox*& rpBox, void* pPara )
+{
+    SwCollectTblLineBoxes* pSplPara = (SwCollectTblLineBoxes*)pPara;
+    USHORT nLen = rpBox->GetTabLines().Count();
+    if( nLen )
+    {
+        // dann mit der richtigen Line weitermachen
+        if( pSplPara->IsGetFromTop() )
+            nLen = 0;
+        else
+            --nLen;
+
+        const SwTableLine* pLn = rpBox->GetTabLines()[ nLen ];
+        lcl_Line_CollectBox( pLn, pPara );
+    }
+    else
+    {
+        const SwTableBox* pSrcBox = pSplPara->GetBoxOfPos( *rpBox );
+        SwFrmFmt* pFmt = pSrcBox->GetFrmFmt();
+        SwTableBox* pBox = (SwTableBox*)rpBox;
+
+        if( HEADLINE_BORDERCOPY == pSplPara->GetMode() )
+        {
+            const SvxBoxItem& rBoxItem = pBox->GetFrmFmt()->GetBox();
+            if( !rBoxItem.GetTop() )
+            {
+                SvxBoxItem aNew( rBoxItem );
+                aNew.SetLine( pFmt->GetBox().GetBottom(), BOX_LINE_TOP );
+                if( aNew != rBoxItem )
+                    pBox->ClaimFrmFmt()->SetAttr( aNew );
+            }
+        }
+        else
+        {
+USHORT __FAR_DATA aTableSplitBoxSetRange[] = {
+    RES_LR_SPACE,       RES_UL_SPACE,
+    RES_BACKGROUND,     RES_SHADOW,
+    RES_PROTECT,        RES_PROTECT,
+    RES_VERT_ORIENT,    RES_VERT_ORIENT,
+    0 };
+            SfxItemSet aTmpSet( pFmt->GetDoc()->GetAttrPool(),
+                                aTableSplitBoxSetRange );
+            aTmpSet.Put( pFmt->GetAttrSet() );
+            if( aTmpSet.Count() )
+                pBox->ClaimFrmFmt()->SetAttr( aTmpSet );
+
+            if( HEADLINE_BOXATRCOLLCOPY == pSplPara->GetMode() )
+            {
+                SwNodeIndex aIdx( *pSrcBox->GetSttNd(), 1 );
+                SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
+                if( !pCNd )
+                    pCNd = aIdx.GetNodes().GoNext( &aIdx );
+                aIdx = *pBox->GetSttNd();
+                SwCntntNode* pDNd = aIdx.GetNodes().GoNext( &aIdx );
+
+                // nur wenn der Node alleine in der Section steht
+                if( 2 == pDNd->EndOfSectionIndex() -
+                        pDNd->StartOfSectionIndex() )
+                {
+                    pSplPara->AddToUndoHistory( *pDNd );
+                    pDNd->ChgFmtColl( pCNd->GetFmtColl() );
+                }
+            }
+
+            // bedingte Vorlage beachten
+            pBox->GetSttNd()->CheckSectionCondColl();
+        }
+    }
+    return TRUE;
+}
+
+
+BOOL SwDoc::SplitTable( const SwPosition& rPos, USHORT eHdlnMode,
+                        BOOL bCalcNewSize )
+{
+    SwNode* pNd = &rPos.nNode.GetNode();
+    SwTableNode* pTNd = pNd->FindTableNode();
+    if( !pTNd || pNd->IsTableNode() )
+        return 0;
+
+    if( pTNd->GetTable().ISA( SwDDETable ))
+        return FALSE;
+
+    SwTable& rTbl = pTNd->GetTable();
+    rTbl.SetHTMLTableLayout( 0 );   // MIB 9.7.97: HTML-Layout loeschen
+
+    SwTableFmlUpdate aMsgHnt( &rTbl );
+
+    SwHistory aHistory;
+    if( DoesUndo() )
+        aMsgHnt.pHistory = &aHistory;
+
+    {
+        ULONG nSttIdx = pNd->FindTableBoxStartNode()->GetIndex();
+
+        // Suche die Grund-Line dieser Box:
+        SwTableBox* pBox = rTbl.GetTblBox( nSttIdx );
+        if( pBox )
+        {
+            SwTableLine* pLine = pBox->GetUpper();
+            while( pLine->GetUpper() )
+                pLine = pLine->GetUpper()->GetUpper();
+
+            // in pLine steht jetzt die GrundLine.
+            aMsgHnt.nSplitLine = rTbl.GetTabLines().C40_GETPOS( SwTableLine, pLine );
+        }
+
+        String sNewTblNm( GetUniqueTblName() );
+        aMsgHnt.DATA.pNewTblNm = &sNewTblNm;
+        aMsgHnt.eFlags = TBL_SPLITTBL;
+        UpdateTblFlds( &aMsgHnt );
+    }
+
+    //Lines fuer das Layout-Update heraussuchen.
+    _FndBox aFndBox( 0, 0 );
+    aFndBox.SetTableLines( rTbl );
+    aFndBox.DelFrms( rTbl );
+    aFndBox.SaveChartData( rTbl );
+
+    SwTableNode* pNew = GetNodes().SplitTable( rPos.nNode, FALSE, bCalcNewSize );
+
+    if( pNew )
+    {
+        SwUndoSplitTbl* pUndo = 0;
+        if( DoesUndo() )
+        {
+            ClearRedo();
+            AppendUndo( pUndo = new SwUndoSplitTbl( *pNew, eHdlnMode, bCalcNewSize ));
+            if( aHistory.Count() )
+                pUndo->SaveFormula( aHistory );
+        }
+
+        switch( eHdlnMode )
+        {
+            // setze die untere Border der vorherige Line,
+            // an der aktuellen als obere
+        case HEADLINE_BORDERCOPY:
+            {
+                SwCollectTblLineBoxes aPara( FALSE, eHdlnMode );
+                SwTableLine* pLn = rTbl.GetTabLines()[
+                            rTbl.GetTabLines().Count() - 1 ];
+                pLn->GetTabBoxes().ForEach( &lcl_Box_CollectBox, &aPara );
+
+                aPara.SetValues( TRUE );
+                pLn = pNew->GetTable().GetTabLines()[ 0 ];
+                pLn->GetTabBoxes().ForEach( &lcl_BoxSetSplitBoxFmts, &aPara );
+
+                // Kopfzeile wiederholen abschalten
+                pNew->GetTable().SetHeadlineRepeat( FALSE );
+            }
+            break;
+
+            // setze die Attributierung der ersten Line an der neuen ersten
+        case HEADLINE_BOXATTRCOPY:
+        case HEADLINE_BOXATRCOLLCOPY:
+            {
+                SwHistory* pHst = 0;
+                if( HEADLINE_BOXATRCOLLCOPY == eHdlnMode && pUndo )
+                    pHst = pUndo->GetHistory();
+
+                SwCollectTblLineBoxes aPara( TRUE, eHdlnMode, pHst );
+                SwTableLine* pLn = rTbl.GetTabLines()[ 0 ];
+                pLn->GetTabBoxes().ForEach( &lcl_Box_CollectBox, &aPara );
+
+                aPara.SetValues( TRUE );
+                pLn = pNew->GetTable().GetTabLines()[ 0 ];
+                pLn->GetTabBoxes().ForEach( &lcl_BoxSetSplitBoxFmts, &aPara );
+            }
+            break;
+
+        case HEADLINE_CNTNTCOPY:
+            rTbl.CopyHeadlineIntoTable( *pNew );
+            if( pUndo )
+                pUndo->SetTblNodeOffset( pNew->GetIndex() );
+            break;
+
+        case HEADLINE_NONE:
+            // Kopfzeile wiederholen abschalten
+            pNew->GetTable().SetHeadlineRepeat( FALSE );
+            break;
+        }
+
+        // und Frms einfuegen.
+        SwNodeIndex aNdIdx( *pNew->EndOfSectionNode() );
+        GetNodes().GoNext( &aNdIdx );      // zum naechsten ContentNode
+        pNew->MakeFrms( &aNdIdx );
+
+        //Zwischen die Tabellen wird ein Absatz geschoben
+        GetNodes().MakeTxtNode( SwNodeIndex( *pNew ),
+                                GetTxtCollFromPool( RES_POOLCOLL_TEXT ) );
+    }
+
+    //Layout updaten
+    aFndBox.MakeFrms( rTbl );
+    aFndBox.RestoreChartData( rTbl );
+    SetFieldsDirty( TRUE );
+
+    return 0 != pNew;
+}
+
+BOOL lcl_ChgTblSize( SwTable& rTbl )
+{
+    // das Attribut darf nicht ueber das Modify an der
+    // Tabelle gesetzt werden, denn sonst werden alle
+    // Boxen wieder auf 0 zurueck gesetzt. Also locke das Format
+    SwFrmFmt* pFmt = rTbl.GetFrmFmt();
+    SwFmtFrmSize aTblMaxSz( pFmt->GetFrmSize() );
+
+    if( USHRT_MAX == aTblMaxSz.GetWidth() )
+        return FALSE;
+
+    BOOL bLocked = pFmt->IsModifyLocked();
+    pFmt->LockModify();
+
+    aTblMaxSz.SetWidth( 0 );
+
+    SwTableLines& rLns = rTbl.GetTabLines();
+    for( USHORT nLns = 0; nLns < rLns.Count(); ++nLns )
+    {
+        SwTwips nMaxLnWidth = 0;
+        SwTableBoxes& rBoxes = rLns[ nLns ]->GetTabBoxes();
+        for( USHORT nBox = 0; nBox < rBoxes.Count(); ++nBox )
+            nMaxLnWidth += rBoxes[nBox]->GetFrmFmt()->GetFrmSize().GetWidth();
+
+        if( nMaxLnWidth > aTblMaxSz.GetWidth() )
+            aTblMaxSz.SetWidth( nMaxLnWidth );
+    }
+    pFmt->SetAttr( aTblMaxSz );
+    if( !bLocked )          // und gegebenenfalls Lock wieder freigeben
+        pFmt->UnlockModify();
+
+    return TRUE;
+}
+
+class _SplitTable_Para
+{
+    SvPtrarr aSrc, aDest;
+    SwTableNode* pNewTblNd;
+    SwTable& rOldTbl;
+
+public:
+    _SplitTable_Para( SwTableNode* pNew, SwTable& rOld )
+        : pNewTblNd( pNew ), aSrc( 16, 16 ), aDest( 16, 16 ), rOldTbl( rOld )
+    {}
+    USHORT SrcFmt_GetPos( void* pFmt ) const
+            { return aSrc.GetPos( pFmt ); }
+
+    void DestFmt_Insert( void* pFmt )
+            { aDest.Insert( pFmt, aDest.Count() ); }
+
+    void SrcFmt_Insert( void* pFmt )
+            { aSrc.Insert( pFmt, aSrc.Count() ); }
+
+    SwFrmFmt* DestFmt_Get( USHORT nPos ) const
+            { return (SwFrmFmt*)aDest[ nPos ]; }
+
+    void ChgBox( SwTableBox* pBox )
+    {
+        rOldTbl.GetTabSortBoxes().Remove( pBox );
+        pNewTblNd->GetTable().GetTabSortBoxes().Insert( pBox );
+    }
+};
+
+
+BOOL lcl_SplitTable_CpyBox( const SwTableBox*& rpBox, void* pPara );
+
+BOOL lcl_SplitTable_CpyLine( const SwTableLine*& rpLine, void* pPara )
+{
+    SwTableLine* pLn = (SwTableLine*)rpLine;
+    _SplitTable_Para& rPara = *(_SplitTable_Para*)pPara;
+
+    SwFrmFmt *pSrcFmt = pLn->GetFrmFmt();
+    USHORT nPos = rPara.SrcFmt_GetPos( pSrcFmt );
+    if( USHRT_MAX == nPos )
+    {
+        rPara.DestFmt_Insert( pLn->ClaimFrmFmt() );
+        rPara.SrcFmt_Insert( pSrcFmt );
+    }
+    else
+        pLn->ChgFrmFmt( (SwTableLineFmt*)rPara.DestFmt_Get( nPos ) );
+
+    pLn->GetTabBoxes().ForEach( &lcl_SplitTable_CpyBox, pPara );
+    return TRUE;
+}
+
+BOOL lcl_SplitTable_CpyBox( const SwTableBox*& rpBox, void* pPara )
+{
+    SwTableBox* pBox = (SwTableBox*)rpBox;
+    _SplitTable_Para& rPara = *(_SplitTable_Para*)pPara;
+
+    SwFrmFmt *pSrcFmt = pBox->GetFrmFmt();
+    USHORT nPos = rPara.SrcFmt_GetPos( pSrcFmt );
+    if( USHRT_MAX == nPos )
+    {
+        rPara.DestFmt_Insert( pBox->ClaimFrmFmt() );
+        rPara.SrcFmt_Insert( pSrcFmt );
+    }
+    else
+        pBox->ChgFrmFmt( (SwTableBoxFmt*)rPara.DestFmt_Get( nPos ) );
+
+    if( pBox->GetSttNd() )
+        rPara.ChgBox( pBox );
+    else
+        pBox->GetTabLines().ForEach( &lcl_SplitTable_CpyLine, pPara );
+    return TRUE;
+}
+
+SwTableNode* SwNodes::SplitTable( const SwNodeIndex& rPos, BOOL bAfter,
+                                    BOOL bCalcNewSize )
+{
+    SwNode* pNd = &rPos.GetNode();
+    SwTableNode* pTNd = pNd->FindTableNode();
+    if( !pTNd || pNd->IsTableNode() )
+        return 0;
+
+    ULONG nSttIdx = pNd->FindTableBoxStartNode()->GetIndex();
+
+    // Suche die Grund-Line dieser Box:
+    SwTable& rTbl = pTNd->GetTable();
+    SwTableBox* pBox = rTbl.GetTblBox( nSttIdx );
+    if( !pBox )
+        return 0;
+
+    SwTableLine* pLine = pBox->GetUpper();
+    while( pLine->GetUpper() )
+        pLine = pLine->GetUpper()->GetUpper();
+
+    // in pLine steht jetzt die GrundLine.
+    USHORT nLinePos = rTbl.GetTabLines().C40_GETPOS( SwTableLine, pLine );
+    if( USHRT_MAX == nLinePos ||
+        ( bAfter ? ++nLinePos >= rTbl.GetTabLines().Count() : !nLinePos ))
+        return 0;       // nicht gefunden oder letze Line !!
+
+    // Suche jetzt die 1. Box der nachfolgenden Line
+    SwTableLine* pNextLine = rTbl.GetTabLines()[ nLinePos ];
+    pBox = pNextLine->GetTabBoxes()[0];
+    while( !pBox->GetSttNd() )
+        pBox = pBox->GetTabLines()[0]->GetTabBoxes()[0];
+
+    // dann fuege mal einen End- und TabelleNode ins Nodes-Array ein.
+    SwTableNode * pNewTblNd;
+    {
+        SwEndNode* pOldTblEndNd = (SwEndNode*)pTNd->EndOfSectionNode()->GetEndNode();
+        ASSERT( pOldTblEndNd, "wo ist der EndNode?" )
+
+        SwNodeIndex aIdx( *pBox->GetSttNd() );
+        new SwEndNode( aIdx, *pTNd );
+        pNewTblNd = new SwTableNode( aIdx );
+
+        pOldTblEndNd->pStartOfSection = pNewTblNd;
+        pNewTblNd->pEndOfSection = pOldTblEndNd;
+
+        SwNode* pBoxNd = aIdx.GetNode().GetStartNode();
+        do {
+            ASSERT( pBoxNd->IsStartNode(), "das muss ein StartNode sein!" );
+            pBoxNd->pStartOfSection = pNewTblNd;
+            pBoxNd = (*this)[ pBoxNd->EndOfSectionIndex() + 1 ];
+        } while( pBoxNd != pOldTblEndNd );
+    }
+
+    {
+        // die Lines ruebermoven
+        SwTable& rNewTbl = pNewTblNd->GetTable();
+        rNewTbl.GetTabLines().Insert( &rTbl.GetTabLines(), 0, nLinePos );
+        // und loeschen
+        rTbl.GetTabLines().Remove( nLinePos,
+                                    rTbl.GetTabLines().Count() - nLinePos );
+
+        // und die betr. Boxen verschieben. Dabei die Formate eindeutig
+        // machen und die StartNodes korrigieren
+        _SplitTable_Para aPara( pNewTblNd, rTbl );
+        rNewTbl.GetTabLines().ForEach( &lcl_SplitTable_CpyLine, &aPara );
+    }
+
+    {
+        // Das Tabellen-FrmFormat kopieren
+        SwFrmFmt* pOldTblFmt = rTbl.GetFrmFmt();
+        SwFrmFmt* pNewTblFmt = pOldTblFmt->GetDoc()->MakeTblFrmFmt(
+                                pOldTblFmt->GetDoc()->GetUniqueTblName(),
+                                pOldTblFmt->GetDoc()->GetDfltFrmFmt() );
+
+        *pNewTblFmt = *pOldTblFmt;
+        pNewTblFmt->Add( &pNewTblNd->GetTable() );
+
+        // neue Size errechnen ? (lcl_ChgTblSize nur das 2. aufrufen, wenn es
+        // beim 1. schon geklappt hat; also absolute Groesse hat)
+        if( bCalcNewSize && lcl_ChgTblSize( rTbl ) )
+            lcl_ChgTblSize( pNewTblNd->GetTable() );
+    }
+
+    return pNewTblNd;       // das wars
+}
+
+// und die Umkehrung davon. rPos muss in der Tabelle stehen, die bestehen
+// bleibt. Das Flag besagt ob die aktuelle mit der davor oder dahinter
+// stehenden vereint wird.
+BOOL SwDoc::MergeTable( const SwPosition& rPos, BOOL bWithPrev, USHORT nMode )
+{
+    SwTableNode* pTblNd = rPos.nNode.GetNode().FindTableNode(), *pDelTblNd;
+    if( !pTblNd )
+        return FALSE;
+
+    SwNodes& rNds = GetNodes();
+    if( bWithPrev )
+        pDelTblNd = rNds[ pTblNd->GetIndex() - 1 ]->FindTableNode();
+    else
+        pDelTblNd = rNds[ pTblNd->EndOfSectionIndex() + 1 ]->GetTableNode();
+    if( !pDelTblNd )
+        return FALSE;
+
+    if( pTblNd->GetTable().ISA( SwDDETable ) ||
+        pDelTblNd->GetTable().ISA( SwDDETable ))
+        return FALSE;
+
+    // MIB 9.7.97: HTML-Layout loeschen
+    pTblNd->GetTable().SetHTMLTableLayout( 0 );
+    pDelTblNd->GetTable().SetHTMLTableLayout( 0 );
+
+    // beide Tabellen vorhanden, also kanns losgehen
+    SwUndoMergeTbl* pUndo = 0;
+    SwHistory* pHistory = 0;
+    if( DoesUndo() )
+    {
+        ClearRedo();
+        AppendUndo( pUndo = new SwUndoMergeTbl( *pTblNd, *pDelTblNd,
+                                                bWithPrev, nMode ));
+        pHistory = new SwHistory;
+    }
+
+    // alle "Tabellenformeln" anpassen
+    SwTableFmlUpdate aMsgHnt( &pTblNd->GetTable() );
+    aMsgHnt.DATA.pDelTbl = &pDelTblNd->GetTable();
+    aMsgHnt.eFlags = TBL_MERGETBL;
+    aMsgHnt.pHistory = pHistory;
+    UpdateTblFlds( &aMsgHnt );
+
+    // das eigentliche Mergen
+    SwNodeIndex aIdx( bWithPrev ? *pTblNd : *pDelTblNd );
+    BOOL bRet = rNds.MergeTable( aIdx, !bWithPrev, nMode, pHistory );
+
+    if( pHistory )
+    {
+        if( pHistory->Count() )
+            pUndo->SaveFormula( *pHistory );
+        delete pHistory;
+    }
+    if( bRet )
+    {
+        SetModified();
+        SetFieldsDirty( TRUE );
+    }
+    return bRet;
+}
+
+BOOL SwNodes::MergeTable( const SwNodeIndex& rPos, BOOL bWithPrev,
+                            USHORT nMode, SwHistory* pHistory )
+{
+    SwTableNode* pDelTblNd = rPos.GetNode().GetTableNode();
+    ASSERT( pDelTblNd, "wo ist der TableNode geblieben?" );
+
+    SwTableNode* pTblNd = (*this)[ rPos.GetIndex() - 1]->FindTableNode();
+    ASSERT( pTblNd, "wo ist der TableNode geblieben?" );
+
+    if( !pDelTblNd || !pTblNd )
+        return FALSE;
+
+    pDelTblNd->DelFrms();
+
+    SwTable& rDelTbl = pDelTblNd->GetTable();
+    SwTable& rTbl = pTblNd->GetTable();
+
+    //Lines fuer das Layout-Update herausuchen.
+    _FndBox aFndBox( 0, 0 );
+    aFndBox.SetTableLines( rTbl );
+    aFndBox.DelFrms( rTbl );
+    aFndBox.SaveChartData( rTbl );
+
+    // die Breite der TabellenFormate abgleichen:
+    {
+        const SwFmtFrmSize& rTblSz = rTbl.GetFrmFmt()->GetFrmSize();
+        const SwFmtFrmSize& rDelTblSz = rDelTbl.GetFrmFmt()->GetFrmSize();
+        if( rTblSz != rDelTblSz )
+        {
+            // dann sollten die mal schleunigst korrigiert werden
+            if( bWithPrev )
+                rDelTbl.GetFrmFmt()->SetAttr( rTblSz );
+            else
+                rTbl.GetFrmFmt()->SetAttr( rDelTblSz );
+        }
+    }
+
+    if( !bWithPrev )
+    {
+        // dann mussen alle Attruibute der hinteren Tabelle auf die
+        // vordere uebertragen werden, weil die hintere ueber das loeschen
+        // des Node geloescht wird.
+        rTbl.SetHeadlineRepeat( rDelTbl.IsHeadlineRepeat() );
+        rTbl.SetTblChgMode( rDelTbl.GetTblChgMode() );
+
+        rTbl.GetFrmFmt()->LockModify();
+        *rTbl.GetFrmFmt() = *rDelTbl.GetFrmFmt();
+        // auch den Namen umsetzen!
+        rTbl.GetFrmFmt()->SetName( rDelTbl.GetFrmFmt()->GetName() );
+        rTbl.GetFrmFmt()->UnlockModify();
+    }
+
+    // die Lines und Boxen ruebermoven
+    USHORT nOldSize = rTbl.GetTabLines().Count();
+    rTbl.GetTabLines().Insert( &rDelTbl.GetTabLines(), nOldSize );
+    rDelTbl.GetTabLines().Remove( 0, rDelTbl.GetTabLines().Count() );
+
+    rTbl.GetTabSortBoxes().Insert( &rDelTbl.GetTabSortBoxes() );
+    rDelTbl.GetTabSortBoxes().Remove( (USHORT)0, rDelTbl.GetTabSortBoxes().Count() );
+
+    // die vordere Tabelle bleibt immer stehen, die hintere wird geloescht
+    SwEndNode* pTblEndNd = pDelTblNd->EndOfSectionNode();
+    pTblNd->pEndOfSection = pTblEndNd;
+
+    SwNodeIndex aIdx( *pDelTblNd, 1 );
+
+    SwNode* pBoxNd = aIdx.GetNode().GetStartNode();
+    do {
+        ASSERT( pBoxNd->IsStartNode(), "das muss ein StartNode sein!" );
+        pBoxNd->pStartOfSection = pTblNd;
+        pBoxNd = (*this)[ pBoxNd->EndOfSectionIndex() + 1 ];
+    } while( pBoxNd != pTblEndNd );
+    pBoxNd->pStartOfSection = pTblNd;
+
+    aIdx -= 2;
+    DelNodes( aIdx, 2 );
+
+    // jetzt an der 1. eingefuegten Line die bedingten Vorlagen umschubsen
+    const SwTableLine* pFirstLn = rTbl.GetTabLines()[ nOldSize ];
+    if( 1 == nMode )        //
+    {
+        // Header-Vorlagen in der Zeile setzen
+        // und ggfs. in der History speichern fuers Undo!!!
+    }
+    lcl_LineSetHeadCondColl( pFirstLn, 0 );
+
+    // und die Borders "aufrauemen"
+    if( nOldSize )
+    {
+        _SwGCLineBorder aPara( rTbl );
+        aPara.nLinePos = --nOldSize;
+        pFirstLn = rTbl.GetTabLines()[ nOldSize ];
+        lcl_GC_Line_Border( pFirstLn, &aPara );
+    }
+
+    //Layout updaten
+    aFndBox.MakeFrms( rTbl );
+    aFndBox.RestoreChartData( rTbl );
+    return TRUE;
+}
+
+// -------------------------------------------------------------------
+
+
+// -- benutze die ForEach Methode vom PtrArray
+struct _SetAFmtTabPara
+{
+    SwTableAutoFmt& rTblFmt;
+    SwUndoTblAutoFmt* pUndo;
+    USHORT nEndBox, nCurBox;
+    BYTE nAFmtLine, nAFmtBox;
+
+    _SetAFmtTabPara( const SwTableAutoFmt& rNew )
+        : rTblFmt( (SwTableAutoFmt&)rNew ),
+        nEndBox( 0 ), nCurBox( 0 ), nAFmtLine( 0 ), nAFmtBox( 0 ), pUndo( 0 )
+    {}
+};
+
+// forward deklarieren damit sich die Lines und Boxen rekursiv aufrufen
+// koennen.
+BOOL lcl_SetAFmtBox( const _FndBox*&, void *pPara );
+BOOL lcl_SetAFmtLine( const _FndLine*&, void *pPara );
+
+BOOL lcl_SetAFmtLine( const _FndLine*& rpLine, void *pPara )
+{
+    ((_FndLine*&)rpLine)->GetBoxes().ForEach( &lcl_SetAFmtBox, pPara );
+    return TRUE;
+}
+
+BOOL lcl_SetAFmtBox( const _FndBox*& rpBox, void *pPara )
+{
+    _SetAFmtTabPara* pSetPara = (_SetAFmtTabPara*)pPara;
+
+    if( !rpBox->GetUpper()->GetUpper() )    // Box auf 1. Ebene ?
+    {
+        if( !pSetPara->nCurBox )
+            pSetPara->nAFmtBox = 0;
+        else if( pSetPara->nCurBox == pSetPara->nEndBox )
+            pSetPara->nAFmtBox = 3;
+        else
+            pSetPara->nAFmtBox = (BYTE)(1 + ((pSetPara->nCurBox-1) & 1));
+    }
+
+    if( rpBox->GetBox()->GetSttNd() )
+    {
+        SwTableBox* pSetBox = (SwTableBox*)rpBox->GetBox();
+        SwDoc* pDoc = pSetBox->GetFrmFmt()->GetDoc();
+        SfxItemSet aCharSet( pDoc->GetAttrPool(), RES_CHRATR_BEGIN, RES_PARATR_END-1 );
+        SfxItemSet aBoxSet( pDoc->GetAttrPool(), aTableBoxSetRange );
+        BYTE nPos = pSetPara->nAFmtLine * 4 + pSetPara->nAFmtBox;
+        pSetPara->rTblFmt.UpdateToSet( nPos, aCharSet,
+                                        SwTableAutoFmt::UPDATE_CHAR, 0 );
+        pSetPara->rTblFmt.UpdateToSet( nPos, aBoxSet,
+                                        SwTableAutoFmt::UPDATE_BOX,
+                                        pDoc->GetNumberFormatter( TRUE ) );
+        if( aCharSet.Count() )
+        {
+            ULONG nSttNd = pSetBox->GetSttIdx()+1;
+            ULONG nEndNd = pSetBox->GetSttNd()->EndOfSectionIndex();
+            for( ; nSttNd < nEndNd; ++nSttNd )
+            {
+                SwCntntNode* pNd = pDoc->GetNodes()[ nSttNd ]->GetCntntNode();
+                if( pNd )
+                    pNd->SetAttr( aCharSet );
+            }
+        }
+
+        if( aBoxSet.Count() )
+        {
+            if( pSetPara->pUndo &&
+                SFX_ITEM_SET == aBoxSet.GetItemState( RES_BOXATR_FORMAT ))
+                pSetPara->pUndo->SaveBoxCntnt( *pSetBox );
+
+            pSetBox->ClaimFrmFmt()->SetAttr( aBoxSet );
+        }
+    }
+    else
+        ((_FndBox*&)rpBox)->GetLines().ForEach( &lcl_SetAFmtLine, pPara );
+
+    if( !rpBox->GetUpper()->GetUpper() )        // eine BaseLine
+        ++pSetPara->nCurBox;
+    return TRUE;
+}
+
+
+        // AutoFormat fuer die Tabelle/TabellenSelection
+BOOL SwDoc::SetTableAutoFmt( const SwSelBoxes& rBoxes, const SwTableAutoFmt& rNew )
+{
+    ASSERT( rBoxes.Count(), "keine gueltige Box-Liste" );
+    SwTableNode* pTblNd = (SwTableNode*)rBoxes[0]->GetSttNd()->FindTableNode();
+    if( !pTblNd )
+        return FALSE;
+
+    // suche alle Boxen / Lines
+    _FndBox aFndBox( 0, 0 );
+    {
+        _FndPara aPara( rBoxes, &aFndBox );
+        pTblNd->GetTable().GetTabLines().ForEach( &_FndLineCopyCol, &aPara );
+    }
+    if( !aFndBox.GetLines().Count() )
+        return FALSE;
+
+    pTblNd->GetTable().SetHTMLTableLayout( 0 );
+
+    _FndBox* pFndBox = &aFndBox;
+    while( 1 == pFndBox->GetLines().Count() &&
+            1 == pFndBox->GetLines()[0]->GetBoxes().Count() )
+        pFndBox = pFndBox->GetLines()[0]->GetBoxes()[0];
+
+    if( !pFndBox->GetLines().Count() )      // eine zu weit? (nur 1 sel.Box)
+        pFndBox = pFndBox->GetUpper()->GetUpper();
+
+
+    // Undo abschalten, Attribute werden sich vorher gemerkt
+    SwUndoTblAutoFmt* pUndo = 0;
+    if( DoesUndo() )
+    {
+        ClearRedo();
+        AppendUndo( pUndo = new SwUndoTblAutoFmt( *pTblNd, rNew ) );
+        DoUndo( FALSE );
+    }
+
+    _SetAFmtTabPara aPara( rNew );
+    _FndLines& rFLns = pFndBox->GetLines();
+    _FndLine* pLine;
+
+    for( USHORT n = 0; n < rFLns.Count(); ++n )
+    {
+        pLine = rFLns[n];
+
+        // Upper auf 0 setzen (Base-Line simulieren!)
+        _FndBox* pSaveBox = pLine->GetUpper();
+        pLine->SetUpper( 0 );
+
+        if( !n )
+            aPara.nAFmtLine = 0;
+        else if( n+1 == rFLns.Count() )
+            aPara.nAFmtLine = 3;
+        else
+            aPara.nAFmtLine = (BYTE)(1 + ((n-1) & 1 ));
+
+        aPara.nAFmtBox = 0;
+        aPara.nCurBox = 0;
+        aPara.nEndBox = pLine->GetBoxes().Count()-1;
+        aPara.pUndo = pUndo;
+        pLine->GetBoxes().ForEach( &lcl_SetAFmtBox, &aPara );
+
+        pLine->SetUpper( pSaveBox );
+    }
+
+    if( pUndo )
+        DoUndo( TRUE );
+
+    SetModified();
+    SetFieldsDirty( TRUE );
+
+    return TRUE;
+}
+
+
+        // Erfrage wie attributiert ist
+BOOL SwDoc::GetTableAutoFmt( const SwSelBoxes& rBoxes, SwTableAutoFmt& rGet )
+{
+    ASSERT( rBoxes.Count(), "keine gueltige Box-Liste" );
+    SwTableNode* pTblNd = (SwTableNode*)rBoxes[0]->GetSttNd()->FindTableNode();
+    if( !pTblNd )
+        return FALSE;
+
+    // suche alle Boxen / Lines
+    _FndBox aFndBox( 0, 0 );
+    {
+        _FndPara aPara( rBoxes, &aFndBox );
+        pTblNd->GetTable().GetTabLines().ForEach( &_FndLineCopyCol, &aPara );
+    }
+    if( !aFndBox.GetLines().Count() )
+        return FALSE;
+
+    _FndBox* pFndBox = &aFndBox;
+    while( 1 == pFndBox->GetLines().Count() &&
+            1 == pFndBox->GetLines()[0]->GetBoxes().Count() )
+        pFndBox = pFndBox->GetLines()[0]->GetBoxes()[0];
+
+    if( !pFndBox->GetLines().Count() )      // eine zu weit? (nur 1 sel.Box)
+        pFndBox = pFndBox->GetUpper()->GetUpper();
+
+    _FndLines& rFLns = pFndBox->GetLines();
+
+    USHORT aLnArr[4];
+    aLnArr[0] = 0;
+    aLnArr[1] = 1 < rFLns.Count() ? 1 : 0;
+    aLnArr[2] = 2 < rFLns.Count() ? 2 : aLnArr[1];
+    aLnArr[3] = rFLns.Count() - 1;
+
+    for( BYTE nLine = 0; nLine < 4; ++nLine )
+    {
+        _FndLine& rLine = *rFLns[ aLnArr[ nLine ] ];
+
+        USHORT aBoxArr[4];
+        aBoxArr[0] = 0;
+        aBoxArr[1] = 1 < rLine.GetBoxes().Count() ? 1 : 0;
+        aBoxArr[2] = 2 < rLine.GetBoxes().Count() ? 2 : aBoxArr[1];
+        aBoxArr[3] = rLine.GetBoxes().Count() - 1;
+
+        for( BYTE nBox = 0; nBox < 4; ++nBox )
+        {
+            SwTableBox* pFBox = rLine.GetBoxes()[ aBoxArr[ nBox ] ]->GetBox();
+            // immer auf die 1. runterfallen
+            while( !pFBox->GetSttNd() )
+                pFBox = pFBox->GetTabLines()[0]->GetTabBoxes()[0];
+
+            BYTE nPos = nLine * 4 + nBox;
+            SwNodeIndex aIdx( *pFBox->GetSttNd(), 1 );
+            SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
+            if( !pCNd )
+                pCNd = GetNodes().GoNext( &aIdx );
+
+            if( pCNd )
+                rGet.UpdateFromSet( nPos, pCNd->GetSwAttrSet(),
+                                    SwTableAutoFmt::UPDATE_CHAR, 0 );
+            rGet.UpdateFromSet( nPos, pFBox->GetFrmFmt()->GetAttrSet(),
+                                SwTableAutoFmt::UPDATE_BOX,
+                                GetNumberFormatter( TRUE ) );
+        }
+    }
+
+    return TRUE;
+}
+
+String SwDoc::GetUniqueTblName() const
+{
+    ResId aId( STR_TABLE_DEFNAME, pSwResMgr );
+    String aName( aId );
+    xub_StrLen nNmLen = aName.Len();
+
+    USHORT nNum, nTmp, nFlagSize = ( pTblFrmFmtTbl->Count() / 8 ) +2;
+    BYTE* pSetFlags = new BYTE[ nFlagSize ];
+    memset( pSetFlags, 0, nFlagSize );
+
+    for( USHORT n = 0; n < pTblFrmFmtTbl->Count(); ++n )
+    {
+        const SwFrmFmt* pFmt = (*pTblFrmFmtTbl)[ n ];
+        if( !pFmt->IsDefault() && IsUsed( *pFmt )  &&
+            pFmt->GetName().Match( aName ) == nNmLen )
+        {
+            // Nummer bestimmen und das Flag setzen
+            nNum = pFmt->GetName().Copy( nNmLen ).ToInt32();
+            if( nNum-- && nNum < pTblFrmFmtTbl->Count() )
+                pSetFlags[ nNum / 8 ] |= (0x01 << ( nNum & 0x07 ));
+        }
+    }
+
+    // alle Nummern entsprechend geflag, also bestimme die richtige Nummer
+    nNum = pTblFrmFmtTbl->Count();
+    for( n = 0; n < nFlagSize; ++n )
+        if( 0xff != ( nTmp = pSetFlags[ n ] ))
+        {
+            // also die Nummer bestimmen
+            nNum = n * 8;
+            while( nTmp & 1 )
+                ++nNum, nTmp >>= 1;
+            break;
+        }
+
+    __DELETE( nFlagSize ) pSetFlags;
+    return aName += String::CreateFromInt32( ++nNum );
+}
+
+SwTableFmt* SwDoc::FindTblFmtByName( const String& rName, BOOL bAll ) const
+{
+    const SwFmt* pRet = 0;
+    if( bAll )
+        pRet = FindFmtByName( (SvPtrarr&)*pTblFrmFmtTbl, rName );
+    else
+    {
+        // dann nur die, die im Doc gesetzt sind
+        for( USHORT n = 0; n < pTblFrmFmtTbl->Count(); ++n )
+        {
+            const SwFrmFmt* pFmt = (*pTblFrmFmtTbl)[ n ];
+            if( !pFmt->IsDefault() && IsUsed( *pFmt ) &&
+                pFmt->GetName() == rName )
+            {
+                pRet = pFmt;
+                break;
+            }
+        }
+    }
+    return (SwTableFmt*)pRet;
+}
+
+BOOL SwDoc::SetColRowWidthHeight( SwTableBox& rAktBox, USHORT eType,
+                                    SwTwips nAbsDiff, SwTwips nRelDiff )
+{
+    SwTableNode* pTblNd = (SwTableNode*)rAktBox.GetSttNd()->FindTableNode();
+    SwUndo* pUndo = 0;
+
+    if( WH_FLAG_INSDEL & eType && pTblNd->GetTable().ISA( SwDDETable ))
+        return FALSE;
+
+    SwTableFmlUpdate aMsgHnt( &pTblNd->GetTable() );
+    aMsgHnt.eFlags = TBL_BOXPTR;
+    UpdateTblFlds( &aMsgHnt );
+
+    BOOL bRet = FALSE;
+    switch( eType & 0xff )
+    {
+    case WH_COL_LEFT:
+    case WH_COL_RIGHT:
+    case WH_CELL_LEFT:
+    case WH_CELL_RIGHT:
+        {
+             bRet = pTblNd->GetTable().SetColWidth( rAktBox,
+                                eType, nAbsDiff, nRelDiff,
+                                DoesUndo() ? &pUndo : 0 );
+        }
+        break;
+    case WH_ROW_TOP:
+    case WH_ROW_BOTTOM:
+    case WH_CELL_TOP:
+    case WH_CELL_BOTTOM:
+        bRet = pTblNd->GetTable().SetRowHeight( rAktBox,
+                            eType, nAbsDiff, nRelDiff,
+                            DoesUndo() ? &pUndo : 0 );
+        break;
+    }
+
+    if( pUndo )
+    {
+        ClearRedo();
+        AppendUndo( pUndo );
+        DoUndo( TRUE );     // im SetColWidth kann es abgeschaltet werden!
+    }
+
+    if( bRet )
+    {
+        SetModified();
+        if( WH_FLAG_INSDEL & eType )
+            SetFieldsDirty( TRUE );
+    }
+    return bRet;
+}
+
+
+void SwDoc::ChkBoxNumFmt( SwTableBox& rBox, BOOL bCallUpdate )
+{
+    //JP 09.07.97: Optimierung: wenn die Box schon sagt, das es Text
+    //                          sein soll, dann bleibt das auch Text!
+    const SfxPoolItem* pNumFmtItem = 0;
+    if( SFX_ITEM_SET == rBox.GetFrmFmt()->GetItemState( RES_BOXATR_FORMAT,
+        FALSE, &pNumFmtItem ) && GetNumberFormatter()->IsTextFormat(
+            ((SwTblBoxNumFormat*)pNumFmtItem)->GetValue() ))
+        return ;
+
+    SwUndoTblNumFmt* pUndo = 0;
+
+    BOOL bIsEmptyTxtNd, bChgd = TRUE;
+    ULONG nFmtIdx;
+    double fNumber;
+    if( rBox.HasNumCntnt( fNumber, nFmtIdx, bIsEmptyTxtNd ) )
+    {
+        if( !rBox.IsNumberChanged() )
+            bChgd = FALSE;
+        else
+        {
+            if( DoesUndo() )
+            {
+                StartUndo( UNDO_START );
+                pUndo = new SwUndoTblNumFmt( rBox );
+                pUndo->SetNumFmt( nFmtIdx, fNumber );
+            }
+
+            SwTableBoxFmt* pBoxFmt = (SwTableBoxFmt*)rBox.GetFrmFmt();
+            SfxItemSet aBoxSet( GetAttrPool(), RES_BOXATR_FORMAT, RES_BOXATR_VALUE );
+
+            BOOL bSetNumFmt = IsInsTblFormatNum(), bLockModify = TRUE;
+            if( bSetNumFmt )
+            {
+                if( !IsInsTblChangeNumFormat() )
+                {
+                    if( !pNumFmtItem )
+                        bSetNumFmt = FALSE;
+                    else
+                    {
+                        ULONG nOldNumFmt = ((SwTblBoxNumFormat*)pNumFmtItem)->
+                                            GetValue();
+                        SvNumberFormatter* pNumFmtr = GetNumberFormatter();
+
+                        short nFmtType = pNumFmtr->GetType( nFmtIdx );
+                        if( nFmtType == pNumFmtr->GetType( nOldNumFmt ) ||
+                            NUMBERFORMAT_NUMBER == nFmtType )
+                            // eingstelltes und vorgegebenes NumFormat
+                            // stimmen ueberein -> altes Format beibehalten
+                            nFmtIdx = nOldNumFmt;
+                        else
+                            // eingstelltes und vorgegebenes NumFormat
+                            // stimmen nicht ueberein -> als Text einfuegen
+                            bLockModify = bSetNumFmt = FALSE;
+                    }
+                }
+
+                if( bSetNumFmt )
+                {
+                    pBoxFmt = (SwTableBoxFmt*)rBox.ClaimFrmFmt();
+
+                    aBoxSet.Put( SwTblBoxValue( fNumber ));
+                    aBoxSet.Put( SwTblBoxNumFormat( nFmtIdx ));
+                }
+            }
+
+            // JP 28.04.98: Nur Formel zuruecksetzen reicht nicht.
+            //              Sorge dafuer, das der Text auch entsprechend
+            //              formatiert wird!
+
+            if( !bSetNumFmt && !bIsEmptyTxtNd && pNumFmtItem )
+            {
+                // JP 15.01.99: Nur Attribute zuruecksetzen reicht nicht.
+                //              Sorge dafuer, das der Text auch entsprechend
+                //              formatiert wird!
+                pBoxFmt->SetAttr( *GetDfltAttr( RES_BOXATR_FORMAT ));
+            }
+
+            if( bLockModify ) pBoxFmt->LockModify();
+            pBoxFmt->ResetAttr( RES_BOXATR_FORMAT, RES_BOXATR_VALUE );
+            if( bLockModify ) pBoxFmt->UnlockModify();
+
+            if( bSetNumFmt )
+                pBoxFmt->SetAttr( aBoxSet );
+        }
+    }
+    else
+    {
+        // es ist keine Zahl
+        const SfxPoolItem* pValueItem = 0, *pFmtItem = 0;
+        SwTableBoxFmt* pBoxFmt = (SwTableBoxFmt*)rBox.GetFrmFmt();
+        if( SFX_ITEM_SET == pBoxFmt->GetItemState( RES_BOXATR_FORMAT,
+                FALSE, &pFmtItem ) ||
+            SFX_ITEM_SET == pBoxFmt->GetItemState( RES_BOXATR_VALUE,
+                FALSE, &pValueItem ))
+        {
+            if( DoesUndo() )
+            {
+                StartUndo( UNDO_START );
+                pUndo = new SwUndoTblNumFmt( rBox );
+            }
+
+            pBoxFmt = (SwTableBoxFmt*)rBox.ClaimFrmFmt();
+
+            // alle Zahlenformate entfernen
+            USHORT nWhich1 = RES_BOXATR_FORMULA;
+            if( !bIsEmptyTxtNd )
+                //JP 15.01.99: dieser Teil wurde doch schon oben abgeprueft!
+                /* && pFmtItem && !GetNumberFormatter()->
+                IsTextFormat( ((SwTblBoxNumFormat*)pFmtItem)->GetValue() ) )*/
+            {
+                nWhich1 = RES_BOXATR_FORMAT;
+
+                // JP 15.01.99: Nur Attribute zuruecksetzen reicht nicht.
+                //              Sorge dafuer, das der Text auch entsprechend
+                //              formatiert wird!
+                pBoxFmt->SetAttr( *GetDfltAttr( nWhich1 ));
+            }
+            pBoxFmt->ResetAttr( nWhich1, RES_BOXATR_VALUE );
+        }
+        else
+            bChgd = FALSE;
+    }
+
+    if( bChgd )
+    {
+        if( pUndo )
+        {
+            pUndo->SetBox( rBox );
+            AppendUndo( pUndo );
+            EndUndo( UNDO_END );
+        }
+
+        if( bCallUpdate )
+        {
+            const SwTableNode* pTblNd = rBox.GetSttNd()->FindTableNode();
+            SwTableFmlUpdate aTblUpdate( &pTblNd->GetTable() );
+            UpdateTblFlds( &aTblUpdate );
+        }
+        SetModified();
+    }
+}
+
+void SwDoc::SetTblBoxFormulaAttrs( SwTableBox& rBox, const SfxItemSet& rSet )
+{
+    if( DoesUndo() )
+    {
+        ClearRedo();
+        AppendUndo( new SwUndoTblNumFmt( rBox, &rSet ) );
+    }
+
+    SwFrmFmt* pBoxFmt = rBox.ClaimFrmFmt();
+    if( SFX_ITEM_SET == rSet.GetItemState( RES_BOXATR_FORMULA ))
+    {
+        pBoxFmt->LockModify();
+        pBoxFmt->ResetAttr( RES_BOXATR_VALUE );
+        pBoxFmt->UnlockModify();
+    }
+    else if( SFX_ITEM_SET == rSet.GetItemState( RES_BOXATR_VALUE ))
+    {
+        pBoxFmt->LockModify();
+        pBoxFmt->ResetAttr( RES_BOXATR_FORMULA );
+        pBoxFmt->UnlockModify();
+    }
+    pBoxFmt->SetAttr( rSet );
+    SetModified();
+}
+
+void SwDoc::ClearBoxNumAttrs( const SwNodeIndex& rNode )
+{
+    SwStartNode* pSttNd;
+    if( 0 != ( pSttNd = GetNodes()[ rNode ]->
+                                FindSttNodeByType( SwTableBoxStartNode )) &&
+        2 == pSttNd->EndOfSectionIndex() - pSttNd->GetIndex() )
+    {
+        SwTableBox* pBox = pSttNd->FindTableNode()->GetTable().
+                            GetTblBox( pSttNd->GetIndex() );
+
+        const SfxPoolItem* pFmtItem = 0;
+        const SfxItemSet& rSet = pBox->GetFrmFmt()->GetAttrSet();
+        if( SFX_ITEM_SET == rSet.GetItemState( RES_BOXATR_FORMAT, FALSE, &pFmtItem ) ||
+            SFX_ITEM_SET == rSet.GetItemState( RES_BOXATR_FORMULA, FALSE ) ||
+            SFX_ITEM_SET == rSet.GetItemState( RES_BOXATR_VALUE, FALSE ))
+        {
+            if( DoesUndo() )
+            {
+                ClearRedo();
+                AppendUndo( new SwUndoTblNumFmt( *pBox ) );
+            }
+
+            SwFrmFmt* pBoxFmt = pBox->ClaimFrmFmt();
+
+            //JP 01.09.97: TextFormate bleiben erhalten!
+            USHORT nWhich1 = RES_BOXATR_FORMAT;
+            if( pFmtItem && GetNumberFormatter()->IsTextFormat(
+                    ((SwTblBoxNumFormat*)pFmtItem)->GetValue() ))
+                nWhich1 = RES_BOXATR_FORMULA;
+            else
+                // JP 15.01.99: Nur Attribute zuruecksetzen reicht nicht.
+                //              Sorge dafuer, das der Text auch entsprechend
+                //              formatiert wird!
+                pBoxFmt->SetAttr( *GetDfltAttr( RES_BOXATR_FORMAT ));
+
+            pBoxFmt->ResetAttr( nWhich1, RES_BOXATR_VALUE );
+            SetModified();
+        }
+    }
+}
+
+BOOL SwDoc::CopyTblInTbl( const SwTable& rSrcTable, SwTable& rDestTable,
+                            const SwNodeIndex& rBoxIdx )
+{
+    SwUndoTblCpyTbl* pUndo = 0;
+    if( DoesUndo() )
+    {
+        ClearRedo();
+        pUndo = new SwUndoTblCpyTbl;
+    }
+
+    BOOL bRet;
+    if( rSrcTable.IsTblComplex() )
+        bRet = rDestTable.InsTable( rSrcTable, rBoxIdx, pUndo );
+    else
+    {
+        SwSelBoxes aBoxes;
+        SwTableBox* pBox = rDestTable.GetTblBox( rBoxIdx.GetIndex() );
+        aBoxes.Insert( pBox );
+
+        bRet = rDestTable.InsTable( rSrcTable, aBoxes, pUndo );
+    }
+
+    if( bRet )
+    {
+        if( pUndo )
+            AppendUndo( pUndo );
+        SetFieldsDirty( TRUE );
+    }
+    else if( pUndo )
+        delete pUndo;
+
+    return bRet;
+}
+
+
+// kopiert eine Tabelle aus dem selben oder einem anderen Doc in sich
+// selbst. Dabei wird eine neue Tabelle angelegt oder eine bestehende
+// mit dem Inhalt gefuellt; wobei entweder der Inhalt ab einer Box oder
+// in eine bestehende TblSelektion gefuellt wird.
+// Gerufen wird es von: edglss.cxx/fecopy.cxx
+
+BOOL SwDoc::InsCopyOfTbl( SwPosition& rInsPos, const SwSelBoxes& rBoxes,
+                        const SwTable* pCpyTbl, BOOL bCpyName, BOOL bCorrPos )
+{
+    BOOL bRet;
+
+    const SwTableNode* pSrcTblNd = pCpyTbl
+            ? pCpyTbl->GetTableNode()
+            : rBoxes[ 0 ]->GetSttNd()->FindTableNode();
+
+    SwTableNode* pInsTblNd = GetNodes()[ rInsPos.nNode ]->FindTableNode();
+
+    if( !pCpyTbl && !pInsTblNd )
+    {
+        SwUndoCpyTbl* pUndo = 0;
+        if( DoesUndo() )
+        {
+            ClearRedo();
+            pUndo = new SwUndoCpyTbl;
+            DoUndo( FALSE );
+        }
+
+        bRet = pSrcTblNd->GetTable().MakeCopy( this, rInsPos, rBoxes,
+                                                TRUE, bCpyName );
+        if( pUndo )
+        {
+            if( !bRet )
+                delete pUndo;
+            else
+            {
+                pInsTblNd = GetNodes()[ rInsPos.nNode.GetIndex() - 1 ]->FindTableNode();
+
+                pUndo->SetTableSttIdx( pInsTblNd->GetIndex() );
+                AppendUndo( pUndo );
+            }
+            DoUndo( TRUE );
+        }
+    }
+    else
+    {
+        SwUndoTblCpyTbl* pUndo = 0;
+        if( DoesUndo() )
+        {
+            ClearRedo();
+            pUndo = new SwUndoTblCpyTbl;
+            DoUndo( FALSE );
+        }
+
+        SwDoc* pCpyDoc = (SwDoc*)pSrcTblNd->GetDoc();
+        BOOL bDelCpyDoc = pCpyDoc == this;
+
+        if( bDelCpyDoc )
+        {
+            // kopiere die Tabelle erstmal in ein temp. Doc
+            pCpyDoc = new SwDoc;
+
+            SwPosition aPos( SwNodeIndex( pCpyDoc->GetNodes().GetEndOfContent() ));
+            if( !pSrcTblNd->GetTable().MakeCopy( pCpyDoc, aPos, rBoxes, TRUE, TRUE ))
+            {
+                delete pCpyDoc;
+                if( pUndo )
+                {
+                    DoUndo( TRUE );
+                    delete pUndo;
+                }
+                return FALSE;
+            }
+            aPos.nNode -= 1;        // auf den EndNode der Tabelle
+            pSrcTblNd = aPos.nNode.GetNode().FindTableNode();
+        }
+
+        const SwStartNode* pSttNd = rInsPos.nNode.GetNode().FindTableBoxStartNode();
+
+        rInsPos.nContent.Assign( 0, 0 );
+
+        // keine complexe Tabelle ??
+        if( !pSrcTblNd->GetTable().IsTblComplex() &&
+            (bDelCpyDoc || rBoxes.Count() ))
+        {
+            // dann die Tabelle "relativ" kopieren
+            const SwSelBoxes* pBoxes;
+            SwSelBoxes aBoxes;
+
+            if( bDelCpyDoc )
+            {
+                SwTableBox* pBox = pInsTblNd->GetTable().GetTblBox(
+                                        pSttNd->GetIndex() );
+                ASSERT( pBox, "Box steht nicht in dieser Tabelle" );
+                aBoxes.Insert( pBox );
+                pBoxes = &aBoxes;
+            }
+            else
+                pBoxes = &rBoxes;
+
+            // kopiere die Tabelle in die selktierten Zellen.
+            bRet = pInsTblNd->GetTable().InsTable( pSrcTblNd->GetTable(),
+                                                        *pBoxes, pUndo );
+        }
+        else
+        {
+            SwNodeIndex aNdIdx( *pSttNd, 1 );
+            bRet = pInsTblNd->GetTable().InsTable( pSrcTblNd->GetTable(),
+                                                    aNdIdx, pUndo );
+        }
+
+        if( bDelCpyDoc )
+            delete pCpyDoc;
+
+        if( pUndo )
+        {
+            // falls die Tabelle nicht kopiert werden konnte, das Undo-Object
+            // wieder loeschen
+            if( !bRet && pUndo->IsEmpty() )
+                delete pUndo;
+            else
+                AppendUndo( pUndo );
+            DoUndo( TRUE );
+        }
+
+        if( bCorrPos )
+        {
+            rInsPos.nNode = *pSttNd;
+            rInsPos.nContent.Assign( GetNodes().GoNext( &rInsPos.nNode ), 0 );
+        }
+    }
+
+    if( bRet )
+    {
+        SetModified();
+        SetFieldsDirty( TRUE );
+    }
+    return bRet;
+}
+
+
+
+BOOL SwDoc::_UnProtectTblCells( SwTable& rTbl )
+{
+    BOOL bChgd = FALSE;
+    SwUndoAttrTbl* pUndo = DoesUndo() ? new SwUndoAttrTbl( *rTbl.GetTableNode() )
+                                      : 0;
+
+    SwTableSortBoxes& rSrtBox = rTbl.GetTabSortBoxes();
+    for( USHORT i = rSrtBox.Count(); i; )
+    {
+        SwFrmFmt *pBoxFmt = rSrtBox[ --i ]->GetFrmFmt();
+        if( pBoxFmt->GetProtect().IsCntntProtected() )
+        {
+            pBoxFmt->ResetAttr( RES_PROTECT );
+            bChgd = TRUE;
+        }
+    }
+
+    if( pUndo )
+    {
+        if( bChgd )
+        {
+            ClearRedo();
+            AppendUndo( pUndo );
+        }
+        else
+            delete pUndo;
+    }
+    return bChgd;
+}
+
+
+BOOL SwDoc::UnProtectCells( const String& rName )
+{
+    BOOL bChgd = FALSE;
+    SwTableFmt* pFmt = FindTblFmtByName( rName );
+    if( pFmt )
+    {
+        bChgd = _UnProtectTblCells( *SwTable::FindTable( pFmt ) );
+        if( bChgd )
+            SetModified();
+    }
+
+    return bChgd;
+}
+
+BOOL SwDoc::UnProtectCells( const SwSelBoxes& rBoxes )
+{
+    BOOL bChgd = FALSE;
+    if( rBoxes.Count() )
+    {
+        SwUndoAttrTbl* pUndo = DoesUndo()
+                ? new SwUndoAttrTbl( *rBoxes[0]->GetSttNd()->FindTableNode() )
+                : 0;
+
+        SvPtrarr aFmts( 16 ), aNewFmts( 16 );
+        for( USHORT i = rBoxes.Count(); i; )
+        {
+            SwTableBox* pBox = rBoxes[ --i ];
+            SwFrmFmt* pBoxFmt = pBox->GetFrmFmt();
+            if( pBoxFmt->GetProtect().IsCntntProtected() )
+            {
+                USHORT nFnd = aFmts.GetPos( pBoxFmt );
+                if( USHRT_MAX != nFnd )
+                    pBox->ChgFrmFmt( (SwTableBoxFmt*)aNewFmts[ nFnd ] );
+                else
+                {
+                    aFmts.Insert( pBoxFmt, aFmts.Count() );
+                    pBoxFmt = pBox->ClaimFrmFmt();
+                    pBoxFmt->ResetAttr( RES_PROTECT );
+                    aNewFmts.Insert( pBoxFmt, aNewFmts.Count() );
+                }
+                bChgd = TRUE;
+            }
+        }
+
+        if( pUndo )
+        {
+            if( bChgd )
+            {
+                ClearRedo();
+                AppendUndo( pUndo );
+            }
+            else
+                delete pUndo;
+        }
+    }
+    return bChgd;
+}
+
+BOOL SwDoc::UnProtectTbls( const SwPaM& rPam )
+{
+    StartUndo();
+
+    BOOL bChgd = FALSE, bHasSel = rPam.HasMark() ||
+                                    rPam.GetNext() != (SwPaM*)&rPam;
+    SwFrmFmts& rFmts = *GetTblFrmFmts();
+    SwTable* pTbl;
+    const SwTableNode* pTblNd;
+    for( USHORT n = rFmts.Count(); n ; )
+        if( 0 != (pTbl = SwTable::FindTable( rFmts[ --n ] )) &&
+            0 != (pTblNd = pTbl->GetTableNode() ) &&
+            pTblNd->GetNodes().IsDocNodes() )
+        {
+            ULONG nTblIdx = pTblNd->GetIndex();
+
+            // dann ueberpruefe ob Tabelle in der Selection liegt
+            if( bHasSel )
+            {
+                int bFound = FALSE;
+                SwPaM* pTmp = (SwPaM*)&rPam;
+                do {
+                    const SwPosition *pStt = pTmp->Start(),
+                                    *pEnd = pTmp->End();
+                    bFound = pStt->nNode.GetIndex() < nTblIdx &&
+                            nTblIdx < pEnd->nNode.GetIndex();
+
+                } while( !bFound && &rPam != ( pTmp = (SwPaM*)pTmp->GetNext() ) );
+                if( !bFound )
+                    continue;       // weitersuchen
+            }
+
+            // dann mal den Schutz aufheben
+            bChgd |= _UnProtectTblCells( *pTbl );
+        }
+
+    EndUndo();
+    if( bChgd )
+        SetModified();
+
+    return bChgd;
+}
+
+BOOL SwDoc::HasTblAnyProtection( const SwPosition* pPos,
+                                 const String* pTblName,
+                                 BOOL* pFullTblProtection )
+{
+    BOOL bHasProtection = FALSE;
+    SwTable* pTbl = 0;
+    if( pTblName )
+        pTbl = SwTable::FindTable( FindTblFmtByName( *pTblName ) );
+    else if( pPos )
+    {
+        SwTableNode* pTblNd = pPos->nNode.GetNode().FindTableNode();
+        if( pTblNd )
+            pTbl = &pTblNd->GetTable();
+    }
+
+    if( pTbl )
+    {
+        SwTableSortBoxes& rSrtBox = pTbl->GetTabSortBoxes();
+        for( USHORT i = rSrtBox.Count(); i; )
+        {
+            SwFrmFmt *pBoxFmt = rSrtBox[ --i ]->GetFrmFmt();
+            if( pBoxFmt->GetProtect().IsCntntProtected() )
+            {
+                if( !bHasProtection )
+                {
+                    bHasProtection = TRUE;
+                    if( !pFullTblProtection )
+                        break;
+                    *pFullTblProtection = TRUE;
+                }
+            }
+            else if( bHasProtection && pFullTblProtection )
+            {
+                *pFullTblProtection = FALSE;
+                break;
+            }
+        }
+    }
+    return bHasProtection;
+}
+
+BOOL SwDoc::GCTableBorder( const SwPosition& rPos )
+{
+    SwNode* pNd = &rPos.nNode.GetNode();
+    SwTableNode* pTNd = pNd->FindTableNode();
+    if( !pTNd || pNd->IsTableNode() )
+        return FALSE;
+
+    if( pTNd->GetTable().ISA( SwDDETable ))
+        return FALSE;
+
+    SwTable& rTbl = pTNd->GetTable();
+    rTbl.SetHTMLTableLayout( 0 );   // MIB 9.7.97: HTML-Layout loeschen
+
+    if( DoesUndo() )
+    {
+        ClearRedo();
+        AppendUndo( new SwUndoAttrTbl( *pTNd ));
+    }
+
+    rTbl.GCBorderLines();
+    SetModified();
+
+    return TRUE;
+}
+
diff --git a/sw/source/core/docnode/ndtbl1.cxx b/sw/source/core/docnode/ndtbl1.cxx
new file mode 100644
index 000000000000..42b42a1b4f8b
--- /dev/null
+++ b/sw/source/core/docnode/ndtbl1.cxx
@@ -0,0 +1,1478 @@
+/*************************************************************************
+ *
+ *  $RCSfile: ndtbl1.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:17 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#define ITEMID_BOXINFO      SID_ATTR_BORDER_INNER
+#ifdef WTC
+#define private public
+#endif
+
+#include "hintids.hxx"
+
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BOXITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BRSHITEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _FMTORNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFSIZE_HXX //autogen
+#include 
+#endif
+#ifndef _TABCOL_HXX //autogen
+#include 
+#endif
+#ifndef _FRMATR_HXX
+#include 
+#endif
+#ifndef _CELLFRM_HXX //autogen
+#include 
+#endif
+#ifndef _TABFRM_HXX //autogen
+#include 
+#endif
+#ifndef _CNTFRM_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFRM_HXX //autogen
+#include 
+#endif
+
+#include "doc.hxx"
+#include "pam.hxx"
+#include "swcrsr.hxx"
+#include "viscrs.hxx"
+#include "swtable.hxx"
+#include "htmltbl.hxx"
+#include "tblsel.hxx"
+#include "swtblfmt.hxx"
+#include "docary.hxx"
+#include "ndindex.hxx"
+#include "undobj.hxx"
+
+
+extern void ClearFEShellTabCols();
+
+//siehe auch swtable.cxx
+#define COLFUZZY 20L
+
+inline BOOL IsSame( long nA, long nB ) { return  Abs(nA-nB) <= COLFUZZY; }
+
+class SwTblFmtCmp
+{
+public:
+    SwFrmFmt *pOld,
+             *pNew;
+    INT16     nType;
+
+    SwTblFmtCmp( SwFrmFmt *pOld, SwFrmFmt *pNew, INT16 nType );
+
+    static SwFrmFmt *FindNewFmt( SvPtrarr &rArr, SwFrmFmt*pOld, INT16 nType );
+    static void Delete( SvPtrarr &rArr );
+};
+
+
+SwTblFmtCmp::SwTblFmtCmp( SwFrmFmt *pO, SwFrmFmt *pN, INT16 nT )
+    : pOld ( pO ), pNew ( pN ), nType( nT )
+{
+}
+
+SwFrmFmt *SwTblFmtCmp::FindNewFmt( SvPtrarr &rArr, SwFrmFmt *pOld, INT16 nType )
+{
+    for ( USHORT i = 0; i < rArr.Count(); ++i )
+    {
+        SwTblFmtCmp *pCmp = (SwTblFmtCmp*)rArr[i];
+        if ( pCmp->pOld == pOld && pCmp->nType == nType )
+            return pCmp->pNew;
+    }
+    return 0;
+}
+
+void SwTblFmtCmp::Delete( SvPtrarr &rArr )
+{
+    for ( USHORT i = 0; i < rArr.Count(); ++i )
+        delete (SwTblFmtCmp*)rArr[i];
+}
+
+void lcl_GetStartEndCell( const SwCursor& rCrsr,
+                        SwLayoutFrm *&prStart, SwLayoutFrm *&prEnd )
+{
+    ASSERT( rCrsr.GetCntntNode() && rCrsr.GetCntntNode( FALSE ),
+            "Tabselection nicht auf Cnt." );
+
+    Point aPtPos, aMkPos;
+    const SwShellCrsr* pShCrsr = rCrsr;
+    if( pShCrsr )
+    {
+        aPtPos = pShCrsr->GetPtPos();
+        aMkPos = pShCrsr->GetMkPos();
+    }
+
+    prStart = rCrsr.GetCntntNode()->GetFrm( &aPtPos )->GetUpper();
+    prEnd   = rCrsr.GetCntntNode(FALSE)->GetFrm( &aMkPos )->GetUpper();
+}
+
+BOOL lcl_GetBoxSel( const SwCursor& rCursor, SwSelBoxes& rBoxes,
+                    BOOL bAllCrsr = FALSE )
+{
+    const SwTableCursor* pTblCrsr = rCursor;
+    if( pTblCrsr )
+        ::GetTblSelCrs( *pTblCrsr, rBoxes );
+    else
+    {
+        const SwPaM *pCurPam = &rCursor, *pSttPam = pCurPam;
+        do {
+            const SwNode* pNd = pCurPam->GetNode()->FindTableBoxStartNode();
+            if( pNd )
+            {
+                SwTableBox* pBox = (SwTableBox*)pNd->FindTableNode()->GetTable().
+                                            GetTblBox( pNd->GetIndex() );
+                rBoxes.Insert( pBox );
+            }
+        } while( bAllCrsr &&
+                pSttPam != ( pCurPam = (SwPaM*)pCurPam->GetNext()) );
+    }
+    return 0 != rBoxes.Count();
+}
+
+/***********************************************************************
+#*  Class      :  SwDoc
+#*  Methoden   :  SetRowHeight(), GetRowHeight()
+#*  Datum      :  MA 17. May. 93
+#*  Update     :  JP 28.04.98
+#***********************************************************************/
+//Die Zeilenhoehe wird ausgehend von der Selektion ermittelt/gesetzt.
+//Ausgehend von jeder Zelle innerhalb der Selektion werden nach oben alle
+//Zeilen abgeklappert, die oberste Zeile erhaelt den gewuenschten Wert alle
+//tieferliegenden Zeilen einen entsprechenden Wert der sich aus der
+//Relation der alten und neuen Groesse der obersten Zeile und ihrer
+//eigenen Groesse ergiebt.
+//Alle veraenderten Zeilen erhalten ggf. ein eigenes FrmFmt.
+//Natuerlich darf jede Zeile nur einmal angefasst werden.
+
+inline void InsertLine( SvPtrarr& rLineArr, SwTableLine* pLine )
+{
+    if( USHRT_MAX == rLineArr.GetPos( (void*&)pLine ) )
+        rLineArr.Insert( (void*&)pLine, rLineArr.Count() );
+}
+
+//-----------------------------------------------------------------------------
+
+BOOL lcl_IsAnLower( const SwTableLine *pLine, const SwTableLine *pAssumed )
+{
+    const SwTableLine *pTmp = pAssumed->GetUpper() ?
+                                    pAssumed->GetUpper()->GetUpper() : 0;
+    while ( pTmp )
+    {
+        if ( pTmp == pLine )
+            return TRUE;
+        pTmp = pTmp->GetUpper() ? pTmp->GetUpper()->GetUpper() : 0;
+    }
+    return FALSE;
+}
+//-----------------------------------------------------------------------------
+
+struct LinesAndTable
+{
+          SvPtrarr &rLines;
+    const SwTable  &rTable;
+          BOOL      bInsertLines;
+
+    LinesAndTable( SvPtrarr &rL, const SwTable &rTbl ) :
+          rLines( rL ), rTable( rTbl ), bInsertLines( TRUE ) {}
+};
+
+
+BOOL _FindLine( const _FndLine*& rpLine, void* pPara );
+
+BOOL _FindBox( const _FndBox*& rpBox, void* pPara )
+{
+    if ( rpBox->GetLines().Count() )
+    {
+        ((LinesAndTable*)pPara)->bInsertLines = TRUE;
+        ((_FndBox*)rpBox)->GetLines().ForEach( _FindLine, pPara );
+        if ( ((LinesAndTable*)pPara)->bInsertLines )
+        {
+            const SwTableLines &rLines = rpBox->GetBox()
+                                    ? rpBox->GetBox()->GetTabLines()
+                                    : ((LinesAndTable*)pPara)->rTable.GetTabLines();
+            if ( rpBox->GetLines().Count() == rLines.Count() )
+            {
+                for ( USHORT i = 0; i < rLines.Count(); ++i )
+                    ::InsertLine( ((LinesAndTable*)pPara)->rLines,
+                                  (SwTableLine*)rLines[i] );
+            }
+            else
+                ((LinesAndTable*)pPara)->bInsertLines = FALSE;
+        }
+    }
+    else if ( rpBox->GetBox() )
+        ::InsertLine( ((LinesAndTable*)pPara)->rLines,
+                      (SwTableLine*)rpBox->GetBox()->GetUpper() );
+    return TRUE;
+}
+
+BOOL _FindLine( const _FndLine*& rpLine, void* pPara )
+{
+    ((_FndLine*)rpLine)->GetBoxes().ForEach( _FindBox, pPara );
+    return TRUE;
+}
+
+void lcl_CollectLines( SvPtrarr &rArr, const SwCursor& rCursor )
+{
+    //Zuerst die selektierten Boxen einsammeln.
+    SwSelBoxes aBoxes;
+    if( !::lcl_GetBoxSel( rCursor, aBoxes ))
+        return ;
+
+    //Die selektierte Struktur kopieren.
+    const SwTable &rTable = aBoxes[0]->GetSttNd()->FindTableNode()->GetTable();
+    LinesAndTable aPara( rArr, rTable );
+    _FndBox aFndBox( 0, 0 );
+    {
+        _FndPara aPara( aBoxes, &aFndBox );
+        ((SwTableLines&)rTable.GetTabLines()).ForEach( &_FndLineCopyCol, &aPara );
+    }
+
+    //Diejenigen Lines einsammeln, die nur selektierte Boxen enthalten.
+    const _FndBox *pTmp = &aFndBox;
+    ::_FindBox( pTmp, &aPara );
+
+    //Jetzt die Lines entfernen, die von einer gemeinsamen uebergeordneten Line
+    //erfasst werden.
+    for ( USHORT i = 0; i < rArr.Count(); ++i )
+    {
+        SwTableLine *pUpLine = (SwTableLine*)rArr[i];
+        for ( USHORT k = 0; k < rArr.Count(); ++k )
+        {
+            if ( k != i && ::lcl_IsAnLower( pUpLine, (SwTableLine*)rArr[k] ) )
+            {
+                rArr.Remove( k );
+                if ( k <= i )
+                    --i;
+                --k;
+            }
+        }
+    }
+}
+
+//-----------------------------------------------------------------------------
+
+void lcl_ProcessBoxSize( SvPtrarr &rFmtCmp, SwTableBox *pBox, const SwFmtFrmSize &rNew );
+
+void lcl_ProcessRowSize( SvPtrarr &rFmtCmp, SwTableLine *pLine, const SwFmtFrmSize &rNew )
+{
+    SwFrmFmt *pNewFmt;
+    if ( 0 != (pNewFmt = SwTblFmtCmp::FindNewFmt( rFmtCmp, pLine->GetFrmFmt(), 0 )))
+        pLine->ChgFrmFmt( (SwTableLineFmt*)pNewFmt );
+    else
+    {
+        SwFrmFmt *pOld = pLine->GetFrmFmt();
+        SwFrmFmt *pNew = pLine->ClaimFrmFmt();
+        pNew->SetAttr( rNew );
+        rFmtCmp.Insert( new SwTblFmtCmp( pOld, pNew, 0 ), rFmtCmp.Count());
+    }
+    SwTableBoxes &rBoxes = pLine->GetTabBoxes();
+    for ( USHORT i = 0; i < rBoxes.Count(); ++i )
+        ::lcl_ProcessBoxSize( rFmtCmp, rBoxes[i], rNew );
+}
+
+//-----------------------------------------------------------------------------
+
+void lcl_ProcessBoxSize( SvPtrarr &rFmtCmp, SwTableBox *pBox, const SwFmtFrmSize &rNew )
+{
+    SwTableLines &rLines = pBox->GetTabLines();
+    if ( rLines.Count() )
+    {
+        SwFmtFrmSize aSz( rNew );
+        aSz.SetHeight( rNew.GetHeight() ? rNew.GetHeight() / rLines.Count() : 0 );
+        for ( USHORT i = 0; i < rLines.Count(); ++i )
+            ::lcl_ProcessRowSize( rFmtCmp, rLines[i], aSz );
+    }
+}
+
+/******************************************************************************
+ *              void SwDoc::SetRowHeight( SwTwips nNew )
+ ******************************************************************************/
+void SwDoc::SetRowHeight( const SwCursor& rCursor, const SwFmtFrmSize &rNew )
+{
+    SwTableNode* pTblNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode();
+    if( pTblNd )
+    {
+        SvPtrarr aRowArr( 25, 50 ); //Zum sammeln Lines.
+        ::lcl_CollectLines( aRowArr, rCursor );
+
+        if( aRowArr.Count() )
+        {
+            if( DoesUndo() )
+            {
+                ClearRedo();
+                AppendUndo( new SwUndoAttrTbl( *pTblNd ));
+            }
+
+            SvPtrarr aFmtCmp( Max( BYTE(255), BYTE(aRowArr.Count()) ), 255 );
+            for ( USHORT i = 0; i < aRowArr.Count(); ++i )
+                ::lcl_ProcessRowSize( aFmtCmp, (SwTableLine*)aRowArr[i], rNew );
+            SwTblFmtCmp::Delete( aFmtCmp );
+
+            SetModified();
+        }
+    }
+}
+
+
+/******************************************************************************
+ *               SwTwips SwDoc::GetRowHeight() const
+ ******************************************************************************/
+void SwDoc::GetRowHeight( const SwCursor& rCursor, SwFmtFrmSize *& rpSz ) const
+{
+    rpSz = 0;
+
+    SwTableNode* pTblNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode();
+    if( pTblNd )
+    {
+        SvPtrarr aRowArr( 25, 50 ); //Zum sammeln der Lines.
+        ::lcl_CollectLines( aRowArr, rCursor );
+
+        if( aRowArr.Count() )
+        {
+            rpSz = &(SwFmtFrmSize&)((SwTableLine*)aRowArr[0])->
+                                                GetFrmFmt()->GetFrmSize();
+
+            for ( USHORT i = 1; i < aRowArr.Count() && rpSz; ++i )
+            {
+                if ( *rpSz != ((SwTableLine*)aRowArr[i])->GetFrmFmt()->GetFrmSize() )
+                    rpSz = 0;
+            }
+            if ( rpSz )
+                rpSz = new SwFmtFrmSize( *rpSz );
+        }
+    }
+}
+
+BOOL SwDoc::BalanceRowHeight( const SwCursor& rCursor, BOOL bTstOnly )
+{
+    BOOL bRet = FALSE;
+    SwTableNode* pTblNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode();
+    if( pTblNd )
+    {
+        SvPtrarr aRowArr( 25, 50 ); //Zum sammeln der Lines.
+        ::lcl_CollectLines( aRowArr, rCursor );
+
+        if( 1 < aRowArr.Count() )
+        {
+            if( !bTstOnly )
+            {
+                long nHeight = 0;
+                for ( USHORT i = 0; i < aRowArr.Count(); ++i )
+                {
+                    SwClientIter aIter( *((SwTableLine*)aRowArr[i])->GetFrmFmt() );
+                    SwFrm* pFrm = (SwFrm*)aIter.First( TYPE(SwFrm) );
+                    while ( pFrm )
+                    {
+                        nHeight = Max( nHeight, pFrm->Frm().Height() );
+                        pFrm = (SwFrm*)aIter.Next();
+                    }
+                }
+                SwFmtFrmSize aNew( ATT_MIN_SIZE, 0, nHeight );
+
+                if( DoesUndo() )
+                {
+                    ClearRedo();
+                    AppendUndo( new SwUndoAttrTbl( *pTblNd ));
+                }
+
+                SvPtrarr aFmtCmp( Max( BYTE(255), BYTE(aRowArr.Count()) ), 255 );
+                for( i = 0; i < aRowArr.Count(); ++i )
+                    ::lcl_ProcessRowSize( aFmtCmp, (SwTableLine*)aRowArr[i], aNew );
+                SwTblFmtCmp::Delete( aFmtCmp );
+
+                SetModified();
+            }
+            bRet = TRUE;
+        }
+    }
+    return bRet;
+}
+
+/******************************************************************************
+ *              void SwDoc::SetRowBackground()
+ ******************************************************************************/
+void SwDoc::SetRowBackground( const SwCursor& rCursor, const SvxBrushItem &rNew )
+{
+    SwTableNode* pTblNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode();
+    if( pTblNd )
+    {
+        SvPtrarr aRowArr( 25, 50 ); //Zum sammeln Lines.
+        ::lcl_CollectLines( aRowArr, rCursor );
+
+        if( aRowArr.Count() )
+        {
+            if( DoesUndo() )
+            {
+                ClearRedo();
+                AppendUndo( new SwUndoAttrTbl( *pTblNd ));
+            }
+
+            SvPtrarr aFmtCmp( Max( BYTE(255), BYTE(aRowArr.Count()) ), 255 );
+
+            for( USHORT i = 0; i < aRowArr.Count(); ++i )
+            {
+                SwTableLine *pLine = (SwTableLine*)aRowArr[i];
+
+                SwFrmFmt *pNewFmt;
+                if( 0 != (pNewFmt = SwTblFmtCmp::FindNewFmt( aFmtCmp,
+                                                pLine->GetFrmFmt(), 0 )))
+                    pLine->ChgFrmFmt( (SwTableLineFmt*)pNewFmt );
+                else
+                {
+                    SwFrmFmt *pOld = pLine->GetFrmFmt();
+                    SwFrmFmt *pNew = pLine->ClaimFrmFmt();
+                    pNew->SetAttr( rNew );
+                    aFmtCmp.Insert( new SwTblFmtCmp( pOld, pNew, 0 ), aFmtCmp.Count());
+                }
+            }
+
+            SwTblFmtCmp::Delete( aFmtCmp );
+            SetModified();
+        }
+    }
+}
+
+/******************************************************************************
+ *               SwTwips SwDoc::GetRowBackground() const
+ ******************************************************************************/
+BOOL SwDoc::GetRowBackground( const SwCursor& rCursor, SvxBrushItem &rToFill ) const
+{
+    BOOL bRet = FALSE;
+    SwTableNode* pTblNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode();
+    if( pTblNd )
+    {
+        SvPtrarr aRowArr( 25, 50 ); //Zum sammeln Lines.
+        ::lcl_CollectLines( aRowArr, rCursor );
+
+        if( aRowArr.Count() )
+        {
+            rToFill = ((SwTableLine*)aRowArr[0])->GetFrmFmt()->GetBackground();
+
+            bRet = TRUE;
+            for ( USHORT i = 1; i < aRowArr.Count(); ++i )
+                if ( rToFill != ((SwTableLine*)aRowArr[i])->GetFrmFmt()->GetBackground() )
+                {
+                    bRet = FALSE;
+                    break;
+                }
+        }
+    }
+    return bRet;
+}
+
+/***********************************************************************
+#*  Class      :  SwDoc
+#*  Methoden   :  SetTabBorders(), GetTabBorders()
+#*  Datum      :  MA 18. May. 93
+#*  Update     :  JP 29.04.98
+#***********************************************************************/
+inline void InsertCell( SvPtrarr& rCellArr, SwCellFrm* pCellFrm )
+{
+    if( USHRT_MAX == rCellArr.GetPos( (void*&)pCellFrm ) )
+        rCellArr.Insert( (void*&)pCellFrm, rCellArr.Count() );
+}
+
+//-----------------------------------------------------------------------------
+void lcl_CollectCells( SvPtrarr &rArr, const SwRect &rUnion,
+                          SwTabFrm *pTab )
+{
+    SwLayoutFrm *pCell = pTab->FirstCell();
+    do
+    {
+        // Wenn in der Zelle ein spaltiger Bereich sitzt, muessen wir
+        // uns erst wieder zur Zelle hochhangeln
+        while ( !pCell->IsCellFrm() )
+            pCell = pCell->GetUpper();
+        ASSERT( pCell, "Frame ist keine Zelle." );
+        if ( rUnion.IsOver( pCell->Frm() ) )
+            ::InsertCell( rArr, (SwCellFrm*)pCell );
+        //Dafuer sorgen, dass die Zelle auch verlassen wird (Bereiche)
+        SwLayoutFrm *pTmp = pCell;
+        do
+        {   pTmp = pTmp->GetNextLayoutLeaf();
+        } while ( pCell->IsAnLower( pTmp ) );
+        pCell = pTmp;
+    } while( pCell && pTab->IsAnLower( pCell ) );
+}
+
+void SwDoc::SetTabBorders( const SwCursor& rCursor, const SfxItemSet& rSet )
+{
+    SwTableNode* pTblNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode();
+    if( !pTblNd )
+        return ;
+
+    SwLayoutFrm *pStart, *pEnd;
+    ::lcl_GetStartEndCell( rCursor, pStart, pEnd );
+
+    SwSelUnions aUnions;
+    ::MakeSelUnions( aUnions, pStart, pEnd );
+
+    if( aUnions.Count() )
+    {
+        SwTable& rTable = pTblNd->GetTable();
+        if( DoesUndo() )
+        {
+            ClearRedo();
+            AppendUndo( new SwUndoAttrTbl( *pTblNd ));
+        }
+
+        SvPtrarr aFmtCmp( 255, 255 );
+        const SvxBoxItem* pSetBox;
+        const SvxBoxInfoItem *pSetBoxInfo;
+
+        const SvxBorderLine* pLeft = 0;
+        const SvxBorderLine* pRight = 0;
+        const SvxBorderLine* pTop = 0;
+        const SvxBorderLine* pBottom = 0;
+        const SvxBorderLine* pHori = 0;
+        const SvxBorderLine* pVert = 0;
+        BOOL bHoriValid = TRUE, bVertValid = TRUE,
+             bTopValid = TRUE, bBottomValid = TRUE,
+             bLeftValid = TRUE, bRightValid = TRUE;
+
+        // JP 21.07.95: die Flags im BoxInfo-Item entscheiden, wann eine
+        //              BorderLine gueltig ist!!
+        if( SFX_ITEM_SET == rSet.GetItemState( SID_ATTR_BORDER_INNER, FALSE,
+            (const SfxPoolItem**)&pSetBoxInfo) )
+        {
+            pHori = pSetBoxInfo->GetHori();
+            pVert = pSetBoxInfo->GetVert();
+
+            bHoriValid = pSetBoxInfo->IsValid(VALID_HORI);
+            bVertValid = pSetBoxInfo->IsValid(VALID_VERT);
+
+            // wollen wir die auswerten ??
+            bTopValid = pSetBoxInfo->IsValid(VALID_TOP);
+            bBottomValid = pSetBoxInfo->IsValid(VALID_BOTTOM);
+            bLeftValid = pSetBoxInfo->IsValid(VALID_LEFT);
+            bRightValid = pSetBoxInfo->IsValid(VALID_RIGHT);
+        }
+
+        if( SFX_ITEM_SET == rSet.GetItemState( RES_BOX, FALSE,
+            (const SfxPoolItem**)&pSetBox) )
+        {
+            pLeft = pSetBox->GetLeft();
+            pRight = pSetBox->GetRight();
+            pTop = pSetBox->GetTop();
+            pBottom = pSetBox->GetBottom();
+        }
+        else
+        {
+            // nicht gesetzt, also keine gueltigen Werte
+            bTopValid = bBottomValid = bLeftValid = bRightValid = FALSE;
+            pSetBox = 0;
+        }
+
+        BOOL bFirst = TRUE;
+        for ( USHORT i = 0; i < aUnions.Count(); ++i )
+        {
+            SwSelUnion *pUnion = aUnions[i];
+            SwTabFrm *pTab = pUnion->GetTable();
+            const SwRect &rUnion = pUnion->GetUnion();
+            const BOOL bLast  = i == aUnions.Count() - 1 ? TRUE : FALSE;
+
+            SvPtrarr aCellArr( 255, 255 );
+            ::lcl_CollectCells( aCellArr, pUnion->GetUnion(), pTab );
+
+            //Alle Zellenkanten, die mit dem UnionRect uebereinstimmen oder
+            //darueber hinausragen sind Aussenkanten. Alle anderen sind
+            //Innenkanten.
+            //neu: Die Aussenkanten koennen abhaengig davon, ob es sich um eine
+            //Start/Mittlere/Folge -Tabelle (bei Selektionen ueber FollowTabs)
+            //handelt doch keine Aussenkanten sein.
+            //Aussenkanten werden links, rechts, oben und unten gesetzt.
+            //Innenkanten werden nur oben und links gesetzt.
+            for ( USHORT j = 0; j < aCellArr.Count(); ++j )
+            {
+                SwCellFrm *pCell = (SwCellFrm*)aCellArr[j];
+
+                //Grundsaetzlich nichts setzen in HeadlineRepeats.
+                if ( pTab->IsFollow() && pTab->GetTable()->IsHeadlineRepeat() &&
+                     ((SwLayoutFrm*)pTab->Lower())->IsAnLower( pCell ) )
+                    continue;
+
+                SvxBoxItem aBox( pCell->GetFmt()->GetBox() );
+
+                INT16 nType = 0;
+
+                //Obere Kante
+                if( bTopValid )
+                {
+                    if ( bFirst && (pCell->Frm().Top() <= rUnion.Top()) )
+                    {
+                        aBox.SetLine( pTop, BOX_LINE_TOP );
+                        nType |= 0x0001;
+                    }
+                    else if ( bHoriValid )
+                    {
+                        aBox.SetLine( 0, BOX_LINE_TOP );
+                        nType |= 0x0002;
+                    }
+                }
+
+                //Linke Kante
+                if ( pCell->Frm().Left() <= rUnion.Left() )
+                {
+                    if( bLeftValid )
+                    {
+                        aBox.SetLine( pLeft, BOX_LINE_LEFT );
+                        nType |= 0x0004;
+                    }
+                }
+                else if( bVertValid )
+                {
+                    aBox.SetLine( pVert, BOX_LINE_LEFT );
+                    nType |= 0x0008;
+                }
+
+                //Rechte Kante
+                if( bRightValid )
+                {
+                    if ( pCell->Frm().Right() >= rUnion.Right() )
+                    {
+                        aBox.SetLine( pRight, BOX_LINE_RIGHT );
+                        nType |= 0x0010;
+                    }
+                    else if ( bVertValid )
+                    {
+                        aBox.SetLine( 0, BOX_LINE_RIGHT );
+                        nType |= 0x0020;
+                    }
+                }
+
+                //Untere Kante
+                if ( bLast && (pCell->Frm().Bottom() >= rUnion.Bottom()) )
+                {
+                    if( bBottomValid )
+                    {
+                        aBox.SetLine( pBottom, BOX_LINE_BOTTOM );
+                        nType |= 0x0040;
+                    }
+                }
+                else if( bHoriValid )
+                {
+                    aBox.SetLine( pHori, BOX_LINE_BOTTOM );
+                    nType |= 0x0080;
+                }
+
+                if( pSetBox )
+                {
+                    static USHORT __READONLY_DATA aBorders[] = {
+                        BOX_LINE_BOTTOM, BOX_LINE_TOP,
+                        BOX_LINE_RIGHT, BOX_LINE_LEFT };
+                    const USHORT* pBrd = aBorders;
+                    for( int i = 0; i < 4; ++i, ++pBrd )
+                        aBox.SetDistance( pSetBox->GetDistance( *pBrd ), *pBrd );
+                }
+
+                SwTableBox *pBox = (SwTableBox*)pCell->GetTabBox();
+                SwFrmFmt *pNewFmt;
+                if ( 0 != (pNewFmt = SwTblFmtCmp::FindNewFmt( aFmtCmp, pBox->GetFrmFmt(), nType )))
+                    pBox->ChgFrmFmt( (SwTableBoxFmt*)pNewFmt );
+                else
+                {
+                    SwFrmFmt *pOld = pBox->GetFrmFmt();
+                    SwFrmFmt *pNew = pBox->ClaimFrmFmt();
+                    pNew->SetAttr( aBox );
+                    aFmtCmp.Insert( new SwTblFmtCmp( pOld, pNew, nType ), aFmtCmp.Count());
+                }
+            }
+
+            bFirst = FALSE;
+        }
+
+        SwHTMLTableLayout *pLayout = rTable.GetHTMLTableLayout();
+        if( pLayout )
+        {
+            SwCntntFrm* pFrm = rCursor.GetCntntNode()->GetFrm();
+            SwTabFrm* pTabFrm = pFrm->ImplFindTabFrm();
+
+            pLayout->BordersChanged(
+                pLayout->GetBrowseWidthByTabFrm( *pTabFrm ), TRUE );
+        }
+        SwTblFmtCmp::Delete( aFmtCmp );
+        ::ClearFEShellTabCols();
+        SetModified();
+    }
+}
+
+void lcl_SetLineStyle( SvxBorderLine *pToSet,
+                          const Color *pColor, const SvxBorderLine *pBorderLine)
+{
+    if ( pBorderLine )
+    {
+        if ( !pColor )
+        {
+            Color aTmp( pToSet->GetColor() );
+            *pToSet = *pBorderLine;
+            pToSet->SetColor( aTmp );
+        }
+        else
+            *pToSet = *pBorderLine;
+    }
+    if ( pColor )
+        pToSet->SetColor( *pColor );
+}
+
+void SwDoc::SetTabLineStyle( const SwCursor& rCursor,
+                             const Color* pColor, BOOL bSetLine,
+                             const SvxBorderLine* pBorderLine )
+{
+    SwTableNode* pTblNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode();
+    if( !pTblNd )
+        return ;
+
+    SwLayoutFrm *pStart, *pEnd;
+    ::lcl_GetStartEndCell( rCursor, pStart, pEnd );
+
+    SwSelUnions aUnions;
+    ::MakeSelUnions( aUnions, pStart, pEnd );
+
+    if( aUnions.Count() )
+    {
+        SwTable& rTable = pTblNd->GetTable();
+        if( DoesUndo() )
+        {
+            ClearRedo();
+            AppendUndo( new SwUndoAttrTbl( *pTblNd ));
+        }
+
+        for( USHORT i = 0; i < aUnions.Count(); ++i )
+        {
+            SwSelUnion *pUnion = aUnions[i];
+            SwTabFrm *pTab = pUnion->GetTable();
+            SvPtrarr aCellArr( 255, 255 );
+            ::lcl_CollectCells( aCellArr, pUnion->GetUnion(), pTab );
+
+            for ( USHORT j = 0; j < aCellArr.Count(); ++j )
+            {
+                SwCellFrm *pCell = ( SwCellFrm* )aCellArr[j];
+
+                //Grundsaetzlich nichts setzen in HeadlineRepeats.
+                if ( pTab->IsFollow() && pTab->GetTable()->IsHeadlineRepeat() &&
+                     ((SwLayoutFrm*)pTab->Lower())->IsAnLower( pCell ) )
+                    continue;
+
+                ((SwTableBox*)pCell->GetTabBox())->ClaimFrmFmt();
+                SwFrmFmt *pFmt = pCell->GetFmt();
+                SvxBoxItem aBox( pFmt->GetBox() );
+
+                if ( !pBorderLine && bSetLine )
+                    aBox = *(SvxBoxItem*)::GetDfltAttr( RES_BOX );
+                else
+                {
+                    if ( aBox.GetTop() )
+                        ::lcl_SetLineStyle( (SvxBorderLine*)aBox.GetTop(),
+                                        pColor, pBorderLine );
+                    if ( aBox.GetBottom() )
+                        ::lcl_SetLineStyle( (SvxBorderLine*)aBox.GetBottom(),
+                                        pColor, pBorderLine );
+                    if ( aBox.GetLeft() )
+                        ::lcl_SetLineStyle( (SvxBorderLine*)aBox.GetLeft(),
+                                        pColor, pBorderLine );
+                    if ( aBox.GetRight() )
+                        ::lcl_SetLineStyle( (SvxBorderLine*)aBox.GetRight(),
+                                        pColor, pBorderLine );
+                }
+                pFmt->SetAttr( aBox );
+            }
+        }
+
+        SwHTMLTableLayout *pLayout = rTable.GetHTMLTableLayout();
+        if( pLayout )
+        {
+            SwCntntFrm* pFrm = rCursor.GetCntntNode()->GetFrm();
+            SwTabFrm* pTabFrm = pFrm->ImplFindTabFrm();
+
+            pLayout->BordersChanged(
+                pLayout->GetBrowseWidthByTabFrm( *pTabFrm ), TRUE );
+        }
+        ::ClearFEShellTabCols();
+        SetModified();
+    }
+}
+
+void SwDoc::GetTabBorders( const SwCursor& rCursor, SfxItemSet& rSet ) const
+{
+    SwTableNode* pTblNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode();
+    if( !pTblNd )
+        return ;
+
+    SwLayoutFrm *pStart, *pEnd;
+    ::lcl_GetStartEndCell( rCursor, pStart, pEnd );
+
+    SwSelUnions aUnions;
+    ::MakeSelUnions( aUnions, pStart, pEnd );
+
+    if( aUnions.Count() )
+    {
+        SvxBoxItem     aSetBox    ((const SvxBoxItem    &) rSet.Get(RES_BOX    ));
+        SvxBoxInfoItem aSetBoxInfo((const SvxBoxInfoItem&) rSet.Get(SID_ATTR_BORDER_INNER));
+
+        BOOL bTopSet      = FALSE,
+             bBottomSet   = FALSE,
+             bLeftSet     = FALSE,
+             bRightSet    = FALSE,
+             bHoriSet     = FALSE,
+             bVertSet     = FALSE,
+             bDistanceSet = FALSE;
+
+        aSetBoxInfo.ResetFlags();
+
+        for ( USHORT i = 0; i < aUnions.Count(); ++i )
+        {
+            SwSelUnion *pUnion = aUnions[i];
+            const SwTabFrm *pTab = pUnion->GetTable();
+            const SwRect &rUnion = pUnion->GetUnion();
+            const BOOL bFirst = i == 0 ? TRUE : FALSE;
+            const BOOL bLast  = i == aUnions.Count() - 1 ? TRUE : FALSE;
+
+            SvPtrarr aCellArr( 255, 255 );
+            ::lcl_CollectCells( aCellArr, rUnion, (SwTabFrm*)pTab );
+
+            for ( USHORT j = 0; j < aCellArr.Count(); ++j )
+            {
+                const SwCellFrm *pCell = (const SwCellFrm*)aCellArr[j];
+                const SwFrmFmt  *pFmt  = pCell->GetFmt();
+                const SvxBoxItem  &rBox  = pFmt->GetBox();
+
+                //Obere Kante
+                if ( bFirst && pCell->Frm().Top() <= rUnion.Top() )
+                {
+                    if (aSetBoxInfo.IsValid(VALID_TOP))
+                    {
+                        if ( !bTopSet )
+                        {   bTopSet = TRUE;
+                            aSetBox.SetLine( rBox.GetTop(), BOX_LINE_TOP );
+                        }
+                        else if ((aSetBox.GetTop() && rBox.GetTop() &&
+                                 !(*aSetBox.GetTop() == *rBox.GetTop())) ||
+                                 ((!aSetBox.GetTop()) ^ (!rBox.GetTop()))) // XOR-Ausdruck ist TRUE, wenn genau einer der beiden Pointer 0 ist
+                        {
+                            aSetBoxInfo.SetValid(VALID_TOP, FALSE );
+                            aSetBox.SetLine( 0, BOX_LINE_TOP );
+                        }
+                    }
+                }
+
+                //Linke Kante
+                if ( pCell->Frm().Left() <= rUnion.Left() )
+                {
+                    if (aSetBoxInfo.IsValid(VALID_LEFT))
+                    {
+                        if ( !bLeftSet )
+                        {   bLeftSet = TRUE;
+                            aSetBox.SetLine( rBox.GetLeft(), BOX_LINE_LEFT );
+                        }
+                        else if ((aSetBox.GetLeft() && rBox.GetLeft() &&
+                                 !(*aSetBox.GetLeft() == *rBox.GetLeft())) ||
+                                 ((!aSetBox.GetLeft()) ^ (!rBox.GetLeft())))
+                        {
+                            aSetBoxInfo.SetValid(VALID_LEFT, FALSE );
+                            aSetBox.SetLine( 0, BOX_LINE_LEFT );
+                        }
+                    }
+                }
+                else
+                {
+                    if (aSetBoxInfo.IsValid(VALID_VERT))
+                    {
+                        if ( !bVertSet )
+                        {   bVertSet = TRUE;
+                            aSetBoxInfo.SetLine( rBox.GetLeft(), BOXINFO_LINE_VERT );
+                        }
+                        else if ((aSetBoxInfo.GetVert() && rBox.GetLeft() &&
+                                 !(*aSetBoxInfo.GetVert() == *rBox.GetLeft())) ||
+                                 ((!aSetBoxInfo.GetVert()) ^ (!rBox.GetLeft())))
+                        {   aSetBoxInfo.SetValid( VALID_VERT, FALSE );
+                            aSetBoxInfo.SetLine( 0, BOXINFO_LINE_VERT );
+                        }
+                    }
+                }
+
+                //Rechte Kante
+                if ( aSetBoxInfo.IsValid(VALID_RIGHT) && pCell->Frm().Right() >= rUnion.Right() )
+                {
+                    if ( !bRightSet )
+                    {   bRightSet = TRUE;
+                        aSetBox.SetLine( rBox.GetRight(), BOX_LINE_RIGHT );
+                    }
+                    else if ((aSetBox.GetRight() && rBox.GetRight() &&
+                             !(*aSetBox.GetRight() == *rBox.GetRight())) ||
+                             (!aSetBox.GetRight() ^ !rBox.GetRight()))
+                    {   aSetBoxInfo.SetValid( VALID_RIGHT, FALSE );
+                        aSetBox.SetLine( 0, BOX_LINE_RIGHT );
+                    }
+                }
+
+                //Untere Kante
+                if ( bLast && pCell->Frm().Bottom() >= rUnion.Bottom() )
+                {
+                    if ( aSetBoxInfo.IsValid(VALID_BOTTOM) )
+                    {
+                        if ( !bBottomSet )
+                        {   bBottomSet = TRUE;
+                            aSetBox.SetLine( rBox.GetBottom(), BOX_LINE_BOTTOM );
+                        }
+                        else if ((aSetBox.GetBottom() && rBox.GetBottom() &&
+                                 !(*aSetBox.GetBottom() == *rBox.GetBottom())) ||
+                                 (!aSetBox.GetBottom() ^ !rBox.GetBottom()))
+                        {   aSetBoxInfo.SetValid( VALID_BOTTOM, FALSE );
+                            aSetBox.SetLine( 0, BOX_LINE_BOTTOM );
+                        }
+                    }
+                }
+                //in allen Zeilen ausser der letzten werden die
+                // horiz. Linien aus der Bottom-Linie entnommen
+                else
+                {
+                    if (aSetBoxInfo.IsValid(VALID_HORI))
+                    {
+                        if ( !bHoriSet )
+                        {   bHoriSet = TRUE;
+                            aSetBoxInfo.SetLine( rBox.GetBottom(), BOXINFO_LINE_HORI );
+                        }
+                        else if ((aSetBoxInfo.GetHori() && rBox.GetBottom() &&
+                                 !(*aSetBoxInfo.GetHori() == *rBox.GetBottom())) ||
+                                 ((!aSetBoxInfo.GetHori()) ^ (!rBox.GetBottom())))
+                        {
+                            aSetBoxInfo.SetValid( VALID_HORI, FALSE );
+                            aSetBoxInfo.SetLine( 0, BOXINFO_LINE_HORI );
+                        }
+                    }
+                }
+
+                // Abstand zum Text
+                if (aSetBoxInfo.IsValid(VALID_DISTANCE))
+                {
+                    static USHORT __READONLY_DATA aBorders[] = {
+                        BOX_LINE_BOTTOM, BOX_LINE_TOP,
+                        BOX_LINE_RIGHT, BOX_LINE_LEFT };
+                    const USHORT* pBrd = aBorders;
+
+                    if( !bDistanceSet )     // bei 1. Durchlauf erstmal setzen
+                    {
+                        bDistanceSet = TRUE;
+                        for( int i = 0; i < 4; ++i, ++pBrd )
+                            aSetBox.SetDistance( rBox.GetDistance( *pBrd ),
+                                                *pBrd );
+                    }
+                    else
+                    {
+                        for( int i = 0; i < 4; ++i, ++pBrd )
+                            if( aSetBox.GetDistance( *pBrd ) !=
+                                rBox.GetDistance( *pBrd ) )
+                            {
+                                aSetBoxInfo.SetValid( VALID_DISTANCE, FALSE );
+                                aSetBox.SetDistance( (USHORT) 0 );
+                                break;
+                            }
+                    }
+                }
+            }
+        }
+        rSet.Put( aSetBox );
+        rSet.Put( aSetBoxInfo );
+    }
+}
+
+/***********************************************************************
+#*  Class      :  SwDoc
+#*  Methoden   :  SetBoxAttr
+#*  Datum      :  MA 18. Dec. 96
+#*  Update     :  JP 29.04.98
+#***********************************************************************/
+void SwDoc::SetBoxAttr( const SwCursor& rCursor, const SfxPoolItem &rNew )
+{
+    SwTableNode* pTblNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode();
+    SwSelBoxes aBoxes;
+    if( pTblNd && ::lcl_GetBoxSel( rCursor, aBoxes, TRUE ) )
+    {
+        SwTable& rTable = pTblNd->GetTable();
+        if( DoesUndo() )
+        {
+            ClearRedo();
+            AppendUndo( new SwUndoAttrTbl( *pTblNd ));
+        }
+
+        SvPtrarr aFmtCmp( Max( BYTE(255), BYTE(aBoxes.Count()) ), 255 );
+        for ( USHORT i = 0; i < aBoxes.Count(); ++i )
+        {
+            SwTableBox *pBox = aBoxes[i];
+
+            SwFrmFmt *pNewFmt;
+            if ( 0 != (pNewFmt = SwTblFmtCmp::FindNewFmt( aFmtCmp, pBox->GetFrmFmt(), 0 )))
+                pBox->ChgFrmFmt( (SwTableBoxFmt*)pNewFmt );
+            else
+            {
+                SwFrmFmt *pOld = pBox->GetFrmFmt();
+                SwFrmFmt *pNew = pBox->ClaimFrmFmt();
+                pNew->SetAttr( rNew );
+                aFmtCmp.Insert( new SwTblFmtCmp( pOld, pNew, 0 ), aFmtCmp.Count());
+            }
+        }
+
+        SwHTMLTableLayout *pLayout = rTable.GetHTMLTableLayout();
+        if( pLayout )
+        {
+            SwCntntFrm* pFrm = rCursor.GetCntntNode()->GetFrm();
+            SwTabFrm* pTabFrm = pFrm->ImplFindTabFrm();
+
+            pLayout->Resize(
+                pLayout->GetBrowseWidthByTabFrm( *pTabFrm ), TRUE );
+        }
+        SwTblFmtCmp::Delete( aFmtCmp );
+        SetModified();
+    }
+}
+
+/***********************************************************************
+#*  Class      :  SwDoc
+#*  Methoden   :  GetBoxBackground()
+#*  Datum      :  MA 01. Jun. 93
+#*  Update     :  JP 29.04.98
+#***********************************************************************/
+
+BOOL SwDoc::GetBoxBackground( const SwCursor& rCursor, SvxBrushItem &rToFill ) const
+{
+    BOOL bRet = FALSE;
+    SwTableNode* pTblNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode();
+    SwSelBoxes aBoxes;
+    if( pTblNd && lcl_GetBoxSel( rCursor, aBoxes ))
+    {
+        bRet = TRUE;
+        BOOL bOneFound = FALSE;
+        for( USHORT i = 0; i < aBoxes.Count(); ++i )
+        {
+            const SvxBrushItem &rBack =
+                            aBoxes[i]->GetFrmFmt()->GetBackground();
+            if( !bOneFound )
+            {
+                rToFill = rBack;
+                bOneFound = TRUE;
+            }
+            else if( rToFill != rBack )
+            {
+                bRet = FALSE;
+                break;
+            }
+        }
+    }
+    return bRet;
+}
+
+/***********************************************************************
+#*  Class      :  SwDoc
+#*  Methoden   :  SetBoxAlign, SetBoxAlign
+#*  Datum      :  MA 18. Dec. 96
+#*  Update     :  JP 29.04.98
+#***********************************************************************/
+void SwDoc::SetBoxAlign( const SwCursor& rCursor, USHORT nAlign )
+{
+    ASSERT( nAlign == VERT_NONE   ||
+            nAlign == VERT_CENTER ||
+            nAlign == VERT_BOTTOM, "wrong alignment" );
+    SwFmtVertOrient aVertOri( 0, SwVertOrient(nAlign) );
+    SetBoxAttr( rCursor, aVertOri );
+}
+
+USHORT SwDoc::GetBoxAlign( const SwCursor& rCursor ) const
+{
+    USHORT nAlign = USHRT_MAX;
+    SwTableNode* pTblNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode();
+    SwSelBoxes aBoxes;
+    if( pTblNd && ::lcl_GetBoxSel( rCursor, aBoxes ))
+        for( USHORT i = 0; i < aBoxes.Count(); ++i )
+        {
+            const SwFmtVertOrient &rOri =
+                            aBoxes[i]->GetFrmFmt()->GetVertOrient();
+            if( USHRT_MAX == nAlign )
+                nAlign = rOri.GetVertOrient();
+            else if( rOri.GetVertOrient() != nAlign )
+            {
+                nAlign = USHRT_MAX;
+                break;
+            }
+        }
+    return nAlign;
+}
+
+
+/***********************************************************************
+#*  Class      :  SwDoc
+#*  Methoden   :  AdjustCellWidth()
+#*  Datum      :  MA 20. Feb. 95
+#*  Update     :  JP 29.04.98
+#***********************************************************************/
+USHORT lcl_CalcCellFit( const SwLayoutFrm *pCell )
+{
+    SwTwips nRet = 0;
+    const SwFrm *pFrm = pCell->Lower(); //Die ganze Zelle.
+    while ( pFrm )
+    {
+        const SwTwips nAdd = pFrm->Frm().Width() - pFrm->Prt().Width();
+        #ifdef HPUX
+        nRet = Max( nRet, ((long)((SwTxtFrm*)pFrm)->CalcFitToContent() + nAdd) );
+        #else
+        nRet = Max( nRet, (((SwTxtFrm*)pFrm)->CalcFitToContent() + nAdd) );
+        #endif
+        pFrm = pFrm->GetNext();
+    }
+    //Umrandung und linker/rechter Rand wollen mit kalkuliert werden.
+    nRet += pCell->Frm().Width() - pCell->Prt().Width();
+
+    //Um Rechenungenauikeiten, die spaeter bei SwTable::SetTabCols enstehen,
+    //auszugleichen, addieren wir noch ein bischen.
+    nRet += COLFUZZY;
+    return (USHORT)Max( long(MINLAY), nRet );
+}
+
+/*Die Zelle ist in der Selektion, wird aber nicht von den TabCols beschrieben.
+ *Das bedeutet, dass die Zelle aufgrund der zweidimensionalen Darstellung von
+ *anderen Zellen "geteilt" wurde. Wir muessen also den Wunsch- bzw. Minimalwert
+ *der Zelle auf die Spalten, durch die sie geteilt wurde verteilen.
+ *
+ *Dazu sammeln wir zuerst die Spalten - nicht die Spaltentrenner! - ein, die
+ *sich mit der Zelle ueberschneiden. Den Wunschwert der Zelle verteilen wir
+ *dann anhand des Betrages der Ueberschneidung auf die Zellen.
+ *Wenn eine Zelle bereits einen groesseren Wunschwert angemeldet hat, so bleibt
+ *dieser erhalten, kleinere Wuensche werden ueberschrieben.
+ */
+
+void lcl_CalcSubColValues( SvUShorts &rToFill, const SwTabCols &rCols,
+                              const SwLayoutFrm *pCell, const SwLayoutFrm *pTab,
+                              BOOL bWishValues )
+{
+    const USHORT nWish = bWishValues ?
+                    ::lcl_CalcCellFit( pCell ) :
+                    MINLAY + USHORT(pCell->Frm().Width() - pCell->Prt().Width());
+
+    for ( USHORT i = 0 ; i <= rCols.Count(); ++i )
+    {
+        long nColLeft  = i == 0             ? rCols.GetLeft()  : rCols[i-1];
+        long nColRight = i == rCols.Count() ? rCols.GetRight() : rCols[i];
+        nColLeft  += rCols.GetLeftMin();
+        nColRight += rCols.GetLeftMin();
+
+        //Werte auf die Verhaeltnisse der Tabelle (Follows) anpassen.
+        if ( rCols.GetLeftMin() !=  USHORT(pTab->Frm().Left()) )
+        {
+            const long nDiff = pTab->Frm().Left() - rCols.GetLeftMin();
+            nColLeft  += nDiff;
+            nColRight += nDiff;
+        }
+        const long nCellLeft  = pCell->Frm().Left();
+        const long nCellRight = pCell->Frm().Right();
+
+        //Ueberschneidungsbetrag ermitteln.
+        long nWidth = 0;
+        if ( nColLeft <= nCellLeft && nColRight >= (nCellLeft+COLFUZZY) )
+            nWidth = nColRight - nCellLeft;
+        else if ( nColLeft <= (nCellRight-COLFUZZY) && nColRight >= nCellRight )
+            nWidth = nCellRight - nColLeft;
+        else if ( nColLeft >= nCellLeft && nColRight <= nCellRight )
+            nWidth = nColRight - nColLeft;
+        if ( nWidth )
+        {
+            long nTmp = nWidth * nWish / pCell->Frm().Width();
+            if ( USHORT(nTmp) > rToFill[i] )
+                rToFill[i] = USHORT(nTmp);
+        }
+    }
+}
+
+/*Besorgt neue Werte zu Einstellung der TabCols.
+ *Es wird nicht ueber die Eintrage in den TabCols itereriert, sondern
+ *quasi ueber die Zwischenraeume, die ja die Zellen beschreiben.
+ *
+ *bWishValues == TRUE:  Es werden zur aktuellen Selektion bzw. zur aktuellen
+ *                      Zelle die Wunschwerte aller betroffen Zellen ermittelt.
+ *                      Sind mehrere Zellen in einer Spalte, so wird der
+ *                      groesste Wunschwert als Ergebnis geliefert.
+ *                      Fuer die TabCol-Eintraege, zu denen keine Zellen
+ *                      ermittelt wurden, werden 0-en eingetragen.
+ *
+ *bWishValues == FALSE: Die Selektion wird senkrecht ausgedehnt. Zu jeder
+ *                      Spalte in den TabCols, die sich mit der Selektion
+ *                      schneidet wird der Minimalwert ermittelt.
+ */
+
+void lcl_CalcColValues( SvUShorts &rToFill, const SwTabCols &rCols,
+                           const SwLayoutFrm *pStart, const SwLayoutFrm *pEnd,
+                           BOOL bWishValues )
+{
+    SwSelUnions aUnions;
+    ::MakeSelUnions( aUnions, pStart, pEnd,
+                    bWishValues ? TBLSEARCH_NONE : TBLSEARCH_COL );
+
+    for ( USHORT i2 = 0; i2 < aUnions.Count(); ++i2 )
+    {
+        SwSelUnion *pSelUnion = aUnions[i2];
+        const SwTabFrm *pTab = pSelUnion->GetTable();
+        const SwRect &rUnion = pSelUnion->GetUnion();
+
+        const SwLayoutFrm *pCell = pTab->FirstCell();
+        do
+        {   if ( ::IsFrmInTblSel( rUnion, pCell ) )
+            {
+                const long nCLeft  = pCell->Frm().Left();
+                const long nCRight = pCell->Frm().Right();
+
+                BOOL bNotInCols = TRUE;
+
+                for ( USHORT i = 0; i <= rCols.Count(); ++i )
+                {
+                    USHORT nFit = rToFill[i];
+                    long nColLeft  = i == 0             ? rCols.GetLeft()  : rCols[i-1];
+                    long nColRight = i == rCols.Count() ? rCols.GetRight() : rCols[i];
+                    nColLeft  += rCols.GetLeftMin();
+                    nColRight += rCols.GetLeftMin();
+
+                    //Werte auf die Verhaeltnisse der Tabelle (Follows) anpassen.
+                    long nLeftA  = nColLeft;
+                    long nRightA = nColRight;
+                    if ( rCols.GetLeftMin() !=  USHORT(pTab->Frm().Left()) )
+                    {
+                        const long nDiff = pTab->Frm().Left() - rCols.GetLeftMin();
+                        nLeftA  += nDiff;
+                        nRightA += nDiff;
+                    }
+
+                    //Wir wollen nicht allzu genau hinsehen.
+                    if ( ::IsSame(nCLeft, nLeftA) && ::IsSame(nCRight, nRightA))
+                    {
+                        bNotInCols = FALSE;
+                        if ( bWishValues )
+                        {
+                            const USHORT nWish = ::lcl_CalcCellFit( pCell );
+                            if ( nWish > nFit )
+                                nFit = nWish;
+                        }
+                        else
+                        {   const USHORT nMin = MINLAY + USHORT(pCell->Frm().Width() -
+                                                                pCell->Prt().Width());
+                            if ( !nFit || nMin < nFit )
+                                nFit = nMin;
+                        }
+                        if ( rToFill[i] < nFit )
+                            rToFill[i] = nFit;
+                    }
+                }
+                if ( bNotInCols )
+                    ::lcl_CalcSubColValues( rToFill, rCols, pCell, pTab, bWishValues );
+            }
+            pCell = pCell->GetNextLayoutLeaf();
+
+        } while ( pCell && ((SwCellFrm*)pCell)->ImplFindTabFrm() == pTab );
+    }
+}
+
+
+void SwDoc::AdjustCellWidth( const SwCursor& rCursor, BOOL bBalance )
+{
+    // pruefe ob vom aktuellen Crsr der Point/Mark in einer Tabelle stehen
+    SwTableNode* pTblNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode();
+    if( !pTblNd )
+        return ;
+
+    SwLayoutFrm *pStart, *pEnd;
+    ::lcl_GetStartEndCell( rCursor, pStart, pEnd );
+
+    //TabCols besorgen, den ueber diese stellen wir die Tabelle neu ein.
+    SwFrm* pBoxFrm = pStart;
+    while( !pBoxFrm->IsCellFrm() )
+        pBoxFrm = pBoxFrm->GetUpper();
+
+    SwTabCols aTabCols;
+    GetTabCols( aTabCols, 0, (SwCellFrm*)pBoxFrm );
+
+    const BYTE nTmp = (BYTE)Max( USHORT(255), USHORT(aTabCols.Count() + 1) );
+    SvUShorts aWish( nTmp, nTmp ),
+              aMins( nTmp, nTmp );
+    for ( USHORT i = 0; i <= aTabCols.Count(); ++i )
+    {
+        aWish.Insert( USHORT(0), aWish.Count() );
+        aMins.Insert( USHORT(0), aMins.Count() );
+    }
+    ::lcl_CalcColValues( aWish, aTabCols, pStart, pEnd, TRUE  );
+
+    //Es ist Robuster wenn wir die Min-Werte fuer die ganze Tabelle berechnen.
+    const SwTabFrm *pTab = pStart->ImplFindTabFrm();
+    pStart = (SwLayoutFrm*)pTab->FirstCell();
+    pEnd   = (SwLayoutFrm*)pTab->FindLastCntnt()->GetUpper();
+    while( !pEnd->IsCellFrm() )
+        pEnd = pEnd->GetUpper();
+    ::lcl_CalcColValues( aMins, aTabCols, pStart, pEnd, FALSE );
+
+    if( bBalance )
+    {
+        //Alle Spalten, die makiert sind haben jetzt einen Wunschwert
+        //eingtragen. Wir addieren die aktuellen Werte, teilen das Ergebnis
+        //durch die Anzahl und haben eine Wunschwert fuer den ausgleich.
+        USHORT nWish = 0, nCnt = 0;
+        for ( i = 0; i <= aTabCols.Count(); ++i )
+        {
+            int nDiff = aWish[i];
+            if ( nDiff )
+            {
+                if ( i == 0 )
+                    nWish += aTabCols[i] - aTabCols.GetLeft();
+                else if ( i == aTabCols.Count() )
+                    nWish += aTabCols.GetRight() - aTabCols[i-1];
+                else
+                    nWish += aTabCols[i] - aTabCols[i-1];
+                ++nCnt;
+            }
+        }
+        nWish /= nCnt;
+        for ( i = 0; i < aWish.Count(); ++i )
+            if ( aWish[i] )
+                aWish[i] = nWish;
+    }
+
+    const USHORT nOldRight = aTabCols.GetRight();
+
+    //Um die Impl. einfach zu gestalten, aber trotzdem in den meissten Faellen
+    //den Platz richtig auszunutzen laufen wir zweimal.
+    //Problem: Erste Spalte wird breiter, die anderen aber erst danach
+    //schmaler. Die Wunschbreite der ersten Spalte wuerde abgelehnt, weil
+    //mit ihr die max. Breite der Tabelle ueberschritten wuerde.
+    for ( USHORT k= 0; k < 2; ++k )
+    {
+        for ( i = 0; i <= aTabCols.Count(); ++i )
+        {
+            int nDiff = aWish[i];
+            if ( nDiff )
+            {
+                int nMin = aMins[i];
+                if ( nMin > nDiff )
+                    nDiff = nMin;
+
+                if ( i == 0 )
+                {
+                    if( aTabCols.Count() )
+                        nDiff -= aTabCols[0] - aTabCols.GetLeft();
+                    else
+                        nDiff -= aTabCols.GetRight() - aTabCols.GetLeft();
+                }
+                else if ( i == aTabCols.Count() )
+                    nDiff -= aTabCols.GetRight() - aTabCols[i-1];
+                else
+                    nDiff -= aTabCols[i] - aTabCols[i-1];
+
+                USHORT nTabRight = aTabCols.GetRight() + nDiff;
+
+                //Wenn die Tabelle zu breit wuerde begrenzen wir die Anpassung
+                //auf das erlaubte Maximum.
+                if ( !bBalance && nTabRight > aTabCols.GetRightMax() )
+                {
+                    const USHORT nTmp = nTabRight - aTabCols.GetRightMax();
+                    nDiff     -= nTmp;
+                    nTabRight -= nTmp;
+                }
+                for ( USHORT i2 = i; i2 < aTabCols.Count(); ++i2 )
+                    aTabCols[i2] += nDiff;
+                aTabCols.SetRight( nTabRight );
+            }
+        }
+    }
+
+    const USHORT nNewRight = aTabCols.GetRight();
+
+    //So, die richtige Arbeit koennen wir jetzt der SwTable ueberlassen.
+    SetTabCols( aTabCols, FALSE, 0, (SwCellFrm*)pBoxFrm );
+
+    //Ggf. Ausrichtung der Tabelle Aendern.
+    //Bei Automatischer Breite wird auf Linksbuendig umgeschaltet.
+    //Bei Randattributen wird der Rechte Rand angepasst.
+    if( !bBalance && nNewRight < nOldRight )
+    {
+        SwFrmFmt *pFmt = pTblNd->GetTable().GetFrmFmt();
+        const SwFmtHoriOrient &rHori = pFmt->GetHoriOrient();
+        if( rHori.GetHoriOrient() == HORI_FULL )
+        {
+            SwFmtHoriOrient aHori( rHori );
+            aHori.SetHoriOrient( HORI_LEFT );
+            pFmt->SetAttr( aHori );
+        }
+    }
+
+    SetModified();
+}
+
diff --git a/sw/source/core/docnode/node.cxx b/sw/source/core/docnode/node.cxx
new file mode 100644
index 000000000000..bce1eae6f54a
--- /dev/null
+++ b/sw/source/core/docnode/node.cxx
@@ -0,0 +1,1840 @@
+/*************************************************************************
+ *
+ *  $RCSfile: node.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:17 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _SVX_PROTITEM_HXX //autogen
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_CHARACTERITERATORMODE_HDL_
+#include 
+#endif
+
+#ifndef _FMTCNTNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTANCHR_HXX
+#include 
+#endif
+#ifndef _FRMFMT_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFTN_HXX //autogen
+#include 
+#endif
+#ifndef _FTNFRM_HXX //autogen
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _NODE_HXX
+#include 
+#endif
+#ifndef _NDINDEX_HXX
+#include 
+#endif
+#ifndef _NUMRULE_HXX
+#include 
+#endif
+#ifndef _FMTCOL_HXX
+#include 
+#endif
+#ifndef _SWTABLE_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _HINTS_HXX
+#include 
+#endif
+#ifndef _ERRHDL_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _SWCACHE_HXX
+#include 
+#endif
+#ifndef _SECTION_HXX
+#include 
+#endif
+#ifndef _CNTFRM_HXX
+#include 
+#endif
+#ifndef _LAYFRM_HXX
+#include 
+#endif
+#ifndef _FLYFRM_HXX
+#include 
+#endif
+#ifndef _TXTFRM_HXX
+#include 
+#endif
+#ifndef _TABFRM_HXX
+#include   // SwTabFrm
+#endif
+#ifndef _VIEWSH_HXX
+#include 
+#endif
+#ifndef _PARATR_HXX
+#include 
+#endif
+#ifndef _FTNIDX_HXX
+#include 
+#endif
+#ifndef _FMTFTN_HXX
+#include 
+#endif
+#ifndef _FMTHDFT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTCNTNT_HXX //autogen
+#include 
+#endif
+#ifndef _FRMATR_HXX
+#include 
+#endif
+#ifndef _FRMTOOL_HXX
+#include 
+#endif
+#ifndef _PAGEFRM_HXX //autogen
+#include 
+#endif
+#ifndef _NODE2LAY_HXX
+#include 
+#endif
+#ifndef _HINTS_HXX
+#include 
+#endif
+#ifndef _PAGEDESC_HXX //autogen
+#include 
+#endif
+#ifndef _FMTPDSC_HXX //autogen
+#include 
+#endif
+#ifndef _BREAKIT_HXX
+#include 
+#endif
+
+using namespace ::com::sun::star::text;
+
+TYPEINIT2( SwCntntNode, SwModify, SwIndexReg )
+
+/*******************************************************************
+|*
+|*  SwNode::GetSectionLevel
+|*
+|*  Beschreibung
+|*      Die Funktion liefert den Sectionlevel an der durch
+|*      aIndex bezeichneten Position.
+|*
+|*      Die Logik ist wie folgt:   ( S -> Start, E -> End, C -> CntntNode)
+|*          Level   0       E
+|*                  1   S  E
+|*                  2    SC
+|*
+|*      alle EndNodes der GrundSection haben den Level 0
+|*      alle StartNodes der GrundSection haben den Level 1
+|*
+|*  Ersterstellung
+|*      VER0100 vb 901214
+|*
+|*  Aenderung:  JP  11.08.93
+|*      keine Rekursion mehr !!
+|*
+*******************************************************************/
+
+
+USHORT SwNode::GetSectionLevel() const
+{
+    // EndNode einer Grund-Section ?? diese sind immer 0 !!
+    if( IsEndNode() && 0 == pStartOfSection->StartOfSectionIndex() )
+        return 0;
+
+    USHORT nLevel;
+    const SwNode* pNode = IsStartNode() ? this : pStartOfSection;
+    for( nLevel = 1; 0 != pNode->StartOfSectionIndex(); ++nLevel )
+        pNode = pNode->pStartOfSection;
+    return IsEndNode() ? nLevel-1 : nLevel;
+}
+
+/*******************************************************************
+|*
+|*  SwNode::SwNode
+|*
+|*  Beschreibung
+|*      Konstruktor; dieser fuegt einen Node in das Array rNodes
+|*      an der Position rWhere ein. Dieser bekommt als
+|*      theEndOfSection den EndOfSection-Index des Nodes
+|*      unmittelbar vor ihm. Falls er sich an der Position 0
+|*      innerhalb des variablen Arrays befindet, wird
+|*      theEndOfSection 0 (der neue selbst).
+|*
+|*  Parameter
+|*      IN
+|*      rNodes bezeichnet das variable Array, in das der Node
+|*      eingefuegt werden soll
+|*      IN
+|*      rWhere bezeichnet die Position innerhalb dieses Arrays,
+|*      an der der Node eingefuegt werden soll
+|*
+|*  Ersterstellung
+|*      VER0100 vb 901214
+|*
+|*  Stand
+|*      VER0100 vb 901214
+|*
+*******************************************************************/
+
+
+SwNode::SwNode( const SwNodeIndex &rWhere, const BYTE nNdType )
+    : pStartOfSection( 0 ), nNodeType( nNdType )
+{
+    bWrongDirty = bACmplWrdDirty = TRUE;
+    nAFmtNumLvl = nSetNumLSpace = 0;
+
+    SwNodes& rNodes = (SwNodes&)rWhere.GetNodes();
+    SwNode* pInsNd = this;      // der MAC kann this nicht einfuegen !!
+    if( rWhere.GetIndex() )
+    {
+        SwNode* pNd = rNodes[ rWhere.GetIndex() -1 ];
+        rNodes.Insert( pInsNd, rWhere );
+        if( 0 == ( pStartOfSection = pNd->GetStartNode()) )
+        {
+            pStartOfSection = pNd->pStartOfSection;
+            if( pNd->GetEndNode() )     // EndNode ? Section ueberspringen!
+            {
+                pNd = pStartOfSection;
+                pStartOfSection = pNd->pStartOfSection;
+            }
+        }
+    }
+    else
+    {
+        rNodes.Insert( pInsNd, rWhere );
+        pStartOfSection = (SwStartNode*)this;
+    }
+}
+
+SwNode::SwNode( SwNodes& rNodes, ULONG nPos, const BYTE nNdType )
+    : pStartOfSection( 0 ), nNodeType( nNdType )
+{
+    bWrongDirty = bACmplWrdDirty = TRUE;
+    nAFmtNumLvl = nSetNumLSpace = 0;
+
+    SwNode* pInsNd = this;      // der MAC kann this nicht einfuegen !!
+    if( nPos )
+    {
+        SwNode* pNd = rNodes[ nPos - 1 ];
+        rNodes.Insert( pInsNd, nPos );
+        if( 0 == ( pStartOfSection = pNd->GetStartNode()) )
+        {
+            pStartOfSection = pNd->pStartOfSection;
+            if( pNd->GetEndNode() )     // EndNode ? Section ueberspringen!
+            {
+                pNd = pStartOfSection;
+                pStartOfSection = pNd->pStartOfSection;
+            }
+        }
+    }
+    else
+    {
+        rNodes.Insert( pInsNd, nPos );
+        pStartOfSection = (SwStartNode*)this;
+    }
+}
+
+SwNode::~SwNode() {}
+
+// suche den TabellenNode, in dem dieser steht. Wenn in keiner
+// Tabelle wird 0 returnt.
+
+
+SwTableNode* SwNode::FindTableNode()
+{
+    if( IsTableNode() )
+        return GetTableNode();
+    SwStartNode* pTmp = pStartOfSection;
+    while( !pTmp->IsTableNode() && pTmp->GetIndex() )
+#if defined( ALPHA ) && defined( UNX )
+        pTmp = ((SwNode*)pTmp)->pStartOfSection;
+#else
+        pTmp = pTmp->pStartOfSection;
+#endif
+    return pTmp->GetTableNode();
+}
+
+
+// liegt der Node im Sichtbarenbereich der Shell ?
+BOOL SwNode::IsVisible( ViewShell* pSh ) const
+{
+    BOOL bRet = FALSE;
+    const SwCntntNode* pNd;
+
+    if( ND_STARTNODE & nNodeType )
+    {
+        SwNodeIndex aIdx( *this );
+        pNd = GetNodes().GoNext( &aIdx );
+    }
+    else if( ND_ENDNODE & nNodeType )
+    {
+        SwNodeIndex aIdx( *EndOfSectionNode() );
+        pNd = GetNodes().GoPrevious( &aIdx );
+    }
+    else
+        pNd = GetCntntNode();
+
+    const SwFrm* pFrm;
+    if( pNd && 0 != ( pFrm = pNd->GetFrm( 0, 0, FALSE ) ) )
+    {
+        if( !pSh )
+            // dann die Shell vom Doc besorgen:
+            GetDoc()->GetEditShell( &pSh );
+
+        if( pSh )
+        {
+            if ( pFrm->IsInTab() )
+                pFrm = pFrm->FindTabFrm();
+
+            if( !pFrm->IsValid() )
+                do
+                {   pFrm = pFrm->FindPrev();
+                } while ( pFrm && !pFrm->IsValid() );
+
+            if( !pFrm || pSh->VisArea().IsOver( pFrm->Frm() ) )
+                bRet = TRUE;
+        }
+    }
+
+    return bRet;
+}
+
+BOOL SwNode::IsInProtectSect() const
+{
+    const SwNode* pNd = ND_SECTIONNODE == nNodeType ? pStartOfSection : this;
+    const SwSectionNode* pSectNd = pNd->FindSectionNode();
+    return pSectNd && pSectNd->GetSection().IsProtectFlag();
+}
+
+    // befindet sich der Node in irgendetwas geschuetzten ?
+    // (Bereich/Rahmen/Tabellenzellen/... incl. des Ankers bei
+    //  Rahmen/Fussnoten/..)
+BOOL SwNode::IsProtect() const
+{
+    const SwNode* pNd = ND_SECTIONNODE == nNodeType ? pStartOfSection : this;
+    const SwStartNode* pSttNd = pNd->FindSectionNode();
+    if( pSttNd && ((SwSectionNode*)pSttNd)->GetSection().IsProtectFlag() )
+        return TRUE;
+
+    if( 0 != ( pSttNd = FindTableBoxStartNode() ) )
+    {
+        SwCntntFrm* pCFrm;
+        if( IsCntntNode() && 0 != (pCFrm = ((SwCntntNode*)this)->GetFrm() ))
+            return pCFrm->IsProtected();
+
+        const SwTableBox* pBox = pSttNd->FindTableNode()->GetTable().
+                                        GetTblBox( pSttNd->GetIndex() );
+        if( pBox->GetFrmFmt()->GetProtect().IsCntntProtected() )
+            return TRUE;
+    }
+
+    SwFrmFmt* pFlyFmt = GetFlyFmt();
+    if( pFlyFmt )
+    {
+        if( pFlyFmt->GetProtect().IsCntntProtected() )
+            return TRUE;
+        const SwFmtAnchor& rAnchor = pFlyFmt->GetAnchor();
+        return rAnchor.GetCntntAnchor()
+                ? rAnchor.GetCntntAnchor()->nNode.GetNode().IsProtect()
+                : FALSE;
+    }
+
+    if( 0 != ( pSttNd = FindFootnoteStartNode() ) )
+    {
+        const SwTxtFtn* pTFtn = GetDoc()->GetFtnIdxs().SeekEntry(
+                                SwNodeIndex( *pSttNd ) );
+        if( pTFtn )
+            return pTFtn->GetTxtNode().IsProtect();
+    }
+
+    return FALSE;
+}
+
+    // suche den PageDesc, mit dem dieser Node formatiert ist. Wenn das
+    // Layout vorhanden ist wird ueber das gesucht, ansonsten gibt es nur
+    // die harte Tour ueber die Nodes nach vorne suchen!!
+const SwPageDesc* SwNode::FindPageDesc( BOOL bCalcLay ) const
+{
+    const SwPageDesc* pPgDesc = 0;
+
+    if( GetNodes().IsDocNodes() )
+    {
+        const SwCntntNode* pNd;
+        if( ND_STARTNODE & nNodeType )
+        {
+            SwNodeIndex aIdx( *this );
+            pNd = GetNodes().GoNext( &aIdx );
+        }
+        else if( ND_ENDNODE & nNodeType )
+        {
+            SwNodeIndex aIdx( *EndOfSectionNode() );
+            pNd = GetNodes().GoPrevious( &aIdx );
+        }
+        else
+        {
+            pNd = GetCntntNode();
+            if( pNd )
+                pPgDesc = ((SwFmtPageDesc&)pNd->GetAttr( RES_PAGEDESC )).GetPageDesc();
+        }
+
+        // geht es uebers Layout?
+        if( !pPgDesc )
+        {
+            const SwFrm* pFrm;
+            const SwPageFrm* pPage;
+            if( pNd && 0 != ( pFrm = pNd->GetFrm( 0, 0, bCalcLay ) ) &&
+                0 != ( pPage = pFrm->FindPageFrm() ) )
+            {
+                pPgDesc = pPage->GetPageDesc();
+            }
+        }
+
+        if( !pPgDesc )
+        {
+            // dann also uebers Nodes-Array
+            const SwDoc* pDoc = GetDoc();
+            const SwNode* pNd = this;
+            const SwStartNode* pSttNd;
+            if( pNd->GetIndex() < GetNodes().GetEndOfExtras().GetIndex() &&
+                0 != ( pSttNd = pNd->FindFlyStartNode() ) )
+            {
+                // dann erstmal den richtigen Anker finden
+                const SwFrmFmt* pFmt = 0;
+                const SwSpzFrmFmts& rFmts = *pDoc->GetSpzFrmFmts();
+                for( USHORT n = 0; n < rFmts.Count(); ++n )
+                {
+                    SwFrmFmt* pFrmFmt = rFmts[ n ];
+                    const SwFmtCntnt& rCntnt = pFrmFmt->GetCntnt();
+                    if( rCntnt.GetCntntIdx() &&
+                        &rCntnt.GetCntntIdx()->GetNode() == (SwNode*)pSttNd )
+                    {
+                        pFmt = pFrmFmt;
+                        break;
+                    }
+                }
+
+                if( pFmt )
+                {
+                    const SwFmtAnchor* pAnchor = &pFmt->GetAnchor();
+                    if( FLY_PAGE != pAnchor->GetAnchorId() &&
+                        pAnchor->GetCntntAnchor() )
+                    {
+                        pNd = &pAnchor->GetCntntAnchor()->nNode.GetNode();
+                        const SwNode* pFlyNd = pNd->FindFlyStartNode();
+                        while( pFlyNd )
+                        {
+                            // dann ueber den Anker nach oben "hangeln"
+                            for( n = 0; n < rFmts.Count(); ++n )
+                            {
+                                const SwFrmFmt* pFrmFmt = rFmts[ n ];
+                                const SwNodeIndex* pIdx = pFrmFmt->GetCntnt().
+                                                            GetCntntIdx();
+                                if( pIdx && pFlyNd == &pIdx->GetNode() )
+                                {
+                                    if( pFmt == pFrmFmt )
+                                    {
+                                        pNd = pFlyNd;
+                                        pFlyNd = 0;
+                                        break;
+                                    }
+                                    pAnchor = &pFrmFmt->GetAnchor();
+                                    if( FLY_PAGE == pAnchor->GetAnchorId() ||
+                                        !pAnchor->GetCntntAnchor() )
+                                    {
+                                        pFlyNd = 0;
+                                        break;
+                                    }
+
+                                    pFlyNd = pAnchor->GetCntntAnchor()->nNode.
+                                            GetNode().FindFlyStartNode();
+                                    break;
+                                }
+                            }
+                            if( n >= rFmts.Count() )
+                            {
+                                ASSERT( !this, "Fly-Section aber kein Format gefunden" );
+                                return FALSE;
+                            }
+                        }
+                    }
+                }
+                // in pNd sollte jetzt der richtige Anker Node stehen oder
+                // immer noch der this
+            }
+
+            if( pNd->GetIndex() < GetNodes().GetEndOfExtras().GetIndex() )
+            {
+                if( pNd->GetIndex() > GetNodes().GetEndOfAutotext().GetIndex() )
+                {
+                    pPgDesc = &pDoc->GetPageDesc( 0 );
+                    pNd = 0;
+                }
+                else
+                {
+                    // suche den Body Textnode
+                    if( 0 != ( pSttNd = pNd->FindHeaderStartNode() ) ||
+                        0 != ( pSttNd = pNd->FindFooterStartNode() ))
+                    {
+                        // dann in den PageDescs diesen StartNode suchen
+                        USHORT nId;
+                        UseOnPage eAskUse;
+                        if( SwHeaderStartNode == pSttNd->GetStartNodeType())
+                        {
+                            nId = RES_HEADER;
+                            eAskUse = PD_HEADERSHARE;
+                        }
+                        else
+                        {
+                            nId = RES_FOOTER;
+                            eAskUse = PD_FOOTERSHARE;
+                        }
+
+                        for( USHORT n = pDoc->GetPageDescCnt(); n && !pPgDesc; )
+                        {
+                            const SwPageDesc& rPgDsc = pDoc->GetPageDesc( --n );
+                            const SwFrmFmt* pFmt = &rPgDsc.GetMaster();
+                            int nStt = 0, nLast = 1;
+                            if( !( eAskUse & rPgDsc.ReadUseOn() )) ++nLast;
+
+                            for( ; nStt < nLast; ++nStt, pFmt = &rPgDsc.GetLeft() )
+                            {
+                                const SwFmtHeader& rHdFt = (SwFmtHeader&)
+                                                        pFmt->GetAttr( nId );
+                                if( rHdFt.GetHeaderFmt() )
+                                {
+                                    const SwFmtCntnt& rCntnt =
+                                        rHdFt.GetHeaderFmt()->GetCntnt();
+                                    if( rCntnt.GetCntntIdx() &&
+                                        &rCntnt.GetCntntIdx()->GetNode() ==
+                                        (SwNode*)pSttNd )
+                                    {
+                                        pPgDesc = &rPgDsc;
+                                        break;
+                                    }
+                                }
+                            }
+                        }
+
+                        if( !pPgDesc )
+                            pPgDesc = &pDoc->GetPageDesc( 0 );
+                        pNd = 0;
+                    }
+                    else if( 0 != ( pSttNd = pNd->FindFootnoteStartNode() ))
+                    {
+                        // der Anker kann nur im Bodytext sein
+                        const SwTxtFtn* pTxtFtn;
+                        const SwFtnIdxs& rFtnArr = pDoc->GetFtnIdxs();
+                        for( USHORT n = 0; n < rFtnArr.Count(); ++n )
+                            if( 0 != ( pTxtFtn = rFtnArr[ n ])->GetStartNode() &&
+                                (SwNode*)pSttNd ==
+                                &pTxtFtn->GetStartNode()->GetNode() )
+                            {
+                                pNd = &pTxtFtn->GetTxtNode();
+                                break;
+                            }
+                    }
+                    else
+                    {
+                        // kann jetzt nur noch ein Seitengebundener Fly sein
+                        // oder irgendetwas neueres.
+                        // Hier koennen wir nur noch den Standard returnen
+                        ASSERT( pNd->FindFlyStartNode(),
+                                "wo befindet sich dieser Node?" );
+
+                        pPgDesc = &pDoc->GetPageDesc( 0 );
+                        pNd = 0;
+                    }
+                }
+            }
+
+            if( pNd )
+            {
+                SwFindNearestNode aInfo( *pNd );
+                // dann ueber alle Nodes aller PageDesc
+                const SfxPoolItem* pItem;
+                USHORT i, nMaxItems = pDoc->GetAttrPool().GetItemCount( RES_PAGEDESC );
+                for( i = 0; i < nMaxItems; ++i )
+                    if( 0 != (pItem = pDoc->GetAttrPool().GetItem( RES_PAGEDESC, i ) ) &&
+                        ((SwFmtPageDesc*)pItem)->GetDefinedIn() )
+                    {
+                        const SwModify* pMod = ((SwFmtPageDesc*)pItem)->GetDefinedIn();
+                        if( pMod->ISA( SwCntntNode ) )
+                            aInfo.CheckNode( *(SwCntntNode*)pMod );
+                        else if( pMod->ISA( SwFmt ))
+                            ((SwFmt*)pMod)->GetInfo( aInfo );
+                    }
+
+                if( 0 != ( pNd = aInfo.GetFoundNode() ))
+                {
+                    if( pNd->IsCntntNode() )
+                        pPgDesc = ((SwFmtPageDesc&)pNd->GetCntntNode()->
+                                    GetAttr( RES_PAGEDESC )).GetPageDesc();
+                    else if( pNd->IsTableNode() )
+                        pPgDesc = pNd->GetTableNode()->GetTable().
+                                GetFrmFmt()->GetPageDesc().GetPageDesc();
+                    else if( pNd->IsSectionNode() )
+                        pPgDesc = pNd->GetSectionNode()->GetSection().
+                                GetFmt()->GetPageDesc().GetPageDesc();
+                }
+                if( !pPgDesc )
+                    pPgDesc = &pDoc->GetPageDesc( 0 );
+            }
+        }
+    }
+    return pPgDesc;
+}
+
+
+    // falls der Node in einem Fly steht, dann wird das entsprechende Format
+    // returnt
+SwFrmFmt* SwNode::GetFlyFmt() const
+{
+    SwFrmFmt* pRet = 0;
+    const SwNode* pSttNd = FindFlyStartNode();
+    if( pSttNd )
+    {
+        if( IsCntntNode() )
+        {
+            SwClientIter aIter( *(SwCntntNode*)this );
+            SwClient* pCli = aIter.First( TYPE( SwCntntFrm ));
+            if( pCli )
+                pRet = ((SwCntntFrm*)pCli)->FindFlyFrm()->GetFmt();
+        }
+        if( !pRet )
+        {
+            // dann gibts noch harten steinigen Weg uebers Dokument:
+            const SwSpzFrmFmts& rFrmFmtTbl = *GetDoc()->GetSpzFrmFmts();
+            for( USHORT n = 0; n < rFrmFmtTbl.Count(); ++n )
+            {
+                SwFrmFmt* pFmt = rFrmFmtTbl[n];
+                const SwFmtCntnt& rCntnt = pFmt->GetCntnt();
+                if( rCntnt.GetCntntIdx() &&
+                    &rCntnt.GetCntntIdx()->GetNode() == pSttNd )
+                {
+                    pRet = pFmt;
+                    break;
+                }
+            }
+        }
+    }
+    return pRet;
+}
+
+const SwFrmFmt* SwNode::GetFrmFmt() const
+{
+    const SwFrmFmt* pRet = 0;
+    const SwNode* pNd = FindStartNode();
+    ASSERT( pNd, "SwNode::GetFrmFmt(): Missing StartNode" );
+    if( pNd->IsSectionNode() )
+        pRet = ((SwSectionNode*)pNd)->GetSection().GetFmt();
+    else if( pNd->IsTableNode() )
+        pRet = ((SwTableNode*)pNd)->GetTable().GetFrmFmt();
+    else switch( ((SwStartNode*)pNd)->GetStartNodeType() )
+    {
+        case SwNormalStartNode: break;
+        case SwTableBoxStartNode: pRet = pNd->FindTableNode()->GetTable().GetTblBox(
+                                         pNd->GetIndex() )->GetFrmFmt(); break;
+        case SwFlyStartNode: pRet = GetFlyFmt(); break;
+        case SwFootnoteStartNode: pRet = GetDoc()->GetDfltFrmFmt(); break;
+        case SwHeaderStartNode: break;
+        case SwFooterStartNode: break;
+        default: ASSERT( FALSE, "GetFrmFmt(): New StartNodeType?" );
+    }
+    return pRet;
+}
+
+SwTableBox* SwNode::GetTblBox() const
+{
+    SwTableBox* pBox = 0;
+    const SwNode* pSttNd = FindTableBoxStartNode();
+    if( pSttNd )
+        pBox = (SwTableBox*)pSttNd->FindTableNode()->GetTable().GetTblBox(
+                                                    pSttNd->GetIndex() );
+    return pBox;
+}
+
+SwStartNode* SwNode::FindSttNodeByType( SwStartNodeType eTyp )
+{
+    SwStartNode* pTmp = IsStartNode() ? (SwStartNode*)this : pStartOfSection;
+
+    while( eTyp != pTmp->GetStartNodeType() && pTmp->GetIndex() )
+#if defined( ALPHA ) && defined( UNX )
+        pTmp = ((SwNode*)pTmp)->pStartOfSection;
+#else
+        pTmp = pTmp->pStartOfSection;
+#endif
+    return eTyp == pTmp->GetStartNodeType() ? pTmp : 0;
+}
+
+const SwTxtNode* SwNode::FindOutlineNodeOfLevel( BYTE nLvl ) const
+{
+    const SwTxtNode* pRet = 0;
+    const SwOutlineNodes& rONds = GetNodes().GetOutLineNds();
+    if( MAXLEVEL > nLvl && rONds.Count() )
+    {
+        USHORT nPos;
+        SwNode* pNd = (SwNode*)this;
+        BOOL bCheckFirst = FALSE;
+        if( !rONds.Seek_Entry( pNd, &nPos ))
+        {
+            if( nPos )
+                nPos = nPos-1;
+            else
+                bCheckFirst = TRUE;
+        }
+
+        if( bCheckFirst )
+        {
+            // der 1.GliederungsNode liegt hinter dem Fragenden. Dann
+            // teste mal, ob dieser auf der gleichen Seite steht. Wenn
+            // nicht, ist das ein ungueltiger. Bug 61865
+            pRet = rONds[0]->GetTxtNode();
+
+            const SwCntntNode* pCNd = GetCntntNode();
+
+            Point aPt( 0, 0 );
+            const SwFrm* pFrm = pRet->GetFrm( &aPt, 0, FALSE ),
+                       * pMyFrm = pCNd ? pCNd->GetFrm( &aPt, 0, FALSE ) : 0;
+            const SwPageFrm* pPgFrm = pFrm ? pFrm->FindPageFrm() : 0;
+            if( pPgFrm && pMyFrm &&
+                pPgFrm->Frm().Top() > pMyFrm->Frm().Top() )
+            {
+                // der Fragende liegt vor der Seite, also ist er ungueltig
+                pRet = 0;
+            }
+        }
+        else
+        {
+            // oder ans Feld und von dort holen !!
+            while( nPos && nLvl < ( pRet = rONds[nPos]->GetTxtNode() )
+                    ->GetTxtColl()->GetOutlineLevel() )
+                --nPos;
+
+            if( !nPos )     // bei 0 gesondert holen !!
+                pRet = rONds[0]->GetTxtNode();
+        }
+    }
+    return pRet;
+}
+
+// is the node the first and/or last node of a section?
+// This information is used for the export filters. Our layout never have a
+// distance before or after if the node is the first or last in a section.
+
+inline IsValidNextPrevNd( const SwNode& rNd )
+{
+    return ND_TABLENODE == rNd.GetNodeType() ||
+           ( ND_CONTENTNODE & rNd.GetNodeType() ) ||
+            ( ND_ENDNODE == rNd.GetNodeType() && rNd.StartOfSectionNode() &&
+            ND_TABLENODE == rNd.StartOfSectionNode()->GetNodeType() );
+}
+
+BYTE SwNode::HasPrevNextLayNode() const
+{
+    BYTE nRet = 0;
+    if( IsValidNextPrevNd( *this ))
+    {
+        SwNodeIndex aIdx( *this, -1 );
+        if( IsValidNextPrevNd( aIdx.GetNode() ))
+            nRet |= ND_HAS_PREV_LAYNODE;
+        aIdx += 2;
+        if( IsValidNextPrevNd( aIdx.GetNode() ))
+            nRet |= ND_HAS_NEXT_LAYNODE;
+    }
+    return nRet;
+}
+
+/*******************************************************************
+|*
+|*  SwNode::StartOfSection
+|*
+|*  Beschreibung
+|*      Die Funktion liefert die StartOfSection des Nodes.
+|*
+|*  Parameter
+|*      IN
+|*      rNodes bezeichnet das variable Array, in dem sich der Node
+|*      befindet
+|*  Ersterstellung
+|*      VER0100 vb 901214
+|*
+|*  Stand
+|*      VER0100 vb 901214
+|*
+*******************************************************************/
+
+
+SwStartNode::SwStartNode( const SwNodeIndex &rWhere, const BYTE nNdType,
+                            SwStartNodeType eSttNd )
+    : SwNode( rWhere, nNdType ), eSttNdTyp( eSttNd )
+{
+    // erstmal temporaer, bis der EndNode eingefuegt wird.
+    pEndOfSection = (SwEndNode*)this;
+}
+
+SwStartNode::SwStartNode( SwNodes& rNodes, ULONG nPos )
+    : SwNode( rNodes, nPos, ND_STARTNODE ), eSttNdTyp( SwNormalStartNode )
+{
+    // erstmal temporaer, bis der EndNode eingefuegt wird.
+    pEndOfSection = (SwEndNode*)this;
+}
+
+
+void SwStartNode::CheckSectionCondColl() const
+{
+//FEATURE::CONDCOLL
+    SwNodeIndex aIdx( *this );
+    ULONG nEndIdx = EndOfSectionIndex();
+    const SwNodes& rNds = GetNodes();
+    SwCntntNode* pCNd;
+    while( 0 != ( pCNd = rNds.GoNext( &aIdx )) && pCNd->GetIndex() < nEndIdx )
+        pCNd->ChkCondColl();
+//FEATURE::CONDCOLL
+}
+
+/*******************************************************************
+|*
+|*  SwEndNode::SwEndNode
+|*
+|*  Beschreibung
+|*      Konstruktor; dieser fuegt einen Node in das Array rNodes
+|*      an der Position aWhere ein. Der
+|*      theStartOfSection-Pointer wird entsprechend gesetzt,
+|*      und der EndOfSection-Pointer des zugehoerigen
+|*      Startnodes -- durch rStartOfSection bezeichnet --
+|*      wird auf diesen Node gesetzt.
+|*
+|*  Parameter
+|*      IN
+|*      rNodes bezeichnet das variable Array, in das der Node
+|*      eingefuegt werden soll
+|*      IN
+|*      aWhere bezeichnet die Position innerhalb dieses Arrays,
+|*      an der der Node eingefuegt werden soll
+|*      !!!!!!!!!!!!
+|*      Es wird eine Kopie uebergeben!
+|*
+|*  Ersterstellung
+|*      VER0100 vb 901214
+|*
+|*  Stand
+|*      VER0100 vb 901214
+|*
+*******************************************************************/
+
+
+SwEndNode::SwEndNode( const SwNodeIndex &rWhere, SwStartNode& rSttNd )
+    : SwNode( rWhere, ND_ENDNODE )
+{
+    pStartOfSection = &rSttNd;
+    pStartOfSection->pEndOfSection = this;
+}
+
+SwEndNode::SwEndNode( SwNodes& rNds, ULONG nPos, SwStartNode& rSttNd )
+    : SwNode( rNds, nPos, ND_ENDNODE )
+{
+    pStartOfSection = &rSttNd;
+    pStartOfSection->pEndOfSection = this;
+}
+
+
+
+// --------------------
+// SwCntntNode
+// --------------------
+
+
+SwCntntNode::SwCntntNode( const SwNodeIndex &rWhere, const BYTE nNdType,
+                            SwFmtColl *pColl )
+    : SwNode( rWhere, nNdType ),
+    pAttrSet( 0 ),
+    pCondColl( 0 ),
+    SwModify( pColl )    // CrsrsShell, FrameFmt
+#ifdef OLD_INDEX
+    ,SwIndexReg(2)
+#endif
+{
+}
+
+
+SwCntntNode::~SwCntntNode()
+{
+    // Die Basisklasse SwClient vom SwFrm nimmt sich aus
+    // der Abhaengikeitsliste raus!
+    // Daher muessen alle Frames in der Abhaengigkeitsliste geloescht werden.
+    if( GetDepends() )
+        DelFrms();
+
+    if( pAttrSet )
+        delete pAttrSet;
+    if( pCondColl )
+        delete pCondColl;
+}
+
+
+void SwCntntNode::Modify( SfxPoolItem* pOldValue, SfxPoolItem* pNewValue )
+{
+    USHORT nWhich = pOldValue ? pOldValue->Which() :
+                    pNewValue ? pNewValue->Which() : 0 ;
+    BOOL bNumRuleSet = FALSE;
+    String sNumRule, sOldNumRule;
+    const SfxPoolItem* pItem;
+
+    switch( nWhich )
+    {
+    case RES_OBJECTDYING :
+        {
+            SwFmt * pFmt = (SwFmt *) ((SwPtrMsgPoolItem *)pNewValue)->pObject;
+
+            // nicht umhaengen wenn dieses das oberste Format ist !!
+            if( pRegisteredIn == pFmt )
+            {
+                if( pFmt->GetRegisteredIn() )
+                {
+                    // wenn Parent, dann im neuen Parent wieder anmelden
+                    ((SwModify*)pFmt->GetRegisteredIn())->Add( this );
+                    if ( pAttrSet )
+                        pAttrSet->SetParent(
+                                &((SwFmt*)GetRegisteredIn())->GetAttrSet() );
+                }
+                else
+                {
+                    // sonst auf jeden Fall beim sterbenden abmelden
+                    ((SwModify*)GetRegisteredIn())->Remove( this );
+                    if ( pAttrSet )
+                        pAttrSet->SetParent( 0 );
+                }
+            }
+        }
+        break;
+
+
+    case RES_FMT_CHG:
+        // falls mein Format Parent umgesetzt wird, dann melde ich
+        // meinen Attrset beim Neuen an.
+
+        // sein eigenes Modify ueberspringen !!
+        if( pAttrSet &&
+            ((SwFmtChg*)pNewValue)->pChangedFmt == GetRegisteredIn() )
+        {
+            // den Set an den neuen Parent haengen
+            pAttrSet->SetParent( GetRegisteredIn() ?
+                &((SwFmt*)GetRegisteredIn())->GetAttrSet() : 0 );
+        }
+        if( GetNodes().IsDocNodes() && IsTxtNode() )
+        {
+            if( 0 != ( pItem = GetNoCondAttr( RES_PARATR_NUMRULE, TRUE )))
+            {
+                bNumRuleSet = TRUE;
+                sNumRule = ((SwNumRuleItem*)pItem)->GetValue();
+            }
+            sOldNumRule = ((SwFmtChg*)pOldValue)->pChangedFmt->GetNumRule().GetValue();
+        }
+        break;
+//FEATURE::CONDCOLL
+    case RES_CONDCOLL_CONDCHG:
+        if( ((SwCondCollCondChg*)pNewValue)->pChangedFmt == GetRegisteredIn() &&
+            &GetNodes() == &GetDoc()->GetNodes() )
+        {
+            ChkCondColl();
+        }
+        return ;    // nicht an die Basisklasse / Frames weitergeben
+//FEATURE::CONDCOLL
+
+    case RES_ATTRSET_CHG:
+        if( GetNodes().IsDocNodes() && IsTxtNode() )
+        {
+            if( SFX_ITEM_SET == ((SwAttrSetChg*)pNewValue)->GetChgSet()->GetItemState(
+                RES_PARATR_NUMRULE, FALSE, &pItem ))
+            {
+                bNumRuleSet = TRUE;
+                sNumRule = ((SwNumRuleItem*)pItem)->GetValue();
+            }
+            if( SFX_ITEM_SET == ((SwAttrSetChg*)pOldValue)->GetChgSet()->GetItemState(
+                RES_PARATR_NUMRULE, FALSE, &pItem ))
+                sOldNumRule = ((SwNumRuleItem*)pItem)->GetValue();
+        }
+        break;
+
+    case RES_PARATR_NUMRULE:
+        if( GetNodes().IsDocNodes() && IsTxtNode() )
+        {
+            if( pNewValue )
+            {
+                bNumRuleSet = TRUE;
+                sNumRule = ((SwNumRuleItem*)pNewValue)->GetValue();
+            }
+            if( pOldValue )
+                sOldNumRule = ((SwNumRuleItem*)pOldValue)->GetValue();
+        }
+        break;
+    }
+
+    if( bNumRuleSet )
+    {
+        if( sNumRule.Len() )
+        {
+            if( !((SwTxtNode*)this)->GetNum() )
+                ((SwTxtNode*)this)->UpdateNum( SwNodeNum(0) );
+#ifndef NUM_RELSPACE
+            SetNumLSpace( TRUE );
+#endif
+            SwNumRule* pRule = GetDoc()->FindNumRulePtr( sNumRule );
+            if( !pRule )
+            {
+                USHORT nPoolId = GetDoc()->GetPoolId( sNumRule, GET_POOLID_NUMRULE );
+                if( USHRT_MAX != nPoolId )
+                    pRule = GetDoc()->GetNumRuleFromPool( nPoolId );
+            }
+            if( pRule )
+                pRule->SetInvalidRule( TRUE );
+        }
+        else if( ((SwTxtNode*)this)->GetNum() )
+        {
+            ((SwTxtNode*)this)->UpdateNum( SwNodeNum(NO_NUMBERING) );
+#ifndef NUM_RELSPACE
+            SetNumLSpace( TRUE );
+#endif
+        }
+    }
+    if( sOldNumRule.Len() && sNumRule != sOldNumRule )
+    {
+        SwNumRule* pRule = GetDoc()->FindNumRulePtr( sOldNumRule );
+        if( pRule )
+            pRule->SetInvalidRule( TRUE );
+    }
+
+    SwModify::Modify( pOldValue, pNewValue );
+}
+
+BOOL SwCntntNode::InvalidateNumRule()
+{
+    SwNumRule* pRule = 0;
+    const SfxPoolItem* pItem;
+    if( GetNodes().IsDocNodes() &&
+        0 != ( pItem = GetNoCondAttr( RES_PARATR_NUMRULE, TRUE )) &&
+        ((SwNumRuleItem*)pItem)->GetValue().Len() &&
+        0 != (pRule = GetDoc()->FindNumRulePtr(
+                                ((SwNumRuleItem*)pItem)->GetValue() ) ) )
+    {
+        pRule->SetInvalidRule( TRUE );
+    }
+    return 0 != pRule;
+}
+
+
+SwCntntFrm *SwCntntNode::GetFrm( const Point* pPoint,
+                                const SwPosition *pPos,
+                                const BOOL bCalcFrm ) const
+{
+    return (SwCntntFrm*) ::GetFrmOfModify( *(SwModify*)this, FRM_CNTNT,
+                                            pPoint, pPos, bCalcFrm );
+}
+
+SwRect SwCntntNode::FindLayoutRect( const BOOL bPrtArea, const Point* pPoint,
+                                    const BOOL bCalcFrm ) const
+{
+    SwRect aRet;
+    SwCntntFrm* pFrm = (SwCntntFrm*)::GetFrmOfModify( *(SwModify*)this,
+                                            FRM_CNTNT, pPoint, 0, bCalcFrm );
+    if( pFrm )
+        aRet = bPrtArea ? pFrm->Prt() : pFrm->Frm();
+    return aRet;
+}
+
+SwRect SwCntntNode::FindPageFrmRect( const BOOL bPrtArea, const Point* pPoint,
+                                    const BOOL bCalcFrm ) const
+{
+    SwRect aRet;
+    SwFrm* pFrm = ::GetFrmOfModify( *(SwModify*)this,
+                                            FRM_CNTNT, pPoint, 0, bCalcFrm );
+    if( pFrm && 0 != ( pFrm = pFrm->FindPageFrm() ))
+        aRet = bPrtArea ? pFrm->Prt() : pFrm->Frm();
+    return aRet;
+}
+
+xub_StrLen SwCntntNode::Len() const { return 0; }
+
+
+
+SwFmtColl *SwCntntNode::ChgFmtColl( SwFmtColl *pNewColl )
+{
+    ASSERT( pNewColl, Collectionpointer ist 0. );
+    SwFmtColl *pOldColl = GetFmtColl();
+    if( pNewColl != pOldColl )
+    {
+        pNewColl->Add( this );
+
+        // setze den Parent von unseren Auto-Attributen auf die neue
+        // Collection:
+        if( pAttrSet )
+            pAttrSet->SetParent( &pNewColl->GetAttrSet() );
+
+//FEATURE::CONDCOLL
+        // HACK: hier muss die entsprechend der neuen Vorlage die Bedingungen
+        //      neu ueberprueft werden!
+        if( TRUE /*pNewColl */ )
+        {
+            SetCondFmtColl( 0 );
+        }
+//FEATURE::CONDCOLL
+
+        if( !IsModifyLocked() )
+        {
+            SwFmtChg aTmp1( pOldColl );
+            SwFmtChg aTmp2( pNewColl );
+//          SwModify::Modify( &aTmp1, &aTmp2 );
+            // damit alles was im Modify passiert hier nicht noch impl.
+            // werden muss
+            SwCntntNode::Modify( &aTmp1, &aTmp2 );
+        }
+    }
+    if ( IsInCache() )
+    {
+        SwFrm::GetCache().Delete( this );
+        SetInCache( FALSE );
+    }
+    return pOldColl;
+}
+
+
+BOOL SwCntntNode::GoNext(SwIndex * pIdx) const
+{
+    if( pIdx->GetIndex() < Len() )
+    {
+        if( !IsTxtNode() )
+        {
+            (*pIdx)++;
+            return TRUE;
+        }
+
+        if( pBreakIt->xBreak.is() )
+        {
+            const SwTxtNode& rTNd = *GetTxtNode();
+            xub_StrLen nPos = pIdx->GetIndex();
+            sal_Int32 nDone = 0;
+            nPos = pBreakIt->xBreak->nextCharacters( rTNd.GetTxt(), nPos,
+                            pBreakIt->GetLocale( rTNd.GetLang( nPos ) ),
+                            CharacterIteratorMode::SKIPCONTROLCHARACTER,
+                            1, nDone );
+            if( 1 == nDone )
+            {
+                *pIdx = nPos;
+                return TRUE;
+            }
+        }
+    }
+    return FALSE;
+}
+
+
+BOOL SwCntntNode::GoPrevious(SwIndex * pIdx) const
+{
+    if( pIdx->GetIndex() > 0 )
+    {
+        if( !IsTxtNode() )
+        {
+            (*pIdx)--;
+            return TRUE;
+        }
+
+        if( pBreakIt->xBreak.is() )
+        {
+            const SwTxtNode& rTNd = *GetTxtNode();
+            xub_StrLen nPos = pIdx->GetIndex();
+            sal_Int32 nDone = 0;
+            nPos = pBreakIt->xBreak->previousCharacters( rTNd.GetTxt(), nPos,
+                            pBreakIt->GetLocale( rTNd.GetLang( nPos ) ),
+                            CharacterIteratorMode::SKIPCONTROLCHARACTER,
+                            1, nDone );
+            if( 1 == nDone )
+            {
+                *pIdx = nPos;
+                return TRUE;
+            }
+        }
+    }
+    return FALSE;
+}
+
+
+/*
+ * Methode erzeugt fuer den vorhergehenden Node alle Ansichten vom
+ * Dokument. Die erzeugten Contentframes werden in das entsprechende
+ * Layout gehaengt.
+ */
+
+
+void SwCntntNode::MakeFrms( SwCntntNode& rNode )
+{
+    ASSERT( &rNode != this,
+            "Kein Contentnode oder Copy-Node und neuer Node identisch." );
+
+    if( !GetDepends() || &rNode == this )   // gibt es ueberhaupt Frames ??
+        return;
+
+    SwFrm *pFrm, *pNew;
+    SwLayoutFrm *pUpper;
+    // Frames anlegen fuer Nodes, die vor oder hinter der Tabelle stehen ??
+    ASSERT( FindTableNode() == rNode.FindTableNode(), "Table confusion" )
+
+    SwNode2Layout aNode2Layout( *this, rNode.GetIndex() );
+
+    while( 0 != (pUpper = aNode2Layout.UpperFrm( pFrm, rNode )) )
+    {
+        pNew = rNode.MakeFrm();
+        pNew->Paste( pUpper, pFrm );
+    }
+}
+
+/*
+ * Methode loescht fuer den Node alle Ansichten vom
+ * Dokument. Die Contentframes werden aus dem entsprechenden
+ * Layout ausgehaengt.
+ */
+
+
+void SwCntntNode::DelFrms()
+{
+    if( !GetDepends() )
+        return;
+
+    SwClientIter aIter( *this );
+    SwCntntFrm *pFrm;
+
+    for( pFrm = (SwCntntFrm*)aIter.First( TYPE(SwCntntFrm)); pFrm;
+         pFrm = (SwCntntFrm*)aIter.Next() )
+    {
+        pFrm->SetFollow( 0 );//Damit er nicht auf dumme Gedanken kommt.
+                                //Andernfalls kann es sein, dass ein Follow
+                                //vor seinem Master zerstoert wird, der Master
+                                //greift dann ueber den ungueltigen
+                                //Follow-Pointer auf fremdes Memory zu.
+                                //Die Kette darf hier zerknauscht werden, weil
+                                //sowieso alle zerstoert werden.
+        if( pFrm->GetUpper() && pFrm->IsInFtn() && !pFrm->GetIndNext() &&
+            !pFrm->GetIndPrev() )
+        {
+            SwFtnFrm *pFtn = pFrm->FindFtnFrm();
+            ASSERT( pFtn, "You promised a FtnFrm?" );
+            if( !pFtn->GetFollow() && !pFtn->GetMaster() && pFtn->GetRef() &&
+                pFtn->GetRef()->IsFollow() )
+            {
+                ASSERT( pFtn->GetRef()->IsTxtFrm(), "NoTxtFrm has Footnote?" );
+                ((SwTxtFrm*)pFtn->GetRef()->FindMaster())->Prepare( PREP_FTN_GONE );
+            }
+        }
+        pFrm->Cut();
+        delete pFrm;
+    }
+    if( IsTxtNode() )
+    {
+        ((SwTxtNode*)this)->SetWrong( NULL );
+        SetWrongDirty( TRUE );
+        SetAutoCompleteWordDirty( TRUE );
+    }
+}
+
+
+SwCntntNode *SwCntntNode::JoinNext()
+{
+    return this;
+}
+
+
+SwCntntNode *SwCntntNode::JoinPrev()
+{
+    return this;
+}
+
+
+
+    // erfrage vom Modify Informationen
+BOOL SwCntntNode::GetInfo( SfxPoolItem& rInfo ) const
+{
+    const SwNumRuleItem* pItem;
+    switch( rInfo.Which() )
+    {
+    case RES_AUTOFMT_DOCNODE:
+        if( &GetNodes() == ((SwAutoFmtGetDocNode&)rInfo).pNodes )
+        {
+            ((SwAutoFmtGetDocNode&)rInfo).pCntntNode = this;
+            return FALSE;
+        }
+        break;
+    case RES_GETNUMNODES:
+        if( IsTxtNode() && 0 != ( pItem = (SwNumRuleItem*)GetNoCondAttr(
+            RES_PARATR_NUMRULE, TRUE )) &&
+            pItem->GetValue().Len() &&
+            pItem->GetValue() == ((SwNumRuleInfo&)rInfo).GetName() )
+        {
+            ((SwNumRuleInfo&)rInfo).AddNode( *(SwTxtNode*)this );
+        }
+        return TRUE;
+
+    case RES_GETLOWERNUMLEVEL:
+        if( IsTxtNode() && ((SwTxtNode*)this)->GetNum() &&
+            0 != ( pItem = (SwNumRuleItem*)GetNoCondAttr(
+            RES_PARATR_NUMRULE, TRUE )) && pItem->GetValue().Len() &&
+            pItem->GetValue() == ((SwNRuleLowerLevel&)rInfo).GetName() &&
+            (((SwTxtNode*)this)->GetNum()->GetLevel() & ~NO_NUMLEVEL)
+                > ((SwNRuleLowerLevel&)rInfo).GetLevel() )
+        {
+            return FALSE;
+        }
+        break;
+
+    case RES_FINDNEARESTNODE:
+        if( ((SwFmtPageDesc&)GetAttr( RES_PAGEDESC )).GetPageDesc() )
+            ((SwFindNearestNode&)rInfo).CheckNode( *this );
+        return TRUE;
+
+    case RES_CONTENT_VISIBLE:
+        {
+            ((SwPtrMsgPoolItem&)rInfo).pObject =
+                SwClientIter( *(SwCntntNode*)this ).First( TYPE(SwFrm) );
+        }
+        return FALSE;
+    }
+
+    return SwModify::GetInfo( rInfo );
+}
+
+
+    // setze ein Attribut
+BOOL SwCntntNode::SetAttr(const SfxPoolItem& rAttr )
+{
+    if( !pAttrSet )         // lasse von den entsprechenden Nodes die
+        NewAttrSet( GetDoc()->GetAttrPool() );      // AttrSets anlegen
+
+    ASSERT( pAttrSet, "warum wurde kein AttrSet angelegt?" );
+
+    if ( IsInCache() )
+    {
+        SwFrm::GetCache().Delete( this );
+        SetInCache( FALSE );
+    }
+
+    BOOL bRet = FALSE;
+    // wenn Modify gelockt ist, werden keine Modifies verschickt
+    if( IsModifyLocked() || !GetDepends() )
+    {
+        if( 0 != ( bRet = (0 != pAttrSet->Put( rAttr )) ))
+            // einige Sonderbehandlungen fuer Attribute
+            pAttrSet->SetModifyAtAttr( this );
+    }
+    else
+    {
+        SwAttrSet aOld( *pAttrSet->GetPool(), pAttrSet->GetRanges() ),
+                    aNew( *pAttrSet->GetPool(), pAttrSet->GetRanges() );
+        if( 0 != ( bRet = pAttrSet->Put_BC( rAttr, &aOld, &aNew ) ))
+        {
+            // einige Sonderbehandlungen fuer Attribute
+            pAttrSet->SetModifyAtAttr( this );
+
+            SwAttrSetChg aChgOld( *pAttrSet, aOld );
+            SwAttrSetChg aChgNew( *pAttrSet, aNew );
+            Modify( &aChgOld, &aChgNew );       // alle veraenderten werden verschickt
+        }
+    }
+    return bRet;
+}
+
+
+BOOL SwCntntNode::SetAttr( const SfxItemSet& rSet )
+{
+    if( !pAttrSet )         // lasse von den entsprechenden Nodes die
+        NewAttrSet( GetDoc()->GetAttrPool() );      // AttrSets anlegen
+
+    if ( IsInCache() )
+    {
+        SwFrm::GetCache().Delete( this );
+        SetInCache( FALSE );
+    }
+
+    BOOL bRet = FALSE;
+
+    // wenn Modify gelockt ist, werden keine Modifies verschickt
+    if( IsModifyLocked() || !GetDepends() )
+    {
+        // einige Sonderbehandlungen fuer Attribute
+        if( 0 != (bRet = (0 != pAttrSet->Put( rSet ))) )
+            pAttrSet->SetModifyAtAttr( this );
+    }
+    else
+    {
+        SwAttrSet aOld( *pAttrSet->GetPool(), pAttrSet->GetRanges() ),
+                    aNew( *pAttrSet->GetPool(), pAttrSet->GetRanges() );
+        if( 0 != (bRet = pAttrSet->Put_BC( rSet, &aOld, &aNew )) )
+        {
+            // einige Sonderbehandlungen fuer Attribute
+            pAttrSet->SetModifyAtAttr( this );
+            SwAttrSetChg aChgOld( *pAttrSet, aOld );
+            SwAttrSetChg aChgNew( *pAttrSet, aNew );
+            Modify( &aChgOld, &aChgNew );       // alle veraenderten werden verschickt
+        }
+    }
+    return bRet;
+}
+
+// Nimmt den Hint mit nWhich aus dem Delta-Array
+
+
+BOOL SwCntntNode::ResetAttr( USHORT nWhich1, USHORT nWhich2 )
+{
+    if( !pAttrSet )
+        return FALSE;
+
+    if ( IsInCache() )
+    {
+        SwFrm::GetCache().Delete( this );
+        SetInCache( FALSE );
+    }
+
+    // wenn Modify gelockt ist, werden keine Modifies verschickt
+    if( IsModifyLocked() )
+    {
+        USHORT nDel = (!nWhich2 || nWhich2 < nWhich1)
+                ? pAttrSet->ClearItem( nWhich1 )
+                : pAttrSet->ClearItem_BC( nWhich1, nWhich2 );
+
+        if( !pAttrSet->Count() )    // leer, dann loeschen
+            DELETEZ( pAttrSet );
+        return 0 != nDel;
+    }
+
+    // sollte kein gueltiger Bereich definiert sein ?
+    if( !nWhich2 || nWhich2 < nWhich1 )
+        nWhich2 = nWhich1;      // dann setze auf 1. Id, nur dieses Item
+
+    SwAttrSet aOld( *pAttrSet->GetPool(), pAttrSet->GetRanges() ),
+                aNew( *pAttrSet->GetPool(), pAttrSet->GetRanges() );
+    BOOL bRet = 0 != pAttrSet->ClearItem_BC( nWhich1, nWhich2, &aOld, &aNew );
+
+    if( bRet )
+    {
+        SwAttrSetChg aChgOld( *pAttrSet, aOld );
+        SwAttrSetChg aChgNew( *pAttrSet, aNew );
+        Modify( &aChgOld, &aChgNew );       // alle veraenderten werden verschickt
+
+        if( !pAttrSet->Count() )    // leer, dann loeschen
+            DELETEZ( pAttrSet );
+    }
+    return bRet;
+}
+BOOL SwCntntNode::ResetAttr( const SvUShorts& rWhichArr )
+{
+    if( !pAttrSet )
+        return FALSE;
+
+    if ( IsInCache() )
+    {
+        SwFrm::GetCache().Delete( this );
+        SetInCache( FALSE );
+    }
+
+    // wenn Modify gelockt ist, werden keine Modifies verschickt
+    USHORT nDel = 0;
+    if( IsModifyLocked() )
+    {
+        for( USHORT n = 0, nEnd = rWhichArr.Count(); n < nEnd; ++n )
+            if( pAttrSet->ClearItem( rWhichArr[ n ] ))
+                ++nDel;
+    }
+    else
+    {
+        SwAttrSet aOld( *pAttrSet->GetPool(), pAttrSet->GetRanges() ),
+                    aNew( *pAttrSet->GetPool(), pAttrSet->GetRanges() );
+
+        for( USHORT n = 0, nEnd = rWhichArr.Count(); n < nEnd; ++n )
+            if( pAttrSet->ClearItem( rWhichArr[ n ] ))
+                ++nDel;
+
+        if( nDel )
+        {
+            SwAttrSetChg aChgOld( *pAttrSet, aOld );
+            SwAttrSetChg aChgNew( *pAttrSet, aNew );
+            Modify( &aChgOld, &aChgNew );       // alle veraenderten werden verschickt
+        }
+    }
+    if( !pAttrSet->Count() )    // leer, dann loeschen
+        DELETEZ( pAttrSet );
+    return 0 != nDel ;
+}
+
+
+USHORT SwCntntNode::ResetAllAttr()
+{
+    if( !pAttrSet )
+        return 0;
+
+    if ( IsInCache() )
+    {
+        SwFrm::GetCache().Delete( this );
+        SetInCache( FALSE );
+    }
+
+    // wenn Modify gelockt ist, werden keine Modifies verschickt
+    if( IsModifyLocked() )
+    {
+        USHORT nDel = pAttrSet->ClearItem( 0 );
+        if( !pAttrSet->Count() )    // leer, dann loeschen
+            DELETEZ( pAttrSet );
+        return nDel;
+    }
+
+    SwAttrSet aOld( *pAttrSet->GetPool(), pAttrSet->GetRanges() ),
+                aNew( *pAttrSet->GetPool(), pAttrSet->GetRanges() );
+    BOOL bRet = 0 != pAttrSet->ClearItem_BC( 0, &aOld, &aNew );
+
+    if( bRet )
+    {
+        SwAttrSetChg aChgOld( *pAttrSet, aOld );
+        SwAttrSetChg aChgNew( *pAttrSet, aNew );
+        Modify( &aChgOld, &aChgNew );       // alle veraenderten werden verschickt
+
+        if( !pAttrSet->Count() )    // leer, dann loeschen
+            DELETEZ( pAttrSet );
+    }
+    return aNew.Count();
+}
+
+
+BOOL SwCntntNode::GetAttr( SfxItemSet& rSet, BOOL bInParent ) const
+{
+    if( rSet.Count() )
+        rSet.ClearItem();
+
+    const SwAttrSet& rAttrSet = GetSwAttrSet();
+    if( bInParent )
+        return rSet.Set( rAttrSet, TRUE ) ? TRUE : FALSE;
+
+    rSet.Put( rAttrSet );
+    return rSet.Count() ? TRUE : FALSE;
+}
+
+const SfxPoolItem* SwCntntNode::GetNoCondAttr( USHORT nWhich,
+                                                BOOL bInParents ) const
+{
+    const SfxPoolItem* pFnd = 0;
+    if( pCondColl && pCondColl->GetRegisteredIn() )
+    {
+        if( !pAttrSet || ( SFX_ITEM_SET != pAttrSet->GetItemState(
+                    nWhich, FALSE, &pFnd ) && bInParents ))
+            ((SwFmt*)GetRegisteredIn())->GetItemState( nWhich, bInParents, &pFnd );
+    }
+    else
+        GetSwAttrSet().GetItemState( nWhich, bInParents, &pFnd );
+    return pFnd;
+}
+
+    // koennen 2 Nodes zusammengefasst werden ?
+    // in pIdx kann die 2. Position returnt werden.
+int SwCntntNode::CanJoinNext( SwNodeIndex* pIdx ) const
+{
+    const SwNodes& rNds = GetNodes();
+    BYTE nNdType = GetNodeType();
+    SwNodeIndex aIdx( *this, 1 );
+
+    const SwNode* pNd = this;
+    while( aIdx < rNds.Count()-1 &&
+        (( pNd = &aIdx.GetNode())->IsSectionNode() ||
+            ( pNd->IsEndNode() && pNd->FindStartNode()->IsSectionNode() )))
+        aIdx++;
+
+    if( pNd->GetNodeType() != nNdType || rNds.Count()-1 == aIdx.GetIndex() )
+        return FALSE;
+    if( pIdx )
+        *pIdx = aIdx;
+    return TRUE;
+}
+
+
+    // koennen 2 Nodes zusammengefasst werden ?
+    // in pIdx kann die 2. Position returnt werden.
+int SwCntntNode::CanJoinPrev( SwNodeIndex* pIdx ) const
+{
+    const SwNodes& rNds = GetNodes();
+    BYTE nNdType = GetNodeType();
+    SwNodeIndex aIdx( *this, -1 );
+
+    const SwNode* pNd = this;
+    while( aIdx.GetIndex() &&
+        (( pNd = &aIdx.GetNode())->IsSectionNode() ||
+            ( pNd->IsEndNode() && pNd->FindStartNode()->IsSectionNode() )))
+        aIdx--;
+
+    if( pNd->GetNodeType() != nNdType || 0 == aIdx.GetIndex() )
+        return FALSE;
+    if( pIdx )
+        *pIdx = aIdx;
+    return TRUE;
+}
+
+
+//FEATURE::CONDCOLL
+
+
+void SwCntntNode::SetCondFmtColl( SwFmtColl* pColl )
+{
+    if( (!pColl && pCondColl) || ( pColl && !pCondColl ) ||
+        ( pColl && pColl != pCondColl->GetRegisteredIn() ) )
+    {
+        SwFmtColl* pOldColl = GetCondFmtColl();
+        delete pCondColl;
+        if( pColl )
+            pCondColl = new SwDepend( this, pColl );
+        else
+            pCondColl = 0;
+
+        if( pAttrSet )
+        {
+// Attrset beibehalten oder loeschen??
+// 13.04.99: Bisher wurden er geloescht, jetzt wird er beibehalten.
+//           #64637#: Beim Laden eines Dokuments wird die bedingte
+//           Vorlage nach dem Laden der harten Attribute gesetzt. Deshalb
+//           wurden die harten Attribute geloescht.
+
+            pAttrSet->SetParent( &GetAnyFmtColl().GetAttrSet() );
+// steht im docfmt.cxx
+//extern BOOL lcl_RstAttr( const SwNodePtr&, void* );
+//          lcl_RstAttr( this, 0 );
+//          if( pAttrSet && !pAttrSet->Count() )
+//              delete pAttrSet, pAttrSet = 0;
+        }
+
+        if( !IsModifyLocked() )
+        {
+            SwFmtChg aTmp1( pOldColl ? pOldColl : GetFmtColl() );
+            SwFmtChg aTmp2( pColl ? pColl : GetFmtColl() );
+            SwModify::Modify( &aTmp1, &aTmp2 );
+        }
+        if( IsInCache() )
+        {
+            SwFrm::GetCache().Delete( this );
+            SetInCache( FALSE );
+        }
+    }
+}
+
+
+BOOL SwCntntNode::IsAnyCondition( SwCollCondition& rTmp ) const
+{
+    const SwNodes& rNds = GetNodes();
+    {
+        int nCond = 0;
+        const SwStartNode* pSttNd = FindStartNode();
+        while( pSttNd )
+        {
+            switch( pSttNd->GetNodeType() )
+            {
+            case ND_TABLENODE:      nCond = PARA_IN_TABLEBODY; break;
+            case ND_SECTIONNODE:    nCond = PARA_IN_SECTION; break;
+
+            default:
+                switch( pSttNd->GetStartNodeType() )
+                {
+                case SwTableBoxStartNode:
+                    {
+                        nCond = PARA_IN_TABLEBODY;
+                        const SwTableNode* pTblNd = pSttNd->FindTableNode();
+                        const SwTableBox* pBox;
+                        if( pTblNd && 0 != ( pBox = pTblNd->GetTable().
+                            GetTblBox( pSttNd->GetIndex() ) ) &&
+                            pBox->IsInHeadline( &pTblNd->GetTable() ) )
+                            nCond = PARA_IN_TABLEHEAD;
+                    }
+                    break;
+                case SwFlyStartNode:        nCond = PARA_IN_FRAME; break;
+                case SwFootnoteStartNode:
+                    {
+                        nCond = PARA_IN_FOOTENOTE;
+                        const SwFtnIdxs& rFtnArr = rNds.GetDoc()->GetFtnIdxs();
+                        const SwTxtFtn* pTxtFtn;
+                        const SwNode* pSrchNd = pSttNd;
+
+                        for( USHORT n = 0; n < rFtnArr.Count(); ++n )
+                            if( 0 != ( pTxtFtn = rFtnArr[ n ])->GetStartNode() &&
+                                pSrchNd == &pTxtFtn->GetStartNode()->GetNode() )
+                            {
+                                if( pTxtFtn->GetFtn().IsEndNote() )
+                                    nCond = PARA_IN_ENDNOTE;
+                                break;
+                            }
+                    }
+                    break;
+                case SwHeaderStartNode:     nCond = PARA_IN_HEADER; break;
+                case SwFooterStartNode:     nCond = PARA_IN_FOOTER; break;
+                }
+            }
+
+            if( nCond )
+            {
+                rTmp.SetCondition( (Master_CollConditions)nCond, 0 );
+                return TRUE;
+            }
+            pSttNd = pSttNd->GetIndex()
+                        ? pSttNd->FindStartNode()
+                        : 0;
+        }
+    }
+
+    {
+        USHORT nPos;
+        const SwOutlineNodes& rOutlNds = rNds.GetOutLineNds();
+        if( rOutlNds.Count() )
+        {
+            if( !rOutlNds.Seek_Entry( (SwCntntNode*)this, &nPos ) && nPos )
+                --nPos;
+            if( nPos < rOutlNds.Count() &&
+                rOutlNds[ nPos ]->GetIndex() < GetIndex() )
+            {
+                SwTxtNode* pOutlNd = rOutlNds[ nPos ]->GetTxtNode();
+
+                if( pOutlNd->GetOutlineNum() && !pOutlNd->GetNumRule() )
+                {
+                    rTmp.SetCondition( PARA_IN_OUTLINE,
+                                    pOutlNd->GetOutlineNum()->GetLevel() );
+                    return TRUE;
+                }
+            }
+        }
+    }
+
+    return FALSE;
+}
+
+
+void SwCntntNode::ChkCondColl()
+{
+    // zur Sicherheit abfragen
+    if( RES_CONDTXTFMTCOLL == GetFmtColl()->Which() )
+    {
+        SwCollCondition aTmp( 0, 0, 0 );
+        const SwCollCondition* pCColl;
+
+        if( IsAnyCondition( aTmp ) && 0 != ( pCColl =
+                ((SwConditionTxtFmtColl*)GetFmtColl())->HasCondition( aTmp )))
+            SetCondFmtColl( pCColl->GetTxtFmtColl() );
+        else
+        {
+            if( IsTxtNode() && ((SwTxtNode*)this)->GetNumRule() &&
+                    ((SwTxtNode*)this)->GetNum() )
+            {
+                // steht in einer Numerierung
+                // welcher Level?
+                aTmp.SetCondition( PARA_IN_LIST,
+                                ((SwTxtNode*)this)->GetNum()->GetLevel() );
+                pCColl = ((SwConditionTxtFmtColl*)GetFmtColl())->
+                                HasCondition( aTmp );
+            }
+            else
+                pCColl = 0;
+
+            if( pCColl )
+                SetCondFmtColl( pCColl->GetTxtFmtColl() );
+            else if( pCondColl )
+                SetCondFmtColl( 0 );
+        }
+    }
+}
+
+//FEATURE::CONDCOLL
+// Metoden aus Node.hxx - erst hier ist der TxtNode bekannt !!
+// os: nur fuer ICC, da der zum optimieren zu dumm ist
+#ifdef ICC
+SwTxtNode   *SwNode::GetTxtNode()
+{
+     return ND_TEXTNODE == nNodeType ? (SwTxtNode*)this : 0;
+}
+const SwTxtNode   *SwNode::GetTxtNode() const
+{
+     return ND_TEXTNODE == nNodeType ? (const SwTxtNode*)this : 0;
+}
+#endif
+
+
+
+
diff --git a/sw/source/core/docnode/node2lay.cxx b/sw/source/core/docnode/node2lay.cxx
new file mode 100644
index 000000000000..24d8d0934f6e
--- /dev/null
+++ b/sw/source/core/docnode/node2lay.cxx
@@ -0,0 +1,422 @@
+/*************************************************************************
+ *
+ *  $RCSfile: node2lay.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:17 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _CALBCK_HXX
+#include    // SwClientIter
+#endif
+#ifndef _NODE_HXX
+#include 
+#endif
+#ifndef _NDINDEX_HXX
+#include 
+#endif
+#ifndef _SWTABLE_HXX
+#include 
+#endif
+#ifndef _FTNFRM_HXX
+#include 
+#endif
+#ifndef _SECTFRM_HXX
+#include 
+#endif
+#include "frmfmt.hxx"
+#include "cntfrm.hxx"
+#include "tabfrm.hxx"
+#include "frmtool.hxx"
+#include "section.hxx"
+#include "node2lay.hxx"
+
+
+/* -----------------25.02.99 10:31-------------------
+ * Die SwNode2LayImpl-Klasse erledigt die eigentliche Arbeit,
+ * die SwNode2Layout-Klasse ist nur die der Oefffentlichkeit bekannte Schnittstelle
+ * --------------------------------------------------*/
+class SwNode2LayImpl
+{
+    SwClientIter *pIter; // Der eigentliche Iterator
+    SvPtrarr *pUpperFrms;// Zum Einsammeln der Upper
+    ULONG nIndex;        // Der Index des einzufuegenden Nodes
+    BOOL bMaster    : 1; // TRUE => nur Master , FALSE => nur Frames ohne Follow
+    BOOL bInit      : 1; // Ist am SwClient bereits ein First()-Aufruf erfolgt?
+public:
+    SwNode2LayImpl( const SwNode& rNode, ULONG nIdx, BOOL bSearch );
+    ~SwNode2LayImpl() { delete pIter; delete pUpperFrms; }
+    SwFrm* NextFrm(); // liefert den naechsten "sinnvollen" Frame
+    SwLayoutFrm* UpperFrm( SwFrm* &rpFrm, const SwNode &rNode );
+    void SaveUpperFrms(); // Speichert (und lockt ggf.) die pUpper
+    // Fuegt unter jeden pUpper des Arrays einen Frame ein.
+    void RestoreUpperFrms( SwNodes& rNds, ULONG nStt, ULONG nEnd );
+
+    SwFrm* GetFrm( const Point* pDocPos = 0,
+                    const SwPosition *pPos = 0,
+                    const BOOL bCalcFrm = TRUE ) const;
+};
+
+/* -----------------25.02.99 10:38-------------------
+ * Hauptaufgabe des Ctor: Das richtige SwModify zu ermitteln,
+ * ueber das iteriert wird.
+ * Uebergibt man bSearch == TRUE, so wird der naechste Cntnt- oder TableNode
+ * gesucht, der Frames besitzt ( zum Einsammeln der pUpper ), ansonsten wird
+ * erwartet, das rNode bereits auf einem solchen Cntnt- oder TableNode sitzt,
+ * vor oder hinter den eingefuegt werden soll.
+ * --------------------------------------------------*/
+
+SwNode2LayImpl::SwNode2LayImpl( const SwNode& rNode, ULONG nIdx, BOOL bSearch )
+    : pUpperFrms( NULL ), nIndex( nIdx ), bInit( FALSE )
+{
+    const SwNode* pNd;
+    if( bSearch || rNode.IsSectionNode() )
+    {
+        // Suche den naechsten Cntnt/TblNode, der einen Frame besitzt,
+        // damit wir uns vor/hinter ihn haengen koennen
+        if( !bSearch && rNode.GetIndex() < nIndex )
+        {
+            SwNodeIndex aTmp( *rNode.EndOfSectionNode(), +1 );
+            pNd = rNode.GetNodes().GoPreviousWithFrm( &aTmp );
+            if( !bSearch && pNd && rNode.GetIndex() > pNd->GetIndex() )
+                pNd = NULL; // Nicht ueber den Bereich hinausschiessen
+            bMaster = FALSE;
+        }
+        else
+        {
+            SwNodeIndex aTmp( rNode, -1 );
+            pNd = rNode.GetNodes().GoNextWithFrm( &aTmp );
+            bMaster = TRUE;
+            if( !bSearch && pNd && rNode.EndOfSectionIndex() < pNd->GetIndex() )
+                pNd = NULL; // Nicht ueber den Bereich hinausschiessen
+        }
+    }
+    else
+    {
+        pNd = &rNode;
+        bMaster = nIndex < rNode.GetIndex();
+    }
+    if( pNd )
+    {
+        SwModify *pMod;
+        if( pNd->IsCntntNode() )
+            pMod = (SwModify*)pNd->GetCntntNode();
+        else
+        {
+            ASSERT( pNd->IsTableNode(), "For Tablenodes only" );
+            pMod = pNd->GetTableNode()->GetTable().GetFrmFmt();
+        }
+        pIter = new SwClientIter( *pMod );
+    }
+    else
+        pIter = NULL;
+}
+
+/* -----------------25.02.99 10:41-------------------
+ * SwNode2LayImpl::NextFrm() liefert den naechsten "sinnvollen" Frame,
+ * beim ersten Aufruf wird am eigentlichen Iterator ein First gerufen,
+ * danach die Next-Methode. Das Ergebnis wird auf Brauchbarkeit untersucht,
+ * so werden keine Follows akzeptiert, ein Master wird beim Einsammeln der
+ * pUpper und beim Einfuegen vor ihm akzeptiert. Beim Einfuegen dahinter
+ * wird vom Master ausgehend der letzte Follow gesucht und zurueckgegeben.
+ * Wenn der Frame innerhalb eines SectionFrms liegt, wird noch festgestellt,
+ * ob statt des Frames der SectionFrm der geeignete Rueckgabewert ist, dies
+ * ist der Fall, wenn der neu einzufuegende Node ausserhalb des Bereichs liegt.
+ * --------------------------------------------------*/
+SwFrm* SwNode2LayImpl::NextFrm()
+{
+    SwFrm* pRet;
+    if( !pIter )
+        return FALSE;
+    if( !bInit )
+    {
+         pRet = (SwFrm*)pIter->First(TYPE(SwFrm));
+         bInit = TRUE;
+    }
+    else
+        pRet = (SwFrm*)pIter->Next();
+    while( pRet )
+    {
+        SwFlowFrm* pFlow = SwFlowFrm::CastFlowFrm( pRet );
+        ASSERT( pFlow, "Cntnt or Table expected?!" );
+        // Follows sind fluechtige Gestalten, deshalb werden sie ignoriert.
+        // Auch wenn wir hinter dem Frame eingefuegt werden sollen, nehmen wir
+        // zunaechst den Master, hangeln uns dann aber zum letzten Follow durch.
+        if( !pFlow->IsFollow() )
+        {
+            if( !bMaster )
+            {
+                while( pFlow->HasFollow() )
+                    pFlow = pFlow->GetFollow();
+                pRet = pFlow->GetFrm();
+            }
+            if( pRet->IsInSct() )
+            {
+                SwSectionFrm* pSct = pRet->FindSctFrm();
+                // Vorsicht: Wenn wir in einer Fussnote sind, so kann diese
+                // Layoutmaessig in einem spaltigen Bereich liegen, obwohl
+                // sie nodemaessig ausserhalb liegt. Deshalb muss bei Fussnoten
+                // ueberprueft werden, ob auch der SectionFrm in der Fussnote
+                // und nicht ausserhalb liegt.
+                if( !pRet->IsInFtn() || pSct->IsInFtn() )
+                {
+                    ASSERT( pSct && pSct->GetSection(), "Where's my section?" );
+                    SwSectionNode* pNd = pSct->GetSection()->GetFmt()->GetSectionNode();
+                    ASSERT( pNd, "Lost SectionNode" );
+                    // Wenn der erhaltene Frame in einem Bereichsframe steht,
+                    // dessen Bereich den Ausgangsnode nicht umfasst, so kehren
+                    // wir mit dem SectionFrm zurueck, sonst mit dem Cntnt/TabFrm
+                    if( bMaster )
+                    {
+                        if( pNd->GetIndex() >= nIndex )
+                            pRet = pSct;
+                    }
+                    else if( pNd->EndOfSectionIndex() < nIndex )
+                        pRet = pSct;
+                }
+            }
+            return pRet;
+        }
+        pRet = (SwFrm*)pIter->Next();
+    }
+    return NULL;
+}
+
+void SwNode2LayImpl::SaveUpperFrms()
+{
+    pUpperFrms = new SvPtrarr( 0, 20 );
+    SwFrm* pFrm;
+    while( 0 != (pFrm = NextFrm()) )
+    {
+        SwFrm* pPrv = pFrm->GetPrev();
+        pFrm = pFrm->GetUpper();
+        if( pFrm )
+        {
+            if( pFrm->IsFtnFrm() )
+                ((SwFtnFrm*)pFrm)->ColLock();
+            else if( pFrm->IsInSct() )
+                pFrm->FindSctFrm()->ColLock();
+            if( pPrv && pPrv->IsSctFrm() )
+                ((SwSectionFrm*)pPrv)->LockJoin();
+            pUpperFrms->Insert( (void*)pPrv, pUpperFrms->Count() );
+            pUpperFrms->Insert( (void*)pFrm, pUpperFrms->Count() );
+        }
+    }
+    delete pIter;
+    pIter = NULL;
+}
+
+SwLayoutFrm* SwNode2LayImpl::UpperFrm( SwFrm* &rpFrm, const SwNode &rNode )
+{
+    rpFrm = NextFrm();
+    if( !rpFrm )
+        return NULL;
+    SwLayoutFrm* pUpper = rpFrm->GetUpper();
+    if( rpFrm->IsSctFrm() )
+    {
+        const SwNode* pNode = rNode.StartOfSectionNode();
+        if( pNode->IsSectionNode() )
+        {
+            SwFrm* pFrm = bMaster ? rpFrm->FindPrev() : rpFrm->FindNext();
+            if( pFrm && pFrm->IsSctFrm() )
+            {
+                if( ((SwSectionNode*)pNode)->GetSection() ==
+                    *((SwSectionFrm*)pFrm)->GetSection() )
+                {
+                    rpFrm = bMaster ? NULL : ((SwLayoutFrm*)pFrm)->Lower();
+                    return ((SwLayoutFrm*)pFrm);
+                }
+                pUpper =new SwSectionFrm(((SwSectionNode*)pNode)->GetSection());
+                pUpper->Paste( rpFrm->GetUpper(),
+                               bMaster ? rpFrm : rpFrm->GetNext() );
+                rpFrm = NULL;
+                return pUpper;
+            }
+        }
+    };
+    if( !bMaster )
+        rpFrm = rpFrm->GetNext();
+    return pUpper;
+}
+
+void SwNode2LayImpl::RestoreUpperFrms( SwNodes& rNds, ULONG nStt, ULONG nEnd )
+{
+    ASSERT( pUpperFrms, "RestoreUpper without SaveUpper?" )
+    SwNode* pNd;
+    SwDoc *pDoc = rNds.GetDoc();
+    BOOL bFirst = TRUE;
+    for( ; nStt < nEnd; ++nStt )
+    {
+        SwFrm* pNew = 0;
+        SwFrm* pNxt;
+        SwLayoutFrm* pUp;
+        if( (pNd = rNds[nStt])->IsCntntNode() )
+            for( USHORT n = 0; n < pUpperFrms->Count(); )
+            {
+                pNxt = (SwFrm*)(*pUpperFrms)[n++];
+                if( bFirst && pNxt && pNxt->IsSctFrm() )
+                    ((SwSectionFrm*)pNxt)->UnlockJoin();
+                pUp = (SwLayoutFrm*)(*pUpperFrms)[n++];
+                if( pNxt )
+                    pNxt = pNxt->GetNext();
+                else
+                    pNxt = pUp->Lower();
+                pNew = ((SwCntntNode*)pNd)->MakeFrm();
+                pNew->Paste( pUp, pNxt );
+                (*pUpperFrms)[n-2] = pNew;
+            }
+        else if( pNd->IsTableNode() )
+            for( USHORT x = 0; x < pUpperFrms->Count(); )
+            {
+                pNxt = (SwFrm*)(*pUpperFrms)[x++];
+                if( bFirst && pNxt && pNxt->IsSctFrm() )
+                    ((SwSectionFrm*)pNxt)->UnlockJoin();
+                pUp = (SwLayoutFrm*)(*pUpperFrms)[x++];
+                if( pNxt )
+                    pNxt = pNxt->GetNext();
+                else
+                    pNxt = pUp->Lower();
+                pNew = ((SwTableNode*)pNd)->MakeFrm();
+                ASSERT( pNew->IsTabFrm(), "Table exspected" );
+                pNew->Paste( pUp, pNxt );
+                ((SwTabFrm*)pNew)->RegistFlys();
+                (*pUpperFrms)[x-2] = pNew;
+            }
+        else if( pNd->IsSectionNode() )
+        {
+            nStt = pNd->EndOfSectionIndex();
+            for( USHORT x = 0; x < pUpperFrms->Count(); )
+            {
+                pNxt = (SwFrm*)(*pUpperFrms)[x++];
+                if( bFirst && pNxt && pNxt->IsSctFrm() )
+                    ((SwSectionFrm*)pNxt)->UnlockJoin();
+                pUp = (SwLayoutFrm*)(*pUpperFrms)[x++];
+                ASSERT( pUp->GetUpper() || pUp->IsFlyFrm(), "Lost Upper" );
+                ::_InsertCnt( pUp, pDoc, pNd->GetIndex(), FALSE, nStt+1, pNxt );
+                pNxt = pUp->Lower();
+                if( pNxt )
+                    while( pNxt->GetNext() )
+                        pNxt = pNxt->GetNext();
+                (*pUpperFrms)[x-2] = pNxt;
+            }
+        }
+        bFirst = FALSE;
+    }
+    for( USHORT x = 0; x < pUpperFrms->Count(); ++x )
+    {
+        SwFrm* pTmp = (SwFrm*)(*pUpperFrms)[++x];
+        if( pTmp->IsFtnFrm() )
+            ((SwFtnFrm*)pTmp)->ColUnlock();
+        else if( pTmp->IsInSct() )
+            pTmp->FindSctFrm()->ColUnlock();
+    }
+}
+
+SwFrm* SwNode2LayImpl::GetFrm( const Point* pDocPos,
+                                const SwPosition *pPos,
+                                const BOOL bCalcFrm ) const
+{
+    return pIter ? ::GetFrmOfModify( pIter->GetModify(), USHRT_MAX,
+                                        pDocPos, pPos, bCalcFrm )
+                 : 0;
+}
+
+SwNode2Layout::SwNode2Layout( const SwNode& rNd, ULONG nIdx )
+{
+    pImpl = new SwNode2LayImpl( rNd, nIdx, FALSE );
+}
+
+SwNode2Layout::SwNode2Layout( const SwNode& rNd )
+{
+    pImpl = new SwNode2LayImpl( rNd, rNd.GetIndex(), TRUE );
+    pImpl->SaveUpperFrms();
+}
+
+void SwNode2Layout::RestoreUpperFrms( SwNodes& rNds, ULONG nStt, ULONG nEnd )
+{
+    ASSERT( pImpl, "RestoreUpperFrms without SaveUpperFrms" );
+    pImpl->RestoreUpperFrms( rNds, nStt, nEnd );
+}
+
+SwFrm* SwNode2Layout::NextFrm()
+{
+    return pImpl->NextFrm();
+}
+
+SwLayoutFrm* SwNode2Layout::UpperFrm( SwFrm* &rpFrm, const SwNode &rNode )
+{
+    return pImpl->UpperFrm( rpFrm, rNode );
+}
+
+SwNode2Layout::~SwNode2Layout()
+{
+    delete pImpl;
+}
+
+SwFrm* SwNode2Layout::GetFrm( const Point* pDocPos,
+                                const SwPosition *pPos,
+                                const BOOL bCalcFrm ) const
+{
+    return pImpl->GetFrm( pDocPos, pPos, bCalcFrm );
+}
+
+
diff --git a/sw/source/core/docnode/nodes.cxx b/sw/source/core/docnode/nodes.cxx
new file mode 100644
index 000000000000..dc5147530b9e
--- /dev/null
+++ b/sw/source/core/docnode/nodes.cxx
@@ -0,0 +1,2604 @@
+/*************************************************************************
+ *
+ *  $RCSfile: nodes.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:18 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include 
+
+#ifndef _NODE_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _TXTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _HINTS_HXX
+#include 
+#endif
+#ifndef _NUMRULE_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _NDNOTXT_HXX
+#include 
+#endif
+#ifndef _SWTABLE_HXX
+#include       // fuer erzuegen / loeschen der Table-Frames
+#endif
+#ifndef _TBLSEL_HXX
+#include 
+#endif
+#ifndef _SECTION_HXX
+#include 
+#endif
+#ifndef _DDEFLD_HXX
+#include 
+#endif
+#ifndef _SWDDETBL_HXX
+#include 
+#endif
+#ifndef _FRAME_HXX
+#include 
+#endif
+
+extern FASTBOOL CheckNodesRange( const SwNodeIndex& rStt,
+                            const SwNodeIndex& rEnd, FASTBOOL bChkSection );
+
+SV_DECL_PTRARR(SwSttNdPtrs,SwStartNode*,2,2);
+
+
+//#define JP_DEBUG
+#ifdef JP_DEBUG
+#include "shellio.hxx"
+#endif
+
+
+// Funktion zum bestimmen des hoechsten Levels innerhalb des Bereiches
+
+USHORT HighestLevel( SwNodes & rNodes, const SwNodeRange & rRange );
+
+//-----------------------------------------------------------------------
+
+/*******************************************************************
+|*  SwNodes::SwNodes
+|*
+|*  Beschreibung
+|*      Konstruktor; legt die vier Grundsektions (PostIts,
+|*      Inserts, Icons, Inhalt) an
+*******************************************************************/
+SwNodes::SwNodes( SwDoc* pDocument )
+    : pMyDoc( pDocument ), pRoot( 0 )
+{
+    bInNodesDel = bInDelUpdOutl = bInDelUpdNum = FALSE;
+
+    ASSERT( pMyDoc, "in welchem Doc stehe ich denn?" );
+
+    ULONG nPos = 0;
+    SwStartNode* pSttNd = new SwStartNode( *this, nPos++ );
+    pEndOfPostIts = new SwEndNode( *this, nPos++, *pSttNd );
+
+    SwStartNode* pTmp = new SwStartNode( *this, nPos++ );
+    pEndOfInserts = new SwEndNode( *this, nPos++, *pTmp );
+
+    pTmp = new SwStartNode( *this, nPos++ );
+    pTmp->pStartOfSection = pSttNd;
+    pEndOfAutotext = new SwEndNode( *this, nPos++, *pTmp );
+
+    pTmp = new SwStartNode( *this, nPos++ );
+    pTmp->pStartOfSection = pSttNd;
+    pEndOfRedlines = new SwEndNode( *this, nPos++, *pTmp );
+
+    pTmp = new SwStartNode( *this, nPos++ );
+    pTmp->pStartOfSection = pSttNd;
+    pEndOfContent = new SwEndNode( *this, nPos++, *pTmp );
+
+    pOutlineNds = new SwOutlineNodes;
+}
+
+/*******************************************************************
+|*
+|*  SwNodes::~SwNodes
+|*
+|*  Beschreibung
+|*      dtor, loescht alle Nodes, deren Pointer in diesem dynamischen
+|*      Array sind. Ist kein Problem, da Nodes ausserhalb dieses
+|*      Arrays nicht erzeugt werden koennen und somit auch nicht
+|*      in mehreren drin sein koennen
+|*
+|*  Ersterstellung
+|*      VER0100 vb 901214
+|*
+|*  Stand
+|*      VER0100 vb 901214
+|*
+*******************************************************************/
+
+SwNodes::~SwNodes()
+{
+    delete pOutlineNds;
+
+    {
+        SwNode *pNode;
+        SwNodeIndex aNdIdx( *this );
+        while( TRUE )
+        {
+            pNode = &aNdIdx.GetNode();
+            if( pNode == pEndOfContent )
+                break;
+
+            aNdIdx++;
+            delete pNode;
+        }
+    }
+
+    // jetzt muessen alle SwNodeIndizies abgemeldet sein!!!
+    delete pEndOfContent;
+}
+
+
+// Sortier-Funktion fuer das Resort der OutlineNodes-Indizies. Wenn innerhalb
+// des Nodes-Arrays Elemente verschoben werden, dann muessen die Indizies
+// im Outline-Array wieder in die richtige Reihenfolge sortiert werden.
+
+int
+#if defined( WNT )
+ __cdecl
+#endif
+#if defined( ICC )
+ _Optlink
+#endif
+    lcl_nodes_CmpFuncIdx( const void* pLower, const void* pUpper )
+{
+    int nRet;
+    if( *(SwNode**)pLower == *(SwNode**)pUpper )
+        nRet = 0;
+    else if( (*(SwNode**)pLower)->GetIndex() < (*(SwNode**)pUpper)->GetIndex() )
+        nRet = -1;
+    else
+        nRet = 1;
+    return nRet;
+}
+
+
+void SwNodes::ChgNode( SwNodeIndex& rDelPos, ULONG nSize,
+                        SwNodeIndex& rInsPos, BOOL bNewFrms )
+{
+    // im UndoBereich brauchen wir keine Frames
+    SwNodes& rNds = rInsPos.GetNodes();
+    const SwNode* pPrevInsNd = rNds[ rInsPos.GetIndex() -1 ];
+
+    //JP 03.02.99: alle Felder als invalide erklaeren, aktu. erfolgt im
+    //              Idle-Handler des Docs
+    if( GetDoc()->SetFieldsDirty( TRUE, &rDelPos.GetNode(), nSize ) &&
+        rNds.GetDoc() != GetDoc() )
+        rNds.GetDoc()->SetFieldsDirty( TRUE );
+
+    //JP 12.03.99: 63293 - Nodes vom RedlineBereich NIE aufnehmen
+    ULONG nNd = rInsPos.GetIndex();
+    BOOL bInsOutlineIdx = !(
+            rNds.GetEndOfRedlines().FindStartNode()->GetIndex() < nNd &&
+            nNd < rNds.GetEndOfRedlines().GetIndex() );
+
+    if( &rNds == this )         // im gleichen Nodes-Array -> moven !!
+    {
+        // wird von vorne nach hinten gemovt, so wird nach vorne immer
+        // nachgeschoben, d.H. die Loeschposition ist immer gleich
+        USHORT nDiff = rDelPos.GetIndex() < rInsPos.GetIndex() ? 0 : 1;
+        int bOutlineNds = FALSE;
+
+        for( ULONG n = rDelPos.GetIndex(); nSize; n += nDiff, --nSize )
+        {
+            SwNodeIndex aDelIdx( *this, n );
+            SwNode& rNd = aDelIdx.GetNode();
+            if( rNd.IsTxtNode() && NO_NUMBERING !=
+                ((SwTxtNode&)rNd).GetTxtColl()->GetOutlineLevel() )
+            {
+                const SwNodePtr pSrch = (SwNodePtr)&rNd;
+                pOutlineNds->Remove( pSrch );
+            }
+
+            BigPtrArray::Move( aDelIdx.GetIndex(), rInsPos.GetIndex() );
+
+            if( rNd.IsTxtNode() )
+            {
+                SwTxtNode& rTxtNd = (SwTxtNode&)rNd;
+                if( bInsOutlineIdx && NO_NUMBERING !=
+                    rTxtNd.GetTxtColl()->GetOutlineLevel() )
+                {
+                    const SwNodePtr pSrch = (SwNodePtr)&rNd;
+                    pOutlineNds->Insert( pSrch );
+                }
+                rTxtNd.InvalidateNumRule();
+
+//FEATURE::CONDCOLL
+                if( RES_CONDTXTFMTCOLL == rTxtNd.GetTxtColl()->Which() )
+                    rTxtNd.ChkCondColl();
+//FEATURE::CONDCOLL
+            }
+            else if( rNd.IsCntntNode() )
+                ((SwCntntNode&)rNd).InvalidateNumRule();
+        }
+    }
+    else
+    {
+        int bSavePersData = GetDoc()->GetUndoNds() == &rNds;
+        int bRestPersData = GetDoc()->GetUndoNds() == this;
+        SwDoc* pDestDoc = rNds.GetDoc() != GetDoc() ? rNds.GetDoc() : 0;
+        if( !bRestPersData && !bSavePersData && pDestDoc )
+            bSavePersData = bRestPersData = TRUE;
+
+        String sNumRule;
+        SwNodeIndex aInsPos( rInsPos );
+        for( ULONG n = 0; n < nSize; n++ )
+        {
+            SwNode* pNd = &rDelPos.GetNode();
+
+            // NoTextNode muessen ihre Persitenten Daten mitnehmen
+            if( pNd->IsNoTxtNode() )
+            {
+                if( bSavePersData )
+                    ((SwNoTxtNode*)pNd)->SavePersistentData();
+            }
+            else if( pNd->IsTxtNode() )
+            {
+                SwTxtNode* pTxtNd = (SwTxtNode*)pNd;
+                // loesche die Gliederungs-Indizies aus dem alten Nodes-Array
+                if( NO_NUMBERING != pTxtNd->GetTxtColl()->GetOutlineLevel() )
+                    pOutlineNds->Remove( pNd );
+
+                // muss die Rule kopiere werden?
+                if( pDestDoc )
+                {
+                    const SwNumRule* pNumRule = pTxtNd->GetNumRule();
+                    if( pNumRule && sNumRule != pNumRule->GetName() )
+                    {
+                        sNumRule = pNumRule->GetName();
+                        SwNumRule* pDestRule = pDestDoc->FindNumRulePtr( sNumRule );
+                        if( pDestRule )
+                            pDestRule->SetInvalidRule( TRUE );
+                        else
+                            pDestDoc->MakeNumRule( sNumRule, pNumRule );
+                    }
+                }
+                else
+                    // wenns ins UndoNodes-Array gemoved wird, sollten die
+                    // Numerierungen auch aktualisiert werden.
+                    pTxtNd->InvalidateNumRule();
+            }
+
+            RemoveNode( rDelPos.GetIndex(), 1, FALSE );     // Indizies verschieben !!
+            SwCntntNode * pCNd = pNd->GetCntntNode();
+            rNds.Insert( pNd, aInsPos );
+
+            if( pCNd )
+            {
+                SwTxtNode* pTxtNd = pCNd->GetTxtNode();
+                if( pTxtNd )
+                {
+                    const SwpHints* pHts = pTxtNd->GetpSwpHints();
+                    // setze die OultineNodes im neuen Nodes-Array
+                    if( bInsOutlineIdx && NO_NUMBERING !=
+                        pTxtNd->GetTxtColl()->GetOutlineLevel() )
+                        rNds.pOutlineNds->Insert( pTxtNd );
+
+                    // Sonderbehandlung fuer die Felder!
+                    if( pHts && pHts->Count() )
+                    {
+                        SwTxtFld* pTxtFld;
+                        int bToUndo = &pDestDoc->GetNodes() != &rNds;
+                        for( USHORT i = pHts->Count(); i; )
+                            if( RES_TXTATR_FIELD == ( pTxtFld =
+                                    (SwTxtFld*)(*pHts)[ --i ])->Which() )
+                            {
+                                rNds.GetDoc()->InsDelFldInFldLst( !bToUndo,
+                                                            *pTxtFld );
+                                const SwFieldType* pTyp = pTxtFld->GetFld().
+                                                        GetFld()->GetTyp();
+                                if( RES_DDEFLD == pTyp->Which() )
+                                {
+                                    if( bToUndo )
+                                        ((SwDDEFieldType*)pTyp)->DecRefCnt();
+                                    else
+                                        ((SwDDEFieldType*)pTyp)->IncRefCnt();
+                                }
+                            }
+                    }
+//FEATURE::CONDCOLL
+                    if( RES_CONDTXTFMTCOLL == pTxtNd->GetTxtColl()->Which() )
+                        pTxtNd->ChkCondColl();
+//FEATURE::CONDCOLL
+                }
+                else
+                {
+                    // in unterschiedliche Docs gemoved ?
+                    // dann die Daten wieder persistent machen
+                    if( pCNd->IsNoTxtNode() && bRestPersData )
+                        ((SwNoTxtNode*)pCNd)->RestorePersistentData();
+                }
+            }
+        }
+    }
+
+    //JP 03.02.99: alle Felder als invalide erklaeren, aktu. erfolgt im
+    //              Idle-Handler des Docs
+    GetDoc()->SetFieldsDirty( TRUE );
+    if( rNds.GetDoc() != GetDoc() )
+        rNds.GetDoc()->SetFieldsDirty( TRUE );
+
+
+    if( bNewFrms )
+        bNewFrms = &GetDoc()->GetNodes() == (const SwNodes*)&rNds &&
+                    GetDoc()->GetRootFrm();
+    if( bNewFrms )
+    {
+        // Frames besorgen:
+        SwNodeIndex aIdx( *pPrevInsNd, 1 );
+        SwNodeIndex aFrmNdIdx( aIdx );
+        SwNode* pFrmNd = rNds.FindPrvNxtFrmNode( aFrmNdIdx,
+                                        rNds[ rInsPos.GetIndex() - 1 ] );
+
+        if( !pFrmNd && aFrmNdIdx > rNds.GetEndOfExtras().GetIndex() )
+        {
+            ASSERT( !this, "ob das so richtig ist ??" );
+            aFrmNdIdx = rNds.GetEndOfContent();
+            pFrmNd = rNds.GoPrevSection( &aFrmNdIdx, TRUE, FALSE );
+            if( pFrmNd && !((SwCntntNode*)pFrmNd)->GetDepends() )
+                pFrmNd = 0;
+
+#ifndef PRODUCT
+            if( !pFrmNd )
+                ASSERT( !this, "ChgNode() - kein FrameNode gefunden" );
+#endif
+        }
+        if( pFrmNd )
+            while( aIdx != rInsPos )
+            {
+                SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
+                if( pCNd )
+                {
+                    if( pFrmNd->IsTableNode() )
+                        ((SwTableNode*)pFrmNd)->MakeFrms( aIdx );
+                    else if( pFrmNd->IsSectionNode() )
+                        ((SwSectionNode*)pFrmNd)->MakeFrms( aIdx );
+                    else
+                        ((SwCntntNode*)pFrmNd)->MakeFrms( *pCNd );
+                    pFrmNd = pCNd;
+                }
+                aIdx++;
+            }
+    }
+}
+
+
+/***********************************************************************
+|*
+|*  SwNodes::Move
+|*
+|*  Beschreibung
+|*  Move loescht die Node-Pointer ab und einschliesslich der Startposition
+|*  bis zu und ausschliesslich der Endposition und fuegt sie an
+|*  der vor der Zielposition ein.
+|*  Wenn das Ziel vor dem ersten oder dem letzten zu bewegenden Element oder
+|*  dazwischen liegt, geschieht nichts.
+|*  Wenn der zu bewegende Bereich leer ist oder das Ende vor
+|*  dem Anfang liegt, geschieht nichts.
+|*
+|*  Allg.: aRange beschreibt den Bereich  -exklusive- aEnd !!
+|*              ( 1.Node: aStart, letzer Node: aEnd-1 !! )
+|*
+|*
+|*
+***********************************************************************/
+
+BOOL SwNodes::_MoveNodes( const SwNodeRange& aRange, SwNodes & rNodes,
+                    const SwNodeIndex& aIndex, BOOL bNewFrms )
+{
+    SwNode * pAktNode;
+    if( aIndex == 0 ||
+        ( (pAktNode = &aIndex.GetNode())->GetStartNode() &&
+          !pAktNode->StartOfSectionIndex() ))
+        return FALSE;
+
+    SwNodeRange aRg( aRange );
+
+    // "einfache" StartNodes oder EndNodes ueberspringen
+    while( ND_STARTNODE == (pAktNode = &aRg.aStart.GetNode())->GetNodeType()
+            || ( pAktNode->IsEndNode() &&
+                !pAktNode->pStartOfSection->IsSectionNode() ) )
+        aRg.aStart++;
+    aRg.aStart--;
+
+    // falls aEnd-1 auf keinem ContentNode steht, dann suche den vorherigen
+    aRg.aEnd--;
+    while( (( pAktNode = &aRg.aEnd.GetNode())->GetStartNode() &&
+            !pAktNode->IsSectionNode() ) ||
+            ( pAktNode->IsEndNode() &&
+            ND_STARTNODE == pAktNode->pStartOfSection->GetNodeType()) )
+        aRg.aEnd--;
+
+
+    // wird im selben Array's verschoben, dann ueberpruefe die Einfuegepos.
+    if( aRg.aStart >= aRg.aEnd )
+        return FALSE;
+
+    if( this == &rNodes )
+    {
+        if( ( aIndex.GetIndex()-1 >= aRg.aStart.GetIndex() &&
+              aIndex.GetIndex()-1 < aRg.aEnd.GetIndex()) ||
+            ( aIndex.GetIndex()-1 == aRg.aEnd.GetIndex() ) )
+            return FALSE;
+    }
+
+    USHORT nLevel = 0;                  // Level-Counter
+    ULONG nInsPos = 0;                  // Cnt fuer das TmpArray
+
+    // das Array bildet einen Stack, es werden alle StartOfSelction's gesichert
+    SwSttNdPtrs aSttNdStack( 1, 5 );
+
+    // setze den Start-Index
+    SwNodeIndex  aIdx( aIndex );
+/*
+    --- JP 17.11.94: sollte ueberholt sein, wird im ChgNode schon erledigt!
+    BOOL bCorrNum = pSect && pSect->aStart.GetIndex() == aIdx.GetIndex();
+*/
+
+    SwStartNode* pStartNode = aIdx.GetNode().pStartOfSection;
+    aSttNdStack.C40_INSERT( SwStartNode, pStartNode, 0 );
+//  aSttNdStack.Insert( rNodes[ aIdx ]->pStartOfSection, 0 );
+    SwNodeRange aOrigInsPos( aIdx, -1, aIdx );      // Originale Insert Pos
+
+    //JP 16.01.98: SectionNodes: DelFrms/MakeFrms beim obersten SectionNode!
+    USHORT nSectNdCnt = 0;
+    BOOL bSaveNewFrms = bNewFrms;
+
+    // bis alles verschoben ist
+    while( aRg.aStart < aRg.aEnd )
+        switch( (pAktNode = &aRg.aEnd.GetNode())->GetNodeType() )
+        {
+        case ND_ENDNODE:
+            {
+                if( nInsPos )       // verschieb schon mal alle bis hier her
+                {
+                    // loeschen und kopieren. ACHTUNG: die Indizies ab
+                    // "aRg.aEnd+1" werden mit verschoben !!
+                    SwNodeIndex aSwIndex( aRg.aEnd, 1 );
+                    ChgNode( aSwIndex, nInsPos, aIdx, bNewFrms );
+                    aIdx -= nInsPos;
+                    nInsPos = 0;
+                }
+
+                SwStartNode* pSttNd = pAktNode->pStartOfSection;
+                if( pSttNd->IsTableNode() )
+                {
+                    SwTableNode* pTblNd = (SwTableNode*)pSttNd;
+
+                    // dann bewege die gesamte Tabelle/den Bereich !!
+                    nInsPos = (aRg.aEnd.GetIndex() -
+                                    pSttNd->GetIndex() )+1;
+                    aRg.aEnd -= nInsPos;
+
+                    //JP 12.03.99: 63293 - Nodes vom RedlineBereich NIE aufnehmen
+                    ULONG nNd = aIdx.GetIndex();
+                    BOOL bInsOutlineIdx = !( rNodes.GetEndOfRedlines().
+                            FindStartNode()->GetIndex() < nNd &&
+                            nNd < rNodes.GetEndOfRedlines().GetIndex() );
+
+                    if( bNewFrms )
+                        // loesche erstmal die Frames
+                        pTblNd->DelFrms();
+                    if( &rNodes == this )   // in sich selbst moven ??
+                    {
+                        // dann bewege alle Start/End/ContentNodes. Loesche
+                        // bei den ContentNodes auch die Frames !!
+                        pTblNd->pStartOfSection = aIdx.GetNode().pStartOfSection;
+                        for( USHORT n = 0; n < nInsPos; ++n )
+                        {
+                            SwNodeIndex aMvIdx( aRg.aEnd, 1 );
+                            SwCntntNode* pCNd = 0;
+                            SwNode* pTmpNd = &aMvIdx.GetNode();
+                            if( pTmpNd->IsCntntNode() )
+                            {
+                                pCNd = (SwCntntNode*)pTmpNd;
+//                              if( bNewFrms )
+//                                  pCNd->DelFrms();
+
+                                // setze bei Start/EndNodes die richtigen Indizies
+                                // loesche die Gliederungs-Indizies aus
+                                // dem alten Nodes-Array
+                                if( pCNd->IsTxtNode() && NO_NUMBERING !=
+                                    ((SwTxtNode*)pCNd)->GetTxtColl()->GetOutlineLevel() )
+                                    pOutlineNds->Remove( pCNd );
+                                else
+                                    pCNd = 0;
+                            }
+//                          else if( bNewFrms && pTmpNd->IsSectionNode() )
+//                              ((SwSectionNode*)pTmpNd)->DelFrms();
+                            BigPtrArray::Move( aMvIdx.GetIndex(), aIdx.GetIndex() );
+
+                            if( bInsOutlineIdx && pCNd )
+                                pOutlineNds->Insert( pCNd );
+                        }
+                    }
+                    else
+                    {
+                        // StartNode holen
+                        SwStartNode* pSttNode = aIdx.GetNode().GetStartNode();
+                        if( !pSttNode )
+                            pSttNode = aIdx.GetNode().pStartOfSection;
+
+                        // Hole alle Boxen mit Inhalt. Deren Indizies auf die
+                        // StartNodes muessen umgemeldet werden !!
+                        // (Array kopieren und alle gefunden wieder loeschen;
+                        //  erleichtert das suchen!!)
+                        SwNodeIndex aMvIdx( aRg.aEnd, 1 );
+                        for( USHORT n = 0; n < nInsPos; ++n )
+                        {
+                            SwNode* pNd = &aMvIdx.GetNode();
+/*                          if( bNewFrms )
+                            {
+                                if( pNd->IsCntntNode() )
+                                    ((SwCntntNode*)pNd)->DelFrms();
+                                else if( pNd->IsSectionNode() )
+                                    ((SwSectionNode*)pNd)->DelFrms();
+                            }
+*/
+                            BOOL bOutlNd = pNd->IsTxtNode() && NO_NUMBERING !=
+                                ((SwTxtNode*)pNd)->GetTxtColl()->GetOutlineLevel();
+                            // loesche die Gliederungs-Indizies aus
+                            // dem alten Nodes-Array
+                            if( bOutlNd )
+                                pOutlineNds->Remove( pNd );
+
+                            RemoveNode( aMvIdx.GetIndex(), 1, FALSE );
+                            pNd->pStartOfSection = pSttNode;
+                            rNodes.Insert( pNd, aIdx );
+
+                            // setze bei Start/EndNodes die richtigen Indizies
+                            if( bInsOutlineIdx && bOutlNd )
+                                // und setze sie im neuen Nodes-Array
+                                rNodes.pOutlineNds->Insert( pNd );
+                            else if( pNd->IsStartNode() )
+                                pSttNode = (SwStartNode*)pNd;
+                            else if( pNd->IsEndNode() )
+                            {
+                                pSttNode->pEndOfSection = (SwEndNode*)pNd;
+                                if( pSttNode->IsSectionNode() )
+                                    ((SwSectionNode*)pSttNode)->NodesArrChgd();
+                                pSttNode = pSttNode->pStartOfSection;
+                            }
+                        }
+
+                        if( pTblNd->GetTable().IsA( TYPE( SwDDETable ) ))
+                        {
+                            SwDDEFieldType* pTyp = ((SwDDETable&)pTblNd->
+                                                GetTable()).GetDDEFldType();
+                            if( pTyp )
+                            {
+                                if( rNodes.IsDocNodes() )
+                                    pTyp->IncRefCnt();
+                                else
+                                    pTyp->DecRefCnt();
+                            }
+                        }
+
+                        if( GetDoc()->GetUndoNds() == &rNodes )
+                        {
+                            SwFrmFmt* pTblFmt = pTblNd->GetTable().GetFrmFmt();
+                            SwPtrMsgPoolItem aMsgHint( RES_REMOVE_UNO_OBJECT,
+                                                        pTblFmt );
+                            pTblFmt->Modify( &aMsgHint, &aMsgHint );
+                        }
+                    }
+                    if( bNewFrms )
+                    {
+                        SwNodeIndex aTmp( aIdx );
+                        pTblNd->MakeFrms( &aTmp );
+                    }
+                    aIdx -= nInsPos;
+                    nInsPos = 0;
+                }
+                else if( pSttNd->GetIndex() < aRg.aStart.GetIndex() )
+                {
+                    // SectionNode: es wird nicht die gesamte Section
+                    //              verschoben, also bewege nur die
+                    //              ContentNodes
+                    // StartNode:   erzeuge an der Postion eine neue Section
+                    do {        // middle check loop
+                        if( !pSttNd->IsSectionNode() )
+                        {
+                            // Start und EndNode an der InsertPos erzeugen
+                            SwStartNode* pTmp = new SwStartNode( aIdx,
+                                                    ND_STARTNODE,
+/*?? welcher NodeTyp ??*/
+                                                    SwNormalStartNode );
+
+                            nLevel++;           // den Index auf StartNode auf den Stack
+                            aSttNdStack.C40_INSERT( SwStartNode, pTmp, nLevel );
+
+                            // noch den EndNode erzeugen
+                            new SwEndNode( aIdx, *pTmp );
+                        }
+                        else if( (const SwNodes*)&rNodes ==
+                                GetDoc()->GetUndoNds() )
+                        {
+                            // im UndoNodes-Array spendieren wir einen
+                            // Platzhalter
+                            new SwNode( aIdx, ND_SECTIONDUMMY );
+                        }
+                        else
+                            break;
+
+                        aRg.aEnd--;
+                        aIdx--;
+                    } while( FALSE );
+                }
+                else
+                {
+                    // Start und EndNode komplett verschieben
+// s. u. SwIndex aOldStt( pSttNd->theIndex );
+//JP 21.05.97: sollte der Start genau der Start des Bereiches sein, so muss
+//              der Node auf jedenfall noch besucht werden!
+                    if( &aRg.aStart.GetNode() == pSttNd )
+                        --aRg.aStart;
+
+                    SwSectionNode* pSctNd = pSttNd->GetSectionNode();
+                    if( bNewFrms && pSctNd )
+                        pSctNd->DelFrms();
+
+                    RemoveNode( aRg.aEnd.GetIndex(), 1, FALSE ); // EndNode loeschen
+                    ULONG nSttPos = pSttNd->GetIndex();
+
+                    // dieser StartNode wird spaeter wieder entfernt!
+                    SwStartNode* pTmpSttNd = new SwStartNode( *this, nSttPos+1 );
+                    pTmpSttNd->pStartOfSection = pSttNd->pStartOfSection;
+
+                    RemoveNode( nSttPos, 1, FALSE ); // SttNode loeschen
+
+                    pSttNd->pStartOfSection = aIdx.GetNode().pStartOfSection;
+                    rNodes.Insert( pSttNd, aIdx  );
+                    rNodes.Insert( pAktNode, aIdx );
+                    aIdx--;
+                    pSttNd->pEndOfSection = (SwEndNode*)pAktNode;
+
+                    aRg.aEnd--;
+
+                    nLevel++;           // den Index auf StartNode auf den Stack
+                    aSttNdStack.C40_INSERT( SwStartNode, pSttNd, nLevel );
+
+                    // SectionNode muss noch ein paar Indizies ummelden
+                    if( pSctNd )
+                    {
+                        pSctNd->NodesArrChgd();
+                        ++nSectNdCnt;
+                        bNewFrms = FALSE;
+                    }
+                }
+            }
+            break;
+
+
+
+        case ND_SECTIONNODE:
+            if( !nLevel &&
+                ( (const SwNodes*)&rNodes == GetDoc()->GetUndoNds() ) )
+            {
+                // dann muss an der akt. InsPos ein SectionDummyNode
+                // eingefuegt werden
+                if( nInsPos )       // verschieb schon mal alle bis hier her
+                {
+                    // loeschen und kopieren. ACHTUNG: die Indizies ab
+                    // "aRg.aEnd+1" werden mit verschoben !!
+                    SwNodeIndex aSwIndex( aRg.aEnd, 1 );
+                    ChgNode( aSwIndex, nInsPos, aIdx, bNewFrms );
+                    aIdx -= nInsPos;
+                    nInsPos = 0;
+                }
+                new SwNode( aIdx, ND_SECTIONDUMMY );
+                aRg.aEnd--;
+                aIdx--;
+                break;
+            }
+            // kein break !!
+        case ND_TABLENODE:
+        case ND_STARTNODE:
+            {
+                if( !nLevel )       // es wird eine Stufe runter gestuft
+                {
+                    // erzeuge die Runterstufung
+                    SwNodeIndex aTmpSIdx( aOrigInsPos.aStart, 1 );
+                    SwStartNode* pTmpStt = new SwStartNode( aTmpSIdx,
+                                ND_STARTNODE,
+                                ((SwStartNode*)pAktNode)->GetStartNodeType() );
+
+                    aTmpSIdx--;
+
+                    SwNodeIndex aTmpEIdx( aOrigInsPos.aEnd );
+                    new SwEndNode( aTmpEIdx, *pTmpStt );
+                    aTmpEIdx--;
+                    aTmpSIdx++;
+
+                    // setze die StartOfSection richtig
+                    aRg.aEnd++;
+                    {
+                        SwNodeIndex aCntIdx( aRg.aEnd );
+                        for( register USHORT n = 0; n < nInsPos; n++, aCntIdx++)
+                            aCntIdx.GetNode().pStartOfSection = pTmpStt;
+                    }
+
+                    // Setze auch bei allen runtergestuften den richtigen StartNode
+                    while( aTmpSIdx < aTmpEIdx )
+                        if( 0 != (( pAktNode = &aTmpEIdx.GetNode())->GetEndNode()) )
+                            aTmpEIdx = pAktNode->StartOfSectionIndex();
+                        else
+                        {
+                            pAktNode->pStartOfSection = pTmpStt;
+                            aTmpEIdx--;
+                        }
+
+                    aIdx--;                 // hinter den eingefuegten StartNode
+                    aRg.aEnd--;             // vor den StartNode
+                    // kopiere jetzt das Array. ACHTUNG: die Indizies ab
+                    // "aRg.aEnd+1" werden mit verschoben !!
+                    SwNodeIndex aSwIndex( aRg.aEnd, 1 );
+                    ChgNode( aSwIndex, nInsPos, aIdx, bNewFrms );
+                    aIdx -= nInsPos+1;
+                    nInsPos = 0;
+                }
+                else                // es wurden alle Nodes innerhalb eines
+                {                   // Start- und End-Nodes verschoben
+                    ASSERT( pAktNode == aSttNdStack[nLevel] ||
+                            ( pAktNode->IsStartNode() &&
+                                aSttNdStack[nLevel]->IsSectionNode()),
+                             "falscher StartNode" );
+
+                    SwNodeIndex aSwIndex( aRg.aEnd, 1 );
+                    ChgNode( aSwIndex, nInsPos, aIdx, bNewFrms );
+                    aIdx -= nInsPos+1;      // vor den eingefuegten StartNode
+                    nInsPos = 0;
+
+                    // loesche nur noch den Pointer aus dem Nodes-Array.
+//                  RemoveNode( aRg.aEnd.GetIndex(), 1, FALSE );
+                    RemoveNode( aRg.aEnd.GetIndex(), 1, TRUE );
+                    aRg.aEnd--;
+
+                    SwSectionNode* pSectNd = aSttNdStack[ nLevel ]->GetSectionNode();
+                    if( pSectNd && !--nSectNdCnt )
+                    {
+                        SwNodeIndex aTmp( *pSectNd );
+                        pSectNd->MakeFrms( &aTmp );
+                        bNewFrms = bSaveNewFrms;
+                    }
+                    aSttNdStack.Remove( nLevel );   // vom Stack loeschen
+                    nLevel--;
+                }
+
+                // loesche alle entstehenden leeren Start-/End-Node-Paare
+                SwNode* pTmpNode = (*this)[ aRg.aEnd.GetIndex()+1 ]->GetEndNode();
+                if( pTmpNode && ND_STARTNODE == (pAktNode = &aRg.aEnd.GetNode())
+                    ->GetNodeType() && pAktNode->StartOfSectionIndex() &&
+                    pTmpNode->FindStartNode() == pAktNode )
+                {
+                    DelNodes( aRg.aEnd, 2 );
+                    aRg.aEnd--;
+                }
+//              aRg.aEnd--;
+            }
+            break;
+
+        case ND_TEXTNODE:
+        case ND_GRFNODE:
+        case ND_OLENODE:
+            {
+                if( bNewFrms && pAktNode->GetCntntNode() )
+                    ((SwCntntNode*)pAktNode)->DelFrms();
+
+                pAktNode->pStartOfSection = aSttNdStack[ nLevel ];
+                nInsPos++;
+                aRg.aEnd--;
+            }
+            break;
+
+        case ND_SECTIONDUMMY:
+            if( (const SwNodes*)this == GetDoc()->GetUndoNds() )
+            {
+                if( &rNodes == this )       // innerhalb vom UndoNodesArray
+                {
+                    // mit verschieben
+                    pAktNode->pStartOfSection = aSttNdStack[ nLevel ];
+                    nInsPos++;
+                }
+                else    // in ein "normales" Nodes-Array verschieben
+                {
+                    // dann muss an der akt. InsPos auch ein SectionNode
+                    // (Start/Ende) stehen; dann diesen ueberspringen.
+                    // Andernfalls nicht weiter beachten.
+                    if( nInsPos )       // verschieb schon mal alle bis hier her
+                    {
+                        // loeschen und kopieren. ACHTUNG: die Indizies ab
+                        // "aRg.aEnd+1" werden mit verschoben !!
+                        SwNodeIndex aSwIndex( aRg.aEnd, 1 );
+                        ChgNode( aSwIndex, nInsPos, aIdx, bNewFrms );
+                        aIdx -= nInsPos;
+                        nInsPos = 0;
+                    }
+                    SwNode* pTmpNd = &aIdx.GetNode();
+                    if( pTmpNd->IsSectionNode() ||
+                        pTmpNd->FindStartNode()->IsSectionNode() )
+                        aIdx--; // ueberspringen
+                }
+            }
+            else
+                ASSERT( FALSE, "wie kommt diser Node ins Nodes-Array??" );
+            aRg.aEnd--;
+            break;
+
+        default:
+            ASSERT( FALSE, "was ist das fuer ein Node??" );
+            break;
+        }
+
+    if( nInsPos )                           // kopiere den Rest
+    {
+        // der Rest muesste so stimmen
+        SwNodeIndex aSwIndex( aRg.aEnd, 1 );
+        ChgNode( aSwIndex, nInsPos, aIdx, bNewFrms );
+    }
+    aRg.aEnd++;                     // wieder exklusive Ende
+
+    // loesche alle leeren Start-/End-Node-Paare
+    if( ( pAktNode = &aRg.aStart.GetNode())->GetStartNode() &&
+        pAktNode->StartOfSectionIndex() &&
+        aRg.aEnd.GetNode().GetEndNode() )
+            DelNodes( aRg.aStart, 2 );
+
+    // rufe jetzt noch das Update fuer die Gliederung/Nummerierung auf
+    aOrigInsPos.aStart++;
+    // im gleichen Nodes-Array verschoben ??,
+    // dann von oben nach unten das Update aufrufen !!
+    if( this == &rNodes &&
+        aRg.aEnd.GetIndex() >= aOrigInsPos.aStart.GetIndex() )
+    {
+        UpdtOutlineIdx( aOrigInsPos.aStart.GetNode() );
+        UpdtOutlineIdx( aRg.aEnd.GetNode() );
+    }
+    else
+    {
+        UpdtOutlineIdx( aRg.aEnd.GetNode() );
+        rNodes.UpdtOutlineIdx( aOrigInsPos.aStart.GetNode() );
+    }
+
+#ifdef JP_DEBUG
+    {
+extern Writer* GetDebugWriter(const String&);
+
+        Writer* pWriter = GetDebugWriter(aEmptyStr);
+        if( pWriter )
+        {
+            int nError;
+            SvFileStream aStrm( "c:\\$$move.db", STREAM_WRITE );
+            SwWriter aWriter( aStrm, *pMyDoc );
+            aWriter.Write( &nError, pWriter );
+        }
+    }
+#endif
+
+    return TRUE;
+}
+
+
+/*******************************************************************
+|*
+|*  SwNodes::SectionDown
+|*
+|*  Beschreibung
+|*    SectionDown() legt ein Paar von Start- und EndSection-Node
+|*    (andere Nodes koennen dazwischen liegen) an.
+|*
+|*    Zustand des SRange beim Verlassen der Funktion: nStart ist der
+|*    Index des ersten Node hinter dem Start Section Node, nEnd ist
+|*    der Index des End Section Nodes. Beispiel: Wird Insert Section
+|*    mehrmals hintereinander aufgerufen, so werden mehrere
+|*    unmittelbar geschachtelte Sections (keine Content Nodes
+|*    zwischen Start- bzw. End Nodes) angelegt.
+|*
+|*  Allg.: aRange beschreibt den Bereich  -exklusive- aEnd !!
+|*              ( 1.Node: aStart, letzer Node: aEnd-1 !! )
+|*
+|*  Parameter
+|*      SwRange &rRange
+|*          IO:
+|*          IN
+|*          rRange.aStart: Einfuegeposition des StartNodes
+|*          rRange.aEnd: Einfuegeposition des EndNodes
+|*          OUT
+|*          rRange.aStart: steht hinter dem eingefuegten Startnode
+|*          rRange.aEnd: steht auf dem eingefuegen Endnode
+|*
+|*  Ausnahmen
+|*   1. SRange-Anfang und SRange-Ende muessen auf dem gleichen Level sein
+|*   2. duerfen nicht auf dem obersten Level sein
+|*      Ist dies nicht der Fall, wird die
+|*      Funktion durch Aufruf von ERR_RAISE verlassen.
+|*
+|*  Debug-Funktionen
+|*      die Debugging Tools geben rRange beim Eintritt und beim
+|*      Verlassen der Funktion aus
+|*
+|*  Ersterstellung
+|*      VER0100 vb 901214
+|*
+|*  Stand
+|*      VER0100 vb 901214
+|*
+*******************************************************************/
+void SwNodes::SectionDown(SwNodeRange *pRange, SwStartNodeType eSttNdTyp )
+{
+    if( pRange->aStart >= pRange->aEnd ||
+        pRange->aEnd >= Count() ||
+        !CheckNodesRange( pRange->aStart, pRange->aEnd ))
+        return;
+
+    // Ist der Anfang vom Bereich vor oder auf einem EndNode, so loesche
+    // diesen, denn sonst wuerden leere S/E-Nodes oder E/S-Nodes enstehen.
+    // Bei anderen Nodes wird eine neuer StartNode eingefuegt
+    SwNode * pAktNode = &pRange->aStart.GetNode();
+    SwNodeIndex aTmpIdx( *pAktNode->StartOfSectionNode() );
+
+    if( pAktNode->GetEndNode() )
+        DelNodes( pRange->aStart, 1 );      // verhinder leere Section
+    else
+    {
+        // fuege einen neuen StartNode ein
+        SwNode* pSttNd = new SwStartNode( pRange->aStart, ND_STARTNODE, eSttNdTyp );
+        pRange->aStart = *pSttNd;
+        aTmpIdx = pRange->aStart;
+    }
+
+    // Ist das Ende vom Bereich vor oder auf einem StartNode, so loesche
+    // diesen, denn sonst wuerden leere S/E-Nodes oder E/S-Nodes enstehen
+    // Bei anderen Nodes wird eine neuer EndNode eingefuegt
+    pRange->aEnd--;
+    if( pRange->aEnd.GetNode().GetStartNode() )
+        DelNodes( pRange->aEnd, 1 );
+    else
+    {
+        pRange->aEnd++;
+        // fuege einen neuen EndNode ein
+        new SwEndNode( pRange->aEnd, *pRange->aStart.GetNode().GetStartNode() );
+    }
+    pRange->aEnd--;
+
+    SectionUpDown( aTmpIdx, pRange->aEnd );
+}
+
+/*******************************************************************
+|*
+|*  SwNodes::SectionUp
+|*
+|*  Beschreibung
+|*      Der von rRange umspannte Bereich wird auf die naechst hoehere
+|*      Ebene gehoben. Das geschieht dadurch, dass bei
+|*      rRange.aStart ein Endnode und bei rRange.aEnd ein
+|*      Startnode eingefuegt wird. Die Indices fuer den Bereich
+|*      innerhalb von rRange werden geupdated.
+|*
+|*  Allg.: aRange beschreibt den Bereich  -exklusive- aEnd !!
+|*              ( 1.Node: aStart, letzer Node: aEnd-1 !! )
+|*
+|*  Parameter
+|*      SwRange &rRange
+|*          IO:
+|*          IN
+|*          rRange.aStart: Anfang des hoeher zubewegenden Bereiches
+|*          rRange.aEnd:   der 1.Node hinter dem Bereich
+|*          OUT
+|*          rRange.aStart:  an der ersten Position innerhalb des
+|*                          hochbewegten Bereiches
+|*          rRange.aEnd:    an der letzten Position innerhalb des
+|*                          hochbewegten Bereiches
+|*
+|*  Debug-Funktionen
+|*      die Debugging Tools geben rRange beim Eintritt und beim
+|*      Verlassen der Funktion aus
+|*
+|*  Ersterstellung
+|*      VER0100 vb 901214
+|*
+|*  Stand
+|*      VER0100 vb 901214
+|*
+*******************************************************************/
+void SwNodes::SectionUp(SwNodeRange *pRange)
+{
+    if( pRange->aStart >= pRange->aEnd ||
+        pRange->aEnd >= Count() ||
+        !CheckNodesRange( pRange->aStart, pRange->aEnd ) ||
+        !( HighestLevel( *this, *pRange ) > 1 ))
+        return;
+
+    // Ist der Anfang vom Bereich vor oder auf einem StartNode, so loesche
+    // diesen, denn sonst wuerden leere S/E-Nodes oder E/S-Nodes enstehen.
+    // Bei anderen Nodes wird eine neuer EndNode eingefuegt
+    SwNode * pAktNode = &pRange->aStart.GetNode();
+    SwNodeIndex aIdx( *pAktNode->StartOfSectionNode() );
+    if( pAktNode->IsStartNode() )       // selbst StartNode
+    {
+        SwEndNode* pEndNd = pRange->aEnd.GetNode().GetEndNode();
+        if( pAktNode == pEndNd->pStartOfSection )
+        {
+            // dann wurde paarig aufgehoben, also nur die im Berich neu anpassen
+            SwStartNode* pTmpSttNd = pAktNode->pStartOfSection;
+            RemoveNode( pRange->aStart.GetIndex(), 1, TRUE );
+            RemoveNode( pRange->aEnd.GetIndex(), 1, TRUE );
+
+            SwNodeIndex aTmpIdx( pRange->aStart );
+            while( aTmpIdx < pRange->aEnd )
+            {
+                pAktNode = &aTmpIdx.GetNode();
+                pAktNode->pStartOfSection = pTmpSttNd;
+                if( pAktNode->IsStartNode() )
+                    aTmpIdx = pAktNode->EndOfSectionIndex() + 1;
+                else
+                    aTmpIdx++;
+            }
+            return ;
+        }
+        DelNodes( pRange->aStart, 1 );
+    }
+    else if( aIdx == pRange->aStart.GetIndex()-1 )          // vor StartNode
+        DelNodes( aIdx, 1 );
+    else
+        new SwEndNode( pRange->aStart, *aIdx.GetNode().GetStartNode() );
+
+    // Ist das Ende vom Bereich vor oder auf einem StartNode, so loesche
+    // diesen, denn sonst wuerden leere S/E-Nodes oder E/S-Nodes entstehen
+    // Bei anderen Nodes wird eine neuer EndNode eingefuegt
+    SwNodeIndex aTmpIdx( pRange->aEnd );
+    if( pRange->aEnd.GetNode().IsEndNode() )
+        DelNodes( pRange->aEnd, 1 );
+    else
+    {
+        pAktNode = new SwStartNode( pRange->aEnd );
+/*?? welcher NodeTyp ??*/
+        aTmpIdx = *pRange->aEnd.GetNode().EndOfSectionNode();
+        pRange->aEnd--;
+    }
+
+    SectionUpDown( aIdx, aTmpIdx );
+}
+
+
+/*************************************************************************
+|*
+|*  SwNodes::SectionUpDown()
+|*
+|*  Beschreibung
+|*      Methode setzt die Indizies die bei SectionUp oder SectionDwon
+|*      veraendert wurden wieder richtig, sodass die Ebenen wieder
+|*      Konsistent sind.
+|*
+|*    Parameter
+|*                      SwIndex & aStart        StartNode !!!
+|*                      SwIndex & aEnd          EndPunkt
+|*
+|*    Ersterstellung    JP 23.04.91
+|*    Letzte Aenderung  JP 23.04.91
+|*
+*************************************************************************/
+void SwNodes::SectionUpDown( const SwNodeIndex & aStart, const SwNodeIndex & aEnd )
+{
+    SwNode * pAktNode;
+    SwNodeIndex aTmpIdx( aStart, +1 );
+    // das Array bildet einen Stack, es werden alle StartOfSelction's gesichert
+    SwSttNdPtrs aSttNdStack( 1, 5 );
+    SwStartNode* pTmp = aStart.GetNode().GetStartNode();
+    aSttNdStack.C40_INSERT( SwStartNode, pTmp, 0 );
+
+    // durchlaufe bis der erste zu aendernde Start-Node gefunden wurde
+    // ( Es wird vom eingefuegten EndNode bis nach vorne die Indexe gesetzt )
+    for( ;; aTmpIdx++ )
+    {
+        pAktNode = &aTmpIdx.GetNode();
+        pAktNode->pStartOfSection = aSttNdStack[ aSttNdStack.Count()-1 ];
+
+        if( pAktNode->GetStartNode() )
+        {
+            pTmp = (SwStartNode*)pAktNode;
+            aSttNdStack.C40_INSERT( SwStartNode, pTmp, aSttNdStack.Count() );
+        }
+        else if( pAktNode->GetEndNode() )
+        {
+            SwStartNode* pSttNd = aSttNdStack[ aSttNdStack.Count() - 1 ];
+            pSttNd->pEndOfSection = (SwEndNode*)pAktNode;
+            aSttNdStack.Remove( aSttNdStack.Count() - 1 );
+            if( aSttNdStack.Count() )
+                continue;       // noch genuegend EndNodes auf dem Stack
+
+            else if( aTmpIdx < aEnd )   // Uebergewicht an StartNodes
+                // ist das Ende noch nicht erreicht, so hole den Start von
+                // der uebergeordneten Section
+            {
+                aSttNdStack.C40_INSERT( SwStartNode, pSttNd->pStartOfSection, 0 );
+            }
+            else    // wenn ueber den Bereich hinaus, dann Ende
+                break;
+        }
+    }
+}
+
+
+
+
+/*******************************************************************
+|*
+|*  SwNodes::Delete
+|*
+|*  Beschreibung
+|*      Spezielle Implementierung der Delete-Funktion des
+|*      variablen Array. Diese spezielle Implementierung ist
+|*      notwendig, da durch das Loeschen von Start- bzw.
+|*      Endnodes Inkonsistenzen entstehen koennen. Diese werden
+|*      durch diese Funktion beseitigt.
+|*
+|*  Parameter
+|*      IN
+|*      SwIndex &rIndex bezeichnet die Position, an der
+|*      geloescht wird
+|*      rIndex ist nach Aufruf der Funktion unveraendert (Kopie?!)
+|*      USHORT nNodes bezeichnet die Anzahl der zu loeschenden
+|*      Nodes; ist auf 1 defaulted
+|*
+|*  Debug-Funktionen
+|*      geben beim Eintritt in die Funktion Position und Anzahl
+|*      der zu loeschenden Nodes aus.
+|*
+|*  Ersterstellung
+|*      VER0100 vb 901214
+|*
+|*  Stand
+|*      VER0100 vb 901214
+|*
+*******************************************************************/
+void SwNodes::Delete(const SwNodeIndex &rIndex, ULONG nNodes)
+{
+    USHORT nLevel = 0;                      // Level-Counter
+    SwNode * pAktNode;
+
+    ULONG nCnt = Count() - rIndex.GetIndex() - 1;
+    if( nCnt > nNodes ) nCnt = nNodes;
+
+    if( nCnt == 0 )         // keine Anzahl -> return
+        return;
+
+    SwNodeRange aRg( rIndex, 0, rIndex, nCnt-1 );
+    // ueberprufe ob rIndex..rIndex + nCnt ueber einen Bereich hinausragt !!
+    if( ( !aRg.aStart.GetNode().StartOfSectionIndex() &&
+            !aRg.aStart.GetIndex() ) ||
+            ! CheckNodesRange( aRg.aStart, aRg.aEnd ) )
+        return;
+
+
+    // falls aEnd auf keinem ContentNode steht, dann suche den vorherigen
+    while( ( pAktNode = &aRg.aEnd.GetNode())->GetStartNode() ||
+             ( pAktNode->GetEndNode() &&
+                !pAktNode->pStartOfSection->IsTableNode() ))
+        aRg.aEnd--;
+
+    nCnt = 0;
+    // Start erhoehen, damit auf < abgefragt wird. ( bei <= kann es zu
+    // Problemen fuehren; ist aEnd == aStart und wird aEnd geloscht,
+    // so ist aEnd <= aStart
+    aRg.aStart--;
+
+    BOOL bSaveInNodesDel = bInNodesDel;
+    bInNodesDel = TRUE;
+    BOOL bUpdateOutline = FALSE;
+
+    // bis alles geloescht ist
+    while( aRg.aStart < aRg.aEnd )
+    {
+        pAktNode = &aRg.aEnd.GetNode();
+
+        if( pAktNode->GetEndNode() )
+        {
+            // die gesamte Section loeschen ?
+            if( pAktNode->StartOfSectionIndex() > aRg.aStart.GetIndex() )
+            {
+                SwTableNode* pTblNd = pAktNode->pStartOfSection->GetTableNode();
+                if( pTblNd )
+                    pTblNd->DelFrms();
+
+                SwNode *pNd, *pChkNd = pAktNode->pStartOfSection;
+                USHORT nIdxPos;
+                do {
+                    pNd = &aRg.aEnd.GetNode();
+
+                    if( pNd->IsTxtNode() )
+                    {
+                        if( NO_NUMBERING !=
+                        ((SwTxtNode*)pNd)->GetTxtColl()->GetOutlineLevel() &&
+                        pOutlineNds->Seek_Entry( pNd, &nIdxPos ))
+                        {
+                            // loesche die Gliederungs-Indizies.
+                            pOutlineNds->Remove( nIdxPos );
+                            bUpdateOutline = TRUE;
+                        }
+                    }
+                    else if( pNd->IsEndNode() &&
+                            pNd->pStartOfSection->IsTableNode() )
+                        ((SwTableNode*)pNd->pStartOfSection)->DelFrms();
+
+                    aRg.aEnd--;
+                    nCnt++;
+
+                } while( pNd != pChkNd );
+            }
+            else
+            {
+                RemoveNode( aRg.aEnd.GetIndex()+1, nCnt, TRUE );    // loesche
+                nCnt = 0;
+                aRg.aEnd--;             // vor den EndNode
+                nLevel++;
+            }
+        }
+        else if( pAktNode->GetStartNode() )   // StartNode gefunden
+        {
+            if( nLevel == 0 )       // es wird eine Stufe runter gestuft
+            {
+                if( nCnt )
+                {
+                    // loesche jetzt das Array
+                    aRg.aEnd++;
+                    RemoveNode( aRg.aEnd.GetIndex(), nCnt, TRUE );
+                    nCnt = 0;
+                }
+            }
+            else    // es werden alle Nodes Innerhalb eines Start- und
+            {       // End-Nodes geloescht, loesche mit Start/EndNode
+                RemoveNode( aRg.aEnd.GetIndex(), nCnt + 2, TRUE );          // loesche Array
+                nCnt = 0;
+                nLevel--;
+            }
+
+            // nach dem loeschen kann aEnd auf einem EndNode stehen
+            // loesche alle leeren Start-/End-Node-Paare
+            SwNode* pTmpNode = aRg.aEnd.GetNode().GetEndNode();
+            aRg.aEnd--;
+            while(  pTmpNode &&
+                    ( pAktNode = &aRg.aEnd.GetNode())->GetStartNode() &&
+                    pAktNode->StartOfSectionIndex() )
+            {
+                // loesche den EndNode und StartNode
+                DelNodes( aRg.aEnd, 2 );
+                pTmpNode = aRg.aEnd.GetNode().GetEndNode();
+                aRg.aEnd--;
+            }
+        }
+        else        // normaler Node, also ins TmpArray einfuegen
+        {
+            SwTxtNode* pTxtNd = pAktNode->GetTxtNode();
+            if( pTxtNd )
+            {
+                if( NO_NUMBERING != pTxtNd->GetTxtColl()->GetOutlineLevel() )
+                {                   // loesche die Gliederungs-Indizies.
+                    pOutlineNds->Remove( pTxtNd );
+                    bUpdateOutline = TRUE;
+                }
+                pTxtNd->InvalidateNumRule();
+            }
+            else if( pAktNode->IsCntntNode() )
+                ((SwCntntNode*)pAktNode)->InvalidateNumRule();
+
+            aRg.aEnd--;
+            nCnt++;
+        }
+    }
+
+    aRg.aEnd++;
+    if( nCnt != 0 )
+        RemoveNode( aRg.aEnd.GetIndex(), nCnt, TRUE );              // loesche den Rest
+
+    // loesche alle leeren Start-/End-Node-Paare
+    while( aRg.aEnd.GetNode().GetEndNode() &&
+            ( pAktNode = &aRg.aStart.GetNode())->GetStartNode() &&
+            pAktNode->StartOfSectionIndex() )
+    // aber ja keinen der heiligen 5.
+    {
+        DelNodes( aRg.aStart, 2 );  // loesche den Start- und EndNode
+        aRg.aStart--;
+    }
+
+    bInNodesDel = bSaveInNodesDel;
+
+    if( !bInNodesDel )
+    {
+        // rufe jetzt noch das Update fuer die Gliederung/Nummerierung auf
+        if( bUpdateOutline || bInDelUpdOutl )
+        {
+            UpdtOutlineIdx( aRg.aEnd.GetNode() );
+            bInDelUpdOutl = FALSE;
+        }
+
+    }
+    else
+    {
+        if( bUpdateOutline )
+            bInDelUpdOutl = TRUE;
+    }
+}
+
+/*******************************************************************
+|*
+|*  SwNodes::GetSectionLevel
+|*
+|*  Beschreibung
+|*      Die Funktion liefert den Sectionlevel an der durch
+|*      aIndex bezeichneten Position. Die Funktion ruft die
+|*      GetSectionlevel-Funktion des durch aIndex bezeichneten
+|*      Nodes. Diese ist eine virtuelle Funktion, die fuer
+|*      Endnodes speziell implementiert werden musste.
+|*      Die Sectionlevels werden ermittelt, indem rekursiv durch
+|*      die Nodesstruktur (jeweils zum naechsten theEndOfSection)
+|*      gegangen wird, bis die oberste Ebene erreicht ist
+|*      (theEndOfSection == 0)
+|*
+|*  Parameter
+|*      aIndex bezeichnet die Position des Nodes, dessen
+|*      Sectionlevel ermittelt werden soll. Hier wird eine Kopie
+|*      uebergeben, da eine Veraenderung der Variablen in der
+|*      rufenden Funktion nicht wuenschenswert ist.
+|*
+|*  Ausnahmen
+|*      Der erste Node im Array  sollte immer ein Startnode sein.
+|*      Dieser erfaehrt in der Funktion SwNodes::GetSectionLevel()
+|*      eine Sonderbehandlung; es wird davon ausgegangen, dass der
+|*      erste Node auch ein Startnode ist.
+|*
+|*  Ersterstellung
+|*      VER0100 vb 901214
+|*
+|*  Stand
+|*      VER0100 vb 901214
+|*
+*******************************************************************/
+USHORT SwNodes::GetSectionLevel(const SwNodeIndex &rIdx) const {
+    // Sonderbehandlung 1. Node
+    if(rIdx == 0) return 1;
+    /*
+     * Keine Rekursion! - hier wird das SwNode::GetSectionLevel
+     * aufgerufen
+     */
+    return (*this)[rIdx]->GetSectionLevel();
+
+}
+
+void SwNodes::GoStartOfSection(SwNodeIndex *pIdx) const
+{
+    // hinter den naechsten Startnode
+    SwNodeIndex aTmp( *pIdx->GetNode().StartOfSectionNode(), +1 );
+
+    // steht der Index auf keinem ContentNode, dann gehe dahin. Ist aber
+    // kein weiterer vorhanden, dann lasse den Index an alter Pos stehen !!!
+    while( !aTmp.GetNode().IsCntntNode() )
+    {   // gehe vom StartNode ( es kann nur ein StartNode sein ! ) an sein
+        // Ende
+        if( *pIdx <= aTmp )
+            return;     // FEHLER: Steht schon hinter der Sektion
+        aTmp = aTmp.GetNode().EndOfSectionIndex()+1;
+        if( *pIdx <= aTmp )
+            return;     // FEHLER: Steht schon hinter der Sektion
+    }
+    (*pIdx) = aTmp;     // steht auf einem ContentNode
+}
+
+void SwNodes::GoEndOfSection(SwNodeIndex *pIdx) const
+{
+    // falls er vor einem Endnode steht --> nichts tun
+    if( !pIdx->GetNode().IsEndNode() )
+        (*pIdx) = *pIdx->GetNode().EndOfSectionNode();
+}
+
+SwCntntNode* SwNodes::GoNext(SwNodeIndex *pIdx) const
+{
+    if( pIdx->GetIndex() >= Count() - 1 )
+        return 0;
+
+    SwNodeIndex aTmp(*pIdx, +1);
+    SwNode* pNd;
+    while( aTmp < Count()-1 && 0 == ( pNd = &aTmp.GetNode())->IsCntntNode() )
+        aTmp++;
+
+    if( aTmp == Count()-1 )
+        pNd = 0;
+    else
+        (*pIdx) = aTmp;
+    return (SwCntntNode*)pNd;
+}
+
+SwCntntNode* SwNodes::GoPrevious(SwNodeIndex *pIdx) const
+{
+    if( !pIdx->GetIndex() )
+        return 0;
+
+    SwNodeIndex aTmp( *pIdx, -1 );
+    SwNode* pNd;
+    while( aTmp.GetIndex() && 0 == ( pNd = &aTmp.GetNode())->IsCntntNode() )
+        aTmp--;
+
+    if( !aTmp.GetIndex() )
+        pNd = 0;
+    else
+        (*pIdx) = aTmp;
+    return (SwCntntNode*)pNd;
+}
+
+SwNode* SwNodes::GoNextWithFrm(SwNodeIndex *pIdx) const
+{
+    if( pIdx->GetIndex() >= Count() - 1 )
+        return 0;
+
+    SwNodeIndex aTmp(*pIdx, +1);
+    SwNode* pNd;
+    while( aTmp < Count()-1 )
+    {
+        pNd = &aTmp.GetNode();
+        SwModify *pMod = 0;
+        if ( pNd->IsCntntNode() )
+            pMod = (SwCntntNode*)pNd;
+        else if ( pNd->IsTableNode() )
+            pMod = ((SwTableNode*)pNd)->GetTable().GetFrmFmt();
+        else if( pNd->IsEndNode() && !pNd->FindStartNode()->IsSectionNode() )
+        {
+            pNd = 0;
+            break;
+        }
+        if ( pMod && pMod->GetDepends() )
+        {
+            SwClientIter aIter( *pMod );
+            if( aIter.First( TYPE(SwFrm) ) )
+                break;
+        }
+        aTmp++;
+    }
+    if( aTmp == Count()-1 )
+        pNd = 0;
+    else if( pNd )
+        (*pIdx) = aTmp;
+    return pNd;
+}
+
+SwNode* SwNodes::GoPreviousWithFrm(SwNodeIndex *pIdx) const
+{
+    if( !pIdx->GetIndex() )
+        return 0;
+
+    SwNodeIndex aTmp( *pIdx, -1 );
+    SwNode* pNd;
+    while( aTmp.GetIndex() )
+    {
+        pNd = &aTmp.GetNode();
+        SwModify *pMod = 0;
+        if ( pNd->IsCntntNode() )
+            pMod = (SwCntntNode*)pNd;
+        else if ( pNd->IsTableNode() )
+            pMod = ((SwTableNode*)pNd)->GetTable().GetFrmFmt();
+        else if( pNd->IsStartNode() && !pNd->IsSectionNode() )
+        {
+            pNd = 0;
+            break;
+        }
+        if ( pMod && pMod->GetDepends() )
+        {
+            SwClientIter aIter( *pMod );
+            if( aIter.First( TYPE(SwFrm) ) )
+                break;
+        }
+        aTmp--;
+    }
+
+    if( !aTmp.GetIndex() )
+        pNd = 0;
+    else if( pNd )
+        (*pIdx) = aTmp;
+    return pNd;
+}
+
+
+
+/*************************************************************************
+|*
+|*    BOOL SwNodes::CheckNodesRange()
+|*
+|*    Beschreibung
+|*      Teste ob der uebergene SRange nicht ueber die Grenzen der
+|*      einzelnen Bereiche (PosIts, Autotext, Content, Icons und Inserts )
+|*      hinaus reicht.
+|*      Nach Wahrscheinlichkeit des Ranges sortiert.
+|*
+|*  Alg.: Da festgelegt ist, das aRange.aEnd den 1.Node hinter dem Bereich
+|*        bezeichnet, wird hier auf aEnd <= End.. getestet !!
+|*
+|*    Parameter         SwIndex &   Start-Index vom Bereich
+|*                      SwIndex &   End-Index vom Bereich
+|*                      BOOL        TRUE:   Start+End in gleicher Section!
+|*                                  FALSE:  Start+End in verschiedenen Sect.
+|*    Return-Wert       BOOL        TRUE:   gueltiger SRange
+|*                                  FALSE:  ungueltiger SRange
+|*
+|*    Ersterstellung    JP 23.04.91
+|*    Letzte Aenderung  JP 18.06.92
+|*
+*************************************************************************/
+
+inline int TstIdx( ULONG nSttIdx, ULONG nEndIdx, ULONG nStt, ULONG nEnd )
+{
+    return nStt < nSttIdx && nEnd >= nSttIdx &&
+            nStt < nEndIdx && nEnd >= nEndIdx;
+}
+
+BOOL SwNodes::CheckNodesRange( const SwNodeIndex& rStt, const SwNodeIndex& rEnd ) const
+{
+    ULONG nStt = rStt.GetIndex(), nEnd = rEnd.GetIndex();
+    if( TstIdx( nStt, nEnd, pEndOfContent->StartOfSectionIndex(),
+                pEndOfContent->GetIndex() )) return TRUE;
+    if( TstIdx( nStt, nEnd, pEndOfAutotext->StartOfSectionIndex(),
+                pEndOfAutotext->GetIndex() )) return TRUE;
+    if( TstIdx( nStt, nEnd, pEndOfPostIts->StartOfSectionIndex(),
+                pEndOfPostIts->GetIndex() )) return TRUE;
+    if( TstIdx( nStt, nEnd, pEndOfInserts->StartOfSectionIndex(),
+                pEndOfInserts->GetIndex() )) return TRUE;
+    if( TstIdx( nStt, nEnd, pEndOfRedlines->StartOfSectionIndex(),
+                pEndOfRedlines->GetIndex() )) return TRUE;
+
+    return FALSE;       // liegt irgendwo dazwischen, FEHLER
+}
+
+
+/*************************************************************************
+|*
+|*    void SwNodes::DelNodes()
+|*
+|*    Beschreibung
+|*      Loesche aus den NodesArray ab einer Position entsprechend Node's.
+|*
+|*    Parameter         SwIndex &   Der Startpunkt im Nodes-Array
+|*                      USHORT      die Anzahl
+|*
+|*    Ersterstellung    JP 23.04.91
+|*    Letzte Aenderung  JP 23.04.91
+|*
+*************************************************************************/
+void SwNodes::DelNodes( const SwNodeIndex & rStart, ULONG nCnt )
+{
+    int bUpdateNum = 0;
+    ULONG nSttIdx = rStart.GetIndex();
+
+    if( !nSttIdx && nCnt == GetEndOfContent().GetIndex()+1 )
+    {
+        // es wird das gesamte Nodes-Array zerstoert, man ist im Doc DTOR!
+        // Die initialen Start-/End-Nodes duerfen nur im SwNodes-DTOR
+        // zerstoert werden!
+        SwNode* aEndNdArr[] = { pEndOfContent,
+                                pEndOfPostIts, pEndOfInserts,
+                                pEndOfAutotext, pEndOfRedlines,
+                                0
+                              };
+
+        SwNode** ppEndNdArr = aEndNdArr;
+        while( *ppEndNdArr )
+        {
+            nSttIdx = (*ppEndNdArr)->StartOfSectionIndex() + 1;
+            ULONG nEndIdx = (*ppEndNdArr)->GetIndex();
+
+            if( nSttIdx != nEndIdx )
+                RemoveNode( nSttIdx, nEndIdx - nSttIdx, TRUE );
+
+            ++ppEndNdArr;
+        }
+    }
+    else
+    {
+        for( ULONG n = nSttIdx, nEnd = nSttIdx + nCnt; n < nEnd; ++n )
+        {
+            SwNode* pNd = (*this)[ n ];
+
+            if( pNd->IsTxtNode() &&
+                NO_NUMBERING != ((SwTxtNode*)pNd)->GetTxtColl()->GetOutlineLevel() )
+            {                   // loesche die Gliederungs-Indizies.
+                USHORT nIdxPos;
+                if( pOutlineNds->Seek_Entry( pNd, &nIdxPos ))
+                {
+                    pOutlineNds->Remove( nIdxPos );
+                    bUpdateNum = 1;
+                }
+            }
+            if( pNd->IsCntntNode() )
+                ((SwCntntNode*)pNd)->InvalidateNumRule();
+        }
+        RemoveNode( nSttIdx, nCnt, TRUE );
+
+        // rufe noch das Update fuer die Gliederungsnumerierung auf
+        if( bUpdateNum )
+            UpdtOutlineIdx( rStart.GetNode() );
+    }
+}
+
+
+/*************************************************************************
+|*
+|*    USHORT HighestLevel( SwNodes & rNodes, const SwNodeRange & rRange )
+|*
+|*    Beschreibung
+|*      Berechne den hoehsten Level innerhalb des Bereiches
+|*
+|*    Parameter         SwNodes &   das Node-Array
+|*                      SwNodeRange &   der zu ueberpruefende Bereich
+|*    Return            USHORT      der hoechste Level
+|*
+|*    Ersterstellung    JP 24.04.91
+|*    Letzte Aenderung  JP 24.04.91
+|*
+*************************************************************************/
+
+struct HighLevel
+{
+    USHORT nLevel, nTop;
+    HighLevel( USHORT nLv ) : nLevel( nLv ), nTop( nLv ) {}
+
+};
+
+BOOL _HighestLevel( const SwNodePtr& rpNode, void * pPara )
+{
+    HighLevel * pHL = (HighLevel*)pPara;
+    if( rpNode->GetStartNode() )
+        pHL->nLevel++;
+    else if( rpNode->GetEndNode() )
+        pHL->nLevel--;
+    if( pHL->nTop > pHL->nLevel )
+        pHL->nTop = pHL->nLevel;
+    return TRUE;
+
+}
+
+USHORT HighestLevel( SwNodes & rNodes, const SwNodeRange & rRange )
+{
+    HighLevel aPara( rNodes.GetSectionLevel( rRange.aStart ));
+    rNodes.ForEach( rRange.aStart, rRange.aEnd, _HighestLevel, &aPara );
+    return aPara.nTop;
+
+}
+
+/*************************************************************************
+|*
+|*    SwNodes::Move()
+|*
+|*    Beschreibung
+|*    Parameter         SwPaM&      zu kopierender Bereich
+|*                      SwNodes&    in dieses Nodes-Array
+|*                      SwPosition& auf diese Position im Nodes-Array
+|*    Ersterstellung    JP 09.07.92
+|*    Letzte Aenderung  JP 09.07.92
+|*
+*************************************************************************/
+void SwNodes::Move( SwPaM & rPam, SwPosition & rPos, SwNodes& rNodes,
+                    BOOL bSplitNd )
+{
+    SwPosition *pStt = (SwPosition*)rPam.Start(), *pEnd = (SwPosition*)rPam.End();
+
+    if( !rPam.HasMark() || *pStt >= *pEnd )
+        return;
+
+    if( this == &rNodes && *pStt <= rPos && rPos < *pEnd )
+        return;
+
+    SwNodeIndex aEndIdx( pEnd->nNode );
+    SwNodeIndex aSttIdx( pStt->nNode );
+    SwTxtNode* pSrcNd = (*this)[ aSttIdx ]->GetTxtNode();
+    SwTxtNode* pDestNd = rNodes[ rPos.nNode ]->GetTxtNode();
+    BOOL bSplitDestNd = TRUE;
+    BOOL bSttTxtNd = 0 != pSrcNd;
+    BOOL bCopyCollFmt = pDestNd && !pDestNd->GetTxt().Len();
+
+    if( pSrcNd )
+    {
+        // ist der 1.Node ein TextNode, dann muss im NodesArray auch
+        // ein TextNode vorhanden sein, in den der Inhalt geschoben wird
+        if( !pDestNd )
+        {
+            pDestNd = rNodes.MakeTxtNode( rPos.nNode, pSrcNd->GetTxtColl() );
+            rPos.nNode--;
+            rPos.nContent.Assign( pDestNd, 0 );
+            bCopyCollFmt = TRUE;
+        }
+/*!NOSPLIT      bSplitDestNd = !bSplitNd &&
+                        ( pDestNd->Len() > rPos.nContent.GetIndex() ||
+                        !aEndIdx.GetNode().IsTxtNode() );
+*/
+//      ASSERT( bSplitNd, "Move mit bSplitNode = FALSE" );
+        bSplitDestNd = pDestNd->Len() > rPos.nContent.GetIndex() ||
+                        pEnd->nNode.GetNode().IsTxtNode();
+
+        // verschiebe jetzt noch den Inhalt in den neuen Node
+        BOOL bOneNd = pStt->nNode == pEnd->nNode;
+        xub_StrLen nLen = ( bOneNd ? pEnd->nContent.GetIndex() : pSrcNd->Len() )
+                        - pStt->nContent.GetIndex();
+
+        if( !pEnd->nNode.GetNode().IsCntntNode() )
+        {
+            bOneNd = TRUE;
+            ULONG nSttNdIdx = pStt->nNode.GetIndex() + 1,
+                    nEndNdIdx = pEnd->nNode.GetIndex();
+            for( ; nSttNdIdx < nEndNdIdx; ++nSttNdIdx )
+                if( (*this)[ nSttNdIdx ]->IsCntntNode() )
+                {
+                    bOneNd = FALSE;
+                    break;
+                }
+        }
+
+        // das kopieren / setzen der Vorlagen darf erst nach
+        // dem Splitten erfolgen
+//!NOSPLIT      if( !bOneNd && ( bSplitNd || bSplitDestNd ))
+        if( !bOneNd && bSplitDestNd )
+        {
+            if( rNodes.IsDocNodes() )
+            {
+                SwDoc* pInsDoc = pDestNd->GetDoc();
+                BOOL bIsUndo = pInsDoc->DoesUndo();
+                pInsDoc->DoUndo( FALSE );
+                pInsDoc->SplitNode( rPos );
+                pInsDoc->DoUndo( bIsUndo );
+            }
+            else
+                pDestNd->SplitNode( rPos );
+
+            if( rPos.nNode == aEndIdx )
+                aEndIdx--;
+            bSplitDestNd = TRUE;
+
+            pDestNd = rNodes[ rPos.nNode.GetIndex() - 1 ]->GetTxtNode();
+            if( nLen )
+                pSrcNd->Cut( pDestNd, SwIndex( pDestNd, pDestNd->Len()),
+                            pStt->nContent, nLen );
+        }
+        else if( nLen )
+            pSrcNd->Cut( pDestNd, rPos.nContent, pStt->nContent, nLen );
+
+        if( bCopyCollFmt )
+        {
+            SwDoc* pInsDoc = pDestNd->GetDoc();
+            BOOL bIsUndo = pInsDoc->DoesUndo();
+            pInsDoc->DoUndo( FALSE );
+            pSrcNd->CopyCollFmt( *pDestNd );
+            pInsDoc->DoUndo( bIsUndo );
+        }
+
+        if( bOneNd )        // das wars schon
+        {
+            // der PaM wird korrigiert, denn falls ueber Nodegrenzen verschoben
+            // wurde, so stehen sie in unterschieden Nodes. Auch die Selektion
+            // wird aufgehoben !
+            pEnd->nContent = pStt->nContent;
+            rPam.DeleteMark();
+            return;
+        }
+
+        aSttIdx++;
+    }
+    else if( pDestNd )
+    {
+        if( rPos.nContent.GetIndex() )
+        {
+//!NOSPLIT          if( !bSplitNd && rPos.nContent.GetIndex() == pDestNd->Len() )
+            if( rPos.nContent.GetIndex() == pDestNd->Len() )
+                rPos.nNode++;
+            else if( rPos.nContent.GetIndex() )
+            {
+                // falls im EndNode gesplittet wird, dann muss der EndIdx
+                // korrigiert werden !!
+                BOOL bCorrEnde = aEndIdx == rPos.nNode;
+                // es wird kein Text an den TextNode angehaengt, also splitte ihn
+
+                if( rNodes.IsDocNodes() )
+                {
+                    SwDoc* pInsDoc = pDestNd->GetDoc();
+                    BOOL bIsUndo = pInsDoc->DoesUndo();
+                    pInsDoc->DoUndo( FALSE );
+                    pInsDoc->SplitNode( rPos );
+                    pInsDoc->DoUndo( bIsUndo );
+                }
+                else
+                    pDestNd->SplitNode( rPos );
+
+                pDestNd = rPos.nNode.GetNode().GetTxtNode();
+
+                if( bCorrEnde )
+                    aEndIdx--;
+            }
+        }
+        // am Ende steht noch ein leerer Text Node herum.
+        bSplitDestNd = TRUE;
+    }
+
+    pSrcNd = (*this)[ aEndIdx ]->GetTxtNode();
+    if( pSrcNd )
+    {
+//      if( pEnd->nContent.GetIndex() ? TRUE : aEndIdx != pStt->nNode )
+        {
+            // am Bereichsende entsteht ein neuer TextNode
+            if( !bSplitDestNd )
+            {
+                if( rPos.nNode < rNodes.GetEndOfContent().GetIndex() )
+                    rPos.nNode++;
+
+                pDestNd = rNodes.MakeTxtNode( rPos.nNode, pSrcNd->GetTxtColl() );
+                rPos.nNode--;
+                rPos.nContent.Assign( pDestNd, 0 );
+            }
+            else
+                pDestNd = rNodes[ rPos.nNode ]->GetTxtNode();
+
+            if( pDestNd && pEnd->nContent.GetIndex() )
+            {
+                // verschiebe jetzt noch den Inhalt in den neuen Node
+                SwIndex aIdx( pSrcNd, 0 );
+                pSrcNd->Cut( pDestNd, rPos.nContent, aIdx,
+                                pEnd->nContent.GetIndex());
+            }
+
+            if( bCopyCollFmt )
+            {
+                SwDoc* pInsDoc = pDestNd->GetDoc();
+                BOOL bIsUndo = pInsDoc->DoesUndo();
+                pInsDoc->DoUndo( FALSE );
+                pSrcNd->CopyCollFmt( *pDestNd );
+                pInsDoc->DoUndo( bIsUndo );
+            }
+        }
+    }
+    else
+    {
+        if( bSttTxtNd && aEndIdx.GetNode().IsCntntNode() )
+            aEndIdx++;
+//!NOSPLIT
+        if( !bSplitDestNd )
+        {
+            rPos.nNode++;
+            rPos.nContent.Assign( rPos.nNode.GetNode().GetCntntNode(), 0 );
+        }
+//!NOSPLIT
+    }
+
+    if( aEndIdx != aSttIdx )
+    {
+        // verschiebe jetzt die Nodes in das NodesArary
+        SwNodeIndex aPrvIdx( rPos.nNode, -1 );
+        ULONG nSttDiff = aSttIdx.GetIndex() - pStt->nNode.GetIndex();
+        SwNodeRange aRg( aSttIdx, aEndIdx );
+        _MoveNodes( aRg, rNodes, rPos.nNode );
+        // falls ins gleiche Nodes-Array verschoben wurde, stehen die
+        // Indizies jetzt auch an der neuen Position !!!!
+        // (also alles wieder umsetzen)
+        if( &rNodes == this )
+            pStt->nNode = aRg.aEnd.GetIndex() - nSttDiff;
+    }
+
+    // falls der Start-Node verschoben wurde, in dem der Cursor stand, so
+    // muss der Content im akt. Content angemeldet werden !!!
+    if( &pStt->nNode.GetNode() == &GetEndOfContent() &&
+        !GoPrevious( &pStt->nNode ))
+    {
+        ASSERT( FALSE, "Move() - kein ContentNode mehr vorhanden" );
+    }
+    pStt->nContent.Assign( (*this)[ pStt->nNode ]->GetCntntNode(),
+                            pStt->nContent.GetIndex() );
+    // der PaM wird korrigiert, denn falls ueber Nodegrenzen verschoben
+    // wurde, so stehen sie in unterschielichen Nodes. Auch die Selektion
+    // wird aufgehoben !
+    *pEnd = *pStt;
+    rPam.DeleteMark();
+}
+
+
+
+/*************************************************************************
+|*
+|*    SwNodes::_Copy()
+|*
+|*    Beschreibung
+|*    Parameter         SwNodeRange&    zu kopierender Bereich
+|*                      SwDoc&      in dieses Dokument
+|*                      SwIndex&    auf diese Position im Nodes-Array
+|*    Ersterstellung    JP 11.11.92
+|*    Letzte Aenderung  JP 11.11.92
+|*
+*************************************************************************/
+
+inline BYTE MaxLvl( BYTE nMin, BYTE nMax, short nNew )
+{
+    return (BYTE)(nNew < nMin ? nMin : nNew > nMax ? nMax : nNew);
+}
+
+void SwNodes::_CopyNodes( const SwNodeRange& rRange,
+            const SwNodeIndex& rIndex, BOOL bNewFrms, BOOL bTblInsDummyNode ) const
+{
+    SwDoc* pDoc = rIndex.GetNode().GetDoc();
+
+    SwNode * pAktNode;
+    if( rIndex == 0 ||
+        ( (pAktNode = &rIndex.GetNode())->GetStartNode() &&
+          !pAktNode->StartOfSectionIndex() ))
+        return;
+
+    SwNodeRange aRg( rRange );
+
+    // "einfache" StartNodes oder EndNodes ueberspringen
+    while( ND_STARTNODE == (pAktNode = (*this)[ aRg.aStart ])->GetNodeType()
+            || ( pAktNode->IsEndNode() &&
+                !pAktNode->pStartOfSection->IsSectionNode() ) )
+        aRg.aStart++;
+
+    // falls aEnd-1 auf keinem ContentNode steht, dann suche den vorherigen
+    aRg.aEnd--;
+    while( (( pAktNode = (*this)[ aRg.aEnd ])->GetStartNode() &&
+            !pAktNode->IsSectionNode() ) ||
+            ( pAktNode->IsEndNode() &&
+            ND_STARTNODE == pAktNode->pStartOfSection->GetNodeType()) )
+        aRg.aEnd--;
+    aRg.aEnd++;
+
+    // wird im selben Array's verschoben, dann ueberpruefe die Einfuegepos.
+    if( aRg.aStart >= aRg.aEnd )
+        return;
+
+    if( this == &pDoc->GetNodes() &&
+        rIndex.GetIndex() >= aRg.aStart.GetIndex() &&
+        rIndex.GetIndex() < aRg.aEnd.GetIndex() )
+            return;
+
+    SwNodeIndex aInsPos( rIndex );
+    SwNodeIndex aOrigInsPos( rIndex, -1 );          // Originale Insert Pos
+    USHORT nLevel = 0;                          // Level-Counter
+
+    for( ULONG nNodeCnt = aRg.aEnd.GetIndex() - aRg.aStart.GetIndex();
+            nNodeCnt > 0; --nNodeCnt )
+    {
+        pAktNode = &aRg.aStart.GetNode();
+        switch( pAktNode->GetNodeType() )
+        {
+        case ND_TABLENODE:
+            // dann kopiere mal den TableNode
+            // Tabelle in Tabelle kopieren ?
+            // Tabell in Fussnote kopieren ?
+            if( pDoc->IsIdxInTbl( aInsPos ) ||
+                ( aInsPos < pDoc->GetNodes().GetEndOfInserts().GetIndex() &&
+                    pDoc->GetNodes().GetEndOfInserts().StartOfSectionIndex()
+                    < aInsPos.GetIndex() ))
+            {
+                nNodeCnt -=
+                    ( pAktNode->EndOfSectionIndex() -
+                        aRg.aStart.GetIndex() );
+
+                // dann alle Nodes der Tabelle in die akt. Zelle kopieren
+                // fuer den TabellenNode einen DummyNode einfuegen?
+                if( bTblInsDummyNode )
+                    new SwNode( aInsPos, ND_SECTIONDUMMY );
+
+                for( aRg.aStart++; aRg.aStart.GetIndex() <
+                    pAktNode->EndOfSectionIndex();
+                    aRg.aStart++ )
+                {
+                    // fuer den Box-StartNode einen DummyNode einfuegen?
+                    if( bTblInsDummyNode )
+                        new SwNode( aInsPos, ND_SECTIONDUMMY );
+
+                    SwStartNode* pSttNd = aRg.aStart.GetNode().GetStartNode();
+                    _CopyNodes( SwNodeRange( *pSttNd, + 1,
+                                            *pSttNd->EndOfSectionNode() ),
+                                aInsPos, bNewFrms, FALSE );
+
+                    // fuer den Box-EndNode einen DummyNode einfuegen?
+                    if( bTblInsDummyNode )
+                        new SwNode( aInsPos, ND_SECTIONDUMMY );
+                    aRg.aStart = *pSttNd->EndOfSectionNode();
+                }
+                // fuer den TabellenEndNode einen DummyNode einfuegen?
+                if( bTblInsDummyNode )
+                    new SwNode( aInsPos, ND_SECTIONDUMMY );
+                aRg.aStart = *pAktNode->EndOfSectionNode();
+            }
+            else
+            {
+                SwNodeIndex nStt( aInsPos, -1 );
+                SwTableNode* pTblNd = ((SwTableNode*)pAktNode)->
+                                        MakeCopy( pDoc, aInsPos );
+                nNodeCnt -= aInsPos.GetIndex() - nStt.GetIndex() -2;
+
+                aRg.aStart = pAktNode->EndOfSectionIndex();
+
+                if( bNewFrms && pTblNd )
+                {
+                    nStt = aInsPos;
+                    pTblNd->MakeFrms( &nStt );
+                }
+            }
+            break;
+
+        case ND_SECTIONNODE:            // SectionNode
+            // der gesamte Bereich oder nur ein Teil ??
+            if( pAktNode->EndOfSectionIndex() < aRg.aEnd.GetIndex() )
+            {
+                // also der gesamte, lege einen neuen SectionNode an
+                SwNodeIndex nStt( aInsPos, -1 );
+                SwSectionNode* pSectNd = ((SwSectionNode*)pAktNode)->
+                                    MakeCopy( pDoc, aInsPos );
+
+                nNodeCnt -= aInsPos.GetIndex() - nStt.GetIndex() -2;
+                aRg.aStart = pAktNode->EndOfSectionIndex();
+
+                if( bNewFrms && pSectNd &&
+                    !pSectNd->GetSection().IsHidden() )
+                    pSectNd->MakeFrms( &nStt );
+            }
+            break;
+
+        case ND_STARTNODE:              // StartNode gefunden
+            {
+                SwStartNode* pTmp = new SwStartNode( aInsPos, ND_STARTNODE,
+                            ((SwStartNode*)pAktNode)->GetStartNodeType() );
+                new SwEndNode( aInsPos, *pTmp );
+                aInsPos--;
+                nLevel++;
+            }
+            break;
+
+        case ND_ENDNODE:
+            if( nLevel )                        // vollstaendige Section
+            {
+                --nLevel;
+                aInsPos++;                      // EndNode schon vorhanden
+            }
+            else if( !pAktNode->pStartOfSection->IsSectionNode() )
+            {
+                // erzeuge eine Section an der originalen InsertPosition
+                SwNodeRange aTmpRg( aOrigInsPos, 1, aInsPos );
+                pDoc->GetNodes().SectionDown( &aTmpRg,
+                        pAktNode->pStartOfSection->GetStartNodeType() );
+            }
+            break;
+
+        case ND_TEXTNODE:
+        case ND_GRFNODE:
+        case ND_OLENODE:
+            {
+                SwCntntNode* pNew = ((SwCntntNode*)pAktNode)->MakeCopy(
+                                            pDoc, aInsPos );
+                if( !bNewFrms )         // dflt. werden die Frames immer angelegt
+                    pNew->DelFrms();
+            }
+            break;
+
+        case ND_SECTIONDUMMY:
+            if( (const SwNodes*)this == GetDoc()->GetUndoNds() )
+            {
+                // dann muss an der akt. InsPos auch ein SectionNode
+                // (Start/Ende) stehen; dann diesen ueberspringen.
+                // Andernfalls nicht weiter beachten.
+                SwNode* pTmpNd = pDoc->GetNodes()[ aInsPos ];
+                if( pTmpNd->IsSectionNode() ||
+                    pTmpNd->FindStartNode()->IsSectionNode() )
+                    aInsPos++;  // ueberspringen
+            }
+            else
+                ASSERT( FALSE, "wie kommt diser Node ins Nodes-Array??" );
+            break;
+
+        default:
+            ASSERT( FALSE, "weder Start-/End-/Content-Node, unbekannter Typ" );
+        }
+        aRg.aStart++;
+    }
+
+
+#ifdef JP_DEBUG
+    {
+extern Writer* GetDebugWriter(const String&);
+
+        Writer* pWriter = GetDebugWriter(aEmptyStr);
+        if( pWriter )
+        {
+            int nError;
+            SvFileStream aStrm( "c:\\$$copy.db", STREAM_WRITE );
+            SwWriter aWriter( aStrm, *pMyDoc );
+            aWriter.Write( &nError, pWriter );
+        }
+    }
+#endif
+}
+
+void SwNodes::_DelDummyNodes( const SwNodeRange& rRg )
+{
+    SwNodeIndex aIdx( rRg.aStart );
+    while( aIdx.GetIndex() < rRg.aEnd.GetIndex() )
+    {
+        if( ND_SECTIONDUMMY == aIdx.GetNode().GetNodeType() )
+            RemoveNode( aIdx.GetIndex(), 1, TRUE );
+        else
+            aIdx++;
+    }
+}
+
+SwStartNode* SwNodes::MakeEmptySection( const SwNodeIndex& rIdx,
+                                        SwStartNodeType eSttNdTyp )
+{
+    SwStartNode* pSttNd = new SwStartNode( rIdx, ND_STARTNODE, eSttNdTyp );
+    new SwEndNode( rIdx, *pSttNd );
+    return pSttNd;
+}
+
+
+SwStartNode* SwNodes::MakeTextSection( const SwNodeIndex & rWhere,
+                                        SwStartNodeType eSttNdTyp,
+                                        SwTxtFmtColl *pColl,
+                                        SwAttrSet* pAutoAttr )
+{
+    SwStartNode* pSttNd = new SwStartNode( rWhere, ND_STARTNODE, eSttNdTyp );
+    new SwEndNode( rWhere, *pSttNd );
+    MakeTxtNode( SwNodeIndex( rWhere, - 1 ), pColl, pAutoAttr );
+    return pSttNd;
+}
+
+    // zum naechsten Content-Node, der nicht geschuetzt oder versteckt ist
+    // (beides auf FALSE ==> GoNext/GoPrevious!!!)
+SwCntntNode* SwNodes::GoNextSection( SwNodeIndex * pIdx,
+                            int bSkipHidden, int bSkipProtect ) const
+{
+    int bFirst = TRUE;
+    SwNodeIndex aTmp( *pIdx );
+    const SwNode* pNd;
+    while( aTmp < Count() - 1 )
+    {
+        if( ND_SECTIONNODE == ( pNd = (*this)[aTmp])->GetNodeType() )
+        {
+            const SwSection& rSect = ((SwSectionNode*)pNd)->GetSection();
+            if( (bSkipHidden && rSect.IsHiddenFlag()) ||
+                (bSkipProtect && rSect.IsProtectFlag()) )
+                // dann diese Section ueberspringen
+                aTmp = *pNd->EndOfSectionNode();
+            bFirst = FALSE;
+        }
+        else if( bFirst )
+        {
+            bFirst = FALSE;
+            if( pNd->pStartOfSection->IsSectionNode() )
+            {
+                const SwSection& rSect = ((SwSectionNode*)pNd->
+                                pStartOfSection)->GetSection();
+                if( (bSkipHidden && rSect.IsHiddenFlag()) ||
+                    (bSkipProtect && rSect.IsProtectFlag()) )
+                    // dann diese Section ueberspringen
+                    aTmp = *pNd->EndOfSectionNode();
+            }
+        }
+        else if( ND_CONTENTNODE & pNd->GetNodeType() )
+        {
+            const SwSectionNode* pSectNd;
+            if( ( bSkipHidden || bSkipProtect ) &&
+                0 != (pSectNd = pNd->FindSectionNode() ) &&
+                ( ( bSkipHidden && pSectNd->GetSection().IsHiddenFlag() ) ||
+                  ( bSkipProtect && pSectNd->GetSection().IsProtectFlag() )) )
+            {
+                aTmp = *pSectNd->EndOfSectionNode();
+            }
+            else
+            {
+                (*pIdx) = aTmp;
+                return (SwCntntNode*)pNd;
+            }
+        }
+        aTmp++;
+        bFirst = FALSE;
+    }
+    return 0;
+}
+
+SwCntntNode* SwNodes::GoPrevSection( SwNodeIndex * pIdx,
+                            int bSkipHidden, int bSkipProtect ) const
+{
+    int bFirst = TRUE;
+    SwNodeIndex aTmp( *pIdx );
+    const SwNode* pNd;
+    while( aTmp > 0 )
+    {
+        if( ND_ENDNODE == ( pNd = (*this)[aTmp])->GetNodeType() )
+        {
+            if( pNd->pStartOfSection->IsSectionNode() )
+            {
+                const SwSection& rSect = ((SwSectionNode*)pNd->
+                                            pStartOfSection)->GetSection();
+                if( (bSkipHidden && rSect.IsHiddenFlag()) ||
+                    (bSkipProtect && rSect.IsProtectFlag()) )
+                    // dann diese Section ueberspringen
+                    aTmp = *pNd->StartOfSectionNode();
+            }
+            bFirst = FALSE;
+        }
+        else if( bFirst )
+        {
+            bFirst = FALSE;
+            if( pNd->pStartOfSection->IsSectionNode() )
+            {
+                const SwSection& rSect = ((SwSectionNode*)pNd->
+                                pStartOfSection)->GetSection();
+                if( (bSkipHidden && rSect.IsHiddenFlag()) ||
+                    (bSkipProtect && rSect.IsProtectFlag()) )
+                    // dann diese Section ueberspringen
+                    aTmp = *pNd->StartOfSectionNode();
+            }
+        }
+        else if( ND_CONTENTNODE & pNd->GetNodeType() )
+        {
+            const SwSectionNode* pSectNd;
+            if( ( bSkipHidden || bSkipProtect ) &&
+                0 != (pSectNd = pNd->FindSectionNode() ) &&
+                ( ( bSkipHidden && pSectNd->GetSection().IsHiddenFlag() ) ||
+                  ( bSkipProtect && pSectNd->GetSection().IsProtectFlag() )) )
+            {
+                aTmp = *pSectNd;
+            }
+            else
+            {
+                (*pIdx) = aTmp;
+                return (SwCntntNode*)pNd;
+            }
+        }
+        aTmp--;
+    }
+    return 0;
+}
+
+
+    // suche den vorhergehenden [/nachfolgenden ] ContentNode oder
+    // TabellenNode mit Frames. Wird kein Ende angeben, dann wird mit
+    // dem FrameIndex begonnen; ansonsten, wird mit dem vor rFrmIdx und
+    // dem hintern pEnd die Suche gestartet. Sollte kein gueltiger Node
+    // gefunden werden, wird 0 returnt. rFrmIdx zeigt auf dem Node mit
+    // Frames
+SwNode* SwNodes::FindPrvNxtFrmNode( SwNodeIndex& rFrmIdx,
+                                    const SwNode* pEnd ) const
+{
+    SwNode* pFrmNd = 0;
+
+    // habe wir gar kein Layout, vergiss es
+    if( GetDoc()->GetRootFrm() )
+    {
+        SwNode* pSttNd = &rFrmIdx.GetNode();
+
+        // wird in eine versteckte Section verschoben ??
+        SwSectionNode* pSectNd = pSttNd->IsSectionNode()
+                    ? pSttNd->FindStartNode()->FindSectionNode()
+                    : pSttNd->FindSectionNode();
+        if( !( pSectNd && pSectNd->GetSection().CalcHiddenFlag()/*IsHiddenFlag()*/ ) )
+        {
+            SwNodeIndex aIdx( rFrmIdx );
+            SwNode* pNd;
+            if( pEnd )
+            {
+                aIdx--;
+                pNd = &aIdx.GetNode();
+            }
+            else
+                pNd = pSttNd;
+
+            if( ( pFrmNd = pNd )->IsCntntNode() )
+                rFrmIdx = aIdx;
+
+                // suche nach vorne/hinten nach einem Content Node
+            else if( 0 != ( pFrmNd = GoPrevSection( &aIdx, TRUE, FALSE )) &&
+                    ::CheckNodesRange( aIdx, rFrmIdx, TRUE ) &&
+                    // nach vorne nie aus der Tabelle hinaus!
+                    pFrmNd->FindTableNode() == pSttNd->FindTableNode() &&
+                    // Bug 37652: nach hinten nie aus der Tabellenzelle hinaus!
+                    (!pFrmNd->FindTableNode() || pFrmNd->FindTableBoxStartNode()
+                        == pSttNd->FindTableBoxStartNode() ) &&
+                     (!pSectNd || pSttNd->IsSectionNode() ||
+                      pSectNd->GetIndex() < pFrmNd->GetIndex())
+                    )
+            {
+                rFrmIdx = aIdx;
+            }
+            else
+            {
+                if( pEnd )
+                    aIdx = pEnd->GetIndex() + 1;
+                else
+                    aIdx = rFrmIdx;
+
+                // JP 19.09.93: aber nie die Section dafuer verlassen !!
+                if( ( pEnd && ( pFrmNd = &aIdx.GetNode())->IsCntntNode() ) ||
+                    ( 0 != ( pFrmNd = GoNextSection( &aIdx, TRUE, FALSE )) &&
+                    ::CheckNodesRange( aIdx, rFrmIdx, TRUE ) &&
+                    // JP 27.01.99: wenn der "Start"Node ein TabellenNode ist,
+                    // dann kann der dahinter liegende nie der gleiche sein!
+                    ( pSttNd->IsTableNode() ||
+                      ( pFrmNd->FindTableNode() == pSttNd->FindTableNode() &&
+                        // Bug 37652: nach hinten nie aus der Tabellenzelle hinaus!
+                        (!pFrmNd->FindTableNode() || pFrmNd->FindTableBoxStartNode()
+                        == pSttNd->FindTableBoxStartNode() ))) &&
+                     (!pSectNd || pSttNd->IsSectionNode() ||
+                      pSectNd->EndOfSectionIndex() > pFrmNd->GetIndex())
+                    ))
+                {
+                    //JP 18.02.99: Undo von Merge einer Tabelle mit der
+                    // der vorherigen, wenn dahinter auch noch eine steht
+                    // falls aber der Node in einer Tabelle steht, muss
+                    // natuerlich dieser returnt werden, wenn der SttNode eine
+                    // Section oder Tabelle ist!
+                    SwTableNode* pTblNd;
+                    if( ( pSttNd->IsTableNode() ) &&
+                        0 != ( pTblNd = pFrmNd->FindTableNode() ))
+                    {
+                        pFrmNd = pTblNd;
+                        rFrmIdx = *pFrmNd;
+                    }
+                    else
+                        rFrmIdx = aIdx;
+                }
+                else if( pNd->IsEndNode() && pNd->FindStartNode()->IsTableNode() )
+                {
+                    pFrmNd = pNd->FindStartNode();
+                    rFrmIdx = *pFrmNd;
+                }
+                else
+                {
+                    if( pEnd )
+                        aIdx = pEnd->GetIndex() + 1;
+                    else
+                        aIdx = rFrmIdx.GetIndex() + 1;
+
+                    if( (pFrmNd = &aIdx.GetNode())->IsTableNode() )
+                        rFrmIdx = aIdx;
+                    else
+                    {
+                        pFrmNd = 0;
+
+                        // is there some sectionnodes before a tablenode?
+                        while( aIdx.GetNode().IsSectionNode() )
+                        {
+                            const SwSection& rSect = aIdx.GetNode().
+                                GetSectionNode()->GetSection();
+                            if( rSect.IsHiddenFlag() )
+                                aIdx = aIdx.GetNode().EndOfSectionIndex()+1;
+                            else
+                                aIdx++;
+                        }
+                        if( aIdx.GetNode().IsTableNode() )
+                        {
+                            rFrmIdx = aIdx;
+                            pFrmNd = &aIdx.GetNode();
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return pFrmNd;
+}
+
+SwCntntFrm* SwNodes::MakeFrm( const SwNodeIndex &rIndex )
+{
+    SwCntntNode *pNode = rIndex.GetNode().GetCntntNode();
+    return pNode ? pNode->MakeFrm() : 0;
+}
+
+void SwNodes::ForEach( const SwNodeIndex& rStart, const SwNodeIndex& rEnd,
+                    FnForEach_SwNodes fnForEach, void* pArgs )
+{
+    BigPtrArray::ForEach( rStart.GetIndex(), rEnd.GetIndex(),
+                            (FnForEach) fnForEach, pArgs );
+}
+
+struct _TempBigPtrEntry : public BigPtrEntry
+{
+    _TempBigPtrEntry() {}
+};
+
+
+void SwNodes::RemoveNode( ULONG nDelPos, ULONG nSize, FASTBOOL bDel )
+{
+    ULONG nEnd = nDelPos + nSize;
+    SwNode* pNew = (*this)[ nEnd ];
+
+    if( pRoot )
+    {
+        SwNodeIndex *p = pRoot;
+        while( p )
+        {
+            ULONG nIdx = p->GetIndex();
+            SwNodeIndex* pNext = p->pNext;
+            if( nDelPos <= nIdx && nIdx < nEnd )
+                (*p) = *pNew;
+
+            p = pNext;
+        }
+
+        p = pRoot->pPrev;
+        while( p )
+        {
+            ULONG nIdx = p->GetIndex();
+            SwNodeIndex* pPrev = p->pPrev;
+            if( nDelPos <= nIdx && nIdx < nEnd )
+                (*p) = *pNew;
+
+            p = pPrev;
+        }
+    }
+
+    if( bDel )
+    {
+        ULONG nCnt = nSize;
+        SwNode *pDel = (*this)[ nDelPos+nCnt-1 ], *pPrev = (*this)[ nDelPos+nCnt-2 ];
+
+#if 1
+// temp. Object setzen
+        //JP 24.08.98: muessten eigentlich einzeln removed werden, weil
+        //      das Remove auch rekursiv gerufen werden kann, z.B. bei
+        //      zeichengebundenen Rahmen. Da aber dabei viel zu viel
+        //      ablaueft, wird hier ein temp. Objekt eingefuegt, das
+        //      dann mit dem Remove wieder entfernt wird.
+        // siehe Bug 55406
+        _TempBigPtrEntry aTempEntry;
+        BigPtrEntry* pTempEntry = &aTempEntry;
+
+        while( nCnt-- )
+        {
+            delete pDel;
+            pDel = pPrev;
+            ULONG nPrevNdIdx = pPrev->GetIndex();
+            BigPtrArray::Replace( nPrevNdIdx+1, pTempEntry );
+            if( nCnt )
+                pPrev = (*this)[ nPrevNdIdx  - 1 ];
+        }
+        nDelPos = pDel->GetIndex() + 1;
+    }
+#else
+// nach jedem Del ein Remove rufen - teuer!
+        //JP 24.08.98: muessen leider einzeln removed werden, weil das
+        //              auch rekursiv gerufen wird - zeichengeb. Flys!
+        // siehe Bug 55406
+        while( nCnt-- )
+        {
+            delete pDel;
+            pDel = pPrev;
+            ULONG nPrevNdIdx = pPrev->GetIndex();
+            BigPtrArray::Remove( nPrevNdIdx+1, 1 );
+            if( nCnt )
+                pPrev = (*this)[ nPrevNdIdx  - 1 ];
+        }
+    }
+    else
+#endif
+
+    BigPtrArray::Remove( nDelPos, nSize );
+}
+
+void SwNodes::RegisterIndex( SwNodeIndex& rIdx )
+{
+    if( !pRoot )        // noch keine Root gesetzt?
+    {
+        pRoot = &rIdx;
+        pRoot->pPrev = 0;
+        pRoot->pNext = 0;
+    }
+    else
+    {
+        // immer hinter die Root haengen
+        rIdx.pNext = pRoot->pNext;
+        pRoot->pNext = &rIdx;
+        rIdx.pPrev = pRoot;
+        if( rIdx.pNext )
+            rIdx.pNext->pPrev = &rIdx;
+    }
+}
+
+void SwNodes::DeRegisterIndex( SwNodeIndex& rIdx )
+{
+    register SwNodeIndex* pN = rIdx.pNext;
+    register SwNodeIndex* pP = rIdx.pPrev;
+
+    if( pRoot == &rIdx )
+        pRoot = pP ? pP : pN;
+
+    if( pP )
+        pP->pNext = pN;
+    if( pN )
+        pN->pPrev = pP;
+
+    rIdx.pNext = 0;
+    rIdx.pPrev = 0;
+}
+
+void SwNodes::Insert( const SwNodePtr pNode, const SwNodeIndex& rPos )
+{
+    const ElementPtr pIns = pNode;
+    BigPtrArray::Insert( pIns, rPos.GetIndex() );
+}
+
+void SwNodes::Insert(const SwNodePtr pNode, ULONG nPos)
+{
+    const ElementPtr pIns = pNode;
+    BigPtrArray::Insert( pIns, nPos );
+}
+
diff --git a/sw/source/core/docnode/section.cxx b/sw/source/core/docnode/section.cxx
new file mode 100644
index 000000000000..264ca9fd97e0
--- /dev/null
+++ b/sw/source/core/docnode/section.cxx
@@ -0,0 +1,1559 @@
+/*************************************************************************
+ *
+ *  $RCSfile: section.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:18 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include 
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _SFXINTITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SFXSTRITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SFXDOCFILE_HXX //autogen
+#include 
+#endif
+#ifndef _SFX_DOCFILT_HACK_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_PROTITEM_HXX //autogen
+#include 
+#endif
+#ifndef _LINKNAME_HXX //autogen
+#include 
+#endif
+#ifndef _SVXLINKMGR_HXX
+#include 
+#endif
+#ifndef _URLOBJ_HXX //autogen
+#include 
+#endif
+
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _FMTCNTNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTPDSC_HXX //autogen
+#include 
+#endif
+#ifndef _ERRHDL_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _NODE_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _FRMTOOL_HXX
+#include 
+#endif
+#ifndef _EDITSH_HXX
+#include 
+#endif
+#ifndef _HINTS_HXX
+#include 
+#endif
+#ifndef _DOCSH_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _SECTION_HXX
+#include 
+#endif
+#ifndef _SWSERV_HXX
+#include 
+#endif
+#ifndef _SHELLIO_HXX
+#include 
+#endif
+#ifndef _POOLFMT_HXX
+#include 
+#endif
+#ifndef _BOOKMRK_HXX
+#include 
+#endif
+#ifndef _EXPFLD_HXX
+#include 
+#endif
+#ifndef _SWBASLNK_HXX
+#include 
+#endif
+#ifndef _MVSAVE_HXX
+#include 
+#endif
+#ifndef _SECTFRM_HXX
+#include 
+#endif
+#ifndef _FMTFTNTX_HXX
+#include 
+#endif
+#ifndef _FTNIDX_HXX
+#include 
+#endif
+#ifndef _DOCTXM_HXX
+#include 
+#endif
+
+#ifndef _SWSWERROR_H
+#include 
+#endif
+
+//static const char __FAR_DATA sSectionFmtNm[] = "Section";
+#define sSectionFmtNm aEmptyStr
+
+class SwIntrnlSectRefLink : public SwBaseLink
+{
+    SwSectionFmt& rSectFmt;
+public:
+    SwIntrnlSectRefLink( SwSectionFmt& rFmt, USHORT nUpdateType, USHORT nFmt )
+        : SwBaseLink( nUpdateType, nFmt ),
+        rSectFmt( rFmt )
+    {}
+
+    virtual void Closed();
+    virtual void DataChanged( SvData& );
+
+    virtual const SwNode* GetAnchor() const;
+    virtual BOOL IsInRange( ULONG nSttNd, ULONG nEndNd, xub_StrLen nStt = 0,
+                            xub_StrLen nEnd = STRING_NOTFOUND ) const;
+};
+
+
+TYPEINIT1(SwSectionFmt,SwFrmFmt );
+TYPEINIT1(SwSection,SwClient );
+
+
+SO2_IMPL_REF( SwServerObject )
+
+
+typedef SwSection* SwSectionPtr;
+
+SV_IMPL_PTRARR( SwSections, SwSection*)
+SV_IMPL_PTRARR(SwSectionFmts,SwSectionFmt*)
+
+
+
+SwSection::SwSection( SectionType eTyp, const String& rName,
+                    SwSectionFmt* pFmt )
+    : SwClient( pFmt ),
+    eType( eTyp ), sSectionNm( rName )
+{
+    bHidden = FALSE;
+    bHiddenFlag = FALSE;
+    bProtectFlag = FALSE;
+    bCondHiddenFlag = TRUE;
+    bConnectFlag = TRUE;
+
+    SwSectionPtr pParentSect = GetParent();
+    if( pParentSect )
+    {
+        FASTBOOL bPHFlag = pParentSect->IsHiddenFlag();
+        if( pParentSect->IsHiddenFlag() )
+            SetHidden( TRUE );
+
+        _SetProtectFlag( pParentSect->IsProtectFlag() );
+    }
+
+    if( pFmt && !bProtectFlag )
+        _SetProtectFlag( pFmt->GetProtect().IsCntntProtected() );
+}
+
+
+SwSection::~SwSection()
+{
+    SwSectionFmt* pFmt = GetFmt();
+    if( !pFmt )
+        return;
+
+    SwDoc* pDoc = pFmt->GetDoc();
+    if( pDoc->IsInDtor() )
+    {
+        // dann melden wir noch schnell unser Format um ans dflt FrameFmt,
+        // damit es keine Abhaengigkeiten gibt
+        if( pFmt->DerivedFrom() != pDoc->GetDfltFrmFmt() )
+            pDoc->GetDfltFrmFmt()->Add( pFmt );
+    }
+    else
+    {
+        pFmt->Remove( this );               // austragen,
+
+        if( CONTENT_SECTION != eType )      // den Link austragen
+            pDoc->GetLinkManager().Remove( *refLink );
+
+        if( refObj.Is() )                   // als Server austragen
+            pDoc->GetLinkManager().RemoveServer( &refObj );
+
+        // ist die Section der letzte Client im Format, kann dieses
+        // geloescht werden
+        if( !pFmt->GetDepends() )
+        {
+            // Bug: 28191 - nicht ins Undo aufnehmen, sollte schon vorher
+            //          geschehen sein!!
+            BOOL bUndo = pDoc->DoesUndo();
+            pDoc->DoUndo( FALSE );
+            pDoc->DelSectionFmt( pFmt );    // und loeschen
+            pDoc->DoUndo( bUndo );
+        }
+    }
+    if( refObj.Is() )
+        refObj->Closed();
+}
+
+
+SwSection& SwSection::operator=( const SwSection& rCpy )
+{
+    sSectionNm = rCpy.sSectionNm;
+    sCondition = rCpy.sCondition;
+    sLinkFileName = rCpy.GetLinkFileName();
+    SetLinkFilePassWd( rCpy.GetLinkFilePassWd() );
+    SetConnectFlag( rCpy.IsConnectFlag() );
+
+    eType = rCpy.eType;
+
+    if( !GetFmt() )
+        SetProtect( rCpy.IsProtect() );
+    else if( rCpy.GetFmt() )
+        _SetProtectFlag( rCpy.bProtectFlag );
+    else
+        SetProtect( rCpy.bProtectFlag );
+
+    bCondHiddenFlag = TRUE;     // sollte immer defaultet werden
+    SetHidden( rCpy.bHidden );
+
+    return *this;
+}
+
+
+int SwSection::operator==( const SwSection& rCmp ) const
+{
+    return  sSectionNm == rCmp.sSectionNm &&
+            sCondition == rCmp.sCondition &&
+            eType == rCmp.eType &&
+            bHidden == rCmp.bHidden &&
+            IsProtect() == rCmp.IsProtect() &&
+            GetLinkFileName() == rCmp.GetLinkFileName() &&
+            GetLinkFilePassWd() == rCmp.GetLinkFilePassWd() &&
+            ( !GetFmt() || !rCmp.GetFmt() || GetFmt() == rCmp.GetFmt());
+}
+
+
+void SwSection::_SetHiddenFlag( int bHidden, int bCondition )
+{
+    SwSectionFmt* pFmt = GetFmt();
+    if( pFmt )
+    {
+        int bHide = bHidden && bCondition;
+
+        if( bHide )                         // die Nodes also "verstecken"
+        {
+            if( !bHiddenFlag )              // ist nicht versteckt
+            {
+                // wie sieht es mit dem Parent aus, ist der versteckt ?
+                // (eigentlich muesste das vom bHiddenFlag angezeigt werden!)
+
+                // erstmal allen Childs sagen, das sie versteckt sind
+                SwMsgPoolItem aMsgItem( RES_SECTION_HIDDEN );
+                pFmt->Modify( &aMsgItem, &aMsgItem );
+
+                // alle Frames loeschen
+                pFmt->DelFrms();
+            }
+        }
+        else if( bHiddenFlag )              // die Nodes wieder anzeigen
+        {
+            // alle Frames sichtbar machen ( Childs Sections werden vom
+            // MakeFrms beruecksichtigt). Aber nur wenn die ParentSection
+            // nichts dagegen hat !
+            SwSection* pParentSect = pFmt->GetParentSection();
+            if( !pParentSect || !pParentSect->IsHiddenFlag() )
+            {
+                // erstmal allen Childs sagen, das der Parent nicht mehr
+                // versteckt ist
+                SwMsgPoolItem aMsgItem( RES_SECTION_NOT_HIDDEN );
+                pFmt->Modify( &aMsgItem, &aMsgItem );
+
+                pFmt->MakeFrms();
+            }
+        }
+    }
+}
+
+int SwSection::CalcHiddenFlag() const
+{
+    const SwSection* pSect = this;
+    do {
+        if( pSect->IsHidden() && pSect->IsCondHidden() )
+            return TRUE;
+    } while( 0 != ( pSect = pSect->GetParent()) );
+
+    return FALSE;
+}
+
+int SwSection::_IsProtect() const
+{
+    return GetFmt()->GetProtect().IsCntntProtected();
+}
+
+
+void SwSection::SetHidden( int bFlag )
+{
+    if( bHidden == bFlag )
+        return;
+
+    bHidden = bFlag;
+    _SetHiddenFlag( bHidden, bCondHiddenFlag );
+}
+
+
+void SwSection::SetProtect( int bFlag )
+{
+    if( GetFmt() )
+    {
+        SvxProtectItem aItem;
+        aItem.SetCntntProtect( (BOOL)bFlag );
+        GetFmt()->SetAttr( aItem );
+    }
+    else
+        bProtectFlag = bFlag;
+}
+
+
+void SwSection::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew )
+{
+    BOOL bRemake = FALSE, bUpdateFtn = FALSE;
+    switch( pOld ? pOld->Which() : pNew ? pNew->Which() : 0 )
+    {
+    case RES_ATTRSET_CHG:
+        {
+            SfxItemSet* pNewSet = ((SwAttrSetChg*)pNew)->GetChgSet();
+            SfxItemSet* pOldSet = ((SwAttrSetChg*)pOld)->GetChgSet();
+            const SfxPoolItem* pItem;
+
+            if( SFX_ITEM_SET == pNewSet->GetItemState(
+                        RES_PROTECT, FALSE, &pItem ) )
+            {
+                _SetProtectFlag( ((SvxProtectItem*)pItem)->IsCntntProtected() );
+                pNewSet->ClearItem( RES_PROTECT );
+                pOldSet->ClearItem( RES_PROTECT );
+            }
+
+            if( SFX_ITEM_SET == pNewSet->GetItemState(
+                        RES_FTN_AT_TXTEND, FALSE, &pItem ) ||
+                SFX_ITEM_SET == pNewSet->GetItemState(
+                        RES_END_AT_TXTEND, FALSE, &pItem ))
+                    bUpdateFtn = TRUE;
+
+            if( !pNewSet->Count() )
+                return;
+        }
+        break;
+
+    case RES_PROTECT:
+        if( pNew )
+        {
+            BOOL bNewFlag = ((SvxProtectItem*)pNew)->IsCntntProtected();
+            if( !bNewFlag )
+            {
+                // Abschalten: teste ob nicht vielleich ueber die Parents
+                //              doch ein Schutzt besteht!
+                const SwSection* pSect = this;
+                do {
+                    if( pSect->IsProtect() )
+                    {
+                        bNewFlag = TRUE;
+                        break;
+                    }
+                } while( 0 != ( pSect = pSect->GetParent()) );
+            }
+
+            _SetProtectFlag( bNewFlag );
+        }
+        return;
+
+    case RES_SECTION_HIDDEN:
+        bHiddenFlag = TRUE;
+        return;
+
+    case RES_SECTION_NOT_HIDDEN:
+    case RES_SECTION_RESETHIDDENFLAG:
+        bHiddenFlag = bHidden && bCondHiddenFlag;
+        return;
+
+    case RES_COL:
+        /* wird ggf. vom Layout erledigt */
+        break;
+
+    case RES_FTN_AT_TXTEND:
+        if( pNew && pOld )
+            bUpdateFtn = TRUE;
+        break;
+
+    case RES_END_AT_TXTEND:
+        if( pNew && pOld )
+            bUpdateFtn = TRUE;
+        break;
+    }
+
+    if( bRemake )
+    {
+        GetFmt()->DelFrms();
+        GetFmt()->MakeFrms();
+    }
+
+    if( bUpdateFtn )
+    {
+        SwSectionNode* pSectNd = GetFmt()->GetSectionNode( FALSE );
+        if( pSectNd )
+            pSectNd->GetDoc()->GetFtnIdxs().UpdateFtn(SwNodeIndex( *pSectNd ));
+    }
+    SwClient::Modify( pOld, pNew );
+}
+
+void SwSection::SetRefObject( SvPseudoObject* pObj )
+{
+    refObj = pObj;
+}
+
+
+void SwSection::SetCondHidden( int bFlag )
+{
+    if( bCondHiddenFlag == bFlag )
+        return;
+
+    bCondHiddenFlag = bFlag;
+    _SetHiddenFlag( bHidden, bCondHiddenFlag );
+}
+
+
+// setze/erfrage den gelinkten FileNamen
+const String& SwSection::GetLinkFileName() const
+{
+    if( refLink.Is() )
+    {
+        String sTmp;
+        switch( eType )
+        {
+        case DDE_LINK_SECTION:
+            {
+                const SvLinkName* pLNm = refLink->GetLinkSourceName();
+                if( pLNm )
+                    sTmp = pLNm->GetName();
+            }
+            break;
+
+        case FILE_LINK_SECTION:
+            {
+                String sRange, sFilter;
+                if( refLink->GetLinkManager() &&
+                    refLink->GetLinkManager()->GetDisplayNames(
+                        *refLink, 0, &sTmp, &sRange, &sFilter ) )
+                {
+                    ( sTmp += cTokenSeperator ) += sFilter;
+                    ( sTmp += cTokenSeperator ) += sRange;
+                }
+                else if( GetFmt() && !GetFmt()->GetSectionNode() )
+                {
+                    // ist die Section im UndoNodesArray, dann steht
+                    // der Link nicht im LinkManager, kann also auch nicht
+                    // erfragt werden. Dann returne den akt. Namen
+                    return sLinkFileName;
+                }
+            }
+            break;
+        }
+        ((SwSection*)this)->sLinkFileName = sTmp;
+    }
+    return sLinkFileName;
+}
+
+
+void SwSection::SetLinkFileName( const String& rNew, const String* pPassWd )
+{
+    if( refLink.Is() )
+        refLink->SetLinkSourceName( new SvLinkName( rNew ));
+    else
+        sLinkFileName = rNew;
+    if( pPassWd )
+        SetLinkFilePassWd( *pPassWd );
+}
+
+// falls es ein gelinkter Bereich war, dann muessen alle
+// Child-Verknuepfungen sichtbar bemacht werden.
+void SwSection::MakeChildLinksVisible( const SwSectionNode& rSectNd )
+{
+    const SwNode* pNd;
+    const SvBaseLinks& rLnks = rSectNd.GetDoc()->GetLinkManager().GetLinks();
+    for( USHORT n = rLnks.Count(); n; )
+    {
+        SvBaseLink* pBLnk = &(*rLnks[ --n ]);
+        if( pBLnk && !pBLnk->IsVisible() &&
+            pBLnk->ISA( SwBaseLink ) &&
+            0 != ( pNd = ((SwBaseLink*)pBLnk)->GetAnchor() ) )
+        {
+            pNd = pNd->FindStartNode(); // falls SectionNode ist!
+            const SwSectionNode* pParent;
+            while( 0 != ( pParent = pNd->FindSectionNode() ) &&
+                    ( CONTENT_SECTION == pParent->GetSection().GetType()
+                        || pNd == &rSectNd ))
+                    pNd = pParent->FindStartNode();
+
+            // steht nur noch in einer normalen Section, also
+            // wieder anzeigen
+            if( !pParent )
+                pBLnk->SetVisible( TRUE );
+        }
+    }
+}
+
+const SwTOXBase* SwSection::GetTOXBase() const
+{
+    const SwTOXBase* pRet = 0;
+    if( TOX_CONTENT_SECTION == GetType() )
+        pRet = PTR_CAST( SwTOXBaseSection, this );
+    return pRet;
+}
+
+SwSectionFmt::SwSectionFmt( SwSectionFmt* pDrvdFrm, SwDoc *pDoc )
+    : SwFrmFmt( pDoc->GetAttrPool(), sSectionFmtNm, pDrvdFrm )
+{
+    LockModify();
+    SetAttr( *GetDfltAttr( RES_COL ) );
+    UnlockModify();
+}
+
+SwSectionFmt::~SwSectionFmt()
+{
+    if( !GetDoc()->IsInDtor() )
+    {
+        SwSectionNode* pSectNd;
+        const SwNodeIndex* pIdx = GetCntnt( FALSE ).GetCntntIdx();
+        if( pIdx && &GetDoc()->GetNodes() == &pIdx->GetNodes() &&
+            0 != (pSectNd = pIdx->GetNode().GetSectionNode() ))
+        {
+            SwSection& rSect = pSectNd->GetSection();
+            // falls es ein gelinkter Bereich war, dann muessen alle
+            // Child-Verknuepfungen sichtbar bemacht werden.
+            if( rSect.IsConnected() )
+                rSect.MakeChildLinksVisible( *pSectNd );
+
+            // vorm loeschen der Nodes pruefe, ob wir uns nicht
+            // noch anzeigen muessen!
+            if( rSect.IsHiddenFlag() )
+            {
+                SwSectionPtr pParentSect = rSect.GetParent();
+                if( !pParentSect || !pParentSect->IsHiddenFlag() )
+                {
+                    // Nodes wieder anzeigen
+                    rSect.SetHidden( FALSE );
+                }
+            }
+            SwClientIter aIter( *this );
+            SwClient *pLast = aIter.GoStart();
+            while ( pLast )
+            {
+                if ( pLast->IsA( TYPE(SwFrm) ) )
+                {
+                    SwSectionFrm *pFrm = (SwSectionFrm*)pLast;
+                    SwSectionFrm::MoveCntntAndDelete( pFrm, TRUE );
+                    pLast = aIter.GoStart();
+                }
+                else
+                    pLast = aIter++;
+            }
+            // hebe die Section doch mal auf
+            SwNodeRange aRg( *pSectNd, 0, *pSectNd->EndOfSectionNode() );
+            GetDoc()->GetNodes().SectionUp( &aRg );
+        }
+        LockModify();
+        ResetAttr( RES_CNTNT );
+        UnlockModify();
+    }
+}
+
+
+SwSectionPtr SwSectionFmt::_GetSection() const
+{
+    if( GetDepends() )
+    {
+        SwClientIter aIter( *(SwSectionFmt*)this );
+        return (SwSectionPtr)aIter.First( TYPE(SwSection) );
+    }
+
+    ASSERT( FALSE, "keine Section als Client." )
+    return 0;
+}
+
+extern void lcl_DeleteFtn( SwSectionNode *pNd, ULONG nStt, ULONG nEnd );
+
+//Vernichtet alle Frms in aDepend (Frms werden per PTR_CAST erkannt).
+void SwSectionFmt::DelFrms()
+{
+    SwSectionNode* pSectNd;
+    const SwNodeIndex* pIdx = GetCntnt(FALSE).GetCntntIdx();
+    if( pIdx && &GetDoc()->GetNodes() == &pIdx->GetNodes() &&
+        0 != (pSectNd = pIdx->GetNode().GetSectionNode() ))
+    {
+        SwClientIter aIter( *this );
+        SwClient *pLast = aIter.GoStart();
+        while ( pLast )
+        {
+            if ( pLast->IsA( TYPE(SwFrm) ) )
+            {
+                SwSectionFrm *pFrm = (SwSectionFrm*)pLast;
+                SwSectionFrm::MoveCntntAndDelete( pFrm, FALSE );
+                pLast = aIter.GoStart();
+            }
+            else
+            {
+                if ( pLast->IsA( TYPE(SwSectionFmt) ) )
+                    ((SwSectionFmt*)pLast)->DelFrms();
+                pLast = aIter++;
+            }
+        }
+        ULONG nEnde = pSectNd->EndOfSectionIndex();
+        ULONG nStart = pSectNd->GetIndex()+1;
+        lcl_DeleteFtn( pSectNd, nStart, nEnde );
+    }
+    if( pIdx )
+    {
+        //JP 22.09.98:
+        //Hint fuer Pagedesc versenden. Das mueste eigntlich das Layout im
+        //Paste der Frames selbst erledigen, aber das fuehrt dann wiederum
+        //zu weiteren Folgefehlern, die mit Laufzeitkosten geloest werden
+        //muesten. #56977# #55001# #56135#
+        SwNodeIndex aNextNd( *pIdx );
+        SwCntntNode* pCNd = GetDoc()->GetNodes().GoNextSection( &aNextNd, TRUE, FALSE );
+        if( pCNd )
+        {
+            const SfxPoolItem& rItem = pCNd->GetSwAttrSet().Get( RES_PAGEDESC );
+            pCNd->Modify( (SfxPoolItem*)&rItem, (SfxPoolItem*)&rItem );
+        }
+    }
+}
+
+
+//Erzeugt die Ansichten
+void SwSectionFmt::MakeFrms()
+{
+    SwSectionNode* pSectNd;
+    const SwNodeIndex* pIdx = GetCntnt(FALSE).GetCntntIdx();
+
+    if( pIdx && &GetDoc()->GetNodes() == &pIdx->GetNodes() &&
+        0 != (pSectNd = pIdx->GetNode().GetSectionNode() ))
+    {
+        SwNodeIndex aIdx( *pIdx );
+        pSectNd->MakeFrms( &aIdx );
+    }
+}
+
+void lcl_ClientIter( SwSectionFmt* pFmt, const SfxPoolItem* pOld,
+                                        const SfxPoolItem* pNew )
+{
+    SwClientIter aIter( *pFmt );
+    SwClient * pLast = aIter.GoStart();
+    if( pLast )
+        do {
+            pLast->Modify( (SfxPoolItem*)pOld, (SfxPoolItem*)pNew );
+        } while( 0 != ( pLast = aIter++ ));
+}
+
+void SwSectionFmt::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew )
+{
+    BOOL bClients = FALSE;
+    USHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
+    switch( nWhich )
+    {
+    case RES_ATTRSET_CHG:
+        if( GetDepends() )
+        {
+            SfxItemSet* pNewSet = ((SwAttrSetChg*)pNew)->GetChgSet();
+            SfxItemSet* pOldSet = ((SwAttrSetChg*)pOld)->GetChgSet();
+            const SfxPoolItem *pItem;
+            if( SFX_ITEM_SET == pNewSet->GetItemState(
+                                        RES_PROTECT, FALSE, &pItem ))
+            {
+                lcl_ClientIter( this, pItem, pItem );
+                pNewSet->ClearItem( RES_PROTECT );
+                pOldSet->ClearItem( RES_PROTECT );
+            }
+            if( SFX_ITEM_SET == pNewSet->GetItemState(
+                                    RES_FTN_AT_TXTEND, FALSE, &pItem ))
+            {
+                lcl_ClientIter( this, &pOldSet->Get( RES_FTN_AT_TXTEND ),
+                                        pItem );
+                pNewSet->ClearItem( RES_FTN_AT_TXTEND );
+                pOldSet->ClearItem( RES_FTN_AT_TXTEND );
+            }
+            if( SFX_ITEM_SET == pNewSet->GetItemState(
+                                    RES_END_AT_TXTEND, FALSE, &pItem ))
+            {
+                lcl_ClientIter( this, &pOldSet->Get( RES_END_AT_TXTEND ),
+                                        pItem );
+                pNewSet->ClearItem( RES_END_AT_TXTEND );
+                pOldSet->ClearItem( RES_END_AT_TXTEND );
+            }
+            if( !((SwAttrSetChg*)pOld)->GetChgSet()->Count() )
+                return;
+        }
+        break;
+
+    case RES_SECTION_RESETHIDDENFLAG:
+    case RES_FTN_AT_TXTEND:
+    case RES_END_AT_TXTEND : bClients = TRUE;
+                            // no break !!
+    case RES_SECTION_HIDDEN:
+    case RES_SECTION_NOT_HIDDEN:
+        {
+            SwSection* pSect = GetSection();
+            if( pSect && ( bClients || ( RES_SECTION_HIDDEN == nWhich ?
+                            !pSect->IsHiddenFlag() : pSect->IsHiddenFlag() ) ) )
+            {
+                // selbst ueber die Clients iterieren, sollte schneller sein!
+                SwClientIter aIter( *this );
+                SwClient * pLast = aIter.GoStart();
+                do {
+                    pLast->Modify( pOld, pNew );
+                } while( 0 != ( pLast = aIter++ ));
+            }
+        }
+        return ;
+
+
+    case RES_PROTECT:
+        // diese Messages bis zum Ende des Baums durchreichen !
+        if( GetDepends() )
+        {
+            SwClientIter aIter( *this );
+            SwClient * pLast = aIter.GoStart();
+            if( pLast )     // konnte zum Anfang gesprungen werden ??
+                do {
+                    pLast->Modify( pOld, pNew );
+                } while( 0 != ( pLast = aIter++ ));
+        }
+        return;     // das wars
+
+    case RES_OBJECTDYING:
+        if( !GetDoc()->IsInDtor() &&
+            ((SwPtrMsgPoolItem *)pOld)->pObject == (void*)GetRegisteredIn() )
+        {
+            // mein Parent wird vernichtet, dann an den Parent vom Parent
+            // umhaengen und wieder aktualisieren
+            SwFrmFmt::Modify( pOld, pNew );     //  erst umhaengen !!!
+            UpdateParent();
+            return;
+        }
+        break;
+
+    case RES_FMT_CHG:
+        if( !GetDoc()->IsInDtor() &&
+            ((SwFmtChg*)pNew)->pChangedFmt == (void*)GetRegisteredIn() &&
+            ((SwFmtChg*)pNew)->pChangedFmt->IsA( TYPE( SwSectionFmt )) )
+        {
+            // mein Parent wird veraendert, muss mich aktualisieren
+            SwFrmFmt::Modify( pOld, pNew );     //  erst umhaengen !!!
+            UpdateParent();
+            return;
+        }
+        break;
+    }
+    SwFrmFmt::Modify( pOld, pNew );
+}
+
+        // erfrage vom Format Informationen
+BOOL SwSectionFmt::GetInfo( SfxPoolItem& rInfo ) const
+{
+    switch( rInfo.Which() )
+    {
+    case RES_FINDNEARESTNODE:
+        if( ((SwFmtPageDesc&)GetAttr( RES_PAGEDESC )).GetPageDesc() )
+        {
+            const SwSectionNode* pNd = GetSectionNode();
+            if( pNd )
+                ((SwFindNearestNode&)rInfo).CheckNode( *pNd );
+        }
+        return TRUE;
+
+    case RES_CONTENT_VISIBLE:
+        {
+            SwFrm* pFrm = (SwFrm*)SwClientIter( *(SwSectionFmt*)this ).First( TYPE(SwFrm) );
+            // if the current section has no own frame search for the children
+            if(!pFrm)
+            {
+                SwClientIter aFormatIter( *(SwSectionFmt*)this );
+                SwSectionFmt* pChild = (SwSectionFmt*)aFormatIter.
+                                                First( TYPE(SwSectionFmt) );
+                while(pChild && !pFrm)
+                {
+                    pFrm = (SwFrm*)SwClientIter( *pChild ).First( TYPE(SwFrm) );
+                    pChild = (SwSectionFmt*)aFormatIter.Next();
+                }
+            }
+            ((SwPtrMsgPoolItem&)rInfo).pObject = pFrm;
+        }
+        return FALSE;
+    }
+    return SwModify::GetInfo( rInfo );
+}
+
+extern "C" {
+
+    int
+#if defined( WNT )
+     __cdecl
+#endif
+#if defined( ICC )
+     _Optlink
+#endif
+        lcl_SectionCmpPos( const void *pFirst, const void *pSecond)
+    {
+        const SwSectionFmt* pFSectFmt = (*(SwSectionPtr*)pFirst)->GetFmt();
+        const SwSectionFmt* pSSectFmt = (*(SwSectionPtr*)pSecond)->GetFmt();
+        ASSERT( pFSectFmt && pSSectFmt &&
+                pFSectFmt->GetCntnt(FALSE).GetCntntIdx() &&
+                pSSectFmt->GetCntnt(FALSE).GetCntntIdx(),
+                    "ungueltige Sections" );
+        return (int)((long)pFSectFmt->GetCntnt(FALSE).GetCntntIdx()->GetIndex()) -
+                      pSSectFmt->GetCntnt(FALSE).GetCntntIdx()->GetIndex();
+    }
+
+    int
+#if defined( WNT )
+     __cdecl
+#endif
+#if defined( ICC )
+     _Optlink
+#endif
+        lcl_SectionCmpNm( const void *pFirst, const void *pSecond)
+    {
+        const SwSectionPtr pFSect = *(SwSectionPtr*)pFirst;
+        const SwSectionPtr pSSect = *(SwSectionPtr*)pSecond;
+        ASSERT( pFSect && pSSect, "ungueltige Sections" );
+        StringCompare eCmp = pFSect->GetName().CompareTo( pSSect->GetName() );
+        return eCmp == COMPARE_EQUAL ? 0
+                            : eCmp == COMPARE_LESS ? 1 : -1;
+    }
+}
+
+    // alle Sections, die von dieser abgeleitet sind
+USHORT SwSectionFmt::GetChildSections( SwSections& rArr,
+                                        SectionSort eSort,
+                                        int bAllSections ) const
+{
+    rArr.Remove( 0, rArr.Count() );
+
+    if( GetDepends() )
+    {
+        SwClientIter aIter( *(SwSectionFmt*)this );
+        SwClient * pLast;
+        const SwNodeIndex* pIdx;
+        for( pLast = aIter.First(TYPE(SwSectionFmt)); pLast; pLast = aIter.Next() )
+            if( bAllSections ||
+                ( 0 != ( pIdx = ((SwSectionFmt*)pLast)->GetCntnt(FALSE).
+                GetCntntIdx()) && &pIdx->GetNodes() == &GetDoc()->GetNodes() ))
+            {
+                const SwSection* Dummy=((SwSectionFmt*)pLast)->GetSection();
+                rArr.C40_INSERT( SwSection,
+                    Dummy,
+                    rArr.Count() );
+            }
+
+        // noch eine Sortierung erwuenscht ?
+        if( 1 < rArr.Count() )
+            switch( eSort )
+            {
+            case SORTSECT_NAME:
+                qsort( (void*)rArr.GetData(),
+                        rArr.Count(),
+                        sizeof( SwSectionPtr ),
+                        lcl_SectionCmpNm );
+                break;
+
+            case SORTSECT_POS:
+                qsort( (void*)rArr.GetData(),
+                        rArr.Count(),
+                        sizeof( SwSectionPtr ),
+                        lcl_SectionCmpPos );
+                break;
+            }
+    }
+    return rArr.Count();
+}
+
+    // erfrage, ob sich die Section im Nodes-Array oder UndoNodes-Array
+    // befindet.
+int SwSectionFmt::IsInNodesArr() const
+{
+    const SwNodeIndex* pIdx = GetCntnt(FALSE).GetCntntIdx();
+    return pIdx && &pIdx->GetNodes() == &GetDoc()->GetNodes();
+}
+
+
+void SwSectionFmt::UpdateParent()       // Parent wurde veraendert
+{
+    if( !GetDepends() )
+        return;
+
+    SwSectionPtr pSection = 0;
+    const SvxProtectItem* pProtect;
+    int bIsHidden = FALSE;
+
+    SwClientIter aIter( *this );
+    SwClient * pLast = aIter.GoStart();
+    if( pLast )     // konnte zum Anfang gesprungen werden ??
+        do {
+            if( pLast->IsA( TYPE(SwSectionFmt) ) )
+            {
+                if( !pSection )
+                {
+                    pSection = GetSection();
+                    if( GetRegisteredIn() )
+                    {
+                        const SwSectionPtr pPS = GetParentSection();
+                        pProtect = &pPS->GetFmt()->GetProtect();
+                        bIsHidden = pPS->IsHiddenFlag();
+                    }
+                    else
+                    {
+                        pProtect = &GetProtect();
+                        bIsHidden = pSection->IsHidden();
+                    }
+                }
+                if( pProtect->IsCntntProtected() !=
+                    pSection->IsProtectFlag() )
+                    pLast->Modify( (SfxPoolItem*)pProtect,
+                                    (SfxPoolItem*)pProtect );
+
+                if( bIsHidden == pSection->IsHiddenFlag() )
+                {
+                    SwMsgPoolItem aMsgItem( bIsHidden
+                                ? RES_SECTION_HIDDEN
+                                : RES_SECTION_NOT_HIDDEN );
+                    pLast->Modify( &aMsgItem, &aMsgItem );
+                }
+            }
+            else if( !pSection &&
+                    pLast->IsA( TYPE(SwSection) ) )
+            {
+                pSection = (SwSectionPtr)pLast;
+                if( GetRegisteredIn() )
+                {
+                    const SwSectionPtr pPS = GetParentSection();
+                    pProtect = &pPS->GetFmt()->GetProtect();
+                    bIsHidden = pPS->IsHiddenFlag();
+                }
+                else
+                {
+                    pProtect = &GetProtect();
+                    bIsHidden = pSection->IsHidden();
+                }
+            }
+        } while( 0 != ( pLast = aIter++ ));
+}
+
+
+SwSectionNode* SwSectionFmt::GetSectionNode( BOOL bAlways )
+{
+    const SwNodeIndex* pIdx = GetCntnt(FALSE).GetCntntIdx();
+    if( pIdx && ( bAlways || &pIdx->GetNodes() == &GetDoc()->GetNodes() ))
+        return pIdx->GetNode().GetSectionNode();
+    return 0;
+}
+
+    // ist die Section eine gueltige fuers GlobalDocument?
+const SwSection* SwSectionFmt::GetGlobalDocSection() const
+{
+    const SwSectionNode* pNd = GetSectionNode();
+    if( pNd &&
+        ( FILE_LINK_SECTION == pNd->GetSection().GetType() ||
+          TOX_CONTENT_SECTION == pNd->GetSection().GetType() ) &&
+        pNd->GetIndex() > pNd->GetNodes().GetEndOfExtras().GetIndex() &&
+        !pNd->FindStartNode()->IsSectionNode() &&
+        !pNd->FindStartNode()->FindSectionNode() )
+        return &pNd->GetSection();
+    return 0;
+}
+
+void lcl_UpdateLinksInSect( SwBaseLink& rUpdLnk, SwSectionNode& rSectNd )
+{
+    SwDoc* pDoc = rSectNd.GetDoc();
+    SwDocShell* pDShell = pDoc->GetDocShell();
+    if( !pDShell || !pDShell->GetMedium() )
+        return ;
+
+    String sName( pDShell->GetMedium()->GetName() );
+    SwBaseLink* pBLink;
+    SvData aEmptyData( FORMAT_FILE );
+    aEmptyData.SetData( sName );        // beliebiger Name
+
+    const SvBaseLinks& rLnks = pDoc->GetLinkManager().GetLinks();
+    for( USHORT n = rLnks.Count(); n; )
+    {
+        SvBaseLink* pLnk = &(*rLnks[ --n ]);
+        if( pLnk && pLnk != &rUpdLnk &&
+            OBJECT_CLIENT_FILE == pLnk->GetObjType() &&
+            pLnk->ISA( SwBaseLink ) &&
+            ( pBLink = (SwBaseLink*)pLnk )->IsInRange( rSectNd.GetIndex(),
+                                                rSectNd.EndOfSectionIndex() ) )
+        {
+            // liegt in dem Bereich: also updaten. Aber nur wenns nicht
+            // im gleichen File liegt
+            String sFName;
+            pDoc->GetLinkManager().GetDisplayNames( *pBLink, 0, &sFName, 0, 0 );
+            if( sFName != sName )
+            {
+                pBLink->DataChanged( aEmptyData );
+
+                // ggfs. neu den Link-Pointer wieder suchen, damit nicht einer
+                // ausgelassen oder doppelt gerufen wird.
+                if( n >= rLnks.Count() && 0 != ( n = rLnks.Count() ))
+                    --n;
+
+                if( n && pLnk != &(*rLnks[ n ]) )
+                {
+                    // suchen - kann nur davor liegen!!
+                    while( n )
+                        if( pLnk == &(*rLnks[ --n ] ) )
+                            break;
+                }
+            }
+        }
+    }
+}
+
+
+// sucht sich die richtige DocShell raus oder erzeugt eine neue:
+// Der Return-Wert gibt an, was mit der Shell zu geschehen hat:
+//  0 - Fehler, konnte DocShell nicht finden
+//  1 - DocShell ist ein existieren Document
+//  2 - DocShell wurde neu angelegt, muss also wieder geschlossen werden
+
+int lcl_FindDocShell( SfxObjectShellRef& xDocSh,
+                        const String& rFileName,
+                        const String& rPasswd,
+                        String& rFilter,
+                        INT16 nVersion,
+                        SwDocShell* pDestSh )
+{
+    if( !rFileName.Len() )
+        return 0;
+
+    // 1. existiert die Datei schon in der Liste aller Dokumente?
+    INetURLObject aTmpObj( rFileName );
+    aTmpObj.SetMark( aEmptyStr );
+
+    // erstmal nur ueber die DocumentShells laufen und die mit dem
+    // Namen heraussuchen:
+    TypeId aType( TYPE(SwDocShell) );
+
+    SfxObjectShell* pShell = pDestSh;
+    BOOL bFirst = 0 != pShell;
+
+    if( !bFirst )
+        // keine DocShell uebergeben, also beginne mit der ersten aus der
+        // DocShell Liste
+        pShell = SfxObjectShell::GetFirst( &aType );
+
+    while( pShell )
+    {
+        // die wollen wir haben
+        SfxMedium* pMed = pShell->GetMedium();
+        if( pMed && pMed->GetURLObject() == aTmpObj )
+        {
+            const SfxPoolItem* pItem;
+            if( ( SFX_ITEM_SET == pMed->GetItemSet()->GetItemState(
+                                            SID_VERSION, FALSE, &pItem ) )
+                    ? (nVersion == ((SfxInt16Item*)pItem)->GetValue())
+                    : !nVersion )
+            {
+                // gefunden also returnen
+                xDocSh = pShell;
+                return 1;
+            }
+        }
+
+        if( bFirst )
+        {
+            bFirst = FALSE;
+            pShell = SfxObjectShell::GetFirst( &aType );
+        }
+        else
+            pShell = SfxObjectShell::GetNext( *pShell, &aType );
+    }
+
+    // 2. selbst die Date oeffnen
+    SfxMedium* pMed = new SfxMedium( aTmpObj.GetMainURL(), STREAM_READ, TRUE );
+    if( INET_PROT_FILE == aTmpObj.GetProtocol() )
+        pMed->DownLoad();     // nur mal das Medium anfassen (DownLoaden)
+
+    if( pMed->GetError() || !pMed->Exists() )
+    {
+        delete pMed;
+        return 0;
+    }
+
+    // kein Filter, dann suche ihn. Ansonsten teste, ob der angegebene ein
+    // gueltiger ist
+    const SfxFilter* pSfxFlt = 0;
+    if( rFilter.Len() )
+    {
+        pSfxFlt =  SwIoSystem::GetFilterOfFilterTxt( rFilter );
+        if( pSfxFlt && !SwIoSystem::IsFileFilter( *pMed, pSfxFlt->GetUserData() ))
+            pSfxFlt = 0;        // dann neu detecten lassen
+    }
+
+    if( !pSfxFlt )
+        pSfxFlt = SwIoSystem::GetFileFilter( pMed->GetPhysicalName(), aEmptyStr );
+
+    if( pSfxFlt )
+    {
+        // ohne Filter geht gar nichts
+        pMed->SetFilter( pSfxFlt );
+
+        if( nVersion )
+            pMed->GetItemSet()->Put( SfxInt16Item( SID_VERSION, nVersion ));
+
+        if( rPasswd.Len() )
+            pMed->GetItemSet()->Put( SfxStringItem( SID_PASSWORD, rPasswd ));
+
+        xDocSh = new SwDocShell( SFX_CREATE_MODE_INTERNAL );
+        if( xDocSh->DoLoad( pMed ) )
+            return 2;
+//      InfoBox( 0, ResId(ERR_CLPBRD_READ) ).Execute();
+    }
+
+    if( !xDocSh.Is() )      // Medium muss noch geloescht werden
+        delete pMed;
+
+    return 0;   // das war wohl nichts
+}
+
+
+void SwIntrnlSectRefLink::DataChanged( SvData& rData )
+{
+    SwSectionNode* pSectNd = rSectFmt.GetSectionNode( FALSE );
+    SwDoc* pDoc = rSectFmt.GetDoc();
+
+    ULONG nDataFormat = rData.GetFormat();
+
+    if( !pSectNd || !pDoc || pDoc->IsInDtor() || ChkNoDataFlag() ||
+        SvxLinkManager::RegisterStatusInfoId() == nDataFormat )
+    {
+        // sollten wir schon wieder im Undo stehen?
+
+        return ;
+    }
+
+    // Undo immer abschalten
+    BOOL bWasUndo = pDoc->DoesUndo();
+    pDoc->DoUndo( FALSE );
+    BOOL bWasVisibleLinks = pDoc->IsVisibleLinks();
+    pDoc->SetVisibleLinks( FALSE );
+
+    SwPaM* pPam;
+    ViewShell* pVSh = 0;
+    SwEditShell* pESh = pDoc->GetEditShell( &pVSh );
+    pDoc->LockExpFlds();
+    {
+        // am Anfang des Bereichs einen leeren TextNode einfuegen
+        SwNodeIndex aIdx( *pSectNd, +1 );
+        SwNodeIndex aEndIdx( *pSectNd->EndOfSectionNode() );
+        SwTxtNode* pNewNd = pDoc->GetNodes().MakeTxtNode( aIdx,
+                        pDoc->GetTxtCollFromPool( RES_POOLCOLL_TEXT ) );
+
+        if( pESh )
+            pESh->StartAllAction();
+        else if( pVSh )
+            pVSh->StartAction();
+
+        SwPosition aPos( aIdx, SwIndex( pNewNd, 0 ));
+        aPos.nNode--;
+        pDoc->CorrAbs( aIdx, aEndIdx, aPos, TRUE );
+
+        pPam = new SwPaM( aPos );
+
+        //und alles dahinter liegende loeschen
+        aIdx--;
+        DelFlyInRange( aIdx, aEndIdx );
+        _DelBookmarks( aIdx, aEndIdx );
+        aIdx++;
+
+        pDoc->GetNodes().Delete( aIdx, aEndIdx.GetIndex() - aIdx.GetIndex() );
+    }
+
+    SwSection& rSection = pSectNd->GetSection();
+    rSection.SetConnectFlag( FALSE );
+
+    String sFileName;
+    Reader* pRead = 0;
+    switch( nDataFormat )
+    {
+    case FORMAT_STRING:
+        pRead = ReadAscii;
+        break;
+
+    case FORMAT_RTF:
+        pRead = ReadRtf;
+        break;
+
+    case FORMAT_FILE:
+        if( rData.GetData( sFileName ) )
+        {
+            String sFilter, sRange;
+            pDoc->GetLinkManager().GetDisplayNames( *this, 0, &sFileName,
+                                                    &sRange, &sFilter );
+
+            SwRedlineMode eOldRedlineMode = REDLINE_NONE;
+            SfxObjectShellRef xDocSh;
+            int nRet;
+            if( !sFileName.Len() )
+            {
+                xDocSh = pDoc->GetDocShell();
+                nRet = 1;
+            }
+            else
+            {
+                nRet = lcl_FindDocShell( xDocSh, sFileName,
+                                    rSection.GetLinkFilePassWd(),
+                                    sFilter, 0, pDoc->GetDocShell() );
+                if( nRet )
+                {
+                    SwDoc* pSrcDoc = ((SwDocShell*)&xDocSh)->GetDoc();
+                    eOldRedlineMode = pSrcDoc->GetRedlineMode();
+                    pSrcDoc->SetRedlineMode( REDLINE_SHOW_INSERT );
+                }
+            }
+
+            if( nRet )
+            {
+                rSection.SetConnectFlag( TRUE );
+
+                SwNodeIndex aSave( pPam->GetPoint()->nNode, -1 );
+                SwNodeRange* pCpyRg = 0;
+
+                if( xDocSh->GetMedium() &&
+                    !rSection.GetLinkFilePassWd().Len() )
+                {
+                    const SfxPoolItem* pItem;
+                    if( SFX_ITEM_SET == xDocSh->GetMedium()->GetItemSet()->
+                        GetItemState( SID_PASSWORD, FALSE, &pItem ) )
+                        rSection.SetLinkFilePassWd(
+                                ((SfxStringItem*)pItem)->GetValue() );
+                }
+
+                SwDoc* pSrcDoc = ((SwDocShell*)&xDocSh)->GetDoc();
+
+                if( sRange.Len() )
+                {
+                    // Rekursionen abfangen
+                    BOOL bRecursion = FALSE;
+                    if( pSrcDoc == pDoc )
+                    {
+                        SwServerObjectRef refObj( pDoc->CreateHotLink( sRange ));
+                        if( refObj.Is() )
+                        {
+                            bRecursion = refObj->IsLinkInServer( this ) ||
+                                        ChkNoDataFlag();
+                        }
+                    }
+
+                    SwNodeIndex& rInsPos = pPam->GetPoint()->nNode;
+
+                    SwPaM* pCpyPam = 0;
+                    if( !bRecursion &&
+                        pSrcDoc->SelectServerObj( sRange, pCpyPam, pCpyRg )
+                        && pCpyPam )
+                    {
+                        if( pSrcDoc != pDoc ||
+                            pCpyPam->Start()->nNode > rInsPos ||
+                            rInsPos >= pCpyPam->End()->nNode )
+                            pSrcDoc->Copy( *pCpyPam, *pPam->GetPoint() );
+                        delete pCpyPam;
+                    }
+                    if( pCpyRg && pSrcDoc == pDoc &&
+                        pCpyRg->aStart < rInsPos && rInsPos < pCpyRg->aEnd )
+                        delete pCpyRg, pCpyRg = 0;
+                }
+                else if( pSrcDoc != pDoc )
+                    pCpyRg = new SwNodeRange( pSrcDoc->GetNodes().GetEndOfExtras(), 2,
+                                          pSrcDoc->GetNodes().GetEndOfContent() );
+
+                if( pCpyRg )
+                {
+                    SwNodeIndex& rInsPos = pPam->GetPoint()->nNode;
+                    BOOL bCreateFrm = rInsPos.GetIndex() <=
+                                pDoc->GetNodes().GetEndOfExtras().GetIndex() ||
+                                rInsPos.GetNode().FindTableNode();
+
+                    SwTblNumFmtMerge aTNFM( *pSrcDoc, *pDoc );
+
+                    pSrcDoc->CopyWithFlyInFly( *pCpyRg, rInsPos, bCreateFrm );
+                    aSave++;
+
+                    if( !bCreateFrm )
+                        ::MakeFrms( pDoc, aSave, rInsPos );
+
+                    // den letzten Node noch loeschen, aber nur wenn
+                    // erfolgreich kopiert werden konnte, also der Bereich
+                    // mehr als 1 Node enthaelt
+                    if( 2 < pSectNd->EndOfSectionIndex() - pSectNd->GetIndex() )
+                    {
+                        aSave = rInsPos;
+                        pPam->Move( fnMoveBackward, fnGoNode );
+                        pPam->SetMark();    // beide SwPositions ummelden!
+
+                        pDoc->CorrAbs( aSave, *pPam->GetPoint(), 0, TRUE );
+                        pDoc->GetNodes().Delete( aSave, 1 );
+                    }
+                    delete pCpyRg;
+                }
+
+                // update alle Links in diesem Bereich
+                lcl_UpdateLinksInSect( *this, *pSectNd );
+            }
+            if( xDocSh.Is() )
+            {
+                if( 2 == nRet )
+                    xDocSh->DoClose();
+                else
+                    ((SwDocShell*)&xDocSh)->GetDoc()->SetRedlineMode(
+                                eOldRedlineMode );
+            }
+        }
+        break;
+    }
+
+    if( pESh && pRead )     // !!!! DDE nur updaten wenn Shell vorhanden ist??
+    {
+        pESh->Push();
+        *pESh->GetCrsr()->GetPoint() = *pPam->GetPoint();
+        delete pPam, pPam = 0;
+
+        SvStorageStreamRef aStrm( new SvStorageStream( aEmptyStr ));
+        rData.GetData( aStrm, TRANSFER_REFERENCE );
+        SwReader aTmpReader( *aStrm, aEmptyStr, *pESh->GetCrsr() );
+
+        if( IsError( aTmpReader.Read( *pRead ) ))
+        {
+//          InfoBox( 0, ResId(ERR_CLPBRD_READ) ).Execute();
+//          bOk = FALSE;
+        }
+        else
+            rSection.SetConnectFlag( TRUE );
+
+        pESh->Pop( FALSE );
+    }
+
+
+    // Alle UndoActions entfernen und Undo wieder einschalten
+    pDoc->DelAllUndoObj();
+    pDoc->DoUndo( bWasUndo );
+    pDoc->SetVisibleLinks( bWasVisibleLinks );
+
+    pDoc->UnlockExpFlds();
+    if( !pDoc->IsExpFldsLocked() )
+        pDoc->UpdateExpFlds();
+
+    if( pESh )
+        pESh->EndAllAction();
+    else if( pVSh )
+        pVSh->EndAction();
+    delete pPam;            // wurde am Anfang angelegt
+}
+
+
+void SwIntrnlSectRefLink::Closed()
+{
+    SwDoc* pDoc = rSectFmt.GetDoc();
+    if( pDoc && !pDoc->IsInDtor() )
+    {
+        // Advise verabschiedet sich, den Bereich als nicht geschuetzt
+        // kennzeichnen und das Flag umsetzen
+
+        const SwSectionFmts& rFmts = pDoc->GetSections();
+        for( USHORT n = rFmts.Count(); n; )
+            if( rFmts[ --n ] == &rSectFmt )
+            {
+                ViewShell* pSh;
+                SwEditShell* pESh = pDoc->GetEditShell( &pSh );
+
+                if( pESh )
+                    pESh->StartAllAction();
+                else
+                    pSh->StartAction();
+
+                SwSection aSect( CONTENT_SECTION, aEmptyStr );
+                aSect = *rSectFmt.GetSection();
+                aSect.SetType( CONTENT_SECTION );
+                aSect.SetLinkFileName( aEmptyStr );
+                aSect.SetHidden( FALSE );
+                aSect.SetProtect( FALSE );
+                aSect.SetConnectFlag( FALSE );
+
+                pDoc->ChgSection( n, aSect );
+
+                // alle in der Section liegenden Links werden sichtbar
+                SwSectionNode* pSectNd = rSectFmt.GetSectionNode( FALSE );
+                if( pSectNd )
+                    pSectNd->GetSection().MakeChildLinksVisible( *pSectNd );
+
+                if( pESh )
+                    pESh->EndAllAction();
+                else
+                    pSh->EndAction();
+                break;
+            }
+    }
+    SvBaseLink::Closed();
+}
+
+
+void SwSection::CreateLink( LinkCreateType eCreateType )
+{
+    SwSectionFmt* pFmt = GetFmt();
+    if( !pFmt || CONTENT_SECTION == eType )
+        return ;
+
+    USHORT nUpdateType = LINKUPDATE_ALWAYS;
+
+    if( !refLink.Is() )
+        // dann mal den BaseLink aufbauen
+        refLink = new SwIntrnlSectRefLink( *pFmt, nUpdateType, FORMAT_RTF );
+    else
+        // sonst aus dem Linkmanager entfernen
+        pFmt->GetDoc()->GetLinkManager().Remove( *refLink );
+
+    SwIntrnlSectRefLink* pLnk = (SwIntrnlSectRefLink*)&refLink;
+
+    String sCmd( sLinkFileName );
+    xub_StrLen nPos;
+    while( STRING_NOTFOUND != (nPos = sCmd.SearchAscii( "  " )) )
+        sCmd.Erase( nPos, 1 );
+
+    pLnk->SetUpdateMode( nUpdateType );
+    pLnk->SetVisible( pFmt->GetDoc()->IsVisibleLinks() );
+
+    switch( eType )
+    {
+    case DDE_LINK_SECTION:
+        pLnk->SetLinkSourceName( new SvLinkName( sCmd ) );
+        pFmt->GetDoc()->GetLinkManager().InsertDDELink( *pLnk );
+        break;
+    case FILE_LINK_SECTION:
+        {
+            pLnk->SetContentType( FORMAT_FILE );
+            String sFltr( sCmd.GetToken( 1, cTokenSeperator ) );
+            String sRange( sCmd.GetToken( 2, cTokenSeperator ) );
+            pFmt->GetDoc()->GetLinkManager().InsertFileLink( *pLnk, eType,
+                                sCmd.GetToken( 0, cTokenSeperator ),
+                                ( sFltr.Len() ? &sFltr : 0 ),
+                                ( sRange.Len() ? &sRange : 0 ) );
+        }
+        break;
+    default:
+        ASSERT( !this, "Was ist das fuer ein Link?" )
+    }
+
+    switch( eCreateType )
+    {
+    case CREATE_CONNECT:            // Link gleich connecten
+        pLnk->Connect();
+        break;
+
+    case CREATE_UPDATE:         // Link connecten und updaten
+        pLnk->Update();
+        break;
+    }
+}
+
+const SwNode* SwIntrnlSectRefLink::GetAnchor() const
+{
+    return rSectFmt.GetSectionNode( FALSE );
+}
+
+
+BOOL SwIntrnlSectRefLink::IsInRange( ULONG nSttNd, ULONG nEndNd,
+                                     xub_StrLen nStt, xub_StrLen nEnd ) const
+{
+    SwStartNode* pSttNd = rSectFmt.GetSectionNode( FALSE );
+    return pSttNd &&
+            nSttNd < pSttNd->GetIndex() &&
+            pSttNd->EndOfSectionIndex() < nEndNd;
+}
+
+
+
diff --git a/sw/source/core/docnode/swbaslnk.cxx b/sw/source/core/docnode/swbaslnk.cxx
new file mode 100644
index 000000000000..78edb6856f39
--- /dev/null
+++ b/sw/source/core/docnode/swbaslnk.cxx
@@ -0,0 +1,850 @@
+/*************************************************************************
+ *
+ *  $RCSfile: swbaslnk.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:18 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#define ITEMID_BOXINFO      SID_ATTR_BORDER_INNER
+
+#include 
+
+#ifndef _LNKBASE_HXX //autogen
+#include 
+#endif
+#ifndef _SOT_DTRANS_HXX //autogen
+#include 
+#endif
+#ifndef _LINKMGR_HXX
+#include 
+#endif
+#ifndef _SFX_OBJSH_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BOXITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_SVXIDS_HRC
+#include        // fuer die EventIds
+#endif
+#ifndef _SVXLINKMGR_HXX
+#include 
+#endif
+#ifndef _SOERR_HXX
+#include 
+#endif
+
+#ifndef _FMTFSIZE_HXX //autogen
+#include 
+#endif
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _FRMATR_HXX
+#include 
+#endif
+#ifndef _FRMFMT_HXX //autogen
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _EDITSH_HXX
+#include 
+#endif
+#ifndef _SWTABLE_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _SWEVENT_HXX
+#include 
+#endif
+#ifndef _SWBASLNK_HXX
+#include 
+#endif
+#ifndef _SWSERV_HXX
+#include 
+#endif
+#ifndef _NDGRF_HXX
+#include 
+#endif
+#ifndef _NDOLE_HXX
+#include 
+#endif
+#ifndef _HINTS_HXX
+#include 
+#endif
+#ifndef _TABFRM_HXX
+#include 
+#endif
+#ifndef _HTMLTBL_HXX
+#include 
+#endif
+
+BOOL SetGrfFlySize( const Size& rGrfSz, SwGrfNode* pGrfNd );
+
+TYPEINIT1(SwBaseLink,SvBaseLink);
+
+SO2_IMPL_REF( SwServerObject )
+
+SwBaseLink::~SwBaseLink()
+{
+}
+
+/*  */
+// Code for the new GraphicObject
+#ifdef USE_GRFOBJECT
+
+
+void SwBaseLink::DataChanged( SvData& rData )
+{
+    if( !pCntntNode )
+    {
+        ASSERT(!this, "DataChanged ohne ContentNode" );
+        return ;
+    }
+
+    SwDoc* pDoc = pCntntNode->GetDoc();
+    if( pDoc->IsInDtor() || ChkNoDataFlag() || bIgnoreDataChanged )
+    {
+        bIgnoreDataChanged = FALSE;
+        return ;
+    }
+
+    if( pCntntNode->IsNoTxtNode() &&
+        rData.GetFormat() == SvxLinkManager::RegisterStatusInfoId() )
+    {
+        // nur eine Statusaenderung - Events bedienen ?
+        String sState;
+        if( rData.GetData( sState ))
+        {
+            USHORT nEvent = 0;
+            switch( sState.ToInt32() )
+            {
+            case STATE_LOAD_OK:     nEvent = SVX_EVENT_IMAGE_LOAD;  break;
+            case STATE_LOAD_ERROR:  nEvent = SVX_EVENT_IMAGE_ERROR; break;
+            case STATE_LOAD_ABORT:  nEvent = SVX_EVENT_IMAGE_ABORT; break;
+            }
+
+            SwFrmFmt* pFmt;
+            if( nEvent && 0 != ( pFmt = pCntntNode->GetFlyFmt() ))
+            {
+                SwCallMouseEvent aCallEvent;
+                aCallEvent.Set( EVENT_OBJECT_IMAGE, pFmt );
+                pDoc->CallEvent( nEvent, aCallEvent );
+            }
+        }
+        return;         // das wars!
+    }
+
+    FASTBOOL bUpdate = FALSE;
+    FASTBOOL bGraphicArrived = FALSE;
+    FASTBOOL bGraphicPieceArrived = FALSE;
+    FASTBOOL bDontNotify = FALSE;
+    Size aGrfSz;
+
+    if( pCntntNode->IsGrfNode() )
+    {
+        GraphicObject& rGrfObj = ((SwGrfNode*)pCntntNode)->GetGrfObj();
+
+        bDontNotify = ((SwGrfNode*)pCntntNode)->IsFrameInPaint();
+
+        ULONG nUpDateState = GetObj()->GetUpToDateStatus();
+        ((SwGrfNode*)pCntntNode)->SetGrafikArrived( ERRCODE_NONE == nUpDateState );
+
+        bGraphicArrived = ERRCODE_NONE == nUpDateState;
+        bGraphicPieceArrived = ERRCODE_SO_PENDING == nUpDateState;
+
+        switch( rData.GetFormat() )
+        {
+        case FORMAT_GDIMETAFILE:
+            {
+                GDIMetaFile *pMetaFile;
+                if( rData.GetData( &pMetaFile, TRANSFER_REFERENCE ) )
+                {
+                    rGrfObj.SetGraphic( *pMetaFile, rGrfObj.GetLink() );
+                    bUpdate = TRUE;
+                }
+            }
+            break;
+
+        case FORMAT_BITMAP:
+            {
+                Bitmap *pBmp;
+                if( rData.GetData( &pBmp, TRANSFER_REFERENCE ) )
+                {
+                    Graphic aEmptyGrf;
+                    if( aEmptyGrf.GetBitmap() != *pBmp )
+                        aEmptyGrf = *pBmp;
+                    rGrfObj.SetGraphic( aEmptyGrf, rGrfObj.GetLink() );
+
+                    bUpdate = TRUE;
+                }
+            }
+            break;
+
+        default:
+            if( rData.GetFormat() == Graphic::RegisterClipboardFormatName() ||
+                FORMAT_PRIVATE == rData.GetFormat() )
+            {
+                Graphic* pGrf;
+                if( rData.GetData( (SvDataCopyStream **)&pGrf,
+                                    Graphic::StaticType(),
+                                    TRANSFER_REFERENCE ) &&
+                    ( GRAPHIC_DEFAULT != pGrf->GetType() ||
+                      GRAPHIC_DEFAULT != rGrfObj.GetType() ) )
+                {
+                    aGrfSz = ::GetGraphicSizeTwip( *pGrf, 0 );
+                    Size aSz( ((SwGrfNode*)pCntntNode)->GetTwipSize() );
+
+                    if( bGraphicPieceArrived &&
+                        GRAPHIC_DEFAULT != pGrf->GetType() &&
+                        ( !aSz.Width() || !aSz.Height() ) )
+                    {
+                        // wenn nur ein Teil ankommt, aber die Groesse nicht
+                        // gesetzt ist, dann muss "unten" der Teil von
+                        // bGraphicArrived durchlaufen werden!
+                        // (ansonten wird die Grafik in deft. Size gepaintet)
+                        bGraphicArrived = TRUE;
+                        bGraphicPieceArrived = FALSE;
+                    }
+                    rGrfObj.SetGraphic( *pGrf, rGrfObj.GetLink() );
+
+                    bUpdate = TRUE;
+
+                    // Bug 33999: damit der Node den Transparent-Status
+                    //      richtig gesetzt hat, ohne auf die Grafik
+                    //      zugreifen zu muessen (sonst erfolgt ein SwapIn!).
+                    if( bGraphicArrived )
+                    {
+                        // Bug #34735#: immer mit der korrekten Grafik-Size
+                        //              arbeiten
+                        if( aGrfSz.Height() && aGrfSz.Width() &&
+                            aSz.Height() && aSz.Width() &&
+                            aGrfSz != aSz )
+                            ((SwGrfNode*)pCntntNode)->SetTwipSize( aGrfSz );
+                    }
+                }
+            }
+            break;
+        }
+        if ( bUpdate && !bGraphicArrived && !bGraphicPieceArrived )
+            ((SwGrfNode*)pCntntNode)->SetTwipSize( Size(0,0) );
+    }
+    else if( pCntntNode->IsOLENode() )
+        bUpdate = TRUE;
+
+    ViewShell *pSh = 0;
+    SwEditShell* pESh = pDoc->GetEditShell( &pSh );
+
+    if ( bUpdate && bGraphicPieceArrived && !(bSwapIn || bDontNotify) )
+    {
+        //Hint ohne Actions verschicken, loest direktes Paint aus.
+        if ( (!pSh || !pSh->ActionPend()) && (!pESh || !pESh->ActionPend()) )
+        {
+            SwMsgPoolItem aMsgHint( RES_GRAPHIC_PIECE_ARRIVED );
+            pCntntNode->Modify( &aMsgHint, &aMsgHint );
+            bUpdate = FALSE;
+        }
+    }
+
+    static BOOL bInNotifyLinks = FALSE;
+    if( bUpdate && !bDontNotify && (!bSwapIn || bGraphicArrived) &&
+        !bInNotifyLinks)
+    {
+        BOOL bLockView = FALSE;
+        if( pSh )
+        {
+            bLockView = pSh->IsViewLocked();
+            pSh->LockView( TRUE );
+        }
+
+        if( pESh )
+            pESh->StartAllAction();
+        else if( pSh )
+            pSh->StartAction();
+
+        SwMsgPoolItem aMsgHint( bGraphicArrived ? RES_GRAPHIC_ARRIVED :
+                                                  RES_UPDATE_ATTR );
+
+        if ( bGraphicArrived )
+        {
+            //Alle benachrichtigen, die am gleichen Link horchen.
+            bInNotifyLinks = TRUE;
+
+            const SvBaseLinks& rLnks = pDoc->GetLinkManager().GetLinks();
+            for( USHORT n = rLnks.Count(); n; )
+            {
+                SvBaseLink* pLnk = &(*rLnks[ --n ]);
+                if( pLnk && OBJECT_CLIENT_GRF == pLnk->GetObjType() &&
+                    pLnk->ISA( SwBaseLink ) && pLnk->GetObj() == GetObj() )
+                {
+                    SwBaseLink* pBLink = (SwBaseLink*)pLnk;
+                    SwGrfNode* pGrfNd = (SwGrfNode*)pBLink->pCntntNode;
+
+                    if( pBLink != this &&
+                        ( !bSwapIn ||
+                            GRAPHIC_DEFAULT == pGrfNd->GetGrfObj().GetType()))
+                    {
+                        pBLink->bIgnoreDataChanged = FALSE;
+                        pBLink->DataChanged( rData );
+                        pBLink->bIgnoreDataChanged = TRUE;
+
+                        pGrfNd->SetGrafikArrived( ((SwGrfNode*)pCntntNode)->
+                                                    IsGrafikArrived() );
+
+                        // Fly der Grafik anpassen !
+                        if( !::SetGrfFlySize( aGrfSz, pGrfNd ) )
+                            pGrfNd->Modify( &aMsgHint, &aMsgHint );
+                    }
+                    else if( pBLink == this &&
+                            !::SetGrfFlySize( aGrfSz, pGrfNd ) )
+                        // Fly der Grafik anpassen !
+                        pGrfNd->Modify( &aMsgHint, &aMsgHint );
+                }
+            }
+
+            bInNotifyLinks = FALSE;
+        }
+        else
+        {
+            pCntntNode->Modify( &aMsgHint, &aMsgHint );
+        }
+
+
+        if( pESh )
+        {
+            const BOOL bEndActionByVirDev = pESh->IsEndActionByVirDev();
+            pESh->SetEndActionByVirDev( TRUE );
+            pESh->EndAllAction();
+            pESh->SetEndActionByVirDev( bEndActionByVirDev );
+        }
+        else if( pSh )
+            pSh->EndAction();
+
+        if( pSh && !bLockView )
+            pSh->LockView( FALSE );
+    }
+}
+
+FASTBOOL SwBaseLink::IsShowQuickDrawBmp() const
+{
+    return pCntntNode && pCntntNode->IsGrfNode() &&
+#ifdef NEW_GRFOBJ
+            ((SwGrfNode*)pCntntNode)->HasMagicId()
+#else
+            // wie kommt man an die Info dran, das eine Grafik im Cache steht?
+            FALSE
+#endif
+        ;
+}
+
+/*  */
+#else
+// USE_GRFOBJECT
+
+#ifndef _GRFCACHE_HXX
+#include 
+#endif
+
+void SwBaseLink::DataChanged( SvData& rData )
+{
+    if( !pCntntNode )
+    {
+        ASSERT(!this, "DataChanged ohne ContentNode" );
+        return ;
+    }
+
+    SwDoc* pDoc = pCntntNode->GetDoc();
+    if( pDoc->IsInDtor() || ChkNoDataFlag() || bIgnoreDataChanged )
+    {
+        bIgnoreDataChanged = FALSE;
+        return ;
+    }
+
+    if( pCntntNode->IsNoTxtNode() &&
+        rData.GetFormat() == SvxLinkManager::RegisterStatusInfoId() )
+    {
+        // nur eine Statusaenderung - Events bedienen ?
+        String sState;
+        if( rData.GetData( sState ))
+        {
+            USHORT nEvent = 0;
+            switch( sState.ToInt32() )
+            {
+            case STATE_LOAD_OK:     nEvent = SVX_EVENT_IMAGE_LOAD;  break;
+            case STATE_LOAD_ERROR:  nEvent = SVX_EVENT_IMAGE_ERROR; break;
+            case STATE_LOAD_ABORT:  nEvent = SVX_EVENT_IMAGE_ABORT; break;
+            }
+
+            SwFrmFmt* pFmt;
+            if( nEvent && 0 != ( pFmt = pCntntNode->GetFlyFmt() ))
+            {
+                SwCallMouseEvent aCallEvent;
+                aCallEvent.Set( EVENT_OBJECT_IMAGE, pFmt );
+                pDoc->CallEvent( nEvent, aCallEvent );
+            }
+        }
+        return;         // das wars!
+    }
+
+    FASTBOOL bUpdate = FALSE;
+    FASTBOOL bGraphicArrived = FALSE;
+    FASTBOOL bGraphicPieceArrived = FALSE;
+    FASTBOOL bDontNotify = FALSE;
+    Size aGrfSz;
+
+    if( pCntntNode->IsGrfNode() )
+    {
+        ((SwGrfNode*)pCntntNode)->InvalidateTransparentFlag();
+        Graphic& rGrf = (Graphic&)((SwGrfNode*)pCntntNode)->GetGrf();
+
+        bDontNotify = ((SwGrfNode*)pCntntNode)->IsFrameInPaint();
+
+        ULONG nUpDateState = GetObj()->GetUpToDateStatus();
+        ((SwGrfNode*)pCntntNode)->SetGrafikArrived( ERRCODE_NONE == nUpDateState );
+
+        bGraphicArrived = ERRCODE_NONE == nUpDateState;
+        bGraphicPieceArrived = ERRCODE_SO_PENDING == nUpDateState;
+
+        switch( rData.GetFormat() )
+        {
+        case FORMAT_GDIMETAFILE:
+            {
+                GDIMetaFile *pMetaFile;
+                if( rData.GetData( &pMetaFile, TRANSFER_REFERENCE ) )
+                {
+                    rGrf = *pMetaFile;
+                    bUpdate = TRUE;
+                }
+            }
+            break;
+
+        case FORMAT_BITMAP:
+            {
+                Bitmap *pBmp;
+                if( rData.GetData( &pBmp, TRANSFER_REFERENCE ) )
+                {
+                    Graphic aEmptyGrf;
+                    if( aEmptyGrf.GetBitmap() == *pBmp )
+                        rGrf = aEmptyGrf;
+                    else
+                        rGrf = *pBmp;
+                    bUpdate = TRUE;
+                }
+            }
+            break;
+
+        default:
+            if( rData.GetFormat() == Graphic::RegisterClipboardFormatName() ||
+                FORMAT_PRIVATE == rData.GetFormat() )
+            {
+                Graphic* pGrf;
+                if( rData.GetData( (SvDataCopyStream **)&pGrf,
+                                    Graphic::StaticType(),
+                                    TRANSFER_REFERENCE ) &&
+                    ( GRAPHIC_DEFAULT != pGrf->GetType() ||
+                      GRAPHIC_DEFAULT != rGrf.GetType() ) )
+                {
+                    aGrfSz = ::GetGraphicSizeTwip( *pGrf, 0 );
+                    Size aSz( ((SwGrfNode*)pCntntNode)->GetTwipSize() );
+
+                    if( bGraphicPieceArrived &&
+                        GRAPHIC_DEFAULT != pGrf->GetType() &&
+                        ( !aSz.Width() || !aSz.Height() ) )
+                    {
+                        // wenn nur ein Teil ankommt, aber die Groesse nicht
+                        // gesetzt ist, dann muss "unten" der Teil von
+                        // bGraphicArrived durchlaufen werden!
+                        // (ansonten wird die Grafik in deft. Size gepaintet)
+                        bGraphicArrived = TRUE;
+                        bGraphicPieceArrived = FALSE;
+                    }
+                    rGrf = *pGrf;
+                    bUpdate = TRUE;
+
+                    // Bug 33999: damit der Node den Transparent-Status
+                    //      richtig gesetzt hat, ohne auf die Grafik
+                    //      zugreifen zu muessen (sonst erfolgt ein SwapIn!).
+                    if( bGraphicArrived )
+                    {
+                        ((SwGrfNode*)pCntntNode)->SetTransparent(
+                                    rGrf.IsTransparent() );
+                        // Bug #34735#: immer mit der korrekten Grafik-Size
+                        //              arbeiten
+                        if( aGrfSz.Height() && aGrfSz.Width() &&
+                            aSz.Height() && aSz.Width() &&
+                            aGrfSz != aSz )
+                            ((SwGrfNode*)pCntntNode)->SetTwipSize( aGrfSz );
+                    }
+                }
+            }
+            break;
+        }
+        if ( bUpdate && !bGraphicArrived && !bGraphicPieceArrived )
+            ((SwGrfNode*)pCntntNode)->SetTwipSize( Size(0,0) );
+    }
+    else if( pCntntNode->IsOLENode() )
+        bUpdate = TRUE;
+
+    ViewShell *pSh = 0;
+    SwEditShell* pESh = pDoc->GetEditShell( &pSh );
+
+    if ( bUpdate && bGraphicPieceArrived && !(bSwapIn || bDontNotify) )
+    {
+        //Hint ohne Actions verschicken, loest direktes Paint aus.
+        if ( (!pSh || !pSh->ActionPend()) && (!pESh || !pESh->ActionPend()) )
+        {
+            SwMsgPoolItem aMsgHint( RES_GRAPHIC_PIECE_ARRIVED );
+            pCntntNode->Modify( &aMsgHint, &aMsgHint );
+            bUpdate = FALSE;
+        }
+    }
+
+    static BOOL bInNotifyLinks = FALSE;
+    if( bUpdate && !bDontNotify && (!bSwapIn || bGraphicArrived) &&
+        !bInNotifyLinks)
+    {
+        BOOL bLockView = FALSE;
+        if( pSh )
+        {
+            bLockView = pSh->IsViewLocked();
+            pSh->LockView( TRUE );
+        }
+
+        if( pESh )
+            pESh->StartAllAction();
+        else if( pSh )
+            pSh->StartAction();
+
+        SwMsgPoolItem aMsgHint( bGraphicArrived ? RES_GRAPHIC_ARRIVED :
+                                                  RES_UPDATE_ATTR );
+
+        if ( bGraphicArrived )
+        {
+            //Alle benachrichtigen, die am gleichen Link horchen.
+            bInNotifyLinks = TRUE;
+
+            const SvBaseLinks& rLnks = pDoc->GetLinkManager().GetLinks();
+            for( USHORT n = rLnks.Count(); n; )
+            {
+                SvBaseLink* pLnk = &(*rLnks[ --n ]);
+                if( pLnk && OBJECT_CLIENT_GRF == pLnk->GetObjType() &&
+                    pLnk->ISA( SwBaseLink ) && pLnk->GetObj() == GetObj() )
+                {
+                    SwBaseLink* pBLink = (SwBaseLink*)pLnk;
+                    SwGrfNode* pGrfNd = (SwGrfNode*)pBLink->pCntntNode;
+
+                    if( pBLink != this &&
+                        ( !bSwapIn ||
+                            GRAPHIC_DEFAULT ==  pGrfNd->GetGrf().GetType()))
+                    {
+                        pBLink->bIgnoreDataChanged = FALSE;
+                        pBLink->DataChanged( rData );
+                        pBLink->bIgnoreDataChanged = TRUE;
+
+                        pGrfNd->SetGrafikArrived( ((SwGrfNode*)pCntntNode)->
+                                                    IsGrafikArrived() );
+
+                        // Fly der Grafik anpassen !
+                        if( !::SetGrfFlySize( aGrfSz, pGrfNd ) )
+                            pGrfNd->Modify( &aMsgHint, &aMsgHint );
+                    }
+                    else if( pBLink == this &&
+                            !::SetGrfFlySize( aGrfSz, pGrfNd ) )
+                        // Fly der Grafik anpassen !
+                        pGrfNd->Modify( &aMsgHint, &aMsgHint );
+                }
+            }
+
+            bInNotifyLinks = FALSE;
+        }
+        else
+        {
+            pCntntNode->Modify( &aMsgHint, &aMsgHint );
+        }
+
+
+        if( pESh )
+        {
+            const BOOL bEndActionByVirDev = pESh->IsEndActionByVirDev();
+            pESh->SetEndActionByVirDev( TRUE );
+            pESh->EndAllAction();
+            pESh->SetEndActionByVirDev( bEndActionByVirDev );
+        }
+        else if( pSh )
+            pSh->EndAction();
+
+        if( pSh && !bLockView )
+            pSh->LockView( FALSE );
+    }
+    SwGraphicCacheObj::SetTimeout( 10000L );
+}
+
+FASTBOOL SwBaseLink::IsShowQuickDrawBmp() const
+{
+    return pCntntNode && pCntntNode->IsGrfNode() &&
+            ((SwGrfNode*)pCntntNode)->HasMagicId();
+}
+
+#endif
+// USE_GRFOBJECT
+
+BOOL SetGrfFlySize( const Size& rGrfSz, SwGrfNode* pGrfNd )
+{
+    BOOL bRet = FALSE;
+    ViewShell *pSh;
+    CurrShell *pCurr = 0;
+    if ( pGrfNd->GetDoc()->GetEditShell( &pSh ) )
+        pCurr = new CurrShell( pSh );
+
+    Size aSz = pGrfNd->GetTwipSize();
+    if ( !(aSz.Width() && aSz.Height()) &&
+            rGrfSz.Width() && rGrfSz.Height() )
+    {
+        SwFrmFmt* pFmt;
+        if( pGrfNd->IsChgTwipSize() &&
+            0 != (pFmt = pGrfNd->GetFlyFmt()) )
+        {
+            Size aCalcSz( aSz );
+            if ( !aSz.Height() && aSz.Width() )
+                //passende Hoehe ausrechnen.
+                aCalcSz.Height() = rGrfSz.Height() *
+                        aSz.Width() / rGrfSz.Width();
+            else if ( !aSz.Width() && aSz.Height() )
+                //passende Breite ausrechnen
+                aCalcSz.Width() = rGrfSz.Width() *
+                        aSz.Height() / rGrfSz.Height();
+            else
+                //Hoehe und Breite uebernehmen
+                aCalcSz = rGrfSz;
+
+            const SvxBoxItem     &rBox = pFmt->GetBox();
+            aCalcSz.Width() += rBox.CalcLineSpace(BOX_LINE_LEFT) +
+                               rBox.CalcLineSpace(BOX_LINE_RIGHT);
+            aCalcSz.Height()+= rBox.CalcLineSpace(BOX_LINE_TOP) +
+                               rBox.CalcLineSpace(BOX_LINE_BOTTOM);
+            const SwFmtFrmSize& rOldAttr = pFmt->GetFrmSize();
+            if( rOldAttr.GetSize() != aCalcSz )
+            {
+                SwFmtFrmSize aAttr( rOldAttr  );
+                aAttr.SetSize( aCalcSz );
+                pFmt->SetAttr( aAttr );
+                bRet = TRUE;
+            }
+
+            if( !aSz.Width() )
+            {
+                // Wenn die Grafik in einer Tabelle verankert ist, muess
+                // die Tabellen-Spalten neu berechnet werden
+                const SwDoc *pDoc = pGrfNd->GetDoc();
+                const SwPosition* pAPos = pFmt->GetAnchor().GetCntntAnchor();
+                SwNode *pANd;
+                SwTableNode *pTblNd;
+                if( pAPos &&
+                    0 != (pANd = pDoc->GetNodes()[pAPos->nNode]) &&
+                    0 != (pTblNd = pANd->FindTableNode()) )
+                {
+                    BOOL bLastGrf = !pTblNd->GetTable().DecGrfsThatResize();
+                    SwHTMLTableLayout *pLayout =
+                        pTblNd->GetTable().GetHTMLTableLayout();
+                    if( pLayout )
+                    {
+                        USHORT nBrowseWidth =
+                            pLayout->GetBrowseWidthByTable( *pDoc );
+                        if( nBrowseWidth )
+                            pLayout->Resize( nBrowseWidth, TRUE, TRUE,
+                                             bLastGrf ? HTMLTABLE_RESIZE_NOW
+                                                      : 500 );
+                    }
+                }
+            }
+        }
+
+        // SetTwipSize skaliert ggf. eine ImageMap neu und
+        // braucht dazu das Frame-Format
+        pGrfNd->SetTwipSize( rGrfSz );
+    }
+
+    delete pCurr;
+
+    return bRet;
+}
+
+FASTBOOL SwBaseLink::SwapIn( BOOL bWaitForData, BOOL bNativFormat )
+{
+    bSwapIn = TRUE;
+
+    FASTBOOL bRes;
+
+    if( !GetObj() && ( bNativFormat || ( !IsSynchron() && bWaitForData ) ))
+    {
+        AddNextRef();
+        _GetRealObject();
+        ReleaseRef();
+    }
+
+#ifdef DEBUG
+    {
+        String sGrfNm;
+        GetLinkManager()->GetDisplayNames( *this, 0, &sGrfNm, 0, 0 );
+        int x = 0;
+    }
+#endif
+
+    if( GetObj() )
+    {
+        SvData aData( GetContentType() );
+        if( !IsSynchron() && bWaitForData )
+            aData.SetAspect( ASPECT_DOCPRINT );
+        if( bNativFormat )
+            aData.SetAspect( aData.GetAspect() | ASPECT_ICON );
+        GetObj()->GetData( &aData );
+        if( bWaitForData && !GetObj() )
+        {
+            ASSERT( !this, "das SvxFileObject wurde in einem GetData geloescht!" );
+            bRes = FALSE;
+        }
+        else if( 0 != ( bRes = aData.HasData() ) )
+        {
+            //JP 14.04.99: Bug 64820 - das Flag muss beim SwapIn natuerlich
+            //              zurueckgesetzt werden. Die Daten sollen ja neu
+            //              uebernommen werden
+            bIgnoreDataChanged = FALSE;
+            DataChanged( aData );
+        }
+    }
+    else if( !IsSynchron() && bWaitForData )
+    {
+        SetSynchron( TRUE );
+        bRes = Update();
+        SetSynchron( FALSE );
+    }
+    else
+        bRes = Update();
+
+    bSwapIn = FALSE;
+    return bRes;
+}
+
+void SwBaseLink::Closed()
+{
+    if( pCntntNode && !pCntntNode->GetDoc()->IsInDtor() )
+    {
+        // wir heben die Verbindung auf
+        if( pCntntNode->IsGrfNode() )
+            ((SwGrfNode*)pCntntNode)->ReleaseLink();
+        else if( pCntntNode->IsOLENode() )
+            ((SwOLENode*)pCntntNode)->GetOLEObj().ReleaseLink();
+    }
+    SvBaseLink::Closed();
+}
+
+const SwNode* SwBaseLink::GetAnchor() const
+{
+    SwFrmFmt* pFmt;
+    if( pCntntNode && 0 != ( pFmt = pCntntNode->GetFlyFmt()) )
+    {
+        const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
+        const SwPosition* pAPos;
+        if( 0 != ( pAPos = rAnchor.GetCntntAnchor()) &&
+            ( FLY_IN_CNTNT == rAnchor.GetAnchorId() ||
+            FLY_AUTO_CNTNT == rAnchor.GetAnchorId() ||
+            FLY_AT_FLY == rAnchor.GetAnchorId() ||
+            FLY_AT_CNTNT == rAnchor.GetAnchorId() ))
+                return &pAPos->nNode.GetNode();
+        return 0;
+    }
+
+    ASSERT( !this, "GetAnchor nicht ueberlagert" );
+    return 0;
+}
+
+BOOL SwBaseLink::IsRecursion( const SwBaseLink* pChkLnk ) const
+{
+    SwServerObjectRef aRef( GetObj() );
+    if( aRef.Is() )
+    {
+        // es ist ein ServerObject, also frage nach allen darin
+        // befindlichen Links, ob wir darin enthalten sind. Ansonsten
+        // handelt es sich um eine Rekursion.
+        return aRef->IsLinkInServer( pChkLnk );
+    }
+    return FALSE;
+}
+
+BOOL SwBaseLink::IsInRange( ULONG, ULONG, xub_StrLen, xub_StrLen ) const
+{
+    // Grafik oder OLE-Links nicht,
+    // Felder oder Sections haben eigene Ableitung!
+    return FALSE;
+}
+
+
+
+
diff --git a/sw/source/core/draw/dcontact.cxx b/sw/source/core/draw/dcontact.cxx
new file mode 100644
index 000000000000..61e26611a069
--- /dev/null
+++ b/sw/source/core/draw/dcontact.cxx
@@ -0,0 +1,774 @@
+/*************************************************************************
+ *
+ *  $RCSfile: dcontact.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:18 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "hintids.hxx"
+
+#ifndef _SVX_PROTITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_OPAQITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_ULSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVDPAGE_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_FMGLOB_HXX
+#include 
+#endif
+#ifndef _SVDOGRP_HXX //autogen
+#include 
+#endif
+#ifndef _SVDOTEXT_HXX //autogen
+#include 
+#endif
+#ifndef _SVDMODEL_HXX //autogen
+#include 
+#endif
+
+
+#ifndef _FMTORNT_HXX //autogen
+#include 
+#endif
+#ifndef _VIEWIMP_HXX //autogen
+#include 
+#endif
+#ifndef _FMTSRND_HXX //autogen
+#include 
+#endif
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _NODE_HXX //autogen
+#include 
+#endif
+#ifndef _FMTCNTNT_HXX //autogen
+#include 
+#endif
+#ifndef _PAGEFRM_HXX
+#include 
+#endif
+#ifndef _ROOTFRM_HXX
+#include 
+#endif
+#ifndef _FRMTOOL_HXX
+#include   // Notify_Background
+#endif
+#ifndef _FLYFRM_HXX
+#include 
+#endif
+#ifndef _FRMFMT_HXX
+#include 
+#endif
+#ifndef _FRMATR_HXX
+#include 
+#endif
+#ifndef _DFLYOBJ_HXX
+#include 
+#endif
+#ifndef _DCONTACT_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _HINTS_HXX
+#include 
+#endif
+#ifndef _CNTFRM_HXX
+#include 
+#endif
+#ifndef _TXTFRM_HXX
+#include 
+#endif
+#ifndef _EDITSH_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+
+TYPEINIT1( SwContact, SwClient )
+TYPEINIT1( SwFlyDrawContact, SwContact )
+TYPEINIT1( SwDrawContact, SwContact )
+
+
+//Der Umgekehrte Weg: Sucht das Format zum angegebenen Objekt.
+//Wenn das Object ein SwVirtFlyDrawObj ist so wird das Format von
+//selbigem besorgt.
+//Anderfalls ist es eben ein einfaches Zeichenobjekt. Diese hat einen
+//UserCall und der ist Client vom gesuchten Format.
+
+SwFrmFmt *FindFrmFmt( SdrObject *pObj )
+{
+    if ( pObj->IsWriterFlyFrame() )
+        return ((SwVirtFlyDrawObj*)pObj)->GetFmt();
+    else
+    {
+        SwDrawContact *pContact = (SwDrawContact*)GetUserCall( pObj );
+        return pContact ? pContact->GetFmt() : NULL;
+    }
+}
+
+/*****************************************************************************
+ *
+ * GetBoundRect liefert das BoundRect _inklusive_ Abstand des Objekts.
+ *
+ *****************************************************************************/
+
+SwRect GetBoundRect( const SdrObject* pObj )
+{
+    SwRect aRet( pObj->GetBoundRect() );
+    const SwFmt *pFmt = ((SwContact*)GetUserCall(pObj))->GetFmt();
+    const SvxULSpaceItem &rUL = pFmt->GetULSpace();
+    const SvxLRSpaceItem &rLR = pFmt->GetLRSpace();
+    aRet.Top ( Max( aRet.Top() - long(rUL.GetUpper()), 0L ));
+    aRet.Left( Max( aRet.Left()- long(rLR.GetLeft()),  0L ));
+    aRet.SSize().Height() += rUL.GetLower();
+    aRet.SSize().Width()  += rLR.GetRight();
+    return aRet;
+}
+
+//Liefert den UserCall ggf. vom Gruppenobjekt
+SdrObjUserCall* GetUserCall( const SdrObject* pObj )
+{
+    SdrObject *pTmp;
+    while ( !pObj->GetUserCall() && 0 != (pTmp = pObj->GetUpGroup()) )
+        pObj = pTmp;
+    return pObj->GetUserCall();
+}
+
+// liefert TRUE falls das SrdObject ein Marquee-Object (Lauftext) ist
+FASTBOOL IsMarqueeTextObj( const SdrObject& rObj )
+{
+    SdrTextAniKind eTKind;
+    return SdrInventor == rObj.GetObjInventor() &&
+        OBJ_TEXT == rObj.GetObjIdentifier() &&
+        ( SDRTEXTANI_SCROLL == ( eTKind = ((SdrTextObj&)rObj).GetTextAniKind())
+         || SDRTEXTANI_ALTERNATE == eTKind || SDRTEXTANI_SLIDE == eTKind );
+}
+
+/*************************************************************************
+|*
+|*  SwContact, Ctor und Dtor
+|*
+|*  Ersterstellung      AMA 27.Sep.96 18:13
+|*  Letzte Aenderung    AMA 27.Sep.96
+|*
+|*************************************************************************/
+
+SwContact::SwContact( SwFrmFmt *pToRegisterIn, SdrObject *pObj ) :
+    SwClient( pToRegisterIn ),
+    pMasterObj( pObj )
+{
+    pObj->SetUserCall( this );
+}
+
+SwContact::~SwContact()
+{
+    if ( pMasterObj )
+    {
+        pMasterObj->SetUserCall( 0 );   //Soll mir nicht in den Ruecken fallen.
+        if ( pMasterObj->GetPage() )    //Der SdrPage die Verantwortung entziehen.
+            pMasterObj->GetPage()->RemoveObject( pMasterObj->GetOrdNum() );
+        delete pMasterObj;
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFlyDrawContact, Ctor und Dtor
+|*
+|*  Ersterstellung      OK 23.11.94 18:13
+|*  Letzte Aenderung    MA 06. Apr. 95
+|*
+|*************************************************************************/
+
+SwFlyDrawContact::SwFlyDrawContact( SwFlyFrmFmt *pToRegisterIn, SdrModel *pMod ) :
+    SwContact( pToRegisterIn )
+{
+    SetMaster( new SwFlyDrawObj() );
+    GetMaster()->SetOrdNum( 0xFFFFFFFE );
+    GetMaster()->SetUserCall( this );
+}
+
+/*************************************************************************
+|*
+|*  SwFlyDrawContact::CreateNewRef()
+|*
+|*  Ersterstellung      MA 14. Dec. 94
+|*  Letzte Aenderung    MA 24. Apr. 95
+|*
+|*************************************************************************/
+
+SwVirtFlyDrawObj *SwFlyDrawContact::CreateNewRef( SwFlyFrm *pFly )
+{
+    SwVirtFlyDrawObj *pDrawObj = new SwVirtFlyDrawObj( *GetMaster(), pFly );
+    pDrawObj->SetModel( GetMaster()->GetModel() );
+    pDrawObj->SetUserCall( this );
+
+    //Der Reader erzeugt die Master und setzt diese, um die Z-Order zu
+    //transportieren, in die Page ein. Beim erzeugen der ersten Referenz werden
+    //die Master aus der Liste entfernt und fuehren von da an ein
+    //Schattendasein.
+    SdrPage *pPg;
+    if ( 0 != ( pPg = GetMaster()->GetPage() ) )
+    {
+        const UINT32 nOrdNum = GetMaster()->GetOrdNum();
+        pPg->ReplaceObject( pDrawObj, nOrdNum );
+    }
+    return pDrawObj;
+}
+
+/*************************************************************************
+|*
+|*  SwFlyDrawContact::Modify()
+|*
+|*  Ersterstellung      OK 08.11.94 10:21
+|*  Letzte Aenderung    MA 06. Dec. 94
+|*
+|*************************************************************************/
+
+void SwFlyDrawContact::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew )
+{
+}
+
+/*************************************************************************
+|*
+|*  SwDrawContact, Ctor+Dtor
+|*
+|*  Ersterstellung      MA 09. Jan. 95
+|*  Letzte Aenderung    MA 22. Jul. 98
+|*
+|*************************************************************************/
+FASTBOOL lcl_CheckControlLayer( const SdrObject *pObj )
+{
+    if ( FmFormInventor == pObj->GetObjInventor() )
+        return TRUE;
+    if ( pObj->ISA( SdrObjGroup ) )
+    {
+        const SdrObjList *pLst = ((SdrObjGroup*)pObj)->GetSubList();
+        for ( USHORT i = 0; i < pLst->GetObjCount(); ++i )
+            if ( ::lcl_CheckControlLayer( pLst->GetObj( i ) ) )
+                return TRUE;
+    }
+    return FALSE;
+}
+
+SwDrawContact::SwDrawContact( SwFrmFmt *pToRegisterIn, SdrObject *pObj ) :
+    SwContact( pToRegisterIn, pObj ),
+    pAnchor( 0 ),
+    pPage( 0 )
+{
+    //Controls muessen immer im Control-Layer liegen. Das gilt auch fuer
+    //Gruppenobjekte, wenn diese Controls enthalten.
+    if ( lcl_CheckControlLayer( pObj ) )
+        pObj->SetLayer( pToRegisterIn->GetDoc()->GetControlsId() );
+}
+
+
+SwDrawContact::~SwDrawContact()
+{
+    DisconnectFromLayout();
+}
+
+/*************************************************************************
+|*
+|*  SwDrawContact::Changed
+|*
+|*  Ersterstellung      MA 09. Jan. 95
+|*  Letzte Aenderung    MA 29. May. 96
+|*
+|*************************************************************************/
+
+void lcl_Notify( SwDrawContact* pThis, const Rectangle* pOldBoundRect )
+{
+    SwFrm *pAnch = pThis->GetAnchor();
+    if( pAnch )
+    {
+        SwPageFrm *pPage = pAnch->FindPageFrm();
+        ASSERT( GetUserCall(pThis->GetMaster()) == pThis, "Wrong Master" );
+        if( pOldBoundRect && pPage )
+        {
+            SwRect aOldRect( *pOldBoundRect );
+            if( aOldRect.HasArea() )
+                Notify_Background( pThis->GetMaster(),pPage, aOldRect,
+                                    PREP_FLY_LEAVE,TRUE);
+        }
+        SwRect aRect( pThis->GetMaster()->GetBoundRect() );
+        if( aRect.HasArea() )
+        {
+            SwPageFrm *pPg = pThis->FindPage( aRect );
+            if( pPg )
+                Notify_Background( pThis->GetMaster(), pPg, aRect,
+                                    PREP_FLY_ARRIVE, TRUE );
+        }
+        ClrContourCache( pThis->GetMaster() );
+    }
+}
+
+
+void SwDrawContact::Changed(const SdrObject& rObj, SdrUserCallType eType,
+                                    const Rectangle& rOldBoundRect)
+{
+    //Action aufsetzen, aber nicht wenn gerade irgendwo eine Action laeuft.
+    ViewShell *pSh = 0, *pOrg;
+    SwDoc *pDoc = GetFmt()->GetDoc();
+    if ( pDoc->GetRootFrm() && pDoc->GetRootFrm()->IsCallbackActionEnabled() )
+    {
+        pDoc->GetEditShell( &pOrg );
+        pSh = pOrg;
+        if ( pSh )
+            do
+            {   if ( pSh->Imp()->IsAction() || pSh->Imp()->IsIdleAction() )
+                    pSh = 0;
+                else
+                    pSh = (ViewShell*)pSh->GetNext();
+
+            } while ( pSh && pSh != pOrg );
+
+        if ( pSh )
+            pDoc->GetRootFrm()->StartAllAction();
+    }
+
+    SdrObjUserCall::Changed( rObj, eType, rOldBoundRect );
+    _Changed( rObj, eType, &rOldBoundRect );    //Achtung, ggf. Suizid!
+
+    if ( pSh )
+        pDoc->GetRootFrm()->EndAllAction();
+}
+
+void SwDrawContact::_Changed(const SdrObject& rObj, SdrUserCallType eType,
+                             const Rectangle* pOldBoundRect)
+{
+    BOOL bInCntnt = FLY_IN_CNTNT == GetFmt()->GetAnchor().GetAnchorId();
+    BOOL bNotify = !bInCntnt &&
+        ( SURROUND_THROUGHT != GetFmt()->GetSurround().GetSurround() );
+    switch( eType )
+    {
+        case SDRUSERCALL_DELETE:
+            {
+                if( bNotify )
+                    lcl_Notify( this, pOldBoundRect );
+                DisconnectFromLayout( FALSE );
+                SetMaster( NULL );
+                delete this;
+                break;
+            }
+        case SDRUSERCALL_INSERTED:
+            {
+                ConnectToLayout();
+                if( bNotify )
+                    lcl_Notify( this, pOldBoundRect );
+                break;
+            }
+        case SDRUSERCALL_REMOVED:
+            {
+                if( bNotify )
+                    lcl_Notify( this, pOldBoundRect );
+                DisconnectFromLayout( FALSE );
+                break;
+            }
+        case SDRUSERCALL_MOVEONLY:
+        case SDRUSERCALL_RESIZE:
+        case SDRUSERCALL_CHILD_MOVEONLY :
+        case SDRUSERCALL_CHILD_RESIZE :
+        case SDRUSERCALL_CHILD_CHGATTR :
+        case SDRUSERCALL_CHILD_DELETE :
+        case SDRUSERCALL_CHILD_COPY :
+        case SDRUSERCALL_CHILD_INSERTED :
+        case SDRUSERCALL_CHILD_REMOVED :
+            if( bInCntnt )
+            {
+                SwFrm *pAnch = GetAnchor();
+                if( !pAnch )
+                {
+                    ConnectToLayout();
+                    pAnch = GetAnchor();
+                }
+                if( pAnch && !((SwTxtFrm*)pAnch)->IsLocked() )
+                {
+                    SwFrmFmt *pFmt = GetFmt();
+                    const SwFmtVertOrient &rVert = pFmt->GetVertOrient();
+                    Point aRelPos = rObj.GetRelativePos();
+                    if( rVert.GetPos() != aRelPos.Y() )
+                    {
+                        SwFmtVertOrient aVert( rVert );
+                        aVert.SetVertOrient( VERT_NONE );
+                        aVert.SetPos( aRelPos.Y() );
+                        pFmt->SetAttr( aVert );
+                    }
+                    ((SwTxtFrm*)pAnch)->Prepare();
+                }
+            }
+            else if( bNotify )
+                lcl_Notify( this, pOldBoundRect );
+            break;
+        case SDRUSERCALL_CHGATTR:
+            if( bNotify )
+                lcl_Notify( this, pOldBoundRect );
+            break;
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwDrawContact::Modify()
+|*
+|*  Ersterstellung      MA 09. Jan. 95
+|*  Letzte Aenderung    MA 03. Dec. 95
+|*
+|*************************************************************************/
+
+void SwDrawContact::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew )
+{
+    //Es kommen immer Sets herein.
+    //MA 03. Dec. 95: Falsch es kommen nicht immer Sets herein
+    //(siehe SwRootFrm::AssertPageFlys()
+    USHORT nWhich = pNew ? pNew->Which() : 0;
+    SwFmtAnchor *pAnch = 0;
+    if( RES_ATTRSET_CHG == nWhich )
+    {
+        if( SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
+                            RES_ANCHOR, FALSE, (const SfxPoolItem**)&pAnch ))
+        ;       // Beim GetItemState wird der AnkerPointer gesetzt !
+        else if( SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->
+                                 GetItemState( RES_VERT_ORIENT, FALSE ))
+        {
+            SwFrm *pFrm = GetAnchor();
+            if( !pFrm )
+            {
+                ConnectToLayout();
+                pFrm = GetAnchor();
+            }
+            if( pFrm && pFrm->IsTxtFrm() )
+                ((SwTxtFrm*)pFrm)->Prepare();
+        }
+    }
+    else if( RES_ANCHOR == nWhich )
+        pAnch = (SwFmtAnchor*)pNew;
+
+    if ( pAnch )
+    {
+        // JP 10.04.95: nicht auf ein Reset Anchor reagieren !!!!!
+        if( SFX_ITEM_SET == ((SwFrmFmt*)pRegisteredIn)->GetAttrSet().
+            GetItemState( RES_ANCHOR, FALSE ) )
+        {
+            SwFrm *pOldAnch = GetAnchor();
+            SwPageFrm *pPg = NULL;
+            SwRect aOldRect;
+            if( pOldAnch )
+            {
+                pPg = pOldAnch->FindPageFrm();
+                aOldRect = SwRect( GetMaster()->GetBoundRect() );
+            }
+            ConnectToLayout( pAnch );
+            if( pPg && aOldRect.HasArea() )
+                Notify_Background(GetMaster(),pPg,aOldRect,PREP_FLY_LEAVE,TRUE);
+            lcl_Notify( this, NULL );
+        }
+        else
+            DisconnectFromLayout();
+    }
+    else if( RES_SURROUND == nWhich || RES_UL_SPACE == nWhich ||
+             RES_LR_SPACE == nWhich ||
+             ( RES_ATTRSET_CHG == nWhich &&
+               ( SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
+                            RES_SURROUND, FALSE ) ||
+                 SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
+                            RES_LR_SPACE, FALSE ) ||
+                 SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
+                            RES_UL_SPACE, FALSE ) ) ) )
+        lcl_Notify( this, NULL );
+}
+
+
+/*************************************************************************
+|*
+|*  SwDrawContact::DisconnectFromLayout()
+|*
+|*  Ersterstellung      MA 09. Jan. 95
+|*  Letzte Aenderung    MA 25. Mar. 99
+|*
+|*************************************************************************/
+
+void SwDrawContact::DisconnectFromLayout( BOOL bRemoveFromPage )
+{
+    if ( pAnchor )
+        pAnchor->RemoveDrawObj( this );
+
+    if ( bRemoveFromPage && GetMaster() && GetMaster()->IsInserted() )
+        ((SwFrmFmt*)pRegisteredIn)->GetDoc()->GetDrawModel()->GetPage(0)->
+                                    RemoveObject( GetMaster()->GetOrdNum() );
+}
+
+/*************************************************************************
+|*
+|*  SwDrawContact::ConnectToLayout()
+|*
+|*  Ersterstellung      MA 09. Jan. 95
+|*  Letzte Aenderung    MA 25. Mar. 99
+|*
+|*************************************************************************/
+
+void SwDrawContact::ConnectToLayout( const SwFmtAnchor *pAnch )
+{
+    SwFrmFmt *pFmt = (SwFrmFmt*)pRegisteredIn;
+
+    SwRootFrm *pRoot = pFmt->GetDoc()->GetRootFrm();
+    if ( !pRoot )
+        return;
+
+    if ( pAnchor )
+        pAnchor->RemoveDrawObj( this );
+
+    if ( !pAnch )
+        pAnch = &pFmt->GetAnchor();
+
+    BOOL bSetAnchorPos = TRUE;
+
+    switch ( pAnch->GetAnchorId() )
+    {
+        case FLY_PAGE:
+            {
+                USHORT nPgNum = pAnch->GetPageNum();
+                SwPageFrm *pPage = (SwPageFrm*)pRoot->Lower();
+
+                for ( USHORT i = 1; i < nPgNum && pPage;
+                            ++i, pPage = (SwPageFrm*)pPage->GetNext() )
+                    /* do nothing */;
+
+                if ( pPage )
+                {
+                    bSetAnchorPos = FALSE;
+                    pPage->SwFrm::AppendDrawObj( this );
+                }
+                else
+                    //Sieht doof aus, ist aber erlaubt (vlg. SwFEShell::SetPageObjsNewPage)
+                    pRoot->SetAssertFlyPages();
+            }
+            break;
+
+        case FLY_AUTO_CNTNT:
+        case FLY_AT_CNTNT:
+            {
+                //Wenn die Zeichenobjekte in mehrfacher Darstellung vorkommen
+                //(z.B. Kopf-/Fusszeilen) wird es komplizierter, dann bitte aus
+                //SwFlyAtCntFrm::Modify() abkupfern.
+                if ( pAnch->GetCntntAnchor() ) //#28154#
+                {
+                    SwCntntNode *pNode = pFmt->GetDoc()->
+                            GetNodes()[pAnch->GetCntntAnchor()->nNode]->GetCntntNode();
+                    SwCntntFrm *pCntnt = pNode->GetFrm( 0, 0, FALSE );
+                    if ( pCntnt )
+                    {
+                        //Kann sein, dass der Anker noch nicht existiert
+                        pCntnt->AppendDrawObj( this );
+                        bSetAnchorPos = FALSE;
+                    }
+                }
+            }
+            break;
+        case FLY_AT_FLY:
+            {
+                if( pAnch->GetCntntAnchor() ) // LAYER_IMPL
+                {
+                    SwFrm *pAnchor = 0;
+                    //Erst einmal ueber den Inhalt suchen, weil konstant schnell. Kann
+                    //Bei verketteten Rahmen aber auch schief gehen, weil dann evtl.
+                    //niemals ein Frame zu dem Inhalt existiert. Dann muss leider noch
+                    //die Suche vom StartNode zum FrameFormat sein.
+                    SwNodeIndex aIdx( pAnch->GetCntntAnchor()->nNode );
+                    SwCntntNode *pCNd = pFmt->GetDoc()->GetNodes().GoNext( &aIdx );
+                    if ( pCNd && 0 != (pAnchor = pCNd->GetFrm( 0, 0, FALSE ) ) )
+                        pAnchor = pAnchor->FindFlyFrm();
+                    else
+                    {
+                        const SwNodeIndex &rIdx = pAnch->GetCntntAnchor()->nNode;
+                        SwSpzFrmFmts& rFmts = *pFmt->GetDoc()->GetSpzFrmFmts();
+                        for( USHORT i = 0; i < rFmts.Count(); ++i )
+                        {
+                            SwFrmFmt *pFmt = rFmts[i];
+                            SwFlyFrmFmt* pFlyFmt;
+                            if( 0 != (pFlyFmt = PTR_CAST( SwFlyFrmFmt, pFmt )) &&
+                                pFlyFmt->GetCntnt().GetCntntIdx() && //#57390#, Reader
+                                rIdx == *pFlyFmt->GetCntnt().GetCntntIdx() )
+                            {
+                                pAnchor = pFlyFmt->GetFrm( 0, FALSE );
+                                break;
+                            }
+                        }
+                    }
+                    if ( pAnchor )  //Kann sein, dass der Anker noch nicht existiert
+                    {
+                        pAnchor->FindFlyFrm()->AppendDrawObj( this );
+                        bSetAnchorPos = FALSE;
+                    }
+                }
+            }
+            break;
+        case FLY_IN_CNTNT:
+            {
+                ClrContourCache( GetMaster() );
+                SwCntntNode *pNode = GetFmt()->GetDoc()->
+                        GetNodes()[pAnch->GetCntntAnchor()->nNode]->GetCntntNode();
+                SwCntntFrm *pCntnt = pNode->GetFrm( 0, 0, FALSE );
+                if ( pCntnt )
+                {
+                    //Kann sein, dass der Anker noch nicht existiert
+                    pCntnt->AppendDrawObj( this );
+                    pCntnt->InvalidatePrt();
+                }
+                bSetAnchorPos = FALSE;
+            }
+            break;
+#ifndef PRODUCT
+        default:    ASSERT( FALSE, "Unknown Anchor." );
+#endif
+    }
+    if ( GetAnchor() )
+    {
+        if( bSetAnchorPos )
+            GetMaster()->SetAnchorPos( GetAnchor()->Frm().Pos() );
+
+        //verankerte Objekte gehoeren immer auch in die Page,
+        if ( !GetMaster()->IsInserted() )
+            pFmt->GetDoc()->GetDrawModel()->GetPage(0)->
+                InsertObject( GetMaster(), GetMaster()->GetOrdNumDirect() );
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwDrawContact::FindPage(), ChkPage()
+|*
+|*  Ersterstellung      MA 21. Mar. 95
+|*  Letzte Aenderung    MA 19. Jul. 96
+|*
+|*************************************************************************/
+
+SwPageFrm *SwDrawContact::FindPage( const SwRect &rRect )
+{
+    SwPageFrm *pPg = pPage;
+    if ( !pPg && pAnchor )
+        pPg = pAnchor->FindPageFrm();
+    if ( pPg )
+        pPg = (SwPageFrm*)::FindPage( rRect, pPg );
+    return pPg;
+}
+
+void SwDrawContact::ChkPage()
+{
+    SwPageFrm *pPg = pAnchor && pAnchor->IsPageFrm() ?
+        pPage : FindPage( GetMaster()->GetBoundRect() );
+    if ( pPage != pPg )
+    {
+        if ( pPage )
+            pPage->SwPageFrm::RemoveDrawObj( this );
+        pPg->SwPageFrm::AppendDrawObj( this );
+        ChgPage( pPg );
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwDrawContact::ChangeMasterObject()
+|*
+|*  Ersterstellung      MA 07. Aug. 95
+|*  Letzte Aenderung    MA 20. Apr. 99
+|*
+|*************************************************************************/
+
+void SwDrawContact::ChangeMasterObject( SdrObject *pNewMaster )
+{
+    SwFrm *pAnch = GetAnchor();
+    DisconnectFromLayout( FALSE );
+    GetMaster()->SetUserCall( 0 );
+    SetMaster( pNewMaster );
+    GetMaster()->SetUserCall( this );
+    GetMaster()->NbcSetRelativePos( GetMaster()->GetSnapRect().TopLeft() -
+                                   pAnch->Frm().Pos() );
+    GetMaster()->NbcSetAnchorPos( pAnch->Frm().Pos() );
+
+    //Hier wird der neue Master ggf. in die Page eingefuegt, was das Drawing
+    //aber gar nicht gut haben kann. Deshalb nehmen wir das Objekt hinterher
+    //gleich wieder aus der Seite heraus.
+    FASTBOOL bInserted = pNewMaster->IsInserted();
+    ConnectToLayout();
+    if ( !bInserted && pNewMaster->IsInserted() )
+        ((SwFrmFmt*)pRegisteredIn)->GetDoc()->GetDrawModel()->GetPage(0)->
+                                    RemoveObject( GetMaster()->GetOrdNum() );
+}
+
+
diff --git a/sw/source/core/draw/dflyobj.cxx b/sw/source/core/draw/dflyobj.cxx
new file mode 100644
index 000000000000..82d9cc6ec7f5
--- /dev/null
+++ b/sw/source/core/draw/dflyobj.cxx
@@ -0,0 +1,707 @@
+/*************************************************************************
+ *
+ *  $RCSfile: dflyobj.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:18 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "hintids.hxx"
+
+#ifndef _XPOLY_HXX //autogen
+#include 
+#endif
+#ifndef _SVDTRANS_HXX
+#include 
+#endif
+#ifndef _SVX_PROTITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_OPAQITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVDPAGE_HXX //autogen
+#include 
+#endif
+
+
+#ifndef _FMTCLDS_HXX //autogen
+#include 
+#endif
+#ifndef _FMTORNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFSIZE_HXX //autogen
+#include 
+#endif
+#ifndef _FMTURL_HXX //autogen
+#include 
+#endif
+#include "frmsh.hxx"
+#include "viewsh.hxx"
+#include "viewimp.hxx"
+#include "cntfrm.hxx"
+#include "frmatr.hxx"
+#include "doc.hxx"
+#include "dview.hxx"
+#include "dflyobj.hxx"
+#include "flyfrm.hxx"
+#include "frmfmt.hxx"
+#include "viewopt.hxx"
+#include "frmtool.hxx"
+#include "flyfrms.hxx"
+#include "ndnotxt.hxx"
+#include "grfatr.hxx"
+#include "pagefrm.hxx"
+
+static FASTBOOL bInResize = FALSE;
+
+TYPEINIT1( SwFlyDrawObj, SdrObject )
+TYPEINIT1( SwVirtFlyDrawObj, SdrVirtObj )
+
+/*************************************************************************
+|*
+|*  SwFlyDrawObj::Ctor
+|*
+|*  Ersterstellung      MA 18. Apr. 95
+|*  Letzte Aenderung    MA 28. May. 96
+|*
+*************************************************************************/
+SwFlyDrawObj::SwFlyDrawObj()
+{
+    bNotPersistent = TRUE;
+}
+
+/*************************************************************************
+|*
+|*  SwFlyDrawObj::Paint()
+|*
+|*  Ersterstellung      MA 08. Dec. 94
+|*  Letzte Aenderung    MA 20. May. 95
+|*
+*************************************************************************/
+
+FASTBOOL __EXPORT SwFlyDrawObj::Paint(ExtOutputDevice& rOut, const SdrPaintInfoRec& rInfoRec) const
+{
+    return TRUE;
+}
+
+/*************************************************************************
+|*
+|*  SwFlyDrawObj::Factory-Methoden
+|*
+|*  Ersterstellung      MA 23. Feb. 95
+|*  Letzte Aenderung    MA 23. Feb. 95
+|*
+*************************************************************************/
+
+UINT32 __EXPORT SwFlyDrawObj::GetObjInventor() const
+{
+    return SWGInventor;
+}
+
+
+UINT16 __EXPORT SwFlyDrawObj::GetObjIdentifier()    const
+{
+    return SwFlyDrawObjIdentifier;
+}
+
+
+UINT16 __EXPORT SwFlyDrawObj::GetObjVersion() const
+{
+    return SwDrawFirst;
+}
+
+/*************************************************************************
+|*
+|*  SwVirtFlyDrawObj::CToren, Dtor
+|*
+|*  Ersterstellung      MA 08. Dec. 94
+|*  Letzte Aenderung    MA 28. May. 96
+|*
+*************************************************************************/
+
+SwVirtFlyDrawObj::SwVirtFlyDrawObj(SdrObject& rNew, SwFlyFrm* pFly) :
+    SdrVirtObj( rNew ),
+    pFlyFrm( pFly )
+{
+    bNotPersistent = bNeedColorRestore = bWriterFlyFrame = TRUE;
+    const SvxProtectItem &rP = pFlyFrm->GetFmt()->GetProtect();
+    bMovProt = rP.IsPosProtected();
+    bSizProt = rP.IsSizeProtected();
+}
+
+
+__EXPORT SwVirtFlyDrawObj::~SwVirtFlyDrawObj()
+{
+    if ( GetPage() )    //Der SdrPage die Verantwortung entziehen.
+        GetPage()->RemoveObject( GetOrdNum() );
+}
+
+/*************************************************************************
+|*
+|*  SwVirtFlyDrawObj::GetFmt()
+|*
+|*  Ersterstellung      MA 08. Dec. 94
+|*  Letzte Aenderung    MA 08. Dec. 94
+|*
+*************************************************************************/
+
+const SwFrmFmt *SwVirtFlyDrawObj::GetFmt() const
+{
+    return GetFlyFrm()->GetFmt();
+}
+
+
+SwFrmFmt *SwVirtFlyDrawObj::GetFmt()
+{
+    return GetFlyFrm()->GetFmt();
+}
+
+/*************************************************************************
+|*
+|*  SwVirtFlyDrawObj::Paint()
+|*
+|*  Ersterstellung      MA 20. Dec. 94
+|*  Letzte Aenderung    MA 18. Dec. 95
+|*
+*************************************************************************/
+
+FASTBOOL __EXPORT SwVirtFlyDrawObj::Paint(ExtOutputDevice& rOut, const SdrPaintInfoRec& rInfoRec) const
+{
+    if ( !pFlyFrm->IsFlyInCntFrm() ) //FlyInCnt werden von den TxtPortions gepaintet.
+    {
+        //Rect auf den Fly begrenzen.
+        SwRect aRect( rInfoRec.aDirtyRect );
+        if ( rInfoRec.aDirtyRect.IsEmpty() )
+            aRect = GetFlyFrm()->Frm();
+        pFlyFrm->Paint( aRect );
+    }
+    return TRUE;
+}
+
+/*************************************************************************
+|*
+|*  SwVirtFlyDrawObj::CheckHit()
+|*  Beschreibung        Das Teil ist genau dann getroffen wenn
+|*                      1. der Point im Rand des Frm liegt.
+|*                      2. der Point im heissen Bereich liegt.
+|*                      3. der Point in der Flaeche liegt und es sich um
+|*                         einen Rahmen mit NoTxtFrm handelt und dieser
+|*                         keine URL traegt.
+|*                      3a nicht aber wenn ueber dem Fly noch ein Fly liegt,
+|*                         und der Point in dessen Flaeche nicht steht.
+|*                      4. der Point in der Flaeche liegt und der Rahmen
+|*                         selektiert ist.
+|*  Ersterstellung      MA 08. Dec. 94
+|*  Letzte Aenderung    JP 25.03.96
+|*
+*************************************************************************/
+
+SdrObject* __EXPORT SwVirtFlyDrawObj::CheckHit( const Point& rPnt, USHORT nTol,
+                                    const SetOfByte* pVisiLayer) const
+{
+    Rectangle aHitRect( pFlyFrm->Frm().Pos(), pFlyFrm->Frm().SSize() );
+    if ( nTol )
+    {
+        Rectangle aExclude( aHitRect );
+        aHitRect.Top()    -= nTol;
+        aHitRect.Bottom() += nTol;
+        aHitRect.Left()   -= nTol;
+        aHitRect.Right()  += nTol;
+        if( aHitRect.IsInside( rPnt ) )
+        {
+//          const SwFmtURL &rURL = pFlyFrm->GetFmt()->GetURL();
+            if( pFlyFrm->Lower() && pFlyFrm->Lower()->IsNoTxtFrm()
+                /*
+                JP 07.08.96: nach Umstellung von JOE zur 330 darf das nicht
+                            mehr sein!
+                && !rURL.GetURL().Len() && !rURL.GetMap()
+                */ )
+            {
+                //Vor dem Return noch 3a (siehe oben) pruefen.
+                SdrPage *pPg = GetPage();
+                for ( UINT32 i = GetOrdNumDirect()+1; i < pPg->GetObjCount(); ++i )
+                {
+                    SdrObject *pObj = pPg->GetObj( i );
+                    if ( pObj->IsWriterFlyFrame() &&
+                         ((SwVirtFlyDrawObj*)pObj)->GetBoundRect().IsInside( rPnt ) )
+                        return 0;
+                }
+                return (SdrObject*)this;
+            }
+            else
+            {
+                ViewShell *pShell = pFlyFrm->GetShell();
+
+                //4. Getroffen wenn das Objekt selektiert ist.
+                if ( pShell )
+                {
+                    const SdrMarkList &rMrkList = pShell->
+                                            Imp()->GetDrawView()->GetMarkList();
+                    for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
+                        if ( long(this) == long(rMrkList.GetMark(i)->GetObj()) )
+                            return (SdrObject*)this;
+                }
+
+                const Rectangle aPrtRect( pFlyFrm->Frm().Pos() + pFlyFrm->Prt().Pos(),
+                                          pFlyFrm->Prt().SSize() );
+                aExclude.Top()    += Max( long(nTol), aPrtRect.Top()   - aHitRect.Top() );
+                aExclude.Bottom() -= Max( long(nTol), aHitRect.Bottom()- aPrtRect.Bottom());
+                aExclude.Left()   += Max( long(nTol), aPrtRect.Left()  - aHitRect.Left() );
+                aExclude.Right()  -= Max( long(nTol), aHitRect.Right() - aPrtRect.Right() );
+                return aExclude.IsInside( rPnt ) ? 0 : (SdrObject*)this;
+            }
+        }
+    }
+    else
+        return aHitRect.IsInside( rPnt ) ? (SdrObject*)this : 0;
+    return 0;
+}
+
+/*************************************************************************
+|*
+|*  SwVirtFlyDrawObj::TakeObjInfo()
+|*
+|*  Ersterstellung      MA 03. May. 95
+|*  Letzte Aenderung    MA 03. May. 95
+|*
+*************************************************************************/
+
+void __EXPORT SwVirtFlyDrawObj::TakeObjInfo( SdrObjTransformInfoRec& rInfo ) const
+{
+    rInfo.bSelectAllowed     = rInfo.bMoveAllowed =
+    rInfo.bResizeFreeAllowed = rInfo.bResizePropAllowed = TRUE;
+
+    rInfo.bRotateFreeAllowed = rInfo.bRotate90Allowed =
+    rInfo.bMirrorFreeAllowed = rInfo.bMirror45Allowed =
+    rInfo.bMirror90Allowed   = rInfo.bShearAllowed    =
+    rInfo.bCanConvToPath     = rInfo.bCanConvToPoly   =
+    rInfo.bCanConvToPathLineToArea = rInfo.bCanConvToPolyLineToArea = FALSE;
+}
+
+
+/*************************************************************************
+|*
+|*  SwVirtFlyDrawObj::Groessenermittlung
+|*
+|*  Ersterstellung      MA 12. Jan. 95
+|*  Letzte Aenderung    MA 10. Nov. 95
+|*
+*************************************************************************/
+
+void SwVirtFlyDrawObj::SetRect() const
+{
+    if ( GetFlyFrm()->Frm().HasArea() )
+        ((SwVirtFlyDrawObj*)this)->aOutRect = GetFlyFrm()->Frm().SVRect();
+    else
+        ((SwVirtFlyDrawObj*)this)->aOutRect = Rectangle();
+}
+
+
+const Rectangle& __EXPORT SwVirtFlyDrawObj::GetBoundRect() const
+{
+    SetRect();
+    return aOutRect;
+}
+
+
+void __EXPORT SwVirtFlyDrawObj::RecalcBoundRect()
+{
+    SetRect();
+}
+
+
+void __EXPORT SwVirtFlyDrawObj::RecalcSnapRect()
+{
+    SetRect();
+}
+
+
+const Rectangle& __EXPORT SwVirtFlyDrawObj::GetSnapRect()  const
+{
+    SetRect();
+    return aOutRect;
+}
+
+
+void __EXPORT SwVirtFlyDrawObj::SetSnapRect(const Rectangle& rRect)
+{
+    Rectangle aTmp( aOutRect );
+    SetRect();
+    SetChanged();
+    SendRepaintBroadcast();
+    if (pUserCall!=NULL)
+        pUserCall->Changed(*this, SDRUSERCALL_RESIZE, aTmp);
+}
+
+
+void __EXPORT SwVirtFlyDrawObj::NbcSetSnapRect(const Rectangle& rRect)
+{
+    SetRect();
+}
+
+
+const Rectangle& __EXPORT SwVirtFlyDrawObj::GetLogicRect() const
+{
+    SetRect();
+    return aOutRect;
+}
+
+
+void __EXPORT SwVirtFlyDrawObj::SetLogicRect(const Rectangle& rRect)
+{
+    Rectangle aTmp( aOutRect );
+    SetRect();
+    SetChanged();
+    SendRepaintBroadcast();
+    if (pUserCall!=NULL)
+        pUserCall->Changed(*this, SDRUSERCALL_RESIZE, aTmp);
+}
+
+
+void __EXPORT SwVirtFlyDrawObj::NbcSetLogicRect(const Rectangle& rRect)
+{
+    SetRect();
+}
+
+
+void __EXPORT SwVirtFlyDrawObj::TakeXorPoly(XPolyPolygon& rPoly, FASTBOOL ) const
+{
+    rPoly = XPolyPolygon( XPolygon( GetFlyFrm()->Frm().SVRect() ) );
+}
+
+/*************************************************************************
+|*
+|*  SwVirtFlyDrawObj::Move() und Resize()
+|*
+|*  Ersterstellung      MA 12. Jan. 95
+|*  Letzte Aenderung    MA 26. Jul. 96
+|*
+*************************************************************************/
+
+void __EXPORT SwVirtFlyDrawObj::NbcMove(const Size& rSiz)
+{
+    MoveRect( aOutRect, rSiz );
+
+    const Point aOldPos( GetFlyFrm()->Frm().Pos() );
+    const Point aNewPos( aOutRect.TopLeft() );
+    const SwRect aFlyRect( aOutRect );
+
+    ASSERT( aOldPos != aNewPos, "PosUnchanged." );
+
+    //Wenn der Fly eine automatische Ausrichtung hat (rechts oder oben),
+    //so soll die Automatik erhalten bleiben
+    SwFrmFmt *pFmt = GetFlyFrm()->GetFmt();
+    const SwHoriOrient eHori = pFmt->GetHoriOrient().GetHoriOrient();
+    const SwVertOrient eVert = pFmt->GetVertOrient().GetVertOrient();
+    const SwRelationOrient eRelHori = pFmt->GetHoriOrient().GetRelationOrient();
+    const SwRelationOrient eRelVert = pFmt->GetVertOrient().GetRelationOrient();
+    //Bei Absatzgebundenen Flys muss ausgehend von der neuen Position ein
+    //neuer Anker gesetzt werden. Anker und neue RelPos werden vom Fly selbst
+    //berechnet und gesetzt.
+    if( GetFlyFrm()->IsFlyAtCntFrm() )
+        ((SwFlyAtCntFrm*)GetFlyFrm())->SetAbsPos( aNewPos );
+    else
+    {
+        const SwFrmFmt *pFmt = GetFmt();
+        const SwFmtVertOrient &rVert = pFmt->GetVertOrient();
+        const SwFmtHoriOrient &rHori = pFmt->GetHoriOrient();
+        long lXDiff = aNewPos.X() - aOldPos.X();
+        if( rHori.IsPosToggle() && HORI_NONE == eHori &&
+            !(GetFlyFrm()->FindPageFrm()->GetVirtPageNum() % 2) )
+            lXDiff = -lXDiff;
+        const long lYDiff = aNewPos.Y() - aOldPos.Y();
+        const Point aTmp( rHori.GetPos() + lXDiff,
+                          rVert.GetPos() + lYDiff );
+        GetFlyFrm()->ChgRelPos( aTmp );
+    }
+
+    SwAttrSet aSet( pFmt->GetDoc()->GetAttrPool(),
+                                            RES_VERT_ORIENT, RES_HORI_ORIENT );
+    SwFmtHoriOrient aHori( pFmt->GetHoriOrient() );
+    SwFmtVertOrient aVert( pFmt->GetVertOrient() );
+    FASTBOOL bPut = FALSE;
+
+    if( !GetFlyFrm()->IsFlyLayFrm() &&
+        ::GetHtmlMode(pFmt->GetDoc()->GetDocShell()) )
+    {
+        //Im HTML-Modus sind nur automatische Ausrichtungen erlaubt.
+        //Einzig einen Snap auf Links/Rechts bzw. Linker-/Rechter-Rand koennen
+        //wir versuchen.
+        SwFrm *pAnch = GetFlyFrm()->GetAnchor();
+        BOOL bNextLine = FALSE;
+
+        if( !GetFlyFrm()->IsAutoPos() || REL_PG_FRAME != aHori.GetRelationOrient() )
+        {
+            if( REL_CHAR == eRelHori )
+            {
+                aHori.SetHoriOrient( HORI_LEFT );
+                aHori.SetRelationOrient( REL_CHAR );
+            }
+            else
+            {
+                bNextLine = TRUE;
+                //Horizontale Ausrichtung:
+                const FASTBOOL bLeftFrm =
+                    aFlyRect.Left() < pAnch->Frm().Left() + pAnch->Prt().Left(),
+                    bLeftPrt = aFlyRect.Left() + aFlyRect.Width() <
+                               pAnch->Frm().Left() + pAnch->Prt().Width()/2;
+                if ( bLeftFrm || bLeftPrt )
+                {
+                    aHori.SetHoriOrient( HORI_LEFT );
+                    aHori.SetRelationOrient( bLeftFrm ? FRAME : PRTAREA );
+                }
+                else
+                {
+                    const FASTBOOL bRightFrm = aFlyRect.Left() >
+                                       pAnch->Frm().Left() + pAnch->Prt().Width();
+                    aHori.SetHoriOrient( HORI_RIGHT );
+                    aHori.SetRelationOrient( bRightFrm ? FRAME : PRTAREA );
+                }
+            }
+            aSet.Put( aHori );
+        }
+        //Vertikale Ausrichtung bleibt grundsaetzlich schlicht erhalten,
+        //nur bei nicht automatischer Ausrichtung wird umgeschaltet.
+        BOOL bRelChar = REL_CHAR == eRelVert;
+        aVert.SetVertOrient( eVert != VERT_NONE ? eVert :
+                GetFlyFrm()->IsFlyInCntFrm() ? VERT_CHAR_CENTER :
+                bRelChar && bNextLine ? VERT_CHAR_TOP : VERT_TOP );
+        if( bRelChar )
+            aVert.SetRelationOrient( REL_CHAR );
+        else
+            aVert.SetRelationOrient( PRTAREA );
+        aSet.Put( aVert );
+        bPut = TRUE;
+    }
+
+    //Automatische Ausrichtungen wollen wir moeglichst nicht verlieren.
+    if ( !bPut && bInResize )
+    {
+        if ( HORI_NONE != eHori )
+        {
+            aHori.SetHoriOrient( eHori );
+            aHori.SetRelationOrient( eRelHori );
+            aSet.Put( aHori );
+            bPut = TRUE;
+        }
+        if ( VERT_NONE != eVert )
+        {
+            aVert.SetVertOrient( eVert );
+            aVert.SetRelationOrient( eRelVert );
+            aSet.Put( aVert );
+            bPut = TRUE;
+        }
+    }
+    if ( bPut )
+        pFmt->SetAttr( aSet );
+}
+
+
+void __EXPORT SwVirtFlyDrawObj::NbcResize(const Point& rRef,
+            const Fraction& xFact, const Fraction& yFact)
+{
+    ResizeRect( aOutRect, rRef, xFact, yFact );
+
+    const Point aNewPos( aOutRect.TopLeft() );
+
+    Size aSz( aOutRect.Right() - aOutRect.Left() + 1,
+              aOutRect.Bottom()- aOutRect.Top()  + 1 );
+    if( aSz != GetFlyFrm()->Frm().SSize() )
+    {
+        //Die Breite darf bei Spalten nicht zu schmal werden
+        if ( GetFlyFrm()->Lower() && GetFlyFrm()->Lower()->IsColumnFrm() )
+        {
+            SwBorderAttrAccess aAccess( SwFrm::GetCache(), GetFlyFrm() );
+            const SwBorderAttrs &rAttrs = *aAccess.Get();
+            long nMin = rAttrs.CalcLeftLine()+rAttrs.CalcRightLine();
+            const SwFmtCol& rCol = rAttrs.GetAttrSet().GetCol();
+            if ( rCol.GetColumns().Count() > 1 )
+            {
+                for ( USHORT i = 0; i < rCol.GetColumns().Count(); ++i )
+                {
+                    nMin += rCol.GetColumns()[i]->GetLeft() +
+                            rCol.GetColumns()[i]->GetRight() +
+                            MINFLY;
+                }
+                nMin -= MINFLY;
+            }
+            aSz.Width() = Max( aSz.Width(), nMin );
+        }
+
+        SwFrmFmt *pFmt = GetFmt();
+        const SwFmtFrmSize aOldFrmSz( pFmt->GetFrmSize() );
+        GetFlyFrm()->ChgSize( aSz );
+        SwFmtFrmSize aFrmSz( pFmt->GetFrmSize() );
+        if ( aFrmSz.GetWidthPercent() || aFrmSz.GetHeightPercent() )
+        {
+            long nRelWidth, nRelHeight;
+            const SwFrm *pRel = GetFlyFrm()->IsFlyLayFrm() ?
+                                GetFlyFrm()->GetAnchor() :
+                                GetFlyFrm()->GetAnchor()->GetUpper();
+            const ViewShell *pSh = GetFlyFrm()->GetShell();
+            if ( pSh && pRel->IsBodyFrm() && pFmt->GetDoc()->IsBrowseMode() &&
+                 pSh->VisArea().HasArea() )
+            {
+                nRelWidth  = pSh->VisArea().Width();
+                nRelHeight = pSh->VisArea().Height();
+                const Size aBorder = pSh->GetOut()->PixelToLogic( pSh->GetBrowseBorder() );
+                nRelWidth  -= 2*aBorder.Width();
+                nRelHeight -= 2*aBorder.Height();
+            }
+            else
+            {
+                nRelWidth  = pRel->Prt().Width();
+                nRelHeight = pRel->Prt().Height();
+            }
+            if ( aFrmSz.GetWidthPercent() && aFrmSz.GetWidthPercent() != 0xFF &&
+                 aOldFrmSz.GetWidth() != aFrmSz.GetWidth() )
+                aFrmSz.SetWidthPercent( BYTE(aSz.Width() * 100L / nRelWidth + 0.5) );
+            if ( aFrmSz.GetHeightPercent() && aFrmSz.GetHeightPercent() != 0xFF &&
+                 aOldFrmSz.GetHeight() != aFrmSz.GetHeight() )
+                aFrmSz.SetHeightPercent( BYTE(aSz.Height() * 100L / nRelHeight + 0.5) );
+            pFmt->GetDoc()->SetAttr( aFrmSz, *pFmt );
+        }
+    }
+
+    //Position kann auch veraendert sein!
+    const Point aOldPos( GetFlyFrm()->Frm().Pos() );
+    if ( aNewPos != aOldPos )
+    {
+        //Kann sich durch das ChgSize veraendert haben!
+        if ( aOutRect.TopLeft() != aNewPos )
+            aOutRect.SetPos( aNewPos );
+        bInResize = TRUE;
+        NbcMove( Size( 0, 0 ) );
+        bInResize = FALSE;
+    }
+}
+
+
+void __EXPORT SwVirtFlyDrawObj::Move(const Size& rSiz)
+{
+    NbcMove( rSiz );
+    SetChanged();
+    GetFmt()->GetDoc()->SetNoDrawUndoObj( TRUE );
+}
+
+
+void __EXPORT SwVirtFlyDrawObj::Resize(const Point& rRef,
+                    const Fraction& xFact, const Fraction& yFact)
+{
+    NbcResize( rRef, xFact, yFact );
+    SetChanged();
+    GetFmt()->GetDoc()->SetNoDrawUndoObj( TRUE );
+}
+
+
+Pointer  __EXPORT SwVirtFlyDrawObj::GetMacroPointer(
+    const SdrObjMacroHitRec& rRec) const
+{
+    return Pointer( POINTER_REFHAND );
+}
+
+
+FASTBOOL __EXPORT SwVirtFlyDrawObj::HasMacro() const
+{
+    const SwFmtURL &rURL = pFlyFrm->GetFmt()->GetURL();
+    return rURL.GetMap() || rURL.GetURL().Len();
+}
+
+
+SdrObject* SwVirtFlyDrawObj::CheckMacroHit( const SdrObjMacroHitRec& rRec ) const
+{
+    const SwFmtURL &rURL = pFlyFrm->GetFmt()->GetURL();
+    if( rURL.GetMap() || rURL.GetURL().Len() )
+    {
+        SwRect aRect;
+        if ( pFlyFrm->Lower() && pFlyFrm->Lower()->IsNoTxtFrm() )
+        {
+            aRect = pFlyFrm->Prt();
+            aRect += pFlyFrm->Frm().Pos();
+        }
+        else
+            aRect = pFlyFrm->Frm();
+
+        if( aRect.IsInside( rRec.aPos ) )
+        {
+            SwRect aActRect( aRect );
+            Size aActSz( aRect.SSize() );
+            aRect.Pos().X() += rRec.nTol;
+            aRect.Pos().Y() += rRec.nTol;
+            aRect.SSize().Height()-= 2 * rRec.nTol;
+            aRect.SSize().Width() -= 2 * rRec.nTol;
+
+            if( aRect.IsInside( rRec.aPos ) )
+            {
+                if( !rURL.GetMap() ||
+                    pFlyFrm->GetFmt()->GetIMapObject( rRec.aPos, pFlyFrm ))
+                    return (SdrObject*)this;
+
+                return 0;
+            }
+        }
+    }
+    return SdrObject::CheckMacroHit( rRec );
+}
+
+
diff --git a/sw/source/core/draw/dobjfac.cxx b/sw/source/core/draw/dobjfac.cxx
new file mode 100644
index 000000000000..c38c30224c0a
--- /dev/null
+++ b/sw/source/core/draw/dobjfac.cxx
@@ -0,0 +1,100 @@
+/*************************************************************************
+ *
+ *  $RCSfile: dobjfac.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:18 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop           // fuer precompiled Header
+
+#ifndef _ERRHDL_HXX
+#include 
+#endif
+#ifndef _DPAGE_HXX
+#include 
+#endif
+#ifndef _DOBJFAC_HXX
+#include 
+#endif
+#ifndef _DFLYOBJ_HXX
+#include 
+#endif
+
+SwObjectFactory aSwObjectFactory;
+
+/*************************************************************************
+|*
+|* void SwObjectFactory::MakeObject()
+|*
+\************************************************************************/
+
+IMPL_LINK( SwObjectFactory, MakeObject, SdrObjFactory*, pObjFactory )
+{
+    if ( pObjFactory->nInventor == SWGInventor )
+    {
+        //Kein switch, derzeit gibt es nur einen.
+        ASSERT( pObjFactory->nIdentifier == SwFlyDrawObjIdentifier,
+                                        "Falscher Inventor oder identifier." );
+        pObjFactory->pNewObj = new SwFlyDrawObj();
+    }
+    return 0;
+}
+
+
diff --git a/sw/source/core/draw/dpage.cxx b/sw/source/core/draw/dpage.cxx
new file mode 100644
index 000000000000..da419f60bde8
--- /dev/null
+++ b/sw/source/core/draw/dpage.cxx
@@ -0,0 +1,375 @@
+/*************************************************************************
+ *
+ *  $RCSfile: dpage.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:18 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _BASMGR_HXX
+#include 
+#endif
+#ifndef _GOODIES_IMAPOBJ_HXX
+#include 
+#endif
+#ifndef SVTOOLS_URIHELPER_HXX
+#include 
+#endif
+#ifndef _URLOBJ_HXX //autogen
+#include 
+#endif
+#ifndef _SV_HELP_HXX //autogen
+#include 
+#endif
+#ifndef _SVDVIEW_HXX //autogen
+#include 
+#endif
+
+#ifndef _FMTURL_HXX //autogen
+#include 
+#endif
+#ifndef _FRMFMT_HXX //autogen
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _VIEWIMP_HXX
+#include 
+#endif
+#ifndef _PAGEFRM_HXX
+#include 
+#endif
+#ifndef _CNTFRM_HXX
+#include 
+#endif
+#ifndef _ROOTFRM_HXX
+#include 
+#endif
+#ifndef _ERRHDL_HXX
+#include 
+#endif
+#ifndef _SWTYPES_HXX
+#include 
+#endif
+#ifndef _FRMATR_HXX
+#include 
+#endif
+#ifndef _VIEWSH_HXX
+#include 
+#endif
+#ifndef _DRAWDOC_HXX
+#include 
+#endif
+#ifndef _DPAGE_HXX
+#include 
+#endif
+#ifndef _DCONTACT_HXX
+#include 
+#endif
+#ifndef _DFLYOBJ_HXX
+#include 
+#endif
+#ifndef _DOCSH_HXX
+#include 
+#endif
+#ifndef _USRFLD_HXX
+#include 
+#endif
+#ifndef _FLYFRM_HXX
+#include 
+#endif
+#ifndef _NDNOTXT_HXX
+#include 
+#endif
+#ifndef _GRFATR_HXX
+#include 
+#endif
+
+
+SwDPage::SwDPage(SwDrawDocument& rNewModel, BOOL bMasterPage) :
+    FmFormPage(rNewModel, 0, bMasterPage),
+    pGridLst( 0 )
+{
+}
+
+
+SwDPage::~SwDPage()
+{
+    delete pGridLst;
+}
+
+
+Point  SwDPage::GetOffset() const
+{
+    return Point( DOCUMENTBORDER, DOCUMENTBORDER );
+}
+
+/*************************************************************************
+|*
+|*  SwDPage::ReplaceObject()
+|*
+|*  Ersterstellung      MA 07. Aug. 95
+|*  Letzte Aenderung    MA 07. Aug. 95
+|*
+*************************************************************************/
+
+SdrObject*  SwDPage::ReplaceObject( SdrObject* pNewObj, ULONG nObjNum )
+{
+    SdrObject *pOld = GetObj( nObjNum );
+    ASSERT( pOld, "Oups, Object not replaced" );
+    SdrObjUserCall* pContact;
+    if ( 0 != ( pContact = GetUserCall(pOld) ) &&
+         RES_DRAWFRMFMT == ((SwContact*)pContact)->GetFmt()->Which())
+        ((SwDrawContact*)pContact)->ChangeMasterObject( pNewObj );
+    return FmFormPage::ReplaceObject( pNewObj, nObjNum );
+}
+
+/*************************************************************************
+|*
+|*  SwDPage::GetGridFrameList()
+|*
+|*  Ersterstellung      MA 04. Sep. 95
+|*  Letzte Aenderung    MA 15. Feb. 96
+|*
+*************************************************************************/
+
+void InsertGridFrame( SdrPageGridFrameList *pLst, const SwFrm *pPg )
+{
+    SwRect aPrt( pPg->Prt() );
+    aPrt += pPg->Frm().Pos();
+    const Rectangle aUser( aPrt.SVRect() );
+    const Rectangle aPaper( pPg->Frm().SVRect() );
+    pLst->Insert( SdrPageGridFrame( aPaper, aUser ) );
+}
+
+
+const SdrPageGridFrameList*  SwDPage::GetGridFrameList(
+                        const SdrPageView* pPV, const Rectangle *pRect ) const
+{
+    ViewShell *pSh = ((SwDrawDocument*)GetModel())->GetDoc().GetRootFrm()->GetCurrShell();
+    if ( pSh )
+    {
+        while ( pSh->Imp()->GetPageView() != pPV )
+            pSh = (ViewShell*)pSh->GetNext();
+        if ( pSh )
+        {
+            if ( pGridLst )
+                ((SwDPage*)this)->pGridLst->Clear();
+            else
+                ((SwDPage*)this)->pGridLst = new SdrPageGridFrameList;
+
+            if ( pRect )
+            {
+                //Das Drawing verlang alle Seiten, die mit dem Rect ueberlappen.
+                const SwRect aRect( *pRect );
+                const SwFrm *pPg = pSh->GetLayout()->Lower();
+                do
+                {   if ( pPg->Frm().IsOver( aRect ) )
+                        ::InsertGridFrame( ((SwDPage*)this)->pGridLst, pPg );
+                    pPg = pPg->GetNext();
+                } while ( pPg );
+            }
+            else
+            {
+                //Das Drawing verlangt alle sichbaren Seiten
+                const SwFrm *pPg = pSh->Imp()->GetFirstVisPage();
+                if ( pPg )
+                    do
+                    {   ::InsertGridFrame( ((SwDPage*)this)->pGridLst, pPg );
+                        pPg = pPg->GetNext();
+                    } while ( pPg && pPg->Frm().IsOver( pSh->VisArea() ) );
+            }
+        }
+    }
+    return pGridLst;
+}
+
+/*************************************************************************
+|*
+|*  String SwDPage::GetLinkData( const String& )
+|*  void SwDPage::SetLinkData( const String&, const String& )
+|*  void SwDPage::UpdateLinkData( const String&, const String& )
+|*
+|*  Ersterstellung      JP 04.09.95
+|*  Letzte Aenderung    JP 04.09.95
+|*
+*************************************************************************/
+
+String SwDPage::GetLinkData( const String& rLinkName )
+{
+    SwDoc& rDoc = ((SwDrawDocument*)GetModel())->GetDoc();
+    SwFieldType* pFTyp = rDoc.GetFldType( RES_USERFLD, rLinkName );
+    if( pFTyp )
+        return ((SwUserFieldType*)pFTyp)->GetContent();
+    return aEmptyStr;
+}
+
+
+void  SwDPage::SetLinkData( const String& rLinkName,
+                                    const String& rLinkData )
+{
+    SwDoc& rDoc = ((SwDrawDocument*)GetModel())->GetDoc();
+    SwFieldType* pFTyp = rDoc.GetFldType( RES_USERFLD, rLinkName );
+    if( pFTyp )
+        ((SwUserFieldType*)pFTyp)->CtrlSetContent( rLinkData );
+}
+
+
+void  SwDPage::RequestBasic()
+{
+    SwDoc& rDoc = ((SwDrawDocument*)GetModel())->GetDoc();
+    if( rDoc.GetDocShell() )
+    {
+        BasicManager *pBasicMgr = rDoc.GetDocShell()->GetBasicManager();
+        ASSERT( pBasicMgr, "wo ist mein BasicManager" )
+        SetBasic( pBasicMgr->GetLib( 0 ) );
+    }
+    else
+        ASSERT( !this, "wo ist meine DocShell" )
+}
+
+
+BOOL SwDPage::RequestHelp( Window* pWindow, SdrView* pView,
+                           const HelpEvent& rEvt )
+{
+    BOOL bWeiter = TRUE;
+
+    if( rEvt.GetMode() & ( HELPMODE_QUICK | HELPMODE_BALLOON ))
+    {
+        Point aPos( rEvt.GetMousePosPixel() );
+        aPos = pWindow->ScreenToOutputPixel( aPos );
+        aPos = pWindow->PixelToLogic( aPos );
+
+        SdrPageView* pPV;
+        SdrObject* pObj;
+        if( pView->PickObj( aPos, 0, pObj, pPV, SDRSEARCH_PICKMACRO ) &&
+             pObj->IsWriterFlyFrame() )
+        {
+            SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+            const SwFmtURL &rURL = pFly->GetFmt()->GetURL();
+            String sTxt;
+            if( rURL.GetMap() )
+            {
+                IMapObject *pObj = pFly->GetFmt()->GetIMapObject( aPos, pFly );
+                if( pObj )
+                {
+                    sTxt = pObj->GetDescription();
+                    if ( !sTxt.Len() )
+                        sTxt = URIHelper::removePassword( pObj->GetURL(),
+                                        INetURLObject::WAS_ENCODED,
+                                           INetURLObject::DECODE_WITH_CHARSET );
+                }
+            }
+            else if ( rURL.GetURL().Len() )
+            {
+                sTxt = URIHelper::removePassword( rURL.GetURL(),
+                                        INetURLObject::WAS_ENCODED,
+                                           INetURLObject::DECODE_WITH_CHARSET );
+
+                if( rURL.IsServerMap() )
+                {
+                    // dann die rel. Pixel Position anhaengen !!
+                    Point aPt( aPos );
+                    aPt -= pFly->Frm().Pos();
+                    // ohne MapMode-Offset !!!!!
+                    // ohne MapMode-Offset, ohne Offset, o ... !!!!!
+                    aPt = (Point&)(Size&)pWindow->LogicToPixel(
+                            (Size&)aPt, MapMode( MAP_TWIP ) );
+                    ((( sTxt += '?' ) += String::CreateFromInt32( aPt.X() ))
+                             += ',' ) += String::CreateFromInt32( aPt.Y() );
+                }
+            }
+
+            if ( sTxt.Len() )
+            {
+                if( rEvt.GetMode() & HELPMODE_QUICK )
+                {
+                    // dann zeige die Hilfe mal an:
+                    Rectangle aRect( rEvt.GetMousePosPixel(), Size(1,1) );
+/*
+Bug 29593: QuickHelp immer an der MausPosition anzeigen (besonders unter OS/2)
+
+                    Rectangle aRect( pObj->GetSnapRect() );
+                    Point aPt( pWindow->OutputToScreenPixel( pWindow->LogicToPixel( aRect.TopLeft() )));
+                    aRect.Left()   = aPt.X();
+                    aRect.Top()    = aPt.Y();
+                    aPt = pWindow->OutputToScreenPixel( pWindow->LogicToPixel( aRect.BottomRight() ));
+                    aRect.Right()  = aPt.X();
+                    aRect.Bottom() = aPt.Y();
+*/
+                    Help::ShowQuickHelp( pWindow, aRect, sTxt );
+                }
+                else
+                    Help::ShowBalloon( pWindow, rEvt.GetMousePosPixel(), sTxt );
+                bWeiter = FALSE;
+            }
+        }
+    }
+
+    if( bWeiter )
+        bWeiter = !FmFormPage::RequestHelp( pWindow, pView, rEvt );
+
+    return bWeiter;
+}
+
+
+
diff --git a/sw/source/core/draw/drawdoc.cxx b/sw/source/core/draw/drawdoc.cxx
new file mode 100644
index 000000000000..f2cc8c87c343
--- /dev/null
+++ b/sw/source/core/draw/drawdoc.cxx
@@ -0,0 +1,279 @@
+/*************************************************************************
+ *
+ *  $RCSfile: drawdoc.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:18 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _SVX_SVXIDS_HRC
+#include 
+#endif
+#ifndef _STREAM_HXX //autogen
+#include 
+#endif
+#ifndef _SFXINIMGR_HXX //autogen
+#include 
+#endif
+#ifndef _SFXINTITEM_HXX
+#include 
+#endif
+#ifndef _SVSTOR_HXX //autogen
+#include 
+#endif
+#ifndef _OFF_APP_HXX //autogen
+#include 
+#endif
+
+#define ITEMID_COLOR_TABLE      SID_COLOR_TABLE
+#define ITEMID_GRADIENT_LIST    SID_GRADIENT_LIST
+#define ITEMID_HATCH_LIST       SID_HATCH_LIST
+#define ITEMID_BITMAP_LIST      SID_BITMAP_LIST
+#define ITEMID_DASH_LIST        SID_DASH_LIST
+#define ITEMID_LINEEND_LIST     SID_LINEEND_LIST
+#ifndef _SVX_DRAWITEM_HXX
+#include 
+#endif
+
+#ifndef _VIEWSH_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _ROOTFRM_HXX
+#include 
+#endif
+#ifndef _DRAWDOC_HXX
+#include 
+#endif
+#ifndef _DPAGE_HXX
+#include 
+#endif
+#ifndef _DOCSH_HXX
+#include 
+#endif
+#ifndef _SHELLIO_HXX
+#include 
+#endif
+#ifndef _SW3IO_HXX
+#include 
+#endif
+
+
+
+/*************************************************************************
+|*
+|* Konstruktor
+|*
+\************************************************************************/
+
+
+SwDrawDocument::SwDrawDocument( SwDoc* pD ) :
+    FmFormModel( SFX_APP()->GetAppIniManager()->Get(
+                                        SFX_KEY_PALETTE_PATH ),
+                 &pD->GetAttrPool(), 0, TRUE ),
+    pDoc( pD )
+{
+    SetScaleUnit( MAP_TWIP );
+    SetDefaultFontHeight( 240 );
+    SetSwapGraphics( TRUE );
+
+    SwDocShell* pDocSh = pDoc->GetDocShell();
+    if ( pDocSh )
+    {
+        SetObjectShell( pDocSh );
+        SvxColorTableItem* pColItem = ( SvxColorTableItem* )
+                                ( pDocSh->GetItem( ITEMID_COLOR_TABLE ) );
+        XColorTable *pXCol = pColItem ? pColItem->GetColorTable() :
+                                        OFF_APP()->GetStdColorTable();
+        SetColorTable( pXCol );
+
+        if ( !pColItem )
+            pDocSh->PutItem( SvxColorTableItem( pXCol ) );
+
+        pDocSh->PutItem( SvxGradientListItem( GetGradientList() ));
+        pDocSh->PutItem( SvxHatchListItem( GetHatchList() ) );
+        pDocSh->PutItem( SvxBitmapListItem( GetBitmapList() ) );
+        pDocSh->PutItem( SvxDashListItem( GetDashList() ) );
+        pDocSh->PutItem( SvxLineEndListItem( GetLineEndList() ) );
+        pDocSh->PutItem( SfxUInt16Item(SID_ATTR_LINEEND_WIDTH_DEFAULT, 111) );
+        SetObjectShell( pDocSh );
+    }
+    else
+        SetColorTable( OFF_APP()->GetStdColorTable() );
+}
+
+/*************************************************************************
+|*
+|* Konstruktor, fuer einfuegen Document
+|*
+\************************************************************************/
+
+
+SwDrawDocument::SwDrawDocument( SfxItemPool *pPool, SwDocShell *pDocSh )
+    : FmFormModel( SFX_APP()->GetAppIniManager()->
+                                Get( SFX_KEY_PALETTE_PATH ),
+                     pPool, 0, TRUE ),
+    pDoc( pDocSh->GetDoc() )
+{
+    SetScaleUnit( MAP_TWIP );
+    SetDefaultFontHeight( 240 );
+    SetSwapGraphics( TRUE );
+
+    ASSERT( pDocSh, "DocShell not found" );
+    SvxColorTableItem* pColItem = ( SvxColorTableItem* )
+                                ( pDocSh->GetItem( ITEMID_COLOR_TABLE ) );
+    XColorTable *pXCol = pColItem ? pColItem->GetColorTable() :
+                                    OFF_APP()->GetStdColorTable();
+    SetColorTable( pXCol );
+
+    if ( !pColItem )
+        pDocSh->PutItem( SvxColorTableItem( pXCol ) );
+
+    // Bug 35371:
+    //  fuers "Datei einfuegen" NIE die anderen Items an der DocShell setzen!!!
+    // Diese zeigen sonst immer in das temporaere SdrModel !
+    SetObjectShell( pDocSh );
+}
+
+/*************************************************************************
+|*
+|* Destruktor
+|*
+\************************************************************************/
+
+
+SwDrawDocument::~SwDrawDocument()
+{
+    Clear();
+}
+
+/*************************************************************************
+|*
+|* Diese Methode erzeugt eine neue Seite (SdPage) und gibt einen Zeiger
+|* darauf zurueck. Die Drawing Engine benutzt diese Methode beim Laden
+|* zur Erzeugung von Seiten (deren Typ sie ja nicht kennt, da es ABLEITUNGEN
+|* der SdrPage sind).
+|*
+\************************************************************************/
+
+
+SdrPage* SwDrawDocument::AllocPage(FASTBOOL bMasterPage)
+{
+    SwDPage* pPage = new SwDPage(*this, bMasterPage);
+    pPage->SetName( String::CreateFromAscii(
+                                    RTL_CONSTASCII_STRINGPARAM( "Controls" )) );
+    return pPage;
+}
+
+
+SvStream* SwDrawDocument::GetDocumentStream( FASTBOOL& rbDeleteAfterUse ) const
+{
+    SvStream* pRet = 0;
+    SvStorageRef xRoot( pDoc->GetDocStorage() );
+    String sDrawStrmNm( String::CreateFromAscii(
+                    RTL_CONSTASCII_STRINGPARAM( DRAWING_STREAM_NAME )));
+    if( xRoot.Is() && SVSTREAM_OK == xRoot->GetError() &&
+        xRoot->IsStream( sDrawStrmNm ) )
+    {
+        long nFFVersion = xRoot->GetVersion();
+        ASSERT( nFFVersion == SOFFICE_FILEFORMAT_31 ||
+                nFFVersion == SOFFICE_FILEFORMAT_40 ||
+                nFFVersion == SOFFICE_FILEFORMAT_NOW,
+                "Am Root-Storage ist keine FF-Version gesetzt!" );
+
+        // Wenn eine 3.1-Clipboard-ID gesetzt ist, die Fileformat-Version
+        // auf 3.1 setzten.
+        if( SOT_FORMATSTR_ID_STARWRITER_30 == xRoot->GetFormat() &&
+            nFFVersion != SOFFICE_FILEFORMAT_31 )
+        {
+            ASSERT( nFFVersion == SOFFICE_FILEFORMAT_31,
+                    "Fileformat-Version auf 3.1 umgesetzt" );
+            xRoot->SetVersion( nFFVersion = SOFFICE_FILEFORMAT_31 );
+        }
+        else if( ( SOT_FORMATSTR_ID_STARWRITER_40 == xRoot->GetFormat() ||
+                   SOT_FORMATSTR_ID_STARWRITERWEB_40 == xRoot->GetFormat() ||
+                   SOT_FORMATSTR_ID_STARWRITERGLOB_40 == xRoot->GetFormat() ) &&
+                 nFFVersion != SOFFICE_FILEFORMAT_40 )
+        {
+            ASSERT( nFFVersion == SOFFICE_FILEFORMAT_40,
+                    "Fileformat-Version auf 4.0 umgesetzt" );
+            xRoot->SetVersion( nFFVersion = SOFFICE_FILEFORMAT_40 );
+        }
+
+        pRet = xRoot->OpenStream( sDrawStrmNm,
+                    STREAM_READ | STREAM_SHARE_DENYWRITE | STREAM_NOCREATE );
+        if( pRet )
+            rbDeleteAfterUse = TRUE;
+    }
+    return pRet;
+}
+
+SdrLayerID SwDrawDocument::GetControlExportLayerId( const SdrObject & ) const
+{
+    //fuer Versionen < 5.0, es gab nur Hell und Heaven
+    return (SdrLayerID)pDoc->GetHeavenId();
+}
+
+
+
+
diff --git a/sw/source/core/draw/dview.cxx b/sw/source/core/draw/dview.cxx
new file mode 100644
index 000000000000..b68629732c36
--- /dev/null
+++ b/sw/source/core/draw/dview.cxx
@@ -0,0 +1,688 @@
+/*************************************************************************
+ *
+ *  $RCSfile: dview.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:18 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "hintids.hxx"
+
+#ifndef _SVX_PROTITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVDPAGV_HXX //autogen
+#include 
+#endif
+#ifndef _FM_FMMODEL_HXX
+#include 
+#endif
+#ifndef _IPOBJ_HXX //autogen
+#include 
+#endif
+
+
+#include "swtypes.hxx"
+#include "pagefrm.hxx"
+#include "rootfrm.hxx"
+#include "cntfrm.hxx"
+#include "flyfrm.hxx"
+#include "frmfmt.hxx"
+#include "dflyobj.hxx"
+#include "dcontact.hxx"
+#include "frmatr.hxx"
+#include "viewsh.hxx"
+#include "viewimp.hxx"
+#include "dview.hxx"
+#include "dpage.hxx"
+#include "doc.hxx"
+#include "mdiexp.hxx"
+
+#ifndef _NDOLE_HXX //autogen
+#include 
+#endif
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#include "shellres.hxx"
+
+
+const SwFrm *lcl_FindAnchor( const SdrObject *pObj, FASTBOOL bAll )
+{
+    const SwVirtFlyDrawObj *pVirt = pObj->IsWriterFlyFrame() ?
+                                            (SwVirtFlyDrawObj*)pObj : 0;
+    if ( pVirt )
+    {
+        if ( bAll || !pVirt->GetFlyFrm()->IsFlyInCntFrm() )
+            return pVirt->GetFlyFrm()->GetAnchor();
+    }
+    else
+    {
+        const SwDrawContact *pCont = (const SwDrawContact*)GetUserCall(pObj);
+        if ( pCont )
+            return pCont->GetAnchor();
+    }
+    return 0;
+}
+
+/*************************************************************************
+|*
+|*  SwDrawView::Ctor
+|*
+|*  Ersterstellung      OK 18.11.94
+|*  Letzte Aenderung    MA 22. Jul. 96
+|*
+*************************************************************************/
+
+
+
+SwDrawView::SwDrawView( SwViewImp &rI, SdrModel *pMd, OutputDevice *pOutDev) :
+    FmFormView( (FmFormModel*)pMd, pOutDev ),
+    rImp( rI )
+{
+    SetPageVisible( FALSE );
+    SetBordVisible( FALSE );
+    SetGridVisible( FALSE );
+    SetHlplVisible( FALSE );
+    SetGlueVisible( FALSE );
+    SetFrameDragSingles( TRUE );
+    SetVirtualObjectBundling( TRUE );
+    SetSwapAsynchron( TRUE );
+
+    EnableExtendedKeyInputDispatcher( FALSE );
+    EnableExtendedMouseEventDispatcher( FALSE );
+    EnableExtendedCommandEventDispatcher( FALSE );
+
+    SetHitTolerancePixel( GetMarkHdlSizePixel()/2 );
+
+    SetPrintPreview( rI.GetShell()->IsPreView() );
+}
+
+/*************************************************************************
+|*
+|*  SwDrawView::AddCustomHdl()
+|*
+|*  Gets called every time the handles need to be build
+|*
+|*  Ersterstellung      AW 06. Sep. 99
+|*  Letzte Aenderung    AW 06. Sep. 99
+|*
+*************************************************************************/
+
+void SwDrawView::AddCustomHdl()
+{
+    const SdrMarkList &rMrkList = GetMarkList();
+
+    if(rMrkList.GetMarkCount() != 1 || !GetUserCall(rMrkList.GetMark( 0 )->GetObj()))
+        return;
+
+    SdrObject *pObj = rMrkList.GetMark(0)->GetObj();
+    const SwFmtAnchor &rAnchor = ::FindFrmFmt(pObj)->GetAnchor();
+
+    if(FLY_IN_CNTNT == rAnchor.GetAnchorId())
+        return;
+
+    const SwFrm* pAnch;
+    if(0 == (pAnch = CalcAnchor()))
+        return;
+
+    ViewShell &rSh = *Imp().GetShell();
+    Point aPos(aAnchorPoint);
+
+    if(FLY_AUTO_CNTNT == rAnchor.GetAnchorId())
+    {
+        SwRect aAutoPos;
+        pAnch->GetCharRect(aAutoPos, *rAnchor.GetCntntAnchor());
+        aPos = aAutoPos.Pos();
+    }
+
+    // add anchor handle:
+    aHdl.AddHdl(new SdrHdl(aPos ,HDL_ANCHOR));
+}
+
+/*************************************************************************
+|*
+|*  SwDrawView::GetMaxToTopObj(), _GetMaxToTopObj()
+|*
+|*  Ersterstellung      MA 13. Jan. 95
+|*  Letzte Aenderung    MA 18. Mar. 97
+|*
+*************************************************************************/
+
+
+SdrObject* SwDrawView::GetMaxToTopObj( SdrObject* pObj ) const
+{
+    if ( GetUserCall(pObj) )
+    {
+        const SwFrm *pAnch = ::lcl_FindAnchor( pObj, FALSE );
+        if ( pAnch )
+        {
+            //Das oberste Obj innerhalb des Ankers darf nicht ueberholt
+            //werden.
+            const SwFlyFrm *pFly = pAnch->FindFlyFrm();
+            if ( pFly )
+            {
+                const SwPageFrm *pPage = pFly->FindPageFrm();
+                if ( pPage->GetSortedObjs() )
+                {
+                    UINT32 nOrdNum = 0;
+                    for ( USHORT i = 0; i < pPage->GetSortedObjs()->Count(); ++i )
+                    {
+                        const SdrObject *pO = (*pPage->GetSortedObjs())[i];
+
+                        if ( pO->GetOrdNumDirect() > nOrdNum )
+                        {
+                            const SwFrm *pAnch = ::lcl_FindAnchor( pO, FALSE );
+                            if ( pFly->IsAnLower( pAnch ) )
+                            {
+                                nOrdNum = pO->GetOrdNumDirect();
+                            }
+                        }
+                    }
+                    if ( nOrdNum )
+                    {
+                        SdrPage *pPage = GetModel()->GetPage( 0 );
+                        ++nOrdNum;
+                        if ( nOrdNum < pPage->GetObjCount() )
+                        {
+                            return pPage->GetObj( nOrdNum );
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return 0;
+}
+
+/*************************************************************************
+|*
+|*  SwDrawView::GetMaxToBtmObj()
+|*
+|*  Ersterstellung      MA 13. Jan. 95
+|*  Letzte Aenderung    MA 05. Sep. 96
+|*
+*************************************************************************/
+
+
+SdrObject* SwDrawView::GetMaxToBtmObj(SdrObject* pObj) const
+{
+    if ( GetUserCall(pObj) )
+    {
+        const SwFrm *pAnch = ::lcl_FindAnchor( pObj, FALSE );
+        if ( pAnch )
+        {
+            //Der Fly des Ankers darf nicht "unterflogen" werden.
+            const SwFlyFrm *pFly = pAnch->FindFlyFrm();
+            if ( pFly )
+            {
+                SdrObject *pRet = (SdrObject*)pFly->GetVirtDrawObj();
+                return pRet != pObj ? pRet : 0;
+            }
+        }
+    }
+    return 0;
+}
+
+/*************************************************************************
+|*
+|*  SwDrawView::ObjOrderChanged()
+|*
+|*  Ersterstellung      MA 31. Jul. 95
+|*  Letzte Aenderung    MA 18. Mar. 97
+|*
+*************************************************************************/
+
+inline BOOL lcl_IsChild( SdrObject *pParent, SdrObject *pChild )
+{
+    if ( pParent->IsWriterFlyFrame() )
+    {
+        const SwFrm *pAnch = lcl_FindAnchor( pChild, FALSE );
+        if ( pAnch && ((SwVirtFlyDrawObj*)pParent)->GetFlyFrm()->IsAnLower( pAnch ))
+        {
+            return TRUE;
+        }
+    }
+    return FALSE;
+}
+
+inline SdrObject *lcl_FindParent( SdrObject *pObj )
+{
+    const SwFrm *pAnch = lcl_FindAnchor( pObj, FALSE );
+    if ( pAnch && pAnch->IsInFly() )
+        return (SdrObject*)pAnch->FindFlyFrm()->GetVirtDrawObj();
+    return 0;
+}
+
+
+
+void SwDrawView::ObjOrderChanged( SdrObject* pObj, ULONG nOldPos,
+                                          ULONG nNewPos )
+{
+    SdrPage *pPg = GetModel()->GetPage( 0 );
+    if ( pPg->IsObjOrdNumsDirty() )
+        pPg->RecalcObjOrdNums();
+    const BOOL bBtm = nOldPos > nNewPos;
+    ULONG nMoveTo = ULONG_MAX;
+
+    //Wenn ein Object nach oben geschoben werden soll, so muss es wenigstens
+    //seine Kinder plus einem ueberspringen.
+    if ( !bBtm && nNewPos < pPg->GetObjCount() - 1 )
+    {
+        ULONG nPos = nOldPos;
+        SdrObject *pTmp = pPg->GetObj( nPos );
+        while ( pTmp == pObj || lcl_IsChild( pObj, pTmp ) )
+        {
+            ++nPos;
+            pTmp = pPg->GetObj( nPos );
+        }
+        if ( nPos > nNewPos )
+            nMoveTo = nPos;
+    }
+    if ( nMoveTo != ULONG_MAX )
+    {
+        if ( nMoveTo <= nNewPos )
+            ++nMoveTo;
+        pPg->SetObjectOrdNum( nNewPos, nMoveTo );
+        if ( pPg->IsObjOrdNumsDirty() )
+            pPg->RecalcObjOrdNums();
+        nNewPos = nMoveTo;
+        nMoveTo = ULONG_MAX;
+    }
+
+    //Kein Objekt darf in eine Schachtelung von Rahmen/Objekten eindringen,
+    //die Kette muss ggf. uebersprungen werden.
+    if ( bBtm )
+    {
+        if ( nNewPos > 0 )
+        {
+            SdrObject *pMax = GetMaxToBtmObj( pObj ),
+                      *pO = pPg->GetObj( nNewPos + 1 ),
+                      *pPre = pO;
+            while ( pO && 0 != (pO = GetMaxToBtmObj( pO )))
+            {
+                if ( pO != pMax )
+                    nMoveTo = pO->GetOrdNumDirect();
+                if ( pO == pPre )
+                    break;
+            }
+        }
+    }
+    else
+    {
+        if ( nNewPos < pPg->GetObjCount() - 1 )
+        {
+            ULONG nPos = nNewPos;
+            SdrObject *pMyParent = lcl_FindParent( pObj ),
+                      *pNxt      = pPg->GetObj( nPos + 1 ),
+                      *pNxtParent= lcl_FindParent( pNxt );
+            while ( pNxtParent && pNxtParent != pMyParent )
+            {
+                nMoveTo = ++nPos;
+                if ( nPos < pPg->GetObjCount() - 1 )
+                {
+                    pNxt       = pPg->GetObj( nPos + 1 );
+                    pNxtParent = lcl_FindParent( pNxt );
+                }
+                else
+                    break;
+            }
+        }
+    }
+    if ( nMoveTo != ULONG_MAX )
+    {
+        pPg->SetObjectOrdNum( nNewPos, nMoveTo );
+        if ( pPg->IsObjOrdNumsDirty() )
+            pPg->RecalcObjOrdNums();
+        nNewPos = nMoveTo;
+    }
+
+    if ( pObj->IsWriterFlyFrame() )
+    {
+        //Ein Rahmen wurde in seiner Order veraendert. Hier muss nachtraeglich
+        //dafuer gesorgt werden, dass seine 'Kinder' nachgezogen werden.
+        const SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+        if ( pPg->IsObjOrdNumsDirty() )
+            pPg->RecalcObjOrdNums();
+        if ( bBtm )
+            ++nNewPos;
+        BOOL bFound = FALSE;
+        for ( ULONG i = nOldPos; i < pPg->GetObjCount(); ++i )
+        {
+            SdrObject *pO = pPg->GetObj( i );
+            if ( pO == pObj )
+                break;
+            const SwFrm *pAnch;
+            const BOOL bFly = pO->IsWriterFlyFrame();
+            if ( bFly )
+                pAnch = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm()->GetAnchor();
+            else
+                pAnch = ((SwDrawContact*)GetUserCall(pO))->GetAnchor();
+            const SwFlyFrm *pF = pAnch ? pAnch->FindFlyFrm() : NULL;
+            if ( pF && (pF == pFly || pFly->IsUpperOf( pAnch->FindFlyFrm())))
+            {
+                //Kind gefunden, verschieben.
+                pPg->SetObjectOrdNum( i, nNewPos );
+                pPg->RecalcObjOrdNums();
+                --i;    //keinen auslassen
+            }
+        }
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwDrawView::TakeDragLimit()
+|*
+|*  Ersterstellung      AMA 26. Apr. 96
+|*  Letzte Aenderung    MA 03. May. 96
+|*
+*************************************************************************/
+
+
+BOOL SwDrawView::TakeDragLimit( SdrDragMode eMode,
+                                            Rectangle& rRect ) const
+{
+    const SdrMarkList &rMrkList = GetMarkList();
+    BOOL bRet = FALSE;
+    if( 1 == rMrkList.GetMarkCount() )
+    {
+        const SdrObject *pObj = rMrkList.GetMark( 0 )->GetObj();
+        SwRect aRect;
+        if( ::CalcClipRect( pObj, aRect, eMode == SDRDRAG_MOVE ) )
+        {
+            rRect = aRect.SVRect();
+             bRet = TRUE;
+        }
+    }
+    return bRet;
+}
+
+/*************************************************************************
+|*
+|*  SwDrawView::CalcAnchor()
+|*
+|*  Ersterstellung      MA 13. Jan. 95
+|*  Letzte Aenderung    MA 08. Nov. 96
+|*
+*************************************************************************/
+
+
+const SwFrm *SwDrawView::CalcAnchor()
+{
+    const SdrMarkList &rMrkList = GetMarkList();
+    if ( rMrkList.GetMarkCount() != 1 )
+        return NULL;
+
+    SdrObject *pObj = rMrkList.GetMark( 0 )->GetObj();
+
+    Point aPt;
+    if ( IsAction() )
+    {
+        if ( !TakeDragObjAnchorPos( aPt ) )
+            return NULL;
+    }
+    else
+        aPt = pObj->GetAnchorPos() + pObj->GetRelativePos();
+
+    //Fuer Absatzgebundene Objekte suchen, andernfalls einfach nur
+    //der aktuelle Anker. Nur suchen wenn wir gerade draggen.
+    const SwFrm *pAnch;
+    Point aMyPt;
+    const BOOL bFly = pObj->IsWriterFlyFrame();
+    if ( bFly )
+    {
+        pAnch = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->GetAnchor();
+        aMyPt = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->Frm().Pos();
+    }
+    else
+    {
+        SwDrawContact *pC = (SwDrawContact*)GetUserCall(pObj);
+        pAnch = pC->GetAnchor();
+        if( !pAnch )
+        {
+            pC->ConnectToLayout();
+            pAnch = pC->GetAnchor();
+        }
+        aMyPt = pObj->GetAnchorPos() + pObj->GetRelativePos();
+    }
+
+    if ( aPt != aMyPt )
+    {
+        if ( pAnch->IsCntntFrm() )
+            pAnch = ::FindAnchor( (SwCntntFrm*)pAnch, aPt, !bFly );
+        else if ( !bFly )
+        {   const SwRect aRect( aPt.X(), aPt.Y(), 1, 1 );
+            SwDrawContact* pContact = (SwDrawContact*)GetUserCall(pObj);
+            if( pContact->GetAnchor() && pContact->GetAnchor()->IsPageFrm() )
+                pAnch = pContact->GetPage();
+            else
+                pAnch = pContact->FindPage( aRect );
+        }
+    }
+    if( pAnch && !pAnch->IsProtected() )
+        aAnchorPoint = pAnch->Frm().Pos();
+    else
+        pAnch = 0;
+    return pAnch;
+}
+
+
+Rectangle *SwDrawView::IsAnchorAtPos( const Point &rPt ) const
+{
+    SdrHdl* pHdl = aHdl.GetHdl(HDL_ANCHOR);
+
+    if(pHdl)
+    {
+        const ViewShell &rSh = *Imp().GetShell();
+        const OutputDevice *pOut = rSh.GetOut();
+
+        if(pHdl->IsHit(rPt, *pOut))
+        {
+            B2dIAObject* pIAO = pHdl->GetIAOGroup().GetIAObject(0);
+
+            if(pIAO && pIAO->ISA(B2dIAOBitmapExReference))
+            {
+                Rectangle aRect(
+                    pIAO->GetBasePosition(),
+                    pOut->PixelToLogic(((B2dIAOBitmapExReference*)pIAO)->GetBitmapEx()->GetSizePixel()));
+                return new Rectangle(aRect);
+            }
+        }
+    }
+
+    return NULL;
+}
+
+/*************************************************************************
+|*
+|*  SwDrawView::ShowDragXor(), HideDragXor()
+|*
+|*  Ersterstellung      MA 17. Jan. 95
+|*  Letzte Aenderung    MA 27. Jan. 95
+|*
+*************************************************************************/
+
+
+void SwDrawView::ShowDragAnchor()
+{
+    SdrHdl* pHdl = aHdl.GetHdl(HDL_ANCHOR);
+    if(pHdl)
+    {
+        CalcAnchor();
+        pHdl->SetPos(aAnchorPoint);
+        RefreshAllIAOManagers();
+    }
+}
+
+
+
+/*************************************************************************
+|*
+|*  SwDrawView::MarkListHasChanged()
+|*
+|*  Ersterstellung      OM 02. Feb. 95
+|*  Letzte Aenderung    OM 07. Jul. 95
+|*
+*************************************************************************/
+
+
+void SwDrawView::MarkListHasChanged()
+{
+    Imp().GetShell()->DrawSelChanged(this);
+    FmFormView::MarkListHasChanged();
+}
+
+
+void SwDrawView::MakeVisible( const Rectangle &rRect, Window &rWin )
+{
+    ASSERT( rImp.GetShell()->GetWin() && &rWin, "MakeVisible, unknown Window");
+    rImp.GetShell()->MakeVisible( SwRect( rRect ) );
+}
+
+#if SUPD<500
+#define SVOBJ_MISCSTATUS_NOTRESIZEABLE 0
+#endif
+
+void SwDrawView::CheckPossibilities()
+{
+    FmFormView::CheckPossibilities();
+
+    //Zusaetzlich zu den bestehenden Flags der Objekte selbst, die von der
+    //DrawingEngine ausgewertet werden, koennen weitere Umstaende zu einem
+    //Schutz fuehren.
+    //Objekte, die in Rahmen verankert sind, muessen genau dann geschuetzt
+    //sein, wenn der Inhalt des Rahmens geschuetzt ist.
+    //OLE-Objekte konnen selbst einen Resize-Schutz wuenschen (StarMath)
+
+    const SdrMarkList &rMrkList = GetMarkList();
+    FASTBOOL bProtect = FALSE,
+             bSzProtect = FALSE;
+    for ( USHORT i = 0; !bProtect && i < rMrkList.GetMarkCount(); ++i )
+    {
+        const SdrObject *pObj = rMrkList.GetMark( i )->GetObj();
+        const SwFrm *pFrm = NULL;
+        if ( pObj->IsWriterFlyFrame() )
+        {
+            const SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+            if ( pFly  )
+            {
+                pFrm = pFly->GetAnchor();
+                if ( pFly->Lower() && pFly->Lower()->IsNoTxtFrm() )
+                {
+                    SwOLENode *pNd = ((SwCntntFrm*)pFly->Lower())->GetNode()->GetOLENode();
+                    if ( pNd )
+                    {
+                        SvInPlaceObjectRef aRef = pNd->GetOLEObj().GetOleRef();
+                        if ( aRef.Is() )
+                        {
+                            bSzProtect = SVOBJ_MISCSTATUS_NOTRESIZEABLE & aRef->GetMiscStatus()
+                                            ? TRUE : FALSE;
+                        }
+                    }
+                }
+            }
+        }
+        else
+        {
+            SwDrawContact *pC = (SwDrawContact*)GetUserCall(pObj);
+            if( pC )
+                pFrm = pC->GetAnchor();
+        }
+        if ( pFrm )
+            bProtect = pFrm->IsProtected(); //Rahmen, Bereiche usw.
+        if ( FLY_IN_CNTNT == ::FindFrmFmt( (SdrObject*)pObj )->GetAnchor().GetAnchorId() &&
+             rMrkList.GetMarkCount() > 1 )
+            bProtect = TRUE;
+    }
+    bMoveProtect    |= bProtect;
+    bResizeProtect  |= bProtect | bSzProtect;
+}
+
+void SwDrawView::DeleteMarked()
+{
+    SwDoc* pDoc = Imp().GetShell()->GetDoc();
+    if( pDoc->GetRootFrm() )
+        pDoc->GetRootFrm()->StartAllAction();
+    pDoc->StartUndo();
+    if( pDoc->DeleteSelection( *this ) )
+    {
+        FmFormView::DeleteMarked();
+        ::FrameNotify( Imp().GetShell(), FLY_DRAG_END );
+    }
+    pDoc->EndUndo();
+    if( pDoc->GetRootFrm() )
+        pDoc->GetRootFrm()->EndAllAction();
+}
+
+/********
+JP 02.10.98: sollte als Fix fuer 57153 gelten, hatte aber Nebenwirkungen,
+            wie Bug 57475
+const SdrMarkList& SwDrawView::GetMarkList() const
+{
+    FlushComeBackTimer();
+    return FmFormView::GetMarkList();
+}
+*************/
+
+
+
+
diff --git a/sw/source/core/draw/makefile.mk b/sw/source/core/draw/makefile.mk
new file mode 100644
index 000000000000..ab75e319d148
--- /dev/null
+++ b/sw/source/core/draw/makefile.mk
@@ -0,0 +1,102 @@
+#*************************************************************************
+#
+#   $RCSfile: makefile.mk,v $
+#
+#   $Revision: 1.1.1.1 $
+#
+#   last change: $Author: hr $ $Date: 2000-09-19 00:08:18 $
+#
+#   The Contents of this file are made available subject to the terms of
+#   either of the following licenses
+#
+#          - GNU Lesser General Public License Version 2.1
+#          - Sun Industry Standards Source License Version 1.1
+#
+#   Sun Microsystems Inc., October, 2000
+#
+#   GNU Lesser General Public License Version 2.1
+#   =============================================
+#   Copyright 2000 by Sun Microsystems, Inc.
+#   901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+#   This library is free software; you can redistribute it and/or
+#   modify it under the terms of the GNU Lesser General Public
+#   License version 2.1, as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   Lesser General Public License for more details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+#   License along with this library; if not, write to the Free Software
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+#   MA  02111-1307  USA
+#
+#
+#   Sun Industry Standards Source License Version 1.1
+#   =================================================
+#   The contents of this file are subject to the Sun Industry Standards
+#   Source License Version 1.1 (the "License"); You may not use this file
+#   except in compliance with the License. You may obtain a copy of the
+#   License at http://www.openoffice.org/license.html.
+#
+#   Software provided under this License is provided on an "AS IS" basis,
+#   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+#   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+#   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+#   See the License for the specific provisions governing your rights and
+#   obligations concerning the Software.
+#
+#   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+#   Copyright: 2000 by Sun Microsystems, Inc.
+#
+#   All Rights Reserved.
+#
+#   Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sw
+TARGET=draw
+
+AUTOSEG=true
+
+PROJECTPCH=core_pch
+PDBTARGET=core_pch
+PROJECTPCHSOURCE=..\core_1st\core_pch
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE :  $(PRJ)$/inc$/swpre.mk
+.INCLUDE :  settings.mk
+.INCLUDE :  $(PRJ)$/inc$/sw.mk
+
+
+# --- Files --------------------------------------------------------
+
+CXXFILES = \
+        dview.cxx		\
+        dcontact.cxx	\
+        dflyobj.cxx     \
+        drawdoc.cxx     \
+        dobjfac.cxx     \
+        dpage.cxx
+
+SLOFILES =  \
+        $(SLO)$/dview.obj	\
+        $(SLO)$/dcontact.obj	\
+        $(SLO)$/dflyobj.obj \
+        $(SLO)$/drawdoc.obj \
+        $(SLO)$/dobjfac.obj \
+        $(SLO)$/dpage.obj
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE :  target.mk
+
diff --git a/sw/source/core/edit/acorrect.cxx b/sw/source/core/edit/acorrect.cxx
new file mode 100644
index 000000000000..cf8d1e5a231c
--- /dev/null
+++ b/sw/source/core/edit/acorrect.cxx
@@ -0,0 +1,628 @@
+/*************************************************************************
+ *
+ *  $RCSfile: acorrect.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:18 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#define _STD_VAR_ARRAYS
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _WORDSEL_HXX
+#include 
+#endif
+#ifndef _OFF_APP_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_SVXIDS_HRC
+#include 
+#endif
+#ifndef _SVX_LANGITEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _FMTINFMT_HXX //autogen
+#include 
+#endif
+#ifndef _TXTATR_HXX //autogen
+#include 
+#endif
+#ifndef _TXTINET_HXX //autogen
+#include 
+#endif
+#ifndef _FMTHBSH_HXX //autogen
+#include 
+#endif
+#ifndef _EDITSH_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _ACORRECT_HXX
+#include 
+#endif
+#ifndef _SHELLIO_HXX
+#include 
+#endif
+#ifndef _TEMPAUTO_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include 
+#endif
+#ifndef _VISCRS_HXX
+#include 
+#endif
+#ifndef _SWFONT_HXX
+#include 
+#endif
+
+class _PaMIntoCrsrShellRing
+{
+    SwCrsrShell& rSh;
+    SwPaM &rDelPam, &rCrsr;
+    Ring *pPrevDelPam, *pPrevCrsr;
+
+    void RemoveFromRing( SwPaM& rPam, Ring* pPrev );
+public:
+    _PaMIntoCrsrShellRing( SwCrsrShell& rSh, SwPaM& rCrsr, SwPaM& rPam );
+    ~_PaMIntoCrsrShellRing();
+};
+
+_PaMIntoCrsrShellRing::_PaMIntoCrsrShellRing( SwCrsrShell& rCSh,
+                                            SwPaM& rShCrsr, SwPaM& rPam )
+    : rSh( rCSh ), rDelPam( rPam ), rCrsr( rShCrsr )
+{
+    SwPaM* pShCrsr = rSh._GetCrsr();
+
+    pPrevDelPam = rDelPam.GetPrev();
+    pPrevCrsr = rCrsr.GetPrev();
+
+    rDelPam.MoveRingTo( pShCrsr );
+    rCrsr.MoveRingTo( pShCrsr );
+}
+_PaMIntoCrsrShellRing::~_PaMIntoCrsrShellRing()
+{
+    // und den Pam wieder herausnehmen:
+    RemoveFromRing( rDelPam, pPrevDelPam );
+    RemoveFromRing( rCrsr, pPrevCrsr );
+}
+void _PaMIntoCrsrShellRing::RemoveFromRing( SwPaM& rPam, Ring* pPrev )
+{
+    Ring *p, *pNext = (Ring*)&rPam;
+    do {
+        p = pNext;
+        pNext = p->GetNext();
+        p->MoveTo( &rPam );
+    } while( p != pPrev );
+}
+
+
+SwAutoCorrDoc::SwAutoCorrDoc( SwEditShell& rEditShell, SwPaM& rPam,
+                                sal_Unicode cIns )
+    : rEditSh( rEditShell ), rCrsr( rPam ), pIdx( 0 ),
+    nUndoId( cIns ? 0 : USHRT_MAX )
+{
+}
+
+
+SwAutoCorrDoc::~SwAutoCorrDoc()
+{
+    if( nUndoId && USHRT_MAX != nUndoId )
+        rEditSh.EndUndo( nUndoId );
+    delete pIdx;
+}
+
+void SwAutoCorrDoc::DeleteSel( SwPaM& rDelPam )
+{
+    SwDoc* pDoc = rEditSh.GetDoc();
+    if( pDoc->IsAutoFmtRedline() )
+    {
+        // damit der DelPam auch verschoben wird, in den Shell-Cursr-Ring
+        // mit aufnehmen !!
+        _PaMIntoCrsrShellRing aTmp( rEditSh, rCrsr, rDelPam );
+        pDoc->DeleteAndJoin( rDelPam );
+    }
+    else
+        pDoc->Delete( rDelPam );
+}
+
+BOOL SwAutoCorrDoc::Delete( xub_StrLen nStt, xub_StrLen nEnd )
+{
+    const SwNodeIndex& rNd = rCrsr.GetPoint()->nNode;
+    SwPaM aSel( rNd, nStt, rNd, nEnd );
+    DeleteSel( aSel );
+
+    if( !nUndoId )
+        nUndoId = USHRT_MAX;
+    return TRUE;
+}
+
+
+BOOL SwAutoCorrDoc::Insert( xub_StrLen nPos, const String& rTxt )
+{
+    SwPaM aPam( rCrsr.GetPoint()->nNode.GetNode(), nPos );
+    rEditSh.GetDoc()->Insert( aPam, rTxt );
+    if( !nUndoId )
+    {
+        if( 1 == rTxt.Len() )
+            rEditSh.StartUndo( nUndoId = UNDO_AUTOCORRECT );
+        else
+            nUndoId = USHRT_MAX;
+    }
+    return TRUE;
+}
+
+
+BOOL SwAutoCorrDoc::Replace( xub_StrLen nPos, const String& rTxt )
+{
+    SwPaM* pPam = &rCrsr;
+    if( pPam->GetPoint()->nContent.GetIndex() != nPos )
+    {
+        pPam = new SwPaM( *rCrsr.GetPoint() );
+        pPam->GetPoint()->nContent = nPos;
+    }
+
+    BOOL bChg = TRUE;
+    SwTxtNode* pNd = pPam->GetNode()->GetTxtNode();
+    if( pNd )
+    {
+        // TextAttribute ohne Ende duerfen nie ersetzt werden!
+        sal_Unicode cChr;
+        for( xub_StrLen n = 0, nLen = rTxt.Len(); n < nLen; ++n )
+            if( ( CH_TXTATR_BREAKWORD == (cChr = pNd->GetTxt().
+                    GetChar( n + nPos )) || CH_TXTATR_INWORD == cChr ) &&
+                pNd->GetTxtAttr( n + nPos ) )
+            {
+                bChg = FALSE;
+                break;
+            }
+    }
+
+    if( bChg )
+    {
+        SwDoc* pDoc = rEditSh.GetDoc();
+        SwRedlineMode eOld = pDoc->GetRedlineMode();
+
+//      if( !pDoc->IsAutoFmtRedline() &&
+//          pPam != &rCrsr )    // nur an akt. Position das Redline sichern
+//          pDoc->SetRedlineMode_intern( eOld | REDLINE_IGNORE );
+
+        if( pDoc->IsAutoFmtRedline() )
+        {
+            if( nPos == pNd->GetTxt().Len() )       // am Ende erfolgt ein Insert
+                pDoc->Insert( *pPam, rTxt );
+            else
+            {
+                _PaMIntoCrsrShellRing aTmp( rEditSh, rCrsr, *pPam );
+
+                pPam->SetMark();
+                pPam->GetPoint()->nContent = Min( pNd->GetTxt().Len(),
+                                              xub_StrLen( nPos + rTxt.Len() ));
+                pDoc->Replace( *pPam, rTxt, FALSE );
+                pPam->Exchange();
+                pPam->DeleteMark();
+            }
+        }
+        else
+            pDoc->Overwrite( *pPam, rTxt );
+
+//      pDoc->SetRedlineMode_intern( eOld );
+        if( !nUndoId )
+        {
+            if( 1 == rTxt.Len() )
+                rEditSh.StartUndo( nUndoId = UNDO_AUTOCORRECT );
+            else
+                nUndoId = USHRT_MAX;
+        }
+    }
+
+    if( pPam != &rCrsr )
+        delete pPam;
+
+    return TRUE;
+}
+
+
+
+BOOL SwAutoCorrDoc::SetAttr( xub_StrLen nStt, xub_StrLen nEnd, USHORT nSlotId,
+                                        SfxPoolItem& rItem )
+{
+    const SwNodeIndex& rNd = rCrsr.GetPoint()->nNode;
+    SwPaM aPam( rNd, nStt, rNd, nEnd );
+
+    USHORT nWhich = rEditSh.GetDoc()->GetAttrPool().GetWhich( nSlotId, FALSE );
+    if( nWhich )
+    {
+        rItem.SetWhich( nWhich );
+        rEditSh.GetDoc()->SetFmtItemByAutoFmt( aPam, rItem );
+
+        if( !nUndoId )
+            nUndoId = USHRT_MAX;
+    }
+    return 0 != nWhich;
+}
+
+
+
+BOOL SwAutoCorrDoc::SetINetAttr( xub_StrLen nStt, xub_StrLen nEnd, const String& rURL )
+{
+    const SwNodeIndex& rNd = rCrsr.GetPoint()->nNode;
+    SwPaM aPam( rNd, nStt, rNd, nEnd );
+
+    rEditSh.GetDoc()->SetFmtItemByAutoFmt( aPam,
+                                            SwFmtINetFmt( rURL, aEmptyStr ));
+    if( !nUndoId )
+        nUndoId = USHRT_MAX;
+    return TRUE;
+}
+
+    // sind in dem Bereich Symbolzeichen?
+BOOL SwAutoCorrDoc::HasSymbolChars( xub_StrLen nStt, xub_StrLen nEnd )
+{
+    BOOL bRet = FALSE;
+    SwTxtNode* pNd = rCrsr.GetPoint()->nNode.GetNode().GetTxtNode();
+    if( pNd )
+        for( ; nStt < nEnd; ++nStt )
+            if( 0 != ( bRet = pNd->IsSymbol( nStt ) ) )
+                break;
+    return bRet;
+}
+
+
+    // returne den Text eines vorherigen Absatzes.
+    // Dieser darf nicht leer sein!
+    // Gibt es diesen nicht oder gibt es davor nur Leere, dann returne 0
+    // Das Flag gibt an:
+    //      TRUE: den, vor der normalen Einfuegeposition (TRUE)
+    //      FALSE: den, in den das korrigierte Wort eingfuegt wurde.
+    //              (Muss nicht der gleiche Absatz sein!!!!)
+const String* SwAutoCorrDoc::GetPrevPara( BOOL bAtNormalPos )
+{
+    const String* pStr = 0;
+
+    if( bAtNormalPos || !pIdx )
+        pIdx = new SwNodeIndex( rCrsr.GetPoint()->nNode, -1 );
+    else
+        (*pIdx)--;
+
+    SwTxtNode* pTNd = pIdx->GetNode().GetTxtNode();
+    while( pTNd && !pTNd->GetTxt().Len() )
+    {
+        (*pIdx)--;
+        pTNd = pIdx->GetNode().GetTxtNode();
+    }
+
+    if( pTNd && NO_NUMBERING == pTNd->GetTxtColl()->GetOutlineLevel() )
+        pStr = &pTNd->GetTxt();
+
+    if( !nUndoId )
+        nUndoId = USHRT_MAX;
+    return pStr;
+}
+
+
+BOOL SwAutoCorrDoc::ChgAutoCorrWord( xub_StrLen & rSttPos, xub_StrLen nEndPos,
+                                            SvxAutoCorrect& rACorrect,
+                                            const String** ppPara )
+{
+    if( !nUndoId )
+        nUndoId = USHRT_MAX;
+
+    // Absatz-Anfang oder ein Blank gefunden, suche nach dem Wort
+    // Kuerzel im Auto
+    SwTxtNode* pTxtNd = rCrsr.GetNode()->GetTxtNode();
+    ASSERT( pTxtNd, "wo ist denn der TextNode?" );
+
+    BOOL bRet = FALSE;
+    if( nEndPos == rSttPos )
+        return bRet;
+
+    LanguageType eLang = GetLanguage(nEndPos, FALSE);
+    if(LANGUAGE_SYSTEM == eLang)
+        eLang = ::GetSystemLang();
+
+    //JP 22.04.99: Bug 63883 - Sonderbehandlung fuer Punkte.
+    BOOL bLastCharIsPoint = nEndPos < pTxtNd->GetTxt().Len() &&
+                            '.' == pTxtNd->GetTxt().GetChar( nEndPos );
+
+    const SvxAutocorrWord* pFnd = rACorrect.SearchWordsInList(
+                                pTxtNd->GetTxt(), rSttPos, nEndPos, *this, eLang );
+    SwDoc* pDoc = rEditSh.GetDoc();
+    if( pFnd )
+    {
+        const SwNodeIndex& rNd = rCrsr.GetPoint()->nNode;
+        SwPaM aPam( rNd, rSttPos, rNd, nEndPos );
+
+        if( pFnd->IsTextOnly() )
+        {
+            //JP 22.04.99: Bug 63883 - Sonderbehandlung fuer Punkte.
+            if( !bLastCharIsPoint || !pFnd->GetLong().Len() ||
+                '.' != pFnd->GetLong().GetChar( pFnd->GetLong().Len() - 1 ) )
+            {
+                // dann mal ersetzen
+                DeleteSel( aPam );
+                pDoc->DontExpandFmt( *aPam.GetPoint() );
+                pDoc->Insert( aPam, pFnd->GetLong() );
+                bRet = TRUE;
+            }
+        }
+        else
+        {
+            SwTextBlocks aTBlks( rACorrect.GetAutoCorrFileName( eLang ));
+            USHORT nPos = aTBlks.GetIndex( pFnd->GetShort() );
+            if( USHRT_MAX != nPos && aTBlks.BeginGetDoc( nPos ) )
+            {
+                DeleteSel( aPam );
+                pDoc->DontExpandFmt( *aPam.GetPoint() );
+
+                if( ppPara )
+                {
+                    ASSERT( !pIdx, "wer hat seinen Index nicht geloescht?" );
+                    pIdx = new SwNodeIndex( rCrsr.GetPoint()->nNode, -1 );
+                }
+
+                //
+                SwDoc* pAutoDoc = aTBlks.GetDoc();
+                SwNodeIndex aSttIdx( pAutoDoc->GetNodes().GetEndOfExtras(), 1 );
+                SwCntntNode* pCntntNd = pAutoDoc->GetNodes().GoNext( &aSttIdx );
+                SwPaM aCpyPam( aSttIdx );
+
+                const SwTableNode* pTblNd = pCntntNd->FindTableNode();
+                if( pTblNd )
+                {
+                    aCpyPam.GetPoint()->nContent.Assign( 0, 0 );
+                    aCpyPam.GetPoint()->nNode = *pTblNd;
+                }
+                aCpyPam.SetMark();
+
+                // dann bis zum Ende vom Nodes Array
+                aCpyPam.GetPoint()->nNode.Assign( pAutoDoc->GetNodes().GetEndOfContent(), -1 );
+                pCntntNd = aCpyPam.GetCntntNode();
+                aCpyPam.GetPoint()->nContent.Assign( pCntntNd, pCntntNd->Len() );
+
+                SwDontExpandItem aExpItem;
+                aExpItem.SaveDontExpandItems( *aPam.GetPoint() );
+
+                pAutoDoc->Copy( aCpyPam, *aPam.GetPoint() );
+
+                aExpItem.RestoreDontExpandItems( *aPam.GetPoint() );
+
+                if( ppPara )
+                {
+                    (*pIdx)++;
+                    pTxtNd = pIdx->GetNode().GetTxtNode();
+                }
+                bRet = TRUE;
+            }
+            aTBlks.EndGetDoc();
+        }
+    }
+    else if( pTempAuto )
+    {
+        String sKurz( pTxtNd->GetTxt().Copy( rSttPos, nEndPos - rSttPos ));
+        // die temporaere Autokorrektur schlaegt zu
+        const SwCorrection* pCorr = pTempAuto->Replaceable( sKurz );
+        //JP 22.04.99: Bug 63883 - Sonderbehandlung fuer Punkte.
+        if( pCorr && ( !bLastCharIsPoint || !pCorr->Correct().Len() ||
+            '.' != pCorr->Correct().GetChar( pCorr->Correct().Len() - 1 )) )
+        {
+            const SwNodeIndex& rNd = rCrsr.GetPoint()->nNode;
+            SwPaM aPam( rNd, rSttPos, rNd, nEndPos );
+
+            DeleteSel( aPam );
+
+            pDoc->DontExpandFmt( *aPam.GetPoint() );
+            pDoc->Insert( aPam, pCorr->Correct() );
+            bRet = TRUE;
+        }
+    }
+
+    if( bRet && ppPara && pTxtNd )
+        *ppPara = &pTxtNd->GetTxt();
+
+    return bRet;
+}
+
+
+    // wird nach dem austauschen der Zeichen von den Funktionen
+    //  - FnCptlSttWrd
+    //  - FnCptlSttSntnc
+    // gerufen. Dann koennen die Worte ggfs. in die Ausnahmelisten
+    // aufgenommen werden.
+void SwAutoCorrDoc::SaveCpltSttWord( ULONG nFlag, xub_StrLen nPos,
+                                            const String& rExceptWord,
+                                            sal_Unicode cChar )
+{
+    ULONG nNode = pIdx ? pIdx->GetIndex() : rCrsr.GetPoint()->nNode.GetIndex();
+    LanguageType eLang = GetLanguage(nPos, FALSE);
+    rEditSh.GetDoc()->SetAutoCorrExceptWord( new SwAutoCorrExceptWord( nFlag,
+                                        nNode, nPos, rExceptWord, cChar, eLang ));
+}
+
+LanguageType SwAutoCorrDoc::GetLanguage( xub_StrLen nPos, BOOL bPrevPara ) const
+{
+    LanguageType eRet = LANGUAGE_SYSTEM;
+    ULONG nNode = pIdx ? pIdx->GetIndex() : rCrsr.GetPoint()->nNode.GetIndex();
+
+    SwTxtNode* pNd = (( bPrevPara && pIdx )
+                            ? *pIdx
+                            : rCrsr.GetPoint()->nNode ).GetNode().GetTxtNode();
+
+    if( pNd )
+    {
+        SfxItemSet aSet( rEditSh.GetDoc()->GetAttrPool(),
+                        RES_CHRATR_LANGUAGE, RES_CHRATR_LANGUAGE );
+        pNd->GetAttr( aSet, nPos, nPos );
+        eRet = ((const SvxLanguageItem&)aSet.Get( RES_CHRATR_LANGUAGE ))
+                                .GetLanguage();
+    }
+    if(LANGUAGE_SYSTEM == eRet)
+        eRet = ::GetSystemLang();
+    return eRet;
+}
+
+void SwAutoCorrExceptWord::CheckChar( const SwPosition& rPos, sal_Unicode cChr )
+{
+    // nur testen ob es eine Verbesserung ist. Wenn ja, dann das Wort
+    // in die Ausnahmeliste aufnehmen.
+    if( cChar == cChr && rPos.nNode.GetIndex() == nNode &&
+        rPos.nContent.GetIndex() == nCntnt )
+    {
+        // die akt. Autokorrektur besorgen:
+        SvxAutoCorrect* pACorr = OFF_APP()->GetAutoCorrect();
+
+        // dann in die Liste aufnehmen:
+        if( CptlSttWrd & nFlags )
+            pACorr->AddWrtSttException( sWord, eLanguage );
+        else if( CptlSttSntnc & nFlags )
+            pACorr->AddCplSttException( sWord, eLanguage );
+    }
+}
+
+
+BOOL SwAutoCorrExceptWord::CheckDelChar( const SwPosition& rPos )
+{
+    BOOL bRet = FALSE;
+    if( !bDeleted && rPos.nNode.GetIndex() == nNode &&
+        rPos.nContent.GetIndex() == nCntnt )
+        bDeleted = bRet = TRUE;
+    return bRet;
+}
+
+SwDontExpandItem::~SwDontExpandItem()
+{
+    delete pDontExpItems;
+}
+
+void SwDontExpandItem::SaveDontExpandItems( const SwPosition& rPos )
+{
+    const SwTxtNode* pTxtNd = rPos.nNode.GetNode().GetTxtNode();
+    if( pTxtNd )
+    {
+        pDontExpItems = new SfxItemSet( ((SwDoc*)pTxtNd->GetDoc())->GetAttrPool(),
+                                            aCharFmtSetRange );
+        xub_StrLen n = rPos.nContent.GetIndex();
+        if( !pTxtNd->GetAttr( *pDontExpItems, n, n,
+                                n != pTxtNd->GetTxt().Len() ))
+            delete pDontExpItems, pDontExpItems = 0;
+    }
+}
+
+void SwDontExpandItem::RestoreDontExpandItems( const SwPosition& rPos )
+{
+    SwTxtNode* pTxtNd = rPos.nNode.GetNode().GetTxtNode();
+    if( pTxtNd )
+    {
+        xub_StrLen nStart = rPos.nContent.GetIndex();
+        if( nStart == pTxtNd->GetTxt().Len() )
+            pTxtNd->FmtToTxtAttr( pTxtNd );
+
+        if( pTxtNd->GetpSwpHints() && pTxtNd->GetpSwpHints()->Count() )
+        {
+            const USHORT nSize = pTxtNd->GetpSwpHints()->Count();
+            register USHORT n;
+            xub_StrLen nAttrStart;
+            register const xub_StrLen* pAttrEnd;
+
+            for( n = 0; n < nSize; ++n )
+            {
+                SwTxtAttr* pHt = pTxtNd->GetpSwpHints()->GetHt( n );
+                nAttrStart = *pHt->GetStart();
+                if( nAttrStart > nStart )       // ueber den Bereich hinaus
+                    break;
+
+                if( 0 != ( pAttrEnd = pHt->GetEnd() ) &&
+                    ( ( nAttrStart < nStart &&
+                        ( pHt->DontExpand() ? nStart < *pAttrEnd
+                                            : nStart <= *pAttrEnd )) ||
+                      ( nStart == nAttrStart &&
+                        ( nAttrStart == *pAttrEnd || !nStart ))) )
+                {
+                    const SfxPoolItem* pItem;
+                    if( !pDontExpItems || SFX_ITEM_SET != pDontExpItems->
+                        GetItemState( pHt->Which(), FALSE, &pItem ) ||
+                        *pItem != pHt->GetAttr() )
+                    {
+                        // das Attribut war vorher nicht in dieser Form im Absatz
+                        // gesetzt, also kann es nur durchs einfuegen/kopieren erzeugt
+                        // worden sein. Damit ist es ein Kandiadat fuers DontExpand
+                        pHt->SetDontExpand( TRUE );
+                    }
+                }
+            }
+        }
+    }
+}
+
+
diff --git a/sw/source/core/edit/autofmt.cxx b/sw/source/core/edit/autofmt.cxx
new file mode 100644
index 000000000000..38053c0ce0ee
--- /dev/null
+++ b/sw/source/core/edit/autofmt.cxx
@@ -0,0 +1,2770 @@
+/*************************************************************************
+ *
+ *  $RCSfile: autofmt.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:18 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#define ITEMID_BOXINFO      SID_ATTR_BORDER_INNER
+#define _SVSTDARR_LONGS
+#define _SVSTDARR_USHORTS
+
+#include 
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _INTN_HXX //autogen
+#include 
+#endif
+#ifndef _WORDSEL_HXX
+#include 
+#endif
+#include 
+#ifndef _SVX_BOXITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BRKITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_ADJITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_TSTPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_FONTITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_LANGITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_CSCOITEM_HXX
+#include 
+#endif
+#ifndef _OFF_APP_HXX //autogen
+#include 
+#endif
+
+#ifndef _SWWAIT_HXX
+#include 
+#endif
+#ifndef _FMTPDSC_HXX //autogen
+#include 
+#endif
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _EDITSH_HXX
+#include 
+#endif
+#ifndef _INDEX_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _EDIMP_HXX
+#include 
+#endif
+#ifndef _FESH_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include        // fuer die UndoIds
+#endif
+#ifndef _POOLFMT_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _TXTFRM_HXX
+#include 
+#endif
+#ifndef _FRMINF_HXX
+#include 
+#endif
+#ifndef _PAGEDESC_HXX
+#include 
+#endif
+#ifndef _PARATR_HXX
+#include 
+#endif
+#ifndef _SWTABLE_HXX
+#include 
+#endif
+#ifndef _ACORRECT_HXX
+#include 
+#endif
+#ifndef _SHELLRES_HXX
+#include 
+#endif
+#ifndef _ITABENUM_HXX
+#include 
+#endif
+#ifndef _SECTION_HXX //autogen
+#include 
+#endif
+#ifndef _FMTHBSH_HXX //autogen
+#include 
+#endif
+#ifndef _FRMATR_HXX
+#include 
+#endif
+
+#ifndef _MDIEXP_HXX
+#include 
+#endif
+#ifndef _STATSTR_HRC
+#include 
+#endif
+#ifndef _COMCORE_HRC
+#include 
+#endif
+
+//-------------------------------------------------------------------
+
+//JP 16.12.99: definition:
+//      from pos cPosEnDash to cPosEmDash all chars changed to endashes,
+//      from pos cPosEmDash to cPosEnd    all chars changed to emdashes
+//      all other chars are changed to the user configuration
+
+// ---> Unicode En-/Emdash??
+#ifdef MAC
+const sal_Char* pBulletChar = "+*-\xD0\xD1";    // plus endash & emdash
+const int cnPosEnDash = 2, cnPosEmDash = 4, cnPosEnd = 5;
+#else
+#if defined(PM2 ) || defined(UNX)
+const sal_Char* pBulletChar = "+*-";
+const int cnPosEnDash = 2, cnPosEmDash = 3, cnPosEnd = 3;
+#else
+const sal_Char* pBulletChar = "+*-\x96\x97";    // plus endash & emdash
+const int cnPosEnDash = 2, cnPosEmDash = 4, cnPosEnd = 5;
+#endif // PM2 / UNX
+#endif // MAC
+const sal_Char cStartBatsEnDash = '\x96';
+const sal_Char cStartBatsEmDash = '\x97';
+
+
+SvxSwAutoFmtFlags* SwEditShell::pAutoFmtFlags = 0;
+
+// Anzahl von Num-/Bullet-Absatzvorlagen. MAXLEVEL wird demnaechst auf
+// x erhoeht, die Anzahl Vorlagen aber nicht (Ueberbleibsel aus <= 4.0)
+const USHORT cnNumBullColls = 4;
+
+class SwAutoFormat
+{
+    SvxSwAutoFmtFlags aFlags;
+    SwPaM aDelPam;              // ein Pam der benutzt werden kann
+    SwNodeIndex aNdIdx;         // der Index auf den akt. TextNode
+    SwNodeIndex aEndNdIdx;      // Index auf das Ende vom Bereich
+
+    SwEditShell* pEditShell;
+    SwDoc* pDoc;
+    SwTxtNode* pAktTxtNd;       // der akt. TextNode
+    SwTxtFrm* pAktTxtFrm;       // Frame vom akt. TextNode
+    ULONG nEndNdIdx;            // fuer die Prozent-Anzeige
+
+    enum
+    {
+        NONE = 0,
+        DELIM = 1,
+        DIGIT = 2,
+        CHG = 4,
+        LOWER_ALPHA = 8,
+        UPPER_ALPHA = 16,
+        LOWER_ROMAN = 32,
+        UPPER_ROMAN = 64,
+        NO_DELIM = (DIGIT|LOWER_ALPHA|UPPER_ALPHA|LOWER_ROMAN|UPPER_ROMAN)
+    };
+
+    enum Format_Status
+    {
+        READ_NEXT_PARA,
+        TST_EMPTY_LINE,
+        TST_ALPHA_LINE,
+        GET_ALL_INFO,
+        IS_ONE_LINE,
+        TST_ENUMERIC,
+        TST_IDENT,
+        TST_NEG_IDENT,
+        TST_TXT_BODY,
+        HAS_FMTCOLL,
+        IS_ENDE
+    } eStat;
+
+    BOOL bEnde : 1;
+    BOOL bEmptyLine : 1;
+    BOOL bMoreLines : 1;
+
+    USHORT nLastHeadLvl, nLastCalcHeadLvl;
+    USHORT nLastEnumLvl, nLastCalcEnumLvl;
+    USHORT nRedlAutoFmtSeqId;
+
+    BOOL IsSpace( const sal_Unicode c ) const
+        { return (' ' == c || '\t' == c || 0x0a == c) ? TRUE : FALSE; }
+
+    void SetColl( USHORT nId, BOOL bHdLineOrText = FALSE );
+    String GoNextPara();
+    BOOL HasObjects( const SwNode& rNd );
+
+    // TxtNode Methoden
+    const SwTxtNode* GetNextNode() const;
+    BOOL IsEmptyLine( const SwTxtNode& rNd ) const
+        {   return 0 == rNd.GetTxt().Len() ||
+                rNd.GetTxt().Len() == GetLeadingBlanks( rNd.GetTxt() ); }
+
+    BOOL IsOneLine( const SwTxtNode& ) const;
+    BOOL IsFastFullLine( const SwTxtNode& ) const;
+    BOOL IsNoAlphaLine( const SwTxtNode&) const;
+    BOOL IsEnumericChar( const SwTxtNode&) const;
+    BOOL IsBlanksInString( const SwTxtNode&) const;
+    USHORT CalcLevel( const SwTxtNode&, USHORT *pDigitLvl = 0 ) const;
+    xub_StrLen GetBigIndent( xub_StrLen& rAktSpacePos ) const;
+
+    String& DelLeadingBlanks( String& rStr ) const;
+    String& DelTrailingBlanks( String& rStr ) const;
+    xub_StrLen GetLeadingBlanks( const String& rStr ) const;
+    xub_StrLen GetTrailingBlanks( const String& rStr ) const;
+
+    const sal_Unicode GetFirstChar( const String& rStr,
+                                    BOOL bSkipDigit = TRUE ) const;
+    USHORT GetDigitLevel( const sal_Unicode** ppStr, String* pPreFix = 0,
+                        String* pPostFix = 0, String* pNumTypes = 0 ) const;
+        // hole den FORMATIERTEN TextFrame
+    SwTxtFrm* GetFrm( const SwTxtNode& rTxtNd ) const;
+
+    void BuildIndent();
+    void BuildText();
+    void BuildTextIndent();
+    void BuildEnum( USHORT nLvl, USHORT nDigitLevel );
+    void BuildNegIndent( SwTwips nSpaces );
+    void BuildHeadLine( USHORT nLvl );
+
+    BOOL HasSelBlanks( SwPaM& rPam ) const;
+    BOOL HasBreakAttr( const SwTxtNode& ) const;
+    void DeleteSel( SwPaM& rPam );
+    BOOL DeleteAktNxtPara( const String& rNxtPara );
+    // loesche im Node Anfang oder/und Ende
+    void DeleteAktPara( BOOL bStart = TRUE, BOOL nEnd = TRUE );
+    void DelEmptyLine();
+        // loesche bei mehrzeiligen Absaetzen die "linken" und/oder
+        // "rechten" Raender
+    void DelMoreLinesBlanks( BOOL bWithLineBreaks = FALSE );
+        // loesche den vorherigen Absatz
+    void DelPrevPara();
+        // dann lasse doch mal das AutoCorrect auf den akt. TextNode los
+    void AutoCorrect( xub_StrLen nSttPos = 0 );
+
+    BOOL CanJoin( const SwTxtNode* pTxtNd ) const
+    {
+        return !bEnde && pTxtNd &&
+             !IsEmptyLine( *pTxtNd ) &&
+             !IsNoAlphaLine( *pTxtNd) &&
+             !IsEnumericChar( *pTxtNd ) &&
+             ((STRING_MAXLEN - 50 - pTxtNd->GetTxt().Len()) >
+                    pAktTxtNd->GetTxt().Len()) &&
+             !HasBreakAttr( *pTxtNd );
+    }
+
+    // ist ein Punkt am Ende ??
+    BOOL IsSentenceAtEnd( const SwTxtNode& rTxtNd ) const;
+
+    BOOL DoUnderline();
+    BOOL DoTable();
+
+    void _SetRedlineTxt( USHORT nId );
+    BOOL SetRedlineTxt( USHORT nId )
+        { if( aFlags.bWithRedlining )   _SetRedlineTxt( nId );  return TRUE; }
+    BOOL ClearRedlineTxt()
+        { if( aFlags.bWithRedlining )   pDoc->SetAutoFmtRedlineComment(0);  return TRUE; }
+
+public:
+    SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFmtFlags& rFlags,
+                SwNodeIndex* pSttNd = 0, SwNodeIndex* pEndNd = 0 );
+};
+
+
+SwTxtFrm* SwAutoFormat::GetFrm( const SwTxtNode& rTxtNd ) const
+{
+    // besorge mal den Frame
+    const SwCntntFrm *pFrm = rTxtNd.GetFrm();
+    ASSERT( pFrm, "zum Autoformat muss das Layout vorhanden sein" );
+    if( aFlags.bAFmtByInput && !pFrm->IsValid() )
+    {
+        SwRect aTmpFrm( pFrm->Frm() );
+        SwRect aTmpPrt( pFrm->Prt() );
+        pFrm->Calc();
+        if( pFrm->Frm() != aTmpFrm || pFrm->Prt() != aTmpPrt ||
+            ( pFrm->IsTxtFrm() && !((SwTxtFrm*)pFrm)->Paint().IsEmpty() ) )
+            pFrm->SetCompletePaint();
+    }
+    return ((SwTxtFrm*)pFrm)->GetFormatted();
+}
+
+void SwAutoFormat::_SetRedlineTxt( USHORT nActionId )
+{
+    String sTxt;
+    USHORT nSeqNo = 0;
+    if( STR_AUTOFMTREDL_END > nActionId )
+    {
+        sTxt = *ViewShell::GetShellRes()->GetAutoFmtNameLst()[ nActionId ];
+        switch( nActionId )
+        {
+        case STR_AUTOFMTREDL_SET_NUMBULET:
+        case STR_AUTOFMTREDL_DEL_MORELINES:
+
+        // AutoCorrect-Actions
+        case STR_AUTOFMTREDL_USE_REPLACE:
+        case STR_AUTOFMTREDL_CPTL_STT_WORD:
+        case STR_AUTOFMTREDL_CPTL_STT_SENT:
+        case STR_AUTOFMTREDL_TYPO:
+        case STR_AUTOFMTREDL_UNDER:
+        case STR_AUTOFMTREDL_BOLD:
+        case STR_AUTOFMTREDL_FRACTION:
+        case STR_AUTOFMTREDL_DASH:
+        case STR_AUTOFMTREDL_ORDINAL:
+            nSeqNo = ++nRedlAutoFmtSeqId;
+            break;
+        }
+    }
+#ifdef DEBUG
+    else
+        sTxt = String::CreateFromAscii(
+                            RTL_CONSTASCII_STRINGPARAM( "Action-Text fehlt" ));
+#endif
+
+    pDoc->SetAutoFmtRedlineComment( &sTxt, nSeqNo );
+}
+
+String SwAutoFormat::GoNextPara()
+{
+    SwNode* pNewNd = 0;
+    do {
+        aNdIdx++;
+        if( aNdIdx.GetIndex() >= aEndNdIdx.GetIndex() )
+        {
+            bEnde = TRUE;
+            return aEmptyStr;
+        }
+        else
+            pNewNd = &aNdIdx.GetNode();
+
+        // kein TextNode ->
+        //      TableNode   : Tabelle ueberspringen
+        //      NoTxtNode   : Nodes ueberspringen
+        //      EndNode     : Ende erreicht, beenden
+        if( pNewNd->IsEndNode() )
+        {
+            bEnde = TRUE;
+            return aEmptyStr;
+        }
+        else if( pNewNd->IsTableNode() )
+            aNdIdx = *pNewNd->EndOfSectionNode();
+        else if( pNewNd->IsSectionNode() )
+        {
+            const SwSection& rSect = pNewNd->GetSectionNode()->GetSection();
+            if( rSect.IsHiddenFlag() || rSect.IsProtectFlag() )
+                aNdIdx = *pNewNd->EndOfSectionNode();
+        }
+    } while( !pNewNd->IsTxtNode() );
+
+    if( !aFlags.bAFmtByInput )
+        ::SetProgressState( aNdIdx.GetIndex() + nEndNdIdx - aEndNdIdx.GetIndex(),
+                            pDoc->GetDocShell() );
+
+    pAktTxtNd = (SwTxtNode*)pNewNd;
+    pAktTxtFrm = GetFrm( *pAktTxtNd );
+    return pAktTxtNd->GetTxt();
+}
+
+BOOL SwAutoFormat::HasObjects( const SwNode& rNd )
+{
+    // haengt irgend etwas absatzgebundenes am Absatz?
+    // z.B. Rahmen, DrawObjecte, ..
+    BOOL bRet = FALSE;
+    const SwSpzFrmFmts& rFmts = *pDoc->GetSpzFrmFmts();
+    for( USHORT n = 0; n < rFmts.Count(); ++n )
+    {
+        const SwFmtAnchor& rAnchor = rFmts[ n ]->GetAnchor();
+        if( FLY_PAGE != rAnchor.GetAnchorId() &&
+            rAnchor.GetCntntAnchor() &&
+            &rAnchor.GetCntntAnchor()->nNode.GetNode() == &rNd )
+        {
+            bRet = TRUE;
+            break;
+        }
+    }
+    return bRet;
+}
+
+const SwTxtNode* SwAutoFormat::GetNextNode() const
+{
+    if( aNdIdx.GetIndex()+1 >= aEndNdIdx.GetIndex() )
+        return 0;
+    return pDoc->GetNodes()[ aNdIdx.GetIndex() + 1 ]->GetTxtNode();
+}
+
+
+BOOL SwAutoFormat::IsOneLine( const SwTxtNode& rNd ) const
+{
+    SwTxtFrmInfo aFInfo( GetFrm( rNd ) );
+    return aFInfo.IsOneLine();
+}
+
+
+BOOL SwAutoFormat::IsFastFullLine( const SwTxtNode& rNd ) const
+{
+    BOOL bRet = aFlags.bRightMargin;
+    if( bRet )
+    {
+        SwTxtFrmInfo aFInfo( GetFrm( rNd ) );
+        bRet = aFInfo.IsFilled( aFlags.nRightMargin );
+    }
+    return bRet;
+}
+
+
+BOOL SwAutoFormat::IsEnumericChar( const SwTxtNode& rNd ) const
+{
+    String sTmp( rNd.GetTxt() );
+    xub_StrLen nBlnks = GetLeadingBlanks( sTmp );
+    xub_StrLen nLen = rNd.GetTxt().Len() - nBlnks;
+    if( !nLen )
+        return FALSE;
+
+    // -, +, * getrennt durch Blank ??
+    const sal_Unicode *pTmp = sTmp.GetBuffer() + nBlnks;
+    if( 2 < nLen && IsSpace( *(pTmp+1) ) )
+    {
+        if( *pTmp < 256 && strchr( pBulletChar, *pTmp ) )
+            return TRUE;
+        // sollte an der Position ein Symbolfont existieren ?
+        SwTxtFrmInfo aFInfo( GetFrm( rNd ) );
+        if( aFInfo.IsBullet( nBlnks ))
+            return TRUE;
+    }
+
+    // 1.) / 1. / 1.1.1 / (1). / (1) / ....
+    return USHRT_MAX != GetDigitLevel( &pTmp );
+}
+
+
+BOOL SwAutoFormat::IsBlanksInString( const SwTxtNode& rNd ) const
+{
+    // suche im String mehr als 5 Blanks/Tabs
+    String sTmp( rNd.GetTxt() );
+    DelTrailingBlanks( DelLeadingBlanks( sTmp ));
+    const sal_Unicode* pTmp = sTmp.GetBuffer();
+    while( *pTmp )
+    {
+        if( IsSpace( *pTmp ) )
+        {
+            if( IsSpace( *++pTmp ))     // 2 Space nach einander
+            {
+                const sal_Unicode* pStt = pTmp;
+                while( *pTmp && IsSpace( *++pTmp ))
+                    ;
+                if( 5 <= pTmp - pStt )
+                    return TRUE;
+            }
+            else
+                ++pTmp;
+        }
+        else
+            ++pTmp;
+    }
+    return FALSE;
+}
+
+
+USHORT SwAutoFormat::CalcLevel( const SwTxtNode& rNd, USHORT *pDigitLvl ) const
+{
+    USHORT nLvl = 0, nBlnk = 0;
+    const sal_Unicode* pTmp = rNd.GetTxt().GetBuffer();
+    if( pDigitLvl )
+        *pDigitLvl = USHRT_MAX;
+
+    if( RES_POOLCOLL_TEXT_MOVE == rNd.GetTxtColl()->GetPoolFmtId() )
+    {
+        if( aFlags.bAFmtByInput )
+        {
+            nLvl = rNd.GetAutoFmtLvl();
+            ((SwTxtNode&)rNd).SetAutoFmtLvl( 0 );
+            if( nLvl )
+                return nLvl;
+        }
+        ++nLvl;
+    }
+
+    while( *pTmp )
+    {
+        switch( *pTmp )
+        {
+        case ' ':   if( 3 == ++nBlnk )  ++nLvl, nBlnk = 0;
+                    break;
+        case '\t':  ++nLvl, nBlnk = 0;
+                    break;
+        default:
+            if( pDigitLvl )
+                // Teste auf 1.) / 1. / 1.1.1 / (1). / (1) / ....
+                *pDigitLvl = GetDigitLevel( &pTmp );
+            return nLvl;
+        }
+        ++pTmp;
+    }
+    return nLvl;
+}
+
+
+
+xub_StrLen SwAutoFormat::GetBigIndent( xub_StrLen& rAktSpacePos ) const
+{
+    SwTxtFrmInfo aFInfo( GetFrm( *pAktTxtNd ) );
+    const SwTxtFrm* pNxtFrm = 0;
+
+    if( !bMoreLines )
+    {
+        const SwTxtNode* pNxtNd = GetNextNode();
+        if( !CanJoin( pNxtNd ) || !IsOneLine( *pNxtNd ) )
+            return 0;
+
+        pNxtFrm = GetFrm( *pNxtNd );
+    }
+
+    return aFInfo.GetBigIndent( rAktSpacePos, pNxtFrm );
+}
+
+
+BOOL SwAutoFormat::IsNoAlphaLine( const SwTxtNode& rNd ) const
+{
+    const String& rStr = rNd.GetTxt();
+    if( !rStr.Len() )
+        return FALSE;
+    // oder besser: ueber die Anzahl von Alpha/Num- und !AN-Zeichen
+    //              bestimmen.
+    xub_StrLen nANChar = 0, nBlnk = 0;
+
+    const International& rInter = Application::GetAppInternational();
+    for( const sal_Unicode* pTmp = rStr.GetBuffer(); *pTmp; ++pTmp )
+        if( IsSpace( *pTmp ) )
+            ++nBlnk;
+        else if( rInter.IsAlphaNumeric( *pTmp ))
+            ++nANChar;
+    // sind zu 75% keine Alpha-Nummerische-Zeichen, dann TRUE
+    ULONG nLen = rStr.Len() - nBlnk;
+    nLen = ( nLen * 3 ) / 4;            // long overflow, if the strlen > USHORT
+    return xub_StrLen(nLen) < (rStr.Len() - nANChar - nBlnk);
+}
+
+
+
+BOOL SwAutoFormat::DoUnderline()
+{
+    if( !aFlags.bSetBorder )
+        return FALSE;
+
+    const sal_Unicode* pStr = pAktTxtNd->GetTxt().GetBuffer();
+    int eState = 0;
+    xub_StrLen nCnt = 0;
+    while( *pStr )
+    {
+//JP 29.03.96: Spaces unterbrechen die Umrandung!
+//      if( !IsSpace( *pStr ) )
+        {
+            int eTmp = 0;
+            switch( *pStr )
+            {
+            case '-': eTmp = 1; break;
+            case '_': eTmp = 2; break;
+            case '=': eTmp = 3; break;
+            case '*': eTmp = 4; break;
+            case '~': eTmp = 5; break;
+            case '#': eTmp = 6; break;
+            default:
+                return FALSE;
+            }
+            if( 0 == eState )
+                eState = eTmp;
+            else if( eState != eTmp )
+                return FALSE;
+            ++nCnt;
+        }
+        ++pStr;
+    }
+
+    if( 2 < nCnt )
+    {
+        // dann unterstreiche mal den vorherigen Absatz, wenn es diesen gibt!
+        DelEmptyLine();
+        aDelPam.SetMark();
+        aDelPam.GetMark()->nContent = 0;
+//JP 19.03.96: kein Underline sondern eine Umrandung setzen!
+//      pDoc->Insert( aDelPam, SvxUnderlineItem( eState ) );
+
+        SvxBorderLine aLine;
+        switch( eState )
+        {
+        case 1:         // einfach, 0,05 pt
+            aLine.SetOutWidth( DEF_LINE_WIDTH_0 );
+            break;
+        case 2:         // einfach, 1,0 pt
+            aLine.SetOutWidth( DEF_LINE_WIDTH_1 );
+            break;
+        case 3:         // doppelt, 1,1 pt
+            aLine.SetOutWidth( DEF_DOUBLE_LINE0_OUT );
+            aLine.SetInWidth( DEF_DOUBLE_LINE0_IN );
+            aLine.SetDistance( DEF_DOUBLE_LINE0_DIST );
+            break;
+        case 4:         // doppelt, 4,5 pt
+            aLine.SetOutWidth( DEF_DOUBLE_LINE4_OUT );
+            aLine.SetInWidth( DEF_DOUBLE_LINE4_IN );
+            aLine.SetDistance( DEF_DOUBLE_LINE4_DIST );
+            break;
+        case 5:         // doppelt, 6,0 pt
+            aLine.SetOutWidth( DEF_DOUBLE_LINE5_OUT );
+            aLine.SetInWidth( DEF_DOUBLE_LINE5_IN );
+            aLine.SetDistance( DEF_DOUBLE_LINE5_DIST );
+            break;
+        case 6:         // doppelt, 9,0 pt
+            aLine.SetOutWidth( DEF_DOUBLE_LINE6_OUT );
+            aLine.SetInWidth( DEF_DOUBLE_LINE6_IN );
+            aLine.SetDistance( DEF_DOUBLE_LINE6_DIST );
+            break;
+        }
+
+        SvxBoxItem aBox;
+        aBox.SetLine( &aLine, BOX_LINE_BOTTOM );
+        aBox.SetDistance( 42 );     // ~0,75 mm
+        pDoc->Insert( aDelPam, aBox );
+
+        aDelPam.DeleteMark();
+    }
+    return 2 < nCnt;
+}
+
+
+BOOL SwAutoFormat::DoTable()
+{
+    if( !aFlags.bCreateTable || !aFlags.bAFmtByInput ||
+        pAktTxtNd->FindTableNode() )
+        return FALSE;
+
+    const String& rTmp = pAktTxtNd->GetTxt();
+    xub_StrLen nSttPlus = GetLeadingBlanks( rTmp );
+    xub_StrLen nEndPlus = GetTrailingBlanks( rTmp );
+    sal_Unicode cChar;
+
+    if( 2 > nEndPlus - nSttPlus ||
+        ( '+' != ( cChar = rTmp.GetChar( nSttPlus )) && '|' != cChar ) ||
+        ( '+' != ( cChar = rTmp.GetChar( nEndPlus - 1)) && '|' != cChar ))
+        return FALSE;
+
+    SwTxtFrmInfo aInfo( pAktTxtFrm );
+
+    xub_StrLen n = nSttPlus;
+    const sal_Unicode* pStr = rTmp.GetBuffer() + n;
+    SvUShorts aPosArr( 5, 5 );
+
+    while( *pStr )
+    {
+        switch( *pStr )
+        {
+        case '-':
+        case '_':
+        case '=':
+        case ' ':
+        case '\t':
+            break;
+
+        case '+':
+        case '|':
+            aPosArr.Insert( aInfo.GetCharPos(n), aPosArr.Count() );
+            break;
+
+        default:
+            return FALSE;
+        }
+        if( ++n == nEndPlus )
+            break;
+
+        ++pStr;
+    }
+
+    if( 1 < aPosArr.Count() )
+    {
+        // Ausrichtung vom Textnode besorgen:
+        USHORT nColCnt = aPosArr.Count() - 1;
+        SwTwips nSttPos = aPosArr[ 0 ];
+        SwHoriOrient eHori;
+        switch( pAktTxtNd->GetSwAttrSet().GetAdjust().GetAdjust() )
+        {
+        case SVX_ADJUST_CENTER:     eHori = HORI_CENTER;    break;
+        case SVX_ADJUST_RIGHT:      eHori = HORI_RIGHT;     break;
+
+        default:
+            if( nSttPos )
+            {
+                eHori = HORI_NONE;
+                // dann muss als letztes noch die akt. FrameBreite
+                // ins Array
+                aPosArr.Insert( pAktTxtFrm->Frm().Width(), aPosArr.Count() );
+            }
+            else
+                eHori = HORI_LEFT;
+            break;
+        }
+
+        // dann erzeuge eine Tabelle, die den Zeichen entspricht
+        DelEmptyLine();
+        SwNodeIndex aIdx( aDelPam.GetPoint()->nNode );
+        aDelPam.Move( fnMoveForward );
+        pDoc->InsertTable( *aDelPam.GetPoint(), 1, nColCnt, eHori, ALL_TBL_INS_ATTR,
+                            0, &aPosArr );
+        aDelPam.GetPoint()->nNode = aIdx;
+    }
+    return 1 < aPosArr.Count();
+}
+
+
+String& SwAutoFormat::DelLeadingBlanks( String& rStr ) const
+{
+    for( xub_StrLen nL = rStr.Len(), n = 0;
+            n < nL && IsSpace( rStr.GetChar(n) ); ++n )
+        ;
+    if( n )     // keine Spaces
+        rStr.Erase( 0, n );
+    return rStr;
+}
+
+
+String& SwAutoFormat::DelTrailingBlanks( String& rStr ) const
+{
+    xub_StrLen nL = rStr.Len(), n = nL;
+    if( !nL )
+        return rStr;
+
+    while( --n && IsSpace( rStr.GetChar( n ) )  )
+        ;
+    if( n+1 != nL )     // keine Spaces
+        rStr.Erase( n+1 );
+    return rStr;
+}
+
+
+xub_StrLen SwAutoFormat::GetLeadingBlanks( const String& rStr ) const
+{
+    for( xub_StrLen nL = rStr.Len(), n = 0;
+        n < nL && IsSpace( rStr.GetChar( n ) ); ++n )
+        ;
+    return n;
+}
+
+
+xub_StrLen SwAutoFormat::GetTrailingBlanks( const String& rStr ) const
+{
+    xub_StrLen nL = rStr.Len(), n = nL;
+    if( !nL )
+        return 0;
+
+    while( --n && IsSpace( rStr.GetChar( n ) )  )
+        ;
+    return ++n;
+}
+
+
+const sal_Unicode SwAutoFormat::GetFirstChar( const String& rStr,
+                                                BOOL bSkipDigit ) const
+{
+    const sal_Unicode* pTmp = rStr.GetBuffer();
+    BOOL bFirstNo = FALSE;
+    while( *pTmp )
+    {
+        if( !IsSpace( *pTmp ))
+        {
+            // Teste auf 1.) / 1. / 1.1.1 / (1). / (1) / ....
+            if( bSkipDigit || bFirstNo ||
+                USHRT_MAX == GetDigitLevel( &pTmp ) )
+                return *pTmp;
+            bFirstNo = TRUE;
+        }
+        ++pTmp;
+    }
+    return *pTmp;
+}
+
+
+USHORT SwAutoFormat::GetDigitLevel( const sal_Unicode** ppStr,
+        String* pPreFix, String* pPostFix, String* pNumTypes ) const
+{
+    // Teste auf 1.) / 1. / 1.1.1 / (1). / (1) / ....
+    const sal_Unicode* pTmp = *ppStr;
+    int eScan = NONE;
+
+    USHORT nStart = 0;
+    BYTE nDigitLvl = 0, nDigitCnt = 0;
+    const International& rInter = Application::GetAppInternational();
+    while( *pTmp )
+    {
+        if( rInter.IsNumeric( *pTmp ) )
+        {
+            if( eScan & DELIM )
+            {
+                if( eScan & CHG )       // nicht wenns mit einer Zahl beginnt
+                {
+                    ++nDigitLvl;
+                    if( pPostFix )
+                        *pPostFix += (sal_Unicode)1;
+                }
+
+                if( pNumTypes )
+                    *pNumTypes += (sal_Unicode)('0' + SVX_NUM_ARABIC);
+
+                eScan = eScan | CHG;
+            }
+            else if( pNumTypes && !(eScan & DIGIT) )
+                *pNumTypes += (sal_Unicode)('0' + SVX_NUM_ARABIC);
+
+            eScan &= ~DELIM;        // Delim raus
+            if( 0 != (eScan & ~CHG) && DIGIT != (eScan & ~CHG))
+                return USHRT_MAX;
+
+            eScan |= DIGIT;         // Digit rein
+            if( 3 == ++nDigitCnt )  // mehr als 2 Nummern sind kein Enum mehr
+                return USHRT_MAX;
+
+            nStart *= 10; nStart += USHORT( *pTmp - '0' );
+        }
+        else if( rInter.IsAlpha( *pTmp ) )
+        {
+            BOOL bIsUpper = rInter.IsUpper( *pTmp );
+            sal_Unicode cLow = rInter.Lower( *pTmp ), cNumTyp;
+            int eTmpScan;
+
+            // roemische Zeichen sind "mdclxvi". Da man aber eher mal eine
+            // Numerierung mit c oder d anfangen will, werden diese erstmal
+            // zu chars und spaeter ggfs. zu romischen Zeichen!
+//          if( strchr( "mdclxvi", cLow ))
+            if( 256 > cLow  &&( (eScan & (LOWER_ROMAN|UPPER_ROMAN))
+                                    ? strchr( "mdclxvi", cLow )
+                                    : strchr( "mlxvi", cLow ) ))
+            {
+                if( bIsUpper )
+                    cNumTyp = '0' + SVX_NUM_ROMAN_UPPER, eTmpScan = UPPER_ROMAN;
+                else
+                    cNumTyp = '0' + SVX_NUM_ROMAN_LOWER, eTmpScan = LOWER_ROMAN;
+            }
+            else if( bIsUpper )
+                cNumTyp = '0' + SVX_NUM_CHARS_UPPER_LETTER, eTmpScan = UPPER_ALPHA;
+            else
+                cNumTyp = '0' + SVX_NUM_CHARS_LOWER_LETTER, eTmpScan = LOWER_ALPHA;
+
+
+            //ggfs. auf roemische Zeichen umschalten (nur bei c/d!)?
+            if( 1 == nDigitCnt && ( eScan & (UPPER_ALPHA|LOWER_ALPHA) ) &&
+                ( 3 == nStart || 4 == nStart) && 256 > cLow &&
+                strchr( "mdclxvi", cLow ) &&
+                (( eScan & UPPER_ALPHA ) ? (eTmpScan & (UPPER_ALPHA|UPPER_ROMAN))
+                                         : (eTmpScan & (LOWER_ALPHA|LOWER_ROMAN))) )
+            {
+                sal_Unicode c = '0';
+                nStart = 3 == nStart ? 100 : 500;
+                if( UPPER_ALPHA == eTmpScan )
+                    eTmpScan = UPPER_ROMAN, c += SVX_NUM_ROMAN_UPPER;
+                else
+                    eTmpScan = LOWER_ROMAN, c += SVX_NUM_ROMAN_LOWER;
+
+#ifndef MAC
+                ( eScan &= ~(UPPER_ALPHA|LOWER_ALPHA)) |= eTmpScan;
+#else
+                eScan &= ~(UPPER_ALPHA|LOWER_ALPHA);
+                eScan |= eTmpScan;
+#endif
+                if( pNumTypes )
+                    pNumTypes->SetChar( pNumTypes->Len() - 1, c );
+            }
+
+            if( eScan & DELIM )
+            {
+                if( eScan & CHG )       // nicht wenns mit einer Zahl beginnt
+                {
+                    ++nDigitLvl;
+                    if( pPostFix )
+                        *pPostFix += (sal_Unicode)1;
+                }
+
+                if( pNumTypes )
+                    *pNumTypes += cNumTyp;
+                eScan = eScan | CHG;
+            }
+            else if( pNumTypes && !(eScan & eTmpScan) )
+                *pNumTypes += cNumTyp;
+
+            eScan &= ~DELIM;        // Delim raus
+
+            // falls ein andere Type gesetzt ist, brechen wir ab
+            if( 0 != ( eScan & ~CHG ) && eTmpScan != ( eScan & ~CHG ))
+                return USHRT_MAX;
+
+            if( eTmpScan & (UPPER_ALPHA | LOWER_ALPHA) )
+            {
+                // Buchstaben nur zulassen, wenn sie einmalig vorkommen
+#ifdef WITH_ALPHANUM_AS_NUMFMT
+//JP 17.06.98: um Abkuerzungen wie P.S. oder Z.b. am Absatzanfang nicht zu
+//              Numerierungen zu expandieren, hier erstmal bei erkannten
+//              ALPHA keinen gueltigen DigitLevel returnen.
+                if( nDigitCnt )
+#endif
+                    return USHRT_MAX;
+                nStart = (USHORT)(cLow - 'a') + 1;
+            }
+            else
+            {
+                // roemische Zahlen: checke ob das gueltige Zeichen sind
+                USHORT nVal;
+                BOOL bError = FALSE;
+                switch( cLow )
+                {
+                case 'm':   nVal = 1000; goto CHECK_ROMAN_1;
+                case 'd':   nVal =  500; goto CHECK_ROMAN_5;
+                case 'c':   nVal =  100; goto CHECK_ROMAN_1;
+                case 'l':   nVal =   50; goto CHECK_ROMAN_5;
+                case 'x':   nVal =   10; goto CHECK_ROMAN_1;
+                case 'v':   nVal =    5; goto CHECK_ROMAN_5;
+
+CHECK_ROMAN_1:
+                    {
+                        int nMod5 = nStart % (nVal * 5);
+                        int nLast = nStart % nVal;
+                        int n10 = nVal / 10;
+
+                        if( nMod5 == ((3 * nVal) + n10 ) ||
+                            nMod5 == ((4 * nVal) + n10 ) ||
+                            nLast == n10 )
+                            nStart += n10 * 8;
+                        else if( nMod5 == 0 ||
+                                 nMod5 == (1 * nVal) ||
+                                 nMod5 == (2 * nVal) )
+                            nStart += nVal;
+                        else
+                            bError = TRUE;
+                    }
+                    break;
+
+CHECK_ROMAN_5:
+                    {
+                        if( ( nStart / nVal ) & 1 )
+                            bError = TRUE;
+                        else
+                        {
+                            int nMod = nStart % nVal;
+                            int n10 = nVal / 5;
+                            if( n10 == nMod )
+                                nStart += 3 * n10;
+                            else if( 0 == nMod )
+                                nStart += nVal;
+                            else
+                                bError = TRUE;
+                        }
+                    }
+                    break;
+
+                case 'i':
+                        if( nStart % 5 >= 3 )
+                            bError = TRUE;
+                        else
+                            nStart += 1;
+                        break;
+
+                default:
+                    bError = TRUE;
+                }
+
+                if( bError )
+                    return USHRT_MAX;
+            }
+            eScan |= eTmpScan;          // Digit rein
+            ++nDigitCnt;
+        }
+        else if( 256 > *pTmp && strchr( /*".,)([]{}"*/ ".,)(<>", *pTmp ) )
+        {
+            // nur wenn noch keine Zahlen gelesen wurden!
+            if( pPreFix && !( eScan & ( NO_DELIM | CHG )) )
+                *pPreFix += *pTmp;
+            else if( pPostFix )
+                *pPostFix += *pTmp;
+
+            if( NO_DELIM & eScan )
+            {
+                eScan |= CHG;
+                if( pPreFix )
+                    (*pPreFix += (sal_Unicode)1)
+                              += String::CreateFromInt32( nStart );
+            }
+            eScan &= ~NO_DELIM;     // Delim raus
+            eScan |= DELIM;         // Digit rein
+            nDigitCnt = 0;
+            nStart = 0;
+        }
+        else
+            break;
+        ++pTmp;
+    }
+    if( !( CHG & eScan ) || *ppStr == pTmp || !*pTmp || !IsSpace( *pTmp ))
+        return USHRT_MAX;
+
+    if( (NO_DELIM & eScan) && pPreFix )     // den letzen nicht vergessen
+        (*pPreFix += (sal_Unicode)1) += String::CreateFromInt32( nStart );
+
+    *ppStr = pTmp;
+    return nDigitLvl;       // von 0 .. 5
+}
+
+
+void SwAutoFormat::SetColl( USHORT nId, BOOL bHdLineOrText )
+{
+    aDelPam.DeleteMark();
+    aDelPam.GetPoint()->nNode = aNdIdx;
+    aDelPam.GetPoint()->nContent.Assign( pAktTxtNd, 0 );
+
+    // behalte harte Tabs, Ausrichtung, Sprache, Silbentrennung,
+    // DropCaps und fast alle Frame-Attribute
+    SfxItemSet aSet( pDoc->GetAttrPool(),
+                        RES_PARATR_ADJUST, RES_PARATR_ADJUST,
+                        RES_PARATR_TABSTOP, RES_PARATR_DROP,
+                        RES_CHRATR_LANGUAGE, RES_CHRATR_LANGUAGE,
+                        RES_BACKGROUND, RES_SHADOW,
+                        0 );
+
+    if( pAktTxtNd->GetpSwAttrSet() )
+    {
+        aSet.Put( *pAktTxtNd->GetpSwAttrSet() );
+        // einige Sonderbedingungen:
+        // HeaderLine/Textkoerper: nur zentriert oder rechts mitnehmem
+        // sonst nur den Blocksatz
+        SvxAdjustItem* pAdj;
+        if( SFX_ITEM_SET == aSet.GetItemState( RES_PARATR_ADJUST,
+                        FALSE, (const SfxPoolItem**)&pAdj ))
+        {
+            SvxAdjust eAdj = pAdj->GetAdjust();
+            if( bHdLineOrText ? (SVX_ADJUST_RIGHT != eAdj &&
+                                 SVX_ADJUST_CENTER != eAdj)
+                              : SVX_ADJUST_BLOCK != eAdj )
+                aSet.ClearItem( RES_PARATR_ADJUST );
+        }
+    }
+
+    pDoc->SetTxtFmtCollByAutoFmt( *aDelPam.GetPoint(), nId, &aSet );
+}
+
+
+BOOL SwAutoFormat::HasSelBlanks( SwPaM& rPam ) const
+{
+    // noch ein Blank am Anfang oder Ende ?
+    // nicht loeschen, wird wieder eingefuegt.
+    SwPosition * pPos = rPam.End();
+    xub_StrLen nBlnkPos = pPos->nContent.GetIndex();
+    SwTxtNode* pTxtNd = pPos->nNode.GetNode().GetTxtNode();
+    if( nBlnkPos && nBlnkPos-- < pTxtNd->GetTxt().Len() &&
+        ( ' ' == pTxtNd->GetTxt().GetChar( nBlnkPos ) ))
+// JP 23.08.95: keine Tabs stehen lassen, diese in Blanks wandeln
+//        ( ' ' == ( cCh = pTxtNd->GetTxt()[ nBlnkPos ] ) || '\t' == cCh ))
+        pPos->nContent--;
+    else
+    {
+        pPos = rPam.GetPoint() == pPos ? rPam.GetMark() : rPam.GetPoint();
+        nBlnkPos = pPos->nContent.GetIndex();
+        pTxtNd = pPos->nNode.GetNode().GetTxtNode();
+        if( nBlnkPos < pTxtNd->GetTxt().Len() &&
+            ( ' ' == pTxtNd->GetTxt().GetChar( nBlnkPos )))
+// JP 23.08.95: keine Tabs stehen lassen, diese in Blanks wandeln
+//            ( ' ' == ( cCh = pTxtNd->GetTxt()[ nBlnkPos ] ) || '\t' == cCh ))
+            pPos->nContent++;
+        else
+            return FALSE;
+    }
+    return TRUE;
+}
+
+
+BOOL SwAutoFormat::HasBreakAttr( const SwTxtNode& rTxtNd ) const
+{
+    const SwAttrSet* pSet = rTxtNd.GetpSwAttrSet();
+    if( !pSet )
+        return FALSE;
+
+    const SfxPoolItem* pItem;
+    if( SFX_ITEM_SET == pSet->GetItemState( RES_BREAK, FALSE, &pItem )
+        && SVX_BREAK_NONE != ((SvxFmtBreakItem*)pItem)->GetBreak() )
+        return TRUE;
+
+    if( SFX_ITEM_SET == pSet->GetItemState( RES_PAGEDESC, FALSE, &pItem )
+        && ((SwFmtPageDesc*)pItem)->GetPageDesc()
+        && PD_NONE != ((SwFmtPageDesc*)pItem)->GetPageDesc()->GetUseOn() )
+        return TRUE;
+    return FALSE;
+}
+
+
+// ist ein Punkt am Ende ??
+BOOL SwAutoFormat::IsSentenceAtEnd( const SwTxtNode& rTxtNd ) const
+{
+    const String& rStr = rTxtNd.GetTxt();
+    xub_StrLen n = rStr.Len();
+    if( !n )
+        return TRUE;
+
+    while( --n && IsSpace( rStr.GetChar( n  ) ) )
+        ;
+    return '.' == rStr.GetChar( n );
+}
+
+
+// loesche im Node Anfang oder/und Ende
+void SwAutoFormat::DeleteAktPara( BOOL bStart, BOOL bEnd )
+{
+    if( aFlags.bAFmtByInput
+        ? aFlags.bAFmtByInpDelSpacesAtSttEnd
+        : aFlags.bAFmtDelSpacesAtSttEnd )
+    {
+        // Loesche Blanks am Ende vom akt. und am Anfang vom naechsten
+        aDelPam.DeleteMark();
+        aDelPam.GetPoint()->nNode = aNdIdx;
+        xub_StrLen nPos;
+        if( bStart && 0 != ( nPos = GetLeadingBlanks( pAktTxtNd->GetTxt() )))
+        {
+            aDelPam.GetPoint()->nContent.Assign( pAktTxtNd, 0 );
+            aDelPam.SetMark();
+            aDelPam.GetPoint()->nContent = nPos;
+            DeleteSel( aDelPam );
+            aDelPam.DeleteMark();
+        }
+        if( bEnd && pAktTxtNd->GetTxt().Len() !=
+                    ( nPos = GetTrailingBlanks( pAktTxtNd->GetTxt() )) )
+        {
+            aDelPam.GetPoint()->nContent.Assign( pAktTxtNd, pAktTxtNd->GetTxt().Len() );
+            aDelPam.SetMark();
+            aDelPam.GetPoint()->nContent = nPos;
+            DeleteSel( aDelPam );
+            aDelPam.DeleteMark();
+        }
+    }
+}
+
+void SwAutoFormat::DeleteSel( SwPaM& rDelPam )
+{
+    if( aFlags.bWithRedlining )
+    {
+        // damit der DelPam auch verschoben wird, in den Shell-Cursr-Ring
+        // mit aufnehmen !!
+        SwPaM* pShCrsr = pEditShell->_GetCrsr();
+        SwPaM aTmp( *pAktTxtNd, 0, pShCrsr );
+
+        Ring *pPrev = rDelPam.GetPrev();
+        rDelPam.MoveRingTo( pShCrsr );
+
+        pEditShell->DeleteSel( rDelPam );
+
+        // und den Pam wieder herausnehmen:
+        Ring *p, *pNext = (Ring*)&rDelPam;
+        do {
+            p = pNext;
+            pNext = p->GetNext();
+            p->MoveTo( &rDelPam );
+        } while( p != pPrev );
+
+        aNdIdx = aTmp.GetPoint()->nNode;
+        pAktTxtNd = aNdIdx.GetNode().GetTxtNode();
+    }
+    else
+        pEditShell->DeleteSel( rDelPam );
+}
+
+BOOL SwAutoFormat::DeleteAktNxtPara( const String& rNxtPara )
+{
+    // Loesche Blanks am Ende vom akt. und am Anfang vom naechsten
+    aDelPam.DeleteMark();
+    aDelPam.GetPoint()->nNode = aNdIdx;
+    aDelPam.GetPoint()->nContent.Assign( pAktTxtNd,
+                    GetTrailingBlanks( pAktTxtNd->GetTxt() ) );
+    aDelPam.SetMark();
+
+    aDelPam.GetPoint()->nNode++;
+    SwTxtNode* pTNd = aDelPam.GetNode()->GetTxtNode();
+    if( !pTNd )
+    {
+        // dann nur bis zum Ende von Absatz loeschen
+        aDelPam.GetPoint()->nNode--;
+        aDelPam.GetPoint()->nContent = pAktTxtNd->GetTxt().Len();
+    }
+    else
+        aDelPam.GetPoint()->nContent.Assign( pTNd,
+                            GetLeadingBlanks( rNxtPara ));
+
+    // noch ein Blank am Anfang oder Ende ?
+    // nicht loeschen, wird wieder eingefuegt.
+    BOOL bHasBlnks = HasSelBlanks( aDelPam );
+
+    if( *aDelPam.GetPoint() != *aDelPam.GetMark() )
+        DeleteSel( aDelPam );
+    aDelPam.DeleteMark();
+
+    return !bHasBlnks;
+}
+
+
+void SwAutoFormat::DelEmptyLine()
+{
+    SetRedlineTxt( STR_AUTOFMTREDL_DEL_EMPTY_PARA );
+    // Loesche Blanks den leeren Absatz
+    aDelPam.DeleteMark();
+    aDelPam.GetPoint()->nNode = aNdIdx;
+    aDelPam.GetPoint()->nContent.Assign( pAktTxtNd, pAktTxtNd->GetTxt().Len() );
+    aDelPam.SetMark();
+
+    aDelPam.GetMark()->nNode--;
+    SwTxtNode* pTNd = aDelPam.GetNode( FALSE )->GetTxtNode();
+    if( pTNd )
+        // erstmal den vorherigen Textnode benutzen.
+        aDelPam.GetMark()->nContent.Assign( pTNd, pTNd->GetTxt().Len() );
+    else
+    {
+        // dann versuche den naechsten (am Anfang vom Dok, Tabellen-Zellen,
+        // Rahmen, ...
+        aDelPam.GetMark()->nNode += 2;
+        pTNd = aDelPam.GetNode( FALSE )->GetTxtNode();
+        if( pTNd )
+        {
+            aDelPam.GetMark()->nContent.Assign( pTNd, 0 );
+            aDelPam.GetPoint()->nContent = 0;
+        }
+    }
+    if( pTNd )
+        DeleteSel( aDelPam );
+
+    aDelPam.DeleteMark();
+    ClearRedlineTxt();
+}
+
+
+void SwAutoFormat::DelMoreLinesBlanks( BOOL bWithLineBreaks )
+{
+    if( aFlags.bAFmtByInput
+        ? aFlags.bAFmtByInpDelSpacesBetweenLines
+        : aFlags.bAFmtDelSpacesBetweenLines )
+    {
+        // loesche alle "Blanks" Links und Rechts vom Einzug
+        aDelPam.DeleteMark();
+        aDelPam.GetPoint()->nNode = aNdIdx;
+        aDelPam.GetPoint()->nContent.Assign( pAktTxtNd, 0 );
+
+        SwTxtFrmInfo aFInfo( pAktTxtFrm );
+        aFInfo.GetSpaces( aDelPam, !aFlags.bAFmtByInput || bWithLineBreaks );
+
+        SwPaM* pNxt;
+        do {
+            pNxt = (SwPaM*)aDelPam.GetNext();
+            if( pNxt->HasMark() && *pNxt->GetPoint() != *pNxt->GetMark() )
+            {
+                BOOL bHasBlnks = HasSelBlanks( *pNxt );
+                DeleteSel( *pNxt );
+                if( !bHasBlnks )
+                    pDoc->Insert( *pNxt, ' ' );
+            }
+
+            if( pNxt == &aDelPam )
+                break;
+            delete pNxt;
+        } while( TRUE );
+
+        aDelPam.DeleteMark();
+    }
+}
+
+
+        // loesche den vorherigen Absatz
+void SwAutoFormat::DelPrevPara()
+{
+    aDelPam.DeleteMark();
+    aDelPam.GetPoint()->nNode = aNdIdx;
+    aDelPam.GetPoint()->nContent.Assign( pAktTxtNd, 0 );
+    aDelPam.SetMark();
+
+    aDelPam.GetPoint()->nNode--;
+    SwTxtNode* pTNd = aDelPam.GetNode()->GetTxtNode();
+    if( pTNd )
+    {
+        // erstmal den vorherigen Textnode benutzen.
+        aDelPam.GetPoint()->nContent.Assign( pTNd, pTNd->GetTxt().Len() );
+        DeleteSel( aDelPam );
+    }
+    aDelPam.DeleteMark();
+}
+
+
+void SwAutoFormat::BuildIndent()
+{
+    SetRedlineTxt( STR_AUTOFMTREDL_SET_TMPL_INDENT );
+
+    // lese alle nachfolgenden Absaetze die zu diesem Einzug gehoeren
+    BOOL bBreak = TRUE;
+    if( bMoreLines )
+        DelMoreLinesBlanks( TRUE );
+    else
+        bBreak = !IsFastFullLine( *pAktTxtNd ) ||
+                IsBlanksInString( *pAktTxtNd ) ||
+                IsSentenceAtEnd( *pAktTxtNd );
+    SetColl( RES_POOLCOLL_TEXT_IDENT );
+    if( !bBreak )
+    {
+        SetRedlineTxt( STR_AUTOFMTREDL_DEL_MORELINES );
+        const SwTxtNode* pNxtNd = GetNextNode();
+        if( pNxtNd && !bEnde )
+        {
+            do {
+                bBreak = !IsFastFullLine( *pNxtNd ) ||
+                        IsBlanksInString( *pNxtNd ) ||
+                        IsSentenceAtEnd( *pNxtNd );
+                if( DeleteAktNxtPara( pNxtNd->GetTxt() ))
+                    pDoc->Insert( aDelPam, ' ' );
+                if( bBreak )
+                    break;
+                pNxtNd = GetNextNode();
+            } while( CanJoin( pNxtNd ) &&
+                    !CalcLevel( *pNxtNd ) );
+        }
+    }
+    DeleteAktPara( TRUE, TRUE );
+    AutoCorrect();
+}
+
+
+void SwAutoFormat::BuildTextIndent()
+{
+    SetRedlineTxt( STR_AUTOFMTREDL_SET_TMPL_TEXT_INDENT);
+    // lese alle nachfolgenden Absaetze die zu diesem Einzug gehoeren
+    BOOL bBreak = TRUE;
+    if( bMoreLines )
+        DelMoreLinesBlanks( TRUE );
+    else
+        bBreak = !IsFastFullLine( *pAktTxtNd ) ||
+                    IsBlanksInString( *pAktTxtNd ) ||
+                    IsSentenceAtEnd( *pAktTxtNd );
+
+    if( aFlags.bAFmtByInput )
+        pAktTxtNd->SetAutoFmtLvl( (BYTE)CalcLevel( *pAktTxtNd ) );
+
+    SetColl( RES_POOLCOLL_TEXT_MOVE );
+    if( !bBreak )
+    {
+        SetRedlineTxt( STR_AUTOFMTREDL_DEL_MORELINES );
+        const SwTxtNode* pNxtNd = GetNextNode();
+        while(  CanJoin( pNxtNd ) &&
+                CalcLevel( *pNxtNd ) )
+        {
+            bBreak = !IsFastFullLine( *pNxtNd ) || IsBlanksInString( *pNxtNd ) ||
+                    IsSentenceAtEnd( *pNxtNd );
+            if( DeleteAktNxtPara( pNxtNd->GetTxt() ) )
+                pDoc->Insert( aDelPam, ' ' );
+            if( bBreak )
+                break;
+            pNxtNd = GetNextNode();
+        }
+    }
+    DeleteAktPara( TRUE, TRUE );
+    AutoCorrect();
+}
+
+
+void SwAutoFormat::BuildText()
+{
+    SetRedlineTxt( STR_AUTOFMTREDL_SET_TMPL_TEXT );
+    // lese alle nachfolgenden Absaetze die zu diesem Text
+    // ohne Einzug gehoeren
+    BOOL bBreak = TRUE;
+    if( bMoreLines )
+        DelMoreLinesBlanks();
+    else
+        bBreak = !IsFastFullLine( *pAktTxtNd ) ||
+                    IsBlanksInString( *pAktTxtNd ) ||
+                    IsSentenceAtEnd( *pAktTxtNd );
+    SetColl( RES_POOLCOLL_TEXT, TRUE );
+    if( !bBreak )
+    {
+        SetRedlineTxt( STR_AUTOFMTREDL_DEL_MORELINES );
+        const SwTxtNode* pNxtNd = GetNextNode();
+        while(  CanJoin( pNxtNd ) &&
+                !CalcLevel( *pNxtNd ) )
+        {
+            bBreak = !IsFastFullLine( *pNxtNd ) || IsBlanksInString( *pNxtNd ) ||
+                    IsSentenceAtEnd( *pNxtNd );
+            if( DeleteAktNxtPara( pNxtNd->GetTxt() ) )
+                pDoc->Insert( aDelPam, ' ' );
+            if( bBreak )
+                break;
+            pNxtNd = GetNextNode();
+        }
+    }
+    DeleteAktPara( TRUE, TRUE );
+    AutoCorrect();
+}
+
+
+void SwAutoFormat::BuildEnum( USHORT nLvl, USHORT nDigitLevel )
+{
+    SetRedlineTxt( STR_AUTOFMTREDL_SET_NUMBULET );
+
+    BOOL bBreak = TRUE;
+
+    // als erstes den akt. Einzug bestimmen und die Framebreite bestimmen
+    SwTwips nFrmWidth = pAktTxtFrm->Prt().Width();;
+    SwTwips nLeftTxtPos;
+    {
+        const sal_Unicode* pTxt = pAktTxtNd->GetTxt().GetBuffer(), *pSav = pTxt;
+        while( IsSpace( *pTxt ) )
+            ++pTxt;
+
+        SwTxtFrmInfo aInfo( pAktTxtFrm );
+        nLeftTxtPos = aInfo.GetCharPos( pTxt - pSav );
+#ifdef NUM_RELSPACE
+        nLeftTxtPos -= pAktTxtNd->GetSwAttrSet().GetLRSpace().GetLeft();
+#endif
+    }
+
+    if( bMoreLines )
+        DelMoreLinesBlanks();
+    else
+        bBreak = !IsFastFullLine( *pAktTxtNd ) ||
+                    IsBlanksInString( *pAktTxtNd ) ||
+                    IsSentenceAtEnd( *pAktTxtNd );
+
+//  SetColl( RES_POOLCOLL_NUM_LEVEL1 + ( nLvl * 4 ) );
+    DeleteAktPara( TRUE, TRUE );
+
+    BOOL bChgBullet = FALSE, bChgEnum = FALSE;
+    xub_StrLen nAutoCorrPos = 0;
+
+    // falls die Numerierung gesetzt werden, die akt. besorgen
+    SwNumRule aRule( pDoc->GetUniqueNumRuleName() );
+    const SwNumRule* pCur;
+    if( aFlags.bSetNumRule && 0 != (pCur = pAktTxtNd->GetNumRule()) )
+        aRule = *pCur;
+
+    // ersetze das Bullet-Zeichen mit dem definiertem
+    const sal_Unicode* pStt = pAktTxtNd->GetTxt().GetBuffer(), *pOrigStt = pStt;
+    const sal_Char* pFndBulletChr;
+//  if( aFlags.bAFmtByInput ? aFlags.bSetNumRule : aFlags.bChgEnumNum &&
+    if( aFlags.bChgEnumNum &&
+        2 < pAktTxtNd->GetTxt().Len() && 256 > *pStt &&
+        0 != ( pFndBulletChr = strchr( pBulletChar, *pStt )) &&
+        IsSpace( *(pStt+1) ) )
+    {
+        if( aFlags.bAFmtByInput )
+        {
+            if( aFlags.bSetNumRule )
+            {
+                SwCharFmt* pCFmt = pDoc->GetCharFmtFromPool(
+                                            RES_POOLCHR_BUL_LEVEL );
+                bChgBullet = TRUE;
+                // wurde das Format schon mal angepasst?
+                if( !aRule.GetNumFmt( nLvl ) )
+                {
+                    int nBulletPos = pFndBulletChr - pBulletChar;
+                    sal_Char cBullChar;
+                    const Font* pBullFnt;
+                    if( nBulletPos < cnPosEnDash )
+                    {
+                        cBullChar = aFlags.cBullet;
+                        pBullFnt = &aFlags.aBulletFont;
+                    }
+                    else
+                    {
+                        cBullChar = nBulletPos < cnPosEmDash
+                                        ? cStartBatsEnDash
+                                        : cStartBatsEmDash;
+                        pBullFnt = &SwNumRule::GetDefBulletFont();
+                    }
+
+                    USHORT nAbsPos = lBullIndent;
+                    USHORT nSpaceSteps = nLvl
+                                            ? USHORT(nLeftTxtPos / nLvl)
+                                            : lBullIndent;
+                    for( BYTE n = 0; n < MAXLEVEL; ++n, nAbsPos += nSpaceSteps )
+                    {
+                        SwNumFmt aFmt( aRule.Get( n ) );
+                        aFmt.SetBulletFont( pBullFnt );
+                        aFmt.SetBulletChar( cBullChar );
+                        aFmt.eType = SVX_NUM_CHAR_SPECIAL;
+                        aFmt.SetRelLSpace( FALSE );
+                        aFmt.SetFirstLineOffset( lBullFirstLineOffset );
+                        aFmt.SetAbsLSpace( nAbsPos );
+                        aRule.Set( n, aFmt );
+
+                        if( !aFmt.GetCharFmt() )
+                            aFmt.SetCharFmt( pCFmt );
+
+                        if( n == nLvl &&
+                            nFrmWidth < ( nSpaceSteps * MAXLEVEL ) )
+                            nSpaceSteps = ( nFrmWidth - nLeftTxtPos ) /
+                                                ( MAXLEVEL - nLvl );
+                    }
+                }
+            }
+        }
+        else
+        {
+            bChgBullet = TRUE;
+            SetColl( RES_POOLCOLL_BUL_LEVEL1 + ( Min( nLvl, cnNumBullColls ) * 4 ) );
+        }
+    }
+    else
+    {
+        // dann ist das eine Nummerierung
+
+        //JP 21.11.97: Der NumLevel wird entweder der DigitLevel oder
+        //              wenn der nicht vorhanden oder 0 ist, durch den
+        //              (Einrueckungs-)Level.
+
+        String aPostFix, aPreFix, aNumTypes;
+        if( USHRT_MAX != ( nDigitLevel = GetDigitLevel(
+                                &pStt, &aPreFix, &aPostFix, &aNumTypes )) )
+        {
+            bChgEnum = TRUE;
+
+            // Ebene 0 und Einrueckung dann wird die Ebene durch den linken
+            // Einzug und der default NumEinrueckung bestimmt.
+            if( !nDigitLevel && nLeftTxtPos )
+                nLvl = Min( USHORT( nLeftTxtPos / lNumIndent ),
+                            USHORT( MAXLEVEL - 1 ) );
+            else
+                nLvl = nDigitLevel;
+        }
+
+        if( bChgEnum && aFlags.bSetNumRule )
+        {
+            if( !pCur )         // NumRule anpassen, wenn sie neu ist
+            {
+                SwCharFmt* pCFmt = pDoc->GetCharFmtFromPool(
+                                            RES_POOLCHR_NUM_LEVEL );
+                if( !nDigitLevel )
+                {
+                    SwNumFmt aFmt( aRule.Get( nLvl ) );
+                    aFmt.SetStartValue( aPreFix.GetToken( 1,
+                                            (sal_Unicode)1 ).ToInt32());
+                    aFmt.SetPrefix( aPreFix.GetToken( 0, (sal_Unicode)1 ));
+                    aFmt.SetPostfix( aPostFix.GetToken( 0, (sal_Unicode)1 ));
+                    aFmt.SetInclUpperLevel( FALSE );
+
+                    if( !aFmt.GetCharFmt() )
+                        aFmt.SetCharFmt( pCFmt );
+
+                    if( aNumTypes.Len() )
+                        aFmt.eType = (SvxExtNumType)(aNumTypes.GetChar( 0 ) - '0');
+
+                    aRule.Set( nLvl, aFmt );
+                }
+                else
+                {
+                    USHORT nSpaceSteps = nLvl ? USHORT(nLeftTxtPos / nLvl) : 0;
+                    for( BYTE n = 0; n <= nLvl; ++n )
+                    {
+                        SwNumFmt aFmt( aRule.Get( n ) );
+
+                        aFmt.SetStartValue( aPreFix.GetToken( n+1,
+                                                    (sal_Unicode)1 ).ToInt32() );
+                        if( !n )
+                            aFmt.SetPrefix( aPreFix.GetToken( n, (sal_Unicode)1 ));
+                        aFmt.SetPostfix( aPostFix.GetToken( n, (sal_Unicode)1 ));
+                        aFmt.SetInclUpperLevel( TRUE );
+                        if( n < aNumTypes.Len() )
+                            aFmt.eType = (SvxExtNumType)(aNumTypes.GetChar( n ) - '0');
+
+                        aFmt.SetRelLSpace( FALSE );
+                        aFmt.SetAbsLSpace( USHORT( nSpaceSteps * n )
+                                            + lNumIndent );
+
+                        if( !aFmt.GetCharFmt() )
+                            aFmt.SetCharFmt( pCFmt );
+
+                        aRule.Set( n, aFmt );
+                    }
+
+                    // passt alles vollstaendig in den Frame?
+                    BOOL bDefStep = nFrmWidth < (nSpaceSteps * MAXLEVEL);
+                    for( ; n < MAXLEVEL; ++n )
+                    {
+                        SwNumFmt aFmt( aRule.Get( n ) );
+                        aFmt.SetInclUpperLevel( TRUE );
+                        aFmt.SetRelLSpace( FALSE );
+                        if( bDefStep )
+                            aFmt.SetAbsLSpace( USHORT( (nLeftTxtPos +
+                                        SwNumRule::GetNumIndent( n - nLvl ))));
+                        else
+                            aFmt.SetAbsLSpace( USHORT( nSpaceSteps * n )
+                                                + lNumIndent );
+                        aRule.Set( n, aFmt );
+                    }
+                }
+            }
+        }
+        else if( !aFlags.bAFmtByInput )
+            SetColl( RES_POOLCOLL_NUM_LEVEL1 + ( Min( nLvl, cnNumBullColls ) * 4 ) );
+        else
+            bChgEnum = FALSE;
+    }
+
+    if( bChgEnum || bChgBullet )
+    {
+        aDelPam.DeleteMark();
+        aDelPam.GetPoint()->nNode = aNdIdx;
+
+        if( aFlags.bSetNumRule )
+        {
+            if( aFlags.bAFmtByInput )
+            {
+                aDelPam.SetMark();
+                aDelPam.GetMark()->nNode++;
+                aDelPam.GetNode(FALSE)->GetTxtNode()->UpdateNum( SwNodeNum( (BYTE)nLvl ) );
+            }
+
+            pAktTxtNd->UpdateNum( SwNodeNum( (BYTE)nLvl ) );
+            pAktTxtNd->SetNumLSpace( TRUE );
+
+            pDoc->SetNumRule( aDelPam, aRule );
+            aDelPam.DeleteMark();
+
+            aDelPam.GetPoint()->nContent.Assign( pAktTxtNd, 0 );
+        }
+        else
+            aDelPam.GetPoint()->nContent.Assign( pAktTxtNd,
+                        bChgEnum ? (pStt - pOrigStt) : 0 );
+        aDelPam.SetMark();
+
+        if( bChgBullet )
+            pStt += 2;
+
+        while( IsSpace( *pStt ))
+            pStt++;
+
+        aDelPam.GetPoint()->nContent = USHORT( pStt - pOrigStt );
+        DeleteSel( aDelPam );
+
+        if( !aFlags.bSetNumRule )
+        {
+            String sChgStr( '\t' );
+            if( bChgBullet )
+                sChgStr.Insert( aFlags.cBullet, 0 );
+            pDoc->Insert( aDelPam, sChgStr );
+
+            if( bChgBullet )
+            {
+                aDelPam.GetPoint()->nContent = 0;
+                aDelPam.SetMark();
+                aDelPam.GetMark()->nContent = 1;
+                SvxFontItem aFnt( aFlags.aBulletFont.GetFamily(),
+                                  aFlags.aBulletFont.GetName(),
+                                  aFlags.aBulletFont.GetStyleName(),
+                                  aFlags.aBulletFont.GetPitch(),
+                                  aFlags.aBulletFont.GetCharSet() );
+                pDoc->SetFmtItemByAutoFmt( aDelPam, aFnt );
+                aDelPam.DeleteMark();
+                nAutoCorrPos = 2;
+            }
+            SvxTabStopItem aTStops;     aTStops.Insert( SvxTabStop( 0 ));
+            pDoc->SetFmtItemByAutoFmt( aDelPam, aTStops );
+        }
+    }
+
+    if( bBreak )
+    {
+        AutoCorrect( nAutoCorrPos );       /* Offset wegen Bullet + Tab */
+        return;
+    }
+
+    const SwTxtNode* pNxtNd = GetNextNode();
+    while( CanJoin( pNxtNd ) &&
+            nLvl == CalcLevel( *pNxtNd ) )
+    {
+        SetRedlineTxt( STR_AUTOFMTREDL_DEL_MORELINES );
+        bBreak = !IsFastFullLine( *pNxtNd ) || IsBlanksInString( *pNxtNd ) ||
+                IsSentenceAtEnd( *pNxtNd );
+        if( DeleteAktNxtPara( pNxtNd->GetTxt() ) )
+            pDoc->Insert( aDelPam, ' ' );
+        if( bBreak )
+            break;
+        pNxtNd = GetNextNode();
+    }
+    DeleteAktPara( FALSE, TRUE );
+    AutoCorrect( nAutoCorrPos );
+}
+
+
+void SwAutoFormat::BuildNegIndent( SwTwips nSpaces )
+{
+    SetRedlineTxt( STR_AUTOFMTREDL_SET_TMPL_NEG_INDENT );
+    // Test auf Gegenueberstellung:
+    // (n Worte, durch Space/Tabs getrennt, mit gleicher
+    //   Einrueckung in der 2.Zeile)
+
+    // lese alle nachfolgenden Absaetze die zu dieser Aufzaehlung gehoeren
+    BOOL bBreak = TRUE;
+    xub_StrLen nSpacePos, nTxtPos = GetBigIndent( nSpacePos );
+    if( bMoreLines )
+        DelMoreLinesBlanks( TRUE );
+    else
+        bBreak = !IsFastFullLine( *pAktTxtNd ) ||
+                    ( !nTxtPos && IsBlanksInString( *pAktTxtNd )) ||
+                    IsSentenceAtEnd( *pAktTxtNd );
+
+    SetColl( nTxtPos
+                ? RES_POOLCOLL_CONFRONTATION
+                : RES_POOLCOLL_TEXT_NEGIDENT );
+
+    if( nTxtPos )
+    {
+        const String& rStr = pAktTxtNd->GetTxt();
+        BOOL bInsTab = TRUE;
+
+        if( '\t' == rStr.GetChar( nSpacePos+1 ))       // ein Tab, das belassen wir
+        {
+            --nSpacePos;
+            bInsTab = FALSE;
+        }
+
+        xub_StrLen nSpaceStt = nSpacePos;
+        while( nSpaceStt && IsSpace( rStr.GetChar( --nSpaceStt ) ) )
+            ;
+        ++nSpaceStt;
+
+        if( bInsTab && '\t' == rStr.GetChar( nSpaceStt ) )      // ein Tab, das belassen wir
+        {
+            ++nSpaceStt;
+            bInsTab = FALSE;
+        }
+
+
+        aDelPam.DeleteMark();
+        aDelPam.GetPoint()->nNode = aNdIdx;
+        aDelPam.GetPoint()->nContent.Assign( pAktTxtNd, nSpacePos );
+
+#if 0
+// nicht auf den akt. Einzug setzen, sondern Vorlagen benutzen
+        // das Attr. setzen
+        // hier sollte die richtige Vorlage benutzt werden !!!
+        SvxLRSpaceItem aLSpace;
+        aLSpace.SetTxtFirstLineOfst( -(SwTwips)nTxtPos );
+        aLSpace.SetTxtLeft( nTxtPos );
+        pDoc->Insert( aDelPam, aLSpace );
+#endif
+        // alten Spaces, usw. loeschen
+        if( nSpaceStt < nSpacePos )
+        {
+            aDelPam.SetMark();
+            aDelPam.GetMark()->nContent = nSpaceStt;
+            DeleteSel( aDelPam );
+            if( bInsTab )
+                pDoc->Insert( aDelPam, '\t' );
+        }
+    }
+
+    if( !bBreak )
+    {
+        SetRedlineTxt( STR_AUTOFMTREDL_DEL_MORELINES );
+        SwTxtFrmInfo aFInfo( pAktTxtFrm );
+        const SwTxtNode* pNxtNd = GetNextNode();
+        while(  CanJoin( pNxtNd ) &&
+                20 < Abs( (long)(nSpaces - aFInfo.SetFrm(
+                                GetFrm( *pNxtNd ) ).GetLineStart() ))
+            )
+        {
+            bBreak = !IsFastFullLine( *pNxtNd ) ||
+                    IsBlanksInString( *pNxtNd ) ||
+                    IsSentenceAtEnd( *pNxtNd );
+            if( DeleteAktNxtPara( pNxtNd->GetTxt() ) )
+                pDoc->Insert( aDelPam, ' ' );
+            if( bBreak )
+                break;
+            pNxtNd = GetNextNode();
+        }
+    }
+    DeleteAktPara( TRUE, TRUE );
+    AutoCorrect();
+}
+
+
+void SwAutoFormat::BuildHeadLine( USHORT nLvl )
+{
+    if( aFlags.bWithRedlining )
+    {
+        String sTxt( *ViewShell::GetShellRes()->GetAutoFmtNameLst()[
+                                    STR_AUTOFMTREDL_SET_TMPL_HEADLINE ] );
+        sTxt.SearchAndReplace( String::CreateFromAscii(
+                                    RTL_CONSTASCII_STRINGPARAM( "$(ARG1)" )),
+                                String::CreateFromInt32( nLvl + 1 ) );
+        pDoc->SetAutoFmtRedlineComment( &sTxt );
+    }
+
+    SetColl( RES_POOLCOLL_HEADLINE1 + nLvl, TRUE );
+    if( aFlags.bAFmtByInput )
+    {
+        SwTxtFmtColl& rNxtColl = pAktTxtNd->GetTxtColl()->GetNextTxtFmtColl();
+
+        DelPrevPara();
+
+        DeleteAktPara( TRUE, FALSE );
+        DeleteAktNxtPara( aEmptyStr );
+
+        aDelPam.DeleteMark();
+        aDelPam.GetPoint()->nNode = aNdIdx.GetIndex() + 1;
+        aDelPam.GetPoint()->nContent.Assign( aDelPam.GetCntntNode(), 0 );
+        pDoc->SetTxtFmtColl( aDelPam, &rNxtColl );
+    }
+    else
+    {
+        DeleteAktPara( TRUE, TRUE );
+        AutoCorrect();
+    }
+}
+
+
+        // dann lasse doch mal das AutoCorrect auf den akt. TextNode los
+void SwAutoFormat::AutoCorrect( xub_StrLen nPos )
+{
+    if( aFlags.bAFmtByInput ||
+        (!aFlags.bAutoCorrect && !aFlags.bReplaceQuote &&
+        !aFlags.bCptlSttSntnc && !aFlags.bCptlSttWrd &&
+        !aFlags.bChgFracionSymbol && !aFlags.bChgOrdinalNumber &&
+        !aFlags.bChgToEnEmDash && !aFlags.bSetINetAttr &&
+        !aFlags.bChgWeightUnderl) )
+        return;
+
+    const String* pTxt = &pAktTxtNd->GetTxt();
+    if( nPos >= pTxt->Len() )
+        return;
+
+    aDelPam.DeleteMark();
+    aDelPam.GetPoint()->nNode = aNdIdx;
+    aDelPam.GetPoint()->nContent.Assign( pAktTxtNd, 0 );
+
+    SwAutoCorrDoc aACorrDoc( *pEditShell, aDelPam );
+    SvxAutoCorrect* pATst = OFF_APP()->GetAutoCorrect();
+
+    SwTxtFrmInfo aFInfo( 0 );
+
+    xub_StrLen nSttPos, nLastBlank = nPos;
+    BOOL bFirst = aFlags.bCptlSttSntnc, bFirstSent = bFirst;
+    sal_Unicode cChar;
+
+    do {
+        while( nPos < pTxt->Len() && IsSpace( cChar = pTxt->GetChar( nPos ) ))
+            ++nPos;
+        if( nPos == pTxt->Len() )
+            break;      // das wars
+
+        if( aFlags.bReplaceQuote &&
+            ( '\"' == cChar || '\'' == cChar ) &&
+            ( !nPos || ' ' == pTxt->GetChar( nPos-1 ) ) )
+        {
+            // --------------------------------------
+            // beachte: Sonderfall Symbolfonts !!!
+            if( !aFInfo.GetFrm() )
+                aFInfo.SetFrm( GetFrm( *pAktTxtNd ) );
+            if( !aFInfo.IsBullet( nPos ))
+            {
+                SetRedlineTxt( STR_AUTOFMTREDL_TYPO );
+                aDelPam.GetPoint()->nContent = nPos;
+                BOOL bSetHardBlank = FALSE;
+
+                String sReplace( pATst->GetQuote( aACorrDoc,
+                                    nPos, cChar, TRUE ));
+
+                aDelPam.SetMark();
+                aDelPam.GetPoint()->nContent = nPos+1;
+                if( 2 == sReplace.Len() && ' ' == sReplace.GetChar( 1 ))
+                {
+                    sReplace.Erase( 1 );
+                    bSetHardBlank = TRUE;
+                }
+                pDoc->Replace( aDelPam, sReplace, FALSE );
+
+                if( aFlags.bWithRedlining )
+                {
+                    aNdIdx = aDelPam.GetPoint()->nNode;
+                    pAktTxtNd = aNdIdx.GetNode().GetTxtNode();
+                    pTxt = &pAktTxtNd->GetTxt();
+                    aDelPam.SetMark();
+                    aFInfo.SetFrm( 0 );
+                }
+
+                nPos += sReplace.Len() - 1;
+                aDelPam.DeleteMark();
+                if( bSetHardBlank )
+                {
+                    pDoc->Insert( aDelPam, CHAR_HARDBLANK );
+                    ++nPos;
+                }
+            }
+        }
+
+        int bCallACorr = FALSE;
+        int bBreak = 0;
+        if( nPos && IsSpace( pTxt->GetChar( nPos-1 )))
+            nLastBlank = nPos;
+        for( nSttPos = nPos; !bBreak && nPos < pTxt->Len(); ++nPos )
+            switch( cChar = pTxt->GetChar( nPos ) )
+            {
+            case '\"':
+            case '\'':
+                if( aFlags.bReplaceQuote )
+                {
+                    // --------------------------------------
+                    // beachte: Sonderfall Symbolfonts !!!
+                    if( !aFInfo.GetFrm() )
+                        aFInfo.SetFrm( GetFrm( *pAktTxtNd ) );
+                    if( !aFInfo.IsBullet( nPos ))
+                    {
+                        SetRedlineTxt( STR_AUTOFMTREDL_TYPO );
+                        BOOL bSetHardBlank = FALSE;
+                        aDelPam.GetPoint()->nContent = nPos;
+                        String sReplace( pATst->GetQuote( aACorrDoc,
+                                                    nPos, cChar, FALSE ));
+
+                        if( 2 == sReplace.Len() && ' ' == sReplace.GetChar( 0 ))
+                        {
+                            sReplace.Erase( 0, 1 );
+                            bSetHardBlank = TRUE;
+                        }
+
+                        aDelPam.SetMark();
+                        aDelPam.GetPoint()->nContent = nPos+1;
+                        pDoc->Replace( aDelPam, sReplace, FALSE );
+
+                        if( aFlags.bWithRedlining )
+                        {
+                            aNdIdx = aDelPam.GetPoint()->nNode;
+                            pAktTxtNd = aNdIdx.GetNode().GetTxtNode();
+                            pTxt = &pAktTxtNd->GetTxt();
+                            aDelPam.SetMark();
+                            aDelPam.DeleteMark();
+                            aFInfo.SetFrm( 0 );
+                        }
+
+                        nPos += sReplace.Len() - 1;
+                        aDelPam.DeleteMark();
+
+                        if( bSetHardBlank )
+                        {
+                            aDelPam.GetPoint()->nContent = nPos;
+                            pDoc->Insert( aDelPam, CHAR_HARDBLANK );
+                            aDelPam.GetPoint()->nContent = ++nPos;
+                        }
+                    }
+                }
+                break;
+            case '*':
+            case '_':
+                if( aFlags.bChgWeightUnderl )
+                {
+                    // --------------------------------------
+                    // beachte: Sonderfall Symbolfonts !!!
+                    if( !aFInfo.GetFrm() )
+                        aFInfo.SetFrm( GetFrm( *pAktTxtNd ) );
+                    if( !aFInfo.IsBullet( nPos ))
+                    {
+                        SetRedlineTxt( '*' == cChar
+                                            ? STR_AUTOFMTREDL_BOLD
+                                            : STR_AUTOFMTREDL_UNDER );
+
+                        sal_Unicode cBlank = nSttPos ? pTxt->GetChar(nSttPos - 1) : 0;
+                        aDelPam.GetPoint()->nContent = nPos;
+
+                        if( pATst->FnChgWeightUnderl( aACorrDoc, *pTxt,
+                                                            nSttPos, nPos ))
+                        {
+                            nPos = aDelPam.GetPoint()->nContent.GetIndex() - 1;
+                            // wurde vorm Start ein Zeichen entfernt?
+                            if( cBlank && cBlank != pTxt->GetChar(nSttPos - 1) )
+                                --nSttPos;
+                        }
+                    }
+                }
+                break;
+
+            case '.':
+            case '!':
+            case '?':
+                if( aFlags.bCptlSttSntnc )
+                    bFirstSent = TRUE;
+//alle Wortrenner loesen die Autokorrektur aus!
+//              break;
+
+            default:
+//alle Wortrenner loesen die Autokorrektur aus!
+//          case ' ':
+//          case '\t':
+                if( !WordSelection::IsNormalChar( cChar ))
+                {
+                    --nPos;     // ++nPos von dem for ungueltig machen !
+                    ++bBreak;
+                }
+                break;
+            }
+
+        if( nPos == nSttPos )
+        {
+            if( ++nPos == pTxt->Len() )
+                bCallACorr = TRUE;
+        }
+        else
+            bCallACorr = TRUE;
+
+
+        if( bCallACorr )
+        {
+            bCallACorr = FALSE;
+            aDelPam.GetPoint()->nContent = nPos;
+            SetRedlineTxt( STR_AUTOFMTREDL_USE_REPLACE );
+            if( aFlags.bAutoCorrect &&
+                aACorrDoc.ChgAutoCorrWord( nSttPos, nPos, *pATst, 0 ) )
+            {
+                nPos = aDelPam.GetPoint()->nContent.GetIndex();
+
+                if( aFlags.bWithRedlining )
+                {
+                    aNdIdx = aDelPam.GetPoint()->nNode;
+                    pAktTxtNd = aNdIdx.GetNode().GetTxtNode();
+                    pTxt = &pAktTxtNd->GetTxt();
+                    aDelPam.SetMark();
+                    aDelPam.DeleteMark();
+                }
+
+                continue;       // nichts weiter mehr abpruefen
+            }
+
+            if( ( aFlags.bChgFracionSymbol &&
+                    SetRedlineTxt( STR_AUTOFMTREDL_FRACTION ) &&
+                    pATst->FnChgFractionSymbol( aACorrDoc, *pTxt, nSttPos, nPos ) ) ||
+                ( aFlags.bChgOrdinalNumber &&
+                    SetRedlineTxt( STR_AUTOFMTREDL_ORDINAL ) &&
+                    pATst->FnChgOrdinalNumber( aACorrDoc, *pTxt, nSttPos, nPos ) ) ||
+                ( aFlags.bChgToEnEmDash &&
+                    SetRedlineTxt( STR_AUTOFMTREDL_DASH ) &&
+                    pATst->FnChgToEnEmDash( aACorrDoc, *pTxt, nSttPos, nPos ) ) ||
+                ( aFlags.bSetINetAttr &&
+                    ( nPos == pTxt->Len() || IsSpace( pTxt->GetChar( nPos )) ) &&
+                    SetRedlineTxt( STR_AUTOFMTREDL_DETECT_URL ) &&
+                    pATst->FnSetINetAttr( aACorrDoc, *pTxt, nLastBlank, nPos ) ) )
+                    nPos = aDelPam.GetPoint()->nContent.GetIndex();
+            else
+            {
+                    LanguageType eLang = LANGUAGE_SYSTEM;
+                    if( pAktTxtNd )
+                    {
+                        SfxItemSet aSet( pEditShell->GetDoc()->GetAttrPool(),
+                                        RES_CHRATR_LANGUAGE, RES_CHRATR_LANGUAGE );
+                        if( pAktTxtNd->GetAttr( aSet, nPos, nPos ))
+                            eLang = ((const SvxLanguageItem&)aSet.Get( RES_CHRATR_LANGUAGE ))
+                                                .GetLanguage();
+                    }
+
+                // Zwei Grossbuchstaben am Wort-Anfang ??
+                if( aFlags.bCptlSttWrd )
+                {
+                    SetRedlineTxt( STR_AUTOFMTREDL_CPTL_STT_WORD );
+                    pATst->FnCptlSttWrd( aACorrDoc, *pTxt, nSttPos, nPos, eLang );
+                }
+                // Grossbuchstabe am Satz-Anfang ??
+                if( aFlags.bCptlSttSntnc && bFirst )
+                {
+                    SetRedlineTxt( STR_AUTOFMTREDL_CPTL_STT_SENT );
+                    pATst->FnCptlSttSntnc( aACorrDoc, *pTxt, TRUE, nSttPos, nPos, eLang);
+                    bFirst = FALSE;
+                }
+
+                bFirst = bFirstSent;
+                bFirstSent = FALSE;
+
+                if( aFlags.bWithRedlining )
+                {
+                    aNdIdx = aDelPam.GetPoint()->nNode;
+                    pAktTxtNd = aNdIdx.GetNode().GetTxtNode();
+                    pTxt = &pAktTxtNd->GetTxt();
+                    aDelPam.SetMark();
+                    aDelPam.DeleteMark();
+                }
+            }
+        }
+    } while( nPos < pTxt->Len() );
+    ClearRedlineTxt();
+}
+
+
+SwAutoFormat::SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFmtFlags& rFlags,
+                            SwNodeIndex* pSttNd, SwNodeIndex* pEndNd )
+    : aFlags( rFlags ),
+    aDelPam( pEdShell->GetDoc()->GetNodes().GetEndOfExtras() ),
+    aNdIdx( pEdShell->GetDoc()->GetNodes().GetEndOfExtras(), +1 ),
+    aEndNdIdx( pEdShell->GetDoc()->GetNodes().GetEndOfContent() ),
+    pEditShell( pEdShell ),
+    pDoc( pEdShell->GetDoc() ),
+    pAktTxtNd( 0 ), pAktTxtFrm( 0 ),
+    nRedlAutoFmtSeqId( 0 )
+{
+    ASSERT( (pSttNd && pEndNd) || (!pSttNd && !pEndNd),
+            "Kein Bereich angegeben" );
+
+    if( aFlags.bSetNumRule && !aFlags.bAFmtByInput )
+        aFlags.bSetNumRule = FALSE;
+
+    BOOL bReplaceStyles = !aFlags.bAFmtByInput || aFlags.bReplaceStyles;
+
+    const International& rInter = Application::GetAppInternational();
+
+    String aStr;
+    const SwTxtNode* pNxtNd;
+    BOOL bNxtEmpty, bNxtAlpha;
+    USHORT nNxtLevel;
+
+    // setze den Bereich zum Autoformatieren
+    if( pSttNd )
+    {
+        aNdIdx = *pSttNd;
+        aNdIdx--;           // fuer GoNextPara, ein Absatz davor
+        aEndNdIdx = *pEndNd;
+        aEndNdIdx++;
+
+        // teste den vorhergehenden TextNode
+        pNxtNd = aNdIdx.GetNode().GetTxtNode();
+        bEmptyLine = !pNxtNd ||
+                    IsEmptyLine( *pNxtNd ) ||
+                    IsNoAlphaLine( *pNxtNd );
+    }
+    else
+        bEmptyLine = TRUE;      // am Dokument Anfang
+
+    bEnde = FALSE;
+
+    // setze die Werte fuer die Prozent-Anzeige
+    nEndNdIdx = aEndNdIdx.GetIndex();
+
+    if( !aFlags.bAFmtByInput )
+        ::StartProgress( STR_STATSTR_AUTOFORMAT, aNdIdx.GetIndex(),
+                         nEndNdIdx = aEndNdIdx.GetIndex(),
+                         pDoc->GetDocShell() );
+
+    SwRedlineMode eRedlMode = pDoc->GetRedlineMode(), eOldMode = eRedlMode;
+    if( aFlags.bWithRedlining )
+    {
+        pDoc->SetAutoFmtRedline( TRUE );
+        eRedlMode = SwRedlineMode(REDLINE_ON | REDLINE_SHOW_INSERT );
+        eOldMode = SwRedlineMode( eOldMode | REDLINE_SHOW_DELETE | REDLINE_SHOW_INSERT );
+    }
+    else
+        eRedlMode = SwRedlineMode( REDLINE_SHOW_INSERT | REDLINE_IGNORE );
+    pDoc->SetRedlineMode( eRedlMode );
+
+    // wenn mehrere Zeilen, dann erstmal nicht mit
+    // dem nachfolgenden Absatz zusammenfassen.
+    bMoreLines = FALSE;
+
+    nLastCalcHeadLvl = nLastCalcEnumLvl = 0;
+    nLastHeadLvl = nLastEnumLvl = USHRT_MAX;
+    USHORT nLevel, nDigitLvl;
+
+    // defaulten
+    SwTxtFrmInfo aFInfo( 0 );
+
+    // das ist unser Automat fuer die Auto-Formatierung
+    eStat = READ_NEXT_PARA;
+    while( !bEnde )
+    {
+        switch( eStat )
+        {
+        case READ_NEXT_PARA:
+            {
+                aStr = GoNextPara();
+                eStat = bEnde ? IS_ENDE : TST_EMPTY_LINE;
+            }
+            break;
+
+        case TST_EMPTY_LINE:
+            if( IsEmptyLine( *pAktTxtNd ) )
+            {
+                if( aFlags.bDelEmptyNode && !HasObjects( *pAktTxtNd ) )
+                {
+                    bEmptyLine = TRUE;
+                    ULONG nOldCnt = pDoc->GetNodes().Count();
+                    DelEmptyLine();
+                    // wurde wiklich ein Node geloescht ?
+                    if( nOldCnt != pDoc->GetNodes().Count() )
+                        aNdIdx--;       // nicht den naechsten Absatz ueberspringen
+                }
+                eStat = READ_NEXT_PARA;
+            }
+            else
+                eStat = TST_ALPHA_LINE;
+            break;
+
+        case TST_ALPHA_LINE:
+            if( IsNoAlphaLine( *pAktTxtNd ))
+            {
+                // erkenne eine Tabellendefinition +---+---+
+                if( aFlags.bAFmtByInput && aFlags.bCreateTable && DoTable() )
+                {
+                    //JP 30.09.96: das DoTable() verlaesst sich auf das
+                    //              Pop und Move - Crsr nach dem AutoFormat!
+                    pEdShell->Pop( FALSE );
+                    *pEdShell->GetCrsr() = aDelPam;
+                    pEdShell->Push();
+
+                    eStat = IS_ENDE;
+                    break;
+                }
+
+                // dann teste mal auf 3 "---" oder "===". In dem Fall
+                // soll der vorherige Absatz unterstrichen und dieser
+                // geloescht werden!
+                if( !DoUnderline() && bReplaceStyles )
+                {
+                    SetColl( RES_POOLCOLL_STANDARD, TRUE );
+                    bEmptyLine = TRUE;
+                }
+                eStat = READ_NEXT_PARA;
+            }
+            else
+                eStat = GET_ALL_INFO;
+            break;
+
+        case GET_ALL_INFO:
+            {
+                if( pAktTxtNd->GetNumRule() )
+                {
+                    // in Numerierung nichts machen, zum naechsten
+                    bEmptyLine = FALSE;
+                    eStat = READ_NEXT_PARA;
+                    // loesche alle Blanks am Anfang/Ende
+                    // und alle mitten drin
+                    //JP 29.04.98: erstmal nur alle "mitten drin".
+                    DelMoreLinesBlanks( FALSE );
+                    break;
+                }
+
+                aFInfo.SetFrm( pAktTxtFrm );
+
+                // erstmal: wurden schon mal entsprechende Vorlagen
+                //          vergeben, so behalte die bei, gehe zum
+                //          naechsten Node.
+                USHORT nPoolId = pAktTxtNd->GetTxtColl()->GetPoolFmtId();
+                if( IsPoolUserFmt( nPoolId )
+                        ? !aFlags.bChgUserColl
+                        : ( RES_POOLCOLL_STANDARD != nPoolId &&
+                           ( !aFlags.bAFmtByInput ||
+                            (RES_POOLCOLL_TEXT_MOVE != nPoolId &&
+                             RES_POOLCOLL_TEXT != nPoolId )) ))
+                {
+                    eStat = HAS_FMTCOLL;
+                    break;
+                }
+
+                // teste auf Harte oder aus Vorlagen gesetzte LRSpaces
+                if( IsPoolUserFmt( nPoolId ) ||
+                    RES_POOLCOLL_STANDARD == nPoolId )
+                {
+                    short nSz;
+                    SvxLRSpaceItem* pLRSpace;
+                    if( SFX_ITEM_SET == pAktTxtNd->GetSwAttrSet().
+                        GetItemState( RES_LR_SPACE, TRUE,
+                                        (const SfxPoolItem**)&pLRSpace ) &&
+                        ( 0 != (nSz = pLRSpace->GetTxtFirstLineOfst()) ||
+                            0 != pLRSpace->GetTxtLeft() ) )
+                    {
+                        // Ausnahme: Numerierun/Aufzaehlung kann mit Einzug
+                        //      existieren!!
+                        if( IsEnumericChar( *pAktTxtNd ))
+                        {
+                            nLevel = CalcLevel( *pAktTxtNd, &nDigitLvl );
+                            if( nLevel >= MAXLEVEL )
+                                nLevel = MAXLEVEL-1;
+                            BuildEnum( nLevel, nDigitLvl );
+                            eStat = READ_NEXT_PARA;
+                            break;
+                        }
+
+
+                        // nie zusammenfassen, so belassen
+                        // (Opt. vielleicht als Ausnahmen nur Einzug)
+                        bMoreLines = TRUE;
+
+                        if( bReplaceStyles )
+                        {
+                            // dann setze doch eine unserer Vorlagen
+                            if( 0 < nSz )           // positiver 1. Zeileneinzug
+                                BuildIndent();
+                            else if( 0 > nSz )      // negativer 1. Zeileneinzug
+                                BuildNegIndent( aFInfo.GetLineStart() );
+                            else if( pLRSpace->GetTxtLeft() )   // ist ein Einzug
+                                BuildTextIndent();
+                        }
+                        eStat = READ_NEXT_PARA;
+                        break;
+                    }
+                }
+
+                nLevel = CalcLevel( *pAktTxtNd, &nDigitLvl );
+                bMoreLines = !IsOneLine( *pAktTxtNd );
+                pNxtNd = GetNextNode();
+                if( pNxtNd )
+                {
+                    bNxtEmpty = IsEmptyLine( *pNxtNd );
+                    bNxtAlpha = IsNoAlphaLine( *pNxtNd );
+                    nNxtLevel = CalcLevel( *pNxtNd );
+
+                    if( !bEmptyLine && HasBreakAttr( *pAktTxtNd ) )
+                        bEmptyLine = TRUE;
+                    if( !bNxtEmpty && HasBreakAttr( *pNxtNd ) )
+                        bNxtEmpty = TRUE;
+
+                    // fuer z.B. selbst definierte Einzuege oder
+                    // rechts/zentierte Ausrichtung
+//                  if( !nLevel && 0 != aFInfo.GetLineStart() )
+//                      nLevel = 1;
+                }
+                else
+                {
+                    bNxtEmpty = FALSE; // TRUE;
+                    bNxtAlpha = FALSE;
+                    nNxtLevel = 0;
+                }
+                eStat = !bMoreLines ? IS_ONE_LINE : TST_ENUMERIC;
+            }
+            break;
+
+        case IS_ONE_LINE:
+            {
+                eStat = TST_ENUMERIC;
+                if( !bReplaceStyles )
+                    break;
+
+                String sClrStr( aStr );
+
+                if( !DelLeadingBlanks( sClrStr ).Len() )
+                {
+                    bEmptyLine = TRUE;
+                    eStat = READ_NEXT_PARA;
+                    break;      // naechsten Absatz lesen
+                }
+
+                // Teste auf Ueberschrift
+                if( !bEmptyLine ||
+                    ((INTN_CHAR_UPPER | INTN_CHAR_ALPHA) != rInter.
+                        GetCharType( GetFirstChar( aStr ) )) ||
+                    IsBlanksInString( *pAktTxtNd ) )
+                    break;
+
+                bEmptyLine = FALSE;
+                String sEndClrStr( sClrStr );
+                xub_StrLen nLen = DelTrailingBlanks( sEndClrStr ).Len();
+
+                // nicht, dann teste auf Ueberschrift
+                if( ':' == sEndClrStr.GetChar( nLen - 1 ) )
+                {
+//---------------------------------------------------------------------------
+// Wie ist denn nun die Bedingung fuer die Ueberschrift auf Ebene 3 ??
+// Zur Zeit: generell wenn am Ende ein ':' ist.
+//
+//                  if( bNxtEmpty || bNxtAlpha )
+//                      !IsEnumericChar( *pNxtNd ) )
+//---------------------------------------------------------------------------
+                    {
+                        BuildHeadLine( 2 );
+                        eStat = READ_NEXT_PARA;
+                        break;
+                    }
+                }
+                else if( 256 <= sEndClrStr.GetChar( nLen-1 ) ||
+                         !strchr( ",.;", sEndClrStr.GetChar( nLen-1 )) )
+                {
+                    if( bNxtEmpty || bNxtAlpha
+                        || ( pNxtNd && IsEnumericChar( *pNxtNd ))
+
+//---------------------------------------------------------------------------
+// ist zum Verwechseln mit neg. Einzug !!
+                        /*|| nLevel < nNxtLevel*/
+//---------------------------------------------------------------------------
+
+                        )
+                    {
+                        // wurde Level vom Text vorgegeben ?
+//                      if( USHRT_MAX != nDigitLvl )
+//                          nLevel = nDigitLvl;
+
+                        // eine Ebene runter ?
+                        if( nLevel >= MAXLEVEL )
+                            nLevel = MAXLEVEL-1;
+
+                        if( USHRT_MAX == nLastHeadLvl )
+                            nLastHeadLvl = 0;
+                        else if( nLastCalcHeadLvl < nLevel )
+                        {
+                            if( nLastHeadLvl+1 < MAXLEVEL )
+                                ++nLastHeadLvl;
+                        }
+                        // eine Ebene hoch ?
+                        else if( nLastCalcHeadLvl > nLevel )
+                        {
+                            if( nLastHeadLvl )
+                                --nLastHeadLvl;
+                        }
+                        nLastCalcHeadLvl = nLevel;
+
+                        if( aFlags.bAFmtByInput )
+                            BuildHeadLine( nLevel );
+                        else
+                            BuildHeadLine( nLastHeadLvl );
+                        eStat = READ_NEXT_PARA;
+                        break;
+                    }
+                }
+            }
+            break;
+
+        case TST_ENUMERIC:
+            {
+                bEmptyLine = FALSE;
+                if( IsEnumericChar( *pAktTxtNd ))
+                {
+                    if( nLevel >= MAXLEVEL )
+                        nLevel = MAXLEVEL-1;
+                    BuildEnum( nLevel, nDigitLvl );
+                    eStat = READ_NEXT_PARA;
+                }
+//JP 25.03.96: Vorlagen fuer Einzug zulassen
+//              else if( aFlags.bAFmtByInput )
+//                  eStat = READ_NEXT_PARA;
+                else if( bReplaceStyles )
+                    eStat = nLevel ? TST_IDENT : TST_NEG_IDENT;
+                else
+                    eStat = READ_NEXT_PARA;
+            }
+            break;
+
+        case TST_IDENT:
+            // Spaces am Anfang, dann teste doch mal auf Einzuege
+            if( bMoreLines && nLevel )
+            {
+                SwTwips nSz = aFInfo.GetFirstIndent();
+                if( 0 < nSz )           // positiver 1. Zeileneinzug
+                    BuildIndent();
+                else if( 0 > nSz )      // negativer 1. Zeileneinzug
+                    BuildNegIndent( aFInfo.GetLineStart() );
+                else                    // ist ein Einzug
+                    BuildTextIndent();
+                eStat = READ_NEXT_PARA;
+            }
+            else if( nLevel && pNxtNd && !bEnde &&
+                     !bNxtEmpty && !bNxtAlpha && !nNxtLevel &&
+                     !IsEnumericChar( *pNxtNd ) )
+            {
+                // ist ein Einzug
+                BuildIndent();
+                eStat = READ_NEXT_PARA;
+            }
+            else
+                eStat = TST_TXT_BODY;
+            break;
+
+        case TST_NEG_IDENT:
+            // keine Spaces am Anfang, dann teste doch mal auf neg. Einzuege
+            {
+                if( bMoreLines && !nLevel )
+                {
+                    SwTwips nSz = aFInfo.GetFirstIndent();
+                    if( 0 < nSz )           // positiver 1. Zeileneinzug
+                        BuildIndent();
+                    else if( 0 > nSz )      // negativer 1. Zeileneinzug
+                        BuildNegIndent( aFInfo.GetLineStart() );
+                    else                    // ist ein kein Einzug
+                        BuildText();
+                    eStat = READ_NEXT_PARA;
+                }
+                else if( !nLevel && pNxtNd && !bEnde &&
+                         !bNxtEmpty && !bNxtAlpha && nNxtLevel &&
+                         !IsEnumericChar( *pNxtNd ) )
+                {
+                    // ist ein neg. Einzug
+                    BuildNegIndent( aFInfo.GetLineStart() );
+                    eStat = READ_NEXT_PARA;
+                }
+                else
+                    eStat = TST_TXT_BODY;
+            }
+            break;
+
+        case TST_TXT_BODY:
+            {
+                if( bMoreLines )
+                {
+                    SwTwips nSz = aFInfo.GetFirstIndent();
+                    if( 0 < nSz )           // positiver 1. Zeileneinzug
+                        BuildIndent();
+                    else if( 0 > nSz )      // negativer 1. Zeileneinzug
+                        BuildNegIndent( aFInfo.GetLineStart() );
+                    else if( nLevel )       // ist ein Einzug
+                        BuildTextIndent();
+                    else
+                        BuildText();
+                }
+                else if( nLevel )
+                    BuildTextIndent();
+                else
+                    BuildText();
+                eStat = READ_NEXT_PARA;
+            }
+            break;
+
+        case HAS_FMTCOLL:
+            {
+                // erstmal: wurden schon mal entsprechende Vorlagen
+                //          vergeben, so behalte die bei, gehe zum
+                //          naechsten Node.
+                bEmptyLine = FALSE;
+                eStat = READ_NEXT_PARA;
+                // loesche alle Blanks am Anfang/Ende
+                // und alle mitten drin
+                //JP 29.04.98: erstmal nur alle "mitten drin".
+                DelMoreLinesBlanks( FALSE );
+
+                // behandel die harte Attributierung
+                if( pAktTxtNd->GetpSwAttrSet() )
+                {
+                    short nSz;
+                    SvxLRSpaceItem* pLRSpace;
+                    if( SFX_ITEM_SET == pAktTxtNd->GetpSwAttrSet()->
+                        GetItemState( RES_LR_SPACE, FALSE,
+                                        (const SfxPoolItem**)&pLRSpace ) &&
+                        ( 0 != (nSz = pLRSpace->GetTxtFirstLineOfst()) ||
+                            0 != pLRSpace->GetTxtLeft() ) )
+                    {
+                        // dann setze doch eine unserer Vorlagen
+                        if( 0 < nSz )           // positiver 1. Zeileneinzug
+                            BuildIndent();
+                        else if( 0 > nSz )      // negativer 1. Zeileneinzug
+                        {
+                            BuildNegIndent( aFInfo.GetLineStart() );
+                        }
+                        else if( pLRSpace->GetTxtLeft() )   // ist ein Einzug
+                            BuildTextIndent();
+                        else
+                            BuildText();
+                    }
+                }
+            }
+            break;
+
+        case IS_ENDE:
+            bEnde = TRUE;
+            break;
+        }
+    }
+
+    if( aFlags.bWithRedlining )
+        pDoc->SetAutoFmtRedline( FALSE );
+    pDoc->SetRedlineMode( eOldMode );
+
+    // Prozent-Anzeige wieder abschalten
+    if( !aFlags.bAFmtByInput )
+        ::EndProgress( pDoc->GetDocShell() );
+}
+
+void SwEditShell::AutoFormat( const SvxSwAutoFmtFlags* pAFlags )
+{
+    SwWait* pWait = 0;
+
+    SET_CURR_SHELL( this );
+    StartAllAction();
+    StartUndo( UNDO_AUTOFORMAT );
+
+    SvxSwAutoFmtFlags aAFFlags;     // erst mal default - Werte
+    if( pAFlags )                   // oder doch angegeben ??
+    {
+        aAFFlags = *pAFlags;
+        if( !aAFFlags.bAFmtByInput )
+            pWait = new SwWait( *GetDoc()->GetDocShell(), TRUE );
+    }
+
+    SwPaM* pCrsr = GetCrsr();
+    // es gibt mehr als einen oder ist eine Selektion offen
+    if( pCrsr->GetNext() != pCrsr || pCrsr->HasMark() )
+    {
+        FOREACHPAM_START(this)
+            if( PCURCRSR->HasMark() )
+            {
+                SwAutoFormat aFmt( this, aAFFlags, &PCURCRSR->Start()->nNode,
+                                     &PCURCRSR->End()->nNode );
+            }
+        FOREACHPAM_END()
+    }
+    else
+    {
+        SwAutoFormat aFmt( this, aAFFlags );
+    }
+
+    EndUndo( UNDO_AUTOFORMAT );
+    EndAllAction();
+
+    delete pWait;
+}
+
+
+void SwEditShell::AutoFmtBySplitNode()
+{
+    SET_CURR_SHELL( this );
+    SwPaM* pCrsr = GetCrsr();
+    if( pCrsr->GetNext() == pCrsr && pCrsr->Move( fnMoveBackward, fnGoNode ) )
+    {
+        StartAllAction();
+        StartUndo( UNDO_AUTOFORMAT );
+
+        BOOL bRange = FALSE;
+        pCrsr->SetMark();
+        SwIndex* pCntnt = &pCrsr->GetMark()->nContent;
+        if( pCntnt->GetIndex() )
+        {
+            *pCntnt = 0;
+            bRange = TRUE;
+        }
+        else
+        {
+            // dann einen Node zurueckspringen
+            SwNodeIndex aNdIdx( pCrsr->GetMark()->nNode, -1 );
+            SwTxtNode* pTxtNd = aNdIdx.GetNode().GetTxtNode();
+            if( pTxtNd && pTxtNd->GetTxt().Len() )
+            {
+                pCntnt->Assign( pTxtNd, 0 );
+                pCrsr->GetMark()->nNode = aNdIdx;
+                bRange = TRUE;
+            }
+        }
+
+        if( bRange )
+        {
+            Push();     // Cursor sichern
+
+            SvxSwAutoFmtFlags aAFFlags = *GetAutoFmtFlags();        // erst mal default - Werte
+
+            SwAutoFormat aFmt( this, aAFFlags, &pCrsr->GetMark()->nNode,
+                                    &pCrsr->GetPoint()->nNode );
+
+            //JP 30.09.96: das DoTable() verlaesst sich auf das PopCrsr
+            //              und MoveCrsr!
+            Pop( FALSE );
+            pCrsr = GetCrsr();
+        }
+        pCrsr->DeleteMark();
+        pCrsr->Move( fnMoveForward, fnGoNode );
+
+        EndUndo( UNDO_AUTOFORMAT );
+        EndAllAction();
+    }
+}
+
+SvxSwAutoFmtFlags* SwEditShell::GetAutoFmtFlags()
+{
+    if (!pAutoFmtFlags)
+        pAutoFmtFlags = new SvxSwAutoFmtFlags;
+
+    return pAutoFmtFlags;
+}
+
+void SwEditShell::SetAutoFmtFlags(SvxSwAutoFmtFlags * pFlags)
+{
+    SvxSwAutoFmtFlags* pEditFlags = GetAutoFmtFlags();
+
+    pEditFlags->bSetNumRule     = pFlags->bSetNumRule;
+    pEditFlags->bChgEnumNum     = pFlags->bChgEnumNum;
+    pEditFlags->bSetBorder      = pFlags->bSetBorder;
+    pEditFlags->bCreateTable    = pFlags->bCreateTable;
+    pEditFlags->bReplaceStyles  = pFlags->bReplaceStyles;
+    pEditFlags->bAFmtByInpDelSpacesAtSttEnd =
+                                    pFlags->bAFmtByInpDelSpacesAtSttEnd;
+    pEditFlags->bAFmtByInpDelSpacesBetweenLines =
+                                    pFlags->bAFmtByInpDelSpacesBetweenLines;
+
+    //JP 15.12.98: BulletZeichen und Font in die "normalen" kopieren,
+    //          weil beim Autoformat nur mit diesen gearbeitet wird!
+    pEditFlags->cBullet             = pFlags->cByInputBullet;
+    pEditFlags->aBulletFont         = pFlags->aByInputBulletFont;
+    pEditFlags->cByInputBullet      = pFlags->cByInputBullet;
+    pEditFlags->aByInputBulletFont  = pFlags->aByInputBulletFont;
+}
+
diff --git a/sw/source/core/edit/edatmisc.cxx b/sw/source/core/edit/edatmisc.cxx
new file mode 100644
index 000000000000..7eaacda5a8cd
--- /dev/null
+++ b/sw/source/core/edit/edatmisc.cxx
@@ -0,0 +1,234 @@
+/*************************************************************************
+ *
+ *  $RCSfile: edatmisc.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:18 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _EDITSH_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include       // fuer aNodes
+#endif
+#ifndef _PAM_HXX
+#include       // fuer SwPaM
+#endif
+#ifndef _EDIMP_HXX
+#include     // fuer MACROS
+#endif
+#ifndef _SWUNDO_HXX
+#include    // fuer die UndoIds
+#endif
+#ifndef _NDTXT_HXX
+#include     // fuer Get-/ChgFmt Set-/GetAttrXXX
+#endif
+
+
+
+/*************************************
+ * harte Formatierung (Attribute)
+ *************************************/
+
+
+void SwEditShell::ResetAttr()
+{
+    SET_CURR_SHELL( this );
+    StartAllAction();
+    BOOL bUndoGroup = GetCrsr()->GetNext() != GetCrsr();
+    if( bUndoGroup )
+        GetDoc()->StartUndo(UNDO_RESETATTR);
+
+        FOREACHPAM_START(this)
+            // if ( PCURCRSR->HasMark() )
+                GetDoc()->ResetAttr(*PCURCRSR);
+        FOREACHPAM_END()
+
+    if( bUndoGroup )
+        GetDoc()->EndUndo(UNDO_RESETATTR);
+
+    EndAllAction();
+
+}
+
+
+
+void SwEditShell::GCAttr()
+{
+//JP 04.02.97: wozu eine Action-Klammerung - ein Formatierung sollte nicht
+//              ausgeloest werden, so dass es hier ueberfluessig ist.
+//              Sonst Probleme im MouseBut.DownHdl - Bug 35562
+//  StartAllAction();
+    FOREACHPAM_START(this)
+        SwTxtNode *pTxtNode;
+        if ( !PCURCRSR->HasMark() )
+        {
+            if( 0 != (pTxtNode = GetDoc()->GetNodes()[
+                                PCURCRSR->GetPoint()->nNode]->GetTxtNode()))
+                pTxtNode->GCAttr();
+        }
+        else
+        {
+            const SwNodeIndex& rEnd = PCURCRSR->End()->nNode;
+            SwNodeIndex aIdx( PCURCRSR->Start()->nNode );
+            SwNode* pNd = &aIdx.GetNode();
+            do {
+                if( pNd->IsTxtNode() )
+                    ((SwTxtNode*)pNd)->GCAttr();
+            }
+            while( 0 != ( pNd = GetDoc()->GetNodes().GoNext( &aIdx )) &&
+                    aIdx <= rEnd );
+        }
+    FOREACHPAM_END()
+//  EndAllAction();
+}
+
+// Setze das Attribut als neues default Attribut im Dokument.
+
+
+void SwEditShell::SetDefault( const SfxPoolItem& rFmtHint )
+{
+    // 7502: Action-Klammerung
+    StartAllAction();
+    GetDoc()->SetDefault( rFmtHint );
+    EndAllAction();
+}
+
+/*
+
+void SwEditShell::SetDefault( const SfxItemSet& rSet )
+{
+    // 7502: Action-Klammerung
+    StartAllAction();
+    GetDoc()->SetDefault( rSet );
+    EndAllAction();
+}
+*/
+
+// Erfrage das Default Attribut in diesem Dokument.
+
+const SfxPoolItem& SwEditShell::GetDefault( USHORT nFmtHint ) const
+{
+    return GetDoc()->GetDefault( nFmtHint );
+
+}
+
+
+void SwEditShell::SetAttr( const SfxPoolItem& rHint, USHORT nFlags )
+{
+    SET_CURR_SHELL( this );
+    StartAllAction();
+    SwPaM* pCrsr = GetCrsr();
+    if( pCrsr->GetNext() != pCrsr )     // Ring von Cursorn
+    {
+        FASTBOOL bIsTblMode = IsTableMode();
+        GetDoc()->StartUndo(UNDO_INSATTR);
+
+        FOREACHPAM_START(this)
+            if( PCURCRSR->HasMark() && ( bIsTblMode ||
+                *PCURCRSR->GetPoint() != *PCURCRSR->GetMark() ))
+                GetDoc()->Insert(*PCURCRSR, rHint, nFlags );
+        FOREACHPAM_END()
+
+        GetDoc()->EndUndo(UNDO_INSATTR);
+    }
+    else
+    {
+        if( !HasSelection() )
+            UpdateAttr();
+        GetDoc()->Insert( *pCrsr, rHint, nFlags );
+    }
+    EndAllAction();
+}
+
+
+void SwEditShell::SetAttr( const SfxItemSet& rSet, USHORT nFlags )
+{
+    SET_CURR_SHELL( this );
+    StartAllAction();
+    SwPaM* pCrsr = GetCrsr();
+    if( pCrsr->GetNext() != pCrsr )     // Ring von Cursorn
+    {
+        FASTBOOL bIsTblMode = IsTableMode();
+        GetDoc()->StartUndo(UNDO_INSATTR);
+
+        FOREACHPAM_START(this)
+            if( PCURCRSR->HasMark() && ( bIsTblMode ||
+                *PCURCRSR->GetPoint() != *PCURCRSR->GetMark() ))
+                GetDoc()->Insert(*PCURCRSR, rSet, nFlags );
+        FOREACHPAM_END()
+
+        GetDoc()->EndUndo(UNDO_INSATTR);
+    }
+    else
+    {
+        if( !HasSelection() )
+            UpdateAttr();
+        GetDoc()->Insert( *pCrsr, rSet, nFlags );
+    }
+    EndAllAction();
+}
+
+
+
+
diff --git a/sw/source/core/edit/edattr.cxx b/sw/source/core/edit/edattr.cxx
new file mode 100644
index 000000000000..19b8cc6fcea0
--- /dev/null
+++ b/sw/source/core/edit/edattr.cxx
@@ -0,0 +1,444 @@
+/*************************************************************************
+ *
+ *  $RCSfile: edattr.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:18 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _SVX_TSTPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _TXATBASE_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFTN_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFTN_HXX //autogen
+#include 
+#endif
+#ifndef _EDITSH_HXX
+#include 
+#endif
+#ifndef _EDIMP_HXX
+#include     // fuer MACROS
+#endif
+#ifndef _SWUNDO_HXX
+#include    // fuer UNDO-Ids
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _FTNIDX_HXX
+#include 
+#endif
+#ifndef _EXPFLD_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _ROOTFRM_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _CNTFRM_HXX
+#include 
+#endif
+
+
+/*************************************
+ * harte Formatierung (Attribute)
+ *************************************/
+
+// wenn Selektion groesser Max Nodes oder mehr als Max Selektionen
+// => keine Attribute
+static const USHORT nMaxLookup = 255;
+
+BOOL SwEditShell::GetAttr( SfxItemSet& rSet ) const
+{
+    if( GetCrsrCnt() > nMaxLookup )
+    {
+        rSet.InvalidateAllItems();
+        return FALSE;
+    }
+
+    SfxItemSet aSet( *rSet.GetPool(), rSet.GetRanges() );
+    SfxItemSet *pSet = &rSet;
+
+    FOREACHPAM_START(this)
+
+        ULONG nSttNd = PCURCRSR->GetMark()->nNode.GetIndex(),
+              nEndNd = PCURCRSR->GetPoint()->nNode.GetIndex();
+        xub_StrLen nSttCnt = PCURCRSR->GetMark()->nContent.GetIndex(),
+                   nEndCnt = PCURCRSR->GetPoint()->nContent.GetIndex();
+
+        if( nSttNd > nEndNd || ( nSttNd == nEndNd && nSttCnt > nEndCnt ))
+        {
+            ULONG nTmp = nSttNd; nSttNd = nEndNd; nEndNd = nTmp;
+            nTmp = nSttCnt; nSttCnt = nEndCnt; nEndCnt = (xub_StrLen)nTmp;
+        }
+
+        if( nEndNd - nSttNd >= nMaxLookup )
+        {
+            rSet.ClearItem();
+            rSet.InvalidateAllItems();
+            return FALSE;
+        }
+
+        // beim 1.Node traegt der Node die Werte in den GetSet ein (Initial)
+        // alle weiteren Nodes werden zum GetSet zu gemergt
+        for( ULONG n = nSttNd; n <= nEndNd; ++n )
+        {
+            SwNode* pNd = GetDoc()->GetNodes()[ n ];
+            switch( pNd->GetNodeType() )
+            {
+            case ND_TEXTNODE:
+                {
+                    xub_StrLen nStt = n == nSttNd ? nSttCnt : 0,
+                                  nEnd = n == nEndNd ? nEndCnt
+                                        : ((SwTxtNode*)pNd)->GetTxt().Len();
+                    ((SwTxtNode*)pNd)->GetAttr( *pSet, nStt, nEnd );
+                }
+                break;
+            case ND_GRFNODE:
+            case ND_OLENODE:
+                ((SwCntntNode*)pNd)->GetAttr( *pSet );
+                break;
+
+            default:
+                pNd = 0;
+            }
+
+            if( pNd )
+            {
+                if( pSet != &rSet )
+                    rSet.MergeValues( aSet );
+
+                if( aSet.Count() )
+                    aSet.ClearItem();
+
+#ifdef JP_NEWCORE
+            // vieleicht sollte man hier noch erfragen, ob schon alle Attribute
+            // "DontCare" sind. Dann kann man abbrechen!
+#endif
+            }
+            pSet = &aSet;
+        }
+
+    FOREACHPAM_END()
+
+    return TRUE;
+}
+
+
+BOOL lcl_GetFmtColl( const SwNodePtr& rpNd, void* pArgs )
+{
+    if( rpNd->IsTxtNode() )
+    {
+        SwFmtColl** ppColl = (SwFmtColl**)pArgs;
+        if( !*ppColl )
+            *ppColl = ((SwTxtNode*)rpNd)->GetTxtColl();
+        else if( *ppColl == ((SwTxtNode*)rpNd)->GetTxtColl() )
+            return FALSE;
+    }
+    return TRUE;
+}
+
+
+SwTxtFmtColl* SwEditShell::GetCurTxtFmtColl() const
+{
+    SwTxtFmtColl *pFmt = 0;
+
+    if ( GetCrsrCnt() > nMaxLookup )
+        return 0;
+
+    FOREACHPAM_START(this)
+
+        ULONG nSttNd = PCURCRSR->GetMark()->nNode.GetIndex(),
+              nEndNd = PCURCRSR->GetPoint()->nNode.GetIndex();
+        xub_StrLen nSttCnt = PCURCRSR->GetMark()->nContent.GetIndex(),
+                   nEndCnt = PCURCRSR->GetPoint()->nContent.GetIndex();
+
+        if( nSttNd > nEndNd || ( nSttNd == nEndNd && nSttCnt > nEndCnt ))
+        {
+            ULONG nTmp = nSttNd; nSttNd = nEndNd; nEndNd = nTmp;
+            nTmp = nSttCnt; nSttCnt = nEndCnt; nEndCnt = (xub_StrLen)nTmp;
+        }
+
+        if( nEndNd - nSttNd >= nMaxLookup )
+        {
+            pFmt = 0;
+            break;
+        }
+
+        for( ULONG n = nSttNd; n <= nEndNd; ++n )
+        {
+            SwNode* pNd = GetDoc()->GetNodes()[ n ];
+            if( pNd->IsTxtNode() )
+            {
+                if( !pFmt )
+                    pFmt = ((SwTxtNode*)pNd)->GetTxtColl();
+                else if( pFmt == ((SwTxtNode*)pNd)->GetTxtColl() ) // ???
+                    break;
+            }
+        }
+
+    FOREACHPAM_END()
+    return pFmt;
+}
+
+
+
+BOOL SwEditShell::GetCurFtn( SwFmtFtn* pFillFtn )
+{
+    // der Cursor muss auf dem akt. Fussnoten-Anker stehen:
+    SwPaM* pCrsr = GetCrsr();
+    SwTxtNode* pTxtNd = pCrsr->GetNode()->GetTxtNode();
+    if( !pTxtNd )
+        return FALSE;
+
+    SwTxtAttr *pFtn = pTxtNd->GetTxtAttr( pCrsr->GetPoint()->nContent,
+                                            RES_TXTATR_FTN );
+    if( pFtn && pFillFtn )
+    {
+        // Daten vom Attribut uebertragen
+        const SwFmtFtn &rFtn = ((SwTxtFtn*)pFtn)->GetFtn();
+        pFillFtn->SetNumber( rFtn );
+        pFillFtn->SetEndNote( rFtn.IsEndNote() );
+    }
+    return 0 != pFtn;
+}
+
+
+BOOL SwEditShell::SetCurFtn( const SwFmtFtn& rFillFtn )
+{
+    BOOL bChgd = FALSE;
+    StartAllAction();
+
+    SwPaM* pCrsr = GetCrsr(), *pFirst = pCrsr;
+    do {
+        bChgd |=  pDoc->SetCurFtn( *pCrsr, rFillFtn.GetNumStr(),
+                                            rFillFtn.GetNumber(),
+                                            rFillFtn.IsEndNote() );
+
+    } while( pFirst != ( pCrsr = (SwPaM*)pCrsr->GetNext() ));
+
+    EndAllAction();
+    return bChgd;
+}
+
+
+
+/*USHORT SwEditShell::GetFtnCnt( BOOL bEndNotes = FALSE ) const
+{
+    const SwFtnIdxs &rIdxs = pDoc->GetFtnIdxs();
+    USHORT nCnt = 0;
+    for ( USHORT i = 0; i < rIdxs.Count(); ++i )
+    {
+        const SwFmtFtn &rFtn = rIdxs[i]->GetFtn();
+        if ( bEndNotes == rFtn.IsEndNote() )
+            nCnt++;
+    }
+    return nCnt;
+} */
+
+
+BOOL SwEditShell::HasFtns( BOOL bEndNotes ) const
+{
+    const SwFtnIdxs &rIdxs = pDoc->GetFtnIdxs();
+    for ( USHORT i = 0; i < rIdxs.Count(); ++i )
+    {
+        const SwFmtFtn &rFtn = rIdxs[i]->GetFtn();
+        if ( bEndNotes == rFtn.IsEndNote() )
+            return TRUE;
+    }
+    return FALSE;
+}
+
+
+    // gebe Liste aller Fussnoten und deren Anfangstexte
+USHORT SwEditShell::GetSeqFtnList( SwSeqFldList& rList, BOOL bEndNotes )
+{
+    if( rList.Count() )
+        rList.Remove( 0, rList.Count() );
+
+    USHORT n, nFtnCnt = pDoc->GetFtnIdxs().Count();
+    SwTxtFtn* pTxtFtn;
+    for( n = 0; n < nFtnCnt; ++n )
+    {
+        pTxtFtn = pDoc->GetFtnIdxs()[ n ];
+        const SwFmtFtn& rFtn = pTxtFtn->GetFtn();
+        if ( rFtn.IsEndNote() != bEndNotes )
+            continue;
+
+        SwNodeIndex* pIdx = pTxtFtn->GetStartNode();
+        if( pIdx )
+        {
+            SwNodeIndex aIdx( *pIdx, 1 );
+            SwTxtNode* pTxtNd = aIdx.GetNode().GetTxtNode();
+            if( !pTxtNd )
+                pTxtNd = (SwTxtNode*)pDoc->GetNodes().GoNext( &aIdx );
+
+            if( pTxtNd )
+            {
+                String sTxt( rFtn.GetViewNumStr( *pDoc ));
+                if( sTxt.Len() )
+                    sTxt += ' ';
+                sTxt += pTxtNd->GetExpandTxt( 0, USHRT_MAX, FALSE );
+
+                _SeqFldLstElem* pNew = new _SeqFldLstElem( sTxt,
+                                            pTxtFtn->GetSeqRefNo() );
+                while( rList.InsertSort( pNew ) )
+                    pNew->sDlgEntry += ' ';
+            }
+        }
+    }
+
+    return rList.Count();
+}
+
+
+// linken Rand ueber Objectleiste einstellen (aenhlich dem Stufen von
+// Numerierungen)
+BOOL SwEditShell::IsMoveLeftMargin( BOOL bRight, BOOL bModulus ) const
+{
+    BOOL bRet = TRUE;
+
+    const SvxTabStopItem& rTabItem = (SvxTabStopItem&)GetDoc()->
+                                GetDefault( RES_PARATR_TABSTOP );
+    USHORT nDefDist = rTabItem.Count() ? rTabItem[0].GetTabPos() : 1134;
+    if( !nDefDist )
+        return FALSE;
+
+    FOREACHPAM_START(this)
+
+        ULONG nSttNd = PCURCRSR->GetMark()->nNode.GetIndex(),
+              nEndNd = PCURCRSR->GetPoint()->nNode.GetIndex();
+
+        if( nSttNd > nEndNd )
+        {
+            ULONG nTmp = nSttNd; nSttNd = nEndNd; nEndNd = nTmp;
+        }
+
+        SwCntntNode* pCNd;
+        for( ULONG n = nSttNd; bRet && n <= nEndNd; ++n )
+            if( 0 != ( pCNd = GetDoc()->GetNodes()[ n ]->GetTxtNode() ))
+            {
+                const SvxLRSpaceItem& rLS = (SvxLRSpaceItem&)
+                                            pCNd->GetAttr( RES_LR_SPACE );
+                if( bRight )
+                {
+                    USHORT nNext = rLS.GetTxtLeft() + nDefDist;
+                    if( bModulus )
+                        nNext = ( nNext / nDefDist ) * nDefDist;
+                    SwFrm* pFrm = pCNd->GetFrm();
+                    bRet = pFrm && pFrm->Frm().Width() > ( nNext + MM50 );
+                }
+                else if( bModulus )
+                    bRet = 0 != rLS.GetLeft();
+                else
+                    bRet = nDefDist <= rLS.GetLeft();
+            }
+
+        if( !bRet )
+            break;
+
+    FOREACHPAM_END()
+    return bRet;
+}
+
+
+void SwEditShell::MoveLeftMargin( BOOL bRight, BOOL bModulus )
+{
+    StartAllAction();
+    StartUndo( UNDO_START );
+
+    SwPaM* pCrsr = GetCrsr();
+    if( pCrsr->GetNext() != pCrsr )         // Mehrfachselektion ?
+    {
+        SwPamRanges aRangeArr( *pCrsr );
+        SwPaM aPam( *pCrsr->GetPoint() );
+        for( USHORT n = 0; n < aRangeArr.Count(); ++n )
+            GetDoc()->MoveLeftMargin( aRangeArr.SetPam( n, aPam ),
+                                        bRight, bModulus );
+    }
+    else
+        GetDoc()->MoveLeftMargin( *pCrsr, bRight, bModulus );
+
+    EndUndo( UNDO_END );
+    EndAllAction();
+}
+
+
+
diff --git a/sw/source/core/edit/eddel.cxx b/sw/source/core/edit/eddel.cxx
new file mode 100644
index 000000000000..de94d80169b3
--- /dev/null
+++ b/sw/source/core/edit/eddel.cxx
@@ -0,0 +1,466 @@
+/*************************************************************************
+ *
+ *  $RCSfile: eddel.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:18 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _EDITSH_HXX
+#include 
+#endif
+#ifndef _CNTFRM_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include        // fuer die UndoIds
+#endif
+#ifndef _EDIMP_HXX
+#include 
+#endif
+#ifndef _BOOKMRK_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+
+
+/************************************************************
+ * Loeschen
+ ************************************************************/
+
+void SwEditShell::DeleteSel( SwPaM& rPam, BOOL* pUndo )
+{
+    // nur bei Selektion
+    if( !rPam.HasMark() || *rPam.GetPoint() == *rPam.GetMark())
+        return;
+
+    // besteht eine Selection in einer Tabelle ?
+    // dann nur den Inhalt der selektierten Boxen loeschen
+    // jetzt gibt es 2 Faelle die beachtet werden muessen:
+    //  1. Point und Mark stehen in einer Box, Selection normal loeschen
+    //  2. Point und Mark stehen in unterschiedlichen Boxen, alle
+    // selektierten Boxen suchen in den Inhalt loeschen
+    if( rPam.GetNode()->FindTableNode() &&
+        rPam.GetNode()->StartOfSectionNode() !=
+        rPam.GetNode(FALSE)->StartOfSectionNode() )
+    {
+        // in Tabellen das Undo gruppieren
+        if( pUndo && !*pUndo )
+        {
+            GetDoc()->StartUndo( UNDO_START );
+            *pUndo = TRUE;
+        }
+        SwPaM aDelPam( *rPam.Start() );
+        const SwPosition* pEndSelPos = rPam.End();
+        do {
+            aDelPam.SetMark();
+            SwNode* pNd = aDelPam.GetNode();
+            const SwNode& rEndNd = *pNd->EndOfSectionNode();
+            if( pEndSelPos->nNode.GetIndex() <= rEndNd.GetIndex() )
+            {
+                *aDelPam.GetPoint() = *pEndSelPos;
+                pEndSelPos = 0;     // Pointer als Flag missbrauchen
+            }
+            else
+            {
+                // dann ans Ende der Section
+                aDelPam.GetPoint()->nNode = rEndNd;
+                aDelPam.Move( fnMoveBackward, fnGoCntnt );
+            }
+                // geschuetze Boxen ueberspringen !
+            if( !pNd->IsCntntNode() ||
+                !((SwCntntNode*)pNd)->GetFrm()->IsProtected() )
+            {
+                // alles loeschen
+                GetDoc()->DeleteAndJoin( aDelPam );
+                SaveTblBoxCntnt( aDelPam.GetPoint() );
+            }
+
+            if( !pEndSelPos )               // am Ende der Selection
+                break;
+            aDelPam.DeleteMark();
+            aDelPam.Move( fnMoveForward, fnGoCntnt );   // naechste Box
+        } while( pEndSelPos );
+    }
+    else
+    {
+            // alles loeschen
+        GetDoc()->DeleteAndJoin( rPam );
+        SaveTblBoxCntnt( rPam.GetPoint() );
+    }
+
+    // Selection wird nicht mehr benoetigt.
+    rPam.DeleteMark();
+}
+
+
+long SwEditShell::Delete()
+{
+    SET_CURR_SHELL( this );
+    long nRet = 0;
+    if( !HasReadonlySel() )
+    {
+        StartAllAction();
+
+        BOOL bUndo = GetCrsr()->GetNext() != GetCrsr();
+        if( bUndo )     // mehr als eine Selection ?
+            GetDoc()->StartUndo( UNDO_START );
+
+        FOREACHPAM_START(this)
+            DeleteSel( *PCURCRSR, &bUndo );
+        FOREACHPAM_END()
+
+        // falls eine Undo-Klammerung, dann hier beenden
+        if( bUndo )
+            GetDoc()->EndUndo( UNDO_END );
+        EndAllAction();
+        nRet = 1;
+    }
+    return nRet;
+}
+
+
+
+long SwEditShell::Move()
+{
+    SET_CURR_SHELL( this );
+
+    long nRet = 0;
+    if( !HasReadonlySel() )
+    {
+        StartAllAction();
+        SwPosition * pPos = 0;
+        BOOL bFirstMove = TRUE;
+
+        String sBookmark( String::CreateFromAscii("Move") );
+        GetDoc()->MakeUniqueBookmarkName( sBookmark );
+
+        BOOL bUndo = GetDoc()->DoesUndo();
+
+        GetDoc()->StartUndo( UNDO_START );
+
+        FOREACHPAM_START(this)
+
+            if( !pPos )
+            {
+                // der 1.Cursor ist die Position, wohin verschoben wird !!
+                PCURCRSR->DeleteMark();
+                pPos = (SwPosition*)PCURCRSR->GetPoint();
+            }
+            // nur bei Selektion (nicht Textnodes haben Selection,
+            // aber Point/GetMark sind gleich
+            else if( PCURCRSR->HasMark() &&
+                    *PCURCRSR->GetPoint() != *PCURCRSR->GetMark() &&
+                    GetDoc()->MoveAndJoin( *PCURCRSR, *pPos ))
+            {
+                nRet = 1;
+                if( bFirstMove )
+                {
+                    // Anfangs-Position vom neuen Bereich merken
+                    bFirstMove = FALSE;
+                    GetDoc()->DoUndo( FALSE );
+                    GetDoc()->MakeBookmark( *PCURCRSR, KeyCode(), sBookmark,
+                                            aEmptyStr, MARK );
+                    GetDoc()->DoUndo( bUndo );
+                }
+            }
+
+        FOREACHPAM_END()
+
+        KillPams();
+
+        // wurde ueberhaupt etwas verschoben ?
+        if( !bFirstMove )
+        {
+            USHORT nFndPos = GetDoc()->FindBookmark( sBookmark );
+            const SwBookmark& rBkmk = *GetDoc()->GetBookmarks()[ nFndPos ];
+
+            SwPaM* pCrsr = GetCrsr();
+            pCrsr->SetMark();
+            *pCrsr->GetMark() = rBkmk.GetPos();
+
+            GetDoc()->DoUndo( FALSE );
+            GetDoc()->DelBookmark( nFndPos );
+            GetDoc()->DoUndo( bUndo );
+        }
+
+#ifdef DEBUG
+// pruefe ob die Indizies auch in den richtigen Nodes angemeldet sind
+{
+    SwPaM* pCmp = GetCrsr();        // sicher den Pointer auf Cursor
+    do {
+        ASSERT( pCmp->GetPoint()->nContent.GetIdxReg()
+                    == pCmp->GetCntntNode(), "Point im falschen Node" );
+        ASSERT( pCmp->GetMark()->nContent.GetIdxReg()
+                    == pCmp->GetCntntNode(FALSE), "Mark im falschen Node" );
+        BOOL bTst = *pCmp->GetPoint() == *pCmp->GetMark();
+    } while( GetCrsr() != ( pCmp = (SwPaM*)pCmp->GetNext() ) );
+}
+#endif
+
+        // Undo-Klammerung hier beenden
+        GetDoc()->EndUndo( UNDO_END );
+        EndAllAction();
+    }
+    return nRet;
+    // falls eine Bitmap nicht verschoben werden konnte so melde das an
+    // die SwWriterShell weiter
+}
+
+
+
+long SwEditShell::Copy( SwEditShell* pDestShell )
+{
+    if( !pDestShell )
+        pDestShell = this;
+
+    SET_CURR_SHELL( pDestShell );
+
+    // ueberpruefe ob Selectionen in sich selbst kopiert werden
+    if( pDestShell->GetDoc() == GetDoc() )
+    {
+        SwPosition * pPos = 0;
+        FOREACHPAM_START(this)
+
+            if( !pPos )
+            {
+                if( pDestShell == this )
+                {
+                    // der 1.Cursor ist die Position, wohin verschoben wird !!
+                    PCURCRSR->DeleteMark();
+                    pPos = (SwPosition*)PCURCRSR->GetPoint();
+                    continue;
+                }
+                else
+                    pPos = pDestShell->GetCrsr()->GetPoint();
+            }
+            if( *PCURCRSR->Start() <= *pPos && *pPos < *PCURCRSR->End() )
+                return FALSE;       // Position im Bereich einer Selection
+                                    // --> Kopieren in sich selbst
+        FOREACHPAM_END()
+    }
+
+    pDestShell->StartAllAction();
+    SwPosition * pPos = 0;
+    BOOL bRet = FALSE;
+    BOOL bFirstMove = TRUE;
+    SwNodeIndex aSttNdIdx( pDestShell->GetDoc()->GetNodes() );
+    xub_StrLen nSttCntIdx = 0;
+
+    pDestShell->GetDoc()->StartUndo( UNDO_START );
+    FOREACHPAM_START(this)
+
+        if( !pPos )
+        {
+            if( pDestShell == this )
+            {
+                // der 1.Cursor ist die Position, wohin verschoben wird !!
+                PCURCRSR->DeleteMark();
+                pPos = (SwPosition*)PCURCRSR->GetPoint();
+                continue;
+            }
+            else
+                pPos = pDestShell->GetCrsr()->GetPoint();
+        }
+
+        // nur bei Selektion (nicht Textnodes haben Selection,
+        // aber Point/GetMark sind gleich
+        if( !PCURCRSR->HasMark() || *PCURCRSR->GetPoint() == *PCURCRSR->GetMark())
+            continue;
+
+        if( bFirstMove )
+        {
+            // Anfangs-Position vom neuen Bereich merken
+            aSttNdIdx = pPos->nNode.GetIndex()-1;
+            nSttCntIdx = pPos->nContent.GetIndex();
+            bFirstMove = FALSE;
+        }
+
+        if( !GetDoc()->Copy( *PCURCRSR, *pPos ))
+            continue;
+
+        bRet = TRUE;
+    FOREACHPAM_END()
+
+
+    // wurde ueberhaupt etwas verschoben ?
+    if( !bFirstMove )
+    {
+        SwPaM* pCrsr = pDestShell->GetCrsr();
+        pCrsr->SetMark();
+        pCrsr->GetPoint()->nNode = aSttNdIdx.GetIndex()+1;
+        pCrsr->GetPoint()->nContent.Assign( pCrsr->GetCntntNode(),nSttCntIdx);
+        pCrsr->Exchange();
+    }
+    else
+    {
+        // falls beim Move der Cursor "gewandert" ist, so setze hier auch
+        // seinen GetMark um, damit dieser nie in den Wald zeigt.
+        pDestShell->GetCrsr()->SetMark();
+        pDestShell->GetCrsr()->DeleteMark();
+    }
+#ifdef DEBUG
+// pruefe ob die Indizies auch in den richtigen Nodes angemeldet sind
+{
+    SwPaM* pCmp = (SwPaM*)pDestShell->GetCrsr();        // sicher den Pointer auf Cursor
+    do {
+        ASSERT( pCmp->GetPoint()->nContent.GetIdxReg()
+                    == pCmp->GetCntntNode(), "Point im falschen Node" );
+        ASSERT( pCmp->GetMark()->nContent.GetIdxReg()
+                    == pCmp->GetCntntNode(FALSE), "Mark im falschen Node" );
+        BOOL bTst = *pCmp->GetPoint() == *pCmp->GetMark();
+    } while( pDestShell->GetCrsr() != ( pCmp = (SwPaM*)pCmp->GetNext() ) );
+}
+#endif
+
+    // Undo-Klammerung hier beenden
+    pDestShell->GetDoc()->EndUndo( UNDO_END );
+    pDestShell->EndAllAction();
+
+    pDestShell->SaveTblBoxCntnt( pDestShell->GetCrsr()->GetPoint() );
+
+    return (long)bRet;
+}
+
+
+    // Ersetz einen selektierten Bereich in einem TextNode mit dem
+    // String. Ist fuers Suchen&Ersetzen gedacht.
+    // bRegExpRplc - ersetze Tabs (\\t) und setze den gefundenen String
+    //               ein ( nicht \& )
+    //              z.B.: Fnd: "zzz", Repl: "xx\t\\t..&..\&"
+    //                      --> "xx\t..zzz..&"
+BOOL SwEditShell::Replace( const String& rNewStr, BOOL bRegExpRplc )
+{
+    SET_CURR_SHELL( this );
+
+    BOOL bRet = FALSE;
+    if( !HasReadonlySel() )
+    {
+        StartAllAction();
+        GetDoc()->StartUndo( UNDO_END );
+
+        FOREACHPAM_START(this)
+
+//JP 02.12.97: muss das noch sein??
+            // sollten mehrere Node selektiert sein, dann loesche diese
+            // erst, fuege ein Zeichen ein und ersetze dann dieses
+            if( PCURCRSR->GetPoint()->nNode != PCURCRSR->GetMark()->nNode )
+            {
+                BOOL bForward = PCURCRSR->GetPoint()->nNode.GetIndex() >
+                                PCURCRSR->GetMark()->nNode.GetIndex();
+                DeleteSel( *PCURCRSR );
+                pDoc->Insert( *PCURCRSR, ' ' );
+                PCURCRSR->SetMark();
+                if( bForward )
+                    PCURCRSR->GetMark()->nContent--;
+                else
+                    PCURCRSR->GetPoint()->nContent--;
+            }
+//JP 02.12.97: muss das noch sein??
+
+            if( PCURCRSR->HasMark() && *PCURCRSR->GetMark() != *PCURCRSR->GetPoint() )
+            {
+                bRet |= GetDoc()->Replace( *PCURCRSR, rNewStr, bRegExpRplc );
+                SaveTblBoxCntnt( PCURCRSR->GetPoint() );
+            }
+        FOREACHPAM_END()
+
+        // Undo-Klammerung hier beenden
+        GetDoc()->EndUndo( UNDO_END );
+        EndAllAction();
+    }
+    return bRet;
+}
+
+
+    // Special-Methode fuer JOE's- Wizzards
+BOOL SwEditShell::DelFullPara()
+{
+    BOOL bRet = FALSE;
+    if( !IsTableMode() )
+    {
+        SwPaM* pCrsr = GetCrsr();
+        // keine Mehrfach-Selection
+        if( pCrsr->GetNext() == pCrsr && !HasReadonlySel() )
+        {
+            SET_CURR_SHELL( this );
+            StartAllAction();
+            bRet = GetDoc()->DelFullPara( *pCrsr );
+            EndAllAction();
+        }
+    }
+    return bRet;
+}
+
+
+
diff --git a/sw/source/core/edit/edfcol.cxx b/sw/source/core/edit/edfcol.cxx
new file mode 100644
index 000000000000..7458eca547ef
--- /dev/null
+++ b/sw/source/core/edit/edfcol.cxx
@@ -0,0 +1,194 @@
+/*************************************************************************
+ *
+ *  $RCSfile: edfcol.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:18 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include 
+
+#ifndef _SVX_BRKITEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _EDITSH_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include       // fuer SwTxtFmtColls
+#endif
+#ifndef _EDIMP_HXX
+#include     // fuer MACROS
+#endif
+#ifndef _FMTCOL_HXX
+#include    // fuer SwXXXFmtColl
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _PARATR_HXX
+#include 
+#endif
+#ifndef _FMTPDSC_HXX //autogen
+#include 
+#endif
+
+/*************************************
+ * FormatColl
+ *************************************/
+// TXT
+
+
+SwTxtFmtColl& SwEditShell::GetDfltTxtFmtColl() const
+{
+    return *((SwTxtFmtColl*) (GetDoc()->GetDfltTxtFmtColl()));
+}
+
+
+USHORT SwEditShell::GetTxtFmtCollCount() const
+{
+    return GetDoc()->GetTxtFmtColls()->Count();
+}
+
+
+SwTxtFmtColl& SwEditShell::GetTxtFmtColl( USHORT nFmtColl) const
+{
+    return *((*(GetDoc()->GetTxtFmtColls()))[nFmtColl]);
+}
+
+
+void SwEditShell::SetTxtFmtColl(SwTxtFmtColl *pFmt)
+{
+    SwTxtFmtColl *pLocal = pFmt? pFmt: (*GetDoc()->GetTxtFmtColls())[0];
+    StartAllAction();
+    GetDoc()->StartUndo();
+    FOREACHPAM_START(this)
+
+        if( !PCURCRSR->HasReadonlySel() )
+            GetDoc()->SetTxtFmtColl(*PCURCRSR, pLocal);
+
+    FOREACHPAM_END()
+    GetDoc()->EndUndo();
+    EndAllAction();
+
+}
+
+
+SwTxtFmtColl* SwEditShell::MakeTxtFmtColl(const String& rFmtCollName,
+        SwTxtFmtColl* pParent)
+{
+    SwTxtFmtColl *pColl;
+    if ( pParent == 0 )
+        pParent = &GetTxtFmtColl(0);
+    if (  (pColl=GetDoc()->MakeTxtFmtColl(rFmtCollName, pParent)) == 0 )
+        ASSERT( FALSE, "MakeTxtFmtColl failed" );
+    return pColl;
+
+}
+
+
+void SwEditShell::FillByEx(SwTxtFmtColl* pColl, BOOL bReset)
+{
+    if( bReset )
+        pColl->ResetAllAttr();
+
+    const SfxItemSet* pSet = GetCrsr()->GetCntntNode()->GetpSwAttrSet();
+    if( pSet )
+    {
+        // JP 05.10.98: falls eines der Attribute Break/PageDesc/NumRule(auto)
+        //      im ItemSet steht, so entferne die VORM setzen an der Collection.
+        //      Ansonst wird zu viel gemacht oder falsche gemacht (NumRules!)
+        //      Bug 57568
+
+        // AutoNumRules NICHT in die Vorlagen uebernehmen
+        const SfxPoolItem* pItem;
+        const SwNumRule* pRule = 0;
+        if( SFX_ITEM_SET == pSet->GetItemState( RES_BREAK, FALSE ) ||
+            SFX_ITEM_SET == pSet->GetItemState( RES_PAGEDESC,FALSE ) ||
+            ( SFX_ITEM_SET == pSet->GetItemState( RES_PARATR_NUMRULE,
+                FALSE, &pItem ) && 0 != (pRule = GetDoc()->FindNumRulePtr(
+                ((SwNumRuleItem*)pItem)->GetValue() )) &&
+                pRule && pRule->IsAutoRule() )
+            )
+        {
+            SfxItemSet aSet( *pSet );
+            aSet.ClearItem( RES_BREAK );
+            aSet.ClearItem( RES_PAGEDESC );
+
+            if( pRule || (SFX_ITEM_SET == pSet->GetItemState( RES_PARATR_NUMRULE,
+                FALSE, &pItem ) && 0 != (pRule = GetDoc()->FindNumRulePtr(
+                ((SwNumRuleItem*)pItem)->GetValue() )) &&
+                pRule && pRule->IsAutoRule() ))
+                aSet.ClearItem( RES_PARATR_NUMRULE );
+
+            if( aSet.Count() )
+                pColl->SetAttr( aSet );
+        }
+        else
+            pColl->SetAttr( *pSet );
+    }
+}
+
+
+
+
diff --git a/sw/source/core/edit/edfld.cxx b/sw/source/core/edit/edfld.cxx
new file mode 100644
index 000000000000..fd7ed8dfad3e
--- /dev/null
+++ b/sw/source/core/edit/edfld.cxx
@@ -0,0 +1,739 @@
+/*************************************************************************
+ *
+ *  $RCSfile: edfld.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:18 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _UNOTOOLS_CHARCLASS_HXX
+#include 
+#endif
+
+#ifndef _EDITSH_HXX
+#include 
+#endif
+#ifndef _FLDBAS_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include         // GetCurFld
+#endif
+#ifndef _HINTS_HXX
+#include         // SwRefMarkFldUpdate
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _FMTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _EDIMP_HXX
+#include 
+#endif
+#ifndef _DBFLD_HXX
+#include 
+#endif
+#ifndef _EXPFLD_HXX
+#include 
+#endif
+#ifndef _FLDDAT_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include 
+#endif
+#ifndef _DBMGR_HXX
+#include 
+#endif
+#ifndef _SWDDETBL_HXX
+#include 
+#endif
+
+
+// wenn Selektion groesser Max Nodes oder mehr als Max Selektionen
+// => keine Attribute
+static const USHORT nMaxLookup = 40;
+
+/*--------------------------------------------------------------------
+    Beschreibung: Feldtypen zu einer ResId zaehlen
+                  wenn 0 alle zaehlen
+ --------------------------------------------------------------------*/
+
+USHORT SwEditShell::GetFldTypeCount(USHORT nResId, BOOL bUsed ) const
+{
+    const SwFldTypes* pFldTypes = GetDoc()->GetFldTypes();
+    const USHORT nSize = pFldTypes->Count();
+
+    if(nResId == USHRT_MAX)
+    {
+        if(!bUsed)
+            return nSize;
+        else
+        {
+            USHORT nUsed = 0;
+            for ( USHORT i = 0; i < nSize; i++ )
+            {
+                if(IsUsed(*(*pFldTypes)[i]))
+                    nUsed++;
+            }
+            return nUsed;
+        }
+    }
+
+    // Alle Typen mit gleicher ResId
+    USHORT nIdx  = 0;
+    for(USHORT i = 0; i < nSize; ++i)
+    {   // Gleiche ResId -> Index erhoehen
+        SwFieldType& rFldType = *((*pFldTypes)[i]);
+        if(rFldType.Which() == nResId)
+            nIdx++;
+    }
+    return nIdx;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Feldtypen zu einer ResId finden
+                  wenn 0 alle finden
+ --------------------------------------------------------------------*/
+SwFieldType* SwEditShell::GetFldType(USHORT nFld, USHORT nResId, BOOL bUsed ) const
+{
+    const SwFldTypes* pFldTypes = GetDoc()->GetFldTypes();
+    const USHORT nSize = pFldTypes->Count();
+
+    if(nResId == USHRT_MAX && nFld < nSize)
+    {
+        if(!bUsed)
+            return (*pFldTypes)[nFld];
+        else
+        {
+            USHORT i, nUsed = 0;
+            for ( i = 0; i < nSize; i++ )
+            {
+                if(IsUsed(*(*pFldTypes)[i]))
+                {
+                    if(nUsed == nFld)
+                        break;
+                    nUsed++;
+                }
+            }
+            return i < nSize ? (*pFldTypes)[i] : 0;
+        }
+    }
+
+    USHORT nIdx = 0;
+    for(USHORT i = 0; i < nSize; ++i)
+    {   // Gleiche ResId -> Index erhoehen
+        SwFieldType* pFldType = (*pFldTypes)[i];
+        if(pFldType->Which() == nResId)
+        {
+            if (!bUsed || IsUsed(*pFldType))
+            {
+                if(nIdx == nFld)
+                    return pFldType;
+                nIdx++;
+            }
+        }
+    }
+    return 0;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Den ersten Typen mit ResId und Namen finden
+ --------------------------------------------------------------------*/
+SwFieldType* SwEditShell::GetFldType(USHORT nResId, const String& rName) const
+{
+    return GetDoc()->GetFldType( nResId, rName );
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Feldtypen loeschen
+ --------------------------------------------------------------------*/
+void SwEditShell::RemoveFldType(USHORT nFld, USHORT nResId)
+{
+    if( USHRT_MAX == nResId )
+    {
+        GetDoc()->RemoveFldType(nFld);
+        return;
+    }
+
+    const SwFldTypes* pFldTypes = GetDoc()->GetFldTypes();
+    const USHORT nSize = pFldTypes->Count();
+    USHORT nIdx = 0;
+    for( USHORT i = 0; i < nSize; ++i )
+        // Gleiche ResId -> Index erhoehen
+        if( (*pFldTypes)[i]->Which() == nResId &&
+            nIdx++ == nFld )
+        {
+            GetDoc()->RemoveFldType( i );
+            return;
+        }
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: FieldType ueber Name loeschen
+ --------------------------------------------------------------------*/
+void SwEditShell::RemoveFldType(USHORT nResId, const String& rStr)
+{
+    const SwFldTypes* pFldTypes = GetDoc()->GetFldTypes();
+    const USHORT nSize = pFldTypes->Count();
+    const CharClass& rCC = GetAppCharClass();
+
+    String aTmp( rCC.lower( rStr ));
+
+    for(USHORT i = 0; i < nSize; ++i)
+    {
+        // Gleiche ResId -> Index erhoehen
+        SwFieldType* pFldType = (*pFldTypes)[i];
+        if( pFldType->Which() == nResId )
+        {
+            if( aTmp.Equals( rCC.lower( pFldType->GetName() ) ))
+            {
+                GetDoc()->RemoveFldType(i);
+                return;
+            }
+        }
+    }
+}
+
+
+void SwEditShell::FieldToText( SwFieldType* pType )
+{
+    if( !pType->GetDepends() )
+        return;
+
+    SET_CURR_SHELL( this );
+    StartAllAction();
+    StartUndo( UNDO_DELETE );
+    Push();
+    SwPaM* pPaM = GetCrsr();
+
+    BOOL bDDEFld = RES_DDEFLD == pType->Which();
+    // Modify-Object gefunden, trage alle Felder ins Array ein
+    SwClientIter aIter( *pType );
+    SwClient * pLast = aIter.GoStart();
+
+    if( pLast )     // konnte zum Anfang gesprungen werden ??
+        do {
+            pPaM->DeleteMark();
+            const SwFmtFld* pFmtFld = bDDEFld
+                        ? PTR_CAST( SwFmtFld, pLast )
+                        : (SwFmtFld*)pLast;
+
+            if( pFmtFld )
+            {
+                if( !pFmtFld->GetTxtFld() )
+                    continue;
+
+                // kann keine DDETabelle sein
+                const SwTxtNode& rTxtNode = pFmtFld->GetTxtFld()->GetTxtNode();
+                pPaM->GetPoint()->nNode = rTxtNode;
+                pPaM->GetPoint()->nContent.Assign( (SwTxtNode*)&rTxtNode,
+                                     *pFmtFld->GetTxtFld()->GetStart() );
+
+                // Feldinhalt durch Text ersetzen
+                String aEntry( pFmtFld->GetFld()->Expand() );
+                pPaM->SetMark();
+                pPaM->Move( fnMoveForward );
+                GetDoc()->Delete( *pPaM );
+                GetDoc()->Insert( *pPaM, aEntry );
+            }
+            else if( bDDEFld )
+            {
+                // DDETabelle
+                SwDepend* pDep = (SwDepend*)pLast;
+                SwDDETable* pDDETbl = (SwDDETable*)pDep->GetToTell();
+                pDDETbl->NoDDETable();
+            }
+
+        } while( 0 != ( pLast = aIter++ ));
+
+    Pop( FALSE );
+    EndAllAction();
+    EndUndo( UNDO_DELETE );
+}
+
+/*************************************************************************
+|*
+|*                  SwEditShell::Insert( SwField )
+|*
+|*    Beschreibung  an der Cursorposition ein Feld einfuegen
+|*    Quelle:       vgl. SwEditShell::Insert( String )
+|*
+*************************************************************************/
+void SwEditShell::Insert(SwField& rFld)
+{
+    SET_CURR_SHELL( this );
+    StartAllAction();
+    SwFmtFld aFld( rFld );
+
+    FOREACHPAM_START(this)                      // fuer jeden PaM
+        if( !GetDoc()->Insert( *PCURCRSR, aFld ) )
+            ASSERT( FALSE, "Doc->Insert(Field) failed");
+    FOREACHPAM_END()                      // fuer jeden PaM
+
+    EndAllAction();
+}
+
+/*************************************************************************
+|*
+|*                  SwEditShell::GetCurFld()
+|*
+|*    Beschreibung  Stehen die PaMs auf Feldern ?
+|*    Quelle:       edtfrm.cxx:
+|*
+*************************************************************************/
+
+inline SwTxtFld *GetDocTxtFld( const SwPosition* pPos )
+{
+    SwTxtNode *pNode = pPos->nNode.GetNode().GetTxtNode();
+    if( pNode )
+        return pNode->GetTxtFld( pPos->nContent );
+    else
+        return 0;
+}
+
+SwField* SwEditShell::GetCurFld() const
+{
+    // Wenn es keine Selektionen gibt, gilt der Wert der aktuellen
+    // Cursor-Position.
+    SwPaM* pCrsr = GetCrsr();
+    SwTxtFld *pTxtFld = GetDocTxtFld( pCrsr->Start() );
+    SwField *pCurFld;
+    if( pTxtFld && pCrsr->GetNext() == pCrsr && !pCrsr->HasMark() )
+    {
+        pCurFld = (SwField*)pTxtFld->GetFld().GetFld();
+        // TabellenFormel ? wandel internen in externen Namen um
+        if( RES_TABLEFLD == pCurFld->GetTyp()->Which() )
+        {
+            const SwTableNode* pTblNd = IsCrsrInTbl();
+            ((SwTblField*)pCurFld)->PtrToBoxNm( pTblNd ? &pTblNd->GetTable() : 0 );
+        }
+        return pCurFld;
+    }
+    pCurFld = 0;
+
+    USHORT nCrsrCnt = 0;
+    SwMsgPoolItem aHint( RES_TXTATR_FIELD );  // Such-Hint
+    FOREACHPAM_START(this)                      // fuer jeden PaM
+        if( nMaxLookup < ++nCrsrCnt  )
+            break;
+
+        if( PCURCRSR->HasMark() )               // ... mit Selektion
+        {
+            // Kopie des PaM
+            SwPaM aCurPam( *PCURCRSR->GetMark(), *PCURCRSR->GetPoint() );
+            SwPaM aPam( *PCURCRSR->GetPoint() );
+
+            SwPosition *pCurStt = aCurPam.Start(), *pCurEnd = aCurPam.End();
+            /*
+             * Fuer den Fall, dass zwei aneinanderliegende Felder in einem
+             * PaM liegen, hangelt sich aPam portionsweise bis zum Ende.
+             * aCurPam wird dabei nach jeder Schleifenrunde verkuerzt.
+             * Wenn aCurPam vollstaendig durchsucht wurde, ist Start = End
+             * und die Schleife terminiert.
+             */
+
+            // Suche nach SwTxtFld ...
+            while( pCurStt->nContent != pCurEnd->nContent
+                   && aPam.Find( aHint, FALSE, fnMoveForward, &aCurPam,
+                                 IsReadOnlyAvailable() ) )
+            {
+                // Wenn die Start's der beiden Bereiche nicht uebereinstimmen,
+                // so liegt in dem selektierten Bereich etwas anderes als
+                // ein/mehrere Felder: RETURN.
+
+                const SwPosition* pStt;
+                if( ( pStt = aPam.Start())->nContent != pCurStt->nContent )
+                    return( 0 );
+
+                SwTxtFld *pTxtFld = GetDocTxtFld( pStt );
+                if( pTxtFld )
+                {
+                    // RETURN bei gemischten Feldtypen
+                    if( pCurFld && pCurFld->GetTyp()->Which() !=
+                        pTxtFld->GetFld().GetFld()->GetTyp()->Which() )
+                        return( 0 );
+                    pCurFld = (SwField*)pTxtFld->GetFld().GetFld();
+                    // TabellenFormel ? wandel internen in externen Namen um
+                    if( RES_TABLEFLD == pCurFld->GetTyp()->Which() )
+                    {
+                        const SwTableNode* pTblNd = GetDoc()->IsIdxInTbl( aPam.GetPoint()->nNode );
+                        ((SwTblField*)pCurFld)->PtrToBoxNm( pTblNd
+                                        ? &pTblNd->GetTable() : 0 );
+                    }
+                }
+
+                // Der Suchbereich wird um den gefundenen Bereich verkuerzt.
+                pCurStt->nContent++;
+            }
+        }
+    FOREACHPAM_END()                      // fuer jeden PaM
+    return pCurFld;
+}
+
+
+/*************************************************************************
+|*
+|*                  SwEditShell::UpdateFlds()
+|*
+|*    Beschreibung  Stehen die PaMs auf Feldern ?
+|*                  BP 12.05.92
+|*
+*************************************************************************/
+SwTxtFld* lcl_FindInputFld( SwDoc* pDoc, SwField& rFld )
+{
+    // suche das Feld ueber seine Addresse. Muss fuer InputFelder in
+    // geschuetzten Feldern erfolgen
+    SwTxtFld* pTFld = 0;
+    if( RES_INPUTFLD == rFld.Which() || ( RES_SETEXPFLD == rFld.Which() &&
+        ((SwSetExpField&)rFld).GetInputFlag() ) )
+    {
+        const SfxPoolItem* pItem;
+        USHORT n, nMaxItems = pDoc->GetAttrPool().GetItemCount( RES_TXTATR_FIELD );
+        for( n = 0; n < nMaxItems; ++n )
+            if( 0 != (pItem = pDoc->GetAttrPool().GetItem( RES_TXTATR_FIELD, n ) )
+                && ((SwFmtFld*)pItem)->GetFld() == &rFld )
+            {
+                pTFld = ((SwFmtFld*)pItem)->GetTxtFld();
+                break;
+            }
+    }
+    return pTFld;
+}
+
+void SwEditShell::UpdateFlds( SwField &rFld )
+{
+    SET_CURR_SHELL( this );
+    StartAllAction();
+    {
+        SwField *pCurFld = 0;
+
+        // Wenn es keine Selektionen gibt, gilt der Wert der aktuellen
+        // Cursor-Position.
+        SwMsgPoolItem* pMsgHnt = 0;
+        SwRefMarkFldUpdate aRefMkHt( GetOut() );
+        USHORT nFldWhich = rFld.GetTyp()->Which();
+        if( RES_GETREFFLD == nFldWhich )
+            pMsgHnt = &aRefMkHt;
+
+        SwPaM* pCrsr = GetCrsr();
+        SwTxtFld *pTxtFld;
+        SwFmtFld *pFmtFld;
+        if( pCrsr->GetNext() == pCrsr && !pCrsr->HasMark() &&
+            ( 0 != ( pTxtFld = GetDocTxtFld( pCrsr->Start() ) ) ||
+              0 != ( pTxtFld = lcl_FindInputFld( GetDoc(), rFld ) ) ) &&
+            ( pFmtFld = (SwFmtFld*)&pTxtFld->GetFld())->GetFld()
+                ->GetTyp()->Which() == rFld.GetTyp()->Which() )
+        {
+            // Das gefundene Feld wird angepasst ...
+            pFmtFld->GetFld()->ChangeFormat( rFld.GetFormat() );
+            pFmtFld->GetFld()->SetLanguage( rFld.GetLanguage() );
+            switch( nFldWhich )
+            {
+            case RES_SETEXPFLD:
+            case RES_GETEXPFLD:
+            case RES_HIDDENTXTFLD:
+            case RES_HIDDENPARAFLD:
+                GetDoc()->UpdateExpFlds( pTxtFld );
+                break;
+
+            case RES_TABLEFLD:
+                {
+                    const SwTableNode* pTblNd = GetDoc()->IsIdxInTbl(
+                                            pCrsr->GetPoint()->nNode );
+                    if( pTblNd )
+                    {
+                        SwTableFmlUpdate aTblUpdate( &pTblNd->GetTable() );
+                        GetDoc()->UpdateTblFlds( &aTblUpdate );
+                    }
+                }
+                break;
+
+            case RES_MACROFLD:
+                if( pTxtFld->GetpTxtNode() )
+                    ((SwTxtNode*)pTxtFld->GetpTxtNode())->Modify( 0, pFmtFld );
+                break;
+
+            case RES_DBFLD:
+                {
+                    // JP 10.02.96: ChgValue aufrufen, damit die Format-
+                    //              aenderung den ContentString richtig setzt
+                    SwDBField* pDBFld = (SwDBField*)pFmtFld->GetFld();
+                    if (pDBFld->IsInitialized())
+                        pDBFld->ChgValue( pDBFld->GetValue(), TRUE );
+                }
+                // kein break;
+
+            default:
+                pFmtFld->Modify( 0, pMsgHnt );
+            }
+
+            // Die Felder die wir berechnen koennen werden hier expli.
+            // zum Update angestossen.
+            if( nFldWhich == RES_USERFLD )
+                GetDoc()->UpdateUsrFlds();
+        }
+
+        // bOkay (statt return wg. EndAllAction) wird FALSE,
+        // 1) wenn nur ein Pam mehr als ein Feld enthaelt oder
+        // 2) bei gemischten Feldtypen
+        BOOL bOkay = TRUE;
+        BOOL bTblSelBreak = FALSE;
+
+        SwMsgPoolItem aHint( RES_TXTATR_FIELD );  // Such-Hint
+        FOREACHPAM_START(this)                      // fuer jeden PaM
+            if( PCURCRSR->HasMark() && bOkay )      // ... mit Selektion
+            {
+                // Kopie des PaM
+                SwPaM aCurPam( *PCURCRSR->GetMark(), *PCURCRSR->GetPoint() );
+                SwPaM aPam( *PCURCRSR->GetPoint() );
+
+                SwPosition *pCurStt = aCurPam.Start(), *pCurEnd = aCurPam.End();
+                /*
+                 * Fuer den Fall, dass zwei aneinanderliegende Felder in einem
+                 * PaM liegen, hangelt sich aPam portionsweise bis zum Ende.
+                 * aCurPam wird dabei nach jeder Schleifenrunde verkuerzt.
+                 * Wenn aCurPam vollstaendig durchsucht wurde, ist Start = End
+                 * und die Schleife terminiert.
+                 */
+
+                // Suche nach SwTxtFld ...
+                while(  bOkay
+                     && pCurStt->nContent != pCurEnd->nContent
+                     && aPam.Find( aHint, FALSE, fnMoveForward, &aCurPam ) )
+                {
+                    //  wenn nur ein Pam mehr als ein Feld enthaelt ...
+                    if( aPam.Start()->nContent != pCurStt->nContent )
+                        bOkay = FALSE;
+
+                    if( 0 != (pTxtFld = GetDocTxtFld( pCurStt )) )
+                    {
+                        pFmtFld = (SwFmtFld*)&pTxtFld->GetFld();
+                        pCurFld = pFmtFld->GetFld();
+
+                        // bei gemischten Feldtypen
+                        if( pCurFld->GetTyp()->Which() != rFld.GetTyp()->Which() )
+                            bOkay = FALSE;
+
+                        // Das gefundene selektierte Feld wird angepasst ...
+                        pCurFld->ChangeFormat( rFld.GetFormat() );
+                        if( RES_SETEXPFLD == nFldWhich ||
+                            RES_GETEXPFLD == nFldWhich ||
+                            RES_HIDDENTXTFLD == nFldWhich )
+                            GetDoc()->UpdateExpFlds( pTxtFld );
+                        else if( RES_TABLEFLD == nFldWhich )
+                        {
+                            SwPaM* pPam = IsTableMode() ? GetTblCrs() : &aCurPam;
+                            const SwTableNode* pTblNd = GetDoc()->IsIdxInTbl(
+                                                    pPam->GetPoint()->nNode );
+                            if( pTblNd )
+                            {
+                                SwTableFmlUpdate aTblUpdate( &pTblNd->GetTable() );
+                                pCurFld->GetTyp()->Modify( 0, &aTblUpdate );
+                            }
+                            // bei Tabellen-SSelection ist hier Ende !!
+                            if( IsTableMode() )
+                            {
+                                bTblSelBreak = TRUE;
+                                break;
+                            }
+                        }
+                        else
+                            pFmtFld->Modify( 0, pMsgHnt );
+
+                        // Die Felder die wir berechnen koennen werden hier
+                        //  expli. zum Update angestossen.
+                        if( nFldWhich == RES_USERFLD )
+                            GetDoc()->UpdateUsrFlds();
+                    }
+                    // Der Suchbereich wird um den gefundenen Bereich verkuerzt.
+                    pCurStt->nContent++;
+                }
+            }
+
+            if( bTblSelBreak )      // wenn Tabellen Selektion und Tabellen-
+                break;              // Formel aktualisiert wurde -> beenden
+
+        FOREACHPAM_END()                      // fuer jeden PaM
+    }
+    GetDoc()->SetModified();
+    EndAllAction();
+}
+
+/*-----------------13.05.92 10:54-------------------
+ Liefert den logischen fuer die Datenbank zurueck
+ --------------------------------------------------*/
+
+String SwEditShell::GetDBName() const
+{
+    return GetDoc()->GetDBName();
+}
+
+const String& SwEditShell::GetDBDesc() const
+{
+    return GetDoc()->GetDBDesc();
+}
+
+void SwEditShell::ChgDBName(const String& rNewName)
+{
+    GetDoc()->ChgDBName(rNewName);
+}
+
+void SwEditShell::GetAllUsedDB( SvStringsDtor& rDBNameList,
+                                SvStringsDtor* pAllDBNames )
+{
+    GetDoc()->GetAllUsedDB( rDBNameList, pAllDBNames );
+}
+
+void SwEditShell::ChangeDBFields( const SvStringsDtor& rOldNames,
+                                    const String& rNewName )
+{
+    GetDoc()->ChangeDBFields( rOldNames, rNewName );
+}
+
+BOOL SwEditShell::RenameUserFields(const String& rOldName, const String& rNewName)
+{
+    return GetDoc()->RenameUserFields(rOldName, rNewName);
+}
+
+
+/*--------------------------------------------------------------------
+    Beschreibung:  Alle Expression-Felder erneuern
+ --------------------------------------------------------------------*/
+void SwEditShell::UpdateExpFlds(BOOL bCloseDB)
+{
+    SET_CURR_SHELL( this );
+    StartAllAction();
+    GetDoc()->UpdateExpFlds();
+    if (bCloseDB)
+        GetDoc()->GetNewDBMgr()->CloseAll();    // Alle Datenbankverbindungen dichtmachen
+    EndAllAction();
+}
+
+SwNewDBMgr* SwEditShell::GetNewDBMgr() const
+{
+    return GetDoc()->GetNewDBMgr();
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Feldtypen einfuegen
+ --------------------------------------------------------------------*/
+SwFieldType* SwEditShell::InsertFldType(const SwFieldType& rFldType)
+{
+    return GetDoc()->InsertFldType(rFldType);
+}
+
+void SwEditShell::LockExpFlds()
+{
+    GetDoc()->LockExpFlds();
+}
+
+void SwEditShell::UnlockExpFlds()
+{
+    GetDoc()->UnlockExpFlds();
+}
+
+BOOL SwEditShell::IsExpFldsLocked() const
+{
+    return GetDoc()->IsExpFldsLocked();
+}
+
+void SwEditShell::SetFldUpdateFlags( USHORT eFlags )
+{
+    GetDoc()->SetFldUpdateFlags( eFlags );
+}
+
+USHORT SwEditShell::GetFldUpdateFlags(BOOL bDocSettings) const
+{
+    return bDocSettings ? GetDoc()->_GetFldUpdateFlags() : GetDoc()->GetFldUpdateFlags();
+}
+
+void SwEditShell::SetFixFields( BOOL bOnlyTimeDate,
+                                const DateTime* pNewDateTime )
+{
+    SET_CURR_SHELL( this );
+    StartAllAction();
+    GetDoc()->SetFixFields( bOnlyTimeDate, pNewDateTime );
+    EndAllAction();
+}
+
+void SwEditShell::SetLabelDoc( BOOL bFlag )
+{
+    GetDoc()->SetLabelDoc( bFlag );
+}
+
+BOOL SwEditShell::IsLabelDoc() const
+{
+    return GetDoc()->IsLabelDoc();
+}
+/* -----------------------------21.12.99 12:53--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SwEditShell::ChangeAuthorityData(const SwAuthEntry* pNewData)
+{
+    GetDoc()->ChangeAuthorityData(pNewData);
+}
+
diff --git a/sw/source/core/edit/edfmt.cxx b/sw/source/core/edit/edfmt.cxx
new file mode 100644
index 000000000000..299720dbce13
--- /dev/null
+++ b/sw/source/core/edit/edfmt.cxx
@@ -0,0 +1,277 @@
+/*************************************************************************
+ *
+ *  $RCSfile: edfmt.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:18 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "doc.hxx"
+#include "editsh.hxx"
+#include "swtable.hxx"
+#include "pam.hxx"
+#ifndef _DOCARY_HXX
+#include 
+#endif
+
+#ifndef _FCHRFMT_HXX //autogen
+#include 
+#endif
+#ifndef _FRMFMT_HXX //autogen
+#include 
+#endif
+#ifndef _CHARFMT_HXX //autogen
+#include 
+#endif
+#include "ndtxt.hxx"    // Fuer GetXXXFmt
+#include "hints.hxx"
+
+
+/*************************************
+ * Formate
+ *************************************/
+// Char
+// OPT: inline
+
+
+USHORT SwEditShell::GetCharFmtCount() const
+{
+    return GetDoc()->GetCharFmts()->Count();
+}
+
+
+SwCharFmt& SwEditShell::GetCharFmt(USHORT nFmt) const
+{
+    return *((*(GetDoc()->GetCharFmts()))[nFmt]);
+}
+
+
+SwCharFmt* SwEditShell::GetCurCharFmt() const
+{
+    SwCharFmt *pFmt = 0;
+    SfxItemSet aSet( GetDoc()->GetAttrPool(), RES_TXTATR_CHARFMT,
+                                                RES_TXTATR_CHARFMT );
+    const SfxPoolItem* pItem;
+    if( GetAttr( aSet ) && SFX_ITEM_SET ==
+        aSet.GetItemState( RES_TXTATR_CHARFMT, FALSE, &pItem ) )
+        pFmt = ((SwFmtCharFmt*)pItem)->GetCharFmt();
+
+    return pFmt;
+}
+
+
+void SwEditShell::FillByEx(SwCharFmt* pCharFmt, BOOL bReset)
+{
+    if ( bReset )
+        pCharFmt->ResetAllAttr();
+
+    SwPaM* pPam = GetCrsr();
+    const SwCntntNode* pCNd = pPam->GetCntntNode();
+    if( pCNd->IsTxtNode() )
+    {
+        xub_StrLen nStt, nEnd;
+        if( pPam->HasMark() )
+        {
+            const SwPosition* pPtPos = pPam->GetPoint();
+            const SwPosition* pMkPos = pPam->GetMark();
+            if( pPtPos->nNode == pMkPos->nNode )        // im selben Node ?
+            {
+                nStt = pPtPos->nContent.GetIndex();
+                if( nStt < pMkPos->nContent.GetIndex() )
+                    nEnd = pMkPos->nContent.GetIndex();
+                else
+                {
+                    nEnd = nStt;
+                    nStt = pMkPos->nContent.GetIndex();
+                }
+            }
+            else
+            {
+                nStt = pMkPos->nContent.GetIndex();
+                if( pPtPos->nNode < pMkPos->nNode )
+                {
+                    nEnd = nStt;
+                    nStt = 0;
+                }
+                else
+                    nEnd = ((SwTxtNode*)pCNd)->GetTxt().Len();
+            }
+        }
+        else
+            nStt = nEnd = pPam->GetPoint()->nContent.GetIndex();
+
+        SfxItemSet aSet( pDoc->GetAttrPool(),
+                            pCharFmt->GetAttrSet().GetRanges() );
+        ((SwTxtNode*)pCNd)->GetAttr( aSet, nStt, nEnd );
+        pCharFmt->SetAttr( aSet );
+    }
+    else if( pCNd->GetpSwAttrSet() )
+        pCharFmt->SetAttr( *pCNd->GetpSwAttrSet() );
+}
+
+// Frm
+USHORT SwEditShell::GetTblFrmFmtCount(BOOL bUsed) const
+{
+    return GetDoc()->GetTblFrmFmtCount(bUsed);
+}
+
+SwFrmFmt& SwEditShell::GetTblFrmFmt(USHORT nFmt, BOOL bUsed ) const
+{
+    return GetDoc()->GetTblFrmFmt(nFmt, bUsed );
+}
+
+String SwEditShell::GetUniqueTblName() const
+{
+    return GetDoc()->GetUniqueTblName();
+}
+
+
+SwCharFmt* SwEditShell::MakeCharFmt( const String& rName,
+                                    SwCharFmt* pDerivedFrom )
+{
+    if( !pDerivedFrom )
+        pDerivedFrom = GetDoc()->GetDfltCharFmt();
+
+    return GetDoc()->MakeCharFmt( rName, pDerivedFrom );
+}
+
+//----------------------------------
+// inlines im Product
+
+
+SwTxtFmtColl* SwEditShell::GetTxtCollFromPool( USHORT nId )
+{
+    return GetDoc()->GetTxtCollFromPool( nId );
+}
+
+
+    // return das geforderte automatische  Format - Basis-Klasse !
+SwFmt* SwEditShell::GetFmtFromPool( USHORT nId )
+{
+    return GetDoc()->GetFmtFromPool( nId );
+}
+
+
+SwPageDesc* SwEditShell::GetPageDescFromPool( USHORT nId )
+{
+    return GetDoc()->GetPageDescFromPool( nId );
+}
+
+
+BOOL SwEditShell::IsUsed( const SwModify& rModify ) const
+{
+    return pDoc->IsUsed( rModify );
+}
+
+
+USHORT SwEditShell::GetPoolId( const String& rName,
+                                SwGetPoolIdFromName eFlags ) const
+{
+    return pDoc->GetPoolId( rName, eFlags );
+}
+
+
+const SvStringsDtor& SwEditShell::GetChrFmtNmArray() const
+{
+    return pDoc->GetChrFmtNmArray();
+}
+
+
+const SvStringsDtor& SwEditShell::GetHTMLChrFmtNmArray() const
+{
+    return pDoc->GetHTMLChrFmtNmArray();
+}
+
+
+const SwFlyFrmFmt* SwEditShell::FindFlyByName( const String& rName, BYTE nNdTyp ) const
+{
+    return pDoc->FindFlyByName(rName, nNdTyp);
+}
+
+
+SwCharFmt* SwEditShell::FindCharFmtByName( const String& rName ) const
+{
+    return pDoc->FindCharFmtByName( rName );
+}
+
+SwFrmFmt* SwEditShell::FindFrmFmtByName( const String& rName ) const
+{
+    return pDoc->FindFrmFmtByName( rName );
+}
+
+SwTxtFmtColl* SwEditShell::FindTxtFmtCollByName( const String& rName ) const
+{
+    return pDoc->FindTxtFmtCollByName( rName );
+}
+
+#ifdef USED
+
+SwGrfFmtColl* SwEditShell::FindGrfFmtCollByName( const String& rName ) const
+{
+    return pDoc->FindGrfFmtCollByName( rName );
+}
+#endif
+
+
+
+
+
diff --git a/sw/source/core/edit/edglbldc.cxx b/sw/source/core/edit/edglbldc.cxx
new file mode 100644
index 000000000000..030b7be42f74
--- /dev/null
+++ b/sw/source/core/edit/edglbldc.cxx
@@ -0,0 +1,470 @@
+/*************************************************************************
+ *
+ *  $RCSfile: edglbldc.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:18 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _EDITSH_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _SWWAIT_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include        // fuer die UndoIds
+#endif
+#ifndef _SECTION_HXX
+#include 
+#endif
+#ifndef _DOCTXM_HXX
+#include 
+#endif
+#ifndef _EDGLBLDC_HXX
+#include 
+#endif
+
+
+SV_IMPL_OP_PTRARR_SORT( SwGlblDocContents, SwGlblDocContentPtr )
+
+void SwEditShell::SetGlobalDoc( BOOL bFlag )
+{
+    GetDoc()->SetGlobalDoc( bFlag );
+}
+
+BOOL SwEditShell::IsGlobalDoc() const
+{
+    return GetDoc()->IsGlobalDoc();
+}
+
+void SwEditShell::SetGlblDocSaveLinks( BOOL bFlag )
+{
+    GetDoc()->SetGlblDocSaveLinks( bFlag );
+    if( !GetDoc()->IsModified() )   // Bug 57028
+        GetDoc()->SetUndoNoResetModified();
+    GetDoc()->SetModified();
+}
+
+BOOL SwEditShell::IsGlblDocSaveLinks() const
+{
+    return GetDoc()->IsGlblDocSaveLinks();
+}
+
+USHORT SwEditShell::GetGlobalDocContent( SwGlblDocContents& rArr ) const
+{
+    if( rArr.Count() )
+        rArr.DeleteAndDestroy( 0, rArr.Count() );
+
+    SwDoc* pDoc = GetDoc();
+    if( !pDoc->IsGlobalDoc() )
+        return 0;
+
+    // dann alle gelinkten Bereiche auf der obersten Ebene
+    const SwSectionFmts& rSectFmts = pDoc->GetSections();
+    for( USHORT n = rSectFmts.Count(); n; )
+    {
+        const SwSection* pSect = rSectFmts[ --n ]->GetGlobalDocSection();
+        if( pSect )
+        {
+            SwGlblDocContentPtr pNew;
+            switch( pSect->GetType() )
+            {
+            case TOX_HEADER_SECTION:    break;      // ignore
+            case TOX_CONTENT_SECTION:
+                ASSERT( pSect->ISA( SwTOXBaseSection ), "keine TOXBaseSection!" );
+                pNew = new SwGlblDocContent( (SwTOXBaseSection*)pSect );
+                break;
+
+            default:
+                pNew = new SwGlblDocContent( pSect );
+                break;
+            }
+            if( !rArr.Insert( pNew ) )
+                delete pNew;
+        }
+    }
+
+    // und als letztes die Dummies (sonstiger Text) einfuegen
+    SwNode* pNd;
+    ULONG nSttIdx = pDoc->GetNodes().GetEndOfExtras().GetIndex() + 2;
+    for( n = 0; n < rArr.Count(); ++n )
+    {
+        const SwGlblDocContent& rNew = *rArr[ n ];
+        // suche von StartPos bis rNew.DocPos nach einem Content Node.
+        // Existiert dieser, so muss ein DummyEintrag eingefuegt werden.
+        for( ; nSttIdx < rNew.GetDocPos(); ++nSttIdx )
+            if( ( pNd = pDoc->GetNodes()[ nSttIdx ])->IsCntntNode()
+                || pNd->IsSectionNode() || pNd->IsTableNode() )
+            {
+                SwGlblDocContentPtr pNew = new SwGlblDocContent( nSttIdx );
+                if( !rArr.Insert( pNew ) )
+                    delete pNew;
+                else
+                    ++n;        // auf die naechste Position
+                break;
+            }
+
+        // StartPosition aufs Ende setzen
+        nSttIdx = pDoc->GetNodes()[ rNew.GetDocPos() ]->EndOfSectionIndex();
+        ++nSttIdx;
+    }
+
+    // sollte man das Ende auch noch setzen??
+    if( rArr.Count() )
+    {
+        ULONG nNdEnd = pDoc->GetNodes().GetEndOfContent().GetIndex();
+        for( ; nSttIdx < nNdEnd; ++nSttIdx )
+            if( ( pNd = pDoc->GetNodes()[ nSttIdx ])->IsCntntNode()
+                || pNd->IsSectionNode() || pNd->IsTableNode() )
+            {
+                SwGlblDocContentPtr pNew = new SwGlblDocContent( nSttIdx );
+                if( !rArr.Insert( pNew ) )
+                    delete pNew;
+                break;
+            }
+    }
+    else
+    {
+        SwGlblDocContentPtr pNew = new SwGlblDocContent(
+                    pDoc->GetNodes().GetEndOfExtras().GetIndex() + 2 );
+        rArr.Insert( pNew );
+    }
+    return rArr.Count();
+}
+
+BOOL SwEditShell::InsertGlobalDocContent( const SwGlblDocContent& rInsPos,
+                                            const SwSection& rNew )
+{
+    SwDoc* pDoc = GetDoc();
+    if( !pDoc->IsGlobalDoc() )
+        return FALSE;
+
+    SET_CURR_SHELL( this );
+    StartAllAction();
+
+    SwPaM* pCrsr = GetCrsr();
+    if( pCrsr->GetNext() != pCrsr || IsTableMode() )
+        ClearMark();
+
+    SwPosition& rPos = *pCrsr->GetPoint();
+    rPos.nNode = rInsPos.GetDocPos();
+
+    BOOL bEndUndo = FALSE;
+    SwTxtNode* pTxtNd = pDoc->GetNodes()[ rPos.nNode ]->GetTxtNode();
+    if( pTxtNd )
+        rPos.nContent.Assign( pTxtNd, 0 );
+    else
+    {
+        bEndUndo = TRUE;
+        pDoc->StartUndo( UNDO_START );
+        rPos.nNode--;
+        pDoc->AppendTxtNode( rPos );
+        pCrsr->SetMark();
+    }
+
+    InsertSection( rNew );
+
+    if( bEndUndo )
+        pDoc->EndUndo( UNDO_END );
+    EndAllAction();
+
+    return TRUE;
+}
+
+BOOL SwEditShell::InsertGlobalDocContent( const SwGlblDocContent& rInsPos,
+                                            const SwTOXBase& rTOX )
+{
+    SwDoc* pDoc = GetDoc();
+    if( !pDoc->IsGlobalDoc() )
+        return FALSE;
+
+    SET_CURR_SHELL( this );
+    StartAllAction();
+
+    SwPaM* pCrsr = GetCrsr();
+    if( pCrsr->GetNext() != pCrsr || IsTableMode() )
+        ClearMark();
+
+    SwPosition& rPos = *pCrsr->GetPoint();
+    rPos.nNode = rInsPos.GetDocPos();
+
+    BOOL bEndUndo = FALSE;
+    SwTxtNode* pTxtNd = rPos.nNode.GetNode().GetTxtNode();
+    if( pTxtNd && pTxtNd->GetTxt().Len() && rPos.nNode.GetIndex() + 1 !=
+        pDoc->GetNodes().GetEndOfContent().GetIndex() )
+        rPos.nContent.Assign( pTxtNd, 0 );
+    else
+    {
+        bEndUndo = TRUE;
+        pDoc->StartUndo( UNDO_START );
+        rPos.nNode--;
+        pDoc->AppendTxtNode( rPos );
+    }
+
+    InsertTableOf( rTOX );
+
+    if( bEndUndo )
+        pDoc->EndUndo( UNDO_END );
+    EndAllAction();
+
+    return TRUE;
+}
+
+BOOL SwEditShell::InsertGlobalDocContent( const SwGlblDocContent& rInsPos )
+{
+    SwDoc* pDoc = GetDoc();
+    if( !pDoc->IsGlobalDoc() )
+        return FALSE;
+
+    SET_CURR_SHELL( this );
+    StartAllAction();
+
+    SwPaM* pCrsr = GetCrsr();
+    if( pCrsr->GetNext() != pCrsr || IsTableMode() )
+        ClearMark();
+
+    SwPosition& rPos = *pCrsr->GetPoint();
+    rPos.nNode = rInsPos.GetDocPos() - 1;
+    rPos.nContent.Assign( 0, 0 );
+
+    pDoc->AppendTxtNode( rPos );
+    EndAllAction();
+    return TRUE;
+}
+
+BOOL SwEditShell::DeleteGlobalDocContent( const SwGlblDocContents& rArr ,
+                                            USHORT nDelPos )
+{
+    SwDoc* pDoc = GetDoc();
+    if( !pDoc->IsGlobalDoc() )
+        return FALSE;
+
+    SET_CURR_SHELL( this );
+    StartAllAction();
+    StartUndo( UNDO_START );
+
+    SwPaM* pCrsr = GetCrsr();
+    if( pCrsr->GetNext() != pCrsr || IsTableMode() )
+        ClearMark();
+
+    SwPosition& rPos = *pCrsr->GetPoint();
+
+    const SwGlblDocContent& rDelPos = *rArr[ nDelPos ];
+    ULONG nDelIdx = rDelPos.GetDocPos();
+    if( 1 == rArr.Count() )
+    {
+        // ein Node muss aber da bleiben!
+        rPos.nNode = nDelIdx - 1;
+        rPos.nContent.Assign( 0, 0 );
+
+        pDoc->AppendTxtNode( rPos );
+        ++nDelIdx;
+    }
+
+    switch( rDelPos.GetType() )
+    {
+    case GLBLDOC_UNKNOWN:
+        {
+            rPos.nNode = nDelIdx;
+            pCrsr->SetMark();
+            if( ++nDelPos < rArr.Count() )
+                rPos.nNode = rArr[ nDelPos ]->GetDocPos();
+            else
+                rPos.nNode = pDoc->GetNodes().GetEndOfContent();
+            rPos.nNode--;
+            if( !pDoc->DelFullPara( *pCrsr ) )
+                Delete();
+        }
+        break;
+
+    case GLBLDOC_TOXBASE:
+        {
+            SwTOXBaseSection* pTOX = (SwTOXBaseSection*)rDelPos.GetTOX();
+            pDoc->DeleteTOX( *pTOX, TRUE );
+        }
+        break;
+
+    case GLBLDOC_SECTION:
+        {
+            SwSectionFmt* pSectFmt = (SwSectionFmt*)rDelPos.GetSection()->GetFmt();
+            pDoc->DelSectionFmt( pSectFmt, TRUE );
+        }
+        break;
+    }
+
+    EndUndo( UNDO_END );
+    EndAllAction();
+    return TRUE;
+}
+
+BOOL SwEditShell::MoveGlobalDocContent( const SwGlblDocContents& rArr ,
+                                        USHORT nFromPos, USHORT nToPos,
+                                        USHORT nInsPos )
+{
+    SwDoc* pDoc = GetDoc();
+    if( !pDoc->IsGlobalDoc() ||
+        nFromPos >= rArr.Count() || nToPos > rArr.Count() ||
+        nInsPos > rArr.Count() || nFromPos >= nToPos ||
+        ( nFromPos <= nInsPos && nInsPos <= nToPos ) )
+        return FALSE;
+
+    SET_CURR_SHELL( this );
+    StartAllAction();
+
+    SwPaM* pCrsr = GetCrsr();
+    if( pCrsr->GetNext() != pCrsr || IsTableMode() )
+        ClearMark();
+
+    SwNodeRange aRg( pDoc->GetNodes(), rArr[ nFromPos ]->GetDocPos() );
+    if( nToPos < rArr.Count() )
+        aRg.aEnd = rArr[ nToPos ]->GetDocPos();
+    else
+        aRg.aEnd = pDoc->GetNodes().GetEndOfContent();
+
+    SwNodeIndex aInsPos( pDoc->GetNodes() );
+    if( nInsPos < rArr.Count() )
+        aInsPos = rArr[ nInsPos ]->GetDocPos();
+    else
+        aInsPos  = pDoc->GetNodes().GetEndOfContent();
+
+    BOOL bRet = pDoc->Move( aRg, aInsPos, DOC_MOVEALLFLYS );
+
+    EndAllAction();
+    return bRet;
+}
+
+BOOL SwEditShell::GotoGlobalDocContent( const SwGlblDocContent& rPos )
+{
+    SwDoc* pDoc = GetDoc();
+    if( !pDoc->IsGlobalDoc() )
+        return FALSE;
+
+    SET_CURR_SHELL( this );
+    SttCrsrMove();
+
+    SwPaM* pCrsr = GetCrsr();
+    if( pCrsr->GetNext() != pCrsr || IsTableMode() )
+        ClearMark();
+
+    SwPosition& rCrsrPos = *pCrsr->GetPoint();
+    rCrsrPos.nNode = rPos.GetDocPos();
+
+    SwCntntNode* pCNd = pDoc->GetNodes()[ rCrsrPos.nNode ]->GetCntntNode();
+    if( !pCNd )
+        pCNd = pDoc->GetNodes().GoNext( &rCrsrPos.nNode );
+
+    rCrsrPos.nContent.Assign( pCNd, 0 );
+
+    EndCrsrMove();
+    return TRUE;
+}
+
+// erzeuge Anhand der Outlines Teildokumente
+BOOL SwEditShell::GenerateGlobalDoc( const String& rPath,
+                                const SwTxtFmtColl* pSplitColl )
+{
+    SwWait aWait( *GetDoc()->GetDocShell(), TRUE );
+    return GetDoc()->GenerateGlobalDoc( rPath, pSplitColl );
+}
+
+/*  */
+
+SwGlblDocContent::SwGlblDocContent( ULONG nPos )
+{
+    eType = GLBLDOC_UNKNOWN;
+    PTR.pTOX = 0;
+    nDocPos = nPos;
+}
+
+SwGlblDocContent::SwGlblDocContent( const SwTOXBaseSection* pTOX )
+{
+    eType = GLBLDOC_TOXBASE;
+    PTR.pTOX = pTOX;
+
+    const SwSectionNode* pSectNd = pTOX->GetFmt()->GetSectionNode();
+    nDocPos = pSectNd ? pSectNd->GetIndex() : 0;
+}
+
+SwGlblDocContent::SwGlblDocContent( const SwSection* pSect )
+{
+    eType = GLBLDOC_SECTION;
+    PTR.pSect = pSect;
+
+    const SwSectionNode* pSectNd = pSect->GetFmt()->GetSectionNode();
+    nDocPos = pSectNd ? pSectNd->GetIndex() : 0;
+}
+
+
+
diff --git a/sw/source/core/edit/edglss.cxx b/sw/source/core/edit/edglss.cxx
new file mode 100644
index 000000000000..3770322e2515
--- /dev/null
+++ b/sw/source/core/edit/edglss.cxx
@@ -0,0 +1,442 @@
+/*************************************************************************
+ *
+ *  $RCSfile: edglss.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:18 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef SVTOOLS_URIHELPER_HXX
+#include 
+#endif
+#ifndef _CACHESTR_HXX //autogen
+#include 
+#endif
+
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _EDITSH_HXX
+#include 
+#endif
+#ifndef _EDIMP_HXX
+#include 
+#endif
+#ifndef _FRMFMT_HXX //autogen
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include        // fuer die UndoIds
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _TBLSEL_HXX
+#include        // fuers kopieren von Tabellen
+#endif
+#ifndef _SWTABLE_HXX
+#include       // fuers kopieren von Tabellen
+#endif
+#ifndef _SHELLIO_HXX
+#include       // SwTextBlocks
+#endif
+#ifndef _ACORRECT_HXX
+#include 
+#endif
+#ifndef _SWSWERROR_H
+#include         // SwTextBlocks
+#endif
+
+
+/******************************************************************************
+ *              jetzt mit einem verkappten Reader/Writer/Dokument
+ ******************************************************************************/
+
+
+
+void SwEditShell::InsertGlossary( SwTextBlocks& rGlossary, const String& rStr )
+{
+    StartAllAction();
+    GetDoc()->InsertGlossary( rGlossary, rStr, *GetCrsr(), this );
+    EndAllAction();
+}
+
+
+/******************************************************************************
+ *              aktuelle Selektion zum Textbaustein machen und ins
+ *          Textbausteindokument einfuegen, einschliesslich Vorlagen
+ ******************************************************************************/
+
+
+USHORT SwEditShell::MakeGlossary( SwTextBlocks& rBlks, const String& rName, const String& rShortName,
+                                    BOOL bSaveRelFile, BOOL bSaveRelNet,
+                                    const String* pOnlyTxt )
+{
+    SwDoc* pGDoc = rBlks.GetDoc();
+
+    // Bis es eine Option dafuer gibt, base URL loeschen
+    const String aOldURL( INetURLObject::GetBaseURL() );
+
+    if(bSaveRelFile)
+    {
+        INetURLObject::SetBaseURL( URIHelper::SmartRelToAbs(rBlks.GetFileName()));
+    }
+    else
+        INetURLObject::SetBaseURL( aEmptyStr );
+
+    USHORT nRet;
+
+    if( pOnlyTxt )
+        nRet = rBlks.PutText( rShortName, rName, *pOnlyTxt );
+    else
+    {
+        rBlks.ClearDoc();
+        if( rBlks.BeginPutDoc( rShortName, rName ) )
+        {
+            rBlks.GetDoc()->SetRedlineMode_intern( REDLINE_DELETE_REDLINES );
+            _CopySelToDoc( pGDoc );
+            rBlks.GetDoc()->SetRedlineMode_intern( 0 );
+            nRet = rBlks.PutDoc();
+        }
+        else
+            nRet = (USHORT) -1;
+    }
+
+    INetURLObject::SetBaseURL( aOldURL );
+    return nRet;
+}
+
+USHORT SwEditShell::SaveGlossaryDoc( SwTextBlocks& rBlock,
+                                    const String& rName,
+                                    const String& rShortName,
+                                    BOOL bSaveRelFile, BOOL bSaveRelNet,
+                                    BOOL bOnlyTxt )
+{
+    StartAllAction();
+
+    SwDoc* pGDoc = rBlock.GetDoc();
+    SwDoc* pDoc = GetDoc();
+
+    // Bis es eine Option dafuer gibt, base URL loeschen
+    const String aOldURL( INetURLObject::GetBaseURL() );
+
+    if(bSaveRelFile)
+    {
+        INetURLObject::SetBaseURL( URIHelper::SmartRelToAbs(rBlock.GetFileName()));
+    }
+    else
+        INetURLObject::SetBaseURL( aEmptyStr );
+
+    USHORT nRet = USHRT_MAX;
+
+    if( bOnlyTxt )
+    {
+        KillPams();
+
+        SwPaM* pCrsr = GetCrsr();
+
+        SwNodeIndex aStt( pDoc->GetNodes().GetEndOfExtras(), 1 );
+        SwCntntNode* pCntntNd = pDoc->GetNodes().GoNext( &aStt );
+        const SwNode* pNd = pCntntNd->FindTableNode();
+        if( !pNd )
+            pNd = pCntntNd;
+
+        pCrsr->GetPoint()->nNode = *pNd;
+        if( pNd == pCntntNd )
+            pCrsr->GetPoint()->nContent.Assign( pCntntNd, 0 );
+        pCrsr->SetMark();
+
+        // dann bis zum Ende vom Nodes Array
+        pCrsr->GetPoint()->nNode = pDoc->GetNodes().GetEndOfContent().GetIndex()-1;
+        pCntntNd = pCrsr->GetCntntNode();
+        if( pCntntNd )
+            pCrsr->GetPoint()->nContent.Assign( pCntntNd, pCntntNd->Len() );
+
+        String sBuf;
+        if( GetSelectedText( sBuf, GETSELTXT_PARABRK_TO_ONLYCR ) && sBuf.Len() )
+            nRet = rBlock.PutText( rShortName, rName, sBuf );
+    }
+    else
+    {
+        rBlock.ClearDoc();
+        if( rBlock.BeginPutDoc( rShortName, rName ) )
+        {
+            SwNodeIndex aStt( pDoc->GetNodes().GetEndOfExtras(), 1 );
+            SwCntntNode* pCntntNd = pDoc->GetNodes().GoNext( &aStt );
+            const SwNode* pNd = pCntntNd->FindTableNode();
+            if( !pNd ) pNd = pCntntNd;
+            SwPaM aCpyPam( *pNd );
+            aCpyPam.SetMark();
+
+            // dann bis zum Ende vom Nodes Array
+            aCpyPam.GetPoint()->nNode = pDoc->GetNodes().GetEndOfContent().GetIndex()-1;
+            pCntntNd = aCpyPam.GetCntntNode();
+            aCpyPam.GetPoint()->nContent.Assign( pCntntNd, pCntntNd->Len() );
+
+            aStt = pGDoc->GetNodes().GetEndOfExtras();
+            pCntntNd = pGDoc->GetNodes().GoNext( &aStt );
+            SwPosition aInsPos( aStt, SwIndex( pCntntNd ));
+            pDoc->Copy( aCpyPam, aInsPos );
+
+            nRet = rBlock.PutDoc();
+        }
+    }
+    INetURLObject::SetBaseURL( aOldURL );
+    EndAllAction();
+    return nRet;
+}
+
+/******************************************************************************
+ *                  kopiere alle Selectionen und das Doc
+ ******************************************************************************/
+
+
+BOOL SwEditShell::_CopySelToDoc( SwDoc* pInsDoc, SwNodeIndex* pSttNd )
+{
+    ASSERT( pInsDoc, "kein Ins.Dokument"  );
+
+    SwNodes& rNds = pInsDoc->GetNodes();
+
+    SwNodeIndex aIdx( rNds.GetEndOfContent(), -1 );
+    SwCntntNode * pNd = aIdx.GetNode().GetCntntNode();
+    SwPosition aPos( aIdx, SwIndex( pNd, pNd->Len() ));
+
+    // soll der Index auf Anfang returnt werden ?
+    if( pSttNd )
+    {
+        *pSttNd = aPos.nNode;
+        (*pSttNd)--;
+    }
+
+    BOOL bRet = FALSE;
+    SET_CURR_SHELL( this );
+
+    pInsDoc->LockExpFlds();
+
+    if( IsTableMode() )
+    {
+        // kopiere Teile aus einer Tabelle: lege eine Tabelle mit der Breite
+        // von der Originalen an und kopiere die selectierten Boxen.
+        // Die Groessen werden prozentual korrigiert.
+
+        // lasse ueber das Layout die Boxen suchen
+        SwTableNode* pTblNd;
+        SwSelBoxes aBoxes;
+        GetTblSel( *this, aBoxes );
+        if( aBoxes.Count() && 0 != (pTblNd = (SwTableNode*)aBoxes[0]
+            ->GetSttNd()->FindTableNode() ))
+        {
+            // teste ob der TabellenName kopiert werden kann
+            BOOL bCpyTblNm = aBoxes.Count() == pTblNd->GetTable().GetTabSortBoxes().Count();
+            if( bCpyTblNm )
+            {
+                const String& rTblName = pTblNd->GetTable().GetFrmFmt()->GetName();
+                const SwFrmFmts& rTblFmts = *pInsDoc->GetTblFrmFmts();
+                for( USHORT n = rTblFmts.Count(); n; )
+                    if( rTblFmts[ --n ]->GetName() == rTblName )
+                    {
+                        bCpyTblNm = FALSE;
+                        break;
+                    }
+            }
+            bRet = pInsDoc->InsCopyOfTbl( aPos, aBoxes, 0, bCpyTblNm, FALSE );
+        }
+        else
+            bRet = FALSE;
+    }
+    else
+    {
+        FOREACHPAM_START(this)
+
+            if( !PCURCRSR->HasMark() )
+            {
+                if( 0 != (pNd = PCURCRSR->GetCntntNode()) && !pNd->GetTxtNode() )
+                {
+                    PCURCRSR->SetMark();
+                    PCURCRSR->Move( fnMoveForward, fnGoCntnt );
+                    bRet |= GetDoc()->Copy( *PCURCRSR, aPos );
+                    PCURCRSR->Exchange();
+                    PCURCRSR->DeleteMark();
+                }
+            }
+            else
+                bRet |= GetDoc()->Copy( *PCURCRSR, aPos );
+
+        FOREACHPAM_END()
+    }
+
+    pInsDoc->UnlockExpFlds();
+    if( !pInsDoc->IsExpFldsLocked() )
+        pInsDoc->UpdateExpFlds();
+
+    // die gemerkte Node-Position wieder auf den richtigen Node
+    if( bRet && pSttNd )
+        (*pSttNd)++;
+
+
+    return bRet;
+}
+
+/*------------------------------------------------------------------------
+ Beschreibung:  Text innerhalb der Selektion erfragen
+ Returnwert:    liefert FALSE, wenn der selektierte Bereich
+                zu gross ist, um in den Stringpuffer kopiert zu werden.
+------------------------------------------------------------------------*/
+
+BOOL SwEditShell::GetSelectedText( String &rBuf, int nHndlParaBrk )
+{
+    BOOL bRet = FALSE;
+    GetCrsr();  // ggfs. alle Cursor erzeugen lassen
+    if( IsSelOnePara() )
+    {
+        rBuf = GetSelTxt();
+        if( GETSELTXT_PARABRK_TO_BLANK == nHndlParaBrk )
+        {
+            xub_StrLen nPos = 0;
+            while( STRING_NOTFOUND !=
+                ( nPos = rBuf.SearchAndReplace( 0x0a, ' ', nPos )) )
+                ;
+        }
+        else if( IsSelFullPara() &&
+            GETSELTXT_PARABRK_TO_ONLYCR != nHndlParaBrk )
+        {
+#if defined(MAC)
+                rBuf += '\015';
+#elif defined(UNX)
+                rBuf += '\012';
+#else
+                rBuf += String::CreateFromAscii(
+                            RTL_CONSTASCII_STRINGPARAM( "\015\012" ));
+#endif
+        }
+        bRet = TRUE;
+    }
+    else if( IsSelection() )
+    {
+        SvCacheStream aStream(20480);
+        WriterRef xWrt;
+        SwIoSystem::GetWriter( String::CreateFromAscii( FILTER_ANSI ), xWrt );
+        if( xWrt.Is() )
+        {
+                // Selektierte Bereiche in ein ASCII Dokument schreiben
+            SwWriter aWriter( aStream, *this);
+            xWrt->SetShowProgress( FALSE );
+
+            switch( nHndlParaBrk )
+            {
+            case GETSELTXT_PARABRK_TO_BLANK:
+                xWrt->bASCII_ParaAsBlanc = TRUE;
+                xWrt->bASCII_NoLastLineEnd = TRUE;
+                break;
+
+            case GETSELTXT_PARABRK_TO_ONLYCR:
+                xWrt->bASCII_ParaAsCR = TRUE;
+                xWrt->bASCII_NoLastLineEnd = TRUE;
+                break;
+            }
+
+            //JP 09.05.00: write as UNICODE ! (and not as ANSI)
+            SwAsciiOptions aAsciiOpt( xWrt->GetAsciiOptions() );
+            aAsciiOpt.SetCharSet( RTL_TEXTENCODING_UCS2 );
+            xWrt->SetAsciiOptions( aAsciiOpt );
+            xWrt->bUCS2_WithStartChar = FALSE;
+
+            long lLen;
+            if( !IsError( aWriter.Write( xWrt ) ) &&
+                STRING_MAXLEN > (( lLen  = aStream.GetSize() )
+                                        / sizeof( sal_Unicode )) + 1 )
+            {
+                aStream << '\0';
+
+                const sal_Unicode *p = (sal_Unicode*)aStream.GetBuffer();
+                if( p )
+                    rBuf = p;
+                else
+                {
+                    sal_Unicode* pStrBuf = rBuf.AllocBuffer( xub_StrLen(
+                                    ( lLen / sizeof( sal_Unicode )) + 1 ) );
+                    aStream.Seek( 0 );
+                    aStream.ResetError();
+                    aStream.Read( pStrBuf, lLen );
+                    pStrBuf[ lLen ] = '\0';
+                }
+            }
+        }
+    }
+
+    return TRUE;
+}
+
+
+
+
+
diff --git a/sw/source/core/edit/editsh.cxx b/sw/source/core/edit/editsh.cxx
new file mode 100644
index 000000000000..8b0751db3c84
--- /dev/null
+++ b/sw/source/core/edit/editsh.cxx
@@ -0,0 +1,1111 @@
+/*************************************************************************
+ *
+ *  $RCSfile: editsh.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:18 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _LIST_HXX //autogen
+#include 
+#endif
+#ifndef _URLOBJ_HXX //autogen
+#include 
+#endif
+#ifndef _VCL_CMDEVT_HXX //autogen
+#include 
+#endif
+#ifndef _IPOBJ_HXX //autogen
+#include 
+#endif
+#ifndef _SCH_DLL_HXX //autogen
+#include 
+#endif
+#ifndef _UNOTOOLS_CHARCLASS_HXX
+#include 
+#endif
+
+#ifndef _SWWAIT_HXX
+#include 
+#endif
+#ifndef _FMTSRND_HXX //autogen
+#include 
+#endif
+#ifndef _FMTINFMT_HXX //autogen
+#include 
+#endif
+#ifndef _TXTINET_HXX //autogen
+#include 
+#endif
+#ifndef _FRMFMT_HXX //autogen
+#include 
+#endif
+#ifndef _CHARFMT_HXX //autogen
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _FINDER_HXX //autogen
+#include 
+#endif
+#ifndef _EDITSH_HXX
+#include 
+#endif
+#ifndef _FRAME_HXX
+#include 
+#endif
+#ifndef _CNTFRM_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _NODE_HXX
+#include              // fuer GetSectionLevel()
+#endif
+#ifndef _NDTXT_HXX
+#include             // fuer SwTxtNode
+#endif
+#ifndef _GRFATR_HXX
+#include 
+#endif
+#ifndef _FLYFRM_HXX
+#include 
+#endif
+#ifndef _SWTABLE_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include            // UNDO_START, UNDO_END
+#endif
+#ifndef _ERRHDL_HXX
+#include 
+#endif
+#ifndef _CALC_HXX
+#include 
+#endif
+#ifndef _EDIMP_HXX
+#include 
+#endif
+#ifndef _NDGRF_HXX
+#include 
+#endif
+#ifndef _NDOLE_HXX
+#include 
+#endif
+#ifndef _TXTFRM_HXX
+#include 
+#endif
+#ifndef _ROOTFRM_HXX
+#include 
+#endif
+#ifndef _EXTINPUT_HXX
+#include 
+#endif
+
+
+SV_IMPL_PTRARR(SwGetINetAttrs, SwGetINetAttr*)
+
+/******************************************************************************
+ *                      void SwEditShell::Insert(char c)
+ ******************************************************************************/
+
+
+void SwEditShell::Insert( sal_Unicode c )
+{
+    StartAllAction();
+    FOREACHPAM_START(this)
+
+        if( !GetDoc()->Insert(*PCURCRSR, c) )
+            ASSERT( FALSE, "Doc->Insert(c) failed." );
+
+        SaveTblBoxCntnt( PCURCRSR->GetPoint() );
+
+    FOREACHPAM_END()
+
+    EndAllAction();
+}
+
+
+/******************************************************************************
+ *                void SwEditShell::Insert(const String &rStr)
+ ******************************************************************************/
+
+
+void SwEditShell::Insert(const String &rStr)
+{
+    StartAllAction();
+    FOREACHPAM_START(this)
+        //OPT: GetSystemCharSet
+        if( !GetDoc()->Insert( *PCURCRSR, rStr ) )
+            ASSERT( FALSE, "Doc->Insert(Str) failed." );
+
+        SaveTblBoxCntnt( PCURCRSR->GetPoint() );
+
+    FOREACHPAM_END()
+    EndAllAction();
+}
+
+
+/******************************************************************************
+ *              void SwEditShell::Overwrite(const String &rStr)
+ ******************************************************************************/
+
+
+void SwEditShell::Overwrite(const String &rStr)
+{
+    StartAllAction();
+    FOREACHPAM_START(this)
+        if( !GetDoc()->Overwrite(*PCURCRSR, rStr ) )
+            ASSERT( FALSE, "Doc->Overwrite(Str) failed." );
+        SaveTblBoxCntnt( PCURCRSR->GetPoint() );
+    FOREACHPAM_END()
+    EndAllAction();
+}
+
+
+/******************************************************************************
+ *                      long SwEditShell::SplitNode()
+ ******************************************************************************/
+
+long SwEditShell::SplitNode( BOOL bAutoFormat, BOOL bCheckTableStart )
+{
+    StartAllAction();
+    GetDoc()->StartUndo();
+
+    FOREACHPAM_START(this)
+        // eine Tabellen Zelle wird jetzt zu einer normalen Textzelle!
+        GetDoc()->ClearBoxNumAttrs( PCURCRSR->GetPoint()->nNode );
+        GetDoc()->SplitNode( *PCURCRSR->GetPoint(), bCheckTableStart );
+    FOREACHPAM_END()
+
+    GetDoc()->EndUndo();
+
+    if( bAutoFormat )
+        AutoFmtBySplitNode();
+
+    ClearTblBoxCntnt();
+
+    EndAllAction();
+    return(1L);
+}
+
+/******************************************************************************
+ *        liefert einen Pointer auf einen SwGrfNode; dieser wird von
+ *              GetGraphic() und GetGraphicSize() verwendet.
+ ******************************************************************************/
+
+
+SwGrfNode * SwEditShell::_GetGrfNode() const
+{
+    SwGrfNode *pGrfNode = 0;
+    SwPaM* pCrsr = GetCrsr();
+    if( !pCrsr->HasMark() ||
+        pCrsr->GetPoint()->nNode == pCrsr->GetMark()->nNode )
+        pGrfNode = pCrsr->GetPoint()->nNode.GetNode().GetGrfNode();
+
+    ASSERT( pGrfNode, "ist keine Graphic!!" );
+    return pGrfNode;
+}
+/******************************************************************************
+ *      liefert Pointer auf eine Graphic, wenn CurCrsr->GetPoint() auf
+ *           einen SwGrfNode zeigt (und GetMark nicht gesetzt ist
+ *                   oder auf die gleiche Graphic zeigt)
+ ******************************************************************************/
+
+const Graphic &SwEditShell::GetGraphic( BOOL bWait ) const
+{
+    SwGrfNode *pGrfNode = _GetGrfNode();
+    const Graphic& rGrf = pGrfNode->GetGrf();
+    if( rGrf.IsSwapOut() ||
+        ( pGrfNode->IsLinkedFile() && GRAPHIC_DEFAULT == rGrf.GetType() ) )
+    {
+#ifndef PRODUCT
+        ASSERT( pGrfNode->SwapIn( bWait ) || !bWait, "Grafik konnte nicht geladen werden" );
+#else
+        pGrfNode->SwapIn( bWait );
+#endif
+    }
+    return rGrf;
+}
+
+BOOL SwEditShell::IsGrfSwapOut( BOOL bOnlyLinked ) const
+{
+    SwGrfNode *pGrfNode = _GetGrfNode();
+    return pGrfNode &&
+        ( ( bOnlyLinked && ( pGrfNode->IsLinkedFile() &&
+// Code for the new GraphicObject
+#ifdef USE_GRFOBJECT
+            GRAPHIC_DEFAULT == pGrfNode->GetGrfObj().GetType() )) ||
+            pGrfNode->GetGrfObj().IsSwappedOut() );
+#else
+            GRAPHIC_DEFAULT == pGrfNode->GetGrf().GetType() )) ||
+            pGrfNode->GetGrf().IsSwapOut() );
+#endif
+}
+
+const GraphicObject& SwEditShell::GetGraphicObj() const
+{
+    SwGrfNode *pGrfNode = _GetGrfNode();
+// Code for the new GraphicObject
+#ifdef USE_GRFOBJECT
+    return pGrfNode->GetGrfObj();
+#else
+    const Graphic& rGrf = pGrfNode->GetGrf();
+    return GraphicObject( rGrf );
+#endif
+}
+
+USHORT SwEditShell::GetGraphicType() const
+{
+// Code for the new GraphicObject
+#ifdef USE_GRFOBJECT
+    SwGrfNode *pGrfNode = _GetGrfNode();
+    return pGrfNode->GetGrfObj().GetType();
+#else
+    const Graphic& rGrf = GetGraphic( FALSE );
+    return rGrf.GetType();
+#endif
+}
+
+/******************************************************************************
+ *      liefert die Groesse der Graphic, wenn CurCrsr->GetPoint() auf
+ *          einen SwGrfNode zeigt (und GetMark nicht gesetzt ist
+ *                  oder auf die gleiche Graphic zeigt)
+ ******************************************************************************/
+
+BOOL SwEditShell::GetGrfSize(Size& rSz) const
+{
+    SwNoTxtNode* pNoTxtNd;
+    SwPaM* pCurCrsr = GetCrsr();
+    if( ( !pCurCrsr->HasMark()
+         || pCurCrsr->GetPoint()->nNode == pCurCrsr->GetMark()->nNode )
+         && 0 != ( pNoTxtNd = pCurCrsr->GetNode()->GetNoTxtNode() ) )
+    {
+        rSz = pNoTxtNd->GetTwipSize();
+        return TRUE;
+    }
+    return FALSE;
+
+}
+/******************************************************************************
+ *      erneutes Einlesen, falls Graphic nicht Ok ist. Die
+ *      aktuelle wird durch die neue ersetzt.
+ ******************************************************************************/
+
+void SwEditShell::ReRead( const String& rGrfName, const String& rFltName,
+                            const Graphic* pGraphic )
+{
+    StartAllAction();
+    pDoc->ReRead( *GetCrsr(), rGrfName, rFltName, pGraphic );
+    EndAllAction();
+}
+
+
+/******************************************************************************
+ *  liefert den Namen und den FilterNamen einer Graphic, wenn der Cursor
+ *  auf einer Graphic steht
+ *  Ist ein String-Ptr != 0 dann returne den entsp. Namen
+ ******************************************************************************/
+
+
+void SwEditShell::GetGrfNms( String* pGrfName, String* pFltName,
+                            const SwFlyFrmFmt* pFmt ) const
+{
+    ASSERT( pGrfName || pFltName, "was wird denn nun erfragt?" );
+    if( pFmt )
+        GetDoc()->GetGrfNms( *pFmt, pGrfName, pFltName );
+    else
+    {
+        SwGrfNode *pGrfNode = _GetGrfNode();
+        if( pGrfNode->IsLinkedFile() )
+            pGrfNode->GetFileFilterNms( pGrfName, pFltName );
+    }
+}
+
+
+// alternativen Text abfragen/setzen
+const String& SwEditShell::GetAlternateText() const
+{
+    SwPaM* pCrsr = GetCrsr();
+    const SwNoTxtNode* pNd;
+    if( !pCrsr->HasMark() && 0 != ( pNd = pCrsr->GetNode()->GetNoTxtNode()) )
+        return pNd->GetAlternateText();
+
+    return aEmptyStr;
+}
+
+
+void SwEditShell::SetAlternateText( const String& rTxt )
+{
+    SwPaM* pCrsr = GetCrsr();
+    SwNoTxtNode* pNd;
+    if( !pCrsr->HasMark() && 0 != ( pNd = pCrsr->GetNode()->GetNoTxtNode()) )
+        pNd->SetAlternateText( rTxt );
+}
+
+
+const PolyPolygon *SwEditShell::GetGraphicPolygon() const
+{
+    SwNoTxtNode *pNd = GetCrsr()->GetNode()->GetNoTxtNode();
+    return pNd->HasContour();
+}
+
+
+void SwEditShell::SetGraphicPolygon( const PolyPolygon *pPoly )
+{
+    SwNoTxtNode *pNd = GetCrsr()->GetNode()->GetNoTxtNode();
+    StartAllAction();
+    pNd->SetContour( pPoly );
+    SwFlyFrm *pFly = (SwFlyFrm*)pNd->GetFrm()->GetUpper();
+    const SwFmtSurround &rSur = pFly->GetFmt()->GetSurround();
+    pFly->GetFmt()->SwModify::Modify( (SwFmtSurround*)&rSur,
+                                      (SwFmtSurround*)&rSur );
+    GetDoc()->SetModified();
+    EndAllAction();
+}
+
+
+/******************************************************************************
+ *      liefert Pointer auf ein SvInPlaceObjectRef, wenn CurCrsr->GetPoint() auf
+ *          einen SwOLENode zeigt (und GetMark nicht gesetzt ist
+ *                  oder auf das gleiche SvInPlaceObjectRef zeigt)
+ *      besorgt den Pointer vom Doc wenn das Objekt per Namen gesucht werden
+ *      soll
+ ******************************************************************************/
+
+
+SvInPlaceObjectRef SwEditShell::GetOLEObj() const
+{
+    ASSERT(  CNT_OLE == GetCntType(), "GetOLEObj: kein OLENode." );
+    ASSERT( !GetCrsr()->HasMark() ||
+            (GetCrsr()->HasMark() &&
+                GetCrsr()->GetPoint()->nNode == GetCrsr()->GetMark()->nNode),
+            "GetOLEObj: kein OLENode." );
+
+    SwOLENode *pOLENode = GetCrsr()->GetNode()->GetOLENode();
+    ASSERT( pOLENode, "GetOLEObj: kein OLENode." );
+    SwOLEObj& rOObj = pOLENode->GetOLEObj();
+    return rOObj.GetOleRef();
+}
+
+
+BOOL SwEditShell::HasOLEObj( const String &rName ) const
+{
+    SwStartNode *pStNd;
+    SwNodeIndex aIdx( *GetNodes().GetEndOfAutotext().StartOfSectionNode(), 1 );
+    while ( 0 != (pStNd = aIdx.GetNode().GetStartNode()) )
+    {
+        aIdx++;
+        SwNode& rNd = aIdx.GetNode();
+        if( rNd.IsOLENode() &&
+            rName == ((SwOLENode&)rNd).GetChartTblName() &&
+            ((SwOLENode&)rNd).GetFrm() )
+            return TRUE;
+
+        aIdx.Assign( *pStNd->EndOfSectionNode(), + 1 );
+    }
+    return FALSE;
+}
+
+
+void SwEditShell::SetChartName( const String &rName )
+{
+    SwOLENode *pONd = GetCrsr()->GetNode()->GetOLENode();
+    ASSERT( pONd, "ChartNode not found" );
+    pONd->SetChartTblName( rName );
+}
+
+const String& SwEditShell::GetChartName( SvInPlaceObject* pObj )
+{
+    if( pObj )
+    {
+        SwClientIter aIter( *(SwModify*)GetDoc()->GetDfltGrfFmtColl() );
+        SwClient *pCli;
+        if( 0 != (pCli = aIter.First( TYPE(SwCntntNode) )) )
+            do{
+                if( ((SwCntntNode*)pCli)->IsOLENode() &&
+                    ((SwOLENode*)pCli)->GetOLEObj().IsOleRef() &&
+                    pObj == &((SwOLENode*)pCli)->GetOLEObj().GetOleRef() )
+                {
+                    return ((SwOLENode*)pCli)->GetChartTblName();
+                }
+            } while ( 0 != (pCli = aIter.Next()) );
+    }
+    else
+    {
+        SwOLENode *pONd = GetCrsr()->GetNode()->GetOLENode();
+        if( pONd )
+            return pONd->GetChartTblName();
+    }
+
+    return aEmptyStr;
+}
+
+void SwEditShell::UpdateChartData( const String &rName, SchMemChart *&pData )
+{
+    //Fuer das Update brauchen wir die SwTable. Also muessen wir ggf. die
+    //gewuenschte Table anspringen.
+    String sSelection;
+    const SwTableNode *pTblNd = IsCrsrInTbl();
+    if( !pTblNd || rName != pTblNd->GetTable().GetFrmFmt()->GetName() )
+    {
+        Push();
+        GotoTable( rName );
+        pTblNd = IsCrsrInTbl();
+        Pop( FALSE );
+    }
+    else if( IsTableMode() )
+        sSelection = GetBoxNms();
+
+    if( pTblNd )
+        pData = pTblNd->GetTable().UpdateData( pData, &sSelection );
+}
+
+
+void SwEditShell::UpdateCharts( const String &rName )
+{
+    GetDoc()->UpdateCharts( rName );
+}
+
+
+/******************************************************************************
+ *      Aenderung des Tabellennamens
+ ******************************************************************************/
+
+void SwEditShell::SetTableName( SwFrmFmt& rTblFmt, const String &rNewName )
+{
+    GetDoc()->SetTableName( rTblFmt, rNewName );
+}
+
+#pragma optimize("",on)
+
+// erfragen des akt. Wortes
+
+
+String SwEditShell::GetCurWord()
+{
+    String aString( GetDoc()->GetCurWord(*GetCrsr()) );
+    aString.EraseAllChars('\xff');
+    return aString;
+}
+
+/****************************************************************************
+ *           void SwEditShell::UpdateDocStat( SwDocStat& rStat )
+ ****************************************************************************/
+
+
+void SwEditShell::UpdateDocStat( SwDocStat& rStat )
+{
+    StartAllAction();
+    GetDoc()->UpdateDocStat( rStat, GetNumPages() );
+    EndAllAction();
+}
+
+// OPT: eddocinl.cxx
+
+
+const SfxDocumentInfo* SwEditShell::GetInfo() const
+{
+    return GetDoc()->GetInfo();
+}
+
+
+    // returne zum Namen die im Doc gesetzte Referenz
+const SwFmtRefMark* SwEditShell::GetRefMark( const String& rName ) const
+{
+    return GetDoc()->GetRefMark( rName );
+}
+
+    // returne die Namen aller im Doc gesetzten Referenzen
+USHORT SwEditShell::GetRefMarks( SvStringsDtor* pStrings ) const
+{
+    return GetDoc()->GetRefMarks( pStrings );
+}
+
+/******************************************************************************
+ *          DropCap-SS
+ ******************************************************************************/
+
+
+String SwEditShell::GetDropTxt( const USHORT nChars ) const
+{
+    String aTxt;
+    SwPaM* pCrsr = GetCrsr();
+    if( pCrsr->GetPoint()->nNode.GetIndex() ==
+        pCrsr->GetMark()->nNode.GetIndex() )
+    {
+        SwTxtNode* pTxtNd = pCrsr->GetNode()->GetTxtNode();
+        if( pTxtNd )
+        {
+            xub_StrLen nDropLen = pTxtNd->GetDropLen( nChars );
+            if( nDropLen )
+                aTxt = pTxtNd->GetTxt().Copy( 0, nDropLen );
+        }
+    }
+    return aTxt;
+}
+
+
+void SwEditShell::ReplaceDropTxt( const String &rStr )
+{
+    SwPaM* pCrsr = GetCrsr();
+    if( pCrsr->GetPoint()->nNode == pCrsr->GetMark()->nNode &&
+        pCrsr->GetNode()->GetTxtNode()->IsTxtNode() )
+    {
+        StartAllAction();
+
+        const SwNodeIndex& rNd = pCrsr->GetPoint()->nNode;
+        SwPaM aPam( rNd, rStr.Len(), rNd, 0 );
+        if( !GetDoc()->Overwrite( aPam, rStr ) )
+        {
+            ASSERT( FALSE, "Doc->Overwrite(Str) failed." );
+        }
+
+        EndAllAction();
+    }
+}
+
+/******************************************************************************
+ *  Methode     :
+ *  Beschreibung:
+ *  Erstellt    :   OK 25.04.94 13:45
+ *  Aenderung   :
+ ******************************************************************************/
+
+String SwEditShell::Calculate()
+{
+    String  aFormel;                    // die entgueltige Formel
+    SwPaM   *pPaMLast = (SwPaM*)GetCrsr()->GetNext(),
+            *pPaM = pPaMLast;           // die Pointer auf Cursor
+    SwCalc  aCalc( *GetDoc() );
+    const CharClass& rCC = GetAppCharClass();
+
+    do {
+        SwTxtNode* pTxtNd = pPaM->GetNode()->GetTxtNode();
+        if(pTxtNd)
+        {
+            const SwPosition *pStart = pPaM->Start(), *pEnd = pPaM->End();
+            xub_StrLen nStt = pStart->nContent.GetIndex();
+            String aStr = pTxtNd->GetExpandTxt( nStt, pEnd->nContent.
+                                                GetIndex() - nStt );
+
+            rCC.toLower( aStr );
+
+            sal_Unicode ch;
+            BOOL    bValidFlds = FALSE;
+            xub_StrLen nPos = 0;
+
+            while( nPos < aStr.Len() )
+            {
+                ch = aStr.GetChar( nPos++ );
+                if( rCC.isLetter( aStr, nPos-1 ) || ch == '_' )
+                {
+                    xub_StrLen nStt = nPos-1;
+                    while(  nPos < aStr.Len() &&
+                            0 != ( ch = aStr.GetChar( nPos++ )) &&
+                           (rCC.isLetterNumeric( aStr, nPos - 1 ) ||
+                               ch == '_'|| ch == '.' ))
+                        ;
+
+                    if( nPos < aStr.Len() )
+                        --nPos;
+
+                    String sVar( aStr.Copy( nStt, nPos - nStt ));
+                    if( !::FindOperator( sVar ) &&
+                        (::Find( sVar, aCalc.GetVarTable(),TBLSZ) ||
+                         aCalc.VarLook( sVar )) )
+                    {
+                        if( !bValidFlds )
+                        {
+                            GetDoc()->FldsToCalc( aCalc,
+                                                  pStart->nNode.GetIndex(),
+                                                  pStart->nContent.GetIndex() );
+                            bValidFlds = TRUE;
+                        }
+                        aFormel += aCalc.GetStrResult( aCalc.VarLook(
+                                                               sVar )->nValue );
+                    }
+                    else
+                        aFormel += sVar;
+                }
+                else
+                    aFormel += ch;
+            }
+        }
+    } while( pPaMLast != (pPaM = (SwPaM*)pPaM->GetNext()) );
+
+    return aCalc.GetStrResult( aCalc.Calculate(aFormel) );
+}
+
+
+SvxLinkManager& SwEditShell::GetLinkManager()
+{
+    return pDoc->GetLinkManager();
+}
+
+
+void *SwEditShell::GetIMapInventor() const
+{
+    //Als eindeutige Identifikation sollte der Node, auf dem der Crsr steht
+    //genuegen.
+    return (void*)GetCrsr()->GetNode();
+}
+
+
+Graphic SwEditShell::GetIMapGraphic( BOOL bWait ) const
+{
+    //Liefert immer eine Graphic, wenn der Crsr in einem Fly steht.
+    SET_CURR_SHELL( (ViewShell*)this );
+    Graphic aRet;
+    SwPaM* pCrsr = GetCrsr();
+    if ( !pCrsr->HasMark() )
+    {
+        SwNode *pNd =pCrsr->GetNode();
+        if( pNd->IsGrfNode() )
+        {
+            const Graphic& rGrf = ((SwGrfNode*)pNd)->GetGrf();
+            if( rGrf.IsSwapOut() || ( ((SwGrfNode*)pNd)->IsLinkedFile() &&
+                                    GRAPHIC_DEFAULT == rGrf.GetType() ) )
+            {
+#ifndef PRODUCT
+                ASSERT( ((SwGrfNode*)pNd)->SwapIn( bWait )||!bWait, "Grafik konnte nicht geladen werden" );
+#else
+                ((SwGrfNode*)pNd)->SwapIn( bWait );
+#endif
+            }
+            aRet = rGrf;
+        }
+        else if ( pNd->IsOLENode() )
+        {
+            SvInPlaceObjectRef aRef = GetOLEObj();
+            GDIMetaFile* pPic = 0;
+            SvData aData( FORMAT_GDIMETAFILE );
+            if ( aRef->GetData( &aData ) )
+                aData.GetData( &pPic, TRANSFER_REFERENCE );
+            if ( pPic )
+                aRet = *pPic;
+        }
+        else
+            aRet = pNd->GetCntntNode()->GetFrm()->FindFlyFrm()->GetFmt()->MakeGraphic();
+    }
+    return aRet;
+}
+
+
+BOOL SwEditShell::InsertURL( const SwFmtINetFmt& rFmt, const String& rStr, BOOL bKeepSelection )
+{
+    // URL und Hinweistext (direkt oder via Selektion) notwendig
+    if( !rFmt.GetValue().Len() ||   ( !rStr.Len() && !HasSelection() ) )
+        return FALSE;
+    StartAllAction();
+    GetDoc()->StartUndo( UIUNDO_INSERT_URLTXT);
+    BOOL bInsTxt = TRUE;
+
+    if( rStr.Len() )
+    {
+        SwPaM* pCrsr = GetCrsr();
+        if( pCrsr->HasMark() && *pCrsr->GetPoint() != *pCrsr->GetMark() )
+        {
+            // Selection vorhanden, MehrfachSelektion?
+            BOOL bDelTxt = TRUE;
+            if( pCrsr->GetNext() == pCrsr )
+            {
+                // einfach Selection -> Text ueberpruefen
+                String sTxt( GetSelTxt() );
+                sTxt.EraseTrailingChars();
+                if( sTxt == rStr )
+                    bDelTxt = bInsTxt = FALSE;
+            }
+            else if( rFmt.GetValue() == rStr )      // Name und URL gleich?
+                bDelTxt = bInsTxt = FALSE;
+
+            if( bDelTxt )
+                Delete();
+        }
+        else if( pCrsr->GetNext() != pCrsr && rFmt.GetValue() == rStr )
+            bInsTxt = FALSE;
+
+        if( bInsTxt )
+        {
+            Insert( rStr );
+            SetMark();
+            ExtendSelection( FALSE, rStr.Len() );
+        }
+    }
+    else
+        bInsTxt = FALSE;
+
+    SetAttr( rFmt );
+    if (bInsTxt && !IsCrsrPtAtEnd())
+        SwapPam();
+    if(!bKeepSelection)
+        ClearMark();
+    if( bInsTxt )
+        DontExpandFmt();
+    GetDoc()->EndUndo( UIUNDO_INSERT_URLTXT );
+    EndAllAction();
+    return TRUE;
+}
+
+
+USHORT SwEditShell::GetINetAttrs( SwGetINetAttrs& rArr )
+{
+    if( rArr.Count() )
+        rArr.DeleteAndDestroy( 0, rArr.Count() );
+
+    const SwTxtNode* pTxtNd;
+    const SwCharFmts* pFmts = GetDoc()->GetCharFmts();
+    for( USHORT n = pFmts->Count(); 1 < n; )
+    {
+        SwClientIter aIter( *(*pFmts)[  --n ] );
+
+        for( SwClient* pFnd = aIter.First(TYPE( SwTxtINetFmt ));
+                pFnd; pFnd = aIter.Next() )
+            if( 0 != ( pTxtNd = ((SwTxtINetFmt*)pFnd)->GetpTxtNode()) &&
+                pTxtNd->GetNodes().IsDocNodes() )
+            {
+                SwTxtINetFmt& rAttr = *(SwTxtINetFmt*)pFnd;
+                String sTxt( pTxtNd->GetExpandTxt( *rAttr.GetStart(),
+                                    *rAttr.GetEnd() - *rAttr.GetStart() ) );
+
+                sTxt.EraseAllChars( 0x0a );
+                sTxt.EraseLeadingChars().EraseTrailingChars();
+
+                if( sTxt.Len() )
+                {
+                    SwGetINetAttr* pNew = new SwGetINetAttr( sTxt, rAttr );
+                    rArr.C40_INSERT( SwGetINetAttr, pNew, rArr.Count() );
+                }
+            }
+    }
+    return rArr.Count();
+}
+
+
+    // ist der Cursor in eine INetAttribut, dann wird das komplett
+    // geloescht; inclusive des Hinweistextes (wird beim Drag&Drop gebraucht)
+BOOL SwEditShell::DelINetAttrWithText()
+{
+    BOOL bRet = SelectTxtAttr( RES_TXTATR_INETFMT );
+    if( bRet )
+        DeleteSel( *GetCrsr() );
+    return bRet;
+}
+
+
+// setzen an den Textzeichenattributen das DontExpand-Flag
+BOOL SwEditShell::DontExpandFmt()
+{
+    BOOL bRet = FALSE;
+    if( !IsTableMode() && GetDoc()->DontExpandFmt( *GetCrsr()->GetPoint() ))
+    {
+        bRet = TRUE;
+        CallChgLnk();
+    }
+    return bRet;
+}
+
+
+SvNumberFormatter* SwEditShell::GetNumberFormatter()
+{
+    return GetDoc()->GetNumberFormatter();
+}
+
+
+void SwEditShell::Summary( SwDoc* pExtDoc, BYTE nLevel, BYTE nPara, BOOL bImpress )
+{
+    GetDoc()->Summary( pExtDoc, nLevel, nPara, bImpress );
+}
+
+BOOL SwEditShell::RemoveInvisibleContent()
+{
+    StartAllAction();
+    BOOL bRet = GetDoc()->RemoveInvisibleContent();
+    EndAllAction();
+    return bRet;
+}
+
+BOOL SwEditShell::EmbedAllLinks()
+{
+    StartAllAction();
+    BOOL bRet = GetDoc()->EmbedAllLinks();
+    EndAllAction();
+    return bRet;
+}
+
+USHORT SwEditShell::GetLineCount( BOOL bActPos )
+{
+    USHORT nRet = 0;
+    CalcLayout();
+    SwPaM* pPam = GetCrsr();
+    SwNodeIndex& rPtIdx = pPam->GetPoint()->nNode;
+    SwNodeIndex aStart( rPtIdx );
+    SwCntntNode* pCNd;
+    SwCntntFrm *pCntFrm;
+    ULONG nTmpPos;
+
+    if( !bActPos )
+        aStart = 0;
+    else if( rPtIdx > ( nTmpPos = GetDoc()->GetNodes().GetEndOfExtras().GetIndex()) )
+        // BodyBereich => Start ist EndOfIcons + 1
+        aStart = nTmpPos + 1;
+    else
+    {
+        if( 0 != ( pCNd = pPam->GetCntntNode() ) &&
+            0 != ( pCntFrm = pCNd->GetFrm() ) )
+        {
+            const SwStartNode *pTmp;
+            if( pCntFrm->IsInFly() )                        // Fly
+                pTmp = pCNd->FindFlyStartNode();
+            else if( pCntFrm->IsInFtn() )                   // Footnote
+                pTmp = pCNd->FindFootnoteStartNode();
+            else
+            {                                               // Footer/Header
+                const USHORT nTyp = FRM_HEADER | FRM_FOOTER;
+                SwFrm* pFrm = pCntFrm;
+                while( pFrm && !(pFrm->GetType() & nTyp) )
+                    pFrm = pFrm->GetUpper();
+                ASSERT( pFrm, "Wo bin ich?" );
+                if( pFrm && ( pFrm->GetType() & FRM_FOOTER ) )
+                    pTmp = pCNd->FindFooterStartNode();
+                else
+                    pTmp = pCNd->FindHeaderStartNode();
+            }
+            ASSERT( pTmp, "Missing StartNode" );
+            aStart  = *pTmp;
+        }
+        ASSERT( pCNd && pCntFrm, "Missing Layout-Information" );
+    }
+
+    while( 0 != ( pCNd = GetDoc()->GetNodes().GoNextSection(
+                &aStart, TRUE, FALSE )) && ( !bActPos || aStart <= rPtIdx ) )
+    {
+        if( 0 != ( pCntFrm = pCNd->GetFrm() ) && pCntFrm->IsTxtFrm() )
+        {
+            xub_StrLen nActPos = bActPos && aStart == rPtIdx ?
+                pPam->GetPoint()->nContent.GetIndex() : USHRT_MAX;
+            nRet += ((SwTxtFrm*)pCntFrm)->GetLineCount( nActPos );
+        }
+    }
+    return nRet;
+}
+
+long SwEditShell::CompareDoc( const SwDoc& rDoc )
+{
+    StartAllAction();
+    GetDoc()->StartUndo();
+
+    long nRet = GetDoc()->CompareDoc( rDoc );
+
+    GetDoc()->EndUndo();
+    EndAllAction();
+
+    return nRet;
+}
+
+long SwEditShell::MergeDoc( const SwDoc& rDoc )
+{
+    StartAllAction();
+    GetDoc()->StartUndo();
+
+    long nRet = GetDoc()->MergeDoc( rDoc );
+
+    GetDoc()->EndUndo();
+    EndAllAction();
+
+    return nRet;
+}
+
+
+const SwFtnInfo& SwEditShell::GetFtnInfo() const
+{
+    return GetDoc()->GetFtnInfo();
+}
+
+void SwEditShell::SetFtnInfo(const SwFtnInfo& rInfo)
+{
+    StartAllAction();
+    SET_CURR_SHELL( this );
+    GetDoc()->SetFtnInfo(rInfo);
+    CallChgLnk();
+    EndAllAction();
+}
+
+const SwEndNoteInfo& SwEditShell::GetEndNoteInfo() const
+{
+    return GetDoc()->GetEndNoteInfo();
+}
+
+void SwEditShell::SetEndNoteInfo(const SwEndNoteInfo& rInfo)
+{
+    StartAllAction();
+    SET_CURR_SHELL( this );
+    GetDoc()->SetEndNoteInfo(rInfo);
+    EndAllAction();
+}
+
+const SwLineNumberInfo& SwEditShell::GetLineNumberInfo() const
+{
+    return GetDoc()->GetLineNumberInfo();
+}
+
+void SwEditShell::SetLineNumberInfo(const SwLineNumberInfo& rInfo)
+{
+    StartAllAction();
+    SET_CURR_SHELL( this );
+    GetDoc()->SetLineNumberInfo(rInfo);
+    AddPaintRect( GetLayout()->Frm() );
+    EndAllAction();
+}
+
+BOOL SwEditShell::GenerateHTMLDoc( const String& rPath,
+                                const SwTxtFmtColl* pSplitColl )
+{
+    SwWait aWait( *GetDoc()->GetDocShell(), TRUE );
+    return GetDoc()->GenerateHTMLDoc( rPath, pSplitColl );
+}
+
+USHORT SwEditShell::GetLinkUpdMode(BOOL bDocSettings) const
+{
+    return bDocSettings ? GetDoc()->_GetLinkUpdMode(): GetDoc()->GetLinkUpdMode();
+}
+
+void SwEditShell::SetLinkUpdMode( USHORT nMode )
+{
+    GetDoc()->SetLinkUpdMode( nMode );
+}
+
+
+// Schnittstelle fuer die TextInputDaten - ( fuer die Texteingabe
+// von japanischen/chinesischen Zeichen)
+SwExtTextInput* SwEditShell::CreateExtTextInput()
+{
+    return GetDoc()->CreateExtTextInput( *GetCrsr() );
+}
+
+void SwEditShell::DeleteExtTextInput( SwExtTextInput* pDel, BOOL bInsText )
+{
+    if( !pDel )
+    {
+        const SwPosition& rPos = *GetCrsr()->GetPoint();
+        pDel = GetDoc()->GetExtTextInput( rPos.nNode.GetNode(),
+                                          rPos.nContent.GetIndex() );
+    }
+
+    if( pDel )
+    {
+        SET_CURR_SHELL( this );
+        StartAllAction();
+        pDel->SetInsText( bInsText );
+        GetDoc()->DeleteExtTextInput( pDel );
+        EndAllAction();
+    }
+}
+
+SwExtTextInput* SwEditShell::GetExtTextInput() const
+{
+    const SwPosition& rPos = *GetCrsr()->GetPoint();
+    return GetDoc()->GetExtTextInput( rPos.nNode.GetNode(),
+                                         rPos.nContent.GetIndex() );
+}
+
+void SwEditShell::SetExtTextInputData( const CommandExtTextInputData& rData )
+{
+    const SwPosition& rPos = *GetCrsr()->GetPoint();
+    SwExtTextInput* pInput = GetDoc()->GetExtTextInput( rPos.nNode.GetNode()
+                                                /*, rPos.nContent.GetIndex()*/ );
+    if( pInput )
+    {
+        StartAllAction();
+        SET_CURR_SHELL( this );
+
+
+        if( !rData.IsOnlyCursorChanged() )
+            pInput->SetInputData( rData );
+        // Cursor positionieren:
+        const SwPosition& rStt = *pInput->Start();
+        xub_StrLen nNewCrsrPos = rStt.nContent.GetIndex() + rData.GetCursorPos();
+
+        // zwar unschoen aber was hilfts
+        long nDiff = nNewCrsrPos - rPos.nContent.GetIndex();
+        if( 0 > nDiff )
+            Left( (xub_StrLen)-nDiff );
+        else if( 0 < nDiff )
+            Right( (xub_StrLen)nDiff );
+
+        if( rData.IsCursorVisible() )
+            ShowCrsr();
+        else
+            HideCrsr();
+
+        EndAllAction();
+    }
+}
+
+
+
diff --git a/sw/source/core/edit/edlingu.cxx b/sw/source/core/edit/edlingu.cxx
new file mode 100644
index 000000000000..7a0b0610a84d
--- /dev/null
+++ b/sw/source/core/edit/edlingu.cxx
@@ -0,0 +1,961 @@
+/*************************************************************************
+ *
+ *  $RCSfile: edlingu.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:18 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _COMCORE_HRC
+#include 
+#endif
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _OFF_APP_HXX //autogen wg. OFF_APP
+#include 
+#endif
+#ifndef _LINGU_LNGPROPS_HHX_
+#include 
+#endif
+#ifndef _SV_MSGBOX_HXX
+#include 
+#endif
+#ifndef _UNO_LINGU_HXX
+#include 
+#endif
+
+#ifndef _SVX_LANGITEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _FMTHBSH_HXX //autogen
+#include 
+#endif
+#ifndef _CHARATR_HXX
+#include 
+#endif
+#ifndef _EDITSH_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _ROOTFRM_HXX
+#include       // SwRootFrm
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include        // fuer die UndoIds
+#endif
+#ifndef _NDTXT_HXX
+#include         // AdjHyphPos
+#endif
+#ifndef _VIEWOPT_HXX
+#include       // HyphStart/End
+#endif
+#ifndef _VISCRS_HXX
+#include        // SwShellCrsr
+#endif
+#ifndef _WRONG_HXX
+#include         // SwWrongList
+#endif
+#ifndef _SWCRSR_HXX
+#include        // SwCursor
+#endif
+#ifndef _MDIEXP_HXX
+#include        // Statusanzeige
+#endif
+#ifndef _STATSTR_HRC
+#include       // StatLine-String
+#endif
+
+#ifdef LINGU_STATISTIK
+#include        // SwLinguStat.Flush()
+#endif
+
+#ifndef S2U
+#define S2U(rString) rtl::OUString::createFromAscii(rString)
+#endif
+using namespace ::com::sun::star;
+
+/*************************************************************************
+ *                     class SwLinguIter
+ *************************************************************************/
+
+class SwLinguIter
+{
+    SwEditShell *pSh;
+    SwPosition  *pStart;
+    SwPosition  *pEnd;
+    SwPosition  *pCurr;
+    SwPosition  *pCurrX;
+    sal_uInt16 nCrsrCnt;
+public:
+    SwLinguIter();
+
+    inline SwEditShell *GetSh()             { return pSh; }
+    inline const SwEditShell *GetSh() const { return pSh; }
+
+    inline const SwPosition *GetEnd() const { return pEnd; }
+    inline void SetEnd( SwPosition* pNew ){ delete pEnd; pEnd = pNew; }
+
+    inline const SwPosition *GetStart() const { return pStart; }
+    inline void SetStart( SwPosition* pNew ){ delete pStart; pStart = pNew; }
+
+    inline const SwPosition *GetCurr() const { return pCurr; }
+    inline void SetCurr( SwPosition* pNew ){ delete pCurr; pCurr = pNew; }
+
+    inline const SwPosition *GetCurrX() const { return pCurrX; }
+    inline void SetCurrX( SwPosition* pNew ){ delete pCurrX; pCurrX = pNew; }
+
+    inline sal_uInt16& GetCrsrCnt(){ return nCrsrCnt; }
+
+    // Der UI-Bauchladen:
+    void _Start( SwEditShell *pSh, SwDocPositions eStart,
+                SwDocPositions eEnd, sal_Bool bRev = sal_False );
+    void _End();
+};
+
+/*************************************************************************
+ *                     class SwSpellIter
+ *************************************************************************/
+
+class SwSpellIter : public SwLinguIter
+{
+    uno::Reference< linguistic::XSpellChecker1 >    xSpeller;
+public:
+    SwSpellIter() {}
+
+    void Start( SwEditShell *pSh, SwDocPositions eStart, SwDocPositions eEnd );
+
+    uno::Reference< uno::XInterface >
+        Continue( sal_uInt16* pPageCnt, sal_uInt16* pPageSt );
+};
+
+/*************************************************************************
+ *                     class SwHyphIter
+ *************************************************************************/
+
+class SwHyphIter : public SwLinguIter
+{
+    sal_Bool bOldIdle;
+    void DelSoftHyph( SwPaM &rPam );
+
+public:
+    SwHyphIter() : bOldIdle(sal_False) {}
+
+    void Start( SwEditShell *pSh, SwDocPositions eStart, SwDocPositions eEnd );
+    void End();
+
+    void Ignore();
+
+    uno::Reference< uno::XInterface >
+        Continue( sal_uInt16* pPageCnt, sal_uInt16* pPageSt );
+
+    sal_Bool IsAuto();
+    void InsertSoftHyph( const xub_StrLen nHyphPos );
+    void ShowSelection();
+};
+
+static SwSpellIter* pSpellIter = 0;
+static SwHyphIter*  pHyphIter = 0;
+
+// Wir ersparen uns in Hyphenate ein GetFrm()
+// Achtung: in txtedt.cxx stehen extern-Deklarationen auf diese Pointer!
+const SwTxtNode *pLinguNode;
+      SwTxtFrm  *pLinguFrm;
+
+/*************************************************************************
+ *                      SwLinguIter::SwLinguIter
+ *************************************************************************/
+
+SwLinguIter::SwLinguIter()
+    : pSh( 0 ), pStart( 0 ), pEnd( 0 ), pCurr( 0 ), pCurrX( 0 )
+{
+    // @@@ es fehlt: Sicherstellen der Reentrance, ASSERTs etc.
+}
+
+/*************************************************************************
+ *                      SwLinguIter::Start
+ *************************************************************************/
+
+
+
+void SwLinguIter::_Start( SwEditShell *pShell, SwDocPositions eStart,
+                            SwDocPositions eEnd, sal_Bool bRev )
+{
+    // es fehlt: Sicherstellen der Reentrance, Locking
+    if( pSh )
+        return;
+
+    sal_Bool bSetCurr;
+
+    pSh = pShell;
+
+    SET_CURR_SHELL( pSh );
+
+    ASSERT( !pEnd, "LinguStart ohne End?");
+
+    SwPaM *pCrsr = pSh->GetCrsr();
+
+    // pStk->SetCurCrsr();
+//  if( pCrsr->HasMark() || pCrsr != pCrsr->GetNext() )
+    if( pShell->HasSelection() || pCrsr != pCrsr->GetNext() )
+    {
+        bSetCurr = 0 != GetCurr();
+        nCrsrCnt = pSh->GetCrsrCnt();
+        if( pSh->IsTableMode() )
+            pSh->TblCrsrToCursor();
+
+        pSh->Push();
+        sal_uInt16 n;
+        for( n = 0; n < nCrsrCnt; ++n )
+        {
+            pSh->Push();
+            pSh->DestroyCrsr();
+        }
+        pSh->Pop( sal_False );
+    }
+    else
+    {
+        bSetCurr = sal_False;
+        nCrsrCnt = 1;
+        pSh->Push();
+        pSh->SetLinguRange( eStart, eEnd );
+    }
+
+    pCrsr = pSh->GetCrsr();
+    if ( *pCrsr->GetPoint() > *pCrsr->GetMark() )
+        pCrsr->Exchange();
+
+    pStart = new SwPosition( *pCrsr->GetPoint() );
+    pEnd = new SwPosition( *pCrsr->GetMark() );
+    if( bSetCurr )
+    {
+        SwPosition* pNew = new SwPosition( bRev ? *GetEnd() : *GetStart() );
+        SetCurr( pNew );
+        pNew = new SwPosition( *pNew );
+        SetCurrX( pNew );
+    }
+
+    pCrsr->SetMark();
+
+    pLinguFrm = 0;
+    pLinguNode = 0;
+}
+
+/*************************************************************************
+ *                      SwLinguIter::End
+ *************************************************************************/
+
+
+
+void SwLinguIter::_End()
+{
+    if( !pSh )
+        return;
+
+    ASSERT( pEnd, "SwEditShell::SpellEnd() ohne Start?");
+    while( nCrsrCnt-- )
+        pSh->Pop( sal_False );
+
+    pSh->KillPams();
+    pSh->ClearMark();
+    DELETEZ(pStart);
+    DELETEZ(pEnd);
+    DELETEZ(pCurr);
+    DELETEZ(pCurrX);
+
+    pSh = 0;
+
+#ifdef LINGU_STATISTIK
+    aSwLinguStat.Flush();
+#endif
+}
+
+/*************************************************************************
+ *               virtual SwSpellIter::Start()
+ *************************************************************************/
+
+
+
+void SwSpellIter::Start( SwEditShell *pShell, SwDocPositions eStart,
+                        SwDocPositions eEnd )
+{
+    if( GetSh() )
+        return;
+     uno::Reference< beans::XPropertySet >  xProp( ::GetLinguPropertySet() );
+    sal_Bool bIsWrapReverse = xProp.is() ?
+        *(sal_Bool*)xProp->getPropertyValue( S2U(UPN_IS_WRAP_REVERSE) ).getValue() : sal_False;
+
+    xSpeller = pShell->GetSpellChecker();
+    if (xSpeller.is())
+        _Start( pShell, eStart, eEnd, bIsWrapReverse );
+}
+
+/*************************************************************************
+ *                   SwSpellIter::Continue
+ *************************************************************************/
+
+// SwSpellIter::Continue ist das alte Original von
+// SwEditShell::SpellContinue()
+
+uno::Reference< uno::XInterface >
+    SwSpellIter::Continue( sal_uInt16* pPageCnt, sal_uInt16* pPageSt )
+{
+ uno::Reference< uno::XInterface >  xSpellRet;
+    SwEditShell *pSh = GetSh();
+    if( !pSh )
+        return xSpellRet;
+
+//  const SwPosition *pEnd = GetEnd();
+
+    ASSERT( GetEnd(), "SwEditShell::SpellContinue() ohne Start?");
+
+    sal_Bool bGoOn = sal_True;
+    do
+    {
+        SwPaM *pCrsr = pSh->GetCrsr();
+        if ( !pCrsr->HasMark() )
+            pCrsr->SetMark();
+     uno::Reference< beans::XPropertySet >  xProp( GetLinguPropertySet() );
+        sal_Bool bRev = xProp.is() ?
+            *(sal_Bool*)xProp->getPropertyValue( S2U(UPN_IS_WRAP_REVERSE) ).getValue() : sal_False;
+        if( bRev )
+        {
+            *pSh->GetCrsr()->GetPoint() = *GetCurrX();
+            *pSh->GetCrsr()->GetMark() = *GetStart();
+        }
+        else
+        {
+            *pSh->GetCrsr()->GetPoint() = *GetCurr();
+            *pSh->GetCrsr()->GetMark() = *GetEnd();
+        }
+        xSpellRet = pSh->GetDoc()->Spell(*pSh->GetCrsr(),
+                    xSpeller, pPageCnt, pPageSt );
+        bGoOn = GetCrsrCnt() > 1;
+        if( xSpellRet.is() )
+        {
+            bGoOn = sal_False;
+            SwPosition* pNewPoint = new SwPosition( *pCrsr->GetPoint() );
+            SwPosition* pNewMark = new SwPosition( *pCrsr->GetMark() );
+            if( bRev )
+            {
+                SetCurr( pNewMark );
+                // Noch steht der sdbcx::Index zwar am Anfang des falschen Wortes,
+                // wenn dies ersetzt wird (Delete,Insert), ist der sdbcx::Index
+                // hinter diesem und das Wort wird erneut geprueft (51308)
+                if( pNewPoint->nContent.GetIndex() )
+                    --pNewPoint->nContent;
+                SetCurrX( pNewPoint );
+            }
+            else
+            {
+                SetCurr( pNewPoint );
+                SetCurrX( pNewMark );
+            }
+        }
+        if( bGoOn )
+        {
+            pSh->Pop( sal_False );
+            pCrsr = pSh->GetCrsr();
+            if ( *pCrsr->GetPoint() > *pCrsr->GetMark() )
+                pCrsr->Exchange();
+            SwPosition* pNew = new SwPosition( *pCrsr->GetPoint() );
+            SetStart( pNew );
+            pNew = new SwPosition( *pCrsr->GetMark() );
+            SetEnd( pNew );
+            pNew = new SwPosition( bRev ? *GetEnd() : *GetStart() );
+            SetCurr( pNew );
+            pNew = new SwPosition( *pNew );
+            SetCurrX( pNew );
+            pCrsr->SetMark();
+            --GetCrsrCnt();
+        }
+    }while ( bGoOn );
+    return xSpellRet;
+}
+
+
+sal_Bool SwHyphIter::IsAuto()
+{
+ uno::Reference< beans::XPropertySet >  xProp( ::GetLinguPropertySet() );
+    return xProp.is() ?
+        *(sal_Bool*)xProp->getPropertyValue( S2U(UPN_IS_HYPH_AUTO) ).getValue() : sal_False;
+}
+
+
+void SwHyphIter::ShowSelection()
+{
+    SwEditShell *pSh = GetSh();
+    if( pSh )
+    {
+        pSh->StartAction();
+        // Ganz fatal: durch das EndAction() werden Formatierungen
+        // angeregt, die dazu fuehren koennen, dass im Hyphenator
+        // neue Worte eingestellt werden. Deswegen sichern!
+        pSh->EndAction();
+    }
+}
+
+/*************************************************************************
+ *               virtual SwHyphIter::Start()
+ *************************************************************************/
+
+
+
+void SwHyphIter::Start( SwEditShell *pShell, SwDocPositions eStart, SwDocPositions eEnd )
+{
+    // robust
+    if( GetSh() || GetEnd() )
+    {
+        ASSERT( !GetSh(), "+SwEditShell::HyphStart: missing HyphEnd()" );
+        return;
+    }
+
+// nothing to be done (at least not in the way as in the "else" part)
+    bOldIdle = pShell->GetViewOptions()->IsIdle();
+    ((SwViewOption*)pShell->GetViewOptions())->SetIdle( sal_False );
+    _Start( pShell, eStart, eEnd );
+}
+
+/*************************************************************************
+ *                 virtual SwHyphIter::End
+ *************************************************************************/
+
+// Selektionen wiederherstellen
+
+
+
+void SwHyphIter::End()
+{
+    if( !GetSh() )
+        return;
+    ((SwViewOption*)GetSh()->GetViewOptions())->SetIdle( bOldIdle );
+    _End();
+}
+
+/*************************************************************************
+ *                   SwHyphIter::Continue
+ *************************************************************************/
+
+uno::Reference< uno::XInterface >
+    SwHyphIter::Continue( sal_uInt16* pPageCnt, sal_uInt16* pPageSt )
+{
+    SwEditShell *pSh = GetSh();
+    if( !pSh )
+        return 0;
+
+    const sal_Bool bAuto = IsAuto();
+     uno::Reference< linguistic::XHyphenatedWord >  xHyphWord;
+    sal_uInt16 nRet;
+    sal_Bool bGoOn = sal_False;
+    do {
+        SwPaM *pCrsr;
+        do {
+            ASSERT( GetEnd(), "SwEditShell::SpellContinue() ohne Start?" );
+            pCrsr = pSh->GetCrsr();
+            if ( !pCrsr->HasMark() )
+                pCrsr->SetMark();
+            if ( *pCrsr->GetPoint() < *pCrsr->GetMark() )
+            {
+                pCrsr->Exchange();
+                pCrsr->SetMark();
+            }
+
+            // geraten BUG:
+            if ( *pCrsr->End() > *GetEnd() )
+                nRet = 0;
+            else
+            {
+                *pCrsr->GetMark() = *GetEnd();
+
+                // Muss an der aktuellen Cursorpos das Wort getrennt werden ?
+                const Point aCrsrPos( pSh->GetCharRect().Pos() );
+                xHyphWord = pSh->GetDoc()->Hyphenate( pCrsr, aCrsrPos,
+                                                       pPageCnt, pPageSt );
+            }
+
+            if( bAuto && xHyphWord.is() )
+            {
+                pSh->InsertSoftHyph( xHyphWord->getHyphenationPos() + 1);
+            }
+        } while( bAuto && xHyphWord.is() ); //end of do-while
+        bGoOn = !xHyphWord.is() && GetCrsrCnt() > 1;
+
+        if( bGoOn )
+        {
+            pSh->Pop( sal_False );
+            pCrsr = pSh->GetCrsr();
+            if ( *pCrsr->GetPoint() > *pCrsr->GetMark() )
+                pCrsr->Exchange();
+            SwPosition* pNew = new SwPosition(*pCrsr->End());
+            SetEnd( pNew );
+            pCrsr->SetMark();
+            --GetCrsrCnt();
+        }
+    } while ( bGoOn );
+    return xHyphWord;
+}
+
+/*************************************************************************
+ *                  SwHyphIter::HyphIgnore
+ *************************************************************************/
+
+// Beschreibung: Trennstelle ignorieren
+
+void SwHyphIter::Ignore()
+{
+    SwEditShell *pSh = GetSh();
+    SwPaM *pCrsr = pSh->GetCrsr();
+
+    // Alten SoftHyphen loeschen
+    DelSoftHyph( *pCrsr );
+
+    // und weiter
+    pCrsr->Start()->nContent = pCrsr->End()->nContent;
+    pCrsr->SetMark();
+}
+
+/*************************************************************************
+ *                        SwHyphIter::DelSoftHyph
+ *************************************************************************/
+
+void SwHyphIter::DelSoftHyph( SwPaM &rPam )
+{
+    const SwPosition* pStt = rPam.Start();
+    const xub_StrLen nStart = pStt->nContent.GetIndex();
+    const xub_StrLen nEnd   = rPam.End()->nContent.GetIndex();
+    SwTxtNode *pNode = pStt->nNode.GetNode().GetTxtNode();
+    pNode->DelSoftHyph( nStart, nEnd );
+}
+
+/*************************************************************************
+ *                  SwHyphIter::InsertSoftHyph
+ *************************************************************************/
+
+
+void SwHyphIter::InsertSoftHyph( const xub_StrLen nHyphPos )
+{
+    SwEditShell *pSh = GetSh();
+    ASSERT( pSh,  "+SwEditShell::InsertSoftHyph: missing HyphStart()");
+    if( !pSh )
+        return;
+
+    SwPaM *pCrsr = pSh->GetCrsr();
+    SwPosition *pStt = pCrsr->Start(), *pEnd = pCrsr->End();
+
+    xub_StrLen nLastHyphLen = GetEnd()->nContent.GetIndex() -
+                          pStt->nContent.GetIndex();
+
+    if( pStt->nNode != pEnd->nNode || !nLastHyphLen )
+    {
+        ASSERT( pStt->nNode == pEnd->nNode,
+                "+SwEditShell::InsertSoftHyph: node warp during hyphenation" );
+        ASSERT(nLastHyphLen, "+SwEditShell::InsertSoftHyph: missing HyphContinue()");
+        *pStt = *pEnd;
+        return;
+    }
+
+    pSh->StartAction();
+    {
+        SwDoc *pDoc = pSh->GetDoc();
+        DelSoftHyph( *pCrsr );
+        pStt->nContent += nHyphPos;
+        SwPaM aRg( *pStt );
+        pDoc->Insert( aRg, CHAR_SOFTHYPHEN );
+        // Durch das Einfuegen des SoftHyphs ist ein Zeichen hinzugekommen
+//JP 18.07.95: warum, ist doch ein SwIndex, dieser wird doch mitverschoben !!
+//        pStt->nContent++;
+    }
+    // Die Selektion wird wieder aufgehoben
+    pCrsr->DeleteMark();
+    pSh->EndAction();
+    pCrsr->SetMark();
+}
+
+// --------------------- Methoden der SwEditShell ------------------------
+
+/*************************************************************************
+ *                      SwEditShell::HasSpellIter
+ *************************************************************************/
+
+BOOL SwEditShell::HasSpellIter() const
+{
+    return 0 != pSpellIter;
+}
+
+/*************************************************************************
+ *                      SwEditShell::HasHyphIter
+ *************************************************************************/
+
+BOOL SwEditShell::HasHyphIter() const
+{
+    return 0 != pHyphIter;
+}
+
+/*************************************************************************
+ *                      SwEditShell::SetFindRange
+ *************************************************************************/
+
+void SwEditShell::SetLinguRange( SwDocPositions eStart, SwDocPositions eEnd )
+{
+    SwPaM *pCrsr = GetCrsr();
+    MakeFindRange( eStart, eEnd, pCrsr );
+    if( *pCrsr->GetPoint() > *pCrsr->GetMark() )
+        pCrsr->Exchange();
+}
+
+/*************************************************************************
+ *                  SwEditShell::SpellStart
+ *************************************************************************/
+
+// Selektionen sichern
+
+
+
+void SwEditShell::SpellStart( SwDocPositions eStart, SwDocPositions eEnd,
+                                SwDocPositions eCurr )
+{
+    // do not spell if interactive spelling is active elsewhere
+    if (!pSpellIter)
+    {
+        ASSERT( !pSpellIter, "wer ist da schon am spellen?" );
+        pSpellIter = new SwSpellIter;
+
+        SwCursor* pSwCrsr = GetSwCrsr();
+
+        SwPosition *pTmp = new SwPosition( *pSwCrsr->GetPoint() );
+        pSwCrsr->FillFindPos( eCurr, *pTmp );
+        pSpellIter->SetCurr( pTmp );
+
+        pTmp = new SwPosition( *pTmp );
+        pSpellIter->SetCurrX( pTmp );
+
+        pSpellIter->Start( this, eStart, eEnd );
+    }
+}
+
+/*************************************************************************
+ *                  SwEditShell::SpellEnd
+ *************************************************************************/
+
+// Selektionen wiederherstellen
+
+
+
+void SwEditShell::SpellEnd()
+{
+    if (pSpellIter->GetSh() == this)
+    {
+        ASSERT( pSpellIter, "wo ist mein Iterator?" );
+        pSpellIter->_End();
+        delete pSpellIter, pSpellIter = 0;
+    }
+}
+
+/*************************************************************************
+ *                  SwEditShell::SpellContinue
+ *************************************************************************/
+
+// liefert Rueckgabewerte entsprechend SPL_ in splchk.hxx
+
+uno::Reference< uno::XInterface >
+    SwEditShell::SpellContinue( sal_uInt16* pPageCnt, sal_uInt16* pPageSt )
+{
+    if (pSpellIter->GetSh() != this)
+        return 0;
+
+    if( pPageCnt && !*pPageCnt )
+    {
+        sal_uInt16 nEndPage = GetLayout()->GetPageNum();
+        nEndPage += nEndPage * 10 / 100;
+        *pPageCnt = nEndPage;
+        if( nEndPage )
+            ::StartProgress( STR_STATSTR_SPELL, 0, nEndPage, GetDoc()->GetDocShell() );
+    }
+
+    ASSERT( pSpellIter, "wo ist mein Iterator?" );
+    //JP 18.07.95: verhinder bei Fehlermeldungen die Anzeige der Selektionen
+    //              KEIN StartAction, da damit auch die Paints abgeschaltet
+    //              werden !!!!!
+    ++nStartAction;
+     uno::Reference< uno::XInterface >  xRet = pSpellIter->Continue( pPageCnt, pPageSt );
+    --nStartAction;
+
+    if( xRet.is() )
+    {
+        // dann die awt::Selection sichtbar machen
+        StartAction();
+        EndAction();
+    }
+    return xRet;
+}
+
+/*************************************************************************
+ *                  SwEditShell::HyphStart
+ *************************************************************************/
+
+/* Interaktive Trennung, BP 10.03.93
+ *
+ * 1) HyphStart
+ *    - Aufheben aller Selektionen
+ *    - Sichern des aktuellen Cursors
+ *    - falls keine Selektion vorhanden:
+ *      - neue Selektion bis zum Dokumentende
+ * 2) HyphContinue
+ *    - nLastHyphLen wird auf den Selektionsstart addiert
+ *    - iteriert ueber alle selektierten Bereiche
+ *      - pDoc->Hyphenate() iteriert ueber alle Nodes der Selektion
+ *          - pTxtNode->Hyphenate() ruft das SwTxtFrm::Hyphenate zur EditShell
+ *              - SwTxtFrm:Hyphenate() iteriert ueber die Zeilen des Pams
+ *                  - LineIter::Hyphenate() stellt den Hyphenator
+ *                    und den Pam auf das zu trennende Wort ein.
+ *    - Es gibt nur zwei Returnwerte sal_True, wenn eine Trennstelle anliegt
+ *      und sal_False, wenn der Pam abgearbeitet wurde.
+ *    - Bei sal_True wird das selektierte Wort zur Anzeige gebracht und
+ *      nLastHyphLen gesetzt.
+ *    - Bei sal_False wird die aktuelle Selektion geloescht und die naechste
+ *      zur aktuellen gewaehlt. Return HYPH_OK, wenn keine mehr vorhanden.
+ * 3) InsertSoftHyph (wird ggf. von der UI gerufen)
+ *    - Der aktuelle Cursor wird plaziert und das Attribut eingefuegt.
+ * 4) HyphEnd
+ *    - Wiederherstellen des alten Cursors, EndAction
+ */
+
+
+
+void SwEditShell::HyphStart( SwDocPositions eStart, SwDocPositions eEnd )
+{
+    // do not hyphenate if interactive hyphenationg is active elsewhere
+    if (!pHyphIter)
+    {
+        ASSERT( !pHyphIter, "wer ist da schon am hyphinieren?" );
+        pHyphIter = new SwHyphIter;
+        pHyphIter->Start( this, eStart, eEnd );
+    }
+}
+
+/*************************************************************************
+ *                  SwEditShell::HyphEnd
+ *************************************************************************/
+
+// Selektionen wiederherstellen
+
+
+
+void SwEditShell::HyphEnd()
+{
+    if (pHyphIter->GetSh() == this)
+    {
+        ASSERT( pHyphIter, "wo ist mein Iterator?" );
+        pHyphIter->End();
+        delete pHyphIter, pHyphIter = 0;
+    }
+}
+
+/*************************************************************************
+ *                  SwEditShell::HyphContinue
+ *************************************************************************/
+
+// Returnwerte: (BP: ich wuerde es genau umdrehen, aber die UI wuenscht es so)
+// HYPH_CONTINUE, wenn eine Trennstelle anliegt
+// HYPH_OK, wenn der selektierte Bereich abgearbeitet wurde.
+
+
+uno::Reference< uno::XInterface >
+    SwEditShell::HyphContinue( sal_uInt16* pPageCnt, sal_uInt16* pPageSt )
+{
+    if (pHyphIter->GetSh() != this)
+        return 0;
+
+    if( pPageCnt && !*pPageCnt && !*pPageSt )
+    {
+        sal_uInt16 nEndPage = GetLayout()->GetPageNum();
+        nEndPage += nEndPage * 10 / 100;
+        if( nEndPage > 14 )
+        {
+            *pPageCnt = nEndPage;
+            ::StartProgress( STR_STATSTR_HYPHEN, 0, nEndPage, GetDoc()->GetDocShell());
+        }
+        else                // Hiermit unterdruecken wir ein fuer allemal
+            *pPageSt = 1;   // das StatLineStartPercent
+    }
+
+    ASSERT( pHyphIter, "wo ist mein Iterator?" );
+    //JP 18.07.95: verhinder bei Fehlermeldungen die Anzeige der Selektionen
+    //              KEIN StartAction, da damit auch die Paints abgeschaltet
+    //              werden !!!!!
+    ++nStartAction;
+     uno::Reference< uno::XInterface >  xRet = pHyphIter->Continue( pPageCnt, pPageSt );
+    --nStartAction;
+
+    if( xRet.is() )
+        pHyphIter->ShowSelection();
+
+    return xRet;
+}
+
+
+/*************************************************************************
+ *                  SwEditShell::InsertSoftHyph
+ *************************************************************************/
+
+// Zum Einfuegen des SoftHyphens, Position ist der Offset
+// innerhalb des getrennten Wortes.
+
+
+void SwEditShell::InsertSoftHyph( const xub_StrLen nHyphPos )
+{
+    ASSERT( pHyphIter, "wo ist mein Iterator?" );
+    pHyphIter->InsertSoftHyph( nHyphPos );
+}
+
+
+/*************************************************************************
+ *                  SwEditShell::HyphIgnore
+ *************************************************************************/
+
+// Beschreibung: Trennstelle ignorieren
+
+void SwEditShell::HyphIgnore()
+{
+    ASSERT( pHyphIter, "wo ist mein Iterator?" );
+    //JP 18.07.95: verhinder bei Fehlermeldungen die Anzeige der Selektionen
+    //              KEIN StartAction, da damit auch die Paints abgeschaltet
+    //              werden !!!!!
+    ++nStartAction;
+    pHyphIter->Ignore();
+    --nStartAction;
+
+    pHyphIter->ShowSelection();
+}
+
+/*************************************************************************
+ *                  SwEditShell::GetCorrection()
+ * liefert eine Liste von Vorschlaegen fuer falsch geschriebene Worte,
+ * ein NULL-Pointer signalisiert, dass das Wort richtig geschrieben ist,
+ * eine leere Liste, dass das Wort zwar unbekannt ist, aber keine Alternativen
+ * geliefert werden koennen.
+ *************************************************************************/
+
+
+uno::Reference< linguistic::XSpellAlternatives >
+    SwEditShell::GetCorrection( const Point* pPt )
+{
+     uno::Reference< linguistic::XSpellAlternatives >  xSpellAlt;
+
+    if( IsTableMode() )
+        return NULL;
+    SwPaM* pCrsr = GetCrsr();
+    SwPosition aPos( *pCrsr->GetPoint() );
+     Point aPt( *pPt );
+    SwCrsrMoveState eTmpState( MV_SETONLYTEXT );
+    SwTxtNode *pNode;
+    SwWrongList *pWrong;
+    if( GetLayout()->GetCrsrOfst( &aPos, aPt, &eTmpState ) &&
+        0 != (pNode = aPos.nNode.GetNode().GetTxtNode()) &&
+        0 != (pWrong = pNode->GetWrong()) &&
+        !pNode->IsInProtectSect() )
+    {
+        xub_StrLen nBegin = aPos.nContent.GetIndex();
+        xub_StrLen nLen = 1;
+        if( pWrong->InWrongWord(nBegin,nLen) && !pNode->IsSymbol(nBegin) )
+        {
+            String aWord( pNode->GetTxt().Copy( nBegin, nLen ) );
+            aWord.EraseAllChars( CH_TXTATR_BREAKWORD ).EraseAllChars( CH_TXTATR_INWORD );
+
+            sal_Bool bSpell = sal_True;
+
+            uno::Reference< linguistic::XSpellChecker1 >  xSpell(
+                                            OFF_APP()->GetSpellChecker() );
+            if( xSpell.is() )
+            {
+                LanguageType eActLang = (LanguageType)pNode->GetLang(
+                                                            nBegin, nLen );
+                if( xSpell->hasLanguage( eActLang ))
+                    xSpellAlt = xSpell->spell( aWord, eActLang );
+            }
+
+            if ( xSpellAlt.is() )
+            {
+#ifdef DEBUG
+                pNode->GetWrong()->Invalidate( 0, STRING_LEN );
+                pNode->SetWrongDirty( sal_True );
+#endif
+                aPos.nContent = nBegin;
+                *pCrsr->GetPoint() = aPos;
+                pCrsr->SetMark();
+                ExtendSelection( sal_True, nLen );
+            }
+        }
+    }
+    return xSpellAlt;
+}
+
+
+
+
diff --git a/sw/source/core/edit/ednumber.cxx b/sw/source/core/edit/ednumber.cxx
new file mode 100644
index 000000000000..d1030db6077d
--- /dev/null
+++ b/sw/source/core/edit/ednumber.cxx
@@ -0,0 +1,714 @@
+/*************************************************************************
+ *
+ *  $RCSfile: ednumber.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:18 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+#ifndef _EDITSH_HXX
+#include 
+#endif
+#ifndef _EDIMP_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _VISCRS_HXX
+#include 
+#endif
+#ifndef _NUMRULE_HXX
+#include 
+#endif
+#ifndef _HINTS_HXX
+#include 
+#endif
+#ifndef _PARATR_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include 
+#endif
+
+
+
+SV_IMPL_VARARR_SORT( _SwPamRanges, SwPamRange )
+
+
+SwPamRanges::SwPamRanges( const SwPaM& rRing )
+{
+    const SwPaM* pTmp = &rRing;
+    do {
+        Insert( pTmp->GetMark()->nNode, pTmp->GetPoint()->nNode );
+    } while( &rRing != ( pTmp = (const SwPaM*)pTmp->GetNext() ));
+}
+
+
+void SwPamRanges::Insert( const SwNodeIndex& rIdx1, const SwNodeIndex& rIdx2 )
+{
+    SwPamRange aRg( rIdx1.GetIndex(), rIdx2.GetIndex() );
+    if( aRg.nEnd < aRg.nStart )
+    {   aRg.nStart = aRg.nEnd; aRg.nEnd = rIdx1.GetIndex(); }
+
+    USHORT nPos = 0;
+    const SwPamRange* pTmp;
+    if( Count() && Seek_Entry( aRg, &nPos ))        // suche Insert Position
+    {
+        // ist der im Array stehende kleiner ??
+        if( ( pTmp = GetData()+ nPos )->nEnd < aRg.nEnd )
+        {
+            aRg.nEnd = pTmp->nEnd;
+            Remove( nPos, 1 );      // zusammenfassen
+        }
+        else
+            return;     // ende, weil schon alle zusammengefasst waren
+    }
+
+    BOOL bEnde;
+    do {
+        bEnde = TRUE;
+
+        // mit dem Vorgaenger zusammenfassen ??
+        if( nPos > 0 )
+        {
+            if( ( pTmp = GetData()+( nPos-1 ))->nEnd == aRg.nStart
+                || pTmp->nEnd+1 == aRg.nStart )
+            {
+                aRg.nStart = pTmp->nStart;
+                bEnde = FALSE;
+                Remove( --nPos, 1 );        // zusammenfassen
+            }
+            // SSelection im Bereich ??
+            else if( pTmp->nStart <= aRg.nStart && aRg.nEnd <= pTmp->nEnd )
+                return;
+        }
+            // mit dem Nachfolger zusammenfassen ??
+        if( nPos < Count() )
+        {
+            if( ( pTmp = GetData() + nPos )->nStart == aRg.nEnd ||
+                pTmp->nStart == aRg.nEnd+1 )
+            {
+                aRg.nEnd = pTmp->nEnd;
+                bEnde = FALSE;
+                Remove( nPos, 1 );      // zusammenfassen
+            }
+
+            // SSelection im Bereich ??
+            else if( pTmp->nStart <= aRg.nStart && aRg.nEnd <= pTmp->nEnd )
+                return;
+        }
+    } while( !bEnde );
+
+    _SwPamRanges::Insert( aRg );
+}
+
+
+
+SwPaM& SwPamRanges::SetPam( USHORT nArrPos, SwPaM& rPam )
+{
+    ASSERT_ID( nArrPos < Count(), ERR_VAR_IDX );
+    const SwPamRange& rTmp = *(GetData() + nArrPos );
+    rPam.GetPoint()->nNode = rTmp.nStart;
+    rPam.GetPoint()->nContent.Assign( rPam.GetCntntNode(), 0 );
+    rPam.SetMark();
+    rPam.GetPoint()->nNode = rTmp.nEnd;
+    rPam.GetPoint()->nContent.Assign( rPam.GetCntntNode(), 0 );
+    return rPam;
+}
+
+
+
+// Numerierung Outline Regelwerk
+
+
+void SwEditShell::SetOutlineNumRule(const SwNumRule& rRule)
+{
+    StartAllAction();       // Klammern fuers Updaten !!
+    GetDoc()->SetOutlineNumRule(rRule);
+    EndAllAction();
+}
+
+
+const SwNumRule* SwEditShell::GetOutlineNumRule() const
+{
+    return GetDoc()->GetOutlineNumRule();
+}
+
+// setzt, wenn noch keine Numerierung, sonst wird geaendert
+// arbeitet mit alten und neuen Regeln, nur Differenzen aktualisieren
+
+// Absaetze ohne Numerierung, aber mit Einzuegen
+
+BOOL SwEditShell::NoNum()
+{
+    BOOL bRet = TRUE;
+    StartAllAction();
+
+    SwPaM* pCrsr = GetCrsr();
+    if( pCrsr->GetNext() != pCrsr )         // Mehrfachselektion ?
+    {
+        GetDoc()->StartUndo( UNDO_START );
+        SwPamRanges aRangeArr( *pCrsr );
+        SwPaM aPam( *pCrsr->GetPoint() );
+        for( USHORT n = 0; n < aRangeArr.Count(); ++n )
+            bRet = bRet && GetDoc()->NoNum( aRangeArr.SetPam( n, aPam ));
+        GetDoc()->EndUndo( UNDO_END );
+    }
+    else
+        bRet = GetDoc()->NoNum( *pCrsr );
+
+    EndAllAction();
+    return bRet;
+}
+// Loeschen, Splitten der Aufzaehlungsliste
+
+
+BOOL SwEditShell::DelNumRules()
+{
+    BOOL bRet = TRUE;
+    StartAllAction();
+
+    SwPaM* pCrsr = GetCrsr();
+    if( pCrsr->GetNext() != pCrsr )         // Mehrfachselektion ?
+    {
+        GetDoc()->StartUndo( UNDO_START );
+        SwPamRanges aRangeArr( *pCrsr );
+        SwPaM aPam( *pCrsr->GetPoint() );
+        for( USHORT n = 0; n < aRangeArr.Count(); ++n )
+            bRet = bRet && GetDoc()->DelNumRules( aRangeArr.SetPam( n, aPam ) );
+        GetDoc()->EndUndo( UNDO_END );
+    }
+    else
+        bRet = GetDoc()->DelNumRules( *pCrsr );
+
+    // rufe das AttrChangeNotify auf der UI-Seite. Sollte eigentlich
+    // ueberfluessig sein, aber VB hatte darueber eine Bugrep.
+    CallChgLnk();
+
+    GetDoc()->SetModified();
+    EndAllAction();
+    return bRet;
+}
+
+// Hoch-/Runterstufen
+
+
+BOOL SwEditShell::NumUpDown( BOOL bDown )
+{
+    StartAllAction();
+
+    BOOL bRet = TRUE;
+    SwPaM* pCrsr = GetCrsr();
+    if( pCrsr->GetNext() == pCrsr )         // keine Mehrfachselektion ?
+        bRet = GetDoc()->NumUpDown( *pCrsr, bDown );
+    else
+    {
+        GetDoc()->StartUndo( UNDO_START );
+        SwPamRanges aRangeArr( *pCrsr );
+        SwPaM aPam( *pCrsr->GetPoint() );
+        for( USHORT n = 0; n < aRangeArr.Count(); ++n )
+            bRet = bRet && GetDoc()->NumUpDown( aRangeArr.SetPam( n, aPam ), bDown );
+        GetDoc()->EndUndo( UNDO_END );
+    }
+    GetDoc()->SetModified();
+    EndAllAction();
+    return bRet;
+}
+
+
+
+BOOL SwEditShell::MoveParagraph( long nOffset )
+{
+    StartAllAction();
+
+    SwPaM *pCrsr = GetCrsr();
+    if( !pCrsr->HasMark() )
+    {
+        // sorge dafuer, das Bound1 und Bound2 im gleichen Node stehen
+        pCrsr->SetMark();
+        pCrsr->DeleteMark();
+    }
+
+    BOOL bRet = GetDoc()->MoveParagraph( *pCrsr, nOffset );
+
+    GetDoc()->SetModified();
+    EndAllAction();
+    return bRet;
+}
+
+
+BOOL SwEditShell::MoveNumParas( BOOL bUpperLower, BOOL bUpperLeft )
+{
+    StartAllAction();
+
+    // auf alle Selektionen ??
+    SwPaM* pCrsr = GetCrsr();
+    SwPaM aCrsr( *pCrsr->Start() );
+    aCrsr.SetMark();
+
+    if( pCrsr->HasMark() )
+        *aCrsr.GetPoint() = *pCrsr->End();
+
+    BOOL bRet = FALSE;
+    BYTE nUpperLevel, nLowerLevel;
+    if( GetDoc()->GotoNextNum( *aCrsr.GetPoint(), FALSE,
+                                &nUpperLevel, &nLowerLevel ))
+    {
+        if( bUpperLower )
+        {
+            // ueber die naechste Nummerierung
+            long nOffset = 0;
+            const SwNode* pNd;
+
+            if( bUpperLeft )        // verschiebe nach oben
+            {
+                SwPosition aPos( *aCrsr.GetMark() );
+                if( GetDoc()->GotoPrevNum( aPos, FALSE ) )
+                    nOffset = aPos.nNode.GetIndex() -
+                            aCrsr.GetMark()->nNode.GetIndex();
+                else
+                {
+                    ULONG nStt = aPos.nNode.GetIndex(), nIdx = nStt - 1;
+                    while( nIdx && (
+                        ( pNd = GetDoc()->GetNodes()[ nIdx ])->IsSectionNode() ||
+                        ( pNd->IsEndNode() && pNd->FindStartNode()->IsSectionNode())))
+                        --nIdx;
+                    if( GetDoc()->GetNodes()[ nIdx ]->IsTxtNode() )
+                        nOffset = nIdx - nStt;
+                }
+            }
+            else                    // verschiebe nach unten
+            {
+                const SwNumRule* pOrig = aCrsr.GetNode(FALSE)->GetTxtNode()->GetNumRule();
+                if( aCrsr.GetNode()->IsTxtNode() &&
+                    pOrig == aCrsr.GetNode()->GetTxtNode()->GetNumRule() )
+                {
+                    ULONG nStt = aCrsr.GetPoint()->nNode.GetIndex(), nIdx = nStt+1;
+                    while( nIdx < GetDoc()->GetNodes().Count()-1 && (
+                        ( pNd = GetDoc()->GetNodes()[ nIdx ])->IsSectionNode() ||
+                        ( pNd->IsEndNode() && pNd->FindStartNode()->IsSectionNode()) ||
+                        ( pNd->IsTxtNode() && pOrig == ((SwTxtNode*)pNd)->GetNumRule() &&
+                            ((SwTxtNode*)pNd)->GetNum() &&
+                            (((SwTxtNode*)pNd)->GetNum()->GetLevel() & ~NO_NUMLEVEL) > nUpperLevel )) )
+                        ++nIdx;
+                    if( nStt == nIdx || !GetDoc()->GetNodes()[ nIdx ]->IsTxtNode() )
+                        nOffset = 1;
+                    else
+                        nOffset = nIdx - nStt;
+                }
+                else
+                    nOffset = 1;
+            }
+
+            if( nOffset )
+            {
+                aCrsr.Move( fnMoveBackward, fnGoNode );
+                bRet = GetDoc()->MoveParagraph( aCrsr, nOffset );
+            }
+        }
+        else if( bUpperLeft ? nUpperLevel : nLowerLevel+1 < MAXLEVEL )
+        {
+            aCrsr.Move( fnMoveBackward, fnGoNode );
+            bRet = GetDoc()->NumUpDown( aCrsr, !bUpperLeft );
+        }
+    }
+
+    GetDoc()->SetModified();
+    EndAllAction();
+    return bRet;
+}
+
+// Abfrage von Oultine Informationen:
+
+
+USHORT SwEditShell::GetOutlineCnt() const
+{
+    return GetDoc()->GetNodes().GetOutLineNds().Count();
+}
+
+
+BYTE SwEditShell::GetOutlineLevel( USHORT nIdx ) const
+{
+    const SwNodes& rNds = GetDoc()->GetNodes();
+    const SwTxtFmtColl* pColl = rNds.GetOutLineNds()[ nIdx ]->GetTxtNode()->GetTxtColl();
+    return pColl->GetOutlineLevel();
+}
+
+
+String SwEditShell::GetOutlineText( USHORT nIdx, BOOL bWithNum ) const
+{
+    const SwNodes& rNds = GetDoc()->GetNodes();
+    return rNds.GetOutLineNds()[ nIdx ]->GetTxtNode()->GetExpandTxt( 0, STRING_LEN, bWithNum );
+}
+
+
+BOOL SwEditShell::OutlineUpDown( short nOffset )
+{
+    StartAllAction();
+
+    BOOL bRet = TRUE;
+    SwPaM* pCrsr = GetCrsr();
+    if( pCrsr->GetNext() == pCrsr )         // keine Mehrfachselektion ?
+        bRet = GetDoc()->OutlineUpDown( *pCrsr, nOffset );
+    else
+    {
+        GetDoc()->StartUndo( UNDO_START );
+        SwPamRanges aRangeArr( *pCrsr );
+        SwPaM aPam( *pCrsr->GetPoint() );
+        for( USHORT n = 0; n < aRangeArr.Count(); ++n )
+            bRet = bRet && GetDoc()->OutlineUpDown(
+                                    aRangeArr.SetPam( n, aPam ), nOffset );
+        GetDoc()->EndUndo( UNDO_END );
+    }
+    GetDoc()->SetModified();
+    EndAllAction();
+    return bRet;
+}
+
+
+BOOL SwEditShell::MoveOutlinePara( short nOffset )
+{
+    StartAllAction();
+    BOOL bRet = GetDoc()->MoveOutlinePara( *GetCrsr(), nOffset );
+    EndAllAction();
+    return bRet;
+}
+
+// Outlines and SubOutline are ReadOnly?
+BOOL SwEditShell::IsProtectedOutlinePara() const
+{
+    BOOL bRet = FALSE;
+    const SwNode& rNd = GetCrsr()->Start()->nNode.GetNode();
+    if( rNd.IsTxtNode() )
+    {
+        const SwOutlineNodes& rOutlNd = GetDoc()->GetNodes().GetOutLineNds();
+        SwNodePtr pNd = (SwNodePtr)&rNd;
+        BOOL bFirst = TRUE;
+        USHORT nPos;
+        BYTE nLvl;
+        if( !rOutlNd.Seek_Entry( pNd, &nPos ) && nPos )
+            --nPos;
+
+        for( ; nPos < rOutlNd.Count(); ++nPos )
+        {
+            SwNodePtr pNd = rOutlNd[ nPos ];
+            BYTE nTmpLvl = GetRealLevel( pNd->GetTxtNode()->
+                                    GetTxtColl()->GetOutlineLevel() );
+            if( bFirst )
+            {
+                nLvl = nTmpLvl;
+                bFirst = FALSE;
+            }
+            else if( nLvl >= nTmpLvl )
+                break;
+
+            if( pNd->IsProtect() )
+            {
+                bRet = TRUE;
+                break;
+            }
+        }
+    }
+#ifndef PRODUCT
+    else
+    {
+        ASSERT(!this, "Cursor not on an outline node" );
+    }
+#endif
+    return bRet;
+}
+
+BOOL SwEditShell::IsOutlineMovable( USHORT nIdx ) const
+{
+    const SwNodes& rNds = GetDoc()->GetNodes();
+    const SwNode* pNd = rNds.GetOutLineNds()[ nIdx ];
+    return pNd->GetIndex() >= rNds.GetEndOfExtras().GetIndex() &&
+            !pNd->FindTableNode() && !pNd->IsProtect();
+}
+
+
+BOOL SwEditShell::NumOrNoNum( BOOL bNumOn, BOOL bChkStart, BOOL bOutline )
+{
+    BOOL bRet = FALSE;
+    SwPaM* pCrsr = GetCrsr();
+    if( pCrsr->GetNext() == pCrsr && !pCrsr->HasMark() &&
+        ( !bChkStart || !pCrsr->GetPoint()->nContent.GetIndex()) )
+    {
+        StartAllAction();       // Klammern fuers Updaten !!
+        bRet = GetDoc()->NumOrNoNum( pCrsr->GetPoint()->nNode, bNumOn, bOutline );
+        EndAllAction();
+    }
+    return bRet;
+}
+
+
+BOOL SwEditShell::IsNoNum( BOOL bChkStart, BOOL bOutline ) const
+{
+    // ein Backspace im Absatz ohne Nummer wird zum Delete
+    const SwTxtNode* pTxtNd;
+    const SwNodeNum* pNum;
+    SwPaM* pCrsr = GetCrsr();
+
+    return pCrsr->GetNext() == pCrsr && !pCrsr->HasMark() &&
+        (!bChkStart || !pCrsr->GetPoint()->nContent.GetIndex()) &&
+        0 != ( pTxtNd = pCrsr->GetNode()->GetTxtNode()) &&
+        ( bOutline ? (NO_NUMBERING != pTxtNd->GetTxtColl()->GetOutlineLevel() &&
+                      0 != (pNum = pTxtNd->GetOutlineNum() ))
+                   : (pTxtNd->GetNumRule() &&
+                      0 != (pNum = pTxtNd->GetNum() ) )) &&
+        0 != ( pNum->GetLevel() & NO_NUMLEVEL );
+}
+
+
+const SwNodeNum* SwEditShell::GetOutlineNum( USHORT nIdx ) const
+{
+    const SwNodes& rNds = GetDoc()->GetNodes();
+    return rNds.GetOutLineNds()[ nIdx ]->GetTxtNode()->GetOutlineNum();
+}
+
+
+BYTE SwEditShell::GetNumLevel( BOOL* pHasChilds ) const
+{
+    // gebe die akt. Ebene zurueck, auf der sich der Point vom Cursor befindet
+    BYTE nLevel = NO_NUMBERING;
+
+    SwPaM* pCrsr = GetCrsr();
+    const SwTxtNode* pTxtNd = pCrsr->GetNode()->GetTxtNode();
+    const SwNumRule* pRule = pTxtNd->GetNumRule();
+    if( pRule && pTxtNd->GetNum() )
+    {
+        nLevel = pTxtNd->GetNum()->GetLevel();
+        if( pHasChilds )
+        {
+            *pHasChilds = FALSE;
+            // dann teste ob die NumSection noch weitere UnterEbenen hat:
+            // zuerst ueber alle TextNodes und falls da nichts gefunden
+            // wurde, ueber die Formate und deren GetInfo bis zu den Nodes
+
+            BYTE nLvl = nLevel & ~NO_NUMLEVEL;
+            if( nLvl + 1 < MAXLEVEL )
+            {
+                const String& rRule = pRule->GetName();
+                SwModify* pMod;
+                const SfxPoolItem* pItem;
+                USHORT i, nMaxItems = GetDoc()->GetAttrPool().GetItemCount( RES_PARATR_NUMRULE);
+                for( i = 0; i < nMaxItems; ++i )
+                    if( 0 != (pItem = GetDoc()->GetAttrPool().GetItem( RES_PARATR_NUMRULE, i ) ) &&
+                        0 != ( pMod = (SwModify*)((SwNumRuleItem*)pItem)->GetDefinedIn()) &&
+                        ((SwNumRuleItem*)pItem)->GetValue().Len() &&
+                        ((SwNumRuleItem*)pItem)->GetValue() == rRule &&
+                        pMod->IsA( TYPE( SwTxtNode )) &&
+                        ((SwTxtNode*)pMod)->GetNodes().IsDocNodes() &&
+                        ((SwTxtNode*)pMod)->GetNum() &&
+                        nLvl < ( ((SwTxtNode*)pMod)->GetNum()->GetLevel() & ~NO_NUMLEVEL) )
+                    {
+                        *pHasChilds = TRUE;
+                        break;
+                    }
+
+                if( !*pHasChilds )
+                {
+                    SwNRuleLowerLevel aHnt( rRule, nLvl );
+                    for( i = 0; i < nMaxItems; ++i )
+                        if( 0 != (pItem = GetDoc()->GetAttrPool().GetItem( RES_PARATR_NUMRULE, i ) ) &&
+                            0 != ( pMod = (SwModify*)((SwNumRuleItem*)pItem)->GetDefinedIn()) &&
+                            ((SwNumRuleItem*)pItem)->GetValue().Len() &&
+                            ((SwNumRuleItem*)pItem)->GetValue() == rRule &&
+                            pMod->IsA( TYPE( SwFmt )) &&
+                            !pMod->GetInfo( aHnt ))
+                        {
+                            *pHasChilds = TRUE;
+                            break;
+                        }
+                }
+
+            }
+        }
+    }
+
+    return nLevel;
+}
+
+const SwNumRule* SwEditShell::GetCurNumRule() const
+{
+    return GetDoc()->GetCurrNumRule( *GetCrsr()->GetPoint() );
+}
+
+BOOL SwEditShell::IsUsed( const SwNumRule& rRule ) const
+{
+    return GetDoc()->IsUsed( rRule );
+}
+
+SwNumRule* SwEditShell::GetNumRuleFromPool( USHORT nId )
+{
+    return GetDoc()->GetNumRuleFromPool( nId );
+}
+
+void SwEditShell::SetCurNumRule( const SwNumRule& rRule )
+{
+    StartAllAction();
+
+    SwPaM* pCrsr = GetCrsr();
+    if( pCrsr->GetNext() != pCrsr )         // Mehrfachselektion ?
+    {
+        GetDoc()->StartUndo( UNDO_START );
+        SwPamRanges aRangeArr( *pCrsr );
+        SwPaM aPam( *pCrsr->GetPoint() );
+        for( USHORT n = 0; n < aRangeArr.Count(); ++n )
+            GetDoc()->SetNumRule( aRangeArr.SetPam( n, aPam ), rRule );
+        GetDoc()->EndUndo( UNDO_END );
+    }
+    else
+        GetDoc()->SetNumRule( *pCrsr, rRule );
+
+    EndAllAction();
+}
+
+String SwEditShell::GetUniqueNumRuleName( const String* pChkStr, BOOL bAutoNum ) const
+{
+    return GetDoc()->GetUniqueNumRuleName( pChkStr, bAutoNum );
+}
+
+void SwEditShell::ChgNumRuleFmts( const SwNumRule& rRule )
+{
+    StartAllAction();
+    GetDoc()->ChgNumRuleFmts( rRule );
+    EndAllAction();
+}
+
+BOOL SwEditShell::ReplaceNumRule( const String& rOldRule, const String& rNewRule )
+{
+    StartAllAction();
+    BOOL bRet = GetDoc()->ReplaceNumRule( *GetCrsr()->GetPoint(), rOldRule, rNewRule );
+    EndAllAction();
+    return bRet;
+}
+
+void SwEditShell::SetNumRuleStart( BOOL bFlag )
+{
+    StartAllAction();
+
+    SwPaM* pCrsr = GetCrsr();
+    if( pCrsr->GetNext() != pCrsr )         // Mehrfachselektion ?
+    {
+        GetDoc()->StartUndo( UNDO_START );
+        SwPamRanges aRangeArr( *pCrsr );
+        SwPaM aPam( *pCrsr->GetPoint() );
+        for( USHORT n = 0; n < aRangeArr.Count(); ++n )
+            GetDoc()->SetNumRuleStart( *aRangeArr.SetPam( n, aPam ).GetPoint(), bFlag );
+        GetDoc()->EndUndo( UNDO_END );
+    }
+    else
+        GetDoc()->SetNumRuleStart( *pCrsr->GetPoint(), bFlag );
+
+    EndAllAction();
+}
+
+BOOL SwEditShell::IsNumRuleStart() const
+{
+    const SwTxtNode* pTxtNd = GetCrsr()->GetNode()->GetTxtNode();
+    if( pTxtNd && pTxtNd->GetNum() && pTxtNd->GetNumRule() )
+        return pTxtNd->GetNum()->IsStart();
+    return FALSE;
+}
+
+void SwEditShell::SetNodeNumStart( USHORT nStt )
+{
+    StartAllAction();
+
+    SwPaM* pCrsr = GetCrsr();
+    if( pCrsr->GetNext() != pCrsr )         // Mehrfachselektion ?
+    {
+        GetDoc()->StartUndo( UNDO_START );
+        SwPamRanges aRangeArr( *pCrsr );
+        SwPaM aPam( *pCrsr->GetPoint() );
+        for( USHORT n = 0; n < aRangeArr.Count(); ++n )
+            GetDoc()->SetNodeNumStart( *aRangeArr.SetPam( n, aPam ).GetPoint(), nStt );
+        GetDoc()->EndUndo( UNDO_END );
+    }
+    else
+        GetDoc()->SetNodeNumStart( *pCrsr->GetPoint(), nStt );
+
+    EndAllAction();
+}
+
+USHORT SwEditShell::IsNodeNumStart() const
+{
+    const SwTxtNode* pTxtNd = GetCrsr()->GetNode()->GetTxtNode();
+    if( pTxtNd && pTxtNd->GetNum() && pTxtNd->GetNumRule() )
+        return pTxtNd->GetNum()->GetSetValue();
+    return USHRT_MAX;
+}
+
+
+
+
diff --git a/sw/source/core/edit/edredln.cxx b/sw/source/core/edit/edredln.cxx
new file mode 100644
index 000000000000..f03944b4391e
--- /dev/null
+++ b/sw/source/core/edit/edredln.cxx
@@ -0,0 +1,228 @@
+/*************************************************************************
+ *
+ *  $RCSfile: edredln.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:18 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _SV_WINDOW_HXX //autogen
+#include 
+#endif
+#include "redline.hxx"
+#include "doc.hxx"
+#include "swundo.hxx"
+#include "editsh.hxx"
+#include "edimp.hxx"
+#include "frmtool.hxx"
+
+
+USHORT SwEditShell::GetRedlineMode() const
+{
+    return GetDoc()->GetRedlineMode();
+}
+
+void SwEditShell::SetRedlineMode( USHORT eMode )
+{
+    if( eMode != GetDoc()->GetRedlineMode() )
+    {
+        SET_CURR_SHELL( this );
+        StartAllAction();
+        GetDoc()->SetRedlineMode( eMode );
+        EndAllAction();
+    }
+}
+
+BOOL SwEditShell::IsRedlineOn() const
+{
+    return GetDoc()->IsRedlineOn();
+}
+
+USHORT SwEditShell::GetRedlineCount() const
+{
+    return GetDoc()->GetRedlineTbl().Count();
+}
+
+const SwRedline& SwEditShell::GetRedline( USHORT nPos ) const
+{
+    return *GetDoc()->GetRedlineTbl()[ nPos ];
+}
+
+void lcl_InvalidateAll( ViewShell* pSh )
+{
+    ViewShell *pStop = pSh;
+    do
+    {
+        if ( pSh->GetWin() )
+            pSh->GetWin()->Invalidate();
+        pSh = (ViewShell*)pSh->GetNext();
+
+    } while ( pSh != pStop );
+}
+
+BOOL SwEditShell::AcceptRedline( USHORT nPos )
+{
+    SET_CURR_SHELL( this );
+    StartAllAction();
+    BOOL bRet = GetDoc()->AcceptRedline( nPos );
+    if( !nPos && !::IsExtraData( GetDoc() ) )
+        lcl_InvalidateAll( this );
+    EndAllAction();
+    return bRet;
+}
+
+BOOL SwEditShell::AcceptRedline()
+{
+    SET_CURR_SHELL( this );
+    StartAllAction();
+
+    GetDoc()->StartUndo();
+    BOOL bRet = FALSE;
+    FOREACHPAM_START(this)
+        if( PCURCRSR->HasMark() && GetDoc()->AcceptRedline( *PCURCRSR ) )
+            bRet = TRUE;
+    FOREACHPAM_END()
+    GetDoc()->EndUndo();
+    if( !::IsExtraData( GetDoc() ) )
+        lcl_InvalidateAll( this );
+
+    EndAllAction();
+    return bRet;
+}
+
+BOOL SwEditShell::RejectRedline( USHORT nPos )
+{
+    SET_CURR_SHELL( this );
+    StartAllAction();
+    BOOL bRet = GetDoc()->RejectRedline( nPos );
+    if( !nPos && !::IsExtraData( GetDoc() ) )
+        lcl_InvalidateAll( this );
+    EndAllAction();
+    return bRet;
+}
+
+BOOL SwEditShell::RejectRedline()
+{
+    SET_CURR_SHELL( this );
+    StartAllAction();
+
+    GetDoc()->StartUndo();
+    BOOL bRet = FALSE;
+    FOREACHPAM_START(this)
+        if( PCURCRSR->HasMark() && GetDoc()->RejectRedline( *PCURCRSR ) )
+            bRet = TRUE;
+    FOREACHPAM_END()
+    GetDoc()->EndUndo();
+    if( !::IsExtraData( GetDoc() ) )
+        lcl_InvalidateAll( this );
+
+    EndAllAction();
+    return bRet;
+}
+
+// Kommentar am Redline setzen
+BOOL SwEditShell::SetRedlineComment( const String& rS )
+{
+    BOOL bRet = FALSE;
+    FOREACHPAM_START(this)
+        bRet = bRet || GetDoc()->SetRedlineComment( *PCURCRSR, rS );
+    FOREACHPAM_END()
+
+    return bRet;
+}
+
+const SwRedline* SwEditShell::GetCurrRedline() const
+{
+    return GetDoc()->GetRedline( *GetCrsr()->GetPoint() );
+}
+
+void SwEditShell::UpdateRedlineAttr()
+{
+    if( ( REDLINE_SHOW_INSERT | REDLINE_SHOW_DELETE ) ==
+        ( REDLINE_SHOW_MASK & GetDoc()->GetRedlineMode() ))
+    {
+        SET_CURR_SHELL( this );
+        StartAllAction();
+
+        GetDoc()->UpdateRedlineAttr();
+
+        EndAllAction();
+    }
+}
+
+    // suche das Redline zu diesem Data und returne die Pos im Array
+    // USHRT_MAX wird returnt, falls nicht vorhanden
+USHORT SwEditShell::FindRedlineOfData( const SwRedlineData& rData ) const
+{
+    const SwRedlineTbl& rTbl = GetDoc()->GetRedlineTbl();
+
+    for( USHORT i = 0, nCnt = rTbl.Count(); i < nCnt; ++i )
+        if( &rTbl[ i ]->GetRedlineData() == &rData )
+            return i;
+    return USHRT_MAX;
+}
+
+
+
diff --git a/sw/source/core/edit/edsect.cxx b/sw/source/core/edit/edsect.cxx
new file mode 100644
index 000000000000..d3e4b6263d39
--- /dev/null
+++ b/sw/source/core/edit/edsect.cxx
@@ -0,0 +1,501 @@
+/*************************************************************************
+ *
+ *  $RCSfile: edsect.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:18 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _EDITSH_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include        // fuer die UndoIds
+#endif
+#ifndef _SECTION_HXX
+#include 
+#endif
+#ifndef _EDIMP_HXX
+#include 
+#endif
+
+#ifndef _SECTFRM_HXX
+#include       // SwSectionFrm
+#endif
+#ifndef _CNTFRM_HXX
+#include        // SwCntntFrm
+#endif
+#ifndef _TABFRM_HXX
+#include        // SwTabFrm
+#endif
+
+
+    // SS fuer Bereiche
+const SwSection* SwEditShell::InsertSection( const SwSection& rNew,
+                                             const SfxItemSet* pAttr )
+{
+    const SwSection* pRet = 0;
+    if( !IsTableMode() )
+    {
+        StartAllAction();
+        GetDoc()->StartUndo( UNDO_INSSECTION );
+
+        FOREACHPAM_START(this)
+            const SwSection* pNew = GetDoc()->Insert( *PCURCRSR,
+                                                        rNew, pAttr );
+            if( !pRet )
+                pRet = pNew;
+        FOREACHPAM_END()
+
+        // Undo-Klammerung hier beenden
+        GetDoc()->EndUndo( UNDO_INSSECTION );
+        EndAllAction();
+    }
+    return pRet;
+}
+
+
+BOOL SwEditShell::IsInsRegionAvailable() const
+{
+    SwPaM* pCrsr;
+    if( IsTableMode() || ( pCrsr = GetCrsr() )->GetNext() != pCrsr )
+        return FALSE;
+    if( pCrsr->HasMark() )
+        return 0 != GetDoc()->IsInsRegionAvailable( *pCrsr );
+
+    return TRUE;
+}
+
+
+const SwSection* SwEditShell::GetCurrSection() const
+{
+    if( IsTableMode() )
+        return 0;
+
+    return GetDoc()->GetCurrSection( *GetCrsr()->GetPoint() );
+}
+
+/*-----------------17.03.99 11:53-------------------
+ * SwEditShell::GetAnySection liefert den fuer Spalten
+ * zustaendigen Bereich, bei Fussnoten kann es nicht der
+ * Bereich innerhalb der Fussnote sein.
+ * --------------------------------------------------*/
+
+const SwSection* SwEditShell::GetAnySection( BOOL bOutOfTab ) const
+{
+    SwFrm* pFrm = GetCurrFrm();
+    if( bOutOfTab && pFrm )
+        pFrm = pFrm->FindTabFrm();
+    if( pFrm && pFrm->IsInSct() )
+    {
+        SwSectionFrm* pSect = pFrm->FindSctFrm();
+        ASSERT( pSect, "GetAnySection: Where's my Sect?" );
+        if( pSect->IsInFtn() && pSect->GetUpper()->IsInSct() )
+        {
+            pSect = pSect->GetUpper()->FindSctFrm();
+            ASSERT( pSect, "GetAnySection: Where's my SectFrm?" );
+        }
+        return pSect->GetSection();
+    }
+    return NULL;
+}
+
+USHORT SwEditShell::GetSectionFmtCount() const
+{
+    return GetDoc()->GetSections().Count();
+}
+
+
+BOOL SwEditShell::IsAnySectionInDoc( BOOL bChkReadOnly, BOOL bChkHidden, BOOL bChkTOX ) const
+{
+    const SwSectionFmts& rFmts = GetDoc()->GetSections();
+    USHORT nCnt = rFmts.Count();
+    for( USHORT n = 0; n < nCnt; ++n )
+    {
+        SectionType eTmpType;
+        const SwSectionFmt* pFmt = rFmts[ n ];
+        if( pFmt->IsInNodesArr() &&
+            (bChkTOX  ||
+                (eTmpType = pFmt->GetSection()->GetType()) != TOX_CONTENT_SECTION
+                && TOX_HEADER_SECTION != eTmpType ))
+        {
+            const SwSection& rSect = *rFmts[ n ]->GetSection();
+            if( (!bChkReadOnly && !bChkHidden ) ||
+                (bChkReadOnly && rSect.IsProtectFlag() ) ||
+                (bChkHidden && rSect.IsHiddenFlag() ) )
+                break;
+        }
+    }
+    return n != nCnt;
+}
+
+USHORT SwEditShell::GetSectionFmtPos( const SwSectionFmt& rFmt ) const
+{
+    SwSectionFmt* pFmt = (SwSectionFmt*)&rFmt;
+    return GetDoc()->GetSections().GetPos( pFmt );
+}
+
+const SwSectionFmt& SwEditShell::GetSectionFmt( USHORT nFmt ) const
+{
+    return *GetDoc()->GetSections()[ nFmt ];
+}
+
+
+void SwEditShell::DelSectionFmt( USHORT nFmt )
+{
+    StartAllAction();
+    GetDoc()->DelSectionFmt( GetDoc()->GetSections()[ nFmt ] );
+    // rufe das AttrChangeNotify auf der UI-Seite.
+    CallChgLnk();
+    EndAllAction();
+}
+
+
+void SwEditShell::ChgSection( USHORT nSect, const SwSection& rSect,
+                                const SfxItemSet* pAttr )
+{
+    StartAllAction();
+    GetDoc()->ChgSection( nSect, rSect, pAttr );
+    // rufe das AttrChangeNotify auf der UI-Seite.
+    CallChgLnk();
+    EndAllAction();
+}
+
+const String& SwEditShell::GetSectionPasswd() const
+{
+    return GetDoc()->GetSectionPasswd();
+
+}
+
+
+void SwEditShell::ChgSectionPasswd( const String& sNew )
+{
+    GetDoc()->ChgSectionPasswd( sNew );
+}
+
+
+String SwEditShell::GetUniqueSectionName( const String* pChkStr ) const
+{
+    return GetDoc()->GetUniqueSectionName( pChkStr );
+}
+
+void SwEditShell::SetSectionAttr( const SfxItemSet& rSet,
+                                    SwSectionFmt* pSectFmt )
+{
+    if( pSectFmt )
+        _SetSectionAttr( *pSectFmt, rSet );
+    else
+    {
+        // for all section in the selection
+
+        FOREACHPAM_START(this)
+
+            const SwPosition* pStt = PCURCRSR->Start(),
+                            * pEnd = PCURCRSR->End();
+
+            const SwSectionNode* pSttSectNd = pStt->nNode.GetNode().FindSectionNode(),
+                               * pEndSectNd = pEnd->nNode.GetNode().FindSectionNode();
+
+            if( pSttSectNd || pEndSectNd )
+            {
+                if( pSttSectNd )
+                    _SetSectionAttr( *pSttSectNd->GetSection().GetFmt(),
+                                    rSet );
+                if( pEndSectNd && pSttSectNd != pEndSectNd )
+                    _SetSectionAttr( *pEndSectNd->GetSection().GetFmt(),
+                                    rSet );
+
+                if( pSttSectNd && pEndSectNd )
+                {
+                    SwNodeIndex aSIdx( pStt->nNode );
+                    SwNodeIndex aEIdx( pEnd->nNode );
+                    if( pSttSectNd->EndOfSectionIndex() <
+                        pEndSectNd->GetIndex() )
+                    {
+                        aSIdx = pSttSectNd->EndOfSectionIndex() + 1;
+                        aEIdx = *pEndSectNd;
+                    }
+
+                    while( aSIdx < aEIdx )
+                    {
+                        if( 0 != (pSttSectNd = aSIdx.GetNode().GetSectionNode())
+                            || ( aSIdx.GetNode().IsEndNode() &&
+                                0 != ( pSttSectNd = aSIdx.GetNode().
+                                    FindStartNode()->GetSectionNode())) )
+                            _SetSectionAttr( *pSttSectNd->GetSection().GetFmt(),
+                                            rSet );
+                        aSIdx++;
+                    }
+                }
+            }
+
+        FOREACHPAM_END()
+    }
+}
+
+void SwEditShell::_SetSectionAttr( SwSectionFmt& rSectFmt,
+                                    const SfxItemSet& rSet )
+{
+    StartAllAction();
+    if(SFX_ITEM_SET == rSet.GetItemState(RES_CNTNT, FALSE))
+    {
+        SfxItemSet aSet(rSet);
+        aSet.ClearItem(RES_CNTNT);
+        GetDoc()->SetAttr( aSet, rSectFmt );
+    }
+    else
+        GetDoc()->SetAttr( rSet, rSectFmt );
+
+    // rufe das AttrChangeNotify auf der UI-Seite.
+    CallChgLnk();
+    EndAllAction();
+}
+
+// search inside the cursor selection for full selected sections.
+// if any part of section in the selection return 0.
+// if more than one in the selection return the count
+USHORT SwEditShell::GetFullSelectedSectionCount() const
+{
+    USHORT nRet = 0;
+    FOREACHPAM_START(this)
+
+        const SwPosition* pStt = PCURCRSR->Start(),
+                        * pEnd = PCURCRSR->End();
+        const SwCntntNode* pCNd;
+        // check the selection, if Start at Node begin and End at Node end
+        if( pStt->nContent.GetIndex() ||
+            ( 0 == ( pCNd = pEnd->nNode.GetNode().GetCntntNode() )) ||
+            pCNd->Len() != pEnd->nContent.GetIndex() )
+        {
+            nRet = 0;
+            break;
+        }
+
+// !!!!!!!!!!!!!!!!!!!!!!!!!!
+// what about table at start or end ?
+//      There is no selection possible!
+// What about only a table inside the section ?
+//      There is only a table selection possible!
+
+        SwNodeIndex aSIdx( pStt->nNode, -1 ), aEIdx( pEnd->nNode, +1 );
+        if( !aSIdx.GetNode().IsSectionNode() ||
+            !aEIdx.GetNode().IsEndNode() ||
+            !aEIdx.GetNode().FindStartNode()->IsSectionNode() )
+        {
+            nRet = 0;
+            break;
+        }
+
+        ++nRet;
+        if( &aSIdx.GetNode() != aEIdx.GetNode().FindStartNode() )
+            ++nRet;
+
+    FOREACHPAM_END()
+    return nRet;
+}
+
+// is the cursor at the last contentposition of any section and is the
+// insertposition not readonly?
+// The return have 3 values:
+//  0 - not at start or end of Section
+//  1 - at start of Section
+//  2 - at End of Section
+int SwEditShell::CanInsertNodeAtEndOfSection() const
+{
+    int nRet = 0;
+    if( !IsTableMode() )
+    {
+        const SwPosition& rPos = *GetCrsr()->GetPoint();
+        const SwSectionNode* pSectNd = rPos.nNode.GetNode().FindSectionNode();
+        if( pSectNd )
+        {
+            BOOL bEnd = FALSE, bStart = FALSE;
+            const SwCntntNode* pCntNd = rPos.nNode.GetNode().GetCntntNode();
+
+            SwNodeIndex aEnd( rPos.nNode, 1 );
+            while( aEnd.GetNode().IsEndNode() &&
+                    (const SwNode*)&aEnd.GetNode() !=
+                    pSectNd->EndOfSectionNode() )
+                aEnd++;
+
+            if( aEnd.GetNode().IsEndNode() &&
+                ( !pCntNd || pCntNd->Len() == rPos.nContent.GetIndex() ))
+                bEnd = TRUE;
+            else
+            {
+                aEnd = rPos.nNode;
+                aEnd--;
+                while( aEnd.GetNode().IsStartNode() &&
+                        (const SwNode*)&aEnd.GetNode() != pSectNd )
+                    aEnd--;
+
+                if( (const SwNode*)&aEnd.GetNode() == pSectNd &&
+                    ( !pCntNd || !rPos.nContent.GetIndex() ))
+                    bStart = TRUE;
+            }
+
+            if( bEnd || bStart )
+            {
+                // is the insertposition readonly?
+                if( bEnd )
+                {
+                    aEnd = *pSectNd->EndOfSectionNode();
+                    aEnd++;
+                }
+                else
+                {
+                    aEnd = *pSectNd;
+                    aEnd--;
+                    // the IsProtect-Method of SwNode test by sectionnode
+                    // his parent!
+                    if( aEnd.GetNode().IsSectionNode() )
+                        aEnd = *pSectNd;
+                }
+
+                do {
+                    if( !aEnd.GetNode().IsProtect() )
+                    {
+                        nRet = bStart ? 1 : 2;
+                        break;
+                    }
+                    else
+                    {
+                        // skip protected sections without any content at
+                        // start or end
+                        if( bStart )
+                        {
+                            if( !aEnd.GetNode().IsSectionNode() ||
+                                !aEnd.GetNode().StartOfSectionIndex() )
+                                break;
+                            aEnd--;
+                        }
+                        else
+                        {
+                            if( !aEnd.GetNode().IsEndNode() ||
+                                !aEnd.GetNode().StartOfSectionNode()->
+                                            IsSectionNode() )
+                                break;
+                               aEnd++;
+                        }
+                    }
+                } while( TRUE );
+            }
+        }
+    }
+    return nRet;
+}
+
+BOOL SwEditShell::AppendNodeInSection()
+{
+    int nRet = CanInsertNodeAtEndOfSection();
+    if( nRet )
+    {
+        StartAllAction();
+
+        SwPosition& rPos = *GetCrsr()->GetPoint();
+        const SwSectionNode* pSectNd = rPos.nNode.GetNode().FindSectionNode();
+        SwPosition aPos( *pSectNd );
+        if( 1 == nRet )
+        {
+            do {
+                const SwNode* pPrvNd = &aPos.nNode.GetNode();
+                aPos.nNode--;
+                if( !aPos.nNode.GetNode().IsSectionNode() ||
+                    !pPrvNd->IsProtect() )
+                    break;
+            } while( TRUE );
+        }
+        else
+        {
+            SwNodeIndex aIdx( *pSectNd->EndOfSectionNode(), 1 );
+            do {
+                if( !aIdx.GetNode().IsEndNode() ||
+                    !aIdx.GetNode().FindStartNode()->IsSectionNode() ||
+                    !aIdx.GetNode().IsProtect() )
+                    break;
+                aIdx++;
+            } while( TRUE );
+            aIdx--;
+            aPos.nNode = aIdx;
+        }
+
+        GetDoc()->AppendTxtNode( aPos );
+        rPos = aPos;
+
+        // rufe das AttrChangeNotify auf der UI-Seite.
+        CallChgLnk();
+        EndAllAction();
+    }
+    return 0 != nRet;
+}
+
+
+
diff --git a/sw/source/core/edit/edtab.cxx b/sw/source/core/edit/edtab.cxx
new file mode 100644
index 000000000000..5d5178dfcccd
--- /dev/null
+++ b/sw/source/core/edit/edtab.cxx
@@ -0,0 +1,713 @@
+/*************************************************************************
+ *
+ *  $RCSfile: edtab.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:18 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#define ITEMID_BOXINFO      SID_ATTR_BORDER_INNER
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#define _SVSTDARR_ULONGS
+#include 
+
+#ifndef _APP_HXX //autogen
+#include 
+#endif
+#ifndef _WINDOW_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BOXITEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _SWWAIT_HXX
+#include 
+#endif
+#ifndef _FMTFSIZE_HXX //autogen
+#include 
+#endif
+#ifndef _FRMATR_HXX
+#include 
+#endif
+#ifndef _EDITSH_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _CNTFRM_HXX
+#include 
+#endif
+#ifndef _LAYFRM_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _HINTS_HXX
+#include 
+#endif
+#ifndef _FLDBAS_HXX
+#include 
+#endif
+#ifndef _NODE_HXX
+#include 
+#endif
+#ifndef _SWTABLE_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include 
+#endif
+#ifndef _TBLSEL_HXX
+#include 
+#endif
+#ifndef _EDIMP_HXX
+#include 
+#endif
+#ifndef _TABFRM_HXX
+#include 
+#endif
+#ifndef _CELLFRM_HXX
+#include 
+#endif
+#ifndef _CELLATR_HXX
+#include 
+#endif
+#ifndef _SWTBLFMT_HXX
+#include 
+#endif
+#ifndef _SWDDETBL_HXX
+#include 
+#endif
+#ifndef _MDIEXP_HXX
+#include 
+#endif
+
+extern void ClearFEShellTabCols();
+
+const SwTable& SwEditShell::InsertTable( USHORT nRows, USHORT nCols,
+                                        SwHoriOrient eAdj,
+                                        USHORT nInsTblFlags,
+                                        const SwTableAutoFmt* pTAFmt )
+{
+    StartAllAction();
+    SwPosition* pPos = GetCrsr()->GetPoint();
+
+    BOOL bEndUndo = 0 != pPos->nContent.GetIndex();
+    if( bEndUndo )
+    {
+        StartUndo( UNDO_START );
+        GetDoc()->SplitNode( *pPos );
+    }
+    const SwTable *pTable = GetDoc()->InsertTable( *pPos, nRows, nCols,
+                                                eAdj, nInsTblFlags, pTAFmt );
+    if( bEndUndo )
+        EndUndo( UNDO_END );
+
+    EndAllAction();
+    return *pTable;
+}
+
+BOOL SwEditShell::TextToTable( sal_Unicode cCh, SwHoriOrient eAdj,
+                                USHORT nInsTblFlags,
+                                const SwTableAutoFmt* pTAFmt )
+{
+    SwWait aWait( *GetDoc()->GetDocShell(), TRUE );
+    BOOL bRet = FALSE;
+    StartAllAction();
+    FOREACHPAM_START(this)
+        if( PCURCRSR->HasMark() )
+            bRet |= 0 != GetDoc()->TextToTable( *PCURCRSR, cCh, eAdj,
+                                                nInsTblFlags, pTAFmt );
+    FOREACHPAM_END()
+    EndAllAction();
+    return bRet;
+}
+
+BOOL SwEditShell::TableToText( sal_Unicode cCh )
+{
+    SwWait aWait( *GetDoc()->GetDocShell(), TRUE );
+    BOOL bRet = FALSE;
+    SwPaM* pCrsr = GetCrsr();
+    const SwTableNode* pTblNd =
+            GetDoc()->IsIdxInTbl( pCrsr->GetPoint()->nNode );
+    if( IsTableMode() )
+    {
+        ClearMark();
+        pCrsr = GetCrsr();
+    }
+    else if( !pTblNd || pCrsr->GetNext() != pCrsr )
+        return bRet;
+
+    StartAllAction();
+
+    // verschiebe den akt. Cursor aus dem Tabellen Bereich
+    // angemeldet ist
+#ifdef USED
+    SwNodeIndex aTabIdx( pCrsr->GetPoint()->nNode );
+#else
+    SwNodeIndex aTabIdx( *pTblNd );
+#endif
+    pCrsr->DeleteMark();
+    pCrsr->GetPoint()->nNode = *pTblNd->EndOfSectionNode();
+    pCrsr->GetPoint()->nContent.Assign( 0, 0 );
+    // SPoint und Mark aus dem Bereich verschieben !!!
+    pCrsr->SetMark();
+    pCrsr->DeleteMark();
+
+    bRet = GetDoc()->TableToText( pTblNd, cCh );
+    pCrsr->GetPoint()->nNode = aTabIdx;
+#ifdef USED
+    pCrsr->Move( fnMoveBackward, fnGoNode );
+#else
+    SwCntntNode* pCNd = pCrsr->GetCntntNode();
+    if( !pCNd )
+        pCrsr->Move( fnMoveForward, fnGoCntnt );
+    else
+        pCrsr->GetPoint()->nContent.Assign( pCNd, 0 );
+#endif
+
+    EndAllAction();
+    return bRet;
+}
+
+FASTBOOL SwEditShell::IsTextToTableAvailable() const
+{
+    FASTBOOL bOnlyText = FALSE;
+    FOREACHPAM_START(this)
+        if( PCURCRSR->HasMark() )
+        {
+            bOnlyText = TRUE;
+
+            // pruefe ob in der Selection eine Tabelle liegt
+            ULONG nStt = PCURCRSR->GetMark()->nNode.GetIndex(),
+                  nEnd = PCURCRSR->GetPoint()->nNode.GetIndex();
+            if( nStt > nEnd )   { ULONG n = nStt; nStt = nEnd; nEnd = n; }
+
+            for( ; nStt <= nEnd; ++nStt )
+                if( !GetDoc()->GetNodes()[ nStt ]->IsTxtNode() )
+                {
+                    bOnlyText = FALSE;
+                    break;
+                }
+
+            if( !bOnlyText )
+                break;
+        }
+    FOREACHPAM_END()
+
+    return bOnlyText;
+}
+
+
+void SwEditShell::InsertDDETable( SwDDEFieldType* pDDEType,
+                                            USHORT nRows, USHORT nCols,
+                                            SwHoriOrient eAdj,
+                                            USHORT nInsTblFlags )
+{
+    SwPosition* pPos = GetCrsr()->GetPoint();
+
+    ASSERT( !GetDoc()->IsIdxInTbl( pPos->nNode ),
+            "Tabelle in Tabelle nicht erlaubt" );
+
+    StartAllAction();
+
+    BOOL bEndUndo = 0 != pPos->nContent.GetIndex();
+    if( bEndUndo )
+    {
+        StartUndo( UNDO_START );
+        GetDoc()->SplitNode( *pPos );
+    }
+
+    SwTable* pTbl = (SwTable*)GetDoc()->InsertTable( *pPos, nRows, nCols, eAdj,
+                                                    nInsTblFlags|DEFAULT_BORDER );
+    SwTableNode* pTblNode = (SwTableNode*)pTbl->GetTabSortBoxes()[ 0 ]->
+                                                GetSttNd()->FindTableNode();
+    SwDDETable* pDDETbl = new SwDDETable( *pTbl, pDDEType );
+    pTblNode->SetNewTable( pDDETbl );       // setze die DDE-Tabelle
+
+    if( bEndUndo )
+        EndUndo( UNDO_END );
+
+    EndAllAction();
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Tabellenfelder einer Tabelle updaten
+ --------------------------------------------------------------------*/
+void SwEditShell::UpdateTable()
+{
+    const SwTableNode* pTblNd = IsCrsrInTbl();
+
+    // Keine Arme keine Kekse
+    if( pTblNd )
+    {
+        StartAllAction();
+        StartUndo();
+        EndAllTblBoxEdit();
+        SwTableFmlUpdate aTblUpdate( (SwTable*)&pTblNd->GetTable() );
+        GetDoc()->UpdateTblFlds( &aTblUpdate );
+        EndUndo();
+        EndAllAction();
+    }
+}
+
+    // Change Modus erfragen/setzen
+USHORT SwEditShell::GetTblChgMode() const
+{
+    USHORT nMode;
+    const SwTableNode* pTblNd = IsCrsrInTbl();
+    if( pTblNd )
+        nMode = pTblNd->GetTable().GetTblChgMode();
+    else
+        nMode = GetTblChgDefaultMode();
+    return nMode;
+}
+
+void SwEditShell::SetTblChgMode( USHORT eMode )
+{
+    const SwTableNode* pTblNd = IsCrsrInTbl();
+
+    // Keine Arme keine Kekse
+    if( pTblNd )
+    {
+        ((SwTable&)pTblNd->GetTable()).SetTblChgMode( (TblChgMode)eMode );
+        if( !GetDoc()->IsModified() )   // Bug 57028
+            GetDoc()->SetUndoNoResetModified();
+        GetDoc()->SetModified();
+    }
+}
+
+BOOL SwEditShell::GetTblBoxFormulaAttrs( SfxItemSet& rSet ) const
+{
+    SwSelBoxes aBoxes;
+    if( IsTableMode() )
+        ::GetTblSelCrs( *this, aBoxes );
+    else
+    {
+        SwPaM *pCrsr = GetCrsr();
+        do {
+            SwFrm *pFrm = GetCurrFrm();
+            do {
+                pFrm = pFrm->GetUpper();
+            } while ( pFrm && !pFrm->IsCellFrm() );
+            if ( pFrm )
+            {
+                SwTableBox *pBox = (SwTableBox*)((SwCellFrm*)pFrm)->GetTabBox();
+                aBoxes.Insert( pBox );
+            }
+        } while( FALSE
+                // JP 24.01.97: dann nur die akt. Zelle!!
+            /*((SwEditShell*)this)->GoNextCrsr() && pCrsr != GetCrsr()*/ );
+    }
+
+    for( USHORT n = 0; n < aBoxes.Count(); ++n )
+    {
+        const SwTableBox* pSelBox = aBoxes[ n ];
+        const SwTableBoxFmt* pTblFmt = (SwTableBoxFmt*)pSelBox->GetFrmFmt();
+        if( !n )
+        {
+            // Formeln in die externe Darstellung bringen!
+            const SwTable& rTbl = pSelBox->GetSttNd()->FindTableNode()->GetTable();
+
+            SwTableFmlUpdate aTblUpdate( (SwTable*)&rTbl );
+            aTblUpdate.eFlags = TBL_BOXNAME;
+            ((SwDoc*)GetDoc())->UpdateTblFlds( &aTblUpdate );
+
+            rSet.Put( pTblFmt->GetAttrSet() );
+        }
+        else
+            rSet.MergeValues( pTblFmt->GetAttrSet() );
+    }
+    return 0 != rSet.Count();
+}
+
+void SwEditShell::SetTblBoxFormulaAttrs( const SfxItemSet& rSet )
+{
+    SET_CURR_SHELL( this );
+    SwSelBoxes aBoxes;
+    if( IsTableMode() )
+        ::GetTblSelCrs( *this, aBoxes );
+    else
+    {
+        SwPaM *pCrsr = GetCrsr();
+        do {
+            SwFrm *pFrm = GetCurrFrm();
+            do {
+                pFrm = pFrm->GetUpper();
+            } while ( pFrm && !pFrm->IsCellFrm() );
+            if ( pFrm )
+            {
+                SwTableBox *pBox = (SwTableBox*)((SwCellFrm*)pFrm)->GetTabBox();
+                aBoxes.Insert( pBox );
+            }
+        } while( FALSE
+                // JP 24.01.97: dann nur die akt. Zelle!!
+            /*GoNextCrsr() && pCrsr != GetCrsr()*/ );
+    }
+
+    // beim setzen einer Formel keine Ueberpruefung mehr vornehmen!
+    if( SFX_ITEM_SET == rSet.GetItemState( RES_BOXATR_FORMULA ))
+        ClearTblBoxCntnt();
+
+    StartAllAction();
+    GetDoc()->StartUndo( UNDO_START );
+    for( USHORT n = 0; n < aBoxes.Count(); ++n )
+        GetDoc()->SetTblBoxFormulaAttrs( *aBoxes[ n ], rSet );
+    GetDoc()->EndUndo( UNDO_END );
+    EndAllAction();
+}
+
+    // Zellenbreiten ueber Min/Max Berechnung an Tabellenbreite anpassen
+void SwEditShell::OptimizeTblBoxWidthMinMax()
+{
+    SET_CURR_SHELL( this );
+
+    SwPaM *pCrsr = GetCrsr();
+    SwTableNode* pTblNd = pCrsr->GetNode()->FindTableNode();
+    if( pTblNd && !pTblNd->GetTable().IsTblComplex() )
+    {
+        SwTabFrm* pTabFrm = 0;
+        SvULongs aMinArr( 16, 16 ), aMaxArr( 16, 16 );
+
+        // ueber alle Spalten aller Zeilen und die Min/Max Breiten einsammeln
+        SwTableLines& rTblLns = pTblNd->GetTable().GetTabLines();
+        for( USHORT n = rTblLns.Count(); n; )
+        {
+            SwTableBoxes& rTblBxs = rTblLns[ --n ]->GetTabBoxes();
+            for( USHORT i = 0; i < rTblBxs.Count(); ++i )
+            {
+                SwTableBox* pBox = rTblBxs[ i ];
+
+                ULONG nMinCell = 0;
+                ULONG nMaxCell = 0;
+
+                // ueber alle Absaetze und die Min/Maxbreiten berechnen
+                const SwStartNode* pSttNd = pBox->GetSttNd();
+                SwNodeIndex aIdx( *pSttNd, 1 );
+                SwNodeIndex aEnd( *pSttNd->EndOfSectionNode() );
+                while( aIdx < aEnd )
+                {
+                    SwTxtNode *pTxtNd = aIdx.GetNode().GetTxtNode();
+                    if( pTxtNd )
+                    {
+                        ULONG nMinCnts;
+                        ULONG nMaxCnts;
+                        ULONG nAbsMinCnts;
+                        pTxtNd->GetMinMaxSize( aIdx.GetIndex(), nMinCnts,
+                                               nMaxCnts, nAbsMinCnts );
+
+                        if( nMinCnts > nMinCell )
+                            nMinCell = nMinCnts;
+                        if( nMaxCnts > nMaxCell )
+                            nMaxCell = nMaxCnts;
+
+                        if( !pTabFrm )
+                        {
+                            SwCntntFrm* pCFrm = pTxtNd->GetFrm( 0, 0, FALSE );
+                            if( pCFrm )
+                                pTabFrm = pCFrm->FindTabFrm();
+                        }
+                    }
+                    aIdx++;
+                }
+
+                // Mindestbreite fuer Inhalt einhalten
+                if( nMinCell < MINLAY )
+                    nMinCell = MINLAY;
+                if( nMaxCell < MINLAY )
+                    nMaxCell = MINLAY;
+
+                // Umrandung und Abstand zum Inhalt beachten
+                const SvxBoxItem& rBoxItem = pBox->GetFrmFmt()->GetBox();
+                USHORT nBrdDist = 0;
+                if( rBoxItem.GetLeft() )
+                {
+                    USHORT nWidth = rBoxItem.GetLeft()->GetOutWidth() +
+                                    rBoxItem.GetLeft()->GetInWidth();
+                    if( !nBrdDist )
+                        nBrdDist = rBoxItem.GetLeft()->GetDistance();
+
+                    nMinCell += nWidth;
+                    nMaxCell += nWidth;
+                }
+                if( rBoxItem.GetRight() )
+                {
+                    USHORT nWidth = rBoxItem.GetRight()->GetOutWidth() +
+                                    rBoxItem.GetRight()->GetInWidth();
+                    if( !nBrdDist )
+                        nBrdDist = rBoxItem.GetRight()->GetDistance();
+
+                    nMinCell += nWidth;
+                    nMaxCell += nWidth;
+                }
+                if( !nBrdDist )
+                    nBrdDist = MIN_BORDER_DIST;
+                nMinCell += 2 * nBrdDist;
+                nMaxCell += 2 * nBrdDist;
+
+                // Max/Min-Werte in den Arrays merken
+                if( i >= aMinArr.Count() )
+                    aMinArr.Insert( nMinCell, i );
+                else if( nMinCell > aMinArr[ i ] )
+                    aMinArr.Replace( nMinCell, i );
+
+                if( i >= aMaxArr.Count() )
+                    aMaxArr.Insert( nMaxCell, i );
+                else if( nMaxCell > aMaxArr[ i ] )
+                    aMaxArr.Replace( nMaxCell, i );
+            }
+        }
+
+        ASSERT( pTabFrm, "ohne TabFrm kann nichts berechnet werden" );
+        if( pTabFrm )
+        {
+            // 2. Teil die Zellen an die Breiten anpassen
+            ULONG nTableMin = 0;
+            ULONG nTableMax = 0;
+            for( n = aMinArr.Count(); n; )
+            {
+                nTableMin += aMinArr[ --n ];
+                nTableMax += aMaxArr[   n ];
+            }
+
+            // Dann errechne mal die Breiten fuer die Spalten. Die Werte
+            // werden im MinArray gesammelt!
+
+            // die MinBreite ist schon groesser als der vorgesehene Platz
+            ULONG nAbsTabWidth = pTabFrm->Prt().Width();
+            if( nTableMin > nAbsTabWidth )
+            {
+                for( n = aMinArr.Count(); n; )
+                {
+                    ULONG nColMin = aMinArr[ --n ];
+                    nColMin *= nAbsTabWidth;
+                    nColMin /= nTableMin;
+                    aMinArr.Replace( nColMin, n );
+                }
+            }
+            // die MaxBreite ist kleiner als der vorgesehene Platz
+            else if( nTableMax < nAbsTabWidth )
+            {
+                for( n = aMinArr.Count(); n; )
+                {
+                    ULONG nColMax = aMaxArr[ --n ];
+                    nColMax *= nAbsTabWidth;
+                    nColMax /= nTableMax;
+                    aMinArr.Replace( nColMax, n );
+                }
+            }
+            else
+            {
+                double nW = nAbsTabWidth - nTableMin;
+                double nD = nTableMax == nTableMin ? 1 : nTableMax - nTableMin;
+                for( n = 0; n < aMinArr.Count(); ++n )
+                {
+                    double nd = aMaxArr[ n ] - aMinArr[ n ];
+                    ULONG nAbsColWidth = aMinArr[ n ] + (ULONG)(( nd * nW ) / nD );
+                    aMinArr.Replace( nAbsColWidth, n );
+                }
+            }
+
+            StartAllAction();
+            GetDoc()->AppendUndoForAttrTable( pTblNd->GetTable() );
+
+            for( n = 0; n < rTblLns.Count(); ++n )
+            {
+                SwTableBoxes& rTblBxs = rTblLns[ n ]->GetTabBoxes();
+                for( USHORT i = rTblBxs.Count(); i; )
+                {
+                    SwTableBox* pBox = rTblBxs[ --i ];
+                    pBox->ClaimFrmFmt()->SetAttr( SwFmtFrmSize( ATT_VAR_SIZE,
+                                                    aMinArr[ i ] ));
+                }
+            }
+
+            SwTableFmt* pFmt = (SwTableFmt*)pTblNd->GetTable().GetFrmFmt();
+            pFmt->LockModify();
+            pFmt->SetAttr( SwFmtFrmSize( ATT_VAR_SIZE, nAbsTabWidth ));
+            pFmt->UnlockModify();
+
+            EndAllAction();
+        }
+    }
+}
+
+BOOL SwEditShell::IsTableBoxTextFormat() const
+{
+    if( IsTableMode() )
+        return FALSE;
+
+    SwTableBox *pBox = 0;
+    SwPaM *pCrsr = GetCrsr();
+    {
+        SwFrm *pFrm = GetCurrFrm();
+        do {
+            pFrm = pFrm->GetUpper();
+        } while ( pFrm && !pFrm->IsCellFrm() );
+        if ( pFrm )
+            pBox = (SwTableBox*)((SwCellFrm*)pFrm)->GetTabBox();
+    }
+
+    if( !pBox )
+        return FALSE;
+
+    ULONG nFmt;
+    const SfxPoolItem* pItem;
+    if( SFX_ITEM_SET == pBox->GetFrmFmt()->GetAttrSet().GetItemState(
+        RES_BOXATR_FORMAT, TRUE, &pItem ))
+    {
+        nFmt = ((SwTblBoxNumFormat*)pItem)->GetValue();
+        return GetDoc()->GetNumberFormatter()->IsTextFormat( nFmt ) ||
+                NUMBERFORMAT_TEXT == nFmt;
+    }
+
+    ULONG nNd = pBox->IsValidNumTxtNd();
+    if( ULONG_MAX == nNd )
+        return TRUE;
+
+    const String& rTxt = GetDoc()->GetNodes()[ nNd ]->GetTxtNode()->GetTxt();
+    if( !rTxt.Len() )
+        return FALSE;
+
+    double fVal;
+    return !GetDoc()->GetNumberFormatter()->IsNumberFormat( rTxt, nFmt, fVal );
+}
+
+
+BOOL SwEditShell::SplitTable( USHORT eMode )
+{
+    BOOL bRet = FALSE;
+    SwPaM *pCrsr = GetCrsr();
+    if( pCrsr->GetNode()->FindTableNode() )
+    {
+        StartAllAction();
+        GetDoc()->StartUndo();
+
+        bRet = GetDoc()->SplitTable( *pCrsr->GetPoint(), eMode, TRUE );
+
+        GetDoc()->EndUndo();
+        ClearFEShellTabCols();
+        EndAllAction();
+    }
+    return bRet;
+}
+
+BOOL SwEditShell::MergeTable( BOOL bWithPrev, USHORT nMode )
+{
+    BOOL bRet = FALSE;
+    SwPaM *pCrsr = GetCrsr();
+    if( pCrsr->GetNode()->FindTableNode() )
+    {
+        StartAllAction();
+        GetDoc()->StartUndo();
+
+        bRet = GetDoc()->MergeTable( *pCrsr->GetPoint(), bWithPrev, nMode );
+
+        GetDoc()->EndUndo();
+        ClearFEShellTabCols();
+        EndAllAction();
+    }
+    return bRet;
+}
+
+BOOL SwEditShell::CanMergeTable( BOOL bWithPrev, BOOL* pChkNxtPrv ) const
+{
+    BOOL bRet = FALSE;
+    const SwPaM *pCrsr = GetCrsr();
+    const SwTableNode* pTblNd = pCrsr->GetNode()->FindTableNode();
+    if( pTblNd && !pTblNd->GetTable().ISA( SwDDETable ))
+    {
+        const SwNodes& rNds = GetDoc()->GetNodes();
+        if( pChkNxtPrv )
+        {
+            const SwTableNode* pChkNd = rNds[ pTblNd->GetIndex() - 1 ]->FindTableNode();
+            if( pChkNd && !pChkNd->GetTable().ISA( SwDDETable ) )
+                *pChkNxtPrv = TRUE, bRet = TRUE;        // mit Prev ist moeglich
+            else
+            {
+                pChkNd = rNds[ pTblNd->EndOfSectionIndex() + 1 ]->GetTableNode();
+                if( pChkNd && !pChkNd->GetTable().ISA( SwDDETable ) )
+                    *pChkNxtPrv = FALSE, bRet = TRUE;       // mit Next ist moeglich
+            }
+        }
+        else
+        {
+            if( bWithPrev )
+                pTblNd = rNds[ pTblNd->GetIndex() - 1 ]->FindTableNode();
+            else
+                pTblNd = rNds[ pTblNd->EndOfSectionIndex() + 1 ]->GetTableNode();
+
+            bRet = pTblNd && !pTblNd->GetTable().ISA( SwDDETable );
+        }
+    }
+    return bRet;
+}
+
diff --git a/sw/source/core/edit/edtox.cxx b/sw/source/core/edit/edtox.cxx
new file mode 100644
index 000000000000..5a6054208b4a
--- /dev/null
+++ b/sw/source/core/edit/edtox.cxx
@@ -0,0 +1,547 @@
+/*************************************************************************
+ *
+ *  $RCSfile: edtox.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:18 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#if SUPD<591
+#include 
+#endif
+#ifndef _UCBHELPER_CONTENT_HXX
+#include 
+#endif
+#ifndef _EDITSH_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _VIEWOPT_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _ERRHDL_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include 
+#endif
+#ifndef _TXTTXMRK_HXX //autogen
+#include 
+#endif
+#ifndef _EDIMP_HXX
+#include 
+#endif
+#ifndef _TOX_HXX
+#include 
+#endif
+#ifndef _DOCTXM_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _MDIEXP_HXX
+#include 
+#endif
+#ifndef _STATSTR_HRC
+#include 
+#endif
+#ifndef _TXTCMP_HXX //autogen wg. SearchParam
+#include 
+#endif
+#ifndef _URLOBJ_HXX
+#include 
+#endif
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::uno;
+using namespace ::rtl;
+
+/*--------------------------------------------------------------------
+     Beschreibung: Verzeichnismarkierung ins Dokument einfuegen/loeschen
+ --------------------------------------------------------------------*/
+
+
+void SwEditShell::Insert(const SwTOXMark& rMark)
+{
+    BOOL bInsAtPos = rMark.IsAlternativeText();
+    StartAllAction();
+    FOREACHPAM_START(this)
+
+        const SwPosition *pStt = PCURCRSR->Start(),
+                         *pEnd = PCURCRSR->End();
+        if( bInsAtPos )
+        {
+            SwPaM aTmp( *pStt );
+            GetDoc()->Insert( aTmp, rMark, 0 );
+        }
+        else if( *pEnd != *pStt )
+            GetDoc()->Insert( *PCURCRSR, rMark, SETATTR_DONTEXPAND );
+
+    FOREACHPAM_END()
+    EndAllAction();
+}
+
+
+
+void SwEditShell::DeleteTOXMark( SwTOXMark* pMark )
+{
+    SET_CURR_SHELL( this );
+    StartAllAction();
+
+    pDoc->Delete( pMark );
+
+    EndAllAction();
+}
+
+
+/*--------------------------------------------------------------------
+     Beschreibung: Alle Verzeichnismarkierungen am SPoint zusammensuchen
+ --------------------------------------------------------------------*/
+
+USHORT SwEditShell::GetCurTOXMarks(SwTOXMarks& rMarks) const
+{
+    return GetDoc()->GetCurTOXMark( *GetCrsr()->Start(), rMarks );
+}
+/* -----------------01.09.99 16:05-------------------
+
+ --------------------------------------------------*/
+const SwAttrSet& SwEditShell::GetTOXBaseAttrSet(const SwTOXBase& rTOXBase) const
+{
+    return GetDoc()->GetTOXBaseAttrSet(rTOXBase);
+}
+/* -----------------01.09.99 16:05-------------------
+
+ --------------------------------------------------*/
+BOOL SwEditShell::IsTOXBaseReadonly(const SwTOXBase& rTOXBase) const
+{
+    ASSERT( rTOXBase.ISA( SwTOXBaseSection ), "no TOXBaseSection!" );
+    const SwTOXBaseSection& rTOXSect = (const SwTOXBaseSection&)rTOXBase;
+    return  rTOXSect.IsProtect();
+}
+/* -----------------18.10.99 15:53-------------------
+
+ --------------------------------------------------*/
+void SwEditShell::SetTOXBaseReadonly(const SwTOXBase& rTOXBase, BOOL bReadonly)
+{
+    ASSERT( rTOXBase.ISA( SwTOXBaseSection ), "no TOXBaseSection!" );
+    const SwTOXBaseSection& rTOXSect = (const SwTOXBaseSection&)rTOXBase;
+    ((SwTOXBase&)rTOXBase).SetProtected(bReadonly);
+    ASSERT( rTOXSect.SwSection::GetType() == TOX_CONTENT_SECTION, "not a TOXContentSection" );
+
+    SwSection aSect(TOX_CONTENT_SECTION, rTOXSect.GetName());
+    aSect = rTOXSect;
+    aSect.SetProtect(bReadonly);
+    ChgSection( GetSectionFmtPos( *rTOXSect.GetFmt()  ), aSect, 0 );
+}
+
+/* -----------------02.09.99 07:47-------------------
+
+ --------------------------------------------------*/
+const SwTOXBase*    SwEditShell::GetDefaultTOXBase( TOXTypes eTyp, BOOL bCreate )
+{
+    return GetDoc()->GetDefaultTOXBase( eTyp, bCreate );
+}
+/* -----------------02.09.99 08:05-------------------
+
+ --------------------------------------------------*/
+void    SwEditShell::SetDefaultTOXBase(const SwTOXBase& rBase)
+{
+    GetDoc()->SetDefaultTOXBase(rBase);
+}
+
+/*--------------------------------------------------------------------
+     Beschreibung: Verzeichnis einfuegen, und Inhalt erzeugen
+ --------------------------------------------------------------------*/
+
+void SwEditShell::InsertTableOf( const SwTOXBase& rTOX, const SfxItemSet* pSet )
+{
+    SET_CURR_SHELL( this );
+    StartAllAction();
+
+    SwDocShell* pDocSh = GetDoc()->GetDocShell();
+    ::StartProgress( STR_STATSTR_TOX_INSERT, 0, 0, pDocSh );
+    ::SetProgressText( STR_STATSTR_TOX_INSERT, pDocSh );
+
+    // Einfuegen des Verzeichnisses
+    const SwTOXBaseSection* pTOX = pDoc->InsertTableOf(
+                                        *GetCrsr()->GetPoint(), rTOX, pSet, TRUE );
+    ASSERT(pTOX, "Kein aktuelles Verzeichnis");
+
+    // Formatierung anstossen
+    CalcLayout();
+
+    // Seitennummern eintragen
+    ((SwTOXBaseSection*)pTOX)->UpdatePageNum();
+
+    pTOX->SetPosAtStartEnd( *GetCrsr()->GetPoint() );
+
+    // Fix fuer leere Verzeichnisse
+    InvalidateWindows( aVisArea );
+    ::EndProgress( pDocSh );
+    EndAllAction();
+}
+
+/*--------------------------------------------------------------------
+     Beschreibung: Verzeichnisinhalt erneuern
+ --------------------------------------------------------------------*/
+
+BOOL SwEditShell::UpdateTableOf( const SwTOXBase& rTOX, const SfxItemSet* pSet )
+{
+    BOOL bRet = FALSE;
+
+    ASSERT( rTOX.ISA( SwTOXBaseSection ),  "keine TOXBaseSection!" );
+    SwTOXBaseSection* pTOX = (SwTOXBaseSection*)&rTOX;
+    ASSERT(pTOX, "Keine aktuelles Verzeichnis");
+    const SwSectionNode* pSectNd;
+    if( pTOX && 0 != ( pSectNd = pTOX->GetFmt()->GetSectionNode() ) )
+    {
+        SwDoc* pDoc = GetDoc();
+        SwDocShell* pDocSh = pDoc->GetDocShell();
+
+        BOOL bInIndex = pTOX == GetCurTOX();
+        SET_CURR_SHELL( this );
+        StartAllAction();
+
+        ::StartProgress( STR_STATSTR_TOX_UPDATE, 0, 0, pDocSh );
+        ::SetProgressText( STR_STATSTR_TOX_UPDATE, pDocSh );
+
+        BOOL bWasUndo = pDoc->DoesUndo();
+        pDoc->DoUndo( FALSE );
+
+        // Verzeichnisrumpf erzeugen
+        pTOX->Update(pSet);
+
+        // Cursor korrigieren
+        if( bInIndex )
+            pTOX->SetPosAtStartEnd( *GetCrsr()->GetPoint() );
+
+        // Formatierung anstossen
+        CalcLayout();
+
+        // Seitennummern eintragen
+        pTOX->UpdatePageNum();
+
+        pDoc->DoUndo( bWasUndo );
+
+        //JP erstmal ein Hack, solange keine Verzeichnisse Undofaehig sind
+        if( bWasUndo )
+            pDoc->DelAllUndoObj();
+
+        ::EndProgress( pDocSh );
+        EndAllAction();
+    }
+    return bRet;
+}
+
+/*--------------------------------------------------------------------
+     Beschreibung: Aktuelles Verzeichnis vor oder in dem der Cursor
+                                   steht
+ --------------------------------------------------------------------*/
+
+const SwTOXBase* SwEditShell::GetCurTOX() const
+{
+    return GetDoc()->GetCurTOX( *GetCrsr()->GetPoint() );
+}
+
+BOOL SwEditShell::DeleteTOX( const SwTOXBase& rTOXBase, BOOL bDelNodes )
+{
+    return GetDoc()->DeleteTOX( (SwTOXBase&)rTOXBase, bDelNodes );
+}
+
+BOOL SwEditShell::DeleteCurTOX()
+{
+    SwTOXBase* pTOX = (SwTOXBase*)GetDoc()->GetCurTOX(*GetCrsr()->GetPoint());
+    return pTOX ? GetDoc()->DeleteTOX( *pTOX, TRUE ) : FALSE;
+}
+
+/*--------------------------------------------------------------------
+     Beschreibung: Typen der Verzeichnisse verwalten
+ --------------------------------------------------------------------*/
+
+const SwTOXType* SwEditShell::GetTOXType(TOXTypes eTyp, USHORT nId) const
+{
+    return pDoc->GetTOXType(eTyp, nId);
+}
+
+/*--------------------------------------------------------------------
+     Beschreibung: Schluessel fuer Stichwortverzeichnisse verwalten
+ --------------------------------------------------------------------*/
+
+USHORT SwEditShell::GetTOIKeys( SwTOIKeyType eTyp, SvStringsSort& rArr ) const
+{
+    return GetDoc()->GetTOIKeys( eTyp, rArr );
+}
+
+
+USHORT SwEditShell::GetTOXCount() const
+{
+    const SwSectionFmts& rFmts = GetDoc()->GetSections();
+    USHORT nRet = 0;
+    for( USHORT n = rFmts.Count(); n; )
+    {
+        const SwSection* pSect = rFmts[ --n ]->GetSection();
+        if( TOX_CONTENT_SECTION == pSect->GetType() &&
+            pSect->GetFmt()->GetSectionNode() )
+            ++nRet;
+    }
+    return nRet;
+}
+
+
+const SwTOXBase* SwEditShell::GetTOX( USHORT nPos ) const
+{
+    const SwSectionFmts& rFmts = GetDoc()->GetSections();
+    for( USHORT n = 0, nCnt = 0; n < rFmts.Count(); ++n )
+    {
+        const SwSection* pSect = rFmts[ n ]->GetSection();
+        if( TOX_CONTENT_SECTION == pSect->GetType() &&
+            pSect->GetFmt()->GetSectionNode() &&
+            nCnt++ == nPos )
+        {
+            ASSERT( pSect->ISA( SwTOXBaseSection ), "keine TOXBaseSection!" );
+            return (SwTOXBaseSection*)pSect;
+        }
+    }
+    return 0;
+}
+
+
+    // nach einlesen einer Datei alle Verzeichnisse updaten
+void SwEditShell::SetUpdateTOX( BOOL bFlag )
+{
+    GetDoc()->SetUpdateTOX( bFlag );
+}
+
+
+BOOL SwEditShell::IsUpdateTOX() const
+{
+    return GetDoc()->IsUpdateTOX();
+}
+/*--------------------------------------------------------------------
+
+ --------------------------------------------------------------------*/
+String SwEditShell::GetUniqueTOXBaseName( const SwTOXType& rType,
+                                const String* pChkStr ) const
+{
+    return GetDoc()->GetUniqueTOXBaseName( rType, pChkStr );
+}
+/*--------------------------------------------------------------------
+
+ --------------------------------------------------------------------*/
+BOOL SwEditShell::SetTOXBaseName(const SwTOXBase& rTOXBase, const String& rName)
+{
+    return GetDoc()->SetTOXBaseName(rTOXBase, rName);
+}
+/*--------------------------------------------------------------------
+
+ --------------------------------------------------------------------*/
+void SwEditShell::SetTOXBaseProtection(const SwTOXBase& rTOXBase, BOOL bProtect)
+{
+    GetDoc()->SetTOXBaseProtection(rTOXBase, bProtect);
+}
+/* -----------------26.08.99 13:49-------------------
+
+ --------------------------------------------------*/
+const String&   SwEditShell::GetTOIAutoMarkURL() const
+{
+    return GetDoc()->GetTOIAutoMarkURL();
+}
+/* -----------------26.08.99 13:49-------------------
+
+ --------------------------------------------------*/
+void SwEditShell::SetTOIAutoMarkURL(const String& rSet)
+{
+    GetDoc()->SetTOIAutoMarkURL(rSet);
+}
+/* -----------------26.08.99 09:29-------------------
+
+ --------------------------------------------------*/
+void SwEditShell::ApplyAutoMark()
+{
+    StartAllAction();
+    BOOL bDoesUndo = DoesUndo();
+    DoUndo(FALSE);
+    //1. remove all automatic generated index entries if AutoMarkURL has a
+    //   length and the file exists
+    //2. load file
+    //3. select all occurrences of the searched words
+    //4. apply index entries
+
+    String sAutoMarkURL(GetDoc()->GetTOIAutoMarkURL());
+    BOOL bIsDocument = FALSE;
+    if(sAutoMarkURL.Len())
+    {
+        try
+        {
+            ::ucb::Content aTestContent(
+    #if SUPD<591
+                SW_MOD()->GetContentBroker(),
+    #endif
+                sAutoMarkURL,
+                uno::Reference< XCommandEnvironment >());
+            bIsDocument = aTestContent.isDocument();
+        }
+        catch(...)
+        {
+            DBG_ERROR("Exception caught")
+        }
+    }
+
+    if( bIsDocument )
+    {
+        //1.
+        const SwTOXType* pTOXType = GetTOXType(TOX_INDEX, 0);
+        SwClientIter aIter(*(SwTOXType*)pTOXType);
+        SwTOXMark* pMark = (SwTOXMark*)aIter.First(TYPE(SwTOXMark));
+        while( pMark )
+        {
+            if(pMark->IsAutoGenerated() && pMark->GetTxtTOXMark())
+                DeleteTOXMark(pMark);
+            pMark = (SwTOXMark*)aIter.Next();
+        }
+
+        //2.
+        SvFileStream aStream(sAutoMarkURL, STREAM_STD_READ);
+        aStream.ReOpen();
+        aStream.Seek(0);
+        ULONG nError = aStream.GetError();
+        const String sZero('0');
+        Push();
+        rtl_TextEncoding eChrSet = ::gsl_getSystemTextEncoding();
+
+        while(!aStream.GetError() && !aStream.IsEof())
+        {
+            ByteString aRdLine;
+            aStream.ReadLine( aRdLine );
+
+            // # -> comment
+            // ; -> delimiter between entries ->
+            // Format: TextToSearchFor;AlternativeString;PrimaryKey;SecondaryKey;CaseSensitive;WordOnly
+            // Leading and trailing blanks are ignored
+            if( aRdLine.Len() && aRdLine.GetChar(0) != '#')
+            {
+                String sLine( aRdLine, eChrSet );
+
+                xub_StrLen nTokenPos = 0;
+                String sToSelect( sLine.GetToken(0, ';', nTokenPos ) );
+                if( sToSelect.Len() )
+                {
+                    String sAlternative = sLine.GetToken(0, ';', nTokenPos);
+                    String sPrimary     = sLine.GetToken(0, ';', nTokenPos);
+                    String sSecondary   = sLine.GetToken(0, ';', nTokenPos);
+                    String sCase        = sLine.GetToken(0, ';', nTokenPos);
+                    String sWordOnly    = sLine.GetToken(0, ';', nTokenPos);
+
+                    //3.
+                    SearchParam aParam( sToSelect, SearchParam::SRCH_NORMAL,
+                                                TRUE, FALSE, FALSE );
+                    BOOL bCaseSensitive = sCase.Len() && sCase != sZero;
+                    BOOL bWordOnly = sWordOnly.Len() && sWordOnly != sZero;
+                    aParam.SetCaseSensitive( bCaseSensitive );
+                    aParam.SetSrchWordOnly( bWordOnly );
+
+                    KillPams();
+                    ULONG nRet = Find( aParam,  DOCPOS_START, DOCPOS_END,
+                                        (FindRanges)(FND_IN_SELALL|FND_IN_BODYONLY), FALSE );
+
+                    if(nRet)
+                    {
+                        SwTOXMark* pMark = new SwTOXMark(pTOXType);
+                        if( sPrimary.Len() )
+                        {
+                            pMark->SetPrimaryKey( sPrimary );
+                            if( sSecondary.Len() )
+                                pMark->SetSecondaryKey( sSecondary );
+                        }
+                        if(sAlternative.Len())
+                            pMark->SetAlternativeText(sAlternative);
+                        pMark->SetMainEntry(FALSE);
+                        pMark->SetAutoGenerated(TRUE);
+                        //4.
+                        SwEditShell::Insert(*pMark);
+                    }
+
+                }
+            }
+        }
+        aStream.Close();
+        KillPams();
+        Pop(FALSE);
+    }
+    DoUndo(bDoesUndo);
+    EndAllAction();
+}
+
+
+
+
+
diff --git a/sw/source/core/edit/edundo.cxx b/sw/source/core/edit/edundo.cxx
new file mode 100644
index 000000000000..c29062354ec4
--- /dev/null
+++ b/sw/source/core/edit/edundo.cxx
@@ -0,0 +1,312 @@
+/*************************************************************************
+ *
+ *  $RCSfile: edundo.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:18 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _SVDVIEW_HXX //autogen wg. SdrView
+#include 
+#endif
+
+#ifndef _EDITSH_HXX
+#include 
+#endif
+#ifndef _FESH_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _UNDOBJ_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include 
+#endif
+#ifndef _DCONTACT_HXX
+#include 
+#endif
+#ifndef _FLYFRM_HXX
+#include 
+#endif
+#ifndef _FRMFMT_HXX
+#include 
+#endif
+#ifndef _VIEWIMP_HXX
+#include 
+#endif
+
+
+BOOL SwEditShell::Undo(USHORT nUndoId)
+{
+    SET_CURR_SHELL( this );
+
+    BOOL bRet = FALSE;
+
+    GetDoc()->DoUndo( FALSE );
+    StartAllAction();
+    {
+        // eigentlich muesste ja nur der aktuelle Cursor berarbeitet
+        // werden, d.H. falls ein Ring besteht, diesen temporaer aufheben,
+        // damit nicht bei Einfuge-Operationen innerhalb von Undo
+        // an allen Bereichen eingefuegt wird.
+        KillPams();
+        SetMark();          // Bound1 und Bound2 in den gleichen Node
+        ClearMark();
+
+        // JP 02.04.98: Cursor merken - beim Auto-Format/-Korrektur
+        //              soll dieser wieder an die Position
+        USHORT nLastUndoId = GetDoc()->GetUndoIds();
+        BOOL bRestoreCrsr = UNDO_AUTOFORMAT == nLastUndoId ||
+                            UNDO_AUTOCORRECT == nLastUndoId;
+        Push();
+
+        //JP 18.09.97: gesicherten TabellenBoxPtr zerstoeren, eine autom.
+        //          Erkennung darf nur noch fuer die neue "Box" erfolgen!
+        ClearTblBoxCntnt();
+
+        SwRedlineMode eOld = GetDoc()->GetRedlineMode();
+
+        SwUndoIter aUndoIter( GetCrsr(), nUndoId );
+        do {
+
+            bRet |= GetDoc()->Undo( aUndoIter );
+
+            if( !aUndoIter.IsNextUndo() )
+                break;
+
+            // es geht weiter, also erzeuge einen neuen Cursor wenn
+            // der alte schon eine Selection hat
+            // JP 02.04.98: aber nicht wenns ein Autoformat ist
+            if( !bRestoreCrsr && HasSelection() )
+            {
+                CreateCrsr();
+                aUndoIter.pAktPam = GetCrsr();
+            }
+        } while( TRUE );
+
+        Pop( !bRestoreCrsr );
+
+        if( aUndoIter.pSelFmt )     // dann erzeuge eine Rahmen-Selection
+        {
+            if( RES_DRAWFRMFMT == aUndoIter.pSelFmt->Which() )
+            {
+                SdrObject* pSObj = aUndoIter.pSelFmt->FindSdrObject();
+                ((SwFEShell*)this)->SelectObj( pSObj->GetBoundRect().Center() );
+            }
+            else
+            {
+                Point aPt;
+                SwFlyFrm* pFly = ((SwFlyFrmFmt*)aUndoIter.pSelFmt)->GetFrm(
+                                                            &aPt, FALSE );
+                if( pFly )
+                    ((SwFEShell*)this)->SelectFlyFrm( *pFly, TRUE );
+            }
+        }
+        else if( aUndoIter.pMarkList )
+        {
+            if( HasDrawView() )
+            {
+                SdrView *pView = GetDrawView();
+                pView->UnmarkAll();
+                const SdrMarkList& rLst = *aUndoIter.pMarkList;
+                for( USHORT i = 0; i < rLst.GetMarkCount(); ++i )
+                    pView->MarkObj( rLst.GetMark( i )->GetObj(),
+                                    Imp()->GetPageView() );
+            }
+        }
+        else if( GetCrsr()->GetNext() != GetCrsr() )    // gehe nach einem
+            GoNextCrsr();               // Undo zur alten Undo-Position !!
+
+        GetDoc()->SetRedlineMode( eOld );
+        GetDoc()->CompressRedlines();
+
+        //JP 18.09.97: autom. Erkennung  fuer die neue "Box"
+        SaveTblBoxCntnt();
+    }
+    EndAllAction();
+    GetDoc()->DoUndo( TRUE );
+    return bRet;
+}
+
+
+USHORT SwEditShell::Redo()
+{
+    SET_CURR_SHELL( this );
+
+    BOOL bRet = FALSE;
+    GetDoc()->DoUndo( FALSE );
+    StartAllAction();
+
+    {
+        // eigentlich muesste ja nur der aktuelle Cursor berarbeitet
+        // werden, d.H. falls ein Ring besteht, diesen temporaer aufheben,
+        // damit nicht bei Einfuge-Operationen innerhalb von Undo
+        // an allen Bereichen eingefuegt wird.
+        KillPams();
+        SetMark();          // Bound1 und Bound2 in den gleichen Node
+        ClearMark();
+
+        //JP 18.09.97: gesicherten TabellenBoxPtr zerstoeren, eine autom.
+        //          Erkennung darf nur noch fuer die neue "Box" erfolgen!
+        ClearTblBoxCntnt();
+
+        SwRedlineMode eOld = GetDoc()->GetRedlineMode();
+
+        SwUndoIter aUndoIter( GetCrsr(), 0 );
+        do {
+
+            bRet |= GetDoc()->Redo( aUndoIter );
+
+            if( !aUndoIter.IsNextUndo() )
+                break;
+
+            // es geht weiter, also erzeugen einen neuen Cursor wenn
+            // der alte schon eine SSelection hat
+            if( HasSelection() )
+            {
+                CreateCrsr();
+                aUndoIter.pAktPam = GetCrsr();
+            }
+        } while( TRUE );
+
+        if( aUndoIter.IsUpdateAttr() )
+            UpdateAttr();
+
+        if( aUndoIter.pSelFmt )     // dann erzeuge eine Rahmen-Selection
+        {
+            if( RES_DRAWFRMFMT == aUndoIter.pSelFmt->Which() )
+            {
+                SdrObject* pSObj = aUndoIter.pSelFmt->FindSdrObject();
+                ((SwFEShell*)this)->SelectObj( pSObj->GetBoundRect().Center() );
+            }
+            else
+            {
+                Point aPt;
+                SwFlyFrm* pFly = ((SwFlyFrmFmt*)aUndoIter.pSelFmt)->GetFrm(
+                                                            &aPt, FALSE );
+                if( pFly )
+                    ((SwFEShell*)this)->SelectFlyFrm( *pFly, TRUE );
+            }
+        }
+        else if( aUndoIter.pMarkList )
+        {
+            if( HasDrawView() )
+            {
+                SdrView *pView = GetDrawView();
+                pView->UnmarkAll();
+                const SdrMarkList& rLst = *aUndoIter.pMarkList;
+                for( USHORT i = 0; i < rLst.GetMarkCount(); ++i )
+                    pView->MarkObj( rLst.GetMark( i )->GetObj(),
+                                    Imp()->GetPageView() );
+            }
+        }
+        else if( GetCrsr()->GetNext() != GetCrsr() )    // gehe nach einem
+            GoNextCrsr();                   // Redo zur alten Undo-Position !!
+
+        GetDoc()->SetRedlineMode( eOld );
+        GetDoc()->CompressRedlines();
+
+        //JP 18.09.97: autom. Erkennung  fuer die neue "Box"
+        SaveTblBoxCntnt();
+    }
+
+    EndAllAction();
+    GetDoc()->DoUndo( TRUE );
+    return bRet;
+}
+
+
+USHORT SwEditShell::Repeat( USHORT nCount )
+{
+    SET_CURR_SHELL( this );
+
+    BOOL bRet = FALSE;
+    StartAllAction();
+
+        SwUndoIter aUndoIter( GetCrsr(), 0 );
+        bRet |= GetDoc()->Repeat( aUndoIter, nCount );
+
+    EndAllAction();
+    return bRet;
+}
+
+        // abfragen/setzen der Anzahl von wiederherstellbaren Undo-Actions
+
+USHORT SwEditShell::GetUndoActionCount()
+{
+    return SwDoc::GetUndoActionCount();
+}
+
+
+void SwEditShell::SetUndoActionCount( USHORT nNew )
+{
+    SwDoc::SetUndoActionCount( nNew );
+}
+
+
+
diff --git a/sw/source/core/edit/edws.cxx b/sw/source/core/edit/edws.cxx
new file mode 100644
index 000000000000..6fbf40af8911
--- /dev/null
+++ b/sw/source/core/edit/edws.cxx
@@ -0,0 +1,443 @@
+/*************************************************************************
+ *
+ *  $RCSfile: edws.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:18 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+
+#ifndef _WINDOW_HXX //autogen
+#include 
+#endif
+
+#ifndef _EDITSH_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _ACORRECT_HXX
+#include 
+#endif
+#ifndef _SWTABLE_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include 
+#endif
+
+using namespace ::com::sun::star;
+
+/********************************************************
+ * Ctor/Dtor
+ ********************************************************/
+// verkleideter Copy-Constructor
+
+
+SwEditShell::SwEditShell( SwEditShell *pEdSH, Window *pWin )
+    : SwCrsrShell( pEdSH, pWin )
+{
+}
+
+// ctor/dtor
+
+
+SwEditShell::SwEditShell(SwDoc *pDoc,
+    uno::Reference< linguistic::XSpellChecker1 >  xSpell,
+    uno::Reference< linguistic::XHyphenator >  xHyph,
+    Window *pWin, SwRootFrm *pRootFrm, const SwViewOption *pOpt )
+    : SwCrsrShell(pDoc, xSpell, xHyph, pWin, pRootFrm, pOpt)
+{
+    GetDoc()->DoUndo();
+}
+
+
+SwEditShell::~SwEditShell() // USED
+{
+}
+
+/******************************************************************************
+ *                  sal_Bool SwEditShell::IsModified() const
+ ******************************************************************************/
+
+
+sal_Bool SwEditShell::IsModified() const
+{
+    return GetDoc()->IsModified();
+}
+/******************************************************************************
+ *                    void SwEditShell::SetModified()
+ ******************************************************************************/
+
+
+void SwEditShell::SetModified()
+{
+    GetDoc()->SetModified();
+}
+/******************************************************************************
+ *                   void SwEditShell::ResetModified()
+ ******************************************************************************/
+
+
+void SwEditShell::ResetModified()
+{
+    GetDoc()->ResetModified();
+}
+
+void SwEditShell::SetUndoNoResetModified()
+{
+    GetDoc()->SetModified();
+    GetDoc()->SetUndoNoResetModified();
+}
+
+#ifdef USED
+/******************************************************************************
+ *                    void SwEditShell::StartAction()
+ ******************************************************************************/
+
+
+void SwEditShell::StartAction() // OPT: ganz wech
+{
+    SwCrsrShell::StartAction();
+}
+/******************************************************************************
+ *                    void SwEditShell::EndAction()
+ ******************************************************************************/
+
+
+void SwEditShell::EndAction()
+{
+    SwCrsrShell::EndAction();
+}
+#endif
+/******************************************************************************
+ *                 void SwEditShell::StartAllAction()
+ ******************************************************************************/
+
+
+void SwEditShell::StartAllAction()
+{
+    ViewShell *pSh = this;
+    do {
+        if( pSh->IsA( TYPE( SwEditShell ) ) )
+            ((SwEditShell*)pSh)->StartAction();
+        else
+            pSh->StartAction();
+        pSh = (ViewShell *)pSh->GetNext();
+    } while(pSh != this);
+}
+/******************************************************************************
+ *                  void SwEditShell::EndAllAction()
+ ******************************************************************************/
+
+
+void SwEditShell::EndAllAction()
+{
+    ViewShell *pSh = this;
+    do {
+        if( pSh->IsA( TYPE( SwEditShell ) ) )
+            ((SwEditShell*)pSh)->EndAction();
+        else
+            pSh->EndAction();
+        pSh = (ViewShell *)pSh->GetNext();
+    } while(pSh != this);
+}
+
+/******************************************************************************
+ *                  void SwEditShell::CalcLayout()
+ ******************************************************************************/
+
+
+void SwEditShell::CalcLayout()
+{
+    StartAllAction();
+    ViewShell::CalcLayout();
+
+    ViewShell *pSh = this;
+    do
+    {
+        if ( pSh->GetWin() )
+            pSh->GetWin()->Invalidate();
+        pSh = (ViewShell*)pSh->GetNext();
+
+    } while ( pSh != this );
+
+    EndAllAction();
+}
+
+/******************************************************************************
+ *                      Inhaltsform bestimmen, holen
+ ******************************************************************************/
+// OPT: wird fuer jedes Attribut gerufen?
+
+
+sal_uInt16 SwEditShell::GetCntType() const
+{
+    // nur noch am SPoint ist der Inhalt interessant
+    sal_uInt16 nRet = 0;
+    if( IsTableMode() )
+        nRet = CNT_TXT;
+    else
+        switch( GetCrsr()->GetNode()->GetNodeType() )
+        {
+        case ND_TEXTNODE:   nRet = CNT_TXT; break;
+        case ND_GRFNODE:    nRet = CNT_GRF; break;
+        case ND_OLENODE:    nRet = CNT_OLE; break;
+        }
+
+    ASSERT( nRet, ERR_OUTOFSCOPE );
+    return nRet;
+}
+
+//------------------------------------------------------------------------------
+
+
+sal_Bool SwEditShell::HasOtherCnt() const
+{
+    const SwNodes &rNds = GetDoc()->GetNodes();
+    const SwNode *pNd;
+    return GetDoc()->GetSpzFrmFmts()->Count() ||
+            1 != (( pNd = &rNds.GetEndOfInserts() )->GetIndex() -
+                pNd->StartOfSectionIndex() ) ||
+            1 != (( pNd = &rNds.GetEndOfAutotext() )->GetIndex() -
+                pNd->StartOfSectionIndex() );
+}
+
+/******************************************************************************
+ *              Zugriffsfunktionen fuer Filename-Behandlung
+ ******************************************************************************/
+
+
+SwActKontext::SwActKontext(SwEditShell *pShell)
+    : pSh(pShell)
+{
+    pSh->StartAction();
+}
+
+
+SwActKontext::~SwActKontext()
+{
+    pSh->EndAction();
+}
+
+/******************************************************************************
+ *          Klasse fuer den automatisierten Aufruf von Start- und
+ *                              EndCrsrMove();
+ ******************************************************************************/
+
+
+SwMvKontext::SwMvKontext(SwEditShell *pShell ) : pSh(pShell)
+{
+    pSh->SttCrsrMove();
+}
+
+
+SwMvKontext::~SwMvKontext()
+{
+    pSh->EndCrsrMove();
+}
+
+
+SwFrmFmt *SwEditShell::GetTableFmt()    // OPT: schnellster Test auf Tabelle?
+{
+    const SwTableNode* pTblNd = IsCrsrInTbl();
+    return pTblNd ? (SwFrmFmt*)pTblNd->GetTable().GetFrmFmt() : 0;
+}
+
+// OPT: wieso 3x beim neuen Dokument
+
+
+sal_uInt16 SwEditShell::GetTOXTypeCount(TOXTypes eTyp) const
+{
+    return pDoc->GetTOXTypeCount(eTyp);
+}
+
+
+void SwEditShell::InsertTOXType(const SwTOXType& rTyp)
+{
+    pDoc->InsertTOXType(rTyp);
+}
+
+
+
+void SwEditShell::DoUndo( sal_Bool bOn )
+{ GetDoc()->DoUndo( bOn ); }
+
+
+sal_Bool SwEditShell::DoesUndo() const
+{ return GetDoc()->DoesUndo(); }
+
+
+void SwEditShell::DoGroupUndo( sal_Bool bOn )
+{ GetDoc()->DoGroupUndo( bOn ); }
+
+
+sal_Bool SwEditShell::DoesGroupUndo() const
+{ return GetDoc()->DoesGroupUndo(); }
+
+
+void SwEditShell::DelAllUndoObj()
+{
+    GetDoc()->DelAllUndoObj();
+}
+
+// Zusammenfassen von Kontinuierlichen Insert/Delete/Overwrite von
+// Charaktern. Default ist sdbcx::Group-Undo.
+
+// setzt Undoklammerung auf, liefert nUndoId der Klammerung
+
+
+sal_uInt16 SwEditShell::StartUndo( sal_uInt16 nUndoId )
+{ return GetDoc()->StartUndo( nUndoId ); }
+
+// schliesst Klammerung der nUndoId, nicht vom UI benutzt
+
+
+sal_uInt16 SwEditShell::EndUndo(sal_uInt16 nUndoId)
+{ return GetDoc()->EndUndo(nUndoId); }
+
+// liefert die Id der letzten undofaehigen Aktion zurueck
+// fuellt ggf. VARARR mit sdbcx::User-UndoIds
+
+
+sal_uInt16 SwEditShell::GetUndoIds(String* pStr,SwUndoIds *pUndoIds) const
+{ return GetDoc()->GetUndoIds(pStr,pUndoIds); }
+
+// liefert die Id der letzten Redofaehigen Aktion zurueck
+// fuellt ggf. VARARR mit RedoIds
+
+
+sal_uInt16 SwEditShell::GetRedoIds(String* pStr,SwUndoIds *pRedoIds) const
+{ return GetDoc()->GetRedoIds(pStr,pRedoIds); }
+
+// liefert die Id der letzten Repeatfaehigen Aktion zurueck
+// fuellt ggf. VARARR mit RedoIds
+
+
+sal_uInt16 SwEditShell::GetRepeatIds(String* pStr, SwUndoIds *pRedoIds) const
+{ return GetDoc()->GetRepeatIds(pStr,pRedoIds); }
+
+
+
+// AutoKorrektur - JP 27.01.94
+void SwEditShell::AutoCorrect( SvxAutoCorrect& rACorr, sal_Bool bInsert,
+                                sal_Unicode cChar )
+{
+    SET_CURR_SHELL( this );
+
+    StartAllAction();
+
+    SwPaM* pCrsr = GetCrsr();
+    SwTxtNode* pTNd = pCrsr->GetNode()->GetTxtNode();
+
+    SwAutoCorrDoc aSwAutoCorrDoc( *this, *pCrsr, cChar );
+    rACorr.AutoCorrect( aSwAutoCorrDoc,
+                    pTNd->GetTxt(), pCrsr->GetPoint()->nContent.GetIndex(),
+                    cChar, bInsert );
+    if( cChar )
+        SaveTblBoxCntnt( pCrsr->GetPoint() );
+    EndAllAction();
+}
+
+
+void SwEditShell::SetNewDoc(sal_Bool bNew)
+{
+    GetDoc()->SetNewDoc(bNew);
+}
+
+
+sal_Bool SwEditShell::GetPrevAutoCorrWord( SvxAutoCorrect& rACorr, String& rWord )
+{
+    SET_CURR_SHELL( this );
+
+    sal_Bool bRet;
+    SwPaM* pCrsr = GetCrsr();
+    xub_StrLen nPos = pCrsr->GetPoint()->nContent.GetIndex();
+    SwTxtNode* pTNd = pCrsr->GetNode()->GetTxtNode();
+    if( pTNd && nPos )
+    {
+        SwAutoCorrDoc aSwAutoCorrDoc( *this, *pCrsr, 0 );
+        bRet = rACorr.GetPrevAutoCorrWord( aSwAutoCorrDoc,
+                                            pTNd->GetTxt(), nPos, rWord );
+    }
+    else
+        bRet = sal_False;
+    return bRet;
+}
+
+SwAutoCompleteWord& SwEditShell::GetAutoCompleteWords()
+{
+    return SwDoc::GetAutoCompleteWords();
+}
+
+
+
diff --git a/sw/source/core/edit/makefile.mk b/sw/source/core/edit/makefile.mk
new file mode 100644
index 000000000000..cbf2d9d34109
--- /dev/null
+++ b/sw/source/core/edit/makefile.mk
@@ -0,0 +1,145 @@
+#*************************************************************************
+#
+#   $RCSfile: makefile.mk,v $
+#
+#   $Revision: 1.1.1.1 $
+#
+#   last change: $Author: hr $ $Date: 2000-09-19 00:08:18 $
+#
+#   The Contents of this file are made available subject to the terms of
+#   either of the following licenses
+#
+#          - GNU Lesser General Public License Version 2.1
+#          - Sun Industry Standards Source License Version 1.1
+#
+#   Sun Microsystems Inc., October, 2000
+#
+#   GNU Lesser General Public License Version 2.1
+#   =============================================
+#   Copyright 2000 by Sun Microsystems, Inc.
+#   901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+#   This library is free software; you can redistribute it and/or
+#   modify it under the terms of the GNU Lesser General Public
+#   License version 2.1, as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   Lesser General Public License for more details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+#   License along with this library; if not, write to the Free Software
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+#   MA  02111-1307  USA
+#
+#
+#   Sun Industry Standards Source License Version 1.1
+#   =================================================
+#   The contents of this file are subject to the Sun Industry Standards
+#   Source License Version 1.1 (the "License"); You may not use this file
+#   except in compliance with the License. You may obtain a copy of the
+#   License at http://www.openoffice.org/license.html.
+#
+#   Software provided under this License is provided on an "AS IS" basis,
+#   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+#   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+#   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+#   See the License for the specific provisions governing your rights and
+#   obligations concerning the Software.
+#
+#   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+#   Copyright: 2000 by Sun Microsystems, Inc.
+#
+#   All Rights Reserved.
+#
+#   Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sw
+TARGET=edit
+
+AUTOSEG=true
+
+PROJECTPCH=core_pch
+PDBTARGET=core_pch
+PROJECTPCHSOURCE=..$/core_1st$/core_pch
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE :	$(PRJ)$/inc$/swpre.mk
+.INCLUDE :	settings.mk
+.INCLUDE :	$(PRJ)$/inc$/sw.mk
+
+.IF "$(GUI)" != "MAC"
+CDEFS+=-Is:\solar\inc\hm
+
+.IF "$(debug)" != ""
+CDEFS+=-DDEBUG
+.ENDIF
+.IF "$(mydebug)" != ""
+CDEFS+=-Dmydebug
+.ENDIF
+.ENDIF #Mac
+
+# --- Files --------------------------------------------------------
+
+CXXFILES = \
+        acorrect.cxx \
+        autofmt.cxx \
+        edatmisc.cxx \
+        edattr.cxx \
+        eddel.cxx \
+        edfcol.cxx \
+        edfld.cxx \
+        edfmt.cxx \
+        edglbldc.cxx \
+        edglss.cxx \
+        editsh.cxx \
+        edlingu.cxx \
+        ednumber.cxx \
+        edredln.cxx \
+        edtab.cxx \
+        edtox.cxx \
+        edundo.cxx \
+        edws.cxx \
+        edsect.cxx \
+        tempauto.cxx
+
+
+
+SLOFILES =	\
+        $(SLO)$/acorrect.obj \
+        $(SLO)$/autofmt.obj \
+        $(SLO)$/edatmisc.obj \
+        $(SLO)$/edattr.obj \
+        $(SLO)$/eddel.obj \
+        $(SLO)$/edfcol.obj \
+        $(SLO)$/edfld.obj \
+        $(SLO)$/edfmt.obj \
+        $(SLO)$/edglbldc.obj \
+        $(SLO)$/edglss.obj \
+        $(SLO)$/editsh.obj \
+        $(SLO)$/edlingu.obj \
+        $(SLO)$/ednumber.obj \
+        $(SLO)$/edredln.obj \
+        $(SLO)$/edtab.obj \
+        $(SLO)$/edtox.obj \
+        $(SLO)$/edundo.obj \
+        $(SLO)$/edws.obj \
+        $(SLO)$/edsect.obj \
+        $(SLO)$/tempauto.obj
+
+EXCEPTIONSFILES =	\
+        $(SLO)$/edtox.obj \
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE :	target.mk
+
diff --git a/sw/source/core/except/dbgloop.cxx b/sw/source/core/except/dbgloop.cxx
new file mode 100644
index 000000000000..5e63721bb664
--- /dev/null
+++ b/sw/source/core/except/dbgloop.cxx
@@ -0,0 +1,201 @@
+/*************************************************************************
+ *
+ *  $RCSfile: dbgloop.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:19 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRODUCT
+#error Wer fummelt denn an den makefiles rum?
+#endif
+
+#ifndef _STREAM_HXX //autogen
+#include 
+#endif
+#include "dbgloop.hxx"
+#include "errhdl.hxx"
+
+DbgLoopStack DbgLoop::aDbgLoopStack;
+
+/*************************************************************************
+ *                      class DbgLoopStack
+ *************************************************************************/
+
+DbgLoopStack::DbgLoopStack()
+{
+    Reset();
+}
+
+void DbgLoopStack::Reset()
+{
+    nPtr = 0;
+    pDbg = 0;
+    for( USHORT i = 0; i < DBG_MAX_STACK; ++i )
+        aCount[i] = 0;
+}
+
+/*************************************************************************
+ *                       DbgLoopStack::Push()
+ *************************************************************************/
+
+void DbgLoopStack::Push( const void *pThis )
+{
+    // Wir muessen irgendwie mitbekommen, wann die erste Stackposition
+    // resettet werden soll, z.B. wenn wir einen Nullpointer uebergeben
+    if( !nPtr && ( pDbg != pThis || !pThis ) )
+    {
+        aCount[1] = 0;
+        pDbg = pThis;
+    }
+
+    ++nPtr;
+    if( DBG_MAX_STACK > nPtr )
+    {
+        // Wenn eine loop entdeckt wird, wird der counter wieder zurueckgesetzt.
+        ASSERT( DBG_MAX_LOOP > aCount[nPtr], "DbgLoopStack::Push: loop detected" );
+        if( DBG_MAX_LOOP > aCount[nPtr] )
+            ++(aCount[nPtr]);
+        else
+            aCount[nPtr] = 0;
+    }
+}
+
+/*************************************************************************
+ *                       DbgLoopStack::Pop()
+ *************************************************************************/
+
+void DbgLoopStack::Pop()
+{
+    if( DBG_MAX_STACK > nPtr )
+    {
+        ASSERT( nPtr, "DbgLoopStack::Pop: can't pop the stack" );
+
+        ASSERT( aCount[nPtr], "DbgLoopStack::Pop: can't dec the count" );
+        if( DBG_MAX_STACK > nPtr + 1 )
+            aCount[nPtr + 1] = 0;
+    }
+    --nPtr;
+}
+
+/*************************************************************************
+ *                       DbgLoopStack::Print()
+ *************************************************************************/
+
+void DbgLoopStack::Print( SvStream &rOS ) const
+{
+    rOS << "POS: " << nPtr << '\n';
+    for( USHORT i = 0; i < DBG_MAX_STACK; ++i )
+        rOS << i << " ";
+    rOS << '\n';
+    for( i = 0; i < DBG_MAX_STACK; ++i )
+        rOS << aCount[i] << " ";
+    rOS << '\n';
+}
+
+#ifdef STAND_ALONE
+// compile with: cl /AL /DSTAND_ALONE dbgloop.cxx
+
+/*************************************************************************
+ *                          main()
+ *************************************************************************/
+
+#include 
+
+void AssertFail( const char *pErr, const char *pFile, USHORT nLine )
+{
+    cout << pErr << '\n';
+    PrintLoopStack( cout );
+    exit(0);
+}
+
+class Test
+{
+public:
+        void Run() const;
+};
+
+void Test::Run() const
+{
+    cout << "---" << '\n';
+    for( USHORT i = 0; i < 10; ++i )
+    {
+        cout << "i" << i;
+        DBG_LOOP;
+        PrintLoopStack( cout );
+        for( USHORT j = 0; j < 10; ++j )
+        {
+            cout << " j" << j;
+            DBG_LOOP;
+            PrintLoopStack( cout );
+        }
+        cout << '\n';
+    }
+    PrintLoopStack( cout );
+}
+
+int main()
+{
+    // unterschiedliche Instanzen waehlen wg. pDbg != pThis
+    Test aTest1;
+    aTest1.Run();
+    Test aTest2;
+    aTest2.Run();
+    return 0;
+}
+#endif
+
+
diff --git a/sw/source/core/except/errhdl.cxx b/sw/source/core/except/errhdl.cxx
new file mode 100644
index 000000000000..75a0c170981a
--- /dev/null
+++ b/sw/source/core/except/errhdl.cxx
@@ -0,0 +1,196 @@
+/*************************************************************************
+ *
+ *  $RCSfile: errhdl.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:19 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define _ERRHDL_CXX
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "stdlib.h"
+#ifdef WIN
+#include               // fuer die Goodies der Windows User
+#include 
+#endif
+
+#ifndef _TOOLS_DEBUG_HXX //autogen
+#include 
+#endif
+#ifndef _SV_SVAPP_HXX //autogen
+#include 
+#endif
+#ifndef _SV_SOUND_HXX //autogen
+#include 
+#endif
+
+#ifndef _ERRHDL_HXX
+#include 
+#endif
+#ifndef _SWERROR_H
+#include               // fuer die defines von ERR_SW6MSG_ ...
+#endif
+
+// break into CodeView
+#if defined(ZTC) && defined(WIN)
+#define CVBREAK     asm( 0xCC );
+#endif
+#if defined(MSC) && defined(WIN)
+#define CVBREAK     __asm int 3;
+#endif
+#ifndef CVBREAK
+#define CVBREAK
+#endif
+
+BOOL bAssertFail = FALSE;           // ist gerade eine Assertbox oben ?
+BOOL bAssert = FALSE;               // TRUE, wenn mal ein ASSERT kam.
+
+/*------------------------------------------------------------------------
+    Ausgabe einer Fehlermeldung inkl. Bedingung, Dateiname und Zeilennummer
+    wo der Fehler auftrat.
+    Die Funktion wird durch das ASSERT Makro gerufen!
+    Parameter:
+                char    *pError     Fehlermeldung
+                char    *pFileName  Filename in dem der Fehler auftrat
+                USHORT  nLine       Zeilennummer in dem der Fehler auftrat
+------------------------------------------------------------------------*/
+
+void AssertFail( const sal_Char* pError, const sal_Char* pFileName, USHORT nLine )
+{
+    CVBREAK;
+    // NOTE4("ASSERT: %s at %d: %s\n", pFileName, nLine, pError);
+    bAssert = TRUE;
+
+    if( !bAssertFail && GetpApp() && GetpApp()->IsInMain() )
+    {
+        bAssertFail = TRUE;
+        ByteString  aErr;
+        aErr = "Assertion failed\n==================\nFILE      :  ";
+        aErr += pFileName;
+        aErr += " at line ";
+        aErr += ByteString::CreateFromInt32( nLine );
+        aErr += "\nERROR :  ";
+        aErr += pError;
+
+        ByteString aTmp( getenv( "SW_NOBEEP" ) );
+        if ( aTmp != "TRUE" )
+            Sound::Beep(SOUND_ERROR);
+
+#if defined( UNX ) && !defined( DBG_UTIL )
+        DBG_ERROR( aErr.GetBuffer() ); // DbgErr ist in UNIX-nicht Produkt-Versionen nicht definiert
+#else
+        DbgError( aErr.GetBuffer() );
+#endif
+        bAssertFail = FALSE;
+    }
+    else
+    {
+        Sound::Beep(SOUND_ERROR);
+        Sound::Beep(SOUND_ERROR);
+        Sound::Beep(SOUND_ERROR);
+        if( !bAssertFail )
+#if defined( MAC )
+        if( !bAssertFail )
+            *(short *)1 = 4711;         // odd address error erzeugen
+#endif
+        if( !bAssertFail )
+            *(short *)0 = 4711;         // UAE ausloesen
+    }
+}
+
+/*------------------------------------------------------------------------
+    Ausgabe einer Fehlermeldung inkl. Bedingung, Dateiname und Zeilennummer
+    wo der Fehler auftrat.
+    Die Funktion wird durch das ASSERT Makro gerufen!
+    Parameter:
+                USHORT  nErrorId    Id fuer Fehlermeldung
+                char    *pFileName  Filename in dem der Fehler auftrat
+                USHORT  nLine       Zeilennummer in dem der Fehler auftrat
+------------------------------------------------------------------------*/
+
+void AssertFail( USHORT nErrorId, const sal_Char* pFileName, USHORT nLine )
+{
+    // Umsetzung der ErrorId in eine Fehlermeldung
+    static const sal_Char
+        /* Error Fehlermeldungen zugriffe ausserhalb eines Bereiches */
+        sERR_VAR_IDX[]      = "Op[]",
+        sERR_OUTOFSCOPE[]   = "Zugriff ausserhalb des Bereiches",
+        /* Error Codes fuer Numerierungsregeln */
+        sERR_NUMLEVEL[]     = "Falscher Num-Level",
+        /* Error Codes fuer TxtNode */
+        sERR_NOHINTS[]      = "Zugriff auf ungueltiges HintsArray",
+        sERR_UNKNOWN[]      = "???";
+
+    static const sal_Char* aErrStrTab[ ERR_SWGMSG_END - ERR_SWGMSG_START +1 ] =
+    {
+        sERR_VAR_IDX, sERR_OUTOFSCOPE, sERR_NUMLEVEL, sERR_NOHINTS
+    };
+
+    const sal_Char* pMsg;
+    if( nErrorId >= ERR_SWGMSG_START && nErrorId < ERR_SWGMSG_END )
+        pMsg = aErrStrTab[ nErrorId - ERR_SWGMSG_START ];
+    else
+        pMsg = sERR_UNKNOWN;
+
+    AssertFail( pMsg, pFileName, nLine );
+}
+
+
diff --git a/sw/source/core/except/makefile.mk b/sw/source/core/except/makefile.mk
new file mode 100644
index 000000000000..72e818c8ce9b
--- /dev/null
+++ b/sw/source/core/except/makefile.mk
@@ -0,0 +1,97 @@
+#*************************************************************************
+#
+#   $RCSfile: makefile.mk,v $
+#
+#   $Revision: 1.1.1.1 $
+#
+#   last change: $Author: hr $ $Date: 2000-09-19 00:08:19 $
+#
+#   The Contents of this file are made available subject to the terms of
+#   either of the following licenses
+#
+#          - GNU Lesser General Public License Version 2.1
+#          - Sun Industry Standards Source License Version 1.1
+#
+#   Sun Microsystems Inc., October, 2000
+#
+#   GNU Lesser General Public License Version 2.1
+#   =============================================
+#   Copyright 2000 by Sun Microsystems, Inc.
+#   901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+#   This library is free software; you can redistribute it and/or
+#   modify it under the terms of the GNU Lesser General Public
+#   License version 2.1, as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   Lesser General Public License for more details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+#   License along with this library; if not, write to the Free Software
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+#   MA  02111-1307  USA
+#
+#
+#   Sun Industry Standards Source License Version 1.1
+#   =================================================
+#   The contents of this file are subject to the Sun Industry Standards
+#   Source License Version 1.1 (the "License"); You may not use this file
+#   except in compliance with the License. You may obtain a copy of the
+#   License at http://www.openoffice.org/license.html.
+#
+#   Software provided under this License is provided on an "AS IS" basis,
+#   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+#   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+#   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+#   See the License for the specific provisions governing your rights and
+#   obligations concerning the Software.
+#
+#   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+#   Copyright: 2000 by Sun Microsystems, Inc.
+#
+#   All Rights Reserved.
+#
+#   Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sw
+TARGET=except
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE :  $(PRJ)$/inc$/swpre.mk
+
+# hier kein PCH!
+prjpch=
+PRJPCH=
+
+.INCLUDE :  settings.mk
+.INCLUDE :  $(PRJ)$/inc$/sw.mk
+
+# --- Files --------------------------------------------------------
+
+CXXFILES =
+
+.IF "$(product)"==""
+.IF "$(cap)"==""
+CXXFILES += \
+        errhdl.cxx			\
+        dbgloop.cxx
+
+SLOFILES +=  \
+        $(SLO)$/errhdl.obj 	\
+        $(SLO)$/dbgloop.obj
+.ENDIF
+.ENDIF
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE :  target.mk
+
diff --git a/sw/source/core/fields/authfld.cxx b/sw/source/core/fields/authfld.cxx
new file mode 100644
index 000000000000..7be341ea8f6b
--- /dev/null
+++ b/sw/source/core/fields/authfld.cxx
@@ -0,0 +1,714 @@
+/*************************************************************************
+ *
+ *  $RCSfile: authfld.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:19 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#define _SVSTDARR_STRINGSDTOR
+#define _SVSTDARR_USHORTS
+#define _SVSTDARR_LONGS
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _SVARRAY_HXX
+#include 
+#endif
+#include 
+
+#ifndef _SWTYPES_HXX
+#include 
+#endif
+#ifndef _SV_SVAPP_HXX
+#include 
+#endif
+#ifndef _AUTHFLD_HXX
+#include 
+#endif
+#ifndef _TOX_HXX
+#include 
+#endif
+#ifndef _TXMSRT_HXX
+#include 
+#endif
+#ifndef _DOCTXM_HXX
+#include 
+#endif
+#ifndef _FMTFLD_HXX
+#include 
+#endif
+#ifndef _TXTFLD_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#include 
+#ifndef _SVSTDARR_HXX
+#define _SVSTDARR_ULONGS
+#include 
+#endif
+#ifndef _SVX_LANGITEM_HXX
+#include 
+#endif
+#ifndef _SV_SYSTEM_HXX
+#include 
+#endif
+
+typedef SwAuthEntry* SwAuthEntryPtr;
+SV_DECL_PTRARR_DEL( SwAuthDataArr, SwAuthEntryPtr, 5, 5 )
+SV_IMPL_PTRARR( SwAuthDataArr, SwAuthEntryPtr )
+
+
+typedef SwTOXSortKey* TOXSortKeyPtr;
+SV_DECL_PTRARR_DEL( SortKeyArr, TOXSortKeyPtr, 5, 5 )
+SV_IMPL_PTRARR( SortKeyArr, TOXSortKeyPtr )
+
+
+/* -----------------16.09.99 11:53-------------------
+
+ --------------------------------------------------*/
+SwAuthEntry::SwAuthEntry(const SwAuthEntry& rCopy)
+    : nRefCount(0)
+{
+    for(USHORT i = 0; i < AUTH_FIELD_END; i++)
+        aAuthFields[i] = rCopy.aAuthFields[i];
+}
+// --------------------------------------------------------
+BOOL    SwAuthEntry::operator==(const SwAuthEntry& rComp)
+{
+    for(USHORT i = 0; i < AUTH_FIELD_END; i++)
+        if(aAuthFields[i] != rComp.aAuthFields[i])
+            return FALSE;
+    return TRUE;
+}
+// --------------------------------------------------------
+BOOL    SwAuthEntry::GetFirstAuthorField(USHORT& nPos, String& rToFill)const
+{
+    BOOL bRet = FALSE;
+        for(USHORT i = 0; i < AUTH_FIELD_END; i++)
+            if(aAuthFields[i].Len())
+            {
+                rToFill = aAuthFields[i];
+                nPos = i;
+                bRet = TRUE;
+                break;
+            }
+    return bRet;
+}
+// --------------------------------------------------------
+BOOL    SwAuthEntry::GetNextAuthorField(USHORT& nPos, String& rToFill)const
+{
+    BOOL bRet = FALSE;
+    if(AUTH_FIELD_END > ++nPos)
+    {
+        for(USHORT i = nPos; i < AUTH_FIELD_END; i++)
+            if(aAuthFields[i].Len())
+            {
+                rToFill = aAuthFields[i];
+                nPos = i;
+                bRet = TRUE;
+                break;
+            }
+    }
+    return bRet;
+}
+
+// --------------------------------------------------------
+
+/* -----------------14.09.99 16:15-------------------
+
+ --------------------------------------------------*/
+SwAuthorityFieldType::SwAuthorityFieldType(SwDoc* pDoc)
+    : SwFieldType( RES_AUTHORITY ),
+    m_pDoc(pDoc),
+    m_pDataArr(new SwAuthDataArr ),
+    m_pSequArr(new SvLongs(5, 5)),
+    m_pSortKeyArr(new SortKeyArr(3, 3)),
+    m_bSortByDocument(TRUE),
+    m_bIsSequence(FALSE),
+    m_cPrefix('['),
+    m_cSuffix(']')
+{
+}
+
+SwAuthorityFieldType::SwAuthorityFieldType( const SwAuthorityFieldType& rFType)
+    : SwFieldType( RES_AUTHORITY ),
+    m_pDataArr(new SwAuthDataArr ),
+    m_pSequArr(new SvLongs(5, 5)),
+    m_pSortKeyArr(new SortKeyArr(3, 3)),
+    m_bSortByDocument(rFType.m_bSortByDocument),
+    m_bIsSequence(rFType.m_bIsSequence),
+    m_cPrefix(rFType.m_cPrefix),
+    m_cSuffix(rFType.m_cSuffix)
+{
+    for(USHORT i = 0; i < rFType.m_pSortKeyArr->Count(); i++)
+        m_pSortKeyArr->Insert((*rFType.m_pSortKeyArr)[i], i);
+}
+
+/* -----------------17.09.99 13:52-------------------
+
+ --------------------------------------------------*/
+SwAuthorityFieldType::~SwAuthorityFieldType()
+{
+    DBG_ASSERT(!m_pDataArr->Count(), "Array is not empty")
+    m_pSortKeyArr->DeleteAndDestroy(0, m_pSortKeyArr->Count());
+    delete m_pSortKeyArr;
+    delete m_pSequArr;
+    delete m_pDataArr;
+}
+/*-- 14.09.99 16:22:09---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwFieldType*    SwAuthorityFieldType::Copy()  const
+{
+    return new SwAuthorityFieldType(m_pDoc);
+}
+/* -----------------17.09.99 13:43-------------------
+
+ --------------------------------------------------*/
+void    SwAuthorityFieldType::RemoveField(long nHandle)
+{
+#ifdef DBG_UTIL
+    BOOL bRemoved = FALSE;
+#endif
+    for(USHORT j = 0; j < m_pDataArr->Count(); j++)
+    {
+        SwAuthEntry* pTemp = m_pDataArr->GetObject(j);
+        long nRet = (long)(void*)pTemp;
+        if(nRet == nHandle)
+        {
+#ifdef DBG_UTIL
+            bRemoved = TRUE;
+#endif
+            pTemp->RemoveRef();
+            if(!pTemp->GetRefCount())
+            {
+                m_pDataArr->DeleteAndDestroy(j, 1);
+            }
+            break;
+        }
+    }
+#ifdef DBG_UTIL
+    DBG_ASSERT(bRemoved, "Field unknown" )
+#endif
+}
+/* -----------------17.09.99 13:43-------------------
+
+ --------------------------------------------------*/
+long    SwAuthorityFieldType::AddField(const String& rFieldContents)
+{
+    long nRet = 0;
+    SwAuthEntry* pEntry = new SwAuthEntry;
+    for( USHORT i = 0; i < AUTH_FIELD_END; ++i )
+        pEntry->SetAuthorField( (ToxAuthorityField)i,
+                        rFieldContents.GetToken( i, TOX_STYLE_DELIMITER ));
+
+    for(USHORT j = 0; j < m_pDataArr->Count() && pEntry; j++)
+    {
+        SwAuthEntry* pTemp = m_pDataArr->GetObject(j);
+        if(*pTemp == *pEntry)
+        {
+            DELETEZ(pEntry);
+            nRet = (long)(void*)pTemp;
+            pTemp->AddRef();
+        }
+    }
+    //if it is a new Entry - insert
+    if(pEntry)
+    {
+        nRet = (long)(void*)pEntry;
+        pEntry->AddRef();
+        m_pDataArr->Insert(pEntry, m_pDataArr->Count());
+    }
+    return nRet;
+}
+/* -----------------17.09.99 14:18-------------------
+
+ --------------------------------------------------*/
+BOOL SwAuthorityFieldType::AddField(long nHandle)
+{
+    BOOL bRet = FALSE;
+    for( USHORT j = 0; j < m_pDataArr->Count(); j++ )
+    {
+        SwAuthEntry* pTemp = m_pDataArr->GetObject(j);
+        long nTmp = (long)(void*)pTemp;
+        if( nTmp == nHandle )
+        {
+            bRet = TRUE;
+            pTemp->AddRef();
+            break;
+        }
+    }
+    return bRet;
+}
+/* -----------------17.09.99 14:52-------------------
+
+ --------------------------------------------------*/
+const SwAuthEntry*  SwAuthorityFieldType::GetEntryByHandle(long nHandle) const
+{
+    const SwAuthEntry* pRet = 0;
+    for(USHORT j = 0; j < m_pDataArr->Count(); j++)
+    {
+        const SwAuthEntry* pTemp = m_pDataArr->GetObject(j);
+        long nTmp = (long)(void*)pTemp;
+        if( nTmp == nHandle )
+        {
+            pRet = pTemp;
+            break;
+        }
+    }
+    ASSERT( pRet, "invalid Handle" );
+    return pRet;
+}
+/* -----------------21.09.99 13:34-------------------
+
+ --------------------------------------------------*/
+void SwAuthorityFieldType::GetAllEntryIdentifiers(
+                SvStringsDtor& rToFill )const
+{
+    for(USHORT j = 0; j < m_pDataArr->Count(); j++)
+    {
+        SwAuthEntry* pTemp = m_pDataArr->GetObject(j);
+        rToFill.Insert( new String( pTemp->GetAuthorField(
+                    AUTH_FIELD_IDENTIFIER )), rToFill.Count() );
+    }
+}
+/* -----------------21.09.99 13:34-------------------
+
+ --------------------------------------------------*/
+const SwAuthEntry*  SwAuthorityFieldType::GetEntryByIdentifier(
+                                const String& rIdentifier)const
+{
+    const SwAuthEntry* pRet = 0;
+    for( USHORT j = 0; j < m_pDataArr->Count(); ++j )
+    {
+        const SwAuthEntry* pTemp = m_pDataArr->GetObject(j);
+        if( rIdentifier == pTemp->GetAuthorField( AUTH_FIELD_IDENTIFIER ))
+        {
+            pRet = pTemp;
+            break;
+        }
+    }
+    return pRet;
+}
+/* -----------------------------21.12.99 13:20--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SwAuthorityFieldType::ChangeEntryContent(const SwAuthEntry* pNewEntry)
+{
+    for( USHORT j = 0; j < m_pDataArr->Count(); ++j )
+    {
+        SwAuthEntry* pTemp = m_pDataArr->GetObject(j);
+        if(pTemp->GetAuthorField(AUTH_FIELD_IDENTIFIER) ==
+                    pNewEntry->GetAuthorField(AUTH_FIELD_IDENTIFIER))
+        {
+            for(USHORT i = 0; i < AUTH_FIELD_END; i++)
+                pTemp->SetAuthorField((ToxAuthorityField) i,
+                    pNewEntry->GetAuthorField((ToxAuthorityField)i));
+            break;
+        }
+    }
+}
+/*-- 11.10.99 08:49:22---------------------------------------------------
+    Description:    appends a new entry (if new) and returns the array position
+
+  -----------------------------------------------------------------------*/
+USHORT  SwAuthorityFieldType::AppendField( const SwAuthEntry& rInsert )
+{
+    USHORT nRet = 0;
+    for( nRet = 0; nRet < m_pDataArr->Count(); ++nRet )
+    {
+        SwAuthEntry* pTemp = m_pDataArr->GetObject( nRet );
+        if( *pTemp == rInsert )
+        {
+            break;
+            //ref count unchanged
+        }
+    }
+
+    //if it is a new Entry - insert
+    if( nRet == m_pDataArr->Count() )
+        m_pDataArr->Insert( new SwAuthEntry( rInsert ), nRet );
+
+    return nRet;
+}
+
+/*-- 11.10.99 08:49:23---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwAuthorityFieldType::MergeFieldType( const SwAuthorityFieldType& rNew,
+                                            SvUShorts& rMap )
+{
+    DBG_ASSERT( !rMap.Count(), "array not empty!")
+    for( USHORT i = 0; i < rNew.m_pDataArr->Count(); ++i )
+    {
+        USHORT  nNewPos = AppendField(*rNew.m_pDataArr->GetObject(i));
+        rMap.Insert(nNewPos, i);
+    }
+}
+
+/*-- 11.10.99 08:49:23---------------------------------------------------
+    Description:    After import is done some of the array members may have a
+
+  -----------------------------------------------------------------------*/
+void SwAuthorityFieldType::RemoveUnusedFields()
+{
+    for( USHORT j = m_pDataArr->Count(); j; )
+    {
+        SwAuthEntry* pTemp = m_pDataArr->GetObject( --j );
+        if( !pTemp->GetRefCount() )
+        {
+            m_pDataArr->Remove( j );
+            delete pTemp;
+        }
+    }
+}
+
+/*-- 11.10.99 08:49:24---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+long    SwAuthorityFieldType::GetHandle(USHORT nPos)
+{
+    long nRet = 0;
+    if( nPos < m_pDataArr->Count() )
+    {
+        SwAuthEntry* pTemp = m_pDataArr->GetObject(nPos);
+        nRet = (long)(void*)pTemp;
+    }
+    return nRet;
+}
+/* -----------------20.10.99 13:38-------------------
+
+ --------------------------------------------------*/
+USHORT  SwAuthorityFieldType::GetPosition(long nHandle)
+{
+    USHORT j = 0;
+    for( ; j < m_pDataArr->Count(); ++j )
+    {
+        const SwAuthEntry* pTemp = m_pDataArr->GetObject(j);
+        long nTmp = (long)(void*)pTemp;
+        if( nTmp == nHandle )
+            break;
+    }
+    if( j == m_pDataArr->Count() )
+        j = USHRT_MAX;
+
+    ASSERT( USHRT_MAX != j, "handle not found" );
+    return j;
+}
+
+/*-- 11.10.99 08:51:03---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+USHORT  SwAuthorityFieldType::GetEntryCount() const
+{
+    return m_pDataArr->Count();
+}
+/*-- 11.10.99 08:51:03---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+const SwAuthEntry*  SwAuthorityFieldType::GetEntryByPosition(USHORT nPos) const
+{
+    if(nPos < m_pDataArr->Count())
+        return m_pDataArr->GetObject(nPos);
+    DBG_ERROR("wrong index")
+    return 0;
+}
+/* -----------------19.10.99 13:46-------------------
+
+ --------------------------------------------------*/
+USHORT  SwAuthorityFieldType::GetSequencePos(long nHandle)
+{
+    //find the field in a sorted array of handles,
+    //aHandleArr....
+    if(!m_pSequArr->Count())
+    {
+        SwTOXSortTabBases aSortArr;
+        SwClientIter aIter(*this);
+        const International* pIntl = &Application::GetAppInternational();
+        LanguageType eLang = ((const SvxLanguageItem&)m_pDoc->GetAttrPool().
+                            GetDefaultItem(RES_CHRATR_LANGUAGE )).GetLanguage();
+
+        BOOL bDelIntl = FALSE;
+        if( !( eLang == ::GetSystemLanguage() &&
+            LANGUAGE_SYSTEM == pIntl->GetLanguage() ) &&
+            eLang != pIntl->GetLanguage() )
+        {
+            bDelIntl = TRUE;
+            pIntl = new International( eLang );
+        }
+        for( SwFmtFld* pFmtFld = (SwFmtFld*)aIter.First( TYPE(SwFmtFld) );
+                                    pFmtFld; pFmtFld = (SwFmtFld*)aIter.Next() )
+        {
+            SwAuthorityField* pAFld = (SwAuthorityField*)pFmtFld->GetFld();
+            const SwTxtFld* pTxtFld = pFmtFld->GetTxtFld();
+            if(!pTxtFld)
+                continue;
+            const SwTxtNode& rTxtNode = pTxtFld->GetTxtNode();
+            ULONG nPos = rTxtNode.GetIndex();
+            BOOL bInsert = TRUE;
+            if( rTxtNode.GetTxt().Len() && rTxtNode.GetFrm() &&
+                rTxtNode.GetNodes().IsDocNodes() )
+            {
+                SwTOXAuthority* pNew = new SwTOXAuthority( rTxtNode, *pFmtFld, *pIntl );
+    //          InsertSorted(pNew);
+    //          aSortArr
+                Range aRange(0, aSortArr.Count());
+                for(short i = (short)aRange.Min(); i < (short)aRange.Max(); ++i)
+                {
+                    SwTOXSortTabBase* pOld = aSortArr[i];
+                    if(*pOld == *pNew)
+                    {
+                        bInsert = FALSE;
+                        //only the first occurence in the document
+                        //has to be in the array
+                        if(*pOld < *pNew)
+                        {
+                            delete pNew;
+                        }
+                        else
+                        {
+                            // remove the old content
+                            aSortArr.DeleteAndDestroy( i, 1 );
+                            aSortArr.Insert(pNew, i );
+                        }
+                    }
+                    if(*pNew < *pOld)
+                        break;
+                }
+                if(bInsert)
+                    aSortArr.Insert(pNew, i );
+                bInsert = TRUE;
+            }
+        }
+        if(bDelIntl)
+            delete (International*)pIntl;
+
+        for(USHORT i = 0; i < aSortArr.Count(); i++)
+        {
+            const SwTOXSortTabBase& rBase = *aSortArr[i];
+            SwFmtFld& rFmtFld = ((SwTOXAuthority&)rBase).GetFldFmt();
+            SwAuthorityField* pAFld = (SwAuthorityField*)rFmtFld.GetFld();
+            m_pSequArr->Insert(pAFld->GetHandle(), i);
+        }
+        aSortArr.DeleteAndDestroy(0, aSortArr.Count());
+    }
+    //find nHandle
+    USHORT nRet;
+    for(USHORT i = 0; i < m_pSequArr->Count(); i++)
+    {
+        if((*m_pSequArr)[i] == nHandle)
+        {
+            nRet = i + 1;
+            break;
+        }
+    }
+    ASSERT(nRet, "Handle not found")
+    return nRet;
+}
+
+/* -----------------19.10.99 13:25-------------------
+
+ --------------------------------------------------*/
+void SwAuthorityFieldType::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew )
+{
+    //re-generate positions of the fields
+    m_pSequArr->Remove(0, m_pSequArr->Count());
+    SwModify::Modify( pOld, pNew );
+}
+/* -----------------20.10.99 13:38-------------------
+
+ --------------------------------------------------*/
+USHORT SwAuthorityFieldType::GetSortKeyCount() const
+{
+    return m_pSortKeyArr->Count();
+}
+/* -----------------20.10.99 13:38-------------------
+
+ --------------------------------------------------*/
+const SwTOXSortKey*  SwAuthorityFieldType::GetSortKey(USHORT nIdx) const
+{
+    SwTOXSortKey* pRet = 0;
+    if(m_pSortKeyArr->Count() > nIdx)
+        pRet = (*m_pSortKeyArr)[nIdx];
+    DBG_ASSERT(pRet, "Sort key not found")
+    return pRet;
+}
+/* -----------------20.10.99 13:38-------------------
+
+ --------------------------------------------------*/
+void SwAuthorityFieldType::SetSortKeys(USHORT nKeyCount, SwTOXSortKey aKeys[])
+{
+    m_pSortKeyArr->DeleteAndDestroy(0, m_pSortKeyArr->Count());
+    USHORT nArrIdx = 0;
+    for(USHORT i = 0; i < nKeyCount; i++)
+        if(aKeys[i].eField < AUTH_FIELD_END)
+            m_pSortKeyArr->Insert(new SwTOXSortKey(aKeys[i]), nArrIdx++);
+}
+
+/* -----------------14.09.99 16:15-------------------
+
+ --------------------------------------------------*/
+SwAuthorityField::SwAuthorityField( SwAuthorityFieldType* pType,
+                                    const String& rFieldContents )
+    : SwField(pType)
+{
+    nHandle = pType->AddField( rFieldContents );
+}
+/* -----------------17.09.99 14:24-------------------
+
+ --------------------------------------------------*/
+SwAuthorityField::SwAuthorityField( SwAuthorityFieldType* pType,
+                                                long nSetHandle )
+    : SwField( pType ),
+    nHandle( nSetHandle )
+{
+    pType->AddField( nHandle );
+}
+/* -----------------15.09.99 15:00-------------------
+
+ --------------------------------------------------*/
+SwAuthorityField::~SwAuthorityField()
+{
+    ((SwAuthorityFieldType* )GetTyp())->RemoveField(nHandle);
+}
+/*-- 14.09.99 16:20:59---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+String  SwAuthorityField::Expand() const
+{
+    SwAuthorityFieldType* pAuthType = (SwAuthorityFieldType*)GetTyp();
+    String sRet(pAuthType->GetPrefix());
+
+    if( pAuthType->IsSequence() )
+    {
+        sRet += String::CreateFromInt32( pAuthType->GetSequencePos( nHandle ));
+    }
+    else
+    {
+        const SwAuthEntry* pEntry = pAuthType->GetEntryByHandle(nHandle);
+        //TODO: Expand to: identifier, number sequence, ...
+        if(pEntry)
+            sRet += pEntry->GetAuthorField(AUTH_FIELD_IDENTIFIER);
+    }
+    sRet += pAuthType->GetSuffix();
+    return sRet;
+}
+/*-- 14.09.99 16:21:00---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwField* SwAuthorityField::Copy() const
+{
+    SwAuthorityFieldType* pAuthType = (SwAuthorityFieldType*)GetTyp();
+    return new SwAuthorityField(pAuthType, nHandle);
+}
+/* -----------------21.09.99 12:55-------------------
+
+ --------------------------------------------------*/
+const String&   SwAuthorityField::GetFieldText(ToxAuthorityField eField) const
+{
+    SwAuthorityFieldType* pAuthType = (SwAuthorityFieldType*)GetTyp();
+    const SwAuthEntry* pEntry = pAuthType->GetEntryByHandle( nHandle );
+    return pEntry->GetAuthorField( eField );
+}
+/* -----------------21.09.99 14:57-------------------
+
+ --------------------------------------------------*/
+void    SwAuthorityField::SetPar1(const String& rStr)
+{
+    SwAuthorityFieldType* pType = (SwAuthorityFieldType* )GetTyp();
+    pType->RemoveField(nHandle);
+    nHandle = pType->AddField(rStr);
+}
+/* -----------------11.10.99 09:43-------------------
+
+ --------------------------------------------------*/
+USHORT  SwAuthorityField::GetHandlePosition() const
+{
+    SwAuthorityFieldType* pAuthType = (SwAuthorityFieldType*)GetTyp();
+    DBG_ASSERT(pAuthType, "no field type")
+    return pAuthType->GetPosition(nHandle);
+}
+
+
+SwFieldType* SwAuthorityField::ChgTyp( SwFieldType* pFldTyp )
+{
+    SwAuthorityFieldType* pSrcTyp = (SwAuthorityFieldType*)GetTyp(),
+                        * pDstTyp = (SwAuthorityFieldType*)pFldTyp;
+    if( pSrcTyp != pDstTyp )
+    {
+
+        const SwAuthEntry* pEntry = pSrcTyp->GetEntryByHandle( nHandle );
+        USHORT nHdlPos = pDstTyp->AppendField( *pEntry );
+        pSrcTyp->RemoveField( nHandle );
+        nHandle = pDstTyp->GetHandle( nHdlPos );
+        pDstTyp->AddField( nHandle );
+        SwField::ChgTyp( pFldTyp );
+    }
+    return pSrcTyp;
+}
+
+
diff --git a/sw/source/core/fields/cellfml.cxx b/sw/source/core/fields/cellfml.cxx
new file mode 100644
index 000000000000..a425de452149
--- /dev/null
+++ b/sw/source/core/fields/cellfml.cxx
@@ -0,0 +1,1305 @@
+/*************************************************************************
+ *
+ *  $RCSfile: cellfml.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:19 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include 
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _FMTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _FRMFMT_HXX //autogen
+#include 
+#endif
+#ifndef _LAYFRM_HXX
+#include 
+#endif
+#ifndef _CNTFRM_HXX
+#include 
+#endif
+#ifndef _TABFRM_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _SWTABLE_HXX
+#include 
+#endif
+#ifndef _TBLSEL_HXX
+#include 
+#endif
+#ifndef _CELLFML_HXX
+#include 
+#endif
+#ifndef _CALC_HXX
+#include 
+#endif
+#ifndef _EXPFLD_HXX
+#include 
+#endif
+#ifndef _USRFLD_HXX
+#include 
+#endif
+#ifndef _FLDDAT_HXX
+#include 
+#endif
+#ifndef _CELLATR_HXX
+#include 
+#endif
+#ifndef _NDINDEX_HXX
+#include 
+#endif
+#ifndef _HINTS_HXX
+#include 
+#endif
+
+const sal_Unicode cRelTrenner = ',';
+const sal_Unicode cRelKennung = '';        // CTRL-R
+
+const USHORT cMAXSTACKSIZE = 50;
+
+const SwFrm* lcl_GetBoxFrm( const SwTableBox& rBox );
+long lcl_GetLongBoxNum( String& rStr );
+const SwTableBox* lcl_RelToBox( const SwTable&, const SwTableBox*, const String& );
+String lcl_BoxNmToRel( const SwTable&, const SwTableNode&,
+                        const String& , const String& , BOOL );
+
+
+/*************************************************************************
+|*
+|*  double SwTableBox::GetValue() const
+|*      gebe den Wert dieser Box zurueck. Der Wert ergibt sich aus dem 1.
+|*      TextNode. Beginnt dieser mit einer Zahl/Formel, so berechne diese;
+|*      oder mit einem Feld, dann hole den Wert.
+|*      Alle anderen Bedingungen returnen einen Fehler (oder 0 ?)
+|*
+|*  Ersterstellung      JP 30. Jun. 93
+|*  Letzte Aenderung    JP 30. Jun. 93
+|*
+|*************************************************************************/
+
+double SwTableBox::GetValue( SwTblCalcPara& rCalcPara ) const
+{
+    double nRet = 0;
+
+    if( rCalcPara.rCalc.IsCalcError() )
+        return nRet;            // schon ein Fehler in der Berechnung
+
+    rCalcPara.rCalc.SetCalcError( CALC_SYNTAX );    // default immer Fehler
+
+    // keine Content Box ?
+    if( !pSttNd  )
+        return nRet;
+
+    if( rCalcPara.IncStackCnt() )
+        return nRet;
+
+    rCalcPara.SetLastTblBox( this );
+
+    // wird eine Rekursion erzeugt ?
+    SwTableBox* pBox = (SwTableBox*)this;
+    if( rCalcPara.pBoxStk->Seek_Entry( pBox ))
+        return nRet;            // steht schon auf dem Stack: FEHLER
+
+    // bei dieser Box nochmal aufsetzen
+    rCalcPara.SetLastTblBox( this );
+
+    rCalcPara.pBoxStk->Insert( pBox );      // eintragen
+    do {        // Middle-Check-Loop, damit aus dieser gesprungen werden kann
+                // hier aufgespannt, damit am Ende der Box-Pointer aus dem
+                // Stack ausgetragen wird
+        SwDoc* pDoc = GetFrmFmt()->GetDoc();
+
+        const SfxPoolItem* pItem;
+        if( SFX_ITEM_SET == GetFrmFmt()->GetItemState(
+                                RES_BOXATR_FORMULA, FALSE, &pItem ) )
+        {
+            rCalcPara.rCalc.SetCalcError( CALC_NOERR ); // wieder zuruecksetzen
+            if( !((SwTblBoxFormula*)pItem)->IsValid() )
+            {
+                // dann berechnen
+                const SwTable* pTmp = rCalcPara.pTbl;
+                rCalcPara.pTbl = &pBox->GetSttNd()->FindTableNode()->GetTable();
+                ((SwTblBoxFormula*)pItem)->Calc( rCalcPara, nRet );
+
+                if( !rCalcPara.IsStackOverFlow() )
+                {
+                    SwFrmFmt* pFmt = pBox->ClaimFrmFmt();
+                    SfxItemSet aTmp( pDoc->GetAttrPool(),
+                                        RES_BOXATR_BEGIN,RES_BOXATR_END-1 );
+                    aTmp.Put( SwTblBoxValue( nRet ) );
+                    if( SFX_ITEM_SET != pFmt->GetItemState( RES_BOXATR_FORMAT ))
+                        aTmp.Put( SwTblBoxNumFormat( 0 ));
+                    pFmt->SetAttr( aTmp );
+                }
+                rCalcPara.pTbl = pTmp;
+            }
+            else
+                nRet = GetFrmFmt()->GetTblBoxValue().GetValue();
+            break;
+        }
+        else if( SFX_ITEM_SET == pBox->GetFrmFmt()->GetItemState(
+                                RES_BOXATR_VALUE, FALSE, &pItem ) )
+        {
+            rCalcPara.rCalc.SetCalcError( CALC_NOERR ); // wieder zuruecksetzen
+            nRet = ((SwTblBoxValue*)pItem)->GetValue();
+            break;
+        }
+
+        SwTxtNode* pTxtNd = pDoc->GetNodes()[ pSttNd->GetIndex() + 1 ]->GetTxtNode();
+        if( !pTxtNd )
+            break;
+
+        xub_StrLen nSttPos = 0;
+        const String& rTxt = pTxtNd->GetTxt();
+        while( nSttPos < rTxt.Len() &&
+                ( ' ' ==  rTxt.GetChar( nSttPos ) || '\t' ==  rTxt.GetChar( nSttPos ) ) )
+            ++nSttPos;
+
+        // beginnt an erster Position ein "RechenFeld", dann erfrage den Wert
+        // von diesem
+        sal_Unicode cChr;
+        if( nSttPos < rTxt.Len() &&
+            ( CH_TXTATR_BREAKWORD == ( cChr = rTxt.GetChar(nSttPos)) ||
+              CH_TXTATR_INWORD == cChr ))
+        {
+            SwIndex aIdx( pTxtNd, nSttPos );
+            SwTxtFld* pTxtFld = pTxtNd->GetTxtFld( aIdx );
+            if( !pTxtFld )
+                break;
+
+            rCalcPara.rCalc.SetCalcError( CALC_NOERR ); // wieder zuruecksetzen
+
+            const SwField* pFld = pTxtFld->GetFld().GetFld();
+            switch( pFld->GetTyp()->Which()  )
+            {
+            case RES_SETEXPFLD:
+                nRet = ((SwSetExpField*)pFld)->GetValue();
+                break;
+            case RES_USERFLD:
+                nRet = ((SwUserFieldType*)pFld)->GetValue();
+                break;
+            case RES_TABLEFLD:
+                {
+                    SwTblField* pTblFld = (SwTblField*)pFld;
+                    if( !pTblFld->IsValid() )       // ist der Wert gueltig ??
+                    {
+                        // die richtige Tabelle mitgeben!
+                        const SwTable* pTmp = rCalcPara.pTbl;
+                        rCalcPara.pTbl = &pTxtNd->FindTableNode()->GetTable();
+                        pTblFld->CalcField( rCalcPara );
+                        rCalcPara.pTbl = pTmp;
+                    }
+                    nRet = pTblFld->GetValue();
+                }
+                break;
+
+            case RES_DATETIMEFLD:
+                nRet = ((SwDateTimeField*)pFld)->GetValue();
+                break;
+
+            case RES_JUMPEDITFLD:
+                //JP 14.09.98: Bug 56112 - der Platzhalter kann nie einen
+                //              gueltigen Inhalt haben!
+                nRet = 0;
+                break;
+
+            default:
+                nRet = rCalcPara.rCalc.Calculate( pFld->Expand() ).GetDouble();
+            }
+        }
+        else
+        {
+            // Ergebnis ist 0 und kein Fehler!
+            rCalcPara.rCalc.SetCalcError( CALC_NOERR ); // wieder zuruecksetzen
+
+            double aNum;
+            String sTxt( rTxt.Copy( nSttPos ) );
+            ULONG nFmtIndex = GetFrmFmt()->GetTblBoxNumFmt().GetValue();
+
+            SvNumberFormatter* pNumFmtr = pDoc->GetNumberFormatter();
+
+            if( NUMBERFORMAT_TEXT == nFmtIndex )
+                nFmtIndex = 0;
+            // JP 22.04.98: Bug 49659 - Sonderbehandlung fuer Prozent
+            else if( sTxt.Len() &&
+                    NUMBERFORMAT_PERCENT == pNumFmtr->GetType( nFmtIndex ))
+            {
+                ULONG nTmpFmt = 0;
+                if( pNumFmtr->IsNumberFormat( sTxt, nTmpFmt, aNum ) &&
+                    NUMBERFORMAT_NUMBER == pNumFmtr->GetType( nTmpFmt ))
+                    sTxt += '%';
+            }
+
+            if( pNumFmtr->IsNumberFormat( sTxt, nFmtIndex, aNum ))
+                nRet = aNum;
+        }
+
+// ?? sonst ist das ein Fehler
+    } while( FALSE );
+
+    if( !rCalcPara.IsStackOverFlow() )
+    {
+        rCalcPara.pBoxStk->Remove( pBox );      // raus aus dem Stack
+        rCalcPara.DecStackCnt();
+    }
+
+    //JP 12.01.99: mit Fehlererkennung, Bug 60794
+    if( DBL_MAX == nRet )
+        rCalcPara.rCalc.SetCalcError( CALC_SYNTAX );    // Fehler setzen
+
+    return nRet;
+}
+
+/*  */
+
+// Struktur, die zum TabelleRechnen benoetigt wird
+
+SwTblCalcPara::SwTblCalcPara( SwCalc& rCalculator, const SwTable& rTable )
+    : rCalc( rCalculator ), pTbl( &rTable ), nStackCnt( 0 ),
+    nMaxSize( cMAXSTACKSIZE ), pLastTblBox( 0 )
+{
+    pBoxStk = new SwTableSortBoxes;
+}
+
+SwTblCalcPara::~SwTblCalcPara()
+{
+    delete pBoxStk;
+}
+
+BOOL SwTblCalcPara::CalcWithStackOverflow()
+{
+    // falls ein StackUeberlauf erkannt wurde, sollte mit
+    // der letzten Box noch mal aufgesetzt werden. Irgend
+    // ein Weg sollte dann
+    USHORT nSaveMaxSize = nMaxSize;
+
+    nMaxSize = cMAXSTACKSIZE - 5;
+    USHORT nCnt = 0;
+    SwTableBoxes aStackOverFlows;
+    do {
+        SwTableBox* pBox = (SwTableBox*)pLastTblBox;
+        nStackCnt = 0;
+        rCalc.SetCalcError( CALC_NOERR );
+        aStackOverFlows.C40_INSERT( SwTableBox, pBox, nCnt++ );
+
+        pBoxStk->Remove( pBox );
+        pBox->GetValue( *this );
+    } while( IsStackOverFlow() );
+
+    nMaxSize = cMAXSTACKSIZE - 3;       // es muss mind. 1 Stufe tiefer gehen!
+
+    // falls Rekursionen erkannt wurden
+    nStackCnt = 0;
+    rCalc.SetCalcError( CALC_NOERR );
+    pBoxStk->Remove( USHORT(0), pBoxStk->Count() );
+
+    while( !rCalc.IsCalcError() && nCnt )
+    {
+        aStackOverFlows[ --nCnt ]->GetValue( *this );
+        if( IsStackOverFlow() && !CalcWithStackOverflow() )
+            break;
+    }
+
+    nMaxSize = nSaveMaxSize;
+    aStackOverFlows.Remove( 0, aStackOverFlows.Count() );
+    return !rCalc.IsCalcError();
+}
+
+/*  */
+
+SwTableFormula::SwTableFormula( const String& rFormel )
+    : sFormel( rFormel )
+{
+    eNmType = EXTRNL_NAME;
+    bValidValue = FALSE;
+}
+
+void SwTableFormula::_MakeFormel( const SwTable& rTbl, String& rNewStr,
+                    String& rFirstBox, String* pLastBox, void* pPara ) const
+{
+    SwTblCalcPara* pCalcPara = (SwTblCalcPara*)pPara;
+    if( pCalcPara->rCalc.IsCalcError() )        // ist schon Fehler gesetzt ?
+        return;
+
+    SwTableBox* pSttBox, *pEndBox = 0;
+
+    rFirstBox.Erase(0,1);       // Kennung fuer Box loeschen
+    // ein Bereich in dieser Klammer ?
+    if( pLastBox )
+    {
+    //TODOUNICODE: does it work?
+//      pEndBox = (SwTableBox*)(long)(*pLastBox);
+        pEndBox = (SwTableBox*)pLastBox->ToInt32();
+
+        // ist das ueberhaupt ein gueltiger Pointer ??
+        if( !rTbl.GetTabSortBoxes().Seek_Entry( pEndBox ))
+            pEndBox = 0;
+        rFirstBox.Erase( 0, pLastBox->Len()+1 );
+    }
+    //TODOUNICODE: does it work?
+//  pSttBox = (SwTableBox*)(long)rFirstBox;
+    pSttBox = (SwTableBox*)rFirstBox.ToInt32();
+    // ist das ueberhaupt ein gueltiger Pointer ??
+    if( !rTbl.GetTabSortBoxes().Seek_Entry( pSttBox ))
+        pSttBox = 0;
+
+    rNewStr += ' ';
+    if( pEndBox && pSttBox )    // Bereich ?
+    {
+        // hole ueber das Layout alle "selectierten" Boxen und berechne
+        // deren Werte
+        SwSelBoxes aBoxes;
+        GetBoxes( *pSttBox, *pEndBox, aBoxes );
+
+        rNewStr += '(';
+        for( USHORT n = 0; n < aBoxes.Count() &&
+                           !pCalcPara->rCalc.IsCalcError(); ++n )
+        {
+            if( n )
+                rNewStr += cListDelim;
+            rNewStr += pCalcPara->rCalc.GetStrResult(
+                        aBoxes[n]->GetValue( *pCalcPara ), FALSE );
+        }
+        rNewStr += ')';
+    }
+    else if( pSttBox && !pLastBox )         // nur die StartBox ?
+                            //JP 12.01.99: und keine EndBox in der Formel!
+        // Berechne den Wert der Box
+        rNewStr += pCalcPara->rCalc.GetStrResult(
+                            pSttBox->GetValue( *pCalcPara ), FALSE );
+    else
+        pCalcPara->rCalc.SetCalcError( CALC_SYNTAX );   // Fehler setzen
+    rNewStr += ' ';
+}
+
+void SwTableFormula::RelNmsToBoxNms( const SwTable& rTbl, String& rNewStr,
+            String& rFirstBox, String* pLastBox, void* pPara ) const
+{
+    // relativen Namen zu Box-Namen (externe Darstellung)
+    SwNode* pNd = (SwNode*)pPara;
+    ASSERT( pNd, "Feld steht in keinem TextNode" );
+    const SwTableBox *pRelBox, *pBox = (SwTableBox *)rTbl.GetTblBox(
+                    pNd->FindTableBoxStartNode()->GetIndex() );
+
+    rNewStr += rFirstBox.Copy(0,1);     // Kennung fuer Box erhalten
+    rFirstBox.Erase(0,1);
+    if( pLastBox )
+    {
+        if( 0 != ( pRelBox = lcl_RelToBox( rTbl, pBox, *pLastBox )) )
+            rNewStr += pRelBox->GetName();
+        else
+            rNewStr.AppendAscii("A1");
+        rNewStr += ':';
+        rFirstBox.Erase( 0, pLastBox->Len()+1 );
+    }
+
+    if( 0 != ( pRelBox = lcl_RelToBox( rTbl, pBox, rFirstBox )) )
+        rNewStr += pRelBox->GetName();
+    else
+        rNewStr.AppendAscii("A1");
+
+    // Kennung fuer Box erhalten
+    rNewStr += rFirstBox.GetChar( rFirstBox.Len() - 1 );
+}
+
+void SwTableFormula::RelBoxNmsToPtr( const SwTable& rTbl, String& rNewStr,
+            String& rFirstBox, String* pLastBox, void* pPara ) const
+{
+    // relativen Namen zu Box-Pointern (interne Darstellung)
+    SwNode* pNd = (SwNode*)pPara;
+    ASSERT( pNd, "Feld steht in keinem Node" );
+    const SwTableBox *pRelBox, *pBox = (SwTableBox*)rTbl.GetTblBox(
+                    pNd->FindTableBoxStartNode()->GetIndex() );
+
+    rNewStr += rFirstBox.Copy(0,1);     // Kennung fuer Box erhalten
+    rFirstBox.Erase(0,1);
+    if( pLastBox )
+    {
+        if( 0 != ( pRelBox = lcl_RelToBox( rTbl, pBox, *pLastBox )) )
+            rNewStr += String::CreateFromInt32( (long)pRelBox );
+        else
+            rNewStr += '0';
+        rNewStr += ':';
+        rFirstBox.Erase( 0, pLastBox->Len()+1 );
+    }
+
+    if( 0 != ( pRelBox = lcl_RelToBox( rTbl, pBox, rFirstBox )) )
+        rNewStr += String::CreateFromInt32( (long)pRelBox );
+    else
+        rNewStr += '0';
+
+    // Kennung fuer Box erhalten
+    rNewStr += rFirstBox.GetChar( rFirstBox.Len() - 1 );
+}
+
+
+void SwTableFormula::BoxNmsToRelNm( const SwTable& rTbl, String& rNewStr,
+                    String& rFirstBox, String* pLastBox, void* pPara ) const
+{
+    // Box-Namen (externe Darstellung) zu relativen Namen
+    SwNode* pNd = (SwNode*)pPara;
+    ASSERT( pNd, "Feld steht in keinem Node" );
+    const SwTableNode* pTblNd = pNd->FindTableNode();
+
+    String sRefBoxNm;
+    if( &pTblNd->GetTable() == &rTbl )
+    {
+        const SwTableBox *pBox = rTbl.GetTblBox(
+                pNd->FindTableBoxStartNode()->GetIndex() );
+        ASSERT( pBox, "Feld steht in keiner Tabelle" );
+        sRefBoxNm = pBox->GetName();
+    }
+
+    rNewStr += rFirstBox.Copy(0,1);     // Kennung fuer Box erhalten
+    rFirstBox.Erase(0,1);
+    if( pLastBox )
+    {
+        rNewStr += lcl_BoxNmToRel( rTbl, *pTblNd, sRefBoxNm, *pLastBox,
+                                eNmType == EXTRNL_NAME );
+        rNewStr += ':';
+        rFirstBox.Erase( 0, pLastBox->Len()+1 );
+    }
+
+    rNewStr += lcl_BoxNmToRel( rTbl, *pTblNd, sRefBoxNm, rFirstBox,
+                            eNmType == EXTRNL_NAME );
+
+    // Kennung fuer Box erhalten
+    rNewStr += rFirstBox.GetChar( rFirstBox.Len() - 1 );
+}
+
+
+void SwTableFormula::PtrToBoxNms( const SwTable& rTbl, String& rNewStr,
+                        String& rFirstBox, String* pLastBox, void* ) const
+{
+    // ein Bereich in dieser Klammer ?
+    SwTableBox* pBox;
+
+    rNewStr += rFirstBox.Copy(0,1);     // Kennung fuer Box erhalten
+    rFirstBox.Erase(0,1);
+    if( pLastBox )
+    {
+//      pBox = (SwTableBox*)(long)(*pLastBox);
+        pBox = (SwTableBox*)pLastBox->ToInt32();
+
+        // ist das ueberhaupt ein gueltiger Pointer ??
+        if( rTbl.GetTabSortBoxes().Seek_Entry( pBox ))
+            rNewStr += pBox->GetName();
+        else
+            rNewStr += '?';
+        rNewStr += ':';
+        rFirstBox.Erase( 0, pLastBox->Len()+1 );
+    }
+
+//  pBox = (SwTableBox*)(long)rFirstBox;
+    pBox = (SwTableBox*)rFirstBox.ToInt32();
+    // ist das ueberhaupt ein gueltiger Pointer ??
+    if( rTbl.GetTabSortBoxes().Seek_Entry( pBox ))
+        rNewStr += pBox->GetName();
+    else
+        rNewStr += '?';
+
+    // Kennung fuer Box erhalten
+    rNewStr += rFirstBox.GetChar( rFirstBox.Len() - 1 );
+}
+
+void SwTableFormula::BoxNmsToPtr( const SwTable& rTbl, String& rNewStr,
+                        String& rFirstBox, String* pLastBox, void* ) const
+{
+    // ein Bereich in dieser Klammer ?
+    const SwTableBox* pBox;
+
+    rNewStr += rFirstBox.Copy(0,1);     // Kennung fuer Box erhalten
+    rFirstBox.Erase(0,1);
+    if( pLastBox )
+    {
+        pBox = rTbl.GetTblBox( *pLastBox );
+        rNewStr += String::CreateFromInt32( (long)pBox );
+        rNewStr += ':';
+        rFirstBox.Erase( 0, pLastBox->Len()+1 );
+    }
+
+    pBox = rTbl.GetTblBox( rFirstBox );
+    rNewStr += String::CreateFromInt32( (long)pBox );
+
+    // Kennung fuer Box erhalten
+    rNewStr += rFirstBox.GetChar( rFirstBox.Len() - 1 );
+}
+
+    // erzeuge die externe (fuer UI) Formel
+void SwTableFormula::PtrToBoxNm( const SwTable* pTbl )
+{
+    const SwNode* pNd = 0;
+    FnScanFormel fnFormel = 0;
+    switch( eNmType)
+    {
+    case INTRNL_NAME:
+        if( pTbl )
+            fnFormel = &SwTableFormula::PtrToBoxNms;
+        break;
+    case REL_NAME:
+        if( pTbl )
+        {
+            fnFormel = &SwTableFormula::RelNmsToBoxNms;
+            pNd = GetNodeOfFormula();
+        }
+        break;
+    case EXTRNL_NAME:
+        return;
+    }
+    sFormel = ScanString( fnFormel, *pTbl, (void*)pNd );
+    eNmType = EXTRNL_NAME;
+}
+
+    // erzeuge die interne (in CORE) Formel
+void SwTableFormula::BoxNmToPtr( const SwTable* pTbl )
+{
+    const SwNode* pNd = 0;
+    FnScanFormel fnFormel = 0;
+    switch( eNmType)
+    {
+    case EXTRNL_NAME:
+        if( pTbl )
+            fnFormel = &SwTableFormula::BoxNmsToPtr;
+        break;
+    case REL_NAME:
+        if( pTbl )
+        {
+            fnFormel = &SwTableFormula::RelBoxNmsToPtr;
+            pNd = GetNodeOfFormula();
+        }
+        break;
+    case INTRNL_NAME:
+        return;
+    }
+    sFormel = ScanString( fnFormel, *pTbl, (void*)pNd );
+    eNmType = INTRNL_NAME;
+}
+
+    // erzeuge die relative (fuers Kopieren) Formel
+void SwTableFormula::ToRelBoxNm( const SwTable* pTbl )
+{
+    const SwNode* pNd = 0;
+    FnScanFormel fnFormel = 0;
+    switch( eNmType)
+    {
+    case INTRNL_NAME:
+    case EXTRNL_NAME:
+        if( pTbl )
+        {
+            fnFormel = &SwTableFormula::BoxNmsToRelNm;
+            pNd = GetNodeOfFormula();
+        }
+        break;
+    case REL_NAME:
+        return;
+    }
+    sFormel = ScanString( fnFormel, *pTbl, (void*)pNd );
+    eNmType = REL_NAME;
+}
+
+
+String SwTableFormula::ScanString( FnScanFormel fnFormel, const SwTable& rTbl,
+                                    void* pPara ) const
+{
+    String aStr;
+    USHORT nFml = 0, nStt = 0, nEnd = 0, nTrenner;
+
+    do {
+        // falls der Formel ein Name vorangestellt ist, diese Tabelle
+        // benutzen !!
+        const SwTable* pTbl = &rTbl;
+
+        nStt = sFormel.Search( '<', nFml );
+        if( STRING_NOTFOUND != nStt )
+        {
+            while( STRING_NOTFOUND != nStt &&
+                ( ' ' == sFormel.GetChar( nStt + 1 ) ||
+                  '=' == sFormel.GetChar( nStt + 1 ) ) )
+                nStt = sFormel.Search( '<', nStt + 1 );
+
+            if( STRING_NOTFOUND != nStt )
+                nEnd = sFormel.Search( '>', nStt+1 );
+        }
+        if( STRING_NOTFOUND == nStt || STRING_NOTFOUND == nEnd )
+        {
+            // den Rest setzen und beenden
+            aStr.Insert( sFormel, nFml, sFormel.Len() - nFml );
+            break;
+        }
+        aStr.Insert( sFormel, nFml, nStt - nFml );  // Anfang schreiben
+
+        if( fnFormel != NULL )
+        {
+            // ist ein TabellenName vorangestellt ??
+            // JP 16.02.99: SplitMergeBoxNm behandeln den Namen selbst
+            // JP 22.02.99: der CAST muss fuer den Linux-Compiler sein
+            // JP 28.06.99: rel. BoxName have no preceding tablename!
+            if( fnFormel != (FnScanFormel)&SwTableFormula::_SplitMergeBoxNm &&
+                1 < sFormel.Len() && cRelKennung != sFormel.GetChar( 1 ) &&
+                STRING_NOTFOUND != ( nTrenner = sFormel.Search( '.', nStt ))
+                && nTrenner < nEnd )
+            {
+                String sTblNm( sFormel.Copy( nStt, nEnd - nStt ));
+
+                // falls im Namen schon die Punkte enthalten sind,
+                // treten diese immer paarig auf!!! (A1.1.1 !!)
+                if( (sTblNm.GetTokenCount( '.' ) - 1 ) & 1 )
+                {
+                    sTblNm.Erase( nTrenner - nStt );
+
+                    // beim Bauen der Formel ist der TabellenName unerwuenscht
+                    //JP 22.02.99: der CAST muss fuer den Linux-Compiler sein
+                    if( fnFormel != (FnScanFormel)&SwTableFormula::_MakeFormel )
+                        aStr += sTblNm;
+                    nStt = nTrenner;
+
+                    sTblNm.Erase( 0, 1 );   // Trenner loeschen
+                    if( sTblNm != rTbl.GetFrmFmt()->GetName() )
+                    {
+                        // dann suchen wir uns mal unsere Tabelle:
+                        const SwTable* pFnd = FindTable(
+                                                *rTbl.GetFrmFmt()->GetDoc(),
+                                                sTblNm );
+                        if( pFnd )
+                            pTbl = pFnd;
+                        // ??
+                        ASSERT( pFnd, "Tabelle nicht gefunden, was nun?" );
+                    }
+                }
+            }
+
+            String sBox( sFormel.Copy( nStt, nEnd - nStt + 1 ));
+            // ein Bereich in dieser Klammer ?
+            if( STRING_NOTFOUND != ( nTrenner = sFormel.Search( ':', nStt ))
+                && nTrenner < nEnd )
+            {
+                // ohne die Anfangsklammer
+                String aFirstBox( sFormel.Copy( nStt+1, nTrenner - nStt - 1 ));
+                (this->*fnFormel)( *pTbl, aStr, sBox, &aFirstBox, pPara );
+            }
+            else
+                (this->*fnFormel)( *pTbl, aStr, sBox, 0, pPara );
+        }
+
+        nFml = nEnd+1;
+    } while( TRUE );
+    return aStr;
+}
+
+const SwTable* SwTableFormula::FindTable( SwDoc& rDoc, const String& rNm ) const
+{
+    const SwFrmFmts& rTblFmts = *rDoc.GetTblFrmFmts();
+    const SwTable* pTmpTbl, *pRet = 0;
+    for( USHORT nFmtCnt = rTblFmts.Count(); nFmtCnt; )
+    {
+        SwFrmFmt* pFmt = rTblFmts[ --nFmtCnt ];
+        // falls wir von Sw3Writer gerufen werden, dann ist dem
+        // FormatNamen eine Nummer anhaengig
+        SwTableBox* pFBox;
+        if( COMPARE_EQUAL == rNm.CompareTo( pFmt->GetName(),
+                                        pFmt->GetName().Search( 0x0a ) ) &&
+            0 != ( pTmpTbl = SwTable::FindTable( pFmt ) ) &&
+            0 != (pFBox = pTmpTbl->GetTabSortBoxes()[0] ) &&
+            pFBox->GetSttNd() &&
+            pFBox->GetSttNd()->GetNodes().IsDocNodes() )
+        {
+            // eine Tabelle im normalen NodesArr
+            pRet = pTmpTbl;
+            break;
+        }
+    }
+    return pRet;
+}
+
+/*  */
+
+const SwFrm* lcl_GetBoxFrm( const SwTableBox& rBox )
+{
+/*
+
+    // oder besser ueber die Box den Frame suchen
+
+    SwClientIter aIter( *pBox->GetFrmFmt() );
+    ULONG nMinPos = ULONG_MAX;
+    const SwFrm* pFnd = 0;
+    for( SwFrm* pF = (SwFrm*)aIter.First( TYPE( SwCellFrm )); pF;
+            pF = (SwFrm*)aIter.Next() )
+    {
+        if( pF->Frm().Y() <
+    }
+*/
+
+    SwNodeIndex aIdx( *rBox.GetSttNd() );
+    SwCntntNode* pCNd = aIdx.GetNodes().GoNext( &aIdx );
+    ASSERT( pCNd, "Box hat keinen TextNode" );
+    Point aPt;      // den im Layout 1. Frame returnen - Tab.Kopfzeile !!
+    return pCNd->GetFrm( &aPt, NULL, FALSE );
+}
+
+long lcl_GetLongBoxNum( String& rStr )
+{
+    USHORT nPos;
+    long nRet;
+    if( STRING_NOTFOUND == ( nPos = rStr.Search( cRelTrenner ) ))
+    {
+        nRet = rStr.ToInt32();
+        rStr.Erase();
+    }
+    else
+    {
+        nRet = rStr.Copy( 0, nPos ).ToInt32();
+        rStr.Erase( 0, nPos+1 );
+    }
+    return nRet;
+}
+
+const SwTableBox* lcl_RelToBox( const SwTable& rTbl,
+                                    const SwTableBox* pRefBox,
+                                    const String& rGetName )
+{
+    // hole die Line
+    const SwTableBox* pBox = 0;
+    String sGetName( rGetName );
+
+    // ist es denn wirklich eine relative Angabe??
+    if( cRelKennung == sGetName.GetChar(0) )            // ja, ...
+    {
+        if( !pRefBox )
+            return 0;
+
+        sGetName.Erase( 0, 1 );
+
+        const SwTableLines* pLines = (SwTableLines*)&rTbl.GetTabLines();
+        const SwTableBoxes* pBoxes;
+        const SwTableLine* pLine;
+
+        // bestimme erst mal die Start-Werte der Box:
+        pBox = (SwTableBox*)pRefBox;
+        pLine = pBox->GetUpper();
+        while( pLine->GetUpper() )
+        {
+            pBox = pLine->GetUpper();
+            pLine = pBox->GetUpper();
+        }
+        USHORT nSttBox = pLine->GetTabBoxes().GetPos( pBox );
+        USHORT nSttLine = rTbl.GetTabLines().GetPos( pLine );
+
+        long nBoxOffset = lcl_GetLongBoxNum( sGetName ) + nSttBox;
+        long nLineOffset = lcl_GetLongBoxNum( sGetName ) + nSttLine;
+
+        if( nBoxOffset < 0 || nBoxOffset >= USHRT_MAX ||
+            nLineOffset < 0 || nLineOffset >= USHRT_MAX )
+            return 0;
+
+        if( nLineOffset >= long(pLines->Count()) )
+            return 0;
+
+        pLine = (*pLines)[ USHORT(nLineOffset) ];
+
+        // dann suche die Box
+        pBoxes = &pLine->GetTabBoxes();
+        if( nBoxOffset >= long(pBoxes->Count()) )
+            return 0;
+        pBox = (*pBoxes)[ USHORT(nBoxOffset) ];
+
+        while( sGetName.Len() )
+        {
+            nSttBox = SwTable::_GetBoxNum( sGetName );
+            pLines = &pBox->GetTabLines();
+            if( nSttBox )
+                --nSttBox;
+
+            nSttLine = SwTable::_GetBoxNum( sGetName );
+
+            // bestimme die Line
+            if( !nSttLine || nSttLine > pLines->Count() )
+                break;
+            pLine = (*pLines)[ nSttLine-1 ];
+
+            // bestimme die Box
+            pBoxes = &pLine->GetTabBoxes();
+            if( nSttBox >= pBoxes->Count() )
+                break;
+            pBox = (*pBoxes)[ nSttBox ];
+        }
+
+        if( pBox )
+        {
+            if( !pBox->GetSttNd() )
+                // "herunterfallen lassen" bis zur ersten Box
+                while( pBox->GetTabLines().Count() )
+                    pBox = pBox->GetTabLines()[0]->GetTabBoxes()[0];
+        }
+    }
+    else
+    {
+        // sonst ist es eine absolute externe Darstellung:
+        pBox = rTbl.GetTblBox( sGetName );
+    }
+    return pBox;
+}
+
+String lcl_BoxNmToRel( const SwTable& rTbl, const SwTableNode& rTblNd,
+                            const String& rRefBoxNm, const String& rGetStr,
+                            BOOL bExtrnlNm )
+{
+    String sCpy( rRefBoxNm );
+    String sTmp( rGetStr );
+    if( !bExtrnlNm )
+    {
+        // in die Externe Darstellung umwandeln.
+//      SwTableBox* pBox = (SwTableBox*)(long)sTmp;
+        SwTableBox* pBox = (SwTableBox*)sTmp.ToInt32();
+        if( !rTbl.GetTabSortBoxes().Seek_Entry( pBox ))
+            return '?';
+        sTmp = pBox->GetName();
+    }
+
+    // sollte die es eine Tabellen uebergreifende Formel sein, dann behalte
+    // die externe Darstellung bei:
+    if( &rTbl == &rTblNd.GetTable() )
+    {
+        long nBox = SwTable::_GetBoxNum( sTmp, TRUE );
+        nBox -= SwTable::_GetBoxNum( sCpy, TRUE );
+        long nLine = SwTable::_GetBoxNum( sTmp );
+        nLine -= SwTable::_GetBoxNum( sCpy );
+
+        sCpy = sTmp;        //JP 01.11.95: den Rest aus dem BoxNamen anhaengen
+
+        sTmp = cRelKennung;
+        sTmp += String::CreateFromInt32( nBox );
+        sTmp += cRelTrenner;
+        sTmp += String::CreateFromInt32( nLine );
+
+        if( sCpy.Len() )
+        {
+            sTmp += cRelTrenner;
+            sTmp += sCpy;
+        }
+    }
+
+    if( sTmp.Len() && '>' == sTmp.GetChar( sTmp.Len() - 1 ))
+        sTmp.Erase( sTmp.Len()-1 );
+
+    return sTmp;
+}
+
+USHORT SwTableFormula::GetBoxesOfFormula( const SwTable& rTbl,
+                                        SwSelBoxes& rBoxes )
+{
+    if( rBoxes.Count() )
+        rBoxes.Remove( USHORT(0), rBoxes.Count() );
+
+    BoxNmToPtr( &rTbl );
+    ScanString( &SwTableFormula::_GetFmlBoxes, rTbl, &rBoxes );
+    return rBoxes.Count();
+}
+
+void SwTableFormula::_GetFmlBoxes( const SwTable& rTbl, String& rNewStr,
+                    String& rFirstBox, String* pLastBox, void* pPara ) const
+{
+    SwSelBoxes* pBoxes = (SwSelBoxes*)pPara;
+    SwTableBox* pSttBox, *pEndBox = 0;
+
+    rFirstBox.Erase(0,1);       // Kennung fuer Box loeschen
+    // ein Bereich in dieser Klammer ?
+    if( pLastBox )
+    {
+//      pEndBox = (SwTableBox*)(long)(*pLastBox);
+        pEndBox = (SwTableBox*)pLastBox->ToInt32();
+
+        // ist das ueberhaupt ein gueltiger Pointer ??
+        if( !rTbl.GetTabSortBoxes().Seek_Entry( pEndBox ))
+            pEndBox = 0;
+        rFirstBox.Erase( 0, pLastBox->Len()+1 );
+    }
+
+//  pSttBox = (SwTableBox*)(long)rFirstBox;
+    pSttBox = (SwTableBox*)rFirstBox.ToInt32();
+    // ist das ueberhaupt ein gueltiger Pointer ??
+    if( !rTbl.GetTabSortBoxes().Seek_Entry( pSttBox ))
+        pSttBox = 0;
+
+    if( pEndBox && pSttBox )    // Bereich ?
+    {
+        // ueber das Layout alle "selectierten" Boxen und berechne
+        // deren Werte
+        SwSelBoxes aBoxes;
+        GetBoxes( *pSttBox, *pEndBox, aBoxes );
+        pBoxes->Insert( &aBoxes );
+    }
+    else if( pSttBox )          // nur die StartBox ?
+        pBoxes->Insert( pSttBox );
+}
+
+void SwTableFormula::GetBoxes( const SwTableBox& rSttBox,
+                                const SwTableBox& rEndBox,
+                                SwSelBoxes& rBoxes ) const
+{
+    // hole ueber das Layout alle "selektierten" Boxen
+    const SwLayoutFrm *pStt, *pEnd;
+    const SwFrm* pFrm = lcl_GetBoxFrm( rSttBox );
+    pStt = pFrm ? pFrm->GetUpper() : 0;
+    pEnd = ( 0 != (pFrm = lcl_GetBoxFrm( rEndBox ))) ? pFrm->GetUpper() : 0;
+    if( !pStt || !pEnd )
+        return ;                        // no valid selection
+
+    GetTblSel( pStt, pEnd, rBoxes );
+
+    const SwTable* pTbl = pStt->FindTabFrm()->GetTable();
+
+    // filter die Kopfzeilen-Boxen heraus:
+    if( pTbl->IsHeadlineRepeat() )
+        do {    // middle-check loop
+            const SwTableLine* pHeadLine = pTbl->GetTabLines()[0];
+            const SwTableLine* pLine = rSttBox.GetUpper();
+            while( pLine->GetUpper() )
+                pLine = pLine->GetUpper()->GetUpper();
+
+            if( pLine == pHeadLine )
+                break;      // Headline mit im Bereich !
+            // vielleicht ist ja Start und Ende vertauscht
+            pLine = rEndBox.GetUpper();
+            while ( pLine->GetUpper() )
+                pLine = pLine->GetUpper()->GetUpper();
+            if( pLine == pHeadLine )
+                break;      // Headline mit im Bereich !
+
+            const SwTabFrm *pTable = pStt->FindTabFrm();
+            const SwTabFrm *pEndTable = pEnd->FindTabFrm();
+            if( pTable == pEndTable )       // keine gespl. Tabelle
+                break;
+
+            // dann mal die Tabellenkoepfe raus:
+            for( USHORT n = 0; n < rBoxes.Count(); ++n )
+            {
+                while( (pLine = rBoxes[n]->GetUpper())->GetUpper() )
+                    pLine = pLine->GetUpper()->GetUpper();
+
+                if( pLine == pHeadLine )
+                    rBoxes.Remove( n--, 1 );
+            }
+        } while( FALSE );
+}
+
+    // sind alle Boxen gueltig, auf die sich die Formel bezieht?
+void SwTableFormula::_HasValidBoxes( const SwTable& rTbl, String& rNewStr,
+                    String& rFirstBox, String* pLastBox, void* pPara ) const
+{
+    BOOL* pBValid = (BOOL*)pPara;
+    if( *pBValid )      // einmal falsch, immer falsch
+    {
+        SwTableBox* pSttBox, *pEndBox = 0;
+        rFirstBox.Erase(0,1);       // Kennung fuer Box loeschen
+
+        // ein Bereich in dieser Klammer ?
+        if( pLastBox )
+            rFirstBox.Erase( 0, pLastBox->Len()+1 );
+
+        switch( eNmType)
+        {
+        case INTRNL_NAME:
+            if( pLastBox )
+            {
+//              pEndBox = (SwTableBox*)(long)(*pLastBox);
+                pEndBox = (SwTableBox*)pLastBox->ToInt32();
+            }
+//          pSttBox = (SwTableBox*)(long)rFirstBox;
+            pSttBox = (SwTableBox*)rFirstBox.ToInt32();
+            break;
+
+        case REL_NAME:
+            {
+                const SwNode* pNd = GetNodeOfFormula();
+                const SwTableBox* pBox = !pNd ? 0
+                                               : (SwTableBox *)rTbl.GetTblBox(
+                                    pNd->FindTableBoxStartNode()->GetIndex() );
+                if( pLastBox )
+                    pEndBox = (SwTableBox*)lcl_RelToBox( rTbl, pBox, *pLastBox );
+                pSttBox = (SwTableBox*)lcl_RelToBox( rTbl, pBox, rFirstBox );
+            }
+            break;
+
+        case EXTRNL_NAME:
+            if( pLastBox )
+                pEndBox = (SwTableBox*)rTbl.GetTblBox( *pLastBox );
+            pSttBox = (SwTableBox*)rTbl.GetTblBox( rFirstBox );
+            break;
+        }
+
+        // sind das gueltige Pointer ?
+        if( ( pLastBox &&
+              ( !pEndBox || !rTbl.GetTabSortBoxes().Seek_Entry( pEndBox ) ) ) ||
+            ( !pSttBox || !rTbl.GetTabSortBoxes().Seek_Entry( pSttBox ) ) )
+                *pBValid = FALSE;
+    }
+}
+
+BOOL SwTableFormula::HasValidBoxes() const
+{
+    BOOL bRet = TRUE;
+    const SwNode* pNd = GetNodeOfFormula();
+    if( pNd && 0 != ( pNd = pNd->FindTableNode() ) )
+        ScanString( &SwTableFormula::_HasValidBoxes,
+                        ((SwTableNode*)pNd)->GetTable(), &bRet );
+    return bRet;
+}
+
+
+USHORT SwTableFormula::GetLnPosInTbl( const SwTable& rTbl, const SwTableBox* pBox )
+{
+    USHORT nRet = USHRT_MAX;
+    if( pBox )
+    {
+        const SwTableLine* pLn = pBox->GetUpper();
+        while( pLn->GetUpper() )
+            pLn = pLn->GetUpper()->GetUpper();
+        nRet = rTbl.GetTabLines().GetPos( pLn );
+    }
+    return nRet;
+}
+
+void SwTableFormula::_SplitMergeBoxNm( const SwTable& rTbl, String& rNewStr,
+                    String& rFirstBox, String* pLastBox, void* pPara ) const
+{
+    SwTableFmlUpdate& rTblUpd = *(SwTableFmlUpdate*)pPara;
+
+    rNewStr += rFirstBox.Copy(0,1);     // Kennung fuer Box erhalten
+    rFirstBox.Erase(0,1);
+
+    String sTblNm;
+    const SwTable* pTbl = &rTbl;
+
+    String* pTblNmBox = pLastBox ? pLastBox : &rFirstBox;
+
+    USHORT nLastBoxLen = pTblNmBox->Len();
+    USHORT nTrenner = pTblNmBox->Search( '.' );
+    if( STRING_NOTFOUND != nTrenner &&
+        // falls im Namen schon die Punkte enthalten sind,
+        // treten diese immer paarig auf!!! (A1.1.1 !!)
+        (pTblNmBox->GetTokenCount( '.' ) - 1 ) & 1 )
+    {
+        sTblNm = pTblNmBox->Copy( 0, nTrenner );
+        pTblNmBox->Erase( 0, nTrenner + 1);// den Punkt entfernen
+        const SwTable* pFnd = FindTable( *rTbl.GetFrmFmt()->GetDoc(), sTblNm );
+        if( pFnd )
+            pTbl = pFnd;
+
+        if( TBL_MERGETBL == rTblUpd.eFlags )
+        {
+            if( pFnd )
+            {
+                if( pFnd == rTblUpd.DATA.pDelTbl )
+                {
+                    if( rTblUpd.pTbl != &rTbl )         // es ist nicht die akt.
+                        (rNewStr += rTblUpd.pTbl->GetFrmFmt()->GetName() )
+                            += '.'; // den neuen Tabellen Namen setzen
+                    rTblUpd.bModified = TRUE;
+                }
+                else if( pFnd != rTblUpd.pTbl ||
+                    ( rTblUpd.pTbl != &rTbl && &rTbl != rTblUpd.DATA.pDelTbl))
+                    (rNewStr += sTblNm ) += '.';    // den Tabellen Namen behalten
+                else
+                    rTblUpd.bModified = TRUE;
+            }
+            else
+                (rNewStr += sTblNm ) += '.';    // den Tabellen Namen behalten
+
+        }
+    }
+    if( pTblNmBox == pLastBox )
+        rFirstBox.Erase( 0, nLastBoxLen + 1 );
+
+    SwTableBox* pSttBox, *pEndBox = 0;
+    switch( eNmType )
+    {
+    case INTRNL_NAME:
+        if( pLastBox )
+        {
+//          pEndBox = (SwTableBox*)(long)(*pLastBox);
+            pEndBox = (SwTableBox*)pLastBox->ToInt32();
+        }
+//      pSttBox = (SwTableBox*)(long)rFirstBox;
+        pSttBox = (SwTableBox*)rFirstBox.ToInt32();
+        break;
+
+    case REL_NAME:
+        {
+            const SwNode* pNd = GetNodeOfFormula();
+            const SwTableBox* pBox = pNd ? pTbl->GetTblBox(
+                            pNd->FindTableBoxStartNode()->GetIndex() ) : 0;
+            if( pLastBox )
+                pEndBox = (SwTableBox*)lcl_RelToBox( *pTbl, pBox, *pLastBox );
+            pSttBox = (SwTableBox*)lcl_RelToBox( *pTbl, pBox, rFirstBox );
+        }
+        break;
+
+    case EXTRNL_NAME:
+        if( pLastBox )
+            pEndBox = (SwTableBox*)pTbl->GetTblBox( *pLastBox );
+        pSttBox = (SwTableBox*)pTbl->GetTblBox( rFirstBox );
+        break;
+    }
+
+    if( pLastBox && !pTbl->GetTabSortBoxes().Seek_Entry( pEndBox ))
+        pEndBox = 0;
+    if( !pTbl->GetTabSortBoxes().Seek_Entry( pSttBox ))
+        pSttBox = 0;
+
+    if( TBL_SPLITTBL == rTblUpd.eFlags )
+    {
+        // wo liegen die Boxen, in der "alten" oder in der neuen Tabelle?
+        BOOL bInNewTbl = FALSE;
+        if( pLastBox )
+        {
+            // das ist die "erste" Box in der Selektion. Die bestimmt ob die
+            // Formel in der alten oder neuen Tabelle steht.
+            USHORT nEndLnPos = SwTableFormula::GetLnPosInTbl( *pTbl, pEndBox ),
+                    nSttLnPos = SwTableFormula::GetLnPosInTbl( *pTbl, pSttBox );
+
+            if( USHRT_MAX != nSttLnPos && USHRT_MAX != nEndLnPos &&
+                rTblUpd.nSplitLine <= nSttLnPos ==
+                rTblUpd.nSplitLine <= nEndLnPos )
+            {
+                // bleiben in der gleichen Tabelle
+                bInNewTbl = rTblUpd.nSplitLine <= nEndLnPos &&
+                                    pTbl == rTblUpd.pTbl;
+            }
+            else
+            {
+                // das ist aufjedenfall eine ungueltige Formel, also fuers
+                // Undo auf Modified setzen
+                rTblUpd.bModified = TRUE;
+                if( pEndBox )
+                    bInNewTbl = USHRT_MAX != nEndLnPos &&
+                                    rTblUpd.nSplitLine <= nEndLnPos &&
+                                    pTbl == rTblUpd.pTbl;
+            }
+        }
+        else
+        {
+            USHORT nSttLnPos = SwTableFormula::GetLnPosInTbl( *pTbl, pSttBox );
+            // dann landet das Teil in der neuen Tabelle?
+            bInNewTbl = USHRT_MAX != nSttLnPos &&
+                            rTblUpd.nSplitLine <= nSttLnPos &&
+                            pTbl == rTblUpd.pTbl;
+        }
+
+        // wenn die Formel selbst in der neuen Tabellen landet
+        if( rTblUpd.bBehindSplitLine )
+        {
+            if( !bInNewTbl )
+            {
+                rTblUpd.bModified = TRUE;
+                ( rNewStr += rTblUpd.pTbl->GetFrmFmt()->GetName() ) += '.';
+            }
+            else if( sTblNm.Len() )
+                ( rNewStr += sTblNm ) += '.';
+        }
+        else if( bInNewTbl )
+        {
+            rTblUpd.bModified = TRUE;
+            ( rNewStr += *rTblUpd.DATA.pNewTblNm ) += '.';
+        }
+        else if( sTblNm.Len() )
+            ( rNewStr += sTblNm ) += '.';
+    }
+
+    if( pLastBox )
+        ( rNewStr += String::CreateFromInt32((long)pEndBox )) += ':';
+    ( rNewStr += String::CreateFromInt32((long)pSttBox ))
+              += rFirstBox.GetChar( rFirstBox.Len() - 1 );
+}
+
+    // erzeuge die externe Formel, beachte aber das die Formel
+    // in einer gesplitteten/gemergten Tabelle landet
+void SwTableFormula::ToSplitMergeBoxNm( SwTableFmlUpdate& rTblUpd )
+{
+    const SwTable* pTbl;
+    const SwNode* pNd = GetNodeOfFormula();
+    if( pNd && 0 != ( pNd = pNd->FindTableNode() ))
+        pTbl = &((SwTableNode*)pNd)->GetTable();
+    else
+        pTbl = rTblUpd.pTbl;
+
+    sFormel = ScanString( &SwTableFormula::_SplitMergeBoxNm, *pTbl, (void*)&rTblUpd );
+    eNmType = INTRNL_NAME;
+}
+
+
diff --git a/sw/source/core/fields/chpfld.cxx b/sw/source/core/fields/chpfld.cxx
new file mode 100644
index 000000000000..6acb68785477
--- /dev/null
+++ b/sw/source/core/fields/chpfld.cxx
@@ -0,0 +1,297 @@
+/*************************************************************************
+ *
+ *  $RCSfile: chpfld.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:19 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _FRAME_HXX
+#include         // SwChapterFieldType::ChangeExpansion()
+#endif
+#ifndef _PAM_HXX
+#include           // fuer GetBodyTxtNode
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _CHPFLD_HXX
+#include 
+#endif
+#ifndef _EXPFLD_HXX
+#include        // fuer GetBodyTxtNode
+#endif
+
+#ifndef _UNOPRNMS_HXX
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_CHAPTERFORMAT_HPP_
+#include 
+#endif
+using namespace ::com::sun::star;
+
+/*--------------------------------------------------------------------
+    Beschreibung: SwChapterFieldType
+ --------------------------------------------------------------------*/
+
+
+SwChapterFieldType::SwChapterFieldType()
+    : SwFieldType( RES_CHAPTERFLD )
+{
+}
+
+
+SwFieldType* SwChapterFieldType::Copy() const
+{
+    return new SwChapterFieldType();
+}
+
+
+/*--------------------------------------------------------------------
+    Beschreibung: Kapittelfeld
+ --------------------------------------------------------------------*/
+
+
+SwChapterField::SwChapterField(SwChapterFieldType* pTyp, sal_uInt32 nFmt)
+    : SwField(pTyp, nFmt), nLevel( 0 )
+{}
+
+
+String SwChapterField::Expand() const
+{
+    String sStr( sNumber );
+    switch( GetFormat() )
+    {
+        case CF_TITLE:      sStr = sTitle;  break;
+
+        case CF_NUMBER:
+        case CF_NUM_TITLE:  sStr.Insert( sPre, 0 );
+                            sStr += sPost;
+                            if( CF_NUM_TITLE == GetFormat() )
+                                sStr += sTitle;
+                            break;
+
+        case CF_NUM_NOPREPST_TITLE: sStr += sTitle; break;
+    }
+    return sStr;
+}
+
+
+SwField* SwChapterField::Copy() const
+{
+    SwChapterField *pTmp =
+        new SwChapterField((SwChapterFieldType*)GetTyp(), GetFormat());
+    pTmp->nLevel = nLevel;
+    pTmp->sTitle = sTitle;
+    pTmp->sNumber = sNumber;
+    pTmp->sPost = sPost;
+    pTmp->sPre = sPre;
+
+    return pTmp;
+}
+
+
+void SwChapterField::ChangeExpansion( const SwFrm* pFrm,
+                                      const SwTxtNode* pTxtNd,
+                                      sal_Bool bSrchNum )
+{
+    ASSERT( pFrm, "in welchem Frame stehe ich denn?" )
+    SwDoc* pDoc = (SwDoc*)pTxtNd->GetDoc();
+    SwPosition aPos( pDoc->GetNodes().GetEndOfContent() );
+
+    if( pFrm->IsInDocBody() )
+        aPos.nNode = *pTxtNd;
+    else if( 0 == (pTxtNd = GetBodyTxtNode( *pDoc, aPos, *pFrm )) )
+        // kein TxtNode (Formatierung Kopf/Fusszeile)
+        return;
+
+    ASSERT( pTxtNd, "Wo steht das Feld" );
+    pTxtNd = pTxtNd->FindOutlineNodeOfLevel( nLevel );
+    if( pTxtNd )
+    {
+        if( bSrchNum )
+        {
+            const SwTxtNode* pONd = pTxtNd;
+            do {
+                if( pONd && pONd->GetTxtColl() )
+                {
+                    BYTE nPrevLvl = nLevel;
+                    nLevel = GetRealLevel( pONd->GetTxtColl()->
+                                            GetOutlineLevel() );
+                    if( nPrevLvl < nLevel )
+                        nLevel = nPrevLvl;
+                    else if( SVX_NUM_NUMBER_NONE != pDoc->GetOutlineNumRule()
+                            ->Get( nLevel ).eType )
+                    {
+                        pTxtNd = pONd;
+                        break;
+                    }
+
+                    if( !nLevel-- )
+                        break;
+                    pONd = pTxtNd->FindOutlineNodeOfLevel( nLevel );
+                }
+                else
+                    break;
+            } while( sal_True );
+        }
+
+        const SwNodeNum& rNum = *pTxtNd->GetOutlineNum();
+        // nur die Nummer besorgen, ohne Pre-/Post-fixstrings
+        sNumber = pDoc->GetOutlineNumRule()->MakeNumString( rNum, sal_False );
+
+        if( NO_NUM > rNum.GetLevel() && !( NO_NUMLEVEL & rNum.GetLevel() ) )
+        {
+            const SwNumFmt& rNFmt = pDoc->GetOutlineNumRule()->Get( rNum.GetLevel() );
+            sPost = rNFmt.GetPostfix();
+            sPre = rNFmt.GetPrefix();
+        }
+        else
+            sPost = aEmptyStr, sPre = aEmptyStr;
+
+        sTitle = pTxtNd->GetExpandTxt();
+
+        for( xub_StrLen i = 0; i < sTitle.Len(); ++i )
+            if( ' ' > sTitle.GetChar( i ) )
+                sTitle.Erase( i--, 1 );
+    }
+    else
+    {
+        sNumber = aEmptyStr;
+        sTitle = aEmptyStr;
+        sPost = aEmptyStr;
+        sPre = aEmptyStr;
+    }
+}
+
+/*-----------------05.03.98 16:19-------------------
+
+--------------------------------------------------*/
+BOOL   SwChapterField::QueryValue( com::sun::star::uno::Any& rAny, const String& rProperty ) const
+{
+    if(rProperty.EqualsAscii(UNO_NAME_LEVEL))
+        rAny <<= (sal_Int8)nLevel;
+    else if(rProperty.EqualsAscii(UNO_NAME_CHAPTER_FORMAT))
+    {
+        sal_Int16 nRet;
+        switch( GetFormat() )
+        {
+            case CF_NUMBER: nRet = text::ChapterFormat::NUMBER; break;
+            case CF_TITLE:  nRet = text::ChapterFormat::NAME; break;
+            case CF_NUMBER_NOPREPST:
+                nRet = text::ChapterFormat::DIGIT;
+            break;
+            case CF_NUM_NOPREPST_TITLE:
+                nRet = text::ChapterFormat::NO_PREFIX_SUFFIX;
+            break;
+            case CF_NUM_TITLE:
+            default:        nRet = text::ChapterFormat::NAME_NUMBER;
+        }
+        rAny <<= nRet;
+    }
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return sal_True;
+}
+/*-----------------05.03.98 16:19-------------------
+
+--------------------------------------------------*/
+BOOL    SwChapterField::PutValue( const com::sun::star::uno::Any& rAny, const String& rProperty )
+{
+    if(rProperty.EqualsAscii(UNO_NAME_LEVEL))
+    {
+        sal_Int8 nTmp;
+        rAny >>= nTmp;
+        if(nTmp >= 0 && nTmp < MAXLEVEL)
+            nLevel = nTmp;
+        else
+            return FALSE;
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_CHAPTER_FORMAT))
+    {
+        sal_Int16 nVal;
+        rAny >>= nVal;
+        switch( nVal )
+        {
+            case text::ChapterFormat::NAME: SetFormat(CF_TITLE); break;
+            case text::ChapterFormat::NUMBER:  SetFormat(CF_NUMBER); break;
+            case text::ChapterFormat::NO_PREFIX_SUFFIX:
+                        SetFormat(CF_NUM_NOPREPST_TITLE);
+            break;
+            case text::ChapterFormat::DIGIT:
+                    SetFormat(CF_NUMBER_NOPREPST);
+            break;
+            //case text::ChapterFormat::NAME_NUMBER:
+            default:        SetFormat(CF_NUM_TITLE);
+        }
+    }
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return sal_True;
+}
diff --git a/sw/source/core/fields/dbfld.cxx b/sw/source/core/fields/dbfld.cxx
new file mode 100644
index 000000000000..fe65ce0e423e
--- /dev/null
+++ b/sw/source/core/fields/dbfld.cxx
@@ -0,0 +1,1112 @@
+/*************************************************************************
+ *
+ *  $RCSfile: dbfld.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:19 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include 
+
+#ifndef _SFXAPP_HXX //autogen
+#include 
+#endif
+#ifndef _ZFORLIST_HXX //autogen
+#include 
+#endif
+#ifndef _UNOPRNMS_HXX
+#include 
+#endif
+#ifndef _SVX_PAGEITEM_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFLD_HXX
+#include 
+#endif
+#ifndef _TXTFLD_HXX
+#include 
+#endif
+
+#include "doc.hxx"
+#include "docary.hxx"
+#include "frame.hxx"
+#include "fldbas.hxx"
+#include "pam.hxx"
+#include "ndtxt.hxx"
+#include "dbfld.hxx"
+#include "dbmgr.hxx"
+#include "docfld.hxx"
+#include "expfld.hxx"
+#include "txtatr.hxx"
+
+#ifdef REPLACE_OFADBMGR
+#ifndef _COM_SUN_STAR_SDBC_DATATYPE_HPP_
+#include 
+#endif
+
+using namespace ::com::sun::star::sdbc;
+#endif
+
+using namespace ::com::sun::star;
+using namespace ::rtl;
+
+/*--------------------------------------------------------------------
+    Beschreibung: Datenbanktrenner durch Punkte fuer Anzeige ersetzen
+ --------------------------------------------------------------------*/
+
+String lcl_DBTrennConv(const String& aContent)
+{
+    String sTmp(aContent);
+    sal_Unicode* pStr = sTmp.GetBufferAccess();
+    for( USHORT i = sTmp.Len(); i; --i, ++pStr )
+        if( DB_DELIM == *pStr )
+            *pStr = '.';
+    return sTmp;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: DatenbankFeldTyp
+ --------------------------------------------------------------------*/
+
+SwDBFieldType::SwDBFieldType(SwDoc* pDocPtr, const String& rNam, const String& rDBNam ) :
+    SwValueFieldType( pDocPtr, RES_DBFLD ),
+    nRefCnt(0),
+    aName(rNam)
+{
+    if (rDBNam.Len())
+    {
+        String sNewName(rDBNam);// Datenbankname muss nicht unbedingt in rNam enthalten sein!
+        if (rDBNam.Len())
+            sNewName += DB_DELIM;
+        sNewName += GetColumnName();
+        aName = sNewName;
+    }
+    else    // Entweder kein Datenbankname, oder er ist in rNam bereits enthalten
+        aName = rNam;
+}
+
+//------------------------------------------------------------------------------
+
+SwFieldType* SwDBFieldType::Copy() const
+{
+    SwDBFieldType* pTmp = new SwDBFieldType(GetDoc(), aName, aEmptyStr);
+    return pTmp;
+}
+
+//------------------------------------------------------------------------------
+
+const String& SwDBFieldType::GetName() const
+{
+    return aName;
+}
+
+//------------------------------------------------------------------------------
+
+String SwDBFieldType::GetColumnName()
+{
+    USHORT nPos = aName.Len();
+
+    // Letztes Token zuruekliefern
+    while( nPos )
+        if( DB_DELIM == (BYTE)aName.GetChar( --nPos )  )
+        {
+            ++nPos;
+            break;
+        }
+
+    return aName.Copy( nPos );
+}
+
+//------------------------------------------------------------------------------
+
+String SwDBFieldType::GetDBName()
+{
+    USHORT nPos;
+
+    if ((nPos = aName.Search(DB_DELIM)) != STRING_NOTFOUND)
+    {
+        if ((nPos = aName.Search(DB_DELIM, nPos + 1)) != STRING_NOTFOUND)
+            return aName.Copy(0, nPos);
+    }
+    return aEmptyStr;
+}
+
+//------------------------------------------------------------------------------
+
+void SwDBFieldType::ReleaseRef()
+{
+    ASSERT(nRefCnt > 0, "RefCount kleiner 0!");
+
+    if (--nRefCnt <= 0)
+    {
+        USHORT nPos = GetDoc()->GetFldTypes()->GetPos(this);
+
+        if (nPos != USHRT_MAX)
+        {
+            GetDoc()->RemoveFldType(nPos);
+            delete this;
+        }
+    }
+}
+
+/* -----------------24.02.99 14:51-------------------
+ *
+ * --------------------------------------------------*/
+BOOL    SwDBFieldType::QueryValue( com::sun::star::uno::Any& rAny, const String& rProperty ) const
+{
+    USHORT nToken = USHRT_MAX;
+    if(rProperty.EqualsAscii(UNO_NAME_DATA_BASE_NAME     ))
+        nToken = 0;
+    else if(rProperty.EqualsAscii(UNO_NAME_DATA_TABLE_NAME))
+        nToken = 1;
+    else if(rProperty.EqualsAscii(UNO_NAME_DATA_COLUMN_NAME))
+        nToken = 2;
+    if(nToken != USHRT_MAX)
+    {
+        String sRet = aName.GetToken(nToken, DB_DELIM);
+        rAny <<= OUString(sRet);
+    }
+    return nToken != USHRT_MAX;
+}
+
+BOOL    SwDBFieldType::PutValue( const com::sun::star::uno::Any& rAny, const String& rProperty )
+{
+    USHORT nToken = USHRT_MAX;
+    BOOL bReInitClients = FALSE;
+    if(rProperty.EqualsAscii(UNO_NAME_DATA_BASE_NAME     ))
+        nToken = 0;
+    else if(rProperty.EqualsAscii(UNO_NAME_DATA_TABLE_NAME))
+        nToken = 1;
+    else if(rProperty.EqualsAscii(UNO_NAME_DATA_COLUMN_NAME))
+    {
+        nToken = 2;
+        bReInitClients = TRUE;
+    }
+    if(nToken != USHRT_MAX)
+    {
+        const String sOld = aName.GetToken(nToken, DB_DELIM);
+
+        OUString sSet;
+        rAny >>= sSet;
+        aName.SetToken(nToken, DB_DELIM, sSet);
+        if(bReInitClients && !sOld.Equals(String(sSet)))
+        {
+            SwClientIter aIter( *this );
+            SwFmtFld* pFld = (SwFmtFld*)aIter.First( TYPE( SwFmtFld ));
+            while(pFld)
+            {
+                // Feld im Undo?
+                SwTxtFld *pTxtFld = pFld->GetTxtFld();
+                if(pTxtFld && pTxtFld->GetTxtNode().GetNodes().IsDocNodes() )
+                {
+                    SwDBField* pDBField = (SwDBField*)pFld->GetFld();
+                    pDBField->ClearInitialized();
+                    pDBField->InitContent();
+
+                }
+                pFld = (SwFmtFld*)aIter.Next();
+            }
+        }
+    }
+    return nToken != USHRT_MAX;
+}
+/*--------------------------------------------------------------------
+    Beschreibung: SwDBField
+ --------------------------------------------------------------------*/
+
+SwDBField::SwDBField(SwDBFieldType* pTyp, ULONG nFmt)
+    :   SwValueField(pTyp, nFmt),
+        bValidValue(FALSE),
+        bIsInBodyTxt(TRUE),
+        bInitialized(FALSE),
+        nSubType(0)
+{
+    if (GetTyp())
+        ((SwDBFieldType*)GetTyp())->AddRef();
+    InitContent();
+}
+
+//------------------------------------------------------------------------------
+
+SwDBField::~SwDBField()
+{
+    if (GetTyp())
+        ((SwDBFieldType*)GetTyp())->ReleaseRef();
+}
+
+//------------------------------------------------------------------------------
+
+void SwDBField::InitContent()
+{
+    if (!IsInitialized())
+    {
+        aContent = '<';
+        aContent += ((SwDBFieldType*)GetTyp())->GetColumnName();
+        aContent += '>';
+    }
+}
+
+//------------------------------------------------------------------------------
+
+void SwDBField::InitContent(const String& rExpansion)
+{
+    if (rExpansion.Len() > 2)
+    {
+        if (rExpansion.GetChar(0) == '<' &&
+            rExpansion.GetChar(rExpansion.Len() - 1) == '>')
+        {
+            String sColumn(rExpansion.Copy(1, rExpansion.Len() - 2));
+            const International rInt = Application::GetAppInternational();
+            if( rInt.CompareEqual(  sColumn,
+                                    ((SwDBFieldType *)GetTyp())->GetColumnName(),
+                                    INTN_COMPARE_IGNORECASE))
+            {
+                InitContent();
+                return;
+            }
+        }
+    }
+    SetExpansion( rExpansion );
+}
+
+//------------------------------------------------------------------------------
+
+String SwDBField::GetOldContent()
+{
+    String sOldExpand = Expand();
+    String sNewExpand = sOldExpand;
+    BOOL bOldInit = bInitialized;
+
+    bInitialized = FALSE;
+    InitContent();
+    bInitialized = bOldInit;
+
+    const International rInt = Application::GetAppInternational();
+
+    if( rInt.CompareEqual(  sNewExpand, Expand(), INTN_COMPARE_IGNORECASE))
+    {
+        sNewExpand = '<';
+        sNewExpand += ((SwDBFieldType *)GetTyp())->GetColumnName();
+        sNewExpand += '>';
+    }
+    SetExpansion( sOldExpand );
+
+    return sNewExpand;
+}
+
+//------------------------------------------------------------------------------
+
+String SwDBField::Expand() const
+{
+    return lcl_DBTrennConv(aContent);
+}
+
+//------------------------------------------------------------------------------
+
+SwField* SwDBField::Copy() const
+{
+    SwDBField *pTmp = new SwDBField((SwDBFieldType*)GetTyp(), GetFormat());
+    pTmp->aContent      = aContent;
+    pTmp->bIsInBodyTxt  = bIsInBodyTxt;
+    pTmp->bValidValue   = bValidValue;
+    pTmp->bInitialized  = bInitialized;
+    pTmp->nSubType      = nSubType;
+    pTmp->SetValue(GetValue());
+
+    return pTmp;
+}
+
+String SwDBField::GetCntnt(BOOL bName) const
+{
+    if(bName)
+    {
+        const String& rDBName = ((SwDBFieldType*)GetTyp())->GetName();
+        String sContent( SFX_APP()->LocalizeDBName(INI2NATIONAL,
+                                            rDBName.GetToken(0, DB_DELIM)));
+
+        if (sContent.Len() > 1)
+        {
+            sContent += DB_DELIM;
+            sContent += rDBName.GetToken(1, DB_DELIM);
+            sContent += DB_DELIM;
+            sContent += rDBName.GetToken(2, DB_DELIM);
+        }
+        return lcl_DBTrennConv(sContent);
+    }
+    return Expand();
+}
+
+//------------------------------------------------------------------------------
+
+void SwDBField::ChgValue( double d, BOOL bVal )
+{
+    bValidValue = bVal;
+    SetValue(d);
+
+    if( bValidValue )
+        aContent = ((SwValueFieldType*)GetTyp())->ExpandValue(d, GetFormat(), GetLanguage());
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung:
+ --------------------------------------------------------------------*/
+
+SwFieldType* SwDBField::ChgTyp( SwFieldType* pNewType )
+{
+    SwFieldType* pOld = SwValueField::ChgTyp( pNewType );
+
+    ((SwDBFieldType*)pNewType)->AddRef();
+    ((SwDBFieldType*)pOld)->ReleaseRef();
+
+    return pOld;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Aktuellen Field-Value holen und chachen
+ --------------------------------------------------------------------*/
+
+void SwDBField::Evaluate()
+{
+    SwNewDBMgr* pMgr = GetDoc()->GetNewDBMgr();
+
+    // erstmal loeschen
+    bValidValue = FALSE;
+    double nValue = DBL_MAX;
+    String sTmpName(GetDBName());
+
+#ifdef REPLACE_OFADBMGR
+    String sDataSource(sTmpName.GetToken(0, DB_DELIM));
+    String sDataTableOrQuery(sTmpName.GetToken(1, DB_DELIM));
+    if(!pMgr || !pMgr->IsDataSourceOpen(sDataSource, sDataTableOrQuery))
+        return ;
+#else
+    if(!pMgr || !pMgr->IsDBOpen(DBMGR_STD, sTmpName) || !pMgr->IsInMerge())
+    {
+        return;
+    }
+#endif
+
+    ULONG nFmt;
+
+    // Passenden Spaltennamen suchen
+    String aColNm( ((SwDBFieldType*)GetTyp())->GetColumnName() );
+
+    SvNumberFormatter* pDocFormatter = GetDoc()->GetNumberFormatter();
+#ifdef REPLACE_OFADBMGR
+    pMgr->GetMergeColumnCnt(aColNm, GetLanguage(), aContent, &nValue, &nFmt);
+    if( !( nSubType & SUB_OWN_FMT ) )
+        SetFormat( nFmt = pMgr->GetColumnFmt( sDataSource, sDataTableOrQuery,
+                                        aContent, pDocFormatter, GetLanguage() ));
+#else
+    pMgr->GetColumnCnt( DBMGR_STD, aColNm,
+                            pMgr->GetCurRecordId( DBMGR_STD ), aContent,
+                            &nValue, &nFmt );
+    if( !( nSubType & SUB_OWN_FMT ) )
+        SetFormat( nFmt = pMgr->GetRealColumnFmt( aColNm, nFmt,
+                                        *pDocFormatter ) );
+#endif
+
+    if( DBL_MAX != nValue )
+    {
+#ifdef REPLACE_OFADBMGR
+        sal_Int32 nColumnType = pMgr->GetColumnType(sDataSource, sDataTableOrQuery, aContent);
+        if( DataType::DATE == nColumnType  || DataType::TIME == nColumnType  ||
+                 DataType::TIMESTAMP )
+
+#else
+        int nColumnPos = pMgr->GetColumnPos(FALSE, aColNm);
+        String  sColumnType = pMgr->GetColumnType(FALSE, nColumnPos, FALSE);
+        if(sColumnType.EqualsAscii("DATE/TIME") || sColumnType.EqualsAscii("DATE"))
+#endif
+        {
+            Date aStandard(1,1,1900);
+            if (*pDocFormatter->GetNullDate() != aStandard)
+                nValue += (aStandard - *pDocFormatter->GetNullDate());
+        }
+        bValidValue = TRUE;
+        SetValue(nValue);
+        aContent = ((SwValueFieldType*)GetTyp())->ExpandValue(nValue, GetFormat(), GetLanguage());
+    }
+    else
+    {
+        SwSbxValue aVal;
+        aVal.PutString( aContent );
+
+        if (aVal.IsNumeric())
+        {
+            SetValue(aVal.GetDouble());
+
+            SvNumberFormatter* pFormatter = GetDoc()->GetNumberFormatter();
+            if (nFmt && nFmt != ULONG_MAX && !pFormatter->IsTextFormat(nFmt))
+                bValidValue = TRUE; // Wegen Bug #60339 nicht mehr bei allen Strings
+        }
+        else
+        {
+            // Bei Strings TRUE wenn Laenge > 0 sonst FALSE
+            SetValue(aContent.Len() ? 1 : 0);
+        }
+    }
+    bInitialized = TRUE;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Namen erfragen
+ --------------------------------------------------------------------*/
+
+const String& SwDBField::GetPar1() const
+{
+    return ((SwDBFieldType*)GetTyp())->GetName();
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung:
+ --------------------------------------------------------------------*/
+
+USHORT SwDBField::GetSubType() const
+{
+    return nSubType;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung:
+ --------------------------------------------------------------------*/
+
+void SwDBField::SetSubType(USHORT nType)
+{
+    nSubType = nType;
+}
+
+/*-----------------06.03.98 16:15-------------------
+
+--------------------------------------------------*/
+BOOL SwDBField::QueryValue( com::sun::star::uno::Any& rAny, const String& rProperty ) const
+{
+    if(rProperty.EqualsAscii(UNO_NAME_IS_DATA_BASE_FORMAT))
+    {
+        BOOL bTemp = 0 == (GetSubType()&SUB_OWN_FMT);
+        rAny.setValue(&bTemp, ::getBooleanCppuType());
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_NUMBER_FORMAT))
+        rAny <<= (sal_Int32)GetFormat();
+    else if(rProperty.EqualsAscii(UNO_NAME_CONTENT)||
+        rProperty.EqualsAscii(UNO_NAME_CURRENT_PRESENTATION))
+        rAny <<= OUString(aContent);
+#ifdef   DBG_UTIL
+    else
+        DBG_ERROR("Was war das fuer ein Typ?")
+#endif
+    return TRUE;
+
+}
+/*-----------------06.03.98 16:15-------------------
+
+--------------------------------------------------*/
+BOOL SwDBField::PutValue( const com::sun::star::uno::Any& rAny, const String& rProperty )
+{
+    if(rProperty.EqualsAscii(UNO_NAME_IS_DATA_BASE_FORMAT))
+    {
+        sal_Bool bTemp = *(sal_Bool*)rAny.getValue();
+        if(bTemp)
+            SetSubType(GetSubType()&~SUB_OWN_FMT);
+        else
+            SetSubType(GetSubType()|SUB_OWN_FMT);
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_NUMBER_FORMAT))
+    {
+        sal_Int32 nTemp;
+        rAny >>= nTemp;
+        SetFormat(nTemp);
+    }
+    else if( rProperty.EqualsAscii( UNO_NAME_CONTENT )||
+        rProperty.EqualsAscii(UNO_NAME_CURRENT_PRESENTATION))
+    {
+        OUString uTmp;
+        rAny >>= uTmp;
+        aContent = uTmp;
+    }
+#ifdef   DBG_UTIL
+    else
+        DBG_ERROR("Was war das fuer ein Typ?")
+#endif
+    return TRUE;
+
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Basisklasse fuer alle weiteren Datenbankfelder
+ --------------------------------------------------------------------*/
+
+SwDBNameInfField::SwDBNameInfField(SwFieldType* pTyp, const String& rDBName, ULONG nFmt) :
+    SwField(pTyp, nFmt),
+    sDBName(rDBName)
+{
+}
+
+//------------------------------------------------------------------------------
+
+String SwDBNameInfField::GetDBName(SwDoc* pDoc)
+{
+    String sTmp;
+    if (sDBName.Len())
+        sTmp=sDBName;
+    else
+        sTmp=pDoc->GetDBName();
+    return (sTmp);
+}
+
+//------------------------------------------------------------------------------
+
+String SwDBNameInfField::GetCntnt(BOOL bName) const
+{
+    String sStr(SwField::GetCntnt(bName));
+
+    if(bName)
+    {
+        if (sDBName.Len())
+        {
+            sStr += ':';
+            sStr += SFX_APP()->LocalizeDBName(INI2NATIONAL, sDBName.GetToken(0, DB_DELIM));
+            sStr += DB_DELIM;
+            sStr += sDBName.GetToken(1, DB_DELIM);
+        }
+    }
+    return lcl_DBTrennConv(sStr);
+}
+
+/*-----------------06.03.98 16:55-------------------
+
+--------------------------------------------------*/
+BOOL SwDBNameInfField::QueryValue( com::sun::star::uno::Any& rAny, const String& rProperty ) const
+{
+    if(rProperty.EqualsAscii(UNO_NAME_DATA_BASE_NAME))
+    {
+        rAny <<= OUString(sDBName.GetToken(0, DB_DELIM));
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_DATA_TABLE_NAME))
+    {
+        rAny <<= OUString(sDBName.GetToken(1, DB_DELIM));
+    }
+    else
+    {
+        DBG_ERROR("was war das fuer ein Typ?")
+        return FALSE;
+    }
+    return TRUE;
+}
+/*-----------------06.03.98 16:55-------------------
+
+--------------------------------------------------*/
+BOOL    SwDBNameInfField::PutValue( const com::sun::star::uno::Any& rAny, const String& rProperty )
+{
+    OUString uTemp;
+    if(rProperty.EqualsAscii(UNO_NAME_DATA_BASE_NAME))
+    {
+        rAny >>= uTemp;
+        sDBName.SetToken(0, DB_DELIM, uTemp);
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_DATA_TABLE_NAME))
+    {
+        rAny >>= uTemp;
+        sDBName.SetToken(1, DB_DELIM, uTemp);
+    }
+    else
+        return FALSE;
+    return TRUE;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: NaechsterDatensatz
+ --------------------------------------------------------------------*/
+
+SwDBNextSetFieldType::SwDBNextSetFieldType()
+    : SwFieldType( RES_DBNEXTSETFLD )
+{
+}
+
+//------------------------------------------------------------------------------
+
+SwFieldType* SwDBNextSetFieldType::Copy() const
+{
+    SwDBNextSetFieldType* pTmp = new SwDBNextSetFieldType();
+    return pTmp;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: SwDBSetField
+ --------------------------------------------------------------------*/
+
+SwDBNextSetField::SwDBNextSetField(SwDBNextSetFieldType* pTyp,
+                                   const String& rCond,
+                                   const String& rDummy,
+                                   const String& rDBName) :
+    SwDBNameInfField(pTyp, rDBName), aCond(rCond), bCondValid(TRUE)
+{}
+
+//------------------------------------------------------------------------------
+
+String SwDBNextSetField::Expand() const
+{
+    return aEmptyStr;
+}
+
+//------------------------------------------------------------------------------
+
+SwField* SwDBNextSetField::Copy() const
+{
+    SwDBNextSetField *pTmp = new SwDBNextSetField((SwDBNextSetFieldType*)GetTyp(),
+                                         aCond, aEmptyStr, GetDBName());
+    pTmp->bCondValid = bCondValid;
+    return pTmp;
+}
+//------------------------------------------------------------------------------
+
+void SwDBNextSetField::Evaluate(SwDoc* pDoc)
+{
+#ifdef REPLACE_OFADBMGR
+    SwNewDBMgr* pMgr = pDoc->GetNewDBMgr();
+    String sTmpName(GetDBName());
+    String sDataSource(sTmpName.GetToken(0, DB_DELIM));
+    String sDataTableOrQuery(sTmpName.GetToken(1, DB_DELIM));
+    if( !bCondValid ||
+            !pMgr || !pMgr->IsDataSourceOpen(sDataSource, sDataTableOrQuery))
+        return ;
+    pMgr->ToNextMergeRecord();
+#else
+    if( bCondValid && pDoc->GetNewDBMgr() &&
+                        pDoc->GetNewDBMgr()->IsDBOpen(DBMGR_STD, GetDBName()) )
+    {
+        // Bedingung OK -> naechste selektierter Record ist der aktuelle
+        pDoc->GetNewDBMgr()->ToNextSelectedRecord(DBMGR_STD);
+    }
+#endif
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Bedingung
+ --------------------------------------------------------------------*/
+
+const String& SwDBNextSetField::GetPar1() const
+{
+    return aCond;
+}
+
+void SwDBNextSetField::SetPar1(const String& rStr)
+{
+    aCond = rStr;
+}
+/*-----------------06.03.98 16:16-------------------
+
+--------------------------------------------------*/
+BOOL SwDBNextSetField::QueryValue( uno::Any& rAny, const String& rProperty ) const
+{
+    if(rProperty.EqualsAscii(UNO_NAME_CONDITION))
+        rAny <<= OUString(aCond);
+    else
+        return SwDBNameInfField::QueryValue(rAny, rProperty);
+    return TRUE;
+}
+/*-----------------06.03.98 16:16-------------------
+
+--------------------------------------------------*/
+BOOL    SwDBNextSetField::PutValue( const com::sun::star::uno::Any& rAny, const String& rProperty )
+{
+    if(rProperty.EqualsAscii(UNO_NAME_CONDITION))
+    {
+        OUString uTemp;
+        rAny >>= uTemp;
+        aCond = String(uTemp);
+    }
+    else
+        return SwDBNameInfField::PutValue(rAny, rProperty);
+    return TRUE;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung:
+ --------------------------------------------------------------------*/
+/*
+String SwDBNextSetField::GetPar2() const
+{
+    return GetDBName();
+}
+
+void SwDBNextSetField::SetPar2(const String& rStr)
+{
+    GetDBName() = rStr;
+}
+*/
+
+/*--------------------------------------------------------------------
+    Beschreibung: Datensatz mit bestimmter ID
+ --------------------------------------------------------------------*/
+
+SwDBNumSetFieldType::SwDBNumSetFieldType() :
+    SwFieldType( RES_DBNUMSETFLD )
+{
+}
+
+//------------------------------------------------------------------------------
+
+SwFieldType* SwDBNumSetFieldType::Copy() const
+{
+    SwDBNumSetFieldType* pTmp = new SwDBNumSetFieldType();
+    return pTmp;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: SwDBSetField
+ --------------------------------------------------------------------*/
+
+SwDBNumSetField::SwDBNumSetField(SwDBNumSetFieldType* pTyp,
+                                 const String& rCond,
+                                 const String& rDBNum,
+                                 const String& rDBName) :
+    SwDBNameInfField(pTyp, rDBName),
+    aCond(rCond),
+    aPar2(rDBNum),
+    bCondValid(TRUE)
+{}
+
+//------------------------------------------------------------------------------
+
+String SwDBNumSetField::Expand() const
+{
+    return aEmptyStr;
+}
+
+//------------------------------------------------------------------------------
+
+SwField* SwDBNumSetField::Copy() const
+{
+    SwDBNumSetField *pTmp = new SwDBNumSetField((SwDBNumSetFieldType*)GetTyp(),
+                                         aCond, aPar2, GetDBName());
+    pTmp->bCondValid = bCondValid;
+    return pTmp;
+}
+
+void SwDBNumSetField::Evaluate(SwDoc* pDoc)
+{
+    SwNewDBMgr* pMgr = pDoc->GetNewDBMgr();
+#ifdef REPLACE_OFADBMGR
+    String sTmpName(GetDBName());
+    String sDataSource(sTmpName.GetToken(0, DB_DELIM));
+    String sDataTableOrQuery(sTmpName.GetToken(1, DB_DELIM));
+    if( bCondValid && pMgr && pMgr->IsInMerge() &&
+                        pMgr->IsDataSourceOpen(sDataSource, sDataTableOrQuery))
+    {   // Bedingug OK -> aktuellen Set einstellen
+        pMgr->ToRecordId(Max((USHORT)aPar2.ToInt32(), USHORT(1))-1);
+    }
+#else
+    if( bCondValid && pMgr && pMgr->IsDBOpen(DBMGR_STD, GetDBName())
+                                                && pMgr->IsInMerge() )
+    {   // Bedingug OK -> aktuellen Set einstellen
+        pMgr->ToSelectedRecord(DBMGR_STD, Max((USHORT)aPar2.ToInt32(), USHORT(1))-1);
+    }
+#endif
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: LogDBName
+ --------------------------------------------------------------------*/
+
+const String& SwDBNumSetField::GetPar1() const
+{
+    return aCond;
+}
+
+void SwDBNumSetField::SetPar1(const String& rStr)
+{
+    aCond = rStr;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Bedingung
+ --------------------------------------------------------------------*/
+
+String SwDBNumSetField::GetPar2() const
+{
+    return aPar2;
+}
+
+void SwDBNumSetField::SetPar2(const String& rStr)
+{
+    aPar2 = rStr;
+}
+/*-----------------06.03.98 16:16-------------------
+
+--------------------------------------------------*/
+BOOL SwDBNumSetField::QueryValue( com::sun::star::uno::Any& rAny, const String& rProperty ) const
+{
+    if(rProperty.EqualsAscii(UNO_NAME_SET_NUMBER))
+        rAny <<= (sal_Int32)aPar2.ToInt32();
+    else if(rProperty.EqualsAscii(UNO_NAME_CONDITION))
+        rAny <<= OUString(aCond);
+    else
+        return SwDBNameInfField::QueryValue(rAny, rProperty);
+    return TRUE;
+}
+/*-----------------06.03.98 16:16-------------------
+
+--------------------------------------------------*/
+BOOL    SwDBNumSetField::PutValue( const com::sun::star::uno::Any& rAny, const String& rProperty )
+{
+    if(rProperty.EqualsAscii(UNO_NAME_SET_NUMBER))
+    {
+        sal_Int32 nVal;
+        rAny >>= nVal;
+        aPar2 = String::CreateFromInt32(nVal);
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_CONDITION))
+    {
+        OUString uTemp;
+        rAny >>= uTemp;
+        aCond = String(uTemp);
+    }
+    else
+        return SwDBNameInfField::PutValue(rAny, rProperty);
+    return TRUE;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: SwDBNameFieldType
+ --------------------------------------------------------------------*/
+
+SwDBNameFieldType::SwDBNameFieldType(SwDoc* pDocument)
+    : SwFieldType( RES_DBNAMEFLD )
+{
+    pDoc = pDocument;
+}
+//------------------------------------------------------------------------------
+
+String SwDBNameFieldType::Expand(ULONG nFmt) const
+{
+    ASSERT( nFmt >= FF_BEGIN && nFmt < FF_END, "Expand: kein guelt. Fmt!" );
+
+    return(pDoc->GetDBName());
+}
+//------------------------------------------------------------------------------
+
+SwFieldType* SwDBNameFieldType::Copy() const
+{
+    SwDBNameFieldType *pTmp = new SwDBNameFieldType(pDoc);
+    return pTmp;
+}
+
+//------------------------------------------------------------------------------
+
+/*--------------------------------------------------------------------
+    Beschreibung: Name der angedockten DB
+ --------------------------------------------------------------------*/
+
+SwDBNameField::SwDBNameField(SwDBNameFieldType* pTyp, const String& rDBName, ULONG nFmt)
+    : SwDBNameInfField(pTyp, rDBName, nFmt)
+{}
+
+//------------------------------------------------------------------------------
+
+String SwDBNameField::Expand() const
+{
+    return((SwDBNameFieldType*)GetTyp())->Expand(GetFormat());
+}
+
+//------------------------------------------------------------------------------
+
+SwField* SwDBNameField::Copy() const
+{
+    SwDBNameField *pTmp = new SwDBNameField((SwDBNameFieldType*)GetTyp(), GetDBName());
+    pTmp->ChangeFormat(GetFormat());
+    pTmp->SetLanguage(GetLanguage());
+    return pTmp;
+}
+
+/*-----------------06.03.98 16:16-------------------
+
+--------------------------------------------------*/
+BOOL SwDBNameField::QueryValue( com::sun::star::uno::Any& rAny, const String& rProperty ) const
+{
+    return SwDBNameInfField::QueryValue(rAny, rProperty);
+}
+/*-----------------06.03.98 16:16-------------------
+
+--------------------------------------------------*/
+BOOL    SwDBNameField::PutValue( const com::sun::star::uno::Any& rAny, const String& rProperty )
+{
+    return SwDBNameInfField::PutValue(rAny, rProperty);
+}
+/*--------------------------------------------------------------------
+    Beschreibung: SwDBNameFieldType
+ --------------------------------------------------------------------*/
+
+SwDBSetNumberFieldType::SwDBSetNumberFieldType()
+    : SwFieldType( RES_DBSETNUMBERFLD )
+{
+}
+
+//------------------------------------------------------------------------------
+
+SwFieldType* SwDBSetNumberFieldType::Copy() const
+{
+    SwDBSetNumberFieldType *pTmp = new SwDBSetNumberFieldType;
+    return pTmp;
+}
+
+//------------------------------------------------------------------------------
+
+/*--------------------------------------------------------------------
+    Beschreibung: SetNumber der angedockten DB
+ --------------------------------------------------------------------*/
+
+SwDBSetNumberField::SwDBSetNumberField(SwDBSetNumberFieldType* pTyp,
+                                       const String& rDBName,
+                                       ULONG nFmt)
+    : SwDBNameInfField(pTyp, rDBName, nFmt), nNumber(0)
+{}
+
+//------------------------------------------------------------------------------
+
+String SwDBSetNumberField::Expand() const
+{
+    if (nNumber == 0)
+        return aEmptyStr;
+    else
+        return FormatNumber((USHORT)nNumber, GetFormat());
+    //return(nNumber == 0 ? aEmptyStr : FormatNumber(nNumber, GetFormat()));
+}
+
+//------------------------------------------------------------------------------
+
+void SwDBSetNumberField::Evaluate(SwDoc* pDoc)
+{
+    SwNewDBMgr* pMgr = pDoc->GetNewDBMgr();
+
+    if (!pMgr->IsInMerge())
+        return;
+
+#ifdef REPLACE_OFADBMGR
+    String sTmpName(GetDBName());
+    String sDataSource(sTmpName.GetToken(0, DB_DELIM));
+    String sDataTableOrQuery(sTmpName.GetToken(1, DB_DELIM));
+    if(!pMgr || !pMgr->IsDataSourceOpen(sDataSource, sDataTableOrQuery))
+    {
+        nNumber = 0;
+        return ;
+    }
+    nNumber = pMgr->GetSelectedRecordId() + 1;
+#else
+    if(!(pMgr && pMgr->IsDBOpen(DBMGR_STD, GetDBName())))
+    {
+        nNumber = 0;
+        return;
+    }
+    nNumber = pMgr->GetCurSelectedRecordId(DBMGR_STD) + 1;
+#endif
+}
+
+
+//------------------------------------------------------------------------------
+
+SwField* SwDBSetNumberField::Copy() const
+{
+    SwDBSetNumberField *pTmp =
+        new SwDBSetNumberField((SwDBSetNumberFieldType*)GetTyp(), GetDBName(), GetFormat());
+    pTmp->SetLanguage(GetLanguage());
+    pTmp->SetSetNumber(nNumber);
+    return pTmp;
+}
+/*-----------------06.03.98 16:15-------------------
+
+--------------------------------------------------*/
+BOOL SwDBSetNumberField::QueryValue( com::sun::star::uno::Any& rAny, const String& rProperty ) const
+{
+    if(rProperty.EqualsAscii(UNO_NAME_NUMBERING_TYPE))
+    {
+        rAny <<= (sal_Int16)GetFormat();
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_SET_NUMBER))
+        rAny <<= nNumber;
+    else
+        return SwDBNameInfField::QueryValue(rAny, rProperty);
+    return TRUE;
+}
+/*-----------------06.03.98 16:15-------------------
+
+--------------------------------------------------*/
+BOOL    SwDBSetNumberField::PutValue( const com::sun::star::uno::Any& rAny, const String& rProperty )
+{
+    if(rProperty.EqualsAscii(UNO_NAME_NUMBERING_TYPE))
+    {
+        sal_Int16 nSet;
+        rAny >>= nSet;
+        if(nSet < (INT16) SVX_NUMBER_NONE )
+            SetFormat(nSet);
+        else
+            //exception(wrong_value)
+            ;
+    }
+    if(rProperty.EqualsAscii(UNO_NAME_SET_NUMBER))
+        rAny >>= nNumber;
+    else
+        return SwDBNameInfField::PutValue(rAny, rProperty);
+    return TRUE;
+}
+
+
diff --git a/sw/source/core/fields/ddefld.cxx b/sw/source/core/fields/ddefld.cxx
new file mode 100644
index 000000000000..bf4f7b91b164
--- /dev/null
+++ b/sw/source/core/fields/ddefld.cxx
@@ -0,0 +1,494 @@
+/*************************************************************************
+ *
+ *  $RCSfile: ddefld.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:19 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _LINKNAME_HXX //autogen
+#include 
+#endif
+#ifndef _SVXLINKMGR_HXX
+#include 
+#endif
+
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _EDITSH_HXX
+#include 
+#endif
+#ifndef _ERRHDL_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _HINTS_HXX
+#include 
+#endif
+#ifndef _FMTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _DDEFLD_HXX
+#include 
+#endif
+#ifndef _SWTABLE_HXX
+#include 
+#endif
+#ifndef _SWBASLNK_HXX
+#include 
+#endif
+#ifndef _SWDDETBL_HXX
+#include 
+#endif
+#ifndef _UNOPRNMS_HXX
+#include 
+#endif
+
+using namespace rtl;
+/*--------------------------------------------------------------------
+    Beschreibung: Globale Variablen
+ --------------------------------------------------------------------*/
+
+class SwIntrnlRefLink : public SwBaseLink
+{
+    SwDDEFieldType& rFldType;
+public:
+    SwIntrnlRefLink( SwDDEFieldType& rType, USHORT nUpdateType, USHORT nFmt )
+        : SwBaseLink( nUpdateType, nFmt ),
+        rFldType( rType )
+    {}
+
+    virtual void Closed();
+    virtual void DataChanged( SvData& );
+
+    virtual const SwNode* GetAnchor() const;
+    virtual BOOL IsInRange( ULONG nSttNd, ULONG nEndNd, xub_StrLen nStt = 0,
+                            xub_StrLen nEnd = STRING_NOTFOUND ) const;
+};
+
+
+void SwIntrnlRefLink::DataChanged( SvData& rData )
+{
+    switch( rData.GetFormat() )
+    {
+    case FORMAT_STRING:
+        if( !IsNoDataFlag() )
+        {
+            String sStr;
+            rData.GetData( sStr );
+            // CR-LF am Ende entfernen, ist ueberfluessig!
+            USHORT n = sStr.Len();
+            if( n && 0x0a == sStr.GetChar( n-1 ) )
+                --n;
+            if( n && 0x0d == sStr.GetChar( n-1 ) )
+                --n;
+
+            BOOL bDel = n != sStr.Len();
+            if( bDel )
+                sStr.Erase( n );
+
+            rFldType.SetExpansion( sStr );
+            // erst Expansion setzen! (sonst wird das Flag geloescht!)
+            rFldType.SetCRLFDelFlag( bDel );
+        }
+        break;
+
+    // weitere Formate ...
+    default:
+        return;
+    }
+
+    ASSERT( rFldType.GetDoc(), "Kein pDoc" );
+
+    // keine Abhaengigen mehr?
+    if( rFldType.GetDepends() && !rFldType.IsModifyLocked() && !ChkNoDataFlag() )
+    {
+        ViewShell* pSh;
+        SwEditShell* pESh = rFldType.GetDoc()->GetEditShell( &pSh );
+
+        // dann suchen wir uns mal alle Felder. Wird kein gueltiges
+        // gefunden, dann Disconnecten wir uns!
+        SwMsgPoolItem aUpdateDDE( RES_UPDATEDDETBL );
+        int bCallModify = FALSE;
+        rFldType.LockModify();
+
+        SwClientIter aIter( rFldType );
+        SwClient * pLast = aIter.GoStart();
+        if( pLast )     // konnte zum Anfang gesprungen werden ??
+            do {
+                // eine DDE-Tabelle oder ein DDE-FeldAttribut im Text
+                if( !pLast->IsA( TYPE( SwFmtFld ) ) ||
+                    ((SwFmtFld*)pLast)->GetTxtFld() )
+                {
+                    if( !bCallModify )
+                    {
+                        if( pESh )
+                            pESh->StartAllAction();
+                        else if( pSh )
+                            pSh->StartAction();
+                    }
+                    pLast->Modify( 0, &aUpdateDDE );
+                    bCallModify = TRUE;
+                }
+            } while( 0 != ( pLast = aIter++ ));
+
+        rFldType.UnlockModify();
+
+        if( bCallModify )
+        {
+            if( pESh )
+                pESh->EndAllAction();
+            else if( pSh )
+                pSh->EndAction();
+
+            if( pSh )
+                pSh->GetDoc()->SetModified();
+        }
+    }
+}
+
+void SwIntrnlRefLink::Closed()
+{
+    if( rFldType.GetDoc() && !rFldType.GetDoc()->IsInDtor() )
+    {
+        // Advise verabschiedet sich, alle Felder in Text umwandeln ?
+        ViewShell* pSh;
+        SwEditShell* pESh = rFldType.GetDoc()->GetEditShell( &pSh );
+        if( pESh )
+        {
+            pESh->StartAllAction();
+            pESh->FieldToText( &rFldType );
+            pESh->EndAllAction();
+        }
+        else
+        {
+            pSh->StartAction();
+            // am Doc aufrufen ??
+            pSh->EndAction();
+        }
+    }
+    SvBaseLink::Closed();
+}
+
+const SwNode* SwIntrnlRefLink::GetAnchor() const
+{
+    // hier sollte irgend ein Anchor aus dem normalen Nodes-Array reichen
+    const SwNode* pNd = 0;
+    SwClientIter aIter( rFldType );
+    SwClient * pLast = aIter.GoStart();
+    if( pLast )     // konnte zum Anfang gesprungen werden ??
+        do {
+            // eine DDE-Tabelle oder ein DDE-FeldAttribut im Text
+            if( !pLast->IsA( TYPE( SwFmtFld ) ))
+            {
+                SwDepend* pDep = (SwDepend*)pLast;
+                SwDDETable* pDDETbl = (SwDDETable*)pDep->GetToTell();
+                pNd = pDDETbl->GetTabSortBoxes()[0]->GetSttNd();
+            }
+            else if( ((SwFmtFld*)pLast)->GetTxtFld() )
+                pNd = ((SwFmtFld*)pLast)->GetTxtFld()->GetpTxtNode();
+
+            if( pNd && &rFldType.GetDoc()->GetNodes() == &pNd->GetNodes() )
+                break;
+            pNd = 0;
+        } while( 0 != ( pLast = aIter++ ));
+
+    return pNd;
+}
+
+BOOL SwIntrnlRefLink::IsInRange( ULONG nSttNd, ULONG nEndNd,
+                                xub_StrLen nStt, xub_StrLen nEnd ) const
+{
+    // hier sollte irgend ein Anchor aus dem normalen Nodes-Array reichen
+    SwNodes* pNds = &rFldType.GetDoc()->GetNodes();
+    SwClientIter aIter( rFldType );
+    SwClient * pLast = aIter.GoStart();
+    if( pLast )     // konnte zum Anfang gesprungen werden ??
+        do {
+            // eine DDE-Tabelle oder ein DDE-FeldAttribut im Text
+            if( !pLast->IsA( TYPE( SwFmtFld ) ))
+            {
+                SwDepend* pDep = (SwDepend*)pLast;
+                SwDDETable* pDDETbl = (SwDDETable*)pDep->GetToTell();
+                const SwTableNode* pTblNd = pDDETbl->GetTabSortBoxes()[0]->
+                                GetSttNd()->FindTableNode();
+                if( pTblNd->GetNodes().IsDocNodes() &&
+                    nSttNd < pTblNd->EndOfSectionIndex() &&
+                    nEndNd > pTblNd->GetIndex() )
+                    return TRUE;
+            }
+            else if( ((SwFmtFld*)pLast)->GetTxtFld() )
+            {
+                const SwTxtFld* pTFld = ((SwFmtFld*)pLast)->GetTxtFld();
+                const SwTxtNode* pNd = pTFld->GetpTxtNode();
+                if( pNd && pNds == &pNd->GetNodes() )
+                {
+                    ULONG nNdPos = pNd->GetIndex();
+                    if( nSttNd <= nNdPos && nNdPos <= nEndNd &&
+                        ( nNdPos != nSttNd || *pTFld->GetStart() >= nStt ) &&
+                        ( nNdPos != nEndNd || *pTFld->GetStart() < nEnd ))
+                        return TRUE;
+                }
+            }
+        } while( 0 != ( pLast = aIter++ ));
+
+    return FALSE;
+}
+
+SwDDEFieldType::SwDDEFieldType(const String& rName,
+                                const String& rCmd, USHORT nUpdateType )
+    : SwFieldType( RES_DDEFLD ),
+    aName( rName ), pDoc( 0 ), nRefCnt( 0 )
+{
+    bCRLFFlag = bDeleted = FALSE;
+    refLink = new SwIntrnlRefLink( *this, nUpdateType, FORMAT_STRING );
+    SetCmd( rCmd );
+}
+
+SwDDEFieldType::~SwDDEFieldType()
+{
+    if( pDoc && !pDoc->IsInDtor() )
+        pDoc->GetLinkManager().Remove( *refLink );
+    refLink->Disconnect();
+}
+
+
+SwFieldType* SwDDEFieldType::Copy() const
+{
+    SwDDEFieldType* pType = new SwDDEFieldType( aName, GetCmd(), GetType() );
+    pType->aExpansion = aExpansion;
+    pType->bCRLFFlag = bCRLFFlag;
+    pType->bDeleted = bDeleted;
+    pType->SetDoc( pDoc );
+    return pType;
+}
+
+const String& SwDDEFieldType::GetName() const
+{
+    return aName;
+}
+
+void SwDDEFieldType::SetCmd( const String& rStr )
+{
+    String sCmd( rStr );
+    xub_StrLen nPos;
+    while( STRING_NOTFOUND != (nPos = sCmd.SearchAscii( "  " )) )
+        sCmd.Erase( nPos, 1 );
+    refLink->SetLinkSourceName( new SvLinkName( sCmd ) );
+}
+
+String SwDDEFieldType::GetCmd() const
+{
+    SvLinkName* pLNm = refLink->GetLinkSourceName();
+    if( pLNm )
+        return pLNm->GetName();
+    return aEmptyStr;
+}
+
+void SwDDEFieldType::SetDoc( SwDoc* pNewDoc )
+{
+    if( pNewDoc == pDoc )
+        return;
+
+    if( pDoc && refLink.Is() )
+    {
+        ASSERT( !nRefCnt, "wie kommen die Referenzen rueber?" );
+        pDoc->GetLinkManager().Remove( *refLink );
+    }
+
+    pDoc = pNewDoc;
+    if( pDoc && nRefCnt )
+    {
+        refLink->SetVisible( pDoc->IsVisibleLinks() );
+        pDoc->GetLinkManager().InsertDDELink( *refLink );
+    }
+}
+
+
+void SwDDEFieldType::_RefCntChgd()
+{
+    if( nRefCnt )
+    {
+        refLink->SetVisible( pDoc->IsVisibleLinks() );
+        pDoc->GetLinkManager().InsertDDELink( *refLink );
+        if( pDoc->GetRootFrm() )
+            UpdateNow();
+    }
+    else
+    {
+        Disconnect();
+        pDoc->GetLinkManager().Remove( *refLink );
+    }
+}
+/* -----------------------------28.08.00 16:23--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL    SwDDEFieldType::QueryValue( com::sun::star::uno::Any& rVal, const String& rProperty ) const
+{
+    USHORT nPart = rProperty.EqualsAscii(UNO_NAME_DDE_COMMAND_TYPE)  ? 0 :
+        rProperty.EqualsAscii(UNO_NAME_DDE_COMMAND_FILE)  ? 1 :
+            rProperty.EqualsAscii(UNO_NAME_DDE_COMMAND_ELEMENT)  ? 2 :
+            rProperty.EqualsAscii(UNO_NAME_IS_AUTOMATIC_UPDATE) ? 3 : USHRT_MAX;
+    if(nPart < 3 )
+    {
+        rVal <<= OUString(GetCmd().GetToken(nPart, cTokenSeperator));
+    }
+    else if(3 == nPart)
+    {
+        sal_Bool bSet = GetType() == LINKUPDATE_ALWAYS ? TRUE : FALSE;
+        rVal.setValue(&bSet, ::getBooleanCppuType());
+    }
+    else
+        return FALSE;
+    return TRUE;
+}
+/* -----------------------------28.08.00 16:23--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL    SwDDEFieldType::PutValue( const com::sun::star::uno::Any& rVal, const String& rProperty )
+{
+    USHORT nPart = rProperty.EqualsAscii(UNO_NAME_DDE_COMMAND_TYPE)  ? 0 :
+        rProperty.EqualsAscii(UNO_NAME_DDE_COMMAND_FILE)  ? 1 :
+            rProperty.EqualsAscii(UNO_NAME_DDE_COMMAND_ELEMENT)  ? 2 :
+            rProperty.EqualsAscii(UNO_NAME_IS_AUTOMATIC_UPDATE) ? 3 : USHRT_MAX;
+    if(nPart < 3 )
+    {
+        OUString sVal;
+        rVal >>= sVal;
+        String sCmd = GetCmd();
+        while(3 > sCmd.GetTokenCount(cTokenSeperator))
+            sCmd += cTokenSeperator;
+        sCmd.SetToken(nPart, cTokenSeperator, sVal);
+        SetCmd( sCmd );
+    }
+    else if(3 == nPart)
+    {
+        sal_Bool bSet = *(sal_Bool*)rVal.getValue();
+        SetType( bSet ? LINKUPDATE_ALWAYS : LINKUPDATE_ONCALL );
+    }
+    else
+        return FALSE;
+    return TRUE;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+SwDDEField::SwDDEField( SwDDEFieldType* pType )
+    : SwField(pType)
+{
+}
+
+SwDDEField::~SwDDEField()
+{
+    if( GetTyp()->IsLastDepend() )                      // der Letzte mach das
+        ((SwDDEFieldType*)GetTyp())->Disconnect();      // Licht aus
+}
+
+String SwDDEField::Expand() const
+{
+    xub_StrLen nPos;
+    String aStr( ((SwDDEFieldType*)GetTyp())->GetExpansion() );
+
+    aStr.EraseAllChars( '\r' );
+    while( (nPos = aStr.Search( '\t' )) != STRING_NOTFOUND )
+        aStr.SetChar( ' ', nPos );
+    while( (nPos = aStr.Search( '\n' )) != STRING_NOTFOUND )
+        aStr.SetChar( '|', nPos );
+    if( aStr.Len() && ( aStr.GetChar( aStr.Len()-1 ) == '|') )
+        aStr.Erase( aStr.Len()-1, 1 );
+    return aStr;
+}
+
+SwField* SwDDEField::Copy() const
+{
+    return new SwDDEField((SwDDEFieldType*)GetTyp());
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Parameter des Typen erfragen
+                  Name
+ --------------------------------------------------------------------*/
+const String& SwDDEField::GetPar1() const
+{
+    return ((SwDDEFieldType*)GetTyp())->GetName();
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Parameter des Typen erfragen
+                  Commando
+ --------------------------------------------------------------------*/
+String SwDDEField::GetPar2() const
+{
+    return ((SwDDEFieldType*)GetTyp())->GetCmd();
+}
+
+void SwDDEField::SetPar2(const String& rStr)
+{
+    ((SwDDEFieldType*)GetTyp())->SetCmd(rStr);
+}
+
diff --git a/sw/source/core/fields/ddetbl.cxx b/sw/source/core/fields/ddetbl.cxx
new file mode 100644
index 000000000000..2a79c1a02562
--- /dev/null
+++ b/sw/source/core/fields/ddetbl.cxx
@@ -0,0 +1,240 @@
+/*************************************************************************
+ *
+ *  $RCSfile: ddetbl.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:19 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _FRMFMT_HXX //autogen
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _INDEX_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _SWTABLE_HXX
+#include 
+#endif
+#ifndef _SWDDETBL_HXX
+#include 
+#endif
+#ifndef _DDEFLD_HXX
+#include            // fuer den FieldType
+#endif
+#ifndef _NDINDEX_HXX
+#include 
+#endif
+#ifndef _FLDUPDE_HXX
+#include 
+#endif
+#ifndef _SWTBLFMT_HXX
+#include 
+#endif
+
+
+TYPEINIT1( SwDDETable, SwTable );
+
+    // Constructor movet alle Lines/Boxen aus der SwTable zu sich.
+    // Die SwTable ist danach Leer und muss geloescht werden.
+SwDDETable::SwDDETable( SwTable& rTable, SwDDEFieldType* pDDEType )
+    : SwTable( rTable ), aDepend( this, pDDEType )
+{
+    // Kopiere/move die Daten der Tabelle
+    aSortCntBoxes.Insert( &rTable.GetTabSortBoxes(), 0,
+                          rTable.GetTabSortBoxes().Count()  ); // move die Inh. Boxen
+    rTable.GetTabSortBoxes().Remove( (USHORT)0, rTable.GetTabSortBoxes().Count() );
+
+    aLines.Insert( &rTable.GetTabLines(),0 );                       // move die Lines
+    rTable.GetTabLines().Remove( 0, rTable.GetTabLines().Count() );
+
+    if( aLines.Count() )
+    {
+        SwDoc* pDoc = GetFrmFmt()->GetDoc();
+        const SwNode& rNd = *GetTabSortBoxes()[0]->GetSttNd();
+        if( rNd.GetNodes().IsDocNodes() )
+        {
+            // "aktivieren der Updates" (Modify nicht noch mal rufen)
+            aDepend.LockModify();
+            pDDEType->IncRefCnt();
+            aDepend.UnlockModify();
+
+            // Setzen der Werte in die einzelnen Boxen
+            ChangeContent();
+        }
+    }
+}
+
+__EXPORT SwDDETable::~SwDDETable()
+{
+    SwDDEFieldType* pFldTyp = (SwDDEFieldType*)aDepend.GetRegisteredIn();
+    SwDoc* pDoc = GetFrmFmt()->GetDoc();
+    if( !pDoc->IsInDtor() && aLines.Count() &&
+        GetTabSortBoxes()[0]->GetSttNd()->GetNodes().IsDocNodes() )
+        pFldTyp->DecRefCnt();
+
+    // sind wir der letzte Abhaengige vom "geloeschten Feld" dann loesche dieses
+    if( pFldTyp->IsDeleted() && pFldTyp->IsLastDepend() )
+    {
+        pFldTyp->Remove( &aDepend );
+        delete pFldTyp;
+    }
+}
+
+void SwDDETable::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew )
+{
+    if( pNew && RES_UPDATEDDETBL == pNew->Which() )
+        ChangeContent();
+    else
+        SwTable::Modify( pOld, pNew );
+}
+
+void SwDDETable::ChangeContent()
+{
+    ASSERT( GetFrmFmt(), "Kein FrameFormat" );
+    SwDoc* pDoc = GetFrmFmt()->GetDoc();
+
+    // Stehen wir im richtigen NodesArray (Wegen UNDO)
+    if( !aLines.Count() )
+        return;
+    ASSERT( GetTabSortBoxes().Count(), "Tabelle ohne Inhalt?" );
+    if( !GetTabSortBoxes()[0]->GetSttNd()->GetNodes().IsDocNodes() )
+        return;
+
+    // zugriff auf den DDEFldType
+    SwDDEFieldType* pDDEType = (SwDDEFieldType*)aDepend.GetRegisteredIn();
+
+    String aExpand = pDDEType->GetExpansion();
+    aExpand.EraseAllChars( '\r' );
+
+    for( USHORT n = 0; n < aLines.Count(); ++n )
+    {
+        String aLine = aExpand.GetToken( n, '\n' );
+        SwTableLine* pLine = aLines[ n ];
+        for( USHORT i = 0; i < pLine->GetTabBoxes().Count(); ++i )
+        {
+            SwTableBox* pBox = pLine->GetTabBoxes()[ i ];
+            ASSERT( pBox->GetSttIdx(), "keine InhaltsBox" );
+            SwNodeIndex aNdIdx( *pBox->GetSttNd(), 1 );
+            SwTxtNode* pTxtNode = aNdIdx.GetNode().GetTxtNode();
+            ASSERT( pTxtNode, "Kein Node" );
+            SwIndex aCntIdx( pTxtNode, 0 );
+            pTxtNode->Erase( aCntIdx );
+            pTxtNode->Insert( aLine.GetToken( i, '\t' ), aCntIdx );
+
+            SwTableBoxFmt* pBoxFmt = (SwTableBoxFmt*)pBox->GetFrmFmt();
+            pBoxFmt->LockModify();
+            pBoxFmt->ResetAttr( RES_BOXATR_VALUE );
+            pBoxFmt->UnlockModify();
+        }
+    }
+
+    if( AUTOUPD_FIELD_AND_CHARTS == pDoc->GetFldUpdateFlags() )
+        pDoc->SetFieldsDirty( TRUE );
+}
+
+SwDDEFieldType* SwDDETable::GetDDEFldType()
+{
+    return (SwDDEFieldType*)aDepend.GetRegisteredIn();
+}
+
+BOOL SwDDETable::NoDDETable()
+{
+    // suche den TabellenNode
+    ASSERT( GetFrmFmt(), "Kein FrameFormat" );
+    SwDoc* pDoc = GetFrmFmt()->GetDoc();
+
+    // Stehen wir im richtigen NodesArray (Wegen UNDO)
+    if( !aLines.Count() )
+        return FALSE;
+    ASSERT( GetTabSortBoxes().Count(), "Tabelle ohne Inhalt?" );
+    SwNode* pNd = (SwNode*)GetTabSortBoxes()[0]->GetSttNd();
+    if( !pNd->GetNodes().IsDocNodes() )
+        return FALSE;
+
+    SwTableNode* pTblNd = pNd->FindTableNode();
+    ASSERT( pTblNd, "wo steht denn die Tabelle ?");
+
+    SwTable* pNewTbl = new SwTable( *this );
+
+    // Kopiere/move die Daten der Tabelle
+    pNewTbl->GetTabSortBoxes().Insert( &GetTabSortBoxes(), 0,
+                          GetTabSortBoxes().Count()  ); // move die Inh. Boxen
+    GetTabSortBoxes().Remove( (USHORT)0, GetTabSortBoxes().Count() );
+
+    pNewTbl->GetTabLines().Insert( &GetTabLines(),0 );                      // move die Lines
+    GetTabLines().Remove( 0, GetTabLines().Count() );
+
+    if( pDoc->GetRootFrm() )
+        ((SwDDEFieldType*)aDepend.GetRegisteredIn())->DecRefCnt();
+
+    pTblNd->SetNewTable( pNewTbl );       // setze die Tabelle
+
+    return TRUE;
+}
+
+
diff --git a/sw/source/core/fields/docufld.cxx b/sw/source/core/fields/docufld.cxx
new file mode 100644
index 000000000000..316eba8619ff
--- /dev/null
+++ b/sw/source/core/fields/docufld.cxx
@@ -0,0 +1,2485 @@
+/*************************************************************************
+ *
+ *  $RCSfile: docufld.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:19 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include 
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _COM_SUN_STAR_TEXT_SETVARIABLETYPE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XTEXTFIELDSSUPPLIER_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_USERDATAPART_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_CHAPTERFORMAT_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XTEXTFIELD_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_PLACEHOLDERTYPE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_TEMPLATEDISPLAYFORMAT_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_USERFIELDFORMAT_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_PAGENUMBERTYPE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_REFERENCEFIELDPART_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_FilenameDisplayFormat_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XDEPENDENTTEXTFIELD_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_DOCUMENTSTATISTIC_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_UTIL_DATE_HPP_
+#include 
+#endif
+#ifndef _UNOPRNMS_HXX
+#include 
+#endif
+
+#ifndef _SVX_ADRITEM_HXX
+#include 
+#endif
+#ifndef _URLOBJ_HXX //autogen
+#include 
+#endif
+#ifndef SVTOOLS_URIHELPER_HXX
+#include 
+#endif
+#ifndef _SFXDOCFILE_HXX //autogen
+#include 
+#endif
+#ifndef _INTN_HXX //autogen
+#include 
+#endif
+#ifndef _SFXDOCINF_HXX //autogen
+#include 
+#endif
+#ifndef _SFXDOCTEMPL_HXX //autogen
+#include 
+#endif
+
+#ifndef _APP_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _CHARFMT_HXX //autogen
+#include 
+#endif
+#ifndef _DOCSTAT_HXX //autogen
+#include 
+#endif
+#ifndef _PAGEDESC_HXX //autogen
+#include 
+#endif
+#ifndef _FMTPDSC_HXX //autogen
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _ROOTFRM_HXX
+#include       // AuthorField
+#endif
+#ifndef _PAGEFRM_HXX
+#include       //
+#endif
+#ifndef _CNTFRM_HXX
+#include        //
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _VIEWSH_HXX
+#include 
+#endif
+#ifndef _DBMGR_HXX
+#include 
+#endif
+#ifndef _SHELLRES_HXX
+#include 
+#endif
+#ifndef _DOCUFLD_HXX
+#include 
+#endif
+#ifndef _FLDDAT_HXX
+#include 
+#endif
+#ifndef _FINDER_HXX
+#include        // AuthorField
+#endif
+#ifndef _DOCFLD_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _EXPFLD_HXX
+#include 
+#endif
+#ifndef _POOLFMT_HXX
+#include 
+#endif
+#ifndef _DOCSH_HXX
+#include 
+#endif
+#ifndef _HINTS_HXX
+#include 
+#endif
+
+#define URL_DECODE  INetURLObject::DECODE_WITH_CHARSET
+
+using namespace ::com::sun::star;
+using namespace ::rtl;
+/*--------------------------------------------------------------------
+    Beschreibung: SwPageNumberFieldType
+ --------------------------------------------------------------------*/
+
+SwPageNumberFieldType::SwPageNumberFieldType()
+    : SwFieldType( RES_PAGENUMBERFLD ),
+    eNumFormat( SVX_NUM_ARABIC ),
+    nNum( 0 ),
+    nMax( USHRT_MAX ),
+    bVirtuell( sal_False )
+{
+}
+
+String& SwPageNumberFieldType::Expand( sal_uInt32 nFmt, short nOff,
+                                const String& rUserStr, String& rRet ) const
+{
+    sal_uInt32 nTmpFmt = (SVX_NUM_PAGEDESC == nFmt) ? (sal_uInt32)eNumFormat : nFmt;
+    long nTmp = nNum + nOff;
+
+    if( 0 >= nTmp || SVX_NUM_NUMBER_NONE == nTmpFmt || (!bVirtuell && nTmp > nMax) )
+        rRet = aEmptyStr;
+    else if( SVX_NUM_CHAR_SPECIAL == nTmpFmt )
+        rRet = rUserStr;
+    else
+        rRet = FormatNumber( (sal_uInt16)nTmp, nTmpFmt );
+    return rRet;
+}
+
+SwFieldType* SwPageNumberFieldType::Copy() const
+{
+    SwPageNumberFieldType *pTmp = new SwPageNumberFieldType();
+
+    pTmp->nNum       = nNum;
+    pTmp->nMax       = nMax;
+    pTmp->eNumFormat = eNumFormat;
+    pTmp->bVirtuell  = bVirtuell;
+
+    return pTmp;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Verschiedene Expandierung
+ --------------------------------------------------------------------*/
+
+void SwPageNumberFieldType::ChangeExpansion( SwDoc* pDoc, sal_uInt16 nPage,
+                                            sal_uInt16 nNumPages, sal_Bool bVirt,
+                                            const SvxExtNumType* pNumFmt )
+{
+    nNum = nPage;
+    nMax = nNumPages;
+    if( pNumFmt )
+        eNumFormat = *pNumFmt;
+
+    bVirtuell = sal_False;
+    if( bVirt )
+    {
+        // dann muss das Flag ueberprueft werden, denn das Layout setzt
+        // es NIE zurueck
+        const SfxItemPool &rPool = pDoc->GetAttrPool();
+        const SwFmtPageDesc *pDesc;
+        sal_uInt16 nMaxItems = rPool.GetItemCount( RES_PAGEDESC );
+        for( sal_uInt16 n = 0; n < nMaxItems; ++n )
+            if( 0 != (pDesc = (SwFmtPageDesc*)rPool.GetItem( RES_PAGEDESC, n ) )
+                && pDesc->GetNumOffset() && pDesc->GetDefinedIn() )
+            {
+                if( pDesc->GetDefinedIn()->ISA( SwCntntNode ))
+                {
+                    SwClientIter aIter( *(SwModify*)pDesc->GetDefinedIn() );
+                    if( aIter.First( TYPE( SwFrm ) ) )
+                    {
+                        bVirtuell = sal_True;
+                        break;
+                    }
+                }
+                else if( pDesc->GetDefinedIn()->ISA( SwFmt ))
+                {
+                    SwAutoFmtGetDocNode aGetHt( &pDoc->GetNodes() );
+                    bVirtuell = !pDesc->GetDefinedIn()->GetInfo( aGetHt );
+                    break;
+                }
+            }
+    }
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: SwPageNumberField
+ --------------------------------------------------------------------*/
+
+SwPageNumberField::SwPageNumberField(SwPageNumberFieldType* pTyp,
+                                     sal_uInt16 nSub, sal_uInt32 nFmt, short nOff)
+    : SwField(pTyp, nFmt), nOffset(nOff), nSubType(nSub)
+{
+}
+
+String SwPageNumberField::Expand() const
+{
+    String sRet;
+    SwPageNumberFieldType* pFldType = (SwPageNumberFieldType*)GetTyp();
+
+    if( PG_NEXT == nSubType && 1 != nOffset )
+    {
+        if( pFldType->Expand( GetFormat(), 1, sUserStr, sRet ).Len() )
+            pFldType->Expand( GetFormat(), nOffset, sUserStr, sRet );
+    }
+    else if( PG_PREV == nSubType && -1 != nOffset )
+    {
+        if( pFldType->Expand( GetFormat(), -1, sUserStr, sRet ).Len() )
+            pFldType->Expand( GetFormat(), nOffset, sUserStr, sRet );
+    }
+    else
+        pFldType->Expand( GetFormat(), nOffset, sUserStr, sRet );
+    return sRet;
+}
+
+SwField* SwPageNumberField::Copy() const
+{
+    SwPageNumberField *pTmp =
+        new SwPageNumberField((SwPageNumberFieldType*)GetTyp(), nSubType, GetFormat(), nOffset);
+    pTmp->SetLanguage( GetLanguage() );
+    pTmp->SetUserString( sUserStr );
+    return pTmp;
+}
+
+String SwPageNumberField::GetPar2() const
+{
+    return String::CreateFromInt32(nOffset);
+}
+
+void SwPageNumberField::SetPar2(const String& rStr)
+{
+    nOffset = (short)rStr.ToInt32();
+}
+
+sal_uInt16 SwPageNumberField::GetSubType() const
+{
+    return nSubType;
+}
+
+/*-----------------05.03.98 10:25-------------------
+
+--------------------------------------------------*/
+BOOL SwPageNumberField::QueryValue( uno::Any& rAny, const String& rProperty ) const
+{
+    if(rProperty.EqualsAscii(UNO_NAME_NUMBERING_TYPE))
+    {
+        rAny <<= (sal_Int16)GetFormat();
+    }
+    else if( rProperty.EqualsAscii(UNO_NAME_OFFSET ))
+    {
+        rAny <<= nOffset;
+    }
+    else if( rProperty.EqualsAscii(UNO_NAME_SUB_TYPE))
+    {
+         text::PageNumberType eType;
+        eType = text::PageNumberType_CURRENT;
+        if(nSubType == PG_PREV)
+            eType = text::PageNumberType_PREV;
+        else if(nSubType == PG_NEXT)
+            eType = text::PageNumberType_NEXT;
+        rAny.setValue(&eType, ::getCppuType((const text::PageNumberType*)0));
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_USERTEXT) )
+    {
+        rAny <<= OUString(sUserStr);
+    }
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return sal_True;
+}
+/*-----------------05.03.98 10:25-------------------
+
+--------------------------------------------------*/
+BOOL SwPageNumberField::PutValue( const uno::Any& rAny, const String& rProperty )
+{
+    if(rProperty.EqualsAscii(UNO_NAME_NUMBERING_TYPE))
+    {
+        sal_Int16 nSet;
+        rAny >>= nSet;
+
+        // TODO: woher kommen die defines?
+        if(nSet <= SVX_NUM_PAGEDESC )
+            SetFormat(nSet);
+        else
+            //exception(wrong_value)
+            ;
+    }
+    else if( rProperty.EqualsAscii(UNO_NAME_OFFSET ))
+    {
+        sal_Int16 nSet;
+        rAny >>= nSet;
+        nOffset = nSet;
+    }
+    else if( rProperty.EqualsAscii(UNO_NAME_SUB_TYPE) &&
+            rAny.getValueType() == ::getCppuType((text::PageNumberType*)0))
+    {
+         text::PageNumberType* pType = (text::PageNumberType*)rAny.getValue();
+        switch( *pType )
+        {
+            case text::PageNumberType_CURRENT:
+                nSubType = PG_RANDOM;
+            break;
+            case text::PageNumberType_PREV:
+                nSubType = PG_PREV;
+            break;
+            default:
+                nSubType = PG_NEXT;
+        }
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_USERTEXT) )
+    {
+        OUString uTmp;
+        rAny >>= uTmp;
+        sUserStr = String(uTmp);
+    }
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return sal_True;
+}
+/*--------------------------------------------------------------------
+    Beschreibung: SwAuthorFieldType
+ --------------------------------------------------------------------*/
+
+SwAuthorFieldType::SwAuthorFieldType(SwDoc* pDocument)
+    : SwFieldType( RES_AUTHORFLD )
+{
+    pDoc = pDocument;
+}
+
+String SwAuthorFieldType::Expand(sal_uInt32 nFmt) const
+{
+    if((nFmt & 0xff) == AF_NAME)
+        return pPathFinder->GetUserName();
+    return pPathFinder->GetShortUserName();
+}
+
+SwFieldType* SwAuthorFieldType::Copy() const
+{
+    SwAuthorFieldType *pTmp = new SwAuthorFieldType(pDoc);
+    return pTmp;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: SwAuthorField
+ --------------------------------------------------------------------*/
+
+SwAuthorField::SwAuthorField(SwAuthorFieldType* pTyp, sal_uInt32 nFmt)
+    : SwField(pTyp, nFmt)
+{
+    aContent = ((SwAuthorFieldType*)GetTyp())->Expand(GetFormat());
+}
+
+String SwAuthorField::Expand() const
+{
+    if (!IsFixed())
+        ((SwAuthorField*)this)->aContent = ((SwAuthorFieldType*)GetTyp())->Expand(GetFormat());
+
+    return aContent;
+}
+
+SwField* SwAuthorField::Copy() const
+{
+    SwAuthorField *pTmp = new SwAuthorField((SwAuthorFieldType*)GetTyp(), GetFormat());
+    pTmp->SetExpansion(aContent);
+
+    return pTmp;
+}
+
+/*-----------------05.03.98 11:15-------------------
+
+--------------------------------------------------*/
+BOOL SwAuthorField::QueryValue( uno::Any& rAny, const String& rProperty ) const
+{
+    if( rProperty.EqualsAscii(UNO_NAME_FULL_NAME ))
+    {
+        sal_Bool bVal = GetFormat() == AF_NAME;
+        rAny.setValue(&bVal, ::getBooleanCppuType());
+    }
+    else if( rProperty.EqualsAscii(UNO_NAME_CONTENT )||
+        rProperty.EqualsAscii(UNO_NAME_CURRENT_PRESENTATION))
+        rAny <<= rtl::OUString(GetContent());
+    else if( rProperty.EqualsAscii(UNO_NAME_IS_FIXED ))
+    {
+        sal_Bool bVal = IsFixed();
+        rAny.setValue(&bVal, ::getBooleanCppuType());
+    }
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return sal_True;
+}
+/*-----------------05.03.98 11:15-------------------
+
+--------------------------------------------------*/
+BOOL SwAuthorField::PutValue( const uno::Any& rAny, const String& rProperty )
+{
+    if( rProperty.EqualsAscii(UNO_NAME_FULL_NAME ))
+    {
+        sal_Bool bSet = *(sal_Bool*)rAny.getValue();
+        SetFormat(bSet ? AF_NAME : AF_SHORTCUT);
+    }
+    else if( rProperty.EqualsAscii(UNO_NAME_CONTENT) ||
+        rProperty.EqualsAscii(UNO_NAME_CURRENT_PRESENTATION))
+    {
+        OUString uTmp;
+        rAny >>= uTmp;
+        aContent = String(uTmp);
+    }
+    else if( rProperty.EqualsAscii(UNO_NAME_IS_FIXED ))
+    {
+        sal_Bool bSet = *(sal_Bool*)rAny.getValue();
+        if(bSet)
+            SetFormat( GetFormat() | AF_FIXED);
+        else
+            SetFormat( GetFormat() & ~AF_FIXED);
+    }
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return sal_True;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: SwFileNameFieldType
+ --------------------------------------------------------------------*/
+
+SwFileNameFieldType::SwFileNameFieldType(SwDoc *pDocument)
+    : SwFieldType( RES_FILENAMEFLD )
+{
+    pDoc = pDocument;
+}
+
+String SwFileNameFieldType::Expand(sal_uInt32 nFmt) const
+{
+    String aRet;
+    const SwDocShell* pDShell = pDoc->GetDocShell();
+    if( pDShell && pDShell->HasName() )
+    {
+        const INetURLObject& rURLObj = pDShell->GetMedium()->GetURLObject();
+        switch( nFmt & ~FF_FIXED )
+        {
+            case FF_PATH:
+                {
+                    if( INET_PROT_FILE == rURLObj.GetProtocol() )
+                    {
+                        INetURLObject aTemp(rURLObj);
+                        aTemp.removeSegment();
+                        aRet = aTemp.GetFull();
+                    }
+                    else
+                    {
+                        aRet = URIHelper::removePassword( rURLObj.GetMainURL(),
+                                    INetURLObject::WAS_ENCODED, URL_DECODE );
+                        aRet.Erase( aRet.Search( rURLObj.GetLastName(
+                                                    URL_DECODE ) ) );
+                    }
+                }
+                break;
+
+            case FF_NAME:
+                aRet = rURLObj.GetLastName( URL_DECODE );
+                break;
+
+            case FF_NAME_NOEXT:
+                aRet = rURLObj.GetBase();
+                break;
+
+            default:
+                if( INET_PROT_FILE == rURLObj.GetProtocol() )
+                    aRet = rURLObj.GetFull();
+                else
+                    aRet = URIHelper::removePassword( rURLObj.GetMainURL(),
+                                    INetURLObject::WAS_ENCODED, URL_DECODE );
+        }
+    }
+    return aRet;
+}
+
+SwFieldType* SwFileNameFieldType::Copy() const
+{
+    SwFieldType *pTmp = new SwFileNameFieldType(pDoc);
+    return pTmp;
+}
+/*--------------------------------------------------------------------
+    Beschreibung: SwFileNameField
+ --------------------------------------------------------------------*/
+
+SwFileNameField::SwFileNameField(SwFileNameFieldType* pTyp, sal_uInt32 nFmt)
+    : SwField(pTyp, nFmt)
+{
+    aContent = ((SwFileNameFieldType*)GetTyp())->Expand(GetFormat());
+}
+
+String SwFileNameField::Expand() const
+{
+    if (!IsFixed())
+        ((SwFileNameField*)this)->aContent = ((SwFileNameFieldType*)GetTyp())->Expand(GetFormat());
+
+    return aContent;
+}
+
+SwField* SwFileNameField::Copy() const
+{
+    SwFileNameField *pTmp =
+        new SwFileNameField((SwFileNameFieldType*)GetTyp(), GetFormat());
+    pTmp->SetExpansion(aContent);
+
+    return pTmp;
+}
+
+/*-----------------05.03.98 08:59-------------------
+
+--------------------------------------------------*/
+BOOL SwFileNameField::QueryValue( uno::Any& rAny, const String& rProperty ) const
+{
+    if(rProperty.EqualsAscii(UNO_NAME_FILE_FORMAT))
+    {
+        sal_Int16 nRet;
+        switch( GetFormat() &(~FF_FIXED) )
+        {
+            case FF_PATH:
+                nRet = text::FilenameDisplayFormat::PATH;
+            break;
+            case FF_NAME_NOEXT:
+                nRet = text::FilenameDisplayFormat::NAME;
+            break;
+            case FF_NAME:
+                nRet = text::FilenameDisplayFormat::NAME_AND_EXT;
+            break;
+            default:    nRet = text::FilenameDisplayFormat::FULL;
+        }
+        rAny <<= nRet;
+    }
+    else if (rProperty.EqualsAscii(UNO_NAME_IS_FIXED))
+    {
+        sal_Bool bVal = IsFixed();
+        rAny.setValue(&bVal, ::getBooleanCppuType());
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_CURRENT_PRESENTATION))
+        rAny <<= OUString(GetContent());
+    return sal_True;
+}
+/*-----------------05.03.98 09:01-------------------
+
+--------------------------------------------------*/
+BOOL SwFileNameField::PutValue( const uno::Any& rAny, const String& rProperty )
+{
+    if(rProperty.EqualsAscii(UNO_NAME_FILE_FORMAT))
+    {
+        sal_Int16 nType;
+        rAny >>= nType;
+        BOOL bFixed = IsFixed();
+        switch( nType )
+        {
+            case text::FilenameDisplayFormat::PATH:
+                nType = FF_PATH;
+            break;
+            case text::FilenameDisplayFormat::NAME:
+                nType = FF_NAME_NOEXT;
+            break;
+            case text::FilenameDisplayFormat::NAME_AND_EXT:
+                nType = FF_NAME;
+            break;
+            default:    nType = FF_PATHNAME;
+        }
+        if(bFixed)
+            nType |= FF_FIXED;
+        SetFormat(nType);
+    }
+    else if (rProperty.EqualsAscii(UNO_NAME_IS_FIXED))
+
+    {
+        sal_Bool bSet = *(sal_Bool*)rAny.getValue();
+        if(bSet)
+            SetFormat( GetFormat() | FF_FIXED);
+        else
+            SetFormat( GetFormat() & ~FF_FIXED);
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_CURRENT_PRESENTATION))
+    {
+        OUString sVal;
+        rAny >>= sVal;
+        SetExpansion(sVal);
+    }
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return sal_True;
+}
+/*--------------------------------------------------------------------
+    Beschreibung: SwTemplNameFieldType
+ --------------------------------------------------------------------*/
+
+SwTemplNameFieldType::SwTemplNameFieldType(SwDoc *pDocument)
+    : SwFieldType( RES_TEMPLNAMEFLD )
+{
+    pDoc = pDocument;
+}
+
+String SwTemplNameFieldType::Expand(sal_uInt32 nFmt) const
+{
+    ASSERT(nFmt >= FF_BEGIN && nFmt < FF_END, "Expand: kein guelt. Fmt!" );
+
+    String aRet;
+    const SfxDocumentInfo* pDInfo = pDoc->GetpInfo();
+
+    if( pDInfo )
+    {
+        if( FF_UI_NAME == nFmt )
+            aRet = pDInfo->GetTemplateName();
+        else if( pDInfo->GetTemplateFileName().Len() )
+        {
+            if( FF_UI_RANGE == nFmt )
+            {
+                // fuers besorgen vom RegionNamen !!
+                SfxDocumentTemplates aFac;
+                aFac.Construct();
+                String sTmp;
+                aFac.GetLogicNames( pDInfo->GetTemplateFileName(), aRet, sTmp );
+            }
+            else
+            {
+                INetURLObject aPathName( pDInfo->GetTemplateFileName() );
+                if( FF_NAME == nFmt )
+                    aRet = aPathName.GetName(URL_DECODE);
+                else if( FF_NAME_NOEXT == nFmt )
+                    aRet = aPathName.GetBase();
+                else
+                {
+                    if( FF_PATH == nFmt )
+                    {
+                        aPathName.removeSegment();
+                        aRet = aPathName.GetFull();
+                    }
+                    else
+                        aRet = aPathName.GetFull();
+                }
+            }
+        }
+    }
+    return aRet;
+}
+
+SwFieldType* SwTemplNameFieldType::Copy() const
+{
+    SwFieldType *pTmp = new SwTemplNameFieldType(pDoc);
+    return pTmp;
+}
+/*--------------------------------------------------------------------
+    Beschreibung: SwTemplNameField
+ --------------------------------------------------------------------*/
+
+SwTemplNameField::SwTemplNameField(SwTemplNameFieldType* pTyp, sal_uInt32 nFmt)
+    : SwField(pTyp, nFmt)
+{}
+
+String SwTemplNameField::Expand() const
+{
+    return((SwTemplNameFieldType*)GetTyp())->Expand(GetFormat());
+}
+
+SwField* SwTemplNameField::Copy() const
+{
+    SwTemplNameField *pTmp =
+        new SwTemplNameField((SwTemplNameFieldType*)GetTyp(), GetFormat());
+    return pTmp;
+}
+
+/*-----------------05.03.98 08:59-------------------
+
+--------------------------------------------------*/
+BOOL SwTemplNameField::QueryValue( uno::Any& rAny, const String& rProperty ) const
+{
+    if(rProperty.EqualsAscii(UNO_NAME_FILE_FORMAT))
+    {
+        sal_Int16 nRet;
+        switch( GetFormat() )
+        {
+            case FF_PATH:       nRet = text::FilenameDisplayFormat::PATH; break;
+            case FF_NAME_NOEXT: nRet = text::FilenameDisplayFormat::NAME; break;
+            case FF_NAME:       nRet = text::FilenameDisplayFormat::NAME_AND_EXT; break;
+            case FF_UI_RANGE:   nRet = text::TemplateDisplayFormat::AREA; break;
+            case FF_UI_NAME:    nRet = text::TemplateDisplayFormat::TITLE;  break;
+            default:    nRet = text::FilenameDisplayFormat::FULL;
+
+        }
+        rAny <<= nRet;
+    }
+    return sal_True;
+}
+/*-----------------05.03.98 09:01-------------------
+
+--------------------------------------------------*/
+BOOL SwTemplNameField::PutValue( const uno::Any& rAny, const String& rProperty )
+{
+    if(rProperty.EqualsAscii(UNO_NAME_FILE_FORMAT))
+    {
+        sal_Int16 nType;
+        rAny >>= nType;
+        switch( nType )
+        {
+            case text::FilenameDisplayFormat::PATH:
+                SetFormat(FF_PATH);
+            break;
+            case text::FilenameDisplayFormat::NAME:
+                SetFormat(FF_NAME_NOEXT);
+            break;
+            case text::FilenameDisplayFormat::NAME_AND_EXT:
+                SetFormat(FF_NAME);
+            break;
+            case text::TemplateDisplayFormat::AREA  :
+                SetFormat(FF_UI_RANGE);
+            break;
+            case text::TemplateDisplayFormat::TITLE  :
+                SetFormat(FF_UI_NAME);
+            break;
+            default:    SetFormat(FF_PATHNAME);
+        }
+    }
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return sal_True;
+}
+/*--------------------------------------------------------------------
+    Beschreibung: SwDocStatFieldType
+ --------------------------------------------------------------------*/
+
+SwDocStatFieldType::SwDocStatFieldType(SwDoc* pDocument)
+    : SwFieldType( RES_DOCSTATFLD ), eNumFormat( SVX_NUM_ARABIC )
+{
+    pDoc = pDocument;
+}
+
+String SwDocStatFieldType::Expand(sal_uInt16 nSubType, sal_uInt32 nFmt) const
+{
+    sal_uInt32 nVal = 0;
+    const SwDocStat& rDStat = pDoc->GetDocStat();
+    switch( nSubType )
+    {
+        case DS_TBL:  nVal = rDStat.nTbl;   break;
+        case DS_GRF:  nVal = rDStat.nGrf;   break;
+        case DS_OLE:  nVal = rDStat.nOLE;   break;
+        case DS_PARA: nVal = rDStat.nPara;  break;
+        case DS_WORD: nVal = rDStat.nWord;  break;
+        case DS_CHAR: nVal = rDStat.nChar;  break;
+        case DS_PAGE:
+            if( pDoc->GetRootFrm() )
+                ((SwDocStat &)rDStat).nPage = pDoc->GetRootFrm()->GetPageNum();
+            nVal = rDStat.nPage;
+            if( SVX_NUM_PAGEDESC == nFmt )
+                nFmt = (sal_uInt32)eNumFormat;
+            break;
+        default:
+            ASSERT( sal_False, "SwDocStatFieldType::Expand: unbekannter SubType" );
+    }
+
+    if( nVal <= SHRT_MAX )
+        return FormatNumber( (sal_uInt16)nVal, nFmt );
+
+    return nVal;
+}
+
+SwFieldType* SwDocStatFieldType::Copy() const
+{
+    SwDocStatFieldType *pTmp = new SwDocStatFieldType(pDoc);
+    return pTmp;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: SwDocStatFieldType
+                  Aus historischen Gruenden steht in nFormat der
+                  SubType
+ --------------------------------------------------------------------*/
+
+SwDocStatField::SwDocStatField(SwDocStatFieldType* pTyp, sal_uInt16 nSub, sal_uInt32 nFmt)
+    : SwField(pTyp, nFmt),
+    nSubType(nSub)
+{}
+
+String SwDocStatField::Expand() const
+{
+    return((SwDocStatFieldType*)GetTyp())->Expand(nSubType, GetFormat());
+}
+
+SwField* SwDocStatField::Copy() const
+{
+    SwDocStatField *pTmp = new SwDocStatField(
+                    (SwDocStatFieldType*)GetTyp(), nSubType, GetFormat() );
+    return pTmp;
+}
+
+sal_uInt16 SwDocStatField::GetSubType() const
+{
+    return nSubType;
+}
+
+void SwDocStatField::SetSubType(sal_uInt16 nSub)
+{
+    nSubType = nSub;
+}
+
+void SwDocStatField::ChangeExpansion( const SwFrm* pFrm )
+{
+    if( DS_PAGE == nSubType && SVX_NUM_PAGEDESC == GetFormat() )
+        ((SwDocStatFieldType*)GetTyp())->SetNumFormat(
+                pFrm->FindPageFrm()->GetPageDesc()->GetNumType().eType );
+}
+
+/*-----------------05.03.98 11:38-------------------
+
+--------------------------------------------------*/
+BOOL SwDocStatField::QueryValue( uno::Any& rAny, const String& rProperty ) const
+{
+    if(rProperty.EqualsAscii(UNO_NAME_NUMBERING_TYPE))
+    {
+        rAny <<= (sal_Int16)GetFormat();
+    }
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return sal_True;
+}
+/*-----------------05.03.98 11:38-------------------
+
+--------------------------------------------------*/
+BOOL SwDocStatField::PutValue( const uno::Any& rAny, const String& rProperty )
+{
+    if(rProperty.EqualsAscii(UNO_NAME_NUMBERING_TYPE))
+    {
+        sal_Int16 nSet;
+        rAny >>= nSet;
+        if(nSet <= SVX_NUM_CHARS_LOWER_LETTER_N &&
+            nSet != SVX_NUM_CHAR_SPECIAL &&
+                nSet != SVX_NUM_BITMAP)
+            SetFormat(nSet);
+        else
+            return FALSE;
+    }
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return sal_True;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: DokumentinfoFields
+ --------------------------------------------------------------------*/
+
+SwDocInfoFieldType::SwDocInfoFieldType(SwDoc* pDc)
+    : SwValueFieldType( pDc, RES_DOCINFOFLD )
+{
+}
+
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+SwFieldType* SwDocInfoFieldType::Copy() const
+{
+    SwDocInfoFieldType* pType = new SwDocInfoFieldType(GetDoc());
+    return pType;
+}
+
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+String SwDocInfoFieldType::Expand(sal_uInt16 nSub, sal_uInt32 nFormat, sal_uInt16 nLang) const
+{
+    String          aStr;
+    International   aInter( (LanguageType)nLang,
+                            GetpApp()->GetAppInternational().GetFormatLanguage() );
+
+    const SfxDocumentInfo*  pInf = GetDoc()->GetInfo();
+
+    sal_uInt16 nExtSub = nSub & 0xff00;
+    nSub &= 0xff;   // ExtendedSubTypes nicht beachten
+
+    switch(nSub)
+    {
+        case DI_TITEL:  aStr = pInf->GetTitle();    break;
+        case DI_THEMA:  aStr = pInf->GetTheme();    break;
+        case DI_KEYS:   aStr = pInf->GetKeywords(); break;
+        case DI_COMMENT:aStr = pInf->GetComment();  break;
+        case DI_INFO1:
+        case DI_INFO2:
+        case DI_INFO3:
+        case DI_INFO4:  aStr = pInf->GetUserKey(nSub - DI_INFO1).GetWord();break;
+        case DI_DOCNO:  aStr = String::CreateFromInt32(
+                                    pInf->GetDocumentNumber() );
+                        break;
+        case DI_EDIT:
+            if (!nFormat)
+                aStr = aInter.GetTime( pInf->GetTime(), sal_False, sal_False);
+            else
+            {
+                // Numberformatter anwerfen!
+                double fVal = SwDateTimeField::GetDateTime(GetDoc(), 0, pInf->GetTime());
+                aStr = ExpandValue(fVal, nFormat, nLang);
+            }
+            break;
+
+        default:
+        {
+            SfxStamp aTmp;
+            aTmp = pInf->GetCreated();
+            if( nSub == DI_CREATE )
+                ;       // das wars schon!!
+            else if( nSub == DI_CHANGE &&
+                    (pInf->GetChanged().GetTime() != aTmp.GetTime() ||
+                    (nExtSub & ~DI_SUB_FIXED) == DI_SUB_AUTHOR &&
+                    pInf->GetDocumentNumber() > 1) )
+                aTmp = pInf->GetChanged();
+            else if( nSub == DI_PRINT &&
+                    pInf->GetPrinted().GetTime() != aTmp.GetTime() )
+                aTmp = pInf->GetPrinted();
+            else
+                return aStr;
+
+            if (aTmp.IsValid())
+            {
+                switch (nExtSub & ~DI_SUB_FIXED)
+                {
+                    case DI_SUB_AUTHOR:
+                        aStr = aTmp.GetName();
+                        break;
+
+                    case DI_SUB_TIME:
+                        if (!nFormat)
+                            aStr = aInter.GetTime(aTmp.GetTime(), sal_False, sal_False);
+                        else
+                        {
+                            // Numberformatter anwerfen!
+                            double fVal = SwDateTimeField::GetDateTime(GetDoc(), aTmp.GetTime().GetDate(), aTmp.GetTime().GetTime());
+                            aStr = ExpandValue(fVal, nFormat, nLang);
+                        }
+                        break;
+
+                    case DI_SUB_DATE:
+                        if (!nFormat)
+                            aStr = aInter.GetDate(aTmp.GetTime());
+                        else
+                        {
+                            // Numberformatter anwerfen!
+                            double fVal = SwDateTimeField::GetDateTime(GetDoc(), aTmp.GetTime().GetDate(), aTmp.GetTime().GetTime());
+                            aStr = ExpandValue(fVal, nFormat, nLang);
+                        }
+                        break;
+                }
+            }
+        }
+    }
+    return aStr;
+}
+
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+SwDocInfoField::SwDocInfoField(SwDocInfoFieldType* pType, sal_uInt16 nSub, sal_uInt32 nFmt) :
+    SwValueField(pType, nFmt), nSubType(nSub)
+{
+    aContent = ((SwDocInfoFieldType*)GetTyp())->Expand(nSubType, nFmt, GetLanguage());
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+String SwDocInfoField::Expand() const
+{
+    if (!IsFixed()) // aContent fuer Umschaltung auf fixed mitpflegen
+        ((SwDocInfoField*)this)->aContent = ((SwDocInfoFieldType*)GetTyp())->Expand(nSubType, GetFormat(), GetLanguage());
+
+    return aContent;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+String SwDocInfoField::GetCntnt(sal_Bool bName) const
+{
+    if ( bName )
+    {
+        String aStr(SwFieldType::GetTypeStr(GetTypeId()));
+        aStr += ':';
+
+        sal_uInt16 nSub = nSubType & 0xff;
+
+        switch(nSub)
+        {
+            case DI_INFO1:
+            case DI_INFO2:
+            case DI_INFO3:
+            case DI_INFO4:
+            {
+                const SfxDocumentInfo*  pInf = GetDoc()->GetInfo();
+                aStr += pInf->GetUserKey(nSub - DI_INFO1).GetTitle();
+            }
+            break;
+
+            default:
+                aStr += *ViewShell::GetShellRes()->aDocInfoLst[(GetSubType() & 0xff) - DI_SUBTYPE_BEGIN];
+                break;
+        }
+        if( IsFixed() )
+            ( aStr += ' ' ) += ViewShell::GetShellRes()->aFixedStr;
+        return aStr;
+    }
+    return Expand();
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+SwField* SwDocInfoField::Copy() const
+{
+    SwDocInfoField* pFld = new SwDocInfoField((SwDocInfoFieldType*)GetTyp(), nSubType, GetFormat());
+    pFld->aContent = aContent;
+
+    return pFld;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_uInt16 SwDocInfoField::GetSubType() const
+{
+    return nSubType;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SwDocInfoField::SetSubType(sal_uInt16 nSub)
+{
+    nSubType = nSub;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SwDocInfoField::SetLanguage(sal_uInt16 nLng)
+{
+    if (!GetFormat())
+        SwField::SetLanguage(nLng);
+    else
+        SwValueField::SetLanguage(nLng);
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwDocInfoField::QueryValue( uno::Any& rAny, const String& rProperty ) const
+{
+    if(rProperty.EqualsAscii(UNO_NAME_AUTHOR) ||
+        rProperty.EqualsAscii(UNO_NAME_CONTENT) )
+    {
+        rAny <<= OUString(aContent);
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_REVISION))
+    {
+        rAny  <<= (sal_Int16)aContent.ToInt32();
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_IS_FIXED))
+    {
+        sal_Bool bVal = 0 != (nSubType & DI_SUB_FIXED);
+        rAny.setValue(&bVal, ::getBooleanCppuType());
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_NUMBER_FORMAT))
+    {
+        rAny  <<= (sal_Int32)GetFormat();
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_DATETIME))
+    {
+        Double fVal = GetValue();
+        rAny.setValue(&fVal, ::getCppuType(&fVal));
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_CURRENT_PRESENTATION))
+        rAny <<= rtl::OUString(Expand());
+    else if(rProperty.EqualsAscii(UNO_NAME_IS_DATE))
+    {
+        sal_Bool bVal = 0 != (nSubType & DI_SUB_DATE);
+        rAny.setValue(&bVal, ::getBooleanCppuType());
+    }
+
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("illegal property")
+#endif
+    return sal_True;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwDocInfoField::PutValue( const uno::Any& rAny, const String& rProperty )
+{
+    if(rProperty.EqualsAscii(UNO_NAME_IS_FIXED))
+    {
+        sal_Bool bTemp = *(sal_Bool*)rAny.getValue();
+        if(bTemp)
+            nSubType |= DI_SUB_FIXED;
+        else
+            nSubType &= ~DI_SUB_FIXED;
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_NUMBER_FORMAT))
+    {
+        sal_Int32 nNumberFormat;
+        rAny >>= nNumberFormat;
+        if(nNumberFormat >= 0)
+            SetFormat(nNumberFormat);
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_REVISION) &&
+        (nSubType & DI_SUB_FIXED))
+    {
+        sal_Int32 nRev;
+        rAny >>= nRev;
+        aContent = String::CreateFromInt32(nRev);
+    }
+    else if((rProperty.EqualsAscii(UNO_NAME_AUTHOR) ||
+        rProperty.EqualsAscii(UNO_NAME_CONTENT)) &&
+        (nSubType & DI_SUB_FIXED) )
+    {
+        OUString sVal;
+        rAny >>= sVal;
+        aContent = sVal;
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_CURRENT_PRESENTATION))
+    {
+        OUString sVal;
+        rAny >>= sVal;
+        SetExpansion(sVal);
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_IS_DATE))
+    {
+        if(*(sal_Bool*)rAny.getValue())
+        {
+            nSubType |= DI_SUB_DATE;
+            nSubType &= ~DI_SUB_TIME;
+        }
+        else
+        {
+            nSubType |= DI_SUB_TIME;
+            nSubType &= ~DI_SUB_DATE;
+        }
+    }
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("illegal property")
+#endif
+    return sal_True;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: SwHiddenTxtFieldType by JP
+ --------------------------------------------------------------------*/
+
+SwHiddenTxtFieldType::SwHiddenTxtFieldType( sal_Bool bSetHidden )
+    : SwFieldType( RES_HIDDENTXTFLD ), bHidden( bSetHidden )
+{}
+
+SwFieldType* SwHiddenTxtFieldType::Copy() const
+{
+    return new SwHiddenTxtFieldType( bHidden );
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SwHiddenTxtFieldType::SetHiddenFlag( sal_Bool bSetHidden )
+{
+    if( bHidden != bSetHidden )
+    {
+        bHidden = bSetHidden;
+        UpdateFlds();       // alle HiddenText benachrichtigen
+    }
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+SwHiddenTxtField::SwHiddenTxtField( SwHiddenTxtFieldType* pFldType,
+                                    sal_Bool    bConditional,
+                                    const   String& rCond,
+                                    const   String& rStr,
+                                    sal_Bool    bHidden,
+                                    sal_uInt16  nSub) :
+    SwField( pFldType ), aCond(rCond), bValid(sal_False),
+    bCanToggle(bConditional), bIsHidden(bHidden), nSubType(nSub)
+{
+    if(nSubType == TYP_CONDTXTFLD)
+    {
+        sal_uInt16 nPos = 0;
+        aTRUETxt = rStr.GetToken(0, '|', nPos);
+
+        if(nPos != STRING_NOTFOUND)
+        {
+            aFALSETxt = rStr.GetToken(0, '|', nPos);
+            if(nPos != STRING_NOTFOUND)
+            {
+                aContent = rStr.GetToken(0, '|', nPos);
+                bValid = sal_True;
+            }
+        }
+    }
+    else
+        aTRUETxt = rStr;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+SwHiddenTxtField::SwHiddenTxtField( SwHiddenTxtFieldType* pFldType,
+                                    const String& rCond,
+                                    const String& rTrue,
+                                    const String& rFalse,
+                                    sal_uInt16 nSub)
+    : SwField( pFldType ), aCond(rCond), bIsHidden(sal_True), nSubType(nSub),
+      aTRUETxt(rTrue), aFALSETxt(rFalse), bValid(sal_False)
+{
+    bCanToggle  = aCond.Len() > 0;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+String SwHiddenTxtField::Expand() const
+{
+    // Type: !Hidden  -> immer anzeigen
+    //        Hide    -> Werte die Bedingung aus
+
+    if( TYP_CONDTXTFLD == nSubType )
+    {
+        if( bValid )
+            return aContent;
+
+        if( bCanToggle && !bIsHidden )
+            return aTRUETxt;
+    }
+    else if( !((SwHiddenTxtFieldType*)GetTyp())->GetHiddenFlag() ||
+        ( bCanToggle && bIsHidden ))
+        return aTRUETxt;
+
+    return aFALSETxt;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Aktuellen Field-Value holen und cachen
+ --------------------------------------------------------------------*/
+
+void SwHiddenTxtField::Evaluate(SwDoc* pDoc)
+{
+    ASSERT(pDoc, Wo ist das Dokument Seniore);
+
+    if( TYP_CONDTXTFLD == nSubType )
+    {
+        SwNewDBMgr* pMgr = pDoc->GetNewDBMgr();
+
+        bValid = sal_False;
+        String sTmpName;
+
+        if (bCanToggle && !bIsHidden)
+            sTmpName = aTRUETxt;
+        else
+            sTmpName = aFALSETxt;
+
+// OS 21.08.97: #42943# Datenbankausdruecke muessen sich von
+//              einfachem Text unterscheiden. also wird der einfache Text
+//              bevorzugt in Anfuehrungszeichen gesetzt.
+//              Sind diese vorhanden werden umschliessende entfernt.
+//              Wenn nicht, dann wird auf die Tauglichkeit als Datenbankname
+//              geprueft. Nur wenn zwei oder mehr Punkte vorhanden sind und kein
+//              Anfuehrungszeichen enthalten ist, gehen wir von einer DB aus.
+        if(sTmpName.Len() > 1 && sTmpName.GetChar(0) == '\"' &&
+            sTmpName.GetChar((sTmpName.Len() - 1)))
+        {
+            aContent = sTmpName.Copy(1, sTmpName.Len() - 2);
+            bValid = sal_True;
+        }
+        else if(sTmpName.Search('\"') == STRING_NOTFOUND &&
+            sTmpName.GetTokenCount('.') > 2)
+        {
+            ::ReplacePoint(sTmpName);
+            if(sTmpName.GetChar(0) == '[' && sTmpName.GetChar(sTmpName.Len()-1) == ']')
+            {   // Eckige Klammern entfernen
+                sTmpName.Erase(0, 1);
+                sTmpName.Erase(sTmpName.Len()-1, 1);
+            }
+
+            if( pMgr)
+            {
+                if (pMgr->IsInMerge())
+                {
+                    String sDBName;
+#ifdef REPLACE_OFADBMGR
+                    sDBName = GetDBName( sTmpName, pDoc );
+                    if(sDBName.Len())
+                    {
+                        String sDataSource(sDBName.GetToken(0, DB_DELIM));
+                        String sDataTableOrQuery(sDBName.GetToken(1, DB_DELIM));
+                        if(pMgr && pMgr->IsDataSourceOpen(sDataSource, sDataTableOrQuery))
+                        {
+                            double fNumber;
+                            sal_uInt32 nFormat;
+                            pMgr->GetMergeColumnCnt(GetColumnName( sTmpName ),
+                                            GetLanguage(), aContent, &fNumber, &nFormat );
+                            bValid = sal_True;
+                        }
+                    }
+#else
+                    if ((sDBName = GetDBName( sTmpName, pDoc )).Len() &&
+                            pMgr->OpenDB( DBMGR_STD, sDBName, sal_False ))
+                    {
+                        String sColumnName( GetColumnName( sTmpName ));
+
+                        if (sColumnName.Len())
+                        {
+                            pMgr->GetColumnCnt(DBMGR_STD, sColumnName,
+                                            pMgr->GetCurRecordId(DBMGR_STD), aContent);
+                            bValid = sal_True;
+                        }
+                    }
+#endif
+                }
+                else
+                    bValid = sal_True;
+            }
+        }
+    }
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+String SwHiddenTxtField::GetCntnt(sal_Bool bName) const
+{
+    if ( bName )
+    {
+        String aStr(SwFieldType::GetTypeStr(nSubType));
+        aStr += ' ';
+        aStr += aCond;
+        aStr += ' ';
+        aStr += aTRUETxt;
+
+        if(nSubType == TYP_CONDTXTFLD)
+        {
+static char __READONLY_DATA cTmp[] = " : ";
+            aStr.AppendAscii(cTmp);
+            aStr += aFALSETxt;
+        }
+        return aStr;
+    }
+    return Expand();
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+SwField* SwHiddenTxtField::Copy() const
+{
+    SwHiddenTxtField* pFld =
+        new SwHiddenTxtField((SwHiddenTxtFieldType*)GetTyp(), aCond,
+                              aTRUETxt, aFALSETxt);
+    pFld->bIsHidden = bIsHidden;
+    pFld->bValid    = bValid;
+    pFld->aContent  = aContent;
+    pFld->SetFormat(GetFormat());
+    pFld->nSubType  = nSubType;
+    return pFld;
+}
+
+
+/*--------------------------------------------------------------------
+    Beschreibung: Bedingung setzen
+ --------------------------------------------------------------------*/
+
+void SwHiddenTxtField::SetPar1(const String& rStr)
+{
+    aCond = rStr;
+    bCanToggle = aCond.Len() > 0;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+const String& SwHiddenTxtField::GetPar1() const
+{
+    return aCond;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: True/False Text
+ --------------------------------------------------------------------*/
+
+void SwHiddenTxtField::SetPar2(const String& rStr)
+{
+    if(nSubType == TYP_CONDTXTFLD)
+    {
+        sal_uInt16 nPos = rStr.Search('|');
+        aTRUETxt = rStr.Copy(0, nPos);
+
+        if(nPos != STRING_NOTFOUND)
+            aFALSETxt = rStr.Copy(nPos + 1);
+    }
+    else
+        aTRUETxt = rStr;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+String SwHiddenTxtField::GetPar2() const
+{
+    String aRet(aTRUETxt);
+    if(nSubType == TYP_CONDTXTFLD)
+    {
+        aRet += '|';
+        aRet += aFALSETxt;
+    }
+    return aRet;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_uInt16 SwHiddenTxtField::GetSubType() const
+{
+    return nSubType;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwHiddenTxtField::QueryValue( uno::Any& rAny, const String& rProperty ) const
+{
+    if(rProperty.EqualsAscii(UNO_NAME_CONDITION))
+    {
+        rAny <<= OUString(aCond);
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_TRUE_CONTENT ) || rProperty.EqualsAscii(UNO_NAME_CONTENT))
+    {
+        rAny <<= OUString(aTRUETxt);
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_FALSE_CONTENT))
+    {
+        rAny <<= OUString(aFALSETxt);
+    }
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return sal_True;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwHiddenTxtField::PutValue( const uno::Any& rAny, const String& rProperty )
+{
+    OUString uTmp;
+    rAny >>= uTmp;
+    String sVal(uTmp);
+
+    if(rProperty.EqualsAscii(UNO_NAME_CONDITION))
+        SetPar1(sVal);
+    else if(rProperty.EqualsAscii(UNO_NAME_TRUE_CONTENT )|| rProperty.EqualsAscii(UNO_NAME_CONTENT))
+        aTRUETxt = sVal;
+    else if(rProperty.EqualsAscii(UNO_NAME_FALSE_CONTENT))
+        aFALSETxt = sVal;
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return sal_True;
+}
+
+//------------------------------------------------------------------------------
+
+String SwHiddenTxtField::GetColumnName(const String& rName)
+{
+    sal_uInt16 nPos = rName.Search(DB_DELIM);
+    if( STRING_NOTFOUND != nPos )
+    {
+        nPos = rName.Search(DB_DELIM, nPos + 1);
+
+        if( STRING_NOTFOUND != nPos )
+            return rName.Copy(nPos + 1);
+    }
+    return rName;
+}
+
+//------------------------------------------------------------------------------
+
+String SwHiddenTxtField::GetDBName(const String& rName, SwDoc *pDoc)
+{
+    sal_uInt16 nPos = rName.Search(DB_DELIM);
+    if( STRING_NOTFOUND != nPos )
+    {
+        nPos = rName.Search(DB_DELIM, nPos + 1);
+
+        if( STRING_NOTFOUND != nPos )
+            return rName.Copy( 0, nPos );
+    }
+    return pDoc->GetDBName();
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Der Feldtyp fuer Zeilenhoehe 0
+ --------------------------------------------------------------------*/
+
+SwHiddenParaFieldType::SwHiddenParaFieldType()
+    : SwFieldType( RES_HIDDENPARAFLD )
+{
+}
+
+SwFieldType* SwHiddenParaFieldType::Copy() const
+{
+    SwHiddenParaFieldType* pType = new SwHiddenParaFieldType();
+    return pType;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Das Feld Zeilenhoehe 0
+ --------------------------------------------------------------------*/
+
+SwHiddenParaField::SwHiddenParaField(SwHiddenParaFieldType* pType, const String& rStr)
+    : SwField(pType), aCond(rStr)
+{
+    bIsHidden = sal_False;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+String SwHiddenParaField::Expand() const
+{
+    return aEmptyStr;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+SwField* SwHiddenParaField::Copy() const
+{
+    SwHiddenParaField* pFld = new SwHiddenParaField((SwHiddenParaFieldType*)GetTyp(), aCond);
+    pFld->bIsHidden = bIsHidden;
+
+    return pFld;
+}
+/*-----------------05.03.98 13:25-------------------
+
+--------------------------------------------------*/
+BOOL SwHiddenParaField::QueryValue( uno::Any& rAny, const String& rProperty ) const
+{
+    if(rProperty.EqualsAscii(UNO_NAME_CONDITION))
+        rAny <<= OUString(aCond);
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return sal_True;
+}
+/*-----------------05.03.98 13:25-------------------
+
+--------------------------------------------------*/
+BOOL SwHiddenParaField::PutValue( const uno::Any& rAny, const String& rProperty )
+{
+    if(rProperty.EqualsAscii(UNO_NAME_CONDITION))
+    {
+        OUString uTmp;
+        rAny >>= uTmp;
+        aCond = String(uTmp);
+    }
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return sal_True;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Bedingung setzen
+ --------------------------------------------------------------------*/
+
+void SwHiddenParaField::SetPar1(const String& rStr)
+{
+    aCond = rStr;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+const String& SwHiddenParaField::GetPar1() const
+{
+    return aCond;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: PostIt
+ --------------------------------------------------------------------*/
+
+SwPostItFieldType::SwPostItFieldType()
+    : SwFieldType( RES_POSTITFLD )
+{}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+SwFieldType* SwPostItFieldType::Copy() const
+{
+    return new SwPostItFieldType;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: SwPostItFieldType
+ --------------------------------------------------------------------*/
+
+SwPostItField::SwPostItField( SwPostItFieldType* pType,
+        const String& rAuthor, const String& rTxt, const Date& rDate )
+    : SwField( pType ), sTxt( rTxt ), sAuthor( rAuthor ), aDate( rDate )
+{
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+String SwPostItField::Expand() const
+{
+    return aEmptyStr;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+SwField* SwPostItField::Copy() const
+{
+    return new SwPostItField( (SwPostItFieldType*)GetTyp(), sAuthor,
+                                sTxt, aDate );
+}
+/*--------------------------------------------------------------------
+    Beschreibung: Author setzen
+ --------------------------------------------------------------------*/
+
+void SwPostItField::SetPar1(const String& rStr)
+{
+    sAuthor = rStr;
+}
+
+const String& SwPostItField::GetPar1() const
+{
+    return sAuthor;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Text fuers PostIt setzen
+ --------------------------------------------------------------------*/
+
+void SwPostItField::SetPar2(const String& rStr)
+{
+    sTxt = rStr;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+String SwPostItField::GetPar2() const
+{
+    return sTxt;
+}
+
+/*-----------------05.03.98 13:42-------------------
+
+--------------------------------------------------*/
+BOOL SwPostItField::QueryValue( uno::Any& rAny, const String& rProperty ) const
+{
+    if(rProperty.EqualsAscii(UNO_NAME_AUTHOR))
+        rAny <<= OUString(sAuthor);
+    else if(rProperty.EqualsAscii(UNO_NAME_CONTENT))
+        rAny <<= OUString(sTxt);
+    else if(rProperty.EqualsAscii(UNO_NAME_DATE))
+    {
+        util::Date aSetDate;
+        aSetDate.Day = aDate.GetDay();
+        aSetDate.Month = aDate.GetMonth();
+        aSetDate.Year = aDate.GetYear();
+        rAny.setValue(&aSetDate, ::getCppuType((util::Date*)0));
+    }
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return sal_True;
+}
+/*-----------------05.03.98 13:42-------------------
+
+--------------------------------------------------*/
+BOOL SwPostItField::PutValue( const uno::Any& rAny, const String& rProperty )
+{
+    if(rProperty.EqualsAscii(UNO_NAME_AUTHOR))
+    {
+        OUString uTmp;
+        rAny >>= uTmp;
+        sAuthor = String(uTmp);
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_CONTENT))
+    {
+        OUString uTmp;
+        rAny >>= uTmp;
+        sTxt = String(uTmp);
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_DATE) &&
+        rAny.getValueType() == ::getCppuType((util::Date*)0))
+    {
+        util::Date aSetDate = *(util::Date*)rAny.getValue();
+        aDate = Date(aSetDate.Day, aSetDate.Month, aSetDate.Year);
+    }
+
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return sal_True;
+}
+/*--------------------------------------------------------------------
+    Beschreibung: DokumentinfoFields
+ --------------------------------------------------------------------*/
+
+SwExtUserFieldType::SwExtUserFieldType()
+    : SwFieldType( RES_EXTUSERFLD )
+{
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+SwFieldType* SwExtUserFieldType::Copy() const
+{
+    SwExtUserFieldType* pType = new SwExtUserFieldType;
+    return pType;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+String SwExtUserFieldType::Expand(sal_uInt16 nSub, sal_uInt32 nFormat) const
+{
+    SvxAddressItem aAdr( pPathFinder->GetAddress() );
+    String aRet( aEmptyStr );
+    sal_uInt16 nRet = USHRT_MAX;
+    switch(nSub)
+    {
+    case EU_FIRSTNAME:      aRet = aAdr.GetFirstName(); break;
+    case EU_NAME:           aRet = aAdr.GetName();      break;
+    case EU_SHORTCUT:       aRet = aAdr.GetShortName(); break;
+
+    case EU_COMPANY:        nRet = ADDRESS_COMPANY;     break;
+    case EU_STREET:         nRet = ADDRESS_STREET;      break;
+    case EU_TITLE:          nRet = ADDRESS_TITLE;       break;
+    case EU_POSITION:       nRet = ADDRESS_POSITION;    break;
+    case EU_PHONE_PRIVATE:  nRet = ADDRESS_TEL_PRIVATE; break;
+    case EU_PHONE_COMPANY:  nRet = ADDRESS_TEL_COMPANY; break;
+    case EU_FAX:            nRet = ADDRESS_FAX;         break;
+    case EU_EMAIL:          nRet = ADDRESS_EMAIL;       break;
+    case EU_COUNTRY:        nRet = ADDRESS_COUNTRY;     break;
+    case EU_ZIP:            nRet = ADDRESS_PLZ;         break;
+    case EU_CITY:           nRet = ADDRESS_CITY;        break;
+    case EU_STATE:          nRet = ADDRESS_STATE;       break;
+    case EU_FATHERSNAME:    nRet = ADDRESS_FATHERSNAME;     break;
+    case EU_APARTMENT:      nRet = ADDRESS_APARTMENT;       break;
+    default:                ASSERT( !this, "Field unknown");
+    }
+    if( USHRT_MAX != nRet )
+        aRet = aAdr.GetToken( nRet );
+    return aRet;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+SwExtUserField::SwExtUserField(SwExtUserFieldType* pType, sal_uInt16 nSubTyp, sal_uInt32 nFmt) :
+    SwField(pType, nFmt), nType(nSubTyp)
+{
+    aContent = ((SwExtUserFieldType*)GetTyp())->Expand(nType, GetFormat());
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+String SwExtUserField::Expand() const
+{
+    if (!IsFixed())
+        ((SwExtUserField*)this)->aContent = ((SwExtUserFieldType*)GetTyp())->Expand(nType, GetFormat());
+
+    return aContent;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+SwField* SwExtUserField::Copy() const
+{
+    SwExtUserField* pFld = new SwExtUserField((SwExtUserFieldType*)GetTyp(), nType, GetFormat());
+    pFld->SetExpansion(aContent);
+
+    return pFld;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_uInt16 SwExtUserField::GetSubType() const
+{
+    return nType;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SwExtUserField::SetSubType(sal_uInt16 nSub)
+{
+    nType = nSub;
+}
+
+/*-----------------05.03.98 14:14-------------------
+
+--------------------------------------------------*/
+BOOL SwExtUserField::QueryValue( uno::Any& rAny, const String& rProperty ) const
+{
+    if(rProperty.EqualsAscii(UNO_NAME_USER_DATA_TYPE))
+    {
+        sal_Int16 nTmp = nType;
+        rAny <<= nTmp;
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_CONTENT)||
+        rProperty.EqualsAscii(UNO_NAME_CURRENT_PRESENTATION))
+        rAny <<= OUString(aContent);
+    else if(rProperty.EqualsAscii(UNO_NAME_IS_FIXED))
+    {
+        sal_Bool bTmp = IsFixed();
+        rAny.setValue(&bTmp, ::getBooleanCppuType());
+    }
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return sal_True;
+}
+/*-----------------05.03.98 14:14-------------------
+
+--------------------------------------------------*/
+BOOL SwExtUserField::PutValue( const uno::Any& rAny, const String& rProperty )
+{
+    if(rProperty.EqualsAscii(UNO_NAME_USER_DATA_TYPE))
+    {
+        sal_Int16 nTmp;
+        rAny >>= nTmp;
+        nType = nTmp;
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_CONTENT)||
+        rProperty.EqualsAscii(UNO_NAME_CURRENT_PRESENTATION))
+    {
+        OUString uTmp;
+        rAny >>= uTmp;
+        aContent = String(uTmp);
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_IS_FIXED))
+    {
+        sal_Bool bSet = *(sal_Bool*)rAny.getValue();
+        if(bSet)
+            SetFormat(GetFormat() | AF_FIXED);
+        else
+            SetFormat(GetFormat() & ~AF_FIXED);
+    }
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return sal_True;
+}
+//-------------------------------------------------------------------------
+
+/*--------------------------------------------------------------------
+    Beschreibung: Relatives Seitennummern - Feld
+ --------------------------------------------------------------------*/
+
+SwRefPageSetFieldType::SwRefPageSetFieldType()
+    : SwFieldType( RES_REFPAGESETFLD )
+{
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+SwFieldType* SwRefPageSetFieldType::Copy() const
+{
+    return new SwRefPageSetFieldType;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+// ueberlagert, weil es nichts zum Updaten gibt!
+void SwRefPageSetFieldType::Modify( SfxPoolItem *, SfxPoolItem * )
+{
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Relative Seitennummerierung
+ --------------------------------------------------------------------*/
+
+SwRefPageSetField::SwRefPageSetField( SwRefPageSetFieldType* pType,
+                    short nOff, sal_Bool bFlag )
+    : SwField( pType ), nOffset( nOff ), bOn( bFlag )
+{
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+String SwRefPageSetField::Expand() const
+{
+    return aEmptyStr;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+SwField* SwRefPageSetField::Copy() const
+{
+    return new SwRefPageSetField( (SwRefPageSetFieldType*)GetTyp(), nOffset, bOn );
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+String SwRefPageSetField::GetPar2() const
+{
+    return String::CreateFromInt32(GetOffset());
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SwRefPageSetField::SetPar2(const String& rStr)
+{
+    SetOffset(rStr.ToInt32());
+}
+
+/*-----------------05.03.98 14:52-------------------
+
+--------------------------------------------------*/
+BOOL SwRefPageSetField::QueryValue( uno::Any& rAny, const String& rProperty ) const
+{
+    if(rProperty.EqualsAscii(UNO_NAME_ON))
+        rAny.setValue(&bOn, ::getBooleanCppuType());
+    else if( rProperty.EqualsAscii(UNO_NAME_OFFSET ))
+        rAny <<= (sal_Int16)nOffset;
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return sal_True;
+}
+/*-----------------05.03.98 14:52-------------------
+
+--------------------------------------------------*/
+BOOL SwRefPageSetField::PutValue( const uno::Any& rAny, const String& rProperty )
+{
+    if(rProperty.EqualsAscii(UNO_NAME_ON))
+        bOn = *(sal_Bool*)rAny.getValue();
+    else if( rProperty.EqualsAscii(UNO_NAME_OFFSET ))
+        rAny >>=nOffset;
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return sal_True;
+}
+/*--------------------------------------------------------------------
+    Beschreibung: relatives Seitennummern - Abfrage Feld
+ --------------------------------------------------------------------*/
+
+SwRefPageGetFieldType::SwRefPageGetFieldType( SwDoc* pDc )
+    : SwFieldType( RES_REFPAGEGETFLD ), eNumFormat( SVX_NUM_ARABIC ), pDoc( pDc )
+{
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+SwFieldType* SwRefPageGetFieldType::Copy() const
+{
+    SwRefPageGetFieldType* pNew = new SwRefPageGetFieldType( pDoc );
+    pNew->eNumFormat = eNumFormat;
+    return pNew;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SwRefPageGetFieldType::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew )
+{
+    // Update auf alle GetReferenz-Felder
+    if( !pNew && !pOld && GetDepends() )
+    {
+        // sammel erstmal alle SetPageRefFelder ein.
+        _SetGetExpFlds aTmpLst( 10, 5 );
+        if( MakeSetList( aTmpLst ) )
+        {
+            SwClientIter aIter( *this );
+            if( aIter.GoStart() )
+                do {
+                    // nur die GetRef-Felder Updaten
+                    SwFmtFld* pFmtFld = (SwFmtFld*)aIter();
+                    if( pFmtFld->GetTxtFld() )
+                        UpdateField( pFmtFld->GetTxtFld(), aTmpLst );
+                } while( aIter++ );
+        }
+    }
+
+    // weiter an die Text-Felder, diese "Expandieren" den Text
+    SwModify::Modify( pOld, pNew );
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_uInt16 SwRefPageGetFieldType::MakeSetList( _SetGetExpFlds& rTmpLst )
+{
+    SwClientIter aIter( *pDoc->GetSysFldType( RES_REFPAGESETFLD));
+    if( aIter.GoStart() )
+        do {
+            // nur die GetRef-Felder Updaten
+            SwFmtFld* pFmtFld = (SwFmtFld*)aIter();
+            const SwTxtFld* pTFld = pFmtFld->GetTxtFld();
+            if( pTFld )
+            {
+                const SwTxtNode& rTxtNd = pTFld->GetTxtNode();
+
+                // immer den ersten !! (in Tab-Headline, Kopf-/Fuss )
+                Point aPt;
+                const SwCntntFrm* pFrm = rTxtNd.GetFrm( &aPt, 0, sal_False );
+
+                _SetGetExpFld* pNew;
+
+                if( !pFrm || pFrm->IsInDocBody() )
+                {
+                    // einen sdbcx::Index fuers bestimmen vom TextNode anlegen
+                    SwNodeIndex aIdx( rTxtNd );
+                    pNew = new _SetGetExpFld( aIdx, pTFld );
+                }
+                else
+                {
+                    // einen sdbcx::Index fuers bestimmen vom TextNode anlegen
+                    SwPosition aPos( pDoc->GetNodes().GetEndOfPostIts() );
+#ifndef PRODUCT
+                    ASSERT( GetBodyTxtNode( *pDoc, aPos, *pFrm ),
+                            "wo steht das Feld" );
+#else
+                    GetBodyTxtNode( *pDoc, aPos, *pFrm );
+#endif
+                    pNew = new _SetGetExpFld( aPos.nNode, pTFld,
+                                                &aPos.nContent );
+                }
+
+                if( !rTmpLst.Insert( pNew ))
+                    delete pNew;
+            }
+        } while( aIter++ );
+
+    return rTmpLst.Count();
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SwRefPageGetFieldType::UpdateField( SwTxtFld* pTxtFld,
+                                        _SetGetExpFlds& rSetList )
+{
+    SwRefPageGetField* pGetFld = (SwRefPageGetField*)pTxtFld->GetFld().GetFld();
+    pGetFld->SetText( aEmptyStr );
+
+    // dann suche mal das richtige RefPageSet-Field
+    SwTxtNode* pTxtNode = (SwTxtNode*)&pTxtFld->GetTxtNode();
+    if( pTxtNode->StartOfSectionIndex() >
+        pDoc->GetNodes().GetEndOfExtras().GetIndex() )
+    {
+        SwNodeIndex aIdx( *pTxtNode );
+        _SetGetExpFld aEndFld( aIdx, pTxtFld );
+
+        sal_uInt16 nLast;
+        rSetList.Seek_Entry( &aEndFld, &nLast );
+
+        if( nLast-- )
+        {
+            const SwTxtFld* pRefTxtFld = rSetList[ nLast ]->GetFld();
+            const SwRefPageSetField* pSetFld =
+                        (SwRefPageSetField*)pRefTxtFld->GetFld().GetFld();
+            if( pSetFld->IsOn() )
+            {
+                // dann bestimme mal den entsp. Offset
+                Point aPt;
+                const SwCntntFrm* pFrm = pTxtNode->GetFrm( &aPt, 0, sal_False );
+                const SwCntntFrm* pRefFrm = pRefTxtFld->GetTxtNode().GetFrm( &aPt, 0, sal_False );
+                const SwPageFrm* pPgFrm = 0;
+                sal_uInt16 nDiff = ( pFrm && pRefFrm )
+                        ?   (pPgFrm = pFrm->FindPageFrm())->GetPhyPageNum() -
+                            pRefFrm->FindPageFrm()->GetPhyPageNum() + 1
+                        : 1;
+
+                sal_uInt32 nTmpFmt = SVX_NUM_PAGEDESC == pGetFld->GetFormat()
+                        ? ( !pPgFrm
+                                ? SVX_NUM_ARABIC
+                                : pPgFrm->GetPageDesc()->GetNumType().eType )
+                        : pGetFld->GetFormat();
+                short nPageNum = Max(0, pSetFld->GetOffset() + (short)nDiff);
+                pGetFld->SetText( FormatNumber( nPageNum, nTmpFmt ) );
+            }
+        }
+    }
+    // dann die Formatierung anstossen
+    ((SwFmtFld&)pTxtFld->GetFld()).Modify( 0, 0 );
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Relative Seitennummerierung Abfragen
+ --------------------------------------------------------------------*/
+
+SwRefPageGetField::SwRefPageGetField( SwRefPageGetFieldType* pType,
+                                    sal_uInt32 nFmt )
+    : SwField( pType, nFmt )
+{
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+String SwRefPageGetField::Expand() const
+{
+    return sTxt;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+SwField* SwRefPageGetField::Copy() const
+{
+    SwRefPageGetField* pCpy = new SwRefPageGetField(
+                        (SwRefPageGetFieldType*)GetTyp(), GetFormat() );
+    pCpy->SetText( sTxt );
+    return pCpy;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SwRefPageGetField::ChangeExpansion( const SwFrm* pFrm,
+                                        const SwTxtFld* pFld )
+{
+    // nur Felder in Footer, Header, FootNote, Flys
+    SwTxtNode* pTxtNode = (SwTxtNode*)&pFld->GetTxtNode();
+    SwRefPageGetFieldType* pGetType = (SwRefPageGetFieldType*)GetTyp();
+    SwDoc* pDoc = pGetType->GetDoc();
+    if( pFld->GetTxtNode().StartOfSectionIndex() >
+        pDoc->GetNodes().GetEndOfExtras().GetIndex() )
+        return;
+
+    sTxt.Erase();
+
+    ASSERT( !pFrm->IsInDocBody(), "Flag ist nicht richtig, Frame steht im DocBody" );
+
+    // sammel erstmal alle SetPageRefFelder ein.
+    _SetGetExpFlds aTmpLst( 10, 5 );
+    if( !pGetType->MakeSetList( aTmpLst ) )
+        return ;
+
+    // einen sdbcx::Index fuers bestimmen vom TextNode anlegen
+    SwPosition aPos( SwNodeIndex( pDoc->GetNodes() ) );
+    pTxtNode = (SwTxtNode*) GetBodyTxtNode( *pDoc, aPos, *pFrm );
+
+    // Wenn kein Layout vorhanden, kommt es in Kopf und Fusszeilen dazu
+    // das ChangeExpansion uebers Layout-Formatieren aufgerufen wird
+    // aber kein TxtNode vorhanden ist
+    //
+    if(!pTxtNode)
+        return;
+
+    _SetGetExpFld aEndFld( aPos.nNode, pFld, &aPos.nContent );
+
+    sal_uInt16 nLast;
+    aTmpLst.Seek_Entry( &aEndFld, &nLast );
+
+    if( !nLast-- )
+        return ;        // es gibt kein entsprechendes Set - Feld vor mir
+
+    const SwTxtFld* pRefTxtFld = aTmpLst[ nLast ]->GetFld();
+    const SwRefPageSetField* pSetFld =
+                        (SwRefPageSetField*)pRefTxtFld->GetFld().GetFld();
+    if( pSetFld->IsOn() )
+    {
+        // dann bestimme mal den entsp. Offset
+        Point aPt;
+        const SwCntntFrm* pRefFrm = pRefTxtFld->GetTxtNode().GetFrm( &aPt, 0, sal_False );
+        const SwPageFrm* pPgFrm = pFrm->FindPageFrm();
+        sal_uInt16 nDiff = pPgFrm->GetPhyPageNum() -
+                            pRefFrm->FindPageFrm()->GetPhyPageNum() + 1;
+
+        SwRefPageGetField* pGetFld = (SwRefPageGetField*)pFld->GetFld().GetFld();
+        sal_uInt32 nTmpFmt = SVX_NUM_PAGEDESC == pGetFld->GetFormat()
+                            ? pPgFrm->GetPageDesc()->GetNumType().eType
+                            : pGetFld->GetFormat();
+        short nPageNum = Max(0, pSetFld->GetOffset() + (short)nDiff );
+        pGetFld->SetText( FormatNumber( nPageNum, nTmpFmt ) );
+    }
+}
+/*-----------------05.03.98 14:52-------------------
+
+--------------------------------------------------*/
+BOOL SwRefPageGetField::QueryValue( uno::Any& rAny, const String& rProperty ) const
+{
+    if(rProperty.EqualsAscii(UNO_NAME_NUMBERING_TYPE))
+    {
+        rAny <<= (sal_Int16)GetFormat();
+    }
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return sal_True;
+}
+/*-----------------05.03.98 14:52-------------------
+
+--------------------------------------------------*/
+BOOL SwRefPageGetField::PutValue( const uno::Any& rAny, const String& rProperty )
+{
+    if(rProperty.EqualsAscii(UNO_NAME_NUMBERING_TYPE ))
+    {
+        sal_Int16 nSet;
+        rAny >>= nSet;
+        if(nSet <= SVX_NUM_PAGEDESC )
+            SetFormat(nSet);
+        else
+            //exception(wrong_value)
+            ;
+    }
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return sal_True;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Feld zum Anspringen und Editieren
+ --------------------------------------------------------------------*/
+
+SwJumpEditFieldType::SwJumpEditFieldType( SwDoc* pD )
+    : SwFieldType( RES_JUMPEDITFLD ), pDoc( pD ), aDep( this, 0 )
+{
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+SwFieldType* SwJumpEditFieldType::Copy() const
+{
+    return new SwJumpEditFieldType( pDoc );
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+SwCharFmt* SwJumpEditFieldType::GetCharFmt()
+{
+    SwCharFmt* pFmt = pDoc->GetCharFmtFromPool( RES_POOLCHR_JUMPEDIT );
+
+    // noch nicht registriert ?
+    if( !aDep.GetRegisteredIn() )
+        pFmt->Add( &aDep );     // anmelden
+
+    return pFmt;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+SwJumpEditField::SwJumpEditField( SwJumpEditFieldType* pTyp, sal_uInt32 nFormat,
+                                const String& rTxt, const String& rHelp )
+    : SwField( pTyp, nFormat ), sTxt( rTxt ), sHelp( rHelp )
+{
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+String SwJumpEditField::Expand() const
+{
+    String sTmp( '<' );
+    sTmp += sTxt;
+    return sTmp += '>';
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+SwField* SwJumpEditField::Copy() const
+{
+    return new SwJumpEditField( (SwJumpEditFieldType*)GetTyp(), GetFormat(),
+                                sTxt, sHelp );
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+// Platzhalter-Text
+
+const String& SwJumpEditField::GetPar1() const
+{
+    return sTxt;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SwJumpEditField::SetPar1(const String& rStr)
+{
+    sTxt = rStr;
+}
+
+// HinweisText
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+String SwJumpEditField::GetPar2() const
+{
+    return sHelp;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SwJumpEditField::SetPar2(const String& rStr)
+{
+    sHelp = rStr;
+}
+
+/*-----------------05.03.98 15:00-------------------
+
+--------------------------------------------------*/
+BOOL SwJumpEditField::QueryValue( uno::Any& rAny, const String& rProperty ) const
+{
+    if(rProperty.EqualsAscii(UNO_NAME_PLACEHOLDER_TYPE))
+    {
+        sal_Int16 nRet;
+        switch( GetFormat() )
+        {
+            case JE_FMT_TEXT:   nRet = text::PlaceholderType::TEXT; break;
+            case JE_FMT_TABLE:  nRet = text::PlaceholderType::TABLE; break;
+            case JE_FMT_FRAME:  nRet = text::PlaceholderType::TEXTFRAME; break;
+            case JE_FMT_GRAPHIC:nRet = text::PlaceholderType::GRAPHIC; break;
+            //case JE_FMT_OLE:
+            default: nRet = nRet = text::PlaceholderType::OBJECT;
+        }
+        rAny <<= nRet;
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_HINT))
+        rAny <<= OUString(sHelp);
+    else if( rProperty.EqualsAscii(UNO_NAME_PLACEHOLDER ))
+         rAny <<= OUString(sTxt);
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return sal_True;
+}
+/*-----------------05.03.98 15:00-------------------
+
+--------------------------------------------------*/
+BOOL SwJumpEditField::PutValue( const uno::Any& rAny, const String& rProperty )
+{
+    if(rProperty.EqualsAscii(UNO_NAME_PLACEHOLDER_TYPE))
+    {
+        sal_Int16 nSet;
+        rAny >>= nSet;
+        switch( nSet )
+        {
+            case text::PlaceholderType::TEXT     : SetFormat(JE_FMT_TEXT); break;
+            case text::PlaceholderType::TABLE    : SetFormat(JE_FMT_TABLE); break;
+            case text::PlaceholderType::TEXTFRAME: SetFormat(JE_FMT_FRAME); break;
+            case text::PlaceholderType::GRAPHIC  : SetFormat(JE_FMT_GRAPHIC); break;
+            case text::PlaceholderType::OBJECT   : SetFormat(JE_FMT_OLE); break;
+        }
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_HINT))
+    {
+        OUString uTmp;
+        rAny >>= uTmp;
+        sHelp = String(uTmp);
+    }
+    else if( rProperty.EqualsAscii(UNO_NAME_PLACEHOLDER ))
+    {
+        OUString uTmp;
+        rAny >>= uTmp;
+        sTxt = String(uTmp);
+    }
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return sal_True;
+}
diff --git a/sw/source/core/fields/expfld.cxx b/sw/source/core/fields/expfld.cxx
new file mode 100644
index 000000000000..1ef398f16f70
--- /dev/null
+++ b/sw/source/core/fields/expfld.cxx
@@ -0,0 +1,1309 @@
+/*************************************************************************
+ *
+ *  $RCSfile: expfld.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:19 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include 
+
+#ifndef _INTN_HXX //autogen
+#include 
+#endif
+#ifndef _TOOLS_RESID_HXX //autogen
+#include 
+#endif
+#ifndef _SV_SVAPP_HXX //autogen
+#include 
+#endif
+#ifndef _UNOTOOLS_CHARCLASS_HXX
+#include 
+#endif
+
+
+#ifndef _FMTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFTN_HXX //autogen
+#include 
+#endif
+#ifndef _FRMFMT_HXX //autogen
+#include 
+#endif
+#ifndef _CHARATR_HXX
+#include 
+#endif
+#ifndef _SVX_PAGEITEM_HXX //autogen
+#include 
+#endif
+#ifndef _UNOPRNMS_HXX
+#include 
+#endif
+#ifndef _SVX_LANGITEM_HXX //autogen wg. SvxLanguageItem
+#include 
+#endif
+#ifndef _SVX_FONTITEM_HXX //autogen wg. SvxFontItem
+#include 
+#endif
+
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _LAYFRM_HXX
+#include 
+#endif
+#ifndef _PAGEFRM_HXX
+#include 
+#endif
+#ifndef _CNTFRM_HXX
+#include 
+#endif
+#ifndef _ROOTFRM_HXX
+#include 
+#endif
+#ifndef _EXPFLD_HXX
+#include 
+#endif
+#ifndef _USRFLD_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _FLYFRM_HXX
+#include 
+#endif
+#ifndef _FTNFRM_HXX
+#include 
+#endif
+#ifndef _CALC_HXX
+#include          // SwGetExpField
+#endif
+#ifndef _PAM_HXX
+#include           // SwGet-/SetExpField
+#endif
+#ifndef _DOCFLD_HXX
+#include        // SwGet-/SetExpField
+#endif
+#ifndef _SWCACHE_HXX
+#include       // SwGet-/SetExpField
+#endif
+#ifndef _COM_SUN_STAR_TEXT_SETVARIABLETYPE_HPP_
+#include 
+#endif
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::text;
+using namespace ::rtl;
+
+SV_IMPL_PTRARR( _SwSeqFldList, _SeqFldLstElem* )
+
+//-----------------------------------------------------------------------------
+sal_Int16 lcl_SubTypeToAPI(USHORT nSubType)
+{
+        sal_Int16 nRet;
+        switch(nSubType)
+        {
+            case GSE_EXPR   :   nRet = SetVariableType::VAR /*0*/; break;
+            case GSE_SEQ    :   nRet = SetVariableType::SEQUENCE /*1*/; break;
+            case GSE_FORMULA:   nRet = SetVariableType::FORMULA /*2*/; break;
+            case GSE_STRING :   nRet = SetVariableType::STRING /*3*/; break;
+        }
+        return nRet;
+}
+//-----------------------------------------------------------------------------
+sal_Int32 lcl_APIToSubType(const uno::Any& rAny)
+{
+        sal_Int16 nVal;
+        rAny >>= nVal;
+        sal_Int32 nSet = 0;
+        switch(nVal)
+        {
+            case SetVariableType::VAR:      nSet = GSE_EXPR;  break;
+            case SetVariableType::SEQUENCE: nSet = GSE_SEQ;  break;
+            case SetVariableType::FORMULA:  nSet = GSE_FORMULA; break;
+            case SetVariableType::STRING:   nSet = GSE_STRING;  break;
+            default:
+                DBG_ERROR("wrong value")
+                nSet = -1;
+        }
+        return nSet;
+}
+//-----------------------------------------------------------------------------
+
+void ReplacePoint( String& rTmpName )
+{
+    // Ersten und letzten Punkt ersetzen, da in Tabellennamen Punkte erlaubt sind
+    xub_StrLen nLen = rTmpName.Len();
+    sal_Unicode *pStr = rTmpName.GetBufferAccess(), *pBackStr = pStr + nLen;
+
+    for( xub_StrLen i = nLen; i; --i, pBackStr-- )
+        if( '.' == *pBackStr )
+        {
+            *pBackStr = DB_DELIM;
+            break;
+        }
+    for( i = 0; i < nLen; ++i, ++pStr )
+        if( '.' == *pStr )
+        {
+            *pStr = DB_DELIM;
+            break;
+        }
+}
+
+SwTxtNode* GetFirstTxtNode( const SwDoc& rDoc, SwPosition& rPos,
+                            const SwCntntFrm *pCFrm, Point &rPt )
+{
+    SwTxtNode* pTxtNode;
+    if ( !pCFrm )
+    {
+        rPos.nNode = *rDoc.GetNodes().GetEndOfContent().StartOfSectionNode();
+        SwCntntNode* pCNd;
+        while( 0 != (pCNd = rDoc.GetNodes().GoNext( &rPos.nNode ) ) &&
+                0 == ( pTxtNode = pCNd->GetTxtNode() ) )
+                        ;
+        ASSERT( pTxtNode, "wo ist der 1.TextNode" );
+        rPos.nContent.Assign( pTxtNode, 0 );
+    }
+    else if ( !pCFrm->IsValid() )
+    {
+        pTxtNode = (SwTxtNode*)pCFrm->GetNode();
+        rPos.nNode = *pTxtNode;
+        rPos.nContent.Assign( pTxtNode, 0 );
+    }
+    else
+    {
+        pCFrm->GetCrsrOfst( &rPos, rPt );
+        pTxtNode = rPos.nNode.GetNode().GetTxtNode();
+    }
+    return pTxtNode;
+}
+
+const SwTxtNode* GetBodyTxtNode( const SwDoc& rDoc, SwPosition& rPos,
+                                const SwFrm& rFrm )
+{
+    const SwLayoutFrm* pLayout = (SwLayoutFrm*)rFrm.GetUpper();
+    const SwTxtNode* pTxtNode = 0;
+
+    while( pLayout )
+    {
+        if( pLayout->IsFlyFrm() )
+        {
+            // hole das FlyFormat
+            SwFrmFmt* pFlyFmt = ((SwFlyFrm*)pLayout)->GetFmt();
+            ASSERT( pFlyFmt, "kein FlyFormat gefunden, wo steht das Feld" );
+
+            const SwFmtAnchor &rAnchor = pFlyFmt->GetAnchor();
+
+            if( FLY_AT_FLY == rAnchor.GetAnchorId() )
+            {
+                // und der Fly muss irgendwo angehaengt sein, also
+                // den befragen
+                pLayout = (SwLayoutFrm*)((SwFlyFrm*)pLayout)->GetAnchor();
+                continue;
+            }
+            else if( FLY_AT_CNTNT == rAnchor.GetAnchorId() ||
+                     FLY_AUTO_CNTNT == rAnchor.GetAnchorId() ||
+                     FLY_IN_CNTNT == rAnchor.GetAnchorId() )
+            {
+                ASSERT( rAnchor.GetCntntAnchor(), "keine gueltige Position" );
+                rPos = *rAnchor.GetCntntAnchor();
+                pTxtNode = rPos.nNode.GetNode().GetTxtNode();
+                if( FLY_AT_CNTNT == rAnchor.GetAnchorId() )
+                    ((SwTxtNode*)pTxtNode)->MakeStartIndex( &rPos.nContent );
+// oder doch besser das Ende vom (Anker-)TextNode nehmen ??
+//                  ((SwTxtNode*)pTxtNode)->MakeEndIndex( &rPos.nContent );
+
+                // noch nicht abbrechen, kann ja auch noch im
+                // Header/Footer/Footnote/Fly stehen !!
+                pLayout = ((SwFlyFrm*)pLayout)->GetAnchor()
+                            ? ((SwFlyFrm*)pLayout)->GetAnchor()->GetUpper() : 0;
+                continue;
+            }
+            else
+            {
+                pLayout->FindPageFrm()->GetCntntPosition(
+                                                pLayout->Frm().Pos(), rPos );
+                pTxtNode = rPos.nNode.GetNode().GetTxtNode();
+            }
+        }
+        else if( pLayout->IsFtnFrm() )
+        {
+            // hole den Node vom Anker
+            const SwTxtFtn* pFtn = ((SwFtnFrm*)pLayout)->GetAttr();
+            pTxtNode = &pFtn->GetTxtNode();
+            rPos.nNode = *pTxtNode;
+            rPos.nContent = *pFtn->GetStart();
+        }
+        else if( pLayout->IsHeaderFrm() || pLayout->IsFooterFrm() )
+        {
+            const SwCntntFrm* pCntFrm;
+            const SwPageFrm* pPgFrm = pLayout->FindPageFrm();
+            if( pLayout->IsHeaderFrm() )
+                pCntFrm = pPgFrm->FindFirstBodyCntnt();
+            else
+                pCntFrm = pPgFrm->FindLastBodyCntnt();
+
+            if( pCntFrm )
+            {
+                pTxtNode = pCntFrm->GetNode()->GetTxtNode();
+                rPos.nNode = *pTxtNode;
+                ((SwTxtNode*)pTxtNode)->MakeEndIndex( &rPos.nContent );
+            }
+            else
+            {
+                Point aPt( pLayout->Frm().Pos() );
+                aPt.Y()++;      // aus dem Header raus
+                pCntFrm = pPgFrm->GetCntntPos( aPt, FALSE, TRUE, FALSE );
+                pTxtNode = GetFirstTxtNode( rDoc, rPos, pCntFrm, aPt );
+            }
+        }
+        else
+        {
+            pLayout = pLayout->GetUpper();
+            continue;
+        }
+        break;      // gefunden und beende die Schleife
+    }
+    return pTxtNode;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: SwSetExpFieldType by JP
+ --------------------------------------------------------------------*/
+
+SwGetExpFieldType::SwGetExpFieldType(SwDoc* pDoc)
+    : SwValueFieldType( pDoc, RES_GETEXPFLD )
+{
+}
+
+SwFieldType* SwGetExpFieldType::Copy() const
+{
+    return new SwGetExpFieldType(GetDoc());
+}
+
+void SwGetExpFieldType::Modify( SfxPoolItem*, SfxPoolItem* pNew )
+{
+    if( pNew && RES_DOCPOS_UPDATE == pNew->Which() )
+        SwModify::Modify( 0, pNew );
+    // sonst nichts weiter expandieren
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: SwGetExpField by JP
+ --------------------------------------------------------------------*/
+
+SwGetExpField::SwGetExpField(SwGetExpFieldType* pTyp, const String& rFormel,
+                            USHORT nSub, ULONG nFmt)
+    : SwFormulaField( pTyp, nFmt, 0.0 ),
+    nSubType(nSub),
+    bIsInBodyTxt( TRUE )
+{
+    SetFormula( rFormel );
+}
+
+String SwGetExpField::Expand() const
+{
+    if(nSubType & SUB_CMD)
+        return GetFormula();
+    else
+        return sExpand;
+}
+
+String SwGetExpField::GetCntnt(BOOL bName) const
+{
+    if ( bName )
+    {
+        String aStr( SwFieldType::GetTypeStr( GSE_FORMULA & nSubType
+                                                ? TYP_FORMELFLD
+                                                : TYP_GETFLD ) );
+        aStr += ' ';
+        aStr += GetFormula();
+        return aStr;
+    }
+    return Expand();
+}
+
+SwField* SwGetExpField::Copy() const
+{
+    SwGetExpField *pTmp = new SwGetExpField((SwGetExpFieldType*)GetTyp(),
+                                            GetFormula(), nSubType, GetFormat());
+    pTmp->SetLanguage(GetLanguage());
+    pTmp->SwValueField::SetValue(GetValue());
+    pTmp->sExpand       = sExpand;
+    pTmp->bIsInBodyTxt  = bIsInBodyTxt;
+
+    return pTmp;
+}
+
+void SwGetExpField::ChangeExpansion( const SwFrm& rFrm, const SwTxtFld& rFld )
+{
+    if( bIsInBodyTxt )      // nur Felder in Footer, Header, FootNote, Flys
+        return;
+
+    ASSERT( !rFrm.IsInDocBody(), "Flag ist nicht richtig, Frame steht im DocBody" );
+
+    // bestimme mal das Dokument (oder geht es noch einfacher?)
+    const SwTxtNode* pTxtNode = &rFld.GetTxtNode();
+    SwDoc& rDoc = *(SwDoc*)pTxtNode->GetDoc();
+
+    // einen Index fuers bestimmen vom TextNode anlegen
+    SwPosition aPos( SwNodeIndex( rDoc.GetNodes() ) );
+    pTxtNode = GetBodyTxtNode( rDoc, aPos, rFrm );
+
+    // Wenn kein Layout vorhanden, kommt es in Kopf und Fusszeilen dazu
+    // das ChnageExpansion uebers Layout-Formatieren aufgerufen wird
+    // aber kein TxtNode vorhanden ist
+    //
+    if(!pTxtNode)
+        return;
+
+    _SetGetExpFld aEndFld( aPos.nNode, &rFld, &aPos.nContent );
+    if(GetSubType() & GSE_STRING)
+    {
+        SwHash** ppHashTbl;
+        USHORT nSize;
+        rDoc.FldsToExpand( ppHashTbl, nSize, aEndFld );
+        LookString( ppHashTbl, nSize, GetFormula(), sExpand );
+        ::DeleteHashTable( ppHashTbl, nSize );      // HashTabelle loeschen
+    }
+    else
+    {
+        // fuelle den Calculator mit den Werten
+        SwCalc aCalc( rDoc );
+        rDoc.FldsToCalc( aCalc, aEndFld );
+
+        // Wert berechnen
+        SetValue(aCalc.Calculate(GetFormula()).GetDouble());
+
+        // Auswertung nach Format
+        sExpand = ((SwValueFieldType*)GetTyp())->ExpandValue(
+                                GetValue(), GetFormat(), GetLanguage());
+    }
+}
+
+String SwGetExpField::GetPar2() const
+{
+    return GetFormula();
+}
+
+void SwGetExpField::SetPar2(const String& rStr)
+{
+    SetFormula(rStr);
+}
+
+USHORT SwGetExpField::GetSubType() const
+{
+    return nSubType;
+}
+
+void SwGetExpField::SetSubType(USHORT nType)
+{
+    nSubType = nType;
+}
+
+void SwGetExpField::SetLanguage(USHORT nLng)
+{
+    if (nSubType & SUB_CMD)
+        SwField::SetLanguage(nLng);
+    else
+        SwValueField::SetLanguage(nLng);
+}
+
+/*-----------------07.03.98 16:08-------------------
+
+--------------------------------------------------*/
+BOOL SwGetExpField::QueryValue( uno::Any& rAny, const String& rProperty ) const
+{
+    if( rProperty.EqualsAscii( UNO_NAME_VALUE ))
+        rAny <<= GetValue();
+    else if( rProperty.EqualsAscii( UNO_NAME_NUMBER_FORMAT ))
+        rAny <<= (sal_Int32)GetFormat();
+    else if( rProperty.EqualsAscii( UNO_NAME_VARIABLE_SUBTYPE ))
+         rAny <<= (sal_Int16)nSubType;
+    else if( rProperty.EqualsAscii( UNO_NAME_CONTENT ))
+         rAny <<= OUString( GetFormula() );
+    else if( rProperty.EqualsAscii( UNO_NAME_SUB_TYPE ))
+    {
+        sal_Int16 nRet = lcl_SubTypeToAPI(GetSubType() & 0xff);
+        rAny <<= nRet;
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_IS_SHOW_FORMULA))
+    {
+        BOOL bTmp = 0 != (nSubType & SUB_CMD);
+        rAny.setValue(&bTmp, ::getBooleanCppuType());
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_CURRENT_PRESENTATION))
+        rAny <<= rtl::OUString(GetExpStr());
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return TRUE;
+}
+/*-----------------07.03.98 16:08-------------------
+
+--------------------------------------------------*/
+BOOL SwGetExpField::PutValue( const uno::Any& rAny, const String& rProperty )
+{
+    if( rProperty.EqualsAscii( UNO_NAME_VALUE ))
+    {
+        SetValue(*(double*) rAny.getValue());
+    }
+    else if( rProperty.EqualsAscii( UNO_NAME_NUMBER_FORMAT ))
+    {
+        sal_Int32 nTmp;
+        rAny >>= nTmp;
+        SetFormat(nTmp);
+    }
+    else if( rProperty.EqualsAscii( UNO_NAME_VARIABLE_SUBTYPE ))
+    {
+         sal_Int32 nTmp;
+         rAny >>= nTmp;
+         nSubType = nTmp;
+    }
+    else if( rProperty.EqualsAscii( UNO_NAME_CONTENT ))
+    {
+        OUString uTmp;
+        rAny >>= uTmp;
+        SetFormula( uTmp );
+    }
+    else if( rProperty.EqualsAscii( UNO_NAME_SUB_TYPE ))
+    {
+        sal_Int32 nSet = lcl_APIToSubType(rAny);
+        if(nSet >=0 )
+            SetSubType((GetSubType() & 0xff00) | nSet);
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_IS_SHOW_FORMULA))
+    {
+        sal_Bool bTmp = *(sal_Bool*) rAny.getValue();
+        if(bTmp)
+            nSubType |= SUB_CMD;
+        else
+            nSubType &= (~SUB_CMD);
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_CURRENT_PRESENTATION))
+    {
+        OUString sVal;
+        rAny >>= sVal;
+        ChgExpStr(sVal);
+    }
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return TRUE;
+}
+
+/*-----------------JP: 17.06.93 -------------------
+ Set-Expression-Type
+ --------------------------------------------------*/
+
+SwSetExpFieldType::SwSetExpFieldType( SwDoc* pDoc, const String& rName, USHORT nTyp )
+    : SwValueFieldType( pDoc, RES_SETEXPFLD ),
+    sName( rName ),
+    nType(nTyp),
+    cDelim( '.' ), nLevel( UCHAR_MAX ),
+    bDeleted( FALSE ),
+    pOutlChgNd( 0 )
+{
+    if( ( GSE_SEQ | GSE_STRING ) & nType )
+        EnableFormat(FALSE);    // Numberformatter nicht einsetzen
+}
+
+SwFieldType* SwSetExpFieldType::Copy() const
+{
+    SwSetExpFieldType* pNew = new SwSetExpFieldType(GetDoc(), sName, nType);
+    pNew->bDeleted = bDeleted;
+    pNew->cDelim = cDelim;
+    pNew->nLevel = nLevel;
+
+    return pNew;
+}
+
+const String& SwSetExpFieldType::GetName() const
+{
+    return sName;
+}
+
+void SwSetExpFieldType::Modify( SfxPoolItem*, SfxPoolItem* )
+{
+    return;     // nicht weiter expandieren
+}
+
+void SwSetExpFieldType::SetSeqFormat(ULONG nFmt)
+{
+    SwClientIter aIter(*this);
+    for( SwFmtFld* pFld = (SwFmtFld*)aIter.First( TYPE(SwFmtFld) );
+            pFld; pFld = (SwFmtFld*)aIter.Next() )
+        pFld->GetFld()->ChangeFormat( nFmt );
+}
+
+ULONG SwSetExpFieldType::GetSeqFormat()
+{
+    if( !GetDepends() )
+        return SVX_NUM_ARABIC;
+
+    SwField *pFld = ((SwFmtFld*)GetDepends())->GetFld();
+    return pFld->GetFormat();
+}
+
+USHORT SwSetExpFieldType::SetSeqRefNo( SwSetExpField& rFld )
+{
+    if( !GetDepends() || !(GSE_SEQ & nType) )
+        return USHRT_MAX;
+
+extern void InsertSort( SvUShorts& rArr, USHORT nIdx, USHORT* pInsPos = 0 );
+    SvUShorts aArr( 64 );
+
+    USHORT n;
+
+    // dann testmal, ob die Nummer schon vergeben ist oder ob eine neue
+    // bestimmt werden muss.
+    SwClientIter aIter( *this );
+    const SwTxtNode* pNd;
+    for( SwFmtFld* pF = (SwFmtFld*)aIter.First( TYPE( SwFmtFld )); pF;
+            pF = (SwFmtFld*)aIter.Next() )
+        if( pF->GetFld() != &rFld && pF->GetTxtFld() &&
+            0 != ( pNd = pF->GetTxtFld()->GetpTxtNode() ) &&
+            pNd->GetNodes().IsDocNodes() )
+            InsertSort( aArr, ((SwSetExpField*)pF->GetFld())->GetSeqNumber() );
+
+
+    // teste erstmal ob die Nummer schon vorhanden ist:
+    USHORT nNum = rFld.GetSeqNumber();
+    if( USHRT_MAX != nNum )
+    {
+        for( n = 0; n < aArr.Count(); ++n )
+            if( aArr[ n ] > nNum )
+                return nNum;            // nicht vorhanden -> also benutzen
+            else if( aArr[ n ] == nNum )
+                break;                  // schon vorhanden -> neue erzeugen
+
+        if( n == aArr.Count() )
+            return nNum;            // nicht vorhanden -> also benutzen
+    }
+
+    // alle Nummern entsprechend geflag, also bestimme die richtige Nummer
+    for( n = 0; n < aArr.Count(); ++n )
+        if( n != aArr[ n ] )
+            break;
+
+    rFld.SetSeqNumber( n );
+    return n;
+}
+
+USHORT SwSetExpFieldType::GetSeqFldList( SwSeqFldList& rList )
+{
+    if( rList.Count() )
+        rList.Remove( 0, rList.Count() );
+
+    SwClientIter aIter( *this );
+    const SwTxtNode* pNd;
+    for( SwFmtFld* pF = (SwFmtFld*)aIter.First( TYPE( SwFmtFld )); pF;
+            pF = (SwFmtFld*)aIter.Next() )
+        if( pF->GetTxtFld() &&
+            0 != ( pNd = pF->GetTxtFld()->GetpTxtNode() ) &&
+            pNd->GetNodes().IsDocNodes() )
+        {
+            _SeqFldLstElem* pNew = new _SeqFldLstElem( pNd->GetExpandTxt( 0,
+                                (*pF->GetTxtFld()->GetStart()) + 1, FALSE ),
+                            ((SwSetExpField*)pF->GetFld())->GetSeqNumber() );
+            rList.InsertSort( pNew );
+        }
+
+    return rList.Count();
+}
+
+
+void SwSetExpFieldType::SetChapter( SwSetExpField& rFld, const SwNode& rNd )
+{
+    const SwTxtNode* pTxtNd = rNd.FindOutlineNodeOfLevel( nLevel );
+    if( pTxtNd )
+    {
+        ASSERT( pTxtNd && pTxtNd->GetOutlineNum(),
+                "kein Outline TextNode" );
+
+        SwNodeNum aNum( *pTxtNd->GetOutlineNum() );
+        if( nLevel < aNum.GetLevel() )
+            aNum.SetLevel( nLevel );
+
+        // nur die Nummer besorgen, ohne Pre-/Post-fixstrings
+        String sNumber( GetDoc()->GetOutlineNumRule()->MakeNumString(
+                                                aNum, FALSE ));
+        if( sNumber.Len() )
+            rFld.ChgExpStr(  ( sNumber += cDelim ) += rFld.GetExpStr() );
+    }
+}
+
+/* -----------------24.03.99 09:44-------------------
+ *
+ * --------------------------------------------------*/
+BOOL SwSetExpFieldType::QueryValue( uno::Any& rAny, const String& rProperty ) const
+{
+    if( rProperty.EqualsAscii( UNO_NAME_SUB_TYPE ))
+    {
+        sal_Int16 nRet = lcl_SubTypeToAPI(GetType());
+        rAny <<= nRet;
+    }
+    else if(rProperty.EqualsAscii( UNO_NAME_NUMBERING_SEPARATOR ))
+    {
+        OUString sRet(GetDelimiter());
+        rAny <<= sRet;
+    }
+    else if(rProperty.EqualsAscii( UNO_NAME_CHAPTER_NUMBERING_LEVEL ))
+    {
+        sal_Int8 nRet = nLevel < MAXLEVEL? nLevel : -1;
+        rAny <<= nRet;
+    }
+    return TRUE;
+}
+
+BOOL SwSetExpFieldType::PutValue( const uno::Any& rAny, const String& rProperty )
+{
+    BOOL bRet = FALSE;
+    if( rProperty.EqualsAscii(UNO_NAME_SUB_TYPE ) )
+    {
+        sal_Int32 nSet = lcl_APIToSubType(rAny);
+        if(nSet >=0)
+            SetType(nSet);
+    }
+    else if(rProperty.EqualsAscii( UNO_NAME_NUMBERING_SEPARATOR ))
+    {
+        OUString sDelim;
+        rAny >>= sDelim;
+        if(sDelim.getLength())
+            SetDelimiter(sDelim.getStr()[0]);
+        else
+            SetDelimiter(' ');
+    }
+    else if(rProperty.EqualsAscii( UNO_NAME_CHAPTER_NUMBERING_LEVEL ))
+    {
+        sal_Int8 nLvl;
+        rAny >>= nLvl;
+        if(nLvl < 0 || nLvl >= MAXLEVEL)
+            SetOutlineLvl(UCHAR_MAX);
+        else
+            SetOutlineLvl(nLvl);
+    }
+    return bRet;
+}
+
+BOOL SwSeqFldList::InsertSort( _SeqFldLstElem* pNew )
+{
+    sal_Unicode* p = pNew->sDlgEntry.GetBufferAccess();
+    while( *p )
+    {
+        if( *p < 0x20 )
+            *p = 0x20;
+        ++p;
+    }
+
+    USHORT nPos;
+    BOOL bRet = SeekEntry( *pNew, &nPos );
+    if( !bRet )
+        C40_INSERT( _SeqFldLstElem, pNew, nPos );
+    return bRet;
+}
+
+BOOL SwSeqFldList::SeekEntry( const _SeqFldLstElem& rNew, USHORT* pP )
+{
+    register USHORT nO = Count(), nM, nU = 0;
+    const International& rInt = Application::GetAppInternational();
+    const CharClass& rCC = GetAppCharClass();
+    if( nO > 0 )
+    {
+        //#59900# Die Sortierung soll die Nummer korrekt einordnen
+        //also "10" nach "9" und nicht "10" nach "1"
+        const String& rTmp2 = rNew.sDlgEntry;
+        xub_StrLen nFndPos2 = 0;
+        String sNum2( rTmp2.GetToken( 0, ' ', nFndPos2 ));
+        BOOL bIsNum2IsNumeric = rCC.isNumeric( sNum2 );
+        sal_Int32 nNum2 = bIsNum2IsNumeric ? sNum2.ToInt32() : 0;
+
+        nO--;
+        while( nU <= nO )
+        {
+            nM = nU + ( nO - nU ) / 2;
+
+            //#59900# Die Sortierung soll die Nummer korrekt einordnen
+            //also "10" nach "9" und nicht "10" nach "1"
+            const String& rTmp1 = (*((_SeqFldLstElem**)pData + nM))->sDlgEntry;
+            xub_StrLen nFndPos1 = 0;
+            String sNum1( rTmp1.GetToken( 0, ' ', nFndPos1 ));
+            StringCompare eCmp;
+
+            if( bIsNum2IsNumeric && rCC.isNumeric( sNum1 ) )
+            {
+                sal_Int32 nNum1 = sNum1.ToInt32();
+                eCmp = nNum2 == nNum1 ? COMPARE_EQUAL
+                                      : nNum2 >= nNum1
+                                            ? COMPARE_GREATER
+                                            : COMPARE_LESS;
+                if( COMPARE_EQUAL == eCmp )
+                    eCmp = rInt.Compare( rTmp2.Copy( nFndPos2 ),
+                                         rTmp1.Copy( nFndPos1 ));
+            }
+            else
+                eCmp = rInt.Compare( rTmp2, rTmp1, INTN_COMPARE_IGNORECASE );
+
+            if( COMPARE_EQUAL == eCmp )
+            {
+                if( pP ) *pP = nM;
+                return TRUE;
+            }
+            else if( COMPARE_GREATER == eCmp )
+                nU = nM + 1;
+            else if( nM == 0 )
+                break;
+            else
+                nO = nM - 1;
+        }
+    }
+    if( pP ) *pP = nU;
+    return FALSE;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: SwSetExpField by JP
+ --------------------------------------------------------------------*/
+
+SwSetExpField::SwSetExpField(SwSetExpFieldType* pTyp, const String& rFormel,
+                                        ULONG nFmt)
+    : SwFormulaField( pTyp, nFmt, 0.0 ), nSeqNo( USHRT_MAX ),
+    nSubType(0)
+{
+    SetFormula(rFormel);
+    // SubType ignorieren !!!
+    bInput = FALSE;
+    if( IsSequenceFld() )
+    {
+        SwValueField::SetValue(1.0);
+        if( !rFormel.Len() )
+        {
+            String sFormel(rFormel);
+            sFormel += pTyp->GetName();
+            sFormel += '+';
+            sFormel += '1';
+            SetFormula(sFormel);
+        }
+    }
+}
+
+String SwSetExpField::Expand() const
+{
+    String aStr;
+    if (nSubType & SUB_CMD)
+    {   // Der CommandString ist gefragt
+        aStr = GetTyp()->GetName();
+        aStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " = " ));
+        aStr += GetFormula();
+    }
+    else if(!(nSubType & SUB_INVISIBLE))
+    {   // Der Wert ist sichtbar
+        aStr = sExpand;
+    }
+    return aStr;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: liefert den Namen oder den Inhalt
+ --------------------------------------------------------------------*/
+
+String SwSetExpField::GetCntnt(BOOL bName) const
+{
+    if( bName )
+    {
+        USHORT nStrType;
+
+        if( IsSequenceFld() )
+            nStrType = TYP_SEQFLD;
+        else if( bInput )
+            nStrType = TYP_SETINPFLD;
+        else
+            nStrType = TYP_SETFLD;
+
+        String aStr( SwFieldType::GetTypeStr( nStrType ) );
+        aStr += ' ';
+        aStr += GetTyp()->GetName();
+
+        if( TYP_SEQFLD != nStrType )
+        {
+            // Sequence nicht die Formel ausgeben
+            aStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " = " ));
+            aStr += GetFormula();
+        }
+        return aStr;
+    }
+    return Expand();
+}
+
+SwField* SwSetExpField::Copy() const
+{
+    SwSetExpField *pTmp = new SwSetExpField((SwSetExpFieldType*)GetTyp(),
+                                            GetFormula(), GetFormat());
+    pTmp->SwValueField::SetValue(GetValue());
+    pTmp->sExpand       = sExpand;
+    pTmp->SetLanguage(GetLanguage());
+    pTmp->aPText        = aPText;
+    pTmp->bInput        = bInput;
+    pTmp->nSeqNo        = nSeqNo;
+    pTmp->SetSubType(GetSubType());
+
+    return pTmp;
+}
+
+void SwSetExpField::SetSubType(USHORT nSub)
+{
+    ((SwSetExpFieldType*)GetTyp())->SetType(nSub & 0xff);
+    nSubType = nSub & 0xff00;
+
+    DBG_ASSERT( (nSub & 0xff) != 3, "SubType ist illegal!" );
+}
+
+USHORT SwSetExpField::GetSubType() const
+{
+    return ((SwSetExpFieldType*)GetTyp())->GetType() | nSubType;
+}
+
+void SwSetExpField::SetValue( const double& rAny )
+{
+    SwValueField::SetValue(rAny);
+
+    if( IsSequenceFld() )
+        sExpand = FormatNumber( (USHORT)GetValue(), GetFormat() );
+    else
+        sExpand = ((SwValueFieldType*)GetTyp())->ExpandValue( rAny,
+                                                GetFormat(), GetLanguage());
+}
+
+void SwGetExpField::SetValue( const double& rAny )
+{
+    SwValueField::SetValue(rAny);
+    sExpand = ((SwValueFieldType*)GetTyp())->ExpandValue( rAny, GetFormat(),
+                                                            GetLanguage());
+}
+/* -----------------14.07.99 12:21-------------------
+    Description: Find the index of the reference text
+    following the current field
+ --------------------------------------------------*/
+xub_StrLen SwGetExpField::GetReferenceTextPos( const SwFmtFld& rFmt, SwDoc& rDoc)
+{
+    //
+    const SwTxtFld* pTxtFld = rFmt.GetTxtFld();
+    const SwTxtNode& rTxtNode = pTxtFld->GetTxtNode();
+    //
+    xub_StrLen nRet = *pTxtFld->GetStart() + 1;
+    String sNodeText = rTxtNode.GetTxt();
+    sNodeText.Erase(0, nRet);
+    if(sNodeText.Len())
+    {
+        //now check if sNodeText starts with a non-alphanumeric character plus a blank
+        static USHORT nIds[] =
+        {
+            RES_CHRATR_LANGUAGE, RES_CHRATR_LANGUAGE,
+            RES_CHRATR_FONT, RES_CHRATR_FONT,
+            0, 0
+        };
+        SwAttrSet aSet(rDoc.GetAttrPool(), nIds);
+        rTxtNode.GetAttr(aSet, nRet, nRet+1);
+
+        LanguageType eLang = aSet.GetLanguage().GetLanguage();
+        if( RTL_TEXTENCODING_SYMBOL != aSet.GetFont().GetCharSet())
+        {
+            International aInt( eLang );
+            sal_Unicode c0 = sNodeText.GetChar(0);
+            BOOL bIsAlphaNum = aInt.IsAlphaNumeric( c0 );
+            if(!bIsAlphaNum ||
+                (c0 == ' ' || c0 == '\t'))
+            {
+                nRet++;
+                if( sNodeText.Len() > 1 &&
+                    (sNodeText.GetChar(1) == ' ' ||
+                     sNodeText.GetChar(1) == '\t'))
+                    nRet++;
+            }
+        }
+    }
+    return nRet;
+}
+
+
+/*--------------------------------------------------------------------
+    Beschreibung: Parameter setzen
+ --------------------------------------------------------------------*/
+
+const String& SwSetExpField::GetPar1() const
+{
+    return ((SwSetExpFieldType*)GetTyp())->GetName();
+}
+
+String SwSetExpField::GetPar2() const
+{
+    USHORT nType = ((SwSetExpFieldType*)GetTyp())->GetType();
+
+    if (nType & GSE_STRING)
+        return GetFormula();
+    return GetExpandedFormula();
+}
+
+void SwSetExpField::SetPar2(const String& rStr)
+{
+    USHORT nType = ((SwSetExpFieldType*)GetTyp())->GetType();
+
+    if( !(nType & GSE_SEQ) || rStr.Len() )
+    {
+        if (nType & GSE_STRING)
+            SetFormula(rStr);
+        else
+            SetExpandedFormula(rStr);
+    }
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Eingabefeld Type
+ ---------------------------------------------------------------------*/
+
+SwInputFieldType::SwInputFieldType( SwDoc* pD )
+    : SwFieldType( RES_INPUTFLD ), pDoc( pD )
+{
+}
+
+SwFieldType* SwInputFieldType::Copy() const
+{
+    SwInputFieldType* pType = new SwInputFieldType( pDoc );
+    return pType;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Eingabefeld
+ --------------------------------------------------------------------*/
+
+SwInputField::SwInputField(SwInputFieldType* pType, const String& rContent,
+                           const String& rPrompt, USHORT nSub, ULONG nFmt) :
+    SwField(pType, nFmt), nSubType(nSub), aContent(rContent), aPText(rPrompt)
+{
+}
+
+String SwInputField::GetCntnt(BOOL bName) const
+{
+    if ( bName )
+    {
+        String aStr(SwField::GetCntnt(bName));
+        if ((nSubType & 0x00ff) == INP_USR)
+        {
+            aStr += GetTyp()->GetName();
+            aStr += ' ';
+            aStr += aContent;
+        }
+        return aStr;
+    }
+    return Expand();
+}
+
+SwField* SwInputField::Copy() const
+{
+    SwInputField* pFld = new SwInputField((SwInputFieldType*)GetTyp(), aContent,
+                                          aPText, GetSubType(), GetFormat());
+    return pFld;
+}
+
+String SwInputField::Expand() const
+{
+    String sRet;
+    if((nSubType & 0x00ff) == INP_TXT)
+        sRet = aContent;
+
+    else if( (nSubType & 0x00ff) == INP_USR )
+    {
+        SwUserFieldType* pUserTyp = (SwUserFieldType*)
+                            ((SwInputFieldType*)GetTyp())->GetDoc()->
+                            GetFldType( RES_USERFLD, aContent );
+        if( pUserTyp )
+            sRet = pUserTyp->GetContent();
+    }
+    return sRet;
+}
+
+/*-----------------06.03.98 11:12-------------------
+
+--------------------------------------------------*/
+BOOL SwInputField::QueryValue( uno::Any& rAny, const String& rProperty ) const
+{
+    if( rProperty.EqualsAscii( UNO_NAME_HINT ))
+        rAny <<= OUString( aPText );
+    else if( rProperty.EqualsAscii( UNO_NAME_CONTENT ))
+         rAny <<= OUString( aContent );
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return TRUE;
+}
+/*-----------------06.03.98 11:12-------------------
+
+--------------------------------------------------*/
+BOOL SwInputField::PutValue( const uno::Any& rAny, const String& rProperty )
+{
+    if( rProperty.EqualsAscii( UNO_NAME_HINT ))
+    {
+        OUString uTmp;
+        rAny >>= uTmp;
+        aPText = String( uTmp );
+    }
+    else if( rProperty.EqualsAscii( UNO_NAME_CONTENT ))
+    {
+        OUString uTmp;
+        rAny >>= uTmp;
+        aContent = String( uTmp );
+    }
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return TRUE;
+}
+/*--------------------------------------------------------------------
+    Beschreibung: Bedingung setzen
+ --------------------------------------------------------------------*/
+
+void SwInputField::SetPar1(const String& rStr)
+{
+    aContent = rStr;
+}
+
+const String& SwInputField::GetPar1() const
+{
+    return aContent;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: True/False Text
+ --------------------------------------------------------------------*/
+
+void SwInputField::SetPar2(const String& rStr)
+{
+    aPText = rStr;
+}
+
+String SwInputField::GetPar2() const
+{
+    return aPText;
+}
+
+USHORT SwInputField::GetSubType() const
+{
+    return nSubType;
+}
+
+void SwInputField::SetSubType(USHORT nSub)
+{
+    nSubType = nSub;
+}
+/*-----------------05.03.98 17:22-------------------
+
+--------------------------------------------------*/
+BOOL SwSetExpField::QueryValue( uno::Any& rAny, const String& rProperty ) const
+{
+    if( rProperty.EqualsAscii( UNO_NAME_IS_VISIBLE ))
+    {
+        sal_Bool bVal = 0 == (nSubType & SUB_INVISIBLE);
+        rAny.setValue(&bVal, ::getBooleanCppuType());
+    }
+    else if( rProperty.EqualsAscii( UNO_NAME_NUMBER_FORMAT ))
+        rAny <<= (sal_Int32)GetFormat();
+    else if( rProperty.EqualsAscii( UNO_NAME_NUMBERING_TYPE ))
+        rAny <<= (sal_Int16)GetFormat();
+    else if( rProperty.EqualsAscii( UNO_NAME_SEQUENCE_VALUE ))
+        rAny <<= (sal_Int16)nSeqNo;
+    else if( rProperty.EqualsAscii( UNO_NAME_VARIABLE_NAME ))
+        rAny <<= OUString( GetPar1() );
+    else if( rProperty.EqualsAscii( UNO_NAME_CONTENT ))
+         rAny <<= OUString( GetFormula() );
+    else if( rProperty.EqualsAscii( UNO_NAME_VALUE ))
+        rAny <<= (Double)GetValue();
+    else if( rProperty.EqualsAscii( UNO_NAME_SUB_TYPE ))
+    {
+        sal_Int16 nRet = 0;
+            nRet = lcl_SubTypeToAPI(GetSubType() & 0xff);
+        rAny <<= nRet;
+    }
+    else if( rProperty.EqualsAscii( UNO_NAME_HINT ))
+        rAny <<= OUString( aPText );
+    else if(rProperty.EqualsAscii(UNO_NAME_IS_SHOW_FORMULA))
+    {
+        BOOL bTmp = 0 != (nSubType & SUB_CMD);
+        rAny.setValue(&bTmp, ::getBooleanCppuType());
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_IS_INPUT))
+    {
+        BOOL bTmp = GetInputFlag();
+        rAny.setValue(&bTmp, ::getBooleanCppuType());
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_CURRENT_PRESENTATION))
+        rAny <<= rtl::OUString(GetExpStr());
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return TRUE;
+}
+/*-----------------05.03.98 17:22-------------------
+
+--------------------------------------------------*/
+BOOL SwSetExpField::PutValue( const uno::Any& rAny, const String& rProperty )
+{
+    if(rProperty.EqualsAscii( UNO_NAME_IS_VISIBLE ))
+    {
+        sal_Bool bVal = *(sal_Bool*)rAny.getValue();
+        if(bVal)
+            nSubType &= ~SUB_INVISIBLE;
+        else
+            nSubType |= SUB_INVISIBLE;
+    }
+    else if( rProperty.EqualsAscii( UNO_NAME_NUMBER_FORMAT ))
+    {
+        sal_Int32 nTmp;
+        rAny >>= nTmp;
+        SetFormat(nTmp);
+    }
+    else if( rProperty.EqualsAscii( UNO_NAME_NUMBERING_TYPE ))
+    {
+        sal_Int16 nSet;
+        rAny >>=nSet;
+        if(nSet <= SVX_NUMBER_NONE )
+            SetFormat(nSet);
+        else
+            //exception(wrong_value)
+            ;
+    }
+    else if( rProperty.EqualsAscii( UNO_NAME_SEQUENCE_VALUE ))
+    {
+        sal_Int16 nSet;
+        rAny >>=nSet;
+        nSeqNo = nSet;
+    }
+    else if( rProperty.EqualsAscii( UNO_NAME_VARIABLE_NAME ))
+    {
+        OUString uTmp;
+        rAny >>= uTmp;
+        SetPar1( uTmp );
+    }
+    else if( rProperty.EqualsAscii( UNO_NAME_CONTENT ))
+    {
+        OUString uTmp;
+        rAny >>= uTmp;
+        SetFormula( uTmp );
+    }
+    else if( rProperty.EqualsAscii( UNO_NAME_VALUE ))
+    {
+         double fVal;
+         rAny >>= fVal;
+         SetValue(fVal);
+    }
+    else if( rProperty.EqualsAscii( UNO_NAME_SUB_TYPE ))
+    {
+        sal_Int32 nSet = lcl_APIToSubType(rAny);
+        if(nSet >= 0)
+            SetSubType((GetSubType() & 0xff00) | nSet);
+    }
+    else if( rProperty.EqualsAscii( UNO_NAME_HINT ))
+    {
+        OUString uTmp;
+        rAny >>= uTmp;
+        aPText = String( uTmp );
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_IS_SHOW_FORMULA))
+    {
+        sal_Bool bTmp = *(sal_Bool*) rAny.getValue();
+        if(bTmp)
+            nSubType |= SUB_CMD;
+        else
+            nSubType &= (~SUB_CMD);
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_IS_INPUT))
+    {
+        sal_Bool bTmp = *(sal_Bool*) rAny.getValue();
+        SetInputFlag(bTmp);
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_CURRENT_PRESENTATION))
+    {
+        OUString sVal;
+        rAny >>= sVal;
+        ChgExpStr(sVal);
+    }
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return TRUE;
+}
+
+
+
diff --git a/sw/source/core/fields/fldbas.cxx b/sw/source/core/fields/fldbas.cxx
new file mode 100644
index 000000000000..efee17482b5c
--- /dev/null
+++ b/sw/source/core/fields/fldbas.cxx
@@ -0,0 +1,1024 @@
+/*************************************************************************
+ *
+ *  $RCSfile: fldbas.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:19 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+
+#include 
+#ifdef MAC
+#include 
+#endif
+#include 
+
+#ifndef _SV_SVAPP_HXX //autogen
+#include 
+#endif
+#ifndef _SV_SYSTEM_HXX //autogen
+#include 
+#endif
+#ifndef _ZFORLIST_HXX //autogen
+#include 
+#endif
+#ifndef _ZFORMAT_HXX //autogen
+#include 
+#endif
+#ifndef _TOOLS_SOLMATH_HXX //autogen wg. SolarMath
+#include 
+#endif
+#ifndef _TOOLS_INTN_HXX //autogen wg. International
+#include 
+#endif
+
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _EDITSH_HXX
+#include 
+#endif
+#ifndef _FRAME_HXX
+#include 
+#endif
+#ifndef _FLDBAS_HXX
+#include 
+#endif
+#ifndef _FLDDAT_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _FMTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _DOCFLD_HXX
+#include 
+#endif
+#ifndef _SWTABLE_HXX
+#include 
+#endif
+#ifndef _DOCFLD_HXX
+#include 
+#endif
+#ifndef _DOCUFLD_HXX
+#include 
+#endif
+#ifndef _EXPFLD_HXX
+#include 
+#endif
+#ifndef _SHELLRES_HXX
+#include 
+#endif
+using namespace ::com::sun::star;
+
+USHORT lcl_GetLanguageOfFormat( USHORT nLng, ULONG nFmt,
+                                const SvNumberFormatter& rFormatter )
+{
+    if( nLng == LANGUAGE_NONE ) // wegen Bug #60010
+        nLng = LANGUAGE_SYSTEM;
+    else if( nLng == ::GetSystemLanguage() )
+        switch( rFormatter.GetIndexTableOffset( nFmt ))
+        {
+        case NF_NUMBER_SYSTEM:
+        case NF_DATE_SYSTEM_SHORT:
+        case NF_DATE_SYSTEM_LONG:
+        case NF_DATETIME_SYSTEM_SHORT_HHMM:
+            nLng = LANGUAGE_SYSTEM;
+            break;
+        }
+    return nLng;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Globals
+ --------------------------------------------------------------------*/
+// Array der Feldname
+
+SvStringsDtor* SwFieldType::pFldNames = 0;
+
+DBG_NAME(SwFieldType);
+
+    USHORT __FAR_DATA aTypeTab[] = {
+    /* RES_DBFLD            */      TYP_DBFLD,
+    /* RES_USERFLD          */      TYP_USERFLD,
+    /* RES_FILENAMEFLD      */      TYP_FILENAMEFLD,
+    /* RES_DBNAMEFLD        */      TYP_DBNAMEFLD,
+    /* RES_DATEFLD          */      TYP_DATEFLD,
+    /* RES_TIMEFLD          */      TYP_TIMEFLD,
+    /* RES_PAGENUMBERFLD    */      TYP_PAGENUMBERFLD,  // dynamisch
+    /* RES_AUTHORFLD        */      TYP_AUTHORFLD,
+    /* RES_CHAPTERFLD       */      TYP_CHAPTERFLD,
+    /* RES_DOCSTATFLD       */      TYP_DOCSTATFLD,
+    /* RES_GETEXPFLD        */      TYP_GETFLD,         // dynamisch
+    /* RES_SETEXPFLD        */      TYP_SETFLD,         // dynamisch
+    /* RES_GETREFFLD        */      TYP_GETREFFLD,
+    /* RES_HIDDENTXTFLD     */      TYP_HIDDENTXTFLD,
+    /* RES_POSTITFLD        */      TYP_POSTITFLD,
+    /* RES_FIXDATEFLD       */      TYP_FIXDATEFLD,
+    /* RES_FIXTIMEFLD       */      TYP_FIXTIMEFLD,
+    /* RES_REGFLD           */      0,                  // alt
+    /* RES_VARREGFLD        */      0,                  // alt
+    /* RES_SETREFFLD        */      TYP_SETREFFLD,
+    /* RES_INPUTFLD         */      TYP_INPUTFLD,
+    /* RES_MACROFLD         */      TYP_MACROFLD,
+    /* RES_DDEFLD           */      TYP_DDEFLD,
+    /* RES_TABLEFLD         */      TYP_FORMELFLD,
+    /* RES_HIDDENPARAFLD    */      TYP_HIDDENPARAFLD,
+    /* RES_DOCINFOFLD       */      TYP_DOCINFOFLD,
+    /* RES_TEMPLNAMEFLD     */      TYP_TEMPLNAMEFLD,
+    /* RES_DBNEXTSETFLD     */      TYP_DBNEXTSETFLD,
+    /* RES_DBNUMSETFLD      */      TYP_DBNUMSETFLD,
+    /* RES_DBSETNUMBERFLD   */      TYP_DBSETNUMBERFLD,
+    /* RES_EXTUSERFLD       */      TYP_EXTUSERFLD,
+    /* RES_REFPAGESETFLD    */      TYP_SETREFPAGEFLD,
+    /* RES_REFPAGEGETFLD    */      TYP_GETREFPAGEFLD,
+    /* RES_INTERNETFLD      */      TYP_INTERNETFLD,
+    /* RES_JUMPEDITFLD      */      TYP_JUMPEDITFLD,
+    /* RES_SCRIPTFLD        */      TYP_SCRIPTFLD,
+    /* RES_DATETIMEFLD      */      0,                  // dynamisch
+    /* RES_AUTHORITY        */      TYP_AUTHORITY
+    };
+        // ????? TYP_USRINPFLD,
+
+
+
+const String& SwFieldType::GetTypeStr(USHORT nTypeId)
+{
+    if( !pFldNames )
+        _GetFldName();
+
+    if( nTypeId < SwFieldType::pFldNames->Count() )
+        return *SwFieldType::pFldNames->GetObject( nTypeId );
+    else
+        return aEmptyStr;
+}
+
+/*---------------------------------------------------
+ Jedes Feld referenziert einen Feldtypen, der fuer
+ jedes Dokument einmalig ist.
+ --------------------------------------------------*/
+
+SwFieldType::SwFieldType( USHORT nWhichId )
+    : SwModify(0),
+    nWhich( nWhichId )
+{
+    DBG_CTOR( SwFieldType, 0 );
+}
+
+#ifndef PRODUCT
+
+SwFieldType::~SwFieldType()
+{
+    DBG_DTOR( SwFieldType, 0 );
+}
+
+#endif
+
+const String& SwFieldType::GetName() const
+{
+    return aEmptyStr;
+}
+
+BOOL    SwFieldType::QueryValue( uno::Any& rVal, const String& rProperty ) const
+{
+    return FALSE;
+}
+BOOL    SwFieldType::PutValue( const uno::Any& rVal, const String& rProperty )
+{
+    return FALSE;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung:   Basisklasse aller Felder
+                    Felder referenzieren einen Feldtyp
+                    Felder sind n-mal vorhanden, Feldtypen nur einmal
+ --------------------------------------------------------------------*/
+
+SwField::SwField(SwFieldType* pTyp, ULONG nFmt, USHORT nLng) :
+    nFormat(nFmt),
+    nLang(nLng)
+{
+    ASSERT( pTyp, "SwField: ungueltiger SwFieldType" );
+    pType = pTyp;
+}
+
+SwField::~SwField()
+{
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Statt Umweg ueber den Typ
+ --------------------------------------------------------------------*/
+
+#ifndef PRODUCT
+USHORT SwField::Which() const
+{
+    ASSERT(pType, "Kein Typ vorhanden");
+    return pType->Which();
+}
+#endif
+
+/*--------------------------------------------------------------------
+    Beschreibung:
+ --------------------------------------------------------------------*/
+
+USHORT SwField::GetResId(USHORT nTypeId, BOOL& bAmbigous)
+{
+    static USHORT __READONLY_DATA aTypeTab[] = {
+     RES_DATETIMEFLD   ,/*      TYP_DATEFLD,        */
+     RES_DATETIMEFLD   ,/*      TYP_TIMEFLD,        */
+     RES_FILENAMEFLD   ,/*      TYP_FILENAMEFLD,    */
+     RES_DBNAMEFLD     ,/*      TYP_DBNAMEFLD,      */
+     RES_CHAPTERFLD    ,/*      TYP_CHAPTERFLD,     */
+     RES_PAGENUMBERFLD ,/*      TYP_PAGENUMBERFLD,  */// dynamisch
+     RES_DOCSTATFLD    ,/*      TYP_DOCSTATFLD,     */
+     RES_AUTHORFLD     ,/*      TYP_AUTHORFLD,      */
+     RES_SETEXPFLD     ,/*      TYP_SETFLD,         */// dynamisch
+     RES_GETEXPFLD     ,/*      TYP_GETFLD,         */// dynamisch
+     RES_TABLEFLD      ,/*      TYP_FORMELFLD,      */
+     RES_HIDDENTXTFLD  ,/*      TYP_HIDDENTXTFLD,   */
+     RES_SETREFFLD     ,/*      TYP_SETREFFLD,      */
+     RES_GETREFFLD     ,/*      TYP_GETREFFLD,      */
+     RES_DDEFLD        ,/*      TYP_DDEFLD,         */
+     RES_MACROFLD      ,/*      TYP_MACROFLD,       */
+     RES_INPUTFLD      ,/*      TYP_INPUTFLD,       */
+     RES_HIDDENPARAFLD ,/*      TYP_HIDDENPARAFLD,  */
+     RES_DOCINFOFLD    ,/*      TYP_DOCINFOFLD,     */
+     RES_DBFLD         ,/*      TYP_DBFLD,          */
+     RES_USERFLD       ,/*      TYP_USERFLD,        */
+     RES_POSTITFLD     ,/*      TYP_POSTITFLD,      */
+     RES_TEMPLNAMEFLD  ,/*      TYP_TEMPLNAMEFLD,   */
+     RES_SETEXPFLD     ,/*      TYP_SEQFLD          */
+     RES_DBNEXTSETFLD  ,/*      TYP_DBNEXTSETFLD,   */
+     RES_DBNUMSETFLD   ,/*      TYP_DBNUMSETFLD,    */
+     RES_DBSETNUMBERFLD,/*      TYP_DBSETNUMBERFLD, */
+     RES_HIDDENTXTFLD  ,/*      TYP_CONDTXTFLD      */
+     RES_PAGENUMBERFLD ,/*      TYP_NEXTPAGEFLD     */
+     RES_PAGENUMBERFLD ,/*      TYP_PREVPAGEFLD     */
+     RES_EXTUSERFLD    ,/*      TYP_EXTUSERFLD      */
+     RES_DATETIMEFLD   ,/*      TYP_FIXDATEFLD,     */
+     RES_DATETIMEFLD   ,/*      TYP_FIXTIMEFLD,     */
+     RES_SETEXPFLD     ,/*      TYP_SETINPFLD       */
+     USHRT_MAX         ,/*      TYP_USRINPFLD       */
+     RES_REFPAGESETFLD ,/*      TYP_SETREFPAGEFLD   */
+     RES_REFPAGEGETFLD ,/*      TYP_GETREFPAGEFLD   */
+     RES_INTERNETFLD   ,/*      TYP_INTERNETFLD     */
+     RES_JUMPEDITFLD   ,/*      TYP_JUMPEDITFLD     */
+     RES_SCRIPTFLD,     /*      TYP_SCRIPTFLD       */
+     RES_AUTHORITY      /*      TYP_AUTHORITY       */
+    };
+
+    switch( nTypeId )
+    {
+        case TYP_CONDTXTFLD:
+        case TYP_HIDDENTXTFLD:
+        case TYP_USRINPFLD:
+        case TYP_PAGENUMBERFLD:
+        case TYP_PREVPAGEFLD:
+        case TYP_NEXTPAGEFLD:
+        case TYP_SEQFLD:
+        case TYP_SETFLD:
+        case TYP_SETINPFLD:
+        case TYP_FORMELFLD:
+            bAmbigous = TRUE;
+            break;
+        default: bAmbigous = FALSE;
+    }
+
+    return aTypeTab[ nTypeId ];
+}
+
+
+
+/*--------------------------------------------------------------------
+    Beschreibung:
+ --------------------------------------------------------------------*/
+
+USHORT SwField::GetTypeId() const
+{
+
+    USHORT nRet;
+    switch( pType->Which() )
+    {
+    case RES_DATETIMEFLD:
+        if (GetSubType() & FIXEDFLD)
+            nRet = GetSubType() & DATEFLD ? TYP_FIXDATEFLD : TYP_FIXTIMEFLD;
+        else
+            nRet = GetSubType() & DATEFLD ? TYP_DATEFLD : TYP_TIMEFLD;
+        break;
+    case RES_GETEXPFLD:
+        nRet = GSE_FORMULA & GetSubType() ? TYP_FORMELFLD : TYP_GETFLD;
+        break;
+
+    case RES_HIDDENTXTFLD:
+        nRet = GetSubType();
+        break;
+
+    case RES_SETEXPFLD:
+        if( GSE_SEQ & GetSubType() )
+            nRet = TYP_SEQFLD;
+        else if( ((SwSetExpField*)this)->GetInputFlag() )
+            nRet = TYP_SETINPFLD;
+        else
+            nRet = TYP_SETFLD;
+        break;
+
+    case RES_PAGENUMBERFLD:
+        nRet = GetSubType();
+        if( PG_NEXT == nRet )
+            nRet = TYP_NEXTPAGEFLD;
+        else if( PG_PREV == nRet )
+            nRet = TYP_PREVPAGEFLD;
+        else
+            nRet = TYP_PAGENUMBERFLD;
+        break;
+
+    default:
+        nRet = aTypeTab[ pType->Which() ];
+    }
+    return nRet;
+}
+
+
+/*--------------------------------------------------------------------
+    Beschreibung: liefert den Namen oder den Inhalt
+ --------------------------------------------------------------------*/
+
+String SwField::GetCntnt( BOOL bName ) const
+{
+    String sRet;
+    if( bName )
+    {
+        USHORT nTypeId = GetTypeId();
+        if( RES_DATETIMEFLD == GetTyp()->Which() )
+            nTypeId = GetSubType() & DATEFLD ? TYP_DATEFLD : TYP_TIMEFLD;
+
+        sRet = SwFieldType::GetTypeStr( nTypeId );
+        if( IsFixed() )
+            ( sRet += ' ' ) += ViewShell::GetShellRes()->aFixedStr;
+    }
+    else
+        sRet = Expand();
+    return sRet;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Parameter setzen auslesen
+ --------------------------------------------------------------------*/
+
+const String& SwField::GetPar1() const
+{
+    return aEmptyStr;
+}
+
+String SwField::GetPar2() const
+{
+    return aEmptyStr;
+}
+
+String SwField::GetFormula() const
+{
+    return GetPar2();
+}
+
+void SwField::SetPar1(const String& rStr)
+{}
+
+void SwField::SetPar2(const String& rStr)
+{}
+
+USHORT SwField::GetSubType() const
+{
+//  ASSERT(0, "Sorry Not implemented");
+    return 0;
+}
+
+void SwField::SetSubType(USHORT nType)
+{
+//  ASSERT(0, "Sorry Not implemented");
+}
+
+BOOL  SwField::QueryValue( uno::Any& rVal, const String& rProperty ) const
+{
+    return FALSE;
+}
+BOOL SwField::PutValue( const uno::Any& rVal, const String& rProperty )
+{
+    return FALSE;
+}
+
+
+/*--------------------------------------------------------------------
+    Beschreibung:   neuen Typ setzen
+                    (wird fuer das Kopieren zwischen Dokumenten benutzt)
+                    muss immer vom gleichen Typ sein.
+ --------------------------------------------------------------------*/
+
+SwFieldType* SwField::ChgTyp( SwFieldType* pNewType )
+{
+    ASSERT( pNewType && pNewType->Which() == pType->Which(),
+            "kein Typ oder ungleiche Typen" );
+
+    SwFieldType* pOld = pType;
+    pType = pNewType;
+    return pOld;
+}
+
+    // hat das Feld eine Action auf dem ClickHandler ? (z.B. INetFelder,..)
+FASTBOOL SwField::HasClickHdl() const
+{
+    FASTBOOL bRet = FALSE;
+    switch( pType->Which() )
+    {
+    case RES_INTERNETFLD:
+    case RES_JUMPEDITFLD:
+    case RES_GETREFFLD:
+    case RES_MACROFLD:
+    case RES_INPUTFLD:
+        bRet = TRUE;
+        break;
+
+    case RES_SETEXPFLD:
+        bRet = ((SwSetExpField*)this)->GetInputFlag();
+        break;
+    }
+    return bRet;
+}
+
+void SwField::SetLanguage(USHORT nLng)
+{
+    nLang = nLng;
+}
+
+void SwField::ChangeFormat(ULONG n)
+{
+    nFormat = n;
+}
+
+FASTBOOL SwField::IsFixed() const
+{
+    FASTBOOL bRet = FALSE;
+    switch( pType->Which() )
+    {
+    case RES_FIXDATEFLD:
+    case RES_FIXTIMEFLD:
+        bRet = TRUE;
+        break;
+
+    case RES_DATETIMEFLD:
+        bRet = 0 != (GetSubType() & FIXEDFLD);
+        break;
+
+    case RES_EXTUSERFLD:
+    case RES_AUTHORFLD:
+        bRet = 0 != (GetFormat() & AF_FIXED);
+        break;
+
+    case RES_FILENAMEFLD:
+        bRet = 0 != (GetFormat() & FF_FIXED);
+        break;
+
+    case RES_DOCINFOFLD:
+        bRet = 0 != (GetSubType() & DI_SUB_FIXED);
+        break;
+    }
+    return bRet;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Sortierte Feldliste aller Felder usw.
+ --------------------------------------------------------------------*/
+
+SwFieldList::SwFieldList(SwEditShell* pShell)
+    : pSh(pShell)
+{
+    // Hier die Liste aller Eingabefelder sortiert erstellen
+    pSrtLst = new _SetGetExpFlds();
+}
+
+void SwFieldList::InsertFields(USHORT nTypeId, const String* pName)
+{
+    const USHORT nSize = pSh->GetFldTypeCount();
+
+    // Alle Typen abklappern
+
+    for(USHORT i=0; i < nSize; ++i)
+    {
+        SwFieldType* pFldType = pSh->GetFldType(i);
+        if( nTypeId == pFldType->Which() )
+        {
+            if( pName )
+            {
+                String aMacTmp( pFldType->GetName() );
+                if( *pName != aMacTmp )
+                    continue;
+            }
+
+            SwClientIter aIter( *pFldType );
+            for( SwFmtFld* pFld = (SwFmtFld*)aIter.First( TYPE(SwFmtFld) );
+                    pFld; pFld = (SwFmtFld*)aIter.Next() )
+                if( pFld->GetTxtFld() )
+                {
+                    const SwTxtFld* pTxtFld = pFld->GetTxtFld();
+                    const SwTxtNode& rTxtNode = pTxtFld->GetTxtNode();
+                    if( rTxtNode.GetNodes().IsDocNodes() )
+                    {
+                        SwNodeIndex aIdx( rTxtNode );
+                        _SetGetExpFld* pNew = new _SetGetExpFld(aIdx, pTxtFld );
+                        pSrtLst->Insert( pNew );
+                    }
+                }
+        }
+    }
+}
+
+SwFieldList::~SwFieldList()
+{
+    delete pSrtLst;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Felder aus der Liste in sortierter Reihenfolge
+ --------------------------------------------------------------------*/
+
+USHORT SwFieldList::Count() const
+{
+    return pSrtLst->Count();
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung:   von der CursorPos das naechste und das Letzte Feld
+                    in der Liste anfahren
+ --------------------------------------------------------------------*/
+
+SwField* SwFieldList::GetNextField() const
+{
+    SwPaM* pCrsr = pSh->GetCrsr();
+    ULONG nNdPos = pCrsr->GetPoint()->nNode.GetIndex();
+    USHORT nCntPos = pCrsr->GetPoint()->nContent.GetIndex();
+
+    const USHORT nSize = pSrtLst->Count();
+    for(USHORT i = 0; i < nSize; ++i )
+    {
+        _SetGetExpFld* pFnd = (*pSrtLst)[i];
+        if( pFnd->GetNode() > nNdPos || ( pFnd->GetNode() == nNdPos &&
+            pFnd->GetCntnt() >= nCntPos ))
+            return (SwField*)pFnd->GetFld()->GetFld().GetFld();
+    }
+    return 0;
+}
+
+SwField* SwFieldList::GetLastField() const
+{
+    SwPaM* pCrsr = pSh->GetCrsr();
+    ULONG nNdPos = pCrsr->GetPoint()->nNode.GetIndex();
+    USHORT nCntPos = pCrsr->GetPoint()->nContent.GetIndex();
+
+    for( USHORT n = pSrtLst->Count(); n; )
+    {
+        _SetGetExpFld* pFnd = (*pSrtLst)[ --n ];
+        if( pFnd->GetNode() < nNdPos || ( pFnd->GetNode() == nNdPos &&
+            pFnd->GetCntnt() <= nCntPos ))
+            return (SwField*)pFnd->GetFld()->GetFld().GetFld();
+    }
+    return 0;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Numerierung expandieren
+ --------------------------------------------------------------------*/
+
+String FormatNumber(USHORT nNum, ULONG nFormat)
+{
+    SwNumType aNumber;
+
+    ASSERT(nFormat != SVX_NUM_NUMBER_NONE, "Falsches Nummern-Format" );
+
+    aNumber.eType = (SvxExtNumType)nFormat;
+    return aNumber.GetNumStr(nNum);
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: CTOR SwValueFieldType
+ --------------------------------------------------------------------*/
+
+SwValueFieldType::SwValueFieldType( SwDoc* pDocPtr, USHORT nWhichId )
+    : SwFieldType(nWhichId),
+    pDoc(pDocPtr),
+    bUseFormat(TRUE)
+{
+}
+
+SwValueFieldType::SwValueFieldType( const SwValueFieldType& rTyp )
+    : SwFieldType(rTyp.Which()),
+    pDoc(rTyp.GetDoc()),
+    bUseFormat(rTyp.UseFormat())
+{
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Wert formatiert als String zurueckgeben
+ --------------------------------------------------------------------*/
+
+String SwValueFieldType::ExpandValue( const double& rVal,
+                                        ULONG nFmt, USHORT nLng) const
+{
+    if (rVal >= DBL_MAX)        // FehlerString fuer Calculator
+        return ViewShell::GetShellRes()->aCalc_Error;
+
+    String sExpand;
+    SvNumberFormatter* pFormatter = pDoc->GetNumberFormatter();
+    Color* pCol = 0;
+
+    // wegen Bug #60010
+    USHORT nFmtLng = ::lcl_GetLanguageOfFormat( nLng, nFmt, *pFormatter );
+
+    if( nFmt < SV_COUNTRY_LANGUAGE_OFFSET && LANGUAGE_SYSTEM != nFmtLng )
+    {
+        short nType = NUMBERFORMAT_DEFINED;
+        xub_StrLen nDummy;
+
+        const SvNumberformat* pEntry = pFormatter->GetEntry(nFmt);
+
+        if (pEntry && nLng != pEntry->GetLanguage())
+        {
+            ULONG nNewFormat = pFormatter->GetFormatForLanguageIfBuiltIn(nFmt,
+                                                    (LanguageType)nFmtLng);
+
+            if (nNewFormat == nFmt)
+            {
+                // Warscheinlich benutzerdefiniertes Format
+                String sFmt(pEntry->GetFormatstring());
+
+                pFormatter->PutandConvertEntry(sFmt, nDummy, nType, nFmt,
+                                        pEntry->GetLanguage(), nFmtLng );
+            }
+            else
+                nFmt = nNewFormat;
+        }
+        ASSERT(pEntry, "Unbekanntes Zahlenformat!");
+    }
+
+    if( pFormatter->IsTextFormat( nFmt ) )
+    {
+        String sValue;
+        DoubleToString(sValue, rVal, nFmtLng);
+        pFormatter->GetOutputString(sValue, nFmt, sExpand, &pCol);
+    }
+    else
+        pFormatter->GetOutputString(rVal, nFmt, sExpand, &pCol);
+
+    return sExpand;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung:
+ --------------------------------------------------------------------*/
+
+void SwValueFieldType::DoubleToString( String &rValue, const double &rVal,
+                                        ULONG nFmt) const
+{
+    SvNumberFormatter* pFormatter = pDoc->GetNumberFormatter();
+    const SvNumberformat* pEntry = pFormatter->GetEntry(nFmt);
+
+    if (pEntry)
+        DoubleToString(rValue, rVal, pEntry->GetLanguage());
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung:
+ --------------------------------------------------------------------*/
+
+void SwValueFieldType::DoubleToString( String &rValue, const double &rVal,
+                                        USHORT nLng ) const
+{
+    SvNumberFormatter* pFormatter = pDoc->GetNumberFormatter();
+
+    // wegen Bug #60010
+    if( nLng == LANGUAGE_NONE ) // wegen Bug #60010
+        nLng = LANGUAGE_SYSTEM;
+
+    pFormatter->ChangeIntl( nLng ); // Separator in der richtigen Sprache besorgen
+    rValue.Erase();
+    SolarMath::DoubleToString( rValue, rVal, 'F', 12,
+                                    pFormatter->GetDecSep(), TRUE );
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: CTOR SwValueField
+ --------------------------------------------------------------------*/
+
+SwValueField::SwValueField( SwValueFieldType* pFldType, ULONG nFmt,
+                            USHORT nLang, const double fVal )
+    : SwField(pFldType, nFmt, nLang),
+    fValue(fVal)
+{
+}
+
+SwValueField::SwValueField( const SwValueField& rFld )
+    : SwField(rFld),
+    fValue(rFld.GetValue())
+{
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung:   neuen Typ setzen
+                    (wird fuer das Kopieren zwischen Dokumenten benutzt)
+                    muss immer vom gleichen Typ sein.
+ --------------------------------------------------------------------*/
+
+SwFieldType* SwValueField::ChgTyp( SwFieldType* pNewType )
+{
+    SwDoc* pNewDoc = ((SwValueFieldType *)pNewType)->GetDoc();
+    SwDoc* pDoc    = GetDoc();
+
+    if( pNewDoc && pDoc && pDoc != pNewDoc)
+    {
+        SvNumberFormatter* pFormatter = pNewDoc->GetNumberFormatter();
+
+        if( pFormatter && pFormatter->HasMergeFmtTbl() &&
+            ((SwValueFieldType *)GetTyp())->UseFormat() )
+            SetFormat(pFormatter->GetMergeFmtIndex( GetFormat() ));
+    }
+
+    return SwField::ChgTyp(pNewType);
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Format aendern
+ --------------------------------------------------------------------*/
+/*
+ Was sollte das denn?
+void SwValueField::ChangeFormat(ULONG n)
+{
+    nFormat = n;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Format in Office-Sprache ermitteln
+ --------------------------------------------------------------------*/
+
+ULONG SwValueField::GetSystemFormat(SvNumberFormatter* pFormatter, ULONG nFmt)
+{
+    const SvNumberformat* pEntry = pFormatter->GetEntry(nFmt);
+    const International& rInter = Application::GetAppInternational();
+    USHORT nLng = rInter.GetLanguage();
+
+    if (pEntry && nLng != pEntry->GetLanguage())
+    {
+        ULONG nNewFormat = pFormatter->GetFormatForLanguageIfBuiltIn(nFmt,
+                                                        (LanguageType)nLng);
+
+        if (nNewFormat == nFmt)
+        {
+            // Warscheinlich benutzerdefiniertes Format
+            short nType = NUMBERFORMAT_DEFINED;
+            xub_StrLen nDummy;
+
+            String sFmt(pEntry->GetFormatstring());
+
+            ULONG nFormat = nFmt;
+            pFormatter->PutandConvertEntry(sFmt, nDummy, nType,
+                                nFormat, pEntry->GetLanguage(), nLng);
+            nFmt = nFormat;
+        }
+        else
+            nFmt = nNewFormat;
+    }
+
+    return nFmt;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Sprache im Format anpassen
+ --------------------------------------------------------------------*/
+
+void SwValueField::SetLanguage( USHORT nLng )
+{
+    if( ((SwValueFieldType *)GetTyp())->UseFormat() &&
+        GetFormat() != ULONG_MAX )
+    {
+        // wegen Bug #60010
+        SvNumberFormatter* pFormatter = GetDoc()->GetNumberFormatter();
+        USHORT nFmtLng = ::lcl_GetLanguageOfFormat( nLng, GetFormat(),
+                                                    *pFormatter );
+
+        if( (GetFormat() >= SV_COUNTRY_LANGUAGE_OFFSET ||
+             LANGUAGE_SYSTEM != nFmtLng ) &&
+            !(Which() == RES_USERFLD && (GetSubType()&SUB_CMD) ) )
+        {
+            const SvNumberformat* pEntry = pFormatter->GetEntry(GetFormat());
+
+            if( pEntry && nFmtLng != pEntry->GetLanguage() )
+            {
+                ULONG nNewFormat = pFormatter->GetFormatForLanguageIfBuiltIn(
+                                        GetFormat(), (LanguageType)nFmtLng );
+
+                if( nNewFormat == GetFormat() )
+                {
+                    // Warscheinlich benutzerdefiniertes Format
+                    short nType = NUMBERFORMAT_DEFINED;
+                    xub_StrLen nDummy;
+                    String sFmt( pEntry->GetFormatstring() );
+                    pFormatter->PutandConvertEntry( sFmt, nDummy, nType,
+                                                    nNewFormat,
+                                                    pEntry->GetLanguage(),
+                                                    nFmtLng );
+                }
+                SetFormat( nNewFormat );
+            }
+            ASSERT(pEntry, "Unbekanntes Zahlenformat!");
+        }
+    }
+
+    SwField::SetLanguage(nLng);
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung:
+ --------------------------------------------------------------------*/
+
+double SwValueField::GetValue() const
+{
+    return fValue;
+}
+
+void SwValueField::SetValue( const double& rVal )
+{
+    fValue = rVal;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: SwFormulaField
+ --------------------------------------------------------------------*/
+
+SwFormulaField::SwFormulaField( SwValueFieldType* pFldType, ULONG nFmt, const double fVal)
+    : SwValueField(pFldType, nFmt, LANGUAGE_SYSTEM, fVal)
+{
+}
+
+SwFormulaField::SwFormulaField( const SwFormulaField& rFld )
+    : SwValueField((SwValueFieldType *)rFld.GetTyp(), rFld.GetFormat(),
+                    rFld.GetLanguage(), rFld.GetValue())
+{
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung:
+ --------------------------------------------------------------------*/
+
+String SwFormulaField::GetFormula() const
+{
+    return sFormula;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung:
+ --------------------------------------------------------------------*/
+
+void SwFormulaField::SetFormula(const String& rStr)
+{
+    sFormula = rStr;
+
+    ULONG nFmt(GetFormat());
+
+    if( nFmt && ULONG_MAX != nFmt )
+    {
+        // String muss im Systemformat vorliegen!
+        // Geht bei Import/Export mit unterschiedlichen Systemformaten
+        // voll in die Hose. Ist aber nicht anders moeglich, da der Kalkulator
+        // nur im Systemformat rechnen kann und es keine Konvertierungsroutine
+        // gibt.
+        const International& rInter = Application::GetAppInternational();
+        int nErrno;
+        double fValue = SolarMath::StringToDouble( rStr.GetBuffer(),
+                                                rInter.GetNumThousandSep(),
+                                                rInter.GetNumDecimalSep(),
+                                                nErrno );
+        if( !nErrno )
+            SwValueField::SetValue( fValue );
+    }
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung:
+ --------------------------------------------------------------------*/
+
+void SwFormulaField::SetExpandedFormula( const String& rStr )
+{
+    ULONG nFmt(GetFormat());
+
+    if (nFmt && nFmt != ULONG_MAX && ((SwValueFieldType *)GetTyp())->UseFormat())
+    {
+        double fValue;
+
+        SvNumberFormatter* pFormatter = GetDoc()->GetNumberFormatter();
+
+        if (pFormatter->IsNumberFormat(rStr, nFmt, fValue))
+        {
+            SwValueField::SetValue(fValue);
+            sFormula.Erase();
+
+            ((SwValueFieldType *)GetTyp())->DoubleToString(sFormula, fValue, nFmt);
+            return;
+        }
+    }
+    sFormula = rStr;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung:
+ --------------------------------------------------------------------*/
+
+String SwFormulaField::GetExpandedFormula() const
+{
+    ULONG nFmt(GetFormat());
+
+    if (nFmt && nFmt != ULONG_MAX && ((SwValueFieldType *)GetTyp())->UseFormat())
+    {
+        String sFormattedValue;
+        Color* pCol = 0;
+
+        SvNumberFormatter* pFormatter = GetDoc()->GetNumberFormatter();
+
+        if (pFormatter->IsTextFormat(nFmt))
+        {
+            String sValue;
+            ((SwValueFieldType *)GetTyp())->DoubleToString(sValue, GetValue(), nFmt);
+            pFormatter->GetOutputString(sValue, nFmt, sFormattedValue, &pCol);
+        }
+        else
+            pFormatter->GetOutputString(GetValue(), nFmt, sFormattedValue, &pCol);
+
+        return sFormattedValue;
+    }
+    else
+        return GetFormula();
+}
diff --git a/sw/source/core/fields/flddat.cxx b/sw/source/core/fields/flddat.cxx
new file mode 100644
index 000000000000..73f1e0461c96
--- /dev/null
+++ b/sw/source/core/fields/flddat.cxx
@@ -0,0 +1,364 @@
+/*************************************************************************
+ *
+ *  $RCSfile: flddat.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:19 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include 
+
+#ifndef _DATE_HXX //autogen
+#include 
+#endif
+#ifndef _TOOLS_TIME_HXX //autogen
+#include 
+#endif
+#ifndef _ZFORLIST_HXX //autogen
+#include 
+#endif
+
+#ifndef _UNOPRNMS_HXX
+#include 
+#endif
+#include "doc.hxx"
+#include "fldbas.hxx"
+#include "flddat.hxx"
+
+using namespace ::com::sun::star;
+/*--------------------------------------------------
+    Beschreibung: Datum/Zeit-Typ
+ ---------------------------------------------------*/
+
+SwDateTimeFieldType::SwDateTimeFieldType(SwDoc* pDoc)
+    : SwValueFieldType( pDoc, RES_DATETIMEFLD )
+{}
+
+/*--------------------------------------------------------------------
+    Beschreibung:
+ --------------------------------------------------------------------*/
+
+SwFieldType* SwDateTimeFieldType::Copy() const
+{
+    SwDateTimeFieldType *pTmp = new SwDateTimeFieldType(GetDoc());
+    return pTmp;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Datum/Zeit-Feld
+ --------------------------------------------------------------------*/
+
+SwDateTimeField::SwDateTimeField(SwDateTimeFieldType* pType, USHORT nSub, ULONG nFmt, USHORT nLng)
+    : SwValueField(pType, nFmt, nLng, 0.0),
+    nSubType(nSub),
+    nOffset(0)
+{
+    if (!nFmt)
+    {
+        SvNumberFormatter* pFormatter = GetDoc()->GetNumberFormatter();
+        if (nSubType & DATEFLD)
+            ChangeFormat(pFormatter->GetFormatIndex(NF_DATE_SYSTEM_SHORT, GetLanguage()));
+        else
+            ChangeFormat(pFormatter->GetFormatIndex(NF_TIME_HHMMSS, GetLanguage()));
+    }
+    if (IsFixed())
+    {
+        Time aTime;
+        Date aDate;
+        SetDateTime(aDate.GetDate(), aTime.GetTime());
+    }
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung:
+ --------------------------------------------------------------------*/
+
+String SwDateTimeField::Expand() const
+{
+    double fVal;
+
+    if (!(IsFixed()))
+    {
+        Time aTime;
+        Date aDate;
+        fVal = GetDateTime(GetDoc(), aDate.GetDate(), aTime.GetTime());
+    }
+    else
+        fVal = GetValue();
+
+    if (nOffset)
+        fVal += (double)(nOffset * 60L) / 86400.0;
+
+    return ExpandValue(fVal, GetFormat(), GetLanguage());
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung:
+ --------------------------------------------------------------------*/
+
+SwField* SwDateTimeField::Copy() const
+{
+    SwDateTimeField *pTmp =
+        new SwDateTimeField((SwDateTimeFieldType*)GetTyp(), nSubType,
+                                            GetFormat(), GetLanguage());
+
+    pTmp->SetValue(GetValue());
+    pTmp->SetOffset(nOffset);
+
+    return pTmp;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung:
+ --------------------------------------------------------------------*/
+
+USHORT SwDateTimeField::GetSubType() const
+{
+    return nSubType;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung:
+ --------------------------------------------------------------------*/
+
+void SwDateTimeField::SetSubType(USHORT nType)
+{
+    nSubType = nType;
+}
+/*--------------------------------------------------------------------
+    Beschreibung:
+ --------------------------------------------------------------------*/
+
+void SwDateTimeField::SetPar2(const String& rStr)
+{
+    nOffset = rStr.ToInt32();
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung:
+ --------------------------------------------------------------------*/
+
+String SwDateTimeField::GetPar2() const
+{
+    if (nOffset)
+        return String::CreateFromInt32(nOffset);
+    else
+        return aEmptyStr;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung:
+ --------------------------------------------------------------------*/
+
+void SwDateTimeField::SetDateTime(ULONG nDate, ULONG nTime)
+{
+    SetValue(GetDateTime(GetDoc(), nDate, nTime));
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung:
+ --------------------------------------------------------------------*/
+
+double SwDateTimeField::GetDateTime(SwDoc* pDoc, ULONG nDate, ULONG nTime)
+{
+    Date aDate(nDate);
+    SvNumberFormatter* pFormatter = pDoc->GetNumberFormatter();
+    Date* pNullDate = pFormatter->GetNullDate();
+
+    if (!nDate) // Damit wirklich das Jahr auf 0 gesetzt wird...
+        aDate.SetDate(pNullDate->GetDate());
+
+    double fResult = aDate - *pNullDate;
+
+    Time aTime(nTime);
+
+    ULONG nNumFmtTime = (ULONG)aTime.GetSec() + (ULONG)aTime.GetMin() * 60L +
+                  (ULONG)aTime.GetHour() * 3600L;
+
+    return fResult + ((double)nNumFmtTime + 0.5) / 86400.0;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung:
+ --------------------------------------------------------------------*/
+
+double SwDateTimeField::GetValue() const
+{
+    if (IsFixed())
+        return SwValueField::GetValue();
+    else
+        return GetDateTime(GetDoc(), Date().GetDate(), Time().GetTime());
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung:
+ --------------------------------------------------------------------*/
+
+ULONG SwDateTimeField::GetDate(BOOL bUseOffset) const
+{
+    SvNumberFormatter* pFormatter = GetDoc()->GetNumberFormatter();
+    Date* pNullDate = pFormatter->GetNullDate();
+
+    long nVal = GetValue();
+
+    if (bUseOffset && nOffset)
+        nVal += nOffset / 60 / 24;
+
+    Date aDate = *pNullDate + nVal;
+
+    return aDate.GetDate();
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung:
+ --------------------------------------------------------------------*/
+
+ULONG SwDateTimeField::GetTime(BOOL bUseOffset) const
+{
+    double fDummy;
+    double fFract = modf(GetValue(), &fDummy);
+
+    ULONG nTime = (ULONG)(fFract * 86400.0);
+    ULONG nHour = nTime / 3600L;
+    ULONG nMin  = (nTime - 3600L * nHour) / 60L;
+    ULONG nSec  = nTime - 3600L * nHour - 60L * nMin;
+
+    if (bUseOffset)
+        nMin += nOffset;
+
+    Time aTime(nHour, nMin, nSec);
+
+    return aTime.GetTime();
+}
+
+/*-----------------04.03.98 11:05-------------------
+
+--------------------------------------------------*/
+BOOL SwDateTimeField::QueryValue( uno::Any& rVal, const String& rProperty ) const
+{
+    if(rProperty.EqualsAscii(UNO_NAME_DATETIME))
+        rVal <<= GetValue();
+    else if(rProperty.EqualsAscii(UNO_NAME_IS_FIXED ))
+    {
+        BOOL bTmp = IsFixed();
+        rVal.setValue(&bTmp, ::getCppuBooleanType());
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_NUMBER_FORMAT))
+        rVal <<= (sal_Int32)GetFormat();
+    else if(rProperty.EqualsAscii(UNO_NAME_IS_DATE))
+    {
+        BOOL bTmp = IsDate();
+        rVal.setValue(&bTmp, ::getCppuBooleanType());
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_ADJUST))
+        rVal <<= (sal_Int32)nOffset;
+
+#ifdef   DBG_UTIL
+    else
+        DBG_ERROR("Was war das fuer ein Typ?")
+#endif
+    return TRUE;
+}
+/*-----------------04.03.98 11:05-------------------
+
+--------------------------------------------------*/
+BOOL SwDateTimeField::PutValue( const uno::Any& rVal, const String& rProperty )
+{
+    if(rProperty.EqualsAscii(UNO_NAME_DATETIME))
+    {
+        SetValue(*(Double*)rVal.getValue());
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_IS_FIXED))
+    {
+        BOOL bFix = *(sal_Bool*)rVal.getValue();
+        if(bFix)
+            nSubType |= FIXEDFLD;
+        else
+            nSubType &= ~FIXEDFLD;
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_NUMBER_FORMAT))
+    {
+        sal_Int32 nTmp;
+        rVal >>= nTmp;
+        ChangeFormat(nTmp);
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_IS_DATE))
+    {
+        BOOL bDate = *(sal_Bool*)rVal.getValue();
+        nSubType &=  ~(DATEFLD|TIMEFLD);
+        nSubType |= bDate ? DATEFLD : TIMEFLD;
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_ADJUST))
+    {
+        sal_Int32 nVal;
+        rVal >>= nVal;
+        nOffset = nVal;
+    }
+#ifdef   DBG_UTIL
+    else
+    {
+        DBG_ERROR("was war das fuer ein Typ?");
+    }
+#endif
+    return TRUE;
+}
+
diff --git a/sw/source/core/fields/fldlst.cxx b/sw/source/core/fields/fldlst.cxx
new file mode 100644
index 000000000000..a2140b977b20
--- /dev/null
+++ b/sw/source/core/fields/fldlst.cxx
@@ -0,0 +1,278 @@
+/*************************************************************************
+ *
+ *  $RCSfile: fldlst.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:19 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "editsh.hxx"
+#include "doc.hxx"
+
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _FMTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFLD_HXX //autogen
+#include 
+#endif
+#include "edimp.hxx"
+#include "expfld.hxx"
+#include "pam.hxx"
+#include "docfld.hxx"
+#include "ndtxt.hxx"
+
+
+/*--------------------------------------------------------------------
+    Beschreibung: Sortieren der Input-Eintraege
+ --------------------------------------------------------------------*/
+
+SwInputFieldList::SwInputFieldList( SwEditShell* pShell, FASTBOOL bBuildTmpLst )
+    : pSh(pShell)
+{
+    // Hier die Liste aller Eingabefelder sortiert erstellen
+    pSrtLst = new _SetGetExpFlds();
+
+    SwNodes* pNds = &pSh->GetDoc()->GetNodes();
+    const SwFldTypes& rFldTypes = *pSh->GetDoc()->GetFldTypes();
+    const USHORT nSize = rFldTypes.Count();
+
+    // Alle Typen abklappern
+
+    for(USHORT i=0; i < nSize; ++i)
+    {
+        SwFieldType* pFldType = (SwFieldType*)rFldTypes[ i ];
+        USHORT nType = pFldType->Which();
+
+        if( RES_SETEXPFLD == nType || RES_INPUTFLD == nType )
+        {
+            SwClientIter aIter( *pFldType );
+            for( SwFmtFld* pFld = (SwFmtFld*)aIter.First( TYPE(SwFmtFld) );
+                    pFld; pFld = (SwFmtFld*)aIter.Next() )
+
+            {
+                const SwTxtFld* pTxtFld = pFld->GetTxtFld();
+
+                //  nur InputFields und interaktive SetExpFlds bearbeiten
+                //
+                if( !pTxtFld || ( RES_SETEXPFLD == nType &&
+                    !((SwSetExpField*)pFld->GetFld())->GetInputFlag()))
+                    continue;
+
+                const SwTxtNode& rTxtNode = pTxtFld->GetTxtNode();
+                if( rTxtNode.GetNodes().IsDocNodes() )
+                {
+                    if( bBuildTmpLst )
+                    {
+                        VoidPtr pTmp = (VoidPtr)pTxtFld;
+                        aTmpLst.Insert( pTmp, aTmpLst.Count() );
+                    }
+                    else
+                    {
+                        SwNodeIndex aIdx( rTxtNode );
+                        _SetGetExpFld* pNew = new _SetGetExpFld(aIdx, pTxtFld );
+                        pSrtLst->Insert( pNew );
+                    }
+                }
+            }
+        }
+    }
+}
+
+SwInputFieldList::~SwInputFieldList()
+{
+    delete pSrtLst;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Felder aus der Liste in sortierter Reihenfolge
+ --------------------------------------------------------------------*/
+
+USHORT SwInputFieldList::Count() const
+{
+    return pSrtLst->Count();
+}
+
+
+SwField* SwInputFieldList::GetField(USHORT nId)
+{
+    const SwTxtFld* pTxtFld = (*pSrtLst)[ nId ]->GetFld();
+    ASSERT( pTxtFld, "kein TextFld" );
+    return (SwField*)pTxtFld->GetFld().GetFld();
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Cursor sichern
+ --------------------------------------------------------------------*/
+
+void SwInputFieldList::PushCrsr()
+{
+    pSh->Push();
+    pSh->ClearMark();
+}
+
+void SwInputFieldList::PopCrsr()
+{
+    pSh->Pop(FALSE);
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Position eines Feldes ansteuern
+ --------------------------------------------------------------------*/
+
+void SwInputFieldList::GotoFieldPos(USHORT nId)
+{
+    pSh->StartAllAction();
+    (*pSrtLst)[ nId ]->GetPosOfContent( *pSh->GetCrsr()->GetPoint() );
+    pSh->EndAllAction();
+}
+
+    // vergleiche TmpLst mit akt Feldern. Alle neue kommen in die SortLst
+    // damit sie geupdatet werden koennen. Returnt die Anzahl.
+    // (Fuer Textbausteine: nur seine Input-Felder aktualisieren)
+USHORT SwInputFieldList::BuildSortLst()
+{
+    SwNodes* pNds = &pSh->GetDoc()->GetNodes();
+    const SwFldTypes& rFldTypes = *pSh->GetDoc()->GetFldTypes();
+    USHORT nSize = rFldTypes.Count();
+
+    // Alle Typen abklappern
+
+    for( USHORT i = 0; i < nSize; ++i )
+    {
+        SwFieldType* pFldType = (SwFieldType*)rFldTypes[ i ];
+        USHORT nType = pFldType->Which();
+
+        if( RES_SETEXPFLD == nType || RES_INPUTFLD == nType )
+        {
+            SwClientIter aIter( *pFldType );
+            for( SwFmtFld* pFld = (SwFmtFld*)aIter.First( TYPE(SwFmtFld) );
+                    pFld; pFld = (SwFmtFld*)aIter.Next() )
+            {
+                const SwTxtFld* pTxtFld = pFld->GetTxtFld();
+
+                //  nur InputFields und interaktive SetExpFlds bearbeiten
+                if( !pTxtFld || ( RES_SETEXPFLD == nType &&
+                    !((SwSetExpField*)pFld->GetFld())->GetInputFlag()))
+                    continue;
+
+                const SwTxtNode& rTxtNode = pTxtFld->GetTxtNode();
+                if( rTxtNode.GetNodes().IsDocNodes() )
+                {
+                    VoidPtr pTmp = (VoidPtr)pTxtFld;
+                    // nicht in der TempListe vorhanden, also in die SortListe
+                    // aufnehemen
+                    USHORT nFndPos = aTmpLst.GetPos( pTmp );
+                    if( USHRT_MAX == nFndPos )
+                    {
+                        SwNodeIndex aIdx( rTxtNode );
+                        _SetGetExpFld* pNew = new _SetGetExpFld(aIdx, pTxtFld );
+                        pSrtLst->Insert( pNew );
+                    }
+                    else
+                        aTmpLst.Remove( nFndPos );
+                }
+            }
+        }
+    }
+
+    // die Pointer werden nicht mehr gebraucht
+    aTmpLst.Remove( 0, aTmpLst.Count() );
+    return pSrtLst->Count();
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Alle Felder auáerhalb von Selektionen aus Liste entfernen
+ --------------------------------------------------------------------*/
+
+void SwInputFieldList::RemoveUnselectedFlds()
+{
+    _SetGetExpFlds* pNewLst = new _SetGetExpFlds();
+
+    FOREACHPAM_START(pSh)
+    {
+        for (USHORT i = 0; i < Count();)
+        {
+            _SetGetExpFld* pFld = (*pSrtLst)[i];
+            SwPosition aPos(*PCURCRSR->GetPoint());
+
+            pFld->GetPos( aPos );
+
+            if (aPos >= *PCURCRSR->Start() && aPos < *PCURCRSR->End())
+            {
+                // Feld innerhalb der Selektion
+                pNewLst->Insert( (*pSrtLst)[i] );
+                pSrtLst->Remove(i, 1);
+            }
+            else
+                i++;
+        }
+    }
+    FOREACHPAM_END()
+
+    delete pSrtLst;
+    pSrtLst = pNewLst;
+}
+
+
diff --git a/sw/source/core/fields/macrofld.cxx b/sw/source/core/fields/macrofld.cxx
new file mode 100644
index 000000000000..2f36473e0590
--- /dev/null
+++ b/sw/source/core/fields/macrofld.cxx
@@ -0,0 +1,226 @@
+/*************************************************************************
+ *
+ *  $RCSfile: macrofld.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:19 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "doc.hxx"
+
+#include "hintids.hxx"
+#include "docufld.hxx"
+
+#ifndef _UNOPRNMS_HXX
+#include 
+#endif
+
+using namespace ::com::sun::star;
+using namespace ::rtl;
+/*--------------------------------------------------------------------
+    Beschreibung: MacroFeldtypen
+ --------------------------------------------------------------------*/
+
+SwMacroFieldType::SwMacroFieldType(SwDoc* pDocument)
+    : SwFieldType( RES_MACROFLD ),
+      pDoc(pDocument)
+{
+}
+
+SwFieldType* SwMacroFieldType::Copy() const
+{
+    SwMacroFieldType* pType = new SwMacroFieldType(pDoc);
+    return pType;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Das Macrofeld selbst
+ --------------------------------------------------------------------*/
+
+SwMacroField::SwMacroField(SwMacroFieldType* pType,
+                           const String& rLibAndName, const String& rTxt) :
+    SwField(pType), aMacro(rLibAndName), aText(rTxt)
+{
+}
+
+String SwMacroField::Expand() const
+{   // Button malen anstatt von
+    return aText ;
+}
+
+SwField* SwMacroField::Copy() const
+{
+    return new SwMacroField((SwMacroFieldType*)GetTyp(), aMacro, aText);
+}
+
+String SwMacroField::GetCntnt(BOOL bName) const
+{
+    if(bName)
+    {
+        String aStr(GetTyp()->GetName());
+        aStr += ' ';
+        aStr += aMacro;
+        return aStr;
+    }
+    return Expand();
+}
+
+String SwMacroField::GetLibName() const
+{
+    if (aMacro.Len())
+    {
+        USHORT nPos = aMacro.Len();
+
+        for (USHORT i = 0; i < 3 && nPos > 0; i++)
+            while (aMacro.GetChar(--nPos) != '.' && nPos > 0);
+
+        return aMacro.Copy(0, nPos );
+    }
+
+    DBG_ASSERT(0, "Kein Macroname vorhanden")
+    return aEmptyStr;
+}
+
+String SwMacroField::GetMacroName() const
+{
+    if (aMacro.Len())
+    {
+        USHORT nPos = aMacro.Len();
+
+        for (USHORT i = 0; i < 3 && nPos > 0; i++)
+            while (aMacro.GetChar(--nPos) != '.' && nPos > 0);
+
+        return aMacro.Copy( ++nPos );
+    }
+
+    DBG_ASSERT(0, "Kein Macroname vorhanden")
+    return aEmptyStr;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: LibName und MacroName
+ --------------------------------------------------------------------*/
+
+void SwMacroField::SetPar1(const String& rStr)
+{
+    aMacro = rStr;
+}
+
+const String& SwMacroField::GetPar1() const
+{
+    return aMacro;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Macrotext
+ --------------------------------------------------------------------*/
+
+void SwMacroField::SetPar2(const String& rStr)
+{
+    aText = rStr;
+}
+
+String SwMacroField::GetPar2() const
+{
+    return aText;
+}
+
+/*-----------------05.03.98 13:38-------------------
+
+--------------------------------------------------*/
+BOOL SwMacroField::QueryValue( uno::Any& rAny, const String& rProperty ) const
+{
+    if(rProperty.EqualsAscii(UNO_NAME_MACRO))
+        rAny <<= OUString(aMacro);
+    else if(rProperty.EqualsAscii(UNO_NAME_HINT))
+        rAny <<= OUString(aText);
+
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return TRUE;
+}
+/*-----------------05.03.98 13:38-------------------
+
+--------------------------------------------------*/
+BOOL SwMacroField::PutValue( const uno::Any& rAny, const String& rProperty )
+{
+    if(rProperty.EqualsAscii(UNO_NAME_MACRO))
+    {
+        OUString uTmp;
+        rAny >>= uTmp;
+        aMacro = String(uTmp);
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_HINT))
+    {
+        OUString uTmp;
+        rAny >>= uTmp;
+        aText = String(uTmp);
+    }
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return TRUE;
+}
+
diff --git a/sw/source/core/fields/makefile.mk b/sw/source/core/fields/makefile.mk
new file mode 100644
index 000000000000..52bf9db0b1a5
--- /dev/null
+++ b/sw/source/core/fields/makefile.mk
@@ -0,0 +1,125 @@
+#*************************************************************************
+#
+#   $RCSfile: makefile.mk,v $
+#
+#   $Revision: 1.1.1.1 $
+#
+#   last change: $Author: hr $ $Date: 2000-09-19 00:08:19 $
+#
+#   The Contents of this file are made available subject to the terms of
+#   either of the following licenses
+#
+#          - GNU Lesser General Public License Version 2.1
+#          - Sun Industry Standards Source License Version 1.1
+#
+#   Sun Microsystems Inc., October, 2000
+#
+#   GNU Lesser General Public License Version 2.1
+#   =============================================
+#   Copyright 2000 by Sun Microsystems, Inc.
+#   901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+#   This library is free software; you can redistribute it and/or
+#   modify it under the terms of the GNU Lesser General Public
+#   License version 2.1, as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   Lesser General Public License for more details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+#   License along with this library; if not, write to the Free Software
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+#   MA  02111-1307  USA
+#
+#
+#   Sun Industry Standards Source License Version 1.1
+#   =================================================
+#   The contents of this file are subject to the Sun Industry Standards
+#   Source License Version 1.1 (the "License"); You may not use this file
+#   except in compliance with the License. You may obtain a copy of the
+#   License at http://www.openoffice.org/license.html.
+#
+#   Software provided under this License is provided on an "AS IS" basis,
+#   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+#   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+#   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+#   See the License for the specific provisions governing your rights and
+#   obligations concerning the Software.
+#
+#   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+#   Copyright: 2000 by Sun Microsystems, Inc.
+#
+#   All Rights Reserved.
+#
+#   Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sw
+TARGET=fields
+
+AUTOSEG=true
+
+PROJECTPCH=core_pch
+PDBTARGET=core_pch
+PROJECTPCHSOURCE=..\core_1st\core_pch
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE :  $(PRJ)$/inc$/swpre.mk
+.INCLUDE :  settings.mk
+.INCLUDE :  $(PRJ)$/inc$/sw.mk
+
+# --- Files --------------------------------------------------------
+
+CXXFILES = \
+        authfld.cxx \
+        cellfml.cxx \
+        chpfld.cxx \
+        dbfld.cxx \
+        ddefld.cxx \
+        ddetbl.cxx \
+        docufld.cxx \
+        expfld.cxx \
+        fldbas.cxx \
+        flddat.cxx \
+        scrptfld.cxx \
+        macrofld.cxx \
+        fldlst.cxx \
+        reffld.cxx \
+        tblcalc.cxx \
+        usrfld.cxx
+
+
+
+SLOFILES =	\
+        $(SLO)$/authfld.obj \
+        $(SLO)$/cellfml.obj \
+        $(SLO)$/chpfld.obj \
+        $(SLO)$/dbfld.obj \
+        $(SLO)$/ddefld.obj \
+        $(SLO)$/ddetbl.obj \
+        $(SLO)$/docufld.obj \
+        $(SLO)$/expfld.obj \
+        $(SLO)$/fldbas.obj \
+        $(SLO)$/flddat.obj \
+        $(SLO)$/fldlst.obj \
+        $(SLO)$/scrptfld.obj \
+        $(SLO)$/macrofld.obj \
+        $(SLO)$/reffld.obj \
+        $(SLO)$/tblcalc.obj \
+        $(SLO)$/usrfld.obj
+
+EXCEPTIONSFILES=$(SLO)$/usrfld.obj
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE :  target.mk
+
diff --git a/sw/source/core/fields/reffld.cxx b/sw/source/core/fields/reffld.cxx
new file mode 100644
index 000000000000..19bec7f83eea
--- /dev/null
+++ b/sw/source/core/fields/reffld.cxx
@@ -0,0 +1,898 @@
+/*************************************************************************
+ *
+ *  $RCSfile: reffld.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:19 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#define _SVSTDARR_USHORTSSORT
+#define _SVSTDARR_USHORTS
+#include 
+
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _CNTFRM_HXX
+#include 
+#endif
+#ifndef _PAGEFRM_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _FMTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFTN_HXX //autogen
+#include 
+#endif
+#ifndef _FMTRFMRK_HXX //autogen
+#include 
+#endif
+#ifndef _TXTRFMRK_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFTN_HXX //autogen
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _CHPFLD_HXX
+#include 
+#endif
+#ifndef _REFFLD_HXX
+#include 
+#endif
+#ifndef _EXPFLD_HXX
+#include 
+#endif
+#ifndef _TXTFRM_HXX
+#include 
+#endif
+#ifndef _FLYFRM_HXX
+#include 
+#endif
+#ifndef _PAGEDESC_HXX
+#include 
+#endif
+#ifndef _BOOKMRK_HXX
+#include 
+#endif
+#ifndef _FTNIDX_HXX
+#include 
+#endif
+#ifndef _VIEWSH_HXX
+#include 
+#endif
+#ifndef _SHELLRES_HXX
+#include 
+#endif
+
+#ifndef _UNOPRNMS_HXX
+#include 
+#endif
+
+#ifndef _COM_SUN_STAR_TEXT_REFERENCEFIELDPART_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_REFERENCEFIELDSOURCE_HPP_
+#include 
+#endif
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::text;
+using namespace ::rtl;
+
+extern void InsertSort( SvUShorts& rArr, USHORT nIdx, USHORT* pInsPos = 0 );
+
+void lcl_GetLayTree( const SwFrm* pFrm, SvPtrarr& rArr )
+{
+    while( pFrm )
+    {
+        if( pFrm->IsBodyFrm() )     // soll uns nicht weiter interessieren
+            pFrm = pFrm->GetUpper();
+        else
+        {
+            void* p = (void*)pFrm;
+            rArr.Insert( p, rArr.Count() );
+
+            // bei der Seite ist schluss
+            if( pFrm->IsPageFrm() )
+                break;
+
+            if( pFrm->IsFlyFrm() )
+                pFrm = ((SwFlyFrm*)pFrm)->GetAnchor();
+            else
+                pFrm = pFrm->GetUpper();
+        }
+    }
+}
+
+
+BOOL IsFrameBehind( const SwTxtNode& rMyNd, USHORT nMySttPos,
+                    const SwTxtNode& rBehindNd, USHORT nSttPos )
+{
+    const SwTxtFrm *pMyFrm = (SwTxtFrm*)rMyNd.GetFrm(0,0,FALSE),
+                   *pFrm = (SwTxtFrm*)rBehindNd.GetFrm(0,0,FALSE);
+
+    while( pFrm && !pFrm->IsInside( nSttPos ) )
+        pFrm = (SwTxtFrm*)pFrm->GetFollow();
+    while( pMyFrm && !pMyFrm->IsInside( nMySttPos ) )
+        pMyFrm = (SwTxtFrm*)pMyFrm->GetFollow();
+
+    if( !pFrm || !pMyFrm || pFrm == pMyFrm )
+        return FALSE;
+
+    SvPtrarr aRefArr( 10, 10 ), aArr( 10, 10 );
+    ::lcl_GetLayTree( pFrm, aRefArr );
+    ::lcl_GetLayTree( pMyFrm, aArr );
+
+    USHORT nRefCnt = aRefArr.Count() - 1, nCnt = aArr.Count() - 1;
+
+    // solange bis ein Frame ungleich ist ?
+    while( nRefCnt && nCnt && aRefArr[ nRefCnt ] == aArr[ nCnt ] )
+        --nCnt, --nRefCnt;
+
+    // sollte einer der Counter ueberlaeufen?
+    if( aRefArr[ nRefCnt ] == aArr[ nCnt ] )
+    {
+        if( nCnt )
+            --nCnt;
+        else
+            --nRefCnt;
+    }
+
+    const SwFrm* pRefFrm = (const SwFrm*)aRefArr[ nRefCnt ];
+    const SwFrm* pFldFrm = (const SwFrm*)aArr[ nCnt ];
+
+    // unterschiedliche Frames, dann ueberpruefe deren Y-/X-Position
+    BOOL bRefIsLower;
+    if( ( FRM_COLUMN | FRM_CELL ) & pFldFrm->GetType() ||
+        ( FRM_COLUMN | FRM_CELL ) & pRefFrm->GetType() )
+    {
+        if( pFldFrm->GetType() == pRefFrm->GetType() )
+        {
+            // hier ist die X-Pos wichtiger!
+            bRefIsLower = pRefFrm->Frm().Left() < pFldFrm->Frm().Left() ||
+                    ( pRefFrm->Frm().Left() == pFldFrm->Frm().Left() &&
+                        pRefFrm->Frm().Top() < pFldFrm->Frm().Top() );
+            pRefFrm = 0;
+        }
+        else if( ( FRM_COLUMN | FRM_CELL ) & pFldFrm->GetType() )
+            pFldFrm = (const SwFrm*)aArr[ nCnt - 1 ];
+        else
+            pRefFrm = (const SwFrm*)aRefArr[ nRefCnt - 1 ];
+    }
+
+    if( pRefFrm )               // als Flag missbrauchen
+        bRefIsLower = pRefFrm->Frm().Top() < pFldFrm->Frm().Top() ||
+                    ( pRefFrm->Frm().Top() == pFldFrm->Frm().Top() &&
+                        pRefFrm->Frm().Left() < pFldFrm->Frm().Left() );
+    return bRefIsLower;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Referenzen holen
+ --------------------------------------------------------------------*/
+
+
+SwGetRefField::SwGetRefField( SwGetRefFieldType* pFldType,
+                              const String& rSetRef, USHORT nSubTyp,
+                              USHORT nSeqenceNo, ULONG nFmt )
+    : SwField( pFldType, nFmt ), sSetRefName( rSetRef ),
+    nSubType( nSubTyp ), nSeqNo( nSeqenceNo )
+{
+}
+
+USHORT SwGetRefField::GetSubType() const
+{
+    return nSubType;
+}
+
+void SwGetRefField::SetSubType( USHORT n )
+{
+    nSubType = n;
+}
+
+String SwGetRefField::Expand() const
+{
+    return sTxt;
+}
+
+
+String SwGetRefField::GetCntnt(BOOL bName) const
+{
+    if( !bName )
+        return Expand();
+
+    String aStr(GetTyp()->GetName());
+    aStr += ' ';
+    aStr += sSetRefName;
+    return aStr;
+}
+
+
+void SwGetRefField::UpdateField()
+{
+    sTxt.Erase();
+
+    SwDoc* pDoc = ((SwGetRefFieldType*)GetTyp())->GetDoc();
+    USHORT nStt, nEnd;
+    SwTxtNode* pTxtNd = SwGetRefFieldType::FindAnchor( pDoc, sSetRefName,
+                                        nSubType, nSeqNo, &nStt, &nEnd );
+    if( !pTxtNd )
+        return ;
+
+    switch( GetFormat() )
+    {
+    case REF_CONTENT:
+    case REF_ONLYNUMBER:
+    case REF_ONLYCAPTION:
+    case REF_ONLYSEQNO:
+        {
+            switch( nSubType )
+            {
+            case REF_SEQUENCEFLD:
+                nEnd = pTxtNd->GetTxt().Len();
+                switch( GetFormat() )
+                {
+                case REF_ONLYNUMBER:
+                    if( nStt + 1 < nEnd )
+                        nEnd = nStt + 1;
+                    nStt = 0;
+                    break;
+
+                case REF_ONLYCAPTION:
+                    {
+                        const SwTxtAttr* pTxtAttr = pTxtNd->GetTxtAttr( nStt,
+                                                        RES_TXTATR_FIELD );
+                        if( pTxtAttr )
+                            nStt = SwGetExpField::GetReferenceTextPos(
+                                                pTxtAttr->GetFld(), *pDoc );
+                        else if( nStt + 1 < nEnd )
+                            ++nStt;
+                    }
+                    break;
+
+                case REF_ONLYSEQNO:
+                    if( nStt + 1 < nEnd )
+                        nEnd = nStt + 1;
+                    break;
+
+                default:
+                    nStt = 0;
+                    break;
+                }
+                break;
+
+            case REF_BOOKMARK:
+                if( USHRT_MAX == nEnd )
+                {
+                    // Text steht ueber verschiedene Nodes verteilt.
+                    // Gesamten Text oder nur bis zum Ende vom Node?
+                    nEnd = pTxtNd->GetTxt().Len();
+                }
+                break;
+
+            case REF_OUTLINE:
+                break;
+
+            case REF_FOOTNOTE:
+            case REF_ENDNOTE:
+                {
+                    // die Nummer oder den NumString besorgen
+                    USHORT n, nFtnCnt = pDoc->GetFtnIdxs().Count();
+                    SwTxtFtn* pFtnIdx;
+                    for( n = 0; n < nFtnCnt; ++n )
+                        if( nSeqNo == (pFtnIdx = pDoc->GetFtnIdxs()[ n ])->GetSeqRefNo() )
+                        {
+                            sTxt = pFtnIdx->GetFtn().GetViewNumStr( *pDoc );
+                            break;
+                        }
+                    nStt = nEnd;        // kein Bereich, der String ist fertig
+                }
+                break;
+            }
+
+            if( nStt != nEnd )      // ein Bereich?
+            {
+                sTxt = pTxtNd->GetExpandTxt( nStt, nEnd - nStt, FALSE );
+
+                // alle Sonderzeichen entfernen (durch Blanks ersetzen):
+                if( sTxt.Len() )
+                    for( sal_Unicode* p = sTxt.GetBufferAccess(); *p; ++p )
+                        if( *p < 0x20 )
+                            *p = 0x20;
+            }
+        }
+        break;
+
+    case REF_PAGE:
+    case REF_PAGE_PGDESC:
+        {
+            const SwTxtFrm* pFrm = (SwTxtFrm*)pTxtNd->GetFrm(0,0,FALSE),
+                        *pSave = pFrm;
+            while( pFrm && !pFrm->IsInside( nStt ) )
+                pFrm = (SwTxtFrm*)pFrm->GetFollow();
+
+            if( pFrm || 0 != ( pFrm = pSave ))
+            {
+                USHORT nPageNo = pFrm->GetVirtPageNum();
+                const SwPageFrm *pPage;
+                if( REF_PAGE_PGDESC == GetFormat() &&
+                    0 != ( pPage = pFrm->FindPageFrm() ) &&
+                    pPage->GetPageDesc() )
+                    sTxt = pPage->GetPageDesc()->GetNumType().GetNumStr( nPageNo );
+                else
+                    sTxt = String::CreateFromInt32(nPageNo);
+            }
+        }
+        break;
+
+    case REF_CHAPTER:
+        {
+            // ein bischen trickreich: suche irgend einen Frame
+            const SwFrm* pFrm = pTxtNd->GetFrm();
+            if( pFrm )
+            {
+                SwChapterFieldType aFldTyp;
+                SwChapterField aFld( &aFldTyp, 0 );
+                aFld.SetLevel( MAXLEVEL - 1 );
+                aFld.ChangeExpansion( pFrm, pTxtNd, TRUE );
+                sTxt = aFld.GetNumber();
+            }
+        }
+        break;
+
+    case REF_UPDOWN:
+        {
+            const SwTxtFld* pTFld = 0;
+
+            {
+                SwClientIter aIter( *GetTyp() );
+                for( SwFmtFld* pFld = (SwFmtFld*)aIter.First( TYPE(SwFmtFld) );
+                        pFld; pFld = (SwFmtFld*)aIter.Next() )
+                    if( pFld->GetFld() == this )
+                    {
+                        pTFld = pFld->GetTxtFld();
+                        break;
+                    }
+            }
+
+            if( !pTFld || !pTFld->GetpTxtNode() )   // noch nicht im Node gestezt?
+                break;
+
+            // erstmal ein "Kurz" - Test - falls beide im selben
+            // Node stehen!
+            if( pTFld->GetpTxtNode() == pTxtNd )
+            {
+                sTxt = nStt < *pTFld->GetStart()
+                            ? ViewShell::GetShellRes()->aGetRefFld_Up
+                            : ViewShell::GetShellRes()->aGetRefFld_Down;
+                break;
+            }
+
+            sTxt = ::IsFrameBehind( *pTFld->GetpTxtNode(), *pTFld->GetStart(),
+                                    *pTxtNd, nStt )
+                        ? ViewShell::GetShellRes()->aGetRefFld_Up
+                        : ViewShell::GetShellRes()->aGetRefFld_Down;
+
+        }
+        break;
+    }
+}
+
+
+SwField* SwGetRefField::Copy() const
+{
+    SwGetRefField* pFld = new SwGetRefField( (SwGetRefFieldType*)GetTyp(),
+                                                sSetRefName, nSubType,
+                                                nSeqNo, GetFormat() );
+    pFld->sTxt = sTxt;
+    return pFld;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: ReferenzName holen
+ --------------------------------------------------------------------*/
+
+
+const String& SwGetRefField::GetPar1() const
+{
+    return sSetRefName;
+}
+
+
+void SwGetRefField::SetPar1( const String& rName )
+{
+    sSetRefName = rName;
+}
+
+
+String SwGetRefField::GetPar2() const
+{
+    return Expand();
+}
+
+/*-----------------06.03.98 13:34-------------------
+
+--------------------------------------------------*/
+BOOL SwGetRefField::QueryValue( uno::Any& rAny, const String& rProperty ) const
+{
+    if(rProperty.EqualsAscii(UNO_NAME_REFERENCE_FIELD_PART))
+    {
+        sal_Int16 nPart = 0;
+        switch(GetFormat())
+        {
+            case REF_PAGE       : nPart = ReferenceFieldPart::PAGE                ; break;
+            case REF_CHAPTER    : nPart = ReferenceFieldPart::CHAPTER             ; break;
+            case REF_CONTENT    : nPart = ReferenceFieldPart::TEXT                ; break;
+            case REF_UPDOWN     : nPart = ReferenceFieldPart::UP_DOWN             ; break;
+            case REF_PAGE_PGDESC: nPart = ReferenceFieldPart::PAGE_DESC           ; break;
+            case REF_ONLYNUMBER : nPart = ReferenceFieldPart::CATEGORY_AND_NUMBER ; break;
+            case REF_ONLYCAPTION: nPart = ReferenceFieldPart::ONLY_CAPTION        ; break;
+            case REF_ONLYSEQNO  : nPart = ReferenceFieldPart::ONLY_SEQUENCE_NUMBER; break;
+        }
+        rAny <<= nPart;
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_REFERENCE_FIELD_SOURCE))
+    {
+        sal_Int16 nSource = 0;
+        switch(nSubType)
+        {
+            case  REF_SETREFATTR : nSource = ReferenceFieldSource::REFERENCE_MARK; break;
+            case  REF_SEQUENCEFLD: nSource = ReferenceFieldSource::SEQUENCE_FIELD; break;
+            case  REF_BOOKMARK   : nSource = ReferenceFieldSource::BOOKMARK; break;
+            case  REF_OUTLINE    : DBG_ERROR("not implemented"); break;
+            case  REF_FOOTNOTE   : nSource = ReferenceFieldSource::FOOTNOTE; break;
+            case  REF_ENDNOTE    : nSource = ReferenceFieldSource::ENDNOTE; break;
+        }
+        rAny <<= nSource;
+    }
+    else if( rProperty.EqualsAscii(UNO_NAME_SOURCE_NAME ))
+        rAny <<= rtl::OUString(GetPar1());
+    else if(rProperty.EqualsAscii(UNO_NAME_CURRENT_PRESENTATION))
+        rAny <<= rtl::OUString(Expand());
+    else if(rProperty.EqualsAscii(UNO_NAME_SEQUENCE_NUMBER))
+        rAny <<= (sal_Int16)nSeqNo;
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return TRUE;
+}
+/*-----------------06.03.98 13:34-------------------
+
+--------------------------------------------------*/
+BOOL SwGetRefField::PutValue( const uno::Any& rAny, const String& rProperty )
+{
+    if(rProperty.EqualsAscii(UNO_NAME_REFERENCE_FIELD_PART))
+    {
+        sal_Int16 nPart;
+        rAny >>= nPart;
+        switch(nPart)
+        {
+            case ReferenceFieldPart::PAGE:                  nPart = REF_PAGE; break;
+            case ReferenceFieldPart::CHAPTER:               nPart = REF_CHAPTER; break;
+            case ReferenceFieldPart::TEXT:                  nPart = REF_CONTENT; break;
+            case ReferenceFieldPart::UP_DOWN:               nPart = REF_UPDOWN; break;
+            case ReferenceFieldPart::PAGE_DESC:             nPart = REF_PAGE_PGDESC; break;
+            case ReferenceFieldPart::CATEGORY_AND_NUMBER:   nPart = REF_ONLYNUMBER; break;
+            case ReferenceFieldPart::ONLY_CAPTION:          nPart = REF_ONLYCAPTION; break;
+            case ReferenceFieldPart::ONLY_SEQUENCE_NUMBER : nPart = REF_ONLYSEQNO; break;
+            default: return FALSE;
+        }
+        SetFormat(nPart);
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_REFERENCE_FIELD_SOURCE))
+    {
+        sal_Int16 nSource;
+        rAny >>= nSource;
+        switch(nSource)
+        {
+            case ReferenceFieldSource::REFERENCE_MARK : nSubType = REF_SETREFATTR ; break;
+            case ReferenceFieldSource::SEQUENCE_FIELD : nSubType = REF_SEQUENCEFLD; break;
+            case ReferenceFieldSource::BOOKMARK       : nSubType = REF_BOOKMARK   ; break;
+            case ReferenceFieldSource::FOOTNOTE       : nSubType = REF_FOOTNOTE   ; break;
+            case ReferenceFieldSource::ENDNOTE        : nSubType = REF_ENDNOTE    ; break;
+        }
+    }
+    else if( rProperty.EqualsAscii(UNO_NAME_SOURCE_NAME ))
+    {
+        OUString uTmp;
+        rAny >>= uTmp;
+        SetPar1(uTmp);
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_CURRENT_PRESENTATION))
+    {
+        OUString sVal;
+        rAny >>= sVal;
+        SetExpand(sVal);
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_SEQUENCE_NUMBER))
+    {
+        sal_Int16 nSetSeq;
+        rAny >>= nSetSeq;
+        if(nSetSeq >= 0)
+            nSeqNo = nSetSeq;
+    }
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return TRUE;
+}
+
+/*-----------------JP: 18.06.93 -------------------
+ Get-Referenz-Type
+ --------------------------------------------------*/
+
+
+SwGetRefFieldType::SwGetRefFieldType( SwDoc* pDc )
+    : SwFieldType( RES_GETREFFLD ), pDoc( pDc )
+{}
+
+
+SwFieldType* SwGetRefFieldType::Copy() const
+{
+    return new SwGetRefFieldType( pDoc );
+}
+
+
+void SwGetRefFieldType::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew )
+{
+    // Update auf alle GetReferenz-Felder
+    if( !pNew && !pOld )
+    {
+        SwClientIter aIter( *this );
+        for( SwFmtFld* pFld = (SwFmtFld*)aIter.First( TYPE(SwFmtFld) );
+                        pFld; pFld = (SwFmtFld*)aIter.Next() )
+        {
+            // nur die GetRef-Felder Updaten
+            ((SwGetRefField*)pFld->GetFld())->UpdateField();
+        }
+    }
+    // weiter an die Text-Felder, diese "Expandieren" den Text
+    SwModify::Modify( pOld, pNew );
+}
+
+SwTxtNode* SwGetRefFieldType::FindAnchor( SwDoc* pDoc, const String& rRefMark,
+                                        USHORT nSubType, USHORT nSeqNo,
+                                        USHORT* pStt, USHORT* pEnd )
+{
+    ASSERT( pStt, "warum wird keine StartPos abgefragt?" );
+
+    SwTxtNode* pTxtNd = 0;
+    switch( nSubType )
+    {
+    case REF_SETREFATTR:
+        {
+            const SwFmtRefMark *pRef = pDoc->GetRefMark( rRefMark );
+            if( pRef && pRef->GetTxtRefMark() )
+            {
+                pTxtNd = (SwTxtNode*)&pRef->GetTxtRefMark()->GetTxtNode();
+                *pStt = *pRef->GetTxtRefMark()->GetStart();
+                if( pEnd )
+                    *pEnd = *pRef->GetTxtRefMark()->GetAnyEnd();
+            }
+        }
+        break;
+
+    case REF_SEQUENCEFLD:
+        {
+            SwFieldType* pFldType = pDoc->GetFldType( RES_SETEXPFLD, rRefMark );
+            if( pFldType && pFldType->GetDepends() &&
+                GSE_SEQ & ((SwSetExpFieldType*)pFldType)->GetType() )
+            {
+                SwClientIter aIter( *pFldType );
+                for( SwFmtFld* pFld = (SwFmtFld*)aIter.First( TYPE(SwFmtFld) );
+                                pFld; pFld = (SwFmtFld*)aIter.Next() )
+                {
+                    if( pFld->GetTxtFld() && nSeqNo ==
+                        ((SwSetExpField*)pFld->GetFld())->GetSeqNumber() )
+                    {
+                        SwTxtFld* pTxtFld = pFld->GetTxtFld();
+                        pTxtNd = (SwTxtNode*)pTxtFld->GetpTxtNode();
+                        *pStt = *pTxtFld->GetStart();
+                        if( pEnd )
+                            *pEnd = (*pStt) + 1;
+                        break;
+                    }
+                }
+            }
+        }
+        break;
+
+    case REF_BOOKMARK:
+        {
+            USHORT nPos = pDoc->FindBookmark( rRefMark );
+            if( USHRT_MAX != nPos )
+            {
+                const SwBookmark& rBkmk = *pDoc->GetBookmarks()[ nPos ];
+                const SwPosition* pPos = &rBkmk.GetPos();
+                if( rBkmk.GetOtherPos() && *pPos > *rBkmk.GetOtherPos() )
+                    pPos = rBkmk.GetOtherPos();
+
+                pTxtNd = pDoc->GetNodes()[ pPos->nNode ]->GetTxtNode();
+                *pStt = pPos->nContent.GetIndex();
+                if( pEnd )
+                {
+                    if( !rBkmk.GetOtherPos() )
+                        *pEnd = *pStt;
+                    else if( rBkmk.GetOtherPos()->nNode == rBkmk.GetPos().nNode )
+                    {
+                        *pEnd = rBkmk.GetOtherPos() == pPos
+                                ? rBkmk.GetPos().nContent.GetIndex()
+                                : rBkmk.GetOtherPos()->nContent.GetIndex();
+                    }
+                    else
+                        *pEnd = USHRT_MAX;
+                }
+            }
+        }
+        break;
+
+    case REF_OUTLINE:
+        break;
+
+    case REF_FOOTNOTE:
+    case REF_ENDNOTE:
+        {
+            USHORT n, nFtnCnt = pDoc->GetFtnIdxs().Count();
+            SwTxtFtn* pFtnIdx;
+            for( n = 0; n < nFtnCnt; ++n )
+                if( nSeqNo == (pFtnIdx = pDoc->GetFtnIdxs()[ n ])->GetSeqRefNo() )
+                {
+                    SwNodeIndex* pIdx = pFtnIdx->GetStartNode();
+                    if( pIdx )
+                    {
+                        SwNodeIndex aIdx( *pIdx, 1 );
+                        if( 0 == ( pTxtNd = aIdx.GetNode().GetTxtNode()))
+                            pTxtNd = (SwTxtNode*)pDoc->GetNodes().GoNext( &aIdx );
+                    }
+                    *pStt = 0;
+                    if( pEnd )
+                        *pEnd = 0;
+                    break;
+                }
+        }
+        break;
+    }
+
+    return pTxtNd;
+}
+
+
+struct _RefIdsMap
+{
+    String aName;
+    SvUShortsSort aIds, aDstIds, aIdsMap;
+    SvUShorts aMap;
+    BOOL bInit;
+
+    _RefIdsMap( const String& rName )
+        : aName( rName ), aIds( 16, 16 ), aIdsMap( 16, 16 ), aMap( 16, 16 ),
+        bInit( FALSE )
+    {}
+
+    void Check( SwDoc& rDoc, SwDoc& rDestDoc, SwGetRefField& rFld,
+                    BOOL bField = TRUE );
+
+    BOOL IsInit() const { return bInit; }
+};
+
+SV_DECL_PTRARR_DEL( _RefIdsMaps, _RefIdsMap*, 5, 5 )
+SV_IMPL_PTRARR( _RefIdsMaps, _RefIdsMap* )
+
+void _RefIdsMap::Check( SwDoc& rDoc, SwDoc& rDestDoc, SwGetRefField& rFld,
+                        BOOL bField )
+{
+
+    if( !bInit )
+    {
+        if( bField )
+        {
+            const SwTxtNode* pNd;
+            SwModify* pMod;
+            if( 0 != ( pMod = rDestDoc.GetFldType( RES_SETEXPFLD, aName ) ))
+            {
+                SwClientIter aIter( *pMod );
+                for( SwFmtFld* pF = (SwFmtFld*)aIter.First( TYPE( SwFmtFld )); pF;
+                    pF = (SwFmtFld*)aIter.Next() )
+                    if( pF->GetTxtFld() &&
+                        0 != ( pNd = pF->GetTxtFld()->GetpTxtNode() ) &&
+                        pNd->GetNodes().IsDocNodes() )
+                        aIds.Insert( ((SwSetExpField*)pF->GetFld())->GetSeqNumber() );
+            }
+            if( 0 != ( pMod = rDoc.GetFldType( RES_SETEXPFLD, aName ) ))
+            {
+                SwClientIter aIter( *pMod );
+                for( SwFmtFld* pF = (SwFmtFld*)aIter.First( TYPE( SwFmtFld )); pF;
+                        pF = (SwFmtFld*)aIter.Next() )
+                    if( pF->GetTxtFld() &&
+                        0 != ( pNd = pF->GetTxtFld()->GetpTxtNode() ) &&
+                        pNd->GetNodes().IsDocNodes() )
+                        aDstIds.Insert( ((SwSetExpField*)pF->GetFld())->GetSeqNumber() );
+            }
+        }
+        else
+        {
+            for( USHORT n = rDestDoc.GetFtnIdxs().Count(); n; )
+                aIds.Insert( rDestDoc.GetFtnIdxs()[ --n ]->GetSeqRefNo() );
+            for( n = rDoc.GetFtnIdxs().Count(); n; )
+                aDstIds.Insert( rDoc.GetFtnIdxs()[ --n ]->GetSeqRefNo() );
+        }
+        bInit = TRUE;
+    }
+
+    // dann teste mal, ob die Nummer schon vergeben ist
+    // oder ob eine neue bestimmt werden muss.
+    USHORT nPos, nSeqNo = rFld.GetSeqNo();
+    if( aIds.Seek_Entry( nSeqNo ) && aDstIds.Seek_Entry( nSeqNo ))
+    {
+        // ist schon vergeben, also muss eine neue
+        // erzeugt werden.
+        if( aIdsMap.Seek_Entry( nSeqNo, &nPos ))
+            rFld.SetSeqNo( aMap[ nPos ] );
+        else
+        {
+            for( USHORT n = 0; n < aIds.Count(); ++n )
+                if( n != aIds[ n ] )
+                    break;
+
+            // die neue SeqNo eintragen, damit die "belegt" ist
+            aIds.Insert( n );
+            aIdsMap.Insert( nSeqNo, nPos );
+            aMap.Insert( n, nPos );
+            rFld.SetSeqNo( n );
+
+            // und noch die Felder oder Fuss-/EndNote auf die neue
+            // Id umsetzen
+            if( bField )
+            {
+                SwModify* pMod = rDoc.GetFldType( RES_SETEXPFLD, aName );
+                if( pMod )
+                {
+                    SwClientIter aIter( *pMod );
+                    for( SwFmtFld* pF = (SwFmtFld*)aIter.First( TYPE( SwFmtFld )); pF;
+                            pF = (SwFmtFld*)aIter.Next() )
+                        if( pF->GetTxtFld() && nSeqNo ==
+                            ((SwSetExpField*)pF->GetFld())->GetSeqNumber() )
+                            ((SwSetExpField*)pF->GetFld())->SetSeqNumber( n );
+                }
+            }
+            else
+            {
+                SwTxtFtn* pFtnIdx;
+                for( USHORT i = 0, nCnt = rDoc.GetFtnIdxs().Count(); i < nCnt; ++i )
+                    if( nSeqNo == (pFtnIdx = rDoc.GetFtnIdxs()[ i ])->GetSeqRefNo() )
+                    {
+                        pFtnIdx->SetSeqNo( n );
+                        break;
+                    }
+            }
+        }
+    }
+    else
+    {
+        aIds.Insert( nSeqNo );
+        aIdsMap.Insert( nSeqNo, nPos );
+        aMap.Insert( nSeqNo, nPos );
+    }
+}
+
+
+void SwGetRefFieldType::MergeWithOtherDoc( SwDoc& rDestDoc )
+{
+    if( &rDestDoc != pDoc &&
+        rDestDoc.GetSysFldType( RES_GETREFFLD )->GetDepends() )
+    {
+        // dann gibt es im DestDoc RefFelder, also muessen im SourceDoc
+        // alle RefFelder auf einduetige Ids in beiden Docs umgestellt
+        // werden.
+        _RefIdsMap aFntMap( aEmptyStr );
+        _RefIdsMaps aFldMap;
+
+        SwClientIter aIter( *this );
+        for( SwClient* pFld = aIter.First( TYPE( SwFmtFld ));
+                pFld; pFld = aIter.Next() )
+        {
+            SwGetRefField& rRefFld = *(SwGetRefField*)((SwFmtFld*)pFld)->GetFld();
+            switch( rRefFld.GetSubType() )
+            {
+            case REF_SEQUENCEFLD:
+                {
+                    _RefIdsMap* pMap = 0;
+                    for( USHORT n = aFldMap.Count(); n; )
+                        if( aFldMap[ --n ]->aName == rRefFld.GetSetRefName() )
+                        {
+                            pMap = aFldMap[ n ];
+                            break;
+                        }
+                    if( !pMap )
+                    {
+                        pMap = new _RefIdsMap( rRefFld.GetSetRefName() );
+                        aFldMap.C40_INSERT( _RefIdsMap, pMap, aFldMap.Count() );
+                    }
+
+                    pMap->Check( *pDoc, rDestDoc, rRefFld, TRUE );
+                }
+                break;
+
+            case REF_FOOTNOTE:
+            case REF_ENDNOTE:
+                aFntMap.Check( *pDoc, rDestDoc, rRefFld, FALSE );
+                break;
+            }
+        }
+    }
+}
+
diff --git a/sw/source/core/fields/scrptfld.cxx b/sw/source/core/fields/scrptfld.cxx
new file mode 100644
index 000000000000..4cc180000091
--- /dev/null
+++ b/sw/source/core/fields/scrptfld.cxx
@@ -0,0 +1,182 @@
+/*************************************************************************
+ *
+ *  $RCSfile: scrptfld.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:19 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "docufld.hxx"
+
+#ifndef _UNOPRNMS_HXX
+#include 
+#endif
+
+using namespace ::com::sun::star;
+using namespace ::rtl;
+/*--------------------------------------------------------------------
+    Beschreibung: ScriptField
+ --------------------------------------------------------------------*/
+
+SwScriptFieldType::SwScriptFieldType( SwDoc* pD )
+    : SwFieldType( RES_SCRIPTFLD ), pDoc( pD )
+{}
+
+SwFieldType* SwScriptFieldType::Copy() const
+{
+    return new SwScriptFieldType( pDoc );
+}
+
+
+/*--------------------------------------------------------------------
+    Beschreibung: SwScriptField
+ --------------------------------------------------------------------*/
+
+SwScriptField::SwScriptField( SwScriptFieldType* pType,
+                                const String& rType, const String& rCode,
+                                BOOL bURL )
+    : SwField( pType ), sType( rType ), sCode( rCode ), bCodeURL( bURL )
+{
+}
+
+String SwScriptField::Expand() const
+{
+    return aEmptyStr;
+}
+
+SwField* SwScriptField::Copy() const
+{
+    return new SwScriptField( (SwScriptFieldType*)GetTyp(), sType, sCode, bCodeURL );
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Type setzen
+ --------------------------------------------------------------------*/
+
+void SwScriptField::SetPar1( const String& rStr )
+{
+    sType = rStr;
+}
+
+const String& SwScriptField::GetPar1() const
+{
+    return sType;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Code setzen
+ --------------------------------------------------------------------*/
+
+void SwScriptField::SetPar2( const String& rStr )
+{
+    sCode = rStr;
+}
+
+
+String SwScriptField::GetPar2() const
+{
+    return sCode;
+}
+/*-----------------05.03.98 15:00-------------------
+
+--------------------------------------------------*/
+BOOL SwScriptField::QueryValue( uno::Any& rAny, const String& rProperty ) const
+{
+    if(rProperty.EqualsAscii(UNO_NAME_URL_CONTENT))
+        rAny.setValue(&bCodeURL, ::getBooleanCppuType());
+    else if(rProperty.EqualsAscii(UNO_NAME_SCRIPT_TYPE))
+        rAny <<= OUString(sType);
+    else if( rProperty.EqualsAscii(UNO_NAME_CONTENT))
+         rAny <<= OUString(sCode);
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return TRUE;
+
+}
+/*-----------------05.03.98 15:00-------------------
+
+--------------------------------------------------*/
+BOOL SwScriptField::PutValue( const uno::Any& rAny, const String& rProperty )
+{
+    if(rProperty.EqualsAscii(UNO_NAME_URL_CONTENT))
+        bCodeURL = *(sal_Bool*)rAny.getValue();
+    else if(rProperty.EqualsAscii(UNO_NAME_SCRIPT_TYPE))
+    {
+        OUString uTmp;
+        rAny >>= uTmp;
+        sType = String(uTmp);
+    }
+    else if( rProperty.EqualsAscii(UNO_NAME_CONTENT))
+    {
+        OUString uTmp;
+        rAny >>= uTmp;
+          sCode = String(uTmp);
+    }
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return TRUE;
+}
+
diff --git a/sw/source/core/fields/tblcalc.cxx b/sw/source/core/fields/tblcalc.cxx
new file mode 100644
index 000000000000..b670d9b5b0f9
--- /dev/null
+++ b/sw/source/core/fields/tblcalc.cxx
@@ -0,0 +1,280 @@
+/*************************************************************************
+ *
+ *  $RCSfile: tblcalc.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:19 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "cntfrm.hxx"
+#include "doc.hxx"
+#include "pam.hxx"      // fuer GetBodyTxtNode
+#include "ndtxt.hxx"
+
+#ifndef _UNOPRNMS_HXX
+#include 
+#endif
+
+#ifndef _FMTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFLD_HXX //autogen
+#include 
+#endif
+#include "expfld.hxx"
+#include "hints.hxx"    // fuer Modify()
+#include "docfld.hxx"   // fuer _SetGetExpFld
+
+using namespace ::com::sun::star;
+using namespace ::rtl;
+
+
+SwTblFieldType::SwTblFieldType(SwDoc* pDocPtr)
+    : SwValueFieldType( pDocPtr, RES_TABLEFLD )
+{}
+
+
+SwFieldType* SwTblFieldType::Copy() const
+{
+    return new SwTblFieldType(GetDoc());
+}
+
+
+
+void SwTblField::CalcField( SwTblCalcPara& rCalcPara )
+{
+    if( rCalcPara.rCalc.IsCalcError() )     // ist schon Fehler gesetzt ?
+        return;
+
+    // erzeuge aus den BoxNamen die Pointer
+    BoxNmToPtr( rCalcPara.pTbl );
+    String sFml( MakeFormel( rCalcPara ));
+    SetValue( rCalcPara.rCalc.Calculate( sFml ).GetDouble() );
+    ChgValid( !rCalcPara.IsStackOverFlow() );       // ist der Wert wieder gueltig?
+}
+
+
+
+SwTblField::SwTblField( SwTblFieldType* pType, const String& rFormel,
+                        USHORT nType, ULONG nFmt )
+    : SwValueField( pType, nFmt ), SwTableFormula( rFormel ),
+    nSubType(nType), sExpand( '0' )
+{
+}
+
+
+SwField* SwTblField::Copy() const
+{
+    SwTblField* pTmp = new SwTblField( (SwTblFieldType*)GetTyp(),
+                                        SwTableFormula::GetFormula(), nSubType, GetFormat() );
+    pTmp->sExpand     = sExpand;
+    pTmp->SwValueField::SetValue(GetValue());
+    pTmp->SwTableFormula::operator=( *this );
+    return pTmp;
+}
+
+
+String SwTblField::GetCntnt(BOOL bName) const
+{
+    if( bName )
+    {
+        // suche die richtige Tabelle
+        String sFml;
+        const SwNode* pNode;
+        if( IsIntrnlName() && GetTyp()->GetDepends() &&
+            0 != ( pNode = GetNodeOfFormula() ))
+        {
+            const SwTableNode* pTblNd = pNode->FindTableNode();
+            ((SwTblField*)this)->PtrToBoxNm( &pTblNd->GetTable() );
+            sFml = GetPar2();
+        }
+        else
+            sFml = GetPar2();
+        String aStr(GetTyp()->GetName());
+        aStr += ' ';
+        aStr += sFml;
+        return aStr;
+    }
+    return Expand();
+}
+
+
+// suche den TextNode, in dem das Feld steht
+const SwNode* SwTblField::GetNodeOfFormula() const
+{
+    if( !GetTyp()->GetDepends() )
+        return 0;
+
+    SwClientIter aIter( *GetTyp() );
+    SwClient * pLast = aIter.GoStart();
+    if( pLast )     // konnte zum Anfang gesprungen werden ??
+        do {
+            const SwFmtFld* pFmtFld = (SwFmtFld*)pLast;
+            if( this == pFmtFld->GetFld() )
+                return (SwTxtNode*)&pFmtFld->GetTxtFld()->GetTxtNode();
+
+        } while( 0 != ( pLast = aIter++ ));
+    return 0;
+}
+
+
+String SwTblField::Expand() const
+{
+    String aStr;
+    if (nSubType & SUB_CMD)
+    {
+        if( EXTRNL_NAME != GetNameType() )
+        {
+            const SwNode* pNd = GetNodeOfFormula();
+            const SwTableNode* pTblNd = pNd ? pNd->FindTableNode() : 0;
+            if( pTblNd )
+                ((SwTblField*)this)->PtrToBoxNm( &pTblNd->GetTable() );
+        }
+        if( EXTRNL_NAME == GetNameType() )
+            aStr = SwTableFormula::GetFormula();
+    }
+    else
+    {
+        aStr = sExpand;
+        if(nSubType & GSE_STRING)
+        {
+            // es ist ein String
+            aStr = sExpand;
+            aStr.Erase( 0,1 );
+            aStr.Erase( aStr.Len()-1, 1 );
+        }
+    }
+    return aStr;
+}
+
+
+USHORT SwTblField::GetSubType() const
+{
+    return nSubType;
+}
+
+void SwTblField::SetSubType(USHORT nType)
+{
+    nSubType = nType;
+}
+
+
+void SwTblField::SetValue( const double& rVal )
+{
+    SwValueField::SetValue(rVal);
+    sExpand = ((SwValueFieldType*)GetTyp())->ExpandValue(rVal, GetFormat(), GetLanguage());
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Parameter setzen
+ --------------------------------------------------------------------*/
+
+
+String SwTblField::GetPar2() const
+{
+    return SwTableFormula::GetFormula();
+}
+
+
+void SwTblField::SetPar2(const String& rStr)
+{
+    SetFormula( rStr );
+}
+
+
+/*-----------------04.03.98 10:33-------------------
+
+--------------------------------------------------*/
+BOOL SwTblField::QueryValue( uno::Any& rAny, const String& rProperty ) const
+{
+    BOOL bRet = TRUE;
+    if(rProperty.EqualsAscii(UNO_NAME_FORMULA))
+    {
+        rAny <<= rtl::OUString(SwTableFormula::GetFormula());
+    }
+    else
+        bRet = FALSE;
+    return bRet;
+}
+/*-----------------04.03.98 10:33-------------------
+
+--------------------------------------------------*/
+BOOL SwTblField::PutValue( const uno::Any& rAny, const String& rProperty )
+{
+    BOOL bRet = TRUE;
+    if(rProperty.EqualsAscii(UNO_NAME_FORMULA))
+    {
+        OUString uTmp;
+        rAny >>= uTmp;
+        SetFormula( uTmp );
+    }
+    else
+    {
+        //exception(wrong_param)
+        bRet = FALSE;
+    }
+    return bRet;
+}
+
+
+
+
diff --git a/sw/source/core/fields/usrfld.cxx b/sw/source/core/fields/usrfld.cxx
new file mode 100644
index 000000000000..8b56abcd9c28
--- /dev/null
+++ b/sw/source/core/fields/usrfld.cxx
@@ -0,0 +1,451 @@
+/*************************************************************************
+ *
+ *  $RCSfile: usrfld.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:19 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _SVDMODEL_HXX //autogen
+#include 
+#endif
+
+#ifndef _ZFORLIST_HXX //autogen
+#include 
+#endif
+
+#ifndef _ZFORMAT_HXX //autogen
+#include 
+#endif
+
+#ifndef _UNOPRNMS_HXX
+#include 
+#endif
+
+#include "calbck.hxx"
+#include "calc.hxx"
+#include "usrfld.hxx"
+#include "doc.hxx"
+#include "editsh.hxx"
+#include "dpage.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::rtl;
+/*--------------------------------------------------------------------
+    Beschreibung: Benutzerfelder
+ --------------------------------------------------------------------*/
+
+SwUserField::SwUserField(SwUserFieldType* pTyp, sal_uInt16 nSub, sal_uInt32 nFmt)
+    : SwValueField(pTyp, nFmt),
+    nSubType(nSub)
+{
+}
+
+String SwUserField::Expand() const
+{
+    String sStr;
+    if(!(nSubType & SUB_INVISIBLE))
+        sStr = ((SwUserFieldType*)GetTyp())->Expand(GetFormat(), nSubType, GetLanguage());
+
+    return sStr;
+}
+
+SwField* SwUserField::Copy() const
+{
+    return new SwUserField((SwUserFieldType*)GetTyp(), nSubType, GetFormat());
+}
+
+String SwUserField::GetCntnt(sal_Bool bName) const
+{
+    if ( bName )
+    {   String aStr(SwFieldType::GetTypeStr(TYP_USERFLD));
+        aStr += ' ';
+        aStr += GetTyp()->GetName();
+        aStr.AppendAscii(" = ");
+        aStr += ((SwUserFieldType*)GetTyp())->GetContent();
+        return aStr;
+    }
+    return Expand();
+}
+
+double SwUserField::GetValue() const
+{
+    return ((SwUserFieldType*)GetTyp())->GetValue();
+}
+
+void SwUserField::SetValue( const double& rVal )
+{
+    ((SwUserFieldType*)GetTyp())->SetValue(rVal);
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Name
+ --------------------------------------------------------------------*/
+
+const String& SwUserField::GetPar1() const
+{
+    return ((SwUserFieldType*)GetTyp())->GetName();
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Content
+ --------------------------------------------------------------------*/
+
+String SwUserField::GetPar2() const
+{
+    return ((SwUserFieldType*)GetTyp())->GetContent(GetFormat());
+}
+
+void SwUserField::SetPar2(const String& rStr)
+{
+    ((SwUserFieldType*)GetTyp())->SetContent(rStr, GetFormat());
+}
+
+sal_uInt16 SwUserField::GetSubType() const
+{
+    return ((SwUserFieldType*)GetTyp())->GetType() | nSubType;
+}
+
+void SwUserField::SetSubType(sal_uInt16 nSub)
+{
+    ((SwUserFieldType*)GetTyp())->SetType(nSub & 0x00ff);
+    nSubType = nSub & 0xff00;
+}
+
+/*-----------------09.03.98 08:04-------------------
+
+--------------------------------------------------*/
+BOOL SwUserField::QueryValue( uno::Any& rAny, const String& rProperty ) const
+{
+    if(rProperty.EqualsAscii(UNO_NAME_NUMBER_FORMAT))
+    {
+        rAny <<= (sal_Int32)GetFormat();
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_IS_VISIBLE))
+    {
+        BOOL bTmp = 0 == (nSubType & SUB_INVISIBLE);
+        rAny.setValue(&bTmp, ::getBooleanCppuType());
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_IS_SHOW_FORMULA))
+    {
+        BOOL bTmp = 0 != (nSubType & SUB_CMD);
+        rAny.setValue(&bTmp, ::getBooleanCppuType());
+    }
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return sal_True;
+}
+/*-----------------09.03.98 08:04-------------------
+
+--------------------------------------------------*/
+sal_Bool SwUserField::PutValue( const uno::Any& rAny, const String& rProperty )
+{
+    if(rProperty.EqualsAscii(UNO_NAME_NUMBER_FORMAT))
+    {
+        sal_Int32 nTmp;
+        rAny >>= nTmp;
+        SetFormat(nTmp);
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_IS_VISIBLE))
+    {
+        sal_Bool bTmp = *(sal_Bool*) rAny.getValue();
+        if(bTmp)
+            nSubType &= (~SUB_INVISIBLE);
+        else
+            nSubType |= SUB_INVISIBLE;
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_IS_SHOW_FORMULA))
+    {
+        sal_Bool bTmp = *(sal_Bool*) rAny.getValue();
+        if(bTmp)
+            nSubType |= SUB_CMD;
+        else
+            nSubType &= (~SUB_CMD);
+    }
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("Welches Property?")
+#endif
+    return sal_True;
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Benutzerfeldtypen
+ --------------------------------------------------------------------*/
+
+SwUserFieldType::SwUserFieldType( SwDoc* pDocPtr, const String& aNam )
+    : SwValueFieldType( pDocPtr, RES_USERFLD ),
+    nType(GSE_STRING),
+    nValue( 0 )
+{
+    bValidValue = bDeleted = sal_False;
+    aName = aNam;
+
+    if (nType & GSE_STRING)
+        EnableFormat(sal_False);    // Numberformatter nicht einsetzen
+}
+
+String SwUserFieldType::Expand(sal_uInt32 nFmt, sal_uInt16 nSubType, sal_uInt16 nLng)
+{
+    String aStr(aContent);
+    if((nType & GSE_EXPR) && !(nSubType & SUB_CMD))
+    {
+        EnableFormat(sal_True);
+        aStr = ExpandValue(nValue, nFmt, nLng);
+    }
+    else
+        EnableFormat(sal_False);    // Numberformatter nicht einsetzen
+
+    return aStr;
+}
+
+SwFieldType* SwUserFieldType::Copy() const
+{
+    SwUserFieldType *pTmp = new SwUserFieldType( GetDoc(), aName );
+    pTmp->aContent      = aContent;
+    pTmp->nType         = nType;
+    pTmp->bValidValue   = bValidValue;
+    pTmp->nValue        = nValue;
+    pTmp->bDeleted      = bDeleted;
+
+    return pTmp;
+}
+
+const String& SwUserFieldType::GetName() const
+{
+    return aName;
+}
+
+void SwUserFieldType::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew )
+{
+    if( !pOld && !pNew )
+        ChgValid( sal_False );
+
+    SwModify::Modify( pOld, pNew );
+    // und ggfs. am UserFeld haengende InputFelder updaten!
+    GetDoc()->GetSysFldType( RES_INPUTFLD )->UpdateFlds();
+}
+
+double SwUserFieldType::GetValue( SwCalc& rCalc )
+{
+    if(bValidValue)
+        return nValue;
+
+    if(!rCalc.Push( this ))
+    {
+        rCalc.SetCalcError( CALC_SYNTAX );
+        return 0;
+    }
+    nValue = rCalc.Calculate( aContent ).GetDouble();
+    rCalc.Pop( this );
+
+    if( !rCalc.IsCalcError() )
+        bValidValue = sal_True;
+    else
+        nValue = 0;
+
+    return nValue;
+}
+
+String SwUserFieldType::GetContent( sal_uInt32 nFmt )
+{
+    if (nFmt && nFmt != ULONG_MAX)
+    {
+        String sFormattedValue;
+        Color* pCol = 0;
+
+        SvNumberFormatter* pFormatter = GetDoc()->GetNumberFormatter();
+
+        pFormatter->GetOutputString(GetValue(), nFmt, sFormattedValue, &pCol);
+        return sFormattedValue;
+    }
+    else
+        return aContent;
+}
+
+void SwUserFieldType::SetContent( const String& rStr, sal_uInt32 nFmt )
+{
+    if( aContent != rStr )
+    {
+        aContent = rStr;
+
+        if (nFmt && nFmt != ULONG_MAX)
+        {
+            double fValue;
+
+            SvNumberFormatter* pFormatter = GetDoc()->GetNumberFormatter();
+
+            if (pFormatter->IsNumberFormat(rStr, nFmt, fValue))
+            {
+                SetValue(fValue);
+                aContent.Erase();
+                DoubleToString(aContent, fValue, nFmt);
+            }
+        }
+
+        // der SdrPage (und damit den VCControls) sagen, das sich was getan hat
+        if( GetDoc()->GetDrawModel() && GetDepends() )
+            ((SwDPage*)GetDoc()->GetDrawModel()->GetPage( 0 ))->
+                    UpdateLinkData( aName, aContent );
+
+        sal_Bool bModified = GetDoc()->IsModified();
+        GetDoc()->SetModified();
+        if( !bModified )    // Bug 57028
+            GetDoc()->SetUndoNoResetModified();
+    }
+}
+
+void SwUserFieldType::CtrlSetContent( const String& rStr )
+{
+    if( aContent != rStr )
+    {
+        aContent = rStr;
+        bValidValue = sal_False;
+
+        sal_Bool bModified = GetDoc()->IsModified();
+        GetDoc()->SetModified();
+        if( !bModified )    // Bug 57028
+            GetDoc()->SetUndoNoResetModified();
+
+        // dann mal alle Feldern updaten
+        if( GetDepends() )
+        {
+            SwEditShell* pSh = GetDoc()->GetEditShell();
+            if( pSh )
+                pSh->StartAllAction();
+
+            Modify( 0, 0 );
+            GetDoc()->UpdateUsrFlds();
+            GetDoc()->UpdateExpFlds();
+
+            GetDoc()->SetModified();
+            if( pSh )
+                pSh->EndAllAction();
+        }
+    }
+}
+/*-----------------04.03.98 17:05-------------------
+
+--------------------------------------------------*/
+BOOL SwUserFieldType::QueryValue( uno::Any& rAny, const String& rProperty ) const
+{
+    if(rProperty.EqualsAscii(UNO_NAME_VALUE))
+    {
+        rAny <<= (Double) nValue;
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_CONTENT))
+    {
+        rAny <<= rtl::OUString(aContent);
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_IS_EXPRESSION))
+    {
+        BOOL bExpression = 0 != (GSE_EXPR&nType);
+        rAny.setValue(&bExpression, ::getBooleanCppuType());
+    }
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("unknown property")
+#endif
+    return sal_True;
+}
+/*-----------------04.03.98 17:05-------------------
+
+--------------------------------------------------*/
+BOOL SwUserFieldType::PutValue( const uno::Any& rAny, const String& rProperty )
+{
+    if(rProperty.EqualsAscii(UNO_NAME_VALUE))
+    {
+        Double fVal;
+        rAny >>= fVal;
+        nValue = fVal;
+
+        // Folgende Zeile ist eigentlich falsch, da die Sprache unbekannt ist
+        // (haengt am Feld) und aContent daher auch eigentlich ans Feld gehoeren
+        // muesste. Jedes Feld kann eine andere Sprache, aber den gleichen Inhalt
+        // haben, nur die Formatierung ist unterschiedlich.
+        DoubleToString(aContent, nValue, (sal_uInt16)LANGUAGE_SYSTEM);
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_CONTENT ))
+    {
+        OUString uTmp;
+        rAny >>= uTmp;
+        aContent = String(uTmp);
+    }
+    else if(rProperty.EqualsAscii(UNO_NAME_IS_EXPRESSION))
+    {
+        BOOL bExpression = *(sal_Bool*)rAny.getValue();
+        if(bExpression)
+            nType |= GSE_EXPR;
+        else
+            nType &= ~GSE_EXPR;
+    }
+#ifdef DBG_UTIL
+    else
+        DBG_ERROR("unknown property")
+#endif
+    return sal_True;
+}
+
+
+
diff --git a/sw/source/core/frmedt/fecopy.cxx b/sw/source/core/frmedt/fecopy.cxx
new file mode 100644
index 000000000000..17697f3a2a73
--- /dev/null
+++ b/sw/source/core/frmedt/fecopy.cxx
@@ -0,0 +1,1431 @@
+/*************************************************************************
+ *
+ *  $RCSfile: fecopy.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:19 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifdef WIN
+#define NEEDED_BY_FESHVIEW
+#endif
+
+#ifndef _SVX_FILLITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SFXINIMGR_HXX //autogen
+#include 
+#endif
+#ifndef _SVDPAGE_HXX //autogen
+#include 
+#endif
+#ifndef _SFXAPP_HXX //autogen
+#include 
+#endif
+#ifndef _XOUTBMP_HXX //autogen
+#include 
+#endif
+#ifndef _SVDOOLE2_HXX //autogen
+#include 
+#endif
+#ifndef _FM_FMMODEL_HXX
+#include 
+#endif
+#ifndef _SVSTOR_HXX //autogen
+#include 
+#endif
+#ifndef _GRAPH_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_XEXCH_HXX
+#include 
+#endif
+#ifndef _SVX_XFLASIT_HXX //autogen
+#include 
+#endif
+#ifndef SVX_XFILLIT0_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_XFLCLIT_HXX //autogen
+#include 
+#endif
+#ifndef _DTRANS_HXX //autogen
+#include 
+#endif
+#ifndef _SFXDISPATCH_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BRSHITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_SVXIDS_HRC
+#include 
+#endif
+#ifndef _EXCHANGE_HXX //autogen
+#include 
+#endif
+#ifndef _SVDCAPT_HXX //autogen
+#include 
+#endif
+#ifndef _SVDOUNO_HXX //autogen
+#include 
+#endif
+
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _FMTCNTNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTORNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFLCNT_HXX //autogen
+#include 
+#endif
+#ifndef _FRMFMT_HXX //autogen
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _TXTFRM_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFLCNT_HXX //autogen
+#include 
+#endif
+#ifndef _FESH_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _ROOTFRM_HXX
+#include 
+#endif
+#ifndef _CNTFRM_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _TBLSEL_HXX
+#include 
+#endif
+#ifndef _SWTABLE_HXX
+#include 
+#endif
+#ifndef _FLYFRM_HXX
+#include 
+#endif
+#ifndef _PAGEFRM_HXX
+#include 
+#endif
+#ifndef _FLDBAS_HXX
+#include 
+#endif
+#ifndef _EDIMP_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include 
+#endif
+#ifndef _VIEWIMP_HXX
+#include 
+#endif
+#ifndef _DVIEW_HXX
+#include 
+#endif
+#ifndef _DCONTACT_HXX
+#include 
+#endif
+#ifndef _DFLYOBJ_HXX
+#include 
+#endif
+#ifndef _REDLENUM_HXX
+#include 
+#endif
+#ifndef _SFXVIEWSH_HXX
+#include 
+#endif
+#ifndef _SFXVIEWFRM_HXX
+#include 
+#endif
+
+
+/*************************************************************************
+|*
+|*  FindPageFrm(), Sucht den PageFrm zum Pt, die StartPage wird hereingereicht.
+|*
+|*  Ersterstellung      MA 11. Oct. 95
+|*  Letzte Aenderung    MA 11. Oct. 95
+|
+|*************************************************************************/
+const SwFrm *FindPage( const SwFrm *pPg, const Point &rPt )
+{
+    if ( !pPg->Frm().IsInside( rPt ) )
+    {
+        const long nTop = rPt.Y();
+        FASTBOOL bPrvAllowed = TRUE;
+        FASTBOOL bNxtAllowed = TRUE;
+        do
+        {   if ( pPg->Frm().Top() > nTop && bPrvAllowed )
+            {
+                if ( pPg->GetPrev() )
+                {
+                    bNxtAllowed = FALSE;
+                    pPg = pPg->GetPrev();
+                }
+                else
+                    break;
+            }
+            else if ( pPg->Frm().Bottom() < nTop && bNxtAllowed )
+            {
+                if ( pPg->GetNext() )
+                {
+                    bPrvAllowed = FALSE;
+                    pPg = pPg->GetNext();
+                }
+                else
+                    break;
+            }
+            else
+                break;
+
+        } while ( !pPg->Frm().IsInside( rPt ) );
+    }
+    return pPg;
+}
+
+
+/*************************************************************************
+|*
+|*  SwFEShell::Copy()   Copy fuer das Interne Clipboard.
+|*      Kopiert alle Selektionen in das Clipboard.
+|*
+|*  Ersterstellung      JP ??
+|*  Letzte Aenderung    MA 22. Feb. 95
+|
+|*************************************************************************/
+
+BOOL SwFEShell::Copy( SwDoc* pClpDoc, const String* pNewClpTxt )
+{
+    ASSERT( pClpDoc, "kein Clipboard-Dokument"  );
+
+    pClpDoc->DoUndo( FALSE );       // immer auf FALSE !!
+
+    // steht noch Inhalt im ClpDocument, dann muss dieser geloescht werden
+    SwNodeIndex aSttIdx( pClpDoc->GetNodes().GetEndOfExtras(), 2 );
+    SwTxtNode* pTxtNd = aSttIdx.GetNode().GetTxtNode();
+    if( !pTxtNd || pTxtNd->GetTxt().Len() ||
+        aSttIdx.GetIndex()+1 != pClpDoc->GetNodes().GetEndOfContent().GetIndex() )
+    {
+        pClpDoc->GetNodes().Delete( aSttIdx,
+            pClpDoc->GetNodes().GetEndOfContent().GetIndex() - aSttIdx.GetIndex() );
+        pTxtNd = pClpDoc->GetNodes().MakeTxtNode( aSttIdx,
+                            (SwTxtFmtColl*)pClpDoc->GetDfltTxtFmtColl() );
+        aSttIdx--;
+    }
+
+    // stehen noch FlyFrames rum, loesche auch diese
+    for( USHORT n = 0; n < pClpDoc->GetSpzFrmFmts()->Count(); ++n )
+    {
+        SwFlyFrmFmt* pFly = (SwFlyFrmFmt*)(*pClpDoc->GetSpzFrmFmts())[n];
+        pClpDoc->DelLayoutFmt( pFly );
+    }
+    pClpDoc->GCFieldTypes();        // loesche die FieldTypes
+
+    // wurde ein String uebergeben, so kopiere diesen in das Clipboard-
+    // Dokument. Somit kann auch der Calculator das interne Clipboard
+    // benutzen.
+    if( pNewClpTxt )
+    {
+        pTxtNd->Insert( *pNewClpTxt, SwIndex( pTxtNd ) );
+        return TRUE;                // das wars.
+    }
+
+    pClpDoc->LockExpFlds();
+    pClpDoc->SetRedlineMode_intern( REDLINE_DELETE_REDLINES );
+    BOOL bRet;
+
+    // soll ein FlyFrame kopiert werden ?
+    if( IsFrmSelected() )
+    {
+        // hole das FlyFormat
+        SwFlyFrm* pFly = FindFlyFrm();
+        SwFrmFmt* pFlyFmt = pFly->GetFmt();
+        SwFmtAnchor aAnchor( pFlyFmt->GetAnchor() );
+
+        if ( FLY_AT_CNTNT == aAnchor.GetAnchorId() ||
+             FLY_AUTO_CNTNT == aAnchor.GetAnchorId() ||
+             FLY_AT_FLY == aAnchor.GetAnchorId() ||
+             FLY_IN_CNTNT == aAnchor.GetAnchorId() )
+        {
+            SwPosition aPos( aSttIdx );
+            if( FLY_IN_CNTNT == aAnchor.GetAnchorId() )
+                aPos.nContent.Assign( pTxtNd, 0 );
+            aAnchor.SetAnchor( &aPos );
+        }
+        pFlyFmt = pClpDoc->CopyLayoutFmt( *pFlyFmt, aAnchor );
+
+        // sorge dafuer das das "RootFmt" als erstes im SpzArray-steht
+        // (Es wurden ggf. Flys in Flys kopiert.
+        SwSpzFrmFmts& rSpzFrmFmts = *(SwSpzFrmFmts*)pClpDoc->GetSpzFrmFmts();
+        if( rSpzFrmFmts[ 0 ] != pFlyFmt )
+        {
+            USHORT nPos = rSpzFrmFmts.GetPos( pFlyFmt );
+            ASSERT( nPos != USHRT_MAX, "Fly steht nicht im Spz-Array" );
+
+            rSpzFrmFmts.Remove( nPos );
+            rSpzFrmFmts.Insert( pFlyFmt, 0 );
+        }
+
+        if( FLY_IN_CNTNT == aAnchor.GetAnchorId() )
+        {
+            // JP 13.02.99 Bug 61863: wenn eine Rahmenselektion ins Clipboard
+            //              gestellt wird, so muss beim Pasten auch wieder
+            //              eine solche vorgefunden werden. Also muss im Node
+            //              das kopierte TextAttribut wieder entfernt werden,
+            //              sonst wird es als TextSelektion erkannt
+            const SwIndex& rIdx = pFlyFmt->GetAnchor().GetCntntAnchor()->nContent;
+            SwTxtFlyCnt* pTxtFly = (SwTxtFlyCnt*)pTxtNd->GetTxtAttr(
+                                                rIdx, RES_TXTATR_FLYCNT );
+            if( pTxtFly )
+            {
+                ((SwFmtFlyCnt&)pTxtFly->GetFlyCnt()).SetFlyFmt( 0 );
+                pTxtNd->Erase( rIdx, 1 );
+            }
+        }
+        bRet = TRUE;
+    }
+    else if ( IsObjSelected() )
+    {
+        Size aSiz( 0, - GetDoc()->GetDrawModel()->GetPage( 0 )->
+                        GetAllObjBoundRect().Top() );
+
+        SwPosition aPos( aSttIdx, SwIndex( pTxtNd, 0 ));
+        const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkList();
+        for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
+        {
+            SdrObject *pObj = rMrkList.GetMark( i )->GetObj();
+
+            if( Imp()->GetDrawView()->IsGroupEntered() ||
+                ( !pObj->GetUserCall() && pObj->GetUpGroup()) )
+            {
+                SfxItemSet aSet( pClpDoc->GetAttrPool(), aFrmFmtSetRange );
+
+                SwFmtAnchor aAnchor( FLY_AT_CNTNT );
+                aAnchor.SetAnchor( &aPos );
+                aSet.Put( aAnchor );
+
+                SdrObject* pNew = pClpDoc->CloneSdrObj( *pObj, FALSE, TRUE );
+//JP 07.01.00: why move??
+//              pNew->NbcMove( aSiz );
+                pClpDoc->Insert( SwPaM( aPos ), *pNew, &aSet );
+            }
+            else
+            {
+                SwDrawContact *pContact = (SwDrawContact*)GetUserCall( pObj );
+                SwFrmFmt *pFmt = pContact->GetFmt();
+                SwFmtAnchor aAnchor( pFmt->GetAnchor() );
+                if ( FLY_AT_CNTNT == aAnchor.GetAnchorId() ||
+                     FLY_AUTO_CNTNT == aAnchor.GetAnchorId() ||
+                     FLY_AT_FLY == aAnchor.GetAnchorId() ||
+                     FLY_IN_CNTNT == aAnchor.GetAnchorId() )
+                {
+                    aAnchor.SetAnchor( &aPos );
+                }
+
+                pClpDoc->CopyLayoutFmt( *pFmt, aAnchor );
+            }
+        }
+        bRet = TRUE;
+    }
+    else
+        bRet = _CopySelToDoc( pClpDoc, 0 );     // kopiere die Selectionen
+
+    pClpDoc->SetRedlineMode_intern( 0 );
+    pClpDoc->UnlockExpFlds();
+    if( !pClpDoc->IsExpFldsLocked() )
+        pClpDoc->UpdateExpFlds();
+
+    return bRet;
+}
+
+const Point &lcl_FindBasePos( const SwFrm *pFrm, const Point &rPt )
+{
+    const SwFrm *pF = pFrm;
+    while ( pF && !pF->Frm().IsInside( rPt ) )
+    {
+        if ( pF->IsCntntFrm() )
+            pF = ((SwCntntFrm*)pF)->GetFollow();
+        else
+            pF = 0;
+    }
+    if ( pF )
+        return pF->Frm().Pos();
+    else
+        return pFrm->Frm().Pos();
+}
+
+BOOL lcl_SetAnchor( const SwPosition& rPos, const SwNode& rNd, SwFlyFrm* pFly,
+                const Point& rInsPt, SwFEShell& rDestShell, SwFmtAnchor& rAnchor,
+                Point& rNewPos, BOOL bCheckFlyRecur )
+{
+    BOOL bRet = TRUE;
+    rAnchor.SetAnchor( &rPos );
+    SwCntntFrm* pTmpFrm = rNd.GetCntntNode()->GetFrm( &rInsPt, 0, FALSE );
+    SwFlyFrm *pTmpFly = pTmpFrm->FindFlyFrm();
+    if( pTmpFly && bCheckFlyRecur && pFly->IsUpperOf( pTmpFly ) )
+        bRet = FALSE;
+    else if ( FLY_AT_FLY == rAnchor.GetAnchorId() )
+    {
+        if( pTmpFly )
+        {
+            const SwNodeIndex& rIdx = *pTmpFly->GetFmt()->GetCntnt().GetCntntIdx();
+            SwPosition aPos( rIdx );
+            rAnchor.SetAnchor( &aPos );
+            rNewPos = pTmpFly->Frm().Pos();
+        }
+        else
+        {
+            rAnchor.SetType( FLY_PAGE );
+            rAnchor.SetPageNum( rDestShell.GetPageNumber( rInsPt ) );
+            const SwFrm *pPg = pTmpFrm->FindPageFrm();
+            rNewPos = pPg->Frm().Pos();
+        }
+    }
+    else
+        rNewPos = ::lcl_FindBasePos( pTmpFrm, rInsPt );
+    return bRet;
+}
+
+BOOL SwFEShell::CopyDrawSel( SwFEShell* pDestShell, const Point& rSttPt,
+                                const Point& rInsPt, BOOL bIsMove )
+{
+    BOOL bRet = TRUE;
+
+    //Die Liste muss kopiert werden, weil unten die neuen Objekte
+    //selektiert werden.
+    const SdrMarkList aMrkList( Imp()->GetDrawView()->GetMarkList() );
+    ULONG nMarkCount = aMrkList.GetMarkCount();
+    if( pDestShell->Imp()->GetDrawView() )
+        pDestShell->Imp()->GetDrawView()->UnmarkAll();
+    else
+        // sollte mal eine erzeugt werden
+        pDestShell->MakeDrawView();
+
+    SdrPageView *pDestPgView = pDestShell->Imp()->GetPageView(),
+                *pSrcPgView = Imp()->GetPageView();
+    SwDrawView *pDestDrwView = pDestShell->Imp()->GetDrawView(),
+                *pSrcDrwView = Imp()->GetDrawView();
+    SwDoc* pDestDoc = pDestShell->GetDoc();
+
+    Size aSiz( rInsPt.X() - rSttPt.X(), rInsPt.Y() - rSttPt.Y() );
+    for( USHORT i = 0; i < nMarkCount; ++i )
+    {
+        SdrObject *pObj = aMrkList.GetMark( i )->GetObj();
+
+        SwDrawContact *pContact = (SwDrawContact*)GetUserCall( pObj );
+        SwFrmFmt *pFmt = pContact->GetFmt();
+        const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
+
+        BOOL bInsWithFmt = TRUE;
+
+        if( pDestDrwView->IsGroupEntered() )
+        {
+            // in die Gruppe einfuegen, wenns aus einer betretenen Gruppe
+            // kommt oder das Object nicht zeichengebunden ist
+            if( pSrcDrwView->IsGroupEntered() ||
+                FLY_IN_CNTNT != rAnchor.GetAnchorId() )
+
+            {
+                SdrObject* pNew = pDestDoc->CloneSdrObj( *pObj, bIsMove &&
+                                        GetDoc() == pDestDoc, FALSE );
+                pNew->NbcMove( aSiz );
+                pDestDrwView->InsertObject( pNew, *pDestPgView );
+                bInsWithFmt = FALSE;
+            }
+        }
+
+        if( bInsWithFmt )
+        {
+            SwFmtAnchor aAnchor( rAnchor );
+            Point aNewAnch;
+
+            if ( FLY_AT_CNTNT == aAnchor.GetAnchorId() ||
+                    FLY_AUTO_CNTNT == aAnchor.GetAnchorId() ||
+                    FLY_AT_FLY == aAnchor.GetAnchorId() ||
+                    FLY_IN_CNTNT == aAnchor.GetAnchorId() )
+            {
+                if ( this == pDestShell )
+                {
+                    //gleiche Shell? Dann erfrage die Position an der
+                    //uebergebenen DokumentPosition
+                    SwPosition aPos( *GetCrsr()->GetPoint() );
+                    Point aPt( rInsPt );
+                    aPt -= rSttPt - pObj->GetSnapRect().TopLeft();
+                    SwCrsrMoveState aState( MV_SETONLYTEXT );
+                    GetLayout()->GetCrsrOfst( &aPos, aPt, &aState );
+                    const SwNode *pNd;
+                    if( (pNd = &aPos.nNode.GetNode())->IsNoTxtNode() )
+                        bRet = FALSE;
+                    else
+                        bRet = ::lcl_SetAnchor( aPos, *pNd, 0, rInsPt,
+                                *pDestShell, aAnchor, aNewAnch, FALSE );
+                }
+                else
+                {
+                    SwPaM *pCrsr = pDestShell->GetCrsr();
+                    if( pCrsr->GetNode()->IsNoTxtNode() )
+                        bRet = FALSE;
+                    else
+                        bRet = ::lcl_SetAnchor( *pCrsr->GetPoint(),
+                                                *pCrsr->GetNode(), 0, rInsPt,
+                                                *pDestShell, aAnchor,
+                                                aNewAnch, FALSE );
+                }
+            }
+            else if( FLY_PAGE == aAnchor.GetAnchorId() )
+            {
+                aAnchor.SetPageNum( pDestShell->GetPageNumber( rInsPt ) );
+                const SwFrm *pPg = ::FindPage( pDestShell->GetLayout()->Lower(), rInsPt);
+                aNewAnch = pPg->Frm().Pos();
+            }
+
+            if( bRet )
+            {
+                if( pSrcDrwView->IsGroupEntered() ||
+                    ( !pObj->GetUserCall() && pObj->GetUpGroup()) )
+                {
+                    SfxItemSet aSet( pDestDoc->GetAttrPool(),aFrmFmtSetRange);
+                    aSet.Put( aAnchor );
+                    SdrObject* pNew = pDestDoc->CloneSdrObj( *pObj, bIsMove &&
+                                                GetDoc() == pDestDoc, TRUE );
+                    pFmt = pDestDoc->Insert( *pDestShell->GetCrsr(),
+                                            *pNew, &aSet );
+                }
+                else
+                    pFmt = pDestDoc->CopyLayoutFmt( *pFmt, aAnchor );
+
+                //Kann 0 sein, weil Draws in Kopf-/Fusszeilen nicht erlaubt sind.
+                if ( pFmt )
+                {
+                    SdrObject *pNew = pFmt->FindSdrObject();
+                    if( FLY_IN_CNTNT != aAnchor.GetAnchorId() )
+                    {
+                        Point aPos( rInsPt );
+                        aPos -= aNewAnch;
+                        aPos -= rSttPt - pObj->GetSnapRect().TopLeft();
+                        pNew->ImpSetAnchorPos( aNewAnch );
+                        pNew->SetRelativePos( aPos );
+                    }
+                    pDestDrwView->MarkObj( pNew, pDestPgView );
+                }
+            }
+        }
+    }
+
+    if ( bIsMove && bRet )
+    {
+        if( pDestShell == this )
+        {
+            const SdrMarkList aList( pSrcDrwView->GetMarkList() );
+            pSrcDrwView->UnmarkAll();
+
+            ULONG nMarkCount = aMrkList.GetMarkCount();
+            for ( USHORT i = 0; i < nMarkCount; ++i )
+            {
+                SdrObject *pObj = aMrkList.GetMark( i )->GetObj();
+                pSrcDrwView->MarkObj( pObj, pSrcPgView );
+            }
+            DelSelectedObj();
+            nMarkCount = aList.GetMarkCount();
+            for ( i = 0; i < nMarkCount; ++i )
+            {
+                SdrObject *pObj = aList.GetMark( i )->GetObj();
+                pSrcDrwView->MarkObj( pObj, pSrcPgView );
+            }
+        }
+        else
+            DelSelectedObj();
+    }
+
+//  if( this != pDestShell )
+//      pDestDrwView->SetMarkHdlHidden( TRUE );
+
+    return bRet;
+}
+
+BOOL SwFEShell::Copy( SwFEShell* pDestShell, const Point& rSttPt,
+                        const Point& rInsPt, BOOL bIsMove )
+{
+    BOOL bRet = FALSE;
+
+    ASSERT( pDestShell, "Copy ohne DestShell." );
+    ASSERT( this == pDestShell || !pDestShell->IsObjSelected(),
+            "Dest-Shell darf nie im Obj-Modus sein" );
+
+    SET_CURR_SHELL( pDestShell );
+
+    pDestShell->StartAllAction();
+    pDestShell->GetDoc()->LockExpFlds();
+
+    // Referenzen sollen verschoben werden.
+    BOOL bCopyIsMove = pDoc->IsCopyIsMove();
+    if( bIsMove )
+        // am Doc ein Flag setzen, damit in den TextNodes
+        pDoc->SetCopyIsMove( TRUE );
+
+    SwRedlineMode eOldRedlMode = pDestShell->GetDoc()->GetRedlineMode();
+    pDestShell->GetDoc()->SetRedlineMode_intern( eOldRedlMode | REDLINE_DELETE_REDLINES );
+
+    // sind Tabellen-Formeln im Bereich, dann muss erst die Tabelle
+    // angezeigt werden, damit die Tabellen-Formel den neuen Wert errechnen
+    // kann (bei Bereichen wird sich ueber das Layout die einzelnen Boxen
+    // besorgt)
+    SwFieldType* pTblFldTyp = pDestShell->GetDoc()->GetSysFldType( RES_TABLEFLD );
+
+    if( IsFrmSelected() )
+    {
+        SwFlyFrm* pFly = FindFlyFrm();
+        SwFrmFmt* pFlyFmt = pFly->GetFmt();
+        SwFmtAnchor aAnchor( pFlyFmt->GetAnchor() );
+        bRet = TRUE;
+        Point aNewAnch;
+
+        if ( FLY_AT_CNTNT == aAnchor.GetAnchorId() ||
+             FLY_AUTO_CNTNT == aAnchor.GetAnchorId() ||
+             FLY_AT_FLY == aAnchor.GetAnchorId() ||
+             FLY_IN_CNTNT == aAnchor.GetAnchorId() )
+        {
+            if ( this == pDestShell )
+            {
+                // gleiche Shell? Dann erfrage die Position an der
+                // uebergebenen DokumentPosition
+                SwPosition aPos( *GetCrsr()->GetPoint() );
+                Point aPt( rInsPt );
+                aPt -= rSttPt - pFly->Frm().Pos();
+                SwCrsrMoveState aState( MV_SETONLYTEXT );
+                GetLayout()->GetCrsrOfst( &aPos, aPt, &aState );
+                const SwNode *pNd;
+                if( (pNd = GetDoc()->GetNodes()[ aPos.nNode ])->IsNoTxtNode() )
+                    bRet = FALSE;
+                else
+                {   //Nicht in sich selbst kopieren
+                    const SwNodeIndex *pTmp = pFlyFmt->GetCntnt().GetCntntIdx();
+                    if ( aPos.nNode > *pTmp && aPos.nNode <
+                        GetDoc()->GetNodes()[*pTmp]->EndOfSectionIndex() )
+                    {
+                        bRet = FALSE;
+                    }
+                    else
+                        bRet = ::lcl_SetAnchor( aPos, *pNd, pFly, rInsPt,
+                                        *pDestShell, aAnchor, aNewAnch, TRUE );
+                }
+            }
+            else
+            {
+                const SwPaM *pCrsr = pDestShell->GetCrsr();
+                if( pCrsr->GetNode()->IsNoTxtNode() )
+                    bRet = FALSE;
+                else
+                    bRet = ::lcl_SetAnchor( *pCrsr->GetPoint(), *pCrsr->GetNode(),
+                                            pFly, rInsPt, *pDestShell, aAnchor,
+                                    aNewAnch, GetDoc() == pDestShell->GetDoc());
+            }
+        }
+        else if( FLY_PAGE == aAnchor.GetAnchorId() )
+        {
+            aAnchor.SetPageNum( pDestShell->GetPageNumber( rInsPt ) );
+            const SwFrm *pPg = ::FindPage( pDestShell->GetLayout()->Lower(), rInsPt);
+            aNewAnch = pPg->Frm().Pos();
+        }
+        else
+            ASSERT( !this, "was fuer ein Anchor ist es denn?" );
+
+        if( bRet )
+        {
+            SwFrmFmt *pOldFmt = pFlyFmt;
+            pFlyFmt = pDestShell->GetDoc()->CopyLayoutFmt( *pFlyFmt, aAnchor );
+
+            if( FLY_IN_CNTNT != aAnchor.GetAnchorId() )
+            {
+                Point aPos( rInsPt );
+                aPos -= aNewAnch;
+                aPos -= rSttPt - pFly->Frm().Pos();
+                pFlyFmt->SetAttr( SwFmtHoriOrient( aPos.X(),HORI_NONE,FRAME ) );
+                pFlyFmt->SetAttr( SwFmtVertOrient( aPos.Y(),VERT_NONE,FRAME ) );
+            }
+
+            const Point aPt( pDestShell->GetCrsrDocPos() );
+
+            if( bIsMove )
+                GetDoc()->DelLayoutFmt( pOldFmt );
+
+            // nur selektieren wenn es in der gleichen Shell verschoben/
+            //  kopiert wird
+            SwFlyFrm* pFlyFrm = ((SwFlyFrmFmt*)pFlyFmt)->GetFrm( &aPt, FALSE );
+            if( pFlyFrm )
+            {
+                //JP 12.05.98: sollte das nicht im SelectFlyFrm stehen???
+                pDestShell->Imp()->GetDrawView()->UnmarkAll();
+                pDestShell->SelectFlyFrm( *pFlyFrm, TRUE );
+            }
+
+            if( this != pDestShell && !pDestShell->HasShFcs() )
+                pDestShell->Imp()->GetDrawView()->SetMarkHdlHidden( TRUE );
+        }
+    }
+    else if ( IsObjSelected() )
+        bRet = CopyDrawSel( pDestShell, rSttPt, rInsPt, bIsMove );
+    else if( IsTableMode() )
+    {
+        // kopiere Teile aus einer Tabelle: lege eine Tabelle mit der Breite
+        // von der Originalen an und kopiere die selectierten Boxen.
+        // Die Groessen werden prozentual korrigiert.
+
+        // lasse ueber das Layout die Boxen suchen
+        const SwTableNode* pTblNd;
+        SwSelBoxes aBoxes;
+        GetTblSel( *this, aBoxes );
+        if( aBoxes.Count() &&
+            0 != (pTblNd = aBoxes[0]->GetSttNd()->FindTableNode()) )
+        {
+            SwPosition* pDstPos = 0;
+            if( this == pDestShell )
+            {
+                // gleiche Shell? Dann erzeuge einen Crsr an der
+                // uebergebenen DokumentPosition
+                pDstPos = new SwPosition( *GetCrsr()->GetPoint() );
+                Point aPt( rInsPt );
+                GetLayout()->GetCrsrOfst( pDstPos, aPt );
+                if( !GetDoc()->GetNodes()[ pDstPos->nNode ]->IsNoTxtNode() )
+                    bRet = TRUE;
+            }
+            else if( !pDestShell->GetCrsr()->GetNode()->IsNoTxtNode() )
+            {
+                pDstPos = new SwPosition( *pDestShell->GetCrsr()->GetPoint() );
+                bRet = TRUE;
+            }
+
+            if( bRet )
+            {
+                if( GetDoc() == pDestShell->GetDoc() )
+                    ParkTblCrsr();
+
+                bRet = pDestShell->GetDoc()->InsCopyOfTbl( *pDstPos, aBoxes,0,
+                                        bIsMove && this == pDestShell &&
+                                        aBoxes.Count() == pTblNd->GetTable().
+                                        GetTabSortBoxes().Count(),
+                                        this != pDestShell );
+
+                if( this != pDestShell )
+                    *pDestShell->GetCrsr()->GetPoint() = *pDstPos;
+
+                // wieder alle geparkten Crsr erzeugen?
+                if( GetDoc() == pDestShell->GetDoc() )
+                    GetCrsr();
+
+                // JP 16.04.99: Bug 64908 - InsPos setzen, damit der geparkte
+                //              Cursor auf die EinfuegePos. positioniert wird
+                if( this == pDestShell )
+                    GetCrsrDocPos() = rInsPt;
+            }
+            delete pDstPos;
+        }
+    }
+    else
+    {
+        bRet = TRUE;
+        if( this == pDestShell )
+        {
+            // gleiche Shell? Dann erfrage die Position an der
+            // uebergebenen DokumentPosition
+            SwPosition aPos( *GetCrsr()->GetPoint() );
+            Point aPt( rInsPt );
+            GetLayout()->GetCrsrOfst( &aPos, aPt );
+            bRet = !GetDoc()->GetNodes()[ aPos.nNode ]->IsNoTxtNode();
+        }
+        else if( pDestShell->GetCrsr()->GetNode()->IsNoTxtNode() )
+            bRet = FALSE;
+
+        if( bRet )
+        {
+
+            bRet = 0 != SwEditShell::Copy( pDestShell );
+        }
+    }
+
+    pDestShell->GetDoc()->SetRedlineMode_intern( eOldRedlMode );
+    pDoc->SetCopyIsMove( bCopyIsMove );
+
+    // wurden neue Tabellenformeln eingefuegt ?
+    if( pTblFldTyp->GetDepends() )
+    {
+        // alte Actions beenden; die Tabellen-Frames werden angelegt und
+        // eine SSelection kann erzeugt werden
+        for( USHORT nActCnt = 0; pDestShell->ActionPend(); ++nActCnt )
+            pDestShell->EndAllAction();
+
+        for( ; nActCnt; --nActCnt )
+            pDestShell->StartAllAction();
+    }
+    pDestShell->GetDoc()->UnlockExpFlds();
+    pDestShell->GetDoc()->UpdateFlds();
+
+    pDestShell->EndAllAction();
+    return bRet;
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::Paste()  Paste fuer das Interne Clipboard.
+|*      Kopiert den Inhalt vom Clipboard in das Dokument.
+|*
+|*  Ersterstellung      JP ??
+|*  Letzte Aenderung    MA 22. Feb. 95
+|
+|*************************************************************************/
+
+BOOL SwFEShell::Paste( SwDoc* pClpDoc )
+{
+    SET_CURR_SHELL( this );
+    ASSERT( pClpDoc, "kein Clipboard-Dokument"  );
+
+    // dann bis zum Ende vom Nodes Array
+    SwNodeIndex aIdx( pClpDoc->GetNodes().GetEndOfExtras(), 2 );
+    SwPaM aCpyPam( aIdx ); //DocStart
+
+    // sind Tabellen-Formeln im Bereich, dann muss erst die Tabelle
+    // angezeigt werden, damit die Tabellen-Formel den neuen Wert errechnen
+    // kann (bei Bereichen wird sich ueber das Layout die einzelnen Boxen
+    // besorgt)
+    SwFieldType* pTblFldTyp = GetDoc()->GetSysFldType( RES_TABLEFLD );
+
+    SwTableNode *pDestNd, *pSrcNd = aCpyPam.GetNode()->GetTableNode();
+    if( !pSrcNd )                               // TabellenNode ?
+    {                                           // nicht ueberspringen!!
+        SwCntntNode* pCNd = aCpyPam.GetNode()->GetCntntNode();
+        if( pCNd )
+            aCpyPam.GetPoint()->nContent.Assign( pCNd, 0 );
+        else if( !aCpyPam.Move( fnMoveForward, fnGoNode ))
+            aCpyPam.Move( fnMoveBackward, fnGoNode );
+    }
+
+    aCpyPam.SetMark();
+    aCpyPam.Move( fnMoveForward, fnGoDoc );
+
+    BOOL bRet = TRUE, bDelTbl = TRUE;
+    StartAllAction();
+    GetDoc()->StartUndo( UNDO_INSGLOSSARY );
+    GetDoc()->LockExpFlds();
+
+    FOREACHPAM_START(this)
+
+        if( pSrcNd &&
+            0 != ( pDestNd = GetDoc()->IsIdxInTbl( PCURCRSR->GetPoint()->nNode )))
+        {
+            SwPosition aDestPos( *PCURCRSR->GetPoint() );
+
+            BOOL bParkTblCrsr = FALSE;
+            const SwStartNode* pSttNd =  PCURCRSR->GetNode()->FindTableBoxStartNode();
+
+            // Tabelle in Tabelle kopieren
+            // lasse ueber das Layout die Boxen suchen
+            SwSelBoxes aBoxes;
+            if( IsTableMode() )     // Tabellen-Selecktion ??
+            {
+                GetTblSel( *this, aBoxes );
+                ParkTblCrsr();
+                bParkTblCrsr = TRUE;
+            }
+            else if( !PCURCRSR->HasMark() && PCURCRSR->GetNext() == PCURCRSR &&
+                    !pSrcNd->GetTable().IsTblComplex() )
+            {
+                // dann die Tabelle "relativ" kopieren
+                SwTableBox* pBox = pDestNd->GetTable().GetTblBox(
+                                        pSttNd->GetIndex() );
+                ASSERT( pBox, "Box steht nicht in dieser Tabelle" );
+                aBoxes.Insert( pBox );
+            }
+
+            SwNodeIndex aNdIdx( *pDestNd->EndOfSectionNode());
+            if( !bParkTblCrsr )
+            {
+                // erstmal aus der gesamten Tabelle raus
+// ????? was ist mit Tabelle alleine im Rahmen ???????
+                SwCntntNode* pCNd = GetDoc()->GetNodes().GoNext( &aNdIdx );
+                SwPosition aPos( aNdIdx, SwIndex( pCNd, 0 ));
+                PaMCorrAbs( SwNodeIndex( *pDestNd ),
+                            SwNodeIndex( *pDestNd->EndOfSectionNode() ),
+                            aPos );
+            }
+
+            bRet = GetDoc()->InsCopyOfTbl( aDestPos, aBoxes, &pSrcNd->GetTable(),
+                                            FALSE, FALSE );
+
+            if( bParkTblCrsr )
+                GetCrsr();
+            else
+            {
+                // und wieder in die Box zurueck
+                aNdIdx = *pSttNd;
+                SwCntntNode* pCNd = GetDoc()->GetNodes().GoNext( &aNdIdx );
+                SwPosition aPos( aNdIdx, SwIndex( pCNd, 0 ));
+                PaMCorrAbs( PCURCRSR->GetPoint()->nNode, aPos );
+            }
+
+            break;      // aus der "while"-Schleife heraus
+        }
+        else if( *aCpyPam.GetPoint() == *aCpyPam.GetMark() &&
+                 pClpDoc->GetSpzFrmFmts()->Count() )
+        {
+            // so langsam sollte mal eine DrawView erzeugt werden
+            if( !Imp()->GetDrawView() )
+                MakeDrawView();
+
+            Size aSiz( 0, GetCharRect().Top() );
+            for ( USHORT i = 0; i < pClpDoc->GetSpzFrmFmts()->Count(); ++i )
+            {
+                BOOL bInsWithFmt = TRUE;
+                const SwFrmFmt& rCpyFmt = *(*pClpDoc->GetSpzFrmFmts())[i];
+
+                if( Imp()->GetDrawView()->IsGroupEntered() &&
+                    RES_DRAWFRMFMT == rCpyFmt.Which() &&
+                    FLY_IN_CNTNT != rCpyFmt.GetAnchor().GetAnchorId() )
+                {
+                    const SdrObject* pSdrObj = rCpyFmt.FindSdrObject();
+                    if( pSdrObj )
+                    {
+                        SdrObject* pNew = GetDoc()->CloneSdrObj( *pSdrObj,
+                                                            FALSE, FALSE );
+                        pNew->NbcMove( aSiz );
+                        Imp()->GetDrawView()->InsertObject( pNew,
+                                                        *Imp()->GetPageView() );
+                        bInsWithFmt = FALSE;
+                    }
+                }
+
+                if( bInsWithFmt  )
+                {
+                    SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() );
+                    if( FLY_AT_CNTNT == aAnchor.GetAnchorId() ||
+                        FLY_AUTO_CNTNT == aAnchor.GetAnchorId() ||
+                        FLY_IN_CNTNT == aAnchor.GetAnchorId() )
+                    {
+                        SwPosition* pPos = PCURCRSR->GetPoint();
+                        if( RES_DRAWFRMFMT == rCpyFmt.Which() &&
+                            GetDoc()->IsInHeaderFooter( pPos->nNode ))
+                            continue;       // Header / Footer  -> nicht kopieren!!!
+
+                        aAnchor.SetAnchor( pPos );
+                    }
+                    else if( FLY_PAGE == aAnchor.GetAnchorId() )
+                    {
+                        aAnchor.SetPageNum( GetPhyPageNum() );
+                    }
+                    else if( FLY_AT_FLY == aAnchor.GetAnchorId() )
+                    {
+                        Point aPt;
+                        lcl_SetAnchor( *PCURCRSR->GetPoint(), *PCURCRSR->GetNode(),
+                                        0, aPt, *this, aAnchor, aPt, FALSE );
+                    }
+
+                    SwFrmFmt * pNew = GetDoc()->CopyLayoutFmt( rCpyFmt, aAnchor );
+
+                    //Kann 0 sein, weil Draws in Kopf-/Fusszeilen nicht erlaubt sind.
+                    if( pNew )
+                    {
+                        if( RES_FLYFRMFMT == pNew->Which() )
+                        {
+                            const Point aPt( GetCrsrDocPos() );
+                            SwFlyFrm* pFlyFrm = ((SwFlyFrmFmt*)pNew)->
+                                                        GetFrm( &aPt, FALSE );
+                            if( pFlyFrm )
+                                SelectFlyFrm( *pFlyFrm, TRUE );
+                            // immer nur den ersten Fly-Frame nehmen; die anderen
+                            // wurden ueber Fly in Fly ins ClipBoard kopiert !
+                            break;
+                        }
+                        else
+                        {
+                            ASSERT( RES_DRAWFRMFMT == pNew->Which(), "Neues Format.");
+                            SdrObject *pObj = pNew->FindSdrObject();
+                            SwDrawView  *pDV = Imp()->GetDrawView();
+                            pDV->MarkObj( pObj, pDV->GetPageView( pObj->GetPage() ) );
+                        }
+                    }
+                }
+            }
+        }
+        else
+        {
+            if( bDelTbl && IsTableMode() )
+            {
+                SwEditShell::Delete();
+                bDelTbl = FALSE;
+            }
+
+            SwPosition& rInsPos = *PCURCRSR->GetPoint();
+            const SwStartNode* pBoxNd = GetDoc()->GetNodes()[
+                                rInsPos.nNode ]->FindTableBoxStartNode();
+            if( pBoxNd && 2 == pBoxNd->EndOfSectionIndex() -
+                                pBoxNd->GetIndex() &&
+                aCpyPam.GetPoint()->nNode != aCpyPam.GetMark()->nNode )
+            {
+                // es wird mehr als 1 Node in die akt. Box kopiert. Dann
+                // muessen die BoxAttribute aber entfernt werden.
+                GetDoc()->ClearBoxNumAttrs( rInsPos.nNode );
+            }
+            pClpDoc->Copy( aCpyPam, rInsPos );
+            SaveTblBoxCntnt( &rInsPos );
+        }
+
+    FOREACHPAM_END()
+    GetDoc()->EndUndo( UNDO_INSGLOSSARY );
+
+    // wurden neue Tabellenformeln eingefuegt ?
+    if( pTblFldTyp->GetDepends() )
+    {
+        // alte Actions beenden; die Tabellen-Frames werden angelegt und
+        // eine Selection kann erzeugt werden
+        for( USHORT nActCnt = 0; ActionPend(); ++nActCnt )
+            EndAllAction();
+
+        for( ; nActCnt; --nActCnt )
+            StartAllAction();
+    }
+    GetDoc()->UnlockExpFlds();
+    GetDoc()->UpdateFlds();
+    EndAllAction();
+
+    return bRet;
+}
+
+BOOL SwFEShell::GetDrawObjGraphic( ULONG nFmt, Graphic& rGrf ) const
+{
+    ASSERT( Imp()->HasDrawView(), "GetDrawObjGraphic without DrawView?" );
+    const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkList();
+    BOOL bConvert = TRUE;
+    if( rMrkList.GetMarkCount() )
+    {
+        if( rMrkList.GetMarkCount() == 1 &&
+            rMrkList.GetMark( 0 )->GetObj()->IsWriterFlyFrame() )
+        {
+            // Rahmen selektiert
+            if( CNT_GRF == GetCntType() )
+            {
+                Graphic aGrf( GetGraphic() );
+                if( FORMAT_GDIMETAFILE == nFmt )
+                {
+                    if( GRAPHIC_BITMAP != aGrf.GetType() )
+                    {
+                        rGrf = aGrf;
+                        bConvert = FALSE;
+                    }
+                    else if( GetWin() )
+                    {
+                        Size aSz;
+                        Point aPt;
+                        GetGrfSize( aSz );
+
+                        VirtualDevice aVirtDev;
+                        aVirtDev.EnableOutput( FALSE );
+
+                        MapMode aTmp( GetWin()->GetMapMode() );
+                        aTmp.SetOrigin( aPt );
+                        aVirtDev.SetMapMode( aTmp );
+
+                        GDIMetaFile aMtf;
+                        aMtf.Record( &aVirtDev );
+                        aGrf.Draw( &aVirtDev, aPt, aSz );
+                        aMtf.Stop();
+                        aMtf.SetPrefMapMode( aTmp );
+                        aMtf.SetPrefSize( aSz );
+#ifndef VCL
+                        aMtf.SetPrefPalette( OutputDevice::GetDitherPalette() );
+#endif
+                        rGrf = aMtf;
+                    }
+                }
+                else if( GRAPHIC_BITMAP == aGrf.GetType() )
+                {
+                    rGrf = aGrf;
+                    bConvert = FALSE;
+                }
+                else
+                {
+                    //fix(23806): Nicht die Originalgroesse, sondern die
+                    //aktuelle. Anderfalls kann es passieren, dass z.B. bei
+                    //Vektorgrafiken mal eben zig MB angefordert werden.
+                    const Size aSz( FindFlyFrm()->Prt().SSize() );
+                    VirtualDevice aVirtDev( *GetWin() );
+
+                    MapMode aTmp( MAP_TWIP );
+                    aVirtDev.SetMapMode( aTmp );
+                    if( aVirtDev.SetOutputSize( aSz ) )
+                    {
+                        aGrf.Draw( &aVirtDev, Point(), aSz );
+                        rGrf = aVirtDev.GetBitmap( Point(), aSz );
+                    }
+                    else
+                    {
+                        rGrf = aGrf;
+                        bConvert = FALSE;
+                    }
+                }
+            }
+        }
+        else if( FORMAT_GDIMETAFILE == nFmt )
+            rGrf = Imp()->GetDrawView()->GetAllMarkedMetaFile();
+        else if( FORMAT_BITMAP == nFmt )
+            rGrf = Imp()->GetDrawView()->GetAllMarkedBitmap();
+    }
+    return bConvert;
+}
+
+void SwFEShell::Paste( SvStorageStream& rStrm, USHORT nAction,
+                        const Point* pPt )
+{
+    SET_CURR_SHELL( this );
+    StartAllAction();
+    StartUndo();
+    String aTmpStr( SFX_APP()->GetAppIniManager()->Get(SFX_KEY_PALETTE_PATH));
+    FmFormModel* pModel = new FmFormModel( aTmpStr, (SfxItemPool*)0,
+                                    (SvPersist*)GetDoc()->GetDocShell() );
+    pModel->SetStreamingSdrModel(TRUE);
+    rStrm.Seek(0);
+    pModel->GetItemPool().Load( rStrm );
+    rStrm >> *pModel;
+    if ( !Imp()->HasDrawView() )
+        Imp()->MakeDrawView();
+
+    Point aPos( pPt ? *pPt : GetCharRect().Pos() );
+    SdrView *pView = Imp()->GetDrawView();
+
+    //Drop auf bestehendes Objekt: Objekt ersetzen oder neu Attributieren.
+    if( 1 == pModel->GetPage(0)->GetObjCount() &&
+        1 == pView->GetMarkList().GetMarkCount() )
+    {
+        SdrObject* pClpObj = pModel->GetPage(0)->GetObj(0);
+        SdrObject* pOldObj = pView->GetMarkList().GetMark( 0 )->GetObj();
+
+        if( SW_PASTESDR_SETATTR == nAction && pOldObj->IsWriterFlyFrame() )
+            nAction = SW_PASTESDR_REPLACE;
+
+        switch( nAction )
+        {
+        case SW_PASTESDR_REPLACE:
+            {
+                const SwFrmFmt* pFmt;
+                const SwFrm* pAnchor;
+                if( pOldObj->IsWriterFlyFrame() )
+                {
+                    pFmt = FindFrmFmt( pOldObj );
+
+                    Point aNullPt;
+                    SwFlyFrm* pFlyFrm = ((SwFlyFrmFmt*)pFmt)->GetFrm( &aNullPt );
+                    pAnchor = pFlyFrm->GetAnchor();
+
+                    if( pAnchor->FindFooterOrHeader() )
+                    {
+                        // wenn TextRahmen in der Kopf/Fusszeile steht, dann
+                        // nicht ersetzen, sondern nur einfuegen
+                        nAction = SW_PASTESDR_INSERT;
+                        break;
+                    }
+                }
+
+                SdrObject* pNewObj = pClpObj->Clone();
+                Rectangle aOldObjRect( pOldObj->GetBoundRect() );
+                Size aOldObjSize( aOldObjRect.GetSize() );
+                Rectangle aNewRect( pNewObj->GetBoundRect() );
+                Size aNewSize( aNewRect.GetSize() );
+
+                Fraction aScaleWidth( aOldObjSize.Width(), aNewSize.Width() );
+                Fraction aScaleHeight( aOldObjSize.Height(), aNewSize.Height());
+                pNewObj->NbcResize( aNewRect.TopLeft(), aScaleWidth, aScaleHeight);
+
+                Point aVec = aOldObjRect.TopLeft() - aNewRect.TopLeft();
+                pNewObj->NbcMove(Size(aVec.X(), aVec.Y()));
+
+                pNewObj->SetLayer( pOldObj->GetLayer() );
+
+                if( pOldObj->IsWriterFlyFrame() )
+                {
+                    // Attribute sichern und dam SdrObject setzen
+                    SfxItemSet aFrmSet( pDoc->GetAttrPool(),
+                                            RES_SURROUND, RES_ANCHOR );
+                    aFrmSet.Set( pFmt->GetAttrSet() );
+
+                    Point aNullPt;
+                    if( pAnchor->IsTxtFrm() && ((SwTxtFrm*)pAnchor)->IsFollow() )
+                    {
+                        const SwTxtFrm* pTmp = (SwTxtFrm*)pAnchor;
+                        do {
+                            pTmp = pTmp->FindMaster();
+                            ASSERT( pTmp, "Where's my Master?" );
+                        } while( pTmp->IsFollow() );
+                        pAnchor = pTmp;
+                    }
+                    if( pOldObj->ISA( SdrCaptionObj ))
+                        aNullPt = ((SdrCaptionObj*)pOldObj)->GetTailPos();
+                    else
+                        aNullPt = aOldObjRect.TopLeft();
+                    pNewObj->NbcSetRelativePos( aNullPt - pAnchor->Frm().Pos() );
+                    pNewObj->NbcSetAnchorPos( pAnchor->Frm().Pos() );
+
+                    UINT32 nOrdNum = pOldObj->GetOrdNum();
+
+                    DelSelectedObj();
+
+                    pFmt = GetDoc()->Insert( *GetCrsr(), *pNewObj, &aFrmSet );
+
+                    // die Ordnungsnummer (Z-Order) noch uebertragen
+                    // JP 04.07.98: klappt aber nicht richtig!
+                    // pNewObj->SetOrdNum( nOrdNum );
+                }
+                else
+                    pView->ReplaceObject( pOldObj, *Imp()->GetPageView(),
+                                            pNewObj, TRUE );
+            }
+            break;
+
+        case SW_PASTESDR_SETATTR:
+            {
+                SfxItemSet aSet( GetAttrPool() );
+                pClpObj->TakeAttributes( aSet, TRUE, FALSE );
+                pView->SetAttributes( aSet, FALSE );
+            }
+            break;
+
+        default:
+            nAction = SW_PASTESDR_INSERT;
+            break;
+        }
+    }
+    else
+        nAction = SW_PASTESDR_INSERT;
+
+    if( SW_PASTESDR_INSERT == nAction )
+    {
+        GetDoc()->SetNoDrawUndoObj( TRUE );
+
+        pView->Paste( *pModel, aPos );
+
+        ULONG nCnt = pView->GetMarkList().GetMarkCount();
+        if( nCnt )
+        {
+            const Point aNull( 0, 0 );
+            for( ULONG i=0; i < nCnt; ++i )
+            {
+                SdrObject *pObj = pView->GetMarkList().GetMark(i)->GetObj();
+                pObj->ImpSetAnchorPos( aNull );
+            }
+
+            pView->SetCurrentObj( OBJ_GRUP, SdrInventor );
+            if ( nCnt > 1 )
+                pView->GroupMarked();
+            SdrObject *pObj = pView->GetMarkList().GetMark(0)->GetObj();
+            pObj->SetLayer( pObj->ISA( SdrUnoObj )
+                                ? GetDoc()->GetControlsId()
+                                : GetDoc()->GetHeavenId() );
+            const Rectangle &rSnap = pObj->GetSnapRect();
+            const Size aDiff( rSnap.GetWidth()/2, rSnap.GetHeight()/2 );
+            pView->MoveMarkedObj( aDiff );
+            ImpEndCreate();
+        }
+        GetDoc()->SetNoDrawUndoObj( FALSE );
+    }
+    EndUndo();
+    EndAllAction();
+    delete pModel;
+}
+
+BOOL SwFEShell::Paste( const Graphic &rGrf )
+{
+    SET_CURR_SHELL( this );
+    SdrObject* pObj;
+    SdrView *pView = Imp()->GetDrawView();
+
+    BOOL bRet = 1 == pView->GetMarkList().GetMarkCount() &&
+        (pObj = pView->GetMarkList().GetMark( 0 )->GetObj())->IsClosedObj() &&
+        !pObj->ISA( SdrOle2Obj );
+
+    if( bRet )
+    {
+        XOBitmap aXOBitmap( rGrf.GetBitmap() );
+        SfxItemSet aSet( GetAttrPool(), XATTR_FILLSTYLE, XATTR_FILLBITMAP );
+        aSet.Put( XFillStyleItem( XFILL_BITMAP ));
+        aSet.Put( XFillBitmapItem( aEmptyStr, aXOBitmap ));
+        pView->SetAttributes( aSet, FALSE );
+    }
+    return bRet;
+}
+
+BOOL SwFEShell::Paste( SotDataObject& rObj, const Point& rPt )
+{
+    SET_CURR_SHELL( this );
+    BOOL bRet = FALSE;
+
+    SvData aData( XFillExchangeData::RegisterClipboardFormatName() );
+    XFillExchangeData* pFillData = NULL;
+
+    if( rObj.GetData( &aData ) )
+    {
+        if (aData.GetData( (SvDataCopyStream**) &pFillData, XFillExchangeData::StaticType(), TRANSFER_MOVE))
+        {
+/*              BegUndo(String(SdResId(STR_UNDO_DRAGDROP)));
+            AddUndo(new SdrUndoAttrObj(*pPickObj));
+            EndUndo();*/
+
+            XFillAttrSetItem* pSetItem = pFillData->GetXFillAttrSetItem();
+            SfxItemSet rSet = pSetItem->GetItemSet();
+
+            XFillStyle eFill= ((XFillStyleItem&) rSet.Get(XATTR_FILLSTYLE)).GetValue();
+
+            if (eFill == XFILL_SOLID)
+            {
+                const XFillColorItem& rColItem = (XFillColorItem&) rSet.Get(XATTR_FILLCOLOR);
+                Color aColor = rColItem.GetValue();
+                String aName = rColItem.GetName();
+
+                SdrView *pSdrView = Imp()->GetDrawView();
+
+                if(pSdrView)
+                {
+                    SdrObject* pPickObj = NULL;
+                    // Ist ein Objekt getroffen worden?
+                    SdrPageView* pPV = NULL;
+                    pSdrView->PickObj( rPt, pPickObj, pPV);
+
+                    if ( pPickObj )
+                    {
+/*                          SfxItemSet aSet(pDoc->GetPool());
+
+                        BOOL bClosed = pPickObj->IsClosedObj();
+                        SdWindow* pWin = pViewSh->GetActiveWindow();
+                        USHORT nHitLog = USHORT ( pWin->PixelToLogic(Size(HITPIX,0)).Width() );
+                        const long  n2HitLog = nHitLog * 2;
+                        Point aHitPosR( aPos );
+                        Point aHitPosL( aPos );
+                        Point aHitPosT( aPos );
+                        Point aHitPosB( aPos );
+
+                        aHitPosR.X() += n2HitLog;
+                        aHitPosL.X() -= n2HitLog;
+                        aHitPosT.Y() += n2HitLog;
+                        aHitPosB.Y() -= n2HitLog;
+
+                        const SetOfByte* pVisiLayer = &GetPageViewPvNum(0)->GetVisibleLayers();
+
+                        if (bClosed                                          &&
+                            pPickObj->IsHit( aHitPosR, nHitLog, pVisiLayer ) &&
+                            pPickObj->IsHit( aHitPosL, nHitLog, pVisiLayer ) &&
+                            pPickObj->IsHit( aHitPosT, nHitLog, pVisiLayer ) &&
+                            pPickObj->IsHit( aHitPosB, nHitLog, pVisiLayer ) )
+                        {
+                            // Flaechenfuellung
+                            aSet.Put(XFillColorItem(aName, aColor));
+                            aSet.Put(XFillStyleItem(XFILL_SOLID));
+                        }
+                        else
+                        {
+                            // Linienstil hinzufuegen
+                            aSet.Put(XLineColorItem(aName, aColor));
+                        }
+
+                        // Textfarbe hinzufuegen
+    //                    aSet.Put(SvxColorItem(aColor, ITEMID_COLOR));
+
+                        pPickObj->SetAttributes(aSet, FALSE);*/
+                        bRet = TRUE;
+                    }
+                }
+                if (!bRet)  // Kein DrawObjekt
+                {
+                    SvxBrushItem aBrushItem(aColor, SID_ATTR_BRUSH);
+                    SfxViewShell* pViewShell = GetSfxViewShell();
+                    DBG_ASSERT(pViewShell, "no SfxViewShell?")
+                    if(pViewShell)
+                        pViewShell->GetViewFrame()->GetDispatcher()->
+                            Execute(    SID_ATTR_BRUSH, SFX_CALLMODE_SLOT,
+                                                &aBrushItem, 0L);
+                    bRet = TRUE;
+                }
+            }
+        }
+    }
+
+    return bRet;
+}
+
+
diff --git a/sw/source/core/frmedt/fedesc.cxx b/sw/source/core/frmedt/fedesc.cxx
new file mode 100644
index 000000000000..da1e2a177b20
--- /dev/null
+++ b/sw/source/core/frmedt/fedesc.cxx
@@ -0,0 +1,327 @@
+/*************************************************************************
+ *
+ *  $RCSfile: fedesc.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:19 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _REF_HXX
+#include 
+#endif
+
+#ifndef _FESH_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _PAGEFRM_HXX
+#include 
+#endif
+#ifndef _ROOTFRM_HXX
+#include 
+#endif
+#ifndef _CNTFRM_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _NODE_HXX
+#include 
+#endif
+#ifndef _FMTPDSC_HXX //autogen
+#include 
+#endif
+#ifndef _PAGEDESC_HXX
+#include 
+#endif
+#ifndef _TABFRM_HXX
+#include 
+#endif
+#ifndef _EDIMP_HXX
+#include 
+#endif
+
+/*************************************************************************
+|*
+|*  SwFEShell::GetPageDescCnt()
+|*
+|*  Ersterstellung      MA 25. Jan. 93
+|*  Letzte Aenderung    MA 25. Jan. 93
+|*
+|*************************************************************************/
+
+USHORT SwFEShell::GetPageDescCnt() const
+{
+    return GetDoc()->GetPageDescCnt();
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::ChgCurPageDesc()
+|*
+|*  Ersterstellung      ST ??
+|*  Letzte Aenderung    MA 01. Aug. 94
+|*
+|*************************************************************************/
+
+void SwFEShell::ChgCurPageDesc( const SwPageDesc& rDesc )
+{
+#ifndef PRODUCT
+    //Die SS veraendert keinen PageDesc, sondern setzt nur das Attribut.
+    //Der Pagedesc muss im Dokument vorhanden sein!
+    BOOL bFound = FALSE;
+    for ( USHORT nTst = 0; nTst < GetPageDescCnt(); ++nTst )
+        if ( &rDesc == &GetPageDesc( nTst ) )
+            bFound = TRUE;
+    ASSERT( bFound, "ChgCurPageDesc mit ungueltigem Descriptor." );
+#endif
+
+    StartAllAction();
+
+    SwPageFrm *pPage = GetCurrFrm()->FindPageFrm();
+    const SwFrm *pFlow;
+    USHORT nPageNmOffset = 0;
+
+    ASSERT( !GetCrsr()->HasMark(), "ChgCurPageDesc nur ohne Selektion!");
+
+    SET_CURR_SHELL( this );
+    while ( pPage )
+    {
+        pFlow = pPage->FindFirstBodyCntnt();
+        if ( pFlow )
+        {
+            if ( pFlow->IsInTab() )
+                pFlow = pFlow->FindTabFrm();
+            const SwFmtPageDesc& rPgDesc = pFlow->GetAttrSet()->GetPageDesc();
+            if( rPgDesc.GetPageDesc() )
+            {
+                // wir haben ihn den Schlingel
+                nPageNmOffset = rPgDesc.GetNumOffset();
+                break;
+            }
+        }
+        pPage = (SwPageFrm*) pPage->GetPrev();
+    }
+    if ( !pPage )
+    {
+        pPage = (SwPageFrm*) (GetLayout()->Lower());
+        pFlow = pPage->FindFirstBodyCntnt();
+        if ( !pFlow )
+        {
+            pPage   = (SwPageFrm*)pPage->GetNext();
+            pFlow = pPage->FindFirstBodyCntnt();
+            ASSERT( pFlow, "Dokuemnt ohne Inhalt?!?" );
+        }
+    }
+
+    // Seitennummer mitnehmen
+    SwFmtPageDesc aNew( &rDesc );
+    aNew.SetNumOffset( nPageNmOffset );
+
+    if ( pFlow->IsInTab() )
+        GetDoc()->SetAttr( aNew, *(SwFmt*)pFlow->FindTabFrm()->GetFmt() );
+    else
+    {
+        SwPaM aPaM( *((SwCntntFrm*)pFlow)->GetNode() );
+        GetDoc()->Insert( aPaM, aNew );
+    }
+    EndAllActionAndCall();
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::ChgPageDesc()
+|*
+|*  Ersterstellung      MA 25. Jan. 93
+|*  Letzte Aenderung    MA 24. Jan. 95
+|*
+|*************************************************************************/
+
+void SwFEShell::ChgPageDesc( USHORT i, const SwPageDesc &rChged )
+{
+    StartAllAction();
+    SET_CURR_SHELL( this );
+    GetDoc()->ChgPageDesc( i, rChged );
+    EndAllActionAndCall();
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::GetPageDesc(), GetCurPageDesc()
+|*
+|*  Ersterstellung      MA 25. Jan. 93
+|*  Letzte Aenderung    MA 23. Apr. 93
+|
+|*************************************************************************/
+
+const SwPageDesc& SwFEShell::GetPageDesc( USHORT i ) const
+{
+    return GetDoc()->GetPageDesc( i );
+}
+
+SwPageDesc* SwFEShell::FindPageDescByName( const String& rName,
+                                            BOOL bGetFromPool,
+                                            USHORT* pPos )
+{
+    SwPageDesc* pDesc = GetDoc()->FindPageDescByName( rName, pPos );
+    if( !pDesc && bGetFromPool )
+    {
+        USHORT nPoolId = GetDoc()->GetPoolId( rName, GET_POOLID_PAGEDESC );
+        if( USHRT_MAX != nPoolId &&
+            0 != (pDesc = GetDoc()->GetPageDescFromPool( nPoolId ))
+            && pPos )
+                // werden immer hinten angehaengt
+            *pPos = GetDoc()->GetPageDescCnt() - 1 ;
+    }
+    return pDesc;
+}
+
+
+USHORT SwFEShell::GetCurPageDesc( const BOOL bCalcFrm ) const
+{
+    const SwFrm *pFrm = GetCurrFrm( bCalcFrm );
+    if ( pFrm )
+    {
+        const SwPageFrm *pPage = pFrm->FindPageFrm();
+        if ( pPage )
+        {
+            SwDoc *pDoc = GetDoc();
+            for ( USHORT i = 0; i < GetDoc()->GetPageDescCnt(); ++i )
+            {
+                if ( pPage->GetPageDesc() == &pDoc->GetPageDesc(i) )
+                    return i;
+            }
+        }
+    }
+    return 0;
+}
+
+// if inside all selection only one PageDesc, return this.
+// Otherwise return 0 pointer
+const SwPageDesc* SwFEShell::GetSelectedPageDescs() const
+{
+    const SwCntntNode* pCNd;
+    const SwFrm* pMkFrm, *pPtFrm;
+    const SwPageDesc* pFnd, *pRetDesc = (SwPageDesc*)0xffffffff;
+    const Point aNulPt;
+
+    FOREACHPAM_START(this)
+
+        if( 0 != (pCNd = PCURCRSR->GetCntntNode() ) &&
+            0 != ( pPtFrm = pCNd->GetFrm( &aNulPt, 0, FALSE )) )
+            pPtFrm = pPtFrm->FindPageFrm();
+        else
+            pPtFrm = 0;
+
+        if( PCURCRSR->HasMark() &&
+            0 != (pCNd = PCURCRSR->GetCntntNode( FALSE ) ) &&
+            0 != ( pMkFrm = pCNd->GetFrm( &aNulPt, 0, FALSE )) )
+            pMkFrm = pMkFrm->FindPageFrm();
+        else
+            pMkFrm = pPtFrm;
+
+
+        if( !pMkFrm || !pPtFrm )
+            pFnd = 0;
+        else if( pMkFrm == pPtFrm )
+            pFnd = ((SwPageFrm*)pMkFrm)->GetPageDesc();
+        else
+        {
+            // swap pointer if PtFrm before MkFrm
+            if( ((SwPageFrm*)pMkFrm)->GetPhyPageNum() >
+                ((SwPageFrm*)pPtFrm)->GetPhyPageNum() )
+            {
+                const SwFrm* pTmp = pMkFrm; pMkFrm = pPtFrm; pPtFrm = pTmp;
+            }
+
+            // now check from MkFrm to PtFrm for equal PageDescs
+            pFnd = ((SwPageFrm*)pMkFrm)->GetPageDesc();
+            while( pFnd && pMkFrm != pPtFrm )
+            {
+                pMkFrm = pMkFrm->GetNext();
+                if( !pMkFrm || pFnd != ((SwPageFrm*)pMkFrm)->GetPageDesc() )
+                    pFnd = 0;
+            }
+        }
+
+        if( (SwPageDesc*)0xffffffff == pRetDesc )
+            pRetDesc = pFnd;
+        else if( pFnd != pRetDesc )
+        {
+            pRetDesc = 0;
+            break;
+        }
+
+    FOREACHPAM_END()
+
+    return pRetDesc;
+}
+
+
+
diff --git a/sw/source/core/frmedt/fefly1.cxx b/sw/source/core/frmedt/fefly1.cxx
new file mode 100644
index 000000000000..73dc9d2c3934
--- /dev/null
+++ b/sw/source/core/frmedt/fefly1.cxx
@@ -0,0 +1,1869 @@
+/*************************************************************************
+ *
+ *  $RCSfile: fefly1.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:19 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _SFXITEMITER_HXX //autogen
+#include 
+#endif
+#ifndef _GOODIES_IMAPOBJ_HXX
+#include 
+#endif
+#ifndef _SOERR_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_PROTITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVDOGRP_HXX //autogen
+#include 
+#endif
+#ifndef _SVDOUNO_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_FMGLOB_HXX
+#include 
+#endif
+#ifndef _SFX_INTERNO_HXX //autogen
+#include 
+#endif
+#ifndef _COM_SUN_STAR_FORM_FORMBUTTONTYPE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
+#include 
+#endif
+
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFLCNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTCNTNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTORNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFLCNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTURL_HXX //autogen
+#include 
+#endif
+#ifndef _FMTCLDS_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFSIZE_HXX //autogen
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _FESH_HXX
+#include 
+#endif
+#ifndef _ROOTFRM_HXX
+#include 
+#endif
+#ifndef _PAGEFRM_HXX
+#include 
+#endif
+#ifndef _CNTFRM_HXX
+#include 
+#endif
+#ifndef _TXTFRM_HXX
+#include 
+#endif
+#ifndef _VIEWIMP_HXX
+#include 
+#endif
+#ifndef _VISCRS_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _DVIEW_HXX
+#include 
+#endif
+#ifndef _DFLYOBJ_HXX
+#include 
+#endif
+#ifndef _DCONTACT_HXX
+#include 
+#endif
+#ifndef _FRMFMT_HXX
+#include 
+#endif
+#ifndef _FLYFRM_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _EDIMP_HXX
+#include 
+#endif
+#ifndef _TBLSEL_HXX
+#include 
+#endif
+#ifndef _SWTABLE_HXX
+#include 
+#endif
+#ifndef _MVSAVE_HXX
+#include        // Strukturen zum Sichern beim Move/Delete
+#endif
+#ifndef _NDGRF_HXX
+#include 
+#endif
+#ifndef _FLYFRMS_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include 
+#endif
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+
+//Zum anmelden von Flys in Flys in ...
+//definiert in layout/frmtool.cxx
+void RegistFlys( SwPageFrm*, const SwLayoutFrm* );
+
+/***********************************************************************
+#*  Class       :  SwDoc
+#*  Methode     :  UseSpzLayoutFmt
+#*  Beschreibung:  Anhand des Request werden zu dem Format entsprechende
+#*      Aenderungen an den Spezifischen Layouts vorgenommen.
+#*  Datum       :  MA 23. Sep. 92
+#*  Update      :  JP 09.03.98
+#***********************************************************************/
+
+sal_Bool lcl_SetNewFlyPos( const SwNode& rNode, SwFmtAnchor& rAnchor,
+                        const Point& rPt )
+{
+    sal_Bool bRet = sal_False;
+    const SwStartNode* pStNode = rNode.FindFlyStartNode();
+    if( pStNode )
+    {
+        SwPosition aPos( *pStNode );
+        rAnchor.SetAnchor( &aPos );
+        bRet = sal_True;
+    }
+    else
+    {
+        const SwCntntFrm* pCFrm = rNode.GetCntntNode()->GetFrm( &rPt, 0, sal_False );
+        const SwPageFrm *pPg = pCFrm ? pCFrm->FindPageFrm() : 0;
+
+        rAnchor.SetPageNum( pPg ? pPg->GetPhyPageNum() : 1 );
+        rAnchor.SetType( FLY_PAGE );
+    }
+    return bRet;
+}
+
+BOOL lcl_FindAnchorPos( SwDoc& rDoc, const Point& rPt, const SwFrm& rFrm,
+                        SfxItemSet& rSet )
+{
+    BOOL bRet = TRUE;
+    SwFmtAnchor aNewAnch( (SwFmtAnchor&)rSet.Get( RES_ANCHOR ) );
+    RndStdIds nNew = aNewAnch.GetAnchorId();
+    const SwFrm *pNewAnch;
+
+    //Neuen Anker ermitteln
+    Point aTmpPnt( rPt );
+    switch( nNew )
+    {
+    case FLY_IN_CNTNT:  // sollte der nicht auch mit hinein?
+    case FLY_AT_CNTNT:
+    case FLY_AUTO_CNTNT: // LAYER_IMPL
+        {
+            //Ausgehend von der linken oberen Ecke des Fly den
+            //dichtesten CntntFrm suchen.
+            const SwFrm* pFrm = rFrm.IsFlyFrm() ? ((SwFlyFrm&)rFrm).GetAnchor()
+                                                : &rFrm;
+            pNewAnch = ::FindAnchor( pFrm, aTmpPnt );
+            if( pNewAnch->IsProtected() )
+            {
+                bRet = FALSE;
+                break;
+            }
+
+            SwPosition aPos( *((SwCntntFrm*)pNewAnch)->GetNode() );
+            if( FLY_AUTO_CNTNT == nNew || FLY_IN_CNTNT == nNew )
+            {
+                // es muss ein TextNode gefunden werden, denn nur in diesen
+                // ist ein Inhaltsgebundene Frames zu verankern
+                SwCrsrMoveState aState( MV_SETONLYTEXT );
+                aTmpPnt.X() -= 1;                   //nicht im Fly landen!!
+                if( !pNewAnch->GetCrsrOfst( &aPos, aTmpPnt, &aState ) )
+                {
+                    SwCntntNode* pCNd = ((SwCntntFrm*)pNewAnch)->GetNode();
+                    if( pNewAnch->Frm().Bottom() < aTmpPnt.Y() )
+                        pCNd->MakeStartIndex( &aPos.nContent );
+                    else
+                        pCNd->MakeEndIndex( &aPos.nContent );
+                }
+            }
+            aNewAnch.SetAnchor( &aPos );
+        }
+        break;
+
+    case FLY_AT_FLY: // LAYER_IMPL
+        {
+            //Ausgehend von der linken oberen Ecke des Fly den
+            //dichtesten SwFlyFrm suchen.
+            SwCrsrMoveState aState( MV_SETONLYTEXT );
+            SwPosition aPos( rDoc.GetNodes() );
+            aTmpPnt.X() -= 1;                   //nicht im Fly landen!!
+            rDoc.GetRootFrm()->GetCrsrOfst( &aPos, aTmpPnt, &aState );
+            pNewAnch = ::FindAnchor(
+                aPos.nNode.GetNode().GetCntntNode()->GetFrm( 0, 0, sal_False ),
+                aTmpPnt )->FindFlyFrm();
+
+            if( pNewAnch && &rFrm != pNewAnch && !pNewAnch->IsProtected() )
+            {
+                aPos.nNode = *((SwFlyFrm*)pNewAnch)->GetFmt()->GetCntnt().
+                                GetCntntIdx();
+                aNewAnch.SetAnchor( &aPos );
+                break;
+            }
+        }
+
+        aNewAnch.SetType( nNew = FLY_PAGE );
+        // no break
+
+    case FLY_PAGE:
+        pNewAnch = rFrm.FindPageFrm();
+        aNewAnch.SetPageNum( pNewAnch->GetPhyPageNum() );
+        break;
+
+    default:
+        ASSERT( !&rDoc, "Falsche ID fuer neuen Anker." );
+    }
+
+    rSet.Put( aNewAnch );
+    return bRet;
+}
+
+sal_Bool lcl_ChkAndSetNewAnchor( const SwFlyFrm& rFly, SfxItemSet& rSet )
+{
+    const SwFrmFmt& rFmt = *rFly.GetFmt();
+    const SwFmtAnchor &rOldAnch = rFmt.GetAnchor();
+    const RndStdIds nOld = rOldAnch.GetAnchorId();
+
+    RndStdIds nNew = ((SwFmtAnchor&)rSet.Get( RES_ANCHOR )).GetAnchorId();
+
+    if( nOld == nNew )
+        return sal_False;
+
+    SwDoc* pDoc = (SwDoc*)rFmt.GetDoc();
+
+#ifndef PRODUCT
+    ASSERT( !(nNew == FLY_PAGE &&
+        (FLY_AT_CNTNT==nOld || FLY_AUTO_CNTNT==nOld || FLY_IN_CNTNT==nOld ) &&
+        pDoc->IsInHeaderFooter( rOldAnch.GetCntntAnchor()->nNode )),
+            "Unerlaubter Ankerwechsel in Head/Foot." );
+#endif
+
+    return ::lcl_FindAnchorPos( *pDoc, rFly.Frm().Pos(), rFly, rSet );
+}
+
+void SwFEShell::SelectFlyFrm( SwFlyFrm& rFrm, sal_Bool bNew )
+{
+    SET_CURR_SHELL( this );
+
+    //  Wenn es ein neuer Rahmen ist, so soll er selektiert sein.
+    //  !!Rahmen immer selektieren, wenn sie nicht selektiert sind.
+    //  - Es kann ein neuer 'alter' sein weil der Anker gewechselt wurde.
+    //  - 'alte' Rahmen sind vorher immer selektiert denn sonst wird nix
+    //    an ihnen veraendert.
+    //  Der Rahmen darf nicht per Dokumentposition selektiert werden, weil er
+    //  auf jedenfall selektiert sein muss!
+    SwViewImp *pImp = Imp();
+    if( GetWin() && (bNew || !pImp->GetDrawView()->HasMarkedObj()) )
+    {
+        ASSERT( rFrm.IsFlyFrm(), "SelectFlyFrm will einen Fly" );
+
+        //Wenn der Fly bereits selektiert ist gibt es hier ja wohl nichts
+        //zu tun.
+        if ( FindFlyFrm() == &rFrm )
+            return;
+
+        //Damit der Anker ueberhaupt noch gepaintet wird.
+        if( rFrm.IsFlyInCntFrm() && rFrm.GetAnchor() )
+             rFrm.GetAnchor()->SetCompletePaint();
+
+        //Hier wurde immer kalkuliert. Leider ist der Sonderfall Fly in Fly mit
+        //Spalten u.U. sehr kritisch wenn der innenliegende zuerst formatiert
+        //wird. Um kein Risiko einzugehen entschaerfen wir nur diesen Sonderfall.
+        if( !rFrm.GetAnchor()->IsInFly() )
+            rFrm.Calc();
+
+        if( pImp->GetDrawView()->HasMarkedObj() )
+            pImp->GetDrawView()->UnmarkAll();
+
+        pImp->GetDrawView()->MarkObj( rFrm.GetVirtDrawObj(),
+                                      pImp->GetPageView(), sal_False, sal_False );
+        KillPams();
+        ClearMark();
+        SelFlyGrabCrsr();
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::FindFlyFrm()
+|*
+|*  Beschreibung        Liefert den Fly wenn einer Selektiert ist.
+|*  Ersterstellung      MA 03. Nov. 92
+|*  Letzte Aenderung    MA 05. Mar. 96
+|*
+*************************************************************************/
+
+SwFlyFrm *SwFEShell::FindFlyFrm() const
+{
+    if ( Imp()->HasDrawView() )
+    {
+        // Ein Fly ist genau dann erreichbar, wenn er selektiert ist.
+        const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkList();
+        if( rMrkList.GetMarkCount() != 1 )
+            return 0;
+
+        SdrObject *pO = rMrkList.GetMark( 0 )->GetObj();
+        return pO->IsWriterFlyFrame() ? ((SwVirtFlyDrawObj*)pO)->GetFlyFrm() : 0;
+    }
+    return 0;
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::IsFlyInFly()
+|*
+|*  Beschreibung        Liefert sal_True, wenn der aktuelle Fly an einem anderen
+|*                      verankert werden koennte (also innerhalb ist)
+|*  Ersterstellung      AMA 11. Sep. 97
+|*  Letzte Aenderung    AMA 14. Jan. 98
+|*
+*************************************************************************/
+
+const SwFrmFmt* SwFEShell::IsFlyInFly()
+{
+    SET_CURR_SHELL( this );
+
+    if ( !Imp()->HasDrawView() )
+        return NULL;
+
+    const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkList();
+    if ( !rMrkList.GetMarkCount() )
+    {
+        SwCntntFrm *pCntnt = GetCurrFrm( sal_False );
+        if( !pCntnt )
+            return NULL;
+        SwFlyFrm *pFly = pCntnt->FindFlyFrm();
+        if ( !pFly )
+            return NULL;
+        return pFly->GetFmt();
+    }
+    else if ( rMrkList.GetMarkCount() != 1 ||
+         !GetUserCall(rMrkList.GetMark( 0 )->GetObj()) )
+        return NULL;
+
+    SdrObject *pObj = rMrkList.GetMark( 0 )->GetObj();
+
+    SwFrmFmt *pFmt = FindFrmFmt( pObj );
+    if( pFmt && FLY_AT_FLY == pFmt->GetAnchor().GetAnchorId() )
+    {
+        SwFrm* pFly = pObj->IsWriterFlyFrame() ?
+            ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->GetAnchor() :
+            ((SwDrawContact*)GetUserCall(pObj))->GetAnchor();
+        ASSERT( pFly, "IsFlyInFly: Where's my anchor?" );
+        ASSERT( pFly->IsFlyFrm(), "IsFlyInFly: Funny anchor!" );
+        return ((SwFlyFrm*)pFly)->GetFmt();
+    }
+
+    Point aTmpPos = pObj->GetBoundRect().TopLeft();
+
+    SwFrm *pTxtFrm;
+    {
+        SwCrsrMoveState aState( MV_SETONLYTEXT );
+        SwNodeIndex aSwNodeIndex( GetDoc()->GetNodes() );
+        SwPosition aPos( aSwNodeIndex );
+        Point aPoint( aTmpPos );
+        aPoint.X() -= 1;                    //nicht im Fly landen!!
+        GetLayout()->GetCrsrOfst( &aPos, aPoint, &aState );
+        pTxtFrm = aPos.nNode.GetNode().GetCntntNode()->GetFrm( 0, 0, sal_False );
+    }
+    const SwFrm *pTmp = ::FindAnchor( pTxtFrm, aTmpPos );
+    const SwFlyFrm *pFly = pTmp->FindFlyFrm();
+    if( pFly )
+        return pFly->GetFmt();
+    return NULL;
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::SetFlyPos
+|*
+|*  Ersterstellung      MA 14. Jan. 93
+|*  Letzte Aenderung    MA 14. Feb. 95
+|*
+*************************************************************************/
+
+void SwFEShell::SetFlyPos( const Point& rAbsPos )
+{
+    SET_CURR_SHELL( this );
+
+    //Bezugspunkt in Dokumentkoordinaten bestimmen
+    SwCntntFrm *pCntnt = GetCurrFrm( sal_False );
+    if( !pCntnt )
+        return;
+    SwFlyFrm *pFly = pCntnt->FindFlyFrm();
+    if ( !pFly )
+        return;
+
+    SwSaveHdl aSaveX( Imp() );
+
+    //Bei Absatzgebundenen Flys muss ausgehend von der absoluten
+    //Position ein neuer Anker gesetzt werden. Anker und neue RelPos werden
+    //vom Fly selbst berechnet und gesetzt.
+    if ( pFly->IsFlyAtCntFrm() )
+        ((SwFlyAtCntFrm*)pFly)->SetAbsPos( rAbsPos );
+    else
+    {
+        const SwFrm *pAnch = pFly->GetAnchor();
+        pAnch->Calc();
+        Point aOrient( pAnch->Frm().Pos() );
+
+        if ( pFly->IsFlyInCntFrm() )
+            aOrient.X() = rAbsPos.X();
+
+        //RelPos errechnen.
+        aOrient.X() = rAbsPos.X() - aOrient.X();
+        aOrient.Y() = rAbsPos.Y() - aOrient.Y();
+        pFly->ChgRelPos( aOrient );
+    }
+    pFly->Calc();
+    CallChgLnk();       // rufe das AttrChangeNotify auf der UI-Seite.
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::FindAnchorPos
+|*
+|*  Ersterstellung      AMA 24. Sep. 97
+|*  Letzte Aenderung    AMA 24. Sep. 97
+|*
+*************************************************************************/
+
+Point SwFEShell::FindAnchorPos( const Point& rAbsPos, sal_Bool bMoveIt )
+{
+    Point aRet;
+
+    SET_CURR_SHELL( this );
+
+    if ( !Imp()->HasDrawView() )
+        return aRet;
+
+    const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkList();
+    if ( rMrkList.GetMarkCount() != 1 ||
+         !GetUserCall(rMrkList.GetMark( 0 )->GetObj()) )
+        return aRet;
+
+    SdrObject *pObj = rMrkList.GetMark( 0 )->GetObj();
+    SwFmt *pFmt = ::FindFrmFmt( pObj );
+    SwFmtAnchor aAnch( pFmt->GetAnchor() );
+    RndStdIds nAnchorId = aAnch.GetAnchorId();
+
+    if ( FLY_IN_CNTNT == nAnchorId )
+        return aRet;
+
+    sal_Bool bFlyFrame = pObj->IsWriterFlyFrame();
+
+    SwFlyFrm *pFly;
+    const SwFrm *pOldAnch;
+    const SwFrm* pFooterOrHeader = NULL;
+
+    if( bFlyFrame )
+    {
+        //Bezugspunkt in Dokumentkoordinaten bestimmen
+        SwCntntFrm *pCntnt = GetCurrFrm( sal_False );
+        if( !pCntnt )
+            return aRet;
+        pFly = pCntnt->FindFlyFrm();
+        if ( !pFly )
+            return aRet;
+        pOldAnch = pFly->GetAnchor();
+        if( !pOldAnch )
+            return aRet;
+        if( FLY_PAGE != nAnchorId )
+            pFooterOrHeader = pCntnt->FindFooterOrHeader();
+    }
+
+    //Ausgehend von der linken oberen Ecke des Fly den
+    //dichtesten SwFlyFrm suchen.
+    SwCntntFrm *pTxtFrm;
+    {
+        SwCrsrMoveState aState( MV_SETONLYTEXT );
+        SwPosition aPos( GetDoc()->GetNodes().GetEndOfExtras() );
+        Point aTmpPnt( rAbsPos );
+        GetLayout()->GetCrsrOfst( &aPos, aTmpPnt, &aState );
+        pTxtFrm = aPos.nNode.GetNode().GetCntntNode()->GetFrm(0,&aPos,FALSE );
+    }
+    const SwFrm *pNewAnch;
+    if( pTxtFrm )
+    {
+        if( FLY_PAGE == nAnchorId )
+            pNewAnch = pTxtFrm->FindPageFrm();
+        else
+        {
+            pNewAnch = ::FindAnchor( pTxtFrm, rAbsPos );
+
+            if( FLY_AT_FLY == nAnchorId ) // LAYER_IMPL
+                pNewAnch = pNewAnch->FindFlyFrm();
+        }
+    }
+    else
+        pNewAnch = 0;
+
+    if( pNewAnch && !pNewAnch->IsProtected() )
+    {
+        const SwFlyFrm* pCheck = bFlyFrame ? pNewAnch->FindFlyFrm() : 0;
+        // Falls wir innerhalb eines Rahmens landen, muss sichergestellt werden,
+        // dass der Rahmen nicht in seinem eigenen Inhalt landet!
+        while( pCheck )
+        {
+            if( pCheck == pFly )
+                break;
+            const SwFrm *pTmp = pCheck->GetAnchor();
+            pCheck = pTmp ? pTmp->FindFlyFrm() : NULL;
+        }
+        // Es darf nicht aus einer Kopf-/Fusszeile in einen anderen Bereich
+        // gewechselt werden, es darf nicht in eine Kopf-/Fusszeile hinein-
+        // gewechselt werden.
+        if( !pCheck &&
+            pFooterOrHeader == pNewAnch->FindFooterOrHeader() )
+        {
+            aRet = pNewAnch->Frm().Pos();
+            if( bMoveIt || nAnchorId == FLY_AUTO_CNTNT )
+            {
+                SwFmtAnchor aAnch( pFmt->GetAnchor() );
+                switch ( nAnchorId )
+                {
+                    case FLY_AT_CNTNT:
+                    {
+                        SwPosition *pPos = (SwPosition*)aAnch.GetCntntAnchor();
+                        pPos->nNode = *pTxtFrm->GetNode();
+                        pPos->nContent.Assign(0,0);
+                        break;
+                    }
+                    case FLY_PAGE:
+                    {
+                        aAnch.SetPageNum( ((const SwPageFrm*)pNewAnch)->
+                                          GetPhyPageNum() );
+                        break;
+                    }
+                    case FLY_AT_FLY:
+                    {
+                        SwPosition aPos( *((SwFlyFrm*)pNewAnch)->GetFmt()->
+                                                  GetCntnt().GetCntntIdx() );
+                        aAnch.SetAnchor( &aPos );
+                        break;
+                    }
+                    case FLY_AUTO_CNTNT:
+                    {
+                        SwPosition *pPos = (SwPosition*)aAnch.GetCntntAnchor();
+                        Point aTmpPnt( rAbsPos );
+                        if( pTxtFrm->GetCrsrOfst( pPos, aTmpPnt, NULL ) )
+                        {
+                            SwRect aTmpRect;
+                            pTxtFrm->GetCharRect( aTmpRect, *pPos );
+                            aRet = aTmpRect.Pos();
+                        }
+                        else
+                        {
+                            pPos->nNode = *pTxtFrm->GetNode();
+                            pPos->nContent.Assign(0,0);
+                        }
+                        break;
+                    }
+                }
+                if( bMoveIt )
+                {
+                    StartAllAction();
+                    pFmt->GetDoc()->SetAttr( aAnch, *pFmt );
+                    if( nAnchorId == FLY_AUTO_CNTNT && bFlyFrame &&
+                        pFly->IsFlyAtCntFrm() )
+                        ((SwFlyAtCntFrm*)pFly)->CheckCharRect();
+                    EndAllAction();
+                }
+            }
+
+            SwRect aTmpRect( aRet, rAbsPos );
+            if( aTmpRect.HasArea() )
+                MakeVisible( aTmpRect );
+#ifndef PRODUCT
+            //TODO: That doesn't seem to be intended
+            if( Color(COL_TRANSPARENT) != GetOut()->GetLineColor() )
+            {
+                ASSERT( FALSE, "Hey, Joe: Where's my Null Pen?" );
+                GetOut()->SetLineColor( Color(COL_TRANSPARENT) );
+            }
+/*          if( PEN_NULL != GetOut()->GetPen().GetStyle() )
+            {
+                ASSERT( FALSE, "Hey, Joe: Where's my Null Pen?" );
+                Pen aPen( PEN_NULL );
+                GetOut()->SetPen( aPen );
+            }
+*/#endif
+        }
+    }
+
+    return aRet;
+}
+
+/***********************************************************************
+#*  Class       :  SwFEShell
+#*  Methode     :  NewFlyFrm
+#*  Beschreibung:
+#*  Datum       :  MA 03. Nov. 92
+#*  Update      :  JP 11. Aug. 93
+#***********************************************************************/
+
+const SwFrmFmt *SwFEShell::NewFlyFrm( const SfxItemSet& rSet, sal_Bool bAnchValid,
+                           SwFrmFmt *pParent )
+{
+    SET_CURR_SHELL( this );
+    StartAllAction();
+
+    SwPaM* pCrsr = GetCrsr();
+    const SwPosition& rPos = *pCrsr->Start();
+    const Point aPt( GetCrsrDocPos() );
+
+    SwSelBoxes aBoxes;
+    sal_Bool bMoveCntnt = sal_True;
+    if( IsTableMode() )
+    {
+        GetTblSel( *this, aBoxes );
+        if( aBoxes.Count() )
+        {
+            // die Crsr muessen noch aus dem Loeschbereich entfernt
+            // werden. Setze sie immer hinter/auf die Tabelle; ueber die
+            // Dokument-Position werden sie dann immer an die alte
+            // Position gesetzt.
+            ParkCrsr( SwNodeIndex( *aBoxes[0]->GetSttNd() ));
+//          KillPams();
+        }
+        else
+            bMoveCntnt = sal_False;
+    }
+    else if( !pCrsr->HasMark() && pCrsr->GetNext() == pCrsr )
+        bMoveCntnt = sal_False;
+
+    SwFmtAnchor& rAnch = (SwFmtAnchor&)rSet.Get( RES_ANCHOR );
+    RndStdIds eRndId = rAnch.GetAnchorId();
+    switch( eRndId )
+    {
+    case FLY_PAGE:
+        if( !rAnch.GetPageNum() )       //HotFix: Bug in UpdateByExample
+            rAnch.SetPageNum( 1 );
+        break;
+
+    case FLY_AT_FLY:
+    case FLY_AT_CNTNT:
+    case FLY_AUTO_CNTNT:
+    case FLY_IN_CNTNT:
+        if( !bAnchValid )
+        {
+            if( FLY_AT_FLY != eRndId )
+                rAnch.SetAnchor( &rPos );
+            else if( lcl_SetNewFlyPos( rPos.nNode.GetNode(), rAnch, aPt ) )
+                eRndId = FLY_PAGE;
+        }
+        break;
+
+#ifndef PRODUCT
+    default:
+            ASSERT( !this, "Was sollte das fuer ein Fly werden?" );
+#endif
+    }
+
+    SwFlyFrmFmt *pRet;
+    if( bMoveCntnt )
+    {
+        GetDoc()->StartUndo( UNDO_INSLAYFMT );
+        SwFmtAnchor* pOldAnchor = 0;
+        sal_Bool bHOriChgd = sal_False, bVOriChgd = sal_False;
+        SwFmtVertOrient aOldV;
+        SwFmtHoriOrient aOldH;
+
+        if( FLY_PAGE != eRndId )
+        {
+            // erstmal als mit Seitenbindung, Absatz/Zeichenbindung erst wenn
+            // alles verschoben ist. Dann ist die Position gueltig!
+            // JP 13.05.98: ggfs. auch noch die Hori/Vert-Orientierung
+            //              umsetzen, damit diese beim Umanker NICHT
+            //              korrigiert wird
+            pOldAnchor = new SwFmtAnchor( rAnch );
+            ((SfxItemSet&)rSet).Put( SwFmtAnchor( FLY_PAGE, 1 ) );
+
+            const SfxPoolItem* pItem;
+            if( SFX_ITEM_SET == rSet.GetItemState( RES_HORI_ORIENT, sal_False, &pItem )
+                && HORI_NONE == ((SwFmtHoriOrient*)pItem)->GetHoriOrient() )
+            {
+                bHOriChgd = sal_True;
+                aOldH = *((SwFmtHoriOrient*)pItem);
+                ((SfxItemSet&)rSet).Put( SwFmtHoriOrient( 0, HORI_LEFT ) );
+            }
+            if( SFX_ITEM_SET == rSet.GetItemState( RES_VERT_ORIENT, sal_False, &pItem )
+                && VERT_NONE == ((SwFmtVertOrient*)pItem)->GetVertOrient() )
+            {
+                bVOriChgd = sal_True;
+                aOldV = *((SwFmtVertOrient*)pItem);
+                ((SfxItemSet&)rSet).Put( SwFmtVertOrient( 0, VERT_TOP ) );
+            }
+        }
+
+        pRet = GetDoc()->MakeFlyAndMove( *pCrsr, rSet, &aBoxes, pParent );
+
+        KillPams();
+
+        if( pOldAnchor )
+        {
+            if( pRet )
+            {
+                // neue Position bestimmen
+                //JP 24.03.97: immer ueber die Seitenbindung gehen - der
+                //           chaos::Anchor darf nie im verschobenen Bereich
+                //              liegen
+                pRet->DelFrms();
+
+                const SwFrm* pAnch = ::FindAnchor( GetLayout(), aPt, sal_False );
+                SwPosition aPos( *((SwCntntFrm*)pAnch)->GetNode() );
+                if( FLY_IN_CNTNT == eRndId )
+                    aPos.nContent.Assign( ((SwCntntFrm*)pAnch)->GetNode(), 0 );
+                pOldAnchor->SetAnchor( &aPos );
+
+                // das verschieben von TabelleSelektion ist noch nicht
+                // Undofaehig - also darf das UmAnkern auch nicht
+                // aufgezeichnet werden.
+                sal_Bool bDoesUndo = GetDoc()->DoesUndo();
+                if( bDoesUndo && UNDO_INSLAYFMT == GetDoc()->GetUndoIds() )
+                    GetDoc()->DoUndo( sal_False );
+
+                ((SfxItemSet&)rSet).Put( *pOldAnchor );
+
+                if( bHOriChgd )
+                    ((SfxItemSet&)rSet).Put( aOldH );
+                if( bVOriChgd )
+                    ((SfxItemSet&)rSet).Put( aOldV );
+
+                GetDoc()->SetFlyFrmAttr( *pRet, (SfxItemSet&)rSet );
+                GetDoc()->DoUndo( bDoesUndo );
+            }
+            delete pOldAnchor;
+        }
+        GetDoc()->EndUndo( UNDO_INSLAYFMT );
+    }
+    else
+        pRet = GetDoc()->MakeFlySection( eRndId, &rPos, &rSet, pParent );
+
+    if( pRet )
+    {
+        SwFlyFrm* pFrm = pRet->GetFrm( &aPt );
+        if( pFrm )
+            SelectFlyFrm( *pFrm, sal_True );
+        else
+        {
+            GetLayout()->SetAssertFlyPages();
+            pRet = 0;
+        }
+    }
+    EndAllActionAndCall();
+
+    return pRet;
+}
+
+/***********************************************************************
+#*  Class       :  SwFEShell
+#*  Methode     :  Insert
+#*  Datum       :  ??
+#*  Update      :  MA 12. Sep. 94
+#***********************************************************************/
+
+void SwFEShell::Insert( const String& rGrfName, const String& rFltName,
+                        const Graphic* pGraphic,
+                        const SfxItemSet* pFlyAttrSet,
+                        const SfxItemSet* pGrfAttrSet,
+                        SwFrmFmt* pFrmFmt )
+{
+    SwFlyFrmFmt* pFmt = 0;
+    SET_CURR_SHELL( this );
+    StartAllAction();
+    FOREACHCURSOR_START( this )
+
+        // Anker noch nicht oder unvollstaendig gesetzt ?
+        if( pFlyAttrSet )
+        {
+            const SfxPoolItem* pItem;
+            if( SFX_ITEM_SET == pFlyAttrSet->GetItemState( RES_ANCHOR, sal_False,
+                    &pItem ) )
+            {
+                SwFmtAnchor* pAnchor = (SwFmtAnchor*)pItem;
+                switch( pAnchor->GetAnchorId())
+                {
+                case FLY_AT_CNTNT:
+                case FLY_AUTO_CNTNT: // LAYER_IMPL
+                case FLY_IN_CNTNT:
+                    if( !pAnchor->GetCntntAnchor() )
+                        pAnchor->SetAnchor( PCURCRSR->GetPoint() );
+                    break;
+                case FLY_AT_FLY:
+                    if( !pAnchor->GetCntntAnchor() )
+                        lcl_SetNewFlyPos( *PCURCRSR->GetNode(),
+                                            *pAnchor, GetCrsrDocPos() );
+                    break;
+                case FLY_PAGE:
+                    if( !pAnchor->GetPageNum() )
+                    {
+                        pAnchor->SetPageNum( PCURCRSR->GetPageNum(
+                                    sal_True, &PCURCRSR->GetPtPos() ) );
+                    }
+                    break;
+                }
+            }
+        }
+        pFmt = GetDoc()->Insert(*PCURCRSR, rGrfName,
+                                rFltName, pGraphic,
+                                pFlyAttrSet,
+                                pGrfAttrSet, pFrmFmt );
+        ASSERT( pFmt, "Doc->Insert(notxt) failed." );
+
+    FOREACHCURSOR_END()
+    EndAllAction();
+
+    if( pFmt )
+    {
+        const Point aPt( GetCrsrDocPos() );
+        SwFlyFrm* pFrm = pFmt->GetFrm( &aPt );
+
+        if( pFrm )
+            SelectFlyFrm( *pFrm, sal_True );
+        else
+            GetLayout()->SetAssertFlyPages();
+    }
+}
+
+void SwFEShell::Insert( SvInPlaceObject *pObj,
+                        const SfxItemSet* pFlyAttrSet,
+                        const SfxItemSet* pGrfAttrSet,
+                        SwFrmFmt* pFrmFmt )
+{
+    SwFlyFrmFmt* pFmt = 0;
+    SET_CURR_SHELL( this );
+    StartAllAction();
+        FOREACHPAM_START( this )
+            pFmt = GetDoc()->Insert(*PCURCRSR, pObj,
+                                    pFlyAttrSet, pGrfAttrSet, pFrmFmt );
+            ASSERT( pFmt, "Doc->Insert(notxt) failed." );
+
+        FOREACHPAM_END()
+    EndAllAction();
+
+    if( pFmt )
+    {
+        const Point aPt( GetCrsrDocPos() );
+        SwFlyFrm* pFrm = pFmt->GetFrm( &aPt );
+
+        if( pFrm )
+            SelectFlyFrm( *pFrm, sal_True );
+        else
+            GetLayout()->SetAssertFlyPages();
+    }
+}
+
+
+void SwFEShell::Insert(  SdrObject& rDrawObj,
+                         const SfxItemSet* pFlyAttrSet,
+                         SwFrmFmt* pFrmFmt, const Point* pPt )
+{
+    SwDrawFrmFmt* pFmt = 0;
+    SET_CURR_SHELL( this );
+
+    if( pPt )
+    {
+        SfxItemSet* pSet = 0;
+        const SfxPoolItem* pItem;
+        if( !pFlyAttrSet ||
+            !pFlyAttrSet->GetItemState( RES_ANCHOR, sal_False, &pItem ) ||
+            FLY_PAGE != ((SwFmtAnchor*)pItem)->GetAnchorId() )
+        {
+            pSet = new SfxItemSet( GetDoc()->GetAttrPool(), aFrmFmtSetRange );
+            pSet->Put( SwFmtAnchor( FLY_AT_CNTNT ));
+            pFlyAttrSet = pSet;
+        }
+
+        SwCrsrMoveState aState( MV_SETONLYTEXT );
+        SwPaM aPam( pDoc->GetNodes() );
+        Point aTmpPt( *pPt );
+        GetDoc()->GetRootFrm()->GetCrsrOfst( aPam.GetPoint(), aTmpPt, &aState );
+        SwFrm* pFrm = aPam.GetCntntNode()->GetFrm( 0, 0, sal_False );
+        const Point aRelPos( pPt->X() - pFrm->Frm().Left(),
+                             pPt->Y() - pFrm->Frm().Top() );
+        rDrawObj.SetRelativePos( aRelPos );
+        ::lcl_FindAnchorPos( *GetDoc(), *pPt, *pFrm, *(SfxItemSet*)pFlyAttrSet );
+        pFmt = GetDoc()->Insert( aPam, rDrawObj, pFlyAttrSet, pFrmFmt );
+        if( pSet )
+            delete pSet;
+    }
+    else
+    {
+        StartAllAction();
+            FOREACHPAM_START( this )
+                pFmt = GetDoc()->Insert(*PCURCRSR, rDrawObj,
+                                        pFlyAttrSet, pFrmFmt );
+                ASSERT( pFmt, "Doc->Insert(sdrobj) failed." );
+
+            FOREACHPAM_END()
+        EndAllAction();
+    }
+
+    if( pFmt )
+        // das DrawObject selektieren
+        Imp()->GetDrawView()->MarkObj( &rDrawObj, Imp()->GetPageView(),
+                                            sal_False, sal_False );
+    else
+        GetLayout()->SetAssertFlyPages();
+}
+
+/***********************************************************************
+#*  Class       :  SwFEShell
+#*  Methode     :  GetPageObjs
+#*  Datum       :  ??
+#*  Update      :  MA 11. Jan. 95
+#***********************************************************************/
+
+void SwFEShell::GetPageObjs( SvPtrarr& rFillArr )
+{
+    if( rFillArr.Count() )
+        rFillArr.Remove( 0, rFillArr.Count() );
+
+    const SwFrmFmt* pFmt;
+    for( sal_uInt16 n = 0; n < pDoc->GetSpzFrmFmts()->Count(); ++n )
+    {
+        pFmt = (const SwFrmFmt*)(*pDoc->GetSpzFrmFmts())[n];
+        if( FLY_PAGE == pFmt->GetAnchor().GetAnchorId() )
+            rFillArr.Insert( (VoidPtr)pFmt, rFillArr.Count() );
+    }
+}
+
+/***********************************************************************
+#*  Class       :  SwFEShell
+#*  Methode     :  SetPageFlysNewPage
+#*  Datum       :  ??
+#*  Update      :  MA 14. Feb. 95
+#***********************************************************************/
+
+void SwFEShell::SetPageObjsNewPage( SvPtrarr& rFillArr, int nOffset )
+{
+    if( !rFillArr.Count() || !nOffset )
+        return;
+
+    StartAllAction();
+    StartUndo();
+
+    SwFrmFmt* pFmt;
+    long nNewPage;
+    sal_uInt16 nMaxPage = GetDoc()->GetRootFrm()->GetPageNum();
+    sal_Bool bAssert = sal_False;
+    for( sal_uInt16 n = 0; n < rFillArr.Count(); ++n )
+    {
+        pFmt = (SwFrmFmt*)rFillArr[n];
+        if( USHRT_MAX != pDoc->GetSpzFrmFmts()->GetPos( pFmt ))
+        {
+            // FlyFmt ist noch gueltig, also behandeln
+            SwFmtAnchor aNewAnchor( pFmt->GetAnchor() );
+            if( FLY_PAGE != aNewAnchor.GetAnchorId() ||
+                0 >= ( nNewPage = aNewAnchor.GetPageNum() + nOffset ) )
+                // chaos::Anchor wurde veraendert oder ungueltige SeitenNummer,
+                // also nicht veraendern !!
+                continue;
+
+            if( sal_uInt16(nNewPage) > nMaxPage )
+            {
+                if ( RES_DRAWFRMFMT == pFmt->Which() )
+                {
+                    SwContact *pCon = pFmt->FindContactObj();
+                    if( pCon )
+                        ((SwDrawContact*)pCon)->DisconnectFromLayout();
+                }
+                else
+                    pFmt->DelFrms();
+                bAssert = sal_True;
+            }
+            aNewAnchor.SetPageNum( sal_uInt16(nNewPage) );
+            pDoc->SetAttr( aNewAnchor, *pFmt );
+        }
+    }
+
+    if( bAssert )
+        GetDoc()->GetRootFrm()->SetAssertFlyPages();
+
+    EndUndo();
+    EndAllAction();
+}
+
+/***********************************************************************
+#*  Class       :  SwFEShell
+#*  Methode     :  GetFlyFrmAttr
+#*  Beschreibung:  Alle Attribute in dem 'Koerbchen' werden mit den
+#*                 Attributen des aktuellen FlyFrms gefuellt.
+#*                 Sind Attribute nicht zu fuellen weil fehl am Platz oder
+#*                 uneindeutig (Mehrfachtselektionen) so werden sie entfernt.
+#*  Datum       :  MA 03. Nov. 92
+#*  Update      :  MA 03. Feb. 94
+#***********************************************************************/
+
+sal_Bool SwFEShell::GetFlyFrmAttr( SfxItemSet &rSet ) const
+{
+    SwFlyFrm *pFly = FindFlyFrm();
+    if ( !pFly )
+    {
+        ASSERT( GetCurrFrm(), "Crsr in parking zone" );
+        pFly = GetCurrFrm()->FindFlyFrm();
+        if ( !pFly )
+        {
+            ASSERT( !this, "GetFlyFrmAttr, no Fly selected." );
+            return sal_False;
+        }
+    }
+
+    SET_CURR_SHELL( (ViewShell*)this );
+
+    if( !rSet.Set( pFly->GetFmt()->GetAttrSet(), sal_True ) )
+        return sal_False;
+
+    //Und die Attribute durchschaufeln. Unerlaubte Attribute entfernen, dann
+    //alle restlichen Attribute besorgen und eintragen.
+    const SfxPoolItem* pItem;
+    if( SFX_ITEM_SET == rSet.GetItemState( RES_ANCHOR, sal_False, &pItem ) )
+    {
+        SwFmtAnchor* pAnchor = (SwFmtAnchor*)pItem;
+        RndStdIds eType = pAnchor->GetAnchorId();
+
+        if( FLY_PAGE != eType )
+        {
+            rSet.Put( SwFmtAnchor( eType ));
+            if( FLY_IN_CNTNT == eType )
+            {
+                rSet.ClearItem( RES_OPAQUE );
+                rSet.ClearItem( RES_SURROUND );
+            }
+        }
+    }
+    rSet.SetParent( pFly->GetFmt()->GetAttrSet().GetParent() );
+    //JP 11.02.97: Bug #35894#: die Attribute MUESSEN entfern werden!
+    rSet.ClearItem( RES_FILL_ORDER );
+    rSet.ClearItem( RES_CNTNT );
+    //MA: Ersteinmal entfernen (Template by example usw.)
+    rSet.ClearItem( RES_CHAIN );
+    return sal_True;
+}
+/***********************************************************************
+#*  Class       :  SwFEShell
+#*  Methode     :  SetFlyFrmAttr
+#*  Beschreibung:  Die Attribute des aktuellen Flys aendern sich.
+#*  Datum       :  MA 03. Nov. 92
+#*  Update      :  MA 01. Aug. 95
+#***********************************************************************/
+
+sal_Bool SwFEShell::SetFlyFrmAttr( SfxItemSet& rSet )
+{
+    SET_CURR_SHELL( this );
+    sal_Bool bRet = sal_False;
+
+    if( rSet.Count() )
+    {
+        SwFlyFrm *pFly = FindFlyFrm();
+        if( !pFly )
+        {
+            ASSERT( GetCurrFrm(), "Crsr in parking zone" );
+            pFly = GetCurrFrm()->FindFlyFrm();
+            ASSERT( pFly, "SetFlyFrmAttr, no Fly selected." );
+        }
+        if( pFly )
+        {
+            StartAllAction();
+            const Point aPt( pFly->Frm().Pos() );
+
+            if( SFX_ITEM_SET == rSet.GetItemState( RES_ANCHOR, sal_False ))
+                ::lcl_ChkAndSetNewAnchor( *pFly, rSet );
+            SwFlyFrmFmt* pFlyFmt = (SwFlyFrmFmt*)pFly->GetFmt();
+
+            if( GetDoc()->SetFlyFrmAttr( *pFlyFmt, rSet ))
+            {
+                bRet = sal_True;
+                SwFlyFrm* pFrm = pFlyFmt->GetFrm( &aPt );
+                if( pFrm )
+                    SelectFlyFrm( *pFrm, sal_True );
+                else
+                    GetLayout()->SetAssertFlyPages();
+            }
+
+            EndAllActionAndCall();
+        }
+    }
+    return bRet;
+}
+
+/***********************************************************************
+#*  Class       :  SwFEShell
+#*  Methode     :  ResetFlyFrmAttr
+#*  Beschreibung:  Das gewuenschte Attribut oder die im Set befindlichen
+#*                  werden zurueckgesetzt.
+#*  Datum       :  MA 14. Mar. 97
+#*  Update      :  MA 14. Mar. 97
+#***********************************************************************/
+
+sal_Bool SwFEShell::ResetFlyFrmAttr( sal_uInt16 nWhich, const SfxItemSet* pSet )
+{
+    sal_Bool bRet = sal_False;
+
+    if( RES_ANCHOR != nWhich && RES_CHAIN != nWhich && RES_CNTNT != nWhich )
+    {
+        SET_CURR_SHELL( this );
+
+        SwFlyFrm *pFly = FindFlyFrm();
+        if( !pFly )
+        {
+            ASSERT( GetCurrFrm(), "Crsr in parking zone" );
+            pFly = GetCurrFrm()->FindFlyFrm();
+            ASSERT( pFly, "SetFlyFrmAttr, no Fly selected." );
+        }
+
+        if( pFly )
+        {
+            StartAllAction();
+
+            if( pSet )
+            {
+                SfxItemIter aIter( *pSet );
+                const SfxPoolItem* pItem = aIter.FirstItem();
+                while( pItem )
+                {
+                    if( !IsInvalidItem( pItem ) &&
+                        RES_ANCHOR != ( nWhich = pItem->Which() ) &&
+                        RES_CHAIN != nWhich && RES_CNTNT != nWhich )
+                        pFly->GetFmt()->ResetAttr( nWhich );
+                    pItem = aIter.NextItem();
+                }
+            }
+            else
+                pFly->GetFmt()->ResetAttr( nWhich );
+
+            bRet = sal_True;
+            EndAllActionAndCall();
+            GetDoc()->SetModified();
+        }
+    }
+    return bRet;
+}
+
+/***********************************************************************
+#*  Class       :  SwFEShell
+#*  Methode     :  GetCurFrmFmt
+#*  Beschreibung:  liefert wenn Rahmen, dann Rahmenvorlage, sonst 0
+#*  Datum       :  ST 04. Jun. 93
+#*  Update      :
+#***********************************************************************/
+
+SwFrmFmt* SwFEShell::GetCurFrmFmt() const
+{
+    SwFrmFmt* pRet = 0;
+    SwLayoutFrm *pFly = FindFlyFrm();
+    if( pFly && ( pRet = (SwFrmFmt*)pFly->GetFmt()->DerivedFrom() ) ==
+                                            GetDoc()->GetDfltFrmFmt() )
+        pRet = 0;
+    return pRet;
+}
+
+/******************************************************************************
+ *  Methode     :   void SwFEShell::SetFrmFmt(SwFrmFmt *pNewFmt)
+ *  Beschreibung:
+ *  Erstellt    :   OK 14.04.94 15:40
+ *  Aenderung   :   MA 23. Apr. 97
+ ******************************************************************************/
+
+void SwFEShell::SetFrmFmt( SwFrmFmt *pNewFmt, sal_Bool bKeepOrient, Point* pDocPos )
+{
+    SwFlyFrm *pFly = 0;
+    if(pDocPos)
+    {
+        const SwFrmFmt* pFmt = GetFmtFromObj( *pDocPos );
+
+        if(PTR_CAST(SwFlyFrmFmt, pFmt))
+            pFly = ((SwFlyFrmFmt*)pFmt)->GetFrm();
+    }
+    else
+        pFly = FindFlyFrm();
+    ASSERT( pFly, "SetFrmFmt: kein Frame" );
+    if( pFly )
+    {
+        StartAllAction();
+        SET_CURR_SHELL( this );
+
+        SwFlyFrmFmt* pFlyFmt = (SwFlyFrmFmt*)pFly->GetFmt();
+        const Point aPt( pFly->Frm().Pos() );
+
+        SfxItemSet* pSet = 0;
+        const SfxPoolItem* pItem;
+        if( SFX_ITEM_SET == pNewFmt->GetItemState( RES_ANCHOR, sal_False, &pItem ))
+        {
+            pSet = new SfxItemSet( GetDoc()->GetAttrPool(), aFrmFmtSetRange );
+            pSet->Put( *pItem );
+            if( !::lcl_ChkAndSetNewAnchor( *pFly, *pSet ))
+                delete pSet, pSet = 0;
+        }
+
+        if( GetDoc()->SetFrmFmtToFly( *pFlyFmt, *pNewFmt, pSet, bKeepOrient ))
+        {
+            SwFlyFrm* pFrm = pFlyFmt->GetFrm( &aPt );
+            if( pFrm )
+                SelectFlyFrm( *pFrm, sal_True );
+            else
+                GetLayout()->SetAssertFlyPages();
+        }
+        if( pSet )
+            delete pSet;
+
+        EndAllActionAndCall();
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::GetFlyFrmFmt()
+|*
+|*  Ersterstellung      OK 23.06.93 13:15
+|*  Letzte Aenderung    OK 23.06.93 13:15
+|*
+*************************************************************************/
+
+const SwFrmFmt* SwFEShell::GetFlyFrmFmt() const
+{
+    const SwFlyFrm* pFly = FindFlyFrm();
+    if ( !pFly )
+        pFly = GetCurrFrm()->FindFlyFrm();
+    if( pFly )
+        return pFly->GetFmt();
+    return 0;
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::GetFlyRect()
+|*
+|*  Ersterstellung      AMA 6. Mae. 97
+|*  Letzte Aenderung    AMA 6. Mae. 97
+|*
+*************************************************************************/
+
+SwRect SwFEShell::GetFlyRect() const
+{
+    SwCntntFrm *pCntnt = GetCurrFrm( sal_False );
+    SwFlyFrm *pFly = pCntnt->FindFlyFrm();
+    if ( !pFly )
+    {
+        SwRect aRect;
+        return aRect;
+    }
+    else
+        return pFly->Frm();
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::GetObjRect()
+|*
+|*  Ersterstellung      MA 22. Aug. 93
+|*  Letzte Aenderung    MA 11. Jan. 95
+|*
+*************************************************************************/
+
+SwRect SwFEShell::GetObjRect() const
+{
+/*  const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkList();
+     Rectangle aRect;
+    for ( sal_uInt16 i = 0; i < rMrkList.GetMarkCount(); ++i )
+        aRect.Union( rMrkList.GetMark( i )->GetObj()->GetBoundRect() );
+    return SwRect( aRect );*/
+    if( Imp()->HasDrawView() )
+        return Imp()->GetDrawView()->GetAllMarkedRect();
+    else
+    {
+        SwRect aRect;
+        return aRect;
+    }
+}
+
+void SwFEShell::SetObjRect( const SwRect& rRect )
+{
+    if ( Imp()->HasDrawView() )
+    {
+        Imp()->GetDrawView()->SetAllMarkedRect( rRect.SVRect() );
+        CallChgLnk();   // rufe das AttrChangeNotify auf der UI-Seite.
+    }
+}
+
+/***********************************************************************
+#*  Class       :  SwFEShell
+#*  Methode     :  RequestObjectResize()
+#*  Datum       :  MA 10. Feb. 95
+#*  Update      :  MA 13. Jul. 95
+#***********************************************************************/
+
+void SwFEShell::RequestObjectResize( const SwRect &rRect, SvEmbeddedObject *pIPObj )
+{
+    SwFlyFrm *pFly = FindFlyFrm( pIPObj );
+    if ( !pFly )
+        return;
+
+    StartAllAction();
+
+    //MA wir lassen den Fly nicht Clippen, damit die Ole-Server mit
+    //beliebigen Wuenschen kommen koennen. Die Formatierung uebernimmt das
+    //Clippen. Die richtige Darstellung wird per Scalierung erledigt.
+    //Die Scalierung wird von SwNoTxtFrm::Format durch einen Aufruf von
+    //SwWrtShell::CalcAndSetScale() erledigt.
+
+    if ( rRect.SSize() != pFly->Prt().SSize() )
+    {
+         Size aSz( rRect.SSize() );
+        aSz.Width() += pFly->Frm().Width() - pFly->Prt().Width();
+        aSz.Height()+= pFly->Frm().Height()- pFly->Prt().Height();
+        pFly->ChgSize( aSz );
+
+        //Wenn sich das Objekt aendert ist die Kontur hoechstwahrscheinlich daneben.
+        ASSERT( pFly->Lower()->IsNoTxtFrm(), "Request ohne NoTxt" );
+        SwNoTxtNode *pNd = ((SwCntntFrm*)pFly->Lower())->GetNode()->GetNoTxtNode();
+        ASSERT( pNd, "Request ohne Node" );
+        pNd->SetContour( 0 );
+        ClrContourCache();
+    }
+
+    //Wenn nur die Size angepasst werden soll, so wird eine Pos mit
+    //ausgezeichneten Werten transportiert.
+    Point aPt( pFly->Prt().Pos() );
+    aPt += pFly->Frm().Pos();
+    if ( rRect.Top() != LONG_MIN && rRect.Pos() != aPt )
+    {
+        aPt = rRect.Pos();
+        aPt.X() -= pFly->Prt().Left();
+        aPt.Y() -= pFly->Prt().Top();
+        //Bei Absatzgebundenen Flys muss ausgehend von der neuen Position ein
+        //neuer Anker gesetzt werden. Anker und neue RelPos werden vom Fly
+        //selbst berechnet und gesetzt.
+        if( pFly->IsFlyAtCntFrm() )
+            ((SwFlyAtCntFrm*)pFly)->SetAbsPos( aPt );
+        else
+        {
+            const SwFrmFmt *pFmt = pFly->GetFmt();
+            const SwFmtVertOrient &rVert = pFmt->GetVertOrient();
+            const SwFmtHoriOrient &rHori = pFmt->GetHoriOrient();
+            const long lXDiff = aPt.X() - pFly->Frm().Left();
+            const long lYDiff = aPt.Y() - pFly->Frm().Top();
+            const Point aTmp( rHori.GetPos() + lXDiff,
+                              rVert.GetPos() + lYDiff );
+            pFly->ChgRelPos( aTmp );
+        }
+    }
+    EndAllAction();
+}
+
+/***********************************************************************
+#*  Class       :  SwFEShell
+#*  Methode     :  DeleteCurrFrmFmt
+#*  Datum       :  JP 28.07.95
+#*  Update      :  JP 28.07.95
+#***********************************************************************/
+
+sal_Bool SwFEShell::WizzardDelFly()
+{
+    // mal nicht uebers Layout den Fly suchen. Dann kann auch ohne gueltiges
+    // Layout ein Rahmen geloescht werden. ( z.B.: fuer die Wizard's )
+    SwFrmFmt* pDelFmt = WizzardGetFly();
+    if( pDelFmt )
+    {
+        // gefunden: dann also loeschen
+        // bei Zeichen/Absatz gebundenen Flys den Crsr auf den Anker umsetzen,
+        // dadurch bleibt der Crsr auf einer "definierten" Position
+        // (Im Wizzard wird das Layout nicht aktualisiert!)
+        SwPosition* pCrsrPos = GetCrsr()->GetPoint(), *pNewPos = 0;
+        const SwFmtAnchor& rAnch = pDelFmt->GetAnchor();
+        if( rAnch.GetCntntAnchor() &&
+            ( FLY_AT_CNTNT == rAnch.GetAnchorId() ||
+              FLY_AUTO_CNTNT == rAnch.GetAnchorId() ||
+                FLY_IN_CNTNT == rAnch.GetAnchorId() ))
+        {
+            pNewPos = new SwPosition( *rAnch.GetCntntAnchor() );
+            if( FLY_IN_CNTNT != rAnch.GetAnchorId() )
+                pNewPos->nContent.Assign( GetDoc()->GetNodes()[ pNewPos->nNode ]
+                                                    ->GetCntntNode(), 0 );
+        }
+
+        GetDoc()->DelLayoutFmt( pDelFmt );
+
+        if( pNewPos )
+        {
+            *pCrsrPos = *pNewPos;
+            delete pNewPos;
+        }
+        return sal_True;
+    }
+    return sal_False;
+}
+
+/***********************************************************************
+#*  Class       :  SwFEShell
+#*  Methode     :  WizzardFindCurFrmFmt
+#*  Datum       :  JP 31.07.95
+#*  Update      :  JP 31.07.95
+#***********************************************************************/
+
+SwFrmFmt* SwFEShell::WizzardGetFly()
+{
+    // mal nicht uebers Layout den Fly suchen. Dann kann auch ohne gueltiges
+    // Layout ein Rahmen geloescht werden. ( z.B.: fuer die Wizard's )
+    SwSpzFrmFmts& rSpzArr = *pDoc->GetSpzFrmFmts();
+    sal_uInt16 nCnt = rSpzArr.Count();
+    if( nCnt )
+    {
+        SwNodeIndex& rCrsrNd = GetCrsr()->GetPoint()->nNode;
+        if( rCrsrNd.GetIndex() > pDoc->GetNodes().GetEndOfExtras().GetIndex() )
+            // Cusor steht im Body-Bereich!
+            return 0;
+
+        for( sal_uInt16 n = 0; n < nCnt; ++n )
+        {
+            SwFrmFmt* pFmt = rSpzArr[ n ];
+            const SwNodeIndex* pIdx = pFmt->GetCntnt( sal_False ).GetCntntIdx();
+            SwStartNode* pSttNd;
+            if( pIdx &&
+                0 != ( pSttNd = pIdx->GetNode().GetStartNode() ) &&
+                pSttNd->GetIndex() < rCrsrNd.GetIndex() &&
+                rCrsrNd.GetIndex() < pSttNd->EndOfSectionIndex() )
+            {
+                // gefunden: also raus damit
+                return pFmt;
+            }
+        }
+    }
+    return 0;
+}
+
+void SwFEShell::SetFlyName( const String& rName )
+{
+    SwLayoutFrm *pFly = FindFlyFrm();
+    if( pFly )
+        GetDoc()->SetFlyName( *(SwFlyFrmFmt*)pFly->GetFmt(), rName );
+    else
+        ASSERT( !this, "kein FlyFrame selektiert" )
+}
+
+const String& SwFEShell::GetFlyName() const
+{
+    SwLayoutFrm *pFly = FindFlyFrm();
+    if( pFly )
+        return pFly->GetFmt()->GetName();
+
+    ASSERT( !this, "kein FlyFrame selektiert" )
+    return aEmptyStr;
+}
+
+
+String SwFEShell::GetUniqueGrfName() const
+{
+    return GetDoc()->GetUniqueGrfName();
+}
+
+const SwFrmFmt* SwFEShell::IsURLGrfAtPos( const Point& rPt, String* pURL,
+                                        String *pTargetFrameName,
+                                        String *pDescription ) const
+{
+    if( !Imp()->HasDrawView() )
+        return 0;
+
+    SdrObject* pObj;
+    SdrPageView* pPV;
+    const SwFrmFmt* pRet = 0;
+    SwDrawView *pDView = (SwDrawView*)Imp()->GetDrawView();
+
+    sal_uInt16 nOld = pDView->GetHitTolerancePixel();
+    pDView->SetHitTolerancePixel( 2 );
+
+    if( pDView->PickObj( rPt, pObj, pPV,SDRSEARCH_PICKMACRO ) &&
+        pObj->IsWriterFlyFrame() )
+    {
+        SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+        const SwFmtURL &rURL = pFly->GetFmt()->GetURL();
+        if( rURL.GetURL().Len() || rURL.GetMap() )
+        {
+            FASTBOOL bSetTargetFrameName = pTargetFrameName != 0;
+            FASTBOOL bSetDescription = pDescription != 0;
+            if ( rURL.GetMap() )
+            {
+                IMapObject *pObj = pFly->GetFmt()->GetIMapObject( rPt, pFly );
+                if ( pObj && pObj->GetURL().Len() )
+                {
+                    if( pURL )
+                        *pURL = pObj->GetURL();
+                    if ( bSetTargetFrameName && pObj->GetTarget().Len() )
+                    {
+                        bSetTargetFrameName = sal_False;
+                        *pTargetFrameName = pObj->GetTarget();
+                    }
+                    if ( bSetDescription )
+                    {
+                        bSetDescription = sal_False;
+                        *pDescription = pObj->GetDescription();
+                    }
+                    pRet = pFly->GetFmt();
+                }
+            }
+            else
+            {
+                if( pURL )
+                {
+                    *pURL = rURL.GetURL();
+                    if( rURL.IsServerMap() )
+                    {
+                        // dann die rel. Pixel Position anhaengen !!
+                        Point aPt( rPt );
+                        aPt -= pFly->Frm().Pos();
+                        // ohne MapMode-Offset, ohne Offset, o ... !!!!!
+                        aPt = (Point&)(Size&)GetOut()->LogicToPixel(
+                                (Size&)aPt, MapMode( MAP_TWIP ) );
+                        ((( *pURL += '?' ) += String::CreateFromInt32( aPt.X() ))
+                                  += ',' ) += String::CreateFromInt32(aPt.Y() );
+                    }
+                }
+                pRet = pFly->GetFmt();
+            }
+            if ( bSetTargetFrameName )
+                *pTargetFrameName = rURL.GetTargetFrameName();
+            if ( bSetDescription )
+                *pDescription = pFly->GetFmt()->GetName();
+        }
+    }
+    pDView->SetHitTolerancePixel( nOld );
+    return pRet;
+}
+
+const Graphic *SwFEShell::GetGrfAtPos( const Point &rPt,
+                                       String &rName, sal_Bool &rbLink ) const
+{
+    if( !Imp()->HasDrawView() )
+        return 0;
+
+    SdrObject* pObj;
+    SdrPageView* pPV;
+    SwDrawView *pDView = (SwDrawView*)Imp()->GetDrawView();
+
+    if( pDView->PickObj( rPt, pObj, pPV ) && pObj->IsWriterFlyFrame() )
+    {
+        SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+        if ( pFly->Lower() && pFly->Lower()->IsNoTxtFrm() )
+        {
+            SwGrfNode *pNd = ((SwCntntFrm*)pFly->Lower())->GetNode()->GetGrfNode();
+            if ( pNd )
+            {
+                if ( pNd->IsGrfLink() )
+                {
+                    //Halbfertige Grafik?
+                    SvPseudoObject* pLnkObj = pNd->GetLink()->GetObj();
+                    if ( pLnkObj && ERRCODE_SO_PENDING == pLnkObj->GetUpToDateStatus() )
+                        return 0;
+                    rbLink = sal_True;
+                }
+
+                pNd->GetFileFilterNms( &rName, 0 );
+                if ( !rName.Len() )
+                    rName = pFly->GetFmt()->GetName();
+                pNd->SwapIn( sal_True );
+                return &pNd->GetGrf();
+            }
+        }
+    }
+    return 0;
+}
+
+
+const SwFrmFmt* SwFEShell::GetFmtFromObj( const Point& rPt, SwRect** pRectToFill ) const
+{
+    SwFrmFmt* pRet = 0;
+
+    if( Imp()->HasDrawView() )
+    {
+        SdrObject* pObj;
+        SdrPageView* pPView;
+
+        SwDrawView *pDView = (SwDrawView*)Imp()->GetDrawView();
+
+        sal_uInt16 nOld = pDView->GetHitTolerancePixel();
+        // Tattergrenze fuer Drawing-SS
+        pDView->SetHitTolerancePixel( pDView->GetMarkHdlSizePixel()/2 );
+
+        if( pDView->PickObj( rPt, pObj, pPView, SDRSEARCH_PICKMARKABLE ) )
+        {
+            // dann teste mal was es ist:
+            if ( pObj->IsWriterFlyFrame() )
+                pRet = ((SwVirtFlyDrawObj*)pObj)->GetFmt();
+            else if ( pObj->GetUserCall() ) //nicht fuer Gruppenobjekte
+                pRet = ((SwDrawContact*)pObj->GetUserCall())->GetFmt();
+            if(pRet && pRectToFill)
+                **pRectToFill = pObj->GetBoundRect();
+        }
+        pDView->SetHitTolerancePixel( nOld );
+    }
+    return pRet;
+}
+
+// returns a format too, if the point is over the text of any fly
+const SwFrmFmt* SwFEShell::GetFmtFromAnyObj( const Point& rPt ) const
+{
+    const SwFrmFmt* pRet = GetFmtFromObj( rPt );
+    if( !pRet || RES_FLYFRMFMT == pRet->Which() )
+    {
+        SwPosition aPos( *GetCrsr()->GetPoint() );
+        Point aPt( rPt );
+        GetLayout()->GetCrsrOfst( &aPos, aPt );
+        SwCntntNode *pNd = aPos.nNode.GetNode().GetCntntNode();
+        SwFrm* pFrm = pNd->GetFrm( &rPt )->FindFlyFrm();
+        pRet = pFrm ? ((SwLayoutFrm*)pFrm)->GetFmt() : 0;
+    }
+    return pRet;
+}
+
+ObjCntType SwFEShell::GetObjCntType( const SdrObject& rObj ) const
+{
+    ObjCntType eType;
+    if( FmFormInventor == rObj.GetObjInventor() )
+    {
+        eType = OBJCNT_CONTROL;
+        uno::Reference< awt::XControlModel >  xModel = ((SdrUnoObj&)rObj).GetUnoControlModel();
+        if( xModel.is() )
+        {
+            uno::Any aVal;
+            OUString sName = OUString::createFromAscii("ButtonType");
+            uno::Reference< beans::XPropertySet >  xSet(xModel, uno::UNO_QUERY);
+
+            uno::Reference< beans::XPropertySetInfo >  xInfo = xSet->getPropertySetInfo();
+            if(xInfo->hasPropertyByName( sName ))
+            {
+                beans::Property xProperty = xInfo->getPropertyByName( sName );
+                aVal = xSet->getPropertyValue( sName );
+                if( aVal.getValue() && form::FormButtonType_URL == *((form::FormButtonType*)aVal.getValue()) )
+                    eType = OBJCNT_URLBUTTON;
+            }
+        }
+    }
+    else if( rObj.IsWriterFlyFrame() )
+    {
+        SwFlyFrm *pFly = ((SwVirtFlyDrawObj&)rObj).GetFlyFrm();
+        if ( pFly->Lower() && pFly->Lower()->IsNoTxtFrm() )
+        {
+            if ( ((SwCntntFrm*)pFly->Lower())->GetNode()->GetGrfNode() )
+                eType = OBJCNT_GRF;
+            else
+                eType = OBJCNT_OLE;
+        }
+        else
+            eType = OBJCNT_FLY;
+    }
+    else if( rObj.ISA( SdrObjGroup ) && FLY_IN_CNTNT !=
+        ((SwDrawContact*)GetUserCall(&rObj))->GetFmt()->GetAnchor().GetAnchorId() )
+        eType = OBJCNT_GROUPOBJ;
+    else
+        eType = OBJCNT_SIMPLE;
+    return eType;
+}
+
+ObjCntType SwFEShell::GetObjCntType( const Point &rPt, SdrObject *&rpObj ) const
+{
+    ObjCntType eType = OBJCNT_NONE;
+
+    if( Imp()->HasDrawView() )
+    {
+        SdrObject* pObj;
+        SdrPageView* pPView;
+
+        SwDrawView *pDView = (SwDrawView*)Imp()->GetDrawView();
+
+        sal_uInt16 nOld = pDView->GetHitTolerancePixel();
+        // Tattergrenze fuer Drawing-SS
+        pDView->SetHitTolerancePixel( pDView->GetMarkHdlSizePixel()/2 );
+
+        if( pDView->PickObj( rPt, pObj, pPView, SDRSEARCH_PICKMARKABLE ) )
+            eType = GetObjCntType( *(rpObj = pObj) );
+
+        pDView->SetHitTolerancePixel( nOld );
+    }
+    return eType;
+}
+
+ObjCntType SwFEShell::GetObjCntTypeOfSelection( SdrObject** ppObj ) const
+{
+    ObjCntType eType = OBJCNT_NONE;
+
+    if( Imp()->HasDrawView() )
+    {
+        const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkList();
+        for( sal_uInt32 i = 0, nE = rMrkList.GetMarkCount(); i < nE; ++i )
+        {
+            SdrObject* pObj = rMrkList.GetMark( i )->GetObj();
+            ObjCntType eTmp = GetObjCntType( *pObj );
+            if( !i )
+            {
+                eType = eTmp;
+                if( ppObj ) *ppObj = pObj;
+            }
+            else if( eTmp != eType )
+            {
+                eType = OBJCNT_DONTCARE;
+                // einmal DontCare, immer DontCare!
+                break;
+            }
+        }
+    }
+    return eType;
+}
+
+
+sal_Bool SwFEShell::ReplaceSdrObj( const String& rGrfName, const String& rFltName,
+                                const Graphic* pGrf )
+{
+    SET_CURR_SHELL( this );
+
+    sal_Bool bRet = sal_False;
+    const SdrMarkList *pMrkList;
+    if( Imp()->HasDrawView() &&  1 ==
+        ( pMrkList = &Imp()->GetDrawView()->GetMarkList())->GetMarkCount() )
+    {
+        SdrObject* pObj = pMrkList->GetMark( 0 )->GetObj();
+        SwFrmFmt *pFmt = FindFrmFmt( pObj );
+
+        // Attribute sichern und dann an der Grafik setzen
+        SfxItemSet aFrmSet( pDoc->GetAttrPool(),
+                            pFmt->GetAttrSet().GetRanges() );
+        aFrmSet.Set( pFmt->GetAttrSet() );
+
+        // Groesse und Position setzen ??
+        if( !pObj->IsWriterFlyFrame() )
+        {
+            // dann mal los:
+            const Rectangle &rBound = pObj->GetSnapRect();
+            Point aRelPos( pObj->GetRelativePos() );
+
+            const long nWidth = rBound.Right()  - rBound.Left();
+            const long nHeight= rBound.Bottom() - rBound.Top();
+            aFrmSet.Put( SwFmtFrmSize( ATT_MIN_SIZE,
+                                Max( nWidth,  long(MINFLY) ),
+                                Max( nHeight, long(MINFLY) )));
+
+            if( SFX_ITEM_SET != aFrmSet.GetItemState( RES_HORI_ORIENT ))
+                aFrmSet.Put( SwFmtHoriOrient( aRelPos.X(), HORI_NONE, FRAME ));
+
+            if( SFX_ITEM_SET != aFrmSet.GetItemState( RES_VERT_ORIENT ))
+                aFrmSet.Put( SwFmtVertOrient( aRelPos.Y(), VERT_NONE, FRAME ));
+
+        }
+
+        sal_uInt32 nOrdNum = pObj->GetOrdNum();
+
+        StartAllAction();
+        StartUndo();
+
+        // das "Sdr-Object" loeschen und dafuer die Grafik einfuegen
+        DelSelectedObj();
+
+        pFmt = GetDoc()->Insert( *GetCrsr(), rGrfName, rFltName, pGrf, &aFrmSet );
+
+        // die Ordnungsnummer (Z-Order) noch uebertragen
+        // JP 04.07.98: klappt aber nicht richtig!
+        //SdrObject* pNewObj = ::FindSdrObject( pFmt );
+        //pNewObj->SetOrdNum( nOrdNum );
+
+        EndUndo();
+        EndAllAction();
+        bRet = sal_True;
+    }
+    return bRet;
+}
+
+
diff --git a/sw/source/core/frmedt/feflyole.cxx b/sw/source/core/frmedt/feflyole.cxx
new file mode 100644
index 000000000000..dd5cbff58965
--- /dev/null
+++ b/sw/source/core/frmedt/feflyole.cxx
@@ -0,0 +1,194 @@
+/*************************************************************************
+ *
+ *  $RCSfile: feflyole.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:19 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _IPOBJ_HXX //autogen
+#include 
+#endif
+#ifndef _EMBOBJ_HXX //autogen
+#include 
+#endif
+
+
+#ifndef _FMTCNTNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#include "fesh.hxx"
+#include "cntfrm.hxx"
+#include "frmfmt.hxx"
+#include "flyfrm.hxx"
+#include "pam.hxx"
+#include "edimp.hxx"
+#include "ndtxt.hxx"
+#include "notxtfrm.hxx"
+#include "ndole.hxx"
+
+
+
+SwFlyFrm *SwFEShell::FindFlyFrm( const SvEmbeddedObject *pIPObj ) const
+{
+    SwFlyFrm *pFly = FindFlyFrm();
+    if ( pFly && pFly->Lower() && pFly->Lower()->IsNoTxtFrm() )
+    {
+        SwOLENode *pNd = ((SwNoTxtFrm*)pFly->Lower())->GetNode()->GetOLENode();
+        if ( !pNd || &pNd->GetOLEObj().GetOleRef() != pIPObj )
+            pFly = 0;
+    }
+    else
+        pFly = 0;
+
+    if ( !pFly )
+    {
+        //Kein Fly oder der falsche selektiert. Ergo muessen wir leider suchen.
+        SwStartNode *pStNd;
+        ULONG nSttIdx = GetNodes().GetEndOfAutotext().StartOfSectionIndex() + 1,
+              nEndIdx = GetNodes().GetEndOfAutotext().GetIndex();
+        while( nSttIdx < nEndIdx &&
+                0 != (pStNd = GetNodes()[ nSttIdx ]->GetStartNode()) )
+        {
+            SwNode *pNd = GetNodes()[ nSttIdx+1 ];
+            if ( pNd->IsOLENode() &&
+                                        //do not load Objects! must not be neccessary here
+                 ((SwOLENode*)pNd)->GetOLEObj().IsOleRef() &&
+                 &((SwOLENode*)pNd)->GetOLEObj().GetOleRef() == pIPObj )
+            {
+                SwFrm *pFrm = ((SwOLENode*)pNd)->GetFrm();
+                if ( pFrm )
+                    pFly = pFrm->FindFlyFrm();
+                break;
+            }
+            nSttIdx = pStNd->EndOfSectionIndex() + 1;
+        }
+
+        if ( !pFly )
+        {
+            ASSERT( !this, "FlyFrm not found." );
+            return 0;
+        }
+    }
+    return pFly;
+}
+
+
+void SwFEShell::GrfToOle( SvInPlaceObject * pObj )
+{
+    SET_CURR_SHELL( this );
+    StartAllAction();
+    FOREACHPAM_START( this )
+
+        GetDoc()->GrfToOle( *PCURCRSR, pObj );
+
+    FOREACHPAM_END()
+    EndAllAction();
+}
+
+
+void SwFEShell::OleToGrf( const Graphic *pGrf )
+{
+    SET_CURR_SHELL( this );
+    StartAllAction();
+    FOREACHPAM_START( this )
+
+        GetDoc()->OleToGrf( *PCURCRSR, pGrf );
+
+    FOREACHPAM_END()
+    EndAllAction();
+}
+
+
+String SwFEShell::GetUniqueOLEName() const
+{
+    return GetDoc()->GetUniqueOLEName();
+}
+
+
+String SwFEShell::GetUniqueFrameName() const
+{
+    return GetDoc()->GetUniqueFrameName();
+}
+
+
+void SwFEShell::MakeObjVisible( const SvEmbeddedObject *pIPObj ) const
+{
+    SwFlyFrm *pFly = FindFlyFrm( pIPObj );
+    if ( pFly )
+    {
+        SwRect aTmp( pFly->Prt() );
+        aTmp += pFly->Frm().Pos();
+        if ( !aTmp.IsOver( VisArea() ) )
+        {
+            ((SwFEShell*)this)->StartAction();
+            ((SwFEShell*)this)->MakeVisible( aTmp );
+            ((SwFEShell*)this)->EndAction();
+        }
+    }
+}
+
+
+
+
diff --git a/sw/source/core/frmedt/feshview.cxx b/sw/source/core/frmedt/feshview.cxx
new file mode 100644
index 000000000000..487b9e40fcac
--- /dev/null
+++ b/sw/source/core/frmedt/feshview.cxx
@@ -0,0 +1,2559 @@
+/*************************************************************************
+ *
+ *  $RCSfile: feshview.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:19 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#define ITEMID_BOXINFO      SID_ATTR_BORDER_INNER
+#include "hintids.hxx"
+
+#ifdef WIN
+#define NEEDED_BY_FESHVIEW
+#define _FESHVIEW_ONLY_INLINE_NEEDED
+#endif
+
+#ifndef _SVDOUNO_HXX //autogen
+#include 
+#endif
+#ifndef _SVDOOLE2_HXX //autogen
+#include 
+#endif
+#ifndef _SVDOGRP_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_FILLITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVDVMARK_HXX //autogen
+#include 
+#endif
+#ifndef _XPOLY_HXX //autogen
+#include 
+#endif
+#ifndef _SVDCAPT_HXX //autogen
+#include 
+#endif
+#ifndef _SFXINIMGR_HXX //autogen
+#include 
+#endif
+#ifndef _SFXAPP_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BOXITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_OPAQITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_PROTITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVDPAGE_HXX //autogen
+#include 
+#endif
+#ifndef _IPOBJ_HXX //autogen
+#include 
+#endif
+
+
+#ifndef _FRMFMT_HXX //autogen
+#include 
+#endif
+#ifndef _FRMATR_HXX
+#include 
+#endif
+#ifndef _FMTFSIZE_HXX //autogen
+#include 
+#endif
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _FMTORNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTSRND_HXX //autogen
+#include 
+#endif
+#ifndef _FMTCNTNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFLCNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTCNCT_HXX //autogen
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _TBLSEL_HXX //autogen
+#include 
+#endif
+#ifndef _SWTABLE_HXX //autogen
+#include 
+#endif
+#include "fesh.hxx"
+#include "rootfrm.hxx"
+#include "pagefrm.hxx"
+#include "sectfrm.hxx"
+#include "doc.hxx"
+#include "dview.hxx"
+#include "dflyobj.hxx"
+#include "dcontact.hxx"
+#include "viewimp.hxx"
+#include "flyfrm.hxx"
+#include "pam.hxx"
+#include "ndole.hxx"
+#include "ndgrf.hxx"
+#include "ndtxt.hxx"
+#include "viewopt.hxx"                  // fuer GetHTMLMode
+#include "swundo.hxx"
+#include "notxtfrm.hxx"
+#include "txtfrm.hxx"
+#include "txatbase.hxx"
+#include "mdiexp.hxx"                   // fuer Update der Statuszeile bei drag
+
+#define SCROLLVAL 75
+
+//Tattergrenze fuer Drawing-SS
+#define MINMOVE ((USHORT)GetOut()->PixelToLogic(Size(Imp()->GetDrawView()->GetMarkHdlSizePixel()/2,0)).Width())
+
+SwFlyFrm *GetFlyFromMarked( const SdrMarkList *pLst, ViewShell *pSh )
+{
+    if ( !pLst )
+        pLst = pSh->HasDrawView() ? &pSh->Imp()->GetDrawView()->GetMarkList():0;
+
+    if ( pLst && pLst->GetMarkCount() == 1 )
+    {
+        SdrObject *pO = pLst->GetMark( 0 )->GetObj();
+        if ( pO->IsWriterFlyFrame() )
+            return ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+    }
+    return 0;
+}
+
+void lcl_GrabCursor( SwFEShell* pSh, SwFlyFrm* pOldSelFly)
+{
+    const SwFrmFmt *pFlyFmt = pSh->SelFlyGrabCrsr();
+    if( pFlyFmt && !pSh->ActionPend() &&
+                        (!pOldSelFly || pOldSelFly->GetFmt() != pFlyFmt) )
+    {
+        // dann das evt. gesetzte Macro rufen
+        pSh->GetFlyMacroLnk().Call( (void*)pFlyFmt );
+extern BOOL bNoInterrupt;       // in swapp.cxx
+        // wir in dem Makro ein Dialog gestartet, dann kommt das
+        // MouseButtonUp zu diesem und nicht zu uns. Dadurch ist
+        // Flag bei uns immer gesetzt und schaltet nie die auf die
+        // entsp. Shell um !!!!!!!
+        bNoInterrupt = FALSE;
+    }
+    else if( !pFlyFmt || RES_DRAWFRMFMT == pFlyFmt->Which() )
+        pSh->SetCrsr( pSh->Imp()->GetDrawView()->GetAllMarkedRect().TopLeft(), TRUE);
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::SelectObj()
+|*
+|*  Ersterstellung      MA 16. Nov. 92
+|*  Letzte Aenderung    MA 22. Oct. 96
+|*
+*************************************************************************/
+
+BOOL SwFEShell::SelectObj( const Point& rPt, BOOL bAddSelect,
+                           BOOL bEnterGroup, SdrObject *pObj )
+{
+    SET_CURR_SHELL( this );
+    StartAction();          //Aktion ist Notwendig, damit nicht mehrere
+                            //AttrChgdNotify (etwa durch Unmark->MarkListHasChgd)
+                            //durchkommen
+
+    ASSERT( Imp()->HasDrawView(), "SelectObj without DrawView?" );
+    SwDrawView *pDView = Imp()->GetDrawView();
+    const SdrMarkList &rMrkList = pDView->GetMarkList();
+    const BOOL bHadSelection = rMrkList.GetMarkCount() ? TRUE : FALSE;
+    SwFlyFrm* pOldSelFly = 0;
+    const Point aOldPos( pDView->GetAllMarkedRect().TopLeft() );
+
+    if( bHadSelection )
+    {
+        //Unmark rufen wenn !bAddSelect oder wenn ein Fly selektiert ist.
+        BOOL bUnmark = !bAddSelect;
+
+        if ( rMrkList.GetMarkCount() == 1 )
+        {
+            //Wenn ein Fly selektiert ist, so muss er erst deselektiert werden.
+            pOldSelFly = ::GetFlyFromMarked( &rMrkList, this );
+            if ( pOldSelFly )
+            {
+                const USHORT nType = GetCntType();
+                if( nType != CNT_TXT ||
+                    ( pOldSelFly->GetFmt()->GetProtect().IsCntntProtected()
+                     && !IsReadOnlyAvailable() ))
+                {
+                    //Wenn ein Fly deselektiert wird, der Grafik, Ole o.ae.
+                    //enthaelt, so muss der Crsr aus diesem entfernt werden.
+                    //Desgleichen wenn ein Fly mit geschuetztem Inhalt deselektiert
+                    //wird. Der Einfachheit halber wire der Crsr 'grad so neben die
+                    //linke obere Ecke gesetzt.
+                    Point aPt( pOldSelFly->Frm().Pos() );
+                    aPt.X() -= 1;
+                    BOOL bUnLockView = !IsViewLocked();
+                    LockView( TRUE );
+                    SetCrsr( aPt, TRUE );
+                    if( bUnLockView )
+                        LockView( FALSE );
+                }
+                if ( nType & CNT_GRF &&
+                     ((SwNoTxtFrm*)pOldSelFly->Lower())->HasAnimation() )
+                {
+                    GetWin()->Invalidate( pOldSelFly->Frm().SVRect() );
+                }
+                bUnmark = TRUE;
+            }
+#ifdef USED
+            else
+            {
+                SdrObject *pObj = rMrkList.GetMark( 0 )->GetObj();
+                SwFrmFmt *pFrmFmt = FindFrmFmt( pObj );
+                if( pFrmFmt &&
+                    FLY_IN_CNTNT == pFrmFmt->GetAnchor().GetAnchorId() )
+                    bUnmark = TRUE;
+            }
+#endif
+        }
+        if ( bUnmark )
+            pDView->UnmarkAll();
+    }
+    else
+    {
+        KillPams();
+        ClearMark();
+    }
+
+    if ( pObj )
+        pDView->MarkObj( pObj, Imp()->GetPageView(), bAddSelect, bEnterGroup );
+    else
+        pDView->MarkObj( rPt, MINMOVE, bAddSelect, bEnterGroup );
+
+    const FASTBOOL bRet = 0 != rMrkList.GetMarkCount();
+
+    if ( rMrkList.GetMarkCount() > 1 )
+    {
+        //Ganz dumm ist es, wenn Zeichenobjekte Selektiert waren und
+        //nun ein Fly hinzuselektiert wird.
+        for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
+        {
+            SdrObject *pObj = rMrkList.GetMark( i )->GetObj();
+            BOOL bForget = pObj->IsWriterFlyFrame();
+            if( bForget )
+            {
+                pDView->UnmarkAll();
+                if ( pObj )
+                    pDView->MarkObj( pObj, Imp()->GetPageView(), bAddSelect, bEnterGroup );
+                else
+                    pDView->MarkObj( rPt, MINMOVE );
+                break;
+            }
+        }
+    }
+
+    if ( bRet )
+    {
+        ::lcl_GrabCursor(this, pOldSelFly);
+        if ( GetCntType() & CNT_GRF )
+        {
+            const SwFlyFrm *pTmp = GetFlyFromMarked( &rMrkList, this );
+            ASSERT( pTmp, "Graphic without Fly" );
+            if ( ((SwNoTxtFrm*)pTmp->Lower())->HasAnimation() )
+                ((SwNoTxtFrm*)pTmp->Lower())->StopAnimation( GetOut() );
+        }
+    }
+    else if ( !pOldSelFly && bHadSelection )
+        SetCrsr( aOldPos, TRUE);
+
+    if( bRet || !bHadSelection )
+        CallChgLnk();
+
+    // update der Statuszeile
+    ::FrameNotify( this, bRet ? FLY_DRAG_START : FLY_DRAG_END );
+
+    EndAction();
+    return bRet;
+}
+
+
+/*************************************************************************
+|*
+|*  SwFEShell::GetSelFrmType()
+|*
+|*  Ersterstellung      MA 12. Jan. 93
+|*  Letzte Aenderung    JP 19.03.96
+|*
+*************************************************************************/
+
+USHORT SwFEShell::GetSelFrmType() const
+{
+    const SdrMarkList* pMrkList;
+    if( !Imp()->GetDrawView() ||
+        0 == (pMrkList = &Imp()->GetDrawView()->GetMarkList()) ||
+        !pMrkList->GetMarkCount())
+        return FRMTYPE_NONE;
+
+    const SwFlyFrm *pFly = ::GetFlyFromMarked( pMrkList, (ViewShell*)this );
+
+    if ( pFly )
+    {
+        if( pFly->IsFlyLayFrm() )
+            return FRMTYPE_FLY_FREE;
+        else if( pFly->IsFlyAtCntFrm() )
+            return FRMTYPE_FLY_ATCNT;
+        ASSERT( pFly->IsFlyInCntFrm(), "Neuer Rahmentyp?" );
+        return FRMTYPE_FLY_INCNT;
+    }
+    return FRMTYPE_DRAWOBJ;
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::Scroll()
+|*
+|*  Ersterstellung      MA 20. Dec. 94
+|*  Letzte Aenderung    MA 27. Jul. 95
+|*
+*************************************************************************/
+
+void SwFEShell::Scroll( const Point &rPt )
+{
+    const SwRect aRect( rPt, rPt );
+    if ( IsScrollMDI( this, aRect ) &&
+         (!Imp()->GetDrawView()->GetMarkList().GetMarkCount() ||
+          Imp()->IsDragPossible( rPt )) )
+    {
+        SwSaveHdl aSave( Imp() );
+        ScrollMDI( this, aRect, SCROLLVAL, SCROLLVAL );
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::SetDragMode()
+|*
+|*  Ersterstellung      MA 30. Jan. 95
+|*  Letzte Aenderung    MA 30. Jan. 95
+|*
+*************************************************************************/
+
+void SwFEShell::SetDragMode( UINT16 eDragMode )
+{
+    if ( Imp()->HasDrawView() )
+        Imp()->GetDrawView()->SetDragMode( (SdrDragMode)eDragMode );
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::BeginDrag()
+|*
+|*  Ersterstellung      MS 10.06.92
+|*  Letzte Aenderung    MA 13. Mar. 96
+|*
+*************************************************************************/
+
+long SwFEShell::BeginDrag( const Point* pPt, BOOL )
+{
+    SdrView *pView = Imp()->GetDrawView();
+    if ( pView && pView->HasMarkedObj() )
+    {
+        delete pChainFrom; delete pChainTo; pChainFrom = pChainTo = 0;
+        SdrHdl* pHdl = pView->HitHandle( *pPt, *GetWin() );
+        pView->BegDragObj( *pPt, GetWin(), pHdl );
+        ::FrameNotify( this, FLY_DRAG );
+        return 1;
+    }
+    return 0;
+}
+/*************************************************************************
+|*
+|*  SwFEShell::Drag()
+|*
+|*  Ersterstellung      MS 10.06.92
+|*  Letzte Aenderung    MA 13. Mar. 96
+|*
+*************************************************************************/
+
+long SwFEShell::Drag( const Point *pPt, BOOL )
+{
+    ASSERT( Imp()->HasDrawView(), "Drag without DrawView?" );
+    if ( Imp()->GetDrawView()->IsDragObj() )
+    {
+        Scroll( *pPt );
+
+#ifdef USED
+JP 31.01.96: der Wunsch ist, das Orthogonale Resizen nur vom Benutzer
+             vorgegeben werden kann.  (beschlossen und verkuendet: ST/WP/..)
+        //OLE wird immer proportional resized.
+        if ( !Imp()->GetDrawView()->IsMoveOnlyDragObj( TRUE ) &&
+             GetCntType() == CNT_OLE )
+            Imp()->GetDrawView()->SetOrtho( TRUE );
+#endif
+
+        Imp()->GetDrawView()->MovDragObj( *pPt );
+        Imp()->GetDrawView()->ShowDragAnchor();
+        ::FrameNotify( this, FLY_DRAG );
+        return 1;
+    }
+    return 0;
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::EndDrag()
+|*
+|*  Ersterstellung      MS 10.06.92
+|*  Letzte Aenderung    MA 13. Mar. 96
+|*
+*************************************************************************/
+
+long SwFEShell::EndDrag( const Point *, BOOL )
+{
+    ASSERT( Imp()->HasDrawView(), "EndDrag without DrawView?" );
+    SdrView *pView = Imp()->GetDrawView();
+    if ( pView->IsDragObj() )
+    {
+        //Start-/EndActions nur an der ViewShell aufsetzen
+        ViewShell *pSh = this;
+        do {
+            pSh->StartAction();
+        } while ( this != (pSh = (ViewShell*)pSh->GetNext()) );
+
+        StartUndo( UNDO_START );
+
+        //#50778# Bug im Draging: Im StartAction wird ein HideShowXor gerufen.
+        //Im EndDragObj() wird dies unsinniger und faelschlicherweise wieder
+        //Rueckgaengig gemacht. Um Konsistenz herzustellen muessen wir das
+        //Xor also wieder zur Anzeige bringen.
+//      pView->ShowShownXor( GetOut() );
+        pView->EndDragObj();
+        // JP 18.08.95: DrawUndo-Action auf FlyFrames werden nicht gespeichert
+        //              Die Fly aendern das Flag
+        GetDoc()->SetNoDrawUndoObj( FALSE );
+        ChgAnchor( 0, TRUE );
+
+        EndUndo( UNDO_END );
+
+        do {
+            pSh->EndAction();
+            if( pSh->IsA( TYPE( SwCrsrShell ) ) )
+                ((SwCrsrShell*)pSh)->CallChgLnk();
+        } while ( this != (pSh = (ViewShell*)pSh->GetNext()) );
+
+        GetDoc()->SetModified();
+        ::FrameNotify( this, FLY_DRAG );
+        return 1;
+    }
+    return 0;
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::BreakDrag()
+|*
+|*  Ersterstellung      OM 02. Okt. 95
+|*  Letzte Aenderung    OM 02. Okt. 95
+|*
+*************************************************************************/
+
+void SwFEShell::BreakDrag()
+{
+    ASSERT( Imp()->HasDrawView(), "BreakDrag without DrawView?" );
+    if ( Imp()->GetDrawView()->IsDragObj() )
+        Imp()->GetDrawView()->BrkDragObj();
+    SetChainMarker();
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::SelFlyGrabCrsr()
+|*
+|*  Beschreibung        Wenn ein Fly selektiert ist, zieht er den Crsr in
+|*                      den ersten CntntFrm
+|*  Ersterstellung      MA 11. Dec. 92
+|*  Letzte Aenderung    MA 07. Oct. 96
+|*
+*************************************************************************/
+
+const SwFrmFmt* SwFEShell::SelFlyGrabCrsr()
+{
+    if ( Imp()->HasDrawView() )
+    {
+        const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkList();
+        SwFlyFrm *pFly = ::GetFlyFromMarked( &rMrkList, this );
+
+        if( pFly )
+        {
+            pFly->GetAnchor()->Calc();
+            SwCntntFrm *pCFrm = pFly->ContainsCntnt();
+            if ( pCFrm )
+            {
+                SwCntntNode *pCNode = pCFrm->GetNode();
+                SwPaM       *pCrsr  = GetCrsr();
+
+                pCrsr->GetPoint()->nNode = *pCNode;
+                pCrsr->GetPoint()->nContent.Assign( pCNode, 0 );
+
+                SwRect& rChrRect = (SwRect&)GetCharRect();
+                rChrRect = pFly->Prt();
+                rChrRect.Pos() += pFly->Frm().Pos();
+                GetCrsrDocPos() = rChrRect.Pos();
+            }
+            return pFly->GetFmt();
+        }
+    }
+    return 0;
+}
+
+
+/*************************************************************************
+|*
+|*  SwFEShell::SelectionToTop(), SelectionToBottom()
+|*
+|*  Beschreibung        Selektion nach oben/unten (Z-Order)
+|*
+|*  Ersterstellung      MA 05. Nov. 92
+|*  Letzte Aenderung    MA 03. Jun. 96
+|*
+*************************************************************************/
+
+void lcl_NotifyNeighbours( const SdrMarkList *pLst )
+{
+    //Die Regeln fuer die Ausweichmanoever haben sich veraendert.
+    //1. Die Umgebung des Fly und aller innenliegenden muss benachrichtigt
+    //   werden.
+    //2. Der Inhalt des Rahmen selbst muss benachrichtigt werden.
+    //3. Rahmen die dem Rahmen ausweichen bzw. wichen muessen benachrichtigt werden.
+    //4. Auch Zeichenobjekte koennen Rahmen verdraengen
+
+    for( USHORT j = 0; j < pLst->GetMarkCount(); ++j )
+    {
+        SwPageFrm *pPage;
+        BOOL bCheckNeighbours = FALSE;
+        SwHoriOrient aHori;
+        SwRect aRect;
+        SdrObject *pO = pLst->GetMark( 0 )->GetObj();
+        if ( pO->IsWriterFlyFrame() )
+        {
+            SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+
+            const SwFmtHoriOrient &rHori = pFly->GetFmt()->GetHoriOrient();
+            aHori = rHori.GetHoriOrient();
+            if( HORI_NONE != aHori && HORI_CENTER != aHori &&
+                pFly->IsFlyAtCntFrm() )
+            {
+                bCheckNeighbours = TRUE;
+                pFly->InvalidatePos();
+                pFly->Frm().Pos().Y() += 1;
+            }
+
+            pPage = pFly->FindPageFrm();
+            aRect = pFly->Frm();
+        }
+        else
+        {
+            SwFrm *pAnch = ( (SwDrawContact*)GetUserCall(pO) )->GetAnchor();
+            if( !pAnch )
+                continue;
+            pPage = pAnch->FindPageFrm();
+            aRect = GetBoundRect( pO );
+        }
+
+        USHORT nCount = pPage->GetSortedObjs() ? pPage->GetSortedObjs()->Count() : 0;
+        for ( USHORT i = 0; i < nCount; ++i )
+        {
+            SdrObject *pO = (*pPage->GetSortedObjs())[i];
+            if ( !pO->IsWriterFlyFrame() )
+                continue;
+
+            SwVirtFlyDrawObj *pObj = (SwVirtFlyDrawObj*)pO;
+
+            SwFlyFrm *pAct = pObj->GetFlyFrm();
+            SwRect aTmpCalcPnt( pAct->Prt() );
+            aTmpCalcPnt += pAct->Frm().Pos();
+            if ( aRect.IsOver( aTmpCalcPnt ) )
+            {
+                SwCntntFrm *pCnt = pAct->ContainsCntnt();
+                while ( pCnt )
+                {
+                    aTmpCalcPnt = pCnt->Prt();
+                    aTmpCalcPnt += pCnt->Frm().Pos();
+                    if ( aRect.IsOver( aTmpCalcPnt ) )
+                        ((SwFrm*)pCnt)->Prepare( PREP_FLY_ATTR_CHG );
+                    pCnt = pCnt->GetNextCntntFrm();
+                }
+            }
+            if ( bCheckNeighbours && pAct->IsFlyAtCntFrm() )
+            {
+                const SwFmtHoriOrient &rH = pAct->GetFmt()->GetHoriOrient();
+                if ( rH.GetHoriOrient() == aHori &&
+                     pAct->Frm().Top()    <= aRect.Bottom() &&
+                     pAct->Frm().Bottom() >= aRect.Top() )
+                {
+                    pAct->InvalidatePos();
+                    pAct->Frm().Pos().Y() += 1;
+                }
+            }
+        }
+    }
+}
+
+void SwFEShell::SelectionToTop( BOOL bTop )
+{
+    ASSERT( Imp()->HasDrawView(), "SelectionToTop without DrawView?" );
+    const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkList();
+    ASSERT( rMrkList.GetMarkCount(), "Kein Object Selektiert." );
+
+    SwFlyFrm *pFly = ::GetFlyFromMarked( &rMrkList, this );
+    if ( pFly && pFly->IsFlyInCntFrm() )
+        return;
+
+    StartAllAction();
+    if ( bTop )
+        Imp()->GetDrawView()->PutMarkedToTop();
+    else
+        Imp()->GetDrawView()->MovMarkedToTop();
+    ::lcl_NotifyNeighbours( &rMrkList );
+    GetDoc()->SetModified();
+    EndAllAction();
+}
+
+void SwFEShell::SelectionToBottom( BOOL bBottom )
+{
+    ASSERT( Imp()->HasDrawView(), "SelectionToBottom without DrawView?" );
+    const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkList();
+    ASSERT( rMrkList.GetMarkCount(), "Kein Object Selektiert." );
+
+    SwFlyFrm *pFly = ::GetFlyFromMarked( &rMrkList, this );
+    if ( pFly && pFly->IsFlyInCntFrm() )
+        return;
+
+    StartAllAction();
+    if ( bBottom )
+        Imp()->GetDrawView()->PutMarkedToBtm();
+    else
+        Imp()->GetDrawView()->MovMarkedToBtm();
+    ::lcl_NotifyNeighbours( &rMrkList );
+    GetDoc()->SetModified();
+    EndAllAction();
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::GetLayerId()
+|*
+|*  Beschreibung        Objekt ueber/unter dem Dokument?
+|*                      2 Controls, 1 Heaven, 0 Hell, -1 Uneindeutig
+|*  Ersterstellung      MA 20. Dec. 94
+|*  Letzte Aenderung    MA 20. Dec. 94
+|*
+*************************************************************************/
+
+short SwFEShell::GetLayerId() const
+{
+    short nRet = SHRT_MAX;
+    if ( Imp()->HasDrawView() )
+    {
+        const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkList();
+        for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
+        {
+            const SdrObject *pObj = rMrkList.GetMark( i )->GetObj();
+            if ( nRet == SHRT_MAX )
+                nRet = pObj->GetLayer();
+            else if ( nRet != pObj->GetLayer() )
+            {
+                nRet = -1;
+                break;
+            }
+        }
+    }
+    if ( nRet == SHRT_MAX )
+        nRet = -1;
+    return nRet;
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::SelectionToHeaven(), SelectionToHell()
+|*
+|*  Beschreibung        Objekt ueber/unter dem Dokument
+|*  Ersterstellung      MA 20. Dec. 94
+|*  Letzte Aenderung    AMA 04. Jun. 98
+|*
+*************************************************************************/
+
+void SwFEShell::ChangeOpaque( BYTE nLayerId )
+{
+    if ( Imp()->HasDrawView() )
+    {
+        const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkList();
+        const BYTE nControls = GetDoc()->GetControlsId();
+        for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
+        {
+            SdrObject *pObj = rMrkList.GetMark( i )->GetObj();
+            if ( pObj->GetLayer() != nLayerId && pObj->GetLayer() != nControls )
+            {
+                pObj->SetLayer( nLayerId );
+                InvalidateWindows( SwRect( pObj->GetBoundRect() ) );
+                if ( pObj->IsWriterFlyFrame() )
+                {
+                    SwFmt *pFmt = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->GetFmt();
+                    SvxOpaqueItem aOpa( pFmt->GetOpaque() );
+                    aOpa.SetValue(  nLayerId == GetDoc()->GetHellId() );
+                    pFmt->SetAttr( aOpa );
+                }
+            }
+        }
+        GetDoc()->SetModified();
+    }
+}
+
+void SwFEShell::SelectionToHeaven()
+{
+    ChangeOpaque( GetDoc()->GetHeavenId() );
+}
+
+void SwFEShell::SelectionToHell()
+{
+    ChangeOpaque( GetDoc()->GetHellId() );
+}
+
+#if 0
+/*************************************************************************
+|*
+|*  SwFEShell::FlipHellAndHeaven()
+|*
+|*  Beschreibung        Alle Zeichenobjekte aus der Hoelle in den Himmel
+|*                      und umgekehrt.
+|*  Ersterstellung      MA 12. Jan. 95
+|*  Letzte Aenderung    AMA 04. Jun. 98
+|*
+*************************************************************************/
+
+void SwFEShell::FlipHellAndHeaven()
+{
+    SwDoc *pDoc = GetDoc();
+    if ( pDoc->GetDrawModel() )
+    {
+        SdrPage* pPage = pDoc->GetDrawModel()->GetPage( 0 );
+        SdrLayerID nHeaven = (SdrLayerID)pDoc->GetHeavenId();
+        SdrLayerID nHell   = (SdrLayerID)pDoc->GetHellId();
+        SdrLayerID nControls = (SdrLayerID)pDoc->GetControlsId();
+        BOOL bChanged = FALSE;
+        for ( USHORT i = 0; i < pPage->GetObjCount(); ++i )
+        {
+            SdrObject *pObj = pPage->GetObj( i );
+            if ( !pObj->IsWriterFlyFrame() && nControls != pObj->GetLayer() )
+            {
+                pObj->SetLayer( nHeaven == pObj->GetLayer() ? nHell : nHeaven );
+                bChanged = TRUE;
+            }
+        }
+        if( bChanged )
+        {
+            InvalidateWindows( pDoc->GetRootFrm()->Frm() );
+            GetDoc()->SetModified();
+        }
+    }
+}
+#endif
+/*************************************************************************
+|*
+|*  SwFEShell::IsObjSelected(), IsFrmSelected()
+|*
+|*  Ersterstellung      MA 16. Nov. 92
+|*  Letzte Aenderung    MA 17. Jan. 95
+|*
+*************************************************************************/
+
+USHORT SwFEShell::IsObjSelected() const
+{
+    if ( IsFrmSelected() || !Imp()->HasDrawView() )
+        return 0;
+    else
+        return USHORT( Imp()->GetDrawView()->GetMarkList().GetMarkCount() );
+}
+
+BOOL SwFEShell::IsFrmSelected() const
+{
+    if ( !Imp()->HasDrawView() )
+        return FALSE;
+    else
+        return 0 != ::GetFlyFromMarked( &Imp()->GetDrawView()->GetMarkList(),
+                                        (ViewShell*)this );
+}
+
+Rectangle *SwFEShell::IsAnchorAtPos( const Point &rPt ) const
+{
+    if ( !Imp()->HasDrawView() )
+        return 0;
+    else
+        return Imp()->GetDrawView()->IsAnchorAtPos( rPt );
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::EndTextEdit()
+|*
+|*  Ersterstellung      MA 19. Feb. 96
+|*  Letzte Aenderung    MA 19. Feb. 96
+|*
+*************************************************************************/
+
+void SwFEShell::EndTextEdit()
+{
+    //Beenden des TextEditModus. Wenn gewuenscht (default wenn das Objekt
+    //keinen Text mehr enthaelt und keine Attribute traegt) wird das
+    //Objekt gel”scht. Alle anderen markierten Objekte bleiben erhalten.
+
+    ASSERT( Imp()->HasDrawView() && Imp()->GetDrawView()->IsTextEdit(),
+            "EndTextEdit an no Object" );
+
+    StartAllAction();
+    SdrView *pView = Imp()->GetDrawView();
+    SdrObject *pObj = pView->GetTextEditObject();
+    SdrObjUserCall* pUserCall;
+    if( 0 != ( pUserCall = GetUserCall(pObj) ) )
+    {
+        pUserCall->Changed( *pObj, SDRUSERCALL_RESIZE,
+            pObj->GetBoundRect() );
+    }
+    if ( !pObj->GetUpGroup() )
+    {
+        if ( SDRENDTEXTEDIT_SHOULDBEDELETED == pView->EndTextEdit( TRUE ) )
+        {
+            if ( pView->GetMarkList().GetMarkCount() > 1 )
+            {
+                {
+                    SdrMarkList aSave( pView->GetMarkList() );
+                    aSave.DeleteMark( aSave.FindObject( pObj ) );
+                    if ( aSave.GetMarkCount() )
+                    {
+                        pView->UnmarkAll();
+                        pView->MarkObj( pObj, Imp()->GetPageView() );
+                    }
+                    DelSelectedObj();
+                    if ( aSave.GetMarkCount() )
+                    {
+                        for ( USHORT i = 0; i < aSave.GetMarkCount(); ++i )
+                            pView->MarkObj( aSave.GetMark( i )->GetObj(),
+                                            Imp()->GetPageView() );
+                    }
+                }
+            }
+            else
+                DelSelectedObj();
+        }
+    }
+    else
+        pView->EndTextEdit();
+    EndAllAction();
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::IsInsideSelectedObj()
+|*
+|*  Ersterstellung      MA 16. Nov. 92
+|*  Letzte Aenderung    MA 08. Nov. 96
+|*
+*************************************************************************/
+
+int SwFEShell::IsInsideSelectedObj( const Point &rPt )
+{
+    if( Imp()->HasDrawView() )
+    {
+        SwDrawView *pDView = Imp()->GetDrawView();
+
+        if( pDView->GetMarkList().GetMarkCount() &&
+            pDView->IsMarkedObjHit( rPt ) )
+        {
+            return SDRHIT_OBJECT;
+        }
+    }
+    return SDRHIT_NONE;
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::IsObjSelectable()
+|*
+|*  Ersterstellung      MA 16. Nov. 92
+|*  Letzte Aenderung    MA 02. Feb. 95
+|*
+*************************************************************************/
+
+int SwFEShell::IsObjSelectable( const Point& rPt )
+{
+    SET_CURR_SHELL(this);
+#ifdef OLD
+    if( Imp()->HasDrawView() )
+        return Imp()->GetDrawView()->PickSomething( rPt, MINMOVE );
+    return 0;
+#else
+    SwDrawView *pDView = Imp()->GetDrawView();
+    BOOL bRet = FALSE;
+    if( pDView )
+    {
+        SdrObject* pObj;
+        SdrPageView* pPV;
+        USHORT nOld = pDView->GetHitTolerancePixel();
+        pDView->SetHitTolerancePixel( pDView->GetMarkHdlSizePixel()/2 );
+
+        bRet = pDView->PickObj( rPt, pObj, pPV, SDRSEARCH_PICKMARKABLE );
+        pDView->SetHitTolerancePixel( nOld );
+    }
+    return bRet ? 1 : 0;
+#endif
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::GotoFly()
+|*
+|*  Beschreibung        Wenn ein Fly selektiert ist, gehen wir von dessen
+|*      TopLeft aus, andernfalls von der Mitte des aktuellen CharRects.
+|*  Ersterstellung      OK  11.03.94 10:12
+|*  Letzte Aenderung    MA 29. Jul. 96
+|*
+*************************************************************************/
+
+BOOL SwFEShell::GotoFly( BOOL bNext, FlyCntType eType )
+{
+    if( !Imp()->HasDrawView() )
+        return FALSE;
+    else
+    {
+        const SwFlyFrm  *pBest  = 0,
+                        *pTop   = 0;
+
+        const long nTmp = bNext ? LONG_MAX : 0;
+        Point aBestPos( nTmp, nTmp );
+        Point aTopPos(  nTmp, nTmp );
+        Point aCurPos;
+        Point aPos;
+        BOOL  bRet = FALSE;
+
+        // Sonderfall, wenn der Cursor in einem Fly steht dann soll dieser
+        // selektiert werden !
+        pBest = GetCurrFrm( FALSE )->FindFlyFrm();
+        const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkList();
+
+        if( !pBest || rMrkList.GetMarkCount() == 1 )
+        {
+            // Ausgangspunkt bestimmen.
+            SwFlyFrm *pFly = ::GetFlyFromMarked( &rMrkList, this );
+            if( pFly )
+                aPos = pFly->Frm().Pos();
+            else
+                aPos = GetCharRect().Center();
+
+            SdrPage* pPage = GetDoc()->GetDrawModel()->GetPage( 0 );
+            const ULONG nObjs = pPage->GetObjCount();
+            for( ULONG nObj = 0; nObj < nObjs; ++nObj )
+            {
+                SdrObject *pO = pPage->GetObj( nObj );
+                if ( !pO->IsWriterFlyFrame() )
+                    continue;
+
+                SwVirtFlyDrawObj *pObj = (SwVirtFlyDrawObj*)pO;
+
+                SwFlyFrm *pFly = pObj->GetFlyFrm();
+
+                switch ( eType )
+                {
+                    case FLYCNTTYPE_FRM:
+                        if ( pFly->Lower() && pFly->Lower()->IsNoTxtFrm() )
+                            continue;
+                    break;
+                    case FLYCNTTYPE_GRF:
+                        if ( pFly->Lower() &&
+                             (pFly->Lower()->IsLayoutFrm() ||
+                              !((SwCntntFrm*)pFly->Lower())->GetNode()->GetGrfNode()))
+                            continue;
+                    break;
+                    case FLYCNTTYPE_OLE:
+                        if ( pFly->Lower() &&
+                             (pFly->Lower()->IsLayoutFrm() ||
+                              !((SwCntntFrm*)pFly->Lower())->GetNode()->GetOLENode()))
+                            continue;
+                    break;
+                }
+
+                aCurPos = pFly->Frm().Pos();
+
+                // Sonderfall wenn ein anderes Obj auf selber Y steht.
+                if( aCurPos != aPos &&          // nur wenn ich es nicht selber bin
+                    aCurPos.Y() == aPos.Y() &&  // ist die Y Position gleich
+                    (bNext? (aCurPos.X() > aPos.X()) :  // liegt neben mir
+                            (aCurPos.X() < aPos.X())) ) // " reverse
+                {
+                    aBestPos = Point( nTmp, nTmp );
+                    for( ULONG i = 0; i < nObjs; ++i )
+                    {
+                        SdrObject *pO = pPage->GetObj( i );
+                        if ( !pO->IsWriterFlyFrame() )
+                            continue;
+
+                        SwVirtFlyDrawObj *pObj = (SwVirtFlyDrawObj*)pO;
+
+                        aCurPos = pObj->GetFlyFrm()->Frm().Pos();
+
+                        if( aCurPos != aPos && aCurPos.Y() == aPos.Y() &&
+                            (bNext? (aCurPos.X() > aPos.X()) :  // liegt neben mir
+                                    (aCurPos.X() < aPos.X())) &&    // " reverse
+                            (bNext? (aCurPos.X() < aBestPos.X()) :  // besser als Beste
+                                    (aCurPos.X() > aBestPos.X())) ) // " reverse
+                        {
+                            aBestPos = aCurPos;
+                            pBest = pObj->GetFlyFrm();
+                        }
+                    }
+                    break;
+                }
+
+                if( (bNext? (aPos.Y() < aCurPos.Y()) :          // nur unter mir
+                            (aPos.Y() > aCurPos.Y())) &&        // " reverse
+                    (bNext? (aBestPos.Y() > aCurPos.Y()) :      // naeher drunter
+                            (aBestPos.Y() < aCurPos.Y())) ||    // " reverse
+                            (aBestPos.Y() == aCurPos.Y() &&
+                    (bNext? (aBestPos.X() > aCurPos.X()) :      // weiter links
+                            (aBestPos.X() < aCurPos.X()))))     // " reverse
+
+                {
+                    aBestPos = aCurPos;
+                    pBest = pObj->GetFlyFrm();
+                }
+
+                if( (bNext? (aTopPos.Y() > aCurPos.Y()) :       // hoeher als Beste
+                            (aTopPos.Y() < aCurPos.Y())) ||     // " reverse
+                            (aTopPos.Y() == aCurPos.Y() &&
+                    (bNext? (aTopPos.X() > aCurPos.X()) :       // weiter links
+                            (aTopPos.X() < aCurPos.X()))))      // " reverse
+                {
+                    aTopPos = aCurPos;
+                    pTop = pObj->GetFlyFrm();
+                }
+            }
+            // leider nichts gefunden
+            if( (bNext? (aBestPos.X() == LONG_MAX) : (aBestPos.X() == 0)) )
+                pBest = pTop;
+        }
+
+        if( pBest )
+        {
+            SelectObj( pBest->Frm().Pos(), FALSE, FALSE, (SdrObject*)pBest->GetVirtDrawObj() );
+            if( !ActionPend() )
+                MakeVisible( pBest->Frm() );
+            CallChgLnk();
+            bRet = TRUE;
+        }
+        return bRet;
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::GotoObj()
+|*
+|*  Beschreibung        Wenn ein Obj selektiert ist, gehen wir von dessen
+|*      TopLeft aus, andernfalls von der Mitte des aktuellen CharRects.
+|*  Ersterstellung      MA 01. Jun. 95
+|*  Letzte Aenderung    MA 30. Apr. 96
+|*
+*************************************************************************/
+/* -----------------23.09.98 10:29-------------------
+ * Beinhaltet das Objekt ein Control oder Gruppen,
+ * die nur aus Controls bestehen
+ * --------------------------------------------------*/
+FASTBOOL lcl_IsControlGroup( const SdrObject *pObj )
+{
+    BOOL bRet = FALSE;
+    if(pObj->ISA(SdrUnoObj))
+        bRet = TRUE;
+    else if( pObj->ISA( SdrObjGroup ) )
+    {
+        bRet = TRUE;
+        const SdrObjList *pLst = ((SdrObjGroup*)pObj)->GetSubList();
+        for ( USHORT i = 0; i < pLst->GetObjCount(); ++i )
+            if( !::lcl_IsControlGroup( pLst->GetObj( i ) ) )
+                return FALSE;
+    }
+    return bRet;
+}
+
+
+BOOL SwFEShell::GotoObj( BOOL bNext, DrawObjType eType )
+{
+    if( !Imp()->HasDrawView() )
+        return FALSE;
+    else
+    {
+        const SdrObject *pBest  = 0,
+                        *pTop   = 0;
+
+        const long nTmp = bNext ? LONG_MAX : 0;
+        Point aBestPos( nTmp, nTmp );
+        Point aTopPos(  nTmp, nTmp );
+        Point aCurPos;
+        Point aPos;
+        BOOL  bRet = FALSE;
+
+        const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkList();
+
+        // Ausgangspunkt bestimmen.
+        if ( rMrkList.GetMarkCount() )
+        {
+            SdrObject *pObj = rMrkList.GetMark(0)->GetObj();
+            aPos = pObj->GetSnapRect().TopLeft();
+        }
+        else
+            aPos = GetCharRect().Center();
+
+        SdrPage* pPage = GetDoc()->GetDrawModel()->GetPage( 0 );
+        const ULONG nObjs = pPage->GetObjCount();
+        for( ULONG nObj = 0; nObj < nObjs; ++nObj )
+        {
+            SdrObject *pObj = pPage->GetObj( nObj );
+
+            if ( pObj->IsWriterFlyFrame() ||
+                eType == DRAW_SIMPLE && lcl_IsControlGroup( pObj ) ||
+                    eType == DRAW_CONTROL && !lcl_IsControlGroup( pObj ))
+                continue;
+
+            aCurPos = pObj->GetBoundRect().TopLeft();
+
+            // Sonderfall wenn ein anderes Obj auf selber Y steht.
+            if( aCurPos != aPos &&          // nur wenn ich es nicht selber bin
+                aCurPos.Y() == aPos.Y() &&  // ist die Y Position gleich
+                (bNext? (aCurPos.X() > aPos.X()) :  // liegt neben mir
+                        (aCurPos.X() < aPos.X())) ) // " reverse
+            {
+                aBestPos = Point( nTmp, nTmp );
+                for( ULONG i = 0; i < nObjs; ++i )
+                {
+                    SdrObject *pObj = pPage->GetObj( i );
+                    if ( pObj->IsWriterFlyFrame() )
+                        continue;
+
+                    aCurPos = pObj->GetBoundRect().TopLeft();
+
+                    if( aCurPos != aPos && aCurPos.Y() == aPos.Y() &&
+                        (bNext? (aCurPos.X() > aPos.X()) :  // liegt neben mir
+                                (aCurPos.X() < aPos.X())) &&    // " reverse
+                        (bNext? (aCurPos.X() < aBestPos.X()) :  // besser als Beste
+                                (aCurPos.X() > aBestPos.X())) ) // " reverse
+                    {
+                        aBestPos = aCurPos;
+                        pBest = pObj;
+                    }
+                }
+                break;
+            }
+
+            if( (bNext? (aPos.Y() < aCurPos.Y()) :          // nur unter mir
+                        (aPos.Y() > aCurPos.Y())) &&        // " reverse
+                (bNext? (aBestPos.Y() > aCurPos.Y()) :      // naeher drunter
+                        (aBestPos.Y() < aCurPos.Y())) ||    // " reverse
+                        (aBestPos.Y() == aCurPos.Y() &&
+                (bNext? (aBestPos.X() > aCurPos.X()) :      // weiter links
+                        (aBestPos.X() < aCurPos.X()))))     // " reverse
+
+            {
+                aBestPos = aCurPos;
+                pBest = pObj;
+            }
+
+            if( (bNext? (aTopPos.Y() > aCurPos.Y()) :       // hoeher als Beste
+                        (aTopPos.Y() < aCurPos.Y())) ||     // " reverse
+                        (aTopPos.Y() == aCurPos.Y() &&
+                (bNext? (aTopPos.X() > aCurPos.X()) :       // weiter links
+                        (aTopPos.X() < aCurPos.X()))))      // " reverse
+            {
+                aTopPos = aCurPos;
+                pTop = pObj;
+            }
+        }
+        // leider nichts gefunden
+        if( (bNext? (aBestPos.X() == LONG_MAX) : (aBestPos.X() == 0)) )
+            pBest = pTop;
+
+        if( pBest )
+        {
+            SelectObj( Point(), FALSE, FALSE, (SdrObject*)pBest );
+            if( !ActionPend() )
+                MakeVisible( pBest->GetBoundRect() );
+            CallChgLnk();
+            bRet = TRUE;
+        }
+        return bRet;
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::ControlCount(), GotoControl()
+|*
+|*  Ersterstellung      MA 22. Jul. 96
+|*  Letzte Aenderung    MA 22. Jul. 96
+|*
+*************************************************************************/
+
+ULONG SwFEShell::ControlCount() const
+{
+    INT32 nRet = 0;
+    if ( Imp()->HasDrawView() )
+    {
+        SdrPage* pPage = GetDoc()->GetDrawModel()->GetPage( 0 );
+        const ULONG nObjs = pPage->GetObjCount();
+        for( ULONG nObj = 0; nObj < nObjs; ++nObj )
+        {
+            if ( pPage->GetObj( nObj )->ISA( SdrUnoObj ) )
+                ++nRet;
+        }
+    }
+    return nRet;
+}
+
+BOOL SwFEShell::GotoControl( ULONG nIndex )
+{
+    if ( Imp()->HasDrawView() )
+    {
+        ULONG nIdx = 0;
+        SdrPage* pPage = GetDoc()->GetDrawModel()->GetPage( 0 );
+        const ULONG nObjs = pPage->GetObjCount();
+        for( ULONG nObj = 0; nObj < nObjs; ++nObj )
+        {
+            SdrObject *pObj = pPage->GetObj( nObj );
+            if ( pObj->ISA( SdrUnoObj ) )
+            {
+                if ( nIdx == nIndex )
+                {
+                    SelectObj( Point(), FALSE, FALSE, pObj );
+                    if( !ActionPend() )
+                        MakeVisible( pObj->GetBoundRect() );
+                    CallChgLnk();
+                    return TRUE;
+                }
+                ++nIdx;
+            }
+        }
+    }
+    return FALSE;
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::BeginCreate()
+|*
+|*  Ersterstellung      MA 20. Dec. 94
+|*  Letzte Aenderung    MA 21. Mar. 95
+|*
+*************************************************************************/
+
+BOOL SwFEShell::BeginCreate( UINT16 eSdrObjectKind, const Point &rPos )
+{
+    BOOL bRet = FALSE;
+
+    if ( !Imp()->HasDrawView() )
+        Imp()->MakeDrawView();
+
+    if ( GetPageNumber( rPos ) )
+    {
+        Imp()->GetDrawView()->SetCurrentObj( eSdrObjectKind );
+        if ( eSdrObjectKind == OBJ_CAPTION )
+            bRet = Imp()->GetDrawView()->BegCreateCaptionObj(
+                        rPos, Size( lMinBorder - MINFLY, lMinBorder - MINFLY ),
+                        GetOut() );
+        else
+            bRet = Imp()->GetDrawView()->BegCreateObj( rPos, GetOut() );
+    }
+    if ( bRet )
+        ::FrameNotify( this, FLY_DRAG_START );
+    return bRet;
+}
+
+BOOL SwFEShell::BeginCreate( UINT16 eSdrObjectKind, UINT32 eObjInventor,
+                             const Point &rPos )
+{
+    BOOL bRet = FALSE;
+
+    if ( !Imp()->HasDrawView() )
+        Imp()->MakeDrawView();
+
+    if ( GetPageNumber( rPos ) )
+    {
+        Imp()->GetDrawView()->SetCurrentObj( eSdrObjectKind, eObjInventor );
+        bRet = Imp()->GetDrawView()->BegCreateObj( rPos, GetOut() );
+    }
+    if ( bRet )
+        ::FrameNotify( this, FLY_DRAG_START );
+    return bRet;
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::MoveCreate()
+|*
+|*  Ersterstellung      MA 20. Dec. 94
+|*  Letzte Aenderung    MA 24. Jan. 95
+|*
+*************************************************************************/
+
+void SwFEShell::MoveCreate( const Point &rPos )
+{
+    ASSERT( Imp()->HasDrawView(), "MoveCreate without DrawView?" );
+    if ( GetPageNumber( rPos ) )
+    {
+        Scroll( rPos );
+        Imp()->GetDrawView()->MovCreateObj( rPos );
+        ::FrameNotify( this, FLY_DRAG );
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::EndCreate(), ImpEndCreate()
+|*
+|*  Ersterstellung      MA 20. Dec. 94
+|*  Letzte Aenderung    MA 14. Oct. 96
+|*
+*************************************************************************/
+
+BOOL SwFEShell::EndCreate( UINT16 eSdrCreateCmd )
+{
+    // JP 18.08.95: Damit das Undo-Object aus der DrawEngine nicht bei uns
+    // gespeichert wird, (wir erzeugen ein eigenes Undo-Object!) hier kurz
+    // das Undo abschalten
+    ASSERT( Imp()->HasDrawView(), "EndCreate without DrawView?" );
+    if( !Imp()->GetDrawView()->IsGroupEntered() )
+        GetDoc()->SetNoDrawUndoObj( TRUE );
+    FASTBOOL bCreate = Imp()->GetDrawView()->EndCreateObj(
+                                    SdrCreateCmd( eSdrCreateCmd ) );
+    GetDoc()->SetNoDrawUndoObj( FALSE );
+
+    if ( !bCreate )
+    {
+        ::FrameNotify( this, FLY_DRAG_END );
+        return FALSE;
+    }
+
+    if ( (SdrCreateCmd)eSdrCreateCmd == SDRCREATE_NEXTPOINT )
+    {
+        ::FrameNotify( this, FLY_DRAG );
+        return TRUE;
+    }
+    return ImpEndCreate();
+}
+
+
+BOOL SwFEShell::ImpEndCreate()
+{
+    ASSERT( Imp()->GetDrawView()->GetMarkList().GetMarkCount() == 1,
+            "Neues Object nicht selektiert." );
+
+    SdrObject& rSdrObj = *Imp()->GetDrawView()->GetMarkList().GetMark(0)->GetObj();
+
+    if( rSdrObj.GetSnapRect().IsEmpty() )
+    {
+        //JP 10.04.95: das Object vergessen wir lieber, fuerht nur
+        //              zu Problemen
+        Imp()->GetDrawView()->DeleteMarked();
+        Imp()->GetDrawView()->UnmarkAll();
+        ::FrameNotify( this, FLY_DRAG_END );
+        return FALSE;
+    }
+
+    if( rSdrObj.GetUpGroup() )
+    {
+        Point aTmpPos( rSdrObj.GetRelativePos() + rSdrObj.GetAnchorPos() );
+        Point aNewAnchor( rSdrObj.GetUpGroup()->GetAnchorPos() );
+        rSdrObj.NbcSetRelativePos( aTmpPos - aNewAnchor );
+        rSdrObj.NbcSetAnchorPos( aNewAnchor );
+        // Imp()->GetDrawView()->UnmarkAll();
+        ::FrameNotify( this, FLY_DRAG );
+        return TRUE;
+    }
+
+    StartAllAction();
+
+    Imp()->GetDrawView()->UnmarkAll();
+
+    SwPaM* pCrsr = GetCrsr();
+
+    const Rectangle &rBound = rSdrObj.GetSnapRect();
+    const Point aPt( rBound.TopLeft() );
+
+    //Fremde Identifier sollen in den Default laufen.
+    //Ueberschneidungen sind moeglich!!
+    UINT16 nIdent = SdrInventor == rSdrObj.GetObjInventor()
+                        ? rSdrObj.GetObjIdentifier()
+                        : 0xFFFF;
+
+    //Default fuer Controls ist Zeichengebunden, Absatzgebunden sonst.
+    SwFmtAnchor aAnch;
+    const SwFrm *pAnch = 0;
+    FASTBOOL bCharBound = FALSE;
+    if( rSdrObj.ISA( SdrUnoObj ) )
+    {
+        SwPosition aPos( GetDoc()->GetNodes() );
+        SwCrsrMoveState aState( MV_SETONLYTEXT );
+        Point aPoint( aPt.X(), aPt.Y() + rBound.GetHeight()/2 );
+        GetDoc()->GetRootFrm()->GetCrsrOfst( &aPos, aPoint, &aState );
+
+        //JP 22.01.99: Zeichenbindung ist im ReadnOnly-Inhalt nicht erlaubt
+        if( !aPos.nNode.GetNode().IsProtect() )
+        {
+            pAnch = aPos.nNode.GetNode().GetCntntNode()->GetFrm( &aPoint, &aPos );
+            SwRect aTmp;
+            pAnch->GetCharRect( aTmp, aPos );
+
+            //Der Crsr darf nicht zu weit entfernt sein.
+            bCharBound = TRUE;
+            Rectangle aRect( aTmp.SVRect() );
+            aRect.Left()  -= MM50*2;
+            aRect.Top()   -= MM50*2;
+            aRect.Right() += MM50*2;
+            aRect.Bottom()+= MM50*2;
+
+            if( !aRect.IsOver( rBound ) && !::GetHtmlMode( GetDoc()->GetDocShell() ))
+                bCharBound = FALSE;
+
+                //Bindung in Kopf-/Fusszeilen ist ebenfalls nicht erlaubt.
+            if( bCharBound )
+                bCharBound = !GetDoc()->IsInHeaderFooter( aPos.nNode );
+
+            if( bCharBound )
+            {
+                aAnch.SetType( FLY_IN_CNTNT );
+                aAnch.SetAnchor( &aPos );
+            }
+        }
+    }
+
+    if( !bCharBound )
+    {
+        BOOL bBodyOnly = OBJ_NONE != nIdent, bAtPage = FALSE;
+        const SwFrm *pPage = 0;
+        SwCrsrMoveState aState( MV_SETONLYTEXT );
+        Point aPoint( aPt );
+        SwPosition aPos( GetDoc()->GetNodes() );
+        GetLayout()->GetCrsrOfst( &aPos, aPoint, &aState );
+
+        //JP 22.01.99: nicht in ReadnOnly-Inhalt setzen
+        if( aPos.nNode.GetNode().IsProtect() )
+            // dann darf er nur seitengebunden sein. Oder sollte man
+            // die naechste nicht READONLY Position suchen?
+            bAtPage = TRUE;
+
+        pAnch = aPos.nNode.GetNode().GetCntntNode()->GetFrm( &aPoint, 0, FALSE );
+
+        if( !bAtPage )
+        {
+            const SwFlyFrm *pTmp = pAnch->FindFlyFrm();
+            if( pTmp )
+            {
+                const SwFrm* pTmpFrm = pAnch;
+                SwRect aBound( rBound );
+                while( pTmp )
+                {
+                    if( pTmp->Frm().IsInside( aBound ) )
+                    {
+                        if( !bBodyOnly || !pTmp->FindFooterOrHeader() )
+                            pPage = pTmpFrm;
+                        break;
+                    }
+                    pTmp = pTmp->GetAnchor()
+                                ? pTmp->GetAnchor()->FindFlyFrm()
+                                : 0;
+                    pTmpFrm = pTmp;
+                }
+            }
+
+            if( !pPage )
+                pPage = pAnch->FindPageFrm();
+
+            // immer ueber FindAnchor gehen, damit der Frame immer an den
+            // davorgehen gebunden wird. Beim GetCrsOfst kann man auch zum
+            // nachfolgenden kommen. DAS IST FALSCH
+            pAnch = ::FindAnchor( pPage, aPt, bBodyOnly );
+            aPos.nNode = *((SwCntntFrm*)pAnch)->GetNode();
+
+            //JP 22.01.99: nicht in ReadnOnly-Inhalt setzen
+            if( aPos.nNode.GetNode().IsProtect() )
+                // dann darf er nur seitengebunden sein. Oder sollte man
+                // die naechste nicht READONLY Position suchen?
+                bAtPage = TRUE;
+            else
+            {
+                aAnch.SetType( FLY_AT_CNTNT );
+                aAnch.SetAnchor( &aPos );
+            }
+        }
+
+        if( bAtPage )
+        {
+            pPage = pAnch->FindPageFrm();
+
+            aAnch.SetType( FLY_PAGE );
+            aAnch.SetPageNum( pPage->GetPhyPageNum() );
+            pAnch = pPage;      // die Page wird jetzt zum Anker
+        }
+    }
+
+    SfxItemSet aSet( GetDoc()->GetAttrPool(), RES_FRM_SIZE, RES_FRM_SIZE,
+                                            RES_SURROUND, RES_ANCHOR, 0 );
+    aSet.Put( aAnch );
+
+    if( OBJ_NONE == nIdent )
+    {
+        //Bei OBJ_NONE wird ein Fly eingefuegt.
+        const long nWidth = rBound.Right()  - rBound.Left();
+        const long nHeight= rBound.Bottom() - rBound.Top();
+        aSet.Put( SwFmtFrmSize( ATT_MIN_SIZE, Max( nWidth,  long(MINFLY) ),
+                                              Max( nHeight, long(MINFLY) )));
+
+        SwFmtHoriOrient aHori( rBound.Left() -
+                                pAnch->Frm().Left(), HORI_NONE, FRAME );
+        SwTwips nYOffset = rBound.Top() - pAnch->Frm().Top();
+        if( pAnch->IsTxtFrm() && ((SwTxtFrm*)pAnch)->IsFollow() )
+        {
+            SwTxtFrm* pTmp = (SwTxtFrm*)pAnch;
+            do {
+                pTmp = pTmp->FindMaster();
+                ASSERT( pTmp, "Where's my Master?" );
+                nYOffset += pTmp->Prt().Height();
+            } while ( pTmp->IsFollow() );
+        }
+        SwFmtVertOrient aVert( nYOffset, VERT_NONE, FRAME );
+        aSet.Put( SwFmtSurround( SURROUND_PARALLEL ) );
+        aSet.Put( aHori );
+        aSet.Put( aVert );
+
+        //Schnell noch das Rechteck merken
+        const SwRect aFlyRect( rBound );
+
+        //Erzeugtes Object wegwerfen, so kann der Fly am elegentesten
+        //ueber vorhandene SS erzeugt werden.
+        GetDoc()->SetNoDrawUndoObj( TRUE );         // siehe oben
+        SdrPage *pPg = GetDoc()->MakeDrawModel()->GetPage( 0 );
+        if( !pPg )
+        {
+            pPg = GetDoc()->GetDrawModel()->AllocPage( FALSE );
+            GetDoc()->GetDrawModel()->InsertPage( pPg );
+        }
+        pPg->RecalcObjOrdNums();
+        delete pPg->RemoveObject( rSdrObj.GetOrdNumDirect() );
+        GetDoc()->SetNoDrawUndoObj( FALSE );
+
+        SwFlyFrm* pFlyFrm;
+        if( NewFlyFrm( aSet, TRUE ) &&
+            ::GetHtmlMode( GetDoc()->GetDocShell() ) &&
+            0 != ( pFlyFrm = FindFlyFrm() ))
+        {
+            SfxItemSet aHtmlSet( GetDoc()->GetAttrPool(), RES_VERT_ORIENT, RES_HORI_ORIENT );
+            //Horizontale Ausrichtung:
+            const FASTBOOL bLeftFrm = aFlyRect.Left() <
+                                      pAnch->Frm().Left() + pAnch->Prt().Left(),
+                           bLeftPrt = aFlyRect.Left() + aFlyRect.Width() <
+                                      pAnch->Frm().Left() + pAnch->Prt().Width()/2;
+            if( bLeftFrm || bLeftPrt )
+            {
+                aHori.SetHoriOrient( HORI_LEFT );
+                aHori.SetRelationOrient( bLeftFrm ? FRAME : PRTAREA );
+            }
+            else
+            {
+                const FASTBOOL bRightFrm = aFlyRect.Left() >
+                                           pAnch->Frm().Left() + pAnch->Prt().Width();
+                aHori.SetHoriOrient( HORI_RIGHT );
+                aHori.SetRelationOrient( bRightFrm ? FRAME : PRTAREA );
+            }
+            aHtmlSet.Put( aHori );
+            aVert.SetVertOrient( VERT_TOP );
+            aVert.SetRelationOrient( PRTAREA );
+            aHtmlSet.Put( aVert );
+
+            GetDoc()->SetAttr( aHtmlSet, *pFlyFrm->GetFmt() );
+        }
+    }
+    else
+    {
+        Point aRelNullPt;
+
+        if( OBJ_CAPTION == nIdent )
+            aRelNullPt = ((SdrCaptionObj&)rSdrObj).GetTailPos();
+        else
+            aRelNullPt = rBound.TopLeft();
+
+        aSet.Put( aAnch );
+        aSet.Put( SwFmtSurround( SURROUND_THROUGHT ) );
+        SwDrawFrmFmt* pFmt = (SwDrawFrmFmt*)GetDoc()->MakeLayoutFmt( RND_DRAW_OBJECT, 0, &aSet );
+
+        SwDrawContact *pContact = new SwDrawContact( pFmt, &rSdrObj );
+        if( bCharBound )
+        {
+            ASSERT( aAnch.GetAnchorId() == FLY_IN_CNTNT, "wrong AnchorType" );
+            SwTxtNode *pNd = aAnch.GetCntntAnchor()->nNode.GetNode().GetTxtNode();
+            pNd->Insert( SwFmtFlyCnt( pFmt ),
+                            aAnch.GetCntntAnchor()->nContent.GetIndex(), 0 );
+            SwFmtVertOrient aVert( pFmt->GetVertOrient() );
+            aVert.SetVertOrient( VERT_LINE_CENTER );
+            pFmt->SetAttr( aVert );
+        }
+        if( pAnch->IsTxtFrm() && ((SwTxtFrm*)pAnch)->IsFollow() )
+        {
+            SwTxtFrm* pTmp = (SwTxtFrm*)pAnch;
+            do {
+                pTmp = pTmp->FindMaster();
+                ASSERT( pTmp, "Where's my Master?" );
+            } while( pTmp->IsFollow() );
+            pAnch = pTmp;
+        }
+        rSdrObj.NbcSetRelativePos( aRelNullPt - pAnch->Frm().Pos() );
+        rSdrObj.NbcSetAnchorPos( pAnch->Frm().Pos() );
+        pContact->ConnectToLayout();
+
+        Imp()->GetDrawView()->MarkObj( &rSdrObj, Imp()->GetPageView(),
+                                        FALSE, FALSE );
+    }
+
+    GetDoc()->SetModified();
+
+    KillPams();
+    EndAllActionAndCall();
+    return TRUE;
+}
+
+
+/*************************************************************************
+|*
+|*  SwFEShell::BreakCreate()
+|*
+|*  Ersterstellung      MA 20. Dec. 94
+|*  Letzte Aenderung    MA 09. Jan. 95
+|*
+*************************************************************************/
+
+void SwFEShell::BreakCreate()
+{
+    ASSERT( Imp()->HasDrawView(), "BreakCreate without DrawView?" );
+    Imp()->GetDrawView()->BrkCreateObj();
+    ::FrameNotify( this, FLY_DRAG_END );
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::IsDrawCreate()
+|*
+|*  Ersterstellung      OM 16. Mar. 95
+|*  Letzte Aenderung    OM 16. Mar. 95
+|*
+*************************************************************************/
+
+BOOL SwFEShell::IsDrawCreate() const
+{
+    return Imp()->HasDrawView() ? Imp()->GetDrawView()->IsCreateObj() : FALSE;
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::BeginMark()
+|*
+|*  Ersterstellung      OM 07. Feb. 95
+|*  Letzte Aenderung    OM 07. Feb. 95
+|*
+*************************************************************************/
+
+BOOL SwFEShell::BeginMark( const Point &rPos )
+{
+    if ( !Imp()->HasDrawView() )
+        Imp()->MakeDrawView();
+
+    if ( GetPageNumber( rPos ) )
+    {
+        SwDrawView* pDView = Imp()->GetDrawView();
+
+        if (pDView->HasMarkablePoints())
+            return pDView->BegMarkPoints( rPos, (OutputDevice*) NULL );
+        else
+            return pDView->BegMarkObj( rPos, (OutputDevice*) NULL );
+    }
+    else
+        return FALSE;
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::MoveMark()
+|*
+|*  Ersterstellung      OM 07. Feb. 95
+|*  Letzte Aenderung    OM 07. Feb. 95
+|*
+*************************************************************************/
+
+void SwFEShell::MoveMark( const Point &rPos )
+{
+    ASSERT( Imp()->HasDrawView(), "MoveMark without DrawView?" );
+
+    if ( GetPageNumber( rPos ) )
+    {
+        Scroll( rPos );
+        SwDrawView* pDView = Imp()->GetDrawView();
+//      Imp()->GetDrawView()->MovMarkObj( rPos );
+
+        if (pDView->IsInsObjPoint())
+            pDView->MovInsObjPoint( rPos );
+        else if (pDView->IsMarkPoints())
+            pDView->MovMarkPoints( rPos );
+        else
+            pDView->MovAction( rPos );
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::EndMark()
+|*
+|*  Ersterstellung      OM 07. Feb. 95
+|*  Letzte Aenderung    MA 08. Feb. 95
+|*
+*************************************************************************/
+
+BOOL SwFEShell::EndMark()
+{
+    BOOL bRet = FALSE;
+    ASSERT( Imp()->HasDrawView(), "EndMark without DrawView?" );
+
+    if (Imp()->GetDrawView()->IsMarkObj())
+    {
+        bRet = Imp()->GetDrawView()->EndMarkObj();
+
+        if ( bRet )
+        {
+            BOOL bShowHdl = FALSE;
+            SwDrawView* pDView = Imp()->GetDrawView();
+            //Rahmen werden auf diese Art nicht Selektiert, es sein denn es
+            //ist nur ein Rahmen.
+            SdrMarkList &rMrkList = (SdrMarkList&)pDView->GetMarkList();
+            SwFlyFrm* pOldSelFly = ::GetFlyFromMarked( &rMrkList, this );
+
+            if ( rMrkList.GetMarkCount() > 1 )
+                for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
+                {
+                    SdrObject *pObj = rMrkList.GetMark( i )->GetObj();
+                    if( pObj->IsWriterFlyFrame() )
+                    {
+                        if ( !bShowHdl )
+                        {
+                            pDView->HideMarkHdl( GetOut() );
+                            bShowHdl = TRUE;
+                        }
+                        rMrkList.DeleteMarkNum( i );
+                        --i;    //keinen auslassen.
+                    }
+                }
+
+            if( bShowHdl )
+            {
+                pDView->MarkListHasChanged();
+                pDView->AdjustMarkHdl();
+                pDView->ShowMarkHdl( GetOut() );
+            }
+
+            if ( rMrkList.GetMarkCount() )
+                ::lcl_GrabCursor(this, pOldSelFly);
+            else
+                bRet = FALSE;
+        }
+        if ( bRet )
+            ::FrameNotify( this, FLY_DRAG_START );
+    }
+    else
+    {
+        if (Imp()->GetDrawView()->IsMarkPoints())
+            bRet = Imp()->GetDrawView()->EndMarkPoints();
+    }
+
+    SetChainMarker();
+    return bRet;
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::BreakSelect()
+|*
+|*  Ersterstellung      OM 07. Feb. 95
+|*  Letzte Aenderung    OM 07. Feb. 95
+|*
+*************************************************************************/
+
+void SwFEShell::BreakMark()
+{
+    ASSERT( Imp()->HasDrawView(), "BreakMark without DrawView?" );
+    Imp()->GetDrawView()->BrkMarkObj();
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::GetAnchorId()
+|*
+|*  Ersterstellung      MA 30. Jan. 95
+|*  Letzte Aenderung    MA 30. Jan. 95
+|*
+*************************************************************************/
+
+short SwFEShell::GetAnchorId() const
+{
+    short nRet = SHRT_MAX;
+    if ( Imp()->HasDrawView() )
+    {
+        const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkList();
+        for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
+        {
+            SdrObject *pObj = rMrkList.GetMark( i )->GetObj();
+            if ( pObj->IsWriterFlyFrame() )
+            {
+                nRet = -1;
+                break;
+            }
+            SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj);
+            short nId = pContact->GetFmt()->GetAnchor().GetAnchorId();
+            if ( nRet == SHRT_MAX )
+                nRet = nId;
+            else if ( nRet != nId )
+            {
+                nRet = -1;
+                break;
+            }
+        }
+    }
+    if ( nRet == SHRT_MAX )
+        nRet = -1;
+    return nRet;
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::ChgAnchor()
+|*
+|*  Ersterstellung      MA 10. Jan. 95
+|*  Letzte Aenderung    MA 30. May. 96
+|*
+*************************************************************************/
+
+void SwFEShell::ChgAnchor( int eAnchorId, BOOL bSameOnly, BOOL bPosCorr )
+{
+    ASSERT( Imp()->HasDrawView(), "ChgAnchor without DrawView?" );
+    const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkList();
+    if( rMrkList.GetMarkCount() &&
+        !rMrkList.GetMark( 0 )->GetObj()->GetUpGroup() )
+    {
+        StartAllAction();
+
+        if( GetDoc()->ChgAnchor( rMrkList, eAnchorId, bSameOnly, bPosCorr ))
+            Imp()->GetDrawView()->UnmarkAll();
+
+        EndAllAction();
+
+        ::FrameNotify( this, FLY_DRAG );
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::DelSelectedObj()
+|*
+|*  Ersterstellung      MA 03. Nov. 92
+|*  Letzte Aenderung    MA 14. Nov. 95
+|*
+*************************************************************************/
+
+void SwFEShell::DelSelectedObj()
+{
+    ASSERT( Imp()->HasDrawView(), "DelSelectedObj(), no DrawView available" );
+    if ( Imp()->HasDrawView() )
+    {
+        StartAllAction();
+        Imp()->GetDrawView()->DeleteMarked();
+        EndAllAction();
+        ::FrameNotify( this, FLY_DRAG_END );
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::GetObjSize(), GetAnchorObjDiff()
+|*
+|*  Beschreibung        Fuer die Statuszeile zum Erfragen der aktuellen
+|*                      Verhaeltnisse
+|*  Ersterstellung      MA 25. Apr. 95
+|*  Letzte Aenderung    MA 25. Apr. 95
+|*
+*************************************************************************/
+
+Size SwFEShell::GetObjSize() const
+{
+    Rectangle aRect;
+    if ( Imp()->HasDrawView() )
+    {
+        if ( Imp()->GetDrawView()->IsAction() )
+            Imp()->GetDrawView()->TakeActionRect( aRect );
+        else
+            aRect = Imp()->GetDrawView()->GetAllMarkedRect();
+    }
+    return aRect.GetSize();
+}
+
+Point SwFEShell::GetAnchorObjDiff() const
+{
+    const SdrView *pView = Imp()->GetDrawView();
+    ASSERT( pView, "GetAnchorObjDiff without DrawView?" );
+
+    Rectangle aRect;
+    if ( Imp()->GetDrawView()->IsAction() )
+        Imp()->GetDrawView()->TakeActionRect( aRect );
+    else
+        aRect = Imp()->GetDrawView()->GetAllMarkedRect();
+
+    Point aRet( aRect.TopLeft() );
+
+    if ( IsFrmSelected() )
+    {
+        SwFlyFrm *pFly = FindFlyFrm();
+        aRet -= pFly->GetAnchor()->Frm().Pos();
+    }
+    else
+    {
+        const SdrObject *pObj = pView->GetMarkList().GetMarkCount() == 1 ?
+                                pView->GetMarkList().GetMark(0)->GetObj() : 0;
+        if ( pObj )
+            aRet -= pObj->GetAnchorPos();
+    }
+
+    return aRet;
+}
+
+Point SwFEShell::GetObjAbsPos() const
+{
+    ASSERT( Imp()->GetDrawView(), "GetObjAbsPos() without DrawView?" );
+    return Imp()->GetDrawView()->GetDragStat().GetActionRect().TopLeft();
+}
+
+
+
+/*************************************************************************
+|*
+|*  SwFEShell::IsGroupSelected()
+|*
+|*  Ersterstellung      MA 30. Jan. 95
+|*  Letzte Aenderung    MA 30. May. 96
+|*
+*************************************************************************/
+
+BOOL SwFEShell::IsGroupSelected()
+{
+    if ( IsObjSelected() )
+    {
+        const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkList();
+        for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
+        {
+            SdrObject *pObj = rMrkList.GetMark( i )->GetObj();
+            if ( pObj->IsA( TYPE(SdrObjGroup) ) &&
+                 FLY_IN_CNTNT != ((SwDrawContact*)GetUserCall(pObj))->
+                                        GetFmt()->GetAnchor().GetAnchorId() )
+                return TRUE;
+        }
+    }
+    return FALSE;
+}
+
+BOOL SwFEShell::IsGroupAllowed() const
+{
+    BOOL bRet;
+    if ( IsObjSelected() > 1 )
+    {
+        bRet = TRUE;
+        const SdrObject* pUpGroup;
+        const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkList();
+        for ( USHORT i = 0; bRet && i < rMrkList.GetMarkCount(); ++i )
+        {
+            const SdrObject *pObj = rMrkList.GetMark( i )->GetObj();
+            if( i )
+                bRet = pObj->GetUpGroup() == pUpGroup;
+            else
+                pUpGroup = pObj->GetUpGroup();
+
+            if( FLY_IN_CNTNT == ::FindFrmFmt( (SdrObject*)pObj )->GetAnchor().GetAnchorId() )
+                bRet = FALSE;
+        }
+    }
+    else
+        bRet = FALSE;
+    return bRet;
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::GroupSelection()
+|*
+|*  Beschreibung        Die Gruppe bekommt den Anker und das Contactobjekt
+|*                      des ersten in der Selektion
+|*  Ersterstellung      MA 30. Jan. 95
+|*  Letzte Aenderung    MA 23. Apr. 95
+|*
+*************************************************************************/
+
+void SwFEShell::GroupSelection()
+{
+    if ( IsGroupAllowed() )
+    {
+        StartAllAction();
+        StartUndo( UNDO_START );
+
+        GetDoc()->GroupSelection( *Imp()->GetDrawView() );
+        ChgAnchor( 0, TRUE );
+
+        EndUndo( UNDO_END );
+        EndAllAction();
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::UnGroupSelection()
+|*
+|*  Beschreibung        Die Einzelobjekte bekommen eine Kopie vom Anker und
+|*                      Contactobjekt der Gruppe.
+|*  Ersterstellung      MA 30. Jan. 95
+|*  Letzte Aenderung    MA 01. Feb. 95
+|*
+*************************************************************************/
+
+void SwFEShell::UnGroupSelection()
+{
+    if ( IsGroupSelected() )
+    {
+        StartAllAction();
+        StartUndo( UNDO_START );
+
+        GetDoc()->UnGroupSelection( *Imp()->GetDrawView() );
+        ChgAnchor( 0, TRUE );
+
+        EndUndo( UNDO_END );
+        EndAllAction();
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::MirrorSelection()
+|*
+|*  Ersterstellung      MA 06. Aug. 95
+|*  Letzte Aenderung    MA 06. Aug. 95
+|*
+*************************************************************************/
+
+void SwFEShell::MirrorSelection( BOOL bHorizontal )
+{
+    SdrView *pView = Imp()->GetDrawView();
+    if ( IsObjSelected() && pView->IsMirrorAllowed() )
+    {
+        if ( bHorizontal )
+            pView->MirrorAllMarkedHorizontal();
+        else
+            pView->MirrorAllMarkedVertical();
+    }
+}
+
+// springe zum benannten Rahmen (Grafik/OLE)
+
+BOOL SwFEShell::GotoFly( const String& rName, FlyCntType eType, BOOL bSelFrm )
+{
+    BOOL bRet = FALSE;
+static BYTE __READONLY_DATA aChkArr[ 4 ] = {
+             /* FLYCNTTYPE_ALL */   0,
+             /* FLYCNTTYPE_FRM */   ND_TEXTNODE,
+             /* FLYCNTTYPE_GRF */   ND_GRFNODE,
+             /* FLYCNTTYPE_OLE */   ND_OLENODE
+            };
+
+    const SwFlyFrmFmt* pFlyFmt = pDoc->FindFlyByName( rName, aChkArr[ eType]);
+    if( pFlyFmt )
+    {
+        SET_CURR_SHELL( this );
+
+        SwClientIter aIter( *(SwModify*)pFlyFmt );
+        SwFlyFrm* pFrm = (SwFlyFrm*)aIter.First( TYPE( SwFlyFrm ));
+        if( pFrm )
+        {
+            ASSERT( pFrm->IsFlyFrm(), "Wrong FrmType" );
+            if( bSelFrm )
+            {
+                SelectObj( pFrm->Frm().Pos(), FALSE, FALSE, ((SwFlyFrm*)pFrm)->GetVirtDrawObj() );
+                if( !ActionPend() )
+                    MakeVisible( pFrm->Frm() );
+            }
+            else
+            {
+                pFrm->GetAnchor()->Calc();
+                SwCntntFrm *pCFrm = pFrm->ContainsCntnt();
+                if ( pCFrm )
+                {
+                    SwCntntNode *pCNode = pCFrm->GetNode();
+                    ClearMark();
+                    SwPaM* pCrsr = GetCrsr();
+
+                    pCrsr->GetPoint()->nNode = *pCNode;
+                    pCrsr->GetPoint()->nContent.Assign( pCNode, 0 );
+
+                    SwRect& rChrRect = (SwRect&)GetCharRect();
+                    rChrRect = pFrm->Prt();
+                    rChrRect.Pos() += pFrm->Frm().Pos();
+                    GetCrsrDocPos() = rChrRect.Pos();
+                }
+            }
+            bRet = TRUE;
+        }
+    }
+    return bRet;
+}
+
+USHORT SwFEShell::GetFlyCount(FlyCntType eType ) const
+{
+    return GetDoc()->GetFlyCount(eType);
+}
+
+
+const SwFrmFmt*  SwFEShell::GetFlyNum(USHORT nIdx, FlyCntType eType ) const
+{
+    return GetDoc()->GetFlyNum(nIdx, eType );
+}
+
+// zeige das akt. selektierte "Object" an
+void SwFEShell::MakeSelVisible()
+{
+    if( Imp()->HasDrawView() &&
+        Imp()->GetDrawView()->GetMarkList().GetMarkCount() )
+    {
+        MakeVisible( Imp()->GetDrawView()->GetAllMarkedRect() );
+    }
+    else
+        SwCrsrShell::MakeSelVisible();
+}
+
+
+//Welcher Schutz ist am selektierten Objekt gesetzt?
+BYTE SwFEShell::IsSelObjProtected( FlyProtectType eType ) const
+{
+    int nChk = 0;
+    BOOL bParent = eType & FLYPROTECT_PARENT;
+    if( Imp()->HasDrawView() )
+    {
+        const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkList();
+        for( ULONG i = rMrkList.GetMarkCount(); i; )
+        {
+            SdrObject *pObj = rMrkList.GetMark( --i )->GetObj();
+            if( !bParent )
+            {
+                nChk |= ( pObj->IsMoveProtect() ? FLYPROTECT_POS : 0 ) |
+                        ( pObj->IsResizeProtect()? FLYPROTECT_SIZE : 0 );
+
+                if( FLYPROTECT_CONTENT & eType && pObj->IsWriterFlyFrame() )
+                {
+                    SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+                    if ( pFly->GetFmt()->GetProtect().IsCntntProtected() )
+                        nChk |= FLYPROTECT_CONTENT;
+
+                    if ( pFly->Lower() && pFly->Lower()->IsNoTxtFrm() )
+                    {
+                        SwOLENode *pNd = ((SwCntntFrm*)pFly->Lower())->GetNode()->GetOLENode();
+                        if ( pNd )
+                        {
+                            SvInPlaceObjectRef aRef = pNd->GetOLEObj().GetOleRef();
+                            if ( aRef.Is() &&
+                                 SVOBJ_MISCSTATUS_NOTRESIZEABLE & aRef->GetMiscStatus() )
+                            {
+                                nChk |= FLYPROTECT_SIZE;
+                                nChk |= FLYPROTECT_FIXED;
+                            }
+                        }
+                    }
+                }
+                nChk &= eType;
+                if( nChk == eType )
+                    return eType;
+            }
+            SwFrm* pAnch;
+            if( pObj->IsWriterFlyFrame() )
+                pAnch = ( (SwVirtFlyDrawObj*)pObj )->GetFlyFrm()->GetAnchor();
+            else
+            {
+                SwDrawContact* pTmp = (SwDrawContact*)GetUserCall(pObj);
+                pAnch = pTmp ? pTmp->GetAnchor() : NULL;
+            }
+            if( pAnch && pAnch->IsProtected() )
+                return eType;
+        }
+    }
+    return nChk;
+}
+
+BOOL SwFEShell::GetObjAttr( SfxItemSet &rSet ) const
+{
+    if ( !IsObjSelected() )
+        return FALSE;
+
+    const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkList();
+    for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
+    {
+        SdrObject *pObj = rMrkList.GetMark( i )->GetObj();
+        SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj);
+        if ( i )
+            rSet.MergeValues( pContact->GetFmt()->GetAttrSet() );
+        else
+            rSet.Put( pContact->GetFmt()->GetAttrSet() );
+    }
+    return TRUE;
+}
+
+BOOL SwFEShell::SetObjAttr( const SfxItemSet& rSet )
+{
+    SET_CURR_SHELL( this );
+
+    if ( !rSet.Count() )
+    {   ASSERT( !this, "SetObjAttr, empty set." );
+        return FALSE;
+    }
+
+    StartAllAction();
+    StartUndo( UNDO_INSATTR );
+
+    const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkList();
+    for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
+    {
+        SdrObject *pObj = rMrkList.GetMark( i )->GetObj();
+        SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj);
+        GetDoc()->SetAttr( rSet, *pContact->GetFmt() );
+    }
+
+    EndUndo( UNDO_INSATTR );
+    EndAllActionAndCall();
+    GetDoc()->SetModified();
+    return TRUE;
+}
+
+BOOL SwFEShell::IsAlignPossible() const
+{
+    USHORT nCnt;
+    if ( 0 < (nCnt = IsObjSelected()) )
+    {
+        BOOL bRet = TRUE;
+        if ( nCnt == 1 )
+        {
+            SdrObject *pO = Imp()->GetDrawView()->GetMarkList().GetMark(0)->GetObj();
+            SwDrawContact *pC = (SwDrawContact*)GetUserCall(pO);
+            if (pC->GetFmt()->GetAnchor().GetAnchorId() == FLY_AT_CNTNT)
+                bRet = FALSE;
+            else
+                bRet = pC->GetAnchor() ? pC->GetAnchor()->IsInDocBody() : FALSE;
+        }
+        if ( bRet )
+            return Imp()->GetDrawView()->IsAlignPossible();
+    }
+    return FALSE;
+}
+
+
+//Temporaerer Fix bis SS von JOE da ist
+void SwFEShell::CheckUnboundObjects()
+{
+    SET_CURR_SHELL( this );
+
+    const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkList();
+    for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
+    {
+        SdrObject *pObj = rMrkList.GetMark( i )->GetObj();
+        if ( !GetUserCall(pObj) )
+        {
+            const Rectangle &rBound = pObj->GetSnapRect();
+            const Point aPt( rBound.TopLeft() );
+            const SwFrm *pPage = GetLayout()->Lower();
+            const SwFrm *pLast = pPage;
+            while ( pPage && !pPage->Frm().IsInside( aPt ) )
+            {
+                if ( aPt.Y() > pPage->Frm().Bottom() )
+                    pLast = pPage;
+                pPage = pPage->GetNext();
+            }
+            if ( !pPage )
+                pPage = pLast;
+            ASSERT( pPage, "Page not found." );
+
+            //Fremde Identifier sollen in den Default laufen.
+            //Ueberschneidungen sind moeglich!!
+            UINT16 nIdent =
+                    Imp()->GetDrawView()->GetCurrentObjInventor() == SdrInventor ?
+                            Imp()->GetDrawView()->GetCurrentObjIdentifier() : 0xFFFF;
+
+            SwFmtAnchor aAnch;
+            const SwFrm *pAnch = 0;
+            {
+            pAnch = ::FindAnchor( pPage, aPt, TRUE );
+            SwPosition aPos( *((SwCntntFrm*)pAnch)->GetNode() );
+            aAnch.SetType( FLY_AT_CNTNT );
+            aAnch.SetAnchor( &aPos );
+            ((SwRect&)GetCharRect()).Pos() = aPt;
+            }
+
+            //Erst hier die Action, damit das GetCharRect aktuelle Werte liefert.
+            StartAllAction();
+
+            SfxItemSet aSet( GetAttrPool(), RES_FRM_SIZE, RES_FRM_SIZE,
+                                            RES_SURROUND, RES_ANCHOR, 0 );
+            aSet.Put( aAnch );
+
+            Point aRelNullPt;
+
+            if( OBJ_CAPTION == nIdent )
+                aRelNullPt = ((SdrCaptionObj*)pObj)->GetTailPos();
+            else
+                aRelNullPt = rBound.TopLeft();
+
+            aSet.Put( aAnch );
+            aSet.Put( SwFmtSurround( SURROUND_THROUGHT ) );
+            SwFrmFmt* pFmt = GetDoc()->MakeLayoutFmt(
+                                            RND_DRAW_OBJECT, 0, &aSet );
+
+            SwDrawContact *pContact = new SwDrawContact(
+                                            (SwDrawFrmFmt*)pFmt, pObj );
+            pObj->NbcSetRelativePos( aRelNullPt - pAnch->Frm().Pos() );
+            pObj->NbcSetAnchorPos  ( pAnch->Frm().Pos() );
+            pContact->ConnectToLayout();
+
+            EndAllAction();
+        }
+    }
+}
+
+void SwFEShell::SetCalcFieldValueHdl(Outliner* pOutliner)
+{
+    GetDoc()->SetCalcFieldValueHdl(pOutliner);
+}
+
+
+
+int SwFEShell::Chainable( SwRect &rRect, const SwFrmFmt &rSource,
+                            const Point &rPt ) const
+{
+    rRect.Clear();
+
+    //Die Source darf noch keinen Follow haben.
+    const SwFmtChain &rChain = rSource.GetChain();
+    if ( rChain.GetNext() )
+        return SW_CHAIN_SOURCE_CHAINED;
+
+    if( Imp()->HasDrawView() )
+    {
+        SdrObject* pObj;
+        SdrPageView* pPView;
+        SwDrawView *pDView = (SwDrawView*)Imp()->GetDrawView();
+        const USHORT nOld = pDView->GetHitTolerancePixel();
+        pDView->SetHitTolerancePixel( 0 );
+        if( pDView->PickObj( rPt, pObj, pPView, SDRSEARCH_PICKMARKABLE ) &&
+            pObj->IsWriterFlyFrame() )
+        {
+            SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+            rRect = pFly->Frm();
+
+            //Ziel darf natuerlich nicht gleich Source sein und es
+            //darf keine geschlossene Kette entstehen.
+            SwFrmFmt *pFmt = pFly->GetFmt();
+            return GetDoc()->Chainable(rSource, *pFmt);
+        }
+        pDView->SetHitTolerancePixel( nOld );
+    }
+    return SW_CHAIN_NOT_FOUND;
+}
+
+int SwFEShell::Chain( SwFrmFmt &rSource, const Point &rPt )
+{
+    SwRect aDummy;
+    int nErr = Chainable( aDummy, rSource, rPt );
+    if ( !nErr )
+    {
+        StartAllAction();
+        SdrObject* pObj;
+        SdrPageView* pPView;
+        SwDrawView *pDView = (SwDrawView*)Imp()->GetDrawView();
+        const USHORT nOld = pDView->GetHitTolerancePixel();
+        pDView->SetHitTolerancePixel( 0 );
+        pDView->PickObj( rPt, pObj, pPView, SDRSEARCH_PICKMARKABLE );
+        pDView->SetHitTolerancePixel( nOld );
+        SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+
+        SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)pFly->GetFmt();
+        GetDoc()->Chain(rSource, *pFmt);
+        EndAllAction();
+        SetChainMarker();
+    }
+    return nErr;
+}
+
+void SwFEShell::Unchain( SwFrmFmt &rFmt )
+{
+    StartAllAction();
+    GetDoc()->Unchain(rFmt);
+    EndAllAction();
+}
+
+
+void SwFEShell::HideChainMarker()
+{
+    if ( pChainFrom )
+        pChainFrom->Hide();
+    if ( pChainTo )
+        pChainTo->Hide();
+}
+
+void SwFEShell::SetChainMarker()
+{
+    FASTBOOL bDelFrom = TRUE,
+             bDelTo   = TRUE;
+    if ( IsFrmSelected() )
+    {
+        SwFlyFrm *pFly = FindFlyFrm();
+
+        XPolygon aPoly(3);
+        if ( pFly->GetPrevLink() )
+        {
+            bDelFrom = FALSE;
+            const SwFrm *pPre = pFly->GetPrevLink();
+            aPoly[0] = Point( pPre->Frm().Right(), pPre->Frm().Bottom());
+            aPoly[1] = pFly->Frm().Pos();
+            if ( !pChainFrom )
+                pChainFrom = new SdrViewUserMarker( GetDrawView() );
+            pChainFrom->SetPolyLine( TRUE );
+            pChainFrom->SetXPolygon( aPoly );
+            pChainFrom->Show();
+        }
+        if ( pFly->GetNextLink() )
+        {
+            bDelTo = FALSE;
+            const SwFlyFrm *pNxt = pFly->GetNextLink();
+            aPoly[0] = Point( pFly->Frm().Right(), pFly->Frm().Bottom());
+            aPoly[1] = pNxt->Frm().Pos();
+            if ( !pChainTo )
+                pChainTo = new SdrViewUserMarker( GetDrawView() );
+            pChainTo->SetXPolygon( aPoly );
+            pChainTo->SetPolyLine( TRUE );
+            pChainTo->Show();
+        }
+    }
+    if ( bDelFrom )
+        delete pChainFrom, pChainFrom = 0;
+    if ( bDelTo )
+        delete pChainTo,   pChainTo = 0;
+}
+
+long SwFEShell::GetSectionWidth( SwFmt& rFmt ) const
+{
+    SwFrm *pFrm = GetCurrFrm();
+    // Steht der Cursor z.Z. in einem SectionFrm?
+    if( pFrm && pFrm->IsInSct() )
+    {
+        SwSectionFrm* pSect = pFrm->FindSctFrm();
+        do
+        {
+            // Ist es der Gewuenschte?
+            if( pSect->GetRegisteredIn() == &rFmt )
+                return pSect->Frm().Width();
+            // fuer geschachtelte Bereiche
+            pSect = pSect->GetUpper()->FindSctFrm();
+        }
+        while( pSect );
+    }
+    SwClientIter aIter( rFmt );
+    SwClient *pLast = aIter.GoStart();
+    while ( pLast )
+    {
+        if ( pLast->IsA( TYPE(SwFrm) ) )
+        {
+            SwSectionFrm* pSct = (SwSectionFrm*)pLast;
+            if( !pSct->IsFollow() )
+                return pSct->Frm().Width();
+        }
+        pLast = aIter++;
+    }
+    return 0;
+}
+
+
diff --git a/sw/source/core/frmedt/fetab.cxx b/sw/source/core/frmedt/fetab.cxx
new file mode 100644
index 000000000000..7ee6420af0a7
--- /dev/null
+++ b/sw/source/core/frmedt/fetab.cxx
@@ -0,0 +1,1659 @@
+/*************************************************************************
+ *
+ *  $RCSfile: fetab.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:19 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#define ITEMID_BOXINFO SID_ATTR_BORDER_INNER
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef __RSC //autogen
+#include 
+#endif
+#ifndef _APP_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_SVXIDS_HRC
+#include 
+#endif
+#ifndef _SVX_PROTITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BRSHITEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _RULER_HXX
+#include 
+#endif
+#ifndef _SWWAIT_HXX
+#include 
+#endif
+#ifndef _FMTFSIZE_HXX //autogen
+#include 
+#endif
+#ifndef _FMTORNT_HXX //autogen
+#include 
+#endif
+#ifndef _FRMATR_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _FESH_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _CNTFRM_HXX
+#include 
+#endif
+#ifndef _ROOTFRM_HXX
+#include 
+#endif
+#ifndef _PAGEFRM_HXX
+#include 
+#endif
+#ifndef _TABFRM_HXX
+#include 
+#endif
+#ifndef _CELLFRM_HXX
+#include 
+#endif
+#ifndef _FLYFRM_HXX
+#include 
+#endif
+#ifndef _DFLYOBJ_HXX
+#include 
+#endif
+#ifndef _SWTABLE_HXX
+#include 
+#endif
+#ifndef _SWDDETBL_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _CALC_HXX
+#include 
+#endif
+#ifndef _TABCOL_HXX
+#include 
+#endif
+#ifndef _CELLATR_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _VISCRS_HXX
+#include 
+#endif
+#ifndef _TBLSEL_HXX
+#include 
+#endif
+#ifndef _SWTBLFMT_HXX
+#include 
+#endif
+
+#ifndef _SWSWERROR_H
+#include 
+#endif
+
+
+//siehe auch swtable.cxx
+#define COLFUZZY 20L
+
+inline BOOL IsSame( long nA, long nB ) { return  Abs(nA-nB) <= COLFUZZY; }
+
+SwTabCols *pLastCols   = 0;
+const SwTable   *pLastTable  = 0;
+const SwTabFrm  *pLastTabFrm = 0;
+const SwFrm     *pLastCellFrm = 0;
+
+class TblWait
+{
+    SwWait *pWait;
+public:
+    TblWait( USHORT nCnt, SwFrm *pFrm, SwDocShell &rDocShell, USHORT nCnt2 = 0);
+    ~TblWait() { delete pWait; }
+};
+
+TblWait::TblWait( USHORT nCnt, SwFrm *pFrm, SwDocShell &rDocShell, USHORT nCnt2):
+    pWait( 0 )
+{
+    BOOL bWait = 20 < nCnt || 20 < nCnt2 || (pFrm &&
+                 20 < pFrm->ImplFindTabFrm()->GetTable()->GetTabLines().Count());
+    if( bWait )
+        pWait = new SwWait( rDocShell, TRUE );
+}
+
+inline const SwCursor& GetShellCursor( const SwCrsrShell& rShell )
+{
+    const SwShellCrsr *pCrsr = rShell.GetTableCrsr();
+    if( !pCrsr )
+        pCrsr = (SwShellCrsr*)*rShell.GetSwCrsr( FALSE );
+    return *pCrsr;
+}
+
+/***********************************************************************
+#*  Class      :  SwFEShell
+#*  Methoden   :  GetStartEndCell
+#*  Datum      :  MA 03. May. 93
+#*  Update     :  MA 23. May. 95
+#***********************************************************************/
+void SwFEShell::GetStartEndCell( SwLayoutFrm *&prStart, SwLayoutFrm *&prEnd )
+{
+    SwPaM* pPam = IsTableMode() ? GetTblCrs() : GetCrsr();
+    SwShellCrsr *pICr = (SwShellCrsr*)*((SwCursor*)pPam);
+
+    ASSERT( pICr->GetCntntNode() && pICr->GetCntntNode( FALSE ),
+            "Tabselection nicht auf Cnt." );
+
+    prStart = pICr->GetCntntNode()->GetFrm( &pICr->GetPtPos() )->GetUpper(),
+    prEnd   = pICr->GetCntntNode(FALSE)->GetFrm( &pICr->GetMkPos() )->GetUpper();
+}
+
+/***********************************************************************
+#*  Class      :  SwFEShell
+#*  Methoden   :  InsertRow(), InsertCol
+#*  Datum      :  MA 03. May. 93
+#*  Update     :  MA 19. Apr. 95
+#***********************************************************************/
+BOOL SwFEShell::InsertRow( USHORT nCnt, BOOL bBehind )
+{
+    // pruefe ob vom aktuellen Crsr der Point/Mark in einer Tabelle stehen
+    SwFrm *pFrm = GetCurrFrm();
+    if( !pFrm->IsInTab() )
+        return FALSE;
+
+    if( pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable ))
+    {
+        ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR,
+                        ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
+        return FALSE;
+    }
+
+    SET_CURR_SHELL( this );
+    StartAllAction();
+
+    // lasse ueber das Layout die Boxen suchen
+    SwSelBoxes aBoxes;
+    GetTblSel( *this, aBoxes, TBLSEARCH_ROW );
+
+    TblWait( nCnt, pFrm, *GetDoc()->GetDocShell(), aBoxes.Count() );
+
+    BOOL bRet = FALSE;
+    if ( aBoxes.Count() )
+        bRet = GetDoc()->InsertRow( aBoxes, nCnt, bBehind );
+
+    EndAllActionAndCall();
+    return bRet;
+}
+
+BOOL SwFEShell::InsertCol( USHORT nCnt, BOOL bBehind )
+{
+    // pruefe ob vom aktuellen Crsr der Point/Mark in einer Tabelle stehen
+    SwFrm *pFrm = GetCurrFrm();
+    if( !pFrm->IsInTab() )
+        return FALSE;
+
+    if( pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable ))
+    {
+        ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR,
+                        ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
+        return FALSE;
+    }
+
+    SET_CURR_SHELL( this );
+
+    if( !CheckSplitCells( *this, nCnt + 1, TBLSEARCH_COL ) )
+    {
+        ErrorHandler::HandleError( ERR_TBLINSCOL_ERROR,
+                        ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
+        return FALSE;
+    }
+
+    StartAllAction();
+    // lasse ueber das Layout die Boxen suchen
+    SwSelBoxes aBoxes;
+    GetTblSel( *this, aBoxes, TBLSEARCH_COL );
+
+    TblWait( nCnt, pFrm, *GetDoc()->GetDocShell(), aBoxes.Count() );
+
+    BOOL bRet = FALSE;
+    if( aBoxes.Count() )
+        bRet = GetDoc()->InsertCol( aBoxes, nCnt, bBehind );
+
+    EndAllActionAndCall();
+    return bRet;
+}
+
+/***********************************************************************
+#*  Class      :  SwFEShell
+#*  Methoden   :  DeleteRow(), DeleteCol()
+#*  Datum      :  MA 03. May. 93
+#*  Update     :  MA 19. Apr. 95
+#***********************************************************************/
+BOOL SwFEShell::DeleteCol()
+{
+    // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen
+    SwFrm *pFrm = GetCurrFrm();
+    if( !pFrm->IsInTab() )
+        return FALSE;
+
+    if( pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable ))
+    {
+        ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR,
+                        ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
+        return FALSE;
+    }
+
+    SET_CURR_SHELL( this );
+    StartAllAction();
+
+    // lasse ueber das Layout die Boxen suchen
+    SwSelBoxes aBoxes;
+    GetTblSel( *this, aBoxes, TBLSEARCH_COL );
+
+    TblWait( aBoxes.Count(), pFrm, *GetDoc()->GetDocShell() );
+
+    // die Crsr muessen noch aus dem Loesch Bereich entfernt
+    // werden. Setze sie immer hinter/auf die Tabelle; ueber die
+    // Dokument-Position werden sie dann immer an die alte Position gesetzt.
+    while( !pFrm->IsCellFrm() )
+        pFrm = pFrm->GetUpper();
+    ParkCrsr( SwNodeIndex( *((SwCellFrm*)pFrm)->GetTabBox()->GetSttNd() ));
+
+    // dann loesche doch die Spalten
+    BOOL bRet = GetDoc()->DeleteRowCol( aBoxes );
+
+    EndAllActionAndCall();
+    return bRet;
+}
+
+BOOL SwFEShell::DeleteRow()
+{
+    // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen
+    SwFrm *pFrm = GetCurrFrm();
+    if( !pFrm->IsInTab() )
+        return FALSE;
+
+    if( pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable ))
+    {
+        ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR,
+                        ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
+        return FALSE;
+    }
+
+    SET_CURR_SHELL( this );
+    StartAllAction();
+
+    // lasse ueber das Layout die Boxen suchen
+    SwSelBoxes aBoxes;
+    GetTblSel( *this, aBoxes, TBLSEARCH_ROW );
+
+    TblWait( aBoxes.Count(), pFrm, *GetDoc()->GetDocShell() );
+
+    // die Crsr aus dem Loeschbereich entfernen.
+    // Der Cursor steht danach:
+    //  - es folgt noch eine Zeile, in dieser
+    //  - vorher steht noch eine Zeile, in dieser
+    //  - sonst immer dahinter
+    {
+        SwTableNode* pTblNd = ((SwCntntFrm*)pFrm)->GetNode()->FindTableNode();
+
+        // suche alle Boxen / Lines
+        _FndBox aFndBox( 0, 0 );
+        {
+            _FndPara aPara( aBoxes, &aFndBox );
+            pTblNd->GetTable().GetTabLines().ForEach( &_FndLineCopyCol, &aPara );
+        }
+
+        if( !aFndBox.GetLines().Count() )
+        {
+            EndAllActionAndCall();
+            return FALSE;
+        }
+
+        KillPams();
+
+        _FndBox* pFndBox = &aFndBox;
+        while( 1 == pFndBox->GetLines().Count() &&
+                1 == pFndBox->GetLines()[0]->GetBoxes().Count() )
+        {
+            _FndBox* pTmp = pFndBox->GetLines()[0]->GetBoxes()[0];
+            if( pTmp->GetBox()->GetSttNd() )
+                break;      // das ist sonst zu weit
+            pFndBox = pTmp;
+        }
+
+        SwTableLine* pDelLine = pFndBox->GetLines()[
+                        pFndBox->GetLines().Count()-1 ]->GetLine();
+        SwTableBox* pDelBox = pDelLine->GetTabBoxes()[
+                            pDelLine->GetTabBoxes().Count() - 1 ];
+        while( !pDelBox->GetSttNd() )
+        {
+            SwTableLine* pLn = pDelBox->GetTabLines()[
+                        pDelBox->GetTabLines().Count()-1 ];
+            pDelBox = pLn->GetTabBoxes()[ pLn->GetTabBoxes().Count() - 1 ];
+        }
+        SwTableBox* pNextBox = pDelLine->FindNextBox( pTblNd->GetTable(),
+                                                        pDelBox, TRUE );
+        while( pNextBox &&
+                pNextBox->GetFrmFmt()->GetProtect().IsCntntProtected() )
+            pNextBox = pNextBox->FindNextBox( pTblNd->GetTable(), pNextBox );
+
+        if( !pNextBox )         // keine nachfolgende? dann die vorhergehende
+        {
+            pDelLine = pFndBox->GetLines()[ 0 ]->GetLine();
+            pDelBox = pDelLine->GetTabBoxes()[ 0 ];
+            while( !pDelBox->GetSttNd() )
+                pDelBox = pDelBox->GetTabLines()[0]->GetTabBoxes()[0];
+            pNextBox = pDelLine->FindPreviousBox( pTblNd->GetTable(),
+                                                        pDelBox, TRUE );
+            while( pNextBox &&
+                    pNextBox->GetFrmFmt()->GetProtect().IsCntntProtected() )
+                pNextBox = pNextBox->FindPreviousBox( pTblNd->GetTable(), pNextBox );
+        }
+
+        ULONG nIdx;
+        if( pNextBox )      // dann den Cursor hier hinein
+            nIdx = pNextBox->GetSttIdx() + 1;
+        else                // ansonsten hinter die Tabelle
+            nIdx = pTblNd->EndOfSectionIndex() + 1;
+
+        SwNodeIndex aIdx( GetDoc()->GetNodes(), nIdx );
+        SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
+        if( !pCNd )
+            pCNd = GetDoc()->GetNodes().GoNext( &aIdx );
+
+        if( pCNd )
+        {
+            SwPaM* pPam = GetCrsr();
+            pPam->GetPoint()->nNode = aIdx;
+            pPam->GetPoint()->nContent.Assign( pCNd, 0 );
+            pPam->SetMark();            // beide wollen etwas davon haben
+            pPam->DeleteMark();
+        }
+    }
+
+    // dann loesche doch die Zeilen
+    BOOL bRet = GetDoc()->DeleteRowCol( aBoxes );
+
+    EndAllActionAndCall();
+    return bRet;
+}
+
+/***********************************************************************
+#*  Class      :  SwFEShell
+#*  Methoden   :  MergeTab(), SplitTab()
+#*  Datum      :  MA 03. May. 93
+#*  Update     :  MA 19. Apr. 95
+#***********************************************************************/
+
+USHORT SwFEShell::MergeTab()
+{
+    // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen
+    USHORT nRet = TBLMERGE_NOSELECTION;
+    if( IsTableMode() )
+    {
+        SwShellTableCrsr* pTblCrsr = GetTableCrsr();
+        const SwTableNode* pTblNd = pTblCrsr->GetNode()->FindTableNode();
+        if( pTblNd->GetTable().ISA( SwDDETable ))
+        {
+            ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR,
+                            ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
+        }
+        else
+        {
+            SET_CURR_SHELL( this );
+            StartAllAction();
+
+            TblWait( pTblCrsr->GetBoxesCount(), 0, *GetDoc()->GetDocShell(),
+                     pTblNd->GetTable().GetTabLines().Count() );
+
+            nRet = GetDoc()->MergeTbl( *pTblCrsr );
+
+            KillPams();
+
+            EndAllActionAndCall();
+        }
+    }
+    return nRet;
+}
+
+BOOL SwFEShell::SplitTab( BOOL bVert, USHORT nCnt )
+{
+    // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen
+    SwFrm *pFrm = GetCurrFrm();
+    if( !pFrm->IsInTab() )
+        return FALSE;
+
+    if( pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable ))
+    {
+        ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR,
+                        ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
+        return FALSE;
+    }
+
+    SET_CURR_SHELL( this );
+
+    if( bVert && !CheckSplitCells( *this, nCnt + 1 ) )
+    {
+        ErrorHandler::HandleError( ERR_TBLSPLIT_ERROR,
+                        ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
+        return FALSE;
+    }
+    StartAllAction();
+    // lasse ueber das Layout die Boxen suchen
+    SwSelBoxes aBoxes;
+    GetTblSel( *this, aBoxes );
+
+    TblWait( nCnt, pFrm, *GetDoc()->GetDocShell(), aBoxes.Count() );
+
+    // dann loesche doch die Spalten
+    BOOL bRet = GetDoc()->SplitTbl( aBoxes, bVert, nCnt );
+
+    DELETEZ( pLastCols );
+    EndAllActionAndCall();
+    return bRet;
+}
+
+
+/***********************************************************************
+#*  Class      :  SwFEShell
+#*  Methoden   :  _GetTabCols
+#*  Datum      :  MA 30. Nov. 95
+#*  Update     :  MA 08. Jan. 97
+#***********************************************************************/
+void SwFEShell::_GetTabCols( SwTabCols &rToFill, const SwFrm *pBox ) const
+{
+    const SwTabFrm *pTab = pBox->FindTabFrm();
+    if ( pLastCols )
+    {
+        //Paar Kleinigkeiten muessen wir schon noch sicherstellen
+        FASTBOOL bDel = TRUE;
+        if ( pLastTable == pTab->GetTable() )
+        {
+            bDel = FALSE;
+            if ( pLastTabFrm != pTab )
+            {
+                //Wenn der TabFrm gewechselt hat, brauchen wir bei gleicher
+                //Breite nur ein wenig shiften.
+                if ( pLastTabFrm->Frm().Width() == pTab->Frm().Width() )
+                {
+                    pLastCols->SetLeftMin( (USHORT)pTab->Frm().Left() );
+                    pLastTabFrm = pTab;
+                }
+                else
+                    bDel = TRUE;
+            }
+
+            if ( !bDel &&
+                 pLastCols->GetLeftMin () == (USHORT)pTab->Frm().Left() &&
+                 pLastCols->GetLeft    () == (USHORT)pTab->Prt().Left() &&
+                 pLastCols->GetRight   () == (USHORT)pTab->Prt().Right()&&
+                 pLastCols->GetRightMax() ==
+                        (USHORT)pTab->Frm().Right() - pLastCols->GetLeftMin() )
+            {
+                if ( pLastCellFrm != pBox )
+                {
+                    pTab->GetTable()->GetTabCols( *pLastCols,
+                                        ((SwCellFrm*)pBox)->GetTabBox(), TRUE);
+                    pLastCellFrm = pBox;
+                }
+                rToFill = *pLastCols;
+            }
+            else
+                bDel = TRUE;
+        }
+        if ( bDel )
+            DELETEZ(pLastCols);
+    }
+    if ( !pLastCols )
+    {
+        GetDoc()->GetTabCols( rToFill, 0, (SwCellFrm*)pBox );
+
+        pLastCols   = new SwTabCols( rToFill );
+        pLastTable  = pTab->GetTable();
+        pLastTabFrm = pTab;
+        pLastCellFrm= pBox;
+    }
+}
+
+/***********************************************************************
+#*  Class      :  SwFEShell
+#*  Methoden   :  SetTabCols(), GetTabCols()
+#*  Datum      :  MA 03. May. 93
+#*  Update     :  MA 18. May. 93
+#***********************************************************************/
+void SwFEShell::SetTabCols( const SwTabCols &rNew, BOOL bCurRowOnly )
+{
+    SwFrm *pBox = GetCurrFrm();
+    if( !pBox->IsInTab() )
+        return;
+
+    SET_CURR_SHELL( this );
+    StartAllAction();
+
+    do {
+        pBox = pBox->GetUpper();
+    } while ( !pBox->IsCellFrm() );
+
+    GetDoc()->SetTabCols( rNew, bCurRowOnly, 0, (SwCellFrm*)pBox );
+    EndAllActionAndCall();
+}
+
+void SwFEShell::GetTabCols( SwTabCols &rToFill ) const
+{
+    const SwFrm *pFrm = GetCurrFrm();
+    if( !pFrm->IsInTab() )
+        return;
+    do
+    {   pFrm = pFrm->GetUpper();
+    } while ( !pFrm->IsCellFrm() );
+
+    _GetTabCols( rToFill, pFrm );
+}
+
+/***********************************************************************
+#*  Class      :  SwFEShell
+#*  Methoden   :  SetRowHeight(), GetRowHeight()
+#*  Datum      :  MA 17. May. 93
+#*  Update     :  JP 29.04.98
+#***********************************************************************/
+
+void SwFEShell::SetRowHeight( const SwFmtFrmSize &rNew )
+{
+    SET_CURR_SHELL( this );
+    StartAllAction();
+    GetDoc()->SetRowHeight( GetShellCursor( *this ), rNew );
+    EndAllActionAndCall();
+}
+
+/******************************************************************************
+ *               SwTwips SwFEShell::GetRowHeight() const
+ ******************************************************************************/
+void SwFEShell::GetRowHeight( SwFmtFrmSize *& rpSz ) const
+{
+    GetDoc()->GetRowHeight( GetShellCursor( *this ), rpSz );
+}
+
+BOOL SwFEShell::BalanceRowHeight( BOOL bTstOnly )
+{
+    SET_CURR_SHELL( this );
+    if( !bTstOnly )
+        StartAllAction();
+    BOOL bRet = GetDoc()->BalanceRowHeight( GetShellCursor( *this ), bTstOnly );
+    if( !bTstOnly )
+        EndAllActionAndCall();
+    return bRet;
+}
+
+/******************************************************************************
+ *              void SwFEShell::SetRowBackground()
+ ******************************************************************************/
+void SwFEShell::SetRowBackground( const SvxBrushItem &rNew )
+{
+    SET_CURR_SHELL( this );
+    StartAllAction();
+    GetDoc()->SetRowBackground( GetShellCursor( *this ), rNew );
+    EndAllActionAndCall();
+}
+
+/******************************************************************************
+ *               SwTwips SwFEShell::GetRowBackground() const
+ ******************************************************************************/
+BOOL SwFEShell::GetRowBackground( SvxBrushItem &rToFill ) const
+{
+    return GetDoc()->GetRowBackground( GetShellCursor( *this ), rToFill );
+}
+
+/***********************************************************************
+#*  Class      :  SwFEShell
+#*  Methoden   :  SetTabBorders(), GetTabBorders()
+#*  Datum      :  MA 18. May. 93
+#*  Update     :  JP 29.04.98
+#***********************************************************************/
+
+void SwFEShell::SetTabBorders( const SfxItemSet& rSet )
+{
+    SET_CURR_SHELL( this );
+    StartAllAction();
+    GetDoc()->SetTabBorders( GetShellCursor( *this ), rSet );
+    EndAllActionAndCall();
+}
+
+void SwFEShell::SetTabLineStyle( const Color* pColor, BOOL bSetLine,
+                                 const SvxBorderLine* pBorderLine )
+{
+    SET_CURR_SHELL( this );
+    StartAllAction();
+    GetDoc()->SetTabLineStyle( GetShellCursor( *this ),
+                                pColor, bSetLine, pBorderLine );
+    EndAllActionAndCall();
+}
+
+void SwFEShell::GetTabBorders( SfxItemSet& rSet ) const
+{
+    GetDoc()->GetTabBorders( GetShellCursor( *this ), rSet );
+}
+
+
+/***********************************************************************
+#*  Class      :  SwFEShell
+#*  Methoden   :  SetBoxBackground(), GetBoxBackground()
+#*  Datum      :  MA 01. Jun. 93
+#*  Update     :  MA 03. Jul. 96
+#***********************************************************************/
+void SwFEShell::SetBoxBackground( const SvxBrushItem &rNew )
+{
+    SET_CURR_SHELL( this );
+    StartAllAction();
+    GetDoc()->SetBoxAttr( GetShellCursor( *this ), rNew );
+    EndAllActionAndCall();
+}
+
+BOOL SwFEShell::GetBoxBackground( SvxBrushItem &rToFill ) const
+{
+    return GetDoc()->GetBoxBackground( GetShellCursor( *this ), rToFill );
+}
+
+/***********************************************************************
+#*  Class      :  SwFEShell
+#*  Methoden   :  SetBoxAlign, SetBoxAlign
+#*  Datum      :  MA 18. Dec. 96
+#*  Update     :  JP 29.04.98
+#***********************************************************************/
+void SwFEShell::SetBoxAlign( USHORT nAlign )
+{
+    SET_CURR_SHELL( this );
+    StartAllAction();
+    GetDoc()->SetBoxAlign( GetShellCursor( *this ), nAlign );
+    EndAllActionAndCall();
+}
+
+USHORT SwFEShell::GetBoxAlign() const
+{
+    return GetDoc()->GetBoxAlign( GetShellCursor( *this ) );
+}
+
+/***********************************************************************
+#*  Class      :  SwFEShell
+#*  Methoden   :  SetTabBackground(), GetTabBackground()
+#*  Datum      :  MA 08. Jul. 96
+#*  Update     :  MA 08. Jul. 96
+#***********************************************************************/
+void SwFEShell::SetTabBackground( const SvxBrushItem &rNew )
+{
+    SwFrm *pFrm = GetCurrFrm();
+    if( !pFrm->IsInTab() )
+        return;
+
+    SET_CURR_SHELL( this );
+    StartAllAction();
+    GetDoc()->SetAttr( rNew, *pFrm->ImplFindTabFrm()->GetFmt() );
+    EndAllAction(); //Kein Call, denn es veraendert sich nichts!
+    GetDoc()->SetModified();
+}
+
+void SwFEShell::GetTabBackground( SvxBrushItem &rToFill ) const
+{
+    SwFrm *pFrm = GetCurrFrm();
+    if( pFrm->IsInTab() )
+        rToFill = pFrm->ImplFindTabFrm()->GetFmt()->GetBackground();
+}
+
+
+/***********************************************************************
+#*  Class      :  SwFEShell
+#*  Methoden   :  HasWholeTabSelection()
+#*  Datum      :  MA 18. May. 93
+#*  Update     :  MA 20. Jul. 93
+#***********************************************************************/
+BOOL SwFEShell::HasWholeTabSelection() const
+{
+    //Ist die ganze Tabelle Selektiert?
+    if ( IsTableMode() )
+    {
+        SwSelBoxes aBoxes;
+        ::GetTblSelCrs( *this, aBoxes );
+        const SwTableNode *pTblNd = IsCrsrInTbl();
+
+        return ( aBoxes[0]->GetSttIdx()-1 == pTblNd->
+            EndOfSectionNode()->StartOfSectionIndex() &&
+            aBoxes[aBoxes.Count()-1]->GetSttNd()->EndOfSectionIndex()+1
+            ==  pTblNd->EndOfSectionIndex() );
+    }
+    return FALSE;
+}
+
+BOOL SwFEShell::HasBoxSelection() const
+{
+    if(!IsCrsrInTbl())
+        return FALSE;
+    //Ist die ganze Tabelle Selektiert?
+    if( IsTableMode() )
+        return TRUE;
+    SwPaM* pPam = GetCrsr();
+        // leere Boxen gelten auch ohne Selektion als selektiert
+//  if( !pPam->HasMark() )
+//      return FALSE;
+    BOOL bChg = FALSE;
+    if( pPam->GetPoint() == pPam->End())
+    {
+        bChg = TRUE;
+        pPam->Exchange();
+    }
+    SwNode* pNd;
+    if( pPam->GetPoint()->nNode.GetIndex() -1 ==
+        ( pNd = pPam->GetNode())->StartOfSectionIndex() &&
+        !pPam->GetPoint()->nContent.GetIndex() &&
+        pPam->GetMark()->nNode.GetIndex() + 1 ==
+        pNd->EndOfSectionIndex())
+    {
+            SwNodeIndex aIdx( *pNd->EndOfSectionNode(), -1 );
+            SwCntntNode* pCNd = GetDoc()->GetNodes()[ aIdx ]->GetCntntNode();
+            if( !pCNd )
+            {
+                pCNd = GetDoc()->GetNodes().GoPrevious( &aIdx );
+                ASSERT( pCNd, "kein ContentNode in der Box ??" );
+            }
+            if( pPam->GetMark()->nContent == pCNd->Len() )
+            {
+                if( bChg )
+                    pPam->Exchange();
+                return TRUE;
+            }
+    }
+    if( bChg )
+        pPam->Exchange();
+    return FALSE;
+}
+
+/***********************************************************************
+#*  Class      :  SwFEShell
+#*  Methoden   :  ProtectCells(), UnProtectCells()
+#*  Datum      :  MA 20. Jul. 93
+#*  Update     :  JP 25. Sep. 93
+#***********************************************************************/
+void SwFEShell::ProtectCells()
+{
+    SvxProtectItem aProt;
+    aProt.SetCntntProtect( TRUE );
+
+    SET_CURR_SHELL( this );
+    StartAllAction();
+
+    GetDoc()->SetBoxAttr( GetShellCursor( *this ), aProt );
+
+    if( !IsCrsrReadonly() )
+    {
+        if( IsTableMode() )
+            ClearMark();
+        ParkCrsr( GetCrsr()->GetPoint()->nNode );
+    }
+    EndAllActionAndCall();
+}
+
+void SwFEShell::UnProtectCells( const String& rTblName )
+{
+    SET_CURR_SHELL( this );
+    StartAllAction();
+    GetDoc()->UnProtectCells( rTblName );
+    EndAllActionAndCall();
+}
+
+// die Tabellenselektion aufheben
+void SwFEShell::UnProtectCells()
+{
+    SET_CURR_SHELL( this );
+    StartAllAction();
+
+    SwSelBoxes aBoxes;
+    if( IsTableMode() )
+        ::GetTblSelCrs( *this, aBoxes );
+    else
+    {
+        SwFrm *pFrm = GetCurrFrm();
+        do {
+            pFrm = pFrm->GetUpper();
+        } while ( pFrm && !pFrm->IsCellFrm() );
+        if( pFrm )
+        {
+            SwTableBox *pBox = (SwTableBox*)((SwCellFrm*)pFrm)->GetTabBox();
+            aBoxes.Insert( pBox );
+        }
+    }
+
+    GetDoc()->UnProtectCells( aBoxes );
+
+    EndAllActionAndCall();
+}
+
+void SwFEShell::UnProtectTbls()
+{
+    SET_CURR_SHELL( this );
+    StartAllAction();
+    GetDoc()->UnProtectTbls( *GetCrsr() );
+    EndAllActionAndCall();
+}
+
+BOOL SwFEShell::HasTblAnyProtection( const String* pTblName,
+                                    BOOL* pFullTblProtection )
+{
+    return GetDoc()->HasTblAnyProtection( GetCrsr()->GetPoint(), pTblName,
+                                        pFullTblProtection );
+}
+
+/***********************************************************************
+#*  Class      :  SwFEShell
+#*  Methoden   :  IsHeadlineRepeat(), SetHeadlineRepeat()
+#*  Datum      :  MA 02. Feb. 94
+#*  Update     :  MA 27. Jul. 95
+#***********************************************************************/
+BOOL SwFEShell::IsHeadlineRepeat() const
+{
+    const SwFrm *pFrm = GetCurrFrm();
+    const SwTabFrm *pTab = pFrm->FindTabFrm();
+    if( pTab )
+        return pTab->GetTable()->IsHeadlineRepeat();
+    return FALSE;
+}
+
+void SwFEShell::SetHeadlineRepeat( BOOL bSet )
+{
+    SwFrm    *pFrm = GetCurrFrm();
+    SwTabFrm *pTab = pFrm->FindTabFrm();
+    if( pTab && pTab->GetTable()->IsHeadlineRepeat() != bSet )
+    {
+        SwWait aWait( *GetDoc()->GetDocShell(), TRUE );
+        SET_CURR_SHELL( this );
+        StartAllAction();
+        GetDoc()->SetHeadlineRepeat( *pTab->GetTable(), bSet );
+        EndAllActionAndCall();
+    }
+}
+
+BOOL SwFEShell::IsInHeadline() const
+{
+    BOOL bRet = FALSE;
+    if ( !IsTableMode() )
+    {
+        SwFrm *pFrm = GetCurrFrm();
+        if ( pFrm->IsInTab() && ((SwLayoutFrm*)pFrm->FindTabFrm()->Lower())->IsAnLower( pFrm))
+            bRet = TRUE;
+    }
+    return bRet;
+}
+
+BOOL SwFEShell::IsInRepeatedHeadline() const
+{
+    BOOL bRet = FALSE;
+    if ( !IsTableMode() )
+    {
+        SwFrm *pFrm = GetCurrFrm();
+        if ( pFrm->IsInTab() )
+        {
+            SwTabFrm *pTab = pFrm->FindTabFrm();
+            if ( pTab->IsFollow() && pTab->GetTable()->IsHeadlineRepeat() &&
+                 ((SwLayoutFrm*)pTab->Lower())->IsAnLower( pFrm ) )
+            {
+                bRet = TRUE;
+            }
+        }
+    }
+    return bRet;
+}
+
+/***********************************************************************
+#*  Class      :  SwFEShell
+#*  Methoden   :  AdjustCellWidth()
+#*  Datum      :  MA 20. Feb. 95
+#*  Update     :  MA 27. Jul. 95
+#***********************************************************************/
+
+void SwFEShell::AdjustCellWidth( BOOL bBalance )
+{
+    SET_CURR_SHELL( this );
+    StartAllAction();
+
+    //WarteCrsr immer einschalten, weil sich im vorraus nicht so recht
+    //ermitteln laesst wieviel Inhalt betroffen ist.
+    TblWait aWait( USHRT_MAX, 0, *GetDoc()->GetDocShell() );
+
+    GetDoc()->AdjustCellWidth( GetShellCursor( *this ), bBalance );
+    EndAllActionAndCall();
+}
+
+BOOL SwFEShell::IsAdjustCellWidthAllowed( BOOL bBalance ) const
+{
+    //Es muss mindestens eine Zelle mit Inhalt in der Selektion enthalten
+    //sein.
+
+    SwFrm *pFrm = GetCurrFrm();
+    if( !pFrm->IsInTab() )
+        return FALSE;
+
+    SwSelBoxes aBoxes;
+    ::GetTblSelCrs( *this, aBoxes );
+
+    if ( bBalance )
+        return aBoxes.Count() > 1;
+
+    if ( !aBoxes.Count() )
+    {
+        do
+        {   pFrm = pFrm->GetUpper();
+        } while ( !pFrm->IsCellFrm() );
+        SwTableBox *pBox = (SwTableBox*)((SwCellFrm*)pFrm)->GetTabBox();
+        aBoxes.Insert( pBox );
+    }
+
+    for ( USHORT i = 0; i < aBoxes.Count(); ++i )
+    {
+        SwTableBox *pBox = aBoxes[i];
+        if ( pBox->GetSttNd() )
+        {
+            SwNodeIndex aIdx( *pBox->GetSttNd(), 1 );
+            SwTxtNode* pCNd = aIdx.GetNode().GetTxtNode();
+            if( !pCNd )
+                pCNd = (SwTxtNode*)GetDoc()->GetNodes().GoNext( &aIdx );
+
+            while ( pCNd )
+            {
+                if ( pCNd->GetTxt().Len() )
+                    return TRUE;
+                ++aIdx;
+                pCNd = GetDoc()->GetNodes()[ aIdx ]->GetTxtNode();
+            }
+        }
+    }
+    return FALSE;
+}
+
+    // AutoFormat fuer die Tabelle/TabellenSelection
+BOOL SwFEShell::SetTableAutoFmt( const SwTableAutoFmt& rNew )
+{
+    SwTableNode *pTblNd = (SwTableNode*)IsCrsrInTbl();
+    if( !pTblNd || pTblNd->GetTable().IsTblComplex() )
+        return FALSE;
+
+    SwSelBoxes aBoxes;
+
+    if ( !IsTableMode() )       // falls Crsr noch nicht akt. sind
+        GetCrsr();
+
+    // gesamte Tabelle oder nur auf die akt. Selektion
+    if( IsTableMode() )
+        ::GetTblSelCrs( *this, aBoxes );
+    else
+    {
+        const SwTableSortBoxes& rTBoxes = pTblNd->GetTable().GetTabSortBoxes();
+        for( USHORT n = 0; n < rTBoxes.Count(); ++n )
+        {
+            SwTableBox* pBox = rTBoxes[ n ];
+            aBoxes.Insert( pBox );
+        }
+    }
+
+    SET_CURR_SHELL( this );
+    StartAllAction();
+    BOOL bRet = GetDoc()->SetTableAutoFmt( aBoxes, rNew );
+    DELETEZ( pLastCols );
+    EndAllActionAndCall();
+
+    return bRet;
+}
+
+BOOL SwFEShell::GetTableAutoFmt( SwTableAutoFmt& rGet )
+{
+    const SwTableNode *pTblNd = IsCrsrInTbl();
+    if( !pTblNd || pTblNd->GetTable().IsTblComplex() )
+        return FALSE;
+
+    SwSelBoxes aBoxes;
+
+    if ( !IsTableMode() )       // falls Crsr noch nicht akt. sind
+        GetCrsr();
+
+    // gesamte Tabelle oder nur auf die akt. Selektion
+    if( IsTableMode() )
+        ::GetTblSelCrs( *this, aBoxes );
+    else
+    {
+        const SwTableSortBoxes& rTBoxes = pTblNd->GetTable().GetTabSortBoxes();
+        for( USHORT n = 0; n < rTBoxes.Count(); ++n )
+        {
+            SwTableBox* pBox = rTBoxes[ n ];
+            aBoxes.Insert( pBox );
+        }
+    }
+
+    return GetDoc()->GetTableAutoFmt( aBoxes, rGet );
+}
+
+/***********************************************************************
+#*  Class      :  SwFEShell
+#*  Methoden   :  DeleteTblSel()
+#*  Datum      :  MA 03. May. 93
+#*  Update     :  MA 19. Apr. 95
+#***********************************************************************/
+BOOL SwFEShell::DeleteTblSel()
+{
+    // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen
+    SwFrm *pFrm = GetCurrFrm();
+    if( !pFrm->IsInTab() )
+        return FALSE;
+
+    if( pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable ))
+    {
+        ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR,
+                        ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
+        return FALSE;
+    }
+
+    SET_CURR_SHELL( this );
+    StartAllAction();
+
+    // lasse ueber das Layout die Boxen suchen
+    SwSelBoxes aBoxes;
+    GetTblSelCrs( *this, aBoxes );
+
+    TblWait( aBoxes.Count(), pFrm, *GetDoc()->GetDocShell() );
+
+    // die Crsr muessen noch aus dem Loesch Bereich entfernt
+    // werden. Setze sie immer hinter/auf die Tabelle; ueber die
+    // Dokument-Position werden sie dann immer an die alte Position gesetzt.
+    while( !pFrm->IsCellFrm() )
+        pFrm = pFrm->GetUpper();
+    ParkCrsr( SwNodeIndex( *((SwCellFrm*)pFrm)->GetTabBox()->GetSttNd() ));
+
+    BOOL bRet = GetDoc()->DeleteRowCol( aBoxes );
+
+    DELETEZ( pLastCols );
+    EndAllActionAndCall();
+    return bRet;
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::GetCurTabColNum()
+|*
+|*  Ersterstellung      MA 03. Feb. 95
+|*  Letzte Aenderung    MA 21. May. 95
+|
+|*************************************************************************/
+USHORT SwFEShell::GetCurTabColNum() const
+{
+    //!!!GetCurMouseTabColNum() mitpflegen!!!!
+    USHORT nRet = 0;
+
+    SwFrm *pFrm = GetCurrFrm();
+    ASSERT( pFrm, "Crsr geparkt?" );
+
+    // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen
+    if( pFrm->IsInTab() )
+    {
+        do {            // JP 26.09.95: warum mit dem CntntFrame und nicht mit
+                        //              dem CellFrame vergleichen????
+            pFrm = pFrm->GetUpper();
+        } while ( !pFrm->IsCellFrm() );
+        const long nX = pFrm->Frm().Left();
+
+        //TabCols besorgen, den nur ueber diese erreichen wir die Position.
+        SwTabCols aTabCols;
+        GetTabCols( aTabCols );
+
+        const long nLeft = aTabCols.GetLeftMin();
+
+        if ( !::IsSame( nX, nLeft + aTabCols.GetLeft() ) )
+        {
+            for ( USHORT i = 0; i < aTabCols.Count(); ++i )
+                if ( ::IsSame( nX, nLeft + aTabCols[i] ) )
+                {
+                    nRet = i + 1;
+                    break;
+                }
+        }
+    }
+    return nRet;
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::GetBox()
+|*
+|*  Ersterstellung      MA 22. Jun. 95
+|*  Letzte Aenderung    MA 21. Nov. 96
+|*
+|*************************************************************************/
+
+const SwFrm *lcl_FindFrmInTab( const SwLayoutFrm *pLay, const Point &rPt, SwTwips nFuzzy )
+{
+    const SwFrm *pFrm = pLay->Lower();
+    do
+    {   if ( pFrm->Frm().IsNear( rPt, nFuzzy ) )
+        {
+            if ( pFrm->IsCellFrm() && ( !((SwCellFrm*)pFrm)->Lower()->IsLayoutFrm() ||
+                ((SwCellFrm*)pFrm)->Lower()->IsSctFrm() ) )
+                return pFrm;
+            if ( pFrm->IsLayoutFrm() )
+            {
+                const SwFrm *pTmp = ::lcl_FindFrmInTab( (SwLayoutFrm*)pFrm, rPt, nFuzzy);
+                if ( pTmp )
+                    return pTmp;
+            }
+            break;
+        }
+        pFrm = pFrm->FindNext();
+    } while ( pFrm && pLay->IsAnLower( pFrm ) );
+
+    return 0;
+}
+
+const SwFrm *lcl_FindFrm( const SwLayoutFrm *pLay, const Point &rPt, SwTwips nFuzzy )
+{
+    const SwFrm *pFrm = pLay->ContainsCntnt();
+    if ( pFrm )
+    {
+        do
+        {
+            if ( pFrm->IsInTab() )
+                pFrm = ((SwFrm*)pFrm)->ImplFindTabFrm();
+            if ( pFrm->IsTabFrm() )
+            {
+                const SwFrm *pTmp = ::lcl_FindFrmInTab( (SwLayoutFrm*)pFrm, rPt, nFuzzy );
+                if ( pTmp )
+                {
+                    pFrm = pTmp;
+                    break;
+                }
+            }
+            pFrm = pFrm->FindNextCnt();
+
+        } while ( pFrm && pLay->IsAnLower( pFrm ) );
+    }
+    if ( pFrm && pFrm->IsInTab() && pLay->IsAnLower( pFrm ) )
+    {
+        do
+        {   while ( pFrm && !pFrm->IsCellFrm() )
+                pFrm = pFrm->GetUpper();
+            if ( pFrm )
+            {
+                if ( ::IsSame(pFrm->Frm().Left(), rPt.X()) ||
+                     ::IsSame(pFrm->Frm().Right(),rPt.X()) )
+                {
+                    return pFrm;
+                }
+                pFrm = pFrm->GetUpper();
+            }
+        } while ( pFrm );
+    }
+    return 0;
+}
+
+const SwFrm *SwFEShell::GetBox( const Point &rPt ) const
+{
+    const SwPageFrm *pPage = (SwPageFrm*)GetLayout()->Lower();
+    Window* pOutWin = GetWin();
+    SwTwips nFuzzy = COLFUZZY;
+    if(pOutWin)
+    {
+        Size aTmp(RULER_MOUSE_MARGINWIDTH, RULER_MOUSE_MARGINWIDTH);
+        aTmp = pOutWin->PixelToLogic(aTmp);
+        nFuzzy = aTmp.Width();
+    }
+    while ( pPage && !pPage->Frm().IsNear( rPt, nFuzzy ) )
+        pPage = (SwPageFrm*)pPage->GetNext();
+
+    const SwFrm *pFrm = 0;
+    if ( pPage )
+    {
+        //Per GetCrsrOfst oder GetCntntPos koennen wir hier die Box leider
+        //nicht suchen. Das wuerde zu einem Performance-Zusammenbruch bei
+        //Dokumenten mit vielen Absaetzen/Tabellen auf einer Seite fuehren
+        //(BrowseMode!)
+
+        //Erst die Flys checken.
+        if ( pPage->GetSortedObjs() )
+        {
+            for ( USHORT i = 0; !pFrm && i < pPage->GetSortedObjs()->Count(); ++i )
+            {
+                const SdrObject *pObj = (*pPage->GetSortedObjs())[i];
+                if ( pObj->IsWriterFlyFrame() )
+                {
+                    pFrm = lcl_FindFrm( ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm(),
+                                        rPt, nFuzzy );
+                }
+            }
+        }
+        const SwLayoutFrm *pLay = (SwLayoutFrm*)pPage->Lower();
+        while ( pLay && !pFrm )
+        {
+            pFrm = lcl_FindFrm( pLay, rPt, nFuzzy );
+            pLay = (SwLayoutFrm*)pLay->GetNext();
+        }
+    }
+    return pFrm;
+}
+
+
+/*************************************************************************
+|*
+|*  SwFEShell::IsMouseTabCol()
+|*
+|*  Ersterstellung      MA 22. Jun. 95
+|*  Letzte Aenderung    MA 22. Jun. 95
+|
+|*************************************************************************/
+BOOL SwFEShell::IsMouseTabCol( const Point &rPt ) const
+{
+    SwCellFrm* pFrm = (SwCellFrm*)GetBox( rPt );
+    if( pFrm )
+    {
+        while( pFrm->Lower()->IsRowFrm() )
+            pFrm = (SwCellFrm*)((SwLayoutFrm*)pFrm->Lower())->Lower();
+        if( pFrm && pFrm->GetTabBox()->GetSttNd() &&
+            pFrm->GetTabBox()->GetSttNd()->IsInProtectSect() )
+            pFrm = 0;
+    }
+    return 0 != pFrm;
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::GetMouseTabCols()
+|*
+|*  Ersterstellung      MA 22. Jun. 95
+|*  Letzte Aenderung    MA 27. Aug. 96
+|
+|*************************************************************************/
+void SwFEShell::GetMouseTabCols( SwTabCols &rToFill, const Point &rPt ) const
+{
+    const SwFrm *pBox = GetBox( rPt );
+    if ( pBox )
+        _GetTabCols( rToFill, pBox );
+}
+
+void SwFEShell::SetMouseTabCols( const SwTabCols &rNew, BOOL bCurRowOnly,
+                                 const Point &rPt )
+{
+    const SwFrm *pBox = GetBox( rPt );
+    if( pBox )
+    {
+        SET_CURR_SHELL( this );
+        StartAllAction();
+        GetDoc()->SetTabCols( rNew, bCurRowOnly, 0, (SwCellFrm*)pBox );
+        EndAllActionAndCall();
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::GetMouseColNum(), GetMouseTabColNum()
+|*
+|*  Ersterstellung      MA 04. Jul. 95
+|*  Letzte Aenderung    MA 04. Jul. 95
+|
+|*************************************************************************/
+USHORT SwFEShell::GetCurMouseColNum( const Point &rPt,
+                                    SwGetCurColNumPara* pPara ) const
+{
+    return _GetCurColNum( GetBox( rPt ), pPara );
+}
+
+USHORT SwFEShell::GetCurMouseTabColNum( const Point &rPt ) const
+{
+    //!!!GetCurTabColNum() mitpflegen!!!!
+    USHORT nRet = 0;
+
+    const SwFrm *pFrm = GetBox( rPt );
+    ASSERT( pFrm, "Table not found" );
+    if( pFrm )
+    {
+        const long nX = pFrm->Frm().Left();
+
+        //TabCols besorgen, den nur ueber diese erreichen wir die Position.
+        SwTabCols aTabCols;
+        GetMouseTabCols( aTabCols, rPt );
+
+        const long nLeft = aTabCols.GetLeftMin();
+
+        if ( !::IsSame( nX, nLeft + aTabCols.GetLeft() ) )
+        {
+            for ( USHORT i = 0; i < aTabCols.Count(); ++i )
+                if ( ::IsSame( nX, nLeft + aTabCols[i] ) )
+                {
+                    nRet = i + 1;
+                    break;
+                }
+        }
+    }
+    return nRet;
+}
+
+void ClearFEShellTabCols()
+{
+    DELETEZ( pLastCols );
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::GetTblAttr(), SetTblAttr()
+|*
+|*  Ersterstellung      MA 09. Dec. 96
+|*  Letzte Aenderung    MA 09. Dec. 96
+|
+|*************************************************************************/
+void SwFEShell::GetTblAttr( SfxItemSet &rSet ) const
+{
+    SwFrm *pFrm = GetCurrFrm();
+    if( pFrm->IsInTab() )
+        rSet.Put( pFrm->ImplFindTabFrm()->GetFmt()->GetAttrSet() );
+}
+
+void SwFEShell::SetTblAttr( const SfxItemSet &rNew )
+{
+    SwFrm *pFrm = GetCurrFrm();
+    if( pFrm->IsInTab() )
+    {
+        SET_CURR_SHELL( this );
+        StartAllAction();
+        SwTabFrm *pTab = pFrm->FindTabFrm();
+        pTab->GetTable()->SetHTMLTableLayout( 0 );
+        GetDoc()->SetAttr( rNew, *pTab->GetFmt() );
+        GetDoc()->SetModified();
+        EndAllActionAndCall();
+    }
+}
+
+    // aender eine  Zellenbreite/-Hoehe/Spaltenbreite/Zeilenhoehe
+BOOL SwFEShell::SetColRowWidthHeight( USHORT eType, USHORT nDiff )
+{
+    SwFrm *pFrm = GetCurrFrm();
+    if( !pFrm->IsInTab() )
+        return FALSE;
+
+    if( WH_FLAG_INSDEL & eType &&
+        pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable ))
+    {
+        ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR,
+                        ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
+        return FALSE;
+    }
+
+    SET_CURR_SHELL( this );
+    StartAllAction();
+
+    do {
+        pFrm = pFrm->GetUpper();
+    } while( !pFrm->IsCellFrm() );
+
+    SwTabFrm *pTab = pFrm->ImplFindTabFrm();
+
+    // sollte die Tabelle noch auf relativen Werten (USHRT_MAX) stehen
+    // dann muss es jetzt auf absolute umgerechnet werden.
+    const SwFmtFrmSize& rTblFrmSz = pTab->GetFmt()->GetFrmSize();
+    if( TBLVAR_CHGABS == pTab->GetTable()->GetTblChgMode() &&
+        ( eType & WH_COL_LEFT || eType & WH_COL_RIGHT ) &&
+        HORI_NONE == pTab->GetFmt()->GetHoriOrient().GetHoriOrient() &&
+        pTab->Prt().Width() != rTblFrmSz.GetWidth() )
+    {
+        SwFmtFrmSize aSz( rTblFrmSz );
+        aSz.SetWidth( pTab->Prt().Width() );
+        pTab->GetFmt()->SetAttr( aSz );
+    }
+
+    if( (eType & (WH_FLAG_BIGGER | WH_FLAG_INSDEL)) ==
+        (WH_FLAG_BIGGER | WH_FLAG_INSDEL) )
+        nDiff = USHORT(pFrm->Frm().Width());
+
+    SwTwips nLogDiff = nDiff;
+    nLogDiff *= pTab->GetFmt()->GetFrmSize().GetWidth();
+    nLogDiff /= pTab->Prt().Width();
+
+    BOOL bRet = GetDoc()->SetColRowWidthHeight(
+                    *(SwTableBox*)((SwCellFrm*)pFrm)->GetTabBox(),
+                    eType, nDiff, nLogDiff );
+
+    delete pLastCols, pLastCols = 0;
+    EndAllActionAndCall();
+
+    if( bRet && (eType & (WH_FLAG_BIGGER | WH_FLAG_INSDEL)) == WH_FLAG_INSDEL )
+    {
+        switch(eType & ~(WH_FLAG_BIGGER | WH_FLAG_INSDEL))
+        {
+        case WH_CELL_LEFT:
+        case WH_COL_LEFT:
+                GoPrevCell();
+                break;
+
+        case WH_CELL_RIGHT:
+        case WH_COL_RIGHT:
+                GoNextCell();
+                break;
+
+        case WH_CELL_TOP:
+        case WH_ROW_TOP:
+                MoveSection( fnSectionCurr, fnSectionStart );
+                Up();
+                break;
+
+        case WH_CELL_BOTTOM:
+        case WH_ROW_BOTTOM:
+                MoveSection( fnSectionCurr, fnSectionEnd );
+                Down();
+                break;
+        }
+    }
+
+    return bRet;
+}
+
+BOOL lcl_IsFormulaSelBoxes( const SwTable& rTbl, const SwTblBoxFormula& rFml,
+                            SwCellFrms& rCells )
+{
+    SwTblBoxFormula aTmp( rFml );
+    SwSelBoxes aBoxes;
+    for( USHORT nSelBoxes = aTmp.GetBoxesOfFormula( rTbl,aBoxes ); nSelBoxes; )
+    {
+        SwTableBox* pBox = aBoxes[ --nSelBoxes ];
+        for( USHORT i = 0; i < rCells.Count(); ++i )
+            if( rCells[ i ]->GetTabBox() == pBox )
+                break;      // gefunden
+
+        if( i == rCells.Count() )
+            return FALSE;
+    }
+
+    return TRUE;
+}
+
+    // erfrage die Formel fuer die Autosumme
+BOOL SwFEShell::GetAutoSum( String& rFml ) const
+{
+    SwFrm *pFrm = GetCurrFrm();
+    SwTabFrm *pTab = pFrm->ImplFindTabFrm();
+    if( !pTab )
+        return FALSE;
+
+    rFml = String::CreateFromAscii( sCalc_Sum );
+
+    SwCellFrms aCells;
+    if( ::GetAutoSumSel( *this, aCells ))
+    {
+        USHORT nW = 0, nInsPos = 0;
+        for( USHORT n = aCells.Count(); n; )
+        {
+            SwCellFrm* pCFrm = aCells[ --n ];
+            USHORT nBoxW = pCFrm->GetTabBox()->IsFormulaOrValueBox();
+            if( !nBoxW )
+                break;
+
+            if( !nW )
+            {
+                if( USHRT_MAX == nBoxW )
+                    continue;       // leere am Anfang ueberspringen
+
+                rFml += '(';
+                nInsPos = rFml.Len();
+
+                // Formeln nur wenn diese Boxen enthalten
+                if( RES_BOXATR_FORMULA == nBoxW &&
+                    !::lcl_IsFormulaSelBoxes( *pTab->GetTable(), pCFrm->
+                    GetTabBox()->GetFrmFmt()->GetTblBoxFormula(), aCells))
+                {
+                    nW = RES_BOXATR_VALUE;
+                    // alle vorhierigen Leere wieder mit aufnehmen !
+                    for( USHORT i = aCells.Count(); n+1 < i; )
+                    {
+                        String sTmp( String::CreateFromAscii(
+                                RTL_CONSTASCII_STRINGPARAM( "|<" )) );
+                        sTmp += aCells[ --i ]->GetTabBox()->GetName();
+                        sTmp += '>';
+                        rFml.Insert( sTmp, nInsPos );
+                    }
+                }
+                else
+                    nW = nBoxW;
+            }
+            else if( RES_BOXATR_VALUE == nW )
+            {
+                // values werden gesucht, Value/Formel/Text gefunden -> aufn.
+                if( RES_BOXATR_FORMULA == nBoxW &&
+                    ::lcl_IsFormulaSelBoxes( *pTab->GetTable(), pCFrm->
+                        GetTabBox()->GetFrmFmt()->GetTblBoxFormula(), aCells ))
+                    break;
+                else if( USHRT_MAX != nBoxW )
+                    rFml.Insert( cListDelim, nInsPos );
+                else
+                    break;
+            }
+            else if( RES_BOXATR_FORMULA == nW )
+            {
+                // bei Formeln nur weiter suchen, wenn die akt. Formel auf
+                // alle Boxen verweist, die sich in der Selektion befinden
+                if( RES_BOXATR_FORMULA == nBoxW )
+                {
+                    if( !::lcl_IsFormulaSelBoxes( *pTab->GetTable(), pCFrm->
+                        GetTabBox()->GetFrmFmt()->GetTblBoxFormula(), aCells ))
+                    {
+                        // dann noch mal von vorne und nur die Values!
+
+                        nW = RES_BOXATR_VALUE;
+                        rFml.Erase( nInsPos );
+                        // alle vorhierigen Leere wieder mit aufnehmen !
+                        for( USHORT i = aCells.Count(); n+1 < i; )
+                        {
+                            String sTmp( String::CreateFromAscii(
+                                    RTL_CONSTASCII_STRINGPARAM( "|<" )) );
+                            sTmp += aCells[ --i ]->GetTabBox()->GetName();
+                            sTmp += '>';
+                            rFml.Insert( sTmp, nInsPos );
+                        }
+                    }
+                    else
+                        rFml.Insert( cListDelim, nInsPos );
+                }
+                else if( USHRT_MAX == nBoxW )
+                    break;
+                else
+                    continue;       // diese Boxen ignorieren
+            }
+            else
+                // alles andere beendet die Schleife
+// evt. Texte noch zu lassen??
+                break;
+
+            String sTmp( '<' );
+            sTmp += pCFrm->GetTabBox()->GetName();
+            sTmp += '>';
+            rFml.Insert( sTmp, nInsPos );
+        }
+        if( nW )
+        {
+            rFml += ')';
+
+/*
+            // TabellenSelektion erzeugen??
+            SwTblBoxFormula aTmp( rFml );
+            SwSelBoxes aBoxes;
+            for( USHORT nSelBoxes = aTmp.GetBoxesOfFormula( rTbl,aBoxes );
+                    nSelBoxes; )
+            {
+            }
+*/
+        }
+    }
+
+    return TRUE;
+}
+
diff --git a/sw/source/core/frmedt/fews.cxx b/sw/source/core/frmedt/fews.cxx
new file mode 100644
index 000000000000..e0aab41951df
--- /dev/null
+++ b/sw/source/core/frmedt/fews.cxx
@@ -0,0 +1,1000 @@
+/*************************************************************************
+ *
+ *  $RCSfile: fews.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:20 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _LIST_HXX //autogen
+#include 
+#endif
+#ifndef _SVDVMARK_HXX //autogen
+#include 
+#endif
+#ifndef _SVDOBJ_HXX //autogen
+#include 
+#endif
+
+#ifndef _FESH_HXX
+#include 
+#endif
+#ifndef _PAGEFRM_HXX
+#include 
+#endif
+#ifndef _ROOTFRM_HXX
+#include 
+#endif
+#ifndef _CNTFRM_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _FRMTOOL_HXX
+#include 
+#endif
+#ifndef _SWTABLE_HXX
+#include 
+#endif
+#ifndef _VIEWIMP_HXX
+#include 
+#endif
+#ifndef _DVIEW_HXX
+#include 
+#endif
+#ifndef _FLYFRM_HXX
+#include 
+#endif
+#ifndef _NODE_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _SECTFRM_HXX
+#include 
+#endif
+#ifndef _FMTPDSC_HXX //autogen
+#include 
+#endif
+#ifndef _FMTCNTNT_HXX //autogen
+#include 
+#endif
+#ifndef _TABFRM_HXX
+#include 
+#endif
+#ifndef _CELLFRM_HXX
+#include 
+#endif
+#ifndef _FLYFRMS_HXX
+#include 
+#endif
+#ifndef _MDIEXP_HXX
+#include 
+#endif
+#ifndef _EDIMP_HXX
+#include 
+#endif
+#ifndef _TBLSEL_HXX
+#include 
+#endif
+#ifndef _PAGEDESC_HXX
+#include 
+#endif
+#ifndef _FMTANCHR_HXX
+#include 
+#endif
+
+using namespace ::com::sun::star;
+TYPEINIT1(SwFEShell,SwEditShell)
+
+/***********************************************************************
+#*  Class      :  SwFEShell
+#*  Methode    :  EndAllActionAndCall()
+#*
+#*  Datum      :  MA 03. May. 93
+#*  Update     :  MA 31. Oct. 95
+#***********************************************************************/
+
+void SwFEShell::EndAllActionAndCall()
+{
+    ViewShell *pTmp = this;
+    do {
+        if( pTmp->IsA( TYPE(SwCrsrShell) ) )
+        {
+            ((SwFEShell*)pTmp)->EndAction();
+            ((SwFEShell*)pTmp)->CallChgLnk();
+        }
+        else
+            pTmp->EndAction();
+    } while( this != ( pTmp = (ViewShell*)pTmp->GetNext() ));
+}
+
+
+/***********************************************************************
+#*  Class       :  SwFEShell
+#*  Methode     :  GetCntntPos
+#*  Beschreibung:  Ermitteln des Cntnt's der dem Punkt am naechsten liegt
+#*  Datum       :  MA 02. Jun. 92
+#*  Update      :  MA 02. May. 95
+#***********************************************************************/
+
+Point SwFEShell::GetCntntPos( const Point& rPoint, BOOL bNext ) const
+{
+    SET_CURR_SHELL( (ViewShell*)this );
+    if ( bNext )
+        return GetLayout()->GetNextCntntPos( rPoint, IsTableMode() );
+    return GetLayout()->GetPrevCntntPos( rPoint );
+}
+
+
+const SwRect& SwFEShell::GetAnyCurRect( CurRectType eType, const Point* pPt,
+                                        const SvEmbeddedObject *pObj ) const
+{
+    const SwFrm *pFrm = Imp()->HasDrawView()
+                ? ::GetFlyFromMarked( &Imp()->GetDrawView()->GetMarkList(),
+                                      (ViewShell*)this)
+                : 0;
+
+    if( !pFrm )
+    {
+        if( pPt )
+        {
+            SwPosition aPos( *GetCrsr()->GetPoint() );
+            Point aPt( *pPt );
+            GetLayout()->GetCrsrOfst( &aPos, aPt );
+            SwCntntNode *pNd = aPos.nNode.GetNode().GetCntntNode();
+            pFrm = pNd->GetFrm( pPt );
+        }
+        else
+            pFrm = GetCurrFrm();
+    }
+
+    if( !pFrm )
+        return GetLayout()->Frm();
+
+    FASTBOOL  bFrm  = TRUE;
+    switch ( eType )
+    {
+        case RECT_PAGE_PRT:         bFrm = FALSE; /* no break */
+        case RECT_PAGE :            pFrm = pFrm->FindPageFrm();
+                                    break;
+
+        case RECT_PAGE_CALC:        pFrm->Calc();
+                                    pFrm = pFrm->FindPageFrm();
+                                    pFrm->Calc();
+                                    break;
+
+        case RECT_FLY_PRT_EMBEDDED: bFrm = FALSE; /* no break */
+        case RECT_FLY_EMBEDDED:     pFrm = pObj ? FindFlyFrm( pObj )
+                                                : pFrm->IsFlyFrm()
+                                                    ? pFrm
+                                                    : pFrm->FindFlyFrm();
+                                    break;
+
+        case RECT_OUTTABSECTION_PRT:
+        case RECT_OUTTABSECTION :   if( pFrm->IsInTab() )
+                                        pFrm = pFrm->FindTabFrm();
+                                    else
+                                        ASSERT( FALSE, "Missing Table" );
+                                    /* KEIN BREAK */
+        case RECT_SECTION_PRT:
+        case RECT_SECTION:          if( pFrm->IsInSct() )
+                                        pFrm = pFrm->FindSctFrm();
+                                    else
+                                        ASSERT( FALSE, "Missing section" );
+
+                                    if( RECT_OUTTABSECTION_PRT == eType ||
+                                        RECT_SECTION_PRT == eType )
+                                        bFrm = FALSE;
+                                    break;
+
+        case RECT_HEADERFOOTER_PRT: bFrm = FALSE; /* no break */
+        case RECT_HEADERFOOTER:     if( 0 == (pFrm = pFrm->FindFooterOrHeader()) )
+                                        return GetLayout()->Frm();
+                                    break;
+
+//JP 20.08.98: wo zu diese Statements? unnoetiger Code
+//      case RECT_FRM:
+//      default:                    break;
+    }
+    return bFrm ? pFrm->Frm() : pFrm->Prt();
+}
+
+
+USHORT SwFEShell::GetPageNumber( const Point &rPoint ) const
+{
+    const SwFrm *pPage = GetLayout()->Lower();
+    while ( pPage && !pPage->Frm().IsInside( rPoint ) )
+        pPage = pPage->GetNext();
+    if ( pPage )
+        return ((const SwPageFrm*)pPage)->GetPhyPageNum();
+    else
+        return 0;
+}
+
+
+BOOL SwFEShell::GetPageNumber( long nYPos, BOOL bAtCrsrPos, USHORT& rPhyNum, USHORT& rVirtNum, String &rDisplay) const
+{
+    const SwFrm *pPage;
+
+    if ( bAtCrsrPos )                   //Seite vom Crsr besorgen
+    {
+        pPage = GetCurrFrm( FALSE );
+        if ( pPage )
+            pPage = pPage->FindPageFrm();
+    }
+    else if ( nYPos > -1 )              //Seite ueber die Positon ermitteln
+    {
+        pPage = GetLayout()->Lower();
+        while( pPage &&  (pPage->Frm().Bottom() < nYPos ||
+                            nYPos < pPage->Frm().Top() ) )
+            pPage = pPage->GetNext();
+    }
+    else                                //Die erste sichtbare Seite
+    {
+        pPage = Imp()->GetFirstVisPage();
+        if ( pPage && ((SwPageFrm*)pPage)->IsEmptyPage() )
+            pPage = pPage->GetNext();
+    }
+
+    if( pPage )
+    {
+        rPhyNum  = ((const SwPageFrm*)pPage)->GetPhyPageNum();
+        rVirtNum = ((const SwPageFrm*)pPage)->GetVirtPageNum();
+        const SwNumType& rNum = ((const SwPageFrm*)pPage)->GetPageDesc()->GetNumType();
+        rDisplay = rNum.GetNumStr( rVirtNum );
+    }
+
+    return 0 != pPage;
+}
+
+#ifdef USED
+/*************************************************************************
+|*
+|*  SwFEShell::GetHeadFootFrmRect()
+|*
+|*  Ersterstellung      MA 08. Feb. 95
+|*  Letzte Aenderung    MA 08. Feb. 95
+|
+|*************************************************************************/
+
+//Das FrmRect von Header bzw. Footer wird relativ zur Seite ermittelt.
+//Der long ist 0 wenn der Crsr nicht in Header oder Footer steht.
+//Andernfalls markiert der long den maximalen bzw. minimalen Spielraum
+//fuer die Hoehe von Header bzw. Footer.
+
+long SwFEShell::GetHeadFootFrmRect( SwRect &rToFill ) const
+{
+    ASSERT( GetCurrFrm(), "Crsr geparkt?" );
+
+    long nRet = 0;
+    const SwFrm *pFrm = GetCurrFrm();
+    while ( pFrm && !pFrm->IsHeaderFrm() && !pFrm->IsFooterFrm() )
+        pFrm = pFrm->GetUpper();
+
+    if ( pFrm )
+    {
+        const SwPageFrm *pPage = pFrm->FindPageFrm();
+        rToFill = pFrm->Frm();
+        rToFill.Pos() -= pPage->Frm().Pos();
+
+        //Wenn Kopf-/Fusszeilen vergroessert werden, sollte die Resthoehe der
+        //PrtArea der Seite wenigstens 2cm (lMinBorder) betragen.
+        const SwFrm *pBody = pPage->FindBodyCont();
+        nRet = pBody->Frm().Top();
+        if ( pFrm->IsHeaderFrm() )
+        {
+            nRet += pBody->Prt().Bottom();
+            nRet -= lMinBorder;
+            nRet -= pBody->Prt().Top();
+        }
+        else if ( pFrm->IsFooterFrm() )
+        {
+            nRet += pBody->Prt().Top();
+            nRet += lMinBorder;
+            nRet += pBody->Frm().Height() -
+                    (pBody->Prt().Height() + pBody->Prt().Top());
+        }
+        nRet -= pPage->Frm().Top();
+    }
+    return nRet;
+}
+#endif
+
+/*************************************************************************
+|*
+|*  SwFEShell::GetFrmType()
+|*
+|*  Ersterstellung      MA 12. Jan. 93
+|*  Letzte Aenderung    AMA 25. Nov. 98
+|*
+*************************************************************************/
+
+USHORT SwFEShell::GetFrmType( const Point *pPt, BOOL bStopAtFly ) const
+{
+    USHORT nReturn = FRMTYPE_NONE;
+    SwFrm *pFrm;
+    if ( pPt )
+    {
+        SwPosition aPos( *GetCrsr()->GetPoint() );
+        Point aPt( *pPt );
+        GetLayout()->GetCrsrOfst( &aPos, aPt );
+        SwCntntNode *pNd = aPos.nNode.GetNode().GetCntntNode();
+        pFrm = pNd->GetFrm( pPt );
+    }
+    else
+        pFrm = GetCurrFrm( FALSE );
+    while ( pFrm )
+    {
+        switch ( pFrm->GetType() )
+        {
+            case FRM_COLUMN:    if( pFrm->GetUpper()->IsSctFrm() )
+                                {
+                                    // Check, if isn't not only a single column
+                                    // from a section with footnotes at the end.
+                                    if( pFrm->GetNext() || pFrm->GetPrev() )
+                                        // Sectioncolumns
+                                        nReturn |= ( nReturn & FRMTYPE_TABLE ) ?
+                                            FRMTYPE_COLSECTOUTTAB : FRMTYPE_COLSECT;
+                                }
+                                else // nur Seiten und Rahmenspalten
+                                    nReturn |= FRMTYPE_COLUMN;
+                                break;
+            case FRM_PAGE:      nReturn |= FRMTYPE_PAGE;
+                                if( ((SwPageFrm*)pFrm)->IsFtnPage() )
+                                    nReturn |= FRMTYPE_FTNPAGE;
+                                break;
+            case FRM_HEADER:    nReturn |= FRMTYPE_HEADER;      break;
+            case FRM_FOOTER:    nReturn |= FRMTYPE_FOOTER;      break;
+            case FRM_BODY:      if( pFrm->GetUpper()->IsPageFrm() ) // nicht bei ColumnFrms
+                                    nReturn |= FRMTYPE_BODY;
+                                break;
+            case FRM_FTN:       nReturn |= FRMTYPE_FOOTNOTE;    break;
+            case FRM_FLY:       if( ((SwFlyFrm*)pFrm)->IsFlyLayFrm() )
+                                    nReturn |= FRMTYPE_FLY_FREE;
+                                else if ( ((SwFlyFrm*)pFrm)->IsFlyAtCntFrm() )
+                                    nReturn |= FRMTYPE_FLY_ATCNT;
+                                else
+                                {
+                                    ASSERT( ((SwFlyFrm*)pFrm)->IsFlyInCntFrm(),
+                                            "Neuer Rahmentyp?" );
+                                    nReturn |= FRMTYPE_FLY_INCNT;
+                                }
+                                nReturn |= FRMTYPE_FLY_ANY;
+                                if( bStopAtFly )
+                                    return nReturn;
+                                break;
+            case FRM_TAB:
+            case FRM_ROW:
+            case FRM_CELL:      nReturn |= FRMTYPE_TABLE;       break;
+            default:            /* do nothing */                break;
+        }
+        if ( pFrm->IsFlyFrm() )
+            pFrm = ((SwFlyFrm*)pFrm)->GetAnchor();
+        else
+            pFrm = pFrm->GetUpper();
+    }
+    return nReturn;
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::ShLooseFcs(), ShGetFcs()
+|*
+|*  Ersterstellung      MA 10. May. 93
+|*  Letzte Aenderung    MA 09. Sep. 98
+|*
+*************************************************************************/
+
+void SwFEShell::ShGetFcs( BOOL bUpdate )
+{
+    ::SetShell( this );
+    SwCrsrShell::ShGetFcs( bUpdate );
+
+    if ( HasDrawView() )
+    {
+        Imp()->GetDrawView()->SetMarkHdlHidden( FALSE );
+        if ( Imp()->GetDrawView()->HasMarkedObj() )
+            FrameNotify( this, FLY_DRAG_START );
+    }
+}
+
+void SwFEShell::ShLooseFcs()
+{
+    SwCrsrShell::ShLooseFcs();
+
+    if ( HasDrawView() && Imp()->GetDrawView()->HasMarkedObj() )
+    {
+        Imp()->GetDrawView()->SetMarkHdlHidden( TRUE );
+        FrameNotify( this, FLY_DRAG_END );
+    }
+//  ::ResetShell();
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::GetPhyPageNum()
+|*  SwFEShell::GetVirtPageNum()
+|*
+|*  Ersterstellung      OK 07.07.93 08:20
+|*  Letzte Aenderung    MA 03. Jan. 94
+|*
+*************************************************************************/
+
+USHORT SwFEShell::GetPhyPageNum()
+{
+    SwFrm *pFrm = GetCurrFrm();
+    if ( pFrm )
+        return pFrm->GetPhyPageNum();
+    return 0;
+}
+
+USHORT SwFEShell::GetVirtPageNum( const BOOL bCalcFrm )
+{
+    SwFrm *pFrm = GetCurrFrm( bCalcFrm );
+    if ( pFrm )
+        return pFrm->GetVirtPageNum();
+    return 0;
+}
+
+/*************************************************************************
+|*
+|*  void lcl_SetAPageOffset()
+|*  void SwFEShell::SetNewPageOffset()
+|*  void SwFEShell::SetPageOffset()
+|*  USHORT SwFEShell::GetPageOffset() const
+|*
+|*  Ersterstellung      OK 07.07.93 08:20
+|*  Letzte Aenderung    MA 30. Mar. 95
+|*
+*************************************************************************/
+
+void lcl_SetAPageOffset( USHORT nOffset, SwPageFrm* pPage, SwFEShell* pThis )
+{
+    pThis->StartAllAction();
+    ASSERT( pPage->FindFirstBodyCntnt(),
+            "SwFEShell _SetAPageOffset() ohne CntntFrm" );
+
+    SwFmtPageDesc aDesc( pPage->GetPageDesc() );
+    aDesc.SetNumOffset( nOffset );
+
+    SwFrm *pFrm = pThis->GetCurrFrm( FALSE );
+    if ( pFrm->IsInTab() )
+        pThis->GetDoc()->SetAttr( aDesc, *pFrm->FindTabFrm()->GetFmt() );
+    else
+        pThis->GetDoc()->Insert( *pThis->GetCrsr(), aDesc );
+
+    pThis->EndAllAction();
+}
+
+void SwFEShell::SetNewPageOffset( USHORT nOffset )
+{
+    GetLayout()->SetVirtPageNum( TRUE );
+    const SwPageFrm *pPage = GetCurrFrm( FALSE )->FindPageFrm();
+    lcl_SetAPageOffset( nOffset, (SwPageFrm*)pPage, this );
+}
+
+void SwFEShell::SetPageOffset( USHORT nOffset )
+{
+    const SwPageFrm *pPage = GetCurrFrm( FALSE )->FindPageFrm();
+    const SwRootFrm* pLayout = GetLayout();
+    while ( pPage )
+    {
+        const SwFrm *pFlow = pPage->FindFirstBodyCntnt();
+        if ( pFlow )
+        {
+            if ( pFlow->IsInTab() )
+                pFlow = pFlow->FindTabFrm();
+            const SwFmtPageDesc& rPgDesc = pFlow->GetAttrSet()->GetPageDesc();
+            if ( rPgDesc.GetNumOffset() )
+            {
+                pLayout->SetVirtPageNum( TRUE );
+                lcl_SetAPageOffset( nOffset, (SwPageFrm*)pPage, this );
+                break;
+            }
+        }
+        pPage = (SwPageFrm*)pPage->GetPrev();
+    }
+}
+
+USHORT SwFEShell::GetPageOffset() const
+{
+    const SwPageFrm *pPage = GetCurrFrm()->FindPageFrm();
+    while ( pPage )
+    {
+        const SwFrm *pFlow = pPage->FindFirstBodyCntnt();
+        if ( pFlow )
+        {
+            if ( pFlow->IsInTab() )
+                pFlow = pFlow->FindTabFrm();
+            const USHORT nOffset = pFlow->GetAttrSet()->GetPageDesc().GetNumOffset();
+            if ( nOffset )
+                return nOffset;
+        }
+        pPage = (SwPageFrm*)pPage->GetPrev();
+    }
+    return 0;
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::InsertLabel()
+|*
+|*  Ersterstellung      MA 10. Feb. 94
+|*  Letzte Aenderung    MA 10. Feb. 94
+|*
+*************************************************************************/
+
+void SwFEShell::InsertLabel( const SwLabelType eType, const String &rTxt,
+                             const BOOL bBefore, const USHORT nId,
+                             const BOOL bCpyBrd )
+{
+    //NodeIndex der CrsrPosition besorgen, den Rest kann das Dokument
+    //selbst erledigen.
+    SwCntntFrm *pCnt = LTYPE_DRAW==eType ? 0 : GetCurrFrm( FALSE );
+    if( LTYPE_DRAW==eType || pCnt )
+    {
+        StartAllAction();
+
+        ULONG nIdx = 0;
+        SwFlyFrmFmt* pFlyFmt = 0;
+        switch( eType )
+        {
+        case LTYPE_OBJECT:
+        case LTYPE_FLY:
+            if( pCnt->IsInFly() )
+            {
+                //Bei Flys den Index auf den StartNode herunterreichen.
+                nIdx = pCnt->FindFlyFrm()->
+                            GetFmt()->GetCntnt().GetCntntIdx()->GetIndex();
+//warum?? Bug 61913     ParkCrsr( GetCrsr()->GetPoint()->nNode );
+            }
+            break;
+        case LTYPE_TABLE:
+            if( pCnt->IsInTab() )
+            {
+                //Bei Tabellen den Index auf den TblNode herunterreichen.
+                const SwTable& rTbl = *pCnt->FindTabFrm()->GetTable();
+                nIdx = rTbl.GetTabSortBoxes()[ 0 ]
+                            ->GetSttNd()->FindTableNode()->GetIndex();
+            }
+            break;
+        case LTYPE_DRAW:
+            if( Imp()->GetDrawView() )
+            {
+                SwDrawView *pDView = Imp()->GetDrawView();
+                const SdrMarkList& rMrkList = pDView->GetMarkList();
+                StartUndo();
+
+                ULONG nCount = rMrkList.GetMarkCount();
+                for( ULONG i=0; i < nCount; i++ )
+                {
+                    SdrObject *pObj = rMrkList.GetMark(i)->GetObj();
+                    if( !pObj->IsWriterFlyFrame() )
+                    {
+                        SwFlyFrmFmt *pFmt =
+                            GetDoc()->InsertDrawLabel( rTxt, nId, *pObj );
+                        if( !pFlyFmt )
+                            pFlyFmt = pFmt;
+                    }
+                }
+                EndUndo();
+            }
+            break;
+        default:
+            ASSERT( !this, "Crsr weder in Tabelle noch in Fly." );
+        }
+
+        if( nIdx )
+            pFlyFmt = GetDoc()->InsertLabel( eType, rTxt, bBefore, nId,
+                                             nIdx, bCpyBrd );
+
+        SwFlyFrm* pFrm;
+        const Point aPt( GetCrsrDocPos() );
+        if( pFlyFmt && 0 != ( pFrm = pFlyFmt->GetFrm( &aPt )))
+            SelectFlyFrm( *pFrm, TRUE );
+
+        EndAllActionAndCall();
+    }
+}
+
+
+/***********************************************************************
+#*  Class       :  SwFEShell
+#*  Methoden    :  Sort
+#*  Datum       :  ??
+#*  Update      :  ??
+#***********************************************************************/
+
+BOOL SwFEShell::Sort(const SwSortOptions& rOpt)
+{
+    if( !HasSelection() )
+        return FALSE;
+
+    SET_CURR_SHELL( this );
+    BOOL bRet;
+    StartAllAction();
+    if(IsTableMode())
+    {
+        // Tabelle sortieren
+        // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen
+        SwFrm *pFrm = GetCurrFrm( FALSE );
+        ASSERT( pFrm->FindTabFrm(), "Crsr nicht in Tabelle." );
+
+        // lasse ueber das Layout die Boxen suchen
+        SwSelBoxes  aBoxes;
+        GetTblSel(*this, aBoxes);
+
+        // die Crsr muessen noch aus dem Loesch Bereich entfernt
+        // werden. Setze sie immer hinter/auf die Tabelle; ueber die
+        // Dokument-Position werden sie dann immer an die alte Position gesetzt.
+        while( !pFrm->IsCellFrm() )
+            pFrm = pFrm->GetUpper();
+        {
+            ParkCrsr( SwNodeIndex( *((SwCellFrm*)pFrm)->GetTabBox()->GetSttNd() ));
+        }
+
+        // Sorting am Dokument aufrufen
+        bRet = pDoc->SortTbl(aBoxes, rOpt);
+    }
+    else
+    {
+        // Text sortieren und nichts anderes
+        FOREACHPAM_START(this)
+
+            SwPaM* pPam = PCURCRSR;
+
+            SwPosition* pStart = pPam->Start();
+            SwPosition* pEnd   = pPam->End();
+
+            SwNodeIndex aPrevIdx( pStart->nNode, -1 );
+            ULONG nOffset = pEnd->nNode.GetIndex() - pStart->nNode.GetIndex();
+            xub_StrLen nCntStt  = pStart->nContent.GetIndex();
+
+            // Das Sortieren
+            bRet = pDoc->SortText(*pPam, rOpt);
+
+            // Selektion wieder setzen
+            pPam->DeleteMark();
+            pPam->GetPoint()->nNode.Assign( aPrevIdx.GetNode(), +1 );
+            SwCntntNode* pCNd = pPam->GetCntntNode();
+            xub_StrLen nLen = pCNd->Len();
+            if( nLen > nCntStt )
+                nLen = nCntStt;
+            pPam->GetPoint()->nContent.Assign(pCNd, nLen );
+            pPam->SetMark();
+
+            pPam->GetPoint()->nNode += nOffset;
+            pCNd = pPam->GetCntntNode();
+            pPam->GetPoint()->nContent.Assign( pCNd, pCNd->Len() );
+
+        FOREACHPAM_END()
+    }
+
+    EndAllAction();
+    return bRet;
+}
+
+/*************************************************************************
+|*
+|*  SwFEShell::GetCurColNum(), _GetColNum()
+|*
+|*  Ersterstellung      MA 03. Feb. 95
+|*  Letzte Aenderung    MA 20. Apr. 95
+|
+|*************************************************************************/
+
+USHORT SwFEShell::_GetCurColNum( const SwFrm *pFrm,
+                                SwGetCurColNumPara* pPara ) const
+{
+    USHORT nRet = 0;
+    while ( pFrm )
+    {
+        pFrm = pFrm->GetUpper();
+        if( pFrm && pFrm->IsColumnFrm() )
+        {
+            const SwFrm *pCurFrm = pFrm;
+            do {
+                ++nRet;
+                pFrm = pFrm->GetPrev();
+            } while ( pFrm );
+
+            if( pPara )
+            {
+                // dann suche mal das Format, was diese Spaltigkeit bestimmt
+                pFrm = pCurFrm->GetUpper();
+                while( pFrm )
+                {
+                    if( ( FRM_PAGE | FRM_FLY | FRM_SECTION ) & pFrm->GetType() )
+                    {
+                        pPara->pFrmFmt = ((SwLayoutFrm*)pFrm)->GetFmt();
+                        pPara->pPrtRect = &pFrm->Prt();
+                        pPara->pFrmRect = &pFrm->Frm();
+                        break;
+                    }
+                    pFrm = pFrm->GetUpper();
+                }
+                if( !pFrm )
+                {
+                    pPara->pFrmFmt = 0;
+                    pPara->pPrtRect = 0;
+                    pPara->pFrmRect = 0;
+                }
+            }
+            break;
+        }
+    }
+    return nRet;
+}
+
+USHORT SwFEShell::GetCurColNum( SwGetCurColNumPara* pPara ) const
+{
+    ASSERT( GetCurrFrm(), "Crsr geparkt?" );
+    return _GetCurColNum( GetCurrFrm(), pPara );
+}
+
+USHORT SwFEShell::GetCurOutColNum( SwGetCurColNumPara* pPara ) const
+{
+    USHORT nRet = 0;
+    SwFrm* pFrm = GetCurrFrm();
+    ASSERT( pFrm, "Crsr geparkt?" );
+    if( pFrm )
+    {
+        pFrm = pFrm->IsInTab() ? (SwFrm*)pFrm->FindTabFrm()
+                               : (SwFrm*)pFrm->FindSctFrm();
+        ASSERT( pFrm, "No Tab, no Sect" );
+        if( pFrm )
+            nRet = _GetCurColNum( pFrm, pPara );
+    }
+    return nRet;
+}
+
+SwFEShell::SwFEShell( SwDoc *pDoc,
+        uno::Reference &xSpell,
+        uno::Reference &xHyph,
+                         Window *pWin,
+                         SwRootFrm *pMaster, const SwViewOption *pOpt )
+    : SwEditShell( pDoc, xSpell, xHyph, pWin, pMaster, pOpt ),
+    pChainFrom( 0 ),
+    pChainTo( 0 )
+{
+}
+
+SwFEShell::SwFEShell( SwEditShell *pShell, Window *pWin )
+    : SwEditShell( pShell, pWin ),
+    pChainFrom( 0 ),
+    pChainTo( 0 )
+{
+}
+
+SwFEShell::~SwFEShell()
+{
+    delete pChainFrom;
+    delete pChainTo;
+}
+
+void SwFEShell::CalcBoundRect( SwRect &rRect, RndStdIds nAnchorId,
+    SwRelationOrient eRelOrient, BOOL bMirror, Point* pRef, Size* pPercent ) const
+{
+    SwFrm *pFrm;
+    SwFlyFrm *pFly;
+    if( pRef )
+    {
+        pFrm = GetCurrFrm();
+        if( 0 != ( pFly = pFrm->FindFlyFrm() ) )
+            pFrm = pFly->GetAnchor();
+    }
+    else
+    {
+        pFly = FindFlyFrm();
+        pFrm = pFly ? pFly->GetAnchor() : GetCurrFrm();
+    }
+    SwPageFrm* pPage = pFrm->FindPageFrm();
+    bMirror = bMirror && !( pPage->GetVirtPageNum() % 2 );
+
+    Point aPos;
+    if( FLY_PAGE == nAnchorId || FLY_AT_FLY == nAnchorId ) // LAYER_IMPL
+    {
+#ifdef AMA_OUT_OF_FLY
+        // Falls wir uns auch ausserhalb des Rahmens aufhalten duerfen
+        SwFrm *pTmp = pFrm->FindPageFrm();
+        rRect = pTmp->Frm();
+        if( FLY_PAGE == nAnchorId )
+            pFrm = pTmp;
+#else
+        SwFrm *pTmp = pFrm;
+        if( FLY_PAGE == nAnchorId )
+            pFrm = pPage;
+        else
+            pFrm = pFrm->FindFlyFrm();
+        if( !pFrm )
+            pFrm = pTmp;
+        rRect = pFrm->Frm();
+        aPos = pFrm->Frm().Pos();
+        if( bMirror )
+        {
+            switch ( eRelOrient )
+            {
+                case PRTAREA:
+                case REL_PG_PRTAREA: aPos.X() += pFrm->Prt().Width();
+                // kein break
+                case REL_PG_RIGHT:
+                case REL_FRM_RIGHT: aPos.X() += pFrm->Prt().Left(); break;
+                default: aPos.X() += pFrm->Frm().Width();
+            }
+        }
+        else
+        {
+            switch ( eRelOrient )
+            {
+                case REL_PG_RIGHT:
+                case REL_FRM_RIGHT: aPos.X() += pFrm->Prt().Width();
+                // kein break!
+                case PRTAREA:
+                case REL_PG_PRTAREA: aPos.X() += pFrm->Prt().Left(); break;
+            }
+        }
+#endif
+        if( pPercent )
+            *pPercent = pFrm->Prt().SSize();
+    }
+    else
+    {
+        BOOL bAtCntnt = FLY_AT_CNTNT == nAnchorId ||
+                        FLY_AUTO_CNTNT == nAnchorId;  // LAYER_IMPL
+        if( pRef && !bAtCntnt && pFly && pFly->IsFlyInCntFrm() )
+            *pRef = ( (SwFlyInCntFrm*)pFly )->GetRefPoint();
+
+        SwFrm *pUpper = ( pFrm->IsPageFrm() || pFrm->IsFlyFrm() ) ?
+                        pFrm : pFrm->GetUpper();
+        rRect = pUpper->Frm();
+        if( pPercent )
+            *pPercent = pUpper->Prt().SSize();
+        if( bAtCntnt )
+        {
+            while( pUpper->IsColumnFrm() || pUpper->IsSctFrm() ||
+                   pUpper->IsColBodyFrm() ) // auch ein Rahmen innerhalb einer Spalte darf
+                                            // ueber die ganze Seite gehen
+                pUpper = pUpper->GetUpper();
+        }
+        if( !pUpper->IsBodyFrm() )
+        {
+            rRect += pUpper->Prt().Pos();
+            rRect.SSize( pUpper->Prt().SSize() );
+            if ( bAtCntnt )
+                rRect.Top( pFrm->Frm().Top() );
+            if ( pUpper->IsCellFrm() )//MA_FLY_HEIGHT
+            {
+                SwFrm *pTab = pUpper->FindTabFrm();
+                long nBottom = pTab->GetUpper()->Frm().Top() +
+                               pTab->GetUpper()->Prt().Bottom();
+                rRect.Bottom( nBottom );
+            }
+        }
+        if( bAtCntnt )
+        {
+            rRect.Left( pPage->Frm().Left() );
+            rRect.Width( pPage->Frm().Width() );
+        }
+        else  // bei zeichengebundenen lieber nur 90% der Hoehe ausnutzen
+            rRect.Height( (rRect.Height()*9)/10 );
+
+        aPos = pFrm->Frm().Pos();
+
+        if( bMirror )
+        {
+            switch ( eRelOrient )
+            {
+                case REL_FRM_RIGHT: aPos.X() += pFrm->Prt().Left(); break;
+                case FRAME:
+                case REL_FRM_LEFT: aPos.X() += pFrm->Frm().Width(); break;
+                case PRTAREA: aPos.X() += pFrm->Prt().Right(); break;
+                case REL_PG_LEFT:
+                case REL_PG_FRAME: aPos.X() = pPage->Frm().Right(); break;
+                case REL_PG_PRTAREA: aPos.X() = pPage->Frm().Left()
+                                              + pPage->Prt().Left(); break;
+            }
+        }
+        else
+        {
+            switch ( eRelOrient )
+            {
+                case REL_FRM_RIGHT: aPos.X() += pFrm->Prt().Width();
+                // kein break!
+                case PRTAREA: aPos += pFrm->Prt().Pos(); break;
+
+                case REL_PG_RIGHT: aPos.X() = pPage->Frm().Left()
+                                            + pPage->Prt().Right(); break;
+                case REL_PG_PRTAREA: aPos.X() = pPage->Frm().Left()
+                                              + pPage->Prt().Left(); break;
+                case REL_PG_LEFT:
+                case REL_PG_FRAME: aPos.X() = pPage->Frm().Left(); break;
+            }
+        }
+
+    }
+    if( !pRef )
+    {
+        rRect.Pos( rRect.Left() - aPos.X(), rRect.Top() - aPos.Y() );
+        if( bMirror )
+            rRect.Pos( -rRect.Right(), rRect.Top() );
+    }
+}
+
+Size SwFEShell::GetGraphicDefaultSize() const
+{
+    Size aRet;
+    SwFlyFrm *pFly = FindFlyFrm();
+    if ( pFly )
+    {
+        aRet = pFly->GetAnchor()->Prt().SSize();
+
+        SwRect aBound;
+        CalcBoundRect( aBound, pFly->GetFmt()->GetAnchor().GetAnchorId());
+        aRet.Height() = aBound.Height();
+    }
+    return aRet;
+}
+
+
diff --git a/sw/source/core/frmedt/makefile.mk b/sw/source/core/frmedt/makefile.mk
new file mode 100644
index 000000000000..c32e88c5fbe3
--- /dev/null
+++ b/sw/source/core/frmedt/makefile.mk
@@ -0,0 +1,112 @@
+#*************************************************************************
+#
+#   $RCSfile: makefile.mk,v $
+#
+#   $Revision: 1.1.1.1 $
+#
+#   last change: $Author: hr $ $Date: 2000-09-19 00:08:20 $
+#
+#   The Contents of this file are made available subject to the terms of
+#   either of the following licenses
+#
+#          - GNU Lesser General Public License Version 2.1
+#          - Sun Industry Standards Source License Version 1.1
+#
+#   Sun Microsystems Inc., October, 2000
+#
+#   GNU Lesser General Public License Version 2.1
+#   =============================================
+#   Copyright 2000 by Sun Microsystems, Inc.
+#   901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+#   This library is free software; you can redistribute it and/or
+#   modify it under the terms of the GNU Lesser General Public
+#   License version 2.1, as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   Lesser General Public License for more details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+#   License along with this library; if not, write to the Free Software
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+#   MA  02111-1307  USA
+#
+#
+#   Sun Industry Standards Source License Version 1.1
+#   =================================================
+#   The contents of this file are subject to the Sun Industry Standards
+#   Source License Version 1.1 (the "License"); You may not use this file
+#   except in compliance with the License. You may obtain a copy of the
+#   License at http://www.openoffice.org/license.html.
+#
+#   Software provided under this License is provided on an "AS IS" basis,
+#   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+#   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+#   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+#   See the License for the specific provisions governing your rights and
+#   obligations concerning the Software.
+#
+#   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+#   Copyright: 2000 by Sun Microsystems, Inc.
+#
+#   All Rights Reserved.
+#
+#   Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sw
+TARGET=frmedt
+
+AUTOSEG=true
+
+PROJECTPCH=core_pch
+PDBTARGET=core_pch
+PROJECTPCHSOURCE=..$/core_1st$/core_pch
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE :  $(PRJ)$/inc$/swpre.mk
+.INCLUDE :  settings.mk
+.INCLUDE :  $(PRJ)$/inc$/sw.mk
+
+
+.IF "$(mydebug)" != ""
+CDEFS+=-Dmydebug
+.ENDIF
+
+# --- Files --------------------------------------------------------
+
+CXXFILES = \
+        fecopy.cxx \
+        fedesc.cxx \
+        fefly1.cxx \
+        feflyole.cxx \
+        feshview.cxx \
+        fetab.cxx \
+        fews.cxx \
+        tblsel.cxx
+
+
+
+SLOFILES =  \
+        $(SLO)$/fecopy.obj \
+        $(SLO)$/fedesc.obj \
+        $(SLO)$/fefly1.obj \
+        $(SLO)$/feflyole.obj \
+        $(SLO)$/feshview.obj \
+        $(SLO)$/fetab.obj \
+        $(SLO)$/fews.obj \
+        $(SLO)$/tblsel.obj
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE :  target.mk
+
diff --git a/sw/source/core/frmedt/tblsel.cxx b/sw/source/core/frmedt/tblsel.cxx
new file mode 100644
index 000000000000..22de0c073afd
--- /dev/null
+++ b/sw/source/core/frmedt/tblsel.cxx
@@ -0,0 +1,2593 @@
+/*************************************************************************
+ *
+ *  $RCSfile: tblsel.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:20 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#define ITEMID_BOXINFO      SID_ATTR_BORDER_INNER
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _IPOBJ_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BOXITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_PROTITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SCH_DLL_HXX //autogen
+#include 
+#endif
+#ifndef _SCH_MEMCHRT_HXX
+#include 
+#endif
+
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFSIZE_HXX //autogen
+#include 
+#endif
+#ifndef _FRMATR_HXX
+#include 
+#endif
+#ifndef _TBLSEL_HXX
+#include 
+#endif
+#ifndef _CRSRSH_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _NDOLE_HXX
+#include 
+#endif
+#ifndef _SWTABLE_HXX
+#include 
+#endif
+#ifndef _CNTFRM_HXX
+#include 
+#endif
+#ifndef _TABFRM_HXX
+#include 
+#endif
+#ifndef _ROWFRM_HXX
+#include 
+#endif
+#ifndef _CELLFRM_HXX
+#include 
+#endif
+#ifndef _PAGEFRM_HXX
+#include 
+#endif
+#ifndef _ROOTFRM_HXX
+#include 
+#endif
+#ifndef _VISCRS_HXX
+#include 
+#endif
+#ifndef _SWCRSR_HXX
+#include 
+#endif
+#ifndef _SWTBLFMT_HXX
+#include 
+#endif
+#ifndef _FMTCOL_HXX
+#include 
+#endif
+#ifndef _UNDOBJ_HXX
+#include 
+#endif
+#ifndef _MVSAVE_HXX
+#include 
+#endif
+
+//siehe auch swtable.cxx
+#define COLFUZZY 20L
+
+// defines, die bestimmen, wie Tabellen Boxen gemergt werden:
+//  - 1. alle leeren Zeilen entfernen, alle Boxen werden mit Blank,
+//      alle Lines mit ParaBreak getrennt
+//  - 2. alle leeren Zeilen und alle leeren Boxen am Anfang und Ende
+//      entfernen, alle Boxen werden mit Blank,
+//      alle Lines mit ParaBreak getrennt
+//  - 3. alle leeren Boxen entfernen, alle Boxen werden mit Blank,
+//      alle Lines mit ParaBreak getrennt
+
+#undef      DEL_ONLY_EMPTY_LINES
+#undef      DEL_EMPTY_BOXES_AT_START_AND_END
+#define     DEL_ALL_EMPTY_BOXES
+
+
+_SV_IMPL_SORTAR_ALG( SwSelBoxes, SwTableBoxPtr )
+BOOL SwSelBoxes::Seek_Entry( const SwTableBoxPtr rSrch, USHORT* pFndPos ) const
+{
+    ULONG nIdx = rSrch->GetSttIdx();
+
+    register USHORT nO = Count(), nM, nU = 0;
+    if( nO > 0 )
+    {
+        nO--;
+        while( nU <= nO )
+        {
+            nM = nU + ( nO - nU ) / 2;
+            if( (*this)[ nM ]->GetSttNd() == rSrch->GetSttNd() )
+            {
+                if( pFndPos )
+                    *pFndPos = nM;
+                return TRUE;
+            }
+            else if( (*this)[ nM ]->GetSttIdx() < nIdx )
+                nU = nM + 1;
+            else if( nM == 0 )
+            {
+                if( pFndPos )
+                    *pFndPos = nU;
+                return FALSE;
+            }
+            else
+                nO = nM - 1;
+        }
+    }
+    if( pFndPos )
+        *pFndPos = nU;
+    return FALSE;
+}
+
+
+SV_IMPL_PTRARR( SwCellFrms, SwCellFrm* )
+
+struct _CmpLPt
+{
+    const Point* pPos;
+    const SwTableBox* pSelBox;
+
+    _CmpLPt( const Point& rPt, const SwTableBox* pBox );
+
+    BOOL operator==( const _CmpLPt& rCmp ) const
+    {   return X() == rCmp.X() && Y() == rCmp.Y() ? TRUE : FALSE; }
+    BOOL operator<( const _CmpLPt& rCmp ) const
+    {   return Y() < rCmp.Y() || ( Y() == rCmp.Y() && X() < rCmp.X() )
+                ? TRUE : FALSE; }
+
+    long X() const { return pPos->X(); }
+    long Y() const { return pPos->Y(); }
+};
+
+SV_DECL_VARARR_SORT( _MergePos, _CmpLPt, 0, 40 )
+SV_IMPL_VARARR_SORT( _MergePos, _CmpLPt )
+
+SV_IMPL_PTRARR( _FndBoxes, _FndBox* )
+SV_IMPL_PTRARR( _FndLines, _FndLine* )
+
+
+struct _Sort_CellFrm
+{
+    const SwCellFrm* pFrm;
+    _Sort_CellFrm( const SwCellFrm& rCFrm ) : pFrm( &rCFrm ) {}
+
+    int operator< ( const _Sort_CellFrm& rCmp ) const
+    {
+        return pFrm->Frm().Top() < rCmp.pFrm->Frm().Top() ||
+                ( pFrm->Frm().Top() == rCmp.pFrm->Frm().Top() &&
+                  pFrm->Frm().Left() < rCmp.pFrm->Frm().Left() );
+    }
+    int operator==( const _Sort_CellFrm& rCmp ) const
+    {
+        return pFrm->Frm().Top() == rCmp.pFrm->Frm().Top() &&
+               pFrm->Frm().Left() == rCmp.pFrm->Frm().Left();
+    }
+};
+
+SV_DECL_VARARR( _Sort_CellFrms, _Sort_CellFrm, 16, 16 )
+SV_IMPL_VARARR( _Sort_CellFrms, _Sort_CellFrm )
+
+SV_IMPL_PTRARR( SwChartBoxes, SwTableBoxPtr );
+SV_IMPL_PTRARR( SwChartLines, SwChartBoxes* );
+
+const SwLayoutFrm *lcl_FindCellFrm( const SwLayoutFrm *pLay )
+{
+    while ( pLay && !pLay->IsCellFrm() )
+        pLay = pLay->GetUpper();
+    return pLay;
+}
+
+const SwLayoutFrm *lcl_FindNextCellFrm( const SwLayoutFrm *pLay )
+{
+    //Dafuer sorgen, dass die Zelle auch verlassen wird (Bereiche)
+    const SwLayoutFrm *pTmp = pLay;
+    do {
+        pTmp = pTmp->GetNextLayoutLeaf();
+    } while( pLay->IsAnLower( pTmp ) );
+
+    while( pTmp && !pTmp->IsCellFrm() )
+        pTmp = pTmp->GetUpper();
+    return pTmp;
+}
+
+void GetTblSelCrs( const SwCrsrShell &rShell, SwSelBoxes& rBoxes )
+{
+    if( rBoxes.Count() )
+        rBoxes.Remove( USHORT(0), rBoxes.Count() );
+    if( rShell.IsTableMode() && ((SwCrsrShell&)rShell).UpdateTblSelBoxes())
+        rBoxes.Insert( &rShell.GetTableCrsr()->GetBoxes() );
+}
+
+void GetTblSelCrs( const SwTableCursor& rTblCrsr, SwSelBoxes& rBoxes )
+{
+    if( rBoxes.Count() )
+        rBoxes.Remove( USHORT(0), rBoxes.Count() );
+
+    if( rTblCrsr.IsChgd() || !rTblCrsr.GetBoxesCount() )
+    {
+        SwTableCursor* pTCrsr = (SwTableCursor*)&rTblCrsr;
+        pTCrsr->GetDoc()->GetRootFrm()->MakeTblCrsrs( *pTCrsr );
+    }
+
+    if( rTblCrsr.GetBoxesCount() )
+        rBoxes.Insert( &rTblCrsr.GetBoxes() );
+}
+
+void GetTblSel( const SwCrsrShell& rShell, SwSelBoxes& rBoxes,
+                const SwTblSearchType eSearchType )
+{
+    //Start- und Endzelle besorgen und den naechsten fragen.
+    if ( !rShell.IsTableMode() )
+        rShell.GetCrsr();
+
+    const SwShellCrsr *pCrsr = rShell.GetTableCrsr();
+    if( !pCrsr )
+        pCrsr = (SwShellCrsr*)*rShell.GetSwCrsr( FALSE );
+
+    GetTblSel( *pCrsr, rBoxes, eSearchType );
+}
+
+void GetTblSel( const SwCursor& rCrsr, SwSelBoxes& rBoxes,
+                const SwTblSearchType eSearchType )
+{
+    //Start- und Endzelle besorgen und den naechsten fragen.
+    ASSERT( rCrsr.GetCntntNode() && rCrsr.GetCntntNode( FALSE ),
+            "Tabselection nicht auf Cnt." );
+
+    // Zeilen-Selektion:
+    // teste ob Tabelle komplex ist. Wenn ja, dann immer uebers Layout
+    // die selektierten Boxen zusammen suchen. Andernfalls ueber die
+    // Tabellen-Struktur (fuer Makros !!)
+    const SwTableNode* pTblNd;
+    if( TBLSEARCH_ROW == ((~TBLSEARCH_PROTECT ) & eSearchType ) &&
+        0 != ( pTblNd = rCrsr.GetNode()->FindTableNode() ) &&
+        !pTblNd->GetTable().IsTblComplex() )
+    {
+        const SwTable& rTbl = pTblNd->GetTable();
+        const SwTableLines& rLines = rTbl.GetTabLines();
+        const SwTableLine* pLine = rTbl.GetTblBox(  rCrsr.GetNode(
+                    FALSE )->StartOfSectionIndex() )->GetUpper();
+        USHORT nSttPos = rLines.GetPos( pLine );
+        ASSERT( USHRT_MAX != nSttPos, "Wo ist meine Zeile in der Tabelle?" );
+
+        pLine = rTbl.GetTblBox( rCrsr.GetNode( TRUE )->StartOfSectionIndex() )
+                                ->GetUpper();
+        USHORT nEndPos = rLines.GetPos( pLine );
+        ASSERT( USHRT_MAX != nEndPos, "Wo ist meine Zeile in der Tabelle?" );
+
+        if( nEndPos < nSttPos )     // vertauschen
+        {
+            USHORT nTmp = nSttPos; nSttPos = nEndPos; nEndPos = nTmp;
+        }
+
+        int bChkProtected = TBLSEARCH_PROTECT & eSearchType;
+        for( ; nSttPos <= nEndPos; ++nSttPos )
+        {
+            pLine = rLines[ nSttPos ];
+            for( USHORT n = pLine->GetTabBoxes().Count(); n ; )
+            {
+                SwTableBox* pBox = pLine->GetTabBoxes()[ --n ];
+                // Zellenschutzt beachten ??
+                if( !bChkProtected ||
+                    !pBox->GetFrmFmt()->GetProtect().IsCntntProtected() )
+                    rBoxes.Insert( pBox );
+            }
+        }
+    }
+    else
+    {
+        Point aPtPos, aMkPos;
+        const SwShellCrsr* pShCrsr = rCrsr;
+        if( pShCrsr )
+        {
+            aPtPos = pShCrsr->GetPtPos();
+            aMkPos = pShCrsr->GetMkPos();
+        }
+        const SwLayoutFrm *pStart = rCrsr.GetCntntNode()->GetFrm(
+                                    &aPtPos )->GetUpper(),
+                          *pEnd   = rCrsr.GetCntntNode(FALSE)->GetFrm(
+                                    &aMkPos )->GetUpper();
+        GetTblSel( pStart, pEnd, rBoxes, eSearchType );
+    }
+}
+
+void GetTblSel( const SwLayoutFrm* pStart, const SwLayoutFrm* pEnd,
+                SwSelBoxes& rBoxes, const SwTblSearchType eSearchType )
+{
+    //Muss ein HeadlineRepeat beachtet werden?
+    const BOOL bRepeat = pStart->FindTabFrm()->GetTable()->IsHeadlineRepeat();
+    int bChkProtected = TBLSEARCH_PROTECT & eSearchType;
+
+    BOOL bTblIsValid;
+    int nLoopMax = 100;     //JP 28.06.99: max 100 loops - Bug 67292
+    do {
+        bTblIsValid = TRUE;
+
+        //Zuerst lassen wir uns die Tabellen und die Rechtecke heraussuchen.
+        SwSelUnions aUnions;
+        ::MakeSelUnions( aUnions, pStart, pEnd, eSearchType );
+
+        //Jetzt zu jedem Eintrag die Boxen herausfischen und uebertragen.
+        for( USHORT i = 0; i < aUnions.Count() && bTblIsValid; ++i )
+        {
+            SwSelUnion *pUnion = aUnions[i];
+            const SwTabFrm *pTable = pUnion->GetTable();
+
+            if( !pTable->IsValid() && nLoopMax )
+            {
+                bTblIsValid = FALSE;
+                break;
+            }
+
+            const SwLayoutFrm *pRow = (const SwLayoutFrm*)pTable->Lower();
+            //Wenn die Row eine wiederholte Headline ist wird sie nicht
+            //beachtet.
+            if( bRepeat && pTable->IsFollow() )
+                pRow = (const SwLayoutFrm*)pRow->GetNext();
+
+            while( pRow && bTblIsValid )
+            {
+                if( !pRow->IsValid() && nLoopMax )
+                {
+                    bTblIsValid = FALSE;
+                    break;
+                }
+
+                if ( pRow->Frm().IsOver( pUnion->GetUnion() ) )
+                {
+                    const SwLayoutFrm *pCell = pRow->FirstCell();
+
+                    while( bTblIsValid && pCell && pRow->IsAnLower( pCell ) )
+                    {
+                        if( !pCell->IsValid() && nLoopMax )
+                        {
+                            bTblIsValid = FALSE;
+                            break;
+                        }
+
+                        ASSERT( pCell->IsCellFrm(), "Frame ohne Celle" );
+                        if( ::IsFrmInTblSel( pUnion->GetUnion(), pCell ) )
+                        {
+                            SwTableBox* pBox = (SwTableBox*)
+                                ((SwCellFrm*)pCell)->GetTabBox();
+                            // Zellenschutzt beachten ??
+                            if( !bChkProtected ||
+                                !pBox->GetFrmFmt()->GetProtect().IsCntntProtected() )
+                                rBoxes.Insert( pBox );
+                        }
+                        if ( pCell->GetNext() )
+                        {
+                            pCell = (const SwLayoutFrm*)pCell->GetNext();
+                            if ( pCell->Lower()->IsRowFrm() )
+                                pCell = pCell->FirstCell();
+                        }
+                        else
+                            pCell = ::lcl_FindNextCellFrm( pCell );
+                    }
+                }
+                pRow = (const SwLayoutFrm*)pRow->GetNext();
+            }
+        }
+
+        if( bTblIsValid )
+            break;
+
+        // ansonsten das Layout der Tabelle kurz "kalkulieren" lassen
+        // und nochmals neu aufsetzen
+
+        for( i = 0; i < aUnions.Count(); ++i )
+        {
+            SwTabFrm *pTable = aUnions[i]->GetTable();
+            if( pTable->IsValid() )
+                pTable->InvalidatePos();
+            pTable->SetONECalcLowers();
+            pTable->Calc();
+            pTable->SetCompletePaint();
+        }
+        i = 0;
+        rBoxes.Remove( i, rBoxes.Count() );
+        --nLoopMax;
+
+    } while( TRUE );
+    ASSERT( nLoopMax, "das Layout der Tabelle wurde nicht valide!" );
+}
+
+
+
+BOOL ChkChartSel( const SwNode& rSttNd, const SwNode& rEndNd,
+                    SwChartLines* pGetCLines )
+{
+    const SwTableNode* pTNd = rSttNd.FindTableNode();
+    if( !pTNd )
+        return FALSE;
+
+    Point aNullPos;
+    SwNodeIndex aIdx( rSttNd );
+    const SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
+    if( !pCNd )
+        pCNd = aIdx.GetNodes().GoNextSection( &aIdx, TRUE, FALSE );
+
+    const SwLayoutFrm *pStart = pCNd ? pCNd->GetFrm( &aNullPos )->GetUpper() : 0;
+    ASSERT( pStart, "ohne Frame geht gar nichts" );
+
+    aIdx = rEndNd;
+    pCNd = aIdx.GetNode().GetCntntNode();
+    if( !pCNd )
+        pCNd = aIdx.GetNodes().GoNextSection( &aIdx, TRUE, FALSE );
+
+    const SwLayoutFrm *pEnd = pCNd ? pCNd->GetFrm( &aNullPos )->GetUpper() : 0;
+    ASSERT( pEnd, "ohne Frame geht gar nichts" );
+
+
+    //Muss ein HeadlineRepeat beachtet werden?
+    const BOOL bRepeat = pTNd->GetTable().IsHeadlineRepeat();
+
+    BOOL bTblIsValid, bValidChartSel;
+    int nLoopMax = 100;     //JP 28.06.99: max 100 loops - Bug 67292
+    do {
+        bTblIsValid = TRUE;
+        bValidChartSel = TRUE;
+
+        USHORT nRowCells = USHRT_MAX;
+
+        //Zuerst lassen wir uns die Tabellen und die Rechtecke heraussuchen.
+        SwSelUnions aUnions;
+        ::MakeSelUnions( aUnions, pStart, pEnd, TBLSEARCH_NO_UNION_CORRECT );
+
+        //Jetzt zu jedem Eintrag die Boxen herausfischen und uebertragen.
+        for( USHORT i = 0; i < aUnions.Count() && bTblIsValid &&
+                                    bValidChartSel; ++i )
+        {
+            SwSelUnion *pUnion = aUnions[i];
+            const SwTabFrm *pTable = pUnion->GetTable();
+
+            if( !pTable->IsValid() && nLoopMax  )
+            {
+                bTblIsValid = FALSE;
+                break;
+            }
+
+            _Sort_CellFrms aCellFrms;
+
+            const SwLayoutFrm *pRow = (const SwLayoutFrm*)pTable->Lower();
+            //Wenn die Row eine wiederholte Headline ist wird sie nicht
+            //beachtet.
+            if( bRepeat && pTable->IsFollow() )
+                pRow = (const SwLayoutFrm*)pRow->GetNext();
+
+            while( pRow && bTblIsValid && bValidChartSel )
+            {
+                if( !pRow->IsValid() && nLoopMax )
+                {
+                    bTblIsValid = FALSE;
+                    break;
+                }
+
+                if( pRow->Frm().IsOver( pUnion->GetUnion() ) )
+                {
+                    const SwLayoutFrm *pCell = pRow->FirstCell();
+
+                    while( bValidChartSel && bTblIsValid && pCell &&
+                            pRow->IsAnLower( pCell ) )
+                    {
+                        if( !pCell->IsValid() && nLoopMax  )
+                        {
+                            bTblIsValid = FALSE;
+                            break;
+                        }
+
+                        ASSERT( pCell->IsCellFrm(), "Frame ohne Celle" );
+                        const SwRect& rUnion = pUnion->GetUnion(),
+                                    & rFrmRect = pCell->Frm();
+
+                        const long nUnionRight = rUnion.Right();
+                        const long nUnionBottom = rUnion.Bottom();
+                        const long nFrmRight = rFrmRect.Right();
+                        const long nFrmBottom = rFrmRect.Bottom();
+
+                        // liegt das FrmRect ausserhalb der Union, kann es
+                        // ignoriert werden.
+                        if( !(  rUnion.Top() > nFrmBottom ||
+                                nUnionBottom < rFrmRect.Top() ||
+                                rUnion.Left() + 20 > nFrmRight ||
+                                nUnionRight < rFrmRect.Left() + 20 ))
+                        {
+                            // wenn es aber nicht komplett in der Union liegt,
+                            // dann ist es fuers Chart eine ungueltige
+                            // Selektion.
+                            if( rUnion.Left()   <= rFrmRect.Left() + 20 &&
+                                rFrmRect.Left() <= nUnionRight &&
+                                rUnion.Left()   <= nFrmRight &&
+                                nFrmRight       <= nUnionRight + 20 &&
+                                rUnion.Top()    <= rFrmRect.Top() &&
+                                rFrmRect.Top()  <= nUnionBottom &&
+                                rUnion.Top()    <= nFrmBottom &&
+                                nFrmBottom      <= nUnionBottom )
+
+                                aCellFrms.Insert(
+                                        _Sort_CellFrm( *(SwCellFrm*)pCell ),
+                                        aCellFrms.Count() );
+                            else
+                            {
+                                bValidChartSel = FALSE;
+                                break;
+                            }
+                        }
+                        if ( pCell->GetNext() )
+                        {
+                            pCell = (const SwLayoutFrm*)pCell->GetNext();
+                            if ( pCell->Lower()->IsRowFrm() )
+                                pCell = pCell->FirstCell();
+                        }
+                        else
+                            pCell = ::lcl_FindNextCellFrm( pCell );
+                    }
+                }
+                pRow = (const SwLayoutFrm*)pRow->GetNext();
+            }
+
+            if( !bValidChartSel )
+                break;
+
+            // alle Zellen der (Teil-)Tabelle zusammen. Dann teste mal ob
+            // all huebsch nebeneinander liegen.
+            USHORT n, nEnd, nCellCnt = 0;
+            long nYPos = LONG_MAX, nXPos, nHeight;
+
+            for( n = 0, nEnd = aCellFrms.Count(); n < nEnd; ++n )
+            {
+                const _Sort_CellFrm& rCF = aCellFrms[ n ];
+                if( rCF.pFrm->Frm().Top() != nYPos )
+                {
+                    // neue Zeile
+                    if( n )
+                    {
+                        if( USHRT_MAX == nRowCells )        // 1. Zeilenwechsel
+                            nRowCells = nCellCnt;
+                        else if( nRowCells != nCellCnt )
+                        {
+                            bValidChartSel = FALSE;
+                            break;
+                        }
+                    }
+                    nCellCnt = 1;
+                    nYPos = rCF.pFrm->Frm().Top();
+                    nHeight = rCF.pFrm->Frm().Height();
+                    nXPos = rCF.pFrm->Frm().Left() + rCF.pFrm->Frm().Width();
+                }
+                else if( nXPos == rCF.pFrm->Frm().Left() &&
+                         nHeight == rCF.pFrm->Frm().Height() )
+                {
+                    nXPos += rCF.pFrm->Frm().Width();
+                    ++nCellCnt;
+                }
+                else
+                {
+                    bValidChartSel = FALSE;
+                    break;
+                }
+            }
+            if( bValidChartSel )
+            {
+                if( USHRT_MAX == nRowCells )
+                    nRowCells = nCellCnt;
+                else if( nRowCells != nCellCnt )
+                    bValidChartSel = FALSE;
+            }
+
+            if( bValidChartSel && pGetCLines )
+            {
+                nYPos = LONG_MAX;
+                SwChartBoxes* pBoxes;
+                for( n = 0, nEnd = aCellFrms.Count(); n < nEnd; ++n )
+                {
+                    const _Sort_CellFrm& rCF = aCellFrms[ n ];
+                    if( rCF.pFrm->Frm().Top() != nYPos )
+                    {
+                        pBoxes = new SwChartBoxes( 255 < nRowCells
+                                                    ? 255 : (BYTE)nRowCells);
+                        pGetCLines->C40_INSERT( SwChartBoxes, pBoxes, pGetCLines->Count() );
+                        nYPos = rCF.pFrm->Frm().Top();
+                    }
+                    SwTableBoxPtr pBox = (SwTableBox*)rCF.pFrm->GetTabBox();
+                    pBoxes->Insert( pBox, pBoxes->Count() );
+                }
+            }
+        }
+
+        if( bTblIsValid )
+            break;
+
+        // ansonsten das Layout der Tabelle kurz "kalkulieren" lassen
+        // und nochmals neu aufsetzen
+        for( i = 0; i < aUnions.Count(); ++i )
+        {
+            SwTabFrm *pTable = aUnions[i]->GetTable();
+            if( pTable->IsValid() )
+                pTable->InvalidatePos();
+            pTable->SetONECalcLowers();
+            pTable->Calc();
+            pTable->SetCompletePaint();
+        }
+        --nLoopMax;
+        if( pGetCLines )
+            pGetCLines->DeleteAndDestroy( 0, pGetCLines->Count() );
+    } while( TRUE );
+
+    ASSERT( nLoopMax, "das Layout der Tabelle wurde nicht valide!" );
+
+    if( !bValidChartSel && pGetCLines )
+        pGetCLines->DeleteAndDestroy( 0, pGetCLines->Count() );
+
+    return bValidChartSel;
+}
+
+
+BOOL IsFrmInTblSel( const SwRect& rUnion, const SwFrm* pCell )
+{
+    return (
+        rUnion.Top() <= pCell->Frm().Top() &&
+        rUnion.Bottom() >= pCell->Frm().Bottom() &&
+
+        (( rUnion.Left() <= pCell->Frm().Left()+20 &&
+           rUnion.Right() > pCell->Frm().Left() ) ||
+
+         ( rUnion.Left() >= pCell->Frm().Left() &&
+           rUnion.Right() < pCell->Frm().Right() )) ? TRUE : FALSE );
+}
+
+BOOL GetAutoSumSel( const SwCrsrShell& rShell, SwCellFrms& rBoxes )
+{
+    SwShellCrsr *pCrsr = (SwShellCrsr*) rShell.IsTableMode() ?
+                          rShell.pTblCrsr : rShell.pCurCrsr;
+
+    const SwLayoutFrm *pStart = pCrsr->GetCntntNode()->GetFrm(
+                      &pCrsr->GetPtPos() )->GetUpper(),
+                      *pEnd   = pCrsr->GetCntntNode(FALSE)->GetFrm(
+                      &pCrsr->GetMkPos() )->GetUpper();
+
+    //Muss ein HeadlineRepeat beachtet werden?
+    const BOOL bRepeat = pStart->FindTabFrm()->GetTable()->IsHeadlineRepeat();
+
+    const SwLayoutFrm* pSttCell = pStart;
+    while( pSttCell && !pSttCell->IsCellFrm() )
+        pSttCell = pSttCell->GetUpper();
+
+    //Zuerst lassen wir uns die Tabellen und die Rechtecke heraussuchen.
+    SwSelUnions aUnions;
+
+    // default erstmal nach oben testen, dann nach links
+    ::MakeSelUnions( aUnions, pStart, pEnd, TBLSEARCH_COL );
+
+    BOOL bTstRow = TRUE, bFound = FALSE;
+    USHORT i;
+
+    // 1. teste ob die darueber liegende Box Value/Formel enhaelt:
+    for( i = 0; i < aUnions.Count(); ++i )
+    {
+        SwSelUnion *pUnion = aUnions[i];
+        const SwTabFrm *pTable = pUnion->GetTable();
+
+        const SwLayoutFrm *pRow = (const SwLayoutFrm*)pTable->Lower();
+        //Wenn die Row eine wiederholte Headline ist wird sie nicht
+        //beachtet.
+        if( bRepeat && pTable->IsFollow() )
+            pRow = (const SwLayoutFrm*)pRow->GetNext();
+
+        while( pRow )
+        {
+            if( pRow->Frm().IsOver( pUnion->GetUnion() ) )
+            {
+                const SwCellFrm* pUpperCell = 0;
+                const SwLayoutFrm *pCell = pRow->FirstCell();
+
+                while( pCell && pRow->IsAnLower( pCell ) )
+                {
+                    if( pCell == pSttCell )
+                    {
+                        USHORT nWhichId = 0;
+                        for( USHORT n = rBoxes.Count(); n; )
+                            if( USHRT_MAX != ( nWhichId = rBoxes[ --n ]
+                                ->GetTabBox()->IsFormulaOrValueBox() ))
+                                break;
+
+                        // alle Boxen zusammen, nicht mehr die Zeile
+                        // pruefen, wenn eine Formel oder Value gefunden wurde
+                        bTstRow = 0 == nWhichId || USHRT_MAX == nWhichId;
+                        bFound = TRUE;
+                        break;
+                    }
+
+                    ASSERT( pCell->IsCellFrm(), "Frame ohne Celle" );
+                    if( ::IsFrmInTblSel( pUnion->GetUnion(), pCell ) )
+                        pUpperCell = (SwCellFrm*)pCell;
+
+                    if( pCell->GetNext() )
+                    {
+                        pCell = (const SwLayoutFrm*)pCell->GetNext();
+                        if ( pCell->Lower()->IsRowFrm() )
+                            pCell = pCell->FirstCell();
+                    }
+                    else
+                        pCell = ::lcl_FindNextCellFrm( pCell );
+                }
+
+                if( pUpperCell )
+                    rBoxes.Insert( pUpperCell, rBoxes.Count() );
+            }
+            if( bFound )
+            {
+                i = aUnions.Count();
+                break;
+            }
+            pRow = (const SwLayoutFrm*)pRow->GetNext();
+        }
+    }
+
+
+    // 2. teste ob die links liegende Box Value/Formel enhaelt:
+    if( bTstRow )
+    {
+        bFound = FALSE;
+
+        rBoxes.Remove( 0, rBoxes.Count() );
+        aUnions.DeleteAndDestroy( 0, aUnions.Count() );
+        ::MakeSelUnions( aUnions, pStart, pEnd, TBLSEARCH_ROW );
+
+        for( i = 0; i < aUnions.Count(); ++i )
+        {
+            SwSelUnion *pUnion = aUnions[i];
+            const SwTabFrm *pTable = pUnion->GetTable();
+
+            const SwLayoutFrm *pRow = (const SwLayoutFrm*)pTable->Lower();
+            //Wenn die Row eine wiederholte Headline ist wird sie nicht
+            //beachtet.
+            if( bRepeat && pTable->IsFollow() )
+                pRow = (const SwLayoutFrm*)pRow->GetNext();
+
+            while( pRow )
+            {
+                if( pRow->Frm().IsOver( pUnion->GetUnion() ) )
+                {
+                    const SwLayoutFrm *pCell = pRow->FirstCell();
+
+                    while( pCell && pRow->IsAnLower( pCell ) )
+                    {
+                        if( pCell == pSttCell )
+                        {
+                            USHORT nWhichId = 0;
+                            for( USHORT n = rBoxes.Count(); n; )
+                                if( USHRT_MAX != ( nWhichId = rBoxes[ --n ]
+                                    ->GetTabBox()->IsFormulaOrValueBox() ))
+                                    break;
+
+                            // alle Boxen zusammen, nicht mehr die Zeile
+                            // pruefen, wenn eine Formel oder Value gefunden wurde
+                            bFound = 0 != nWhichId && USHRT_MAX != nWhichId;
+                            bTstRow = FALSE;
+                            break;
+                        }
+
+                        ASSERT( pCell->IsCellFrm(), "Frame ohne Celle" );
+                        if( ::IsFrmInTblSel( pUnion->GetUnion(), pCell ) )
+                        {
+                            const SwCellFrm* pC = (SwCellFrm*)pCell;
+                            rBoxes.Insert( pC, rBoxes.Count() );
+                        }
+                        if( pCell->GetNext() )
+                        {
+                            pCell = (const SwLayoutFrm*)pCell->GetNext();
+                            if ( pCell->Lower()->IsRowFrm() )
+                                pCell = pCell->FirstCell();
+                        }
+                        else
+                            pCell = ::lcl_FindNextCellFrm( pCell );
+                    }
+                }
+                if( !bTstRow )
+                {
+                    i = aUnions.Count();
+                    break;
+                }
+
+                pRow = (const SwLayoutFrm*)pRow->GetNext();
+            }
+        }
+    }
+
+    return bFound;
+}
+
+BOOL HasProtectedCells( const SwSelBoxes& rBoxes )
+{
+    BOOL bRet = FALSE;
+    for( USHORT n = 0, nCnt = rBoxes.Count(); n < nCnt; ++n )
+        if( rBoxes[ n ]->GetFrmFmt()->GetProtect().IsCntntProtected() )
+        {
+            bRet = TRUE;
+            break;
+        }
+    return bRet;
+}
+
+
+_CmpLPt::_CmpLPt( const Point& rPt, const SwTableBox* pBox )
+    : pPos( &rPt ), pSelBox( pBox )
+{}
+
+void lcl_InsTblBox( SwTableNode* pTblNd, SwDoc* pDoc, SwTableBox* pBox,
+                        USHORT nInsPos, USHORT nCnt = 1 )
+{
+    ASSERT( pBox->GetSttNd(), "Box ohne Start-Node" );
+    SwCntntNode* pCNd = pDoc->GetNodes()[ pBox->GetSttIdx() + 1 ]
+                                ->GetCntntNode();
+    if( pCNd && pCNd->IsTxtNode() )
+        pDoc->GetNodes().InsBoxen( pTblNd, pBox->GetUpper(),
+                (SwTableBoxFmt*)pBox->GetFrmFmt(),
+                ((SwTxtNode*)pCNd)->GetTxtColl(),
+                pCNd->GetpSwAttrSet(),
+                nInsPos, nCnt );
+    else
+        pDoc->GetNodes().InsBoxen( pTblNd, pBox->GetUpper(),
+                (SwTableBoxFmt*)pBox->GetFrmFmt(),
+                (SwTxtFmtColl*)pDoc->GetDfltTxtFmtColl(), 0,
+                nInsPos, nCnt );
+}
+
+BOOL lcl_IsEmptyBox( const SwTableBox& rBox, SwPaM& rPam )
+{
+    rPam.GetPoint()->nNode = *rBox.GetSttNd()->EndOfSectionNode();
+    rPam.Move( fnMoveBackward, fnGoCntnt );
+    rPam.SetMark();
+    rPam.GetPoint()->nNode = *rBox.GetSttNd();
+    rPam.Move( fnMoveForward, fnGoCntnt );
+
+    BOOL bRet = *rPam.GetMark() == *rPam.GetPoint();
+    if( bRet )
+    {
+        // dann teste mal auf absatzgebundenen Flys
+        const SwSpzFrmFmts& rFmts = *rPam.GetDoc()->GetSpzFrmFmts();
+        ULONG nSttIdx = rPam.GetPoint()->nNode.GetIndex(),
+              nEndIdx = rBox.GetSttNd()->EndOfSectionIndex(),
+              nIdx;
+
+        for( USHORT n = 0; n < rFmts.Count(); ++n )
+        {
+            const SwPosition* pAPos;
+            const SwFmtAnchor& rAnchor = rFmts[n]->GetAnchor();
+            if( ( FLY_AT_CNTNT == rAnchor.GetAnchorId() ||
+                  FLY_AUTO_CNTNT == rAnchor.GetAnchorId() ) &&
+                0 != ( pAPos = rAnchor.GetCntntAnchor() ) &&
+                nSttIdx <= ( nIdx = pAPos->nNode.GetIndex() ) &&
+                nIdx < nEndIdx )
+            {
+                bRet = FALSE;
+                break;
+            }
+        }
+    }
+    return bRet;
+}
+
+
+void GetMergeSel( const SwPaM& rPam, SwSelBoxes& rBoxes,
+                SwTableBox** ppMergeBox, SwUndoTblMerge* pUndo )
+{
+    if( rBoxes.Count() )
+        rBoxes.Remove( USHORT(0), rBoxes.Count() );
+
+    //Zuerst lassen wir uns die Tabellen und die Rechtecke heraussuchen.
+    ASSERT( rPam.GetCntntNode() && rPam.GetCntntNode( FALSE ),
+            "Tabselection nicht auf Cnt." );
+
+//JP 24.09.96: Merge mit wiederholenden TabellenHeadline funktioniert nicht
+//              richtig. Warum nicht Point 0,0 benutzen? Dann ist garantiert,
+//              das die 1. Headline mit drin ist.
+//  Point aPt( rShell.GetCharRect().Pos() );
+    Point aPt( 0, 0 );
+    const SwLayoutFrm *pStart = rPam.GetCntntNode()->GetFrm(
+                                                        &aPt )->GetUpper(),
+                      *pEnd = rPam.GetCntntNode(FALSE)->GetFrm(
+                                                        &aPt )->GetUpper();
+
+    SwSelUnions aUnions;
+    ::MakeSelUnions( aUnions, pStart, pEnd );
+    if( !aUnions.Count() )
+        return;
+
+    const SwTable *pTable = aUnions[0]->GetTable()->GetTable();
+    SwDoc* pDoc = (SwDoc*)pStart->GetFmt()->GetDoc();
+    SwTableNode* pTblNd = (SwTableNode*)pTable->GetTabSortBoxes()[ 0 ]->
+                                        GetSttNd()->FindTableNode();
+
+    _MergePos aPosArr;      // Sort-Array mit den Positionen der Frames
+    long nWidth;
+    SwTableBox* pLastBox = 0;
+
+    for ( USHORT i = 0; i < aUnions.Count(); ++i )
+    {
+        const SwTabFrm *pTabFrm = aUnions[i]->GetTable();
+        SwRect &rUnion = aUnions[i]->GetUnion();
+        const SwLayoutFrm *pRow = (const SwLayoutFrm*)pTabFrm->Lower();
+        if ( pRow && pTabFrm->IsFollow() && pTable->IsHeadlineRepeat() )
+            pRow = (SwLayoutFrm*)pRow->GetNext();
+
+        while ( pRow )
+        {
+            if ( pRow->Frm().IsOver( rUnion ) )
+            {
+                const SwLayoutFrm *pCell = pRow->FirstCell();
+//              while ( !pCell->IsCellFrm() )
+//                  pCell = pCell->GetUpper();
+
+                while ( pCell && pRow->IsAnLower( pCell ) )
+                {
+                    ASSERT( pCell->IsCellFrm(), "Frame ohne Celle" );
+                        // in der vollen Breite ueberlappend ?
+                    if( rUnion.Top() <= pCell->Frm().Top() &&
+                        rUnion.Bottom() >= pCell->Frm().Bottom() )
+                    {
+                        SwTableBox* pBox =(SwTableBox*)((SwCellFrm*)pCell)->GetTabBox();
+
+                        // nur nach rechts ueberlappend
+                        if( ( rUnion.Left() - COLFUZZY ) <= pCell->Frm().Left() &&
+                            ( rUnion.Right() - COLFUZZY ) > pCell->Frm().Left() )
+                        {
+                            if( ( rUnion.Right() + COLFUZZY ) < pCell->Frm().Right() )
+                            {
+                                USHORT nInsPos = pBox->GetUpper()->
+                                                    GetTabBoxes().C40_GETPOS( SwTableBox, pBox )+1;
+                                lcl_InsTblBox( pTblNd, pDoc, pBox, nInsPos );
+                                pBox->ClaimFrmFmt();
+                                SwFmtFrmSize aNew(
+                                        pBox->GetFrmFmt()->GetFrmSize() );
+                                nWidth = rUnion.Right() - pCell->Frm().Left();
+                                nWidth = nWidth * aNew.GetWidth() /
+                                         pCell->Frm().Width();
+                                long nTmpWidth = aNew.GetWidth() - nWidth;
+                                aNew.SetWidth( nWidth );
+                                pBox->GetFrmFmt()->SetAttr( aNew );
+                                // diese Box ist selektiert
+                                pLastBox = pBox;
+                                rBoxes.Insert( pBox );
+                                aPosArr.Insert( _CmpLPt( pCell->Frm().Pos(), pBox ));
+
+                                pBox = pBox->GetUpper()->GetTabBoxes()[ nInsPos ];
+                                aNew.SetWidth( nTmpWidth );
+                                pBox->ClaimFrmFmt();
+                                pBox->GetFrmFmt()->SetAttr( aNew );
+
+                                if( pUndo )
+                                    pUndo->AddNewBox( pBox->GetSttIdx() );
+                            }
+                            else
+                            {
+                                // diese Box ist selektiert
+                                pLastBox = pBox;
+                                rBoxes.Insert( pBox );
+                                aPosArr.Insert( _CmpLPt( pCell->Frm().Pos(), pBox ));
+                            }
+                        }
+                        // oder rechts und links ueberlappend
+                        else if( ( rUnion.Left() - COLFUZZY ) >= pCell->Frm().Left() &&
+                                ( rUnion.Right() + COLFUZZY ) < pCell->Frm().Right() )
+                        {
+                            USHORT nInsPos = pBox->GetUpper()->GetTabBoxes().
+                                            C40_GETPOS( SwTableBox, pBox )+1;
+                            lcl_InsTblBox( pTblNd, pDoc, pBox, nInsPos, 2 );
+                            pBox->ClaimFrmFmt();
+                            SwFmtFrmSize aNew(
+                                        pBox->GetFrmFmt()->GetFrmSize() );
+                            long nLeft = rUnion.Left() - pCell->Frm().Left();
+                            nLeft = nLeft * aNew.GetWidth() /
+                                    pCell->Frm().Width();
+                            long nRight = pCell->Frm().Right() - rUnion.Right();
+                            nRight = nRight * aNew.GetWidth() /
+                                     pCell->Frm().Width();
+                            nWidth = aNew.GetWidth() - nLeft - nRight;
+
+                            aNew.SetWidth( nLeft );
+                            pBox->GetFrmFmt()->SetAttr( aNew );
+
+                            {
+                            const SfxPoolItem* pItem;
+                            if( SFX_ITEM_SET == pBox->GetFrmFmt()->GetAttrSet()
+                                        .GetItemState( RES_BOX, FALSE, &pItem ))
+                            {
+                                SvxBoxItem aBox( *(SvxBoxItem*)pItem );
+                                aBox.SetLine( 0, BOX_LINE_RIGHT );
+                                pBox->GetFrmFmt()->SetAttr( aBox );
+                            }
+                            }
+
+                            pBox = pBox->GetUpper()->GetTabBoxes()[ nInsPos ];
+                            aNew.SetWidth( nWidth );
+                            pBox->ClaimFrmFmt();
+                            pBox->GetFrmFmt()->SetAttr( aNew );
+
+                            if( pUndo )
+                                pUndo->AddNewBox( pBox->GetSttIdx() );
+
+                            // diese Box ist selektiert
+                            pLastBox = pBox;
+                            rBoxes.Insert( pBox );
+                            aPosArr.Insert( _CmpLPt( pCell->Frm().Pos(), pBox ));
+
+                            pBox = pBox->GetUpper()->GetTabBoxes()[ nInsPos+1 ];
+                            aNew.SetWidth( nRight );
+                            pBox->ClaimFrmFmt();
+                            pBox->GetFrmFmt()->SetAttr( aNew );
+
+                            if( pUndo )
+                                pUndo->AddNewBox( pBox->GetSttIdx() );
+                        }
+                        // oder reicht die rechte Kante der Box in den
+                        // selektierten Bereich?
+                        else if( ( pCell->Frm().Right() - COLFUZZY ) < rUnion.Right() &&
+                                 ( pCell->Frm().Right() - COLFUZZY ) > rUnion.Left() &&
+                                 ( pCell->Frm().Left() + COLFUZZY ) < rUnion.Left() )
+                        {
+                            // dann muss eine neue Box einfuegt und die
+                            // Breiten angepasst werden
+                            USHORT nInsPos = pBox->GetUpper()->GetTabBoxes().
+                                            C40_GETPOS( SwTableBox, pBox )+1;
+                            lcl_InsTblBox( pTblNd, pDoc, pBox, nInsPos, 1 );
+
+                            SwFmtFrmSize aNew(pBox->GetFrmFmt()->GetFrmSize() );
+                            long nLeft = rUnion.Left() - pCell->Frm().Left(),
+                                nRight = pCell->Frm().Right() - rUnion.Left();
+
+                            nLeft = nLeft * aNew.GetWidth() /
+                                    pCell->Frm().Width();
+                            nRight = nRight * aNew.GetWidth() /
+                                    pCell->Frm().Width();
+
+                            aNew.SetWidth( nLeft );
+                            pBox->ClaimFrmFmt()->SetAttr( aNew );
+
+                                // diese Box ist selektiert
+                            pBox = pBox->GetUpper()->GetTabBoxes()[ nInsPos ];
+                            aNew.SetWidth( nRight );
+                            pBox->ClaimFrmFmt();
+                            pBox->GetFrmFmt()->SetAttr( aNew );
+
+                            pLastBox = pBox;
+                            rBoxes.Insert( pBox );
+                            aPosArr.Insert( _CmpLPt( Point( rUnion.Left(),
+                                                pCell->Frm().Top()), pBox ));
+
+                            if( pUndo )
+                                pUndo->AddNewBox( pBox->GetSttIdx() );
+                        }
+                    }
+                    if ( pCell->GetNext() )
+                    {
+                        pCell = (const SwLayoutFrm*)pCell->GetNext();
+                        if ( pCell->Lower()->IsRowFrm() )
+                            pCell = pCell->FirstCell();
+                    }
+                    else
+                        pCell = ::lcl_FindNextCellFrm( pCell );
+                }
+            }
+            pRow = (const SwLayoutFrm*)pRow->GetNext();
+        }
+    }
+
+    // keine SSelection / keine gefundenen Boxen
+    if( 1 >= rBoxes.Count() )
+        return;
+
+    // dann suche mal alle Boxen, die nebeneinander liegen, und verbinde
+    // deren Inhalte mit Blanks. Alle untereinander liegende werden als
+    // Absaetze zusammengefasst
+
+    // 1. Loesung: gehe ueber das Array und
+    //      alle auf der gleichen Y-Ebene werden mit Blanks getrennt
+    //      alle anderen werden als Absaetze getrennt.
+    BOOL bCalcWidth = TRUE;
+    const SwTableBox* pFirstBox = aPosArr[ 0 ].pSelBox;
+
+    // JP 27.03.98:  Optimierung - falls die Boxen einer Line leer sind,
+    //              dann werden jetzt dafuer keine Blanks und
+    //              kein Umbruch mehr eingefuegt.
+    //Block damit SwPaM, SwPosition vom Stack geloescht werden
+    {
+        SwPaM aPam( pDoc->GetNodes() );
+
+#if defined( DEL_ONLY_EMPTY_LINES )
+        nWidth = pFirstBox->GetFrmFmt()->GetFrmSize().GetWidth();
+        BOOL bEmptyLine = TRUE;
+        USHORT n, nSttPos = 0;
+
+        for( n = 0; n < aPosArr.Count(); ++n )
+        {
+            const _CmpLPt& rPt = aPosArr[ n ];
+            if( n && aPosArr[ n - 1 ].Y() == rPt.Y() )  // gleiche Ebene ?
+            {
+                if( bEmptyLine && !lcl_IsEmptyBox( *rPt.pSelBox, aPam ))
+                    bEmptyLine = FALSE;
+                if( bCalcWidth )
+                    nWidth += rPt.pSelBox->GetFrmFmt()->GetFrmSize().GetWidth();
+            }
+            else
+            {
+                if( bCalcWidth && n )
+                    bCalcWidth = FALSE;     // eine Zeile fertig
+
+                if( bEmptyLine && nSttPos < n )
+                {
+                    // dann ist die gesamte Line leer und braucht
+                    // nicht mit Blanks aufgefuellt und als Absatz
+                    // eingefuegt werden.
+                    if( pUndo )
+                        for( USHORT i = nSttPos; i < n; ++i )
+                            pUndo->SaveCollection( *aPosArr[ i ].pSelBox );
+
+                    aPosArr.Remove( nSttPos, n - nSttPos );
+                    n = nSttPos;
+                }
+                else
+                    nSttPos = n;
+
+                bEmptyLine = lcl_IsEmptyBox( *aPosArr[n].pSelBox, aPam );
+            }
+        }
+        if( bEmptyLine && nSttPos < n )
+        {
+            if( pUndo )
+                for( USHORT i = nSttPos; i < n; ++i )
+                    pUndo->SaveCollection( *aPosArr[ i ].pSelBox );
+            aPosArr.Remove( nSttPos, n - nSttPos );
+        }
+#elsif defined( DEL_EMPTY_BOXES_AT_START_AND_END )
+
+        nWidth = pFirstBox->GetFrmFmt()->GetFrmSize().GetWidth();
+        USHORT n, nSttPos = 0, nSEndPos = 0, nESttPos = 0;
+
+        for( n = 0; n < aPosArr.Count(); ++n )
+        {
+            const _CmpLPt& rPt = aPosArr[ n ];
+            if( n && aPosArr[ n - 1 ].Y() == rPt.Y() )  // gleiche Ebene ?
+            {
+                BOOL bEmptyBox = lcl_IsEmptyBox( *rPt.pSelBox, aPam );
+                if( bEmptyBox )
+                {
+                    if( nSEndPos == n )     // der Anfang ist leer
+                        nESttPos = ++nSEndPos;
+                }
+                else                        // das Ende kann leer sein
+                    nESttPos = n+1;
+
+                if( bCalcWidth )
+                    nWidth += rPt.pSelBox->GetFrmFmt()->GetFrmSize().GetWidth();
+            }
+            else
+            {
+                if( bCalcWidth && n )
+                    bCalcWidth = FALSE;     // eine Zeile fertig
+
+                // zuerst die vom Anfang
+                if( nSttPos < nSEndPos )
+                {
+                    // dann ist der vorder Teil der Line leer und braucht
+                    // nicht mit Blanks aufgefuellt werden.
+                    if( pUndo )
+                        for( USHORT i = nSttPos; i < nSEndPos; ++i )
+                            pUndo->SaveCollection( *aPosArr[ i ].pSelBox );
+
+                    USHORT nCnt = nSEndPos - nSttPos;
+                    aPosArr.Remove( nSttPos, nCnt );
+                    nESttPos -= nCnt;
+                    n -= nCnt;
+                }
+
+                if( nESttPos < n )
+                {
+                    // dann ist der vorder Teil der Line leer und braucht
+                    // nicht mit Blanks aufgefuellt werden.
+                    if( pUndo )
+                        for( USHORT i = nESttPos; i < n; ++i )
+                            pUndo->SaveCollection( *aPosArr[ i ].pSelBox );
+
+                    USHORT nCnt = n - nESttPos;
+                    aPosArr.Remove( nESttPos, nCnt );
+                    n -= nCnt;
+                }
+
+                nSttPos = nSEndPos = nESttPos = n;
+                if( lcl_IsEmptyBox( *aPosArr[n].pSelBox, aPam ))
+                    ++nSEndPos;
+                else
+                    ++nESttPos;
+            }
+        }
+
+        // zuerst die vom Anfang
+        if( nSttPos < nSEndPos )
+        {
+            // dann ist der vorder Teil der Line leer und braucht
+            // nicht mit Blanks aufgefuellt werden.
+            if( pUndo )
+                for( USHORT i = nSttPos; i < nSEndPos; ++i )
+                    pUndo->SaveCollection( *aPosArr[ i ].pSelBox );
+
+            USHORT nCnt = nSEndPos - nSttPos;
+            aPosArr.Remove( nSttPos, nCnt );
+            nESttPos -= nCnt;
+            n -= nCnt;
+        }
+        if( nESttPos < n )
+        {
+            // dann ist der vorder Teil der Line leer und braucht
+            // nicht mit Blanks aufgefuellt werden.
+            if( pUndo )
+                for( USHORT i = nESttPos; i < n; ++i )
+                    pUndo->SaveCollection( *aPosArr[ i ].pSelBox );
+
+            USHORT nCnt = n - nESttPos;
+            aPosArr.Remove( nESttPos, nCnt );
+        }
+#else
+// DEL_ALL_EMPTY_BOXES
+
+        nWidth = 0;
+        long nY = aPosArr.Count() ? aPosArr[ 0 ].Y() : 0;
+        for( USHORT n = 0; n < aPosArr.Count(); ++n )
+        {
+            const _CmpLPt& rPt = aPosArr[ n ];
+            if( bCalcWidth )
+            {
+                if( nY == rPt.Y() )         // gleiche Ebene ?
+                    nWidth += rPt.pSelBox->GetFrmFmt()->GetFrmSize().GetWidth();
+                else
+                    bCalcWidth = FALSE;     // eine Zeile fertig
+            }
+
+            if( lcl_IsEmptyBox( *rPt.pSelBox, aPam ) )
+            {
+                if( pUndo )
+                    pUndo->SaveCollection( *rPt.pSelBox );
+
+                aPosArr.Remove( n, 1 );
+                --n;
+            }
+        }
+#endif
+    }
+
+    // lege schon mal die neue Box an
+    {
+        SwTableBox* pTmpBox = rBoxes[0];
+        SwTableLine* pInsLine = pTmpBox->GetUpper();
+        USHORT nInsPos = pInsLine->GetTabBoxes().C40_GETPOS( SwTableBox, pTmpBox );
+
+        lcl_InsTblBox( pTblNd, pDoc, pTmpBox, nInsPos );
+        (*ppMergeBox) = pInsLine->GetTabBoxes()[ nInsPos ];
+        pInsLine->GetTabBoxes().Remove( nInsPos );      // wieder austragen
+        (*ppMergeBox)->SetUpper( 0 );
+        (*ppMergeBox)->ClaimFrmFmt();
+
+        // setze die Umrandung: von der 1. Box die linke/obere von der
+        // letzten Box die rechte/untere Kante:
+        if( pLastBox && pFirstBox )
+        {
+            SvxBoxItem aBox( pFirstBox->GetFrmFmt()->GetBox() );
+            const SvxBoxItem& rBox = pLastBox->GetFrmFmt()->GetBox();
+            aBox.SetLine( rBox.GetRight(), BOX_LINE_RIGHT );
+            aBox.SetLine( rBox.GetBottom(), BOX_LINE_BOTTOM );
+            if( aBox.GetLeft() || aBox.GetTop() ||
+                aBox.GetRight() || aBox.GetBottom() )
+                (*ppMergeBox)->GetFrmFmt()->SetAttr( aBox );
+        }
+    }
+
+    //Block damit SwPaM, SwPosition vom Stack geloescht werden
+    if( aPosArr.Count() )
+    {
+        SwTxtNode* pTxtNd;
+        SwPosition aInsPos( *(*ppMergeBox)->GetSttNd() );
+        SwNodeIndex& rInsPosNd = aInsPos.nNode;
+
+        SwPaM aPam( aInsPos );
+
+        for( USHORT n = 0; n < aPosArr.Count(); ++n )
+        {
+            const _CmpLPt& rPt = aPosArr[ n ];
+            aPam.GetPoint()->nNode.Assign( *rPt.pSelBox->GetSttNd()->
+                                            EndOfSectionNode(), -1 );
+            SwCntntNode* pCNd = aPam.GetCntntNode();
+            USHORT nL = pCNd ? pCNd->Len() : 0;
+            aPam.GetPoint()->nContent.Assign( pCNd, nL );
+
+            SwNodeIndex aSttNdIdx( *rPt.pSelBox->GetSttNd(), 1 );
+
+            if( n && aPosArr[n-1].Y() == rPt.Y() && pTxtNd &&   // gleiche Ebene ?
+                aSttNdIdx.GetNode().IsTxtNode() )
+            {
+                pTxtNd->Insert( '\x20', aInsPos.nContent );
+                aPam.SetMark();
+                aPam.GetPoint()->nNode = aSttNdIdx;
+                aPam.GetPoint()->nContent.Assign(
+                                aSttNdIdx.GetNode().GetCntntNode(), 0 );
+
+                // alle absatzgebundenen Flys mitnehmen!
+                _SaveFlyArr aSaveFlyArr;
+                SwNodeIndex aIdx( rInsPosNd, -1 );
+                {
+                    SwNodeRange aRg( aPam.GetPoint()->nNode.GetNode(), 0,
+                                *rPt.pSelBox->GetSttNd()->EndOfSectionNode() );
+                    _SaveFlyInRange( aRg, aSaveFlyArr );
+                }
+
+                if( pUndo )
+                    pUndo->MoveBoxCntnt( aPam, aInsPos, aSaveFlyArr );
+                else
+                    pDoc->Move( aPam, aInsPos );
+                aPam.DeleteMark();
+                if( bCalcWidth )
+                    nWidth += rPt.pSelBox->GetFrmFmt()->GetFrmSize().GetWidth();
+
+                if( aSaveFlyArr.Count() )
+                {
+                    aIdx++;
+                    _RestFlyInRange( aSaveFlyArr, aIdx );
+                }
+            }
+            else                                // Nodes moven
+            {
+                // ein Node muss in der Box erhalten bleiben (sonst wird beim
+                // Move die gesamte Section geloescht)
+                if( pUndo )
+                    pDoc->DoUndo( FALSE );
+                pDoc->AppendTxtNode( *aPam.GetPoint() );
+                if( pUndo )
+                    pDoc->DoUndo( TRUE );
+                SwNodeRange aRg( aSttNdIdx, aPam.GetPoint()->nNode );
+                rInsPosNd++;
+                if( pUndo )
+                    pUndo->MoveBoxCntnt( pDoc, aRg, rInsPosNd );
+                else
+                    pDoc->Move( aRg, rInsPosNd );
+                // wo steht jetzt aInsPos ??
+
+                if( bCalcWidth )
+                    bCalcWidth = FALSE;     // eine Zeile fertig
+            }
+
+            // den initialen TextNode ueberspringen
+            rInsPosNd.Assign( pDoc->GetNodes(),
+                            rInsPosNd.GetNode().EndOfSectionIndex() - 2 );
+            pTxtNd = rInsPosNd.GetNode().GetTxtNode();
+            if( pTxtNd )
+                aInsPos.nContent.Assign( pTxtNd, pTxtNd->GetTxt().Len() );
+        }
+
+        // in der MergeBox sollte jetzt der gesamte Text stehen
+        // loesche jetzt noch den initialen TextNode
+        ASSERT( (*ppMergeBox)->GetSttIdx()+2 <
+                (*ppMergeBox)->GetSttNd()->EndOfSectionIndex(),
+                    "leere Box" );
+        SwNodeIndex aIdx( *(*ppMergeBox)->GetSttNd()->EndOfSectionNode(), -1 );
+        pDoc->GetNodes().Delete( aIdx, 1 );
+    }
+
+    // setze die Breite der Box
+    (*ppMergeBox)->GetFrmFmt()->SetAttr( SwFmtFrmSize( ATT_VAR_SIZE, nWidth, 0 ));
+    if( pUndo )
+        pUndo->AddNewBox( (*ppMergeBox)->GetSttIdx() );
+}
+
+
+BOOL lcl_CheckCol( const _FndBox*& rpFndBox, void* pPara );
+
+BOOL lcl_CheckRow( const _FndLine*& rpFndLine, void* pPara )
+{
+    ((_FndLine*)rpFndLine)->GetBoxes().ForEach( &lcl_CheckCol, pPara );
+    return *(BOOL*)pPara;
+}
+
+BOOL lcl_CheckCol( const _FndBox*& rpFndBox, void* pPara )
+{
+    if( !rpFndBox->GetBox()->GetSttNd() )
+    {
+        if( rpFndBox->GetLines().Count() !=
+            rpFndBox->GetBox()->GetTabLines().Count() )
+            *((BOOL*)pPara) = FALSE;
+        else
+            ((_FndBox*)rpFndBox)->GetLines().ForEach( &lcl_CheckRow, pPara );
+    }
+    // Box geschuetzt ??
+    else if( rpFndBox->GetBox()->GetFrmFmt()->GetProtect().IsCntntProtected() )
+        *((BOOL*)pPara) = FALSE;
+    return *(BOOL*)pPara;
+}
+
+
+USHORT CheckMergeSel( const SwPaM& rPam )
+{
+    SwSelBoxes aBoxes;
+//JP 24.09.96: Merge mit wiederholenden TabellenHeadline funktioniert nicht
+//              richtig. Warum nicht Point 0,0 benutzen? Dann ist garantiert,
+//              das die 1. Headline mit drin ist.
+    Point aPt;
+    const SwLayoutFrm *pStart = rPam.GetCntntNode()->GetFrm(
+                                                    &aPt )->GetUpper(),
+                        *pEnd = rPam.GetCntntNode(FALSE)->GetFrm(
+                                                    &aPt )->GetUpper();
+    GetTblSel( pStart, pEnd, aBoxes );
+    return CheckMergeSel( aBoxes );
+}
+
+USHORT CheckMergeSel( const SwSelBoxes& rBoxes )
+{
+    USHORT eRet = TBLMERGE_NOSELECTION;
+    if( rBoxes.Count() )
+    {
+        eRet = TBLMERGE_OK;
+
+        _FndBox aFndBox( 0, 0 );
+        _FndPara aPara( rBoxes, &aFndBox );
+        const SwTableNode* pTblNd = aPara.rBoxes[0]->GetSttNd()->FindTableNode();
+        ((SwTable&)pTblNd->GetTable()).GetTabLines().ForEach(
+                    &_FndLineCopyCol, &aPara );
+        if( aFndBox.GetLines().Count() )
+        {
+            BOOL bMergeSelOk = TRUE;
+            _FndBox* pFndBox = &aFndBox;
+            _FndLine* pFndLine = 0;
+            while( pFndBox && 1 == pFndBox->GetLines().Count() )
+            {
+                pFndLine = pFndBox->GetLines()[0];
+                if( 1 == pFndLine->GetBoxes().Count() )
+                    pFndBox = pFndLine->GetBoxes()[0];
+                else
+                    pFndBox = 0;
+            }
+            if( pFndBox )
+                pFndBox->GetLines().ForEach( &lcl_CheckRow, &bMergeSelOk );
+            else if( pFndLine )
+                pFndLine->GetBoxes().ForEach( &lcl_CheckCol, &bMergeSelOk );
+            if( !bMergeSelOk )
+                eRet = TBLMERGE_TOOCOMPLEX;
+        }
+        else
+            eRet = TBLMERGE_NOSELECTION;
+    }
+    return eRet;
+}
+
+//Ermittelt die von einer Tabellenselektion betroffenen Tabellen und die
+//Union-Rechteckte der Selektionen - auch fuer aufgespaltene Tabellen.
+SV_IMPL_PTRARR( SwSelUnions, SwSelUnion* );
+
+SwTwips lcl_CalcWish( const SwLayoutFrm *pCell, long nWish,
+                                                const long nAct )
+{
+    SwTwips nRet = 0;
+    const SwLayoutFrm *pTmp = pCell;
+    if ( !nWish )
+        nWish = 1;
+    while ( pTmp )
+    {
+        while ( pTmp->GetPrev() )
+        {   pTmp = (SwLayoutFrm*)pTmp->GetPrev();
+            long nTmp = pTmp->GetFmt()->GetFrmSize().GetWidth();
+            nRet += nTmp * nAct / nWish;
+        }
+        pTmp = pTmp->GetUpper()->GetUpper();
+        if ( pTmp && !pTmp->IsCellFrm() )
+            pTmp = 0;
+    }
+    return nRet;
+}
+
+/*  MA: 20. Sep. 93 wird nicht mehr gebraucht.
+static const SwLayoutFrm *GetPrevCell( const SwLayoutFrm *pCell )
+{
+    const SwLayoutFrm *pLay = pCell->GetPrevLayoutLeaf();
+    if ( pLay && pLay->IsLayoutFrm() && !pLay->IsTab() )
+    {
+        //GetPrevLayoutLeaf() liefert ggf. auch die Umgebung einer Tab zurueck
+        //(naehmlich genau dann, wenn die Zelle noch Vorgaenger hat).
+        const SwFrm *pFrm = pLay->Lower();
+        while ( pFrm->GetNext() )
+            pFrm = pFrm->GetNext();
+        pLay = pFrm->IsTabFrm() ? (SwLayoutFrm*)pFrm : 0;
+    }
+    if ( pLay && pLay->IsTabFrm() )
+    {
+        //GetPrevLayoutLeaf() liefert ggf. auch Tabellen zurueck die letzte
+        //Zelle dieser Tabelle ist das das gesuchte Blatt.
+        pLay = ((SwTabFrm*)pLay)->FindLastCntnt()->GetUpper();
+        while ( !pLay->IsCellFrm() )
+            pLay = pLay->GetUpper();
+    }
+    return pLay;
+}
+*/
+
+void lcl_FindStartEndRow( const SwLayoutFrm *&rpStart,
+                             const SwLayoutFrm *&rpEnd,
+                             const int bChkProtected )
+{
+    //Start an den Anfang seiner Zeile setzen.
+    //End an das Ende seiner Zeile setzen.
+    rpStart = (SwLayoutFrm*)rpStart->GetUpper()->Lower();
+    while ( rpEnd->GetNext() )
+        rpEnd = (SwLayoutFrm*)rpEnd->GetNext();
+
+    SvPtrarr aSttArr( 8, 8 ), aEndArr( 8, 8 );
+    const SwLayoutFrm *pTmp;
+    for( pTmp = rpStart; (FRM_CELL|FRM_ROW) & pTmp->GetType();
+                pTmp = pTmp->GetUpper() )
+    {
+        void* p = (void*)pTmp;
+        aSttArr.Insert( p, 0 );
+    }
+    for( pTmp = rpEnd; (FRM_CELL|FRM_ROW) & pTmp->GetType();
+                pTmp = pTmp->GetUpper() )
+    {
+        void* p = (void*)pTmp;
+        aEndArr.Insert( p, 0 );
+    }
+
+    for( USHORT n = 0; n < aEndArr.Count() && n < aSttArr.Count(); ++n )
+        if( aSttArr[ n ] != aEndArr[ n ] )
+        {
+            // first unequal line or box - all odds are
+            if( n & 1 )                 // 1, 3, 5, ... are boxes
+            {
+                rpStart = (SwLayoutFrm*)aSttArr[ n ];
+                rpEnd = (SwLayoutFrm*)aEndArr[ n ];
+            }
+            else                                // 0, 2, 4, ... are lines
+            {
+                // check if start & end line are the first & last Line of the
+                // box. If not return these cells.
+                // Else the hole line with all Boxes has to be deleted.
+                rpStart = (SwLayoutFrm*)aSttArr[ n+1 ];
+                rpEnd = (SwLayoutFrm*)aEndArr[ n+1 ];
+                if( n )
+                {
+                    const SwCellFrm* pCellFrm = (SwCellFrm*)aSttArr[ n-1 ];
+                    const SwTableLines& rLns = pCellFrm->
+                                                GetTabBox()->GetTabLines();
+                    if( rLns[ 0 ] == ((SwRowFrm*)aSttArr[ n ])->GetTabLine() &&
+                        rLns[ rLns.Count() - 1 ] ==
+                                    ((SwRowFrm*)aEndArr[ n ])->GetTabLine() )
+                    {
+                        rpStart = rpEnd = pCellFrm;
+                        while ( rpStart->GetPrev() )
+                            rpStart = (SwLayoutFrm*)rpStart->GetPrev();
+                        while ( rpEnd->GetNext() )
+                            rpEnd = (SwLayoutFrm*)rpEnd->GetNext();
+                    }
+                }
+            }
+            break;
+        }
+
+    if( !bChkProtected )    // geschuetzte Zellen beachten ?
+        return;
+
+
+    //Anfang und Ende duerfen nicht auf geschuetzten Zellen liegen.
+    while ( rpStart->GetFmt()->GetProtect().IsCntntProtected() )
+        rpStart = (SwLayoutFrm*)rpStart->GetNext();
+    while ( rpEnd->GetFmt()->GetProtect().IsCntntProtected() )
+        rpEnd = (SwLayoutFrm*)rpEnd->GetPrev();
+}
+
+void lcl_FindStartEndCol( const SwLayoutFrm *&rpStart,
+                             const SwLayoutFrm *&rpEnd,
+                             const int bChkProtected )
+{
+    //Start und End senkrecht bis an den Rand der Tabelle denken; es muss
+    //die Gesamttabelle betrachtet werden, also inklusive Masters und
+    //Follows.
+    //Fuer den Start brauchen wir den Mutter-TabellenFrm.
+    const SwTabFrm *pOrg = rpStart->FindTabFrm();
+    const SwTabFrm *pTab = pOrg;
+    const long nWish = pOrg->GetFmt()->GetFrmSize().GetWidth();
+    while ( pTab->IsFollow() )
+    {
+        const SwFrm *pTmp = pTab->FindPrev();
+        ASSERT( pTmp->IsTabFrm(), "Vorgaenger vom Follow nicht der Master." );
+        pTab = (const SwTabFrm*)pTmp;
+    }
+
+    const SwTwips nSX = ::lcl_CalcWish( rpStart, nWish, pTab->Prt().Width() ) +
+                        (pTab->Frm().Left() + pTab->Prt().Left());
+    const SwTwips nSX2= nSX + (rpStart->GetFmt()->GetFrmSize().GetWidth() *
+                                            pTab->Prt().Width() / nWish);
+
+    const SwLayoutFrm *pTmp = pTab->FirstCell();
+    while ( pTmp &&
+            (!pTmp->IsCellFrm() ||
+             (pTmp->Frm().Left() < nSX &&
+              pTmp->Frm().Right()< nSX2)))
+        pTmp = pTmp->GetNextLayoutLeaf();
+    if ( pTmp )
+        rpStart = pTmp;
+
+    pTab = pOrg;
+    while ( pTab->GetFollow() )
+        pTab = pTab->GetFollow();
+    const SwTwips nEX = ::lcl_CalcWish( rpEnd, nWish, pTab->Prt().Width() ) +
+                        (pTab->Frm().Left() + pTab->Prt().Left());
+    rpEnd = pTab->FindLastCntnt()->GetUpper();
+    while( !rpEnd->IsCellFrm() )
+        rpEnd = rpEnd->GetUpper();
+    while ( rpEnd->Frm().Left() > nEX )
+        rpEnd = rpEnd->GetPrevLayoutLeaf();
+
+    if( !bChkProtected )    // geschuetzte Zellen beachten ?
+        return;
+
+    //Anfang und Ende duerfen nicht auf geschuetzten Zellen liegen.
+    //Also muss ggf. nocheinmal rueckwaerts gesucht werden.
+    while ( rpStart->GetFmt()->GetProtect().IsCntntProtected() )
+    {
+        const SwLayoutFrm *pTmp = rpStart;
+        pTmp = pTmp->GetNextLayoutLeaf();
+        while ( pTmp && pTmp->Frm().Left() > nEX )//erstmal die Zeile ueberspr.
+            pTmp = pTmp->GetNextLayoutLeaf();
+        while ( pTmp && pTmp->Frm().Left() < nSX &&
+                        pTmp->Frm().Right()< nSX2 )
+            pTmp = pTmp->GetNextLayoutLeaf();
+        const SwTabFrm *pTab = rpStart->FindTabFrm();
+        if ( !pTab->IsAnLower( pTmp ) )
+        {
+            pTab = pTab->GetFollow();
+            rpStart = pTab->FirstCell();
+            while ( rpStart->Frm().Left() < nSX &&
+                    rpStart->Frm().Right()< nSX2 )
+                rpStart = rpStart->GetNextLayoutLeaf();
+        }
+        else
+            rpStart = pTmp;
+    }
+    while ( rpEnd->GetFmt()->GetProtect().IsCntntProtected() )
+    {
+        const SwLayoutFrm *pTmp = rpEnd;
+        pTmp = pTmp->GetPrevLayoutLeaf();
+        while ( pTmp && pTmp->Frm().Left() < nEX )//erstmal die Zeile ueberspr.
+            pTmp = pTmp->GetPrevLayoutLeaf();
+        while ( pTmp && pTmp->Frm().Left() > nEX )
+            pTmp = pTmp->GetPrevLayoutLeaf();
+        const SwTabFrm *pTab = rpEnd->FindTabFrm();
+        if ( !pTmp || !pTab->IsAnLower( pTmp ) )
+        {
+            pTab = (const SwTabFrm*)pTab->FindPrev();
+            ASSERT( pTab->IsTabFrm(), "Vorgaenger vom Follow nicht der Master.");
+            rpEnd = pTab->FindLastCntnt()->GetUpper();
+            while( !rpEnd->IsCellFrm() )
+                rpEnd = rpEnd->GetUpper();
+            while ( rpEnd->Frm().Left() > nEX )
+                rpEnd = rpEnd->GetPrevLayoutLeaf();
+        }
+        else
+            rpEnd = pTmp;
+    }
+}
+
+
+void MakeSelUnions( SwSelUnions& rUnions, const SwLayoutFrm *pStart,
+                    const SwLayoutFrm *pEnd, const SwTblSearchType eSearchType )
+{
+    while ( !pStart->IsCellFrm() )
+        pStart = pStart->GetUpper();
+    while ( !pEnd->IsCellFrm() )
+        pEnd = pEnd->GetUpper();
+
+    const SwTabFrm *pTable = pStart->FindTabFrm();
+    const SwTabFrm *pEndTable = pEnd->FindTabFrm();
+    BOOL bExchange = FALSE;
+
+    if ( pTable != pEndTable )
+    {
+        if ( !pTable->IsAnFollow( pEndTable ) )
+        {
+            ASSERT( pEndTable->IsAnFollow( pTable ), "Tabkette verknotet." );
+            bExchange = TRUE;
+        }
+    }
+    else if ( pStart->Frm().Top() > pEnd->Frm().Top() ||
+             (pStart->Frm().Top() == pEnd->Frm().Top() &&
+              pStart->Frm().Left() > pEnd->Frm().Left()) )
+        bExchange = TRUE;
+    if ( bExchange )
+    {
+        const SwLayoutFrm *pTmp = pStart;
+        pStart = pEnd;
+        pEnd = pTmp;
+        //pTable und pEndTable nicht umsortieren, werden unten neu gesetzt.
+        //MA: 28. Dec. 93 Bug: 5190
+    }
+
+    //Start und End sind jetzt huebsch sortiert, jetzt muessen sie falls
+    //erwuenscht noch versetzt werden.
+    if( TBLSEARCH_ROW == ((~TBLSEARCH_PROTECT ) & eSearchType ) )
+        ::lcl_FindStartEndRow( pStart, pEnd, TBLSEARCH_PROTECT & eSearchType );
+    else if( TBLSEARCH_COL == ((~TBLSEARCH_PROTECT ) & eSearchType ) )
+        ::lcl_FindStartEndCol( pStart, pEnd, TBLSEARCH_PROTECT & eSearchType );
+
+    //neu besorgen, da sie jetzt verschoben sind. MA: 28. Dec. 93 Bug 5190
+    pTable = pStart->FindTabFrm();
+    pEndTable = pEnd->FindTabFrm();
+
+    const FASTBOOL bRepeat = pTable->GetTable()->IsHeadlineRepeat();
+
+    const long nStSz = pStart->GetFmt()->GetFrmSize().GetWidth();
+    const long nEdSz = pEnd->GetFmt()->GetFrmSize().GetWidth();
+    const long nWish = Max( 1L, pTable->GetFmt()->GetFrmSize().GetWidth() );
+    while ( pTable )
+    {
+        const long nOfst = pTable->Frm().Left() + pTable->Prt().Left();
+        long nSt = ::lcl_CalcWish( pStart, nWish, pTable->Prt().Width() ) + nOfst;
+        long nEd = ::lcl_CalcWish( pEnd,   nWish, pTable->Prt().Width() ) + nOfst;
+
+        if ( nSt <= nEd )
+            nEd += (long)((nEdSz * pTable->Prt().Width()) / nWish) - 1;
+        else
+            nSt += (long)((nStSz * pTable->Prt().Width()) / nWish) - 1;
+
+        Point aSt( nSt, pStart->Frm().Top() ),
+              aEd( nEd, pEnd->Frm().Bottom() );
+
+        if ( !pTable->IsAnLower( pStart ) )
+            aSt.Y() = pTable->Frm().Top();
+        if ( !pTable->IsAnLower( pEnd ) )
+            aEd.Y() = pTable->Frm().Bottom();
+
+        SwRect aUnion( aSt, aEd );
+        aUnion.Justify();
+
+        // fuers
+        if( !(TBLSEARCH_NO_UNION_CORRECT & eSearchType ))
+        {
+            //Leider ist die Union jetzt mit Rundungsfehlern behaftet und dadurch
+            //wuerden beim Split/Merge fehlertraechtige Umstaende entstehen.
+            //Um dies zu vermeiden werden jetzt fuer die Table die erste und
+            //letzte Zelle innerhalb der Union ermittelt und aus genau deren
+            //Werten wird die Union neu gebildet.
+            const SwLayoutFrm *pRow = (SwLayoutFrm*)pTable->Lower();
+            if ( bRepeat && pRow && pTable->IsFollow() )
+                pRow = (SwLayoutFrm*)pRow->GetNext();
+            while ( pRow && !pRow->Frm().IsOver( aUnion ) )
+                pRow = (SwLayoutFrm*)pRow->GetNext();
+            const SwLayoutFrm *pFirst = pRow ? pRow->FirstCell() : 0;
+            while ( pFirst && !::IsFrmInTblSel( aUnion, pFirst ) )
+            {
+                if ( pFirst->GetNext() )
+                {
+                    pFirst = (const SwLayoutFrm*)pFirst->GetNext();
+                    if ( pFirst->Lower()->IsRowFrm() )
+                        pFirst = pFirst->FirstCell();
+                }
+                else
+                    pFirst = ::lcl_FindNextCellFrm( pFirst );
+            }
+            const SwLayoutFrm *pLast = ::lcl_FindCellFrm( pTable->FindLastCntnt()->GetUpper());
+            while ( pLast && !::IsFrmInTblSel( aUnion, pLast ) )
+                pLast = ::lcl_FindCellFrm( pLast->GetPrevLayoutLeaf() );
+
+            if ( pFirst && pLast ) //Robust
+                aUnion = SwRect( pFirst->Frm().Pos(),
+                                 Point( pLast->Frm().Right(),
+                                         pLast->Frm().Bottom() ) );
+            else
+                aUnion.Width( 0 );
+        }
+
+        if( aUnion.Width() )
+        {
+            SwSelUnion *pTmp = new SwSelUnion( aUnion, (SwTabFrm*)pTable );
+            rUnions.C40_INSERT( SwSelUnion, pTmp, rUnions.Count() );
+        }
+
+        pTable = pTable->GetFollow();
+        if ( pTable != pEndTable && pEndTable->IsAnFollow( pTable ) )
+            pTable = 0;
+    }
+}
+
+BOOL CheckSplitCells( const SwCrsrShell& rShell, USHORT nDiv,
+                        const SwTblSearchType eSearchType )
+{
+    if( !rShell.IsTableMode() )
+        rShell.GetCrsr();
+
+    const SwShellCrsr *pCrsr = rShell.GetTableCrsr();
+    if( !pCrsr )
+        pCrsr = (SwShellCrsr*)*rShell.GetSwCrsr( FALSE );
+
+    return CheckSplitCells( *pCrsr, nDiv, eSearchType );
+}
+
+BOOL CheckSplitCells( const SwCursor& rCrsr, USHORT nDiv,
+                        const SwTblSearchType eSearchType )
+{
+    if( 1 >= nDiv )
+        return FALSE;
+
+    USHORT nMinValue = nDiv * MINLAY;
+
+    //Start- und Endzelle besorgen und den naechsten fragen.
+    Point aPtPos, aMkPos;
+    const SwShellCrsr* pShCrsr = rCrsr;
+    if( pShCrsr )
+    {
+        aPtPos = pShCrsr->GetPtPos();
+        aMkPos = pShCrsr->GetMkPos();
+    }
+    const SwLayoutFrm *pStart = rCrsr.GetCntntNode()->GetFrm(
+                                &aPtPos )->GetUpper(),
+                      *pEnd   = rCrsr.GetCntntNode(FALSE)->GetFrm(
+                                &aMkPos )->GetUpper();
+
+    //Zuerst lassen wir uns die Tabellen und die Rechtecke heraussuchen.
+    SwSelUnions aUnions;
+
+    ::MakeSelUnions( aUnions, pStart, pEnd, eSearchType );
+
+    //Muss ein HeadlineRepeat beachtet werden?
+    const BOOL bRepeat = pStart->FindTabFrm()->GetTable()->IsHeadlineRepeat();
+
+    //Jetzt zu jedem Eintrag die Boxen herausfischen und uebertragen.
+    for ( USHORT i = 0; i < aUnions.Count(); ++i )
+    {
+        SwSelUnion *pUnion = aUnions[i];
+        const SwTabFrm *pTable = pUnion->GetTable();
+
+        const SwLayoutFrm *pRow = (const SwLayoutFrm*)pTable->Lower();
+        //Wenn die Row eine wiederholte Headline ist wird sie nicht
+        //beachtet.
+        if ( bRepeat && pTable->IsFollow() )
+            pRow = (const SwLayoutFrm*)pRow->GetNext();
+
+        while ( pRow )
+        {
+            if ( pRow->Frm().IsOver( pUnion->GetUnion() ) )
+            {
+                const SwLayoutFrm *pCell = pRow->FirstCell();
+
+                while ( pCell && pRow->IsAnLower( pCell ) )
+                {
+                    ASSERT( pCell->IsCellFrm(), "Frame ohne Celle" );
+                    if( ::IsFrmInTblSel( pUnion->GetUnion(), pCell ) )
+                    {
+                        if( pCell->Frm().Width() < nMinValue )
+                            return FALSE;
+                    }
+
+                    if ( pCell->GetNext() )
+                    {
+                        pCell = (const SwLayoutFrm*)pCell->GetNext();
+                        if ( pCell->Lower()->IsRowFrm() )
+                            pCell = pCell->FirstCell();
+                    }
+                    else
+                        pCell = ::lcl_FindNextCellFrm( pCell );
+                }
+            }
+            pRow = (const SwLayoutFrm*)pRow->GetNext();
+        }
+    }
+    return TRUE;
+}
+
+// -------------------------------------------------------------------
+// Diese Klassen kopieren die aktuelle Tabellen-Selektion (rBoxes)
+// unter Beibehaltung der Tabellen-Struktur in eine eigene Struktur
+// neu: SS zum gezielten Loeschen/Retaurieren des Layouts.
+
+void lcl_InsertRow( SwTableLine &rLine, SwLayoutFrm *pUpper, SwFrm *pSibling )
+{
+    SwRowFrm *pRow = new SwRowFrm( rLine );
+    if ( pUpper->IsTabFrm() && ((SwTabFrm*)pUpper)->IsFollow() )
+    {
+        ((SwTabFrm*)pUpper)->FindMaster()->InvalidatePos(); //kann die Zeile vielleicht aufnehmen
+        if ( ((SwTabFrm*)pUpper)->GetTable()->IsHeadlineRepeat() &&
+             pSibling && !pSibling->GetPrev() )
+        {
+            //Nicht vor die Headline-Wiederholung pasten.
+            pSibling = pSibling->GetNext();
+        }
+    }
+    pRow->Paste( pUpper, pSibling );
+    pRow->RegistFlys();
+}
+
+
+BOOL _FndBoxCopyCol( const SwTableBox*& rpBox, void* pPara )
+{
+    _FndPara* pFndPara = (_FndPara*)pPara;
+    _FndBox* pFndBox = new _FndBox( (SwTableBox*)rpBox, pFndPara->pFndLine );
+    if( rpBox->GetTabLines().Count() )
+    {
+        _FndPara aPara( *pFndPara, pFndBox );
+        pFndBox->GetBox()->GetTabLines().ForEach( &_FndLineCopyCol, &aPara );
+        if( !pFndBox->GetLines().Count() )
+        {
+            delete pFndBox;
+            return TRUE;
+        }
+    }
+    else
+    {
+        SwTableBoxPtr pSrch = (SwTableBoxPtr)rpBox;
+        USHORT nFndPos;
+        if( !pFndPara->rBoxes.Seek_Entry( pSrch, &nFndPos ))
+        {
+            delete pFndBox;
+            return TRUE;
+        }
+    }
+    pFndPara->pFndLine->GetBoxes().C40_INSERT( _FndBox, pFndBox,
+                    pFndPara->pFndLine->GetBoxes().Count() );
+    return TRUE;
+}
+
+BOOL _FndLineCopyCol( const SwTableLine*& rpLine, void* pPara )
+{
+    _FndPara* pFndPara = (_FndPara*)pPara;
+    _FndLine* pFndLine = new _FndLine( (SwTableLine*)rpLine, pFndPara->pFndBox );
+    _FndPara aPara( *pFndPara, pFndLine );
+    pFndLine->GetLine()->GetTabBoxes().ForEach( &_FndBoxCopyCol, &aPara );
+    if( pFndLine->GetBoxes().Count() )
+    {
+        pFndPara->pFndBox->GetLines().C40_INSERT( _FndLine, pFndLine,
+                pFndPara->pFndBox->GetLines().Count() );
+    }
+    else
+        delete pFndLine;
+    return TRUE;
+}
+
+void _FndBox::SetTableLines( const SwSelBoxes &rBoxes, const SwTable &rTable )
+{
+    //Pointer auf die Lines vor und hinter den zu verarbeitenden Bereich
+    //setzen. Wenn die erste/letzte Zeile in den Bereich eingeschlossen
+    //sind, so bleiben die Pointer eben einfach 0.
+    //Gesucht werden zunachst die Positionen der ersten/letzten betroffenen
+    //Line im Array der SwTable. Damit die 0 fuer 'keine Line' verwand werden
+    //kann werden die Positionen um 1 nach oben versetzt!
+
+    USHORT nStPos = USHRT_MAX;
+    USHORT nEndPos= 0;
+
+    for ( USHORT i = 0; i < rBoxes.Count(); ++i )
+    {
+        SwTableLine *pLine = rBoxes[i]->GetUpper();
+        while ( pLine->GetUpper() )
+            pLine = pLine->GetUpper()->GetUpper();
+        const USHORT nPos = rTable.GetTabLines().GetPos(
+                    (const SwTableLine*&)pLine ) + 1;
+
+        ASSERT( nPos != USHRT_MAX, "TableLine not found." );
+
+        if( nStPos > nPos )
+            nStPos = nPos;
+
+        if( nEndPos < nPos )
+            nEndPos = nPos;
+    }
+    if ( nStPos > 1 )
+        pLineBefore = rTable.GetTabLines()[nStPos - 2];
+    if ( nEndPos < rTable.GetTabLines().Count() )
+        pLineBehind = rTable.GetTabLines()[nEndPos];
+}
+
+void _FndBox::SetTableLines( const SwTable &rTable )
+{
+    // Pointer auf die Lines vor und hinter den zu verarbeitenden Bereich
+    // setzen. Wenn die erste/letzte Zeile in den Bereich eingeschlossen
+    // sind, so bleiben die Pointer eben einfach 0.
+    // Die Positionen der ersten/letzten betroffenen Line im Array der
+    // SwTable steht in der FndBox. Damit die 0 fuer 'keine Line' verwand
+    // werdenkann werden die Positionen um 1 nach oben versetzt!
+
+    if( !GetLines().Count() )
+        return;
+
+    SwTableLine* pTmpLine = GetLines()[0]->GetLine();
+    USHORT nPos = rTable.GetTabLines().C40_GETPOS( SwTableLine, pTmpLine );
+    ASSERT( USHRT_MAX != nPos, "Line steht nicht in der Tabelle" );
+    if( nPos )
+        pLineBefore = rTable.GetTabLines()[ nPos - 1 ];
+
+    pTmpLine = GetLines()[GetLines().Count()-1]->GetLine();
+    nPos = rTable.GetTabLines().C40_GETPOS( SwTableLine, pTmpLine );
+    ASSERT( USHRT_MAX != nPos, "Line steht nicht in der Tabelle" );
+    if( ++nPos < rTable.GetTabLines().Count() )
+        pLineBehind = rTable.GetTabLines()[nPos];
+}
+
+inline void UnsetFollow( SwFlowFrm *pTab )
+{
+    pTab->bIsFollow = FALSE;
+}
+
+void _FndBox::DelFrms( SwTable &rTable )
+{
+    //Alle Lines zwischen pLineBefore und pLineBehind muessen aus dem
+    //Layout ausgeschnitten und geloescht werden.
+    //Entstehen dabei leere Follows so muessen diese vernichtet werden.
+    //Wird ein Master vernichtet, so muss der Follow Master werden.
+    //Ein TabFrm muss immer uebrigbleiben.
+
+    USHORT nStPos = 0;
+    USHORT nEndPos= rTable.GetTabLines().Count() - 1;
+    if ( pLineBefore )
+    {
+        nStPos = rTable.GetTabLines().GetPos(
+                        (const SwTableLine*&)pLineBefore );
+        ASSERT( nStPos != USHRT_MAX, "Fuchs Du hast die Line gestohlen!" );
+        ++nStPos;
+    }
+    if ( pLineBehind )
+    {
+        nEndPos = rTable.GetTabLines().GetPos(
+                        (const SwTableLine*&)pLineBehind );
+        ASSERT( nEndPos != USHRT_MAX, "Fuchs Du hast die Line gestohlen!" );
+        --nEndPos;
+    }
+    for ( USHORT i = nStPos; i <= nEndPos; ++i)
+    {
+        SwFrmFmt *pFmt = rTable.GetTabLines()[i]->GetFrmFmt();
+        SwClientIter aIter( *pFmt );
+        SwClient* pLast = aIter.GoStart();
+        if( pLast )
+        {
+            do {
+                SwFrm *pFrm = PTR_CAST( SwFrm, pLast );
+                if ( pFrm &&
+                     ((SwRowFrm*)pFrm)->GetTabLine() == rTable.GetTabLines()[i] )
+                {
+                    BOOL bDel = TRUE;
+                    SwTabFrm *pUp = !pFrm->GetPrev() && !pFrm->GetNext() ?
+                                            (SwTabFrm*)pFrm->GetUpper() : 0;
+                    if ( !pUp )
+                    {
+                        if ( ((SwTabFrm*)pFrm->GetUpper())->GetTable()->IsHeadlineRepeat() &&
+                             ((SwTabFrm*)pFrm->GetUpper())->IsFollow() )
+                        {
+                            if ( !pFrm->GetNext() && pFrm->GetPrev() &&
+                                 !pFrm->GetPrev()->GetPrev() )
+                            {
+                                pUp = (SwTabFrm*)pFrm->GetUpper();
+                            }
+                        }
+                    }
+                    if ( pUp )
+                    {
+                        SwTabFrm *pFollow = pUp->GetFollow();
+                        SwTabFrm *pPrev   = pUp->IsFollow() ? pUp : 0;
+                        if ( pPrev )
+                        {
+                            SwFrm *pTmp = pPrev->FindPrev();
+                            ASSERT( pTmp->IsTabFrm(),
+                                    "Vorgaenger vom Follow kein Master.");
+                            pPrev = (SwTabFrm*)pTmp;
+                        }
+                        if ( pPrev )
+                            pPrev->SetFollow( pFollow );
+                        else if ( pFollow )
+                            ::UnsetFollow( pFollow );
+
+                        //Ein TabellenFrm muss immer stehenbleiben!
+                        if ( pPrev || pFollow )
+                        {
+                            pUp->Cut();
+                            delete pUp;
+                            bDel = FALSE;//Die Row wird mit in den Abgrund
+                                         //gerissen.
+                        }
+                    }
+                    if ( bDel )
+                    {
+                        pFrm->Cut();
+                        delete pFrm;
+                    }
+                }
+            } while( 0 != ( pLast = aIter++ ));
+        }
+    }
+}
+
+BOOL lcl_IsLineOfTblFrm( const SwTabFrm& rTable, const SwFrm& rChk )
+{
+    const SwTabFrm* pTblFrm = rChk.FindTabFrm();
+    while( pTblFrm->IsFollow() )
+        pTblFrm = pTblFrm->FindMaster();
+    return &rTable == pTblFrm;
+}
+
+void _FndBox::MakeFrms( SwTable &rTable )
+{
+    //Alle Lines zwischen pLineBefore und pLineBehind muessen im Layout
+    //wieder neu erzeugt werden.
+    //Und Zwar fuer alle Auspraegungen der Tabelle (mehrere z.B. im Kopf/Fuss).
+
+    USHORT nStPos = 0;
+    USHORT nEndPos= rTable.GetTabLines().Count() - 1;
+    if ( pLineBefore )
+    {
+        nStPos = rTable.GetTabLines().GetPos(
+                        (const SwTableLine*&)pLineBefore );
+        ASSERT( nStPos != USHRT_MAX, "Fuchs Du hast die Line gestohlen!" );
+        ++nStPos;
+
+    }
+    if ( pLineBehind )
+    {
+        nEndPos = rTable.GetTabLines().GetPos(
+                        (const SwTableLine*&)pLineBehind );
+        ASSERT( nEndPos != USHRT_MAX, "Fuchs Du hast die Line gestohlen!" );
+        --nEndPos;
+    }
+    //Jetzt die grosse Einfuegeoperation fuer alle Tabllen.
+    SwClientIter aTabIter( *rTable.GetFrmFmt() );
+    for ( SwTabFrm *pTable = (SwTabFrm*)aTabIter.First( TYPE(SwFrm) ); pTable;
+          pTable = (SwTabFrm*)aTabIter.Next() )
+    {
+        if ( !pTable->IsFollow() )
+        {
+            SwFrm  *pSibling = 0;
+            SwFrm  *pUpper   = 0;
+            int i;
+            for ( i = rTable.GetTabLines().Count()-1;
+                    i >= 0 && !pSibling; --i )
+            {
+                SwTableLine *pLine = pLineBehind ? pLineBehind :
+                                                    rTable.GetTabLines()[i];
+                SwClientIter aIter( *pLine->GetFrmFmt() );
+                for ( pSibling = (SwFrm*)aIter.First( TYPE(SwFrm) );
+                      pSibling && (
+                        ((SwRowFrm*)pSibling)->GetTabLine() != pLine ||
+                        !lcl_IsLineOfTblFrm( *pTable, *pSibling ) );
+                      pSibling = (SwFrm*)aIter.Next() )
+                    /* do nothing */;
+            }
+            if ( pSibling )
+            {
+                pUpper = pSibling->GetUpper();
+                if ( !pLineBehind )
+                    pSibling = 0;
+            }
+            else
+// ???? oder das der Letzte Follow der Tabelle ????
+                pUpper = pTable;
+
+            for ( i = nStPos; (USHORT)i <= nEndPos; ++i )
+                ::lcl_InsertRow( *rTable.GetTabLines()[i],
+                                (SwLayoutFrm*)pUpper, pSibling );
+            if ( pUpper->IsTabFrm() )
+                ((SwTabFrm*)pUpper)->SetCalcLowers();
+        }
+        else if ( nStPos == 0 && rTable.IsHeadlineRepeat() )
+        {
+            //Headline in den Follow einsetzen
+            SwRowFrm *pRow = new SwRowFrm( *rTable.GetTabLines()[0] );
+            pRow->Paste( pTable, pTable->Lower() );
+            pRow->RegistFlys();
+            pTable->SetCalcLowers();
+        }
+    }
+}
+
+void _FndBox::MakeNewFrms( SwTable &rTable, const USHORT nNumber,
+                                            const BOOL bBehind )
+{
+    //Frms fuer neu eingefuege Zeilen erzeugen.
+    //bBehind == TRUE:  vor     pLineBehind
+    //        == FALSE: hinter  pLineBefore
+    const USHORT nBfPos = pLineBefore ?
+        rTable.GetTabLines().GetPos( (const SwTableLine*&)pLineBefore ) :
+        USHRT_MAX;
+    const USHORT nBhPos = pLineBehind ?
+        rTable.GetTabLines().GetPos( (const SwTableLine*&)pLineBehind ) :
+        USHRT_MAX;
+
+    //nNumber: wie oft ist eingefuegt worden.
+    //nCnt:    wieviele sind nNumber mal eingefuegt worden.
+
+    const USHORT nCnt =
+        ((nBhPos != USHRT_MAX ? nBhPos : rTable.GetTabLines().Count()) -
+         (nBfPos != USHRT_MAX ? nBfPos + 1 : 0)) / (nNumber + 1);
+
+    //Den Master-TabFrm suchen
+    SwClientIter aTabIter( *rTable.GetFrmFmt() );
+    SwTabFrm *pTable;
+    for ( pTable = (SwTabFrm*)aTabIter.First( TYPE(SwFrm) ); pTable;
+          pTable = (SwTabFrm*)aTabIter.Next() )
+        if( !pTable->IsFollow() )
+        {
+            SwFrm       *pSibling = 0;
+            SwLayoutFrm *pUpper   = 0;
+            if ( bBehind )
+            {
+                if ( pLineBehind )
+                {
+                    SwClientIter aIter( *pLineBehind->GetFrmFmt() );
+                    for ( pSibling = (SwFrm*)aIter.First( TYPE(SwFrm) );
+                          pSibling && (
+                            ((SwRowFrm*)pSibling)->GetTabLine() != pLineBehind ||
+                            !lcl_IsLineOfTblFrm( *pTable, *pSibling ) );
+                          pSibling = (SwFrm*)aIter.Next() )
+                        /* do nothing */;
+                }
+                if ( pSibling )
+                    pUpper = pSibling->GetUpper();
+                else
+                {
+                    while( pTable->GetFollow() )
+                        pTable = pTable->GetFollow();
+                    pUpper = pTable;
+                }
+                const USHORT nMax = nBhPos != USHRT_MAX ?
+                                    nBhPos : rTable.GetTabLines().Count();
+
+                USHORT i = nBfPos != USHRT_MAX ? nBfPos + 1 + nCnt : nCnt;
+
+                for ( ; i < nMax; ++i )
+                    ::lcl_InsertRow( *rTable.GetTabLines()[i], pUpper, pSibling );
+                if ( pUpper->IsTabFrm() )
+                    ((SwTabFrm*)pUpper)->SetCalcLowers();
+            }
+            else //davor einfuegen
+            {
+                USHORT i;
+                for ( i = 0; !pSibling; ++i )
+                {
+                    SwTableLine *pLine = pLineBefore ? pLineBefore :
+                                                    rTable.GetTabLines()[i];
+
+                    SwClientIter aIter( *pLine->GetFrmFmt() );
+                    for ( pSibling = (SwFrm*)aIter.First( TYPE(SwFrm) );
+                          pSibling && (
+                            ((SwRowFrm*)pSibling)->GetTabLine() != pLine ||
+                            !lcl_IsLineOfTblFrm( *pTable, *pSibling ) ||
+                            ((!pLineBefore || pLine == rTable.GetTabLines()[0]) &&
+                             pSibling->FindTabFrm() != pTable)); // Master finden!
+                          pSibling = (SwFrm*)aIter.Next() )
+                        /* do nothing */;
+                }
+                pUpper = pSibling->GetUpper();
+                if ( pLineBefore )
+                    pSibling = pSibling->GetNext();
+
+                USHORT nMax = nBhPos != USHRT_MAX ?
+                                    nBhPos - nCnt :
+                                    rTable.GetTabLines().Count() - nCnt;
+
+                i = nBfPos != USHRT_MAX ? nBfPos + 1 : 0;
+                for ( ; i < nMax; ++i )
+                    ::lcl_InsertRow( *rTable.GetTabLines()[i],
+                                pUpper, pSibling );
+                if ( pUpper->IsTabFrm() )
+                    ((SwTabFrm*)pUpper)->SetCalcLowers();
+            }
+        }
+
+    //Die Headlines mussen ggf. auch verarbeitet werden. Um gut arbeitenden
+    //Code nicht zu zerfasern wird hier nochmals iteriert.
+    if ( !bBehind && nBfPos == USHRT_MAX && rTable.IsHeadlineRepeat() )
+    {
+        SwTabFrm *pTab = (SwTabFrm*)aTabIter.First( TYPE(SwFrm) );
+        if ( pTab->Lower() )
+        {
+            if ( pTab->IsFollow() )
+            {
+                //Alte Headline vernichten
+                SwFrm *pLow = pTab->Lower();
+                pLow->Cut();
+                delete pLow;
+            }
+            if ( ((SwRowFrm*)pTab->Lower())->GetTabLine() !=
+                 rTable.GetTabLines()[0] )
+            {
+                //Neue Headline einsetzen
+                SwRowFrm *pRow = new SwRowFrm( *rTable.GetTabLines()[0]);
+                pRow->Paste( pTab, pTab->Lower() );
+                pRow->RegistFlys();
+                pTab->SetCalcLowers();
+            }
+        }
+    }
+}
+
+BOOL _FndBox::AreLinesToRestore( const SwTable &rTable ) const
+{
+    //Lohnt es sich MakeFrms zu rufen?
+
+    if ( !pLineBefore && !pLineBehind && rTable.GetTabLines().Count() )
+        return TRUE;
+
+    USHORT nBfPos;
+    if(pLineBefore)
+    {
+        const SwTableLine* rLBefore = (const SwTableLine*)pLineBefore;
+        nBfPos = rTable.GetTabLines().GetPos( rLBefore );
+    }
+    else
+        nBfPos = USHRT_MAX;
+
+    USHORT nBhPos;
+    if(pLineBehind)
+    {
+        const SwTableLine* rLBehind = (const SwTableLine*)pLineBehind;
+        nBhPos = rTable.GetTabLines().GetPos( rLBehind );
+    }
+    else
+        nBhPos = USHRT_MAX;
+
+    if ( nBfPos == nBhPos ) //Duerfte eigentlich nie vorkommen.
+    {
+        ASSERT( FALSE, "Table, Loeschen auf keinem Bereich !?!" );
+        return FALSE;
+    }
+
+    if ( nBfPos == USHRT_MAX && nBhPos == 0 )
+    {
+        // ups. sollte unsere zu wiederholende Kopfzeile geloescht worden
+        // sein??
+        if( rTable.IsHeadlineRepeat() )
+        {
+            SwClientIter aIter( *rTable.GetFrmFmt() );
+            for( SwTabFrm* pTable = (SwTabFrm*)aIter.First( TYPE( SwFrm ));
+                    pTable; pTable = (SwTabFrm*)aIter.Next() )
+                if( pTable->IsFollow() )
+                {
+                    //Headline in den Follow einsetzen
+                    SwRowFrm *pRow = new SwRowFrm( *rTable.GetTabLines()[0] );
+                    pRow->Paste( pTable, pTable->Lower() );
+                    pRow->RegistFlys();
+                }
+        }
+        return FALSE;
+    }
+
+    if ( nBhPos == USHRT_MAX && nBfPos == (rTable.GetTabLines().Count() - 1) )
+        return FALSE;
+
+    if ( nBfPos != USHRT_MAX && nBhPos != USHRT_MAX && (nBfPos + 1) == nBhPos )
+        return FALSE;
+
+    return TRUE;
+}
+
+
+//Save- und RestoreChartData:
+//Zu der Tabelle werden alle Charts gesucht. Die Namentliche Addressierung der
+//Boxen in der Tabelle (etwa: ) wird ausgelesen. Die Addressen der
+//Boxen werden im Chart festgehalten. Im Restore wird versucht zu den Pointern
+//die Boxen wiederzufinden. Wenn dies gelingt, wird die neue Addressierung
+//wieder in das Chart geschrieben. Wenn sie nicht gefunden werden gibt es
+//einen FallBack auf die erste/letzte Box.
+
+const SwTableBox *lcl_FindFirstBox( const SwTable &rTable )
+{
+    const SwTableLines *pLines = &rTable.GetTabLines();
+    const SwTableBox *pBox;
+    do
+    {   pBox = (*pLines)[0]->GetTabBoxes()[0];
+        if ( pBox->GetSttNd() )
+            pLines = 0;
+        else
+            pLines = &pBox->GetTabLines();
+
+    } while ( pLines );
+    return pBox;
+}
+
+const SwTableBox *lcl_FindLastBox( const SwTable &rTable )
+{
+    const SwTableLines *pLines = &rTable.GetTabLines();
+    const SwTableBox *pBox;
+    do
+    {   const SwTableBoxes &rBoxes = (*pLines)[pLines->Count()-1]->GetTabBoxes();
+        pBox = rBoxes[rBoxes.Count()-1];
+        if ( pBox->GetSttNd() )
+            pLines = 0;
+        else
+            pLines = &pBox->GetTabLines();
+
+    } while ( pLines );
+
+    return pBox;
+}
+
+
+//GPF bei Tab in letzer Zelle mit MSC4
+#pragma optimize("",off)
+
+void _FndBox::SaveChartData( const SwTable &rTable )
+{
+    SwDoc *pDoc = rTable.GetFrmFmt()->GetDoc();
+    SwClientIter aIter( *(SwModify*)pDoc->GetDfltGrfFmtColl() );
+    SwClient *pCli;
+    if ( 0 != (pCli = aIter.First( TYPE(SwCntntNode) )) )
+        do
+        {   if ( !((SwCntntNode*)pCli)->GetOLENode() )
+                continue;
+            SwOLENode *pONd = (SwOLENode*)pCli;
+            if ( rTable.GetFrmFmt()->GetName() == pONd->GetChartTblName() )
+            {
+                SwOLEObj& rOObj = pONd->GetOLEObj();
+                SchMemChart *pData = SchDLL::GetChartData( rOObj.GetOleRef() );
+                if ( pData )
+                {
+                    String &rStr = pData->SomeData1();
+                    xub_StrLen nTmp = rStr.Search( ':' );
+                    String aBox( rStr.Copy( 1, nTmp - 1 ) );
+                    //const this, weil Borland so dumm ist!
+                    const SwTableBox *pSttBox = rTable.GetTblBox( aBox );
+                    if ( !pSttBox )
+                        pSttBox = rTable.GetTabLines()[0]->GetTabBoxes()[0];
+                    aBox = rStr.Copy( nTmp + 1, rStr.Len()-2 - nTmp);
+                    const SwTableBox *pEndBox = rTable.GetTblBox( aBox );
+                    if ( !pEndBox )
+                    {
+                        SwTableLine *pLine =
+                            rTable.GetTabLines()[rTable.GetTabLines().Count()-1];
+                        pEndBox = pLine->GetTabBoxes()[pLine->GetTabBoxes().Count()-1];
+                    }
+                    pData->SomeData3() = String::CreateFromInt32(
+                                        pSttBox != ::lcl_FindFirstBox(rTable)
+                                            ? long(pSttBox)
+                                            : LONG_MAX );
+                    pData->SomeData4() = String::CreateFromInt32(
+                                        pEndBox != ::lcl_FindLastBox(rTable)
+                                            ? long(pEndBox)
+                                            : LONG_MAX );
+                }
+            }
+        } while ( 0 != (pCli = aIter.Next()) );
+}
+
+void _FndBox::RestoreChartData( const SwTable &rTable )
+{
+    SwDoc *pDoc = rTable.GetFrmFmt()->GetDoc();
+    SwClientIter aIter( *(SwModify*)pDoc->GetDfltGrfFmtColl() );
+    SwClient *pCli;
+    if ( 0 != (pCli = aIter.First( TYPE(SwCntntNode) )) )
+        do
+        {   if ( !((SwCntntNode*)pCli)->GetOLENode() )
+                continue;
+            SwOLENode *pONd = (SwOLENode*)pCli;
+            if ( rTable.GetFrmFmt()->GetName() == pONd->GetChartTblName() )
+            {
+                SwOLEObj& rOObj = pONd->GetOLEObj();
+                SchMemChart *pData = SchDLL::GetChartData( rOObj.GetOleRef() );
+                if ( pData )
+                {
+                    const SwTableBox *pSttBox = (SwTableBox*)
+                                                pData->SomeData3().ToInt32();
+                    if ( long(pSttBox) == LONG_MAX )
+                        pSttBox = ::lcl_FindFirstBox( rTable );
+                    const SwTableBox *pEndBox = (SwTableBox*)
+                                                pData->SomeData4().ToInt32();
+                    if ( long(pEndBox) == LONG_MAX )
+                        pEndBox = ::lcl_FindLastBox( rTable );
+                    FASTBOOL bSttFound = FALSE, bEndFound = FALSE;
+                    const SwTableSortBoxes &rBoxes = rTable.GetTabSortBoxes();
+                    for ( USHORT i = 0; i < rBoxes.Count(); ++i )
+                    {
+                        const SwTableBox *pTmp = rBoxes[i];
+                        if ( pTmp == pSttBox )
+                            bSttFound = TRUE;
+                        if ( pTmp == pEndBox )
+                            bEndFound = TRUE;
+                    }
+                    if ( !bSttFound )
+                        pSttBox = rTable.GetTabLines()[0]->GetTabBoxes()[0];
+                    if ( !bEndFound )
+                    {
+                        SwTableLine *pLine =
+                            rTable.GetTabLines()[rTable.GetTabLines().Count()-1];
+                        pEndBox = pLine->GetTabBoxes()[pLine->GetTabBoxes().Count()-1];
+                    }
+                    String &rStr = pData->SomeData1();
+                    rStr = '<'; rStr += pSttBox->GetName(); rStr += ':';
+                    rStr += pEndBox->GetName(); rStr += '>';
+                    pData->SomeData3().Erase(); pData->SomeData4().Erase();
+                    SchDLL::Update( rOObj.GetOleRef(), pData );
+                }
+            }
+        } while ( 0 != (pCli = aIter.Next()) );
+}
+
+#pragma optimize("",on)
+
diff --git a/sw/source/core/graphic/grfatr.cxx b/sw/source/core/graphic/grfatr.cxx
new file mode 100644
index 000000000000..ea0b6ea7658e
--- /dev/null
+++ b/sw/source/core/graphic/grfatr.cxx
@@ -0,0 +1,417 @@
+/*************************************************************************
+ *
+ *  $RCSfile: grfatr.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:20 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _COM_SUN_STAR_TEXT_RELORIENTATION_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_VERTORIENTATION_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_HORIZONTALADJUST_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_DOCUMENTSTATISTIC_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_HORIORIENTATION_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_HORIORIENTATIONFORMAT_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_NOTEPRINTMODE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_SIZETYPE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_VERTORIENTATIONFORMAT_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_WRAPTEXTMODE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_GRAPHICCROP_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XTEXTGRAPHICOBJECTSSUPPLIER_HPP_
+#include 
+#endif
+
+#ifndef _GRFMGR_HXX
+#include 
+#endif
+#ifndef _SWTYPES_HXX
+#include 
+#endif
+#ifndef _GRFATR_HXX
+#include 
+#endif
+
+#ifndef _CMDID_H
+#include 
+#endif
+#ifndef _UNOMID_H
+#include 
+#endif
+
+using namespace ::com::sun::star;
+
+TYPEINIT1_AUTOFACTORY(SwCropGrf, SfxPoolItem)
+TYPEINIT1_AUTOFACTORY(SwGammaGrf, SfxPoolItem)
+
+/******************************************************************************
+ *  Implementierung     class SwMirrorGrf
+ ******************************************************************************/
+
+SfxPoolItem* SwMirrorGrf::Clone( SfxItemPool* ) const
+{
+    return new SwMirrorGrf( *this );
+}
+
+sal_uInt16 SwMirrorGrf::GetValueCount() const
+{
+    return RES_GRFMIRROR_END - RES_GRFMIRROR_BEGIN;
+}
+
+int SwMirrorGrf::operator==( const SfxPoolItem& rItem) const
+{
+    return SfxEnumItem::operator==(rItem) &&
+            ((SwMirrorGrf&)rItem).IsGrfToggle() == IsGrfToggle();
+}
+
+BOOL SwMirrorGrf::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+    sal_Bool bRet = sal_True,
+         bVal;
+    // Vertikal und Horizontal sind mal getauscht worden!
+    switch ( nMemberId )
+    {
+        case MID_MIRROR_HORZ:
+            bVal = GetValue() == RES_MIRROR_GRF_VERT ||
+                   GetValue() == RES_MIRROR_GRF_BOTH;
+            break;
+        case MID_MIRROR_VERT:
+            bVal = GetValue() == RES_MIRROR_GRF_HOR ||
+                   GetValue() == RES_MIRROR_GRF_BOTH;
+            break;
+        case MID_MIRROR_HORZ_PAGETOGGLE:
+            bVal = IsGrfToggle();
+            break;
+        default:
+            ASSERT( !this, "unknown MemberId" );
+            bRet = sal_False;
+    }
+    rVal.setValue( &bVal, ::getBooleanCppuType() );
+    return bRet;
+}
+
+BOOL SwMirrorGrf::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+    sal_Bool bRet = sal_True;
+    sal_Bool bVal = *(sal_Bool*)rVal.getValue();
+    // Vertikal und Horizontal sind mal getauscht worden!
+    switch ( nMemberId )
+    {
+        case MID_MIRROR_HORZ:
+            if ( bVal )
+            {
+                if ( GetValue() == RES_MIRROR_GRF_HOR )
+                    SetValue( RES_MIRROR_GRF_BOTH );
+                else if ( GetValue() != RES_MIRROR_GRF_BOTH )
+                    SetValue( RES_MIRROR_GRF_VERT );
+            }
+            else
+            {
+                if ( GetValue() == RES_MIRROR_GRF_BOTH )
+                    SetValue( RES_MIRROR_GRF_HOR );
+                else if ( GetValue() == RES_MIRROR_GRF_VERT )
+                    SetValue( RES_DONT_MIRROR_GRF );
+            }
+            break;
+        case MID_MIRROR_VERT:
+            if ( bVal )
+            {
+                if ( GetValue() == RES_MIRROR_GRF_VERT )
+                    SetValue( RES_MIRROR_GRF_BOTH );
+                else if ( GetValue() != RES_MIRROR_GRF_BOTH )
+                    SetValue( RES_MIRROR_GRF_HOR );
+            }
+            else
+            {
+                if ( GetValue() == RES_MIRROR_GRF_BOTH )
+                    SetValue( RES_MIRROR_GRF_VERT );
+                else if ( GetValue() == RES_MIRROR_GRF_HOR )
+                    SetValue( RES_DONT_MIRROR_GRF );
+            }
+            break;
+        case MID_MIRROR_HORZ_PAGETOGGLE:
+            SetGrfToggle( bVal );
+            break;
+        default:
+            ASSERT( !this, "unknown MemberId" );
+            bRet = sal_False;
+    }
+    return bRet;
+}
+
+
+/******************************************************************************
+ *  Implementierung     class SwCropGrf
+ ******************************************************************************/
+
+SwCropGrf::SwCropGrf()
+    : SvxGrfCrop( RES_GRFATR_CROPGRF )
+{}
+
+SwCropGrf::SwCropGrf(sal_Int32 nL, sal_Int32 nR, sal_Int32 nT, sal_Int32 nB )
+    : SvxGrfCrop( nL, nR, nT, nB, RES_GRFATR_CROPGRF )
+{}
+
+SfxPoolItem* SwCropGrf::Clone( SfxItemPool* ) const
+{
+    return new SwCropGrf( *this );
+}
+
+// ------------------------------------------------------------------
+
+SfxPoolItem* SwRotationGrf::Clone( SfxItemPool * ) const
+{
+    return new SwRotationGrf( GetValue(), aUnrotatedSize );
+}
+
+
+int SwRotationGrf::operator==( const SfxPoolItem& rCmp ) const
+{
+    return SfxUInt16Item::operator==( rCmp ) &&
+        GetUnrotatedSize() == ((SwRotationGrf&)rCmp).GetUnrotatedSize();
+}
+
+
+BOOL SwRotationGrf::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+/*
+!!JP 28.07.00: IMPL- fehlt
+    text::GraphicCrop  aCrop;
+    aCrop.Left   = TWIP_TO_MM100(nLeft);
+    aCrop.Right  = TWIP_TO_MM100(nRight) ;
+    aCrop.Top    = TWIP_TO_MM100(nTop)   ;
+    aCrop.Bottom = TWIP_TO_MM100(nBottom);
+    rVal.setValue( &aCrop, ::getCppuType((text::GraphicCrop*)0) );
+
+    return   sal_True;
+*/
+    return   sal_False;
+}
+
+BOOL SwRotationGrf::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+    sal_Bool bRet = sal_False;
+/*
+!!JP 28.07.00: IMPL- fehlt
+    if(rVal.getValueType() == ::getCppuType((const text::GraphicCrop*)0))
+    {
+        const text::GraphicCrop* pCrop = (const text::GraphicCrop*)rVal.getValue();
+Size aUnrotatedSize;
+        nLeft   = MM100_TO_TWIP(pCrop->Left  );
+        nRight  = MM100_TO_TWIP(pCrop->Right );
+        nTop    = MM100_TO_TWIP(pCrop->Top   );
+        nBottom = MM100_TO_TWIP(pCrop->Bottom);
+        bRet = sal_True;
+    }
+    else
+        //exception(wrong_type)
+        ;
+*/
+    return bRet;
+}
+
+// ------------------------------------------------------------------
+
+SfxPoolItem* SwLuminanceGrf::Clone( SfxItemPool *pPool ) const
+{
+    return new SwLuminanceGrf( *this );
+}
+
+// ------------------------------------------------------------------
+
+SfxPoolItem* SwContrastGrf::Clone( SfxItemPool *pPool ) const
+{
+    return new SwContrastGrf( *this );
+}
+
+// ------------------------------------------------------------------
+
+SfxPoolItem* SwChannelRGrf::Clone( SfxItemPool *pPool ) const
+{
+    return new SwChannelRGrf( *this );
+}
+
+// ------------------------------------------------------------------
+
+SfxPoolItem* SwChannelGGrf::Clone( SfxItemPool *pPool ) const
+{
+    return new SwChannelGGrf( *this );
+}
+
+// ------------------------------------------------------------------
+
+SfxPoolItem* SwChannelBGrf::Clone( SfxItemPool *pPool ) const
+{
+    return new SwChannelBGrf( *this );
+}
+
+// ------------------------------------------------------------------
+
+SfxPoolItem* SwGammaGrf::Clone( SfxItemPool *pPool ) const
+{
+    return new SwGammaGrf( *this );
+}
+
+int SwGammaGrf::operator==( const SfxPoolItem& rCmp ) const
+{
+    return SfxPoolItem::operator==( rCmp ) &&
+        nValue == ((SwGammaGrf&)rCmp).GetValue();
+}
+
+BOOL SwGammaGrf::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+//!!JP 28.07.00: IMPL- fehlt
+    return sal_False;
+}
+
+BOOL SwGammaGrf::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+    sal_Bool bRet = sal_False;
+/*
+!!JP 28.07.00: IMPL- fehlt
+    double aVal;
+    rVal >>= aVal;
+
+    if(rVal.getValueType() == ::getCppuType((const text::GraphicCrop*)0))
+    {
+        const text::GraphicCrop* pCrop = (const text::GraphicCrop*)rVal.getValue();
+Size aUnrotatedSize;
+        nLeft   = MM100_TO_TWIP(pCrop->Left  );
+        nRight  = MM100_TO_TWIP(pCrop->Right );
+        nTop    = MM100_TO_TWIP(pCrop->Top   );
+        nBottom = MM100_TO_TWIP(pCrop->Bottom);
+        bRet = sal_True;
+    }
+    else
+        //exception(wrong_type)
+        ;
+*/
+    return bRet;
+
+
+}
+
+// ------------------------------------------------------------------
+
+SfxPoolItem* SwInvertGrf::Clone( SfxItemPool *pPool ) const
+{
+    return new SwInvertGrf( *this );
+}
+
+// ------------------------------------------------------------------
+
+SfxPoolItem* SwTransparencyGrf::Clone( SfxItemPool *pPool ) const
+{
+    return new SwTransparencyGrf( *this );
+}
+
+// ------------------------------------------------------------------
+
+SfxPoolItem* SwDrawModeGrf::Clone( SfxItemPool *pPool ) const
+{
+    return new SwDrawModeGrf( *this );
+}
+
+USHORT SwDrawModeGrf::GetValueCount() const
+{
+    // GRAPHICDRAWMODE_STANDARD = 0,
+    // GRAPHICDRAWMODE_GREYS = 1,
+    // GRAPHICDRAWMODE_MONO = 2,
+    // GRAPHICDRAWMODE_WATERMARK = 3
+    return GRAPHICDRAWMODE_WATERMARK + 1;
+}
+
+BOOL SwDrawModeGrf::QueryValue( com::sun::star::uno::Any& rVal,
+                                BYTE nMemberId ) const
+{
+    return FALSE;
+}
+
+BOOL SwDrawModeGrf::PutValue( const com::sun::star::uno::Any& rVal,
+                                BYTE nMemberId  )
+{
+    return FALSE;
+}
+
+
+
diff --git a/sw/source/core/graphic/makefile.mk b/sw/source/core/graphic/makefile.mk
new file mode 100644
index 000000000000..8e0603aaacac
--- /dev/null
+++ b/sw/source/core/graphic/makefile.mk
@@ -0,0 +1,105 @@
+#*************************************************************************
+#
+#   $RCSfile: makefile.mk,v $
+#
+#   $Revision: 1.1.1.1 $
+#
+#   last change: $Author: hr $ $Date: 2000-09-19 00:08:20 $
+#
+#   The Contents of this file are made available subject to the terms of
+#   either of the following licenses
+#
+#          - GNU Lesser General Public License Version 2.1
+#          - Sun Industry Standards Source License Version 1.1
+#
+#   Sun Microsystems Inc., October, 2000
+#
+#   GNU Lesser General Public License Version 2.1
+#   =============================================
+#   Copyright 2000 by Sun Microsystems, Inc.
+#   901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+#   This library is free software; you can redistribute it and/or
+#   modify it under the terms of the GNU Lesser General Public
+#   License version 2.1, as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   Lesser General Public License for more details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+#   License along with this library; if not, write to the Free Software
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+#   MA  02111-1307  USA
+#
+#
+#   Sun Industry Standards Source License Version 1.1
+#   =================================================
+#   The contents of this file are subject to the Sun Industry Standards
+#   Source License Version 1.1 (the "License"); You may not use this file
+#   except in compliance with the License. You may obtain a copy of the
+#   License at http://www.openoffice.org/license.html.
+#
+#   Software provided under this License is provided on an "AS IS" basis,
+#   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+#   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+#   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+#   See the License for the specific provisions governing your rights and
+#   obligations concerning the Software.
+#
+#   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+#   Copyright: 2000 by Sun Microsystems, Inc.
+#
+#   All Rights Reserved.
+#
+#   Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sw
+TARGET=graphic
+
+AUTOSEG=true
+
+PROJECTPCH=core_pch
+PDBTARGET=core_pch
+PROJECTPCHSOURCE=..\core_1st\core_pch
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE :  $(PRJ)$/inc$/swpre.mk
+.INCLUDE :  settings.mk
+.INCLUDE :  $(PRJ)$/inc$/sw.mk
+
+# --- Files --------------------------------------------------------
+
+CXXFILES = \
+        grfatr.cxx \
+        ndgrf.cxx
+
+.IF "$(USE_GRFOBJECT)" == ""
+CXXFILES += grfcache.cxx
+.ENDIF
+
+SLOFILES =	\
+        $(SLO)$/grfatr.obj \
+        $(SLO)$/ndgrf.obj
+
+.IF "$(USE_GRFOBJECT)" == ""
+SLOFILES += $(SLO)$/grfcache.obj
+.ENDIF
+
+EXCEPTIONSFILES = \
+        $(SLO)$/grfcache.obj \
+        $(SLO)$/ndgrf.obj
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE :  target.mk
+
diff --git a/sw/source/core/graphic/ndgrf.cxx b/sw/source/core/graphic/ndgrf.cxx
new file mode 100644
index 000000000000..73b8613d19c1
--- /dev/null
+++ b/sw/source/core/graphic/ndgrf.cxx
@@ -0,0 +1,2061 @@
+/*************************************************************************
+ *
+ *  $RCSfile: ndgrf.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:20 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#define ITEMID_BOXINFO      SID_ATTR_BORDER_INNER
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _UCBHELPER_CONTENT_HXX
+#include 
+#endif
+#ifndef _UNDO_HXX //autogen
+#include 
+#endif
+#ifndef _LINKNAME_HXX //autogen
+#include 
+#endif
+#ifndef _BINDCTX_HXX //autogen
+#include 
+#endif
+#ifndef _LINKMGR_HXX //autogen
+#include 
+#endif
+#ifndef _SVSTOR_HXX //autogen
+#include 
+#endif
+#ifndef _SFXDOCINF_HXX //autogen
+#include 
+#endif
+#ifndef _URLOBJ_HXX //autogen
+#include 
+#endif
+#ifndef _SVXLINKMGR_HXX
+#include 
+#endif
+#ifndef _SVX_BOXITEM_HXX //autogen
+#include 
+#endif
+#ifndef _IMAP_HXX //autogen
+#include 
+#endif
+#ifndef _FILTER_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_IMPGRF_HXX //autogen
+#include 
+#endif
+
+
+#ifndef _FMTFSIZE_HXX //autogen
+#include 
+#endif
+#ifndef _FMTURL_HXX //autogen
+#include 
+#endif
+#ifndef _FRMFMT_HXX //autogen
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _FRMATR_HXX
+#include 
+#endif
+#ifndef _GRFATR_HXX
+#include 
+#endif
+#ifndef _SWTYPES_HXX
+#include 
+#endif
+#ifndef _NDGRF_HXX
+#include 
+#endif
+#ifndef _FMTCOL_HXX
+#include 
+#endif
+#ifndef _HINTS_HXX
+#include 
+#endif
+#ifndef _SW3IO_HXX
+#include 
+#endif
+#ifndef _SWBASLNK_HXX
+#include 
+#endif
+#ifndef _PAGEFRM_HXX
+#include 
+#endif
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::uno;
+using namespace ::rtl;
+
+// Code for the new GraphicObject
+#ifdef USE_GRFOBJECT
+
+// --------------------
+// SwGrfNode
+// --------------------
+SwGrfNode::SwGrfNode( const SwNodeIndex & rWhere,
+                  const String& rGrfName, const String& rFltName,
+                  const Graphic* pGraphic,
+                  SwGrfFmtColl *pGrfColl,
+                  SwAttrSet* pAutoAttr )
+    : SwNoTxtNode( rWhere, ND_GRFNODE, pGrfColl, pAutoAttr )
+{
+    aGrfObj.SetSwapStreamHdl( LINK( this, SwGrfNode, SwapGraphic ) );
+    bInSwapIn = bChgTwipSize = bLoadLowResGrf = bFrameInPaint =
+        bScaleImageMap = FALSE;
+    bGrafikArrived = TRUE;
+    ReRead( rGrfName, rFltName, pGraphic, FALSE );
+}
+
+// Konstruktor fuer den SW/G-Reader. Dieser ctor wird verwendet,
+// wenn eine gelinkte Grafik gelesen wird. Sie liest diese NICHT ein.
+
+
+SwGrfNode::SwGrfNode( const SwNodeIndex & rWhere,
+                  const String& rGrfName, const String& rFltName,
+                  SwGrfFmtColl *pGrfColl,
+                  SwAttrSet* pAutoAttr )
+    : SwNoTxtNode( rWhere, ND_GRFNODE, pGrfColl, pAutoAttr )
+{
+    aGrfObj.SetSwapStreamHdl( LINK( this, SwGrfNode, SwapGraphic ) );
+
+    Graphic aGrf; aGrf.SetDefaultType();
+    aGrfObj.SetGraphic( aGrf, rGrfName );
+
+    bInSwapIn = bChgTwipSize = bLoadLowResGrf = bFrameInPaint =
+        bScaleImageMap = FALSE;
+    bGrafikArrived = TRUE;
+
+    InsertLink( rGrfName, rFltName );
+    if( IsLinkedFile() )
+    {
+        INetURLObject aUrl( rGrfName );
+        if( aUrl.GetProtocol() == INET_PROT_FILE )
+        {
+            try
+            {
+                ::ucb::Content aTestContent( aUrl.GetMainURL(),
+                                    uno::Reference< XCommandEnvironment >());
+                if(aTestContent.isDocument())
+//              if( FSYS_KIND_FILE == FileStat( aFileNm ).GetKind() )
+                    // File vorhanden, Verbindung herstellen ohne ein Update
+                    ((SwBaseLink*)&refLink)->Connect();
+            }
+            catch(...)
+            {
+                DBG_ERROR("Exception caught")
+            }
+        }
+    }
+}
+
+
+// erneutes Einlesen, falls Graphic nicht Ok ist. Die
+// aktuelle wird durch die neue ersetzt.
+
+BOOL SwGrfNode::ReRead( const String& rGrfName, const String& rFltName,
+                        const Graphic* pGraphic, BOOL bNewGrf )
+{
+    BOOL bReadGrf = FALSE, bSetTwipSize = TRUE;
+
+    ASSERT( pGraphic || rGrfName.Len(), "GrafikNode ohne Name und Grafik" );
+
+    // ReadRead mit Namen
+    if( refLink.Is() )
+    {
+        ASSERT( !bInSwapIn, "ReRead: stehe noch im SwapIn" );
+        if( rGrfName.Len() )
+        {
+            // Besonderheit: steht im FltNamen DDE, handelt es sich um eine
+            //                  DDE-gelinkte Grafik
+            String sCmd( rGrfName );
+            if( rFltName.Len() )
+            {
+                USHORT nNewType;
+                if( rFltName.EqualsAscii( "DDE" ))
+                    nNewType = OBJECT_CLIENT_DDE;
+                else
+                {
+                    ::MakeLnkName( sCmd, 0, rGrfName, aEmptyStr, &rFltName );
+                    nNewType = OBJECT_CLIENT_GRF;
+                }
+
+                if( nNewType != refLink->GetObjectType() )
+                {
+                    refLink->Disconnect();
+                    ((SwBaseLink*)&refLink)->SetObjType( nNewType );
+                }
+            }
+
+            refLink->SetLinkSourceName( new SvLinkName( sCmd ) );
+        }
+        else        // kein Name mehr, Link aufheben
+        {
+            GetDoc()->GetLinkManager().Remove( *refLink );
+            refLink.Clear();
+        }
+
+        if( pGraphic )
+        {
+            aGrfObj.SetGraphic( *pGraphic, rGrfName );
+            bReadGrf = TRUE;
+        }
+        else
+        {
+            // MIB 25.02.97: Daten der alten Grafik zuruecksetzen, damit
+            // die korrekte Ersatz-Darstellung erscheint, wenn die
+            // der neue Link nicht geladen werden konnte.
+            Graphic aGrf; aGrf.SetDefaultType();
+            aGrfObj.SetGraphic( aGrf, rGrfName );
+
+            if( refLink.Is() )
+            {
+                if( GetFrm() )
+                {
+                    SwMsgPoolItem aMsgHint( RES_GRF_REREAD_AND_INCACHE );
+                    Modify( &aMsgHint, &aMsgHint );
+                }
+                else
+                    ((SwBaseLink*)&refLink)->SwapIn();
+            }
+            bSetTwipSize = FALSE;
+        }
+    }
+    else if( pGraphic && !rGrfName.Len() )
+    {
+        aGrfObj.SetGraphic( *pGraphic );
+        bReadGrf = TRUE;
+
+        if( aStrmName.Len() )
+            DelStreamName();
+    }
+        // Import einer Grafik:
+        // Ist die Grafik bereits geladen?
+    else if( !bNewGrf && GRAPHIC_NONE != aGrfObj.GetType() )
+        return TRUE;
+
+    else
+    {
+        if( aStrmName.Len() )
+            DelStreamName();
+
+        // einen neuen Grafik-Link anlegen
+        InsertLink( rGrfName, rFltName );
+
+        if( GetNodes().IsDocNodes() )
+        {
+            if( !pGraphic )
+            {
+                // MIB 25.02.97: Daten der alten Grafik zuruecksetzen, damit
+                // die korrekte Ersatz-Darstellung erscheint, wenn die
+                // der neue Kink nicht geladen werden konnte.
+                Graphic aGrf; aGrf.SetDefaultType();
+                aGrfObj.SetGraphic( aGrf, rGrfName );
+                ((SwBaseLink*)&refLink)->SwapIn();
+            }
+            else
+            {
+                aGrfObj.SetGraphic( *pGraphic, rGrfName );
+                bReadGrf = TRUE;
+                // Verbindung herstellen ohne ein Update; Grafik haben wir!
+                ((SwBaseLink*)&refLink)->Connect();
+            }
+        }
+    }
+
+    // Bug 39281: Size nicht sofort loeschen - Events auf ImageMaps
+    //            sollten nicht beim Austauschen nicht ins "leere greifen"
+    if( bSetTwipSize )
+        SetTwipSize( ::GetGraphicSizeTwip( aGrfObj.GetGraphic(), 0 ) );
+
+    // erzeuge noch einen Update auf die Frames
+    if( bReadGrf && bNewGrf )
+    {
+        SwMsgPoolItem aMsgHint( RES_UPDATE_ATTR );
+        Modify( &aMsgHint, &aMsgHint );
+    }
+
+    return bReadGrf;
+}
+
+
+SwGrfNode::~SwGrfNode()
+{
+    SwDoc* pDoc = GetDoc();
+    if( refLink.Is() )
+    {
+        ASSERT( !bInSwapIn, "DTOR: stehe noch im SwapIn" );
+        pDoc->GetLinkManager().Remove( *refLink );
+        refLink->Disconnect();
+    }
+    else
+    {
+        if( !pDoc->IsInDtor() && aStrmName.Len() )
+            DelStreamName();
+    }
+    //#39289# Die Frames muessen hier bereits geloescht weil der DTor der
+    //Frms die Grafik noch fuer StopAnimation braucht.
+    if( GetDepends() )
+        DelFrms();
+}
+
+
+SwCntntNode *SwGrfNode::SplitNode( const SwPosition &rPos )
+{
+    return this;
+}
+
+
+SwGrfNode * SwNodes::MakeGrfNode( const SwNodeIndex & rWhere,
+                                const String& rGrfName,
+                                const String& rFltName,
+                                const Graphic* pGraphic,
+                                SwGrfFmtColl* pGrfColl,
+                                SwAttrSet* pAutoAttr,
+                                BOOL bDelayed )
+{
+    ASSERT( pGrfColl, "MakeGrfNode: Formatpointer ist 0." );
+    SwGrfNode *pNode;
+    // Delayed erzeugen nur aus dem SW/G-Reader
+    if( bDelayed )
+        pNode = new SwGrfNode( rWhere, rGrfName,
+                                rFltName, pGrfColl, pAutoAttr );
+    else
+        pNode = new SwGrfNode( rWhere, rGrfName,
+                                rFltName, pGraphic, pGrfColl, pAutoAttr );
+    return pNode;
+}
+
+
+Size SwGrfNode::GetTwipSize() const
+{
+    return nGrfSize;
+}
+
+
+
+// Returnwert:
+// -1 : ReRead erfolgreich
+//  0 : nicht geladen
+//  1 : Einlesen erfolgreich
+
+
+short SwGrfNode::SwapIn( BOOL bWaitForData )
+{
+    if( bInSwapIn )                 // nicht rekuriv!!
+        return !aGrfObj.IsSwappedOut();
+
+    short nRet = 0;
+    bInSwapIn = TRUE;
+    SwBaseLink* pLink = (SwBaseLink*)(SvBaseLink*) refLink;
+    if( pLink )
+    {
+        if( GRAPHIC_NONE == aGrfObj.GetType() ||
+            GRAPHIC_DEFAULT == aGrfObj.GetType() )
+        {
+            // noch nicht geladener Link
+            if( pLink->SwapIn( bWaitForData ) )
+                nRet = -1;
+            else if( GRAPHIC_DEFAULT == aGrfObj.GetType() )
+            {
+                // keine default Bitmap mehr, also neu Painten!
+                aGrfObj.SetGraphic( Graphic() );
+                SwMsgPoolItem aMsgHint( RES_GRAPHIC_PIECE_ARRIVED );
+                Modify( &aMsgHint, &aMsgHint );
+            }
+        }
+        else if( aGrfObj.IsSwappedOut() )
+            // nachzuladender Link
+            nRet = pLink->SwapIn( bWaitForData ) ? 1 : 0;
+        else
+            nRet = 1;
+    }
+    else if( aGrfObj.IsSwappedOut() )
+    {
+        // Die Grafik ist im Storage oder im TempFile drin
+        if( !aStrmName.Len() )
+            nRet = (short)aGrfObj.SwapIn();
+        else
+        {
+            SvStorageRef refRoot = GetDoc()->GetDocStorage();
+            ASSERT( refRoot.Is(), "Kein Storage am Doc" );
+            if( refRoot.Is() )
+            {
+                String aPicStgName( String::CreateFromAscii(
+                        RTL_CONSTASCII_STRINGPARAM( "EmbeddedPictures" )));
+                SvStorageRef refPics = refRoot->OpenStorage( aPicStgName,
+                        STREAM_READ | STREAM_SHARE_DENYWRITE );
+                if( refPics->GetError() == SVSTREAM_OK )
+                {
+                    SvStorageStreamRef refStrm =
+                        refPics->OpenStream( aStrmName,
+                        STREAM_READ | STREAM_SHARE_DENYWRITE );
+                    if( refStrm->GetError() == SVSTREAM_OK )
+                    {
+                        refStrm->SetVersion( refRoot->GetVersion() );
+                        if( aGrfObj.SwapIn( refStrm ) )
+                            nRet = 1;
+                    }
+                }
+            }
+        }
+    }
+    else
+        nRet = 1;
+    DBG_ASSERTWARNING( nRet, "Grafik kann nicht eingeswapt werden" );
+
+    if( nRet )
+    {
+        if( !nGrfSize.Width() && !nGrfSize.Height() )
+            SetTwipSize( ::GetGraphicSizeTwip( aGrfObj.GetGraphic(), 0 ) );
+    }
+    bInSwapIn = FALSE;
+    return nRet;
+}
+
+
+short SwGrfNode::SwapOut()
+{
+    if( aGrfObj.GetType() != GRAPHIC_DEFAULT &&
+        aGrfObj.GetType() != GRAPHIC_NONE &&
+        !aGrfObj.IsSwappedOut() && !bInSwapIn )
+    {
+        if( !refLink.Is() )
+        {
+            // Das Swapping brauchen wir nur fuer Embedded Pictures
+            // Die Grafik wird in eine TempFile geschrieben, wenn
+            // sie frisch eingefuegt war, d.h. wenn es noch keinen
+            // Streamnamen im Storage gibt.
+            if( !aStrmName.Len() )
+                if( !aGrfObj.SwapOut() )
+                    return 0;
+        }
+        // Geschriebene Grafiken oder Links werden jetzt weggeschmissen
+        return (short) aGrfObj.SwapOut( NULL );
+    }
+    return 1;
+}
+
+// Wird nach einem SaveAs aufgerufen und setzt die StreamNamen um
+
+
+void SwGrfNode::SaveCompleted( BOOL bClear )
+{
+    if( aNewStrmName.Len() )
+    {
+        if( !bClear )       // der Name wird zum aktuellen
+            aStrmName = aNewStrmName;
+        aNewStrmName.Erase();
+    }
+}
+
+
+// Falls die Grafik noch nicht im Doc-Storage existiert,
+// wird sie neu geschrieben; falls sie bereits drin ist,
+// wird nicht geschrieben. Wenn der Storage nicht dem
+// Doc-Storage entspricht, wird, falls aNewStrmName nicht
+// besetzt ist, in diesem Storage unter dem angegebenen
+// Streamnamen abgelegt (SaveAs). nach einem SaveAs wird
+// vom SW3-I/O-System noch SaveCompleted() aufgerufen,
+// da nun der Doc-Storage dem neuen Storage entspricht.
+
+
+BOOL SwGrfNode::StoreGraphics( SvStorage* pRoot )
+{
+    if( !refLink.Is() )
+    {
+        String aName( aStrmName );
+        SvStorage* pDocStg = GetDoc()->GetDocStorage();
+        if( !pRoot )
+            pRoot = pDocStg;
+
+        String aPicStgName( String::CreateFromAscii(
+                        RTL_CONSTASCII_STRINGPARAM( "EmbeddedPictures" )));
+        if( pRoot != pDocStg )
+        {
+            // Neuer Storage. Wenn die Grafik im DocStg drin ist,
+            // kann sie bequem per CopyTo() kopiert werden.
+            if( aName.Len() )
+            {
+                SvStorageRef refSrcPics =
+                    pDocStg->OpenStorage( aPicStgName,
+                        STREAM_READ | STREAM_SHARE_DENYWRITE );
+
+                SvStorageStreamRef refStrm;
+
+                BOOL bWriteNew = pDocStg->GetVersion() != pRoot->GetVersion();
+                if( !bWriteNew &&
+                    SOFFICE_FILEFORMAT_40 <= pRoot->GetVersion() )
+                {
+                    refStrm = refSrcPics->OpenStream( aName,
+                                    STREAM_READ | STREAM_SHARE_DENYWRITE );
+                    if( SVSTREAM_OK == refStrm->GetError() )
+                    {
+                        // JP 21.06.98: pruefe ob der CompressMode uebereinstimmt
+                        USHORT nCmprsMode =
+                                Graphic::GetGraphicsCompressMode(*refStrm ) &
+                                ~(COMPRESSMODE_ZBITMAP|COMPRESSMODE_NATIVE );
+                        USHORT nNewCmprsMode = 0;
+                        if( GRAPHIC_BITMAP == aGrfObj.GetType() &&
+                            GetDoc()->GetInfo()->IsSaveGraphicsCompressed() )
+                            nNewCmprsMode |= COMPRESSMODE_ZBITMAP;
+                        if( SOFFICE_FILEFORMAT_40 < pRoot->GetVersion() &&
+                            GetDoc()->GetInfo()->IsSaveOriginalGraphics() )
+                            nNewCmprsMode |= COMPRESSMODE_NATIVE;
+
+                        if( nCmprsMode != nNewCmprsMode )
+                        {
+                            // der Kompressedmode stimmt nicht, also muss
+                            // ggfs. die Grafik reingeswappt und ueber den
+                            // unteren Teil neu geschrieben werden.
+                            bWriteNew = TRUE;
+                            refStrm->Seek( STREAM_SEEK_TO_BEGIN );
+                        }
+                    }
+                }
+
+                if( bWriteNew )
+                {
+                    if( aGrfObj.IsSwappedOut() &&
+                        SVSTREAM_OK == refSrcPics->GetError() )
+                    {
+                        if( !refStrm.Is() )
+                            refStrm = refSrcPics->OpenStream( aName,
+                                    STREAM_READ | STREAM_SHARE_DENYWRITE );
+                        if( SVSTREAM_OK == refStrm->GetError() )
+                        {
+                            refStrm->SetVersion( pDocStg->GetVersion() );
+                            if( !aGrfObj.SwapIn( refStrm ) )
+                                return FALSE;
+                        }
+                    }
+                    aName.Erase();
+                }
+                else
+                {
+                    SvStorageRef refDstPics =
+                        pRoot->OpenStorage( aPicStgName,
+                            STREAM_READWRITE | STREAM_SHARE_DENYALL );
+                    if( refDstPics->IsContained( aName ) )
+                        // nur neu erzeugen, wenn Name schon vorhanden ist!
+                        aName = Sw3Io::UniqueName( refDstPics, "Pic" );
+
+                    if( refSrcPics->CopyTo( aStrmName, refDstPics, aName )
+                        && refDstPics->Commit() )
+                        aNewStrmName = aName;
+                    else
+                        return FALSE;
+                }
+            }
+        }
+
+        if( !aName.Len() )
+        {
+            ASSERT( pRoot, "Kein Storage gegeben" );
+            if( pRoot )
+            {
+                SvStorageRef refPics =
+                    pRoot->OpenStorage( aPicStgName,
+                        STREAM_READWRITE | STREAM_SHARE_DENYALL );
+                if( SVSTREAM_OK == refPics->GetError() )
+                {
+                    aName = Sw3Io::UniqueName( refPics, "Pic" );
+                    SvStorageStreamRef refStrm =
+                        refPics->OpenStream( aName,
+                        STREAM_READWRITE | STREAM_SHARE_DENYALL );
+                    if( SVSTREAM_OK == refStrm->GetError() )
+                    {
+                        // HACK bis die Grafik als Portable markiert
+                        // werden kann!!!
+                        // Die Grafik kann in einer TempFile sein!
+                        FASTBOOL bIsSwapOut = aGrfObj.IsSwappedOut();
+                        if( bIsSwapOut && !aGrfObj.SwapIn() )
+                            return FALSE;
+
+                        refStrm->SetVersion( pRoot->GetVersion() );
+
+                        //JP 04.05.98: laut ChangesMail vom KA und Bug 49617
+                        //JP 21.06.98: laut ChangesMail vom KA, natives Save
+                        USHORT nComprMode = refStrm->GetCompressMode();
+                        if( SOFFICE_FILEFORMAT_40 <= refStrm->GetVersion() &&
+                            GRAPHIC_BITMAP == aGrfObj.GetType() &&
+                            GetDoc()->GetInfo()->IsSaveGraphicsCompressed() )
+                            nComprMode |= COMPRESSMODE_ZBITMAP;
+                        else
+                            nComprMode &= ~COMPRESSMODE_ZBITMAP;
+
+                        //JP 21.06.98: laut ChangesMail vom KA, natives Save
+                        if( SOFFICE_FILEFORMAT_40 < refStrm->GetVersion() &&
+                            GetDoc()->GetInfo()->IsSaveOriginalGraphics() )
+                            nComprMode |= COMPRESSMODE_NATIVE;
+                        else
+                            nComprMode &= ~COMPRESSMODE_NATIVE;
+                        refStrm->SetCompressMode( nComprMode );
+
+                        BOOL bRes = FALSE;
+                        if( pRoot == pDocStg )
+                        {
+                            if( aGrfObj.SwapOut( refStrm ) &&
+                                ( refStrm->Commit() | refPics->Commit()
+                                  /*| pRoot->Commit()*/ ))
+                            {
+                                aStrmName = aName;
+                                bRes = TRUE;
+                            }
+                        }
+                        else if( ((Graphic&)aGrfObj.GetGraphic()).
+                                                WriteEmbedded( *refStrm )
+                                && ( refStrm->Commit() | refPics->Commit()
+                                  /*| pRoot->Commit()*/ ))
+                        {
+                            if( bIsSwapOut )
+                                aGrfObj.SwapOut();
+                            aNewStrmName = aName;
+                            bRes = TRUE;
+                        }
+                        return bRes;
+                    }
+                }
+            }
+            // Da fehlte doch was?
+            return FALSE;
+        }
+    }
+    // Schon drin im Storage oder Linked
+    return TRUE;
+}
+
+
+BOOL SwGrfNode::GetFileFilterNms( String* pFileNm, String* pFilterNm ) const
+{
+    BOOL bRet = FALSE;
+    if( refLink.Is() && refLink->GetLinkManager() )
+    {
+        USHORT nType = refLink->GetObjType();
+        if( OBJECT_CLIENT_GRF == nType )
+            bRet = refLink->GetLinkManager()->GetDisplayNames(
+                    *refLink, 0, pFileNm, 0, pFilterNm );
+        else if( OBJECT_CLIENT_DDE == nType && pFileNm && pFilterNm )
+        {
+            String sApp, sTopic, sItem;
+            if( refLink->GetLinkManager()->GetDisplayNames(
+                    *refLink, &sApp, &sTopic, &sItem ) )
+            {
+                ( *pFileNm = sApp ) += cTokenSeperator;
+                ( *pFileNm += sTopic ) += cTokenSeperator;
+                *pFileNm += sItem;
+                pFilterNm->AssignAscii( RTL_CONSTASCII_STRINGPARAM( "DDE" ));
+                bRet = TRUE;
+            }
+        }
+    }
+    return bRet;
+}
+
+
+const String& SwGrfNode::GetStreamName() const
+{
+    if( aNewStrmName.Len() )
+        return aNewStrmName;
+    return aStrmName;
+}
+
+// Eine Grafik Undo-faehig machen. Falls sie sich bereits in
+// einem Storage befindet, muss sie geladen werden.
+
+BOOL SwGrfNode::SavePersistentData()
+{
+    if( refLink.Is() )
+    {
+        ASSERT( !bInSwapIn, "SavePersistentData: stehe noch im SwapIn" );
+        GetDoc()->GetLinkManager().Remove( *refLink );
+        return TRUE;
+    }
+
+    // Erst mal reinswappen, falls sie im Storage ist
+    if( aStrmName.Len() && !SwapIn() )
+        return FALSE;
+
+    if( aStrmName.Len() )
+        DelStreamName();
+
+    // Und in TempFile rausswappen
+    return (BOOL) SwapOut();
+}
+
+
+BOOL SwGrfNode::RestorePersistentData()
+{
+    if( refLink.Is() )
+    {
+        refLink->SetVisible( GetDoc()->IsVisibleLinks() );
+        GetDoc()->GetLinkManager().InsertDDELink( *refLink );
+        if( GetDoc()->GetRootFrm() )
+            refLink->Update();
+    }
+    return TRUE;
+}
+
+
+void SwGrfNode::InsertLink( const String& rGrfName, const String& rFltName )
+{
+    refLink = new SwBaseLink( LINKUPDATE_ONCALL, FORMAT_GDIMETAFILE, this );
+    SwDoc* pDoc = GetDoc();
+    if( GetNodes().IsDocNodes() )
+    {
+        refLink->SetVisible( pDoc->IsVisibleLinks() );
+        if( rFltName.EqualsAscii( "DDE" ))
+        {
+            USHORT nTmp = 0;
+            String sApp, sTopic, sItem;
+            sApp = rGrfName.GetToken( 0, cTokenSeperator, nTmp );
+            sTopic = rGrfName.GetToken( 0, cTokenSeperator, nTmp );
+            sItem = rGrfName.Copy( nTmp );
+            pDoc->GetLinkManager().InsertDDELink( *refLink,
+                                            sApp, sTopic, sItem );
+        }
+        else
+        {
+            BOOL bSync = rFltName.EqualsAscii( "SYNCHRON" );
+            refLink->SetSynchron( bSync );
+            refLink->SetContentType( Graphic::RegisterClipboardFormatName() );
+
+            pDoc->GetLinkManager().InsertFileLink( *refLink,
+                                            OBJECT_CLIENT_GRF, rGrfName,
+                                (!bSync && rFltName.Len() ? &rFltName : 0) );
+        }
+    }
+    aGrfObj.SetLink( rGrfName );
+}
+
+
+void SwGrfNode::ReleaseLink()
+{
+    if( refLink.Is() )
+    {
+        // erst die Grafik reinswappen!
+//      if( aGraphic.IsSwapOut() || !refLink->IsSynchron() )
+        {
+            bInSwapIn = TRUE;
+            SwBaseLink* pLink = (SwBaseLink*)(SvBaseLink*) refLink;
+            pLink->SwapIn( TRUE, TRUE );
+            bInSwapIn = FALSE;
+        }
+        GetDoc()->GetLinkManager().Remove( *refLink );
+        refLink.Clear();
+        aGrfObj.SetLink();
+    }
+}
+
+
+void SwGrfNode::SetTwipSize( const Size& rSz )
+{
+    nGrfSize = rSz;
+    if( IsScaleImageMap() && nGrfSize.Width() && nGrfSize.Height() )
+    {
+        // Image-Map an Grafik-Groesse anpassen
+        ScaleImageMap();
+
+        // Image-Map nicht noch einmal skalieren
+        SetScaleImageMap( FALSE );
+    }
+}
+
+        // Prioritaet beim Laden der Grafik setzen. Geht nur, wenn der Link
+        // ein FileObject gesetzt hat
+void SwGrfNode::SetTransferPriority( USHORT nPrio )
+{
+    if( refLink.Is() && refLink->GetObj() )
+        SvxLinkManager::SetTransferPriority( *refLink, nPrio );
+}
+
+
+void SwGrfNode::ScaleImageMap()
+{
+    if( !nGrfSize.Width() || !nGrfSize.Height() )
+        return;
+
+    // dann die Image-Map skalieren
+    SwFrmFmt* pFmt = GetFlyFmt();
+
+    if( !pFmt )
+        return;
+
+    SwFmtURL aURL( pFmt->GetURL() );
+    if ( !aURL.GetMap() )
+        return;
+
+    BOOL bScale = FALSE;
+    Fraction aScaleX( 1, 1 );
+    Fraction aScaleY( 1, 1 );
+
+    const SwFmtFrmSize& rFrmSize = pFmt->GetFrmSize();
+    const SvxBoxItem& rBox = pFmt->GetBox();
+
+    if( !rFrmSize.GetWidthPercent() )
+    {
+        SwTwips nWidth = rFrmSize.GetWidth();
+
+        nWidth -= rBox.CalcLineSpace(BOX_LINE_LEFT) +
+                  rBox.CalcLineSpace(BOX_LINE_RIGHT);
+
+        ASSERT( nWidth>0, "Gibt es 0 twip breite Grafiken!?" );
+
+        if( nGrfSize.Width() != nWidth )
+        {
+            aScaleX = Fraction( nGrfSize.Width(), nWidth );
+            bScale = TRUE;
+        }
+    }
+    if( !rFrmSize.GetHeightPercent() )
+    {
+        SwTwips nHeight = rFrmSize.GetHeight();
+
+        nHeight -= rBox.CalcLineSpace(BOX_LINE_TOP) +
+                   rBox.CalcLineSpace(BOX_LINE_BOTTOM);
+
+        ASSERT( nHeight>0, "Gibt es 0 twip hohe Grafiken!?" );
+
+        if( nGrfSize.Height() != nHeight )
+        {
+            aScaleY = Fraction( nGrfSize.Height(), nHeight );
+            bScale = TRUE;
+        }
+    }
+
+    if( bScale )
+    {
+        aURL.GetMap()->Scale( aScaleX, aScaleY );
+        pFmt->SetAttr( aURL );
+    }
+}
+
+
+void SwGrfNode::DelStreamName()
+{
+    if( aStrmName.Len() )
+    {
+        // Dann die Grafik im Storage loeschen
+        SvStorage* pDocStg = GetDoc()->GetDocStorage();
+        if( pDocStg )
+        {
+            String aPicStgName( String::CreateFromAscii(
+                            RTL_CONSTASCII_STRINGPARAM( "EmbeddedPictures" )));
+            SvStorageRef refPics =
+                pDocStg->OpenStorage( aPicStgName,
+                    STREAM_READWRITE | STREAM_SHARE_DENYALL );
+            if( refPics->GetError() == SVSTREAM_OK )
+            {
+                refPics->Remove( aStrmName );
+                refPics->Commit();
+                refPics->ResetError();  // Falls wir ReadOnly waren
+            }
+        }
+        aStrmName.Erase();
+    }
+}
+
+
+SwCntntNode* SwGrfNode::MakeCopy( SwDoc* pDoc, const SwNodeIndex& rIdx ) const
+{
+    // kopiere die Formate in das andere Dokument:
+    SwGrfFmtColl* pColl = pDoc->CopyGrfColl( *GetGrfColl() );
+
+    SwGrfNode* pThis = (SwGrfNode*)this;
+
+    Graphic aTmpGrf;
+    SwBaseLink* pLink = (SwBaseLink*)(SvBaseLink*) refLink;
+    if( !pLink && aStrmName.Len() )
+    {
+        SvStorageRef refRoot = pThis->GetDoc()->GetDocStorage();
+        ASSERT( refRoot.Is(), "Kein Storage am Doc" );
+        if( refRoot.Is() )
+        {
+            String aPicStgName( String::CreateFromAscii(
+                            RTL_CONSTASCII_STRINGPARAM( "EmbeddedPictures" )));
+            SvStorageRef refPics = refRoot->OpenStorage( aPicStgName,
+                        STREAM_READ | STREAM_SHARE_DENYWRITE );
+            if( refPics->GetError() == SVSTREAM_OK )
+            {
+                SvStorageStreamRef refStrm = refPics->OpenStream( aStrmName,
+                        STREAM_READ | STREAM_SHARE_DENYWRITE );
+                if( refStrm->GetError() == SVSTREAM_OK )
+                {
+                    refStrm->SetVersion( refRoot->GetVersion() );
+                    aTmpGrf.SwapIn( refStrm );
+                }
+            }
+        }
+    }
+    else
+    {
+        if( aGrfObj.IsSwappedOut() )
+            pThis->SwapIn();
+        aTmpGrf = aGrfObj.GetGraphic();
+    }
+
+    const SvLinkManager& rMgr = GetDoc()->GetLinkManager();
+    String sFile, sFilter;
+    if( IsLinkedFile() )
+        rMgr.GetDisplayNames( *refLink, 0, &sFile, 0, &sFilter );
+    else if( IsLinkedDDE() )
+    {
+        String sTmp1, sTmp2;
+        rMgr.GetDisplayNames( *refLink, &sTmp1, &sTmp2, &sFilter );
+        ::MakeLnkName( sFile, &sTmp1, sTmp2, sFilter );
+        sFilter.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "DDE" ));
+    }
+
+    SwGrfNode* pGrfNd = pDoc->GetNodes().MakeGrfNode( rIdx, sFile, sFilter,
+                                                    &aTmpGrf, pColl,
+                                            (SwAttrSet*)GetpSwAttrSet() );
+    pGrfNd->SetAlternateText( GetAlternateText() );
+    pGrfNd->SetContour( HasContour() );
+    return pGrfNd;
+}
+
+IMPL_LINK( SwGrfNode, SwapGraphic, GraphicObject*, pGrfObj )
+{
+    SvStream* pRet;
+    if( refLink.Is() )
+    {
+        if( pGrfObj->IsInSwapIn() )
+        {
+            // then make it by your self
+            if( !bInSwapIn )
+            {
+                BOOL bIsModifyLocked = IsModifyLocked();
+                LockModify();
+                SwapIn( FALSE );
+                if( !bIsModifyLocked )
+                    UnlockModify();
+            }
+            pRet = GRFMGR_AUTOSWAPSTREAM_NONE;
+        }
+        else
+            pRet = GRFMGR_AUTOSWAPSTREAM_LINK;
+    }
+    else
+    {
+        pRet = GRFMGR_AUTOSWAPSTREAM_TEMP;
+
+        if( aStrmName.Len() )
+        {
+            SvStorageRef refRoot = GetDoc()->GetDocStorage();
+            ASSERT( refRoot.Is(), "Kein Storage am Doc" );
+            if( refRoot.Is() )
+            {
+                String aPicStgName( String::CreateFromAscii(
+                            RTL_CONSTASCII_STRINGPARAM( "EmbeddedPictures" )));
+                SvStorageRef refPics =
+                    refRoot->OpenStorage( aPicStgName,
+                        STREAM_READ | STREAM_SHARE_DENYWRITE );
+                if( refPics->GetError() == SVSTREAM_OK )
+                {
+                    SvStream* pTmp = refPics->OpenStream( aStrmName,
+                        STREAM_READ | STREAM_SHARE_DENYWRITE );
+                    BOOL bDelStrm = TRUE;
+                    if( pTmp->GetError() == SVSTREAM_OK )
+                    {
+                        if( pGrfObj->IsInSwapOut() )
+                            pRet = GRFMGR_AUTOSWAPSTREAM_LINK;
+                        else
+                        {
+                            pRet = pTmp;
+                            bDelStrm = FALSE;
+                            pRet->SetVersion( refRoot->GetVersion() );
+                        }
+                    }
+                    if( bDelStrm )
+                        delete pTmp;
+                }
+            }
+        }
+    }
+
+    return (long)pRet;
+
+/*
+    SvStream* pStream = GetSwapStream();
+
+    if( GRFMGR_AUTOSWAPSTREAM_NONE != pStream )
+    {
+        if( GRFMGR_AUTOSWAPSTREAM_LINK == pStream )
+            mbAutoSwapped = maGraphic.SwapOut( NULL );
+        else
+        {
+            if( GRFMGR_AUTOSWAPSTREAM_TEMP == pStream )
+                mbAutoSwapped = maGraphic.SwapOut();
+            else
+                mbAutoSwapped = maGraphic.SwapOut( pStream );
+        }
+    }
+*/
+}
+
+
+// alle QuickDraw-Bitmaps eines speziellen Docs loeschen
+void DelAllGrfCacheEntries( SwDoc* pDoc )
+{
+    if( pDoc )
+    {
+        // alle Graphic-Links mit dem Namen aus dem Cache loeschen
+        const SvxLinkManager& rLnkMgr = pDoc->GetLinkManager();
+        const SvBaseLinks& rLnks = rLnkMgr.GetLinks();
+        SwGrfNode* pGrfNd;
+        String sFileNm;
+        for( USHORT n = rLnks.Count(); n; )
+        {
+            SvBaseLink* pLnk = &(*rLnks[ --n ]);
+            if( pLnk && OBJECT_CLIENT_GRF == pLnk->GetObjType() &&
+                rLnkMgr.GetDisplayNames( *pLnk, 0, &sFileNm ) &&
+                pLnk->ISA( SwBaseLink ) && 0 != ( pGrfNd =
+                ((SwBaseLink*)pLnk)->GetCntntNode()->GetGrfNode()) )
+            {
+                pGrfNd->GetGrfObj().ReleaseFromCache();
+            }
+        }
+    }
+}
+
+// returns the with our graphic attributes filled Graphic-Attr-Structure
+GraphicAttr& SwGrfNode::GetGraphicAttr( GraphicAttr& rGA,
+                                        const SwFrm* pFrm ) const
+{
+    const SwAttrSet& rSet = GetSwAttrSet();
+
+    rGA.SetDrawMode( (GraphicDrawMode)rSet.GetDrawModeGrf().GetValue() );
+
+    const SwMirrorGrf & rMirror = rSet.GetMirrorGrf();
+    ULONG nMirror = BMP_MIRROR_NONE;
+    if( rMirror.IsGrfToggle() && pFrm &&
+        !(pFrm->FindPageFrm()->GetVirtPageNum() % 2 ) )
+    {
+        switch( rMirror.GetValue() )
+        {
+        case RES_DONT_MIRROR_GRF:   nMirror = BMP_MIRROR_VERT; break;
+        case RES_MIRROR_GRF_VERT:   nMirror = BMP_MIRROR_NONE; break;
+        case RES_MIRROR_GRF_HOR:    nMirror = BMP_MIRROR_HORZ|BMP_MIRROR_VERT;
+                                    break;
+        default:                    nMirror = BMP_MIRROR_HORZ; break;
+        }
+    }
+    else
+        switch( rMirror.GetValue() )
+        {
+        case RES_MIRROR_GRF_BOTH:   nMirror = BMP_MIRROR_HORZ|BMP_MIRROR_VERT;
+                                    break;
+        case RES_MIRROR_GRF_VERT:   nMirror = BMP_MIRROR_VERT; break;
+        case RES_MIRROR_GRF_HOR:    nMirror = BMP_MIRROR_HORZ; break;
+        }
+
+    rGA.SetMirrorFlags( nMirror );
+
+//  const SwCropGrf   &rSet.GetCropGrf(BOOL bInP) const
+
+    const SwRotationGrf& rRotation = rSet.GetRotationGrf();
+    rGA.SetRotation( rRotation.GetValue(), rRotation.GetUnrotatedSize() );
+
+    rGA.SetLuminance( rSet.GetLuminanceGrf().GetValue() );
+    rGA.SetContrast( rSet.GetContrastGrf().GetValue() );
+    rGA.SetChannelR( rSet.GetChannelRGrf().GetValue() );
+    rGA.SetChannelG( rSet.GetChannelGGrf().GetValue() );
+    rGA.SetChannelB( rSet.GetChannelBGrf().GetValue() );
+    rGA.SetGamma( rSet.GetGammaGrf().GetValue() );
+    rGA.SetInvert( rSet.GetInvertGrf().GetValue() );
+    rGA.SetTransparency( rSet.GetTransparencyGrf().GetValue() );
+
+    return rGA;
+}
+
+
+/*  */
+#else
+// USE_GRFOBJECT
+
+#include "grfcache.hxx"
+
+// --------------------
+// SwGrfNode
+// --------------------
+
+SwGrfNode::SwGrfNode( const SwNodeIndex & rWhere,
+                  const String& rGrfName, const String& rFltName,
+                  const Graphic* pGraphic,
+                  SwGrfFmtColl *pGrfColl,
+                  SwAttrSet* pAutoAttr )
+    : SwNoTxtNode( rWhere, ND_GRFNODE, pGrfColl, pAutoAttr ),
+    pCchMagic( 0 ), nCchIndex( 0 )
+{
+    bTransparentFlagValid = bInSwapIn = bChgTwipSize = bLoadLowResGrf =
+    bFrameInPaint = bScaleImageMap = FALSE;
+    bGrafikArrived = TRUE;
+    ReRead( rGrfName, rFltName, pGraphic, FALSE );
+}
+
+// Konstruktor fuer den SW/G-Reader. Dieser ctor wird verwendet,
+// wenn eine gelinkte Grafik gelesen wird. Sie liest diese NICHT ein.
+
+SwGrfNode::SwGrfNode( const SwNodeIndex & rWhere,
+                  const String& rGrfName, const String& rFltName,
+                  SwGrfFmtColl *pGrfColl,
+                  SwAttrSet* pAutoAttr )
+    : SwNoTxtNode( rWhere, ND_GRFNODE, pGrfColl, pAutoAttr ),
+    pCchMagic( 0 ), nCchIndex( 0 )
+{
+    bTransparentFlagValid = bInSwapIn = bChgTwipSize = bLoadLowResGrf =
+    bFrameInPaint = bScaleImageMap = FALSE;
+    bGrafikArrived = TRUE;
+    InsertLink( rGrfName, rFltName );
+    if( IsLinkedFile() )
+    {
+        INetURLObject aUrl( GUI2FSYS( rGrfName ) );
+        if( aUrl.GetProtocol() == INET_PROT_FILE )
+        {
+            try
+            {
+                ::ucb::Content aTestContent(
+                    aUrl.GetMainURL(),
+                    uno::Reference< XCommandEnvironment >());
+                if(aTestContent.isDocument())
+                    // File vorhanden, Verbindung herstellen ohne ein Update
+                    ((SwBaseLink*)&refLink)->Connect();
+            }
+            catch(...)
+            {
+                DBG_ERROR("Exception caught")
+            }
+//          DirEntry aFileNm( aUrl.PathToFileName() );
+//          aFileNm.ToAbs();
+
+//          if( FSYS_KIND_FILE == FileStat( aFileNm ).GetKind() )
+                // File vorhanden, Verbindung herstellen ohne ein Update
+//              ((SwBaseLink*)&refLink)->Connect();
+        }
+    }
+}
+
+
+// erneutes Einlesen, falls Graphic nicht Ok ist. Die
+// aktuelle wird durch die neue ersetzt.
+
+BOOL SwGrfNode::ReRead( const String& rGrfName, const String& rFltName,
+                        const Graphic* pGraphic, BOOL bNewGrf )
+{
+    bTransparentFlagValid = FALSE;
+    BOOL bReadGrf = FALSE, bSetTwipSize = TRUE;
+
+    ASSERT( pGraphic || rGrfName.Len(), "GrafikNode ohne Name und Grafik" );
+
+
+    // ReadRead mit Namen
+    if( refLink.Is() )
+    {
+        ASSERT( !bInSwapIn, "ReRead: stehe noch im SwapIn" );
+        if( rGrfName.Len() )
+        {
+            // Besonderheit: steht im FltNamen DDE, handelt es sich um eine
+            //                  DDE-gelinkte Grafik
+            String sCmd( rGrfName );
+            if( rFltName.Len() )
+            {
+                USHORT nNewType;
+                if( rFltName.EqualsAscii( "DDE" ))
+                    nNewType = OBJECT_CLIENT_DDE;
+                else
+                {
+                    ::MakeLnkName( sCmd, 0, rGrfName, aEmptyStr, &rFltName );
+                    nNewType = OBJECT_CLIENT_GRF;
+                }
+
+                if( nNewType != refLink->GetObjectType() )
+                {
+                    refLink->Disconnect();
+                    ((SwBaseLink*)&refLink)->SetObjType( nNewType );
+                }
+            }
+
+            refLink->SetLinkSourceName( new SvLinkName( sCmd ) );
+        }
+        else        // kein Name mehr, Link aufheben
+        {
+            GetDoc()->GetLinkManager().Remove( *refLink );
+            refLink.Clear();
+        }
+
+        if( pGraphic )
+        {
+            aGraphic = *pGraphic;
+            bReadGrf = TRUE;
+        }
+        else
+        {
+            // MIB 25.02.97: Daten der alten Grafik zuruecksetzen, damit
+            // die korrekte Ersatz-Darstellung erscheint, wenn die
+            // der neue Link nicht geladen werden konnte.
+            aGraphic.Clear();
+
+            SetCacheFlags( 0, 0 );
+
+            BOOL bAvailable = FALSE;
+            {
+                SwGraphicAccess aGrfAcc( rGrfName );
+                if( aGrfAcc.IsAvailable() )
+                {
+                    bTransparentFlagValid = aGrfAcc.Get()->IsTransparentFlagValid();
+                    bIsTransparent = aGrfAcc.Get()->IsTransparent();
+                    SetTwipSize( aGrfAcc.Get()->GetGrfSize() );
+                    aGraphic.SetDefaultType();
+                    bAvailable = TRUE;
+                }
+            }
+
+            if( bAvailable )
+            {
+                SwMsgPoolItem aMsgHint( RES_GRF_REREAD_AND_INCACHE );
+                Modify( &aMsgHint, &aMsgHint );
+            }
+            else if( refLink.Is() )
+                ((SwBaseLink*)&refLink)->SwapIn();
+
+            bSetTwipSize = FALSE;
+        }
+    }
+    else if( pGraphic && !rGrfName.Len() )
+    {
+        aGraphic = *pGraphic;
+        bReadGrf = TRUE;
+
+        SwGraphicCacheObj::GetCache()->Delete( this );
+
+        if( aStrmName.Len() )
+            DelStreamName();
+    }
+        // Import einer Grafik:
+        // Ist die Grafik bereits geladen?
+    else if( !bNewGrf && GRAPHIC_NONE != aGraphic.GetType() )
+        return TRUE;
+
+    else
+    {
+        SwGraphicCacheObj::GetCache()->Delete( this );
+
+        // einen neuen Grafik-Link anlegen
+        InsertLink( rGrfName, rFltName );
+
+        if( aStrmName.Len() )
+            DelStreamName();
+
+        if( GetNodes().IsDocNodes() )
+        {
+            if( !pGraphic )
+            {
+                // MIB 25.02.97: Daten der alten Grafik zuruecksetzen, damit
+                // die korrekte Ersatz-Darstellung erscheint, wenn die
+                // der neue Kink nicht geladen werden konnte.
+                aGraphic = Graphic(); // Geht hier auch Clear? Niemand weiss es.
+                ((SwBaseLink*)&refLink)->SwapIn();  //Damit wir die richtige Groesse bekommen.
+            }
+            else
+            {
+                aGraphic = *pGraphic;
+                bReadGrf = TRUE;
+                // Verbindung herstellen ohne ein Update; Grafik haben wir!
+                ((SwBaseLink*)&refLink)->Connect();
+            }
+        }
+    }
+
+    // Bug 39281: Size nicht sofort loeschen - Events auf ImageMaps
+    //            sollten nicht beim Austauschen nicht ins "leere greifen"
+    if( bSetTwipSize )
+        SetTwipSize( ::GetGraphicSizeTwip( aGraphic, 0 ) );
+
+    // erzeuge noch einen Update auf die Frames
+    if( bReadGrf && bNewGrf )
+    {
+        SwMsgPoolItem aMsgHint( RES_UPDATE_ATTR );
+        Modify( &aMsgHint, &aMsgHint );
+    }
+
+    return bReadGrf;
+}
+
+
+SwGrfNode::~SwGrfNode()
+{
+    SwDoc* pDoc = GetDoc();
+    if( refLink.Is() )
+    {
+        ASSERT( !bInSwapIn, "DTOR: stehe noch im SwapIn" );
+        pDoc->GetLinkManager().Remove( *refLink );
+        refLink->Disconnect();
+        if( pCchMagic )
+        {
+            SwGraphicAccess aGrfAcc( *this );
+            if( aGrfAcc.IsAvailable() )
+                aGrfAcc.Get()->ClearLastCheckTime();
+        }
+    }
+    else
+    {
+        if( !pDoc->IsInDtor() && aStrmName.Len() )
+            DelStreamName();
+        SwGraphicCacheObj::GetCache()->Delete( this );
+    }
+    //#39289# Die Frames muessen hier bereits geloescht weil der DTor der
+    //Frms die Grafik noch fuer StopAnimation braucht.
+    if( GetDepends() )
+        DelFrms();
+}
+
+
+SwCntntNode *SwGrfNode::SplitNode( const SwPosition &rPos )
+{
+    // ohne Ressourcen....
+    return this;
+}
+
+
+SwGrfNode * SwNodes::MakeGrfNode( const SwNodeIndex & rWhere,
+                                const String& rGrfName,
+                                const String& rFltName,
+                                const Graphic* pGraphic,
+                                SwGrfFmtColl* pGrfColl,
+                                SwAttrSet* pAutoAttr,
+                                BOOL bDelayed )
+{
+    ASSERT( pGrfColl, "MakeGrfNode: Formatpointer ist 0." );
+    SwGrfNode *pNode;
+    // Delayed erzeugen nur aus dem SW/G-Reader
+    if( bDelayed )
+        pNode = new SwGrfNode( rWhere, rGrfName,
+                                rFltName, pGrfColl, pAutoAttr );
+    else
+        pNode = new SwGrfNode( rWhere, rGrfName,
+                                rFltName, pGraphic, pGrfColl, pAutoAttr );
+    return pNode;
+}
+
+
+Size SwGrfNode::GetTwipSize() const
+{
+    return nGrfSize;
+}
+
+
+void SwGrfNode::Impl_IsTransparent()
+{
+    if ( GRAPHIC_DEFAULT != aGraphic.GetType() )
+        SwapIn();
+    bIsTransparent = aGraphic.IsTransparent();
+    bTransparentFlagValid = TRUE;
+}
+
+
+// Returnwert:
+// -1 : ReRead erfolgreich
+//  0 : nicht geladen
+//  1 : Einlesen erfolgreich
+
+
+short SwGrfNode::SwapIn( BOOL bWaitForData )
+{
+    if( bInSwapIn )                 // nicht rekuriv!!
+        return !aGraphic.IsSwapOut();
+
+    short nRet = 0;
+    bInSwapIn = TRUE;
+    SwBaseLink* pLink = (SwBaseLink*)(SvBaseLink*) refLink;
+    if( pLink )
+    {
+        if( GRAPHIC_NONE == aGraphic.GetType() ||
+            GRAPHIC_DEFAULT == aGraphic.GetType() )
+        {
+            // noch nicht geladener Link
+            if( pLink->SwapIn( bWaitForData ) )
+                nRet = -1;
+            else if( GRAPHIC_DEFAULT == aGraphic.GetType() )
+            {
+                // keine default Bitmap mehr, also neu Painten!
+                aGraphic.Clear();
+                SwMsgPoolItem aMsgHint( RES_GRAPHIC_PIECE_ARRIVED );
+                Modify( &aMsgHint, &aMsgHint );
+            }
+        }
+        else if( aGraphic.IsSwapOut() )
+            // nachzuladender Link
+            nRet = pLink->SwapIn( bWaitForData ) ? 1 : 0;
+        else
+            nRet = 1;
+    }
+    else if( aGraphic.IsSwapOut() )
+    {
+        // Die Grafik ist im Storage oder im TempFile drin
+        if( !aStrmName.Len() )
+            nRet = aGraphic.IsSwapOut() ? (short)aGraphic.SwapIn() : 1;
+        else
+        {
+            SvStorageRef refRoot = GetDoc()->GetDocStorage();
+            ASSERT( refRoot.Is(), "Kein Storage am Doc" );
+            if( refRoot.Is() )
+            {
+                SvStorageRef refPics =
+                    refRoot->OpenStorage( String::CreateFromAscii(
+                        RTL_CONSTASCII_STRINGPARAM( "EmbeddedPictures" )),
+                        STREAM_READ | STREAM_SHARE_DENYWRITE );
+                if( refPics->GetError() == SVSTREAM_OK )
+                {
+                    SvStorageStreamRef refStrm =
+                        refPics->OpenStream( aStrmName,
+                        STREAM_READ | STREAM_SHARE_DENYWRITE );
+                    if( refStrm->GetError() == SVSTREAM_OK )
+                    {
+                        refStrm->SetVersion( refRoot->GetVersion() );
+                        if( aGraphic.SwapIn( refStrm ) )
+                            nRet = 1;
+                    }
+                }
+            }
+        }
+    }
+    else
+        nRet = 1;
+    DBG_ASSERTWARNING( nRet, "Grafik kann nicht eingeswapt werden" );
+
+    if( nRet )
+    {
+        SwGraphicCacheObj::SetTimeout( 10000L );
+        if( !nGrfSize.Width() && !nGrfSize.Height() )
+            SetTwipSize( ::GetGraphicSizeTwip( aGraphic, 0 ) );
+    }
+    bInSwapIn = FALSE;
+    return nRet;
+}
+
+
+short SwGrfNode::SwapOut()
+{
+    if( aGraphic.GetType() != GRAPHIC_DEFAULT &&
+        aGraphic.GetType() != GRAPHIC_NONE &&
+        !aGraphic.IsSwapOut() && !bInSwapIn )
+    {
+        if( !refLink.Is() )
+        {
+            // Das Swapping brauchen wir nur fuer Embedded Pictures
+            // Die Grafik wird in eine TempFile geschrieben, wenn
+            // sie frisch eingefuegt war, d.h. wenn es noch keinen
+            // Streamnamen im Storage gibt.
+            if( !aStrmName.Len() )
+                if( !aGraphic.SwapOut() )
+                    return 0;
+        }
+        // Geschriebene Grafiken oder Links werden jetzt weggeschmissen
+        return (short) aGraphic.SwapOut( NULL );
+    }
+    else
+        return 1;
+}
+
+// Wird nach einem SaveAs aufgerufen und setzt die StreamNamen um
+
+void SwGrfNode::SaveCompleted( BOOL bClear )
+{
+    if( aNewStrmName.Len() )
+    {
+        if( !bClear )       // der Name wird zum aktuellen
+            aStrmName = aNewStrmName;
+        aNewStrmName.Erase();
+    }
+}
+
+
+// Falls die Grafik noch nicht im Doc-Storage existiert,
+// wird sie neu geschrieben; falls sie bereits drin ist,
+// wird nicht geschrieben. Wenn der Storage nicht dem
+// Doc-Storage entspricht, wird, falls aNewStrmName nicht
+// besetzt ist, in diesem Storage unter dem angegebenen
+// Streamnamen abgelegt (SaveAs). nach einem SaveAs wird
+// vom SW3-I/O-System noch SaveCompleted() aufgerufen,
+// da nun der Doc-Storage dem neuen Storage entspricht.
+
+
+BOOL SwGrfNode::StoreGraphics( SvStorage* pRoot )
+{
+    if( !refLink.Is() )
+    {
+        String aName( aStrmName );
+        SvStorage* pDocStg = GetDoc()->GetDocStorage();
+        if( !pRoot )
+            pRoot = pDocStg;
+
+        String aPicStgName( String::CreateFromAscii(
+                        RTL_CONSTASCII_STRINGPARAM( "EmbeddedPictures" )));
+        if( pRoot != pDocStg )
+        {
+            // Neuer Storage. Wenn die Grafik im DocStg drin ist,
+            // kann sie bequem per CopyTo() kopiert werden.
+            if( aName.Len() )
+            {
+                SvStorageRef refSrcPics =
+                    pDocStg->OpenStorage( aPicStgName,
+                        STREAM_READ | STREAM_SHARE_DENYWRITE );
+
+                SvStorageStreamRef refStrm;
+
+                BOOL bWriteNew = pDocStg->GetVersion() != pRoot->GetVersion();
+                if( !bWriteNew &&
+                    SOFFICE_FILEFORMAT_40 <= pRoot->GetVersion() )
+                {
+                    refStrm = refSrcPics->OpenStream( aName,
+                                    STREAM_READ | STREAM_SHARE_DENYWRITE );
+                    if( SVSTREAM_OK == refStrm->GetError() )
+                    {
+                        // JP 21.06.98: pruefe ob der CompressMode uebereinstimmt
+                        USHORT nCmprsMode =
+                                Graphic::GetGraphicsCompressMode(*refStrm ) &
+                                ~(COMPRESSMODE_ZBITMAP|COMPRESSMODE_NATIVE );
+                        USHORT nNewCmprsMode = 0;
+                        if( GRAPHIC_BITMAP == aGraphic.GetType() &&
+                            GetDoc()->GetInfo()->IsSaveGraphicsCompressed() )
+                            nNewCmprsMode |= COMPRESSMODE_ZBITMAP;
+                        if( SOFFICE_FILEFORMAT_40 < pRoot->GetVersion() &&
+                            GetDoc()->GetInfo()->IsSaveOriginalGraphics() )
+                            nNewCmprsMode |= COMPRESSMODE_NATIVE;
+
+                        if( nCmprsMode != nNewCmprsMode )
+                        {
+                            // der Kompressedmode stimmt nicht, also muss
+                            // ggfs. die Grafik reingeswappt und ueber den
+                            // unteren Teil neu geschrieben werden.
+                            bWriteNew = TRUE;
+                            refStrm->Seek( STREAM_SEEK_TO_BEGIN );
+                        }
+                    }
+                }
+
+                if( bWriteNew )
+                {
+                    if( aGraphic.IsSwapOut() &&
+                        SVSTREAM_OK == refSrcPics->GetError() )
+                    {
+                        if( !refStrm.Is() )
+                            refStrm = refSrcPics->OpenStream( aName,
+                                    STREAM_READ | STREAM_SHARE_DENYWRITE );
+                        if( SVSTREAM_OK == refStrm->GetError() )
+                        {
+                            refStrm->SetVersion( pDocStg->GetVersion() );
+                            if( !aGraphic.SwapIn( refStrm ) )
+                                return FALSE;
+                        }
+                    }
+                    aName.Erase();
+                }
+                else
+                {
+                    SvStorageRef refDstPics =
+                        pRoot->OpenStorage( aPicStgName,
+                            STREAM_READWRITE | STREAM_SHARE_DENYALL );
+                    if( refDstPics->IsContained( aName ) )
+                        // nur neu erzeugen, wenn Name schon vorhanden ist!
+                        aName = Sw3Io::UniqueName( refDstPics, "Pic" );
+
+                    if( refSrcPics->CopyTo( aStrmName, refDstPics, aName )
+                        && refDstPics->Commit() )
+                        aNewStrmName = aName;
+                    else
+                        return FALSE;
+                }
+            }
+        }
+
+        if( !aName.Len() )
+        {
+            ASSERT( pRoot, "Kein Storage gegeben" );
+            if( pRoot )
+            {
+                SvStorageRef refPics =
+                    pRoot->OpenStorage( aPicStgName,
+                        STREAM_READWRITE | STREAM_SHARE_DENYALL );
+                if( SVSTREAM_OK == refPics->GetError() )
+                {
+                    aName = Sw3Io::UniqueName( refPics, "Pic" );
+                    SvStorageStreamRef refStrm =
+                        refPics->OpenStream( aName,
+                        STREAM_READWRITE | STREAM_SHARE_DENYALL );
+                    if( SVSTREAM_OK == refStrm->GetError() )
+                    {
+                        // HACK bis die Grafik als Portable markiert
+                        // werden kann!!!
+                        // Die Grafik kann in einer TempFile sein!
+                        FASTBOOL bIsSwapOut = aGraphic.IsSwapOut();
+                        if( bIsSwapOut && !aGraphic.SwapIn() )
+                            return FALSE;
+
+                        refStrm->SetVersion( pRoot->GetVersion() );
+
+                        //JP 04.05.98: laut ChangesMail vom KA und Bug 49617
+                        //JP 21.06.98: laut ChangesMail vom KA, natives Save
+                        USHORT nComprMode = refStrm->GetCompressMode();
+                        if( SOFFICE_FILEFORMAT_40 <= refStrm->GetVersion() &&
+                            GRAPHIC_BITMAP == aGraphic.GetType() &&
+                            GetDoc()->GetInfo()->IsSaveGraphicsCompressed() )
+                            nComprMode |= COMPRESSMODE_ZBITMAP;
+                        else
+                            nComprMode &= ~COMPRESSMODE_ZBITMAP;
+
+                        //JP 21.06.98: laut ChangesMail vom KA, natives Save
+                        if( SOFFICE_FILEFORMAT_40 < refStrm->GetVersion() &&
+                            GetDoc()->GetInfo()->IsSaveOriginalGraphics() )
+                            nComprMode |= COMPRESSMODE_NATIVE;
+                        else
+                            nComprMode &= ~COMPRESSMODE_NATIVE;
+                        refStrm->SetCompressMode( nComprMode );
+
+                        BOOL bRes = FALSE;
+                        if( pRoot == pDocStg )
+                        {
+                            if( aGraphic.SwapOut( refStrm ) &&
+                                ( refStrm->Commit() | refPics->Commit()
+                                  /*| pRoot->Commit()*/ ))
+                            {
+                                aStrmName = aName;
+                                bRes = TRUE;
+                            }
+                        }
+                        else if( aGraphic.WriteEmbedded( *refStrm)
+                                && ( refStrm->Commit() | refPics->Commit()
+                                  /*| pRoot->Commit()*/ ))
+                        {
+                            if( bIsSwapOut )
+                                aGraphic.SwapOut();
+                            aNewStrmName = aName;
+                            bRes = TRUE;
+                        }
+                        return bRes;
+                    }
+                }
+            }
+            // Da fehlte doch was?
+            return FALSE;
+        }
+    }
+    // Schon drin im Storage oder Linked
+    return TRUE;
+}
+
+
+BOOL SwGrfNode::GetFileFilterNms( String* pFileNm, String* pFilterNm ) const
+{
+    BOOL bRet = FALSE;
+    if( refLink.Is() && refLink->GetLinkManager() )
+    {
+        USHORT nType = refLink->GetObjType();
+        if( OBJECT_CLIENT_GRF == nType )
+            bRet = refLink->GetLinkManager()->GetDisplayNames(
+                    *refLink, 0, pFileNm, 0, pFilterNm );
+        else if( OBJECT_CLIENT_DDE == nType && pFileNm && pFilterNm )
+        {
+            String sApp, sTopic, sItem;
+            if( refLink->GetLinkManager()->GetDisplayNames(
+                    *refLink, &sApp, &sTopic, &sItem ) )
+            {
+                ( *pFileNm = sApp ) += cTokenSeperator;
+                ( *pFileNm += sTopic ) += cTokenSeperator;
+                *pFileNm += sItem;
+                pFilterNm->AssignAscii( RTL_CONSTASCII_STRINGPARAM( "DDE" ));
+                bRet = TRUE;
+            }
+        }
+    }
+
+    return bRet;
+}
+
+
+const String& SwGrfNode::GetStreamName() const
+{
+    if( aNewStrmName.Len() )
+        return aNewStrmName;
+    else
+        return aStrmName;
+}
+
+// Eine Grafik Undo-faehig machen. Falls sie sich bereits in
+// einem Storage befindet, muss sie geladen werden.
+
+
+BOOL SwGrfNode::SavePersistentData()
+{
+    if( refLink.Is() )
+    {
+        ASSERT( !bInSwapIn, "SavePersistentData: stehe noch im SwapIn" );
+        GetDoc()->GetLinkManager().Remove( *refLink );
+        if( pCchMagic )
+        {
+            SwGraphicAccess aGrfAcc( *this );
+            if( aGrfAcc.IsAvailable() )
+                aGrfAcc.Get()->ClearLastCheckTime();
+        }
+        return TRUE;
+    }
+
+    // Erst mal reinswappen, falls sie im Storage ist
+    if( aStrmName.Len() && !SwapIn() )
+        return FALSE;
+
+    if( aStrmName.Len() )
+        DelStreamName();
+
+    // Und in TempFile rausswappen
+    return (BOOL) SwapOut();
+}
+
+
+BOOL SwGrfNode::RestorePersistentData()
+{
+    if( refLink.Is() )
+    {
+        refLink->SetVisible( GetDoc()->IsVisibleLinks() );
+        GetDoc()->GetLinkManager().InsertDDELink( *refLink );
+        if( GetDoc()->GetRootFrm() )
+            refLink->Update();
+    }
+    return TRUE;
+}
+
+
+void SwGrfNode::InsertLink( const String& rGrfName, const String& rFltName )
+{
+    refLink = new SwBaseLink( LINKUPDATE_ONCALL, FORMAT_GDIMETAFILE, this );
+    SwDoc* pDoc = GetDoc();
+    if( GetNodes().IsDocNodes() )
+    {
+        refLink->SetVisible( pDoc->IsVisibleLinks() );
+        if( rFltName.EqualsAscii( "DDE" ))
+        {
+            USHORT nTmp = 0;
+            String sApp, sTopic, sItem;
+            sApp = rGrfName.GetToken( 0, cTokenSeperator, nTmp );
+            sTopic = rGrfName.GetToken( 0, cTokenSeperator, nTmp );
+            sItem = rGrfName.Copy( nTmp );
+            pDoc->GetLinkManager().InsertDDELink( *refLink,
+                                            sApp, sTopic, sItem );
+        }
+        else
+        {
+            BOOL bSync = rFltName.EqualsAscii( "SYNCHRON" );
+            refLink->SetSynchron( bSync );
+            refLink->SetContentType( Graphic::RegisterClipboardFormatName() );
+
+            pDoc->GetLinkManager().InsertFileLink( *refLink,
+                                            OBJECT_CLIENT_GRF, rGrfName,
+                                (!bSync && rFltName.Len() ? &rFltName : 0) );
+            if( !bSync )
+                aGraphic.SetDefaultType();
+        }
+    }
+}
+
+
+void SwGrfNode::ReleaseLink()
+{
+    if( refLink.Is() )
+    {
+        // erst die Grafik reinswappen!
+//      if( aGraphic.IsSwapOut() || !refLink->IsSynchron() )
+        {
+            bInSwapIn = TRUE;
+            SwBaseLink* pLink = (SwBaseLink*)(SvBaseLink*) refLink;
+            pLink->SwapIn( TRUE, TRUE );
+            bInSwapIn = FALSE;
+        }
+        GetDoc()->GetLinkManager().Remove( *refLink );
+        refLink.Clear();
+
+        if( pCchMagic )
+        {
+            SwGraphicAccess aGrfAcc( *this );
+            if( aGrfAcc.IsAvailable() )
+                aGrfAcc.Get()->ClearLastCheckTime();
+        }
+        pCchMagic = 0;
+    }
+}
+
+
+void SwGrfNode::SetTwipSize( const Size& rSz )
+{
+    nGrfSize = rSz;
+
+    if( IsLinkedFile() && nGrfSize.Width() && nGrfSize.Height() )
+    {
+        // dann die Size in den Cache haemmern
+        SwGraphicAccess aGrfAcc( *this );
+        aGrfAcc.Get()->SetGrfSize( nGrfSize );
+
+        // Cache Index wieder auf 0 setzen wenn keine gueltige Graik ist!
+        if( GRAPHIC_NONE == aGraphic.GetType() ||
+            GRAPHIC_DEFAULT == aGraphic.GetType() )
+        {
+            pCchMagic = 0;
+            nCchIndex = 0;
+        }
+    }
+
+    if( IsScaleImageMap() &&
+        nGrfSize.Width() && nGrfSize.Height() )
+    {
+        // Image-Map an Grafik-Groesse anpassen
+        ScaleImageMap();
+
+        // Image-Map nicht noch einmal skalieren
+        SetScaleImageMap( FALSE );
+    }
+}
+
+
+void SwGrfNode::ClearQBmpCache()
+{
+    if( !pCchMagic )
+        SwGraphicCacheObj::GetCache()->Delete( this );
+//JP 29.10.96: Bug 32846 - QuickDraw Bitmap aus dem Cache entfernen
+//              (wird das vielleicht zu oft gerufen?)
+    else
+    {
+        SwGraphicCacheObj::GetCache()->Delete( pCchMagic );
+        pCchMagic = 0;
+    }
+    nCchIndex = 0;
+}
+
+        // Prioritaet beim Laden der Grafik setzen. Geht nur, wenn der Link
+        // ein FileObject gesetzt hat
+void SwGrfNode::SetTransferPriority( USHORT nPrio )
+{
+    if( refLink.Is() && refLink->GetObj() )
+        SvxLinkManager::SetTransferPriority( *refLink, nPrio );
+}
+
+
+
+
+void SwGrfNode::ScaleImageMap()
+{
+    if( !nGrfSize.Width() || !nGrfSize.Height() )
+        return;
+
+    // dann die Image-Map skalieren
+    SwFrmFmt* pFmt = GetFlyFmt();
+
+    if( !pFmt )
+        return;
+
+    SwFmtURL aURL( pFmt->GetURL() );
+    if ( !aURL.GetMap() )
+        return;
+
+    BOOL bScale = FALSE;
+    Fraction aScaleX( 1, 1 );
+    Fraction aScaleY( 1, 1 );
+
+    const SwFmtFrmSize& rFrmSize = pFmt->GetFrmSize();
+    const SvxBoxItem& rBox = pFmt->GetBox();
+
+    if( !rFrmSize.GetWidthPercent() )
+    {
+        SwTwips nWidth = rFrmSize.GetWidth();
+
+        nWidth -= rBox.CalcLineSpace(BOX_LINE_LEFT) +
+                  rBox.CalcLineSpace(BOX_LINE_RIGHT);
+
+        ASSERT( nWidth>0, "Gibt es 0 twip breite Grafiken!?" );
+
+        if( nGrfSize.Width() != nWidth )
+        {
+            aScaleX = Fraction( nGrfSize.Width(), nWidth );
+            bScale = TRUE;
+        }
+    }
+    if( !rFrmSize.GetHeightPercent() )
+    {
+        SwTwips nHeight = rFrmSize.GetHeight();
+
+        nHeight -= rBox.CalcLineSpace(BOX_LINE_TOP) +
+                   rBox.CalcLineSpace(BOX_LINE_BOTTOM);
+
+        ASSERT( nHeight>0, "Gibt es 0 twip hohe Grafiken!?" );
+
+        if( nGrfSize.Height() != nHeight )
+        {
+            aScaleY = Fraction( nGrfSize.Height(), nHeight );
+            bScale = TRUE;
+        }
+    }
+
+    if( bScale )
+    {
+        aURL.GetMap()->Scale( aScaleX, aScaleY );
+        pFmt->SetAttr( aURL );
+    }
+}
+
+
+void SwGrfNode::DelStreamName()
+{
+    if( aStrmName.Len() )
+    {
+        // Dann die Grafik im Storage loeschen
+        SvStorage* pDocStg = GetDoc()->GetDocStorage();
+        if( pDocStg )
+        {
+            String aPicStgName( String::CreateFromAscii(
+                        RTL_CONSTASCII_STRINGPARAM( "EmbeddedPictures" )));
+            SvStorageRef refPics =
+                pDocStg->OpenStorage( aPicStgName,
+                    STREAM_READWRITE | STREAM_SHARE_DENYALL );
+            if( refPics->GetError() == SVSTREAM_OK )
+            {
+                refPics->Remove( aStrmName );
+                refPics->Commit();
+                refPics->ResetError();  // Falls wir ReadOnly waren
+            }
+        }
+        aStrmName.Erase();
+    }
+}
+
+
+SwCntntNode* SwGrfNode::MakeCopy( SwDoc* pDoc, const SwNodeIndex& rIdx ) const
+{
+    // kopiere die Formate in das andere Dokument:
+    SwGrfFmtColl* pColl = pDoc->CopyGrfColl( *GetGrfColl() );
+
+    SwGrfNode* pThis = (SwGrfNode*)this;
+
+    Graphic aTmpGrf;
+    SwBaseLink* pLink = (SwBaseLink*)(SvBaseLink*) refLink;
+    if( !pLink && aStrmName.Len() )
+    {
+        SvStorageRef refRoot = pThis->GetDoc()->GetDocStorage();
+        ASSERT( refRoot.Is(), "Kein Storage am Doc" );
+        if( refRoot.Is() )
+        {
+            SvStorageRef refPics = refRoot->OpenStorage( String::CreateFromAscii(
+                        RTL_CONSTASCII_STRINGPARAM( "EmbeddedPictures" )),
+                        STREAM_READ | STREAM_SHARE_DENYWRITE );
+            if( refPics->GetError() == SVSTREAM_OK )
+            {
+                SvStorageStreamRef refStrm = refPics->OpenStream( aStrmName,
+                        STREAM_READ | STREAM_SHARE_DENYWRITE );
+                if( refStrm->GetError() == SVSTREAM_OK )
+                {
+                    refStrm->SetVersion( refRoot->GetVersion() );
+                    aTmpGrf.SwapIn( refStrm );
+                }
+            }
+        }
+    }
+    else
+    {
+        if( aGraphic.IsSwapOut() )
+            pThis->SwapIn();
+        aTmpGrf = aGraphic;
+    }
+
+    const SvLinkManager& rMgr = GetDoc()->GetLinkManager();
+    String sFile, sFilter;
+    if( IsLinkedFile() )
+        rMgr.GetDisplayNames( *refLink, 0, &sFile, 0, &sFilter );
+    else if( IsLinkedDDE() )
+    {
+        String sTmp1, sTmp2;
+        rMgr.GetDisplayNames( *refLink, &sTmp1, &sTmp2, &sFilter );
+        ::MakeLnkName( sFile, &sTmp1, sTmp2, sFilter );
+        sFilter.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "DDE" ));
+    }
+
+    SwGrfNode* pGrfNd = pDoc->GetNodes().MakeGrfNode( rIdx, sFile, sFilter,
+                                                    &aTmpGrf, pColl,
+                                            (SwAttrSet*)GetpSwAttrSet() );
+    pGrfNd->SetAlternateText( GetAlternateText() );
+    pGrfNd->SetContour( HasContour() );
+    return pGrfNd;
+}
+
+
+
+#endif
+// USE_GRFOBJECT
+
+
+
diff --git a/sw/source/core/inc/acorrect.hxx b/sw/source/core/inc/acorrect.hxx
new file mode 100644
index 000000000000..f44020ee9746
--- /dev/null
+++ b/sw/source/core/inc/acorrect.hxx
@@ -0,0 +1,157 @@
+/*************************************************************************
+ *
+ *  $RCSfile: acorrect.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:20 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _ACORRECT_HXX
+#define _ACORRECT_HXX
+
+#ifndef _MySVXACORR_HXX //autogen
+#include 
+#endif
+
+class SwEditShell;
+class SwPaM;
+class SwNodeIndex;
+struct SwPosition;
+
+class SwDontExpandItem
+{
+    SfxItemSet* pDontExpItems;
+public:
+    SwDontExpandItem() :
+        pDontExpItems(0){}
+    ~SwDontExpandItem();
+
+    void SaveDontExpandItems( const SwPosition& rPos );
+    void RestoreDontExpandItems( const SwPosition& rPos );
+
+};
+
+class SwAutoCorrDoc : public SvxAutoCorrDoc
+{
+    SwEditShell& rEditSh;
+    SwPaM& rCrsr;
+    SwNodeIndex* pIdx;
+    USHORT nUndoId;
+
+    void DeleteSel( SwPaM& rDelPam );
+
+public:
+    SwAutoCorrDoc( SwEditShell& rEditShell, SwPaM& rPam, sal_Unicode cIns = 0 );
+    ~SwAutoCorrDoc();
+
+    virtual BOOL Delete( xub_StrLen nStt, xub_StrLen nEnd );
+    virtual BOOL Insert( xub_StrLen nPos, const String& rTxt );
+    virtual BOOL Replace( xub_StrLen nPos, const String& rTxt );
+
+    virtual BOOL SetAttr( xub_StrLen nStt, xub_StrLen nEnd, USHORT nSlotId,
+                            SfxPoolItem& );
+
+    virtual BOOL SetINetAttr( xub_StrLen nStt, xub_StrLen nEnd, const String& rURL );
+
+    // sind in dem Bereich Symbolzeichen?
+    virtual BOOL HasSymbolChars( xub_StrLen nStt, xub_StrLen nEnd );
+
+    // returne den Text eines vorherigen Absatzes.
+    // Dieser darf nicht leer sein!
+    // Gibt es diesen nicht oder gibt es davor nur Leere, dann returne 0
+    // Das Flag gibt an:
+    //      TRUE: den, vor der normalen Einfuegeposition (TRUE)
+    //      FALSE: den, in den das korrigierte Wort eingfuegt wurde.
+    //              (Muss nicht der gleiche Absatz sein!!!!)
+    virtual const String* GetPrevPara( BOOL bAtNormalPos );
+
+    virtual BOOL ChgAutoCorrWord( xub_StrLen& rSttPos, xub_StrLen nEndPos,
+                                  SvxAutoCorrect& rACorrect,
+                                  const String** ppPara );
+
+    // wird nach dem austauschen der Zeichen von den Funktionen
+    //  - FnCptlSttWrd
+    //  - FnCptlSttSntnc
+    // gerufen. Dann koennen die Worte ggfs. in die Ausnahmelisten
+    // aufgenommen werden.
+    virtual void SaveCpltSttWord( ULONG nFlag, xub_StrLen nPos,
+                                    const String& rExceptWord, sal_Unicode cChar );
+    virtual LanguageType GetLanguage( xub_StrLen nPos, BOOL bPrevPara ) const;
+};
+
+class SwAutoCorrExceptWord
+{
+    String sWord;
+    ULONG nFlags, nNode;
+    xub_StrLen nCntnt;
+    sal_Unicode cChar;
+    LanguageType eLanguage;
+    BOOL bDeleted;
+public:
+    SwAutoCorrExceptWord( ULONG nAFlags, ULONG nNd, xub_StrLen nContent,
+                                        const String& rWord, sal_Unicode cChr,
+                                        LanguageType eLang )
+        : sWord( rWord ), nFlags( nAFlags ), nNode( nNd ),
+            nCntnt( nContent ), cChar( cChr ), bDeleted( FALSE ),
+            eLanguage(eLang)
+    {}
+
+    BOOL IsDeleted() const                          { return bDeleted; }
+    void CheckChar( const SwPosition& rPos, sal_Unicode cChar );
+    BOOL CheckDelChar( const SwPosition& rPos );
+};
+
+
+#endif
diff --git a/sw/source/core/inc/blink.hxx b/sw/source/core/inc/blink.hxx
new file mode 100644
index 000000000000..0bb4d5615ccb
--- /dev/null
+++ b/sw/source/core/inc/blink.hxx
@@ -0,0 +1,126 @@
+/*************************************************************************
+ *
+ *  $RCSfile: blink.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:20 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _BLINK_HXX
+#define _BLINK_HXX
+
+class SwLinePortion;
+class SwRootFrm;
+class SwTxtFrm;
+
+#ifndef _SVARRAY_HXX //autogen
+#include 
+#endif
+#ifndef _TIMER_HXX //autogen
+#include 
+#endif
+#ifndef _GEN_HXX //autogen
+#include 
+#endif
+
+class SwBlinkPortion
+{
+    const SwLinePortion *pPor;
+    const SwRootFrm     *pFrm;
+    Point           aPos;
+public:
+    SwBlinkPortion( const SwLinePortion* pPortion ){ pPor = pPortion; }
+    SwBlinkPortion( const SwBlinkPortion* pBlink, const SwLinePortion* pPort )
+    {   pPor = pPort; pFrm = pBlink->pFrm; aPos = pBlink->aPos; }
+    void SetPos( const Point& aNew ){ aPos = aNew; }
+    const Point& GetPos() const{ return aPos; }
+    void SetRootFrm( const SwRootFrm* pNew ){ pFrm = pNew; }
+    const SwRootFrm* GetRootFrm() const{ return pFrm; }
+    const SwLinePortion *GetPortion() const{ return pPor; }
+    BOOL operator<( const SwBlinkPortion& rBlinkPortion ) const
+    { return (long)pPor < (long)rBlinkPortion.pPor; }
+    BOOL operator==( const SwBlinkPortion& rBlinkPortion ) const
+    { return (long)pPor == (long)rBlinkPortion.pPor; }
+};
+
+typedef SwBlinkPortion* SwBlinkPortionPtr;
+SV_DECL_PTRARR_SORT_DEL(SwBlinkList, SwBlinkPortionPtr, 0, 10)
+
+class SwBlink
+{
+    SwBlinkList     aList;
+    AutoTimer       aTimer;
+    BOOL            bVisible;
+public:
+    SwBlink();
+    ~SwBlink();
+
+    DECL_LINK( Blinker, Timer * );
+
+    void Insert( const SwLinePortion* pPor, const Point& rPoint,
+                 const SwTxtFrm *pTxtFrm );
+    void Replace( const SwLinePortion* pOld, const SwLinePortion* pNew );
+    void Delete( const SwLinePortion* pPor );
+    void FrmDelete( const SwRootFrm* pRoot );
+    inline BOOL IsVisible() const { return bVisible ; }
+};
+
+// Blink-Manager, globale Variable, in Blink.Cxx angelegt
+extern SwBlink *pBlink;
+
+
+#endif
+
diff --git a/sw/source/core/inc/bodyfrm.hxx b/sw/source/core/inc/bodyfrm.hxx
new file mode 100644
index 000000000000..123b301e0147
--- /dev/null
+++ b/sw/source/core/inc/bodyfrm.hxx
@@ -0,0 +1,89 @@
+/*************************************************************************
+ *
+ *  $RCSfile: bodyfrm.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:20 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _BODYFRM_HXX
+#define _BODYFRM_HXX
+
+#ifndef _SVMEMPOOL_HXX //autogen
+#include 
+#endif
+
+#include "layfrm.hxx"
+
+class Sw3FrameIo;
+class SwBorderAttrs;
+
+class SwBodyFrm: public SwLayoutFrm
+{
+protected:
+    virtual void Format( const SwBorderAttrs *pAttrs = 0 );
+
+#if defined ( GCC) && defined ( C272 )
+    ~SwBodyFrm();
+#endif
+public:
+    SwBodyFrm( SwFrmFmt* );
+    SwBodyFrm( Sw3FrameIo&, SwLayoutFrm* );
+
+    virtual void   Store( Sw3FrameIo& ) const;
+    DECL_FIXEDMEMPOOL_NEWDEL(SwBodyFrm)
+};
+
+#endif  //_BODYFRM_HXX
diff --git a/sw/source/core/inc/cellfrm.hxx b/sw/source/core/inc/cellfrm.hxx
new file mode 100644
index 000000000000..9eb51c6ff5b4
--- /dev/null
+++ b/sw/source/core/inc/cellfrm.hxx
@@ -0,0 +1,96 @@
+/*************************************************************************
+ *
+ *  $RCSfile: cellfrm.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:20 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _CELLFRM_HXX
+#define _CELLFRM_HXX
+
+#ifndef _SVMEMPOOL_HXX //autogen
+#include 
+#endif
+
+#include "layfrm.hxx"
+
+class SwTableBox;
+class Sw3FrameIo;
+struct SwCrsrMoveState;
+class SwBorderAttrs;
+
+class SwCellFrm: public SwLayoutFrm
+{
+    const SwTableBox *pTabBox;
+
+protected:
+    virtual void Format( const SwBorderAttrs *pAttrs = 0 );
+
+public:
+    SwCellFrm( const SwTableBox & );
+    SwCellFrm( Sw3FrameIo&, SwLayoutFrm* );
+    ~SwCellFrm();
+
+    virtual void   Store( Sw3FrameIo& ) const;
+    virtual BOOL   GetCrsrOfst( SwPosition *, Point&,
+                                const SwCrsrMoveState* = 0 ) const;
+    virtual void   Modify( SfxPoolItem*, SfxPoolItem* );
+
+    const SwTableBox *GetTabBox() const { return pTabBox; }
+    DECL_FIXEDMEMPOOL_NEWDEL(SwCellFrm)
+};
+
+#endif
diff --git a/sw/source/core/inc/cntfrm.hxx b/sw/source/core/inc/cntfrm.hxx
new file mode 100644
index 000000000000..a41aa2e47902
--- /dev/null
+++ b/sw/source/core/inc/cntfrm.hxx
@@ -0,0 +1,196 @@
+/*************************************************************************
+ *
+ *  $RCSfile: cntfrm.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:20 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _CNTFRM_HXX
+#define _CNTFRM_HXX
+
+#include "frame.hxx"
+#include "flowfrm.hxx"
+#include "cshtyp.hxx"
+
+class SwLayoutFrm;
+class SwPageFrm;
+class SwCntntNode;
+class Sw3FrameIo;
+struct SwCrsrMoveState;
+class SwBorderAttrs;
+class SwAttrSetChg;
+
+//Implementiert in cntfrm.cxx, wird von cntfrm.cxx und crsrsh.cxx angezogen
+extern BOOL GetFrmInPage( const SwCntntFrm*, SwWhichPage, SwPosPage, SwPaM* );
+
+class SwCntntFrm: public SwFrm, public SwFlowFrm
+{
+    friend void MakeNxt( SwFrm *pFrm, SwFrm *pNxt );    //ruft MakePrtArea
+
+    BOOL _WouldFit( SwTwips nSpace, SwLayoutFrm *pNewUpper, BOOL bTstMove );
+    virtual void MakeAll();
+
+    const SwCntntFrm *ImplGetNextCntntFrm() const;
+    const SwCntntFrm *ImplGetPrevCntntFrm() const;
+
+    void _UpdateAttr( SfxPoolItem*, SfxPoolItem*, BYTE &,
+                      SwAttrSetChg *pa = 0, SwAttrSetChg *pb = 0 );
+
+    virtual BOOL ShouldBwdMoved( SwLayoutFrm *pNewUpper, BOOL, BOOL& );
+
+protected:
+
+    BOOL MakePrtArea( const SwBorderAttrs & );
+
+    virtual void Modify( SfxPoolItem*, SfxPoolItem* );
+    virtual SwTwips ShrinkFrm( SwTwips, const SzPtr,
+                               BOOL bTst = FALSE, BOOL bInfo = FALSE );
+    virtual SwTwips GrowFrm  ( SwTwips, const SzPtr,
+                               BOOL bTst = FALSE, BOOL bInfo = FALSE );
+
+    SwCntntFrm( SwCntntNode * const );
+    SwCntntFrm( Sw3FrameIo&, SwLayoutFrm* );
+
+public:
+    virtual ~SwCntntFrm();
+    TYPEINFO(); //bereits in Basisklassen drin
+
+    virtual void Store( Sw3FrameIo& ) const;
+
+    virtual void Cut();
+    virtual void Paste( SwFrm* pParent, SwFrm* pSibling = 0 );
+
+    inline       SwCntntNode *GetNode();
+    inline const SwCntntNode *GetNode() const;
+                 USHORT       GetSectionLevel();
+
+    inline const SwCntntFrm *GetFollow() const;
+    inline       SwCntntFrm *GetFollow();
+
+        //Layoutabhaengiges Cursortravelling
+    virtual BOOL    LeftMargin( SwPaM * ) const;
+    virtual BOOL    RightMargin( SwPaM *, BOOL bAPI = FALSE ) const;
+    virtual BOOL    UnitUp( SwPaM *, const SwTwips nOffset = 0,
+                            BOOL bSetInReadOnly = FALSE ) const;
+    virtual BOOL    UnitDown( SwPaM *, const SwTwips nOffset = 0,
+                            BOOL bSetInReadOnly = FALSE ) const;
+    inline  BOOL    StartNextPage( SwPaM * ) const;
+    inline  BOOL    StartPrevPage( SwPaM * ) const;
+    inline  BOOL    StartCurrPage( SwPaM * ) const;
+    inline  BOOL    EndCurrPage( SwPaM * ) const;
+    inline  BOOL    EndNextPage( SwPaM * ) const;
+    inline  BOOL    EndPrevPage( SwPaM * ) const;
+    inline  SwCntntFrm *GetNextCntntFrm();
+    inline  SwCntntFrm *GetPrevCntntFrm();
+    inline  const SwCntntFrm *GetNextCntntFrm() const;
+    inline  const SwCntntFrm *GetPrevCntntFrm() const;
+
+    //nMaxHeight liefert die benoetigte Hoehe,
+    //bSplit sagt, obj der Absatz gesplittet werden muss.
+    virtual BOOL WouldFit( SwTwips &nMaxHeight, BOOL &bSplit );
+
+    BOOL MoveFtnCntFwd( BOOL, SwFtnBossFrm* );//von MoveFwd gerufen bei Ftn-Inhalt
+};
+
+inline SwCntntNode *SwCntntFrm::GetNode()
+{
+    return (SwCntntNode*)GetDep();
+}
+inline const SwCntntNode *SwCntntFrm::GetNode() const
+{
+    return (SwCntntNode*)GetDep();
+}
+
+inline const SwCntntFrm *SwCntntFrm::GetNextCntntFrm() const
+{
+    if ( GetNext() && GetNext()->IsCntntFrm() )
+        return (const SwCntntFrm*)GetNext();
+    else
+        return ImplGetNextCntntFrm();
+}
+inline const SwCntntFrm *SwCntntFrm::GetPrevCntntFrm() const
+{
+    if ( GetPrev() && GetPrev()->IsCntntFrm() )
+        return (const SwCntntFrm*)GetPrev();
+    else
+        return ImplGetPrevCntntFrm();
+}
+//Um doppelte Implementierung zu sparen wird hier ein bischen gecasted.
+inline SwCntntFrm *SwCntntFrm::GetNextCntntFrm()
+{
+    if ( GetNext() && GetNext()->IsCntntFrm() )
+        return (SwCntntFrm*)GetNext();
+    else
+        return (SwCntntFrm*)(((const SwCntntFrm*)this)->ImplGetNextCntntFrm());
+}
+inline SwCntntFrm *SwCntntFrm::GetPrevCntntFrm()
+{
+    if ( GetPrev() && GetPrev()->IsCntntFrm() )
+        return (SwCntntFrm*)GetPrev();
+    else
+        return (SwCntntFrm*)(((const SwCntntFrm*)this)->ImplGetPrevCntntFrm());
+}
+
+inline const SwCntntFrm *SwCntntFrm::GetFollow() const
+{
+    return (const SwCntntFrm*)SwFlowFrm::GetFollow();
+}
+inline SwCntntFrm *SwCntntFrm::GetFollow()
+{
+    return (SwCntntFrm*)SwFlowFrm::GetFollow();
+}
+
+#endif
diff --git a/sw/source/core/inc/colfrm.hxx b/sw/source/core/inc/colfrm.hxx
new file mode 100644
index 000000000000..f29a4e1c38ed
--- /dev/null
+++ b/sw/source/core/inc/colfrm.hxx
@@ -0,0 +1,83 @@
+/*************************************************************************
+ *
+ *  $RCSfile: colfrm.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:20 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _COLFRM_HXX
+#define _COLFRM_HXX
+
+#ifndef _SVMEMPOOL_HXX //autogen
+#include 
+#endif
+
+#include "ftnboss.hxx"
+
+class Sw3FrameIo;
+
+class SwColumnFrm: public SwFtnBossFrm
+{
+public:
+    SwColumnFrm( SwFrmFmt* );
+    SwColumnFrm( Sw3FrameIo&, SwLayoutFrm* );
+    ~SwColumnFrm();
+
+    virtual void Store( Sw3FrameIo& ) const;
+    DECL_FIXEDMEMPOOL_NEWDEL(SwColumnFrm)
+};
+
+#endif  //_COLFRM_HXX
diff --git a/sw/source/core/inc/dbg_lay.hxx b/sw/source/core/inc/dbg_lay.hxx
new file mode 100644
index 000000000000..1daf3339f856
--- /dev/null
+++ b/sw/source/core/inc/dbg_lay.hxx
@@ -0,0 +1,144 @@
+/*************************************************************************
+ *
+ *  $RCSfile: dbg_lay.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:20 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _DBG_LAY_HXX
+#define _DBG_LAY_HXX
+
+#define PROT_FILE_INIT  0x00000000
+#define PROT_INIT       0x00000001
+#define PROT_MAKEALL    0x00000002
+#define PROT_MOVE_FWD   0x00000004
+#define PROT_MOVE_BWD   0x00000008
+#define PROT_GROW       0x00000010
+#define PROT_SHRINK     0x00000020
+#define PROT_GROW_TST   0x00000040
+#define PROT_SHRINK_TST 0x00000080
+#define PROT_SIZE       0x00000100
+#define PROT_PRTAREA    0x00000200
+#define PROT_POS        0x00000400
+#define PROT_ADJUSTN    0x00000800
+#define PROT_SECTION    0x00001000
+#define PROT_CUT        0x00002000
+#define PROT_PASTE      0x00004000
+#define PROT_LEAF       0x00008000
+#define PROT_TESTFORMAT 0x00010000
+#define PROT_FRMCHANGES 0x00020000
+
+
+#define ACT_START           1
+#define ACT_END             2
+#define ACT_CREATE_MASTER   3
+#define ACT_CREATE_FOLLOW   4
+#define ACT_DEL_MASTER      5
+#define ACT_DEL_FOLLOW      6
+#define ACT_MERGE           7
+#define ACT_NEXT_SECT       8
+#define ACT_PREV_SECT       9
+
+#ifndef PRODUCT
+
+#include "swtypes.hxx"
+
+class SwImplProtocol;
+class SwFrm;
+class SwImplEnterLeave;
+
+class SwProtocol
+{
+    static ULONG nRecord;
+    static SwImplProtocol* pImpl;
+    static BOOL Start() { return 0 != ( PROT_INIT & nRecord ); }
+public:
+    static ULONG Record() { return nRecord; }
+    static void SetRecord( ULONG nNew ) { nRecord = nNew; }
+    static BOOL Record( ULONG nFunc ) { return 0 != (( nFunc | PROT_INIT ) & nRecord); }
+    static void Record( const SwFrm* pFrm, ULONG nFunction, ULONG nAction, void* pParam );
+    static void Init();
+    static void Stop();
+};
+
+class SwEnterLeave
+{
+    SwImplEnterLeave* pImpl;
+    void Ctor( const SwFrm* pFrm, ULONG nFunc, ULONG nAct, void* pPar );
+    void Dtor();
+public:
+    SwEnterLeave( const SwFrm* pFrm, ULONG nFunc, ULONG nAct, void* pPar )
+        { if( SwProtocol::Record( nFunc ) ) Ctor( pFrm, nFunc, nAct, pPar ); else pImpl = NULL; }
+    ~SwEnterLeave() { if( pImpl ) Dtor(); }
+};
+
+#define PROTOCOL( pFrm, nFunc, nAct, pPar ) {   if( SwProtocol::Record( nFunc ) )\
+                                                    SwProtocol::Record( pFrm, nFunc, nAct, pPar ); }
+#define PROTOCOL_INIT SwProtocol::Init();
+#define PROTOCOL_STOP SwProtocol::Stop();
+#define PROTOCOL_ENTER( pFrm, nFunc, nAct, pPar ) SwEnterLeave aEnter( pFrm, nFunc, nAct, pPar );
+
+#else
+
+#define PROTOCOL( pFrm, nFunc, nAct, pPar )
+#define PROTOCOL_INIT
+#define PROTOCOL_STOP
+#define PROTOCOL_ENTER( pFrm, nFunc, nAct, pPar )
+
+#endif
+
+#endif
diff --git a/sw/source/core/inc/dbgloop.hxx b/sw/source/core/inc/dbgloop.hxx
new file mode 100644
index 000000000000..91de39367932
--- /dev/null
+++ b/sw/source/core/inc/dbgloop.hxx
@@ -0,0 +1,113 @@
+/*************************************************************************
+ *
+ *  $RCSfile: dbgloop.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:20 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _DBGLOOP_HXX
+#define _DBGLOOP_HXX
+
+#ifndef PRODUCT
+
+#ifndef _SOLAR_H
+#include 
+#endif
+
+class SvStream;
+
+#define DBG_MAX_STACK   20      // Verschachtelungstiefe
+#define DBG_MAX_LOOP  1000      // das Abbruchkriterium
+
+class DbgLoopStack
+{
+    USHORT aCount[DBG_MAX_STACK];
+    USHORT nPtr;
+    const void *pDbg;
+    void Reset();
+public:
+    DbgLoopStack();
+    void Push( const void *pThis );
+    void Pop();
+    void Print( SvStream &rOS ) const; //$ ostream
+};
+
+class DbgLoop
+{
+    friend inline void PrintLoopStack( SvStream &rOS ); //$ ostream
+    static DbgLoopStack aDbgLoopStack;
+public:
+    inline DbgLoop( const void *pThis ) { aDbgLoopStack.Push( pThis ); }
+    inline ~DbgLoop() { aDbgLoopStack.Pop(); }
+};
+
+inline void PrintLoopStack( SvStream &rOS ) //$ ostream
+{
+    DbgLoop::aDbgLoopStack.Print( rOS );
+}
+
+#define DBG_LOOP    DbgLoop aDbgLoop( (const void*)this );
+#define DBG_LOOP_RESET  DbgLoop aDbgLoop( 0 );
+
+#else
+
+#define DBG_LOOP
+#define DBG_LOOP_RESET
+
+#endif
+
+#endif
diff --git a/sw/source/core/inc/dflyobj.hxx b/sw/source/core/inc/dflyobj.hxx
new file mode 100644
index 000000000000..b0471353d679
--- /dev/null
+++ b/sw/source/core/inc/dflyobj.hxx
@@ -0,0 +1,156 @@
+/*************************************************************************
+ *
+ *  $RCSfile: dflyobj.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:20 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _DFLYOBJ_HXX
+#define _DFLYOBJ_HXX
+
+#ifndef _SVDOVIRT_HXX //autogen
+#include 
+#endif
+#ifndef _SVDOBJ_HXX //autogen
+#include 
+#endif
+
+class SwFlyFrm;
+class SwFrmFmt;
+class SdrObjMacroHitRec;
+
+const UINT32 SWGInventor =  UINT32('S')*0x00000001+
+                            UINT32('W')*0x00000100+
+                            UINT32('G')*0x00010000;
+
+const UINT16 SwFlyDrawObjIdentifier = 0x0001;
+const UINT16 SwDrawFirst            = 0x0001;
+
+//---------------------------------------
+//SwFlyDrawObj, Die DrawObjekte fuer Flys.
+
+class SwFlyDrawObj : public SdrObject
+{
+public:
+    TYPEINFO();
+
+    SwFlyDrawObj();
+
+    virtual FASTBOOL Paint(ExtOutputDevice& rOut, const SdrPaintInfoRec& rInfoRec) const;
+
+    //Damit eine Instanz dieser Klasse beim laden erzeugt werden kann
+    //(per Factory).
+    virtual UINT32 GetObjInventor()     const;
+    virtual UINT16 GetObjIdentifier()   const;
+    virtual UINT16 GetObjVersion()      const;
+};
+
+//---------------------------------------
+//SwVirtFlyDrawObj, die virtuellen Objekte fuer Flys.
+//Flys werden immer mit virtuellen Objekten angezeigt. Nur so koennen sie
+//ggf. mehrfach angezeigt werden (Kopf-/Fusszeilen).
+
+class SwVirtFlyDrawObj : public SdrVirtObj
+{
+    SwFlyFrm *pFlyFrm;
+
+public:
+    TYPEINFO();
+
+    SwVirtFlyDrawObj(SdrObject& rNew, SwFlyFrm* pFly);
+    ~SwVirtFlyDrawObj();
+
+    //Ueberladene Methoden der Basisklasse SdrVirtObj
+    virtual SdrObject* CheckHit(const Point& rPnt, USHORT nTol, const SetOfByte* pVisiLayer) const;
+    virtual FASTBOOL Paint(ExtOutputDevice& rOut, const SdrPaintInfoRec& rInfoRec) const;
+    virtual void     TakeObjInfo( SdrObjTransformInfoRec& rInfo ) const;
+
+    //Wir nehemen die Groessenbehandlung vollstaendig selbst in die Hand.
+    virtual const Rectangle& GetBoundRect() const;
+    virtual       void       RecalcBoundRect();
+    virtual       void       RecalcSnapRect();
+    virtual const Rectangle& GetSnapRect()  const;
+    virtual       void       SetSnapRect(const Rectangle& rRect);
+    virtual       void       NbcSetSnapRect(const Rectangle& rRect);
+    virtual const Rectangle& GetLogicRect() const;
+    virtual       void       SetLogicRect(const Rectangle& rRect);
+    virtual       void       NbcSetLogicRect(const Rectangle& rRect);
+    virtual       void       TakeXorPoly(XPolyPolygon& rPoly, FASTBOOL) const;
+    virtual       void       NbcMove  (const Size& rSiz);
+    virtual       void       NbcResize(const Point& rRef, const Fraction& xFact,
+                                       const Fraction& yFact);
+    virtual       void       Move  (const Size& rSiz);
+    virtual       void       Resize(const Point& rRef, const Fraction& xFact,
+                                    const Fraction& yFact);
+
+    const SwFrmFmt *GetFmt() const;
+          SwFrmFmt *GetFmt();
+
+    // Get Methoden fuer die Fly Verpointerung
+          SwFlyFrm* GetFlyFrm()         { return pFlyFrm; }
+    const SwFlyFrm* GetFlyFrm() const   { return pFlyFrm; }
+
+    void SetRect() const;
+    void _SetRectsDirty()               { SetRectsDirty(); }
+
+    // ist eine URL an einer Grafik gesetzt, dann ist das ein Makro-Object
+    virtual FASTBOOL HasMacro() const;
+    virtual SdrObject* CheckMacroHit       (const SdrObjMacroHitRec& rRec) const;
+    virtual Pointer    GetMacroPointer     (const SdrObjMacroHitRec& rRec) const;
+};
+
+
+#endif
diff --git a/sw/source/core/inc/docfld.hxx b/sw/source/core/inc/docfld.hxx
new file mode 100644
index 000000000000..0410e3e1807e
--- /dev/null
+++ b/sw/source/core/inc/docfld.hxx
@@ -0,0 +1,221 @@
+/*************************************************************************
+ *
+ *  $RCSfile: docfld.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:20 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _DOCFLD_HXX
+#define _DOCFLD_HXX
+
+#ifndef _CALC_HXX
+#include          // fuer SwHash
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+
+class SwTxtFld;
+class SwIndex;
+class SwNodeIndex;
+class SwCntntNode;
+class SwCntntFrm;
+class SwSectionNode;
+class SwSection;
+class SwTxtTOXMark;
+class SwTableBox;
+
+// Update an den Expression Feldern
+class _SetGetExpFld
+{
+    ULONG nNode;
+    xub_StrLen nCntnt;
+    union {
+        const SwTxtFld* pTxtFld;
+        const SwSection* pSection;
+        const SwPosition* pPos;
+        const SwTxtTOXMark* pTxtTOX;
+        const SwTableBox* pTBox;
+    } CNTNT;
+    enum _SetGetExpFldType
+        {
+            TEXTFIELD, TEXTTOXMARK, SECTIONNODE, CRSRPOS, TABLEBOX
+        } eSetGetExpFldType;
+
+public:
+    _SetGetExpFld( const SwNodeIndex& rNdIdx, const SwTxtFld* pFld = 0,
+                    const SwIndex* pIdx = 0 );
+
+    _SetGetExpFld( const SwSectionNode& rSectNode,
+                    const SwPosition* pPos = 0  );
+
+    _SetGetExpFld( const SwTableBox& rTableBox,
+                    const SwPosition* pPos = 0  );
+
+    _SetGetExpFld( const SwNodeIndex& rNdIdx, const SwTxtTOXMark& rTOX,
+                    const SwIndex* pIdx );
+
+    _SetGetExpFld( const SwPosition& rPos );
+
+    BOOL operator==( const _SetGetExpFld& rFld ) const
+    {   return nNode == rFld.nNode && nCntnt == rFld.nCntnt &&
+                ( !CNTNT.pTxtFld || !rFld.CNTNT.pTxtFld ||
+                    CNTNT.pTxtFld == rFld.CNTNT.pTxtFld ); }
+    BOOL operator<( const _SetGetExpFld& rFld ) const;
+
+    const SwTxtFld* GetFld() const
+        { return TEXTFIELD == eSetGetExpFldType ? CNTNT.pTxtFld : 0; }
+    const SwTxtTOXMark* GetTOX() const
+        { return TEXTTOXMARK == eSetGetExpFldType ? CNTNT.pTxtTOX : 0; }
+    const SwSection* GetSection() const
+        { return SECTIONNODE == eSetGetExpFldType ? CNTNT.pSection : 0; }
+    const SwTableBox* GetTableBox() const
+        { return TABLEBOX == eSetGetExpFldType ? CNTNT.pTBox : 0; }
+
+    ULONG GetNode() const { return nNode; }
+    xub_StrLen GetCntnt() const { return nCntnt; }
+    const void* GetPointer() const { return CNTNT.pTxtFld; }
+
+    void GetPos( SwPosition& rPos ) const;
+    void GetPosOfContent( SwPosition& rPos ) const;
+
+    const SwNode* GetNodeFromCntnt() const;
+    xub_StrLen GetCntPosFromCntnt() const;
+
+    void SetBodyPos( const SwCntntFrm& rFrm );
+};
+
+typedef _SetGetExpFld* _SetGetExpFldPtr;
+SV_DECL_PTRARR_SORT_DEL( _SetGetExpFlds, _SetGetExpFldPtr, 0, 10 )
+
+
+// Struktur zum Speichern der Strings aus SetExp-String-Feldern
+struct _HashStr : public SwHash
+{
+    String aSetStr;
+    _HashStr( const String& rName, const String& rText, _HashStr* = 0 );
+};
+
+struct SwCalcFldType : public SwHash
+{
+    const SwFieldType* pFldType;
+
+    SwCalcFldType( const String& rStr, const SwFieldType* pFldTyp )
+        : SwHash( rStr ), pFldType( pFldTyp )
+    {}
+};
+
+// Suche nach dem String, der unter dem Namen in der HashTabelle abgelegt
+// wurde
+void LookString( SwHash** ppTbl, USHORT nSize, const String& rName,
+                    String& rRet, USHORT* pPos = 0 );
+
+
+// --------
+
+const int GETFLD_ALL        = 3;        // veroderte Flags !!
+const int GETFLD_CALC       = 1;
+const int GETFLD_EXPAND     = 2;
+
+class SwDocUpdtFld
+{
+    _SetGetExpFlds* pFldSortLst;    // akt. Field-Liste zum Calculieren
+    SwCalcFldType*  aFldTypeTable[ TBLSZ ];
+
+// noch eine weitere Optimierung - wird z.Z. nicht angesprochen!
+    long nFldUpdtPos;               // ab dieser Position mit Update starten
+    SwCntntNode* pCNode;            // der TxtNode zur UpdatePos.
+
+    ULONG nNodes;                   // sollte die NodesAnzahl unterschiedlich sein
+    BYTE nFldLstGetMode;
+
+    BOOL bInUpdateFlds : 1;         // zur Zeit laeuft ein UpdateFlds,
+    BOOL bFldsDirty : 1;            // irgendwelche Felder sind ungueltig
+
+    void _MakeFldList( SwDoc& pDoc, int eGetMode );
+    void GetBodyNode( const SwTxtFld& , USHORT nFldWhich );
+    void GetBodyNode( const SwSectionNode&);
+public:
+    SwDocUpdtFld();
+    ~SwDocUpdtFld();
+
+    const _SetGetExpFlds* GetSortLst() const { return pFldSortLst; }
+
+    void MakeFldList( SwDoc& rDoc, int bAll, int eGetMode )
+    {
+        if( !pFldSortLst || bAll || !( eGetMode & nFldLstGetMode ) ||
+            rDoc.GetNodes().Count() != nNodes )
+            _MakeFldList( rDoc, eGetMode );
+    }
+
+    void InsDelFldInFldLst( BOOL bIns, const SwTxtFld& rFld );
+
+    void InsertFldType( const SwFieldType& rType );
+    void RemoveFldType( const SwFieldType& rType );
+
+    BOOL IsInUpdateFlds() const         { return bInUpdateFlds; }
+    void SetInUpdateFlds( BOOL b )      { bInUpdateFlds = b; }
+
+    BOOL IsFieldsDirty() const          { return bFldsDirty; }
+    void SetFieldsDirty( BOOL b )       { bFldsDirty = b; }
+
+    SwHash**    GetFldTypeTable() const { return (SwHash**)aFldTypeTable; }
+};
+
+
+#endif  // _DOCFLD_HXX
+
diff --git a/sw/source/core/inc/docsort.hxx b/sw/source/core/inc/docsort.hxx
new file mode 100644
index 000000000000..3d5d77ef9821
--- /dev/null
+++ b/sw/source/core/inc/docsort.hxx
@@ -0,0 +1,201 @@
+/*************************************************************************
+ *
+ *  $RCSfile: docsort.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:20 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _SORT_HXX
+#define _SORT_HXX
+
+#ifndef _SVARRAY_HXX //autogen
+#include 
+#endif
+
+class SwDoc;
+class SwTableBox;
+class SwUndoSort;
+class FlatFndBox;
+struct SwSortOptions;
+struct SwSortElement;
+class _FndBox;
+class _FndLine;
+class International;
+
+/*--------------------------------------------------------------------
+    Beschreibung: Liste aller sortierten Elemente
+ --------------------------------------------------------------------*/
+typedef const _FndBox*      _FndBoxPtr;
+typedef SwSortElement*      SwSortElementPtr;
+typedef const SwTableBox*   SwMovedBoxPtr;
+
+SV_DECL_PTRARR_SORT(SwSortElements, SwSortElementPtr, 0, 1 );
+SV_DECL_PTRARR(SwMovedBoxes,        SwMovedBoxPtr, 10, 10 );
+
+/*--------------------------------------------------------------------
+    Beschreibung: Funktionen zum Moven von Boxen
+ --------------------------------------------------------------------*/
+
+void MoveCol(SwDoc* pDoc, const FlatFndBox& rBox,
+             USHORT nS, USHORT nT, SwMovedBoxes& rMovedList, SwUndoSort* pUD=0);
+void MoveRow(SwDoc* pDoc, const FlatFndBox& rBox,
+             USHORT nS, USHORT nT, SwMovedBoxes& rMovedList, SwUndoSort* pUD=0);
+void MoveCell(SwDoc* pDoc, const SwTableBox* pSource,
+              const SwTableBox* pTar, BOOL bMovedBefore, SwUndoSort* pUD=0);
+
+/*-------------------------------------------------------------------
+    Beschreibung: Elemente zum Sortieren von Text und Tabellen-Inhalt
+ --------------------------------------------------------------------*/
+
+struct SwSortElement
+{
+    static  SwSortOptions*   pOptions;
+    static  SwDoc*           pDoc;
+    static const FlatFndBox* pBox;
+    static  International*   pIntl;
+
+    static void Init( SwDoc*, const SwSortOptions& rOpt, FlatFndBox* = 0 );
+    static void Finit();
+
+    virtual ~SwSortElement();
+
+    virtual String GetKey(USHORT nKey ) const = 0;
+    virtual double GetValue(USHORT nKey ) const;
+
+    BOOL operator==(const SwSortElement& );
+    BOOL operator<(const SwSortElement& );
+
+    double StrToDouble(const String& rStr) const;
+};
+
+/*--------------------------------------------------------------------
+    Beschreibung: Sortieren Text
+ --------------------------------------------------------------------*/
+
+struct SwSortTxtElement : public SwSortElement
+{
+    // fuer Text
+    ULONG           nOrg;
+    SwNodeIndex     aPos;
+
+    SwSortTxtElement( const SwNodeIndex& rPos );
+    virtual ~SwSortTxtElement();
+
+    virtual String GetKey( USHORT nKey ) const;
+};
+
+/*--------------------------------------------------------------------
+    Beschreibung: Sortieren Tabelle
+ --------------------------------------------------------------------*/
+
+struct SwSortBoxElement : public SwSortElement
+{
+    USHORT                      nRow;
+
+    SwSortBoxElement( USHORT nRC );
+    virtual ~SwSortBoxElement();
+
+    virtual String GetKey( USHORT nKey ) const;
+    virtual double GetValue( USHORT nKey ) const;
+};
+
+
+/*--------------------------------------------------------------------
+    Beschreibung: SymFndBoxes stellt ein zweidimensionales
+                  Array von FndBoxes dar
+ --------------------------------------------------------------------*/
+
+class FlatFndBox
+{
+public:
+    FlatFndBox(SwDoc* pDocPtr, const _FndBox& rBox);
+    ~FlatFndBox();
+
+    BOOL                IsSymmetric() const { return bSym;  }
+    USHORT              GetRows()     const { return nRows; }
+    USHORT              GetCols()     const { return nCols; }
+
+    const _FndBox*      GetBox(USHORT nCol, USHORT nRow) const;
+
+    inline BOOL         HasItemSets() const;
+    const SfxItemSet*   GetItemSet(USHORT nCol, USHORT nRow) const;
+
+private:
+
+    BOOL                CheckLineSymmetry(const _FndBox& rBox);
+    BOOL                CheckBoxSymmetry(const _FndLine& rLn);
+    USHORT              GetColCount(const _FndBox& rBox);
+    USHORT              GetRowCount(const _FndBox& rBox);
+    void                FillFlat(const _FndBox&, BOOL bLastBox=FALSE);
+
+    SwDoc*              pDoc;
+    const _FndBox&      rBoxRef;
+    _FndBoxPtr*         pArr;
+    SfxItemSet**        ppItemSets;
+
+    USHORT              nRows;
+    USHORT              nCols;
+
+    USHORT              nRow;
+    USHORT              nCol;
+
+    BOOL                bSym;
+};
+
+
+inline BOOL FlatFndBox::HasItemSets() const { return 0 != ppItemSets; }
+
+#endif // _NDSORT_HXX
diff --git a/sw/source/core/inc/doctxm.hxx b/sw/source/core/inc/doctxm.hxx
new file mode 100644
index 000000000000..4e577cb873ad
--- /dev/null
+++ b/sw/source/core/inc/doctxm.hxx
@@ -0,0 +1,176 @@
+/*************************************************************************
+ *
+ *  $RCSfile: doctxm.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:20 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _DOCTXM_HXX
+#define _DOCTXM_HXX
+
+
+#ifndef _SVARRAY_HXX //autogen
+#include 
+#endif
+
+#ifndef _TOX_HXX
+#include 
+#endif
+#ifndef _SECTION_HXX
+#include 
+#endif
+
+class  International;
+class  SvUShorts;
+class  SvStringsDtor;
+class  SvPtrarr;
+class  SwTxtNode;
+class  SwTxtFmtColl;
+struct SwPosition;
+struct SwTOXSortTabBase;
+
+typedef SwTOXSortTabBase* SwTOXSortTabBasePtr;
+
+SV_DECL_PTRARR(SwTOXSortTabBases, SwTOXSortTabBasePtr, 0, 5 );
+
+/*--------------------------------------------------------------------
+     Beschreibung: Ring der speziellen Verzeichnisse
+ --------------------------------------------------------------------*/
+
+class SwTOXBaseSection : public SwTOXBase, public SwSection
+{
+    SwTOXSortTabBases aSortArr;
+
+    void    UpdateMarks( const International& rIntl,
+                            const SwTxtNode* pOwnChapterNode );
+    void    UpdateOutline( const SwTxtNode* pOwnChapterNode );
+    void    UpdateTemplate( const SwTxtNode* pOwnChapterNode );
+    void    UpdateCntnt( SwTOXElement eType,
+                            const SwTxtNode* pOwnChapterNode );
+    void    UpdateTable( const SwTxtNode* pOwnChapterNode );
+    void    UpdateSequence( const SwTxtNode* pOwnChapterNode );
+    void    UpdateAuthorities( const SwTxtNode* pOwnChapterNode,
+                                        const International& rIntl );
+    void    UpdateAll();
+
+    // Sortiert einfuegen ins Array fuer die Generierung
+    void    InsertSorted(SwTOXSortTabBase* pBase);
+
+    // Alpha-Trennzeichen bei der Generierung einfuegen
+    void    InsertAlphaDelimitter( const International& rIntl );
+
+    // Textrumpf generieren
+    void GenerateText( USHORT nArrayIdx, USHORT nCount, SvStringsDtor& );
+
+    // Seitennummerplatzhalter gegen aktuelle Nummern austauschen
+    void    _UpdatePageNum( SwTxtNode* pNd,
+                            const SvUShorts& rNums,
+                            const SvPtrarr &rDescs,
+                            const SvUShorts* pMainEntryNums );
+
+    // Bereich fuer Stichwort einfuegen suchen
+    Range GetKeyRange(const String& rStr, USHORT nLevel, const Range& rRange,
+                        const International& rIntl );
+
+    // returne die TextCollection ueber den Namen / aus Format-Pool
+    SwTxtFmtColl* GetTxtFmtColl( USHORT nLevel );
+
+public:
+    SwTOXBaseSection( const SwTOXBase& rBase );
+    virtual ~SwTOXBaseSection();
+
+    void Update(const SfxItemSet* pAttr = 0); // Formatieren
+    void UpdatePageNum();               // Seitennummern einfuegen
+    TYPEINFO();                         // fuers rtti
+
+    BOOL SetPosAtStartEnd( SwPosition& rPos, BOOL bAtStart = TRUE ) const;
+};
+/* -----------------02.09.99 07:52-------------------
+
+ --------------------------------------------------*/
+struct SwDefTOXBase_Impl
+{
+    SwTOXBase* pContBase;
+    SwTOXBase* pIdxBase;
+    SwTOXBase* pUserBase;
+    SwTOXBase* pTblBase;
+    SwTOXBase* pObjBase;
+    SwTOXBase* pIllBase;
+    SwTOXBase* pAuthBase;
+
+    SwDefTOXBase_Impl() :
+    pContBase(0),
+    pIdxBase(0),
+    pUserBase(0),
+    pTblBase(0),
+    pObjBase(0),
+    pIllBase(0),
+    pAuthBase(0)
+    {}
+    ~SwDefTOXBase_Impl()
+    {
+        delete pContBase;
+        delete pIdxBase;
+        delete pUserBase;
+        delete pTblBase;
+        delete pObjBase;
+        delete pIllBase;
+        delete pAuthBase;
+    }
+
+};
+
+#endif  // _DOCTXM_HXX
diff --git a/sw/source/core/inc/drawdev.hxx b/sw/source/core/inc/drawdev.hxx
new file mode 100644
index 000000000000..6d9d6467a328
--- /dev/null
+++ b/sw/source/core/inc/drawdev.hxx
@@ -0,0 +1,174 @@
+/*************************************************************************
+ *
+ *  $RCSfile: drawdev.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:20 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _DRAWDEV_HXX
+#define _DRAWDEV_HXX
+
+#include "swrect.hxx"
+
+#ifndef _OUTDEV_HXX //autogen
+#include 
+#endif
+
+/*************************************************************************
+ *                          class SwDrawDev
+ *
+ * Alle Draw-Methoden werden um den Offset *pPos verschoben.
+ *************************************************************************/
+
+class SwDrawDev
+{
+    OutputDevice  *pOut;
+    const Point *pPos;
+
+public:
+    inline SwDrawDev( OutputDevice *pOut, const Point *pPos )
+        :pOut(pOut), pPos(pPos) { }
+
+    inline OutputDevice *GetOut() { return pOut; }
+
+    // Ausgabemethoden
+    inline void DrawText( const Point& rStart, const String& rTxt,
+                          const USHORT nIdx = 0,
+                          const USHORT nLen = STRING_LEN );
+    inline void DrawStretchText( const Point& rStart, USHORT nWidth,
+                          const String& rTxt,
+                          const USHORT nIdx = 0,
+                          const USHORT nLen = STRING_LEN );
+    inline void DrawTextArray( const Point& rStart,
+                          const String& rTxt,
+                          long *pKernArray = 0,
+                          const USHORT nIdx = 0,
+                          const USHORT nLen = STRING_LEN);
+    inline void DrawLine( const Point& rStart, const Point& rEnd );
+    inline void DrawRect( const SwRect& rRect,
+                          const USHORT nHorzRount = 0,
+                          const USHORT nVertRound = 0 );
+
+    inline const Point *GetOrigin() const {return pPos; }
+};
+
+/*************************************************************************
+ *                      SwDrawDev::DrawText
+ *************************************************************************/
+
+inline void SwDrawDev::DrawText( const Point& rStart, const String& rTxt,
+                                 const USHORT nIdx, const USHORT nLen )
+{
+    if( !pPos )
+        pOut->DrawText( rStart, rTxt, nIdx, nLen );
+    else
+        pOut->DrawText( rStart - *pPos, rTxt, nIdx, nLen );
+}
+
+/*************************************************************************
+ *                      SwDrawDev::DrawStretchText
+ *************************************************************************/
+
+inline void SwDrawDev::DrawStretchText( const Point& rStart, USHORT nWidth,
+       const String& rTxt, const USHORT nIdx, const USHORT nLen )
+{
+    if( !pPos )
+        pOut->DrawStretchText( rStart, nWidth, rTxt, nIdx, nLen );
+    else
+        pOut->DrawStretchText( rStart - *pPos, nWidth, rTxt, nIdx, nLen );
+}
+
+/*************************************************************************
+ *                      SwDrawDev::DrawTextArray
+ *************************************************************************/
+
+inline void SwDrawDev::DrawTextArray( const Point& rStart, const String& rTxt,
+            long *pKernArray, const USHORT nIdx, const USHORT nLen )
+{
+    if( !pPos )
+        pOut->DrawTextArray( rStart, rTxt, pKernArray, nIdx, nLen );
+    else
+        pOut->DrawTextArray( rStart - *pPos, rTxt, pKernArray, nIdx, nLen );
+}
+
+/*************************************************************************
+ *                      SwDrawDev::DrawLine
+ *************************************************************************/
+
+inline void SwDrawDev::DrawLine( const Point& rStart, const Point& rEnd )
+{
+    if( !pPos )
+        pOut->DrawLine( rStart, rEnd );
+    else
+        pOut->DrawLine( rStart - *pPos, rEnd - *pPos );
+}
+
+/*************************************************************************
+ *                      SwDrawDev::DrawRect
+ *************************************************************************/
+
+inline void SwDrawDev::DrawRect( const SwRect& rRect,
+                      const USHORT nHorzRound, const USHORT nVertRound )
+{
+    SwRect aRect( rRect );
+    if( pPos )
+        aRect.Pos() -= *pPos;
+    pOut->DrawRect( aRect.SVRect(), nHorzRound, nVertRound );
+}
+
+
+#endif
diff --git a/sw/source/core/inc/drawfont.hxx b/sw/source/core/inc/drawfont.hxx
new file mode 100644
index 000000000000..4cc92ab5f964
--- /dev/null
+++ b/sw/source/core/inc/drawfont.hxx
@@ -0,0 +1,348 @@
+/*************************************************************************
+ *
+ *  $RCSfile: drawfont.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:20 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _DRAWFONT_HXX
+#define _DRAWFONT_HXX
+
+
+#ifndef _GEN_HXX //autogen
+#include 
+#endif
+#ifndef _STRING_HXX //autogen
+#include 
+#endif
+#include "errhdl.hxx"
+
+class OutputDevice;
+class Point;
+class SwWrongList;
+class Size;
+class SwFont;
+
+class SwDrawTextInfo
+{
+    OutputDevice* pOut;
+    ViewShell* pSh;
+    const Point* pPos;
+    const XubString* pText;
+    const SwWrongList* pWrong;
+    const Size* pSize;
+    SwFont *pFnt;
+    long nLeft;
+    long nRight;
+    xub_StrLen nIdx;
+    xub_StrLen nLen;
+    USHORT nWidth;
+    USHORT nAscent;
+    short nSperren;
+    short nKern;
+    short nSpace;
+    BOOL bBullet : 1;
+    BOOL bSpecialUnderline : 1;
+    BOOL bUpper : 1;        // Fuer Kapitaelchen: Grossbuchstaben-Flag
+    BOOL bDrawSpace : 1;    // Fuer Kapitaelchen: Unter/Durchstreichung
+    BOOL bGreyWave  : 1;    // Graue Wellenlinie beim extended TextInput
+    SwDrawTextInfo();       // nicht zulaessig
+public:
+#ifndef PRODUCT
+    BOOL bOut   : 1;    // In der Non-Product wird der Zugriff auf die Member
+    BOOL bPos   : 1;    // durch diese Flags ueberwacht.
+    BOOL bText  : 1;    // Wird ein Member gesetzt, so wird das entsprechende
+    BOOL bWrong : 1;    // Flag gesetzt.
+    BOOL bSize  : 1;    // Wird ein Member ausgelesen, so wird ASSERTet, dass
+    BOOL bFnt   : 1;    // dieser zuvor gesetzt worden ist.
+    BOOL bIdx   : 1;
+    BOOL bLen   : 1;
+    BOOL bWidth : 1;
+    BOOL bAscent: 1;
+    BOOL bSperr : 1;
+    BOOL bKern  : 1;
+    BOOL bSpace : 1;
+    BOOL bBull  : 1;
+    BOOL bSpec  : 1;
+    BOOL bUppr  : 1;
+    BOOL bDrawSp: 1;
+    BOOL bGreyWv: 1;
+    BOOL bLeft  : 1;
+    BOOL bRight : 1;
+#endif
+    SwDrawTextInfo( ViewShell *pS, OutputDevice &rO,
+                    const XubString &rSt, xub_StrLen nI, xub_StrLen nL,
+                    USHORT nW, BOOL bB )
+    {   pSh = pS; pOut = &rO; pText = &rSt; nIdx = nI; nLen = nL; nWidth = nW;
+        bBullet = bB; bSpecialUnderline = bGreyWave = FALSE;
+#ifndef PRODUCT
+        bOut = bText = bIdx = bLen = bWidth = bBull = bSpec = bGreyWv = TRUE;
+        bPos = bWrong = bSize = bFnt = bAscent = bKern = bSpace = bUppr =
+            bDrawSp = bLeft = bRight = FALSE;
+#endif
+    }
+    ViewShell *GetShell() const { return pSh; }
+    OutputDevice& GetOut() const {
+        ASSERT( bOut, "DrawTextInfo: Undefined Outputdevice" );
+        return *pOut;
+    }
+    OutputDevice *GetpOut() const {
+        ASSERT( bOut, "DrawTextInfo: Undefined Outputdevice" );
+        return pOut;
+    }
+    const Point &GetPos() const {
+        ASSERT( bPos, "DrawTextInfo: Undefined Position" );
+        return *pPos;
+    }
+    const XubString &GetText() const {
+        ASSERT( bText, "DrawTextInfo: Undefined String" );
+        return *pText;
+    }
+    const SwWrongList* GetWrong() const {
+        ASSERT( bWrong, "DrawTextInfo: Undefined WrongList" );
+        return pWrong;
+    }
+    const Size &GetSize() const {
+        ASSERT( bSize, "DrawTextInfo: Undefined Size" );
+        return *pSize;
+    }
+    SwFont* GetFont() const {
+        ASSERT( bFnt, "DrawTextInfo: Undefined Font" );
+        return pFnt;
+    }
+    xub_StrLen GetIdx() const {
+        ASSERT( bIdx, "DrawTextInfo: Undefined Index" );
+        return nIdx;
+    }
+    xub_StrLen GetLen() const {
+        ASSERT( bLen, "DrawTextInfo: Undefined Length" );
+        return nLen;
+    }
+    xub_StrLen GetEnd() const {
+        ASSERT( bIdx, "DrawTextInfo: Undefined Index" );
+        ASSERT( bLen, "DrawTextInfo: Undefined Length" );
+        return nIdx + nLen;
+    }
+    long GetLeft() const {
+        ASSERT( bLeft, "DrawTextInfo: Undefined left range" );
+        return nLeft;
+    }
+    long GetRight() const {
+        ASSERT( bRight, "DrawTextInfo: Undefined right range" );
+        return nRight;
+    }
+    USHORT GetWidth() const {
+        ASSERT( bWidth, "DrawTextInfo: Undefined Width" );
+        return nWidth;
+    }
+    USHORT GetAscent() const {
+        ASSERT( bAscent, "DrawTextInfo: Undefined Ascent" );
+        return nAscent;
+    }
+    short GetSperren() const {
+        ASSERT( bSperr, "DrawTextInfo: Undefined >Sperren<" );
+        return nSperren;
+    }
+    short GetKern() const {
+        ASSERT( bKern, "DrawTextInfo: Undefined Kerning" );
+        return nKern;
+    }
+    short GetSpace() const {
+        ASSERT( bSpace, "DrawTextInfo: Undefined Spacing" );
+        return nSpace;
+    }
+    BOOL GetBullet() const {
+        ASSERT( bBull, "DrawTextInfo: Undefined Bulletflag" );
+        return bBullet;
+    }
+    BOOL GetSpecialUnderline() const {
+        ASSERT( bSpec, "DrawTextInfo: Undefined Underlineflag" );
+        return bSpecialUnderline;
+    }
+    BOOL GetUpper() const {
+        ASSERT( bUppr, "DrawTextInfo: Undefined Upperflag" );
+        return bUpper;
+    }
+    BOOL GetDrawSpace() const {
+        ASSERT( bDrawSp, "DrawTextInfo: Undefined DrawSpaceflag" );
+        return bDrawSpace;
+    }
+    BOOL GetGreyWave() const {
+        ASSERT( bGreyWv, "DrawTextInfo: Undefined GreyWave" );
+        return bGreyWave;
+    }
+
+    void SetOut( OutputDevice &rNew ){ pOut = &rNew;
+#ifndef PRODUCT
+        bOut = TRUE;
+#endif
+    }
+    void SetPos( const Point &rNew ){ pPos = &rNew;
+#ifndef PRODUCT
+        bPos = TRUE;
+#endif
+    }
+    void SetText( const XubString &rNew ){ pText = &rNew;
+#ifndef PRODUCT
+        bText = TRUE;
+#endif
+    }
+    void SetWrong( const SwWrongList* pNew ){ pWrong = pNew;
+#ifndef PRODUCT
+        bWrong = TRUE;
+#endif
+    }
+    void SetSize( const Size &rNew ){ pSize = &rNew;
+#ifndef PRODUCT
+        bSize = TRUE;
+#endif
+    }
+    void SetFont( SwFont* pNew ){ pFnt = pNew;
+#ifndef PRODUCT
+        bFnt = TRUE;
+#endif
+    }
+    void SetIdx( xub_StrLen nNew ){ nIdx = nNew;
+#ifndef PRODUCT
+        bIdx = TRUE;
+#endif
+    }
+    void SetLen( xub_StrLen nNew ){ nLen = nNew;
+#ifndef PRODUCT
+        bLen = TRUE;
+#endif
+    }
+    void SetLeft( long nNew ){ nLeft = nNew;
+#ifndef PRODUCT
+        bLeft = TRUE;
+#endif
+    }
+    void SetRight( long nNew ){ nRight = nNew;
+#ifndef PRODUCT
+        bRight = TRUE;
+#endif
+    }
+    void SetWidth( USHORT nNew ){ nWidth = nNew;
+#ifndef PRODUCT
+        bWidth = TRUE;
+#endif
+    }
+    void SetAscent( USHORT nNew ){ nAscent = nNew;
+#ifndef PRODUCT
+        bAscent = TRUE;
+#endif
+    }
+    void SetKern( short nNew ){ nKern = nNew;
+#ifndef PRODUCT
+        bKern = TRUE;
+#endif
+    }
+    void SetSperren( short nNew ){ nSperren = nNew;
+#ifndef PRODUCT
+        bSperr = TRUE;
+#endif
+    }
+    void SetSpace( short nNew ){
+        if( nNew < 0 )
+        {
+            SetSperren( -nNew );
+            nSpace = 0;
+        }
+        else
+        {
+            nSpace = nNew;
+            SetSperren( 0 );
+        }
+#ifndef PRODUCT
+        bSpace = TRUE;
+#endif
+    }
+    void SetBullet( BOOL bNew ){ bBullet = bNew;
+#ifndef PRODUCT
+        bBull = TRUE;
+#endif
+    }
+    void SetSpecialUnderline( BOOL bNew ){ bSpecialUnderline = bNew;
+#ifndef PRODUCT
+        bSpec = TRUE;
+#endif
+    }
+    void SetUpper( BOOL bNew ){ bUpper = bNew;
+#ifndef PRODUCT
+        bUppr = TRUE;
+#endif
+    }
+    void SetDrawSpace( BOOL bNew ){ bDrawSpace = bNew;
+#ifndef PRODUCT
+        bDrawSp = TRUE;
+#endif
+    }
+    void SetGreyWave( BOOL bNew ){ bGreyWave = bNew;
+#ifndef PRODUCT
+        bGreyWv = TRUE;
+#endif
+    }
+    void ShiftX()
+    {
+        ASSERT( bPos, "DrawTextInfo: Undefined Position" );
+        ASSERT( bSize, "DrawTextInfo: Undefined Width" );
+        ((Point*)pPos)->X() += GetSize().Width();
+    }
+};
+
+
+#endif
+
diff --git a/sw/source/core/inc/dview.hxx b/sw/source/core/inc/dview.hxx
new file mode 100644
index 000000000000..03a4c98f51d8
--- /dev/null
+++ b/sw/source/core/inc/dview.hxx
@@ -0,0 +1,119 @@
+/*************************************************************************
+ *
+ *  $RCSfile: dview.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:20 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _DVIEW_HXX
+#define _DVIEW_HXX
+
+
+#ifndef _SVX_FMVIEW_HXX //autogen
+#include 
+#endif
+
+class OutputDevice;
+class SwViewImp;
+
+class SwDrawView : public FmFormView
+{
+    //Fuer den Anker
+    Point           aAnchorPoint;       //Ankerposition
+    SwViewImp      &rImp;               //Die View gehoert immer zu einer Shell
+
+    const SwFrm *CalcAnchor();
+
+protected:
+    // add custom handles (used by other apps, e.g. AnchorPos)
+    virtual void AddCustomHdl();
+
+public:
+    SwDrawView( SwViewImp &rI, SdrModel *pMd, OutputDevice* pOutDev=NULL );
+
+    //aus der Basisklasse
+    virtual SdrObject*   GetMaxToTopObj(SdrObject* pObj) const;
+    virtual SdrObject*   GetMaxToBtmObj(SdrObject* pObj) const;
+    virtual void         MarkListHasChanged();
+    virtual void         ObjOrderChanged( SdrObject* pObj, ULONG nOldPos,
+                                            ULONG nNewPos );
+    virtual BOOL TakeDragLimit(SdrDragMode eMode, Rectangle& rRect) const;
+    virtual void MakeVisible( const Rectangle&, Window &rWin );
+    virtual void CheckPossibilities();
+
+    const SwViewImp &Imp() const { return rImp; }
+          SwViewImp &Imp()       { return rImp; }
+
+    // Innerhalb eines des sichtbaren Ankers?
+    Rectangle *IsAnchorAtPos( const Point &rPt ) const;
+
+    //Anker und Xor fuer das Draggen.
+    void ShowDragAnchor();
+
+    virtual void DeleteMarked();
+
+    // temp. Fix fuer Bug 57153 - nach Undo kann in der MarkListe nicht
+    //  immer ein Writer-Draw-Object stehen ( SdrObject ohne User-Call)
+    // Dann muss die Markliste aktualisiert werden.
+    // JP 02.10.98: hat aber Nebenwirkungen,wie Bug 57475
+    //const SdrMarkList& GetMarkList() const;
+    //JP 06.10.98: 2. Versuch
+    inline void ValidateMarkList() { FlushComeBackTimer(); }
+};
+
+
+#endif
+
diff --git a/sw/source/core/inc/flowfrm.hxx b/sw/source/core/inc/flowfrm.hxx
new file mode 100644
index 000000000000..7e5371c9a9d4
--- /dev/null
+++ b/sw/source/core/inc/flowfrm.hxx
@@ -0,0 +1,216 @@
+/*************************************************************************
+ *
+ *  $RCSfile: flowfrm.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:20 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _FLOWFRM_HXX
+#define _FLOWFRM_HXX
+
+//Der FlowFrm gibt die Funktionalitaet fuer alle Frms vor, die fliessen und
+//die sich aufspalten koennen (wie CntntFrm oder TabFrm).
+//Teile der Funktionalitaet sind im FlowFrm implementiert, andere Teile werden
+//von den spezifischen Frms implementiert.
+//Der FlowFrm ist kein eigenstaender Frm, es kann also auch niemals eine
+//eigenstaendige Instanz vom FlowFrm existieren.
+//Der FlowFrm ist nicht einmal ein echter Frm. Die naheliegende Implementierung
+//waere ein FlowFrm der virtual vom SwFrm abgeleitet ist und direkt auf den
+//eigenen Instanzdaten arbeitet. Abgeleitete Klassen muessten sich
+//vom FlowFrm und (ueber mehrere Basisklassen weil der Klassenbaum sich direkt
+//vom SwFrm zu SwCntntFrm und zum SwLayoutFrm spaltet) virtual vom SwFrm
+//ableiten.
+//Leider entstehen dadurch - neben Problemen mit Compilern und Debuggern -
+//erhebliche zusaetzliche Kosten, die wir uns heutzutage IMHO nicht erlauben
+//koennen.
+//Ich greife deshalb auf eine andere Technik zurueck: Der FlowFrm hat eine
+//Referenz auf den SwFrm - der er genau betrachtet selbst ist - und ist mit
+//diesem befreundet. So kann der FlowFrm anstelle des this-Pointer mit der
+//Referenz auf den SwFrm arbeiten.
+
+#include "frame.hxx"    //fuer inlines
+
+class SwPageFrm;
+class SwRect;
+class SwBorderAttrs;
+class SwDoc;
+class SwNodeIndex;
+
+class SwFlowFrm
+{
+    //PrepareMake darf Locken/Unlocken (Robustheit)
+    friend inline void PrepareLock  ( SwFlowFrm * );
+    friend inline void PrepareUnlock( SwFlowFrm * );
+
+    //TblSel darf das Follow-Bit zuruecksetzen.
+    friend inline void UnsetFollow( SwFlowFrm *pFlow );
+
+    friend void MakeFrms( SwDoc *, const SwNodeIndex &, const SwNodeIndex & );
+
+    friend class SwNode2LayImpl;
+
+    SwFrm &rThis;
+
+    //Hilfsfunktionen fuer MoveSubTree()
+    static SwLayoutFrm *CutTree( SwFrm* );
+    static BOOL   PasteTree( SwFrm *, SwLayoutFrm *, SwFrm *, SwFrm* );
+
+    //Wird fuer das Zusammenspiel von _GetPrevxxx und MoveBwd gebraucht, damit
+    //mehrere Blaetter gleichzeitig uebersprungen werden koennen.
+    //Wird auch vom MoveBwd des TabFrm ausgewertet!
+    static BOOL bMoveBwdJump;
+
+protected:
+
+    SwFlowFrm *pFollow;
+
+    BOOL bIsFollow  :1; //Ist's ein Follow
+    BOOL bLockJoin  :1; //Join (und damit deleten) verboten wenn TRUE!
+    BOOL bUndersized:1; // wir sind kleiner als gewuenscht
+    BOOL bFtnAtEnd  :1; // For sectionfrms only: footnotes at the end of section
+    BOOL bEndnAtEnd :1; //  "       "        " : endnotes at the end of section
+    BOOL bCntntLock :1; //  "       "        " : content locked
+    BOOL bOwnFtnNum :1; //  "       "        " : special numbering of footnotes
+    BOOL bFtnLock   :1; //  "       "        " : ftn, don't leave this section bwd
+
+    //Prueft ob Vorwaertsfluss noch Sinn macht Endloswanderschaften (unterbinden)
+    inline BOOL IsFwdMoveAllowed();
+    BOOL IsKeepFwdMoveAllowed();    //Wie oben, Move fuer Keep.
+
+    //Prueft ob ein Obj das Umlauf wuenscht ueberlappt.
+    //eine Null bedeutet, kein Objekt ueberlappt,
+    // 1 heisst, Objekte, die am FlowFrm selbst verankert sind, ueberlappen
+    // 2 heisst, Objekte, die woanders verankert sind, ueberlappen
+    // 3 heistt, beiderlei verankerte Objekte ueberlappen
+    BYTE BwdMoveNecessary( const SwPageFrm *pPage, const SwRect &rRect );
+
+    void LockJoin()   { bLockJoin = TRUE;  }
+    void UnlockJoin() { bLockJoin = FALSE; }
+
+            BOOL CheckMoveFwd( BOOL &rbMakePage, BOOL bKeep, BOOL bMovedBwd );
+            BOOL MoveFwd( BOOL bMakePage, BOOL bPageBreak, BOOL bMoveAlways = FALSE );
+    virtual BOOL ShouldBwdMoved( SwLayoutFrm *pNewUpper, BOOL bHead, BOOL &rReformat )=0;
+            BOOL MoveBwd( BOOL &rbReformat );
+
+    BOOL IsKeep( const SwBorderAttrs &rAttrs ) const; //Ist ein Keep zu beruecksichtigen (Breaks!)
+
+public:
+    SwFlowFrm( SwFrm &rFrm );
+
+    const SwFrm *GetFrm() const            { return &rThis; }
+          SwFrm *GetFrm()                  { return &rThis; }
+
+    static BOOL IsMoveBwdJump()            { return bMoveBwdJump; }
+    static void SetMoveBwdJump( BOOL bNew ){ bMoveBwdJump = bNew; }
+
+    inline void SetUndersized( const BOOL bNew ) { bUndersized = bNew; }
+    inline BOOL IsUndersized()  const { return bUndersized; }
+
+    BOOL IsPrevObjMove() const;
+
+    //Die Kette mit minimalen Operationen und Benachrichtigungen unter den
+    //neuen Parent Moven.
+    void MoveSubTree( SwLayoutFrm* pParent, SwFrm* pSibling = 0 );
+
+           BOOL       HasFollow() const    { return pFollow ? TRUE : FALSE; }
+           BOOL       IsFollow()     const { return bIsFollow; }
+    inline void       _SetIsFollow( BOOL bSet ) { bIsFollow = bSet; }
+    const  SwFlowFrm *GetFollow() const    { return pFollow;   }
+           SwFlowFrm *GetFollow()          { return pFollow;   }
+           BOOL       IsAnFollow( const SwFlowFrm *pFlow ) const;
+    inline void       SetFollow( SwFlowFrm *pNew ) { pFollow = pNew; }
+                 SwFlowFrm *FindMaster();
+    inline const SwFlowFrm *FindMaster() const;
+
+    BOOL IsJoinLocked() const { return bLockJoin; }
+    BOOL IsFtnAtEnd() const { return bFtnAtEnd; }
+    BOOL IsEndnAtEnd() const { return bEndnAtEnd;   }
+    BOOL IsAnyNoteAtEnd() const { return bFtnAtEnd || bEndnAtEnd; }
+    BOOL AreNotesAtEnd() const { return bFtnAtEnd && bEndnAtEnd; }
+
+    BOOL IsPageBreak( BOOL bAct ) const;
+    BOOL IsColBreak( BOOL bAct ) const;
+
+    BOOL HasParaSpaceAtPages( BOOL bSct ) const;
+    SwTwips CalcUpperSpace( const SwBorderAttrs *pAttrs = NULL,
+                            const SwFrm* pPr = NULL ) const;
+
+    void CheckKeep();
+
+    void SetFtnLock( BOOL bNew ){ bFtnLock = bNew; }
+    BOOL IsFtnLock() const {    return bFtnLock; }
+    void SetOwnFtnNum( BOOL bNew ){ bOwnFtnNum = bNew; }
+    BOOL IsOwnFtnNum() const {  return bOwnFtnNum; }
+    void SetCntntLock( BOOL bNew ){ bCntntLock = bNew; }
+    BOOL IsCntntLocked() const {    return bCntntLock; }
+
+    //casten einen Frm auf einen FlowFrm - wenns denn einer ist, sonst 0
+    //Diese Methoden muessen fuer neue Ableitungen geaendert werden!
+    static       SwFlowFrm *CastFlowFrm( SwFrm *pFrm );
+    static const SwFlowFrm *CastFlowFrm( const SwFrm *pFrm );
+};
+
+inline const SwFlowFrm *SwFlowFrm::FindMaster() const
+{
+    return ((SwFlowFrm*)this)->FindMaster();
+}
+inline BOOL SwFlowFrm::IsFwdMoveAllowed()
+{
+    return rThis.GetIndPrev() != 0;
+}
+
+
+#endif
diff --git a/sw/source/core/inc/flyfrm.hxx b/sw/source/core/inc/flyfrm.hxx
new file mode 100644
index 000000000000..bbd6d1e82d92
--- /dev/null
+++ b/sw/source/core/inc/flyfrm.hxx
@@ -0,0 +1,248 @@
+/*************************************************************************
+ *
+ *  $RCSfile: flyfrm.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:20 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _FLYFRM_HXX
+#define _FLYFRM_HXX
+
+#include "layfrm.hxx"
+
+class SwPageFrm;
+class SwFlyFrmFmt;
+class SwFmtFrmSize;
+struct SwCrsrMoveState;
+class SwBorderAttrs;
+class SwVirtFlyDrawObj;
+class SwSpzFrmFmts;
+class SwAttrSetChg;
+class PolyPolygon;
+
+#include 
+
+//Sucht ausgehend von pOldAnch einen Anker fuer Absatzgebundene Rahmen.
+//Wird beim Draggen von Absatzgebundenen Objekten zur Ankeranzeige sowie
+//fuer Ankerwechsel benoetigt.
+//implementiert in layout/flycnt.cxx
+const SwCntntFrm *FindAnchor( const SwFrm *pOldAnch, const Point &rNew,
+                              const BOOL bBody = FALSE );
+
+// berechnet das Rechteck, in dem das Objekt bewegt bzw. resized werden darf
+BOOL CalcClipRect( const SdrObject *pSdrObj, SwRect &rRect, BOOL bMove = TRUE );
+
+//allg. Basisklasse fuer alle Freifliegenden Rahmen
+class SwFlyFrm : public SwLayoutFrm
+{
+    //darf Locken. Definiert in frmtool.cxx
+    friend void AppendObjs   ( const SwSpzFrmFmts *, ULONG, SwFrm *, SwPageFrm * );
+    friend void AppendAllObjs( const SwSpzFrmFmts * );
+    friend void Notify( SwFlyFrm *, SwPageFrm *pOld, const SwRect &rOld );
+    //darf die Pos berechnen (lassen)
+    friend void lcl_MakeFlyPosition( SwFlyFrm *pFly );
+
+    void InitDrawObj( BOOL bNotify );   //Wird von den CToren gerufen.
+    void FinitDrawObj();                //Wird vom CTor gerufen.
+
+    void _UpdateAttr( SfxPoolItem*, SfxPoolItem*, BYTE &,
+                      SwAttrSetChg *pa = 0, SwAttrSetChg *pb = 0 );
+
+protected:
+
+    SwVirtFlyDrawObj *pDrawObj; // das Drawingobject zum Fly
+    SwFrm *pAnchor;             // An diesem LayoutFrm haengt der Frm, kann 0 sein
+
+    SwFlyFrm *pPrevLink,        // Vorgaenger/Nachfolger fuer Verkettung mit
+             *pNextLink;        // Textfluss
+
+    Point aRelPos;   //Die Relative Position zum Master
+
+private:
+    BOOL bLocked    :1; //Cntnt-gebundene Flys muessen derart blockiert werden
+                        //koennen, dass sie nicht Formatiert werden; :MakeAll
+                        //returnt dann sofort. Dies ist bei Seitenwechseln
+                        //waehrend der Formatierung notwendig.
+                        //Auch wahrend des RootCTors ist dies notwendig da
+                        //sonst der Anker formatiert wird obwohl die Root noch
+                        //nicht korrekt an der Shell haengt und weil sonst
+                        //initial zuviel Formatiert wuerde.
+    BOOL bNotifyBack:1; //TRUE wenn am Ende eines MakeAll() der Background
+                        //vom NotifyDTor benachrichtigt werden muss.
+protected:
+
+    BOOL bInvalid :1;   //Pos, PrtArea od. SSize wurden Invalidiert, sie werden
+                        //gleich wieder Validiert, denn sie muessen _immer_
+                        //gueltig sein. Damit in LayAction korrekt gearbeitet
+                        //werden kann muss hier festgehalten werden, dass sie
+                        //invalidiert wurden. Ausnahmen bestaetigen die Regelt!
+    BOOL bMinHeight:1;  //TRUE wenn die vom Attribut vorgegebene Hoehe eine
+                        //eine Minimalhoehe ist (der Frm also bei Bedarf
+                        //darueberhinaus wachsen kann).
+    BOOL bHeightClipped :1; //TRUE wenn der Fly nicht die Pos/Size anhand der Attrs
+    BOOL bWidthClipped  :1; //formatieren konnte, weil z.B. nicht genug Raum vorh.
+                            //war.
+    BOOL bFormatHeightOnly  :1; //Damit nach einer Anpassung der Breite
+                                //(CheckClip) nur das Format aufgerufen wird;
+                                //nicht aber die Breite anhand der Attribute
+                                //wieder bestimmt wird.
+    BOOL bInCnt         :1; // FLY_IN_CNTNT, als Zeichen verankert
+    BOOL bAtCnt         :1; // FLY_AT_CNTNT, am Absatz verankert
+    BOOL bLayout        :1; // FLY_PAGE, FLY_AT_FLY, an Seite oder Rahmen
+    BOOL bAutoPosition  :1; // FLY_AUTO_CNTNT, im Text verankerter Rahmen
+
+    friend class SwNoTxtFrm; // Darf NotifyBackground rufen
+    virtual void NotifyBackground( SwPageFrm *pPage,
+                                   const SwRect& rRect, PrepareHint eHint) = 0;
+
+    //Wird nur von SwXFrm::MakeAll() gerufen; wer es anders macht wird
+    //in einen Sack gesteckt und muss zwei Tage drin hocken bleiben.
+    virtual void MakeFlyPos();
+    virtual void Format( const SwBorderAttrs *pAttrs = 0 );
+    void MakePrtArea( const SwBorderAttrs &rAttrs );
+
+    void Lock()         { bLocked = TRUE; }
+    void Unlock()       { bLocked = FALSE; }
+
+    void SetMinHeight()  { bMinHeight = TRUE; }
+    void ResetMinHeight(){ bMinHeight = FALSE; }
+
+    Size CalcRel( const SwFmtFrmSize &rSz ) const;
+
+    SwFlyFrm( SwFlyFrmFmt*, SwFrm *pAnchor );
+    SwFlyFrm( Sw3FrameIo&, SwLayoutFrm* );
+public:
+
+    virtual ~SwFlyFrm();
+    virtual void Store( Sw3FrameIo& ) const;
+    virtual void Modify( SfxPoolItem*, SfxPoolItem* );
+        // erfrage vom Client Informationen
+    virtual BOOL GetInfo( SfxPoolItem& ) const;
+    virtual void Paint( const SwRect& ) const;
+    virtual void ChgSize( const Size& aNewSize );
+    virtual BOOL GetCrsrOfst( SwPosition *, Point&,
+                                const SwCrsrMoveState* = 0 ) const;
+
+    virtual void Cut();
+#ifndef PRODUCT
+    virtual void Paste( SwFrm* pParent, SwFrm* pSibling = 0 );
+#endif
+
+    SwTwips _Shrink( SwTwips, const SzPtr, BOOL bTst );
+    SwTwips _Grow  ( SwTwips, const SzPtr, BOOL bTst );
+    void    _Invalidate( SwPageFrm *pPage = 0 );
+
+    BOOL FrmSizeChg( const SwFmtFrmSize & );
+
+    const SwFrm *GetAnchor() const { return pAnchor; }
+          SwFrm *GetAnchor() { return pAnchor; }
+          void   ChgAnchor( SwFrm *pNew ) { pAnchor = pNew; }
+
+    SwFlyFrm *GetPrevLink() { return pPrevLink; }
+    SwFlyFrm *GetNextLink() { return pNextLink; }
+
+    static void ChainFrames( SwFlyFrm *pMaster, SwFlyFrm *pFollow );
+    static void UnchainFrames( SwFlyFrm *pMaster, SwFlyFrm *pFollow );
+
+    SwFlyFrm *FindChainNeighbour( SwFrmFmt &rFmt, SwFrm *pAnch = 0 );
+
+    const SwVirtFlyDrawObj *GetVirtDrawObj() const { return pDrawObj; }
+          SwVirtFlyDrawObj *GetVirtDrawObj()       { return pDrawObj; }
+    void NotifyDrawObj();
+
+    const Point& GetCurRelPos() const { return aRelPos; }
+    void ChgRelPos( const Point &rAbsPos );
+    BOOL IsInvalid() const { return bInvalid; }
+    void Invalidate() const { ((SwFlyFrm*)this)->bInvalid = TRUE; }
+    void Validate() const { ((SwFlyFrm*)this)->bInvalid = FALSE; }
+
+    BOOL IsMinHeight()  const { return bMinHeight; }
+    BOOL IsLocked()     const { return bLocked; }
+    BOOL IsAutoPos()    const { return bAutoPosition; }
+    BOOL IsFlyInCntFrm() const { return bInCnt; }
+    BOOL IsFlyFreeFrm() const { return bAtCnt || bLayout; }
+    BOOL IsFlyLayFrm() const { return bLayout; }
+    BOOL IsFlyAtCntFrm() const { return bAtCnt; }
+
+    BOOL IsNotifyBack() const { return bNotifyBack; }
+    void SetNotifyBack()      { bNotifyBack = TRUE; }
+    void ResetNotifyBack()    { bNotifyBack = FALSE; }
+
+    BOOL IsClipped()        const   { return bHeightClipped || bWidthClipped; }
+    BOOL IsHeightClipped()  const   { return bHeightClipped; }
+    BOOL IsWidthClipped()   const   { return bWidthClipped;  }
+
+    BOOL IsLowerOf( const SwLayoutFrm *pUpper ) const;
+    inline BOOL IsUpperOf( const SwFlyFrm *pLower ) const;
+
+    SwFrm *FindLastLower();
+
+    SwRect AddSpacesToFrm() const;
+
+    BOOL GetContour( PolyPolygon & rPoly ) const;
+
+    BOOL ConvertHoriTo40( SwHoriOrient &rHori, SwRelationOrient &rRel, SwTwips &rPos ) const;
+
+    //Auf dieser Shell painten (PreView, Print-Flag usw. rekursiv beachten)?.
+    static BOOL IsPaint( SdrObject *pObj, const ViewShell *pSh );
+};
+
+inline BOOL SwFlyFrm::IsUpperOf( const SwFlyFrm *pLower ) const
+{
+    return pLower->IsLowerOf( this );
+}
+
+#endif
diff --git a/sw/source/core/inc/flyfrms.hxx b/sw/source/core/inc/flyfrms.hxx
new file mode 100644
index 000000000000..f464193e7f66
--- /dev/null
+++ b/sw/source/core/inc/flyfrms.hxx
@@ -0,0 +1,207 @@
+/*************************************************************************
+ *
+ *  $RCSfile: flyfrms.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:20 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _FLYFRMS_HXX
+#define _FLYFRMS_HXX
+
+#include "flyfrm.hxx"
+
+//Basisklasse fuer diejenigen Flys, die sich relativ frei Bewegen koennen -
+//also die nicht _im_ Inhalt gebundenen Flys.
+class SwFlyFreeFrm : public SwFlyFrm
+{
+    SwPageFrm *pPage;   //Bei dieser Seite ist der Fly angemeldet.
+
+    void CheckClip( const SwFmtFrmSize &rSz );  //'Emergency' Clipping.
+
+protected:
+    virtual void NotifyBackground( SwPageFrm *pPage,
+                                   const SwRect& rRect, PrepareHint eHint);
+
+
+    SwFlyFreeFrm( SwFlyFrmFmt*, SwFrm *pAnchor );
+    SwFlyFreeFrm( Sw3FrameIo&, SwLayoutFrm* );
+public:
+
+    virtual ~SwFlyFreeFrm();
+    virtual void Store( Sw3FrameIo& ) const;
+
+    virtual void MakeAll();
+
+          SwPageFrm *GetPage()       { return pPage; }
+    const SwPageFrm *GetPage() const { return pPage; }
+    void  SetPage( SwPageFrm *pNew ) { pPage = pNew; }
+};
+
+
+//Die Fly's, die an einem Layoutfrm haengen und nicht inhaltsgebunden sind
+class SwFlyLayFrm : public SwFlyFreeFrm
+{
+public:
+    SwFlyLayFrm( SwFlyFrmFmt*, SwFrm *pAnchor );
+    SwFlyLayFrm( SwFlyLayFrm& );
+    SwFlyLayFrm( Sw3FrameIo&, SwLayoutFrm* );
+
+    virtual void Store( Sw3FrameIo& ) const;
+    virtual void Modify( SfxPoolItem*, SfxPoolItem* );
+
+};
+
+//Die Flys, die an einem Cntnt haengen nicht aber im Inhalt
+class SwFlyAtCntFrm : public SwFlyFreeFrm
+{
+    SwRect aLastCharRect; // Fuer autopositionierte Frames ( LAYER_IMPL )
+protected:
+    //Stellt sicher, das der Fly an der richtigen Seite haengt.
+    void AssertPage();
+
+    virtual void MakeAll();
+    virtual void MakeFlyPos();
+public:
+    SwFlyAtCntFrm( SwFlyFrmFmt*, SwFrm *pAnchor );
+    SwFlyAtCntFrm( Sw3FrameIo&, SwLayoutFrm* );
+
+    virtual void Store( Sw3FrameIo& ) const;
+    virtual void Modify( SfxPoolItem*, SfxPoolItem* );
+
+    void SetAbsPos( const Point &rNew );
+
+    // Fuer autopositionierte Frames ( LAYER_IMPL ), ueberprueft, ob sich
+    // die Ankerposition geaendert hat und invalidiert ggf.
+    void CheckCharRect();
+
+    SwTwips GetLastCharX() const { return aLastCharRect.Left() - Frm().Left(); }
+
+    SwTwips GetRelCharX( const SwFrm* pFrm ) const
+        { return aLastCharRect.Left() - pFrm->Frm().Left(); }
+    SwTwips GetRelCharY( const SwFrm* pFrm ) const
+        { return aLastCharRect.Bottom() - pFrm->Frm().Top(); }
+
+    void AddLastCharY( long nDiff ){ aLastCharRect.Pos().Y() += nDiff; }
+};
+
+//Die Flys, die an einem Zeichen in einem Cntnt haengen.
+class SwFlyInCntFrm : public SwFlyFrm
+{
+    Point aRef;  //Relativ zu diesem Point wird die AbsPos berechnet.
+    long  nLine; //Zeilenhoehe, Ref.Y() - nLine == Zeilenanfang.
+
+    BOOL bInvalidLayout :1;
+    BOOL bInvalidCntnt  :1;
+
+    virtual void MakeFlyPos();
+
+protected:
+    virtual void NotifyBackground( SwPageFrm *pPage,
+                                   const SwRect& rRect, PrepareHint eHint);
+    virtual void MakeAll();
+
+public:
+    SwFlyInCntFrm( SwFlyFrmFmt*, SwFrm *pAnchor );
+    SwFlyInCntFrm( Sw3FrameIo&, SwLayoutFrm* );
+
+    virtual ~SwFlyInCntFrm();
+    virtual void  Store( Sw3FrameIo& ) const;
+    virtual void  Format(  const SwBorderAttrs *pAttrs = 0 );
+    virtual void  Modify( SfxPoolItem*, SfxPoolItem* );
+
+    void SetRefPoint( const Point& rPoint, const Point &rRelPos );
+    const Point &GetRefPoint() const { return aRef; }
+    const Point &GetRelPos() const;
+          long   GetLineHeight() const { return nLine; }
+
+    inline void InvalidateLayout() const;
+    inline void InvalidateCntnt() const;
+    inline void ValidateLayout() const;
+    inline void ValidateCntnt() const;
+    BOOL IsInvalid() const { return (bInvalidLayout || bInvalidCntnt); }
+    BOOL IsInvalidLayout() const { return bInvalidLayout; }
+    BOOL IsInvalidCntnt() const { return bInvalidCntnt; }
+
+
+    //BP 26.11.93: vgl. tabfrm.hxx, gilt bestimmt aber fuer andere auch...
+    //Zum Anmelden der Flys nachdem ein FlyCnt erzeugt _und_ eingefuegt wurde.
+    //Muss vom Erzeuger gerufen werden, denn erst nach dem Konstruieren wird
+    //Das Teil gepastet; mithin ist auch erst dann die Seite zum Anmelden der
+    //Flys erreichbar.
+    void RegistFlys();
+
+    //siehe layact.cxx
+    void AddRefOfst( long nOfst ) { aRef.Y() += nOfst; }
+};
+
+inline void SwFlyInCntFrm::InvalidateLayout() const
+{
+    ((SwFlyInCntFrm*)this)->bInvalidLayout = TRUE;
+}
+inline void SwFlyInCntFrm::InvalidateCntnt() const
+{
+    ((SwFlyInCntFrm*)this)->bInvalidCntnt = TRUE;
+}
+inline void SwFlyInCntFrm::ValidateLayout() const
+{
+    ((SwFlyInCntFrm*)this)->bInvalidLayout = FALSE;
+}
+inline void SwFlyInCntFrm::ValidateCntnt() const
+{
+    ((SwFlyInCntFrm*)this)->bInvalidCntnt = FALSE;
+}
+
+#endif
diff --git a/sw/source/core/inc/fntcache.hxx b/sw/source/core/inc/fntcache.hxx
new file mode 100644
index 000000000000..e31eab87be57
--- /dev/null
+++ b/sw/source/core/inc/fntcache.hxx
@@ -0,0 +1,194 @@
+/*************************************************************************
+ *
+ *  $RCSfile: fntcache.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:20 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _FNTCACHE_HXX
+#define _FNTCACHE_HXX
+
+
+#ifndef _SV_FONT_HXX //autogen
+#include 
+#endif
+#ifndef _SVMEMPOOL_HXX //autogen
+#include 
+#endif
+#ifndef _GDIOBJ_HXX //autogen
+#include 
+#endif
+
+#include "swtypes.hxx"
+#include "swcache.hxx"
+
+class Printer;
+class OutputDevice;
+class FontMetric;
+class SwFntObj;
+class SwDrawTextInfo;   // DrawText
+class ViewShell;
+
+/*************************************************************************
+ *                      class SwFntCache
+ *************************************************************************/
+
+class SwFntCache : public SwCache
+{
+public:
+
+    inline SwFntCache() : SwCache(50,50
+#ifndef PRODUCT
+    , ByteString( RTL_CONSTASCII_STRINGPARAM(
+                        "Globaler Font-Cache pFntCache" ))
+#endif
+    ) {}
+
+    inline SwFntObj *First( ) { return (SwFntObj *)SwCache::First(); }
+    inline SwFntObj *Next( SwFntObj *pFntObj)
+        { return (SwFntObj *)SwCache::Next( (SwCacheObj *)pFntObj ); }
+    void Flush();
+};
+
+// Font-Cache, globale Variable, in txtinit.Cxx angelegt/zerstoert
+extern SwFntCache *pFntCache;
+extern SwFntObj *pLastFont;
+extern BYTE *pMagicNo;
+extern Color *pSpellCol;
+extern Color *pWaveCol;
+
+/*************************************************************************
+ *                      class SwFntObj
+ *************************************************************************/
+
+class SwFntObj : public SwCacheObj
+{
+    friend class SwFntAccess;
+    friend void _InitCore();
+    friend void _FinitCore();
+
+    Font *pScrFont;
+    Printer *pPrinter;
+    Font aFont;
+    USHORT nLeading;
+    USHORT nScrAscent;
+    USHORT nPrtAscent;
+    USHORT nScrHeight;
+    USHORT nPrtHeight;
+    USHORT nZoom;
+    BOOL bSymbol : 1;
+    BOOL bPaintBlank : 1;
+    BOOL ChooseFont( ViewShell *pSh, OutputDevice *pOut );
+
+    static long nPixWidth;
+    static MapMode *pPixMap;
+    static OutputDevice *pPixOut;
+
+public:
+    DECL_FIXEDMEMPOOL_NEWDEL(SwFntObj)
+
+    SwFntObj( const Font &rFont, const void* pOwner,
+              ViewShell *pSh );
+
+    virtual ~SwFntObj();
+
+    inline       Font *GetScrFont()     { return pScrFont; }
+    inline       Font *GetFont()        { return &aFont; }
+    inline const Font *GetFont() const  { return &aFont; }
+
+    inline USHORT GetLeading() const  { return nLeading; }
+
+    void GuessLeading( ViewShell *pSh, const FontMetric& rMet );
+    USHORT GetAscent( ViewShell *pSh, const OutputDevice *pOut );
+    USHORT GetHeight( ViewShell *pSh, const OutputDevice *pOut );
+    inline void CheckScrFont( ViewShell *pSh, const OutputDevice *pOut )
+                                 { if (!pScrFont) CreateScrFont(pSh,pOut); }
+    void   CreateScrFont( ViewShell *pSh, const OutputDevice *pOut );
+
+           void     SetDevFont( ViewShell *pSh, OutputDevice *pOut );
+    inline Printer *GetPrt() { return pPrinter; }
+    inline USHORT   GetZoom() { return nZoom; }
+    inline BOOL     IsSymbol() { return bSymbol; }
+
+    void   DrawText( SwDrawTextInfo &rInf );
+    Size  GetTextSize( ViewShell *pSh,
+             const OutputDevice *pOut, const XubString &rTxt,
+             const xub_StrLen nIdx, const xub_StrLen nLen, const short nKern = 0 );
+    xub_StrLen GetCrsrOfst( const OutputDevice *pOut, const XubString &rTxt,
+             const USHORT nOfst, const xub_StrLen nIdx, const xub_StrLen nLen,
+             short nKern = 0, short nSpaceAdd = 0 );
+};
+
+/*************************************************************************
+ *                      class SwFntAccess
+ *************************************************************************/
+
+
+class SwFntAccess : public SwCacheAccess
+{
+    ViewShell *pShell;
+protected:
+    virtual SwCacheObj *NewObj( );
+
+public:
+    SwFntAccess( const void * &rMagic, USHORT &rIndex, const void *pOwner,
+                 ViewShell *pShell,
+                 BOOL bCheck = FALSE  );
+    SwFntObj *Get();
+};
+
+
+#endif
diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx
new file mode 100644
index 000000000000..74b9d197d973
--- /dev/null
+++ b/sw/source/core/inc/frame.hxx
@@ -0,0 +1,919 @@
+/*************************************************************************
+ *
+ *  $RCSfile: frame.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:20 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _FRAME_HXX
+#define _FRAME_HXX
+
+#ifndef _SVARRAY_HXX //autogen
+#include 
+#endif
+#include "swtypes.hxx"  // fuer SwTwips
+#include "swrect.hxx"
+#include "calbck.hxx"   // fuer SwClient
+
+typedef long Size::* SzPtr;
+extern SzPtr pHeight;
+extern SzPtr pWidth;
+typedef long Point::* PtPtr;
+extern PtPtr pX;
+extern PtPtr pY;
+
+//Liefern Memberpointer auf die jeweiligen Groessen.
+#define pFIXPOS  ( bVarHeight ? pX : pY )
+#define pFIXSIZE ( bVarHeight ? pWidth : pHeight )
+#define pVARPOS  ( bVarHeight ? pY : pX )
+#define pVARSIZE ( bVarHeight ? pHeight : pWidth )
+
+class SwLayoutFrm;
+class SwRootFrm;
+class SwPageFrm;
+class SwFlyFrm;
+class SwSectionFrm;
+class SdrObject;
+class SwDrawContact;
+class SwFtnFrm;
+class SwFtnBossFrm;
+class SwTabFrm;
+class SwFlowFrm;
+class SwCntntFrm;
+class SfxPoolItem;
+class SwAttrSet;
+class ViewShell;
+class Brush;
+class Color;
+class SwBorderAttrs;
+class Sw3FrameIo;
+class SwCache;
+class SvxBrushItem;
+class SwTxtFtn;
+struct SwPosition;
+struct SwCrsrMoveState;
+
+//Jeder FrmTyp findet sich hier in einem Bit wieder.
+//Die Bits muessen so gesetzt werden, dass mit einer Maskierung festgestellt
+//werden kann was fuer ein FrmTyp eine Instanz ist _und_ von welchen Klassen
+//sie abgeleitet ist.
+//Der Frm hat in der Basisklasse einen Member der von den CToren der
+//einzelnen Frms entsprechend gesetzt werden muss.
+#define FRM_ROOT        0x0001
+#define FRM_PAGE        0x0002
+#define FRM_COLUMN      0x0004
+#define FRM_HEADER      0x0008
+#define FRM_FOOTER      0x0010
+#define FRM_FTNCONT     0x0020
+#define FRM_FTN         0x0040
+#define FRM_BODY        0x0080
+#define FRM_FLY         0x0100
+#define FRM_SECTION     0x0200
+#define FRM_UNUSED      0x0400
+#define FRM_TAB         0x0800
+#define FRM_ROW         0x1000
+#define FRM_CELL        0x2000
+#define FRM_TXT         0x4000
+#define FRM_NOTXT       0x8000
+
+//Fuer den internen Gebrauch ein paar gebraeuchliche Verknuepfungen.
+#define FRM_LAYOUT      0x3FFF
+#define FRM_CNTNT       0xC000
+#define FRM_FTNBOSS     0x0006
+
+        //Weils so schon ist das ganze als Bitfeld....
+//0000 0000 0000 0001   ROOT
+//0000 0000 0000 0010   PAGE
+//0000 0000 0000 0100   COLUMN
+//0000 0000 0000 1000   HEADER
+//0000 0000 0001 0000   FOOTER
+//0000 0000 0010 0000   FTNCONT
+//0000 0000 0100 0000   FTN
+//0000 0000 1000 0000   BODY
+//0000 0001 0000 0000   FLY
+//0000 0010 0000 0000   SECTION
+//0000 0100 0000 0000   UNUSED
+//0000 1000 0000 0000   TAB
+//0001 0000 0000 0000   ROW
+//0010 0000 0000 0000   CELL
+//0100 0000 0000 0000   TXT
+//1000 0000 0000 0000   NOTXT
+
+//fuer Prepare() zur Benachrichtigung des Inhaltes durch das Layout auf
+//dem kurzen Dienstweg.
+//Der Inhalt sorgt dafuer, dass beim naechsten Aufruf von ::Format() das
+//minimal notwendige berechnet wird.
+enum PrepareHint
+{
+    PREP_BEGIN,             //BEGIN
+    PREP_CLEAR = PREP_BEGIN,//Komplett neuformatieren.
+    PREP_WIDOWS_ORPHANS,    //Nur Witwen- und Waisen-Regelung pruefen und ggf.
+                            //Aufspalten.
+    PREP_FIXSIZE_CHG,       //Die FixSize hat sich veraendert.
+    PREP_FOLLOW_FOLLOWS,    //Follow ist jetzt moeglicherweise direkter
+                            //Nachbar.
+    PREP_ADJUST_FRM,        //Groesse per Grow/Shrink Ausrichten ohne zu
+                            //Formatieren.
+    PREP_FLY_CHGD,          //Ein FlyFrm hat sich (Groesse) veraendert.
+    PREP_FLY_ATTR_CHG,      //Ein FlyFrm hat seine Attribute veraendert
+                            //(z.B. Umlauf)
+    PREP_FLY_ARRIVE,        //Ein FlyFrm ueberlappt den Bereich jetzt neu.
+    PREP_FLY_LEAVE,         //Ein FlyFrm hat den Bereich verlassen.
+    PREP_FTN,               //Fussnoten-Invalidierung
+    PREP_POS_CHGD,          //Position des Frm hat sich verandert
+                            //(Zum Fly-Umbruch pruefen). Im void* des Prepare()
+                            //wird ein BOOL& uebergeben, dieser zeigt mit TRUE,
+                            //dass ein Format ausgefuehrt wurde.
+    PREP_UL_SPACE,          //UL-Space hat sich veraendert, TxtFrms muessen
+                            //den Zeilenabstand neu kalkulieren.
+    PREP_MUST_FIT,          //Frm passen machen (aufspalten) auch wenn die
+                            //Attribute es nicht erlauben (z.B. zusammenhalten).
+    PREP_WIDOWS,            // Ein Follow stellt fest, dass in ihm die Orphans-
+                            // regel zuschlaegt und verschickt an seinen
+                            // Vorgaenger (Master/Follow) ein PREP_WIDOWS
+    PREP_QUOVADIS,          // Wenn eine Fussnote _zwischen_ zwei Absaetzen
+                            // aufgespalten werden muss, dann muss der
+                            // letzte auf der Seite noch ein QUOVADIS bekommen
+                            // damit er den Text hineinformatiert.
+    PREP_BOSS_CHGD,         // Wenn ein Frm die Spalte/Seite wechselt, wird dieses
+                            // Zusatzprepare zum POS_CHGD im MoveFwd/Bwd
+                            // verschickt (Ftn-Nummern joinen etc.)
+                            // Die Richtung wird ueber pVoid mitgeteilt:
+                            //     MoveFwd: pVoid == 0
+                            //     MoveBwd: pVoid == pOldPage
+    PREP_SWAP,              //Grafiken Swappen, fuer Grafiken im sichtbaren
+                            //Bereich.
+    PREP_REGISTER,          //Registerhaltige Frames invalidieren
+    PREP_FTN_GONE,          //Ein Follow verliert eine Fussnote, ggf. kann seine erste
+                            //Zeile hochrutschen
+    PREP_MOVEFTN,           //eine Fussnote wechselt die Seite, der Inhalt bekommt
+                            //zunaechst eine Hoehe von Null, damit nicht zuviel
+                            //Unruhe entsteht. Beim Formatieren prueft er, ob er
+                            //ueberhaupt passt und wechselt ggf. unbemerkt wieder
+                            //die Seite.
+    PREP_ERGOSUM,           //wg. Bewegung in FtnFrms QuoVadis/ErgoSum pruefen
+    PREP_END                //END
+};
+
+//Fuer GetNextLeaf/GetPrevLeaf.
+enum MakePageType
+{
+    MAKEPAGE_NONE,      //Keine Seite bzw. Fussnote anlegen
+    MAKEPAGE_APPEND,    //Nur ggf. Seite anhaengen
+    MAKEPAGE_INSERT,    //Seite ggf. anhaengen oder einfuegen.
+    MAKEPAGE_FTN        //Fussnote ggf. einfuegen.
+};
+
+typedef SdrObject* SdrObjectPtr;
+SV_DECL_PTRARR(SwDrawObjs,SdrObjectPtr,1,1);
+
+class SwFrm: public SwClient
+{
+    //Der verkappte Frm
+    friend class SwFlowFrm;
+    friend class SwLayoutFrm;       // Sw3FrameIo: fuer pNext, pPrev
+    friend class SwLooping;         // LoopControlling  (layouter.cxx)
+
+        //Hebt die Lower waehrend eines Spaltenumbaus auf.
+    friend SwFrm *SaveCntnt( SwLayoutFrm *, SwFrm* pStart = NULL );
+    friend void   RestoreCntnt( SwFrm *, SwLayoutFrm *, SwFrm *pSibling );
+
+    //Checkt ob sich beim MakePos die Pos des Frm aendert oder nicht
+    //layact.cxx
+    friend BOOL CheckPos( SwFrm *pFrm );
+
+    //entfernt leere SwSectionFrms aus einer Kette
+    friend SwFrm* SwClearDummies( SwFrm* pFrm );
+
+        //Zum validieren eines unsinnig invalidierten in SwCntntFrm::MakeAll
+    friend void ValidateSz( SwFrm *pFrm );
+        // Implementiert in text/txtftn.cxx, verhindert Ftn-Oszillation
+    friend void ValidateTxt( SwFrm *pFrm );
+
+//  friend void CalcAnchorAndKeep( SwFlyFrm * );
+
+    friend void MakeNxt( SwFrm *pFrm, SwFrm *pNxt );
+
+    //Cache fuer (Umrandungs-)Attribute.
+    static SwCache *pCache;
+
+#ifndef PRODUCT
+    //Nur zu Debugging Zwecken! eindeutige Nummerierung aller Frames,
+    //verwaltet in den CToren.
+    static USHORT nLastFrmId;
+    const  USHORT nFrmId;
+#endif
+
+    SwLayoutFrm *pUpper;
+    SwFrm       *pNext;
+    SwFrm       *pPrev;
+
+        //Schatten und Umrandung painten
+    void PaintShadow( const SwRect&, SwRect&, const SwPageFrm *,
+                      const SwBorderAttrs& ) const;
+    SwFrm *_FindNext();
+    SwFrm *_FindPrev();
+    SwCntntFrm *_FindNextCnt();
+
+    void _UpdateAttr( SfxPoolItem*, SfxPoolItem*, BYTE & );
+    SwFrm* _GetIndPrev();
+    SwFrm* _GetIndNext();
+
+    SwFrm( SwFrm & );       //Kopieren ist nicht erlaubt.
+protected:
+    SwDrawObjs *pDrawObjs;  //Hier haengen die DrawObjs, kann 0 sein
+
+    SwRect  aFrm;   //Absolute Dokumentposition und groesse des Frm
+    SwRect  aPrt;   //Position der PrtArea rel zum Frm und groesse der PrtArea
+
+    USHORT  nType;  //Was bin ich fuer ein Perverser?
+
+    BOOL bValidPos:         1;
+    BOOL bValidPrtArea:     1;
+    BOOL bValidSize:        1;
+    BOOL bValidLineNum:     1;
+    BOOL bFixHeight:        1;
+    BOOL bFixWidth:         1;
+    BOOL bCompletePaint:    1;  //Frame wird ganz gepaintet wenn TRUE, auch
+                                //wenn der Inhalt nur teilw. veraendert ist;
+                                //Bei CntntFrms wird ausschliesslich wenn TRUE
+                                //der Border (von Action) gemalt.
+    BOOL bRetouche:         1;  //Der Frame ist fuer Retusche verantwortlich
+                                //wenn TRUE.
+public:
+    BOOL bVarHeight:        1;  //Variable groesse ist die Hoehe wenn TRUE.
+protected:
+    BOOL bInfInvalid:       1;  //InfoFlags sind Invalid.
+    BOOL bInfBody:          1;  //Frm steht im DokumentBody.
+    BOOL bInfTab:           1;  //Frm steht in einer Tabelle.
+    BOOL bInfFly:           1;  //Frm steht in einem Fly.
+    BOOL bInfFtn:           1;  //Frm steht in einer Fussnote.
+    BOOL bInfSct:           1;  //Frm steht in einem Bereich.
+    BOOL bColLocked:        1;  //Grow/Shrink sperren bei spaltigen Section-
+                                //oder Fly-Frames, wird im Format gesetzt
+
+    void ColLock()      { bColLocked = TRUE; }
+    void ColUnlock()    { bColLocked = FALSE; }
+
+    SwPageFrm *InsertPage( SwPageFrm *pSibling, BOOL bFtn );
+    void PrepareMake();
+    void OptPrepareMake();
+    void MakePos();
+    virtual void MakeAll() = 0;
+        //Adjustierung der Frames einer Seite
+    SwTwips AdjustNeighbourhood( SwTwips nDiff, BOOL bTst = FALSE );
+
+
+        //Aendern nur die Framesize, nicht die PrtArea-SSize
+    virtual SwTwips ShrinkFrm( SwTwips, const SzPtr,
+                               BOOL bTst = FALSE, BOOL bInfo = FALSE ) = 0;
+    virtual SwTwips GrowFrm  ( SwTwips, const SzPtr,
+                               BOOL bTst = FALSE, BOOL bInfo = FALSE ) = 0;
+
+    SwModify        *GetDep()       { return pRegisteredIn; }
+    const SwModify  *GetDep() const { return pRegisteredIn; }
+
+    SwFrm( SwModify* );
+
+    SwFrm( Sw3FrameIo&, SwLayoutFrm* );
+public:
+    TYPEINFO(); //Bereits in Basisklasse Client drin.
+
+    USHORT GetType() const { return nType; }
+
+    static SwCache &GetCache()                { return *pCache; }
+    static SwCache *GetCachePtr()             { return pCache;  }
+    static void     SetCache( SwCache *pNew ) { pCache = pNew;  }
+
+    virtual void Store( Sw3FrameIo& ) const;
+
+        //Aendern die PrtArea-SSize und die FrmSize.
+    SwTwips Shrink( SwTwips, const SzPtr,
+                    BOOL bTst = FALSE, BOOL bInfo = FALSE );
+    SwTwips Grow  ( SwTwips, const SzPtr,
+                    BOOL bTst = FALSE, BOOL bInfo = FALSE );
+
+
+    //Wir brauchen unterschiedliche Methoden (wg. Performance) fuer das
+    //Einfuegenin den Layout Baum:
+
+    //Einfuegen vor pBehind  oder am Ende der Kette unter pUpper
+    void InsertBefore( SwLayoutFrm* pParent, SwFrm* pBehind );
+    //Einfuegen hinter pBefore oder am Anfang der Kette unter pUpper
+    void InsertBehind( SwLayoutFrm *pParent, SwFrm *pBefore );
+    //Einfuegen vor pBehind oder am Ende der Kette, unter Beruecksichtigung
+    //der Geschwister von pSct
+    void InsertGroupBefore( SwFrm* pParent, SwFrm* pWhere, SwFrm* pSct );
+    void Remove();
+
+    //For internal use only; wer es anders macht wird
+    //in einen Sack gesteckt und muss zwei Tage drin hocken bleiben.
+    //Fuert Spezialbehandlung fuer _Get[Next|Prev]Leaf() durch (Tabellen).
+    SwLayoutFrm *GetLeaf( MakePageType eMakePage, BOOL bFwd );
+    SwLayoutFrm *GetNextLeaf   ( MakePageType eMakePage );
+    SwLayoutFrm *GetNextFtnLeaf( MakePageType eMakePage );
+    SwLayoutFrm *GetNextSctLeaf( MakePageType eMakePage );
+    SwLayoutFrm *GetPrevLeaf   ( MakePageType eMakeFtn = MAKEPAGE_FTN );
+    SwLayoutFrm *GetPrevFtnLeaf( MakePageType eMakeFtn = MAKEPAGE_FTN );
+    SwLayoutFrm *GetPrevSctLeaf( MakePageType eMakeFtn = MAKEPAGE_FTN );
+    const SwLayoutFrm *GetLeaf ( MakePageType eMakePage, BOOL bFwd,
+                                 const SwFrm *pAnch ) const;
+    BOOL WrongPageDesc( SwPageFrm* pNew );
+
+    void AppendDrawObj( SwDrawContact *pObj );
+    void RemoveDrawObj( SwDrawContact *pToRemove );
+
+    //Arbeiten mit der Kette der FlyFrms
+    void  AppendFly( SwFlyFrm *pNew );
+    void  RemoveFly( SwFlyFrm *pToRemove );
+    const SwDrawObjs *GetDrawObjs() const { return pDrawObjs; }
+          SwDrawObjs *GetDrawObjs()       { return pDrawObjs; }
+    void  CalcFlys( BOOL bInvaPosOnly );
+
+    virtual void PaintBorder( const SwRect&, const SwPageFrm *pPage,
+                              const SwBorderAttrs & ) const;
+    void PaintBaBo( const SwRect&, const SwPageFrm *pPage = 0,
+                    const BOOL bLowerBorder = FALSE ) const;
+    void PaintBackground( const SwRect&, const SwPageFrm *pPage,
+                          const SwBorderAttrs &,
+                          const BOOL bLowerMode = FALSE,
+                          const BOOL bLowerBorder = FALSE ) const;
+    void PaintBorderLine( const SwRect&, const SwRect&, const SwPageFrm*,
+                          const Color *pColor ) const;
+
+    //Retouche, nicht im Bereich des uebergebenen Rect!
+    void Retouche( const SwPageFrm *pPage, const SwRect &rRect ) const;
+
+    BOOL GetBackgroundBrush( const SvxBrushItem*& rpBrush,
+                             const Color*& rpColor,
+                             SwRect &rOrigRect,
+                             BOOL bLowerMode ) const;
+
+    inline void SetCompletePaint() const;
+    inline void ResetCompletePaint() const;
+    inline BOOL IsCompletePaint() const { return bCompletePaint; }
+
+    inline void SetRetouche() const;
+    inline void ResetRetouche() const;
+    inline BOOL IsRetouche() const { return bRetouche; }
+
+    void SetInfFlags();                 //Setzen der InfoFlags
+    inline void InvalidateInfFlags() { bInfInvalid = TRUE; }
+    inline BOOL IsInDocBody() const;    //Benutzen die InfoFlags.
+    inline BOOL IsInFtn() const;        //ggf. werden die Flags ermittelt.
+    inline BOOL IsInTab() const;
+    inline BOOL IsInFly() const;
+    inline BOOL IsInSct() const;
+
+    BOOL IsMoveable() const;
+
+    //Ist es fuer den (Txt)Frm in der aktuellen Umgebung erlaubt eine
+    //Fussnote einzufuegen (nicht z.B. in wiederholten TabellenHeadlines).
+    BOOL IsFtnAllowed() const;
+
+    virtual void  Modify( SfxPoolItem*, SfxPoolItem* );
+    virtual void  Format( const SwBorderAttrs *pAttrs = 0 );
+
+    void ReinitializeFrmSizeAttrFlags();
+
+    const SwAttrSet *GetAttrSet() const;
+          SwAttrSet *GetAttrSet();
+    void             GetAttrSet( SwAttrSet* );
+
+    BOOL HasFixSize( const SzPtr ) const;
+
+    //Kann 0 liefern, pruefen auch ob die Shell zum richtigen Dokument
+    //gehoert. Impl in frmsh.hxx
+    inline ViewShell *GetShell() const;
+
+    //Prueft alle Seiten ab der Uebergebenen und korrigiert ggf.
+    static void CheckPageDescs( SwPageFrm *pStart, BOOL bNotifyFields = TRUE );
+
+        //Koennen 0 liefern, einmal const einmal nicht
+    SwFrm               *GetNext()  { return pNext; }
+    SwFrm               *GetPrev()  { return pPrev; }
+    SwLayoutFrm         *GetUpper() { return pUpper; }
+    SwRootFrm           *FindRootFrm();
+    SwPageFrm           *FindPageFrm();
+    SwFrm               *FindColFrm();
+    SwFtnBossFrm        *FindFtnBossFrm( BOOL bFootnotes = FALSE );
+    SwTabFrm            *ImplFindTabFrm();
+    SwFtnFrm            *ImplFindFtnFrm();
+    SwFlyFrm            *ImplFindFlyFrm();
+    SwSectionFrm        *ImplFindSctFrm();
+    SwSectionFrm        *ImplFindTopSctFrm();
+    SwFrm               *FindFooterOrHeader();
+    SwFrm               *GetLower();
+    const SwFrm         *GetNext()  const { return pNext; }
+    const SwFrm         *GetPrev()  const { return pPrev; }
+    const SwLayoutFrm   *GetUpper() const { return pUpper; }
+    inline SwTabFrm     *FindTabFrm();
+    inline SwFtnFrm     *FindFtnFrm();
+    inline SwFlyFrm     *FindFlyFrm();
+    inline SwSectionFrm *FindSctFrm();
+    inline SwSectionFrm *FindTopSctFrm();
+    inline SwFrm        *FindNext();
+    inline SwCntntFrm   *FindNextCnt();
+    inline SwFrm        *FindPrev();
+    inline const SwPageFrm *FindPageFrm() const;
+    inline const SwRootFrm *FindRootFrm() const;
+    inline const SwFtnBossFrm *FindFtnBossFrm( BOOL bFtn = FALSE ) const;
+    inline const SwFrm     *FindColFrm() const;
+    inline const SwFrm     *FindFooterOrHeader() const;
+    inline const SwTabFrm  *FindTabFrm() const;
+    inline const SwFtnFrm  *FindFtnFrm() const;
+    inline const SwFlyFrm  *FindFlyFrm() const;
+    inline const SwSectionFrm *FindSctFrm() const;
+    inline const SwSectionFrm *FindTopSctFrm() const;
+    inline const SwFrm     *FindNext() const;
+    inline const SwCntntFrm *FindNextCnt() const;
+    inline const SwFrm     *FindPrev() const;
+           const SwFrm     *GetLower()  const;
+
+    SwFrm* GetIndPrev()
+        { return ( pPrev || !IsInSct() ) ? pPrev : _GetIndPrev(); }
+    const SwFrm* GetIndPrev() const { return ((SwFrm*)this)->GetIndPrev(); }
+    SwFrm* GetIndNext()
+        { return ( pNext || !IsInSct() ) ? pNext : _GetIndNext(); }
+    const SwFrm* GetIndNext() const { return ((SwFrm*)this)->GetIndNext(); }
+
+    USHORT GetPhyPageNum() const;   //Seitennummer ohne Offset
+    USHORT GetVirtPageNum() const;  //Seitenummer mit Offset
+
+    const  SwLayoutFrm *GetPrevLayoutLeaf() const;
+    const  SwLayoutFrm *GetNextLayoutLeaf() const;
+    inline SwLayoutFrm *GetPrevLayoutLeaf();
+    inline SwLayoutFrm *GetNextLayoutLeaf();
+
+    inline void Calc() const;       //Hier wird ggf. 'Formatiert'
+    inline void OptCalc() const;    //Hier wird zur Optimierung davon ausgegangen,
+                                    //das die Vorgaenger bereits formatiert sind.
+
+    inline Point   GetRelPos() const;
+    const  SwRect &Frm() const { return aFrm; }
+    const  SwRect &Prt() const { return aPrt; }
+
+    // The PaintArea is the area, where content may be displayed.
+    // The margin of the page or the space between columns belongs to her.
+    const SwRect PaintArea() const;
+    // The UnionFrm is the union of frm- and prt-area, normally identical
+    // to the frm-area except the case of negative prt-margins.
+    const SwRect UnionFrm( BOOL bBorder = FALSE ) const;
+
+    //Der Zugriff auf die Member wird hier ausnahmsweiste gestattet,
+    //dies soll aber nicht dazu dienen die Werte wahllos zu veraendern;
+    //es ist nur die einzige Moeglichkeit die Compilerprobleme zu umgehen
+    //(gleiche Methode mal public mal protected).
+    SwRect &Frm() { return aFrm; }
+    SwRect &Prt() { return aPrt; }
+
+    virtual void ChgSize( const Size& aNewSize );
+
+    virtual void Cut() = 0;
+    virtual void Paste( SwFrm* pParent, SwFrm* pSibling = 0 ) = 0;
+
+    void ValidateLineNum() { bValidLineNum = TRUE; }
+
+    BOOL GetValidPosFlag()    const { return bValidPos; }
+    BOOL GetValidPrtAreaFlag()const { return bValidPrtArea; }
+    BOOL GetValidSizeFlag()   const { return bValidSize; }
+    BOOL GetValidLineNumFlag()const { return bValidLineNum; }
+    BOOL IsValid() const { return bValidPos && bValidSize && bValidPrtArea; }
+
+        //Invalideren nur den Frm
+    void _InvalidateSize()      { bValidSize = FALSE; }
+    void _InvalidatePrt()       { bValidPrtArea = FALSE; }
+    void _InvalidatePos()       { bValidPos = FALSE; }
+    void _InvalidateLineNum()   { bValidLineNum = FALSE; }
+    void _InvalidateAll()       { bValidSize = bValidPrtArea = bValidPos = FALSE; }
+
+    //Benachrichtigen gleich die Seite mit.
+    inline void InvalidateSize();
+    inline void InvalidatePrt();
+    inline void InvalidatePos();
+    inline void InvalidateLineNum();
+    inline void InvalidateAll();
+    void ImplInvalidateSize();
+    void ImplInvalidatePrt();
+    void ImplInvalidatePos();
+    void ImplInvalidateLineNum();
+
+    inline void InvalidateNextPos( BOOL bNoFtn = FALSE );
+    void ImplInvalidateNextPos( BOOL bNoFtn = FALSE );
+    void InvalidatePage( const SwPageFrm *pPage = 0 ) const;
+
+    virtual BOOL    GetCrsrOfst( SwPosition *, Point&,
+                                 const SwCrsrMoveState* = 0 ) const;
+    virtual BOOL    GetCharRect( SwRect &, const SwPosition&,
+                                 SwCrsrMoveState* = 0 ) const;
+    virtual void    Paint( const SwRect& ) const;
+
+    // der "kurze Dienstweg" zwischen den Frames und der Formatierung.
+    // Wer den void* falsch Casted ist selbst schuld!
+    // Auf jedenfall muss der void* auf 0 geprueft werden.
+    virtual void Prepare( const PrepareHint ePrep = PREP_CLEAR,
+                          const void *pVoid = 0, BOOL bNotify = TRUE );
+
+    //TRUE wenn's die richtige Klasse ist, FALSE sonst
+    inline BOOL IsLayoutFrm() const;
+    inline BOOL IsRootFrm() const;
+    inline BOOL IsPageFrm() const;
+    inline BOOL IsColumnFrm() const;
+    inline BOOL IsFtnBossFrm() const; // Fussnotenbosse sind PageFrms und ColumnFrms
+    inline BOOL IsHeaderFrm() const;
+    inline BOOL IsFooterFrm() const;
+    inline BOOL IsFtnContFrm() const;
+    inline BOOL IsFtnFrm() const;
+    inline BOOL IsBodyFrm() const;
+    inline BOOL IsColBodyFrm() const;   // in layfrm.hxx implementiert, BodyFrm unterhalb ColumnFrm
+    inline BOOL IsPageBodyFrm() const;  // in layfrm.hxx implementiert, BodyFrm unterhalb PageFrm
+    inline BOOL IsFlyFrm() const;
+    inline BOOL IsSctFrm() const;
+    inline BOOL IsTabFrm() const;
+    inline BOOL IsRowFrm() const;
+    inline BOOL IsCellFrm() const;
+    inline BOOL IsCntntFrm() const;
+    inline BOOL IsTxtFrm() const;
+    inline BOOL IsNoTxtFrm() const;
+    inline BOOL IsFlowFrm() const;      //Frms deren PrtArea von den Nachbarn
+                                        //abhaengen und die halt im Inhaltsfluss
+                                        //stehen.
+    inline BOOL IsRetoucheFrm() const;  //Frms die Retouchefaehig sind bzw. die
+                                        //u.U. hinter sich Retouchieren muessen.
+
+    void PrepareCrsr();                 //Die CrsrShell darf.
+
+    //Ist der Frm (bzw. die Section in der er steht) geschuetzt?
+    //Auch Fly in Fly in ... und Fussnoten
+    BOOL IsProtected() const;
+
+    BOOL IsColLocked()  const { return bColLocked; }
+
+    virtual ~SwFrm();
+
+#ifndef PRODUCT
+    inline USHORT GetFrmId() const { return nFrmId; }
+    inline USHORT GetLastFrmId() const { return nLastFrmId; }
+#endif
+};
+
+inline BOOL SwFrm::IsInDocBody() const
+{
+    if ( bInfInvalid )
+        ((SwFrm*)this)->SetInfFlags();
+    return bInfBody;
+}
+inline BOOL SwFrm::IsInFtn() const
+{
+    if ( bInfInvalid )
+        ((SwFrm*)this)->SetInfFlags();
+    return bInfFtn;
+}
+inline BOOL SwFrm::IsInTab() const
+{
+    if ( bInfInvalid )
+        ((SwFrm*)this)->SetInfFlags();
+    return bInfTab;
+}
+inline BOOL SwFrm::IsInFly() const
+{
+    if ( bInfInvalid )
+        ((SwFrm*)this)->SetInfFlags();
+    return bInfFly;
+}
+inline BOOL SwFrm::IsInSct() const
+{
+    if ( bInfInvalid )
+        ((SwFrm*)this)->SetInfFlags();
+    return bInfSct;
+}
+
+inline void SwFrm::SetCompletePaint() const
+{
+    ((SwFrm*)this)->bCompletePaint = TRUE;
+}
+inline void SwFrm::ResetCompletePaint() const
+{
+    ((SwFrm*)this)->bCompletePaint = FALSE;
+}
+
+inline void SwFrm::SetRetouche() const
+{
+    ((SwFrm*)this)->bRetouche = TRUE;
+}
+inline void SwFrm::ResetRetouche() const
+{
+    ((SwFrm*)this)->bRetouche = FALSE;
+}
+
+inline SwLayoutFrm *SwFrm::GetPrevLayoutLeaf()
+{
+    return (SwLayoutFrm*)((const SwFrm*)this)->GetPrevLayoutLeaf();
+}
+inline SwLayoutFrm *SwFrm::GetNextLayoutLeaf()
+{
+    return (SwLayoutFrm*)((const SwFrm*)this)->GetNextLayoutLeaf();
+}
+
+inline void SwFrm::InvalidateSize()
+{
+    if ( bValidSize )
+        ImplInvalidateSize();
+}
+inline void SwFrm::InvalidatePrt()
+{
+    if ( bValidPrtArea )
+        ImplInvalidatePrt();
+}
+inline void SwFrm::InvalidatePos()
+{
+    if ( bValidPos )
+        ImplInvalidatePos();
+}
+inline void SwFrm::InvalidateLineNum()
+{
+    if ( bValidLineNum )
+        ImplInvalidateLineNum();
+}
+
+inline void SwFrm::InvalidateAll()
+{
+    if ( bValidPrtArea && bValidSize && bValidPos  )
+        ImplInvalidatePos();
+    bValidPrtArea = bValidSize = bValidPos = FALSE;
+}
+
+inline void SwFrm::InvalidateNextPos( BOOL bNoFtn )
+{
+    if ( pNext )
+        pNext->InvalidatePos();
+#ifndef C30 // vielleicht geht es ja bei C40 ?
+    else
+        ImplInvalidateNextPos( bNoFtn );
+#else
+    if ( !pNext )
+        ImplInvalidateNextPos( bNoFtn );
+#endif
+}
+
+inline void SwFrm::Calc() const
+{
+    if ( !bValidPos || !bValidPrtArea || !bValidSize )
+        ((SwFrm*)this)->PrepareMake();
+}
+inline void SwFrm::OptCalc() const
+{
+    if ( !bValidPos || !bValidPrtArea || !bValidSize )
+        ((SwFrm*)this)->OptPrepareMake();
+}
+
+inline Point SwFrm::GetRelPos() const
+{
+    Point aRet( aFrm.Pos() );
+        //hier wird gecasted, weil die Klasse SwLayoutFrm nur vorward-
+        //declariert ist.
+    aRet -= ((SwFrm*)GetUpper())->Prt().Pos();
+    aRet -= ((SwFrm*)GetUpper())->Frm().Pos();
+    return aRet;
+}
+
+inline const SwPageFrm *SwFrm::FindPageFrm() const
+{
+    return ((SwFrm*)this)->FindPageFrm();
+}
+inline const SwRootFrm *SwFrm::FindRootFrm() const
+{
+    return ((SwFrm*)this)->FindRootFrm();
+}
+inline const SwFrm *SwFrm::FindColFrm() const
+{
+    return ((SwFrm*)this)->FindColFrm();
+}
+inline const SwFrm *SwFrm::FindFooterOrHeader() const
+{
+    return ((SwFrm*)this)->FindFooterOrHeader();
+}
+inline SwTabFrm *SwFrm::FindTabFrm()
+{
+    return IsInTab() ? ImplFindTabFrm() : 0;
+}
+inline const SwFtnBossFrm *SwFrm::FindFtnBossFrm( BOOL bFtn ) const
+{
+    return ((SwFrm*)this)->FindFtnBossFrm( bFtn );
+}
+inline SwFtnFrm *SwFrm::FindFtnFrm()
+{
+    return IsInFtn() ? ImplFindFtnFrm() : 0;
+}
+inline SwFlyFrm *SwFrm::FindFlyFrm()
+{
+    return IsInFly() ? ImplFindFlyFrm() : 0;
+}
+inline SwSectionFrm *SwFrm::FindSctFrm()
+{
+    return IsInSct() ? ImplFindSctFrm() : 0;
+}
+
+inline SwSectionFrm *SwFrm::FindTopSctFrm()
+{
+    return IsInSct() ? ImplFindTopSctFrm() : 0;
+}
+
+inline const SwTabFrm *SwFrm::FindTabFrm() const
+{
+    return IsInTab() ? ((SwFrm*)this)->ImplFindTabFrm() : 0;
+}
+inline const SwFtnFrm *SwFrm::FindFtnFrm() const
+{
+    return IsInFtn() ? ((SwFrm*)this)->ImplFindFtnFrm() : 0;
+}
+inline const SwFlyFrm *SwFrm::FindFlyFrm() const
+{
+    return IsInFly() ? ((SwFrm*)this)->ImplFindFlyFrm() : 0;
+}
+inline const SwSectionFrm *SwFrm::FindSctFrm() const
+{
+    return IsInSct() ? ((SwFrm*)this)->ImplFindSctFrm() : 0;
+}
+inline const SwSectionFrm *SwFrm::FindTopSctFrm() const
+{
+    return IsInSct() ? ((SwFrm*)this)->ImplFindTopSctFrm() : 0;
+}
+inline SwFrm *SwFrm::FindNext()
+{
+    if ( pNext )
+        return pNext;
+    else
+        return _FindNext();
+}
+inline const SwFrm *SwFrm::FindNext() const
+{
+    if ( pNext )
+        return pNext;
+    else
+        return ((SwFrm*)this)->_FindNext();
+}
+inline SwCntntFrm *SwFrm::FindNextCnt()
+{
+    if ( pNext && pNext->IsCntntFrm() )
+        return (SwCntntFrm*)pNext;
+    else
+        return _FindNextCnt();
+}
+inline const SwCntntFrm *SwFrm::FindNextCnt() const
+{
+    if ( pNext && pNext->IsCntntFrm() )
+        return (SwCntntFrm*)pNext;
+    else
+        return ((SwFrm*)this)->_FindNextCnt();
+}
+inline SwFrm *SwFrm::FindPrev()
+{
+    if ( pPrev && !pPrev->IsSctFrm() )
+        return pPrev;
+    else
+        return _FindPrev();
+}
+inline const SwFrm *SwFrm::FindPrev() const
+{
+    if ( pPrev && !pPrev->IsSctFrm() )
+        return pPrev;
+    else
+        return ((SwFrm*)this)->_FindPrev();
+}
+
+inline BOOL SwFrm::IsLayoutFrm() const
+{
+    return nType & FRM_LAYOUT ? TRUE : FALSE;
+}
+inline BOOL SwFrm::IsRootFrm() const
+{
+    return nType == FRM_ROOT;
+}
+inline BOOL SwFrm::IsPageFrm() const
+{
+    return nType == FRM_PAGE;
+}
+inline BOOL SwFrm::IsColumnFrm() const
+{
+    return nType == FRM_COLUMN;
+}
+inline BOOL SwFrm::IsFtnBossFrm() const
+{
+    return nType & FRM_FTNBOSS ? TRUE : FALSE;
+}
+inline BOOL SwFrm::IsHeaderFrm() const
+{
+    return nType == FRM_HEADER;
+}
+inline BOOL SwFrm::IsFooterFrm() const
+{
+    return nType == FRM_FOOTER;
+}
+inline BOOL SwFrm::IsFtnContFrm() const
+{
+    return nType == FRM_FTNCONT;
+}
+inline BOOL SwFrm::IsFtnFrm() const
+{
+    return nType == FRM_FTN;
+}
+inline BOOL SwFrm::IsBodyFrm() const
+{
+    return nType == FRM_BODY;
+}
+inline BOOL SwFrm::IsFlyFrm() const
+{
+    return nType == FRM_FLY;
+}
+inline BOOL SwFrm::IsSctFrm() const
+{
+    return nType == FRM_SECTION;
+}
+inline BOOL SwFrm::IsTabFrm() const
+{
+    return nType == FRM_TAB;
+}
+inline BOOL SwFrm::IsRowFrm() const
+{
+    return nType == FRM_ROW;
+}
+inline BOOL SwFrm::IsCellFrm() const
+{
+    return nType == FRM_CELL;
+}
+inline BOOL SwFrm::IsCntntFrm() const
+{
+    return nType & FRM_CNTNT ? TRUE : FALSE;
+}
+inline BOOL SwFrm::IsTxtFrm() const
+{
+    return nType == FRM_TXT;
+}
+inline BOOL SwFrm::IsNoTxtFrm() const
+{
+    return nType == FRM_NOTXT;
+}
+inline BOOL SwFrm::IsFlowFrm() const
+{
+    return nType & 0xCA00 ? TRUE : FALSE;   //TabFrm, CntntFrm, SectionFrm
+}
+inline BOOL SwFrm::IsRetoucheFrm() const
+{
+    return nType & 0xCA40 ? TRUE : FALSE;   //TabFrm, CntntFrm, SectionFrm, Ftnfrm
+}
+
+#endif
diff --git a/sw/source/core/inc/frminf.hxx b/sw/source/core/inc/frminf.hxx
new file mode 100644
index 000000000000..f5cfb450ad3a
--- /dev/null
+++ b/sw/source/core/inc/frminf.hxx
@@ -0,0 +1,119 @@
+/*************************************************************************
+ *
+ *  $RCSfile: frminf.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:20 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _FRMINF_HXX
+#define _FRMINF_HXX
+
+#include "swtypes.hxx"
+
+class SwTxtFrm;     // SwTxtFrmInfo
+class SwPaM;        // SwTxtFrmInfo
+class SwTxtCursor;  // SwTxtFrmInfo
+
+
+/*************************************************************************
+ *                      class SwTxtFrmInfo
+ *************************************************************************/
+
+class SwTxtFrmInfo
+{
+    const SwTxtFrm *pFrm;
+
+    // Wo beginnt der Text (ohne whitespaces)? (Dokument global !!)
+    SwTwips GetLineStart( const SwTxtCursor &rLine ) const;
+
+public:
+    inline SwTxtFrmInfo( const SwTxtFrm *pFrm ) : pFrm(pFrm) { }
+
+    // Passt der Absatz in eine Zeile?
+    BOOL IsOneLine() const;
+
+    // Ist die Zeile zu X% gefuellt?
+    BOOL IsFilled( const BYTE nPercent ) const;
+
+    // Wo beginnt der Text (ohne whitespaces)? (rel. im Frame !!)
+    SwTwips GetLineStart() const;
+
+    //returne die mittel Position des n. Charakters
+    SwTwips GetCharPos( xub_StrLen nChar, BOOL bCenter = TRUE ) const;
+
+    // Sammelt die whitespaces am Zeilenbeginn und -ende im Pam
+    void GetSpaces( SwPaM &rPam, BOOL bWithLineBreak ) const;
+
+    // Ist an der ersten Textposition ein Bullet/Symbol etc?
+    BOOL IsBullet( xub_StrLen nTxtPos ) const;
+
+    // Ermittelt Erstzeileneinzug
+    SwTwips GetFirstIndent() const;
+
+    // setze und erfrage den Frame;
+    const SwTxtFrm* GetFrm() const { return pFrm; }
+    SwTxtFrmInfo& SetFrm( const SwTxtFrm* pNew )
+        { pFrm = pNew; return *this; }
+
+    // liegt eine Gegenueberstellung vor? (returnt Pos im Frame)
+    USHORT GetBigIndent( xub_StrLen& rFndPos,
+                        const SwTxtFrm *pNextFrm = 0 ) const;
+};
+
+
+
+#endif
+
diff --git a/sw/source/core/inc/frmtool.hxx b/sw/source/core/inc/frmtool.hxx
new file mode 100644
index 000000000000..1f1783b19d8c
--- /dev/null
+++ b/sw/source/core/inc/frmtool.hxx
@@ -0,0 +1,457 @@
+/*************************************************************************
+ *
+ *  $RCSfile: frmtool.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:20 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _FRMTOOL_HXX
+#define _FRMTOOL_HXX
+
+#include "swtypes.hxx"
+#include "layfrm.hxx"
+#include "frmatr.hxx"
+#include "swcache.hxx"
+
+class SwPageFrm;
+class SwFlyFrm;
+class SwCntntFrm;
+class SwFtnContFrm;
+class SwDoc;
+class SwAttrSet;
+class SdrObject;
+class BigInt;
+class SvxBrushItem;
+class SdrMarkList;
+class SwNodeIndex;
+class OutputDevice;
+class SwPageDesc;
+class SwCrsrShell;
+
+#if defined(MSC)
+#define MA_FASTCALL __fastcall
+#else
+#define MA_FASTCALL
+#endif
+
+#define WEIT_WECH       LONG_MAX - 20000        //Initale Position der Flys.
+#define BROWSE_HEIGHT   56700L * 10L                //10 Meter
+
+#define GRFNUM_NO 0
+#define GRFNUM_YES 1
+#define GRFNUM_REPLACE 2
+
+//Painten des Hintergrunds. Mit Brush oder Graphic.
+void MA_FASTCALL DrawGraphic( const SvxBrushItem *, OutputDevice *,
+      const SwRect &rOrg, const SwRect &rOut, const BYTE nGrfNum = GRFNUM_NO );
+
+//Fly besorgen, wenn keine List hineingereicht wird, wir die der aktuellen
+//Shell benutzt.
+//Implementierung in feshview.cxx
+SwFlyFrm *GetFlyFromMarked( const SdrMarkList *pLst, ViewShell *pSh );
+
+//Nicht gleich die math.lib anziehen.
+ULONG MA_FASTCALL SqRt( BigInt nX );
+
+//CntntNodes besorgen, CntntFrms erzeugen und in den LayFrm haengen.
+void MA_FASTCALL _InsertCnt( SwLayoutFrm *pLay, SwDoc *pDoc, ULONG nIndex,
+                 BOOL bPages = FALSE, ULONG nEndIndex = 0,
+                 SwFrm *pPrv = 0 );
+
+//Erzeugen der Frames fuer einen bestimmten Bereich, verwendet _InsertCnt
+void MakeFrms( SwDoc *pDoc, const SwNodeIndex &rSttIdx,
+                            const SwNodeIndex &rEndIdx );
+
+//Um z.B. fuer Tabelleheadlines das Erzeugen der Flys in _InsertCnt zu unterbinden.
+extern FASTBOOL bDontCreateObjects;
+
+//Fuer FlyCnts, siehe SwFlyAtCntFrm::MakeAll()
+extern FASTBOOL bSetCompletePaintOnInvalidate;
+
+//Rechteck fuer BorderPaint ausdehen/wieder schrumpfen.
+void MA_FASTCALL SizeBorderRect( SwRect &rRect );
+void MA_FASTCALL InvertSizeBorderRect( SwRect &rRect, ViewShell *pSh );
+
+//Fuer Tabelleneinstellung per Tastatur.
+long MA_FASTCALL CalcRowRstHeight( SwLayoutFrm *pRow );
+long MA_FASTCALL CalcHeightWidthFlys( const SwFrm *pFrm );  //MA_FLY_HEIGHT
+
+//Neue Seite einsetzen
+SwPageFrm * MA_FASTCALL InsertNewPage( SwPageDesc &rDesc, SwFrm *pUpper,
+                          BOOL bOdd, BOOL bFtn,
+                          SwFrm *pSibling );
+
+//Flys bei der Seite anmelden.
+void RegistFlys( SwPageFrm*, const SwLayoutFrm* );
+
+//Benachrichtung des Fly Hintergrundes wenn Notwendig.
+void Notify( SwFlyFrm *pFly, SwPageFrm *pOld, const SwRect &rOld );
+
+void Notify_Background( SdrObject *pObj, SwPageFrm *pPage, const SwRect& rRect,
+                        const PrepareHint eHint, const BOOL bInva );
+
+const SwFrm* GetVirtualUpper( const SwFrm* pFrm, const Point& rPos );
+
+BOOL Is_Lower_Of( const SwFrm *pCurrFrm, const SdrObject* pObj );
+
+const SwFrm *FindKontext( const SwFrm *pFrm, USHORT nAdditionalKontextTyp );
+
+BOOL IsFrmInSameKontext( const SwFrm *pInnerFrm, const SwFrm *pFrm );
+
+void MA_ParkCrsr( SwPageDesc *pDesc, SwCrsrShell &rSh );
+
+const SwFrm * MA_FASTCALL FindPage( const SwRect &rRect, const SwFrm *pPage );
+
+// JP 07.05.98: wird von SwCntntNode::GetFrm und von SwFlyFrm::GetFrm
+//              gerufen
+SwFrm* GetFrmOfModify( SwModify&, USHORT nFrmType, const Point* = 0,
+                        const SwPosition *pPos = 0,
+                        const BOOL bCalcFrm = FALSE );
+
+//Sollen ExtraDaten (Reline-Strich, Zeilennummern) gepaintet werden?
+FASTBOOL IsExtraData( const SwDoc *pDoc );
+
+
+//Die Notify-Klassen merken sich im CTor die aktuellen Groessen und fuehren
+//im DTor ggf. die notwendigen Benachrichtigungen durch.
+
+class SwFrmNotify
+{
+protected:
+    SwFrm *pFrm;
+    const SwRect aFrm;
+    const SwRect aPrt;
+    FASTBOOL     bHadFollow;
+    FASTBOOL     bInvaKeep;
+public:
+    SwFrmNotify( SwFrm *pFrm );
+    ~SwFrmNotify();
+
+    const SwRect &Frm() const { return aFrm; }
+    const SwRect &Prt() const { return aPrt; }
+    void SetInvaKeep() { bInvaKeep = TRUE; }
+};
+
+class SwLayNotify : public SwFrmNotify
+{
+    SwTwips  nHeightOfst;
+    SwTwips  nWidthOfst;
+    FASTBOOL bLowersComplete;
+
+    SwLayoutFrm *GetLay() { return (SwLayoutFrm*)pFrm; }
+public:
+    SwLayNotify( SwLayoutFrm *pLayFrm );
+    ~SwLayNotify();
+
+    void AddHeightOfst     ( SwTwips nAdd ) { nHeightOfst += nAdd; }
+    void AddWidthOfst      ( SwTwips nAdd ) { nHeightOfst += nAdd; }
+    void SubtractHeightOfst( SwTwips nSub ) { nWidthOfst -= nSub; }
+    void SubtractWidthOfst ( SwTwips nSub ) { nWidthOfst -= nSub; }
+    SwTwips GetHeightOfst() const { return nHeightOfst; }
+    SwTwips GetWidthOfst()  const { return nWidthOfst; }
+    void    ResetHeightOfst() { nHeightOfst = 0; }
+    void    ResetWidthOfst()  { nWidthOfst = 0; }
+
+    void SetLowersComplete( FASTBOOL b ) { bLowersComplete = b; }
+    FASTBOOL IsLowersComplete()          { return bLowersComplete; }
+};
+
+class SwFlyNotify : public SwLayNotify
+{
+    SwPageFrm *pOldPage;
+    const SwRect aFrmAndSpace;
+    SwFlyFrm *GetFly() { return (SwFlyFrm*)pFrm; }
+public:
+    SwFlyNotify( SwFlyFrm *pFlyFrm );
+    ~SwFlyNotify();
+
+    SwPageFrm *GetOldPage() const { return pOldPage; }
+};
+
+class SwCntntNotify : public SwFrmNotify
+{
+    SwCntntFrm *GetCnt() { return (SwCntntFrm*)pFrm; }
+public:
+    SwCntntNotify( SwCntntFrm *pCntFrm );
+    ~SwCntntNotify();
+};
+
+//SwBorderAttrs kapselt die Berechnung fuer die Randattribute inclusive
+//Umrandung. Die Attribute und die errechneten Werte werden gecached.
+//Neu: Die gesammte Klasse wird gecached.
+
+//!!!Achtung: Wenn weitere Attribute gecached werden muss unbedingt die
+//Methode Modify::Modify mitgepflegt werden!!!
+
+class SwBorderAttrs : public SwCacheObj
+{
+    const SwAttrSet      &rAttrSet;
+    const SvxULSpaceItem &rUL;
+    const SvxLRSpaceItem &rLR;
+    const SvxBoxItem     &rBox;
+    const SvxShadowItem  &rShadow;
+    const Size            aFrmSize;     //Die FrmSize
+    long nRight;
+
+    BOOL bBorderDist    :1;             //Ist's ein Frm der auch ohne Linie
+                                        //einen Abstand haben kann?
+
+    //Mit den Folgenden Bools werden die gecache'ten Werte fuer UNgueltig
+    //erklaert - bis sie einmal berechnet wurden.
+    BOOL bTopLine       :1;
+    BOOL bBottomLine    :1;
+    BOOL bLeftLine      :1;
+    BOOL bRightLine     :1;
+    BOOL bTop           :1;
+    BOOL bBottom        :1;
+    BOOL bRight         :1;
+    BOOL bLine          :1;
+
+    BOOL bIsLine        :1; //Umrandung an mind. einer Kante?
+
+    BOOL bCacheGetLine        :1; //GetTopLine(), GetBottomLine() cachen?
+    BOOL bCachedGetTopLine    :1; //GetTopLine() gecached?
+    BOOL bCachedGetBottomLine :1; //GetTopLine() gecached?
+
+    //Die gecache'ten Werte, undefiniert bis sie einmal berechnet wurden.
+    USHORT nTopLine,
+           nBottomLine,
+           nLeftLine,
+           nRightLine,
+           nTop,
+           nBottom,
+           nGetTopLine,
+           nGetBottomLine;
+
+    //Nur die Lines + Shadow errechnen.
+    void _CalcTopLine();
+    void _CalcBottomLine();
+    void _CalcLeftLine();
+    void _CalcRightLine();
+
+    //Lines + Shadow + Abstaende
+    void _CalcTop();
+    void _CalcBottom();
+    void _CalcRight();
+
+    void _IsLine();
+
+    void _GetTopLine   ( const SwFrm *pFrm );
+    void _GetBottomLine( const SwFrm *pFrm );
+
+     //Rechte und linke Linie sowie LRSpace gleich?
+    BOOL CmpLeftRight( const SwBorderAttrs &rAttrs, const SwFrm *pCaller,
+                       const SwFrm *pCmp ) const;
+
+public:
+    DECL_FIXEDMEMPOOL_NEWDEL(SwBorderAttrs)
+
+    SwBorderAttrs( const SwModify *pOwner, const SwFrm *pConstructor );
+    ~SwBorderAttrs();
+
+    inline const SwAttrSet      &GetAttrSet() const { return rAttrSet;  }
+    inline const SvxULSpaceItem &GetULSpace() const { return rUL;       }
+    inline const SvxLRSpaceItem &GetLRSpace() const { return rLR;       }
+    inline const SvxBoxItem     &GetBox()     const { return rBox;      }
+    inline const SvxShadowItem  &GetShadow()  const { return rShadow;   }
+
+    inline USHORT CalcTopLine() const;
+    inline USHORT CalcBottomLine() const;
+    inline USHORT CalcLeftLine() const;
+    inline USHORT CalcRightLine() const;
+    inline USHORT CalcTop() const;
+    inline USHORT CalcBottom() const;
+           long CalcLeft( const SwFrm *pCaller ) const;
+    inline long CalcRight() const;
+
+    inline BOOL IsLine() const;
+
+    inline const Size &GetSize()     const { return aFrmSize; }
+
+    inline BOOL IsBorderDist() const { return bBorderDist; }
+
+    //Sollen obere bzw. untere Umrandung fuer den Frm ausgewertet werden?
+    inline USHORT GetTopLine   ( const SwFrm *pFrm ) const;
+    inline USHORT GetBottomLine( const SwFrm *pFrm ) const;
+    inline void   SetGetCacheLine( BOOL bNew ) const;
+};
+
+class SwBorderAttrAccess : public SwCacheAccess
+{
+    const SwFrm *pConstructor;      //opt: Zur weitergabe an SwBorderAttrs
+protected:
+    virtual SwCacheObj *NewObj();
+
+public:
+    SwBorderAttrAccess( SwCache &rCache, const SwFrm *pOwner );
+
+    SwBorderAttrs *Get();
+};
+
+//---------------------------------------------------------------------
+//Iterator fuer die DrawObjecte einer Seite. Die Objecte werden Nach ihrer
+//Z-Order iteriert.
+//Das iterieren ist nicht eben billig, denn fuer alle Operationen muss jeweils
+//ueber das gesamte SortArray iteriert werden.
+class SwOrderIter
+{
+    const SwPageFrm *pPage;
+    const SdrObject *pCurrent;
+    const FASTBOOL bFlysOnly;
+public:
+    SwOrderIter( const SwPageFrm *pPage, FASTBOOL bFlysOnly = TRUE );
+
+    void             Current( const SdrObject *pNew ) { pCurrent = pNew; }
+    const SdrObject *Current()    const { return pCurrent; }
+    const SdrObject *operator()() const { return pCurrent; }
+    const SdrObject *Top();
+    const SdrObject *Bottom();
+    const SdrObject *Next();
+    const SdrObject *Prev();
+};
+
+
+class StackHack
+{
+    static BYTE nCnt;
+    static BOOL bLocked;
+public:
+    StackHack()
+    {
+        if ( ++StackHack::nCnt > 50 )
+            StackHack::bLocked = TRUE;
+    }
+    ~StackHack()
+    {
+        if ( --StackHack::nCnt == 0 )
+            StackHack::bLocked = FALSE;
+    }
+
+    static BOOL IsLocked()  { return StackHack::bLocked; }
+    static BYTE Count()     { return StackHack::nCnt; }
+};
+
+
+//Sollen obere bzw. untere Umrandung fuer den Frm ausgewertet werden?
+inline USHORT SwBorderAttrs::GetTopLine   ( const SwFrm *pFrm ) const
+{
+    if ( !bCachedGetTopLine )
+        ((SwBorderAttrs*)this)->_GetTopLine( pFrm );
+    return nGetTopLine;
+}
+inline USHORT SwBorderAttrs::GetBottomLine( const SwFrm *pFrm ) const
+{
+    if ( !bCachedGetBottomLine )
+        ((SwBorderAttrs*)this)->_GetBottomLine( pFrm );
+    return nGetBottomLine;
+}
+inline void SwBorderAttrs::SetGetCacheLine( BOOL bNew ) const
+{
+    ((SwBorderAttrs*)this)->bCacheGetLine = bNew;
+    ((SwBorderAttrs*)this)->bCachedGetBottomLine =
+    ((SwBorderAttrs*)this)->bCachedGetTopLine = FALSE;
+}
+
+inline USHORT SwBorderAttrs::CalcTopLine() const
+{
+    if ( bTopLine )
+        ((SwBorderAttrs*)this)->_CalcTopLine();
+    return nTopLine;
+}
+inline USHORT SwBorderAttrs::CalcBottomLine() const
+{
+    if ( bBottomLine )
+        ((SwBorderAttrs*)this)->_CalcBottomLine();
+    return nBottomLine;
+}
+inline USHORT SwBorderAttrs::CalcLeftLine() const
+{
+    if ( bLeftLine )
+        ((SwBorderAttrs*)this)->_CalcLeftLine();
+    return nLeftLine;
+}
+inline USHORT SwBorderAttrs::CalcRightLine() const
+{
+    if ( bRightLine )
+        ((SwBorderAttrs*)this)->_CalcRightLine();
+    return nRightLine;
+}
+inline USHORT SwBorderAttrs::CalcTop() const
+{
+    if ( bTop )
+        ((SwBorderAttrs*)this)->_CalcTop();
+    return nTop;
+}
+inline USHORT SwBorderAttrs::CalcBottom() const
+{
+    if ( bBottom )
+        ((SwBorderAttrs*)this)->_CalcBottom();
+    return nBottom;
+}
+inline long SwBorderAttrs::CalcRight() const
+{
+    if ( bRight )
+        ((SwBorderAttrs*)this)->_CalcRight();
+    return nRight;
+}
+inline BOOL SwBorderAttrs::IsLine() const
+{
+    if ( bLine )
+        ((SwBorderAttrs*)this)->_IsLine();
+    return bIsLine;
+}
+
+#endif  //_FRMTOOL_HXX
diff --git a/sw/source/core/inc/ftnboss.hxx b/sw/source/core/inc/ftnboss.hxx
new file mode 100644
index 000000000000..0a4e64aa40e3
--- /dev/null
+++ b/sw/source/core/inc/ftnboss.hxx
@@ -0,0 +1,158 @@
+/*************************************************************************
+ *
+ *  $RCSfile: ftnboss.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:20 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _FTNBOSS_HXX
+#define _FTNBOSS_HXX
+
+#include "layfrm.hxx"
+
+class SwFtnBossFrm;
+class SwFtnContFrm;
+class SwFtnFrm;
+class SwTxtFtn;
+
+
+//Setzen des maximalen Fussnotenbereiches. Restaurieren des alten Wertes im DTor.
+//Implementierung im ftnfrm.cxx
+class SwSaveFtnHeight
+{
+    SwFtnBossFrm *pBoss;
+    const SwTwips nOldHeight;
+    SwTwips nNewHeight;
+public:
+    SwSaveFtnHeight( SwFtnBossFrm *pBs, const SwTwips nDeadLine );
+    ~SwSaveFtnHeight();
+};
+
+#define NA_ONLY_ADJUST 0
+#define NA_GROW_SHRINK 1
+#define NA_GROW_ADJUST 2
+#define NA_ADJUST_GROW 3
+
+class SwFtnBossFrm: public SwLayoutFrm
+{
+    //Fuer die privaten Fussnotenoperationen
+    friend class SwFrm;
+    friend class SwSaveFtnHeight;
+    friend class SwPageFrm; // fuer das Setzen der MaxFtnHeight
+
+    //Maximale Hoehe des Fussnotencontainers fuer diese Seite.
+    SwTwips nMaxFtnHeight;
+
+    SwFtnContFrm *MakeFtnCont();
+    SwFtnFrm     *FindFirstFtn();
+    BYTE _NeighbourhoodAdjustment( const SwFrm* pFrm ) const;
+protected:
+    inline SwFtnBossFrm( Sw3FrameIo& rFr, SwLayoutFrm* pLay) : SwLayoutFrm( rFr, pLay ) {}
+
+    void          InsertFtn( SwFtnFrm * );
+    static void   ResetFtn( const SwFtnFrm *pAssumed );
+public:
+    inline SwFtnBossFrm( SwFrmFmt* pFmt) : SwLayoutFrm( pFmt ) {}
+
+                 SwLayoutFrm *FindBodyCont();
+    inline const SwLayoutFrm *FindBodyCont() const;
+    inline void SetMaxFtnHeight( const SwTwips nNewMax ) { nMaxFtnHeight = nNewMax; }
+
+    //Fussnotenschnittstelle
+    void AppendFtn( SwCntntFrm *, SwTxtFtn * );
+    void RemoveFtn( const SwCntntFrm *, const SwTxtFtn *, BOOL bPrep = TRUE );
+    static       SwFtnFrm     *FindFtn( const SwCntntFrm *, const SwTxtFtn * );
+                 SwFtnContFrm *FindFtnCont();
+    inline const SwFtnContFrm *FindFtnCont() const;
+           const SwFtnFrm     *FindFirstFtn( SwCntntFrm* ) const;
+                 SwFtnContFrm *FindNearestFtnCont( BOOL bDontLeave = FALSE );
+
+    void ChangeFtnRef( const SwCntntFrm *pOld, const SwTxtFtn *,
+                       SwCntntFrm *pNew );
+    void RearrangeFtns( const SwTwips nDeadLine, const BOOL bLock = FALSE,
+                        const SwTxtFtn *pAttr = 0 );
+
+    //SS damit der Textformatierer Temporaer die Fussnotenhoehe begrenzen
+    //kann. DeadLine in Dokumentkoordinaten.
+    void    SetFtnDeadLine( const SwTwips nDeadLine );
+    SwTwips GetMaxFtnHeight() const { return nMaxFtnHeight; }
+
+    //Liefert den Wert, der noch uebrig ist, bis der Body seine minimale
+    //Hoehe erreicht hat.
+    SwTwips GetVarSpace() const;
+
+        //Layoutseitig benoetigte Methoden
+    static void _CollectFtns( const SwCntntFrm *pRef, SwFtnFrm *pFtn,
+                              SvPtrarr &rFtnArr );
+    void    CollectFtns( const SwCntntFrm *, SwFtnBossFrm *pOld, SvPtrarr &rFtnArr);
+    void    _MoveFtns( SvPtrarr &rFtnArr, BOOL bCalc = FALSE );
+    void    MoveFtns( const SwCntntFrm *pSrc, SwCntntFrm *pDest,
+                      SwTxtFtn *pAttr );
+    // Sollte AdjustNeighbourhood gerufen werden (oder Grow/Shrink)?
+    BYTE NeighbourhoodAdjustment( const SwFrm* pFrm ) const
+        { return IsPageFrm() ? NA_ONLY_ADJUST : _NeighbourhoodAdjustment( pFrm ); }
+};
+
+inline const SwLayoutFrm *SwFtnBossFrm::FindBodyCont() const
+{
+    return ((SwFtnBossFrm*)this)->FindBodyCont();
+}
+inline const SwFtnContFrm *SwFtnBossFrm::FindFtnCont() const
+{
+    return ((SwFtnBossFrm*)this)->FindFtnCont();
+}
+
+#endif  //_FTNBOSS_HXX
diff --git a/sw/source/core/inc/ftnfrm.hxx b/sw/source/core/inc/ftnfrm.hxx
new file mode 100644
index 000000000000..5efbab1ba59c
--- /dev/null
+++ b/sw/source/core/inc/ftnfrm.hxx
@@ -0,0 +1,156 @@
+/*************************************************************************
+ *
+ *  $RCSfile: ftnfrm.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:20 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _FTNFRM_HXX
+#define _FTNFRM_HXX
+
+#include "layfrm.hxx"
+
+class SwCntntFrm;
+class SwTxtFtn;
+class Sw3FrameIo;
+class SwBorderAttrs;
+class SwFtnFrm;
+
+//Fuer Fussnoten gibt es einen Speziellen Bereich auf der Seite. Dieser
+//Bereich ist ein SwFtnContFrm.
+//Jede Fussnote ist durch einen SwFtnFrm abgegrenzt, dieser nimmt die
+//Fussnotenabsaetze auf. SwFtnFrm koennen aufgespalten werden, sie gehen
+//dann auf einer anderen Seite weiter.
+
+class SwFtnContFrm: public SwLayoutFrm
+{
+public:
+    SwFtnContFrm( SwFrmFmt* );
+    SwFtnContFrm( Sw3FrameIo&, SwLayoutFrm* );
+
+    const SwFtnFrm* FindFootNote() const;
+    const SwFtnFrm* FindEndNote() const;
+
+    virtual void    Store( Sw3FrameIo& ) const;
+    virtual SwTwips ShrinkFrm( SwTwips, const SzPtr,
+                               BOOL bTst = FALSE, BOOL bInfo = FALSE );
+    virtual SwTwips GrowFrm( SwTwips, const SzPtr,
+                             BOOL bTst = FALSE, BOOL bInfo = FALSE );
+    virtual void    Format( const SwBorderAttrs *pAttrs = 0 );
+    virtual void    PaintBorder( const SwRect &, const SwPageFrm *pPage,
+                                 const SwBorderAttrs & ) const;
+            void    PaintLine( const SwRect &, const SwPageFrm * ) const;
+};
+
+class SwFtnFrm: public SwLayoutFrm
+{
+    friend class SwFrm;         // fuer Sw3FrameIo
+    //Zeiger auf den FtnFrm in dem die Fussnote weitergefuehrt wird:
+    // 0     wenn kein Follow vorhanden,
+    // this  beim letzten
+    // der Follow sonst.
+    SwFtnFrm     *pFollow;
+    SwFtnFrm     *pMaster;      //Der FtnFrm dessen Follow ich bin.
+    SwCntntFrm   *pRef;         //In diesem CntntFrm steht die Fussnotenref.
+    SwTxtFtn     *pAttr;        //Fussnotenattribut (zum wiedererkennen)
+
+    BOOL bBackMoveLocked;       //Absaetze in dieser Fussnote duerfen derzeit
+                                //nicht rueckwaerts fliessen.
+#ifndef PRODUCT
+protected:
+    virtual SwTwips ShrinkFrm( SwTwips, const SzPtr,
+                               BOOL bTst = FALSE, BOOL bInfo = FALSE );
+    virtual SwTwips GrowFrm  ( SwTwips, const SzPtr,
+                               BOOL bTst = FALSE, BOOL bInfo = FALSE );
+#endif
+
+
+public:
+    SwFtnFrm( SwFrmFmt*, SwCntntFrm*, SwTxtFtn* );
+    SwFtnFrm( Sw3FrameIo&, SwLayoutFrm* );
+
+    virtual void Store( Sw3FrameIo& ) const;
+
+    virtual void Cut();
+    virtual void Paste( SwFrm* pParent, SwFrm* pSibling = 0 );
+
+    BOOL operator<( const SwTxtFtn* pTxtFtn ) const;
+
+    SwCntntFrm *GetRef()  { return pRef; }
+    SwFtnFrm *GetFollow() { return pFollow; }
+    SwFtnFrm *GetMaster() { return pMaster; }
+    const SwTxtFtn   *GetAttr() const { return pAttr; }
+          SwTxtFtn   *GetAttr()       { return pAttr; }
+    const SwCntntFrm *GetRef()  const { return pRef; }
+    const SwFtnFrm *GetFollow() const { return pFollow; }
+    const SwFtnFrm *GetMaster() const { return pMaster; }
+
+    void SetFollow( SwFtnFrm *pNew ) { pFollow = pNew; }
+    void SetMaster( SwFtnFrm *pNew ) { pMaster = pNew; }
+    void SetRef   ( SwCntntFrm *pNew ) { pRef = pNew; }
+
+    void InvalidateNxtFtnCnts( SwPageFrm* pPage );
+
+    void LockBackMove()     { bBackMoveLocked = TRUE; }
+    void UnlockBackMove()   { bBackMoveLocked = FALSE;}
+    BOOL IsBackMoveLocked() { return bBackMoveLocked; }
+
+    // Verhindert, dass der letzte Inhalt den SwFtnFrm mitloescht (Cut())
+    inline void ColLock()       { bColLocked = TRUE; }
+    inline void ColUnlock()     { bColLocked = FALSE; }
+};
+
+#endif  //_FTNFRM_HXX
diff --git a/sw/source/core/inc/hffrm.hxx b/sw/source/core/inc/hffrm.hxx
new file mode 100644
index 000000000000..837db8c67ac9
--- /dev/null
+++ b/sw/source/core/inc/hffrm.hxx
@@ -0,0 +1,102 @@
+/*************************************************************************
+ *
+ *  $RCSfile: hffrm.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:21 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _HFFRM_HXX
+#define _HFFRM_HXX
+
+#ifndef _SVMEMPOOL_HXX //autogen
+#include 
+#endif
+
+#include "layfrm.hxx"
+
+class Sw3FrameIo;
+
+class SwHeaderFrm: public SwLayoutFrm
+{
+public:
+    SwHeaderFrm( SwFrmFmt* );
+    SwHeaderFrm( Sw3FrameIo&, SwLayoutFrm* );
+
+    virtual void Store( Sw3FrameIo& ) const;
+    virtual SwTwips ShrinkFrm( SwTwips, const SzPtr,
+                               BOOL bTst = FALSE, BOOL bInfo = FALSE );
+    virtual SwTwips GrowFrm  ( SwTwips, const SzPtr,
+                               BOOL bTst = FALSE, BOOL bInfo = FALSE );
+
+    DECL_FIXEDMEMPOOL_NEWDEL(SwHeaderFrm)
+};
+
+class SwFooterFrm: public SwLayoutFrm
+{
+public:
+    SwFooterFrm( SwFrmFmt* );
+    SwFooterFrm( Sw3FrameIo&, SwLayoutFrm* );
+
+    virtual void Store( Sw3FrameIo& ) const;
+    virtual void Format( const SwBorderAttrs *pAttrs = 0 );
+    virtual SwTwips ShrinkFrm( SwTwips, const SzPtr,
+                               BOOL bTst = FALSE, BOOL bInfo = FALSE );
+    virtual SwTwips GrowFrm  ( SwTwips, const SzPtr,
+                               BOOL bTst = FALSE, BOOL bInfo = FALSE );
+    DECL_FIXEDMEMPOOL_NEWDEL(SwFooterFrm)
+};
+
+#endif  //_HFFRM_HXX
diff --git a/sw/source/core/inc/layact.hxx b/sw/source/core/inc/layact.hxx
new file mode 100644
index 000000000000..3e50212bae64
--- /dev/null
+++ b/sw/source/core/inc/layact.hxx
@@ -0,0 +1,267 @@
+/*************************************************************************
+ *
+ *  $RCSfile: layact.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:21 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _LAYACT_HXX
+#define _LAYACT_HXX
+
+#include "swtypes.hxx"
+#include "swrect.hxx"
+
+class SwRootFrm;
+class SwLayoutFrm;
+class SwPageFrm;
+class SwFlyFrm;
+class SwFlyInCntFrm;
+class SwCntntFrm;
+class SwTabFrm;
+class SwViewImp;
+class SwCntntNode;
+class SwWait;
+
+//Die Verwendung der LayAction laeuft immer gleich ab:
+//
+// 1. Erzeugen des LayAction-Objektes.
+// 2. Einstellen des gewuenschten Verhaltens mittels der Set-Methoden
+// 3. Aufruf von Action()
+// 4. Baldiges Zerstoeren des Objektes.
+//
+// Das Objekt meldet sich im CTor beim SwViewImp an und erst im DTor
+// wieder ab! Es handelt sich mithin um ein typisches Stackobjekt.
+
+
+class SwLayAction
+{
+    SwRootFrm  *pRoot;
+    SwViewImp  *pImp;   //Hier Meldet sich die Action an und ab.
+
+    //Zur Optimierung, damit die Tabellen etwas besser am Crsr kleben beim
+    //Return/Backspace davor.
+    //Wenn der erste TabFrm, der sich Paintet (pro Seite) traegt sich im
+    //Pointer ein. Die CntntFrms unterhalb der Seite brauchen sich
+    //dann nicht mehr bei der Shell zum Painten anmelden.
+    const SwTabFrm *pOptTab;
+
+    SwWait *pWait;
+
+    //Wenn ein Absatz - oder was auch immer - bei der Formatierung mehr
+    //als eine Seite rueckwaerts floss traegt er seine neue Seitennummer
+    //hier ein. Die Steuerung der InternalAction kann dann geeignet reagieren.
+    USHORT nPreInvaPage;
+
+    ULONG nStartTicks;  //Startzeitpunkt der Aktion, vergeht zu viel Zeit kann
+                        //der WaitCrsr per CheckWaitCrsr() eingeschaltet werden.
+
+    USHORT nInputType;  //Bei welchem Input soll die Verarbeitung abgebrochen
+                        //werden?
+    USHORT nEndPage;    //StatBar Steuerung.
+    USHORT nCheckPageNum; //CheckPageDesc() wurde verzoegert wenn != USHRT_MAX
+                          //ab dieser Seite Checken.
+
+    BOOL bPaint;        //Painten oder nur Formatieren?
+    BOOL bComplete;     //Alles bis zum sichtbaren Bereich Formatieren oder
+                        //oder nur den sichtbaren Bereich?
+    BOOL bCalcLayout;   //Vollstaendige Reformatierung?
+    BOOL bAgain;        //Zur automatisch wiederholten Action wenn Seiten
+                        //geloscht werden.
+    BOOL bNextCycle;    //Wiederaufsetzen bei der ersten Ungueltigen Seite.
+    BOOL bInput;        //Zum Abbrechen der Verarbeitung wenn ein Input anliegt.
+    BOOL bIdle;         //True wenn die Layaction vom Idler ausgeloest wurde.
+    BOOL bReschedule;   //Soll das Reschedule - abhaengig vom Progress -
+                        //gerufen werden?
+    BOOL bCheckPages;   //CheckPageDescs() ausfuehren oder verzoegern.
+    BOOL bUpdateExpFlds;//Wird gesetzt wenn nach dem Formatierien noch eine
+                        //Runde fuer den ExpFld laufen muss.
+    BOOL bBrowseActionStop; //Action fruehzeitig beenden (per bInput) und den
+                            //Rest dem Idler ueberlassen.
+    BOOL bWaitAllowed;      //Wartecursor erlaubt?
+    BOOL bPaintExtraData;   //Anzeige von Zeilennumerierung o. ae. eingeschaltet?
+    BOOL bActionInProgress; // wird in Action() anfangs gesetzt und zum Schluss geloescht
+
+#ifdef _LAYACT_CXX
+
+    void _AddScrollRect( const SwCntntFrm *, const SwPageFrm *,
+                         const SwTwips, const SwTwips );
+    void PaintCntnt( const SwCntntFrm *, const SwPageFrm *,
+                     const SwRect &rOldRect, long nOldBottom );
+    BOOL PaintWithoutFlys( const SwRect &, const SwCntntFrm *,
+                           const SwPageFrm * );
+    inline BOOL _PaintCntnt( const SwCntntFrm *, const SwPageFrm *,
+                             const SwRect & );
+
+    void ChkFlyAnchor( SwFlyFrm *, const SwPageFrm * );
+
+    void FormatFlyLayout( const SwPageFrm * );
+    BOOL FormatFlyCntnt( const SwPageFrm * );
+    BOOL _FormatFlyCntnt( const SwFlyFrm * );
+    BOOL __FormatFlyCntnt( const SwCntntFrm * );
+    void FormatFlyInCnt( SwFlyInCntFrm * );
+    BOOL FormatLayout( SwLayoutFrm *, BOOL bAddRect = TRUE );
+    BOOL FormatLayoutTab( SwTabFrm *, BOOL bAddRect = TRUE );
+    BOOL FormatLayoutFly( SwFlyFrm *, BOOL bAddRect = TRUE );
+    BOOL FormatCntnt( const SwPageFrm * );
+    void _FormatCntnt( const SwCntntFrm *, const SwPageFrm *pPage );
+    BOOL IsShortCut( SwPageFrm *& );
+
+    BOOL TurboAction();
+    BOOL _TurboAction( const SwCntntFrm * );
+    void InternalAction();
+
+    SwPageFrm *CheckFirstVisPage( SwPageFrm *pPage );
+
+    BOOL RemoveEmptyBrowserPages();
+
+    inline void CheckIdleEnd();
+    inline ULONG GetStartTicks() { return nStartTicks; }
+#endif
+
+public:
+    SwLayAction( SwRootFrm *pRt, SwViewImp *pImp );
+    ~SwLayAction();
+
+#ifdef _LAYACT_CXX
+    void SetIdle            ( BOOL bNew )   { bIdle = bNew; }
+    void SetCheckPages      ( BOOL bNew )   { bCheckPages = bNew; }
+    void SetBrowseActionStop(BOOL bNew  )   { bBrowseActionStop = bNew; }
+    void SetNextCycle       ( BOOL bNew )   { bNextCycle = bNew; }
+
+    BOOL IsWaitAllowed()        const       { return bWaitAllowed; }
+    BOOL IsNextCycle()          const       { return bNextCycle; }
+    BOOL IsInput()              const       { return bInput; }
+    BOOL IsWait()               const       { return 0 != pWait;  }
+    BOOL IsPaint()              const       { return bPaint; }
+    BOOL IsIdle()               const       { return bIdle;  }
+    BOOL IsReschedule()         const       { return bReschedule;  }
+    BOOL IsPaintExtraData()     const       { return bPaintExtraData;}
+
+    USHORT GetInputType()    const { return nInputType; }
+#endif
+
+    //Einstellen der Action auf das gewuenschte Verhalten.
+    void SetPaint       ( BOOL bNew )   { bPaint = bNew; }
+    void SetComplete    ( BOOL bNew )   { bComplete = bNew; }
+    void SetStatBar     ( BOOL bNew );
+    void SetInputType   ( USHORT nNew ) { nInputType = nNew; }
+    void SetCalcLayout  ( BOOL bNew )   { bCalcLayout = bNew; }
+    void SetReschedule  ( BOOL bNew )   { bReschedule = bNew; }
+    void SetWaitAllowed ( BOOL bNew )   { bWaitAllowed = bNew; }
+
+    void SetAgain()         { bAgain = TRUE; }
+    void SetUpdateExpFlds() {bUpdateExpFlds = TRUE; }
+
+    inline void SetCheckPageNum( USHORT nNew );
+    inline void SetCheckPageNumDirect( USHORT nNew ) { nCheckPageNum = nNew; }
+
+    void Action();  //Jetzt gehts loos...
+    void Reset();   //Zurueck auf CTor-Defaults.
+
+    BOOL IsAgain()      const { return bAgain; }
+    BOOL IsComplete()   const { return bComplete; }
+    BOOL IsExpFlds()    const { return bUpdateExpFlds; }
+    BOOL IsCalcLayout() const { return bCalcLayout;  }
+    BOOL IsCheckPages() const { return bCheckPages;  }
+    BOOL IsBrowseActionStop() const { return bBrowseActionStop; }
+    BOOL IsActionInProgress() const { return bActionInProgress; }
+
+    USHORT GetCheckPageNum() const { return nCheckPageNum; }
+
+    //Auch andere sollen den Wartecrsr einschalten koennen.
+    void CheckWaitCrsr();
+};
+
+
+class SwLayIdle
+{
+
+    SwRootFrm *pRoot;
+    SwViewImp  *pImp;           // Hier Meldet sich der Idler an und ab.
+    SwCntntNode *pCntntNode;    // Hier wird die aktuelle Cursorposition
+    xub_StrLen  nTxtPos;        // zwischengespeichert.
+    BOOL        bPageValid;     // Konnte die Seite alles validiert werden?
+    BOOL        bAllValid;      // Konnte alles validiert werden?
+
+#ifndef PRODUCT
+    BOOL bIndicator;
+#endif
+
+#ifdef _LAYACT_CXX
+
+#ifndef PRODUCT
+    void ShowIdle( ColorData eName );
+#endif
+    BOOL _FormatSpelling( const SwCntntFrm * );
+    BOOL FormatSpelling( BOOL );
+
+    BOOL _CollectAutoCmplWords( const SwCntntFrm *, BOOL bOnlyVisArea );
+    BOOL CollectAutoCmplWords( BOOL );
+
+#endif
+
+public:
+    SwLayIdle( SwRootFrm *pRt, SwViewImp *pImp );
+    ~SwLayIdle();
+};
+
+inline void SwLayAction::SetCheckPageNum( USHORT nNew )
+{
+    if ( nNew < nCheckPageNum )
+        nCheckPageNum = nNew;
+}
+
+#endif  //_LAYACT_HXX
diff --git a/sw/source/core/inc/layfrm.hxx b/sw/source/core/inc/layfrm.hxx
new file mode 100644
index 000000000000..d2f9d58939c3
--- /dev/null
+++ b/sw/source/core/inc/layfrm.hxx
@@ -0,0 +1,208 @@
+/*************************************************************************
+ *
+ *  $RCSfile: layfrm.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:21 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _LAYFRM_HXX
+#define _LAYFRM_HXX
+
+#include "frame.hxx"
+
+class SwCntntFrm;
+class SwFlowFrm;
+class Sw3FrameIo;
+class SwFmtCol;
+struct SwCrsrMoveState;
+class SwFrmFmt;
+class SwBorderAttrs;
+class SwFmtFrmSize;
+class SwCellFrm;
+
+class SwLayoutFrm: public SwFrm
+{
+    //Der verkappte SwFrm
+    friend class SwFlowFrm;
+    friend class SwFrm;
+
+        //Hebt die Lower waehrend eines Spaltenumbaus auf.
+    friend SwFrm* SaveCntnt( SwLayoutFrm *, SwFrm * );
+    friend void   RestoreCntnt( SwFrm *, SwLayoutFrm *, SwFrm *pSibling );
+
+    //entfernt leere SwSectionFrms aus einer Kette
+    friend SwFrm* SwClearDummies( SwFrm* pFrm );
+
+    void CopySubtree( const SwLayoutFrm *pDest );
+protected:
+    virtual void Format( const SwBorderAttrs *pAttrs = 0 );
+    virtual void MakeAll();
+
+    SwFrm           *pLower;
+
+    virtual SwTwips ShrinkFrm( SwTwips, const SzPtr,
+                               BOOL bTst = FALSE, BOOL bInfo = FALSE );
+    virtual SwTwips GrowFrm  ( SwTwips, const SzPtr,
+                               BOOL bTst = FALSE, BOOL bInfo = FALSE );
+
+    long CalcRel( const SwFmtFrmSize &rSz, BOOL bWidth ) const;
+
+    SwLayoutFrm( Sw3FrameIo&, SwLayoutFrm* );
+    void LoadLower( Sw3FrameIo& );
+    void StoreLower( Sw3FrameIo& ) const;
+public:
+    void PaintSubsidiaryLines( const SwPageFrm*, const SwRect& ) const;
+    void RefreshLaySubsidiary( const SwPageFrm*, const SwRect& ) const;
+    void RefreshExtraData( const SwRect & ) const;
+
+        //Proportionale Groessenanpassung der untergeordneten.
+    void ChgLowersProp( const Size& rOldSize );
+
+    void AdjustColumns( const SwFmtCol *pCol, BOOL bAdjustAttributes );
+    void ChgColumns( const SwFmtCol &rOld, const SwFmtCol &rNew,
+        const BOOL bChgFtn = FALSE );
+
+
+        //Painted die Column-Trennlinien fuer die innenliegenden Columns.
+    void PaintColLines( const SwRect &, const SwFmtCol &,
+                        const SwPageFrm * ) const;
+
+    virtual void Store( Sw3FrameIo& ) const;
+
+    virtual BOOL  GetCrsrOfst( SwPosition *, Point&,
+                                const SwCrsrMoveState* = 0 ) const;
+
+    virtual void Cut();
+    virtual void Paste( SwFrm* pParent, SwFrm* pSibling = 0 );
+
+        //sucht den dichtesten Cntnt zum SPoint, wird bei Seiten, Flys und Cells
+        //benutzt wenn GetCrsrOfst versagt hat.
+    const SwCntntFrm* GetCntntPos( Point &rPoint, const BOOL bDontLeave,
+                                   const BOOL bBodyOnly = FALSE,
+                                   const BOOL bCalc = FALSE,
+                                   const SwCrsrMoveState *pCMS = 0,
+                                   const BOOL bDefaultExpand = TRUE ) const;
+
+    SwLayoutFrm( SwFrmFmt* );
+    ~SwLayoutFrm();
+
+    virtual void Paint( const SwRect& ) const;
+    const SwFrm *Lower() const { return pLower; }
+          SwFrm *Lower()       { return pLower; }
+    const SwCntntFrm *ContainsCntnt() const;
+    inline SwCntntFrm *ContainsCntnt();
+    const SwCellFrm *FirstCell() const;
+    inline SwCellFrm *FirstCell();
+    const SwFrm *ContainsAny() const;
+    inline SwFrm *ContainsAny();
+    BOOL IsAnLower( const SwFrm * ) const;
+
+    const SwFrmFmt *GetFmt() const { return (const SwFrmFmt*)GetDep(); }
+          SwFrmFmt *GetFmt()       { return (SwFrmFmt*)GetDep(); }
+    void            SetFrmFmt( SwFrmFmt* );
+
+    //Verschieben der Ftns aller Lower - ab dem StartCntnt.
+    //TRUE wenn mindestens eine Ftn verschoben wurde.
+    //Ruft das Update der Seitennummer wenn bFtnNums gesetzt ist.
+    BOOL MoveLowerFtns( SwCntntFrm *pStart, SwFtnBossFrm *pOldBoss,
+                        SwFtnBossFrm *pNewBoss, const BOOL bFtnNums );
+
+    //Sorgt dafuer, dass innenliegende Flys noetigenfalls zum clippen bzw.
+    //reformatieren invalidiert werden.
+    void NotifyFlys();
+
+    //Invalidiert diejenigen innenliegenden Frames, deren Breite und/oder
+    //Hoehe Prozentual berechnet werden. Auch Rahmen, die an this oder an
+    //innenliegenden verankert sind werden ggf. invalidiert.
+    void InvaPercentLowers();
+
+    //Gerufen von Format fuer Rahmen und Bereichen mit Spalten.
+    void FormatWidthCols( const SwBorderAttrs &, const SwTwips nBorder,
+                          const SwTwips nMinHeight );
+
+    // InnerHeight returns the height of the content and may be bigger or
+    // less than the PrtArea-Height of the layoutframe himself
+    SwTwips InnerHeight() const;
+};
+
+//Um doppelte Implementierung zu sparen wird hier ein bischen gecasted
+inline SwCntntFrm* SwLayoutFrm::ContainsCntnt()
+{
+    return (SwCntntFrm*)(((const SwLayoutFrm*)this)->ContainsCntnt());
+}
+
+inline SwCellFrm* SwLayoutFrm::FirstCell()
+{
+    return (SwCellFrm*)(((const SwLayoutFrm*)this)->FirstCell());
+}
+
+inline SwFrm* SwLayoutFrm::ContainsAny()
+{
+    return (SwFrm*)(((const SwLayoutFrm*)this)->ContainsAny());
+}
+
+// Diese SwFrm-inlines sind hier, damit frame.hxx nicht layfrm.hxx includen muss
+inline BOOL SwFrm::IsColBodyFrm() const
+{
+    return nType == FRM_BODY && GetUpper()->IsColumnFrm();
+}
+
+inline BOOL SwFrm::IsPageBodyFrm() const
+{
+    return nType == FRM_BODY && GetUpper()->IsPageFrm();
+}
+
+#endif  //_LAYFRM_HXX
diff --git a/sw/source/core/inc/layouter.hxx b/sw/source/core/inc/layouter.hxx
new file mode 100644
index 000000000000..147a0265a388
--- /dev/null
+++ b/sw/source/core/inc/layouter.hxx
@@ -0,0 +1,98 @@
+/*************************************************************************
+ *
+ *  $RCSfile: layouter.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:21 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _LAYOUTER_HXX
+#define _LAYOUTER_HXX
+
+#include "swtypes.hxx"
+
+class SwEndnoter;
+class SwDoc;
+class SwSectionFrm;
+class SwFtnFrm;
+class SwPageFrm;
+class SwLooping;
+
+#define LOOP_PAGE 1
+
+class SwLayouter
+{
+    SwEndnoter* pEndnoter;
+    SwLooping* pLooping;
+    void _CollectEndnotes( SwSectionFrm* pSect );
+    BOOL StartLooping( SwPageFrm* pPage );
+public:
+    SwLayouter();
+    ~SwLayouter();
+    void InsertEndnotes( SwSectionFrm* pSect );
+    void CollectEndnote( SwFtnFrm* pFtn );
+    BOOL HasEndnotes() const;
+
+    void LoopControl( SwPageFrm* pPage, BYTE nLoop );
+    void EndLoopControl();
+
+    static void CollectEndnotes( SwDoc* pDoc, SwSectionFrm* pSect );
+    static BOOL Collecting( SwDoc* pDoc, SwSectionFrm* pSect, SwFtnFrm* pFtn );
+    static BOOL StartLoopControl( SwDoc* pDoc, SwPageFrm *pPage );
+};
+
+#endif  //_LAYOUTER_HXX
+
+
diff --git a/sw/source/core/inc/makefile.mk b/sw/source/core/inc/makefile.mk
new file mode 100644
index 000000000000..031f533976ed
--- /dev/null
+++ b/sw/source/core/inc/makefile.mk
@@ -0,0 +1,61 @@
+#*************************************************************************
+#
+#   $RCSfile: makefile.mk,v $
+#
+#   $Revision: 1.1.1.1 $
+#
+#   last change: $Author: hr $ $Date: 2000-09-19 00:08:21 $
+#
+#   The Contents of this file are made available subject to the terms of
+#   either of the following licenses
+#
+#          - GNU Lesser General Public License Version 2.1
+#          - Sun Industry Standards Source License Version 1.1
+#
+#   Sun Microsystems Inc., October, 2000
+#
+#   GNU Lesser General Public License Version 2.1
+#   =============================================
+#   Copyright 2000 by Sun Microsystems, Inc.
+#   901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+#   This library is free software; you can redistribute it and/or
+#   modify it under the terms of the GNU Lesser General Public
+#   License version 2.1, as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   Lesser General Public License for more details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+#   License along with this library; if not, write to the Free Software
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+#   MA  02111-1307  USA
+#
+#
+#   Sun Industry Standards Source License Version 1.1
+#   =================================================
+#   The contents of this file are subject to the Sun Industry Standards
+#   Source License Version 1.1 (the "License"); You may not use this file
+#   except in compliance with the License. You may obtain a copy of the
+#   License at http://www.openoffice.org/license.html.
+#
+#   Software provided under this License is provided on an "AS IS" basis,
+#   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+#   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+#   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+#   See the License for the specific provisions governing your rights and
+#   obligations concerning the Software.
+#
+#   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+#   Copyright: 2000 by Sun Microsystems, Inc.
+#
+#   All Rights Reserved.
+#
+#   Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
diff --git a/sw/source/core/inc/mvsave.hxx b/sw/source/core/inc/mvsave.hxx
new file mode 100644
index 000000000000..bf79c0dae428
--- /dev/null
+++ b/sw/source/core/inc/mvsave.hxx
@@ -0,0 +1,250 @@
+/*************************************************************************
+ *
+ *  $RCSfile: mvsave.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:21 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _MVSAVE_HXX
+#define _MVSAVE_HXX
+
+
+#ifndef _STRING_HXX //autogen
+#include 
+#endif
+#ifndef _KEYCOD_HXX //autogen
+#include 
+#endif
+#ifndef _SVARRAY_HXX //autogen
+#include 
+#endif
+
+class SvNumberFormatter;
+class SvULongs;
+class SwBookmark;
+class SwDoc;
+class SwCrsrShell;
+class SwFmtAnchor;
+class SwFrmFmt;
+class SwIndex;
+class SwNodeIndex;
+class SwNodeRange;
+class SwPaM;
+class SwRedline;
+struct SwPosition;
+
+enum SaveBookmarkType { BKMK_POS_NONE   = 0x00,
+                        BKMK_POS        = 0x01,
+                        BKMK_POS_OTHER  = 0x02
+                         };
+
+class SaveBookmark
+{
+    String  aName, aShortName;
+    ULONG nNode1, nNode2;
+    xub_StrLen nCntnt1, nCntnt2;
+    KeyCode aCode;
+    SaveBookmarkType eBkmkType;
+
+public:
+    SaveBookmark( int, const SwBookmark&, const SwNodeIndex&,
+                                    const SwIndex* pIdx = 0 );
+    void SetInDoc( SwDoc* pDoc, const SwNodeIndex&, const SwIndex* pIdx = 0);
+};
+
+SV_DECL_PTRARR_DEL( SaveBookmarks, SaveBookmark*, 0, 10 )
+
+void _DelBookmarks( const SwNodeIndex& rStt,
+                    const SwNodeIndex& rEnd,
+                    SaveBookmarks* pSaveBkmk = 0,
+                    const SwIndex* pSttIdx = 0,
+                    const SwIndex* pEndIdx = 0 );
+
+
+#define SAVEFLY 1
+#define SAVEFLY_SPLIT 2
+
+void _SaveCntntIdx( SwDoc* pDoc, ULONG nNode, xub_StrLen nCntnt,
+                    SvULongs& rSaveArr, BYTE nSaveFly = 0 );
+void _RestoreCntntIdx( SwDoc* pDoc, SvULongs& rSaveArr,
+                        ULONG nNode, xub_StrLen nOffset = 0,
+                        BOOL bAuto = FALSE );
+void _RestoreCntntIdx( SvULongs& rSaveArr, const SwNode& rNd,
+                        xub_StrLen nLen, xub_StrLen nCorrLen );
+
+
+struct _SaveFly
+{
+    ULONG nNdDiff;
+    SwFrmFmt* pFrmFmt;
+    _SaveFly( ULONG nNodeDiff, SwFrmFmt* pFmt )
+        : nNdDiff( nNodeDiff ), pFrmFmt( pFmt ) {}
+};
+
+SV_DECL_VARARR( _SaveFlyArr, _SaveFly, 0, 10 )
+
+void _RestFlyInRange( _SaveFlyArr& rArr, const SwNodeIndex& rSttIdx );
+void _SaveFlyInRange( const SwNodeRange& rRg, _SaveFlyArr& rArr );
+void _SaveFlyInRange( const SwPaM& rPam, const SwNodeIndex& rInsPos,
+                       _SaveFlyArr& rArr, sal_Bool bMoveAllFlys );
+
+void DelFlyInRange( const SwNodeIndex& rMkNdIdx,
+                    const SwNodeIndex& rPtNdIdx );
+
+
+class SwDataChanged
+{
+    const SwPaM* pPam;
+    const SwPosition* pPos;
+    SwDoc* pDoc;
+    ULONG nNode;
+    xub_StrLen nCntnt;
+    USHORT nType;       // Insert/Move/Delete/... (UndoIds)
+
+public:
+    SwDataChanged( const SwPaM& rPam, USHORT nType );
+    SwDataChanged( SwDoc* pDoc, const SwPosition& rPos, USHORT nType );
+    ~SwDataChanged();
+
+    ULONG GetNode() const           { return nNode; }
+    xub_StrLen GetCntnt() const     { return nCntnt; }
+};
+
+
+// Funktions-Deklaration damit auch alles unter der CrsrShell mal die
+// Crsr verschieben kann
+// die Funktionen rufen nicht die SwDoc::Corr - Methoden!
+
+    // Setzt alle PaMs an OldPos auf NewPos + Offset
+void PaMCorrAbs( const SwPosition &rOldPos,
+                const SwPosition &rNewPos,
+                const xub_StrLen nOffset = 0 );
+
+    // Setzt alle PaMs in OldNode auf NewPos + Offset
+void PaMCorrAbs( const SwNodeIndex &rOldNode,
+                const SwPosition &rNewPos,
+                const xub_StrLen nOffset = 0 );
+
+    // Setzt alle PaMs im Bereich vom Range nach NewPos
+void PaMCorrAbs( const SwPaM& rRange,
+                 const SwPosition& rNewPos );
+
+    // Setzt alle PaMs im Bereich von [StartNode, EndNode] nach NewPos
+void PaMCorrAbs( SwCrsrShell *pShell,
+                 const SwNodeIndex &rStartNode,
+                 const SwNodeIndex &rEndNode,
+                 const SwPosition &rNewPos );
+
+    // Setzt alle PaMs in OldNode auf relative Pos
+void PaMCorrRel( const SwNodeIndex &rOldNode,
+                 const SwPosition &rNewPos,
+                 const xub_StrLen nOffset = 0 );
+
+
+// Hilfsklasse zum kopieren von absatzgebundenen Flys. Durch die Sortierung
+// nach der Ordnungsnummer wird versucht die layout seitige Anordnung
+// bei zu behalten
+class _ZSortFly
+{
+    const SwFrmFmt* pFmt;
+    const SwFmtAnchor* pAnchor;
+    UINT32 nOrdNum;
+
+public:
+    _ZSortFly( const SwFrmFmt* pFrmFmt, const SwFmtAnchor* pFlyAnchor,
+                UINT32 nArrOrdNum );
+    _ZSortFly& operator=( const _ZSortFly& rCpy )
+    {
+        pFmt = rCpy.pFmt, pAnchor = rCpy.pAnchor, nOrdNum = rCpy.nOrdNum;
+        return *this;
+    }
+
+    int operator==( const _ZSortFly& ) const { return FALSE; }
+    int operator<( const _ZSortFly& rCmp ) const
+        { return nOrdNum < rCmp.nOrdNum; }
+
+    const SwFrmFmt* GetFmt() const              { return pFmt; }
+    const SwFmtAnchor* GetAnchor() const        { return pAnchor; }
+};
+
+SV_DECL_VARARR_SORT( _ZSortFlys, _ZSortFly, 0, 10 )
+
+
+class SwTblNumFmtMerge
+{
+    SvNumberFormatter* pNFmt;
+public:
+    SwTblNumFmtMerge( const SwDoc& rSrc, SwDoc& rDest );
+    ~SwTblNumFmtMerge();
+};
+
+
+class _SaveRedlEndPosForRestore
+{
+    SvPtrarr* pSavArr;
+    SwNodeIndex* pSavIdx;
+
+    void _Restore();
+public:
+    _SaveRedlEndPosForRestore( const SwNodeIndex& rInsIdx );
+    ~_SaveRedlEndPosForRestore();
+    void Restore() { if( pSavArr ) _Restore(); }
+};
+
+
+#endif  // _MVSAVE_HXX
+
diff --git a/sw/source/core/inc/node2lay.hxx b/sw/source/core/inc/node2lay.hxx
new file mode 100644
index 000000000000..7edf79cb35ee
--- /dev/null
+++ b/sw/source/core/inc/node2lay.hxx
@@ -0,0 +1,110 @@
+/*************************************************************************
+ *
+ *  $RCSfile: node2lay.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:21 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _NODE2LAY_HXX
+#define _NODE2LAY_HXX
+
+/* -----------------23.02.99 11:33-------------------
+ * Die Klasse SwNode2Layout stellt die Verbindung von Nodes zum Layout her.
+ * Sie liefert einen intelligenten Iterator ueber die zum Node oder Nodebereich
+ * gehoerenden Frames. Je nach Zweck der Iteration, z.B. um vor oder hinter
+ * den Frames andere Frames einzufuegen, werden Master/Follows erkannt und nur
+ * die relevanten zurueckgegeben. Auch wiederholte Tabellenueberschriften werden
+ * beachtet.
+ * Es ist auch moeglich, ueber SectionNodes zu iterieren, die durch Schachtelung
+ * manchmal gar keinem SectionFrm direkt zugeordnet sind, manchmal aber sogar
+ * mehreren.
+ * SwNode2Layout ist ein Schnittstelle zwischen der aufrufenden Methode und
+ * einem SwClientIter, sie waehlt je nach Aufgabenstellung das richtige
+ * SwModify aus, erzeugt einen SwClientIter und filtert dessen Iterationen
+ * je nach Aufgabenstellung.
+ * Die Aufgabenstellung wird durch die Wahl des Ctors bestimmt.
+ * 1. Das Einsammeln der UpperFrms, damit spaeter RestoreUpperFrms wird,
+ *    wird von MakeFrms gerufen, wenn es keinen PrevNext gibt, vor/hinter den
+ *    die Frames gehaengt werden koennen.
+ * 2. Die Lieferung der Frames hinter/vor die die neuen Frames eines Nodes
+ *    gehaengt werden muessen, ebenfalls von MakeFrms gerufen.
+ * --------------------------------------------------*/
+
+class SwNode2LayImpl;
+class SwFrm;
+class SwLayoutFrm;
+class SwNode;
+
+class SwNode2Layout
+{
+    SwNode2LayImpl *pImpl;
+public:
+    // Dieser Ctor ist zum Einsammeln der UpperFrms gedacht.
+    SwNode2Layout( const SwNode& rNd );
+    // Dieser Ctor ist fuer das Einfuegen vor oder hinter rNd gedacht,
+    // nIdx ist der Index des einzufuegenden Nodes
+    SwNode2Layout( const SwNode& rNd, ULONG nIdx );
+    ~SwNode2Layout();
+    SwFrm* NextFrm();
+    SwLayoutFrm* UpperFrm( SwFrm* &rpFrm, const SwNode& rNode );
+    void RestoreUpperFrms( SwNodes& rNds, ULONG nStt, ULONG nEnd );
+
+    SwFrm *GetFrm( const Point* pDocPos = 0,
+                    const SwPosition *pPos = 0,
+                    const BOOL bCalcFrm = TRUE ) const;
+};
+
+#endif
diff --git a/sw/source/core/inc/noteurl.hxx b/sw/source/core/inc/noteurl.hxx
new file mode 100644
index 000000000000..52d00012f313
--- /dev/null
+++ b/sw/source/core/inc/noteurl.hxx
@@ -0,0 +1,116 @@
+/*************************************************************************
+ *
+ *  $RCSfile: noteurl.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:21 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _NOTEURL_HXX
+#define _NOTEURL_HXX
+
+
+#ifndef _SVARRAY_HXX //autogen
+#include 
+#endif
+#ifndef _STRING_HXX //autogen
+#include 
+#endif
+#ifndef _SWRECT_HXX
+#include "swrect.hxx"
+#endif
+
+class ImageMap;
+class MapMode;
+
+class SwURLNote
+{
+    String aURL;
+    String aTarget;
+    SwRect aRect;
+public:
+    SwURLNote( const String& rURL, const String& rTarget, const SwRect& rRect )
+    : aURL( rURL ), aTarget( rTarget ), aRect( rRect )
+    {}
+    const String& GetURL()      const { return aURL; }
+    const String& GetTarget()   const { return aTarget; }
+    const SwRect& GetRect()     const { return aRect; }
+    BOOL operator==( const SwURLNote& rSwURLNote ) const
+    { return aRect == rSwURLNote.aRect; }
+};
+
+typedef SwURLNote* SwURLNotePtr;
+SV_DECL_PTRARR_DEL(SwURLNoteList, SwURLNotePtr, 0, 5)
+
+class SwNoteURL
+{
+    SwURLNoteList aList;
+public:
+    SwNoteURL() {}
+    USHORT Count() const { return aList.Count(); }
+    void InsertURLNote( const String& rURL, const String& rTarget,
+                 const SwRect& rRect );
+    const SwURLNote& GetURLNote( USHORT nPos ) const
+        { return *aList.GetObject( nPos ); }
+    void FillImageMap( ImageMap* pMap, const Point& rPos, const MapMode& rMap );
+};
+
+// globale Variable, in NoteURL.Cxx angelegt
+extern SwNoteURL *pNoteURL;
+
+
+#endif
+
diff --git a/sw/source/core/inc/notxtfrm.hxx b/sw/source/core/inc/notxtfrm.hxx
new file mode 100644
index 000000000000..7675e0d0af23
--- /dev/null
+++ b/sw/source/core/inc/notxtfrm.hxx
@@ -0,0 +1,119 @@
+/*************************************************************************
+ *
+ *  $RCSfile: notxtfrm.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:21 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _NOTXTFRM_HXX
+#define _NOTXTFRM_HXX
+
+#ifndef _CNTFRM_HXX
+#include 
+#endif
+
+class SwNoTxtNode;
+class Sw3FrameIo;
+class OutputDevice;
+class SwBorderAttrs;
+class Bitmap;
+struct SwCrsrMoveState;
+
+class SwNoTxtFrm: public SwCntntFrm
+{
+    friend void _FrmFinit();    //erase pErrorBmp and pReplaceBmp
+    static Bitmap *pErrorBmp, *pReplaceBmp;
+
+    short    nWeight;                   // "Wichtigkeit" der Grafik
+
+    const Size& GetSize() const;
+
+    void InitCtor();
+
+    void Format ( const SwBorderAttrs *pAttrs = 0 );
+    void PaintCntnt  ( OutputDevice*, const SwRect&, const SwRect& ) const;
+    void PaintPicture( OutputDevice*, const SwRect&, const SwRect& ) const;
+protected:
+    virtual void MakeAll();
+public:
+    SwNoTxtFrm( SwNoTxtNode * const );
+    SwNoTxtFrm( Sw3FrameIo&, SwLayoutFrm* );
+    ~SwNoTxtFrm();
+
+    virtual void Store( Sw3FrameIo& ) const;
+    virtual void Modify( SfxPoolItem*, SfxPoolItem* );
+    virtual void Paint(const SwRect& ) const;
+    virtual BOOL GetCharRect( SwRect &, const SwPosition&,
+                              SwCrsrMoveState* = 0) const;
+    BOOL GetCrsrOfst(SwPosition* pPos, Point& aPoint,
+                            const SwCrsrMoveState* = 0) const;
+
+    const Size &GetGrfSize() const  { return GetSize(); }
+    void GetGrfArea( SwRect &rRect, SwRect * = 0, BOOL bMirror = TRUE ) const;
+
+    BOOL IsTransparent() const;
+
+    void StopAnimation( OutputDevice* = 0 ) const;
+    BOOL HasAnimation()  const;
+
+    // Routinen fuer den Grafik-Cache
+    USHORT GetWeight() { return nWeight; }
+
+    static const Bitmap& GetBitmap( BOOL bError );
+};
+
+
+#endif
diff --git a/sw/source/core/inc/pagefrm.hxx b/sw/source/core/inc/pagefrm.hxx
new file mode 100644
index 000000000000..d0c4d6e4125f
--- /dev/null
+++ b/sw/source/core/inc/pagefrm.hxx
@@ -0,0 +1,327 @@
+/*************************************************************************
+ *
+ *  $RCSfile: pagefrm.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:21 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _PAGEFRM_HXX
+#define _PAGEFRM_HXX
+
+
+
+#ifndef _SVARRAY_HXX //autogen
+#include 
+#endif
+
+#include "ftnboss.hxx"
+
+#ifndef _SVMEMPOOL_HXX //autogen
+#include 
+#endif
+
+class SwFlyFrm;
+class SwFrmFmt;
+class SwPageDesc;
+class SwCntntFrm;
+class Sw3FrameIo;
+struct SwPosition;
+struct SwCrsrMoveState;
+class SwFmtAnchor;
+class SdrObject;
+class SwDrawContact;
+class SwAttrSetChg;
+class SvPtrarr;
+
+SV_DECL_PTRARR_SORT(SwSortDrawObjs,SdrObjectPtr,1,2);
+
+enum SwPageChg
+{
+    CHG_NEWPAGE,
+    CHG_CUTPAGE,
+    CHG_CHGPAGE
+};
+
+class SwPageFrm: public SwFtnBossFrm
+{
+    friend class SwFrm;
+
+    //Array fuer die Draw-Objekte auf der Seite.
+    //Das Sortierte Array ist nach den Pointeraddressen sortiert.
+    //Die Objs in dem Array haben ihren Anker nicht notwendigerweise auf
+    //der Seite.
+    SwSortDrawObjs *pSortedObjs;
+
+    SwPageDesc *pDesc;      //PageDesc der die Seite beschreibt.
+
+    USHORT  nPhyPageNum;        //Physikalische Seitennummer.
+
+    BOOL bInvalidCntnt      :1;
+    BOOL bInvalidLayout     :1;
+    BOOL bInvalidFlyCntnt   :1;
+    BOOL bInvalidFlyLayout  :1;
+    BOOL bInvalidFlyInCnt   :1;
+    BOOL bFtnPage           :1; //Diese Seite ist fuer Dokumentende-Fussnoten.
+    BOOL bEmptyPage         :1; //Dies ist eine explizite Leerseite
+    BOOL bInvalidSpelling   :1; //Das Online-Spelling ist gefordert
+    BOOL bEndNotePage       :1; //'Fussnotenseite' fuer Endnoten
+    BOOL bInvalidAutoCmplWrds :1; //Auto-Complete Wordliste aktualisieren
+
+    //Anpassung der RootSize und Benachrichtigungen beim Einsetzen,
+    //Entfernen und Groessenaenderungen der Seite.
+    void AdjustRootSize( const SwPageChg eChgType, const SwRect *pOld );
+
+    void _UpdateAttr( SfxPoolItem*, SfxPoolItem*, BYTE &,
+                      SwAttrSetChg *pa = 0, SwAttrSetChg *pb = 0 );
+
+    // Anpassen der max. Fussnotenhoehen in den einzelnen Spalten
+    void SetColMaxFtnHeight();
+
+protected:
+    virtual void MakeAll();
+
+public:
+    DECL_FIXEDMEMPOOL_NEWDEL(SwPageFrm)
+
+    SwPageFrm( SwFrmFmt*, SwPageDesc* );
+    SwPageFrm( Sw3FrameIo&, SwLayoutFrm* );
+    ~SwPageFrm();
+
+    //public, damit die ViewShell beim Umschalten vom BrowseMode darauf
+    //zugreifen kann.
+    void PrepareHeader();   //Kopf-/Fusszeilen anlegen/entfernen.
+    void PrepareFooter();
+
+    const SwSortDrawObjs  *GetSortedObjs() const  { return pSortedObjs; }
+          SwSortDrawObjs  *GetSortedObjs()        { return pSortedObjs; }
+
+    void AppendDrawObj( SwDrawContact *pNew );
+    void RemoveDrawObj( SwDrawContact *pToRemove );
+
+    void AppendFly( SwFlyFrm *pNew );
+    void RemoveFly( SwFlyFrm *pToRemove );
+    void MoveFly( SwFlyFrm *pToMove, SwPageFrm *pDest );//optimiertes Remove/Append
+
+    void  SetPageDesc( SwPageDesc *, SwFrmFmt * );
+          SwPageDesc *GetPageDesc() { return pDesc; }
+    const SwPageDesc *GetPageDesc() const { return pDesc; }
+          SwPageDesc *FindPageDesc();
+
+                 SwCntntFrm  *FindLastBodyCntnt();
+    inline       SwCntntFrm  *FindFirstBodyCntnt();
+    inline const SwCntntFrm  *FindFirstBodyCntnt() const;
+    inline const SwCntntFrm  *FindLastBodyCntnt() const;
+
+    //Spezialisiertes GetCntntPos() fuer Felder in Rahmen.
+    void GetCntntPosition( const Point &rPt, SwPosition &rPos ) const;
+
+    BOOL IsEmptyPage() const { return bEmptyPage; } //explizite Leerseite.
+
+    void    UpdateFtnNum();
+
+    //Immer nach dem Paste rufen. Erzeugt die Seitengeb. Rahmen und Formatiert
+    //generischen Inhalt.
+    void PreparePage( BOOL bFtn );
+
+    //Schickt an alle ContentFrames ein Prepare wg. geaenderter Registervorlage
+    void PrepareRegisterChg();
+
+    //Haengt einen Fly an den geeigneten LayoutFrm unterhalb der Seite,
+    //fuer SwFEShell und Modify der Flys.
+    SwFrm *PlaceFly( SwFlyFrm *, SwFrmFmt *, const SwFmtAnchor * );
+
+    virtual void Store( Sw3FrameIo& ) const;
+
+    virtual BOOL GetCrsrOfst( SwPosition *, Point&,
+                              const SwCrsrMoveState* = 0 ) const;
+    virtual void Modify( SfxPoolItem*, SfxPoolItem* );
+        // erfrage vom Client Informationen
+    virtual BOOL GetInfo( SfxPoolItem& ) const;
+
+    virtual void Cut();
+    virtual void Paste( SwFrm* pParent, SwFrm* pSibling = 0 );
+
+    //Umrandungen aller Frms innerhalb der Seite Painten.
+    void PaintAllBorders( const SwRect &rRect ) const;
+
+    //Zeilennummern usw malen
+    void RefreshExtraData( const SwRect & ) const;
+
+    //Hilfslinien malen.
+    void RefreshSubsidiary( const SwRect& ) const;
+
+    //Fussnotenschnittstelle
+    BOOL IsFtnPage() const                                  { return bFtnPage; }
+    BOOL IsEndNotePage() const                              { return bEndNotePage; }
+    void SetFtnPage( BOOL b )                               { bFtnPage = b; }
+    void SetEndNotePage( BOOL b )                           { bEndNotePage = b; }
+
+    inline  const USHORT GetPhyPageNum() const  { return nPhyPageNum;}
+    inline  void SetPhyPageNum( USHORT nNum )   { nPhyPageNum = nNum;}
+    inline  void DecrPhyPageNum()               { --nPhyPageNum;     }
+    inline  void IncrPhyPageNum()               { ++nPhyPageNum;     }
+
+    //Validieren, invalidieren und abfragen des Status der Seite.
+    //Layout/Cntnt und jeweils Fly/nicht Fly werden getrennt betrachtet.
+    inline void InvalidateFlyLayout() const;
+    inline void InvalidateFlyCntnt() const;
+    inline void InvalidateFlyInCnt() const;
+    inline void InvalidateLayout() const;
+    inline void InvalidateCntnt() const;
+    inline void InvalidateSpelling() const;
+    inline void InvalidateAutoCompleteWords() const;
+    inline void ValidateFlyLayout() const;
+    inline void ValidateFlyCntnt() const;
+    inline void ValidateFlyInCnt() const;
+    inline void ValidateLayout() const;
+    inline void ValidateCntnt() const;
+    inline void ValidateSpelling()  const;
+    inline void ValidateAutoCompleteWords() const;
+    inline BOOL IsInvalid() const;
+    inline BOOL IsInvalidFly() const;
+    BOOL IsInvalidFlyLayout() const { return bInvalidFlyLayout; }
+    BOOL IsInvalidFlyCntnt() const { return bInvalidFlyCntnt; }
+    BOOL IsInvalidFlyInCnt() const { return bInvalidFlyInCnt; }
+    BOOL IsInvalidLayout() const { return bInvalidLayout; }
+    BOOL IsInvalidCntnt() const { return (bInvalidCntnt || bInvalidFlyInCnt); }
+    BOOL IsInvalidSpelling() const { return bInvalidSpelling; }
+    BOOL IsInvalidAutoCompleteWords() const { return bInvalidAutoCmplWrds; }
+};
+
+inline SwCntntFrm *SwPageFrm::FindFirstBodyCntnt()
+{
+    SwLayoutFrm *pBody = FindBodyCont();
+    return pBody ? pBody->ContainsCntnt() : 0;
+}
+inline const SwCntntFrm *SwPageFrm::FindFirstBodyCntnt() const
+{
+    const SwLayoutFrm *pBody = FindBodyCont();
+    return pBody ? pBody->ContainsCntnt() : 0;
+}
+inline const SwCntntFrm *SwPageFrm::FindLastBodyCntnt() const
+{
+    return ((SwPageFrm*)this)->FindLastBodyCntnt();
+}
+inline void SwPageFrm::InvalidateFlyLayout() const
+{
+    ((SwPageFrm*)this)->bInvalidFlyLayout = TRUE;
+}
+inline void SwPageFrm::InvalidateFlyCntnt() const
+{
+    ((SwPageFrm*)this)->bInvalidFlyCntnt = TRUE;
+}
+inline void SwPageFrm::InvalidateFlyInCnt() const
+{
+    ((SwPageFrm*)this)->bInvalidFlyInCnt = TRUE;
+}
+inline void SwPageFrm::InvalidateLayout() const
+{
+    ((SwPageFrm*)this)->bInvalidLayout = TRUE;
+}
+inline void SwPageFrm::InvalidateCntnt() const
+{
+    ((SwPageFrm*)this)->bInvalidCntnt = TRUE;
+}
+inline void SwPageFrm::InvalidateSpelling() const
+{
+    ((SwPageFrm*)this)->bInvalidSpelling = TRUE;
+}
+inline void SwPageFrm::InvalidateAutoCompleteWords() const
+{
+    ((SwPageFrm*)this)->bInvalidAutoCmplWrds = FALSE;
+}
+inline void SwPageFrm::ValidateFlyLayout() const
+{
+    ((SwPageFrm*)this)->bInvalidFlyLayout = FALSE;
+}
+inline void SwPageFrm::ValidateFlyCntnt() const
+{
+    ((SwPageFrm*)this)->bInvalidFlyCntnt = FALSE;
+}
+inline void SwPageFrm::ValidateFlyInCnt() const
+{
+    ((SwPageFrm*)this)->bInvalidFlyInCnt = FALSE;
+}
+inline void SwPageFrm::ValidateLayout() const
+{
+    ((SwPageFrm*)this)->bInvalidLayout = FALSE;
+}
+inline void SwPageFrm::ValidateCntnt() const
+{
+    ((SwPageFrm*)this)->bInvalidCntnt = FALSE;
+}
+inline void SwPageFrm::ValidateSpelling() const
+{
+    ((SwPageFrm*)this)->bInvalidSpelling = FALSE;
+}
+inline void SwPageFrm::ValidateAutoCompleteWords() const
+{
+    ((SwPageFrm*)this)->bInvalidAutoCmplWrds = FALSE;
+}
+
+
+inline BOOL SwPageFrm::IsInvalid() const
+{
+    return (bInvalidCntnt || bInvalidLayout || bInvalidFlyInCnt);
+}
+inline BOOL SwPageFrm::IsInvalidFly() const
+{
+    return bInvalidFlyLayout || bInvalidFlyCntnt;
+}
+
+
+
+#endif  //_PAGEFRM_HXX
diff --git a/sw/source/core/inc/pamtyp.hxx b/sw/source/core/inc/pamtyp.hxx
new file mode 100644
index 000000000000..c63f613ad6ef
--- /dev/null
+++ b/sw/source/core/inc/pamtyp.hxx
@@ -0,0 +1,140 @@
+/*************************************************************************
+ *
+ *  $RCSfile: pamtyp.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:21 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _PAMTYP_HXX
+#define _PAMTYP_HXX
+
+#ifndef _TXTCMP_HXX //autogen
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _NODE_HXX
+#include 
+#endif
+#ifndef _STRING_HXX //autogen
+#include 
+#endif
+
+class SwpHints;
+struct SwPosition;
+class SwPaM;
+class SwTxtAttr;
+
+// Funktions-Deklarationen fuer die Move/Find-Methoden vom SwPaM
+
+void GoStartDoc( SwPosition*);
+void GoEndDoc( SwPosition*);
+void GoStartSection( SwPosition*);
+void GoEndSection( SwPosition*);
+FASTBOOL GoInDoc( SwPaM&, SwMoveFn);
+FASTBOOL GoInSection( SwPaM&, SwMoveFn);
+FASTBOOL GoInNode( SwPaM&, SwMoveFn);
+FASTBOOL GoInCntnt( SwPaM&, SwMoveFn);
+const SwTxtAttr* GetFrwrdTxtHint( const SwpHints&, USHORT&, xub_StrLen );
+const SwTxtAttr* GetBkwrdTxtHint( const SwpHints&, USHORT&, xub_StrLen );
+
+FASTBOOL GoNext(SwNode* pNd, SwIndex * pIdx );
+FASTBOOL GoPrevious(SwNode* pNd, SwIndex * pIdx);
+SwCntntNode* GoNextNds( SwNodeIndex * pIdx, FASTBOOL );
+SwCntntNode* GoPreviousNds( SwNodeIndex * pIdx, FASTBOOL );
+
+// --------- Funktionsdefinitionen fuer die SwCrsrShell --------------
+
+FASTBOOL GoPrevPara( SwPaM&, SwPosPara);
+FASTBOOL GoCurrPara( SwPaM&, SwPosPara);
+FASTBOOL GoNextPara( SwPaM&, SwPosPara);
+FASTBOOL GoPrevSection( SwPaM&, SwPosSection);
+FASTBOOL GoCurrSection( SwPaM&, SwPosSection);
+FASTBOOL GoNextSection( SwPaM&, SwPosSection);
+
+
+// ------------ Typedefiniton fuer Funktionen ----------------------
+
+typedef FASTBOOL (*GoNd)( SwNode*, SwIndex* );
+typedef SwCntntNode* (*GoNds)( SwNodeIndex*, FASTBOOL );
+typedef void (*GoDoc)( SwPosition* );
+typedef void (*GoSection)( SwPosition* );
+typedef FASTBOOL (SwPosition:: *CmpOp)( const SwPosition& ) const;
+typedef const SwTxtAttr* (*GetHint)( const SwpHints&, USHORT&, xub_StrLen );
+typedef int (SearchText:: *SearchTxt)( const String&, xub_StrLen*, xub_StrLen* );
+typedef void (SwNodes:: *MvSection)( SwNodeIndex * ) const;
+
+
+struct SwMoveFnCollection
+{
+    GoNd      fnNd;
+    GoNds     fnNds;
+    GoDoc     fnDoc;
+    GoSection fnSections;
+    CmpOp     fnCmpOp;
+    GetHint   fnGetHint;
+    SearchTxt fnSearch;
+    MvSection fnSection;
+};
+
+// --------- Funktionsdefinitionen fuers Suchen --------------
+SwCntntNode* GetNode( SwPaM&, FASTBOOL&, SwMoveFn, FASTBOOL bInReadOnly = FALSE );
+
+
+
+#endif
diff --git a/sw/source/core/inc/ptqueue.hxx b/sw/source/core/inc/ptqueue.hxx
new file mode 100644
index 000000000000..e06ebb8f25e9
--- /dev/null
+++ b/sw/source/core/inc/ptqueue.hxx
@@ -0,0 +1,96 @@
+/*************************************************************************
+ *
+ *  $RCSfile: ptqueue.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:21 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _PTQUEUE_HXX
+#define _PTQUEUE_HXX
+
+//Leider vertragen wir es nicht so gut, wenn wir mehr als ein Paint
+//gleichzeitig verarbeiten sollen. Insbesondere beim Drucken kommt dies
+//leider haeufig vor.
+//SwRootFrm::Paint() stellt fest, dass es zum zweitenmal gerufen wird, und
+//traegt das Rechteck sowie die dazugehoerige Shell in den PaintCollector ein.
+//Diejenigen stellen, die moeglicherweise das doppelte Paint "Verursachen"
+//brauchen nur noch zum richtigen Zeitpunkt die gesammelten Paints verarbeiten.
+//Derzeit bietet sich der Druckvorgang an, und zwar nach dem Druck von jeweils
+//einer Seite.
+
+//Das Invalidieren der Windows direkt aus dem RootFrm::Paint hat sich als nicht
+//erfolgreich erwiesen, weil die Paints dann in den allermeisten Faellen
+//wiederum zu einem sehr unguenstigen Zeitpunkt ankommen.
+//Nach dem Druck jeder Seite ein Update auf alle Fenster auszuloesen scheint
+//auch nicht angeraten, weil einerseits die edit-Windows nicht im direkten
+//Zugriff sind und anderseits das notwendige Update je nach Plattform extrem
+//teuer werden kann.
+
+class SwQueuedPaint;
+class ViewShell;
+class SwRect;
+
+class SwPaintQueue
+{
+public:
+    static SwQueuedPaint *pQueue;
+
+    static void Add( ViewShell *pSh, const SwRect &rNew );
+    static void Remove( ViewShell *pSh );
+    static void Repaint();
+};
+
+#endif
diff --git a/sw/source/core/inc/rootfrm.hxx b/sw/source/core/inc/rootfrm.hxx
new file mode 100644
index 000000000000..5fbd909576d4
--- /dev/null
+++ b/sw/source/core/inc/rootfrm.hxx
@@ -0,0 +1,342 @@
+/*************************************************************************
+ *
+ *  $RCSfile: rootfrm.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:21 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _ROOTFRM_HXX
+#define _ROOTFRM_HXX
+
+#include "layfrm.hxx"
+
+class SwCntntFrm;
+class ViewShell;
+class SdrPage;
+class SwFrmFmt;
+class SwPaM;
+class SwCursor;
+class SwShellCrsr;
+class SwTableCursor;
+class SwRegionRects;
+class Sw3FrameIo;
+class OutputDevice;
+class SwLayVout;
+class SwDestroyList;
+class SwCurrShells;
+struct SwPosition;
+struct SwCrsrMoveState;
+
+#define HACK_TABLEMODE_INIT         0
+#define HACK_TABLEMODE_LOCKLINES    1
+#define HACK_TABLEMODE_PAINTLINES   2
+#define HACK_TABLEMODE_UNLOCKLINES  3
+#define HACK_TABLEMODE_EXIT         4
+
+#define INV_SIZE    1
+#define INV_PRTAREA 2
+#define INV_POS     4
+#define INV_TABLE   8
+#define INV_SECTION 16
+#define INV_LINENUM 32
+
+class SwRootFrm: public SwLayoutFrm
+{
+    //Muss das Superfluous temporaer abschalten.
+    friend void AdjustSizeChgNotify( SwRootFrm *pRoot );
+
+    //Pflegt pLastPage (Cut() und Paste() vom SwPageFrm
+    friend inline void SetLastPage( SwPageFrm* );
+
+    // Fuer das Anlegen und Zerstoeren des virtuellen Outputdevice-Managers
+    friend void _FrmInit();     //erzeugt pVout
+    friend void _FrmFinit();    //loescht pVout
+
+    static SwLayVout     *pVout;
+    static BOOL           bInPaint;     //Schutz gegen doppelte Paints.
+    static BOOL           bNoVirDev;    //Bei SystemPaints kein virt. Device
+
+    BOOL    bCheckSuperfluous   :1; //Leere Seiten suchen?
+    BOOL    bIdleFormat         :1; //Idle-Formatierer anwerfen?
+    BOOL    bBrowseWidthValid   :1; //Ist nBrowseWidth gueltig?
+    BOOL    bDummy2             :1; //Unbenutzt
+    BOOL    bTurboAllowed       :1;
+    BOOL    bAssertFlyPages     :1; //Ggf. weitere Seiten fuer Flys einfuegen?
+    BOOL    bDummy              :1; //Unbenutzt
+    BOOL    bIsVirtPageNum      :1; //gibt es eine virtuelle Seitennummer ?
+    BOOL    bIsNewLayout        :1; //Layout geladen oder neu erzeugt.
+    BOOL    bCallbackActionEnabled:1; //Keine Action in Benachrichtung erwuenscht
+                                    //siehe dcontact.cxx, ::Changed()
+
+    //Fuer den BrowseMode. nBrowseWidth ist die Aeussere Kante des am weitesten
+    //rechts stehenden Objectes. Die rechte Kante der Seiten soll im BrowseMode
+    //nicht kleiner werden als dieser Wert.
+    long    nBrowseWidth;
+
+    //Wenn nur _ein: CntntFrm zu formatieren ist, so steht dieser in pTurbo.
+    const SwCntntFrm *pTurbo;
+
+    //Die letzte Seite wollen wir uns nicht immer muehsam zusammensuchen.
+    SwPageFrm *pLastPage;
+
+    //Die Root kuemmert sich nun auch um den Shell-Zugriff. Ueber das Dokument
+    //sollte man auch immer an die Root herankommen und somit auch immer
+    //einen Zugriff auf die Shell haben.
+    //Der Pointer pCurrShell ist der Pointer auf irgendeine der Shells fuer
+    //das Dokument
+    //Da es durchaus nicht immer egal ist, auf welcher Shell gearbeitet wird,
+    //ist es notwendig die aktive Shell zu kennen. Das wird dadurch angenaehert,
+    //dass der Pointer pCurrShell immer dann umgesetzt wird, wenn eine
+    //Shell den Fokus erhaelt (FEShell). Zusaetzlich wird der Pointer
+    //Temporaer von SwCurrShell umgesetzt, dieses wird typischerweise
+    //ueber das Macro SET_CURR_SHELL erledigt. Makro + Klasse sind in der
+    //ViewShell zu finden. Diese Objekte koennen auch verschachtelt (auch fuer
+    //unterschiedliche Shells) erzeugt werden. Sie werden im Array pCurrShells
+    //gesammelt.
+    //Weiterhin kann es noch vorkommen, dass eine Shell aktiviert wird,
+    //waehrend noch ein CurrShell-Objekt "aktiv" ist. Dieses wird dann in
+    //pWaitingCurrShell eingetragen und vom letzten DTor der CurrShell
+    //"aktiviert".
+    //Ein weiteres Problem ist dass Zerstoeren einer Shell waehrend sie aktiv
+    //ist. Der Pointer pCurrShell wird dann auf eine beliebige andere Shell
+    //umgesetzt.
+    //Wenn zum Zeitpunkt der zerstoerung einer Shell diese noch in irgendwelchen
+    //CurrShell-Objekten referenziert wird, so wird auch dies aufgeklart.
+    friend class CurrShell;
+    friend void SetShell( ViewShell *pSh );
+    friend void InitCurrShells( SwRootFrm *pRoot );
+    ViewShell *pCurrShell;
+    ViewShell *pWaitingCurrShell;
+    SwCurrShells *pCurrShells;
+
+    //Eine Page im DrawModel pro Dokument, hat immer die Groesse der Root.
+    SdrPage *pDrawPage;
+
+    SwDestroyList* pDestroy;
+
+    USHORT  nPhyPageNums;           //Anzahl der Seiten.
+
+    void ImplCalcBrowseWidth();
+    void ImplInvalidateBrowseWidth();
+
+    void _DeleteEmptySct(); // zerstoert ggf. die angemeldeten SectionFrms
+    void _RemoveFromList( SwSectionFrm* pSct ); // entfernt SectionFrms aus der Delete-Liste
+
+protected:
+
+    virtual void MakeAll();
+
+public:
+
+    //MasterObjekte aus der Page entfernen (von den Ctoren gerufen).
+    static void RemoveMasterObjs( SdrPage *pPg );
+
+    //Virtuelles Device ausgeben (z.B. wenn Animationen ins Spiel kommen)
+    static BOOL FlushVout();
+    //Clipping sparen, wenn im Vout eh genau das Cliprechteck ausgegeben wird
+    static BOOL HasSameRect( const SwRect& rRect );
+
+    SwRootFrm( SwFrmFmt*, ViewShell* );
+    SwRootFrm( Sw3FrameIo&, SwLayoutFrm* );
+    ~SwRootFrm();
+
+    ViewShell *GetCurrShell() const { return pCurrShell; }
+    void SwRootFrm::DeRegisterShell( ViewShell *pSh );
+
+    //Start-/EndAction fuer alle Shells auf moeglichst hoeher
+    //(Shell-Ableitungs-)Ebene aufsetzen. Fuer die StarONE Anbindung, die
+    //die Shells nicht dirkt kennt.
+    //Der ChangeLinkd der CrsrShell (UI-Benachrichtigung) wird im EndAllAction
+    //automatisch gecallt.
+    void StartAllAction();
+    void EndAllAction( BOOL bVirDev = FALSE );
+
+    // fuer bestimmte UNO-Aktionen (Tabellencursor) ist es notwendig, dass alle Actions
+    // kurzfristig zurueckgesetzt werden. Dazu muss sich jede ViewShell ihren alten Action-zaehler
+    // merken
+    void UnoRemoveAllActions();
+    void UnoRestoreAllActions();
+
+    const SdrPage* GetDrawPage() const { return pDrawPage; }
+          SdrPage* GetDrawPage()       { return pDrawPage; }
+          void     SetDrawPage( SdrPage* pNew ){ pDrawPage = pNew; }
+
+    virtual void  Store( Sw3FrameIo& ) const;
+    virtual BOOL  GetCrsrOfst( SwPosition *, Point&,
+                               const SwCrsrMoveState* = 0 ) const;
+    virtual void  Paint( const SwRect& ) const;
+    virtual SwTwips ShrinkFrm( SwTwips, const SzPtr,
+                               BOOL bTst = FALSE, BOOL bInfo = FALSE );
+    virtual SwTwips GrowFrm  ( SwTwips, const SzPtr,
+                               BOOL bTst = FALSE, BOOL bInfo = FALSE );
+#ifndef PRODUCT
+    virtual void Cut();
+    virtual void Paste( SwFrm* pParent, SwFrm* pSibling = 0 );
+#endif
+
+    Point  GetNextCntntPos( const Point &rPoint, BOOL bIgnoreTblHdln ) const;
+    Point  GetPrevCntntPos( const Point &rPoint ) const;
+    void   SetFixSize( SzPtr );
+    virtual void ChgSize( const Size& aNewSize );
+
+    inline void SetIdleFlags();
+           BOOL IsIdleFormat()  const { return bIdleFormat; }
+           void ResetIdleFormat()     { bIdleFormat = FALSE; }
+
+    //Sorgt dafuer, dass alle gewuenschten Seitengebunden Flys eine Seite finden
+    void SetAssertFlyPages() { bAssertFlyPages = TRUE; }
+    void AssertFlyPages();
+    BOOL IsAssertFlyPages()  { return bAssertFlyPages; }
+
+    //Stellt sicher, dass ab der uebergebenen Seite auf allen Seiten die
+    //Seitengebundenen Rahmen auf der richtigen Seite (Seitennummer) stehen.
+    void AssertPageFlys( SwPageFrm * );
+
+    //Saemtlichen Inhalt invalidieren, Size oder PrtArea
+    void InvalidateAllCntnt( BYTE nInvalidate = INV_SIZE );
+
+    //Ueberfluessige Seiten entfernen.
+    void SetSuperfluous()      { bCheckSuperfluous = TRUE; }
+    BOOL IsSuperfluous() const { return bCheckSuperfluous; }
+    void RemoveSuperfluous();
+
+    //abfragen/setzen der aktuellen Seite und der Gesamtzahl der Seiten.
+    //Es wird soweit wie notwendig Formatiert.
+    USHORT  GetCurrPage( const SwPaM* ) const;
+    USHORT  SetCurrPage( SwCursor*, USHORT nPageNum );
+    Point   GetPagePos( USHORT nPageNum ) const;
+    USHORT  GetPageNum() const      { return nPhyPageNums; }
+    void    DecrPhyPageNums()       { --nPhyPageNums; }
+    void    IncrPhyPageNums()       { ++nPhyPageNums; }
+    BOOL    IsVirtPageNum() const   { return bIsVirtPageNum; }
+    inline  void SetVirtPageNum( const BOOL bOf ) const;
+
+    //Der Crsr moechte die zu selektierenden Bereiche wissen.
+    void CalcFrmRects( SwShellCrsr&, BOOL bIsTblSel );
+    //Ermitteln der von der Selection eingeschl. Zellen.
+    void MakeTblCrsrs( SwTableCursor& );
+
+    void DisallowTurbo()  const { ((SwRootFrm*)this)->bTurboAllowed = FALSE; }
+    void ResetTurboFlag() const { ((SwRootFrm*)this)->bTurboAllowed = TRUE; }
+    BOOL IsTurboAllowed() const { return bTurboAllowed; }
+    void SetTurbo( const SwCntntFrm *pCntnt ) { pTurbo = pCntnt; }
+    void ResetTurbo() { pTurbo = 0; }
+    const SwCntntFrm *GetTurbo() { return pTurbo; }
+
+    //Fussnotennummern aller Seiten auf den neuesten Stand bringen.
+    void UpdateFtnNums();           //nur bei Seitenweiser Nummerierung!
+
+    //Alle Fussnoten (nicht etwa die Referenzen) entfernen.
+    void RemoveFtns( SwPageFrm *pPage = 0, BOOL bPageOnly = FALSE,
+                     BOOL bEndNotes = FALSE );
+    void CheckFtnPageDescs( BOOL bEndNote );
+
+    const SwPageFrm *GetLastPage() const { return pLastPage; }
+          SwPageFrm *GetLastPage()       { return pLastPage; }
+
+    static BOOL IsInPaint() { return bInPaint; }
+
+    static void SetNoVirDev( const BOOL bNew ) { bNoVirDev = bNew; }
+
+    inline long GetBrowseWidth() const;
+    void SetBrowseWidth( long n ) { bBrowseWidthValid = TRUE; nBrowseWidth = n;}
+    inline void InvalidateBrowseWidth();
+
+    void HackPrepareLongTblPaint( int nMode );
+
+    BOOL IsNewLayout() const { return bIsNewLayout; }
+    void ResetNewLayout()    { bIsNewLayout = FALSE;}
+
+    // Hier werden leere SwSectionFrms zur Zerstoerung angemeldet
+    // und spaeter zerstoert oder wieder abgemeldet
+    void InsertEmptySct( SwSectionFrm* pDel );
+    void DeleteEmptySct() { if( pDestroy ) _DeleteEmptySct(); }
+    void RemoveFromList( SwSectionFrm* pSct ) { if( pDestroy ) _RemoveFromList( pSct ); }
+#ifndef PRODUCT
+    // Wird zur Zeit nur fuer ASSERTs benutzt:
+    BOOL IsInDelList( SwSectionFrm* pSct ) const; // Ist der SectionFrm in der Liste enthalten?
+#endif
+
+
+    void SetCallbackActionEnabled( BOOL b ) { bCallbackActionEnabled = b; }
+    BOOL IsCallbackActionEnabled() const    { return bCallbackActionEnabled; }
+};
+
+inline long SwRootFrm::GetBrowseWidth() const
+{
+    if ( !bBrowseWidthValid )
+        ((SwRootFrm*)this)->ImplCalcBrowseWidth();
+    return nBrowseWidth;
+}
+
+inline void SwRootFrm::InvalidateBrowseWidth()
+{
+    if ( bBrowseWidthValid )
+        ImplInvalidateBrowseWidth();
+}
+
+inline void SwRootFrm::SetIdleFlags()
+{
+    bIdleFormat = TRUE;
+}
+
+inline  void SwRootFrm::SetVirtPageNum( const BOOL bOf) const
+{
+    ((SwRootFrm*)this)->bIsVirtPageNum = bOf;
+}
+
+#endif  //_ROOTFRM_HXX
+
diff --git a/sw/source/core/inc/rowfrm.hxx b/sw/source/core/inc/rowfrm.hxx
new file mode 100644
index 000000000000..d31b35cfc2ae
--- /dev/null
+++ b/sw/source/core/inc/rowfrm.hxx
@@ -0,0 +1,112 @@
+/*************************************************************************
+ *
+ *  $RCSfile: rowfrm.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:21 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _ROWFRM_HXX
+#define _ROWFRM_HXX
+
+#ifndef _SVMEMPOOL_HXX //autogen
+#include 
+#endif
+
+#include "layfrm.hxx"
+
+class SwTableLine;
+class Sw3FrameIo;
+class SwBorderAttrs;
+
+class SwRowFrm: public SwLayoutFrm
+{
+    virtual void Format( const SwBorderAttrs *pAttrs = 0 );
+        //Aendern nur die Framesize, nicht die PrtArea-SSize
+    virtual SwTwips ShrinkFrm( SwTwips, const SzPtr,
+                               BOOL bTst = FALSE, BOOL bInfo = FALSE );
+    virtual SwTwips GrowFrm  ( SwTwips, const SzPtr,
+                               BOOL bTst = FALSE, BOOL bInfo = FALSE );
+
+    const SwTableLine *pTabLine;
+
+protected:
+    virtual void MakeAll();
+
+public:
+    SwRowFrm( const SwTableLine & );
+    SwRowFrm( Sw3FrameIo&, SwLayoutFrm* );
+    ~SwRowFrm();
+
+    virtual void   Store( Sw3FrameIo& ) const;
+
+    virtual void Cut();
+    virtual void  Modify( SfxPoolItem*, SfxPoolItem* );
+
+    //Zum Anmelden der Flys nachdem eine Zeile erzeugt _und_ eingefuegt wurde.
+    //Muss vom Erzeuger gerufen werden, denn erst nach dem Konstruieren wird
+    //Das Teil gepastet; mithin ist auch erst dann die Seite zum Anmelden der
+    //Flys erreichbar.
+    void RegistFlys( SwPageFrm *pPage = 0 );
+
+    const SwTableLine *GetTabLine() const { return pTabLine; }
+
+    //Passt die Zellen auf die aktuelle Hoehe an, invalidiert die Zellen
+    //wenn die Direction nicht der Hoehe entspricht.
+    void AdjustCells( const SwTwips nHeight, const BOOL bHeight );
+    DECL_FIXEDMEMPOOL_NEWDEL(SwRowFrm)
+};
+
+#endif
diff --git a/sw/source/core/inc/rvp_mark.hxx b/sw/source/core/inc/rvp_mark.hxx
new file mode 100644
index 000000000000..b323e66e0003
--- /dev/null
+++ b/sw/source/core/inc/rvp_mark.hxx
@@ -0,0 +1,77 @@
+/*************************************************************************
+ *
+ *  $RCSfile: rvp_mark.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:21 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _RVP_MARK_HXX
+#define _RVP_MARK_HXX
+
+class OutputDevice;
+class SwRVPMarker
+{
+    const OutputDevice *pOutp;
+public:
+    SwRVPMarker( const OutputDevice* pOut ) : pOutp( pOut )
+        { SwRVPMarker::Mark( pOutp ); }
+    ~SwRVPMarker() { SwRVPMarker::Mark( pOutp ); }
+    static void Mark( const OutputDevice* pOut );
+};
+
+
+#endif  //_RVP_MARK_HXX
diff --git a/sw/source/core/inc/scrrect.hxx b/sw/source/core/inc/scrrect.hxx
new file mode 100644
index 000000000000..bee0478f3a98
--- /dev/null
+++ b/sw/source/core/inc/scrrect.hxx
@@ -0,0 +1,158 @@
+/*************************************************************************
+ *
+ *  $RCSfile: scrrect.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:21 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _SCRRECT_HXX
+#define _SCRRECT_HXX
+
+
+#ifndef _SVARRAY_HXX //autogen
+#include 
+#endif
+#include "swrect.hxx"
+#ifndef _SWTYPES_HXX
+#include 
+#endif
+
+class SwStripe
+{
+    SwTwips nY;
+    SwTwips nHeight;
+public:
+    inline SwStripe( SwTwips nPos, SwTwips nHght )
+        : nY( nPos ), nHeight( nHght ) {}
+    inline SwTwips GetY() const { return nY; }
+    inline SwTwips& Y() { return nY; }
+    inline SwTwips GetHeight() const { return nHeight; }
+    inline SwTwips& Height() { return nHeight; }
+    inline SwTwips GetBottom() const { return nHeight ? nY + nHeight - 1 : nY; }
+    inline BOOL operator<( const SwStripe &rTst ) const
+        { return nY < rTst.nY || ( nY == rTst.nY && nHeight > rTst.nHeight ); }
+    inline BOOL operator==( const SwStripe& rTst ) const
+        { return nY == rTst.nY && nHeight == rTst.nHeight; }
+};
+
+SV_DECL_VARARR( SwStripeArr, SwStripe, 1, 4 );
+
+class SwStripes : public SwStripeArr, public SwStripe
+{
+    SwTwips nMin;       // Left minimum
+    SwTwips nMax;       // Right maximum
+public:
+    SwStripes( const SwRect& rRect ) : SwStripe( rRect.Top(), rRect.Height() ),
+        nMin(rRect.Left()), nMax(rRect.Left() + rRect.Width()) {}
+    SwStripes& operator+=( const SwStripes& rOther );
+    BOOL Recalc();
+    inline SwTwips GetMin() const { return nMin; }
+    inline SwTwips GetMax() const { return nMax; }
+    inline void SetMin( const SwTwips nNew ) { nMin = nNew; }
+    inline void SetMax( const SwTwips nNew ) { nMax = nNew; }
+    inline void ChkMin( const SwTwips nNew ) { if( nNew < nMin ) nMin = nNew; }
+    inline void ChkMax( const SwTwips nNew ) { if( nNew > nMax ) nMax = nNew; }
+    inline SwTwips GetRight() const { return nMax > nMin ? nMax - 1 : nMax; }
+    inline SwTwips GetWidth() const { return nMax - nMin; }
+};
+
+class SwScrollColumn
+{
+    SwTwips nX;
+    SwTwips nWidth;
+    SwTwips nOffs;
+public:
+    inline SwScrollColumn( const SwRect& rRect, SwTwips nOff )
+        : nX( rRect.Left() ), nWidth( rRect.Width() ), nOffs( nOff ) {}
+    inline SwScrollColumn( const SwScrollColumn& rCol )
+        : nX( rCol.nX ), nWidth( rCol.nWidth ), nOffs( rCol.nOffs ) {}
+    inline SwTwips GetX() const { return nX; }
+    inline SwTwips GetWidth() const { return nWidth; }
+    inline SwTwips GetOffs() const { return nOffs; }
+    inline void ClrOffs() { nOffs = 0; }
+    inline SwTwips GetRight() const { return nWidth ? nX + nWidth - 1 : nX; }
+    inline BOOL operator<( const SwScrollColumn &rTst ) const
+        { return nX < rTst.nX || ( nX == rTst.nX && ( nWidth < rTst.nWidth ||
+          ( nWidth == rTst.nWidth && nOffs < rTst.nOffs ) ) ); }
+    inline BOOL operator==( const SwScrollColumn &rTst ) const
+        { return nX == rTst.nX && nWidth == rTst.nWidth && nOffs == rTst.nOffs;}
+};
+
+typedef SwStripes* SwStripesPtr;
+SV_DECL_PTRARR_SORT(SwScrollStripes, SwStripesPtr, 1, 4)
+
+class SwScrollArea : public SwScrollColumn, public SwScrollStripes
+{
+public:
+    void SmartInsert( SwStripes* pStripes );
+    void Add( SwScrollArea *pScroll );
+    inline SwScrollArea( const SwScrollColumn &rCol, SwStripes* pStripes )
+        : SwScrollColumn( rCol )
+        { Insert( pStripes ); }
+    BOOL Compress();
+};
+
+typedef SwScrollArea* SwScrollAreaPtr;
+SV_DECL_PTRARR_SORT(SScrAreas,SwScrollAreaPtr,1,2);
+
+class SwScrollAreas : public SScrAreas
+{
+public:
+    void InsertCol( const SwScrollColumn &rCol, SwStripes *pStripes );
+};
+
+
+#endif //_SCRRECT_HXX
diff --git a/sw/source/core/inc/sectfrm.hxx b/sw/source/core/inc/sectfrm.hxx
new file mode 100644
index 000000000000..59aa69c7aea9
--- /dev/null
+++ b/sw/source/core/inc/sectfrm.hxx
@@ -0,0 +1,197 @@
+/*************************************************************************
+ *
+ *  $RCSfile: sectfrm.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:21 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _SECTFRM_HXX
+#define _SECTFRM_HXX
+
+#ifndef _SVMEMPOOL_HXX //autogen
+#include 
+#endif
+
+#include "layfrm.hxx"
+#include "flowfrm.hxx"
+
+class SwSection;
+class SwSectionFmt;
+class SwAttrSetChg;
+class SwFtnContFrm;
+class SwFtnFrm;
+class SwLayouter;
+
+#define FINDMODE_ENDNOTE 1
+#define FINDMODE_LASTCNT 2
+#define FINDMODE_MYLAST  4
+
+class SwSectionFrm: public SwLayoutFrm, public SwFlowFrm
+{
+    SwSection* pSection;
+
+    void _UpdateAttr( SfxPoolItem*, SfxPoolItem*, BYTE &,
+                      SwAttrSetChg *pa = 0, SwAttrSetChg *pb = 0 );
+    void _Cut( BOOL bRemove );
+    // Is there a FtnContainer?
+    // An empty sectionfrm without FtnCont is superfluous
+    BOOL IsSuperfluous() const { return !ContainsAny() && !ContainsFtnCont(); }
+    void CalcFtnAtEndFlag();
+    void CalcEndAtEndFlag();
+    BOOL IsAncestorOf( const SwSection* pSect ) const;
+    BOOL IsAncestorOf( const SwSectionFrm* pSct ) const
+        { return IsAncestorOf( pSct->pSection ); }
+    const SwSectionFmt* _GetEndSectFmt() const;
+    BOOL IsEndnoteAtMyEnd() const;
+protected:
+    virtual void MakeAll();
+    virtual BOOL ShouldBwdMoved( SwLayoutFrm *pNewUpper, BOOL bHead, BOOL &rReformat );
+    virtual void Format( const SwBorderAttrs *pAttrs = 0 );
+public:
+    SwSectionFrm( SwSection & );                 //Inhalt wird nicht erzeugt!
+    SwSectionFrm( SwSectionFrm &, BOOL bMaster );//_Nur_ zum Erzeugen von Master/Follows
+    SwSectionFrm( Sw3FrameIo&, SwLayoutFrm* );
+    ~SwSectionFrm();
+
+    virtual void Store( Sw3FrameIo& ) const;
+    virtual void Cut();
+    virtual void Paste( SwFrm* pParent, SwFrm* pSibling = 0 );
+    virtual void Modify( SfxPoolItem*, SfxPoolItem* );
+
+    inline const SwSectionFrm *GetFollow() const;
+    inline       SwSectionFrm *GetFollow();
+    inline const SwSectionFrm *FindMaster() const;
+    inline       SwSectionFrm *FindMaster();
+                 SwCntntFrm *FindLastCntnt( BYTE nMode = 0 );
+    inline const SwCntntFrm *FindLastCntnt( BYTE nMode = 0 ) const;
+    inline SwSection* GetSection() { return pSection; }
+    inline const SwSection* GetSection() const { return pSection; }
+    inline void ColLock()       { bColLocked = TRUE; }
+    inline void ColUnlock()     { bColLocked = FALSE; }
+
+    void CalcFtnCntnt();
+    void SimpleFormat();
+    BOOL IsDescendantFrom( const SwSectionFmt* pSect ) const;
+    BOOL HasToBreak( const SwFrm* pFrm ) const;
+    void MergeNext( SwSectionFrm* pNxt );
+    //Zerlegt den pFrm umgebenden SectionFrm in zwei Teile,
+    //pFrm an den Anfang des 2. Teils
+    BOOL SplitSect( SwFrm* pFrm, BOOL bApres );
+    void DelEmpty( BOOL bRemove );  // wie Cut(), Follow-Verkettung wird aber mitgepflegt
+    BOOL IsToIgnore() const         // Keine Groesse, kein Inhalt, muss ignoriert werden
+    { return !Frm().Height() && !ContainsCntnt(); }
+    SwSectionFrm *FindSectionMaster();
+    SwSectionFrm *FindFirstSectionMaster();
+    SwFtnContFrm* ContainsFtnCont( const SwFtnContFrm* pCont = NULL ) const;
+    BOOL Growable() const;
+    SwTwips _Shrink( SwTwips, const SzPtr, BOOL bTst );
+    SwTwips _Grow  ( SwTwips, const SzPtr, BOOL bTst );
+
+    // A sectionfrm has to maximize, if he has a follow or a ftncontainer at
+    // the end of the page. A superfluous follow will be ignored,
+    // if bCheckFollow is set.
+    BOOL ToMaximize( BOOL bCheckFollow ) const;
+    inline BOOL _ToMaximize() const
+        { if( !pSection ) return FALSE; return ToMaximize( FALSE ); }
+    BOOL MoveAllowed( const SwFrm* ) const;
+    BOOL CalcMinDiff( SwTwips& rMinDiff ) const;
+    // Uebergibt man kein bOverSize bzw. FALSE, so ist der Returnwert
+    // >0 fuer Undersized-Frames, ==0 sonst.
+    // Uebergibt man TRUE, so kann es auch einen negativen Returnwert geben,
+    // wenn der SectionFrm nicht vollstaendig ausgefuellt ist, was z.B. bei
+    // SectionFrm mit Follow meist vorkommt. Benoetigt wird dies im
+    // FormatWidthCols, um "Luft" aus den Spalten zu lassen.
+    long Undersize( BOOL bOverSize = FALSE );
+    // Groesse an die Umgebung anpassen
+    void _CheckClipping( BOOL bGrow, BOOL bMaximize );
+
+    void InvalidateFtnPos();
+    void CollectEndnotes( SwLayouter* pLayouter );
+    const SwSectionFmt* GetEndSectFmt() const
+        { if( IsEndnAtEnd() ) return _GetEndSectFmt(); return NULL; }
+
+    static void MoveCntntAndDelete( SwSectionFrm* pDel, BOOL bSave );
+    DECL_FIXEDMEMPOOL_NEWDEL(SwSectionFrm)
+};
+
+typedef SwSectionFrm* SwSectionFrmPtr;
+SV_DECL_PTRARR_SORT( SwDestroyList, SwSectionFrmPtr, 1, 5)
+
+inline const SwSectionFrm *SwSectionFrm::GetFollow() const
+{
+    return (const SwSectionFrm*)SwFlowFrm::GetFollow();
+}
+inline SwSectionFrm *SwSectionFrm::GetFollow()
+{
+    return (SwSectionFrm*)SwFlowFrm::GetFollow();
+}
+
+inline const SwSectionFrm *SwSectionFrm::FindMaster() const
+{
+    return (const SwSectionFrm*)SwFlowFrm::FindMaster();
+}
+inline SwSectionFrm *SwSectionFrm::FindMaster()
+{
+    return (SwSectionFrm*)SwFlowFrm::FindMaster();
+}
+
+inline const SwCntntFrm *SwSectionFrm::FindLastCntnt( BYTE nMode ) const
+{
+    return ((SwSectionFrm*)this)->FindLastCntnt( nMode );
+}
+
+
+#endif  //_SECTFRM_HXX
diff --git a/sw/source/core/inc/swblocks.hxx b/sw/source/core/inc/swblocks.hxx
new file mode 100644
index 000000000000..8fb0f9e2e4ab
--- /dev/null
+++ b/sw/source/core/inc/swblocks.hxx
@@ -0,0 +1,260 @@
+/*************************************************************************
+ *
+ *  $RCSfile: swblocks.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:21 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _SWBLOCKS_HXX
+#define _SWBLOCKS_HXX
+
+#ifndef _DATE_HXX //autogen
+#include 
+#endif
+#ifndef _PERSIST_HXX //autogen
+#include 
+#endif
+#ifndef _SVARRAY_HXX //autogen
+#include 
+#endif
+
+class SwPaM;
+class SwDoc;
+class SvxMacroTableDtor;
+
+// Name eines Textblocks:
+
+class SwBlockName
+{
+    friend class SwImpBlocks;
+    friend class Sw2TextBlocks;
+    USHORT nHashS, nHashL;              // Hash-Codes zum Checken
+    long   nPos;                        // Dateiposition (SW2-Format)
+public:
+    String aShort;                      // Kurztext
+    String aLong;                       // Langtext
+    BOOL bIsOnlyTxtFlagInit : 1;        // ist das Flag gueltig?
+    BOOL bIsOnlyTxt : 1;                // Text ohne Formatierung
+    BOOL bInPutMuchBlocks : 1;          // put serveral block entries
+
+    SwBlockName( const String& rShort, const String& rLong, long n );
+
+    // fuer das Einsortieren in das Array
+    int operator==( const SwBlockName& r ) { return aShort == r.aShort; }
+    int operator< ( const SwBlockName& r ) { return aShort <  r.aShort; }
+};
+
+SV_DECL_PTRARR_SORT( SwBlockNames, SwBlockName*, 10, 10 );
+
+
+class SwImpBlocks
+{
+    friend class SwTextBlocks;
+protected:
+    String aFile;                       // physikalischer Dateiname
+    String aName;                       // logischer Name der Datei
+    String aCur;                        // aktueller Text
+    String aShort, aLong;               // Kurz- und Langname (PutDoc)
+    SwBlockNames aNames;                // Liste aller Bausteine
+    Date aDateModified;                 // fuers abgleichen bei den Aktionen
+    Time aTimeModified;
+    SwDoc* pDoc;                        // Austauschdokument
+    USHORT nCur;                        // aktueller Index
+    BOOL bReadOnly : 1;
+    BOOL bInPutMuchBlocks : 1;          // put serveral block entries
+    BOOL bInfoChanged : 1;              // any Info of TextBlock is changed
+
+    SwImpBlocks( const String&, BOOL = FALSE );
+    virtual ~SwImpBlocks();
+
+    static short GetFileType( const String& );
+#define SWBLK_NO_FILE   0               // nicht da
+#define SWBLK_NONE      1               // keine TB-Datei
+#define SWBLK_SW2       2               // SW2-Datei
+#define SWBLK_SW3       3               // SW3-Datei
+
+    void   ClearDoc();                  // Doc-Inhalt loeschen
+    SwPaM* MakePaM();                   // PaM ueber Doc aufspannen
+    void   AddName( const String&, const String&, BOOL bOnlyTxt = FALSE );
+    BOOL   IsFileChanged() const;
+    void   Touch();
+
+public:
+    static USHORT Hash( const String& );        // Hashcode fuer Blocknamen
+    USHORT GetCount() const;                    // Anzahl Textbausteine ermitteln
+    USHORT GetIndex( const String& ) const;     // Index fuer Kurznamen ermitteln
+    USHORT GetLongIndex( const String& ) const; //Index fuer Langnamen ermitteln
+    const String& GetShortName( USHORT ) const; // Kurzname fuer Index zurueck
+    const String& GetLongName( USHORT ) const;  // Langname fuer Index zurueck
+
+    const String& GetFileName() const {return aFile;}   // phys. Dateinamen liefern
+    void SetName( const String& rName )                 // logic name
+        { aName = rName; bInfoChanged = TRUE; }
+
+    virtual BOOL IsOld() const = 0;
+
+    virtual ULONG Delete( USHORT ) = 0;
+    virtual ULONG Rename( USHORT, const String&, const String& ) = 0;
+    virtual ULONG CopyBlock( SwImpBlocks& rImp, String& rShort, const String& rLong) = 0;
+    virtual ULONG GetDoc( USHORT ) = 0;
+    virtual ULONG BeginPutDoc( const String&, const String& ) = 0;
+    virtual ULONG PutDoc() = 0;
+    virtual ULONG GetText( USHORT, String& ) = 0;
+    virtual ULONG PutText( const String&, const String&, const String& ) = 0;
+    virtual ULONG MakeBlockList() = 0;
+
+    virtual ULONG OpenFile( BOOL bReadOnly = TRUE ) = 0;
+    virtual void  CloseFile() = 0;
+
+    virtual BOOL IsOnlyTextBlock( const String& rShort ) const;
+
+    virtual ULONG GetMacroTable( USHORT nIdx, SvxMacroTableDtor& rMacroTbl );
+    virtual BOOL PutMuchEntries( BOOL bOn );
+};
+
+class Sw3Persist : public SvPersist
+{
+    virtual void FillClass( SvGlobalName * pClassName,
+                            ULONG * pClipFormat,
+                            String * pAppName,
+                            String * pLongUserName,
+                            String * pUserName,
+                            long nFileFormat=SOFFICE_FILEFORMAT_NOW ) const;
+    virtual BOOL Save();
+    virtual BOOL SaveCompleted( SvStorage * );
+public:
+    Sw3Persist();
+};
+
+class SwSwgReader;
+
+class Sw2TextBlocks : public SwImpBlocks
+{
+    SvPersistRef refPersist;            // Fuer OLE-Objekte
+    SwSwgReader* pRdr;                  // Lese-Routinen
+    SvStream* pFstrm;                   // der logische Input-Stream
+    String* pText;                      // String fuer GetText()
+    long   nDocStart;                   // Beginn des Doc-Records
+    long   nDocSize;                    // Laenge des Doc-Records
+    long   nStart;                      // Beginn des CONTENTS-Records
+    long   nSize;                       // Laenge des CONTENTS-Records
+    USHORT nNamedFmts;                  // benannte Formate
+    USHORT nColls;                      // Text-Collections
+    USHORT nBlks;                       // Anzahl Elemente im CONTENTS-Record
+public:
+    Sw2TextBlocks( const String& );
+    virtual ~Sw2TextBlocks();
+    virtual BOOL   IsOld() const;
+    virtual ULONG Delete( USHORT );
+    virtual ULONG Rename( USHORT, const String&, const String& );
+    virtual ULONG CopyBlock( SwImpBlocks& rImp, String& rShort, const String& rLong);
+    virtual ULONG GetDoc( USHORT );
+    virtual ULONG BeginPutDoc( const String&, const String& );
+    virtual ULONG PutDoc();
+    virtual ULONG GetText( USHORT, String& );
+    virtual ULONG PutText( const String&, const String&, const String& );
+    virtual ULONG MakeBlockList();
+    ULONG LoadDoc();
+
+    virtual ULONG OpenFile( BOOL bReadOnly = TRUE );
+    virtual void  CloseFile();
+
+    void StatLineStartPercent();                // zum Anzeigen des Prozessbars
+};
+
+class Sw3Io;
+class Sw3IoImp;
+
+class Sw3TextBlocks : public SwImpBlocks
+{
+    Sw3Io*       pIo3;
+    Sw3IoImp*    pImp;
+    BOOL         bAutocorrBlock;
+
+public:
+    Sw3TextBlocks( const String& );
+    Sw3TextBlocks( SvStorage& );
+    virtual ~Sw3TextBlocks();
+    virtual BOOL   IsOld() const;
+    virtual ULONG Delete( USHORT );
+    virtual ULONG Rename( USHORT, const String&, const String& );
+    virtual ULONG CopyBlock( SwImpBlocks& rImp, String& rShort, const String& rLong);
+    virtual ULONG GetDoc( USHORT );
+    virtual ULONG BeginPutDoc( const String&, const String& );
+    virtual ULONG PutDoc();
+    virtual ULONG GetText( USHORT, String& );
+    virtual ULONG PutText( const String&, const String&, const String& );
+    virtual ULONG MakeBlockList();
+
+    virtual ULONG OpenFile( BOOL bReadOnly = TRUE );
+    virtual void  CloseFile();
+
+    ULONG SetConvertMode( BOOL );
+
+    // Methoden fuer die neue Autokorrektur
+    ULONG GetText( const String& rShort, String& );
+    SwDoc* GetDoc() const { return pDoc; }
+
+    virtual BOOL IsOnlyTextBlock( const String& rShort ) const;
+
+    virtual ULONG GetMacroTable( USHORT, SvxMacroTableDtor& rMacroTbl );
+    virtual BOOL PutMuchEntries( BOOL bOn );
+
+    void ReadInfo();
+    void WriteInfo();
+};
+
+#endif
diff --git a/sw/source/core/inc/swcache.hxx b/sw/source/core/inc/swcache.hxx
new file mode 100644
index 000000000000..f2fc640f8d4e
--- /dev/null
+++ b/sw/source/core/inc/swcache.hxx
@@ -0,0 +1,336 @@
+/*************************************************************************
+ *
+ *  $RCSfile: swcache.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:21 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _SWCACHE_HXX
+#define _SWCACHE_HXX
+
+
+
+/*
+ * Es werden Pointer auf Objekte verwaltet. Diese werden in einem einfachen
+ * PtrArray verwaltet.
+ * Angelegt (new) werden die Objekte von Cache-Zugriffsklassen, zuerstoert
+ * werden die Objekte vom Cache.
+ *
+ * Auf die Objekte kann wahlweise per Index in das Array oder per Suche
+ * zugegriffen werden. Soll per Index zugegriffen werden, so obliegt die
+ * Verwaltung des Index dem Anwender des Cache.
+ *
+ * Fuer die verwalteten Cache-Objekte gibt es eine Basisklasse, von dieser
+ * sind spezifische Klassen abzuleiten.
+ * In der Basisklasse werden die Cache-Objekte eines Cache doppelt verkettet,
+ * das ermoeglich die Implementierung eines LRU-Algorithmus.
+ *
+ * Der LRU kann in der Cache-Basisklasse manipuliert werden, indem ein
+ * virtueller First-Pointer gesetzt wird. Dieser kann auf den echten ersten
+ * plus einem Ofst gesetzt werden. Dadurch kann man den Anfangsbereich des
+ * Cache sichern und so dafuer sorgen, dass man waehrend bestimmter
+ * Operationen nicht den Cache versaut. Beispiel: Der Idle-Handler sollte nicht
+ * den Cache fuer den sichtbaren Bereich vernichten.
+ *
+ * Der Cache kann in der Groesse erweitert und wieder verkleinert werden.
+ * Beispiel: Fuer jede neue Shell wird der Cache fuer FormatInfo vergrossert
+ * und beim Destruieren der Shell wieder verkleinert.
+ *
+ */
+
+#ifndef PRODUCT
+#ifndef _STRING_HXX //autogen
+#include 
+#endif
+#endif
+
+#ifndef _SVSTDARR_HXX
+#define _SVSTDARR_USHORTS
+#include 
+#endif
+
+class SwCacheObj;
+
+SV_DECL_PTRARR_DEL(SwCacheObjArr,SwCacheObj*,1,1)
+
+class SwCache : public SwCacheObjArr
+{
+    SvUShorts aFreePositions;       //Freie Positionen fuer das Insert wenn
+                                    //die Maximalgrenze nicht erreicht ist.
+                                    //Immer wenn ein Objekt ausgetragen wird,
+                                    //so wird seine Position hier eingetragen.
+
+    SwCacheObj *pRealFirst;         //_immer_ der echte LRU-erste
+    SwCacheObj *pFirst;             //der virtuelle erste.
+    SwCacheObj *pLast;
+
+    const USHORT nMax;              //Mehr sollen nicht aufgenommen werden,
+                                    //der Cache kann aber dynamisch um jeweils
+                                    //nMax vergroessert werden.
+          USHORT nCurMax;           //Mehr werden nicht aufgenommen.
+
+
+    void DeleteObj( SwCacheObj *pObj );
+
+#ifndef PRODUCT
+    ByteString aName;
+    long nAppend;           //Anzahl der Eintragungen durch Erweiterung.
+    long nInsertFree;       //Anzahl der Eintragungen auf freie Plaetze.
+    long nReplace;          //Anzahl der Ersetzungen durch ein neues Objekt
+    long nGetSuccess;       //Anzahl der Erfolgreichen Get's
+    long nGetFail;          //Anzahl der nicht Erfolgreichen Get's
+    long nToTop;            //Anzahl der Umsortierungen (LRU)
+    long nDelete;           //Anzahl der Loeschungen (von Aussen)
+    long nGetSeek;          //Anzahl der Get's ohne Index
+    long nAverageSeekCnt;   //Anzahl der Seek's fuer alle Get's ohne Index
+    long nFlushCnt;         //Anzahl von Flush-Aufrufen.
+    long nFlushedObjects;   //Anzahl der wg. Flush vernichteten Objekte
+    long nIncreaseMax;      //Anzahl Cache-Erweiterungen
+    long nDecreaseMax;      //Anzahl Cache-Verkleinerungen
+
+    void Check();           //Wird bei swcache.cxx mit DEBUG aktiv!
+#endif
+
+public:
+
+    //nur BYTE hineinstecken!!!
+#ifndef PRODUCT
+    SwCache( const USHORT nInitSize, const USHORT nGrowSize,
+            const ByteString &rNm );
+    ~SwCache();
+#else
+    SwCache( const USHORT nInitSize, const USHORT nGrowSize );
+#endif
+
+    void Flush( const BYTE nPercent = 100 );
+
+    //bToTop == FALSE -> Keine LRU-Umsortierung!
+    SwCacheObj *Get( const void *pOwner, const BOOL bToTop = TRUE );
+    SwCacheObj *Get( const void *pOwner, const USHORT nIndex,
+                     const BOOL bToTop = TRUE );
+    void ToTop( SwCacheObj *pObj );
+
+    BOOL Insert( SwCacheObj *pNew );
+    void Delete( const void *pOwner );
+//  void Delete( const void *pOwner, const USHORT nIndex );
+
+    void SetLRUOfst( const USHORT nOfst );      //nOfst sagt wieviele unangetastet
+                                                //bleiben sollen.
+    void ResetLRUOfst() { pFirst = pRealFirst; }
+
+    inline void IncreaseMax( const USHORT nAdd );
+    inline void DecreaseMax( const USHORT nSub );
+    USHORT GetCurMax() const { return nCurMax; }
+    inline SwCacheObj *First() { return pRealFirst; }
+    inline SwCacheObj *Last()  { return pLast; }
+    inline SwCacheObj *Next( SwCacheObj *pCacheObj);
+};
+
+//Cache-Manipulation auf die sichere Art.
+class SwSaveSetLRUOfst
+{
+    SwCache &rCache;
+public:
+    SwSaveSetLRUOfst( SwCache &rC, const USHORT nOfst )
+        : rCache( rC )          { rCache.SetLRUOfst( nOfst );  }
+
+    ~SwSaveSetLRUOfst()         { rCache.ResetLRUOfst(); }
+};
+
+//Das allgemeine CacheObjekt. Anwender des Cache muessen eine Klasse vom
+//CacheObjekt ableiten und dort die Nutzdaten unterbringen.
+
+class SwCacheObj
+{
+    friend class SwCache;   //Der darf alles
+
+    SwCacheObj *pNext;      //Fuer die LRU-Verkettung.
+    SwCacheObj *pPrev;
+
+    USHORT nCachePos;       //Position im Cache-Array.
+
+    BYTE        nLock;
+
+    inline SwCacheObj *GetNext() { return pNext; }
+    inline SwCacheObj *GetPrev() { return pPrev; }
+    inline void SetNext( SwCacheObj *pNew )  { pNext = pNew; }
+    inline void SetPrev( SwCacheObj *pNew )  { pPrev = pNew; }
+
+    inline void   SetCachePos( const USHORT nNew ) { nCachePos = nNew; }
+
+protected:
+    const void *pOwner;
+    inline void SetOwner( const void *pNew ) { pOwner = pNew; }
+
+public:
+
+    SwCacheObj( const void *pOwner );
+    virtual ~SwCacheObj();
+
+    inline const void *GetOwner() const { return pOwner; }
+    inline BOOL IsOwner( const void *pNew ) const;
+
+    inline USHORT GetCachePos() const { return nCachePos; }
+    inline void Invalidate()          { pOwner = 0; }
+
+    inline BOOL IsLocked() const { return 0 != nLock; }
+
+#ifdef PRODUCT
+    inline void Lock() { ++nLock; }
+    inline void Unlock() { --nLock; }
+#else
+    void Lock();
+    void Unlock();
+#endif
+
+    SwCacheObj *Next() { return pNext; }
+    SwCacheObj *Prev() { return pPrev; }
+
+};
+
+//Zugriffsklasse fuer den Cache. Im CTor wird das CacheObjekt erzeugt.
+//Wenn der Cache keines herausrueckt wird der Member zunaechst auf 0 gesetzt.
+//Beim Get wird dann eines erzeugt und, falls moeglich, in den Cache
+//eingetragen.
+//Anwender der des Cache muessen eine Klasse vom Access ableiten um
+//fuer Typsicherheit zu sorgen, die Basisklasse sollte fuer das Get aber immer
+//gerufen werden, ein Abgeleitetes Get sollte nur der Typsicherheit dienen.
+//Cache-Objekte werden stets gelockt solange die Instanz lebt.
+
+class SwCacheAccess
+{
+    SwCache &rCache;
+
+    void _Get();
+
+protected:
+    SwCacheObj *pObj;
+    const void *pOwner;     //Kann ggf. in NewObj benutzt werden.
+
+    virtual SwCacheObj *NewObj() = 0;
+
+    inline SwCacheObj *Get();
+
+    inline SwCacheAccess( SwCache &rCache, const void *pOwner, BOOL bSeek = TRUE );
+    inline SwCacheAccess( SwCache &rCache, const void *pOwner, const USHORT nIndex );
+
+public:
+    ~SwCacheAccess() { if ( pObj ) pObj->Unlock(); }
+
+    virtual BOOL IsAvailable() const;
+
+    //Abkuerzung fuer diejenigen, die wissen, das die Ableitung das IsAvailable
+    //nicht ueberladen haben.
+    BOOL IsAvail() const { return pObj != 0; }
+};
+
+inline void SwCache::IncreaseMax( const USHORT nAdd )
+{
+    nCurMax += nAdd;
+#ifndef PRODUCT
+    ++nIncreaseMax;
+#endif
+}
+inline void SwCache::DecreaseMax( const USHORT nSub )
+{
+    if ( nCurMax > nSub )
+        nCurMax -= nSub;
+#ifndef PRODUCT
+    ++nDecreaseMax;
+#endif
+}
+
+inline BOOL SwCacheObj::IsOwner( const void *pNew ) const
+{
+    return pOwner && pOwner == pNew;
+}
+
+inline SwCacheObj *SwCache::Next( SwCacheObj *pCacheObj)
+{
+    if ( pCacheObj )
+        return pCacheObj->GetNext();
+    else
+        return NULL;
+}
+
+inline SwCacheAccess::SwCacheAccess( SwCache &rC, const void *pOwn, BOOL bSeek ) :
+    rCache( rC ),
+    pOwner( pOwn ),
+    pObj( 0 )
+{
+    if ( bSeek && pOwner && 0 != (pObj = rCache.Get( pOwner )) )
+        pObj->Lock();
+}
+
+inline SwCacheAccess::SwCacheAccess( SwCache &rC, const void *pOwn,
+                              const USHORT nIndex ) :
+    rCache( rC ),
+    pOwner( pOwn ),
+    pObj( 0 )
+{
+    if ( pOwner && 0 != (pObj = rCache.Get( pOwner, nIndex )) )
+        pObj->Lock();
+}
+
+inline SwCacheObj *SwCacheAccess::Get()
+{
+    if ( !pObj )
+        _Get();
+    return pObj;
+}
+
+
+#endif
diff --git a/sw/source/core/inc/swfntcch.hxx b/sw/source/core/inc/swfntcch.hxx
new file mode 100644
index 000000000000..6713bf7b6a93
--- /dev/null
+++ b/sw/source/core/inc/swfntcch.hxx
@@ -0,0 +1,133 @@
+/*************************************************************************
+ *
+ *  $RCSfile: swfntcch.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:21 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _SWFNTCCH_HXX
+#define _SWFNTCCH_HXX
+
+
+#ifndef _SVMEMPOOL_HXX //autogen
+#include 
+#endif
+#include "swcache.hxx"
+#include "swfont.hxx"
+
+class ViewShell;
+
+/*************************************************************************
+ *                      class SwFontCache
+ *************************************************************************/
+
+class SwFontCache : public SwCache
+{
+public:
+
+    inline SwFontCache() : SwCache(50,50
+#ifndef PRODUCT
+    , "Globaler AttributSet/Font-Cache pSwFontCache"
+#endif
+    ) {}
+
+};
+
+// AttributSet/Font-Cache, globale Variable, in FontCache.Cxx angelegt
+extern SwFontCache *pSwFontCache;
+
+/*************************************************************************
+ *                      class SwFontObj
+ *************************************************************************/
+
+class SwFontObj : public SwCacheObj
+{
+    friend class SwFontAccess;
+
+private:
+    SwFont aSwFont;
+
+public:
+    DECL_FIXEDMEMPOOL_NEWDEL(SwFontObj)
+
+    SwFontObj( const void* pOwner, ViewShell *pSh );
+
+    virtual ~SwFontObj();
+
+    inline       SwFont *GetFont()      { return &aSwFont; }
+    inline const SwFont *GetFont() const  { return &aSwFont; }
+
+};
+
+/*************************************************************************
+ *                      class SwFontAccess
+ *************************************************************************/
+
+
+class SwFontAccess : public SwCacheAccess
+{
+    ViewShell *pShell;
+protected:
+    virtual SwCacheObj *NewObj( );
+
+public:
+    SwFontAccess( const void *pOwner, ViewShell *pSh );
+    SwFontObj *Get();
+};
+
+
+
+#endif
diff --git a/sw/source/core/inc/swfont.hxx b/sw/source/core/inc/swfont.hxx
new file mode 100644
index 000000000000..7c4580174ce6
--- /dev/null
+++ b/sw/source/core/inc/swfont.hxx
@@ -0,0 +1,850 @@
+/*************************************************************************
+ *
+ *  $RCSfile: swfont.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:21 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _SWFONT_HXX
+#define _SWFONT_HXX
+
+
+#ifndef _TOOLS_LANG_HXX //autogen
+#include 
+#endif
+#ifndef _TOOLS_COLOR_HXX //autogen
+#include 
+#endif
+#ifndef _TOOLS_STREAM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_SVXFONT_HXX //autogen
+#include 
+#endif
+
+// Hiermit kann man einen Kerning-Test mit CodeView in ITRPAINT.CXX
+// und FNTCACHE durchfuehren, solange die UI dies nicht anbietet.
+#ifdef DEBUG
+#define KERNINGTEST
+#endif
+
+class LinguBase;        // SetLingu()
+class SfxItemSet;
+class SwAttrSet;
+class SwDoCapitals;     // DoCapitals
+class SwWrongList;
+class SwDrawTextInfo;   // _DrawText
+class ViewShell;
+
+const xub_Unicode CH_BLANK = ' ';   // ' ' Leerzeichen
+const xub_Unicode CH_BREAK = 0x0A;  //
+const xub_Unicode CH_TAB   = '\t';  // \t
+const xub_Unicode CH_PAR_ALTER = 0xDE;      // Paragraph (StarBats)
+
+#if defined(WIN) || defined(WNT) || defined(UNX)
+const xub_Unicode CH_PAR    = 0xB6;     // Paragraph
+const xub_Unicode CH_BULLET = 0xB7;     // mittiger Punkt
+#endif
+
+#ifdef PM2
+const xub_Unicode CH_PAR    = 0xF4;     // Paragraph
+const xub_Unicode CH_BULLET = 0xFA;         // mittiger Punkt
+#endif
+
+#ifdef MAC
+const xub_Unicode CH_PAR    = 0xA6;     // Paragraph
+const xub_Unicode CH_BULLET = 0xE1;     // mittiger Punkt
+#endif
+
+LanguageType GetSystemLang();
+
+class SwSubFont : public SvxFont
+{
+    friend class SwFont;
+    const void *pMagic;         // "MagicNumber" innerhalb des Fontcaches
+    Size        aSize;          // Fremde kriegen nur diese Size zu sehen
+    USHORT      nFntIndex;      // Index im Fontcache
+    USHORT      nOrgHeight;     // Hoehe inkl. Escapement/Proportion
+    USHORT      nOrgAscent;     // Ascent inkl. Escapement/Proportion
+
+    inline SwSubFont() : aSize(0,0)
+        { pMagic = NULL; nFntIndex = 0; nOrgHeight = nOrgAscent = 0; }
+
+    USHORT CalcEscAscent( const USHORT nOldAscent ) const;
+    USHORT CalcEscHeight( const USHORT nOldHeight,
+                          const USHORT nOldAscent ) const;
+    inline void CopyMagic( const SwSubFont& rFnt )
+        { pMagic = rFnt.pMagic; nFntIndex = rFnt.nFntIndex; }
+
+    BOOL operator==( const SwFont &rFnt ) const;
+    SwSubFont& operator=( const SwSubFont &rFont );
+
+    short _CheckKerning( );
+    void SetFnt( const SvxFont &rFont );
+
+    BOOL ChgFnt( ViewShell *pSh, OutputDevice *pOut );
+    BOOL IsSymbol( ViewShell *pSh );
+    USHORT GetAscent( ViewShell *pSh, const OutputDevice *pOut );
+    USHORT GetHeight( ViewShell *pSh, const OutputDevice *pOut );
+    Size _GetTxtSize( ViewShell *pSh, const OutputDevice *pOut,
+        const XubString &rTxt, const xub_StrLen nIdx, const xub_StrLen nLen );
+    Size GetCapitalSize( ViewShell *pSh, const OutputDevice *pOut,
+        const XubString &rTxt, const xub_StrLen nIdx, const xub_StrLen nLen );
+    void _DrawText( SwDrawTextInfo &rInf, const BOOL bGrey );
+    void DrawCapital( SwDrawTextInfo &rInf );
+    void DrawStretchCapital( SwDrawTextInfo &rInf );
+    void DoOnCapitals( SwDoCapitals &rDo );
+    void _DrawStretchText( SwDrawTextInfo &rInf );
+    xub_StrLen _GetCrsrOfst( ViewShell *pSh, OutputDevice *pOut,
+            const XubString &rTxt, const USHORT nOfst, const xub_StrLen nIdx,
+            const xub_StrLen nLen, const short nSpaceAdd );
+    xub_StrLen GetCapitalCrsrOfst( ViewShell *pSh, OutputDevice *pOut,
+            const XubString &rTxt, const USHORT nOfst, const xub_StrLen nIdx,
+            const xub_StrLen nLen, const short nSpaceAdd );
+
+    inline void SetColor( const Color& rColor );
+    inline void SetFillColor( const Color& rColor );
+    inline void SetCharSet( const CharSet eCharSet );
+    inline void SetPitch( const FontPitch ePitch );
+    inline void SetAlign( const FontAlign eAlign );
+    inline void SetUnderline( const FontUnderline eUnderline );
+    inline void SetStrikeout( const FontStrikeout eStrikeout );
+    inline void SetItalic( const FontItalic eItalic );
+    inline void SetOutline( const BOOL bOutline );
+    inline void SetShadow( const BOOL bShadow );
+    inline void SetAutoKern( const BOOL bAutoKern );
+    inline void SetWordLineMode( const BOOL bWordLineMode );
+
+    // Methoden fuer die Hoch-/Tiefstellung
+    inline void SetEscapement( const short nNewEsc );
+    inline void SetProportion( const BYTE nNewPropr );
+
+    inline void SetFamily( const FontFamily eFamily );
+    inline void SetName( const XubString& rName );
+    inline void SetStyleName( const XubString& rStyleName );
+    inline void SetSize( const Size& rSize );
+    inline void SetWeight( const FontWeight eWeight );
+    inline void SetLanguage( LanguageType eNewLang );
+    inline short CheckKerning()
+    {   return GetFixKerning() >= 0 ? GetFixKerning() : _CheckKerning( ); }
+};
+
+#define SW_LATIN 0
+#define SW_CJK 1
+#define SW_CTL 2
+
+class SwFont
+{                               // CJK == Chinese, Japanese, Korean
+                                // CTL == Complex text layout ( Hebrew, Arabic )
+    SwSubFont   aSub[3];        // Latin-, CJK- and CTL-font
+    Color*      pBackColor;     // background color (i.e. at character styles)
+    BYTE        nToxCnt;        // Zaehlt die Schachtelungstiefe der Tox
+    BYTE        nRefCnt;        // Zaehlt die Schachtelungstiefe der Refs
+    BYTE        nActual;        // actual font (Latin, CJK or CTL)
+
+    // Schalter fuer die Font-Extensions
+    BOOL bNoHyph        :1;  // SwTxtNoHyphenHere:    keine Trennstelle
+    BOOL bBlink         :1;  // blinkender Font
+    BOOL bPaintBlank    :1;  // Blanks nicht mit DrawRect
+    BOOL bFntChg        :1;
+    BOOL bOrgChg        :1;  // nOrgHeight/Ascent sind invalid
+    BOOL bURL           :1;
+    BOOL bPaintWrong    :1;  // Flag fuer Rechtschreibfehler
+    BOOL bGreyWave      :1;  // Fuers extended TextInput: Graue Wellenlinie
+    BOOL bNoColReplace  :1;  // Replacement without colormanipulation
+
+
+    BOOL operator==( const SwFont &rFnt ) const;
+
+protected:
+    inline SwFont() { pBackColor = NULL; nActual = SW_LATIN; }
+
+public:
+    SwFont( const SwAttrSet* pSet );
+    SwFont( const SwFont& rFont );
+
+    inline void ChgFnt( ViewShell *pSh, OutputDevice *pOut )
+        { bPaintBlank = aSub[nActual].ChgFnt( pSh, pOut ); }
+
+    ~SwFont(){ delete pBackColor; }
+
+    SwFont& operator=( const SwFont &rFont );
+
+    inline BYTE GetActual() const { return nActual; }
+    inline void SetActual( BYTE nNew ) { nActual = nNew; bFntChg = TRUE; }
+    inline const SvxFont& GetActualFont() const { return aSub[nActual]; }
+
+    // holt sich eine MagicNumber ueber SwFntAccess
+    void GoMagic( ViewShell *pSh, BYTE nWhich );
+    // set background color
+    void SetBackColor( Color* pNewColor );
+    Color* XChgBackColor( Color* pNewColor );
+    inline const Color* GetBackColor() const{ return pBackColor; }
+
+    inline void ChkMagic( ViewShell *pSh, BYTE nWhich )
+        { if( !aSub[ nWhich ].pMagic ) GoMagic( pSh, nWhich ); }
+    // uebernimmt die MagicNumber eines (hoffentlich ident.) Kollegen
+    inline void CopyMagic( const SwFont* pFnt, BYTE nWhich )
+        { aSub[nWhich].CopyMagic( pFnt->aSub[nWhich] ); }
+    inline void GetMagic( const void* &rMagic, USHORT &rIdx, BYTE nWhich )
+        { rMagic = aSub[nWhich].pMagic; rIdx = aSub[nWhich].nFntIndex; }
+    inline void SetMagic( const void* pNew, const USHORT nIdx, BYTE nWhich )
+        { aSub[nWhich].pMagic = pNew; aSub[nWhich].nFntIndex = nIdx; }
+    inline BOOL DifferentMagic( const SwFont* pFnt, BYTE nWhich )
+        { return aSub[nWhich].pMagic != pFnt->aSub[nWhich].pMagic ||
+          !aSub[nWhich].pMagic || !pFnt->aSub[nWhich].pMagic; }
+
+    inline const Size &GetSize( BYTE nWhich ) const
+        { return aSub[nWhich].aSize; }
+    inline BOOL IsFntChg() const { return bFntChg; }
+    inline void SetFntChg( const BOOL bNew ) { bFntChg = bNew; }
+
+    // die gekapselten SV-Font-Methoden (setzen bFntChg auf TRUE)
+    inline void SetColor( const Color& rColor );
+    inline void SetFillColor( const Color& rColor );
+    inline void SetAlign( const FontAlign eAlign );
+    inline void SetUnderline( const FontUnderline eUnderline );
+    inline void SetStrikeout( const FontStrikeout eStrikeout );
+    inline void SetOutline( const BOOL bOutline );
+    inline void SetShadow( const BOOL bShadow );
+    inline void SetAutoKern( const BOOL bAutoKern );
+    inline void SetTransparent( const BOOL bTrans );
+    inline void SetWordLineMode( const BOOL bWordLineMode );
+    inline void SetFixKerning( const short nNewKern );
+    inline void SetCaseMap( const SvxCaseMap eNew );
+
+    // Methoden fuer die Hoch-/Tiefstellung
+    inline void SetEscapement( const short nNewEsc );
+    inline void SetProportion( const BYTE nNewPropr );
+
+    inline void SetFamily( const FontFamily eFamily, const BYTE nWhich );
+    inline void SetName( const XubString& rName, const BYTE nWhich );
+    inline void SetStyleName( const XubString& rStyleName, const BYTE nWhich );
+    inline void SetSize( const Size& rSize, const BYTE nWhich );
+    inline void SetWeight( const FontWeight eWeight, const BYTE nWhich );
+    inline void SetItalic( const FontItalic eItalic, const BYTE nWhich );
+    inline void SetLanguage( LanguageType eNewLang, const BYTE nWhich );
+    inline void SetCharSet( const CharSet eCharSet, const BYTE nWhich );
+    inline void SetPitch( const FontPitch ePitch, const BYTE nWhich );
+
+    // Get/Set-Methoden fuer die aktuelle Einstellung
+    inline void SetNoHyph( const BOOL bNew );
+    inline BOOL IsNoHyph() const { return bNoHyph; }
+    inline void SetBlink( const BOOL bBlink );
+    inline BOOL IsBlink() const { return bBlink; }
+    inline BYTE &GetTox() { return nToxCnt; }
+    inline BYTE GetTox() const { return nToxCnt; }
+    inline BOOL IsTox() const { return ( 0 != nToxCnt ); }
+    inline BYTE &GetRef() { return nRefCnt; }
+    inline BYTE GetRef() const { return nRefCnt; }
+    inline BOOL IsRef() const { return ( 0 != nRefCnt ); }
+    inline void SetURL( const BOOL bURL );
+    inline BOOL IsURL() const { return bURL; }
+    inline void SetGreyWave( const BOOL bNew );
+    inline BOOL IsGreyWave() const { return bGreyWave; }
+    inline void SetNoCol( const BOOL bNew );
+    inline BOOL IsNoCol() const { return bNoColReplace; }
+
+    inline void SetPaintBlank( const BOOL bNew );
+    inline BOOL IsPaintBlank() const { return bPaintBlank; }
+    inline void SetPaintWrong( const BOOL bNew );
+    inline BOOL IsPaintWrong() const { return bPaintWrong; }
+
+    // Setzen der Basisklasse Font fuer SwTxtCharFmt
+           void SetDiffFnt( const SfxItemSet* pSet );
+    inline void SetFnt( const SvxFont &rFont, const BYTE nWhich )
+        { bFntChg = bOrgChg = TRUE; aSub[nWhich].SetFnt( rFont ); }
+           void SetFnt( const SwAttrSet* pSet );
+    inline void SetSwFnt( const SwFont &rFont )
+            { *this = rFont; }
+    inline const SvxFont &GetFnt( const BYTE nWhich ) const
+        { return aSub[nWhich]; };
+    inline SvxFont &GetFnt( const BYTE nWhich )
+        { return aSub[nWhich]; };
+
+    void SetSystemLang();
+
+    BOOL IsSymbol( ViewShell *pSh )
+        { return aSub[nActual].IsSymbol( pSh ); }
+    FontUnderline GetUnderline() const { return aSub[nActual].GetUnderline(); }
+    short GetFixKerning() const { return aSub[nActual].GetFixKerning(); }
+    FontStrikeout GetStrikeout() const { return aSub[nActual].GetStrikeout(); }
+    const Color& GetColor() const { return aSub[nActual].GetColor(); }
+    BOOL IsShadow() const { return aSub[nActual].IsShadow(); }
+    BOOL IsWordLineMode() const { return aSub[nActual].IsWordLineMode(); }
+    BOOL IsOutline() const { return aSub[nActual].IsOutline(); }
+    BOOL IsKerning() const { return aSub[nActual].IsKerning(); }
+    short GetEscapement() const { return aSub[nActual].GetEscapement(); }
+    SvxCaseMap GetCaseMap() const { return aSub[nActual].GetCaseMap(); }
+    BYTE GetPropr() const { return aSub[nActual].GetPropr(); }
+    FontItalic GetItalic() const { return aSub[nActual].GetItalic(); }
+    LanguageType GetLanguage() const { return aSub[nActual].GetLanguage(); }
+    FontAlign GetAlign() const { return aSub[nActual].GetAlign(); }
+    const XubString& GetName() const { return aSub[nActual].GetName(); }
+    const XubString& GetStyleName() const {return aSub[nActual].GetStyleName();}
+    FontFamily GetFamily() const { return aSub[nActual].GetFamily(); }
+    FontPitch GetPitch() const { return aSub[nActual].GetPitch(); }
+    rtl_TextEncoding GetCharSet() const { return aSub[nActual].GetCharSet(); }
+    long GetHeight() const { return aSub[nActual].GetSize().Height(); }
+    FontWeight GetWeight() const { return aSub[nActual].GetWeight(); }
+
+    inline const XubString& GetName( const BYTE nWhich ) const
+        { return aSub[nWhich].GetName(); }
+    inline LanguageType GetLanguage( const BYTE nWhich ) const
+        { return aSub[nWhich].GetLanguage(); }
+    inline const XubString& GetStyleName( const BYTE nWhich ) const
+        { return aSub[nWhich].GetStyleName(); }
+    inline FontFamily GetFamily( const BYTE nWhich ) const
+        { return aSub[nWhich].GetFamily(); }
+    inline FontItalic GetItalic( const BYTE nWhich ) const
+        { return aSub[nWhich].GetItalic(); }
+    inline FontPitch GetPitch( const BYTE nWhich ) const
+        { return aSub[nWhich].GetPitch(); }
+    inline rtl_TextEncoding GetCharSet( const BYTE nWhich ) const
+        { return aSub[nWhich].GetCharSet(); }
+    inline long GetHeight( const BYTE nWhich ) const
+        { return aSub[nWhich].GetSize().Height(); }
+    inline FontWeight GetWeight( const BYTE nWhich ) const
+        { return aSub[nWhich].GetWeight(); }
+
+    // Macht den logischen Font im OutputDevice wirksam.
+    void ChgPhysFnt( ViewShell *pSh, OutputDevice *pOut );
+
+    Size GetCapitalSize( ViewShell *pSh,
+                         const OutputDevice *pOut, const XubString &rTxt,
+                         const xub_StrLen nIdx = 0,
+                         const xub_StrLen nLen = STRING_LEN )
+        { aSub[nActual].GetCapitalSize( pSh, pOut, rTxt, nIdx, nLen ); }
+
+    xub_StrLen GetCapitalBreak( ViewShell *pSh,
+                            const OutputDevice *pOut, const XubString &rTxt,
+                            long nTextWidth, xub_StrLen *pExtra = 0,
+                            const xub_StrLen nIdx = 0,
+                            const xub_StrLen nLen = STRING_LEN );
+
+    xub_StrLen GetCapitalCrsrOfst( ViewShell *pSh,
+                    OutputDevice *pOut,
+                    const XubString &rTxt, const USHORT nOfst,
+                    const xub_StrLen nIdx, const xub_StrLen nLen,
+                    const short nSpaceAdd = 0 )
+        { return aSub[nActual].GetCapitalCrsrOfst( pSh, pOut, rTxt, nOfst,
+                                                   nIdx, nLen, nSpaceAdd ); }
+
+
+    void DrawCapital( SwDrawTextInfo &rInf )
+        { aSub[nActual].DrawCapital( rInf ); }
+
+    void DrawStretchCapital( SwDrawTextInfo &rInf )
+        { aSub[nActual].DrawStretchCapital( rInf ); }
+
+    void DoOnCapitals( SwDoCapitals &rDo )
+        { aSub[nActual].DoOnCapitals( rDo ); }
+
+    Size _GetTxtSize( ViewShell *pSh,
+                     const OutputDevice *pOut, const XubString &rTxt,
+                     const xub_StrLen nIdx = 0,
+                     const xub_StrLen nLen = STRING_LEN )
+        { return aSub[nActual]._GetTxtSize( pSh, pOut, rTxt, nIdx, nLen ); }
+
+    xub_StrLen GetTxtBreak( ViewShell *pSh,
+                const OutputDevice *pOut, const XubString &rTxt,
+                long nTextWidth, xub_StrLen& rExtraCharPos,
+                const xub_StrLen nIdx = 0,
+                const xub_StrLen nLen = STRING_LEN );
+
+    xub_StrLen GetTxtBreak( ViewShell *pSh,
+                const OutputDevice *pOut, const XubString &rTxt,
+                long nTextWidth, const xub_StrLen nIdx = 0,
+                const xub_StrLen nLen = STRING_LEN );
+
+    xub_StrLen _GetCrsrOfst( ViewShell *pSh,
+                         OutputDevice *pOut, const XubString &rTxt,
+                         const USHORT nOfst,
+                         const xub_StrLen nIdx = 0,
+                         const xub_StrLen nLen = STRING_LEN,
+                         const short nSpaceAdd = 0 )
+        { return aSub[nActual]._GetCrsrOfst( pSh, pOut, rTxt, nOfst,
+                                             nIdx, nLen, nSpaceAdd ); }
+    inline void _DrawText( SwDrawTextInfo &rInf )
+        { aSub[nActual]._DrawText( rInf, IsGreyWave() ); }
+
+    inline void _DrawStretchText( SwDrawTextInfo &rInf )
+        { aSub[nActual]._DrawStretchText( rInf ); }
+
+    inline short CheckKerning()
+        { return aSub[nActual].CheckKerning(); }
+    inline USHORT GetAscent( ViewShell *pSh, const OutputDevice *pOut )
+        { return aSub[nActual].GetAscent( pSh, pOut ); }
+    USHORT GetLeading( ViewShell *pSh, const OutputDevice *pOut );
+    inline USHORT GetHeight( ViewShell *pSh, const OutputDevice *pOut )
+        { return aSub[nActual].GetHeight( pSh, pOut ); }
+    inline void Invalidate()
+        { bFntChg = bOrgChg = TRUE; }
+};
+
+// gekapselte SV-Font-Methode
+inline void SwSubFont::SetColor( const Color& rColor )
+{
+    pMagic = 0;
+    Font::SetColor( rColor );
+}
+
+inline void SwFont::SetColor( const Color& rColor )
+{
+    bFntChg = TRUE;
+    aSub[0].SetColor( rColor );
+    aSub[1].SetColor( rColor );
+    aSub[2].SetColor( rColor );
+}
+
+
+// gekapselte SV-Font-Methode
+inline void SwSubFont::SetFillColor( const Color& rColor )
+{
+    pMagic = 0;
+    Font::SetFillColor( rColor );
+}
+
+inline void SwFont::SetFillColor( const Color& rColor )
+{
+    bFntChg = TRUE;
+    aSub[0].SetFillColor( rColor );
+    aSub[1].SetFillColor( rColor );
+    aSub[2].SetFillColor( rColor );
+}
+
+// gekapselte SV-Font-Methode
+inline void SwSubFont::SetFamily( const FontFamily eFamily )
+{
+    pMagic = 0;
+    Font::SetFamily( eFamily );
+}
+
+inline void SwFont::SetFamily( const FontFamily eFamily, const BYTE nWhich )
+{
+    bFntChg = TRUE;
+    aSub[nWhich].SetFamily( eFamily );
+}
+
+// gekapselte SV-Font-Methode
+inline void SwSubFont::SetName( const XubString& rName )
+{
+    pMagic = 0;
+    Font::SetName( rName );
+}
+
+inline void SwFont::SetName( const XubString& rName, const BYTE nWhich )
+{
+    bFntChg = TRUE;
+    aSub[nWhich].SetName( rName );
+}
+
+// gekapselte SV-Font-Methode
+inline void SwSubFont::SetStyleName( const XubString& rStyleName )
+{
+    pMagic = 0;
+    Font::SetStyleName( rStyleName );
+}
+
+inline void SwFont::SetStyleName( const XubString& rStyle, const BYTE nWhich )
+{
+    bFntChg = TRUE;
+    aSub[nWhich].SetStyleName( rStyle );
+}
+
+// gekapselte SV-Font-Methode
+inline void SwSubFont::SetCharSet( const CharSet eCharSet )
+{
+    pMagic = 0;
+    Font::SetCharSet( eCharSet );
+}
+
+inline void SwFont::SetCharSet( const CharSet eCharSet, const BYTE nWhich )
+{
+    bFntChg = TRUE;
+    aSub[nWhich].SetCharSet( eCharSet );
+}
+
+// gekapselte SV-Font-Methode
+inline void SwSubFont::SetPitch( const FontPitch ePitch )
+{
+    pMagic = 0;
+    Font::SetPitch( ePitch );
+}
+
+// gekapselte SV-Font-Methode
+inline void SwFont::SetPitch( const FontPitch ePitch, const BYTE nWhich )
+{
+    bFntChg = TRUE;
+    aSub[nWhich].SetPitch( ePitch );
+}
+
+// gekapselte SV-Font-Methode
+inline void SwSubFont::SetAlign( const FontAlign eAlign )
+{
+    pMagic = 0;
+    Font::SetAlign( eAlign );
+}
+
+inline void SwFont::SetAlign( const FontAlign eAlign )
+{
+    bFntChg = TRUE;
+    aSub[0].SetAlign( eAlign );
+    aSub[1].SetAlign( eAlign );
+    aSub[2].SetAlign( eAlign );
+}
+
+// gekapselte SV-Font-Methode
+inline void SwSubFont::SetWeight( const FontWeight eWeight )
+{
+    pMagic = 0;
+    Font::SetWeight( eWeight );
+}
+
+inline void SwFont::SetWeight( const FontWeight eWeight, const BYTE nWhich )
+{
+    bFntChg = TRUE;
+    aSub[nWhich].SetWeight( eWeight );
+}
+
+// gekapselte SV-Font-Methode
+inline void SwSubFont::SetUnderline( const FontUnderline eUnderline )
+{
+    pMagic = 0;
+    Font::SetUnderline( eUnderline );
+}
+
+inline void SwFont::SetUnderline( const FontUnderline eUnderline )
+{
+    bFntChg = TRUE;
+    aSub[0].SetUnderline( eUnderline );
+    aSub[1].SetUnderline( eUnderline );
+    aSub[2].SetUnderline( eUnderline );
+}
+
+// gekapselte SV-Font-Methode
+inline void SwSubFont::SetStrikeout( const FontStrikeout eStrikeout )
+{
+    pMagic = 0;
+    Font::SetStrikeout( eStrikeout );
+}
+
+inline void SwFont::SetStrikeout( const FontStrikeout eStrikeout )
+{
+    bFntChg = TRUE;
+    aSub[0].SetStrikeout( eStrikeout );
+    aSub[1].SetStrikeout( eStrikeout );
+    aSub[2].SetStrikeout( eStrikeout );
+}
+
+// gekapselte SV-Font-Methode
+inline void SwSubFont::SetItalic( const FontItalic eItalic )
+{
+    pMagic = 0;
+    Font::SetItalic( eItalic );
+}
+
+inline void SwFont::SetItalic( const FontItalic eItalic, const BYTE nWhich )
+{
+    bFntChg = TRUE;
+    aSub[nWhich].SetItalic( eItalic );
+}
+
+// gekapselte SV-Font-Methode
+inline void SwSubFont::SetOutline( const BOOL bOutline )
+{
+    pMagic = 0;
+    Font::SetOutline( bOutline );
+}
+
+inline void SwFont::SetOutline( const BOOL bOutline )
+{
+    bFntChg = TRUE;
+    aSub[0].SetOutline( bOutline );
+    aSub[1].SetOutline( bOutline );
+    aSub[2].SetOutline( bOutline );
+}
+
+// gekapselte SV-Font-Methode
+inline void SwSubFont::SetShadow( const BOOL bShadow )
+{
+    pMagic = 0;
+    Font::SetShadow( bShadow );
+}
+
+inline void SwFont::SetShadow( const BOOL bShadow )
+{
+    bFntChg = TRUE;
+    aSub[0].SetShadow( bShadow );
+    aSub[1].SetShadow( bShadow );
+    aSub[2].SetShadow( bShadow );
+}
+
+// gekapselte SV-Font-Methode
+inline void SwSubFont::SetAutoKern( const BOOL bAutoKern )
+{
+    pMagic = 0;
+    Font::SetKerning( bAutoKern );
+}
+
+inline void SwFont::SetAutoKern( const BOOL bAutoKern )
+{
+    bFntChg = TRUE;
+    aSub[0].SetAutoKern( bAutoKern );
+    aSub[1].SetAutoKern( bAutoKern );
+    aSub[2].SetAutoKern( bAutoKern );
+}
+
+inline void SwFont::SetTransparent( const BOOL bTrans )
+{
+    aSub[0].SetTransparent( bTrans );
+    aSub[1].SetTransparent( bTrans );
+    aSub[2].SetTransparent( bTrans );
+}
+
+inline void SwFont::SetFixKerning( const short nNewKern )
+{
+    aSub[SW_LATIN].SetFixKerning( nNewKern );
+    aSub[SW_CJK].SetFixKerning( nNewKern );
+    aSub[SW_CTL].SetFixKerning( nNewKern );
+}
+
+inline void SwFont::SetCaseMap( const SvxCaseMap eNew )
+{
+    aSub[SW_LATIN].SetCaseMap( eNew );
+    aSub[SW_CJK].SetCaseMap( eNew );
+    aSub[SW_CTL].SetCaseMap( eNew );
+}
+
+// gekapselte SV-Font-Methode
+inline void SwSubFont::SetWordLineMode( const BOOL bWordLineMode )
+{
+    pMagic = 0;
+    Font::SetWordLineMode( bWordLineMode );
+}
+
+inline void SwFont::SetWordLineMode( const BOOL bWordLineMode )
+{
+    bFntChg = TRUE;
+    aSub[0].SetWordLineMode( bWordLineMode );
+    aSub[1].SetWordLineMode( bWordLineMode );
+    aSub[2].SetWordLineMode( bWordLineMode );
+}
+
+// ueberladene Font-Methode
+inline void SwSubFont::SetSize( const Size& rSize )
+{
+    aSize = rSize;
+    if ( GetPropr() == 100 )
+        Font::SetSize( aSize );
+    else
+    {
+        Font::SetSize( Size(
+            (long) aSize.Width() * GetPropr() / 100L,
+            (long) aSize.Height() * GetPropr() / 100L ) );
+    }
+    pMagic = 0;
+}
+
+inline void SwFont::SetSize( const Size& rSize, const BYTE nWhich )
+{
+    if( aSub[nWhich].aSize != rSize )
+    {
+        aSub[nWhich].SetSize( rSize );
+        bFntChg = TRUE;
+        bOrgChg = TRUE;
+    }
+}
+
+inline void SwSubFont::SetProportion( const BYTE nNewPropr )
+{
+    pMagic = 0;
+    Font::SetSize( Size( (long) aSize.Width() * nNewPropr / 100L,
+                         (long) aSize.Height() * nNewPropr / 100L ) );
+    SvxFont::SetPropr( nNewPropr );
+}
+
+inline void SwFont::SetProportion( const BYTE nNewPropr )
+{
+    if( nNewPropr != aSub[0].GetPropr() )
+    {
+        bFntChg = TRUE;
+        bOrgChg = TRUE;
+        aSub[0].SetProportion( nNewPropr );
+        aSub[1].SetProportion( nNewPropr );
+        aSub[2].SetProportion( nNewPropr );
+    }
+}
+
+inline void SwSubFont::SetEscapement( const short nNewEsc )
+{
+    pMagic = 0;
+    SvxFont::SetEscapement( nNewEsc );
+}
+
+inline void SwFont::SetEscapement( const short nNewEsc )
+{
+    if( nNewEsc != aSub[0].GetEscapement() )
+    {
+        aSub[0].SetEscapement( nNewEsc );
+        aSub[1].SetEscapement( nNewEsc );
+        aSub[2].SetEscapement( nNewEsc );
+    }
+}
+
+inline void SwSubFont::SetLanguage( LanguageType eNewLang )
+{
+    if( eNewLang == LANGUAGE_SYSTEM )
+        eNewLang = ::GetSystemLang();
+    SvxFont::SetLanguage( eNewLang );
+}
+
+inline void SwFont::SetLanguage( const LanguageType eNewLang, const BYTE nWhich )
+{
+    aSub[nWhich].SetLanguage( eNewLang );
+}
+
+inline void SwFont::SetPaintBlank( const BOOL bNew )
+{
+    bPaintBlank = bNew;
+}
+
+inline void SwFont::SetPaintWrong( const BOOL bNew )
+{
+    bPaintWrong = bNew;
+}
+
+inline void SwFont::SetNoHyph( const BOOL bNew )
+{
+    bNoHyph = bNew;
+}
+
+inline void SwFont::SetBlink( const BOOL bNew )
+{
+    bBlink = bNew;
+}
+
+inline void SwFont::SetURL( const BOOL bNew )
+{
+    bURL = bNew;
+}
+
+inline void SwFont::SetGreyWave( const BOOL bNew )
+{
+    bGreyWave = bNew;
+}
+
+inline void SwFont::SetNoCol( const BOOL bNew )
+{
+    bNoColReplace = bNew;
+}
+
+/*************************************************************************
+ *                      class SvStatistics
+ *************************************************************************/
+
+#ifdef PRODUCT
+#define SV_STAT(nWhich)
+#else
+
+class SvStatistics
+{
+public:
+    USHORT nGetTextSize;
+    USHORT nDrawText;
+    USHORT nGetStretchTextSize;
+    USHORT nDrawStretchText;
+    USHORT nChangeFont;
+    USHORT nGetFontMetric;
+
+    inline void Reset()
+    {
+        nGetTextSize = nDrawText = nGetStretchTextSize =
+        nDrawStretchText = nChangeFont = nGetFontMetric = 0;
+    }
+
+    inline SvStatistics() { Reset(); }
+
+    inline void PrintOn( SvStream &rOS ) const; //$ ostream
+    inline BOOL IsEmpty() const
+    {
+        return !( nGetTextSize || nDrawText ||
+                  nDrawStretchText || nChangeFont || nGetFontMetric );
+    }
+};
+
+// globale Variable, implementiert in swfont.cxx
+extern SvStatistics aSvStat;
+
+#define SV_STAT(nWhich) ++(aSvStat.nWhich);
+
+inline void SvStatistics::PrintOn( SvStream &rOS ) const //$ ostream
+{
+    if( IsEmpty() )
+        return;
+
+    rOS << "{   SV called:" << '\n';
+    if( nGetTextSize )
+        rOS << "\tnGetTextSize: " <<    nGetTextSize    << '\n';        if( nDrawText   )
+        rOS << "\tnDrawText: "  << nDrawText    << '\n';        if( nGetStretchTextSize )
+        rOS << "\tnGetStretchTextSize: "    << nGetStretchTextSize  << '\n';        if( nDrawStretchText    )
+        rOS << "\tnDrawStretchText: "   << nDrawStretchText << '\n';        if( nChangeFont )
+        rOS << "\tnChangeFont: "    << nChangeFont  << '\n';        if( nGetFontMetric  )
+        rOS << "\tnGetFontMetric: " << nGetFontMetric   << '\n';        rOS << "}"  << '\n';    }
+#endif  /*  PRODUCT */
+
+#endif
+
diff --git a/sw/source/core/inc/tabfrm.hxx b/sw/source/core/inc/tabfrm.hxx
new file mode 100644
index 000000000000..a3eab54d3606
--- /dev/null
+++ b/sw/source/core/inc/tabfrm.hxx
@@ -0,0 +1,190 @@
+/*************************************************************************
+ *
+ *  $RCSfile: tabfrm.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:21 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _TABFRM_HXX
+#define _TABFRM_HXX
+
+#ifndef _SVMEMPOOL_HXX //autogen
+#include 
+#endif
+#include "layfrm.hxx"
+#include "flowfrm.hxx"
+
+class SwTable;
+class Sw3FrameIo;
+class SwBorderAttrs;
+class SwAttrSetChg;
+
+class SwTabFrm: public SwLayoutFrm, public SwFlowFrm
+{
+    //darf mit den Flags spielen.
+    friend void CalcCntnt( SwLayoutFrm *pLay, BOOL bNoColl = FALSE );
+
+    //Fuert Spezialbehandlung fuer _Get[Next|Prev]Leaf() durch.
+    SwLayoutFrm *GetLeaf( MakePageType eMakePage, BOOL bFwd );
+
+    SwTable *pTable;
+
+    BOOL bComplete          :1; //Eintrage als Repaint ohne das CompletePaint
+                                //der Basisklasse gesetzt werden muss. Damit
+                                //sollen unertraegliche Tabellen-Repaints
+                                //vermieden werden.
+    BOOL bCalcLowers        :1; //Im MakeAll auf jedenfall auch fuer Stabilitaet
+                                //des Inhaltes sorgen.
+    BOOL bLowersFormatted   :1;//Kommunikation zwischen MakeAll und Layact
+    BOOL bLockBackMove      :1; //BackMove-Test hat der Master erledigt.
+    BOOL bResizeHTMLTable   :1; //Resize des HTMLTableLayout rufen im MakeAll
+                                //Zur Optimierung, damit dies nicht im
+                                //CntntFrm::Grow gerufen werden muss, denn dann
+                                //wird es ggf. fuer jede Zelle gerufen #47483#
+    BOOL bONECalcLowers     :1; //Primaer fuer die StarONE-SS. Beim MakeAll werden
+                                //die Cntnts auf jedenfall per Calc() formatiert.
+                                //es finden keine zusaetzlichen Invalidierungen
+                                //statt und dieser Weg kann auch kaum garantien
+                                //geben.
+
+    //Split() spaltet den Frm an der angegebenen Stelle, es wird ein
+    //Follow erzeugt und aufgebaut und direkt hinter this gepastet.
+    //Join() Holt sich den Inhalt aus dem Follow und vernichtet diesen.
+    SwTwips Split( const SwTwips nCutPos );
+    SwTwips Join();
+
+    void _UpdateAttr( SfxPoolItem*, SfxPoolItem*, BYTE &,
+                      SwAttrSetChg *pa = 0, SwAttrSetChg *pb = 0 );
+
+    virtual BOOL ShouldBwdMoved( SwLayoutFrm *pNewUpper, BOOL bHead, BOOL &rReformat );
+
+protected:
+    virtual void MakeAll();
+    virtual void Format( const SwBorderAttrs *pAttrs = 0 );
+        //Aendert nur die Framesize, nicht die PrtArea-SSize
+    virtual SwTwips GrowFrm  ( SwTwips, const SzPtr,
+                               BOOL bTst = FALSE, BOOL bInfo = FALSE );
+public:
+    SwTabFrm( SwTable & );  //Immer nach dem erzeugen _und_ pasten das
+                            //Regist Flys rufen!
+    SwTabFrm( SwTabFrm & ); //_Nur_ zum erzeugen von Follows
+    SwTabFrm( Sw3FrameIo&, SwLayoutFrm* );
+    ~SwTabFrm();
+
+    void JoinAndDelFollows();   //Fuer DelFrms des TableNodes!
+
+    //Ruft das RegistFlys der Zeilen.
+    void RegistFlys();
+
+    inline const SwTabFrm *GetFollow() const;
+    inline       SwTabFrm *GetFollow();
+    inline const SwTabFrm *FindMaster() const;
+    inline       SwTabFrm *FindMaster();
+
+    virtual void Store( Sw3FrameIo& ) const;
+    virtual void Modify( SfxPoolItem*, SfxPoolItem* );
+    virtual BOOL GetInfo( SfxPoolItem &rHnt ) const;
+    virtual void Paint( const SwRect& ) const;
+
+    virtual void Cut();
+    virtual void Paste( SwFrm* pParent, SwFrm* pSibling = 0 );
+
+                 SwCntntFrm *FindLastCntnt();
+    inline const SwCntntFrm *FindLastCntnt() const;
+
+    const SwTable *GetTable() const { return pTable; }
+          SwTable *GetTable()       { return pTable; }
+
+    BOOL IsComplete()  { return bComplete; }
+    void SetComplete() { bComplete = TRUE; }
+    void ResetComplete() { bComplete = FALSE; }
+
+    BOOL IsLowersFormatted() const      { return bLowersFormatted; }
+    void SetLowersFormatted( BOOL b )   { bLowersFormatted = b;    }
+
+    void SetCalcLowers()        { bCalcLowers = TRUE;      } //Sparsam einsetzen!
+    void SetResizeHTMLTable()   { bResizeHTMLTable = TRUE; } //dito
+    void SetONECalcLowers()     { bONECalcLowers = TRUE;   }
+
+    BOOL CalcFlyOffsets( SwTwips& rUpper, long& rLeftOffset,
+                         long& rRightOffset ) const;
+    DECL_FIXEDMEMPOOL_NEWDEL(SwTabFrm)
+};
+
+inline const SwCntntFrm *SwTabFrm::FindLastCntnt() const
+{
+    return ((SwTabFrm*)this)->FindLastCntnt();
+}
+
+inline const SwTabFrm *SwTabFrm::GetFollow() const
+{
+    return (const SwTabFrm*)SwFlowFrm::GetFollow();
+}
+inline SwTabFrm *SwTabFrm::GetFollow()
+{
+    return (SwTabFrm*)SwFlowFrm::GetFollow();
+}
+
+inline const SwTabFrm *SwTabFrm::FindMaster() const
+{
+    return (const SwTabFrm*)SwFlowFrm::FindMaster();
+}
+inline SwTabFrm *SwTabFrm::FindMaster()
+{
+    return (SwTabFrm*)SwFlowFrm::FindMaster();
+}
+
+#endif  //_TABFRM_HXX
diff --git a/sw/source/core/inc/tblrwcl.hxx b/sw/source/core/inc/tblrwcl.hxx
new file mode 100644
index 000000000000..ae10f3ea7460
--- /dev/null
+++ b/sw/source/core/inc/tblrwcl.hxx
@@ -0,0 +1,263 @@
+/*************************************************************************
+ *
+ *  $RCSfile: tblrwcl.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:21 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _TBLRWCL_HXX
+#define _TBLRWCL_HXX
+
+#ifndef _SVSTDARR_HXX
+#define _SVSTDARR_USHORTS
+#include 
+#endif
+
+#ifndef _SWTYPES_HXX
+#include 
+#endif
+#ifndef _TBLSEL_HXX
+#include 
+#endif
+#ifndef _SWTABLE_HXX
+#include 
+#endif
+
+class SvxBorderLine;
+class SwDoc;
+class SwTableNode;
+class _FndLine;
+class _FndBox;
+class SwTableLine;
+class SwTableBox;
+class SwTableBoxFmt;
+class SwTableLineFmt;
+class SwHistory;
+class SwCntntNode;
+class SfxPoolItem;
+class SwShareBoxFmts;
+class SwFmtFrmSize;
+
+// Funktions Deklarationen:
+BOOL lcl_CopyRow( const _FndLine*& rpFndLine, void* pPara );
+BOOL lcl_CopyCol( const _FndBox*& rpFndBox, void* pPara );
+
+BOOL lcl_MergeGCBox( const SwTableBox*& rpBox, void* pPara );
+BOOL lcl_MergeGCLine( const SwTableLine*& rpLine, void* pPara );
+
+BOOL lcl_Merge_MoveBox( const _FndBox*& rpFndBox, void* pPara );
+BOOL lcl_Merge_MoveLine( const _FndLine*& rpFndLine, void* pPara );
+
+BOOL lcl_CopyBoxToDoc( const _FndBox*& rpFndBox, void* pPara );
+BOOL lcl_CopyLineToDoc( const _FndLine*& rpFndLn, void* pPara );
+
+BOOL lcl_BoxSetHeadCondColl( const SwTableBox*& rpBox, void* pPara );
+BOOL lcl_LineSetHeadCondColl( const SwTableLine*& rpLine, void* pPara );
+
+
+#ifndef PRODUCT
+void _CheckBoxWidth( const SwTableLine& rLine, SwTwips nSize );
+#endif
+
+void _InsTblBox( SwDoc* pDoc, SwTableNode* pTblNd,
+                SwTableLine* pLine, SwTableBoxFmt* pBoxFrmFmt,
+                SwTableBox* pBox, USHORT nInsPos, USHORT nCnt = 1 );
+
+void _DeleteBox( SwTable& rTbl, SwTableBox* pBox, SwUndo* pUndo = 0,
+                BOOL bCalcNewSize = TRUE, const BOOL bCorrBorder = TRUE,
+                SwShareBoxFmts* pShareFmts = 0 );
+
+// Klasse fuers SplitTable
+// sammelt von einer Line die Boxen aller obersten oder untersten Lines
+// in einem Array. Zusaetzlich werden die Positionen vermerkt.
+// ( die Implementierung steht im ndtbl.cxx)
+
+class SwCollectTblLineBoxes
+{
+    SvUShorts aPosArr;
+    SwSelBoxes_SAR aBoxes;
+    SwHistory* pHst;
+    USHORT nMode, nWidth;
+    BOOL bGetFromTop : 1;
+    BOOL bGetValues : 1;
+
+public:
+    SwCollectTblLineBoxes( BOOL bTop, USHORT nMd = 0, SwHistory* pHist=0 )
+        : aPosArr( 16, 16 ), aBoxes( 16, 16 ),
+        bGetFromTop( bTop ), bGetValues( TRUE ), nMode( nMd ),
+        nWidth( 0 ), pHst( pHist )
+    {}
+
+    void AddBox( const SwTableBox& rBox );
+    const SwTableBox* GetBoxOfPos( const SwTableBox& rBox );
+    void AddToUndoHistory( const SwCntntNode& rNd );
+
+    USHORT Count() const                { return aBoxes.Count(); }
+    const SwTableBox& GetBox( USHORT nPos, USHORT* pWidth = 0 ) const
+        {
+            // hier wird die EndPos der Spalte benoetigt!
+            if( pWidth )
+                *pWidth = nPos+1 == aPosArr.Count() ? nWidth
+                                                    : aPosArr[ nPos+1 ];
+            return *aBoxes[ nPos ];
+        }
+
+    BOOL IsGetFromTop() const           { return bGetFromTop; }
+    BOOL IsGetValues() const            { return bGetValues; }
+
+    USHORT GetMode() const              { return nMode; }
+    void SetValues( BOOL bFlag )        { bGetValues = FALSE; nWidth = 0;
+                                          bGetFromTop = bFlag; }
+    FASTBOOL Resize( USHORT nOffset, USHORT nWidth );
+};
+
+BOOL lcl_Box_CollectBox( const SwTableBox*& rpBox, void* pPara );
+BOOL lcl_Line_CollectBox( const SwTableLine*& rpLine, void* pPara );
+
+BOOL lcl_BoxSetSplitBoxFmts( const SwTableBox*& rpBox, void* pPara );
+
+
+
+
+struct _SwGCLineBorder
+{
+    const SwTableLines* pLines;
+    SwShareBoxFmts* pShareFmts;
+    USHORT nLinePos;
+
+    _SwGCLineBorder( const SwTable& rTable )
+        : pLines( &rTable.GetTabLines() ), nLinePos( 0 ), pShareFmts(0) {}
+
+    _SwGCLineBorder( const SwTableBox& rBox )
+        : pLines( &rBox.GetTabLines() ), nLinePos( 0 ), pShareFmts(0) {}
+    BOOL IsLastLine() const { return nLinePos + 1 >= pLines->Count(); }
+};
+
+class _SwGCBorder_BoxBrd
+{
+    const SvxBorderLine* pBrdLn;
+    BOOL bAnyBorderFnd;
+public:
+    _SwGCBorder_BoxBrd() : pBrdLn( 0 ), bAnyBorderFnd( FALSE ) {}
+
+    void SetBorder( const SvxBorderLine& rBorderLine )
+        { pBrdLn = &rBorderLine; bAnyBorderFnd = FALSE; }
+
+    // checke, ob die linke Border dieselbe wie die gesetzte ist
+    // returnt FALSE falls gar keine Border gesetzt ist
+    BOOL CheckLeftBorderOfFormat( const SwFrmFmt& rFmt );
+
+    BOOL IsAnyBorderFound() const { return bAnyBorderFnd; }
+};
+
+BOOL lcl_GC_Line_Border( const SwTableLine*& , void* pPara );
+BOOL lcl_GC_Box_Border( const SwTableBox*& , void* pPara );
+
+BOOL lcl_GCBorder_ChkBoxBrd_L( const SwTableLine*& , void* pPara );
+BOOL lcl_GCBorder_ChkBoxBrd_B( const SwTableBox*& , void* pPara );
+
+BOOL lcl_GCBorder_GetLastBox_L( const SwTableLine*& , void* pPara );
+BOOL lcl_GCBorder_GetLastBox_B( const SwTableBox*& , void* pPara );
+
+
+class SwShareBoxFmt
+{
+    const SwFrmFmt* pOldFmt;
+    SvPtrarr aNewFmts;
+
+public:
+    SwShareBoxFmt( const SwFrmFmt& rFmt )
+        : pOldFmt( &rFmt ), aNewFmts( 1, 4 )
+    {}
+
+    const SwFrmFmt& GetOldFormat() const { return *pOldFmt; }
+
+    SwFrmFmt* GetFormat( long nWidth ) const;
+    SwFrmFmt* GetFormat( const SfxPoolItem& rItem ) const;
+    void AddFormat( const SwFrmFmt& rFmt );
+    // returnt TRUE, wenn geloescht werden kann
+    FASTBOOL RemoveFormat( const SwFrmFmt& rFmt );
+};
+
+
+SV_DECL_PTRARR_DEL( _SwShareBoxFmts, SwShareBoxFmt*, 8, 8 )
+
+class SwShareBoxFmts
+{
+    _SwShareBoxFmts aShareArr;
+    BOOL Seek_Entry( const SwFrmFmt& rFmt, USHORT* pPos ) const;
+
+    void ChangeFrmFmt( SwTableBox* pBox, SwTableLine* pLn, SwFrmFmt& rFmt );
+
+public:
+    SwShareBoxFmts() {}
+    ~SwShareBoxFmts();
+
+    SwFrmFmt* GetFormat( const SwFrmFmt& rFmt, long nWidth ) const;
+    SwFrmFmt* GetFormat( const SwFrmFmt& rFmt, const SfxPoolItem& ) const;
+
+    void AddFormat( const SwFrmFmt& rOld, const SwFrmFmt& rNew );
+
+    void SetSize( SwTableBox& rBox, const SwFmtFrmSize& rSz );
+    void SetAttr( SwTableBox& rBox, const SfxPoolItem& rItem );
+    void SetAttr( SwTableLine& rLine, const SfxPoolItem& rItem );
+
+    void RemoveFormat( const SwFrmFmt& rFmt );
+};
+
+
+
+#endif
diff --git a/sw/source/core/inc/txmsrt.hxx b/sw/source/core/inc/txmsrt.hxx
new file mode 100644
index 000000000000..57072e8ea8f0
--- /dev/null
+++ b/sw/source/core/inc/txmsrt.hxx
@@ -0,0 +1,243 @@
+/*************************************************************************
+ *
+ *  $RCSfile: txmsrt.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:21 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _TXMSRT_HXX
+#define _TXMSRT_HXX
+
+#ifndef _TOX_HXX
+#include 
+#endif
+
+class International;
+class SwCntntNode;
+class SwTxtNode;
+class SwTxtTOXMark;
+class SwIndex;
+class SwFmtFld;
+
+enum TOXSortType
+{
+    TOX_SORT_INDEX,
+    TOX_SORT_CUSTOM,
+    TOX_SORT_CONTENT,
+    TOX_SORT_PARA,
+    TOX_SORT_TABLE,
+    TOX_SORT_AUTHORITY
+};
+
+struct SwTOXSource
+{
+    const SwCntntNode* pNd;
+    xub_StrLen nPos;
+    BOOL bMainEntry;
+
+    SwTOXSource() : pNd(0), nPos(0), bMainEntry(FALSE) {}
+    SwTOXSource( const SwCntntNode* pNode, xub_StrLen n, BOOL bMain )
+        : pNd(pNode), nPos(n), bMainEntry(bMain)
+    {}
+};
+
+SV_DECL_VARARR( SwTOXSources, SwTOXSource, 0, 10 )
+
+/*--------------------------------------------------------------------
+     Beschreibung: Klassen fuer die Sortierung der Verzeichnisse
+ --------------------------------------------------------------------*/
+
+struct SwTOXSortTabBase
+{
+    SwTOXSources aTOXSources;
+    const SwTxtNode* pTOXNd;
+    const SwTxtTOXMark* pTxtMark;
+    const International* pIntl;
+    ULONG nPos;
+    xub_StrLen nCntPos;
+    USHORT nType, nLanguage;
+    static USHORT nOpt;
+
+    SwTOXSortTabBase( TOXSortType nType,
+                      const SwCntntNode* pTOXSrc,
+                      const SwTxtTOXMark* pTxtMark,
+                      const International* pIntl );
+
+    USHORT  GetType() const         { return nType; }
+    USHORT  GetOptions() const      { return nOpt; }
+
+    virtual void    FillText( SwTxtNode& rNd, const SwIndex& rInsPos, USHORT nAuthField = 0) const;
+    virtual USHORT  GetLevel()  const = 0;
+    virtual BOOL    operator==( const SwTOXSortTabBase& );
+    virtual BOOL    operator<( const SwTOXSortTabBase& );
+
+    virtual String  GetURL() const;
+
+    inline const String& GetTxt() const;
+private:
+    BOOL bValidTxt;
+    String sSortTxt;
+    virtual void _GetText( String& ) = 0;
+};
+
+inline const String& SwTOXSortTabBase::GetTxt() const
+{
+    if( !bValidTxt )
+    {
+        SwTOXSortTabBase* pThis = (SwTOXSortTabBase*)this;
+        pThis->_GetText( pThis->sSortTxt );
+        pThis->bValidTxt = TRUE;
+    }
+    return sSortTxt;
+}
+
+/*--------------------------------------------------------------------
+     Beschreibung: fuer Sortierung nach Text
+ --------------------------------------------------------------------*/
+
+struct SwTOXIndex : public SwTOXSortTabBase
+{
+    SwTOXIndex( const SwTxtNode&, const SwTxtTOXMark*, USHORT nOptions, BYTE nKeyLevel,
+                    const International& rIntl );
+
+    virtual void    FillText( SwTxtNode& rNd, const SwIndex& rInsPos, USHORT nAuthField = 0 ) const;
+    virtual USHORT  GetLevel() const;
+    virtual BOOL    operator==( const SwTOXSortTabBase& );
+    virtual BOOL    operator<( const SwTOXSortTabBase& );
+
+private:
+    virtual void _GetText( String& );
+    BYTE    nKeyLevel;
+};
+
+struct SwTOXCustom : public SwTOXSortTabBase
+{
+    SwTOXCustom(const String& rKey, USHORT nLevel, const International& rIntl );
+
+    virtual USHORT GetLevel() const;
+    virtual BOOL   operator==( const SwTOXSortTabBase& );
+    virtual BOOL   operator<( const SwTOXSortTabBase& );
+
+private:
+    virtual void _GetText( String& );
+    String  aKey;
+    USHORT  nLev;
+};
+
+/*--------------------------------------------------------------------
+     Beschreibung: fuer Sortierung nach Position
+ --------------------------------------------------------------------*/
+
+struct SwTOXContent : public SwTOXSortTabBase
+{
+    SwTOXContent( const SwTxtNode&, const SwTxtTOXMark*,
+                const International& rIntl );
+
+    virtual void    FillText( SwTxtNode& rNd, const SwIndex& rInsPos, USHORT nAuthField = 0 ) const;
+    virtual USHORT  GetLevel() const;
+private:
+    virtual void _GetText( String& );
+};
+
+struct SwTOXPara : public SwTOXSortTabBase
+{
+    SwTOXPara( const SwCntntNode&, SwTOXElement, USHORT nLevel = FORM_ALPHA_DELIMITTER );
+
+    void    SetStartIndex( xub_StrLen nSet)     { nStartIndex = nSet;}
+    void    SetEndIndex( xub_StrLen nSet )      { nEndIndex = nSet;}
+
+    virtual void    FillText( SwTxtNode& rNd, const SwIndex& rInsPos, USHORT nAuthField = 0 ) const;
+    virtual USHORT  GetLevel() const;
+
+    virtual String  GetURL() const;
+private:
+    virtual void _GetText( String& );
+    SwTOXElement eType;
+    USHORT m_nLevel;
+    xub_StrLen nStartIndex;
+    xub_StrLen nEndIndex;
+};
+
+struct SwTOXTable : public SwTOXSortTabBase
+{
+    SwTOXTable( const SwCntntNode& rNd );
+    void    SetLevel(USHORT nSet){nLevel = nSet;}
+
+    virtual USHORT  GetLevel() const;
+
+    virtual String  GetURL() const;
+private:
+    virtual void _GetText( String& );
+    USHORT nLevel;
+};
+
+struct SwTOXAuthority : public SwTOXSortTabBase
+{
+private:
+    SwFmtFld& m_rField;
+    virtual void    FillText( SwTxtNode& rNd, const SwIndex& rInsPos, USHORT nAuthField = 0 ) const;
+    virtual void _GetText( String& );
+public:
+    SwTOXAuthority( const SwCntntNode& rNd, SwFmtFld& rField, const International& rIntl );
+    SwFmtFld& GetFldFmt() {return m_rField;}
+
+    virtual BOOL    operator==( const SwTOXSortTabBase& );
+    virtual BOOL    operator<( const SwTOXSortTabBase& );
+    virtual USHORT  GetLevel() const;
+};
+
+
+#endif // _TXMSRT_HXX
diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx
new file mode 100644
index 000000000000..f8a309b836d2
--- /dev/null
+++ b/sw/source/core/inc/txtfrm.hxx
@@ -0,0 +1,639 @@
+/*************************************************************************
+ *
+ *  $RCSfile: txtfrm.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:21 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _TXTFRM_HXX
+#define _TXTFRM_HXX
+
+#ifndef _SVMEMPOOL_HXX //autogen
+#include 
+#endif
+#ifndef _STRING_HXX //autogen
+#include 
+#endif
+#include "cntfrm.hxx"
+
+#define STRSIZE(x) (sizeof(x)-1)
+
+class SwCharRange;
+class SwTxtNode;
+class SwTxtFormatter;
+class SwTxtFormatInfo;
+class SwParaPortion;
+class WidowsAndOrphans;
+class Sw3FrameIo;
+class SwBodyFrm;
+class SwFooterFrm;
+class SwTxtFtn;
+class SwInterHyphInfo;      // Hyphenate()
+class SwCache;
+class SwBorderAttrs;
+class SwFrmFmt;
+class SwFldPortion;
+class OutputDevice;
+class SwTestFormat;
+class SwStripes;
+struct SwCrsrMoveState;
+struct SwFillData;
+
+class SwTxtFrm: public SwCntntFrm
+{
+    friend class SwTestFormat;
+    friend class WidowsAndOrphans;
+    friend class SwTxtFrmLocker;        // duerfen Lock()/Unlock()
+    friend sal_Bool lcl_ChangeOffset( SwTxtFrm* pFrm, USHORT nNew );
+
+
+    static SwCache *pTxtCache;  //Pointer auf den Line-Cache
+    static long nMinPrtLine;    //Diese Linie darf beim Drucken nicht
+        //unterschritten werden, Hack fuer Tabellenzellen ueber mehrere Seiten
+
+    ULONG  nAllLines        :24;//Anzahl der Zeilen fuer das Paint (inkl. nThisLines)
+    ULONG  nThisLines       :8; //Anzahl der Zeilen dieses Frames
+
+    xub_StrLen nOfst;           //nOfst gibt den Offset im Cntnt (Anzahl Zeichen) an.
+
+    USHORT nCacheIdx;           //Index in den Cache, USHRT_MAX wenn definitiv
+                                //kein passendes Objekt im Cache steht.
+
+    //Teilt den Master ab und erzeugt einen Follow oder passt die
+    //Daten im Follow an.
+           void _AdjustFollow( SwTxtFormatter &rLine, const xub_StrLen nOffset,
+                               const xub_StrLen nStrEnd, const sal_uInt8 nMode );
+    inline void AdjustFollow( SwTxtFormatter &rLine, const xub_StrLen nOffset,
+                              const xub_StrLen nStrEnd, const sal_uInt8 nMode );
+
+    //Iteriert ueber alle Zeilen und stellt das Linespacing
+    //entsprechend dem Attribut ein.
+    void CalcLineSpace();
+
+    void InitCtor();        // Wird in beiden Ctoren gerufen
+
+    // Wird nur in Format gerufen:
+    void AdjustFrm( const SwTwips nChgHeight, sal_Bool bHasToFit = sal_False );
+
+    // wertet in Format() die Preps aus.
+    sal_Bool CalcPreps();
+    void PrepWidows( const USHORT nNeed, sal_Bool bNotify = sal_True );
+    void _InvalidateRange( const SwCharRange &, const long = 0);
+    inline void InvalidateRange( const SwCharRange &, const long = 0);
+
+    // WidowsAndOrphans, AdjustFrm, AdjustFollow
+    void FormatAdjust( SwTxtFormatter &rLine, WidowsAndOrphans &rFrmBreak,
+                       const xub_StrLen nStrLen, const sal_Bool bDummy );
+
+    sal_Bool bLocked        : 1;        // im Format?
+    sal_Bool bFormatted     : 1;        // nach Format auf sal_True
+    sal_Bool bWidow         : 1;        // sind wir ein Widow
+    sal_Bool bJustWidow     : 1;        // haben wir soeben Widow angefordert
+    sal_Bool bEmpty         : 1;        // sind wir ein leerer Absatz
+    sal_Bool bInFtnConnect  : 1;        // Steht gerade im Connect
+    sal_Bool bFtn           : 1;        // Hat mindestens eine Fussnote
+    sal_Bool bRepaint       : 1;        // TxtFrm: Repaint steht zur Abholung bereit
+    sal_Bool bBlinkPor      : 1;        // enthaelt Blink-Portions
+    sal_Bool bFieldFollow   : 1;        // beginne mit Feldrest des Masters
+    sal_Bool bHasAnimation  : 1;        // enthaelt animierte SwGrfNumPortion
+
+    void ResetPreps();
+    inline void Lock() { bLocked = sal_True; }
+    inline void Unlock() { bLocked = sal_False; }
+    inline void SetFormatted( const sal_Bool bNew ) { bFormatted = bNew; }
+    inline void SetWidow( const sal_Bool bNew ) { bWidow = bNew; }
+    inline void SetJustWidow( const sal_Bool bNew ) { bJustWidow = bNew; }
+    inline void SetEmpty( const sal_Bool bNew ) { bEmpty = bNew; }
+    inline void SetFieldFollow( const sal_Bool bNew ) { bFieldFollow = bNew; }
+
+    sal_Bool IsIdxInside( const xub_StrLen nPos, const xub_StrLen nLen ) const;
+
+    // Wechselt den Frame oder auch nicht (vgl. FlyCnt)
+    sal_Bool _GetCrsrOfst(SwPosition *pPos, const Point &rPoint,
+                      const sal_Bool bChgFrm, const SwCrsrMoveState* = 0 ) const;
+    void FillCrsrPos( SwFillData &rFill ) const;
+
+    // formatiert genau eine Zeile ...
+    sal_Bool FormatLine( SwTxtFormatter &rLine, const sal_Bool bPrev );
+
+    // Um Stack einzusparen aufgeteilt ...
+    // _Format ruft _Format mit Parametern
+    void _Format( SwParaPortion *pPara );
+    void _Format( SwTxtFormatter &rLine, SwTxtFormatInfo &rInf,
+                  const sal_Bool bAdjust = sal_False );
+    void FormatOnceMore( SwTxtFormatter &rLine, SwTxtFormatInfo &rInf );
+
+    // formatiert den Follow und sorgt fuer die Entsorgung bei Orphans
+    sal_Bool CalcFollow(  const xub_StrLen nTxtOfst );
+
+    // korrigiert die Stelle ab der formatiert werden muss.
+    xub_StrLen FindBrk(const String &rTxt, const xub_StrLen nStart,
+                                       const xub_StrLen nEnd) const;
+
+    // inline-Weiche
+    SwTwips _GetFtnFrmHeight() const;
+
+    // Aus CalcPreps ausgelagert.
+    sal_Bool CalcPrepFtnAdjust();
+
+    // Fuer Ftn und WidOrp: Zwangsvalidierung
+    void ValidateFrm();
+    void ValidateBodyFrm();
+
+    sal_Bool _GetDropRect( SwRect &rRect ) const;
+
+    void SetPara( SwParaPortion *pNew, sal_Bool bDelete = sal_True );
+
+    sal_Bool _IsFtnNumFrm() const;
+
+    // 6995: Formatinformationen auffrischen
+    sal_Bool FormatQuick();
+
+    // Opt: Leere Absaetze formatieren
+    sal_Bool FormatEmpty();
+    SwTwips EmptyHeight() const;
+    // Opt: Leere Absaetze painten
+    sal_Bool PaintEmpty( const SwRect &, sal_Bool bCheck ) const;
+
+    void ChgThisLines();//Muss immer gerufen werden, wenn sich die Zeilenazahl
+                        //veraendert haben kann.
+public:
+
+    //public, weil der eine oder andere die Methode rufen darf um das
+    //Prepare zu sparen - mit Vorsicht zu geniessen!
+    void Init();
+
+    // Wird von FormatSpelling( ) gerufen
+    SwRect _AutoSpell( SwCntntNode* , USHORT );
+    // Wird vom CollectAutoCmplWords gerufen
+    void CollectAutoCmplWrds( SwCntntNode* , USHORT , sal_Bool bIsVisArea );
+
+    //Liefert in pPoint den X- und Y-Offset der linken, oberen
+    //Ecke eines Characters innerhalb der SSize des
+    //Paragraph-Layout (nicht absolut oder Window-relativ)
+    //zurueck. Wenn nOffset groesser ist als die Anzahl der
+    //Character im Textbuffer, liefert die Funktion sal_False, sal_True
+    //sonst.
+    virtual sal_Bool   GetCharRect( SwRect &, const SwPosition&,
+                                SwCrsrMoveState* = 0) const;
+    // Eine etwas abgespeckte GetCharRect-Version fuer autopositionierte Rahmen
+    sal_Bool GetAutoPos( SwRect &, const SwPosition& ) const;
+
+    //Liefert in nOffset den Offset des Characters innerhalb des
+    //gesetzten Textbuffers zurueck, welcher der durch aPoint
+    //gegebenen Position innerhalb der SSize des Layout am
+    //naechsten ist. Wenn der SPoint ausserhalb der SSize liegt,
+    //liefert die Funktion sal_False, sal_True sonst.
+    virtual sal_Bool GetCrsrOfst( SwPosition *, Point&,
+                              const SwCrsrMoveState* = 0) const;
+
+    // GetKeyCrsrOfst sorgt dafuer, dass der Frame nicht gewechselt wird
+    // (z.B. Wechsel in den zeichengebundenen Frame).
+    inline  sal_Bool GetKeyCrsrOfst(SwPosition *pPos, const Point &rPoint ) const
+            { return _GetCrsrOfst( pPos, rPoint, sal_False ); }
+
+    void   PaintExtraData( const SwRect & rRect ) const; //Seitennummer usw.
+    SwRect Paint();
+    virtual void Paint( const SwRect & ) const;
+    virtual void Modify( SfxPoolItem*, SfxPoolItem* );
+    virtual sal_Bool GetInfo( SfxPoolItem & ) const;
+
+    //Layoutorientiertes Cursortravelling: Linker, rechter Rand,
+    //vorhergehende/naechste Zeile, gleiche horizontale Position.
+    virtual sal_Bool LeftMargin(SwPaM *) const;
+    virtual sal_Bool RightMargin(SwPaM *, sal_Bool bAPI = sal_False) const;
+
+    virtual sal_Bool UnitUp(SwPaM *, const SwTwips nOffset = 0,
+                            sal_Bool bSetInReadOnly = sal_False  ) const;
+    virtual sal_Bool UnitDown(SwPaM *, const SwTwips nOffset = 0,
+                            sal_Bool bSetInReadOnly = sal_False ) const;
+    sal_Bool _UnitUp(SwPaM *, const SwTwips nOffset = 0,
+                            sal_Bool bSetInReadOnly = sal_False ) const;
+    sal_Bool _UnitDown(SwPaM *, const SwTwips nOffset = 0,
+                            sal_Bool bSetInReadOnly = sal_False ) const;
+
+    // Methoden zur Verwaltung von FolgeFrames
+           SwCntntFrm *SplitFrm( const xub_StrLen nTxtPos );
+           SwCntntFrm *JoinFrm();
+    inline USHORT      GetOfst() const { return nOfst; }
+           void        _SetOfst( const USHORT nNewOfst );
+    inline void        SetOfst ( const USHORT nNewOfst );
+    inline void        ManipOfst ( const USHORT nNewOfst ){ nOfst = nNewOfst; }
+           SwTxtFrm   *GetFrmAtPos ( const SwPosition &rPos);
+    inline const SwTxtFrm *GetFrmAtPos ( const SwPosition &rPos) const;
+           SwTxtFrm   *GetFrmAtOfst( const xub_StrLen nOfst );
+    // Wenn es einen Follow gibt und wir selbst keinen Text enthalten:
+    inline sal_Bool IsEmptyMaster() const
+        { return GetFollow() && !GetFollow()->GetOfst(); }
+
+    // Liefert den zu bearbeitenden Textausschnitt zurueck (inline, s.u.)
+    const String& GetTxt() const;
+    inline SwTxtNode *GetTxtNode()
+        { return (SwTxtNode*)SwCntntFrm::GetNode(); }
+    inline const SwTxtNode *GetTxtNode() const
+        { return (SwTxtNode*)SwCntntFrm::GetNode(); }
+
+    SwTxtFrm(SwTxtNode * const);
+    SwTxtFrm( Sw3FrameIo&, SwLayoutFrm* );
+    inline ~SwTxtFrm() { if( HasAnimation() ) ClearPara(); }
+
+    virtual void Store( Sw3FrameIo& ) const;
+
+    // SwCntntFrm: der "kurze Dienstweg" fuer die Frames.
+    // Wer den void* falsch casted ist selbst Schuld!
+    // Auf jedenfall muss der void* auf 0 geprueft werden.
+    virtual void Prepare( const PrepareHint ePrep = PREP_CLEAR,
+                          const void *pVoid = 0, sal_Bool bNotify = sal_True );
+
+    //nMaxHeight liefert die benoetigte Hoehe,
+    //bSplit sagt, obj der Absatz gesplittet werden muss.
+    virtual sal_Bool WouldFit( SwTwips &nMaxHeight, sal_Bool &bSplit );
+
+    // Hier das WouldFit-Aequivalent fuer mal kurz probeweise
+    // umgehaengte TextFrames, auch hier liefert
+    // nMaxHeight die benoetigte Hoehe,
+    // und bSplit sagt, obj der Absatz gesplittet werden muss.
+    // Uebergeben wird der potentielle Vorgaenger fuer die Abstandsberechnung
+    sal_Bool TestFormat( const SwFrm* pPrv, SwTwips &nMaxHeight, sal_Bool &bSplit );
+
+    // Wir formatieren eine Zeile fuer die interaktive Trennung
+    // Return: found
+    sal_Bool Hyphenate( SwInterHyphInfo &rInf );
+
+    // Liefert den Rest eines Feldes fuer den Follow zurueck
+    const SwFldPortion* GetRestPortion();
+
+    // Probegrow
+    inline SwTwips GrowTst( const SwTwips nGrow );
+
+    SwParaPortion *GetPara();
+    inline const SwParaPortion *GetPara() const;
+    inline sal_Bool HasPara() const;
+    sal_Bool _HasPara() const;
+
+    // RTTI
+    TYPEINFO();
+    DECL_FIXEDMEMPOOL_NEWDEL(SwTxtFrm)
+
+    // Locking
+    inline sal_Bool IsLocked()      const { return bLocked;     }
+    inline sal_Bool IsFormatted()   const { return bFormatted;  }
+
+    inline sal_Bool IsWidow()       const { return bWidow;      }
+    inline sal_Bool IsJustWidow()   const { return bJustWidow;  }
+    inline sal_Bool IsEmpty()       const { return bEmpty;      }
+    inline sal_Bool HasFtn()        const { return bFtn;        }
+    inline sal_Bool IsInFtnConnect()const { return bInFtnConnect;}
+    inline sal_Bool IsFieldFollow() const { return bFieldFollow;}
+
+    inline void SetRepaint() const;
+    inline void ResetRepaint() const;
+    inline sal_Bool HasRepaint() const { return bRepaint; }
+    inline void SetBlinkPor() const;
+    inline void ResetBlinkPor() const;
+    inline sal_Bool HasBlinkPor() const { return bBlinkPor; }
+    inline void SetAnimation() const
+        { ( (SwTxtFrm*)this )->bHasAnimation = sal_True; }
+    inline sal_Bool HasAnimation() const { return bHasAnimation; }
+
+    // Hat der Frm eine lokale Fussnote (in diesem Frm bzw. Follow)?
+#ifdef PRODUCT
+    void CalcFtnFlag();
+#else
+    void CalcFtnFlag( xub_StrLen nStop = STRING_LEN );//Fuer den Test von SplitFrm
+#endif
+
+    // Hidden
+    sal_Bool IsHiddenNow() const;       // bHidden && pOut == pPrt
+    void HideHidden();              // Anhaengsel entfernen wenn Hidden
+
+    // Ftn
+    void RemoveFtn( const xub_StrLen nStart = 0,
+                    const xub_StrLen nLen = STRING_LEN );
+    inline SwTwips GetFtnFrmHeight() const;
+    SwTxtFrm *FindFtnRef( const SwTxtFtn *pFtn );
+    inline const SwTxtFrm *FindFtnRef( const SwTxtFtn *pFtn ) const
+    { return FindFtnRef( pFtn ); }
+    void ConnectFtn( SwTxtFtn *pFtn, const SwTwips nDeadLine );
+
+    // Wenn wir eine Ftn sind, die auf ihre Referenz zu waechst...
+    // public weil von SwCntntFrm::MakeAll benoetigt.
+    SwTwips GetFtnLine( const SwTxtFtn *pFtn, sal_Bool bLocked ) const;
+
+    // Liefern den linken und den rechten Rand in
+    // Dokumentkoordinaten (unter Beachtung der Absatzattribute).
+    inline SwTwips GetLeftMargin() const;
+    inline SwTwips GetRightMargin() const;
+
+    virtual void Format( const SwBorderAttrs *pAttrs = 0 );
+
+    // Liefert die Summe der Zeilenhoehen in pLine zurueck.
+    USHORT GetParHeight() const;
+
+    // Liefert die Resthoehe zurueck
+    inline SwTwips GetRstHeight() const;
+
+    inline       SwTxtFrm *GetFollow();
+    inline const SwTxtFrm *GetFollow() const;
+    inline       SwTxtFrm *FindMaster();
+    inline const SwTxtFrm *FindMaster() const;
+
+    // Suche die Seitennummer von ErgoSum und QuoVadis
+    SwTxtFrm *FindQuoVadisFrm();
+    SwTxtFrm *FindErgoSumFrm();
+    void SetErgoSumNum( const USHORT nErgo );
+
+    // holt die Formatierug nach, wenn der Idle-Handler zugeschlagen hat.
+    SwTxtFrm *GetFormatted();
+
+    // wird demnaechst uebertragen
+    inline void SetFtn( const sal_Bool bNew ) { bFtn = bNew; }
+
+    // Beruecksichtigung der Follows
+    inline sal_Bool IsInside( const xub_StrLen nPos ) const;
+
+    const SwBodyFrm   *FindBodyFrm()   const;
+
+    // DropCaps und Selektionen
+    inline sal_Bool GetDropRect( SwRect &rRect ) const
+    { return HasPara() ? _GetDropRect( rRect ) : sal_False; }
+
+    static SwCache *GetTxtCache() { return pTxtCache; }
+    static void     SetTxtCache( SwCache *pNew ) { pTxtCache = pNew; }
+
+    static long GetMinPrtLine() { return nMinPrtLine; }
+    static void SetMinPrtLine( long nNew ) { nMinPrtLine = nNew; }
+
+    inline USHORT GetCacheIdx() const { return nCacheIdx; }
+    inline void   SetCacheIdx( const USHORT nNew ) { nCacheIdx = nNew; }
+
+    //Entfert die Line-Informationen aus dem Cache.
+    void ClearPara();
+
+    // Bin ich ein FtnFrm, der eine Nummer am Absatzanfang hat?
+    inline sal_Bool IsFtnNumFrm() const
+    { return IsInFtn() && !GetIndPrev() && _IsFtnNumFrm(); }
+
+    // simuliert eine Formatierung, als wenn es keinen rechten Rand und
+    // keine Flys oder andere Hindernisse gaebe und liefert die Breite.
+    USHORT CalcFitToContent();
+
+    // liefert den zusaetzlichen Zeilenabstand fuer den naechsten Absatz
+    USHORT GetLineSpace() const;
+
+    // liefert die erste Zeilenhoehe zurueck
+    USHORT FirstLineHeight() const;
+
+    const SwFrmFmt* IsFirstBullet();
+
+    // Haengt FlyInCntFrm um, wenn nEnd > Index >= nStart ist.
+    void MoveFlyInCnt( SwTxtFrm *pNew, USHORT nStart, USHORT nEnd );
+
+    // Berechnet die Position von FlyInCntFrms
+    USHORT CalcFlyPos( SwFrmFmt* pSearch );
+
+    // Ermittelt die Startposition und Schrittweite des Registers
+    sal_Bool FillRegister( SwTwips& rRegStart, USHORT& rRegDiff );
+
+
+    USHORT GetLineCount( USHORT nPos );     //Ermittelt die Zeilenanzahl
+
+    //Fuer die Anzeige der Zeilennummern.
+    ULONG GetAllLines()  const { return nAllLines; }
+    ULONG GetThisLines() const { return nThisLines;}
+    void RecalcAllLines();
+
+    // Stoppt Animationen innerhalb von Numerierungen
+    void StopAnimation( OutputDevice *pOut );
+
+    void CriticalLines(const OutputDevice& rOut,SwStripes &rStripes,long nOffs);
+};
+
+/*************************************************************************
+ *                          class SwTxtFrmLocker
+ *************************************************************************/
+
+class SwTxtFrmLocker
+{
+private:
+    SwTxtFrm * const pFrm;
+public:
+    inline SwTxtFrmLocker( SwTxtFrm *pTxtFrm )
+        : pFrm( pTxtFrm->IsLocked() ? 0 : pTxtFrm )
+    { if( pFrm ) pFrm->Lock(); }
+    inline ~SwTxtFrmLocker() { if( pFrm ) pFrm->Unlock(); }
+};
+
+/*************************************************************************
+ *                      Inline-Implementierung
+ *************************************************************************/
+
+inline const SwParaPortion *SwTxtFrm::GetPara() const
+{
+    return ((SwTxtFrm*)this)->GetPara();
+}
+
+inline sal_Bool SwTxtFrm::HasPara() const
+{
+    return nCacheIdx != USHRT_MAX ? _HasPara() : sal_False;
+}
+
+// 9104: Frm().Height() - Prt().Height(), siehe widorp.cxx und 7455, 6114, 7908
+inline SwTwips SwTxtFrm::GetRstHeight() const
+{
+    return !GetUpper() ? 0 : ((const SwFrm*)GetUpper())->Frm().Top()
+                           + ((const SwFrm*)GetUpper())->Prt().Top()
+                           + ((const SwFrm*)GetUpper())->Prt().Height()
+                           - Frm().Top() - (Frm().Height() - Prt().Height());
+}
+
+inline SwTwips SwTxtFrm::GetLeftMargin() const
+{
+    return Frm().Left() + Prt().Left();
+}
+inline SwTwips SwTxtFrm::GetRightMargin() const
+{
+    return Frm().Left() + Prt().Left() + Prt().Width();
+}
+inline SwTwips SwTxtFrm::GrowTst( const SwTwips nGrow )
+{
+    return Grow( nGrow, pHeight, sal_True );
+}
+
+
+#ifdef DEBUG
+// fragt auf WYSIWYG DBG ab
+extern sal_Bool IsDbg( const SwTxtFrm *pFrm );
+#define DBTXTFRM aDbstream << "SwTxtFrm[" << GetFrmId() << "]"
+#endif
+
+inline sal_Bool SwTxtFrm::IsInside( const xub_StrLen nPos ) const
+{
+    sal_Bool bRet = sal_True;
+    if( nPos < GetOfst() )
+        bRet = sal_False;
+    else
+    {
+        const SwTxtFrm *pFoll = GetFollow();
+        if( pFoll && nPos >= pFoll->GetOfst() )
+            bRet = sal_False;
+    }
+    return bRet;
+}
+
+inline SwTwips SwTxtFrm::GetFtnFrmHeight() const
+{
+    if(  !IsFollow() && IsInFtn() && HasPara() )
+        return _GetFtnFrmHeight();
+    else
+        return 0;
+}
+
+inline SwTxtFrm *SwTxtFrm::FindMaster()
+{
+    return (SwTxtFrm*)SwFlowFrm::FindMaster();
+}
+inline const SwTxtFrm *SwTxtFrm::FindMaster() const
+{
+    return (const SwTxtFrm*)SwFlowFrm::FindMaster();
+}
+inline const SwTxtFrm *SwTxtFrm::GetFollow() const
+{
+    return (const SwTxtFrm*)SwCntntFrm::GetFollow();
+}
+inline SwTxtFrm *SwTxtFrm::GetFollow()
+{
+    return (SwTxtFrm*)SwCntntFrm::GetFollow();
+}
+
+inline const SwTxtFrm *SwTxtFrm::GetFrmAtPos( const SwPosition &rPos) const
+{
+    return ((SwTxtFrm*)this)->GetFrmAtPos( rPos );
+}
+
+inline void SwTxtFrm::AdjustFollow( SwTxtFormatter &rLine,
+    const xub_StrLen nOffset, const xub_StrLen nStrEnd, const sal_uInt8 nMode )
+{
+    if ( HasFollow() )
+        _AdjustFollow( rLine, nOffset, nStrEnd, nMode );
+}
+
+inline void SwTxtFrm::SetOfst( const xub_StrLen nNewOfst )
+{
+    if ( nOfst != nNewOfst )
+        _SetOfst( nNewOfst );
+}
+
+inline void SwTxtFrm::SetRepaint() const
+{
+    ((SwTxtFrm*)this)->bRepaint = sal_True;
+}
+inline void SwTxtFrm::ResetRepaint() const
+{
+    ((SwTxtFrm*)this)->bRepaint = sal_False;
+}
+
+inline void SwTxtFrm::SetBlinkPor() const
+{
+    ((SwTxtFrm*)this)->bBlinkPor = sal_True;
+}
+inline void SwTxtFrm::ResetBlinkPor() const
+{
+    ((SwTxtFrm*)this)->bBlinkPor = sal_False;
+}
+
+#ifdef LINGU_STATISTIK
+
+class SwLinguStatistik
+{
+public:
+    long nWords;    // gepruefte Worte
+    long nFlushCnt; // zaehlt die Messungen
+
+    long nWrong;  // als falsch erkannt
+    long nAlter;  // Alternativvorschlaege
+    long nSpellTime; // Zeitmessung
+    long nSynonym; // Thesaurus
+    long nNoSynonym; // Thesaurus ratlos
+    long nMeaning; // Thesaurus-Bedeutung
+    long nNoMeaning; // Thesaurus meinungslos
+    long nTheTime; // Zeitmessung
+    long nHyphens; // Trennstellen
+    long nNoHyph; // Worte ohne Trennstellen
+    long nHyphErr; // Fehler beim Trennen
+    long nHyphTime; // Zeitmessung
+    SpellCheck *pSpell;
+    LanguageType eLang;
+
+    void Flush();
+
+    inline SwLinguStatistik()
+        { nWords = nWrong = nAlter = nSynonym = nNoSynonym =
+          nHyphens = nNoHyph = nHyphErr = nSpellTime = nTheTime =
+          nHyphTime = nFlushCnt = 0;
+          pSpell = NULL;
+          eLang = LANGUAGE_DONTKNOW; }
+    inline ~SwLinguStatistik(){ Flush(); }
+};
+
+// globale Variable, implementiert in txtfrm.cxx
+extern SwLinguStatistik aSwLinguStat;
+
+#define SW_LING(nWhich,nInc) (aSwLinguStat.nWhich) += nInc;
+
+#endif
+
+#endif
diff --git a/sw/source/core/inc/txttypes.hxx b/sw/source/core/inc/txttypes.hxx
new file mode 100644
index 000000000000..86138873077a
--- /dev/null
+++ b/sw/source/core/inc/txttypes.hxx
@@ -0,0 +1,75 @@
+/*************************************************************************
+ *
+ *  $RCSfile: txttypes.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:21 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _TXTTYPES_HXX
+#define _TXTTYPES_HXX
+
+#include "swtypes.hxx"
+
+// Ueberpruefte USHORTs, z.B. Indizes auf Arrays oder garantiert kleine
+// Integerwerte, auch von aussen vorgegebene
+#define MSHORT USHORT
+#define MSHRT_MAX USHRT_MAX
+// Koordinaten: Breite, Hoehe und Offsets in X-/Y-Richtung sowie Ascent etc.
+#define KSHORT USHORT
+#define KSHRT_MAX USHRT_MAX
+
+
+#endif  //_TXTTYPES_HXX
diff --git a/sw/source/core/inc/unoclbck.hxx b/sw/source/core/inc/unoclbck.hxx
new file mode 100644
index 000000000000..ef69639eecf2
--- /dev/null
+++ b/sw/source/core/inc/unoclbck.hxx
@@ -0,0 +1,85 @@
+/*************************************************************************
+ *
+ *  $RCSfile: unoclbck.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:21 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _UNOCLBCK_HXX
+#define _UNOCLBCK_HXX
+
+
+#ifndef _CALBCK_HXX
+#include 
+#endif
+
+class SwXReferenceMark;
+class SwFmtRefMark;
+class SwFmtFtn;
+class SwXFootnote;
+class SwUnoCallBack : public SwModify
+{
+public:
+    SwUnoCallBack(SwModify *pToRegisterIn);
+    virtual ~SwUnoCallBack();
+
+    virtual void Modify( SfxPoolItem *pOldValue, SfxPoolItem *pNewValue );
+
+    // returns the API object of a reference mark if available
+    SwXReferenceMark*   GetRefMark(const SwFmtRefMark& rMark);
+    SwXFootnote*        GetFootnote(const SwFmtFtn& rMark);
+};
+#endif
diff --git a/sw/source/core/inc/viewimp.hxx b/sw/source/core/inc/viewimp.hxx
new file mode 100644
index 000000000000..a7b3377119f5
--- /dev/null
+++ b/sw/source/core/inc/viewimp.hxx
@@ -0,0 +1,269 @@
+/*************************************************************************
+ *
+ *  $RCSfile: viewimp.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:21 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _VIEWIMP_HXX
+#define _VIEWIMP_HXX
+
+
+#ifndef _TIMER_HXX //autogen
+#include 
+#endif
+#ifndef _SV_COLOR_HXX //autogen
+#include 
+#endif
+#include "swtypes.hxx"
+#include "swrect.hxx"
+
+class ViewShell;
+class SwFlyFrm;
+class SwViewOption;
+class SwRegionRects;
+class SwScrollAreas;
+class SwScrollColumn;
+class SwFrm;
+class SwLayAction;
+class SwLayIdle;
+class SwDrawView;
+class SdrPageView;
+class SwPageFrm;
+class SwRegionRects;
+class ExtOutputDevice;
+class SdrPaintInfoRec;
+struct SdrPaintProcRec;
+
+class SwViewImp
+{
+    friend class ViewShell;
+
+    friend class SwLayAction;   //Lay- und IdleAction tragen sich ein und aus.
+    friend class SwLayIdle;
+
+    ViewShell *pSh;             //Falls jemand einen Imp durchreicht und doch
+                                //mal eine ViewShell braucht hier die
+                                //Rueckwaertsverkettung.
+
+    SwDrawView  *pDrawView;     //Unsere DrawView
+    SdrPageView *pSdrPageView;  //Genau eine Seite fuer unsere DrawView
+
+    SwPageFrm     *pFirstVisPage;//Zeigt immer auf die erste sichtbare Seite.
+    SwRegionRects *pRegion;      //Sammler fuer Paintrects aus der LayAction.
+    SwScrollAreas *pScrollRects; //Sammler fuer Scrollrects aus der LayAction.
+    SwScrollAreas *pScrolledArea;//Sammler der gescrollten Rechtecke.
+
+    SwLayAction   *pLayAct;      //Ist gesetzt wenn ein Action-Objekt existiert
+                                 //Wird vom SwLayAction-CTor ein- und vom DTor
+                                 //ausgetragen.
+    SwLayIdle     *pIdleAct;     //Analog zur SwLayAction fuer SwLayIdle.
+
+    AutoTimer     aScrollTimer;  //Fuer das Aufraeumen nach dem Scrollen.
+
+    BOOL bFirstPageInvalid  :1; //Pointer auf erste Seite ungueltig?
+    BOOL bNextScroll        :1; //Scroll in der folgenden EndAction erlaubt?
+    BOOL bScroll            :1; //Scroll in der aktuellen EndAction erlaubt?
+    BOOL bScrolled          :1; //Wurde gescrolled? Dann im Idle aufraeumen.
+
+    BOOL bResetXorVisibility:1; //StartAction/EndAction
+    BOOL bShowHdlPaint      :1; //LockPaint/UnlockPaint
+    BOOL bResetHdlHiddenPaint:1;//  -- "" --
+    BOOL bPaintInScroll     :1; //Paint (Update() im ScrollHdl der ViewShell
+
+    BOOL bSmoothUpdate      :1; //Meber fuer SmoothScroll
+    BOOL bStopSmooth        :1;
+
+    USHORT nRestoreActions  :1; //Die Anzahl der zu restaurierenden Actions (UNO)
+    SwRect aSmoothRect;
+
+    void SetFirstVisPage();     //Neue Ermittlung der ersten sichtbaren Seite
+
+    void ResetNextScroll()    { bNextScroll = FALSE; }
+    void SetNextScroll()      { bNextScroll = TRUE; }
+    void SetScroll()          { bScroll = TRUE; }
+    void ResetScrolled()      { bScrolled = FALSE; }
+    void SetScrolled()        { bScrolled = TRUE; }
+
+    SwScrollAreas *GetScrollRects() { return pScrollRects; }
+    void FlushScrolledArea();
+    BOOL _FlushScrolledArea( SwRect& rRect );
+    BOOL FlushScrolledArea( SwRect& rRect )
+    { if( !pScrolledArea ) return FALSE; return _FlushScrolledArea( rRect ); }
+    void _ScrolledRect( const SwRect& rRect, long nOffs );
+    void ScrolledRect( const SwRect& rRect, long nOffs )
+    { if( pScrolledArea ) _ScrolledRect( rRect, nOffs ); }
+
+    void StartAction();         //Henkel Anzeigen und verstecken.
+    void EndAction();           //gerufen von ViewShell::ImplXXXAction
+    void LockPaint();           //dito, gerufen von ViewShell::ImplLockPaint
+    void UnlockPaint();
+
+    void PaintFlyChilds( SwFlyFrm *pFly, ExtOutputDevice& rOut,
+                         const SdrPaintInfoRec& rInfoRec );
+
+public:
+    SwViewImp( ViewShell * );
+    ~SwViewImp();
+    void Init( const SwViewOption * );          //nur fuer ViewShell::Init()
+
+    const ViewShell *GetShell() const { return pSh; }
+          ViewShell *GetShell()       { return pSh; }
+
+    Color GetRetoucheColor() const;
+
+    //Verwaltung zur ersten sichtbaren Seite
+    inline const SwPageFrm *GetFirstVisPage() const;
+    inline       SwPageFrm *GetFirstVisPage();
+    void SetFirstVisPageInvalid() { bFirstPageInvalid = TRUE; }
+
+    //SS'en fuer Paint- und Scrollrects.
+    BOOL AddPaintRect( const SwRect &rRect );
+    void AddScrollRect( const SwFrm *pFrm, const SwRect &rRect, long nOffs );
+    void MoveScrollArea();
+    SwRegionRects *GetRegion()      { return pRegion; }
+    void DelRegions();                      //Loescht Scroll- und PaintRects
+
+    //Handler fuer das Refresh von gescrollten Bereichen (Korrektur des
+    //Alignments). Ruft das Refresh mit der ScrolledArea.
+    //RefreshScrolledArea kann z.B. beim Setzen des Crsr genutzt werden, es
+    //wird nur der Anteil des Rect refreshed, der mit der ScrolledArea
+    //ueberlappt. Das 'reingereichte Rechteck wird veraendert!
+    void RestartScrollTimer()            { aScrollTimer.Start(); }
+    DECL_LINK( RefreshScrolledHdl, Timer * );
+    void _RefreshScrolledArea( const SwRect &rRect );
+    void RefreshScrolledArea( SwRect &rRect );
+
+    //Wird vom Layout ggf. waehrend einer Action gerufen, wenn der
+    //Verdacht besteht, dass es etwas drunter und drueber geht.
+    void ResetScroll()        { bScroll = FALSE; }
+
+    BOOL IsNextScroll() const { return bNextScroll; }
+    BOOL IsScroll()     const { return bScroll; }
+    BOOL IsScrolled()   const { return bScrolled; }
+
+    BOOL IsPaintInScroll() const { return bPaintInScroll; }
+
+    // neues Interface fuer StarView Drawing
+    inline const BOOL HasDrawView() const { return 0 != pDrawView; }
+          SwDrawView* GetDrawView()       { return pDrawView; }
+    const SwDrawView* GetDrawView() const { return pDrawView; }
+          SdrPageView*GetPageView()       { return pSdrPageView; }
+    const SdrPageView*GetPageView() const { return pSdrPageView; }
+    void MakeDrawView();
+
+    void   PaintLayer  ( const BYTE nLayerID, const SwRect &rRect ) const;
+
+    //wird als Link an die DrawEngine uebergeben, entscheidet was wie
+    //gepaintet wird oder nicht.
+    DECL_LINK( PaintDispatcher, SdrPaintProcRec * );
+
+    // Interface Drawing
+    BOOL IsDragPossible( const Point &rPoint );
+    void NotifySizeChg( const Size &rNewSz );
+
+    //SS Fuer die Lay- bzw. IdleAction und verwandtes
+    BOOL  IsAction() const                   { return pLayAct  != 0; }
+    BOOL  IsIdleAction() const               { return pIdleAct != 0; }
+          SwLayAction &GetLayAction()        { return *pLayAct; }
+    const SwLayAction &GetLayAction() const  { return *pLayAct; }
+          SwLayIdle   &GetIdleAction()       { return *pIdleAct;}
+    const SwLayIdle   &GetIdleAction() const { return *pIdleAct;}
+
+    //Wenn eine Aktion laueft wird diese gebeten zu pruefen ob es
+    //an der zeit ist den WaitCrsr einzuschalten.
+    void CheckWaitCrsr();
+    BOOL IsCalcLayoutProgress() const;  //Fragt die LayAction wenn vorhanden.
+    //TRUE wenn eine LayAction laeuft, dort wird dann auch das Flag fuer
+    //ExpressionFields gesetzt.
+    BOOL IsUpdateExpFlds();
+
+    void    SetRestoreActions(USHORT nSet){nRestoreActions = nSet;}
+    USHORT  GetRestoreActions() const{return nRestoreActions;}
+};
+
+//Kann auf dem Stack angelegt werden, wenn etwas ausgegeben oder
+//gescrolled wird. Handles und sontiges vom Drawing werden im CTor
+//gehidet und im DTor wieder sichtbar gemacht.
+//AW 06-Sep99: Hiding of handles is no longer necessary, removed
+class SwSaveHdl
+{
+    SwViewImp *pImp;
+    BOOL       bXorVis;
+public:
+    SwSaveHdl( SwViewImp *pImp );
+    ~SwSaveHdl();
+};
+
+
+inline SwPageFrm *SwViewImp::GetFirstVisPage()
+{
+    if ( bFirstPageInvalid )
+        SetFirstVisPage();
+    return pFirstVisPage;
+}
+
+inline const SwPageFrm *SwViewImp::GetFirstVisPage() const
+{
+    if ( bFirstPageInvalid )
+        ((SwViewImp*)this)->SetFirstVisPage();
+    return pFirstVisPage;
+}
+
+
+
+#endif //_VIEWIMP_HXX
+
diff --git a/sw/source/core/inc/visiturl.hxx b/sw/source/core/inc/visiturl.hxx
new file mode 100644
index 000000000000..ef00a49fb8d3
--- /dev/null
+++ b/sw/source/core/inc/visiturl.hxx
@@ -0,0 +1,85 @@
+/*************************************************************************
+ *
+ *  $RCSfile: visiturl.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:21 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _VISITURL_HXX
+#define _VISITURL_HXX
+
+
+
+
+#ifndef _SFXLSTNER_HXX //autogen
+#include 
+#endif
+class SwDoc;
+
+class SwURLStateChanged : public SfxListener
+{
+    const SwDoc* pDoc;
+public:
+    SwURLStateChanged( const SwDoc* pD );
+    virtual ~SwURLStateChanged();
+
+    virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+};
+
+
+
+#endif
+
diff --git a/sw/source/core/inc/wrong.hxx b/sw/source/core/inc/wrong.hxx
new file mode 100644
index 000000000000..76cdbe588804
--- /dev/null
+++ b/sw/source/core/inc/wrong.hxx
@@ -0,0 +1,121 @@
+/*************************************************************************
+ *
+ *  $RCSfile: wrong.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:21 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _WRONG_HXX
+#define _WRONG_HXX
+
+#ifndef _SVSTDARR_HXX
+#define _SVSTDARR_XUB_STRLEN
+#define _SVSTDARR_ULONGS
+#include 
+#endif
+
+#define WRPOS( nIdx ) ((xub_StrLen)( GetObject( nIdx ) ))
+#define WRLEN( nIdx ) ((xub_StrLen)( aLen.GetObject( nIdx ) ))
+
+class SwWrongList : public SvXub_StrLens
+{
+    SvXub_StrLens aLen;
+    xub_StrLen nBeginInvalid;   // Start des ungueltigen Bereichs
+    xub_StrLen nEndInvalid;     // Ende des ungueltigen Bereichs
+    void ShiftLeft( xub_StrLen &rPos, xub_StrLen nStart, xub_StrLen nEnd )
+    { if( rPos > nStart ) rPos = rPos > nEnd ? rPos - nEnd + nStart : nStart; }
+    void ShiftRight( xub_StrLen &rPos, xub_StrLen nStart, xub_StrLen nEnd )
+    { if( rPos >= nStart ) rPos += nStart - nEnd; }
+    void _Invalidate( xub_StrLen nBegin, xub_StrLen nEnd );
+public:
+    inline SwWrongList() :
+        SvXub_StrLens(5,5), aLen(5,5), nBeginInvalid( STRING_LEN ){}
+    inline xub_StrLen GetBeginInv() const { return nBeginInvalid; }
+    inline xub_StrLen GetEndInv() const { return nEndInvalid; }
+    inline BOOL InsideInvalid( xub_StrLen nChk ) const
+        { return nChk >= nBeginInvalid && nChk <= nEndInvalid; }
+    inline void SetInvalid( xub_StrLen nBegin, xub_StrLen nEnd )
+        { nBeginInvalid = nBegin; nEndInvalid = nEnd; }
+    inline void Validate(){ nBeginInvalid = STRING_LEN; }
+    inline void Invalidate( xub_StrLen nBegin, xub_StrLen nEnd )
+        { if( STRING_LEN == GetBeginInv() ) SetInvalid( nBegin, nEnd );
+          else _Invalidate( nBegin, nEnd ); }
+    BOOL InvalidateWrong();
+    BOOL Fresh( xub_StrLen &rStart, xub_StrLen &rEnd, xub_StrLen nPos,
+            xub_StrLen nLen, USHORT nIndex, xub_StrLen nCursorPos );
+    USHORT GetPos( xub_StrLen nValue ) const;
+    sal_Bool Check( xub_StrLen &rChk, xub_StrLen &rLn ) const;
+    sal_Bool InWrongWord( xub_StrLen &rChk, xub_StrLen &rLn ) const;
+    xub_StrLen NextWrong( xub_StrLen nChk ) const;
+    xub_StrLen LastWrong( xub_StrLen nChk ) const;
+    void Move( xub_StrLen nPos, long nDiff );
+    void Clear();
+    void Clear( xub_StrLen nBegin, xub_StrLen nEnd );
+
+    inline xub_StrLen Len( USHORT nIdx ) const { return WRLEN( nIdx );  }
+    inline xub_StrLen Pos( USHORT nIdx ) const { return WRPOS( nIdx );  }
+    inline void Insert( xub_StrLen nNewPos, xub_StrLen nNewLen, USHORT nWhere )
+    {SvXub_StrLens::Insert( nNewPos, nWhere ); aLen.Insert( nNewLen, nWhere );}
+
+// Wer braucht dies?
+    void Insert( ULONG nNew )
+    ;// { SvULongs::Insert( nNew, GetPos( (USHORT)( nNew & WRMASK ) ) ); }
+};
+
+
+#endif
+
diff --git a/sw/source/core/layout/atrfrm.cxx b/sw/source/core/layout/atrfrm.cxx
new file mode 100644
index 000000000000..104048687c4a
--- /dev/null
+++ b/sw/source/core/layout/atrfrm.cxx
@@ -0,0 +1,2519 @@
+/*************************************************************************
+ *
+ *  $RCSfile: atrfrm.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:21 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef __SBX_SBXVARIABLE_HXX //autogen
+#include 
+#endif
+#ifndef _IMAP_HXX //autogen
+#include 
+#endif
+#ifndef _GOODIES_IMAPOBJ_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_ULSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVDMODEL_HXX //autogen
+#include 
+#endif
+#ifndef _SVDPAGE_HXX //autogen
+#include 
+#endif
+#ifndef _UNOSETT_HXX
+#include 
+#endif
+
+#ifndef _UTL_TYPES_HXX_
+#include 
+#endif
+#ifndef _FMTCLDS_HXX //autogen
+#include 
+#endif
+#ifndef _FMTORNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTHDFT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTPDSC_HXX //autogen
+#include 
+#endif
+#ifndef _FMTCNTNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFSIZE_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFORDR_HXX //autogen
+#include 
+#endif
+#ifndef _FMTSRND_HXX //autogen
+#include 
+#endif
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _FMTTSPLT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFTNTX_HXX //autogen
+#include 
+#endif
+#ifndef _FMTEIRO_HXX //autogen
+#include 
+#endif
+#ifndef _FMTURL_HXX //autogen
+#include 
+#endif
+#ifndef _FMTCNCT_HXX //autogen
+#include 
+#endif
+#ifndef _NODE_HXX //autogen
+#include 
+#endif
+#ifndef _SECTION_HXX //autogen
+#include 
+#endif
+#ifndef _FMTLINE_HXX
+#include 
+#endif
+#ifndef _SWTYPES_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _PAGEFRM_HXX
+#include 
+#endif
+#ifndef _ROOTFRM_HXX
+#include 
+#endif
+#ifndef _CNTFRM_HXX
+#include 
+#endif
+#ifndef _CRSRSH_HXX
+#include 
+#endif
+#ifndef _ERRHDL_HXX
+#include 
+#endif
+#ifndef _CALBCK_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _DFLYOBJ_HXX
+#include 
+#endif
+#ifndef _DCONTACT_HXX
+#include 
+#endif
+#ifndef _FLYFRM_HXX
+#include 
+#endif
+#ifndef _FRMTOOL_HXX
+#include 
+#endif
+#ifndef _HINTS_HXX
+#include 
+#endif
+#ifndef _FLYFRMS_HXX
+#include 
+#endif
+#ifndef _PAGEDESC_HXX
+#include 
+#endif
+#ifndef _GRFATR_HXX
+#include 
+#endif
+#ifndef _NDNOTXT_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _NODE2LAY_HXX
+#include 
+#endif
+#ifndef _FMTCLBL_HXX
+#include 
+#endif
+
+#ifndef _CMDID_H
+#include 
+#endif
+#ifndef _UNOMID_H
+#include 
+#endif
+
+#ifndef _COM_SUN_STAR_TEXT_RELORIENTATION_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_VERTORIENTATION_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_HORIZONTALADJUST_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_DOCUMENTSTATISTIC_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_HORIORIENTATION_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_HORIORIENTATIONFORMAT_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_NOTEPRINTMODE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_SIZETYPE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_VERTORIENTATIONFORMAT_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_WRAPTEXTMODE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_TEXTCONTENTANCHORTYPE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_INVALIDTEXTCONTENTEXCEPTION_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XTEXTCONTENT_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_AWT_SIZE_HPP_
+#include 
+#endif
+
+using namespace ::com::sun::star;
+using namespace ::rtl;
+
+SV_IMPL_PTRARR(SwColumns,SwColumn*)
+
+TYPEINIT1(SwFrmFmt,     SwFmt );  //rtti fuer SwFrmFmt
+TYPEINIT1(SwFlyFrmFmt,  SwFrmFmt);
+TYPEINIT1(SwDrawFrmFmt, SwFrmFmt);
+TYPEINIT1(SwFmtVertOrient, SfxPoolItem);
+TYPEINIT1(SwFmtHoriOrient, SfxPoolItem);
+TYPEINIT2(SwFmtHeader,  SfxPoolItem, SwClient );
+TYPEINIT2(SwFmtFooter,  SfxPoolItem, SwClient );
+TYPEINIT2(SwFmtPageDesc,  SfxPoolItem, SwClient );
+
+/* -----------------19.05.98 09:26-------------------
+ *  Umwandlung fuer QueryValue
+ * --------------------------------------------------*/
+sal_Int16 lcl_RelToINT(SwRelationOrient eRelation)
+{
+    sal_Int16 nRet = text::RelOrientation::FRAME;
+    switch(eRelation)
+    {
+    case  PRTAREA:          nRet = text::RelOrientation::PRINT_AREA; break;
+    case  REL_CHAR:         nRet = text::RelOrientation::CHAR; break;
+    case  REL_PG_LEFT:      nRet = text::RelOrientation::PAGE_LEFT; break;
+    case  REL_PG_RIGHT:     nRet = text::RelOrientation::PAGE_RIGHT; break;
+    case  REL_FRM_LEFT:     nRet = text::RelOrientation::FRAME_LEFT; break;
+    case  REL_FRM_RIGHT:    nRet = text::RelOrientation::FRAME_RIGHT; break;
+    case  REL_PG_FRAME:     nRet = text::RelOrientation::PAGE_FRAME; break;
+    case  REL_PG_PRTAREA:   nRet = text::RelOrientation::PAGE_PRINT_AREA; break;
+    }
+    return nRet;
+}
+SwRelationOrient    lcl_IntToRelation(const uno::Any& rVal)
+{
+    SwRelationOrient eRet = FRAME;
+    switch(*(sal_Int16*)rVal.getValue())
+    {
+        case  text::RelOrientation::PRINT_AREA:     eRet =   PRTAREA           ; break;
+        case  text::RelOrientation::CHAR:       eRet =   REL_CHAR          ; break;
+        case  text::RelOrientation::PAGE_LEFT:    eRet =   REL_PG_LEFT       ; break;
+        case  text::RelOrientation::PAGE_RIGHT:    eRet =   REL_PG_RIGHT      ; break;
+        case  text::RelOrientation::FRAME_LEFT:    eRet =   REL_FRM_LEFT      ; break;
+        case  text::RelOrientation::FRAME_RIGHT:    eRet =   REL_FRM_RIGHT     ; break;
+        case  text::RelOrientation::PAGE_FRAME:    eRet =   REL_PG_FRAME      ; break;
+        case  text::RelOrientation::PAGE_PRINT_AREA:    eRet =   REL_PG_PRTAREA    ; break;
+    }
+    return eRet;
+}
+
+void DelHFFormat( SwClient *pToRemove, SwFrmFmt *pFmt )
+{
+    //Wenn der Client der letzte ist der das Format benutzt, so muss dieses
+    //vernichtet werden. Zuvor muss jedoch ggf. die Inhaltssection vernichtet
+    //werden.
+    SwDoc* pDoc = pFmt->GetDoc();
+    pFmt->Remove( pToRemove );
+    if( pDoc->IsInDtor() )
+    {
+        delete pFmt;
+        return;
+    }
+
+    //Nur noch Frms angemeldet?
+    sal_Bool bDel = sal_True;
+    {
+        // Klammer, weil im DTOR SwClientIter das Flag bTreeChg zurueck
+        // gesetzt wird. Unguenstig, wenn das Format vorher zerstoert wird.
+        SwClientIter aIter( *pFmt );
+        SwClient *pLast = aIter.GoStart();
+        if( pLast )
+            do {
+                bDel = pLast->IsA( TYPE(SwFrm) );
+            } while( bDel && 0 != ( pLast = aIter++ ));
+    }
+
+    if ( bDel )
+    {
+        //Wenn in einem der Nodes noch ein Crsr angemeldet ist, muss das
+        //ParkCrsr einer (beliebigen) Shell gerufen werden.
+        SwFmtCntnt& rCnt = (SwFmtCntnt&)pFmt->GetCntnt();
+        if ( rCnt.GetCntntIdx() )
+        {
+            SwNode *pNode = 0;
+            {
+                SwNodeIndex aIdx( *rCnt.GetCntntIdx(), 1 );
+                //Wenn in einem der Nodes noch ein Crsr angemeldet ist, muss das
+                //ParkCrsr einer (beliebigen) Shell gerufen werden.
+                pNode = pDoc->GetNodes()[ aIdx ];
+                sal_uInt32 nEnd = pNode->EndOfSectionIndex();
+                while ( aIdx < nEnd )
+                {
+                    if ( pNode->IsCntntNode() &&
+                         ((SwCntntNode*)pNode)->GetDepends() )
+                    {
+                        SwClientIter aIter( *(SwCntntNode*)pNode );
+                        do
+                        {
+                            if( aIter()->ISA( SwCrsrShell ) )
+                            {
+                                ((SwCrsrShell*)aIter())->ParkCrsr( aIdx );
+                                aIdx = nEnd-1;
+                                break;
+                            }
+                        } while ( aIter++ );
+                    }
+                    aIdx++;
+                    pNode = pDoc->GetNodes()[ aIdx ];
+                }
+            }
+            rCnt.SetNewCntntIdx( (const SwNodeIndex*)0 );
+
+            // beim Loeschen von Header/Footer-Formaten IMMER das Undo
+            // abschalten! (Bug 31069)
+            sal_Bool bDoesUndo = pDoc->DoesUndo();
+            pDoc->DoUndo( sal_False );
+
+            ASSERT( pNode, "Ein grosses Problem." );
+            pDoc->DeleteSection( pNode );
+
+            if( bDoesUndo )
+            {
+                pDoc->DelAllUndoObj();
+                pDoc->DoUndo( sal_True );
+            }
+        }
+        delete pFmt;
+    }
+}
+
+//  class SwFmtFrmSize
+//  Implementierung teilweise inline im hxx
+
+SwFmtFrmSize::SwFmtFrmSize( SwFrmSize eSize, SwTwips nWidth, SwTwips nHeight )
+    : SfxPoolItem( RES_FRM_SIZE ),
+    aSize( nWidth, nHeight ),
+    eFrmSize( eSize )
+{
+    nWidthPercent = nHeightPercent = 0;
+}
+
+SwFmtFrmSize& SwFmtFrmSize::operator=( const SwFmtFrmSize& rCpy )
+{
+    aSize = rCpy.GetSize();
+    eFrmSize = rCpy.GetSizeType();
+    nHeightPercent = rCpy.GetHeightPercent();
+    nWidthPercent  = rCpy.GetWidthPercent();
+    return *this;
+}
+
+int  SwFmtFrmSize::operator==( const SfxPoolItem& rAttr ) const
+{
+    ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" );
+    return( eFrmSize        == ((SwFmtFrmSize&)rAttr).eFrmSize &&
+            aSize           == ((SwFmtFrmSize&)rAttr).GetSize()&&
+            nWidthPercent   == ((SwFmtFrmSize&)rAttr).GetWidthPercent() &&
+            nHeightPercent  == ((SwFmtFrmSize&)rAttr).GetHeightPercent() );
+}
+
+SfxPoolItem*  SwFmtFrmSize::Clone( SfxItemPool* ) const
+{
+    return new SwFmtFrmSize( *this );
+}
+
+
+/* -----------------24.04.98 11:36-------------------
+ *
+ * --------------------------------------------------*/
+BOOL SwFmtFrmSize::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+    // hier wird immer konvertiert!
+    nMemberId &= ~CONVERT_TWIPS;
+    switch ( nMemberId )
+    {
+        case MID_FRMSIZE_SIZE:
+        {
+            awt::Size aTmp;
+            aTmp.Height = TWIP_TO_MM100(aSize.Height());
+            aTmp.Width = TWIP_TO_MM100(aSize.Width());
+            rVal.setValue(&aTmp, ::getCppuType((const awt::Size*)0));
+        }
+        break;
+        case MID_FRMSIZE_REL_HEIGHT:
+            rVal <<= (sal_Int8)GetHeightPercent();
+        break;
+        case MID_FRMSIZE_REL_WIDTH:
+            rVal <<= (sal_Int8)GetWidthPercent();
+        break;
+        case MID_FRMSIZE_IS_SYNC_REL_SIZE:
+        {
+            BOOL bTmp = 0xFF == GetHeightPercent();
+            rVal.setValue(&bTmp, ::getBooleanCppuType());
+        }
+        break;
+        case MID_FRMSIZE_WIDTH :
+            rVal <<= (sal_Int32)TWIP_TO_MM100(aSize.Width());
+        break;
+        case MID_FRMSIZE_HEIGHT:
+            rVal <<= (sal_Int32)TWIP_TO_MM100(aSize.Height());
+        break;
+        case MID_FRMSIZE_SIZE_TYPE:
+            rVal <<= (sal_Int16)GetSizeType();
+        break;
+        case MID_FRMSIZE_IS_AUTO_HEIGHT:
+        {
+            BOOL bTmp = ATT_FIX_SIZE != GetSizeType();
+            rVal.setValue(&bTmp, ::getBooleanCppuType());
+        }
+        break;
+    }
+    return sal_True;
+}
+
+/* -----------------24.04.98 11:36-------------------
+ *
+ * --------------------------------------------------*/
+BOOL SwFmtFrmSize::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+    sal_Bool bConvert = 0 != (nMemberId&CONVERT_TWIPS);
+    nMemberId &= ~CONVERT_TWIPS;
+    sal_Bool bRet = sal_True;
+    switch ( nMemberId )
+    {
+        case MID_FRMSIZE_SIZE:
+        {
+            awt::Size aVal(*(awt::Size*)rVal.getValue());
+            Size aTmp(aVal.Width, aVal.Height);
+            if(bConvert)
+            {
+                aTmp.Height() = MM100_TO_TWIP(aTmp.Height());
+                aTmp.Width() = MM100_TO_TWIP(aTmp.Width());
+            }
+            if(aTmp.Height() && aTmp.Width())
+                aSize = aTmp;
+            else
+                bRet = sal_False;
+        }
+        break;
+        case MID_FRMSIZE_REL_HEIGHT:
+        {
+            sal_Int32 nSet;
+            rVal >>= nSet;
+            if(nSet > 0 && nSet <= 100)
+                SetHeightPercent(nSet);
+            else
+                bRet = sal_False;
+        }
+        break;
+        case MID_FRMSIZE_REL_WIDTH:
+        {
+            sal_Int32 nSet;
+            rVal >>= nSet;
+            if(nSet > 0 && nSet <= 100)
+                SetWidthPercent(nSet);
+            else
+                bRet = sal_False;
+        }
+        break;
+        case MID_FRMSIZE_IS_SYNC_REL_SIZE:
+        {
+            sal_Bool bSet = *(sal_Bool*)rVal.getValue();
+            if(bSet)
+                SetHeightPercent(0xff);
+            else
+                    // 0xff kann so nicht abgeschaltet werden
+                    bRet = sal_False;
+        }
+        break;
+        case MID_FRMSIZE_WIDTH :
+        {
+            sal_Int32 nWd = *(sal_Int32*)rVal.getValue();
+            if(bConvert)
+                nWd = MM100_TO_TWIP(nWd);
+            if(nWd > 0)
+                aSize.Width() = nWd;
+            else
+                bRet = sal_False;
+        }
+        break;
+        case MID_FRMSIZE_HEIGHT:
+        {
+            sal_Int32 nHg = *(sal_Int32*)rVal.getValue();
+            if(bConvert)
+                nHg = MM100_TO_TWIP(nHg);
+            if(nHg > 0)
+                aSize.Height() = nHg;
+            else
+                bRet = sal_False;
+        }
+        break;
+        case MID_FRMSIZE_SIZE_TYPE:
+        {
+            sal_Int16 nType = *(sal_Int16*)rVal.getValue();
+            if(nType <= ATT_MIN_SIZE )
+            {
+                SetSizeType((SwFrmSize)nType);
+            }
+        }
+        break;
+        case MID_FRMSIZE_IS_AUTO_HEIGHT:
+        {
+            sal_Bool bSet = *(sal_Bool*)rVal.getValue();
+            SetSizeType(bSet ? ATT_VAR_SIZE : ATT_FIX_SIZE);
+        }
+        break;
+        default:
+            bRet = sal_False;
+    }
+    return bRet;
+}
+
+Size  SwFmtFrmSize::GetSizeConvertedToSw31(
+                const SvxLRSpaceItem *pLRSpace,
+                const SvxULSpaceItem *pULSpace ) const
+{
+    // Sw4.0: Groesse enthaelt keine Raender
+    // Sw3.x: Groesse enthaelt Raender
+    // ==> Raender addieren
+    Size aNewSize = GetSize();
+    if( pLRSpace )
+    {
+        aNewSize.Width() += pLRSpace->GetLeft();
+        aNewSize.Width() += pLRSpace->GetRight();
+    }
+    if( pULSpace )
+    {
+        aNewSize.Height() += pULSpace->GetUpper();
+        aNewSize.Height() +=  pULSpace->GetLower();
+    }
+    return aNewSize;
+}
+
+Size  SwFmtFrmSize::GetSizeConvertedFromSw31(
+                const SvxLRSpaceItem *pLRSpace,
+                const SvxULSpaceItem *pULSpace ) const
+{
+    // Sw4.0: Groesse enthaelt keine Raender
+    // Sw3.x: Groesse enthaelt Raender
+    // ==> Raender subtrahieren
+    Size aNewSize = GetSize();
+    if( pLRSpace )
+    {
+        aNewSize.Width() -= pLRSpace->GetLeft();
+        aNewSize.Width() -= pLRSpace->GetRight();
+    }
+    if( pULSpace )
+    {
+        aNewSize.Height() -= pULSpace->GetUpper();
+        aNewSize.Height() -=  pULSpace->GetLower();
+    }
+    return aNewSize;
+}
+
+
+//  class SwFmtFillOrder
+//  Implementierung teilweise inline im hxx
+
+SwFmtFillOrder::SwFmtFillOrder( SwFillOrder nFO )
+    : SfxEnumItem( RES_FILL_ORDER, sal_uInt16(nFO) )
+{}
+
+SfxPoolItem*  SwFmtFillOrder::Clone( SfxItemPool* ) const
+{
+    return new SwFmtFillOrder( GetFillOrder() );
+}
+
+sal_uInt16  SwFmtFillOrder::GetValueCount() const
+{
+    return SW_FILL_ORDER_END - SW_FILL_ORDER_BEGIN;
+}
+
+//  class SwFmtHeader
+//  Implementierung teilweise inline im hxx
+
+SwFmtHeader::SwFmtHeader( SwFrmFmt *pHeaderFmt )
+    : SfxPoolItem( RES_HEADER ),
+    SwClient( pHeaderFmt ),
+    bActive( pHeaderFmt ? sal_True : sal_False )
+{
+}
+
+SwFmtHeader::SwFmtHeader( const SwFmtHeader &rCpy )
+    : SfxPoolItem( RES_HEADER ),
+    SwClient( (SwModify*)rCpy.GetRegisteredIn() ),
+    bActive( rCpy.IsActive() )
+{
+}
+
+SwFmtHeader::SwFmtHeader( sal_Bool bOn )
+    : SfxPoolItem( RES_HEADER ),
+    SwClient( 0 ),
+    bActive( bOn )
+{
+}
+
+ SwFmtHeader::~SwFmtHeader()
+{
+    if ( GetHeaderFmt() )
+        DelHFFormat( this, GetHeaderFmt() );
+}
+
+int  SwFmtHeader::operator==( const SfxPoolItem& rAttr ) const
+{
+    ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" );
+    return ( pRegisteredIn == ((SwFmtHeader&)rAttr).GetRegisteredIn() &&
+             bActive == ((SwFmtHeader&)rAttr).IsActive() );
+}
+
+SfxPoolItem*  SwFmtHeader::Clone( SfxItemPool* ) const
+{
+    return new SwFmtHeader( *this );
+}
+
+//  class SwFmtFooter
+//  Implementierung teilweise inline im hxx
+
+SwFmtFooter::SwFmtFooter( SwFrmFmt *pFooterFmt )
+    : SfxPoolItem( RES_FOOTER ),
+    SwClient( pFooterFmt ),
+    bActive( pFooterFmt ? sal_True : sal_False )
+{
+}
+
+SwFmtFooter::SwFmtFooter( const SwFmtFooter &rCpy )
+    : SfxPoolItem( RES_FOOTER ),
+    SwClient( (SwModify*)rCpy.GetRegisteredIn() ),
+    bActive( rCpy.IsActive() )
+{
+}
+
+SwFmtFooter::SwFmtFooter( sal_Bool bOn )
+    : SfxPoolItem( RES_FOOTER ),
+    SwClient( 0 ),
+    bActive( bOn )
+{
+}
+
+ SwFmtFooter::~SwFmtFooter()
+{
+    if ( GetFooterFmt() )
+        DelHFFormat( this, GetFooterFmt() );
+}
+
+int  SwFmtFooter::operator==( const SfxPoolItem& rAttr ) const
+{
+    ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" );
+    return ( pRegisteredIn == ((SwFmtFooter&)rAttr).GetRegisteredIn() &&
+             bActive == ((SwFmtFooter&)rAttr).IsActive() );
+}
+
+SfxPoolItem*  SwFmtFooter::Clone( SfxItemPool* ) const
+{
+    return new SwFmtFooter( *this );
+}
+
+//  class SwFmtCntnt
+//  Implementierung teilweise inline im hxx
+
+SwFmtCntnt::SwFmtCntnt( const SwFmtCntnt &rCpy )
+    : SfxPoolItem( RES_CNTNT )
+{
+    pStartNode = rCpy.GetCntntIdx() ?
+                    new SwNodeIndex( *rCpy.GetCntntIdx() ) : 0;
+}
+
+SwFmtCntnt::SwFmtCntnt( const SwStartNode *pStartNd )
+    : SfxPoolItem( RES_CNTNT )
+{
+    pStartNode = pStartNd ? new SwNodeIndex( *pStartNd ) : 0;
+}
+
+ SwFmtCntnt::~SwFmtCntnt()
+{
+    delete pStartNode;
+}
+
+void SwFmtCntnt::SetNewCntntIdx( const SwNodeIndex *pIdx )
+{
+    delete pStartNode;
+    pStartNode = pIdx ? new SwNodeIndex( *pIdx ) : 0;
+}
+
+int  SwFmtCntnt::operator==( const SfxPoolItem& rAttr ) const
+{
+    ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" );
+    if( (long)pStartNode ^ (long)((SwFmtCntnt&)rAttr).pStartNode )
+        return 0;
+    if( pStartNode )
+        return ( *pStartNode == *((SwFmtCntnt&)rAttr).GetCntntIdx() );
+    return 1;
+}
+
+SfxPoolItem*  SwFmtCntnt::Clone( SfxItemPool* ) const
+{
+    return new SwFmtCntnt( *this );
+}
+
+//  class SwFmtPageDesc
+//  Implementierung teilweise inline im hxx
+
+SwFmtPageDesc::SwFmtPageDesc( const SwFmtPageDesc &rCpy )
+    : SfxPoolItem( RES_PAGEDESC ),
+    SwClient( (SwPageDesc*)rCpy.GetPageDesc() ),
+    pDefinedIn( 0 ),
+    nNumOffset( rCpy.nNumOffset ),
+    nDescNameIdx( rCpy.nDescNameIdx )
+{
+}
+
+SwFmtPageDesc::SwFmtPageDesc( const SwPageDesc *pDesc )
+    : SfxPoolItem( RES_PAGEDESC ),
+    SwClient( (SwPageDesc*)pDesc ),
+    pDefinedIn( 0 ),
+    nNumOffset( 0 ),
+    nDescNameIdx( 0xFFFF )  // IDX_NO_VALUE
+{
+}
+
+ SwFmtPageDesc::~SwFmtPageDesc() {}
+
+int  SwFmtPageDesc::operator==( const SfxPoolItem& rAttr ) const
+{
+    ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" );
+    return  ( pDefinedIn == ((SwFmtPageDesc&)rAttr).pDefinedIn ) &&
+            ( nNumOffset == ((SwFmtPageDesc&)rAttr).nNumOffset ) &&
+            ( GetPageDesc() == ((SwFmtPageDesc&)rAttr).GetPageDesc() );
+}
+
+SfxPoolItem*  SwFmtPageDesc::Clone( SfxItemPool* ) const
+{
+    return new SwFmtPageDesc( *this );
+}
+
+void SwFmtPageDesc::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew )
+{
+    if( !pDefinedIn )
+        return;
+
+    sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
+    switch( nWhich )
+    {
+        case RES_OBJECTDYING:
+                //Der Pagedesc, bei dem ich angemeldet bin stirbt, ich trage
+                //mich also bei meinem Format aus.
+                //Dabei werden ich Deletet!!!
+            if( IS_TYPE( SwFmt, pDefinedIn ))
+#ifndef PRODUCT
+            {
+                sal_Bool bDel = ((SwFmt*)pDefinedIn)->ResetAttr( RES_PAGEDESC );
+                ASSERT( bDel, ";-) FmtPageDesc nicht zerstoert." );
+            }
+#else
+                ((SwFmt*)pDefinedIn)->ResetAttr( RES_PAGEDESC );
+#endif
+            else if( IS_TYPE( SwCntntNode, pDefinedIn ))
+#ifndef PRODUCT
+            {
+                sal_Bool bDel = ((SwCntntNode*)pDefinedIn)->ResetAttr( RES_PAGEDESC );
+                ASSERT( bDel, ";-) FmtPageDesc nicht zerstoert." );
+            }
+#else
+                ((SwCntntNode*)pDefinedIn)->ResetAttr( RES_PAGEDESC );
+#endif
+            break;
+
+        default:
+            /* do nothing */;
+    }
+}
+
+BOOL SwFmtPageDesc::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+    // hier wird immer konvertiert!
+    nMemberId &= ~CONVERT_TWIPS;
+    sal_Bool    bRet = sal_True;
+    switch ( nMemberId )
+    {
+        case MID_PAGEDESC_PAGENUMOFFSET:
+            rVal <<= (sal_Int16)GetNumOffset();
+            break;
+
+        case MID_PAGEDESC_PAGEDESCNAME:
+            /* geht nicht, weil das Attribut eigentlich nicht den Namen
+             * sondern einen Pointer auf den PageDesc braucht (ist Client davon).
+             * Der Pointer waere aber ueber den Namen nur vom Dokument zu erfragen.
+             */
+        default:
+            ASSERT( !this, "unknown MemberId" );
+            bRet = sal_False;
+    }
+    return bRet;
+}
+
+BOOL SwFmtPageDesc::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+    // hier wird immer konvertiert!
+    nMemberId &= ~CONVERT_TWIPS;
+    sal_Bool bRet = sal_True;
+    switch ( nMemberId )
+    {
+        case MID_PAGEDESC_PAGENUMOFFSET:
+            SetNumOffset( *(sal_uInt16*)rVal.getValue());
+            break;
+
+        case MID_PAGEDESC_PAGEDESCNAME:
+            /* geht nicht, weil das Attribut eigentlich nicht den Namen
+             * sondern einen Pointer auf den PageDesc braucht (ist Client davon).
+             * Der Pointer waere aber ueber den Namen nur vom Dokument zu erfragen.
+             */
+        default:
+            ASSERT( !this, "unknown MemberId" );
+            bRet = sal_False;
+    }
+    return bRet;
+}
+
+
+//  class SwFmtCol
+//  Implementierung teilweise inline im hxx
+
+SwColumn::SwColumn() :
+    nUpper( 0 ),
+    nLower( 0 ),
+    nLeft ( 0 ),
+    nRight( 0 ),
+    nWish ( 0 )
+{
+}
+
+sal_Bool SwColumn::operator==( const SwColumn &rCmp )
+{
+    return (nWish    == rCmp.GetWishWidth() &&
+            GetLeft()  == rCmp.GetLeft() &&
+            GetRight() == rCmp.GetRight() &&
+            GetUpper() == rCmp.GetUpper() &&
+            GetLower() == rCmp.GetLower()) ? sal_True : sal_False;
+}
+
+SwFmtCol::SwFmtCol( const SwFmtCol& rCpy )
+    : SfxPoolItem( RES_COL ),
+    nLineWidth( rCpy.nLineWidth),
+    aLineColor( rCpy.aLineColor),
+    nLineHeight( rCpy.GetLineHeight() ),
+    eAdj( rCpy.GetLineAdj() ),
+    nWidth( rCpy.GetWishWidth() ),
+    bOrtho( rCpy.IsOrtho() ),
+    aColumns( (sal_Int8)rCpy.GetNumCols(), 1 )
+{
+    for ( sal_uInt16 i = 0; i < rCpy.GetNumCols(); ++i )
+    {
+        SwColumn *pCol = new SwColumn( *rCpy.GetColumns()[i] );
+        aColumns.Insert( pCol, aColumns.Count() );
+    }
+}
+
+SwFmtCol::~SwFmtCol() {}
+
+SwFmtCol& SwFmtCol::operator=( const SwFmtCol& rCpy )
+{
+    nLineWidth  = rCpy.nLineWidth;
+    aLineColor  = rCpy.aLineColor;
+    nLineHeight = rCpy.GetLineHeight();
+    eAdj        = rCpy.GetLineAdj();
+    nWidth      = rCpy.GetWishWidth();
+    bOrtho      = rCpy.IsOrtho();
+
+    if ( aColumns.Count() )
+        aColumns.DeleteAndDestroy( 0, aColumns.Count() );
+    for ( sal_uInt16 i = 0; i < rCpy.GetNumCols(); ++i )
+    {
+        SwColumn *pCol = new SwColumn( *rCpy.GetColumns()[i] );
+        aColumns.Insert( pCol, aColumns.Count() );
+    }
+    return *this;
+}
+
+SwFmtCol::SwFmtCol()
+    : SfxPoolItem( RES_COL ),
+    nLineHeight( 100 ),
+    eAdj( COLADJ_NONE ),
+    nWidth( USHRT_MAX ),
+    bOrtho( sal_True ),
+    nLineWidth(0)
+{
+}
+
+int SwFmtCol::operator==( const SfxPoolItem& rAttr ) const
+{
+    ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" );
+    const SwFmtCol &rCmp = (const SwFmtCol&)rAttr;
+    if( !(nLineWidth        == rCmp.nLineWidth  &&
+          aLineColor        == rCmp.aLineColor  &&
+          nLineHeight        == rCmp.GetLineHeight() &&
+          eAdj               == rCmp.GetLineAdj() &&
+          nWidth             == rCmp.GetWishWidth() &&
+          bOrtho             == rCmp.IsOrtho() &&
+          aColumns.Count() == rCmp.GetNumCols()) )
+        return 0;
+
+    for ( sal_uInt16 i = 0; i < aColumns.Count(); ++i )
+        if ( !(*aColumns[i] == *rCmp.GetColumns()[i]) )
+            return 0;
+
+    return 1;
+}
+
+SfxPoolItem*  SwFmtCol::Clone( SfxItemPool* ) const
+{
+    return new SwFmtCol( *this );
+}
+
+sal_uInt16 SwFmtCol::GetGutterWidth( sal_Bool bMin ) const
+{
+    sal_uInt16 nRet = 0;
+    if ( aColumns.Count() == 2 )
+        nRet = aColumns[0]->GetRight() + aColumns[1]->GetLeft();
+    else if ( aColumns.Count() > 2 )
+    {
+        sal_Bool bSet = sal_False;
+        for ( sal_uInt16 i = 1; i < aColumns.Count()-1; ++i )
+        {
+            const sal_uInt16 nTmp = aColumns[i]->GetRight() + aColumns[i+1]->GetLeft();
+            if ( bSet )
+            {
+                if ( nTmp != nRet )
+                {
+                    if ( !bMin )
+                        return USHRT_MAX;
+                    if ( nRet > nTmp )
+                        nRet = nTmp;
+                }
+            }
+            else
+            {   bSet = sal_True;
+                nRet = nTmp;
+            }
+        }
+    }
+    return nRet;
+}
+
+void SwFmtCol::SetGutterWidth( sal_uInt16 nNew, sal_uInt16 nAct )
+{
+    if ( bOrtho )
+        Calc( nNew, nAct );
+    else
+    {
+        sal_uInt16 nHalf = nNew / 2;
+        for ( sal_uInt16 i = 0; i < aColumns.Count(); ++i )
+        {   SwColumn *pCol = aColumns[i];
+            pCol->SetLeft ( nHalf );
+            pCol->SetRight( nHalf );
+            if ( i == 0 )
+                pCol->SetLeft( 0 );
+            else if ( i == (aColumns.Count() - 1) )
+                pCol->SetRight( 0 );
+        }
+    }
+}
+
+void SwFmtCol::Init( sal_uInt16 nNumCols, sal_uInt16 nGutterWidth, sal_uInt16 nAct )
+{
+    //Loeschen scheint hier auf den erste Blick vielleicht etwas zu heftig;
+    //anderfalls muessten allerdings alle Werte der verbleibenden SwColumn's
+    //initialisiert werden.
+    if ( aColumns.Count() )
+        aColumns.DeleteAndDestroy( 0, aColumns.Count() );
+    for ( sal_uInt16 i = 0; i < nNumCols; ++i )
+    {   SwColumn *pCol = new SwColumn;
+        aColumns.Insert( pCol, i );
+    }
+    bOrtho = sal_True;
+    nWidth = USHRT_MAX;
+    if( nNumCols )
+        Calc( nGutterWidth, nAct );
+}
+
+void SwFmtCol::SetOrtho( sal_Bool bNew, sal_uInt16 nGutterWidth, sal_uInt16 nAct )
+{
+    bOrtho = bNew;
+    if ( bNew && aColumns.Count() )
+        Calc( nGutterWidth, nAct );
+}
+
+sal_uInt16 SwFmtCol::CalcColWidth( sal_uInt16 nCol, sal_uInt16 nAct ) const
+{
+    ASSERT( nCol < aColumns.Count(), ":-( ColumnsArr ueberindiziert." );
+    if ( nWidth != nAct )
+    {
+        long nW = aColumns[nCol]->GetWishWidth();
+        nW *= nAct;
+        nW /= nWidth;
+        return sal_uInt16(nW);
+    }
+    else
+        return aColumns[nCol]->GetWishWidth();
+}
+
+sal_uInt16 SwFmtCol::CalcPrtColWidth( sal_uInt16 nCol, sal_uInt16 nAct ) const
+{
+    ASSERT( nCol < aColumns.Count(), ":-( ColumnsArr ueberindiziert." );
+    sal_uInt16 nRet = CalcColWidth( nCol, nAct );
+    SwColumn *pCol = aColumns[nCol];
+    nRet -= pCol->GetLeft();
+    nRet -= pCol->GetRight();
+    return nRet;
+}
+
+void SwFmtCol::Calc( sal_uInt16 nGutterWidth, sal_uInt16 nAct )
+{
+    //Erstmal die Spalten mit der Aktuellen Breite einstellen, dann die
+    //Wunschbreite der Spalten anhand der Gesamtwunschbreite hochrechnen.
+
+    const sal_uInt16 nGutterHalf = nGutterWidth ? nGutterWidth / 2 : 0;
+
+    //Breite der PrtAreas ist Gesamtbreite - Zwischenraeume / Anzahl
+    const sal_uInt16 nPrtWidth =
+                (nAct - ((GetNumCols()-1) * nGutterWidth)) / GetNumCols();
+    sal_uInt16 nAvail = nAct;
+
+    //Die erste Spalte ist PrtBreite + (Zwischenraumbreite/2)
+    const sal_uInt16 nLeftWidth = nPrtWidth + nGutterHalf;
+    SwColumn *pCol = aColumns[0];
+    pCol->SetWishWidth( nLeftWidth );
+    pCol->SetRight( nGutterHalf );
+    pCol->SetLeft ( 0 );
+    nAvail -= nLeftWidth;
+
+    //Spalte 2 bis n-1 ist PrtBreite + Zwischenraumbreite
+    const sal_uInt16 nMidWidth = nPrtWidth + nGutterWidth;
+    for ( sal_uInt16 i = 1; i < GetNumCols()-1; ++i )
+    {
+        pCol = aColumns[i];
+        pCol->SetWishWidth( nMidWidth );
+        pCol->SetLeft ( nGutterHalf );
+        pCol->SetRight( nGutterHalf );
+        nAvail -= nMidWidth;
+    }
+
+    //Die Letzte Spalte entspricht wieder der ersten, um Rundungsfehler
+    //auszugleichen wird der letzten Spalte alles zugeschlagen was die
+    //anderen nicht verbraucht haben.
+    pCol = aColumns[aColumns.Count()-1];
+    pCol->SetWishWidth( nAvail );
+    pCol->SetLeft ( nGutterHalf );
+    pCol->SetRight( 0 );
+
+    //Umrechnen der aktuellen Breiten in Wunschbreiten.
+    for ( i = 0; i < aColumns.Count(); ++i )
+    {
+        pCol = aColumns[i];
+        long nTmp = pCol->GetWishWidth();
+        nTmp *= GetWishWidth();
+        nTmp /= nAct;
+        pCol->SetWishWidth( sal_uInt16(nTmp) );
+    }
+}
+
+BOOL SwFmtCol::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+    // hier wird immer konvertiert!
+    nMemberId &= ~CONVERT_TWIPS;
+    if(MID_COLUMN_SEPARATOR_LINE == nMemberId)
+    {
+        DBG_ERROR("not implemented")
+    }
+    else
+    {
+        uno::Reference< text::XTextColumns >  xCols = new SwXTextColumns(*this);
+        rVal.setValue(&xCols, ::getCppuType((uno::Reference< text::XTextColumns>*)0));
+    }
+    return sal_True;
+}
+
+BOOL SwFmtCol::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+    // hier wird immer konvertiert!
+    nMemberId &= ~CONVERT_TWIPS;
+    sal_Bool bRet = sal_False;
+    if(MID_COLUMN_SEPARATOR_LINE == nMemberId)
+    {
+        DBG_ERROR("not implemented")
+    }
+    else
+    {
+        uno::Reference< text::XTextColumns > * pxCols = (uno::Reference< text::XTextColumns > *)rVal.getValue();
+        if(pxCols)
+        {
+            uno::Sequence aSetColumns = (*pxCols)->getColumns();
+            const text::TextColumn* pArray = aSetColumns.getConstArray();
+            aColumns.DeleteAndDestroy(0, aColumns.Count());
+            //max. Count ist hier 64K - das kann das Array aber nicht
+            sal_uInt16 nCount = min((sal_uInt16)aSetColumns.getLength(), 0x3fff);
+            sal_uInt16 nWidthSum = 0;
+            for(sal_uInt16 i = 0; i < nCount; i++)
+            {
+                SwColumn* pCol = new SwColumn;
+                pCol->SetWishWidth( pArray[i].Width );
+                nWidthSum += pArray[i].Width;
+                pCol->SetLeft ( MM100_TO_TWIP(pArray[i].LeftMargin) );
+                pCol->SetRight( MM100_TO_TWIP(pArray[i].RightMargin) );
+                aColumns.Insert(pCol, i);
+            }
+            bRet = sal_True;
+            nWidth = nWidthSum;
+            bOrtho = sal_False;
+        }
+    }
+    return bRet;
+}
+
+
+//  class SwFmtSurround
+//  Implementierung teilweise inline im hxx
+
+SwFmtSurround::SwFmtSurround( SwSurround eFly ) :
+    SfxEnumItem( RES_SURROUND, sal_uInt16( eFly ) )
+{
+    bAnchorOnly = bContour = bOutside = sal_False;
+}
+
+SwFmtSurround::SwFmtSurround( const SwFmtSurround &rCpy ) :
+    SfxEnumItem( RES_SURROUND, rCpy.GetValue() )
+{
+    bAnchorOnly = rCpy.bAnchorOnly;
+    bContour = rCpy.bContour;
+    bOutside = rCpy.bOutside;
+}
+
+int  SwFmtSurround::operator==( const SfxPoolItem& rAttr ) const
+{
+    ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" );
+    return ( GetValue() == ((SwFmtSurround&)rAttr).GetValue() &&
+             bAnchorOnly== ((SwFmtSurround&)rAttr).bAnchorOnly &&
+             bContour== ((SwFmtSurround&)rAttr).bContour &&
+             bOutside== ((SwFmtSurround&)rAttr).bOutside );
+}
+
+SfxPoolItem*  SwFmtSurround::Clone( SfxItemPool* ) const
+{
+    return new SwFmtSurround( *this );
+}
+
+sal_uInt16  SwFmtSurround::GetValueCount() const
+{
+    return SURROUND_END - SURROUND_BEGIN;
+}
+
+
+BOOL SwFmtSurround::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+    // hier wird immer konvertiert!
+    nMemberId &= ~CONVERT_TWIPS;
+    sal_Bool bRet = sal_True;
+    switch ( nMemberId )
+    {
+        case MID_SURROUND_SURROUNDTYPE:
+                rVal <<= (text::WrapTextMode)GetSurround();
+        break;
+        case MID_SURROUND_ANCHORONLY:
+        {
+            BOOL bTmp = IsAnchorOnly();
+            rVal.setValue(&bTmp, ::getBooleanCppuType());
+        }
+                break;
+        case MID_SURROUND_CONTOUR:
+        {
+            BOOL bTmp = IsContour();
+            rVal.setValue(&bTmp, ::getBooleanCppuType());
+        }
+                break;
+        case MID_SURROUND_CONTOUROUTSIDE:
+        {
+            BOOL bTmp = IsOutside();
+            rVal.setValue(&bTmp, ::getBooleanCppuType());
+        }
+                break;
+        default:
+            ASSERT( !this, "unknown MemberId" );
+            bRet = sal_False;
+    }
+    return bRet;
+}
+
+BOOL SwFmtSurround::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+    // hier wird immer konvertiert!
+    nMemberId &= ~CONVERT_TWIPS;
+    sal_Bool bRet = sal_True;
+    switch ( nMemberId )
+    {
+        case MID_SURROUND_SURROUNDTYPE:
+        {
+            sal_Int32 eVal;
+            try
+            {
+                eVal = utl::getEnumAsINT32(rVal);
+            }
+            catch(...) {}
+
+            if( eVal >= 0 && eVal < (sal_Int16)SURROUND_END )
+                SetValue( eVal );
+            else
+                //exception
+                ;
+        }
+        break;
+
+        case MID_SURROUND_ANCHORONLY:
+            SetAnchorOnly( *(sal_Bool*)rVal.getValue() );
+            break;
+        case MID_SURROUND_CONTOUR:
+            SetContour( *(sal_Bool*)rVal.getValue() );
+            break;
+        case MID_SURROUND_CONTOUROUTSIDE:
+            SetOutside( *(sal_Bool*)rVal.getValue() );
+            break;
+        default:
+            ASSERT( !this, "unknown MemberId" );
+            bRet = sal_False;
+    }
+    return bRet;
+}
+
+//  class SwFmtVertOrient
+//  Implementierung teilweise inline im hxx
+
+SwFmtVertOrient::SwFmtVertOrient( SwTwips nY, SwVertOrient eVert,
+                                  SwRelationOrient eRel )
+    : SfxPoolItem( RES_VERT_ORIENT ),
+    nYPos( nY ),
+    eOrient( eVert ),
+    eRelation( eRel )
+{}
+
+int  SwFmtVertOrient::operator==( const SfxPoolItem& rAttr ) const
+{
+    ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" );
+    return ( nYPos     == ((SwFmtVertOrient&)rAttr).nYPos &&
+             eOrient   == ((SwFmtVertOrient&)rAttr).eOrient &&
+             eRelation == ((SwFmtVertOrient&)rAttr).eRelation );
+}
+
+SfxPoolItem*  SwFmtVertOrient::Clone( SfxItemPool* ) const
+{
+    return new SwFmtVertOrient( nYPos, eOrient, eRelation );
+}
+
+
+SwTwips  SwFmtVertOrient::GetPosConvertedToSw31(
+    const SvxULSpaceItem *pULSpace ) const
+{
+    SwTwips nNewPos = GetPos();
+
+    if( VERT_NONE==GetVertOrient() && pULSpace )
+    {
+        nNewPos -= pULSpace->GetUpper();
+    }
+
+    return nNewPos;
+}
+
+SwTwips  SwFmtVertOrient::GetPosConvertedFromSw31(
+    const SvxULSpaceItem *pULSpace ) const
+{
+    SwTwips nNewPos = GetPos();
+
+    if( VERT_NONE==GetVertOrient() && pULSpace )
+    {
+        nNewPos += pULSpace->GetUpper();
+    }
+
+    return nNewPos;
+}
+
+
+BOOL SwFmtVertOrient::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+    // hier wird immer konvertiert!
+    nMemberId &= ~CONVERT_TWIPS;
+    sal_Bool bRet = sal_True;
+    switch ( nMemberId )
+    {
+        case MID_VERTORIENT_ORIENT:
+        {
+            sal_Int16 nRet = text::VertOrientation::NONE;
+            switch( eOrient )
+            {
+                case VERT_TOP        :  nRet = text::VertOrientation::TOP        ;break;
+                case VERT_CENTER     :  nRet = text::VertOrientation::CENTER     ;break;
+                case VERT_BOTTOM     :  nRet = text::VertOrientation::BOTTOM     ;break;
+                case VERT_CHAR_TOP   :  nRet = text::VertOrientation::CHAR_TOP   ;break;
+                case VERT_CHAR_CENTER:  nRet = text::VertOrientation::CHAR_CENTER;break;
+                case VERT_CHAR_BOTTOM:  nRet = text::VertOrientation::CHAR_BOTTOM;break;
+                case VERT_LINE_TOP   :  nRet = text::VertOrientation::LINE_TOP   ;break;
+                case VERT_LINE_CENTER:  nRet = text::VertOrientation::LINE_CENTER;break;
+                case VERT_LINE_BOTTOM:  nRet = text::VertOrientation::LINE_BOTTOM;break;
+            }
+            rVal <<= nRet;
+        }
+        break;
+        case MID_VERTORIENT_RELATION:
+                rVal <<= lcl_RelToINT(eRelation);
+        break;
+        case MID_VERTORIENT_POSITION:
+                rVal <<= (sal_Int32)TWIP_TO_MM100(GetPos());
+                break;
+        default:
+            ASSERT( !this, "unknown MemberId" );
+            bRet = sal_False;
+    }
+    return bRet;
+}
+
+BOOL SwFmtVertOrient::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+    sal_Bool bConvert = 0 != (nMemberId&CONVERT_TWIPS);
+    nMemberId &= ~CONVERT_TWIPS;
+    sal_Bool bRet = sal_True;
+    switch ( nMemberId )
+    {
+        case MID_VERTORIENT_ORIENT:
+        {
+            sal_uInt16 nVal;
+            rVal >>= nVal;
+            switch( nVal )
+            {
+                case text::VertOrientation::NONE:           eOrient = VERT_NONE;    break;
+                case text::VertOrientation::TOP        :    eOrient = VERT_TOP;     break;
+                case text::VertOrientation::CENTER     :    eOrient = VERT_CENTER;     break;
+                case text::VertOrientation::BOTTOM     :    eOrient = VERT_BOTTOM;     break;
+                case text::VertOrientation::CHAR_TOP   :    eOrient = VERT_CHAR_TOP;   break;
+                case text::VertOrientation::CHAR_CENTER:    eOrient = VERT_CHAR_CENTER;break;
+                case text::VertOrientation::CHAR_BOTTOM:    eOrient = VERT_CHAR_BOTTOM;break;
+                case text::VertOrientation::LINE_TOP   :    eOrient = VERT_LINE_TOP;    break;
+                case text::VertOrientation::LINE_CENTER:    eOrient = VERT_LINE_CENTER;break;
+                case text::VertOrientation::LINE_BOTTOM:    eOrient = VERT_LINE_BOTTOM;break;
+            }
+        }
+        break;
+        case MID_VERTORIENT_RELATION:
+        {
+            eRelation = lcl_IntToRelation(rVal);
+        }
+        break;
+        case MID_VERTORIENT_POSITION:
+        {
+            sal_Int32 nVal;
+            rVal >>= nVal;
+            if(bConvert)
+                nVal = MM100_TO_TWIP(nVal);
+            SetPos( nVal );
+        }
+        break;
+        default:
+            ASSERT( !this, "unknown MemberId" );
+            bRet = sal_False;
+    }
+    return bRet;
+}
+
+
+
+//  class SwFmtHoriOrient
+//  Implementierung teilweise inline im hxx
+
+SwFmtHoriOrient::SwFmtHoriOrient( SwTwips nX, SwHoriOrient eHori,
+                              SwRelationOrient eRel, sal_Bool bPos )
+    : SfxPoolItem( RES_HORI_ORIENT ),
+    nXPos( nX ),
+    eOrient( eHori ),
+    eRelation( eRel ),
+    bPosToggle( bPos )
+{}
+
+int  SwFmtHoriOrient::operator==( const SfxPoolItem& rAttr ) const
+{
+    ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" );
+    return ( nXPos == ((SwFmtHoriOrient&)rAttr).nXPos &&
+             eOrient == ((SwFmtHoriOrient&)rAttr).eOrient &&
+             eRelation == ((SwFmtHoriOrient&)rAttr).eRelation &&
+             bPosToggle == ((SwFmtHoriOrient&)rAttr).bPosToggle );
+}
+
+SfxPoolItem*  SwFmtHoriOrient::Clone( SfxItemPool* ) const
+{
+    return new SwFmtHoriOrient( nXPos, eOrient, eRelation, bPosToggle );
+}
+
+
+SwTwips  SwFmtHoriOrient::GetPosConvertedToSw31(
+    const SvxLRSpaceItem *pLRSpace ) const
+{
+    SwTwips nNewPos = GetPos();
+
+    if( HORI_NONE==GetHoriOrient() && pLRSpace )
+    {
+        nNewPos -= pLRSpace->GetLeft();
+    }
+
+    return nNewPos;
+}
+
+SwTwips  SwFmtHoriOrient::GetPosConvertedFromSw31(
+    const SvxLRSpaceItem *pLRSpace ) const
+{
+    SwTwips nNewPos = GetPos();
+
+    if( HORI_NONE==GetHoriOrient() && pLRSpace )
+    {
+        nNewPos += pLRSpace->GetLeft();
+    }
+
+    return nNewPos;
+}
+
+BOOL SwFmtHoriOrient::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+    // hier wird immer konvertiert!
+    nMemberId &= ~CONVERT_TWIPS;
+    sal_Bool bRet = sal_True;
+    switch ( nMemberId )
+    {
+        case MID_HORIORIENT_ORIENT:
+        {
+            sal_Int16 nRet = text::HoriOrientation::NONE;
+            switch( eOrient )
+            {
+                case HORI_RIGHT:    nRet = text::HoriOrientation::RIGHT; break;
+                case HORI_CENTER :  nRet = text::HoriOrientation::CENTER; break;
+                case HORI_LEFT   :  nRet = text::HoriOrientation::LEFT; break;
+                case HORI_INSIDE :  nRet = text::HoriOrientation::INSIDE; break;
+                case HORI_OUTSIDE:  nRet = text::HoriOrientation::OUTSIDE; break;
+                case HORI_FULL:     nRet = text::HoriOrientation::FULL; break;
+                case HORI_LEFT_AND_WIDTH :
+                    nRet = text::HoriOrientation::LEFT_AND_WIDTH;
+                break;
+            }
+            rVal <<= nRet;
+        }
+        break;
+        case MID_HORIORIENT_RELATION:
+            rVal <<= lcl_RelToINT(eRelation);
+        break;
+        case MID_HORIORIENT_POSITION:
+                rVal <<= (sal_Int32)TWIP_TO_MM100(GetPos());
+                break;
+        case MID_HORIORIENT_PAGETOGGLE:
+        {
+            BOOL bTmp = IsPosToggle();
+            rVal.setValue(&bTmp, ::getBooleanCppuType());
+        }
+                break;
+        default:
+            ASSERT( !this, "unknown MemberId" );
+            bRet = sal_False;
+    }
+    return bRet;
+}
+
+BOOL SwFmtHoriOrient::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+    sal_Bool bConvert = 0 != (nMemberId&CONVERT_TWIPS);
+    nMemberId &= ~CONVERT_TWIPS;
+    sal_Bool bRet = sal_True;
+    switch ( nMemberId )
+    {
+        case MID_HORIORIENT_ORIENT:
+        {
+            switch( *(sal_Int16*)rVal.getValue() )
+            {
+                case text::HoriOrientation::NONE:       eOrient = HORI_NONE ;   break;
+                case text::HoriOrientation::RIGHT:  eOrient = HORI_RIGHT;   break;
+                case text::HoriOrientation::CENTER :    eOrient = HORI_CENTER;  break;
+                case text::HoriOrientation::LEFT   :    eOrient = HORI_LEFT;    break;
+                case text::HoriOrientation::INSIDE :    eOrient = HORI_INSIDE;  break;
+                case text::HoriOrientation::OUTSIDE:    eOrient = HORI_OUTSIDE; break;
+                case text::HoriOrientation::FULL:      eOrient = HORI_FULL;     break;
+                case text::HoriOrientation::LEFT_AND_WIDTH:
+                    eOrient = HORI_LEFT_AND_WIDTH;
+                break;
+            }
+        }
+        break;
+        case MID_HORIORIENT_RELATION:
+        {
+            eRelation = lcl_IntToRelation(rVal);
+        }
+        break;
+        case MID_HORIORIENT_POSITION:
+        {
+            sal_Int32 nVal = *(sal_Int32*)rVal.getValue();
+            if(bConvert)
+                nVal = MM100_TO_TWIP(nVal);
+            SetPos( nVal );
+        }
+        break;
+        case MID_HORIORIENT_PAGETOGGLE:
+                SetPosToggle( *(sal_Bool*)rVal.getValue());
+            break;
+        default:
+            ASSERT( !this, "unknown MemberId" );
+            bRet = sal_False;
+    }
+    return bRet;
+}
+
+
+
+//  class SwFmtAnchor
+//  Implementierung teilweise inline im hxx
+
+SwFmtAnchor::SwFmtAnchor( RndStdIds nRnd, sal_uInt16 nPage )
+    : SfxPoolItem( RES_ANCHOR ),
+    pCntntAnchor( 0 ),
+    nAnchorId( nRnd ),
+    nPageNum( nPage )
+{}
+
+SwFmtAnchor::SwFmtAnchor( const SwFmtAnchor &rCpy )
+    : SfxPoolItem( RES_ANCHOR ),
+    nAnchorId( rCpy.GetAnchorId() ),
+    nPageNum( rCpy.GetPageNum() )
+{
+    pCntntAnchor = rCpy.GetCntntAnchor() ?
+                        new SwPosition( *rCpy.GetCntntAnchor() ) : 0;
+}
+
+ SwFmtAnchor::~SwFmtAnchor()
+{
+    delete pCntntAnchor;
+}
+
+void SwFmtAnchor::SetAnchor( const SwPosition *pPos )
+{
+    if ( pCntntAnchor )
+        delete pCntntAnchor;
+    pCntntAnchor = pPos ? new SwPosition( *pPos ) : 0;
+        //AM Absatz gebundene Flys sollten nie in den Absatz hineinzeigen.
+    if ( pCntntAnchor && ( FLY_AT_CNTNT == nAnchorId ||
+                           FLY_AT_FLY == nAnchorId ))
+        pCntntAnchor->nContent.Assign( 0, 0 );
+}
+
+SwFmtAnchor& SwFmtAnchor::operator=(const SwFmtAnchor& rAnchor)
+{
+    nAnchorId  = rAnchor.GetAnchorId();
+    nPageNum   = rAnchor.GetPageNum();
+
+    delete pCntntAnchor;
+    pCntntAnchor = rAnchor.pCntntAnchor ?
+                                    new SwPosition(*(rAnchor.pCntntAnchor)) : 0;
+    return *this;
+}
+
+int  SwFmtAnchor::operator==( const SfxPoolItem& rAttr ) const
+{
+    ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" );
+    return ( nAnchorId == ((SwFmtAnchor&)rAttr).GetAnchorId() &&
+             nPageNum == ((SwFmtAnchor&)rAttr).GetPageNum()   &&
+                    //Anker vergleichen. Entweder zeigen beide auf das gleiche
+                    //Attribut bzw. sind 0 oder die SwPosition* sind beide
+                    //gueltig und die SwPositions sind gleich.
+             (pCntntAnchor == ((SwFmtAnchor&)rAttr).GetCntntAnchor() ||
+              (pCntntAnchor && ((SwFmtAnchor&)rAttr).GetCntntAnchor() &&
+               *pCntntAnchor == *((SwFmtAnchor&)rAttr).GetCntntAnchor())));
+}
+
+SfxPoolItem*  SwFmtAnchor::Clone( SfxItemPool* ) const
+{
+    return new SwFmtAnchor( *this );
+}
+
+/*-----------------16.02.98 15:21-------------------
+
+--------------------------------------------------*/
+BOOL SwFmtAnchor::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+    // hier wird immer konvertiert!
+    nMemberId &= ~CONVERT_TWIPS;
+    sal_Bool bRet = sal_True;
+    switch ( nMemberId )
+    {
+        case MID_ANCHOR_ANCHORTYPE:
+
+            text::TextContentAnchorType eRet;
+            switch((sal_Int16)GetAnchorId())
+            {
+                case  FLY_AUTO_CNTNT : eRet = text::TextContentAnchorType_AT_CHARACTER;break;
+                case  FLY_PAGE       : eRet = text::TextContentAnchorType_AT_PAGE;      break;
+                case  FLY_AT_FLY     : eRet = text::TextContentAnchorType_AT_FRAME;    break;
+                case  FLY_IN_CNTNT   : eRet = text::TextContentAnchorType_AS_CHARACTER;break;
+                //case  FLY_AT_CNTNT  :
+                default: eRet = text::TextContentAnchorType_AT_PARAGRAPH;
+            }
+            rVal <<= eRet;
+        break;
+        case MID_ANCHOR_PAGENUM:
+            rVal <<= (sal_Int16)GetPageNum();
+            break;
+        default:
+            ASSERT( !this, "unknown MemberId" );
+            bRet = sal_False;
+    }
+    return bRet;
+}
+
+BOOL SwFmtAnchor::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+    // hier wird immer konvertiert!
+    nMemberId &= ~CONVERT_TWIPS;
+    sal_Bool bRet = sal_True;
+    switch ( nMemberId )
+    {
+        case MID_ANCHOR_ANCHORTYPE:
+        {
+            RndStdIds   eAnchor;
+            sal_Int32 eVal;
+            try
+            {
+                eVal = utl::getEnumAsINT32(rVal);
+            }
+            catch(...) {}
+            switch(eVal)
+            {
+                case  text::TextContentAnchorType_AS_CHARACTER: eAnchor = FLY_IN_CNTNT; break;
+                case  text::TextContentAnchorType_AT_PAGE      : eAnchor = FLY_PAGE;        break;
+                case  text::TextContentAnchorType_AT_FRAME    : eAnchor = FLY_AT_FLY;       break;
+                case  text::TextContentAnchorType_AT_CHARACTER: eAnchor = FLY_AUTO_CNTNT;   break;
+                //case  text::TextContentAnchorType_AT_PARAGRAPH:
+                default: eAnchor = FLY_AT_CNTNT;
+            }
+            SetType( eAnchor );
+        }
+        break;
+        case MID_ANCHOR_PAGENUM:
+        {
+            sal_Int16 nVal = *(sal_Int16*)rVal.getValue();
+            if(nVal > 0)
+                SetPageNum( nVal );
+            else
+                bRet = sal_False;
+        }
+        break;
+        default:
+            ASSERT( !this, "unknown MemberId" );
+            bRet = sal_False;
+    }
+    return bRet;
+}
+
+//  class SwFmtURL
+//  Implementierung teilweise inline im hxx
+
+SwFmtURL::SwFmtURL() :
+    SfxPoolItem( RES_URL ),
+    pMap( 0 ),
+    bIsServerMap( sal_False )
+{
+}
+
+SwFmtURL::SwFmtURL( const SwFmtURL &rURL) :
+    SfxPoolItem( RES_URL ),
+    sURL( rURL.GetURL() ),
+    sTargetFrameName( rURL.GetTargetFrameName() ),
+    sName( rURL.GetName() ),
+    bIsServerMap( rURL.IsServerMap() )
+{
+    pMap = rURL.GetMap() ? new ImageMap( *rURL.GetMap() ) : 0;
+}
+
+SwFmtURL::~SwFmtURL()
+{
+    if ( pMap )
+        delete pMap;
+}
+
+int SwFmtURL::operator==( const SfxPoolItem &rAttr ) const
+{
+    ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" );
+    const SwFmtURL &rCmp = (SwFmtURL&)rAttr;
+    sal_Bool bRet = bIsServerMap     == rCmp.IsServerMap() &&
+                sURL             == rCmp.GetURL() &&
+                sTargetFrameName == rCmp.GetTargetFrameName() &&
+                sName            == rCmp.GetName();
+    if ( bRet )
+    {
+        if ( pMap && rCmp.GetMap() )
+            bRet = *pMap == *rCmp.GetMap();
+        else
+            bRet = pMap == rCmp.GetMap();
+    }
+    return bRet;
+}
+
+SfxPoolItem* SwFmtURL::Clone( SfxItemPool* pPool ) const
+{
+    return new SwFmtURL( *this );
+}
+
+void SwFmtURL::SetURL( const XubString &rURL, sal_Bool bServerMap )
+{
+    sURL = rURL;
+    bIsServerMap = bServerMap;
+}
+
+void SwFmtURL::SetMap( const ImageMap *pM )
+{
+    if ( pMap )
+        delete pMap;
+    pMap = pM ? new ImageMap( *pM ) : 0;
+}
+
+
+BOOL SwFmtURL::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+    // hier wird immer konvertiert!
+    nMemberId &= ~CONVERT_TWIPS;
+    sal_Bool bRet = sal_True;
+    switch ( nMemberId )
+    {
+        case MID_URL_URL:
+        {
+            OUString sRet = GetURL();
+            rVal <<= sRet;
+        }
+        break;
+        case MID_URL_TARGET:
+        {
+            OUString sRet = GetTargetFrameName();
+            rVal <<= sRet;
+        }
+        break;
+        case MID_URL_HYPERLINKNAME:
+            rVal <<= OUString( GetName() );
+            break;
+        case MID_URL_CLIENTMAP:
+            ASSERT( !this, "not implemented" );
+            break;
+        case MID_URL_SERVERMAP:
+        {
+            BOOL bTmp = IsServerMap();
+            rVal.setValue(&bTmp, ::getBooleanCppuType());
+        }
+            break;
+        default:
+            ASSERT( !this, "unknown MemberId" );
+            bRet = sal_False;
+    }
+    return bRet;
+}
+
+BOOL SwFmtURL::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+    // hier wird immer konvertiert!
+    nMemberId &= ~CONVERT_TWIPS;
+    sal_Bool bRet = sal_True;
+    switch ( nMemberId )
+    {
+        case MID_URL_URL:
+            SetURL( *(OUString*)rVal.getValue(), bIsServerMap );
+        break;
+        case MID_URL_TARGET:
+            SetTargetFrameName( *(OUString*)rVal.getValue() );
+        break;
+        case MID_URL_HYPERLINKNAME:
+            SetName( *(OUString*)rVal.getValue() );
+        break;
+        case MID_URL_CLIENTMAP:
+            ASSERT( !this, "not implemented" );
+            break;
+        case MID_URL_SERVERMAP:
+            bIsServerMap = *(sal_Bool*)rVal.getValue();
+            break;
+        default:
+            ASSERT( !this, "unknown MemberId" );
+            bRet = sal_False;
+    }
+    return bRet;
+}
+
+
+// class SwNoReadOnly
+
+SfxPoolItem* SwFmtEditInReadonly::Clone( SfxItemPool* pPool ) const
+{
+    return new SwFmtEditInReadonly( Which(), GetValue() );
+}
+
+// class SwFmtLayoutSplit
+
+SfxPoolItem* SwFmtLayoutSplit::Clone( SfxItemPool* pPool ) const
+{
+    return new SwFmtLayoutSplit( GetValue() );
+}
+
+// class SwFmtNoBalancedColumns
+
+SfxPoolItem* SwFmtNoBalancedColumns::Clone( SfxItemPool* pPool ) const
+{
+    return new SwFmtNoBalancedColumns( GetValue() );
+}
+
+// class SwFmtFtnEndAtTxtEnd
+
+sal_uInt16 SwFmtFtnEndAtTxtEnd::GetValueCount() const
+{
+    return sal_uInt16( FTNEND_ATTXTEND_END );
+}
+
+SwFmtFtnEndAtTxtEnd& SwFmtFtnEndAtTxtEnd::operator=(
+                        const SwFmtFtnEndAtTxtEnd& rAttr )
+{
+    SfxEnumItem::SetValue( rAttr.GetValue() );
+    aFmt = rAttr.aFmt;
+    nOffset = rAttr.nOffset;
+    sPrefix = rAttr.sPrefix;
+    sSuffix = rAttr.sSuffix;
+    return *this;
+}
+
+int SwFmtFtnEndAtTxtEnd::operator==( const SfxPoolItem& rItem ) const
+{
+    const SwFmtFtnEndAtTxtEnd& rAttr = (SwFmtFtnEndAtTxtEnd&)rItem;
+    return SfxEnumItem::operator==( rAttr ) &&
+            aFmt.eType == rAttr.aFmt.eType &&
+            nOffset == rAttr.nOffset &&
+            sPrefix == rAttr.sPrefix &&
+            sSuffix == rAttr.sSuffix;
+}
+
+BOOL SwFmtFtnEndAtTxtEnd::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+    return SfxEnumItem::QueryValue( rVal, nMemberId );
+}
+
+BOOL SwFmtFtnEndAtTxtEnd::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+    return SfxEnumItem::PutValue( rVal, nMemberId );
+}
+
+
+// class SwFmtFtnAtTxtEnd
+
+SfxPoolItem* SwFmtFtnAtTxtEnd::Clone( SfxItemPool* pPool ) const
+{
+    SwFmtFtnAtTxtEnd* pNew = new SwFmtFtnAtTxtEnd;
+    *pNew = *this;
+    return pNew;
+}
+
+// class SwFmtEndAtTxtEnd
+
+SfxPoolItem* SwFmtEndAtTxtEnd::Clone( SfxItemPool* pPool ) const
+{
+    SwFmtEndAtTxtEnd* pNew = new SwFmtEndAtTxtEnd;
+    *pNew = *this;
+    return pNew;
+}
+
+//class SwFmtChain
+
+
+int SwFmtChain::operator==( const SfxPoolItem &rAttr ) const
+{
+    ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" );
+
+    return GetPrev() == ((SwFmtChain&)rAttr).GetPrev() &&
+           GetNext() == ((SwFmtChain&)rAttr).GetNext();
+}
+
+SwFmtChain::SwFmtChain( const SwFmtChain &rCpy ) :
+    SfxPoolItem( RES_CHAIN )
+{
+    SetPrev( rCpy.GetPrev() );
+    SetNext( rCpy.GetNext() );
+}
+
+SfxPoolItem* SwFmtChain::Clone( SfxItemPool* pPool ) const
+{
+    SwFmtChain *pRet = new SwFmtChain;
+    pRet->SetPrev( GetPrev() );
+    pRet->SetNext( GetNext() );
+    return pRet;
+}
+
+void SwFmtChain::SetPrev( SwFlyFrmFmt *pFmt )
+{
+    if ( pFmt )
+        pFmt->Add( &aPrev );
+    else if ( aPrev.GetRegisteredIn() )
+        ((SwModify*)aPrev.GetRegisteredIn())->Remove( &aPrev );
+}
+
+void SwFmtChain::SetNext( SwFlyFrmFmt *pFmt )
+{
+    if ( pFmt )
+        pFmt->Add( &aNext );
+    else if ( aNext.GetRegisteredIn() )
+        ((SwModify*)aNext.GetRegisteredIn())->Remove( &aNext );
+}
+
+BOOL SwFmtChain::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+    // hier wird immer konvertiert!
+    nMemberId &= ~CONVERT_TWIPS;
+    sal_Bool   bRet = sal_True;
+    XubString aRet;
+    switch ( nMemberId )
+    {
+        case MID_CHAIN_PREVNAME:
+            if ( GetPrev() )
+                aRet = GetPrev()->GetName();
+            break;
+        case MID_CHAIN_NEXTNAME:
+            if ( GetNext() )
+                aRet = GetNext()->GetName();
+            break;
+        default:
+            ASSERT( !this, "unknown MemberId" );
+            bRet = sal_False;
+    }
+    rVal <<= OUString(aRet);
+    return bRet;
+}
+
+
+
+
+//class SwFmtLineNumber
+
+SwFmtLineNumber::SwFmtLineNumber() :
+    SfxPoolItem( RES_LINENUMBER )
+{
+    nStartValue = 0;
+    bCountLines = sal_True;
+}
+
+SwFmtLineNumber::~SwFmtLineNumber()
+{
+}
+
+int SwFmtLineNumber::operator==( const SfxPoolItem &rAttr ) const
+{
+    ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" );
+
+    return nStartValue  == ((SwFmtLineNumber&)rAttr).GetStartValue() &&
+           bCountLines  == ((SwFmtLineNumber&)rAttr).IsCount();
+}
+
+SfxPoolItem* SwFmtLineNumber::Clone( SfxItemPool* pPool ) const
+{
+    return new SwFmtLineNumber( *this );
+}
+
+BOOL SwFmtLineNumber::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+    // hier wird immer konvertiert!
+    nMemberId &= ~CONVERT_TWIPS;
+    sal_Bool bRet = sal_True;
+    switch ( nMemberId )
+    {
+        case MID_LINENUMBER_COUNT:
+        {
+            BOOL bTmp = IsCount();
+            rVal.setValue(&bTmp, ::getBooleanCppuType());
+        }
+        break;
+        case MID_LINENUMBER_STARTVALUE:
+            rVal <<= (sal_Int32)GetStartValue();
+            break;
+        default:
+            ASSERT( !this, "unknown MemberId" );
+            bRet = sal_False;
+    }
+    return bRet;
+}
+
+BOOL SwFmtLineNumber::PutValue( const uno::Any& rVal, BYTE nMemberId )
+{
+    // hier wird immer konvertiert!
+    nMemberId &= ~CONVERT_TWIPS;
+    sal_Bool bRet = sal_True;
+    switch ( nMemberId )
+    {
+        case MID_LINENUMBER_COUNT:
+            SetCountLines( *(sal_Bool*)rVal.getValue() );
+            break;
+        case MID_LINENUMBER_STARTVALUE:
+            SetStartValue( *(sal_Int32*)rVal.getValue());
+            break;
+        default:
+            ASSERT( !this, "unknown MemberId" );
+            bRet = sal_False;
+    }
+    return bRet;
+}
+
+
+
+//  class SwFrmFmt
+//  Implementierung teilweise inline im hxx
+
+void SwFrmFmt::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew )
+{
+    SwFmtHeader *pH = 0;
+    SwFmtFooter *pF = 0;
+
+    sal_uInt16 nWhich = pNew ? pNew->Which() : 0;
+
+    if( RES_ATTRSET_CHG == nWhich )
+    {
+        ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
+            RES_HEADER, sal_False, (const SfxPoolItem**)&pH );
+        ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
+            RES_FOOTER, sal_False, (const SfxPoolItem**)&pF );
+    }
+    else if( RES_HEADER == nWhich )
+        pH = (SwFmtHeader*)pNew;
+    else if( RES_FOOTER == nWhich )
+        pF = (SwFmtFooter*)pNew;
+
+    if( pH && pH->IsActive() && !pH->GetHeaderFmt() )
+    {   //Hat er keinen, mach ich ihm einen
+        SwFrmFmt *pFmt = GetDoc()->MakeLayoutFmt( RND_STD_HEADER );
+        pFmt->Add( pH );
+    }
+
+    if( pF && pF->IsActive() && !pF->GetFooterFmt() )
+    {   //Hat er keinen, mach ich ihm einen
+        SwFrmFmt *pFmt = GetDoc()->MakeLayoutFmt( RND_STD_FOOTER );
+        pFmt->Add( pF );
+    }
+
+    // MIB 24.3.98: Modify der Basisklasse muss immer gerufen werden, z.B.
+    // wegen RESET_FMTWRITTEN.
+//  if ( GetDepends() )
+        SwFmt::Modify( pOld, pNew );
+}
+
+//Vernichtet alle Frms, die in aDepend angemeldet sind.
+
+void SwFrmFmt::DelFrms()
+{
+    SwClientIter aIter( *this );
+    SwClient * pLast = aIter.GoStart();
+    if( pLast )
+        do {
+            if ( pLast->ISA(SwFrm) )
+            {
+                ((SwFrm*)pLast)->Cut();
+                delete pLast;
+            }
+        } while( 0 != ( pLast = aIter++ ));
+}
+
+void SwFrmFmt::MakeFrms()
+{
+    ASSERT( !this, "Sorry not implemented." );
+}
+
+
+
+SwRect SwFrmFmt::FindLayoutRect( const sal_Bool bPrtArea, const Point* pPoint,
+                                 const sal_Bool bCalcFrm ) const
+{
+    SwRect aRet;
+    SwFrm *pFrm = 0;
+    if( ISA( SwSectionFmt ) )
+    {
+        // dann den ::com::sun::star::frame::Frame per Node2Layout besorgen
+        SwSectionNode* pSectNd = ((SwSectionFmt*)this)->GetSectionNode();
+        if( pSectNd )
+        {
+            SwNode2Layout aTmp( *pSectNd, pSectNd->GetIndex() - 1 );
+            pFrm = aTmp.NextFrm();
+
+            if( pFrm && pFrm->GetRegisteredIn() != this )
+            {
+                // die Section hat keinen eigenen ::com::sun::star::frame::Frame, also falls
+                // jemand die tatsaechliche Groeáe braucht, so muss das
+                // noch implementier werden, in dem sich vom Ende noch
+                // der entsprechende ::com::sun::star::frame::Frame besorgt wird.
+                // PROBLEM: was passiert bei SectionFrames, die auf unter-
+                //          schiedlichen Seiten stehen??
+                if( bPrtArea )
+                    aRet = pFrm->Prt();
+                else
+                {
+                    aRet = pFrm->Frm();
+                    --aRet.Pos().Y();
+                }
+                pFrm = 0;       // das Rect ist ja jetzt fertig
+            }
+        }
+    }
+    else
+    {
+        sal_uInt16 nFrmType = RES_FLYFRMFMT == Which() ? FRM_FLY : USHRT_MAX;
+        pFrm = ::GetFrmOfModify( *(SwModify*)this, nFrmType, pPoint,
+                                    0, bCalcFrm );
+    }
+
+    if( pFrm )
+    {
+        if( bPrtArea )
+            aRet = pFrm->Prt();
+        else
+            aRet = pFrm->Frm();
+    }
+    return aRet;
+}
+
+SwContact* SwFrmFmt::FindContactObj()
+{
+    SwClientIter aIter( *this );
+    return (SwContact*)aIter.First( TYPE( SwContact ) );
+}
+
+SdrObject* SwFrmFmt::FindSdrObject()
+{
+    SwClientIter aIter( *this );
+    SwClient* pFnd = aIter.First( TYPE( SwContact ) );
+    return pFnd ? ((SwContact*)pFnd)->GetMaster() : 0;
+}
+
+SdrObject* SwFrmFmt::FindRealSdrObject()
+{
+    if( RES_FLYFRMFMT == Which() )
+    {
+        Point aNullPt;
+        SwFlyFrm* pFly = (SwFlyFrm*)::GetFrmOfModify( *this, FRM_FLY,
+                                                    &aNullPt, 0, sal_False );
+        return pFly ? pFly->GetVirtDrawObj() : 0;
+    }
+    return FindSdrObject();
+}
+
+
+sal_Bool SwFrmFmt::IsLowerOf( const SwFrmFmt& rFmt ) const
+{
+    //Auch eine Verkettung von Innen nach aussen oder von aussen
+    //nach innen ist nicht zulaessig.
+    SwClientIter aIter( *(SwModify*)this );
+    SwFlyFrm *pSFly = (SwFlyFrm*)aIter.First( TYPE(SwFlyFrm) );
+    if( pSFly )
+    {
+        SwClientIter aOtherIter( (SwModify&)rFmt );
+        SwFlyFrm *pAskFly = (SwFlyFrm*)aOtherIter.First( TYPE(SwFlyFrm) );
+        if( pAskFly )
+            return pSFly->IsLowerOf( pAskFly );
+    }
+
+    // dann mal ueber die Node-Positionen versuchen
+    const SwFmtAnchor* pAnchor = &rFmt.GetAnchor();
+    if( FLY_PAGE != pAnchor->GetAnchorId() && pAnchor->GetCntntAnchor() )
+    {
+        const SwSpzFrmFmts& rFmts = *GetDoc()->GetSpzFrmFmts();
+        const SwNode* pFlyNd = pAnchor->GetCntntAnchor()->nNode.GetNode().
+                                FindFlyStartNode();
+        while( pFlyNd )
+        {
+            // dann ueber den Anker nach oben "hangeln"
+            for( sal_uInt16 n = 0; n < rFmts.Count(); ++n )
+            {
+                const SwFrmFmt* pFmt = rFmts[ n ];
+                const SwNodeIndex* pIdx = pFmt->GetCntnt().GetCntntIdx();
+                if( pIdx && pFlyNd == &pIdx->GetNode() )
+                {
+                    if( pFmt == this )
+                        return sal_True;
+
+                    pAnchor = &pFmt->GetAnchor();
+                    if( FLY_PAGE == pAnchor->GetAnchorId() ||
+                        !pAnchor->GetCntntAnchor() )
+                        return sal_False;
+
+                    pFlyNd = pAnchor->GetCntntAnchor()->nNode.GetNode().
+                                FindFlyStartNode();
+                    break;
+                }
+            }
+            if( n >= rFmts.Count() )
+            {
+                ASSERT( !this, "Fly-Section aber kein Format gefunden" );
+                return sal_False;
+            }
+        }
+    }
+    return sal_False;
+}
+
+//  class SwFlyFrmFmt
+//  Implementierung teilweise inline im hxx
+
+SwFlyFrmFmt::~SwFlyFrmFmt()
+{
+    SwClientIter aIter( *this );
+    SwClient * pLast = aIter.GoStart();
+    if( pLast )
+        do {
+            if ( pLast->ISA( SwFlyFrm ) )
+                delete pLast;
+
+        } while( 0 != ( pLast = aIter++ ));
+
+    pLast = aIter.GoStart();
+    if( pLast )
+        do {
+            if ( pLast->ISA( SwFlyDrawContact ) )
+                delete pLast;
+
+        } while( 0 != ( pLast = aIter++ ));
+}
+
+//Erzeugen der Frms wenn das Format einen Absatzgebundenen Rahmen beschreibt.
+//MA: 14. Feb. 94, Erzeugen der Frms auch fuer Seitengebundene Rahmen.
+
+void SwFlyFrmFmt::MakeFrms()
+{
+    // gibts ueberhaupt ein Layout ??
+    if( !GetDoc()->GetRootFrm() )
+        return;
+
+    SwModify *pModify = 0;
+    const SwFmtAnchor &rAnch = GetAnchor();
+    switch( rAnch.GetAnchorId() )
+    {
+    case FLY_IN_CNTNT:
+    case FLY_AT_CNTNT:
+    case FLY_AUTO_CNTNT:
+        if( rAnch.GetCntntAnchor() )
+            pModify = rAnch.GetCntntAnchor()->nNode.GetNode().GetCntntNode();
+        break;
+
+    case FLY_AT_FLY:
+        if( rAnch.GetCntntAnchor() )
+        {
+            //Erst einmal ueber den Inhalt suchen, weil konstant schnell. Kann
+            //Bei verketteten Rahmen aber auch schief gehen, weil dann evtl.
+            //niemals ein ::com::sun::star::frame::Frame zu dem Inhalt existiert. Dann muss leider noch
+            //die Suche vom StartNode zum FrameFormat sein.
+            SwNodeIndex aIdx( rAnch.GetCntntAnchor()->nNode );
+            SwCntntNode *pCNd = GetDoc()->GetNodes().GoNext( &aIdx );
+            SwClientIter aIter( *pCNd );
+            if ( aIter.First( TYPE(SwFrm) ) )
+                pModify = pCNd;
+            else
+            {
+                const SwNodeIndex &rIdx = rAnch.GetCntntAnchor()->nNode;
+                SwSpzFrmFmts& rFmts = *GetDoc()->GetSpzFrmFmts();
+                for( sal_uInt16 i = 0; i < rFmts.Count(); ++i )
+                {
+                    SwFrmFmt* pFlyFmt = rFmts[i];
+                    if( pFlyFmt->GetCntnt().GetCntntIdx() &&
+                        rIdx == *pFlyFmt->GetCntnt().GetCntntIdx() )
+                    {
+                        pModify = pFlyFmt;
+                        break;
+                    }
+                }
+            }
+        }
+        break;
+
+    case FLY_PAGE:
+        {
+            const sal_uInt16 nPgNum = rAnch.GetPageNum();
+            SwPageFrm *pPage = (SwPageFrm*)GetDoc()->GetRootFrm()->Lower();
+            while ( pPage )
+            {
+                if ( pPage->GetPhyPageNum() == nPgNum )
+                {
+                    pPage->PlaceFly( 0, this, &rAnch );
+                    break;
+                }
+                pPage = (SwPageFrm*)pPage->GetNext();
+            }
+        }
+        break;
+    }
+
+    if( pModify )
+    {
+        SwClientIter aIter( *pModify );
+        for( SwFrm *pFrm = (SwFrm*)aIter.First( TYPE(SwFrm) );
+             pFrm;
+             pFrm = (SwFrm*)aIter.Next() )
+        {
+            FASTBOOL bAdd = !pFrm->IsCntntFrm() ||
+                            !((SwCntntFrm*)pFrm)->IsFollow();
+
+            if ( FLY_AT_FLY == rAnch.GetAnchorId() && !pFrm->IsFlyFrm() )
+                pFrm = pFrm->FindFlyFrm();
+
+            if( pFrm->GetDrawObjs() )
+            {
+                SwDrawObjs &rObjs = *pFrm->GetDrawObjs();
+                for( sal_uInt16 i = 0; i < rObjs.Count(); ++i)
+                {
+                    SdrObject *pO = rObjs[i];
+                    if( pO->ISA( SwVirtFlyDrawObj ) &&
+                        ((SwVirtFlyDrawObj*)pO)->GetFmt() == this )
+                    {
+                        bAdd = sal_False;
+                        break;
+                    }
+                }
+            }
+
+            if( bAdd )
+            {
+                SwFlyFrm *pFly = 0;
+                switch( rAnch.GetAnchorId() )
+                {
+                case FLY_AT_FLY:
+                    pFly = new SwFlyLayFrm( this, pFrm );
+                    break;
+
+                case FLY_AT_CNTNT:
+                case FLY_AUTO_CNTNT:
+                    pFly = new SwFlyAtCntFrm( this, pFrm );
+                    break;
+
+                case FLY_IN_CNTNT:
+                    pFly = new SwFlyInCntFrm( this, pFrm );
+                    break;
+#ifndef PRODUCT
+                default:
+                    ASSERT( !this, "Neuer Ankertyp" );
+#endif
+                }
+                pFrm->AppendFly( pFly );
+                SwPageFrm *pPage = pFly->FindPageFrm();
+                if( pPage )
+                    ::RegistFlys( pPage, pFly );
+            }
+        }
+    }
+}
+
+SwFlyFrm* SwFlyFrmFmt::GetFrm( const Point* pPoint, const sal_Bool bCalcFrm ) const
+{
+    return (SwFlyFrm*)::GetFrmOfModify( *(SwModify*)this, FRM_FLY,
+                                            pPoint, 0, bCalcFrm );
+}
+
+sal_Bool SwFlyFrmFmt::GetInfo( SfxPoolItem& rInfo ) const
+{
+    switch( rInfo.Which() )
+    {
+    case RES_CONTENT_VISIBLE:
+        {
+            ((SwPtrMsgPoolItem&)rInfo).pObject =
+                SwClientIter( *(SwFlyFrmFmt*)this ).First( TYPE(SwFrm) );
+        }
+        return sal_False;
+
+    default:
+        return SwFrmFmt::GetInfo( rInfo );
+    }
+    return sal_True;
+}
+
+//  class SwDrawFrmFmt
+//  Implementierung teilweise inline im hxx
+
+#pragma optimize( "e", off )
+
+SwDrawFrmFmt::~SwDrawFrmFmt()
+{
+    SwContact *pContact = FindContactObj();
+    delete pContact;
+}
+
+#pragma optimize( "e", on )
+
+void SwDrawFrmFmt::MakeFrms()
+{
+    SwDrawContact *pContact = (SwDrawContact*)FindContactObj();
+    pContact->ConnectToLayout();
+}
+
+void SwDrawFrmFmt::DelFrms()
+{
+    SwDrawContact *pContact = (SwDrawContact *)FindContactObj();
+    if ( pContact ) //fuer den Reader und andere Unabwaegbarkeiten.
+        pContact->DisconnectFromLayout();
+}
+
+
+IMapObject* SwFrmFmt::GetIMapObject( const Point& rPoint,
+                                        const SwFlyFrm *pFly ) const
+{
+    const SwFmtURL &rURL = GetURL();
+    if( !rURL.GetMap() )
+        return 0;
+
+    if( !pFly )
+    {
+        pFly = (SwFlyFrm*) SwClientIter( *(SwFrmFmt*)this ).First( TYPE( SwFlyFrm ));
+        if( !pFly )
+            return 0;
+    }
+
+    //Orignialgroesse fuer OLE und Grafik ist die TwipSize,
+    //ansonsten die Groesse vom FrmFmt des Fly.
+    const SwFrm *pRef;
+    SwNoTxtNode *pNd;
+    Size aOrigSz;
+    if( pFly->Lower() && pFly->Lower()->IsNoTxtFrm() )
+    {
+        pRef = pFly->Lower();
+        pNd = ((SwCntntFrm*)pRef)->GetNode()->GetNoTxtNode();
+        aOrigSz = pNd->GetTwipSize();
+    }
+    else
+    {
+        pRef = pFly;
+        aOrigSz = pFly->GetFmt()->GetFrmSize().GetSize();
+    }
+
+    if( aOrigSz.Width() != 0 && aOrigSz.Height() != 0 )
+    {
+        Point aPos( rPoint );
+        Size aActSz ( pRef == pFly ? pFly->Frm().SSize() : pRef->Prt().SSize() );
+        const MapMode aSrc ( MAP_TWIP );
+        const MapMode aDest( MAP_100TH_MM );
+        aOrigSz = OutputDevice::LogicToLogic( aOrigSz, aSrc, aDest );
+        aActSz  = OutputDevice::LogicToLogic( aActSz,  aSrc, aDest );
+        aPos -= pRef->Frm().Pos();
+        aPos -= pRef->Prt().Pos();
+        aPos    = OutputDevice::LogicToLogic( aPos, aSrc, aDest );
+        sal_uInt32 nFlags = 0;
+        if ( pFly != pRef && pNd->IsGrfNode() )
+        {
+            const sal_uInt16 nMirror = pNd->GetSwAttrSet().
+                                        GetMirrorGrf().GetValue();
+            if ( RES_MIRROR_GRF_BOTH == nMirror )
+                nFlags = IMAP_MIRROR_HORZ | IMAP_MIRROR_VERT;
+            else if ( RES_MIRROR_GRF_VERT == nMirror )
+                nFlags = IMAP_MIRROR_VERT;
+            else if ( RES_MIRROR_GRF_HOR == nMirror )
+                nFlags = IMAP_MIRROR_HORZ;
+
+        }
+        return ((ImageMap*)rURL.GetMap())->GetHitIMapObject( aOrigSz,
+                                                aActSz, aPos, nFlags );
+    }
+
+    return 0;
+}
+
+
+
diff --git a/sw/source/core/layout/calcmove.cxx b/sw/source/core/layout/calcmove.cxx
new file mode 100644
index 000000000000..9c4f539154d5
--- /dev/null
+++ b/sw/source/core/layout/calcmove.cxx
@@ -0,0 +1,1551 @@
+/*************************************************************************
+ *
+ *  $RCSfile: calcmove.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:21 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "rootfrm.hxx"
+#include "pagefrm.hxx"
+#include "cntfrm.hxx"
+#include "viewsh.hxx"
+#include "doc.hxx"
+#include "viewimp.hxx"
+#include "swtypes.hxx"
+#include "dflyobj.hxx"
+#include "dcontact.hxx"
+#include "flyfrm.hxx"
+#include "frmtool.hxx"
+#include "txtftn.hxx"
+#include "fmtftn.hxx"
+
+#ifndef _SVX_ULSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_KEEPITEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _OUTDEV_HXX //autogen
+#include 
+#endif
+
+#ifndef _FMTFSIZE_HXX //autogen
+#include 
+#endif
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#include "tabfrm.hxx"
+#include "ftnfrm.hxx"
+#include "txtfrm.hxx"
+#include "frmsh.hxx"
+#include "pagedesc.hxx"
+#include "ftninfo.hxx"
+#include "sectfrm.hxx"
+#include "dbg_lay.hxx"
+
+//------------------------------------------------------------------------
+//              Move-Methoden
+//------------------------------------------------------------------------
+
+/*************************************************************************
+|*
+|*  SwCntntFrm::ShouldBwdMoved()
+|*
+|*  Beschreibung        Returnwert sagt, ob der Frm verschoben werden sollte.
+|*  Ersterstellung      MA 05. Dec. 96
+|*  Letzte Aenderung    MA 05. Dec. 96
+|*
+|*************************************************************************/
+
+
+BOOL SwCntntFrm::ShouldBwdMoved( SwLayoutFrm *pNewUpper, BOOL, BOOL & )
+{
+    if ( (SwFlowFrm::IsMoveBwdJump() || !IsPrevObjMove()))
+    {
+        //Das zurueckfliessen von Frm's ist leider etwas Zeitintensiv.
+        //Der haufigste Fall ist der, dass dort wo der Frm hinfliessen
+        //moechte die FixSize die gleiche ist, die der Frm selbst hat.
+        //In diesem Fall kann einfach geprueft werden, ob der Frm genug
+        //Platz fuer seine VarSize findet, ist dies nicht der Fall kann
+        //gleich auf das Verschieben verzichtet werden.
+        //Die Pruefung, ob der Frm genug Platz findet fuehrt er selbst
+        //durch, dabei wird beruecksichtigt, dass er sich moeglicherweise
+        //aufspalten kann.
+        //Wenn jedoch die FixSize eine andere ist oder Flys im Spiel sind
+        //(an der alten oder neuen Position) hat alle Prueferei keinen Sinn
+        //der Frm muss dann halt Probehalber verschoben werden (Wenn ueberhaupt
+        //etwas Platz zur Verfuegung steht).
+
+        //Die FixSize der Umgebungen in denen Cntnts herumlungern ist immer
+        //Die Breite.
+
+        //Wenn mehr als ein Blatt zurueckgegangen wurde (z.B. ueberspringen
+        //von Leerseiten), so muss in jedemfall gemoved werden - sonst wuerde,
+        //falls der Frm nicht in das Blatt passt, nicht mehr auf die
+        //dazwischenliegenden Blaetter geachtet werden.
+        BYTE nMoveAnyway = 0;
+        SwPageFrm * const pNewPage = pNewUpper->FindPageFrm();
+        SwPageFrm *pOldPage = FindPageFrm();
+
+        if ( SwFlowFrm::IsMoveBwdJump() )
+            return TRUE;
+
+        if( IsInFtn() && IsInSct() )
+        {
+            SwFtnFrm* pFtn = FindFtnFrm();
+            SwSectionFrm* pMySect = pFtn->FindSctFrm();
+            if( pMySect && pMySect->IsFtnLock() )
+            {
+                SwSectionFrm *pSect = pNewUpper->FindSctFrm();
+                while( pSect && pSect->IsInFtn() )
+                    pSect = pSect->GetUpper()->FindSctFrm();
+                ASSERT( pSect, "Escaping footnote" );
+                if( pSect != pMySect )
+                    return FALSE;
+            }
+        }
+        if( Abs(pNewUpper->Prt().Width() - GetUpper()->Prt().Width()) > 1 )
+            nMoveAnyway = 2; // Damit kommt nur noch ein _WouldFit mit Umhaengen in Frage
+        if ( (nMoveAnyway |= BwdMoveNecessary( pOldPage, Frm() )) < 3 )
+        {
+            SwTwips nSpace = 0;
+            SwRect aRect( pNewUpper->Prt() );
+            aRect.Pos() += pNewUpper->Frm().Pos();
+            const SwFrm *pPrevFrm = pNewUpper->Lower();
+            while ( pPrevFrm )
+            {
+                if( !pPrevFrm->GetNext() && !pPrevFrm->IsValid() )
+                    return TRUE;
+                aRect.Top( pPrevFrm->Frm().Bottom() );
+                pPrevFrm = pPrevFrm->GetNext();
+            }
+
+            nMoveAnyway |= BwdMoveNecessary( pNewPage, aRect);
+            if ( nMoveAnyway < 3 )
+            {
+                //Zur Verfuegung stehenden Raum berechenen.
+                nSpace = aRect.Height();
+                if ( IsInFtn() || GetAttrSet()->GetDoc()->IsBrowseMode() ||
+                     ( pNewUpper->IsInSct() && ( pNewUpper->IsSctFrm() ||
+                       ( pNewUpper->IsColBodyFrm() &&
+                         !pNewUpper->GetUpper()->GetPrev() &&
+                         !pNewUpper->GetUpper()->GetNext() ) ) ) )
+                    nSpace += pNewUpper->Grow( LONG_MAX, pHeight, TRUE );
+                if ( nSpace )
+                {
+                    //Keine Beruecksichtigung der Fussnoten die an dem Absatz
+                    //kleben, denn dies wuerde extrem unuebersichtlichen Code
+                    //beduerfen (wg. Beruecksichtung der Breiten und vor allem
+                    //der Flys, die ja wieder Einfluss auf die Fussnoten nehmen...).
+
+                    // _WouldFit kann bei gleicher Breite und _nur_ selbst verankerten Flys
+                    // befragt werden.
+                    // _WouldFit kann auch gefragt werden, wenn _nur_ fremdverankerte Flys vorliegen,
+                    // dabei ist sogar die Breite egal, da ein TestFormat in der neuen Umgebung
+                    // vorgenommen wird.
+                    return _WouldFit( nSpace, pNewUpper, nMoveAnyway == 2 );
+                }
+                //Bei einem spaltigen Bereichsfrischling kann _WouldFit kein
+                //brauchbares Ergebnis liefern, also muessen wir wirklich
+                //zurueckfliessen
+                else if( pNewUpper->IsInSct() && pNewUpper->IsColBodyFrm() &&
+                    !pNewUpper->Prt().Width() &&
+                    ( pNewUpper->GetUpper()->GetPrev() ||
+                      pNewUpper->GetUpper()->GetNext() ) )
+                    return TRUE;
+                else
+                    return FALSE; // Kein Platz, dann ist es sinnlos, zurueckzufliessen
+            }
+        }
+        return TRUE;
+    }
+    return  FALSE;
+}
+
+//------------------------------------------------------------------------
+//              Calc-Methoden
+//------------------------------------------------------------------------
+
+/*************************************************************************
+|*
+|*  SwFrm::Prepare()
+|*
+|*  Beschreibung        Bereitet den Frm auf die 'Formatierung' (MakeAll())
+|*      vor. Diese Methode dient dazu auf dem Stack Platz einzusparen,
+|*      denn zur Positionsberechnung des Frm muss sichergestellt sein, dass
+|*      die Position von Upper und Prev gueltig sind, mithin also ein
+|*      rekursiver Aufruf (Schleife waere relativ teuer, da selten notwendig).
+|*      Jeder Aufruf von MakeAll verbraucht aber ca. 500Byte Stack -
+|*      das Ende ist leicht abzusehen. _Prepare benoetigt nur wenig Stack,
+|*      deshalb solle der Rekursive Aufruf hier kein Problem sein.
+|*      Ein weiterer Vorteil ist, das eines schoenen Tages das _Prepare und
+|*      damit die Formatierung von Vorgaengern umgangen werden kann.
+|*      So kann evtl. mal 'schnell' an's Dokumentende gesprungen werden.
+|*  Ersterstellung      MA ??
+|*  Letzte Aenderung    MA 13. Dec. 93
+|*
+|*************************************************************************/
+//Zwei kleine Freundschaften werden hier zu einem Geheimbund.
+inline void PrepareLock( SwFlowFrm *pTab )
+{
+    pTab->LockJoin();
+}
+inline void PrepareUnlock( SwFlowFrm *pTab )
+{
+    pTab->UnlockJoin();
+
+}
+
+
+
+void SwFrm::PrepareMake()
+{
+    StackHack aHack;
+    if ( GetUpper() )
+    {
+        if( !GetUpper()->IsSctFrm() )
+            GetUpper()->Calc();
+        ASSERT( GetUpper(), ":-( Layoutgeruest wackelig (Upper wech)." );
+        if ( !GetUpper() )
+            return;
+
+        const BOOL bCnt = IsCntntFrm();
+        const BOOL bTab = IsTabFrm();
+        BOOL bNoSect = IsInSct();
+        BOOL bOldTabLock = FALSE, bFoll = FALSE;
+        SwFlowFrm* pThis = bCnt ? (SwCntntFrm*)this : NULL;
+
+        if ( bTab )
+        {
+            pThis = (SwTabFrm*)this;
+            bOldTabLock = ((SwTabFrm*)this)->IsJoinLocked();
+            ::PrepareLock( (SwTabFrm*)this );
+            bFoll = pThis->IsFollow();
+        }
+        else if( IsSctFrm() )
+        {
+            pThis = (SwSectionFrm*)this;
+            bFoll = pThis->IsFollow();
+            bNoSect = FALSE;
+        }
+        else if ( bCnt && TRUE == (bFoll = pThis->IsFollow()) &&
+             GetPrev() )
+        {
+            //Wenn der Master gereade ein CalcFollow ruft braucht die Kette
+            //nicht durchlaufen werden. Das spart Zeit und vermeidet Probleme.
+            if ( ((SwTxtFrm*)((SwTxtFrm*)this)->FindMaster())->IsLocked() )
+            {
+                MakeAll();
+                return;
+            }
+        }
+
+        SwFrm *pFrm = GetUpper()->Lower();
+        while ( pFrm != this )
+        {
+            ASSERT( pFrm, ":-( Layoutgeruest wackelig (this not found)." );
+            if ( !pFrm )
+                return; //Oioioioi ...
+
+            if ( !pFrm->IsValid() )
+            {
+                //Ein kleiner Eingriff der hoffentlich etwas zur Verbesserung
+                //der Stabilitaet beitraegt:
+                //Wenn ich Follow _und_ Nachbar eines Frms vor mir bin,
+                //so wuerde dieser mich beim Formatieren deleten; wie jeder
+                //leicht sehen kann waere dies eine etwas unuebersichtliche
+                //Situation die es zu vermeiden gilt.
+                if ( bFoll && pFrm->IsFlowFrm() &&
+                     (SwFlowFrm::CastFlowFrm(pFrm))->IsAnFollow( pThis ) )
+                    break;
+
+//MA: 24. Mar. 94, Calc wuerde doch nur wieder in ein _Prepare laufen und so
+//die ganze Kette nocheinmal abhuenern.
+//              pFrm->Calc();
+                pFrm->MakeAll();
+                if( IsSctFrm() && !((SwSectionFrm*)this)->GetSection() )
+                    break;
+            }
+            //Die Kette kann bei CntntFrms waehrend des durchlaufens
+            //aufgebrochen werden, deshalb muss der Nachfolger etwas
+            //umstaendlich ermittelt werden. However, irgendwann _muss_
+            //ich wieder bei mir selbst ankommen.
+            pFrm = pFrm->FindNext();
+
+            //Wenn wir in einem SectionFrm gestartet sind, koennen wir durch die
+            //MakeAll-Aufrufe in einen Section-Follow gewandert sein.
+            //FindNext liefert allerdings den SectionFrm, nicht seinen Inhalt.
+            // => wir finden uns selbst nicht mehr!
+            if( bNoSect && pFrm && pFrm->IsSctFrm() )
+            {
+                SwFrm* pCnt = ((SwSectionFrm*)pFrm)->ContainsAny();
+                if( pCnt )
+                    pFrm = pCnt;
+            }
+        }
+        ASSERT( GetUpper(), "Layoutgeruest wackelig (Upper wech II)." );
+        if ( !GetUpper() )
+            return;
+
+        if( !GetUpper()->IsSctFrm() )
+            GetUpper()->Calc();
+
+        ASSERT( GetUpper(), "Layoutgeruest wackelig (Upper wech III)." );
+
+        if ( bTab && !bOldTabLock )
+            ::PrepareUnlock( (SwTabFrm*)this );
+    }
+    MakeAll();
+}
+
+void SwFrm::OptPrepareMake()
+{
+    if ( GetUpper() )
+    {
+        GetUpper()->Calc();
+        ASSERT( GetUpper(), ":-( Layoutgeruest wackelig (Upper wech)." );
+        if ( !GetUpper() )
+            return;
+    }
+    if ( GetPrev() && !GetPrev()->IsValid() )
+        PrepareMake();
+    else
+    {
+        StackHack aHack;
+        MakeAll();
+    }
+}
+
+
+
+void SwFrm::PrepareCrsr()
+{
+    StackHack aHack;
+    if( GetUpper() && !GetUpper()->IsSctFrm() )
+    {
+        GetUpper()->PrepareCrsr();
+        GetUpper()->Calc();
+
+        ASSERT( GetUpper(), ":-( Layoutgeruest wackelig (Upper wech)." );
+        if ( !GetUpper() )
+            return;
+
+        const BOOL bCnt = IsCntntFrm();
+        const BOOL bTab = IsTabFrm();
+        BOOL bNoSect = IsInSct();
+
+        BOOL bOldTabLock = FALSE, bFoll;
+        SwFlowFrm* pThis = bCnt ? (SwCntntFrm*)this : NULL;
+
+        if ( bTab )
+        {
+            bOldTabLock = ((SwTabFrm*)this)->IsJoinLocked();
+            ::PrepareLock( (SwTabFrm*)this );
+            pThis = (SwTabFrm*)this;
+        }
+        else if( IsSctFrm() )
+        {
+            pThis = (SwSectionFrm*)this;
+            bNoSect = FALSE;
+        }
+        bFoll = pThis && pThis->IsFollow();
+
+        SwFrm *pFrm = GetUpper()->Lower();
+        while ( pFrm != this )
+        {
+            ASSERT( pFrm, ":-( Layoutgeruest wackelig (this not found)." );
+            if ( !pFrm )
+                return; //Oioioioi ...
+
+            if ( !pFrm->IsValid() )
+            {
+                //Ein kleiner Eingriff der hoffentlich etwas zur Verbesserung
+                //der Stabilitaet beitraegt:
+                //Wenn ich Follow _und_ Nachbar eines Frms vor mir bin,
+                //so wuerde dieser mich beim Formatieren deleten; wie jeder
+                //leicht sehen kann waere dies eine etwas unuebersichtliche
+                //Situation die es zu vermeiden gilt.
+                if ( bFoll && pFrm->IsFlowFrm() &&
+                     (SwFlowFrm::CastFlowFrm(pFrm))->IsAnFollow( pThis ) )
+                    break;
+
+                pFrm->MakeAll();
+            }
+            //Die Kette kann bei CntntFrms waehrend des durchlaufens
+            //aufgebrochen werden, deshalb muss der Nachfolger etwas
+            //umstaendlich ermittelt werden. However, irgendwann _muss_
+            //ich wieder bei mir selbst ankommen.
+            pFrm = pFrm->FindNext();
+            if( bNoSect && pFrm && pFrm->IsSctFrm() )
+            {
+                SwFrm* pCnt = ((SwSectionFrm*)pFrm)->ContainsAny();
+                if( pCnt )
+                    pFrm = pCnt;
+            }
+        }
+        ASSERT( GetUpper(), "Layoutgeruest wackelig (Upper wech II)." );
+        if ( !GetUpper() )
+            return;
+
+        GetUpper()->Calc();
+
+        ASSERT( GetUpper(), "Layoutgeruest wackelig (Upper wech III)." );
+
+        if ( bTab && !bOldTabLock )
+            ::PrepareUnlock( (SwTabFrm*)this );
+    }
+    Calc();
+}
+
+/*************************************************************************
+|*
+|*  SwFrm::MakePos()
+|*
+|*  Ersterstellung      MA ??
+|*  Letzte Aenderung    MA 24. May. 93
+|*
+|*************************************************************************/
+
+// Hier wird GetPrev() zurueckgegeben, allerdings werden
+// dabei leere SectionFrms ueberlesen
+SwFrm* lcl_Prev( SwFrm* pFrm, BOOL bSectPrv = TRUE )
+{
+    SwFrm* pRet = pFrm->GetPrev();
+    if( !pRet && pFrm->GetUpper() && pFrm->GetUpper()->IsSctFrm() &&
+        bSectPrv && !pFrm->IsColumnFrm() )
+        pRet = pFrm->GetUpper()->GetPrev();
+    while( pRet && pRet->IsSctFrm() &&
+           !((SwSectionFrm*)pRet)->GetSection() )
+        pRet = pRet->GetPrev();
+    return pRet;
+}
+
+SwFrm* lcl_NotHiddenPrev( SwFrm* pFrm )
+{
+    SwFrm *pRet = pFrm;
+    do
+    {
+        pRet = lcl_Prev( pRet );
+    } while ( pRet && pRet->IsTxtFrm() && ((SwTxtFrm*)pRet)->IsHiddenNow() );
+    return pRet;
+}
+
+void SwFrm::MakePos()
+{
+    if ( !bValidPos )
+    {
+        bValidPos = TRUE;
+        FASTBOOL bUseUpper = FALSE;
+        SwFrm* pPrv = lcl_Prev( this );
+        if ( pPrv && (!pPrv->IsCntntFrm() ||
+              (((SwCntntFrm*)pPrv)->GetFollow() != this)) )
+        {
+            if( !StackHack::IsLocked() && ( !IsInSct() || IsSctFrm() ) &&
+                !pPrv->IsSctFrm() && !pPrv->GetAttrSet()->GetKeep().GetValue() )
+                pPrv->Calc();   //hierbei kann der Prev verschwinden!
+            else if ( pPrv->Frm().Top() == 0 )
+                bUseUpper = TRUE;
+        }
+
+        pPrv = lcl_Prev( this, FALSE );
+        if ( !bUseUpper && pPrv )
+        {   aFrm.Pos( pPrv->Frm().Pos() );
+            aFrm.Pos().*pVARPOS += pPrv->Frm().SSize().*pVARSIZE;
+        }
+        else if ( GetUpper() )
+        {
+            // In einem spaltigen Rahmen rufen wir lieber kein Calc "von unten"
+            if( !GetUpper()->IsSctFrm() )
+                GetUpper()->Calc(); // Jetzt koennte ein Prev dazugekommen sein...
+            pPrv = lcl_Prev( this, FALSE );
+            if ( !bUseUpper && pPrv )
+            {   aFrm.Pos( pPrv->Frm().Pos() );
+                aFrm.Pos().*pVARPOS += pPrv->Frm().SSize().*pVARSIZE;
+            }
+            else
+            {
+                aFrm.Pos( GetUpper()->Frm().Pos() );
+                aFrm.Pos() += GetUpper()->Prt().Pos();
+            }
+        }
+        else
+            aFrm.Pos().X() = aFrm.Pos().Y() = 0;
+        bValidPos = TRUE;
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwPageFrm::MakeAll()
+|*
+|*  Ersterstellung      MA 23. Feb. 93
+|*  Letzte Aenderung    MA 20. Jul. 98
+|*
+|*************************************************************************/
+
+void lcl_CheckObjects( SwSortDrawObjs* pSortedObjs, SwFrm* pFrm, long& rBot )
+{
+    //Und dann kann es natuerlich noch Absatzgebundene
+    //Rahmen geben, die unterhalb ihres Absatzes stehen.
+    long nMax = 0;
+    for ( USHORT i = 0; i < pSortedObjs->Count(); ++i )
+    {
+        SdrObject *pObj = (*pSortedObjs)[i];
+        long nTmp = 0;
+        if ( pObj->IsWriterFlyFrame() )
+        {
+            SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+            if( pFly->Frm().Top() != WEIT_WECH &&
+                ( pFrm->IsPageFrm() ? pFly->IsFlyLayFrm() :
+                  ( pFly->IsFlyAtCntFrm() &&
+                    ( pFrm->IsBodyFrm() ? pFly->GetAnchor()->IsInDocBody() :
+                                          pFly->GetAnchor()->IsInFtn() ) ) ) )
+            {
+                nTmp = pFly->Frm().Bottom();
+            }
+        }
+        else
+            nTmp = pObj->GetBoundRect().Bottom();
+        nMax = Max( nTmp, nMax );
+    }
+    ++nMax; //Unterkante vs. Hoehe!
+    rBot = Max( rBot, nMax );
+}
+
+
+void SwPageFrm::MakeAll()
+{
+    PROTOCOL_ENTER( this, PROT_MAKEALL, 0, 0 )
+
+    const SwRect aOldRect( Frm() );     //Anpassung der Root-Groesse
+    const SwLayNotify aNotify( this );  //uebernimmt im DTor die Benachrichtigung
+    SwBorderAttrAccess *pAccess = 0;
+    const SwBorderAttrs*pAttrs = 0;
+
+    while ( !bValidPos || !bValidSize || !bValidPrtArea )
+    {
+        if ( !bValidPos )
+        {
+            MakePos();
+            if ( GetPrev() &&  !((SwPageFrm*)GetPrev())->IsEmptyPage() )
+                aFrm.Pos().Y() += DOCUMENTBORDER/2;
+        }
+
+        if ( !bValidSize || !bValidPrtArea )
+        {
+            if ( IsEmptyPage() )
+            {
+                Frm().Width( 0 );  Prt().Width( 0 );
+                Frm().Height( 0 ); Prt().Height( 0 );
+                Prt().Left( 0 );   Prt().Top( 0 );
+                bValidSize = bValidPrtArea = TRUE;
+            }
+            else
+            {
+                if ( !pAccess )
+                {
+                    pAccess = new SwBorderAttrAccess( SwFrm::GetCache(), this );
+                    pAttrs = pAccess->Get();
+                }
+                //Bei der BrowseView gelten feste Einstellungen.
+                ViewShell *pSh = GetShell();
+                if ( pSh && GetFmt()->GetDoc()->IsBrowseMode() )
+                {
+                    const Size aBorder = pSh->GetOut()->PixelToLogic( pSh->GetBrowseBorder() );
+                    const long nTop    = pAttrs->CalcTopLine()   + aBorder.Height();
+                    const long nBottom = pAttrs->CalcBottomLine()+ aBorder.Height();
+
+                    long nWidth = GetUpper() ? ((SwRootFrm*)GetUpper())->
+                        GetBrowseWidth() + 2 * aBorder.Width() : 0;
+//                  if ( !pSh->VisArea().Width() )
+//                      nWidth = Max( nWidth, 5000L );
+                    if ( nWidth < pSh->VisArea().Width() )
+                        nWidth = pSh->VisArea().Width();
+                    nWidth = Max( nWidth, 2L * aBorder.Width() + 4L*MM50 );
+                    Frm().Width( nWidth );
+
+                    SwLayoutFrm *pBody = FindBodyCont();
+                    if ( pBody && pBody->Lower() && pBody->Lower()->IsColumnFrm() )
+                    {
+                        //Fuer Spalten gilt eine feste Hoehe
+                        Frm().Height( pAttrs->GetSize().Height() );
+                    }
+                    else
+                    {
+                        //Fuer Seiten ohne Spalten bestimmt der Inhalt die
+                        //Groesse.
+                        long nBot = Frm().Top() + nTop;
+                        SwFrm *pFrm = Lower();
+                        while ( pFrm )
+                        {
+                            long nTmp = 0;
+                            SwFrm *pCnt = ((SwLayoutFrm*)pFrm)->ContainsAny();
+                            while ( pCnt && (pCnt->GetUpper() == pFrm ||
+                                             ((SwLayoutFrm*)pFrm)->IsAnLower( pCnt )))
+                            {
+                                nTmp += pCnt->Frm().Height();
+                                if( pCnt->IsTxtFrm() &&
+                                    ((SwTxtFrm*)pCnt)->IsUndersized() )
+                                    nTmp += ((SwTxtFrm*)pCnt)->GetParHeight()
+                                            - pCnt->Prt().Height();
+                                else if( pCnt->IsSctFrm() &&
+                                         ((SwSectionFrm*)pCnt)->IsUndersized() )
+                                    nTmp += ((SwSectionFrm*)pCnt)->Undersize();
+                                pCnt = pCnt->FindNext();
+                            }
+                            nTmp += pFrm->Frm().Height() - pFrm->Prt().Height();
+                            if ( !pFrm->IsBodyFrm() )
+                                nTmp = Min( nTmp, pFrm->Frm().Height() );
+                            nBot += nTmp;
+                            // Hier werden die absatzgebundenen Objekte ueberprueft,
+                            // ob sie ueber den Body/FtnCont hinausragen.
+                            if( pSortedObjs && !pFrm->IsHeaderFrm() &&
+                                !pFrm->IsFooterFrm() )
+                                lcl_CheckObjects( pSortedObjs, pFrm, nBot );
+                            pFrm = pFrm->GetNext();
+                        }
+                        nBot += nBottom;
+                        //Und die Seitengebundenen
+                        if ( pSortedObjs )
+                            lcl_CheckObjects( pSortedObjs, this, nBot );
+                        nBot -= Frm().Top();
+                        if ( !GetPrev() )
+                            nBot = Max( nBot, pSh->VisArea().Height() );
+                        Frm().Height( nBot );
+                    }
+                    Prt().Left ( pAttrs->CalcLeftLine() + aBorder.Width() );
+                    Prt().Top  ( nTop );
+                    Prt().Width( Frm().Width() - ( Prt().Left()
+                        + pAttrs->CalcRightLine() + aBorder.Width() ) );
+                    Prt().Height( Frm().Height() - (nTop + nBottom) );
+                    bValidSize = bValidPrtArea = TRUE;
+                }
+                else
+                {   //FixSize einstellen, bei Seiten nicht vom Upper sondern vom
+                    //Attribut vorgegeben.
+                    Frm().SSize( pAttrs->GetSize() );
+                    Format( pAttrs );
+                }
+            }
+        }
+    } //while ( !bValidPos || !bValidSize || !bValidPrtArea )
+    delete pAccess;
+    if ( Frm() != aOldRect )
+        AdjustRootSize( CHG_CHGPAGE, &aOldRect );
+
+#ifndef PRODUCT
+    //Der Upper (Root) muss mindestens so breit
+    //sein, dass er die breiteste Seite aufnehmen kann.
+    if ( GetUpper() )
+    {   if ( bVarHeight )
+        {   ASSERT( GetUpper()->Prt().Width() >= aFrm.Width(),
+                    "Rootsize" );
+        }
+        else
+        {   ASSERT( GetUpper()->Prt().Height() >= aFrm.Height(),
+                    "Rootsize" );
+        }
+    }
+#endif
+}
+
+/*************************************************************************
+|*
+|*  SwLayoutFrm::MakeAll()
+|*
+|*  Ersterstellung      MA ??
+|*  Letzte Aenderung    MA 28. Nov. 95
+|*
+|*************************************************************************/
+
+
+void SwLayoutFrm::MakeAll()
+{
+    PROTOCOL_ENTER( this, PROT_MAKEALL, 0, 0 )
+
+        //uebernimmt im DTor die Benachrichtigung
+    const SwLayNotify aNotify( this );
+    const SzPtr pFix = pFIXSIZE;
+
+    SwBorderAttrAccess *pAccess = 0;
+    const SwBorderAttrs*pAttrs = 0;
+
+    while ( !bValidPos || !bValidSize || !bValidPrtArea )
+    {
+        if ( !bValidPos )
+            MakePos();
+
+        if ( GetUpper() )
+        {
+            if ( !bValidSize )
+            {
+                //FixSize einstellen, die VarSize wird von Format() nach
+                //Berechnung der PrtArea eingestellt.
+                aFrm.SSize().*pFix = GetUpper()->Prt().SSize().*pFix;
+                bValidPrtArea = FALSE;
+            }
+            else
+            {   //nicht ueber die auessere Kante des Upper hinausragen.
+                const SwTwips nDeadLine = GetUpper()->Frm().Pos().*pVARPOS +
+                    (bVarHeight ?
+                        GetUpper()->Prt().Top() + GetUpper()->Prt().Height() :
+                        GetUpper()->Prt().Left() + GetUpper()->Prt().Width());
+                const SwTwips nBot = bVarHeight ?
+                    Frm().Top() + Frm().Height() : Frm().Left() + Frm().Width();
+                if ( nBot > nDeadLine )
+                    bValidSize = FALSE;
+            }
+        }
+        if ( !bValidSize || !bValidPrtArea )
+        {
+            if ( !pAccess )
+            {
+                pAccess = new SwBorderAttrAccess( SwFrm::GetCache(), this );
+                pAttrs  = pAccess->Get();
+            }
+            Format( pAttrs );
+        }
+    } //while ( !bValidPos || !bValidSize || !bValidPrtArea )
+    if ( pAccess )
+        delete pAccess;
+}
+
+/*************************************************************************
+|*
+|*  SwCntntFrm::MakePrtArea()
+|*
+|*  Ersterstellung      MA 17. Nov. 92
+|*  Letzte Aenderung    MA 03. Mar. 96
+|*
+|*************************************************************************/
+
+
+BOOL SwCntntFrm::MakePrtArea( const SwBorderAttrs &rAttrs )
+{
+    BOOL bSizeChgd = FALSE;
+
+    if ( !bValidPrtArea )
+    {
+        bValidPrtArea = TRUE;
+
+        const FASTBOOL bTxtFrm = IsTxtFrm();
+        SwTwips nUpper = 0;
+        if ( bTxtFrm && ((SwTxtFrm*)this)->IsHiddenNow() )
+        {
+            if ( Prt().Height() )
+                ((SwTxtFrm*)this)->HideHidden();
+            Prt().Pos().X() = Prt().Pos().Y() = 0;
+            Prt().Width( Frm().Width() );
+            Prt().Height( 0 );
+            nUpper = -Frm().Height();
+        }
+        else
+        {
+            //Vereinfachung: CntntFrms sind immer in der Hoehe Variabel!
+
+            //An der FixSize gibt der umgebende Frame die Groesse vor, die
+            //Raender werden einfach abgezogen.
+            const long nLeft = rAttrs.CalcLeft( this );
+            Prt().Width( Frm().Width() - (nLeft + rAttrs.CalcRight()) );
+            Prt().Pos().X() = nLeft;
+
+            ViewShell *pSh = GetShell();
+            if ( pSh && pSh->VisArea().Width() &&
+                 GetUpper()->IsPageBodyFrm() &&  // nicht dagegen bei BodyFrms in Columns
+                 pSh->GetDoc()->IsBrowseMode() )
+            {
+                //Nicht ueber die Kante des sichbaren Bereiches hinausragen.
+                //Die Seite kann breiter sein, weil es Objekte mit "ueberbreite"
+                //geben kann (RootFrm::ImplCalcBrowseWidth())
+                long nMinWidth = 0;
+
+                for (USHORT i = 0; GetDrawObjs() && i < GetDrawObjs()->Count();++i)
+                {
+                    SdrObject *pObj = (*GetDrawObjs())[i];
+                    SwFrmFmt *pFmt = ::FindFrmFmt( pObj );
+                    const FASTBOOL bFly = pObj->IsWriterFlyFrame();
+                    if ( bFly &&
+                         WEIT_WECH == ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->Frm().Width()||
+                         pFmt->GetFrmSize().GetWidthPercent() )
+                        continue;
+
+                    if ( FLY_IN_CNTNT == pFmt->GetAnchor().GetAnchorId() )
+                        nMinWidth = Max( nMinWidth,
+                                      bFly ? pFmt->GetFrmSize().GetWidth()
+                                           : pObj->GetBoundRect().GetWidth() );
+                }
+
+                const Size aBorder = pSh->GetOut()->PixelToLogic( pSh->GetBrowseBorder() );
+                long nWidth = pSh->VisArea().Width() - 2 * aBorder.Width();
+                nWidth -= Prt().Left();
+                nWidth -= rAttrs.CalcRightLine();
+                nWidth = Max( nMinWidth, nWidth );
+                Prt().Width( Min( nWidth, Prt().Width() ) );
+            }
+
+            if ( Prt().Width() <= MINLAY )
+            {
+                //Die PrtArea sollte schon wenigstens MINLAY breit sein, passend
+                //zu den Minimalwerten des UI
+                Prt().Width( Min( long(MINLAY), Frm().Width() ) );
+                if ( (Prt().Pos().X() + Prt().Width()) > Frm().Width() )
+                    Prt().Pos().X() = Frm().Width() - Prt().Width();
+            }
+
+            //Fuer die VarSize gelten folgende Regeln:
+            //1. Der erste einer Kette hat keinen Rand nach oben
+            //2. Nach unten gibt es nie einen Rand
+            //3. Der Rand nach oben ist das Maximum aus dem Abstand des
+            //   Prev nach unten und dem eigenen Abstand nach oben.
+            //Die drei Regeln werden auf die Berechnung der Freiraeume, die von
+            //UL- bzw. LRSpace vorgegeben werden, angewand. Es gibt in alle
+            //Richtungen jedoch ggf. trotzdem einen Abstand; dieser wird durch
+            //Umrandung und/oder Schatten vorgegeben.
+            //4. Der Abstand fuer TextFrms entspricht mindestens dem Durchschuss
+
+            nUpper = CalcUpperSpace( &rAttrs, NULL );
+            Prt().Pos().Y() = nUpper;
+
+            nUpper += rAttrs.GetBottomLine( this );
+            nUpper -= Frm().Height() - Prt().Height();
+        }
+        //Wenn Unterschiede zwischen Alter und neuer Groesse,
+        //Grow() oder Shrink() rufen
+        if ( nUpper )
+        {
+            if ( nUpper > 0 )
+                GrowFrm( nUpper, pHeight );
+            else
+                ShrinkFrm( -nUpper, pHeight );
+            bSizeChgd = TRUE;
+        }
+    }
+    return bSizeChgd;
+}
+
+/*************************************************************************
+|*
+|*  SwCntntFrm::MakeAll()
+|*
+|*  Ersterstellung      MA ??
+|*  Letzte Aenderung    MA 16. Dec. 96
+|*
+|*************************************************************************/
+
+inline void ValidateSz( SwFrm *pFrm )
+{
+    if ( pFrm )
+    {
+        pFrm->bValidSize = TRUE;
+        pFrm->bValidPrtArea = TRUE;
+    }
+}
+
+
+void SwCntntFrm::MakeAll()
+{
+    ASSERT( GetUpper(), "keinen Upper?" );
+    ASSERT( IsTxtFrm(), "MakeAll(), NoTxt" );
+
+    if ( !IsFollow() && StackHack::IsLocked() )
+        return;
+
+    if ( IsJoinLocked() )
+        return;
+
+    StackHack aHack;
+
+    if ( ((SwTxtFrm*)this)->IsLocked() )
+    {
+        ASSERT( FALSE, "Format fuer gelockten TxtFrm." );
+        return;
+    }
+
+    LockJoin();
+    PROTOCOL_ENTER( this, PROT_MAKEALL, 0, 0 )
+
+    //uebernimmt im DTor die Benachrichtigung
+    SwCntntNotify *pNotify = new SwCntntNotify( this );
+
+    BOOL    bMakePage   = TRUE;     //solange TRUE kann eine neue Seite
+                                    //angelegt werden (genau einmal)
+    BOOL    bMovedBwd   = FALSE;    //Wird TRUE wenn der Frame zurueckfliesst
+    BOOL    bMovedFwd   = FALSE;    //solange FALSE kann der Frm zurueck-
+                                    //fliessen (solange, bis er einmal
+                                    //vorwaerts ge'moved wurde).
+    BOOL    bFormatted  = FALSE;    //Fuer die Witwen und Waisen Regelung
+                                    //wird der letzte CntntFrm einer Kette
+                                    //u.U. zum Formatieren angeregt, dies
+                                    //braucht nur einmal zu passieren.
+                                    //Immer wenn der Frm gemoved wird muss
+                                    //das Flag zurueckgesetzt werden.
+    BOOL    bMustFit    = FALSE;    //Wenn einmal die Notbremse gezogen wurde,
+                                    //werden keine anderen Prepares mehr
+                                    //abgesetzt.
+    BOOL    bFitPromise = FALSE;    //Wenn ein Absatz nicht passte, mit WouldFit
+                                    //aber verspricht, dass er sich passend
+                                    //einstellt wird dieses Flag gesetzt.
+                                    //Wenn er dann sein Versprechen nicht haelt,
+                                    //kann kontrolliert verfahren werden.
+    BOOL bMoveable;
+    const BOOL bFly = IsInFly();
+    const BOOL bTab = IsInTab();
+    const BOOL bFtn = IsInFtn();
+    const BOOL bSct = IsInSct();
+
+    Point aOldFrmPos;               //Damit bei Turnarounds jew. mit der
+    Point aOldPrtPos;               //letzten Pos verglichen und geprueft
+                                    //werden kann, ob ein Prepare sinnvoll ist.
+    long  nKeepBottom = Frm().Bottom(); //Um beim Keep den naechsten sinnvoll
+                                        //anstossen zu koennen.
+
+    SwBorderAttrAccess aAccess( SwFrm::GetCache(), this );
+    const SwBorderAttrs &rAttrs = *aAccess.Get();
+
+    const BOOL bKeep = IsKeep( rAttrs );
+
+    SwSaveFtnHeight *pSaveFtn = 0;
+    if ( bFtn )
+    {
+        SwFtnFrm *pFtn = FindFtnFrm();
+        SwSectionFrm* pSct = pFtn->FindSctFrm();
+        if ( !((SwTxtFrm*)pFtn->GetRef())->IsLocked() )
+        {
+            SwFtnBossFrm* pBoss = pFtn->GetRef()->FindFtnBossFrm(
+                                    pFtn->GetAttr()->GetFtn().IsEndNote() );
+            if( !pSct || pSct->IsColLocked() || !pSct->Growable() )
+                pSaveFtn = new SwSaveFtnHeight( pBoss,
+                    ((SwTxtFrm*)pFtn->GetRef())->GetFtnLine( pFtn->GetAttr(),
+                                                   pFtn->IsBackMoveLocked() ) );
+        }
+    }
+
+    //Wenn ein Follow neben seinem Master steht und nicht passt, kann er
+    //gleich verschoben werden.
+    if( lcl_Prev( this ) && ((SwTxtFrm*)this)->IsFollow() && IsMoveable() )
+    {
+        bMovedFwd = TRUE;
+        MoveFwd( bMakePage, FALSE );
+    }
+
+    while ( !bValidPos || !bValidSize || !bValidPrtArea )
+    {
+        if ( TRUE == (bMoveable = IsMoveable()) )
+        {
+            SwFrm *pPre = GetIndPrev();
+            if ( CheckMoveFwd( bMakePage, bKeep, bMovedBwd ) )
+            {
+                bMovedFwd = TRUE;
+                if ( bMovedBwd )
+                {
+                    //Beim zurueckfliessen wurde der Upper angeregt sich
+                    //vollstaendig zu Painten, dass koennen wir uns jetzt
+                    //nach dem hin und her fliessen sparen.
+                    GetUpper()->ResetCompletePaint();
+                    //Der Vorgaenger wurde Invalidiert, das ist jetzt auch obsolete.
+                    ASSERT( pPre, "missing old Prev" );
+                    if( !pPre->IsSctFrm() )
+                        ::ValidateSz( pPre );
+                }
+                bMoveable = IsMoveable();
+            }
+        }
+
+
+        aOldFrmPos = Frm().Pos();
+        aOldPrtPos = Prt().Pos();
+
+        if ( !bValidPos )
+            MakePos();
+
+        //FixSize einstellen, die VarSize wird von Format() justiert.
+        if ( !bValidSize )
+            Frm().Width( GetUpper()->Prt().Width() );
+
+        if ( !bValidPrtArea )
+        {
+            const long nWidth = Prt().Width();
+            MakePrtArea( rAttrs );
+            if ( nWidth != Prt().Width() )
+                Prepare( PREP_FIXSIZE_CHG );
+        }
+
+        if ( aOldFrmPos != Frm().Pos() )//Erst nach Berechnung von Breite und PrtArea,
+            CalcFlys( TRUE );           //sonst droht mehrfache Berechnung!
+
+        //Damit die Witwen- und Waisen-Regelung eine Change bekommt muss der
+        //CntntFrm benachrichtigt werden.
+        //Kriterium:
+        //- Er muss Moveable sein (sonst mach das Spalten keinen Sinn.)
+        //- Er muss mit der Unterkante der PrtArea des Upper ueberlappen.
+        if ( !bMustFit )
+        {
+            BOOL bWidow = TRUE;
+            const SwTwips nDeadLine = GetUpper()->Prt().Bottom() +
+                                      GetUpper()->Frm().Top();
+            if ( bMoveable && !bFormatted &&
+                 ((Frm().Top() < nDeadLine && Frm().Bottom() > nDeadLine) ||
+                  GetFollow()) )
+            {
+                Prepare( PREP_WIDOWS_ORPHANS, 0, FALSE );
+                bValidSize = bWidow = FALSE;
+            }
+            if ( (Frm().Pos() != aOldFrmPos) || (Prt().Pos() != aOldPrtPos) )
+            {
+                // In diesem Prepare erfolgt ggf. ein _InvalidateSize().
+                // bValidSize wird FALSE und das Format() wird gerufen.
+                Prepare( PREP_POS_CHGD, (const void*)&bFormatted, FALSE );
+                if ( bWidow && GetFollow() )
+                {   Prepare( PREP_WIDOWS_ORPHANS, 0, FALSE );
+                    bValidSize = FALSE;
+                }
+            }
+        }
+        if ( !bValidSize )
+        {   bValidSize = bFormatted = TRUE;
+            Format();
+        }
+        //Wenn ich der erste einer Kette bin koennte ich mal sehen ob
+        //ich zurueckfliessen kann (wenn ich mich ueberhaupt bewegen soll).
+        //Damit es keine Oszillation gibt, darf ich nicht gerade vorwaerts
+        //geflossen sein.
+        BOOL bDummy;
+        if ( !lcl_Prev( this ) && !bMovedFwd && (bMoveable || (bFly && !bTab)) &&
+             (!bFtn || !GetUpper()->FindFtnFrm()->GetPrev()) && MoveBwd( bDummy ))
+        {
+            bMovedBwd = TRUE;
+            bFormatted = FALSE;
+            if ( bKeep )
+            {
+                if( CheckMoveFwd( bMakePage, FALSE, bMovedBwd ) )
+                {
+                    bMovedFwd = TRUE;
+                    bMoveable = IsMoveable();
+                }
+                const Point aOldFrmPos( Frm().Pos() );
+                MakePos();
+                if ( aOldFrmPos != Frm().Pos() )
+                {
+                    CalcFlys( TRUE );
+                    Prepare( PREP_POS_CHGD, (const void*)&bFormatted, FALSE );
+                    if ( !bValidSize )
+                    {
+                        Frm().Width( GetUpper()->Prt().Width() );
+                        if ( !bValidPrtArea )
+                        {
+                            const long nWidth = Prt().Width();
+                            MakePrtArea( rAttrs );
+                            if ( nWidth != Prt().Width() )
+                                Prepare( PREP_FIXSIZE_CHG, 0, FALSE );
+                        }
+                        if( GetFollow() )
+                            Prepare( PREP_WIDOWS_ORPHANS, 0, FALSE );
+                        bValidSize = bFormatted = TRUE;
+                        Format();
+                    }
+                }
+
+                SwFrm *pNxt = FindNext();
+                while( pNxt && pNxt->IsSctFrm() )
+                {   // Leere Bereiche auslassen, in die anderen hinein
+                    if( ((SwSectionFrm*)pNxt)->GetSection() )
+                    {
+                        SwFrm* pTmp = ((SwSectionFrm*)pNxt)->ContainsAny();
+                        if( pTmp )
+                        {
+                            pNxt = pTmp;
+                            break;
+                        }
+                    }
+                    pNxt = pNxt->FindNext();
+                }
+                if ( pNxt )
+                {
+                    pNxt->Calc();
+                    if( bValidPos && !GetIndNext() )
+                    {
+                        SwSectionFrm *pSct = FindSctFrm();
+                        if( pSct && !pSct->GetValidSizeFlag() )
+                        {
+                            SwSectionFrm* pNxtSct = pNxt->FindSctFrm();
+                            if( pNxtSct && pSct->IsAnFollow( pNxtSct ) )
+                                bValidPos = FALSE;
+                        }
+                        else
+                            bValidPos = FALSE;
+                    }
+                }
+            }
+        }
+
+        //Der TxtFrm Validiert sich bei Fussnoten ggf. selbst, dass kann leicht
+        //dazu fuehren, dass seine Position obwohl unrichtig valide ist.
+        if ( bValidPos )
+        {
+            if ( bFtn )
+            {   bValidPos = FALSE;
+                MakePos();
+                aOldFrmPos = Frm().Pos();
+                aOldPrtPos = Prt().Pos();
+            }
+        }
+
+        //Wieder ein Wert ungueltig? - dann nochmal das ganze...
+        if ( !bValidPos || !bValidSize || !bValidPrtArea )
+            continue;
+
+        //Fertig?
+        // Achtung, wg. Hoehe==0, ist es besser statt Bottom() Top()+Height() zu nehmen
+        // (kommt bei Undersized TxFrms an der Unterkante eines spaltigen Bereichs vor)
+        if ( GetUpper()->Prt().Top()+GetUpper()->Prt().Height()+GetUpper()->Frm().Top() >=
+             Frm().Top()+Frm().Height() )
+        {
+            if ( bKeep )
+            {
+                //Wir sorgen dafuer, dass der Nachfolger gleich mit formatiert
+                //wird. Dadurch halten wir das Heft in der Hand, bis wirklich
+                //(fast) alles stabil ist. So vermeiden wir Endlosschleifen,
+                //die durch staendig wiederholte Versuche entstehen.
+                //Das bMoveFwdInvalid ist fuer #38407# notwendig. War urspruenglich
+                //in flowfrm.cxx rev 1.38 behoben, das unterbrach aber obiges
+                //Schema und spielte lieber Tuerme von Hanoi (#43669#).
+                SwFrm *pNxt = FindNext();
+                // Bei Bereichen nehmen wir lieber den Inhalt, denn nur
+                // dieser kann ggf. die Seite wechseln
+                while( pNxt && pNxt->IsSctFrm() )
+                {
+                    if( ((SwSectionFrm*)pNxt)->GetSection() )
+                    {
+                        pNxt = ((SwSectionFrm*)pNxt)->ContainsAny();
+                        break;
+                    }
+                    pNxt = pNxt->FindNext();
+                }
+                if ( pNxt )
+                {
+                    const FASTBOOL bMoveFwdInvalid = 0 != GetIndNext();
+                    const FASTBOOL bNxtNew = !pNxt->Prt().Height() &&
+                       (!pNxt->IsTxtFrm() || !((SwTxtFrm*)pNxt)->IsHiddenNow());
+                    nKeepBottom = Frm().Bottom();
+                    pNxt->Calc();
+                    if ( !bMovedBwd &&
+                         ((bMoveFwdInvalid && !GetIndNext()) ||
+                          bNxtNew) )
+                        bMovedFwd = FALSE;
+                }
+            }
+            continue;
+        }
+
+        //Ich passe nicht mehr in meinen Uebergeordneten, also ist es jetzt
+        //an der Zeit moeglichst konstruktive Veranderungen vorzunehmen
+
+        //Wenn ich den uebergeordneten Frm nicht verlassen darf, habe
+        //ich ein Problem; Frei nach Artur Dent tun wir das einzige das man
+        //mit einen nicht loesbaren Problem tun kann: wir ignorieren es - und
+        //zwar mit aller Kraft.
+        if ( !bMoveable || IsUndersized() )
+        {
+            if( !bMoveable && IsInTab() )
+            {
+                long nDiff = Frm().Top()+Frm().Height() -GetUpper()->Prt().Top()
+                        -GetUpper()->Prt().Height()-GetUpper()->Frm().Top();
+                long nReal = Grow( nDiff, pHeight );
+                if( nReal )
+                    continue;
+            }
+            break;
+        }
+
+        //Wenn ich nun ueberhaupt ganz und garnicht in meinen Upper passe
+        //so kann die Situation vielleicht doch noch durch Aufbrechen
+        //aufgeklart werden. Diese Situation tritt bei einem frisch
+        //erzeugten Follow auf, der zwar auf die Folgeseite geschoben wurde
+        //aber selbst noch zu gross fuer diese ist; also wiederum
+        //aufgespalten werden muss.
+        //Wenn ich nicht passe und nicht Spaltbar (WouldFit()) bin, so schicke
+        //ich meinem TxtFrmanteil die Nachricht, dass eben falls moeglich
+        //trotz des Attributes 'nicht aufspalten' aufgespalten werden muss.
+        BOOL bMoveOrFit = FALSE;
+        BOOL bDontMoveMe = !GetIndPrev();
+        if( bDontMoveMe && IsInSct() )
+        {
+            SwFtnBossFrm* pBoss = FindFtnBossFrm();
+            bDontMoveMe = !pBoss->IsInSct() ||
+                          ( !pBoss->Lower()->GetNext() && !pBoss->GetPrev() );
+        }
+
+        if ( bDontMoveMe && Frm().Height() > GetUpper()->Prt().Height() )
+        {
+#ifdef USED
+            // Wozu mag dies gut gewesen sein?
+            // Wurde am 24. Jan 94 mit dem Kommentar "Diverse Ftn Bugs." eingecheckt.
+
+            //Koennte es sein, dass der Upper nicht so recht angepasst wurde?
+            if ( bFtn )
+            {
+                GetUpper()->_InvalidateSize();
+                GetUpper()->Calc();
+                if ( !bValidPos )
+                {
+                    MakePos();
+                    aOldFrmPos = Frm().Pos();
+                    aOldPrtPos = Prt().Pos();
+                }
+            }
+#endif
+            if ( !bFitPromise ) //Wer einmal luegt...
+            {
+                // In WouldFit kann wird der obere Absatzabstand _nicht_
+                // beruecksichtigt werden, da er nicht bei jedem Aufruf
+                // von WouldFit auf die richtige Umgebung bezieht. An dieser
+                // Stelle allerdings stimmt er, deshalb ziehen wir ihn schon
+                // mal von der zur Verfuegung stehenden Hoehe ab.
+                SwTwips nTmp = GetUpper()->Prt().Height() - Prt().Top();
+                BOOL bSplit = !GetIndPrev();
+                if ( nTmp > 0 && WouldFit( nTmp, bSplit ) )
+                {
+                    Prepare( PREP_WIDOWS_ORPHANS, 0, FALSE );
+                    bValidSize = FALSE;
+                    bFitPromise = TRUE;
+                    continue;
+                }
+                /* -----------------19.02.99 12:58-------------------
+                 * Frueher wurde in Rahmen und Bereichen niemals versucht,
+                 * durch bMoveOrFit den TxtFrm unter Verzicht auf seine
+                 * Attribute (Widows,Keep) doch noch passend zu bekommen.
+                 * Dies haette zumindest bei spaltigen Rahmen versucht
+                 * werden muessen, spaetestens bei verketteten Rahmen und
+                 * in Bereichen muss es versucht werden.
+                 * Ausnahme: Wenn wir im FormatWidthCols stehen, duerfen die
+                 * Attribute nicht ausser Acht gelassen werden.
+                 * --------------------------------------------------*/
+                else if ( !bFtn && bMoveable &&
+                      ( !bFly || !FindFlyFrm()->IsColLocked() ) &&
+                      ( !bSct || !FindSctFrm()->IsColLocked() ) )
+                    bMoveOrFit = TRUE;
+            }
+#ifndef PRODUCT
+            else
+            {
+                ASSERT( FALSE, "+TxtFrm hat WouldFit-Versprechen nicht eingehalten." );
+            }
+#endif
+        }
+
+        //Mal sehen ob ich irgenwo Platz finde...
+        //Benachbarte Fussnoten werden in _MoveFtnCntFwd 'vorgeschoben'
+        SwFrm *pPre = GetIndPrev();
+        SwFrm *pOldUp = GetUpper();
+
+/* MA 13. Oct. 98: Was soll das denn sein!?
+ * AMA 14. Dec 98: Wenn ein spaltiger Bereich keinen Platz mehr fuer seinen ersten ContentFrm
+ *      bietet, so soll dieser nicht nur in die naechste Spalte, sondern ggf. bis zur naechsten
+ *      Seite wandern und dort einen Section-Follow erzeugen.
+ */
+        if( IsInSct() && bMovedFwd && bMakePage && pOldUp->IsColBodyFrm() &&
+            pOldUp->GetUpper()->GetUpper()->IsSctFrm() &&
+            ( pPre || pOldUp->GetUpper()->GetPrev() ) &&
+            ((SwSectionFrm*)pOldUp->GetUpper()->GetUpper())->MoveAllowed(this) )
+            bMovedFwd = FALSE;
+
+        if ( !bMovedFwd && !MoveFwd( bMakePage, FALSE ) )
+            bMakePage = FALSE;
+        bMovedFwd = TRUE;
+        bFormatted = FALSE;
+        if ( bMoveOrFit && GetUpper() == pOldUp )
+        {
+            Prepare( PREP_MUST_FIT, 0, FALSE );
+            bValidSize = FALSE;
+            bMustFit = TRUE;
+            continue;
+        }
+        if ( bMovedBwd && GetUpper() )
+        {   //Unuetz gewordene Invalidierungen zuruecknehmen.
+            GetUpper()->ResetCompletePaint();
+            if( pPre && !pPre->IsSctFrm() )
+                ::ValidateSz( pPre );
+        }
+
+        if ( bValidPos && bValidSize && bValidPrtArea && GetDrawObjs() &&
+             Prt().SSize() != pNotify->Prt().SSize() )
+        {
+            //Wenn sich meine PrtArea in der Groesse verandert hat, so ist die
+            //automatische Ausrichtung der Flys zum Teufel. Diese muss
+            //Waehrend der Fahrt korrigiert werden, weil sie mich ggf. wiederum
+            //invalidiert.
+            SwDrawObjs &rObjs = *GetDrawObjs();
+            for ( USHORT i = 0; i < rObjs.Count(); ++i )
+            {
+                SdrObject *pO = rObjs[i];
+                if ( pO->IsWriterFlyFrame() )
+                    ((SwVirtFlyDrawObj*)pO)->GetFlyFrm()->InvalidatePos();
+            }
+        }
+
+    } //while ( !bValidPos || !bValidSize || !bValidPrtArea )
+
+    if ( pSaveFtn )
+        delete pSaveFtn;
+
+    UnlockJoin();
+    if ( bMovedFwd || bMovedBwd )
+        pNotify->SetInvaKeep();
+    delete pNotify;
+}
+
+/*************************************************************************
+|*
+|*  SwCntntFrm::_WouldFit()
+|*
+|*  Ersterstellung      MA 28. Feb. 95
+|*  Letzte Aenderung    AMA 15. Feb. 99
+|*
+|*************************************************************************/
+
+
+
+
+void MakeNxt( SwFrm *pFrm, SwFrm *pNxt )
+{
+    //fix(25455): Validieren, sonst kommt es zu einer Rekursion.
+    //Der erste Versuch, der Abbruch mit pFrm = 0 wenn !Valid,
+    //fuehrt leider zu dem Problem, dass das Keep dann u.U. nicht mehr
+    //korrekt beachtet wird (27417)
+    const BOOL bOldPos = pFrm->GetValidPosFlag();
+    const BOOL bOldSz  = pFrm->GetValidSizeFlag();
+    const BOOL bOldPrt = pFrm->GetValidPrtAreaFlag();
+    pFrm->bValidPos = pFrm->bValidPrtArea = pFrm->bValidSize = TRUE;
+
+    //fix(29272): Nicht MakeAll rufen, dort wird evtl. pFrm wieder invalidert
+    //und kommt rekursiv wieder herein.
+    if ( pNxt->IsCntntFrm() )
+    {
+        SwCntntNotify aNotify( (SwCntntFrm*)pNxt );
+        SwBorderAttrAccess aAccess( SwFrm::GetCache(), pNxt );
+        const SwBorderAttrs &rAttrs = *aAccess.Get();
+        if ( !pNxt->GetValidSizeFlag() )
+            pNxt->Frm().Width( pNxt->GetUpper()->Prt().Width() );
+        ((SwCntntFrm*)pNxt)->MakePrtArea( rAttrs );
+        pNxt->Format( &rAttrs );
+    }
+    else
+    {
+        SwLayNotify aNotify( (SwLayoutFrm*)pNxt );
+        SwBorderAttrAccess aAccess( SwFrm::GetCache(), pNxt );
+        const SwBorderAttrs &rAttrs = *aAccess.Get();
+        if ( !pNxt->GetValidSizeFlag() )
+            pNxt->Frm().Width( pNxt->GetUpper()->Prt().Width() );
+        pNxt->Format( &rAttrs );
+    }
+
+    pFrm->bValidPos      = bOldPos;
+    pFrm->bValidSize     = bOldSz;
+    pFrm->bValidPrtArea  = bOldPrt;
+}
+
+// Diese Routine ueberprueft, ob zwischen dem FtnBoss von pFrm und dem
+// von pNxt keine anderen FtnBosse liegen
+
+BOOL lcl_IsNextFtnBoss( const SwFrm *pFrm, const SwFrm* pNxt )
+{
+    ASSERT( pFrm && pNxt, "lcl_IsNextFtnBoss: No Frames?" );
+    pFrm = pFrm->FindFtnBossFrm();
+    pNxt = pNxt->FindFtnBossFrm();
+    // Falls pFrm eine letzte Spalte ist, wird stattdessen die Seite genommen
+    while( pFrm && pFrm->IsColumnFrm() && !pFrm->GetNext() )
+        pFrm = pFrm->GetUpper()->FindFtnBossFrm();
+    // Falls pNxt eine erste Spalte ist, wird stattdessen die Seite genommen
+    while( pNxt && pNxt->IsColumnFrm() && !pNxt->GetPrev() )
+        pNxt = pNxt->GetUpper()->FindFtnBossFrm();
+    // So, jetzt muessen pFrm und pNxt entweder zwei benachbarte Seiten oder Spalten sein.
+    return ( pFrm && pNxt && pFrm->GetNext() == pNxt );
+}
+
+BOOL SwCntntFrm::_WouldFit( SwTwips nSpace, SwLayoutFrm *pNewUpper, BOOL bTstMove )
+{
+    //Damit die Fussnote sich ihren Platz sorgsam waehlt, muss
+    //sie in jedem Fall gemoved werden, wenn zwischen dem
+    //neuen Upper und ihrer aktuellen Seite/Spalte mindestens eine
+    //Seite/Spalte liegt.
+    SwFtnFrm* pFtnFrm = 0;
+    if ( IsInFtn() )
+    {
+        if( !lcl_IsNextFtnBoss( pNewUpper, this ) )
+            return TRUE;
+        pFtnFrm = FindFtnFrm();
+    }
+
+    BOOL bRet;
+    BOOL bSplit = !pNewUpper->Lower();
+    SwCntntFrm *pFrm = this;
+    const SwFrm *pPrev = pNewUpper->Lower();
+    if( pPrev && pPrev->IsFtnFrm() )
+        pPrev = ((SwFtnFrm*)pPrev)->Lower();
+    while ( pPrev && pPrev->GetNext() )
+        pPrev = pPrev->GetNext();
+    do
+    {
+        if ( bTstMove || IsInFly() || ( IsInSct() &&
+             ( pFrm->GetUpper()->IsColBodyFrm() || ( pFtnFrm &&
+               pFtnFrm->GetUpper()->GetUpper()->IsColumnFrm() ) ) ) )
+        {
+            //Jetzt wirds ein bischen hinterlistig; empfindliche Gemueter sollten
+            //lieber wegsehen. Wenn ein Flys Spalten enthaelt so sind die Cntnts
+            //moveable, mit Ausnahme der in der letzten Spalte (siehe
+            //SwFrm::IsMoveable()). Zurueckfliessen duerfen sie aber natuerlich.
+            //Das WouldFit() liefert leider nur dann einen vernueftigen Wert, wenn
+            //der Frm moveable ist. Um dem WouldFit() einen Moveable Frm
+            //vorzugaukeln haenge ich ihn einfach solange um.
+            // Auch bei spaltigen Bereichen muss umgehaengt werden, damit
+            // SwSectionFrm::Growable() den richtigen Wert liefert.
+            // Innerhalb von Fussnoten muss ggf. sogar der SwFtnFrm umgehaengt werden,
+            // falls es dort keinen SwFtnFrm gibt.
+            SwFrm* pTmpFrm = pFrm->IsInFtn() && !pNewUpper->FindFtnFrm() ?
+                             (SwFrm*)pFrm->FindFtnFrm() : pFrm;
+            SwLayoutFrm *pUp = pTmpFrm->GetUpper();
+            SwFrm *pOldNext = pTmpFrm->GetNext();
+            pTmpFrm->Remove();
+            pTmpFrm->InsertBefore( pNewUpper, 0 );
+            if( pFrm->IsTxtFrm() && ( bTstMove ||
+                ((SwTxtFrm*)pFrm)->HasFollow() ||
+                ( !((SwTxtFrm*)pFrm)->HasPara() &&
+                    !((SwTxtFrm*)pFrm)->IsEmpty() ) ) )
+            {
+                bTstMove = TRUE;
+                bRet = ((SwTxtFrm*)pFrm)->TestFormat( pPrev, nSpace, bSplit );
+            }
+            else
+                bRet = pFrm->WouldFit( nSpace, bSplit );
+            pTmpFrm->Remove();
+            pTmpFrm->InsertBefore( pUp, pOldNext );
+        }
+        else
+            bRet = pFrm->WouldFit( nSpace, bSplit );
+
+        //Bitter aber wahr: Der Abstand muss auch noch mit einkalkuliert werden.
+        //Bei TestFormatierung ist dies bereits geschehen.
+        if ( bRet && !bTstMove )
+        {
+            SwTwips nUpper;
+            if ( pPrev )
+            {
+                nUpper = CalcUpperSpace( NULL, pPrev );
+                SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFrm );
+                const SwBorderAttrs &rAttrs = *aAccess.Get();
+                nUpper += rAttrs.GetBottomLine( pFrm );
+            }
+            else
+                nUpper = pFrm->Frm().Height() - pFrm->Prt().Height();
+            nSpace -= nUpper;
+            if ( nSpace < 0 )
+                bRet = FALSE;
+        }
+
+        if ( bRet && !bSplit && pFrm->GetAttrSet()->GetKeep().GetValue() )
+        {
+            if( bTstMove )
+                while( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->HasFollow() )
+                    pFrm = ((SwTxtFrm*)pFrm)->GetFollow();
+            SwFrm *pNxt;
+            if( 0 != (pNxt = pFrm->FindNext()) && pNxt->IsCntntFrm() &&
+                ( !pFtnFrm || ( pNxt->IsInFtn() &&
+                  pNxt->FindFtnFrm()->GetAttr() == pFtnFrm->GetAttr() ) ) )
+            {
+                // ProbeFormatierung vertraegt keine absatz- oder gar zeichengebundene Objekte
+                if( bTstMove && pNxt->GetDrawObjs() )
+                    return TRUE;
+
+                if ( !pNxt->IsValid() )
+                    MakeNxt( pFrm, pNxt );
+
+                //Kleiner Trick: Wenn der naechste einen Vorgaenger hat, so hat
+                //er den Absatzabstand bereits berechnet. Er braucht dann nicht
+                //teuer kalkuliert werden.
+                if( lcl_NotHiddenPrev( pNxt ) )
+                    pPrev = 0;
+                else
+                {
+                    if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsHiddenNow() )
+                        pPrev = lcl_NotHiddenPrev( pFrm );
+                    else
+                        pPrev = pFrm;
+                }
+                pFrm = (SwCntntFrm*)pNxt;
+            }
+            else
+                pFrm = 0;
+        }
+        else
+            pFrm = 0;
+
+    } while ( bRet && pFrm );
+
+    return bRet;
+}
+
+
+
+
diff --git a/sw/source/core/layout/colfrm.cxx b/sw/source/core/layout/colfrm.cxx
new file mode 100644
index 000000000000..c996cb71be51
--- /dev/null
+++ b/sw/source/core/layout/colfrm.cxx
@@ -0,0 +1,469 @@
+/*************************************************************************
+ *
+ *  $RCSfile: colfrm.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:22 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include 
+#include "cntfrm.hxx"
+#include "doc.hxx"
+
+#include "hintids.hxx"
+
+#ifndef _SVX_ULSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _FMTCLDS_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFORDR_HXX //autogen
+#include 
+#endif
+#ifndef _FRMFMT_HXX //autogen
+#include 
+#endif
+#ifndef _NODE_HXX //autogen
+#include 
+#endif
+#include "frmtool.hxx"
+#include "colfrm.hxx"
+#include "pagefrm.hxx"
+#include "bodyfrm.hxx"   // ColumnFrms jetzt mit BodyFrm
+#include "rootfrm.hxx"   // wg. RemoveFtns
+#include "sectfrm.hxx"   // wg. FtnAtEnd-Flag
+
+// ftnfrm.cxx:
+void lcl_RemoveFtns( SwFtnBossFrm* pBoss, BOOL bPageOnly, BOOL bEndNotes );
+
+
+/*************************************************************************
+|*
+|*  SwColumnFrm::SwColumnFrm()
+|*
+|*  Ersterstellung      MA ??
+|*  Letzte Aenderung    AMA 30. Oct 98
+|*
+|*************************************************************************/
+SwColumnFrm::SwColumnFrm( SwFrmFmt *pFmt ):
+    SwFtnBossFrm( pFmt )
+{
+    nType = FRM_COLUMN;
+    SwBodyFrm* pColBody = new SwBodyFrm( pFmt->GetDoc()->GetDfltFrmFmt() );
+    pColBody->InsertBehind( this, 0 ); // ColumnFrms jetzt mit BodyFrm
+    SetMaxFtnHeight( LONG_MAX );
+}
+
+SwColumnFrm::~SwColumnFrm()
+{
+    SwFrmFmt *pFmt = GetFmt();
+    SwDoc *pDoc;
+    if ( !(pDoc = pFmt->GetDoc())->IsInDtor() && pFmt->IsLastDepend() )
+    {
+        //Ich bin der einzige, weg mit dem Format.
+        //Vorher ummelden, damit die Basisklasse noch klarkommt.
+        pDoc->GetDfltFrmFmt()->Add( this );
+        pDoc->DelFrmFmt( pFmt );
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwLayoutFrm::ChgColumns()
+|*
+|*  Ersterstellung      MA 11. Feb. 93
+|*  Letzte Aenderung    MA 12. Oct. 98
+|*
+|*************************************************************************/
+
+void MA_FASTCALL lcl_RemoveColumns( SwLayoutFrm *pCont, USHORT nCnt )
+{
+    ASSERT( pCont && pCont->Lower() && pCont->Lower()->IsColumnFrm(),
+            "Keine Spalten zu entfernen." );
+
+    SwColumnFrm *pColumn = (SwColumnFrm*)pCont->Lower();
+    ::lcl_RemoveFtns( pColumn, TRUE, TRUE );
+    while ( pColumn->GetNext() )
+    {
+        ASSERT( pColumn->GetNext()->IsColumnFrm(),
+                "Nachbar von ColFrm kein ColFrm." );
+        pColumn = (SwColumnFrm*)pColumn->GetNext();
+    }
+    for ( USHORT i = 0; i < nCnt; ++i )
+    {
+        SwColumnFrm *pTmp = (SwColumnFrm*)pColumn->GetPrev();
+        pColumn->Cut();
+        delete pColumn; //Format wird ggf. im DTor mit vernichtet.
+        pColumn = pTmp;
+    }
+}
+
+SwLayoutFrm * MA_FASTCALL lcl_FindColumns( SwLayoutFrm *pLay, USHORT nCount )
+{
+    SwFrm *pCol = pLay->Lower();
+    if ( pLay->IsPageFrm() )
+        pCol = ((SwPageFrm*)pLay)->FindBodyCont()->Lower();
+
+    if ( pCol && pCol->IsColumnFrm() )
+    {
+        SwFrm *pTmp = pCol;
+        USHORT i;
+        for ( i = 0; pTmp; pTmp = pTmp->GetNext(), ++i )
+            /* do nothing */;
+        return i == nCount ? (SwLayoutFrm*)pCol : 0;
+    }
+    return 0;
+}
+
+
+BOOL MA_FASTCALL lcl_AddColumns( SwLayoutFrm *pCont, USHORT nCount )
+{
+    SwDoc *pDoc = pCont->GetFmt()->GetDoc();
+    const BOOL bMod = pDoc->IsModified();
+
+    //Format sollen soweit moeglich geshared werden. Wenn es also schon einen
+    //Nachbarn mit den selben Spalteneinstellungen gibt, so koennen die
+    //Spalten an die selben Formate gehaengt werden.
+    //Der Nachbar kann ueber das Format gesucht werden, wer der Owner des Attributes
+    //ist, ist allerdings vom Frametyp abhaengig.
+    SwLayoutFrm *pAttrOwner = pCont;
+    if ( pCont->IsBodyFrm() )
+        pAttrOwner = pCont->FindPageFrm();
+    SwLayoutFrm *pNeighbourCol = 0;
+    SwClientIter aIter( *pAttrOwner->GetFmt() );
+    SwLayoutFrm *pNeighbour = (SwLayoutFrm*)aIter.First( TYPE(SwLayoutFrm) );
+
+    USHORT nAdd = 0;
+    SwFrm *pCol = pCont->Lower();
+    if ( pCol && pCol->IsColumnFrm() )
+        for ( nAdd = 1; pCol; pCol = pCol->GetNext(), ++nAdd )
+            /* do nothing */;
+    while ( pNeighbour )
+    {
+        if ( 0 != (pNeighbourCol = lcl_FindColumns( pNeighbour, nCount+nAdd )) &&
+             pNeighbourCol != pCont )
+            break;
+        pNeighbourCol = 0;
+        pNeighbour = (SwLayoutFrm*)aIter.Next();
+    }
+
+    BOOL bRet;
+    SwTwips nMax = pCont->IsPageBodyFrm() ?
+                   pCont->FindPageFrm()->GetMaxFtnHeight() : LONG_MAX;
+    if ( pNeighbourCol )
+    {
+        bRet = FALSE;
+        SwFrm *pTmp = pCont->Lower();
+        while ( pTmp )
+        {
+            pTmp = pTmp->GetNext();
+            pNeighbourCol = (SwLayoutFrm*)pNeighbourCol->GetNext();
+        }
+        for ( USHORT i = 0; i < nCount; ++i )
+        {
+            SwColumnFrm *pTmp = new SwColumnFrm( pNeighbourCol->GetFmt() );
+            pTmp->SetMaxFtnHeight( nMax );
+            pTmp->InsertBefore( pCont, NULL );
+            pTmp->bVarHeight = FALSE;
+            pNeighbourCol = (SwLayoutFrm*)pNeighbourCol->GetNext();
+        }
+    }
+    else
+    {
+        bRet = TRUE;
+        for ( USHORT i = 0; i < nCount; ++i )
+        {
+            SwFrmFmt *pFmt = pDoc->MakeFrmFmt( aEmptyStr, pDoc->GetDfltFrmFmt());
+            SwColumnFrm *pTmp = new SwColumnFrm( pFmt );
+            pTmp->SetMaxFtnHeight( nMax );
+            pTmp->Paste( pCont );
+        }
+    }
+
+    if ( !bMod )
+        pDoc->ResetModified();
+    return bRet;
+}
+
+/*-----------------21.09.99 15:42-------------------
+ * ChgColumns() adds or removes columns from a layoutframe.
+ * Normally, a layoutframe with a column attribut of 1 or 0 columns contains
+ * no columnframe. However, a sectionframe with "footnotes at the end" needs
+ * a columnframe. If the bChgFtn-flag is set, the columnframe will be inserted
+ * or remove, if necessary.
+ * --------------------------------------------------*/
+
+void SwLayoutFrm::ChgColumns( const SwFmtCol &rOld, const SwFmtCol &rNew,
+    const BOOL bChgFtn )
+{
+    if ( rOld.GetNumCols() <= 1 && rNew.GetNumCols() <= 1 && !bChgFtn )
+        return;
+    USHORT nNewNum, nOldNum = 1;
+    if( Lower() && Lower()->IsColumnFrm() )
+    {
+        SwFrm* pCol = Lower();
+        while( 0 != (pCol=pCol->GetNext()) )
+            ++nOldNum;
+    }
+    nNewNum = rNew.GetNumCols();
+    if( !nNewNum )
+        ++nNewNum;
+    BOOL bAtEnd;
+    if( IsSctFrm() )
+        bAtEnd = ((SwSectionFrm*)this)->IsAnyNoteAtEnd();
+    else
+        bAtEnd = FALSE;
+
+    //Einstellung der Spaltenbreiten ist nur bei neuen Formaten notwendig.
+    BOOL bAdjustAttributes = nOldNum != rOld.GetNumCols();
+
+    //Wenn die Spaltenanzahl unterschiedlich ist, wird der Inhalt
+    //gesichert und restored.
+    SwFrm *pSave = 0;
+    if( nOldNum != nNewNum || bChgFtn )
+    {
+        SwDoc *pDoc = GetFmt()->GetDoc();
+        ASSERT( pDoc, "FrmFmt gibt kein Dokument her." );
+        // SaveCntnt wuerde auch den Inhalt der Fussnotencontainer aufsaugen
+        // und im normalen Textfluss unterbringen.
+        if( IsPageBodyFrm() )
+            pDoc->GetRootFrm()->RemoveFtns( (SwPageFrm*)GetUpper(), TRUE, FALSE );
+        pSave = ::SaveCntnt( this );
+
+        //Wenn Spalten existieren, jetzt aber eine Spaltenanzahl von
+        //0 oder eins gewuenscht ist, so werden die Spalten einfach vernichtet.
+        if ( nNewNum == 1 && !bAtEnd )
+        {
+            ::lcl_RemoveColumns( this, nOldNum );
+            if ( IsBodyFrm() )
+                SetFrmFmt( pDoc->GetDfltFrmFmt() );
+            else
+                GetFmt()->SetAttr( SwFmtFillOrder() );
+            if ( pSave )
+                ::RestoreCntnt( pSave, this, 0 );
+            return;
+        }
+        if ( nOldNum == 1 )
+        {
+            if ( IsBodyFrm() )
+                SetFrmFmt( pDoc->GetColumnContFmt() );
+            else
+                GetFmt()->SetAttr( SwFmtFillOrder( ATT_LEFT_TO_RIGHT ) );
+            if( !Lower() || !Lower()->IsColumnFrm() )
+                --nOldNum;
+        }
+        if ( nOldNum > nNewNum )
+        {
+            ::lcl_RemoveColumns( this, nOldNum - nNewNum );
+            bAdjustAttributes = TRUE;
+        }
+        else if( nOldNum < nNewNum )
+        {
+            USHORT nAdd = nNewNum - nOldNum;
+            bAdjustAttributes = ::lcl_AddColumns( this, nAdd );
+        }
+    }
+
+    if ( !bAdjustAttributes )
+    {
+        if ( rOld.GetLineWidth()    != rNew.GetLineWidth() ||
+             rOld.GetWishWidth()    != rNew.GetWishWidth() ||
+             rOld.IsOrtho()         != rNew.IsOrtho() )
+            bAdjustAttributes = TRUE;
+        else
+        {
+            USHORT nCount = Min( rNew.GetColumns().Count(), rOld.GetColumns().Count() );
+            for ( USHORT i = 0; i < nCount; ++i )
+                if ( !(*rOld.GetColumns()[i] == *rNew.GetColumns()[i]) )
+                {
+                    bAdjustAttributes = TRUE;
+                    break;
+                }
+        }
+    }
+
+    //Sodele, jetzt koennen die Spalten bequem eingestellt werden.
+    AdjustColumns( &rNew, bAdjustAttributes );
+
+    //Erst jetzt den Inhalt restaurieren. Ein frueheres Restaurieren wuerde
+    //unnuetzte Aktionen beim Einstellen zur Folge haben.
+    if ( pSave )
+    {
+        ASSERT( Lower() && Lower()->IsLayoutFrm() &&
+                ((SwLayoutFrm*)Lower())->Lower() &&
+                ((SwLayoutFrm*)Lower())->Lower()->IsLayoutFrm(),
+                "Gesucht: Spaltenbody (Tod oder Lebend)." );   // ColumnFrms jetzt mit BodyFrm
+        ::RestoreCntnt( pSave, (SwLayoutFrm*)((SwLayoutFrm*)Lower())->Lower(), 0 );
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwLayoutFrm::AdjustColumns()
+|*
+|*  Ersterstellung      MA 19. Jan. 99
+|*  Letzte Aenderung    MA 19. Jan. 99
+|*
+|*************************************************************************/
+
+void SwLayoutFrm::AdjustColumns( const SwFmtCol *pAttr, BOOL bAdjustAttributes )
+{
+    if( !Lower()->GetNext() )
+    {
+        Lower()->ChgSize( Prt().SSize() );
+        return;
+    }
+
+    //Ist ein Pointer da, oder sollen wir die Attribute einstellen,
+    //so stellen wir auf jeden Fall die Spaltenbreiten ein. Andernfalls
+    //checken wir, ob eine Einstellung notwendig ist.
+    if ( !pAttr )
+    {
+        pAttr = &GetFmt()->GetCol();
+        if ( !bAdjustAttributes )
+        {
+            ;
+            long nAvail = Prt().Width();
+            for ( SwLayoutFrm *pCol = (SwLayoutFrm*)Lower();
+                  pCol;
+                  pCol = (SwLayoutFrm*)pCol->GetNext() )
+                nAvail -= pCol->Frm().Width();
+            if ( !nAvail )
+                return;
+        }
+    }
+
+    //Sodele, jetzt koennen die Spalten bequem eingestellt werden.
+    //Die Breiten werden mitgezaehlt, damit wir dem letzten den Rest geben
+    //koennen.
+    SwTwips nAvail = Prt().Width();
+    const BOOL bLine = pAttr->GetLineAdj() != COLADJ_NONE;
+    USHORT nMin = 0;
+    if ( bLine )
+        nMin = USHORT(20 + (pAttr->GetLineWidth() / 2));
+    SwFrm *pCol = Lower();
+    for ( USHORT i = 0; i < pAttr->GetNumCols(); pCol = pCol->GetNext(), ++i )
+    {
+        const SwTwips nWidth = i == (pAttr->GetNumCols() - 1) ?
+                                nAvail :
+                                pAttr->CalcColWidth( i, USHORT(Prt().Width()) );
+        const Size aColSz( nWidth, Prt().Height() );
+        pCol->ChgSize( aColSz );
+
+        // Hierdurch werden die ColumnBodyFrms von Seitenspalten angepasst und
+        // ihr bFixHeight-Flag wird gesetzt, damit sie nicht schrumpfen/wachsen.
+        // Bei Rahmenspalten hingegen soll das Flag _nicht_ gesetzt werden,
+        // da BodyFrms in Rahmenspalten durchaus wachsen/schrumpfen duerfen.
+        if( IsBodyFrm() )
+            ((SwLayoutFrm*)pCol)->Lower()->ChgSize( aColSz );
+
+        nAvail -= nWidth;
+
+        if ( bAdjustAttributes )
+        {
+            SwColumn *pC = pAttr->GetColumns()[i];
+            SwAttrSet* pSet = pCol->GetAttrSet();
+            SvxLRSpaceItem aLR( pSet->GetLRSpace() );
+            SvxULSpaceItem aUL( pSet->GetULSpace() );
+
+            //Damit die Trennlinien Platz finden, muessen sie hier
+            //Beruecksichtigung finden. Ueberall wo zwei Spalten aufeinanderstossen
+            //wird jeweils rechts bzw. links ein Sicherheitsabstand von 20 plus
+            //der halben Penbreite einkalkuliert.
+            if ( bLine )
+            {
+                if ( i == 0 )
+                {   aLR.SetLeft ( pC->GetLeft() );
+                    aLR.SetRight( Max(pC->GetRight(), nMin) );
+                }
+                else if ( i == (pAttr->GetNumCols() - 1) )
+                {   aLR.SetLeft ( Max(pC->GetLeft(), nMin) );
+                    aLR.SetRight( pC->GetRight() );
+                }
+                else
+                {   aLR.SetLeft ( Max(pC->GetLeft(),  nMin) );
+                    aLR.SetRight( Max(pC->GetRight(), nMin) );
+                }
+            }
+            else
+            {
+                aLR.SetLeft ( pC->GetLeft() );
+                aLR.SetRight( pC->GetRight());
+            }
+            aUL.SetUpper( pC->GetUpper());
+            aUL.SetLower( pC->GetLower());
+
+            ((SwLayoutFrm*)pCol)->GetFmt()->SetAttr( aLR );
+            ((SwLayoutFrm*)pCol)->GetFmt()->SetAttr( aUL );
+        }
+    }
+}
+
+
+
+
+
diff --git a/sw/source/core/layout/dbg_lay.cxx b/sw/source/core/layout/dbg_lay.cxx
new file mode 100644
index 000000000000..e1a6c1e832b6
--- /dev/null
+++ b/sw/source/core/layout/dbg_lay.cxx
@@ -0,0 +1,813 @@
+/*************************************************************************
+ *
+ *  $RCSfile: dbg_lay.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:22 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+/* -----------------08.01.99 14:55-------------------
+ * Und hier die Beschreibung:
+ *
+ * Durch die PROTOCOL-Makros wird es ermoeglicht, Ereignisse im Frame-Methoden zu protokollieren.
+ * In protokollwuerdigen Stellen in Frame-Methoden muss entweder ein PROTOCOL(...) oder bei Methoden,
+ * bei denen auch das Verlassen der Methode mitprotokolliert werden soll, ein PROTOCOL_ENTER(...)-Makro
+ * stehen.
+ * Die Parameter der PROTOCOL-Makros sind
+ * 1.   Ein Pointer auf einen SwFrm, also meist "this" oder "rThis"
+ * 2.   Die Funktionsgruppe z.B. PROT_MAKEALL, hierueber wird (inline) entschieden, ob dies
+ *      zur Zeit protokolliert werden soll oder nicht.
+ * 3.   Die Aktion, im Normalfall 0, aber z.B. ein ACT_START bewirkt eine Einrueckung in der
+ *      Ausgabedatei, ein ACT_END nimmt dies wieder zurueck. Auf diese Art wird z.B. durch
+ *      PROTOCOL_ENTER am Anfang einer Methode eingerueckt und beim Verlassen wieder zurueck.
+ * 4.   Der vierte Parameter ist ein void-Pointer, damit man irgendetwas uebergeben kann,
+ *      was in das Protokoll einfliessen kann, typesches Beispiel bei PROT_GROW muss man
+ *      einen Pointer auf den Wert, um den gegrowt werden soll, uebergeben.
+ *
+ *
+ * Das Protokoll ist die Datei "dbg_lay.out" im aktuellen (BIN-)Verzeichnis.
+ * Es enthaelt Zeilen mit FrmId, Funktionsgruppe sowie weiteren Infos.
+ *
+ * Was genau protokolliert wird, kann auf folgende Arten eingestellt werden:
+ * 1.   Die statische Variable SwProtokoll::nRecord enthaelt die Funktionsgruppen,
+ *      die aufgezeichnet werden sollen.
+ *      Ein Wert von z.B. PROT_GROW bewirkt, das Aufrufe von SwFrm::Grow dokumentiert werden,
+ *      PROT_MAKEALL protokolliert Aufrufe von xxx::MakeAll.
+ *      Die PROT_XY-Werte koennen oderiert werden.
+ *      Default ist Null, es wird keine Methode aufgezeichnet.
+ * 2.   In der SwImplProtocol-Klasse gibt es einen Filter fuer Frame-Typen,
+ *      nur die Methodenaufrufe von Frame-Typen, die dort gesetzt sind, werden protokolliert.
+ *      Der Member nTypes kann auf Werte wie FRM_PAGE, FRM_SECTION gesetzt und oderiert werden.
+ *      Default ist 0xFFFF, d.h. alle Frame-Typen.
+ * 3.   In der SwImplProtocol-Klasse gibt es einen ArrayPointer auf FrmIds, die zu ueberwachen sind.
+ *      Ist der Pointer Null, so werden alle Frames protokolliert, ansonsten nur Frames,
+ *      die in dem Array vermerkt sind.
+ *
+ * Eine Aufzeichnung in Gang zu setzen, erfordert entweder Codemanipulation, z.B. in
+ * SwProtocol::Init() einen anderen Default fuer nRecord setzen oder Debuggermanipulation.
+ * Im Debugger gibt verschiedene, sich anbietende Stellen:
+ * 1.   In SwProtocol::Init() einen Breakpoint setzen und dort nRecord manipulieren, ggf.
+ *      FrmIds eintragen, dann beginnt die Aufzeichnung bereits beim Programmstart.
+ * 2.   Waehrend des Programmlaufs einen Breakpoint vor irgendein PROTOCOL oder PROTOCOL_ENTER-
+ *      Makro setzen, dann am SwProtocol::nRecord das unterste Bit setzen (PROT_INIT). Dies
+ *      bewirkt, dass die Funktionsgruppe des folgenden Makros aktiviert und in Zukunft
+ *      protokolliert wird.
+ * 3.   Spezialfall von 2.: Wenn man 2. in der Methode SwRootFrm::Paint(..) anwendet, werden
+ *      die Aufzeichnungseinstellung aus der Datei "dbg_lay.ini" ausgelesen!
+ *      In dieser INI-Datei kann es Kommentarzeilen geben, diese beginnen mit '#', dann
+ *      sind die Sektionen "[frmid]", "[frmtype]" und "[record]" relevant.
+ *      Nach [frmid] koennen die FrameIds der zu protokollierenden Frames folgen. Gibt es
+ *      dort keine Eintraege, werden alle Frames aufgezeichnet.
+ *      Nach [frmtype] koennen FrameTypen folgen, die aufgezeichnet werden sollen, da der
+ *      Default hier allerdings USHRT_MAX ist, werden sowieso alle aufgezeichnet. Man kann
+ *      allerdings auch Typen entfernen, in dem man ein '!' vor den Wert setzt, z.B.
+ *      !0xC000 nimmt die SwCntntFrms aus der Aufzeichnung heraus.
+ *      Nach [record] folgen die Funktionsgruppen, die aufgezeichnet werden sollen, Default
+ *      ist hier 0, also keine. Auch hier kann man mit einem vorgestellten '!' Funktionen
+ *      wieder entfernen.
+ *      Hier mal ein Beispiel fuer eine INI-Datei:
+ *      ------------------------------------------
+ *          #Funktionen: Alle, ausser PRTAREA
+ *          [record] 0xFFFFFFE !0x200
+ *          [frmid]
+ *          #folgende FrmIds:
+ *          1 2 12 13 14 15
+ *          #keine Layoutframes ausser ColumnFrms
+ *          [frmtype] !0x3FFF 0x4
+ *      ------------------------------------------
+ *
+ * Wenn die Aufzeichnung erstmal laeuft, kann man in SwImplProtocol::_Record(...) mittels
+ * Debugger vielfaeltige Manipulationen vornehmen, z.B. bezueglich FrameTypen oder FrmIds.
+ *
+ * --------------------------------------------------*/
+
+#ifdef PRODUCT
+#error Wer fummelt denn an den makefiles rum?
+#endif
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "dbg_lay.hxx"
+
+#ifndef _STREAM_HXX //autogen
+#include 
+#endif
+
+#ifndef _SVSTDARR_HXX
+#define _SVSTDARR_USHORTS
+#define _SVSTDARR_USHORTSSORT
+#include 
+#endif
+
+#include 
+
+#include "frame.hxx"
+#include "layfrm.hxx"
+
+ULONG SwProtocol::nRecord = 0;
+SwImplProtocol* SwProtocol::pImpl = NULL;
+
+class SwImplProtocol
+{
+    SvFileStream *pStream;      // Ausgabestream
+    SvUShortsSort *pFrmIds;     // welche FrmIds sollen aufgezeichnet werden ( NULL == alle )
+    ByteString aLayer;          // Einrueckung der Ausgabe ("  " pro Start/End)
+    USHORT nTypes;              // welche Typen sollen aufgezeichnet werden
+    USHORT nLineCount;          // Ausgegebene Zeilen
+    USHORT nMaxLines;           // Maximal auszugebende Zeilen
+    BYTE nInitFile;             // Bereich (FrmId,FrmType,Record) beim Einlesen der INI-Datei
+    BYTE nTestMode;             // Special fuer Testformatierung, es wird ggf. nur
+                                // innerhalb einer Testformatierung aufgezeichnet.
+    void _Record( const SwFrm* pFrm, ULONG nFunction, ULONG nAct, void* pParam );
+    BOOL NewStream();
+    void CheckLine( ByteString& rLine );
+    void SectFunc( ByteString &rOut, const SwFrm* pFrm, ULONG nAct, void* pParam );
+public:
+    SwImplProtocol();
+    ~SwImplProtocol();
+    // Aufzeichnen
+    void Record( const SwFrm* pFrm, ULONG nFunction, ULONG nAct, void* pParam )
+        { if( pStream ) _Record( pFrm, nFunction, nAct, pParam ); }
+    BOOL InsertFrm( USHORT nFrmId );    // FrmId aufnehmen zum Aufzeichnen
+    BOOL DeleteFrm( USHORT nFrmId );    // FrmId entfernen, diesen nicht mehr Aufzeichnen
+    void FileInit();                    // Auslesen der INI-Datei
+    void ChkStream() { if( !pStream ) NewStream(); }
+};
+
+/* -----------------11.01.99 10:43-------------------
+ * Durch das PROTOCOL_ENTER-Makro wird ein SwEnterLeave-Objekt erzeugt,
+ * wenn die aktuelle Funktion aufgezeichnet werden soll, wird ein
+ * SwImplEnterLeave-Objekt angelegt. Der Witz dabei ist, das der Ctor
+ * des Impl-Objekt am Anfang der Funktion und automatisch der Dtor beim
+ * Verlassen der Funktion gerufen wird. In der Basis-Implementierung ruft
+ * der Ctor lediglich ein PROTOCOL(..) mit ACT_START und im Dtor ein
+ * PROTOCOL(..) mit ACT_END.
+ * Es lassen sich Ableitungen der Klasse bilden, um z.B. beim Verlassen
+ * einer Funktion Groessenaenderungen des Frames zu dokumentieren u.v.a.m.
+ * Dazu braucht dann nur noch in SwEnterLeave::Ctor(...) die gewuenschte
+ * SwImplEnterLeave-Klasse angelegt zu werden.
+ *
+ * --------------------------------------------------*/
+
+class SwImplEnterLeave
+{
+protected:
+    const SwFrm* pFrm;              // Der Frame,
+    ULONG nFunction, nAction;       // die Funktion, ggf. die Aktion
+    void* pParam;                   // und weitere Parameter
+public:
+    SwImplEnterLeave( const SwFrm* pF, ULONG nFunct, ULONG nAct, void* pPar )
+        : pFrm( pF ), nFunction( nFunct ), nAction( nAct ), pParam( pPar ) {}
+    virtual void Enter();           // Ausgabe beim Eintritt
+    virtual void Leave();           // Ausgabe beim Verlassen
+};
+
+class SwSizeEnterLeave : public SwImplEnterLeave
+{
+    long nFrmHeight;
+public:
+    SwSizeEnterLeave( const SwFrm* pF, ULONG nFunct, ULONG nAct, void* pPar )
+        : SwImplEnterLeave( pF, nFunct, nAct, pPar ), nFrmHeight( pF->Frm().Height() ) {}
+    virtual void Leave();           // Ausgabe der Groessenaenderung
+};
+
+class SwUpperEnterLeave : public SwImplEnterLeave
+{
+    USHORT nFrmId;
+public:
+    SwUpperEnterLeave( const SwFrm* pF, ULONG nFunct, ULONG nAct, void* pPar )
+        : SwImplEnterLeave( pF, nFunct, nAct, pPar ), nFrmId( 0 ) {}
+    virtual void Enter();           // Ausgabe
+    virtual void Leave();           // Ausgabe der FrmId des Uppers
+};
+
+class SwFrmChangesLeave : public SwImplEnterLeave
+{
+    SwRect aFrm;
+public:
+    SwFrmChangesLeave( const SwFrm* pF, ULONG nFunct, ULONG nAct, void* pPar )
+        : SwImplEnterLeave( pF, nFunct, nAct, pPar ), aFrm( pF->Frm() ) {}
+    virtual void Enter();           // keine Ausgabe
+    virtual void Leave();           // Ausgabe bei Aenderung der Frm-Area
+};
+
+void SwProtocol::Record( const SwFrm* pFrm, ULONG nFunction, ULONG nAct, void* pParam )
+{
+    if( Start() )
+    {   // Hier landen wir, wenn im Debugger SwProtocol::nRecord mit PROT_INIT(0x1) oderiert wurde
+        BOOL bFinit = FALSE; // Dies bietet im Debugger die Moeglichkeit,
+        if( bFinit )         // die Aufzeichnung dieser Action zu beenden
+        {
+            nRecord &= ~nFunction;  // Diese Funktion nicht mehr aufzeichnen
+            nRecord &= ~PROT_INIT;  // PROT_INIT stets zuruecksetzen
+            return;
+        }
+        nRecord |= nFunction;       // Aufzeichnung dieser Funktion freischalten
+        nRecord &= ~PROT_INIT;      // PROT_INIT stets zuruecksetzen
+        if( pImpl )
+            pImpl->ChkStream();
+    }
+    if( !pImpl )                        // Impl-Object anlegen, wenn noetig
+        pImpl = new SwImplProtocol();
+    pImpl->Record( pFrm, nFunction, nAct, pParam ); // ...und Aufzeichnen
+}
+
+// Die folgende Funktion wird beim Anziehen der Writer-DLL durch TxtInit(..) aufgerufen
+// und ermoeglicht dem Debuggenden Funktionen und/oder FrmIds freizuschalten
+
+void SwProtocol::Init()
+{
+    nRecord = 0;
+    XubString aName( "dbg_lay.go", RTL_TEXTENCODING_MS_1252 );
+    SvFileStream aStream( aName, STREAM_READ );
+    if( aStream.IsOpen() )
+    {
+        pImpl = new SwImplProtocol();
+        pImpl->FileInit();
+    }
+}
+
+// Ende der Aufzeichnung
+
+void SwProtocol::Stop()
+{
+     if( pImpl )
+     {
+        delete pImpl;
+        pImpl = NULL;
+     }
+     nRecord = 0;
+}
+
+SwImplProtocol::SwImplProtocol()
+    : pStream( NULL ), pFrmIds( NULL ), nTypes( 0xffff ), nTestMode( 0 ),
+    nLineCount( 0 ), nMaxLines( USHRT_MAX )
+{
+    NewStream();
+}
+
+BOOL SwImplProtocol::NewStream()
+{
+    XubString aName( "dbg_lay.out", RTL_TEXTENCODING_MS_1252 );
+    nLineCount = 0;
+    pStream = new SvFileStream( aName, STREAM_WRITE | STREAM_TRUNC );
+    if( pStream->GetError() )
+    {
+        delete pStream;
+        pStream = NULL;
+    }
+    return 0 != pStream;
+}
+
+SwImplProtocol::~SwImplProtocol()
+{
+    delete pStream;
+    delete pFrmIds;
+}
+
+/* -----------------11.01.99 11:03-------------------
+ * SwImplProtocol::CheckLine analysiert eine Zeile der INI-Datei
+ * --------------------------------------------------*/
+
+void SwImplProtocol::CheckLine( ByteString& rLine )
+{
+    rLine = rLine.ToLowerAscii(); // Gross/Kleinschreibung ist einerlei
+    while( STRING_LEN > rLine.SearchAndReplace( '\t', ' ' ) )
+        ; //nothing                 // Tabs werden durch Blanks ersetzt
+    if( '#' == rLine.GetChar(0) )   // Kommentarzeilen beginnen mit '#'
+        return;
+    if( '[' == rLine.GetChar(0) )   // Bereiche: FrmIds, Typen oder Funktionen
+    {
+        ByteString aTmp = rLine.GetToken( 0, ']' );
+        if( "[frmid" == aTmp )      // Bereich FrmIds
+        {
+            nInitFile = 1;
+            delete pFrmIds;
+            pFrmIds = NULL;         // Default: Alle Frames aufzeichnen
+        }
+        else if( "[frmtype" == aTmp )// Bereich Typen
+        {
+            nInitFile = 2;
+            nTypes = USHRT_MAX;     // Default: Alle FrmaeTypen aufzeichnen
+        }
+        else if( "[record" == aTmp )// Bereich Funktionen
+        {
+            nInitFile = 3;
+            SwProtocol::SetRecord( 0 );// Default: Keine Funktion wird aufgezeichnet
+        }
+        else if( "[test" == aTmp )// Bereich Funktionen
+        {
+            nInitFile = 4; // Default:
+            nTestMode = 0; // Ausserhalb der Testformatierung wird aufgezeichnet
+        }
+        else if( "[max" == aTmp )// maximale Zeilenzahl
+        {
+            nInitFile = 5; // Default:
+            nMaxLines = USHRT_MAX;
+        }
+        else
+            nInitFile = 0;          // Nanu: Unbekannter Bereich?
+        rLine.Erase( 0, aTmp.Len() + 1 );
+    }
+    USHORT nToks = rLine.GetTokenCount( ' ' );  // Blanks (oder Tabs) sind die Trenner
+    for( USHORT i=0; i < nToks; ++i )
+    {
+        ByteString aTok = rLine.GetToken( i, ' ' );
+        BOOL bNo = FALSE;
+        if( '!' == aTok.GetChar(0) )
+        {
+            bNo = TRUE;                 // Diese(n) Funktion/Typ entfernen
+            aTok.Erase( 0, 1 );
+        }
+        if( aTok.Len() )
+        {
+            ULONG nVal;
+            sscanf( aTok.GetBuffer(), "%li", &nVal );
+            switch ( nInitFile )
+            {
+                case 1: InsertFrm( USHORT( nVal ) );    // FrmId aufnehmen
+                        break;
+                case 2: {
+                            USHORT nNew = (USHORT)nVal;
+                            if( bNo )
+                                nTypes &= ~nNew;    // Typ entfernen
+                            else
+                                nTypes |= nNew;     // Typ aufnehmen
+                        }
+                        break;
+                case 3: {
+                            ULONG nOld = SwProtocol::Record();
+                            if( bNo )
+                                nOld &= ~nVal;      // Funktion entfernen
+                            else
+                                nOld |= nVal;       // Funktion aufnehmen
+                            SwProtocol::SetRecord( nOld );
+                        }
+                        break;
+                case 4: {
+                            BYTE nNew = (BYTE)nVal;
+                            if( bNo )
+                                nTestMode &= ~nNew; // TestMode zuruecksetzen
+                            else
+                                nTestMode |= nNew;      // TestMode setzen
+                        }
+                        break;
+                case 5: nMaxLines = (USHORT)nVal;
+                        break;
+            }
+        }
+    }
+}
+
+/* -----------------11.01.99 11:17-------------------
+ * SwImplProtocol::FileInit() liest die Datei "dbg_lay.ini"
+ * im aktuellen Verzeichnis und wertet sie aus.
+ * --------------------------------------------------*/
+void SwImplProtocol::FileInit()
+{
+    XubString aName( "dbg_lay.ini", RTL_TEXTENCODING_MS_1252 );
+    SvFileStream aStream( aName, STREAM_READ );
+    if( aStream.IsOpen() )
+    {
+        ByteString aLine;
+        nInitFile = 0;
+        while( !aStream.IsEof() )
+        {
+            sal_Char c;
+            aStream >> c;
+            if( '\n' == c || '\r' == c )    // Zeilenende
+            {
+                aLine.EraseLeadingChars();
+                aLine.EraseTrailingChars();
+                if( aLine.Len() )
+                    CheckLine( aLine );     // Zeile auswerten
+                aLine.Erase();
+            }
+            else
+                aLine += c;
+        }
+        if( aLine.Len() )
+            CheckLine( aLine );     // letzte Zeile auswerten
+    }
+}
+
+/* -----------------11.01.99 11:20-------------------
+ * lcl_Start sorgt fuer Einrueckung um zwei Blanks bei ACT_START
+ * und nimmt diese bei ACT_END wieder zurueck.
+ * --------------------------------------------------*/
+void lcl_Start( ByteString& rOut, ByteString& rLay, ULONG nAction )
+{
+    if( nAction == ACT_START )
+    {
+        rLay += "  ";
+        rOut += " On";
+    }
+    else if( nAction == ACT_END )
+    {
+        if( rLay.Len() > 1 )
+        {
+            rLay.Erase( rLay.Len() - 2 );
+            rOut.Erase( 0, 2 );
+        }
+        rOut += " Off";
+    }
+}
+
+/* -----------------11.01.99 11:21-------------------
+ * lcl_Flags gibt das ValidSize-, ValidPos- und ValidPrtArea-Flag ("Sz","Ps","PA")
+ * des Frames aus, "+" fuer valid, "-" fuer invalid.
+ * --------------------------------------------------*/
+
+void lcl_Flags( ByteString& rOut, const SwFrm* pFrm )
+{
+    rOut += " Sz";
+    rOut += pFrm->GetValidSizeFlag() ? '+' : '-';
+    rOut += " Ps";
+    rOut += pFrm->GetValidPosFlag() ? '+' : '-';
+    rOut += " PA";
+    rOut += pFrm->GetValidPrtAreaFlag() ? '+' : '-';
+}
+
+/* -----------------11.01.99 11:23-------------------
+ * lcl_FrameType gibt den Typ des Frames in Klartext aus.
+ * --------------------------------------------------*/
+
+void lcl_FrameType( ByteString& rOut, const SwFrm* pFrm )
+{
+    if( pFrm->IsTxtFrm() )
+        rOut += "Txt ";
+    else if( pFrm->IsLayoutFrm() )
+    {
+        if( pFrm->IsPageFrm() )
+            rOut += "Page ";
+        else if( pFrm->IsColumnFrm() )
+            rOut += "Col ";
+        else if( pFrm->IsBodyFrm() )
+        {
+            if( pFrm->GetUpper() && pFrm->IsColBodyFrm() )
+                rOut += "(Col)";
+            rOut += "Body ";
+        }
+        else if( pFrm->IsRootFrm() )
+            rOut += "Root ";
+        else if( pFrm->IsCellFrm() )
+            rOut += "Cell ";
+        else if( pFrm->IsTabFrm() )
+            rOut += "Tab ";
+        else if( pFrm->IsRowFrm() )
+            rOut += "Row ";
+        else if( pFrm->IsSctFrm() )
+            rOut += "Sect ";
+        else if( pFrm->IsHeaderFrm() )
+            rOut += "Header ";
+        else if( pFrm->IsFooterFrm() )
+            rOut += "Footer ";
+        else if( pFrm->IsFtnFrm() )
+            rOut += "Ftn ";
+        else if( pFrm->IsFtnContFrm() )
+            rOut += "FtnCont ";
+        else if( pFrm->IsFlyFrm() )
+            rOut += "Fly ";
+        else
+            rOut += "Layout ";
+    }
+    else if( pFrm->IsNoTxtFrm() )
+        rOut += "NoTxt ";
+    else
+        rOut += "Not impl. ";
+}
+
+/* -----------------11.01.99 11:25-------------------
+ * SwImplProtocol::Record(..) wird nur gerufen, wenn das PROTOCOL-Makro
+ * feststellt, dass die Funktion aufgezeichnet werden soll ( SwProtocol::nRecord ).
+ * In dieser Methode werden noch die beiden weiteren Einschraenkungen ueberprueft,
+ * ob die FrmId und der FrameType zu den aufzuzeichnenden gehoeren.
+ * --------------------------------------------------*/
+
+void SwImplProtocol::_Record( const SwFrm* pFrm, ULONG nFunction, ULONG nAct, void* pParam )
+{
+    USHORT nSpecial = 0;
+    if( nSpecial )  // Debugger-Manipulationsmoeglichkeit
+    {
+        USHORT nId = pFrm->GetFrmId();
+        switch ( nSpecial )
+        {
+            case 1: InsertFrm( nId ); break;
+            case 2: DeleteFrm( nId ); break;
+            case 3: delete pFrmIds; pFrmIds = NULL; break;
+            case 4: delete pStream; pStream = NULL; break;
+        }
+        return;
+    }
+    if( !pStream && !NewStream() )
+        return; // Immer noch kein Stream
+
+    if( pFrmIds && !pFrmIds->Seek_Entry( pFrm->GetFrmId() ) )
+        return; // gehoert nicht zu den gewuenschten FrmIds
+
+    if( !(pFrm->GetType() & nTypes) )
+        return; // Der Typ ist unerwuenscht
+
+    if( 1 == nTestMode && nFunction != PROT_TESTFORMAT )
+        return; // Wir sollen nur innerhalb einer Testformatierung aufzeichnen
+    BOOL bTmp = FALSE;
+    ByteString aOut = aLayer;
+    aOut += pFrm->GetFrmId();       // Erstmal die FrmId ausgeben
+    aOut += ' ';
+    lcl_FrameType( aOut, pFrm );    // dann den FrameType
+    switch ( nFunction )            // und die Funktion
+    {
+        case PROT_MAKEALL:  aOut += "MakeAll";
+                            lcl_Start( aOut, aLayer, nAct );
+                            if( nAct == ACT_START )
+                                lcl_Flags( aOut, pFrm );
+                            break;
+        case PROT_MOVE_FWD: bTmp = TRUE; // NoBreak
+        case PROT_MOVE_BWD: aOut += ( nFunction == bTmp ) ? "Fwd" : "Bwd";
+                            lcl_Start( aOut, aLayer, nAct );
+                            if( pParam )
+                            {
+                                aOut += ' ';
+                                aOut += *((USHORT*)pParam);
+                            }
+                            break;
+        case PROT_GROW_TST: if( ACT_START != nAct )
+                                return;
+                            aOut += "TestGrow";
+                            break;
+        case PROT_SHRINK_TST: if( ACT_START != nAct )
+                                return;
+                            aOut += "TestShrink";
+                            break;
+        case PROT_ADJUSTN :
+        case PROT_SHRINK:   bTmp = TRUE; // NoBreak
+        case PROT_GROW:     aOut += !bTmp ? "Grow" :
+                                    ( nFunction == PROT_SHRINK ? "Shrink" : "AdjustNgbhd" );
+                            lcl_Start( aOut, aLayer, nAct );
+                            if( pParam )
+                            {
+                                aOut += ' ';
+                                aOut += *((long*)pParam);
+                            }
+                            break;
+        case PROT_POS:      break;
+        case PROT_PRTAREA:  aOut += "PrtArea";
+                            lcl_Start( aOut, aLayer, nAct );
+                            break;
+        case PROT_SIZE:     aOut += "Size";
+                            lcl_Start( aOut, aLayer, nAct );
+                            aOut += ' ';
+                            aOut += pFrm->Frm().Height();
+                            break;
+        case PROT_LEAF:     aOut += "Prev/NextLeaf";
+                            lcl_Start( aOut, aLayer, nAct );
+                            aOut += ' ';
+                            if( pParam )
+                            {
+                                aOut += ' ';
+                                aOut += ((SwFrm*)pParam)->GetFrmId();
+                            }
+                            break;
+        case PROT_FILE_INIT: FileInit();
+                             aOut = "Initialize";
+                            break;
+        case PROT_SECTION:  SectFunc( aOut, pFrm, nAct, pParam );
+                            break;
+        case PROT_CUT:      bTmp = TRUE; // NoBreak
+        case PROT_PASTE:    aOut += bTmp ? "Cut from " : "Paste to ";
+                            aOut += ((SwFrm*)pParam)->GetFrmId();
+                            break;
+        case PROT_TESTFORMAT: aOut += "Test";
+                            lcl_Start( aOut, aLayer, nAct );
+                            if( ACT_START == nAct )
+                                nTestMode |= 2;
+                            else
+                                nTestMode &= ~2;
+                            break;
+        case PROT_FRMCHANGES:
+                            {
+                                SwRect& rFrm = *((SwRect*)pParam);
+                                if( pFrm->Frm().Pos() != rFrm.Pos() )
+                                {
+                                    aOut += "PosChg: (";
+                                    aOut += rFrm.Left();
+                                    aOut += ", ";
+                                    aOut += rFrm.Top();
+                                    aOut += ") (";
+                                    aOut += pFrm->Frm().Left();
+                                    aOut += ", ";
+                                    aOut += pFrm->Frm().Top();
+                                    aOut += ") ";
+                                }
+                                if( pFrm->Frm().Height() != rFrm.Height() )
+                                {
+                                    aOut += "Height: ";
+                                    aOut += rFrm.Height();
+                                    aOut += " -> ";
+                                    aOut += pFrm->Frm().Height();
+                                    aOut += " ";
+                                }
+                                if( pFrm->Frm().Width() != rFrm.Width() )
+                                {
+                                    aOut += "Width: ";
+                                    aOut += rFrm.Width();
+                                    aOut += " -> ";
+                                    aOut += pFrm->Frm().Width();
+                                    aOut += " ";
+                                }
+                                break;
+                            }
+    }
+    *pStream << aOut.GetBuffer() << endl;   // Ausgabe
+    pStream->Flush();   // Gleich auf die Platte, damit man mitlesen kann
+    if( ++nLineCount >= nMaxLines )     // Maximale Ausgabe erreicht?
+        SwProtocol::SetRecord( 0 );        // => Ende der Aufzeichnung
+}
+
+/* -----------------13.01.99 11:39-------------------
+ * SwImplProtocol::SectFunc(...) wird von SwImplProtocol::_Record(..) gerufen,
+ * hier werden die Ausgaben rund um SectionFrms abgehandelt.
+ * --------------------------------------------------*/
+
+void SwImplProtocol::SectFunc( ByteString &rOut, const SwFrm* pFrm, ULONG nAct, void* pParam )
+{
+    BOOL bTmp = FALSE;
+    switch( nAct )
+    {
+        case ACT_MERGE:         rOut += "Merge Section ";
+                                rOut += ((SwFrm*)pParam)->GetFrmId();
+                                break;
+        case ACT_CREATE_MASTER: bTmp = TRUE; // NoBreak
+        case ACT_CREATE_FOLLOW: rOut += "Create Section ";
+                                rOut += bTmp ? "Master to " : "Follow from ";
+                                rOut += ((SwFrm*)pParam)->GetFrmId();
+                                break;
+        case ACT_DEL_MASTER:    bTmp = TRUE; // NoBreak
+        case ACT_DEL_FOLLOW:    rOut += "Delete Section ";
+                                rOut += bTmp ? "Master to " : "Follow from ";
+                                rOut += ((SwFrm*)pParam)->GetFrmId();
+                                break;
+    }
+}
+
+/* -----------------11.01.99 11:31-------------------
+ * SwImplProtocol::InsertFrm(..) nimmt eine neue FrmId zum Aufzeichnen auf,
+ * wenn pFrmIds==NULL, werden alle aufgezeichnet, sobald durch InsertFrm(..)
+ * pFrmIds angelegt wird, werden nur noch die enthaltenen FrmIds aufgezeichnet.
+ * --------------------------------------------------*/
+
+BOOL SwImplProtocol::InsertFrm( USHORT nId )
+{
+    if( !pFrmIds )
+        pFrmIds = new SvUShortsSort(5,5);
+    if( pFrmIds->Seek_Entry( nId ) )
+        return FALSE;
+    pFrmIds->Insert( nId );
+    return TRUE;
+}
+
+/* -----------------11.01.99 11:52-------------------
+ * SwImplProtocol::DeleteFrm(..) entfernt eine FrmId aus dem pFrmIds-Array,
+ * so dass diese Frame nicht mehr aufgezeichnet wird.
+ * --------------------------------------------------*/
+BOOL SwImplProtocol::DeleteFrm( USHORT nId )
+{
+    USHORT nPos;
+    if( !pFrmIds || !pFrmIds->Seek_Entry( nId, &nPos ) )
+        return FALSE;
+    pFrmIds->Remove( nPos );
+    return TRUE;
+}
+
+/* -----------------11.01.99 11:53-------------------
+ * SwEnterLeave::Ctor(..) wird vom eigentlichen (inline-)Kontruktor gerufen,
+ * wenn die Funktion aufgezeichnet werden soll.
+ * Die Aufgabe ist es abhaengig von der Funktion das richtige SwImplEnterLeave-Objekt
+ * zu erzeugen, alles weitere geschieht dann in dessen Ctor/Dtor.
+ * --------------------------------------------------*/
+void SwEnterLeave::Ctor( const SwFrm* pFrm, ULONG nFunc, ULONG nAct, void* pPar )
+{
+    switch( nFunc )
+    {
+        case PROT_ADJUSTN :
+        case PROT_GROW:
+        case PROT_SHRINK : pImpl = new SwSizeEnterLeave( pFrm, nFunc, nAct, pPar ); break;
+        case PROT_MOVE_FWD:
+        case PROT_MOVE_BWD : pImpl = new SwUpperEnterLeave( pFrm, nFunc, nAct, pPar ); break;
+        case PROT_FRMCHANGES : pImpl = new SwFrmChangesLeave( pFrm, nFunc, nAct, pPar ); break;
+        default: pImpl = new SwImplEnterLeave( pFrm, nFunc, nAct, pPar ); break;
+    }
+    pImpl->Enter();
+}
+
+/* -----------------11.01.99 11:56-------------------
+ * SwEnterLeave::Dtor() ruft lediglich den Destruktor des SwImplEnterLeave-Objekts,
+ * ist nur deshalb nicht inline, damit die SwImplEnterLeave-Definition nicht
+ * im dbg_lay.hxx zu stehen braucht.
+ * --------------------------------------------------*/
+
+void SwEnterLeave::Dtor()
+{
+    if( pImpl )
+    {
+        pImpl->Leave();
+        delete pImpl;
+    }
+}
+
+void SwImplEnterLeave::Enter()
+{
+    SwProtocol::Record( pFrm, nFunction, ACT_START, pParam );
+}
+
+void SwImplEnterLeave::Leave()
+{
+    SwProtocol::Record( pFrm, nFunction, ACT_END, pParam );
+}
+
+void SwSizeEnterLeave::Leave()
+{
+    nFrmHeight = pFrm->Frm().Height() - nFrmHeight;
+    SwProtocol::Record( pFrm, nFunction, ACT_END, &nFrmHeight );
+}
+
+void SwUpperEnterLeave::Enter()
+{
+    nFrmId = pFrm->GetUpper() ? pFrm->GetUpper()->GetFrmId() : 0;
+    SwProtocol::Record( pFrm, nFunction, ACT_START, &nFrmId );
+}
+
+void SwUpperEnterLeave::Leave()
+{
+    nFrmId = pFrm->GetUpper() ? pFrm->GetUpper()->GetFrmId() : 0;
+    SwProtocol::Record( pFrm, nFunction, ACT_END, &nFrmId );
+}
+
+void SwFrmChangesLeave::Enter()
+{
+}
+
+void SwFrmChangesLeave::Leave()
+{
+    if( pFrm->Frm() != aFrm )
+        SwProtocol::Record( pFrm, PROT_FRMCHANGES, 0, &aFrm );
+}
+
+
diff --git a/sw/source/core/layout/findfrm.cxx b/sw/source/core/layout/findfrm.cxx
new file mode 100644
index 000000000000..528cb399aae1
--- /dev/null
+++ b/sw/source/core/layout/findfrm.cxx
@@ -0,0 +1,1116 @@
+/*************************************************************************
+ *
+ *  $RCSfile: findfrm.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:22 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "pagefrm.hxx"
+#include "rootfrm.hxx"
+#include "cntfrm.hxx"
+#include "node.hxx"
+#include "doc.hxx"
+#include "frmtool.hxx"
+#include "flyfrm.hxx"
+
+#ifndef _FRMFMT_HXX //autogen
+#include 
+#endif
+#include "tabfrm.hxx"
+#include "sectfrm.hxx"
+#include "flyfrms.hxx"
+#include "ftnfrm.hxx"
+#include "txtftn.hxx"
+#include "fmtftn.hxx"
+
+/*************************************************************************
+|*
+|*  FindBodyCont, FindLastBodyCntnt()
+|*
+|*  Beschreibung        Sucht den ersten/letzten CntntFrm im BodyText unterhalb
+|*      der Seite.
+|*  Ersterstellung      MA 15. Feb. 93
+|*  Letzte Aenderung    MA 18. Apr. 94
+|*
+|*************************************************************************/
+SwLayoutFrm *SwFtnBossFrm::FindBodyCont()
+{
+    SwFrm *pLay = Lower();
+    while ( pLay && !pLay->IsBodyFrm() )
+        pLay = pLay->GetNext();
+    return (SwLayoutFrm*)pLay;
+}
+
+SwCntntFrm *SwPageFrm::FindLastBodyCntnt()
+{
+    SwCntntFrm *pRet = FindFirstBodyCntnt();
+    SwCntntFrm *pNxt = pRet;
+    while ( pNxt && pNxt->IsInDocBody() && IsAnLower( pNxt ) )
+    {   pRet = pNxt;
+        pNxt = pNxt->FindNextCnt();
+    }
+    return pRet;
+}
+
+/*************************************************************************
+|*
+|*  SwLayoutFrm::ContainsCntnt
+|*
+|*  Beschreibung            Prueft, ob der Frame irgendwo in seiner
+|*          untergeordneten Struktur einen oder mehrere CntntFrm's enthaelt;
+|*          Falls ja wird der erste gefundene CntntFrm zurueckgegeben.
+|*
+|*  Ersterstellung      MA 13. May. 92
+|*  Letzte Aenderung    MA 20. Apr. 94
+|*
+|*************************************************************************/
+
+const SwCntntFrm *SwLayoutFrm::ContainsCntnt() const
+{
+    //LayoutBlatt nach unten hin suchen und wenn dieses keinen Inhalt hat
+    //solange die weiteren Blatter abklappern bis Inhalt gefunden oder der
+    //this verlassen wird.
+    //Sections: Cntnt neben Sections wuerde so nicht gefunden (leere Section
+    //direct neben CntntFrm), deshalb muss fuer diese Aufwendiger rekursiv gesucht
+    //werden.
+
+    const SwLayoutFrm *pLayLeaf = this;
+    do
+    {
+        while ( (!pLayLeaf->IsSctFrm() || pLayLeaf == this ) &&
+                pLayLeaf->Lower() && pLayLeaf->Lower()->IsLayoutFrm() )
+            pLayLeaf = (SwLayoutFrm*)pLayLeaf->Lower();
+
+        if( pLayLeaf->IsSctFrm() && pLayLeaf != this )
+        {
+            const SwCntntFrm *pCnt = pLayLeaf->ContainsCntnt();
+            if( pCnt )
+                return pCnt;
+            if( pLayLeaf->GetNext() )
+            {
+                if( pLayLeaf->GetNext()->IsLayoutFrm() )
+                {
+                    pLayLeaf = (SwLayoutFrm*)pLayLeaf->GetNext();
+                    continue;
+                }
+                else
+                    return (SwCntntFrm*)pLayLeaf->GetNext();
+            }
+        }
+        else if ( pLayLeaf->Lower() )
+            return (SwCntntFrm*)pLayLeaf->Lower();
+
+        pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
+        if( !IsAnLower( pLayLeaf) )
+            return 0;
+    } while( pLayLeaf );
+    return 0;
+}
+
+/*************************************************************************
+|*
+|*  SwLayoutFrm::FirstCell
+|*
+|*  Beschreibung    ruft zunaechst ContainsAny auf, um in die innerste Zelle
+|*                  hineinzukommen. Dort hangelt es sich wieder hoch zum
+|*                  ersten SwCellFrm, seit es SectionFrms gibt, reicht kein
+|*                  ContainsCntnt()->GetUpper() mehr...
+|*  Ersterstellung      AMA 17. Mar. 99
+|*  Letzte Aenderung    AMA 17. Mar. 99
+|*
+|*************************************************************************/
+
+const SwCellFrm *SwLayoutFrm::FirstCell() const
+{
+    const SwFrm* pCnt = ContainsAny();
+    while( pCnt && !pCnt->IsCellFrm() )
+        pCnt = pCnt->GetUpper();
+    return (const SwCellFrm*)pCnt;
+}
+
+/*************************************************************************
+|*
+|*  SwLayoutFrm::ContainsAny
+|*
+|*  Beschreibung wie ContainsCntnt, nur dass nicht nur CntntFrms, sondern auch
+|*          Bereiche und Tabellen zurueckgegeben werden.
+|*  Ersterstellung      AMA 10. Mar. 99
+|*  Letzte Aenderung    AMA 10. Mar. 99
+|*
+|*************************************************************************/
+
+const SwFrm *SwLayoutFrm::ContainsAny() const
+{
+    //LayoutBlatt nach unten hin suchen und wenn dieses keinen Inhalt hat
+    //solange die weiteren Blatter abklappern bis Inhalt gefunden oder der
+    //this verlassen wird.
+    // Oder bis wir einen SectionFrm oder TabFrm gefunden haben
+
+    const SwLayoutFrm *pLayLeaf = this;
+    BOOL bNoFtn = IsSctFrm();
+    do
+    {
+        while ( ( (!pLayLeaf->IsSctFrm() && !pLayLeaf->IsTabFrm())
+                 || pLayLeaf == this ) &&
+                pLayLeaf->Lower() && pLayLeaf->Lower()->IsLayoutFrm() )
+            pLayLeaf = (SwLayoutFrm*)pLayLeaf->Lower();
+
+        if( ( pLayLeaf->IsTabFrm() || pLayLeaf->IsSctFrm() )
+            && pLayLeaf != this )
+        {
+            // Wir liefern jetzt auch "geloeschte" SectionFrms zurueck,
+            // damit diese beim SaveCntnt und RestoreCntnt mitgepflegt werden.
+            return pLayLeaf;
+#ifdef USED
+            const SwCntntFrm *pCnt = pLayLeaf->ContainsCntnt();
+            if( pCnt )
+                return pLayLeaf;
+            if( pLayLeaf->GetNext() )
+            {
+                if( pLayLeaf->GetNext()->IsLayoutFrm() )
+                {
+                    pLayLeaf = (SwLayoutFrm*)pLayLeaf->GetNext();
+                    continue;
+                }
+                else
+                    return (SwCntntFrm*)pLayLeaf->GetNext();
+            }
+#endif
+        }
+        else if ( pLayLeaf->Lower() )
+            return (SwCntntFrm*)pLayLeaf->Lower();
+
+        pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
+        if( bNoFtn && pLayLeaf && pLayLeaf->IsInFtn() )
+        {
+            do
+            {
+                pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
+            } while( pLayLeaf && pLayLeaf->IsInFtn() );
+        }
+        if( !IsAnLower( pLayLeaf) )
+            return 0;
+    } while( pLayLeaf );
+    return 0;
+}
+
+
+/*************************************************************************
+|*
+|*  SwFrm::GetLower()
+|*
+|*  Ersterstellung      MA 27. Jul. 92
+|*  Letzte Aenderung    MA 09. Oct. 97
+|*
+|*************************************************************************/
+const SwFrm* SwFrm::GetLower() const
+{
+    return IsLayoutFrm() ? ((SwLayoutFrm*)this)->Lower() : 0;
+}
+
+SwFrm* SwFrm::GetLower()
+{
+    return IsLayoutFrm() ? ((SwLayoutFrm*)this)->Lower() : 0;
+}
+
+/*************************************************************************
+|*
+|*  SwLayoutFrm::IsAnLower()
+|*
+|*  Ersterstellung      MA 18. Mar. 93
+|*  Letzte Aenderung    MA 18. Mar. 93
+|*
+|*************************************************************************/
+BOOL SwLayoutFrm::IsAnLower( const SwFrm *pAssumed ) const
+{
+    const SwFrm *pUp = pAssumed;
+    while ( pUp )
+    {
+        if ( pUp == this )
+            return TRUE;
+        if ( pUp->IsFlyFrm() )
+            pUp = ((SwFlyFrm*)pUp)->GetAnchor();
+        else
+            pUp = pUp->GetUpper();
+    }
+    return FALSE;
+}
+
+/*************************************************************************
+|*
+|*  SwFrm::GetPrevLayoutLeaf()
+|*
+|*  Beschreibung        Findet das vorhergehende Layout-Blatt. Ein Layout-
+|*      Blatt ist ein LayoutFrm, der keinen LayoutFrm in seinen Unterbaum hat;
+|*      genau gesagt, darf pLower kein LayoutFrm sein.
+|*      Anders ausgedrueckt: pLower darf 0 sein oder auf einen CntntFrm
+|*      zeigen.
+|*      pLower darf allerdings auf einen TabFrm zeigen, denn diese stehen
+|*      direkt neben den CntntFrms.
+|*  Ersterstellung      MA 29. May. 92
+|*  Letzte Aenderung    MA 30. Oct. 97
+|*
+|*************************************************************************/
+const SwFrm * MA_FASTCALL lcl_LastLower( const SwFrm *pFrm )
+{
+    const SwFrm *pLower = pFrm->GetLower();
+    if ( pLower )
+        while ( pLower->GetNext() )
+            pLower = pLower->GetNext();
+    return pLower;
+}
+
+const SwLayoutFrm *SwFrm::GetPrevLayoutLeaf() const
+{
+    const SwFrm       *pFrm = this;
+    const SwLayoutFrm *pLayoutFrm = 0;
+    const SwFrm       *p;
+    FASTBOOL bGoingUp = TRUE;
+    do {
+        FASTBOOL bGoingBwd = FALSE, bGoingDown = FALSE;
+        if( !(bGoingDown = (!bGoingUp && ( 0 != (p = ::lcl_LastLower( pFrm ))))) &&
+            !(bGoingBwd = (0 != (p = pFrm->IsFlyFrm() ? ((SwFlyFrm*)pFrm)->GetPrevLink()
+                                                      : pFrm->GetPrev()))) &&
+            !(bGoingUp = (0 != (p = pFrm->GetUpper()))))
+            return 0;
+        bGoingUp = !( bGoingBwd || bGoingDown );
+        pFrm = p;
+        p = pFrm->IsLayoutFrm() ? ((SwLayoutFrm*)pFrm)->Lower() : 0;
+    } while( (p && !p->IsFlowFrm()) ||
+             pFrm == this ||
+             0 == (pLayoutFrm = pFrm->IsLayoutFrm() ? (SwLayoutFrm*)pFrm:0) ||
+             pLayoutFrm->IsAnLower( this ) );
+
+    return pLayoutFrm;
+}
+/*************************************************************************
+|*
+|*  SwFrm::GetNextLayoutLeaf
+|*
+|*  Beschreibung        Findet das naechste Layout-Blatt. Ein Layout-Blatt
+|*          ist ein LayoutFrm, der kein LayoutFrm in seinen Unterbaum hat;
+|*          genau gesagt, darf pLower kein LayoutFrm sein.
+|*          Anders ausgedrueckt: pLower darf 0 sein oder auf einen CntntFrm
+|*          zeigen.
+|*          pLower darf allerdings auf einen TabFrm zeigen, denn diese stehen
+|*          direkt neben den CntntFrms.
+|*  Ersterstellung      MA 13. May. 92
+|*  Letzte Aenderung    MA 30. Oct. 97
+|*
+|*************************************************************************/
+const SwLayoutFrm *SwFrm::GetNextLayoutLeaf() const
+{
+    const SwFrm       *pFrm = this;
+    const SwLayoutFrm *pLayoutFrm = 0;
+    const SwFrm       *p;
+    FASTBOOL bGoingUp = FALSE;
+    do {
+        FASTBOOL bGoingFwd = FALSE, bGoingDown = FALSE;
+        if( !(bGoingDown = (!bGoingUp && ( 0 !=
+            (p = pFrm->IsLayoutFrm() ? ((SwLayoutFrm*)pFrm)->Lower() : 0)))) &&
+            !(bGoingFwd = (0 != (p = pFrm->IsFlyFrm() ? ((SwFlyFrm*)pFrm)->GetNextLink()
+                                                      : pFrm->GetNext()))) &&
+            !(bGoingUp = (0 != (p = pFrm->GetUpper()))))
+            return 0;
+        bGoingUp = !( bGoingFwd || bGoingDown );
+        pFrm = p;
+        p = pFrm->IsLayoutFrm() ? ((SwLayoutFrm*)pFrm)->Lower() : 0;
+    } while( (p && !p->IsFlowFrm()) ||
+             pFrm == this ||
+             0 == (pLayoutFrm = pFrm->IsLayoutFrm() ? (SwLayoutFrm*)pFrm:0 ) ||
+             pLayoutFrm->IsAnLower( this ) );
+
+    return pLayoutFrm;
+}
+
+/*************************************************************************
+|*
+|*  SwFrm::FindRootFrm(), FindTabFrm(), FindFtnFrm(), FindFlyFrm(),
+|*         FindPageFrm(), FindColFrm()
+|*
+|*  Ersterstellung      ??
+|*  Letzte Aenderung    MA 05. Sep. 93
+|*
+|*************************************************************************/
+SwRootFrm* SwFrm::FindRootFrm()
+{
+    SwDoc *pDoc = IsLayoutFrm() ? ((SwLayoutFrm*)this)->GetFmt()->GetDoc()
+                                : ((SwCntntFrm*)this)->GetNode()->GetDoc();
+    return pDoc->GetRootFrm();
+}
+
+SwPageFrm* SwFrm::FindPageFrm()
+{
+    SwFrm *pRet = this;
+    while ( pRet && !pRet->IsPageFrm() )
+    {
+        if ( pRet->GetUpper() )
+            pRet = pRet->GetUpper();
+        else if ( pRet->IsFlyFrm() )
+        {
+            if ( ((SwFlyFrm*)pRet)->IsFlyFreeFrm() )
+                pRet = ((SwFlyFreeFrm*)pRet)->GetPage();
+            else
+                pRet = ((SwFlyFrm*)pRet)->GetAnchor();
+        }
+        else
+            return 0;
+    }
+    return (SwPageFrm*)pRet;
+}
+
+SwFtnBossFrm* SwFrm::FindFtnBossFrm( BOOL bFootnotes )
+{
+    SwFrm *pRet = this;
+    // Innerhalb einer Tabelle gibt es keine Fussnotenbosse, auch spaltige
+    // Bereiche enthalten dort keine Fussnotentexte
+    if( pRet->IsInTab() )
+        pRet = pRet->FindTabFrm();
+    while ( pRet && !pRet->IsFtnBossFrm() )
+    {
+        if ( pRet->GetUpper() )
+            pRet = pRet->GetUpper();
+        else if ( pRet->IsFlyFrm() )
+        {
+            if ( ((SwFlyFrm*)pRet)->IsFlyFreeFrm() )
+                pRet = ((SwFlyFreeFrm*)pRet)->GetPage();
+            else
+                pRet = ((SwFlyFrm*)pRet)->GetAnchor();
+        }
+        else
+            return 0;
+    }
+    if( bFootnotes && pRet && pRet->IsColumnFrm() &&
+        !pRet->GetNext() && !pRet->GetPrev() )
+    {
+        SwSectionFrm* pSct = pRet->FindSctFrm();
+        ASSERT( pSct, "FindFtnBossFrm: Single column outside section?" );
+        if( !pSct->IsFtnAtEnd() )
+            return pSct->FindFtnBossFrm( TRUE );
+    }
+    return (SwFtnBossFrm*)pRet;
+}
+
+SwTabFrm* SwFrm::ImplFindTabFrm()
+{
+    SwFrm *pRet = this;
+    while ( !pRet->IsTabFrm() )
+    {
+        pRet = pRet->GetUpper();
+        if ( !pRet )
+            return 0;
+    }
+    return (SwTabFrm*)pRet;
+}
+
+SwSectionFrm* SwFrm::ImplFindSctFrm()
+{
+    SwFrm *pRet = this;
+    while ( !pRet->IsSctFrm() )
+    {
+        pRet = pRet->GetUpper();
+        if ( !pRet )
+            return 0;
+    }
+    return (SwSectionFrm*)pRet;
+}
+
+SwSectionFrm* SwFrm::ImplFindTopSctFrm()
+{
+    SwFrm *pRet = 0;
+    SwFrm *pTmp = this;
+    do
+    {   if( pTmp->IsSctFrm() )
+            pRet = pTmp;
+       pTmp = pTmp->GetUpper();
+    } while ( pTmp && pTmp->IsInSct() );
+    return (SwSectionFrm*)pRet;
+}
+
+SwFtnFrm *SwFrm::ImplFindFtnFrm()
+{
+    SwFrm *pRet = this;
+    while ( !pRet->IsFtnFrm() )
+    {
+        pRet = pRet->GetUpper();
+        if ( !pRet )
+            return 0;
+    }
+    return (SwFtnFrm*)pRet;
+}
+
+SwFlyFrm *SwFrm::ImplFindFlyFrm()
+{
+    const SwFrm *pRet = this;
+    do
+    {
+        if ( pRet->IsFlyFrm() )
+            return (SwFlyFrm*)pRet;
+        else
+            pRet = pRet->GetUpper();
+    } while ( pRet );
+    return 0;
+}
+
+SwFrm *SwFrm::FindColFrm()
+{
+    SwFrm *pFrm = this;
+    do
+    {   pFrm = pFrm->GetUpper();
+    } while ( pFrm && !pFrm->IsColumnFrm() );
+    return pFrm;
+}
+
+SwFrm* SwFrm::FindFooterOrHeader()
+{
+    SwFrm* pRet = this;
+    do
+    {   if ( pRet->GetType() & 0x0018 ) //Header und Footer
+            return pRet;
+        else if ( pRet->GetUpper() )
+            pRet = pRet->GetUpper();
+        else if ( pRet->IsFlyFrm() )
+            pRet = ((SwFlyFrm*)pRet)->GetAnchor();
+        else
+            return 0;
+    } while ( pRet );
+    return pRet;
+}
+
+const SwFtnFrm* SwFtnContFrm::FindFootNote() const
+{
+    const SwFtnFrm* pRet = (SwFtnFrm*)Lower();
+    if( pRet && !pRet->GetAttr()->GetFtn().IsEndNote() )
+        return pRet;
+    return NULL;
+}
+
+const SwFtnFrm* SwFtnContFrm::FindEndNote() const
+{
+    const SwFtnFrm* pRet = (SwFtnFrm*)Lower();
+    while( pRet && !pRet->GetAttr()->GetFtn().IsEndNote() )
+        pRet = (SwFtnFrm*)pRet->GetNext();
+    return pRet;
+}
+
+/*************************************************************************
+|*
+|*  SwFrmFrm::GetAttrSet()
+|*
+|*  Ersterstellung      MA 02. Aug. 93
+|*  Letzte Aenderung    MA 02. Aug. 93
+|*
+|*************************************************************************/
+const SwAttrSet* SwFrm::GetAttrSet() const
+{
+    if ( IsCntntFrm() )
+        return &((const SwCntntFrm*)this)->GetNode()->GetSwAttrSet();
+    else
+        return &((const SwLayoutFrm*)this)->GetFmt()->GetAttrSet();
+}
+
+SwAttrSet* SwFrm::GetAttrSet()
+{
+    if ( IsCntntFrm() )
+        return &((SwCntntFrm*)this)->GetNode()->GetSwAttrSet();
+    else
+        return (SwAttrSet*)&((SwLayoutFrm*)this)->GetFmt()->GetAttrSet();
+}
+
+/*************************************************************************
+|*
+|*  SwFrm::_FindNext(), _FindPrev(), InvalidateNextPos()
+|*         _FindNextCnt() geht in Tabellen und Bereiche hineinund liefert
+|*         nur SwCntntFrms.
+|*
+|*  Beschreibung        Invalidiert die Position des Naechsten Frames.
+|*      Dies ist der direkte Nachfolger, oder bei CntntFrm's der naechste
+|*      CntntFrm der im gleichen Fluss liegt wie ich:
+|*      - Body,
+|*      - Fussnoten,
+|*      - Bei Kopf-/Fussbereichen ist die Benachrichtigung nur innerhalb des
+|*        Bereiches weiterzuleiten.
+|*      - dito fuer Flys.
+|*      - Cntnts in Tabs halten sich ausschliesslich innerhalb ihrer Zelle
+|*        auf.
+|*      - Tabellen verhalten sich prinzipiell analog zu den Cntnts
+|*      - Bereiche ebenfalls
+|*  Ersterstellung      AK 14-Feb-1991
+|*  Letzte Aenderung    AMA 10. Mar. 99
+|*
+|*************************************************************************/
+
+// Diese Hilfsfunktion ist ein Aequivalent zur ImplGetNextCntntFrm()-Methode,
+// sie liefert allerdings neben ContentFrames auch TabFrms und SectionFrms.
+SwFrm* lcl_NextFrm( SwFrm* pFrm )
+{
+    SwFrm *pRet = 0;
+    FASTBOOL bGoingUp = FALSE;
+    do {
+        SwFrm *p;
+        FASTBOOL bGoingFwd = FALSE, bGoingDown = FALSE;
+        if( !(bGoingDown = (!bGoingUp && ( 0 !=
+             (p = pFrm->IsLayoutFrm() ? ((SwLayoutFrm*)pFrm)->Lower() : 0)))) &&
+            !(bGoingFwd = (0 != (p = pFrm->IsFlyFrm() ? ((SwFlyFrm*)pFrm)->GetNextLink()
+                                                      : pFrm->GetNext()))) &&
+            !(bGoingUp = (0 != (p = pFrm->GetUpper()))))
+            return 0;
+        bGoingUp = !(bGoingFwd || bGoingDown);
+        pFrm = p;
+    } while ( 0 == (pRet = ( ( pFrm->IsCntntFrm() || ( !bGoingUp &&
+            ( pFrm->IsTabFrm() || pFrm->IsSctFrm() ) ) )? pFrm : 0 ) ) );
+    return pRet;
+}
+
+SwFrm *SwFrm::_FindNext()
+{
+    BOOL bIgnoreTab = FALSE;
+    SwFrm *pThis = this;
+
+    if ( IsTabFrm() )
+    {
+        //Der letzte Cntnt der Tabelle wird
+        //gegriffen und dessen Nachfolger geliefert. Um die Spezialbeh.
+        //Fuer Tabellen (s.u.) auszuschalten wird bIgnoreTab gesetzt.
+        if ( ((SwTabFrm*)this)->GetFollow() )
+            return ((SwTabFrm*)this)->GetFollow();
+
+        pThis = ((SwTabFrm*)this)->FindLastCntnt();
+        if ( !pThis )
+            pThis = this;
+        bIgnoreTab = TRUE;
+    }
+    else if ( IsSctFrm() )
+    {
+        //Der letzte Cntnt des Bereichs wird gegriffen und dessen Nachfolger
+        // geliefert.
+        if ( ((SwSectionFrm*)this)->GetFollow() )
+            return ((SwSectionFrm*)this)->GetFollow();
+
+        pThis = ((SwSectionFrm*)this)->FindLastCntnt();
+        if ( !pThis )
+            pThis = this;
+    }
+    else if ( IsCntntFrm() )
+    {
+        if( ((SwCntntFrm*)this)->GetFollow() )
+            return ((SwCntntFrm*)this)->GetFollow();
+    }
+    else
+        return NULL;
+
+    SwFrm* pRet = NULL;
+    const BOOL bFtn  = pThis->IsInFtn();
+    if ( !bIgnoreTab && pThis->IsInTab() )
+    {
+        SwLayoutFrm *pUp = pThis->GetUpper();
+        while ( !pUp->IsCellFrm() )
+            pUp = pUp->GetUpper();
+        ASSERT( pUp, "Cntnt in Tabelle aber nicht in Zelle." );
+        SwFrm *pNxt = lcl_NextFrm( pThis );
+        if ( pUp->IsAnLower( pNxt ) )
+            pRet = pNxt;
+    }
+    else
+    {
+        const BOOL bBody = pThis->IsInDocBody();
+        SwFrm *pNxtCnt = lcl_NextFrm( pThis );
+        if ( pNxtCnt )
+        {
+            if ( bBody || bFtn )
+            {
+                while ( pNxtCnt )
+                {
+                    BOOL bEndn = IsInSct() && !IsSctFrm();
+                    if ( ( bBody && pNxtCnt->IsInDocBody() ) ||
+                         ( pNxtCnt->IsInFtn() && ( bFtn || ( bEndn && pNxtCnt->
+                           FindFtnFrm()->GetAttr()->GetFtn().IsEndNote() ) ) ) )
+                    {
+                        pRet = pNxtCnt->IsInTab() ? pNxtCnt->FindTabFrm()
+                                                    : (SwFrm*)pNxtCnt;
+                        break;
+                    }
+                    pNxtCnt = lcl_NextFrm( pNxtCnt );
+                }
+            }
+            else if ( pThis->IsInFly() )
+            {
+                pRet = pNxtCnt->IsInTab() ? pNxtCnt->FindTabFrm()
+                                            : (SwFrm*)pNxtCnt;
+            }
+            else    //Fuss-/oder Kopfbereich
+            {
+                const SwFrm *pUp = pThis->GetUpper();
+                const SwFrm *pCntUp = pNxtCnt->GetUpper();
+                while ( pUp && pUp->GetUpper() &&
+                        !pUp->IsHeaderFrm() && !pUp->IsFooterFrm() )
+                    pUp = pUp->GetUpper();
+                while ( pCntUp && pCntUp->GetUpper() &&
+                        !pCntUp->IsHeaderFrm() && !pCntUp->IsFooterFrm() )
+                    pCntUp = pCntUp->GetUpper();
+                if ( pCntUp == pUp )
+                {
+                    pRet = pNxtCnt->IsInTab() ? pNxtCnt->FindTabFrm()
+                                                : (SwFrm*)pNxtCnt;
+                }
+            }
+        }
+    }
+    if( pRet && pRet->IsInSct() )
+    {
+        SwSectionFrm* pSct = pRet->FindSctFrm();
+        //Fussnoten in spaltigen Rahmen duerfen nicht den Bereich
+        //liefern, der die Fussnoten umfasst
+        if( !pSct->IsAnLower( this ) &&
+            (!bFtn || pSct->IsInFtn() ) )
+            return pSct;
+    }
+    return pRet;
+}
+
+SwCntntFrm *SwFrm::_FindNextCnt()
+{
+    SwFrm *pThis = this;
+
+    if ( IsTabFrm() )
+    {
+        if ( ((SwTabFrm*)this)->GetFollow() )
+        {
+            pThis = ((SwTabFrm*)this)->GetFollow()->ContainsCntnt();
+            if( pThis )
+                return (SwCntntFrm*)pThis;
+        }
+        pThis = ((SwTabFrm*)this)->FindLastCntnt();
+        if ( !pThis )
+            return 0;
+    }
+    else if ( IsSctFrm() )
+    {
+        if ( ((SwSectionFrm*)this)->GetFollow() )
+        {
+            pThis = ((SwSectionFrm*)this)->GetFollow()->ContainsCntnt();
+            if( pThis )
+                return (SwCntntFrm*)pThis;
+        }
+        pThis = ((SwSectionFrm*)this)->FindLastCntnt();
+        if ( !pThis )
+            return 0;
+    }
+    else if ( IsCntntFrm() && ((SwCntntFrm*)this)->GetFollow() )
+        return ((SwCntntFrm*)this)->GetFollow();
+
+    if ( pThis->IsCntntFrm() )
+    {
+        const BOOL bBody = pThis->IsInDocBody();
+        const BOOL bFtn  = pThis->IsInFtn();
+        SwCntntFrm *pNxtCnt = ((SwCntntFrm*)pThis)->GetNextCntntFrm();
+        if ( pNxtCnt )
+        {
+            if ( bBody || bFtn )
+            {
+                while ( pNxtCnt )
+                {
+                    if ( (bBody && pNxtCnt->IsInDocBody()) ||
+                         (bFtn  && pNxtCnt->IsInFtn()) )
+                        return pNxtCnt;
+                    pNxtCnt = pNxtCnt->GetNextCntntFrm();
+                }
+            }
+            else if ( pThis->IsInFly() )
+                return pNxtCnt;
+            else    //Fuss-/oder Kopfbereich
+            {
+                const SwFrm *pUp = pThis->GetUpper();
+                const SwFrm *pCntUp = pNxtCnt->GetUpper();
+                while ( pUp && pUp->GetUpper() &&
+                        !pUp->IsHeaderFrm() && !pUp->IsFooterFrm() )
+                    pUp = pUp->GetUpper();
+                while ( pCntUp && pCntUp->GetUpper() &&
+                        !pCntUp->IsHeaderFrm() && !pCntUp->IsFooterFrm() )
+                    pCntUp = pCntUp->GetUpper();
+                if ( pCntUp == pUp )
+                    return pNxtCnt;
+            }
+        }
+    }
+    return 0;
+}
+
+SwFrm *SwFrm::_FindPrev()
+{
+    BOOL bIgnoreTab = FALSE;
+    SwFrm *pThis = this;
+
+    if ( IsTabFrm() )
+    {
+        //Der erste Cntnt der Tabelle wird
+        //gegriffen und dessen Vorgaenger geliefert. Um die Spezialbeh.
+        //Fuer Tabellen (s.u.) auszuschalten wird bIgnoreTab gesetzt.
+        pThis = ((SwTabFrm*)this)->ContainsCntnt();
+        bIgnoreTab = TRUE;
+    }
+
+    if ( pThis->IsCntntFrm() )
+    {
+        SwCntntFrm *pPrvCnt = ((SwCntntFrm*)pThis)->GetPrevCntntFrm();
+        if( !pPrvCnt )
+            return 0;
+        if ( !bIgnoreTab && pThis->IsInTab() )
+        {
+            SwLayoutFrm *pUp = pThis->GetUpper();
+            while ( !pUp->IsCellFrm() )
+                pUp = pUp->GetUpper();
+            ASSERT( pUp, "Cntnt in Tabelle aber nicht in Zelle." );
+            if ( pUp->IsAnLower( pPrvCnt ) )
+                return pPrvCnt;
+        }
+        else
+        {
+            SwFrm* pRet;
+            const BOOL bBody = pThis->IsInDocBody();
+            const BOOL bFtn  = bBody ? FALSE : pThis->IsInFtn();
+            if ( bBody || bFtn )
+            {
+                while ( pPrvCnt )
+                {
+                    if ( (bBody && pPrvCnt->IsInDocBody()) ||
+                            (bFtn   && pPrvCnt->IsInFtn()) )
+                    {
+                        pRet = pPrvCnt->IsInTab() ? pPrvCnt->FindTabFrm()
+                                                  : (SwFrm*)pPrvCnt;
+                        return pRet;
+                    }
+                    pPrvCnt = pPrvCnt->GetPrevCntntFrm();
+                }
+            }
+            else if ( pThis->IsInFly() )
+            {
+                pRet = pPrvCnt->IsInTab() ? pPrvCnt->FindTabFrm()
+                                            : (SwFrm*)pPrvCnt;
+                return pRet;
+            }
+            else    //Fuss-/oder Kopfbereich oder Fly
+            {
+                const SwFrm *pUp = pThis->GetUpper();
+                const SwFrm *pCntUp = pPrvCnt->GetUpper();
+                while ( pUp && pUp->GetUpper() &&
+                        !pUp->IsHeaderFrm() && !pUp->IsFooterFrm() )
+                    pUp = pUp->GetUpper();
+                while ( pCntUp && pCntUp->GetUpper() )
+                    pCntUp = pCntUp->GetUpper();
+                if ( pCntUp == pUp )
+                {
+                    pRet = pPrvCnt->IsInTab() ? pPrvCnt->FindTabFrm()
+                                                : (SwFrm*)pPrvCnt;
+                    return pRet;
+                }
+            }
+        }
+    }
+    return 0;
+}
+
+void SwFrm::ImplInvalidateNextPos( BOOL bNoFtn )
+{
+    SwFrm *pFrm;
+    if ( 0 != (pFrm = _FindNext()) )
+    {
+        if( pFrm->IsSctFrm() )
+        {
+            while( pFrm && pFrm->IsSctFrm() )
+            {
+                if( ((SwSectionFrm*)pFrm)->GetSection() )
+                {
+                    SwFrm* pTmp = ((SwSectionFrm*)pFrm)->ContainsAny();
+                    if( pTmp )
+                        pTmp->_InvalidatePos();
+                    else if( !bNoFtn )
+                        ((SwSectionFrm*)pFrm)->InvalidateFtnPos();
+                    if( !IsInSct() || FindSctFrm()->GetFollow() != pFrm )
+                        pFrm->InvalidatePos();
+                    return;
+                }
+                pFrm = pFrm->FindNext();
+            }
+            if( pFrm )
+            {
+                if ( pFrm->IsSctFrm())
+                { // Damit der Inhalt eines Bereichs die Chance erhaelt,
+                  // die Seite zu wechseln, muss er ebenfalls invalidiert werden.
+                    SwFrm* pTmp = ((SwSectionFrm*)pFrm)->ContainsAny();
+                    if( pTmp )
+                        pTmp->_InvalidatePos();
+                    if( !IsInSct() || FindSctFrm()->GetFollow() != pFrm )
+                        pFrm->InvalidatePos();
+                }
+                else
+                    pFrm->InvalidatePos();
+            }
+        }
+        else
+            pFrm->InvalidatePos();
+    }
+}
+
+/*************************************************************************
+|*
+|*    lcl_IsInColSect()
+|*      liefert nur TRUE, wenn der Frame _direkt_ in einem spaltigen Bereich steht,
+|*      nicht etwa, wenn er in einer Tabelle steht, die in einem spaltigen Bereich ist.
+|*
+|*************************************************************************/
+
+BOOL lcl_IsInColSct( const SwFrm *pUp )
+{
+    BOOL bRet = FALSE;
+    while( pUp )
+    {
+        if( pUp->IsColumnFrm() )
+            bRet = TRUE;
+        else if( pUp->IsSctFrm() )
+            return bRet;
+        else if( pUp->IsTabFrm() )
+            return FALSE;
+        pUp = pUp->GetUpper();
+    }
+    return FALSE;
+}
+
+/*************************************************************************
+|*
+|*    SwFrm::IsMoveable();
+|*
+|*    Ersterstellung    MA 09. Mar. 93
+|*    Letzte Aenderung  MA 05. May. 95
+|*
+|*************************************************************************/
+BOOL SwFrm::IsMoveable() const
+{
+    if ( IsFlowFrm() )
+    {
+        if( IsInSct() && lcl_IsInColSct( GetUpper() ) )
+            return TRUE;
+        if( IsInFly() || IsInDocBody() || IsInFtn() || IsInSct() )
+        {
+            if ( IsInTab() && !IsTabFrm() )
+                return FALSE;
+            BOOL bRet = TRUE;
+            if ( IsInFly() )
+            {
+                //Wenn der Fly noch einen Follow hat ist der Inhalt auf jeden
+                //Fall moveable
+                if ( !((SwFlyFrm*)FindFlyFrm())->GetNextLink() )
+                {
+                    //Fuer Inhalt innerhab von Spaltigen Rahmen ist nur der Inhalt
+                    //der letzten Spalte nicht moveable.
+                    const SwFrm *pCol = GetUpper();
+                    while ( pCol && !pCol->IsColumnFrm() )
+                        pCol = pCol->GetUpper();
+                    if ( !pCol || (pCol && !pCol->GetNext()) )
+                        bRet = FALSE;
+                }
+            }
+            return bRet;
+        }
+    }
+    return FALSE;
+}
+
+/*************************************************************************
+|*
+|*    SwFrm::ImplGetNextCntntFrm(), ImplGetPrevCntntFrm()
+|*
+|*      Rueckwaertswandern im Baum: Den untergeordneten Frm greifen,
+|*      wenn es einen gibt und nicht gerade zuvor um eine Ebene
+|*      aufgestiegen wurde (das wuerde zu einem endlosen Auf und Ab
+|*      fuehren!). Damit wird sichergestellt, dass beim
+|*      Rueckwaertswandern alle Unterbaeume durchsucht werden. Wenn
+|*      abgestiegen wurde, wird zuerst an das Ende der Kette gegangen,
+|*      weil im weiteren ja vom letzten Frm innerhalb eines anderen
+|*      Frms rueckwaerts gegangen wird.
+|*      Vorwaetzwander funktioniert analog.
+|*
+|*    Ersterstellung    ??
+|*    Letzte Aenderung  MA 30. Oct. 97
+|*
+|*************************************************************************/
+
+
+// Achtung: Fixes in ImplGetNextCntntFrm() muessen moeglicherweise auch in
+// die weiter oben stehende Methode lcl_NextFrm(..) eingepflegt werden
+const SwCntntFrm *SwCntntFrm::ImplGetNextCntntFrm() const
+{
+    const SwFrm *pFrm = this;
+    const SwCntntFrm *pCntntFrm = 0;
+    FASTBOOL bGoingUp = FALSE;
+    do {
+        const SwFrm *p;
+        FASTBOOL bGoingFwd = FALSE, bGoingDown = FALSE;
+        if( !(bGoingDown = (!bGoingUp && ( 0 !=
+             (p = pFrm->IsLayoutFrm() ? ((SwLayoutFrm*)pFrm)->Lower() : 0)))) &&
+            !(bGoingFwd = (0 != (p = pFrm->IsFlyFrm() ? ((SwFlyFrm*)pFrm)->GetNextLink()
+                                                      : pFrm->GetNext()))) &&
+            !(bGoingUp = (0 != (p = pFrm->GetUpper()))))
+            return 0;
+        bGoingUp = !(bGoingFwd || bGoingDown);
+        pFrm = p;
+    } while ( 0 == (pCntntFrm = (pFrm->IsCntntFrm() ? (SwCntntFrm*)pFrm:0) ));
+    return pCntntFrm;
+
+}
+
+const SwCntntFrm *SwCntntFrm::ImplGetPrevCntntFrm() const
+{
+    const SwFrm *pFrm = this;
+    const SwCntntFrm *pCntntFrm = 0;
+    FASTBOOL bGoingUp = FALSE;
+    do {
+        const SwFrm *p;
+        FASTBOOL bGoingBack = FALSE, bGoingDown = FALSE;
+        if( !(bGoingDown = (!bGoingUp && (0 !=
+             (p = pFrm->IsLayoutFrm() ? ((SwLayoutFrm*)pFrm)->Lower() : 0)))) &&
+            !(bGoingBack = (0 != (p = pFrm->IsFlyFrm() ? ((SwFlyFrm*)pFrm)->GetPrevLink()
+                                                       : pFrm->GetPrev()))) &&
+            !(bGoingUp = (0 != (p = pFrm->GetUpper()))))
+            return 0;
+        bGoingUp = !(bGoingBack || bGoingDown);
+        if( bGoingDown && p )
+            while ( p->GetNext() )
+                p = p->GetNext();
+        pFrm = p;
+    } while ( 0 == (pCntntFrm = (pFrm->IsCntntFrm() ? (SwCntntFrm*)pFrm:0) ));
+    return pCntntFrm;
+}
+
+/*************************************************************************
+|*
+|*    SwFrm::SetInfFlags();
+|*
+|*    Ersterstellung    MA 05. Apr. 94
+|*    Letzte Aenderung  MA 05. Apr. 94
+|*
+|*************************************************************************/
+void SwFrm::SetInfFlags()
+{
+    if ( !IsFlyFrm() && !GetUpper() ) //noch nicht gepastet, keine Informationen
+        return;                       //lieferbar
+
+    bInfInvalid = bInfBody = bInfTab = bInfFly = bInfFtn = bInfSct = FALSE;
+#ifndef PRODUCT
+    BOOL bIsInTab = FALSE;
+#endif
+
+    SwFrm *pFrm = this;
+    if( IsFtnContFrm() )
+        bInfFtn = TRUE;
+    do
+    {   // bInfBody wird nur am Seitenbody, nicht im ColumnBody gesetzt
+        if ( pFrm->IsBodyFrm() && !bInfFtn && pFrm->GetUpper()
+             && pFrm->GetUpper()->IsPageFrm() )
+            bInfBody = TRUE;
+        else if ( pFrm->IsTabFrm() || pFrm->IsCellFrm() )
+        {
+#ifndef PRODUCT
+            if( pFrm->IsTabFrm() )
+            {
+                ASSERT( !bIsInTab, "Table in table: Not implemented." );
+                bIsInTab = TRUE;
+            }
+#endif
+            bInfTab = TRUE;
+        }
+        else if ( pFrm->IsFlyFrm() )
+            bInfFly = TRUE;
+        else if ( pFrm->IsSctFrm() )
+            bInfSct = TRUE;
+        else if ( pFrm->IsFtnFrm() )
+            bInfFtn = TRUE;
+
+//MA: 06. Apr. 94, oberhalb eines Fly geht es nicht weiter!
+//      if ( pFrm->IsFlyFrm() )
+//          pFrm = ((SwFlyFrm*)pFrm)->GetAnchor();
+//      else
+            pFrm = pFrm->GetUpper();
+
+    } while ( pFrm && !pFrm->IsPageFrm() ); //Oberhalb der Seite kommt nix
+}
+
+/*************************************************************************
+|*
+|*    SwFrm::HasFixSize()
+|*
+|*    Ersterstellung    MA 08. Apr. 94
+|*    Letzte Aenderung  MA 08. Apr. 94
+|*
+|*************************************************************************/
+BOOL SwFrm::HasFixSize( const SzPtr pSize ) const
+{
+    if ( pFIXSIZE == pSize )
+        return TRUE;
+
+    SzPtr pVar = pVARSIZE;
+    return ((pSize == pHeight) && bFixHeight && pVar == pHeight) ||
+           ((pSize == pWidth) && bFixWidth && pVar == pWidth);
+}
+
+
diff --git a/sw/source/core/layout/flowfrm.cxx b/sw/source/core/layout/flowfrm.cxx
new file mode 100644
index 000000000000..3774595d09b1
--- /dev/null
+++ b/sw/source/core/layout/flowfrm.cxx
@@ -0,0 +1,1837 @@
+/*************************************************************************
+ *
+ *  $RCSfile: flowfrm.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:22 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "pam.hxx"
+#include "swtable.hxx"
+#include "frame.hxx"
+#include "pagefrm.hxx"
+#include "flyfrm.hxx"
+#include "viewsh.hxx"
+#include "doc.hxx"
+#include "viewimp.hxx"
+#include "dflyobj.hxx"
+#include "frmtool.hxx"
+#include "dcontact.hxx"
+
+#ifndef _SVX_BRKITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_KEEPITEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _FMTSRND_HXX //autogen
+#include 
+#endif
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _FMTPDSC_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_ULSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _NODE_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFTN_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFTN_HXX //autogen
+#include 
+#endif
+
+#include "ftnfrm.hxx"
+#include "txtfrm.hxx"
+#include "tabfrm.hxx"
+#include "pagedesc.hxx"
+#include "layact.hxx"
+#include "frmsh.hxx"
+#include "fmtornt.hxx"
+#include "flyfrms.hxx"
+#include "sectfrm.hxx"
+#include "section.hxx"
+#include "dbg_lay.hxx"
+#include "lineinfo.hxx"
+
+BOOL SwFlowFrm::bMoveBwdJump = FALSE;
+
+
+/*************************************************************************
+|*
+|*  SwFlowFrm::SwFlowFrm()
+|*
+|*  Ersterstellung      MA 26. Apr. 95
+|*  Letzte Aenderung    MA 26. Apr. 95
+|*
+|*************************************************************************/
+
+
+SwFlowFrm::SwFlowFrm( SwFrm &rFrm ) :
+    rThis( rFrm ),
+    pFollow( 0 )
+{
+    bLockJoin = bIsFollow = bCntntLock = bOwnFtnNum = bFtnLock = FALSE;
+}
+
+/*************************************************************************
+|*
+|*  SwFlowFrm::IsKeepFwdMoveAllowed()
+|*
+|*  Ersterstellung      MA 20. Jul. 94
+|*  Letzte Aenderung    MA 16. May. 95
+|*
+|*************************************************************************/
+
+
+BOOL SwFlowFrm::IsKeepFwdMoveAllowed()
+{
+    //Wenn der Vorgaenger das KeepAttribut traegt und auch dessen
+    //Vorgaenger usw. bis zum ersten der Kette und fuer diesen das
+    //IsFwdMoveAllowed ein FALSE liefert, so ist das Moven eben nicht erlaubt.
+    SwFrm *pFrm = &rThis;
+    if ( !pFrm->IsInFtn() )
+        do
+        {   if ( pFrm->GetAttrSet()->GetKeep().GetValue() )
+                pFrm = pFrm->GetIndPrev();
+            else
+                return TRUE;
+        } while ( pFrm );
+
+                  //Siehe IsFwdMoveAllowed()
+    return pFrm ? pFrm->GetIndPrev() != 0 : FALSE;
+}
+
+/*************************************************************************
+|*
+|*    SwFlowFrm::CheckKeep()
+|*
+|*    Beschreibung
+|*    Ersterstellung    MA 20. Jun. 95
+|*    Letzte Aenderung  MA 09. Apr. 97
+|*
+|*************************************************************************/
+
+
+void SwFlowFrm::CheckKeep()
+{
+    //Den 'letzten' Vorgaenger mit KeepAttribut anstossen, denn
+    //die ganze Truppe koennte zuruckrutschen.
+    SwFrm *pPre = rThis.GetIndPrev();
+    if( pPre->IsSctFrm() )
+    {
+        SwFrm *pLast = ((SwSectionFrm*)pPre)->FindLastCntnt();
+        if( pLast && pLast->FindSctFrm() == pPre )
+            pPre = pLast;
+        else
+            return;
+    }
+    SwFrm* pTmp;
+    BOOL bKeep;
+    while ( TRUE == (bKeep = pPre->GetAttrSet()->GetKeep().GetValue()) &&
+            0 != ( pTmp = pPre->GetIndPrev() ) )
+    {
+        if( pTmp->IsSctFrm() )
+        {
+            SwFrm *pLast = ((SwSectionFrm*)pTmp)->FindLastCntnt();
+            if( pLast && pLast->FindSctFrm() == pTmp )
+                pTmp = pLast;
+            else
+                break;
+        }
+        pPre = pTmp;
+    }
+    if ( bKeep )
+        pPre->InvalidatePos();
+}
+
+/*************************************************************************
+|*
+|*  SwFlowFrm::IsKeep()
+|*
+|*  Ersterstellung      MA 09. Apr. 97
+|*  Letzte Aenderung    MA 09. Apr. 97
+|*
+|*************************************************************************/
+
+
+BOOL SwFlowFrm::IsKeep( const SwBorderAttrs &rAttrs ) const
+{
+    BOOL bKeep = !rThis.IsInFtn() && rAttrs.GetAttrSet().GetKeep().GetValue();
+    //Keep Zaehlt nicht wenn die Umbrueche dagegen sprechen.
+    if ( bKeep )
+    {
+        switch ( rAttrs.GetAttrSet().GetBreak().GetBreak() )
+        {
+            case SVX_BREAK_COLUMN_AFTER:
+            case SVX_BREAK_COLUMN_BOTH:
+            case SVX_BREAK_PAGE_AFTER:
+            case SVX_BREAK_PAGE_BOTH:
+                bKeep = FALSE;
+        }
+        if ( bKeep )
+        {
+            SwFrm *pNxt;
+            if( 0 != (pNxt = rThis.FindNextCnt()) &&
+                (!pFollow || pNxt != pFollow->GetFrm()))
+            {
+                const SwAttrSet &rSet = *pNxt->GetAttrSet();
+                if ( rSet.GetPageDesc().GetPageDesc() )
+                    bKeep = FALSE;
+                else switch ( rSet.GetBreak().GetBreak() )
+                {
+                    case SVX_BREAK_COLUMN_BEFORE:
+                    case SVX_BREAK_COLUMN_BOTH:
+                    case SVX_BREAK_PAGE_BEFORE:
+                    case SVX_BREAK_PAGE_BOTH:
+                        bKeep = FALSE;
+                }
+            }
+        }
+    }
+    return bKeep;
+}
+
+/*************************************************************************
+|*
+|*  SwFlowFrm::BwdMoveNecessary()
+|*
+|*  Ersterstellung      MA 20. Jul. 94
+|*  Letzte Aenderung    MA 02. May. 96
+|*
+|*************************************************************************/
+
+
+BYTE SwFlowFrm::BwdMoveNecessary( const SwPageFrm *pPage, const SwRect &rRect )
+{
+    // Der return-Wert entscheidet mit,
+    // ob auf Zurueckgeflossen werden muss, (3)
+    // ob das gute alte WouldFit gerufen werden kann (0, 1)
+    // oder ob ein Umhaengen und eine Probeformatierung sinnvoll ist (2)
+    // dabei bedeutet Bit 1, dass Objekte an mir selbst verankert sind
+    // und Bit 2, dass ich anderen Objekten ausweichen muss.
+
+    //Wenn ein SurroundObj, dass einen Umfluss wuenscht mit dem Rect ueberlappt
+    //ist der Fluss notwendig (weil die Verhaeltnisse nicht geschaetzt werden
+    //koennen), es kann allerdings ggf. eine TestFormatierung stattfinden.
+    //Wenn das SurroundObj ein Fly ist und ich selbst ein Lower bin oder der Fly
+    //Lower von mir ist, so spielt er keine Rolle.
+    //Wenn das SurroundObj in einem zeichengebunden Fly verankert ist, und ich
+    //selbst nicht Lower dieses Zeichengebundenen Flys bin, so spielt der Fly
+    //keine Rolle.
+    //#32639# Wenn das Objekt bei mir verankert ist kann ich es
+    //vernachlaessigen, weil es hoechstwahrscheinlich (!?) mitfliesst,
+    //eine TestFormatierung ist dann allerdings nicht erlaubt!
+    BYTE nRet = 0;
+    SwFlowFrm *pTmp = this;
+    do
+    {   // Wenn an uns oder einem Follow Objekte haengen, so
+        // kann keine ProbeFormatierung stattfinden, da absatzgebundene
+        // nicht richtig beruecksichtigt wuerden und zeichengebundene sollten
+        // gar nicht zur Probe formatiert werden.
+        if( pTmp->GetFrm()->GetDrawObjs() )
+            nRet = 1;
+        pTmp = pTmp->GetFollow();
+    } while ( !nRet && pTmp );
+    if ( pPage->GetSortedObjs() )
+    {
+        const SwSortDrawObjs &rObjs = *pPage->GetSortedObjs();
+        ULONG nIndex = ULONG_MAX;
+        for ( USHORT i = 0; nRet < 3 && i < rObjs.Count(); ++i )
+        {
+            SdrObject *pObj = rObjs[i];
+            SdrObjUserCall *pUserCall;
+            const SwFrmFmt *pFmt = pObj->IsWriterFlyFrame() ?
+                ((SwVirtFlyDrawObj*)pObj)->GetFmt() :
+                ((SwContact*)(pUserCall = GetUserCall(pObj)))->GetFmt();
+            const SwRect aRect( pObj->GetBoundRect() );
+            if ( aRect.IsOver( rRect ) &&
+                 pFmt->GetSurround().GetSurround() != SURROUND_THROUGHT )
+            {
+                if( rThis.IsLayoutFrm() && //Fly Lower von This?
+                    Is_Lower_Of( &rThis, pObj ) )
+                    continue;
+                const SwFrm* pAnchor;
+                if( pObj->IsWriterFlyFrame() )
+                {
+                    const SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+                    if ( pFly->IsAnLower( &rThis ) )//This Lower vom Fly?
+                        continue;
+                    pAnchor = pFly->GetAnchor();
+                }
+                else
+                    pAnchor = ((SwDrawContact*)pUserCall)->GetAnchor();
+
+                if ( pAnchor == &rThis )
+                {
+                    nRet |= 1;
+                    continue;
+                }
+
+                //Nicht wenn das Objekt im Textfluss hinter mir verankert ist,
+                //denn dann weiche ich ihm nicht aus.
+                if ( ::IsFrmInSameKontext( pAnchor, &rThis ) )
+                {
+                    if ( pFmt->GetAnchor().GetAnchorId() == FLY_AT_CNTNT )
+                    {
+                        // Den Index des anderen erhalten wir immer ueber das Ankerattr.
+                        ULONG nTmpIndex = pFmt->GetAnchor().GetCntntAnchor()->nNode.GetIndex();
+                        // Jetzt wird noch ueberprueft, ob der aktuelle Absatz vor dem
+                        // Anker des verdraengenden Objekts im Text steht, dann wird
+                        // nicht ausgewichen.
+                        // Der Index wird moeglichst ueber einen SwFmtAnchor ermittelt,
+                        // da sonst recht teuer.
+                        if( ULONG_MAX == nIndex )
+                        {
+                            const SwNode *pNode;
+                            if ( rThis.IsCntntFrm() )
+                                pNode = ((SwCntntFrm&)rThis).GetNode();
+                            else if( rThis.IsSctFrm() )
+                                pNode = ((SwSectionFmt*)((SwSectionFrm&)rThis).
+                                        GetFmt())->GetSectionNode();
+                            else
+                            {
+                                ASSERT( rThis.IsTabFrm(), "new FowFrm?" );
+                                pNode = ((SwTabFrm&)rThis).GetTable()->
+                                    GetTabSortBoxes()[0]->GetSttNd()->FindTableNode();
+                            }
+                            nIndex = pNode->GetIndex();
+                        }
+                        if( nIndex < nTmpIndex )
+                            continue;
+                    }
+                }
+                else
+                    continue;
+
+                nRet |= 2;
+            }
+        }
+    }
+    return nRet;
+}
+
+/*************************************************************************
+|*
+|*  SwFlowFrm::CutTree(), PasteTree(), MoveSubTree()
+|*
+|*  Beschreibung        Eine Spezialisierte Form des Cut() und Paste(), die
+|*      eine ganze Kette umhaengt (naehmlich this und folgende). Dabei werden
+|*      nur minimale Operationen und Benachrichtigungen ausgefuehrt.
+|*  Ersterstellung      MA 18. Mar. 93
+|*  Letzte Aenderung    MA 18. May. 95
+|*
+|*************************************************************************/
+
+
+SwLayoutFrm *SwFlowFrm::CutTree( SwFrm *pStart )
+{
+    //Der Start und alle Nachbarn werden ausgeschnitten, sie werden aneinander-
+    //gereiht und ein Henkel auf den ersten wird zurueckgeliefert.
+    //Zurueckbleibende werden geeignet invalidiert.
+
+    SwLayoutFrm *pLay = pStart->GetUpper();
+    if ( pLay->IsInFtn() )
+        pLay = pLay->FindFtnFrm();
+    if( pLay )
+    {
+        SwFrm* pTmp = pStart->GetIndPrev();
+        if( pTmp )
+            pTmp->Prepare( PREP_QUOVADIS );
+    }
+
+    //Nur fix auschneiden und zwar so, dass klare Verhaeltnisse bei den
+    //Verlassenen herrschen. Die Pointer der ausgeschnittenen Kette zeigen
+    //noch wer weiss wo hin.
+    if ( pStart == pStart->GetUpper()->Lower() )
+        pStart->GetUpper()->pLower = 0;
+    if ( pStart->GetPrev() )
+    {
+        pStart->GetPrev()->pNext = 0;
+        pStart->pPrev = 0;
+    }
+
+    if ( pLay->IsFtnFrm() )
+    {   if ( !pLay->Lower() && !pLay->IsColLocked() )
+        {   pLay->Cut();
+            delete pLay;
+        }
+        else
+        {   ((SwFtnFrm*)pLay)->LockBackMove();
+            pLay->InvalidateSize();
+            pLay->Calc();
+            SwCntntFrm *pCnt = pLay->ContainsCntnt();
+            while ( pCnt && pLay->IsAnLower( pCnt ) )
+            {
+                //Kann sein, dass der CntFrm gelockt ist, wir wollen hier nicht
+                //in eine endlose Seitenwanderung hineinlaufen und rufen das
+                //Calc garnicht erst!
+                ASSERT( pCnt->IsTxtFrm(), "Die Graphic ist gelandet." );
+                if ( ((SwTxtFrm*)pCnt)->IsLocked() ||
+                     ((SwTxtFrm*)pCnt)->GetFollow() == pStart )
+                    break;
+                pCnt->Calc();
+                pCnt = pCnt->GetNextCntntFrm();
+            }
+            ((SwFtnFrm*)pLay)->UnlockBackMove();
+        }
+        pLay = 0;
+    }
+    return pLay;
+}
+
+
+
+BOOL SwFlowFrm::PasteTree( SwFrm *pStart, SwLayoutFrm *pParent, SwFrm *pSibling,
+                           SwFrm *pOldParent )
+{
+    //returnt TRUE wenn in der Kette ein LayoutFrm steht.
+    BOOL bRet = FALSE;
+
+    //Die mit pStart beginnende Kette wird vor den Sibling unter den Parent
+    //gehaengt. Fuer geeignete Invalidierung wird ebenfalls gesorgt.
+
+    //Ich bekomme eine fertige Kette. Der Anfang der Kette muss verpointert
+    //werden, dann alle Upper fuer die Kette und schliesslich dass Ende.
+    //Unterwegs werden alle geeignet invalidiert.
+    if ( pSibling )
+    {
+        if ( 0 != (pStart->pPrev = pSibling->GetPrev()) )
+            pStart->GetPrev()->pNext = pStart;
+        else
+            pParent->pLower = pStart;
+        pSibling->_InvalidatePos();
+        pSibling->_InvalidatePrt();
+    }
+    else
+    {
+        if ( 0 == (pStart->pPrev = pParent->Lower()) )
+            pParent->pLower = pStart;
+        else
+            pParent->Lower()->pNext = pStart;
+    }
+    SwFrm *pFloat = pStart;
+    SwFrm *pLst;
+    SwTwips nGrowVal = 0;
+    do
+    {   pFloat->pUpper = pParent;
+        pFloat->_InvalidateAll();
+
+        //Ich bin Freund des TxtFrm und darf deshalb so einiges. Das mit
+        //dem CacheIdx scheint etwas riskant!
+        if ( pFloat->IsTxtFrm() )
+        {
+            if ( ((SwTxtFrm*)pFloat)->GetCacheIdx() != USHRT_MAX )
+                ((SwTxtFrm*)pFloat)->Init();    //Ich bin sein Freund.
+        }
+        else
+            bRet = TRUE;
+
+        nGrowVal += pFloat->Frm().Height();
+        if ( pFloat->GetNext() )
+            pFloat = pFloat->GetNext();
+        else
+        {   pLst = pFloat;
+            pFloat = 0;
+        }
+    } while ( pFloat );
+
+    if ( pSibling )
+    {
+        pLst->pNext = pSibling;
+        pSibling->pPrev = pLst;
+        if( pSibling->IsInFtn() )
+        {
+            if( pSibling->IsSctFrm() )
+                pSibling = ((SwSectionFrm*)pSibling)->ContainsAny();
+            if( pSibling )
+                pSibling->Prepare( PREP_ERGOSUM );
+        }
+    }
+    if ( nGrowVal )
+    {
+        if ( pOldParent && pOldParent->IsBodyFrm() ) //Fuer variable Seitenhoehe beim Browsen
+            pOldParent->Shrink( nGrowVal, pHeight );
+        pParent->Grow( nGrowVal, pHeight );
+    }
+
+    if ( pParent->IsFtnFrm() )
+        ((SwFtnFrm*)pParent)->InvalidateNxtFtnCnts( pParent->FindPageFrm() );
+    return bRet;
+}
+
+
+
+void SwFlowFrm::MoveSubTree( SwLayoutFrm* pParent, SwFrm* pSibling )
+{
+    ASSERT( pParent, "Kein Parent uebergeben." );
+    ASSERT( rThis.GetUpper(), "Wo kommen wir denn her?" );
+
+    //Sparsamer benachrichtigen wenn eine Action laeuft.
+    ViewShell *pSh = rThis.GetShell();
+    const SwViewImp *pImp = pSh ? pSh->Imp() : 0;
+    const BOOL bComplete = pImp && pImp->IsAction() && pImp->GetLayAction().IsComplete();
+
+    if ( !bComplete )
+    {
+        SwFrm *pPre = rThis.GetIndPrev();
+        if ( pPre )
+        {
+            pPre->SetRetouche();
+            pPre->InvalidatePage();
+        }
+        else
+        {   rThis.GetUpper()->SetCompletePaint();
+            rThis.GetUpper()->InvalidatePage();
+        }
+    }
+
+    SwPageFrm *pOldPage = rThis.FindPageFrm();
+
+    SwLayoutFrm *pOldParent = CutTree( &rThis );
+    const BOOL bInvaLay = PasteTree( &rThis, pParent, pSibling, pOldParent );
+
+    // Wenn durch das Cut&Paste ein leerer SectionFrm entstanden ist, sollte
+    // dieser automatisch verschwinden.
+    SwSectionFrm *pSct;
+    if ( pOldParent && !pOldParent->Lower() &&
+         (pOldParent->IsInSct() &&
+          !(pSct = pOldParent->FindSctFrm())->ContainsCntnt() ) )
+            pSct->DelEmpty( FALSE );
+    // In einem spaltigen Bereich rufen wir lieber kein Calc "von unten"
+    if( !rThis.IsInSct() )
+        rThis.GetUpper()->Calc();
+    else if( rThis.GetUpper()->IsSctFrm() )
+    {
+        SwSectionFrm* pSct = (SwSectionFrm*)rThis.GetUpper();
+        BOOL bOld = pSct->IsCntntLocked();
+        pSct->SetCntntLock( TRUE );
+        pSct->Calc();
+        if( !bOld )
+            pSct->SetCntntLock( FALSE );
+    }
+    SwPageFrm *pPage = rThis.FindPageFrm();
+
+    if ( pOldPage != pPage )
+    {
+        rThis.InvalidatePage( pPage );
+        if ( rThis.IsLayoutFrm() )
+        {
+            SwCntntFrm *pCnt = ((SwLayoutFrm*)&rThis)->ContainsCntnt();
+            if ( pCnt )
+                pCnt->InvalidatePage( pPage );
+        }
+        else if ( pSh->GetDoc()->GetLineNumberInfo().IsRestartEachPage() &&
+                  pPage->FindFirstBodyCntnt() == &rThis )
+        {
+            rThis._InvalidateLineNum();
+        }
+    }
+    if ( bInvaLay || (pSibling && pSibling->IsLayoutFrm()) )
+        rThis.GetUpper()->InvalidatePage( pPage );
+}
+
+/*************************************************************************
+|*
+|*  SwFlowFrm::IsAnFollow()
+|*
+|*  Ersterstellung      MA 26. Apr. 95
+|*  Letzte Aenderung    MA 26. Apr. 95
+|*
+|*************************************************************************/
+
+
+BOOL SwFlowFrm::IsAnFollow( const SwFlowFrm *pAssumed ) const
+{
+    const SwFlowFrm *pFoll = this;
+    do
+    {   if ( pAssumed == pFoll )
+            return TRUE;
+        pFoll = pFoll->GetFollow();
+    } while ( pFoll );
+    return FALSE;
+}
+
+/*************************************************************************
+|*
+|*  SwFlowFrm::FindMaster()
+|*
+|*  Ersterstellung      MA 26. Apr. 95
+|*  Letzte Aenderung    MA 26. Apr. 95
+|*
+|*************************************************************************/
+
+
+SwFlowFrm *SwFlowFrm::FindMaster()
+{
+    ASSERT( IsFollow(), "FindMaster und kein Follow." );
+
+    SwCntntFrm *pCnt;
+    BOOL bCntnt;
+    if ( rThis.IsCntntFrm() )
+    {
+        pCnt = (SwCntntFrm*)&rThis;
+        bCntnt = TRUE;
+    }
+    else if( rThis.IsTabFrm() )
+    {   pCnt = ((SwLayoutFrm&)rThis).ContainsCntnt();
+        bCntnt = FALSE;
+    }
+    else
+    {
+        ASSERT( rThis.IsSctFrm(), "FindMaster: Funny FrameTyp" );
+        return ((SwSectionFrm&)rThis).FindSectionMaster();
+    }
+
+    pCnt = pCnt->GetPrevCntntFrm();
+    while ( pCnt )
+    {
+        if ( bCntnt )
+        {
+            if ( pCnt->HasFollow() && pCnt->GetFollow() == this )
+                return pCnt;
+        }
+        else
+        {   SwTabFrm  *pTab = pCnt->FindTabFrm();
+            if ( pTab && pTab->GetFollow() == this )
+                return pTab;
+        }
+        pCnt = pCnt->GetPrevCntntFrm();
+    }
+    ASSERT( FALSE, "Follow ist lost in Space." );
+    return 0;
+}
+
+/*************************************************************************
+|*
+|*  SwFrm::GetLeaf()
+|*
+|*  Beschreibung        Liefert das naechste/vorhergehende LayoutBlatt,
+|*      das _nicht_ unterhalb von this liegt (oder gar this selbst ist).
+|*      Ausserdem muss dieses LayoutBlatt im gleichen Textfluss wie
+|*      pAnch Ausgangsfrm liegen (Body, Ftn)
+|*  Ersterstellung      MA 25. Nov. 92
+|*  Letzte Aenderung    MA 25. Apr. 95
+|*
+|*************************************************************************/
+
+
+const SwLayoutFrm *SwFrm::GetLeaf( MakePageType eMakePage, BOOL bFwd,
+                                   const SwFrm *pAnch ) const
+{
+    //Ohne Fluss kein genuss...
+    if ( IsInTab() || !(IsInDocBody() || IsInFtn() || IsInFly()) )
+        return 0;
+
+    const SwFrm *pLeaf = this;
+    BOOL bFound = FALSE;
+
+    do
+    {   pLeaf = ((SwFrm*)pLeaf)->GetLeaf( eMakePage, bFwd );
+
+        if ( pLeaf &&
+            (!IsLayoutFrm() || !((SwLayoutFrm*)this)->IsAnLower( pLeaf )))
+        {
+            if ( pAnch->IsInDocBody() == pLeaf->IsInDocBody() &&
+                 pAnch->IsInFtn()     == pLeaf->IsInFtn() )
+            {
+                bFound = TRUE;
+            }
+        }
+    } while ( !bFound && pLeaf );
+
+    return (const SwLayoutFrm*)pLeaf;
+}
+
+/*************************************************************************
+|*
+|*  SwFrm::GetLeaf()
+|*
+|*  Beschreibung        Ruft Get[Next|Prev]Leaf
+|*
+|*  Ersterstellung      MA 20. Mar. 93
+|*  Letzte Aenderung    MA 25. Apr. 95
+|*
+|*************************************************************************/
+
+
+SwLayoutFrm *SwFrm::GetLeaf( MakePageType eMakePage, BOOL bFwd )
+{
+    if ( IsInFtn() )
+        return bFwd ? GetNextFtnLeaf( eMakePage ) : GetPrevFtnLeaf( eMakePage );
+    if ( IsInSct() )
+        return bFwd ? GetNextSctLeaf( eMakePage ) : GetPrevSctLeaf( eMakePage );
+    return bFwd ? GetNextLeaf( eMakePage ) : GetPrevLeaf( eMakePage );
+}
+
+
+
+BOOL SwFrm::WrongPageDesc( SwPageFrm* pNew )
+{
+    //Jetzt wirds leider etwas kompliziert:
+    //Ich bringe ich evtl. selbst
+    //einen Pagedesc mit; der der Folgeseite muss dann damit
+    //uebereinstimmen.
+    //Anderfalls muss ich mir etwas genauer ansehen wo der
+    //Folgepagedesc herkam.
+    //Wenn die Folgeseite selbst schon sagt, dass ihr
+    //Pagedesc nicht stimmt so kann ich das Teil bedenkenlos
+    //auswechseln.
+    //Wenn die Seite meint, dass ihr Pagedesc stimmt, so heisst
+    //das leider noch immer nicht, dass ich damit etwas anfangen
+    //kann: Wenn der erste BodyCntnt einen PageDesc oder einen
+    //PageBreak wuenscht, so muss ich ebenfalls eine neue
+    //Seite einfuegen; es sein denn die gewuenschte Seite ist
+    //die richtige.
+    //Wenn ich einen neue Seite eingefuegt habe, so fangen die
+    //Probleme leider erst an, denn wahrscheinlich wird die dann
+    //folgende Seite verkehrt gewesen und ausgewechselt worden
+    //sein. Das hat zur Folge, dass ich zwar eine neue (und
+    //jetzt richtige) Seite habe, die Bedingungen zum auswechseln
+    //aber leider noch immer stimmen.
+    //Ausweg: Vorlaeufiger Versuch, nur einmal eine neue Seite
+    //einsetzen (Leerseiten werden noetigenfalls bereits von
+    //InsertPage() eingefuegt.
+    const SwFmtPageDesc &rFmtDesc = GetAttrSet()->GetPageDesc();
+
+    //Mein Pagedesc zaehlt nicht, wenn ich ein Follow bin!
+    SwPageDesc *pDesc = 0;
+    SwFlowFrm *pFlow = SwFlowFrm::CastFlowFrm( this );
+    if ( !pFlow || !pFlow->IsFollow() )
+        pDesc = (SwPageDesc*)rFmtDesc.GetPageDesc();
+
+    //Bringt der Cntnt einen Pagedesc mit oder muss zaehlt die
+    //virtuelle Seitennummer des neuen Layoutleafs?
+    // Bei Follows zaehlt der PageDesc nicht
+    const USHORT nTmp = ( pDesc && rFmtDesc.GetNumOffset() )
+                                    ? rFmtDesc.GetNumOffset()
+                                    : pNew->GetVirtPageNum();
+    const BOOL bOdd = nTmp % 2 ? TRUE : FALSE;
+    if ( !pDesc )
+        pDesc = pNew->FindPageDesc();
+    const SwFlowFrm *pNewFlow = pNew->FindFirstBodyCntnt();
+    // Haben wir uns selbst gefunden?
+    if( pNewFlow == pFlow )
+        pNewFlow = NULL;
+    if ( pNewFlow && pNewFlow->GetFrm()->IsInTab() )
+        pNewFlow = pNewFlow->GetFrm()->FindTabFrm();
+    const SwPageDesc *pNewDesc= ( pNewFlow && !pNewFlow->IsFollow() )
+            ? pNewFlow->GetFrm()->GetAttrSet()->GetPageDesc().GetPageDesc():0;
+
+    return ( pNew->GetPageDesc() != pDesc ||   //  own desc ?
+        pNew->GetFmt() != (bOdd ? pDesc->GetRightFmt() : pDesc->GetLeftFmt()) ||
+        ( pNewDesc && pNewDesc == pDesc ) );
+}
+
+
+/*************************************************************************
+|*
+|*  SwFrm::GetNextLeaf()
+|*
+|*  Beschreibung        Liefert das naechste LayoutBlatt in den das
+|*      Frame gemoved werden kann.
+|*
+|*  Ersterstellung      MA 16. Nov. 92
+|*  Letzte Aenderung    MA 05. Dec. 96
+|*
+|*************************************************************************/
+
+SwLayoutFrm *SwFrm::GetNextLeaf( MakePageType eMakePage )
+{
+    ASSERT( !IsInFtn(), "GetNextLeaf(), don't call me for Ftn." );
+    ASSERT( !IsInSct(), "GetNextLeaf(), don't call me for Sections." );
+
+    const BOOL bBody = IsInDocBody();       //Wenn ich aus dem DocBody komme
+                                            //Will ich auch im Body landen.
+
+    // Bei Flys macht es keinen Sinn, Seiten einzufuegen, wir wollen lediglich
+     // die Verkettung absuchen.
+    if( IsInFly() )
+        eMakePage = MAKEPAGE_NONE;
+    //Bei Tabellen gleich den grossen Sprung wagen, ein einfaches GetNext...
+    //wuerde die erste Zellen und in der Folge alle weiteren Zellen nacheinander
+    //abklappern....
+    SwLayoutFrm *pLayLeaf;
+    if ( IsTabFrm() )
+        pLayLeaf = ((SwTabFrm*)this)->FindLastCntnt()->GetUpper();
+    else
+        pLayLeaf = GetNextLayoutLeaf();
+
+    SwLayoutFrm *pOldLayLeaf = 0;           //Damit bei neu erzeugten Seiten
+                                            //nicht wieder vom Anfang gesucht
+                                            //wird.
+    BOOL bNewPg = FALSE;    //nur einmal eine neue Seite einfuegen.
+
+    while ( TRUE )
+    {
+        if ( pLayLeaf )
+        {
+            //Es gibt noch einen weiteren LayoutFrm, mal sehen,
+            //ob er bereit ist mich aufzunehmen.
+            //Dazu braucht er nur von der gleichen Art wie mein Ausgangspunkt
+            //sein (DocBody bzw. Footnote.)
+            if ( pLayLeaf->FindPageFrm()->IsFtnPage() )
+            {   //Wenn ich bei den Endnotenseiten angelangt bin hat sichs.
+                pLayLeaf = 0;
+                continue;
+            }
+            if ( (bBody && !pLayLeaf->IsInDocBody()) || pLayLeaf->IsInTab()
+                 || pLayLeaf->IsInSct() )
+            {
+                //Er will mich nicht; neuer Versuch, neues Glueck
+                pOldLayLeaf = pLayLeaf;
+                pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
+                continue;
+            }
+            //Er will mich, also ist er der gesuchte und ich bin fertig.
+            //Bei einem Seitenwechsel kann es allerdings noch sein, dass
+            //Der Seitentyp nicht der gewuenschte ist, in diesem Fall muessen
+            //wir eine Seite des richtigen Typs einfuegen.
+
+            if ( !IsFlowFrm() &&
+                 (eMakePage == MAKEPAGE_NONE || eMakePage == MAKEPAGE_APPEND) )
+                return pLayLeaf;
+
+            SwPageFrm *pNew = pLayLeaf->FindPageFrm();
+            if ( pNew != FindPageFrm() && !bNewPg )
+            {
+                if( WrongPageDesc( pNew ) )
+                {
+                    SwFtnContFrm *pCont = pNew->FindFtnCont();
+                    if( pCont )
+                    {
+                        // Falls die Referenz der ersten Fussnote dieser Seite
+                        // vor der Seite liegt, fuegen wir lieber keine neue Seite
+                        // ein (Bug #55620#)
+                        SwFtnFrm *pFtn = (SwFtnFrm*)pCont->Lower();
+                        if( pFtn && pFtn->GetRef() )
+                        {
+                            const USHORT nRefNum = pNew->GetPhyPageNum();
+                            if( pFtn->GetRef()->GetPhyPageNum() < nRefNum )
+                                break;
+                        }
+                    }
+                    //Erwischt, die folgende Seite ist verkehrt, also
+                    //muss eine neue eingefuegt werden.
+                    if ( eMakePage == MAKEPAGE_INSERT )
+                    {
+                        bNewPg = TRUE;
+
+                        SwPageFrm *pPg = pOldLayLeaf ?
+                                    pOldLayLeaf->FindPageFrm() : 0;
+                        if ( pPg && pPg->IsEmptyPage() )
+                            //Nicht hinter, sondern vor der EmptyPage einfuegen.
+                            pPg = (SwPageFrm*)pPg->GetPrev();
+
+                        if ( !pPg || pPg == pNew )
+                            pPg = FindPageFrm();
+
+                        InsertPage( pPg, FALSE );
+                        pLayLeaf = GetNextLayoutLeaf();
+                        pOldLayLeaf = 0;
+                        continue;
+                    }
+                    else
+                        pLayLeaf = 0;
+                }
+            }
+            break;
+        }
+        else
+        {
+            //Es gibt keinen passenden weiteren LayoutFrm, also muss eine
+            //neue Seite her.
+            if ( eMakePage == MAKEPAGE_APPEND || eMakePage == MAKEPAGE_INSERT )
+            {
+                InsertPage(
+                    pOldLayLeaf ? pOldLayLeaf->FindPageFrm() : FindPageFrm(),
+                    FALSE );
+
+                //und nochmal das ganze
+                pLayLeaf = pOldLayLeaf ? pOldLayLeaf : GetNextLayoutLeaf();
+            }
+            else
+                break;
+        }
+    }
+    return pLayLeaf;
+}
+
+/*************************************************************************
+|*
+|*  SwFrm::GetPrevLeaf()
+|*
+|*  Beschreibung        Liefert das vorhergehende LayoutBlatt in das der
+|*      Frame gemoved werden kann.
+|*  Ersterstellung      MA 16. Nov. 92
+|*  Letzte Aenderung    MA 25. Apr. 95
+|*
+|*************************************************************************/
+
+
+SwLayoutFrm *SwFrm::GetPrevLeaf( MakePageType eMakeFtn )
+{
+    ASSERT( !IsInFtn(), "GetPrevLeaf(), don't call me for Ftn." );
+
+    const BOOL bBody = IsInDocBody();       //Wenn ich aus dem DocBody komme
+                                            //will ich auch im Body landen.
+    const BOOL bFly  = IsInFly();
+
+    SwLayoutFrm *pLayLeaf = GetPrevLayoutLeaf();
+    SwLayoutFrm *pPrevLeaf = 0;
+
+    while ( pLayLeaf )
+    {
+        if ( pLayLeaf->IsInTab() ||     //In Tabellen geht's niemals hinein.
+             pLayLeaf->IsInSct() )      //In Bereiche natuerlich auch nicht!
+            pLayLeaf = pLayLeaf->GetPrevLayoutLeaf();
+        else if ( bBody && pLayLeaf->IsInDocBody() )
+        {
+            if ( pLayLeaf->Lower() )
+                break;
+            pPrevLeaf = pLayLeaf;
+            pLayLeaf = pLayLeaf->GetPrevLayoutLeaf();
+            if ( pLayLeaf )
+                SwFlowFrm::SetMoveBwdJump( TRUE );
+        }
+        else if ( bFly )
+            break;  //Cntnts in Flys sollte jedes Layout-Blatt recht sein.
+        else
+            pLayLeaf = pLayLeaf->GetPrevLayoutLeaf();
+    }
+    return pLayLeaf ? pLayLeaf : pPrevLeaf;
+}
+
+/*************************************************************************
+|*
+|*  SwFlowFrm::IsPrevObjMove()
+|*
+|*  Ersterstellung      MA 20. Feb. 96
+|*  Letzte Aenderung    MA 22. Feb. 96
+|*
+|*************************************************************************/
+
+
+BOOL SwFlowFrm::IsPrevObjMove() const
+{
+    //TRUE der FlowFrm soll auf einen Rahmen des Vorgaengers Ruecksicht nehmen
+    //     und fuer diesen ggf. Umbrechen.
+
+    //!!!!!!!!!!!Hack!!!!!!!!!!!
+    if ( rThis.GetUpper()->GetFmt()->GetDoc()->IsBrowseMode() )
+        return FALSE;
+
+    SwFrm *pPre = rThis.FindPrev();
+
+    if ( pPre && pPre->GetDrawObjs() )
+    {
+        ASSERT( SwFlowFrm::CastFlowFrm( pPre ), "new flowfrm?" );
+        if( SwFlowFrm::CastFlowFrm( pPre )->IsAnFollow( this ) )
+            return FALSE;
+        SwFrm* pPreUp = pPre->GetUpper();
+        // Wenn der Upper ein SectionFrm oder die Spalte eines SectionFrms ist,
+        // duerfen wir aus diesem durchaus heraushaengen,
+        // es muss stattdessen der Upper des SectionFrms beruecksichtigt werden.
+        if( pPreUp->IsInSct() )
+        {
+            if( pPreUp->IsSctFrm() )
+                pPreUp = pPreUp->GetUpper();
+            else if( pPreUp->IsColBodyFrm() &&
+                     pPreUp->GetUpper()->GetUpper()->IsSctFrm() )
+                pPreUp = pPreUp->GetUpper()->GetUpper();
+        }
+        const long nBottom = pPreUp->Frm().Bottom();
+        const long nRight  = pPreUp->Frm().Right();
+        const FASTBOOL bCol = pPreUp->IsColBodyFrm();//ColFrms jetzt mit BodyFrm
+        for ( USHORT i = 0; i < pPre->GetDrawObjs()->Count(); ++i )
+        {
+            const SdrObject *pObj = (*pPre->GetDrawObjs())[i];
+            if ( pObj->IsWriterFlyFrame() )
+            {
+                const SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+
+                if ( WEIT_WECH != pFly->Frm().Top() && !pFly->IsFlyInCntFrm() )
+                {
+                    if( pObj->GetSnapRect().Top()  > nBottom )
+                        return TRUE;
+                    if( bCol && pObj->GetSnapRect().Left() > nRight )
+                    {
+                        SwFmtHoriOrient aHori( pFly->GetFmt()->GetHoriOrient() );
+                        if( FRAME == aHori.GetRelationOrient() ||
+                            PRTAREA == aHori.GetRelationOrient() ||
+                            REL_CHAR == aHori.GetRelationOrient() ||
+                            REL_FRM_LEFT == aHori.GetRelationOrient() ||
+                            REL_FRM_RIGHT == aHori.GetRelationOrient() )
+                        {
+                            if( HORI_NONE == aHori.GetHoriOrient() )
+                            {
+                                SwTwips nAdd = 0;
+                                switch ( aHori.GetRelationOrient() )
+                                {
+                                    case PRTAREA:
+                                        nAdd = pFly->Prt().Left(); break;
+                                    case REL_FRM_RIGHT:
+                                        nAdd = pFly->Frm().Width(); break;
+                                    case REL_CHAR:
+                                        if( pFly->IsFlyAtCntFrm() )
+                                            nAdd = ((SwFlyAtCntFrm*)pFly)->GetLastCharX();
+                                        break;
+                                }
+                                nAdd += aHori.GetPos();
+                                if( nAdd < pPreUp->Frm().Width() &&
+                                    nAdd + pFly->Frm().Width() > 0 )
+                                    return TRUE;
+                            }
+                            else
+                                return TRUE;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return FALSE;
+}
+
+/*************************************************************************
+|*
+|*  BOOL SwFlowFrm::IsPageBreak()
+|*
+|*  Beschreibung        Wenn vor dem Frm ein harter Seitenumbruch steht UND
+|*      es einen Vorgaenger auf der gleichen Seite gibt, wird TRUE
+|*      zurueckgeliefert (es muss ein PageBreak erzeugt werden) FALSE sonst.
+|*      Wenn in bAct TRUE uebergeben wird, gibt die Funktion dann TRUE
+|*      zurueck, wenn ein PageBreak besteht.
+|*      Fuer Follows wird der harte Seitenumbruch natuerlich nicht
+|*      ausgewertet.
+|*      Der Seitenumbruch steht im eigenen FrmFmt (BEFORE) oder im FrmFmt
+|*      des Vorgaengers (AFTER). Wenn es keinen Vorgaenger auf der Seite
+|*      gibt ist jede weitere Ueberlegung ueberfluessig.
+|*      Ein Seitenumbruch (oder der Bedarf) liegt auch dann vor, wenn
+|*      im FrmFmt ein PageDesc angegeben wird.
+|*      Die Implementierung arbeitet zuaechst nur auf CntntFrms!
+|*      -->Fuer LayoutFrms ist die Definition des Vorgaengers unklar.
+|*  Ersterstellung      MA ??
+|*  Letzte Aenderung    MA 21. Mar. 95
+|*
+|*************************************************************************/
+
+
+BOOL SwFlowFrm::IsPageBreak( BOOL bAct ) const
+{
+    const SwAttrSet *pSet;
+    if ( !IsFollow() && rThis.IsInDocBody() &&
+         !(pSet = rThis.GetAttrSet())->GetDoc()->IsBrowseMode() )
+    {
+        //Vorgaenger ermitteln
+        const SwFrm *pPrev = rThis.FindPrev();
+        while ( pPrev && ( !pPrev->IsInDocBody() ||
+                ( pPrev->IsTxtFrm() && ((SwTxtFrm*)pPrev)->IsHiddenNow() ) ) )
+            pPrev = pPrev->FindPrev();
+
+        if ( pPrev )
+        {
+            ASSERT( pPrev->IsInDocBody(), "IsPageBreak: Not in DocBody?" );
+            if ( bAct )
+            {   if ( rThis.FindPageFrm() == pPrev->FindPageFrm() )
+                    return FALSE;
+            }
+            else
+            {   if ( rThis.FindPageFrm() != pPrev->FindPageFrm() )
+                    return FALSE;
+            }
+
+            const SvxBreak eBreak = pSet->GetBreak().GetBreak();
+            if ( eBreak == SVX_BREAK_PAGE_BEFORE || eBreak == SVX_BREAK_PAGE_BOTH )
+                return TRUE;
+            else
+            {
+                const SvxBreak &ePrB = pPrev->GetAttrSet()->GetBreak().GetBreak();
+                if ( ePrB == SVX_BREAK_PAGE_AFTER ||
+                     ePrB == SVX_BREAK_PAGE_BOTH  ||
+                     pSet->GetPageDesc().GetPageDesc() )
+                    return TRUE;
+            }
+        }
+    }
+    return FALSE;
+}
+
+/*************************************************************************
+|*
+|*  BOOL SwFlowFrm::IsColBreak()
+|*
+|*  Beschreibung        Wenn vor dem Frm ein harter Spaltenumbruch steht UND
+|*      es einen Vorgaenger in der gleichen Spalte gibt, wird TRUE
+|*      zurueckgeliefert (es muss ein PageBreak erzeugt werden) FALSE sonst.
+|*      Wenn in bAct TRUE uebergeben wird, gibt die Funktion dann TRUE
+|*      zurueck, wenn ein ColBreak besteht.
+|*      Fuer Follows wird der harte Spaltenumbruch natuerlich nicht
+|*      ausgewertet.
+|*      Der Spaltenumbruch steht im eigenen FrmFmt (BEFORE) oder im FrmFmt
+|*      des Vorgaengers (AFTER). Wenn es keinen Vorgaenger in der Spalte
+|*      gibt ist jede weitere Ueberlegung ueberfluessig.
+|*      Die Implementierung arbeitet zuaechst nur auf CntntFrms!
+|*      -->Fuer LayoutFrms ist die Definition des Vorgaengers unklar.
+|*  Ersterstellung      MA 11. Jun. 93
+|*  Letzte Aenderung    MA 21. Mar. 95
+|*
+|*************************************************************************/
+
+
+BOOL SwFlowFrm::IsColBreak( BOOL bAct ) const
+{
+    if ( !IsFollow() && (rThis.IsMoveable() || bAct) )
+    {
+        const SwFrm *pCol = rThis.FindColFrm();
+        if ( pCol )
+        {
+            //Vorgaenger ermitteln
+            const SwFrm *pPrev = rThis.FindPrev();
+            while( pPrev && ( ( !pPrev->IsInDocBody() && !rThis.IsInFly() ) ||
+                   ( pPrev->IsTxtFrm() && ((SwTxtFrm*)pPrev)->IsHiddenNow() ) ) )
+                    pPrev = pPrev->FindPrev();
+
+            if ( pPrev )
+            {
+                if ( bAct )
+                {   if ( pCol == pPrev->FindColFrm() )
+                        return FALSE;
+                }
+                else
+                {   if ( pCol != pPrev->FindColFrm() )
+                        return FALSE;
+                }
+
+                const SvxBreak eBreak = rThis.GetAttrSet()->GetBreak().GetBreak();
+                if ( eBreak == SVX_BREAK_COLUMN_BEFORE ||
+                     eBreak == SVX_BREAK_COLUMN_BOTH )
+                    return TRUE;
+                else
+                {
+                    const SvxBreak &ePrB = pPrev->GetAttrSet()->GetBreak().GetBreak();
+                    if ( ePrB == SVX_BREAK_COLUMN_AFTER ||
+                         ePrB == SVX_BREAK_COLUMN_BOTH )
+                        return TRUE;
+                }
+            }
+        }
+    }
+    return FALSE;
+}
+
+BOOL SwFlowFrm::HasParaSpaceAtPages( BOOL bSct ) const
+{
+    if( rThis.IsInSct() )
+    {
+        const SwFrm* pTmp = rThis.GetUpper();
+        while( pTmp )
+        {
+            if( pTmp->IsCellFrm() || pTmp->IsFlyFrm() ||
+                pTmp->IsFooterFrm() || pTmp->IsHeaderFrm() ||
+                ( pTmp->IsFtnFrm() && !((SwFtnFrm*)pTmp)->GetMaster() ) )
+                return TRUE;
+            if( pTmp->IsPageFrm() )
+                return ( pTmp->GetPrev() && !IsPageBreak(TRUE) ) ? FALSE : TRUE;
+            if( pTmp->IsColumnFrm() && pTmp->GetPrev() )
+                return IsColBreak( TRUE );
+            if( pTmp->IsSctFrm() && ( !bSct || pTmp->GetPrev() ) )
+                return FALSE;
+            pTmp = pTmp->GetUpper();
+        }
+        ASSERT( FALSE, "HasParaSpaceAtPages: Where's my page?" );
+        return FALSE;
+    }
+    if( !rThis.IsInDocBody() || ( rThis.IsInTab() && !rThis.IsTabFrm()) ||
+        IsPageBreak( TRUE ) || ( rThis.FindColFrm() && IsColBreak( TRUE ) ) )
+        return TRUE;
+    const SwFrm* pTmp = rThis.FindColFrm();
+    if( pTmp )
+    {
+        if( pTmp->GetPrev() )
+            return FALSE;
+    }
+    else
+        pTmp = &rThis;
+    pTmp = pTmp->FindPageFrm();
+    return pTmp && !pTmp->GetPrev();
+}
+
+SwTwips SwFlowFrm::CalcUpperSpace( const SwBorderAttrs *pAttrs,
+    const SwFrm* pPr ) const
+{
+    const SwFrm *pPre = pPr ? pPr : rThis.GetPrev();
+    BOOL bInFtn = rThis.IsInFtn();
+    do {
+        while( pPre && ( (pPre->IsTxtFrm() && ((SwTxtFrm*)pPre)->IsHiddenNow())
+               || ( pPre->IsSctFrm() && !((SwSectionFrm*)pPre)->GetSection() ) ) )
+            pPre = pPre->GetPrev();
+        if( !pPre && bInFtn )
+        {
+            bInFtn = FALSE;
+            if( !rThis.IsInSct() || rThis.IsSctFrm() ||
+                !rThis.FindSctFrm()->IsInFtn() )
+                pPre = rThis.FindFtnFrm()->GetPrev();
+            if( pPre )
+            {
+                pPre = ((SwFtnFrm*)pPre)->Lower();
+                if( pPre )
+                    while( pPre->GetNext() )
+                        pPre = pPre->GetNext();
+                continue;
+            }
+        }
+        if( pPre && pPre->IsSctFrm() )
+        {
+            SwSectionFrm* pSect = (SwSectionFrm*)pPre;
+            pPre = pSect->FindLastCntnt();
+            // If the last content is in a table _inside_ the section,
+            // take the table herself.
+            if( pPre && pPre->IsInTab() && !pSect->IsInTab() )
+                pPre = pPre->FindTabFrm();
+        }
+        break;
+    } while( pPre );
+    SwBorderAttrAccess *pAccess;
+    SwFrm* pOwn;
+    if( !pAttrs )
+    {
+        if( rThis.IsSctFrm() )
+        {
+            SwSectionFrm* pFoll = &((SwSectionFrm&)rThis);
+            do
+                pOwn = pFoll->ContainsAny();
+            while( !pOwn && 0 != ( pFoll = pFoll->GetFollow() ) );
+            if( !pOwn )
+                return 0;
+        }
+        else
+            pOwn = &rThis;
+        pAccess= new SwBorderAttrAccess( SwFrm::GetCache(), pOwn );
+        pAttrs = pAccess->Get();
+    }
+    else
+    {
+        pAccess = NULL;
+        pOwn = &rThis;
+    }
+    SwTwips nUpper = 0;
+    if( pPre )
+    {
+        const SvxULSpaceItem &rPrevUL = pPre->GetAttrSet()->GetULSpace();
+        if( rThis.GetAttrSet()->GetDoc()->IsParaSpaceMax() )
+        {
+            nUpper = rPrevUL.GetLower() + pAttrs->GetULSpace().GetUpper();
+            SwTwips nAdd = 0;
+            if ( pOwn->IsTxtFrm() )
+                nAdd = Max( nAdd, long(((SwTxtFrm&)rThis).GetLineSpace()) );
+            if ( pPre->IsTxtFrm() )
+                nAdd = Max( nAdd, long(((SwTxtFrm*)pPre)->GetLineSpace()) );
+            nUpper += nAdd;
+        }
+        else
+        {
+            nUpper = Max( rPrevUL.GetLower(), pAttrs->GetULSpace().GetUpper() );
+            if ( pOwn->IsTxtFrm() )
+                nUpper = Max( nUpper, long(((SwTxtFrm*)pOwn)->GetLineSpace()) );
+            if ( pPre->IsTxtFrm() )
+                nUpper = Max( nUpper, long(((SwTxtFrm*)pPre)->GetLineSpace()) );
+        }
+    }
+    else if( rThis.GetAttrSet()->GetDoc()->IsParaSpaceMaxAtPages() &&
+             CastFlowFrm( pOwn )->HasParaSpaceAtPages( rThis.IsSctFrm() ) )
+        nUpper = pAttrs->GetULSpace().GetUpper();
+
+    nUpper += pAttrs->GetTopLine( &rThis );
+
+    delete pAccess;
+    return nUpper;
+}
+
+/*************************************************************************
+|*
+|*  BOOL SwFlowFrm::CheckMoveFwd()
+|*
+|*  Beschreibung        Moved den Frm vorwaerts wenn es durch die aktuellen
+|*      Bedingungen und Attribute notwendig erscheint.
+|*  Ersterstellung      MA 05. Dec. 96
+|*  Letzte Aenderung    MA 09. Mar. 98
+|*
+|*************************************************************************/
+
+
+BOOL SwFlowFrm::CheckMoveFwd( BOOL &rbMakePage, BOOL bKeep, BOOL bMovedBwd )
+{
+    const SwFrm* pNxt = rThis.GetIndNext();
+
+    if ( bKeep && //!bMovedBwd &&
+         ( !pNxt || ( pNxt->IsTxtFrm() && ((SwTxtFrm*)pNxt)->IsEmptyMaster() ) ) &&
+         ( 0 != (pNxt = rThis.FindNext()) ) && IsKeepFwdMoveAllowed() )
+    {
+        if( pNxt->IsSctFrm() )
+        {   // Nicht auf leere SectionFrms hereinfallen
+            const SwFrm* pTmp = NULL;
+            while( pNxt && pNxt->IsSctFrm() &&
+                   ( !((SwSectionFrm*)pNxt)->GetSection() ||
+                     !( pTmp = ((SwSectionFrm*)pNxt)->ContainsAny() ) ) )
+            {
+                pNxt = pNxt->FindNext();
+                pTmp = NULL;
+            }
+            if( pTmp )
+                pNxt = pTmp; // the content of the next notempty sectionfrm
+        }
+        if( pNxt && pNxt->GetValidPosFlag() )
+        {
+            BOOL bMove = FALSE;
+            const SwSectionFrm *pSct = rThis.FindSctFrm();
+            if( pSct && !pSct->GetValidSizeFlag() )
+            {
+                const SwSectionFrm* pNxtSct = pNxt->FindSctFrm();
+                if( pNxtSct && pSct->IsAnFollow( pNxtSct ) )
+                    bMove = TRUE;
+            }
+            else
+                bMove = TRUE;
+            if( bMove )
+            {
+                //Keep together with the following frame
+                MoveFwd( rbMakePage, FALSE );
+                return TRUE;
+            }
+        }
+    }
+
+    BOOL bMovedFwd = FALSE;
+
+    if ( rThis.GetIndPrev() )
+    {
+        if ( IsPrevObjMove() ) //Auf Objekte des Prev Ruecksicht nehmen?
+        {
+            bMovedFwd = TRUE;
+            if ( !MoveFwd( rbMakePage, FALSE ) )
+                rbMakePage = FALSE;
+        }
+        else
+        {
+            if ( IsPageBreak( FALSE ) )
+            {
+                while ( MoveFwd( rbMakePage, TRUE ) )
+                        /* do nothing */;
+                rbMakePage = FALSE;
+                bMovedFwd = TRUE;
+            }
+            else if ( IsColBreak ( FALSE ) )
+            {
+                const SwPageFrm *pPage = rThis.FindPageFrm();
+                SwFrm *pCol = rThis.FindColFrm();
+                do
+                {   MoveFwd( rbMakePage, FALSE );
+                    SwFrm *pTmp = rThis.FindColFrm();
+                    if( pTmp != pCol )
+                    {
+                        bMovedFwd = TRUE;
+                        pCol = pTmp;
+                    }
+                    else
+                        break;
+                } while ( IsColBreak( FALSE ) );
+                if ( pPage != rThis.FindPageFrm() )
+                    rbMakePage = FALSE;
+            }
+        }
+    }
+    return bMovedFwd;
+}
+
+/*************************************************************************
+|*
+|*  BOOL SwFlowFrm::MoveFwd()
+|*
+|*  Beschreibung        Returnwert sagt, ob der Frm die Seite gewechselt hat.
+|*  Ersterstellung      MA 05. Dec. 96
+|*  Letzte Aenderung    MA 05. Dec. 96
+|*
+|*************************************************************************/
+
+
+BOOL SwFlowFrm::MoveFwd( BOOL bMakePage, BOOL bPageBreak, BOOL bMoveAlways )
+{
+//!!!!MoveFtnCntFwd muss ggf. mitgepflegt werden.
+    SwFtnBossFrm *pOldBoss = rThis.FindFtnBossFrm();
+    if ( rThis.IsInFtn() )
+        return ((SwCntntFrm&)rThis).MoveFtnCntFwd( bMakePage, pOldBoss );
+
+    if( !IsFwdMoveAllowed() && !bMoveAlways )
+    {
+        BOOL bNoFwd = TRUE;
+        if( rThis.IsInSct() )
+        {
+            SwFtnBossFrm* pBoss = rThis.FindFtnBossFrm();
+            bNoFwd = !pBoss->IsInSct() || ( !pBoss->Lower()->GetNext() &&
+                     !pBoss->GetPrev() );
+        }
+        if( bNoFwd )
+        {
+            //Fuer PageBreak ist das Moven erlaubt, wenn der Frm nicht
+            //bereits der erste der Seite ist.
+            if ( !bPageBreak )
+                return FALSE;
+
+            const SwFrm *pCol = rThis.FindColFrm();
+            if ( !pCol || !pCol->GetPrev() )
+                return FALSE;
+        }
+    }
+
+    BOOL bSamePage = TRUE;
+    SwLayoutFrm *pNewUpper =
+            rThis.GetLeaf( bMakePage ? MAKEPAGE_INSERT : MAKEPAGE_NONE, TRUE );
+
+    if ( pNewUpper )
+    {
+        PROTOCOL_ENTER( &rThis, PROT_MOVE_FWD, 0, 0 );
+        SwPageFrm *pOldPage = pOldBoss->FindPageFrm();
+        //Wir moven uns und alle direkten Nachfolger vor den ersten
+        //CntntFrm unterhalb des neuen Uppers.
+
+        // Wenn unser NewUpper in einem SectionFrm liegt, muessen wir
+        // verhindern, dass sich dieser im Calc selbst zerstoert
+        SwSectionFrm* pSect = pNewUpper->FindSctFrm();
+        BOOL bUnlock = FALSE;
+        if( pSect )
+        {
+            // Wenn wir nur innerhalb unseres SectionFrms die Spalte wechseln,
+            // rufen wir lieber kein Calc, sonst wird noch der SectionFrm
+            // formatiert, der wiederum uns ruft etc.
+            if( pSect != rThis.FindSctFrm() )
+            {
+                bUnlock = !pSect->IsColLocked();
+                pSect->ColLock();
+                pNewUpper->Calc();
+                if( bUnlock )
+                    pSect->ColUnlock();
+            }
+        }
+        else
+            pNewUpper->Calc();
+
+        SwFtnBossFrm *pNewBoss = pNewUpper->FindFtnBossFrm();
+        BOOL bBossChg = pNewBoss != pOldBoss;
+        pNewBoss = pNewBoss->FindFtnBossFrm( TRUE );
+        pOldBoss = pOldBoss->FindFtnBossFrm( TRUE );
+        SwPageFrm* pNewPage = pOldPage;
+
+        //Erst die Fussnoten verschieben!
+        BOOL bFtnMoved = FALSE;
+        if ( pNewBoss != pOldBoss )
+        {
+            pNewPage = pNewBoss->FindPageFrm();
+            bSamePage = pNewPage == pOldPage;
+            //Damit die Fussnoten nicht auf dumme Gedanken kommen
+            //setzen wir hier die Deadline.
+            SwSaveFtnHeight aHeight( pOldBoss,
+                pOldBoss->Frm().Top() + pOldBoss->Frm().Height() );
+            SwCntntFrm* pStart = rThis.IsCntntFrm() ?
+                (SwCntntFrm*)&rThis : ((SwLayoutFrm&)rThis).ContainsCntnt();
+            ASSERT( pStart, "MoveFwd: Missing Content" );
+            SwLayoutFrm* pBody = pStart ? ( pStart->IsTxtFrm() ?
+                (SwLayoutFrm*)((SwTxtFrm*)pStart)->FindBodyFrm() : 0 ) : 0;
+            if( pBody )
+                bFtnMoved = pBody->MoveLowerFtns( pStart, pOldBoss, pNewBoss,
+                                                  FALSE);
+        }
+        // Bei SectionFrms ist es moeglich, dass wir selbst durch pNewUpper->Calc()
+        // bewegt wurden, z. B. in den pNewUpper.
+        // MoveSubTree bzw. PasteTree ist auf so etwas nicht vorbereitet.
+        if( pNewUpper != rThis.GetUpper() )
+        {
+            MoveSubTree( pNewUpper, pNewUpper->Lower() );
+            if ( bFtnMoved && !bSamePage )
+            {
+                pOldPage->UpdateFtnNum();
+                pNewPage->UpdateFtnNum();
+            }
+
+            if( bBossChg )
+            {
+                rThis.Prepare( PREP_BOSS_CHGD, 0, FALSE );
+                if( !bSamePage )
+                {
+                    ViewShell *pSh = rThis.GetShell();
+                    if ( pSh && !pSh->Imp()->IsUpdateExpFlds() )
+                        pSh->GetDoc()->SetNewFldLst();  //Wird von CalcLayout() hinterher erledigt!
+                    pNewPage->InvalidateSpelling();
+                    pNewPage->InvalidateAutoCompleteWords();
+                }
+            }
+        }
+        //Bei Sections kann es passieren, das wir gleich  in den Follow geflutscht
+        //sind. Dadurch wird nicht vom GetLeaf fuer die richtige Seite gesorgt.
+        //Das muessen wir fuer diesen Fall pruefen.
+        if ( !bSamePage && pNewUpper->IsInSct() &&
+             ( rThis.GetAttrSet()->GetPageDesc().GetPageDesc() ||
+               pOldPage->GetPageDesc()->GetFollow() != pNewPage->GetPageDesc() ) )
+            SwFrm::CheckPageDescs( pNewPage, FALSE );
+    }
+    return bSamePage;
+}
+
+
+/*************************************************************************
+|*
+|*  BOOL SwFlowFrm::MoveBwd()
+|*
+|*  Beschreibung        Returnwert sagt, ob der Frm die Seite wechseln soll.
+|*                      Sollte von abgeleiteten Klassen gerufen werden.
+|*                      Das moven selbst muessen die abgeleiteten uebernehmen.
+|*  Ersterstellung      MA 05. Dec. 96
+|*  Letzte Aenderung    MA 05. Dec. 96
+|*
+|*************************************************************************/
+
+extern BOOL lcl_Apres( SwLayoutFrm* pFirst, SwLayoutFrm* pSecond );
+
+BOOL SwFlowFrm::MoveBwd( BOOL &rbReformat )
+{
+    SwFlowFrm::SetMoveBwdJump( FALSE );
+
+    SwFtnFrm* pFtn = rThis.FindFtnFrm();
+    if ( pFtn && pFtn->IsBackMoveLocked() )
+        return FALSE;
+
+    SwFtnBossFrm * pOldBoss = rThis.FindFtnBossFrm();
+    SwPageFrm * const pOldPage = pOldBoss->FindPageFrm();
+    SwLayoutFrm *pNewUpper = 0;
+    FASTBOOL bCheckPageDescs = FALSE;
+
+    if ( pFtn )
+    {
+        //Wenn die Fussnote bereits auf der gleichen Seite/Spalte wie die Referenz
+        //steht, ist nix mit zurueckfliessen. Die breaks brauche fuer die
+        //Fussnoten nicht geprueft zu werden.
+        BOOL bEndnote = pFtn->GetAttr()->GetFtn().IsEndNote();
+        SwFrm* pRef = bEndnote && pFtn->IsInSct() ?
+            pFtn->FindSctFrm()->FindLastCntnt( FINDMODE_LASTCNT ) : pFtn->GetRef();
+        ASSERT( pRef, "MoveBwd: Endnote for an empty section?" );
+        if( !bEndnote )
+            pOldBoss = pOldBoss->FindFtnBossFrm( TRUE );
+        SwFtnBossFrm *pRefBoss = pRef->FindFtnBossFrm( !bEndnote );
+        if( pOldBoss != pRefBoss &&
+            ( !bEndnote || lcl_Apres( pRefBoss, pOldBoss ) ) )
+            pNewUpper = rThis.GetLeaf( MAKEPAGE_FTN, FALSE );
+    }
+    else if ( IsPageBreak( TRUE ) ) //PageBreak zu beachten?
+    {
+        //Wenn auf der vorhergehenden Seite kein Frm im Body steht,
+        //so ist das Zurueckfliessen trotz Pagebreak sinnvoll
+        //(sonst: leere Seite).
+        //Natuerlich muessen Leereseiten geflissentlich uebersehen werden!
+        const SwFrm *pFlow = &rThis;
+        do
+        {   pFlow = pFlow->FindPrev();
+        } while ( pFlow && ( pFlow->FindPageFrm() == pOldPage ||
+                  !pFlow->IsInDocBody() ) );
+        if ( pFlow )
+        {
+            long nDiff = pOldPage->GetPhyPageNum() - pFlow->GetPhyPageNum();
+            if ( nDiff > 1 )
+            {
+                if ( ((SwPageFrm*)pOldPage->GetPrev())->IsEmptyPage() )
+                    nDiff -= 1;
+                if ( nDiff > 1 )
+                {
+                    pNewUpper = rThis.GetLeaf( MAKEPAGE_NONE, FALSE );
+                    bCheckPageDescs = TRUE;
+                }
+            }
+        }
+    }
+    else if ( IsColBreak( TRUE ) )
+    {
+        //Wenn in der vorhergehenden Spalte kein CntntFrm steht, so ist
+        //das Zurueckfliessen trotz ColumnBreak sinnvoll
+        //(sonst: leere Spalte).
+        if( rThis.IsInSct() )
+        {
+            pNewUpper = rThis.GetLeaf( MAKEPAGE_NONE, FALSE );
+            if( pNewUpper && !SwFlowFrm::IsMoveBwdJump() &&
+                ( pNewUpper->ContainsCntnt() ||
+                  ( ( !pNewUpper->IsColBodyFrm() ||
+                      !pNewUpper->GetUpper()->GetPrev() ) &&
+                    !pNewUpper->FindSctFrm()->GetPrev() ) ) )
+                pNewUpper = 0;
+        }
+        else
+        {
+            const SwFrm *pCol = rThis.FindColFrm();
+            BOOL bGoOn = TRUE;
+            BOOL bJump = FALSE;
+            do
+            {
+                if ( pCol->GetPrev() )
+                    pCol = pCol->GetPrev();
+                else
+                {
+                    bGoOn = FALSE;
+                    pCol = rThis.GetLeaf( MAKEPAGE_NONE, FALSE );
+                }
+                if ( pCol )
+                {
+                    // ColumnFrms jetzt mit BodyFrm
+                    SwLayoutFrm* pColBody = pCol->IsColumnFrm() ?
+                        (SwLayoutFrm*)((SwLayoutFrm*)pCol)->Lower() :
+                        (SwLayoutFrm*)pCol;
+                    if ( pColBody->ContainsCntnt() )
+                    {
+                        bGoOn = FALSE; // Hier gibt's Inhalt, wir akzeptieren diese
+                        // nur, wenn GetLeaf() das MoveBwdJump-Flag gesetzt hat.
+                        if( SwFlowFrm::IsMoveBwdJump() )
+                            pNewUpper = pColBody;
+                    }
+                    else
+                    {
+                        if( pNewUpper ) // Wir hatten schon eine leere Spalte, haben
+                            bJump = TRUE;   // also eine uebersprungen
+                        pNewUpper = pColBody;  // Diese leere Spalte kommt in Frage,
+                                               // trotzdem weitersuchen
+                    }
+                }
+            } while( bGoOn );
+            if( bJump )
+                SwFlowFrm::SetMoveBwdJump( TRUE );
+        }
+    }
+    else //Keine Breaks also kann ich zurueckfliessen
+        pNewUpper = rThis.GetLeaf( MAKEPAGE_NONE, FALSE );
+
+    //Fuer Follows ist das zurueckfliessen nur dann erlaubt wenn in der
+    //neuen Umgebung kein Nachbar existiert (denn dieses waere der Master).
+    //(6677)Wenn allerdings leere Blaetter uebersprungen wurden wird doch gemoved.
+    if ( pNewUpper && IsFollow() && pNewUpper->Lower() )
+    {
+        if ( SwFlowFrm::IsMoveBwdJump() )
+        {
+            //Nicht hinter den Master sondern in das naechstfolgende leere
+            //Blatt moven.
+            SwFrm *pFrm = pNewUpper->Lower();
+            while ( pFrm->GetNext() )
+                pFrm = pFrm->GetNext();
+            pNewUpper = pFrm->GetLeaf( MAKEPAGE_INSERT, TRUE );
+            if( pNewUpper == rThis.GetUpper() ) //Landen wir wieder an der gleichen Stelle?
+                pNewUpper = NULL;           //dann eruebrigt sich das Moven
+        }
+        else
+            pNewUpper = 0;
+    }
+    if ( pNewUpper && !ShouldBwdMoved( pNewUpper, TRUE, rbReformat ) )
+    {
+        if( !pNewUpper->Lower() )
+        {
+            if( pNewUpper->IsFtnContFrm() )
+            {
+                pNewUpper->Cut();
+                delete pNewUpper;
+            }
+            else
+            {
+                SwSectionFrm* pSectFrm = pNewUpper->FindSctFrm();
+                if( pSectFrm && !pSectFrm->IsColLocked() && !pSectFrm->ContainsCntnt() )
+                {
+                    pSectFrm->DelEmpty( TRUE );
+                    delete pSectFrm;
+                    rThis.bValidPos = TRUE;
+                }
+            }
+        }
+        pNewUpper = 0;
+    }
+    if ( pNewUpper )
+    {
+        PROTOCOL_ENTER( &rThis, PROT_MOVE_BWD, 0, 0 );
+        if ( pNewUpper->IsFtnContFrm() )
+        {
+            //Kann sein, dass ich einen Container bekam.
+            SwFtnFrm *pOld = rThis.FindFtnFrm();
+            SwFtnFrm *pNew = new SwFtnFrm( pOld->GetFmt(),
+                                           pOld->GetRef(), pOld->GetAttr() );
+            if ( pOld->GetMaster() )
+            {
+                pNew->SetMaster( pOld->GetMaster() );
+                pOld->GetMaster()->SetFollow( pNew );
+            }
+            pNew->SetFollow( pOld );
+            pOld->SetMaster( pNew );
+            pNew->Paste( pNewUpper );
+            pNewUpper = pNew;
+        }
+        if( pNewUpper->IsFtnFrm() && rThis.IsInSct() )
+        {
+            SwSectionFrm* pSct = rThis.FindSctFrm();
+            //Wenn wir in einem Bereich in einer Fussnote stecken, muss im
+            //neuen Upper ggf. ein SwSectionFrm angelegt werden
+            if( pSct->IsInFtn() )
+            {
+                SwFrm* pTmp = pNewUpper->Lower();
+                if( pTmp )
+                {
+                    while( pTmp->GetNext() )
+                        pTmp = pTmp->GetNext();
+                    if( !pTmp->IsSctFrm() ||
+                        ((SwSectionFrm*)pTmp)->GetFollow() != pSct )
+                        pTmp = NULL;
+                }
+                if( pTmp )
+                    pNewUpper = (SwSectionFrm*)pTmp;
+                else
+                {
+                    pSct = new SwSectionFrm( *pSct, TRUE );
+                    pSct->Paste( pNewUpper );
+                    pNewUpper = pSct;
+                    pSct->SimpleFormat();
+                }
+            }
+        }
+        BOOL bUnlock = FALSE;
+        BOOL bFollow;
+        //Section locken, sonst kann sie bei Fluss des einzigen Cntnt etwa
+        //von zweiter in die erste Spalte zerstoert werden.
+        SwSectionFrm* pSect = pNewUpper->FindSctFrm();
+        if( pSect )
+        {
+            bUnlock = !pSect->IsColLocked();
+            pSect->ColLock();
+            bFollow = pSect->HasFollow();
+        }
+        pNewUpper->Calc();
+        rThis.Cut();
+        if( bUnlock )
+        {
+            if( pSect->HasFollow() != bFollow )
+                pSect->_InvalidateSize();
+            pSect->ColUnlock();
+        }
+
+        rThis.Paste( pNewUpper );
+
+        SwPageFrm *pNewPage = pNewUpper->FindPageFrm();
+        if( pNewPage != pOldPage )
+        {
+            rThis.Prepare( PREP_BOSS_CHGD, (const void*)pOldPage, FALSE );
+            ViewShell *pSh = rThis.GetShell();
+            if ( pSh && !pSh->Imp()->IsUpdateExpFlds() )
+                pSh->GetDoc()->SetNewFldLst();  //Wird von CalcLayout() hinterher eledigt!
+            pNewPage->InvalidateSpelling();
+            pNewPage->InvalidateAutoCompleteWords();
+            if ( bCheckPageDescs && pNewPage->GetNext() )
+                SwFrm::CheckPageDescs( (SwPageFrm*)pNewPage->GetNext(), FALSE);
+            else if ( rThis.GetAttrSet()->GetPageDesc().GetPageDesc() )
+            {
+                //Erste Seite wird etwa durch Ausblenden eines Bereiches leer
+                SwFrm::CheckPageDescs( (SwPageFrm*)pNewPage, FALSE);
+            }
+        }
+    }
+    return pNewUpper != 0;
+}
+
+/*************************************************************************
+|*
+|*  SwFlowFrm::CastFlowFrm
+|*
+|*  Ersterstellung      MA 03. May. 95
+|*  Letzte Aenderung    AMA 02. Dec. 97
+|*
+|*************************************************************************/
+
+SwFlowFrm *SwFlowFrm::CastFlowFrm( SwFrm *pFrm )
+{
+    if ( pFrm->IsCntntFrm() )
+        return (SwCntntFrm*)pFrm;
+    if ( pFrm->IsTabFrm() )
+        return (SwTabFrm*)pFrm;
+    if ( pFrm->IsSctFrm() )
+        return (SwSectionFrm*)pFrm;
+    return 0;
+}
+
+const SwFlowFrm *SwFlowFrm::CastFlowFrm( const SwFrm *pFrm )
+{
+    if ( pFrm->IsCntntFrm() )
+        return (SwCntntFrm*)pFrm;
+    if ( pFrm->IsTabFrm() )
+        return (SwTabFrm*)pFrm;
+    if ( pFrm->IsSctFrm() )
+        return (SwSectionFrm*)pFrm;
+    return 0;
+}
+
+
+
+
+
diff --git a/sw/source/core/layout/fly.cxx b/sw/source/core/layout/fly.cxx
new file mode 100644
index 000000000000..c221afb099d6
--- /dev/null
+++ b/sw/source/core/layout/fly.cxx
@@ -0,0 +1,2202 @@
+/*************************************************************************
+ *
+ *  $RCSfile: fly.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:22 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "hintids.hxx"
+#ifndef _SFXITEMITER_HXX //autogen
+#include 
+#endif
+#ifndef _IMAP_HXX //autogen
+#include 
+#endif
+#ifndef _GRAPH_HXX //autogen
+#include 
+#endif
+#ifndef _POLY_HXX //autogen
+#include 
+#endif
+#ifndef _CONTDLG_HXX_ //autogen
+#include 
+#endif
+#ifndef _SVX_PROTITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_OPAQITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_ULSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFSIZE_HXX //autogen
+#include 
+#endif
+#ifndef _FMTCLDS_HXX //autogen
+#include 
+#endif
+#ifndef _FMTCNTNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTURL_HXX //autogen
+#include 
+#endif
+#ifndef _FMTSRND_HXX //autogen
+#include 
+#endif
+#ifndef _FMTORNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTPDSC_HXX //autogen
+#include 
+#endif
+#ifndef _FMTCNCT_HXX //autogen
+#include 
+#endif
+
+
+#include "doc.hxx"
+#include "viewsh.hxx"
+#include "layouter.hxx"
+#include "pagefrm.hxx"
+#include "rootfrm.hxx"
+#include "cntfrm.hxx"
+#include "pam.hxx"
+#include "frmatr.hxx"
+#include "viewimp.hxx"
+#include "errhdl.hxx"
+#include "dcontact.hxx"
+#include "dflyobj.hxx"
+#include "dview.hxx"
+#include "flyfrm.hxx"
+#include "frmtool.hxx"
+#include "frmfmt.hxx"
+#include "hints.hxx"
+#include "swregion.hxx"
+#include "frmsh.hxx"
+#include "tabfrm.hxx"
+#include "txtfrm.hxx"
+#include "ndnotxt.hxx"
+#include "notxtfrm.hxx"   // GetGrfArea
+#include "flyfrms.hxx"
+#include "ndindex.hxx"   // GetGrfArea
+#include "sectfrm.hxx"
+
+//Aus dem PageFrm:
+
+SV_IMPL_PTRARR_SORT(SwSortDrawObjs,SdrObjectPtr)
+
+
+/*************************************************************************
+|*
+|*  SwFlyFrm::SwFlyFrm()
+|*
+|*  Ersterstellung      MA 28. Sep. 92
+|*  Letzte Aenderung    MA 09. Apr. 99
+|*
+|*************************************************************************/
+
+SwFlyFrm::SwFlyFrm( SwFlyFrmFmt *pFmt, SwFrm *pAnch ) :
+    SwLayoutFrm( pFmt ),
+    aRelPos(),
+    pAnchor( 0 ),
+    pPrevLink( 0 ),
+    pNextLink( 0 ),
+    bInCnt( FALSE ),
+    bAtCnt( FALSE ),
+    bLayout( FALSE ),
+    bAutoPosition( FALSE )
+{
+    nType = FRM_FLY;
+
+    bInvalid = bNotifyBack = TRUE;
+    bLocked  = bMinHeight =
+    bHeightClipped = bWidthClipped = bFormatHeightOnly = FALSE;
+
+    //Grosseneinstellung, Fixe groesse ist immer die Breite
+    const SwFmtFrmSize &rFrmSize = pFmt->GetFrmSize();
+    bVarHeight = TRUE;
+    bFixWidth = TRUE;
+    Frm().Width( rFrmSize.GetWidth() );
+    Frm().Height( rFrmSize.GetHeight() );
+
+    //Hoehe Fix oder Variabel oder was?
+    if ( rFrmSize.GetSizeType() == ATT_MIN_SIZE )
+        bMinHeight = TRUE;
+    else if ( rFrmSize.GetSizeType() == ATT_FIX_SIZE )
+        bFixHeight = TRUE;
+
+    //Spalten?
+    const SwFmtCol &rCol = pFmt->GetCol();
+    if ( rCol.GetNumCols() > 1 )
+    {
+        //PrtArea ersteinmal so gross wie der Frm, damit die Spalten
+        //vernuenftig eingesetzt werden koennen; das schaukelt sich dann
+        //schon zurecht.
+        Prt().Width( Frm().Width() );
+        Prt().Height( Frm().Height() );
+        const SwFmtCol aOld; //ChgColumns() verlaesst sich darauf, dass auch ein
+                             //Old-Wert hereingereicht wird.
+        ChgColumns( aOld, rCol );
+    }
+
+    //Erst das Init, dann den Inhalt, denn zum Inhalt koennen  widerum
+    //Objekte/Rahmen gehoeren die dann angemeldet werden.
+    InitDrawObj( FALSE );
+
+    //Fuer Verkettungen kann jetzt die Verbindung aufgenommen werden. Wenn
+    //ein Nachbar nicht existiert, so macht das nichts, denn dieser wird ja
+    //irgendwann Konsturiert und nimmt dann die Verbindung auf.
+    const SwFmtChain &rChain = pFmt->GetChain();
+    if ( rChain.GetPrev() || rChain.GetNext() )
+    {
+        if ( rChain.GetNext() )
+        {
+            SwFlyFrm *pFollow = FindChainNeighbour( *rChain.GetNext(), pAnch );
+            if ( pFollow )
+            {
+                ASSERT( !pFollow->GetPrevLink(), "wrong chain detected" );
+                if ( !pFollow->GetPrevLink() )
+                    SwFlyFrm::ChainFrames( this, pFollow );
+            }
+        }
+        if ( rChain.GetPrev() )
+        {
+            SwFlyFrm *pMaster = FindChainNeighbour( *rChain.GetPrev(), pAnch );
+            if ( pMaster )
+            {
+                ASSERT( !pMaster->GetNextLink(), "wrong chain detected" );
+                if ( !pMaster->GetNextLink() )
+                    SwFlyFrm::ChainFrames( pMaster, this );
+            }
+        }
+    }
+
+    if ( !GetPrevLink() ) //Inhalt gehoert sonst immer dem Master und meiner Zaehlt nicht
+    {
+        const SwFmtCntnt &rCntnt = pFmt->GetCntnt();
+        ASSERT( rCntnt.GetCntntIdx(), ":-( Kein Inhalt vorbereitet." );
+        ULONG nIndex = rCntnt.GetCntntIdx()->GetIndex();
+        // Lower() bedeutet SwColumnFrm, eingefuegt werden muss der Inhalt dann in den (Column)BodyFrm
+        ::_InsertCnt( Lower() ? (SwLayoutFrm*)((SwLayoutFrm*)Lower())->Lower() : (SwLayoutFrm*)this,
+                      pFmt->GetDoc(), nIndex );
+
+        //NoTxt haben immer eine FixHeight.
+        if ( Lower() && Lower()->IsNoTxtFrm() )
+        {
+            bFixHeight = TRUE;
+            bMinHeight = FALSE;
+        }
+    }
+
+    //Und erstmal in den Wald stellen die Kiste, damit bei neuen Dokument nicht
+    //unnoetig viel formatiert wird.
+    Frm().Pos().X() = Frm().Pos().Y() = WEIT_WECH;
+}
+
+/*************************************************************************
+|*
+|*  SwFlyFrm::~SwFlyFrm()
+|*
+|*  Ersterstellung      MA 28. Sep. 92
+|*  Letzte Aenderung    MA 07. Jul. 95
+|*
+|*************************************************************************/
+
+SwFlyFrm::~SwFlyFrm()
+{
+    if( GetFmt() && !GetFmt()->GetDoc()->IsInDtor() )
+    {
+        //Aus der Verkettung loessen.
+        if ( GetPrevLink() )
+            UnchainFrames( GetPrevLink(), this );
+        if ( GetNextLink() )
+            UnchainFrames( this, GetNextLink() );
+
+        //Unterstruktur zerstoeren, wenn dies erst im LayFrm DTor passiert ist's
+        //zu spaet, denn dort ist die Seite nicht mehr erreichbar (muss sie aber
+        //sein, damit sich ggf. weitere Flys abmelden koennen).
+        SwFrm *pFrm = pLower;
+        while ( pFrm )
+        {
+            //Erst die Flys des Frm vernichten, denn diese koennen sich sonst nach
+            //dem Remove nicht mehr bei der Seite abmelden.
+            while ( pFrm->GetDrawObjs() && pFrm->GetDrawObjs()->Count() )
+            {   SdrObject *pObj = (*pFrm->GetDrawObjs())[0];
+                SdrObjUserCall *pUserCall;
+                if ( pObj->IsWriterFlyFrame() )
+                    delete ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+                else if ( 0 != ( pUserCall = GetUserCall(pObj) ) )
+                    ((SwDrawContact*)pUserCall)->DisconnectFromLayout();
+            }
+            pFrm->Remove();
+            delete pFrm;
+            pFrm = pLower;
+        }
+
+        //Damit kein zerstoerter Cntnt als Turbo bei der Root angemeldet bleiben
+        //kann verhindere ich hier, dass dort ueberhaupt noch einer angemeldet
+        //ist.
+        InvalidatePage();
+
+        //Tschuess sagen.
+        if ( pAnchor )
+            pAnchor->RemoveFly( this );
+    }
+    FinitDrawObj();
+}
+
+/*************************************************************************
+|*
+|*  SwFlyFrm::InitDrawObj()
+|*
+|*  Ersterstellung      MA 02. Dec. 94
+|*  Letzte Aenderung    MA 30. Nov. 95
+|*
+|*************************************************************************/
+#pragma optimize("",off)
+
+void SwFlyFrm::InitDrawObj( BOOL bNotify )
+{
+    //ContactObject aus dem Format suchen. Wenn bereits eines existiert, so
+    //braucht nur eine neue Ref erzeugt werden, anderfalls ist es jetzt an
+    //der Zeit das Contact zu erzeugen.
+    SwClientIter aIter( *GetFmt() );
+    SwFlyDrawContact *pContact = (SwFlyDrawContact*)
+                                        aIter.First( TYPE(SwFlyDrawContact) );
+    if ( !pContact )
+        pContact = new SwFlyDrawContact( (SwFlyFrmFmt*)GetFmt(),
+                            GetFmt()->GetDoc()->MakeDrawModel() );
+    ASSERT( pContact, "InitDrawObj failed" );
+    pDrawObj = pContact->CreateNewRef( this );
+
+    //Den richtigen Layer setzen.
+    pDrawObj->SetLayer( GetFmt()->GetOpaque().GetValue() ?
+                            GetFmt()->GetDoc()->GetHeavenId() :
+                            GetFmt()->GetDoc()->GetHellId() );
+    if ( bNotify )
+        NotifyDrawObj();
+}
+
+#pragma optimize("",on)
+
+/*************************************************************************
+|*
+|*  SwFlyFrm::FinitDrawObj()
+|*
+|*  Ersterstellung      MA 12. Dec. 94
+|*  Letzte Aenderung    MA 15. May. 95
+|*
+|*************************************************************************/
+
+void SwFlyFrm::FinitDrawObj()
+{
+    if ( !pDrawObj )
+        return;
+
+    //Bei den SdrPageViews abmelden falls das Objekt dort noch selektiert ist.
+    if ( !GetFmt()->GetDoc()->IsInDtor() )
+    {
+        ViewShell *p1St = GetShell();
+        if ( p1St )
+        {
+            ViewShell *pSh = p1St;
+            do
+            {   //z.Zt. kann das Drawing nur ein Unmark auf alles, weil das
+                //Objekt bereits Removed wurde.
+                if( pSh->HasDrawView() )
+                    pSh->Imp()->GetDrawView()->UnmarkAll();
+                pSh = (ViewShell*)pSh->GetNext();
+
+            } while ( pSh != p1St );
+        }
+    }
+
+    //VirtObject mit in das Grab nehmen. Wenn das letzte VirObject
+    //zerstoert wird, mussen das DrawObject und DrawContact ebenfalls
+    //zerstoert werden.
+    SwFlyDrawContact *pMyContact = 0;
+    if ( GetFmt() )
+    {
+        SwClientIter aIter( *GetFmt() );
+        aIter.GoStart();
+        do {
+            if ( aIter()->ISA(SwFrm) && (SwFrm*)aIter() != this )
+            {
+                pMyContact = 0;
+                break;
+            }
+            if( !pMyContact && aIter()->ISA(SwFlyDrawContact) )
+                pMyContact = (SwFlyDrawContact*)aIter();
+            aIter++;
+        } while( aIter() );
+    }
+
+    pDrawObj->SetUserCall( 0 ); //Ruft sonst Delete des ContactObj
+    delete pDrawObj;            //Meldet sich selbst beim Master ab.
+    if ( pMyContact )
+        delete pMyContact;      //zerstoert den Master selbst.
+}
+
+/*************************************************************************
+|*
+|*  SwFlyFrm::ChainFrames()
+|*
+|*  Ersterstellung      MA 29. Oct. 97
+|*  Letzte Aenderung    MA 20. Jan. 98
+|*
+|*************************************************************************/
+
+void SwFlyFrm::ChainFrames( SwFlyFrm *pMaster, SwFlyFrm *pFollow )
+{
+    ASSERT( pMaster && pFollow, "uncomplete chain" );
+    ASSERT( !pMaster->GetNextLink(), "link can not be changed" );
+    ASSERT( !pFollow->GetPrevLink(), "link can not be changed" );
+
+    pMaster->pNextLink = pFollow;
+    pFollow->pPrevLink = pMaster;
+
+    if ( pMaster->ContainsCntnt() )
+    {
+        //Damit ggf. ein Textfluss zustande kommt muss invalidiert werden.
+        SwFrm *pInva = pMaster->FindLastLower();
+        const long nBottom = pMaster->Prt().Bottom() + pMaster->Frm().Top();
+        while ( pInva )
+        {
+            if ( pInva->Frm().Bottom() >= nBottom )
+            {
+                pInva->InvalidateSize();
+                pInva->Prepare( PREP_CLEAR );
+                pInva = pInva->FindPrev();
+            }
+            else
+                pInva = 0;
+        }
+    }
+
+    if ( pFollow->ContainsCntnt() )
+    {
+        //Es gibt nur noch den Inhalt des Masters, der Inhalt vom Follow
+        //hat keine Frames mehr (sollte immer nur genau ein leerer TxtNode sein).
+        SwFrm *pFrm = pFollow->ContainsCntnt();
+        ASSERT( !pFrm->IsTabFrm() && !pFrm->FindNext(), "follow in chain contains content" );
+        pFrm->Cut();
+        delete pFrm;
+    }
+}
+
+void SwFlyFrm::UnchainFrames( SwFlyFrm *pMaster, SwFlyFrm *pFollow )
+{
+    pMaster->pNextLink = 0;
+    pFollow->pPrevLink = 0;
+
+    if ( pFollow->ContainsCntnt() )
+    {
+        //Der Master saugt den Inhalt vom Follow auf
+        SwLayoutFrm *pUpper = pMaster;
+        if ( pUpper->Lower()->IsColumnFrm() )
+        {
+            pUpper = (SwLayoutFrm*)pUpper->Lower();
+            while ( pUpper->GetNext() ) // sucht die letzte Spalte
+                pUpper = (SwLayoutFrm*)pUpper->GetNext();
+            pUpper = (SwLayoutFrm*)((SwLayoutFrm*)pUpper)->Lower(); // der (Column)BodyFrm
+            ASSERT( pUpper && pUpper->IsColBodyFrm(), "Missing ColumnBody" );
+        }
+        SwFlyFrm *pFoll = pFollow;
+        while ( pFoll )
+        {
+            SwFrm *pTmp = ::SaveCntnt( pFoll );
+            if ( pTmp )
+                ::RestoreCntnt( pTmp, pUpper, pMaster->FindLastLower() );
+            pFoll->SetCompletePaint();
+            pFoll->InvalidateSize();
+            pFoll = pFoll->GetNextLink();
+        }
+    }
+
+    //Der Follow muss mit seinem eigenen Inhalt versorgt werden.
+    const SwFmtCntnt &rCntnt = pFollow->GetFmt()->GetCntnt();
+    ASSERT( rCntnt.GetCntntIdx(), ":-( Kein Inhalt vorbereitet." );
+    ULONG nIndex = rCntnt.GetCntntIdx()->GetIndex();
+    // Lower() bedeutet SwColumnFrm, dieser beinhaltet wieder einen SwBodyFrm
+    ::_InsertCnt( pFollow->Lower() ? (SwLayoutFrm*)((SwLayoutFrm*)pFollow->Lower())->Lower()
+                                   : (SwLayoutFrm*)pFollow,
+                  pFollow->GetFmt()->GetDoc(), ++nIndex );
+}
+
+/*************************************************************************
+|*
+|*  SwFlyFrm::FindChainNeighbour()
+|*
+|*  Ersterstellung      MA 11. Nov. 97
+|*  Letzte Aenderung    MA 09. Apr. 99
+|*
+|*************************************************************************/
+
+SwFlyFrm *SwFlyFrm::FindChainNeighbour( SwFrmFmt &rChain, SwFrm *pAnch )
+{
+    //Wir suchen denjenigen Fly, der in dem selben Bereich steht.
+    //Bereiche koennen zunaechst nur Kopf-/Fusszeilen oder Flys sein.
+
+    if ( !pAnch )           //Wenn ein Anchor uebergeben Wurde zaehlt dieser: Ctor!
+        pAnch = GetAnchor();
+
+    SwLayoutFrm *pLay;
+    if ( pAnch->IsInFly() )
+        pLay = pAnch->FindFlyFrm();
+    else
+    {
+        //FindFooterOrHeader taugt hier nicht, weil evtl. noch keine Verbindung
+        //zum Anker besteht.
+        pLay = pAnch->GetUpper();
+        while ( pLay && !(pLay->GetType() & (FRM_HEADER|FRM_FOOTER)) )
+            pLay = pLay->GetUpper();
+    }
+
+    SwClientIter aIter( rChain );
+    SwFlyFrm *pFly = (SwFlyFrm*)aIter.First( TYPE(SwFlyFrm ) );
+    if ( pLay )
+    {
+        while ( pFly )
+        {
+            if ( pFly->GetAnchor() )
+            {
+                if ( pFly->GetAnchor()->IsInFly() )
+                {
+                    if ( pFly->GetAnchor()->FindFlyFrm() == pLay )
+                        break;
+                }
+                else if ( pLay == pFly->FindFooterOrHeader() )
+                    break;
+            }
+            pFly = (SwFlyFrm*)aIter.Next();
+        }
+    }
+    else if ( pFly )
+    {
+        ASSERT( !aIter.Next(), "chain with more than one inkarnation" );
+    }
+    return pFly;
+}
+
+
+/*************************************************************************
+|*
+|*  SwFlyFrm::FindLastLower()
+|*
+|*  Ersterstellung      MA 29. Oct. 97
+|*  Letzte Aenderung    MA 29. Oct. 97
+|*
+|*************************************************************************/
+
+SwFrm *SwFlyFrm::FindLastLower()
+{
+    SwFrm *pRet = ContainsAny();
+    if ( pRet && pRet->IsInTab() )
+        pRet = pRet->FindTabFrm();
+    SwFrm *pNxt = pRet;
+    while ( pNxt && IsAnLower( pNxt ) )
+    {   pRet = pNxt;
+        pNxt = pNxt->FindNext();
+    }
+    return pRet;
+}
+
+
+/*************************************************************************
+|*
+|*  SwFlyFrm::FrmSizeChg()
+|*
+|*  Ersterstellung      MA 17. Dec. 92
+|*  Letzte Aenderung    MA 24. Jul. 96
+|*
+|*************************************************************************/
+
+BOOL SwFlyFrm::FrmSizeChg( const SwFmtFrmSize &rFrmSize )
+{
+    BOOL bRet = FALSE;
+    SwTwips nDiffHeight = Frm().Height();
+    if ( rFrmSize.GetSizeType() == ATT_VAR_SIZE )
+        bFixHeight = bMinHeight = FALSE;
+    else
+    {
+        if ( rFrmSize.GetSizeType() == ATT_FIX_SIZE )
+        {   bFixHeight = TRUE;
+            bMinHeight = FALSE;
+        }
+        else if ( rFrmSize.GetSizeType() == ATT_MIN_SIZE )
+        {   bFixHeight = FALSE;
+            bMinHeight = TRUE;
+        }
+        nDiffHeight -= rFrmSize.GetHeight();
+    }
+    //Wenn der Fly Spalten enthaehlt muessen der Fly und
+    //die Spalten schon einmal auf die Wunschwerte gebracht
+    //werden, sonst haben wir ein kleines Problem.
+    if ( Lower() )
+    {
+        if ( Lower()->IsColumnFrm() )
+        {
+            const SwRect aOld( AddSpacesToFrm() );
+            const Size   aOldSz( Prt().SSize() );
+            const SwTwips nDiffWidth = Frm().Width() - rFrmSize.GetWidth();
+            aFrm.Height( aFrm.Height() - nDiffHeight );
+            aFrm.Width ( aFrm.Width()  - nDiffWidth  );
+            aPrt.Height( aPrt.Height() - nDiffHeight );
+            aPrt.Width ( aPrt.Width()  - nDiffWidth  );
+            ChgLowersProp( aOldSz );
+            ::Notify( this, FindPageFrm(), aOld );
+            bValidPos = FALSE;
+            bRet = TRUE;
+        }
+        else if ( Lower()->IsNoTxtFrm() )
+        {
+            bFixHeight = TRUE;
+            bMinHeight = FALSE;
+        }
+    }
+    return bRet;
+}
+
+/*************************************************************************
+|*
+|*  SwFlyFrm::Modify()
+|*
+|*  Ersterstellung      MA 17. Dec. 92
+|*  Letzte Aenderung    MA 17. Jan. 97
+|*
+|*************************************************************************/
+
+void SwFlyFrm::Modify( SfxPoolItem * pOld, SfxPoolItem * pNew )
+{
+    BYTE nInvFlags = 0;
+
+    if( pNew && RES_ATTRSET_CHG == pNew->Which() )
+    {
+        SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() );
+        SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() );
+        SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld );
+        SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew );
+        while( TRUE )
+        {
+            _UpdateAttr( (SfxPoolItem*)aOIter.GetCurItem(),
+                         (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags,
+                         &aOldSet, &aNewSet );
+            if( aNIter.IsAtEnd() )
+                break;
+            aNIter.NextItem();
+            aOIter.NextItem();
+        }
+        if ( aOldSet.Count() || aNewSet.Count() )
+            SwLayoutFrm::Modify( &aOldSet, &aNewSet );
+    }
+    else
+        _UpdateAttr( pOld, pNew, nInvFlags );
+
+    if ( nInvFlags != 0 )
+    {
+        _Invalidate();
+        if ( nInvFlags & 0x01 )
+            _InvalidatePos();
+        if ( nInvFlags & 0x02 )
+            _InvalidateSize();
+        if ( nInvFlags & 0x04 )
+            _InvalidatePrt();
+        if ( nInvFlags & 0x08 )
+            SetNotifyBack();
+        if ( nInvFlags & 0x10 )
+            SetCompletePaint();
+        if ( ( nInvFlags & 0x40 ) && Lower() && Lower()->IsNoTxtFrm() )
+            ClrContourCache( GetVirtDrawObj() );
+        SwRootFrm *pRoot;
+        if ( nInvFlags & 0x20 && 0 != (pRoot = FindRootFrm()) )
+            pRoot->InvalidateBrowseWidth();
+    }
+}
+
+void SwFlyFrm::_UpdateAttr( SfxPoolItem *pOld, SfxPoolItem *pNew,
+                            BYTE &rInvFlags,
+                            SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet )
+{
+    BOOL bClear = TRUE;
+    const USHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
+    ViewShell *pSh = GetShell();
+    switch( nWhich )
+    {
+        case RES_VERT_ORIENT:
+        case RES_HORI_ORIENT:
+            //Achtung! _immer_ Aktion in ChgRePos() mitpflegen.
+            rInvFlags |= 0x09;
+            break;
+
+        case RES_SURROUND:
+            {
+            rInvFlags |= 0x40;
+            //Der Hintergrund muss benachrichtigt und Invalidiert werden.
+            const SwRect aTmp( AddSpacesToFrm() );
+            NotifyBackground( FindPageFrm(), aTmp, PREP_FLY_ATTR_CHG );
+
+            // Durch eine Umlaufaenderung von rahmengebundenen Rahmen kann eine
+            // vertikale Ausrichtung aktiviert/deaktiviert werden => MakeFlyPos
+            if( FLY_AT_FLY == GetFmt()->GetAnchor().GetAnchorId() )
+                rInvFlags |= 0x09;
+
+            //Ggf. die Kontur am Node loeschen.
+            if ( Lower() && Lower()->IsNoTxtFrm() &&
+                 !GetFmt()->GetSurround().IsContour() )
+            {
+                SwNoTxtNode *pNd = (SwNoTxtNode*)((SwCntntFrm*)Lower())->GetNode();
+                if ( pNd->HasContour() )
+                    pNd->SetContour( 0 );
+            }
+            }
+            break;
+
+        case RES_PROTECT:
+            {
+            const SvxProtectItem *pP = (SvxProtectItem*)pNew;
+            GetVirtDrawObj()->SetMoveProtect( pP->IsPosProtected()  );
+            GetVirtDrawObj()->SetResizeProtect( pP->IsSizeProtected() );
+            break;
+            }
+
+        case RES_COL:
+            {
+                ChgColumns( *(const SwFmtCol*)pOld, *(const SwFmtCol*)pNew );
+                const SwFmtFrmSize &rNew = GetFmt()->GetFrmSize();
+                if ( FrmSizeChg( rNew ) )
+                    NotifyDrawObj();
+                rInvFlags |= 0x1A;
+                break;
+            }
+
+        case RES_FRM_SIZE:
+        case RES_FMT_CHG:
+        {
+            const SwFmtFrmSize &rNew = GetFmt()->GetFrmSize();
+            if ( FrmSizeChg( rNew ) )
+                NotifyDrawObj();
+            rInvFlags |= 0x7F;
+            if ( RES_FMT_CHG == nWhich )
+            {
+                SwRect aNew( AddSpacesToFrm() );
+                SwRect aOld( aFrm );
+                const SvxULSpaceItem &rUL = ((SwFmtChg*)pOld)->pChangedFmt->GetULSpace();
+                aOld.Top( Max( aOld.Top() - long(rUL.GetUpper()), 0L ) );
+                aOld.SSize().Height()+= rUL.GetLower();
+                const SvxLRSpaceItem &rLR = ((SwFmtChg*)pOld)->pChangedFmt->GetLRSpace();
+                aOld.Left  ( Max( aOld.Left() - long(rLR.GetLeft()), 0L ) );
+                aOld.SSize().Width() += rLR.GetRight();
+                aNew.Union( aOld );
+                NotifyBackground( FindPageFrm(), aNew, PREP_CLEAR );
+
+                //Dummer Fall. Bei der Zusweisung einer Vorlage k”nnen wir uns
+                //nicht auf das alte Spaltenattribut verlassen. Da diese
+                //wenigstens anzahlgemass fuer ChgColumns vorliegen muessen,
+                //bleibt uns nur einen temporaeres Attribut zu basteln.
+                SwFmtCol aCol;
+                if ( Lower() && Lower()->IsColumnFrm() )
+                {
+                    USHORT nCol = 0;
+                    SwFrm *pTmp = Lower();
+                    do
+                    {   ++nCol;
+                        pTmp = pTmp->GetNext();
+                    } while ( pTmp );
+                    aCol.Init( nCol, 0, 1000 );
+                }
+                ChgColumns( aCol, GetFmt()->GetCol() );
+            }
+
+            SwFmtURL aURL( GetFmt()->GetURL() );
+            if ( aURL.GetMap() )
+            {
+                const SwFmtFrmSize &rOld = nWhich == RES_FRM_SIZE ?
+                                *(SwFmtFrmSize*)pNew :
+                                ((SwFmtChg*)pOld)->pChangedFmt->GetFrmSize();
+                //#35091# Kann beim Laden von Vorlagen mal 0 sein
+                if ( rOld.GetWidth() && rOld.GetHeight() )
+                {
+
+                    Fraction aScaleX( rOld.GetWidth(), rNew.GetWidth() );
+                    Fraction aScaleY( rOld.GetHeight(), rOld.GetHeight() );
+                    aURL.GetMap()->Scale( aScaleX, aScaleY );
+                    SwFrmFmt *pFmt = GetFmt();
+                    pFmt->LockModify();
+                    pFmt->SetAttr( aURL );
+                    pFmt->UnlockModify();
+                }
+            }
+            const SvxProtectItem &rP = GetFmt()->GetProtect();
+            GetVirtDrawObj()->SetMoveProtect( rP.IsPosProtected()   );
+            GetVirtDrawObj()->SetResizeProtect( rP.IsSizeProtected() );
+
+            if ( pSh )
+                pSh->InvalidateWindows( Frm() );
+            const BYTE nId = GetFmt()->GetOpaque().GetValue() ?
+                                GetFmt()->GetDoc()->GetHeavenId() :
+                                GetFmt()->GetDoc()->GetHellId();
+            GetVirtDrawObj()->SetLayer( nId );
+
+            if ( Lower() )
+            {
+                //Ggf. die Kontur am Node loeschen.
+                if( Lower()->IsNoTxtFrm() &&
+                     !GetFmt()->GetSurround().IsContour() )
+                {
+                    SwNoTxtNode *pNd = (SwNoTxtNode*)((SwCntntFrm*)Lower())->GetNode();
+                    if ( pNd->HasContour() )
+                        pNd->SetContour( 0 );
+                }
+                else if( !Lower()->IsColumnFrm() )
+                {
+                    SwFrm* pFrm = Lower();
+                    while( pFrm->GetNext() )
+                        pFrm = pFrm->GetNext();
+                    if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() )
+                        pFrm->Prepare( PREP_ADJUST_FRM );
+                }
+            }
+
+            break;
+        }
+        case RES_UL_SPACE:
+        case RES_LR_SPACE:
+            {
+            rInvFlags |= 0x41;
+            if ( GetFmt()->GetDoc()->IsBrowseMode() )
+                GetFmt()->GetDoc()->GetRootFrm()->InvalidateBrowseWidth();
+            SwRect aNew( AddSpacesToFrm() );
+            SwRect aOld( aFrm );
+            if ( RES_UL_SPACE == nWhich )
+            {
+                const SvxULSpaceItem &rUL = *(SvxULSpaceItem*)pNew;
+                aOld.Top( Max( aOld.Top() - long(rUL.GetUpper()), 0L ) );
+                aOld.SSize().Height()+= rUL.GetLower();
+            }
+            else
+            {
+                const SvxLRSpaceItem &rLR = *(SvxLRSpaceItem*)pNew;
+                aOld.Left  ( Max( aOld.Left() - long(rLR.GetLeft()), 0L ) );
+                aOld.SSize().Width() += rLR.GetRight();
+            }
+            aNew.Union( aOld );
+            NotifyBackground( FindPageFrm(), aNew, PREP_CLEAR );
+            }
+            break;
+
+        case RES_BOX:
+        case RES_SHADOW:
+            rInvFlags |= 0x17;
+            break;
+
+        case RES_OPAQUE:
+            {
+            if ( pSh )
+                pSh->InvalidateWindows( Frm() );
+            const BYTE nId = ((SvxOpaqueItem*)pNew)->GetValue() ?
+                                GetFmt()->GetDoc()->GetHeavenId() :
+                                GetFmt()->GetDoc()->GetHellId();
+            GetVirtDrawObj()->SetLayer( nId );
+            }
+            break;
+
+        case RES_URL:
+            //Das Interface arbeitet bei Textrahmen auf der Rahmengroesse,
+            //die Map muss sich aber auf die FrmSize beziehen
+            if ( (!Lower() || !Lower()->IsNoTxtFrm()) &&
+                 ((SwFmtURL*)pNew)->GetMap() && ((SwFmtURL*)pOld)->GetMap() )
+            {
+                const SwFmtFrmSize &rSz = GetFmt()->GetFrmSize();
+                if ( rSz.GetHeight() != Frm().Height() ||
+                     rSz.GetWidth()  != Frm().Width() )
+                {
+                    SwFmtURL aURL( GetFmt()->GetURL() );
+                    Fraction aScaleX( Frm().Width(),  rSz.GetWidth() );
+                    Fraction aScaleY( Frm().Height(), rSz.GetHeight() );
+                    aURL.GetMap()->Scale( aScaleX, aScaleY );
+                    SwFrmFmt *pFmt = GetFmt();
+                    pFmt->LockModify();
+                    pFmt->SetAttr( aURL );
+                    pFmt->UnlockModify();
+                }
+            }
+            /* Keine Invalidierung notwendig */
+            break;
+
+        case RES_CHAIN:
+            {
+                SwFmtChain *pChain = (SwFmtChain*)pNew;
+                if ( pChain->GetNext() )
+                {
+                    SwFlyFrm *pFollow = FindChainNeighbour( *pChain->GetNext() );
+                    if ( GetNextLink() && pFollow != GetNextLink() )
+                        SwFlyFrm::UnchainFrames( this, GetNextLink());
+                    if ( pFollow )
+                    {
+                        if ( pFollow->GetPrevLink() &&
+                             pFollow->GetPrevLink() != this )
+                            SwFlyFrm::UnchainFrames( pFollow->GetPrevLink(),
+                                                     pFollow );
+                        if ( !GetNextLink() )
+                            SwFlyFrm::ChainFrames( this, pFollow );
+                    }
+                }
+                else if ( GetNextLink() )
+                    SwFlyFrm::UnchainFrames( this, GetNextLink() );
+                if ( pChain->GetPrev() )
+                {
+                    SwFlyFrm *pMaster = FindChainNeighbour( *pChain->GetPrev() );
+                    if ( GetPrevLink() && pMaster != GetPrevLink() )
+                        SwFlyFrm::UnchainFrames( GetPrevLink(), this );
+                    if ( pMaster )
+                    {
+                        if ( pMaster->GetNextLink() &&
+                             pMaster->GetNextLink() != this )
+                            SwFlyFrm::UnchainFrames( pMaster,
+                                                     pMaster->GetNextLink() );
+                        if ( !GetPrevLink() )
+                            SwFlyFrm::ChainFrames( pMaster, this );
+                    }
+                }
+                else if ( GetPrevLink() )
+                    SwFlyFrm::UnchainFrames( GetPrevLink(), this );
+            }
+
+        default:
+            bClear = FALSE;
+    }
+    if ( bClear )
+    {
+        if ( pOldSet || pNewSet )
+        {
+            if ( pOldSet )
+                pOldSet->ClearItem( nWhich );
+            if ( pNewSet )
+                pNewSet->ClearItem( nWhich );
+        }
+        else
+            SwLayoutFrm::Modify( pOld, pNew );
+    }
+}
+
+/*************************************************************************
+|*
+|*                SwFlyFrm::GetInfo()
+|*
+|*    Beschreibung      erfragt Informationen
+|*    Ersterstellung    JP 31.03.94
+|*    Letzte Aenderung  JP 31.03.94
+|*
+*************************************************************************/
+
+    // erfrage vom Modify Informationen
+BOOL SwFlyFrm::GetInfo( SfxPoolItem & rInfo ) const
+{
+    if( RES_AUTOFMT_DOCNODE == rInfo.Which() )
+        return FALSE;   // es gibt einen FlyFrm also wird er benutzt
+    return TRUE;        // weiter suchen
+}
+
+/*************************************************************************
+|*
+|*  SwFlyFrm::_Invalidate()
+|*
+|*  Ersterstellung      MA 15. Oct. 92
+|*  Letzte Aenderung    MA 26. Jun. 96
+|*
+|*************************************************************************/
+
+void SwFlyFrm::_Invalidate( SwPageFrm *pPage )
+{
+    InvalidatePage( pPage );
+    bNotifyBack = bInvalid = TRUE;
+
+    SwFlyFrm *pFrm;
+    if ( GetAnchor() && 0 != (pFrm = GetAnchor()->FindFlyFrm()) )
+    {
+        //Gaanz dumm: Wenn der Fly innerhalb eines Fly gebunden ist, der
+        //Spalten enthaehlt, sollte das Format von diesem ausgehen.
+        if ( !pFrm->IsLocked() && !pFrm->IsColLocked() &&
+             pFrm->Lower() && pFrm->Lower()->IsColumnFrm() )
+            pFrm->InvalidateSize();
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFlyFrm::ChgRelPos()
+|*
+|*  Beschreibung        Aenderung der relativen Position, die Position wird
+|*      damit automatisch Fix, das Attribut wird entprechend angepasst.
+|*  Ersterstellung      MA 25. Aug. 92
+|*  Letzte Aenderung    MA 09. Aug. 95
+|*
+|*************************************************************************/
+
+void SwFlyFrm::ChgRelPos( const Point &rNewPos )
+{
+    if ( GetCurRelPos() != rNewPos )
+    {
+        SwFrmFmt *pFmt = GetFmt();
+        SwTwips nTmpY = rNewPos.Y() == LONG_MAX ? 0 : rNewPos.Y();
+        SfxItemSet aSet( pFmt->GetDoc()->GetAttrPool(),
+                         RES_VERT_ORIENT, RES_HORI_ORIENT);
+
+        SwFmtVertOrient aVert( pFmt->GetVertOrient() );
+        SwTxtFrm *pAutoFrm = NULL;
+        if( IsFlyAtCntFrm() || VERT_NONE != aVert.GetVertOrient() )
+        {
+            if( REL_CHAR == aVert.GetRelationOrient() && IsAutoPos() )
+            {
+                if( LONG_MAX != rNewPos.Y() )
+                {
+                    aVert.SetVertOrient( VERT_NONE );
+                    xub_StrLen nOfs =
+                        pFmt->GetAnchor().GetCntntAnchor()->nContent.GetIndex();
+                    ASSERT( GetAnchor()->IsTxtFrm(), "TxtFrm expected" );
+                    pAutoFrm = (SwTxtFrm*)GetAnchor();
+                    while( pAutoFrm->GetFollow() &&
+                           pAutoFrm->GetFollow()->GetOfst() <= nOfs )
+                    {
+                        if( pAutoFrm == GetAnchor() )
+                            nTmpY += pAutoFrm->GetRelPos().Y();
+                        nTmpY -= pAutoFrm->GetUpper()->Prt().Height();
+                        pAutoFrm = pAutoFrm->GetFollow();
+                    }
+                    nTmpY = ((SwFlyAtCntFrm*)this)->GetRelCharY(pAutoFrm)-nTmpY;
+                }
+                else
+                    aVert.SetVertOrient( VERT_CHAR_BOTTOM );
+            }
+            else
+            {
+                aVert.SetVertOrient( VERT_NONE );
+                aVert.SetRelationOrient( FRAME );
+            }
+        }
+        aVert.SetPos( nTmpY );
+        aSet.Put( aVert );
+
+        //Fuer Flys im Cnt ist die horizontale Ausrichtung uninterressant,
+        //den sie ist stets 0.
+        if ( !IsFlyInCntFrm() )
+        {
+            SwTwips nTmpX = rNewPos.X() == LONG_MAX ? 0 : rNewPos.X();
+            SwFmtHoriOrient aHori( pFmt->GetHoriOrient() );
+            if( IsFlyAtCntFrm() || HORI_NONE != aHori.GetHoriOrient() )
+            {
+                aHori.SetHoriOrient( HORI_NONE );
+                if( REL_CHAR == aHori.GetRelationOrient() && IsAutoPos() )
+                {
+                    if( LONG_MAX != rNewPos.X() )
+                    {
+                        if( !pAutoFrm )
+                        {
+                            xub_StrLen nOfs = pFmt->GetAnchor().GetCntntAnchor()
+                                          ->nContent.GetIndex();
+                            ASSERT( GetAnchor()->IsTxtFrm(), "TxtFrm expected");
+                            pAutoFrm = (SwTxtFrm*)GetAnchor();
+                            while( pAutoFrm->GetFollow() &&
+                                   pAutoFrm->GetFollow()->GetOfst() <= nOfs )
+                                pAutoFrm = pAutoFrm->GetFollow();
+                        }
+                        nTmpX -= ((SwFlyAtCntFrm*)this)->GetRelCharX(pAutoFrm);
+                    }
+                }
+                else
+                    aHori.SetRelationOrient( FRAME );
+                aHori.SetPosToggle( FALSE );
+            }
+            aHori.SetPos( nTmpX );
+            aSet.Put( aHori );
+        }
+        pFmt->GetDoc()->SetAttr( aSet, *pFmt );
+    }
+}
+/*************************************************************************
+|*
+|*  SwFlyFrm::Format()
+|*
+|*  Beschreibung:       "Formatiert" den Frame; Frm und PrtArea.
+|*                      Die Fixsize wird hier nicht eingestellt.
+|*  Ersterstellung      MA 14. Jun. 93
+|*  Letzte Aenderung    MA 13. Jun. 96
+|*
+|*************************************************************************/
+
+void SwFlyFrm::Format( const SwBorderAttrs *pAttrs )
+{
+    ASSERT( pAttrs, "FlyFrm::Format, pAttrs ist 0." );
+
+    ColLock();
+
+    if ( !bValidSize )
+    {
+        if ( Frm().Top() == WEIT_WECH && Frm().Left() == WEIT_WECH )
+            //Sicherheitsschaltung wegnehmen (siehe SwFrm::CTor)
+            Frm().Pos().X() = Frm().Pos().Y() = 0;
+
+        //Breite der Spalten pruefen und ggf. einstellen.
+        if ( Lower() && Lower()->IsColumnFrm() )
+            AdjustColumns( 0, FALSE );
+
+        bValidSize = TRUE;
+
+        const SwTwips nUL  = pAttrs->CalcTopLine() + pAttrs->CalcBottomLine();
+        const SwTwips nLR  = pAttrs->CalcLeftLine()+ pAttrs->CalcRightLine();
+        const Size    &rSz = pAttrs->GetSize();
+        const SwFmtFrmSize &rFrmSz = GetFmt()->GetFrmSize();
+
+        ASSERT( rSz.Height() != 0 || rFrmSz.GetHeightPercent(), "Hoehe des RahmenAttr ist 0." );
+        ASSERT( rSz.Width()  != 0 || rFrmSz.GetWidthPercent(), "Breite des RahmenAttr ist 0." );
+
+        if ( !HasFixSize( pHeight ) )
+        {
+            //Die Groesse in der VarSize wird durch den Inhalt plus den
+            //Raendern bestimmt.
+            SwTwips nRemaining = 0;
+            const long nMinHeight = IsMinHeight() ?
+                CalcRel( rFrmSz ).Height() : 0;
+            if ( Lower() )
+            {
+                if ( Lower()->IsColumnFrm() )
+                {
+                    FormatWidthCols( *pAttrs, nUL, nMinHeight );
+                    nRemaining = Lower()->Frm().Height();
+                }
+                else
+                {
+                    SwFrm *pFrm = Lower();
+                    while ( pFrm )
+                    {   nRemaining += pFrm->Frm().Height();
+                        if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() )
+                            // Dieser TxtFrm waere gern ein bisschen groesser
+                            nRemaining += ((SwTxtFrm*)pFrm)->GetParHeight()
+                                    - pFrm->Prt().Height();
+                        else if( pFrm->IsSctFrm() && ((SwSectionFrm*)pFrm)->IsUndersized() )
+                            nRemaining += ((SwSectionFrm*)pFrm)->Undersize();
+                        pFrm = pFrm->GetNext();
+                    }
+                }
+            }
+            //Die Minimalgroesse darf falls erwuenscht nicht unterschritten
+            //werden.
+#ifndef PRODUCT
+            if ( IsMinHeight() )
+            {
+                const long nMinHeightII = CalcRel( rFrmSz ).Height();
+                ASSERT( nMinHeight==nMinHeightII, "FlyFrm::Format: Changed MinHeight" );
+            }
+#endif
+            if( IsMinHeight() && (nRemaining + nUL) < nMinHeight )
+                nRemaining = nMinHeight - nUL;
+            //Weil das Grow/Shrink der Flys die Groessen nicht direkt
+            //einstellt, sondern indirekt per Invalidate ein Format
+            //ausloesst, muessen die Groessen hier direkt eingestellt
+            //werden. Benachrichtung laeuft bereits mit.
+            //Weil bereits haeufiger 0en per Attribut hereinkamen wehre
+            //ich mich ab sofort dagegen.
+            if ( nRemaining < MINFLY )
+                nRemaining = MINFLY;
+            Prt().Height( nRemaining );
+            Frm().Height( nRemaining + nUL );
+            bValidSize = TRUE;
+        }
+        else
+        {
+            bValidSize = TRUE;  //Fixe Frms formatieren sich nicht.
+                                //Flys stellen ihre Groesse anhand des Attr ein.
+            const SwTwips nMin = MINFLY + nUL;
+            Frm().Height( Max( CalcRel( rFrmSz ).Height(), nMin ) );
+            Prt().Height( Frm().Height() - nUL );
+        }
+        if ( !bFormatHeightOnly )
+        {
+            const SwTwips nMin = MINFLY + nLR;
+            Frm().Width( Max( CalcRel( rFrmSz ).Width(), nMin ) );
+            Prt().Width( Frm().Width() - (nLR) );
+        }
+    }
+    ColUnlock();
+}
+
+void CalcCntnt( SwLayoutFrm *pLay, BOOL bNoColl )
+{
+    SwSectionFrm* pSect;
+    BOOL bCollect = FALSE;
+    if( pLay->IsSctFrm() )
+    {
+        pSect = (SwSectionFrm*)pLay;
+        if( pSect->IsEndnAtEnd() && !bNoColl )
+        {
+            bCollect = TRUE;
+            SwLayouter::CollectEndnotes( pLay->GetFmt()->GetDoc(), pSect );
+        }
+        pSect->CalcFtnCntnt();
+    }
+    else
+        pSect = NULL;
+    SwFrm *pFrm = pLay->ContainsAny();
+    if ( !pFrm )
+    {
+        if( pSect )
+        {
+            if( pSect->HasFollow() )
+                pFrm = pSect->GetFollow()->ContainsAny();
+            if( !pFrm )
+            {
+                if( pSect->IsEndnAtEnd() )
+                {
+                    if( bCollect )
+                        pLay->GetFmt()->GetDoc()->GetLayouter()->
+                            InsertEndnotes( pSect );
+                    BOOL bLock = pSect->IsFtnLock();
+                    pSect->SetFtnLock( TRUE );
+                    pSect->CalcFtnCntnt();
+                    pSect->CalcFtnCntnt();
+                    pSect->SetFtnLock( bLock );
+                }
+                return;
+            }
+            pFrm->_InvalidatePos();
+        }
+        else
+            return;
+    }
+    pFrm->InvalidatePage();
+
+    do
+    {
+        SwFlyFrm *pAgainFly1 = 0,       //Oszillation abknipsen.
+                 *pAgainFly2 = 0;
+        SwFrm* pLast;
+        do
+        {
+            pLast = pFrm;
+            if ( pFrm->GetUpper()->Prt().Width() != pFrm->Frm().Width() )
+            {
+                pFrm->Prepare( PREP_FIXSIZE_CHG );
+                pFrm->_InvalidateSize();
+            }
+
+            if ( pFrm->IsTabFrm() )
+            {
+                ((SwTabFrm*)pFrm)->bCalcLowers = TRUE;
+                if ( ((SwTabFrm*)pFrm)->IsFollow() )
+                    ((SwTabFrm*)pFrm)->bLockBackMove = TRUE;
+            }
+
+            pFrm->Calc();
+
+            //Dumm aber wahr, die Flys muessen mitkalkuliert werden.
+            BOOL bAgain = FALSE;
+            if ( pFrm->GetDrawObjs() )
+            {
+                USHORT nCnt = pFrm->GetDrawObjs()->Count();
+                for ( USHORT i = 0; i < nCnt; ++i )
+                {
+                    SdrObject *pO = (*pFrm->GetDrawObjs())[i];
+                    if ( pO->IsWriterFlyFrame() )
+                    {
+                        SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+                        pFly->InvalidatePos();
+                        SwRect aRect( pFly->Frm() );
+                        pFly->Calc();
+                        if ( aRect != pFly->Frm() )
+                        {
+                            bAgain = TRUE;
+                            if ( pAgainFly2 == pFly )
+                            {
+                                //Oszillation unterbinden.
+                                SwFrmFmt *pFmt = pFly->GetFmt();
+                                SwFmtSurround aAttr( pFmt->GetSurround() );
+                                if( SURROUND_THROUGHT != aAttr.GetSurround() )
+                                {
+                                    // Bei autopositionierten hilft manchmal nur
+                                    // noch, auf Durchlauf zu schalten
+                                    if( pFly->IsAutoPos() &&
+                                        SURROUND_PARALLEL == aAttr.GetSurround() )
+                                        aAttr.SetSurround( SURROUND_THROUGHT );
+                                    else
+                                        aAttr.SetSurround( SURROUND_PARALLEL );
+                                    pFmt->LockModify();
+                                    pFmt->SetAttr( aAttr );
+                                    pFmt->UnlockModify();
+                                }
+                            }
+                            else
+                            {
+                                if ( pAgainFly1 == pFly )
+                                    pAgainFly2 = pFly;
+                                pAgainFly1 = pFly;
+                            }
+                        }
+                        if ( !pFrm->GetDrawObjs() )
+                            break;
+                        if ( pFrm->GetDrawObjs()->Count() < nCnt )
+                        {
+                            --i;
+                            --nCnt;
+                        }
+                    }
+                }
+                if ( bAgain )
+                {
+                    pFrm = pLay->ContainsCntnt();
+                    if ( pFrm && pFrm->IsInTab() )
+                        pFrm = pFrm->FindTabFrm();
+                    if( pFrm && pFrm->IsInSct() )
+                    {
+                        SwSectionFrm* pTmp = pFrm->FindSctFrm();
+                        if( pTmp != pLay && pLay->IsAnLower( pTmp ) )
+                            pFrm = pTmp;
+                    }
+                    continue;
+                }
+            }
+            if ( pFrm->IsTabFrm() )
+            {
+                if ( ((SwTabFrm*)pFrm)->IsFollow() )
+                    ((SwTabFrm*)pFrm)->bLockBackMove = FALSE;
+            }
+            pFrm = pFrm->FindNext();
+            if( pFrm && pFrm->IsSctFrm() && pSect )
+            {
+                // Es koennen hier leere SectionFrms herumspuken
+                while( pFrm && pFrm->IsSctFrm() && !((SwSectionFrm*)pFrm)->GetSection() )
+                    pFrm = pFrm->FindNext();
+                // Wenn FindNext den Follow des urspruenglichen Bereichs liefert,
+                // wollen wir mit dessen Inhalt weitermachen, solange dieser
+                // zurueckfliesst.
+                if( pFrm && pFrm->IsSctFrm() && ( pFrm == pSect->GetFollow() ||
+                    ((SwSectionFrm*)pFrm)->IsAnFollow( pSect ) ) )
+                {
+                    pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
+                    if( pFrm )
+                        pFrm->_InvalidatePos();
+                }
+            }
+            // Im pLay bleiben, Ausnahme, bei SectionFrms mit Follow wird der erste
+            // CntntFrm des Follows anformatiert, damit er die Chance erhaelt, in
+            // pLay zu landen. Solange diese Frames in pLay landen, geht's weiter.
+        } while ( pFrm && ( pLay->IsAnLower( pFrm ) ||
+                ( pSect && ( ( pSect->HasFollow() && pLay->IsAnLower( pLast )
+                  && pSect->GetFollow()->IsAnLower( pFrm ) ) || ( pFrm->IsInSct()
+                  && pFrm->FindSctFrm()->IsAnFollow( pSect ) ) ) ) ) );
+        if( pSect )
+        {
+            if( bCollect )
+            {
+                pLay->GetFmt()->GetDoc()->GetLayouter()->InsertEndnotes(pSect);
+                pSect->CalcFtnCntnt();
+            }
+            if( pSect->HasFollow() )
+            {
+                SwSectionFrm* pNxt = pSect->GetFollow();
+                while( pNxt && !pNxt->ContainsCntnt() )
+                    pNxt = pNxt->GetFollow();
+                if( pNxt )
+                    pNxt->CalcFtnCntnt();
+            }
+            if( bCollect )
+            {
+                pFrm = pLay->ContainsAny();
+                bCollect = FALSE;
+                if( pFrm )
+                    continue;
+            }
+        }
+        break;
+    }
+    while( TRUE );
+}
+
+/*************************************************************************
+|*
+|*  SwFlyFrm::MakeFlyPos()
+|*
+|*  Ersterstellung      MA ??
+|*  Letzte Aenderung    MA 14. Nov. 96
+|*
+|*************************************************************************/
+
+void SwFlyFrm::MakeFlyPos()
+{
+    if ( !bValidPos )
+    {   bValidPos = TRUE;
+        GetAnchor()->Calc();
+
+            //Die Werte in den Attributen muessen ggf. upgedated werden,
+            //deshalb werden hier Attributinstanzen und Flags benoetigt.
+        SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)GetFmt();
+        BOOL bFlyAtFly = FLY_AT_FLY == pFmt->GetAnchor().GetAnchorId();
+        SwFmtVertOrient aVert( pFmt->GetVertOrient() );
+        SwFmtHoriOrient aHori( pFmt->GetHoriOrient() );
+        const SvxLRSpaceItem &rLR = pFmt->GetLRSpace();
+        const SvxULSpaceItem &rUL = pFmt->GetULSpace();
+        FASTBOOL bVertChgd = FALSE,
+                 bHoriChgd = FALSE;
+
+        //Horizontale und vertikale Positionen werden getrennt berechnet.
+        //Sie koennen jeweils Fix oder Variabel (automatisch) sein.
+
+        //Erst die vertikale Position
+        BOOL bVertPrt = aVert.GetRelationOrient() == PRTAREA ||
+                        aVert.GetRelationOrient() == REL_PG_PRTAREA;
+        if ( aVert.GetVertOrient() == VERT_NONE )
+        {
+            SwTwips nYPos = aVert.GetPos();
+            if ( bVertPrt )
+            {
+                nYPos += GetAnchor()->Prt().Top();
+                if( GetAnchor()->IsPageFrm() )
+                {
+                    SwFrm* pPrtFrm = ((SwPageFrm*)GetAnchor())->Lower();
+                    if( pPrtFrm && pPrtFrm->IsHeaderFrm() )
+                        nYPos += pPrtFrm->Frm().Height();
+                }
+            }
+            if( nYPos < 0 )
+#ifdef AMA_OUT_OF_FLY
+              if( !bFlyAtFly  )
+#endif
+                nYPos = 0;
+            aRelPos.Y() = nYPos;
+        }
+        else
+        {   //Zuerst den Bezugsrahmen festlegen (PrtArea oder Frame)
+            SwTwips nRel, nAdd;
+            if ( bVertPrt )
+            {   nRel = GetAnchor()->Prt().Height();
+                nAdd = GetAnchor()->Prt().Top();
+                if( GetAnchor()->IsPageFrm() )
+                {
+                    // Wenn wir am SeitenTextBereich ausgerichtet sind,
+                    // sollen Kopf- und Fusszeilen _nicht_ mit zaehlen.
+                    SwFrm* pPrtFrm = ((SwPageFrm*)GetAnchor())->Lower();
+                    while( pPrtFrm )
+                    {
+                        if( pPrtFrm->IsHeaderFrm() )
+                        {
+                            nRel -= pPrtFrm->Frm().Height();
+                            nAdd += pPrtFrm->Frm().Height();
+                        }
+                        else if( pPrtFrm->IsFooterFrm() )
+                            nRel -= pPrtFrm->Frm().Height();
+                        pPrtFrm = pPrtFrm->GetNext();
+                    }
+                }
+            }
+            else
+            {   nRel = GetAnchor()->Frm().Height();
+                nAdd = 0;
+            }
+            // Bei rahmengebunden Rahmen wird nur vertikal unten oder zentriert
+            // ausgerichtet, wenn der Text durchlaeuft oder der Anker eine feste
+            // Hoehe besitzt.
+            if( bFlyAtFly && VERT_TOP != aVert.GetVertOrient() &&
+                SURROUND_THROUGHT != pFmt->GetSurround().GetSurround() &&
+                !GetAnchor()->HasFixSize( pHeight ) )
+                aRelPos.Y() = rUL.GetUpper();
+            else if ( aVert.GetVertOrient() == VERT_CENTER )
+                aRelPos.Y() = (nRel / 2) - (aFrm.Height() / 2);
+            else if ( aVert.GetVertOrient() == VERT_BOTTOM )
+                aRelPos.Y() = nRel - (aFrm.Height() + rUL.GetLower());
+            else
+                aRelPos.Y() = rUL.GetUpper();
+            aRelPos.Y() += nAdd;
+
+            if ( aVert.GetPos() != aRelPos.Y() )
+            {   aVert.SetPos( aRelPos.Y() );
+                bVertChgd = TRUE;
+            }
+        }
+
+        //Fuer die Hoehe der Seiten im Browser muessen wir etwas tricksen. Das
+        //Grow muessen wir auf den Body rufen; wegen ggf. eingeschalteter
+        //Kopfzeilen und weil die Seite sowieso eine fix-Hoehe hat.
+        if ( !bFlyAtFly && GetFmt()->GetDoc()->IsBrowseMode() &&
+             GetAnchor()->IsPageFrm() ) //Was sonst?
+        {
+            const long nAnchorBottom = GetAnchor()->Frm().Bottom();
+            const long nBottom = GetAnchor()->Frm().Top() + aRelPos.Y() + Frm().Height();
+            if ( nAnchorBottom < nBottom )
+            {
+                ((SwPageFrm*)GetAnchor())->FindBodyCont()->
+                                    Grow( nBottom - nAnchorBottom, pHeight );
+            }
+        }
+
+
+        //Jetzt die Horizontale Position
+        const BOOL bToggle = aHori.IsPosToggle() &&
+                       !(FindPageFrm()->GetVirtPageNum() % 2);
+        BOOL bTmpToggle = bToggle;
+        //und wieder erst der Bezugsrahmen
+        SwTwips nRel, nAdd;
+        SwHoriOrient eHOri = aHori.GetHoriOrient();
+        if( bToggle )
+        {
+            if( HORI_RIGHT == eHOri )
+                eHOri = HORI_LEFT;
+            else if( HORI_LEFT == eHOri )
+                eHOri = HORI_RIGHT;
+        }
+        switch ( aHori.GetRelationOrient() )
+        {
+            case PRTAREA:
+            case REL_PG_PRTAREA:
+            {
+                nRel = GetAnchor()->Prt().Width();
+                nAdd = GetAnchor()->Prt().Left();
+                break;
+            }
+            case REL_PG_LEFT:
+            case REL_FRM_LEFT:
+                bTmpToggle = !bToggle;
+                // kein break;
+            case REL_PG_RIGHT:
+            case REL_FRM_RIGHT:
+            {
+                if ( bTmpToggle )    // linker Seitenrand
+                {
+                    nRel = GetAnchor()->Prt().Left();
+                    nAdd = 0;
+                }
+                else            // rechter Seitenrand
+                {
+                    nRel = GetAnchor()->Frm().Width();
+                    nAdd = GetAnchor()->Prt().Right();
+                    nRel -= nAdd;
+                }
+                break;
+            }
+            default:
+            {
+                nRel = GetAnchor()->Frm().Width();
+                nAdd = 0;
+                break;
+            }
+        }
+        if ( aHori.GetHoriOrient() == HORI_NONE )
+        {
+            if( bToggle )
+                aRelPos.X() = nRel - aFrm.Width() - aHori.GetPos();
+            else
+                aRelPos.X() = aHori.GetPos();
+        }
+        else if ( HORI_CENTER == eHOri )
+            aRelPos.X() = (nRel / 2) - (aFrm.Width() / 2);
+        else if ( HORI_RIGHT == eHOri )
+            aRelPos.X() = nRel - (aFrm.Width() + rLR.GetRight());
+        else
+            aRelPos.X() = rLR.GetLeft();
+        aRelPos.X() += nAdd;
+
+        if( aRelPos.X() < 0 )
+            aRelPos.X() = 0;
+        if ( HORI_NONE != aHori.GetHoriOrient() &&
+            aHori.GetPos() != aRelPos.X() )
+        {   aHori.SetPos( aRelPos.X() );
+            bHoriChgd = TRUE;
+        }
+        //Die Absolute Position ergibt sich aus der absoluten Position des
+        //Ankers plus der relativen Position.
+        aFrm.Pos( aRelPos );
+        aFrm.Pos() += GetAnchor()->Frm().Pos();
+
+        //Und ggf. noch die aktuellen Werte im Format updaten, dabei darf
+        //zu diesem Zeitpunkt natuerlich kein Modify verschickt werden.
+        pFmt->LockModify();
+        if ( bVertChgd )
+            pFmt->SetAttr( aVert );
+        if ( bHoriChgd )
+            pFmt->SetAttr( aHori );
+        pFmt->UnlockModify();
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFlyFrm::MakePrtArea()
+|*
+|*  Ersterstellung      MA 23. Jun. 93
+|*  Letzte Aenderung    MA 23. Jun. 93
+|*
+|*************************************************************************/
+
+void SwFlyFrm::MakePrtArea( const SwBorderAttrs &rAttrs )
+{
+
+    if ( !bValidPrtArea )
+    {
+        bValidPrtArea = TRUE;
+
+        //Position einstellen.
+        aPrt.Left( rAttrs.CalcLeftLine() );
+        aPrt.Top ( rAttrs.CalcTopLine()  );
+
+        //Sizes einstellen; die Groesse gibt der umgebende Frm vor, die
+        //die Raender werden einfach abgezogen.
+        aPrt.Width ( aFrm.Width() - (rAttrs.CalcRightLine() + aPrt.Left()) );
+        aPrt.Height( aFrm.Height()- (aPrt.Top() + rAttrs.CalcBottomLine()));
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFlyFrm::_Grow(), _Shrink()
+|*
+|*  Ersterstellung      MA 05. Oct. 92
+|*  Letzte Aenderung    MA 05. Sep. 96
+|*
+|*************************************************************************/
+
+SwTwips SwFlyFrm::_Grow( SwTwips nDist, const SzPtr pDirection, BOOL bTst )
+{
+    if ( Lower() && !IsColLocked() && !HasFixSize( pDirection ) )
+    {
+        if ( Frm().SSize().*pDirection > 0 &&
+             nDist > (LONG_MAX - Frm().SSize().*pDirection) )
+            nDist = LONG_MAX - Frm().SSize().*pDirection;
+
+        if ( nDist <= 0L )
+            return 0L;
+
+        if ( Lower()->IsColumnFrm() )
+        {   //Bei Spaltigkeit ubernimmt das Format die Kontrolle ueber
+            //das Wachstum (wg. des Ausgleichs).
+            if ( !bTst )
+            {   _InvalidatePos();
+                InvalidateSize();
+            }
+            return 0L;
+        }
+
+        if ( !bTst )
+        {
+            const SwRect aOld( AddSpacesToFrm() );
+            _InvalidateSize();
+            const BOOL bOldLock = bLocked;
+            Unlock();
+            if ( IsFlyFreeFrm() )
+                ((SwFlyFreeFrm*)this)->SwFlyFreeFrm::MakeAll();
+            else
+                MakeAll();
+            _InvalidateSize();
+            InvalidatePos();
+            if ( bOldLock )
+                Lock();
+            const SwRect aNew( AddSpacesToFrm() );
+            if ( aOld != aNew )
+                ::Notify( this, FindPageFrm(), aOld );
+            return aNew.SSize().*pDirection - aOld.SSize().*pDirection;
+        }
+        return nDist;
+    }
+    return 0L;
+}
+
+SwTwips SwFlyFrm::_Shrink( SwTwips nDist, const SzPtr pDirection, BOOL bTst )
+{
+    if ( Lower() && !IsColLocked() && !HasFixSize( pDirection ) )
+    {
+        if ( nDist > Frm().SSize().*pDirection )
+            nDist = Frm().SSize().*pDirection;
+
+        SwTwips nVal = IsMinHeight() && pDirection == pHeight ?
+            Min( nDist, Frm().Height() - GetFmt()->GetFrmSize().GetHeight() ) :
+            nDist;
+        if ( nVal <= 0L )
+            return 0L;
+
+        if ( Lower()->IsColumnFrm() )
+        {   //Bei Spaltigkeit ubernimmt das Format die Kontrolle ueber
+            //das Wachstum (wg. des Ausgleichs).
+            if ( !bTst )
+            {
+                SwRect aOld( AddSpacesToFrm() );
+                Frm().SSize().*pDirection -= nVal;
+                Prt().SSize().*pDirection -= nVal;
+                _InvalidatePos();
+                InvalidateSize();
+                ::Notify( this, FindPageFrm(), aOld );
+                NotifyDrawObj();
+                if ( GetAnchor()->IsInFly() )
+                    GetAnchor()->FindFlyFrm()->Shrink( nDist, pDirection, bTst );
+            }
+            return 0L;
+        }
+
+        if ( !bTst )
+        {
+            const SwRect aOld( AddSpacesToFrm() );
+            _InvalidateSize();
+            const BOOL bOldLocked = bLocked;
+            Unlock();
+            if ( IsFlyFreeFrm() )
+                ((SwFlyFreeFrm*)this)->SwFlyFreeFrm::MakeAll();
+            else
+                MakeAll();
+            _InvalidateSize();
+            InvalidatePos();
+            if ( bOldLocked )
+                Lock();
+            const SwRect aNew( AddSpacesToFrm() );
+            if ( aOld != aNew )
+            {
+                ::Notify( this, FindPageFrm(), aOld );
+                if ( GetAnchor()->IsInFly() )
+                    GetAnchor()->FindFlyFrm()->Shrink( nDist, pDirection, bTst );
+            }
+            return aOld.SSize().*pDirection - aNew.SSize().*pDirection;
+        }
+        return nVal;
+    }
+    return 0L;
+}
+
+/*************************************************************************
+|*
+|*  SwFlyFrm::ChgSize()
+|*
+|*  Ersterstellung      MA 05. Oct. 92
+|*  Letzte Aenderung    MA 04. Sep. 96
+|*
+|*************************************************************************/
+
+void SwFlyFrm::ChgSize( const Size& aNewSize )
+{
+    if ( aNewSize != Frm().SSize() )
+    {
+        SwFrmFmt *pFmt = GetFmt();
+        SwFmtFrmSize aSz( pFmt->GetFrmSize() );
+        aSz.SetWidth( aNewSize.Width() );
+        if ( Abs(aNewSize.Height() - Frm().Height()) > 1 )
+            aSz.SetHeight( aNewSize.Height() );
+        // uebers Doc fuers Undo!
+        pFmt->GetDoc()->SetAttr( aSz, *pFmt );
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFlyFrm::IsLowerOf()
+|*
+|*  Ersterstellung      MA 27. Dec. 93
+|*  Letzte Aenderung    MA 27. Dec. 93
+|*
+|*************************************************************************/
+
+BOOL SwFlyFrm::IsLowerOf( const SwLayoutFrm *pUpper ) const
+{
+    ASSERT( GetAnchor(), "8-( Fly is lost in Space." );
+    const SwFrm *pFrm = GetAnchor();
+    do
+    {   if ( pFrm == pUpper )
+            return TRUE;
+        pFrm = pFrm->IsFlyFrm() ? ((const SwFlyFrm*)pFrm)->GetAnchor() :
+                                  pFrm->GetUpper();
+    } while ( pFrm );
+    return FALSE;
+}
+
+/*************************************************************************
+|*
+|*  SwFlyFrm::Cut()
+|*
+|*  Ersterstellung      MA 23. Feb. 94
+|*  Letzte Aenderung    MA 23. Feb. 94
+|*
+|*************************************************************************/
+
+void SwFlyFrm::Cut()
+{
+}
+
+/*************************************************************************
+|*
+|*  SwFrm::AppendFly(), RemoveFly()
+|*
+|*  Ersterstellung      MA 25. Aug. 92
+|*  Letzte Aenderung    MA 09. Jun. 95
+|*
+|*************************************************************************/
+
+void SwFrm::AppendFly( SwFlyFrm *pNew )
+{
+    if ( !pDrawObjs )
+        pDrawObjs = new SwDrawObjs();
+    SdrObject *pObj = pNew->GetVirtDrawObj();
+    pDrawObjs->Insert( pObj, pDrawObjs->Count() );
+    pNew->ChgAnchor( this );
+
+    //Bei der Seite anmelden; kann sein, dass noch keine da ist - die
+    //Anmeldung wird dann in SwPageFrm::PreparePage durch gefuehrt.
+    SwPageFrm *pPage = FindPageFrm();
+    if ( pPage )
+    {
+        if ( pNew->IsFlyAtCntFrm() && pNew->Frm().Top() == WEIT_WECH )
+        {
+            //Versuch die Seitenformatierung von neuen Dokumenten etwas
+            //guenstiger zu gestalten.
+            //Wir haengen die Flys erstenmal nach hinten damit sie bei heftigem
+            //Fluss der Anker nicht unoetig oft formatiert werden.
+            //Damit man noch brauchbar an das Ende des Dokumentes springen
+            //kann werden die Flys nicht ganz an das Ende gehaengt.
+            SwRootFrm *pRoot = (SwRootFrm*)pPage->GetUpper();
+            SwPageFrm *pTmp = pRoot->GetLastPage();
+            if ( pTmp->GetPhyPageNum() > 30 )
+            {
+                for ( USHORT i = 0; i < 10; ++i )
+                {
+                    pTmp = (SwPageFrm*)pTmp->GetPrev();
+                    if( pTmp->GetPhyPageNum() <= pPage->GetPhyPageNum() )
+                        break; // damit wir nicht vor unserem Anker landen
+                }
+                if ( pTmp->IsEmptyPage() )
+                    pTmp = (SwPageFrm*)pTmp->GetPrev();
+                pPage = pTmp;
+            }
+            pPage->SwPageFrm::AppendFly( pNew );
+        }
+        else
+            pPage->SwPageFrm::AppendFly( pNew );
+    }
+}
+
+void SwFrm::RemoveFly( SwFlyFrm *pToRemove )
+{
+    //Bei der Seite Abmelden - kann schon passiert sein weil die Seite
+    //bereits destruiert wurde.
+    SwPageFrm *pPage = pToRemove->FindPageFrm();
+    if ( pPage && pPage->GetSortedObjs() )
+        pPage->SwPageFrm::RemoveFly( pToRemove );
+
+    const SdrObjectPtr pObj = pToRemove->GetVirtDrawObj();
+    pDrawObjs->Remove( pDrawObjs->GetPos( pObj ) );
+    if ( !pDrawObjs->Count() )
+        DELETEZ( pDrawObjs );
+
+    pToRemove->ChgAnchor( 0 );
+
+    if ( !pToRemove->IsFlyInCntFrm() && GetUpper() && IsInTab() )//MA_FLY_HEIGHT
+        GetUpper()->InvalidateSize();
+}
+
+/*************************************************************************
+|*
+|*  SwFrm::AppendDrawObj(), RemoveDrawObj()
+|*
+|*  Ersterstellung      MA 09. Jan. 95
+|*  Letzte Aenderung    MA 26. Jun. 95
+|*
+|*************************************************************************/
+
+void SwFrm::AppendDrawObj( SwDrawContact *pNew )
+{
+    if ( pNew->GetAnchor() && pNew->GetAnchor() != this )
+        pNew->DisconnectFromLayout( FALSE );
+
+    SdrObject *pObj = pNew->GetMaster();
+    if ( pNew->GetAnchor() != this )
+    {
+        if ( !pDrawObjs )
+            pDrawObjs = new SwDrawObjs();
+        pDrawObjs->Insert( pObj, pDrawObjs->Count() );
+        pNew->ChgAnchor( this );
+    }
+    const SwFmtAnchor &rAnch = pNew->GetFmt()->GetAnchor();
+    if( FLY_AUTO_CNTNT == rAnch.GetAnchorId() )
+    {
+        SwRect aTmpRect;
+        SwPosition *pPos = (SwPosition*)rAnch.GetCntntAnchor();
+        GetCharRect( aTmpRect, *pPos );
+        pNew->GetMaster()->SetAnchorPos( aTmpRect.Pos() );
+    }
+    else if( FLY_IN_CNTNT != rAnch.GetAnchorId() )
+        pNew->GetMaster()->SetAnchorPos( Frm().Pos() );
+    //Bei der Seite anmelden; kann sein, dass noch keine da ist - die
+    //Anmeldung wird dann in SwPageFrm::PreparePage durch gefuehrt.
+    SwPageFrm *pPage = FindPageFrm();
+    if ( pPage )
+        pPage->SwPageFrm::AppendDrawObj( pNew );
+}
+
+void SwFrm::RemoveDrawObj( SwDrawContact *pToRemove )
+{
+    //Bei der Seite Abmelden - kann schon passiert sein weil die Seite
+    //bereits destruiert wurde.
+    SwPageFrm *pPage = pToRemove->GetPage();
+    if ( pPage && pPage->GetSortedObjs() )
+        pPage->SwPageFrm::RemoveDrawObj( pToRemove );
+
+    SdrObject *pObj = pToRemove->GetMaster();
+    pDrawObjs->Remove( pDrawObjs->GetPos( pObj ) );
+    if ( !pDrawObjs->Count() )
+        DELETEZ( pDrawObjs );
+
+    pToRemove->ChgAnchor( 0 );
+}
+
+/*************************************************************************
+|*
+|*  SwFrm::CalcFlys()
+|*
+|*  Ersterstellung      MA 29. Nov. 96
+|*  Letzte Aenderung    MA 29. Nov. 96
+|*
+|*************************************************************************/
+
+void lcl_MakeFlyPosition( SwFlyFrm *pFly )
+{
+    if( pFly->IsFlyFreeFrm() )
+    {
+        ((SwFlyFreeFrm*)pFly)->SwFlyFreeFrm::MakeAll();
+        return;
+    }
+
+    BOOL bOldLock = pFly->IsLocked();
+    pFly->Lock();
+    SwFlyNotify aNotify( pFly );
+    pFly->MakeFlyPos();
+    if( !bOldLock )
+        pFly->Unlock();
+}
+
+void SwFrm::CalcFlys( BOOL bPosOnly )
+{
+    if ( GetDrawObjs() )
+    {
+        USHORT nCnt = GetDrawObjs()->Count();
+        for ( USHORT i = 0; i < nCnt; ++i )
+        {
+            SdrObject *pO = (*GetDrawObjs())[i];
+            if ( pO->IsWriterFlyFrame() )
+            {
+                SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+                // Bei autopositionierten (am Zeichen geb.) Rahmen vertrauen wir
+                // darauf, dass die Positionierung vom SwTxtFrm::Format vorgenommen
+                // wird. Wenn wir sie dagegen hier kalkulieren wuerden, fuehrt es
+                // zur Endlosschleife in Bug 50796.
+                if ( pFly->IsFlyInCntFrm() )
+                    continue;
+                if( pFly->IsAutoPos() )
+                {
+                    if( bPosOnly )
+                    {
+                        pFly->_Invalidate();
+                        pFly->_InvalidatePos();
+                    }
+                    continue;
+                }
+                pFly->_Invalidate();
+                pFly->_InvalidatePos();
+
+                if ( bPosOnly && pFly->GetValidSizeFlag() && pFly->GetValidPrtAreaFlag() )
+                    ::lcl_MakeFlyPosition( pFly );
+                else
+                {
+                    if ( !bPosOnly )
+                        pFly->_InvalidateSize();
+                    pFly->Calc();
+                }
+                if ( !GetDrawObjs() )
+                    break;
+                if ( GetDrawObjs()->Count() < nCnt )
+                {
+                    --i;
+                    --nCnt;
+                }
+            }
+            else
+            {
+                SwFrmFmt *pFrmFmt = ::FindFrmFmt( pO );
+                if( !pFrmFmt ||
+                    FLY_IN_CNTNT != pFrmFmt->GetAnchor().GetAnchorId() )
+                {
+                    pO->SetAnchorPos( Frm().Pos() );
+                    ((SwDrawContact*)GetUserCall(pO))->ChkPage();
+                }
+            }
+        }
+    }
+}
+
+
+/*************************************************************************
+|*
+|*  SwLayoutFrm::NotifyFlys()
+|*
+|*  Ersterstellung      MA 18. Feb. 94
+|*  Letzte Aenderung    MA 26. Jun. 96
+|*
+|*************************************************************************/
+
+void SwLayoutFrm::NotifyFlys()
+{
+    //Sorgt dafuer, dass untergeordnete Flys pruefen, ob sich sich an
+    //die Verhaeltnisse anpassen muessen.
+
+    //Wenn mehr Platz da ist muessen die Positionen und Sizes der
+    //Flys berechnet werden, denn es koennte sein, das sie kuenstlich
+    //geschrumpft/vershoben wurden und jetzt wieder naeher an ihre
+    //Sollwerte gehen duerfen.
+    //Ist weniger Platz da, so reicht es wenn sie in das MakeAll laufen
+    //der preiswerteste Weg dazu ist die Invalidierung der PrtArea.
+
+    SwPageFrm *pPage = FindPageFrm();
+    if ( pPage && pPage->GetSortedObjs() )
+    {
+        //Die Seite nur einmal antriggern.
+        FASTBOOL bPageInva = TRUE;
+
+        SwSortDrawObjs &rObjs = *pPage->GetSortedObjs();
+        const BOOL bHeadFoot = IsHeaderFrm() || IsFooterFrm();
+        for ( USHORT i = 0; i < rObjs.Count(); ++i )
+        {
+            SdrObject *pO = rObjs[i];
+            if ( pO->IsWriterFlyFrame() )
+            {
+                SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+
+                if ( pFly->Frm().Left() == WEIT_WECH )
+                    continue;
+
+                //Wenn der Fly nicht irgendwo ausserhalb liegt braucht er nur
+                //nur benachrichtigt werden, wenn er geclipped ist.
+                // Bei Header/Footer keine Abkuerzung, denn hier muesste die
+                // die PrtArea geprueft werden, die zu diesem Zeitpunkt
+                // (ShrinkFrm) noch nicht angepasst ist.
+                if ( !bHeadFoot && Frm().IsInside( pFly->Frm() ) && !pFly->IsClipped() )
+                    continue;
+
+                const BOOL bLow = pFly->IsLowerOf( this );
+                if ( bLow || pFly->GetAnchor()->FindPageFrm() != pPage )
+                {
+                    pFly->_Invalidate( pPage );
+                    if ( !bLow || pFly->IsFlyAtCntFrm() )
+                        pFly->_InvalidatePos();
+                    else
+                        pFly->_InvalidatePrt();
+                }
+            }
+        }
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFlyFrm::NotifyDrawObj()
+|*
+|*  Ersterstellung      OK 22. Nov. 94
+|*  Letzte Aenderung    MA 10. Jan. 97
+|*
+|*************************************************************************/
+
+void SwFlyFrm::NotifyDrawObj()
+{
+    pDrawObj->SetRect();
+    pDrawObj->_SetRectsDirty();
+    pDrawObj->SetChanged();
+    pDrawObj->SendRepaintBroadcast( TRUE ); //Broadcast ohne Repaint!
+    if ( GetFmt()->GetSurround().IsContour() )
+        ClrContourCache( pDrawObj );
+}
+
+/*************************************************************************
+|*
+|*  SwLayoutFrm::CalcRel()
+|*
+|*  Ersterstellung      MA 13. Jun. 96
+|*  Letzte Aenderung    MA 10. Oct. 96
+|*
+|*************************************************************************/
+
+Size SwFlyFrm::CalcRel( const SwFmtFrmSize &rSz ) const
+{
+    Size aRet( rSz.GetSize() );
+
+    const SwFrm *pRel = IsFlyLayFrm() ? GetAnchor() : GetAnchor()->GetUpper();
+    if( pRel ) // LAYER_IMPL
+    {
+        long nRelWidth = LONG_MAX, nRelHeight = LONG_MAX;
+        const ViewShell *pSh = GetShell();
+        if ( ( pRel->IsBodyFrm() || pRel->IsPageFrm() ) &&
+             GetFmt()->GetDoc()->IsBrowseMode() &&
+             pSh && pSh->VisArea().HasArea() )
+        {
+            nRelWidth  = pSh->VisArea().Width();
+            nRelHeight = pSh->VisArea().Height();
+            const Size aBorder = pSh->GetOut()->PixelToLogic( pSh->GetBrowseBorder() );
+            nRelWidth -= 2*aBorder.Width();
+            long nDiff = nRelWidth - pRel->Prt().Width();
+            if ( nDiff > 0 )
+                nRelWidth -= nDiff;
+            nRelHeight -= 2*aBorder.Height();
+            nDiff = nRelHeight - pRel->Prt().Height();
+            if ( nDiff > 0 )
+                nRelHeight -= nDiff;
+        }
+        nRelWidth  = Min( nRelWidth,  pRel->Prt().Width() );
+        nRelHeight = Min( nRelHeight, pRel->Prt().Height() );
+
+        if ( rSz.GetWidthPercent() && rSz.GetWidthPercent() != 0xFF )
+            aRet.Width() = nRelWidth * rSz.GetWidthPercent() / 100;
+        if ( rSz.GetHeightPercent() && rSz.GetHeightPercent() != 0xFF )
+            aRet.Height() = nRelHeight * rSz.GetHeightPercent() / 100;
+
+        if ( rSz.GetWidthPercent() == 0xFF )
+        {
+            aRet.Width() *= aRet.Height();
+            aRet.Width() /= rSz.GetHeight();
+        }
+        else if ( rSz.GetHeightPercent() == 0xFF )
+        {
+            aRet.Height() *= aRet.Width();
+            aRet.Height() /= rSz.GetWidth();
+        }
+    }
+    return aRet;
+}
+
+/*************************************************************************
+|*
+|*  SwFlyFrm::AddSpacesToFrm
+|*
+|*  Ersterstellung      MA 11. Nov. 96
+|*  Letzte Aenderung    MA 10. Mar. 97
+|*
+|*************************************************************************/
+
+SwRect SwFlyFrm::AddSpacesToFrm() const
+{
+    SwRect aRect( Frm() );
+    const SvxULSpaceItem &rUL = GetFmt()->GetULSpace();
+    const SvxLRSpaceItem &rLR = GetFmt()->GetLRSpace();
+    aRect.Left( Max( aRect.Left() - long(rLR.GetLeft()), 0L ) );
+    aRect.SSize().Width() += rLR.GetRight();
+    aRect.Top( Max( aRect.Top() - long(rUL.GetUpper()), 0L ) );
+    aRect.SSize().Height()+= rUL.GetLower();
+    return aRect;
+}
+
+/*************************************************************************
+|*
+|*  SwFlyFrm::GetContour()
+|*
+|*  Ersterstellung      MA 09. Jan. 97
+|*  Letzte Aenderung    MA 10. Jan. 97
+|*
+|*************************************************************************/
+
+BOOL SwFlyFrm::GetContour( PolyPolygon & rPoly ) const
+{
+    BOOL bRet = FALSE;
+    if( GetFmt()->GetSurround().IsContour() && Lower() &&
+        Lower()->IsNoTxtFrm() )
+    {
+        SwNoTxtNode *pNd = (SwNoTxtNode*)((SwCntntFrm*)Lower())->GetNode();
+        const Graphic aGrf( pNd->GetGraphic() );
+        if( GRAPHIC_NONE != aGrf.GetType() )
+        {
+            if( !pNd->HasContour() )
+                pNd->CreateContour();
+            pNd->GetContour( rPoly );
+            //Der Node haelt das Polygon passend zur Originalgroesse der Grafik
+            //hier muss die Skalierung einkalkuliert werden.
+            SwRect aClip;
+            SwRect aOrig;
+            Lower()->Calc();
+            ((SwNoTxtFrm*)Lower())->GetGrfArea( aClip, &aOrig, FALSE );
+            SvxContourDlg::ScaleContour( rPoly, aGrf, MAP_TWIP, aOrig.SSize() );
+            rPoly.Move( aOrig.Left(), aOrig.Top() );
+            rPoly.Clip( aClip.SVRect() );
+            bRet = TRUE;
+        }
+    }
+    return bRet;
+}
+
+BOOL SwFlyFrm::ConvertHoriTo40( SwHoriOrient &rHori, SwRelationOrient &rRel,
+                                SwTwips &rPos ) const
+{
+    ASSERT( rHori > PRTAREA, "ConvertHoriTo40: Why?" );
+    if( !GetAnchor() )
+        return FALSE;
+    rHori = HORI_NONE;
+    rRel = FRAME;
+    rPos = Frm().Left() - GetAnchor()->Frm().Left();
+    return TRUE;
+}
+
+
diff --git a/sw/source/core/layout/flycnt.cxx b/sw/source/core/layout/flycnt.cxx
new file mode 100644
index 000000000000..36b2719730a4
--- /dev/null
+++ b/sw/source/core/layout/flycnt.cxx
@@ -0,0 +1,1970 @@
+/*************************************************************************
+ *
+ *  $RCSfile: flycnt.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:22 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+
+#ifndef _BIGINT_HXX //autogen
+#include 
+#endif
+#include "pagefrm.hxx"
+#include "rootfrm.hxx"
+#include "cntfrm.hxx"
+#include "flyfrm.hxx"
+#include "txtfrm.hxx"
+#include "doc.hxx"
+#include "viewsh.hxx"
+#include "viewimp.hxx"
+#include "pam.hxx"
+#include "frmfmt.hxx"
+#include "frmtool.hxx"
+#include "dflyobj.hxx"
+#include "hints.hxx"
+#include "swundo.hxx"
+#include "errhdl.hxx"
+
+#ifndef _SVX_ULSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _FMTORNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFSIZE_HXX //autogen
+#include 
+#endif
+#ifndef _FMTSRND_HXX //autogen
+#include 
+#endif
+#ifndef _NODE_HXX //autogen
+#include 
+#endif
+#include "tabfrm.hxx"
+#include "flyfrms.hxx"
+#include "crstate.hxx"
+#include "sectfrm.hxx"
+
+/*************************************************************************
+|*
+|*  SwFlyAtCntFrm::SwFlyAtCntFrm()
+|*
+|*  Ersterstellung      MA 11. Nov. 92
+|*  Letzte Aenderung    MA 09. Apr. 99
+|*
+|*************************************************************************/
+
+SwFlyAtCntFrm::SwFlyAtCntFrm( SwFlyFrmFmt *pFmt, SwFrm *pAnch ) :
+    SwFlyFreeFrm( pFmt, pAnch )
+{
+    bAtCnt = TRUE;
+    bAutoPosition = FLY_AUTO_CNTNT == pFmt->GetAnchor().GetAnchorId();
+}
+
+/*************************************************************************
+|*
+|*  SwFlyAtCntFrm::CheckCharRect()
+|*
+|*************************************************************************/
+
+void SwFlyAtCntFrm::CheckCharRect()
+{
+    SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)GetFmt();
+    if( FLY_AUTO_CNTNT == pFmt->GetAnchor().GetAnchorId() && GetAnchor() )
+    {
+        SwRect aAutoPos;
+        const SwFmtAnchor& rAnch = pFmt->GetAnchor();
+        if( !rAnch.GetCntntAnchor() )
+            return;
+        if( ((SwTxtFrm*)GetAnchor())->GetAutoPos( aAutoPos,
+              *rAnch.GetCntntAnchor() ) && aAutoPos != aLastCharRect )
+        {
+            SwFmtVertOrient aVert( pFmt->GetVertOrient() );
+            SwFmtHoriOrient aHori( pFmt->GetHoriOrient() );
+            if( ( REL_CHAR == aHori.GetRelationOrient() &&
+                  aAutoPos.Left() != aLastCharRect.Left() ) ||
+                  ( REL_CHAR == aVert.GetRelationOrient() &&
+                    ( aAutoPos.Top() != aLastCharRect.Top() ||
+                      aAutoPos.Height() != aLastCharRect.Height() ) ) )
+                InvalidatePos();
+            aLastCharRect = aAutoPos;
+        }
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFlyAtCntFrm::Modify()
+|*
+|*  Ersterstellung      MA 08. Feb. 93
+|*  Letzte Aenderung    MA 23. Nov. 94
+|*
+|*************************************************************************/
+
+void SwFlyAtCntFrm::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew )
+{
+    USHORT nWhich = pNew ? pNew->Which() : 0;
+    const SwFmtAnchor *pAnch = 0;
+    if( RES_ATTRSET_CHG == nWhich && SFX_ITEM_SET ==
+        ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState( RES_ANCHOR, FALSE,
+            (const SfxPoolItem**)&pAnch ))
+        ;       // Beim GetItemState wird der AnkerPointer gesetzt !
+
+    else if( RES_ANCHOR == nWhich )
+    {
+        //Ankerwechsel, ich haenge mich selbst um.
+        //Es darf sich nicht um einen Wechsel des Ankertyps handeln,
+        //dies ist nur ueber die SwFEShell moeglich.
+        pAnch = (const SwFmtAnchor*)pNew;
+    }
+
+    if( pAnch )
+    {
+        ASSERT( pAnch->GetAnchorId() == GetFmt()->GetAnchor().GetAnchorId(),
+                "Unzulaessiger Wechsel des Ankertyps." );
+
+        //Abmelden, neuen Anker besorgen und 'dranhaengen.
+        SwRect aOld( AddSpacesToFrm() );
+        SwPageFrm *pOldPage = FindPageFrm();
+        const SwFrm *pOldAnchor = GetAnchor();
+        SwCntntFrm *pCntnt = (SwCntntFrm*)GetAnchor();
+        GetAnchor()->RemoveFly( this );
+
+        const BOOL bBodyFtn = (pCntnt->IsInDocBody() || pCntnt->IsInFtn());
+
+        //Den neuen Anker anhand des NodeIdx suchen, am alten und
+        //neuen NodeIdx kann auch erkannt werden, in welche Richtung
+        //gesucht werden muss.
+        const SwNodeIndex aNewIdx( pAnch->GetCntntAnchor()->nNode );
+        SwNodeIndex aOldIdx( *pCntnt->GetNode() );
+
+        //fix: Umstellung, ehemals wurde in der do-while-Schleife nach vorn bzw.
+        //nach hinten gesucht; je nachdem wie welcher Index kleiner war.
+        //Das kann aber u.U. zu einer Endlosschleife fuehren. Damit
+        //wenigstens die Schleife unterbunden wird suchen wir nur in eine
+        //Richtung. Wenn der neue Anker nicht gefunden wird koennen wir uns
+        //immer noch vom Node einen Frame besorgen. Die Change, dass dies dann
+        //der richtige ist, ist gut.
+        const FASTBOOL bNext = aOldIdx < aNewIdx;
+        while ( pCntnt && aOldIdx != aNewIdx )
+        {
+            do
+            {   if ( bNext )
+                    pCntnt = pCntnt->GetNextCntntFrm();
+                else
+                    pCntnt = pCntnt->GetPrevCntntFrm();
+            } while ( pCntnt &&
+                      !(bBodyFtn == (pCntnt->IsInDocBody() ||
+                                     pCntnt->IsInFtn())) );
+            if (pCntnt)
+                aOldIdx = *pCntnt->GetNode();
+        }
+        if ( !pCntnt )
+        {
+            SwCntntNode *pNode = aNewIdx.GetNode().GetCntntNode();
+            pCntnt = pNode->GetFrm( &pOldAnchor->Frm().Pos(), 0, FALSE );
+            ASSERT( pCntnt, "Neuen Anker nicht gefunden" );
+        }
+        //Flys haengen niemals an einem Follow sondern immer am
+        //Master, den suchen wir uns jetzt.
+        const SwFlowFrm *pFlow = pCntnt;
+        while ( pFlow->IsFollow() )
+            pFlow = pFlow->FindMaster();
+        pCntnt = (SwCntntFrm*)pFlow->GetFrm();
+
+        //und schwupp angehaengt das teil...
+        pCntnt->AppendFly( this );
+        if ( pOldPage && pOldPage != FindPageFrm() )
+            NotifyBackground( pOldPage, aOld, PREP_FLY_LEAVE );
+
+        //Fix(3495)
+        _InvalidatePos();
+        InvalidatePage();
+        SetNotifyBack();
+    }
+    else
+        SwFlyFrm::Modify( pOld, pNew );
+}
+
+/*************************************************************************
+|*
+|*  SwFlyAtCntFrm::MakeAll()
+|*
+|*  Beschreibung        Bei einem Absatzgebunden Fly kann es durchaus sein,
+|*      das der Anker auf die Veraenderung des Flys reagiert. Auf diese
+|*      Reaktion hat der Fly natuerlich auch wieder zu reagieren.
+|*      Leider kann dies zu Oszillationen fuehren z.b. Der Fly will nach
+|*      unten, dadurch kann der Inhalt nach oben, der TxtFrm wird kleiner,
+|*      der Fly muss wieder hoeher woduch der Text wieder nach unten
+|*      verdraengt wird...
+|*      Um derartige Oszillationen zu vermeiden, wird ein kleiner Positions-
+|*      stack aufgebaut. Wenn der Fly ein Position erreicht, die er bereits
+|*      einmal einnahm, so brechen wir den Vorgang ab. Um keine Risiken
+|*      einzugehen, wird der Positionsstack so aufgebaut, dass er fuenf
+|*      Positionen zurueckblickt.
+|*      Wenn der Stack ueberlaeuft, wird ebenfalls abgebrochen.
+|*      Der Abbruch fuer dazu, dass der Fly am Ende eine unguenste Position
+|*      einnimmt. Damit es nicht durch einen wiederholten Aufruf von
+|*      Aussen zu einer 'grossen Oszillation' kommen kann wird im Abbruch-
+|*      fall das Attribut des Rahmens auf automatische Ausrichtung oben
+|*      eingestellt.
+|*
+|*  Ersterstellung      MA 12. Nov. 92
+|*  Letzte Aenderung    MA 20. Sep. 96
+|*
+|*************************************************************************/
+//Wir brauchen ein Paar Hilfsklassen zur Kontrolle der Ozillation und ein paar
+//Funktionen um die Uebersicht zu gewaehrleisten.
+
+class SwOszControl
+{
+    static const SwFlyFrm *pStk1;
+    static const SwFlyFrm *pStk2;
+    static const SwFlyFrm *pStk3;
+    static const SwFlyFrm *pStk4;
+    static const SwFlyFrm *pStk5;
+
+    const SwFlyFrm *pFly;
+    Point aStk1, aStk2, aStk3, aStk4, aStk5;
+
+public:
+    SwOszControl( const SwFlyFrm *pFrm );
+    ~SwOszControl();
+    FASTBOOL ChkOsz();
+    static FASTBOOL IsInProgress( const SwFlyFrm *pFly );
+};
+const SwFlyFrm *SwOszControl::pStk1 = 0;
+const SwFlyFrm *SwOszControl::pStk2 = 0;
+const SwFlyFrm *SwOszControl::pStk3 = 0;
+const SwFlyFrm *SwOszControl::pStk4 = 0;
+const SwFlyFrm *SwOszControl::pStk5 = 0;
+
+SwOszControl::SwOszControl( const SwFlyFrm *pFrm ) :
+    pFly( pFrm )
+{
+    if ( !SwOszControl::pStk1 )
+        SwOszControl::pStk1 = pFly;
+    else if ( !SwOszControl::pStk2 )
+        SwOszControl::pStk2 = pFly;
+    else if ( !SwOszControl::pStk3 )
+        SwOszControl::pStk3 = pFly;
+    else if ( !SwOszControl::pStk4 )
+        SwOszControl::pStk4 = pFly;
+    else if ( !SwOszControl::pStk5 )
+        SwOszControl::pStk5 = pFly;
+}
+
+SwOszControl::~SwOszControl()
+{
+    if ( SwOszControl::pStk1 == pFly )
+        SwOszControl::pStk1 = 0;
+    else if ( SwOszControl::pStk2 == pFly )
+        SwOszControl::pStk2 = 0;
+    else if ( SwOszControl::pStk3 == pFly )
+        SwOszControl::pStk3 = 0;
+    else if ( SwOszControl::pStk4 == pFly )
+        SwOszControl::pStk4 = 0;
+    else if ( SwOszControl::pStk5 == pFly )
+        SwOszControl::pStk5 = 0;
+}
+
+FASTBOOL IsInProgress( const SwFlyFrm *pFly )
+{
+    return SwOszControl::IsInProgress( pFly );
+}
+
+FASTBOOL SwOszControl::IsInProgress( const SwFlyFrm *pFly )
+{
+    if ( SwOszControl::pStk1 && !pFly->IsLowerOf( SwOszControl::pStk1 ) )
+        return TRUE;
+    if ( SwOszControl::pStk2 && !pFly->IsLowerOf( SwOszControl::pStk2 ) )
+        return TRUE;
+    if ( SwOszControl::pStk3 && !pFly->IsLowerOf( SwOszControl::pStk3 ) )
+        return TRUE;
+    if ( SwOszControl::pStk4 && !pFly->IsLowerOf( SwOszControl::pStk4 ) )
+        return TRUE;
+    if ( SwOszControl::pStk5 && !pFly->IsLowerOf( SwOszControl::pStk5 ) )
+        return TRUE;
+    return FALSE;
+}
+
+FASTBOOL SwOszControl::ChkOsz()
+{
+    FASTBOOL bRet = TRUE;
+    Point aTmp = pFly->Frm().Pos();
+    if( aTmp == Point() )
+        aTmp.X() = 1;
+    //Ist der Stack am Ende?
+    if ( aStk1 != Point() )
+        return TRUE;
+    if ( aTmp != aStk1 && aTmp != aStk2 && aTmp != aStk3 &&
+         aTmp != aStk4 && aTmp != aStk5 )
+    {
+        aStk1 = aStk2;
+        aStk2 = aStk3;
+        aStk3 = aStk4;
+        aStk4 = aStk5;
+        aStk5 = aTmp;
+        bRet = FALSE;
+    }
+    return bRet;
+}
+
+void SwFlyAtCntFrm::MakeAll()
+{
+    if ( !SwOszControl::IsInProgress( this ) && !IsLocked() && !IsColLocked() &&
+         GetPage() )
+    {
+        //Den Anker muessen wir zwischendurch natuerlich Formatieren, damit
+        //Repaints usw. stimmen sollte er natuerlich trotzdem Invalid bleiben.
+        //Jetzt Stufe 2: Damit Repaints stimmen muessen alle Frms wieder Invalidiert
+        //werden, die unterwegs formatiert werden.
+        //Dazu werden sie ein ein PrtArr eingetragen; die Frms mit CompletePaint
+        //zu flaggen scheint mir hier das Mittel der Wahl.
+        //(Vielleicht sollte es einmal die Moeglichkeit geben sie einfach mit
+        //Paint zu flaggen; kein Formatieren, aber ein Paint-Aufruf, vor allem
+        //wohl fuer TxtFrms geeignet.
+        //Jetzt Stufe 3: einfach ein globales Flag und schon flaggen sie sich
+        //selbst.
+        bSetCompletePaintOnInvalidate = TRUE;
+        SwOszControl aOszCntrl( this );
+
+        if( GetAnchor()->IsInSct() )
+        {
+            SwSectionFrm *pSct = GetAnchor()->FindSctFrm();
+            pSct->Calc();
+        }
+
+        GetAnchor()->Calc();
+        SwFrm* pFooter = GetAnchor()->FindFooterOrHeader();
+        if( pFooter && !pFooter->IsFooterFrm() )
+            pFooter = NULL;
+        FASTBOOL bOsz = FALSE;
+        FASTBOOL bExtra = Lower() && Lower()->IsColumnFrm();
+
+        do {
+            Point aOldPos( Frm().Pos() );
+            SwFlyFreeFrm::MakeAll();
+            BOOL bPosChg = aOldPos != Frm().Pos();
+            if( GetAnchor()->IsInSct() )
+            {
+                SwSectionFrm *pSct = GetAnchor()->FindSctFrm();
+                pSct->Calc();
+            }
+
+            GetAnchor()->Calc();
+            if ( aOldPos != Frm().Pos() || ( !GetValidPosFlag() &&
+                 ( pFooter || bPosChg ) ) )
+                bOsz = aOszCntrl.ChkOsz();
+            if( bExtra && Lower() && !Lower()->GetValidPosFlag() )
+            {  // Wenn ein mehrspaltiger Rahmen wg. Positionswechsel ungueltige
+                // Spalten hinterlaesst, so drehen wir lieber hier eine weitere
+                // Runde und formatieren unseren Inhalt via FormatWidthCols nochmal.
+                _InvalidateSize();
+                bExtra = FALSE; // Sicherhaltshalber gibt es nur eine Ehrenrunde.
+            }
+        } while ( !IsValid() && !bOsz );
+
+        if ( bOsz )
+        {
+            SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)GetFmt();
+            pFmt->LockModify();
+            SwFmtSurround aMain( pFmt->GetSurround() );
+            // Im Notfall setzen wir automatisch positionierte Rahmen mit
+            // Rekursion auf Durchlauf, das duerfte beruhigend wirken.
+            if( IsAutoPos() && aMain.GetSurround() != SURROUND_THROUGHT )
+            {
+                aMain.SetSurround( SURROUND_THROUGHT );
+                pFmt->SetAttr( aMain );
+            }
+            else
+            {
+                SwFmtVertOrient aOrient( pFmt->GetVertOrient() );
+                aOrient.SetVertOrient( VERT_TOP );
+                pFmt->SetAttr( aOrient );
+                //Wenn der Rahmen auf "Kein Umlauf" steht, versuchen wir es mal
+                //mit Seitenumlauf.
+                if ( aMain.GetSurround() == SURROUND_NONE )
+                {
+                    aMain.SetSurround( SURROUND_PARALLEL );
+                    pFmt->SetAttr( aMain );
+                }
+            }
+            pFmt->UnlockModify();
+
+            _InvalidatePos();
+            SwFlyFreeFrm::MakeAll();
+            GetAnchor()->Calc();
+            if ( !GetValidPosFlag() )
+            {
+                SwFlyFreeFrm::MakeAll();
+                GetAnchor()->Calc();
+            }
+            //Osz auf jeden fall zum Stehen bringen.
+            bValidPos = bValidSize = bValidPrtArea = TRUE;
+        }
+        bSetCompletePaintOnInvalidate = FALSE;
+    }
+
+/* MA 18. Apr. 94: Bei Spalten kann der Fly durchaus Y-Maessig ueber dem
+ * Anker stehen!
+    ASSERT( Frm().Top() >= GetAnchor()->Frm().Top(),
+            "Achtung: Rahmen auf Hoehenflug." );
+*/
+
+}
+
+/*************************************************************************
+|*
+|*  FindAnchor() und Hilfsfunktionen.
+|*
+|*  Beschreibung:       Sucht ausgehend von pOldAnch einen Anker fuer
+|*      Absatzgebundene Objekte.
+|*      Wird beim Draggen von Absatzgebundenen Objekten zur Ankeranzeige sowie
+|*      fuer Ankerwechsel benoetigt.
+|*  Ersterstellung      MA 22. Jun. 93
+|*  Letzte Aenderung    MA 30. Jan. 95
+|*
+|*************************************************************************/
+
+class SwDistance
+{
+public:
+    SwTwips nMain, nSub;
+    SwDistance() { nMain = nSub = 0; }
+    SwDistance& operator=( const SwDistance &rTwo )
+        { nMain = rTwo.nMain; nSub = rTwo.nSub; return *this; }
+    BOOL operator<( const SwDistance& rTwo )
+        { return nMain < rTwo.nMain || ( nMain == rTwo.nMain && nSub &&
+          rTwo.nSub && nSub < rTwo.nSub ); }
+    BOOL operator<=( const SwDistance& rTwo )
+        { return nMain < rTwo.nMain || ( nMain == rTwo.nMain && ( !nSub ||
+          !rTwo.nSub || nSub <= rTwo.nSub ) ); }
+};
+
+const SwFrm * MA_FASTCALL lcl_CalcDownDist( SwDistance &rRet,
+                                         const Point &rPt,
+                                         const SwCntntFrm *pCnt )
+{
+    rRet.nSub = 0;
+    //Wenn der Point direkt innerhalb des Cnt steht ist die Sache klar und
+    //der Cntnt hat automatisch eine Entfernung von 0
+    if ( pCnt->Frm().IsInside( rPt ) )
+    {
+        rRet.nMain = 0;
+        return pCnt;
+    }
+    else
+    {
+        const SwLayoutFrm *pUp = pCnt->IsInTab() ? pCnt->FindTabFrm()->GetUpper() : pCnt->GetUpper();
+        // einspaltige Bereiche muessen zu ihrem Upper durchschalten
+        while( pUp->IsSctFrm() )
+            pUp = pUp->GetUpper();
+        //Dem Textflus folgen.
+        if ( pCnt->IsInTab() && pUp->Frm().IsInside( rPt ) )
+        {
+            rRet.nMain = rPt.Y() - pCnt->Frm().Top();
+            return pCnt;
+        }
+        else if ( pUp->Frm().IsInside( rPt ) )
+        {
+            rRet.nMain =  rPt.Y() - pCnt->Frm().Top();
+            return pCnt;
+        }
+        else if ( rPt.X() <  pUp->Frm().Left() &&
+                  rPt.Y() <= pUp->Frm().Bottom() )
+        {
+            const SwFrm *pLay = pUp->GetLeaf( MAKEPAGE_NONE, FALSE, pCnt );
+            if ( !pLay || (pLay->Frm().Left() + pLay->Prt().Right()) < rPt.X() )
+            {
+                rRet.nMain = rPt.Y() - pCnt->Frm().Top();
+                return pCnt;
+            }
+            else
+                rRet.nMain = LONG_MAX;
+        }
+        else
+        {
+            rRet.nMain = (pUp->Frm().Top() + pUp->Prt().Bottom()) - pCnt->Frm().Top();
+
+            const SwFrm *pPre = pCnt;
+            const SwFrm *pLay = pUp->GetLeaf( MAKEPAGE_NONE, TRUE, pCnt );
+            SwTwips nFrmTop, nPrtHeight;
+            BOOL bSct;
+            const SwSectionFrm *pSect = pUp->FindSctFrm();
+            if( pSect )
+            {
+                rRet.nSub = rRet.nMain;
+                rRet.nMain = 0;
+            }
+            if( pSect && !pSect->IsAnLower( pLay ) )
+            {
+                bSct = FALSE;
+                const SwSectionFrm* pNxtSect = pLay ? pLay->FindSctFrm() : 0;
+                if( pSect->IsAnFollow( pNxtSect ) )
+                {
+                    nFrmTop = pLay->Frm().Top();
+                    nPrtHeight = pLay->Prt().Height();
+                    pSect = pNxtSect;
+                }
+                else
+                {
+                    pLay = pSect->GetUpper();
+                    nFrmTop = pSect->Frm().Bottom();
+                    nPrtHeight = pLay->Frm().Top() + pLay->Prt().Top()
+                                 + pLay->Prt().Height() - pSect->Frm().Top()
+                                 - pSect->Frm().Height();
+                    pSect = 0;
+                }
+            }
+            else if( pLay )
+            {
+                nFrmTop = pLay->Frm().Top();
+                nPrtHeight = pLay->Prt().Height();
+                bSct = 0 != pSect;
+            }
+            while ( pLay && !pLay->Frm().IsInside( rPt ) &&
+                    ( pLay->Frm().Top() <= rPt.Y() || pLay->IsInFly() ||
+                      ( pLay->IsInSct() &&
+                      pLay->FindSctFrm()->GetUpper()->Frm().Top() <= rPt.Y())) )
+            {
+                if ( pLay->IsFtnContFrm() )
+                {
+                    if ( !((SwLayoutFrm*)pLay)->Lower() )
+                    {
+                        SwFrm *pDel = (SwFrm*)pLay;
+                        pDel->Cut();
+                        delete pDel;
+                        return pPre;
+                    }
+                    return 0;
+                }
+                else
+                {
+                    if( bSct || pSect )
+                        rRet.nSub += nPrtHeight;
+                    else
+                        rRet.nMain += nPrtHeight;
+                    pPre = pLay;
+                    pLay = pLay->GetLeaf( MAKEPAGE_NONE, TRUE, pCnt );
+                    if( pSect && !pSect->IsAnLower( pLay ) )
+                    {   // If we're leaving a SwSectionFrm, the next Leaf-Frm
+                        // is the part of the upper below the SectionFrm.
+                        const SwSectionFrm* pNxtSect = pLay ?
+                            pLay->FindSctFrm() : NULL;
+                        bSct = FALSE;
+                        if( pSect->IsAnFollow( pNxtSect ) )
+                        {
+                            nFrmTop = pLay->Frm().Top();
+                            nPrtHeight = pLay->Prt().Height();
+                            pSect = pNxtSect;
+                        }
+                        else
+                        {
+                            pLay = pSect->GetUpper();
+                            nFrmTop = pSect->Frm().Bottom();
+                            nPrtHeight = pLay->Frm().Top() + pLay->Prt().Top()
+                                         + pLay->Prt().Height() - pSect->Frm().Top()
+                                         - pSect->Frm().Height();
+                            pSect = 0;
+                        }
+                    }
+                    else if( pLay )
+                    {
+                        nFrmTop = pLay->Frm().Top();
+                        nPrtHeight = pLay->Prt().Height();
+                        bSct = 0 != pSect;
+                    }
+                }
+            }
+            if ( pLay )
+            {
+                if ( pLay->Frm().IsInside( rPt ) )
+                {
+                    if( bSct || pSect )
+                        rRet.nSub += rPt.Y() - nFrmTop;
+                    else
+                        rRet.nMain += rPt.Y() - nFrmTop;
+                }
+                if ( pLay->IsFtnContFrm() && !((SwLayoutFrm*)pLay)->Lower() )
+                {
+                    SwFrm *pDel = (SwFrm*)pLay;
+                    pDel->Cut();
+                    delete pDel;
+                    return 0;
+                }
+                return pLay;
+            }
+            else
+                rRet.nMain = LONG_MAX;
+        }
+    }
+    return 0;
+}
+
+//Bug 3985, optimierungsproblem, vergleiche auch trvlfrm.cxx lcl_FindCntnt()
+#pragma optimize("e",off)
+
+ULONG MA_FASTCALL lcl_FindCntDiff( const Point &rPt, const SwLayoutFrm *pLay,
+                          const SwCntntFrm *& rpCnt,
+                          const BOOL bBody, const BOOL bFtn )
+{
+    //Sucht unterhalb von pLay den dichtesten Cnt zum Point. Der Bezugspunkt
+    //der Cntnts ist immer die linke obere Ecke.
+    //Der Cnt soll moeglichst ueber dem Point liegen.
+
+#ifdef DEBUG
+    Point arPoint( rPt );
+#endif
+
+    rpCnt = 0;
+    ULONG nDistance = ULONG_MAX;
+    ULONG nNearest  = ULONG_MAX;
+    const SwCntntFrm *pCnt = pLay->ContainsCntnt();
+
+    while ( pCnt && (bBody != pCnt->IsInDocBody() || bFtn != pCnt->IsInFtn()))
+    {
+        pCnt = pCnt->GetNextCntntFrm();
+        if ( !pLay->IsAnLower( pCnt ) )
+            pCnt = 0;
+    }
+    const SwCntntFrm *pNearest = pCnt;
+    if ( pCnt )
+    {
+        do
+        {
+            //Jetzt die Entfernung zwischen den beiden Punkten berechnen.
+            //'Delta' X^2 + 'Delta'Y^2 = 'Entfernung'^2
+            ULONG dX = Max( pCnt->Frm().Left(), rPt.X() ) -
+                       Min( pCnt->Frm().Left(), rPt.X() ),
+                  dY = Max( pCnt->Frm().Top(), rPt.Y() ) -
+                       Min( pCnt->Frm().Top(), rPt.Y() );
+            BigInt dX1( dX ), dY1( dY );
+            dX1 *= dX1; dY1 *= dY1;
+            const ULONG nDiff = ::SqRt( dX1 + dY1 );
+            if ( pCnt->Frm().Top() <= rPt.Y() )
+            {
+                if ( nDiff < nDistance )
+                {   //Der ist dichter dran
+                    nDistance = nNearest = nDiff;
+                    rpCnt = pNearest = pCnt;
+                }
+            }
+            else if ( nDiff < nNearest )
+            {
+                nNearest = nDiff;
+                pNearest = pCnt;
+            }
+            pCnt = pCnt->GetNextCntntFrm();
+            while ( pCnt &&
+                    (bBody != pCnt->IsInDocBody() || bFtn != pCnt->IsInFtn()))
+                pCnt = pCnt->GetNextCntntFrm();
+
+        }  while ( pCnt && pLay->IsAnLower( pCnt ) );
+    }
+    if ( nDistance == ULONG_MAX )
+    {   rpCnt = pNearest;
+        return nNearest;
+    }
+    return nDistance;
+}
+
+#pragma optimize("e",on)
+
+const SwCntntFrm * MA_FASTCALL lcl_FindCnt( const Point &rPt, const SwCntntFrm *pCnt,
+                                  const BOOL bBody, const BOOL bFtn )
+{
+    //Sucht ausgehen von pCnt denjenigen CntntFrm, dessen linke obere
+    //Ecke am dichtesten am Point liegt.
+    //Liefert _immer_ einen CntntFrm zurueck.
+
+    //Zunaechst wird versucht den dichtesten Cntnt innerhalt derjenigen
+    //Seite zu suchen innerhalb derer der Cntnt steht.
+    //Ausgehend von der Seite muessen die Seiten in beide
+    //Richtungen beruecksichtigt werden.
+    //Falls moeglich wird ein Cntnt geliefert, dessen Y-Position ueber der
+    //des Point sitzt.
+    const SwCntntFrm  *pRet, *pNew;
+    const SwLayoutFrm *pLay = pCnt->FindPageFrm();
+    ULONG nDist;
+
+    nDist = ::lcl_FindCntDiff( rPt, pLay, pNew, bBody, bFtn );
+    if ( pNew )
+        pRet = pNew;
+    else
+    {   pRet  = pCnt;
+        nDist = ULONG_MAX;
+    }
+    const SwCntntFrm *pNearest = pRet;
+    ULONG nNearest = nDist;
+
+    if ( pLay )
+    {
+        const SwLayoutFrm *pPge = pLay;
+        ULONG nOldNew = ULONG_MAX;
+        for ( USHORT i = 0; pPge->GetPrev() && (i < 3); ++i )
+        {
+            pPge = (SwLayoutFrm*)pPge->GetPrev();
+            const ULONG nNew = ::lcl_FindCntDiff( rPt, pPge, pNew, bBody, bFtn );
+            if ( nNew < nDist )
+            {
+                if ( pNew->Frm().Top() <= rPt.Y() )
+                {
+                    pRet = pNearest = pNew;
+                    nDist = nNearest = nNew;
+                }
+                else if ( nNew < nNearest )
+                {
+                    pNearest = pNew;
+                    nNearest = nNew;
+                }
+            }
+            else if ( nOldNew != ULONG_MAX && nNew > nOldNew )
+                break;
+            else
+                nOldNew = nNew;
+
+        }
+        pPge = pLay;
+        nOldNew = ULONG_MAX;
+        for ( USHORT j = 0; pPge->GetNext() && (j < 3); ++j )
+        {
+            pPge = (SwLayoutFrm*)pPge->GetNext();
+            const ULONG nNew = ::lcl_FindCntDiff( rPt, pPge, pNew, bBody, bFtn );
+            if ( nNew < nDist )
+            {
+                if ( pNew->Frm().Top() <= rPt.Y() )
+                {
+                    pRet = pNearest = pNew;
+                    nDist = nNearest = nNew;
+                }
+                else if ( nNew < nNearest )
+                {
+                    pNearest = pNew;
+                    nNearest = nNew;
+                }
+            }
+            else if ( nOldNew != ULONG_MAX && nNew > nOldNew )
+                break;
+            else
+                nOldNew = nNew;
+        }
+    }
+    if ( (pRet->Frm().Top() > rPt.Y()) )
+        return pNearest;
+    else
+        return pRet;
+}
+
+void lcl_PointToPrt( Point &rPoint, const SwFrm *pFrm )
+{
+    SwRect aTmp( pFrm->Prt() );
+    aTmp += pFrm->Frm().Pos();
+    if ( rPoint.X() < aTmp.Left() )
+        rPoint.X() = aTmp.Left();
+    else if ( rPoint.X() > aTmp.Right() )
+        rPoint.X() = aTmp.Right();
+    if ( rPoint.Y() < aTmp.Top() )
+        rPoint.Y() = aTmp.Top();
+    else if ( rPoint.Y() > aTmp.Bottom() )
+        rPoint.Y() = aTmp.Bottom();
+
+}
+
+const SwCntntFrm *FindAnchor( const SwFrm *pOldAnch, const Point &rNew,
+                              const BOOL bBodyOnly )
+{
+    //Zu der angegebenen DokumentPosition wird der dichteste Cnt im
+    //Textfluss gesucht. AusgangsFrm ist der uebergebene Anker.
+    const SwCntntFrm *pCnt;
+    if ( pOldAnch->IsCntntFrm() )
+        pCnt = (const SwCntntFrm*)pOldAnch;
+    else
+    {   Point aTmp( rNew );
+        SwLayoutFrm *pTmpLay = (SwLayoutFrm*)pOldAnch;
+        if( pTmpLay->IsRootFrm() )
+        {
+            SwRect aTmpRect( aTmp, Size(0,0) );
+            pTmpLay = (SwLayoutFrm*)::FindPage( aTmpRect, pTmpLay->Lower() );
+        }
+        pCnt = pTmpLay->GetCntntPos( aTmp, FALSE, bBodyOnly );
+    }
+
+    //Beim Suchen darauf achten, dass die Bereiche sinnvoll erhalten
+    //bleiben. D.h. in diesem Fall nicht in Header/Footer hinein und
+    //nicht aus Header/Footer hinaus.
+    const BOOL bBody = pCnt->IsInDocBody() || bBodyOnly;
+    const BOOL bFtn  = !bBodyOnly && pCnt->IsInFtn();
+
+    Point aNew( rNew );
+    if ( bBody )
+    {
+        //#38848 Vom Seitenrand in den Body ziehen.
+        const SwFrm *pPage = pCnt->FindPageFrm();
+        ::lcl_PointToPrt( aNew, pPage->GetUpper() );
+        SwRect aTmp( aNew, Size( 0, 0 ) );
+        pPage = ::FindPage( aTmp, pPage );
+        ::lcl_PointToPrt( aNew, pPage );
+    }
+
+    if ( pCnt->IsInDocBody() == bBody && pCnt->Frm().IsInside( aNew ) )
+        return pCnt;
+    else if ( pOldAnch->IsInDocBody() || pOldAnch->IsPageFrm() )
+    {
+        //Vielleicht befindet sich der gewuenschte Anker ja auf derselben
+        //Seite wie der aktuelle Anker.
+        //So gibt es kein Problem mit Spalten.
+        Point aTmp( aNew );
+        const SwCntntFrm *pTmp = pCnt->FindPageFrm()->
+                                        GetCntntPos( aTmp, FALSE, TRUE, FALSE );
+        if ( pTmp && pTmp->Frm().IsInside( aNew ) )
+            return pTmp;
+    }
+
+    //Ausgehend vom Anker suche ich jetzt in beide Richtungen bis ich
+    //den jeweils dichtesten gefunden habe.
+    //Nicht die direkte Entfernung ist relevant sondern die Strecke die
+    //im Textfluss zurueckgelegt werden muss.
+    const SwCntntFrm *pUpLst;
+    const SwCntntFrm *pUpFrm = pCnt;
+    SwDistance nUp, nUpLst;
+    ::lcl_CalcDownDist( nUp, aNew, pUpFrm );
+    SwDistance nDown = nUp;
+    BOOL bNegAllowed = TRUE;//Einmal aus dem negativen Bereich heraus lassen.
+    do
+    {
+        pUpLst = pUpFrm; nUpLst = nUp;
+        pUpFrm = pUpLst->GetPrevCntntFrm();
+        while ( pUpFrm &&
+                (bBody != pUpFrm->IsInDocBody() || bFtn != pUpFrm->IsInFtn()))
+            pUpFrm = pUpFrm->GetPrevCntntFrm();
+        if ( pUpFrm )
+        {
+            ::lcl_CalcDownDist( nUp, aNew, pUpFrm );
+            //Wenn die Distanz innnerhalb einer Tabelle waechst, so lohnt es
+            //sich weiter zu suchen.
+            if ( pUpLst->IsInTab() && pUpFrm->IsInTab() )
+            {
+                while ( pUpFrm && ((nUpLst < nUp && pUpFrm->IsInTab()) ||
+                        bBody != pUpFrm->IsInDocBody()) )
+                {
+                    pUpFrm = pUpFrm->GetPrevCntntFrm();
+                    if ( pUpFrm )
+                        ::lcl_CalcDownDist( nUp, aNew, pUpFrm );
+                }
+            }
+        }
+        if ( !pUpFrm )
+            nUp.nMain = LONG_MAX;
+        if ( nUp.nMain >= 0 )
+        {
+            bNegAllowed = FALSE;
+            if ( nUpLst.nMain < 0 ) //nicht den falschen erwischen, wenn der Wert
+                                    //gerade von negativ auf positiv gekippt ist.
+            {   pUpLst = pUpFrm;
+                nUpLst = nUp;
+            }
+        }
+    } while ( pUpFrm && ( ( bNegAllowed && nUp.nMain < 0 ) || ( nUp <= nUpLst &&
+              ( nUp.nMain != LONG_MAX && nUpLst.nMain != LONG_MAX ) ) ) );
+
+    const SwCntntFrm *pDownLst;
+    const SwCntntFrm *pDownFrm = pCnt;
+    SwDistance nDownLst;
+    if ( nDown.nMain < 0 )
+        nDown.nMain = LONG_MAX;
+    do
+    {
+        pDownLst = pDownFrm; nDownLst = nDown;
+        pDownFrm = pDownLst->GetNextCntntFrm();
+        while ( pDownFrm &&
+                (bBody != pDownFrm->IsInDocBody() || bFtn != pDownFrm->IsInFtn()))
+            pDownFrm = pDownFrm->GetNextCntntFrm();
+        if ( pDownFrm )
+        {
+            ::lcl_CalcDownDist( nDown, aNew, pDownFrm );
+            if ( nDown.nMain < 0 )
+                nDown.nMain = LONG_MAX;
+            //Wenn die Distanz innnerhalb einer Tabelle waechst, so lohnt es
+            //sich weiter zu suchen.
+            if ( pDownLst->IsInTab() && pDownFrm->IsInTab() )
+            {
+                while ( pDownFrm && ( ( nDown.nMain != LONG_MAX && nDownLst < nDownLst
+                        && pDownFrm->IsInTab()) || bBody != pDownFrm->IsInDocBody() ) )
+                {
+                    pDownFrm = pDownFrm->GetNextCntntFrm();
+                    if ( pDownFrm )
+                        ::lcl_CalcDownDist( nDown, aNew, pDownFrm );
+                    if ( nDown.nMain < 0 )
+                        nDown.nMain = LONG_MAX;
+                }
+            }
+        }
+        if ( !pDownFrm )
+            nDown.nMain = LONG_MAX;
+
+    } while ( pDownFrm && nDown <= nDownLst &&
+              nDown.nMain != LONG_MAX && nDownLst.nMain != LONG_MAX );
+
+    //Wenn ich in beide Richtungen keinen gefunden habe, so suche ich mir
+    //denjenigen Cntnt dessen linke obere Ecke dem Point am naechsten liegt.
+    //Eine derartige Situation tritt z.b. auf, wenn der Point nicht im Text-
+    //fluss sondern in irgendwelchen Raendern steht.
+    if ( nDownLst.nMain == LONG_MAX && nUpLst.nMain == LONG_MAX )
+        return ::lcl_FindCnt( aNew, pCnt, bBody, bFtn );
+    else
+        return nDownLst < nUpLst ? pDownLst : pUpLst;
+}
+
+/*************************************************************************
+|*
+|*  SwFlyAtCntFrm::SetAbsPos()
+|*
+|*  Ersterstellung      MA 22. Jun. 93
+|*  Letzte Aenderung    MA 11. Sep. 98
+|*
+|*************************************************************************/
+
+void SwFlyAtCntFrm::SetAbsPos( const Point &rNew )
+{
+//  SwPageFrm *pPage = FindPageFrm();
+//  const SwRect aOld( AddSpacesToFrm() );
+    SwCntntFrm *pCnt = (SwCntntFrm*)::FindAnchor( GetAnchor(), rNew );
+    if( pCnt->IsProtected() )
+        pCnt = (SwCntntFrm*)GetAnchor();
+
+    Point aNew( rNew );
+    SwPageFrm *pPage = 0;
+    if ( pCnt->IsInDocBody() )
+    {
+        //#38848 Vom Seitenrand in den Body ziehen.
+        pPage = pCnt->FindPageFrm();
+        ::lcl_PointToPrt( aNew, pPage->GetUpper() );
+        SwRect aTmp( aNew, Size( 0, 0 ) );
+        pPage = (SwPageFrm*)::FindPage( aTmp, pPage );
+        ::lcl_PointToPrt( aNew, pPage );
+    }
+
+    //RelPos einstellen, nur auf Wunsch invalidieren.
+    //rNew ist eine Absolute Position. Um die RelPos korrekt einzustellen
+    //muessen wir uns die Entfernung von rNew zum Anker im Textfluss besorgen.
+//!!!!!Hier kann Optimiert werden: FindAnchor koennte die RelPos mitliefern!
+    const SwFrm *pFrm = 0;
+    SwTwips nY;
+    if ( pCnt->Frm().IsInside( aNew ) )
+        nY = rNew.Y() - pCnt->Frm().Top();
+    else
+    {
+        SwDistance aDist;
+        pFrm = ::lcl_CalcDownDist( aDist, aNew, pCnt );
+        nY = aDist.nMain + aDist.nSub;
+    }
+
+    SwTwips nX = 0;
+
+    if ( pCnt->IsFollow() )
+    {
+        //Flys haengen niemals an einem Follow sondern immer am
+        //Master, den suchen wir uns jetzt.
+        const SwCntntFrm *pOriginal = pCnt;
+        const SwCntntFrm *pFollow = pCnt;
+        while ( pCnt->IsFollow() )
+        {
+            do
+            {   pCnt = pCnt->GetPrevCntntFrm();
+            } while ( pCnt->GetFollow() != pFollow );
+            pFollow = pCnt;
+        }
+        SwTwips nDiff = 0;
+        do
+        {   const SwFrm *pUp = pFollow->GetUpper();
+            nDiff += pUp->Prt().Height() - pFollow->GetRelPos().Y();
+            pFollow = pFollow->GetFollow();
+        } while ( pFollow != pOriginal );
+        nY += nDiff;
+        nX = pCnt->Frm().Left() - pOriginal->Frm().Left();
+    }
+
+    if ( nY == LONG_MAX )
+        nY = rNew.Y() - pCnt->Frm().Top();
+
+    if ( !pFrm )
+        nX += rNew.X() - pCnt->Frm().Left();
+    else
+        nX = rNew.X() - pFrm->Frm().Left();
+
+    GetFmt()->GetDoc()->StartUndo( UNDO_START );
+
+    if( pCnt != GetAnchor() || ( IsAutoPos() && pCnt->IsTxtFrm() &&
+                                  GetFmt()->GetDoc()->IsHTMLMode() ) )
+    {
+        //Das Ankerattribut auf den neuen Cnt setzen.
+        SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)GetFmt();
+        SwFmtAnchor aAnch( pFmt->GetAnchor() );
+        SwPosition *pPos = (SwPosition*)aAnch.GetCntntAnchor();
+        if( IsAutoPos() && pCnt->IsTxtFrm() )
+        {
+            SwCrsrMoveState eTmpState( MV_SETONLYTEXT );
+            Point aPt( rNew );
+            if( pCnt->GetCrsrOfst( pPos, aPt, &eTmpState )
+                && pPos->nNode == *pCnt->GetNode() )
+            {
+                aLastCharRect.Height( 0 );
+                if( REL_CHAR == pFmt->GetVertOrient().GetRelationOrient() )
+                    nY = LONG_MAX;
+                if( REL_CHAR == pFmt->GetHoriOrient().GetRelationOrient() )
+                    nX = LONG_MAX;
+            }
+            else
+            {
+                pPos->nNode = *pCnt->GetNode();
+                pPos->nContent.Assign( pCnt->GetNode(), 0 );
+            }
+        }
+        else
+        {
+            pPos->nNode = *pCnt->GetNode();
+            pPos->nContent.Assign( pCnt->GetNode(), 0 );
+        }
+        pFmt->GetDoc()->SetAttr( aAnch, *pFmt );
+    }
+    else if ( pPage && pPage != GetPage() )
+        GetPage()->MoveFly( this, pPage );
+
+    const Point aRelPos( nX, nY );
+    ChgRelPos( aRelPos );
+
+    GetFmt()->GetDoc()->EndUndo( UNDO_END );
+
+//  if ( pPage != FindPageFrm() )
+//      ::Notify_Background(GetVirtDrawObj(), pPage, aOld, PREP_FLY_LEAVE, FALSE);
+}
+
+/*************************************************************************
+|*
+|*  SwFlyAtCntFrm::MakeFlyPos()
+|*
+|*  Beschreibung:
+|*
+|*      virtueller Anker: Der virtuelle Anker eines Flys ist der Anker selbst
+|*                        oder einer seiner Follows. Es ist genau derjenige
+|*                        Cntnt, der dem Fly aktuell am naechsten liegt,
+|*                        genauer der aktuellen relativen Position des Fly
+|*                        (siehe auch VertPos, Fix). Es wird nur die
+|*                        vertikale Entfernung gemessen.
+|*                        Der virtuelle Anker fuer die Horizontale Ausrichtung
+|*                        muss nicht ein CntntFrm sein, denn wenn der Fly
+|*                        z.B. ueber einer leeren Spalte steht, so muss eben
+|*                        der LayoutFrm als virtueller Anker dienen, der im
+|*                        Textfluss des Ankers liegt.
+|*
+|*      HoriPos:
+|*          - Automatisch: Die automatische Ausrichtung orientiert sich
+|*            an einem SwFrm der folgendermassen ermittelt wird: Abhaengig
+|*            vom Attriut und ausgehend vom virtuellen Anker wird der
+|*            Bezugsframe gesucht (CntntFrm, LayoutFrm).
+|*          - Fix: Der Wert der relativen Entfernung aus dem Attribut ist
+|*                 die relative Entfernung vom virtuellen Anker.
+|*      VertPos:
+|*          - Automatisch: Die automatische Ausrichtung orientiert sich immer
+|*            am virtuellen Anker.
+|*          - Fix: Der Fly muss nicht in der Umgebung untergebracht sein, in
+|*                 der sein Anker steht; er folgt aber stets dem Textfluss dem
+|*                 der Anker folgt. Geclippt (Drawing) wird der Fly am Rootfrm.
+|*                 Damit die erstgenannte Bedingung erreicht wird, wird der
+|*                 Fly ggf. entsprechend verschoben. Dabei bleibt die relative
+|*                 Position des Attributes erhalten, die tatsaechliche relative
+|*                 Position verhaelt sich zu der des Attributes etwa wie ein
+|*                 Teleskoparm. Der Betrag der relativen Position ist die
+|*                 Entfernung zur AbsPos des Ankers im Textfluss.
+|*
+|*      Es wird immer zuerst die vertikale Position bestimmt, denn erst dann
+|*      steht der virtuelle Anker fest.
+|*      Die tatsaechliche relative Position (Member aRelPos) ist immer die
+|*      die Entfernung zum Anker - sie muss also nicht mit den im Attribut
+|*      angegebenen Werten uebereinstimmen, denn diese geben die Entfernung
+|*      'im Textfluss' an.
+|*
+|*  Ersterstellung      MA 19. Nov. 92
+|*  Letzte Aenderung    MA 14. Nov. 96
+|*
+|*************************************************************************/
+
+inline void ValidateSz( SwFrm *pFrm )
+{
+    if ( pFrm )
+        pFrm->bValidSize = TRUE;
+}
+
+void DeepCalc( const SwFrm *pFrm )
+{
+    if( pFrm->IsSctFrm() )
+        return;
+    USHORT nCnt = 0;
+
+    FASTBOOL bContinue = FALSE;
+    do
+    {   if ( ++nCnt == 10 )
+        {
+            ASSERT( !nCnt, "DeepCalc: Loop detected1?" );
+            break;
+        }
+
+        const FASTBOOL bSetComplete = !pFrm->IsValid();
+        const SwRect aOldFrm( pFrm->Frm() );
+        const SwRect aOldPrt( pFrm->Prt() );
+
+        const SwFrm *pUp = pFrm->GetUpper();
+        if ( pUp )
+        {
+            //Nicht weiter wenn der Up ein Fly mit Spalten ist.
+            if( ( !pUp->IsFlyFrm() || !((SwLayoutFrm*)pUp)->Lower() ||
+                 !((SwLayoutFrm*)pUp)->Lower()->IsColumnFrm() ) &&
+                 !pUp->IsSctFrm() )
+            {
+                const Point aPt( pUp->Frm().Pos() );
+                ::DeepCalc( pUp );
+                bContinue = aPt != pUp->Frm().Pos();
+            }
+        }
+        else
+            pUp = pFrm;
+
+        pFrm->Calc();
+        if ( bSetComplete && (aOldFrm != pFrm->Frm() || aOldPrt != pFrm->Prt()))
+            pFrm->SetCompletePaint();
+
+//      bContinue = !pUp->IsValid();
+        if ( pUp->IsFlyFrm() )
+        {
+            if ( ((SwFlyFrm*)pUp)->IsLocked() ||
+                 (((SwFlyFrm*)pUp)->IsFlyAtCntFrm() &&
+                  SwOszControl::IsInProgress( (const SwFlyFrm*)pUp )) )
+            {
+                bContinue = FALSE;
+            }
+        }
+    } while ( bContinue );
+}
+
+//Ermittlung des virtuellen Ankers fuer die Positionierung.
+//Dieser ist entweder der Anker selbst oder einer seiner Follows.
+
+const SwCntntFrm *GetVirtualAnchor( const SwFlyAtCntFrm *pFly, xub_StrLen nOfs )
+{
+    const SwTxtFrm *pAct = (const SwTxtFrm*)pFly->GetAnchor();
+    const SwTxtFrm* pTmp;
+    do
+    {
+        pTmp = pAct;
+        pAct = pTmp->GetFollow();
+    }
+    while( pAct && nOfs >= pAct->GetOfst() );
+    return pTmp;
+}
+
+//Ermittlung des virtuellen Ankers, an dem sich die horizontale Ausrichtung
+//orientieren muss.
+//pAssumed enthaelt entweder bereits den Anker (Es ist dann der Anker des
+//Flys oder einer seiner Follows) oder die Umgebung die der Orientierung,
+//mangels einer besseren Moeglichkeit, dienen muss.
+
+const SwFrm *GetVirtualHoriAnchor( const SwFrm *pAssumed, const SwFlyFrm *pFly )
+{
+    const SwFrm *pRet = pAssumed;
+
+    if ( !pRet->IsCntntFrm() )
+    {   //Wenn es Lower gibt, die selbst der Anker des Fly oder ein Follow
+        //desselben sind, so wird derjenige ausgewaehlt, der der aktuellen
+        //absoluten vertikalen Position des Fly am naechsten steht.
+        //Gibt es keinen, so bleib es bei pAssumed
+        const SwFrm *pFlow = ((SwLayoutFrm*)pRet)->Lower();
+        SwTwips nCntDiff = LONG_MAX;
+        while ( pFlow )
+        {
+            if ( pFlow->IsCntntFrm() &&
+                 ((SwCntntFrm*)pFly->GetAnchor())->IsAnFollow( (SwCntntFrm*)pFlow ) )
+            {
+                SwTwips nDiff = pFly->Frm().Top() - pFlow->Frm().Top();
+                if ( (nDiff = Abs(nDiff)) < nCntDiff )
+                {
+                    pRet = pFlow;           //Der ist dichter dran
+                    nCntDiff = nDiff;
+                }
+            }
+            pFlow = pFlow->GetNext();
+        }
+    }
+    return pRet;
+
+}
+
+void SwFlyAtCntFrm::AssertPage()
+{
+    //Prueft ob der Fly an der Seite haengt, auf der er steht, falls nicht
+    //wird er umgehaengt. Zur Pruefung wird nur die vertikale Ausrichtung
+    //herangezogen.
+
+    SwPageFrm *pNewPage = FindPageFrm();
+    SwPageFrm *pMyPage  = pNewPage;
+    BOOL bSuperfluous = FALSE;
+
+    //#45516# Ausnahmebehandlung. Eine Tabelle ist zu gross und haengt aus der
+    //Seite heraus. Der Rahmen kann dann zwar richtig bei seinem Anker stehen,
+    //Positionsmaessig aber ueber der naechsten Seite haengen. Damit das dann
+    //noch halbwegs brauchbar gedruckt werden kann (HTML) und der Rahmen nicht
+    //wirr in der Gegend gepaintet wird, wird der Rahmen bei der Seite verankert,
+    //auf der auch sein Anker sitzt.
+    if ( GetAnchor()->GetValidSizeFlag() &&
+         Frm().Top() >= GetAnchor()->Frm().Top() &&
+         Frm().Top() < GetAnchor()->Frm().Bottom() )
+    {
+        pNewPage = GetAnchor()->FindPageFrm();
+    }
+    else
+    {
+        BOOL bFound = FALSE;
+        const BOOL bFtn = GetAnchor()->IsInFtn();
+        int nDir = INT_MAX; // 1 == Forward, 2 == Backward.
+        while ( !bFound )
+        {
+            pNewPage->Calc();
+            if ( Frm().Top() < pNewPage->Frm().Top() && pNewPage->GetPrev() )
+            {
+                pNewPage = (SwPageFrm*)pNewPage->GetPrev();
+                if ( nDir == 2 )
+                {
+                    bFound = TRUE;
+                    pNewPage = GetAnchor()->FindPageFrm();
+                }
+                else
+                    nDir = 1;
+            }
+            else if ( Frm().Top() > pNewPage->Frm().Bottom() )
+            {
+                if ( nDir == 1 )
+                {
+                    bFound = TRUE;
+                    pNewPage = GetAnchor()->FindPageFrm();
+                }
+                else
+                {
+                    nDir = 2;
+                    if ( !pNewPage->GetNext() )
+                    {
+                        pNewPage->GetLeaf( bFtn ? MAKEPAGE_NONE : MAKEPAGE_APPEND,
+                                            TRUE, GetAnchor());
+                        bSuperfluous = TRUE;
+                    }
+                    if ( pNewPage->GetNext() )
+                    {
+                        pNewPage = (SwPageFrm*)pNewPage->GetNext();
+                        if( pNewPage->IsEmptyPage() )
+                        {
+                            if( pNewPage->GetNext() )
+                                pNewPage = (SwPageFrm*)pNewPage->GetNext();
+                            else
+                            {
+                                bFound = TRUE;
+                                pNewPage = (SwPageFrm*)pNewPage->GetPrev();
+                            }
+                        }
+                    }
+                    else
+                        bFound = TRUE;
+                }
+            }
+            else
+                bFound = TRUE;
+        }
+    }
+
+    if ( pMyPage != pNewPage )
+    {
+        ASSERT( IsLocked(), "AssertPage: Unlocked Frame??" );
+        pMyPage->MoveFly( this, pNewPage );
+        if ( bSuperfluous && pMyPage->GetPhyPageNum() > pNewPage->GetPhyPageNum() )
+            ((SwRootFrm*)pNewPage->GetUpper())->SetSuperfluous();
+    }
+
+}
+
+BOOL MA_FASTCALL lcl_IsMoveable( SwFlyFrm *pFly, SwLayoutFrm *pLay )
+{
+    //Waere der Anker auch in der neuen Umgebung noch moveable?
+    BOOL bRet;
+    SwLayoutFrm *pUp = pFly->GetAnchor()->GetUpper();
+    SwFrm *pNext = pFly->GetAnchor()->GetNext();
+    pFly->GetAnchor()->Remove();
+    pFly->GetAnchor()->InsertBefore( pLay, pLay->Lower() );
+    bRet = pFly->GetAnchor()->IsMoveable();
+    pFly->GetAnchor()->Remove();
+    pFly->GetAnchor()->InsertBefore( pUp, pNext );
+    return bRet;
+
+}
+
+// Wer weicht wem aus bzw. welcher Bereich ist "linker"/"rechter" als welcher?
+BOOL MA_FASTCALL lcl_Minor( SwRelationOrient eRelO, SwRelationOrient eRelO2,
+    BOOL bLeft )
+{
+    // Die Ausweichreihenfolge der SwRelationOrient-Enums bei linker Ausrichtung
+    static USHORT __READONLY_DATA aLeft[ LAST_ENUM_DUMMY ] =
+        { 5, 6, 0, 1, 8, 4, 7, 2, 3 };
+    // Die Ausweichreihenfolge der SwRelationOrient-Enums Ausrichtung rechts
+    static USHORT __READONLY_DATA aRight[ LAST_ENUM_DUMMY ] =
+        { 5, 6, 0, 8, 1, 7, 4, 2, 3 };
+    // Hier wird z.B. entschieden, dass ein Rahmen im Absatzbereich
+    // einem Rahmen im Seitentextbereich ausweicht usw.
+    if( bLeft )
+        return aLeft[ eRelO ] >= aLeft[ eRelO2 ];
+    return aRight[ eRelO ] >= aRight[ eRelO2 ];
+}
+
+void SwFlyAtCntFrm::MakeFlyPos()
+{
+    if ( !bValidPos )
+    {
+        const SwFrm* pFooter = GetAnchor()->FindFooterOrHeader();
+        if( pFooter && !pFooter->IsFooterFrm() )
+            pFooter = NULL;
+        const FASTBOOL bBrowse = GetAnchor()->IsInDocBody() && !GetAnchor()->IsInTab() ?
+                                     GetFmt()->GetDoc()->IsBrowseMode() : FALSE;
+        FASTBOOL bInvalidatePage = FALSE;
+        SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)GetFmt();
+        const SvxLRSpaceItem &rLR = pFmt->GetLRSpace();
+        const SvxULSpaceItem &rUL = pFmt->GetULSpace();
+        const FASTBOOL bNoSurround
+            = pFmt->GetSurround().GetSurround() == SURROUND_NONE;
+        BOOL bGrow =
+            !GetAnchor()->IsInTab() || !pFmt->GetFrmSize().GetHeightPercent();
+
+        for (;;)
+        {
+        bValidPos = TRUE;
+        if( !pFooter )
+            ::DeepCalc( GetAnchor() );
+        bValidPos = TRUE;
+
+        //Die Werte in den Attributen muessen ggf. upgedated werden,
+        //deshalb werden hier Attributinstanzen und Flags benoetigt.
+        SwFmtVertOrient aVert( pFmt->GetVertOrient() );
+        SwFmtHoriOrient aHori( pFmt->GetHoriOrient() );
+        BOOL bVertChgd = FALSE,
+             bHoriChgd = FALSE,
+             bMoveable = GetAnchor()->IsMoveable();
+
+        //Wird waehrend der Berechnung der vertikalen Position benutzt
+        //und enthaelt hinterher den Frm, an dem sich die horizontale
+        //Positionierung orientieren muss.
+        const SwFrm *pOrient = GetAnchor();
+
+        // Dies wird der Frame, der das Zeichen eines am Zeichen gebundenen
+        // Rahmens enthaelt.
+        const SwFrm *pAutoOrient = pOrient;
+
+        SwRect *pAutoPos;
+        if( FLY_AUTO_CNTNT == pFmt->GetAnchor().GetAnchorId() )
+        {
+            const SwFmtAnchor& rAnch = pFmt->GetAnchor();
+            if( !aLastCharRect.Height() &&
+                !((SwTxtFrm*)GetAnchor())->GetAutoPos( aLastCharRect,
+                                                    *rAnch.GetCntntAnchor() ) )
+                return;
+            pAutoPos = &aLastCharRect;
+            pAutoOrient = ::GetVirtualAnchor( this, rAnch.GetCntntAnchor()->
+                                              nContent.GetIndex() );
+        }
+        else
+            pAutoPos = NULL;
+
+        //Horizontale und vertikale Positionen werden getrennt berechnet.
+        //Sie koennen jeweils Fix oder Variabel sein.
+
+        //Zuerst die vertikale Position, damit feststeht auf welcher Seite
+        //bzw. in welchen Upper sich der Fly befindet.
+        if ( aVert.GetVertOrient() != VERT_NONE )
+        {
+            pOrient = pAutoOrient;
+            if( !pFooter )
+                ::DeepCalc( pOrient );
+            SwTwips nHeight, nAdd;
+            if ( aVert.GetRelationOrient() == PRTAREA )
+            {
+                nHeight = pOrient->Prt().Height();
+                nAdd = pOrient->Prt().Top();
+            }
+            else if( pAutoPos && REL_CHAR == aVert.GetRelationOrient() )
+            {
+                nHeight = pAutoPos->Height();
+                nAdd = pAutoPos->Top() - pAutoOrient->Frm().Top();
+            }
+            else
+            {   nHeight = pOrient->Frm().Height();
+                nAdd = 0;
+            }
+            if ( aVert.GetVertOrient() == VERT_CENTER )
+                aRelPos.Y() = (nHeight / 2) - (aFrm.Height() / 2);
+            else if ( aVert.GetVertOrient() == VERT_BOTTOM )
+            {
+                if( bNoSurround )
+                    aRelPos.Y() = nHeight + rUL.GetUpper();
+                else
+                    aRelPos.Y() = nHeight - (aFrm.Height() + rUL.GetLower());
+            }
+            else  if( pAutoPos && aVert.GetVertOrient() == VERT_CHAR_BOTTOM )
+                aRelPos.Y() = nHeight + rUL.GetUpper();
+            else
+                aRelPos.Y() = rUL.GetUpper();
+            aRelPos.Y() += nAdd;
+            SwTwips nBot = pOrient->Frm().Top() + aRelPos.Y() + Frm().Height()
+                           - pOrient->GetUpper()->Frm().Top()
+                           - pOrient->GetUpper()->Prt().Bottom() - 1;
+            if( nBot > 0 )
+                aRelPos.Y() -= nBot;
+            aRelPos.Y() = Max( aRelPos.Y(), 0L );
+            //Da die relative Position immer zum Anker relativ ist, muss dessen
+            //Entfernung zum virtuellen Anker aufaddiert werden.
+            if ( GetAnchor() != pOrient )
+                aRelPos.Y() += pOrient->Frm().Top() - GetAnchor()->Frm().Top();
+
+            if ( aRelPos.Y() != aVert.GetPos() )
+            {   aVert.SetPos( aRelPos.Y() );
+                bVertChgd = TRUE;
+            }
+        }
+
+        pOrient = aVert.GetVertOrient() == VERT_NONE ?
+                  GetAnchor()->GetUpper() : pAutoOrient->GetUpper();
+        if( !pFooter )
+            ::DeepCalc( pOrient );
+
+        SwTwips nRelDiff = 0;
+        if ( aVert.GetVertOrient() == VERT_NONE )
+        {
+            SwTwips nRel;
+            if( pAutoPos && REL_CHAR == aVert.GetRelationOrient() )
+            {
+                nRel = pAutoPos->Bottom() - pAutoOrient->Frm().Top() + 1
+                       - aVert.GetPos();
+                if( pAutoOrient != GetAnchor() )
+                {
+                    SwTxtFrm* pTmp = (SwTxtFrm*)GetAnchor();
+                    nRel -= pTmp->GetRelPos().Y();
+                    while( pTmp != pAutoOrient )
+                    {
+                        nRel += pTmp->GetUpper()->Prt().Height();
+                        pTmp = pTmp->GetFollow();
+                    }
+                }
+            }
+            else
+                nRel = aVert.GetPos();
+
+            // Einen einspaltigen Bereich koennen wir getrost ignorieren,
+            // er hat keine Auswirkung auf die Fly-Position
+            while( pOrient->IsSctFrm() )
+                pOrient = pOrient->GetUpper();
+            //pOrient ist das LayoutBlatt, das gerade verfolgt wird.
+            //nRel    enthaelt die noch zu verarbeitende relative Entfernung.
+            //nAvail  enthaelt die Strecke die im LayoutBlatt, das gerade
+            //        verfolgt wird zur Verfuegung steht.
+
+            if ( nRel <= 0 )
+                aRelPos.Y() = 0;
+            else
+            {
+                SwTwips nAvail = pOrient->Frm().Top() + pOrient->Prt().Top()
+                    + pOrient->Prt().Height() - GetAnchor()->Frm().Top();
+                const BOOL bFtn = GetAnchor()->IsInFtn();
+                while ( nRel )
+                {   if ( nRel <= nAvail ||
+                            (bBrowse &&
+                            ((SwFrm*)pOrient)->Grow( nRel-nAvail, pHeight, TRUE)) ||
+                            (pOrient->IsInTab() && bGrow && //MA_FLY_HEIGHT
+                            ((SwFrm*)pOrient)->Grow( nRel-nAvail, pHeight, TRUE)))
+                    {   aRelPos.Y() = (pOrient->Frm().Top() +
+                                        pOrient->Prt().Top() +
+                                        (pOrient->Prt().Height() -
+                                        nAvail) + nRel) -
+                                        GetAnchor()->Frm().Top();
+                        if ( ( bBrowse || ( pOrient->IsInTab() && bGrow ) )
+                             && nRel - nAvail > 0 )
+                        {
+                            nRel = ((SwFrm*)pOrient)->Grow( nRel-nAvail, pHeight );
+                            SwFrm *pTmp = (SwFrm*) pOrient->FindPageFrm();
+                            ::ValidateSz( pTmp );
+                            bInvalidatePage = TRUE;
+                            //Schon mal einstellen, weil wir wahrscheinlich
+                            //wegen Invalidierung eine Ehrenrunde drehen.
+                            aFrm.Pos().Y() = aFrm.Top() + nRel;
+                        }
+                        nRel = 0;
+                    }
+                    else if ( bMoveable )
+                    {   //Dem Textfluss folgen.
+                        nRel -= nAvail;
+                        const BOOL bSct = pOrient->IsInSct();
+                        const SwFrm *pTmp = pOrient->
+                            GetLeaf( ( bFtn || bSct ) ? MAKEPAGE_NONE : MAKEPAGE_APPEND,
+                                        TRUE, GetAnchor() );
+                        if ( pTmp && ( !bSct || pOrient->FindSctFrm()->
+                                IsAnFollow( pTmp->FindSctFrm() ) ) )
+                        {
+                            pOrient = pTmp;
+                            bMoveable =
+                                    ::lcl_IsMoveable( this, (SwLayoutFrm*)pOrient);
+                            if( !pFooter )
+                                ::DeepCalc( pOrient );
+                            nAvail = pOrient->Prt().Height();
+                        }
+                        else
+                        {
+                            // Wenn wir innerhalb des (spaltigen) Bereichs nicht genug
+                            // Platz ist, wird es Zeit, diesen zu verlassen. Wir gehen
+                            // also in seinen Upper und nehmen als nAvail den Platz, der
+                            // hinter dem Bereich ist. Sollte dieser immer noch nicht
+                            // ausreichen, wandern wir weiter, es hindert uns aber nun
+                            // niemand mehr, neue Seiten anzulegen.
+                            if( bSct )
+                            {
+                                const SwFrm* pSct = pOrient->FindSctFrm();
+                                pOrient = pSct->GetUpper();
+                                nAvail = pOrient->Frm().Top() + pOrient->Prt().Bottom()
+                                            - pSct->Frm().Top() - pSct->Prt().Bottom();
+                            }
+                            else
+                            {
+                                nRelDiff = nRel;
+                                nRel = 0;
+                            }
+                        }
+                    }
+                    else
+                        nRel = 0;
+                }
+                if ( !bValidPos )
+                    continue;
+            }
+        }
+        //Damit das Teil ggf. auf die richtige Seite gestellt und in die
+        //PrtArea des LayLeaf gezogen werden kann, muss hier seine
+        //absolute Position berechnet werden.
+        aFrm.Pos().Y() = GetAnchor()->Frm().Top() +
+                         (aRelPos.Y() - nRelDiff);
+
+        //Bei automatischer Ausrichtung nicht ueber die Oberkante hinausschiessen.
+        if ( aVert.GetVertOrient() != VERT_NONE )
+        {
+            SwTwips nTop = pOrient->Frm().Top();
+            if ( aVert.GetRelationOrient() == PRTAREA )
+                nTop += pOrient->Prt().Top();
+            if ( aFrm.Top() < nTop )
+            {
+                aFrm.Pos().Y() = nTop;
+                aRelPos.Y() = nTop - GetAnchor()->Frm().Top();
+                bHeightClipped = TRUE;
+            }
+        }
+
+        const BOOL bFtn = GetAnchor()->IsInFtn();
+        while( pOrient->IsSctFrm() )
+            pOrient = pOrient->GetUpper();
+        if ( aFrm.Bottom() > (pOrient->Frm().Top() + pOrient->Prt().Bottom()) )
+        {
+                                                           //MA_FLY_HEIGHT
+            if ( ( bBrowse && GetAnchor()->IsMoveable() ) ||
+                 ( GetAnchor()->IsInTab() && bGrow ) )
+            {
+                ((SwFrm*)pOrient)->Grow(
+                        aFrm.Bottom() - (pOrient->Frm().Top() + pOrient->Prt().Bottom()), pHeight );
+                SwFrm *pTmp = (SwFrm*) pOrient->FindPageFrm();
+                ::ValidateSz( pTmp );
+                bInvalidatePage = TRUE;
+            }
+
+            while ( bMoveable &&
+                    aFrm.Bottom() > (pOrient->Frm().Top() + pOrient->Prt().Bottom()) )
+            {
+                // Vorsicht, auch innerhalb von Bereichen duerfen keine neuen Seiten angelegt werden
+                const BOOL bSct = pOrient->IsInSct();
+                if ( !bSct && Frm().Top() == pOrient->Frm().Top() + pOrient->Prt().Top() )
+                    //Das teil passt nimmer, da hilft auch kein moven.
+                    break;
+
+                const SwLayoutFrm *pNextLay = pOrient->GetLeaf(
+                    ( bFtn || bSct ) ? MAKEPAGE_NONE : MAKEPAGE_APPEND, TRUE, GetAnchor() );
+                if ( pNextLay && ( !bSct || ( pOrient->FindSctFrm()->
+                     IsAnFollow( pNextLay->FindSctFrm() ) && pNextLay->Prt().Height() ) ) )
+                {
+                    if( !pFooter )
+                        ::DeepCalc( pNextLay );
+                    aRelPos.Y() = pNextLay->Frm().Top() + pNextLay->Prt().Top()
+                                  - GetAnchor()->Frm().Top();
+                    pOrient = pNextLay;
+                    bMoveable = ::lcl_IsMoveable( this, (SwLayoutFrm*)pOrient );
+                    if ( bMoveable && !pFooter )
+                        ::DeepCalc( pOrient );
+                    aFrm.Pos().Y() = GetAnchor()->Frm().Top() + aRelPos.Y();
+                }
+                else if( bSct )
+                {
+                    // Wenn wir innerhalb des Bereich nicht genug Platz haben, gucken
+                    // wir uns mal die Seite an.
+                    const SwFrm* pTmp = pOrient->FindSctFrm()->GetUpper();
+                    if( aFrm.Bottom() > (pTmp->Frm().Top() + pTmp->Prt().Bottom()) )
+                        pOrient = pTmp;
+                    else
+                        break;
+                }
+                else
+                    bMoveable = FALSE;
+            }
+        }
+        AssertPage();
+
+        //Horizontale Ausrichtung.
+        //Die absolute Pos in der vertikalen muss schon mal eingestellt
+        //werden, sonst habe ich Schwierigkeiten den virtuellen Anker
+        //zu ermitteln.
+        aFrm.Pos().Y() = aRelPos.Y() + GetAnchor()->Frm().Top();
+
+        //Den Frm besorgen, an dem sich die horizontale Ausrichtung orientiert.
+        pOrient = ::GetVirtualHoriAnchor( pOrient, this );
+
+        if( !pFooter )
+            ::DeepCalc( pOrient );
+
+        // Achtung: pPage ist nicht unbedingt ein PageFrm, es kann auch ein
+        // SwFlyFrm oder SwCellFrm dahinterstecken
+        const SwFrm *pPage = pOrient;
+        while( !pPage->IsPageFrm() && !pPage->IsFlyFrm() && !pPage->IsCellFrm() )
+        {
+            ASSERT( pPage->GetUpper(), "MakeFlyPos: No Page/FlyFrm Found" );
+            pPage = pPage->GetUpper();
+        }
+
+        const BOOL bEven = !(pPage->FindPageFrm()->GetVirtPageNum() % 2);
+        const BOOL bToggle = aHori.IsPosToggle() && bEven;
+        BOOL bTmpToggle = bToggle;
+        BOOL bPageRel = FALSE;
+        SwTwips nWidth, nAdd;
+        switch ( aHori.GetRelationOrient() )
+        {
+            case PRTAREA:
+            {
+                nWidth = pOrient->Prt().Width();
+                nAdd = pOrient->Prt().Left();
+                break;
+            }
+            case REL_PG_LEFT:
+                bTmpToggle = !bToggle;
+                // kein break;
+            case REL_PG_RIGHT:
+            {
+                if ( bTmpToggle )    // linker Seitenrand
+                {
+                    nWidth = pPage->Prt().Left();
+                    nAdd = pPage->Frm().Left() - pOrient->Frm().Left();
+                }
+                else            // rechter Seitenrand
+                {
+                    nWidth = pPage->Frm().Width();
+                    nAdd = pPage->Prt().Right();
+                    nWidth -= nAdd;
+                    nAdd += pPage->Frm().Left() - pOrient->Frm().Left();
+                }
+                bPageRel = TRUE;
+                break;
+            }
+            case REL_FRM_LEFT:
+                bTmpToggle = !bToggle;
+                // kein break;
+            case REL_FRM_RIGHT:
+            {
+                if ( bTmpToggle )    // linker Absatzrand
+                {
+                    nWidth = pOrient->Prt().Left();
+                    nAdd = 0;
+                }
+                else            // rechter Absatzrand
+                {
+                    nWidth = pOrient->Frm().Width();
+                    nAdd = pOrient->Prt().Right();
+                    nWidth -= nAdd;
+                }
+                break;
+            }
+            case REL_CHAR:
+            {
+                if( pAutoPos )
+                {
+                    nWidth = 0;
+                    nAdd = pAutoPos->Left() - pAutoOrient->Frm().Left();
+                    break;
+                }
+                // No Break!
+            }
+            case REL_PG_PRTAREA:
+            {
+                nWidth = pPage->Prt().Width();
+                nAdd = pPage->Frm().Left() + pPage->Prt().Left()
+                       - pOrient->Frm().Left();
+                bPageRel = TRUE;
+                break;
+            }
+            case REL_PG_FRAME:
+            {
+                nWidth = pPage->Frm().Width();
+                nAdd = pPage->Frm().Left() - pOrient->Frm().Left();
+                bPageRel = TRUE;
+                break;
+            }
+            default:
+            {
+                nWidth = pOrient->Frm().Width();
+                nAdd = 0;
+                break;
+            }
+        }
+        if ( aHori.GetHoriOrient() == HORI_NONE )
+        {
+            if( pAutoPos && REL_CHAR == aHori.GetRelationOrient() )
+                aRelPos.X() = aHori.GetPos() + nAdd;
+            else if( bToggle )
+                aRelPos.X() = nWidth - aFrm.Width() - aHori.GetPos();
+            else
+                aRelPos.X() = aHori.GetPos() + nAdd;
+            //Da die relative Position immer zum Anker relativ ist,
+            //muss dessen Entfernung zum virtuellen Anker aufaddiert werden.
+            if ( GetAnchor() != pOrient )
+            {
+                long nTmp = pOrient->Frm().Left();
+                aRelPos.X() += nTmp - GetAnchor()->Frm().Left();
+                //fix(18546): Kleine Notbremse, wenn der Rahmen jetzt so positioniert
+                //wird, dass er den Anker verdraengt, muessen wir unbedingt agieren.
+                //fix(22698): in Ergaenzung zu obigem Bug passen wir jetzt etwas
+                //grundlicher auf.
+                if( !bPageRel && nTmp > pAnchor->Frm().Right() &&
+                    Frm().Top() < GetAnchor()->Frm().Bottom() )
+                {
+                    nTmp = aRelPos.X() + GetAnchor()->Frm().Left();
+                    if ( nTmp < GetAnchor()->Frm().Right() )
+                        aRelPos.X() = GetAnchor()->Frm().Width()+1;
+                }
+            }
+            if( GetAnchor()->Frm().Left() + aRelPos.X() + aFrm.Width() >
+                pPage->Frm().Right() )
+                aRelPos.X() = pPage->Frm().Right() - GetAnchor()->Frm().Left()
+                              - aFrm.Width();
+            if( GetAnchor()->Frm().Left() + aRelPos.X() < pPage->Frm().Left() )
+                aRelPos.X() = pPage->Frm().Left() - GetAnchor()->Frm().Left();
+        }
+        else
+        {
+            SwHoriOrient eHOri = aHori.GetHoriOrient();
+            SwRelationOrient eRelO = aHori.GetRelationOrient();
+            if( bToggle )
+            {
+                if( HORI_RIGHT == eHOri )
+                    eHOri = HORI_LEFT;
+                else if( HORI_LEFT == eHOri )
+                    eHOri = HORI_RIGHT;
+                if( REL_PG_RIGHT == eRelO )
+                    eRelO = REL_PG_LEFT;
+                else if( REL_PG_LEFT == eRelO )
+                    eRelO = REL_PG_RIGHT;
+                else if( REL_FRM_RIGHT == eRelO )
+                    eRelO = REL_FRM_LEFT;
+                else if( REL_FRM_LEFT == eRelO )
+                    eRelO = REL_FRM_RIGHT;
+            }
+            if ( eHOri == HORI_CENTER )
+                aRelPos.X() = (nWidth / 2) - (aFrm.Width() / 2);
+            else if ( eHOri == HORI_RIGHT )
+                aRelPos.X() = nWidth - (aFrm.Width() + rLR.GetRight());
+            else
+                aRelPos.X() = rLR.GetLeft();
+            aRelPos.X() += nAdd;
+
+            //Da die relative Position immer zum Anker relativ ist,
+            //muss dessen Entfernung zum virtuellen Anker aufaddiert werden.
+            if ( GetAnchor() != pOrient )
+                aRelPos.X() += pOrient->Frm().Left() -
+                               GetAnchor()->Frm().Left();
+
+            if( GetAnchor()->Frm().Left() + aRelPos.X() + aFrm.Width() >
+                pPage->Frm().Right() )
+                aRelPos.X() = pPage->Frm().Right() - GetAnchor()->Frm().Left()
+                              - aFrm.Width();
+            if( GetAnchor()->Frm().Left() + aRelPos.X() < pPage->Frm().Left() )
+                aRelPos.X() = pPage->Frm().Left() - GetAnchor()->Frm().Left();
+
+            //Es muss allen Rahmen ausgewichen werden, die die selbe
+            //automatische Ausrichtung haben und die unter dem Rahmen liegen.
+            if ( HORI_CENTER != eHOri && REL_CHAR != eRelO )
+            {
+                SwRect aTmpFrm( GetAnchor()->Frm().Pos() + aRelPos, Frm().SSize() );
+                const UINT32 nMyOrd = GetVirtDrawObj()->GetOrdNum();
+                SwOrderIter aIter( FindPageFrm(), TRUE );
+                const SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)aIter.Bottom())->GetFlyFrm();
+                const SwFrm *pKontext = ::FindKontext( GetAnchor(), FRM_COLUMN );
+                while ( pFly && nMyOrd > pFly->GetVirtDrawObj()->GetOrdNumDirect() )
+                {
+                    if ( pFly->IsFlyAtCntFrm() && //pFly->IsValid() &&
+                         pFly->Frm().Bottom() >= aTmpFrm.Top() &&
+                         pFly->Frm().Top() <= aTmpFrm.Bottom() &&
+                         ::FindKontext( pFly->GetAnchor(), FRM_COLUMN ) == pKontext )
+                    {
+                        const SwFmtHoriOrient &rHori = pFly->GetFmt()->GetHoriOrient();
+                        SwRelationOrient eRelO2 = rHori.GetRelationOrient();
+                        if( REL_CHAR != eRelO2 )
+                        {
+                            SwHoriOrient eHOri2 = rHori.GetHoriOrient();
+                            if( bEven && rHori.IsPosToggle() )
+                            {
+                                if( HORI_RIGHT == eHOri2 )
+                                    eHOri2 = HORI_LEFT;
+                                else if( HORI_LEFT == eHOri2 )
+                                    eHOri2 = HORI_RIGHT;
+                                if( REL_PG_RIGHT == eRelO2 )
+                                    eRelO2 = REL_PG_LEFT;
+                                else if( REL_PG_LEFT == eRelO2 )
+                                    eRelO2 = REL_PG_RIGHT;
+                                else if( REL_FRM_RIGHT == eRelO2 )
+                                    eRelO2 = REL_FRM_LEFT;
+                                else if( REL_FRM_LEFT == eRelO2 )
+                                    eRelO2 = REL_FRM_RIGHT;
+                            }
+                            if ( eHOri2 == eHOri &&
+                                 lcl_Minor( eRelO, eRelO2, HORI_LEFT == eHOri ) )
+                            {
+                                //Die Berechnung wird dadurch etwas aufwendiger, das die
+                                //Ausgangsbasis der Flys unterschiedlich sein koennen.
+                                const SvxLRSpaceItem &rLRI = pFly->GetFmt()->GetLRSpace();
+                                const SwTwips nFlyLeft = pFly->Frm().Left() - rLRI.GetLeft();
+                                const SwTwips nFlyRight = pFly->Frm().Right() + rLRI.GetRight();
+                                // Hier wird noch abgefangen, dass die beiden Rahmen in verschiedenen
+                                // Spalten stehen, aber an ein und demselben TxtFrm (Master/Follow)
+                                // verankert sind. Das FindKontext ist nur bedingt aussagekraeftig,
+                                // da es sich immer auf den Master bezieht.
+                                if( nFlyLeft <= aTmpFrm.Right() + rLR.GetRight() &&
+                                    nFlyRight >= aTmpFrm.Left() - rLR.GetLeft() )
+                                {
+                                    // Im folgenden GetAnchor() und nicht pOrient!
+                                    if ( eHOri == HORI_LEFT )
+                                        aRelPos.X() = Max( aRelPos.X(), nFlyRight+1
+                                            +rLRI.GetRight() -GetAnchor()->Frm().Left());
+                                    else if ( eHOri == HORI_RIGHT )
+                                        aRelPos.X() = Min( aRelPos.X(), nFlyLeft-1
+                                            -rLRI.GetLeft() - Frm().Width() - GetAnchor()->Frm().Left());
+                                    aTmpFrm.Pos() = GetAnchor()->Frm().Pos() + aRelPos;
+                                }
+                            }
+                        }
+                    }
+                    pFly = ((SwVirtFlyDrawObj*)aIter.Next())->GetFlyFrm();
+                }
+            }
+
+            if ( aHori.GetPos() != aRelPos.X() )
+            {   aHori.SetPos( aRelPos.X() );
+                bHoriChgd = TRUE;
+            }
+        }
+
+        AssertPage();
+
+        //Die AbsPos ergibt sich aus der Absoluten Position des Ankers
+        //plus der relativen Position
+        aFrm.Pos( aRelPos + GetAnchor()->Frm().Pos() );
+
+        //Und ggf. noch die aktuellen Werte im Format updaten, dabei darf
+        //zu diesem Zeitpunkt natuerlich kein Modify verschickt werden.
+        pFmt->LockModify();
+        if ( bVertChgd )
+            pFmt->SetAttr( aVert );
+        if ( bHoriChgd )
+            pFmt->SetAttr( aHori );
+        pFmt->UnlockModify();
+
+        break;
+        }
+        if ( bInvalidatePage )
+            FindPageFrm()->InvalidateSize();
+        if ( !bValidPos && !GetAnchor()->IsValid() )
+        {
+//          ASSERT( StackHack::IsLocked(), "invalid Anchor" );
+            bValidPos = TRUE;
+        }
+    }
+}
+
+
diff --git a/sw/source/core/layout/flyincnt.cxx b/sw/source/core/layout/flyincnt.cxx
new file mode 100644
index 000000000000..b277c541ac41
--- /dev/null
+++ b/sw/source/core/layout/flyincnt.cxx
@@ -0,0 +1,369 @@
+/*************************************************************************
+ *
+ *  $RCSfile: flyincnt.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:22 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "cntfrm.hxx"
+#include "doc.hxx"
+#include "flyfrm.hxx"
+#include "frmtool.hxx"
+#include "frmfmt.hxx"
+#include "hints.hxx"
+
+#ifndef _FMTORNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFSIZE_HXX //autogen
+#include 
+#endif
+#include "txtfrm.hxx"       //fuer IsLocked()
+#include "flyfrms.hxx"
+
+
+#if !defined( PRODUCT ) && defined( WNT ) && !defined( ALPHA )
+USHORT DiesIstEinDummyFuerLibMist = 0;
+#endif
+
+//aus FlyCnt.cxx
+void DeepCalc( const SwFrm *pFrm );
+
+/*************************************************************************
+|*
+|*  SwFlyInCntFrm::SwFlyInCntFrm(), ~SwFlyInCntFrm()
+|*
+|*  Ersterstellung      MA 01. Dec. 92
+|*  Letzte Aenderung    MA 09. Apr. 99
+|*
+|*************************************************************************/
+SwFlyInCntFrm::SwFlyInCntFrm( SwFlyFrmFmt *pFmt, SwFrm *pAnch ) :
+    SwFlyFrm( pFmt, pAnch )
+{
+    bInCnt = bInvalidLayout = bInvalidCntnt = TRUE;
+    const SwFmtVertOrient &rVert = pFmt->GetVertOrient();
+    aRelPos.Y() = rVert.GetPos();
+}
+
+SwFlyInCntFrm::~SwFlyInCntFrm()
+{
+    //und Tschuess.
+    if ( !GetFmt()->GetDoc()->IsInDtor() && GetAnchor() )
+    {
+        SwRect aTmp( AddSpacesToFrm() );
+        SwFlyInCntFrm::NotifyBackground( FindPageFrm(), aTmp, PREP_FLY_LEAVE );
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFlyInCntFrm::SetRefPoint(),
+|*
+|*  Ersterstellung      MA 01. Dec. 92
+|*  Letzte Aenderung    MA 06. Aug. 95
+|*
+|*************************************************************************/
+void SwFlyInCntFrm::SetRefPoint( const Point& rPoint, const Point& rRelPos )
+{
+    ASSERT( rPoint != aRef || rRelPos != aRelPos, "SetRefPoint: no change" );
+    const SwFlyNotify aNotify( this );
+    aRef = rPoint;
+    aRelPos = rRelPos;
+    Frm().Pos( rPoint + rRelPos );
+/*
+    //Kein InvalidatePos hier, denn das wuerde dem Cntnt ein Prepare
+    //senden - dieser hat uns aber gerade gerufen.
+    //Da der Frm aber durchaus sein Position wechseln kann, muss hier
+    //der von ihm abdeckte Window-Bereich invalidiert werden damit keine
+    //Reste stehenbleiben.
+    //Fix: Nicht fuer PreView-Shells, dort ist es nicht notwendig und
+    //fuehrt zu fiesen Problemen (Der Absatz wird nur formatiert weil
+    //er gepaintet wird und der Cache uebergelaufen ist, beim Paint durch
+    //das Invalidate wird der Absatz formatiert weil...)
+    if ( Frm().HasArea() && GetShell()->ISA(SwCrsrShell) )
+        GetShell()->InvalidateWindows( Frm() );
+*/
+    InvalidatePage();
+    bValidPos = FALSE;
+    bInvalid  = TRUE;
+    Calc();
+}
+
+/*************************************************************************
+|*
+|*  SwFlyInCntFrm::Modify()
+|*
+|*  Ersterstellung      MA 16. Dec. 92
+|*  Letzte Aenderung    MA 02. Sep. 93
+|*
+|*************************************************************************/
+void SwFlyInCntFrm::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew )
+{
+    BOOL bCallPrepare = FALSE;
+    USHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
+    if( RES_ATTRSET_CHG == nWhich )
+    {
+        if( SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->
+            GetItemState( RES_SURROUND, FALSE ) ||
+            SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->
+            GetItemState( RES_FRMMACRO, FALSE ) )
+        {
+            SwAttrSetChg aOld( *(SwAttrSetChg*)pOld );
+            SwAttrSetChg aNew( *(SwAttrSetChg*)pNew );
+
+            aOld.ClearItem( RES_SURROUND );
+            aNew.ClearItem( RES_SURROUND );
+            aOld.ClearItem( RES_FRMMACRO );
+            aNew.ClearItem( RES_FRMMACRO );
+            if( aNew.Count() )
+            {
+                SwFlyFrm::Modify( &aOld, &aNew );
+                bCallPrepare = TRUE;
+            }
+        }
+        else if( ((SwAttrSetChg*)pNew)->GetChgSet()->Count())
+        {
+            SwFlyFrm::Modify( pOld, pNew );
+            bCallPrepare = TRUE;
+        }
+    }
+    else if( nWhich != RES_SURROUND && RES_FRMMACRO != nWhich )
+    {
+        SwFlyFrm::Modify( pOld, pNew );
+        bCallPrepare = TRUE;
+    }
+
+    if ( bCallPrepare && GetAnchor() )
+        GetAnchor()->Prepare( PREP_FLY_ATTR_CHG, GetFmt() );
+}
+/*************************************************************************
+|*
+|*  SwFlyInCntFrm::Format()
+|*
+|*  Beschreibung:       Hier wird der Inhalt initial mit Formatiert.
+|*  Ersterstellung      MA 16. Dec. 92
+|*  Letzte Aenderung    MA 19. May. 93
+|*
+|*************************************************************************/
+void SwFlyInCntFrm::Format( const SwBorderAttrs *pAttrs )
+{
+    if ( !Frm().Height() )
+    {
+        Lock(); //nicht hintenherum den Anker formatieren.
+        SwCntntFrm *pCntnt = ContainsCntnt();
+        while ( pCntnt )
+        {   pCntnt->Calc();
+            pCntnt = pCntnt->GetNextCntntFrm();
+        }
+        Unlock();
+    }
+    SwFlyFrm::Format( pAttrs );
+}
+/*************************************************************************
+|*
+|*  SwFlyInCntFrm::MakeFlyPos()
+|*
+|*  Beschreibung        Im Unterschied zu anderen Frms wird hier nur die
+|*      die RelPos berechnet. Die absolute Position wird ausschliesslich
+|*      per SetAbsPos errechnet.
+|*  Ersterstellung      MA 03. Dec. 92
+|*  Letzte Aenderung    MA 12. Apr. 96
+|*
+|*************************************************************************/
+void SwFlyInCntFrm::MakeFlyPos()
+{
+    if ( !bValidPos )
+    {
+        if ( !GetAnchor()->IsTxtFrm() || !((SwTxtFrm*)GetAnchor())->IsLocked() )
+            ::DeepCalc( GetAnchor() );
+        if( GetAnchor()->IsTxtFrm() )
+            ((SwTxtFrm*)GetAnchor())->GetFormatted();
+        bValidPos = TRUE;
+        SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)GetFmt();
+        const SwFmtVertOrient &rVert = pFmt->GetVertOrient();
+        //Und ggf. noch die aktuellen Werte im Format updaten, dabei darf
+        //zu diesem Zeitpunkt natuerlich kein Modify verschickt werden.
+        if ( rVert.GetPos() != aRelPos.Y() )
+        {
+            SwFmtVertOrient aVert( rVert );
+            aVert.SetPos( aRelPos.Y() );
+            pFmt->LockModify();
+            pFmt->SetAttr( aVert );
+            pFmt->UnlockModify();
+        }
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFlyInCntFrm::NotifyBackground()
+|*
+|*  Ersterstellung      MA 03. Dec. 92
+|*  Letzte Aenderung    MA 26. Aug. 93
+|*
+|*************************************************************************/
+void SwFlyInCntFrm::NotifyBackground( SwPageFrm *, const SwRect& rRect,
+                                       PrepareHint eHint)
+{
+    if ( eHint == PREP_FLY_ATTR_CHG )
+        GetAnchor()->Prepare( PREP_FLY_ATTR_CHG );
+    else
+        GetAnchor()->Prepare( eHint, (void*)&rRect );
+}
+
+/*************************************************************************
+|*
+|*  SwFlyInCntFrm::GetRelPos()
+|*
+|*  Ersterstellung      MA 04. Dec. 92
+|*  Letzte Aenderung    MA 04. Dec. 92
+|*
+|*************************************************************************/
+const Point &SwFlyInCntFrm::GetRelPos() const
+{
+    Calc();
+    return GetCurRelPos();
+}
+
+/*************************************************************************
+|*
+|*  SwFlyInCntFrm::RegistFlys()
+|*
+|*  Ersterstellung      MA 26. Nov. 93
+|*  Letzte Aenderung    MA 26. Nov. 93
+|*
+|*************************************************************************/
+void SwFlyInCntFrm::RegistFlys()
+{
+    // vgl. SwRowFrm::RegistFlys()
+    SwPageFrm *pPage = FindPageFrm();
+    ASSERT( pPage, "Flys ohne Seite anmelden?" );
+    ::RegistFlys( pPage, this );
+}
+
+/*************************************************************************
+|*
+|*  SwFlyInCntFrm::MakeAll()
+|*
+|*  Ersterstellung      MA 18. Feb. 94
+|*  Letzte Aenderung    MA 13. Jun. 96
+|*
+|*************************************************************************/
+void SwFlyInCntFrm::MakeAll()
+{
+    if ( !GetAnchor() || IsLocked() || IsColLocked() || !FindPageFrm() )
+        return;
+
+    Lock(); //Der Vorhang faellt
+
+        //uebernimmt im DTor die Benachrichtigung
+    const SwFlyNotify aNotify( this );
+    SwBorderAttrAccess aAccess( SwFrm::GetCache(), this );
+    const SwBorderAttrs &rAttrs = *aAccess.Get();
+    const Size &rSz = rAttrs.GetSize();
+    const SwFmtFrmSize &rFrmSz = GetFmt()->GetFrmSize();
+
+    if ( IsClipped() )
+        bValidSize = bHeightClipped = bWidthClipped = FALSE;
+
+    while ( !bValidPos || !bValidSize || !bValidPrtArea )
+    {
+        //Nur einstellen wenn das Flag gesetzt ist!!
+        if ( !bValidSize )
+        {
+            bValidPrtArea = FALSE;
+            long nOldWidth = aFrm.Width();
+            aFrm.Width( CalcRel( rFrmSz ).Width() );
+
+            if ( aFrm.Width() > nOldWidth )
+                //Damit sich der Inhalt anpasst
+                aFrm.Height( CalcRel( rFrmSz ).Height() );
+        }
+
+        if ( !bValidPrtArea )
+            MakePrtArea( rAttrs );
+
+        if ( !bValidSize )
+            Format( &rAttrs );
+
+        if ( !bValidPos )
+            MakeFlyPos();
+
+        if ( bValidPos && bValidSize )
+        {
+            SwFrm *pFrm = GetAnchor();
+            if (
+//MA 03. Apr. 96 fix(26652), Das trifft uns bestimmt nocheinmal
+//          !pFrm->IsMoveable() &&
+                 Frm().Left() == (pFrm->Frm().Left()+pFrm->Prt().Left()) &&
+                 Frm().Width() > pFrm->Prt().Width() )
+            {
+                Frm().Width( pFrm->Prt().Width() );
+                bValidPrtArea = FALSE;
+                bWidthClipped = TRUE;
+            }
+        }
+    }
+    Unlock();
+}
+
diff --git a/sw/source/core/layout/flylay.cxx b/sw/source/core/layout/flylay.cxx
new file mode 100644
index 000000000000..bee3d6ae889d
--- /dev/null
+++ b/sw/source/core/layout/flylay.cxx
@@ -0,0 +1,997 @@
+/*************************************************************************
+ *
+ *  $RCSfile: flylay.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:22 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "doc.hxx"
+#include "pagefrm.hxx"
+#include "rootfrm.hxx"
+#include "cntfrm.hxx"
+#include "dview.hxx"
+#include "dflyobj.hxx"
+#include "dcontact.hxx"
+#include "flyfrm.hxx"
+#include "ftnfrm.hxx"
+#include "frmtool.hxx"
+#include "frmfmt.hxx"
+#include "errhdl.hxx"
+#include "hints.hxx"
+#include "pam.hxx"
+#include "sectfrm.hxx"
+
+
+#ifndef _SVDPAGE_HXX //autogen
+#include 
+#endif
+
+#ifndef _SVX_ULSPITEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _FMTORNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFSIZE_HXX //autogen
+#include 
+#endif
+#include "ndole.hxx"
+#include "tabfrm.hxx"
+#include "flyfrms.hxx"
+
+/*************************************************************************
+|*
+|*  SwFlyFreeFrm::SwFlyFreeFrm(), ~SwFlyFreeFrm()
+|*
+|*  Ersterstellung      MA 03. Dec. 92
+|*  Letzte Aenderung    MA 09. Apr. 99
+|*
+|*************************************************************************/
+
+SwFlyFreeFrm::SwFlyFreeFrm( SwFlyFrmFmt *pFmt, SwFrm *pAnch ) :
+    SwFlyFrm( pFmt, pAnch ),
+    pPage( 0 )
+{
+}
+
+SwFlyFreeFrm::~SwFlyFreeFrm()
+{
+    //und Tschuess.
+    if( GetPage() )
+    {
+        if( GetFmt()->GetDoc()->IsInDtor() )
+        {
+            if ( IsFlyAtCntFrm() && GetPage()->GetSortedObjs() )
+                GetPage()->GetSortedObjs()->Remove( GetVirtDrawObj() );
+        }
+        else
+        {
+            SwRect aTmp( AddSpacesToFrm() );
+            SwFlyFreeFrm::NotifyBackground( GetPage(), aTmp, PREP_FLY_LEAVE );
+        }
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFlyFreeFrm::NotifyBackground()
+|*
+|*  Beschreibung        Benachrichtigt den Hintergrund (alle CntntFrms die
+|*      gerade ueberlappt werden. Ausserdem wird das Window in einigen
+|*      Faellen direkt invalidiert (vor allem dort, wo keine CntntFrms
+|*      ueberlappt werden.
+|*      Es werden auch die CntntFrms innerhalb von anderen Flys
+|*      beruecksichtigt.
+|*  Ersterstellung      MA 03. Dec. 92
+|*  Letzte Aenderung    MA 26. Aug. 93
+|*
+|*************************************************************************/
+
+void SwFlyFreeFrm::NotifyBackground( SwPageFrm *pPage,
+                                     const SwRect& rRect, PrepareHint eHint )
+{
+    ::Notify_Background( GetVirtDrawObj(), pPage, rRect, eHint, TRUE );
+}
+
+/*************************************************************************
+|*
+|*  SwFlyFreeFrm::MakeAll()
+|*
+|*  Ersterstellung      MA 18. Feb. 94
+|*  Letzte Aenderung    MA 03. Mar. 97
+|*
+|*************************************************************************/
+
+void SwFlyFreeFrm::MakeAll()
+{
+    if ( !GetAnchor() || IsLocked() || IsColLocked() || !GetPage() )
+        return;
+
+    Lock(); //Der Vorhang faellt
+
+    //uebernimmt im DTor die Benachrichtigung
+    const SwFlyNotify aNotify( this );
+
+    if ( IsClipped() )
+        bValidPos = bValidSize = bHeightClipped = bWidthClipped = FALSE;
+
+    while ( !bValidPos || !bValidSize || !bValidPrtArea || bFormatHeightOnly )
+    {
+        const SwFmtFrmSize *pSz;
+        {   //Zusaetzlicher Scope, damit aAccess vor dem Check zerstoert wird!
+
+            SwBorderAttrAccess aAccess( SwFrm::GetCache(), this );
+            const SwBorderAttrs &rAttrs = *aAccess.Get();
+            pSz = &rAttrs.GetAttrSet().GetFrmSize();
+
+            //Nur einstellen wenn das Flag gesetzt ist!!
+            if ( !bValidSize )
+            {
+                bValidPrtArea = FALSE;
+                const long nOldWidth = Frm().Width();
+                const Size aTmp( CalcRel( *pSz ) );
+                const SwTwips nMin = MINFLY + rAttrs.CalcLeftLine()+rAttrs.CalcRightLine();
+                aFrm.Width( Max( aTmp.Width(), nMin ) );
+                if ( nOldWidth != Frm().Width() )
+                {
+                    bValidPos = FALSE;  //Clipping kann notwendig sein.
+//MA 03. Mar. 97: Wozu das? Stoert bei #37008#
+//                  if ( aFrm.Width() > nOldWidth )
+//                      aFrm.Height( aTmp.Height() );
+                }
+            }
+
+            if ( !bValidPrtArea )
+                MakePrtArea( rAttrs );
+
+            if ( !bValidSize || bFormatHeightOnly )
+            {
+                bValidSize = FALSE;
+                Format( &rAttrs );
+                bFormatHeightOnly = FALSE;
+            }
+
+            if ( !bValidPos )
+            {
+                const Point aOldPos( Frm().Pos() );
+                MakeFlyPos();
+                if( aOldPos == Frm().Pos() )
+                {
+                    if( !bValidPos && GetAnchor()->IsInSct() &&
+                        !GetAnchor()->FindSctFrm()->IsValid() )
+                        bValidPos = TRUE;
+                }
+                else
+                    bValidSize = FALSE;
+            }
+        }
+        if ( bValidPos && bValidSize )
+            CheckClip( *pSz );
+    }
+    Unlock();
+
+    ASSERT( bHeightClipped || (Frm().Height() > 0 && Prt().Height() > 0),
+            "SwFlyFreeFrm::Format(), flipping Fly." );
+}
+
+/*************************************************************************
+|*
+|*  SwFlyFreeFrm::CheckClip()
+|*
+|*  Ersterstellung      MA 21. Feb. 94
+|*  Letzte Aenderung    MA 03. Mar. 97
+|*
+|*************************************************************************/
+
+void SwFlyFreeFrm::CheckClip( const SwFmtFrmSize &rSz )
+{
+    //Jetzt ist es ggf. an der Zeit geignete Massnahmen zu ergreifen wenn
+    //der Fly nicht in seine Umgebung passt.
+    //Zuerst gibt der Fly seine Position auf. Dananch wird er zunaechst
+    //Formatiert. Erst wenn er auch durch die Aufgabe der Position nicht
+    //passt wird die Breite oder Hoehe aufgegeben - der Rahmen wird soweit
+    //wie notwendig zusammengequetscht.
+
+    const SwVirtFlyDrawObj *pObj = GetVirtDrawObj();
+    SwRect aClip, aTmpStretch;
+    ::CalcClipRect( pObj, aClip, TRUE );
+    ::CalcClipRect( pObj, aTmpStretch, FALSE );
+    aClip._Intersection( aTmpStretch );
+
+    const long nBot = Frm().Bottom();
+    const long nRig = Frm().Right();
+    const long nClipBot = aClip.Bottom();
+    const long nClipRig = aClip.Right();
+
+    const FASTBOOL bBot = nBot > nClipBot;
+    const FASTBOOL bRig = nRig > nClipRig;
+    if ( bBot || bRig )
+    {
+        FASTBOOL bAgain = FALSE;
+        if ( bBot )
+        {
+            const long nOld = Frm().Top();
+            Frm().Pos().Y() = Max( aClip.Top(), aClip.Bottom() - Frm().Height());
+            if ( Frm().Top() != nOld )
+                bAgain = TRUE;
+            bHeightClipped = TRUE;
+        }
+        if ( bRig )
+        {
+            const long nOld = Frm().Left();
+            Frm().Pos().X() = Max( aClip.Left(), aClip.Right() - Frm().Width() );
+            if ( Frm().Left() != nOld )
+            {
+                const SwFmtHoriOrient &rH = GetFmt()->GetHoriOrient();
+                // Links ausgerichtete duerfen nicht nach links verschoben werden,
+                // wenn sie einem anderen ausweichen.
+                if( rH.GetHoriOrient() == HORI_LEFT )
+                    Frm().Pos().X() = nOld;
+                else
+                    bAgain = TRUE;
+            }
+            bWidthClipped = TRUE;
+        }
+        if ( bAgain )
+            bValidSize = FALSE;
+        else
+        {
+            //Wenn wir hier ankommen ragt der Frm in unerlaubte Bereiche
+            //hinein, und eine Positionskorrektur ist nicht erlaubt bzw.
+            //moeglich oder noetig.
+
+            //Fuer Flys mit OLE-Objekten als Lower sorgen wir dafuer, dass
+            //immer proportional Resized wird.
+            Size aOldSize( Frm().SSize() );
+
+            //Zuerst wird das FrmRect eingestellt, und dann auf den Frm
+            //uebertragen.
+            SwRect aFrmRect( Frm() );
+
+            if ( bBot )
+            {
+                long nDiff = nClipBot;
+                nDiff -= aFrmRect.Top() - 1; //nDiff ist die verfuegbare Strecke.
+                nDiff = aFrmRect.Height() - nDiff;
+                aFrmRect.Height( aFrmRect.Height() - nDiff );
+                bHeightClipped = TRUE;
+            }
+            if ( bRig )
+            {
+                long nDiff = nClipRig;
+                nDiff -= aFrmRect.Left() - 1;//nDiff ist die verfuegbare Strecke.
+                nDiff = aFrmRect.Width() - nDiff;
+                aFrmRect.Width( aFrmRect.Width() - nDiff );
+                bWidthClipped = TRUE;
+            }
+
+            if ( Lower() && Lower()->IsNoTxtFrm() &&
+                 ((SwCntntFrm*)Lower())->GetNode()->GetOLENode() )
+            {
+                //Wenn Breite und Hoehe angepasst wurden, so ist die
+                //groessere Veraenderung massgeblich.
+                if ( aFrmRect.Width() != aOldSize.Width() &&
+                     aFrmRect.Height()!= aOldSize.Height() )
+                {
+                    if ( (aOldSize.Width() - aFrmRect.Width()) >
+                         (aOldSize.Height()- aFrmRect.Height()) )
+                        aFrmRect.Height( aOldSize.Height() );
+                    else
+                        aFrmRect.Width( aOldSize.Width() );
+                }
+
+                //Breite angepasst? - Hoehe dann proportional verkleinern
+                if( aFrmRect.Width() != aOldSize.Width() )
+                    aFrmRect.Height( aFrmRect.Width() * aOldSize.Height() /
+                                     aOldSize.Width() );
+
+                //Hoehe angepasst? - Breite dann proportional verkleinern
+                if( aFrmRect.Height() != aOldSize.Height() )
+                    aFrmRect.Width( aFrmRect.Height() * aOldSize.Width() /
+                                    aOldSize.Height() );
+            }
+
+            //Jetzt die Einstellungen am Frm vornehmen, bei Spalten werden
+            //die neuen Werte in die Attribute eingetragen, weil es sonst
+            //ziemlich fiese Oszillationen gibt.
+            const long nPrtHeightDiff = Frm().Height() - Prt().Height();
+            const long nPrtWidthDiff  = Frm().Width()  - Prt().Width();
+            Frm().Height( aFrmRect.Height() );
+            Frm().Width ( aFrmRect.Width() );
+            if ( Lower() && Lower()->IsColumnFrm() )
+            {
+                ColLock();  //Grow/Shrink locken.
+                const Size aOldSize( Prt().SSize() );
+                Prt().Height( Frm().Height() - nPrtHeightDiff );
+                Prt().Width ( Frm().Width()  - nPrtWidthDiff );
+                ChgLowersProp( aOldSize );
+                SwFrm *pLow = Lower();
+                do
+                {   pLow->Calc();
+                    // auch den (Column)BodyFrm mitkalkulieren
+                    ((SwLayoutFrm*)pLow)->Lower()->Calc();
+                    pLow = pLow->GetNext();
+                } while ( pLow );
+                ::CalcCntnt( this );
+                ColUnlock();
+/* MA 02. Sep. 96: Wenn das Attribut gesetzt wird funktionieren Flys in Flys
+ * nicht  (30095 30096)
+                SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)GetFmt();
+                pFmt->LockModify();
+                SwFmtFrmSize aFrmSize( rSz );
+                if ( bRig )
+                    aFrmSize.SetWidth( Frm().Width() );
+                if ( bBot )
+                {
+                    aFrmSize.SetSizeType( ATT_FIX_SIZE );
+                    aFrmSize.SetHeight( Frm().Height() );
+                    bFixHeight = TRUE;
+                    bMinHeight = FALSE;
+                }
+                pFmt->SetAttr( aFrmSize );
+                pFmt->UnlockModify();
+*/
+//Stattdessen:
+                if ( !bValidSize && !bWidthClipped )
+                    bFormatHeightOnly = bValidSize = TRUE;
+            }
+            else
+            {
+                Prt().Height( Frm().Height() - nPrtHeightDiff );
+                Prt().Width ( Frm().Width()  - nPrtWidthDiff );
+            }
+        }
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFlyLayFrm::SwFlyLayFrm()
+|*
+|*  Ersterstellung      MA 25. Aug. 92
+|*  Letzte Aenderung    MA 09. Apr. 99
+|*
+|*************************************************************************/
+
+SwFlyLayFrm::SwFlyLayFrm( SwFlyFrmFmt *pFmt, SwFrm *pAnch ) :
+    SwFlyFreeFrm( pFmt, pAnch )
+{
+    bLayout = TRUE;
+}
+
+/*************************************************************************
+|*
+|*  SwFlyLayFrm::Modify()
+|*
+|*  Ersterstellung      MA 08. Feb. 93
+|*  Letzte Aenderung    MA 28. Aug. 93
+|*
+|*************************************************************************/
+
+void SwFlyLayFrm::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew )
+{
+    USHORT nWhich = pNew ? pNew->Which() : 0;
+
+    SwFmtAnchor *pAnch = 0;
+    if( RES_ATTRSET_CHG == nWhich && SFX_ITEM_SET ==
+        ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState( RES_ANCHOR, FALSE,
+            (const SfxPoolItem**)&pAnch ))
+        ;       // Beim GetItemState wird der AnkerPointer gesetzt !
+
+    else if( RES_ANCHOR == nWhich )
+    {
+        //Ankerwechsel, ich haenge mich selbst um.
+        //Es darf sich nicht um einen Wechsel des Ankertyps handeln,
+        //dies ist nur ueber die SwFEShell moeglich.
+        pAnch = (SwFmtAnchor*)pNew;
+    }
+
+    if( pAnch )
+    {
+        ASSERT( pAnch->GetAnchorId() ==
+                GetFmt()->GetAnchor().GetAnchorId(),
+                "8-) Unzulaessiger Wechsel des Ankertyps." );
+
+        //Abmelden, Seite besorgen, an den entsprechenden LayoutFrm
+        //haengen.
+        SwRect aOld( AddSpacesToFrm() );
+        SwPageFrm *pOldPage = GetPage();
+        GetAnchor()->RemoveFly( this );
+
+        if( FLY_PAGE == pAnch->GetAnchorId() )
+        {
+            USHORT nPgNum = pAnch->GetPageNum();
+            SwRootFrm *pRoot = FindRootFrm();
+            SwPageFrm *pPage = (SwPageFrm*)pRoot->Lower();
+            for ( USHORT i = 1; (i <= nPgNum) && pPage; ++i,
+                                pPage = (SwPageFrm*)pPage->GetNext() )
+            {
+                if ( i == nPgNum )
+                    pPage->PlaceFly( this, 0, pAnch );
+            }
+            if( !pPage )
+            {
+                pRoot->SetAssertFlyPages();
+                pRoot->AssertFlyPages();
+            }
+        }
+        else
+        {
+            SwNodeIndex aIdx( pAnch->GetCntntAnchor()->nNode );
+            SwCntntFrm *pCntnt = GetFmt()->GetDoc()->GetNodes().GoNext( &aIdx )->
+                         GetCntntNode()->GetFrm( 0, 0, FALSE );
+            if( pCntnt )
+            {
+                SwFlyFrm *pTmp = pCntnt->FindFlyFrm();
+                if( pTmp )
+                    pTmp->AppendFly( this );
+            }
+        }
+        if ( pOldPage && pOldPage != GetPage() )
+            NotifyBackground( pOldPage, aOld, PREP_FLY_LEAVE );
+        SetCompletePaint();
+        InvalidateAll();
+        SetNotifyBack();
+    }
+    else
+        SwFlyFrm::Modify( pOld, pNew );
+}
+
+/*************************************************************************
+|*
+|*  SwPageFrm::AppendFly()
+|*
+|*  Ersterstellung      MA 10. Oct. 92
+|*  Letzte Aenderung    MA 08. Jun. 96
+|*
+|*************************************************************************/
+
+void SwPageFrm::AppendFly( SwFlyFrm *pNew )
+{
+    if ( !pNew->GetVirtDrawObj()->IsInserted() )
+        FindRootFrm()->GetDrawPage()->InsertObject(
+                (SdrObject*)pNew->GetVirtDrawObj(),
+                pNew->GetVirtDrawObj()->GetReferencedObj().GetOrdNumDirect() );
+
+    InvalidateSpelling();
+    InvalidateAutoCompleteWords();
+
+    if ( GetUpper() )
+    {
+        ((SwRootFrm*)GetUpper())->SetIdleFlags();
+        ((SwRootFrm*)GetUpper())->InvalidateBrowseWidth();
+    }
+
+    const SdrObjectPtr pObj = pNew->GetVirtDrawObj();
+    ASSERT( pNew->GetAnchor(), "Fly without Anchor" );
+    SwFlyFrm *pFly = pNew->GetAnchor()->FindFlyFrm();
+    if ( pFly && pObj->GetOrdNum() < pFly->GetVirtDrawObj()->GetOrdNum() )
+    {
+        UINT32 nNewNum = pFly->GetVirtDrawObj()->GetOrdNumDirect() + 1;
+        if ( pObj->GetPage() )
+            pObj->GetPage()->SetObjectOrdNum( pObj->GetOrdNumDirect(), nNewNum);
+        else
+            pObj->SetOrdNum( nNewNum );
+    }
+
+    //Flys die im Cntnt sitzen beachten wir nicht weiter.
+    if ( pNew->IsFlyInCntFrm() )
+    {
+        InvalidateFlyInCnt();
+        return;
+    }
+    InvalidateFlyCntnt();
+
+    if ( !pSortedObjs )
+        pSortedObjs = new SwSortDrawObjs();
+    if ( !pSortedObjs->Insert( pObj ) )
+        ASSERT( FALSE, "Fly nicht in Sorted eingetragen." );
+
+    ((SwFlyFreeFrm*)pNew)->SetPage( this );
+    pNew->InvalidatePage( this );
+
+
+    //fix(3018): Kein pNew->Calc() oder sonstiges hier.
+    //Code enfernt in flylay.cxx Rev 1.51
+}
+
+/*************************************************************************
+|*
+|*  SwPageFrm::RemoveFly()
+|*
+|*  Ersterstellung      MA 10. Oct. 92
+|*  Letzte Aenderung    MA 26. Aug. 96
+|*
+|*************************************************************************/
+
+void SwPageFrm::RemoveFly( SwFlyFrm *pToRemove )
+{
+    const UINT32 nOrdNum = pToRemove->GetVirtDrawObj()->GetOrdNum();
+    FindRootFrm()->GetDrawPage()->RemoveObject( nOrdNum );
+    pToRemove->GetVirtDrawObj()->ReferencedObj().SetOrdNum( nOrdNum );
+
+    if ( GetUpper() )
+    {
+        if ( !pToRemove->IsFlyInCntFrm() )
+            ((SwRootFrm*)GetUpper())->SetSuperfluous();
+        ((SwRootFrm*)GetUpper())->InvalidateBrowseWidth();
+    }
+
+    //Flys die im Cntnt sitzen beachten wir nicht weiter.
+    if ( pToRemove->IsFlyInCntFrm() )
+        return;
+
+    //Collections noch nicht loeschen. Das passiert am Ende
+    //der Action im RemoveSuperfluous der Seite - angestossen von gleich-
+    //namiger Methode der Root.
+    //Die FlyColl kann bereits weg sein, weil der DTor der Seite
+    //gerade 'laeuft'
+    if ( pSortedObjs )
+    {
+        pSortedObjs->Remove( pToRemove->GetVirtDrawObj() );
+        if ( !pSortedObjs->Count() )
+        {   DELETEZ( pSortedObjs );
+        }
+    }
+    ((SwFlyFreeFrm*)pToRemove)->SetPage( 0 );
+}
+
+/*************************************************************************
+|*
+|*  SwPageFrm::MoveFly
+|*
+|*  Ersterstellung      MA 25. Jan. 97
+|*  Letzte Aenderung    MA 25. Jan. 97
+|*
+|*************************************************************************/
+
+void SwPageFrm::MoveFly( SwFlyFrm *pToMove, SwPageFrm *pDest )
+{
+    //Invalidierungen
+    if ( GetUpper() )
+    {
+        ((SwRootFrm*)GetUpper())->SetIdleFlags();
+        if ( !pToMove->IsFlyInCntFrm() && pDest->GetPhyPageNum() < GetPhyPageNum() )
+            ((SwRootFrm*)GetUpper())->SetSuperfluous();
+    }
+    pDest->InvalidateSpelling();
+    pDest->InvalidateAutoCompleteWords();
+
+    if ( pToMove->IsFlyInCntFrm() )
+    {
+        pDest->InvalidateFlyInCnt();
+        return;
+    }
+
+    //Die FlyColl kann bereits weg sein, weil der DTor der Seite
+    //gerade 'laeuft'
+    const SdrObjectPtr pObj = pToMove->GetVirtDrawObj();
+    if ( pSortedObjs )
+    {
+        pSortedObjs->Remove( pObj );
+        if ( !pSortedObjs->Count() )
+        {   DELETEZ( pSortedObjs );
+        }
+    }
+
+    //Anmelden
+    if ( !pDest->GetSortedObjs() )
+        pDest->pSortedObjs = new SwSortDrawObjs();
+    if ( !pDest->GetSortedObjs()->Insert( pObj ) )
+        ASSERT( FALSE, "Fly nicht in Sorted eingetragen." );
+
+    ((SwFlyFreeFrm*)pToMove)->SetPage( pDest );
+    pToMove->InvalidatePage( pDest );
+    pToMove->SetNotifyBack();
+    pDest->InvalidateFlyCntnt();
+}
+
+/*************************************************************************
+|*
+|*  SwPageFrm::AppendDrawObject(), RemoveDrawObject()
+|*
+|*  Ersterstellung      MA 09. Jan. 95
+|*  Letzte Aenderung    MA 31. Jul. 96
+|*
+|*************************************************************************/
+
+void SwPageFrm::AppendDrawObj( SwDrawContact *pNew )
+{
+    if ( GetUpper() )
+        ((SwRootFrm*)GetUpper())->InvalidateBrowseWidth();
+
+    const SdrObjectPtr pObj = pNew->GetMaster();
+    ASSERT( pNew->GetAnchor(), "Contact without Anchor" );
+    SwFlyFrm *pFly = pNew->GetAnchor()->FindFlyFrm();
+    if ( pFly && pObj->GetOrdNum() < pFly->GetVirtDrawObj()->GetOrdNum() )
+    {
+        UINT32 nNewNum = pFly->GetVirtDrawObj()->GetOrdNumDirect() + 1;
+        if ( pObj->GetPage() )
+            pObj->GetPage()->SetObjectOrdNum( pObj->GetOrdNumDirect(), nNewNum);
+        else
+            pObj->SetOrdNum( nNewNum );
+    }
+
+    if ( FLY_IN_CNTNT == pNew->GetFmt()->GetAnchor().GetAnchorId() )
+        return;
+
+    if ( !pSortedObjs )
+        pSortedObjs = new SwSortDrawObjs();
+    if ( !pSortedObjs->Insert( pObj ) )
+    {
+#ifndef PRODUCT
+        USHORT nIdx;
+        ASSERT( pSortedObjs->Seek_Entry( pObj, &nIdx ),
+                "Fly nicht in Sorted eingetragen." );
+#endif
+    }
+    pNew->ChgPage( this );
+}
+
+void SwPageFrm::RemoveDrawObj( SwDrawContact *pToRemove )
+{
+    //Auch Zeichengebundene muessen hier leider durchlaufen, weil beim
+    //setzen des Attributes zuerst das Attribut gesetzt und dann das Modify
+    //versendet wird.
+
+    //Die FlyColl kann bereits weg sein, weil der DTor der Seite
+    //gerade 'laeuft'
+    if ( pSortedObjs )
+    {
+        const SdrObjectPtr *pDel = pSortedObjs->GetData();
+        pSortedObjs->Remove( pToRemove->GetMaster() );
+        if ( !pSortedObjs->Count() )
+        {
+            DELETEZ( pSortedObjs );
+        }
+        if ( GetUpper() )
+        {
+            if ( FLY_IN_CNTNT != pToRemove->GetFmt()->GetAnchor().GetAnchorId() )
+            {
+                ((SwRootFrm*)GetUpper())->SetSuperfluous();
+                InvalidatePage();
+            }
+            ((SwRootFrm*)GetUpper())->InvalidateBrowseWidth();
+        }
+    }
+    pToRemove->ChgPage( 0 );
+}
+
+/*************************************************************************
+|*
+|*  SwPageFrm::PlaceFly
+|*
+|*  Ersterstellung      MA 08. Feb. 93
+|*  Letzte Aenderung    MA 27. Feb. 93
+|*
+|*************************************************************************/
+
+SwFrm *SwPageFrm::PlaceFly( SwFlyFrm *pFly, SwFrmFmt *pFmt,
+                            const SwFmtAnchor *pAnch )
+{
+    //Der Fly will immer an der Seite direkt haengen.
+    ASSERT( pAnch->GetAnchorId() == FLY_PAGE, "Unerwartete AnchorId." );
+
+    //Wenn ein Fly uebergeben wurde, so benutzen wir diesen, ansonsten wird
+    //mit dem Format einer erzeugt.
+    if ( pFly )
+        SwFrm::AppendFly( pFly );
+    else
+    {   ASSERT( pFmt, ":-( kein Format fuer Fly uebergeben." );
+        pFly = new SwFlyLayFrm( (SwFlyFrmFmt*)pFmt, this );
+        SwFrm::AppendFly( pFly );
+        ::RegistFlys( this, pFly );
+    }
+    return pFly;
+}
+
+/*************************************************************************
+|*
+|*  ::CalcClipRect
+|*
+|*  Ersterstellung      AMA 24. Sep. 96
+|*  Letzte Aenderung    MA  18. Dec. 96
+|*
+|*************************************************************************/
+
+BOOL CalcClipRect( const SdrObject *pSdrObj, SwRect &rRect, BOOL bMove )
+{
+    BOOL bRet = TRUE;
+    if ( pSdrObj->IsWriterFlyFrame() )
+    {
+        const SwFlyFrm *pFly = ((const SwVirtFlyDrawObj*)pSdrObj)->GetFlyFrm();
+        if( pFly->IsFlyLayFrm() )
+        {
+#ifdef AMA_OUT_OF_FLY
+            const SwFrm *pClip = pFly->GetAnchor()->FindPageFrm();
+#else
+            const SwFrm *pClip = pFly->GetAnchor();
+#endif
+            pClip->Calc();
+
+            rRect = pClip->Frm();
+
+            //Vertikales clipping: Top und Bottom, ggf. an PrtArea
+            const SwFmtVertOrient &rV = pFly->GetFmt()->GetVertOrient();
+            if( rV.GetVertOrient() != VERT_NONE &&
+                rV.GetRelationOrient() == PRTAREA )
+            {
+                rRect.Top( pClip->Frm().Top() + pClip->Prt().Top() );
+                rRect.Bottom( pClip->Frm().Top() + pClip->Prt().Bottom() );
+            }
+            //Horizontales clipping: Left und Right, ggf. an PrtArea
+            const SwFmtHoriOrient &rH = pFly->GetFmt()->GetHoriOrient();
+            if( rH.GetHoriOrient() != HORI_NONE &&
+                rH.GetRelationOrient() == PRTAREA )
+            {
+                rRect.Left( pClip->Frm().Left() + pClip->Prt().Left() );
+                rRect.Right( pClip->Frm().Left() + pClip->Prt().Right() );
+            }
+        }
+        else if( pFly->IsFlyAtCntFrm() )
+        {
+            const SwFrm *pClip = pFly->GetAnchor();
+            const SwLayoutFrm *pUp = pClip->GetUpper();
+            const SwFrm *pCell = pUp->IsCellFrm() ? pUp : 0;
+            USHORT nType = bMove ? FRM_ROOT   | FRM_FLY | FRM_HEADER |
+                                   FRM_FOOTER | FRM_FTN
+                                 : FRM_BODY   | FRM_FLY | FRM_HEADER |
+                                   FRM_FOOTER | FRM_CELL| FRM_FTN;
+
+            while ( !(pUp->GetType() & nType) || pUp->IsColBodyFrm() )
+            {
+                pUp = pUp->GetUpper();
+                if ( !pCell && pUp->IsCellFrm() )
+                    pCell = pUp;
+            }
+            if ( bMove )
+            {
+                if ( pUp->IsRootFrm() )
+                {
+                    rRect  = pUp->Prt();
+                    rRect += pUp->Frm().Pos();
+
+                    const SwPageFrm *pPg = (SwPageFrm*)pUp->Lower();
+                    if( !pPg->Lower() )
+                        pPg = (SwPageFrm*)pPg->GetNext();
+                    const SwFrm *pBody = pPg->FindBodyCont();
+                    if ( pBody->GetPrev() )
+                        pBody->GetPrev()->Calc();
+                    pBody->Calc();
+                    rRect.Top( pBody->Frm().Top() + pBody->Prt().Top() );
+
+                    //Den Bottom setzen wir auf den unteren Rand der letzten Seite.
+                    pPg = ((SwRootFrm*)pUp)->GetLastPage();
+                    if ( !pPg->Lower() )
+                        pPg = (SwPageFrm*)pPg->GetPrev();
+                    if ( pPg )
+                    {
+                        pPg->Calc();
+                        pBody = pPg->FindBodyCont();
+                        if ( pBody->GetPrev() )
+                            pBody->GetPrev()->Calc();
+                        pBody->Calc();
+                        rRect.Bottom( pBody->Frm().Top() + pBody->Prt().Bottom());
+                        if( pFly->GetFmt()->GetDoc()->IsBrowseMode() )
+                        {
+                            // Hier wird folgende Situation abgefangen: Im Browse-
+                            // Modus hat man mehrere Seiten, die aktuelle Seite
+                            // waechst gerade, die letzte Seite hat dies noch nicht
+                            // mitbekommen, dann koennte der von der letzten Seite
+                            // gelieferte nBot zu klein sein, der Fly sich also
+                            // zum Clippen/Moven genoetigt sehen, obgleich genug
+                            // Platz vorhanden ist.
+                            const SwPageFrm* pMyPg = pClip->FindPageFrm();
+                            if( pMyPg != pPg && pMyPg &&
+                                pMyPg->Frm().Bottom() > pPg->Frm().Top() )
+                            {
+                                pBody = pMyPg->FindBodyCont();
+                                if ( pBody->GetPrev() )
+                                    pBody->GetPrev()->Calc();
+                                pBody->Calc();
+                                SwTwips nBot = pBody->Frm().Top() + pBody->Prt().Bottom();
+                                if( rRect.Bottom() < nBot )
+                                    rRect.Bottom( nBot );
+                            }
+                        }
+                    }
+                    pUp = 0;
+                }
+            }
+            if ( pUp )
+            {
+                if ( !pUp->IsFlyFrm() ||
+                     (!pUp->Lower() || !pUp->Lower()->IsColumnFrm()) )
+                    pUp->Calc();
+                if ( pUp->GetType() & FRM_BODY )
+                {
+                    const SwPageFrm *pPg;
+                    if ( pUp->GetUpper() != (pPg = pFly->FindPageFrm()) )
+                        pUp = pPg->FindBodyCont();
+                    rRect = pUp->GetUpper()->Frm();
+                    rRect.Pos().Y() = pUp->Frm().Top() + pUp->Prt().Top();
+                    rRect.SSize().Height() = pUp->Prt().Height();
+                }
+                else
+                {
+                    if( ( pUp->GetType() & (FRM_FLY | FRM_FTN ) ) &&
+                        !pUp->Frm().IsInside( pFly->Frm().Pos() ) )
+                    {
+                        if( pUp->IsFlyFrm() )
+                        {
+                            SwFlyFrm *pTmpFly = (SwFlyFrm*)pUp;
+                            while( pTmpFly->GetNextLink() )
+                            {
+                                pTmpFly = pTmpFly->GetNextLink();
+                                if( pTmpFly->Frm().IsInside( pFly->Frm().Pos() ) )
+                                    break;
+                            }
+                            pUp = pTmpFly;
+                        }
+                        else if( pUp->IsInFtn() )
+                        {
+                            const SwFtnFrm *pTmp = pUp->FindFtnFrm();
+                            while( pTmp->GetFollow() )
+                            {
+                                pTmp = pTmp->GetFollow();
+                                if( pTmp->Frm().IsInside( pFly->Frm().Pos() ) )
+                                    break;
+                            }
+                            pUp = pTmp;
+                        }
+                    }
+                    rRect = pUp->Prt();
+                    rRect.Pos() += pUp->Frm().Pos();
+                    if ( pUp->GetType() & (FRM_HEADER | FRM_FOOTER) )
+                    {
+                        rRect.Left ( pUp->GetUpper()->Frm().Left() );
+                        rRect.Width( pUp->GetUpper()->Frm().Width());
+                    }
+                    else if ( pUp->IsCellFrm() )                //MA_FLY_HEIGHT
+                    {
+                        const SwFrm *pTab = pUp->FindTabFrm();
+                        long nBottom = pTab->GetUpper()->Frm().Top() +
+                                       pTab->GetUpper()->Prt().Bottom();
+                        rRect.Bottom( nBottom );
+                    }
+                }
+            }
+            if ( pCell )
+            {
+                //CellFrms koennen auch in 'unerlaubten' Bereichen stehen, dann
+                //darf der Fly das auch.
+                SwRect aTmp( pCell->Prt() );
+                aTmp += pCell->Frm().Pos();
+                rRect.Union( aTmp );
+            }
+        }
+        else
+        {
+            if( bMove )
+            {
+                const SwFmt *pFmt = ((SwContact*)GetUserCall(pSdrObj))
+                                        ->GetFmt();
+                const SvxULSpaceItem &rUL = pFmt->GetULSpace();
+                const SwRect &rTmp = pFly->Frm();
+                long nTmpH = rUL.GetLower() + rUL.GetUpper() + rTmp.Height();
+                rRect.Width( rTmp.Width() );
+                rRect.Height( rTmp.Height() + nTmpH - 1 );
+                rRect.Pos( ((SwFlyInCntFrm*)pFly)->GetRefPoint().X(),
+                    ((SwFlyInCntFrm*)pFly)->GetRefPoint().Y() - nTmpH + 1 );
+            }
+            else
+            {
+                //Sizeable ist er bis zur Grosse der PrtArea
+                // des Uppers seines Ankers.
+                const SwFrm *pUp = pFly->GetAnchor()->GetUpper();
+                pUp->Calc();
+                rRect  = pUp->Prt();
+                rRect += pUp->Frm().Pos();
+            }
+        }
+    }
+    else
+    {
+        const SwDrawContact *pC = (const SwDrawContact*)GetUserCall(pSdrObj);
+        const SwFrmFmt  *pFmt = (const SwFrmFmt*)pC->GetFmt();
+        const SwFmtAnchor &rAnch = pFmt->GetAnchor();
+        if ( FLY_IN_CNTNT == rAnch.GetAnchorId() )
+        {
+            if( bMove )
+            {
+                //Verschiebbar ist das Teil nur vertikal um seinen Ankerpunkt herum.
+                SwRect aSnapRect( pSdrObj->GetSnapRect() );
+                const SvxULSpaceItem &rUL = pFmt->GetULSpace();
+                long nTmpH = pSdrObj->GetBoundRect().GetHeight()+rUL.GetLower()+rUL.GetUpper();
+                rRect.Width( aSnapRect.Width() );
+                rRect.Height( aSnapRect.Height() + nTmpH - 1 );
+                rRect.Pos( pSdrObj->GetAnchorPos().X(),
+                           pSdrObj->GetAnchorPos().Y() - nTmpH + 1 );
+            }
+            else
+            {
+                //Sizeable ist er bis zur Grosse der PrtArea des Uppers
+                //seines Ankers.
+                const SwFrm *pFrm = pC->GetAnchor();
+                if( !pFrm )
+                {
+                    ((SwDrawContact*)pC)->ConnectToLayout();
+                    pFrm = pC->GetAnchor();
+                }
+                const SwFrm *pUp = pFrm->GetUpper();
+                pUp->Calc();
+                rRect = pUp->Prt();
+                rRect += pUp->Frm().Pos();
+            }
+        }
+        else
+            bRet = FALSE;
+    }
+    return bRet;
+}
+
+
diff --git a/sw/source/core/layout/flypos.cxx b/sw/source/core/layout/flypos.cxx
new file mode 100644
index 000000000000..90d0d4a38738
--- /dev/null
+++ b/sw/source/core/layout/flypos.cxx
@@ -0,0 +1,147 @@
+/*************************************************************************
+ *
+ *  $RCSfile: flypos.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:22 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "doc.hxx"
+#include "node.hxx"
+#ifndef _DOCARY_HXX
+#include 
+#endif
+
+
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#include "flypos.hxx"
+#include "frmfmt.hxx"
+#include "dcontact.hxx"
+#include "dview.hxx"
+#include "flyfrm.hxx"
+#include "dflyobj.hxx"
+#include "ndindex.hxx"
+
+
+
+SV_IMPL_OP_PTRARR_SORT( SwPosFlyFrms, SwPosFlyFrmPtr )
+
+SwPosFlyFrm::SwPosFlyFrm( const SwNodeIndex& rIdx, const SwFrmFmt* pFmt,
+                            USHORT nArrPos )
+    : pNdIdx( (SwNodeIndex*) &rIdx ), pFrmFmt( pFmt )
+{
+    BOOL bFnd = FALSE;
+    const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
+    if( FLY_PAGE == rAnchor.GetAnchorId() )
+        pNdIdx = new SwNodeIndex( rIdx );
+    else if( pFmt->GetDoc()->GetRootFrm() )
+    {
+        SwClientIter aIter( (SwFmt&)*pFmt );
+        if( RES_FLYFRMFMT == pFmt->Which() )
+        {
+            // Schauen, ob es ein SdrObject dafuer gibt
+            if( aIter.First( TYPE( SwFlyFrm) ) )
+                nOrdNum = ((SwFlyFrm*)aIter())->GetVirtDrawObj()->GetOrdNum(),
+                bFnd = TRUE;
+        }
+        else if( RES_DRAWFRMFMT == pFmt->Which() )
+        {
+            // Schauen, ob es ein SdrObject dafuer gibt
+            if( aIter.First( TYPE(SwDrawContact) ) )
+                nOrdNum = ((SwDrawContact*)aIter())->GetMaster()->GetOrdNum(),
+                bFnd = TRUE;
+        }
+    }
+
+    if( !bFnd )
+    {
+        nOrdNum = pFmt->GetDoc()->GetSpzFrmFmts()->Count();
+        nOrdNum += nArrPos;
+    }
+}
+
+SwPosFlyFrm::~SwPosFlyFrm()
+{
+    const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor();
+    if( FLY_PAGE == rAnchor.GetAnchorId() )
+        delete pNdIdx;
+}
+
+BOOL SwPosFlyFrm::operator==( const SwPosFlyFrm& rPosFly )
+{
+    return FALSE;   // FlyFrames koennen auf der gleichen Position stehen
+}
+
+BOOL SwPosFlyFrm::operator<( const SwPosFlyFrm& rPosFly )
+{
+    if( pNdIdx->GetIndex() == rPosFly.pNdIdx->GetIndex() )
+    {
+        // dann entscheidet die Ordnungsnummer!
+        return nOrdNum < rPosFly.nOrdNum;
+    }
+    return pNdIdx->GetIndex() < rPosFly.pNdIdx->GetIndex();
+}
+
+
+
diff --git a/sw/source/core/layout/frmtool.cxx b/sw/source/core/layout/frmtool.cxx
new file mode 100644
index 000000000000..ab849d1efcaf
--- /dev/null
+++ b/sw/source/core/layout/frmtool.cxx
@@ -0,0 +1,3171 @@
+/*************************************************************************
+ *
+ *  $RCSfile: frmtool.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:22 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#define ITEMID_BOXINFO      SID_ATTR_BORDER_INNER
+#define ITEMID_SIZE         SID_ATTR_PAGE_SIZE
+#include 
+
+
+#ifndef _BIGINT_HXX //autogen
+#include 
+#endif
+#ifndef _SVDMODEL_HXX //autogen
+#include 
+#endif
+#ifndef _SVDPAGE_HXX //autogen
+#include 
+#endif
+#ifndef _SFX_PROGRESS_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BRSHITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BRKITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_KEEPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_SIZEITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_SHADITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_ULSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BOXITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SFX_PRINTER_HXX //autogen
+#include 
+#endif
+
+
+#ifndef _FMTORNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _FMTPDSC_HXX //autogen
+#include 
+#endif
+#ifndef _FMTPDSC_HXX //autogen
+#include 
+#endif
+#ifndef _FMTPDSC_HXX //autogen
+#include 
+#endif
+#ifndef _FMTHDFT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTCNTNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFSIZE_HXX //autogen
+#include 
+#endif
+#ifndef _FMTCNCT_HXX //autogen
+#include 
+#endif
+#ifndef _DOCSTAT_HXX //autogen
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef SW_LINEINFO_HXX //autogen
+#include 
+#endif
+#ifndef _SWMODULE_HXX
+#include 
+#endif
+#include "rootfrm.hxx"
+#include "pagefrm.hxx"
+#include "cntfrm.hxx"
+#include "colfrm.hxx"
+#include "flyfrm.hxx"
+#include "doc.hxx"
+#include "fesh.hxx"
+#include "viewimp.hxx"
+#include "pam.hxx"
+#include "dflyobj.hxx"
+#include "dcontact.hxx"
+#include "frmtool.hxx"
+#include "docsh.hxx"
+#include "swtable.hxx"
+#include "errhdl.hxx"
+#include "tabfrm.hxx"
+#include "rowfrm.hxx"
+#include "ftnfrm.hxx"
+#include "txtfrm.hxx"
+#include "notxtfrm.hxx"
+#include "flyfrms.hxx"
+#include "frmsh.hxx"
+#include "layact.hxx"
+#include "pagedesc.hxx"
+#include "section.hxx"
+#include "sectfrm.hxx"
+#include "node2lay.hxx"
+#include "ndole.hxx"
+#include "ndtxt.hxx"
+
+#include "mdiexp.hxx"
+#include "statstr.hrc"
+
+// ftnfrm.cxx:
+void lcl_RemoveFtns( SwFtnBossFrm* pBoss, BOOL bPageOnly, BOOL bEndNotes );
+
+FASTBOOL bObjsDirect = TRUE;
+FASTBOOL bDontCreateObjects = FALSE;
+FASTBOOL bSetCompletePaintOnInvalidate = FALSE;
+
+BYTE StackHack::nCnt = 0;
+BOOL StackHack::bLocked = FALSE;
+
+/*************************************************************************
+|*
+|*  SwFrmNotify::SwFrmNotify()
+|*
+|*  Ersterstellung      MA 27. Nov. 92
+|*  Letzte Aenderung    MA 09. Apr. 97
+|*
+|*************************************************************************/
+
+SwFrmNotify::SwFrmNotify( SwFrm *pF ) :
+    pFrm( pF ),
+    aFrm( pF->Frm() ),
+    aPrt( pF->Prt() ),
+    bInvaKeep( FALSE )
+{
+    bHadFollow = pF->IsCntntFrm() ?
+                    (((SwCntntFrm*)pF)->GetFollow() ? TRUE : FALSE) :
+                    FALSE;
+}
+
+/*************************************************************************
+|*
+|*  SwFrmNotify::~SwFrmNotify()
+|*
+|*  Ersterstellung      MA 27. Nov. 92
+|*  Letzte Aenderung    MA 09. Apr. 97
+|*
+|*************************************************************************/
+
+SwFrmNotify::~SwFrmNotify()
+{
+    const FASTBOOL bAbsP = aFrm.Pos() != pFrm->Frm().Pos();
+
+    if ( pFrm->IsFlowFrm() && !pFrm->IsInFtn() )
+    {
+        SwFlowFrm *pFlow = SwFlowFrm::CastFlowFrm( pFrm );
+
+        if ( !pFlow->IsFollow() )
+        {
+            if ( !pFrm->GetIndPrev() )
+            {
+                if ( bInvaKeep )
+                {
+                    //Wenn der Vorgaenger das Attribut fuer Zusammenhalten traegt
+                    //muss er angestossen werden.
+                    SwFrm *pPre;
+                    if ( 0 != (pPre = pFrm->FindPrev()) &&
+                         pPre->GetAttrSet()->GetKeep().GetValue() )
+                        pPre->InvalidatePos();
+                }
+            }
+            else if ( !pFlow->HasFollow() &&
+                      (aFrm.Height() > pFrm->Frm().Height() ||
+                       (!aFrm.Height() && pFrm->Frm().Height()) ) )
+                pFlow->CheckKeep();
+        }
+    }
+
+    if ( bAbsP )
+    {
+        pFrm->SetCompletePaint();
+
+        SwFrm* pNxt = pFrm->GetIndNext();
+
+        if ( pNxt )
+            pNxt->InvalidatePos();
+        else
+        {
+            if( pFrm->IsRetoucheFrm() && aFrm.Pos().Y() > pFrm->Frm().Pos().Y() )
+                pFrm->SetRetouche();
+
+            //Wenn ein TxtFrm gerade einen Follow erzeugt hat, so ist dieser
+            //frisch formatiert und braucht nicht nocheinmal angestossen werden.
+            if ( bHadFollow || !pFrm->IsCntntFrm() ||
+                 !((SwCntntFrm*)pFrm)->GetFollow() )
+                pFrm->InvalidateNextPos();
+        }
+    }
+
+    //Fuer Hintergrundgrafiken muss bei Groessenaenderungen ein Repaint her.
+    const FASTBOOL bPrtS = aPrt.SSize()!= pFrm->Prt().SSize();
+    if ( bPrtS )
+    {
+        const SvxGraphicPosition ePos = pFrm->GetAttrSet()->GetBackground().GetGraphicPos();
+        if ( GPOS_NONE != ePos && GPOS_TILED != ePos )
+            pFrm->SetCompletePaint();
+    }
+
+    //Auch die Flys wollen etwas von den Veraenderungen mitbekommen,
+    //FlyInCnts brauchen hier nicht benachrichtigt werden.
+    if ( pFrm->GetDrawObjs() )
+    {
+        const FASTBOOL bPrtP = aPrt.Pos() != pFrm->Prt().Pos();
+        const FASTBOOL bFrmS = aFrm.SSize()!= pFrm->Frm().SSize();
+
+        if ( bAbsP || bPrtP || bFrmS || bPrtS )
+        {
+            const SwDrawObjs &rObjs = *pFrm->GetDrawObjs();
+            SwPageFrm *pPage = 0;
+            for ( USHORT i = 0; i < rObjs.Count(); ++i )
+            {
+                FASTBOOL bNotify = FALSE;
+                FASTBOOL bNotifySize = FALSE;
+                SdrObject *pObj = rObjs[i];
+                if ( pObj->IsWriterFlyFrame() )
+                {
+                    SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+                    if ( !pFly->IsFlyInCntFrm() )
+                    {
+                        //Wenn sich die AbsPos geaendert hat oder der Anker kein
+                        //CntntFrm ist, so benachrichten wir auf jeden Fall.
+                        if ( bAbsP || !pFly->GetAnchor()->IsCntntFrm() )
+                        {
+                            bNotify = TRUE;
+                            if ( bAbsP )
+                            {
+                                if ( !pPage )
+                                    pPage = pFrm->FindPageFrm();
+                                SwPageFrm *pFlyPage = pFly->FindPageFrm();
+                                // Am Rahmen gebundene Objekte wandern stets mit,
+                                // an TxtFrms gebundene nicht unbedingt.
+                                //MA 09. Jul. 98: An TxtFrms gebundene wurden
+                                //bereits im MakeAll formatiert und sollten
+                                //damit auf der richtigen Seite stehen.
+                                if ( pPage != pFlyPage && pFrm->IsFlyFrm() )
+//                                   (pFrm->IsFlyFrm() || pOldPage != pPage ||
+//                                    WEIT_WECH == pFly->Frm().Top()) )
+                                {
+                                    ASSERT( pFlyPage, "~SwFrmNotify: Fly from Nowhere" );
+                                    if( pFlyPage )
+                                        pFlyPage->MoveFly( pFly, pPage );
+                                    else
+                                        pPage->SwPageFrm::AppendFly( pFly );
+                                }
+                            }
+                        }
+                        else
+                        {
+                            //Andere benachrichtigen wir nur wenn sie eine
+                            //automatische Ausrichtung haben.
+                            //MA 16. Oct. 95: (fix:21063) Verfeinert.
+                            const SwFmtVertOrient &rVert =
+                                        pFly->GetFmt()->GetVertOrient();
+                            const SwFmtHoriOrient &rHori =
+                                        pFly->GetFmt()->GetHoriOrient();
+                            if ( (rVert.GetVertOrient()    == VERT_CENTER  ||
+                                  rVert.GetVertOrient()    == VERT_BOTTOM  ||
+                                  rVert.GetRelationOrient()== PRTAREA)  &&
+                                 (aFrm.Height() != pFrm->Frm().Height() ||
+                                  aPrt.Height() != pFrm->Prt().Height()) )
+                            {
+                                bNotify = TRUE;
+                            }
+                            if ( rHori.GetHoriOrient() != HORI_NONE &&
+                                 (aFrm.Width() != pFrm->Frm().Width() ||
+                                  aPrt.Width() != pFrm->Prt().Width()) )
+                            {
+                                bNotify = TRUE;
+                            }
+                        }
+                    }
+                    else if ( aPrt.Width() != pFrm->Prt().Width() )
+                    {
+                        bNotify = TRUE;
+                        bNotifySize = TRUE;
+                    }
+                    if ( bNotify )
+                    {
+                        if ( bNotifySize )
+                            pFly->_InvalidateSize();
+                        pFly->_InvalidatePos();
+                        pFly->_Invalidate();
+                    }
+                }
+                else if ( bAbsP )
+                {
+                    SwFrmFmt *pFrmFmt = FindFrmFmt( pObj );
+                    if( !pFrmFmt ||
+                        FLY_IN_CNTNT != pFrmFmt->GetAnchor().GetAnchorId() )
+                    {
+                        pObj->SetAnchorPos( pFrm->Frm().Pos() );
+                        ((SwDrawContact*)GetUserCall(pObj))->ChkPage();
+                    }
+                }
+            }
+        }
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwLayNotify::SwLayNotify()
+|*
+|*  Ersterstellung      MA 17. Nov. 92
+|*  Letzte Aenderung    MA 03. Jun. 93
+|*
+|*************************************************************************/
+
+
+SwLayNotify::SwLayNotify( SwLayoutFrm *pLayFrm ) :
+    SwFrmNotify( pLayFrm ),
+    nHeightOfst( 0 ),
+    nWidthOfst ( 0 ),
+    bLowersComplete( FALSE )
+{
+}
+
+/*************************************************************************
+|*
+|*  SwLayNotify::~SwLayNotify()
+|*
+|*  Ersterstellung      MA 17. Nov. 92
+|*  Letzte Aenderung    MA 13. Jun. 96
+|*
+|*************************************************************************/
+
+void MA_FASTCALL lcl_MoveDrawObjs( SwFrm *pLow, const Point &rDiff,
+                                   SwPageFrm *pNewPage )
+{
+    for ( USHORT i = 0; pLow->GetDrawObjs() && i < pLow->GetDrawObjs()->Count();
+            ++i )
+    {
+        SdrObject *pObj = (*pLow->GetDrawObjs())[i];
+        if ( pObj->IsWriterFlyFrame() )
+        {
+            SwFlyFrm *pF = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+            if ( pF->Frm().Left() != WEIT_WECH )
+            {
+                {//Scope fuer Notify
+                    SwFlyNotify aNotify( pF );
+                    pF->Frm().Pos() += rDiff;
+                    //Wenn ein Fly die Position wechselt muss er
+                    //natuerlich an der Seite umgemeldet werden.
+                    if ( pF->IsFlyFreeFrm() )
+                    {
+                        if ( aNotify.GetOldPage() != pNewPage )
+                            aNotify.GetOldPage()->MoveFly( pF, pNewPage );
+                    }
+                }
+            }
+        }
+        else
+        {
+            pObj->SetAnchorPos( pObj->GetAnchorPos() + rDiff );
+            ((SwDrawContact*)GetUserCall(pObj))->ChkPage();
+        }
+    }
+}
+
+void MA_FASTCALL lcl_MoveLowerFlys( SwLayoutFrm *pLay, const Point &rDiff,
+                                    SwPageFrm *pNewPage )
+{
+    if( pLay->IsFlyFrm() )
+        ::lcl_MoveDrawObjs( pLay, rDiff, pNewPage );
+
+    SwFrm *pLow = pLay->Lower();
+    if( !pLow )
+        return ;
+
+    do
+    {   if ( pLow->GetDrawObjs() )
+            ::lcl_MoveDrawObjs( pLow, rDiff, pNewPage );
+        pLow->Frm().Pos() += rDiff;
+        pLow->InvalidatePos();
+        if ( pLow->IsTxtFrm() )
+            ((SwTxtFrm*)pLow)->Prepare( PREP_POS_CHGD );
+        else if ( pLow->IsTabFrm() )
+            pLow->InvalidatePrt();
+        if ( pLow->IsLayoutFrm() )
+            ::lcl_MoveLowerFlys( (SwLayoutFrm*)pLow, rDiff, pNewPage );
+
+        pLow = pLow->GetNext();
+    } while ( pLow );
+}
+
+SwLayNotify::~SwLayNotify()
+{
+    SwLayoutFrm *pLay = GetLay();
+    FASTBOOL bNotify = FALSE;
+    if ( pLay->Prt().SSize() != aPrt.SSize() )
+    {
+        if ( !IsLowersComplete() )
+        {
+            BOOL bInvaPercent;
+
+            if ( pLay->IsRowFrm() )
+            {
+                bInvaPercent = TRUE;
+                if ( pLay->Prt().Height() != aPrt.Height() )
+                     ((SwRowFrm*)pLay)->AdjustCells( pLay->Prt().Height(),TRUE);
+                if ( pLay->Prt().Width() != aPrt.Width() )
+                     ((SwRowFrm*)pLay)->AdjustCells( 0, FALSE );
+            }
+            else
+            {
+                //Proportionale Anpassung der innenliegenden.
+                //1. Wenn der Formatierte kein Fly ist
+                //2. Wenn er keine Spalten enthaelt
+                //3. Wenn der Fly eine feste Hoehe hat und die Spalten in der
+                //   Hoehe danebenliegen.
+                //4. niemals bei SectionFrms.
+                BOOL bLow;
+                if( pLay->IsFlyFrm() )
+                {
+                    if ( pLay->Lower() )
+                    {
+                        bLow = !pLay->Lower()->IsColumnFrm() ||
+                            pLay->Lower()->Frm().Height() != pLay->Prt().Height();
+                    }
+                    else
+                        bLow = FALSE;
+                }
+                else if( pLay->IsSctFrm() )
+                {
+                    if ( pLay->Lower() )
+                    {
+                        if( pLay->Lower()->IsColumnFrm() && pLay->Lower()->GetNext() )
+                            bLow = pLay->Lower()->Frm().Height() != pLay->Prt().Height();
+                        else
+                            bLow = pLay->Prt().Width() != aPrt.Width();
+                    }
+                    else
+                        bLow = FALSE;
+                }
+                else
+                    bLow = TRUE;
+                bInvaPercent = bLow;
+                if ( bLow )
+                {
+                    if ( nHeightOfst || nWidthOfst )
+                    {
+                        const Size aSz( aPrt.Width()  + nWidthOfst,
+                                        aPrt.Height() + nHeightOfst );
+                        if ( pLay->Prt().SSize() != aSz )
+                            pLay->ChgLowersProp( aSz );
+                    }
+                    else
+                        pLay->ChgLowersProp( aPrt.SSize() );
+
+                }
+                //Wenn die PrtArea gewachsen ist, so ist es moeglich, dass die
+                //Kette der Untergeordneten einen weiteren Frm aufnehmen kann,
+                //mithin muss also der 'moeglicherweise passende' Invalidiert werden.
+                //Das invalidieren lohnt nur, wenn es sich beim mir bzw. meinen
+                //Uppers um eine Moveable-Section handelt.
+                //Die PrtArea ist gewachsen, wenn die Breite oder die Hoehe groesser
+                //geworden ist.
+                if ( (pLay->Prt().Height() > aPrt.Height() ||
+                      pLay->Prt().Width()  > aPrt.Width()) &&
+                     (pLay->IsMoveable() || pLay->IsFlyFrm()) )
+                {
+                    SwFrm *pFrm = pLay->Lower();
+                    if ( pFrm && pFrm->IsFlowFrm() )
+                    {
+                        while ( pFrm->GetNext() )
+                            pFrm = pFrm->GetNext();
+                        pFrm->InvalidateNextPos();
+                    }
+                }
+            }
+            bNotify = TRUE;
+            //TEUER!! aber wie macht man es geschickter?
+            if( bInvaPercent )
+                pLay->InvaPercentLowers();
+        }
+        if ( pLay->IsTabFrm() )
+            //Damit _nur_ der Shatten bei Groessenaenderungen gemalt wird.
+            ((SwTabFrm*)pLay)->SetComplete();
+        else if ( !pLay->GetFmt()->GetDoc()->IsBrowseMode() ||
+                  !(pLay->GetType() & (FRM_BODY | FRM_PAGE)) )
+            //Damit die untergeordneten sauber retouchiert werden.
+            //Problembsp: Flys an den Henkeln packen und verkleinern.
+            //Nicht fuer Body und Page, sonst flackerts beim HTML-Laden.
+            pLay->SetCompletePaint();
+
+    }
+    //Lower benachrichtigen wenn sich die Position veraendert hat.
+    const BOOL bPrtPos = pLay->Prt().Pos() != aPrt.Pos();
+    const BOOL bPos = bPrtPos || pLay->Frm().Pos() != aFrm.Pos();
+
+    if ( bPos && pLay->Lower() && !IsLowersComplete() )
+        pLay->Lower()->InvalidatePos();
+
+    if ( bPrtPos )
+        pLay->SetCompletePaint();
+
+    //Nachfolger benachrichtigen wenn sich die SSize geaendert hat.
+    if ( pLay->GetNext() && pLay->Frm().SSize() != aFrm.SSize() )
+    {
+        if ( pLay->GetNext()->IsLayoutFrm() )
+            pLay->GetNext()->_InvalidatePos();
+        else
+            pLay->GetNext()->InvalidatePos();
+    }
+    if ( !IsLowersComplete() &&
+         !((pLay->GetType()&FRM_FLY|FRM_SECTION) &&
+            pLay->Lower() && pLay->Lower()->IsColumnFrm()) &&
+         (bPos || bNotify) && !(pLay->GetType() & 0x1823) )  //Tab, Row, FtnCont, Root, Page
+    {
+        pLay->NotifyFlys();
+    }
+    if ( bPos && pLay->IsFtnFrm() && pLay->Lower() )
+    {
+        Point aDiff( pLay->Frm().Pos() );
+        aDiff -= aFrm.Pos();
+        lcl_MoveLowerFlys( pLay, aDiff, pLay->FindPageFrm() );
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFlyNotify::SwFlyNotify()
+|*
+|*  Ersterstellung      MA 17. Nov. 92
+|*  Letzte Aenderung    MA 26. Aug. 93
+|*
+|*************************************************************************/
+
+SwFlyNotify::SwFlyNotify( SwFlyFrm *pFlyFrm ) :
+    SwLayNotify( pFlyFrm ),
+    pOldPage( pFlyFrm->FindPageFrm() ),
+    aFrmAndSpace( pFlyFrm->AddSpacesToFrm() )
+{
+}
+
+/*************************************************************************
+|*
+|*  SwFlyNotify::~SwFlyNotify()
+|*
+|*  Ersterstellung      MA 17. Nov. 92
+|*  Letzte Aenderung    MA 09. Nov. 95
+|*
+|*************************************************************************/
+
+SwFlyNotify::~SwFlyNotify()
+{
+    SwFlyFrm *pFly = GetFly();
+    if ( pFly->IsNotifyBack() )
+    {
+        ViewShell *pSh = pFly->GetShell();
+        SwViewImp *pImp = pSh ? pSh->Imp() : 0;
+        if ( !pImp || !pImp->IsAction() || !pImp->GetLayAction().IsAgain() )
+        {
+            //Wenn in der LayAction das IsAgain gesetzt ist kann es sein,
+            //dass die alte Seite inzwischen vernichtet wurde!
+            ::Notify( pFly, pOldPage, aFrmAndSpace );
+        }
+        pFly->ResetNotifyBack();
+    }
+
+    //Haben sich Groesse oder Position geaendert, so sollte die View
+    //das wissen.
+    const FASTBOOL bPosChgd = pFly->Frm().Pos() != aFrm.Pos();
+    if ( bPosChgd || pFly->Frm().SSize() != aFrm.SSize() )
+    {
+        pFly->NotifyDrawObj();
+    }
+    if ( bPosChgd && aFrm.Pos().X() != WEIT_WECH )
+    {
+        //Bei Spalten sind die Lower wahrscheinlich bereits Formatiert und
+        //Positioniert. Bei zeichengebundenen Rahmen mit Spalten macht dies
+        //heftige Probleme #42867#
+        if ( pFly->Lower() &&
+             (!pFly->IsFlyInCntFrm() || !pFly->Lower()->IsColumnFrm()) )
+        {
+            Point aDiff( pFly->Frm().Pos() );
+            aDiff -= aFrm.Pos();
+            lcl_MoveLowerFlys( pFly, aDiff, pFly->FindPageFrm() );
+        }
+
+        if ( pFly->IsFlyAtCntFrm() )
+        {
+            SwFrm *pNxt = pFly->GetAnchor()->FindNext();
+            if ( pNxt )
+                pNxt->InvalidatePos();
+        }
+    }
+}
+/*************************************************************************
+|*
+|*  SwCntntNotify::SwCntntNotify()
+|*
+|*  Ersterstellung      MA 24. Nov. 92
+|*  Letzte Aenderung    MA 16. May. 95
+|*
+|*************************************************************************/
+
+SwCntntNotify::SwCntntNotify( SwCntntFrm *pCntntFrm ) :
+    SwFrmNotify( pCntntFrm )
+{
+}
+
+/*************************************************************************
+|*
+|*  SwCntntNotify::~SwCntntNotify()
+|*
+|*  Ersterstellung      MA 24. Nov. 92
+|*  Letzte Aenderung    MA 09. Apr. 97
+|*
+|*************************************************************************/
+
+SwCntntNotify::~SwCntntNotify()
+{
+    SwCntntFrm *pCnt = GetCnt();
+    if ( bSetCompletePaintOnInvalidate )
+        pCnt->SetCompletePaint();
+
+
+    //Wenn sich meine PrtArea in der Fix-Size geaendert hat, so muss mein
+    //Nachfolger dazu angeregt werden sich auch neu zu Formatieren.
+
+//MA: Ist das wirklich noetig? Auf keinen Fall sollte das doch notwendig sein,
+//wenn der Frm das erste Mal formatiert wurde (alte PrtArea == 0).
+/*  if ( pCnt->GetNext() &&
+         pCnt->Prt().Width() != aPrt.Width() )
+    {
+        pCnt->GetNext()->Prepare( PREP_FIXSIZE_CHG );
+        pCnt->GetNext()->_InvalidatePrt();
+        pCnt->GetNext()->InvalidateSize();
+    }
+*/
+    if ( pCnt->IsInTab() && (pCnt->Frm().Pos() != aFrm.Pos() ||
+                             pCnt->Frm().SSize() != aFrm.SSize()))
+    {
+        SwLayoutFrm* pCell = pCnt->GetUpper();
+        while( !pCell->IsCellFrm() && pCell->GetUpper() )
+            pCell = pCell->GetUpper();
+        ASSERT( pCell->IsCellFrm(), "Where's my cell?" );
+        if ( VERT_NONE != pCell->GetFmt()->GetVertOrient().GetVertOrient() )
+            pCell->InvalidatePrt(); //fuer vertikale Ausrichtung.
+    }
+
+    FASTBOOL bFirst = aFrm.Width() == 0 && aFrm.Height() == 0;
+
+    if ( pCnt->IsNoTxtFrm() )
+    {
+        //Aktive PlugIn's oder OLE-Objekte sollten etwas von der Veraenderung
+        //mitbekommen, damit sie Ihr Window entsprechend verschieben.
+        ViewShell *pSh  = pCnt->GetShell();
+        if ( pSh )
+        {
+            SwOLENode *pNd;
+            if ( 0 != (pNd = pCnt->GetNode()->GetOLENode()) &&
+                 (pNd->GetOLEObj().IsOleRef() ||
+                  pNd->IsOLESizeInvalid()) )
+            {
+                ASSERT( pCnt->IsInFly(), "OLE not in FlyFrm" );
+                SwFlyFrm *pFly = pCnt->FindFlyFrm();
+                SvEmbeddedObjectRef xObj( (SvInPlaceObject*) pNd->GetOLEObj().GetOleRef() );
+                SwFEShell *pFESh = 0;
+                ViewShell *pTmp = pSh;
+                do
+                {   if ( pTmp->ISA( SwCrsrShell ) )
+                    {
+                        pFESh = (SwFEShell*)pTmp;
+                        if ( !bFirst )
+                            pFESh->CalcAndSetScale( xObj, &pFly->Prt(), &pFly->Frm());
+                    }
+                    pTmp = (ViewShell*)pTmp->GetNext();
+                } while ( pTmp != pSh );
+
+                if ( pFESh && pNd->IsOLESizeInvalid() )
+                {
+                    pNd->SetOLESizeInvalid( FALSE );
+                    xObj->OnDocumentPrinterChanged( pNd->GetDoc()->GetPrt() );
+                    pFESh->CalcAndSetScale( xObj );//Client erzeugen lassen.
+                }
+            }
+            //dito Animierte Grafiken
+            if ( Frm().HasArea() && ((SwNoTxtFrm*)pCnt)->HasAnimation() )
+            {
+                ((SwNoTxtFrm*)pCnt)->StopAnimation();
+                pSh->InvalidateWindows( Frm() );
+            }
+        }
+    }
+
+    if ( bFirst )
+    {
+        pCnt->SetRetouche();    //fix(13870)
+
+        SwDoc *pDoc = pCnt->GetNode()->GetDoc();
+        if ( pDoc->GetSpzFrmFmts()->Count() &&
+             !pDoc->IsLoaded() && !pDoc->IsNewDoc() )
+        {
+            //Der Frm wurde wahrscheinlich zum ersten mal formatiert.
+            //Wenn ein Filter Flys oder Zeichenobjekte einliest und diese
+            //Seitengebunden sind, hat er ein Problem, weil er i.d.R. die
+            //Seitennummer nicht kennt. Er weiss lediglich welches der Inhalt
+            //(CntntNode) an dieser Stelle ist.
+            //Die Filter stellen dazu das Ankerattribut der Objekte so ein, dass
+            //sie vom Typ zwar Seitengebunden sind, aber der Index des Ankers
+            //auf diesen CntntNode zeigt.
+            //Hier werden diese vorlauefigen Verbindungen aufgeloest.
+
+            const SwPageFrm *pPage = 0;
+            SwNodeIndex   *pIdx  = 0;
+            SwSpzFrmFmts *pTbl = pDoc->GetSpzFrmFmts();
+
+            for ( USHORT i = 0; i < pTbl->Count(); ++i )
+            {
+                if ( !pPage )
+                    pPage = pCnt->FindPageFrm();
+                SwFrmFmt *pFmt = (*pTbl)[i];
+                const SwFmtAnchor &rAnch = pFmt->GetAnchor();
+
+                if ( FLY_PAGE       != rAnch.GetAnchorId() &&
+                     FLY_AT_CNTNT   != rAnch.GetAnchorId() )
+                    continue;   //#60878# nicht etwa zeichengebundene.
+
+                FASTBOOL bCheckPos = FALSE;
+                if ( rAnch.GetCntntAnchor() )
+                {
+                    if ( !pIdx )
+                    {
+                        pIdx = new SwNodeIndex( *pCnt->GetNode() );
+                    }
+                    if ( rAnch.GetCntntAnchor()->nNode == *pIdx )
+                    {
+                        bCheckPos = TRUE;
+                        if ( FLY_PAGE == rAnch.GetAnchorId() )
+                        {
+                            SwFmtAnchor aAnch( rAnch );
+                            aAnch.SetAnchor( 0 );
+                            aAnch.SetPageNum( pPage->GetPhyPageNum() );
+                            pFmt->SetAttr( aAnch );
+                            if ( RES_DRAWFRMFMT != pFmt->Which() )
+                                pFmt->MakeFrms();
+                        }
+                    }
+                }
+                if ( !bCheckPos || RES_DRAWFRMFMT != pFmt->Which() )
+                    continue;
+
+                SdrObject *pObj = pFmt->FindSdrObject();
+                const Point aAktPos( pObj->GetSnapRect().TopLeft() );
+                Point aPos( aAktPos );
+                FASTBOOL bSetPos = FALSE;
+                SwFmtVertOrient *pVert;
+                if ( SFX_ITEM_SET == pFmt->GetAttrSet().GetItemState(
+                            RES_VERT_ORIENT, FALSE, (const SfxPoolItem**)&pVert ) )
+                {
+                    bSetPos = TRUE;
+                    switch ( pVert->GetRelationOrient() )
+                    {
+                        case REL_PG_FRAME:      aPos.Y() = pPage->Frm().Top(); break;
+                        case REL_PG_PRTAREA:    aPos.Y() = pPage->Frm().Top();
+                                                aPos.Y() += pPage->Prt().Top(); break;
+                        case FRAME:             aPos.Y() = pCnt->Frm().Top(); break;
+                        default:
+                            bSetPos = FALSE;
+                            ASSERT( !this,"neuer Trick vom WW Reader?" );
+                    }
+                    aPos.Y() += pVert->GetPos();
+                    pFmt->ResetAttr( RES_VERT_ORIENT );
+                }
+                SwFmtHoriOrient *pHori;
+                if ( SFX_ITEM_SET == pFmt->GetAttrSet().GetItemState(
+                            RES_HORI_ORIENT, FALSE, (const SfxPoolItem**)&pHori ) )
+                {
+                    bSetPos = TRUE;
+                    switch ( pHori->GetRelationOrient() )
+                    {
+                        case REL_PG_FRAME:      aPos.X() = pPage->Frm().Left(); break;
+                        case REL_PG_PRTAREA:    aPos.X() = pPage->Frm().Left();
+                                                aPos.X() += pPage->Prt().Left();    break;
+
+                        case FRAME:
+                            // da es fuer den WW95/97 Import ist und die
+                            // Horizontal nur Spalten kennen, muss hier die
+                            // Spalte gesucht werden. Wenn es keine gibt,
+                            // ist es die PrtArea der Seite.
+                            {
+                                SwFrm* pColFrm = pCnt->FindColFrm();
+                                if( pColFrm )
+                                    aPos.X() = pColFrm->Frm().Left() +
+                                               pColFrm->Prt().Left();
+                                else
+                                    aPos.X() = pPage->Frm().Left() +
+                                               pPage->Prt().Left();
+                            }
+                            break;
+                        default:
+                            bSetPos = FALSE;
+                            ASSERT( !this,"neuer Trick vom WW Reader?" );
+                    }
+                    aPos.X() += pHori->GetPos();
+                    pFmt->ResetAttr( RES_HORI_ORIENT );
+                }
+                if ( bSetPos )
+                {
+                    aPos -= aAktPos;
+                    pObj->Move( Size( aPos.X(), aPos.Y() ) );
+                }
+            }
+            delete pIdx;
+        }
+    }
+}
+
+/*************************************************************************
+|*
+|*  InsertCnt
+|*
+|*  Beschreibung        Hilfsfunktionen, die friend von irgendwem sind, damit
+|*                      nicht immer gleich 'ne ganze Klasse befreundet werden
+|*                      muss.
+|*  Ersterstellung      MA 13. Apr. 93
+|*  Letzte Aenderung    MA 11. May. 95
+|*
+|*************************************************************************/
+
+void AppendObjs( const SwSpzFrmFmts *pTbl, ULONG nIndex,
+                        SwFrm *pFrm, SwPageFrm *pPage )
+{
+    for ( USHORT i = 0; i < pTbl->Count(); ++i )
+    {
+        SwFrmFmt *pFmt = (SwFrmFmt*)(*pTbl)[i];
+        const SwFmtAnchor &rAnch = pFmt->GetAnchor();
+        if ( rAnch.GetCntntAnchor() &&
+             (rAnch.GetCntntAnchor()->nNode.GetIndex() == nIndex) )
+        {
+            BOOL bFlyAtFly = rAnch.GetAnchorId() == FLY_AT_FLY; // LAYER_IMPL
+
+            if( bFlyAtFly || rAnch.GetAnchorId() == FLY_AT_CNTNT ||
+                rAnch.GetAnchorId() == FLY_AUTO_CNTNT )
+            {
+                //Wird ein Rahmen oder ein SdrObject beschrieben?
+                const BOOL bSdrObj = RES_DRAWFRMFMT == pFmt->Which();
+                SdrObject *pSdrObj = 0;
+                if ( bSdrObj  && 0 == (pSdrObj = pFmt->FindSdrObject()) )
+                {
+                    ASSERT( !bSdrObj, "DrawObject not found." );
+                    pFmt->GetDoc()->DelFrmFmt( pFmt );
+                    --i;
+                    continue;
+                }
+                if ( pSdrObj )
+                {
+                    if ( !pSdrObj->GetPage() )
+                        pFmt->GetDoc()->GetDrawModel()->GetPage(0)->
+                                InsertObject(pSdrObj, pSdrObj->GetOrdNumDirect());
+                    pFrm->AppendDrawObj((SwDrawContact*)GetUserCall(pSdrObj) );
+                }
+                else
+                {
+                    SwFlyFrm *pFly;
+                    if( bFlyAtFly )
+                        pFly = new SwFlyLayFrm( (SwFlyFrmFmt*)pFmt, pFrm );
+                    else
+                        pFly = new SwFlyAtCntFrm( (SwFlyFrmFmt*)pFmt, pFrm );
+                    pFly->Lock();
+                    pFrm->AppendFly( pFly );
+                    pFly->Unlock();
+                    if ( pPage )
+                        ::RegistFlys( pPage, pFly );
+                }
+            }
+        }
+    }
+}
+
+FASTBOOL MA_FASTCALL lcl_ObjConnected( SwFrmFmt *pFmt )
+{
+    SwClientIter aIter( *pFmt );
+    if ( RES_FLYFRMFMT == pFmt->Which() )
+        return 0 != aIter.First( TYPE(SwFlyFrm) );
+    else
+    {
+        SwDrawContact *pContact;
+        if ( 0 != (pContact = (SwDrawContact*)aIter.First( TYPE(SwDrawContact))))
+            return pContact->GetAnchor() != 0;
+    }
+    return FALSE;
+}
+
+void AppendAllObjs( const SwSpzFrmFmts *pTbl )
+{
+    //Verbinden aller Objekte, die in der SpzTbl beschrieben sind mit dem
+    //Layout.
+    //Wenn sich nix mehr tut hoeren wir auf. Dann koennen noch Formate
+    //uebrigbleiben, weil wir weder zeichengebunde Rahmen verbinden noch
+    //Objecte die in zeichengebundenen verankert sind.
+
+    SwSpzFrmFmts aCpy( 255, 255 );
+    aCpy.Insert( pTbl, 0 );
+
+    USHORT nOldCnt = USHRT_MAX;
+
+    while ( aCpy.Count() && aCpy.Count() != nOldCnt )
+    {
+        nOldCnt = aCpy.Count();
+        for ( int i = 0; i < int(aCpy.Count()); ++i )
+        {
+            SwFrmFmt *pFmt = (SwFrmFmt*)aCpy[ USHORT(i) ];
+            const SwFmtAnchor &rAnch = pFmt->GetAnchor();
+            FASTBOOL bRemove = FALSE;
+            if ( rAnch.GetAnchorId() == FLY_PAGE || rAnch.GetAnchorId() == FLY_IN_CNTNT )
+                //Seitengebunde sind bereits verankert, zeichengebundene
+                //will ich hier nicht.
+                bRemove = TRUE;
+            else if ( FALSE == (bRemove = ::lcl_ObjConnected( pFmt )) )
+            {
+                //Fuer Flys und DrawObjs nur dann ein MakeFrms rufen wenn noch
+                //keine abhaengigen Existieren, andernfalls, oder wenn das
+                //MakeFrms keine abhaengigen erzeugt, entfernen.
+                pFmt->MakeFrms();
+                bRemove = ::lcl_ObjConnected( pFmt );
+            }
+            if ( bRemove )
+            {
+                aCpy.Remove( USHORT(i) );
+                --i;
+            }
+        }
+    }
+    aCpy.Remove( 0, aCpy.Count() );
+}
+
+BOOL MA_FASTCALL lcl_CheckInsertPage( SwFrm *pFrm, SwPageFrm *&rpPage,
+                                      SwLayoutFrm *&rpLay,
+                                      ULONG nParagraphCnt,
+                                      USHORT nMaxParaPerPage, BOOL &rbBreakAfter )
+{
+    FASTBOOL bEnd = 0 == rpPage->GetNext();
+    const SwAttrSet *pAttr = pFrm->GetAttrSet();
+    const SvxFmtBreakItem &rBrk = pAttr->GetBreak();
+    const SwFmtPageDesc &rDesc = pAttr->GetPageDesc();
+    const SwPageDesc *pDesc = rDesc.GetPageDesc();
+
+    BOOL bBrk = nParagraphCnt > nMaxParaPerPage || rbBreakAfter;
+    rbBreakAfter = rBrk.GetBreak() == SVX_BREAK_PAGE_AFTER ||
+                   rBrk.GetBreak() == SVX_BREAK_PAGE_BOTH;
+    if ( !bBrk )
+        bBrk = rBrk.GetBreak() == SVX_BREAK_PAGE_BEFORE ||
+               rBrk.GetBreak() == SVX_BREAK_PAGE_BOTH;
+
+    if ( bBrk || pDesc )
+    {
+        USHORT nPgNum = 0;
+        if ( !pDesc )
+            pDesc = rpPage->GetPageDesc()->GetFollow();
+        else
+        {
+            if ( 0 != (nPgNum = rDesc.GetNumOffset()) )
+                ((SwRootFrm*)rpPage->GetUpper())->SetVirtPageNum(TRUE);
+        }
+        if ( !nPgNum )
+            nPgNum = rpPage->GetVirtPageNum();
+        BOOL bOdd = nPgNum % 2 ? FALSE : TRUE;
+        ::InsertNewPage( (SwPageDesc&)*pDesc, rpPage->GetUpper(),
+                         bOdd, FALSE, rpPage->GetNext() );
+        if ( bEnd )
+        {
+            ASSERT( rpPage->GetNext(), "Keine neue Seite?" );
+            do
+            {   rpPage = (SwPageFrm*)rpPage->GetNext();
+            } while ( rpPage->GetNext() );
+        }
+        else
+        {
+            ASSERT( rpPage->GetNext(), "Keine neue Seite?" );
+            rpPage = (SwPageFrm*)rpPage->GetNext();
+            if ( rpPage->IsEmptyPage() )
+            {
+                ASSERT( rpPage->GetNext(), "Keine neue Seite?" );
+                rpPage = (SwPageFrm*)rpPage->GetNext();
+            }
+        }
+        rpLay = rpPage->FindBodyCont();
+        while( rpLay->Lower() )
+            rpLay = (SwLayoutFrm*)rpLay->Lower();
+        return TRUE;
+    }
+    return FALSE;
+}
+
+//Solange eine Section "offen" ist ist im InsertCnt ein Pointer auf die
+//Hilfsklasse SwActualSection vorhanden.
+//Bei Seitenumbruchen wird fuer "offene" Sections entsprechend ein Follow
+//erzeugt.
+//Da Bereiche ineinander verschachtelt sein koennen, sich aber wiederum im
+//Layout nicht ineinander verschachteln, hat die Klasse eine Pointer auf ihren
+//Upper wenn eine "innere" Section notwendig ist. Wenn diese abgeschlossen ist
+//wird einfach wieder der "Upper" weiterverwendet (im Layout muss dafuer
+//natuerlich wieder ein entsprechender Frame erzeugt werden.
+
+//!!Nicht fuer im Layout verschachtelte Bereiche funktionsfaehig.
+
+class SwActualSection
+{
+    SwActualSection *pUpper;
+    SwSectionFrm    *pSectFrm;
+    SwSectionNode   *pSectNode;
+public:
+    SwActualSection( SwActualSection *pUpper,
+                     SwSectionFrm    *pSect,
+                     SwSectionNode   *pNd );
+
+    SwSectionFrm    *GetSectionFrm()                    { return pSectFrm; }
+    void             SetSectionFrm( SwSectionFrm *p )   { pSectFrm = p; }
+    SwSectionNode   *GetSectionNode()                   { return pSectNode;}
+    SwActualSection *GetUpper()                         { return pUpper; }
+};
+
+SwActualSection::SwActualSection( SwActualSection *pUp,
+                                  SwSectionFrm    *pSect,
+                                  SwSectionNode   *pNd ) :
+    pUpper( pUp ),
+    pSectFrm( pSect ),
+    pSectNode( pNd )
+{
+    if ( !pSectNode )
+    {
+        const SwNodeIndex *pIndex = pSect->GetFmt()->GetCntnt().GetCntntIdx();
+        pSectNode = pSect->GetFmt()->GetDoc()->GetNodes()[*pIndex]->
+                                                            FindSectionNode();
+    }
+}
+
+void MA_FASTCALL _InsertCnt( SwLayoutFrm *pLay, SwDoc *pDoc,
+                             ULONG nIndex, BOOL bPages, ULONG nEndIndex,
+                             SwFrm *pPrv )
+{
+    const BOOL bOldIdle = pDoc->IsIdleTimerActive();
+    pDoc->StopIdleTimer();
+    const BOOL bOldCallbackActionEnabled = pDoc->GetRootFrm()->IsCallbackActionEnabled();
+    pDoc->GetRootFrm()->SetCallbackActionEnabled( FALSE );
+
+    //Bei der Erzeugung des Layouts wird bPages mit TRUE uebergeben. Dann
+    //werden schon mal alle x Absaetze neue Seiten angelegt. Bei umbruechen
+    //und/oder Pagedescriptorwechseln werden gleich die entsprechenden Seiten
+    //angelegt.
+    //Vorteil ist, das einerseits schon eine annaehernd realistische Zahl von
+    //Seiten angelegt wird, vor allem aber gibt es nicht mehr eine schier
+    //lange Kette von Absaetzen teuer verschoben werden muss, bis sie sich auf
+    //ertraegliches mass reduziert hat.
+    //Wir gehen mal davon aus, daá 20 Absaetze auf eine Seite passen
+    //Damit es in extremen Faellen nicht gar so heftig rechenen wir je nach
+    //Node noch etwas drauf.
+    //Wenn in der DocStatistik eine brauchebare Seitenzahl angegeben ist
+    //(wird beim Schreiben gepflegt), so wird von dieser Seitenanzahl
+    //ausgegengen.
+    ULONG nMaxParaPerPage = 25;
+    ULONG nPgCount;
+    BOOL bStartPercent = bPages && !nEndIndex &&
+                                   !SfxProgress::GetActiveProgress() &&
+                                   !SfxProgress::GetActiveProgress( pDoc->GetDocShell() );
+    if ( bStartPercent )
+    {
+        nPgCount = pDoc->GetDocStat().nPage;
+        if ( nPgCount <= 10 ) //darunter machen wir es nicht.
+            nPgCount = 0;
+        ULONG nNdCount = pDoc->GetDocStat().nPara;
+        if ( nNdCount <= 1 )
+        {
+            //Anzahl der Absaetze schaetzen.
+            ULONG nTmp = pDoc->GetNodes().GetEndOfContent().GetIndex() -
+                        pDoc->GetNodes().GetEndOfExtras().GetIndex();
+            //Fuer Die Tabellen ziehen wir einiges wg. der Start-/EndNodes ab.
+            nTmp -= pDoc->GetTblFrmFmts()->Count() * 25;
+            //Fuer die Rahmen ziehen auch nocheinmal etwa 5 Absaetze ab.
+            nTmp -= (pDoc->GetNodes().GetEndOfAutotext().GetIndex() -
+                       pDoc->GetNodes().GetEndOfInserts().GetIndex()) / 3 * 5;
+            if ( nTmp > 0 )
+                nNdCount = nTmp;
+        }
+        if ( nNdCount < 1000 )
+            bStartPercent = FALSE;
+        if ( nNdCount > 100 ) //darunter machen wir es nicht
+        {
+            if ( nPgCount > 0 )
+                nMaxParaPerPage = nNdCount / nPgCount;
+            else
+            {
+                nMaxParaPerPage = Max( ULONG(20),
+                                       ULONG(20 + nNdCount / 1000 * 3) );
+                //Standard ASCII-Leerzeilen
+#ifdef PM2
+                const ULONG nMax = 49;
+#elif MAC
+                const ULONG nMax = 56;
+#elif UNIX
+                const ULONG nMax = 57;
+#else
+                const ULONG nMax = 53;
+#endif
+                nMaxParaPerPage = Min( nMaxParaPerPage, nMax );
+                nPgCount = nNdCount / nMaxParaPerPage;
+            }
+            if ( pDoc->IsBrowseMode() )
+                nMaxParaPerPage *= 6;
+        }
+    }
+
+    //Wenn das Layout erzeugt wird (bPages == TRUE) steuern wir den Progress
+    //an. Flys und DrawObjekte werden dann nicht gleich verbunden, dies
+    //passiert erst am Ende der Funktion.
+    if ( bPages && bStartPercent )
+    {
+        ::StartProgress( STR_STATSTR_LAYOUTINIT, 1, nPgCount, pDoc->GetDocShell());
+        bObjsDirect = FALSE;
+    }
+
+    SwPageFrm *pPage = pLay->FindPageFrm();
+    const SwSpzFrmFmts *pTbl = pDoc->GetSpzFrmFmts();
+    SwFrm       *pFrm = 0;
+    USHORT nParagraphCnt = 0;
+    BOOL   bBreakAfter   = FALSE;
+    BOOL   bFirst = TRUE;
+
+    SwActualSection *pActualSection = 0;    //Siehe Dokumentation oben bei der
+    if( pLay->IsInSct() &&                  //Klassendefinition
+        ( pLay->IsSctFrm() || pLay->GetUpper() ) ) // Hierdurch werden Frischlinge
+            // abgefangen, deren Flags noch nicht ermittelt werden koennen,
+            // so z.B. beim Einfuegen einer Tabelle
+    {
+        SwSectionFrm* pSct = pLay->FindSctFrm();
+        // Wenn Inhalt in eine Fussnote eingefuegt wird, die in einem spaltigen
+        // Bereich liegt, so darf der spaltige Bereich nicht aufgebrochen werden.
+        // Nur wenn im Innern der Fussnote ein Bereich liegt, ist dies ein
+        // Kandidat fuer pActualSection.
+        // Gleiches gilt fuer Bereiche in Tabellen, wenn innerhalb einer Tabelle
+        // eingefuegt wird, duerfen nur Bereiche, die ebenfalls im Innern liegen,
+        // aufgebrochen werden.
+        if( ( !pLay->IsInFtn() || pSct->IsInFtn() ) &&
+            ( !pLay->IsInTab() || pSct->IsInTab() ) )
+        {
+            pActualSection = new SwActualSection( 0, pSct, 0 );
+            ASSERT( !pLay->Lower() || !pLay->Lower()->IsColumnFrm(),
+                "_InsertCnt: Wrong Call" );
+        }
+    }
+
+    while( TRUE )
+    {
+        SwNode *pNd = pDoc->GetNodes()[nIndex];
+        if ( pNd->IsCntntNode() )
+        {
+            SwCntntNode* pNode = (SwCntntNode*)pNd;
+            pFrm = pNode->IsTxtNode() ? new SwTxtFrm( (SwTxtNode*)pNode ) :
+                                        pNode->MakeFrm();
+            if ( bPages )
+            {
+                ++nParagraphCnt;
+                if ( !bFirst || nEndIndex )
+                {
+                    if ( bFirst )
+                        nParagraphCnt = USHRT_MAX;
+
+                    if ( lcl_CheckInsertPage( pFrm, pPage, pLay, nParagraphCnt,
+                                              nMaxParaPerPage, bBreakAfter ) )
+                    {
+                        pPrv = 0;
+                        nParagraphCnt = 0;
+                        if ( bPages && bStartPercent )
+                            ::SetProgressState( pPage->GetPhyPageNum(), pDoc->GetDocShell());
+
+                        if ( pActualSection )
+                        {
+                            //Hatte der SectionFrm ueberhaupt Inhalt? Wenn
+                            //nicht kann er gleich umgehaengt werden.
+                            SwFrm *pFrm;
+                            if ( !pActualSection->GetSectionFrm()->ContainsCntnt())
+                            {
+                                pFrm = pActualSection->GetSectionFrm();
+                                pFrm->Remove();
+                            }
+                            else
+                            {
+                                pFrm = new SwSectionFrm(
+                                    *pActualSection->GetSectionFrm(), FALSE );
+                                pActualSection->GetSectionFrm()->SimpleFormat();
+                                pFrm->Frm().Width( pLay->Prt().Width() );
+                                pFrm->Prt().Width( pLay->Prt().Width() );
+                            }
+                            pActualSection->SetSectionFrm( (SwSectionFrm*)pFrm );
+                            pFrm->InsertBehind( pLay, 0 );
+                            pFrm->Frm().Pos() = pLay->Frm().Pos();
+                            pFrm->Frm().Pos().Y() += 1; //wg. Benachrichtigungen.
+
+                            pLay = (SwLayoutFrm*)pFrm;
+                            if ( pLay->Lower() && pLay->Lower()->IsLayoutFrm() )
+                                pLay = pLay->GetNextLayoutLeaf();
+                        }
+                    }
+                }
+                bFirst = FALSE;
+            }
+            pFrm->InsertBehind( pLay, pPrv );
+            pFrm->Frm().Pos() = pLay->Frm().Pos();
+            pFrm->Frm().Pos().Y() += 1; //wg. Benachrichtigungen.
+            pPrv = pFrm;
+
+            if ( pTbl->Count() && bObjsDirect && !bDontCreateObjects )
+                AppendObjs( pTbl, nIndex, pFrm, pPage );
+        }
+        else if ( pNd->IsTableNode() )
+        {   //Sollten wir auf eine Tabelle gestossen sein?
+            SwTableNode *pTblNode = (SwTableNode*)pNd;
+            pFrm = pTblNode->MakeFrm();
+
+            if ( bPages )
+            {
+                //Fuer die Seiten zaehlt jede Zeile als ein Absatz.
+                SwFrm *pLow = ((SwTabFrm*)pFrm)->Lower();
+                do
+                {   ++nParagraphCnt;
+                    pLow = pLow->GetNext();
+                } while ( pLow );
+
+                if ( !bFirst || nEndIndex )
+                {
+                    if ( bFirst )
+                        nParagraphCnt = USHRT_MAX;
+
+                    if ( lcl_CheckInsertPage( pFrm, pPage, pLay, nParagraphCnt,
+                                                nMaxParaPerPage, bBreakAfter ) )
+                    {
+                        pPrv = 0;
+                        nParagraphCnt = 0;
+                        if ( bPages && bStartPercent )
+                            ::SetProgressState( pPage->GetPhyPageNum(), pDoc->GetDocShell());
+
+                        if ( pActualSection )
+                        {
+                            //Hatte der SectionFrm ueberhaupt Inhalt? Wenn
+                            //nicht kann er gleich umgehaengt werden.
+                            SwFrm *pFrm;
+                            if ( !pActualSection->GetSectionFrm()->ContainsCntnt())
+                            {
+                                pFrm = pActualSection->GetSectionFrm();
+                                pFrm->Remove();
+                            }
+                            else
+                            {
+                                pFrm = new SwSectionFrm(
+                                    *pActualSection->GetSectionFrm(), FALSE );
+                                pActualSection->GetSectionFrm()->SimpleFormat();
+                                pFrm->Frm().Width( pLay->Prt().Width() );
+                                pFrm->Prt().Width( pLay->Prt().Width() );
+                            }
+                            pActualSection->SetSectionFrm( (SwSectionFrm*)pFrm );
+                            pFrm->InsertBehind( pLay, 0 );
+                            pFrm->Frm().Pos() = pLay->Frm().Pos();
+                            pFrm->Frm().Pos().Y() += 1; //wg. Benachrichtigungen.
+
+                            pLay = (SwLayoutFrm*)pFrm;
+                            if ( pLay->Lower() && pLay->Lower()->IsLayoutFrm() )
+                                pLay = pLay->GetNextLayoutLeaf();
+                        }
+                    }
+                }
+            }
+
+            pFrm->InsertBehind( pLay, pPrv );
+            if ( bObjsDirect && pTbl->Count() )
+                ((SwTabFrm*)pFrm)->RegistFlys();
+            pFrm->Frm().Pos() = pLay->Frm().Pos();
+            pFrm->Frm().Pos().Y() += 1; //wg. Benachrichtigungen.
+            pPrv = pFrm;
+            //Index auf den Endnode der Tabellensection setzen.
+            nIndex = pTblNode->EndOfSectionIndex();
+        }
+        else if ( pNd->IsSectionNode() )
+        {
+            SwSectionNode *pNode = (SwSectionNode*)pNd;
+            if( pNode->GetSection().CalcHiddenFlag() )
+                // ist versteckt, ueberspringe den Bereich
+                nIndex = pNode->EndOfSectionIndex();
+            else
+            {
+                pFrm = pNode->MakeFrm();
+                pActualSection = new SwActualSection( pActualSection,
+                                                (SwSectionFrm*)pFrm, pNode );
+                if ( pActualSection->GetUpper() )
+                {
+                    //Hinter den Upper einsetzen, beim EndNode wird der "Follow"
+                    //des Uppers erzeugt.
+                    SwSectionFrm *pTmp = pActualSection->GetUpper()->GetSectionFrm();
+                    pFrm->InsertBehind( pTmp->GetUpper(), pTmp );
+                }
+                else
+                {
+                    pFrm->InsertBehind( pLay, pPrv );
+                    if( pPrv && pPrv->IsInFtn() )
+                    {
+                        if( pPrv->IsSctFrm() )
+                            pPrv = ((SwSectionFrm*)pPrv)->ContainsCntnt();
+                        if( pPrv && pPrv->IsTxtFrm() )
+                            ((SwTxtFrm*)pPrv)->Prepare( PREP_QUOVADIS, 0, FALSE );
+                    }
+                }
+                pFrm->Frm().Pos() = pLay->Frm().Pos();
+                pFrm->Frm().Pos().Y() += 1; //wg. Benachrichtigungen.
+
+                pLay = (SwLayoutFrm*)pFrm;
+                if ( pLay->Lower() && pLay->Lower()->IsLayoutFrm() )
+                    pLay = pLay->GetNextLayoutLeaf();
+                pPrv = 0;
+            }
+        }
+        else if ( pNd->IsEndNode() && pNd->FindStartNode()->IsSectionNode() )
+        {
+            ASSERT( pActualSection, "Sectionende ohne Anfang?" );
+            ASSERT( pActualSection->GetSectionNode() == pNd->FindStartNode(),
+                            "Sectionende mit falschen Start Node?" );
+
+            //Section schliessen, ggf. die umgebende Section wieder
+            //aktivieren.
+            SwActualSection *pTmp = pActualSection->GetUpper();
+            delete pActualSection;
+            pLay = pLay->FindSctFrm();
+            if ( 0 != (pActualSection = pTmp) )
+            {
+                //Koennte noch sein, das der letzte SectionFrm leer geblieben
+                //ist. Dann ist es jetzt an der Zeit ihn zu entfernen.
+                if ( !pLay->ContainsCntnt() )
+                {
+                    SwFrm *pTmp = pLay;
+                    pLay = pTmp->GetUpper();
+                    pPrv = pTmp->GetPrev();
+                    pTmp->Remove();
+                    delete pTmp;
+                }
+                else
+                {
+                    pPrv = pLay;
+                    pLay = pLay->GetUpper();
+                }
+                // Wenn der umgebende Bereich bereits einen Follow besitzt,
+                // wird dieser benutzt. Es muss allerdings die Master/Follow-
+                // verkettung geloest werden, unterbrochenene SectionFrms sind
+                // _nicht_ durch Master/Follow verbunden.
+                pFrm = pActualSection->GetSectionFrm()->GetFollow();
+                if( pFrm )
+                {
+                    ((SwSectionFrm*)pFrm)->_SetIsFollow( FALSE );
+                    pActualSection->GetSectionFrm()->SetFollow( NULL );
+                    pActualSection->GetSectionFrm()->InvalidateSize();
+                }
+                else
+                {
+                    pFrm = pActualSection->GetSectionNode()->MakeFrm();
+                    pFrm->InsertBehind( pLay, pPrv );
+                    pFrm->Frm().Pos() = pLay->Frm().Pos();
+                    pFrm->Frm().Pos().Y() += 1; //wg. Benachrichtigungen.
+                }
+                SwSectionFrm* pSectFrm = pActualSection->GetSectionFrm();
+                // Wir wollen keine leeren Teile zuruecklassen
+                if( !pSectFrm->IsColLocked() && !pSectFrm->ContainsCntnt() )
+                {
+                    pSectFrm->DelEmpty( TRUE );
+                    delete pSectFrm;
+                }
+                pActualSection->SetSectionFrm( (SwSectionFrm*)pFrm );
+
+                pLay = (SwLayoutFrm*)pFrm;
+                if ( pLay->Lower() && pLay->Lower()->IsLayoutFrm() )
+                    pLay = pLay->GetNextLayoutLeaf();
+                pPrv = 0;
+            }
+            else
+            {
+                //Nix mehr mit Sections, es geht direkt hinter dem SectionFrame
+                //weiter.
+                pPrv = pLay;
+                pLay = pLay->GetUpper();
+            }
+        }
+        else if( pNd->IsStartNode() &&
+                 SwFlyStartNode == ((SwStartNode*)pNd)->GetStartNodeType() )
+        {
+            if ( pTbl->Count() && bObjsDirect && !bDontCreateObjects )
+            {
+                SwFlyFrm* pFly = pLay->FindFlyFrm();
+                if( pFly )
+                    AppendObjs( pTbl, nIndex, pFly, pPage );
+            }
+        }
+        else
+            // Weder Cntnt noch Tabelle noch Section,
+            // also muessen wir fertig sein.
+            break;
+
+        ++nIndex;
+        // Der Endnode wird nicht mehr mitgenommen, es muss vom
+        // Aufrufenden (Section/MakeFrms()) sichergestellt sein, dass das Ende
+        // des Bereichs vor dem EndIndex liegt!
+        if ( nEndIndex && nIndex >= nEndIndex )
+            break;
+    }
+
+    if ( pActualSection )
+    {
+        //Kann passieren, dass noch eine leere (Follow-)Section uebrig geblieben ist.
+        if ( !(pLay = pActualSection->GetSectionFrm())->ContainsCntnt() )
+        {
+            pLay->Remove();
+            delete pLay;
+        }
+        delete pActualSection;
+    }
+
+    if ( bPages )       //Jetzt noch die Flys verbinden lassen.
+    {
+        if ( !bDontCreateObjects )
+            AppendAllObjs( pTbl );
+        bObjsDirect = TRUE;
+        if ( bStartPercent )
+            ::EndProgress( pDoc->GetDocShell() );
+    }
+
+    if ( bOldIdle )
+        pDoc->StartIdleTimer();
+    pDoc->GetRootFrm()->SetCallbackActionEnabled( bOldCallbackActionEnabled );
+}
+
+void MakeFrms( SwDoc *pDoc, const SwNodeIndex &rSttIdx,
+               const SwNodeIndex &rEndIdx )
+{
+    bObjsDirect = FALSE;
+
+    SwNodeIndex aTmp( rSttIdx );
+    ULONG nEndIdx = rEndIdx.GetIndex();
+    SwNode *pNd = pDoc->GetNodes().FindPrvNxtFrmNode( aTmp,
+                                            pDoc->GetNodes()[ nEndIdx-1 ]);
+    if ( pNd )
+    {
+        BOOL bApres = aTmp < rSttIdx;
+        SwNode2Layout aNode2Layout( *pNd, rSttIdx.GetIndex() );
+        SwFrm* pFrm;
+        while( 0 != (pFrm = aNode2Layout.NextFrm()) )
+        {
+            //Fuer klare Verhaeltnisse sorgen. Wenn ein Prev da ist
+            //alle Nachfolger von diesem auf die folgenden Seite
+            //schieben
+            SwLayoutFrm *pUpper = pFrm->GetUpper();
+            SwFtnFrm* pFtnFrm = pUpper->FindFtnFrm();
+            BOOL bOldLock, bOldFtn;
+            if( pFtnFrm )
+            {
+                bOldFtn = pFtnFrm->IsColLocked();
+                pFtnFrm->ColLock();
+            }
+            else
+                bOldFtn = TRUE;
+            SwSectionFrm* pSct = pUpper->FindSctFrm();
+            // Es sind innerhalb von Fussnoten nur die Bereiche interessant,
+            // die in den Fussnoten liegen, nicht etwa die (spaltigen) Bereiche,
+            // in denen die Fussnoten(Container) liegen.
+            if( pSct && pFtnFrm && !pSct->IsInFtn() )
+                pSct = NULL;
+            if( pSct )
+            {   // damit der SectionFrm nicht zerstoert wird durch pTmp->MoveFwd()
+                bOldLock = pSct->IsColLocked();
+                pSct->ColLock();
+            }
+            else
+                bOldLock = TRUE;
+            // Wenn pFrm sich nicht bewegen kann, koennen wir auch niemanden
+            // auf die naechste Seite schieben. Innerhalb eines Rahmens auch
+            // nicht ( in der 1. Spalte eines Rahmens waere pFrm Moveable()! )
+            // Auch in spaltigen Bereichen in Tabellen waere pFrm Moveable.
+            if ( !pFrm->IsInFly() && pFrm->IsMoveable() &&
+                 (!pFrm->IsInTab() || pFrm->IsTabFrm() ) )
+            {
+                SwFrm *pMove = pFrm;
+                SwFrm *pPrev = pFrm->GetPrev();
+                SwFlowFrm *pTmp = SwFlowFrm::CastFlowFrm( pMove );
+                ASSERT( pTmp, "Missing FlowFrm" );
+
+                if ( bApres )
+                {
+                    // Wir wollen, dass der Rest der Seite leer ist, d.h.
+                    // der naechste muss auf die naechste Seite wandern.
+                    // Dieser kann auch in der naechsten Spalte stehen!
+                    ASSERT( !pTmp->HasFollow(), "Follows forbidden" );
+                    pPrev = pFrm;
+                    // Wenn unser umgebender SectionFrm einen Next besitzt,
+                    // so soll dieser ebenfalls gemoved werden!
+                    pMove = pFrm->GetIndNext();
+                    SwColumnFrm* pCol = (SwColumnFrm*)pFrm->FindColFrm();
+                    if( pCol )
+                        pCol = (SwColumnFrm*)pCol->GetNext();
+                    do
+                    {
+                        if( pCol && !pMove )
+                        {   // Bisher haben wir keinen Nachfolger gefunden
+                            // jetzt gucken wir in die naechste Spalte
+                            pMove = pCol->ContainsAny();
+                            if( pCol->GetNext() )
+                                pCol = (SwColumnFrm*)pCol->GetNext();
+                            else if( pCol->IsInSct() )
+                            {   // Wenn es keine naechste Spalte gibt, wir aber
+                                // innerhalb eines spaltigen Bereichs sind,
+                                // koennte es noch ausserhalb des Bereich
+                                // (Seiten-)Spalten geben
+                                pCol = (SwColumnFrm*)pCol->FindSctFrm()->FindColFrm();
+                                if( pCol )
+                                    pCol = (SwColumnFrm*)pCol->GetNext();
+                            }
+                            else
+                                pCol = NULL;
+                        }
+                        // Falls hier verschrottete SectionFrms herumgammeln,
+                        // muessen diese uebersprungen werden.
+                        while( pMove && pMove->IsSctFrm() &&
+                               !((SwSectionFrm*)pMove)->GetSection() )
+                            pMove = pMove->GetNext();
+                    } while( !pMove && pCol );
+
+                    if( pMove )
+                    {
+                        if ( pMove->IsCntntFrm() )
+                            pTmp = (SwCntntFrm*)pMove;
+                        else if ( pMove->IsTabFrm() )
+                            pTmp = (SwTabFrm*)pMove;
+                        else if ( pMove->IsSctFrm() )
+                        {
+                            pMove = ((SwSectionFrm*)pMove)->ContainsAny();
+                            if( pMove )
+                                pTmp = SwFlowFrm::CastFlowFrm( pMove );
+                            else
+                                pTmp = NULL;
+                        }
+                    }
+                    else
+                        pTmp = 0;
+                }
+                else
+                {
+                    ASSERT( !pTmp->IsFollow(), "Follows really forbidden" );
+                    // Bei Bereichen muss natuerlich der Inhalt auf die Reise
+                    // geschickt werden.
+                    if( pMove->IsSctFrm() )
+                    {
+                        while( pMove && pMove->IsSctFrm() &&
+                               !((SwSectionFrm*)pMove)->GetSection() )
+                            pMove = pMove->GetNext();
+                        if( pMove && pMove->IsSctFrm() )
+                            pMove = ((SwSectionFrm*)pMove)->ContainsAny();
+                        if( pMove )
+                            pTmp = SwFlowFrm::CastFlowFrm( pMove );
+                        else
+                            pTmp = NULL;
+                    }
+                }
+
+                if( pTmp )
+                {
+                    SwFrm* pOldUp = pTmp->GetFrm()->GetUpper();
+                    // MoveFwd==TRUE bedeutet, dass wir auf der gleichen
+                    // Seite geblieben sind, wir wollen aber die Seite wechseln,
+                    // sofern dies moeglich ist
+                    BOOL bOldLock = pTmp->IsJoinLocked();
+                    pTmp->LockJoin();
+                    while( pTmp->MoveFwd( TRUE, FALSE, TRUE ) )
+                    {
+                        if( pOldUp == pTmp->GetFrm()->GetUpper() )
+                            break;
+                        pOldUp = pTmp->GetFrm()->GetUpper();
+                    }
+                    if( !bOldLock )
+                        pTmp->UnlockJoin();
+                }
+                ::_InsertCnt( pUpper, pDoc, rSttIdx.GetIndex(),
+                              pFrm->IsInDocBody(), nEndIdx, pPrev );
+            }
+            else
+            {
+                BOOL bSplit;
+                SwFrm* pPrv = bApres ? pFrm : pFrm->GetPrev();
+                // Wenn in einen SectionFrm ein anderer eingefuegt wird,
+                // muss dieser aufgebrochen werden
+                if( pSct && rSttIdx.GetNode().IsSectionNode() )
+                {
+                    bSplit = pSct->SplitSect( pFrm, bApres );
+                    // Wenn pSct nicht aufgespalten werden konnte
+                    if( !bSplit && !bApres )
+                    {
+                        pUpper = pSct->GetUpper();
+                        pPrv = pSct->GetPrev();
+                    }
+                }
+                else
+                    bSplit = FALSE;
+                ::_InsertCnt( pUpper, pDoc, rSttIdx.GetIndex(), FALSE, nEndIdx,
+                              pPrv );
+                // Wenn nichts eingefuegt wurde, z.B. ein ausgeblendeter Bereich,
+                // muss das Splitten rueckgaengig gemacht werden
+                if( bSplit && pSct && pSct->GetNext()
+                    && pSct->GetNext()->IsSctFrm() )
+                    pSct->MergeNext( (SwSectionFrm*)pSct->GetNext() );
+                if( pFrm->IsInFly() )
+                    pFrm->FindFlyFrm()->_Invalidate();
+                if( pFrm->IsInTab() )
+                    pFrm->InvalidateSize();
+            }
+
+            SwPageFrm *pPage = pUpper->FindPageFrm();
+            SwFrm::CheckPageDescs( pPage, FALSE );
+            if( !bOldFtn )
+                pFtnFrm->ColUnlock();
+            if( !bOldLock )
+            {
+                pSct->ColUnlock();
+                // Zum Beispiel beim Einfuegen von gelinkten Bereichen,
+                // die wiederum Bereiche enthalten, kann pSct jetzt leer sein
+                // und damit ruhig zerstoert werden.
+                if( !pSct->ContainsCntnt() )
+                {
+                    pSct->DelEmpty( TRUE );
+                    pDoc->GetRootFrm()->RemoveFromList( pSct );
+                    delete pSct;
+                }
+            }
+        }
+    }
+
+    bObjsDirect = TRUE;
+}
+
+/*************************************************************************
+|*
+|*  SwBorderAttrs::Ctor, DTor
+|*
+|*  Ersterstellung      MA 19. May. 93
+|*  Letzte Aenderung    MA 25. Jan. 97
+|*
+|*************************************************************************/
+
+SwBorderAttrs::SwBorderAttrs( const SwModify *pMod, const SwFrm *pConstructor ) :
+    SwCacheObj( pMod ),
+    rAttrSet( pConstructor->IsCntntFrm()
+                    ? ((SwCntntFrm*)pConstructor)->GetNode()->GetSwAttrSet()
+                    : ((SwLayoutFrm*)pConstructor)->GetFmt()->GetAttrSet() ),
+    rUL     ( rAttrSet.GetULSpace() ),
+    rLR     ( rAttrSet.GetLRSpace() ),
+    rBox    ( rAttrSet.GetBox()     ),
+    rShadow ( rAttrSet.GetShadow()  ),
+    aFrmSize( rAttrSet.GetFrmSize().GetSize() )
+{
+    //Achtung: Die USHORTs fuer die gecache'ten Werte werden absichtlich
+    //nicht initialisiert!
+
+    //Muessen alle einmal berechnet werden:
+    bTopLine = bBottomLine = bLeftLine = bRightLine =
+    bTop     = bBottom     = bRight     = bLine  = TRUE;
+
+    bCacheGetLine = bCachedGetTopLine = bCachedGetBottomLine = FALSE;
+
+    bBorderDist = 0 != (pConstructor->GetType() & (FRM_CELL));
+}
+
+SwBorderAttrs::~SwBorderAttrs()
+{
+    ((SwModify*)pOwner)->SetInCache( FALSE );
+}
+
+/*************************************************************************
+|*
+|*  SwBorderAttrs::CalcTop(), CalcBottom(), CalcLeft(), CalcRight()
+|*
+|*  Beschreibung        Die Calc-Methoden errechnen zusaetzlich zu den
+|*      von den Attributen vorgegebenen Groessen einen Sicherheitsabstand.
+|*      der Sicherheitsabstand wird nur einkalkuliert, wenn Umrandung und/oder
+|*      Schatten im Spiel sind; er soll vermeiden, dass aufgrund der
+|*      groben physikalischen Gegebenheiten Raender usw. uebermalt werden.
+|*  Ersterstellung      MA 19. May. 93
+|*  Letzte Aenderung    MA 08. Jul. 93
+|*
+|*************************************************************************/
+
+void SwBorderAttrs::_CalcTop()
+{
+    nTop = CalcTopLine() + rUL.GetUpper();
+    bTop = FALSE;
+}
+
+void SwBorderAttrs::_CalcBottom()
+{
+    nBottom = CalcBottomLine() + rUL.GetLower();
+    bBottom = FALSE;
+}
+
+long SwBorderAttrs::CalcLeft( const SwFrm *pCaller ) const
+{
+    long nLeft = rLR.GetLeft() + CalcLeftLine();
+#ifdef NUM_RELSPACE
+    if ( pCaller->IsTxtFrm() )
+        nLeft += ((SwTxtFrm*)pCaller)->GetTxtNode()->GetLeftMarginWithNum();
+#endif
+    return nLeft;
+}
+
+void SwBorderAttrs::_CalcRight()
+{
+    nRight = CalcRightLine() + rLR.GetRight();
+    bRight = FALSE;
+}
+
+/*************************************************************************
+|*
+|*  SwBorderAttrs::CalcTopLine(), CalcBottomLine(),
+|*                 CalcLeftLine(), CalcRightLine()
+|*
+|*  Beschreibung        Berechnung der Groessen fuer Umrandung und Schatten.
+|*                      Es kann auch ohne Linien ein Abstand erwuenscht sein,
+|*                      dieser wird  dann nicht vom Attribut sondern hier
+|*                      beruecksichtigt (bBorderDist, z.B. fuer Zellen).
+|*  Ersterstellung      MA 21. May. 93
+|*  Letzte Aenderung    MA 07. Jun. 99
+|*
+|*************************************************************************/
+
+void SwBorderAttrs::_CalcTopLine()
+{
+    nTopLine = (bBorderDist && !rBox.GetTop())
+                            ? rBox.GetDistance  (BOX_LINE_TOP)
+                            : rBox.CalcLineSpace(BOX_LINE_TOP);
+    nTopLine += rShadow.CalcShadowSpace(SHADOW_TOP);
+    bTopLine = FALSE;
+}
+
+void SwBorderAttrs::_CalcBottomLine()
+{
+    nBottomLine = (bBorderDist && !rBox.GetBottom())
+                            ? rBox.GetDistance  (BOX_LINE_BOTTOM)
+                            : rBox.CalcLineSpace(BOX_LINE_BOTTOM);
+    nBottomLine += rShadow.CalcShadowSpace(SHADOW_BOTTOM);
+    bBottomLine = FALSE;
+}
+
+void SwBorderAttrs::_CalcLeftLine()
+{
+    nLeftLine = (bBorderDist && !rBox.GetLeft())
+                            ? rBox.GetDistance  (BOX_LINE_LEFT)
+                            : rBox.CalcLineSpace(BOX_LINE_LEFT);
+    nLeftLine += rShadow.CalcShadowSpace(SHADOW_LEFT);
+    bLeftLine = FALSE;
+}
+
+void SwBorderAttrs::_CalcRightLine()
+{
+    nRightLine = (bBorderDist && !rBox.GetRight())
+                            ? rBox.GetDistance  (BOX_LINE_RIGHT)
+                            : rBox.CalcLineSpace(BOX_LINE_RIGHT);
+    nRightLine += rShadow.CalcShadowSpace(SHADOW_RIGHT);
+    bRightLine = FALSE;
+}
+
+/*************************************************************************
+|*
+|*  SwBorderAttrs::_IsLine()
+|*
+|*  Ersterstellung      MA 29. Sep. 94
+|*  Letzte Aenderung    MA 29. Sep. 94
+|*
+|*************************************************************************/
+
+void SwBorderAttrs::_IsLine()
+{
+    bIsLine = rBox.GetTop() || rBox.GetBottom() ||
+              rBox.GetLeft()|| rBox.GetRight();
+    bLine = FALSE;
+}
+
+/*************************************************************************
+|*
+|*  SwBorderAttrs::CmpLeftRightLine(), IsTopLine(), IsBottomLine()
+|*
+|*      Die Umrandungen benachbarter Absaetze werden nach folgendem
+|*      Algorithmus zusammengefasst:
+|*
+|*      1. Die Umrandung oben faellt weg, wenn der Vorgaenger dieselbe
+|*         Umrandung oben aufweist und 3. Zutrifft.
+|*         Zusaetzlich muss der Absatz mindestens rechts oder links oder
+|*         unten eine Umrandung haben.
+|*      2. Die Umrandung unten faellt weg, wenn der Nachfolger dieselbe
+|*         Umrandung untern aufweist und 3. Zustrifft.
+|*         Zusaetzlich muss der Absatz mindestens rechts oder links oder
+|*         oben eine Umrandung haben.
+|*      3. Die Umrandungen links und rechts vor Vorgaenger bzw. Nachfolger
+|*         sind identisch.
+|*
+|*  Ersterstellung      MA 22. Mar. 95
+|*  Letzte Aenderung    MA 22. May. 95
+|*
+|*************************************************************************/
+inline int CmpLines( const SvxBorderLine *pL1, const SvxBorderLine *pL2 )
+{
+    return ( ((pL1 && pL2) && (*pL1 == *pL2)) || (!pL1 && !pL2) );
+}
+
+BOOL SwBorderAttrs::CmpLeftRight( const SwBorderAttrs &rAttrs,
+                                  const SwFrm *pCaller,
+                                  const SwFrm *pCmp ) const
+{
+    return ( CmpLines( rAttrs.GetBox().GetLeft(), GetBox().GetLeft()  ) &&
+             CmpLines( rAttrs.GetBox().GetRight(),GetBox().GetRight() ) &&
+             CalcLeft( pCaller ) == rAttrs.CalcLeft( pCmp ) &&  //Bereucksichtigt TxtFrms ueber den Node
+             rLR.GetRight() == rAttrs.GetLRSpace().GetRight() );
+}
+
+void SwBorderAttrs::_GetTopLine( const SwFrm *pFrm )
+{
+    USHORT nRet = CalcTopLine();
+    if ( nRet && pFrm->GetPrev() && pFrm->IsCntntFrm() && pFrm->GetPrev()->IsCntntFrm() )
+    {
+        SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFrm->GetPrev() );
+        const SwBorderAttrs &rAttrs = *aAccess.Get();
+        if ( nRet == rAttrs.CalcTopLine() )
+        {
+            if ( (GetBox().GetLeft() || GetBox().GetRight() || GetBox().GetBottom()) &&
+                 rAttrs.GetShadow() == rShadow   &&
+                 CmpLines( rAttrs.GetBox().GetTop(), rBox.GetTop() ) &&
+                 CmpLeftRight( rAttrs, pFrm, pFrm->GetPrev() ) )
+            {
+                nRet = 0;
+            }
+        }
+    }
+    if ( bCacheGetLine )
+        bCachedGetTopLine = TRUE;
+
+    nGetTopLine = nRet;
+}
+
+void SwBorderAttrs::_GetBottomLine( const SwFrm *pFrm )
+{
+    USHORT nRet = CalcBottomLine();
+    if ( nRet && pFrm->GetNext() && pFrm->IsCntntFrm() && pFrm->GetNext()->IsCntntFrm() )
+    {
+        SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFrm->GetNext() );
+        const SwBorderAttrs &rAttrs = *aAccess.Get();
+        if ( nRet == rAttrs.CalcBottomLine() )
+        {
+            if ( (GetBox().GetLeft() || GetBox().GetRight() || GetBox().GetTop()) &&
+                 rAttrs.GetShadow() == rShadow   &&
+                 CmpLines( rAttrs.GetBox().GetBottom(), rBox.GetBottom() ) &&
+                 CmpLeftRight( rAttrs, pFrm, pFrm->GetNext() ) )
+            {
+                nRet = 0;
+            }
+        }
+    }
+    if ( bCacheGetLine )
+        bCachedGetBottomLine = TRUE;
+
+    nGetBottomLine = nRet;
+}
+
+/*************************************************************************
+|*
+|*  SwBorderAttrAccess::CTor
+|*
+|*  Ersterstellung      MA 20. Mar. 95
+|*  Letzte Aenderung    MA 29. Nov. 95
+|*
+|*************************************************************************/
+
+SwBorderAttrAccess::SwBorderAttrAccess( SwCache &rCache, const SwFrm *pFrm ) :
+    SwCacheAccess( rCache, (pFrm->IsCntntFrm() ?
+                                (void*)((SwCntntFrm*)pFrm)->GetNode() :
+                                (void*)((SwLayoutFrm*)pFrm)->GetFmt()),
+                           (BOOL)(pFrm->IsCntntFrm() ?
+                (BOOL)((SwModify*)((SwCntntFrm*)pFrm)->GetNode())->IsInCache() :
+                (BOOL)((SwModify*)((SwLayoutFrm*)pFrm)->GetFmt())->IsInCache()) ),
+    pConstructor( pFrm )
+{
+}
+
+/*************************************************************************
+|*
+|*  SwBorderAttrAccess::NewObj, Get
+|*
+|*  Ersterstellung      MA 20. Mar. 95
+|*  Letzte Aenderung    MA 20. Mar. 95
+|*
+|*************************************************************************/
+
+SwCacheObj *SwBorderAttrAccess::NewObj()
+{
+    ((SwModify*)pOwner)->SetInCache( TRUE );
+    return new SwBorderAttrs( (SwModify*)pOwner, pConstructor );
+}
+
+SwBorderAttrs *SwBorderAttrAccess::Get()
+{
+    return (SwBorderAttrs*)SwCacheAccess::Get();
+}
+
+/*************************************************************************
+|*
+|*  SwOrderIter::Ctor
+|*
+|*  Ersterstellung      MA 06. Jan. 95
+|*  Letzte Aenderung    MA 22. Nov. 95
+|*
+|*************************************************************************/
+
+SwOrderIter::SwOrderIter( const SwPageFrm *pPg, FASTBOOL bFlys ) :
+    pPage( pPg ),
+    pCurrent( 0 ),
+    bFlysOnly( bFlys )
+{
+}
+
+/*************************************************************************
+|*
+|*  SwOrderIter::Top()
+|*
+|*  Ersterstellung      MA 06. Jan. 95
+|*  Letzte Aenderung    MA 22. Nov. 95
+|*
+|*************************************************************************/
+
+const SdrObject *SwOrderIter::Top()
+{
+    pCurrent = 0;
+    if ( pPage->GetSortedObjs() )
+    {
+        UINT32 nTopOrd = 0;
+        const SwSortDrawObjs *pObjs = pPage->GetSortedObjs();
+        if ( pObjs->Count() )
+        {
+            (*pObjs)[0]->GetOrdNum();   //Aktualisieren erzwingen!
+            for ( USHORT i = 0; i < pObjs->Count(); ++i )
+            {
+                const SdrObject *pObj = (*pObjs)[i];
+                if ( bFlysOnly && !pObj->IsWriterFlyFrame() )
+                    continue;
+                UINT32 nTmp = pObj->GetOrdNumDirect();
+                if ( nTmp >= nTopOrd )
+                {
+                    nTopOrd = nTmp;
+                    pCurrent = pObj;
+                }
+            }
+        }
+    }
+    return pCurrent;
+}
+
+/*************************************************************************
+|*
+|*  SwOrderIter::Bottom()
+|*
+|*  Ersterstellung      MA 06. Jan. 95
+|*  Letzte Aenderung    MA 22. Nov. 95
+|*
+|*************************************************************************/
+
+const SdrObject *SwOrderIter::Bottom()
+{
+    pCurrent = 0;
+    if ( pPage->GetSortedObjs() )
+    {
+        UINT32 nBotOrd = USHRT_MAX;
+        const SwSortDrawObjs *pObjs = pPage->GetSortedObjs();
+        if ( pObjs->Count() )
+        {
+            (*pObjs)[0]->GetOrdNum();   //Aktualisieren erzwingen!
+            for ( USHORT i = 0; i < pObjs->Count(); ++i )
+            {
+                SdrObject *pObj = (*pObjs)[i];
+                if ( bFlysOnly && !pObj->IsWriterFlyFrame() )
+                    continue;
+                UINT32 nTmp = pObj->GetOrdNumDirect();
+                if ( nTmp < nBotOrd )
+                {
+                    nBotOrd = nTmp;
+                    pCurrent = pObj;
+                }
+            }
+        }
+    }
+    return pCurrent;
+}
+
+/*************************************************************************
+|*
+|*  SwOrderIter::Next()
+|*
+|*  Ersterstellung      MA 06. Jan. 95
+|*  Letzte Aenderung    MA 22. Nov. 95
+|*
+|*************************************************************************/
+
+const SdrObject *SwOrderIter::Next()
+{
+    const UINT32 nCurOrd = pCurrent ? pCurrent->GetOrdNumDirect() : 0;
+    pCurrent = 0;
+    if ( pPage->GetSortedObjs() )
+    {
+        UINT32 nOrd = USHRT_MAX;
+        const SwSortDrawObjs *pObjs = pPage->GetSortedObjs();
+        if ( pObjs->Count() )
+        {
+            (*pObjs)[0]->GetOrdNum();   //Aktualisieren erzwingen!
+            for ( USHORT i = 0; i < pObjs->Count(); ++i )
+            {
+                SdrObject *pObj = (*pObjs)[i];
+                if ( bFlysOnly && !pObj->IsWriterFlyFrame() )
+                    continue;
+                UINT32 nTmp = pObj->GetOrdNumDirect();
+                if ( nTmp > nCurOrd && nTmp < nOrd )
+                {
+                    nOrd = nTmp;
+                    pCurrent = pObj;
+                }
+            }
+        }
+    }
+    return pCurrent;
+}
+
+/*************************************************************************
+|*
+|*  SwOrderIter::Prev()
+|*
+|*  Ersterstellung      MA 06. Jan. 95
+|*  Letzte Aenderung    MA 22. Nov. 95
+|*
+|*************************************************************************/
+
+const SdrObject *SwOrderIter::Prev()
+{
+    const UINT32 nCurOrd = pCurrent ? pCurrent->GetOrdNumDirect() : 0;
+    pCurrent = 0;
+    if ( pPage->GetSortedObjs() )
+    {
+        UINT32 nOrd = 0;
+        const SwSortDrawObjs *pObjs = pPage->GetSortedObjs();
+        if ( pObjs->Count() )
+        {
+            (*pObjs)[0]->GetOrdNum();   //Aktualisieren erzwingen!
+            for ( USHORT i = 0; i < pObjs->Count(); ++i )
+            {
+                SdrObject *pObj = (*pObjs)[i];
+                if ( bFlysOnly && !pObj->IsWriterFlyFrame() )
+                    continue;
+                UINT32 nTmp = pObj->GetOrdNumDirect();
+                if ( nTmp < nCurOrd && nTmp >= nOrd )
+                {
+                    nOrd = nTmp;
+                    pCurrent = pObj;
+                }
+            }
+        }
+    }
+    return pCurrent;
+}
+
+/*************************************************************************
+|*
+|*  SaveCntnt(), RestoreCntnt()
+|*
+|*  Ersterstellung      MA 10. Jun. 93
+|*  Letzte Aenderung    MA 07. Mar. 95
+|*
+|*************************************************************************/
+
+//Unterstruktur eines LayoutFrms fuer eine Aktion aufheben und wieder
+//restaurieren.
+//Neuer Algorithmus: Es ist unuetz jeden Nachbarn einzeln zu betrachten und
+//die Pointer sauber zu setzen (Upper, Nachbarn, usw.)
+//Es reicht vollkommen jeweils eine Einzelkette zu loesen, und mit dem
+//Letzen der Einzelkette nachzuschauen ob noch eine weitere Kette
+//angeheangt werden muss. Es brauchen nur die Pointer korrigiert werden,
+//die zur Verkettung notwendig sind. So koennen Beipspielsweise die Pointer
+//auf die Upper auf den alten Uppern stehenbleiben. Korrigiert werden die
+//Pointer dann im RestoreCntnt. Zwischenzeitlich ist sowieso jeder Zugriff
+//verboten.
+//Unterwegs werden die Flys bei der Seite abgemeldet.
+
+void MA_FASTCALL lcl_RemoveFlysFromPage( SwCntntFrm *pCntnt )
+{
+    ASSERT( pCntnt->GetDrawObjs(), "Keine DrawObjs fuer lcl_RemoveFlysFromPage." );
+    SwDrawObjs &rObjs = *pCntnt->GetDrawObjs();
+    for ( USHORT i = 0; i < rObjs.Count(); ++i )
+    {
+        SdrObject *pO = rObjs[i];
+        SwVirtFlyDrawObj *pObj = pO->IsWriterFlyFrame() ?
+                                                        (SwVirtFlyDrawObj*)pO : 0;
+        if ( pObj && pObj->GetFlyFrm()->IsFlyFreeFrm() )
+        {
+            SwCntntFrm *pCnt = pObj->GetFlyFrm()->ContainsCntnt();
+            while ( pCnt )
+            {
+                if ( pCnt->GetDrawObjs() )
+                    ::lcl_RemoveFlysFromPage( pCnt );
+                pCnt = pCnt->GetNextCntntFrm();
+            }
+            ((SwFlyFreeFrm*)pObj->GetFlyFrm())->GetPage()->
+                    SwPageFrm::RemoveFly( pObj->GetFlyFrm() );
+        }
+    }
+}
+
+SwFrm *SaveCntnt( SwLayoutFrm *pLay, SwFrm *pStart )
+{
+    if( pLay->IsSctFrm() && pLay->Lower() && pLay->Lower()->IsColumnFrm() )
+        lcl_RemoveFtns( (SwColumnFrm*)pLay->Lower(), TRUE, TRUE );
+
+    SwFrm *pSav;
+    if ( 0 == (pSav = pLay->ContainsAny()) )
+        return 0;
+
+    if( pSav->IsInFtn() && !pLay->IsInFtn() )
+    {
+        do
+            pSav = pSav->FindNext();
+        while( pSav && pSav->IsInFtn() );
+        if( !pSav || !pLay->IsAnLower( pSav ) )
+            return NULL;
+    }
+    // Tabellen sollen immer komplett gesichert werden, es sei denn, es wird
+    // der Inhalt eines Bereichs innerhalb einer Tabelle gesichert.
+    if ( pSav->IsInTab() && !( pLay->IsSctFrm() && pLay->IsInTab() ) )
+        while ( !pSav->IsTabFrm() )
+            pSav = pSav->GetUpper();
+
+    if( pSav->IsInSct() )
+    { // Jetzt wird der oberste Bereich gesucht, der innerhalb von pLay ist.
+        SwFrm* pSect = pLay->FindSctFrm();
+        SwFrm *pTmp = pSav;
+        do
+        {
+            pSav = pTmp;
+            pTmp = pSav->GetUpper() ? pSav->GetUpper()->FindSctFrm() : NULL;
+        } while ( pTmp != pSect );
+    }
+
+    SwFrm *pFloat = pSav;
+    if( !pStart )
+        pStart = pSav;
+    BOOL bGo = pStart == pSav;
+    do
+    {
+        if( bGo )
+            pFloat->GetUpper()->pLower = 0;     //Die Teilkette ausklinken.
+
+        //Das Ende der Teilkette suchen, unterwegs die Flys abmelden.
+        do
+        {
+            if( bGo )
+            {
+                if ( pFloat->IsCntntFrm() )
+                {
+                    if ( pFloat->GetDrawObjs() )
+                        ::lcl_RemoveFlysFromPage( (SwCntntFrm*)pFloat );
+                }
+                else if ( pFloat->IsTabFrm() || pFloat->IsSctFrm() )
+                {
+                    SwCntntFrm *pCnt = ((SwLayoutFrm*)pFloat)->ContainsCntnt();
+                    if( pCnt )
+                    {
+                        do
+                        {   if ( pCnt->GetDrawObjs() )
+                                ::lcl_RemoveFlysFromPage( pCnt );
+                            pCnt = pCnt->GetNextCntntFrm();
+                        } while ( pCnt && ((SwLayoutFrm*)pFloat)->IsAnLower( pCnt ) );
+                    }
+                }
+                else
+                    ASSERT( !pFloat, "Neuer Float-Frame?" );
+            }
+            if ( pFloat->GetNext()  )
+            {
+                if( bGo )
+                    pFloat->pUpper = NULL;
+                pFloat = pFloat->GetNext();
+                if( !bGo && pFloat == pStart )
+                {
+                    bGo = TRUE;
+                    pFloat->pPrev->pNext = NULL;
+                    pFloat->pPrev = NULL;
+                }
+            }
+            else
+                break;
+
+        } while ( pFloat );
+
+        //Die naechste Teilkette suchen und die Ketten miteinander verbinden.
+        SwFrm *pTmp = pFloat->FindNext();
+        if( bGo )
+            pFloat->pUpper = NULL;
+
+        if( !pLay->IsInFtn() )
+            while( pTmp && pTmp->IsInFtn() )
+                pTmp = pTmp->FindNext();
+
+        if ( !pLay->IsAnLower( pTmp ) )
+            pTmp = 0;
+
+        if ( pTmp && bGo )
+        {
+            pFloat->pNext = pTmp;           //Die beiden Ketten verbinden.
+            pFloat->pNext->pPrev = pFloat;
+        }
+        pFloat = pTmp;
+        bGo = bGo || ( pStart == pFloat );
+    }  while ( pFloat );
+
+    return bGo ? pStart : NULL;
+}
+
+void MA_FASTCALL lcl_AddFlysToPage( SwCntntFrm *pCntnt, SwPageFrm *pPage )
+{
+    ASSERT( pCntnt->GetDrawObjs(), "Keine DrawObjs fuer lcl_AddFlysToPage." );
+    SwDrawObjs &rObjs = *pCntnt->GetDrawObjs();
+    for ( USHORT i = 0; i < rObjs.Count(); ++i )
+    {
+        SdrObject *pO = rObjs[i];
+        SwVirtFlyDrawObj *pObj = pO->IsWriterFlyFrame() ?
+                                                        (SwVirtFlyDrawObj*)pO : 0;
+        if ( pObj && pObj->GetFlyFrm()->IsFlyFreeFrm() )
+        {
+            SwFlyFrm *pFly = pObj->GetFlyFrm();
+            pPage->SwPageFrm::AppendFly( pFly );
+            pFly->_InvalidatePos();
+            pFly->_InvalidateSize();
+            pFly->InvalidatePage( pPage );
+            SwCntntFrm *pCnt = pFly->ContainsCntnt();
+            while ( pCnt )
+            {
+                if ( pCnt->GetDrawObjs() )
+                    ::lcl_AddFlysToPage( pCnt, pPage );
+                pCnt = pCnt->GetNextCntntFrm();
+            }
+        }
+    }
+}
+
+void RestoreCntnt( SwFrm *pSav, SwLayoutFrm *pParent, SwFrm *pSibling )
+{
+    ASSERT( pSav && pParent, "Kein Save oder Parent fuer Restore." );
+
+    //Wenn es bereits FlowFrms unterhalb des neuen Parent gibt, so wird die
+    //Kette, beginnend mit pSav,  hinter dem letzten angehaengt.
+    //Die Teile werden kurzerhand insertet und geeignet invalidiert.
+    //Unterwegs werden die Flys der CntntFrms bei der Seite angemeldet.
+
+    SwPageFrm *pPage = pParent->FindPageFrm();
+
+    if ( pPage )
+        pPage->InvalidatePage( pPage ); //Invalides Layout anmelden.
+
+    //Vorgaenger festellen und die Verbindung herstellen bzw. initialisieren.
+    pSav->pPrev = pSibling;
+    SwFrm* pNxt;
+    if ( pSibling )
+    {
+        pNxt = pSibling->pNext;
+        pSibling->pNext = pSav;
+        pSibling->_InvalidatePrt();
+        ((SwCntntFrm*)pSibling)->InvalidatePage( pPage );//Invaliden Cntnt anmelden.
+        if ( ((SwCntntFrm*)pSibling)->GetFollow() )
+            pSibling->Prepare( PREP_CLEAR, 0, sal_False );
+    }
+    else
+    {   pNxt = pParent->pLower;
+        pParent->pLower = pSav;
+        pSav->pUpper = pParent;     //Schon mal setzen, sonst ist fuer das
+                                    //invalidate der Parent (z.B. ein Fly) nicht klar.
+        //Invaliden Cntnt anmelden.
+        if ( pSav->IsCntntFrm() )
+            ((SwCntntFrm*)pSav)->InvalidatePage( pPage );
+        else
+        {   // pSav koennte auch ein leerer SectFrm sein
+            SwCntntFrm* pCnt = pParent->ContainsCntnt();
+            if( pCnt )
+                pCnt->InvalidatePage( pPage );
+        }
+    }
+
+    //Der Parent muss entsprechend gegrow'ed werden.
+    SwTwips nGrowVal = 0;
+    SwFrm* pLast;
+    do
+    {   pSav->pUpper = pParent;
+        nGrowVal += pSav->Frm().Height();
+        pSav->_InvalidateAll();
+
+        //Jetzt die Flys anmelden, fuer TxtFrms gleich geeignet invalidieren.
+        if ( pSav->IsCntntFrm() )
+        {
+            if ( pSav->IsTxtFrm() &&
+                 ((SwTxtFrm*)pSav)->GetCacheIdx() != USHRT_MAX )
+                ((SwTxtFrm*)pSav)->Init();  //Ich bin sein Freund.
+
+            if ( pPage && pSav->GetDrawObjs() )
+                ::lcl_AddFlysToPage( (SwCntntFrm*)pSav, pPage );
+        }
+        else
+        {   SwCntntFrm *pBlub = ((SwLayoutFrm*)pSav)->ContainsCntnt();
+            if( pBlub )
+            {
+                do
+                {   if ( pPage && pBlub->GetDrawObjs() )
+                        ::lcl_AddFlysToPage( pBlub, pPage );
+                    if( pBlub->IsTxtFrm() && ((SwTxtFrm*)pBlub)->HasFtn() &&
+                         ((SwTxtFrm*)pBlub)->GetCacheIdx() != USHRT_MAX )
+                        ((SwTxtFrm*)pBlub)->Init(); //Ich bin sein Freund.
+                    pBlub = pBlub->GetNextCntntFrm();
+                } while ( pBlub && ((SwLayoutFrm*)pSav)->IsAnLower( pBlub ));
+            }
+        }
+        pLast = pSav;
+        pSav = pSav->GetNext();
+
+    } while ( pSav );
+
+    if( pNxt )
+    {
+        pLast->pNext = pNxt;
+        pNxt->pPrev = pLast;
+    }
+    pParent->Grow( nGrowVal, pHeight );
+}
+
+/*************************************************************************
+|*
+|*  SqRt()              Berechnung der Quadratwurzel, damit die math.lib
+|*      nicht auch noch dazugelinkt werden muss.
+|*
+|*  Ersterstellung      OK ??
+|*  Letzte Aenderung    MA 09. Jan. 97
+|*
+|*************************************************************************/
+
+ULONG MA_FASTCALL SqRt( BigInt nX )
+{
+    BigInt nErg = 1;
+
+    if ( !nX.IsNeg() )
+    {
+        BigInt nOldErg = 1;
+        for ( int i = 0; i <= 5; i++ )
+        {
+            nErg = (nOldErg + (nX / nOldErg)) / BigInt(2);
+            nOldErg = nErg;
+        }
+    }
+    return nErg >= BigInt((ULONG)ULONG_MAX) ? ULONG_MAX : (ULONG)nErg;
+}
+
+/*************************************************************************
+|*
+|*  InsertNewPage()     Einsetzen einer neuen Seite.
+|*
+|*  Ersterstellung      MA 01. Jul. 93
+|*  Letzte Aenderung    MA 31. Jul. 95
+|*
+|*************************************************************************/
+
+SwPageFrm * MA_FASTCALL InsertNewPage( SwPageDesc &rDesc, SwFrm *pUpper,
+                          BOOL bOdd, BOOL bFtn,
+                          SwFrm *pSibling )
+{
+    SwPageFrm *pRet;
+    SwDoc *pDoc = ((SwLayoutFrm*)pUpper)->GetFmt()->GetDoc();
+    SwFrmFmt *pFmt = bOdd ? rDesc.GetRightFmt() : rDesc.GetLeftFmt();
+    //Wenn ich kein FrmFmt fuer die Seite gefunden habe, muss ich eben
+    //eine Leerseite einfuegen.
+    if ( !pFmt )
+    {
+        SwPageDesc *pTmpDesc = pSibling && pSibling->GetPrev() ?
+                ((SwPageFrm*)pSibling->GetPrev())->GetPageDesc() : &rDesc;
+        pRet = new SwPageFrm( pDoc->GetEmptyPageFmt(), pTmpDesc );
+        pRet->Paste( pUpper, pSibling );
+        pRet->PreparePage( bFtn );
+        //Jetzt muss ich ein Format fuer die entsprechende Seite erhalten.
+        bOdd = bOdd ? FALSE : TRUE;
+        pFmt = bOdd ? rDesc.GetRightFmt() : rDesc.GetLeftFmt();
+        ASSERT( pFmt, "Descriptor gibt kein Format her." );
+    }
+    pRet = new SwPageFrm( pFmt, &rDesc );
+    pRet->Paste( pUpper, pSibling );
+    pRet->PreparePage( bFtn );
+    if ( pRet->GetNext() )
+        ((SwRootFrm*)pRet->GetUpper())->AssertPageFlys( pRet );
+    return pRet;
+}
+
+
+/*************************************************************************
+|*
+|*  RegistFlys(), Regist()  Die beiden folgenden Methoden durchsuchen rekursiv
+|*      eine Layoutstruktur und melden alle FlyFrms, die einen beliebigen Frm
+|*      innerhalb der Struktur als Anker haben bei der Seite an.
+|*
+|*  Ersterstellung      MA 08. Jul. 93
+|*  Letzte Aenderung    MA 07. Jul. 95
+|*
+|*************************************************************************/
+
+void MA_FASTCALL lcl_Regist( SwPageFrm *pPage, const SwFrm *pAnch )
+{
+    SwDrawObjs *pObjs = (SwDrawObjs*)pAnch->GetDrawObjs();
+    for ( USHORT i = 0; i < pObjs->Count(); ++i )
+    {
+        SdrObject *pObj = (*pObjs)[i];
+        SwVirtFlyDrawObj *pFObj = pObj->IsWriterFlyFrame() ?
+                                                    (SwVirtFlyDrawObj*)pObj : 0;
+        if ( pFObj )
+        {
+            SwFlyFrm *pFly = pFObj->GetFlyFrm();
+            //Ggf. ummelden, nicht anmelden wenn bereits bekannt.
+            SwPageFrm *pPg = pFly->FindPageFrm();
+            if ( pPg != pPage )
+            {
+                if ( pPg )
+                    pPg->SwPageFrm::RemoveFly( pFly );
+                pPage->AppendFly( pFly );
+            }
+            ::RegistFlys( pPage, pFly );
+        }
+        else
+        {
+            SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj);
+            if ( pContact->GetPage() != pPage )
+            {
+                if ( pContact->GetPage() )
+                    pContact->GetPage()->SwPageFrm::RemoveDrawObj( pContact );
+                pPage->AppendDrawObj( pContact );
+            }
+        }
+
+        const SwFlyFrm *pFly = pAnch->FindFlyFrm();
+        if ( pFly && pObj->GetOrdNum() < pFly->GetVirtDrawObj()->GetOrdNum() )
+            pObj->GetPage()->SetObjectOrdNum( pObj->GetOrdNumDirect(),
+                                    pFly->GetVirtDrawObj()->GetOrdNumDirect() + 1 );
+    }
+}
+
+void RegistFlys( SwPageFrm *pPage, const SwLayoutFrm *pLay )
+{
+    if ( pLay->GetDrawObjs() )
+        ::lcl_Regist( pPage, pLay );
+    const SwFrm *pFrm = pLay->Lower();
+    while ( pFrm )
+    {
+        if ( pFrm->IsLayoutFrm() )
+            ::RegistFlys( pPage, (const SwLayoutFrm*)pFrm );
+        else if ( pFrm->GetDrawObjs() )
+            ::lcl_Regist( pPage, pFrm );
+        pFrm = pFrm->GetNext();
+    }
+}
+
+/*************************************************************************
+|*
+|*  void Notify()
+|*
+|*  Beschreibung        Benachrichtigt den Hintergrund je nach der
+|*      Veraenderung zwischen altem und neuem Rechteckt.
+|*  Ersterstellung      MA 18. Jun. 93
+|*  Letzte Aenderung    MA 06. Jun. 96
+|*
+|*************************************************************************/
+
+void Notify( SwFlyFrm *pFly, SwPageFrm *pOld, const SwRect &rOld )
+{
+    const SwRect aFrm( pFly->AddSpacesToFrm() );
+    if ( rOld.Pos() != aFrm.Pos() )
+    {   //Positionsaenderung, alten und neuen Bereich invalidieren
+        if ( rOld.HasArea() &&
+             rOld.Left()+pFly->GetFmt()->GetLRSpace().GetLeft() < WEIT_WECH )
+        {
+            pFly->NotifyBackground( pOld, rOld, PREP_FLY_LEAVE );
+        }
+        pFly->NotifyBackground( pFly->FindPageFrm(), aFrm, PREP_FLY_ARRIVE );
+    }
+    else if ( rOld.SSize() != aFrm.SSize() )
+    {   //Groessenaenderung, den Bereich der Verlassen wurde bzw. jetzt
+        //ueberdeckt wird invalidieren.
+        //Der Einfachheit halber wird hier bewusst jeweils ein Twip
+        //unnoetig invalidiert.
+
+        ViewShell *pSh = pFly->GetShell();
+        if( pSh && rOld.HasArea() )
+            pSh->InvalidateWindows( rOld );
+
+        if ( rOld.Left() != aFrm.Left() )
+        {   SwRect aTmp( rOld );
+            aTmp.Union( aFrm );
+            aTmp.Left(  Min(aFrm.Left(), rOld.Left()) );
+            aTmp.Right( Max(aFrm.Left(), rOld.Left()) );
+            pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
+        }
+        SwTwips nOld = rOld.Right();
+        SwTwips nNew = aFrm.Right();
+        if ( nOld != nNew )
+        {   SwRect aTmp( rOld );
+            aTmp.Union( aFrm );
+            aTmp.Left(  Min(nNew, nOld) );
+            aTmp.Right( Max(nNew, nOld) );
+            pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
+        }
+        if ( rOld.Top() != aFrm.Top() )
+        {   SwRect aTmp( rOld );
+            aTmp.Union( aFrm );
+            aTmp.Top(    Min(aFrm.Top(), rOld.Top()) );
+            aTmp.Bottom( Max(aFrm.Top(), rOld.Top()) );
+            pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
+        }
+        nOld = rOld.Bottom();
+        nNew = aFrm.Bottom();
+        if ( nOld != nNew )
+        {   SwRect aTmp( rOld );
+            aTmp.Union( aFrm );
+            aTmp.Top(    Min(nNew, nOld) );
+            aTmp.Bottom( Max(nNew, nOld) );
+            pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
+        }
+    }
+}
+
+/*************************************************************************
+|*
+|*  NotifyBackground()
+|*
+|*************************************************************************/
+#pragma optimize("",off)
+
+void MA_FASTCALL lcl_NotifyCntnt( SdrObject *pThis, SwCntntFrm *pCnt,
+    const SwRect &rRect, const PrepareHint eHint )
+{
+    if ( pCnt->IsTxtFrm() )
+    {
+        SwRect aCntPrt( pCnt->Prt() );
+        aCntPrt.Pos() += pCnt->Frm().Pos();
+        if ( eHint == PREP_FLY_ATTR_CHG )
+        {
+            if ( aCntPrt.IsOver( pThis->GetBoundRect() ) )
+                pCnt->Prepare( PREP_FLY_ATTR_CHG );
+        }
+        else if ( aCntPrt.IsOver( rRect ) || pCnt->IsFollow() || pCnt->HasFollow() )
+            pCnt->Prepare( eHint, (void*)&aCntPrt._Intersection( rRect ) );
+        if ( pCnt->GetDrawObjs() )
+        {
+            const SwDrawObjs &rObjs = *pCnt->GetDrawObjs();
+            for ( USHORT i = 0; i < rObjs.Count(); ++i )
+            {
+                SdrObject *pO = rObjs[i];
+                if ( pO->IsWriterFlyFrame() )
+                {
+                    SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+                    if ( pFly->IsFlyInCntFrm() )
+                    {
+                        SwCntntFrm *pCntnt = pFly->ContainsCntnt();
+                        while ( pCntnt )
+                        {
+                            ::lcl_NotifyCntnt( pThis, pCntnt, rRect, eHint );
+                            pCntnt = pCntnt->GetNextCntntFrm();
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+void Notify_Background( SdrObject *pObj, SwPageFrm *pPage, const SwRect& rRect,
+                        const PrepareHint eHint, const BOOL bInva )
+{
+
+    //Wenn der Frm gerade erstmalig sinnvoll positioniert wurde, braucht der
+    //alte Bereich nicht benachrichtigt werden.
+    if ( eHint == PREP_FLY_LEAVE && rRect.Top() == WEIT_WECH )
+         return;
+
+    SwLayoutFrm *pArea;
+    SwFlyFrm *pFlyFrm = 0;
+    SwFrm* pAnchor;
+    if( pObj->IsWriterFlyFrame() )
+    {
+        pFlyFrm = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+
+        //MA: Wozu ausserhalb des Ankers invalidieren? Dort wird ja eh nicht
+        //auf den Rahmen Ruecksicht genommen; normalerweise kann er dort
+        //gar nicht hin, ausser temporaer beim Formatieren.
+        pAnchor = pFlyFrm->GetAnchor();
+    }
+    else
+    {
+        pFlyFrm = NULL;
+        pAnchor = ((SwDrawContact*)GetUserCall(pObj))->GetAnchor();
+    }
+    if( PREP_FLY_LEAVE != eHint && pAnchor->IsInFly() )
+        pArea = pAnchor->FindFlyFrm();
+    else
+        pArea = pPage;
+    SwCntntFrm *pCnt = 0;
+    if ( pArea )
+    {
+        //Es reagieren sowieso nur die auf den Anker folgenden auf den Fly, also
+        //brauchen diese nicht abgeklappert werden.
+        //Ausnahme sind ist natuerlich das LEAVE, denn der Fly koennte ja von
+        //"oben" kommen.
+        // Wenn der Anker auf der vorhergehenden Seite liegt, muss ebenfalls
+        // die gesamte Seite abgearbeitet werden. (47722)
+        if ( PREP_FLY_LEAVE != eHint && pAnchor->IsCntntFrm() &&
+            pArea->IsAnLower( pAnchor ) )
+            pCnt = (SwCntntFrm*)pAnchor;
+        else
+            pCnt = pArea->ContainsCntnt();
+    }
+    SwFrm *pLastTab = 0;
+
+    while ( pCnt && pArea->IsAnLower( pCnt ) )
+    {
+        ::lcl_NotifyCntnt( pObj, pCnt, rRect, eHint );
+        if ( pCnt->IsInTab() )
+        {
+            SwLayoutFrm* pCell = pCnt->GetUpper();
+            if( pCell->IsCellFrm() &&
+                ( (pCell->Frm().IsOver( pObj->GetBoundRect() ) ||
+                    pCell->Frm().IsOver( rRect )) ) )
+            {
+                const SwFmtVertOrient &rOri = pCell->GetFmt()->GetVertOrient();
+                if ( VERT_NONE != rOri.GetVertOrient() )
+                    pCell->InvalidatePrt();
+            }
+            SwTabFrm *pTab = pCnt->FindTabFrm();
+            if ( pTab != pLastTab )
+            {
+                pLastTab = pTab;
+                if ( pTab->Frm().IsOver( pObj->GetBoundRect() ) ||
+                        pTab->Frm().IsOver( rRect ) )
+                {
+                    if ( !pFlyFrm || !pFlyFrm->IsLowerOf( pTab ) )
+                        pTab->InvalidatePrt();
+                }
+            }
+        }
+        pCnt = pCnt->GetNextCntntFrm();
+    }
+    if( pPage->Lower() )
+    {
+        SwFrm* pFrm = pPage->Lower();
+        while( pFrm->GetNext() )
+            pFrm = pFrm->GetNext();
+        if( pFrm->IsFooterFrm() &&
+            ( ( pFrm->Frm().IsOver( pObj->GetBoundRect() ) ||
+                pFrm->Frm().IsOver( rRect ) ) ) )
+            pFrm->InvalidateSize();
+    }
+    if( pPage->GetSortedObjs() )
+    {
+        pObj->GetOrdNum();
+        const SwSortDrawObjs &rObjs = *pPage->GetSortedObjs();
+        for ( USHORT i = 0; i < rObjs.Count(); ++i )
+        {
+            SdrObject *pO = rObjs[i];
+            if ( pO->IsWriterFlyFrame() )
+            {
+                if( pO == pObj )
+                    continue;
+                SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+                if ( pFly->Frm().Top() == WEIT_WECH )
+                    continue;
+
+                if ( !pFlyFrm ||
+                        (!pFly->IsLowerOf( pFlyFrm ) &&
+                        pFly->GetVirtDrawObj()->GetOrdNumDirect() < pObj->GetOrdNumDirect()))
+                {
+                    pCnt = pFly->ContainsCntnt();
+                    while ( pCnt )
+                    {
+                        ::lcl_NotifyCntnt( pObj, pCnt, rRect, eHint );
+                        pCnt = pCnt->GetNextCntntFrm();
+                    }
+                }
+                if( pFly->IsFlyLayFrm() )
+                {
+                    if( pFly->Lower() && pFly->Lower()->IsColumnFrm() &&
+                        pFly->Frm().Bottom() >= rRect.Top() &&
+                        pFly->Frm().Top() <= rRect.Bottom() &&
+                        pFly->Frm().Right() >= rRect.Left() &&
+                        pFly->Frm().Left() <= rRect.Right() )
+                     {
+                        const SwFmtFrmSize &rSz = pFly->GetFmt()->GetFrmSize();
+                        pFly->InvalidateSize();
+                     }
+                }
+                //Flys, die ueber mir liegen muessen/mussten evtl.
+                //ausweichen, wenn sie eine automatische Ausrichtung haben.
+                //das ist unabhaengig von meinem Attribut, weil dies sich
+                //gerade geaendert haben kann und eben deshalb
+                //umformatiert wurde.
+                else if ( pFly->IsFlyAtCntFrm() &&
+                        pObj->GetOrdNumDirect() <
+                        pFly->GetVirtDrawObj()->GetOrdNumDirect() &&
+                        pFlyFrm && !pFly->IsLowerOf( pFlyFrm ) )
+                {
+                    const SwFmtHoriOrient &rH = pFly->GetFmt()->GetHoriOrient();
+                    if ( HORI_NONE != rH.GetHoriOrient()  &&
+                            HORI_CENTER != rH.GetHoriOrient()  &&
+                            ( !pFly->IsAutoPos() || REL_CHAR != rH.GetRelationOrient() ) &&
+                            (pFly->Frm().Bottom() >= rRect.Top() &&
+                            pFly->Frm().Top() <= rRect.Bottom()) )
+                        pFly->InvalidatePos();
+                }
+            }
+        }
+    }
+    if ( pFlyFrm && pAnchor->GetUpper() && pAnchor->IsInTab() )//MA_FLY_HEIGHT
+        pAnchor->GetUpper()->InvalidateSize();
+
+    ViewShell *pSh;
+    if( bInva && 0 != (pSh = pPage->GetShell()) )
+        pSh->InvalidateWindows( rRect );
+}
+
+#pragma optimize("",on)
+
+/*************************************************************************
+|*
+|*  GetVirtualUpper() liefert bei absatzgebundenen Objekten den Upper
+|*  des Ankers. Falls es sich dabei um verkettete Rahmen oder
+|*  Fussnoten handelt, wird ggf. der "virtuelle" Upper ermittelt.
+|*
+|*************************************************************************/
+
+const SwFrm* GetVirtualUpper( const SwFrm* pFrm, const Point& rPos )
+{
+    if( pFrm->IsTxtFrm() )
+    {
+        pFrm = pFrm->GetUpper();
+        if( !pFrm->Frm().IsInside( rPos ) )
+        {
+            if( pFrm->IsFtnFrm() )
+            {
+                const SwFtnFrm* pTmp = ((SwFtnFrm*)pFrm)->GetFollow();
+                while( pTmp )
+                {
+                    if( pTmp->Frm().IsInside( rPos ) )
+                        return pTmp;
+                    pTmp = pTmp->GetFollow();
+                }
+            }
+            else
+            {
+                SwFlyFrm* pTmp = (SwFlyFrm*)pFrm->FindFlyFrm();
+                while( pTmp )
+                {
+                    if( pTmp->Frm().IsInside( rPos ) )
+                        return pTmp;
+                    pTmp = pTmp->GetNextLink();
+                }
+            }
+        }
+    }
+    return pFrm;
+}
+
+/*************************************************************************
+|*
+|*  IsLowerOf()
+|*
+|*************************************************************************/
+
+BOOL Is_Lower_Of( const SwFrm *pCurrFrm, const SdrObject* pObj )
+{
+    Point aPos;
+    const SwFrm* pFrm;
+    if( pObj->IsWriterFlyFrame() )
+    {
+        const SwFlyFrm* pFly = ( (SwVirtFlyDrawObj*)pObj )->GetFlyFrm();
+        pFrm = pFly->GetAnchor();
+        aPos = pFly->Frm().Pos();
+    }
+    else
+    {
+        pFrm = ( (SwDrawContact*)GetUserCall(pObj) )->GetAnchor();
+        aPos = pObj->GetBoundRect().TopLeft();
+    }
+    ASSERT( pFrm, "8-( Fly is lost in Space." );
+    pFrm = GetVirtualUpper( pFrm, aPos );
+    do
+    {   if ( pFrm == pCurrFrm )
+            return TRUE;
+        if( pFrm->IsFlyFrm() )
+        {
+            aPos = pFrm->Frm().Pos();
+            pFrm = GetVirtualUpper( ((const SwFlyFrm*)pFrm)->GetAnchor(), aPos );
+        }
+        else
+            pFrm = pFrm->GetUpper();
+    } while ( pFrm );
+    return FALSE;
+}
+
+const SwFrm *FindKontext( const SwFrm *pFrm, USHORT nAdditionalKontextTyp )
+{
+    //Liefert die Umgebung des Frm in die kein Fly aus einer anderen
+    //Umgebung hineinragen kann.
+    const USHORT nTyp = FRM_ROOT | FRM_HEADER   | FRM_FOOTER | FRM_FTNCONT  |
+                        FRM_FTN  | FRM_FLY      |
+                        FRM_TAB  | FRM_ROW      | FRM_CELL |
+                        nAdditionalKontextTyp;
+    do
+    {   if ( pFrm->GetType() & nTyp )
+            break;
+        pFrm = pFrm->GetUpper();
+    } while( pFrm );
+    return pFrm;
+}
+
+BOOL IsFrmInSameKontext( const SwFrm *pInnerFrm, const SwFrm *pFrm )
+{
+    const SwFrm *pKontext = FindKontext( pInnerFrm, 0 );
+
+    const USHORT nTyp = FRM_ROOT | FRM_HEADER   | FRM_FOOTER | FRM_FTNCONT  |
+                        FRM_FTN  | FRM_FLY      |
+                        FRM_TAB  | FRM_ROW      | FRM_CELL;
+    do
+    {   if ( pFrm->GetType() & nTyp )
+        {
+            if( pFrm == pKontext )
+                return TRUE;
+            if( pFrm->IsCellFrm() )
+                return FALSE;
+        }
+        if( pFrm->IsFlyFrm() )
+        {
+            Point aPos( pFrm->Frm().Pos() );
+            pFrm = GetVirtualUpper( ((const SwFlyFrm*)pFrm)->GetAnchor(), aPos );
+        }
+        else
+            pFrm = pFrm->GetUpper();
+    } while( pFrm );
+
+    return FALSE;
+}
+
+
+//---------------------------------
+
+SwTwips MA_FASTCALL lcl_CalcCellRstHeight( SwLayoutFrm *pCell )
+{
+    if ( pCell->Lower()->IsCntntFrm() || pCell->Lower()->IsSctFrm() )
+    {
+        SwFrm *pLow = pCell->Lower();
+        long nHeight = 0, nFlyAdd = 0;
+        do
+        {
+            long nLow = pLow->Frm().Height();
+            if( pLow->IsTxtFrm() && ((SwTxtFrm*)pLow)->IsUndersized() )
+                nLow += ((SwTxtFrm*)pLow)->GetParHeight()-pLow->Prt().Height();
+            else if( pLow->IsSctFrm() && ((SwSectionFrm*)pLow)->IsUndersized() )
+                nLow += ((SwSectionFrm*)pLow)->Undersize();
+            nFlyAdd = Max( 0L, nFlyAdd - nLow );
+            nFlyAdd = Max( nFlyAdd, ::CalcHeightWidthFlys( pLow ) );
+            nHeight += nLow;
+            pLow = pLow->GetNext();
+        } while ( pLow );
+        if ( nFlyAdd )
+            nHeight += nFlyAdd;
+
+        //Der Border will natuerlich auch mitspielen, er kann leider nicht
+        //aus PrtArea und Frm errechnet werden, da diese in beliebiger
+        //Kombination ungueltig sein koennen.
+        SwBorderAttrAccess aAccess( SwFrm::GetCache(), pCell );
+        const SwBorderAttrs &rAttrs = *aAccess.Get();
+        nHeight += rAttrs.CalcTop() + rAttrs.CalcBottom();
+
+        return pCell->Frm().Height() - nHeight;
+    }
+    else
+    {
+        long nRstHeight = 0;
+        SwFrm *pLow = pCell->Lower();
+        do
+        {   nRstHeight += ::CalcRowRstHeight( (SwLayoutFrm*)pLow );
+            pLow = pLow->GetNext();
+
+        } while ( pLow );
+
+        return nRstHeight;
+    }
+}
+
+SwTwips MA_FASTCALL CalcRowRstHeight( SwLayoutFrm *pRow )
+{
+    SwTwips nRstHeight = LONG_MAX;
+    SwLayoutFrm *pLow = (SwLayoutFrm*)pRow->Lower();
+    while ( pLow )
+    {
+        nRstHeight = Min( nRstHeight, ::lcl_CalcCellRstHeight( pLow ) );
+        pLow = (SwLayoutFrm*)pLow->GetNext();
+    }
+    return nRstHeight;
+}
+
+
+void MA_ParkCrsr( SwPageDesc *pDesc, SwCrsrShell &rSh )
+{
+    //Footer
+    const SwFrmFmt  *pFmt = pDesc->GetMaster().GetFooter().GetFooterFmt();
+    const SwFmtCntnt  *pCnt;
+    if( pFmt )
+    {
+        pCnt = &pFmt->GetCntnt();
+        if ( pCnt->GetCntntIdx() )
+            rSh.ParkCrsr( *pCnt->GetCntntIdx() );
+    }
+    pFmt = pDesc->GetLeft().GetFooter().GetFooterFmt();
+    if( pFmt )
+    {
+        pCnt = &pFmt->GetCntnt();
+        if ( pCnt->GetCntntIdx() )
+            rSh.ParkCrsr( *pCnt->GetCntntIdx() );
+    }
+
+    //Header
+    pFmt = pDesc->GetMaster().GetHeader().GetHeaderFmt();
+    if( pFmt )
+    {
+        pCnt = &pFmt->GetCntnt();
+        if ( pCnt->GetCntntIdx() )
+            rSh.ParkCrsr( *pCnt->GetCntntIdx() );
+    }
+    pFmt = pDesc->GetLeft().GetHeader().GetHeaderFmt();
+    if( pFmt )
+    {
+        pCnt = &pFmt->GetCntnt();
+        if ( pCnt->GetCntntIdx() )
+            rSh.ParkCrsr( *pCnt->GetCntntIdx() );
+    }
+}
+
+const SwFrm* MA_FASTCALL FindPage( const SwRect &rRect, const SwFrm *pPage )
+{
+    if ( !rRect.IsOver( pPage->Frm() ) )
+    {
+        BOOL bPrvAllowed = TRUE;
+        BOOL bNxtAllowed = TRUE;
+        do
+        {   if ( pPage->Frm().Top() > rRect.Top() && bPrvAllowed )
+            {
+                if ( pPage->GetPrev() )
+                {
+                    bNxtAllowed = FALSE;
+                    pPage = pPage->GetPrev();
+                }
+                else
+                    break;
+            }
+            else if ( pPage->Frm().Bottom() < rRect.Top() && bNxtAllowed )
+            {
+                if ( pPage->GetNext() )
+                {
+                    bPrvAllowed = FALSE;
+                    pPage = pPage->GetNext();
+                }
+                else
+                    break;
+            }
+            else
+                break;
+
+        } while ( !rRect.IsOver( pPage->Frm() ) );
+    }
+    return pPage;
+}
+
+
+SwFrm* GetFrmOfModify( SwModify& rMod, USHORT nFrmType, const Point* pPoint,
+                        const SwPosition *pPos, const BOOL bCalcFrm )
+{
+    SwFrm *pMinFrm = 0, *pTmpFrm;
+    SwRect aCalcRect;
+
+    SwClientIter aIter( rMod );
+    do {
+        pMinFrm = 0;
+        Size aMinSize;
+
+        for( pTmpFrm = (SwFrm*)aIter.First( TYPE( SwFrm )); pTmpFrm;
+                pTmpFrm = (SwFrm*)aIter.Next() )
+            if( pTmpFrm->GetType() & nFrmType &&
+                (!pTmpFrm->IsFlowFrm() ||
+                 !SwFlowFrm::CastFlowFrm( pTmpFrm )->IsFollow() ))
+            {
+                if( pPoint )
+                {
+                    if( bCalcFrm )
+                        pTmpFrm->Calc();
+
+                    if( aIter.IsChanged() )     // der Liste hat sich ver-
+                        break;                  // aendert, neu anfangen !!
+
+                    // bei Flys ggfs. ueber den Parent gehen wenn sie selbst
+                    // nocht nicht "formatiert" sind
+                    if( !bCalcFrm && nFrmType & FRM_FLY &&
+                        ((SwFlyFrm*)pTmpFrm)->GetAnchor() &&
+                        WEIT_WECH == pTmpFrm->Frm().Pos().X() &&
+                        WEIT_WECH == pTmpFrm->Frm().Pos().Y() )
+                        aCalcRect = ((SwFlyFrm*)pTmpFrm)->GetAnchor()->Frm();
+                    else
+                        aCalcRect = pTmpFrm->Frm();
+
+                    // fasse den Point und das Recteck zusammen, falls
+                    // er Point nicht innerhalb liegt. Liegt er ausserhalb,
+                    // wird nach dem kleinsten Rectangle gesucht, also das,
+                    // wo der Point am dichtesten dran liegt. Ist der Point im
+                    // Rechteck, wird die Schleife beendet.
+                    {
+                        BOOL bInside = TRUE;
+                        // die Left/Right-Position erweitern
+                        if( pPoint->X() < aCalcRect.Left() )
+                            {   bInside = FALSE; aCalcRect.Left( pPoint->X() ); }
+                        if( pPoint->X() > aCalcRect.Right() )
+                            {   bInside = FALSE; aCalcRect.Right( pPoint->X() ); }
+
+                        if( pPoint->Y() > aCalcRect.Bottom() )
+                            {   bInside = FALSE; aCalcRect.Bottom( pPoint->Y() ); }
+                        if( pPoint->Y() < aCalcRect.Top() )
+                            {   bInside = FALSE; aCalcRect.Top( pPoint->Y() ); }
+                        if( bInside )
+                        {
+                            pMinFrm = pTmpFrm;
+                            break;
+                        }
+                    }
+
+                    if( pMinFrm )
+                    {
+                        long nDiffW = aMinSize.Width() - aCalcRect.Width();
+                        long nDiffH = aMinSize.Height() - aCalcRect.Height();
+
+                            // gleiche Hoehe, dann entscheided die Breite
+                        if( !nDiffH )       { if( 0 >= nDiffW ) continue; }
+                            // gleiche Breite, dann entscheided die Hoehe
+                        else if( !nDiffW )  { if( 0 >= nDiffH ) continue; }
+
+                            // hoehere Gewichtung auf die Hoehe !!
+                        else if( !(0 < nDiffW && 0 < nDiffH ) &&
+                                ((0 > nDiffW && 0 > nDiffH ) ||
+                                0 >= nDiffH ))
+                            continue;
+                    }
+                }
+                else
+                {
+                    // Wenn kein pPoint angegeben ist, dann reichen
+                    // wir irgendeinen raus: den ersten!
+                    pMinFrm = pTmpFrm;
+                    break;
+                }
+                pMinFrm = pTmpFrm;
+                aMinSize = aCalcRect.SSize();
+            }
+    } while( aIter.IsChanged() );
+
+    if( pPos && pMinFrm && pMinFrm->IsTxtFrm() )
+        return ((SwTxtFrm*)pMinFrm)->GetFrmAtPos( *pPos );
+
+    return pMinFrm;
+}
+
+FASTBOOL IsExtraData( const SwDoc *pDoc )
+{
+    const SwLineNumberInfo &rInf = pDoc->GetLineNumberInfo();
+    return rInf.IsPaintLineNumbers() ||
+           rInf.IsCountInFlys() ||
+           ((SwHoriOrient)SW_MOD()->GetRedlineMarkPos() != HORI_NONE &&
+            pDoc->GetRedlineTbl().Count());
+}
+
diff --git a/sw/source/core/layout/ftnfrm.cxx b/sw/source/core/layout/ftnfrm.cxx
new file mode 100644
index 000000000000..7f26f79b06bc
--- /dev/null
+++ b/sw/source/core/layout/ftnfrm.cxx
@@ -0,0 +1,2931 @@
+/*************************************************************************
+ *
+ *  $RCSfile: ftnfrm.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:22 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _TXTFTN_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFTN_HXX //autogen
+#include 
+#endif
+#ifndef _FTNIDX_HXX //autogen
+#include 
+#endif
+#include "pagefrm.hxx"
+#include "colfrm.hxx"
+#include "rootfrm.hxx"
+#include "cntfrm.hxx"
+#include "doc.hxx"
+#include "ndtxt.hxx"
+#include "frmtool.hxx"
+#include "errhdl.hxx"
+#include "swtable.hxx"
+#include "ftnfrm.hxx"
+#include "txtfrm.hxx"
+#include "tabfrm.hxx"
+#include "pagedesc.hxx"
+#include "ftninfo.hxx"
+#include "ndindex.hxx"
+#include "sectfrm.hxx"
+
+/*************************************************************************
+|*
+|*  lcl_FindFtnPos()        Sucht die Position des Attributes im FtnArray am
+|*      Dokument, dort stehen die Fussnoten gluecklicherweise nach ihrem
+|*      Index sortiert.
+|*
+|*  Ersterstellung      MA 29. Jun. 93
+|*  Letzte Aenderung    MA 13. Dec. 93
+|*
+|*************************************************************************/
+
+#define ENDNOTE 0x80000000
+
+ULONG MA_FASTCALL lcl_FindFtnPos( const SwDoc *pDoc, const SwTxtFtn *pAttr )
+{
+    const SwFtnIdxs &rFtnIdxs = pDoc->GetFtnIdxs();
+
+#ifdef MA_DEBUG
+    //Wenn das Array nicht stimmt haben wir ein Problem, denn viele
+    //Ftn-Functions bauen auf dem Array auf.
+    for ( USHORT k = 0; k+1 < rFtnIdxs.Count(); ++k )
+    {
+        SwIndex aIdx1(&pDoc->GetNodes());
+        SwIndex aIdx2(&pDoc->GetNodes());
+        rFtnIdxs[k]->pFtn->  GetTxtNode().GetIndex(aIdx1);
+        rFtnIdxs[k+1]->pFtn->GetTxtNode().GetIndex(aIdx2);
+        if ( aIdx1.GetIndex() > aIdx2.GetIndex() )
+        {
+            ASSERT( !rFtnIdxs.Count(), "FtnIdxs not up to date" );
+        }
+        else if ( aIdx1.GetIndex() == aIdx2.GetIndex() )
+        {
+            SwTxtFtn *p1 = rFtnIdxs[k];
+            SwTxtFtn *p2 = rFtnIdxs[k+1];
+            ASSERT( *p1->GetStart() < *p2->GetStart(),
+                    "FtnIdxs not up to date" );
+        }
+    }
+#endif
+
+    USHORT nRet;
+    SwTxtFtnPtr pBla = (SwTxtFtn*)pAttr;
+    if ( rFtnIdxs.Seek_Entry( pBla, &nRet ) )
+    {
+        if( pAttr->GetFtn().IsEndNote() )
+            return ULONG(nRet) + ENDNOTE;
+        return nRet;
+    }
+    ASSERT( !pDoc, "FtnPos not found." );
+    return 0;
+}
+
+BOOL SwFtnFrm::operator<( const SwTxtFtn* pTxtFtn ) const
+{
+    const SwDoc* pDoc = GetFmt()->GetDoc();
+    ASSERT( pDoc, "SwFtnFrm: Missing doc!" );
+    return lcl_FindFtnPos( pDoc, GetAttr() ) <
+           lcl_FindFtnPos( pDoc, pTxtFtn );
+}
+
+/*************************************************************************
+|*
+|*  BOOL lcl_NextFtnBoss( SwFtnBossFrm* pBoss, SwPageFrm* pPage)
+|*  setzt pBoss auf den naechsten SwFtnBossFrm, das kann entweder eine Spalte
+|*  oder eine Seite (ohne Spalten) sein. Wenn die Seite dabei gewechselt wird
+|*  enthaelt pPage die neue Seite und die Funktion liefert TRUE.
+|*
+|*  Ersterstellung      AMA 06. Nov. 98
+|*  Letzte Aenderung    AMA 06. Nov. 98
+|*
+|*************************************************************************/
+
+BOOL lcl_NextFtnBoss( SwFtnBossFrm* &rpBoss, SwPageFrm* &rpPage,
+    BOOL bDontLeave )
+{
+    if( rpBoss->IsColumnFrm() )
+    {
+        if( rpBoss->GetNext() )
+        {
+            rpBoss = (SwFtnBossFrm*)rpBoss->GetNext(); //naechste Spalte
+            return FALSE;
+        }
+        if( rpBoss->IsInSct() )
+        {
+            SwSectionFrm* pSct = rpBoss->FindSctFrm()->GetFollow();
+            if( pSct )
+            {
+                ASSERT( pSct->Lower() && pSct->Lower()->IsColumnFrm(),
+                        "Where's the column?" );
+                rpBoss = (SwColumnFrm*)pSct->Lower();
+                SwPageFrm* pOld = rpPage;
+                rpPage = pSct->FindPageFrm();
+                return pOld != rpPage;
+            }
+            else if( bDontLeave )
+            {
+                rpPage = NULL;
+                rpBoss = NULL;
+                return FALSE;
+            }
+        }
+    }
+    rpPage = (SwPageFrm*)rpPage->GetNext(); // naechste Seite
+    rpBoss = rpPage;
+    if( rpPage )
+    {
+        SwLayoutFrm* pBody = rpPage->FindBodyCont();
+        if( pBody && pBody->Lower() && pBody->Lower()->IsColumnFrm() )
+            rpBoss = (SwFtnBossFrm*)pBody->Lower(); // erste Spalte
+    }
+    return TRUE;
+}
+
+/*************************************************************************
+|*
+|*  USHORT lcl_ColumnNum( SwFrm* pBoss )
+|*  liefert die Spaltennummer, wenn pBoss eine Spalte ist,
+|*  sonst eine Null (bei Seiten).
+|*
+|*  Ersterstellung      AMA 06. Nov. 98
+|*  Letzte Aenderung    AMA 06. Nov. 98
+|*
+|*************************************************************************/
+
+USHORT lcl_ColumnNum( const SwFrm* pBoss )
+{
+    USHORT nRet = 0;
+    if( !pBoss->IsColumnFrm() )
+        return 0;
+    const SwFrm* pCol;
+    if( pBoss->IsInSct() )
+    {
+        pCol = pBoss->GetUpper()->FindColFrm();
+        if( pBoss->GetNext() || pBoss->GetPrev() )
+        {
+            while( pBoss )
+            {
+                ++nRet;                     // Section columns
+                pBoss = pBoss->GetPrev();
+            }
+        }
+    }
+    else
+        pCol = pBoss;
+    while( pCol )
+    {
+        nRet += 256;                    // Page columns
+        pCol = pCol->GetPrev();
+    }
+    return nRet;
+}
+
+/*************************************************************************
+|*
+|*  SwFtnContFrm::SwFtnContFrm()
+|*
+|*  Ersterstellung      MA 24. Feb. 93
+|*  Letzte Aenderung    MA 02. Mar. 93
+|*
+|*************************************************************************/
+
+
+SwFtnContFrm::SwFtnContFrm( SwFrmFmt *pFmt ):
+    SwLayoutFrm( pFmt )
+{
+    nType = FRM_FTNCONT;
+}
+
+
+// lcl_Undersize(..) klappert einen SwFrm und dessen Inneres ab
+// und liefert die Summe aller TxtFrm-Vergroesserungswuensche
+
+long lcl_Undersize( const SwFrm* pFrm )
+{
+    long nRet = 0;
+    if( pFrm->IsTxtFrm() )
+    {
+        if( ((SwTxtFrm*)pFrm)->IsUndersized() )
+            // Dieser TxtFrm waere gern ein bisschen groesser
+            nRet = ((SwTxtFrm*)pFrm)->GetParHeight() - pFrm->Prt().Height();
+            if( nRet < 0 )
+                nRet = 0;
+    }
+    else if( pFrm->IsLayoutFrm() )
+    {
+        const SwFrm* pNxt = ((SwLayoutFrm*)pFrm)->Lower();
+        while( pNxt )
+        {
+            nRet += lcl_Undersize( pNxt );
+            pNxt = pNxt->GetNext();
+        }
+    }
+    return nRet;
+}
+
+/*************************************************************************
+|*
+|*  SwFtnContFrm::Format()
+|*
+|*  Beschreibung:       "Formatiert" den Frame;
+|*                      Die Fixsize wird hier nicht eingestellt.
+|*  Ersterstellung      MA 01. Mar. 93
+|*  Letzte Aenderung    MA 17. Nov. 98
+|*
+|*************************************************************************/
+
+
+void SwFtnContFrm::Format( const SwBorderAttrs * )
+{
+    //GesamtBorder ermitteln, es gibt nur einen Abstand nach oben.
+    const SwPageFrm* pPage = FindPageFrm();
+    const SwPageFtnInfo &rInf = pPage->GetPageDesc()->GetFtnInfo();
+    const SwTwips nBorder = rInf.GetTopDist() + rInf.GetBottomDist() +
+                            rInf.GetLineWidth();
+
+    if ( !bValidPrtArea )
+    {
+        bValidPrtArea = TRUE;
+        Prt().Top( nBorder );
+        Prt().Width ( Frm().Width() );
+        Prt().Height( Frm().Height() - nBorder );
+        if( Prt().Height() < 0 && !pPage->IsFtnPage() )
+            bValidSize = FALSE;
+    }
+
+    if ( !bValidSize )
+    {
+        if ( pPage->IsFtnPage() && !GetFmt()->GetDoc()->IsBrowseMode() )
+        {
+            //Das Teil ist immer so gross wie moeglich
+//MA 17. Nov. 98 Wozu soll das Probegrow sinnvoll sein?
+//          if ( Grow( LONG_MAX, pHeight, TRUE ) )
+                Grow( LONG_MAX, pHeight, FALSE );
+        }
+        else
+        {
+            //Die Groesse in der VarSize wird durch den Inhalt plus den
+            //Raendern bestimmt.
+            SwTwips nRemaining = 0;
+            SwFrm *pFrm = pLower;
+            while ( pFrm )
+            {   // lcl_Undersize(..) beruecksichtigt (rekursiv) TxtFrms, die gerne
+                // groesser waeren. Diese entstehen insbesondere in spaltigen Rahmen,
+                // wenn diese noch nicht ihre maximale Groesse haben.
+                nRemaining += pFrm->Frm().SSize().Height() + lcl_Undersize( pFrm );
+                pFrm = pFrm->GetNext();
+            }
+            //Jetzt noch den Rand addieren
+            nRemaining += nBorder;
+
+            SwTwips nDiff;
+            if( IsInSct() )
+            {
+                nDiff = GetUpper()->Frm().Top() + GetUpper()->Prt().Top() +
+                        GetUpper()->Prt().Height() - Frm().Top();
+                if( nDiff < Frm().Height() )
+                {
+                    if( nDiff < 0 )
+                        nDiff = 0;
+                    Frm().Height( nDiff );
+                    Prt().Height( nDiff - Prt().Top() );
+                }
+            }
+            nDiff = Frm().SSize().Height() - nRemaining;
+            if ( nDiff > 0 )
+                Shrink( nDiff, pHeight );
+            else if ( nDiff < 0 )
+            {
+                Grow( -nDiff, pHeight );
+                //Es kann passieren, dass weniger Platz zur Verfuegung steht,
+                //als der bereits der Border benoetigt - die Groesse der
+                //PrtArea wird dann negativ.
+                if ( Prt().Height() < 0 )
+                {
+                    //Ausweg: Der Border wird so verkleinert, das die Hoehe
+                    //der PrtArea gerade 0 wird. Das richtet sich dann schon
+                    //wieder.
+                    const SwTwips nDiff = Max( Prt().Top(), -Prt().Height() );
+                    Prt().SSize().Height() += nDiff;
+                    Prt().Pos().Y() -= nDiff;
+                }
+            }
+        }
+        bValidSize = TRUE;
+    }
+}
+/*************************************************************************
+|*
+|*  SwFtnContFrm::GrowFrm(), ShrinkFrm()
+|*
+|*  Ersterstellung      MA 24. Feb. 93
+|*  Letzte Aenderung    AMA 05. Nov. 98
+|*
+|*************************************************************************/
+
+
+SwTwips SwFtnContFrm::GrowFrm( SwTwips nDist, const SzPtr pDirection,
+                               BOOL bTst, BOOL bInfo )
+{
+    //Keine Pruefung ob FixSize oder nicht, die FtnContainer sind immer bis
+    //zur Maximalhoehe variabel.
+    //Wenn die Maximalhoehe LONG_MAX ist, so nehmen wir uns soviel Platz wie eben
+    //moeglich.
+    //Wenn die Seite eine spezielle Fussnotenseite ist, so nehmen wir uns auch
+    //soviel Platz wie eben moeglich.
+#ifndef PRODUCT
+    if ( !GetUpper() || !GetUpper()->IsFtnBossFrm() )
+    {   ASSERT( !this, "Keine FtnBoss." );
+        return 0;
+    }
+#endif
+
+    if ( Frm().SSize().*pDirection > 0 &&
+         nDist > (LONG_MAX - Frm().SSize().*pDirection) )
+        nDist = LONG_MAX - Frm().SSize().*pDirection;
+
+    SwFtnBossFrm *pBoss = (SwFtnBossFrm*)GetUpper();
+    if( IsInSct() )
+    {
+        SwSectionFrm* pSect = FindSctFrm();
+        ASSERT( pSect, "GrowFrm: Missing SectFrm" );
+        // In a section, which has to maximize, a footnotecontainer is allowed
+        // to grow, when the section can't grow anymore.
+        if( !bTst && !pSect->IsColLocked() &&
+            pSect->ToMaximize( FALSE ) && pSect->Growable() )
+        {
+            pSect->InvalidateSize();
+            return 0;
+        }
+    }
+    SwPageFrm *pPage = pBoss->FindPageFrm();
+    if ( !pPage->IsFtnPage() || GetFmt()->GetDoc()->IsBrowseMode() )
+    {
+        if ( pBoss->GetMaxFtnHeight() != LONG_MAX )
+        {
+            nDist = Min( nDist, pBoss->GetMaxFtnHeight() - Frm().Height() );
+            if ( nDist <= 0 )
+                return 0L;
+        }
+        //Der FtnBoss will bezueglich des MaxWerts auch noch mitreden.
+        if( !IsInSct() )
+        {
+            const SwTwips nMax = pBoss->GetVarSpace();
+            if ( nDist > nMax )
+                nDist = nMax;
+            if ( nDist <= 0 )
+                return 0L;
+        }
+    }
+    else if ( nDist > GetPrev()->Frm().Height() )
+        //aber mehr als der Body kann koennen und wollen wir nun auch wieder
+        //nicht herausruecken.
+        nDist = GetPrev()->Frm().Height();
+
+    //Nicht mehr verlangen als benoetigt wird.
+    long nAvail = 0;
+    if ( GetFmt()->GetDoc()->IsBrowseMode() )
+    {
+        nAvail = GetUpper()->Prt().Height();
+        const SwFrm *pAvail = GetUpper()->Lower();
+        do
+        {   nAvail -= pAvail->Frm().Height();
+            pAvail = pAvail->GetNext();
+        } while ( pAvail );
+        if ( nAvail > nDist )
+            nAvail = nDist;
+    }
+
+    if ( !bTst )
+        Frm().SSize().*pDirection += nDist;
+
+    long nGrow = nDist - nAvail,
+         nReal = 0;
+    if ( nGrow > 0 )
+    {
+        BYTE nAdjust = pBoss->NeighbourhoodAdjustment( this );
+        if( NA_ONLY_ADJUST == nAdjust )
+            nReal = AdjustNeighbourhood( nGrow, bTst );
+        else
+        {
+            if( NA_GROW_ADJUST == nAdjust )
+            {
+                SwFrm* pFtn = Lower();
+                if( pFtn )
+                {
+                    while( pFtn->GetNext() )
+                        pFtn = pFtn->GetNext();
+                    if( ((SwFtnFrm*)pFtn)->GetAttr()->GetFtn().IsEndNote() )
+                    {
+                        nReal = AdjustNeighbourhood( nGrow, bTst );
+                        nAdjust = NA_GROW_SHRINK; // no more AdjustNeighbourhood
+                    }
+                }
+            }
+            nReal += pBoss->Grow( nGrow - nReal, pHeight, bTst );
+            if( ( NA_GROW_ADJUST == nAdjust || NA_ADJUST_GROW == nAdjust )
+                  && nReal < nGrow )
+                nReal += AdjustNeighbourhood( nGrow - nReal, bTst );
+        }
+    }
+
+    nReal += nAvail;
+
+    if ( !bTst )
+    {
+        if ( nReal != nDist )
+            //Den masslosen Wunsch koennen wir leider nur in Grenzen erfuellen.
+            Frm().SSize().*pDirection -= (nDist - nReal);
+        //Nachfolger braucht nicht invalidiert werden, denn wir wachsen
+        //immer nach oben.
+        if( nReal )
+        {
+            _InvalidateSize();
+            _InvalidatePos();
+            InvalidatePage( pPage );
+        }
+    }
+    return nReal;
+}
+
+
+
+SwTwips SwFtnContFrm::ShrinkFrm( SwTwips nDiff, const SzPtr pDirection,
+                                 BOOL bTst, BOOL bInfo )
+{
+    SwPageFrm *pPage = FindPageFrm();
+    if ( pPage && (!pPage->IsFtnPage() || GetFmt()->GetDoc()->IsBrowseMode()) )
+    {
+        SwTwips nRet = SwLayoutFrm::ShrinkFrm( nDiff, pDirection, bTst, bInfo );
+        if ( !bTst && nRet )
+        {
+            _InvalidatePos();
+            InvalidatePage( pPage );
+        }
+        return nRet;
+    }
+    return 0;
+}
+
+
+/*************************************************************************
+|*
+|*  SwFtnFrm::SwFtnFrm()
+|*
+|*  Ersterstellung      MA 24. Feb. 93
+|*  Letzte Aenderung    MA 11. Oct. 93
+|*
+|*************************************************************************/
+
+
+SwFtnFrm::SwFtnFrm( SwFrmFmt *pFmt, SwCntntFrm *pCnt, SwTxtFtn *pAt ):
+    SwLayoutFrm( pFmt ),
+    pFollow( 0 ),
+    pMaster( 0 ),
+    pRef( pCnt ),
+    pAttr( pAt ),
+    bBackMoveLocked( FALSE )
+{
+    nType = FRM_FTN;
+}
+
+/*************************************************************************
+|*
+|*  SwFtnFrm::InvalidateNxtFtnCnts()
+|*
+|*  Ersterstellung      MA 29. Jun. 93
+|*  Letzte Aenderung    MA 29. Jun. 93
+|*
+|*************************************************************************/
+
+
+void SwFtnFrm::InvalidateNxtFtnCnts( SwPageFrm *pPage )
+{
+    if ( GetNext() )
+    {
+        SwFrm *pCnt = ((SwLayoutFrm*)GetNext())->ContainsAny();
+        if( pCnt )
+        {
+            pCnt->InvalidatePage( pPage );
+            pCnt->_InvalidatePrt();
+            do
+            {   pCnt->_InvalidatePos();
+                if( pCnt->IsSctFrm() )
+                {
+                    SwFrm* pTmp = ((SwSectionFrm*)pCnt)->ContainsAny();
+                    if( pTmp )
+                        pTmp->_InvalidatePos();
+                }
+                pCnt->GetUpper()->_InvalidateSize();
+                pCnt = pCnt->FindNext();
+            } while ( pCnt && GetUpper()->IsAnLower( pCnt ) );
+        }
+    }
+}
+
+#ifndef PRODUCT
+
+
+SwTwips SwFtnFrm::GrowFrm( SwTwips nDist, const SzPtr pDirection,
+                           BOOL bTst, BOOL bInfo )
+{
+#ifdef DEBUG
+    static USHORT nNum = USHRT_MAX;
+    SwTxtFtn* pTxtFtn = GetAttr();
+    if ( pTxtFtn->GetFtn().GetNumber() == nNum )
+    {
+        int bla = 5;
+    }
+#endif
+    return SwLayoutFrm::GrowFrm( nDist, pDirection, bTst, bInfo );
+}
+
+
+
+SwTwips SwFtnFrm::ShrinkFrm( SwTwips nDist, const SzPtr pDirection,
+                                BOOL bTst, BOOL bInfo )
+{
+#ifdef DEBUG
+    static USHORT nNum = USHRT_MAX;
+    if( nNum != USHRT_MAX )
+    {
+        SwTxtFtn* pTxtFtn = GetAttr();
+        if( &pTxtFtn->GetAttr() && pTxtFtn->GetFtn().GetNumber() == nNum )
+        {
+            int bla = 5;
+        }
+    }
+#endif
+    return SwLayoutFrm::ShrinkFrm( nDist, pDirection, bTst, bInfo );
+}
+#endif
+
+/*************************************************************************
+|*
+|*  SwFtnFrm::Cut()
+|*
+|*  Ersterstellung      MA 23. Feb. 94
+|*  Letzte Aenderung    MA 24. Jul. 95
+|*
+|*************************************************************************/
+
+
+void SwFtnFrm::Cut()
+{
+    if ( GetNext() )
+        GetNext()->InvalidatePos();
+    else if ( GetPrev() )
+        GetPrev()->SetRetouche();
+
+    //Erst removen, dann Upper Shrinken.
+    SwLayoutFrm *pUp = GetUpper();
+
+    //Verkettung korrigieren.
+    SwFtnFrm *pFtn = (SwFtnFrm*)this;
+    if ( pFtn->GetFollow() )
+        pFtn->GetFollow()->SetMaster( pFtn->GetMaster() );
+    if ( pFtn->GetMaster() )
+        pFtn->GetMaster()->SetFollow( pFtn->GetFollow() );
+    pFtn->SetFollow( 0 );
+    pFtn->SetMaster( 0 );
+
+    // Alle Verbindungen kappen.
+    Remove();
+
+    if ( pUp )
+    {
+        //Die letzte Fussnote nimmt ihren Container mit.
+        if ( !pUp->Lower() )
+        {
+            SwPageFrm *pPage = pUp->FindPageFrm();
+            if ( pPage )
+            {
+                SwLayoutFrm *pBody = pPage->FindBodyCont();
+                if ( !pBody->ContainsCntnt() )
+                    pPage->FindRootFrm()->SetSuperfluous();
+            }
+            SwSectionFrm* pSect = pUp->FindSctFrm();
+            pUp->Cut();
+            delete pUp;
+            // Wenn der letzte Fussnotencontainer aus einem spaltigen Bereich verschwindet,
+            // so kann dieser, falls er keinen Follow besitzt, zusammenschrumpfen.
+            if( pSect && !pSect->ToMaximize( FALSE ) && !pSect->IsColLocked() )
+                pSect->_InvalidateSize();
+        }
+        else
+        {   if ( Frm().Height() )
+                pUp->Shrink( Frm().Height(), pHeight );
+            pUp->SetCompletePaint();
+            pUp->InvalidatePage();
+        }
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFtnFrm::Paste()
+|*
+|*  Ersterstellung      MA 23. Feb. 94
+|*  Letzte Aenderung    MA 23. Feb. 94
+|*
+|*************************************************************************/
+
+
+void SwFtnFrm::Paste(  SwFrm* pParent, SwFrm* pSibling )
+{
+    ASSERT( pParent, "Kein Parent fuer Paste." );
+    ASSERT( pParent->IsLayoutFrm(), "Parent ist CntntFrm." );
+    ASSERT( pParent != this, "Bin selbst der Parent." );
+    ASSERT( pSibling != this, "Bin mein eigener Nachbar." );
+    ASSERT( !GetPrev() && !GetNext() && !GetUpper(),
+            "Bin noch irgendwo angemeldet." );
+
+    //In den Baum einhaengen.
+    InsertBefore( (SwLayoutFrm*)pParent, pSibling );
+
+    if( Frm().Width() != pParent->Prt().Width() )
+        _InvalidateSize();
+    _InvalidatePos();
+    SwPageFrm *pPage = FindPageFrm();
+    InvalidatePage( pPage );
+    if ( GetNext() )
+        GetNext()->_InvalidatePos();
+    if ( Frm().Height() )
+        pParent->Grow( Frm().Height(), pHeight );
+
+    //Wenn mein Vorgaenger mein Master ist und/oder wenn mein Nachfolger mein
+    //Follow ist so kann ich deren Inhalt uebernehmen und sie vernichten.
+    if ( GetPrev() && GetPrev() == GetMaster() )
+    {   ASSERT( SwFlowFrm::CastFlowFrm( GetPrev()->GetLower() ),
+                "Fussnote ohne Inhalt?" );
+        (SwFlowFrm::CastFlowFrm( GetPrev()->GetLower()))->
+            MoveSubTree( this, GetLower() );
+        SwFrm *pDel = GetPrev();
+        pDel->Cut();
+        delete pDel;
+    }
+    if ( GetNext() && GetNext() == GetFollow() )
+    {   ASSERT( SwFlowFrm::CastFlowFrm( GetNext()->GetLower() ),
+                "Fussnote ohne Inhalt?" );
+        (SwFlowFrm::CastFlowFrm( GetNext()->GetLower()))->MoveSubTree( this );
+        SwFrm *pDel = GetNext();
+        pDel->Cut();
+        delete pDel;
+    }
+#ifndef PRODUCT
+    SwDoc *pDoc = GetFmt()->GetDoc();
+    if ( GetPrev() )
+    {
+        ASSERT( lcl_FindFtnPos( pDoc, ((SwFtnFrm*)GetPrev())->GetAttr() ) <=
+                lcl_FindFtnPos( pDoc, GetAttr() ), "Prev ist not FtnPrev" );
+    }
+    if ( GetNext() )
+    {
+        ASSERT( lcl_FindFtnPos( pDoc, GetAttr() ) <=
+                lcl_FindFtnPos( pDoc, ((SwFtnFrm*)GetNext())->GetAttr() ),
+                "Next is not FtnNext" );
+    }
+#endif
+    InvalidateNxtFtnCnts( pPage );
+}
+
+/*************************************************************************
+|*
+|*  SwFrm::GetNextFtnLeaf()
+|*
+|*  Beschreibung        Liefert das naechste LayoutBlatt in den das
+|*      Frame gemoved werden kann.
+|*      Neue Seiten werden nur dann erzeugt, wenn der Parameter TRUE ist.
+|*  Ersterstellung      MA 16. Nov. 92
+|*  Letzte Aenderung    AMA 09. Nov. 98
+|*
+|*************************************************************************/
+
+
+SwLayoutFrm *SwFrm::GetNextFtnLeaf( MakePageType eMakePage )
+{
+    SwFtnBossFrm *pOldBoss = FindFtnBossFrm();
+    SwPageFrm* pOldPage = pOldBoss->FindPageFrm();
+    SwPageFrm* pPage;
+    SwFtnBossFrm *pBoss = pOldBoss->IsColumnFrm() ?
+        (SwFtnBossFrm*)pOldBoss->GetNext() : 0; // naechste Spalte, wenn vorhanden
+    if( pBoss )
+        pPage = NULL;
+    else
+    {
+        if( pOldBoss->GetUpper()->IsSctFrm() )
+        {   // Das kann nur in einem spaltigen Bereich sein
+            SwLayoutFrm* pNxt = pOldBoss->GetNextSctLeaf( eMakePage );
+            if( pNxt )
+            {
+                ASSERT( pNxt->IsColBodyFrm(), "GetNextFtnLeaf: Funny Leaf" );
+                pBoss = (SwFtnBossFrm*)pNxt->GetUpper();
+                pPage = pBoss->FindPageFrm();
+            }
+            else
+                return 0;
+        }
+        else
+        {
+            // naechste Seite
+            pPage = (SwPageFrm*)pOldPage->GetNext();
+            // Leerseiten ueberspringen
+            if( pPage && pPage->IsEmptyPage() )
+                pPage = (SwPageFrm*)pPage->GetNext();
+            pBoss = pPage;
+        }
+    }
+    // Was haben wir jetzt?
+    // pBoss != NULL, pPage==NULL => pBoss ist die auf der gleichen Seite folgende Spalte
+    // pBoss != NULL, pPage!=NULL => pBoss und pPage sind die folgende Seite (Empty uebersprungen)
+    // pBoss == NULL => pPage == NULL, es gibt keine folgende Seite
+
+    //Wenn die Fussnote bereits einen Follow hat brauchen wir nicht zu suchen.
+    //Wenn allerdings zwischen Ftn und Follow unerwuenschte Leerseiten/spalten
+    //herumlungern, so legen wir auf der naechstbesten Seite/Spalte einen weiteren
+    //Follow an, der Rest wird sich schon finden.
+    SwFtnFrm *pFtn = FindFtnFrm();
+    if ( pFtn && pFtn->GetFollow() )
+    {
+        SwFtnBossFrm* pTmpBoss = pFtn->GetFollow()->FindFtnBossFrm();
+        // Folgende Faelle werden hier erkannt und akzeptiert
+        // 1. Die FtnBosse sind benachbarte Seiten oder benachbarte Spalten
+        // 2. Der neue ist die erste Spalte der benachbarten Seite
+        // 3. Der neue ist die erste Spalte in einem Bereich in der naechsten Spalte/Seite
+        while( pTmpBoss != pBoss && pTmpBoss && !pTmpBoss->GetPrev() )
+            pTmpBoss = pTmpBoss->GetUpper()->FindFtnBossFrm();
+        if( pTmpBoss == pBoss )
+            return pFtn->GetFollow();
+    }
+
+    // Wenn wir keinen pBoss gefunden haben oder es sich um eine "falsche" Seite handelt,
+    // muss eine neue Seite her
+    if ( !pBoss || ( pPage && pPage->IsEndNotePage() && !pOldPage->IsEndNotePage() ) )
+    {
+        if ( eMakePage == MAKEPAGE_APPEND || eMakePage == MAKEPAGE_INSERT )
+        {
+            pBoss = InsertPage( pOldPage, pOldPage->IsFtnPage() );
+            ((SwPageFrm*)pBoss)->SetEndNotePage( pOldPage->IsEndNotePage() );
+        }
+        else
+            return 0;
+    }
+    if( pBoss->IsPageFrm() )
+    {   // Wenn wir auf einer spaltigen Seite gelandet sind,
+        // gehen wir in die erste Spalte
+        SwLayoutFrm* pLay = pBoss->FindBodyCont();
+        if( pLay && pLay->Lower() && pLay->Lower()->IsColumnFrm() )
+            pBoss = (SwFtnBossFrm*)pLay->Lower();
+    }
+    //Seite/Spalte gefunden, da schummeln wir uns doch gleich mal 'rein
+    SwFtnContFrm *pCont = pBoss->FindFtnCont();
+    if ( !pCont && pBoss->GetMaxFtnHeight() &&
+         ( eMakePage == MAKEPAGE_APPEND || eMakePage == MAKEPAGE_INSERT ) )
+        pCont = pBoss->MakeFtnCont();
+    return pCont;
+}
+
+/*************************************************************************
+|*
+|*  SwFrm::GetPrevFtnLeaf()
+|*
+|*  Beschreibung        Liefert das vorhergehende LayoutBlatt in das der
+|*      Frame gemoved werden kann.
+|*  Ersterstellung      MA 16. Nov. 92
+|*  Letzte Aenderung    AMA 06. Nov. 98
+|*
+|*************************************************************************/
+
+
+SwLayoutFrm *SwFrm::GetPrevFtnLeaf( MakePageType eMakeFtn )
+{
+    //Der Vorgaenger fuer eine Fussnote ist falls moeglich der Master
+    //in der Fussnoteneigenen Verkettung.
+    SwLayoutFrm *pRet = 0;
+    SwFtnFrm *pFtn = FindFtnFrm();
+    pRet = pFtn->GetMaster();
+
+    SwFtnBossFrm* pOldBoss = FindFtnBossFrm();
+    SwPageFrm *pOldPage = pOldBoss->FindPageFrm();
+
+    if ( !pOldBoss->GetPrev() && !pOldPage->GetPrev() )
+        return pRet; // es gibt weder eine Spalte noch eine Seite vor uns
+
+    if ( !pRet )
+    {
+        BOOL bEndn = pFtn->GetAttr()->GetFtn().IsEndNote();
+        SwFrm* pTmpRef = NULL;
+        if( bEndn && pFtn->IsInSct() )
+        {
+            SwSectionFrm* pSect = pFtn->FindSctFrm();
+            if( pSect->IsEndnAtEnd() )
+                pTmpRef = pSect->FindLastCntnt( FINDMODE_LASTCNT );
+        }
+        if( !pTmpRef )
+            pTmpRef = pFtn->GetRef();
+        SwFtnBossFrm* pStop = pTmpRef->FindFtnBossFrm( !bEndn );
+
+        const USHORT nNum = pStop->GetPhyPageNum();
+
+        //Wenn die Fussnoten am Dokumentende angezeigt werden, so verlassen wir
+        //die Entsprechenden Seiten nicht.
+        //Selbiges gilt analog fuer die Endnotenseiten.
+        const FASTBOOL bEndNote = pOldPage->IsEndNotePage();
+        const FASTBOOL bFtnEndDoc = pOldPage->IsFtnPage();
+        SwFtnBossFrm* pNxtBoss = pOldBoss;
+        SwSectionFrm *pSect = pNxtBoss->GetUpper()->IsSctFrm() ?
+                              (SwSectionFrm*)pNxtBoss->GetUpper() : 0;
+
+        do
+        {
+            if( pNxtBoss->IsColumnFrm() && pNxtBoss->GetPrev() )
+                pNxtBoss = (SwFtnBossFrm*)pNxtBoss->GetPrev();  // eine Spalte zurueck
+            else                                // oder eine Seite zurueck
+            {
+                SwLayoutFrm* pBody;
+                if( pSect )
+                {
+                    if( pSect->IsFtnLock() )
+                    {
+                        if( pNxtBoss == pOldBoss )
+                            return 0;
+                        pStop = pNxtBoss;
+                    }
+                    else
+                    {
+                        pSect = pSect->FindMaster();
+                        if( !pSect || !pSect->Lower() )
+                            return 0;
+                        ASSERT( pSect->Lower()->IsColumnFrm(),
+                                "GetPrevFtnLeaf: Where's the column?" );
+                        pNxtBoss = (SwFtnBossFrm*)pSect->Lower();
+                        pBody = pSect;
+                    }
+                }
+                else
+                {
+                    SwPageFrm* pPage = (SwPageFrm*)pNxtBoss->FindPageFrm()->GetPrev();
+                    if( !pPage || pPage->GetPhyPageNum() < nNum ||
+                        bEndNote != pPage->IsEndNotePage() || bFtnEndDoc != pPage->IsFtnPage() )
+                        return NULL; // Keine in Frage kommende Seite mehr gefunden
+                    pNxtBoss = pPage;
+                    pBody = pPage->FindBodyCont();
+                }
+                // Die vorherige Seite haben wir nun, ggf. sollten wir in die letzte Spalte
+                // der Seite wechseln
+                if( pBody )
+                {
+                    if ( pBody->Lower() && pBody->Lower()->IsColumnFrm() )
+                    {
+                        pNxtBoss = (SwFtnBossFrm*)pBody->Lower();
+                        while( pNxtBoss->GetNext() ) // letzte Spalte suchen
+                            pNxtBoss = (SwFtnBossFrm*)pNxtBoss->GetNext();
+                    }
+                }
+            }
+            SwFtnContFrm *pCont = pNxtBoss->FindFtnCont();
+            if ( pCont )
+            {
+                pRet = pCont;
+                break;
+            }
+            if ( pStop == pNxtBoss )
+            {   //Die Seite/Spalte auf der sich auch die Referenz tummelt, ist erreicht.
+                //Wir koennen jetzt probehalber mal einen Container erzeugen und
+                //uns hineinpasten.
+                if ( eMakeFtn == MAKEPAGE_FTN && pNxtBoss->GetMaxFtnHeight() )
+                    pRet = pNxtBoss->MakeFtnCont();
+                break;
+            }
+        } while( !pRet );
+    }
+    if ( pRet )
+    {
+        const SwFtnBossFrm* pNewBoss = pRet->FindFtnBossFrm();
+        BOOL bJump = FALSE;
+        if( pOldBoss->IsColumnFrm() && pOldBoss->GetPrev() ) // es gibt eine vorherige Spalte
+            bJump = pOldBoss->GetPrev() != (SwFrm*)pNewBoss;         // sind wir darin gelandet?
+        else if( pNewBoss->IsColumnFrm() && pNewBoss->GetNext() )
+            bJump = TRUE; // es gibt hinter dem neuen Boss noch eine Spalte, die aber nicht
+                          // der alte Boss sein kann, das haben wir ja bereits geprueft.
+        else // hier landen wir nur, wenn neuer und alter Boss entweder Seiten oder letzte (neu)
+        {   // bzw. erste (alt) Spalten einer Seite sind. In diesem Fall muss noch geprueft
+            // werden, ob Seiten ueberspringen wurden.
+            USHORT nDiff = pOldPage->GetPhyPageNum() - pRet->FindPageFrm()->GetPhyPageNum();
+            if ( nDiff > 2 ||
+                 (nDiff > 1 && !((SwPageFrm*)pOldPage->GetPrev())->IsEmptyPage()) )
+                bJump = TRUE;
+        }
+        if( bJump )
+            SwFlowFrm::SetMoveBwdJump( TRUE );
+    }
+    return pRet;
+}
+
+/*************************************************************************
+|*
+|*  SwFrm::IsFtnAllowed()
+|*
+|*  Ersterstellung      MA 22. Mar. 94
+|*  Letzte Aenderung    MA 01. Dec. 94
+|*
+|*************************************************************************/
+
+
+BOOL SwFrm::IsFtnAllowed() const
+{
+    if ( !IsInDocBody() )
+        return FALSE;
+
+    if ( IsInTab() )
+    {
+        //Keine Ftns in wiederholten Headlines.
+        const SwTabFrm *pTab = ((SwFrm*)this)->ImplFindTabFrm();
+        if ( pTab->GetTable()->IsHeadlineRepeat() && pTab->IsFollow() )
+            return !((SwLayoutFrm*)pTab->Lower())->IsAnLower( this );
+    }
+    return TRUE;
+}
+
+/*************************************************************************
+|*
+|*  SwRootFrm::UpdateFtnNums()
+|*
+|*  Ersterstellung      MA 02. Mar. 93
+|*  Letzte Aenderung    MA 09. Dec. 97
+|*
+|*************************************************************************/
+
+
+void SwRootFrm::UpdateFtnNums()
+{
+    //Seitenweise Numerierung nur wenn es am Dokument so eingestellt ist.
+    if ( GetFmt()->GetDoc()->GetFtnInfo().eNum == FTNNUM_PAGE )
+    {
+        SwPageFrm *pPage = (SwPageFrm*)Lower();
+        while ( pPage && !pPage->IsFtnPage() )
+        {
+            pPage->UpdateFtnNum();
+            pPage = (SwPageFrm*)pPage->GetNext();
+        }
+    }
+}
+
+/*************************************************************************
+|*
+|*  RemoveFtns()        Entfernen aller Fussnoten (nicht etwa die Referenzen)
+|*                      und Entfernen aller Fussnotenseiten.
+|*
+|*  Ersterstellung      MA 05. Dec. 97
+|*  Letzte Aenderung    AMA 06. Nov. 98
+|*
+|*************************************************************************/
+
+void lcl_RemoveFtns( SwFtnBossFrm* pBoss, BOOL bPageOnly, BOOL bEndNotes )
+{
+    do
+    {
+        SwFtnContFrm *pCont = pBoss->FindFtnCont();
+        if ( pCont )
+        {
+            SwFtnFrm *pFtn = (SwFtnFrm*)pCont->Lower();
+            ASSERT( pFtn, "FtnCont ohne Ftn." );
+            if ( bPageOnly )
+                while ( pFtn->GetMaster() )
+                    pFtn = pFtn->GetMaster();
+            do
+            {
+                SwFtnFrm *pNxt = (SwFtnFrm*)pFtn->GetNext();
+                if ( !pFtn->GetAttr()->GetFtn().IsEndNote() ||
+                        bEndNotes )
+                {
+                    pFtn->GetRef()->Prepare( PREP_FTN, (void*)pFtn->GetAttr() );
+                    if ( bPageOnly && !pNxt )
+                        pNxt = pFtn->GetFollow();
+                    pFtn->Cut();
+                    delete pFtn;
+                }
+                pFtn = pNxt;
+
+            } while ( pFtn );
+        }
+        else if( !pBoss->IsInSct() )
+        {
+            // A sectionframe with the Ftn/EndnAtEnd-flags may contain
+            // foot/endnotes. If the last lower frame of the bodyframe is
+            // a multicolumned sectionframe, it may contain footnotes, too.
+            SwLayoutFrm* pBody = pBoss->FindBodyCont();
+            if( pBody && pBody->Lower() )
+            {
+                SwFrm* pLow = pBody->Lower();
+                while( pLow->GetNext() )
+                {
+                    if( pLow->IsSctFrm() && ( !pLow->GetNext() ||
+                        ((SwSectionFrm*)pLow)->IsAnyNoteAtEnd() ) &&
+                        ((SwSectionFrm*)pLow)->Lower() &&
+                        ((SwSectionFrm*)pLow)->Lower()->IsColumnFrm() )
+                        lcl_RemoveFtns( (SwColumnFrm*)((SwSectionFrm*)pLow)->Lower(),
+                            bPageOnly, bEndNotes );
+                    pLow = pLow->GetNext();
+                }
+            }
+        }
+        // noch 'ne Spalte?
+        pBoss = pBoss->IsColumnFrm() ? (SwColumnFrm*)pBoss->GetNext() : NULL;
+    } while( pBoss );
+}
+
+void SwRootFrm::RemoveFtns( SwPageFrm *pPage, BOOL bPageOnly, BOOL bEndNotes )
+{
+    if ( !pPage )
+        pPage = (SwPageFrm*)Lower();
+
+    do
+    {   // Bei spaltigen Seiten muessen wir in allen Spalten aufraeumen
+        SwFtnBossFrm* pBoss;
+        SwLayoutFrm* pBody = pPage->FindBodyCont();
+        if( pBody && pBody->Lower() && pBody->Lower()->IsColumnFrm() )
+            pBoss = (SwFtnBossFrm*)pBody->Lower(); // die erste Spalte
+        else
+            pBoss = pPage; // keine Spalten
+        lcl_RemoveFtns( pBoss, bPageOnly, bEndNotes );
+        if ( !bPageOnly )
+        {
+            if ( pPage->IsFtnPage() &&
+                 (!pPage->IsEndNotePage() || bEndNotes) )
+            {
+                SwFrm *pDel = pPage;
+                pPage = (SwPageFrm*)pPage->GetNext();
+                pDel->Cut();
+                delete pDel;
+            }
+            else
+                pPage = (SwPageFrm*)pPage->GetNext();
+        }
+        else
+            break;
+
+    } while ( pPage );
+}
+
+/*************************************************************************
+|*
+|*  SetFtnPageDescs()   Seitenvorlagen der Fussnotenseiten aendern
+|*
+|*  Ersterstellung      MA 11. Dec. 97
+|*  Letzte Aenderung    MA 11. Dec. 97
+|*
+|*************************************************************************/
+
+void SwRootFrm::CheckFtnPageDescs( BOOL bEndNote )
+{
+    SwPageFrm *pPage = (SwPageFrm*)Lower();
+    while ( pPage && !pPage->IsFtnPage() )
+        pPage = (SwPageFrm*)pPage->GetNext();
+    while ( pPage && pPage->IsEndNotePage() != bEndNote )
+        pPage = (SwPageFrm*)pPage->GetNext();
+    if ( pPage )
+        SwFrm::CheckPageDescs( pPage, FALSE );
+}
+
+
+/*************************************************************************
+|*
+|*  SwFtnBossFrm::MakeFtnCont()
+|*
+|*  Ersterstellung      MA 25. Feb. 93
+|*  Letzte Aenderung    AMA 29. Oct. 98
+|*
+|*************************************************************************/
+
+
+SwFtnContFrm *SwFtnBossFrm::MakeFtnCont()
+{
+    //Einfuegen eines Fussnotencontainers. Der Fussnotencontainer sitzt
+    //immer direkt hinter dem Bodytext.
+    //Sein FrmFmt ist immer das DefaultFrmFmt.
+
+#ifndef PRODUCT
+    if ( FindFtnCont() )
+    {   ASSERT( !this, "Fussnotencontainer bereits vorhanden." );
+        return 0;
+    }
+#endif
+
+    SwFtnContFrm *pNew = new SwFtnContFrm( GetFmt()->GetDoc()->GetDfltFrmFmt());
+    SwLayoutFrm *pLay = FindBodyCont();
+    pNew->Paste( this, pLay->GetNext() );
+    return pNew;
+}
+
+/*************************************************************************
+|*
+|*  SwFtnBossFrm::FindFtnCont()
+|*
+|*  Ersterstellung      MA 25. Feb. 93
+|*  Letzte Aenderung    AMA 29. Oct. 98
+|*
+|*************************************************************************/
+
+
+SwFtnContFrm *SwFtnBossFrm::FindFtnCont()
+{
+    SwFrm *pFrm = Lower();
+    while( pFrm && !pFrm->IsFtnContFrm() )
+        pFrm = pFrm->GetNext();
+
+#ifndef PRODUCT
+    if ( pFrm )
+    {
+        SwFrm *pFtn = pFrm->GetLower();
+        ASSERT( pFtn, "Cont ohne Fussnote." );
+        while ( pFtn )
+        {
+            ASSERT( pFtn->IsFtnFrm(), "Nachbar von Fussnote keine Fussnote." );
+            pFtn = pFtn->GetNext();
+        }
+    }
+#endif
+
+    return (SwFtnContFrm*)pFrm;
+}
+
+/*************************************************************************
+|*
+|*  SwFtnBossFrm::FindNearestFtnCont()  Sucht den naechst greifbaren Fussnotencontainer.
+|*
+|*  Ersterstellung      MA 02. Aug. 93
+|*  Letzte Aenderung    AMA 29. Oct. 98
+|*
+|*************************************************************************/
+
+SwFtnContFrm *SwFtnBossFrm::FindNearestFtnCont( BOOL bDontLeave )
+{
+    SwFtnContFrm *pCont = 0;
+    if ( GetFmt()->GetDoc()->GetFtnIdxs().Count() )
+    {
+        pCont = FindFtnCont();
+        if ( !pCont )
+        {
+            SwPageFrm *pPage = FindPageFrm();
+            SwFtnBossFrm* pBoss = this;
+            BOOL bEndNote = pPage->IsEndNotePage();
+            do
+            {
+                BOOL bChgPage = lcl_NextFtnBoss( pBoss, pPage, bDontLeave );
+                // Haben wir noch einen Boss gefunden? Bei einem Seitenwechsel muss
+                // zudem noch das EndNotenFlag uebereinstimmen
+                if( pBoss && ( !bChgPage || pPage->IsEndNotePage() == bEndNote ) )
+                    pCont = pBoss->FindFtnCont();
+            } while ( !pCont && pPage );
+        }
+    }
+    return pCont;
+}
+
+
+/*************************************************************************
+|*
+|*  SwFtnBossFrm::FindFirstFtn()
+|*
+|*  Beschreibung        Erste Fussnote des Fussnotenbosses suchen.
+|*  Ersterstellung      MA 26. Feb. 93
+|*  Letzte Aenderung    AMA 29. Oct. 99
+|*
+|*************************************************************************/
+
+
+SwFtnFrm *SwFtnBossFrm::FindFirstFtn()
+{
+    //Erstmal den naechsten FussnotenContainer suchen.
+    SwFtnContFrm *pCont = FindNearestFtnCont();
+    if ( !pCont )
+        return 0;
+
+    //Ab der ersten Fussnote im Container die erste suchen, die
+    //von der aktuellen Spalte (bzw. einspaltigen Seite) referenziert wird.
+
+    SwFtnFrm *pRet = (SwFtnFrm*)pCont->Lower();
+    const USHORT nRefNum = FindPageFrm()->GetPhyPageNum();
+    const USHORT nRefCol = lcl_ColumnNum( this );
+    USHORT nPgNum, nColNum; //Seitennummer, Spaltennummer
+    SwFtnBossFrm* pBoss;
+    SwPageFrm* pPage;
+    if( pRet )
+    {
+        pBoss = pRet->GetRef()->FindFtnBossFrm();
+        ASSERT( pBoss, "FindFirstFtn: No boss found" );
+        if( !pBoss )
+            return FALSE; // ´There must be a bug, but no GPF
+        pPage = pBoss->FindPageFrm();
+        nPgNum = pPage->GetPhyPageNum();
+        if ( nPgNum == nRefNum )
+        {
+            nColNum = lcl_ColumnNum( pBoss );
+            if( nColNum == nRefCol )
+                return pRet; //hat ihn.
+            else if( nColNum > nRefCol )
+                return NULL; //mind. eine Spalte zu weit.
+        }
+        else if ( nPgNum > nRefNum )
+            return NULL;    //mind. eine Seite zu weit.
+    }
+    else
+        return NULL;
+    // Ende, wenn Ref auf einer spaeteren Seite oder auf der gleichen Seite in einer
+    // spaeteren Spalte liegt
+
+    do
+    {
+        while ( pRet->GetFollow() )
+            pRet = pRet->GetFollow();
+
+        SwFtnFrm *pNxt = (SwFtnFrm*)pRet->GetNext();
+        if ( !pNxt )
+        {
+            pBoss = pRet->FindFtnBossFrm();
+            pPage = pBoss->FindPageFrm();
+            lcl_NextFtnBoss( pBoss, pPage, FALSE ); // naechster FtnBoss
+            pCont = pBoss ? pBoss->FindNearestFtnCont() : 0;
+            if ( pCont )
+                pNxt = (SwFtnFrm*)pCont->Lower();
+        }
+        if ( pNxt )
+        {
+            pRet = pNxt;
+            pBoss = pRet->GetRef()->FindFtnBossFrm();
+            pPage = pBoss->FindPageFrm();
+            nPgNum = pPage->GetPhyPageNum();
+            if ( nPgNum == nRefNum )
+            {
+                nColNum = lcl_ColumnNum( pBoss );
+                if( nColNum == nRefCol )
+                    break; //hat ihn.
+                else if( nColNum > nRefCol )
+                    pRet = 0; //mind. eine Spalte zu weit.
+            }
+            else if ( nPgNum > nRefNum )
+                pRet = 0;   //mind. eine Seite zu weit.
+        }
+        else
+            pRet = 0;   //Gibt eben keinen.
+    } while( pRet );
+    return pRet;
+}
+
+/*************************************************************************
+|*
+|*  SwFtnBossFrm::FindFirstFtn()
+|*
+|*  Beschreibunt        Erste Fussnote zum Cnt suchen.
+|*  Ersterstellung      MA 04. Mar. 93
+|*  Letzte Aenderung    AMA 28. Oct. 98
+|*
+|*************************************************************************/
+
+
+const SwFtnFrm *SwFtnBossFrm::FindFirstFtn( SwCntntFrm *pCnt ) const
+{
+    const SwFtnFrm *pRet = ((SwFtnBossFrm*)this)->FindFirstFtn();
+    if ( pRet )
+    {
+        const USHORT nColNum = lcl_ColumnNum( this ); //Spaltennummer
+        const USHORT nPageNum = GetPhyPageNum();
+        while ( pRet && (pRet->GetRef() != pCnt) )
+        {
+            while ( pRet->GetFollow() )
+                pRet = pRet->GetFollow();
+
+            if ( pRet->GetNext() )
+                pRet = (const SwFtnFrm*)pRet->GetNext();
+            else
+            {   SwFtnBossFrm *pBoss = (SwFtnBossFrm*)pRet->FindFtnBossFrm();
+                SwPageFrm *pPage = pBoss->FindPageFrm();
+                lcl_NextFtnBoss( pBoss, pPage, FALSE ); // naechster FtnBoss
+                SwFtnContFrm *pCont = pBoss ? pBoss->FindNearestFtnCont() : 0;
+                pRet = pCont ? (SwFtnFrm*)pCont->Lower() : 0;
+            }
+            if ( pRet )
+            {
+                const SwFtnBossFrm* pBoss = pRet->GetRef()->FindFtnBossFrm();
+                if( pBoss->GetPhyPageNum() != nPageNum ||
+                    nColNum != lcl_ColumnNum( pBoss ) )
+                pRet = 0;
+            }
+        }
+    }
+    return pRet;
+}
+
+/*************************************************************************
+|*
+|*  SwFtnBossFrm::ResetFtn()
+|*
+|*  Ersterstellung      MA 11. May. 95
+|*  Letzte Aenderung    AMA 29. Oct. 98
+|*
+|*************************************************************************/
+
+
+void SwFtnBossFrm::ResetFtn( const SwFtnFrm *pCheck )
+{
+    //Vernichten der Inkarnationen von Fussnoten zum Attribut, wenn sie nicht
+    //zu pAssumed gehoeren.
+    ASSERT( !pCheck->GetMaster(), "Master not an Master." );
+
+    SwNodeIndex aIdx( *pCheck->GetAttr()->GetStartNode(), 1 );
+    SwCntntNode *pNd = aIdx.GetNode().GetCntntNode();
+    if ( !pNd )
+        pNd = pCheck->GetFmt()->GetDoc()->
+              GetNodes().GoNextSection( &aIdx, TRUE, FALSE );
+    SwClientIter aIter( *pNd );
+    SwClient* pLast = aIter.GoStart();
+    while( pLast )
+    {
+        if ( pLast->ISA(SwFrm) )
+        {
+            SwFrm *pFrm = (SwFrm*)pLast;
+            SwFrm *pTmp = pFrm->GetUpper();
+            while ( pTmp && !pTmp->IsFtnFrm() )
+                pTmp = pTmp->GetUpper();
+
+            SwFtnFrm *pFtn = (SwFtnFrm*)pTmp;
+            while ( pFtn && pFtn->GetMaster() )
+                pFtn = pFtn->GetMaster();
+            if ( pFtn != pCheck )
+            {
+                while ( pFtn )
+                {
+                    SwFtnFrm *pNxt = pFtn->GetFollow();
+                    pFtn->Cut();
+                    delete pFtn;
+                    pFtn = pNxt;
+                }
+            }
+        }
+        pLast = ++aIter;
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFtnBossFrm::InsertFtn()
+|*
+|*  Ersterstellung      MA 26. Feb. 93
+|*  Letzte Aenderung    AMA 29. Oct. 98
+|*
+|*************************************************************************/
+
+
+void SwFtnBossFrm::InsertFtn( SwFtnFrm* pNew )
+{
+#if defined(DEBUG) && !defined(PRODUCT)
+    static USHORT nStop = 0;
+    if ( nStop == pNew->GetFrmId() )
+    {
+        int bla = 5;
+    }
+#endif
+    //Die Fussnote haben wir, sie muss jetzt nur noch irgendwo
+    //hin und zwar vor die Fussnote, deren Attribut vor das
+    //der neuen zeigt (Position wird ueber das Doc ermittelt)
+    //Gibt es in diesem Fussnotenboss noch keine Fussnoten, so muss eben ein
+    //Container erzeugt werden.
+    //Gibt es bereits einen Container aber noch keine Fussnote zu diesem
+    //Fussnotenboss, so muss die Fussnote hinter die letzte Fussnote der dichtesten
+    //Vorseite/spalte.
+
+    ResetFtn( pNew );
+    SwFtnFrm *pSibling = FindFirstFtn();
+    BOOL bDontLeave = FALSE;
+
+    // Ok, a sibling has been found, but is the sibling in an acceptable
+    // environment?
+    if( IsInSct() )
+    {
+        SwSectionFrm* pMySect = ImplFindSctFrm();
+        BOOL bEndnt = pNew->GetAttr()->GetFtn().IsEndNote();
+        if( bEndnt )
+        {
+            const SwSectionFmt* pEndFmt = pMySect->GetEndSectFmt();
+            bDontLeave = 0 != pEndFmt;
+            if( pSibling )
+            {
+                if( pEndFmt )
+                {
+                    if( !pSibling->IsInSct() ||
+                        !pSibling->ImplFindSctFrm()->IsDescendantFrom( pEndFmt ) )
+                        pSibling = NULL;
+                }
+                else if( pSibling->IsInSct() )
+                    pSibling = NULL;
+            }
+        }
+        else
+        {
+            bDontLeave = pMySect->IsFtnAtEnd();
+            if( pSibling )
+            {
+                if( pMySect->IsFtnAtEnd() )
+                {
+                    if( !pSibling->IsInSct() ||
+                        !pMySect->IsAnFollow( pSibling->ImplFindSctFrm() ) )
+                        pSibling = NULL;
+                }
+                else if( pSibling->IsInSct() )
+                    pSibling = NULL;
+            }
+        }
+    }
+
+    if( pSibling && pSibling->FindPageFrm()->IsEndNotePage() !=
+        FindPageFrm()->IsEndNotePage() )
+        pSibling = NULL;
+
+    //Damit die Position herausgefunden werden kann.
+    SwDoc *pDoc = GetFmt()->GetDoc();
+    const ULONG nStPos = ::lcl_FindFtnPos( pDoc, pNew->GetAttr() );
+
+    ULONG nCmpPos, nLastPos;
+    SwFtnContFrm *pParent = 0;
+    if( pSibling )
+    {
+        nCmpPos = ::lcl_FindFtnPos( pDoc, pSibling->GetAttr() );
+        if( nCmpPos > nStPos )
+            pSibling = NULL;
+    }
+
+    if ( !pSibling )
+    {   pParent = FindFtnCont();
+        if ( !pParent )
+        {
+            //Es gibt noch keinen FussnotenContainer, also machen wir einen.
+            //HAAAAAAAALT! So einfach ist das leider mal wieder nicht: Es kann
+            //sein, dass irgendeine naechste Fussnote existiert die vor der
+            //einzufuegenden zu stehen hat, weil z.B. eine Fussnote ueber zig
+            //Seiten aufgespalten ist usw.
+            pParent = FindNearestFtnCont( bDontLeave );
+            if ( pParent )
+            {
+                SwFtnFrm *pFtn = (SwFtnFrm*)pParent->Lower();
+                if ( pFtn )
+                {
+
+                    nCmpPos = ::lcl_FindFtnPos( pDoc, pFtn->GetAttr() );
+                    if ( nCmpPos > nStPos )
+                        pParent = 0;
+                }
+                else
+                    pParent = 0;
+            }
+        }
+        if ( !pParent )
+            //Jetzt kann aber ein Fussnotencontainer gebaut werden.
+            pParent = MakeFtnCont();
+        else
+        {
+            //Ausgehend von der ersten Fussnote unterhalb des Parents wird die
+            //erste Fussnote gesucht deren Index hinter dem Index der
+            //einzufuegenden liegt; vor dieser kann der neue dann gepastet
+            //werden.
+            pSibling = (SwFtnFrm*)pParent->Lower();
+            if ( !pSibling )
+            {   ASSERT( !this, "Keinen Platz fuer Fussnote gefunden.");
+                return;
+            }
+            nCmpPos  = ::lcl_FindFtnPos( pDoc, pSibling->GetAttr() );
+
+            SwFtnBossFrm *pNxtB = this; //Immer den letzten merken, damit wir nicht
+            SwFtnFrm  *pLastSib = 0;    //ueber das Ziel hinausschiessen.
+
+            while ( pSibling && nCmpPos <= nStPos )
+            {
+                pLastSib = pSibling; // der kommt schon mal in Frage
+                nLastPos = nCmpPos;
+
+                while ( pSibling->GetFollow() )
+                    pSibling = pSibling->GetFollow();
+
+                if ( pSibling->GetNext() )
+                {
+                    pSibling = (SwFtnFrm*)pSibling->GetNext();
+                    ASSERT( !pSibling->GetMaster() || ( ENDNOTE > nStPos &&
+                            pSibling->GetAttr()->GetFtn().IsEndNote() ),
+                            "InsertFtn: Master expected I" );
+                }
+                else
+                {
+                    pNxtB = pSibling->FindFtnBossFrm();
+                    SwPageFrm *pSibPage = pNxtB->FindPageFrm();
+                    BOOL bEndNote = pSibPage->IsEndNotePage();
+                    BOOL bChgPage = lcl_NextFtnBoss( pNxtB, pSibPage, bDontLeave );
+                    // Bei Seitenwechsel muss das EndNoteFlag ueberprueft werden.
+                    SwFtnContFrm *pCont = pNxtB && ( !bChgPage ||
+                        pSibPage->IsEndNotePage() == bEndNote )
+                        ? pNxtB->FindNearestFtnCont( bDontLeave ) : 0;
+                    if( pCont )
+                        pSibling = (SwFtnFrm*)pCont->Lower();
+                    else // kein weiterer FtnContainer, dann werden  wir uns wohl hinter
+                        break; // pSibling haengen
+                }
+                if ( pSibling )
+                {
+                    nCmpPos = ::lcl_FindFtnPos( pDoc, pSibling->GetAttr() );
+                    ASSERT( nCmpPos > nLastPos, "InsertFtn: Order of FtnFrm's buggy" );
+                }
+            }
+            // pLastSib ist jetzt die letzte Fussnote vor uns,
+            // pSibling leer oder die erste nach uns.
+            if ( pSibling && pLastSib && (pSibling != pLastSib) )
+            {   //Sind wir vielleicht bereits ueber das Ziel hinausgeschossen?
+                if ( nCmpPos > nStPos )
+                    pSibling = pLastSib;
+            }
+            else if ( !pSibling )
+            {   //Eine Chance haben wir noch: wir nehmen einfach die letzte
+                //Fussnote im Parent. Ein Sonderfall, der z.B. beim
+                //zurueckfliessen von Absaetzen mit mehreren Fussnoten
+                //vorkommt.
+                //Damit wir nicht die Reihenfolge verwuerfeln muessen wir den
+                //Parent der letzten Fussnote, die wir an der Hand hatten benutzen.
+                pSibling = pLastSib;
+                while( pSibling->GetFollow() )
+                    pSibling = pSibling->GetFollow();
+                ASSERT( !pSibling->GetNext(), "InsertFtn: Who's that guy?" );
+            }
+        }
+    }
+    else
+    {   //Die erste Fussnote der Spalte/Seite haben wir an der Hand, jetzt ausgehend
+        //von dieser die erste zur selben Spalte/Seite suchen deren Index hinter
+        //den uebergebenen zeigt, die letzte, die wir an der Hand hatten, ist
+        //dann der Vorgaenger.
+        SwFtnBossFrm* pBoss = pNew->GetRef()->FindFtnBossFrm(
+            !pNew->GetAttr()->GetFtn().IsEndNote() );
+        USHORT nRefNum = pBoss->GetPhyPageNum();    // Die Seiten- und
+        USHORT nRefCol = lcl_ColumnNum( pBoss );    // Spaltennummer der neuen Fussnote
+        BOOL bEnd = FALSE;
+        SwFtnFrm *pLastSib = 0;
+        while ( pSibling && !bEnd && (nCmpPos <= nStPos) )
+        {
+            pLastSib = pSibling;
+            nLastPos = nCmpPos;
+
+            while ( pSibling->GetFollow() )
+                pSibling = pSibling->GetFollow();
+
+            SwFtnFrm *pFoll = (SwFtnFrm*)pSibling->GetNext();
+            if ( pFoll )
+            {
+                pBoss = pSibling->GetRef()->FindFtnBossFrm( !pSibling->
+                                            GetAttr()->GetFtn().IsEndNote() );
+                USHORT nTmpRef;
+                if( nStPos >= ENDNOTE ||
+                    (nTmpRef = pBoss->GetPhyPageNum()) < nRefNum ||
+                    ( nTmpRef == nRefNum && lcl_ColumnNum( pBoss ) <= nRefCol ))
+                    pSibling = pFoll;
+                else
+                    bEnd = TRUE;
+            }
+            else
+            {
+                SwFtnBossFrm* pNxtB = pSibling->FindFtnBossFrm();
+                SwPageFrm *pSibPage = pNxtB->FindPageFrm();
+                BOOL bEndNote = pSibPage->IsEndNotePage();
+                BOOL bChgPage = lcl_NextFtnBoss( pNxtB, pSibPage, bDontLeave );
+                // Bei Seitenwechsel muss das EndNoteFlag ueberprueft werden.
+                SwFtnContFrm *pCont = pNxtB && ( !bChgPage ||
+                    pSibPage->IsEndNotePage() == bEndNote )
+                    ? pNxtB->FindNearestFtnCont( bDontLeave ) : 0;
+                if ( pCont )
+                    pSibling = (SwFtnFrm*)pCont->Lower();
+                else
+                    bEnd = TRUE;
+            }
+            if ( !bEnd && pSibling )
+                nCmpPos = ::lcl_FindFtnPos( pDoc, pSibling->GetAttr() );
+            if ( pSibling && pLastSib && (pSibling != pLastSib) )
+            {   //Sind wir vielleicht bereits ueber das Ziel hinausgeschossen?
+                if ( (nLastPos < nCmpPos) && (nCmpPos > nStPos) )
+                {
+                    pSibling = pLastSib;
+                    bEnd = TRUE;
+                }
+            }
+        }
+    }
+    if ( pSibling )
+    {
+        nCmpPos = ::lcl_FindFtnPos( pDoc, pSibling->GetAttr() );
+        if ( nCmpPos < nStPos )
+        {
+            while ( pSibling->GetFollow() )
+                pSibling = pSibling->GetFollow();
+            pParent = (SwFtnContFrm*)pSibling->GetUpper();
+            pSibling = (SwFtnFrm*)pSibling->GetNext();
+        }
+        else
+        {
+            if( pSibling->GetMaster() )
+            {
+                if( ENDNOTE > nCmpPos || nStPos >= ENDNOTE )
+                {
+                    ASSERT( FALSE, "InsertFtn: Master expected II" );
+                    do
+                        pSibling = pSibling->GetMaster();
+                    while ( pSibling->GetMaster() );
+                }
+            }
+            pParent = (SwFtnContFrm*)pSibling->GetUpper();
+        }
+    }
+    ASSERT( pParent, "paste in space?" );
+    pNew->Paste( pParent, pSibling );
+}
+
+/*************************************************************************
+|*
+|*  SwFtnBossFrm::AppendFtn()
+|*
+|*  Ersterstellung      MA 25. Feb. 93
+|*  Letzte Aenderung    AMA 29. Oct. 98
+|*
+|*************************************************************************/
+
+
+void SwFtnBossFrm::AppendFtn( SwCntntFrm *pRef, SwTxtFtn *pAttr )
+{
+    //Wenn es die Fussnote schon gibt tun wir nix.
+    if ( FindFtn( pRef, pAttr ) )
+        return;
+
+    //Wenn Fussnoten am Dokumentende eingestellt sind, so brauchen wir 'eh erst
+    //ab der entsprechenden Seite zu suchen.
+    //Wenn es noch keine gibt, muss eben eine erzeugt werden.
+    //Wenn es sich um eine Endnote handelt, muss eine Endnotenseite gesucht
+    //bzw. erzeugt werden.
+    SwDoc *pDoc = GetFmt()->GetDoc();
+    SwFtnBossFrm *pBoss = this;
+    SwPageFrm *pPage = FindPageFrm();
+    SwPageFrm *pMyPage = pPage;
+    BOOL bChgPage = FALSE;
+    BOOL bEnd = FALSE;
+    if ( pAttr->GetFtn().IsEndNote() )
+    {
+        bEnd = TRUE;
+        if( GetUpper()->IsSctFrm() &&
+            ((SwSectionFrm*)GetUpper())->IsEndnAtEnd() )
+        {
+            SwFrm* pLast =
+                ((SwSectionFrm*)GetUpper())->FindLastCntnt( FINDMODE_ENDNOTE );
+            if( pLast )
+            {
+                pBoss = pLast->FindFtnBossFrm();
+                pPage = pBoss->FindPageFrm();
+            }
+        }
+        else
+        {
+            while ( pPage->GetNext() && !pPage->IsEndNotePage() )
+            {
+                pPage = (SwPageFrm*)pPage->GetNext();
+                bChgPage = TRUE;
+            }
+            if ( !pPage->IsEndNotePage() )
+            {
+                SwPageDesc *pDesc = pDoc->GetEndNoteInfo().GetPageDesc( *pDoc );
+                BOOL bOdd = pPage->GetVirtPageNum() % 2 ? FALSE : TRUE;
+                pPage = ::InsertNewPage( *pDesc, pPage->GetUpper(), bOdd, TRUE, 0 );
+                pPage->SetEndNotePage( TRUE );
+                bChgPage = TRUE;
+            }
+            else
+            {
+                //Wir koennen wenigstens schon mal ungefaehr die richtige Seite
+                //suchen. Damit stellen wir sicher das wir auch bei hunderten
+                //Fussnoten noch in endlicher Zeit fertig werden.
+                SwPageFrm *pNxt = (SwPageFrm*)pPage->GetNext();
+                const ULONG nStPos = ::lcl_FindFtnPos( pDoc, pAttr );
+                while ( pNxt && pNxt->IsEndNotePage() )
+                {
+                    SwFtnContFrm *pCont = pNxt->FindFtnCont();
+                    if ( pCont && pCont->Lower() )
+                    {
+                        ASSERT( pCont->Lower()->IsFtnFrm(), "Keine Ftn im Container" );
+                        if ( nStPos > ::lcl_FindFtnPos( pDoc,
+                                        ((SwFtnFrm*)pCont->Lower())->GetAttr()))
+                        {
+                            pPage = pNxt;
+                            pNxt = (SwPageFrm*)pPage->GetNext();
+                            continue;
+                        }
+                    }
+                    break;
+                }
+            }
+        }
+    }
+    else if( FTNPOS_CHAPTER == pDoc->GetFtnInfo().ePos && ( !GetUpper()->
+             IsSctFrm() || !((SwSectionFrm*)GetUpper())->IsFtnAtEnd() ) )
+    {
+        while ( pPage->GetNext() && !pPage->IsFtnPage() &&
+                !((SwPageFrm*)pPage->GetNext())->IsEndNotePage() )
+        {
+            pPage = (SwPageFrm*)pPage->GetNext();
+            bChgPage = TRUE;
+        }
+
+        if ( !pPage->IsFtnPage() )
+        {
+            SwPageDesc *pDesc = pDoc->GetFtnInfo().GetPageDesc( *pDoc );
+            BOOL bOdd = pPage->GetVirtPageNum() % 2 ? FALSE : TRUE;
+            pPage = ::InsertNewPage( *pDesc, pPage->GetUpper(), bOdd, TRUE, pPage->GetNext() );
+            bChgPage = TRUE;
+        }
+        else
+        {
+            //Wir koennen wenigstens schon mal ungefaehr die richtige Seite
+            //suchen. Damit stellen wir sicher das wir auch bei hunderten
+            //Fussnoten noch in endlicher Zeit fertig werden.
+            SwPageFrm *pNxt = (SwPageFrm*)pPage->GetNext();
+            const ULONG nStPos = ::lcl_FindFtnPos( pDoc, pAttr );
+            while ( pNxt && pNxt->IsFtnPage() && !pNxt->IsEndNotePage() )
+            {
+                SwFtnContFrm *pCont = pNxt->FindFtnCont();
+                if ( pCont && pCont->Lower() )
+                {
+                    ASSERT( pCont->Lower()->IsFtnFrm(), "Keine Ftn im Container" );
+                    if ( nStPos > ::lcl_FindFtnPos( pDoc,
+                                        ((SwFtnFrm*)pCont->Lower())->GetAttr()))
+                    {
+                        pPage = pNxt;
+                        pNxt = (SwPageFrm*)pPage->GetNext();
+                        continue;
+                    }
+                }
+                break;
+            }
+        }
+    }
+
+    //Erstmal eine Fussnote und die benoetigten CntntFrms anlegen.
+    if ( !pAttr->GetStartNode() )
+    {   ASSERT( !this, "Kein Fussnoteninhalt." );
+        return;
+    }
+
+    // Wenn es auf der Seite/Spalte bereits einen FtnCont gibt,
+    // kann in einen spaltigen Bereich keiner erzeugt werden.
+    if( pBoss->IsInSct() && pBoss->IsColumnFrm() && !pPage->IsFtnPage() )
+    {
+        SwSectionFrm* pSct = pBoss->FindSctFrm();
+        if( bEnd ? !pSct->IsEndnAtEnd() : !pSct->IsFtnAtEnd() )
+        {
+            SwFtnContFrm* pFtnCont = pSct->FindFtnBossFrm(!bEnd)->FindFtnCont();
+            if( pFtnCont )
+            {
+                SwFtnFrm* pTmp = (SwFtnFrm*)pFtnCont->Lower();
+                if( bEnd )
+                    while( pTmp && !pTmp->GetAttr()->GetFtn().IsEndNote() )
+                        pTmp = (SwFtnFrm*)pTmp->GetNext();
+                if( pTmp && *pTmp < pAttr )
+                    return;
+            }
+        }
+    }
+
+    SwFtnFrm *pNew = new SwFtnFrm( pDoc->GetDfltFrmFmt(), pRef, pAttr );
+    {
+        SwNodeIndex aIdx( *pAttr->GetStartNode(), 1 );
+        ::_InsertCnt( pNew, pDoc, aIdx.GetIndex() );
+    }
+    // Wenn die Seite gewechselt (oder gar neu angelegt) wurde,
+    // muessen wir uns dort in die erste Spalte setzen
+    if( bChgPage )
+    {
+        SwLayoutFrm* pBody = pPage->FindBodyCont();
+        ASSERT( pBody, "AppendFtn: NoPageBody?" );
+        if( pBody->Lower() && pBody->Lower()->IsColumnFrm() )
+            pBoss = (SwFtnBossFrm*)pBody->Lower();
+        else
+            pBoss = pPage; // bei nichtspaltigen Seiten auf die Seite selbst
+    }
+    pBoss->InsertFtn( pNew );
+    if ( pNew->GetUpper() )         //Eingesetzt oder nicht?
+    {
+        ::RegistFlys( pNew->FindPageFrm(), pNew );
+        SwSectionFrm* pSect = FindSctFrm();
+        // Der Inhalt des FtnContainers in einem (spaltigen) Bereich
+        // braucht nur kalkuliert zu werden,
+        // wenn der Bereich bereits bis zur Unterkante seines Uppers geht.
+        if( pSect && !pSect->IsJoinLocked() && ( bEnd ? !pSect->IsEndnAtEnd() :
+            !pSect->IsFtnAtEnd() ) && pSect->Growable() )
+            pSect->InvalidateSize();
+        else
+        {
+            SwCntntFrm *pCnt = pNew->ContainsCntnt();
+            while ( pCnt && pCnt->FindFtnFrm()->GetAttr() == pAttr )
+            {
+                pCnt->Calc();
+                pCnt = (SwCntntFrm*)pCnt->FindNextCnt();
+            }
+        }
+        pMyPage->UpdateFtnNum();
+    }
+    else
+        delete pNew;
+}
+/*************************************************************************
+|*
+|*  SwFtnBossFrm::FindFtn()
+|*
+|*  Ersterstellung      MA 25. Feb. 93
+|*  Letzte Aenderung    AMA 29. Oct. 98
+|*
+|*************************************************************************/
+
+
+SwFtnFrm *SwFtnBossFrm::FindFtn( const SwCntntFrm *pRef, const SwTxtFtn *pAttr )
+{
+    //Der einfachste und sicherste Weg geht ueber das Attribut.
+    ASSERT( pAttr->GetStartNode(), "FtnAtr ohne StartNode." );
+    SwNodeIndex aIdx( *pAttr->GetStartNode(), 1 );
+    SwCntntNode *pNd = aIdx.GetNode().GetCntntNode();
+    if ( !pNd )
+        pNd = pRef->GetAttrSet()->GetDoc()->
+              GetNodes().GoNextSection( &aIdx, TRUE, FALSE );
+    if ( !pNd )
+        return 0;
+    SwClientIter aIter( *pNd );
+    SwClient *pClient;
+    if ( 0 != (pClient = aIter.GoStart()) )
+        do
+        {
+            if ( pClient->IsA( TYPE(SwFrm) ) )
+            {
+                SwFrm *pFrm = ((SwFrm*)pClient)->GetUpper();
+                SwFtnFrm *pFtn = pFrm->FindFtnFrm();
+                if ( pFtn && pFtn->GetRef() == pRef )
+                {
+                    // The following condition becomes true, if the whole
+                    // footnotecontent is a section. While no frames exist,
+                    // the HiddenFlag of the section is set, this causes
+                    // the GoNextSection-function leaves the footnote.
+                    if( pFtn->GetAttr() != pAttr )
+                        return 0;
+                    while ( pFtn && pFtn->GetMaster() )
+                        pFtn = pFtn->GetMaster();
+                    return pFtn;
+                }
+            }
+        } while ( 0 != (pClient = aIter++) );
+
+    return 0;
+}
+/*************************************************************************
+|*
+|*  SwFtnBossFrm::RemoveFtn()
+|*
+|*  Ersterstellung      MA 25. Feb. 93
+|*  Letzte Aenderung    AMA 29. Oct. 98
+|*
+|*************************************************************************/
+
+
+void SwFtnBossFrm::RemoveFtn( const SwCntntFrm *pRef, const SwTxtFtn *pAttr,
+                              BOOL bPrep )
+{
+    SwFtnFrm *pFtn = FindFtn( pRef, pAttr );
+    if( pFtn )
+    {
+        do
+        {
+            SwFtnFrm *pFoll = pFtn->GetFollow();
+            pFtn->Cut();
+            delete pFtn;
+            pFtn = pFoll;
+        } while ( pFtn );
+        if( bPrep && pRef->IsFollow() )
+        {
+            ASSERT( pRef->IsTxtFrm(), "NoTxtFrm has Footnote?" );
+            SwTxtFrm* pMaster = (SwTxtFrm*)pRef->FindMaster();
+            if( !pMaster->IsLocked() )
+                pMaster->Prepare( PREP_FTN_GONE );
+        }
+    }
+    FindPageFrm()->UpdateFtnNum();
+}
+
+/*************************************************************************
+|*
+|*  SwFtnBossFrm::ChangeFtnRef()
+|*
+|*  Ersterstellung      MA 25. Feb. 93
+|*  Letzte Aenderung    AMA 29. Oct. 98
+|*
+|*************************************************************************/
+
+
+void SwFtnBossFrm::ChangeFtnRef( const SwCntntFrm *pOld, const SwTxtFtn *pAttr,
+                                 SwCntntFrm *pNew )
+{
+    SwFtnFrm *pFtn = FindFtn( pOld, pAttr );
+    while ( pFtn )
+    {
+        pFtn->SetRef( pNew );
+        pFtn = pFtn->GetFollow();
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFtnBossFrm::CollectFtns()
+|*
+|*  Ersterstellung      MA 24. Jul. 95
+|*  Letzte Aenderung    AMA 29. Oct. 98
+|*
+|*************************************************************************/
+
+
+void SwFtnBossFrm::CollectFtns( const SwCntntFrm *pRef, SwFtnBossFrm *pOld,
+                                SvPtrarr &rFtnArr )
+{
+    SwFtnFrm *pFtn = pOld->FindFirstFtn();
+    while( !pFtn )
+    {
+        if( pOld->IsColumnFrm() )
+        {   // Spalten abklappern
+            while ( !pFtn && pOld->GetPrev() )
+            {
+                //Wenn wir keine Fussnote gefunden haben, ist noch nicht alles zu
+                //spaet. Die Schleife wird beim Aufnehmen von Follow-Zeilen durch
+                //Tabellen benoetigt. Fuer alle anderen Faelle ist sie in der Lage
+                //'krumme' Verhaeltnisse zu korrigieren.
+                pOld = (SwFtnBossFrm*)pOld->GetPrev();
+                pFtn = pOld->FindFirstFtn();
+            }
+        }
+        if( !pFtn )
+        {
+            //  vorherige Seite
+            SwPageFrm* pPg;
+            for( SwFrm* pTmp = pOld;
+                    0 != ( pPg = (SwPageFrm*)pTmp->FindPageFrm()->GetPrev())
+                    && pPg->IsEmptyPage() ; )
+                pTmp = pPg;
+            if( !pPg )
+                return;
+
+            SwLayoutFrm* pBody = pPg->FindBodyCont();
+            if( pBody->Lower() && pBody->Lower()->IsColumnFrm() )
+            {   // mehrspaltige Seite => letzte Spalte suchen
+                pOld = (SwFtnBossFrm*)pBody->Lower();
+                while ( pOld->GetNext() )
+                    pOld = (SwFtnBossFrm*)pOld->GetNext();
+            }
+            else
+                pOld = pPg; // einspaltige Seite
+            pFtn = pOld->FindFirstFtn();
+        }
+    }
+    _CollectFtns( pRef, pFtn, rFtnArr );
+}
+
+
+/*************************************************************************
+|*
+|*  SwFtnBossFrm::_CollectFtns()
+|*
+|*  Ersterstellung      MA 24. Jul. 95
+|*  Letzte Aenderung    AMA 29. Oct. 98
+|*
+|*************************************************************************/
+inline void FtnInArr( SvPtrarr& rFtnArr, SwFtnFrm* pFtn )
+{
+    if ( USHRT_MAX == rFtnArr.GetPos( (VoidPtr)pFtn ) )
+        rFtnArr.Insert( (VoidPtr)pFtn, rFtnArr.Count() );
+}
+
+void SwFtnBossFrm::_CollectFtns( const SwCntntFrm *pRef, SwFtnFrm *pFtn,
+                                 SvPtrarr &rFtnArr )
+{
+    //Alle Fussnoten die von pRef referenziert werden nacheinander
+    //einsammeln (Attribut fuer Attribut), zusammengefuegen
+    //(der Inhalt zu einem Attribut kann ueber mehrere Seiten verteilt sein)
+    //und ausschneiden.
+
+    SvPtrarr aNotFtnArr( 20, 20 );  //Zur Robustheit werden hier die nicht
+                                    //dazugehoerigen Fussnoten eingetragen.
+                                    //Wenn eine Fussnote zweimal angefasst wird
+                                    //ists vorbei! So kommt die Funktion auch
+                                    //noch mit einem kaputten Layout
+                                    //einigermassen (ohne Schleife und Absturz)
+                                    //"klar".
+
+    //Hier sollte keiner mit einer Follow-Ftn ankommen, es sei denn er hat
+    //ernste Absichten (:-)); spricht er kommt mit einer Ftn an die vor der
+    //ersten der Referenz liegt.
+    ASSERT( !pFtn->GetMaster() || pFtn->GetRef() != pRef, "FollowFtn moven?" );
+    while ( pFtn->GetMaster() )
+        pFtn = pFtn->GetMaster();
+
+    BOOL bFound = FALSE;
+
+    while ( pFtn )
+    {
+        //Erstmal die naechste Fussnote der Spalte/Seite suchen, damit wir nicht
+        //nach dem Cut jeder Fussnote von vorn anfangen muessen.
+        SwFtnFrm *pNxtFtn = pFtn;
+        while ( pNxtFtn->GetFollow() )
+            pNxtFtn = pNxtFtn->GetFollow();
+        pNxtFtn = (SwFtnFrm*)pNxtFtn->GetNext();
+
+        if ( !pNxtFtn )
+        {
+            SwFtnBossFrm* pBoss = pFtn->FindFtnBossFrm();
+            SwPageFrm* pPage = pBoss->FindPageFrm();
+            do
+            {
+                lcl_NextFtnBoss( pBoss, pPage, FALSE );
+                if( pBoss )
+                {
+                    SwLayoutFrm* pCont = pBoss->FindFtnCont();
+                    if( pCont )
+                    {
+                        pNxtFtn = (SwFtnFrm*)pCont->Lower();
+                        if( pNxtFtn )
+                        {
+                            while( pNxtFtn->GetMaster() )
+                                pNxtFtn = pNxtFtn->GetMaster();
+                            if( pNxtFtn == pFtn )
+                                pNxtFtn = NULL;
+                        }
+                    }
+                }
+            } while( !pNxtFtn && pBoss );
+        }
+        else if( !pNxtFtn->GetAttr()->GetFtn().IsEndNote() )
+        {   ASSERT( !pNxtFtn->GetMaster(), "_CollectFtn: Master exspected" );
+            while ( pNxtFtn->GetMaster() )
+                pNxtFtn = pNxtFtn->GetMaster();
+        }
+        if ( pNxtFtn == pFtn )
+        {
+            ASSERT( FALSE, "_CollectFtn: Devil's circle" );
+            pNxtFtn = 0;
+        }
+
+        if ( pFtn->GetRef() == pRef && !pFtn->GetAttr()->GetFtn().IsEndNote() )
+        {
+            ASSERT( !pFtn->GetMaster(), "FollowFtn moven?" );
+            SwFtnFrm *pNxt = pFtn->GetFollow();
+            while ( pNxt )
+            {
+                SwFrm *pCnt = pNxt->ContainsAny();
+                if ( pCnt )
+                {   //Unterwegs wird der Follow zerstoert weil er leer wird!
+                    do
+                    {   SwFrm *pNxtCnt = pCnt->GetNext();
+                        pCnt->Cut();
+                        pCnt->Paste( pFtn );
+                        pCnt = pNxtCnt;
+                    } while ( pCnt );
+                }
+                else
+                {   ASSERT( !pNxt, "Fussnote ohne Inhalt?" );
+                    pNxt->Cut();
+                    delete pNxt;
+                }
+                pNxt = pFtn->GetFollow();
+            }
+            pFtn->Cut();
+            FtnInArr( rFtnArr, pFtn );
+            bFound = TRUE;
+        }
+        else
+        {
+            FtnInArr( aNotFtnArr, pFtn );
+            if( bFound )
+                break;
+        }
+        if ( pNxtFtn &&
+             USHRT_MAX == rFtnArr.GetPos( (VoidPtr)pNxtFtn ) &&
+             USHRT_MAX == aNotFtnArr.GetPos( (VoidPtr)pNxtFtn ) )
+            pFtn = pNxtFtn;
+        else
+            break;
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFtnBossFrm::_MoveFtns()
+|*
+|*  Ersterstellung      MA 26. Feb. 93
+|*  Letzte Aenderung    AMA 29. Oct. 98
+|*
+|*************************************************************************/
+
+
+void SwFtnBossFrm::_MoveFtns( SvPtrarr &rFtnArr, BOOL bCalc )
+{
+    //Alle Fussnoten die von pRef referenziert werden muessen von der
+    //aktuellen Position, die sich durch die alte Spalte/Seite ergab, auf eine
+    //neue Position, bestimmt durch die neue Spalte/Seite, gemoved werden.
+    const USHORT nMyNum = FindPageFrm()->GetPhyPageNum();
+    const USHORT nMyCol = lcl_ColumnNum( this );
+
+    for ( USHORT i = 0; i < rFtnArr.Count(); ++i )
+    {
+        SwFtnFrm *pFtn = (SwFtnFrm*)rFtnArr[i];
+
+        SwFtnBossFrm* pRefBoss = pFtn->GetRef()->FindFtnBossFrm( TRUE );
+        if( pRefBoss != this )
+        {
+            const USHORT nRefNum = pRefBoss->FindPageFrm()->GetPhyPageNum();
+            const USHORT nRefCol = lcl_ColumnNum( this );
+            if( nRefNum < nMyNum || ( nRefNum == nMyNum && nRefCol <= nMyCol ) )
+                pRefBoss = this;
+        }
+        pRefBoss->InsertFtn( pFtn );
+
+        if ( pFtn->GetUpper() ) //Robust, z.B. bei doppelten
+        {
+            // Damit FtnFrms, die nicht auf die Seite passen, nicht fuer zuviel
+            // Unruhe sorgen (Loop 66312), wird ihr Inhalt zunaechst zusammengestaucht.
+            // Damit wird der FtnCont erst gegrowt, wenn der Inhalt formatiert wird
+            // und feststellt, dass er auf die Seite passt.
+            SwFrm *pCnt = pFtn->ContainsAny();
+            while( pCnt )
+            {
+                if( pCnt->IsLayoutFrm() )
+                {
+                    SwFrm* pTmp = ((SwLayoutFrm*)pCnt)->ContainsAny();
+                    while( pTmp && ((SwLayoutFrm*)pCnt)->IsAnLower( pTmp ) )
+                    {
+                        pTmp->Prepare( PREP_MOVEFTN );
+                        pTmp->Frm().Height(0);
+                        pTmp->Prt().Height(0);
+                        pTmp = pTmp->FindNext();
+                    }
+                }
+                else
+                    pCnt->Prepare( PREP_MOVEFTN );
+                pCnt->Frm().Height(0);
+                pCnt->Prt().Height(0);
+                pCnt = pCnt->GetNext();
+            }
+            pFtn->Frm().Height(0);
+            pFtn->Prt().Height(0);
+            pFtn->Calc();
+            pFtn->GetUpper()->Calc();
+
+            if( bCalc )
+            {
+                SwTxtFtn *pAttr = pFtn->GetAttr();
+                pCnt = pFtn->ContainsAny();
+                pFtn->LockBackMove();
+
+                while ( pCnt && pCnt->FindFtnFrm()->GetAttr() == pAttr )
+                {
+                    pCnt->_InvalidatePos();
+                    pCnt->Calc();
+                    if( pCnt->IsSctFrm() )
+                    {   // Wenn es sich um einen nichtleeren Bereich handelt,
+                        // iterieren wir auch ueber seinen Inhalt
+                        SwFrm* pTmp = ((SwSectionFrm*)pCnt)->ContainsAny();
+                        if( pTmp )
+                            pCnt = pTmp;
+                        else
+                            pCnt = pCnt->FindNext();
+                    }
+                    else
+                        pCnt = pCnt->FindNext();
+                }
+                pFtn->UnlockBackMove();
+            }
+        }
+        else
+        {   ASSERT( !pFtn->GetMaster() && !pFtn->GetFollow(),
+                    "DelFtn und Master/Follow?" );
+            delete pFtn;
+        }
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFtnBossFrm::MoveFtns()
+|*
+|*  Ersterstellung      BP 05. Aug. 93
+|*  Letzte Aenderung    AMA 29. Oct. 98
+|*
+|*************************************************************************/
+
+
+void SwFtnBossFrm::MoveFtns( const SwCntntFrm *pSrc, SwCntntFrm *pDest,
+                             SwTxtFtn *pAttr )
+{
+    if( ( GetFmt()->GetDoc()->GetFtnInfo().ePos == FTNPOS_CHAPTER &&
+        (!GetUpper()->IsSctFrm() || !((SwSectionFrm*)GetUpper())->IsFtnAtEnd()))
+        || pAttr->GetFtn().IsEndNote() )
+        return;
+
+    ASSERT( this == pSrc->FindFtnBossFrm( TRUE ),
+            "SwPageFrm::MoveFtns: source frame isn't on that FtnBoss" );
+
+    SwFtnFrm *pFtn = FindFirstFtn();
+    if( pFtn )
+    {
+        ChangeFtnRef( pSrc, pAttr, pDest );
+        SwFtnBossFrm *pDestBoss = pDest->FindFtnBossFrm( TRUE );
+        ASSERT( pDestBoss, "+SwPageFrm::MoveFtns: no destination boss" );
+        if( pDestBoss )     // robust
+        {
+            SvPtrarr aFtnArr( 5, 5 );
+            pDestBoss->_CollectFtns( pDest, pFtn, aFtnArr );
+            if ( aFtnArr.Count() )
+            {
+                pDestBoss->_MoveFtns( aFtnArr, TRUE );
+                SwPageFrm* pSrcPage = FindPageFrm();
+                SwPageFrm* pDestPage = pDestBoss->FindPageFrm();
+                // Nur beim Seitenwechsel FtnNum Updaten
+                if( pSrcPage != pDestPage )
+                {
+                    if( pSrcPage->GetPhyPageNum() > pDestPage->GetPhyPageNum() )
+                        pSrcPage->UpdateFtnNum();
+                    pDestPage->UpdateFtnNum();
+                }
+            }
+        }
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFtnBossFrm::RearrangeFtns()
+|*
+|*  Ersterstellung      MA 20. Jan. 94
+|*  Letzte Aenderung    AMA 29. Oct. 98
+|*
+|*************************************************************************/
+
+
+void SwFtnBossFrm::RearrangeFtns( const SwTwips nDeadLine, const BOOL bLock,
+                                  const SwTxtFtn *pAttr )
+{
+    //Alle Fussnoten der Spalte/Seite dergestalt anformatieren,
+    //dass sie ggf. die Spalte/Seite wechseln.
+
+    SwSaveFtnHeight aSave( this, nDeadLine );
+    SwFtnFrm *pFtn = FindFirstFtn();
+    if( pFtn && pFtn->GetPrev() && bLock )
+    {
+        SwFtnFrm* pFirst = (SwFtnFrm*)pFtn->GetUpper()->Lower();
+        SwFrm* pCntnt = pFirst->ContainsAny();
+        if( pCntnt )
+        {
+            pFirst->LockBackMove();
+            pFirst->Calc();
+            pCntnt->Calc();
+            pFirst->UnlockBackMove();
+        }
+        pFtn = FindFirstFtn();
+    }
+    SwDoc *pDoc = GetFmt()->GetDoc();
+    const ULONG nFtnPos = pAttr ? ::lcl_FindFtnPos( pDoc, pAttr ) : 0;
+    SwFrm *pCnt = pFtn ? pFtn->ContainsAny() : 0;
+    if ( pCnt )
+    {
+        BOOL bMore = TRUE;
+        BOOL bStart = pAttr == 0; // wenn kein Attribut uebergeben wird, alle bearbeiten
+        do
+        {
+            if( !bStart )
+                bStart = ::lcl_FindFtnPos( pDoc, pCnt->FindFtnFrm()->GetAttr() )
+                         == nFtnPos;
+            if( bStart )
+            {   pCnt->_InvalidatePos();
+                pCnt->_InvalidateSize();
+                pCnt->Prepare( PREP_ADJUST_FRM );
+                SwFtnFrm* pTmp = pCnt->FindFtnFrm();
+                if ( bLock )
+                {
+                    pTmp->LockBackMove();
+                    pTmp->Calc();
+                    pCnt->Calc();
+                    pTmp->UnlockBackMove();
+                }
+                else
+                {
+                    pTmp->Calc();
+                    pCnt->Calc();
+                }
+            }
+            SwSectionFrm *pDel = NULL;
+            if( pCnt->IsSctFrm() )
+            {
+                SwFrm* pTmp = ((SwSectionFrm*)pCnt)->ContainsAny();
+                if( pTmp )
+                {
+                    pCnt = pTmp;
+                    continue;
+                }
+                pDel = (SwSectionFrm*)pCnt;
+            }
+            if ( pCnt->GetNext() )
+                pCnt = pCnt->GetNext();
+            else
+            {
+                pCnt = pCnt->FindNext();
+                if ( pCnt )
+                {
+                    SwFtnFrm* pFtn = pCnt->FindFtnFrm();
+                    if( pFtn->GetRef()->FindFtnBossFrm(
+                        pFtn->GetAttr()->GetFtn().IsEndNote() ) != this )
+                        bMore = FALSE;
+                }
+                else
+                    bMore = FALSE;
+            }
+            if( pDel )
+            {
+                pDel->Cut();
+                delete pDel;
+            }
+            if ( bMore )
+            {
+                //Nicht weiter als bis zur angegebenen Fussnote, falls eine
+                //angegeben wurde.
+                if ( pAttr &&
+                     (::lcl_FindFtnPos( pDoc,
+                                    pCnt->FindFtnFrm()->GetAttr()) > nFtnPos ) )
+                    bMore = FALSE;
+            }
+        } while ( bMore );
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwPageFrm::UpdateFtnNum()
+|*
+|*  Ersterstellung      MA 02. Mar. 93
+|*  Letzte Aenderung    AMA 29. Oct. 98
+|*
+|*************************************************************************/
+
+void SwPageFrm::UpdateFtnNum()
+{
+    //Seitenweise Numerierung nur wenn es am Dokument so eingestellt ist.
+    if ( GetFmt()->GetDoc()->GetFtnInfo().eNum != FTNNUM_PAGE )
+        return;
+
+    SwLayoutFrm* pBody = FindBodyCont();
+    if( !pBody || !pBody->Lower() )
+        return;
+
+    SwCntntFrm* pCntnt = pBody->ContainsCntnt();
+    USHORT nNum = 0;
+
+    while( pCntnt && pCntnt->FindPageFrm() == this )
+    {
+        if( ((SwTxtFrm*)pCntnt)->HasFtn() )
+        {
+            SwFtnBossFrm* pBoss = pCntnt->FindFtnBossFrm( TRUE );
+            if( pBoss->GetUpper()->IsSctFrm() &&
+                ((SwSectionFrm*)pBoss->GetUpper())->IsOwnFtnNum() )
+                pCntnt = ((SwSectionFrm*)pBoss->GetUpper())->FindLastCntnt();
+            else
+            {
+                SwFtnFrm* pFtn = (SwFtnFrm*)pBoss->FindFirstFtn( pCntnt );
+                while( pFtn )
+                {
+                    SwTxtFtn* pTxtFtn = pFtn->GetAttr();
+                    if( !pTxtFtn->GetFtn().IsEndNote() &&
+                         !pTxtFtn->GetFtn().GetNumStr().Len() &&
+                         !pFtn->GetMaster() &&
+                         (pTxtFtn->GetFtn().GetNumber() != ++nNum) )
+                        pTxtFtn->SetNumber( nNum );
+                    if ( pFtn->GetNext() )
+                        pFtn = (SwFtnFrm*)pFtn->GetNext();
+                    else
+                    {
+                        SwFtnBossFrm* pBoss = pFtn->FindFtnBossFrm( TRUE );
+                        SwPageFrm* pPage = pBoss->FindPageFrm();
+                        pFtn = NULL;
+                        lcl_NextFtnBoss( pBoss, pPage, FALSE );
+                        if( pBoss )
+                        {
+                            SwFtnContFrm *pCont = pBoss->FindNearestFtnCont();
+                            if ( pCont )
+                                pFtn = (SwFtnFrm*)pCont->Lower();
+                        }
+                    }
+                    if( pFtn && pFtn->GetRef() != pCntnt )
+                        pFtn = NULL;
+                }
+            }
+        }
+        pCntnt = pCntnt->FindNextCnt();
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFtnBossFrm::SetFtnDeadLine()
+|*
+|*  Ersterstellung      MA 02. Aug. 93
+|*  Letzte Aenderung    MA 16. Nov. 98
+|*
+|*************************************************************************/
+
+void SwFtnBossFrm::SetFtnDeadLine( const SwTwips nDeadLine )
+{
+    SwFrm *pBody = FindBodyCont();
+    pBody->Calc();
+
+    SwFrm *pCont = FindFtnCont();
+    const SwTwips nMax = nMaxFtnHeight;//Aktuelle MaxHeight nicht ueberschreiten.
+    if ( pCont )
+    {
+        pCont->Calc();
+        nMaxFtnHeight = pCont->Frm().Height() + pCont->Frm().Top() - nDeadLine;
+    }
+    else
+        nMaxFtnHeight = pBody->Frm().Top() + pBody->Frm().Height() - nDeadLine;
+
+    if ( GetFmt()->GetDoc()->IsBrowseMode() )
+        nMaxFtnHeight += pBody->Grow( LONG_MAX, pHeight, TRUE );
+    if ( IsInSct() )
+        nMaxFtnHeight += FindSctFrm()->Grow( LONG_MAX, pHeight, TRUE );
+
+    if ( nMaxFtnHeight < 0 )
+        nMaxFtnHeight = 0;
+    if ( nMax != LONG_MAX && nMaxFtnHeight > nMax )
+        nMaxFtnHeight = nMax;
+}
+
+/*************************************************************************
+|*
+|*  SwFtnBossFrm::GetVarSpace()
+|*
+|*  Ersterstellung      MA 03. Apr. 95
+|*  Letzte Aenderung    MA 16. Nov. 98
+|*
+|*************************************************************************/
+SwTwips SwFtnBossFrm::GetVarSpace() const
+{
+    //Fuer Seiten soll ein Wert von 20% der Seitenhoehe nicht unterschritten
+    //werden (->AMA: was macht MS da?)
+    //->AMA: Was ist da fuer Bereiche sinnvoll (und kompatibel zu MS ;-)?
+    //AMA: MS kennt scheinbar kein Begrenzung, die Fussnoten nehmen durchaus
+    // die ganze Seite/Spalte ein.
+
+    const SwPageFrm* pPg = FindPageFrm();
+    ASSERT( pPg, "Footnote lost page" );
+
+    const SwFrm *pBody = FindBodyCont();
+    SwTwips nRet;
+    if( pBody )
+    {
+        if( IsInSct() )
+        {
+            nRet = 0;
+            SwTwips nTmp = pBody->Frm().Top() + pBody->Prt().Top() -Frm().Top();
+            const SwSectionFrm* pSect = FindSctFrm();
+            //  Endnotes in a ftncontainer causes a deadline:
+            // the bottom of the last contentfrm
+            if( pSect->IsEndnAtEnd() ) // endnotes allowed?
+            {
+                ASSERT( !Lower() || !Lower()->GetNext() || Lower()->GetNext()->
+                        IsFtnContFrm(), "FtnContainer exspected" );
+                const SwFtnContFrm* pCont = Lower() ?
+                    (SwFtnContFrm*)Lower()->GetNext() : 0;
+                if( pCont )
+                {
+                    SwFtnFrm* pFtn = (SwFtnFrm*)pCont->Lower();
+                    while( pFtn)
+                    {
+                        if( pFtn->GetAttr()->GetFtn().IsEndNote() )
+                        { // endnote found
+                            SwFrm* pFrm = ((SwLayoutFrm*)Lower())->Lower();
+                            if( pFrm )
+                            {
+                                while( pFrm->GetNext() )
+                                    pFrm = pFrm->GetNext(); // last cntntfrm
+                                nTmp += Frm().Top() - pFrm->Frm().Top()
+                                        - pFrm->Frm().Height();
+                            }
+                            break;
+                        }
+                        pFtn = (SwFtnFrm*)pFtn->GetNext();
+                    }
+                }
+            }
+            if( nTmp < nRet )
+                nRet = nTmp;
+        }
+        else
+            nRet = - pPg->Prt().Height()/5;
+        nRet += pBody->Frm().Height();
+        if( nRet < 0 )
+            nRet = 0;
+    }
+    else
+        nRet = 0;
+    if ( IsPageFrm() && GetFmt()->GetDoc()->IsBrowseMode() )
+        nRet += BROWSE_HEIGHT - Frm().Height();
+    return nRet;
+}
+
+/*************************************************************************
+|*
+|*  SwFtnBossFrm::NeighbourhoodAdjustment(SwFrm*)
+|*
+|*  gibt Auskunft, ob die Groessenveraenderung von pFrm von AdjustNeighbourhood(...)
+|*  oder von Grow/Shrink(..) verarbeitet werden sollte.
+|*  Bei einem PageFrm oder in Spalten direkt unterhalb der Seite muss AdjustNei..
+|*  gerufen werden, in Rahmenspalten Grow/Shrink.
+|*  Spannend sind die spaltigen Bereiche: Wenn es in der Spalte einen Fussnotencontainer
+|*  gibt und die Fussnoten nicht vom Bereich eingesammelt werden, ist ein Adjust..,
+|*  ansonsten ein Grow/Shrink notwendig.
+|*
+|*  Ersterstellung      AMA 09. Dec 98
+|*  Letzte Aenderung    AMA 09. Dec 98
+|*
+|*************************************************************************/
+
+BYTE SwFtnBossFrm::_NeighbourhoodAdjustment( const SwFrm* pFrm ) const
+{
+    BYTE nRet = NA_ONLY_ADJUST;
+    if( GetUpper() && !GetUpper()->IsPageBodyFrm() )
+    {
+        // Spaltige Rahmen erfordern Grow/Shrink
+        if( GetUpper()->IsFlyFrm() )
+            nRet = NA_GROW_SHRINK;
+        else
+        {
+            ASSERT( GetUpper()->IsSctFrm(), "NeighbourhoodAdjustment: Unexspected Upper" );
+            if( !GetNext() && !GetPrev() )
+                nRet = NA_GROW_ADJUST; // section with a single column (FtnAtEnd)
+            else
+            {
+                const SwFrm* pTmp = Lower();
+                ASSERT( pTmp, "NeighbourhoodAdjustment: Missing Lower()" );
+                if( !pTmp->GetNext() )
+                    nRet = NA_GROW_SHRINK;
+                else if( !GetUpper()->IsColLocked() )
+                    nRet = NA_ADJUST_GROW;
+                ASSERT( !pTmp->GetNext() || pTmp->GetNext()->IsFtnContFrm(),
+                        "NeighbourhoodAdjustment: Who's that guy?" );
+            }
+        }
+    }
+    return nRet;
+}
+
+/*************************************************************************
+|*
+|*  SwPageFrm::SetColMaxFtnHeight()
+|*
+|*  Ersterstellung      AMA 29. Oct 98
+|*  Letzte Aenderung    AMA 29. Oct 98
+|*
+|*************************************************************************/
+void SwPageFrm::SetColMaxFtnHeight()
+{
+    SwLayoutFrm *pBody = FindBodyCont();
+    if( pBody && pBody->Lower() && pBody->Lower()->IsColumnFrm() )
+    {
+        SwColumnFrm* pCol = (SwColumnFrm*)pBody->Lower();
+        do
+        {
+            pCol->SetMaxFtnHeight( GetMaxFtnHeight() );
+            pCol = (SwColumnFrm*)pCol->GetNext();
+        } while ( pCol );
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwLayoutFrm::MoveLowerFtns
+|*
+|*  Ersterstellung      MA 01. Sep. 94
+|*  Letzte Aenderung    MA 05. Sep. 95
+|*
+|*************************************************************************/
+
+
+BOOL SwLayoutFrm::MoveLowerFtns( SwCntntFrm *pStart, SwFtnBossFrm *pOldBoss,
+                                 SwFtnBossFrm *pNewBoss, const BOOL bFtnNums )
+{
+    SwDoc *pDoc = GetFmt()->GetDoc();
+    if ( !pDoc->GetFtnIdxs().Count() )
+        return FALSE;
+    if( pDoc->GetFtnInfo().ePos == FTNPOS_CHAPTER &&
+        ( !IsInSct() || !FindSctFrm()->IsFtnAtEnd() ) )
+        return TRUE;
+
+    if ( !pNewBoss )
+        pNewBoss = FindFtnBossFrm( TRUE );
+    if ( pNewBoss == pOldBoss )
+        return FALSE;
+
+    BOOL bMoved = FALSE;
+    if( !pStart )
+        pStart = ContainsCntnt();
+
+    SvPtrarr aFtnArr( 5, 5 );
+
+    while ( IsAnLower( pStart ) )
+    {
+        if ( ((SwTxtFrm*)pStart)->HasFtn() )
+            pNewBoss->CollectFtns( pStart, pOldBoss, aFtnArr );
+        pStart = pStart->GetNextCntntFrm();
+    }
+
+    ASSERT( pOldBoss->IsInSct() == pNewBoss->IsInSct(),
+            "MoveLowerFtns: Section confusion" );
+    SvPtrarr *pFtnArr;
+    SwLayoutFrm *pNewChief, *pOldChief;
+    if( pStart && pOldBoss->IsInSct() && ( pOldChief = pOldBoss->FindSctFrm() )
+        != ( pNewChief = pNewBoss->FindSctFrm() ) )
+    {
+        pFtnArr = new SvPtrarr( 5, 5 );
+        pOldChief = pOldBoss->FindFtnBossFrm( TRUE );
+        pNewChief = pNewBoss->FindFtnBossFrm( TRUE );
+        while( pOldChief->IsAnLower( pStart ) )
+        {
+            if ( ((SwTxtFrm*)pStart)->HasFtn() )
+                ((SwFtnBossFrm*)pNewChief)->CollectFtns( pStart,
+                                        (SwFtnBossFrm*)pOldBoss, *pFtnArr );
+            pStart = pStart->GetNextCntntFrm();
+        }
+        if( !pFtnArr->Count() )
+        {
+            delete pFtnArr;
+            pFtnArr = NULL;
+        }
+    }
+    else
+        pFtnArr = NULL;
+
+    if ( aFtnArr.Count() || pFtnArr )
+    {
+        if( aFtnArr.Count() )
+            pNewBoss->_MoveFtns( aFtnArr, TRUE );
+        if( pFtnArr )
+        {
+            ((SwFtnBossFrm*)pNewChief)->_MoveFtns( *pFtnArr, TRUE );
+            delete pFtnArr;
+        }
+        bMoved = TRUE;
+
+        // Nur bei einem Seitenwechsel muss die FtnNum neu berechnet werden
+        if ( bFtnNums )
+        {
+            SwPageFrm* pOldPage = pOldBoss->FindPageFrm();
+            SwPageFrm* pNewPage =pNewBoss->FindPageFrm();
+            if( pOldPage != pNewPage )
+            {
+                pOldPage->UpdateFtnNum();
+                pNewPage->UpdateFtnNum();
+            }
+        }
+    }
+    return bMoved;
+}
+
+/*************************************************************************
+|*
+|*  SwLayoutFrm::MoveFtnCntFwd()
+|*
+|*  Ersterstellung      MA 24. Nov. 94
+|*  Letzte Aenderung    MA 15. Jun. 95
+|*
+|*************************************************************************/
+
+
+BOOL SwCntntFrm::MoveFtnCntFwd( BOOL bMakePage, SwFtnBossFrm *pOldBoss )
+{
+    ASSERT( IsInFtn(), "Keine Ftn." );
+    SwLayoutFrm *pFtn = FindFtnFrm();
+
+    // The first paragraph in the first footnote in the first column in the
+    // sectionfrm at the top of the page has not to move forward, if the
+    // columnbody is empty.
+    if( pOldBoss->IsInSct() && !pOldBoss->GetIndPrev() && !GetIndPrev() &&
+        !pFtn->GetPrev() )
+    {
+        SwLayoutFrm* pBody = pOldBoss->FindBodyCont();
+        if( !pBody || !pBody->Lower() )
+            return TRUE;
+    }
+
+    //fix(9538): Wenn die Ftn noch Nachbarn hinter sich hat, so muessen
+    //diese ersteinmal verschwinden.
+    SwLayoutFrm *pNxt = (SwLayoutFrm*)pFtn->GetNext();
+    SwLayoutFrm *pLst = 0;
+    while ( pNxt )
+    {
+        while ( pNxt->GetNext() )
+            pNxt = (SwLayoutFrm*)pNxt->GetNext();
+        if ( pNxt == pLst )
+            pNxt = 0;
+        else
+        {   pLst = pNxt;
+            SwCntntFrm *pCnt = pNxt->ContainsCntnt();
+            if( pCnt )
+                pCnt->MoveFtnCntFwd( TRUE, pOldBoss );
+            pNxt = (SwLayoutFrm*)pFtn->GetNext();
+        }
+    }
+
+    BOOL bSamePage = TRUE;
+    SwLayoutFrm *pNewUpper =
+                GetLeaf( bMakePage ? MAKEPAGE_INSERT : MAKEPAGE_NONE, TRUE );
+
+    if ( pNewUpper )
+    {
+        BOOL bSameBoss = TRUE;
+        SwFtnBossFrm * const pNewBoss = pNewUpper->FindFtnBossFrm();
+        //Wechseln wir die Spalte/Seite?
+        if ( FALSE == ( bSameBoss = pNewBoss == pOldBoss ) )
+        {   bSamePage = pOldBoss->FindPageFrm() == pNewBoss->FindPageFrm(); // Seitenwechsel?
+            pNewUpper->Calc();
+        }
+
+        //Das Layoutblatt, dass wir fuer Fussnoten bekommen ist entweder
+        //ein Fussnotencontainer oder eine Fussnote
+        //Wenn es eine Fussnote ist, und sie die gleiche Fussnotenreferez
+        //wie der alte Upper hat, so moven wir uns direkt hinein.
+        //Ist die Referenz einen andere oder ist es ein Container, so wird
+        //eine neue Fussnote erzeugt und in den Container gestellt.
+        // Wenn wir in einem Bereich innerhalb der Fussnote sind, muss
+        // SectionFrame noch angelegt werden.
+        SwFtnFrm* pTmpFtn = pNewUpper->IsFtnFrm() ? ((SwFtnFrm*)pNewUpper) : 0;
+        if( !pTmpFtn )
+        {
+            ASSERT( pNewUpper->IsFtnContFrm(), "Neuer Upper kein FtnCont.");
+            SwFtnContFrm *pCont = (SwFtnContFrm*)pNewUpper;
+
+            //Fussnote erzeugen.
+            SwFtnFrm *pOld = FindFtnFrm();
+            pTmpFtn = new SwFtnFrm( pOld->GetFmt()->GetDoc()->GetDfltFrmFmt(),
+                                    pOld->GetRef(), pOld->GetAttr() );
+            //Verkettung der Fussnoten.
+            if ( pOld->GetFollow() )
+            {
+                pTmpFtn->SetFollow( pOld->GetFollow() );
+                pOld->GetFollow()->SetMaster( pTmpFtn );
+            }
+            pOld->SetFollow( pTmpFtn );
+            pTmpFtn->SetMaster( pOld );
+            SwFrm* pNx = pCont->Lower();
+            if( pNx && pTmpFtn->GetAttr()->GetFtn().IsEndNote() )
+                while(pNx && !((SwFtnFrm*)pNx)->GetAttr()->GetFtn().IsEndNote())
+                    pNx = pNx->GetNext();
+            pTmpFtn->Paste( pCont, pNx );
+            pTmpFtn->Calc();
+        }
+        ASSERT( pTmpFtn->GetAttr() == FindFtnFrm()->GetAttr(), "Wrong Footnote!" );
+        // Bereiche in Fussnoten beduerfen besonderer Behandlung
+        SwLayoutFrm *pNewUp = pTmpFtn;
+        if( IsInSct() )
+        {
+            SwSectionFrm* pSect = FindSctFrm();
+            // Bereich in Fussnote (oder nur Fussnote in Bereich)?
+            if( pSect->IsInFtn() )
+            {
+                if( pTmpFtn->Lower() && pTmpFtn->Lower()->IsSctFrm() &&
+                    pSect->GetFollow() == (SwSectionFrm*)pTmpFtn->Lower() )
+                    pNewUp = (SwSectionFrm*)pTmpFtn->Lower();
+                else
+                {
+                    pNewUp = new SwSectionFrm( *pSect, FALSE );
+                    pNewUp->InsertBefore( pTmpFtn, pTmpFtn->Lower() );
+                    pNewUp->Frm().Pos() = pTmpFtn->Frm().Pos();
+                    pNewUp->Frm().Pos().Y() += 1; //wg. Benachrichtigungen.
+
+                    // Wenn unser Bereichsframe einen Nachfolger hat, so muss dieser
+                    // umgehaengt werden hinter den neuen Follow der Bereichsframes.
+                    SwFrm* pTmp = pSect->GetNext();
+                    if( pTmp )
+                    {
+                        SwFlowFrm* pNxt;
+                        if( pTmp->IsCntntFrm() )
+                            pNxt = (SwCntntFrm*)pTmp;
+                        else if( pTmp->IsSctFrm() )
+                            pNxt = (SwSectionFrm*)pTmp;
+                        else
+                        {
+                            ASSERT( pTmp->IsTabFrm(), "GetNextSctLeaf: Wrong Type" );
+                            pNxt = (SwTabFrm*)pTmp;
+                        }
+                        pNxt->MoveSubTree( pTmpFtn, pNewUp->GetNext() );
+                    }
+                }
+            }
+        }
+
+        MoveSubTree( pNewUp, pNewUp->Lower() );
+
+        if( !bSameBoss )
+            Prepare( PREP_BOSS_CHGD );
+    }
+    return bSamePage;
+}
+
+/*************************************************************************
+|*
+|*  class SwSaveFtnHeight
+|*
+|*  Ersterstellung      MA 19. Jan. 94
+|*  Letzte Aenderung    MA 19. Jan. 94
+|*
+|*************************************************************************/
+
+
+SwSaveFtnHeight::SwSaveFtnHeight( SwFtnBossFrm *pBs, const SwTwips nDeadLine ) :
+    pBoss( pBs ),
+    nOldHeight( pBs->GetMaxFtnHeight() )
+{
+    pBoss->SetFtnDeadLine( nDeadLine );
+    nNewHeight = pBoss->GetMaxFtnHeight();
+}
+
+
+
+SwSaveFtnHeight::~SwSaveFtnHeight()
+{
+    //Wenn zwischendurch jemand an der DeadLine gedreht hat, so lassen wir
+    //ihm seinen Spass!
+    if ( nNewHeight == pBoss->GetMaxFtnHeight() )
+        pBoss->nMaxFtnHeight = nOldHeight;
+}
+
+
diff --git a/sw/source/core/layout/hffrm.cxx b/sw/source/core/layout/hffrm.cxx
new file mode 100644
index 000000000000..dc8740fda970
--- /dev/null
+++ b/sw/source/core/layout/hffrm.cxx
@@ -0,0 +1,438 @@
+/*************************************************************************
+ *
+ *  $RCSfile: hffrm.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:22 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "pagefrm.hxx"
+#include "viewsh.hxx"
+#include "doc.hxx"
+#include "errhdl.hxx"
+
+#ifndef _FMTCNTNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTHDFT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFSIZE_HXX //autogen
+#include 
+#endif
+#include "hffrm.hxx"
+#include "txtfrm.hxx"
+#include "sectfrm.hxx"
+#include "flyfrm.hxx"
+#include "frmtool.hxx"
+#include "dflyobj.hxx"
+#include "frmfmt.hxx"
+#include "frmsh.hxx"
+#include "ndindex.hxx"
+
+extern FASTBOOL bObjsDirect;    //frmtool.cxx
+
+/*************************************************************************
+|*
+|*  SwHeaderFrm::SwHeaderFrm()
+|*
+|*  Ersterstellung      MA ??
+|*  Letzte Aenderung    MA ??
+|*
+|*************************************************************************/
+
+
+SwHeaderFrm::SwHeaderFrm( SwFrmFmt *pFmt ):
+    SwLayoutFrm( pFmt )
+{
+    nType = FRM_HEADER;
+
+    const SwFmtCntnt &rCnt = pFmt->GetCntnt();
+
+    ASSERT( rCnt.GetCntntIdx(), "Kein Inhalt fuer Header." );
+
+    //Fuer Header Footer die Objekte gleich erzeugen lassen.
+    FASTBOOL bOld = bObjsDirect;
+    bObjsDirect = TRUE;
+    ULONG nIndex = rCnt.GetCntntIdx()->GetIndex();
+    ::_InsertCnt( this, pFmt->GetDoc(), ++nIndex );
+    bObjsDirect = bOld;
+}
+
+SwTwips SwHeaderFrm::GrowFrm( SwTwips nDist, const SzPtr pPtr,
+                              BOOL bTst, BOOL bInfo )
+{
+    SwTwips nRet = SwLayoutFrm::GrowFrm( nDist, pPtr, bTst, bInfo );
+    if ( nRet && !bTst )
+        SetCompletePaint();
+    return nRet;
+}
+
+SwTwips SwHeaderFrm::ShrinkFrm( SwTwips nDist, const SzPtr pPtr,
+                               BOOL bTst, BOOL bInfo )
+{
+    SwTwips nRet = SwLayoutFrm::ShrinkFrm( nDist, pPtr, bTst, bInfo );
+    if ( nRet && !bTst )
+        SetCompletePaint();
+    return nRet;
+}
+
+
+/*************************************************************************
+|*
+|*  SwFooterFrm::SwFooterFrm()
+|*
+|*  Ersterstellung      MA ??
+|*  Letzte Aenderung    MA ??
+|*
+|*************************************************************************/
+
+
+SwFooterFrm::SwFooterFrm( SwFrmFmt *pFmt ):
+    SwLayoutFrm( pFmt )
+{
+    nType = FRM_FOOTER;
+
+    const SwFmtCntnt &rCnt = pFmt->GetCntnt();
+
+    ASSERT( rCnt.GetCntntIdx(), "Kein Inhalt fuer Footer." );
+
+    //Fuer Header Footer die Objekte gleich erzeugen lassen.
+    FASTBOOL bOld = bObjsDirect;
+    bObjsDirect = TRUE;
+    ULONG nIndex = rCnt.GetCntntIdx()->GetIndex();
+    ::_InsertCnt( this, pFmt->GetDoc(), ++nIndex );
+    bObjsDirect = bOld;
+}
+
+void SwFooterFrm::Format( const SwBorderAttrs *pAttrs )
+{
+    ASSERT( pAttrs, "SwFooterFrm::Format, pAttrs ist 0." );
+
+    if ( bValidPrtArea && bValidSize )
+        return;
+
+    const USHORT nLR = pAttrs->CalcLeft( this ) + pAttrs->CalcRight();
+    const USHORT nUL = pAttrs->CalcTop()  + pAttrs->CalcBottom();
+
+    if ( !bValidPrtArea )
+    {
+        bValidPrtArea = TRUE;
+
+        //Position einstellen.
+        aPrt.Left( pAttrs->CalcLeft( this ) );
+        aPrt.Top ( pAttrs->CalcTop()  );
+
+        //Sizes einstellen; die Groesse gibt der umgebende Frm vor, die
+        //die Raender werden einfach abgezogen.
+        aPrt.Width ( aFrm.Width() - nLR );
+        aPrt.Height( aFrm.Height()- nUL );
+    }
+
+    if ( !bValidSize )
+    {
+        const SzPtr pVarSz = pVARSIZE;
+        if ( !HasFixSize( pVarSz ) )
+        {
+            if( !IsColLocked() )
+            {
+                bValidSize = bValidPrtArea = TRUE;
+                const SwTwips nBorder = bVarHeight ? nUL : nLR;
+                const PtPtr pVarPs = pVARPOS;
+                const SwFmtFrmSize &rSz = GetFmt()->GetFrmSize();
+                SwTwips nMinHeight = rSz.GetSizeType() == ATT_MIN_SIZE ? rSz.GetHeight() : 0;
+                ColLock();
+                SwTwips nMaxHeight = LONG_MAX;
+                SwTwips nRemaining, nOldHeight;
+                Point aOldPos;
+                do
+                {
+                    nOldHeight = Frm().SSize().*pVarSz;
+                    SwFrm* pFrm = Lower();
+                    if( Frm().Pos() != aOldPos && pFrm )
+                    {
+                        pFrm->_InvalidatePos();
+                        aOldPos = Frm().Pos();
+                    }
+                    while( pFrm )
+                    {
+                        pFrm->Calc();
+                        pFrm = pFrm->GetNext();
+                    }
+                    nRemaining = nBorder;
+                    pFrm = Lower();
+                    while ( pFrm )
+                    {   nRemaining += pFrm->Frm().SSize().*pVarSz;
+                        if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() )
+                        // Dieser TxtFrm waere gern ein bisschen groesser
+                            nRemaining += ((SwTxtFrm*)pFrm)->GetParHeight()
+                                        - pFrm->Prt().Height();
+                        else if( pFrm->IsSctFrm() && ((SwSectionFrm*)pFrm)->IsUndersized() )
+                            nRemaining += ((SwSectionFrm*)pFrm)->Undersize();
+                        pFrm = pFrm->GetNext();
+                    }
+                    SwTwips nDiff = nRemaining - nOldHeight;
+                    if( !nDiff )
+                        break;
+                    if( nDiff < 0 )
+                    {
+                        nMaxHeight = nOldHeight;
+                        if( nRemaining <= nMinHeight )
+                            nRemaining = ( nMaxHeight + nMinHeight + 1 ) / 2;
+                    }
+                    else
+                    {
+                        nMinHeight = nOldHeight;
+                        if( nRemaining >= nMaxHeight )
+                            nRemaining = ( nMaxHeight + nMinHeight + 1 ) / 2;
+                    }
+                    nDiff = nRemaining - nOldHeight;
+                    if ( nDiff )
+                    {
+                        ColUnlock();
+                        if ( nDiff > 0 )
+                            Grow( nDiff, pVarSz );
+                        else
+                            Shrink( -nDiff, pVarSz );
+                        //Schnell auf dem kurzen Dienstweg die Position updaten.
+                        MakePos();
+                        ColLock();
+                    }
+                    else
+                        break;
+                    //Unterkante des Uppers nicht ueberschreiten.
+                    if ( GetUpper() && Frm().SSize().*pVarSz )
+                    {
+                        const SwTwips nDeadLine =
+                            GetUpper()->Frm().Pos().*pVarPs +
+                                    (bVarHeight ? GetUpper()->Prt().Bottom() :
+                                                GetUpper()->Prt().Right());
+                        const SwTwips nBot = bVarHeight ?
+                                                    Frm().Bottom():Frm().Right();
+                        if ( nBot > nDeadLine )
+                        {
+                            Frm().Bottom( nDeadLine );
+                            Prt().SSize().Height() = Frm().SSize().Height() - nBorder;
+                        }
+                    }
+                    bValidSize = bValidPrtArea = TRUE;
+                } while( nRemaining < nMaxHeight && nOldHeight != Frm().SSize().*pVarSz );
+                ColUnlock();
+            }
+            bValidSize = bValidPrtArea = TRUE;
+        }
+        else if ( GetType() & 0x0018 )
+        {
+            do
+            {   if ( Frm().Height() != pAttrs->GetSize().Height() )
+                    ChgSize( Size( Frm().Width(), pAttrs->GetSize().Height()));
+                bValidSize = TRUE;
+                MakePos();
+            } while ( !bValidSize );
+        }
+        else
+            bValidSize = TRUE;
+    }
+}
+
+SwTwips SwFooterFrm::GrowFrm( SwTwips nDist, const SzPtr pPtr,
+                              BOOL bTst, BOOL bInfo )
+{
+    if( IsColLocked() )
+        return 0;
+    return SwLayoutFrm::GrowFrm( nDist, pPtr, bTst, bInfo );
+}
+
+SwTwips SwFooterFrm::ShrinkFrm( SwTwips nDist, const SzPtr pPtr,
+                              BOOL bTst, BOOL bInfo )
+{
+    if( IsColLocked() )
+        return 0;
+    return SwLayoutFrm::ShrinkFrm( nDist, pPtr, bTst, bInfo );
+}
+
+
+/*************************************************************************
+|*
+|*  SwPageFrm::PrepareHeader()
+|*
+|*  Beschreibung        Erzeugt oder Entfernt Header
+|*  Ersterstellung      MA 04. Feb. 93
+|*  Letzte Aenderung    MA 12. May. 96
+|*
+|*************************************************************************/
+
+
+void DelFlys( SwLayoutFrm *pFrm, SwPageFrm *pPage )
+{
+    for ( int i = 0; pPage->GetSortedObjs() &&
+                        pPage->GetSortedObjs()->Count() &&
+                        i < (int)pPage->GetSortedObjs()->Count(); ++i )
+    {
+        SdrObject *pO = (*pPage->GetSortedObjs())[i];
+        if ( pO->IsWriterFlyFrame() )
+        {
+            SwVirtFlyDrawObj *pObj = (SwVirtFlyDrawObj*)pO;
+            if ( pFrm->IsAnLower( pObj->GetFlyFrm() ) )
+            {
+                delete pObj->GetFlyFrm();
+                --i;
+            }
+        }
+    }
+}
+
+
+
+void SwPageFrm::PrepareHeader()
+{
+    SwLayoutFrm *pLay = (SwLayoutFrm*)Lower();
+    if ( !pLay )
+        return;
+
+    const SwFmtHeader &rH = ((SwFrmFmt*)pRegisteredIn)->GetHeader();
+
+    const FASTBOOL bOn = !((SwFrmFmt*)pRegisteredIn)->GetDoc()->IsBrowseMode() ||
+                          ((SwFrmFmt*)pRegisteredIn)->GetDoc()->IsHeadInBrowse();
+
+    if ( bOn && rH.IsActive() )
+    {   //Header einsetzen, vorher entfernen falls vorhanden.
+        ASSERT( rH.GetHeaderFmt(), "FrmFmt fuer Header nicht gefunden." );
+
+        if ( pLay->GetFmt() == (SwFrmFmt*)rH.GetHeaderFmt() )
+            return; //Der Footer ist bereits der richtige
+
+        if ( pLay->IsHeaderFrm() )
+        {   SwLayoutFrm *pDel = pLay;
+            pLay = (SwLayoutFrm*)pLay->GetNext();
+            ::DelFlys( pDel, this );
+            pDel->Cut();
+            delete pDel;
+        }
+        ASSERT( pLay, "Wohin mit dem Header?" );
+        SwHeaderFrm *pH = new SwHeaderFrm( (SwFrmFmt*)rH.GetHeaderFmt() );
+        pH->Paste( this, pLay );
+        if ( GetUpper() )
+            ::RegistFlys( this, pH );
+    }
+    else if ( pLay && pLay->IsHeaderFrm() )
+    {   //Header entfernen falls vorhanden.
+        ::DelFlys( pLay, this );
+        pLay->Cut();
+        delete pLay;
+    }
+}
+/*************************************************************************
+|*
+|*  SwPageFrm::PrepareFooter()
+|*
+|*  Beschreibung        Erzeugt oder Entfernt Footer
+|*  Ersterstellung      MA 04. Feb. 93
+|*  Letzte Aenderung    MA 12. May. 96
+|*
+|*************************************************************************/
+
+
+void SwPageFrm::PrepareFooter()
+{
+    SwLayoutFrm *pLay = (SwLayoutFrm*)Lower();
+    if ( !pLay )
+        return;
+
+    const SwFmtFooter &rF = ((SwFrmFmt*)pRegisteredIn)->GetFooter();
+    while ( pLay->GetNext() )
+        pLay = (SwLayoutFrm*)pLay->GetNext();
+
+    const FASTBOOL bOn = !((SwFrmFmt*)pRegisteredIn)->GetDoc()->IsBrowseMode() ||
+                         ((SwFrmFmt*)pRegisteredIn)->GetDoc()->IsFootInBrowse();
+
+    if ( bOn && rF.IsActive() )
+    {   //Footer einsetzen, vorher entfernen falls vorhanden.
+        ASSERT( rF.GetFooterFmt(), "FrmFmt fuer Footer nicht gefunden." );
+
+        if ( pLay->GetFmt() == (SwFrmFmt*)rF.GetFooterFmt() )
+            return; //Der Footer ist bereits der richtige.
+
+        if ( pLay->IsFooterFrm() )
+        {   ::DelFlys( pLay, this );
+            pLay->Cut();
+            delete pLay;
+        }
+        SwFooterFrm *pF = new SwFooterFrm( (SwFrmFmt*)rF.GetFooterFmt() );
+        pF->Paste( this );
+        if ( GetUpper() )
+            ::RegistFlys( this, pF );
+    }
+    else if ( pLay && pLay->IsFooterFrm() )
+    {   //Footer entfernen falls vorhanden.
+        ::DelFlys( pLay, this );
+        ViewShell *pSh;
+        if ( pLay->GetPrev() && 0 != (pSh = GetShell()) &&
+             pSh->VisArea().HasArea() )
+            pSh->InvalidateWindows( pSh->VisArea() );
+        pLay->Cut();
+        delete pLay;
+    }
+}
+
+
+
diff --git a/sw/source/core/layout/layact.cxx b/sw/source/core/layout/layact.cxx
new file mode 100644
index 000000000000..b92b734ae0b4
--- /dev/null
+++ b/sw/source/core/layout/layact.cxx
@@ -0,0 +1,2741 @@
+/*************************************************************************
+ *
+ *  $RCSfile: layact.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:22 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include 
+#include "rootfrm.hxx"
+#include "pagefrm.hxx"
+#include "cntfrm.hxx"
+#include "doc.hxx"
+#include "viewimp.hxx"
+#include "crsrsh.hxx"
+#include "dflyobj.hxx"
+#include "flyfrm.hxx"
+#include "frmtool.hxx"
+#include "dcontact.hxx"
+#include "ndtxt.hxx"    // OnlineSpelling
+#include "frmfmt.hxx"
+#include "swregion.hxx"
+#include "viewopt.hxx"  // OnlineSpelling ueber Internal-TabPage testen.
+#include "pam.hxx"      // OnlineSpelling wg. der aktuellen Cursorposition
+#include "dbg_lay.hxx"
+#include "layouter.hxx" // LoopControlling
+
+#include 
+
+#ifndef _WINDOW_HXX //autogen
+#include 
+#endif
+#ifndef _SV_SVAPP_HXX //autogen wg. Application
+#include 
+#endif
+#ifndef _SVX_OPAQITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BRSHITEM_HXX //autogen
+#include 
+#endif
+
+#define _SVSTDARR_BOOLS
+#include 
+
+#define _LAYACT_CXX
+#include "layact.hxx"
+
+#ifndef _SWWAIT_HXX
+#include 
+#endif
+#ifndef _FMTSRND_HXX //autogen
+#include 
+#endif
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _SHL_HXX
+#include 
+#endif
+#include "swmodule.hxx"
+#include "fmtline.hxx"
+#include "tabfrm.hxx"
+#include "ftnfrm.hxx"
+#include "txtfrm.hxx"
+#include "notxtfrm.hxx"
+#include "flyfrms.hxx"
+#include "frmsh.hxx"
+#include "mdiexp.hxx"
+#include "fmtornt.hxx"
+#include "sectfrm.hxx"
+#include "lineinfo.hxx"
+#include "scrrect.hxx"
+#ifndef _ACMPLWRD_HXX
+#include 
+#endif
+
+//#pragma optimize("ity",on)
+
+/*************************************************************************
+|*
+|*  SwLayAction Statisches Geraffel
+|*
+|*  Ersterstellung      MA 22. Dec. 93
+|*  Letzte Aenderung    MA 22. Dec. 93
+|*
+|*************************************************************************/
+
+#define IS_FLYS (pPage->GetSortedObjs())
+#define IS_INVAFLY (pPage->IsInvalidFly())
+
+
+//Sparen von Schreibarbeit um den Zugriff auf zerstoerte Seiten zu vermeiden.
+#ifndef PRODUCT
+
+static void BreakPoint()
+{
+    return;
+}
+
+#define CHECKPAGE \
+            {   if ( IsAgain() ) \
+                {   BreakPoint(); \
+                    return; \
+                } \
+            }
+
+#define XCHECKPAGE \
+            {   if ( IsAgain() ) \
+                {   BreakPoint(); \
+                    if( bNoLoop ) \
+                        pDoc->GetLayouter()->EndLoopControl(); \
+                    return; \
+                } \
+            }
+#else
+#define CHECKPAGE \
+            {   if ( IsAgain() ) \
+                    return; \
+            }
+
+#define XCHECKPAGE \
+            {   if ( IsAgain() ) \
+                { \
+                    if( bNoLoop ) \
+                        pDoc->GetLayouter()->EndLoopControl(); \
+                    return; \
+                } \
+            }
+#endif
+
+#define RESCHEDULE \
+    { \
+        if ( IsReschedule() )  \
+            ::RescheduleProgress( pImp->GetShell()->GetDoc()->GetDocShell() ); \
+    }
+
+inline ULONG Ticks()
+{
+    return 1000 * clock() / CLOCKS_PER_SEC;
+}
+
+void SwLayAction::CheckWaitCrsr()
+{
+    RESCHEDULE
+    if ( !IsWait() && IsWaitAllowed() && IsPaint() &&
+         ((Ticks() - GetStartTicks()) >= CLOCKS_PER_SEC/2) )
+    {
+        pWait = new SwWait( *pRoot->GetFmt()->GetDoc()->GetDocShell(), TRUE );
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwLayAction::CheckIdleEnd()
+|*
+|*  Ersterstellung      MA 12. Aug. 94
+|*  Letzte Aenderung    MA 24. Jun. 96
+|*
+|*************************************************************************/
+//Ist es wirklich schon soweit...
+inline void SwLayAction::CheckIdleEnd()
+{
+    if ( !IsInput() )
+        bInput = GetInputType() && GetpApp()->AnyInput( GetInputType() );
+}
+
+/*************************************************************************
+|*
+|*  SwLayAction::SetStatBar()
+|*
+|*  Ersterstellung      MA 10. Aug. 94
+|*  Letzte Aenderung    MA 06. Aug. 95
+|*
+|*************************************************************************/
+void SwLayAction::SetStatBar( BOOL bNew )
+{
+    if ( bNew )
+    {
+        nEndPage = pRoot->GetPageNum();
+        nEndPage += nEndPage * 10 / 100;
+    }
+    else
+        nEndPage = USHRT_MAX;
+}
+
+/*************************************************************************
+|*
+|*  SwLayAction::PaintCntnt()
+|*
+|*  Beschreibung        Je nach Typ wird der Cntnt entsprechend seinen
+|*      Veraenderungen ausgegeben bzw. wird die auszugebende Flaeche in der
+|*      Region eingetragen.
+|*      PaintCntnt:  fuellt die Region,
+|*  Ersterstellung      BP 19. Jan. 92
+|*  Letzte Aenderung    MA 10. Sep. 96
+|*
+|*************************************************************************/
+BOOL SwLayAction::PaintWithoutFlys( const SwRect &rRect, const SwCntntFrm *pCnt,
+                                    const SwPageFrm *pPage )
+{
+    SwRegionRects aTmp( rRect );
+    const SwSortDrawObjs &rObjs = *pPage->GetSortedObjs();
+    const SwFlyFrm *pSelfFly = pCnt->FindFlyFrm();
+
+    for ( USHORT i = 0; i < rObjs.Count() && aTmp.Count(); ++i )
+    {
+        SdrObject *pO = rObjs[i];
+        if ( !pO->IsWriterFlyFrame() )
+            continue;
+
+        SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+
+        if ( pFly == pSelfFly || !rRect.IsOver( pFly->Frm() ) )
+            continue;
+
+        if ( pSelfFly && pSelfFly->IsLowerOf( pFly ) )
+            continue;
+
+        if ( pFly->GetVirtDrawObj()->GetLayer() == pFly->GetFmt()->GetDoc()->GetHellId() )
+            continue;
+
+        if ( pSelfFly )
+        {
+            const SdrObject *pTmp = pSelfFly->GetVirtDrawObj();
+            if ( pO->GetLayer() == pTmp->GetLayer() )
+            {
+                if ( pO->GetOrdNumDirect() < pTmp->GetOrdNumDirect() )
+                    //Im gleichen Layer werden nur obenliegende beachtet.
+                    continue;
+            }
+            else
+            {
+                const FASTBOOL bLowerOfSelf = pFly->IsLowerOf( pSelfFly );
+                if ( !bLowerOfSelf && !pFly->GetFmt()->GetOpaque().GetValue() )
+                    //Aus anderem Layer interessieren uns nur nicht transparente
+                    //oder innenliegende
+                    continue;
+            }
+        }
+
+        if ( !pFly->Lower() ||
+             (pFly->Lower()->IsNoTxtFrm() &&
+              (((SwNoTxtFrm*)pFly->Lower())->IsTransparent() ||
+               pFly->GetFmt()->GetSurround().IsContour())) )
+        {
+            continue;
+        }
+        aTmp -= pFly->Frm();
+    }
+
+    BOOL bPaint = FALSE;
+    const SwRect *pData = aTmp.GetData();
+    for ( i = 0; i < aTmp.Count(); ++pData, ++i )
+        bPaint |= pImp->GetShell()->AddPaintRect( *pData );
+    return bPaint;
+}
+
+inline BOOL SwLayAction::_PaintCntnt( const SwCntntFrm *pCntnt,
+                                      const SwPageFrm *pPage,
+                                      const SwRect &rRect )
+{
+    if ( rRect.HasArea() )
+    {
+        if ( pPage->GetSortedObjs() )
+            return PaintWithoutFlys( rRect, pCntnt, pPage );
+        else
+            return pImp->GetShell()->AddPaintRect( rRect );
+    }
+    return FALSE;
+}
+
+void SwLayAction::PaintCntnt( const SwCntntFrm *pCnt,
+                              const SwPageFrm *pPage,
+                              const SwRect &rOldRect, long nOldBottom )
+{
+    const BOOL bHeightDiff  = rOldRect.Height() != pCnt->Frm().Height();
+    if ( pCnt->IsCompletePaint() || !pCnt->IsTxtFrm() )
+    {
+        SwRect aPaint( pCnt->PaintArea() );
+        aPaint.Union( rOldRect );
+        if ( !_PaintCntnt( pCnt, pPage, aPaint ) )
+            pCnt->ResetCompletePaint();
+    }
+    else
+    {
+        if( bHeightDiff )
+        {
+            SwRect aDrawRect( pCnt->UnionFrm( TRUE ) );
+            if( rOldRect.Height() < pCnt->Frm().Height() )
+                aDrawRect.Top( nOldBottom );
+            else
+                aDrawRect.Top( pCnt->Frm().Top() + pCnt->Prt().Bottom() + 1 );
+            _PaintCntnt( pCnt, pPage, aDrawRect );
+        }
+        _PaintCntnt( pCnt, pPage, ((SwTxtFrm*)pCnt)->Paint() );
+    }
+
+    if ( pCnt->IsRetouche() && !pCnt->GetNext() )
+    {
+        const SwFrm *pTmp = pCnt;
+        if( pCnt->IsInSct() )
+        {
+            const SwSectionFrm* pSct = pCnt->FindSctFrm();
+            if( pSct->IsRetouche() && !pSct->GetNext() )
+                pTmp = pSct;
+        }
+        SwRect aRect( pTmp->GetUpper()->PaintArea() );
+        aRect.Top( pTmp->Frm().Top() + pTmp->Prt().Bottom() + 1 );
+        if ( !_PaintCntnt( pCnt, pPage, aRect ) )
+            pCnt->ResetRetouche();
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwLayAction::_AddScrollRect()
+|*
+|*  Ersterstellung      MA 04. Mar. 94
+|*  Letzte Aenderung    MA 04. Mar. 94
+|*
+|*************************************************************************/
+BOOL MA_FASTCALL lcl_IsOverObj( const SwFrm *pFrm, const SwPageFrm *pPage,
+                       const SwRect &rRect1, const SwRect &rRect2,
+                       const SwLayoutFrm *pLay )
+{
+    const SwSortDrawObjs &rObjs = *pPage->GetSortedObjs();
+    const SwFlyFrm *pSelfFly = pFrm->FindFlyFrm();
+    const BOOL bInCnt = pSelfFly && pSelfFly->IsFlyInCntFrm() ? TRUE : FALSE;
+
+    for ( USHORT j = 0; j < rObjs.Count(); ++j )
+    {
+        const SdrObject         *pObj = rObjs[j];
+        const SwRect aRect( pObj->GetBoundRect() );
+        if ( !rRect1.IsOver( aRect ) && !rRect2.IsOver( aRect ) )
+            continue;       //Keine Ueberlappung, der naechste.
+
+        const SwVirtFlyDrawObj *pFlyObj = pObj->IsWriterFlyFrame() ?
+                                                (SwVirtFlyDrawObj*)pObj : 0;
+        const SwFlyFrm *pFly = pFlyObj ? pFlyObj->GetFlyFrm() : 0;
+
+        //Wenn der Rahmen innerhalb des LayFrm verankert ist, so darf er
+        //mitgescrollt werden, wenn er nicht seitlich aus dem Rechteck
+        //herausschaut.
+        if ( pLay && pFlyObj && pFlyObj->GetFlyFrm()->IsLowerOf( pLay ) )
+        {
+             if ( pFly->Frm().Left() < rRect1.Left() ||
+                  pFly->Frm().Right()> rRect1.Right() )
+                return TRUE;
+            continue;
+        }
+
+        if ( !pSelfFly )    //Nur wenn der Frm in einem Fly steht kann
+            return TRUE;    //es Einschraenkungen geben.
+
+        if ( !pFlyObj )     //Keine Einschraenkung fuer Zeichenobjekte.
+            return TRUE;
+
+        if ( pFly != pSelfFly )
+        {
+            //Flys unter dem eigenen nur dann abziehen, wenn sie innerhalb des
+            //eigenen stehen.
+            //Fuer inhaltsgebundene Flys alle Flys abziehen fuer die gilt, dass
+            //pSelfFly nicht innerhalb von ihnen steht.
+            if ( bInCnt )
+            {
+                const SwFlyFrm *pTmp = pSelfFly->GetAnchor()->FindFlyFrm();
+                while ( pTmp )
+                {
+                    if ( pTmp == pFly )
+                        return FALSE;
+                    else
+                        pTmp = pTmp->GetAnchor()->FindFlyFrm();
+                }
+            } else if ( pObj->GetOrdNum() < pSelfFly->GetVirtDrawObj()->GetOrdNum() )
+            {
+                const SwFlyFrm *pTmp = pFly;
+                do
+                {   if ( pTmp == pSelfFly )
+                        return TRUE;
+                    else
+                        pTmp = pTmp->GetAnchor()->FindFlyFrm();
+                } while ( pTmp );
+            } else
+                return TRUE;
+        }
+    }
+    return FALSE;
+}
+
+void SwLayAction::_AddScrollRect( const SwCntntFrm *pCntnt,
+                                  const SwPageFrm *pPage,
+                                  const SwTwips nOfst,
+                                  const SwTwips nOldBottom )
+{
+    FASTBOOL bScroll = TRUE;
+    SwRect aPaintRect( pCntnt->PaintArea() );
+
+    //Wenn altes oder neues Rechteck mit einem Fly ueberlappen, in dem der
+    //Cntnt nicht selbst steht, so ist nichts mit Scrollen.
+    if ( pPage->GetSortedObjs() )
+    {
+        SwRect aRect( aPaintRect );
+        aPaintRect.Pos().Y() -= nOfst;
+        if ( ::lcl_IsOverObj( pCntnt, pPage, aPaintRect, aRect, 0 ) )
+            bScroll = FALSE;
+        aPaintRect.Pos().Y() += nOfst;
+    }
+    if ( bScroll && pPage->GetFmt()->GetBackground().GetGraphicPos() != GPOS_NONE )
+        bScroll = FALSE;
+
+    aPaintRect.Intersection( pCntnt->UnionFrm( TRUE ) );
+    if ( bScroll )
+    {
+        if( aPaintRect.HasArea() )
+            pImp->GetShell()->AddScrollRect( pCntnt, aPaintRect, nOfst );
+        if ( pCntnt->IsRetouche() && !pCntnt->GetNext() )
+        {
+            SwRect aRect( pCntnt->GetUpper()->PaintArea() );
+            aRect.Top( pCntnt->Frm().Top() + pCntnt->Prt().Bottom() + 1 );
+            if ( !pImp->GetShell()->AddPaintRect( aRect ) )
+                pCntnt->ResetRetouche();
+        }
+        pCntnt->ResetCompletePaint();
+    }
+    else if( aPaintRect.HasArea() )
+    {
+        aPaintRect.Pos().Y() -= nOfst;
+        PaintCntnt( pCntnt, pPage, aPaintRect, nOldBottom );
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwLayAction::SwLayAction()
+|*
+|*  Ersterstellung      MA 30. Oct. 92
+|*  Letzte Aenderung    MA 09. Jun. 95
+|*
+|*************************************************************************/
+SwLayAction::SwLayAction( SwRootFrm *pRt, SwViewImp *pI ) :
+    pRoot( pRt ),
+    pImp( pI ),
+    pOptTab( 0 ),
+    pWait( 0 ),
+    nPreInvaPage( USHRT_MAX ),
+    nCheckPageNum( USHRT_MAX ),
+    nStartTicks( Ticks() ),
+    nInputType( 0 ),
+    nEndPage( USHRT_MAX )
+{
+    bPaintExtraData = ::IsExtraData( pImp->GetShell()->GetDoc() );
+    bPaint = bComplete = bWaitAllowed = bCheckPages = TRUE;
+    bInput = bAgain = bNextCycle = bCalcLayout = bIdle = bReschedule =
+    bUpdateExpFlds = bBrowseActionStop = bActionInProgress = FALSE;
+    pImp->pLayAct = this;   //Anmelden
+}
+
+SwLayAction::~SwLayAction()
+{
+    ASSERT( !pWait, "Wait object not destroyed" );
+    pImp->pLayAct = 0;      //Abmelden
+}
+
+/*************************************************************************
+|*
+|*  SwLayAction::Reset()
+|*
+|*  Ersterstellung      MA 11. Aug. 94
+|*  Letzte Aenderung    MA 09. Jun. 95
+|*
+|*************************************************************************/
+void SwLayAction::Reset()
+{
+    pOptTab = 0;
+    nStartTicks = Ticks();
+    nInputType = 0;
+    nEndPage = nPreInvaPage = nCheckPageNum = USHRT_MAX;
+    bPaint = bComplete = bWaitAllowed = bCheckPages = TRUE;
+    bInput = bAgain = bNextCycle = bCalcLayout = bIdle = bReschedule =
+    bUpdateExpFlds = bBrowseActionStop = FALSE;
+}
+
+/*************************************************************************
+|*
+|*  SwLayAction::RemoveEmptyBrowserPages()
+|*
+|*  Ersterstellung      MA 10. Sep. 97
+|*  Letzte Aenderung    MA 10. Sep. 97
+|*
+|*************************************************************************/
+
+BOOL SwLayAction::RemoveEmptyBrowserPages()
+{
+    //Beim umschalten vom normalen in den Browsermodus bleiben u.U. einige
+    //unangenehm lange stehen. Diese beseiten wir mal schnell.
+    BOOL bRet = FALSE;
+    if ( pRoot->GetFmt()->GetDoc()->IsBrowseMode() )
+    {
+        SwPageFrm *pPage = (SwPageFrm*)pRoot->Lower();
+        do
+        {
+            if ( (pPage->GetSortedObjs() && pPage->GetSortedObjs()->Count()) ||
+                 pPage->ContainsCntnt() )
+                pPage = (SwPageFrm*)pPage->GetNext();
+            else
+            {
+                bRet = TRUE;
+                SwPageFrm *pDel = pPage;
+                pPage = (SwPageFrm*)pPage->GetNext();
+                pDel->Cut();
+                delete pDel;
+            }
+        } while ( pPage );
+    }
+    return bRet;
+}
+
+
+/*************************************************************************
+|*
+|*  SwLayAction::Action()
+|*
+|*  Ersterstellung      MA 10. Aug. 94
+|*  Letzte Aenderung    MA 06. Aug. 95
+|*
+|*************************************************************************/
+void SwLayAction::Action()
+{
+    bActionInProgress = TRUE;
+    //TurboMode? Disqualifiziert fuer Idle-Format.
+    if ( IsPaint() && !IsIdle() && TurboAction() )
+    {
+        delete pWait, pWait = 0;
+        pRoot->ResetTurboFlag();
+        bActionInProgress = FALSE;
+        pRoot->DeleteEmptySct();
+        return;
+    }
+    else if ( pRoot->GetTurbo() )
+    {
+        pRoot->DisallowTurbo();
+        const SwFrm *pFrm = pRoot->GetTurbo();
+        pRoot->ResetTurbo();
+        pFrm->InvalidatePage();
+    }
+    pRoot->DisallowTurbo();
+
+    if ( IsCalcLayout() )
+        SetCheckPages( FALSE );
+
+    InternalAction();
+    bAgain |= RemoveEmptyBrowserPages();
+    while ( IsAgain() )
+    {
+        bAgain = bNextCycle = FALSE;
+        InternalAction();
+        bAgain |= RemoveEmptyBrowserPages();
+    }
+    pRoot->DeleteEmptySct();
+
+    delete pWait, pWait = 0;
+
+    //Turbo-Action ist auf jedenfall wieder erlaubt.
+    pRoot->ResetTurboFlag();
+    pRoot->ResetTurbo();
+
+    if ( IsInput() )
+        pImp->GetShell()->SetNoNextScroll();
+    SetCheckPages( TRUE );
+    bActionInProgress = FALSE;
+}
+
+SwPageFrm *SwLayAction::CheckFirstVisPage( SwPageFrm *pPage )
+{
+    SwCntntFrm *pCnt = pPage->FindFirstBodyCntnt();
+    SwCntntFrm *pChk = pCnt;
+    BOOL bPageChgd = FALSE;
+    while ( pCnt && pCnt->IsFollow() )
+        pCnt = (SwCntntFrm*)pCnt->FindPrev();
+    if ( pCnt && pChk != pCnt )
+    {   bPageChgd = TRUE;
+        pPage = pCnt->FindPageFrm();
+    }
+
+    if ( pPage->GetFmt()->GetDoc()->GetFtnIdxs().Count() )
+    {
+        SwFtnContFrm *pCont = pPage->FindFtnCont();
+        if ( pCont )
+        {
+            pCnt = pCont->ContainsCntnt();
+            pChk = pCnt;
+            while ( pCnt && pCnt->IsFollow() )
+                pCnt = (SwCntntFrm*)pCnt->FindPrev();
+            if ( pCnt && pCnt != pChk )
+            {
+                if ( bPageChgd )
+                {
+                    //Die 'oberste' Seite benutzten.
+                    SwPageFrm *pTmp = pCnt->FindPageFrm();
+                    if ( pPage->GetPhyPageNum() > pTmp->GetPhyPageNum() )
+                        pPage = pTmp;
+                }
+                else
+                    pPage = pCnt->FindPageFrm();
+            }
+        }
+    }
+    return pPage;
+}
+
+void SwLayAction::InternalAction()
+{
+    ASSERT( pRoot->Lower()->IsPageFrm(), ":-( Keine Seite unterhalb der Root.");
+
+    pRoot->Calc();
+
+    //Die erste ungueltige bzw. zu formatierende Seite ermitteln.
+    //Bei einer Complete-Action ist es die erste ungueltige; mithin ist die
+    //erste zu formatierende Seite diejenige Seite mit der Numemr eins.
+    //Bei einer Luegen-Formatierung ist die Nummer der erste Seite die Nummer
+    //der ersten Sichtbaren Seite.
+    SwPageFrm *pPage = IsComplete() ? (SwPageFrm*)pRoot->Lower() :
+                pImp->GetFirstVisPage();
+    if ( !pPage )
+        pPage = (SwPageFrm*)pRoot->Lower();
+
+    //Wenn ein "Erster-Fliess-Cntnt" innerhalb der der ersten sichtbaren Seite
+    //ein Follow ist, so schalten wir die Seite zurueck auf den Ur-Master dieses
+    //Cntnt's
+    if ( !IsComplete() )
+        pPage = CheckFirstVisPage( pPage );
+    const USHORT nFirstPageNum = pPage->GetPhyPageNum();
+
+    while ( pPage && !pPage->IsInvalid() && !pPage->IsInvalidFly() )
+        pPage = (SwPageFrm*)pPage->GetNext();
+
+    SwDoc* pDoc = pRoot->GetFmt()->GetDoc();
+    BOOL bNoLoop = pPage ? SwLayouter::StartLoopControl( pDoc, pPage ) : NULL;
+    USHORT nPercentPageNum = 0;
+    while ( (pPage && !IsInput()) || nCheckPageNum != USHRT_MAX )
+    {
+        if ( !pPage && nCheckPageNum != USHRT_MAX &&
+             (!pPage || pPage->GetPhyPageNum() >= nCheckPageNum) )
+        {
+            if ( !pPage || pPage->GetPhyPageNum() > nCheckPageNum )
+            {
+                SwPageFrm *pPg = (SwPageFrm*)pRoot->Lower();
+                while ( pPg && pPg->GetPhyPageNum() < nCheckPageNum )
+                    pPg = (SwPageFrm*)pPg->GetNext();
+                if ( pPg )
+                    pPage = pPg;
+                if ( !pPage )
+                    break;
+            }
+            SwPageFrm *pTmp = pPage->GetPrev() ?
+                                        (SwPageFrm*)pPage->GetPrev() : pPage;
+            SetCheckPages( TRUE );
+            SwFrm::CheckPageDescs( pPage );
+            SetCheckPages( FALSE );
+            nCheckPageNum = USHRT_MAX;
+            pPage = pTmp;
+            continue;
+        }
+
+#ifdef MA_DEBUG
+        static USHORT nStop = USHRT_MAX;
+        if ( pPage->GetPhyPageNum() == nStop )
+        {
+            int bla = 5;
+        }
+        Window *pWin = pImp->GetShell()->GetWin();
+        if ( pWin )
+        {
+            pWin->Push( PUSH_FILLCOLOR );
+            pWin->SetFillColor( COL_WHITE );
+            Point aOfst( pImp->GetShell()->VisArea().Pos() );
+            pWin->DrawRect( Rectangle( aOfst, Size( 2000, 1000 )));
+            pWin->DrawText( Point( 500, 500 ) + aOfst, pPage->GetPhyPageNum() );
+            pWin->Pop();
+        }
+#endif
+        if ( nEndPage != USHRT_MAX && pPage->GetPhyPageNum() > nPercentPageNum )
+        {
+            nPercentPageNum = pPage->GetPhyPageNum();
+            ::SetProgressState( nPercentPageNum, pImp->GetShell()->GetDoc()->GetDocShell());
+        }
+        pOptTab = 0;
+             //Kein ShortCut fuer Idle oder CalcLayout
+        if ( !IsIdle() && !IsComplete() && IsShortCut( pPage ) )
+        {
+            pRoot->DeleteEmptySct();
+            XCHECKPAGE;
+            if ( !IsInput() &&
+                 (pRoot->IsSuperfluous() || pRoot->IsAssertFlyPages()) )
+            {
+                if ( pRoot->IsAssertFlyPages() )
+                    pRoot->AssertFlyPages();
+                if ( pRoot->IsSuperfluous() )
+                {
+                    BOOL bOld = IsAgain();
+                    pRoot->RemoveSuperfluous();
+                    bAgain = bOld;
+                }
+                if ( IsAgain() )
+                {
+                    if( bNoLoop )
+                        pDoc->GetLayouter()->EndLoopControl();
+                    return;
+                }
+                pPage = (SwPageFrm*)pRoot->Lower();
+                while ( pPage && !pPage->IsInvalid() && !pPage->IsInvalidFly() )
+                    pPage = (SwPageFrm*)pPage->GetNext();
+                while ( pPage && pPage->GetNext() &&
+                        pPage->GetPhyPageNum() < nFirstPageNum )
+                    pPage = (SwPageFrm*)pPage->GetNext();
+                continue;
+            }
+            break;
+        }
+        else
+        {
+            pRoot->DeleteEmptySct();
+            XCHECKPAGE;
+            //Erst das Layout der Seite formatieren. Erst wenn das Layout
+            //stabil ist lohnt sich die Inhaltsformatiertung.
+            //Wenn durch die Inhaltsformatierung das Layout wieder ungueltig
+            //wird, so wird die Inhaltsformatierung abgebrochen und das
+            //Layout wird wieder stabilisiert.
+            //Keine Angst: im Normafall kommt es nicht zu Oszillationen.
+            //Das Spielchen spielen wir zweimal. erst fuer die Flys, dann
+            //fuer den Rest.
+            //Die Flys haben Vorrang, d.h. wenn sich an den Flys waehrend der
+            //Formatierung des Bodys etwas aendert wird die Body-Formatierung
+            //unterbrochen und wieder bei den Flys angefangen.
+
+            while ( !IsInput() && !IsNextCycle() &&
+                    ((IS_FLYS && IS_INVAFLY) || pPage->IsInvalid()) )
+            {
+                while ( !IsInput() && IS_INVAFLY && IS_FLYS )
+                {
+                    XCHECKPAGE;
+                    if ( pPage->IsInvalidFlyLayout() )
+                    {
+                        pPage->ValidateFlyLayout();
+                        FormatFlyLayout( pPage );
+                        XCHECKPAGE;
+                    }
+                    if ( pPage->IsInvalidFlyCntnt() && IS_FLYS )
+                    {
+                        pPage->ValidateFlyCntnt();
+                        if ( !FormatFlyCntnt( pPage ) )
+                        {   XCHECKPAGE;
+                            pPage->InvalidateFlyCntnt();
+                        }
+                    }
+                }
+                if ( !IS_FLYS )
+                {
+                    //Wenn keine Flys (mehr) da sind, sind die Flags
+                    //mehr als fluessig.
+                    pPage->ValidateFlyLayout();
+                    pPage->ValidateFlyCntnt();
+                }
+                while ( !IsInput() && !IsNextCycle() && pPage->IsInvalid() &&
+                        (!IS_FLYS || (IS_FLYS && !IS_INVAFLY)) )
+                {
+                    PROTOCOL( pPage, PROT_FILE_INIT, 0, 0)
+                    XCHECKPAGE;
+                    while ( !IsNextCycle() && pPage->IsInvalidLayout() )
+                    {
+                        pPage->ValidateLayout();
+                        FormatLayout( pPage );
+                        XCHECKPAGE;
+                    }
+                    if ( !IsNextCycle() && pPage->IsInvalidCntnt() &&
+                         (!IS_FLYS || (IS_FLYS && !IS_INVAFLY)) )
+                    {
+                        pPage->ValidateFlyInCnt();
+                        pPage->ValidateCntnt();
+                        if ( !FormatCntnt( pPage ) )
+                        {
+                            XCHECKPAGE;
+                            pPage->InvalidateCntnt();
+                            pPage->InvalidateFlyInCnt();
+                            if ( IsBrowseActionStop() )
+                                bInput = TRUE;
+                        }
+                    }
+                    if( bNoLoop )
+                        pDoc->GetLayouter()->LoopControl( pPage, LOOP_PAGE );
+
+                }
+            }
+            //Eine vorige Seite kann wieder invalid sein.
+            XCHECKPAGE;
+            if ( !IS_FLYS )
+            {
+                //Wenn keine Flys (mehr) da sind, sind die Flags
+                //mehr als fluessig.
+                pPage->ValidateFlyLayout();
+                pPage->ValidateFlyCntnt();
+            }
+            if ( !IsInput() )
+            {
+                SetNextCycle( FALSE );
+
+                if ( nPreInvaPage != USHRT_MAX )
+                {
+                    while ( pPage->GetPrev() && pPage->GetPhyPageNum() > nPreInvaPage )
+                        pPage = (SwPageFrm*)pPage->GetPrev();
+                    nPreInvaPage = USHRT_MAX;
+                }
+
+                //Ist eine Vorseite invalid?
+                while ( pPage->GetPrev() &&
+                        ( ((SwPageFrm*)pPage->GetPrev())->IsInvalid() ||
+                          ( ((SwPageFrm*)pPage->GetPrev())->GetSortedObjs() &&
+                            ((SwPageFrm*)pPage->GetPrev())->IsInvalidFly())) &&
+                        (((SwPageFrm*)pPage->GetPrev())->GetPhyPageNum() >=
+                            nFirstPageNum) )
+                {
+                    pPage = (SwPageFrm*)pPage->GetPrev();
+                }
+                //Weiter bis zur naechsten invaliden Seite.
+                while ( pPage && !pPage->IsInvalid() &&
+                        (!IS_FLYS || (IS_FLYS && !IS_INVAFLY)) )
+                {
+                    pPage = (SwPageFrm*)pPage->GetNext();
+                }
+                if( bNoLoop )
+                    pDoc->GetLayouter()->LoopControl( pPage, LOOP_PAGE );
+            }
+        }
+        if ( !pPage && !IsInput() &&
+             (pRoot->IsSuperfluous() || pRoot->IsAssertFlyPages()) )
+        {
+            if ( pRoot->IsAssertFlyPages() )
+                pRoot->AssertFlyPages();
+            if ( pRoot->IsSuperfluous() )
+            {
+                BOOL bOld = IsAgain();
+                pRoot->RemoveSuperfluous();
+                bAgain = bOld;
+            }
+            if ( IsAgain() )
+            {
+                if( bNoLoop )
+                    pDoc->GetLayouter()->EndLoopControl();
+                return;
+            }
+            pPage = (SwPageFrm*)pRoot->Lower();
+            while ( pPage && !pPage->IsInvalid() && !pPage->IsInvalidFly() )
+                pPage = (SwPageFrm*)pPage->GetNext();
+            while ( pPage && pPage->GetNext() &&
+                    pPage->GetPhyPageNum() < nFirstPageNum )
+                pPage = (SwPageFrm*)pPage->GetNext();
+        }
+    }
+    if ( IsInput() && pPage )
+    {
+        //Wenn ein Input anliegt wollen wir keinen Inhalt mehr Formatieren,
+        //Das Layout muessen wir aber schon in Ordnung bringen.
+        //Andernfalls kann folgende Situation auftreten (Bug: 3244):
+        //Am Ende des Absatz der letzten Seite wird Text eingegeben, so das
+        //der Absatz einen Follow fuer die nachste Seite erzeugt, ausserdem
+        //wird gleich schnell weitergetippt - Es liegt waehrend der
+        //Verarbeitung ein Input an. Der Absatz auf der neuen Seite wurde
+        //bereits anformatiert, die neue Seite ist Formatiert und steht
+        //auf CompletePaint, hat sich aber noch nicht im Auszugebenden Bereich
+        //eingetragen. Es wird gepaintet, das CompletePaint der Seite wird
+        //zurueckgesetzt weil der neue Absatz sich bereits eingetragen hatte,
+        //aber die Raender der Seite werden nicht gepaintet. Naja, bei der
+        //zwangslaeufig auftretenden naechsten LayAction traegt sich die Seite
+        //nicht mehr ein, weil ihre (LayoutFrm-)Flags bereits zurueckgesetzt
+        //wurden -- Der Rand der Seite wird nie gepaintet.
+        SwPageFrm *pPg = pPage;
+        XCHECKPAGE;
+        const SwRect &rVis = pImp->GetShell()->VisArea();
+        while ( pPg && !(pPg->Frm().Top() >= rVis.Bottom() ||
+                         pPg->Frm().Left()>= rVis.Right()) )
+        {
+            XCHECKPAGE;
+            while ( pPg->IsInvalidLayout() )
+            {
+                pPg->ValidateLayout();
+                FormatLayout( pPg );
+                XCHECKPAGE;
+            }
+            pPg = (SwPageFrm*)pPg->GetNext();
+        }
+    }
+    pOptTab = 0;
+    if( bNoLoop )
+        pDoc->GetLayouter()->EndLoopControl();
+}
+/*************************************************************************
+|*
+|*  SwLayAction::TurboAction(), _TurboAction()
+|*
+|*  Ersterstellung      MA 04. Dec. 92
+|*  Letzte Aenderung    MA 15. Aug. 93
+|*
+|*************************************************************************/
+BOOL SwLayAction::_TurboAction( const SwCntntFrm *pCnt )
+{
+
+    const SwPageFrm *pPage = 0;
+    if ( !pCnt->IsValid() || pCnt->IsCompletePaint() || pCnt->IsRetouche() )
+    {
+        const SwRect aOldRect( pCnt->UnionFrm( TRUE ) );
+        const long   nOldBottom = pCnt->Frm().Top() + pCnt->Prt().Bottom();
+        pCnt->Calc();
+        if ( pCnt->Frm().Bottom() < aOldRect.Bottom() )
+            pCnt->SetRetouche();
+
+        pPage = pCnt->FindPageFrm();
+        PaintCntnt( pCnt, pPage, aOldRect, nOldBottom );
+
+        if ( !pCnt->GetValidLineNumFlag() && pCnt->IsTxtFrm() )
+        {
+            const ULONG nAllLines = ((SwTxtFrm*)pCnt)->GetAllLines();
+            ((SwTxtFrm*)pCnt)->RecalcAllLines();
+            if ( nAllLines != ((SwTxtFrm*)pCnt)->GetAllLines() )
+            {
+                if ( IsPaintExtraData() )
+                    pImp->GetShell()->AddPaintRect( pCnt->Frm() );
+                //Damit die restlichen LineNums auf der Seite bereichnet werden
+                //und nicht hier abgebrochen wird.
+                //Das im RecalcAllLines zu erledigen waere teuer, weil dort
+                //auch in unnoetigen Faellen (normale Action) auch immer die
+                //Seite benachrichtigt werden muesste.
+                const SwCntntFrm *pNxt = pCnt->GetNextCntntFrm();
+                while ( pNxt &&
+                        (pNxt->IsInTab() || pNxt->IsInDocBody() != pCnt->IsInDocBody()) )
+                    pNxt = pNxt->GetNextCntntFrm();
+                if ( pNxt )
+                    pNxt->InvalidatePage();
+            }
+            return FALSE;
+        }
+
+        if ( pPage->IsInvalidLayout() || (IS_FLYS && IS_INVAFLY) )
+            return FALSE;
+    }
+    if ( !pPage )
+        pPage = pCnt->FindPageFrm();
+    //Die im Absatz verankerten Flys wollen auch beachtet werden.
+    if ( pPage->IsInvalidFlyInCnt() && pCnt->GetDrawObjs() )
+    {
+        const SwDrawObjs *pObjs = pCnt->GetDrawObjs();
+        for ( USHORT i = 0; i < pObjs->Count(); ++i )
+        {
+            SdrObject *pO = (*pObjs)[i];
+            if ( pO->IsWriterFlyFrame() )
+            {
+                SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+                if ( pFly->IsFlyInCntFrm() && ((SwFlyInCntFrm*)pFly)->IsInvalid() )
+                {
+                    FormatFlyInCnt( (SwFlyInCntFrm*)pFly );
+                    pObjs = pCnt->GetDrawObjs();
+                }
+            }
+        }
+    }
+    if ( pPage->IsInvalidCntnt() )
+        return FALSE;
+    return TRUE;
+}
+
+BOOL SwLayAction::TurboAction()
+{
+    BOOL bRet = TRUE;
+
+    if ( pRoot->GetTurbo() )
+    {
+        if ( !_TurboAction( pRoot->GetTurbo() ) )
+        {
+            CheckIdleEnd();
+            bRet = FALSE;
+        }
+        pRoot->ResetTurbo();
+    }
+    else
+        bRet = FALSE;
+    return bRet;
+}
+/*************************************************************************
+|*
+|*  SwLayAction::IsShortCut()
+|*
+|*  Beschreibung:       Liefert ein True, wenn die Seite vollstaendig unter
+|*      oder rechts neben dem sichbaren Bereich liegt.
+|*      Es kann passieren, dass sich die Verhaeltnisse derart aendern, dass
+|*      die Verarbeitung (des Aufrufers!) mit der Vorgaengerseite der
+|*      uebergebenen Seite weitergefuehrt werden muss. Der Paramter wird also
+|*      ggf. veraendert!
+|*      Fuer den BrowseMode kann auch dann der ShortCut aktiviert werden,
+|*      wenn der ungueltige Inhalt der Seite unterhalb des sichbaren
+|*      bereiches liegt.
+|*  Ersterstellung      MA 30. Oct. 92
+|*  Letzte Aenderung    MA 18. Jul. 96
+|*
+|*************************************************************************/
+const SwFrm *lcl_FindFirstInvaLay( const SwFrm *pFrm, long nBottom )
+{
+    ASSERT( pFrm->IsLayoutFrm(), "FindFirstInvaLay, no LayFrm" );
+
+    if ( !pFrm->IsValid() || pFrm->IsCompletePaint() &&
+         pFrm->Frm().Top() < nBottom )
+        return pFrm;
+    pFrm = ((SwLayoutFrm*)pFrm)->Lower();
+    while ( pFrm )
+    {
+        if ( pFrm->IsLayoutFrm() )
+        {
+            if ( !pFrm->IsValid() || pFrm->IsCompletePaint() &&
+                 pFrm->Frm().Top() < nBottom )
+                return pFrm;
+            const SwFrm *pTmp;
+            if ( 0 != (pTmp = ::lcl_FindFirstInvaLay( pFrm, nBottom )) )
+                return pTmp;
+        }
+        pFrm = pFrm->GetNext();
+    }
+    return 0;
+}
+
+const SwFrm *lcl_FindFirstInvaCntnt( const SwLayoutFrm *pLay, long nBottom,
+                                     const SwCntntFrm *pFirst )
+{
+    const SwCntntFrm *pCnt = pFirst ? pFirst->GetNextCntntFrm() :
+                                      pLay->ContainsCntnt();
+    while ( pCnt )
+    {
+        if ( !pCnt->IsValid() || pCnt->IsCompletePaint() )
+        {
+            if ( pCnt->Frm().Top() <= nBottom )
+                return pCnt;
+        }
+
+        if ( pCnt->GetDrawObjs() )
+        {
+            const SwDrawObjs &rObjs = *pCnt->GetDrawObjs();
+            for ( USHORT i = 0; i < rObjs.Count(); ++i )
+            {
+                const SdrObject *pO = rObjs[i];
+                if ( pO->IsWriterFlyFrame() )
+                {
+                    const SwFlyFrm* pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+                    if ( pFly->IsFlyInCntFrm() )
+                    {
+                        if ( ((SwFlyInCntFrm*)pFly)->IsInvalid() ||
+                             pFly->IsCompletePaint() )
+                        {
+                            if ( pFly->Frm().Top() <= nBottom )
+                                return pFly;
+                        }
+                        const SwFrm *pFrm = lcl_FindFirstInvaCntnt( pFly, nBottom, 0 );
+                        if ( pFrm && pFrm->Frm().Bottom() <= nBottom )
+                            return pFrm;
+                    }
+                }
+            }
+        }
+        if ( pCnt->Frm().Top() > nBottom && !pCnt->IsInTab() )
+            return 0;
+        pCnt = pCnt->GetNextCntntFrm();
+        if ( !pLay->IsAnLower( pCnt ) )
+            break;
+    }
+    return 0;
+}
+
+const SwFrm *lcl_FindFirstInvaFly( const SwPageFrm *pPage, long nBottom )
+{
+    ASSERT( pPage->GetSortedObjs(), "FindFirstInvaFly, no Flys" )
+
+    for ( USHORT i = 0; i < pPage->GetSortedObjs()->Count(); ++i )
+    {
+        SdrObject *pO = (*pPage->GetSortedObjs())[i];
+        if ( pO->IsWriterFlyFrame() )
+        {
+            const SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+            if ( pFly->Frm().Top() <= nBottom )
+            {
+                if ( pFly->IsInvalid() || pFly->IsCompletePaint() )
+                    return pFly;
+
+                const SwFrm *pTmp;
+                if ( 0 != (pTmp = lcl_FindFirstInvaCntnt( pFly, nBottom, 0 )) &&
+                     pTmp->Frm().Top() <= nBottom )
+                    return pTmp;
+            }
+        }
+    }
+    return 0;
+}
+
+BOOL SwLayAction::IsShortCut( SwPageFrm *&prPage )
+{
+    BOOL bRet = FALSE;
+    const FASTBOOL bBrowse = pRoot->GetFmt()->GetDoc()->IsBrowseMode();
+
+    //Wenn die Seite nicht Gueltig ist wird sie schnell formatiert, sonst
+    //gibts nix als Aerger.
+    if ( !prPage->IsValid() )
+    {
+        if ( bBrowse )
+        {
+            prPage->Calc();
+            if ( prPage->Lower() )
+                prPage->Lower()->Calc();
+        }
+        else
+            FormatLayout( prPage );
+        if ( IsAgain() )
+            return FALSE;
+    }
+
+
+    const SwRect &rVis = pImp->GetShell()->VisArea();
+    if ( (prPage->Frm().Top() >= rVis.Bottom()) ||
+         (prPage->Frm().Left()>= rVis.Right()) )
+    {
+        bRet = TRUE;
+
+        //Jetzt wird es ein bischen unangenehm: Der erste CntntFrm dieser Seite
+        //im Bodytext muss Formatiert werden, wenn er dabei die Seite
+        //wechselt, muss ich nochmal eine Seite zuvor anfangen, denn
+        //es wurde ein PageBreak verarbeitet.
+//Noch unangenehmer: Der naechste CntntFrm ueberhaupt muss
+        //Formatiert werden, denn es kann passieren, dass kurzfristig
+        //leere Seiten existieren (Bsp. Absatz ueber mehrere Seiten
+        //wird geloescht oder verkleinert).
+
+        //Ist fuer den Browser uninteressant, wenn der letzte Cnt davor bereits
+        //nicht mehr sichbar ist.
+
+        const SwPageFrm *p2ndPage = prPage;
+        const SwCntntFrm *pCntnt;
+        const SwLayoutFrm* pBody = p2ndPage->FindBodyCont();
+        if( p2ndPage->IsFtnPage() && pBody )
+            pBody = (SwLayoutFrm*)pBody->GetNext();
+        pCntnt = pBody ? pBody->ContainsCntnt() : 0;
+        while ( p2ndPage && !pCntnt )
+        {
+            p2ndPage = (SwPageFrm*)p2ndPage->GetNext();
+            if( p2ndPage )
+            {
+                pBody = p2ndPage->FindBodyCont();
+                if( p2ndPage->IsFtnPage() && pBody )
+                    pBody = (SwLayoutFrm*)pBody->GetNext();
+                pCntnt = pBody ? pBody->ContainsCntnt() : 0;
+            }
+        }
+        if ( pCntnt )
+        {
+            FASTBOOL bTstCnt = TRUE;
+            if ( bBrowse )
+            {
+                //Der Cnt davor schon nicht mehr sichtbar?
+                const SwFrm *pLst = pCntnt;
+                if ( pLst->IsInTab() )
+                    pLst = pCntnt->FindTabFrm();
+                if ( pLst->IsInSct() )
+                    pLst = pCntnt->FindSctFrm();
+                pLst = pLst->FindPrev();
+                if ( pLst &&
+                     (pLst->Frm().Top() >= rVis.Bottom() ||
+                      pLst->Frm().Left()>= rVis.Right()) )
+                {
+                    bTstCnt = FALSE;
+                }
+            }
+
+            if ( bTstCnt )
+            {
+                if ( pCntnt->IsInSct() )
+                {
+                    const SwSectionFrm *pSct = ((SwFrm*)pCntnt)->ImplFindSctFrm();
+                    if ( !pSct->IsValid() )
+                    {
+                        pSct->Calc();
+                        pSct->SetCompletePaint();
+                        if ( IsAgain() )
+                            return FALSE;
+                    }
+                }
+                if ( !pCntnt->IsValid() )
+                {   pCntnt->Calc();
+                    pCntnt->SetCompletePaint();
+                    if ( IsAgain() )
+                        return FALSE;
+                }
+                if ( pCntnt->IsInTab() )
+                {
+                    const SwTabFrm *pTab = ((SwFrm*)pCntnt)->ImplFindTabFrm();
+                    if ( !pTab->IsValid() )
+                    {
+                        pTab->Calc();
+                        pTab->SetCompletePaint();
+                        if ( IsAgain() )
+                            return FALSE;
+                    }
+                }
+                if ( pCntnt->IsInSct() )
+                {
+                    const SwSectionFrm *pSct = ((SwFrm*)pCntnt)->ImplFindSctFrm();
+                    if ( !pSct->IsValid() )
+                    {
+                        pSct->Calc();
+                        pSct->SetCompletePaint();
+                        if ( IsAgain() )
+                            return FALSE;
+                    }
+                }
+#ifdef USED
+                if ( (pCntnt->FindPageFrm() != p2ndPage) &&
+                     prPage->GetPrev() )
+                {
+                    prPage = (SwPageFrm*)prPage->GetPrev();
+                    bRet = FALSE;
+                }
+#else
+                const SwPageFrm* pTmp = pCntnt->FindPageFrm();
+                if ( pTmp != p2ndPage && prPage->GetPrev() )
+                {
+                    bRet = FALSE;
+                    if( pTmp->GetPhyPageNum() < prPage->GetPhyPageNum()
+                        && pTmp->IsInvalid() )
+                        prPage = (SwPageFrm*)pTmp;
+                    else
+                        prPage = (SwPageFrm*)prPage->GetPrev();
+                }
+#endif
+            }
+        }
+    }
+
+    if ( !bRet && bBrowse )
+    {
+        const long nBottom = rVis.Bottom();
+        const SwFrm *pFrm;
+        if ( prPage->GetSortedObjs() &&
+             (prPage->IsInvalidFlyLayout() || prPage->IsInvalidFlyCntnt()) &&
+             0 != (pFrm = lcl_FindFirstInvaFly( prPage, nBottom )) &&
+             pFrm->Frm().Top() <= nBottom )
+        {
+            return FALSE;
+        }
+        if ( prPage->IsInvalidLayout() &&
+             0 != (pFrm = lcl_FindFirstInvaLay( prPage, nBottom )) &&
+             pFrm->Frm().Top() <= nBottom )
+        {
+            return FALSE;
+        }
+        if ( (prPage->IsInvalidCntnt() || prPage->IsInvalidFlyInCnt()) &&
+             0 != (pFrm = lcl_FindFirstInvaCntnt( prPage, nBottom, 0 )) &&
+             pFrm->Frm().Top() <= nBottom )
+        {
+            return FALSE;
+        }
+        bRet = TRUE;
+    }
+    return bRet;
+}
+
+/*************************************************************************
+|*
+|*  SwLayAction::ChkFlyAnchor()
+|*
+|*  Ersterstellung      MA 30. Oct. 92
+|*  Letzte Aenderung    MA 02. Sep. 96
+|*
+|*************************************************************************/
+void SwLayAction::ChkFlyAnchor( SwFlyFrm *pFly, const SwPageFrm *pPage )
+{
+    //Wenn der Fly innerhalb eines anderen Rahmens gebunden ist, so sollte
+    //dieser zuerst Formatiert werden.
+
+    if ( pFly->GetAnchor()->IsInTab() )
+        pFly->GetAnchor()->FindTabFrm()->Calc();
+
+    SwFlyFrm *pAnch = pFly->GetAnchor()->FindFlyFrm();
+    if ( pAnch )
+    {
+        ChkFlyAnchor( pAnch, pPage );
+        CHECKPAGE;
+        while ( pPage == pAnch->FindPageFrm() && FormatLayoutFly( pAnch ) )
+            /* do nothing */;
+    }
+}
+
+
+/*************************************************************************
+|*
+|*  SwLayAction::FormatFlyLayout()
+|*
+|*  Ersterstellung      MA 30. Oct. 92
+|*  Letzte Aenderung    MA 03. Jun. 96
+|*
+|*************************************************************************/
+void SwLayAction::FormatFlyLayout( const SwPageFrm *pPage )
+{
+    for ( USHORT i = 0; pPage->GetSortedObjs() &&
+                        i < pPage->GetSortedObjs()->Count(); ++i )
+    {
+        SdrObject *pO = (*pPage->GetSortedObjs())[i];
+        if ( pO->IsWriterFlyFrame() )
+        {
+            const USHORT nOld = i;
+            SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+            ChkFlyAnchor( pFly, pPage );
+            if ( IsAgain() )
+                return;
+            while ( pPage == pFly->FindPageFrm() )
+            {
+                SwFrmFmt *pFmt = pFly->GetFmt();
+                if( FLY_AUTO_CNTNT == pFmt->GetAnchor().GetAnchorId() &&
+                    pFly->GetAnchor() &&
+                    ( REL_CHAR == pFmt->GetHoriOrient().GetRelationOrient() ||
+                      REL_CHAR == pFmt->GetVertOrient().GetRelationOrient() ) )
+                    _FormatCntnt( (SwCntntFrm*)pFly->GetAnchor(), pPage );
+                 if( !FormatLayoutFly( pFly ) )
+                    break;
+            }
+            CHECKPAGE;
+            if ( !IS_FLYS )
+                break;
+            if ( nOld > pPage->GetSortedObjs()->Count() )
+                i -= nOld - pPage->GetSortedObjs()->Count();
+            else
+            {   //Positionswechsel!
+                USHORT nAct;
+                pPage->GetSortedObjs()->Seek_Entry(pFly->GetVirtDrawObj(),&nAct);
+                if ( nAct < i )
+                    i = nAct;
+                else if ( nAct > i )
+                    --i;
+            }
+        }
+    }
+}
+/*************************************************************************
+|*
+|*  SwLayAction::FormatLayout(), FormatLayoutFly, FormatLayoutTab()
+|*
+|*  Ersterstellung      MA 30. Oct. 92
+|*  Letzte Aenderung    MA 18. May. 98
+|*
+|*************************************************************************/
+BOOL SwLayAction::FormatLayout( SwLayoutFrm *pLay, BOOL bAddRect )
+{
+    ASSERT( !IsAgain(), "Ungueltige Seite beachten." );
+    if ( IsAgain() )
+        return FALSE;
+
+    BOOL bChanged = FALSE;
+
+    if ( !pLay->IsValid() || pLay->IsCompletePaint() )
+    {
+        if ( pLay->GetPrev() && !pLay->GetPrev()->IsValid() )
+            pLay->GetPrev()->SetCompletePaint();
+
+        SwRect aOldRect( pLay->Frm() );
+        pLay->Calc();
+        if ( aOldRect != pLay->Frm() )
+            bChanged = TRUE;
+
+        FASTBOOL bNoPaint = FALSE;
+        if ( pLay->IsPageBodyFrm() && pLay->Frm().Pos() == aOldRect.Pos() &&
+             pLay->Lower() && pLay->GetFmt()->GetDoc()->IsBrowseMode() )
+        {
+            //HotFix: Vobis Homepage, nicht so genau hinsehen, sonst
+            //rpaints
+
+            //Einschraenkungen wegen Kopf-/Fusszeilen
+            if ( !(pLay->IsCompletePaint() &&
+                   (pLay->GetFmt()->GetDoc()->IsHeadInBrowse() ||
+                    pLay->GetFmt()->GetDoc()->IsFootInBrowse() ||
+                    pLay->FindPageFrm()->FindFtnCont())))
+            {
+                bNoPaint = TRUE;
+            }
+        }
+
+        if ( !bNoPaint && IsPaint() && bAddRect && (pLay->IsCompletePaint() || bChanged) )
+        {
+            SwRect aPaint( pLay->Frm() );
+            aPaint.Pos().Y() -= 1;
+            aPaint.Pos().X() -= 1;
+            aPaint.SSize().Height() += 2;
+            aPaint.SSize().Width()  += 2;
+            if ( pLay->IsPageFrm() && pLay->GetFmt()->GetDoc()->IsBrowseMode() )
+            {
+                //Ist die Aenderung ueberhaupt sichtbar?
+                if ( pLay->IsCompletePaint() )
+                {
+                    pImp->GetShell()->AddPaintRect( aPaint );
+                    bAddRect = FALSE;
+                }
+                else
+                {
+                    SwRegionRects aRegion( aOldRect );
+                    aRegion -= aPaint;
+                    for ( USHORT i = 0; i < aRegion.Count(); ++i )
+                        pImp->GetShell()->AddPaintRect( aRegion[i] );
+                    aRegion.ChangeOrigin( aPaint );
+                    aRegion.Remove( 0, aRegion.Count() );
+                    aRegion.Insert( aPaint, 0 );
+                    aRegion -= aOldRect;
+                    for ( i = 0; i < aRegion.Count(); ++i )
+                        pImp->GetShell()->AddPaintRect( aRegion[i] );
+                }
+
+                //ggf. die Zwischenraeume mit invalidieren.
+                if ( pLay->GetPrev() )
+                {
+                    SwRect aTmp( aPaint );
+                    long nTmp = aTmp.Top() - DOCUMENTBORDER/2;
+                    if ( nTmp >= 0 )
+                        aTmp.Top( nTmp );
+                    aTmp.Bottom( pLay->Frm().Top() );
+                    pImp->GetShell()->AddPaintRect( aTmp );
+                }
+                if ( pLay->GetNext() )
+                {
+                    aPaint.Bottom( aPaint.Bottom() + DOCUMENTBORDER/2 );
+                    aPaint.Top( pLay->Frm().Bottom() );
+                    pImp->GetShell()->AddPaintRect( aPaint );
+                }
+            }
+            else
+            {
+                pImp->GetShell()->AddPaintRect( aPaint );
+                bAddRect = FALSE;
+            }
+        }
+        pLay->ResetCompletePaint();
+    }
+
+    if ( IsPaint() && bAddRect &&
+         !pLay->GetNext() && pLay->IsRetoucheFrm() && pLay->IsRetouche() )
+    {
+        SwRect aRect( pLay->GetUpper()->Prt() );
+        aRect += pLay->GetUpper()->Frm().Pos();
+        aRect.Top( pLay->Frm().Top() + pLay->Prt().Bottom() + 1 );
+        if ( !pImp->GetShell()->AddPaintRect( aRect ) )
+            pLay->ResetRetouche();
+    }
+
+    CheckWaitCrsr();
+
+    if ( IsAgain() )
+        return FALSE;
+
+    //Jetzt noch diejenigen Lowers versorgen die LayoutFrm's sind
+
+    if ( pLay->IsFtnFrm() ) //Hat keine LayFrms als Lower.
+        return bChanged;
+
+    SwFrm *pLow = pLay->Lower();
+    BOOL bTabChanged = FALSE;
+    while ( pLow && pLow->GetUpper() == pLay )
+    {
+        if ( pLow->IsLayoutFrm() )
+        {
+            if ( pLow->IsTabFrm() )
+                bTabChanged |= FormatLayoutTab( (SwTabFrm*)pLow, bAddRect );
+            // bereits zum Loeschen angemeldete Ueberspringen
+            else if( !pLow->IsSctFrm() || ((SwSectionFrm*)pLow)->GetSection() )
+                bChanged |= FormatLayout( (SwLayoutFrm*)pLow, bAddRect );
+        }
+        else if ( pImp->GetShell()->IsPaintLocked() )
+            //Abkuerzung im die Zyklen zu minimieren, bei Lock kommt das
+            //Paint sowieso (Primaer fuer Browse)
+            pLow->OptCalc();
+
+        if ( IsAgain() )
+            return FALSE;
+        pLow = pLow->GetNext();
+    }
+    return bChanged || bTabChanged;
+}
+
+BOOL SwLayAction::FormatLayoutFly( SwFlyFrm *pFly, BOOL bAddRect )
+{
+    ASSERT( !IsAgain(), "Ungueltige Seite beachten." );
+    if ( IsAgain() )
+        return FALSE;
+
+    BOOL bChanged = FALSE;
+
+    if ( !pFly->IsValid() || pFly->IsCompletePaint() || pFly->IsInvalid() )
+    {
+        //Der Frame hat sich veraendert, er wird jetzt Formatiert
+        const SwRect aOldRect( pFly->Frm() );
+        pFly->Calc();
+        bChanged = aOldRect != pFly->Frm();
+
+        if ( IsPaint() && bAddRect && (pFly->IsCompletePaint() || bChanged) &&
+             pFly->Frm().Top() > 0 && pFly->Frm().Left() > 0 )
+            pImp->GetShell()->AddPaintRect( pFly->Frm() );
+
+        if ( bChanged )
+            pFly->Invalidate();
+        else
+            pFly->Validate();
+        bAddRect = FALSE;
+        pFly->ResetCompletePaint();
+    }
+
+    if ( IsAgain() )
+        return FALSE;
+
+    //Jetzt noch diejenigen Lowers versorgen die LayoutFrm's sind
+    BOOL bTabChanged = FALSE;
+    SwFrm *pLow = pFly->Lower();
+    while ( pLow )
+    {
+        if ( pLow->IsLayoutFrm() )
+        {
+            if ( pLow->IsTabFrm() )
+                bTabChanged |= FormatLayoutTab( (SwTabFrm*)pLow, bAddRect );
+            else
+                bChanged |= FormatLayout( (SwLayoutFrm*)pLow, bAddRect );
+        }
+        pLow = pLow->GetNext();
+    }
+    return bChanged || bTabChanged;
+}
+
+BOOL MA_FASTCALL lcl_AreLowersScrollable( const SwLayoutFrm *pLay )
+{
+    const SwFrm *pLow = pLay->Lower();
+    while ( pLow )
+    {
+        if ( pLow->IsCompletePaint() || !pLow->IsValid() )
+            return FALSE;
+        if ( pLow->IsLayoutFrm() && !::lcl_AreLowersScrollable( (SwLayoutFrm*)pLow ))
+            return FALSE;
+        pLow = pLow->GetNext();
+    }
+    return TRUE;
+}
+
+SwLayoutFrm * MA_FASTCALL lcl_IsTabScrollable( SwTabFrm *pTab )
+{
+    //returnt die erste unveraenderte Zeile, oder 0 wenn nicht
+    //gescrollt werden darf.
+    if ( !pTab->IsCompletePaint() )
+    {
+        SwLayoutFrm *pUnchgdRow = 0;
+        SwLayoutFrm *pRow = (SwLayoutFrm*)pTab->Lower();
+        while ( pRow )
+        {
+            if ( !::lcl_AreLowersScrollable( pRow ) )
+                pUnchgdRow = 0;
+            else if ( !pUnchgdRow )
+                pUnchgdRow = pRow;
+            pRow = (SwLayoutFrm*)pRow->GetNext();
+        }
+        return pUnchgdRow;
+    }
+    return 0;
+}
+
+void MA_FASTCALL lcl_ValidateLowers( SwLayoutFrm *pLay, const SwTwips nOfst,
+                        SwLayoutFrm *pRow, SwPageFrm *pPage,
+                        BOOL bResetOnly )
+{
+    pLay->ResetCompletePaint();
+    SwFrm *pLow = pLay->Lower();
+    if ( pRow )
+        while ( pLow != pRow )
+            pLow = pLow->GetNext();
+
+    while ( pLow )
+    {
+        if ( !bResetOnly )
+        {
+            pLow->Frm().Pos().Y() += nOfst;
+//#55435# schon hier wuerden die zeichengeb. Rahmen formatiert und dann unten
+//faelschlich noch einmal verschoben.
+            //pLow->Calc();
+        }
+        if ( pLow->IsLayoutFrm() )
+            ::lcl_ValidateLowers( (SwLayoutFrm*)pLow, nOfst, 0, pPage, bResetOnly);
+        else
+        {
+            pLow->ResetCompletePaint();
+            if ( pLow->GetDrawObjs() )
+            {
+                for ( USHORT i = 0; i < pLow->GetDrawObjs()->Count(); ++i )
+                {
+                    SdrObject *pO = (*pLow->GetDrawObjs())[i];
+                    if ( pO->IsWriterFlyFrame() )
+                    {
+                        SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+                        if ( !bResetOnly )
+                        {
+                            pFly->Frm().Pos().Y() += nOfst;
+                            if ( pFly->IsFlyInCntFrm() )
+                                ((SwFlyInCntFrm*)pFly)->AddRefOfst( nOfst );
+                        }
+                        ::lcl_ValidateLowers( pFly, nOfst, 0, pPage, bResetOnly);
+                    }
+                    else
+                    {
+                        pO->SetAnchorPos( pLow->Frm().Pos() );
+                        SwFrmFmt *pFrmFmt = FindFrmFmt( pO );
+                        if( !pFrmFmt ||
+                            FLY_IN_CNTNT != pFrmFmt->GetAnchor().GetAnchorId() )
+                            ((SwDrawContact*)pO->GetUserCall())->ChkPage();
+                    }
+                }
+            }
+        }
+        if ( !bResetOnly )
+            pLow->Calc();           //#55435# Stabil halten.
+        pLow = pLow->GetNext();
+    }
+}
+
+void MA_FASTCALL lcl_AddScrollRectTab( SwTabFrm *pTab, SwLayoutFrm *pRow,
+                               const SwRect &rRect,
+                               const SwTwips nOfst)
+{
+    //Wenn altes oder neues Rechteck mit einem Fly ueberlappen, in dem der
+    //Frm nicht selbst steht, so ist nichts mit Scrollen.
+    const SwPageFrm *pPage = pTab->FindPageFrm();
+    SwRect aRect( rRect );
+    aRect.Pos().Y() += nOfst;
+    if ( pPage->GetSortedObjs() )
+    {
+        if ( ::lcl_IsOverObj( pTab, pPage, rRect, aRect, pTab ) )
+            return;
+    }
+    if ( pPage->GetFmt()->GetBackground().GetGraphicPos() != GPOS_NONE )
+        return;
+
+    ViewShell *pSh = pPage->GetShell();
+    if ( pSh )
+        pSh->AddScrollRect( pTab, aRect, nOfst );
+    ::lcl_ValidateLowers( pTab, nOfst, pRow, pTab->FindPageFrm(),
+                                                pTab->IsLowersFormatted() );
+}
+
+BOOL CheckPos( SwFrm *pFrm )
+{
+    if ( !pFrm->GetValidPosFlag() )
+    {
+        Point aOld( pFrm->Frm().Pos() );
+        pFrm->MakePos();
+        if ( aOld != pFrm->Frm().Pos() )
+        {
+            pFrm->Frm().Pos( aOld );
+            pFrm->_InvalidatePos();
+            return FALSE;
+        }
+    }
+    return TRUE;
+}
+
+BOOL SwLayAction::FormatLayoutTab( SwTabFrm *pTab, BOOL bAddRect )
+{
+    ASSERT( !IsAgain(), "8-) Ungueltige Seite beachten." );
+    if ( IsAgain() )
+        return FALSE;
+
+    BOOL bChanged = FALSE;
+    FASTBOOL bPainted = FALSE;
+
+    const SwPageFrm *pOldPage = pTab->FindPageFrm();
+
+    if ( !pTab->IsValid() || pTab->IsCompletePaint() || pTab->IsComplete() )
+    {
+        if ( pTab->GetPrev() && !pTab->GetPrev()->IsValid() )
+            pTab->GetPrev()->SetCompletePaint();
+
+        //Potenzielles Scrollrect ist die ganze Tabelle. Da bereits ein
+        //Wachstum innerhalb der Tabelle - und damit der Tabelle selbst -
+        //stattgefunden haben kann, muss die untere Kante durch die
+        //Unterkante der letzten Zeile bestimmt werden.
+        SwLayoutFrm *pRow;
+        SwRect aScrollRect( pTab->PaintArea() );
+        if ( IsPaint() || bAddRect )
+        {
+            pRow = (SwLayoutFrm*)pTab->Lower();
+            while ( pRow->GetNext() )
+                pRow = (SwLayoutFrm*)pRow->GetNext();
+            aScrollRect.Bottom( pRow->Frm().Bottom() );
+            //Die Oberkante wird ggf. durch die erste unveraenderte Zeile bestimmt.
+            pRow = ::lcl_IsTabScrollable( pTab );
+            if ( pRow && pRow != pTab->Lower() )
+                aScrollRect.Top( pRow->Frm().Top() );
+        }
+
+        const SwFrm *pOldUp = pTab->GetUpper();
+
+        SwRect aOldRect( pTab->Frm() );
+        pTab->SetLowersFormatted( FALSE );
+        pTab->Calc();
+        if ( aOldRect != pTab->Frm() )
+            bChanged = TRUE;
+        SwRect aPaintFrm = pTab->PaintArea();
+
+        if ( IsPaint() && bAddRect )
+        {
+            if ( pRow && pOldUp == pTab->GetUpper() &&
+                 pTab->Frm().SSize() == aOldRect.SSize() &&
+                 pTab->Frm().Left()  == aOldRect.Left() &&
+                 pTab->IsAnLower( pRow ) )
+            {
+                SwTwips nOfst;
+                if ( pRow->GetPrev() )
+                {
+                    if ( pRow->GetPrev()->IsValid() ||
+                         ::CheckPos( pRow->GetPrev() ) )
+                        nOfst = (pRow->GetPrev()->Frm().Bottom()+1) - pRow->Frm().Top();
+                    else
+                        nOfst = 0;
+                }
+                else
+                    nOfst = pTab->Frm().Top() - aOldRect.Top();
+
+                if ( nOfst )
+                {
+                     ::lcl_AddScrollRectTab( pTab, pRow, aScrollRect, nOfst );
+                     bPainted = TRUE;
+                }
+            }
+
+            if ( !pTab->IsCompletePaint() && pTab->IsComplete() &&
+                 ( pTab->Frm().SSize() != pTab->Prt().SSize() ||
+                   pTab->Prt().Left() ) )
+            {
+                if ( pTab->Frm().Height() != pTab->Prt().Height() )
+                {
+                    if ( pTab->Prt().Top() )
+                    {
+                        aOldRect = pTab->Frm();
+                        aOldRect.Height( pTab->Prt().Top() );
+                        pImp->GetShell()->AddPaintRect( aOldRect );
+                    }
+                    aOldRect.Height( pTab->Frm().Height() );
+                    aOldRect.Top( aOldRect.Top() + pTab->Prt().Height() );
+                    if ( aOldRect.HasArea() )
+                        pImp->GetShell()->AddPaintRect( aOldRect );
+                }
+                if ( pTab->Frm().Width() != pTab->Prt().Width() ||
+                     pTab->Prt().Left() )
+                {
+                    if ( pTab->Prt().Left() > 0 )
+                    {
+                        aOldRect = pTab->Frm();
+                        aOldRect.Width( pTab->Prt().Left() );
+                        pImp->GetShell()->AddPaintRect( aOldRect );
+                    }
+                    aOldRect.Width( pTab->Frm().Width() );
+                    if( pTab->Prt().Left() + pTab->Prt().Width() <
+                        aOldRect.Left() + aOldRect.Width() )
+                    {
+                        aOldRect.Left( aOldRect.Left() + pTab->Prt().Right() );
+                        if ( aOldRect.HasArea() )
+                            pImp->GetShell()->AddPaintRect( aOldRect );
+                    }
+                }
+            }
+            else if ( pTab->IsCompletePaint() )
+            {
+                pImp->GetShell()->AddPaintRect( aPaintFrm );
+                bAddRect = FALSE;
+                bPainted = TRUE;
+            }
+            if ( pTab->IsRetouche() && !pTab->GetNext() )
+            {
+                SwRect aRect( pTab->GetUpper()->PaintArea() );
+                aRect.Top( pTab->Frm().Top() + pTab->Prt().Bottom() - 1 );
+                if ( !pImp->GetShell()->AddPaintRect( aRect ) )
+                    pTab->ResetRetouche();
+            }
+        }
+        else
+            bAddRect = FALSE;
+
+        if ( pTab->IsCompletePaint() && !pOptTab )
+            pOptTab = pTab;
+        pTab->ResetCompletePaint();
+    }
+    if ( IsPaint() && bAddRect && pTab->IsRetouche() && !pTab->GetNext() )
+    {
+        SwRect aRect( pTab->PaintArea() );
+        aRect.Top( pTab->Frm().Top() + pTab->Prt().Bottom() + 1 );
+        if ( !pImp->GetShell()->AddPaintRect( aRect ) )
+            pTab->ResetRetouche();
+    }
+
+    CheckWaitCrsr();
+
+    //Heftige Abkuerzung!
+    if ( pTab->IsLowersFormatted() &&
+         (bPainted || !pImp->GetShell()->VisArea().IsOver( pTab->Frm())) )
+        return FALSE;
+
+    //Jetzt noch die Lowers versorgen
+    if ( IsAgain() )
+        return FALSE;
+    SwLayoutFrm *pLow = (SwLayoutFrm*)pTab->Lower();
+    while ( pLow )
+    {
+        bChanged |= FormatLayout( (SwLayoutFrm*)pLow, bAddRect );
+        if ( IsAgain() )
+            return FALSE;
+        pLow = (SwLayoutFrm*)pLow->GetNext();
+    }
+
+    if ( pOldPage->GetPhyPageNum() > (pTab->FindPageFrm()->GetPhyPageNum() + 1) )
+        SetNextCycle( TRUE );
+
+    return bChanged;
+}
+
+/*************************************************************************
+|*
+|*  SwLayAction::FormatCntnt()
+|*
+|*  Ersterstellung      MA 30. Oct. 92
+|*  Letzte Aenderung    MA 16. Nov. 95
+|*
+|*************************************************************************/
+BOOL SwLayAction::FormatCntnt( const SwPageFrm *pPage )
+{
+    const SwCntntFrm *pCntnt = pPage->ContainsCntnt();
+    const FASTBOOL bBrowse = pRoot->GetFmt()->GetDoc()->IsBrowseMode();
+
+    while ( pCntnt && pPage->IsAnLower( pCntnt ) )
+    {
+        //Wenn der Cntnt sich eh nicht veraendert koennen wir ein paar
+        //Abkuerzungen nutzen.
+        const BOOL bFull = !pCntnt->IsValid() || pCntnt->IsCompletePaint() ||
+                           pCntnt->IsRetouche() || pCntnt->GetDrawObjs();
+        if ( bFull )
+        {
+            //Damit wir nacher nicht suchen muessen.
+            const BOOL bNxtCnt = IsCalcLayout() && !pCntnt->GetFollow();
+            const SwCntntFrm *pCntntNext = bNxtCnt ? pCntnt->GetNextCntntFrm() : 0;
+            const SwCntntFrm *pCntntPrev = pCntnt->GetPrev() ? pCntnt->GetPrevCntntFrm() : 0;
+
+            const SwLayoutFrm*pOldUpper  = pCntnt->GetUpper();
+            const SwTabFrm *pTab = pCntnt->FindTabFrm();
+            const BOOL bInValid = !pCntnt->IsValid() || pCntnt->IsCompletePaint();
+            const BOOL bOldPaint = IsPaint();
+            bPaint = bOldPaint && !(pTab && pTab == pOptTab);
+            _FormatCntnt( pCntnt, pPage );
+            bPaint = bOldPaint;
+
+            if ( !pCntnt->GetValidLineNumFlag() && pCntnt->IsTxtFrm() )
+            {
+                const ULONG nAllLines = ((SwTxtFrm*)pCntnt)->GetAllLines();
+                ((SwTxtFrm*)pCntnt)->RecalcAllLines();
+                if ( IsPaintExtraData() && IsPaint() &&
+                     nAllLines != ((SwTxtFrm*)pCntnt)->GetAllLines() )
+                    pImp->GetShell()->AddPaintRect( pCntnt->Frm() );
+            }
+
+            if ( IsAgain() )
+                return FALSE;
+
+            //Wenn Layout oder Flys wieder Invalid sind breche ich die Verarbeitung
+            //vorlaeufig ab - allerdings nicht fuer die BrowseView, denn dort wird
+            //das Layout staendig ungueltig, weil die Seitenhoehe angepasst wird.
+            //Desgleichen wenn der Benutzer weiterarbeiten will und mindestens ein
+            //Absatz verarbeitet wurde.
+            if ( (!pTab || (pTab && !bInValid)) )
+            {
+                CheckIdleEnd();
+                if ( IsInput() || (!bBrowse && pPage->IsInvalidLayout()) ||
+                     (IS_FLYS && IS_INVAFLY) )
+                    return FALSE;
+            }
+            if ( pOldUpper != pCntnt->GetUpper() )
+            {
+                const USHORT nCurNum = pCntnt->FindPageFrm()->GetPhyPageNum();
+                if (  nCurNum < pPage->GetPhyPageNum() )
+                    nPreInvaPage = nCurNum;
+
+                //Wenn der Frm mehr als eine Seite rueckwaerts geflossen ist, so
+                //fangen wir nocheinmal von vorn an damit wir nichts auslassen.
+                if ( !IsCalcLayout() && pPage->GetPhyPageNum() > nCurNum+1 )
+                {
+                    SetNextCycle( TRUE );
+                    return FALSE;
+                }
+            }
+            //Wenn der Frame die Seite vorwaerts gewechselt hat, so lassen wir
+            //den Vorgaenger nocheinmal durchlaufen.
+            //So werden einerseits Vorgaenger erwischt, die jetzt fr Retouche
+            //verantwortlich sind, andererseits werden die Fusszeilen
+            //auch angefasst.
+            FASTBOOL bSetCntnt = TRUE;
+            if ( pCntntPrev )
+            {
+                if ( !pCntntPrev->IsValid() )
+                    pPage->InvalidateCntnt();
+                if ( pOldUpper != pCntnt->GetUpper() &&
+                     pPage->GetPhyPageNum() < pCntnt->FindPageFrm()->GetPhyPageNum() )
+                {
+                    pCntnt = pCntntPrev;
+                    bSetCntnt = FALSE;
+                }
+            }
+            if ( bSetCntnt )
+            {
+                if ( bBrowse && !IsIdle() && !IsCalcLayout() && !IsComplete() &&
+                     pCntnt->Frm().Top() > pImp->GetShell()->VisArea().Bottom())
+                {
+                    const long nBottom = pImp->GetShell()->VisArea().Bottom();
+                    const SwFrm *pTmp = lcl_FindFirstInvaCntnt( pPage,
+                                                            nBottom, pCntnt );
+                    if ( !pTmp )
+                    {
+                        if ( (!(IS_FLYS && IS_INVAFLY) ||
+                              !lcl_FindFirstInvaFly( pPage, nBottom )) &&
+                              (!pPage->IsInvalidLayout() ||
+                               !lcl_FindFirstInvaLay( pPage, nBottom )))
+                            SetBrowseActionStop( TRUE );
+                        return FALSE;
+                    }
+                }
+                pCntnt = bNxtCnt ? pCntntNext : pCntnt->GetNextCntntFrm();
+            }
+
+            RESCHEDULE;
+        }
+        else
+        {
+            if ( !pCntnt->GetValidLineNumFlag() && pCntnt->IsTxtFrm() )
+            {
+                const ULONG nAllLines = ((SwTxtFrm*)pCntnt)->GetAllLines();
+                ((SwTxtFrm*)pCntnt)->RecalcAllLines();
+                if ( IsPaintExtraData() && IsPaint() &&
+                     nAllLines != ((SwTxtFrm*)pCntnt)->GetAllLines() )
+                    pImp->GetShell()->AddPaintRect( pCntnt->Frm() );
+            }
+
+            //Falls der Frm schon vor der Abarbeitung hier formatiert wurde.
+            if ( pCntnt->IsTxtFrm() && ((SwTxtFrm*)pCntnt)->HasRepaint() &&
+                  IsPaint() )
+                PaintCntnt( pCntnt, pPage, pCntnt->Frm(), pCntnt->Frm().Bottom());
+            if ( IsIdle() )
+            {
+                CheckIdleEnd();
+                if ( IsInput() )
+                    return FALSE;
+            }
+            if ( bBrowse && !IsIdle() && !IsCalcLayout() && !IsComplete() &&
+                 pCntnt->Frm().Top() > pImp->GetShell()->VisArea().Bottom())
+            {
+                const long nBottom = pImp->GetShell()->VisArea().Bottom();
+                const SwFrm *pTmp = lcl_FindFirstInvaCntnt( pPage,
+                                                    nBottom, pCntnt );
+                if ( !pTmp )
+                {
+                    if ( (!(IS_FLYS && IS_INVAFLY) ||
+                            !lcl_FindFirstInvaFly( pPage, nBottom )) &&
+                            (!pPage->IsInvalidLayout() ||
+                            !lcl_FindFirstInvaLay( pPage, nBottom )))
+                        SetBrowseActionStop( TRUE );
+                    return FALSE;
+                }
+            }
+            pCntnt = pCntnt->GetNextCntntFrm();
+        }
+    }
+    CheckWaitCrsr();
+    return !IsInput();
+}
+/*************************************************************************
+|*
+|*  SwLayAction::_FormatCntnt()
+|*
+|*  Beschreibung        Returnt TRUE wenn der Absatz verarbeitet wurde,
+|*                      FALSE wenn es nichts zu verarbeiten gab.
+|*  Ersterstellung      MA 07. Dec. 92
+|*  Letzte Aenderung    MA 11. Mar. 98
+|*
+|*************************************************************************/
+void SwLayAction::_FormatCntnt( const SwCntntFrm *pCntnt,
+                                const SwPageFrm *pPage )
+{
+    //wird sind hier evtl. nur angekommen, weil der Cntnt DrawObjekte haelt.
+    const BOOL bDrawObjsOnly = pCntnt->IsValid() && !pCntnt->IsCompletePaint() &&
+                         !pCntnt->IsRetouche();
+
+    if ( !bDrawObjsOnly && IsPaint() )
+    {
+        const BOOL bPosOnly = !pCntnt->GetValidPosFlag() &&
+                              !pCntnt->IsCompletePaint() &&
+                              pCntnt->GetValidSizeFlag() &&
+                              pCntnt->GetValidPrtAreaFlag() &&
+                              ( !pCntnt->IsTxtFrm() ||
+                                !((SwTxtFrm*)pCntnt)->HasAnimation() );
+        const SwFrm *pOldUp = pCntnt->GetUpper();
+        const SwRect aOldRect( pCntnt->UnionFrm() );
+        const long   nOldBottom = pCntnt->Frm().Top() + pCntnt->Prt().Bottom();
+        pCntnt->OptCalc();
+        if( IsAgain() )
+            return;
+        if ( pCntnt->Frm().Bottom() < aOldRect.Bottom() )
+            pCntnt->SetRetouche();
+        const SwRect aNewRect( pCntnt->UnionFrm() );
+        if ( bPosOnly && aNewRect.Top() != aOldRect.Top() &&
+             !pCntnt->IsInTab() && !pCntnt->IsInSct() &&
+             pOldUp == pCntnt->GetUpper() &&
+             aNewRect.Left() == aOldRect.Left() &&
+             aNewRect.SSize() == aOldRect.SSize() )
+        {
+            _AddScrollRect( pCntnt, pPage, pCntnt->Frm().Top() - aOldRect.Top(),
+                            nOldBottom);
+        }
+        else
+            PaintCntnt( pCntnt, pCntnt->FindPageFrm(), aOldRect, nOldBottom);
+    }
+    else
+    {
+        if ( IsPaint() && pCntnt->IsTxtFrm() && ((SwTxtFrm*)pCntnt)->HasRepaint() )
+            PaintCntnt( pCntnt, pPage, pCntnt->Frm(), pCntnt->Frm().Bottom());
+        pCntnt->OptCalc();
+    }
+
+    //Die im Absatz verankerten Flys wollen auch mitspielen.
+    if ( pCntnt->GetDrawObjs() )
+    {
+        const SwDrawObjs *pObjs = pCntnt->GetDrawObjs();
+        for ( USHORT i = 0; i < pObjs->Count(); ++i )
+        {
+            SdrObject *pO = (*pObjs)[i];
+            if ( pO->IsWriterFlyFrame() )
+            {
+                SwFlyFrm* pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+                if ( pFly->IsFlyInCntFrm() && ((SwFlyInCntFrm*)pFly)->IsInvalid() )
+                {
+                    FormatFlyInCnt( (SwFlyInCntFrm*)pFly );
+                    pObjs = pCntnt->GetDrawObjs();
+                    CHECKPAGE;
+                }
+            }
+        }
+    }
+}
+/*************************************************************************
+|*
+|*  SwLayAction::FormatFlyCntnt()
+|*
+|*      - Returnt TRUE wenn der Inhalt aller Flys vollstaendig verarbeitet
+|*        wurde, FALSE bei einem vorzeitigen Abbruch.
+|*  Ersterstellung      MA 02. Dec. 92
+|*  Letzte Aenderung    MA 16. Sep. 93
+|*
+|*************************************************************************/
+BOOL SwLayAction::FormatFlyCntnt( const SwPageFrm *pPage )
+{
+    for ( USHORT i = 0; pPage->GetSortedObjs() &&
+                        i < pPage->GetSortedObjs()->Count(); ++i )
+    {
+        if ( IsAgain() )
+            return FALSE;
+        SdrObject *pO = (*pPage->GetSortedObjs())[i];
+        if ( pO->IsWriterFlyFrame() )
+        {
+            const SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+            if ( !_FormatFlyCntnt( pFly ) )
+                return FALSE;
+        }
+    }
+    return TRUE;
+}
+/*************************************************************************
+|*
+|*  SwLayAction::FormatFlyInCnt()
+|*
+|*  Beschreibung        Da die Flys im Cntnt nix mit der Seite am Hut
+|*      (bzw. in den Bits ;-)) haben werden sie vom Cntnt (FormatCntnt)
+|*      gerufen und hier verarbeitet. Die Verarebeitungsmimik ist
+|*      prinzipiell die gleich wie bei Seiten nur nicht ganz so
+|*      kompliziert (SwLayAction::Action()).
+|*      - Returnt TRUE wenn der Fly vollstaendig verbeitet wurde, FALSE bei
+|*        einem vorzeitigen Abbruch.
+|*  Ersterstellung      MA 04. Dec. 92
+|*  Letzte Aenderung    MA 24. Jun. 96
+|*
+|*************************************************************************/
+void SwLayAction::FormatFlyInCnt( SwFlyInCntFrm *pFly )
+{
+    //Wg. Aenderung eine kleine Vorsichtsmassnahme. Es wird jetzt vor der
+    //Cntntformatierung das Flag validiert und wenn die Formatierung mit
+    //FALSE returnt wird halt wieder invalidiert.
+    while ( pFly->IsInvalid() )
+    {
+        if ( pFly->IsInvalidLayout() )
+        {
+            while ( FormatLayoutFly( pFly ) )
+            {
+                if ( IsAgain() )
+                    return;
+            }
+            if ( IsAgain() )
+                return;
+            pFly->ValidateLayout();
+        }
+        if ( pFly->IsInvalidCntnt() )
+        {
+            pFly->ValidateCntnt();
+            if ( !_FormatFlyCntnt( pFly ) )
+                pFly->InvalidateCntnt();
+        }
+    }
+    CheckWaitCrsr();
+}
+/*************************************************************************
+|*
+|*  SwLayAction::_FormatFlyCntnt()
+|*
+|*  Beschreibung:
+|*      - Returnt TRUE wenn alle Cntnts des Flys vollstaendig verarbeitet
+|*        wurden. FALSE wenn vorzeitig unterbrochen wurde.
+|*  Ersterstellung      MA 02. Dec. 92
+|*  Letzte Aenderung    MA 24. Jun. 96
+|*
+|*************************************************************************/
+BOOL SwLayAction::_FormatFlyCntnt( const SwFlyFrm *pFly )
+{
+    BOOL bOneProcessed = FALSE;
+    const SwCntntFrm *pCntnt = pFly->ContainsCntnt();
+
+    while ( pCntnt )
+    {
+        if ( __FormatFlyCntnt( pCntnt ) )
+            bOneProcessed = TRUE;
+
+        if ( !pCntnt->GetValidLineNumFlag() && pCntnt->IsTxtFrm() )
+        {
+            const ULONG nAllLines = ((SwTxtFrm*)pCntnt)->GetAllLines();
+            ((SwTxtFrm*)pCntnt)->RecalcAllLines();
+            if ( IsPaintExtraData() && IsPaint() &&
+                 nAllLines != ((SwTxtFrm*)pCntnt)->GetAllLines() )
+                pImp->GetShell()->AddPaintRect( pCntnt->Frm() );
+        }
+
+        if ( IsAgain() )
+            return FALSE;
+
+        //wenn eine Eingabe anliegt breche ich die Verarbeitung ab.
+        if ( bOneProcessed && !pFly->IsFlyInCntFrm() )
+        {
+            CheckIdleEnd();
+            if ( IsInput() )
+                return FALSE;
+        }
+        pCntnt = pCntnt->GetNextCntntFrm();
+    }
+    CheckWaitCrsr();
+    return !IsInput();
+}
+
+/*************************************************************************
+|*
+|*  SwLayAction::__FormatFlyCntnt()
+|*
+|*  Beschreibung:
+|*      - Returnt TRUE, wenn der Cntnt verarbeitet,
+|*        d.h. Kalkuliert und/oder gepaintet wurde.
+|*
+|*  Ersterstellung      MA 05. Jan. 93
+|*  Letzte Aenderung    MA 18. May. 95
+|*
+|*************************************************************************/
+BOOL SwLayAction::__FormatFlyCntnt( const SwCntntFrm *pCntnt )
+{
+    BOOL bRet = FALSE;
+    if ( !pCntnt->IsValid() || pCntnt->IsCompletePaint() ||
+         pCntnt->IsRetouche() )
+    {
+        if ( IsPaint() )
+        {
+            const SwRect aOldRect( pCntnt->UnionFrm( TRUE ) );
+            const long   nOldBottom = pCntnt->Frm().Top() + pCntnt->Prt().Bottom();
+            pCntnt->OptCalc();
+            if ( pCntnt->Frm().Bottom() <  aOldRect.Bottom() )
+                pCntnt->SetRetouche();
+            PaintCntnt( pCntnt, pCntnt->FindPageFrm(), aOldRect, nOldBottom );
+        }
+        else
+            pCntnt->OptCalc();
+        if( IsAgain() )
+            return FALSE;
+        bRet = TRUE;
+    }
+    else
+    {
+        //Falls der Frm schon vor der Abarbeitung hier formatiert wurde.
+        if ( pCntnt->IsTxtFrm() && ((SwTxtFrm*)pCntnt)->HasRepaint() &&
+             IsPaint() )
+            PaintCntnt( pCntnt, pCntnt->FindPageFrm(), pCntnt->Frm(), pCntnt->Frm().Bottom());
+    }
+    //Die im Absatz verankerten Flys wollen auch mitspielen.
+    if ( pCntnt->GetDrawObjs() )
+    {
+        const SwDrawObjs *pObjs = pCntnt->GetDrawObjs();
+        for ( USHORT i = 0; i < pObjs->Count(); ++i )
+        {
+            SdrObject *pO = (*pObjs)[i];
+            if ( pO->IsWriterFlyFrame() )
+            {
+                SwFlyFrm* pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+                if ( pFly->IsFlyInCntFrm() && ((SwFlyInCntFrm*)pFly)->IsInvalid() )
+                {
+                    FormatFlyInCnt( (SwFlyInCntFrm*)pFly );
+                    if ( IsAgain() )
+                        return FALSE;
+                    pObjs = pCntnt->GetDrawObjs();
+                }
+            }
+        }
+    }
+    return bRet;
+}
+
+/*************************************************************************
+|*
+|*  SwLayAction::FormatSpelling(), _FormatSpelling()
+|*
+|*  Ersterstellung      AMA 01. Feb. 96
+|*  Letzte Aenderung    AMA 01. Feb. 96
+|*
+|*************************************************************************/
+BOOL SwLayIdle::_FormatSpelling( const SwCntntFrm *pCnt )
+{
+    ASSERT( pCnt->IsTxtFrm(), "NoTxt neighbour of Txt" );
+    if( pCnt->GetNode()->IsWrongDirty() )
+    {
+        if( STRING_LEN == nTxtPos )
+        {
+            --nTxtPos;
+            ViewShell *pSh = pImp->GetShell();
+            if( pSh->ISA(SwCrsrShell) && !((SwCrsrShell*)pSh)->IsTableMode() )
+            {
+                SwPaM *pCrsr = ((SwCrsrShell*)pSh)->GetCrsr();
+                if( !pCrsr->HasMark() && pCrsr == pCrsr->GetNext() )
+                {
+                    pCntntNode = pCrsr->GetCntntNode();
+                    nTxtPos =  pCrsr->GetPoint()->nContent.GetIndex();
+                }
+            }
+        }
+        SwRect aRepaint( ((SwTxtFrm*)pCnt)->_AutoSpell( pCntntNode, nTxtPos ) );
+        bPageValid = bPageValid && !pCnt->GetNode()->IsWrongDirty();
+        if( !bPageValid )
+            bAllValid = FALSE;
+        if ( aRepaint.HasArea() )
+            pImp->GetShell()->InvalidateWindows( aRepaint );
+        if ( GetpApp()->AnyInput( INPUT_ANY ) )
+            return TRUE;
+    }
+    //Die im Absatz verankerten Flys wollen auch mitspielen.
+    if ( pCnt->GetDrawObjs() )
+    {
+        const SwDrawObjs &rObjs = *pCnt->GetDrawObjs();
+        for ( USHORT i = 0; i < rObjs.Count(); ++i )
+        {
+            SdrObject *pO = rObjs[i];
+            if ( pO->IsWriterFlyFrame() )
+            {
+                SwFlyFrm* pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+                if ( pFly->IsFlyInCntFrm() )
+                {
+                    const SwCntntFrm *pC = pFly->ContainsCntnt();
+                    while( pC )
+                    {
+                        if ( pC->IsTxtFrm() && _FormatSpelling( pC ) )
+                            return TRUE;
+                        pC = pC->GetNextCntntFrm();
+                    }
+                }
+            }
+        }
+    }
+    return FALSE;
+}
+
+BOOL SwLayIdle::FormatSpelling( BOOL bVisAreaOnly )
+{
+    //Spellchecken aller Inhalte der Seiten. Entweder nur der sichtbaren
+    //Seiten oder eben aller. Nach dem Checken jedes Absatzes wird abgebrochen
+    //wenn ein Input anliegt.
+    if( !pImp->GetShell()->GetViewOptions()->IsOnlineSpell() )
+        return FALSE;
+    SwPageFrm *pPage;
+    if ( bVisAreaOnly )
+        pPage = pImp->GetFirstVisPage();
+    else
+        pPage = (SwPageFrm*)pRoot->Lower();
+
+    pCntntNode = NULL;
+    nTxtPos = STRING_LEN;
+
+    while ( pPage )
+    {
+        bPageValid = TRUE;
+        const SwCntntFrm *pCnt = pPage->ContainsCntnt();
+        while( pCnt && pPage->IsAnLower( pCnt ) )
+        {
+            if ( _FormatSpelling( pCnt ) )
+                return TRUE;
+            pCnt = pCnt->GetNextCntntFrm();
+        }
+        if ( pPage->GetSortedObjs() )
+        {
+            for ( USHORT i = 0; pPage->GetSortedObjs() &&
+                                i < pPage->GetSortedObjs()->Count(); ++i )
+            {
+                SdrObject *pO = (*pPage->GetSortedObjs())[i];
+                if ( pO->IsWriterFlyFrame() )
+                {
+                    const SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+                    const SwCntntFrm *pC = pFly->ContainsCntnt();
+                    while( pC )
+                    {
+                        if ( pC->IsTxtFrm() && _FormatSpelling( pC ) )
+                            return TRUE;
+                        pC = pC->GetNextCntntFrm();
+                    }
+                }
+            }
+        }
+        if( bPageValid )
+            pPage->ValidateSpelling();
+        pPage = (SwPageFrm*)pPage->GetNext();
+        if ( pPage && bVisAreaOnly &&
+             !pPage->Frm().IsOver( pImp->GetShell()->VisArea()))
+            return  FALSE;
+    }
+    return FALSE;
+}
+
+BOOL SwLayIdle::_CollectAutoCmplWords( const SwCntntFrm *pCnt,
+                                        BOOL bVisAreaOnly )
+{
+    ASSERT( pCnt->IsTxtFrm(), "NoTxt neighbour of Txt" );
+    if( pCnt->GetNode()->IsAutoCompleteWordDirty() )
+    {
+        if( STRING_LEN == nTxtPos )
+        {
+            --nTxtPos;
+            ViewShell *pSh = pImp->GetShell();
+            if( pSh->ISA(SwCrsrShell) && !((SwCrsrShell*)pSh)->IsTableMode() )
+            {
+                SwPaM *pCrsr = ((SwCrsrShell*)pSh)->GetCrsr();
+                if( !pCrsr->HasMark() && pCrsr == pCrsr->GetNext() )
+                {
+                    pCntntNode = pCrsr->GetCntntNode();
+                    nTxtPos =  pCrsr->GetPoint()->nContent.GetIndex();
+                }
+            }
+        }
+
+        ((SwTxtFrm*)pCnt)->CollectAutoCmplWrds( pCntntNode, nTxtPos,
+                                                bVisAreaOnly );
+/*      bPageValid = bPageValid && !pCnt->GetNode()->IsAutoCompleteWordDirty();
+
+        if( !bPageValid )
+            bAllValid = FALSE;
+*/
+        if ( GetpApp()->AnyInput( INPUT_ANY ) )
+            return TRUE;
+    }
+
+    //Die im Absatz verankerten Flys wollen auch mitspielen.
+    if ( pCnt->GetDrawObjs() )
+    {
+        const SwDrawObjs &rObjs = *pCnt->GetDrawObjs();
+        for ( USHORT i = 0; i < rObjs.Count(); ++i )
+        {
+            SdrObject *pO = rObjs[i];
+            if ( pO->IsWriterFlyFrame() )
+            {
+                SwFlyFrm* pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+                if ( pFly->IsFlyInCntFrm() )
+                {
+                    const SwCntntFrm *pC = pFly->ContainsCntnt();
+                    while( pC )
+                    {
+                        if( pC->IsTxtFrm() &&
+                            _CollectAutoCmplWords( pC, bVisAreaOnly ) )
+                            return TRUE;
+                        pC = pC->GetNextCntntFrm();
+                    }
+                }
+            }
+        }
+    }
+    return FALSE;
+}
+
+BOOL SwLayIdle::CollectAutoCmplWords( BOOL bVisAreaOnly )
+{
+    //Worte aller Inhalte der Seiten zusammensammeln, um eine
+    //AutoComplete-Liste zu erstellen. Entweder nur der sichtbaren
+    //Seiten oder eben aller. Falls ein Input am Ende einer Seite anliegt,
+    // so wird abgebrochen.
+    if( !pImp->GetShell()->GetViewOptions()->IsAutoCompleteWords() ||
+        pImp->GetShell()->GetDoc()->GetAutoCompleteWords().IsLockWordLstLocked())
+        return FALSE;
+
+    SwPageFrm *pPage;
+    if ( bVisAreaOnly )
+        pPage = pImp->GetFirstVisPage();
+    else
+        pPage = (SwPageFrm*)pRoot->Lower();
+
+    pCntntNode = NULL;
+    nTxtPos = STRING_LEN;
+
+    while ( pPage )
+    {
+        bPageValid = TRUE;
+        const SwCntntFrm *pCnt = pPage->ContainsCntnt();
+        while( pCnt && pPage->IsAnLower( pCnt ) )
+        {
+            if ( _CollectAutoCmplWords( pCnt, bVisAreaOnly ) )
+                return TRUE;
+            pCnt = pCnt->GetNextCntntFrm();
+        }
+        if ( pPage->GetSortedObjs() )
+        {
+            for ( USHORT i = 0; pPage->GetSortedObjs() &&
+                                i < pPage->GetSortedObjs()->Count(); ++i )
+            {
+                SdrObject *pO = (*pPage->GetSortedObjs())[i];
+                if ( pO->IsWriterFlyFrame() )
+                {
+                    const SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+                    const SwCntntFrm *pC = pFly->ContainsCntnt();
+                    while( pC )
+                    {
+                        if ( pC->IsTxtFrm() &&
+                            _CollectAutoCmplWords( pC, bVisAreaOnly ) )
+                            return TRUE;
+                        pC = pC->GetNextCntntFrm();
+                    }
+                }
+            }
+        }
+
+        if( bPageValid )
+            pPage->ValidateAutoCompleteWords();
+
+        pPage = (SwPageFrm*)pPage->GetNext();
+        if ( pPage && bVisAreaOnly &&
+             !pPage->Frm().IsOver( pImp->GetShell()->VisArea()))
+            break;
+    }
+    return FALSE;
+}
+
+#ifndef PRODUCT
+#ifdef DEBUG
+
+/*************************************************************************
+|*
+|*  void SwLayIdle::SwLayIdle()
+|*
+|*  Ersterstellung      MA ??
+|*  Letzte Aenderung    MA 09. Jun. 94
+|*
+|*************************************************************************/
+void SwLayIdle::ShowIdle( ColorName eName )
+{
+    if ( !bIndicator )
+    {
+        bIndicator = TRUE;
+        Window *pWin = pImp->GetShell()->GetWin();
+        if ( pWin )
+        {
+            Rectangle aRect( 0, 0, 5, 5 );
+            aRect = pWin->PixelToLogic( aRect );
+            pWin->Push( PUSH_FILLCOLOR );
+            pWin->SetFillColor( eName );
+            pWin->DrawRect( aRect );
+            pWin->Pop();
+        }
+    }
+}
+#define SHOW_IDLE( ColorName ) ShowIdle( ColorName )
+#else
+#define SHOW_IDLE( ColorName )
+#endif
+#else
+#define SHOW_IDLE( ColorName )
+#endif
+
+/*************************************************************************
+|*
+|*  void SwLayIdle::SwLayIdle()
+|*
+|*  Ersterstellung      MA 30. Oct. 92
+|*  Letzte Aenderung    MA 23. May. 95
+|*
+|*************************************************************************/
+SwLayIdle::SwLayIdle( SwRootFrm *pRt, SwViewImp *pI ) :
+    pRoot( pRt ),
+    pImp( pI )
+#ifndef PRODUCT
+#ifdef DEBUG
+    , bIndicator( FALSE )
+#endif
+#endif
+{
+    pImp->pIdleAct = this;
+
+    SHOW_IDLE( COL_LIGHTRED );
+
+    pImp->GetShell()->EnableSmooth( FALSE );
+
+    //Zuerst den Sichtbaren Bereich Spellchecken, nur wenn dort nichts
+    //zu tun war wird das IdleFormat angestossen.
+    if ( !FormatSpelling( TRUE ) && !CollectAutoCmplWords( TRUE ))
+    {
+        //Formatieren und ggf. Repaint-Rechtecke an der ViewShell vormerken.
+        //Dabei muessen kuenstliche Actions laufen, damit es z.B. bei
+        //Veraenderungen der Seitenzahl nicht zu unerwuenschten Effekten kommt.
+        //Wir merken uns bei welchen Shells der Cursor sichtbar ist, damit
+        //wir ihn bei Dokumentaenderung ggf. wieder sichbar machen koennen.
+        SvBools aBools;
+        ViewShell *pSh = pImp->GetShell();
+        do
+        {   ++pSh->nStartAction;
+            BOOL bVis = FALSE;
+            if ( pSh->ISA(SwCrsrShell) )
+            {
+#ifdef SW_CRSR_TIMER
+                ((SwCrsrShell*)pSh)->ChgCrsrTimerFlag( FALSE );
+#endif
+                bVis = ((SwCrsrShell*)pSh)->GetCharRect().IsOver(pSh->VisArea());
+            }
+            aBools.Insert( bVis, aBools.Count() );
+            pSh = (ViewShell*)pSh->GetNext();
+        } while ( pSh != pImp->GetShell() );
+
+        SwLayAction aAction( pRoot, pImp );
+        aAction.SetInputType( INPUT_ANY );
+        aAction.SetIdle( TRUE );
+        aAction.SetWaitAllowed( FALSE );
+        aAction.Action();
+
+        //Weitere Start-/EndActions nur auf wenn irgendwo Paints aufgelaufen
+        //sind oder wenn sich die Sichtbarkeit des CharRects veraendert hat.
+        FASTBOOL bActions = FALSE;
+        USHORT nBoolIdx = 0;
+        do
+        {   --pSh->nStartAction;
+
+            if ( pSh->Imp()->GetRegion() || pSh->Imp()->GetScrollRects() )
+                bActions = TRUE;
+            else
+            {
+                SwRect aTmp( pSh->VisArea() );
+                pSh->UISizeNotify();
+
+                bActions |= aTmp != pSh->VisArea() ||
+                            aBools[nBoolIdx] !=
+                                   ((SwCrsrShell*)pSh)->GetCharRect().IsOver(pSh->VisArea());
+            }
+
+            pSh = (ViewShell*)pSh->GetNext();
+            ++nBoolIdx;
+        } while ( pSh != pImp->GetShell() );
+
+        if ( bActions )
+        {
+            //Start- EndActions aufsetzen. ueber die CrsrShell, damit der
+            //Cursor/Selektion und die VisArea korrekt gesetzt werden.
+            nBoolIdx = 0;
+            do
+            {   FASTBOOL bCrsrShell = pSh->IsA( TYPE(SwCrsrShell) );
+
+                if ( bCrsrShell )
+                    ((SwCrsrShell*)pSh)->SttCrsrMove();
+//              else
+//                  pSh->StartAction();
+
+                //Wenn Paints aufgelaufen sind, ist es am sinnvollsten schlicht das
+                //gesamte Window zu invalidieren. Anderfalls gibt es Paintprobleme
+                //deren Loesung unverhaeltnissmaessig aufwendig waere.
+                //fix(18176):
+                SwViewImp *pImp = pSh->Imp();
+                FASTBOOL bUnlock = FALSE;
+                if ( pImp->GetRegion() || pImp->GetScrollRects() )
+                {
+                    pImp->DelRegions();
+
+                    //Fuer Repaint mit virtuellem Device sorgen.
+                    pSh->LockPaint();
+                    bUnlock = TRUE;
+                }
+
+                if ( bCrsrShell )
+                    //Wenn der Crsr sichbar war wieder sichbar machen, sonst
+                    //EndCrsrMove mit TRUE fuer IdleEnd.
+                    ((SwCrsrShell*)pSh)->EndCrsrMove( TRUE^aBools[nBoolIdx] );
+//              else
+//                  pSh->EndAction();
+                if( bUnlock )
+                {
+                    if( bCrsrShell )
+                    {
+                        // UnlockPaint overwrite the selection from the
+                        // CrsrShell and calls the virtual method paint
+                        // to fill the virtual device. This fill dont have
+                        // paint the selection! -> Set the focus flag at
+                        // CrsrShell and it dont paint the selection.
+                        ((SwCrsrShell*)pSh)->ShLooseFcs();
+                        pSh->UnlockPaint( TRUE );
+                        ((SwCrsrShell*)pSh)->ShGetFcs( FALSE );
+                    }
+                    else
+                        pSh->UnlockPaint( TRUE );
+                }
+
+                pSh = (ViewShell*)pSh->GetNext();
+                ++nBoolIdx;
+
+            } while ( pSh != pImp->GetShell() );
+        }
+
+        if ( !aAction.IsInput() )
+        {
+            if( !FormatSpelling( FALSE ))
+                CollectAutoCmplWords( FALSE );
+        }
+
+        FASTBOOL bInValid;
+        const SwViewOption& rVOpt = *pImp->GetShell()->GetViewOptions();
+        FASTBOOL bSpell = rVOpt.IsOnlineSpell(),
+                 bACmplWrd = rVOpt.IsAutoCompleteWords();
+        SwPageFrm *pPg = (SwPageFrm*)pRoot->Lower();
+        do
+        {   bInValid = pPg->IsInvalidCntnt()    || pPg->IsInvalidLayout() ||
+                       pPg->IsInvalidFlyCntnt() || pPg->IsInvalidFlyLayout() ||
+                       pPg->IsInvalidFlyInCnt() ||
+                       (bSpell && pPg->IsInvalidSpelling()) ||
+                       (bACmplWrd && pPg->IsInvalidAutoCompleteWords());
+
+            pPg = (SwPageFrm*)pPg->GetNext();
+
+        } while ( pPg && TRUE^bInValid );
+
+        if ( TRUE^bInValid )
+            pRoot->ResetIdleFormat();
+    }
+
+    pImp->GetShell()->EnableSmooth( TRUE );
+
+#ifndef PRODUCT
+#ifdef DEBUG
+    if ( bIndicator && pImp->GetShell()->GetWin() )
+    {
+        Rectangle aRect( 0, 0, 5, 5 );
+        aRect = pImp->GetShell()->GetWin()->PixelToLogic( aRect );
+        pImp->GetShell()->GetWin()->Invalidate( aRect );
+    }
+#endif
+#endif
+}
+
+SwLayIdle::~SwLayIdle()
+{
+    pImp->pIdleAct = 0;
+}
+
diff --git a/sw/source/core/layout/layouter.cxx b/sw/source/core/layout/layouter.cxx
new file mode 100644
index 000000000000..352ba37da02a
--- /dev/null
+++ b/sw/source/core/layout/layouter.cxx
@@ -0,0 +1,345 @@
+/*************************************************************************
+ *
+ *  $RCSfile: layouter.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:22 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "layouter.hxx"
+#include "doc.hxx"
+#include "sectfrm.hxx"
+#include "ftnboss.hxx"
+#include "cntfrm.hxx"
+#include "pagefrm.hxx"
+#include "ftnfrm.hxx"
+
+#define LOOP_DETECT 200
+
+class SwLooping
+{
+    USHORT nMinPage;
+    USHORT nMaxPage;
+    USHORT nCount;
+public:
+    SwLooping( SwPageFrm* pPage );
+    void Control( SwPageFrm* pPage );
+    static void Drastic( SwFrm* pFrm );
+};
+
+class SwEndnoter
+{
+    SwLayouter* pMaster;
+    SwSectionFrm* pSect;
+    SvPtrarr* pEndArr;
+public:
+    SwEndnoter( SwLayouter* pLay )
+        : pMaster( pLay ), pSect( NULL ), pEndArr( NULL ) {}
+    ~SwEndnoter() { delete pEndArr; }
+    void CollectEndnotes( SwSectionFrm* pSct );
+    void CollectEndnote( SwFtnFrm* pFtn );
+    void Collect( SwFtnFrm* pFtn );
+    const SwSectionFrm* GetSect() { return pSect; }
+    void InsertEndnotes();
+    BOOL HasEndnotes() const { return pEndArr && pEndArr->Count(); }
+};
+
+void SwEndnoter::CollectEndnotes( SwSectionFrm* pSct )
+{
+    ASSERT( pSct, "CollectEndnotes: Which section?" );
+    if( !pSect )
+        pSect = pSct;
+    else if( pSct != pSect )
+        return;
+    pSect->CollectEndnotes( pMaster );
+}
+
+void SwEndnoter::CollectEndnote( SwFtnFrm* pFtn )
+{
+    if( pEndArr && USHRT_MAX != pEndArr->GetPos( (VoidPtr)pFtn ) )
+        return;
+
+    if( pFtn->GetUpper() )
+    {
+        // pFtn is the master, he incorporates its follows
+        SwFtnFrm *pNxt = pFtn->GetFollow();
+        while ( pNxt )
+        {
+            SwFrm *pCnt = pNxt->ContainsAny();
+            if ( pCnt )
+            {
+                do
+                {   SwFrm *pNxtCnt = pCnt->GetNext();
+                    pCnt->Cut();
+                    pCnt->Paste( pFtn );
+                    pCnt = pNxtCnt;
+                } while ( pCnt );
+            }
+            else
+            {   ASSERT( pNxt->Lower() && pNxt->Lower()->IsSctFrm(),
+                        "Endnote without content?" );
+                pNxt->Cut();
+                delete pNxt;
+            }
+            pNxt = pFtn->GetFollow();
+        }
+        if( pFtn->GetMaster() )
+            return;
+        pFtn->Cut();
+    }
+    else if( pEndArr )
+    {
+        for ( USHORT i = 0; i < pEndArr->Count(); ++i )
+        {
+            SwFtnFrm *pEndFtn = (SwFtnFrm*)((*pEndArr)[i]);
+            if( pEndFtn->GetAttr() == pFtn->GetAttr() )
+            {
+                delete pFtn;
+                return;
+            }
+        }
+    }
+    if( !pEndArr )
+        pEndArr = new SvPtrarr( 5, 5 );  // deleted from the SwLayouter
+    pEndArr->Insert( (VoidPtr)pFtn, pEndArr->Count() );
+}
+
+void SwEndnoter::Collect( SwFtnFrm* pFtn )
+{
+}
+
+void SwEndnoter::InsertEndnotes()
+{
+    if( !pSect )
+        return;
+    if( !pEndArr || !pEndArr->Count() )
+    {
+        pSect = NULL;
+        return;
+    }
+    ASSERT( pSect->Lower() && pSect->Lower()->IsFtnBossFrm(),
+            "InsertEndnotes: Where's my column?" );
+    SwFrm* pRef = pSect->FindLastCntnt( FINDMODE_MYLAST );
+    SwFtnBossFrm *pBoss = pRef ? pRef->FindFtnBossFrm()
+                               : (SwFtnBossFrm*)pSect->Lower();
+    pBoss->_MoveFtns( *pEndArr );
+    delete pEndArr;
+    pEndArr = NULL;
+    pSect = NULL;
+}
+
+SwLooping::SwLooping( SwPageFrm* pPage )
+{
+    ASSERT( pPage, "Where's my page?" );
+    nMinPage = pPage->GetPhyPageNum();
+    nMaxPage = nMinPage;
+    nCount = 0;
+}
+
+void SwLooping::Drastic( SwFrm* pFrm )
+{
+    while( pFrm )
+    {
+        if( pFrm->IsLayoutFrm() )
+            Drastic( ((SwLayoutFrm*)pFrm)->Lower() );
+        pFrm->bValidPos = TRUE;
+        pFrm->bValidSize = TRUE;
+        pFrm->bValidPrtArea = TRUE;
+        pFrm = pFrm->GetNext();
+    }
+}
+
+void SwLooping::Control( SwPageFrm* pPage )
+{
+    if( !pPage )
+        return;
+    USHORT nNew = pPage->GetPhyPageNum();
+    if( nNew > nMaxPage )
+        nMaxPage = nNew;
+    if( nNew < nMinPage )
+    {
+        nMinPage = nNew;
+        nMaxPage = nNew;
+        nCount = 0;
+    }
+    else if( nNew > nMinPage + 2 )
+    {
+        nMinPage = nNew - 2;
+        nMaxPage = nNew;
+        nCount = 0;
+    }
+    else if( ++nCount > LOOP_DETECT )
+    {
+#ifndef PRODUCT
+#ifdef DEBUG
+        static BOOL bNoLouie = FALSE;
+        if( bNoLouie )
+            return;
+#endif
+#endif
+        ASSERT( FALSE, "Looping Louie" );
+        nCount = 0;
+        Drastic( pPage->Lower() );
+        if( nNew > nMinPage && pPage->GetPrev() )
+            Drastic( ((SwPageFrm*)pPage->GetPrev())->Lower() );
+        if( nNew < nMaxPage && pPage->GetNext() )
+            Drastic( ((SwPageFrm*)pPage->GetNext())->Lower() );
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwLayouter::SwLayouter()
+|*
+|*  Ersterstellung      AMA 02. Nov. 99
+|*  Letzte Aenderung    AMA 02. Nov. 99
+|*
+|*************************************************************************/
+
+SwLayouter::SwLayouter() : pEndnoter( NULL ), pLooping( NULL )
+{
+}
+
+SwLayouter::~SwLayouter()
+{
+    delete pEndnoter;
+    delete pLooping;
+}
+
+void SwLayouter::_CollectEndnotes( SwSectionFrm* pSect )
+{
+    if( !pEndnoter )
+        pEndnoter = new SwEndnoter( this );
+    pEndnoter->CollectEndnotes( pSect );
+}
+
+BOOL SwLayouter::HasEndnotes() const
+{
+    return pEndnoter->HasEndnotes();
+}
+
+void SwLayouter::CollectEndnote( SwFtnFrm* pFtn )
+{
+    pEndnoter->CollectEndnote( pFtn );
+}
+
+void SwLayouter::InsertEndnotes( SwSectionFrm* pSect )
+{
+    if( !pEndnoter || pEndnoter->GetSect() != pSect )
+        return;
+    pEndnoter->InsertEndnotes();
+}
+
+void SwLayouter::LoopControl( SwPageFrm* pPage, BYTE nLoop )
+{
+    ASSERT( pLooping, "Looping: Lost control" );
+    pLooping->Control( pPage );
+}
+
+BOOL SwLayouter::StartLooping( SwPageFrm* pPage )
+{
+    if( pLooping )
+        return FALSE;
+    pLooping = new SwLooping( pPage );
+    return TRUE;
+}
+
+void SwLayouter::EndLoopControl()
+{
+    delete pLooping;
+    pLooping = NULL;
+}
+
+void SwLayouter::CollectEndnotes( SwDoc* pDoc, SwSectionFrm* pSect )
+{
+    ASSERT( pDoc, "No doc, no fun" );
+    if( !pDoc->GetLayouter() )
+        pDoc->SetLayouter( new SwLayouter() );
+    pDoc->GetLayouter()->_CollectEndnotes( pSect );
+}
+
+BOOL SwLayouter::Collecting( SwDoc* pDoc, SwSectionFrm* pSect, SwFtnFrm* pFtn )
+{
+    if( !pDoc->GetLayouter() )
+        return FALSE;
+    SwLayouter *pLayouter = pDoc->GetLayouter();
+    if( pLayouter->pEndnoter && pLayouter->pEndnoter->GetSect() && pSect &&
+        ( pLayouter->pEndnoter->GetSect()->IsAnFollow( pSect ) ||
+          pSect->IsAnFollow( pLayouter->pEndnoter->GetSect() ) ) )
+    {
+        if( pFtn )
+            pLayouter->CollectEndnote( pFtn );
+        return TRUE;
+    }
+    return FALSE;
+}
+
+BOOL SwLayouter::StartLoopControl( SwDoc* pDoc, SwPageFrm *pPage )
+{
+    ASSERT( pDoc, "No doc, no fun" );
+    if( !pDoc->GetLayouter() )
+        pDoc->SetLayouter( new SwLayouter() );
+    return !pDoc->GetLayouter()->pLooping &&
+            pDoc->GetLayouter()->StartLooping( pPage );
+}
+
+
diff --git a/sw/source/core/layout/makefile.mk b/sw/source/core/layout/makefile.mk
new file mode 100644
index 000000000000..4258e46a2916
--- /dev/null
+++ b/sw/source/core/layout/makefile.mk
@@ -0,0 +1,175 @@
+#*************************************************************************
+#
+#   $RCSfile: makefile.mk,v $
+#
+#   $Revision: 1.1.1.1 $
+#
+#   last change: $Author: hr $ $Date: 2000-09-19 00:08:22 $
+#
+#   The Contents of this file are made available subject to the terms of
+#   either of the following licenses
+#
+#          - GNU Lesser General Public License Version 2.1
+#          - Sun Industry Standards Source License Version 1.1
+#
+#   Sun Microsystems Inc., October, 2000
+#
+#   GNU Lesser General Public License Version 2.1
+#   =============================================
+#   Copyright 2000 by Sun Microsystems, Inc.
+#   901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+#   This library is free software; you can redistribute it and/or
+#   modify it under the terms of the GNU Lesser General Public
+#   License version 2.1, as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   Lesser General Public License for more details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+#   License along with this library; if not, write to the Free Software
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+#   MA  02111-1307  USA
+#
+#
+#   Sun Industry Standards Source License Version 1.1
+#   =================================================
+#   The contents of this file are subject to the Sun Industry Standards
+#   Source License Version 1.1 (the "License"); You may not use this file
+#   except in compliance with the License. You may obtain a copy of the
+#   License at http://www.openoffice.org/license.html.
+#
+#   Software provided under this License is provided on an "AS IS" basis,
+#   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+#   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+#   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+#   See the License for the specific provisions governing your rights and
+#   obligations concerning the Software.
+#
+#   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+#   Copyright: 2000 by Sun Microsystems, Inc.
+#
+#   All Rights Reserved.
+#
+#   Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sw
+TARGET=layout
+
+AUTOSEG=true
+
+PROJECTPCH=core_pch
+PDBTARGET=core_pch
+PROJECTPCHSOURCE=..$/core_1st$/core_pch
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE :  $(PRJ)$/inc$/swpre.mk
+.INCLUDE :  settings.mk
+.INCLUDE :  $(PRJ)$/inc$/sw.mk
+
+.IF "$(mydebug)" != ""
+CDEFS+=-Dmydebug
+.ENDIF
+
+.IF "$(madebug)" != ""
+CDEFS+=-DDEBUG
+.ENDIF
+
+#		"Querdarstellung des Dokumentes"
+#		CDEFS=$(CDEFS) -DQUER
+
+# 		CDEFS=$(CDEFS) -DPAGE
+
+.IF "$(GUI)$(COM)" == "WINMSC"
+LIBFLAGS=/NOI /NOE /PAGE:512
+.ENDIF
+
+
+# --- Files --------------------------------------------------------
+
+CXXFILES = \
+        atrfrm.cxx \
+        calcmove.cxx \
+        colfrm.cxx \
+        findfrm.cxx \
+        flowfrm.cxx \
+        fly.cxx \
+        flycnt.cxx \
+        flyincnt.cxx \
+        flylay.cxx \
+        flypos.cxx \
+        frmtool.cxx \
+        ftnfrm.cxx \
+        hffrm.cxx \
+        layact.cxx \
+        layouter.cxx \
+        newfrm.cxx \
+        pagechg.cxx \
+        pagedesc.cxx \
+        pageiter.cxx \
+        paintfrm.cxx \
+        sectfrm.cxx \
+        ssfrm.cxx \
+        tabfrm.cxx \
+        trvlfrm.cxx \
+        unusedf.cxx \
+        virtoutp.cxx \
+        wsfrm.cxx
+
+
+
+SLOFILES =  \
+        $(SLO)$/atrfrm.obj \
+        $(SLO)$/calcmove.obj \
+        $(SLO)$/colfrm.obj \
+        $(SLO)$/findfrm.obj \
+        $(SLO)$/flowfrm.obj \
+        $(SLO)$/fly.obj \
+        $(SLO)$/flycnt.obj \
+        $(SLO)$/flyincnt.obj \
+        $(SLO)$/flylay.obj \
+        $(SLO)$/flypos.obj \
+        $(SLO)$/frmtool.obj \
+        $(SLO)$/ftnfrm.obj \
+        $(SLO)$/hffrm.obj \
+        $(SLO)$/layact.obj \
+        $(SLO)$/layouter.obj \
+        $(SLO)$/newfrm.obj \
+        $(SLO)$/pagechg.obj \
+        $(SLO)$/pagedesc.obj \
+        $(SLO)$/pageiter.obj \
+        $(SLO)$/paintfrm.obj \
+        $(SLO)$/sectfrm.obj \
+        $(SLO)$/ssfrm.obj \
+        $(SLO)$/tabfrm.obj \
+        $(SLO)$/trvlfrm.obj \
+        $(SLO)$/unusedf.obj \
+        $(SLO)$/virtoutp.obj \
+        $(SLO)$/wsfrm.obj
+
+EXCEPTIONSFILES= \
+        $(SLO)$/atrfrm.obj \
+
+.IF "$(product)"==""
+.IF "$(cap)"==""
+CXXFILES += \
+        dbg_lay.cxx
+SLOFILES +=  \
+        $(SLO)$/dbg_lay.obj
+.ENDIF
+.ENDIF
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE :  target.mk
+
diff --git a/sw/source/core/layout/newfrm.cxx b/sw/source/core/layout/newfrm.cxx
new file mode 100644
index 000000000000..09853fdcc461
--- /dev/null
+++ b/sw/source/core/layout/newfrm.cxx
@@ -0,0 +1,441 @@
+/*************************************************************************
+ *
+ *  $RCSfile: newfrm.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:22 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _SVDMODEL_HXX //autogen
+#include 
+#endif
+#ifndef _SVDPAGE_HXX //autogen
+#include 
+#endif
+
+#ifndef _FMTFORDR_HXX //autogen
+#include 
+#endif
+#ifndef _FMTPDSC_HXX //autogen
+#include 
+#endif
+#ifndef _FRMFMT_HXX //autogen
+#include 
+#endif
+#ifndef _SWTABLE_HXX
+#include 
+#endif
+#ifndef _ROOTFRM_HXX
+#include 
+#endif
+#ifndef _PAGEFRM_HXX
+#include 
+#endif
+#ifndef _CNTFRM_HXX
+#include 
+#endif
+#ifndef _VIEWSH_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _NODE_HXX
+#include 
+#endif
+#ifndef _DFLYOBJ_HXX
+#include 
+#endif
+#ifndef _FRMTOOL_HXX
+#include 
+#endif
+#ifndef _VIRTOUTP_HXX
+#include 
+#endif
+#ifndef _BLINK_HXX
+#include 
+#endif
+#ifndef _NDINDEX_HXX
+#include 
+#endif
+#ifndef _SECTFRM_HXX
+#include 
+#endif
+#ifndef _NOTXTFRM_HXX
+#include 
+#endif
+
+
+PtPtr pX = &Point::nA;
+PtPtr pY = &Point::nB;
+SzPtr pWidth = &Size::nA;
+SzPtr pHeight = &Size::nB;
+
+SwLayVout     *SwRootFrm::pVout = 0;
+BOOL           SwRootFrm::bInPaint = FALSE;
+BOOL           SwRootFrm::bNoVirDev = FALSE;
+
+SwCache *SwFrm::pCache = 0;
+
+Bitmap* SwNoTxtFrm::pErrorBmp = 0;
+Bitmap* SwNoTxtFrm::pReplaceBmp = 0;
+
+#ifndef PRODUCT
+USHORT SwFrm::nLastFrmId=0;
+#endif
+
+
+//paintfrm.cxx
+extern void InitBackgroundCache( FASTBOOL );
+
+TYPEINIT1(SwFrm,SwClient);      //rtti fuer SwFrm
+TYPEINIT1(SwCntntFrm,SwFrm);    //rtti fuer SwCntntFrm
+
+
+void _FrmInit()
+{
+    SwRootFrm::pVout = new SwLayVout();
+    SwCache *pNew = new SwCache( 100, 100
+#ifndef PRODUCT
+    , "static SwBorderAttrs::pCache"
+#endif
+    );
+    SwFrm::SetCache( pNew );
+    ::InitBackgroundCache( TRUE );
+}
+
+
+
+void _FrmFinit()
+{
+#ifndef PRODUCT
+    // im Chache duerfen nur noch 0-Pointer stehen
+    for( USHORT n = SwFrm::GetCachePtr()->Count(); n; )
+        if( (*SwFrm::GetCachePtr())[ --n ] )
+        {
+            SwCacheObj* pObj = (*SwFrm::GetCachePtr())[ n ];
+            ASSERT( !pObj, "Wer hat sich nicht ausgetragen?")
+        }
+#endif
+    delete SwRootFrm::pVout;
+    delete SwFrm::GetCachePtr();
+    ::InitBackgroundCache( FALSE );
+}
+
+/*************************************************************************
+|*
+|*  RootFrm::Alles was so zur CurrShell gehoert
+|*
+|*  Ersterstellung      MA 09. Sep. 98
+|*  Letzte Aenderung    MA 18. Feb. 99
+|*
+|*************************************************************************/
+
+typedef CurrShell* CurrShellPtr;
+SV_DECL_PTRARR_SORT(SwCurrShells,CurrShellPtr,4,4)
+SV_IMPL_PTRARR_SORT(SwCurrShells,CurrShellPtr)
+
+CurrShell::CurrShell( ViewShell *pNew )
+{
+    ASSERT( pNew, "0-Shell einsetzen?" );
+    pRoot = pNew->GetLayout();
+    if ( pRoot )
+    {
+        pPrev = pRoot->pCurrShell;
+        pRoot->pCurrShell = pNew;
+        pRoot->pCurrShells->Insert( this );
+    }
+    else
+        pPrev = 0;
+}
+
+CurrShell::~CurrShell()
+{
+    if ( pRoot )
+    {
+        pRoot->pCurrShells->Remove( this );
+        if ( pPrev )
+            pRoot->pCurrShell = pPrev;
+        if ( !pRoot->pCurrShells->Count() && pRoot->pWaitingCurrShell )
+        {
+            pRoot->pCurrShell = pRoot->pWaitingCurrShell;
+            pRoot->pWaitingCurrShell = 0;
+        }
+    }
+}
+
+void SetShell( ViewShell *pSh )
+{
+    SwRootFrm *pRoot = pSh->GetLayout();
+    if ( !pRoot->pCurrShells->Count() )
+        pRoot->pCurrShell = pSh;
+    else
+        pRoot->pWaitingCurrShell = pSh;
+}
+
+void SwRootFrm::DeRegisterShell( ViewShell *pSh )
+{
+    //Wenn moeglich irgendeine Shell aktivieren
+    if ( pCurrShell == pSh )
+        pCurrShell = pSh->GetNext() != pSh ? (ViewShell*)pSh->GetNext() : 0;
+
+    //Das hat sich eruebrigt
+    if ( pWaitingCurrShell == pSh )
+        pWaitingCurrShell = 0;
+
+    //Referenzen entfernen.
+    for ( USHORT i = 0; i < pCurrShells->Count(); ++i )
+    {
+        CurrShell *pC = (*pCurrShells)[i];
+        if (pC->pPrev == pSh)
+            pC->pPrev = 0;
+    }
+}
+
+void InitCurrShells( SwRootFrm *pRoot )
+{
+    pRoot->pCurrShells = new SwCurrShells;
+}
+
+
+/*************************************************************************
+|*
+|*  SwRootFrm::SwRootFrm()
+|*
+|*  Beschreibung:
+|*      Der RootFrm laesst sich grundsaetzlich vom Dokument ein eigenes
+|*      FrmFmt geben. Dieses loescht er dann selbst im DTor.
+|*      Das eigene FrmFmt wird vom uebergebenen Format abgeleitet.
+|*  Ersterstellung      SS 05-Apr-1991
+|*  Letzte Aenderung    MA 12. Dec. 94
+|*
+|*************************************************************************/
+
+
+SwRootFrm::SwRootFrm( SwFrmFmt *pFmt, ViewShell * pSh ) :
+    SwLayoutFrm( pFmt->GetDoc()->MakeFrmFmt(
+        XubString( "Root", RTL_TEXTENCODING_MS_1252 ), pFmt ) ),
+    pTurbo( 0 ),
+    pLastPage( 0 ),
+    pCurrShell( pSh ),
+    pWaitingCurrShell( 0 ),
+    pDestroy( 0 ),
+    nPhyPageNums( 0 ),
+    pDrawPage( 0 ),
+    nBrowseWidth( MM50*4 )  //2cm Minimum
+{
+    nType = FRM_ROOT;
+    bIdleFormat = bTurboAllowed = bAssertFlyPages = bIsNewLayout = TRUE;
+    bCheckSuperfluous = bBrowseWidthValid = FALSE;
+
+    InitCurrShells( this );
+
+    SwDoc *pDoc = pFmt->GetDoc();
+    const BOOL bOldIdle = pDoc->IsIdleTimerActive();
+    pDoc->StopIdleTimer();
+    pDoc->SetRootFrm( this );       //Fuer das Erzeugen der Flys durch MakeFrms()
+    bCallbackActionEnabled = FALSE; //vor Verlassen auf TRUE setzen!
+
+#ifdef QUER
+    //StarWriter /QUER ? bitteschoen:
+    SetFixSize( pHeight );
+#else
+    SetFixSize( pWidth );
+#endif
+
+    SdrModel *pMd = pDoc->GetDrawModel();
+    if ( pMd )
+    {
+        pDrawPage = pMd->GetPage( 0 );
+        pDrawPage->SetSize( Frm().SSize() );
+    }
+
+    //Initialisierung des Layouts: Seiten erzeugen. Inhalt mit cntnt verbinden
+    //usw.
+    //Zuerst einiges initialiseren und den ersten Node besorgen (der wird
+    //fuer den PageDesc benoetigt).
+
+    SwNodeIndex aIndex( *pDoc->GetNodes().GetEndOfContent().StartOfSectionNode() );
+    SwCntntNode *pNode = pDoc->GetNodes().GoNextSection( &aIndex, TRUE, FALSE );
+    SwTableNode *pTblNd= pNode->FindTableNode();
+
+    //PageDesc besorgen (entweder vom FrmFmt des ersten Node oder den
+    //initialen.)
+    SwPageDesc *pDesc = 0;
+    USHORT nPgNum = 1;
+
+    if ( pTblNd )
+    {
+        const SwFmtPageDesc &rDesc = pTblNd->GetTable().GetFrmFmt()->GetPageDesc();
+        pDesc = (SwPageDesc*)rDesc.GetPageDesc();
+        //#19104# Seitennummeroffset beruecksictigen!!
+        bIsVirtPageNum = 0 != ( nPgNum = rDesc.GetNumOffset() );
+    }
+    else if ( pNode )
+    {
+        const SwFmtPageDesc &rDesc = pNode->GetSwAttrSet().GetPageDesc();
+        pDesc = (SwPageDesc*)rDesc.GetPageDesc();
+        //#19104# Seitennummeroffset beruecksictigen!!
+        bIsVirtPageNum = 0 != ( nPgNum = rDesc.GetNumOffset() );
+    }
+    if ( !pDesc )
+        pDesc = (SwPageDesc*)&pDoc->GetPageDesc( 0 );
+    if( !nPgNum )
+        nPgNum = 1;
+
+    //Eine Seite erzeugen und in das Layout stellen
+    SwPageFrm *pPage = ::InsertNewPage( *pDesc, this, 0 != nPgNum % 2 , FALSE, 0 );
+
+    //Erstes Blatt im Bodytext-Bereich suchen.
+    SwLayoutFrm *pLay = pPage->FindBodyCont();
+    while( pLay->Lower() )
+        pLay = (SwLayoutFrm*)pLay->Lower();
+
+    SwNodeIndex aTmp( *pDoc->GetNodes().GetEndOfContent().StartOfSectionNode(), 1 );
+    ::_InsertCnt( pLay, pDoc, aTmp.GetIndex(), TRUE );
+    //Noch nicht ersetzte Master aus der Liste entfernen.
+    RemoveMasterObjs( pDrawPage );
+    if( pDoc->IsGlobalDoc() )
+        pDoc->UpdateRefFlds( NULL );
+    if ( bOldIdle )
+        pDoc->StartIdleTimer();
+    bCallbackActionEnabled = TRUE;
+}
+
+/*************************************************************************
+|*
+|*  SwRootFrm::~SwRootFrm()
+|*
+|*  Ersterstellung      SS 05-Apr-1991
+|*  Letzte Aenderung    MA 12. Dec. 94
+|*
+|*************************************************************************/
+
+
+
+SwRootFrm::~SwRootFrm()
+{
+    bTurboAllowed = FALSE;
+    pTurbo = 0;
+    if(pBlink)
+        pBlink->FrmDelete( this );
+    ((SwFrmFmt*)pRegisteredIn)->GetDoc()->DelFrmFmt( (SwFrmFmt*)pRegisteredIn );
+    delete pDestroy;
+
+    //Referenzen entfernen.
+    for ( USHORT i = 0; i < pCurrShells->Count(); ++i )
+        (*pCurrShells)[i]->pRoot = 0;
+
+    delete pCurrShells;
+}
+
+/*************************************************************************
+|*
+|*  SwRootFrm::SetFixSize()
+|*
+|*  Ersterstellung      MA 23. Jul. 92
+|*  Letzte Aenderung    MA 11. Mar. 93
+|*
+|*************************************************************************/
+
+
+
+void SwRootFrm::SetFixSize( SzPtr pNew )
+{
+    if ( pNew == pHeight )
+    {
+        GetFmt()->SetAttr( SwFmtFillOrder( ATT_LEFT_TO_RIGHT ) );
+        bVarHeight = bFixWidth = FALSE;
+        bFixHeight = TRUE;
+    }
+    else
+    {
+        GetFmt()->SetAttr( SwFmtFillOrder( ATT_TOP_DOWN ) );
+        bVarHeight = bFixWidth = TRUE;
+        bFixHeight = FALSE;
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwRootFrm::RemoveMasterObjs()
+|*
+|*  Ersterstellung      MA 19.10.95
+|*  Letzte Aenderung    MA 19.10.95
+|*
+|*************************************************************************/
+
+
+void SwRootFrm::RemoveMasterObjs( SdrPage *pPg )
+{
+    //Alle Masterobjekte aus der Page entfernen. Nicht loeschen!!
+    for( ULONG i = pPg ? pPg->GetObjCount() : 0; i; )
+    {
+        SdrObject* pObj = pPg->GetObj( --i );
+        if( pObj->ISA(SwFlyDrawObj ) )
+            pPg->RemoveObject( i );
+    }
+}
+
+
+
+
diff --git a/sw/source/core/layout/pagechg.cxx b/sw/source/core/layout/pagechg.cxx
new file mode 100644
index 000000000000..0ea9be9e89fd
--- /dev/null
+++ b/sw/source/core/layout/pagechg.cxx
@@ -0,0 +1,1955 @@
+/*************************************************************************
+ *
+ *  $RCSfile: pagechg.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:22 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _SFXITEMITER_HXX //autogen
+#include 
+#endif
+
+#ifndef _FMTFSIZE_HXX //autogen
+#include 
+#endif
+#ifndef _FMTHDFT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTCLDS_HXX //autogen
+#include 
+#endif
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _FMTPDSC_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFORDR_HXX //autogen
+#include 
+#endif
+#ifndef _FMTORNT_HXX //autogen
+#include 
+#endif
+#ifndef _FTNINFO_HXX //autogen
+#include 
+#endif
+
+#include "viewimp.hxx"
+#include "pagefrm.hxx"
+#include "rootfrm.hxx"
+#include "cntfrm.hxx"
+#include "flyfrm.hxx"
+#include "doc.hxx"
+#include "fesh.hxx"
+#include "dview.hxx"
+#include "dflyobj.hxx"
+#include "dcontact.hxx"
+#include "frmtool.hxx"
+#include "fldbas.hxx"
+#include "hints.hxx"
+#include "errhdl.hxx"
+#include "swtable.hxx"
+
+#include "ftnidx.hxx"
+#include "bodyfrm.hxx"
+#include "ftnfrm.hxx"
+#include "tabfrm.hxx"
+#include "layact.hxx"
+#include "flyfrms.hxx"
+#include "frmsh.hxx"
+#include "htmltbl.hxx"
+#include "pagedesc.hxx"
+#include "poolfmt.hxx"
+
+/*************************************************************************
+|*
+|*  SwBodyFrm::SwBodyFrm()
+|*
+|*  Ersterstellung      MA ??
+|*  Letzte Aenderung    MA 01. Aug. 93
+|*
+|*************************************************************************/
+SwBodyFrm::SwBodyFrm( SwFrmFmt *pFmt ):
+    SwLayoutFrm( pFmt )
+{
+    nType = FRM_BODY;
+}
+
+/*************************************************************************
+|*
+|*  SwBodyFrm::Format()
+|*
+|*  Ersterstellung      MA 30. May. 94
+|*  Letzte Aenderung    MA 20. Jan. 99
+|*
+|*************************************************************************/
+void SwBodyFrm::Format( const SwBorderAttrs *pAttrs )
+{
+    //Formatieren des Body ist zu einfach, deshalb bekommt er ein eigenes
+    //Format; Umrandungen und dergl. sind hier nicht zu beruecksichtigen.
+    //Breite ist die der PrtArea des Uppers, Hoehe ist die Hoehe der PrtArea
+    //des Uppers abzueglich der Nachbarn (Wird eigentlich eingestellt aber
+    //Vorsicht ist die Mutter der Robustheit).
+    //Die PrtArea ist stets so gross wie der Frm itself.
+
+    if ( !bValidSize )
+    {
+        SwTwips nHeight = GetUpper()->Prt().Height();
+        const SwFrm *pFrm = GetUpper()->Lower();
+        do
+        {   if ( pFrm != this )
+                nHeight -= pFrm->Frm().Height();
+            pFrm = pFrm->GetNext();
+        } while ( pFrm );
+        if ( nHeight < 0 )
+            nHeight = 0;
+        Frm().Height( nHeight );
+        Frm().Width( GetUpper()->Prt().Width() );
+    }
+
+    Prt().Pos().X() = Prt().Pos().Y() = 0;
+    Prt().Height( Frm().Height() );
+    Prt().Width( Frm().Width() );
+    bValidSize = bValidPrtArea = TRUE;
+}
+
+
+/*************************************************************************
+|*
+|*  SwPageFrm::SwPageFrm(), ~SwPageFrm()
+|*
+|*  Ersterstellung      MA 20. Oct. 92
+|*  Letzte Aenderung    MA 08. Dec. 97
+|*
+|*************************************************************************/
+SwPageFrm::SwPageFrm( SwFrmFmt *pFmt, SwPageDesc *pPgDsc ) :
+    SwFtnBossFrm( pFmt ),
+    pSortedObjs( 0 ),
+    pDesc( pPgDsc ),
+    nPhyPageNum( 0 )
+{
+    SetMaxFtnHeight( pPgDsc->GetFtnInfo().GetHeight() ?
+                     pPgDsc->GetFtnInfo().GetHeight() : LONG_MAX ),
+    nType = FRM_PAGE;
+    bInvalidLayout = bInvalidCntnt = bInvalidSpelling = TRUE;
+    bInvalidFlyLayout = bInvalidFlyCntnt = bInvalidFlyInCnt =
+    bFtnPage = bEndNotePage = FALSE;
+
+    SwDoc *pDoc = pFmt->GetDoc();
+    if ( pDoc->IsBrowseMode() )
+    {
+        Frm().Height( 0 );
+        ViewShell *pSh = GetShell();
+        long nWidth = pSh ? pSh->VisArea().Width():0;
+        if ( !nWidth )
+            nWidth = 5000L;     //aendert sich sowieso
+        Frm().Width ( nWidth );
+    }
+    else
+        Frm().SSize( pFmt->GetFrmSize().GetSize() );
+
+    //Body-Bereich erzeugen und einsetzen, aber nur wenn ich nicht gerade
+    //eine Leerseite bin.
+    if ( FALSE == (bEmptyPage = pFmt == pDoc->GetEmptyPageFmt()) )
+    {
+        bEmptyPage = FALSE;
+        Calc();                             //Damit die PrtArea stimmt.
+        SwBodyFrm *pBodyFrm = new SwBodyFrm( pDoc->GetDfltFrmFmt() );
+        pBodyFrm->ChgSize( Prt().SSize() );
+        pBodyFrm->Paste( this );
+        pBodyFrm->Calc();                   //Damit die Spalten korrekt
+                                            //eingesetzt werden koennen.
+        pBodyFrm->InvalidatePos();
+
+        if ( pDoc->IsBrowseMode() )
+            _InvalidateSize();      //Alles nur gelogen
+
+        //Header/Footer einsetzen, nur rufen wenn aktiv.
+        if ( pFmt->GetHeader().IsActive() )
+            PrepareHeader();
+        if ( pFmt->GetFooter().IsActive() )
+            PrepareFooter();
+
+        const SwFmtCol &rCol = pFmt->GetCol();
+        if ( rCol.GetNumCols() > 1 )
+        {
+            const SwFmtCol aOld; //ChgColumns() verlaesst sich darauf, dass ein
+                                 //Old-Wert hereingereicht wird.
+            pBodyFrm->ChgColumns( aOld, rCol );
+        }
+    }
+}
+
+SwPageFrm::~SwPageFrm()
+{
+    //FlyContainer entleeren, delete der Flys uebernimmt der Anchor
+    //(Basisklasse SwFrm)
+    if ( pSortedObjs )
+    {
+        //Objekte koennen (warum auch immer) auch an Seiten verankert sein,
+        //die vor Ihren Ankern stehen. Dann wuerde auf bereits freigegebenen
+        //Speicher zugegriffen.
+        for ( USHORT i = 0; i < pSortedObjs->Count(); ++i )
+        {
+            SdrObject *pObj = (*pSortedObjs)[i];
+            if ( pObj->IsWriterFlyFrame() )
+            {
+                SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+                if ( pFly->IsFlyFreeFrm() )
+                    ((SwFlyFreeFrm*)pFly)->SetPage ( 0 );
+            }
+            else if ( pObj->GetUserCall() )
+                ((SwDrawContact*)pObj->GetUserCall())->ChgPage( 0 );
+        }
+        delete pSortedObjs;
+        pSortedObjs = 0;        //Auf 0 setzen, sonst rauchts beim Abmdelden von Flys!
+    }
+
+    //Damit der Zugriff auf zerstoerte Seiten verhindert werden kann.
+    if ( !IsEmptyPage() ) //#59184# sollte fuer Leerseiten unnoetig sein.
+    {
+        SwDoc *pDoc = GetFmt()->GetDoc();
+        if( pDoc && !pDoc->IsInDtor() )
+        {
+            ViewShell *pSh = GetShell();
+            if ( pSh )
+            {
+                SwViewImp *pImp = pSh->Imp();
+                pImp->SetFirstVisPageInvalid();
+                if ( pImp->IsAction() )
+                    pImp->GetLayAction().SetAgain();
+            }
+        }
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwPageFrm::PreparePage()
+|*
+|*  Beschreibung        Erzeugt die Spezifischen Flys zur Seite und formatiert
+|*      generischen Cntnt
+|*  Ersterstellung      MA 20. Oct. 92
+|*  Letzte Aenderung    MA 09. Nov. 95
+|*
+|*************************************************************************/
+void MA_FASTCALL lcl_FormatLay( SwLayoutFrm *pLay )
+{
+    //Alle LayoutFrms - nicht aber Tables, Flys o.ae. - formatieren.
+
+    SwFrm *pTmp = pLay->Lower();
+    //Erst die untergeordneten
+    while ( pTmp )
+    {
+        if ( pTmp->GetType() & 0x00FF )
+            ::lcl_FormatLay( (SwLayoutFrm*)pTmp );
+        pTmp = pTmp->GetNext();
+    }
+    pLay->Calc();
+}
+
+void MA_FASTCALL lcl_MakeObjs( const SwSpzFrmFmts &rTbl, SwPageFrm *pPage )
+{
+    //Anlegen bzw. registrieren von Flys und Drawobjekten.
+    //Die Formate stehen in der SpzTbl (vom Dokument).
+    //Flys werden angelegt, DrawObjekte werden bei der Seite angemeldet.
+
+    for ( USHORT i = 0; i < rTbl.Count(); ++i )
+    {
+        SdrObject *pSdrObj;
+        SwFrmFmt *pFmt = rTbl[i];
+        const SwFmtAnchor &rAnch = pFmt->GetAnchor();
+        if ( rAnch.GetPageNum() == pPage->GetPhyPageNum() &&
+             !rAnch.GetCntntAnchor() )
+        {
+            //Wird ein Rahmen oder ein SdrObject beschrieben?
+            BOOL bSdrObj = RES_DRAWFRMFMT == pFmt->Which();
+            pSdrObj = 0;
+            if ( bSdrObj  && 0 == (pSdrObj = pFmt->FindSdrObject()) )
+            {
+                ASSERT( FALSE, "DrawObject not found." );
+                pFmt->GetDoc()->DelFrmFmt( pFmt );
+                --i;
+                continue;
+            }
+            //Das Objekt kann noch an einer anderen Seite verankert sein.
+            //Z.B. beim Einfuegen einer neuen Seite aufgrund eines
+            //Pagedescriptor-Wechsels. Das Objekt muss dann umgehaengt
+            //werden.
+            //Fuer bestimmte Faelle ist das Objekt bereits an der richtigen
+            //Seite verankert. Das wird hier automatisch erledigt und braucht
+            //- wenngleich performater machbar - nicht extra codiert werden.
+            SwPageFrm *pPg = pPage->IsEmptyPage() ? (SwPageFrm*)pPage->GetNext() : pPage;
+            if ( bSdrObj )
+            {
+                SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pSdrObj);
+                if ( pContact->GetAnchor() )
+                    pContact->DisconnectFromLayout( FALSE );
+                pPg->SwFrm::AppendDrawObj( pContact );
+            }
+            else
+            {
+                SwClientIter aIter( *pFmt );
+                SwClient *pTmp = aIter.First( TYPE(SwFrm) );
+                SwFlyFrm *pFly;
+                if ( pTmp )
+                {
+                    pFly = (SwFlyFrm*)pTmp;
+                    if( pFly->GetAnchor() )
+                        pFly->GetAnchor()->RemoveFly( pFly );
+                }
+                else
+                    pFly = new SwFlyLayFrm( (SwFlyFrmFmt*)pFmt, pPg );
+                pPg->SwFrm::AppendFly( pFly );
+                ::RegistFlys( pPg, pFly );
+            }
+        }
+    }
+}
+
+void SwPageFrm::PreparePage( BOOL bFtn )
+{
+    SetFtnPage( bFtn );
+
+    //Klare Verhaeltnisse schaffen, sprich LayoutFrms der Seite formatieren.
+    if ( Lower() )
+        ::lcl_FormatLay( this );
+
+    //Vorhandene Flys bei der Seite anmelden.
+    ::RegistFlys( this, this );
+
+    //Flys und DrawObjekte die noch am Dokument bereitstehen.
+    //Fussnotenseiten tragen keine Seitengebundenen Flys!
+    //Es kann Flys und Objekte geben, die auf Leerseiten (Seitennummernmaessig)
+    //stehen wollen, diese werden jedoch von den Leerseiten ignoriert;
+    //sie werden von den Folgeseiten aufgenommen.
+    if ( !bFtn && !IsEmptyPage() )
+    {
+        SwDoc *pDoc = GetFmt()->GetDoc();
+
+        if ( GetPrev() && ((SwPageFrm*)GetPrev())->IsEmptyPage() )
+            lcl_MakeObjs( *pDoc->GetSpzFrmFmts(), (SwPageFrm*)GetPrev() );
+        lcl_MakeObjs( *pDoc->GetSpzFrmFmts(), this );
+
+        //Kopf-/Fusszeilen) formatieren.
+        SwLayoutFrm *pLow = (SwLayoutFrm*)Lower();
+        while ( pLow )
+        {
+            if ( pLow->GetType() & (FRMTYPE_HEADER|FRMTYPE_FOOTER) )
+            {
+                SwCntntFrm *pCntnt = pLow->ContainsCntnt();
+                while ( pCntnt && pLow->IsAnLower( pCntnt ) )
+                {
+                    pCntnt->OptCalc();  //Nicht die Vorgaenger
+                    pCntnt = pCntnt->GetNextCntntFrm();
+                }
+            }
+            pLow = (SwLayoutFrm*)pLow->GetNext();
+        }
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwPageFrm::Modify()
+|*
+|*  Ersterstellung      MA 20. Oct. 92
+|*  Letzte Aenderung    MA 03. Mar. 96
+|*
+|*************************************************************************/
+void SwPageFrm::Modify( SfxPoolItem * pOld, SfxPoolItem * pNew )
+{
+    ViewShell *pSh = GetShell();
+    if ( pSh )
+        pSh->SetFirstVisPageInvalid();
+    BYTE nInvFlags = 0;
+
+    if( pNew && RES_ATTRSET_CHG == pNew->Which() )
+    {
+        SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() );
+        SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() );
+        SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld );
+        SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew );
+        while( TRUE )
+        {
+            _UpdateAttr( (SfxPoolItem*)aOIter.GetCurItem(),
+                         (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags,
+                         &aOldSet, &aNewSet );
+            if( aNIter.IsAtEnd() )
+                break;
+            aNIter.NextItem();
+            aOIter.NextItem();
+        }
+        if ( aOldSet.Count() || aNewSet.Count() )
+            SwLayoutFrm::Modify( &aOldSet, &aNewSet );
+    }
+    else
+        _UpdateAttr( pOld, pNew, nInvFlags );
+
+    if ( nInvFlags != 0 )
+    {
+        InvalidatePage( this );
+        if ( nInvFlags & 0x01 )
+            _InvalidatePrt();
+        if ( nInvFlags & 0x02 )
+            SetCompletePaint();
+        if ( nInvFlags & 0x04 && GetNext() )
+            GetNext()->InvalidatePos();
+        if ( nInvFlags & 0x08 )
+            PrepareHeader();
+        if ( nInvFlags & 0x10 )
+            PrepareFooter();
+    }
+}
+
+void SwPageFrm::_UpdateAttr( SfxPoolItem *pOld, SfxPoolItem *pNew,
+                             BYTE &rInvFlags,
+                             SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet )
+{
+    BOOL bClear = TRUE;
+    const USHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
+    switch( nWhich )
+    {
+        case RES_FMT_CHG:
+        {
+            //Wenn sich das FrmFmt aendert kann hier einiges passieren.
+            //Abgesehen von den Grossenverhaeltnissen sind noch andere
+            //Dinge betroffen.
+            //1. Spaltigkeit.
+            ASSERT( pOld && pNew, "FMT_CHG Missing Format." );
+            const SwFmt* pOldFmt = ((SwFmtChg*)pOld)->pChangedFmt;
+            const SwFmt* pNewFmt = ((SwFmtChg*)pNew)->pChangedFmt;
+            ASSERT( pOldFmt && pNewFmt, "FMT_CHG Missing Format." );
+
+            const SwFmtCol &rOldCol = pOldFmt->GetCol();
+            const SwFmtCol &rNewCol = pNewFmt->GetCol();
+            if( rOldCol != rNewCol )
+            {
+                SwLayoutFrm *pB = FindBodyCont();
+                ASSERT( pB, "Seite ohne Body." );
+                pB->ChgColumns( rOldCol, rNewCol );
+            }
+
+            //2. Kopf- und Fusszeilen.
+            const SwFmtHeader &rOldH = pOldFmt->GetHeader();
+            const SwFmtHeader &rNewH = pNewFmt->GetHeader();
+            if( rOldH != rNewH )
+                rInvFlags |= 0x08;
+
+            const SwFmtFooter &rOldF = pOldFmt->GetFooter();
+            const SwFmtFooter &rNewF = pNewFmt->GetFooter();
+            if( rOldF != rNewF )
+                rInvFlags |= 0x10;
+        }
+            /* kein break hier */
+        case RES_FRM_SIZE:
+        {
+            const SwRect aOldRect( Frm() );
+            if ( GetFmt()->GetDoc()->IsBrowseMode() )
+            {
+                bValidSize = FALSE;
+                MakeAll();
+            }
+            else
+            {
+                const SwFmtFrmSize &rSz = nWhich == RES_FMT_CHG ?
+                        ((SwFmtChg*)pNew)->pChangedFmt->GetFrmSize() :
+                        (SwFmtFrmSize&)*pNew;
+
+                Frm().Height( Max( rSz.GetHeight(), long(MINLAY) ) );
+                Frm().Width ( Max( rSz.GetWidth(),  long(MINLAY) ) );
+                AdjustRootSize( CHG_CHGPAGE, &aOldRect );
+            }
+            //Window aufraeumen.
+            ViewShell *pSh;
+            if ( 0 != (pSh = GetShell()) && pSh->GetWin() && aOldRect.HasArea() )
+                pSh->InvalidateWindows( aOldRect );
+            rInvFlags |= 0x03;
+            SzPtr pVar = pVARSIZE;
+            if ( aOldRect.SSize().*pVar != Frm().SSize().*pVar)
+                rInvFlags |= 0x04;
+        }
+        break;
+
+        case RES_COL:
+        {
+            SwLayoutFrm *pB = FindBodyCont();
+            ASSERT( pB, "Seite ohne Body." );
+            pB->ChgColumns( *(const SwFmtCol*)pOld, *(const SwFmtCol*)pNew );
+            rInvFlags |= 0x02;
+        }
+        break;
+
+        case RES_HEADER:
+            rInvFlags |= 0x08;
+            break;
+
+        case RES_FOOTER:
+            rInvFlags |= 0x10;
+            break;
+
+        case RES_PAGEDESC_FTNINFO:
+            //Die derzeit einzig sichere Methode:
+            ((SwRootFrm*)GetUpper())->SetSuperfluous();
+            SetMaxFtnHeight( pDesc->GetFtnInfo().GetHeight() );
+            if ( !GetMaxFtnHeight() )
+                SetMaxFtnHeight( LONG_MAX );
+            SetColMaxFtnHeight();
+            //Hier wird die Seite ggf. zerstoert!
+            ((SwRootFrm*)GetUpper())->RemoveFtns( 0, FALSE, TRUE );
+            break;
+
+        default:
+            bClear = FALSE;
+    }
+    if ( bClear )
+    {
+        if ( pOldSet || pNewSet )
+        {
+            if ( pOldSet )
+                pOldSet->ClearItem( nWhich );
+            if ( pNewSet )
+                pNewSet->ClearItem( nWhich );
+        }
+        else
+            SwLayoutFrm::Modify( pOld, pNew );
+    }
+}
+
+/*************************************************************************
+|*
+|*                SwPageFrm::GetInfo()
+|*
+|*    Beschreibung      erfragt Informationen
+|*    Ersterstellung    JP 31.03.94
+|*    Letzte Aenderung  JP 31.03.94
+|*
+*************************************************************************/
+    // erfrage vom Modify Informationen
+BOOL SwPageFrm::GetInfo( SfxPoolItem & rInfo ) const
+{
+    if( RES_AUTOFMT_DOCNODE == rInfo.Which() )
+    {
+        // es gibt einen PageFrm also wird er benutzt
+        return FALSE;
+    }
+    return TRUE;        // weiter suchen
+}
+
+/*************************************************************************
+|*
+|*  SwPageFrm::SetPageDesc()
+|*
+|*  Ersterstellung      MA 02. Nov. 94
+|*  Letzte Aenderung    MA 02. Nov. 94
+|*
+|*************************************************************************/
+void  SwPageFrm::SetPageDesc( SwPageDesc *pNew, SwFrmFmt *pFmt )
+{
+    pDesc = pNew;
+    if ( pFmt )
+        SetFrmFmt( pFmt );
+}
+
+/*************************************************************************
+|*
+|*  SwPageFrm::FindPageDesc()
+|*
+|*  Beschreibung        Der richtige PageDesc wird bestimmt:
+|*      0.  Vom Dokument bei Fussnotenseiten und Endnotenseiten
+|*      1.  vom ersten BodyCntnt unterhalb der Seite.
+|*      2.  vom PageDesc der vorstehenden Seite.
+|*      3.  bei Leerseiten vom PageDesc der vorigen Seite.
+|*      3.1 vom PageDesc der folgenden Seite wenn es keinen Vorgaenger gibt.
+|*      4.  es ist der Default-PageDesc sonst.
+|*      5.  Im BrowseMode ist der Pagedesc immer der vom ersten Absatz im
+|*          Dokument oder Standard (der 0-te) wenn der erste Absatz keinen
+|*          wuenscht.
+|*     (6.  Im HTML-Mode ist der Pagedesc immer die HTML-Seitenvorlage.)
+|*  Ersterstellung      MA 15. Feb. 93
+|*  Letzte Aenderung    MA 17. Jun. 99
+|*
+|*************************************************************************/
+SwPageDesc *SwPageFrm::FindPageDesc()
+{
+    //0.
+    if ( IsFtnPage() )
+    {
+        SwDoc *pDoc = GetFmt()->GetDoc();
+        if ( IsEndNotePage() )
+            return pDoc->GetEndNoteInfo().GetPageDesc( *pDoc );
+        else
+            return pDoc->GetFtnInfo().GetPageDesc( *pDoc );
+    }
+
+    //6.
+    //if ( GetFmt()->GetDoc()->IsHTMLMode() )
+    //  return GetFmt()->GetDoc()->GetPageDescFromPool( RES_POOLPAGE_HTML );
+
+    SwPageDesc *pRet = 0;
+
+    //5.
+    if ( GetFmt()->GetDoc()->IsBrowseMode() )
+    {
+        SwCntntFrm *pFrm = GetUpper()->ContainsCntnt();
+        while ( !pFrm->IsInDocBody() )
+            pFrm = pFrm->GetNextCntntFrm();
+        SwFrm *pFlow = pFrm;
+        if ( pFlow->IsInTab() )
+            pFlow = pFlow->FindTabFrm();
+        pRet = (SwPageDesc*)pFlow->GetAttrSet()->GetPageDesc().GetPageDesc();
+        if ( !pRet )
+            pRet = &GetFmt()->GetDoc()->_GetPageDesc( 0 );
+        return pRet;
+    }
+
+    SwFrm *pFlow = FindFirstBodyCntnt();
+    if ( pFlow && pFlow->IsInTab() )
+        pFlow = pFlow->FindTabFrm();
+
+    //1.
+    if ( pFlow )
+    {
+        SwFlowFrm *pTmp = SwFlowFrm::CastFlowFrm( pFlow );
+        if ( !pTmp->IsFollow() )
+            pRet = (SwPageDesc*)pFlow->GetAttrSet()->GetPageDesc().GetPageDesc();
+    }
+
+    //3. und 3.1
+    if ( !pRet && IsEmptyPage() )
+        pRet = GetPrev() ? ((SwPageFrm*)GetPrev())->GetPageDesc()->GetFollow() :
+               GetNext() ? ((SwPageFrm*)GetNext())->GetPageDesc() : 0;
+
+    //2.
+    if ( !pRet )
+        pRet = GetPrev() ?
+                    ((SwPageFrm*)GetPrev())->GetPageDesc()->GetFollow() : 0;
+
+    //4.
+    if ( !pRet )
+        pRet = (SwPageDesc*)&GetFmt()->GetDoc()->GetPageDesc( 0 );
+
+
+    ASSERT( pRet, "Kein Descriptor gefunden." );
+    return pRet;
+}
+/*************************************************************************
+|*
+|*  SwPageFrm::AdjustRootSize()
+|*
+|*  Ersterstellung      MA 13. Aug. 93
+|*  Letzte Aenderung    MA 25. Jun. 95
+|*
+|*************************************************************************/
+//Wenn der RootFrm seine Groesse aendert muss benachrichtigt werden.
+void AdjustSizeChgNotify( SwRootFrm *pRoot )
+{
+    const BOOL bOld = pRoot->IsSuperfluous();
+    pRoot->bCheckSuperfluous = FALSE;
+    ViewShell *pSh = pRoot->GetCurrShell();
+    if ( pSh )
+    {
+        pSh->Imp()->NotifySizeChg( pRoot->Frm().SSize() );//Einmal fuer das Drawing.
+        do
+        {   pSh->SizeChgNotify( pRoot->Frm().SSize() );   //Einmal fuer jede Sicht.
+            pSh = (ViewShell*)pSh->GetNext();
+        } while ( pSh != pRoot->GetCurrShell() );
+    }
+    pRoot->bCheckSuperfluous = bOld;
+}
+
+void MA_FASTCALL lcl_ChgRootSize( SwFrm *pP, SwTwips nVal )
+{
+    if ( pP->bVarHeight )
+        pP->GetUpper()->ChgSize( Size( nVal, pP->GetUpper()->Frm().Height()));
+    else
+        pP->GetUpper()->ChgSize( Size( pP->GetUpper()->Frm().Width(), nVal));
+}
+
+void MA_FASTCALL lcl_AdjustRoot( SwFrm *pPage, SzPtr pFix, long nOld )
+{
+    //Groesse der groessten Seite ermitteln.
+    //nOld enthaelt den alten Wert wenn die Seite geschrumpft ist und
+    //den aktuellen Wert wenn sie etwa ausgeschnitten wurde. Dadurch
+    //kann abgebrochen werden, wenn eine Seite gefunden wird, deren Wert
+    //dem alten entspricht.
+    long nMax = pPage->Frm().SSize().*pFix;
+    if ( nMax == nOld )
+        nMax = 0;
+    const SwFrm *pFrm = pPage->GetUpper()->Lower();
+    while ( pFrm )
+    {
+        if ( pFrm != pPage )
+        {
+            const SwTwips nTmp = pFrm->Frm().SSize().*pFix;
+            if ( nTmp == nOld )
+            {
+                nMax = 0;
+                break;
+            }
+            else if ( nTmp > nMax )
+                nMax = nTmp;
+        }
+        pFrm = pFrm->GetNext();
+    }
+    if ( nMax )
+        lcl_ChgRootSize( pPage, nMax );
+}
+
+void SwPageFrm::AdjustRootSize( const SwPageChg eChgType, const SwRect *pOld )
+{
+    if ( !GetUpper() )
+        return;
+
+    const SwRect aOld( GetUpper()->Frm() );
+
+    SzPtr pFix = pFIXSIZE;
+    SzPtr pVar = pVARSIZE;
+    const SwTwips nVar = Frm().SSize().*pVar;
+    SwTwips nFix = Frm().SSize().*pFix;
+    SwTwips nDiff = 0;
+
+    switch ( eChgType )
+    {
+        case CHG_NEWPAGE:
+            {
+                if ( nFix > GetUpper()->Prt().SSize().*pFix )
+                    ::lcl_ChgRootSize( this, nFix );
+                nDiff = nVar;
+                if ( GetPrev() && !((SwPageFrm*)GetPrev())->IsEmptyPage() )
+                    nDiff += DOCUMENTBORDER/2;
+                else if ( !IsEmptyPage() && GetNext() )
+                    nDiff += DOCUMENTBORDER/2;
+            }
+            break;
+        case CHG_CUTPAGE:
+            {
+                if ( nFix == GetUpper()->Prt().SSize().*pFix )
+                    ::lcl_AdjustRoot( this, pFix, nFix );
+                nDiff = -nVar;
+                if ( GetPrev() && !((SwPageFrm*)GetPrev())->IsEmptyPage() )
+                    nDiff -= DOCUMENTBORDER/2;
+                else if ( !IsEmptyPage() && GetNext() )
+                    nDiff -= DOCUMENTBORDER/2;
+                if ( IsEmptyPage() && GetNext() && GetPrev() )
+                    nDiff = -nVar;
+            }
+            break;
+        case CHG_CHGPAGE:
+            {
+                ASSERT( pOld, "ChgPage ohne OldValue nicht moeglich." );
+                if ( pOld->SSize().*pFix < nFix )
+                {
+                    if ( nFix > GetUpper()->Prt().SSize().*pFix )
+                        ::lcl_ChgRootSize( this, nFix );
+                }
+                else if ( pOld->SSize().*pFix > nFix )
+                    ::lcl_AdjustRoot( this, pFix, pOld->SSize().*pFix );
+                nDiff = nVar - pOld->SSize().*pVar;
+            }
+            break;
+
+        default:
+            ASSERT( FALSE, "Neuer Typ fuer PageChg." );
+    }
+
+    if ( nDiff > 0 )
+        GetUpper()->Grow( nDiff, pVar );
+    else if ( nDiff < 0 )
+        GetUpper()->Shrink( -nDiff, pVar );
+
+    //Fix(8522): Calc auf die Root damit sich dir PrtArea sofort einstellt.
+    //Anderfalls gibt es Probleme wenn mehrere Aenderungen innerhalb einer
+    //Action laufen.
+    GetUpper()->Calc();
+
+    if ( aOld != GetUpper()->Frm() )
+    {
+        SwLayoutFrm *pUp = GetUpper();
+        if ( eChgType == CHG_CUTPAGE )
+        {
+            //Seiten vorher kurz aushaengen, weil sonst falsch formatiert wuerde.
+            SwFrm *pSibling = GetNext();
+            if ( ((SwRootFrm*)pUp)->GetLastPage() == this )
+                ::SetLastPage( (SwPageFrm*)GetPrev() );
+            Remove();
+            ::AdjustSizeChgNotify( (SwRootFrm*)pUp );
+            InsertBefore( pUp, pSibling );
+        }
+        else
+            ::AdjustSizeChgNotify( (SwRootFrm*)pUp );
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwPageFrm::Cut()
+|*
+|*  Ersterstellung      MA 23. Feb. 94
+|*  Letzte Aenderung    MA 22. Jun. 95
+|*
+|*************************************************************************/
+inline void SetLastPage( SwPageFrm *pPage )
+{
+    ((SwRootFrm*)pPage->GetUpper())->pLastPage = pPage;
+}
+
+void SwPageFrm::Cut()
+{
+    ViewShell *pSh = GetShell();
+    if ( !IsEmptyPage() )
+    {
+        if ( GetNext() )
+            GetNext()->InvalidatePos();
+
+        AdjustRootSize( CHG_CUTPAGE, 0 );
+
+        //Flys deren Anker auf anderen Seiten stehen umhaengen.
+        //DrawObjecte spielen hier keine Rolle.
+        if ( GetSortedObjs() )
+        {
+            for ( int i = 0; GetSortedObjs() &&
+                             (USHORT)i < GetSortedObjs()->Count(); ++i )
+            {
+                SdrObject *pO = (*GetSortedObjs())[i];
+                SwFlyFrm *pFly;
+                if ( pO->IsWriterFlyFrame() &&
+                     (pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm())->IsFlyAtCntFrm() )
+                {
+                    SwPageFrm *pAnchPage = pFly->GetAnchor() ?
+                                pFly->GetAnchor()->FindPageFrm() : 0;
+                    if ( pAnchPage && (pAnchPage != this) )
+                    {
+                        MoveFly( pFly, pAnchPage );
+                        --i;
+                        pFly->InvalidateSize();
+                        pFly->_InvalidatePos();
+                    }
+                }
+            }
+        }
+        //Window aufraeumen
+        if ( pSh && pSh->GetWin() )
+            pSh->InvalidateWindows( Frm() );
+    }
+
+    // die Seitennummer der Root runterzaehlen.
+    ((SwRootFrm*)GetUpper())->DecrPhyPageNums();
+    SwPageFrm *pPg = (SwPageFrm*)GetNext();
+    if ( pPg )
+    {
+        while ( pPg )
+        {
+            pPg->DecrPhyPageNum();  //inline --nPhyPageNum
+            pPg = (SwPageFrm*)pPg->GetNext();
+        }
+    }
+    else
+        ::SetLastPage( (SwPageFrm*)GetPrev() );
+
+    // Alle Verbindungen kappen.
+    Remove();
+    if ( pSh )
+        pSh->SetFirstVisPageInvalid();
+}
+
+/*************************************************************************
+|*
+|*  SwPageFrm::Paste()
+|*
+|*  Ersterstellung      MA 23. Feb. 94
+|*  Letzte Aenderung    MA 07. Dec. 94
+|*
+|*************************************************************************/
+void SwPageFrm::Paste( SwFrm* pParent, SwFrm* pSibling )
+{
+    ASSERT( pParent->IsRootFrm(), "Parent ist keine Root." );
+    ASSERT( pParent, "Kein Parent fuer Paste." );
+    ASSERT( pParent != this, "Bin selbst der Parent." );
+    ASSERT( pSibling != this, "Bin mein eigener Nachbar." );
+    ASSERT( !GetPrev() && !GetNext() && !GetUpper(),
+            "Bin noch irgendwo angemeldet." );
+
+    //In den Baum einhaengen.
+    InsertBefore( (SwLayoutFrm*)pParent, pSibling );
+
+    // die Seitennummer am Root hochzaehlen.
+    ((SwRootFrm*)GetUpper())->IncrPhyPageNums();
+    if( GetPrev() )
+        SetPhyPageNum( ((SwPageFrm*)GetPrev())->GetPhyPageNum() + 1 );
+    else
+        SetPhyPageNum( 1 );
+    SwPageFrm *pPg = (SwPageFrm*)GetNext();
+    if ( pPg )
+    {
+        while ( pPg )
+        {
+            pPg->IncrPhyPageNum();  //inline ++nPhyPageNum
+            pPg->_InvalidatePos();
+            pPg->InvalidateLayout();
+            pPg = (SwPageFrm*)pPg->GetNext();
+        }
+    }
+    else
+        ::SetLastPage( this );
+
+    //ggf. die Memberpointer korrigieren.
+    const SwFmtFillOrder &rFill =((SwLayoutFrm*)pParent)->GetFmt()->GetFillOrder();
+    if ( rFill.GetFillOrder() == ATT_BOTTOM_UP ||
+         rFill.GetFillOrder() == ATT_TOP_DOWN )
+        bVarHeight = TRUE;
+    else
+        bVarHeight = FALSE;
+
+    const SzPtr pFix = pFIXSIZE;
+    if( Frm().SSize().*pFix != pParent->Prt().SSize().*pFix )
+        _InvalidateSize();
+    InvalidatePos();
+
+    if ( !IsEmptyPage() )
+        AdjustRootSize( CHG_NEWPAGE, 0 );
+
+    ViewShell *pSh = GetShell();
+    if ( pSh )
+        pSh->SetFirstVisPageInvalid();
+}
+
+/*************************************************************************
+|*
+|*  SwPageFrm::PrepareRegisterChg()
+|*
+|*  Ersterstellung      AMA 22. Jul. 96
+|*  Letzte Aenderung    AMA 22. Jul. 96
+|*
+|*************************************************************************/
+void lcl_PrepFlyInCntRegister( SwCntntFrm *pFrm )
+{
+    pFrm->Prepare( PREP_REGISTER );
+    if( pFrm->GetDrawObjs() )
+    {
+        for( USHORT i = 0; i < pFrm->GetDrawObjs()->Count(); ++i )
+        {
+            SwFlyFrm *pFly;
+            SdrObject *pO = (*pFrm->GetDrawObjs())[i];
+            if( pO->IsWriterFlyFrame() &&
+                0 != (pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm()) &&
+                pFly->IsFlyInCntFrm() )
+            {
+                SwCntntFrm *pCnt = pFly->ContainsCntnt();
+                while ( pCnt )
+                {
+                    lcl_PrepFlyInCntRegister( pCnt );
+                    pCnt = pCnt->GetNextCntntFrm();
+                }
+            }
+        }
+    }
+}
+
+void SwPageFrm::PrepareRegisterChg()
+{
+    SwCntntFrm *pFrm = FindFirstBodyCntnt();
+    while( pFrm )
+    {
+        lcl_PrepFlyInCntRegister( pFrm );
+        pFrm = pFrm->GetNextCntntFrm();
+        if( !IsAnLower( pFrm ) )
+            break;
+    }
+    if( GetSortedObjs() )
+    {
+        for( USHORT i = 0; i < GetSortedObjs()->Count(); ++i )
+        {
+            SdrObject *pO = (*GetSortedObjs())[i];
+            if ( pO->IsWriterFlyFrame() )
+            {
+                SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+                pFrm = pFly->ContainsCntnt();
+                while ( pFrm )
+                {
+                    ::lcl_PrepFlyInCntRegister( pFrm );
+                    pFrm = pFrm->GetNextCntntFrm();
+                }
+            }
+        }
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFrm::CheckPageDescs()
+|*
+|*  Beschreibung        Prueft alle Seiten ab der uebergebenen, daraufhin,
+|*      ob sie das richtige FrmFmt verwenden. Wenn 'falsche' Seiten
+|*      aufgespuehrt werden, so wird versucht die Situation moeglichst
+|*      einfache zu bereinigen.
+|*
+|*  Ersterstellung      MA 10. Feb. 93
+|*  Letzte Aenderung    MA 18. Apr. 96
+|*
+|*************************************************************************/
+void SwFrm::CheckPageDescs( SwPageFrm *pStart, BOOL bNotifyFields )
+{
+    ASSERT( pStart, "Keine Startpage." );
+
+    ViewShell *pSh   = pStart->GetShell();
+    SwViewImp *pImp  = pSh ? pSh->Imp() : 0;
+
+    if ( pImp && pImp->IsAction() && !pImp->GetLayAction().IsCheckPages() )
+    {
+        pImp->GetLayAction().SetCheckPageNum( pStart->GetPhyPageNum() );
+        return;
+    }
+
+    //Fuer das Aktualisieren der Seitennummern-Felder gibt nDocPos
+    //die Seitenposition an, _ab_ der invalidiert werden soll.
+    SwTwips nDocPos  = LONG_MAX;
+
+    SwRootFrm *pRoot = (SwRootFrm*)pStart->GetUpper();
+    SwDoc* pDoc      = pStart->GetFmt()->GetDoc();
+    const BOOL bFtns = 0 != pDoc->GetFtnIdxs().Count();
+
+    if ( pStart->GetPrev() && ((SwPageFrm*)pStart->GetPrev())->IsEmptyPage() )
+        pStart = (SwPageFrm*)pStart->GetPrev();
+    SwPageFrm *pPage = pStart;
+    while ( pPage )
+    {
+        //gewuenschten PageDesc und FrmFmt festellen.
+        SwPageDesc *pDesc = pPage->FindPageDesc();
+        const USHORT nPgNum = pPage->GetVirtPageNum();
+        BOOL bOdd = nPgNum % 2 ? TRUE : FALSE;
+        SwFrmFmt *pFmtWish = bOdd ? pDesc->GetRightFmt() : pDesc->GetLeftFmt();
+
+        if ( pDesc != pPage->GetPageDesc() ||       //falscher Desc
+             (pFmtWish != pPage->GetFmt()  &&       //falsches Format und
+             (!pPage->IsEmptyPage() || pFmtWish)))  //nicht Leerseite
+        {
+            //Wenn wir schon ein Seite veraendern muessen kann das eine
+            //Weile dauern, deshalb hier den WaitCrsr pruefen.
+            if( pImp )
+                pImp->CheckWaitCrsr();
+
+            //Ab hier muessen die Felder invalidiert werden!
+            if ( nDocPos == LONG_MAX )
+                nDocPos = pPage->GetPrev() ?
+                            pPage->GetPrev()->Frm().Top() : pPage->Frm().Top();
+
+            //Faelle:
+            //1. Wir haben eine EmptyPage und wollen eine "Normalseite".
+            //      ->EmptyPage wegwerfen und weiter mit der naechsten.
+            //2. Wir haben eine EmptyPage und wollen eine EmptyPage mit
+            //   anderem Descriptor.
+            //      ->Descriptor austauschen.
+            //3. Wir haben eine "Normalseite" und wollen eine EmptyPage.
+            //      ->Emptypage einfuegen, nicht aber wenn die Vorseite
+            //                             bereits eine EmptyPage ist -> 6.
+            //4. Wir haben eine "Normalseite" und wollen eine "Normalseite"
+            //   mit anderem Descriptor
+            //      ->Descriptor und Format austauschen
+            //5. Wir haben eine "Normalseite" und wollen eine "Normalseite"
+            //   mit anderem Format
+            //      ->Format austauschen.
+            //6. Wir haben kein Wunschformat erhalten, also nehmen wir das
+            //   'andere' Format (rechts/links) des PageDesc.
+
+            if ( pPage->IsEmptyPage() && pFmtWish )         //1.
+            {
+                SwPageFrm *pTmp = (SwPageFrm*)pPage->GetNext();
+                pPage->Cut();
+                delete pPage;
+                if ( pStart == pPage )
+                    pStart = pTmp;
+                pPage = pTmp;
+                continue;
+            }
+            else if ( pPage->IsEmptyPage() && !pFmtWish &&  //2.
+                      pDesc != pPage->GetPageDesc() )
+            {
+                pPage->SetPageDesc( pDesc, 0 );
+            }
+            else if ( !pPage->IsEmptyPage() && !pFmtWish && //3
+                      (!pPage->GetPrev() ||                 //nicht wenn Vorseite
+                       (pPage->GetPrev() &&                 //EmptyPage
+                        !((SwPageFrm*)pPage->GetPrev())->IsEmptyPage())))
+            {
+                if ( pPage->GetPrev() )
+                    pDesc = ((SwPageFrm*)pPage->GetPrev())->GetPageDesc();
+                SwPageFrm *pTmp = new SwPageFrm( pDoc->GetEmptyPageFmt(),pDesc);
+                pTmp->Paste( pRoot, pPage );
+                pTmp->PreparePage( FALSE );
+                pPage = pTmp;
+            }
+            else if ( pPage->GetPageDesc() != pDesc )           //4.
+            {
+                SwPageDesc *pOld = pPage->GetPageDesc();
+                pPage->SetPageDesc( pDesc, pFmtWish );
+                if ( bFtns )
+                {
+                    //Wenn sich bestimmte Werte der FtnInfo veraendert haben
+                    //muss etwas passieren. Wir versuchen den Schaden zu
+                    //begrenzen.
+                    //Wenn die Seiten keinen FtnCont hat, ist zwar theoretisches
+                    //ein Problem denkbar, aber das ignorieren wir mit aller Kraft.
+                    //Bei Aenderungen hoffen wir mal, dass eine Invalidierung
+                    //ausreicht, denn alles andere wuerde viel Kraft kosten.
+                    SwFtnContFrm *pCont = pPage->FindFtnCont();
+                    if ( pCont && !(pOld->GetFtnInfo() == pDesc->GetFtnInfo()) )
+                        pCont->_InvalidateAll();
+                }
+            }
+            else if ( pFmtWish && pPage->GetFmt() != pFmtWish )         //5.
+            {
+                pPage->SetFrmFmt( pFmtWish );
+            }
+            else if ( !pFmtWish )                                       //6.
+            {
+                //Format mit verdrehter Logic besorgen.
+                pFmtWish = bOdd ? pDesc->GetLeftFmt() : pDesc->GetRightFmt();
+                if ( pPage->GetFmt() != pFmtWish )
+                    pPage->SetFrmFmt( pFmtWish );
+            }
+#ifndef PRODUCT
+            else
+            {
+                ASSERT( FALSE, "CheckPageDescs, missing solution" );
+            }
+#endif
+        }
+        else if ( pPage->IsEmptyPage() )
+        {
+            //Es kann noch sein, dass die Leerseite schlicht  ueberflussig ist.
+            //Obiger Algorithmus kann dies leider nicht feststellen.
+            //Eigentlich muesste die Leerseite einfach praeventiv entfernt
+            //werden; sie wuerde ja ggf. wieder eingefuegt.
+            //Die EmptyPage ist genau dann ueberfluessig, wenn die Folgeseite
+            //auch ohne sie auskommt. Dazu muessen wir uns die Verhaeltnisse
+            //genauer ansehen. Wir bestimmen den PageDesc und die virtuelle
+            //Seitennummer manuell.
+            SwPageFrm *pPg = (SwPageFrm*)pPage->GetNext();
+            BOOL bDel = FALSE;
+            if ( pPg )
+            {
+                SwFrm *pFlow = pPg->FindFirstBodyCntnt();
+                SwPageDesc *pDesc = 0;
+                USHORT nPgNum = 0;
+                if ( pFlow )
+                {
+                    if ( pFlow->IsInTab() )
+                        pFlow = pFlow->FindTabFrm();
+                    const SwFmtPageDesc& rPgDesc = pFlow->GetAttrSet()->GetPageDesc();
+                    pDesc = (SwPageDesc*)rPgDesc.GetPageDesc();
+                    nPgNum = rPgDesc.GetNumOffset();
+                }
+                if ( !pDesc )
+                {
+                    if ( pPage->GetPrev() )
+                        pDesc = ((SwPageFrm*)pPage->GetPrev())->GetPageDesc()->
+                                                                    GetFollow();
+                    else
+                        pDesc = (SwPageDesc*)&pDoc->GetPageDesc( 0 );
+                }
+                if ( !nPgNum )
+                    nPgNum = pPage->GetVirtPageNum();
+                BOOL bOdd = nPgNum % 2 ? TRUE : FALSE;
+                SwFrmFmt *pFmt = bOdd ? pDesc->GetRightFmt() : pDesc->GetLeftFmt();
+                bDel = pFmt ? TRUE : FALSE;
+            }
+            else
+                bDel = TRUE;
+
+            if ( bDel )
+            {
+                //Die Folgeseite hat kein Problem ein FrmFmt zu finden oder keinen
+                //Nachfolger, also ist die Leerseite ueberfluessig.
+                SwPageFrm *pTmp = (SwPageFrm*)pPage->GetNext();
+                pPage->Cut();
+                delete pPage;
+                if ( pStart == pPage )
+                    pStart = pTmp;
+                pPage = pTmp;
+                continue;
+            }
+        }
+        pPage = (SwPageFrm*)pPage->GetNext();
+    }
+
+    pRoot->SetAssertFlyPages();
+    pRoot->AssertPageFlys( pStart );
+
+    if ( bNotifyFields && (!pImp || !pImp->IsUpdateExpFlds()) )
+    {
+        SwDocPosUpdate aMsgHnt( nDocPos );
+        pDoc->UpdatePageFlds( &aMsgHnt );
+    }
+
+#ifndef PRODUCT
+    //Ein paar Pruefungen muessen schon erlaubt sein.
+
+    //1. Keine zwei EmptyPages hintereinander.
+    //2. Alle PageDescs richtig?
+    BOOL bEmpty = FALSE;
+    SwPageFrm *pPg = pStart;
+    while ( pPg )
+    {
+        if ( pPg->IsEmptyPage() )
+        {
+            if ( bEmpty )
+            {
+                ASSERT( FALSE, "Doppelte Leerseiten." );
+                break;  //Einmal reicht.
+            }
+            bEmpty = TRUE;
+        }
+        else
+            bEmpty = FALSE;
+
+//MA 21. Jun. 95: Kann zu testzwecken 'rein, ist aber bei zyklen durchaus
+//moeglich: Ein paar Seiten, auf der ersten 'erste Seite' anwenden,
+//rechte als folge der ersten, linke als folge der rechten, rechte als
+//folge der linken.
+//      ASSERT( pPg->GetPageDesc() == pPg->FindPageDesc(),
+//              "Seite mit falschem Descriptor." );
+
+        pPg = (SwPageFrm*)pPg->GetNext();
+    }
+#endif
+}
+
+/*************************************************************************
+|*
+|*  SwFrm::InsertPage()
+|*
+|*  Beschreibung
+|*  Ersterstellung      MA 10. Feb. 93
+|*  Letzte Aenderung    MA 27. Jul. 93
+|*
+|*************************************************************************/
+SwPageFrm *SwFrm::InsertPage( SwPageFrm *pPrevPage, BOOL bFtn )
+{
+    SwPageFrm *pSibling = (SwPageFrm*)pPrevPage->GetNext();
+    SwRootFrm *pRoot = (SwRootFrm*)pPrevPage->GetUpper();
+
+        //Rechte (ungerade) oder linke (gerade) Seite einfuegen?
+    BOOL bNumOfst = FALSE;
+    BOOL bOdd;
+
+    //Welcher PageDesc gilt?
+    //Bei CntntFrm der aus dem Format wenn einer angegeben ist,
+    //der Follow vom bereits in der PrevPage gueltigen sonst.
+    SwPageDesc *pDesc = 0;
+    if ( IsFlowFrm() && !SwFlowFrm::CastFlowFrm( this )->IsFollow() )
+    {   SwFmtPageDesc &rDesc = (SwFmtPageDesc&)GetAttrSet()->GetPageDesc();
+        pDesc = rDesc.GetPageDesc();
+        if ( rDesc.GetNumOffset() )
+        {   //Wenn sich PageDesc und NumOfset wiedersprechen kann nur
+            //der PageDesc 'rechter haben'
+            bOdd = rDesc.GetNumOffset() % 2 ? TRUE : FALSE;
+            if ( !(bOdd ? pDesc->GetRightFmt() : pDesc->GetLeftFmt()) )
+                bOdd = !bOdd;
+            bNumOfst = TRUE;
+            //Die Gelegenheit nutzen wir um das Flag an der Root zu pflegen.
+            pRoot->SetVirtPageNum( TRUE );
+        }
+    }
+    if ( !bNumOfst )
+        bOdd = pPrevPage->GetVirtPageNum() % 2 ? FALSE : TRUE;
+
+    if ( !pDesc )
+        pDesc = pPrevPage->GetPageDesc()->GetFollow();
+
+    ASSERT( pDesc, "Kein PageDesc gefunden." );
+
+    SwDoc *pDoc = pPrevPage->GetFmt()->GetDoc();
+    SwFrmFmt *pFmt = bOdd ? pDesc->GetRightFmt() : pDesc->GetLeftFmt();
+    BOOL bCheckPages = FALSE;
+    //Wenn ich kein FrmFmt fuer die Seite gefunden habe, muss ich eben eine
+    //Leerseite einfuegen.
+    if ( !pFmt )
+    {   pFmt = pDoc->GetEmptyPageFmt();
+        SwPageDesc *pTmpDesc = pPrevPage->GetPageDesc();
+        SwPageFrm *pPage = new SwPageFrm( pFmt, pTmpDesc );
+        pPage->Paste( pRoot, pSibling );
+        pPage->PreparePage( bFtn );
+        //Wenn der Sibling keinen Bodytext enthaelt kann ich ihn vernichten
+        //Es sei denn, es ist eine Fussnotenseite
+        if ( pSibling && !pSibling->IsFtnPage() &&
+             !pSibling->FindFirstBodyCntnt() )
+        {
+            SwPageFrm *pDel = pSibling;
+            pSibling = (SwPageFrm*)pSibling->GetNext();
+            if ( pDoc->GetFtnIdxs().Count() )
+                pRoot->RemoveFtns( pDel, TRUE );
+            pDel->Cut();
+            delete pDel;
+        }
+        else
+            bCheckPages = TRUE;
+        //Jetzt muss ich ein Format fuer die entsprechende Seite bekommen.
+        pFmt = bOdd ? pDesc->GetLeftFmt() : pDesc->GetRightFmt();
+        ASSERT( pFmt, "Descriptor gibt kein Format her." );
+    }
+    SwPageFrm *pPage = new SwPageFrm( pFmt, pDesc );
+    pPage->Paste( pRoot, pSibling );
+    pPage->PreparePage( bFtn );
+    //Wenn der Sibling keinen Bodytext enthaelt kann ich ihn vernichten
+    //Es sei denn es ist eine Fussnotenseite.
+    if ( pSibling && !pSibling->IsFtnPage() &&
+         !pSibling->FindFirstBodyCntnt() )
+    {
+        SwPageFrm *pDel = pSibling;
+        pSibling = (SwPageFrm*)pSibling->GetNext();
+        if ( pDoc->GetFtnIdxs().Count() )
+            pRoot->RemoveFtns( pDel, TRUE );
+        pDel->Cut();
+        delete pDel;
+    }
+    else
+        bCheckPages = TRUE;
+
+    if ( pSibling )
+    {
+        if ( bCheckPages )
+        {
+            CheckPageDescs( pSibling, FALSE );
+            ViewShell *pSh = GetShell();
+            SwViewImp *pImp = pSh ? pSh->Imp() : 0;
+            if ( pImp && pImp->IsAction() && !pImp->GetLayAction().IsCheckPages() )
+            {
+                const USHORT nNum = pImp->GetLayAction().GetCheckPageNum();
+                if ( nNum == pPrevPage->GetPhyPageNum() + 1 )
+                    pImp->GetLayAction().SetCheckPageNumDirect(
+                                                    pSibling->GetPhyPageNum() );
+                return pPage;
+            }
+        }
+        else
+            pRoot->AssertPageFlys( pSibling );
+    }
+
+    //Fuer das Aktualisieren der Seitennummern-Felder gibt nDocPos
+    //die Seitenposition an, _ab_ der invalidiert werden soll.
+    ViewShell *pSh = GetShell();
+    if ( !pSh || !pSh->Imp()->IsUpdateExpFlds() )
+    {
+        SwDocPosUpdate aMsgHnt( pPrevPage->Frm().Top() );
+        pDoc->UpdatePageFlds( &aMsgHnt );
+    }
+    return pPage;
+}
+
+/*************************************************************************
+|*
+|*  SwRootFrm::GrowFrm()
+|*
+|*  Ersterstellung      MA 30. Jul. 92
+|*  Letzte Aenderung    MA 05. May. 94
+|*
+|*************************************************************************/
+SwTwips SwRootFrm::GrowFrm( SwTwips nDist, const SzPtr pDirection,
+                            BOOL bTst, BOOL bInfo )
+{
+    if ( !bTst )
+        Frm().SSize().*pDirection += nDist;
+    return nDist;
+}
+/*************************************************************************
+|*
+|*  SwRootFrm::ShrinkFrm()
+|*
+|*  Ersterstellung      MA 30. Jul. 92
+|*  Letzte Aenderung    MA 05. May. 94
+|*
+|*************************************************************************/
+SwTwips SwRootFrm::ShrinkFrm( SwTwips nDist, const SzPtr pDirection,
+                              BOOL bTst, BOOL bInfo )
+{
+    ASSERT( nDist >= 0, "nDist < 0." );
+    ASSERT( nDist <= Frm().SSize().*pDirection, "nDist > als aktuelle Groesse." );
+
+    if ( !bTst )
+        Frm().SSize().*pDirection -= nDist;
+    return nDist;
+}
+
+/*************************************************************************
+|*
+|*  SwRootFrm::RemoveSuperfluous()
+|*
+|*  Beschreibung:       Entfernung von ueberfluessigen Seiten.
+|*          Arbeitet nur wenn das Flag bCheckSuperfluous gesetzt ist.
+|*          Definition: Eine Seite ist genau dann leer, wenn der
+|*          Body-Textbereich keinen CntntFrm enthaelt, aber nicht, wenn noch
+|*          mindestens ein Fly an der Seite klebt.
+|*          Die Seite ist auch dann nicht leer, wenn sie noch eine
+|*          Fussnote enthaelt.
+|*          Es muss zweimal angesetzt werden um leeren Seiten aufzuspueren:
+|*              - einmal fuer die Endnotenseiten.
+|*              - und einmal fuer die Seiten des Bodytextes.
+|*
+|*  Ersterstellung      MA 20. May. 92
+|*  Letzte Aenderung    MA 10. Jan. 95
+|*
+|*************************************************************************/
+void SwRootFrm::RemoveSuperfluous()
+{
+    if ( !IsSuperfluous() )
+        return;
+    bCheckSuperfluous = FALSE;
+
+    SwPageFrm *pPage = GetLastPage();
+    long nDocPos = LONG_MAX;
+
+    //Jetzt wird fuer die jeweils letzte Seite geprueft ob sie leer ist
+    //bei der ersten nicht leeren Seite wird die Schleife beendet.
+    do
+    {
+        FASTBOOL bFlys = 0 != pPage->GetSortedObjs();
+        if ( bFlys )
+        {
+            //Nur weil die Seite Flys hat sind wir noch lange nicht fertig,
+            //denn wenn alle Flys an generischem Inhalt haengen, so ist sie
+            //trotzdem ueberfluessig (Ueberpruefung auf DocBody sollte reichen).
+            //DrawObjekte haengen niemals an generischem Inhalt.
+            FASTBOOL bOnlyGen = TRUE;
+            SwSortDrawObjs &rObjs = *pPage->GetSortedObjs();
+            for ( USHORT i = 0; bOnlyGen && i < rObjs.Count(); ++i )
+            {
+                SdrObject *pO = rObjs[i];
+                if ( pO->IsWriterFlyFrame() )
+                {
+                    SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+                    while ( bOnlyGen && pFly )
+                    {
+                        if ( pFly->IsFlyLayFrm() ||
+                             (pFly->GetAnchor()->IsInDocBody() &&
+                              !pFly->GetAnchor()->IsInFly()) )
+                            bOnlyGen = FALSE;
+                        else
+                            pFly = pFly->GetAnchor()->FindFlyFrm();
+                    }
+                }
+                else
+                    bOnlyGen = FALSE;
+            }
+            bFlys = !bOnlyGen;
+        }
+
+        if ( pPage->FindFirstBodyCntnt() || pPage->FindFtnCont() || bFlys )
+        {
+            if ( pPage->IsFtnPage() )
+            {
+                while ( pPage->IsFtnPage() )
+                {
+                    pPage = (SwPageFrm*)pPage->GetPrev();
+                    ASSERT( pPage, "Nur noch Endnotenseiten uebrig." );
+                }
+                continue;
+            }
+            else
+                pPage = 0;
+        }
+
+        if ( pPage )
+        {
+            SwPageFrm *pEmpty = pPage;
+            pPage = (SwPageFrm*)pPage->GetPrev();
+            if ( GetFmt()->GetDoc()->GetFtnIdxs().Count() )
+                RemoveFtns( pEmpty, TRUE );
+            pEmpty->Cut();
+            delete pEmpty;
+            nDocPos = pPage ? pPage->Frm().Top() : 0;
+        }
+    } while ( pPage );
+
+    ViewShell *pSh = GetShell();
+    if ( nDocPos != LONG_MAX &&
+         (!pSh || !pSh->Imp()->IsUpdateExpFlds()) )
+    {
+        SwDocPosUpdate aMsgHnt( nDocPos );
+        GetFmt()->GetDoc()->UpdatePageFlds( &aMsgHnt );
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwRootFrm::AssertFlyPages()
+|*
+|*  Beschreibung        Stellt sicher, dass genuegend Seiten vorhanden
+|*      sind, damit alle Seitengebundenen Rahmen und DrawObject
+|*      untergebracht sind.
+|*
+|*  Ersterstellung      MA 27. Jul. 93
+|*  Letzte Aenderung    MA 24. Apr. 97
+|*
+|*************************************************************************/
+void SwRootFrm::AssertFlyPages()
+{
+    if ( !IsAssertFlyPages() )
+        return;
+    bAssertFlyPages = FALSE;
+
+    SwDoc *pDoc = GetFmt()->GetDoc();
+    const SwSpzFrmFmts *pTbl = pDoc->GetSpzFrmFmts();
+
+    //Auf welche Seite will der 'letzte' Fly?
+    USHORT nMaxPg = 0;
+    for ( USHORT i = 0; i < pTbl->Count(); ++i )
+    {
+        const SwFmtAnchor &rAnch = (*pTbl)[i]->GetAnchor();
+        if ( !rAnch.GetCntntAnchor() && nMaxPg < rAnch.GetPageNum() )
+            nMaxPg = rAnch.GetPageNum();
+    }
+    //Wieviele Seiten haben wir derzeit?
+    SwPageFrm *pPage = (SwPageFrm*)Lower();
+    while ( pPage && pPage->GetNext() &&
+            !((SwPageFrm*)pPage->GetNext())->IsFtnPage() )
+    {
+        pPage = (SwPageFrm*)pPage->GetNext();
+    }
+
+    if ( nMaxPg > pPage->GetPhyPageNum() )
+    {
+        //Die Seiten werden ausgehend von der letzten Seite konsequent
+        //nach den Regeln der PageDescs weitergefuehrt.
+        BOOL bOdd = pPage->GetPhyPageNum() % 2 ? TRUE : FALSE;
+        SwPageDesc *pDesc = pPage->GetPageDesc();
+        SwFrm *pSibling = pPage->GetNext();
+        for ( i = pPage->GetPhyPageNum(); i < nMaxPg; ++i  )
+        {
+            if ( !(bOdd ? pDesc->GetRightFmt() : pDesc->GetLeftFmt()) )
+            {
+                //Leerseite einfuegen, die Flys werden aber erst von
+                //der naechsten Seite aufgenommen!
+                pPage = new SwPageFrm( pDoc->GetEmptyPageFmt(), pDesc );
+                pPage->Paste( this, pSibling );
+                pPage->PreparePage( FALSE );
+                bOdd = bOdd ? FALSE : TRUE;
+                ++i;
+            }
+            pPage = new
+                    SwPageFrm( (bOdd ? pDesc->GetRightFmt() :
+                                       pDesc->GetLeftFmt()), pDesc );
+            pPage->Paste( this, pSibling );
+            pPage->PreparePage( FALSE );
+            bOdd = bOdd ? FALSE : TRUE;
+            pDesc = pDesc->GetFollow();
+        }
+        //Jetzt koennen die Endnotenseiten natuerlich wieder krumm sein;
+        //in diesem Fall werden sie vernichtet.
+        if ( pDoc->GetFtnIdxs().Count() )
+        {
+            pPage = (SwPageFrm*)Lower();
+            while ( pPage && !pPage->IsFtnPage() )
+                pPage = (SwPageFrm*)pPage->GetNext();
+
+            if ( pPage )
+            {
+                SwPageDesc *pDesc = pPage->FindPageDesc();
+                bOdd = pPage->GetVirtPageNum() % 2 ? TRUE : FALSE;
+                if ( pPage->GetFmt() !=
+                     (bOdd ? pDesc->GetRightFmt() : pDesc->GetLeftFmt()) )
+                    RemoveFtns( pPage, FALSE, TRUE );
+            }
+        }
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwRootFrm::AssertPageFlys()
+|*
+|*  Beschreibung        Stellt sicher, dass ab der uebergebenen Seite
+|*      auf allen Seiten die Seitengebunden Objecte auf der richtigen
+|*      Seite (Seitennummer stehen).
+|*
+|*  Ersterstellung      MA 02. Nov. 94
+|*  Letzte Aenderung    MA 10. Aug. 95
+|*
+|*************************************************************************/
+void SwRootFrm::AssertPageFlys( SwPageFrm *pPage )
+{
+    while ( pPage )
+    {
+        if ( pPage->GetSortedObjs() )
+        {
+            pPage->GetSortedObjs();
+            for ( int i = 0;
+                  pPage->GetSortedObjs() && USHORT(i) < pPage->GetSortedObjs()->Count();
+                  ++i)
+            {
+                SwFrmFmt *pFmt = ::FindFrmFmt( (*pPage->GetSortedObjs())[i] );
+                const SwFmtAnchor &rAnch = pFmt->GetAnchor();
+                const USHORT nPg = rAnch.GetPageNum();
+                if ( rAnch.GetAnchorId() == FLY_PAGE &&
+                     nPg != pPage->GetPhyPageNum() )
+                {
+                    //Das er auf der falschen Seite steht muss noch nichts
+                    //heissen, wenn er eigentlich auf der Vorseite
+                    //stehen will und diese eine EmptyPage ist.
+                    if ( !(pPage->GetPhyPageNum()-1 == nPg &&
+                            ((SwPageFrm*)pPage->GetPrev())->IsEmptyPage()) )
+                    {
+                        //Umhaengen kann er sich selbst, indem wir ihm
+                        //einfach ein Modify mit seinem AnkerAttr schicken.
+#ifdef PRODUCT
+                        pFmt->SwModify::Modify( 0, (SwFmtAnchor*)&rAnch );
+#else
+                        const USHORT nCnt = pPage->GetSortedObjs()->Count();
+                        pFmt->SwModify::Modify( 0, (SwFmtAnchor*)&rAnch );
+                        ASSERT( !pPage->GetSortedObjs() ||
+                                nCnt != pPage->GetSortedObjs()->Count(),
+                                "Kann das Obj nicht umhaengen." );
+#endif
+                        --i;
+                    }
+                }
+            }
+        }
+        pPage = (SwPageFrm*)pPage->GetNext();
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwRootFrm::ChgSize()
+|*
+|*  Ersterstellung      MA 24. Jul. 92
+|*  Letzte Aenderung    MA 13. Aug. 93
+|*
+|*************************************************************************/
+void SwRootFrm::ChgSize( const Size& aNewSize )
+{
+    Frm().SSize() = aNewSize;
+    _InvalidatePrt();
+    bFixHeight =  bVarHeight;
+    bFixWidth  = !bVarHeight;
+}
+
+/*************************************************************************
+|*
+|*  SwRootFrm::MakeAll()
+|*
+|*  Ersterstellung      MA 17. Nov. 92
+|*  Letzte Aenderung    MA 19. Apr. 93
+|*
+|*************************************************************************/
+void SwRootFrm::MakeAll()
+{
+    if ( !bValidPos )
+    {   bValidPos = TRUE;
+        aFrm.Pos().X() = aFrm.Pos().Y() = DOCUMENTBORDER;
+    }
+    if ( !bValidPrtArea )
+    {   bValidPrtArea = TRUE;
+        aPrt.Pos().X() = aPrt.Pos().Y() = 0;
+        aPrt.SSize( aFrm.SSize() );
+    }
+    if ( !bValidSize )
+        //SSize wird von den Seiten (Cut/Paste) eingestellt.
+        bValidSize = TRUE;
+}
+
+/*************************************************************************
+|*
+|*  SwRootFrm::ImplInvalidateBrowseWidth()
+|*
+|*  Ersterstellung      MA 08. Jun. 96
+|*  Letzte Aenderung    MA 08. Jun. 96
+|*
+|*************************************************************************/
+void SwRootFrm::ImplInvalidateBrowseWidth()
+{
+    bBrowseWidthValid = FALSE;
+    SwFrm *pPg = Lower();
+    while ( pPg )
+    {
+        pPg->InvalidateSize();
+        pPg = pPg->GetNext();
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwRootFrm::ImplCalcBrowseWidth()
+|*
+|*  Ersterstellung      MA 07. Jun. 96
+|*  Letzte Aenderung    MA 13. Jun. 96
+|*
+|*************************************************************************/
+void SwRootFrm::ImplCalcBrowseWidth()
+{
+    ASSERT( GetFmt()->GetDoc()->IsBrowseMode(),
+            "CalcBrowseWidth and not in BrowseView" );
+
+    //Die (minimale) Breite wird von Rahmen, Tabellen und Zeichenobjekten
+    //bestimmt. Die Breite wird nicht anhand ihrer aktuellen Groessen bestimmt,
+    //sondern anhand der Attribute. Es interessiert also nicht wie breit sie
+    //sind, sondern wie breit sie sein wollen.
+    //Rahmen und Zeichenobjekte innerhalb ander Objekte (Rahmen, Tabellen)
+    //Zaehlen nicht.
+    //Seitenraender und Spalten werden hier nicht beruecksichtigt.
+
+    SwFrm *pFrm = ContainsCntnt();
+    while ( pFrm && !pFrm->IsInDocBody() )
+        pFrm = ((SwCntntFrm*)pFrm)->GetNextCntntFrm();
+    if ( !pFrm )
+        return;
+
+    bBrowseWidthValid = TRUE;
+    ViewShell *pSh = GetShell();
+    nBrowseWidth = pSh
+                    ? MINLAY + 2 * pSh->GetOut()->
+                                PixelToLogic( pSh->GetBrowseBorder() ).Width()
+                    : 5000;
+    do
+    {
+        if ( pFrm->IsInTab() )
+            pFrm = pFrm->FindTabFrm();
+
+        if ( pFrm->IsTabFrm() &&
+             !((SwLayoutFrm*)pFrm)->GetFmt()->GetFrmSize().GetWidthPercent() )
+        {
+            SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFrm );
+            const SwBorderAttrs &rAttrs = *aAccess.Get();
+            const SwFmtHoriOrient &rHori = rAttrs.GetAttrSet().GetHoriOrient();
+            long nWidth = rAttrs.GetSize().Width();
+            if ( nWidth < USHRT_MAX-2000 && //-2000, weil bei Randeinstellung per
+                                            //Zuppeln das USHRT_MAX verlorengeht!
+                 HORI_FULL != rHori.GetHoriOrient() )
+            {
+                const SwHTMLTableLayout *pLayoutInfo =
+                    ((const SwTabFrm *)pFrm)->GetTable()
+                                            ->GetHTMLTableLayout();
+                if ( pLayoutInfo )
+                    nWidth = Min( nWidth, pLayoutInfo->GetBrowseWidthMin() );
+
+                switch ( rHori.GetHoriOrient() )
+                {
+                    case HORI_NONE:
+                        nWidth += rAttrs.CalcLeft( pFrm ) + rAttrs.CalcRight();
+                        break;
+                    case HORI_LEFT_AND_WIDTH:
+                        nWidth += rAttrs.CalcLeft( pFrm );
+                }
+                nBrowseWidth = Max( nBrowseWidth, nWidth );
+            }
+        }
+        else if ( pFrm->GetDrawObjs() )
+        {
+            for ( USHORT i = 0; i < pFrm->GetDrawObjs()->Count(); ++i )
+            {
+                SdrObject *pObj = (*pFrm->GetDrawObjs())[i];
+                SwFrmFmt *pFmt = ::FindFrmFmt( pObj );
+                const FASTBOOL bFly = pObj->IsWriterFlyFrame();
+                if ( bFly &&
+                     WEIT_WECH == ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->Frm().Width()||
+                     pFmt->GetFrmSize().GetWidthPercent() )
+                    continue;
+
+                long nWidth = 0;
+                switch ( pFmt->GetAnchor().GetAnchorId() )
+                {
+                    case FLY_IN_CNTNT:
+                        nWidth = bFly ? pFmt->GetFrmSize().GetWidth() :
+                                        pObj->GetBoundRect().GetWidth();
+                        break;
+                    case FLY_AT_CNTNT:
+                        {
+                        if ( bFly )
+                        {
+                            nWidth = pFmt->GetFrmSize().GetWidth();
+                            const SwFmtHoriOrient &rHori = pFmt->GetHoriOrient();
+                            switch ( rHori.GetHoriOrient() )
+                            {
+                                case HORI_NONE:
+                                    nWidth += rHori.GetPos();
+                                    break;
+                                case HORI_INSIDE:
+                                case HORI_LEFT:
+                                    if ( PRTAREA == rHori.GetRelationOrient() )
+                                        nWidth += pFrm->Prt().Left();
+                            }
+                        }
+                        else
+                            //Fuer Zeichenobjekte ist die Auswahl sehr klein,
+                            //weil sie keine Attribute haben, also durch ihre
+                            //aktuelle Groesse bestimmt werden.
+                            nWidth = pObj->GetBoundRect().Right() -
+                                     pObj->GetAnchorPos().X();
+
+//MA 31. Jan. 97: Zaehlt doch garnicht mehr, seit die Flys den Rand nicht
+//mehr beruecksichtigen.
+//                      const SwContact *pCon = (SwContact*)pObj->GetUserCall();
+//                      const SvxLRSpaceItem &rLR = pCon->GetFmt()->GetLRSpace();
+//                      nWidth += rLR.GetLeft() + rLR.GetRight();
+                        }
+                        break;
+                    default:    /* do nothing */;
+                }
+                nBrowseWidth = Max( nBrowseWidth, nWidth );
+            }
+        }
+        pFrm = pFrm->FindNextCnt();
+    } while ( pFrm );
+}
+
+/*************************************************************************
+|*
+|*  SwRootFrm::StartAllAction()
+|*
+|*  Ersterstellung      MA 08. Mar. 98
+|*  Letzte Aenderung    MA 08. Mar. 98
+|*
+|*************************************************************************/
+
+void SwRootFrm::StartAllAction()
+{
+    ViewShell *pSh = GetCurrShell();
+    if ( pSh )
+        do
+        {   if ( pSh->ISA( SwCrsrShell ) )
+                ((SwCrsrShell*)pSh)->StartAction();
+            else
+                pSh->StartAction();
+            pSh = (ViewShell*)pSh->GetNext();
+
+        } while ( pSh != GetCurrShell() );
+}
+
+void SwRootFrm::EndAllAction( BOOL bVirDev )
+{
+    ViewShell *pSh = GetCurrShell();
+    if ( pSh )
+        do
+        {
+            const BOOL bOldEndActionByVirDev = pSh->IsEndActionByVirDev();
+            pSh->SetEndActionByVirDev( bVirDev );
+            if ( pSh->ISA( SwCrsrShell ) )
+            {
+                ((SwCrsrShell*)pSh)->EndAction();
+                ((SwCrsrShell*)pSh)->CallChgLnk();
+                if ( pSh->ISA( SwFEShell ) )
+                    ((SwFEShell*)pSh)->SetChainMarker();
+            }
+            else
+                pSh->EndAction();
+            pSh->SetEndActionByVirDev( bOldEndActionByVirDev );
+            pSh = (ViewShell*)pSh->GetNext();
+
+        } while ( pSh != GetCurrShell() );
+}
+
+void SwRootFrm::UnoRemoveAllActions()
+{
+    ViewShell *pSh = GetCurrShell();
+    if ( pSh )
+        do
+        {
+
+            BOOL bCrsr = pSh->ISA( SwCrsrShell );
+            BOOL bFE = pSh->ISA( SwFEShell );
+            USHORT nRestore = 0;
+            while( pSh->ActionCount() )
+            {
+                if( bCrsr )
+                {
+                    ((SwCrsrShell*)pSh)->EndAction();
+                    ((SwCrsrShell*)pSh)->CallChgLnk();
+                    if ( bFE )
+                        ((SwFEShell*)pSh)->SetChainMarker();
+                }
+                else
+                    pSh->EndAction();
+                nRestore++;
+            }
+            pSh->SetRestoreActions(nRestore);
+            pSh->LockView(TRUE);
+            pSh = (ViewShell*)pSh->GetNext();
+
+        } while ( pSh != GetCurrShell() );
+}
+
+void SwRootFrm::UnoRestoreAllActions()
+{
+    ViewShell *pSh = GetCurrShell();
+    if ( pSh )
+        do
+        {
+            USHORT nActions = pSh->GetRestoreActions();
+            while( nActions-- )
+            {
+                if ( pSh->ISA( SwCrsrShell ) )
+                    ((SwCrsrShell*)pSh)->StartAction();
+                else
+                    pSh->StartAction();
+            }
+            pSh->SetRestoreActions(0);
+            pSh->LockView(FALSE);
+            pSh = (ViewShell*)pSh->GetNext();
+
+        } while ( pSh != GetCurrShell() );
+}
+
diff --git a/sw/source/core/layout/pagedesc.cxx b/sw/source/core/layout/pagedesc.cxx
new file mode 100644
index 000000000000..a39f4ce38355
--- /dev/null
+++ b/sw/source/core/layout/pagedesc.cxx
@@ -0,0 +1,482 @@
+/*************************************************************************
+ *
+ *  $RCSfile: pagedesc.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:22 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#define ITEMID_BOXINFO      SID_ATTR_BORDER_INNER
+#include 
+
+#ifndef _SVX_PBINITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_ULSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BOXITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BRSHITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_SHADITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _FMTCLDS_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFSIZE_HXX //autogen
+#include 
+#endif
+#ifndef _FRMATR_HXX
+#include 
+#endif
+#ifndef _PAGEFRM_HXX //autogen
+#include 
+#endif
+#ifndef _PAGEDESC_HXX
+#include 
+#endif
+#ifndef _FRMFMT_HXX
+#include 
+#endif
+#ifndef _FMTCOL_HXX
+#include    // SwTxtFmtColl
+#endif
+#ifndef _NODE_HXX //autogen
+#include 
+#endif
+#ifndef _SWTABLE_HXX //autogen
+#include 
+#endif
+#ifndef _FRMTOOL_HXX //autogen
+#include 
+#endif
+#ifndef _DOC_HXX
+#include           // fuer GetAttrPool
+#endif
+
+/*************************************************************************
+|*
+|*  SwPageDesc::SwPageDesc()
+|*
+|*  Ersterstellung      MA 25. Jan. 93
+|*  Letzte Aenderung    MA 16. Feb. 94
+|*
+|*************************************************************************/
+
+
+
+SwPageDesc::SwPageDesc( const String& rName, SwFrmFmt *pFmt, SwDoc *pDc ) :
+    SwModify( 0 ),
+    aDescName( rName ),
+    aDepend( this, 0 ),
+    nRegHeight( 0 ),
+    nRegAscent( 0 ),
+    bLandscape( FALSE ),
+    eUse( (UseOnPage)(PD_ALL | PD_HEADERSHARE | PD_FOOTERSHARE) ),
+    aMaster( pDc->GetAttrPool(), rName, pFmt ),
+    aLeft( pDc->GetAttrPool(), rName, pFmt ),
+    pFollow( this ),
+    aFtnInfo()
+{
+}
+
+
+
+SwPageDesc::SwPageDesc( const SwPageDesc &rCpy ) :
+    SwModify( 0 ),
+    aDepend( this, (SwModify*)rCpy.aDepend.GetRegisteredIn() ),
+    nRegHeight( rCpy.GetRegHeight() ),
+    nRegAscent( rCpy.GetRegAscent() ),
+    aDescName( rCpy.GetName() ),
+    bLandscape( rCpy.GetLandscape() ),
+    aNumType( rCpy.GetNumType() ),
+    eUse( rCpy.ReadUseOn() ),
+    aMaster( rCpy.GetMaster() ),
+    aLeft( rCpy.GetLeft() ),
+    pFollow( rCpy.pFollow ),
+    aFtnInfo( rCpy.GetFtnInfo() )
+{
+}
+
+
+
+SwPageDesc::~SwPageDesc()
+{
+}
+
+/*************************************************************************
+|*
+|*  SwPageDesc::Mirror()
+|*
+|*  Beschreibung        Gespiegelt werden nur die Raender.
+|*      Attribute wie Umrandung und dergleichen werden 1:1 kopiert.
+|*  Ersterstellung      MA 25. Jan. 93
+|*  Letzte Aenderung    01. Nov. 94
+|*
+|*************************************************************************/
+
+
+
+void SwPageDesc::Mirror()
+{
+    //Das Spiegeln findet nur beim RandAttribut statt, alle anderen Werte
+    //werden schlicht uebertragen.
+    SvxLRSpaceItem aLR;
+    const SvxLRSpaceItem &rLR = aMaster.GetLRSpace();
+    aLR.SetLeft(  rLR.GetRight() );
+    aLR.SetRight( rLR.GetLeft() );
+
+    SfxItemSet aSet( *aMaster.GetAttrSet().GetPool(),
+                     aMaster.GetAttrSet().GetRanges() );
+    aSet.Put( aLR );
+    aSet.Put( aMaster.GetFrmSize() );
+    aSet.Put( aMaster.GetPaperBin() );
+    aSet.Put( aMaster.GetULSpace() );
+    aSet.Put( aMaster.GetBox() );
+    aSet.Put( aMaster.GetBackground() );
+    aSet.Put( aMaster.GetShadow() );
+    aSet.Put( aMaster.GetCol() );
+    aLeft.SetAttr( aSet );
+}
+
+/*************************************************************************
+|*
+|*                SwPageDesc::GetInfo()
+|*
+|*    Beschreibung      erfragt Informationen
+|*    Ersterstellung    JP 31.03.94
+|*    Letzte Aenderung  JP 31.03.94
+|*
+*************************************************************************/
+
+
+    // erfrage vom Modify Informationen
+BOOL SwPageDesc::GetInfo( SfxPoolItem & rInfo ) const
+{
+//    if( RES_AUTOFMT_DOCNODE == rInfo.Which() )
+//    {
+        // dann weiter zum Format
+        if( !aMaster.GetInfo( rInfo ) )
+            return FALSE;       // gefunden
+        return aLeft.GetInfo( rInfo );
+//    }
+//    return TRUE;        // weiter suchen
+}
+
+/*************************************************************************
+|*
+|*                SwPageDesc::SetRegisterFmtColl()
+|*
+|*    Beschreibung      setzt die Vorlage fuer die Registerhaltigkeit
+|*    Ersterstellung    AMA 22.07.96
+|*    Letzte Aenderung  AMA 22.07.96
+|*
+*************************************************************************/
+
+
+void SwPageDesc::SetRegisterFmtColl( const SwTxtFmtColl* pFmt )
+{
+    if( pFmt != GetRegisterFmtColl() )
+    {
+        if( pFmt )
+            ((SwTxtFmtColl*)pFmt)->Add( &aDepend );
+        else
+            ((SwTxtFmtColl*)GetRegisterFmtColl())->Remove( &aDepend );
+
+        RegisterChange();
+    }
+}
+
+/*************************************************************************
+|*
+|*                SwPageDesc::GetRegisterFmtColl()
+|*
+|*    Beschreibung      holt die Vorlage fuer die Registerhaltigkeit
+|*    Ersterstellung    AMA 22.07.96
+|*    Letzte Aenderung  AMA 22.07.96
+|*
+*************************************************************************/
+
+
+const SwTxtFmtColl* SwPageDesc::GetRegisterFmtColl() const
+{
+    const SwModify* pReg = aDepend.GetRegisteredIn();
+    return (SwTxtFmtColl*)pReg;
+}
+
+/*************************************************************************
+|*
+|*                SwPageDesc::RegisterChange()
+|*
+|*    Beschreibung      benachrichtigt alle betroffenen PageFrames
+|*    Ersterstellung    AMA 22.07.96
+|*    Letzte Aenderung  AMA 22.07.96
+|*
+*************************************************************************/
+
+
+void SwPageDesc::RegisterChange()
+{
+    nRegHeight = 0;
+    {
+        SwClientIter aIter( GetMaster() );
+        for( SwClient* pLast = aIter.First(TYPE(SwFrm)); pLast;
+                pLast = aIter.Next() )
+        {
+            if( ((SwFrm*)pLast)->IsPageFrm() )
+                ((SwPageFrm*)pLast)->PrepareRegisterChg();
+        }
+    }
+    {
+        SwClientIter aIter( GetLeft() );
+        for( SwClient* pLast = aIter.First(TYPE(SwFrm)); pLast;
+                pLast = aIter.Next() )
+        {
+            if( ((SwFrm*)pLast)->IsPageFrm() )
+                ((SwPageFrm*)pLast)->PrepareRegisterChg();
+        }
+    }
+}
+
+/*************************************************************************
+|*
+|*                SwPageDesc::Modify()
+|*
+|*    Beschreibung      reagiert insbesondere auf Aenderungen
+|*                      der Vorlage fuer die Registerhaltigkeit
+|*    Ersterstellung    AMA 22.07.96
+|*    Letzte Aenderung  AMA 22.07.96
+|*
+*************************************************************************/
+
+
+void SwPageDesc::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew )
+{
+    const USHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
+    SwModify::Modify( pOld, pNew );
+
+    if( RES_ATTRSET_CHG == nWhich || RES_FMT_CHG == nWhich ||
+        ( nWhich >= RES_CHRATR_BEGIN && nWhich < RES_CHRATR_END ) ||
+         nWhich == RES_PARATR_LINESPACING )
+        RegisterChange();
+}
+
+const SwFrm* lcl_GetFrmOfNode( const SwNode& rNd )
+{
+    SwModify* pMod;
+    USHORT nFrmType;
+
+    if( rNd.IsCntntNode() )
+    {
+        pMod = &(SwCntntNode&)rNd;
+        nFrmType = FRM_CNTNT;
+    }
+    else if( rNd.IsTableNode() )
+    {
+        pMod = ((SwTableNode&)rNd).GetTable().GetFrmFmt();
+        nFrmType = FRM_TAB;
+    }
+    else
+        pMod = 0;
+
+    Point aNullPt;
+    return pMod ? ::GetFrmOfModify( *pMod, nFrmType, &aNullPt, 0, FALSE )
+                : 0;
+}
+
+const SwFrmFmt* SwPageDesc::GetPageFmtOfNode( const SwNode& rNd,
+                                              BOOL bCheckForThisPgDc ) const
+{
+    // welches PageDescFormat ist fuer diesen Node gueltig?
+    const SwFrmFmt* pRet;
+    const SwFrm* pChkFrm = ::lcl_GetFrmOfNode( rNd );
+
+    if( pChkFrm && 0 != ( pChkFrm = pChkFrm->FindPageFrm() ))
+    {
+        const SwPageDesc* pPd = bCheckForThisPgDc ? this :
+                                ((SwPageFrm*)pChkFrm)->GetPageDesc();
+        pRet = &pPd->GetMaster();
+        ASSERT( ((SwPageFrm*)pChkFrm)->GetPageDesc() == pPd,
+                "Falcher Node fuers erkennen des Seitenformats" );
+        // an welchem Format haengt diese Seite?
+        if( pRet != pChkFrm->GetRegisteredIn() )
+        {
+            pRet = &pPd->GetLeft();
+            ASSERT( pRet == pChkFrm->GetRegisteredIn(),
+                    "Falcher Node fuers erkennen des Seitenformats" );
+        }
+    }
+    else
+        pRet = &GetMaster();
+    return pRet;
+}
+
+BOOL SwPageDesc::IsFollowNextPageOfNode( const SwNode& rNd ) const
+{
+    BOOL bRet = FALSE;
+    if( GetFollow() && this != GetFollow() )
+    {
+        const SwFrm* pChkFrm = ::lcl_GetFrmOfNode( rNd );
+        if( pChkFrm && 0 != ( pChkFrm = pChkFrm->FindPageFrm() ) &&
+            pChkFrm->IsPageFrm() &&
+            ( !pChkFrm->GetNext() || GetFollow() ==
+                        ((SwPageFrm*)pChkFrm->GetNext())->GetPageDesc() ))
+            // die Seite gefunden, auf die der Follow verweist
+            bRet = TRUE;
+    }
+    return bRet;
+}
+
+/*************************************************************************
+|*
+|*  SwPageFtnInfo::SwPageFtnInfo()
+|*
+|*  Ersterstellung      MA 24. Feb. 93
+|*  Letzte Aenderung    MA 24. Feb. 93
+|*
+|*************************************************************************/
+
+
+
+SwPageFtnInfo::SwPageFtnInfo() :
+    nMaxHeight( 0 ),
+//  aPen( PEN_SOLID ),
+    nLineWidth(10),
+    aWidth( 25, 100 ),
+    eAdj( FTNADJ_LEFT ),
+    nTopDist( 57 ),         //1mm
+    nBottomDist( 57 )
+{
+//  aPen.SetWidth( 10 );
+}
+
+
+
+SwPageFtnInfo::SwPageFtnInfo( const SwPageFtnInfo &rCpy ) :
+    nMaxHeight( rCpy.GetHeight() ),
+//  aPen( rCpy.GetPen() ),
+    nLineWidth(rCpy.nLineWidth),
+    aLineColor(rCpy.aLineColor),
+    aWidth( rCpy.GetWidth() ),
+    eAdj( rCpy.GetAdj() ),
+    nTopDist( rCpy.GetTopDist() ),
+    nBottomDist( rCpy.GetBottomDist() )
+{
+}
+
+/*************************************************************************
+|*
+|*  SwPageFtnInfo::operator=
+|*
+|*  Ersterstellung      MA 24. Feb. 93
+|*  Letzte Aenderung    MA 24. Feb. 93
+|*
+|*************************************************************************/
+
+
+
+SwPageFtnInfo &SwPageFtnInfo::operator=( const SwPageFtnInfo& rCpy )
+{
+    nMaxHeight  = rCpy.GetHeight();
+//  aPen        = rCpy.GetPen();
+    nLineWidth  = rCpy.nLineWidth;
+    aLineColor  = rCpy.aLineColor;
+    aWidth      = rCpy.GetWidth();
+    eAdj        = rCpy.GetAdj();
+    nTopDist    = rCpy.GetTopDist();
+    nBottomDist = rCpy.GetBottomDist();
+    return *this;
+}
+/*************************************************************************
+|*
+|*  SwPageFtnInfo::operator==
+|*
+|*  Ersterstellung      MA 01. Mar. 93
+|*  Letzte Aenderung    MA 01. Mar. 93
+|*
+|*************************************************************************/
+
+
+
+BOOL SwPageFtnInfo::operator==( const SwPageFtnInfo& rCmp ) const
+{
+//  const Pen aTmp( rCmp.GetPen() );
+    return ( nMaxHeight == rCmp.GetHeight() &&
+//           aPen       == aTmp &&
+             nLineWidth == rCmp.nLineWidth &&
+             aLineColor == rCmp.aLineColor &&
+             aWidth     == rCmp.GetWidth() &&
+             eAdj       == rCmp.GetAdj() &&
+             nTopDist   == rCmp.GetTopDist() &&
+             nBottomDist== rCmp.GetBottomDist() );
+}
+
+
+
+
diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
new file mode 100644
index 000000000000..54a622fbb868
--- /dev/null
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -0,0 +1,3904 @@
+/*************************************************************************
+ *
+ *  $RCSfile: paintfrm.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:22 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#define ITEMID_BOXINFO      SID_ATTR_BORDER_INNER
+#include 
+
+#ifndef _SOUND_HXX //autogen
+#include 
+#endif
+#ifndef _POLY_HXX //autogen
+#include 
+#endif
+#define _SVSTDARR_LONGS
+#include 
+
+#ifndef _XOUTBMP_HXX //autogen
+#include 
+#endif
+#ifndef _SFX_PROGRESS_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BRSHITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_OPAQITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_PRNTITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BOXITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_SHADITEM_HXX //autogen
+#include 
+#endif
+#ifndef _GRAPH_HXX //autogen
+#include 
+#endif
+#ifndef _SVDPAGV_HXX //autogen
+#include 
+#endif
+
+
+#ifndef _FMTSRND_HXX //autogen
+#include 
+#endif
+#ifndef _FMTCLDS_HXX //autogen
+#include 
+#endif
+#ifndef _SHL_HXX
+#include 
+#endif
+
+#ifndef _SWMODULE_HXX
+#include 
+#endif
+#ifndef _ROOTFRM_HXX
+#include 
+#endif
+#ifndef _PAGEFRM_HXX
+#include 
+#endif
+#ifndef _CNTFRM_HXX
+#include 
+#endif
+#ifndef _VIEWSH_HXX
+#include 
+#endif
+#ifndef _SECTION_HXX
+#include 
+#endif
+#ifndef _SECTFRM_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _VIEWIMP_HXX
+#include 
+#endif
+#ifndef _SWATRSET_HXX
+#include 
+#endif
+#ifndef _DFLYOBJ_HXX
+#include 
+#endif
+#ifndef _FLYFRM_HXX
+#include 
+#endif
+#ifndef _FRMTOOL_HXX
+#include 
+#endif
+#ifndef _VIEWOPT_HXX
+#include 
+#endif
+#ifndef _DVIEW_HXX
+#include 
+#endif
+#ifndef _DCONTACT_HXX
+#include 
+#endif
+#ifndef _TXTFRM_HXX
+#include 
+#endif
+#ifndef _FTNFRM_HXX
+#include 
+#endif
+#ifndef _TABFRM_HXX
+#include 
+#endif
+#ifndef _NOTXTFRM_HXX
+#include 
+#endif
+#ifndef _FRMSH_HXX
+#include 
+#endif
+#ifndef _SWREGION_HXX
+#include 
+#endif
+#ifndef _LAYACT_HXX
+#include 
+#endif
+#ifndef _PAGEDESC_HXX
+#include 
+#endif
+#ifndef _PTQUEUE_HXX
+#include 
+#endif
+#ifndef _NOTEURL_HXX
+#include 
+#endif
+#ifndef _VIRTOUTP_HXX
+#include 
+#endif
+#ifndef _LINEINFO_HXX
+#include 
+#endif
+#ifndef _DBG_LAY_HXX
+#include 
+#endif
+
+#define GETOBJSHELL()       ((SfxObjectShell*)rSh.GetDoc()->GetDocShell())
+
+//Tabellenhilfslinien an?
+#define IS_SUBS_TABLE \
+    (pGlobalShell->GetViewOptions()->IsTable() && \
+     pGlobalShell->GetViewOptions()->IsSubsTable())
+//sonstige Hilfslinien an?
+#define IS_SUBS pGlobalShell->GetViewOptions()->IsSubsLines()
+//Hilfslinien fuer Bereiche
+#define IS_SUBS_SECTION pGlobalShell->GetViewOptions()->IsSectionBounds()
+
+#define SW_MAXBORDERCACHE 20
+
+//Klassendeklarationen. Hier weil sie eben nur in diesem File benoetigt
+//werden.
+
+#define SUBCOL_STANDARD 0x01    //normale Hilfslinien
+#define SUBCOL_BREAK    0x02    //Hilfslinien bei Umbruechen
+#define SUBCOL_GRAY     0x04    //normale Hilfslinien bei LIGHTGRAY-Hintergrund
+
+
+//----- Klassen zum Sammeln von Umrandungen und Hilfslinien ---
+class SwLineRect : public SwRect
+{
+    const Color    *pColor;
+    const SwTabFrm *pTab;
+          BYTE      nSubColor;  //Hilfslinien einfaerben
+          BOOL      bPainted;   //schon gepaintet?
+          BYTE      nLock;      //Um die Linien zum Hell-Layer abzugrenzen.
+public:
+    SwLineRect( const SwRect &rRect, const Color *pCol,
+                const SwTabFrm *pT, const BYTE nSCol = SUBCOL_STANDARD );
+
+    const Color         *GetColor() const { return pColor;}
+    const SwTabFrm      *GetTab()   const { return pTab;  }
+    void  SetPainted()                    { bPainted = TRUE; }
+    void  Lock( BOOL bLock )              { if ( bLock )
+                                                ++nLock;
+                                            else if ( nLock )
+                                                --nLock;
+                                          }
+    BOOL  IsPainted()               const { return bPainted; }
+    BOOL  IsLocked()                const { return nLock != 0;  }
+    BYTE  GetSubColor()             const { return nSubColor;}
+
+    BOOL MakeUnion( const SwRect &rRect );
+};
+
+SV_DECL_VARARR( SwLRects, SwLineRect, 100, 100 );
+
+class SwLineRects : public SwLRects
+{
+    USHORT nLastCount;  //unuetze Durchlaeufe im PaintLines verhindern.
+public:
+    SwLineRects() : nLastCount( 0 ) {}
+    void AddLineRect( const SwRect& rRect,  const Color *pColor,
+                      const SwTabFrm *pTab, const BYTE nSCol = SUBCOL_STANDARD );
+    void ConnectEdges( OutputDevice *pOut );
+    void PaintLines  ( OutputDevice *pOut );
+    void LockLines( BOOL bLock );
+
+    BYTE Free() const { return nFree; }
+};
+
+class SwSubsRects : public SwLineRects
+{
+    void RemoveSuperfluousSubsidiaryLines( const SwLineRects &rRects ); //;-)
+public:
+    void PaintSubsidiary( OutputDevice *pOut, const SwLineRects *pRects );
+
+    inline void Ins( const SwRect &rRect, const BYTE nSCol );
+};
+
+//----------------- End Klassen Umrandungen ----------------------
+
+static ViewShell *pGlobalShell = 0;
+
+//Fuer PaintBackground, eigentlich lokal, aber fuer SwSavePaintStatics jetzt global
+static FASTBOOL bPageOnly = FALSE;
+
+//Wenn durchsichtige FlyInCnts im PaintBackground gepainted werden so soll der
+//Hintergrund nicht mehr retouchiert werden.
+//static FASTBOOL bLockFlyBackground = FALSE;
+
+//Wenn vom Fly ein Metafile abgezogen wird, so soll nur der FlyInhalt und vor
+//nur hintergrund vom FlyInhalt gepaintet werden.
+static FASTBOOL bFlyMetafile = FALSE;
+static OutputDevice *pFlyMetafileOut = 0;
+
+//Die Retouche fuer Durchsichtige Flys wird vom Hintergrund der Flys
+//erledigt. Dabei darf der Fly selbst natuerlich nicht ausgespart werden.
+//siehe PaintBackground und lcl_SubtractFlys()
+static SwFlyFrm *pRetoucheFly  = 0;
+static SwFlyFrm *pRetoucheFly2 = 0;
+
+//Groesse eines Pixel und die Haelfte davon. Wird jeweils bei Eintritt in
+//SwRootFrm::Paint neu gesetzt.
+static long nPixelSzW = 0, nPixelSzH = 0;
+static long nHalfPixelSzW = 0, nHalfPixelSzH = 0;
+static long nMinDistPixelW = 0, nMinDistPixelH = 0;
+static FASTBOOL  bPixelHeightOdd;
+static FASTBOOL  bPixelWidthOdd;
+
+//Aktueller Zoomfaktor
+static double aScaleX = 1.0;
+static double aScaleY = 1.0;
+static double aMinDistScale = 0.73;
+static double aEdgeScale = 0.5;
+
+//In pLines werden Umrandungen waehrend des Paint gesammelt und soweit
+//moeglich zusammengefasst.
+//In pSubsLines werden Hilfslinien gesammelt und zusammengefasst. Diese
+//werden vor der Ausgabe mit pLines abgeglichen, so dass moeglichst keine
+//Umrandungen von den Hilfslinen verdeckt werden.
+//bTablines ist waerend des Paints einer Tabelle TRUE.
+static SwLineRects *pLines = 0;
+static SwSubsRects *pSubsLines = 0;
+
+static SfxProgress *pProgress = 0;
+
+//Nicht mehr als ein Beep pro Paint, wird auch im Textbereich benutzt!
+FASTBOOL bOneBeepOnly = TRUE;
+
+class SwBackgroundCache;
+static SwBackgroundCache *pBackgroundCache = 0;
+
+static SwFlyFrm *pFlyOnlyDraw = 0;
+
+//Damit die Flys auch fuer den Hack richtig gepaintet werden koennen.
+static FASTBOOL bTableHack = FALSE;
+
+//Um das teure Ermitteln der RetoucheColor zu optimieren
+Color aGlobalRetoucheColor;
+
+//Statics fuer Umrandungsalignment setzen.
+void SwCalcPixStatics( OutputDevice *pOut )
+{
+    Size aSz( pOut->PixelToLogic( Size( 1,1 )) );
+    nPixelSzW = aSz.Width(), nPixelSzH = aSz.Height();
+    nHalfPixelSzW = nPixelSzW / 2 + 1;
+    nHalfPixelSzH = nPixelSzH / 2 + 1;
+    nMinDistPixelW = nPixelSzW * 2 + 1;
+    nMinDistPixelH = nPixelSzH * 2 + 1;
+    bPixelHeightOdd = nPixelSzH % 2 ? TRUE : FALSE;
+    bPixelWidthOdd  = nPixelSzW % 2 ? TRUE : FALSE;
+
+    const MapMode &rMap = pOut->GetMapMode();
+    aScaleX = rMap.GetScaleX();
+    aScaleY = rMap.GetScaleY();
+}
+
+//Zum Sichern der statics, damit das Paint (quasi) reentrant wird.
+class SwSavePaintStatics
+{
+//  FASTBOOL            bSLockFlyBackground,
+    FASTBOOL            bSFlyMetafile,
+                        bSPixelHeightOdd,
+                        bSPixelWidthOdd,
+                        bSOneBeepOnly,
+                        bSPageOnly;
+    ViewShell          *pSGlobalShell;
+    OutputDevice       *pSFlyMetafileOut;
+    SwFlyFrm           *pSRetoucheFly,
+                       *pSRetoucheFly2,
+                       *pSFlyOnlyDraw;
+    SwLineRects        *pSLines;
+    SwSubsRects        *pSSubsLines;
+    SfxProgress        *pSProgress;
+    long                nSPixelSzW,
+                        nSPixelSzH,
+                        nSHalfPixelSzW,
+                        nSHalfPixelSzH,
+                        nSMinDistPixelW,
+                        nSMinDistPixelH;
+    Color               aSGlobalRetoucheColor;
+    double              aSScaleX,
+                        aSScaleY;
+public:
+    SwSavePaintStatics();
+    ~SwSavePaintStatics();
+};
+
+SwSavePaintStatics::SwSavePaintStatics() :
+//  bSLockFlyBackground ( bLockFlyBackground),
+    bSFlyMetafile       ( bFlyMetafile      ),
+    bSPixelHeightOdd    ( bPixelHeightOdd   ),
+    bSPixelWidthOdd     ( bPixelWidthOdd    ),
+    bSOneBeepOnly       ( bOneBeepOnly      ),
+    bSPageOnly          ( bPageOnly         ),
+    pSGlobalShell       ( pGlobalShell      ),
+    pSFlyMetafileOut    ( pFlyMetafileOut   ),
+    pSRetoucheFly       ( pRetoucheFly      ),
+    pSRetoucheFly2      ( pRetoucheFly2     ),
+    pSFlyOnlyDraw       ( pFlyOnlyDraw      ),
+    pSLines             ( pLines            ),
+    pSSubsLines         ( pSubsLines        ),
+    pSProgress          ( pProgress         ),
+    nSPixelSzW          ( nPixelSzW         ),
+    nSPixelSzH          ( nPixelSzH         ),
+    nSHalfPixelSzW      ( nHalfPixelSzW     ),
+    nSHalfPixelSzH      ( nHalfPixelSzH     ),
+    nSMinDistPixelW     ( nMinDistPixelW    ),
+    nSMinDistPixelH     ( nMinDistPixelH    ),
+    aSGlobalRetoucheColor( aGlobalRetoucheColor ),
+    aSScaleX            ( aScaleX           ),
+    aSScaleY            ( aScaleY           )
+{
+    bPageOnly = /*bLockFlyBackground = */bFlyMetafile = FALSE;
+    pFlyMetafileOut = 0;
+    pRetoucheFly  = 0;
+    pRetoucheFly2 = 0;
+    nPixelSzW = nPixelSzH =
+    nHalfPixelSzW = nHalfPixelSzH =
+    nMinDistPixelW = nMinDistPixelH = 0;
+    aScaleX = aScaleY = 1.0;
+    aMinDistScale = 0.73;
+    aEdgeScale = 0.5;
+    pLines = 0;
+    pSubsLines = 0;
+    pProgress = 0;
+    bOneBeepOnly = TRUE;
+}
+
+SwSavePaintStatics::~SwSavePaintStatics()
+{
+//  bLockFlyBackground = bSLockFlyBackground;
+    pGlobalShell       = pSGlobalShell;
+    bFlyMetafile       = bSFlyMetafile;
+    bPixelHeightOdd    = bSPixelHeightOdd;
+    bPixelWidthOdd     = bSPixelWidthOdd;
+    bOneBeepOnly       = bSOneBeepOnly;
+    bPageOnly          = bSPageOnly;
+    pFlyMetafileOut    = pSFlyMetafileOut;
+    pRetoucheFly       = pSRetoucheFly;
+    pRetoucheFly2      = pSRetoucheFly2;
+    pFlyOnlyDraw       = pSFlyOnlyDraw;
+    pLines             = pSLines;
+    pSubsLines         = pSSubsLines;
+    pProgress          = pSProgress;
+    nPixelSzW          = nSPixelSzW;
+    nPixelSzH          = nSPixelSzH;
+    nHalfPixelSzW      = nSHalfPixelSzW;
+    nHalfPixelSzH      = nSHalfPixelSzH;
+    nMinDistPixelW     = nSMinDistPixelW;
+    nMinDistPixelH     = nSMinDistPixelH;
+    aGlobalRetoucheColor = aSGlobalRetoucheColor;
+    aScaleX            = aSScaleX;
+    aScaleY            = aSScaleY;
+}
+
+//----------------- Implementierungen fuer Tabellenumrandung --------------
+
+SV_IMPL_VARARR( SwLRects, SwLineRect );
+
+SwLineRect::SwLineRect( const SwRect &rRect, const Color *pCol,
+                        const SwTabFrm *pT, const BYTE nSCol ) :
+    SwRect( rRect ),
+    pColor( pCol ),
+    pTab( pT ),
+    bPainted( FALSE ),
+    nSubColor( nSCol ),
+    nLock( 0 )
+{
+}
+
+BOOL SwLineRect::MakeUnion( const SwRect &rRect )
+{
+    //Es wurde bereits ausserhalb geprueft, ob die Rechtecke die gleiche
+    //Ausrichtung (horizontal bzw. vertikal), Farbe usw. besitzen.
+    if ( Height() > Width() ) //Vertikale Linie
+    {
+        if ( Left()  == rRect.Left() && Width() == rRect.Width() )
+        {
+            //Zusammenfassen wenn kein Luecke zwischen den Linien ist.
+            const long nAdd = nPixelSzW + nHalfPixelSzW;
+            if ( Bottom() + nAdd >= rRect.Top() &&
+                 Top()    - nAdd <= rRect.Bottom()  )
+            {
+                Bottom( Max( Bottom(), rRect.Bottom() ) );
+                Top   ( Min( Top(),    rRect.Top()    ) );
+                return TRUE;
+            }
+        }
+    }
+    else
+    {
+        if ( Top()  == rRect.Top() && Height() == rRect.Height() )
+        {
+            //Zusammenfassen wenn kein Luecke zwischen den Linien ist.
+            const long nAdd = nPixelSzW + nHalfPixelSzW;
+            if ( Right() + nAdd >= rRect.Left() &&
+                 Left()  + nAdd <= rRect.Right() )
+            {
+                Right( Max( Right(), rRect.Right() ) );
+                Left ( Min( Left(),  rRect.Left()  ) );
+                return TRUE;
+            }
+        }
+    }
+    return FALSE;
+}
+
+void SwLineRects::AddLineRect( const SwRect &rRect, const Color *pCol,
+                               const SwTabFrm *pTab, const BYTE nSCol )
+{
+    //Rueckwaerts durch, weil Linien die zusammengefasst werden koennen i.d.R.
+    //im gleichen Kontext gepaintet werden.
+    for ( USHORT i = Count(); i ; )
+    {
+        SwLineRect &rLRect = operator[](--i);
+        //Pruefen von Ausrichtung, Farbe, Tabelle.
+        if ( rLRect.GetTab() == pTab &&
+             !rLRect.IsPainted() && rLRect.GetSubColor() == nSCol &&
+             (rLRect.Height() > rLRect.Width()) == (rRect.Height() > rRect.Width()) &&
+             ((!rLRect.GetColor() && !pCol) ||
+              (rLRect.GetColor() && pCol && *rLRect.GetColor() == *pCol)) )
+        {
+            if ( rLRect.MakeUnion( rRect ) )
+                return;
+        }
+    }
+    Insert( SwLineRect( rRect, pCol, pTab, nSCol ), Count() );
+}
+
+void SwLineRects::ConnectEdges( OutputDevice *pOut )
+{
+    if ( pOut->GetOutDevType() != OUTDEV_PRINTER )
+    {
+        //Fuer einen zu kleinen Zoom arbeite ich nicht.
+        if ( aScaleX < aEdgeScale || aScaleY < aEdgeScale )
+            return;
+    }
+
+    static const long nAdd = 20;
+
+    SvPtrarr   aCheck( 64, 64 );
+
+    for ( int i = 0; i < (int)Count(); ++i )
+    {
+        SwLineRect &rL1 = operator[](USHORT(i));
+        if ( !rL1.GetTab() || rL1.IsPainted() || rL1.IsLocked() )
+            continue;
+
+        aCheck.Remove( 0, aCheck.Count() );
+
+        const FASTBOOL bVert = rL1.Height() > rL1.Width();
+        long nL1a, nL1b, nL1c, nL1d;
+
+        if ( bVert )
+        {   nL1a = rL1.Top();   nL1b = rL1.Left();
+            nL1c = rL1.Right(); nL1d = rL1.Bottom();
+        }
+        else
+        {   nL1a = rL1.Left();   nL1b = rL1.Top();
+            nL1c = rL1.Bottom(); nL1d = rL1.Right();
+        }
+
+        //Alle moeglicherweise mit i1 zu verbindenden Linien einsammeln.
+        for ( USHORT i2 = 0; i2 < Count(); ++i2 )
+        {
+            SwLineRect &rL2 = operator[](i2);
+            if ( rL2.GetTab() != rL1.GetTab() ||
+                 rL2.IsPainted()              ||
+                 rL2.IsLocked()               ||
+                 bVert == rL2.Height() > rL2.Width() )
+                continue;
+
+            long nL2a, nL2b, nL2c, nL2d;
+            if ( bVert )
+            {   nL2a = rL2.Top();   nL2b = rL2.Left();
+                nL2c = rL2.Right(); nL2d = rL2.Bottom();
+            }
+            else
+            {   nL2a = rL2.Left();   nL2b = rL2.Top();
+                nL2c = rL2.Bottom(); nL2d = rL2.Right();
+            }
+
+            if ( (nL1a - nAdd < nL2d && nL1d + nAdd > nL2a) &&
+                  ((nL1b >  nL2b && nL1c        < nL2c) ||
+                   (nL1c >= nL2c && nL1b - nAdd < nL2c) ||
+                   (nL1b <= nL2b && nL1c + nAdd > nL2b)) )
+            {
+                SwLineRect *pMSC = &rL2;
+                aCheck.Insert( (void*&)pMSC, aCheck.Count() );
+            }
+        }
+        if ( aCheck.Count() < 2 )
+            continue;
+
+        FASTBOOL bRemove = FALSE;
+
+        //Fuer jede Linie jede alle folgenden checken.
+        for ( USHORT k = 0; !bRemove && k < aCheck.Count(); ++k )
+        {
+            SwLineRect &rR1 = (SwLineRect&)*(SwLineRect*)aCheck[k];
+
+            for ( USHORT k2 = k+1; !bRemove && k2 < aCheck.Count(); ++k2 )
+            {
+                SwLineRect &rR2 = (SwLineRect&)*(SwLineRect*)aCheck[k2];
+                if ( bVert )
+                {
+                    SwLineRect *pLA = 0, *pLB;
+                    if ( rR1.Top() < rR2.Top() )
+                    {
+                        pLA = &rR1; pLB = &rR2;
+                    }
+                    else if ( rR1.Top() > rR2.Top() )
+                    {
+                        pLA = &rR2; pLB = &rR1;
+                    }
+                    //beschreiben k1 und k2 eine Doppellinie?
+                    if ( pLA && pLA->Bottom() + 60 > pLB->Top() )
+                    {
+                        if ( rL1.Top() < pLA->Top() )
+                        {
+                            if ( rL1.Bottom() == pLA->Bottom() )
+                                continue;   //kleiner Irrtum (woher?)
+
+                            SwRect aIns( rL1 );
+                            aIns.Bottom( pLA->Bottom() );
+                            if ( !rL1.IsInside( aIns ) )
+                                continue;
+                            const USHORT nFree = Free();
+                            Insert( SwLineRect( aIns, rL1.GetColor(),
+                                        rL1.GetTab() ), Count() );
+                            if ( !nFree )
+                            {
+                                --i;
+                                k = aCheck.Count();
+                                break;
+                            }
+                        }
+
+                        if ( rL1.Bottom() > pLB->Bottom() )
+                            rL1.Top( pLB->Top() );  //i1 nach oben verlaengern
+                        else
+                            bRemove = TRUE;         //abbrechen, i1 entfernen
+                    }
+                }
+                else
+                {
+                    SwLineRect *pLA = 0, *pLB;
+                    if ( rR1.Left() < rR2.Left() )
+                    {
+                        pLA = &rR1; pLB = &rR2;
+                    }
+                    else if ( rR1.Left() > rR2.Left() )
+                    {
+                        pLA = &rR2; pLB = &rR1;
+                    }
+                    //Liegt eine 'doppellinie' vor?
+                    if ( pLA && pLA->Right() + 60 > pLB->Left() )
+                    {
+                        if ( rL1.Left() < pLA->Left() )
+                        {
+                            if ( rL1.Right() == pLA->Right() )
+                                continue;   //kleiner irrtum
+
+                            SwRect aIns( rL1 );
+                            aIns.Right( pLA->Right() );
+                            if ( !rL1.IsInside( aIns ) )
+                                continue;
+                            const USHORT nFree = Free();
+                            Insert( SwLineRect( aIns, rL1.GetColor(),
+                                        rL1.GetTab() ), Count() );
+                            if ( !nFree )
+                            {
+                                --i;
+                                k = aCheck.Count();
+                                break;
+                            }
+                        }
+                        if ( rL1.Right() > pLB->Right() )
+                            rL1.Left( pLB->Left() );
+                        else
+                            bRemove = TRUE;
+                    }
+                }
+            }
+        }
+        if ( bRemove )
+        {
+            Remove( i, 1 );
+            --i;            //keinen auslassen!
+        }
+    }
+}
+
+inline void SwSubsRects::Ins( const SwRect &rRect, const BYTE nSCol )
+{
+    //Linien die kuerzer als die breiteste Linienbreite sind werden
+    //nicht aufgenommen.
+    if ( rRect.Height() > DEF_LINE_WIDTH_4 || rRect.Width() > DEF_LINE_WIDTH_4 )
+        Insert( SwLineRect( rRect, 0, 0, nSCol ), Count());
+}
+
+void SwSubsRects::RemoveSuperfluousSubsidiaryLines( const SwLineRects &rRects )
+{
+    //Alle Hilfslinien, die sich mit irgendwelchen Umrandungen decken werden
+    //entfernt bzw. zerstueckelt..
+    for ( USHORT i = 0; i < Count(); ++i )
+    {
+        SwLineRect &rSubs = operator[](i);
+
+        if ( rSubs.IsPainted() )
+            continue;
+
+        const FASTBOOL bVert = rSubs.Height() > rSubs.Width();
+        SwRect aSubs( rSubs );
+        if ( bVert )
+        {
+            aSubs.Left  ( aSubs.Left()   - (nPixelSzW+nHalfPixelSzW) );
+            aSubs.Right ( aSubs.Right()  + (nPixelSzW+nHalfPixelSzW) );
+        }
+        else
+        {
+            aSubs.Top   ( aSubs.Top()    - (nPixelSzH+nHalfPixelSzH) );
+            aSubs.Bottom( aSubs.Bottom() + (nPixelSzH+nHalfPixelSzH) );
+        }
+        for ( USHORT k = 0; k < rRects.Count(); ++k )
+        {
+            SwLineRect &rLine = rRects[k];
+
+            if ( !bVert == rLine.Height() > rLine.Width() ) //gleiche Ausrichtung?
+                continue;
+
+            if ( aSubs.IsOver( rLine ) )
+            {
+                if ( bVert ) //Vertikal?
+                {
+                    if ( aSubs.Left()  <= rLine.Right() &&
+                         aSubs.Right() >= rLine.Left() )
+                    {
+                        long nTmp = rLine.Top()-(nPixelSzH+1);
+                        if ( rSubs.Top() < nTmp )
+                        {
+                            SwRect aRect( rSubs );
+                            aRect.Bottom( nTmp );
+                            Ins( aRect, rSubs.GetSubColor() );
+                        }
+                        nTmp = rLine.Bottom()+nPixelSzH+1;
+                        if ( rSubs.Bottom() > nTmp )
+                        {
+                            SwRect aRect( rSubs );
+                            aRect.Top( nTmp );
+                            Ins( aRect, rSubs.GetSubColor() );
+                        }
+                        Remove( i, 1 );
+                        --i;
+                        break;
+                    }
+                }
+                else                                    //Horizontal
+                {
+                    if ( aSubs.Top()    <= rLine.Bottom() &&
+                         aSubs.Bottom() >= rLine.Top() )
+                    {
+                        long nTmp = rLine.Left()-(nPixelSzW+1);
+                        if ( rSubs.Left() < nTmp )
+                        {
+                            SwRect aRect( rSubs );
+                            aRect.Right( nTmp );
+                            Ins( aRect, rSubs.GetSubColor() );
+                        }
+                        nTmp = rLine.Right()+nPixelSzW+1;
+                        if ( rSubs.Right() > nTmp )
+                        {
+                            SwRect aRect( rSubs );
+                            aRect.Left( nTmp );
+                            Ins( aRect, rSubs.GetSubColor() );
+                        }
+                        Remove( i, 1 );
+                        --i;
+                        break;
+                    }
+                }
+            }
+        }
+    }
+}
+
+void SwLineRects::LockLines( BOOL bLock )
+{
+    for ( USHORT i = 0; i < Count(); ++i )
+        operator[](i).Lock( bLock );
+}
+
+void SwLineRects::PaintLines( OutputDevice *pOut )
+{
+    //Painten der Umrandungen. Leider muessen wir zweimal durch.
+    //Einmal fuer die innenliegenden und einmal fuer die Aussenkanten
+    //der Tabellen.
+    if ( Count() != nLastCount )
+    {
+        pOut->Push( PUSH_FILLCOLOR );
+
+        ConnectEdges( pOut );
+        const Color *pLast = 0;
+
+        FASTBOOL bPaint2nd = FALSE;
+        USHORT nMinCount = Count();
+        for ( USHORT i = 0; i < Count(); ++i )
+        {
+            SwLineRect &rLRect = operator[](i);
+
+            if ( rLRect.IsPainted() )
+                continue;
+
+            if ( rLRect.IsLocked() )
+            {
+                nMinCount = Min( nMinCount, i );
+                continue;
+            }
+
+            //Jetzt malen oder erst in der zweiten Runde?
+            FASTBOOL bPaint = TRUE;
+            if ( rLRect.GetTab() )
+            {
+                if ( rLRect.Height() > rLRect.Width() )
+                {
+                    //Senkrechte Kante, ueberlappt sie mit der TabellenKante?
+                    SwTwips nLLeft  = rLRect.Left()  - 30,
+                            nLRight = rLRect.Right() + 30,
+                            nTLeft  = rLRect.GetTab()->Frm().Left() + rLRect.GetTab()->Prt().Left(),
+                            nTRight = rLRect.GetTab()->Frm().Left() + rLRect.GetTab()->Prt().Right();
+                    if ( (nTLeft >= nLLeft && nTLeft <= nLRight) ||
+                         (nTRight>= nLLeft && nTRight<= nLRight) )
+                        bPaint = FALSE;
+                }
+                else
+                {   //Waagerechte Kante, ueberlappt sie mit der Tabellenkante?
+                    SwTwips nLTop    = rLRect.Top()    - 30,
+                            nLBottom = rLRect.Bottom() + 30,
+                            nTTop    = rLRect.GetTab()->Frm().Top()  + rLRect.GetTab()->Prt().Top(),
+                            nTBottom = rLRect.GetTab()->Frm().Top()  + rLRect.GetTab()->Prt().Bottom();
+                    if ( (nTTop    >= nLTop && nTTop      <= nLBottom) ||
+                         (nTBottom >= nLTop && nTBottom <= nLBottom) )
+                        bPaint = FALSE;
+                }
+            }
+            if ( bPaint )
+            {
+                if ( !pLast || *pLast != *rLRect.GetColor() )
+                {
+                    pLast = rLRect.GetColor();
+                    pOut->SetFillColor( *pLast );
+                }
+                pOut->DrawRect( rLRect.SVRect() );
+                rLRect.SetPainted();
+            }
+            else
+                bPaint2nd = TRUE;
+        }
+        if ( bPaint2nd )
+            for ( i = 0; i < Count(); ++i )
+            {
+                SwLineRect &rLRect = operator[](i);
+                if ( rLRect.IsPainted() )
+                    continue;
+
+                if ( rLRect.IsLocked() )
+                {
+                    nMinCount = Min( nMinCount, i );
+                    continue;
+                }
+
+                if ( !pLast || *pLast != *rLRect.GetColor() )
+                {
+                    pLast = rLRect.GetColor();
+                    pOut->SetFillColor( *pLast );
+                }
+                pOut->DrawRect( rLRect.SVRect() );
+                rLRect.SetPainted();
+            }
+        nLastCount = nMinCount;
+        pOut->Pop();
+    }
+}
+
+void SwSubsRects::PaintSubsidiary( OutputDevice *pOut,
+                                   const SwLineRects *pRects )
+{
+    if ( Count() )
+    {
+        //Alle Hilfslinien, die sich fast decken entfernen (Tabellen)
+        for ( USHORT i = 0; i < Count(); ++i )
+        {
+            SwLineRect &rLi = operator[](i);
+            const FASTBOOL bVert = rLi.Height() > rLi.Width();
+
+            for ( USHORT k = i+1; k < Count(); ++k )
+            {
+                SwLineRect &rLk = operator[](k);
+                if ( rLi.SSize() == rLk.SSize() )
+                {
+                    if ( bVert == rLk.Height() > rLk.Width() )
+                    {
+                        if ( bVert )
+                        {
+                            long nLi = rLi.Right();
+                            long nLk = rLk.Right();
+                            if ( rLi.Top() == rLk.Top() &&
+                                 ((nLi < rLk.Left() && nLi+21 > rLk.Left()) ||
+                                  (nLk < rLi.Left() && nLk+21 > rLi.Left())))
+                            {
+                                Remove( k, 1 );
+                                //Nicht mit der inneren Schleife weiter, weil
+                                //das Array schrumpfen koennte!
+                                --i; k = Count();
+                            }
+                        }
+                        else
+                        {
+                            long nLi = rLi.Bottom();
+                            long nLk = rLk.Bottom();
+                            if ( rLi.Left() == rLk.Left() &&
+                                 ((nLi < rLk.Top() && nLi+21 > rLk.Top()) ||
+                                  (nLk < rLi.Top() && nLk+21 > rLi.Top())))
+                            {
+                                Remove( k, 1 );
+                                --i; k = Count();
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+
+        if ( pRects && pRects->Count() )
+            RemoveSuperfluousSubsidiaryLines( *pRects );
+
+        if ( Count() )
+        {
+            pOut->Push( PUSH_FILLCOLOR );
+
+            const Color aStandard( COL_LIGHTGRAY );
+            const Color aGray( COL_GRAY );
+            const Color aBreak(COL_BLUE );
+
+            for ( USHORT i = 0; i < Count(); ++i )
+            {
+                SwLineRect &rLRect = operator[](i);
+                if ( !rLRect.IsPainted() )
+                {
+                    const Color *pCol;
+                    switch ( rLRect.GetSubColor() )
+                    {
+                        case SUBCOL_STANDARD: pCol = &aStandard; break;
+                        case SUBCOL_BREAK:    pCol = &aBreak;    break;
+                        case SUBCOL_GRAY:     pCol = &aGray;     break;
+                    }
+                    if ( pOut->GetFillColor() != *pCol )
+                        pOut->SetFillColor( *pCol );
+                    pOut->DrawRect( rLRect.SVRect() );
+                    rLRect.SetPainted();
+                }
+            }
+            pOut->Pop();
+        }
+    }
+}
+
+//-------------------------------------------------------------------------
+//Diverse Functions die in diesem File so verwendet werden.
+
+void MA_FASTCALL SizeBorderRect( SwRect &rRect )
+{
+    //Das Rechteck um einen Pixel ausdehnen, damit die aligned'en Umrandungen
+    //korrekt gemalt werden.
+    if ( pGlobalShell->GetOut()->GetOutDevType() != OUTDEV_PRINTER )
+    {
+        rRect.Pos().Y() = Max( 0L, rRect.Top() - nPixelSzH );
+        rRect.Pos().X() = Max( 0L, rRect.Left()- nPixelSzW );
+        rRect.SSize().Width() += nPixelSzW * 2;
+        rRect.SSize().Height()+= nPixelSzH* 2;
+    }
+}
+
+void MA_FASTCALL InvertSizeBorderRect( SwRect &rRect, ViewShell *pSh )
+{
+    if ( pSh->GetOut()->GetOutDevType() != OUTDEV_PRINTER )
+    {
+        rRect.Pos().Y() = rRect.Top() + nPixelSzH;
+        rRect.Pos().X() = rRect.Left()+ nPixelSzW;
+        rRect.SSize().Width() -= nPixelSzW * 2;
+        rRect.SSize().Height()-= nPixelSzH* 2;
+    }
+}
+
+void MA_FASTCALL SwAlignRect( SwRect &rRect, ViewShell *pSh )
+{
+    const OutputDevice *pOut = bFlyMetafile ?
+                        pFlyMetafileOut : pSh->GetOut();
+    Rectangle aTmp( rRect.SVRect() );
+    //Bei ungeraden Pixelwerten korrigieren.
+    if ( bPixelHeightOdd )
+    {
+        aTmp.Top()    += 1;
+        aTmp.Bottom() -= 1;
+    }
+    if ( bPixelWidthOdd )
+    {
+        aTmp.Left()  += 1;
+        aTmp.Right() -= 1;
+    }
+    aTmp = pOut->PixelToLogic( pOut->LogicToPixel( aTmp ) );
+
+    SwRect aRect( aTmp );
+
+    if ( rRect.Top() > aRect.Top() )
+        rRect.Top( aRect.Top() + nHalfPixelSzH );
+    else
+        rRect.Top( aRect.Top() );
+
+    if ( rRect.Bottom() < aRect.Bottom() )
+        rRect.Bottom( aRect.Bottom() - nHalfPixelSzH );
+    else
+        rRect.Bottom( aRect.Bottom() );
+
+    if ( rRect.Left() > aRect.Left() )
+        rRect.Left( aRect.Left() + nHalfPixelSzW );
+    else
+        rRect.Left( aRect.Left() );
+
+    if ( rRect.Right() < aRect.Right() )
+        rRect.Right( aRect.Right() - nHalfPixelSzW );
+    else
+        rRect.Right( aRect.Right() );
+}
+
+long MA_FASTCALL lcl_AlignWidth( const long nWidth )
+{
+    if ( nWidth )
+    {
+        const long nW = nWidth % nPixelSzW;
+
+        if ( !nW || nW > nHalfPixelSzW )
+            return Max(1L, nWidth - nHalfPixelSzW);
+    }
+    return nWidth;
+}
+
+long MA_FASTCALL lcl_AlignHeight( const long nHeight )
+{
+    if ( nHeight )
+    {
+        const long nH = nHeight % nPixelSzH;
+
+        if ( !nH || nH > nHalfPixelSzH )
+            return Max(1L, nHeight - nHalfPixelSzH);
+    }
+    return nHeight;
+}
+
+long MA_FASTCALL lcl_MinHeightDist( const long nDist )
+{
+    if ( aScaleX < aMinDistScale || aScaleY < aMinDistScale )
+        return nDist;
+    return ::lcl_AlignHeight( Max( nDist, nMinDistPixelH ));
+}
+
+long MA_FASTCALL lcl_MinWidthDist( const long nDist )
+{
+    if ( aScaleX < aMinDistScale || aScaleY < aMinDistScale )
+        return nDist;
+    return ::lcl_AlignWidth( Max( nDist, nMinDistPixelW ));
+}
+
+
+//Ermittelt PrtArea plus Umrandung plus Schatten.
+
+void MA_FASTCALL lcl_CalcBorderRect( SwRect &rRect, const SwFrm *pFrm,
+                                        const SwBorderAttrs &rAttrs,
+                                        const BOOL bShadow )
+{
+    if( pFrm->IsSctFrm() )
+        rRect = pFrm->Frm();
+    else
+    {
+        rRect = pFrm->Prt();
+        rRect.Pos() += pFrm->Frm().Pos();
+
+        if ( rAttrs.IsLine() || rAttrs.IsBorderDist() ||
+             (bShadow && rAttrs.GetShadow().GetLocation() != SVX_SHADOW_NONE) )
+        {
+            const SvxBoxItem &rBox = rAttrs.GetBox();
+            const FASTBOOL bTop = 0 != pFrm->Prt().Top();
+            if ( bTop )
+            {
+                if ( rBox.GetTop() )
+                    rRect.Top( rRect.Top() - rBox.CalcLineSpace( BOX_LINE_TOP ) );
+                else if ( rAttrs.IsBorderDist() )
+                    rRect.Top( rRect.Top() - rBox.GetDistance( BOX_LINE_TOP ) - 1 );
+            }
+
+            const FASTBOOL bBottom = pFrm->Prt().Height()+pFrm->Prt().Top() < pFrm->Frm().Height();
+            if ( bBottom )
+            {
+                if ( rBox.GetBottom() )
+                    rRect.SSize().Height() += rBox.CalcLineSpace( BOX_LINE_BOTTOM );
+                else if ( rAttrs.IsBorderDist() )
+                    rRect.SSize().Height() += rBox.GetDistance( BOX_LINE_BOTTOM ) + 1;
+            }
+
+            if ( rBox.GetLeft() )
+                rRect.Left( rRect.Left() - rBox.CalcLineSpace( BOX_LINE_LEFT ) );
+            else if ( rAttrs.IsBorderDist() )
+                rRect.Left( rRect.Left() - rBox.GetDistance( BOX_LINE_LEFT ) - 1 );
+
+            if ( rBox.GetRight() )
+                rRect.SSize().Width() += rBox.CalcLineSpace( BOX_LINE_RIGHT );
+            else if ( rAttrs.IsBorderDist() )
+                rRect.SSize().Width() += rBox.GetDistance( BOX_LINE_RIGHT )  + 1;
+
+            if ( bShadow && rAttrs.GetShadow().GetLocation() != SVX_SHADOW_NONE )
+            {
+                const SvxShadowItem &rShadow = rAttrs.GetShadow();
+                if ( bTop )
+                    rRect.Top ( rRect.Top() - rShadow.CalcShadowSpace(SHADOW_TOP) );
+                rRect.Left( rRect.Left()- rShadow.CalcShadowSpace(SHADOW_LEFT) );
+                if ( bBottom )
+                    rRect.SSize().Height() += rShadow.CalcShadowSpace(SHADOW_BOTTOM);
+                rRect.SSize().Width()  += rShadow.CalcShadowSpace(SHADOW_RIGHT);
+            }
+        }
+    }
+
+    ::SwAlignRect( rRect, pGlobalShell );
+}
+
+void MA_FASTCALL lcl_ExtendLeftAndRight( SwRect &rRect, const SwFrm *pFrm,
+                                            const SwBorderAttrs &rAttrs )
+{
+    //In der Hoehe aufbohren wenn TopLine bzw. BottomLine entfallen.
+    if ( rAttrs.GetBox().GetTop() && !rAttrs.GetTopLine( pFrm ) )
+    {
+        const SwFrm *pPre = pFrm->GetPrev();
+        rRect.Top( pPre->Frm().Top() + pPre->Prt().Bottom() );
+    }
+    if ( rAttrs.GetBox().GetBottom() && !rAttrs.GetBottomLine( pFrm ) )
+    {
+        const SwFrm *pNxt = pFrm->GetNext();
+        rRect.Bottom( pNxt->Frm().Top() + pNxt->Prt().Top() );
+    }
+}
+
+
+void MA_FASTCALL lcl_SubtractFlys( const SwFrm *pFrm, const SwPageFrm *pPage,
+                           const SwRect &rRect, SwRegionRects &rRegion )
+{
+    const SwSortDrawObjs &rObjs = *pPage->GetSortedObjs();
+    const SwFlyFrm *pSelfFly = pFrm->IsInFly() ? pFrm->FindFlyFrm() : pRetoucheFly2;
+    if ( !pRetoucheFly )
+        pRetoucheFly = pRetoucheFly2;
+
+    for ( USHORT j = 0; (j < rObjs.Count()) && rRegion.Count(); ++j )
+    {
+        SdrObject *pO = rObjs[j];
+        if ( !pO->IsWriterFlyFrame() )
+            continue;
+
+        const SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+
+        if ( pSelfFly == pFly || pRetoucheFly == pFly || !rRect.IsOver( pFly->Frm() ) )
+            continue;
+
+        if ( !pFly->GetFmt()->GetPrint().GetValue() &&
+                (OUTDEV_PRINTER == pGlobalShell->GetOut()->GetOutDevType() ||
+                pGlobalShell->IsPreView()))
+            continue;
+
+        const FASTBOOL bLowerOfSelf = pSelfFly && pFly->IsLowerOf( pSelfFly ) ?
+                                            TRUE : FALSE;
+
+        //Bei zeichengebundenem Fly nur diejenigen betrachten, in denen er
+        //nicht selbst verankert ist.
+        //#33429# Warum nur bei zeichengebundenen? Es macht doch nie Sinn
+        //Rahmen abzuziehen in denen er selbst verankert ist oder?
+        if ( pSelfFly && pSelfFly->IsLowerOf( pFly ) )
+            continue;
+
+        //#57194# Und warum gilt das nicht analog fuer den RetoucheFly?
+        if ( pRetoucheFly && pRetoucheFly->IsLowerOf( pFly ) )
+            continue;
+
+
+#ifndef PRODUCT
+        //Flys, die innerhalb des eigenen verankert sind, muessen eine
+        //groessere OrdNum haben oder Zeichengebunden sein.
+        if ( pSelfFly && bLowerOfSelf )
+        {
+            ASSERT( pFly->IsFlyInCntFrm() ||
+                    pO->GetOrdNumDirect() > pSelfFly->GetVirtDrawObj()->GetOrdNumDirect(),
+                    "Fly with wrong z-Order" );
+        }
+#endif
+
+        BOOL bStopOnHell = TRUE;
+        if ( pSelfFly )
+        {
+            const SdrObject *pTmp = pSelfFly->GetVirtDrawObj();
+            if ( pO->GetLayer() == pTmp->GetLayer() )
+            {
+                if ( pO->GetOrdNumDirect() < pTmp->GetOrdNumDirect() )
+                    //Im gleichen Layer werden nur obenliegende beachtet.
+                    continue;
+            }
+            else
+            {
+                if ( !bLowerOfSelf && !pFly->GetFmt()->GetOpaque().GetValue() )
+                    //Aus anderem Layer interessieren uns nur nicht transparente
+                    //oder innenliegende
+                    continue;
+                bStopOnHell = FALSE;
+            }
+        }
+        if ( pRetoucheFly )
+        {
+            const SdrObject *pTmp = pRetoucheFly->GetVirtDrawObj();
+            if ( pO->GetLayer() == pTmp->GetLayer() )
+            {
+                if ( pO->GetOrdNumDirect() < pTmp->GetOrdNumDirect() )
+                    //Im gleichen Layer werden nur obenliegende beachtet.
+                    continue;
+            }
+            else
+            {
+                if ( !pFly->IsLowerOf( pRetoucheFly ) && !pFly->GetFmt()->GetOpaque().GetValue() )
+                    //Aus anderem Layer interessieren uns nur nicht transparente
+                    //oder innenliegende
+                    continue;
+                bStopOnHell = FALSE;
+            }
+        }
+
+        //Wenn der Inhalt des Fly Transparent ist, wird er nicht abgezogen, es sei denn
+        //er steht im Hell-Layer (#31941#)
+        BOOL bHell = pO->GetLayer() == pFly->GetFmt()->GetDoc()->GetHellId();
+        if ( (bStopOnHell && bHell) ||
+             (pFly->Lower() && pFly->Lower()->IsNoTxtFrm() &&
+              !bHell &&
+              (((SwNoTxtFrm*)pFly->Lower())->IsTransparent() ||
+               pFly->GetFmt()->GetSurround().IsContour())))
+            continue;
+
+
+        if ( bHell && pFly->GetAnchor()->IsInFly() )
+        {
+            //Damit die Umrandung nicht vom Hintergrund des anderen Flys
+            //zerlegt wird.
+            SwRect aRect;
+            SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)pFly );
+            const SwBorderAttrs &rAttrs = *aAccess.Get();
+            ::lcl_CalcBorderRect( aRect, pFly, rAttrs, TRUE );
+            rRegion -= aRect;
+        }
+        else
+        {
+            SwRect aRect( pFly->Prt() );
+            aRect += pFly->Frm().Pos();
+            rRegion -= aRect;
+        }
+        continue;
+    }
+    if ( pRetoucheFly == pRetoucheFly2 )
+        pRetoucheFly = 0;
+}
+
+inline FASTBOOL IsShortCut( const SwRect &rRect, const SwRect &rFrmRect )
+{
+    //Wenn der Frm vollstaendig rechts neben bzw. unter dem
+    //Rect sitzt ist's genug mit Painten.
+    return ( (rFrmRect.Top()  > rRect.Bottom()) ||
+             (rFrmRect.Left() > rRect.Right()) );
+}
+
+
+//---------------- Cache und Ausgabe fuer das BrushItem ----------------
+
+//Die Objekte werden, bei gelinkten Grafiken mit derselben ULR, ggf. von mehreren
+//DocShells verwendet. Jede dieser DocShell wird in das (long-)Array eingetragen.
+//Wenn eine DocShell ein Reload bekommt wird sie aus dem Array entfernt
+//(RemoveFromBackgroundCache()). Gleichzeitig wird das Objekt eingefroren, ab diesem
+//Zeitpunkt wird das Objekt nur noch von den restlichen DocShells verwendet.
+//weitere DocShells muessen sich ein neues (aber wieder gemeinsam verwendetes)
+//Objekt erzeugen.
+
+class SwBackgroundCacheObj
+{
+    XubString aStr; //Die URL bei gelinkten Grafiken
+    Graphic   aGrf; //Die Graphic, kann gepurged sein bei gelinkten Grafiken
+    const SvxBrushItem   *pItem; //Der Owner bei nicht gelinkten Grafiken
+    SwBackgroundCacheObj *pPrev,
+                         *pNext;
+    BitmapEx *pBmp; //Die QuickDrawBitmap, kann 0 sein.
+    Size     aSz;   //Die Size fuer die die Bitmap erzeugt wurde
+    Size     aGrfSz;//Originalgroesse der Grafik
+    Size     aGrfPixSz;
+    FASTBOOL bFreezed;     //Darf nur noch von denjenigen DocShells verwendet
+                           //werden, die noch in dem Array eingetragen sind.
+    SvLongs  aDocShellArr; //'Pointer' auf diejenigen DocShells, die dieses
+                           //Objekt 'verwenden'
+    MapMode  aMap;         //Der MapMode fuer den die Bitmap erzeugt wurde
+
+
+public:
+    SwBackgroundCacheObj( const SvxBrushItem &rBrush, SfxObjectShell &rObjSh );
+    ~SwBackgroundCacheObj() { if ( pBmp ) delete pBmp; }
+
+    SwBackgroundCacheObj *GetNext() { return pNext; }
+    SwBackgroundCacheObj *GetPrev() { return pPrev; }
+    void SetNext( SwBackgroundCacheObj *p ) { pNext = p; }
+    void SetPrev( SwBackgroundCacheObj *p ) { pPrev = p; }
+
+    USHORT Find( const SfxObjectShell &rDocSh ) const;
+
+    const XubString &GetStr() const              { return aStr; }
+    const SvxBrushItem *GetBrushItem() const { return pItem;}
+          BitmapEx*GetBmp()                  { return pBmp; }
+    const BitmapEx*GetBmp() const            { return pBmp; }
+    const MapMode &GetMap() const            { return aMap; }
+    const Graphic &GetGrf() const            { return aGrf; }
+    const Size    &GetSize()const            { return aSz;  }
+    const Size    &GetGrfSize() const        { return aGrfSz;}
+    const Size    &GetGrfPixSize() const     { return aGrfPixSz;}
+          FASTBOOL IsFreezed() const         { return bFreezed; }
+          SvLongs &GetDocShells()            { return aDocShellArr; }
+
+    void SetBmp ( BitmapEx *p )         { pBmp = p; }
+    void SetMap ( const MapMode &r)     { aMap = r; }
+    void SetSize( const Size &r   )     { aSz  = r; }
+    void ResetGrf()                     { aGrf = Graphic(); }
+    void SetGrf ( const Graphic &rGrf ) { aGrf = rGrf; }
+    void SetItem( const SvxBrushItem*p) { pItem= p; }
+    void Freeze()                       { bFreezed = TRUE; }
+};
+
+
+class SwBackgroundCache
+{
+    friend void RemoveFromBackgroundCache( const SfxObjectShell &, FASTBOOL );
+
+    Timer aTimer;
+    SwBackgroundCacheObj *pFirst;
+
+    SwBackgroundCacheObj *Insert( const SvxBrushItem &rBrush, ViewShell &rSh );
+
+public:
+    SwBackgroundCache();
+    ~SwBackgroundCache();
+
+    DECL_STATIC_LINK( SwBackgroundCache, TimeoutHdl, Timer* );
+
+    SwBackgroundCacheObj *Find( const SvxBrushItem &rBrush, ViewShell &rSh );
+
+    Size MakeQuickDrawBmp( const SvxBrushItem &rBrush,
+                           SwBackgroundCacheObj *pObj,
+                           OutputDevice *pOut, ViewShell &rSh,
+                           const Size &rSize, BOOL bGrfNum );
+};
+
+void InitBackgroundCache( FASTBOOL bNew )
+{
+    delete pBackgroundCache;
+    if ( bNew )
+        pBackgroundCache = new SwBackgroundCache;
+}
+
+void RemoveFromBackgroundCache( const SfxObjectShell &rDocShell,
+                                FASTBOOL bFreeze )
+{
+    SwBackgroundCacheObj *pObj = pBackgroundCache->pFirst;
+    while ( pObj )
+    {
+        USHORT nPos;
+        if ( USHRT_MAX != (nPos = pObj->Find( rDocShell )) )
+        {
+            pObj->GetDocShells().Remove( nPos );
+            if ( !pObj->GetDocShells().Count() )
+            {
+                if ( pObj == pBackgroundCache->pFirst )
+                    pBackgroundCache->pFirst = pObj->GetNext();
+                if ( pObj->GetPrev() )
+                    pObj->GetPrev()->SetNext( pObj->GetNext() );
+                if ( pObj->GetNext() )
+                    pObj->GetNext()->SetPrev( pObj->GetPrev() );
+                SwBackgroundCacheObj *pDel = pObj;
+                pObj = pObj->GetNext();
+                delete pDel;
+                continue;
+            }
+            else if ( bFreeze )
+                pObj->Freeze();
+        }
+        pObj = pObj->GetNext();
+    }
+}
+
+
+SwBackgroundCacheObj::SwBackgroundCacheObj( const SvxBrushItem &rBrush,
+                                            SfxObjectShell &rObjSh ) :
+    aStr( aEmptyStr ),
+    aGrf( *rBrush.GetGraphic( &rObjSh ) ),
+    pItem( &rBrush ),
+    pBmp( 0 ),
+    pPrev( 0 ),
+    pNext( 0 ),
+    bFreezed( FALSE )
+{
+    aDocShellArr.Insert( long(&rObjSh), aDocShellArr.Count() );
+    if ( rBrush.GetGraphicLink() )
+        aStr = *rBrush.GetGraphicLink();
+
+    if ( aGrf.IsSupportedGraphic() )
+    {
+        const MapMode aMapTwip( MAP_TWIP );
+        if ( aGrf.GetPrefMapMode().GetMapUnit() == MAP_PIXEL )
+        {
+            OutputDevice *pTmp = (OutputDevice*) GetpApp()->GetDefaultDevice();
+            MapMode aOldMap( pTmp->GetMapMode() );
+            pTmp->SetMapMode( aMapTwip );
+            aGrfSz = pTmp->PixelToLogic( aGrf.GetPrefSize() );
+            pTmp->SetMapMode( aOldMap );
+            aGrfPixSz = aGrf.GetPrefSize();
+        }
+        else
+        {
+            aGrfSz = OutputDevice::LogicToLogic( aGrf.GetPrefSize(),
+                                        aGrf.GetPrefMapMode(), aMapTwip );
+            MapMode aMapPixel( MAP_PIXEL );
+            aGrfPixSz = OutputDevice::LogicToLogic( aGrf.GetPrefSize(),
+                                        aGrf.GetPrefMapMode(), MAP_PIXEL );
+        }
+    }
+}
+
+USHORT SwBackgroundCacheObj::Find( const SfxObjectShell &rDocSh ) const
+{
+    for ( USHORT i = 0; i < aDocShellArr.Count(); ++i )
+    {
+        if ( (long)(&rDocSh) == aDocShellArr[i] )
+            return i;
+    }
+    return USHRT_MAX;
+}
+
+SwBackgroundCache::SwBackgroundCache() :
+    pFirst( 0 )
+{
+    aTimer.SetTimeoutHdl( STATIC_LINK( this, SwBackgroundCache, TimeoutHdl ));
+    aTimer.SetTimeout( 10000 );
+    aTimer.Stop();
+}
+
+SwBackgroundCache::~SwBackgroundCache()
+{
+    SwBackgroundCacheObj *pObj = pFirst;
+    while ( pObj )
+    {
+        SwBackgroundCacheObj *pTmp = pObj->GetNext();
+        delete pObj;
+        pObj = pTmp;
+    }
+}
+
+IMPL_STATIC_LINK( SwBackgroundCache, TimeoutHdl, Timer*, EMPTYARG )
+{
+    if ( pThis->pFirst )
+    {
+        SwBackgroundCacheObj *pObj = pThis->pFirst;
+        long nSizeBytes = 0;
+        while ( pObj && nSizeBytes < 250*1024 )
+        {
+            if ( pObj->GetBmp() )
+                nSizeBytes += pObj->GetBmp()->GetSizeBytes();
+            nSizeBytes += pObj->GetGrf().GetSizeBytes();
+            pObj = pObj->GetNext();
+        }
+
+        if ( pObj )
+        {
+            pObj->GetPrev()->SetNext( 0 );
+            while ( pObj )
+            {
+                SwBackgroundCacheObj *pDel = pObj;
+                pObj = pObj->GetNext();
+                delete pDel;
+            }
+        }
+    }
+    return 0;
+}
+
+
+SwBackgroundCacheObj *SwBackgroundCache::Find( const SvxBrushItem &rBrush,
+                                               ViewShell &rSh )
+{
+    SwBackgroundCacheObj *pObj = pFirst;
+    while (  pObj )
+    {
+        if ( rBrush.GetGraphicLink() && rBrush.GetGraphicLink()->Len() )
+        {
+            if ( pObj->GetStr() == *rBrush.GetGraphicLink() )
+            {
+                //Immer das aktuelle Item setzen, denn das alte koennte bereits
+                //zerstoert sein. Das neue lebt auf jedenfall und es ist letzlich
+                //egal welches Item hier steht.
+
+                //ObjektShell eintragen wenn noch nicht vorhanden
+                const SfxObjectShell &rDocSh = *GETOBJSHELL();
+                if ( USHRT_MAX == pObj->Find( rDocSh ) )
+                {
+                    if ( !pObj->IsFreezed() ) //Werden noch neue aufgenommen?
+                    {
+                        pObj->GetDocShells().Insert( long(&rDocSh),
+                                                     pObj->GetDocShells().Count());
+                        pObj->SetItem( &rBrush );
+                        break;
+                    }
+                }
+                else
+                {
+                    pObj->SetItem( &rBrush );
+                    break;
+                }
+            }
+        }
+        else if ( pObj->GetBrushItem() == &rBrush )
+            break;
+        pObj = pObj->GetNext();
+    }
+    if ( !pObj )
+        pObj = Insert( rBrush, rSh );
+    //touchen!
+    if ( pObj && pObj != pFirst )
+    {
+        pObj->GetPrev()->SetNext( pObj->GetNext() );
+        if ( pObj->GetNext() )
+            pObj->GetNext()->SetPrev( pObj->GetPrev() );
+        pFirst->SetPrev( pObj );
+        pObj->SetNext( pFirst );
+        pObj->SetPrev( 0 );
+        pFirst = pObj;
+    }
+    return pObj;
+}
+
+SwBackgroundCacheObj *SwBackgroundCache::Insert( const SvxBrushItem &rBrush,
+                                                 ViewShell &rSh )
+{
+    ((SvxBrushItem&)rBrush).SetDoneLink( STATIC_LINK(
+                                    rSh.GetDoc(), SwDoc, BackgroundDone ) );
+    SfxObjectShell &rObjSh = *GETOBJSHELL();
+    if ( rBrush.GetGraphic( &rObjSh ) &&
+         rBrush.GetGraphic( &rObjSh )->GetType() != GRAPHIC_NONE)
+    {
+        SwBackgroundCacheObj *pObj = new SwBackgroundCacheObj( rBrush, rObjSh );
+        if ( pFirst )
+        {
+            pFirst->SetPrev( pObj );
+            pObj->SetNext( pFirst );
+        }
+        pFirst = pObj;
+        aTimer.Start();
+        return pFirst;
+    }
+    return 0;
+}
+
+Size SwBackgroundCache::MakeQuickDrawBmp( const SvxBrushItem &rBrush,
+                                        SwBackgroundCacheObj *pObj,
+                                        OutputDevice *pOut, ViewShell &rSh,
+                                        const Size &rSize, BOOL bGrfNum )
+{
+    Size aOutSize = rSize;
+    if ( OUTDEV_PRINTER != pOut->GetOutDevType() && !pOut->GetConnectMetaFile() &&
+         aOutSize.Width() && aOutSize.Height() )
+    {
+        const FASTBOOL bTiled = rBrush.GetGraphicPos() == GPOS_TILED;
+        if ( bTiled )
+        {
+            long nTmp = 30 * nPixelSzH;
+            if ( aOutSize.Height() < nTmp )
+                aOutSize.Height() *= (nTmp+aOutSize.Height()) / aOutSize.Height();
+            nTmp = 30 * nPixelSzW;
+            if ( aOutSize.Width() < nTmp )
+                aOutSize.Width() *= (nTmp+aOutSize.Width()) / aOutSize.Width();
+            //Die Grafik sollte schon ganzahlig hineinpassen!
+            aOutSize.Width() -= aOutSize.Width() % pObj->GetGrfPixSize().Width();
+            aOutSize.Height()-= aOutSize.Height()% pObj->GetGrfPixSize().Height();
+        }
+
+        BitmapEx *pQuickDrawBmp = pObj->GetBmp();
+        if ( pQuickDrawBmp )
+        {
+            if ( aOutSize != pObj->GetSize() ||
+                 pObj->GetMap().GetScaleX() != pOut->GetMapMode().GetScaleX() ||
+                 pObj->GetMap().GetScaleY() != pOut->GetMapMode().GetScaleY() )
+            {
+                DELETEZ( pQuickDrawBmp );
+            }
+        }
+        if ( !pQuickDrawBmp )
+        {
+            Size aSizePixel = pOut->LogicToPixel( rSize );
+            ULONG nArea     = (ULONG)aSizePixel.Width() *
+                                (ULONG)aSizePixel.Height();
+            ULONG nColors   = pOut->GetColorCount();
+            if( nColors <= 16 )
+                nArea /= 2;
+            else if( nColors > 65536 )
+                nArea *= 4;
+            nArea *= 2;
+
+            const Graphic &rGraphic = (Graphic&)pObj->GetGrf();
+            if ( rGraphic.GetType() == GRAPHIC_NONE )
+            {
+                ((SvxBrushItem*)pObj->GetBrushItem())->SetDoneLink( Link() );
+                const Graphic *pGrf = pObj->GetBrushItem()->GetGraphic(
+                                                        GETOBJSHELL() );
+                if ( pGrf )
+                    pObj->SetGrf( *pGrf );
+            }
+
+            if ( rGraphic.GetType() != GRAPHIC_NONE &&
+                 rGraphic.GetType() != GRAPHIC_DEFAULT &&
+                (rGraphic.GetType() != GRAPHIC_BITMAP ||
+                 ((nArea < 2000000) && (rGraphic.GetType() == GRAPHIC_BITMAP))))
+            {
+                pQuickDrawBmp = new BitmapEx;
+                // JP 23.08.96: aus Performance keine Transparence an der
+                //              Bitmap zulassen. Bugdoc ware dazu
+                //                  http://www.cherryh.com
+                  if( rGraphic.IsTransparent() && !bGrfNum )
+                {
+                    // Bug 30581: aber keinen schwarzen Hintergrund!!
+                    //            Die Farbe aus dem BrushItem holen.
+                    Point aTmpPt;
+                    Size aBmpSz( rGraphic.GetPrefSize() );
+                    VirtualDevice aVout( *pOut );
+                    aVout.SetMapMode( rGraphic.GetPrefMapMode() );
+                    if( aVout.SetOutputSize( aBmpSz ) )
+                    {
+                        aVout.SetFillColor( rBrush.GetColor() );
+                        aVout.SetLineColor( rBrush.GetColor() );
+                        aVout.DrawRect( Rectangle( aTmpPt, aBmpSz ) );
+                        rGraphic.Draw( &aVout, aTmpPt );
+
+                        *pQuickDrawBmp = XOutBitmap::CreateQuickDrawBitmapEx(
+                                         aVout.GetBitmap( aTmpPt, aBmpSz ),
+                                         *pOut, pOut->GetMapMode(), rSize,
+                                         Point(), rSize );
+                    }
+                    else
+                        *pQuickDrawBmp = XOutBitmap::CreateQuickDrawBitmapEx(
+                                         rGraphic.GetBitmap(), *pOut, pOut->GetMapMode(),
+                                           rSize, Point(), rSize );
+                }
+                else
+                      *pQuickDrawBmp = XOutBitmap::CreateQuickDrawBitmapEx(
+                                     rGraphic, *pOut, pOut->GetMapMode(),
+                                       rSize, Point(), rSize );
+
+                const Size aTSize = pQuickDrawBmp->GetSizePixel();
+                if( !aTSize.Width() || !aTSize.Height() )
+                {   DELETEZ( pQuickDrawBmp ); }
+                else
+                {
+                    pObj->SetSize( aOutSize );
+                    pObj->SetMap ( pOut->GetMapMode() );
+                    if ( bTiled && aOutSize != rSize )
+                    {
+                        VirtualDevice aVout( *pOut );
+                        MapMode aMapMode( pOut->GetMapMode() );
+                        aMapMode.SetOrigin( Point() );
+                        aVout.SetMapMode( aMapMode );
+                        if ( aVout.SetOutputSize( aOutSize ) )
+                        {
+                            aVout.SetLineColor( pOut->GetLineColor() );
+                            aVout.SetFillColor( pOut->GetFillColor() );
+                            const Point aPoint;
+                            Rectangle aOut( aPoint, aOutSize );
+                            XOutBitmap::DrawTiledBitmapEx( &aVout,
+                                                aPoint, rSize,
+                                                aOut, *pQuickDrawBmp );
+                            delete pQuickDrawBmp;
+                            pQuickDrawBmp = new BitmapEx(
+                                        aVout.GetBitmap( aPoint, aOutSize) );
+                        }
+                        else
+                            aOutSize = rSize;
+                    }
+                }
+            }
+            pObj->SetBmp( pQuickDrawBmp );
+            if ( pQuickDrawBmp && rGraphic.GetType() != GRAPHIC_DEFAULT )
+            {
+                pObj->ResetGrf();
+                if ( pObj->GetBrushItem()->GetGraphicLink() &&
+                     pObj->GetBrushItem()->GetGraphicLink()->Len() )
+                    rBrush.PurgeGraphic();
+            }
+        }
+    }
+    return aOutSize;
+}
+
+void lcl_DrawGraphic( const SwBackgroundCacheObj &rObj, OutputDevice *pOut,
+                      ViewShell &rSh,
+                      const SwRect &rGrf, const SwRect &rOut,
+                      BOOL bClip, BOOL bGrfNum )
+{
+    const FASTBOOL bNotInside = bClip && !rOut.IsInside( rGrf );
+    if ( bNotInside )
+    {
+        pOut->Push( PUSH_CLIPREGION );
+        pOut->IntersectClipRegion( rOut.SVRect() );
+    }
+
+    const Color aColor( !rObj.GetBrushItem()->GetColor().GetTransparency() || bFlyMetafile
+                ? rObj.GetBrushItem()->GetColor()
+                : aGlobalRetoucheColor );
+
+      const FASTBOOL bUseQuickBmp = OUTDEV_PRINTER != pOut->GetOutDevType() &&
+                                  !pOut->GetConnectMetaFile();
+    if ( bUseQuickBmp && rObj.GetBmp() )
+    {
+        if ( rObj.GetBmp()->IsTransparent() && !bGrfNum )
+        {
+            if ( pOut->GetFillColor() != aColor )
+                pOut->SetFillColor( aColor );
+            pOut->DrawRect( rGrf.SVRect() );
+        }
+        XOutBitmap::DrawQuickDrawBitmapEx( pOut, rGrf.Pos(), rGrf.SSize(), *rObj.GetBmp());
+    }
+    else
+    {
+        const Graphic *pGrf = 0;
+        if ( !bUseQuickBmp )
+        {   //Hier kein Link, wir wollen die Grafik synchron laden!
+            ((SvxBrushItem*)rObj.GetBrushItem())->SetDoneLink( Link() );
+            pGrf = rObj.GetBrushItem()->GetGraphic( GETOBJSHELL() );
+            if ( pGrf && rObj.GetGrf().GetType() == GRAPHIC_NONE )
+                ((SwBackgroundCacheObj&)rObj).SetGrf( *pGrf );
+        }
+        if ( !pGrf )
+            pGrf = (Graphic*)&rObj.GetGrf();
+        if ( !bGrfNum &&
+             ( pGrf->IsTransparent() || !pGrf->IsSupportedGraphic() ) )
+        {
+            if ( pOut->GetFillColor() != aColor )
+                pOut->SetFillColor( aColor );
+            pOut->DrawRect( rGrf.SVRect() );
+        }
+        ((Graphic*)pGrf)->Draw( pOut, rGrf.Pos(), rGrf.SSize() );
+    }
+
+    if ( bNotInside )
+        pOut->Pop();
+}
+
+void MA_FASTCALL DrawGraphic( const SvxBrushItem *pBrush, OutputDevice *pOut,
+    const SwRect &rOrg, const SwRect &rOut, const BYTE nGrfNum )
+{
+    ViewShell &rSh = *pGlobalShell;
+    BOOL bReplaceGrfNum = GRFNUM_REPLACE == nGrfNum;
+    BOOL bGrfNum = GRFNUM_NO != nGrfNum;
+    SwBackgroundCacheObj *pObj = 0;
+    Size aGrfSize;
+    SvxGraphicPosition ePos = GPOS_NONE;
+    if( pBrush && !bReplaceGrfNum )
+    {
+        if( rSh.GetViewOptions()->IsGraphic() )
+            pObj = pBackgroundCache->Find( *pBrush, rSh );
+        else
+            bReplaceGrfNum = bGrfNum;
+    }
+    if ( pObj )
+    {
+        ePos = pBrush->GetGraphicPos();
+        aGrfSize = pObj->GetGrfSize();
+    }
+
+    const Color aColor( pBrush && ( (!pBrush->GetColor().GetTransparency()) || bFlyMetafile )
+                ? pBrush->GetColor()
+                : aGlobalRetoucheColor );
+
+    SwRect aGrf;
+    aGrf.SSize( aGrfSize );
+    FASTBOOL bDraw = TRUE;
+    FASTBOOL bRetouche = TRUE;
+    switch ( ePos )
+    {
+        case GPOS_LT: aGrf.Pos() = rOrg.Pos();
+                      break;
+        case GPOS_MT: aGrf.Pos().Y() = rOrg.Top();
+                      aGrf.Pos().X() = rOrg.Left() + rOrg.Width()/2 - aGrfSize.Width()/2;
+                      break;
+        case GPOS_RT: aGrf.Pos().Y() = rOrg.Top();
+                      aGrf.Pos().X() = rOrg.Right() - aGrfSize.Width();
+                      break;
+
+        case GPOS_LM: aGrf.Pos().Y() = rOrg.Top() + rOrg.Height()/2 - aGrfSize.Height()/2;
+                      aGrf.Pos().X() = rOrg.Left();
+                      break;
+        case GPOS_MM: aGrf.Pos().Y() = rOrg.Top() + rOrg.Height()/2 - aGrfSize.Height()/2;
+                      aGrf.Pos().X() = rOrg.Left() + rOrg.Width()/2 - aGrfSize.Width()/2;
+                      break;
+        case GPOS_RM: aGrf.Pos().Y() = rOrg.Top() + rOrg.Height()/2 - aGrfSize.Height()/2;
+                      aGrf.Pos().X() = rOrg.Right() - aGrfSize.Width();
+                      break;
+
+        case GPOS_LB: aGrf.Pos().Y() = rOrg.Bottom() - aGrfSize.Height();
+                      aGrf.Pos().X() = rOrg.Left();
+                      break;
+        case GPOS_MB: aGrf.Pos().Y() = rOrg.Bottom() - aGrfSize.Height();
+                      aGrf.Pos().X() = rOrg.Left() + rOrg.Width()/2 - aGrfSize.Width()/2;
+                      break;
+        case GPOS_RB: aGrf.Pos().Y() = rOrg.Bottom() - aGrfSize.Height();
+                      aGrf.Pos().X() = rOrg.Right() - aGrfSize.Width();
+                      break;
+
+        case GPOS_AREA:
+                      aGrf = rOrg;
+                      bRetouche = FALSE;
+                      break;
+        case GPOS_TILED:
+                      {
+                      aGrf.Pos() = rOrg.Pos();
+                      aGrf.SSize() = pBackgroundCache->MakeQuickDrawBmp(
+                                *pBrush, pObj, pOut, rSh, aGrf.SSize(), bGrfNum);
+                      BitmapEx *pBmpEx = pObj->GetBmp();
+                      const FASTBOOL bQuick = OUTDEV_PRINTER != pOut->GetOutDevType() &&
+                                                !pOut->GetConnectMetaFile();
+
+                      if ( bQuick && pBmpEx )
+                      {
+                          const Rectangle aOut( rOut.SVRect() );
+                          if ( pBmpEx->IsTransparent() )
+                          {
+                              if ( pOut->GetFillColor() != aColor )
+                                  pOut->SetFillColor( aColor );
+                              pOut->DrawRect( aOut );
+                          }
+                            XOutBitmap::DrawTiledBitmapEx( pOut, aGrf.Pos(),
+                                                           aGrf.SSize(),
+                                                         aOut, *pBmpEx );
+                      }
+                      else
+                      {
+                            pOut->Push( PUSH_CLIPREGION );
+                          pOut->IntersectClipRegion( rOut.SVRect() );
+                          do
+                          { do
+                            {   if ( aGrf.IsOver( rOut ) )
+                                    lcl_DrawGraphic( *pObj, pOut, rSh, aGrf,
+                                                     rOut, FALSE, bGrfNum);
+                                aGrf.Pos().X() += aGrf.Width();
+
+                            } while ( aGrf.Left() < rOut.Right() );
+
+                            aGrf.Pos().X() = rOrg.Left();
+                            aGrf.Pos().Y() += aGrf.Height();
+
+                          }  while ( aGrf.Top() < rOut.Bottom() ) ;
+                          pOut->Pop();
+                      }
+                      bDraw = bRetouche = FALSE;
+                      break;
+                      }
+        case GPOS_NONE:
+                      bDraw = FALSE;
+                      break;
+
+        default: ASSERT( !pOut, "new Graphic position?" );
+    }
+    if ( bRetouche )
+    {
+        SwRegionRects aRegion( rOut, 4 );
+        aRegion -= aGrf;
+        pOut->Push( PUSH_FILLCOLOR );
+        if ( pOut->GetFillColor() != aColor )
+            pOut->SetFillColor( aColor );
+        for ( USHORT i = 0; i < aRegion.Count(); ++i )
+            pOut->DrawRect( aRegion[i].SVRect() );
+        pOut->Pop();
+    }
+    if ( bDraw && aGrf.IsOver( rOut ) )
+    {
+        pBackgroundCache->MakeQuickDrawBmp( *pBrush, pObj, pOut, rSh,
+                                            aGrf.SSize(), bGrfNum );
+        lcl_DrawGraphic( *pObj, pOut, rSh, aGrf, rOut, TRUE, bGrfNum );
+    }
+    if( bReplaceGrfNum )
+    {
+        const Bitmap& rBmp = SwNoTxtFrm::GetBitmap( FALSE );
+        Font aTmp( pOut->GetFont() );
+        ((Graphic*)0)->Draw( pOut, aEmptyStr, aTmp, rBmp,
+                             rOrg.Pos(), rOrg.SSize() );
+    }
+}
+
+//------------------------------------------------------------------------
+
+/*************************************************************************
+|*
+|*  SwRootFrm::Paint()
+|*
+|*  Beschreibung
+|*      Fuer jede sichtbare Seite, die von Rect berhrt wird einmal Painten.
+|*      1. Umrandungen und Hintergruende Painten.
+|*      2. Den DrawLayer (Ramen und Zeichenobjekte) der unter dem Dokument
+|*         liegt painten (Hoelle).
+|*      3. Den Dokumentinhalt (Text) Painten.
+|*      4. Den Drawlayer der ueber dem Dokuemnt liegt painten.
+|*
+|*  Ersterstellung      MA 01. Jun. 92
+|*  Letzte Aenderung    MA 10. Oct. 97
+|*
+|*************************************************************************/
+
+void SwRootFrm::Paint( const SwRect& rRect ) const
+{
+    ASSERT( Lower() && Lower()->IsPageFrm(), "Lower der Root keine Seite." );
+
+    PROTOCOL( this, PROT_FILE_INIT, 0, 0)
+
+    FASTBOOL bResetRootPaint = FALSE;
+    ViewShell *pSh = pCurrShell;
+
+    if ( pSh->GetWin() )
+    {
+        if ( pSh->GetOut() == pSh->GetWin() && !pSh->GetWin()->IsVisible() )
+        {
+            return;
+        }
+        if ( SwRootFrm::bInPaint )
+        {
+            SwPaintQueue::Add( pSh, rRect );
+            return;
+        }
+    }
+    else
+        SwRootFrm::bInPaint = bResetRootPaint = TRUE;
+
+    SwSavePaintStatics *pStatics = 0;
+    if ( pGlobalShell )
+        pStatics = new SwSavePaintStatics();
+    pGlobalShell = pSh;
+
+    bOneBeepOnly = pSh->GetWin() != 0 && pSh->GetDoc()->IsFrmBeepEnabled();
+    if( !pSh->GetWin() )
+        pProgress = SfxProgress::GetActiveProgress( (SfxObjectShell*) pSh->GetDoc()->GetDocShell() );
+
+    ::SwCalcPixStatics( pSh->GetOut() );
+    aGlobalRetoucheColor = pSh->Imp()->GetRetoucheColor();
+
+    //Ggf. eine Action ausloesen um klare Verhaeltnisse zu schaffen.
+    //Durch diesen Kunstgriff kann in allen Paints davon ausgegangen werden,
+    //das alle Werte gueltigt sind - keine Probleme, keine Sonderbehandlung(en).
+    if ( !pSh->IsInEndAction() && !pSh->IsPaintInProgress() &&
+         (!pSh->Imp()->IsAction() || !pSh->Imp()->GetLayAction().IsActionInProgress() ) )
+    {
+        ((SwRootFrm*)this)->ResetTurbo();
+        SwLayAction aAction( (SwRootFrm*)this, pSh->Imp() );
+        aAction.SetPaint( FALSE );
+        aAction.SetComplete( FALSE );
+        aAction.SetReschedule( pProgress ? TRUE : FALSE );
+        aAction.Action();
+        ((SwRootFrm*)this)->ResetTurboFlag();
+        if ( !pSh->ActionPend() )
+            pSh->Imp()->DelRegions();
+    }
+
+    SwRect aRect( rRect );
+    aRect.Intersection( pSh->VisArea() );
+
+    FASTBOOL bExtraData = ::IsExtraData( GetFmt()->GetDoc() );
+
+    pLines = new SwLineRects;   //Sammler fuer Umrandungen.
+
+    const SwPageFrm *pPage = pSh->Imp()->GetFirstVisPage();
+
+    while ( pPage && !::IsShortCut( aRect, pPage->Frm() ) )
+    {
+        if ( !pPage->IsEmptyPage() && aRect.IsOver( pPage->Frm() ) )
+        {
+            if ( pSh->GetWin() )
+                pSubsLines = new SwSubsRects;
+
+            SwRect aPaintRect( pPage->Frm() );
+            aPaintRect._Intersection( aRect );
+
+            if ( bExtraData )
+            {
+                //Ja, das ist grob, aber wie macht man es besser?
+                aPaintRect.Left( pPage->Frm().Left() );
+                aPaintRect.Right( pPage->Frm().Right() );
+                aPaintRect._Intersection( pSh->VisArea() );
+            }
+
+            pVout->Enter( pSh, aPaintRect, !bNoVirDev );
+
+               SwRect aBorderRect( aPaintRect );
+               ::SizeBorderRect( aBorderRect );
+
+            aPaintRect.Top(  Max( 0L, aPaintRect.Top() - nPixelSzH ));
+            aPaintRect.Left( Max( 0L, aPaintRect.Left()- nPixelSzW ));
+            pVout->SetOrgRect( aPaintRect );
+
+            pPage->PaintBaBo( aPaintRect, pPage, TRUE );
+
+            if ( pSh->Imp()->HasDrawView() )
+            {
+                pLines->LockLines( TRUE );
+                pSh->Imp()->PaintLayer( pSh->GetDoc()->GetHellId(), aBorderRect );
+                pLines->PaintLines( pSh->GetOut() );
+                pLines->LockLines( FALSE );
+            }
+
+            pPage->Paint( aPaintRect );
+            pLines->PaintLines( pSh->GetOut() );
+
+            BOOL bControlExtra = FALSE;
+            if ( pSh->Imp()->HasDrawView() )
+            {
+                pSh->Imp()->PaintLayer( pSh->GetDoc()->GetHeavenId(), aBorderRect );
+                if( pVout->IsFlushable() )
+                    bControlExtra = TRUE;
+                else
+                    pSh->Imp()->PaintLayer( pSh->GetDoc()->GetControlsId(), aBorderRect );
+                pLines->PaintLines( pSh->GetOut() );
+            }
+
+            if ( bExtraData )
+                pPage->RefreshExtraData( aBorderRect );
+
+            if ( pSh->GetWin() )
+            {
+                pPage->RefreshSubsidiary( aBorderRect );
+                pSubsLines->PaintSubsidiary( pSh->GetOut(), pLines );
+                DELETEZ( pSubsLines );
+            }
+            pVout->Leave();
+            if( bControlExtra )
+                pSh->Imp()->PaintLayer( pSh->GetDoc()->GetControlsId(), aBorderRect );
+        }
+        ASSERT( !pPage->GetNext() || pPage->GetNext()->IsPageFrm(),
+                "Nachbar von Seite keine Seite." );
+        pPage = (SwPageFrm*)pPage->GetNext();
+    }
+
+    DELETEZ( pLines );
+
+    if ( pSh->GetWin() && pSh->Imp()->HasDrawView() &&
+         pSh->Imp()->GetDrawView()->IsGridVisible() )
+        pSh->Imp()->GetDrawView()->GetPageViewPgNum(0)->DrawGrid(
+                                            *pSh->GetOut(), rRect.SVRect() );
+
+    if ( bResetRootPaint )
+        SwRootFrm::bInPaint = FALSE;
+    if ( pStatics )
+        delete pStatics;
+    else
+    {
+        pProgress = 0;
+        pGlobalShell = 0;
+    }
+
+    if ( ViewShell::IsLstEndAction() && pSh->GetWin() && pSh->Imp()->HasDrawView() )
+        pSh->Imp()->GetDrawView()->PostPaint();
+}
+
+/*************************************************************************
+|*
+|*  SwRootFrm::HackPrepareLongTblPaint()
+|*
+|*  Ersterstellung      MA 27. Sep. 96
+|*  Letzte Aenderung    MA 18. Nov. 97
+|*
+|*************************************************************************/
+
+void SwRootFrm::HackPrepareLongTblPaint( int nMode )
+{
+    switch ( nMode )
+    {
+        case HACK_TABLEMODE_INIT       : ASSERT( !pLines, "HackPrepare: already prepared" );
+                                         pLines = new SwLineRects;
+                                         ASSERT( !pGlobalShell, "old GlobalShell lost" );
+                                         pGlobalShell = GetShell();
+                                         bTableHack = TRUE;
+                                         break;
+        case HACK_TABLEMODE_LOCKLINES  : pLines->LockLines( TRUE ); break;
+        case HACK_TABLEMODE_PAINTLINES : pLines->PaintLines( GetShell()->GetOut() );
+                                         break;
+        case HACK_TABLEMODE_UNLOCKLINES: pLines->LockLines( FALSE ); break;
+        case HACK_TABLEMODE_EXIT       : pLines->PaintLines( GetShell()->GetOut() );
+                                         DELETEZ( pLines );
+                                         pGlobalShell = 0;
+                                         bTableHack = FALSE;
+                                         break;
+    }
+}
+
+
+/*************************************************************************
+|*
+|*  SwLayoutFrm::Paint()
+|*
+|*  Ersterstellung      MA 19. May. 92
+|*  Letzte Aenderung    MA 19. Apr. 95
+|*
+|*************************************************************************/
+
+void MA_FASTCALL lcl_EmergencyFormatFtnCont( SwFtnContFrm *pCont )
+{
+    //Es kann sein, dass der Cont vernichtet wird.
+    SwCntntFrm *pCnt = pCont->ContainsCntnt();
+    while ( pCnt && pCnt->IsInFtn() )
+    {
+        pCnt->Calc();
+        pCnt = pCnt->GetNextCntntFrm();
+    }
+}
+
+
+void SwLayoutFrm::Paint( const SwRect& rRect ) const
+{
+    const SwFrm *pFrm = Lower();
+    if ( !pFrm )
+        return;
+
+    BOOL bCnt;
+    if ( TRUE == (bCnt = pFrm->IsCntntFrm()) )
+        pFrm->Calc();
+
+    if ( pFrm->IsFtnContFrm() )
+    {   ::lcl_EmergencyFormatFtnCont( (SwFtnContFrm*)pFrm );
+        pFrm = Lower();
+    }
+
+    const SwPageFrm *pPage = 0;
+    const FASTBOOL bWin   = pGlobalShell->GetWin() ? TRUE : FALSE;
+
+    while ( IsAnLower( pFrm ) )
+    {
+        SwRect aPaintRect( pFrm->PaintArea() );
+        if( ::IsShortCut( rRect, aPaintRect ) )
+            break;
+        if ( bCnt && pProgress )
+            pProgress->Reschedule();
+
+        //Wenn ein Frm es explizit will muss retouchiert werden.
+        //Erst die Retouche, denn selbige koennte die aligned'en Raender
+        //plaetten.
+        if ( pFrm->IsRetouche() )
+        {
+            if ( pFrm->IsRetoucheFrm() && bWin && !pFrm->GetNext() )
+            {   if ( !pPage )
+                    pPage = FindPageFrm();
+                pFrm->Retouche( pPage, rRect );
+            }
+            pFrm->ResetRetouche();
+        }
+        if ( rRect.IsOver( aPaintRect ) )
+        {
+            if ( bCnt && pFrm->IsCompletePaint() &&
+                 !rRect.IsInside( aPaintRect ) && GetpApp()->AnyInput( INPUT_KEYBOARD ) )
+            {
+                //fix(8104): Es kann vorkommen, dass die Verarbeitung nicht
+                //vollstaendig war, aber trotzdem Teile des Absatzes gepaintet
+                //werden. In der Folge werden dann evtl. wiederum andere Teile
+                //des Absatzes garnicht mehr gepaintet. Einziger Ausweg scheint
+                //hier ein Invalidieren der Windows zu sein.
+                //Um es nicht alzu Heftig werden zu lassen versuche ich hier
+                //das Rechteck zu begrenzen indem der gewuenschte Teil gepaintet
+                //und nur die uebrigen Absatzanteile invalidiert werden.
+                if ( aPaintRect.Left()  == rRect.Left() &&
+                     aPaintRect.Right() == rRect.Right() )
+                {
+                    aPaintRect.Bottom( rRect.Top() - 1 );
+                    if ( aPaintRect.Height() > 0 )
+                        pGlobalShell->InvalidateWindows(aPaintRect);
+                    aPaintRect.Top( rRect.Bottom() + 1 );
+                    aPaintRect.Bottom( pFrm->Frm().Bottom() );
+                    if ( aPaintRect.Height() > 0 )
+                        pGlobalShell->InvalidateWindows(aPaintRect);
+                    aPaintRect.Top( pFrm->Frm().Top() );
+                    aPaintRect.Bottom( pFrm->Frm().Bottom() );
+                }
+                else
+                {
+                    pGlobalShell->InvalidateWindows( aPaintRect );
+                    pFrm = pFrm->GetNext();
+                    if ( pFrm && (TRUE == (bCnt = pFrm->IsCntntFrm())) )
+                        pFrm->Calc();
+                    continue;
+                }
+            }
+            pFrm->ResetCompletePaint();
+            aPaintRect._Intersection( rRect );
+            pFrm->Paint( aPaintRect );
+
+            if ( Lower() && Lower()->IsColumnFrm() )
+            {
+                //Ggf. die Spaltentrennlinien malen. Fuer den Seitenbody ist
+                //nicht der Upper sondern die Seite Zustaendig.
+                const SwFrmFmt *pFmt = GetUpper() && GetUpper()->IsPageFrm()
+                                            ? GetUpper()->GetFmt()
+                                            : GetFmt();
+                const SwFmtCol &rCol = pFmt->GetCol();
+                if ( rCol.GetLineAdj() != COLADJ_NONE )
+                {
+                    if ( !pPage )
+                        pPage = pFrm->FindPageFrm();
+                    PaintColLines( aPaintRect, rCol, pPage );
+                }
+            }
+
+            //Nur: Body, Column, Tab, Header, Footer, FtnCont, Ftn
+            if ( bOneBeepOnly && (pFrm->GetType() & 0x08FC))
+            {
+                //Wenn der Frm ueber seinen Upper hinausragt gibts die gelbe Karte.
+                const long nDeadline = Frm().Top() + Prt().Top() +
+                                       Prt().Height() - 1;
+                if ( pFrm->Frm().Bottom() > nDeadline )
+                {
+                    if ( pGlobalShell->VisArea().Bottom() > nDeadline &&
+                         pGlobalShell->VisArea().Top() < nDeadline )
+                    {
+                        bOneBeepOnly = FALSE;
+                        Sound::Beep();
+                    }
+                }
+            }
+        }
+        if ( !bCnt && pFrm->GetNext() && pFrm->GetNext()->IsFtnContFrm() )
+            ::lcl_EmergencyFormatFtnCont( (SwFtnContFrm*)pFrm->GetNext() );
+
+        pFrm = pFrm->GetNext();
+        if ( pFrm && (TRUE == (bCnt = pFrm->IsCntntFrm())) )
+            pFrm->Calc();
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFlyFrm::IsPaint()
+|*
+|*  Ersterstellung      MA 16. Jan. 97
+|*  Letzte Aenderung    MA 16. Jan. 97
+|*
+|*************************************************************************/
+
+BOOL SwFlyFrm::IsPaint( SdrObject *pObj, const ViewShell *pSh )
+{
+    SdrObjUserCall *pUserCall;
+
+    if ( 0 == ( pUserCall = GetUserCall(pObj) ) )
+        return TRUE;
+
+    //Attributabhaengig nicht fuer Drucker oder PreView painten
+    FASTBOOL bPaint =  pFlyOnlyDraw ||
+                       ((SwContact*)pUserCall)->GetFmt()->GetPrint().GetValue();
+    if ( !bPaint )
+        bPaint = pSh->GetWin() && !pSh->IsPreView();
+
+    if ( bPaint )
+    {
+        //Das Paint kann evtl. von von uebergeordneten Flys verhindert werden.
+        SwFrm *pAnch = 0;
+        if ( pObj->IsWriterFlyFrame() )
+        {
+            SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+            if ( pFlyOnlyDraw && pFlyOnlyDraw == pFly )
+                return TRUE;
+
+            //Die Anzeige eines Zwischenstadiums vermeiden, Flys die nicht mit
+            //der Seite auf der sie verankert sind ueberlappen werden auch
+            //nicht gepaintet.
+            //HACK: Ausnahme: Drucken von Rahmen in Tabellen, diese koennen
+            //bei uebergrossen Tabellen (HTML) schon mal auserhalb der Seite
+            //stehen.
+            SwPageFrm *pPage = pFly->FindPageFrm();
+            if ( pPage )
+            {
+                if ( pPage->Frm().IsOver( pFly->Frm() ) )
+                    pAnch = pFly->GetAnchor();
+                else if ( bTableHack &&
+                          pFly->Frm().Top() >= pFly->GetAnchor()->Frm().Top() &&
+                            pFly->Frm().Top() < pFly->GetAnchor()->Frm().Bottom() &&
+                          long(pSh->GetOut()) == long(pSh->GetPrt()) )
+                {
+                    pAnch = pFly->GetAnchor();
+                }
+            }
+
+        }
+        else
+        {
+            pAnch = ((SwDrawContact*)pUserCall)->GetAnchor();
+            if ( pAnch )
+            {
+                if ( !pAnch->GetValidPosFlag() )
+                    pAnch = 0;
+                else if ( long(pSh->GetOut()) == long(pSh->GetPrt()) )
+                {
+                    //HACK: fuer das Drucken muessen wir ein paar Objekte
+                    //weglassen, da diese sonst doppelt gedruckt werden.
+                    //Die Objekte sollen gedruckt werden, wenn der TableHack
+                    //gerade greift. In der Folge duerfen sie nicht gedruckt werden
+                    //wenn sie mit der Seite dran sind, ueber der sie von der
+                    //Position her gerade schweben.
+                    SwPageFrm *pPage = pAnch->FindPageFrm();
+                    if ( !bTableHack &&
+                         !pPage->Frm().IsOver( pObj->GetBoundRect() ) )
+                        pAnch = 0;
+                }
+            }
+        }
+        if ( pAnch )
+        {
+            if ( pAnch->IsInFly() )
+                bPaint = SwFlyFrm::IsPaint( pAnch->FindFlyFrm()->GetVirtDrawObj(),
+                                            pSh );
+            else if ( pFlyOnlyDraw )
+                bPaint = FALSE;
+        }
+        else
+            bPaint = FALSE;
+    }
+    return bPaint;
+}
+
+/*************************************************************************
+|*
+|*  SwFlyFrm::Paint()
+|*
+|*  Ersterstellung      MA ??
+|*  Letzte Aenderung    MA 16. Jan. 97
+|*
+|*************************************************************************/
+
+//Weiter unten definiert
+void MA_FASTCALL lcl_PaintLowerBorders( const SwLayoutFrm *pLay,
+                               const SwRect &rRect, const SwPageFrm *pPage );
+
+void SwFlyFrm::Paint( const SwRect& rRect ) const
+{
+    //wegen der Ueberlappung von Rahmen und Zeichenobjekten muessen die
+    //Flys ihre Umrandung (und die der Innenliegenden) direkt ausgeben.
+    //z.B. #33066#
+    pLines->LockLines(TRUE);
+
+    SwRect aRect( rRect );
+    if ( !IsFlyInCntFrm() )
+        ::InvertSizeBorderRect( aRect, pGlobalShell );
+    aRect._Intersection( Frm() );
+
+    OutputDevice *pOut = pGlobalShell->GetOut();
+    pOut->Push( PUSH_CLIPREGION );
+    pOut->SetClipRegion();
+    const SwPageFrm *pPage = FindPageFrm();
+
+    const SwNoTxtFrm *pNoTxt = Lower() && Lower()->IsNoTxtFrm()
+                                                ? (SwNoTxtFrm*)Lower() : 0;
+    FASTBOOL bTransparent = pNoTxt ? pNoTxt->IsTransparent() : FALSE,
+             bContour     = GetFmt()->GetSurround().IsContour(),
+             bHell, bPaintBack;
+
+    if ( bTransparent &&
+         GetVirtDrawObj()->GetLayer() == GetFmt()->GetDoc()->GetHellId() &&
+         GetAnchor()->FindFlyFrm() )
+    {
+        SwFlyFrm *pOldRet = pRetoucheFly2; pRetoucheFly2 = (SwFlyFrm*)this;
+        const SwFrm *pFrm = GetAnchor()->FindFlyFrm();
+        SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFrm );
+        const SwBorderAttrs &rAttrs = *aAccess.Get();
+        pFrm->PaintBackground( aRect, pPage, rAttrs, FALSE, FALSE );
+        pRetoucheFly2 = pOldRet;
+    }
+//#33429#           else
+    {
+        PolyPolygon aPoly;
+        if ( bContour )
+            bContour = GetContour( aPoly );
+
+        //Hintergrund painten fuer:
+        bPaintBack = !pNoTxt || Prt().SSize() != Frm().SSize();
+        //sowie fuer Transparente und Contour in der Hoelle
+        bPaintBack = bPaintBack ||
+                ((bTransparent || bContour ) &&
+                TRUE == (bHell = GetVirtDrawObj()->GetLayer() == GetFmt()->GetDoc()->GetHellId()));
+        //sowie fuer Transparente und Contour mit eigener Brush
+        if ( !bPaintBack && (bTransparent||bContour) )
+        {
+            const SvxBrushItem &rBack = GetFmt()->GetBackground();
+            bPaintBack = !rBack.GetColor().GetTransparency() ||
+                             rBack.GetGraphicPos() != GPOS_NONE;
+        }
+
+        if ( bPaintBack )
+        {
+            //#24926# JP 01.02.96, PaintBaBo in teilen hier, damit PaintBorder
+            //das orig. Rect bekommt, aber PaintBackground das begrenzte.
+
+            pOut->Push( PUSH_FILLCOLOR );
+
+            pPage = FindPageFrm();
+
+            SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)this );
+            const SwBorderAttrs &rAttrs = *aAccess.Get();
+
+/*          //Das Paint der FlyInCnt's wird vom Paint der Lines gerufen. Damit
+            //der Rand (UL-/LRSpace) mit der richtigen Farbe retouchiert wird,
+            //muss Das Paint an den Anker weitergereicht werden.
+            FASTBOOL bUnlock = FALSE;
+            if ( IsFlyInCntFrm() )
+            {
+                bLockFlyBackground = bUnlock = TRUE;
+                SwBorderAttrAccess aAccess( SwFrm::GetCache(), GetAnchor());
+                const SwBorderAttrs &rAttrs = *aAccess.Get();
+                GetAnchor()->PaintBackground( aRect, pPage, rAttrs, FALSE );
+            }
+*/
+            SwRegionRects aRegion( aRect );
+            if ( pNoTxt && !bTransparent )
+            {
+                //Was wir eigentlich Painten wollen ist der schmale Streifen
+                //zwischen PrtArea und aeusserer Umrandung.
+                 SwRect aTmp( Prt() ); aTmp += Frm().Pos();
+                aRegion -= aTmp;
+            }
+            if ( bContour )
+            {
+                pOut->Push();
+                if ( !pOut->GetConnectMetaFile() || pOut->GetOutDevType() == OUTDEV_PRINTER )
+                {
+                    pOut->SetClipRegion( aPoly );
+                }
+                for ( USHORT i = 0; i < aRegion.Count(); ++i )
+                    PaintBackground( aRegion[i], pPage, rAttrs, FALSE, TRUE );
+                pOut->Pop();
+            }
+            else
+                for ( USHORT i = 0; i < aRegion.Count(); ++i )
+                    PaintBackground( aRegion[i], pPage, rAttrs, FALSE, TRUE );
+
+            SwRect aTmp( rRect );
+            if ( IsFlyInCntFrm() )
+                ::SizeBorderRect( aTmp );
+//??        aTmp._Intersection( Frm() );
+            PaintBorder( aTmp, pPage, rAttrs );
+/*          if ( bUnlock )
+                bLockFlyBackground = FALSE;
+*/
+            pOut->Pop();
+        }
+    }
+
+    SwLayoutFrm::Paint( aRect );
+    Validate();
+
+    pLines->LockLines( FALSE );
+    pLines->PaintLines( pOut );
+
+    pOut->Pop();
+
+    if ( pProgress && pNoTxt )
+        pProgress->Reschedule();
+}
+/*************************************************************************
+|*
+|*    SwTabFrm::Paint()
+|*
+|*    Ersterstellung    MA 11. May. 93
+|*    Letzte Aenderung  MA 23. Mar. 95
+|*
+|*************************************************************************/
+
+void SwTabFrm::Paint( const SwRect& rRect ) const
+{
+    if( pGlobalShell->GetViewOptions()->IsTable() )
+        SwLayoutFrm::Paint( rRect );
+    else if( pGlobalShell->GetWin() )
+    {
+        pGlobalShell->GetViewOptions()->
+                DrawRect( pGlobalShell->GetOut(), rRect, COL_LIGHTGRAY );
+    }
+    ((SwTabFrm*)this)->ResetComplete();
+}
+
+/*************************************************************************
+|*
+|*  SwFrm::PaintShadow()
+|*
+|*  Beschreibung        Malt einen Shatten wenns das FrmFormat fordert.
+|*      Der Schatten wird immer an den auesseren Rand des OutRect gemalt.
+|*      Das OutRect wird ggf. so verkleinert, dass auf diesem das
+|*      malen der Umrandung stattfinden kann.
+|*  Ersterstellung      MA 21. Dec. 92
+|*  Letzte Aenderung    MA 29. May. 97
+|*
+|*************************************************************************/
+
+void SwFrm::PaintShadow( const SwRect& rRect, SwRect& rOutRect,
+                         const SwPageFrm *pPage,
+                         const SwBorderAttrs &rAttrs ) const
+{
+    const SvxShadowItem &rShadow = rAttrs.GetShadow();
+    const long nWidth  = ::lcl_AlignWidth ( rShadow.GetWidth() );
+    const long nHeight = ::lcl_AlignHeight( rShadow.GetWidth() );
+
+    SwRects aRegion( 2, 2 );
+    SwRect aOut( rOutRect );
+
+    const FASTBOOL bCnt    = IsCntntFrm();
+    const FASTBOOL bTop    = !bCnt || rAttrs.GetTopLine  ( this ) ? TRUE : FALSE;
+    const FASTBOOL bBottom = !bCnt || rAttrs.GetBottomLine( this ) ? TRUE : FALSE;
+
+    switch ( rShadow.GetLocation() )
+    {
+        case SVX_SHADOW_BOTTOMRIGHT:
+            {
+                aOut.Top ( aOut.Bottom() - nHeight );
+                aOut.Left( aOut.Left()   + nWidth );
+                if ( bBottom )
+                    aRegion.Insert( aOut, aRegion.Count() );
+                aOut.Left( aOut.Right()   - nWidth );
+                aOut.Top ( rOutRect.Top() + nHeight );
+                if ( bBottom )
+                    aOut.Bottom( aOut.Bottom() - nHeight );
+                if ( bCnt && (!bTop || !bBottom) )
+                    ::lcl_ExtendLeftAndRight( aOut, this, rAttrs );
+                aRegion.Insert( aOut, aRegion.Count() );
+
+                rOutRect.Right ( rOutRect.Right() - nWidth );
+                rOutRect.Bottom( rOutRect.Bottom()- nHeight );
+            }
+            break;
+        case SVX_SHADOW_TOPLEFT:
+            {
+                aOut.Bottom( aOut.Top()   + nHeight );
+                aOut.Right ( aOut.Right() - nWidth );
+                if ( bTop )
+                    aRegion.Insert( aOut, aRegion.Count() );
+                aOut.Right ( aOut.Left() + nWidth );
+                aOut.Bottom( rOutRect.Bottom() - nHeight );
+                if ( bTop )
+                    aOut.Top( aOut.Top() + nHeight );
+                if ( bCnt && (!bBottom || !bTop) )
+                    ::lcl_ExtendLeftAndRight( aOut, this, rAttrs );
+                aRegion.Insert( aOut, aRegion.Count() );
+
+                rOutRect.Left( rOutRect.Left() + nWidth );
+                rOutRect.Top(  rOutRect.Top() + nHeight );
+            }
+            break;
+        case SVX_SHADOW_TOPRIGHT:
+            {
+                aOut.Bottom( aOut.Top() + nHeight );
+                aOut.Left (  aOut.Left()+ nWidth );
+                if ( bTop )
+                    aRegion.Insert( aOut, aRegion.Count() );
+                aOut.Left  ( aOut.Right() - nWidth );
+                aOut.Bottom( rOutRect.Bottom() - nHeight );
+                if ( bTop )
+                    aOut.Top( aOut.Top() + nHeight );
+                if ( bCnt && (!bBottom || bTop) )
+                    ::lcl_ExtendLeftAndRight( aOut, this, rAttrs );
+                aRegion.Insert( aOut, aRegion.Count() );
+
+                rOutRect.Right( rOutRect.Right() - nWidth );
+                rOutRect.Top( rOutRect.Top() + nHeight );
+            }
+            break;
+        case SVX_SHADOW_BOTTOMLEFT:
+            {
+                aOut.Top  ( aOut.Bottom()- nHeight );
+                aOut.Right( aOut.Right() - nWidth );
+                if ( bBottom )
+                    aRegion.Insert( aOut, aRegion.Count() );
+                aOut.Right( aOut.Left() + nWidth );
+                aOut.Top( rOutRect.Top() + nHeight );
+                if ( bBottom )
+                    aOut.Bottom( aOut.Bottom() - nHeight );
+                if ( bCnt && (!bTop || !bBottom) )
+                    ::lcl_ExtendLeftAndRight( aOut, this, rAttrs );
+                aRegion.Insert( aOut, aRegion.Count() );
+
+                rOutRect.Left( rOutRect.Left() + nWidth );
+                rOutRect.Bottom( rOutRect.Bottom() - nHeight );
+            }
+            break;
+#ifndef PRODUCT
+        default:    ASSERT( !this, "new ShadowLocation() ?" );
+#endif
+    }
+
+    OutputDevice *pOut = pGlobalShell->GetOut();
+    if ( pOut->GetFillColor() != rShadow.GetColor() )
+        pOut->SetFillColor( rShadow.GetColor() );
+    for ( USHORT i = 0; i < aRegion.Count(); ++i )
+    {
+        SwRect &rOut = aRegion[i];
+        aOut = rOut;
+        ::SwAlignRect( aOut, pGlobalShell );
+        if ( rRect.IsOver( aOut ) && aOut.Height() > 0 && aOut.Width() > 0 )
+        {
+            aOut._Intersection( rRect );
+            pOut->DrawRect( aOut.SVRect() );
+        }
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFrm::PaintBorderLine()
+|*
+|*  Ersterstellung      MA 22. Dec. 92
+|*  Letzte Aenderung    MA 22. Jan. 95
+|*
+|*************************************************************************/
+
+void SwFrm::PaintBorderLine( const SwRect& rRect,
+                             const SwRect& rOutRect,
+                             const SwPageFrm *pPage,
+                             const Color *pColor ) const
+{
+    if ( !rOutRect.IsOver( rRect ) )
+        return;
+
+    SwRect aOut( rOutRect );
+    aOut._Intersection( rRect );
+
+    const SwTabFrm *pTab = IsCellFrm() ? FindTabFrm() : 0;
+    if ( pPage->GetSortedObjs() )
+    {
+        SwRegionRects aRegion( aOut, 4, 1 );
+        ::lcl_SubtractFlys( this, pPage, aOut, aRegion );
+        for ( USHORT i = 0; i < aRegion.Count(); ++i )
+            pLines->AddLineRect( aRegion[i], pColor, pTab );
+    }
+    else
+        pLines->AddLineRect( aOut, pColor, pTab );
+}
+
+/*************************************************************************
+|*
+|*  SwFrm::PaintBorderLines()
+|*
+|*  Beschreibung        Nur alle Linien einfach oder alle Linien doppelt!!!!
+|*  Ersterstellung      MA 22. Dec. 92
+|*  Letzte Aenderung    MA 22. Mar. 95
+|*
+|*************************************************************************/
+
+void MA_FASTCALL lcl_SubTopBottom( SwRect &rRect, const SvxBoxItem &rBox,
+                          const SwBorderAttrs &rAttrs, const SwFrm *pFrm )
+{
+    const BOOL bCnt = pFrm->IsCntntFrm();
+    if ( rBox.GetTop() && rBox.GetTop()->GetInWidth() &&
+         (!bCnt || rAttrs.GetTopLine( pFrm )) )
+    {
+        const long nDist = ::lcl_MinHeightDist( rBox.GetTop()->GetDistance() );
+        rRect.Top( rRect.Top() +
+                         ::lcl_AlignHeight( rBox.GetTop()->GetOutWidth() ) + nDist );
+    }
+
+    if ( rBox.GetBottom() && rBox.GetBottom()->GetInWidth() &&
+         (!bCnt || rAttrs.GetBottomLine( pFrm)))
+    {
+        const long nDist = ::lcl_MinHeightDist( rBox.GetBottom()->GetDistance() );
+        rRect.Bottom( rRect.Bottom() -
+                        (::lcl_AlignHeight( rBox.GetBottom()->GetOutWidth() + 1 ) +
+                         nDist));
+    }
+}
+
+void MA_FASTCALL lcl_SubLeftRight( SwRect &rRect, const SvxBoxItem &rBox )
+{
+    if ( rBox.GetLeft() && rBox.GetLeft()->GetInWidth() )
+    {
+        const long nDist = ::lcl_MinWidthDist( rBox.GetLeft()->GetDistance() );
+        rRect.Left( rRect.Left() +
+                        ::lcl_AlignWidth( rBox.GetLeft()->GetOutWidth() ) + nDist );
+    }
+
+    if ( rBox.GetRight() && rBox.GetRight()->GetInWidth() )
+    {
+        const long nDist = ::lcl_MinWidthDist( rBox.GetRight()->GetDistance() );
+        rRect.Right( rRect.Right() -
+                        (::lcl_AlignWidth( rBox.GetRight()->GetOutWidth() + 1 ) +
+                         nDist));
+    }
+}
+
+void MA_FASTCALL lcl_PaintLeftLine( const SwFrm *pFrm, const SwPageFrm *pPage,
+                           const SwRect &rOutRect, const SwRect &rRect,
+                           const SwBorderAttrs &rAttrs )
+{
+    const SvxBoxItem &rBox = rAttrs.GetBox();
+    const SvxBorderLine *pLeft = rBox.GetLeft();
+
+    if ( !pLeft )
+        return;
+
+    SwRect aRect( rOutRect );
+    aRect.Width( ::lcl_AlignWidth( pLeft->GetOutWidth() ) );
+
+    const BOOL bCnt = pFrm->IsCntntFrm();
+
+    if ( bCnt )
+        ::lcl_ExtendLeftAndRight( aRect, pFrm, rAttrs );
+
+    if ( !pLeft->GetInWidth() )
+        ::lcl_SubTopBottom( aRect, rBox, rAttrs, pFrm );
+
+    pFrm->PaintBorderLine( rRect, aRect, pPage, &pLeft->GetColor() );
+
+    if ( pLeft->GetInWidth() )
+    {
+        const long nDist = ::lcl_MinWidthDist( pLeft->GetDistance() );
+        aRect.Pos().X() = aRect.Right() + nDist;
+        aRect.Width( ::lcl_AlignWidth( pLeft->GetInWidth() ) );
+        ::lcl_SubTopBottom( aRect, rBox, rAttrs, pFrm );
+        pFrm->PaintBorderLine( rRect, aRect, pPage, &pLeft->GetColor() );
+    }
+}
+
+void MA_FASTCALL lcl_PaintRightLine( const SwFrm *pFrm, const SwPageFrm *pPage,
+                            const SwRect &rOutRect, const SwRect &rRect,
+                            const SwBorderAttrs &rAttrs )
+{
+    const SvxBoxItem &rBox = rAttrs.GetBox();
+    const SvxBorderLine *pRight = rBox.GetRight();
+
+    if ( !pRight )
+        return;
+
+    SwRect aRect( rOutRect );
+    aRect.Left( aRect.Right() - ::lcl_AlignWidth( pRight->GetOutWidth() ) + 1 );
+
+    const BOOL bCnt = pFrm->IsCntntFrm();
+
+    if ( bCnt )
+        ::lcl_ExtendLeftAndRight( aRect, pFrm, rAttrs );
+
+    if ( !pRight->GetInWidth() )
+        ::lcl_SubTopBottom( aRect, rBox, rAttrs, pFrm );
+
+    pFrm->PaintBorderLine( rRect, aRect, pPage, &pRight->GetColor() );
+
+    if ( pRight->GetInWidth() )
+    {
+        const long nDist = ::lcl_MinWidthDist( pRight->GetDistance() );
+        aRect.Right( aRect.Left() - nDist );
+        aRect.Left ( aRect.Right()- ::lcl_AlignWidth( pRight->GetInWidth()  ) + 1 );
+        ::lcl_SubTopBottom( aRect, rBox, rAttrs, pFrm );
+        pFrm->PaintBorderLine( rRect, aRect, pPage, &pRight->GetColor() );
+    }
+}
+
+void MA_FASTCALL lcl_PaintTopLine( const SwFrm *pFrm, const SwPageFrm *pPage,
+                          const SwRect &rOutRect, const SwRect &rRect,
+                          const SwBorderAttrs &rAttrs )
+{
+    const SvxBoxItem &rBox = rAttrs.GetBox();
+    const SvxBorderLine *pTop = rBox.GetTop();
+
+    if ( !pTop )
+        return;
+
+    SwRect aRect( rOutRect );
+    aRect.Height( ::lcl_AlignHeight( pTop->GetOutWidth() ) );
+    pFrm->PaintBorderLine( rRect, aRect, pPage, &pTop->GetColor() );
+
+    if ( pTop->GetInWidth() )
+    {
+        const long nDist = ::lcl_MinHeightDist( pTop->GetDistance() );
+        aRect.Pos().Y() = aRect.Bottom() + nDist;
+        aRect.Height( ::lcl_AlignHeight( pTop->GetInWidth() ) );
+        ::lcl_SubLeftRight( aRect, rBox );
+        pFrm->PaintBorderLine( rRect, aRect, pPage, &pTop->GetColor() );
+    }
+}
+
+void MA_FASTCALL lcl_PaintBottomLine( const SwFrm *pFrm, const SwPageFrm *pPage,
+                             const SwRect &rOutRect, const SwRect &rRect,
+                             const SwBorderAttrs &rAttrs )
+{
+    const SvxBoxItem &rBox = rAttrs.GetBox();
+    const SvxBorderLine *pBottom = rBox.GetBottom();
+
+    if ( !pBottom )
+        return;
+
+    SwRect aRect( rOutRect );
+    aRect.Top( aRect.Bottom() - ::lcl_AlignHeight( pBottom->GetOutWidth() ) + 1);
+    pFrm->PaintBorderLine( rRect, aRect, pPage, &pBottom->GetColor() );
+
+    if ( pBottom->GetInWidth() )
+    {
+        const long nDist = ::lcl_MinHeightDist( pBottom->GetDistance() );
+        aRect.Bottom( aRect.Top()   - nDist );
+        aRect.Top   ( aRect.Bottom()- ::lcl_AlignHeight( pBottom->GetInWidth()  ) + 1 );
+        ::lcl_SubLeftRight( aRect, rBox );
+        pFrm->PaintBorderLine( rRect, aRect, pPage, &pBottom->GetColor() );
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFrm::PaintBorder()
+|*
+|*  Beschreibung        Malt Schatten und Umrandung
+|*  Ersterstellung      MA 23.01.92
+|*  Letzte Aenderung    MA 29. Jul. 96
+|*
+|*************************************************************************/
+
+void SwFrm::PaintBorder( const SwRect& rRect, const SwPageFrm *pPage,
+                         const SwBorderAttrs &rAttrs ) const
+{
+    //fuer (Row,Body,Ftn,Root,Column,NoTxt) gibt's hier nix zu tun
+    if ( (GetType() & 0x90C5) || (Prt().SSize() == Frm().SSize()) )
+        return;
+
+    if ( (GetType() & 0x2000) &&    //Cell
+         !pGlobalShell->GetViewOptions()->IsTable() )
+        return;
+
+    const FASTBOOL bLine   = rAttrs.IsLine();
+    const FASTBOOL bShadow = rAttrs.GetShadow().GetLocation() != SVX_SHADOW_NONE;
+    if ( bLine || bShadow )
+    {
+        //Wenn das Rechteck vollstandig innerhalb der PrtArea liegt,
+        //so braucht kein Rand gepainted werden.
+        //Fuer die PrtArea muss der Aligned'e Wert zugrunde gelegt werden,
+        //anderfalls wuerden u.U. Teile nicht verarbeitet.
+        SwRect aRect( Prt() );
+        aRect += Frm().Pos();
+        ::SwAlignRect( aRect, pGlobalShell );
+        if ( aRect.IsInside( rRect ) )
+            return;
+
+        if ( !pPage )
+            pPage = FindPageFrm();
+
+        ::lcl_CalcBorderRect( aRect, this, rAttrs, TRUE );
+        rAttrs.SetGetCacheLine( TRUE );
+        if ( bShadow )
+            PaintShadow( rRect, aRect, pPage, rAttrs );
+        if ( bLine )
+        {
+            ::lcl_PaintLeftLine  ( this, pPage, aRect, rRect, rAttrs );
+            ::lcl_PaintRightLine ( this, pPage, aRect, rRect, rAttrs );
+            if ( !IsCntntFrm() || rAttrs.GetTopLine( this ) )
+                ::lcl_PaintTopLine( this, pPage, aRect, rRect, rAttrs );
+            if ( !IsCntntFrm() || rAttrs.GetBottomLine( this ) )
+                ::lcl_PaintBottomLine( this, pPage, aRect, rRect, rAttrs );
+        }
+        rAttrs.SetGetCacheLine( FALSE );
+    }
+}
+/*************************************************************************
+|*
+|*  SwFtnContFrm::PaintBorder()
+|*
+|*  Beschreibung        Spezialimplementierung wg. der Fussnotenlinie.
+|*      Derzeit braucht nur der obere Rand beruecksichtigt werden.
+|*      Auf andere Linien und Schatten wird verzichtet.
+|*  Ersterstellung      MA 27. Feb. 93
+|*  Letzte Aenderung    MA 08. Sep. 93
+|*
+|*************************************************************************/
+
+void SwFtnContFrm::PaintBorder( const SwRect& rRect, const SwPageFrm *pPage,
+                                const SwBorderAttrs & ) const
+{
+    //Wenn das Rechteck vollstandig innerhalb der PrtArea liegt, so gibt es
+    //keinen Rand zu painten.
+    SwRect aRect( Prt() );
+    aRect.Pos() += Frm().Pos();
+    if ( !aRect.IsInside( rRect ) )
+        PaintLine( rRect, pPage );
+}
+/*************************************************************************
+|*
+|*  SwFtnContFrm::PaintLine()
+|*
+|*  Beschreibung        Fussnotenline malen.
+|*  Ersterstellung      MA 02. Mar. 93
+|*  Letzte Aenderung    MA 28. Mar. 94
+|*
+|*************************************************************************/
+
+void SwFtnContFrm::PaintLine( const SwRect& rRect,
+                              const SwPageFrm *pPage ) const
+{
+    //Laenge der Linie ergibt sich aus der prozentualen Angabe am PageDesc.
+    //Die Position ist ebenfalls am PageDesc angegeben.
+    //Der Pen steht direkt im PageDesc.
+
+    if ( !pPage )
+        pPage = FindPageFrm();
+    const SwPageFtnInfo &rInf = pPage->GetPageDesc()->GetFtnInfo();
+
+    Fraction aFract( Prt().Width(), 1 );
+    const SwTwips nWidth = (long)(aFract *= rInf.GetWidth());
+
+    SwTwips nX = Frm().Left() + Prt().Left();
+    switch ( rInf.GetAdj() )
+    {
+        case FTNADJ_CENTER:
+            nX += Prt().Width()/2 - nWidth/2; break;
+        case FTNADJ_RIGHT:
+            nX = nX + Prt().Width() - nWidth; break;
+        case FTNADJ_LEFT:
+            /* do nothing */; break;
+        default:
+            ASSERT( !this, "Neues Adjustment fuer Fussnotenlinie?" );
+    }
+    const SwRect aLineRect( Point( nX, Frm().Pos().Y() + rInf.GetTopDist() ),
+                            Size( nWidth, rInf.GetLineWidth()));
+
+    if ( aLineRect.HasArea() )
+        PaintBorderLine( rRect, aLineRect , pPage, &rInf.GetLineColor() );
+}
+
+/*************************************************************************
+|*
+|*  SwLayoutFrm::PaintColLines()
+|*
+|*  Beschreibung        Painted die Trennlinien fuer die innenliegenden
+|*                      Spalten.
+|*  Ersterstellung      MA 21. Jun. 93
+|*  Letzte Aenderung    MA 28. Mar. 94
+|*
+|*************************************************************************/
+
+void SwLayoutFrm::PaintColLines( const SwRect &rRect, const SwFmtCol &rFmtCol,
+                                 const SwPageFrm *pPage ) const
+{
+    const SwFrm *pCol = Lower();
+    if ( !pCol || !pCol->IsColumnFrm() )
+        return;
+
+    //Laenge der Linie ergibt sich aus der prozentualen Angabe im Attribut.
+    //Die Position ist ebenfalls im Attribut angegeben.
+    //Der Pen steht direkt im Attribut.
+
+    const SwTwips nHeight = Prt().Height() * rFmtCol.GetLineHeight() / 100;
+
+    SwTwips nY = Frm().Top() + Prt().Top();
+    switch ( rFmtCol.GetLineAdj() )
+    {
+        case COLADJ_CENTER:
+            nY += Prt().Height()/2 - nHeight/2; break;
+        case COLADJ_BOTTOM:
+            nY = nY + Prt().Height() - nHeight; break;
+        case COLADJ_TOP:
+            /* do nothing */; break;
+        default:
+            ASSERT( !this, "Neues Adjustment fuer Spaltenlinie?" );
+    }
+
+    const Size aSz( rFmtCol.GetLineWidth(), nHeight );
+    const SwTwips nPenHalf = rFmtCol.GetLineWidth() / 2;
+
+    //Damit uns nichts verlorengeht muessen wir hier etwas grosszuegiger sein.
+    SwRect aRect( rRect );
+    aRect.Pos().X() -= rFmtCol.GetLineWidth() + nPixelSzW;
+    aRect.SSize().Width() += 2 * rFmtCol.GetLineWidth() + nPixelSzW;
+
+    while ( pCol->GetNext() )
+    {
+        const SwRect aLineRect( Point( pCol->Frm().Right() - nPenHalf, nY ),
+                                aSz );
+        if ( aRect.IsOver( aLineRect ) )
+            PaintBorderLine( aRect, aLineRect , pPage, &rFmtCol.GetLineColor() );
+        pCol = pCol->GetNext();
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwPageFrm::PaintAllBorders()
+|*
+|*  Beschreibung        Malt Schatten und Umrandung aller innenliegenden Frms
+|*  Ersterstellung      MA 23. Jan. 95
+|*  Letzte Aenderung    MA 06. May. 95
+|*
+|*************************************************************************/
+
+void MA_FASTCALL lcl_PaintLowerBorders( const SwLayoutFrm *pLay,
+                               const SwRect &rRect, const SwPageFrm *pPage )
+{
+    const SwFrm *pFrm = pLay->Lower();
+    if ( pFrm )
+    {
+        OutputDevice *pOut = pGlobalShell->GetOut();
+        pOut->Push( PUSH_FILLCOLOR );
+        do
+        {   if ( pFrm->Frm().IsOver( rRect ) )
+            {
+                if ( pFrm->IsLayoutFrm() )
+                    ::lcl_PaintLowerBorders( (SwLayoutFrm*)pFrm, rRect, pPage );
+
+                SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)pFrm );
+                const SwBorderAttrs &rAttrs = *aAccess.Get();
+                pFrm->PaintBorder( rRect, pPage, rAttrs );
+            }
+            pFrm = pFrm->GetNext();
+
+        } while ( pFrm && !::IsShortCut( rRect, pFrm->Frm() ) );
+        pOut->Pop();
+    }
+}
+
+void SwPageFrm::PaintAllBorders( const SwRect &rRect ) const
+{
+    ::lcl_PaintLowerBorders( this, rRect, this );
+}
+/*************************************************************************
+|*
+|*  SwFrm::PaintBaBo()
+|*
+|*  Ersterstellung      MA 22. Oct. 93
+|*  Letzte Aenderung    MA 19. Jun. 96
+|*
+|*************************************************************************/
+
+void SwFrm::PaintBaBo( const SwRect& rRect, const SwPageFrm *pPage,
+                       const BOOL bLowerBorder ) const
+{
+    if ( !pPage )
+        pPage = FindPageFrm();
+
+    OutputDevice *pOut = pGlobalShell->GetOut();
+    pOut->Push( PUSH_FILLCOLOR );
+
+    SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)this );
+    const SwBorderAttrs &rAttrs = *aAccess.Get();
+
+/*  //FlyInCnt's kommen hier aus der ::Retouche hier an.
+    FASTBOOL bUnlock = FALSE;
+    if ( IsFlyFrm() && ((SwFlyFrm*)this)->IsFlyInCntFrm() )
+    {
+        bLockFlyBackground = bUnlock = TRUE;
+        const SwFlyFrm *pFly = (const SwFlyFrm*)this;
+        SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFly );
+        const SwBorderAttrs &rAttrs = *aAccess.Get();
+        pFly->GetAnchor()->PaintBackground( rRect, pPage, rAttrs, FALSE );
+    }
+*/
+    PaintBackground( rRect, pPage, rAttrs, FALSE, bLowerBorder );
+    SwRect aRect( rRect );
+    ::SizeBorderRect( aRect );
+    PaintBorder( aRect, pPage, rAttrs );
+/*  if ( bUnlock )
+        bLockFlyBackground = FALSE;
+*/
+    pOut->Pop();
+}
+
+/*************************************************************************
+|*
+|*  SwFrm::PaintBackground()
+|*
+|*  Ersterstellung      MA 04. Jan. 93
+|*  Letzte Aenderung    MA 06. Feb. 97
+|*
+|*************************************************************************/
+
+void SwFrm::PaintBackground( const SwRect &rRect, const SwPageFrm *pPage,
+                              const SwBorderAttrs & rAttrs,
+                             const BOOL bLowerMode,
+                             const BOOL bLowerBorder ) const
+{
+    FASTBOOL bResetPageOnly = FALSE;
+
+    ViewShell *pSh = pGlobalShell;
+    const FASTBOOL bWin = pSh->GetWin() ? TRUE : FALSE;
+    const SvxBrushItem* pItem;
+    const Color* pCol;
+    SwRect aOrigBackRect;
+    FASTBOOL bBack= GetBackgroundBrush( pItem, pCol, aOrigBackRect, bLowerMode );
+    const FASTBOOL bPageFrm = IsPageFrm();
+    FASTBOOL bLowMode = TRUE;
+
+    //- Ausgabe wenn ein eigener Hintergrund mitgebracht wird.
+    //- Retouche fuer durchsichtige Flys muss vom Hintergrund des Flys
+    //  uebernommen werden.
+    //  ->Selbiges fuer Flys die eine Grafik enthalten.
+    FASTBOOL bFlyBackground = !bFlyMetafile && !bBack && IsFlyFrm();
+    if ( bFlyBackground && (!GetLower() || !((SwFlyFrm*)this)->Lower()->IsNoTxtFrm()) )
+         bPageOnly = bResetPageOnly = TRUE;
+
+    SwRect aPaintRect( Frm() );
+    if( IsTxtFrm() )
+        aPaintRect = UnionFrm( TRUE );
+
+    if ( aPaintRect.IsOver( rRect ) )
+    {
+    if ( bFlyBackground )
+    {
+        const SwFrm *pBackFrm = bPageOnly || !((SwFlyFrm*)this)->GetAnchor()->IsInFly()
+                            ? (SwFrm*)pPage
+                            : ((SwFlyFrm*)this)->GetAnchor()->FindFlyFrm();
+
+        SwFlyFrm *pOld = pRetoucheFly;
+        pRetoucheFly = (SwFlyFrm*)this;
+
+        SwRect aRect;
+        ::lcl_CalcBorderRect( aRect, this, rAttrs, FALSE );
+        aRect.Intersection( rRect );
+        pBackFrm->PaintBaBo( aRect, pPage, bLowerBorder );
+        pRetoucheFly = pOld;
+        //Clipping muss aufgehoben werden, weil vom Formatter oft ein Clipping
+        //gesetzt wird.
+        OutputDevice *pOut = pSh->GetOut();
+        pOut->Push( PUSH_CLIPREGION );
+        pOut->SetClipRegion();
+        pLines->PaintLines( GetShell()->GetOut() );
+        pOut->Pop();
+
+    }
+    else if ( bBack || bPageFrm || !bLowerMode )
+    {
+        const FASTBOOL bBrowse = pSh->GetDoc()->IsBrowseMode();
+
+        SwRect aRect;
+        if ( (bPageFrm && bBrowse) ||
+             (IsTxtFrm() && Prt().SSize() == Frm().SSize()) )
+        {
+            aRect = Frm();
+            ::SwAlignRect( aRect, pGlobalShell );
+        }
+        else
+        {
+            ::lcl_CalcBorderRect( aRect, this, rAttrs, FALSE );
+            if ( (IsTxtFrm() || IsTabFrm()) && GetPrev() )
+            {
+                if ( GetPrev()->GetAttrSet()->GetBackground() ==
+                     GetAttrSet()->GetBackground() )
+                {
+                    aRect.Top( Frm().Top() );
+                }
+            }
+        }
+        aRect.Intersection( rRect );
+
+        OutputDevice *pOut = pSh->GetOut();
+
+        if ( bPageFrm && bWin && !bBrowse )
+        {
+            //Irgendjemand muss sich um den Rand der Seite kuemmern. Eine Farbe
+            //kann fuer diesen Rand niemals angegeben sein.
+            SwRect aPgRect( Prt() );
+            aPgRect.Pos() += Frm().Pos();
+            if ( !aPgRect.IsInside( rRect ) )
+            {
+                aPgRect = Frm();
+                aPgRect._Intersection( rRect );
+                SwRegionRects aPgRegion( aPgRect );
+                aPgRegion -= aRect;
+                if ( pPage->GetSortedObjs() )
+                    ::lcl_SubtractFlys( this, pPage, aPgRect, aPgRegion );
+                if ( aPgRegion.Count() )
+                {
+                    if ( pOut->GetFillColor() != aGlobalRetoucheColor )
+                        pOut->SetFillColor( aGlobalRetoucheColor );
+                    for ( USHORT i = 0; i < aPgRegion.Count(); ++i )
+                    {
+                        if ( 1 < aPgRegion.Count() )
+                        {
+                            ::SwAlignRect( aPgRegion[i], pGlobalShell );
+                            if( !aPgRegion[i].HasArea() )
+                                continue;
+                        }
+                        pOut->DrawRect( aPgRegion[i].SVRect() );
+                    }
+                }
+            }
+        }
+        if ( aRect.HasArea() )
+        {
+            SvxBrushItem* pNewItem;
+            SwRegionRects aRegion( aRect );
+            if( pCol )
+            {
+                pNewItem = new SvxBrushItem( *pCol );
+                pItem = pNewItem;
+            }
+            if ( pPage->GetSortedObjs() )
+                ::lcl_SubtractFlys( this, pPage, aRect, aRegion );
+            for ( USHORT i = 0; i < aRegion.Count(); ++i )
+            {
+                if ( 1 < aRegion.Count() )
+                {
+                    ::SwAlignRect( aRegion[i], pGlobalShell );
+                    if( !aRegion[i].HasArea() )
+                        continue;
+                }
+                ::DrawGraphic( pItem, pOut, aOrigBackRect, aRegion[i] );
+            }
+            if( pCol )
+                delete pNewItem;
+        }
+    }
+    else
+        bLowMode = bLowerMode ? TRUE : FALSE;
+    }
+    if ( bResetPageOnly )
+        bPageOnly = FALSE;
+
+    //Jetzt noch Lower und dessen Nachbarn.
+    //Wenn ein Frn dabei die Kette verlaesst also nicht mehr Lower von mir ist
+    //so hoert der Spass auf.
+    const SwFrm *pFrm = GetLower();
+    if ( !bPageOnly && pFrm )
+    {
+        SwRect aFrmRect;
+        SwRect aRect( PaintArea() );
+        aRect._Intersection( rRect );
+        SwRect aBorderRect( aRect );
+        ::SizeBorderRect( aBorderRect );
+        do
+        {   if ( pProgress )
+                pProgress->Reschedule();
+
+            aFrmRect = pFrm->PaintArea();
+            if ( aFrmRect.IsOver( aBorderRect ) )
+            {
+                SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)pFrm );
+                const SwBorderAttrs &rAttrs = *aAccess.Get();
+                if ( ( pFrm->IsLayoutFrm() && bLowerBorder ) ||
+                     aFrmRect.IsOver( aRect ) )
+                    pFrm->PaintBackground( aRect, pPage, rAttrs, bLowMode,
+                                           bLowerBorder );
+                if ( bLowerBorder )
+                    pFrm->PaintBorder( aBorderRect, pPage, rAttrs );
+            }
+            pFrm = pFrm->GetNext();
+        } while ( pFrm && pFrm->GetUpper() == this &&
+                  !::IsShortCut( aBorderRect, aFrmRect ) );
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwPageFrm::RefreshSubsidiary()
+|*
+|*  Beschreibung        Erneuert alle Hilfslinien der Seite.
+|*  Ersterstellung      MA 04. Nov. 92
+|*  Letzte Aenderung    MA 10. May. 95
+|*
+|*************************************************************************/
+
+void SwPageFrm::RefreshSubsidiary( const SwRect &rRect ) const
+{
+    if ( IS_SUBS || IS_SUBS_TABLE || IS_SUBS_SECTION )
+    {
+        SwRect aRect( rRect );
+        ::SwAlignRect( aRect, pGlobalShell );
+        if ( aRect.HasArea() )
+        {
+            //Beim Paint ueber die Root wird das Array von dort gesteuert.
+            //Anderfalls kuemmern wir uns selbst darum.
+            FASTBOOL bDelSubs = FALSE;
+            if ( !pSubsLines )
+            {
+                pSubsLines = new SwSubsRects;
+                bDelSubs = TRUE;
+            }
+
+            RefreshLaySubsidiary( this, aRect );
+            if ( GetSortedObjs() )
+            {
+                const SwSortDrawObjs &rObjs = *GetSortedObjs();
+                for ( USHORT i = 0; i < rObjs.Count(); ++i )
+                {
+                    SdrObject *pO = rObjs[i];
+                    if ( pO->IsWriterFlyFrame() )
+                    {
+                        const SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+                        if ( pFly->Frm().IsOver( aRect ) )
+                        {
+                            if ( !pFly->Lower() || !pFly->Lower()->IsNoTxtFrm() ||
+                                    !((SwNoTxtFrm*)pFly->Lower())->HasAnimation())
+                                pFly->RefreshLaySubsidiary( this, aRect );
+                        }
+                    }
+                }
+            }
+            if ( bDelSubs )
+            {
+                pSubsLines->PaintSubsidiary( pGlobalShell->GetOut(), pLines );
+                DELETEZ( pSubsLines );
+            }
+        }
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwLayoutFrm::RefreshLaySubsidiary()
+|*
+|*  Ersterstellung      MA 04. Nov. 92
+|*  Letzte Aenderung    MA 22. Jan. 95
+|*
+|*************************************************************************/
+
+void SwLayoutFrm::RefreshLaySubsidiary( const SwPageFrm *pPage,
+                                        const SwRect &rRect ) const
+{
+    const FASTBOOL bNoLowerColumn = !Lower() || !Lower()->IsColumnFrm();
+    const FASTBOOL bSubsOpt   = IS_SUBS;
+    const FASTBOOL bSubsTable = ((GetType() & (FRM_ROW | FRM_CELL)) && IS_SUBS_TABLE);
+    const FASTBOOL bSubsOther = (GetType() & (FRM_HEADER | FRM_FOOTER | FRM_FTN )) && bSubsOpt;
+    const FASTBOOL bSubsSect  = IsSctFrm() &&
+                                bNoLowerColumn &&
+                                IS_SUBS_SECTION;
+    const FASTBOOL bSubsFly   = (GetType() & FRM_FLY) &&
+                                bSubsOpt &&
+                                bNoLowerColumn &&
+                                (!Lower() || !Lower()->IsNoTxtFrm() ||
+                                 !((SwNoTxtFrm*)Lower())->HasAnimation());
+    FASTBOOL bSubsBody = FALSE;
+    if ( GetType() & FRM_BODY )
+    {
+        if ( IsPageBodyFrm() )
+            bSubsBody = bSubsOpt && bNoLowerColumn;                                 //nur ohne Spalten
+        else    //Spaltenbody
+        {
+            if ( GetUpper()->GetUpper()->IsSctFrm() )
+                bSubsBody = IS_SUBS_SECTION;
+            else
+                bSubsBody = bSubsOpt;
+        }
+    }
+
+    if ( bSubsOther || bSubsSect  || bSubsBody || bSubsTable || bSubsFly )
+        PaintSubsidiaryLines( pPage, rRect );
+
+    const SwFrm *pLow = Lower();
+    while ( pLow && !::IsShortCut( rRect, pLow->Frm() ) )
+    {   if ( pLow->Frm().IsOver( rRect ) && pLow->Frm().HasArea() )
+        {
+            if ( pLow->IsLayoutFrm() )
+                ((const SwLayoutFrm*)pLow)->RefreshLaySubsidiary( pPage, rRect);
+            else if ( pLow->GetDrawObjs() )
+            {
+                const SwDrawObjs &rObjs = *pLow->GetDrawObjs();
+                for ( USHORT i = 0; i < rObjs.Count(); ++i )
+                {
+                    SdrObject *pO = rObjs[i];
+                    if ( pO->IsWriterFlyFrame() )
+                    {
+                        const SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+                        if ( pFly->IsFlyInCntFrm() && pFly->Frm().IsOver( rRect ) )
+                        {
+                            if ( !pFly->Lower() || !pFly->Lower()->IsNoTxtFrm() ||
+                                 !((SwNoTxtFrm*)pFly->Lower())->HasAnimation())
+                                pFly->RefreshLaySubsidiary( pPage, rRect );
+                        }
+                    }
+                }
+            }
+        }
+        pLow = pLow->GetNext();
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwLayoutFrm::PaintSubsidiaryLines()
+|*
+|*  Beschreibung        Hilfslinien um die PrtAreas malen
+|*      Nur die LayoutFrm's die direkt Cntnt enthalten.
+|*  Ersterstellung      MA 21. May. 92
+|*  Letzte Aenderung    MA 22. Jan. 95
+|*
+|*************************************************************************/
+
+//Malt die angegebene Linie, achtet darauf, dass keine Flys uebermalt werden.
+
+void MA_FASTCALL lcl_RefreshLine( const SwLayoutFrm *pLay, const SwPageFrm *pPage,
+                         const Point &rP1, const Point &rP2, const BYTE nSubColor )
+{
+    //In welche Richtung gehts? Kann nur Horizontal oder Vertikal sein.
+    ASSERT( ((rP1.X() == rP2.X()) || (rP1.Y() == rP2.Y())),
+            "Schraege Hilfslinien sind nicht erlaubt." );
+    const PtPtr pDirPt = rP1.X() == rP2.X() ? pY : pX;
+    const PtPtr pOthPt = pDirPt == pX ? pY : pX;
+    const SzPtr pDirSz = pDirPt == pX ? pWidth : pHeight;
+    const SzPtr pOthSz = pDirSz == pWidth ? pHeight : pWidth;
+    Point aP1( rP1 ),
+          aP2( rP2 );
+
+    while ( aP1.*pDirPt < aP2.*pDirPt )
+    {   //Der Startpunkt wird jetzt, falls er in einem Fly sitzt, direkt
+        //hinter den Fly gesetzt.
+        //Wenn der Endpunkt in einem Fly sitzt oder zwischen Start und Endpunkt
+        //ein Fly sitzt, so wird der Endpunkt eben an den Start herangezogen.
+        //Auf diese art und weise wird eine Portion nach der anderen
+        //ausgegeben.
+
+        //Wenn ich selbst ein Fly bin, weiche ich nur denjenigen Flys aus,
+        //die 'ueber' mir sitzen; d.h. die in dem Array hinter mir stehen.
+        //Auch wenn ich in einem Fly sitze oder in einem Fly im Fly usw. weiche
+        //ich keinem dieser Flys aus.
+        SwOrderIter aIter( pPage );
+        const SwFlyFrm *pMyFly = pLay->FindFlyFrm();
+        if ( pMyFly )
+        {
+            aIter.Current( pMyFly->GetVirtDrawObj() );
+            while ( 0 != (pMyFly = pMyFly->GetAnchor()->FindFlyFrm()) )
+            {
+                if ( aIter()->GetOrdNum() > pMyFly->GetVirtDrawObj()->GetOrdNum() )
+                    aIter.Current( pMyFly->GetVirtDrawObj() );
+            }
+        }
+        else
+            aIter.Bottom();
+
+        while ( aIter() )
+        {
+            const SwVirtFlyDrawObj *pObj = (SwVirtFlyDrawObj*)aIter();
+            const SwFlyFrm *pFly = pObj ? pObj->GetFlyFrm() : 0;
+
+            //Mir selbst weiche ich natuerlich nicht aus. Auch wenn ich
+            //_in_ dem Fly sitze weiche ich nicht aus.
+            if ( !pFly || (pFly == pLay || pFly->IsAnLower( pLay )) )
+            {   aIter.Next();
+                continue;
+            }
+
+            //Sitzt das Obj auf der Linie
+            const Rectangle &rBound = pObj->GetBoundRect();
+            const Point aDrPt( rBound.TopLeft() );
+            const Size  aDrSz( rBound.GetSize() );
+            if ( rP1.*pOthPt >= aDrPt.*pOthPt &&
+                 rP1.*pOthPt <= (aDrPt.*pOthPt + aDrSz.*pOthSz) )
+            {
+                if ( aP1.*pDirPt >= aDrPt.*pDirPt &&
+                         aP1.*pDirPt <= (aDrPt.*pDirPt + aDrSz.*pDirSz) )
+                    aP1.*pDirPt = aDrPt.*pDirPt + aDrSz.*pDirSz;
+
+                if ( aP2.*pDirPt >= aDrPt.*pDirPt &&
+                     aP1.*pDirPt < (aDrPt.*pDirPt - 1) )
+                    aP2.*pDirPt = aDrPt.*pDirPt - 1;
+            }
+            aIter.Next();
+        }
+
+        if ( aP1.*pDirPt < aP2.*pDirPt )
+        {
+            SwRect aRect( aP1, aP2 );
+            pSubsLines->AddLineRect( aRect, 0, 0, nSubColor );
+        }
+        aP1 = aP2;
+        aP1.*pDirPt += 1;
+        aP2 = rP2;
+    }
+}
+
+void SwLayoutFrm::PaintSubsidiaryLines( const SwPageFrm *pPage,
+                                        const SwRect &rRect ) const
+{
+    //Wenn die Linien der Zellen nicht durchgehen siehts irgendwie nicht so
+    //Toll aus; deswegen wird fuer die Zellen der Frm benutzt.
+    const FASTBOOL bCell = IsCellFrm();
+    const FASTBOOL bFlys = pPage->GetSortedObjs() ? TRUE : FALSE;
+    SwRect aOriginal( bCell ? Frm() : Prt() );
+    if ( !bCell )
+        aOriginal.Pos() += Frm().Pos();
+
+    ::SwAlignRect( aOriginal, pGlobalShell );
+    if ( !aOriginal.IsOver( rRect ) )
+        return;
+
+    SwRect aOut( aOriginal );
+    aOut._Intersection( rRect );
+    aOut.Intersection( PaintArea() );
+
+    const SwTwips nRight = aOut.Right();
+    const SwTwips nBottom= aOut.Bottom();
+
+    const Point aRT( nRight, aOut.Top() );
+    const Point aRB( nRight, nBottom );
+    const Point aLB( aOut.Left(), nBottom );
+
+    BYTE nSubColor = SUBCOL_STANDARD;
+    const SvxBrushItem &rBrush = pPage->GetFmt()->GetBackground();
+    const Color aTmp( COL_LIGHTGRAY );
+    if ( rBrush.GetColor() == aTmp ||
+         (rBrush.GetColor().GetTransparency() &&
+          aGlobalRetoucheColor == aTmp ))
+    {
+        nSubColor = SUBCOL_GRAY;
+    }
+
+    BOOL bBreak = FALSE;
+    if ( GetType() & 0x0084 ) //Body oder Column
+    {
+        const SwCntntFrm *pCnt = ContainsCntnt();
+        if ( pCnt )
+        {
+            if ( FALSE == (bBreak = pCnt->IsPageBreak( TRUE )) && IsColumnFrm() )
+                bBreak = pCnt->IsColBreak( TRUE );
+        }
+    }
+
+    if ( bFlys )
+    {
+        if ( aOriginal.Left() == aOut.Left() )
+            ::lcl_RefreshLine( this, pPage, aOut.Pos(), aLB, nSubColor );
+        if ( aOriginal.Right() == nRight )
+            ::lcl_RefreshLine( this, pPage, aRT, aRB, nSubColor );
+        if ( !bCell )
+        {
+            if ( aOriginal.Top() == aOut.Top() )
+                ::lcl_RefreshLine( this, pPage, aOut.Pos(), aRT,
+                                   bBreak ? SUBCOL_BREAK : nSubColor );
+            if ( aOriginal.Bottom() == nBottom )
+                ::lcl_RefreshLine( this, pPage, aLB, aRB, nSubColor );
+        }
+    }
+    else
+    {
+        if ( aOriginal.Left() == aOut.Left() )
+        {
+            SwRect aRect( aOut.Pos(), aLB );
+            pSubsLines->AddLineRect( aRect, 0, 0, nSubColor );
+        }
+        if ( aOriginal.Right() == nRight )
+        {
+            SwRect aRect( aRT, aRB );
+            pSubsLines->AddLineRect( aRect, 0, 0, nSubColor );
+        }
+        if ( !bCell )
+        {
+            if ( aOriginal.Top() == aOut.Top() )
+            {
+                SwRect aRect( aOut.Pos(), aRT );
+                pSubsLines->AddLineRect( aRect, 0, 0,
+                                         bBreak ? SUBCOL_BREAK : nSubColor );
+            }
+            if ( aOriginal.Bottom() == nBottom )
+            {
+                SwRect aRect( aLB, aRB );
+                pSubsLines->AddLineRect( aRect, 0, 0, nSubColor );
+            }
+        }
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwPageFrm::RefreshExtraData(), SwLayoutFrm::RefreshExtraData()
+|*
+|*  Beschreibung        Erneuert alle Extradaten (Zeilennummern usw) der Seite.
+|*                      Grundsaetzlich sind nur diejenigen Objekte beruecksichtig,
+|*                      die in die seitliche Ausdehnung des Rects ragen.
+|*  Ersterstellung      MA 20. Jan. 98
+|*  Letzte Aenderung    MA 18. Feb. 98
+|*
+|*************************************************************************/
+
+void SwPageFrm::RefreshExtraData( const SwRect &rRect ) const
+{
+    const SwLineNumberInfo &rInfo = GetFmt()->GetDoc()->GetLineNumberInfo();
+    FASTBOOL bLineInFly = rInfo.IsPaintLineNumbers() && rInfo.IsCountInFlys()
+        || (SwHoriOrient)SW_MOD()->GetRedlineMarkPos() != HORI_NONE;
+
+    SwRect aRect( rRect );
+    ::SwAlignRect( aRect, pGlobalShell );
+    if ( aRect.HasArea() )
+    {
+        SwLayoutFrm::RefreshExtraData( aRect );
+
+        if ( bLineInFly && GetSortedObjs() )
+            for ( USHORT i = 0; i < GetSortedObjs()->Count(); ++i )
+            {
+                SdrObject *pO = (*GetSortedObjs())[i];
+                if ( pO->IsWriterFlyFrame() )
+                {
+                    const SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+                    if ( pFly->Frm().Top() <= aRect.Bottom() &&
+                         pFly->Frm().Bottom() >= aRect.Top() )
+                        pFly->RefreshExtraData( aRect );
+                }
+            }
+    }
+}
+
+void SwLayoutFrm::RefreshExtraData( const SwRect &rRect ) const
+{
+
+    const SwLineNumberInfo &rInfo = GetFmt()->GetDoc()->GetLineNumberInfo();
+    FASTBOOL bLineInBody = rInfo.IsPaintLineNumbers(),
+             bLineInFly  = bLineInBody && rInfo.IsCountInFlys(),
+             bRedLine = (SwHoriOrient)SW_MOD()->GetRedlineMarkPos()!=HORI_NONE;
+
+    const SwCntntFrm *pCnt = ContainsCntnt();
+    while ( pCnt && IsAnLower( pCnt ) )
+    {
+        if ( pCnt->IsTxtFrm() && ( bRedLine ||
+             ( !pCnt->IsInTab() &&
+               ((bLineInBody && pCnt->IsInDocBody()) ||
+               (bLineInFly  && pCnt->IsInFly())) ) ) &&
+             pCnt->Frm().Top() <= rRect.Bottom() &&
+             pCnt->Frm().Bottom() >= rRect.Top() )
+        {
+            ((SwTxtFrm*)pCnt)->PaintExtraData( rRect );
+        }
+        if ( bLineInFly && pCnt->GetDrawObjs() )
+            for ( USHORT i = 0; i < pCnt->GetDrawObjs()->Count(); ++i )
+            {
+                SdrObject *pO = (*pCnt->GetDrawObjs())[i];
+                if ( pO->IsWriterFlyFrame() )
+                {
+                    const SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+                    if ( pFly->IsFlyInCntFrm() &&
+                         pFly->Frm().Top() <= rRect.Bottom() &&
+                         pFly->Frm().Bottom() >= rRect.Top() )
+                        pFly->RefreshExtraData( rRect );
+                }
+        }
+        pCnt = pCnt->GetNextCntntFrm();
+    }
+}
+
+/*************************************************************************
+|*
+|*    SwFrm::Retouche
+|*
+|*    Beschreibung      Retouche fuer einen Bereich.
+|*      Retouche wird nur dann durchgefuehrt, wenn der Frm der letzte seiner
+|*      Kette ist. Der Gesamte Bereich des Upper unterhalb des Frm wird
+|*      per PaintBackground gecleared.
+|*    Ersterstellung    MA 13. Apr. 93
+|*    Letzte Aenderung  MA 25. Jul. 96
+|*
+|*************************************************************************/
+
+void SwFrm::Retouche( const SwPageFrm * pPage, const SwRect &rRect ) const
+{
+    if ( bFlyMetafile )
+        return;
+
+    ASSERT( GetUpper(), "Retoucheversuch ohne Upper." );
+    ASSERT( GetShell() && pGlobalShell->GetWin(), "Retouche auf dem Drucker?" );
+
+    SwRect aRetouche( GetUpper()->PaintArea() );
+    aRetouche.Top( Frm().Top() + Frm().Height() );
+    aRetouche.Intersection( pGlobalShell->VisArea() );
+
+    if ( aRetouche.HasArea() )
+    {
+        //Uebergebenes Rect ausparen. Dafuer brauchen wir leider eine Region
+        //zum ausstanzen.
+        SwRegionRects aRegion( aRetouche );
+        aRegion -= rRect;
+        ViewShell *pSh = GetShell();
+        for ( USHORT i = 0; i < aRegion.Count(); ++i )
+        {
+            SwRect &rRetouche = aRegion[i];
+
+            GetUpper()->PaintBaBo( rRetouche, pPage, TRUE );
+
+            //Hoelle und Himmel muessen auch refreshed werden.
+            //Um Rekursionen zu vermeiden muss mein Retouche Flag zuerst
+            //zurueckgesetzt werden!
+            ResetRetouche();
+            SwRect aRetouche( rRetouche );
+            ::SizeBorderRect( aRetouche );
+            pSh->Imp()->PaintLayer( pSh->GetDoc()->GetHellId(), aRetouche );
+            pSh->Imp()->PaintLayer( pSh->GetDoc()->GetHeavenId(), aRetouche );
+            pSh->Imp()->PaintLayer( pSh->GetDoc()->GetControlsId(), aRetouche );
+            SetRetouche();
+
+            //Da wir uns ausserhalb aller Paint-Bereiche begeben muessen hier
+            //leider die Hilfslinien erneuert werden.
+            pPage->RefreshSubsidiary( aRetouche );
+        }
+    }
+    if ( ViewShell::IsLstEndAction() )
+        ResetRetouche();
+}
+
+/*************************************************************************
+|*
+|*  SwFrm::GetBackgroundBrush()
+|*
+|*  Beschreibung        Liefert die Backgroundbrush fuer den Bereich des
+|*      des Frm. Die Brush wird entweder von ihm selbst oder von einem
+|*      Upper vorgegeben, die erste Brush wird benutzt.
+|*      Ist fuer keinen Frm eine Brush angegeben, so wird FALSE zurueck-
+|*      geliefert.
+|*  Ersterstellung      MA 23. Dec. 92
+|*  Letzte Aenderung    MA 04. Feb. 97
+|*
+|*************************************************************************/
+
+BOOL SwFrm::GetBackgroundBrush( const SvxBrushItem* & rpBrush,
+                                const Color*& rpCol,
+                                SwRect &rOrigRect,
+                                BOOL bLowerMode ) const
+{
+    const SwFrm *pFrm = this;
+    ViewShell *pSh = GetShell();
+    const SwViewOption *pOpt = pSh->GetViewOptions();
+    rpBrush = 0;
+    rpCol = NULL;
+    do
+    {   if ( pFrm->IsPageFrm() && !pOpt->IsPageBack() )
+            return FALSE;
+
+        const SvxBrushItem &rBack = pFrm->GetAttrSet()->GetBackground();
+        if( pFrm->IsSctFrm() )
+        {
+            const SwSection* pSection = ((SwSectionFrm*)pFrm)->GetSection();
+            if( pSection && ( TOX_HEADER_SECTION == pSection->GetType() ||
+                TOX_CONTENT_SECTION == pSection->GetType() ) &&
+                rBack.GetColor().GetTransparency() &&
+                rBack.GetGraphicPos() == GPOS_NONE && pOpt->IsIndexBackground() &&
+                pSh->GetOut()->GetOutDevType() != OUTDEV_PRINTER )
+                rpCol = &pOpt->GetIndexBackgrndColor();
+        }
+        if ( !rBack.GetColor().GetTransparency() ||
+             rBack.GetGraphicPos() != GPOS_NONE || rpCol )
+        {
+            rpBrush = &rBack;
+            if ( pFrm->IsPageFrm() && pSh->GetDoc()->IsBrowseMode() )
+                rOrigRect = pFrm->Frm();
+            else
+            {
+                if ( pFrm->Frm().SSize() != pFrm->Prt().SSize() )
+                {
+                    SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFrm );
+                    const SwBorderAttrs &rAttrs = *aAccess.Get();
+                    ::lcl_CalcBorderRect( rOrigRect, pFrm, rAttrs, FALSE );
+                }
+                else
+                {
+                    rOrigRect = pFrm->Prt();
+                    rOrigRect += pFrm->Frm().Pos();
+                }
+            }
+            return TRUE;
+        }
+        if ( bLowerMode )
+            return FALSE;
+        if ( pFrm->IsFlyFrm() )
+            pFrm = ((SwFlyFrm*)pFrm)->GetAnchor();
+        else
+            pFrm = pFrm->GetUpper();
+    } while ( pFrm );
+    return FALSE;
+}
+
+/*************************************************************************
+|*
+|*  SwFrmFmt::GetGraphic()
+|*
+|*  Ersterstellung      MA 23. Jul. 96
+|*  Letzte Aenderung    MA 23. Jul. 96
+|*
+|*************************************************************************/
+
+void SetOutDevAndWin( ViewShell *pSh, OutputDevice *pO,
+                      Window *pW, USHORT nZoom )
+{
+    pSh->pOut = pO;
+    pSh->pWin = pW;
+    pSh->pOpt->SetZoom( nZoom );
+}
+
+Graphic SwFrmFmt::MakeGraphic( ImageMap* pMap )
+{
+    return Graphic();
+}
+
+Graphic SwFlyFrmFmt::MakeGraphic( ImageMap* pMap )
+{
+    Graphic aRet;
+    //irgendeinen Fly suchen!
+    SwClientIter aIter( *this );
+    SwClient *pFirst = aIter.First( TYPE(SwFrm) );
+    ViewShell *pSh;
+    if ( pFirst && 0 != ( pSh = ((SwFrm*)pFirst)->GetShell()) )
+    {
+        ViewShell *pOldGlobal = pGlobalShell;
+        pGlobalShell = pSh;
+
+        FASTBOOL bNoteURL = pMap &&
+            SFX_ITEM_SET != GetAttrSet().GetItemState( RES_URL, TRUE );
+        if( bNoteURL )
+        {
+            ASSERT( !pNoteURL, "MakeGraphic: pNoteURL already used? " );
+            pNoteURL = new SwNoteURL;
+        }
+        SwFlyFrm *pFly = (SwFlyFrm*)pFirst;
+
+        OutputDevice *pOld = pSh->GetOut();
+        VirtualDevice aDev( *pOld );
+        aDev.EnableOutput( FALSE );
+
+        GDIMetaFile aMet;
+        MapMode aMap( pOld->GetMapMode().GetMapUnit() );
+        aDev.SetMapMode( aMap );
+        aMet.SetPrefMapMode( aMap );
+
+        ::SwCalcPixStatics( pSh->GetOut() );
+        aMet.SetPrefSize( pFly->Frm().SSize() );
+
+        aMet.Record( &aDev );
+        aDev.SetLineColor();
+        aDev.SetFillColor();
+        aDev.SetFont( pOld->GetFont() );
+
+        Window *pWin = pSh->GetWin();
+        USHORT nZoom = pSh->GetViewOptions()->GetZoom();
+        ::SetOutDevAndWin( pSh, &aDev, 0, 100 );
+        bFlyMetafile = TRUE;
+        pFlyMetafileOut = pWin;
+
+        SwViewImp *pImp = pSh->Imp();
+        pFlyOnlyDraw = pFly;
+        pLines = new SwLineRects;
+
+        //Rechteck ggf. ausdehnen, damit die Umrandunge mit aufgezeichnet werden.
+        SwRect aOut( pFly->Frm() );
+        SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFly );
+        const SwBorderAttrs &rAttrs = *aAccess.Get();
+        if ( rAttrs.CalcRightLine() )
+            aOut.SSize().Width() += 2*nPixelSzW;
+        if ( rAttrs.CalcBottomLine() )
+            aOut.SSize().Height()+= 2*nPixelSzH;
+
+        pImp->PaintLayer( pSh->GetDoc()->GetHellId(), aOut );
+        pLines->PaintLines( &aDev );
+        if ( pFly->IsFlyInCntFrm() )
+            pFly->Paint( aOut );
+        pLines->PaintLines( &aDev );
+        pImp->PaintLayer( pSh->GetDoc()->GetHeavenId(), aOut );
+        pLines->PaintLines( &aDev );
+        if( pSh->GetViewOptions()->IsControl() )
+        {
+            pImp->PaintLayer( pSh->GetDoc()->GetControlsId(), aOut );
+            pLines->PaintLines( &aDev );
+        }
+        DELETEZ( pLines );
+        pFlyOnlyDraw = 0;
+
+        pFlyMetafileOut = 0;
+        bFlyMetafile = FALSE;
+        ::SetOutDevAndWin( pSh, pOld, pWin, nZoom );
+
+        aMet.Stop();
+        aMet.Move( -pFly->Frm().Left(), -pFly->Frm().Top() );
+        aRet = Graphic( aMet );
+
+        if( bNoteURL )
+        {
+            ASSERT( pNoteURL, "MakeGraphic: Good Bye, NoteURL." );
+            pNoteURL->FillImageMap( pMap, pFly->Frm().Pos(), aMap );
+            delete pNoteURL;
+            pNoteURL = NULL;
+        }
+        pGlobalShell = pOldGlobal;
+    }
+    return aRet;
+}
+
+Graphic SwDrawFrmFmt::MakeGraphic( ImageMap* pMap )
+{
+    Graphic aRet;
+    SdrModel *pMod = GetDoc()->GetDrawModel();
+    if ( pMod )
+    {
+        SdrObject *pObj = FindSdrObject();
+        SdrView *pView = new SdrView( pMod );
+        SdrPageView *pPgView = pView->ShowPagePgNum( 0, Point() );
+        pView->MarkObj( pObj, pPgView );
+        aRet = pView->GetMarkedObjBitmap();
+        pView->HidePage( pPgView );
+        delete pView;
+    }
+    return aRet;
+}
+
+
+
diff --git a/sw/source/core/layout/sectfrm.cxx b/sw/source/core/layout/sectfrm.cxx
new file mode 100644
index 000000000000..d09a1a54c9c6
--- /dev/null
+++ b/sw/source/core/layout/sectfrm.cxx
@@ -0,0 +1,2483 @@
+/*************************************************************************
+ *
+ *  $RCSfile: sectfrm.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:22 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _SFXITEMITER_HXX //autogen
+#include 
+#endif
+
+#ifndef _HINTS_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFTN_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFTN_HXX //autogen
+#include 
+#endif
+#ifndef _FMTCLBL_HXX
+#include 
+#endif
+#include "sectfrm.hxx"
+#include "section.hxx"      // SwSection
+#include "frmtool.hxx"      // StackHack
+#include "doc.hxx"          // SwDoc
+#include "cntfrm.hxx"       // SwCntntFrm
+#include "rootfrm.hxx"      // SwRootFrm
+#include "pagefrm.hxx"      // SwPageFrm
+#include "fmtpdsc.hxx"      // SwFmtPageDesc
+#include "fmtcntnt.hxx"     // SwFmtCntnt
+#include "ndindex.hxx"      // SwNodeIndex
+#include "ftnidx.hxx"
+#include "txtfrm.hxx"       // SwTxtFrm
+#include "fmtclds.hxx"      // SwFmtCol
+#include "colfrm.hxx"       // SwColumnFrm
+#include "tabfrm.hxx"       // SwTabFrm
+#include "flyfrm.hxx"       // SwFlyFrm
+#include "ftnfrm.hxx"       // SwFtnFrm
+#include "layouter.hxx"     // SwLayouter
+#include "dbg_lay.hxx"
+#ifndef _SVX_ULSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BRSHITEM_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFTNTX_HXX //autogen
+#include 
+#endif
+
+SV_IMPL_PTRARR_SORT( SwDestroyList, SwSectionFrmPtr )
+
+/*************************************************************************
+|*
+|*  SwSectionFrm::SwSectionFrm(), ~SwSectionFrm()
+|*
+|*  Ersterstellung      AMA 26. Nov. 97
+|*  Letzte Aenderung    AMA 26. Nov. 97
+|*
+|*************************************************************************/
+SwSectionFrm::SwSectionFrm( SwSection &rSect ) :
+    SwLayoutFrm( rSect.GetFmt() ),
+    SwFlowFrm( (SwFrm&)*this ),
+    pSection( &rSect )
+{
+    nType = FRM_SECTION;
+
+    CalcFtnAtEndFlag();
+    CalcEndAtEndFlag();
+
+    const SwFmtCol &rCol = rSect.GetFmt()->GetCol();
+    if ( rCol.GetNumCols() > 1 || IsAnyNoteAtEnd() )
+    {
+        const SwNodeIndex *pCntnt = rSect.GetFmt()->GetCntnt().GetCntntIdx();
+        ASSERT( pCntnt, ":-( Kein Inhalt vorbereitet." );
+        // In Fussnoten duerfen die Bereiche nicht mehrspaltig sein
+        if( !pCntnt->GetNode().FindFootnoteStartNode() )
+        {
+            //PrtArea ersteinmal so gross wie der Frm, damit die Spalten
+            //vernuenftig eingesetzt werden koennen; das schaukelt sich dann
+            //schon zurecht.
+            Frm().Width( 9637 );    //Damit die Spalten einen brauchbaren Wert erhalten.
+                                    //Koennte fuer viele Faelle als Parameter hereinkommen!
+            Prt().Width( Frm().Width() );
+            const SwFmtCol aOld; //ChgColumns() verlaesst sich darauf, dass auch ein
+                                 //Old-Wert hereingereicht wird.
+            ChgColumns( aOld, rCol, IsAnyNoteAtEnd() );
+        }
+    }
+}
+
+SwSectionFrm::SwSectionFrm( SwSectionFrm &rSect, BOOL bMaster ) :
+    SwLayoutFrm( rSect.GetFmt() ),
+    SwFlowFrm( (SwFrm&)*this ),
+    pSection( rSect.GetSection() )
+{
+    bFtnAtEnd = rSect.IsFtnAtEnd();
+    bEndnAtEnd = rSect.IsEndnAtEnd();
+    bLockJoin = FALSE;
+    nType = FRM_SECTION;
+
+    PROTOCOL( this, PROT_SECTION, bMaster ? ACT_CREATE_MASTER : ACT_CREATE_FOLLOW, &rSect )
+
+    if( bMaster )
+    {
+        if( rSect.IsFollow() )
+        {
+            SwSectionFrm* pMaster = rSect.FindSectionMaster();
+            pMaster->SetFollow( this );
+            bIsFollow = TRUE;
+        }
+        else
+            rSect.bIsFollow = TRUE;
+        SetFollow( &rSect );
+    }
+    else
+    {
+        bIsFollow = TRUE;
+        SetFollow( rSect.GetFollow() );
+        rSect.SetFollow( this );
+        if( !GetFollow() )
+            rSect.SimpleFormat();
+        if( !rSect.IsColLocked() )
+            rSect.InvalidateSize();
+    }
+    Frm().Width( rSect.Frm().Width() );
+    Prt().Width( rSect.Prt().Width() );
+    const SwFmtCol &rCol = rSect.GetFmt()->GetCol();
+    if ( ( rCol.GetNumCols() > 1 || IsAnyNoteAtEnd() ) && !rSect.IsInFtn() )
+    {
+        const SwFmtCol aOld; //ChgColumns() verlaesst sich darauf, dass auch ein
+                             //Old-Wert hereingereicht wird.
+        ChgColumns( aOld, rCol, IsAnyNoteAtEnd() );
+    }
+}
+
+SwSectionFrm::~SwSectionFrm()
+{
+    if( GetFmt() && !GetFmt()->GetDoc()->IsInDtor() )
+    {
+        SwRootFrm *pRootFrm = GetFmt()->GetDoc()->GetRootFrm();
+        if( pRootFrm )
+            pRootFrm->RemoveFromList( this );
+        if( IsFollow() )
+        {
+            SwSectionFrm *pMaster = FindSectionMaster();
+            if( pMaster )
+            {
+                PROTOCOL( this, PROT_SECTION, ACT_DEL_FOLLOW, pMaster )
+                pMaster->SetFollow( GetFollow() );
+                // Ein Master greift sich immer den Platz bis zur Unterkante seines
+                // Uppers. Wenn er keinen Follow mehr hat, kann er diesen ggf. wieder
+                // freigeben, deshalb wird die Size des Masters invalidiert.
+                if( !GetFollow() )
+                    pMaster->InvalidateSize();
+            }
+        }
+        else if( HasFollow() )
+        {
+            PROTOCOL( this, PROT_SECTION, ACT_DEL_MASTER, GetFollow() )
+            GetFollow()->bIsFollow = FALSE;
+        }
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwSectionFrm::FindSectionMaster()
+|*
+|*  Ersterstellung      AMA 17. Dec. 97
+|*  Letzte Aenderung    AMA 17. Dec. 97
+|*
+|*************************************************************************/
+
+SwSectionFrm *SwSectionFrm::FindSectionMaster()
+{
+    ASSERT( IsFollow(), "FindSectionMaster: !IsFollow" );
+    SwClientIter aIter( *(pSection->GetFmt()) );
+    SwClient *pLast = aIter.GoStart();
+    while ( pLast )
+    {
+        if ( pLast->ISA( SwFrm ) )
+        {
+            SwSectionFrm* pSect = (SwSectionFrm*)pLast;
+            if( pSect->GetFollow() == this )
+                return pSect;
+        }
+        pLast = aIter++;
+    }
+    return NULL;
+}
+
+SwSectionFrm *SwSectionFrm::FindFirstSectionMaster()
+{
+    ASSERT( IsFollow(), "FindSectionMaster: !IsFollow" );
+    SwClientIter aIter( *(pSection->GetFmt()) );
+    SwClient *pLast = aIter.GoStart();
+    while ( pLast )
+    {
+        if ( pLast->ISA( SwFrm ) )
+        {
+            SwSectionFrm* pSect = (SwSectionFrm*)pLast;
+            if( !pSect->IsFollow() )
+            {
+                SwSectionFrm *pNxt = pSect;
+                while ( pNxt )
+                {
+                    if( pNxt->GetFollow() == this )
+                        return pSect;
+                    pNxt = pNxt->GetFollow();
+                }
+            }
+        }
+        pLast = aIter++;
+    }
+    return NULL;
+}
+
+/*************************************************************************
+|*
+|*  SwSectionFrm::DelEmpty()
+|*
+|*  Ersterstellung      AMA 17. Dec. 97
+|*  Letzte Aenderung    AMA 17. Dec. 97
+|*
+|*************************************************************************/
+void SwSectionFrm::DelEmpty( BOOL bRemove )
+{
+    if( IsColLocked() )
+    {
+        ASSERT( !bRemove, "Don't delete locked SectionFrms" );
+        return;
+    }
+    SwFrm* pUp = GetUpper();
+    if( pUp )
+        _Cut( bRemove );
+    if( IsFollow() )
+    {
+        SwSectionFrm *pMaster = FindSectionMaster();
+        pMaster->SetFollow( GetFollow() );
+        // Ein Master greift sich immer den Platz bis zur Unterkante seines
+        // Uppers. Wenn er keinen Follow mehr hat, kann er diesen ggf. wieder
+        // freigeben, deshalb wird die Size des Masters invalidiert.
+        if( !GetFollow() && !pMaster->IsColLocked() )
+            pMaster->InvalidateSize();
+        bIsFollow = FALSE;
+    }
+    else if( HasFollow() )
+        GetFollow()->bIsFollow = FALSE;
+    pFollow = NULL;
+    if( pUp )
+    {
+        Frm().Height( 0 );
+        // Wenn wir sowieso sofort zerstoert werden, brauchen/duerfen wir
+        // uns gar nicht erst in die Liste eintragen
+        if( bRemove )
+        {   // Wenn wir bereits halbtot waren vor diesem DelEmpty, so
+            // stehen wir vermutlich auch in der Liste und muessen uns
+            // dort austragen
+            if( !pSection )
+                GetFmt()->GetDoc()->GetRootFrm()->RemoveFromList( this );
+        }
+        else
+            GetFmt()->GetDoc()->GetRootFrm()->InsertEmptySct( this );
+        pSection = NULL; // damit ist allerdings eine Reanimierung quasi ausgeschlossen
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwSectionFrm::Cut()
+|*
+|*  Ersterstellung      AMA 02. Dec. 97
+|*  Letzte Aenderung    AMA 02. Dec. 97
+|*
+|*************************************************************************/
+void SwSectionFrm::Cut()
+{
+    _Cut( TRUE );
+}
+
+void SwSectionFrm::_Cut( BOOL bRemove )
+{
+    ASSERT( GetUpper(), "Cut ohne Upper()." );
+
+    PROTOCOL( this, PROT_CUT, 0, GetUpper() )
+
+    SwPageFrm *pPage = FindPageFrm();
+    InvalidatePage( pPage );
+    SwFrm *pFrm = GetNext();
+    SwFrm* pPrepFrm = NULL;
+    while( pFrm && pFrm->IsSctFrm() && !((SwSectionFrm*)pFrm)->GetSection() )
+        pFrm = pFrm->GetNext();
+    if( pFrm )
+    {   //Der alte Nachfolger hat evtl. einen Abstand zum Vorgaenger
+        //berechnet der ist jetzt wo er der erste wird obsolete
+        pFrm->_InvalidatePrt();
+        pFrm->_InvalidatePos();
+        if( pFrm->IsSctFrm() )
+            pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
+        if ( pFrm && pFrm->IsCntntFrm() )
+        {
+            pFrm->InvalidatePage( pPage );
+            if( IsInFtn() && !GetIndPrev() )
+                pPrepFrm = pFrm;
+        }
+    }
+    else
+    {
+        InvalidateNextPos();
+        //Einer muss die Retusche uebernehmen: Vorgaenger oder Upper
+        if ( 0 != (pFrm = GetPrev()) )
+        {   pFrm->SetRetouche();
+            pFrm->Prepare( PREP_WIDOWS_ORPHANS );
+            if ( pFrm->IsCntntFrm() )
+                pFrm->InvalidatePage( pPage );
+        }
+        //Wenn ich der einzige FlowFrm in meinem Upper bin (war), so muss
+        //er die Retouche uebernehmen.
+        //Ausserdem kann eine Leerseite entstanden sein.
+        else
+        {   SwRootFrm *pRoot = (SwRootFrm*)pPage->GetUpper();
+            pRoot->SetSuperfluous();
+            GetUpper()->SetCompletePaint();
+        }
+    }
+    //Erst removen, dann Upper Shrinken.
+    SwLayoutFrm *pUp = GetUpper();
+    if( bRemove )
+    {
+        Remove();
+        if( pUp && !pUp->Lower() && pUp->IsFtnFrm() && !pUp->IsColLocked() &&
+            pUp->GetUpper() )
+        {
+            pUp->Cut();
+            delete pUp;
+            pUp = NULL;
+        }
+    }
+    if( pPrepFrm )
+        pPrepFrm->Prepare( PREP_FTN );
+    if ( pUp )
+    {
+        if ( Frm().Height() > 0 )
+        {
+            SwTwips nFrmHeight = Frm().Height();
+            if( !bRemove )
+            {
+                Frm().Height( 0 );
+                Prt().Height( 0 );
+            }
+            pUp->Shrink( nFrmHeight, pHeight );
+        }
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwSectionFrm::Paste()
+|*
+|*  Ersterstellung      AMA 04. Dec. 97
+|*  Letzte Aenderung    AMA 04. Dec. 97
+|*
+|*************************************************************************/
+
+void SwSectionFrm::Paste( SwFrm* pParent, SwFrm* pSibling )
+{
+    ASSERT( pParent, "Kein Parent fuer Paste." );
+    ASSERT( pParent->IsLayoutFrm(), "Parent ist CntntFrm." );
+    ASSERT( pParent != this, "Bin selbst der Parent." );
+    ASSERT( pSibling != this, "Bin mein eigener Nachbar." );
+    ASSERT( !GetPrev() && !GetUpper(),
+            "Bin noch irgendwo angemeldet." );
+
+    PROTOCOL( this, PROT_PASTE, 0, GetUpper() )
+
+    //In den Baum einhaengen.
+    SwSectionFrm* pSect = pParent->FindSctFrm();
+    if( pSect && HasToBreak( pSect ) )
+    {
+        if( pParent->IsColBodyFrm() ) // handelt es sich um einen spaltigen Bereich
+        {
+            // Falls wir zufaellig am Ende einer Spalte stehen, muss pSibling
+            // auf den ersten Frame der naechsten Spalte zeigen, damit
+            // der Inhalt der naechsten Spalte von InsertGroup richtig in den
+            // neu angelegten pSect umgehaengt wird.
+            SwColumnFrm *pCol = (SwColumnFrm*)pParent->GetUpper();
+            while( !pSibling && 0 != ( pCol = (SwColumnFrm*)pCol->GetNext() ) )
+                pSibling = ((SwLayoutFrm*)((SwColumnFrm*)pCol)->Lower())->Lower();
+            if( pSibling )
+            {
+                // Schlimmer noch: alle folgenden Spalteninhalte muessen
+                // an die pSibling-Kette angehaengt werden, damit sie
+                // mitgenommen werden.
+                SwFrm *pTmp = pSibling;
+                while ( 0 != ( pCol = (SwColumnFrm*)pCol->GetNext() ) )
+                {
+                    while ( pTmp->GetNext() )
+                        pTmp = pTmp->GetNext();
+                    SwFrm* pSave = ::SaveCntnt( pCol );
+                    ::RestoreCntnt( pSave, pSibling->GetUpper(), pTmp );
+                }
+            }
+        }
+        pParent = pSect;
+        pSect = new SwSectionFrm( *((SwSectionFrm*)pParent)->GetSection() );
+        // Wenn pParent in zwei Teile zerlegt wird, so muss sein Follow am
+        // neuen, zweiten Teil angebracht werden.
+        pSect->SetFollow( ((SwSectionFrm*)pParent)->GetFollow() );
+        ((SwSectionFrm*)pParent)->SetFollow( NULL );
+        if( pSect->GetFollow() )
+            pParent->_InvalidateSize();
+
+        InsertGroupBefore( pParent, pSibling, pSect );
+        if( pSect->GetPrev() )
+        {
+            pSect->Frm().Pos() = pSect->GetPrev()->Frm().Pos();
+            pSect->Frm().Pos().Y() += pSect->GetPrev()->Frm().Height();
+        }
+        else
+            pSect->Frm().Pos() = pSect->GetUpper()->Frm().Pos();
+        pSect->Frm().Pos().Y() += 1; //wg. Benachrichtigungen.
+
+        if( !((SwLayoutFrm*)pParent)->Lower() )
+        {
+            SwSectionFrm::MoveCntntAndDelete( (SwSectionFrm*)pParent, FALSE );
+            pParent = this;
+        }
+    }
+    else
+        InsertGroupBefore( pParent, pSibling, NULL );
+
+    _InvalidateAll();
+    SwPageFrm *pPage = FindPageFrm();
+    InvalidatePage( pPage );
+
+    if ( pSibling )
+    {
+        pSibling->_InvalidatePos();
+        pSibling->_InvalidatePrt();
+        if ( pSibling->IsCntntFrm() )
+            pSibling->InvalidatePage( pPage );
+    }
+
+    if ( Frm().Height() )
+        pParent->Grow( Frm().Height(), pHeight );
+
+    if ( GetPrev() )
+    {
+        if ( !IsFollow() )
+        {
+            GetPrev()->InvalidateSize();
+            if ( GetPrev()->IsCntntFrm() )
+                GetPrev()->InvalidatePage( pPage );
+        }
+    }
+}
+
+
+/*************************************************************************
+|*
+|*  SwSectionFrm::HasToBreak()
+|*
+|*  Hier wird entschieden, ob der this-SectionFrm den uebergebenen
+|*  (Section)Frm aufbrechen soll oder nicht.
+|*  Zunaechst werden uebergeordnete Bereiche immer aufgebrochen,
+|*  spaeter koennte man es einstellbar machen.
+|*
+|*  Ersterstellung      AMA 12. Dec. 97
+|*  Letzte Aenderung    AMA 12. Dec. 97
+|*
+|*************************************************************************/
+
+BOOL SwSectionFrm::HasToBreak( const SwFrm* pFrm ) const
+{
+    if( !pFrm->IsSctFrm() )
+        return FALSE;
+
+    SwSectionFmt *pTmp = (SwSectionFmt*)GetFmt();
+//  if( !pTmp->GetSect().GetValue() )
+//      return FALSE;
+
+    const SwFrmFmt *pOtherFmt = ((SwSectionFrm*)pFrm)->GetFmt();
+    do
+    {
+        pTmp = pTmp->GetParent();
+        if( !pTmp )
+            return FALSE;
+        if( pTmp == pOtherFmt )
+            return TRUE;
+    } while( TRUE ); // ( pTmp->GetSect().GetValue() );
+    return FALSE;
+}
+
+/*************************************************************************
+|*
+|*  SwSectionFrm::MergeNext()
+|*
+|*  Ersterstellung      AMA 04. Dec. 97
+|*  Letzte Aenderung    AMA 04. Dec. 97
+|*
+|*  Verschmilzt zwei SectionFrms, falls es sich um den
+|*  gleichen Bereich handelt.
+|*  Notwendig kann dies sein, wenn ein (Unter-)Bereich geloescht wird, der
+|*  einen anderen in zwei Teile zerlegt hatte.
+|*
+|*************************************************************************/
+
+void SwSectionFrm::MergeNext( SwSectionFrm* pNxt )
+{
+    if( !pNxt->IsJoinLocked() && GetSection() == pNxt->GetSection() )
+    {
+        PROTOCOL( this, PROT_SECTION, ACT_MERGE, pNxt )
+
+        SwFrm* pTmp = ::SaveCntnt( pNxt );
+        if( pTmp )
+        {
+            SwFrm* pLast = Lower();
+            SwLayoutFrm* pLay = this;
+            if( pLast )
+            {
+                while( pLast->GetNext() )
+                    pLast = pLast->GetNext();
+                if( pLast->IsColumnFrm() )
+                {   // Spalten jetzt mit BodyFrm
+                    pLay = (SwLayoutFrm*)((SwLayoutFrm*)pLast)->Lower();
+                    pLast = pLay->Lower();
+                    if( pLast )
+                        while( pLast->GetNext() )
+                            pLast = pLast->GetNext();
+                }
+            }
+            ::RestoreCntnt( pTmp, pLay, pLast );
+        }
+        SetFollow( pNxt->GetFollow() );
+        pNxt->SetFollow( NULL );
+        pNxt->bIsFollow = FALSE;
+        pNxt->Cut();
+        delete pNxt;
+        InvalidateSize();
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwSectionFrm::SplitSect()
+|*
+|*  Ersterstellung      AMA 29. Apr. 99
+|*  Letzte Aenderung    AMA 29. Apr. 99
+|*
+|*  Zerteilt einen SectionFrm in zwei Teile, der zweite Teil beginnt mit dem
+|*  uebergebenen Frame.
+|*  Benoetigt wird dies beim Einfuegen eines inneren Bereichs, weil innerhalb
+|*  von Rahmen oder Tabellenzellen das MoveFwd nicht den erwuenschten Effekt
+|*  haben kann.
+|*
+|*************************************************************************/
+
+BOOL SwSectionFrm::SplitSect( SwFrm* pFrm, BOOL bApres )
+{
+    ASSERT( pFrm, "SplitSect: Why?" );
+    SwFrm* pOther = bApres ? pFrm->FindNext() : pFrm->FindPrev();
+    if( !pOther )
+        return FALSE;
+    SwSectionFrm* pSect = pOther->FindSctFrm();
+    if( !pSect || ( pSect != this ) )
+        return FALSE;
+    // Den Inhalt zur Seite stellen
+    SwFrm* pSav = ::SaveCntnt( this, bApres ? pOther : pFrm );
+    ASSERT( pSav, "SplitSect: What's on?" );
+    if( pSav ) // Robust
+    {   // Einen neuen SctFrm anlegen, nicht als Follow/Master
+        SwSectionFrm* pNew = new SwSectionFrm( *pSect->GetSection() );
+        SwLayoutFrm* pLay = pNew;
+        // Bei spaltigen Bereichen muss der erste ColumnBody gesucht werden
+        while( pLay->Lower() && pLay->Lower()->IsLayoutFrm() )
+            pLay = (SwLayoutFrm*)pLay->Lower();
+        pNew->InsertBehind( pSect->GetUpper(), pSect );
+        pNew->Frm().Pos() = pSect->Frm().Pos();
+        pNew->Frm().Pos().Y() += pSect->Frm().Height();
+        pNew->Frm().Pos().Y() += 1; //wg. Benachrichtigungen.
+        ::RestoreCntnt( pSav, pLay, NULL );
+        pSect->_InvalidateSize();
+        return TRUE;
+    }
+    return FALSE;
+}
+
+/*************************************************************************
+|*
+|*  SwSectionFrm::MoveCntntAndDelete()
+|*
+|*  Ersterstellung      AMA 29. Jan 99
+|*  Letzte Aenderung    AMA 29. Jan 99
+|*
+|*  MoveCntnt wird zur Zerstoerung eines SectionFrms wg. Aufhebung oder
+|*  Verstecken des Bereichs gerufen, um den Inhalt umzuhaengen.
+|*  Wenn der SectionFrm keinen anderen aufbrach, so wird der Inhalt in
+|*  den Upper bewegt. Anderfalls wird der Inhalt in den anderen SectionFrm
+|*  umgehaengt, dieser muss ggf. gemergt werden.
+|*
+|*************************************************************************/
+// Wenn ein mehrspaltiger Bereich aufgehoben wird, muessen die ContentFrms
+// invalidiert werden
+
+void lcl_InvalidateInfFlags( SwFrm* pFrm, BOOL bInva )
+{
+    while ( pFrm )
+    {
+        pFrm->InvalidateInfFlags();
+        if( bInva )
+        {
+            pFrm->_InvalidatePos();
+            pFrm->_InvalidateSize();
+            pFrm->_InvalidatePrt();
+        }
+        if( pFrm->IsLayoutFrm() )
+            lcl_InvalidateInfFlags( ((SwLayoutFrm*)pFrm)->GetLower(), FALSE );
+        pFrm = pFrm->GetNext();
+    }
+}
+
+#define FIRSTLEAF( pLayFrm ) ( ( pLayFrm->Lower() && pLayFrm->Lower()->IsColumnFrm() )\
+                    ? pLayFrm->GetNextLayoutLeaf() \
+                    : pLayFrm )
+
+void SwSectionFrm::MoveCntntAndDelete( SwSectionFrm* pDel, BOOL bSave )
+{
+    BOOL bSize = pDel->Lower() && pDel->Lower()->IsColumnFrm();
+    SwFrm* pPrv = pDel->GetPrev();
+    SwLayoutFrm* pUp = pDel->GetUpper();
+    SwFrm *pPrvCntnt, *pNxt;
+    SwSectionFrm *pPrvSct, *pNxtSct;
+    SwSectionFmt *pTmp = (SwSectionFmt*)pDel->GetFmt();
+    SwSectionFmt* pParent = pTmp->GetParent();
+    if( pDel->IsInTab() && pParent )
+    {
+        SwTabFrm *pTab = pDel->FindTabFrm();
+        // Wenn wir innerhalb einer Tabelle liegen, koennen wir nur Bereiche
+        // aufgebrochen haben, die ebenfalls innerhalb liegen, nicht etwa
+        // einen Bereich, der die gesamte Tabelle umfasst.
+        if( pTab->IsInSct() && pParent == pTab->FindSctFrm()->GetFmt() )
+            pParent = NULL;
+    }
+    // Wenn unser Format einen Parent besitzt, so haben wir vermutlich
+    // einen anderen SectionFrm aufgebrochen, dies muss geprueft werden,
+    // dazu besorgen wir uns zunaechst den vorhergehende und den nach-
+    // folgenden CntntFrm, mal sehen, ob diese in SectionFrms liegen.
+    if( pParent && 0 != ( pPrvCntnt = pDel->ContainsCntnt() ) )
+    {
+        if( pPrvCntnt )
+            pPrvCntnt = pPrvCntnt->FindPrev();
+        pPrvSct = pPrvCntnt ? pPrvCntnt->FindSctFrm() : NULL;
+        pNxt = pDel->FindLastCntnt();
+        if( pNxt )
+            pNxt = pNxt->FindNext();
+        pNxtSct = pNxt ? pNxt->FindSctFrm() : NULL;
+    }
+    else
+    {
+        pParent = NULL;
+        pPrvCntnt = pNxt = NULL;
+        pPrvSct = pNxtSct = NULL;
+    }
+    // Jetzt wird der Inhalt beseite gestellt und der Frame zerstoert
+    SwFrm *pSave = bSave ? ::SaveCntnt( pDel ) : NULL;
+    BOOL bOldFtn = TRUE;
+    if( pSave && pUp->IsFtnFrm() )
+    {
+        bOldFtn = ((SwFtnFrm*)pUp)->IsColLocked();
+        ((SwFtnFrm*)pUp)->ColLock();
+    }
+    pDel->DelEmpty( TRUE );
+    delete pDel;
+    if( pParent )
+    {   // Hier wird die geeignete Einfuegeposition gesucht
+        if( pNxtSct && pNxtSct->GetFmt() == pParent )
+        {   // Hier koennen wir uns am Anfang einfuegen
+            pUp = FIRSTLEAF( pNxtSct );
+            pPrv = NULL;
+            if( pPrvSct && !( pPrvSct->GetFmt() == pParent ) )
+                pPrvSct = NULL; // damit nicht gemergt wird
+        }
+        else if( pPrvSct && pPrvSct->GetFmt() == pParent )
+        {   // Wunderbar, hier koennen wir uns am Ende einfuegen
+            pUp = pPrvSct;
+            if( pUp->Lower() && pUp->Lower()->IsColumnFrm() )
+            {
+                pUp = (SwLayoutFrm*)pUp->Lower(); // Die erste Spalte
+                while( pUp->GetNext() )
+                    pUp = (SwLayoutFrm*)pUp->GetNext();
+                pUp = (SwLayoutFrm*)pUp->Lower(); // Der Body der letzten Spalte
+            }
+            pPrv = pUp->Lower(); // damit hinter dem letzten eingefuegt wird
+            if( pPrv )
+                while( pPrv->GetNext() )
+                    pPrv = pPrv->GetNext();
+            pPrvSct = NULL; // damit nicht gemergt wird
+        }
+        else
+        {
+            if( pSave )
+            {   // Folgende Situationen: Vor und hinter dem zu loeschenden Bereich
+                // ist entweder die Bereichsgrenze des umfassenden Bereichs oder
+                // es schliesst ein anderer (Geschwister-)Bereich direkt an, der
+                // vom gleichen Parent abgeleitet ist.
+                // Dann gibt es (noch) keinen Teil unseres Parents, der den Inhalt
+                // aufnehmen kann,also bauen wir ihn uns.
+                pPrvSct = new SwSectionFrm( *pParent->GetSection() );
+                pPrvSct->InsertBehind( pUp, pPrv );
+                if( pPrv )
+                {
+                    pPrvSct->Frm().Pos() = pPrv->Frm().Pos();
+                    pPrvSct->Frm().Pos().Y() += pPrv->Frm().Height();
+                }
+                else
+                    pPrvSct->Frm().Pos() = pUp->Frm().Pos();
+                pPrvSct->Frm().Pos().Y() += 1; //wg. Benachrichtigungen.
+
+                pUp = FIRSTLEAF( pPrvSct );
+                pPrv = NULL;
+            }
+            pPrvSct = NULL; // damit nicht gemergt wird
+        }
+    }
+    // Der Inhalt wird eingefuegt..
+    if( pSave )
+    {
+        lcl_InvalidateInfFlags( pSave, bSize );
+        ::RestoreCntnt( pSave, pUp, pPrv );
+        pUp->FindPageFrm()->InvalidateCntnt();
+        if( !bOldFtn )
+            ((SwFtnFrm*)pUp)->ColUnlock();
+    }
+    // jetzt koennen eventuell zwei Teile des uebergeordneten Bereich verschmelzen
+    if( pPrvSct && !pPrvSct->IsJoinLocked() )
+    {
+        ASSERT( pNxtSct, "MoveCntnt: No Merge" );
+        pPrvSct->MergeNext( pNxtSct );
+    }
+}
+
+void SwSectionFrm::MakeAll()
+{
+    if ( IsJoinLocked() || IsColLocked() || StackHack::IsLocked() || StackHack::Count() > 50 )
+        return;
+    if( !pSection ) // Durch DelEmpty
+    {
+        ASSERT( GetFmt()->GetDoc()->GetRootFrm()->IsInDelList( this ), "SectionFrm without Section" );
+        if( !bValidPos )
+        {
+            if( GetPrev() )
+            {   aFrm.Pos( GetPrev()->Frm().Pos() );
+                aFrm.Pos().*pVARPOS += GetPrev()->Frm().SSize().*pVARSIZE;
+            }
+            else if( GetUpper() )
+            {
+                aFrm.Pos( GetUpper()->Frm().Pos() );
+                aFrm.Pos() += GetUpper()->Prt().Pos();
+            }
+        }
+        bValidSize = bValidPos = bValidPrtArea = TRUE;
+        return;
+    }
+    LockJoin(); //Ich lass mich nicht unterwegs vernichten.
+
+    while( GetNext() && GetNext() == GetFollow() )
+    {
+        const SwFrm* pFoll = GetFollow();
+        MergeNext( (SwSectionFrm*)GetNext() );
+        if( pFoll == GetFollow() )
+            break;
+    }
+
+    // Ein Bereich mit Follow nimmt allen Platz bis zur Unterkante des Uppers
+    // in Anspruch. Bewegt er sich, so kann seine Groesse zu- oder abnehmen...
+    if( !bValidPos && ToMaximize( FALSE ) )
+        bValidSize = FALSE;
+
+#ifdef DEBUG
+    const SwFmtCol &rCol = GetFmt()->GetCol();
+#endif
+    SwLayoutFrm::MakeAll();
+    UnlockJoin();
+    if( pSection && IsSuperfluous() )
+        DelEmpty( FALSE );
+}
+
+BOOL SwSectionFrm::ShouldBwdMoved( SwLayoutFrm *pNewUpper, BOOL bHead, BOOL &rReformat )
+{
+    ASSERT( FALSE, "Hups, wo ist meine Tarnkappe?" );
+    return FALSE;
+}
+
+const SwSectionFmt* SwSectionFrm::_GetEndSectFmt() const
+{
+    const SwSectionFmt *pFmt = pSection->GetFmt();
+    while( !pFmt->GetEndAtTxtEnd().IsAtEnd() )
+    {
+        if( pFmt->GetRegisteredIn()->ISA( SwSectionFmt ) )
+            pFmt = (SwSectionFmt*)pFmt->GetRegisteredIn();
+        else
+            return NULL;
+    }
+    return pFmt;
+}
+
+void lcl_FindCntntFrm( SwCntntFrm* &rpCntntFrm, SwFtnFrm* &rpFtnFrm,
+    SwFrm* pFrm, BOOL &rbChkFtn )
+{
+    if( pFrm )
+    {
+        while( pFrm->GetNext() )
+            pFrm = pFrm->GetNext();
+        while( !rpCntntFrm && pFrm )
+        {
+            if( pFrm->IsCntntFrm() )
+                rpCntntFrm = (SwCntntFrm*)pFrm;
+            else if( pFrm->IsLayoutFrm() )
+            {
+                if( pFrm->IsFtnFrm() )
+                {
+                    if( rbChkFtn )
+                    {
+                        rpFtnFrm = (SwFtnFrm*)pFrm;
+                        rbChkFtn = rpFtnFrm->GetAttr()->GetFtn().IsEndNote();
+                    }
+                }
+                else
+                    lcl_FindCntntFrm( rpCntntFrm, rpFtnFrm,
+                        ((SwLayoutFrm*)pFrm)->Lower(), rbChkFtn );
+            }
+            pFrm = pFrm->GetPrev();
+        }
+    }
+}
+
+SwCntntFrm *SwSectionFrm::FindLastCntnt( BYTE nMode )
+{
+    SwCntntFrm *pRet = NULL;
+    SwFtnFrm *pFtnFrm = NULL;
+    SwSectionFrm *pSect = this;
+    if( nMode )
+    {
+        const SwSectionFmt *pFmt = IsEndnAtEnd() ? GetEndSectFmt() :
+                                     pSection->GetFmt();
+        do {
+            while( pSect->HasFollow() )
+                pSect = pSect->GetFollow();
+            SwFrm* pTmp = pSect->FindNext();
+            while( pTmp && pTmp->IsSctFrm() &&
+                   !((SwSectionFrm*)pTmp)->GetSection() )
+                pTmp = pTmp->FindNext();
+            if( pTmp && pTmp->IsSctFrm() &&
+                ((SwSectionFrm*)pTmp)->IsDescendantFrom( pFmt ) )
+                pSect = (SwSectionFrm*)pTmp;
+            else
+                break;
+        } while( TRUE );
+    }
+    BOOL bFtnFound = nMode == FINDMODE_ENDNOTE;
+    do
+    {
+        lcl_FindCntntFrm( pRet, pFtnFrm, pSect->Lower(), bFtnFound );
+        if( pRet || !pSect->IsFollow() || !nMode ||
+            ( FINDMODE_MYLAST == nMode && this == pSect ) )
+            break;
+        pSect = pSect->FindSectionMaster();
+    } while( pSect );
+    if( ( nMode == FINDMODE_ENDNOTE ) && pFtnFrm )
+        pRet = pFtnFrm->ContainsCntnt();
+    return pRet;
+}
+
+BOOL SwSectionFrm::CalcMinDiff( SwTwips& rMinDiff ) const
+{
+    if( ToMaximize( TRUE ) )
+    {
+        rMinDiff = GetUpper()->Frm().Top() + GetUpper()->Prt().Top() +
+                   GetUpper()->Prt().Height() - Frm().Top() - Frm().Height();
+        return TRUE;
+    }
+    return FALSE;
+}
+
+/*************************************************************************
+ *
+ *  SwSectionFrm::CollectEndnotes(  )
+ *
+ *  Ersterstellung      AMA 03. Nov 99
+ *  Letzte Aenderung    AMA 03. Nov 99
+ *
+ *  CollectEndnotes looks for endnotes in the sectionfrm and his follows,
+ *  the endnotes will cut off the layout and put into the array.
+ *  If the first endnote is not a master-SwFtnFrm, the whole sectionfrm
+ *  contains only endnotes and it is not necessary to collect them.
+ *
+ *************************************************************************/
+
+SwFtnFrm* lcl_FindEndnote( SwSectionFrm* &rpSect, BOOL &rbEmpty,
+    SwLayouter *pLayouter )
+{
+    // if rEmpty is set, the rpSect is already searched
+    SwSectionFrm* pSect = rbEmpty ? rpSect->GetFollow() : rpSect;
+    while( pSect )
+    {
+        ASSERT( pSect->Lower() && pSect->Lower()->IsColumnFrm(),
+            "InsertEndnotes: Where's my column?" );
+        SwColumnFrm* pCol = (SwColumnFrm*)pSect->Lower();
+        do // check all columns
+        {
+            SwFtnContFrm* pFtnCont = pCol->FindFtnCont();
+            if( pFtnCont )
+            {
+                SwFtnFrm* pRet = (SwFtnFrm*)pFtnCont->Lower();
+                while( pRet ) // look for endnotes
+                {
+                    if( pRet->GetAttr()->GetFtn().IsEndNote() )
+                    {
+                        if( pRet->GetMaster() )
+                        {
+                            if( pLayouter )
+                                pLayouter->CollectEndnote( pRet );
+                            else
+                                return 0;
+                        }
+                        else
+                            return pRet; // Found
+                    }
+                    pRet = (SwFtnFrm*)pRet->GetNext();
+                }
+            }
+            pCol = (SwColumnFrm*)pCol->GetNext();
+        } while ( pCol );
+        rpSect = pSect;
+        pSect = pLayouter ? pSect->GetFollow() : NULL;
+        rbEmpty = TRUE;
+    }
+    return NULL;
+}
+
+void lcl_ColumnRefresh( SwSectionFrm* pSect, BOOL bFollow )
+{
+    while( pSect )
+    {
+        BOOL bOldLock = pSect->IsColLocked();
+        pSect->ColLock();
+        if( pSect->Lower() && pSect->Lower()->IsColumnFrm() )
+        {
+            SwColumnFrm *pCol = (SwColumnFrm*)pSect->Lower();
+            do
+            {   pCol->_InvalidateSize();
+                pCol->_InvalidatePos();
+                ((SwLayoutFrm*)pCol)->Lower()->_InvalidateSize();
+                pCol->Calc();   // calculation of column and
+                ((SwLayoutFrm*)pCol)->Lower()->Calc();  // body
+                pCol = (SwColumnFrm*)pCol->GetNext();
+            } while ( pCol );
+        }
+        if( !bOldLock )
+            pSect->ColUnlock();
+        if( bFollow )
+            pSect = pSect->GetFollow();
+        else
+            pSect = NULL;
+    }
+}
+
+void SwSectionFrm::CollectEndnotes( SwLayouter* pLayouter )
+{
+    ASSERT( IsColLocked(), "CollectEndnotes: You love the risk?" );
+    ASSERT( Lower() && Lower()->IsColumnFrm(), "Where's my column?" );
+    SwSectionFrm* pSect = this;
+    SwFtnFrm* pFtn;
+    BOOL bEmpty = FALSE;
+    // pSect is the last sectionfrm without endnotes or the this-pointer
+    // the first sectionfrm with endnotes may be destroyed, when the endnotes
+    // is cutted
+    while( 0 != (pFtn = lcl_FindEndnote( pSect, bEmpty, pLayouter )) )
+        pLayouter->CollectEndnote( pFtn );
+    if( pLayouter->HasEndnotes() )
+        lcl_ColumnRefresh( this, TRUE );
+}
+
+/*************************************************************************
+|*
+|*  SwSectionFrm::_CheckClipping( BOOL bGrow, BOOL bMaximize )
+|*
+|*  Beschreibung:       Passt die Groesse an die Umgebung an.
+|*      Wer einen Follow oder Fussnoten besitzt, soll bis zur Unterkante
+|*      des Uppers gehen (bMaximize).
+|*      Niemand darf ueber den Upper hinausgehen, ggf. darf man versuchen (bGrow)
+|*      seinen Upper zu growen.
+|*      Wenn die Groesse veraendert werden musste, wird der Inhalt kalkuliert.
+|*
+|*************************************************************************/
+
+extern BOOL lcl_Apres( SwLayoutFrm* pFirst, SwLayoutFrm* pSecond );
+
+void SwSectionFrm::_CheckClipping( BOOL bGrow, BOOL bMaximize )
+{
+    SwTwips nDeadLine = GetUpper()->Frm().Top() + GetUpper()->Prt().Top()
+                        + GetUpper()->Prt().Height();
+    //Vielleicht schafft der Upper ja noch Platz, ein spaltiger Rahmen,
+    //der gerade formatiert wird, wird nicht gefragt
+    if( bGrow && ( !IsInFly() || !GetUpper()->IsColBodyFrm() ||
+                   !FindFlyFrm()->IsLocked() ) )
+    {
+        long nBottom = Frm().Top() + Frm().Height() + ( bMaximize ? 0 : Undersize() );
+        if( nBottom > nDeadLine )
+            nDeadLine += GetUpper()->Grow( nBottom - nDeadLine, pHeight );
+    }
+    // Bei maximierten SectionFrms ist das Undersized-Flag ueberfluessig,
+    // aber sonst muss es auch gesetzt werden, wenn die DeadLine genau
+    // erreicht wurde (spaltige Bereiche wachsen nicht ueber die Umgebung
+    // hinaus.
+    SetUndersized( !bMaximize && Frm().Top() + Frm().Height() >= nDeadLine );
+    BOOL bCalc = ( IsUndersized() || bMaximize ) &&
+        ( Frm().Top() + Frm().Height() != nDeadLine ||
+          Prt().Top() > Frm().Height() );
+    if( !bCalc && !bGrow && IsAnyNoteAtEnd() )
+    {
+        SwSectionFrm *pSect = this;
+        BOOL bEmpty = FALSE;
+        SwLayoutFrm* pFtn = IsEndnAtEnd() ?
+            lcl_FindEndnote( pSect, bEmpty, NULL ) : NULL;
+        if( pFtn )
+        {
+            pFtn = pFtn->FindFtnBossFrm();
+            SwFrm* pTmp = FindLastCntnt( FINDMODE_LASTCNT );
+            if( pTmp && lcl_Apres( pFtn, pTmp->FindFtnBossFrm() ) )
+                bCalc = TRUE;
+        }
+        else if( GetFollow() && !GetFollow()->ContainsAny() )
+            bCalc = TRUE;
+    }
+    if( bCalc )
+    {
+        if( nDeadLine < Frm().Top() )  // Wenn wir ganz unterhalb
+            nDeadLine = Frm().Top();  // liegen, keine neg. Hoehe!
+        const Size aOldSz( Prt().SSize() );
+        Frm().Height( nDeadLine - Frm().Top() );
+        if( Prt().Top() > Frm().Height() )
+            Prt().Pos().Y() = Frm().Height();
+        Prt().Height( Frm().Height() - Prt().Top() );
+
+        // Wir haben zu guter Letzt noch einmal die Hoehe geaendert,
+        // dann wird das innere Layout (Columns) kalkuliert und
+        // der Inhalt ebenfalls.
+        if( Lower() )
+        {
+            if( Lower()->IsColumnFrm() )
+            {
+                lcl_ColumnRefresh( this, FALSE );
+                ::CalcCntnt( this );
+            }
+            else
+            {
+                ChgLowersProp( aOldSz );
+                if( !bMaximize && !IsCntntLocked() )
+                    ::CalcCntnt( this );
+            }
+        }
+    }
+}
+
+void SwSectionFrm::SimpleFormat()
+{
+    if ( IsJoinLocked() || IsColLocked() )
+        return;
+    // ASSERT( pFollow, "SimpleFormat: Follow required" );
+    LockJoin();
+    if( GetPrev() )
+    {
+        aFrm.Pos( GetPrev()->Frm().Pos() );
+        aFrm.Pos().*pVARPOS += GetPrev()->Frm().SSize().*pVARSIZE;
+        bValidPos = TRUE;
+    }
+    else if( GetUpper() )
+    {
+        aFrm.Pos( GetUpper()->Frm().Pos() );
+        aFrm.Pos() += GetUpper()->Prt().Pos();
+        bValidPos = TRUE;
+    }
+
+    SwTwips nDeadLine = GetUpper()->Frm().Top() + GetUpper()->Prt().Top()
+                        + GetUpper()->Prt().Height();
+    if( Frm().Top() + Frm().Height() < nDeadLine )
+    {
+        const Size aOldSz( Prt().SSize() );
+        Frm().Height( nDeadLine - Frm().Top() );
+        Prt().Pos().Y() = CalcUpperSpace();
+        if( Prt().Top() > Frm().Height() )
+            Prt().Pos().Y() = Frm().Height();
+        Prt().Height( Frm().Height() - Prt().Top() );
+        lcl_ColumnRefresh( this, FALSE );
+    }
+    UnlockJoin();
+}
+
+/*************************************************************************
+|*
+|*  SwSectionFrm::Format()
+|*
+|*  Beschreibung:       "Formatiert" den Frame; Frm und PrtArea.
+|*  Ersterstellung      AMA 03. Dec. 97
+|*  Letzte Aenderung    MA 09. Oct. 98
+|*
+|*************************************************************************/
+
+void SwSectionFrm::Format( const SwBorderAttrs *pAttr )
+{
+    if( !pSection ) // Durch DelEmpty
+    {
+        ASSERT( GetFmt()->GetDoc()->GetRootFrm()->IsInDelList( this ),
+                 "SectionFrm without Section" );
+        bValidSize = bValidPos = bValidPrtArea = TRUE;
+        return;
+    }
+    if ( !bValidPrtArea )
+    {
+        PROTOCOL( this, PROT_PRTAREA, 0, 0 )
+        bValidPrtArea = TRUE;
+        const SwTwips nOldHeight = Prt().Height();
+        aPrt.Left( 0 );
+        aPrt.Width ( aFrm.Width() );
+        SwTwips nUpper = CalcUpperSpace();
+
+        if( nUpper != Prt().Top() )
+        {
+            Prt().Pos().Y() = nUpper;
+            bValidSize = FALSE;
+            SwFrm* pOwn = ContainsAny();
+            if( pOwn )
+                pOwn->_InvalidatePos();
+        }
+        aPrt.Height( aFrm.Height() - nUpper );
+    }
+
+    if ( !bValidSize )
+    {
+        PROTOCOL_ENTER( this, PROT_SIZE, 0, 0 )
+        const long nOldHeight = Frm().Height();
+        BOOL bOldLock = IsColLocked();
+        ColLock();
+
+        bValidSize = TRUE;
+
+        //die Groesse wird nur dann vom Inhalt bestimmt, wenn der SectFrm
+        //keinen Follow hat. Anderfalls fuellt er immer den Upper bis
+        //zur Unterkante aus. Fuer den Textfluss ist nicht er, sondern sein
+        //Inhalt selbst verantwortlich.
+        BOOL bMaximize = ToMaximize( FALSE );
+
+        if( GetUpper() )
+        {
+            aFrm.Width( GetUpper()->Prt().Width() );
+            aPrt.Width ( aFrm.Width() );
+            _CheckClipping( FALSE, bMaximize );
+            bMaximize = ToMaximize( FALSE );
+            bValidSize = TRUE;
+        }
+
+        //Breite der Spalten pruefen und ggf. einstellen.
+        if ( Lower() && Lower()->IsColumnFrm() )
+        {
+            if( Lower()->GetNext() )
+                AdjustColumns( 0, FALSE );
+            else if( bMaximize )
+                ((SwColumnFrm*)Lower())->Lower()->Calc();
+        }
+
+        if ( !bMaximize )
+        {
+            SwTwips nRemaining = Prt().Top(),
+                    nDiff;
+            SwFrm *pFrm = pLower;
+            if( pFrm )
+            {
+                if( pFrm->IsColumnFrm() && pFrm->GetNext() )
+                {
+                    FormatWidthCols( *pAttr, Prt().Top(), MINLAY );
+                    while( HasFollow() && !GetFollow()->ContainsCntnt() )
+                    {
+                        SwFrm* pOld = GetFollow();
+                        GetFollow()->DelEmpty( FALSE );
+                        if( pOld == GetFollow() )
+                            break;
+                    }
+                    bMaximize = ToMaximize( FALSE );
+                    nRemaining += pFrm->Frm().Height();
+                }
+                else
+                {
+                    if( pFrm->IsColumnFrm() )
+                    {
+                        pFrm->Calc();
+                        pFrm = ((SwColumnFrm*)pFrm)->Lower();
+                        pFrm->Calc();
+                        pFrm = ((SwLayoutFrm*)pFrm)->Lower();
+                        CalcFtnCntnt();
+                    }
+                    // Wenn wir in einem spaltigen Rahmen stehen und dieser
+                    // gerade im FormatWidthCols ein CalcCntnt ruft, muss
+                    // unser Inhalt ggf. kalkuliert werden.
+                    if( pFrm && !pFrm->IsValid() && IsInFly() &&
+                        FindFlyFrm()->IsColLocked() )
+                        ::CalcCntnt( this );
+                    nRemaining += InnerHeight();
+                    bMaximize = HasFollow();
+                }
+            }
+
+            nDiff = Frm().Height() - nRemaining;
+            if( nDiff < 0)
+            {
+                // Nicht groesser als die Umgebung werden
+                SwTwips nDeadLine = GetUpper()->Frm().Top() + GetUpper()->Prt().Bottom();
+                {
+                    long nBottom = Frm().Bottom() - nDiff;
+                    if( nBottom > nDeadLine )
+                    {
+                        nDeadLine += GetUpper()->Grow( nBottom - nDeadLine, pHeight, TRUE );
+                        if( nBottom > nDeadLine )
+                            nDiff += nBottom - nDeadLine;
+                        if( nDiff > 0 )
+                            nDiff = 0;
+                    }
+                }
+            }
+            if( nDiff )
+            {
+                //Weil das Grow/Shrink die Groessen nicht direkt
+                //einstellt, sondern indirekt per Invalidate ein Format
+                //ausloesst, muessen die Groessen hier direkt eingestellt
+                //werden.
+                Prt().Height( nRemaining - Prt().Top() );
+                Frm().Height( nRemaining );
+                InvalidateNextPos();
+                if( pLower && ( !pLower->IsColumnFrm() || !pLower->GetNext() ) )
+                {
+                    // Wenn ein einspaltiger Bereich gerade den Platz geschaffen
+                    // hat, den sich die "undersized" Absaetze gewuenscht haben,
+                    // muessen diese invalidiert und kalkuliert werden, damit
+                    // sie diesen ausfuellen.
+                    pFrm = pLower;
+                    if( pFrm->IsColumnFrm() )
+                    {
+                        pFrm->_InvalidateSize();
+                        pFrm->_InvalidatePos();
+                        pFrm->Calc();
+                        pFrm = ((SwColumnFrm*)pFrm)->Lower();
+                        pFrm->Calc();
+                        pFrm = ((SwLayoutFrm*)pFrm)->Lower();
+                        CalcFtnCntnt();
+                    }
+                    BOOL bUnderSz = FALSE;
+                    while( pFrm )
+                    {
+                        if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() )
+                        {
+                            pFrm->Prepare( PREP_ADJUST_FRM );
+                            bUnderSz = TRUE;
+                        }
+                        pFrm = pFrm->GetNext();
+                    }
+                    if( bUnderSz && !IsCntntLocked() )
+                        ::CalcCntnt( this );
+                }
+            }
+        }
+
+        //Unterkante des Uppers nicht ueberschreiten. Fuer Sections mit
+        //Follows die Unterkante auch nicht unterschreiten.
+        if ( GetUpper() )
+            _CheckClipping( TRUE, bMaximize );
+        if( !bOldLock )
+            ColUnlock();
+        if( nOldHeight > Frm().Height() )
+        {
+            if( !GetNext() )
+                SetRetouche(); // Dann muessen wir die Retusche selbst uebernehmen
+            if( GetUpper() )
+                GetUpper()->Shrink( nOldHeight - Frm().Height(), pHeight );
+        }
+        if( IsUndersized() )
+            bValidPrtArea = TRUE;
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFrm::GetNextSctLeaf()
+|*
+|*  Beschreibung        Liefert das naechste Layoutblatt in das der Frame
+|*      gemoved werden kann.
+|*      Neue Seiten werden nur dann erzeugt, wenn der Parameter TRUE ist.
+|*  Ersterstellung      AMA 07. Jan. 98
+|*  Letzte Aenderung    AMA 07. Jan. 98
+|*
+|*************************************************************************/
+
+
+SwLayoutFrm *SwFrm::GetNextSctLeaf( MakePageType eMakePage )
+{
+    //Achtung: Geschachtelte Bereiche werden zur Zeit nicht unterstuetzt.
+
+    PROTOCOL_ENTER( this, PROT_LEAF, ACT_NEXT_SECT, GetUpper()->FindSctFrm() )
+
+    // Abkuerzungen fuer spaltige Bereiche, wenn wir noch nicht in der letzten Spalte sind.
+    // Koennen wir in die naechste Spalte des Bereichs rutschen?
+    if( IsColBodyFrm() && GetUpper()->GetNext() )
+        return (SwLayoutFrm*)((SwLayoutFrm*)GetUpper()->GetNext())->Lower();
+    if( GetUpper()->IsColBodyFrm() && GetUpper()->GetUpper()->GetNext() )
+        return (SwLayoutFrm*)((SwLayoutFrm*)GetUpper()->GetUpper()->GetNext())->Lower();
+    // Innerhalb von Bereichen in Tabellen oder Bereichen in Kopf/Fusszeilen kann
+    // nur ein Spaltenwechsel erfolgen, eine der oberen Abkuerzungen haette zuschlagen muessen
+    if( ( IsInTab() && !IsTabFrm() ) || FindFooterOrHeader() )
+        return 0;
+
+//MA 03. Feb. 99: Warum GetUpper()? Das knallt mit Buch.sgl weil im
+//FlyAtCnt::MakeFlyPos ein Orient der SectionFrm ist und auf diesen ein
+//GetLeaf gerufen wird.
+//  SwSectionFrm *pSect = GetUpper()->FindSctFrm();
+    SwSectionFrm *pSect = FindSctFrm();
+    BOOL bWrongPage = FALSE;
+    ASSERT( pSect, "GetNextSctLeaf: Missing SectionFrm" );
+
+    // Hier eine Abkuerzung fuer Bereiche mit Follows,
+    // dieser kann akzeptiert werden, wenn keine Spalten oder Seiten (ausser Dummyseiten)
+    // dazwischen liegen.
+    // Bei verketteten Rahmen und ind Fussnoten wuerde die Abkuerzung noch aufwendiger
+    if( pSect->HasFollow() && pSect->IsInDocBody() )
+    {
+        SwFrm* pTmp;
+        if( !pSect->GetUpper()->IsColBodyFrm() ||
+            0 == ( pTmp = pSect->GetUpper()->GetUpper()->GetNext() ) )
+            pTmp = pSect->FindPageFrm()->GetNext();
+        if( pTmp ) // ist jetzt die naechste Spalte oder Seite
+        {
+            SwFrm* pTmpX = pTmp;
+            if( pTmp->IsPageFrm() && ((SwPageFrm*)pTmp)->IsEmptyPage() )
+                pTmp = pTmp->GetNext(); // Dummyseiten ueberspringen
+            SwFrm *pUp = pSect->GetFollow()->GetUpper();
+            // pUp wird die Spalte, wenn der Follow in einer "nicht ersten" Spalte
+            // liegt, ansonsten die Seite:
+            if( !pUp->IsColBodyFrm() ||
+                !( pUp = pUp->GetUpper() )->GetPrev() )
+                pUp = pUp->FindPageFrm();
+            // Jetzt muessen pUp und pTmp die gleiche Seite/Spalte sein,
+            // sonst liegen Seiten oder Spalten zwischen Master und Follow.
+            if( pUp == pTmp || pUp->GetNext() == pTmpX )
+            {
+                SwPageFrm* pNxtPg = pUp->IsPageFrm() ?
+                                    (SwPageFrm*)pUp : pUp->FindPageFrm();
+                if( WrongPageDesc( pNxtPg ) )
+                    bWrongPage = TRUE;
+                else
+                    return FIRSTLEAF( pSect->GetFollow() );
+            }
+        }
+    }
+
+    // Immer im gleichen Bereich landen: Body wieder in Body etc.
+    const BOOL bBody = IsInDocBody();
+    const BOOL bFtnPage = FindPageFrm()->IsFtnPage();
+
+    SwLayoutFrm *pLayLeaf;
+    // Eine Abkuerzung fuer TabFrms, damit nicht alle Zellen abgehuehnert werden
+    if( bWrongPage )
+        pLayLeaf = 0;
+    else if( IsTabFrm() )
+        pLayLeaf = ((SwTabFrm*)this)->FindLastCntnt()->GetUpper();
+    else
+    {
+        pLayLeaf = GetNextLayoutLeaf();
+        if( IsColumnFrm() )
+        {
+            while( pLayLeaf && ((SwColumnFrm*)this)->IsAnLower( pLayLeaf ) )
+                pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
+        }
+    }
+
+    SwLayoutFrm *pOldLayLeaf = 0;           //Damit bei neu erzeugten Seiten
+                                            //nicht wieder vom Anfang gesucht
+                                            //wird.
+
+    while( TRUE )
+    {
+        if( pLayLeaf )
+        {
+            // Ein Layoutblatt wurde gefunden, mal sehen, ob er mich aufnehmen kann,
+            // ob hier ein weiterer SectionFrm eingefuegt werden kann
+            // oder ob wir weitersuchen muessen.
+            SwPageFrm* pNxtPg = pLayLeaf->FindPageFrm();
+            if ( !bFtnPage && pNxtPg->IsFtnPage() )
+            {   //Wenn ich bei den Endnotenseiten angelangt bin hat sichs.
+                pLayLeaf = 0;
+                continue;
+            }
+            // Einmal InBody, immer InBody, nicht in Tabellen hinein
+            // und nicht in fremde Bereiche hinein
+            if ( (bBody && !pLayLeaf->IsInDocBody()) ||
+                 (IsInFtn() != pLayLeaf->IsInFtn() ) ||
+                 pLayLeaf->IsInTab() ||
+                 ( pLayLeaf->IsInSct() && ( !pSect->HasFollow()
+                   || pSect->GetFollow() != pLayLeaf->FindSctFrm() ) ) )
+            {
+                //Er will mich nicht; neuer Versuch, neues Glueck
+                pOldLayLeaf = pLayLeaf;
+                pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
+                continue;
+            }
+            if( WrongPageDesc( pNxtPg ) )
+            {
+                if( bWrongPage )
+                    break; // there's a column between me and my right page
+                pLayLeaf = 0;
+                bWrongPage = TRUE;
+                pOldLayLeaf = 0;
+                continue;
+            }
+        }
+        //Es gibt keinen passenden weiteren LayoutFrm, also muss eine
+        //neue Seite her, allerdings nuetzen uns innerhalb eines Rahmens
+        //neue Seiten nichts.
+        else if( !pSect->IsInFly() &&
+            ( eMakePage == MAKEPAGE_APPEND || eMakePage == MAKEPAGE_INSERT ) )
+        {
+            InsertPage(pOldLayLeaf ? pOldLayLeaf->FindPageFrm() : FindPageFrm(),
+                       FALSE );
+            //und nochmal das ganze
+            pLayLeaf = pOldLayLeaf ? pOldLayLeaf : GetNextLayoutLeaf();
+            continue;
+        }
+        break;
+    }
+
+    if( pLayLeaf )
+    {
+        // Das passende Layoutblatt haben wir gefunden, wenn es dort bereits einen
+        // Follow unseres Bereichs gibt, nehmen wir dessen erstes Layoutblatt,
+        // andernfalls wird es Zeit, einen Bereichsfollow zu erzeugen
+        SwSectionFrm* pNew;
+
+        //Dies kann entfallen, wenn bei existierenden Follows bereits abgekuerzt wurde
+        SwFrm* pFirst = pLayLeaf->Lower();
+        // Auch hier muessen zum Loeschen angemeldete SectionFrms ignoriert werden
+        while( pFirst && pFirst->IsSctFrm() && !((SwSectionFrm*)pFirst)->GetSection() )
+            pFirst = pFirst->GetNext();
+        if( pFirst && pFirst->IsSctFrm() && pSect->GetFollow() == pFirst )
+            pNew = pSect->GetFollow();
+        else
+        {
+            pNew = new SwSectionFrm( *pSect, FALSE );
+            pNew->InsertBefore( pLayLeaf, pLayLeaf->Lower() );
+
+            pNew->Frm().Pos() = pLayLeaf->Frm().Pos();
+            pNew->Frm().Pos().Y() += 1; //wg. Benachrichtigungen.
+
+            // Wenn unser Bereichsframe einen Nachfolger hat, so muss dieser
+            // umgehaengt werden hinter den neuen Follow der Bereichsframes.
+            SwFrm* pTmp = pSect->GetNext();
+            if( pTmp && pTmp != pSect->GetFollow() )
+            {
+                SwFlowFrm* pNxt;
+                SwCntntFrm* pNxtCntnt = NULL;
+                if( pTmp->IsCntntFrm() )
+                {
+                    pNxt = (SwCntntFrm*)pTmp;
+                    pNxtCntnt = (SwCntntFrm*)pTmp;
+                }
+                else
+                {
+                    pNxtCntnt = ((SwLayoutFrm*)pTmp)->ContainsCntnt();
+                    if( pTmp->IsSctFrm() )
+                        pNxt = (SwSectionFrm*)pTmp;
+                    else
+                    {
+                        ASSERT( pTmp->IsTabFrm(), "GetNextSctLeaf: Wrong Type" );
+                        pNxt = (SwTabFrm*)pTmp;
+                    }
+                    while( !pNxtCntnt && 0 != ( pTmp = pTmp->GetNext() ) )
+                    {
+                        if( pTmp->IsCntntFrm() )
+                            pNxtCntnt = (SwCntntFrm*)pTmp;
+                        else
+                            pNxtCntnt = ((SwLayoutFrm*)pTmp)->ContainsCntnt();
+                    }
+                }
+                if( pNxtCntnt )
+                {
+                    SwFtnBossFrm* pOldBoss = pSect->FindFtnBossFrm( TRUE );
+                    if( pOldBoss == pNxtCntnt->FindFtnBossFrm( TRUE ) )
+                    {
+                        SwSaveFtnHeight aHeight( pOldBoss,
+                            pOldBoss->Frm().Top() + pOldBoss->Frm().Height() );
+                        pSect->GetUpper()->MoveLowerFtns( pNxtCntnt, pOldBoss,
+                                    pLayLeaf->FindFtnBossFrm( TRUE ), FALSE );
+                    }
+                }
+                ((SwFlowFrm*)pNxt)->MoveSubTree( pLayLeaf, pNew->GetNext() );
+            }
+            if( pNew->GetFollow() )
+                pNew->SimpleFormat();
+        }
+        // Das gesuchte Layoutblatt ist jetzt das erste des ermittelten SctFrms:
+        pLayLeaf = FIRSTLEAF( pNew );
+    }
+    return pLayLeaf;
+}
+
+/*************************************************************************
+|*
+|*  SwFrm::GetPrevSctLeaf()
+|*
+|*  Beschreibung        Liefert das vorhergehende LayoutBlatt in das der
+|*      Frame gemoved werden kann.
+|*  Ersterstellung      AMA 07. Jan. 98
+|*  Letzte Aenderung    AMA 07. Jan. 98
+|*
+|*************************************************************************/
+
+
+SwLayoutFrm *SwFrm::GetPrevSctLeaf( MakePageType eMakeFtn )
+{
+    PROTOCOL_ENTER( this, PROT_LEAF, ACT_PREV_SECT, GetUpper()->FindSctFrm() )
+
+    SwLayoutFrm* pCol;
+    // ColumnFrm beinhalten jetzt stets einen BodyFrm
+    if( IsColBodyFrm() )
+        pCol = GetUpper();
+    else if( GetUpper()->IsColBodyFrm() )
+        pCol = GetUpper()->GetUpper();
+    else
+        pCol = NULL;
+    BOOL bJump = FALSE;
+    if( pCol )
+    {
+        if( pCol->GetPrev() )
+        {
+            do
+            {
+                pCol = (SwLayoutFrm*)pCol->GetPrev();
+                // Gibt es dort Inhalt?
+                if( ((SwLayoutFrm*)pCol->Lower())->Lower() )
+                {
+                    if( bJump )     // Haben wir eine leere Spalte uebersprungen?
+                        SwFlowFrm::SetMoveBwdJump( TRUE );
+                    return (SwLayoutFrm*)pCol->Lower();  // Der Spaltenbody
+                }
+                bJump = TRUE;
+            } while( pCol->GetPrev() );
+
+            // Hier landen wir, wenn alle Spalten leer sind,
+            // pCol ist jetzt die erste Spalte, wir brauchen aber den Body:
+            pCol = (SwLayoutFrm*)pCol->Lower();
+        }
+        else
+            pCol = NULL;
+    }
+
+    if( bJump )     // Haben wir eine leere Spalte uebersprungen?
+        SwFlowFrm::SetMoveBwdJump( TRUE );
+
+    // Innerhalb von Bereichen in Tabellen oder Bereichen in Kopf/Fusszeilen kann
+    // nur ein Spaltenwechsel erfolgen, eine der oberen Abkuerzungen haette
+    // zuschlagen muessen, ebenso wenn der Bereich einen pPrev hat.
+    // Jetzt ziehen wir sogar eine leere Spalte in Betracht...
+    ASSERT( FindSctFrm(), "GetNextSctLeaf: Missing SectionFrm" );
+    if( ( IsInTab() && !IsTabFrm() ) || FindFooterOrHeader() )
+        return pCol;
+
+    SwSectionFrm *pSect = FindSctFrm();
+    SwFrm *pPrv;
+    if( 0 != ( pPrv = pSect->GetIndPrev() ) )
+    {
+        // Herumlungernde, halbtote SectionFrms sollen uns nicht beirren
+        while( pPrv && pPrv->IsSctFrm() && !((SwSectionFrm*)pPrv)->GetSection() )
+            pPrv = pPrv->GetPrev();
+        if( pPrv )
+            return pCol;
+    }
+
+    const BOOL bBody = IsInDocBody();
+    const BOOL bFly  = IsInFly();
+
+    SwLayoutFrm *pLayLeaf = GetPrevLayoutLeaf();
+    SwLayoutFrm *pPrevLeaf = 0;
+
+    while ( pLayLeaf )
+    {   //In Tabellen oder Bereiche geht's niemals hinein.
+        if ( pLayLeaf->IsInTab() || pLayLeaf->IsInSct() )
+            pLayLeaf = pLayLeaf->GetPrevLayoutLeaf();
+        else if ( bBody && pLayLeaf->IsInDocBody() )
+        {
+            if ( pLayLeaf->Lower() )
+                break;
+            pPrevLeaf = pLayLeaf;
+            pLayLeaf = pLayLeaf->GetPrevLayoutLeaf();
+            if ( pLayLeaf )
+                SwFlowFrm::SetMoveBwdJump( TRUE );
+        }
+        else if ( bFly )
+            break;  //Cntnts in Flys sollte jedes Layout-Blatt recht sein. Warum?
+        else
+            pLayLeaf = pLayLeaf->GetPrevLayoutLeaf();
+    }
+    if( !pLayLeaf )
+    {
+        if( !pPrevLeaf )
+            return pCol;
+        pLayLeaf = pPrevLeaf;
+    }
+
+    SwSectionFrm* pNew = NULL;
+    // Zunaechst einmal an das Ende des Layoutblatts gehen
+    SwFrm *pTmp = pLayLeaf->Lower();
+    if( pTmp )
+    {
+        while( pTmp->GetNext() )
+            pTmp = pTmp->GetNext();
+        if( pTmp->IsSctFrm() )
+        {
+            // Halbtote stoeren hier nur...
+            while( !((SwSectionFrm*)pTmp)->GetSection() && pTmp->GetPrev() &&
+                    pTmp->GetPrev()->IsSctFrm() )
+                pTmp = pTmp->GetPrev();
+            if( ((SwSectionFrm*)pTmp)->GetFollow() == pSect )
+                pNew = (SwSectionFrm*)pTmp;
+        }
+    }
+    if( !pNew )
+    {
+        pNew = new SwSectionFrm( *pSect, TRUE );
+        pNew->InsertBefore( pLayLeaf, NULL );
+        if( pNew->GetPrev() )
+        {
+            pNew->Frm().Pos() = pNew->GetPrev()->Frm().Pos();
+            pNew->Frm().Pos().Y() += pNew->GetPrev()->Frm().Height();
+        }
+        else
+            pNew->Frm().Pos() = pLayLeaf->Frm().Pos();
+        pNew->Frm().Pos().Y() += 1; //wg. Benachrichtigungen.
+
+        pLayLeaf = FIRSTLEAF( pNew );
+        if( !pNew->Lower() )    // einspaltige Bereiche formatieren
+        {
+            pNew->MakePos();
+            pLayLeaf->Format(); // damit die PrtArea fuers MoveBwd stimmt
+        }
+        else
+            pNew->SimpleFormat();
+    }
+    else
+    {
+        pLayLeaf = FIRSTLEAF( pNew );
+        if( pLayLeaf->IsColBodyFrm() )
+        {   // Bei bereits vorhandenen spaltigen Bereichen suchen wir den Body der letzten Spalte
+            while( pLayLeaf->GetUpper()->GetNext() )
+                pLayLeaf = (SwLayoutFrm*)((SwLayoutFrm*)pLayLeaf->GetUpper()->GetNext())->Lower();
+        }
+    }
+    return pLayLeaf;
+}
+
+SwTwips lcl_DeadLine( const SwFrm* pFrm )
+{
+    const SwLayoutFrm* pUp = pFrm->GetUpper();
+    while( pUp && pUp->IsInSct() )
+    {
+        if( pUp->IsSctFrm() )
+            pUp = pUp->GetUpper();
+        // Spalten jetzt mit BodyFrm
+        else if( pUp->IsColBodyFrm() && pUp->GetUpper()->GetUpper()->IsSctFrm() )
+            pUp = pUp->GetUpper()->GetUpper();
+        else
+            break;
+    }
+    return pUp ? pUp->Frm().Top() + pUp->Prt().Top() + pUp->Prt().Height() :
+                 pFrm->Frm().Top() + pFrm->Frm().Height();
+}
+
+// SwSectionFrm::Growable(..) prueft, ob der SectionFrm noch wachsen kann,
+// ggf. muss die Umgebung gefragt werden
+
+BOOL SwSectionFrm::Growable() const
+{
+    if( Frm().Top() + Frm().Height() < lcl_DeadLine( this ) )
+        return TRUE;
+    return ( GetUpper() && ((SwFrm*)GetUpper())->Grow( LONG_MAX, pHeight, TRUE ) );
+}
+
+/*************************************************************************
+|*
+|*  SwSectionFrm::_Grow(), _Shrink()
+|*
+|*  Ersterstellung      AMA 14. Jan. 98
+|*  Letzte Aenderung    AMA 14. Jan. 98
+|*
+|*************************************************************************/
+
+SwTwips SwSectionFrm::_Grow( SwTwips nDist, const SzPtr pDirection, BOOL bTst )
+{
+    if ( !IsColLocked() && !HasFixSize( pDirection ) )
+    {
+        if ( Frm().SSize().*pDirection > 0 &&
+             nDist > (LONG_MAX - Frm().SSize().*pDirection) )
+            nDist = LONG_MAX - Frm().SSize().*pDirection;
+
+        if ( nDist <= 0L )
+            return 0L;
+
+        BOOL bInCalcCntnt = IsInFly() && FindFlyFrm()->IsLocked();
+        if ( !Lower() || !Lower()->IsColumnFrm() || !Lower()->GetNext() ||
+             GetSection()->GetFmt()->GetBalancedColumns().GetValue() )
+        {
+            SwTwips nGrow = IsInFtn() ? 0 :
+                lcl_DeadLine( this ) - Frm().Top() - Frm().Height();
+            SwTwips nSpace = nGrow;
+            if( !bInCalcCntnt && nGrow < nDist )
+                nGrow += GetUpper()->Grow( LONG_MAX, pHeight, TRUE );
+
+            if( nGrow > nDist )
+                nGrow = nDist;
+            if( nGrow <= 0 )
+            {
+                nGrow = 0;
+                if( nDist && !bTst )
+                {
+                    if( bInCalcCntnt )
+                        _InvalidateSize();
+                    else
+                        InvalidateSize();
+                }
+            }
+            else if( !bTst )
+            {
+                if( bInCalcCntnt )
+                    _InvalidateSize();
+                else if( nSpace < nGrow &&  nDist != nSpace + GetUpper()->
+                         Grow( nGrow - nSpace, pDirection, FALSE ) )
+                    InvalidateSize();
+                else
+                {
+                    const SvxGraphicPosition ePos =
+                        GetAttrSet()->GetBackground().GetGraphicPos();
+                    if ( GPOS_RT < ePos && GPOS_TILED != ePos )
+                    {
+                        SetCompletePaint();
+                        InvalidatePage();
+                    }
+                }
+                Frm().SSize().*pDirection += nGrow;
+                Prt().SSize().*pDirection += nGrow;
+                if( Lower() && Lower()->IsColumnFrm() && Lower()->GetNext() )
+                {
+                    SwFrm* pTmp = Lower();
+                    do
+                    {
+                        pTmp->_InvalidateSize();
+                        pTmp = pTmp->GetNext();
+                    } while ( pTmp );
+                    _InvalidateSize();
+                }
+                if( GetNext() )
+                {
+                    SwFrm *pFrm = GetNext();
+                    while( pFrm && pFrm->IsSctFrm() && !((SwSectionFrm*)pFrm)->GetSection() )
+                        pFrm = pFrm->GetNext();
+                    if( pFrm )
+                    {
+                        if( bInCalcCntnt )
+                            pFrm->_InvalidatePos();
+                        else
+                            pFrm->InvalidatePos();
+                    }
+                }
+            }
+            return nGrow;
+        }
+        if ( !bTst )
+        {
+            if( bInCalcCntnt )
+                _InvalidateSize();
+            else
+                InvalidateSize();
+        }
+    }
+    return 0L;
+}
+
+SwTwips SwSectionFrm::_Shrink( SwTwips nDist, const SzPtr pDirection, BOOL bTst )
+{
+    if ( Lower() && !IsColLocked() && !HasFixSize( pDirection ) )
+    {
+        if( ToMaximize( FALSE ) )
+        {
+            if( !bTst )
+                InvalidateSize();
+        }
+        else
+        {
+            if ( nDist > Frm().SSize().*pDirection )
+                nDist = Frm().SSize().*pDirection;
+
+            if ( Lower()->IsColumnFrm() && Lower()->GetNext() && // FtnAtEnd
+                 !GetSection()->GetFmt()->GetBalancedColumns().GetValue() )
+            {   //Bei Spaltigkeit ubernimmt das Format die Kontrolle ueber
+                //das Wachstum (wg. des Ausgleichs).
+                if ( !bTst )
+                {
+#ifdef USED
+                    Frm().SSize().*pDirection -= nDist;
+                    Prt().SSize().*pDirection -= nDist;
+#endif
+                    InvalidateSize();
+#ifdef USED
+                    if( !GetNext() )
+                        SetRetouche();
+                    GetUpper()->Shrink( nDist, pDirection, FALSE );
+#endif
+                }
+                return nDist;
+            }
+            else if( !bTst )
+            {
+                const SvxGraphicPosition ePos =
+                    GetAttrSet()->GetBackground().GetGraphicPos();
+                if ( GPOS_RT < ePos && GPOS_TILED != ePos )
+                {
+                    SetCompletePaint();
+                    InvalidatePage();
+                }
+                Frm().SSize().*pDirection -= nDist;
+                Prt().SSize().*pDirection -= nDist;
+                const SwTwips nReal = GetUpper()->Shrink( nDist, pDirection, bTst );
+                if( Lower() && Lower()->IsColumnFrm() && Lower()->GetNext() )
+                {
+                    SwFrm* pTmp = Lower();
+                    do
+                    {
+                        pTmp->_InvalidateSize();
+                        pTmp = pTmp->GetNext();
+                    } while ( pTmp );
+                }
+                if( GetNext() )
+                {
+                    SwFrm* pFrm = GetNext();
+                    while( pFrm && pFrm->IsSctFrm() && !((SwSectionFrm*)pFrm)->GetSection() )
+                        pFrm = pFrm->GetNext();
+                    if( pFrm )
+                        pFrm->InvalidatePos();
+                    else
+                        SetRetouche();
+                }
+                else
+                    SetRetouche();
+                return nDist;
+            }
+        }
+    }
+    return 0L;
+}
+
+/*************************************************************************
+|*
+|*  SwSectionFrm::MoveAllowed()
+|*
+|*  Ersterstellung      MA 08. Oct. 98
+|*  Letzte Aenderung    MA 08. Oct. 98
+|*
+|*  Wann sind Frms innerhalb eines SectionFrms moveable?
+|*  Wenn sie noch nicht in der letzten Spalte des SectionFrms sind,
+|*  wenn es einen Follow gibt,
+|*  wenn der SectionFrm nicht mehr wachsen kann, wird es komplizierter,
+|*  dann kommt es darauf an, ob der SectionFrm ein naechstes Layoutblatt
+|*  finden kann. In (spaltigen/verketteten) Flys wird dies via GetNextLayout
+|*  geprueft, in Tabellen und in Kopf/Fusszeilen gibt es keins, im DocBody
+|*  und auch im Fussnoten dagegen immer.
+|*
+|*  Benutzt wird diese Routine im TxtFormatter, um zu entscheiden, ob ein
+|*  (Absatz-)Follow erzeugt werden darf oder ob der Absatz zusammenhalten muss.
+|*
+|*************************************************************************/
+
+BOOL SwSectionFrm::MoveAllowed( const SwFrm* pFrm) const
+{
+    // Gibt es einen Follow oder ist der Frame nicht in der letzten Spalte?
+    if( HasFollow() || ( pFrm->GetUpper()->IsColBodyFrm() &&
+        pFrm->GetUpper()->GetUpper()->GetNext() ) )
+        return TRUE;
+    if( pFrm->IsInFtn() )
+    {
+        if( IsInFtn() )
+        {
+            if( GetUpper()->IsInSct() )
+            {
+                if( Growable() )
+                    return FALSE;
+                return GetUpper()->FindSctFrm()->MoveAllowed( this );
+            }
+            else
+                return TRUE;
+        }
+        // The content of footnote inside a columned sectionfrm is moveable
+        // except in the last column
+        const SwLayoutFrm *pLay = pFrm->FindFtnFrm()->GetUpper()->GetUpper();
+        if( pLay->IsColumnFrm() && pLay->GetNext() )
+        {
+            // The first paragraph in the first footnote in the first column
+            // in the sectionfrm at the top of the page is not moveable,
+            // if the columnbody is empty.
+            BOOL bRet = FALSE;
+            if( pLay->GetIndPrev() || pFrm->GetIndPrev() ||
+                pFrm->FindFtnFrm()->GetPrev() )
+                bRet = TRUE;
+            else
+            {
+                SwLayoutFrm* pBody = ((SwColumnFrm*)pLay)->FindBodyCont();
+                if( pBody && pBody->Lower() )
+                    bRet = TRUE;
+            }
+            if( bRet && ( IsFtnAtEnd() || !Growable() ) )
+                return TRUE;
+        }
+    }
+    // Oder kann der Bereich noch wachsen?
+    if( !IsColLocked() && Growable() )
+        return FALSE;
+    // Jetzt muss untersucht werden, ob es ein Layoutblatt gibt, in dem
+    // ein Bereichsfollow erzeugt werden kann.
+    if( IsInTab() || ( !IsInDocBody() && FindFooterOrHeader() ) )
+        return FALSE; // In Tabellen/Kopf/Fusszeilen geht es nicht
+    if( IsInFly() ) // Bei spaltigen oder verketteten Rahmen
+        return 0 != ((SwFrm*)GetUpper())->GetNextLeaf( MAKEPAGE_NONE );
+    return TRUE;
+}
+
+SwFrm* SwFrm::_GetIndPrev()
+{
+    SwFrm *pRet = NULL;
+    ASSERT( !pPrev && IsInSct(), "Why?" );
+    SwFrm* pSct = GetUpper();
+    if( !pSct )
+        return NULL;
+    if( pSct->IsSctFrm() )
+        pRet = pSct->GetIndPrev();
+    else if( pSct->IsColBodyFrm() && (pSct = pSct->GetUpper()->GetUpper())->IsSctFrm() )
+    {   // Wir duerfen nur den Vorgaenger des SectionFrms zurueckliefern,
+        // wenn in keiner vorhergehenden Spalte mehr Inhalt ist
+        SwFrm* pCol = GetUpper()->GetUpper()->GetPrev();
+        while( pCol )
+        {
+            ASSERT( pCol->IsColumnFrm(), "GetIndPrev(): ColumnFrm expected" );
+            ASSERT( pCol->GetLower() && pCol->GetLower()->IsBodyFrm(),
+                    "GetIndPrev(): Where's the body?");
+            if( ((SwLayoutFrm*)((SwLayoutFrm*)pCol)->Lower())->Lower() )
+                return NULL;
+            pCol = pCol->GetPrev();
+        }
+        pRet = pSct->GetIndPrev();
+    }
+    // Scheintote SectionFrames ueberspringen wir lieber
+    while( pRet && pRet->IsSctFrm() && !((SwSectionFrm*)pRet)->GetSection() )
+        pRet = pRet->GetIndPrev();
+    return pRet;
+}
+
+SwFrm* SwFrm::_GetIndNext()
+{
+    ASSERT( !pNext && IsInSct(), "Why?" );
+    SwFrm* pSct = GetUpper();
+    if( !pSct )
+        return NULL;
+    if( pSct->IsSctFrm() )
+        return pSct->GetIndNext();
+    if( pSct->IsColBodyFrm() && (pSct = pSct->GetUpper()->GetUpper())->IsSctFrm() )
+    {   // Wir duerfen nur den Nachfolger des SectionFrms zurueckliefern,
+        // wenn in keiner folgenden Spalte mehr Inhalt ist
+        SwFrm* pCol = GetUpper()->GetUpper()->GetNext();
+        while( pCol )
+        {
+            ASSERT( pCol->IsColumnFrm(), "GetIndNext(): ColumnFrm expected" );
+            ASSERT( pCol->GetLower() && pCol->GetLower()->IsBodyFrm(),
+                    "GetIndNext(): Where's the body?");
+            if( ((SwLayoutFrm*)((SwLayoutFrm*)pCol)->Lower())->Lower() )
+                return NULL;
+            pCol = pCol->GetNext();
+        }
+        return pSct->GetIndNext();
+    }
+    return NULL;
+}
+
+BOOL SwSectionFrm::IsAncestorOf( const SwSection* pSect ) const
+{
+    if( !pSection || !pSect )
+        return FALSE;
+    const SwSectionFmt *pFmt = pSect->GetFmt();
+    const SwSectionFmt *pMyFmt = pSection->GetFmt();
+    while( pFmt != pMyFmt )
+    {
+        if( pFmt->GetRegisteredIn()->ISA( SwSectionFmt ) )
+            pFmt = (SwSectionFmt*)pFmt->GetRegisteredIn();
+        else
+            return FALSE;
+    }
+    return TRUE;
+}
+
+BOOL SwSectionFrm::IsDescendantFrom( const SwSectionFmt* pFmt ) const
+{
+    if( !pSection || !pFmt )
+        return FALSE;
+    const SwSectionFmt *pMyFmt = pSection->GetFmt();
+    while( pFmt != pMyFmt )
+    {
+        if( pMyFmt->GetRegisteredIn()->ISA( SwSectionFmt ) )
+            pMyFmt = (SwSectionFmt*)pMyFmt->GetRegisteredIn();
+        else
+            return FALSE;
+    }
+    return TRUE;
+}
+
+void SwSectionFrm::CalcFtnAtEndFlag()
+{
+    SwSectionFmt *pFmt = GetSection()->GetFmt();
+    USHORT nVal = pFmt->GetFtnAtTxtEnd( FALSE ).GetValue();
+    bFtnAtEnd = FTNEND_ATPGORDOCEND != nVal;
+    bOwnFtnNum = FTNEND_ATTXTEND_OWNNUMSEQ == nVal ||
+                 FTNEND_ATTXTEND_OWNNUMANDFMT == nVal;
+    while( !bFtnAtEnd && !bOwnFtnNum )
+    {
+        if( pFmt->GetRegisteredIn()->ISA( SwSectionFmt ) )
+            pFmt = (SwSectionFmt*)pFmt->GetRegisteredIn();
+        else
+            break;
+        nVal = pFmt->GetFtnAtTxtEnd( FALSE ).GetValue();
+        if( FTNEND_ATPGORDOCEND != nVal )
+        {
+            bFtnAtEnd = TRUE;
+            bOwnFtnNum = bOwnFtnNum ||FTNEND_ATTXTEND_OWNNUMSEQ == nVal ||
+                         FTNEND_ATTXTEND_OWNNUMANDFMT == nVal;
+        }
+    }
+}
+
+BOOL SwSectionFrm::IsEndnoteAtMyEnd() const
+{
+    return pSection->GetFmt()->GetEndAtTxtEnd( FALSE ).IsAtEnd();
+}
+
+void SwSectionFrm::CalcEndAtEndFlag()
+{
+    SwSectionFmt *pFmt = GetSection()->GetFmt();
+    bEndnAtEnd = pFmt->GetEndAtTxtEnd( FALSE ).IsAtEnd();
+    while( !bEndnAtEnd )
+    {
+        if( pFmt->GetRegisteredIn()->ISA( SwSectionFmt ) )
+            pFmt = (SwSectionFmt*)pFmt->GetRegisteredIn();
+        else
+            break;
+        bEndnAtEnd = pFmt->GetEndAtTxtEnd( FALSE ).IsAtEnd();
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwSectionFrm::Modify()
+|*
+|*  Ersterstellung      MA 08. Oct. 98
+|*  Letzte Aenderung    MA 08. Oct. 98
+|*
+|*************************************************************************/
+
+void SwSectionFrm::Modify( SfxPoolItem * pOld, SfxPoolItem * pNew )
+{
+    BYTE nInvFlags = 0;
+
+    if( pNew && RES_ATTRSET_CHG == pNew->Which() )
+    {
+        SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() );
+        SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() );
+        SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld );
+        SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew );
+        while( TRUE )
+        {
+            _UpdateAttr( (SfxPoolItem*)aOIter.GetCurItem(),
+                         (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags,
+                         &aOldSet, &aNewSet );
+            if( aNIter.IsAtEnd() )
+                break;
+            aNIter.NextItem();
+            aOIter.NextItem();
+        }
+        if ( aOldSet.Count() || aNewSet.Count() )
+            SwLayoutFrm::Modify( &aOldSet, &aNewSet );
+    }
+    else
+        _UpdateAttr( pOld, pNew, nInvFlags );
+
+    if ( nInvFlags != 0 )
+    {
+        if ( nInvFlags & 0x01 )
+            InvalidateSize();
+        if ( nInvFlags & 0x10 )
+            SetCompletePaint();
+    }
+}
+
+void SwSectionFrm::_UpdateAttr( SfxPoolItem *pOld, SfxPoolItem *pNew,
+                            BYTE &rInvFlags,
+                            SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet )
+{
+    BOOL bClear = TRUE;
+    const USHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
+    switch( nWhich )
+    {   // Mehrspaltigkeit in Fussnoten unterdruecken...
+        case RES_FMT_CHG:
+        {
+            const SwFmtCol& rNewCol = GetFmt()->GetCol();
+            if( !IsInFtn() )
+            {
+                //Dummer Fall. Bei der Zuweisung einer Vorlage k”nnen wir uns
+                //nicht auf das alte Spaltenattribut verlassen. Da diese
+                //wenigstens anzahlgemass fuer ChgColumns vorliegen muessen,
+                //bleibt uns nur einen temporaeres Attribut zu basteln.
+                SwFmtCol aCol;
+                if ( Lower() && Lower()->IsColumnFrm() )
+                {
+                    USHORT nCol = 0;
+                    SwFrm *pTmp = Lower();
+                    do
+                    {   ++nCol;
+                        pTmp = pTmp->GetNext();
+                    } while ( pTmp );
+                    aCol.Init( nCol, 0, 1000 );
+                }
+                BOOL bChgFtn = IsFtnAtEnd();
+                BOOL bChgEndn = IsEndnAtEnd();
+                BOOL bChgMyEndn = IsEndnoteAtMyEnd();
+                CalcFtnAtEndFlag();
+                CalcEndAtEndFlag();
+                bChgFtn = ( bChgFtn != IsFtnAtEnd() ) ||
+                          ( bChgEndn != IsEndnAtEnd() ) ||
+                          ( bChgMyEndn != IsEndnoteAtMyEnd() );
+                ChgColumns( aCol, rNewCol, bChgFtn );
+                rInvFlags |= 0x10;
+            }
+            rInvFlags |= 0x01;
+            bClear = FALSE;
+        }
+            break;
+
+        case RES_COL:
+            if( !IsInFtn() )
+            {
+                ChgColumns( *(const SwFmtCol*)pOld, *(const SwFmtCol*)pNew );
+                rInvFlags |= 0x11;
+            }
+            break;
+
+        case RES_FTN_AT_TXTEND:
+            if( !IsInFtn() )
+            {
+                BOOL bOld = IsFtnAtEnd();
+                CalcFtnAtEndFlag();
+                if( bOld != IsFtnAtEnd() )
+                {
+                    const SwFmtCol& rNewCol = GetFmt()->GetCol();
+                    ChgColumns( rNewCol, rNewCol, TRUE );
+                    rInvFlags |= 0x01;
+                }
+            }
+            break;
+
+        case RES_END_AT_TXTEND:
+            if( !IsInFtn() )
+            {
+                BOOL bOld = IsEndnAtEnd();
+                BOOL bMyOld = IsEndnoteAtMyEnd();
+                CalcEndAtEndFlag();
+                if( bOld != IsEndnAtEnd() || bMyOld != IsEndnoteAtMyEnd())
+                {
+                    const SwFmtCol& rNewCol = GetFmt()->GetCol();
+                    ChgColumns( rNewCol, rNewCol, TRUE );
+                    rInvFlags |= 0x01;
+                }
+            }
+            break;
+        case RES_COLUMNBALANCE:
+            rInvFlags |= 0x01;
+            break;
+
+        default:
+            bClear = FALSE;
+    }
+    if ( bClear )
+    {
+        if ( pOldSet || pNewSet )
+        {
+            if ( pOldSet )
+                pOldSet->ClearItem( nWhich );
+            if ( pNewSet )
+                pNewSet->ClearItem( nWhich );
+        }
+        else
+            SwLayoutFrm::Modify( pOld, pNew );
+    }
+}
+
+/*-----------------09.06.99 14:58-------------------
+ * SwSectionFrm::ToMaximize(..): A follow or a ftncontainer at the end of the
+ * page causes a maximal Size of the sectionframe.
+ * --------------------------------------------------*/
+
+BOOL SwSectionFrm::ToMaximize( BOOL bCheckFollow ) const
+{
+    if( HasFollow() )
+    {
+        if( !bCheckFollow ) // Don't check superfluous follows
+            return TRUE;
+        const SwSectionFrm* pFoll = GetFollow();
+        while( pFoll && pFoll->IsSuperfluous() )
+            pFoll = pFoll->GetFollow();
+        if( pFoll )
+            return TRUE;
+    }
+    if( IsFtnAtEnd() )
+        return FALSE;
+    const SwFtnContFrm* pCont = ContainsFtnCont();
+    if( !IsEndnAtEnd() )
+        return 0 != pCont;
+    BOOL bRet = FALSE;
+    while( pCont && !bRet )
+    {
+        if( pCont->FindFootNote() )
+            bRet = TRUE;
+        else
+            pCont = ContainsFtnCont( pCont );
+    }
+    return bRet;
+}
+
+/*-----------------09.06.99 15:07-------------------
+ * BOOL SwSectionFrm::ContainsFtnCont()
+ * checks every Column for FtnContFrms.
+ * --------------------------------------------------*/
+
+SwFtnContFrm* SwSectionFrm::ContainsFtnCont( const SwFtnContFrm* pCont ) const
+{
+    SwFtnContFrm* pRet = NULL;
+    const SwLayoutFrm* pLay;
+    if( pCont )
+    {
+        pLay = pCont->FindFtnBossFrm( NULL );
+        ASSERT( IsAnLower( pLay ), "ConatainsFtnCont: Wrong FtnContainer" );
+        pLay = (SwLayoutFrm*)pLay->GetNext();
+    }
+    else if( Lower() && Lower()->IsColumnFrm() )
+        pLay = (SwLayoutFrm*)Lower();
+    else
+        pLay = NULL;
+    while ( !pRet && pLay )
+    {
+        if( pLay->Lower() && pLay->Lower()->GetNext() )
+        {
+            ASSERT( pLay->Lower()->GetNext()->IsFtnContFrm(),
+                    "ToMaximize: Unexspected Frame" );
+            pRet = (SwFtnContFrm*)pLay->Lower()->GetNext();
+        }
+        ASSERT( !pLay->GetNext() || pLay->GetNext()->IsLayoutFrm(),
+                "ToMaximize: ColFrm exspected" );
+        pLay = (SwLayoutFrm*)pLay->GetNext();
+    }
+    return pRet;
+}
+
+void SwSectionFrm::InvalidateFtnPos()
+{
+    SwFtnContFrm* pCont = ContainsFtnCont( NULL );
+    if( pCont )
+    {
+        SwFrm *pTmp = pCont->ContainsCntnt();
+        if( pTmp )
+            pTmp->_InvalidatePos();
+    }
+}
+
+/*-----------------18.03.99 10:37-------------------
+ * SwSectionFrm::Undersize() liefert den Betrag, um den der Bereich gern
+ * groesser waere, wenn in ihm Undersized TxtFrms liegen, ansonsten Null.
+ * Das Undersized-Flag wird ggf. korrigiert.
+ * --------------------------------------------------*/
+
+long lcl_InnerSize( SwLayoutFrm* pLay )
+{
+    SwFrm *pLow = pLay->Lower();
+    long nBot = 0;
+    while( pLow )
+    {
+        nBot += pLow->Frm().Height();
+        if( pLow->IsTxtFrm() && ((SwTxtFrm*)pLow)->IsUndersized() )
+            nBot += ((SwTxtFrm*)pLow)->GetParHeight() - pLow->Prt().Height();
+        pLow = pLow->GetNext();
+    }
+    return nBot;
+}
+
+long SwSectionFrm::Undersize( BOOL bOverSize )
+{
+    bUndersized = FALSE;
+    long nRet = InnerHeight() - Prt().Height();
+    if( nRet > 0 )
+        bUndersized = TRUE;
+    else if( !bOverSize )
+        nRet = 0;
+    return nRet;
+}
+
+void SwSectionFrm::CalcFtnCntnt()
+{
+    SwFtnContFrm* pCont = ContainsFtnCont();
+    if( pCont )
+    {
+        SwFrm* pFrm = pCont->ContainsAny();
+        if( pFrm )
+            pCont->Calc();
+        while( pFrm && IsAnLower( pFrm ) )
+        {
+            SwFtnFrm* pFtn = pFrm->FindFtnFrm();
+            if( pFtn )
+                pFtn->Calc();
+            pFrm->Calc();
+            if( pFrm->IsSctFrm() )
+            {
+                SwFrm *pTmp = ((SwSectionFrm*)pFrm)->ContainsAny();
+                if( pTmp )
+                {
+                    pFrm = pTmp;
+                    continue;
+                }
+            }
+            pFrm = pFrm->FindNext();
+        }
+    }
+}
+
+/* -----------------09.02.99 14:26-------------------
+ * Wenn ein SectionFrm leerlaeuft, z.B. weil sein Inhalt die Seite/Spalte wechselt,
+ * so wird er nicht sofort zerstoert (es koennte noch jemand auf dem Stack einen Pointer
+ * auf ihn halten), sondern er traegt sich in eine Liste am RootFrm ein, die spaeter
+ * abgearbeitet wird (in LayAction::Action u.a.). Seine Groesse wird auf Null gesetzt und
+ * sein Zeiger auf seine Section ebenfalls. Solche zum Loeschen vorgesehene SectionFrms
+ * muessen vom Layout/beim Formatieren ignoriert werden.
+ *
+ * Mit InsertEmptySct nimmt der RootFrm einen SectionFrm in die Liste auf,
+ * mit RemoveFromList kann ein SectionFrm wieder aus der Liste entfernt werden (Dtor),
+ * mit DeleteEmptySct wird die Liste abgearbeitet und die SectionFrms zerstoert
+ * --------------------------------------------------*/
+
+void SwRootFrm::InsertEmptySct( SwSectionFrm* pDel )
+{
+    if( !pDestroy )
+        pDestroy = new SwDestroyList;
+    USHORT nPos;
+    if( !pDestroy->Seek_Entry( pDel, &nPos ) )
+        pDestroy->Insert( pDel );
+}
+
+void SwRootFrm::_DeleteEmptySct()
+{
+    ASSERT( pDestroy, "Keine Liste, keine Kekse" );
+    while( pDestroy->Count() )
+    {
+        SwSectionFrm* pSect = (*pDestroy)[0];
+        pDestroy->Remove( USHORT(0) );
+        ASSERT( !pSect->IsColLocked() && !pSect->IsJoinLocked(),
+                "DeleteEmptySct: Locked SectionFrm" );
+        if( !pSect->Frm().HasArea() && !pSect->ContainsCntnt() )
+        {
+            SwLayoutFrm* pUp = pSect->GetUpper();
+            pSect->Remove();
+            delete pSect;
+            if( pUp && !pUp->Lower() )
+            {
+                if( pUp->IsPageBodyFrm() )
+                    pUp->FindRootFrm()->SetSuperfluous();
+                else if( pUp->IsFtnFrm() && !pUp->IsColLocked() &&
+                    pUp->GetUpper() )
+                {
+                    pUp->Cut();
+                    delete pUp;
+                }
+            }
+        }
+        else
+            ASSERT( pSect->GetSection(), "DeleteEmptySct: Halbtoter SectionFrm?!" );
+    }
+}
+
+void SwRootFrm::_RemoveFromList( SwSectionFrm* pSct )
+{
+    ASSERT( pDestroy, "Where's my list?" );
+    USHORT nPos;
+    if( pDestroy->Seek_Entry( pSct, &nPos ) )
+        pDestroy->Remove( nPos );
+}
+
+#ifndef PRODUCT
+
+BOOL SwRootFrm::IsInDelList( SwSectionFrm* pSct ) const
+{
+    USHORT nPos;
+    return ( pDestroy && pDestroy->Seek_Entry( pSct, &nPos ) );
+}
+
+#endif
+
diff --git a/sw/source/core/layout/ssfrm.cxx b/sw/source/core/layout/ssfrm.cxx
new file mode 100644
index 000000000000..b4fab9067001
--- /dev/null
+++ b/sw/source/core/layout/ssfrm.cxx
@@ -0,0 +1,345 @@
+/*************************************************************************
+ *
+ *  $RCSfile: ssfrm.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:22 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "pagefrm.hxx"
+#include "rootfrm.hxx"
+#include "cntfrm.hxx"
+#include "doc.hxx"
+#include "node.hxx"
+#include "errhdl.hxx"
+
+#include "dview.hxx"
+#include "dcontact.hxx"
+#include "dflyobj.hxx"
+#include "flyfrm.hxx"
+#include "txtfrm.hxx"       // ClearPara()
+
+#include "frmtool.hxx"
+#include "pagedesc.hxx"
+#define ITEMID_BOXINFO      SID_ATTR_BORDER_INNER
+#include "hints.hxx"        //fuer SwFmtChg
+#ifndef _SVX_BOXITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_SHADITEM_HXX //autogen
+#include 
+#endif
+
+/*************************************************************************
+|*
+|*  SwFrm::~SwFrm()
+|*
+|*  Ersterstellung      MA 02. Mar. 94
+|*  Letzte Aenderung    MA 25. Jun. 95
+|*
+|*************************************************************************/
+
+
+SwFrm::~SwFrm()
+{
+    if( pDrawObjs )
+    {
+        for ( USHORT i = pDrawObjs->Count(); i; )
+        {
+            SdrObject *pObj = (*pDrawObjs)[--i];
+            if ( pObj->IsWriterFlyFrame() )
+                delete ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+            else if ( pObj->GetUserCall() )
+                ((SwDrawContact*)pObj->GetUserCall())->DisconnectFromLayout();
+        }
+        if ( pDrawObjs )
+            delete pDrawObjs;
+    }
+}
+
+/*************************************************************************
+|*
+|*    SwLayoutFrm::SetFrmFmt()
+|*    Ersterstellung    MA 22. Apr. 93
+|*    Letzte Aenderung  MA 02. Nov. 94
+|*
+|*************************************************************************/
+
+
+void SwLayoutFrm::SetFrmFmt( SwFrmFmt *pNew )
+{
+    if ( pNew != GetFmt() )
+    {
+        SwFmtChg aOldFmt( GetFmt() );
+        pNew->Add( this );
+        SwFmtChg aNewFmt( pNew );
+        Modify( &aOldFmt, &aNewFmt );
+    }
+}
+
+/*************************************************************************
+|*
+|*    SwCntntFrm::SwCntntFrm(), ~SwCntntFrm()
+|*
+|*    Ersterstellung    AK 15-Feb-1991
+|*    Letzte Aenderung  MA 25. Apr. 95
+|*
+|*************************************************************************/
+
+
+SwCntntFrm::SwCntntFrm( SwCntntNode * const pCntnt ) :
+    SwFrm( pCntnt ),
+    SwFlowFrm( (SwFrm&)*this )
+{
+    nType = FRM_CNTNT;
+}
+
+
+
+SwCntntFrm::~SwCntntFrm()
+{
+    SwCntntNode* pCNd;
+    if( 0 != ( pCNd = PTR_CAST( SwCntntNode, pRegisteredIn )) &&
+        !pCNd->GetDoc()->IsInDtor() )
+    {
+        //Bei der Root abmelden wenn ich dort noch im Turbo stehe.
+        SwRootFrm *pRoot = FindRootFrm();
+        if( pRoot && pRoot->GetTurbo() == this )
+        {
+            pRoot->DisallowTurbo();
+            pRoot->ResetTurbo();
+        }
+    }
+    if( IsTxtFrm() && ((SwTxtFrm*)this)->HasBlinkPor() )
+        ((SwTxtFrm*)this)->ClearPara();
+}
+
+/*************************************************************************
+|*
+|*  SwLayoutFrm::~SwLayoutFrm
+|*
+|*  Ersterstellung      AK 28-Feb-1991
+|*  Letzte Aenderung    MA 11. Jan. 95
+|*
+|*************************************************************************/
+
+
+SwLayoutFrm::~SwLayoutFrm()
+{
+    SwFrm *pFrm = pLower;
+
+    if( GetFmt() && !GetFmt()->GetDoc()->IsInDtor() )
+    {
+        while ( pFrm )
+        {
+            //Erst die Objs des Frm vernichten, denn diese koennen sich sonst nach
+            //dem Remove nicht mehr bei der Seite abmelden.
+            //Falls sich einer nicht abmeldet wollen wir nicht gleich
+            //endlos schleifen.
+            USHORT nCnt;
+            while ( pFrm->GetDrawObjs() && pFrm->GetDrawObjs()->Count() )
+            {
+                nCnt = pFrm->GetDrawObjs()->Count();
+                SdrObject *pObj = (*pFrm->GetDrawObjs())[0];
+                if ( pObj->IsWriterFlyFrame() )
+                    delete ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+                else if ( pObj->GetUserCall() )
+                    ((SwDrawContact*)pObj->GetUserCall())->DisconnectFromLayout();
+
+                if ( pFrm->GetDrawObjs() &&
+                     nCnt == pFrm->GetDrawObjs()->Count() )
+                    pFrm->GetDrawObjs()->Remove( 0 );
+            }
+            pFrm->Remove();
+            delete pFrm;
+            pFrm = pLower;
+        }
+        //Fly's vernichten. Der letzte loescht gleich das Array.
+        USHORT nCnt;
+        while ( GetDrawObjs() && GetDrawObjs()->Count() )
+        {
+            nCnt = GetDrawObjs()->Count();
+            SdrObject *pObj = (*GetDrawObjs())[0];
+            if ( pObj->IsWriterFlyFrame() )
+                delete ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+            else if ( pObj->GetUserCall() )
+                ((SwDrawContact*)pObj->GetUserCall())->DisconnectFromLayout();
+
+            if ( GetDrawObjs() && nCnt == GetDrawObjs()->Count() )
+                GetDrawObjs()->Remove( 0 );
+        }
+    }
+    else
+    {
+        while( pFrm )
+        {
+            SwFrm *pNxt = pFrm->GetNext();
+            delete pFrm;
+            pFrm = pNxt;
+        }
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFrm::PaintArea()
+|*
+|*  Created     AMA 08/22/2000
+|*  Last change AMA 08/23/2000
+|*
+|*  The paintarea is the area, in which the content of a frame is allowed
+|*  to be displayed. This region could be larger than the printarea (Prt())
+|*  of the upper, it includes e.g. often the margin of the page.
+|*
+|*************************************************************************/
+
+const SwRect SwFrm::PaintArea() const
+{
+    SwRect aRect( Frm() );
+    long nRight = aRect.Right();
+    const SwFrm* pTmp = this;
+    BOOL bLeft = TRUE;
+    BOOL bRight = TRUE;
+    while( pTmp )
+    {
+        long nTmpRight = pTmp->Frm().Right();
+        ASSERT( pTmp, "PaintArea lost in time and space" );
+        if( pTmp->IsPageFrm() || pTmp->IsFlyFrm() ||
+            pTmp->IsCellFrm() || pTmp->IsRowFrm() || //nobody leaves a table!
+            pTmp->IsRootFrm() )
+        {
+            if( bLeft || aRect.Left() < pTmp->Frm().Left() )
+                aRect.Left( pTmp->Frm().Left() );
+            if( bRight || nTmpRight < nRight )
+                nRight = nTmpRight;
+            if( pTmp->IsPageFrm() || pTmp->IsFlyFrm() || pTmp->IsRootFrm() )
+                break;
+            bLeft = FALSE;
+            bRight = FALSE;
+        }
+        else if( pTmp->IsColumnFrm() )  // nobody enters neightbour columns
+        {
+            if( pTmp->GetPrev() )   // the first column has _no_
+            {                       // influence to the left range
+                if( bLeft || aRect.Left() < pTmp->Frm().Left() )
+                    aRect.Left( pTmp->Frm().Left() );
+                bLeft = FALSE;
+            }
+            if( pTmp->GetNext() )   // the last column has _no_
+            {                       // influence to the right range
+                if( bRight || nTmpRight < nRight )
+                nRight = nTmpRight;
+                bRight = FALSE;
+            }
+        }
+        pTmp = pTmp->GetUpper();
+    }
+    aRect.Right( nRight );
+    return aRect;
+}
+
+/*************************************************************************
+|*
+|*  SwFrm::UnionFrm()
+|*
+|*  Created     AMA 08/22/2000
+|*  Last change AMA 08/23/2000
+|*
+|*  The unionframe is the framearea (Frm()) of a frame expanded by the
+|*  printarea, if there's a negative margin at the left or right side.
+|*
+|*************************************************************************/
+
+const SwRect SwFrm::UnionFrm( BOOL bBorder ) const
+{
+    SwRect aRet( Frm() );
+    if( Prt().Left() < 0 )
+        aRet.Left( aRet.Left() + Prt().Left() );
+    if( Prt().Left() + Prt().Width() > Frm().Width() )
+        aRet.Width(aRet.Width() + Prt().Left() + Prt().Width() - Frm().Width());
+    if( bBorder )
+    {
+        SwBorderAttrAccess aAccess( SwFrm::GetCache(), this );
+        const SwBorderAttrs &rAttrs = *aAccess.Get();
+        const SvxBoxItem &rBox = rAttrs.GetBox();
+        if ( rBox.GetLeft() )
+            aRet.Left( aRet.Left() - rBox.CalcLineSpace( BOX_LINE_LEFT ) );
+        else if ( rAttrs.IsBorderDist() )
+            aRet.Left( aRet.Left() - rBox.GetDistance( BOX_LINE_LEFT ) - 1 );
+
+        if ( rBox.GetRight() )
+            aRet.SSize().Width() += rBox.CalcLineSpace( BOX_LINE_RIGHT );
+        else if ( rAttrs.IsBorderDist() )
+            aRet.SSize().Width() += rBox.GetDistance( BOX_LINE_RIGHT )  + 1;
+        if( rAttrs.GetShadow().GetLocation() != SVX_SHADOW_NONE )
+        {
+            const SvxShadowItem &rShadow = rAttrs.GetShadow();
+            aRet.Left( aRet.Left()- rShadow.CalcShadowSpace(SHADOW_LEFT) );
+            aRet.SSize().Width()  += rShadow.CalcShadowSpace(SHADOW_RIGHT);
+        }
+    }
+    return aRet;
+}
+
+
+
+
diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx
new file mode 100644
index 000000000000..0107f726b280
--- /dev/null
+++ b/sw/source/core/layout/tabfrm.cxx
@@ -0,0 +1,2573 @@
+/*************************************************************************
+ *
+ *  $RCSfile: tabfrm.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:22 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "pagefrm.hxx"
+#include "rootfrm.hxx"
+#include "cntfrm.hxx"
+#include "viewsh.hxx"
+#include "doc.hxx"
+#include "docsh.hxx"
+#include "viewimp.hxx"
+#include "swtable.hxx"
+#include "dflyobj.hxx"
+#include "flyfrm.hxx"
+#include "frmtool.hxx"
+#include "frmfmt.hxx"
+#include "dcontact.hxx"
+#include "viewopt.hxx"
+#include "hints.hxx"
+
+#include 
+
+#ifndef _SFXITEMITER_HXX //autogen
+#include 
+#endif
+
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _SVX_KEEPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_ULSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BRSHITEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _FMTTSPLT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTSRND_HXX //autogen
+#include 
+#endif
+#ifndef _FMTORNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTPDSC_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFSIZE_HXX //autogen
+#include 
+#endif
+#include "tabfrm.hxx"
+#include "rowfrm.hxx"
+#include "cellfrm.hxx"
+#include "flyfrms.hxx"
+#include "txtfrm.hxx"       //HasFtn()
+#include "htmltbl.hxx"
+#include "frmsh.hxx"
+#include "sectfrm.hxx"  //SwSectionFrm
+
+/*************************************************************************
+|*
+|*  SwTabFrm::SwTabFrm(), ~SwTabFrm()
+|*
+|*  Ersterstellung      MA 09. Mar. 93
+|*  Letzte Aenderung    MA 30. May. 96
+|*
+|*************************************************************************/
+SwTabFrm::SwTabFrm( SwTable &rTab ):
+    SwLayoutFrm( rTab.GetFrmFmt() ),
+    SwFlowFrm( (SwFrm&)*this ),
+    pTable( &rTab )
+{
+    bComplete = bCalcLowers = bONECalcLowers = bLowersFormatted = bLockBackMove =
+    bResizeHTMLTable = FALSE;
+    bFixHeight = FALSE;     //Nicht nochmal auf die Importfilter hereinfallen.
+    nType = FRM_TAB;
+
+    //Gleich die Zeilen erzeugen und einfuegen.
+    const SwTableLines &rLines = rTab.GetTabLines();
+    SwFrm *pPrev = 0;
+    for ( USHORT i = 0; i < rLines.Count(); ++i )
+    {
+        SwRowFrm *pNew = new SwRowFrm( *rLines[i] );
+        pNew->InsertBehind( this, pPrev );
+        pPrev = pNew;
+    }
+}
+
+SwTabFrm::SwTabFrm( SwTabFrm &rTab ) :
+    SwLayoutFrm( rTab.GetFmt() ),
+    SwFlowFrm( (SwFrm&)*this ),
+    pTable( rTab.GetTable() )
+{
+    bIsFollow = TRUE;
+    bLockJoin = bComplete = bONECalcLowers = bCalcLowers = bLowersFormatted = bLockBackMove =
+    bResizeHTMLTable = FALSE;
+    bFixHeight = FALSE;     //Nicht nochmal auf die Importfilter hereinfallen.
+    nType = FRM_TAB;
+
+    SetFollow( rTab.GetFollow() );
+    rTab.SetFollow( this );
+}
+
+SwTabFrm::~SwTabFrm()
+{
+}
+
+/*************************************************************************
+|*
+|*  SwTabFrm::JoinAndDelFollows()
+|*
+|*  Ersterstellung      MA 30. May. 96
+|*  Letzte Aenderung    MA 30. May. 96
+|*
+|*************************************************************************/
+void SwTabFrm::JoinAndDelFollows()
+{
+    SwTabFrm *pFoll = GetFollow();
+    if ( pFoll->HasFollow() )
+        pFoll->JoinAndDelFollows();
+    pFoll->Cut();
+    SetFollow( pFoll->GetFollow() );
+    delete pFoll;
+}
+
+/*************************************************************************
+|*
+|*  SwTabFrm::RegistFlys()
+|*
+|*  Ersterstellung      MA 08. Jul. 93
+|*  Letzte Aenderung    MA 27. Jan. 99
+|*
+|*************************************************************************/
+void SwTabFrm::RegistFlys()
+{
+    ASSERT( Lower() && Lower()->IsRowFrm(), "Keine Zeilen." );
+
+    SwPageFrm *pPage = FindPageFrm();
+    if ( pPage )
+    {
+        SwRowFrm *pRow = (SwRowFrm*)Lower();
+        do
+        {   pRow->RegistFlys( pPage );
+            pRow = (SwRowFrm*)pRow->GetNext();
+        } while ( pRow );
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwTabFrm::Split(), Join()
+|*
+|*  Ersterstellung      MA 03. Jun. 93
+|*  Letzte Aenderung    MA 03. Sep. 96
+|*
+|*************************************************************************/
+SwTwips SwTabFrm::Split( const SwTwips nCutPos )
+{
+    ASSERT( nCutPos >= Frm().Top() && nCutPos <= Frm().Bottom(),
+            "SplitLine ausserhalb der Tabelle." );
+
+    //Um die Positionen der Zellen mit der CutPos zu vergleichen muessen sie
+    //ausgehend von der Tabelle nacheinander berechnet werden. Sie koennen
+    //wg. Positionsaenderungen der Tabelle durchaus ungueltig sein.
+
+    SwFrm *pRow = Lower();
+    if( !pRow )
+        return 0;
+    SwTwips nRowPos = Frm().Top() + Prt().Top() + pRow->Frm().Height();
+    const BOOL bRepeat  = GetTable()->IsHeadlineRepeat();
+    pRow = pRow->GetNext();
+    if( pRow && bRepeat )
+    {
+        nRowPos += pRow->Frm().Height();
+        pRow = pRow->GetNext();
+    }
+    // No break before the first row and, in case of repeated headlines,
+    // before the the second row.
+    if( !pRow )
+        return 0;
+
+    while ( pRow && nCutPos > (nRowPos + pRow->Frm().Height() - 1) )
+    {
+        nRowPos += pRow->Frm().Height();
+        pRow = pRow->GetNext();
+    }
+
+    if ( !pRow )
+    {
+#ifdef DEBUG
+        ASSERT( FALSE, "Tablesplit out of rows?" );
+#endif
+        pRow = Lower();
+        while ( pRow && pRow->GetNext() )
+            pRow = pRow->GetNext();
+    }
+
+    //Wenn es bereits einen Follow gibt so geht's dort hinein andernfalls
+    //muss eben einer erzeugt werden.
+    FASTBOOL bNewFollow;
+    SwTabFrm *pFoll;
+    if ( GetFollow() )
+    {
+        pFoll = GetFollow();
+        bNewFollow = FALSE;
+    }
+    else
+    {
+        bNewFollow = TRUE;
+        pFoll = new SwTabFrm( *this );
+        pFoll->InsertBehind( GetUpper(), this );
+
+        if( bRepeat )
+        {   //Ueberschrift wiederholen.
+            ASSERT( GetTable()->GetTabLines()[0], "Table ohne Zeilen?" );
+            bDontCreateObjects = TRUE;              //frmtool
+            SwRowFrm *pHeadline = new SwRowFrm(
+                                    *GetTable()->GetTabLines()[0] );
+            bDontCreateObjects = FALSE;
+            pHeadline->InsertBefore( pFoll, 0 );
+        }
+    }
+    SwTwips nRet = 0;
+    SwFrm *pNxt;
+
+    //Optimierung beim neuen Follow braucht's kein Paste und dann kann
+    //das Optimierte Insert verwendet werden (nur dann treten gluecklicher weise
+    //auch groessere Mengen von Rows auf).
+    if ( bNewFollow )
+    {
+        SwFrm *pPrv = GetTable()->IsHeadlineRepeat() ? pFoll->Lower() : 0;
+        while ( pRow )
+        {
+            pNxt = pRow->GetNext();
+            nRet += pRow->Frm().Height();
+            pRow->Remove();
+            pRow->InsertBehind( pFoll, pPrv );
+            pRow->_InvalidateAll();
+            pPrv = pRow;
+            pRow = pNxt;
+        }
+    }
+    else
+    {
+        SwFrm *pPrv = pFoll->Lower();
+        if ( pPrv && GetTable()->IsHeadlineRepeat() )
+            pPrv = pPrv->GetNext();
+        while ( pRow )
+        {
+            pNxt = pRow->GetNext();
+            nRet += pRow->Frm().Height();
+            pRow->Remove();
+            pRow->Paste( pFoll, pPrv );
+            pRow = pNxt;
+        }
+    }
+    ASSERT( !bNewFollow || !pFoll->Frm().Height(), "Dont care about Performance");
+    Shrink( nRet, pHeight );
+    return nRet;
+}
+
+SwTwips SwTabFrm::Join()
+{
+    SwTabFrm *pFoll = GetFollow();
+    SwTwips nHeight = 0;    //Gesamthoehe der eingefuegten Zeilen als Return.
+
+    if ( !pFoll->IsJoinLocked() )
+    {
+        pFoll->Cut();   //Erst ausschneiden um unuetze Benachrichtigungen zu
+                        //minimieren.
+
+        SwFrm *pRow = pFoll->Lower(),
+              *pNxt;
+
+        if ( pRow && GetTable()->IsHeadlineRepeat() )
+            pRow = pRow->GetNext();
+
+        SwFrm *pPrv = Lower();
+        while ( pPrv && pPrv->GetNext() )
+            pPrv = pPrv->GetNext();
+        while ( pRow )
+        {
+            pNxt = pRow->GetNext();
+            nHeight += pRow->Frm().Height();
+            pRow->Remove();
+            pRow->_InvalidateAll();
+            pRow->InsertBehind( this, pPrv );
+            pPrv = pRow;
+            pRow = pNxt;
+        }
+        SetFollow( pFoll->GetFollow() );
+        delete pFoll;
+        Grow( nHeight, pHeight );
+    }
+    return nHeight;
+}
+
+/*************************************************************************
+|*
+|*  SwTabFrm::MakeAll()
+|*
+|*  Ersterstellung      MA 09. Mar. 93
+|*  Letzte Aenderung    MA 10. Apr. 97
+|*
+|*************************************************************************/
+void MA_FASTCALL SwInvalidatePositions( SwFrm *pFrm, long nBottom )
+{
+    do
+    {   pFrm->_InvalidatePos();
+        pFrm->_InvalidateSize();
+        if( pFrm->IsLayoutFrm() )
+        {
+            if ( ((SwLayoutFrm*)pFrm)->Lower() )
+                ::SwInvalidatePositions( ((SwLayoutFrm*)pFrm)->Lower(), nBottom);
+        }
+        else
+            pFrm->Prepare( PREP_ADJUST_FRM );
+        pFrm = pFrm->GetNext();
+    } while ( pFrm && pFrm->Frm().Top() < nBottom );
+}
+
+BOOL MA_FASTCALL lcl_CalcLowers( SwLayoutFrm *pLay, long nBottom )
+{
+    BOOL bRet = FALSE;
+    SwCntntFrm *pCnt = pLay->ContainsCntnt();
+    while ( pCnt && pLay->GetUpper()->IsAnLower( pCnt ) )
+    {
+        bRet |= !pCnt->IsValid();
+        pCnt->CalcFlys( FALSE );
+        pCnt->Calc();
+        pCnt->GetUpper()->Calc();
+        if ( pCnt->Frm().Top() > nBottom )
+            break;
+        pCnt = pCnt->GetNextCntntFrm();
+    }
+    return bRet;
+}
+
+BOOL MA_FASTCALL lcl_InnerCalcLayout( SwFrm *pFrm, long nBottom )
+{
+    BOOL bRet = FALSE;
+    do
+    {
+        if( pFrm->IsLayoutFrm() )
+        {
+            bRet |= !pFrm->IsValid();
+            pFrm->Calc();
+            if( ((SwLayoutFrm*)pFrm)->Lower() )
+                bRet |= lcl_InnerCalcLayout( ((SwLayoutFrm*)pFrm)->Lower(), nBottom);
+        }
+        pFrm = pFrm->GetNext();
+    } while ( pFrm && pFrm->Frm().Top() < nBottom );
+    return bRet;
+}
+
+void MA_FASTCALL lcl_CalcLayout( SwLayoutFrm *pLay, long nBottom )
+{
+    BOOL bCheck = TRUE;
+    do
+    {
+        while( lcl_InnerCalcLayout( pLay, nBottom ) )
+            bCheck = TRUE;
+        if( bCheck )
+        {
+            bCheck = FALSE;
+            if( lcl_CalcLowers( pLay, nBottom ) )
+                continue;
+        }
+        break;
+    } while( TRUE );
+}
+
+void MA_FASTCALL lcl_FirstTabCalc( SwTabFrm *pTab )
+{
+    //Ersteinmal koennen wir die Strukturen auf die richtige Groesse
+    //bringen.
+    if ( !pTab->IsFollow() && !pTab->GetTable()->IsTblComplex() )
+    {
+        SwLayoutFrm *pRow = (SwLayoutFrm*)pTab->Lower();
+        do
+        {
+            SwLayoutFrm *pCell = (SwLayoutFrm*)pRow->Lower();
+            SwFrm *pCnt = pCell->Lower();
+            pCnt->Calc();
+            const long nCellHeight = pCell->Frm().Height();
+            const long nCellY      = pCell->Frm().Top()-1;
+            const long nCntHeight  = pCnt->Frm().Height();
+            const long nCntY       = pCnt->Frm().Top()-1;
+            if ( 0 != (pCell = (SwLayoutFrm*)pCell->GetNext()) )
+                do
+                {   pCell->Frm().SSize().Height() =
+                    pCell->Prt().SSize().Height() = nCellHeight;
+                    pCell->Frm().Pos().Y() = nCellY;
+                    pCell->_InvalidateAll();
+
+                    pCnt = pCell->Lower();
+                    pCnt->Frm().SSize().Height() =
+                    pCnt->Prt().SSize().Height() = nCntHeight;
+                    pCnt->Frm().Pos().Y() = nCntY;
+                    pCnt->_InvalidateAll();
+
+                    pCell = (SwLayoutFrm*)pCell->GetNext();
+                } while ( pCell );
+
+            pRow = (SwLayoutFrm*)pRow->GetNext();
+
+        } while ( pRow );
+    }
+    //MA 28. Nov. 95: einen weiteren habe ich noch: Es braucht
+    //nur soweit formatiert werden, wie Platz vorhanden ist.
+    SwFrm *pUp = pTab->GetUpper();
+    long nBottom = pUp->Prt().Bottom() + pUp->Frm().Top();
+    if ( pTab->GetFmt()->GetDoc()->IsBrowseMode() )
+        nBottom += pUp->Grow( LONG_MAX, pHeight, TRUE );
+    lcl_CalcLowers( (SwLayoutFrm*)pTab->Lower(), nBottom );
+}
+
+void MA_FASTCALL lcl_Recalc( SwTabFrm *pTab,
+                             SwLayoutFrm *pFirstRow,
+                             SwLayNotify &rNotify )
+{
+    if ( pTab->Lower() )
+    {
+        const SwTwips nOldHeight = pTab->Frm().Height();
+        const SwTwips nOldWidth  = pTab->Frm().Width();
+        if ( !pFirstRow )
+        {
+            pFirstRow = (SwLayoutFrm*)pTab->Lower();
+            rNotify.SetLowersComplete( TRUE );
+        }
+        ::SwInvalidatePositions( pFirstRow, LONG_MAX );
+        ::lcl_CalcLayout( pFirstRow, LONG_MAX );
+        if ( nOldHeight < pTab->Frm().Height() )
+            rNotify.AddHeightOfst( pTab->Frm().Height() - nOldHeight );
+        else if ( nOldHeight > pTab->Frm().Height() )
+            rNotify.SubtractHeightOfst( nOldHeight - pTab->Frm().Height() );
+        if ( nOldWidth < pTab->Frm().Width() )
+            rNotify.AddWidthOfst( pTab->Frm().Width() - nOldWidth );
+        else if ( nOldWidth > pTab->Frm().Width() )
+            rNotify.SubtractWidthOfst( nOldWidth - pTab->Frm().Width() );
+    }
+}
+
+#define KEEPTAB ( !GetFollow() && !IsFollow() )
+
+void SwTabFrm::MakeAll()
+{
+    if ( IsJoinLocked() || StackHack::IsLocked() || StackHack::Count() > 50 )
+        return;
+
+    LockJoin(); //Ich lass mich nicht unterwegs vernichten.
+    SwLayNotify aNotify( this );    //uebernimmt im DTor die Benachrichtigung
+
+    //Wenn mein direkter Nachbar gleichzeitig mein Follow ist
+    //verleibe ich mir das Teil ein.
+    if ( GetNext() && GetNext() == GetFollow() )
+        aNotify.AddHeightOfst( Join() );
+
+    if ( bResizeHTMLTable ) //Optimiertes Zusammenspiel mit Grow/Shrink des Inhaltes
+    {
+        bResizeHTMLTable = FALSE;
+        SwHTMLTableLayout *pLayout = GetTable()->GetHTMLTableLayout();
+        if ( pLayout )
+            bCalcLowers = pLayout->Resize(
+                            pLayout->GetBrowseWidthByTabFrm( *this ), FALSE );
+    }
+
+
+    BOOL bMakePage  = TRUE;     //solange TRUE kann eine neue Seite
+                                //angelegt werden (genau einmal)
+    BOOL bMovedBwd  = FALSE;    //Wird TRUE wenn der Frame zurueckfliesst
+    BOOL bMovedFwd  = FALSE;    //solange FALSE kann der Frm zurueck-
+                                //fliessen (solange, bis er einmal
+                                //vorwaerts ge'moved wurde).
+    BOOL bSplit     = FALSE;    //Wird TRUE wenn der Frm gesplittet wurde.
+    BOOL bFtnsInDoc = GetFmt()->GetDoc()->GetFtnIdxs().Count();
+    BOOL bMoveable;
+    const BOOL bRepeat  = GetTable()->IsHeadlineRepeat();
+    const BOOL bFly     = IsInFly();
+
+    SwBorderAttrAccess  *pAccess= new SwBorderAttrAccess( SwFrm::GetCache(), this );
+    const SwBorderAttrs *pAttrs = pAccess->Get();
+
+    const BOOL bKeep = IsKeep( *pAttrs );
+    const BOOL bDontSplit = !IsFollow() && !GetFmt()->GetLayoutSplit().GetValue();
+
+    if ( bDontSplit )
+        while ( GetFollow() )
+            aNotify.AddHeightOfst( Join() );
+
+    //Einen Frischling moven wir gleich schon einmal vorwaerts...
+    if ( !Frm().Top() && IsFollow() )
+    {
+        SwFrm *pPre = GetPrev();
+        if ( pPre && pPre->IsTabFrm() && ((SwTabFrm*)pPre)->GetFollow() == this)
+        {
+            if ( !MoveFwd( bMakePage, FALSE ) )
+                bMakePage = FALSE;
+            bMovedFwd = TRUE;
+        }
+    }
+
+    while ( !bValidPos || !bValidSize || !bValidPrtArea )
+    {
+        if ( TRUE == (bMoveable = IsMoveable()) )
+            if ( CheckMoveFwd( bMakePage, bKeep && KEEPTAB, bMovedBwd ) )
+            {
+                bMovedFwd = TRUE;
+                bCalcLowers = TRUE;
+            }
+
+        Point aOldPos( Frm().Pos() );
+        MakePos();
+        if ( aOldPos != Frm().Pos() )
+        {
+            if ( aOldPos.Y() != Frm().Top() )
+            {
+                SwHTMLTableLayout *pLayout = GetTable()->GetHTMLTableLayout();
+                if( pLayout )
+                {
+                    delete pAccess;
+                    bCalcLowers |= pLayout->Resize(
+                        pLayout->GetBrowseWidthByTabFrm( *this ), FALSE );
+                    pAccess= new SwBorderAttrAccess( SwFrm::GetCache(), this );
+                    pAttrs = pAccess->Get();
+                }
+
+                bValidPrtArea = FALSE;
+                aNotify.SetLowersComplete( FALSE );
+            }
+            SwFrm *pPre;
+            if ( bKeep || (0 != (pPre = FindPrev()) &&
+                           pPre->GetAttrSet()->GetKeep().GetValue()) )
+            {
+                bCalcLowers = TRUE;
+            }
+        }
+
+        //Wir muessen die Hoehe der ersten Zeile kennen, denn nur wenn diese
+        //kleiner wird muss ggf. der Master angestossen werden um noetigenfalls
+        //die Zeile aufzunehmen.
+        long n1StLineHeight = 0;
+        if ( IsFollow() )
+        {
+            SwFrm *pFrm = Lower();
+            if ( bRepeat && pFrm )
+                pFrm = pFrm->GetNext();
+            if ( pFrm )
+                n1StLineHeight = pFrm->Frm().Height();
+        }
+
+        if ( !bValidSize || !bValidPrtArea )
+        {
+            const BOOL bOptLower = Frm().Height() == 0;
+
+            const long nOldPrtWidth = Prt().Width();
+            const long nOldFrmWidth = Frm().Width();
+            const Point aOldPrtPos  = Prt().Pos();
+            Format( pAttrs );
+
+            SwHTMLTableLayout *pLayout = GetTable()->GetHTMLTableLayout();
+            if ( /*!bOptLower &&*/ pLayout &&
+                 (Prt().Width() != nOldPrtWidth ||
+                  Frm().Width() != nOldFrmWidth) )
+            {
+                delete pAccess;
+                bCalcLowers |= pLayout->Resize(
+                        pLayout->GetBrowseWidthByTabFrm( *this ), FALSE );
+//                  GetFmt()->GetDoc()->GetDocShell()->IsReadOnly() ? FALSE : TRUE );
+                pAccess= new SwBorderAttrAccess( SwFrm::GetCache(), this );
+                pAttrs = pAccess->Get();
+            }
+            if ( !bOptLower && aOldPrtPos != Prt().Pos() )
+            {
+                aNotify.SetLowersComplete( FALSE );
+            }
+
+            if ( bOptLower )
+            {
+                //MA 24. May. 95: Optimierungsversuch!
+                //Ganz nigel nagel neu das Teil. Damit wir nicht n-fach
+                //MakeAll'en formatieren wir flugs den Inhalt.
+                //Das erste Format mussten wir allerdings abwarten, damit
+                //die Breiten Stimmen!
+                //MA: Fix, Kein Calc wenn evtl. noch Seitengebunde Flys
+                //an den Cntnt haengen (siehe frmtool.cxx, ~SwCntntNotify).
+                SwDoc *pDoc = GetFmt()->GetDoc();
+                if ( !pDoc->GetSpzFrmFmts()->Count() ||
+                     pDoc->IsLoaded() || pDoc->IsNewDoc() )
+                {
+                    //MA 28. Nov. 95: Und wieder ein Trick, gleich mal sehen
+                    //ob ein Rueckfluss lohnt.
+                    if ( bMoveable && !GetPrev() )
+                    {
+                        GetLeaf( MAKEPAGE_NONE, FALSE ); //setzt das BackMoveJump
+                        if ( SwFlowFrm::IsMoveBwdJump() )
+                        {
+                            BOOL bDummy;
+                            SwFtnBossFrm *pOldBoss = bFtnsInDoc ?
+                                FindFtnBossFrm( TRUE ) : 0;
+                            const FASTBOOL bOldPrev = GetPrev() != 0;
+                            if ( MoveBwd( bDummy ) )
+                            {
+                                bMovedBwd = TRUE;
+                                if ( bFtnsInDoc )
+                                    MoveLowerFtns( 0, pOldBoss, 0, TRUE );
+
+                                long nOldTop = Frm().Top();
+                                MakePos();
+                                if( nOldTop != Frm().Top() )
+                                {
+                                    SwHTMLTableLayout *pLayout =
+                                        GetTable()->GetHTMLTableLayout();
+                                    if( pLayout )
+                                    {
+                                        delete pAccess;
+                                        bCalcLowers |= pLayout->Resize(
+                                            pLayout->GetBrowseWidthByTabFrm(
+                                                            *this ), FALSE );
+                                        pAccess= new SwBorderAttrAccess(
+                                                    SwFrm::GetCache(), this );
+                                        pAttrs = pAccess->Get();
+                                    }
+                                }
+
+                                if ( bOldPrev != (0 != GetPrev()) )
+                                {
+                                    //Abstand nicht vergessen!
+                                    bValidPrtArea = FALSE;
+                                    Format( pAttrs );
+                                }
+                                if ( bKeep && KEEPTAB )
+                                {
+                                    SwFrm *pNxt = FindNextCnt();
+                                    // FindNextCnt geht ggf. in einen Bereich
+                                    // hinein, in eine Tabelle allerdings auch
+                                    if( pNxt && pNxt->IsInTab() )
+                                        pNxt = pNxt->FindTabFrm();
+                                    if ( pNxt )
+                                    {
+                                        pNxt->Calc();
+                                        if ( !GetNext() )
+                                            bValidPos = FALSE;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    ::lcl_FirstTabCalc( this );
+                    bValidSize = bValidPrtArea = FALSE;
+                    Format( pAttrs );
+                    aNotify.SetLowersComplete( TRUE );
+                }
+            }
+        }
+
+        //Wenn ich der erste einer Kette bin koennte ich mal sehen ob
+        //ich zurueckfliessen kann (wenn ich mich ueberhaupt bewegen soll).
+        //Damit es keine Oszillation gibt, darf ich nicht gerade vorwaerts
+        //geflosssen sein.
+        if ( !GetIndPrev() && !bMovedFwd && (bMoveable || bFly) )
+        {
+            //Bei Follows muss der Master benachrichtigt
+            //werden. Der Follow muss nur dann Moven, wenn er leere Blaetter
+            //ueberspringen muss.
+            if ( IsFollow() )
+            {
+                //Nur wenn die Hoehe der ersten Zeile kleiner geworder ist.
+                SwFrm *pFrm = Lower();
+                if ( bRepeat && pFrm )
+                    pFrm = pFrm->GetNext();
+                if ( pFrm && n1StLineHeight > pFrm->Frm().Height() )
+                {
+                    SwTabFrm *pMaster = (SwTabFrm*)FindMaster();
+                    BOOL bDummy;
+                    if ( ShouldBwdMoved( pMaster->GetUpper(), FALSE, bDummy ) )
+                        pMaster->InvalidatePos();
+                }
+            }
+            SwFtnBossFrm *pOldBoss = bFtnsInDoc ? FindFtnBossFrm( TRUE ) : 0;
+            BOOL bReformat;
+            if ( MoveBwd( bReformat ) )
+            {
+                bMovedBwd = TRUE;
+                aNotify.SetLowersComplete( FALSE );
+                if ( bFtnsInDoc )
+                    MoveLowerFtns( 0, pOldBoss, 0, TRUE );
+                if ( bReformat || bKeep )
+                {
+                    long nOldTop = Frm().Top();
+                    MakePos();
+                    if ( nOldTop != Frm().Top() )
+                    {
+                        SwHTMLTableLayout *pLayout =
+                            GetTable()->GetHTMLTableLayout();
+                        if( pLayout )
+                        {
+                            delete pAccess;
+                            bCalcLowers |= pLayout->Resize(
+                                pLayout->GetBrowseWidthByTabFrm( *this ),
+                                FALSE );
+                            pAccess= new SwBorderAttrAccess(
+                                        SwFrm::GetCache(), this );
+                            pAttrs = pAccess->Get();
+                        }
+
+                        bValidPrtArea = FALSE;
+                        Format( pAttrs );
+                    }
+                    ::lcl_Recalc( this, 0, aNotify );
+                    bLowersFormatted = TRUE;
+                    if ( bKeep && KEEPTAB )
+                    {
+                        SwFrm *pNxt = FindNextCnt();
+                        if( pNxt && pNxt->IsInTab() )
+                            pNxt = pNxt->FindTabFrm();
+                        if ( pNxt )
+                        {
+                            pNxt->Calc();
+                            if ( !GetNext() )
+                                bValidPos = FALSE;
+                        }
+                    }
+                }
+            }
+        }
+
+        //Wieder ein Wert ungueltig? - dann nochmal das ganze...
+        if ( !bValidPos || !bValidSize || !bValidPrtArea )
+            continue;
+
+        //Fertig?
+        if ( GetUpper()->Prt().Bottom()+GetUpper()->Frm().Top() >=
+             Frm().Bottom() )
+        {
+            //Wenn ich zur Unterkante des Upper noch Raum habe, so kann ich
+            //wenigstens probehalber eine weitere Zeile meines Follows
+            //aufnehmen.
+            if ( !bSplit && GetFollow() )
+            {
+                BOOL bDummy;
+                if ( GetFollow()->ShouldBwdMoved( GetUpper(), FALSE, bDummy ) )
+                {
+                    SwFrm *pTmp = GetUpper();
+                    SwTwips nDeadLine = pTmp->Prt().Bottom() + pTmp->Frm().Top();
+                    if ( GetFmt()->GetDoc()->IsBrowseMode() )
+                        nDeadLine += pTmp->Grow( LONG_MAX, pHeight, TRUE );
+                    if ( Frm().Bottom() < nDeadLine )
+                    {
+                        SwFrm *pRow = GetFollow()->Lower();
+                        if ( bRepeat )
+                            pRow = pRow->GetNext();
+                        const SwTwips nOld = Frm().Height();
+
+                        const BOOL bMoveFtns = bFtnsInDoc && pRow &&
+                                               !GetFollow()->IsJoinLocked();
+
+                        SwFtnBossFrm *pOldBoss;
+                        if ( bMoveFtns )
+                            pOldBoss = pRow->FindFtnBossFrm( TRUE );
+
+                        //fix(8680): Row kann 0 werden.
+                        if ( !pRow || !pRow->GetNext() )
+                            //Der Follow wird leer und damit ueberfluessig.
+                            aNotify.AddHeightOfst( Join() );
+                        else
+                        {
+                            pRow->Cut();
+                            pRow->Paste( this );
+                            aNotify.AddHeightOfst( pRow->Frm().Height() );
+                        }
+                        //Die Fussnoten verschieben!
+                        if ( pRow && bMoveFtns )
+                            if ( ((SwLayoutFrm*)pRow)->MoveLowerFtns(
+                                 0, pOldBoss, FindFtnBossFrm( TRUE ), TRUE ) )
+                                GetUpper()->Calc();
+
+                        if ( pRow && nOld != Frm().Height() )
+                            ::lcl_Recalc( this, (SwLayoutFrm*)pRow, aNotify );
+                        continue;
+                    }
+                }
+            }
+            else if ( bKeep && KEEPTAB )
+            {
+                SwFrm *pNxt = FindNextCnt();
+                if( pNxt && pNxt->IsInTab() )
+                    pNxt = pNxt->FindTabFrm();
+                if ( pNxt )
+                    pNxt->Calc();
+            }
+            if ( IsValid() )
+            {
+                if ( bCalcLowers )
+                {
+                    ::lcl_Recalc( this, 0, aNotify );
+                    bLowersFormatted = TRUE;
+                    bCalcLowers = FALSE;
+                }
+                else if ( bONECalcLowers )
+                {
+                    lcl_CalcLayout( (SwLayoutFrm*)Lower(), LONG_MAX );
+                    bONECalcLowers = FALSE;
+                }
+            }
+            continue;
+        }
+
+        //Ich passe nicht mehr in meinen Uebergeordneten, also ist es jetzt
+        //an der Zeit moeglichst konstruktive Veranderungen vorzunehmen
+
+        //Wenn ich den uebergeordneten Frm nicht verlassen darf, habe
+        //ich ein Problem; Frei nach Artur Dent tun wir das einzige das man
+        //mit einen nicht loesbaren Problem tun kann: wir ignorieren es - und
+        //zwar mit aller Kraft.
+        if ( !bMoveable )
+        {
+            if ( bCalcLowers && IsValid() )
+            {
+                lcl_Recalc( this, 0, aNotify );
+                bLowersFormatted = TRUE;
+                bCalcLowers = FALSE;
+            }
+            else if ( bONECalcLowers )
+            {
+                lcl_CalcLayout( (SwLayoutFrm*)Lower(), LONG_MAX );
+                bONECalcLowers = FALSE;
+            }
+            continue;
+        }
+
+        //Der erste Versuch muss natuerlich das Aufspalten der Tabelle sein.
+        //Das funktioniert natuerlich nur dann, wenn die Tabelle mehr als eine
+        //Zeile enthaelt und wenn die Unterkante des Upper unter der ersten
+        //Zeile liegt.
+        SwFrm *pIndPrev = GetIndPrev();
+        if ( Lower()->GetNext() && (!bDontSplit || !pIndPrev) )
+        {
+            //Damit der Schatten nicht extra herausgerechnet werden muss,
+            //lassen wir das Spiel gleich wenn es ein HeadlineRepeat gibt und
+            //nur noch eine nicht Headline Zeile vorhanden ist.
+            if ( !bRepeat || Lower()->GetNext()->GetNext() )
+            {
+                SwTwips nDeadLine = GetUpper()->Prt().Bottom() +
+                                    GetUpper()->Frm().Top();
+                if( IsInSct() )
+                    nDeadLine += GetUpper()->Grow( LONG_MAX, pHeight, TRUE );
+
+                //Zunaechst einmal sollten wir fuer Stabilitaet sorgen,
+                //denn andernfalls koennen wir nicht hinreichend zuverlaessig
+                //splitten.
+                ::lcl_CalcLayout( (SwLayoutFrm*)Lower(), nDeadLine );
+                bLowersFormatted = TRUE;
+                aNotify.SetLowersComplete( TRUE );
+                if( Frm().Bottom() < nDeadLine )
+                    continue;
+
+                //Position unter der ersten Zeile ermitteln. Wenn Headlines im
+                //Spiel sind, ist es die Pos unter der ersten nicht-Headline
+                //Zeile.
+                SwTwips nBreakLine = Lower()->Frm().Height();
+                if ( bRepeat )
+                    nBreakLine += Lower()->GetNext()->Frm().Height();
+                nBreakLine += Frm().Top() + Prt().Top();
+                if ( nBreakLine <= nDeadLine || !pIndPrev )
+                {
+                    aNotify.SubtractHeightOfst( Split( nDeadLine ) );
+                    if ( aNotify.GetHeightOfst() < 0 )
+                        aNotify.ResetHeightOfst();
+                    aNotify.SetLowersComplete( FALSE );
+                    bSplit = TRUE;
+                    //Damit es nicht zu Oszillationen kommt, muss der
+                    //Follow gleich gueltig gemacht werden.
+                    if ( GetFollow() )
+                    {
+                        if ( !StackHack::IsLocked() )
+                        {
+                            StackHack aHack;
+                            GetFollow()->MakeAll();
+                            ((SwTabFrm*)GetFollow())->SetLowersFormatted(FALSE);
+                            ::lcl_CalcLayout((SwLayoutFrm*)GetFollow()->Lower(),
+                                GetFollow()->GetUpper()->Frm().Bottom() );
+                            if ( !GetFollow()->GetFollow() )
+                            {
+                                SwFrm *pNxt = ((SwFrm*)GetFollow())->FindNext();
+                                if ( pNxt )
+                                    pNxt->Calc();
+                            }
+                        }
+                        else if ( GetFollow() == GetNext() )
+                            ((SwTabFrm*)GetFollow())->MoveFwd( TRUE, FALSE );
+                        ViewShell *pSh;
+                        if ( 0 != (pSh = GetShell()) )
+                            pSh->Imp()->ResetScroll();
+                    }
+                    continue;
+                }
+            }
+        }
+
+        if( IsInSct() && bMovedFwd && bMakePage && GetUpper()->IsColBodyFrm() &&
+            GetUpper()->GetUpper()->GetUpper()->IsSctFrm() &&
+            ( GetUpper()->GetUpper()->GetPrev() || GetIndPrev() ) &&
+            ((SwSectionFrm*)GetUpper()->GetUpper()->GetUpper())->MoveAllowed(this) )
+            bMovedFwd = FALSE;
+
+        //Mal sehen ob ich irgenwo Platz finde...
+        if ( !bMovedFwd && !MoveFwd( bMakePage, FALSE ) )
+            bMakePage = FALSE;
+        bMovedFwd = bCalcLowers = TRUE;
+        aNotify.SetLowersComplete( FALSE );
+        if ( IsFollow() )
+        {   //Um Oszillationen zu vermeiden sollte kein ungueltiger Master
+            //zurueckbleiben.
+            SwTabFrm *pTab = FindMaster();
+            if ( pTab->GetUpper() )
+                pTab->GetUpper()->Calc();
+            pTab->Calc();
+            pTab->SetLowersFormatted( FALSE );
+        }
+
+        //Wenn mein direkter Nachbar jetzt gleichzeitig mein Follow ist
+        //verleibe ich mir das Teil ein.
+        if ( GetNext() && GetNext() == GetFollow() )
+            aNotify.AddHeightOfst( Join() );
+
+        if ( bMovedBwd && GetUpper() )
+            //Beim zurueckfliessen wurde der Upper angeregt sich vollstaendig
+            //zu Painten, dass koennen wir uns jetzt nach dem hin und her
+            //fliessen sparen.
+            GetUpper()->ResetCompletePaint();
+
+        if ( bCalcLowers && IsValid() )
+        {
+            ::lcl_Recalc( this, 0, aNotify );
+            bLowersFormatted = TRUE;
+            bCalcLowers = FALSE;
+        }
+
+    } //while ( !bValidPos || !bValidSize || !bValidPrtArea )
+
+    //Wenn mein direkter Vorgaenger jetzt mein Master ist, so kann er mich
+    //bei der nachstbesten Gelegenheit vernichten.
+    if ( IsFollow() )
+    {
+        SwFrm *pPre = GetPrev();
+        if ( pPre && pPre->IsTabFrm() && ((SwTabFrm*)pPre)->GetFollow() == this)
+            pPre->InvalidatePos();
+    }
+
+    bCalcLowers = bONECalcLowers = FALSE;
+    delete pAccess;
+    UnlockJoin();
+    if ( bMovedFwd || bMovedBwd )
+        aNotify.SetInvaKeep();
+}
+
+/*************************************************************************
+|*
+|*  SwTabFrm::CalcFlyOffsets()
+|*
+|*  Beschreibung:       Berechnet die Offsets, die durch FlyFrames
+|*                      entstehen.
+|*  Ersterstellung      MA/MIB 14. Apr. 99
+|*  Letzte Aenderung
+|*
+|*************************************************************************/
+BOOL SwTabFrm::CalcFlyOffsets( SwTwips& rUpper,
+                               long& rLeftOffset,
+                               long& rRightOffset ) const
+{
+    BOOL bInvalidatePrtArea = FALSE;
+    const SwPageFrm *pPage = FindPageFrm();
+    const SwFlyFrm* pMyFly = FindFlyFrm();
+    if ( pPage->GetSortedObjs() )
+    {
+        long nPrtPos = Frm().Top() + rUpper;
+        SwRect aRect( Frm() );
+        if ( Prt().Top() - rUpper > 0 )
+            aRect.SSize().Height() -= Prt().Top() - rUpper;
+        for ( USHORT i = 0; i < pPage->GetSortedObjs()->Count(); ++i )
+        {
+            SdrObject *pObj = (*pPage->GetSortedObjs())[i];
+            if ( pObj->IsWriterFlyFrame() )
+            {
+                SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+                const SwRect aFlyRect = pFly->AddSpacesToFrm();
+                if ( WEIT_WECH != pFly->Frm().Top() &&
+                     pFly->IsFlyAtCntFrm() && aFlyRect.IsOver( aRect ) &&
+                     pFly->GetAnchor()->Frm().Bottom() < Frm().Top() &&
+                     !IsAnLower( pFly ) && !pFly->IsAnLower( this ) &&
+                     ( !pMyFly || pMyFly->IsAnLower( pFly ) ) &&
+                     pPage->GetPhyPageNum() >=
+                     pFly->GetAnchor()->FindPageFrm()->GetPhyPageNum() )
+                {
+                    const SwFmtSurround   &rSur = pFly->GetFmt()->GetSurround();
+                    const SwFmtHoriOrient &rHori= pFly->GetFmt()->GetHoriOrient();
+                    if ( SURROUND_NONE == rSur.GetSurround() )
+                    {
+                        nPrtPos = Max( nPrtPos, aFlyRect.Bottom() + 1l );
+                        bInvalidatePrtArea = TRUE;
+                    }
+                    if ( (SURROUND_RIGHT    == rSur.GetSurround() ||
+                          SURROUND_PARALLEL == rSur.GetSurround())&&
+                         HORI_LEFT == rHori.GetHoriOrient() )
+                    {
+                        //Der Rahmen kann auch noch einem anderen Rahmen
+                        //ausgewichen sein.
+                        const long nWidth = aFlyRect.Width() +
+                                    aFlyRect.Left() - pFly->GetAnchor()->Frm().Left();
+                        rLeftOffset = Max( rLeftOffset, nWidth );
+                        bInvalidatePrtArea = TRUE;
+                    }
+                    if ( (SURROUND_LEFT     == rSur.GetSurround() ||
+                          SURROUND_PARALLEL == rSur.GetSurround())&&
+                         HORI_RIGHT == rHori.GetHoriOrient() )
+                    {
+                        const long nWidth = aFlyRect.Width() +
+                                    pFly->GetAnchor()->Frm().Right() - aFlyRect.Right();
+                        rRightOffset = Max( rRightOffset, nWidth );
+                        bInvalidatePrtArea = TRUE;
+                    }
+                }
+            }
+        }
+        rUpper = nPrtPos - Frm().Top();
+    }
+
+    return bInvalidatePrtArea;
+}
+
+/*************************************************************************
+|*
+|*  SwTabFrm::Format()
+|*
+|*  Beschreibung:       "Formatiert" den Frame; Frm und PrtArea
+|*                      Die Fixsize wird hier nicht eingestellt.
+|*  Ersterstellung      MA 09. Mar. 93
+|*  Letzte Aenderung    MA 18. Jun. 97
+|*
+|*************************************************************************/
+void SwTabFrm::Format( const SwBorderAttrs *pAttrs )
+{
+    ASSERT( pAttrs, "TabFrm::Format, pAttrs ist 0." );
+
+    //FixSize einstellen
+    if ( !bValidSize )
+        aFrm.Width( GetUpper()->Prt().Width() );
+
+    //VarSize ist immer die Hoehe.
+    //Fuer den oberen/unteren Rand gelten die selben Regeln wie fuer
+    //cntfrms (sie MakePrtArea() von diesen).
+
+    SwTwips nUpper = CalcUpperSpace( pAttrs );
+
+    //Wir wollen Rahmen ausweichen. Zwei Moeglichkeiten:
+    //1. Es gibt Rahmen mit SurroundNone, diesen wird vollsaendig ausgewichen
+    //2. Es gibt Rahmen mit Umlauf nur rechts bzw. nur links und diese sind
+    //   rechts bzw. links ausgerichtet, diese geben ein Minimum fuer die
+    //   Raender vor.
+    long nRightOffset = 0,
+         nLeftOffset  = 0;
+    if( CalcFlyOffsets( nUpper, nLeftOffset, nRightOffset ) )
+        bValidPrtArea = FALSE;
+
+    SwTwips nLower = pAttrs->CalcBottomLine();
+
+    if ( !bValidPrtArea )
+    {   bValidPrtArea = TRUE;
+
+        const SwTwips nOldHeight = Prt().Height();
+
+        //Die Breite der PrtArea wird vom FrmFmt vorgegeben, die Raender
+        //sind entsprechend einzustellen.
+        //Mindestraender werden von Umrandung und Schatten vorgegeben.
+        //Die Rander werden so eingestellt, dass die PrtArea nach dem
+        //angegebenen Adjustment im Frm ausgerichtet wird.
+        //Wenn das Adjustment 0 ist, so werden die Rander anhand des
+        //Randattributes eingestellt.
+
+        const SwTwips nMax = aFrm.Width();
+        SwTwips nLeft  = pAttrs->CalcLeftLine();
+        SwTwips nRight = pAttrs->CalcRightLine();
+
+        //Die Breite ist evtl. eine Prozentangabe. Wenn die Tabelle irgendwo
+        //'drinsteckt bezieht sie sich auf die Umgebung. Ist es der Body, so
+        //bezieht sie sich in der BrowseView auf die Bildschirmbreite.
+        const SwFmtFrmSize &rSz = GetFmt()->GetFrmSize();
+        const SwTwips nWish = CalcRel( rSz, TRUE );
+
+        BOOL bCheckBrowseWidth = FALSE;
+
+        switch ( GetFmt()->GetHoriOrient().GetHoriOrient() )
+        {
+            case HORI_LEFT:
+                {
+                    const SwTwips nTmp = nMax-nLeftOffset-nRightOffset -
+                                         (nWish + nLeft);
+                    nLeft  += nLeftOffset;
+                    nRight += nRightOffset;
+                    nRight -= nLeftOffset;
+                    if ( nTmp > nRight )
+                        nRight = nTmp;
+                    nRight = Max( nRight, 0L );
+                }
+                break;
+            case HORI_RIGHT:
+                {
+                    const SwTwips nTmp = nMax-nLeftOffset-nRightOffset -
+                                         (nWish + nRight);
+                    nRight += nRightOffset;
+                    nLeft  += nLeftOffset;
+                    nLeft  -= nRightOffset;
+                    if ( nTmp > nLeft )
+                        nLeft = nTmp;
+                    nLeft = Max( nLeft, 0L );
+                }
+                break;
+            case HORI_CENTER:
+                {
+                    const SwTwips nTmp = (nMax-nLeftOffset-nRightOffset - nWish) / 2;
+                    nLeft += nLeftOffset;
+                    nRight+= nRightOffset;
+                    if ( nTmp > nLeft )
+                        nLeft = nTmp;
+                    if ( nTmp > nRight )
+                        nRight = nTmp;
+                    nRight= Max( nRight, 0L );
+                    nLeft = Max( nLeft, 0L );
+                }
+                break;
+            case HORI_FULL:
+                    //Das Teil dehnt sich ueber die gesamte Breite aus.
+                    //Nur die fuer die Umrandung benoetigten Freiraeume
+                    //werden beruecksichtigt.
+                    //Die Attributwerte von LRSpace werden bewusst missachtet!
+                    bCheckBrowseWidth = TRUE;
+                    nLeft  += nLeftOffset;
+                    nRight += nRightOffset;
+                break;
+            case HORI_NONE:
+                {
+                    //Die Raender werden vom Randattribut bestimmt.
+                    nLeft = pAttrs->CalcLeft( this );
+                    if( nLeftOffset )
+                    {
+                        if( nLeft < 0 )
+                            nLeft = 0;
+                        nLeft += nLeftOffset;
+                    }
+                    nRight = pAttrs->CalcRight();
+                    if( nRightOffset )
+                    {
+                        if( nRight < 0 )
+                            nRight = 0;
+                        nRight += nRightOffset;
+                    }
+                    if ( !pAttrs->GetLRSpace().GetRight() )
+                        nRight = Max( nRight, nMax - (nWish + nLeft + nRight));
+                }
+                break;
+            case HORI_LEFT_AND_WIDTH:
+                    //Linker Rand und die Breite zaehlen (Word-Spezialitaet)
+                    bCheckBrowseWidth = TRUE;
+                    nLeft = pAttrs->CalcLeft( this );
+                    if( nLeftOffset )
+                    {
+                        if( nLeft < 0 )
+                            nLeft = 0;
+                        nLeft += nLeftOffset;
+                    }
+                    nRight = Max( nMax - nLeft - nWish, nRightOffset );
+                break;
+            default:
+                ASSERT( FALSE, "Ungueltige orientation fuer Table." );
+        }
+        Prt().Top( nUpper );
+        Prt().Height( aFrm.Height() - (nUpper + nLower) );
+        if ( (nMax - MINLAY) < (nLeft + nRight) )
+        {   //Wenn die Raender garnicht passen lasse ich sie lieber gleich weg.
+            Prt().Left( 0 );
+            Prt().Width( nMax );
+        }
+        else
+        {
+            Prt().Left( nLeft );
+            Prt().Width( nMax - (nLeft + nRight) );
+        }
+
+        ViewShell *pSh;
+        if ( bCheckBrowseWidth && GetFmt()->GetDoc()->IsBrowseMode() &&
+             GetUpper()->IsPageBodyFrm() &&  // nur PageBodyFrms, nicht etwa ColBodyFrms
+             0 != (pSh = GetShell()) && pSh->VisArea().Width() )
+        {
+            //Nicht ueber die Kante des sichbaren Bereiches hinausragen.
+            //Die Seite kann breiter sein, weil es Objekte mit "ueberbreite"
+            //geben kann (RootFrm::ImplCalcBrowseWidth())
+            const Size aBorder = pSh->GetOut()->PixelToLogic( pSh->GetBrowseBorder() );
+            long nWidth = pSh->VisArea().Width() - 2 * aBorder.Width();
+            nWidth -= Prt().Left();
+            nWidth -= pAttrs->CalcRightLine();
+            Prt().Width( Min( nWidth, Prt().Width() ) );
+        }
+
+        if ( nOldHeight != Prt().Height() )
+            bValidSize = FALSE;
+    }
+
+    if ( !bValidSize )
+    {
+        bValidSize = TRUE;
+
+        //Die Groesse wird durch den Inhalt plus den Raendern bestimmt.
+        SwTwips nRemaining = 0, nDiff;
+        SwFrm *pFrm = pLower;
+        while ( pFrm )
+        {   nRemaining += pFrm->Frm().Height();
+            pFrm = pFrm->GetNext();
+        }
+        //Jetzt noch die Raender addieren
+        nRemaining += nUpper + nLower;
+
+        nDiff = Frm().Height() - nRemaining;
+        if ( nDiff > 0 )
+            Shrink( nDiff, pHeight );
+        else if ( nDiff < 0 )
+            Grow( -nDiff, pHeight );
+    }
+}
+/*************************************************************************
+|*
+|*  SwTabFrm::GrowFrm()
+|*
+|*  Ersterstellung      MA 12. Mar. 93
+|*  Letzte Aenderung    MA 23. Sep. 96
+|*
+|*************************************************************************/
+SwTwips SwTabFrm::GrowFrm( SwTwips nDist, const SzPtr pDirection,
+                           BOOL bTst, BOOL bInfo )
+{
+    //Tabellen sind immer in der Breite fix
+    if( pDirection == pWidth )
+        return 0;
+
+    if ( Frm().SSize().Height() > 0 && nDist > (LONG_MAX - Frm().Height()) )
+        nDist = LONG_MAX - Frm().Height();
+
+    //Tabelle waechst immer (sie kann ja ggf. aufgespalten werden).
+    if ( !bTst )
+    {
+        if ( GetUpper() )
+        {
+            //Der Upper wird nur soweit wie notwendig gegrowed. In nReal wird erstmal
+            //die bereits zur Verfuegung stehende Strecke bereitgestellt.
+            SwTwips nReal = GetUpper()->Prt().SSize().*pDirection;
+            SwFrm *pFrm = GetUpper()->Lower();
+            while ( pFrm )
+            {   nReal -= pFrm->Frm().Height();
+                pFrm = pFrm->GetNext();
+            }
+
+            Frm().SSize().Height() += nDist;
+
+            if ( nReal < nDist )
+                GetUpper()->Grow( nDist - (nReal > 0 ? nReal : 0),
+                                                pDirection, bTst, bInfo );
+        }
+        else
+        {
+            ASSERT( !this, "Table without Upper" );
+            Frm().SSize().Height() += nDist;
+        }
+
+        SwPageFrm *pPage = FindPageFrm();
+        if ( GetNext() )
+        {
+            GetNext()->_InvalidatePos();
+            if ( GetNext()->IsCntntFrm() )
+                GetNext()->InvalidatePage( pPage );
+        }
+        _InvalidateAll();
+        InvalidatePage( pPage );
+        SetComplete();
+
+        const SvxGraphicPosition ePos = GetFmt()->GetBackground().GetGraphicPos();
+        if ( GPOS_NONE != ePos && GPOS_TILED != ePos )
+            SetCompletePaint();
+    }
+    return nDist;
+}
+/*************************************************************************
+|*
+|*    SwTabFrm::Modify()
+|*
+|*    Ersterstellung    MA 14. Mar. 93
+|*    Letzte Aenderung  MA 06. Dec. 96
+|*
+|*************************************************************************/
+void SwTabFrm::Modify( SfxPoolItem * pOld, SfxPoolItem * pNew )
+{
+    BYTE nInvFlags = 0;
+    BOOL bAttrSetChg = pNew && RES_ATTRSET_CHG == pNew->Which();
+
+    if( bAttrSetChg )
+    {
+        SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() );
+        SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() );
+        SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld );
+        SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew );
+        while( TRUE )
+        {
+            _UpdateAttr( (SfxPoolItem*)aOIter.GetCurItem(),
+                         (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags,
+                         &aOldSet, &aNewSet );
+            if( aNIter.IsAtEnd() )
+                break;
+            aNIter.NextItem();
+            aOIter.NextItem();
+        }
+        if ( aOldSet.Count() || aNewSet.Count() )
+            SwLayoutFrm::Modify( &aOldSet, &aNewSet );
+    }
+    else
+        _UpdateAttr( pOld, pNew, nInvFlags );
+
+    if ( nInvFlags != 0 )
+    {
+        SwPageFrm *pPage = FindPageFrm();
+        InvalidatePage( pPage );
+//      if ( nInvFlags & 0x01 )
+//          SetCompletePaint();
+        if ( nInvFlags & 0x02 )
+            _InvalidatePrt();
+        if ( nInvFlags & 0x40 )
+            _InvalidatePos();
+        SwFrm *pTmp;
+        if ( 0 != (pTmp = GetIndNext()) )
+        {
+            if ( nInvFlags & 0x04 )
+            {
+                pTmp->_InvalidatePrt();
+                if ( pTmp->IsCntntFrm() )
+                    pTmp->InvalidatePage( pPage );
+            }
+            if ( nInvFlags & 0x10 )
+                pTmp->SetCompletePaint();
+        }
+        if ( nInvFlags & 0x08 && 0 != (pTmp = GetPrev()) )
+        {
+            pTmp->_InvalidatePrt();
+            if ( pTmp->IsCntntFrm() )
+                pTmp->InvalidatePage( pPage );
+        }
+        if ( nInvFlags & 0x20  )
+        {
+            if ( pPage && pPage->GetUpper() && !IsFollow() )
+                ((SwRootFrm*)pPage->GetUpper())->InvalidateBrowseWidth();
+        }
+        if ( nInvFlags & 0x80 )
+            InvalidateNextPos();
+    }
+}
+
+void SwTabFrm::_UpdateAttr( SfxPoolItem *pOld, SfxPoolItem *pNew,
+                            BYTE &rInvFlags,
+                            SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet )
+{
+    BOOL bClear = TRUE;
+    const USHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
+    switch( nWhich )
+    {
+        case RES_TBLHEADLINECHG:
+            //Es wird getoggelt.
+            if ( IsFollow() )
+            {
+                if ( GetTable()->IsHeadlineRepeat() )
+                {
+                    bDontCreateObjects = TRUE;          //frmtool
+                    SwFrm *pRow = new SwRowFrm( *GetTable()->GetTabLines()[0] );
+                    bDontCreateObjects = FALSE;
+                    pRow->Paste( this, Lower() );
+                }
+                else if ( Lower() )
+                {
+                    SwFrm *pLow = Lower();
+                    pLow->Cut();
+                    delete pLow;
+                }
+            }
+            else if ( !HasFollow() )
+                rInvFlags |= 0x02;
+            break;
+
+        case RES_FRM_SIZE:
+        case RES_HORI_ORIENT:
+            rInvFlags |= 0x22;
+            break;
+
+        case RES_PAGEDESC:                      //Attributaenderung (an/aus)
+            if ( IsInDocBody() )
+            {
+                rInvFlags |= 0x40;
+                SwPageFrm *pPage = FindPageFrm();
+                if ( !GetPrev() )
+                    CheckPageDescs( pPage );
+                if ( pPage && GetFmt()->GetPageDesc().GetNumOffset() )
+                    ((SwRootFrm*)pPage->GetUpper())->SetVirtPageNum( TRUE );
+                SwDocPosUpdate aMsgHnt( pPage->Frm().Top() );
+                GetFmt()->GetDoc()->UpdatePageFlds( &aMsgHnt );
+            }
+            break;
+
+        case RES_BREAK:
+            rInvFlags |= 0xC0;
+            break;
+
+        case RES_LAYOUT_SPLIT:
+            if ( !IsFollow() )
+                rInvFlags |= 0x40;
+            break;
+
+        case RES_UL_SPACE:
+            rInvFlags |= 0x1C;
+            /* kein Break hier */
+
+        default:
+            bClear = FALSE;
+    }
+    if ( bClear )
+    {
+        if ( pOldSet || pNewSet )
+        {
+            if ( pOldSet )
+                pOldSet->ClearItem( nWhich );
+            if ( pNewSet )
+                pNewSet->ClearItem( nWhich );
+        }
+        else
+            SwLayoutFrm::Modify( pOld, pNew );
+    }
+}
+
+/*************************************************************************
+|*
+|*    SwTabFrm::GetInfo()
+|*
+|*    Ersterstellung    MA 06. Dec. 96
+|*    Letzte Aenderung  MA 26. Jun. 98
+|*
+|*************************************************************************/
+BOOL SwTabFrm::GetInfo( SfxPoolItem &rHnt ) const
+{
+    if ( RES_VIRTPAGENUM_INFO == rHnt.Which() && IsInDocBody() )
+    {
+        SwVirtPageNumInfo &rInfo = (SwVirtPageNumInfo&)rHnt;
+        const SwPageFrm *pPage = FindPageFrm();
+        if ( pPage  )
+        {
+            if ( pPage == rInfo.GetOrigPage() && !GetPrev() )
+            {
+                //Das sollte er sein (kann allenfalls temporaer anders sein,
+                //                    sollte uns das beunruhigen?)
+                rInfo.SetInfo( pPage, this );
+                return FALSE;
+            }
+            if ( pPage->GetPhyPageNum() < rInfo.GetOrigPage()->GetPhyPageNum() &&
+                 (!rInfo.GetPage() || pPage->GetPhyPageNum() > rInfo.GetPage()->GetPhyPageNum()))
+            {
+                //Das koennte er sein.
+                rInfo.SetInfo( pPage, this );
+            }
+        }
+    }
+    return TRUE;
+}
+
+/*************************************************************************
+|*
+|*    SwTabFrm::FindLastCntnt()
+|*
+|*    Ersterstellung    MA 13. Apr. 93
+|*    Letzte Aenderung  MA 15. May. 98
+|*
+|*************************************************************************/
+SwCntntFrm *SwTabFrm::FindLastCntnt()
+{
+    SwFrm *pRet = pLower;
+    while ( pRet && !pRet->IsCntntFrm() )
+    {
+        SwFrm *pOld = pRet;
+        while ( pRet->GetNext() )
+            pRet = pRet->GetNext();
+        if ( pRet->GetLower() )
+            pRet = pRet->GetLower();
+        if ( pRet == pOld )
+        {   // Wenn am Ende der letzten Zelle ein spaltiger Bereich steht,
+            // der eine leere letzte Spalte hat, muessen wir noch die anderen
+            // Spalten abklappern, dies erledigt SwSectionFrm::FindLastCntnt
+            if( pRet->IsColBodyFrm() )
+            {
+#ifndef PRODUCT
+                SwSectionFrm* pSect = pRet->FindSctFrm();
+                ASSERT( pSect, "Wo kommt denn die Spalte her?")
+                ASSERT( IsAnLower( pSect ), "Gespaltene Zelle?" );
+#endif
+                return pRet->FindSctFrm()->FindLastCntnt();
+            }
+            return 0;   //Hier geht es nicht weiter. Inkonsistenter Zustand
+                        //der Tabelle (z.B. Undo TextToTable).
+        }
+    }
+//  ASSERT( pRet && pRet->IsCntntFrm(), "Letzter Lower von Tab kein Cnt." );
+    if ( pRet ) //#50235#
+        while ( pRet->GetNext() )
+            pRet = pRet->GetNext();
+    if( pRet->IsSctFrm() )
+        pRet = ((SwSectionFrm*)pRet)->FindLastCntnt();
+    ASSERT( pRet && pRet->IsCntntFrm(), "Letzter Lower von Tab kein Cnt." );
+    return (SwCntntFrm*)pRet;
+}
+
+/*************************************************************************
+|*
+|*  SwTabFrm::GetLeaf()
+|*
+|*  Ersterstellung      MA 19. Mar. 93
+|*  Letzte Aenderung    MA 25. Apr. 95
+|*
+|*************************************************************************/
+SwLayoutFrm *SwTabFrm::GetLeaf( MakePageType eMakePage, BOOL bFwd )
+{
+    SwLayoutFrm *pRet;
+    if ( bFwd )
+    {
+        pRet = GetNextLeaf( eMakePage );
+        while ( IsAnLower( pRet ) )
+            pRet = pRet->GetNextLeaf( eMakePage );
+    }
+    else
+        pRet = GetPrevLeaf();
+    if ( pRet )
+        pRet->Calc();
+    return pRet;
+}
+
+/*************************************************************************
+|*
+|*  SwTabFrm::ShouldBwdMoved()
+|*
+|*  Beschreibung        Returnwert sagt ob der Frm verschoben werden sollte
+|*  Ersterstellung      MA 10. Jul. 95
+|*  Letzte Aenderung    MA 04. Mar. 97
+|*
+|*************************************************************************/
+BOOL SwTabFrm::ShouldBwdMoved( SwLayoutFrm *pNewUpper, BOOL bHead, BOOL &rReformat )
+{
+    rReformat = FALSE;
+    if ( (SwFlowFrm::IsMoveBwdJump() || !IsPrevObjMove()) )
+    {
+        //Das zurueckfliessen von Frm's ist leider etwas Zeitintensiv.
+        //Der haufigste Fall ist der, dass dort wo der Frm hinfliessen
+        //moechte die FixSize die gleiche ist, die der Frm selbst hat.
+        //In diesem Fall kann einfach geprueft werden, ob der Frm genug
+        //Platz fuer seine VarSize findet, ist dies nicht der Fall kann
+        //gleich auf das Verschieben verzichtet werden.
+        //Die Pruefung, ob der Frm genug Platz findet fuehrt er selbst
+        //durch, dabei wird beruecksichtigt, dass er sich moeglicherweise
+        //aufspalten kann.
+        //Wenn jedoch die FixSize eine andere ist oder Flys im Spiel sind
+        //(an der alten oder neuen Position) hat alle Prueferei keinen Sinn
+        //der Frm muss dann halt Probehalber verschoben werden (Wenn ueberhaupt
+        //etwas Platz zur Verfuegung steht).
+
+        //Die FixSize der Umgebungen in denen Tabellen herumlungern ist immer
+        //Die Breite.
+
+        SwPageFrm *pOldPage = FindPageFrm(),
+                  *pNewPage = pNewUpper->FindPageFrm();
+        BOOL bMoveAnyway = FALSE;
+        SwTwips nSpace = 0;
+
+        if ( !SwFlowFrm::IsMoveBwdJump() &&
+             Abs(pNewUpper->Prt().Width() - GetUpper()->Prt().Width()) < 2 )
+        {
+            if ( FALSE == (bMoveAnyway = BwdMoveNecessary( pOldPage, Frm() ) > 1) )
+            {
+                //Das Rechteck, in dem ich landen wuerde berechenen.
+                SwRect aRect( pNewUpper->Prt() );
+                aRect.Pos() += pNewUpper->Frm().Pos();
+                const SwFrm *pPrevFrm = pNewUpper->Lower();
+                while ( pPrevFrm )
+                {
+                    aRect.Top( pPrevFrm->Frm().Bottom() );
+                    pPrevFrm = pPrevFrm->GetNext();
+                }
+                bMoveAnyway = BwdMoveNecessary( pNewPage, aRect) > 1;
+                nSpace = aRect.Height();
+                if ( GetFmt()->GetDoc()->IsBrowseMode() )
+                    nSpace += pNewUpper->Grow( LONG_MAX, pHeight, TRUE );
+            }
+        }
+        else if ( SwFlowFrm::IsMoveBwdJump() || !bLockBackMove )
+            bMoveAnyway = TRUE;
+
+        if ( bMoveAnyway )
+            return rReformat = TRUE;
+        else if ( !bLockBackMove )
+        {   const BOOL bRepeat = GetTable()->IsHeadlineRepeat();
+            SwTwips nHeight = bRepeat && Lower()->GetNext() ?
+                    Lower()->GetNext()->Frm().Height() : Lower()->Frm().Height();
+            if ( bHead && bRepeat && Lower()->GetNext() )
+                nHeight += Lower()->Frm().Height();
+            return nHeight <= nSpace;
+        }
+    }
+    return FALSE;
+}
+
+/*************************************************************************
+|*
+|*  SwTabFrm::Cut()
+|*
+|*  Ersterstellung      MA 23. Feb. 94
+|*  Letzte Aenderung    MA 09. Sep. 98
+|*
+|*************************************************************************/
+void SwTabFrm::Cut()
+{
+    ASSERT( GetUpper(), "Cut ohne Upper()." );
+
+    SwPageFrm *pPage = FindPageFrm();
+    InvalidatePage( pPage );
+    SwFrm *pFrm = GetNext();
+    if( pFrm )
+    {   //Der alte Nachfolger hat evtl. einen Abstand zum Vorgaenger
+        //berechnet der ist jetzt wo er der erste wird obsolete
+        pFrm->_InvalidatePrt();
+        pFrm->_InvalidatePos();
+        if ( pFrm->IsCntntFrm() )
+            pFrm->InvalidatePage( pPage );
+        if( IsInSct() && !GetPrev() )
+        {
+            SwSectionFrm* pSct = FindSctFrm();
+            if( !pSct->IsFollow() )
+            {
+                pSct->_InvalidatePrt();
+                pSct->InvalidatePage( pPage );
+            }
+        }
+    }
+    else
+    {
+        InvalidateNextPos();
+        //Einer muss die Retusche uebernehmen: Vorgaenger oder Upper
+        if ( 0 != (pFrm = GetPrev()) )
+        {   pFrm->SetRetouche();
+            pFrm->Prepare( PREP_WIDOWS_ORPHANS );
+            pFrm->_InvalidatePos();
+            if ( pFrm->IsCntntFrm() )
+                pFrm->InvalidatePage( pPage );
+        }
+        //Wenn ich der einzige FlowFrm in meinem Upper bin (war), so muss
+        //er die Retouche uebernehmen.
+        //Ausserdem kann eine Leerseite entstanden sein.
+        else
+        {   SwRootFrm *pRoot = (SwRootFrm*)pPage->GetUpper();
+            pRoot->SetSuperfluous();
+            GetUpper()->SetCompletePaint();
+            if( IsInSct() )
+            {
+                SwSectionFrm* pSct = FindSctFrm();
+                if( !pSct->IsFollow() )
+                {
+                    pSct->_InvalidatePrt();
+                    pSct->InvalidatePage( pPage );
+                }
+            }
+        }
+    }
+
+    //Erst removen, dann Upper Shrinken.
+    SwLayoutFrm *pUp = GetUpper();
+    Remove();
+    if ( pUp )
+    {
+        ASSERT( !pUp->IsFtnFrm(), "Tabelle in Fussnote." );
+        SwSectionFrm *pSct;
+        if( !pUp->Lower() && pUp->IsInSct() &&
+            !(pSct = pUp->FindSctFrm())->ContainsCntnt() )
+        {
+            if ( pUp->GetUpper() )
+            {
+                pSct->DelEmpty( FALSE );
+                pSct->_InvalidateSize();
+            }
+        }
+        else if ( Frm().Height() )
+            pUp->Shrink( Frm().Height(), pHeight );
+    }
+
+    if ( pPage && !IsFollow() && pPage->GetUpper() )
+        ((SwRootFrm*)pPage->GetUpper())->InvalidateBrowseWidth();
+}
+
+/*************************************************************************
+|*
+|*  SwTabFrm::Paste()
+|*
+|*  Ersterstellung      MA 23. Feb. 94
+|*  Letzte Aenderung    MA 09. Sep. 98
+|*
+|*************************************************************************/
+void SwTabFrm::Paste( SwFrm* pParent, SwFrm* pSibling )
+{
+    ASSERT( pParent, "Kein Parent fuer Paste." );
+    ASSERT( pParent->IsLayoutFrm(), "Parent ist CntntFrm." );
+    ASSERT( pParent != this, "Bin selbst der Parent." );
+    ASSERT( pSibling != this, "Bin mein eigener Nachbar." );
+    ASSERT( !GetPrev() && !GetNext() && !GetUpper(),
+            "Bin noch irgendwo angemeldet." );
+
+    //In den Baum einhaengen.
+    InsertBefore( (SwLayoutFrm*)pParent, pSibling );
+
+    _InvalidateAll();
+    SwPageFrm *pPage = FindPageFrm();
+    InvalidatePage( pPage );
+
+    if ( GetNext() )
+    {
+        GetNext()->_InvalidatePos();
+        GetNext()->_InvalidatePrt();
+        if ( GetNext()->IsCntntFrm() )
+            GetNext()->InvalidatePage( pPage );
+    }
+
+    if ( Frm().Height() )
+        pParent->Grow( Frm().Height(), pHeight );
+
+    if ( Frm().Width() != pParent->Prt().Width() )
+        Prepare( PREP_FIXSIZE_CHG );
+
+    if ( GetPrev() )
+    {
+        if ( !IsFollow() )
+        {
+            GetPrev()->InvalidateSize();
+            if ( GetPrev()->IsCntntFrm() )
+                GetPrev()->InvalidatePage( pPage );
+        }
+    }
+    else if ( GetNext() )
+        //Bei CntntFrm's gilt es den Abstand zum Vorgaenger/Nachfolger
+        //zu beachten. Faelle (beide treten immer gleichzeitig auf):
+        //a) Der Cntnt wird der erste einer Kette
+        //b) Der neue Nachfolger war vorher der erste einer Kette
+        GetNext()->_InvalidatePrt();
+
+    if ( pPage && !IsFollow() )
+    {
+        if ( pPage->GetUpper() )
+            ((SwRootFrm*)pPage->GetUpper())->InvalidateBrowseWidth();
+
+        if ( !GetPrev() )//Mindestens fuer HTML mit Tabelle am Anfang notwendig.
+        {
+            const SwPageDesc *pDesc = GetFmt()->GetPageDesc().GetPageDesc();
+            if ( (pDesc && pDesc != pPage->GetPageDesc()) ||
+                 (!pDesc && pPage->GetPageDesc() != &GetFmt()->GetDoc()->GetPageDesc(0)) )
+                CheckPageDescs( pPage, TRUE );
+        }
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwRowFrm::SwRowFrm(), ~SwRowFrm()
+|*
+|*  Ersterstellung      MA 09. Mar. 93
+|*  Letzte Aenderung    MA 30. May. 96
+|*
+|*************************************************************************/
+SwRowFrm::SwRowFrm( const SwTableLine &rLine ):
+    SwLayoutFrm( rLine.GetFrmFmt() ),
+    pTabLine( &rLine )
+{
+    nType = FRM_ROW;
+
+    //Gleich die Boxen erzeugen und einfuegen.
+    const SwTableBoxes &rBoxes = rLine.GetTabBoxes();
+    SwFrm *pPrev = 0;
+    for ( USHORT i = 0; i < rBoxes.Count(); ++i )
+    {
+        SwCellFrm *pNew = new SwCellFrm( *rBoxes[i] );
+        pNew->InsertBehind( this, pPrev );
+        pNew->bVarHeight = FALSE;
+        pPrev = pNew;
+    }
+}
+
+SwRowFrm::~SwRowFrm()
+{
+    SwModify* pMod = GetFmt();
+    if( pMod )
+    {
+        pMod->Remove( this );           // austragen,
+        if( !pMod->GetDepends() )
+            delete pMod;                // und loeschen
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwRowFrm::RegistFlys()
+|*
+|*  Ersterstellung      MA 08. Jul. 93
+|*  Letzte Aenderung    MA 08. Jul. 93
+|*
+|*************************************************************************/
+void SwRowFrm::RegistFlys( SwPageFrm *pPage )
+{
+    ::RegistFlys( pPage ? pPage : FindPageFrm(), this );
+}
+
+/*************************************************************************
+|*
+|*    SwRowFrm::Modify()
+|*
+|*    Ersterstellung    MA 12. Nov. 97
+|*    Letzte Aenderung  MA 12. Nov. 97
+|*
+|*************************************************************************/
+void SwRowFrm::Modify( SfxPoolItem * pOld, SfxPoolItem * pNew )
+{
+    BOOL bAttrSetChg = pNew && RES_ATTRSET_CHG == pNew->Which();
+    const SfxPoolItem *pItem = 0;
+
+    if( bAttrSetChg )
+        ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState( RES_FRM_SIZE, FALSE, &pItem);
+    else if ( RES_FRM_SIZE == pNew->Which() )
+        pItem = pNew;
+
+    if ( pItem )
+    {
+        SwTabFrm *pTab = FindTabFrm();
+        if ( pTab && pTab->IsFollow() &&
+             (!GetPrev() ||
+              (pTab->GetTable()->IsHeadlineRepeat() && !GetPrev()->GetPrev())))
+        {
+            pTab->FindMaster()->InvalidatePos();
+        }
+    }
+
+    SwLayoutFrm::Modify( pOld, pNew );
+}
+
+
+
+/*************************************************************************
+|*
+|*  SwRowFrm::MakeAll()
+|*
+|*  Ersterstellung      MA 01. Mar. 94
+|*  Letzte Aenderung    MA 01. Mar. 94
+|*
+|*************************************************************************/
+void SwRowFrm::MakeAll()
+{
+    if ( !GetNext() )
+        bValidSize = FALSE;
+    SwLayoutFrm::MakeAll();
+}
+
+/*************************************************************************
+|*
+|*  SwRowFrm::Format()
+|*
+|*  Ersterstellung      MA 13. Mar. 93
+|*  Letzte Aenderung    MA 20. Jun. 96
+|*
+|*************************************************************************/
+long MA_FASTCALL CalcHeightWidthFlys( const SwFrm *pFrm )
+{
+    long nHeight = 0;
+    const SwFrm* pTmp = pFrm->IsSctFrm() ?
+            ((SwSectionFrm*)pFrm)->ContainsCntnt() : pFrm;
+    while( pTmp )
+    {
+        if ( pTmp->GetDrawObjs() )
+        {
+            for ( USHORT i = 0; i < pTmp->GetDrawObjs()->Count(); ++i )
+            {
+                const SdrObject *pO = (*pTmp->GetDrawObjs())[i];
+                if ( pO->IsWriterFlyFrame() )
+                {
+                    const SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+                    if ( !pFly->IsFlyInCntFrm() && pFly->Frm().Top()!=WEIT_WECH )
+//                       pFrm->GetValidPosFlag() && pFrm->GetValidSizeFlag() )
+                    {
+                        const SwFmtFrmSize &rSz = pFly->GetFmt()->GetFrmSize();
+                        if( !rSz.GetHeightPercent() )
+                            nHeight = Max( nHeight, pFly->Frm().Height() +
+                                pFly->GetCurRelPos().Y() + pTmp->Frm().Top()
+                                - pFrm->Frm().Top() - pFrm->Frm().Height() );
+                    }
+                }
+            }
+        }
+        if( !pFrm->IsSctFrm() )
+            break;
+        pTmp = pTmp->FindNextCnt();
+        if( !((SwSectionFrm*)pFrm)->IsAnLower( pTmp ) )
+            break;
+    }
+    return nHeight;
+}
+
+SwTwips MA_FASTCALL lcl_CalcMinRowHeight( SwLayoutFrm *pRow );
+
+SwTwips MA_FASTCALL lcl_CalcMinCellHeight( SwLayoutFrm *pCell,
+                                  const SwBorderAttrs *pAttrs = 0 )
+{
+    SwTwips nHeight = 0;
+    SwFrm *pLow = pCell->Lower();
+    if ( pLow )
+    {
+        long nFlyAdd = 0;
+        while ( pLow )
+        {
+            if( pLow->IsCntntFrm() || pLow->IsSctFrm() )
+            {
+                nHeight += pLow->Frm().Height();
+                nFlyAdd = Max( 0L, nFlyAdd - pLow->Frm().Height() );
+                nFlyAdd = Max( nFlyAdd, ::CalcHeightWidthFlys( pLow ) );
+            }
+            else
+                nHeight += ::lcl_CalcMinRowHeight( (SwLayoutFrm*)pLow );
+
+            pLow = pLow->GetNext();
+        }
+        if ( nFlyAdd )
+            nHeight += nFlyAdd;
+    }
+    //Der Border will natuerlich auch mitspielen, er kann leider nicht
+    //aus PrtArea und Frm errechnet werden, da diese in beliebiger
+    //Kombination ungueltig sein koennen.
+    if ( pAttrs )
+        nHeight += pAttrs->CalcTop() + pAttrs->CalcBottom();
+    else
+    {
+        SwBorderAttrAccess aAccess( SwFrm::GetCache(), pCell );
+        const SwBorderAttrs &rAttrs = *aAccess.Get();
+        nHeight += rAttrs.CalcTop() + rAttrs.CalcBottom();
+    }
+    return nHeight;
+}
+
+SwTwips MA_FASTCALL lcl_CalcMinRowHeight( SwLayoutFrm *pRow )
+{
+    if ( pRow->HasFixSize( pHeight ) )
+        return pRow->Frm().Height();
+
+    SwTwips nHeight = 0;
+    SwLayoutFrm *pLow = (SwLayoutFrm*)pRow->Lower();
+    while ( pLow )
+    {
+        SwTwips nTmp = ::lcl_CalcMinCellHeight( pLow );
+        if ( nTmp > nHeight )
+            nHeight = nTmp;
+        pLow = (SwLayoutFrm*)pLow->GetNext();
+    }
+    const SwFmtFrmSize &rSz = pRow->GetFmt()->GetFrmSize();
+    if ( rSz.GetSizeType() == ATT_MIN_SIZE )
+        nHeight = Max( nHeight, rSz.GetHeight() );
+    return nHeight;
+}
+
+void SwRowFrm::Format( const SwBorderAttrs *pAttrs )
+{
+    ASSERT( pAttrs, "SwRowFrm::Format ohne Attrs." );
+
+    const BOOL bFix = bFixHeight;
+
+    if ( !bValidPrtArea )
+    {
+        //RowFrms haben keine Umrandung usw. also entspricht die PrtArea immer
+        //dem Frm.
+        bValidPrtArea = TRUE;
+        aPrt.Left( 0 );
+        aPrt.Top( 0 );
+        aPrt.Width ( aFrm.Width() );
+        aPrt.Height( aFrm.Height() );
+    }
+
+    while ( !bValidSize )
+    {
+        bValidSize = TRUE;
+
+#ifndef PRODUCT
+        if ( HasFixSize( pHeight ) )
+        {
+            const SwFmtFrmSize &rFrmSize = GetFmt()->GetFrmSize();
+            ASSERT( rFrmSize.GetSize().Height() > 0, "Hat ihn" );
+        }
+#endif
+        const SwTwips nDiff = Frm().Height() - (HasFixSize( pHeight ) ?
+                                                    pAttrs->GetSize().Height() :
+                                                    ::lcl_CalcMinRowHeight( this ));
+        if ( nDiff )
+        {
+            bFixHeight = FALSE;
+            if ( nDiff > 0 )
+                Shrink( nDiff, pHeight, FALSE, TRUE );
+            else if ( nDiff < 0 )
+                Grow( -nDiff, pHeight );
+            bFixHeight = bFix;
+        }
+    }
+    if ( !GetNext() )
+    {
+        //Der letzte fuellt den verbleibenden Raum im Upper aus.
+        SwTwips nDiff = GetUpper()->Prt().Height();
+        SwFrm *pSibling = GetUpper()->Lower();
+        do
+        {   nDiff -= pSibling->Frm().Height();
+            pSibling = pSibling->GetNext();
+        } while ( pSibling );
+        if ( nDiff > 0 )
+        {
+            bFixHeight = FALSE;
+            Grow( nDiff, pHeight );
+            bFixHeight = bFix;
+            bValidSize = TRUE;
+        }
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwRowFrm::AdjustCells()
+|*
+|*  Ersterstellung      MA 10. Aug. 93
+|*  Letzte Aenderung    MA 16. Dec. 96
+|*
+|*************************************************************************/
+void SwRowFrm::AdjustCells( const SwTwips nHeight, const BOOL bHeight )
+{
+    SwFrm *pFrm = Lower();
+    if ( bHeight )
+    {
+        while ( pFrm )
+        {   if ( pFrm->Frm().Height() != nHeight )
+            {
+                pFrm->Frm().Height( nHeight );
+                pFrm->_InvalidatePrt();
+            }
+            pFrm = pFrm->GetNext();
+        }
+    }
+    else
+    {   while ( pFrm )
+        {
+            pFrm->_InvalidateAll();
+            pFrm = pFrm->GetNext();
+        }
+    }
+    InvalidatePage();
+}
+
+/*************************************************************************
+|*
+|*  SwRowFrm::Cut()
+|*
+|*  Ersterstellung      MA 12. Nov. 97
+|*  Letzte Aenderung    MA 12. Nov. 97
+|*
+|*************************************************************************/
+void SwRowFrm::Cut()
+{
+    SwTabFrm *pTab = FindTabFrm();
+    if ( pTab && pTab->IsFollow() &&
+         (!GetPrev() ||
+          (pTab->GetTable()->IsHeadlineRepeat() && !GetPrev()->GetPrev())))
+    {
+        pTab->FindMaster()->InvalidatePos();
+    }
+    SwLayoutFrm::Cut();
+}
+
+/*************************************************************************
+|*
+|*  SwRowFrm::GrowFrm()
+|*
+|*  Ersterstellung      MA 15. Mar. 93
+|*  Letzte Aenderung    MA 05. May. 94
+|*
+|*************************************************************************/
+SwTwips SwRowFrm::GrowFrm( SwTwips nDist, const SzPtr pDirection,
+                           BOOL bTst, BOOL bInfo )
+{
+    const SwTwips nReal = SwLayoutFrm::GrowFrm( nDist, pDirection, bTst, bInfo);
+
+    //Hoehe der Zellen auf den neuesten Stand bringen.
+    if ( !bTst )
+    {
+        AdjustCells( Prt().Height() + nReal,
+                                      pDirection == pHeight ? TRUE : FALSE );
+        if ( nReal )
+            SetCompletePaint();
+    }
+    return nReal;
+}
+/*************************************************************************
+|*
+|*  SwRowFrm::ShrinkFrm()
+|*
+|*  Ersterstellung      MA 15. Mar. 93
+|*  Letzte Aenderung    MA 20. Jun. 96
+|*
+|*************************************************************************/
+SwTwips SwRowFrm::ShrinkFrm( SwTwips nDist, const SzPtr pDirection,
+                             BOOL bTst, BOOL bInfo )
+{
+    if ( HasFixSize( pDirection ) )
+    {
+        AdjustCells( Prt().Height(), pDirection == pHeight ? TRUE : FALSE);
+        return 0L;
+    }
+
+    //bInfo wird ggf. vom SwRowFrm::Format auf TRUE gesetzt, hier muss dann
+    //entsprechend reagiert werden
+    const BOOL bShrinkAnyway = bInfo;
+
+    //Nur soweit Shrinken, wie es der Inhalt der groessten Zelle zulaesst.
+    SwTwips nRealDist = nDist;
+    if ( pDirection == pHeight )
+    {
+        const SwFmtFrmSize &rSz = GetFmt()->GetFrmSize();
+        SwTwips nMinHeight = rSz.GetSizeType() == ATT_MIN_SIZE ? rSz.GetHeight() : 0;
+        SwLayoutFrm *pCell = (SwLayoutFrm*)Lower();
+        if ( nMinHeight < Frm().Height() )
+        {
+            SwLayoutFrm *pCell = (SwLayoutFrm*)Lower();
+            while ( pCell )
+            {
+                SwTwips nAct = ::lcl_CalcMinCellHeight( pCell );
+                if ( nAct > nMinHeight )
+                    nMinHeight = nAct;
+                if ( nMinHeight >= Frm().Height() )
+                    break;
+                pCell = (SwLayoutFrm*)pCell->GetNext();
+            }
+        }
+        if ( (Frm().Height() - nRealDist) < nMinHeight )
+            nRealDist = Frm().Height() - nMinHeight;
+    }
+    if ( nRealDist < 0 )
+        nRealDist = 0;
+
+    SwTwips nReal = nRealDist;
+    if ( nReal )
+    {
+        if ( !bTst )
+            Frm().SSize().*pDirection -= nReal;
+
+        SwTwips nTmp = GetUpper()->Shrink( nReal, pDirection, bTst );
+        if ( !bShrinkAnyway && !GetNext() && nTmp != nReal )
+        {
+            //Der letzte bekommt den Rest im Upper und nimmt deshalb
+            //ggf. Ruecksichten (sonst: Endlosschleife)
+            if ( !bTst )
+                Frm().SSize().*pDirection += nReal - nTmp;
+            nReal = nTmp;
+        }
+    }
+
+    //Geeignet invalidieren und die Hoehe der Zellen auf den neuesten
+    //Stand bringen.
+    if ( !bTst )
+    {
+        if ( nReal )
+        {
+            if ( GetNext() )
+                GetNext()->_InvalidatePos();
+            _InvalidateAll();
+            SetCompletePaint();
+
+            SwTabFrm *pTab = FindTabFrm();
+            if ( pTab->IsFollow() &&
+                 (!GetPrev() ||
+                  (pTab->GetTable()->IsHeadlineRepeat() && !GetPrev()->GetPrev())))
+            {
+                pTab->FindMaster()->InvalidatePos();
+            }
+        }
+        AdjustCells( Prt().Height() - nReal,
+                                         pDirection == pHeight ? TRUE : FALSE );
+    }
+    return nReal;
+}
+
+/*************************************************************************
+|*
+|*  SwCellFrm::SwCellFrm(), ~SwCellFrm()
+|*
+|*  Ersterstellung      MA 09. Mar. 93
+|*  Letzte Aenderung    MA 30. May. 96
+|*
+|*************************************************************************/
+SwCellFrm::SwCellFrm( const SwTableBox &rBox ) :
+    SwLayoutFrm( rBox.GetFrmFmt() ),
+    pTabBox( &rBox )
+{
+    nType = FRM_CELL;
+
+    //Wenn ein StartIdx vorhanden ist, so werden CntntFrms in der Zelle
+    //angelegt, andernfalls muessen Rows vorhanden sein und diese werden
+    //angelegt.
+    if ( rBox.GetSttIdx() )
+    {
+        ULONG nIndex = rBox.GetSttIdx();
+        ::_InsertCnt( this, rBox.GetFrmFmt()->GetDoc(), ++nIndex );
+    }
+    else
+    {   const SwTableLines &rLines = rBox.GetTabLines();
+        SwFrm *pPrev = 0;
+        for ( USHORT i = 0; i < rLines.Count(); ++i )
+        {
+            SwRowFrm *pNew = new SwRowFrm( *rLines[i] );
+            pNew->InsertBehind( this, pPrev );
+            pPrev = pNew;
+        }
+    }
+}
+
+SwCellFrm::~SwCellFrm()
+{
+    SwModify* pMod = GetFmt();
+    if( pMod )
+    {
+        pMod->Remove( this );           // austragen,
+        if( !pMod->GetDepends() )
+            delete pMod;                // und loeschen
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwCellFrm::Format()
+|*
+|*  Ersterstellung      MA 09. Mar. 93
+|*  Letzte Aenderung    MA 29. Jan. 98
+|*
+|*************************************************************************/
+BOOL lcl_ArrangeLowers( SwLayoutFrm *pLay, long lYStart, BOOL bInva )
+{
+    BOOL bRet = FALSE;
+    SwFrm *pFrm = pLay->Lower();
+    while ( pFrm )
+    {
+        if ( pFrm->Frm().Top() != lYStart )
+        {
+            bRet = TRUE;
+            const long lDiff = lYStart - pFrm->Frm().Top();
+            pFrm->Frm().Pos().Y() = lYStart;
+            pFrm->SetCompletePaint();
+            if ( !pFrm->GetNext() )
+                pFrm->SetRetouche();
+            if( bInva )
+                pFrm->Prepare( PREP_POS_CHGD );
+            if ( pFrm->IsLayoutFrm() && ((SwLayoutFrm*)pFrm)->Lower() )
+                lcl_ArrangeLowers( (SwLayoutFrm*)pFrm,
+                    ((SwLayoutFrm*)pFrm)->Lower()->Frm().Top()+lDiff, bInva );
+            if ( pFrm->GetDrawObjs() )
+            {
+                for ( USHORT i = 0; i < pFrm->GetDrawObjs()->Count(); ++i )
+                {
+                    SdrObject *pO = (*pFrm->GetDrawObjs())[i];
+                    if ( pO->IsWriterFlyFrame() )
+                    {
+                        SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+                        if ( WEIT_WECH != pFly->Frm().Top() )
+                            pFly->Frm().Pos().Y() += lDiff;
+                        if ( pFly->IsFlyInCntFrm() )
+                            ((SwFlyInCntFrm*)pFly)->AddRefOfst( lDiff );
+                        else if( pFly->IsAutoPos() )
+                            ((SwFlyAtCntFrm*)pFly)->AddLastCharY( lDiff );
+                        if ( ::lcl_ArrangeLowers( pFly, pFly->Frm().Top() +
+                                pFly->Prt().Top(), bInva ) )
+                            pFly->SetCompletePaint();
+                    }
+                    else
+                        pO->SetAnchorPos( pFrm->Frm().Pos() );
+                }
+            }
+        }
+        if( !pFrm->IsColumnFrm() ) // Spalten in Bereichen sind nebeneinander,
+            lYStart += pFrm->Frm().Height();  // nicht untereinander!
+        pFrm = pFrm->GetNext();
+    }
+    return bRet;
+}
+
+void SwCellFrm::Format( const SwBorderAttrs *pAttrs )
+{
+    ASSERT( pAttrs, "CellFrm::Format, pAttrs ist 0." );
+
+    if ( !bValidPrtArea )
+    {
+        bValidPrtArea = TRUE;
+
+        //Position einstellen.
+        aPrt.Left( pAttrs->CalcLeft( this ) );
+        aPrt.Top(  pAttrs->CalcTop() );
+
+        //Sizes einstellen; die Groesse gibt der umgebende Frm vor, die
+        //die Raender werden einfach abgezogen.
+        aPrt.Width ( aFrm.Width() - (aPrt.Left() + pAttrs->CalcRight()) );
+        aPrt.Height( aFrm.Height()- (aPrt.Top()  + pAttrs->CalcBottom()));
+    }
+
+    long nRemaining = ::lcl_CalcMinCellHeight( this, pAttrs );
+    if ( !bValidSize )
+    {
+        bValidSize = TRUE;
+
+        //Die VarSize der CellFrms ist immer die Breite.
+        //Tatsaechlich ist die Breite jedoch nicht Variabel, sie wird durch das
+        //Format vorgegeben. Dieser Vorgegebene Wert muss aber nun wiederum
+        //nicht der tatsaechlichen Breite entsprechen. Die Breite wird auf
+        //Basis des Attributes errechnet, der Wert im Attribut passt zu dem
+        //gewuenschten Wert des TabFrms. Anpassungen die dort vorgenommen
+        //wurden werden hier Proportional beruecksichtigt.
+        //Wenn die Celle keinen Nachbarn mehr hat beruecksichtigt sie nicht
+        //die Attribute, sonder greift sich einfach den Rest des
+        //Uppers.
+        SwTwips nWidth;
+        if ( GetNext() )
+        {
+            const SwTabFrm *pTab = FindTabFrm();
+            SwTwips nWish = pTab->GetFmt()->GetFrmSize().GetWidth();
+            nWidth = pAttrs->GetSize().Width();
+
+            ASSERT( nWish, "Tabelle ohne Breite?" );
+            ASSERT( nWidth <= nWish, "Zelle breiter als Tabelle." );
+            ASSERT( nWidth > 0, "Box without width" );
+
+            if ( nWish != pTab->Prt().Width() )
+            {
+                nWidth *= pTab->Prt().Width();
+                nWidth /= nWish;
+            }
+        }
+        else
+        {
+            ASSERT( pAttrs->GetSize().Width() > 0, "Box without width" );
+            nWidth = GetUpper()->Prt().Width();
+            SwFrm *pPre = GetUpper()->Lower();
+            while ( pPre != this )
+            {   nWidth -= pPre->Frm().Width();
+                pPre = pPre->GetNext();
+            }
+        }
+        const long nDiff = nWidth - Frm().Width();
+        Frm().Width( nWidth );
+        Prt().Width( Prt().Width() + nDiff );
+
+        //Jetzt die Hoehe einstellen, sie wird vom Inhalt und den Raendern
+        //bestimmt.
+        const long nDiffHeight = nRemaining - Frm().Height();
+        if ( nDiffHeight )
+        {
+            if ( nDiffHeight > 0 )
+            {
+                //Wieder validieren wenn kein Wachstum stattgefunden hat.
+                //Invalidiert wird durch AdjustCells von der Row.
+                if ( !Grow( nDiffHeight, pHeight ) )
+                    bValidSize = bValidPrtArea = TRUE;
+            }
+            else
+            {
+                //Nur dann invalidiert lassen, wenn tatsaechlich
+                //geshrinkt wurde; das kann abgelehnt werden, weil alle
+                //nebeneinanderliegenden Zellen gleichgross sein muessen.
+                if ( !Shrink( -nDiffHeight, pHeight ) )
+                    bValidSize = bValidPrtArea = TRUE;
+            }
+        }
+    }
+    const SwFmtVertOrient &rOri = pAttrs->GetAttrSet().GetVertOrient();
+    if ( VERT_NONE != rOri.GetVertOrient() )
+    {
+        if ( !Lower()->IsCntntFrm() && !Lower()->IsSctFrm() )
+        {
+            //ASSERT fuer HTML-Import!
+            ASSERT( !this, "VAlign an Zelle ohne Inhalt" );
+            return;
+        }
+        BOOL bVertDir = TRUE;
+        //Keine Ausrichtung wenn Rahmen mit Umlauf in die Zelle ragen.
+        SwPageFrm *pPg = FindPageFrm();
+        if ( pPg->GetSortedObjs() )
+        {
+            SwRect aRect( Prt() ); aRect += Frm().Pos();
+            for ( USHORT i = 0; i < pPg->GetSortedObjs()->Count(); ++i )
+            {
+                const SdrObject *pObj = (*pPg->GetSortedObjs())[i];
+                SwRect aTmp( pObj->GetBoundRect() );
+                if ( aTmp.IsOver( aRect ) )
+                {
+                    SdrObjUserCall *pUserCall;
+                    const SwFmtSurround &rSur = ((SwContact*)
+                               (pUserCall=GetUserCall(pObj)))->GetFmt()->GetSurround();
+                    if ( SURROUND_THROUGHT != rSur.GetSurround() )
+                    {
+                        const SwFrm *pAnch;
+                        if ( pObj->IsWriterFlyFrame() )
+                        {
+                            const SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+                            if ( pFly->IsAnLower( this ) )
+                                continue;
+                            pAnch = pFly->GetAnchor();
+                        }
+                        else
+                            pAnch = ((SwDrawContact*)pUserCall)->GetAnchor();
+                        if ( !IsAnLower( pAnch ) )
+                        {
+                            bVertDir = FALSE;
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+        if ( (bVertDir &&
+                (nRemaining -= (pAttrs->CalcTop() + pAttrs->CalcBottom())) < Prt().Height()) ||
+                Lower()->Frm().Top() > Frm().Top()+Prt().Top() )
+        {
+            long lTopOfst = 0,
+                    nDiff = Prt().Height() - nRemaining;
+            if ( nDiff >= 0 )
+            {
+                if ( bVertDir )
+                {
+                    switch ( rOri.GetVertOrient() )
+                    {
+                        case VERT_CENTER:   lTopOfst = nDiff / 2; break;
+                        case VERT_BOTTOM:   lTopOfst = nDiff;     break;
+                    };
+                }
+                if ( lcl_ArrangeLowers( this, Frm().Top()+Prt().Top()+lTopOfst,
+                      !bVertDir ) )
+                    SetCompletePaint();
+            }
+        }
+    }
+    else
+    {
+        //Ist noch eine alte Ausrichtung beruecksichtigt worden?
+        if ( Lower()->IsCntntFrm() )
+        {
+            const long lYStart = Frm().Top()+Prt().Top();
+            lcl_ArrangeLowers( this, lYStart, TRUE );
+        }
+    }
+}
+
+/*************************************************************************
+|*
+|*    SwCellFrm::Modify()
+|*
+|*    Ersterstellung    MA 20. Dec. 96
+|*    Letzte Aenderung  MA 20. Dec. 96
+|*
+|*************************************************************************/
+void SwCellFrm::Modify( SfxPoolItem * pOld, SfxPoolItem * pNew )
+{
+    BOOL bAttrSetChg = pNew && RES_ATTRSET_CHG == pNew->Which();
+    const SfxPoolItem *pItem = 0;
+
+    if( bAttrSetChg )
+        ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState( RES_VERT_ORIENT, FALSE, &pItem);
+    else if ( RES_VERT_ORIENT == pNew->Which() )
+        pItem = pNew;
+
+    if ( pItem )
+    {
+        BOOL bInva = TRUE;
+        if ( VERT_NONE == ((SwFmtVertOrient*)pItem)->GetVertOrient() &&
+             Lower()->IsCntntFrm() )
+        {
+            const long lYStart = Frm().Top()+Prt().Top();
+            bInva = lcl_ArrangeLowers( this, lYStart, FALSE );
+        }
+        if ( bInva )
+        {
+            SetCompletePaint();
+            InvalidatePrt();
+        }
+    }
+
+    SwLayoutFrm::Modify( pOld, pNew );
+}
+
diff --git a/sw/source/core/layout/trvlfrm.cxx b/sw/source/core/layout/trvlfrm.cxx
new file mode 100644
index 000000000000..f1c6a10354c7
--- /dev/null
+++ b/sw/source/core/layout/trvlfrm.cxx
@@ -0,0 +1,2075 @@
+/*************************************************************************
+ *
+ *  $RCSfile: trvlfrm.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:22 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _BIGINT_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_PROTITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SV_SETTINGS_HXX //autogen
+#include 
+#endif
+#ifndef _SV_OUTDEV_HXX //autogen
+#include 
+#endif
+#ifndef _FMTPDSC_HXX //autogen
+#include 
+#endif
+#ifndef _FMTSRND_HXX //autogen
+#include 
+#endif
+
+#ifndef _PAGEFRM_HXX //autogen
+#include 
+#endif
+#ifndef _ROOTFRM_HXX //autogen
+#include 
+#endif
+#ifndef _CNTFRM_HXX //autogen
+#include 
+#endif
+#ifndef _FTNFRM_HXX //autogen
+#include 
+#endif
+#ifndef _FLYFRM_HXX //autogen
+#include 
+#endif
+#ifndef _TABFRM_HXX //autogen
+#include 
+#endif
+#ifndef _CELLFRM_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFRM_HXX //autogen
+#include 
+#endif
+#ifndef _VIEWSH_HXX //autogen
+#include 
+#endif
+#ifndef _DOC_HXX //autogen
+#include 
+#endif
+#ifndef _VISCRS_HXX //autogen
+#include 
+#endif
+#ifndef _PAM_HXX //autogen
+#include 
+#endif
+#ifndef _NODE_HXX //autogen
+#include 
+#endif
+#ifndef _FRMFMT_HXX //autogen
+#include 
+#endif
+#ifndef _SWTABLE_HXX //autogen
+#include 
+#endif
+#ifndef _DFLYOBJ_HXX //autogen
+#include 
+#endif
+#ifndef _CRSTATE_HXX //autogen
+#include 
+#endif
+#ifndef _FRMTOOL_HXX //autogen
+#include 
+#endif
+#ifndef _HINTS_HXX //autogen
+#include 
+#endif
+#ifndef _FRMSH_HXX
+#include 
+#endif
+
+
+//Fuer SwFlyFrm::GetCrsrOfst
+class SwCrsrOszControl
+{
+public:
+    // damit schon der Compiler die Klasse initialisieren kann, keinen
+    // DTOR und member als publics:
+    const SwFlyFrm *pEntry;
+    const SwFlyFrm *pStk1;
+    const SwFlyFrm *pStk2;
+
+//public:
+//    SwCrsrOszControl() : pStk1( 0 ), pStk2( 0 ) {}; // ; <- ????
+
+    BOOL ChkOsz( const SwFlyFrm *pFly )
+        {
+            BOOL bRet = TRUE;
+            if ( pFly != pStk1 && pFly != pStk2 )
+            {
+                pStk1 = pStk2;
+                pStk2 = pFly;
+                bRet  = FALSE;
+            }
+            return bRet;
+        }
+    void Entry( const SwFlyFrm *pFly )
+        {
+            if ( !pEntry )
+                pEntry = pStk1 = pFly;
+        }
+    void Exit( const SwFlyFrm *pFly )
+        {
+            if ( pFly == pEntry )
+                pEntry = pStk1 = pStk2 = 0;
+        }
+};
+
+static SwCrsrOszControl aOszCtrl = { 0, 0, 0 };
+
+/*************************************************************************
+|*
+|*  SwLayoutFrm::GetCrsrOfst()
+|*
+|*  Beschreibung:       Sucht denjenigen CntntFrm, innerhalb dessen
+|*                      PrtArea der Point liegt.
+|*  Ersterstellung      MA 20. Jul. 92
+|*  Letzte Aenderung    MA 23. May. 95
+|*
+|*************************************************************************/
+BOOL SwLayoutFrm::GetCrsrOfst( SwPosition *pPos, Point &rPoint,
+                            const SwCrsrMoveState* pCMS ) const
+{
+    BOOL bRet = FALSE;
+    const SwFrm *pFrm = Lower();
+    while ( !bRet && pFrm )
+    {   pFrm->Calc();
+        SwRect aPrtRect( pFrm->Prt() );
+        aPrtRect.Pos() += pFrm->Frm().Pos();
+        if ( aPrtRect.IsInside( rPoint ) &&
+            pFrm->GetCrsrOfst( pPos, rPoint, pCMS ) )
+            bRet = TRUE;
+        else
+            pFrm = pFrm->GetNext();
+        if ( pCMS && pCMS->bStop )
+            return FALSE;
+    }
+    return bRet;
+}
+
+/*************************************************************************
+|*
+|*  SwPageFrm::GetCrsrOfst()
+|*
+|*  Beschreibung:       Sucht die Seite, innerhalb der der gesuchte Point
+|*                      liegt.
+|*  Ersterstellung      MA 20. Jul. 92
+|*  Letzte Aenderung    MA 18. Jul. 96
+|*
+|*************************************************************************/
+#pragma optimize("e",off)
+
+BOOL SwPageFrm::GetCrsrOfst( SwPosition *pPos, Point &rPoint,
+                            const SwCrsrMoveState* pCMS ) const
+{
+    BOOL bRet     = FALSE;
+    const SwPageFrm *pPage = this;
+    const PtPtr pFix = pFIXPOS;
+    const PtPtr pVar = pVARPOS;
+    Point aStPoint( rPoint );
+    Point aPoint;
+    while ( !bRet && pPage )
+    {
+        aPoint = aStPoint;
+
+        //Wenn der Point in der VarRichtung zwischen zwei Seiten liegt
+        //erhaelt die Seite die dem Point naeher steht den Zuschlag.
+        SwTwips nTmp = bVarHeight ? pPage->Frm().Top() :
+                                    pPage->Frm().Left();
+        if ( pPage->GetPrev() )
+        {
+            const SwTwips nPreTmp = bVarHeight ?
+                                pPage->GetPrev()->Frm().Bottom() :
+                                pPage->GetPrev()->Frm().Right();
+            if ( (aPoint.*pVar > nPreTmp) &&
+                 (aPoint.*pVar < nTmp)    &&
+                 ((aPoint.*pVar - nPreTmp) >= (nTmp - aPoint.*pVar)) )
+                aPoint.*pVar = nTmp;
+        }
+        else if ( aPoint.*pVar < nTmp )
+            aPoint.*pVar = nTmp;
+
+        nTmp = bVarHeight ? pPage->Frm().Bottom() : pPage->Frm().Right();
+        if ( pPage->GetNext() )
+        {
+            const SwTwips nNxtTmp = bVarHeight ?
+                                pPage->GetNext()->Frm().Top() :
+                                pPage->GetNext()->Frm().Left();
+            if ( (aPoint.*pVar > nTmp) &&
+                 (aPoint.*pVar < nNxtTmp) &&
+                 ((nNxtTmp - aPoint.*pVar) >= (aPoint.*pVar - nTmp)) )
+                aPoint.*pVar = nTmp;
+        }
+        else if ( aPoint.*pVar > nTmp )
+            aPoint.*pVar = nTmp;
+
+        //Wenn der Punkt in der Fix-Richtung neben der Seite liegt wird er
+        //hineingezogen.
+        const SwTwips nVarA = pPage->Frm().Pos().*pFix;
+        const SwTwips nVarB = bVarHeight ? pPage->Frm().Right() :
+                                           pPage->Frm().Bottom();
+        if ( nVarA > aPoint.*pFix )
+            aPoint.*pFix = nVarA;
+        else if ( nVarB < aPoint.*pFix )
+            aPoint.*pFix = nVarB;
+
+        //Weitere versuche mit der aktuellen Seite nur dann, wenn sich der
+        //Point innerhalb der Seite befindet.
+        const BOOL bInside = pPage->Frm().IsInside( aPoint );
+
+        //Koennte ein Freifliegender gemeint sein?
+        //Wenn sein Inhalt geschuetzt werden soll, so ist nix mit Crsr
+        //hineinsetzen, dadurch sollten alle Aenderungen unmoeglich sein.
+        if ( bInside && pPage->GetSortedObjs() )
+        {
+            SwOrderIter aIter( pPage );
+            aIter.Top();
+            while ( aIter() )
+            {
+                SwVirtFlyDrawObj *pObj = (SwVirtFlyDrawObj*)aIter();
+                SwFlyFrm *pFly = pObj ? pObj->GetFlyFrm() : 0;
+                if ( pFly &&
+                     ((pCMS?pCMS->bSetInReadOnly:FALSE) ||
+                      !pFly->IsProtected())
+                     && pFly->GetCrsrOfst( pPos, aPoint, pCMS ) )
+                {
+                    bRet = TRUE;
+                    break;
+                }
+                if ( pCMS && pCMS->bStop )
+                    return FALSE;
+                aIter.Prev();
+            }
+        }
+        if ( !bRet && bInside )
+        {
+            //Wenn kein Cntnt unterhalb der Seite 'antwortet', so korrigieren
+            //wir den StartPoint und fangen nochmal eine Seite vor der
+            //aktuellen an. Mit Flys ist es dann allerdings vorbei.
+            if ( pPage->SwLayoutFrm::GetCrsrOfst( pPos, aPoint, pCMS ) )
+                bRet = TRUE;
+            else
+            {
+                if ( pCMS && (pCMS->bStop || pCMS->bExactOnly) )
+                {
+                    ((SwCrsrMoveState*)pCMS)->bStop = TRUE;
+                    return FALSE;
+                }
+                const SwCntntFrm *pCnt = pPage->GetCntntPos(
+                                    aPoint, FALSE, FALSE, FALSE, pCMS, FALSE );
+                if ( pCMS && pCMS->bStop )
+                    return FALSE;
+                ASSERT( pCnt, "Crsr is gone to a Black hole" );
+                if( pCMS && pCMS->pFill && pCnt->IsTxtFrm() )
+                    pCnt->GetCrsrOfst( pPos, rPoint, pCMS );
+                else
+                    pCnt->GetCrsrOfst( pPos, aPoint, pCMS );
+                bRet = TRUE;
+            }
+        }
+        pPage = (const SwPageFrm*)pPage->GetNext();
+    }
+    if ( bRet )
+        rPoint = aPoint;
+    return bRet;
+}
+
+#pragma optimize("",on)
+
+/*************************************************************************
+|*
+|*  SwRootFrm::GetCrsrOfst()
+|*
+|*  Beschreibung:       Reicht Primaer den Aufruf an die erste Seite weiter.
+|*                      Wenn der 'reingereichte Point veraendert wird,
+|*                      so wird FALSE zurueckgegeben.
+|*  Ersterstellung      MA 01. Jun. 92
+|*  Letzte Aenderung    MA 30. Nov. 94
+|*
+|*************************************************************************/
+BOOL SwRootFrm::GetCrsrOfst( SwPosition *pPos, Point &rPoint,
+                            const SwCrsrMoveState* pCMS ) const
+{
+    ASSERT( (Lower() && Lower()->IsPageFrm()), "Keinen PageFrm gefunden." );
+    if( pCMS && pCMS->pFill )
+        ((SwCrsrMoveState*)pCMS)->bFillRet = FALSE;
+    Point aOldPoint = rPoint;
+    const SwPageFrm *pPage = (SwPageFrm*)Lower();
+    pPage->SwPageFrm::GetCrsrOfst( pPos, rPoint, pCMS );
+    if( pCMS )
+    {
+        if( pCMS->bStop )
+            return FALSE;
+        if( pCMS->pFill )
+            return pCMS->bFillRet;
+    }
+    return aOldPoint == rPoint;
+}
+
+/*************************************************************************
+|*
+|*  SwCellFrm::GetCrsrOfst()
+|*
+|*  Beschreibung        Wenn es sich um eine Cntnt-tragende Cell handelt wird
+|*                      der Crsr notfalls mit Gewalt in einen der CntntFrms
+|*                      gesetzt.
+|*                      In geschuetzte Zellen gibt es hier keinen Eingang.
+|*  Ersterstellung      MA 04. Jun. 93
+|*  Letzte Aenderung    MA 23. May. 95
+|*
+|*************************************************************************/
+BOOL SwCellFrm::GetCrsrOfst( SwPosition *pPos, Point &rPoint,
+                            const SwCrsrMoveState* pCMS ) const
+{
+    ASSERT( Lower(), "Zelle ohne Inhalt." );
+
+    if ( !(pCMS?pCMS->bSetInReadOnly:FALSE) &&
+         GetFmt()->GetProtect().IsCntntProtected() )
+        return FALSE;
+
+    if ( pCMS && pCMS->eState == MV_TBLSEL )
+    {
+        const SwTabFrm *pTab = FindTabFrm();
+        if ( pTab->IsFollow() && pTab->GetTable()->IsHeadlineRepeat() &&
+             ((SwLayoutFrm*)pTab->Lower())->IsAnLower( this ) )
+        {
+            ((SwCrsrMoveState*)pCMS)->bStop = TRUE;
+            return FALSE;
+        }
+    }
+
+    if ( Lower()->IsLayoutFrm() )
+        return SwLayoutFrm::GetCrsrOfst( pPos, rPoint, pCMS );
+    else
+    {
+        Calc();
+        BOOL bRet = FALSE;
+
+        const SwFrm *pFrm = Lower();
+        while ( pFrm && !bRet )
+        {
+            pFrm->Calc();
+            if ( pFrm->Frm().IsInside( rPoint ) )
+            {
+                bRet = pFrm->GetCrsrOfst( pPos, rPoint, pCMS );
+                if ( pCMS && pCMS->bStop )
+                    return FALSE;
+            }
+            pFrm = pFrm->GetNext();
+        }
+        if ( !bRet )
+        {
+            Point *pPoint = pCMS && pCMS->pFill ? new Point( rPoint ) : NULL;
+            const SwCntntFrm *pCnt = GetCntntPos( rPoint, TRUE );
+            if( pPoint && pCnt->IsTxtFrm() )
+            {
+                pCnt->GetCrsrOfst( pPos, *pPoint, pCMS );
+                rPoint = *pPoint;
+            }
+            else
+                pCnt->GetCrsrOfst( pPos, rPoint, pCMS );
+            delete pPoint;
+        }
+        return TRUE;
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFlyFrm::GetCrsrOfst()
+|*
+|*  Ersterstellung      MA 15. Dec. 92
+|*  Letzte Aenderung    MA 23. May. 95
+|*
+|*************************************************************************/
+//Problem: Wenn zwei Flys genau gleich gross sind und auf derselben
+//Position stehen, so liegt jeder innerhalb des anderen.
+//Da jeweils geprueft wird, ob der Point nicht zufaellig innerhalb eines
+//anderen Flys liegt, der sich vollstaendig innerhalb des aktuellen befindet
+//und ggf. ein rekursiver Aufruf erfolgt wuerde o.g. Situation zu einer
+//endlosen Rekursion fuehren.
+//Mit der Hilfsklasse SwCrsrOszControl unterbinden wir die Rekursion. Das
+//GetCrsrOfst entscheidet sich bei einer Rekursion fuer denjenigen der
+//am weitesten oben liegt.
+
+BOOL SwFlyFrm::GetCrsrOfst( SwPosition *pPos, Point &rPoint,
+                            const SwCrsrMoveState* pCMS ) const
+{
+    aOszCtrl.Entry( this );
+
+    //Wenn der Point innerhalb des Fly sitzt wollen wir energisch
+    //versuchen den Crsr hineinzusetzen.
+    //Wenn der Point allerdings in einem Flys sitzt, der sich vollstaendig
+    //innerhalb des aktuellen befindet, so wird fuer diesen das
+    //GetCrsrOfst gerufen.
+    Calc();
+    BOOL bInside = Frm().IsInside( rPoint ) && Lower(),
+         bRet = FALSE;
+
+    //Wenn der Frm eine Grafik enthaelt, aber nur Text gewuenscht ist, so
+    //nimmt er den Crsr grundsaetzlich nicht an.
+    if ( bInside && pCMS && pCMS->eState == MV_SETONLYTEXT &&
+         (!Lower() || Lower()->IsNoTxtFrm()) )
+        bInside = FALSE;
+
+    const SwPageFrm *pPage = FindPageFrm();
+    if ( bInside && pPage && pPage->GetSortedObjs() )
+    {
+        SwOrderIter aIter( pPage );
+        aIter.Top();
+        while ( aIter() && !bRet )
+        {
+            SwVirtFlyDrawObj *pObj = (SwVirtFlyDrawObj*)aIter();
+            SwFlyFrm *pFly = pObj ? pObj->GetFlyFrm() : 0;
+            if ( pFly && pFly->Frm().IsInside( rPoint ) &&
+                 Frm().IsInside( pFly->Frm() ) )
+            {
+                if ( aOszCtrl.ChkOsz( pFly ) ||
+                     TRUE == (bRet = pFly->GetCrsrOfst( pPos, rPoint, pCMS )))
+                    break;
+                if ( pCMS && pCMS->bStop )
+                    return FALSE;
+            }
+            aIter.Next();
+        }
+    }
+
+    while ( bInside && !bRet )
+    {
+        const SwFrm *pFrm = Lower();
+        while ( pFrm && !bRet )
+        {
+            pFrm->Calc();
+            if ( pFrm->Frm().IsInside( rPoint ) )
+            {
+                bRet = pFrm->GetCrsrOfst( pPos, rPoint, pCMS );
+                if ( pCMS && pCMS->bStop )
+                    return FALSE;
+            }
+            pFrm = pFrm->GetNext();
+        }
+        if ( !bRet )
+        {
+            Point *pPoint = pCMS && pCMS->pFill ? new Point( rPoint ) : NULL;
+            const SwCntntFrm *pCnt = GetCntntPos(
+                                            rPoint, TRUE, FALSE, FALSE, pCMS );
+            if ( pCMS && pCMS->bStop )
+                return FALSE;
+            if( pPoint && pCnt->IsTxtFrm() )
+            {
+                pCnt->GetCrsrOfst( pPos, *pPoint, pCMS );
+                rPoint = *pPoint;
+            }
+            else
+                pCnt->GetCrsrOfst( pPos, rPoint, pCMS );
+            delete pPoint;
+            bRet = TRUE;
+        }
+    }
+    aOszCtrl.Exit( this );
+    return bRet;
+}
+
+/*************************************************************************
+|*
+|*    Beschreibung      Layoutabhaengiges Cursortravelling
+|*    Ersterstellung    MA 23. Jul. 92
+|*    Letzte Aenderung  MA 06. Sep. 93
+|*
+|*************************************************************************/
+BOOL SwCntntFrm::LeftMargin(SwPaM *pPam) const
+{
+    if( pPam->GetNode() != (SwCntntNode*)GetNode() )
+        return FALSE;
+    ((SwCntntNode*)GetNode())->
+        MakeStartIndex((SwIndex *) &pPam->GetPoint()->nContent);
+    return TRUE;
+}
+
+BOOL SwCntntFrm::RightMargin(SwPaM *pPam, BOOL) const
+{
+    if( pPam->GetNode() != (SwCntntNode*)GetNode() )
+        return FALSE;
+    ((SwCntntNode*)GetNode())->
+        MakeEndIndex((SwIndex *) &pPam->GetPoint()->nContent);
+    return TRUE;
+}
+
+const SwCntntFrm *lcl_GetNxtCnt( const SwCntntFrm* pCnt )
+{
+    return pCnt->GetNextCntntFrm();
+}
+
+const SwCntntFrm *lcl_GetPrvCnt( const SwCntntFrm* pCnt )
+{
+    return pCnt->GetPrevCntntFrm();
+}
+
+typedef const SwCntntFrm *(*GetNxtPrvCnt)( const SwCntntFrm* );
+
+//Frame in wiederholter Headline?
+FASTBOOL lcl_IsInRepeatedHeadline( const SwFrm *pFrm )
+{
+    const SwTabFrm *pTab;
+    return 0 != (pTab = pFrm->FindTabFrm()) &&
+           pTab->IsFollow() &&
+           pTab->GetTable()->IsHeadlineRepeat() &&
+           ((SwLayoutFrm*)pTab->Lower())->IsAnLower( pFrm );
+}
+
+
+//Ueberspringen geschuetzter Tabellenzellen. Optional auch
+//Ueberspringen von wiederholten Headlines.
+//MA 26. Jan. 98: Chg auch andere Geschuetzte Bereiche ueberspringen.
+const SwCntntFrm * MA_FASTCALL lcl_MissProtectedFrames( const SwCntntFrm *pCnt,
+                                                       GetNxtPrvCnt fnNxtPrv,
+                                                       FASTBOOL bMissHeadline,
+                                                       FASTBOOL bInReadOnly )
+{
+    if ( pCnt && pCnt->IsInTab() )
+    {
+        BOOL bProtect = TRUE;
+        while ( pCnt && bProtect )
+        {
+            const SwLayoutFrm *pCell = pCnt->GetUpper();
+            while ( pCell && !pCell->IsCellFrm() )
+                pCell = pCell->GetUpper();
+            if ( !pCell ||
+                    ((bInReadOnly || !pCell->GetFmt()->GetProtect().IsCntntProtected()) &&
+                     (!bMissHeadline || !lcl_IsInRepeatedHeadline( pCell ) )))
+                bProtect = FALSE;
+            else
+                pCnt = (*fnNxtPrv)( pCnt );
+        }
+    }
+    else if ( !bInReadOnly )
+        while ( pCnt && pCnt->IsProtected() )
+            pCnt = (*fnNxtPrv)( pCnt );
+
+    return pCnt;
+}
+
+BOOL MA_FASTCALL lcl_UpDown( SwPaM *pPam, const SwCntntFrm *pStart,
+                    GetNxtPrvCnt fnNxtPrv, BOOL bInReadOnly )
+{
+    ASSERT( pPam->GetNode() == (SwCntntNode*)pStart->GetNode(),
+            "lcl_UpDown arbeitet nicht fuer andere." );
+
+    const SwCntntFrm *pCnt = 0;
+
+    //Wenn gerade eine Tabellenselection laeuft muss ein bischen getricktst
+    //werden: Beim hochlaufen an den Anfang der Zelle gehen, beim runterlaufen
+    //an das Ende der Zelle gehen.
+    if ( pStart->IsInTab() &&
+        pPam->GetNode( TRUE )->StartOfSectionNode() !=
+        pPam->GetNode( FALSE )->StartOfSectionNode() )
+    {
+        const SwLayoutFrm  *pCell = pStart->GetUpper();
+        while ( !pCell->IsCellFrm() )
+            pCell = pCell->GetUpper();
+        const SwCntntFrm *pNxt = pCnt = pStart;
+        while ( pCell->IsAnLower( pNxt ) )
+        {   pCnt = pNxt;
+            pNxt = (*fnNxtPrv)( pNxt );
+        }
+    }
+
+    pCnt = (*fnNxtPrv)( pCnt ? pCnt : pStart );
+    pCnt = ::lcl_MissProtectedFrames( pCnt, fnNxtPrv, TRUE, bInReadOnly );
+
+
+    const SwTabFrm *pStTab = pStart->FindTabFrm();
+    const SwTabFrm *pTable;
+    const BOOL bTab = pStTab || (pCnt && pCnt->IsInTab()) ? TRUE : FALSE;
+    BOOL bEnd = bTab ? FALSE : TRUE;
+
+    SwTwips nX;
+    if ( bTab )
+    {
+        SwRect aRect( pStart->Frm() );
+        pStart->GetCharRect( aRect, *pPam->GetPoint() );
+        nX = aRect.Center().X();
+
+        const SwTabFrm *pTab = pCnt ? pCnt->FindTabFrm() : 0;
+        if ( !pTab )
+            pTab = pStTab;
+        pTable = pTab;
+        if ( pStTab )
+        {
+            //Der Fluss fuehrt von einer Tabelle in die nachste. Der X-Wert
+            //muss ausgehend von der Mitte der Startzelle um die Verschiebung
+            //der Tabellen korrigiert werden.
+            const SwFrm *pCell = pStart->GetUpper();
+            while ( pCell && !pCell->IsCellFrm() )
+                pCell = pCell->GetUpper();
+            ASSERT( pCell, "Zelle nicht gefunden." );
+            nX = pCell->Frm().Left() + pCell->Frm().Width() / 2;
+            nX += pTab->Frm().Left() - pStTab->Frm().Left();
+        }
+
+        const SwCntntFrm *pTmp = pTab->ContainsCntnt();
+        if ( nX < (pTmp->Frm().Left() + pTmp->Prt().Left()) )
+            nX = pTmp->Frm().Left() + pTmp->Prt().Left();
+        else
+        {
+            pTmp = pTab->FindLastCntnt();
+            if ( nX > (pTmp->Frm().Left() + pTmp->Prt().Right()) )
+                nX = pTmp->Frm().Left() + pTmp->Prt().Right();
+        }
+    }
+    do
+    {
+        //Wenn ich im DokumentBody bin, so will ich da auch bleiben
+        if ( pStart->IsInDocBody() )
+            while ( pCnt && (!pCnt->IsInDocBody() ||
+                             (pCnt->IsTxtFrm() && ((SwTxtFrm*)pCnt)->IsHiddenNow())))
+            {
+                pCnt = (*fnNxtPrv)( pCnt );
+                pCnt = ::lcl_MissProtectedFrames( pCnt, fnNxtPrv, TRUE, bInReadOnly );
+            }
+
+        //Wenn ich im Fussnotenbereich bin, so versuche ich notfalls den naechsten
+        //Fussnotenbereich zu erreichen.
+        else if ( pStart->IsInFtn() )
+            while ( pCnt && !pCnt->IsInFtn() )
+            {
+                pCnt = (*fnNxtPrv)( pCnt );
+                pCnt = ::lcl_MissProtectedFrames( pCnt, fnNxtPrv, TRUE, bInReadOnly );
+            }
+
+        //In Flys kann es Blind weitergehen solange ein Cntnt
+        //gefunden wird.
+        else if ( pStart->IsInFly() )
+        {
+            if ( pCnt && pCnt->IsTxtFrm() && ((SwTxtFrm*)pCnt)->IsHiddenNow() )
+            {
+                pCnt = (*fnNxtPrv)( pCnt );
+                pCnt = ::lcl_MissProtectedFrames( pCnt, fnNxtPrv, TRUE, bInReadOnly );
+            }
+        }
+
+        //Andernfalls weigere ich mich einfach den derzeitigen Bereich zu
+        //verlassen.
+        else if ( pCnt )
+        {
+            const SwFrm *pUp = pStart->GetUpper();               //Head/Foot
+            while ( pUp && pUp->GetUpper() && !(pUp->GetType() & 0x0018 ) )
+                pUp = pUp->GetUpper();
+            BOOL bSame = FALSE;
+            const SwFrm *pCntUp = pCnt->GetUpper();
+            while ( pCntUp && !bSame )
+            {   if ( pUp == pCntUp )
+                    bSame = TRUE;
+                else
+                    pCntUp = pCntUp->GetUpper();
+            }
+            if ( !bSame )
+                pCnt = 0;
+        }
+
+        if ( bTab )
+        {
+            if ( !pCnt )
+                bEnd = TRUE;
+            else
+            {   const SwTabFrm *pTab = pCnt->FindTabFrm();
+                if( !pTab )
+                    bEnd = TRUE;
+                else
+                {
+                    if ( pTab != pTable )
+                    {   //Der Fluss fuehrt von einer Tabelle in die nachste. Der
+                        //X-Wert muss um die Verschiebung der Tabellen korrigiert
+                        //werden.
+                        if ( pTable )
+                            nX += pTab->Frm().Left() - pTable->Frm().Left();
+                        pTable = pTab;
+                    }
+                    const SwLayoutFrm *pCell = pTab ? pCnt->GetUpper() : 0;
+                    while ( pCell && !pCell->IsCellFrm() )
+                        pCell = pCell->GetUpper();
+                    if ( pCell &&
+                         pCell->Frm().IsInside( Point( nX, pCell->Frm().Top())) )
+                    {
+                        bEnd = TRUE;
+                        //Jetzt noch schnell den richtigen Cntnt in der Zelle
+                        //greifen.
+                        if ( !pCnt->Frm().IsInside( Point( nX, pCnt->Frm().Top())))
+                        {
+                            pCnt = pCell->ContainsCntnt();
+                            if ( fnNxtPrv == lcl_GetPrvCnt )
+                                while ( pCell->IsAnLower(pCnt->GetNextCntntFrm()) )
+                                    pCnt = pCnt->GetNextCntntFrm();
+                        }
+                    }
+                    else if ( pCnt->Frm().IsInside( Point( nX, pCnt->Frm().Top())))
+                        bEnd = TRUE;
+                }
+            }
+            if ( !bEnd )
+            {
+                pCnt = (*fnNxtPrv)( pCnt );
+                pCnt = ::lcl_MissProtectedFrames( pCnt, fnNxtPrv, TRUE, bInReadOnly );
+            }
+        }
+
+    } while ( !bEnd ||
+              (pCnt && pCnt->IsTxtFrm() && ((SwTxtFrm*)pCnt)->IsHiddenNow()));
+
+    if( pCnt )
+    {   // setze den Point auf den Content-Node
+        SwCntntNode *pCNd = (SwCntntNode*)pCnt->GetNode();
+        pPam->GetPoint()->nNode = *pCNd;
+        if ( fnNxtPrv == lcl_GetPrvCnt )
+            pCNd->MakeEndIndex( (SwIndex*)&pPam->GetPoint()->nContent );
+        else
+            pCNd->MakeStartIndex( (SwIndex*)&pPam->GetPoint()->nContent );
+        return TRUE;
+    }
+    return FALSE;
+}
+
+BOOL SwCntntFrm::UnitUp( SwPaM* pPam, const SwTwips, BOOL bInReadOnly ) const
+{
+    return ::lcl_UpDown( pPam, this, lcl_GetPrvCnt, bInReadOnly );
+}
+
+BOOL SwCntntFrm::UnitDown( SwPaM* pPam, const SwTwips, BOOL bInReadOnly ) const
+{
+    return ::lcl_UpDown( pPam, this, lcl_GetNxtCnt, bInReadOnly );
+}
+
+/*************************************************************************
+|*
+|*  SwRootFrm::GetCurrPage()
+|*
+|*  Beschreibung:       Liefert die Nummer der aktuellen Seite.
+|*          Wenn die Methode einen PaM bekommt, so ist die aktuelle Seite
+|*          diejenige in der der PaM sitzt. Anderfalls ist die aktuelle
+|*          Seite die erste Seite innerhalb der VisibleArea.
+|*          Es wird nur auf den vorhandenen Seiten gearbeitet!
+|*  Ersterstellung      MA 20. May. 92
+|*  Letzte Aenderung    MA 09. Oct. 97
+|*
+|*************************************************************************/
+USHORT SwRootFrm::GetCurrPage( const SwPaM *pActualCrsr ) const
+{
+    ASSERT( pActualCrsr, "Welche Seite soll's denn sein?" );
+    const SwFrm *pActFrm = GetFmt()->GetDoc()->GetNodes()[pActualCrsr->GetPoint()->nNode]->
+                                    GetCntntNode()->GetFrm( 0,
+                                                    pActualCrsr->GetPoint(),
+                                                    FALSE );
+    return pActFrm->FindPageFrm()->GetPhyPageNum();
+}
+
+/*************************************************************************
+|*
+|*  SwRootFrm::SetCurrPage()
+|*
+|*  Beschreibung:       Liefert einen PaM der am Anfang der gewuenschten
+|*          Seite sitzt.
+|*          Formatiert wird soweit notwendig
+|*          Liefert Null, wenn die Operation nicht moeglich ist.
+|*          Der PaM sitzt in der letzten Seite, wenn die Seitenzahl zu gross
+|*          gewaehlt wurde.
+|*  Ersterstellung      MA 20. May. 92
+|*  Letzte Aenderung    MA 09. Oct. 97
+|*
+|*************************************************************************/
+USHORT SwRootFrm::SetCurrPage( SwCursor* pToSet, USHORT nPageNum )
+{
+    ASSERT( Lower() && Lower()->IsPageFrm(), "Keine Seite vorhanden." );
+
+    SwPageFrm *pPage = (SwPageFrm*)Lower();
+    BOOL bEnd =FALSE;
+    while ( !bEnd && pPage->GetPhyPageNum() != nPageNum )
+    {   if ( pPage->GetNext() )
+            pPage = (SwPageFrm*)pPage->GetNext();
+        else
+        {   //Ersten CntntFrm Suchen, und solange Formatieren bis
+            //eine neue Seite angefangen wird oder bis die CntntFrm's alle
+            //sind.
+            const SwCntntFrm *pCntnt = pPage->ContainsCntnt();
+            while ( pCntnt && pPage->IsAnLower( pCntnt ) )
+            {   pCntnt->Calc();
+                pCntnt = pCntnt->GetNextCntntFrm();
+            }
+            //Jetzt ist entweder eine neue Seite da, oder die letzte Seite
+            //ist gefunden.
+            if ( pPage->GetNext() )
+                pPage = (SwPageFrm*)pPage->GetNext();
+            else
+                bEnd = TRUE;
+        }
+    }
+    //pPage zeigt jetzt auf die 'gewuenschte' Seite. Jetzt muss noch der
+    //PaM auf den Anfang des ersten CntntFrm im Body-Text erzeugt werden.
+    //Wenn es sich um eine Fussnotenseite handelt, wird der PaM in die erste
+    //Fussnote gesetzt.
+    const SwCntntFrm *pCntnt = pPage->ContainsCntnt();
+    if ( pPage->IsFtnPage() )
+        while ( pCntnt && !pCntnt->IsInFtn() )
+            pCntnt = pCntnt->GetNextCntntFrm();
+    else
+        while ( pCntnt && !pCntnt->IsInDocBody() )
+            pCntnt = pCntnt->GetNextCntntFrm();
+    if ( pCntnt )
+    {
+        SwCntntNode* pCNd = (SwCntntNode*)pCntnt->GetNode();
+        pToSet->GetPoint()->nNode = *pCNd;
+        pCNd->MakeStartIndex( (SwIndex*)&pToSet->GetPoint()->nContent );
+        pToSet->GetPoint()->nContent = ((SwTxtFrm*)pCntnt)->GetOfst();
+
+        SwShellCrsr* pSCrsr = (SwShellCrsr*)*pToSet;
+        if( pSCrsr )
+        {
+            Point &rPt = pSCrsr->GetPtPos();
+            rPt = pCntnt->Frm().Pos();
+            rPt += pCntnt->Prt().Pos();
+        }
+        return pPage->GetPhyPageNum();
+    }
+    return 0;
+}
+
+/*************************************************************************
+|*
+|*    SwCntntFrm::StartxxPage(), EndxxPage()
+|*
+|*    Beschreibung      Cursor an Anfang/Ende der aktuellen/vorherigen/
+|*      naechsten Seite. Alle sechs Methoden rufen GetFrmInPage() mit der
+|*      entsprechenden Parametrisierung.
+|*      Zwei Parameter steuern die Richtung: einer bestimmt die Seite, der
+|*      andere Anfang/Ende.
+|*      Fuer die Bestimmung der Seite und des Cntnt (Anfang/Ende) werden
+|*      die im folgenden definierten Funktionen benutzt.
+|*    Ersterstellung    MA 15. Oct. 92
+|*    Letzte Aenderung  MA 28. Feb. 93
+|*
+|*************************************************************************/
+SwCntntFrm *GetFirstSub( const SwLayoutFrm *pLayout )
+{
+    return ((SwPageFrm*)pLayout)->FindFirstBodyCntnt();
+}
+
+SwCntntFrm *GetLastSub( const SwLayoutFrm *pLayout )
+{
+    return ((SwPageFrm*)pLayout)->FindLastBodyCntnt();
+}
+
+SwLayoutFrm *GetNextFrm( const SwLayoutFrm *pFrm )
+{
+    return (pFrm->GetNext() && pFrm->GetNext()->IsLayoutFrm()) ?
+                                            (SwLayoutFrm*)pFrm->GetNext() : 0;
+}
+
+SwLayoutFrm *GetThisFrm( const SwLayoutFrm *pFrm )
+{
+    return (SwLayoutFrm*)pFrm;
+}
+
+SwLayoutFrm *GetPrevFrm( const SwLayoutFrm *pFrm )
+{
+    return (pFrm->GetPrev() && pFrm->GetPrev()->IsLayoutFrm()) ?
+                                            (SwLayoutFrm*)pFrm->GetPrev() : 0;
+}
+
+//Jetzt koennen auch die Funktionspointer initalisiert werden;
+//sie sind in cshtyp.hxx declariert.
+SwPosPage fnPageStart = GetFirstSub;
+SwPosPage fnPageEnd = GetLastSub;
+SwWhichPage fnPagePrev = GetPrevFrm;
+SwWhichPage fnPageCurr = GetThisFrm;
+SwWhichPage fnPageNext = GetNextFrm;
+
+//Liefert den ersten/den letzten Contentframe (gesteuert ueber
+//den Parameter fnPosPage) in der
+//aktuellen/vorhergehenden/folgenden Seite (gesteuert durch den
+//Parameter fnWhichPage).
+BOOL GetFrmInPage( const SwCntntFrm *pCnt, SwWhichPage fnWhichPage,
+                   SwPosPage fnPosPage, SwPaM *pPam )
+{
+    //Erstmal die gewuenschte Seite besorgen, anfangs die aktuelle, dann
+    //die die per fnWichPage gewuenscht wurde
+    const SwLayoutFrm *pLayoutFrm = pCnt->FindPageFrm();
+    if ( !pLayoutFrm || (0 == (pLayoutFrm = (*fnWhichPage)(pLayoutFrm))) )
+        return FALSE;
+
+    //Jetzt den gewuenschen CntntFrm unterhalb der Seite
+    if( 0 == (pCnt = (*fnPosPage)(pLayoutFrm)) )
+        return FALSE;
+    else
+    {
+        SwCntntNode *pCNd = (SwCntntNode*)pCnt->GetNode();
+        pPam->GetPoint()->nNode = *pCNd;
+        xub_StrLen nIdx;
+        if( fnPosPage == GetFirstSub )
+            nIdx = ((SwTxtFrm*)pCnt)->GetOfst();
+        else
+            nIdx = pCnt->GetFollow() ?
+                    ((SwTxtFrm*)pCnt)->GetFollow()->GetOfst()-1 : pCNd->Len();
+        pPam->GetPoint()->nContent.Assign( pCNd, nIdx );
+        return TRUE;
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwLayoutFrm::GetCntntPos()
+|*
+|*  Beschreibung        Es wird der nachstliegende Cntnt zum uebergebenen
+|*                      gesucht. Betrachtet werden die vorhergehende, die
+|*                      aktuelle und die folgende Seite.
+|*                      Wenn kein Inhalt gefunden wird, so wird der Bereich
+ *                      erweitert bis einer gefunden wird.
+|*                      Zurueckgegeben wird die 'Semantisch richtige' Position
+|*                      innerhalb der PrtArea des gefundenen CntntFrm
+|*  Ersterstellung      MA 15. Jul. 92
+|*  Letzte Aenderung    MA 09. Jan. 97
+|*
+|*************************************************************************/
+ULONG CalcDiff( const Point &rPt1, const Point &rPt2 )
+{
+    //Jetzt die Entfernung zwischen den beiden Punkten berechnen.
+    //'Delta' X^2 + 'Delta'Y^2 = 'Entfernung'^2
+    ULONG dX = Max( rPt1.X(), rPt2.X() ) -
+               Min( rPt1.X(), rPt2.X() ),
+          dY = Max( rPt1.Y(), rPt2.Y() ) -
+               Min( rPt1.Y(), rPt2.Y() );
+    BigInt dX1( dX ), dY1( dY );
+    dX1 *= dX1; dY1 *= dY1;
+    return ::SqRt( dX1 + dY1 );
+}
+
+// lcl_Inside ueberprueft, ob der Punkt innerhalb des Seitenteils liegt, in dem
+// auch der CntntFrame liegt. Als Seitenteile gelten in diesem Zusammenhang
+// Kopfzeile, Seitenbody, Fusszeile und FussnotenContainer.
+// Dies dient dazu, dass ein CntntFrm, der im "richtigen" Seitenteil liegt,
+// eher akzeptiert wird als ein anderer, der nicht dort liegt, auch wenn
+// dessen Abstand zum Punkt geringer ist.
+
+const SwLayoutFrm* lcl_Inside( const SwCntntFrm *pCnt, Point& rPt )
+{
+    const SwLayoutFrm* pUp = pCnt->GetUpper();
+    while( pUp )
+    {
+        if( pUp->IsPageBodyFrm() || pUp->IsFooterFrm() || pUp->IsHeaderFrm() )
+        {
+            if( rPt.Y() >= pUp->Frm().Top() && rPt.Y() <= pUp->Frm().Bottom() )
+                return pUp;
+            return NULL;
+        }
+        if( pUp->IsFtnContFrm() )
+            return pUp->Frm().IsInside( rPt ) ? pUp : NULL;
+        pUp = pUp->GetUpper();
+    }
+    return NULL;
+}
+
+//Fuer MSC keine Optimierung mit e (enable register...) hier, sonst gibts
+//einen Bug (ID: 2857)
+#pragma optimize("e",off)
+
+const SwCntntFrm *SwLayoutFrm::GetCntntPos( Point& rPoint,
+                                            const BOOL bDontLeave,
+                                            const BOOL bBodyOnly,
+                                            const BOOL bCalc,
+                                            const SwCrsrMoveState *pCMS,
+                                            const BOOL bDefaultExpand ) const
+{
+    //Ersten CntntFrm ermitteln.
+    const SwLayoutFrm *pStart = (!bDontLeave && bDefaultExpand && GetPrev()) ?
+                                    (SwLayoutFrm*)GetPrev() : this;
+    const SwCntntFrm *pCntnt = pStart->ContainsCntnt();
+
+    if ( !pCntnt && (GetPrev() && !bDontLeave) )
+        pCntnt = ContainsCntnt();
+
+    if ( bBodyOnly && pCntnt && !pCntnt->IsInDocBody() )
+        while ( pCntnt && !pCntnt->IsInDocBody() )
+            pCntnt = pCntnt->GetNextCntntFrm();
+
+    const SwCntntFrm *pActual= pCntnt;
+    const SwLayoutFrm *pInside = NULL;
+    USHORT nMaxPage = GetPhyPageNum() + (bDefaultExpand ? 1 : 0);
+    Point aPoint = rPoint;
+    ULONG nDistance = ULONG_MAX;
+
+    while ( TRUE )  //Sicherheitsschleifchen, damit immer einer gefunden wird.
+    {
+        while ( pCntnt &&
+                ((!bDontLeave || IsAnLower( pCntnt )) &&
+                (pCntnt->GetPhyPageNum() <= nMaxPage)) )
+        {
+            if ( ( bCalc || pCntnt->Frm().Width() ) &&
+                 ( !bBodyOnly || pCntnt->IsInDocBody() ) )
+            {
+                //Wenn der Cntnt in einem geschuetzen Bereich (Zelle, Ftn, Section)
+                //liegt, wird der nachste Cntnt der nicht geschuetzt ist gesucht.
+                const SwCntntFrm *pComp = pCntnt;
+                pCntnt = ::lcl_MissProtectedFrames( pCntnt, lcl_GetNxtCnt, FALSE,
+                                        pCMS ? pCMS->bSetInReadOnly : FALSE );
+                if ( pComp != pCntnt )
+                    continue;
+
+                if ( !pCntnt->IsTxtFrm() || !((SwTxtFrm*)pCntnt)->IsHiddenNow() )
+                {
+                    if ( bCalc )
+                        pCntnt->Calc();
+
+                    SwRect aCntFrm( pCntnt->UnionFrm() );
+                    if ( aCntFrm.IsInside( rPoint ) )
+                    {
+                        pActual = pCntnt;
+                        aPoint = rPoint;
+                        break;
+                    }
+                    //Die Strecke von rPoint zum dichtesten Punkt von pCntnt wird
+                    //jetzt berechnet.
+                    Point aCntntPoint( rPoint );
+
+                    //Erst die Vertikale Position einstellen
+                    if ( aCntFrm.Top() > aCntntPoint.Y() )
+                        aCntntPoint.Y() = aCntFrm.Top();
+                    else if ( aCntFrm.Bottom() < aCntntPoint.Y() )
+                        aCntntPoint.Y() = aCntFrm.Bottom();
+
+                    //Jetzt die Horizontale Position
+                    if ( aCntFrm.Left() > aCntntPoint.X() )
+                        aCntntPoint.X() = aCntFrm.Left();
+                    else if ( aCntFrm.Right() < aCntntPoint.X() )
+                        aCntntPoint.X() = aCntFrm.Right();
+
+                    // pInside ist ein Seitenbereich, in dem der Punkt liegt,
+                    // sobald pInside!=0 ist, werden nur noch Frames akzeptiert,
+                    // die innerhalb liegen.
+                    if( !pInside || ( pInside->IsAnLower( pCntnt ) &&
+                        ( !pCntnt->IsInFtn() || pInside->IsFtnContFrm() ) ) )
+                    {
+                        const ULONG nDiff = ::CalcDiff( aCntntPoint, rPoint );
+                        BOOL bBetter = nDiff < nDistance;  // Dichter dran
+                        if( !pInside )
+                        {
+                            pInside = lcl_Inside( pCntnt, rPoint );
+                            if( pInside )  // Im "richtigen" Seitenteil
+                                bBetter = TRUE;
+                        }
+                        if( bBetter )
+                        {
+                            aPoint = aCntntPoint;
+                            nDistance = nDiff;
+                            pActual = pCntnt;
+                        }
+                    }
+                }
+            }
+            pCntnt = pCntnt->GetNextCntntFrm();
+            if ( bBodyOnly )
+                while ( pCntnt && !pCntnt->IsInDocBody() )
+                    pCntnt = pCntnt->GetNextCntntFrm();
+        }
+        if ( !pActual )
+        {   //Wenn noch keiner gefunden wurde muss der Suchbereich erweitert
+            //werden, irgenwann muessen wir einen Finden!
+            //MA 09. Jan. 97: Opt fuer viele leere Seiten, wenn wir nur im
+            //Body suchen, koennen wir den Suchbereich gleich in einem
+            //Schritt hinreichend erweitern.
+            if ( bBodyOnly )
+            {
+                while ( !pCntnt && pStart->GetPrev() )
+                {
+                    ++nMaxPage;
+                    if( !pStart->GetPrev()->IsLayoutFrm() )
+                        return 0;
+                    pStart = (SwLayoutFrm*)pStart->GetPrev();
+                    pCntnt = pStart->IsInDocBody()
+                                ? pStart->ContainsCntnt()
+                                : pStart->FindPageFrm()->FindFirstBodyCntnt();
+                }
+                if ( !pCntnt )  //irgendwann muessen wir mit irgendeinem Anfangen!
+                {
+                    pCntnt = pStart->FindPageFrm()->GetUpper()->ContainsCntnt();
+                    while ( pCntnt && !pCntnt->IsInDocBody() )
+                        pCntnt = pCntnt->GetNextCntntFrm();
+                    if ( !pCntnt )
+                        return 0;   //Es gibt noch keine Dokumentinhalt!
+                }
+            }
+            else
+            {
+                ++nMaxPage;
+                if ( pStart->GetPrev() )
+                {
+                    if( !pStart->GetPrev()->IsLayoutFrm() )
+                        return 0;
+                    pStart = (SwLayoutFrm*)pStart->GetPrev();
+                    pCntnt = pStart->ContainsCntnt();
+                }
+                else //irgendwann muessen wir mit irgendeinem Anfangen!
+                    pCntnt = pStart->FindPageFrm()->GetUpper()->ContainsCntnt();
+            }
+            pActual = pCntnt;
+        }
+        else
+            break;
+    }
+
+#ifndef PRODUCT
+    ASSERT( pActual, "Keinen Cntnt gefunden." );
+    if ( bBodyOnly )
+        ASSERT( pActual->IsInDocBody(), "Cnt nicht im Body." );
+#endif
+
+    //Spezialfall fuer das selektieren von Tabellen, nicht in wiederholte
+    //TblHedlines.
+    if ( pActual->IsInTab() && pCMS && pCMS->eState == MV_TBLSEL )
+    {
+        const SwTabFrm *pTab = pActual->FindTabFrm();
+        if ( pTab->IsFollow() && pTab->GetTable()->IsHeadlineRepeat() &&
+             ((SwLayoutFrm*)pTab->Lower())->IsAnLower( pActual ) )
+        {
+            ((SwCrsrMoveState*)pCMS)->bStop = TRUE;
+            return 0;
+        }
+    }
+
+    //Jetzt noch eine kleine Korrektur beim ersten/letzten
+    Size aActualSize( pActual->Prt().SSize() );
+    if ( aActualSize.Height() > pActual->GetUpper()->Prt().Height() )
+        aActualSize.Height() = pActual->GetUpper()->Prt().Height();
+    if ( !pActual->GetPrev() &&
+        ((pActual->Frm().Top() + pActual->Prt().Top()) > rPoint.Y()) )
+        aPoint = pActual->Frm().Pos() + pActual->Prt().Pos();
+    else if ( !pActual->GetNext() &&
+            ((pActual->Frm().Top() + pActual->Prt().Bottom()) < rPoint.Y()) )
+    {   aPoint.Y() = pActual->Frm().Top() + pActual->Prt().Bottom();
+        aPoint.X() = pActual->Frm().Left() + pActual->Prt().Right();
+    }
+    //Und den Point in die PrtArea bringen
+    if ( bCalc )
+        pActual->Calc();
+    const SwRect aRect( pActual->Frm().Pos() + pActual->Prt().Pos(),
+                        aActualSize );
+    if ( aPoint.Y() < aRect.Top() )
+        aPoint.Y() = aRect.Top();
+    else if ( aPoint.Y() > aRect.Bottom() )
+        aPoint.Y() = aRect.Bottom();
+    if ( aPoint.X() < aRect.Left() )
+        aPoint.X() = aRect.Left();
+    else if ( aPoint.X() > aRect.Right() )
+        aPoint.X() = aRect.Right();
+    rPoint = aPoint;
+    return pActual;
+}
+
+#pragma optimize("",on)
+
+/*************************************************************************
+|*
+|*  SwPageFrm::GetCntntPosition()
+|*
+|*  Beschreibung        Analog zu SwLayoutFrm::GetCntntPos().
+|*                      Spezialisiert fuer Felder in Rahmen.
+|*
+|*  Ersterstellung      MA 22. Mar. 95
+|*  Letzte Aenderung    MA 07. Nov. 95
+|*
+|*************************************************************************/
+void SwPageFrm::GetCntntPosition( const Point &rPt, SwPosition &rPos ) const
+{
+    //Ersten CntntFrm ermitteln.
+    const SwCntntFrm *pCntnt = ContainsCntnt();
+    if ( pCntnt )
+    {
+        //Einen weiter zurueck schauen (falls moeglich).
+        const SwCntntFrm *pTmp = pCntnt->GetPrevCntntFrm();
+        while ( pTmp && !pTmp->IsInDocBody() )
+            pTmp = pTmp->GetPrevCntntFrm();
+        if ( pTmp )
+            pCntnt = pTmp;
+    }
+    else
+        pCntnt = GetUpper()->ContainsCntnt();
+
+    const SwCntntFrm *pAct = pCntnt;
+    Point aAct       = rPt;
+    ULONG nDist      = ULONG_MAX;
+
+    while ( pCntnt )
+    {
+        SwRect aCntFrm( pCntnt->UnionFrm() );
+        if ( aCntFrm.IsInside( rPt ) )
+        {
+            //dichter gehts nimmer.
+            pAct = pCntnt;
+            break;
+        }
+
+        //Die Strecke von rPt zum dichtesten Punkt von pCntnt berechnen.
+        Point aPoint( rPt );
+
+        //Erst die vertikale Position einstellen
+        if ( aCntFrm.Top() > rPt.Y() )
+            aPoint.Y() = aCntFrm.Top();
+        else if ( aCntFrm.Bottom() < rPt.Y() )
+            aPoint.Y() = aCntFrm.Bottom();
+
+        //Jetzt die horizontale Position
+        if ( aCntFrm.Left() > rPt.X() )
+            aPoint.X() = aCntFrm.Left();
+        else if ( aCntFrm.Right() < rPt.X() )
+            aPoint.X() = aCntFrm.Right();
+
+        const ULONG nDiff = ::CalcDiff( aPoint, rPt );
+        if ( nDiff < nDist )
+        {
+            aAct    = aPoint;
+            nDist   = nDiff;
+            pAct    = pCntnt;
+        }
+        else if ( aCntFrm.Top() > Frm().Bottom() )
+            //Dichter wirds im Sinne der Felder nicht mehr!
+            break;
+
+        pCntnt = pCntnt->GetNextCntntFrm();
+        while ( pCntnt && !pCntnt->IsInDocBody() )
+            pCntnt = pCntnt->GetNextCntntFrm();
+    }
+
+    //Und den Point in die PrtArea bringen
+    const SwRect aRect( pAct->Frm().Pos() + pAct->Prt().Pos(), pAct->Prt().SSize() );
+    if ( aAct.Y() < aRect.Top() )
+        aAct.Y() = aRect.Top();
+    else if ( aAct.Y() > aRect.Bottom() )
+        aAct.Y() = aRect.Bottom();
+    if ( aAct.X() < aRect.Left() )
+        aAct.X() = aRect.Left();
+    else if ( aAct.X() > aRect.Right() )
+        aAct.X() = aRect.Right();
+
+    if( !pAct->IsValid() )
+    {
+        // CntntFrm nicht formatiert -> immer auf Node-Anfang
+        SwCntntNode* pCNd = (SwCntntNode*)pAct->GetNode();
+        ASSERT( pCNd, "Wo ist mein CntntNode?" );
+        rPos.nNode = *pCNd;
+        rPos.nContent.Assign( pCNd, 0 );
+    }
+    else
+    {
+        SwCrsrMoveState aTmpState( MV_SETONLYTEXT );
+        pAct->GetCrsrOfst( &rPos, aAct, &aTmpState );
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwRootFrm::GetNextCntntPos()
+|*
+|*  Beschreibung        Es wird der naechstliegende Cntnt zum uebergebenen
+|*                      Point gesucht. Es wird nur im BodyText gesucht.
+|*  Ersterstellung      MA 15. Jul. 92
+|*  Letzte Aenderung    MA 20. Dec. 93
+|*
+|*************************************************************************/
+
+//!!!!! Es wird nur der vertikal naechstliegende gesucht.
+Point SwRootFrm::GetNextCntntPos( const Point& rPoint, BOOL bIgnoreTblHdln ) const
+{
+    //Ersten CntntFrm und seinen Nachfolger im Body-Bereich suchen
+    //Damit wir uns nicht tot suchen (und vor allem nicht zuviel formatieren)
+    //gehen wir schon mal von der richtigen Seite aus.
+    SwLayoutFrm *pPage = (SwLayoutFrm*)Lower();
+    while ( pPage && pPage->Frm().Bottom() < rPoint.Y() )
+        pPage = (SwLayoutFrm*)pPage->GetNext();
+
+    const SwCntntFrm *pCnt = pPage ? pPage->ContainsCntnt() : ContainsCntnt();
+    while ( pCnt && !pCnt->IsInDocBody() )
+        pCnt = pCnt->GetNextCntntFrm();
+
+    if ( !pCnt )
+        return Point( 0, 0 );
+
+    //Liegt der Point ueber dem ersten CntntFrm?
+    pCnt->Calc();
+    if ( rPoint.Y() < pCnt->Frm().Top() && !lcl_IsInRepeatedHeadline( pCnt ) )
+        return  pCnt->Frm().Pos();
+
+    while ( pCnt )
+    {   //Liegt der Point mitten im aktuellen CntntFrm?
+        SwRect aCntFrm( pCnt->UnionFrm() );
+        if ( aCntFrm.IsInside( rPoint ) && !lcl_IsInRepeatedHeadline( pCnt ) )
+            return rPoint;
+
+        const SwCntntFrm *pNxt = pCnt->GetNextCntntFrm();
+        while ( pNxt && !pNxt->IsInDocBody() )
+            pNxt = pNxt->GetNextCntntFrm();
+
+        //Liegt der Point hinter dem letzten CntntFrm?
+        if ( !pNxt )
+            return Point( aCntFrm.Right(), aCntFrm.Bottom() );
+
+        //Wenn der naechste CntntFrm hinter dem Point liegt ist er der
+        //gesuchte.
+        pNxt->Calc();
+        if ( pNxt->Frm().Top() > rPoint.Y() && !lcl_IsInRepeatedHeadline( pCnt ) )
+            return pNxt->Frm().Pos();
+        pCnt = pNxt;
+    }
+    return Point( 0, 0 );
+}
+/*************************************************************************
+|*
+|*  SwRootFrm::GetPrevCntntPos()
+|*
+|*  Beschreibung        Es wird der vorhergehende Cntnt zum uebergebenen
+|*                      Point gesucht. Es wird nur im BodyTextGesucht
+|*  Ersterstellung      MA 13. Jul. 92
+|*  Letzte Aenderung    MA 19. Apr. 94
+|*
+|*************************************************************************/
+//!!!!! Es wird nur der vertikal naechstliegende gesucht.
+Point SwRootFrm::GetPrevCntntPos( const Point& rPoint ) const
+{
+    //Ersten CntntFrm und seinen Nachfolger im Body-Bereich suchen
+    //Damit wir uns nicht tot suchen (und vor allem nicht zuviel formatieren)
+    //gehen wir schon mal von der richtigen Seite aus.
+    SwLayoutFrm *pPage = (SwLayoutFrm*)Lower();
+    while ( pPage && pPage->Frm().Bottom() < rPoint.Y() )
+        pPage = (SwLayoutFrm*)pPage->GetNext();
+
+    const SwCntntFrm *pCnt = pPage ? pPage->ContainsCntnt() : ContainsCntnt();
+    while ( pCnt && !pCnt->IsInDocBody() )
+        pCnt = pCnt->GetNextCntntFrm();
+
+    if ( !pCnt )
+        return Point( 0, 0 );
+
+    //Solange der Point vor dem ersten CntntFrm liegt und es noch vorhergehende
+    //Seiten gibt gehe ich jeweils eine Seite nach vorn.
+    pCnt->Calc();
+    while ( rPoint.Y() < pCnt->Frm().Top() && pPage->GetPrev() )
+    {
+        pPage = (SwLayoutFrm*)pPage->GetPrev();
+        pCnt = pPage->ContainsCntnt();
+        while ( !pCnt )
+        {   pPage = (SwLayoutFrm*)pPage->GetPrev();
+            if ( pPage )
+                pCnt = pPage->ContainsCntnt();
+            else
+                return ContainsCntnt()->UnionFrm().Pos();
+        }
+        pCnt->Calc();
+    }
+    if ( rPoint.Y() < pCnt->Frm().Top() )
+        return pCnt->UnionFrm().Pos();
+
+    while ( pCnt )
+    {   //Liegt der Point im aktuellen CntntFrm?
+        SwRect aCntFrm( pCnt->UnionFrm() );
+        if ( aCntFrm.IsInside( rPoint ) )
+            return rPoint;
+
+        //Ist der aktuelle der letzte CntntFrm? ||
+        //Wenn der naechste CntntFrm hinter dem Point liegt, ist der
+        //aktuelle der gesuchte.
+        const SwCntntFrm *pNxt = pCnt->GetNextCntntFrm();
+        while ( pNxt && !pNxt->IsInDocBody() )
+            pNxt = pNxt->GetNextCntntFrm();
+
+        if ( pNxt )
+            pNxt->Calc();
+
+        if ( !pNxt ||
+             pNxt->Frm().Top() > rPoint.Y() )
+            return Point( aCntFrm.Right(), aCntFrm.Bottom() );
+        pCnt = pNxt;
+    }
+    return Point( 0, 0 );
+}
+
+/*************************************************************************
+|*
+|*  SwRootFrm::GetPagePos()
+|*
+|*  Beschreibung:   Liefert die absolute Dokumentpositon der gewuenschten
+|*          Seite.
+|*          Formatiert wird nur soweit notwendig und nur dann wenn bFormat=TRUE
+|*          Liefert Null, wenn die Operation nicht moeglich ist.
+|*          Die Pos ist die der letzten Seite, wenn die Seitenzahl zu gross
+|*          gewaehlt wurde.
+|*  Ersterstellung      MA 01. Jun. 92
+|*  Letzte Aenderung    MA 09. Oct. 97
+|*
+|*************************************************************************/
+Point SwRootFrm::GetPagePos( USHORT nPageNum ) const
+{
+    ASSERT( Lower() && Lower()->IsPageFrm(), "Keine Seite vorhanden." );
+
+    const SwPageFrm *pPage = (const SwPageFrm*)Lower();
+    while ( TRUE )
+    {
+        if ( pPage->GetPhyPageNum() >= nPageNum || !pPage->GetNext() )
+            break;
+        pPage = (const SwPageFrm*)pPage->GetNext();
+    }
+    return pPage->Frm().Pos();
+}
+
+/*************************************************************************
+|*
+|*    SwFrm::IsProtected()
+|*
+|*    Beschreibung      Ist der Frm bzw. die Section in der er steht
+|*                      geschuetzt?
+|*                      Auch Fly in Fly in ... und Fussnoten
+|*
+|*    Ersterstellung    MA 28. Jul. 93
+|*    Letzte Aenderung  MA 06. Nov. 97
+|*
+|*************************************************************************/
+BOOL SwFrm::IsProtected() const
+{
+    //Der Frm kann in Rahmen, Zellen oder Bereichen geschuetzt sein.
+    //Geht auch FlyFrms rekursiv hoch. Geht auch von Fussnoten zum Anker.
+    const SwFrm *pFrm = this;
+    do
+    {
+        if ( pFrm->IsCntntFrm() )
+        {
+            if ( ((SwCntntFrm*)pFrm)->GetNode()->IsInProtectSect() )
+                return TRUE;
+        }
+        else if ( ((SwLayoutFrm*)pFrm)->GetFmt()->GetProtect().IsCntntProtected() )
+            return TRUE;
+
+        if ( pFrm->IsFlyFrm() )
+        {
+            //Der Schutz des Inhaltes kann bei Verkettung vom Master der Kette
+            //vorgegeben werden.
+            if ( ((SwFlyFrm*)pFrm)->GetPrevLink() )
+            {
+                SwFlyFrm *pMaster = (SwFlyFrm*)pFrm;
+                do
+                {   pMaster = pMaster->GetPrevLink();
+                } while ( pMaster->GetPrevLink() );
+                if ( pMaster->IsProtected() )
+                    return TRUE;
+            }
+            pFrm = ((SwFlyFrm*)pFrm)->GetAnchor();
+        }
+        else if ( pFrm->IsFtnFrm() )
+            pFrm = ((SwFtnFrm*)pFrm)->GetRef();
+        else
+            pFrm = pFrm->GetUpper();
+
+    } while ( pFrm );
+
+    return FALSE;
+}
+
+/*************************************************************************
+|*
+|*    SwFrm::GetPhyPageNum()
+|*    Beschreibung:     Liefert die physikalische Seitennummer
+|*
+|*    Ersterstellung    OK 06.07.93 08:35
+|*    Letzte Aenderung  MA 30. Nov. 94
+|*
+|*************************************************************************/
+USHORT SwFrm::GetPhyPageNum() const
+{
+    const SwPageFrm *pPage = FindPageFrm();
+    return pPage ? pPage->GetPhyPageNum() : 0;
+}
+
+/*************************************************************************
+|*
+|*    SwFrm::GetVirtPageNum()
+|*    Beschreibung:     Liefert die virtuelle Seitennummer mit Offset
+|*
+|*    Ersterstellung    OK 06.07.93 08:35
+|*    Letzte Aenderung  MA 30. Nov. 94
+|*
+|*************************************************************************/
+USHORT SwFrm::GetVirtPageNum() const
+{
+    const SwPageFrm *pPage = FindPageFrm();
+    if ( !pPage || !pPage->GetUpper() )
+        return 0;
+
+    USHORT nPhyPage = pPage->GetPhyPageNum();
+    if ( !((SwRootFrm*)pPage->GetUpper())->IsVirtPageNum() )
+        return nPhyPage;
+
+    //Den am naechsten stehenden Absatz mit virtueller Seitennummer suchen.
+    //Da das rueckwaertsuchen insgesamt sehr viel Zeit verschlingt suchen
+    //wir jetzt gezielt ueber die Abhaengigkeiten.
+    //von den PageDescs bekommen wir die Attribute, von den Attributen
+    //wiederum bekommen wir die Absaetze.
+    const SwPageFrm *pVirtPage = 0;
+    const SwFrm *pFrm = 0;
+    const SfxItemPool &rPool = pPage->GetFmt()->GetDoc()->GetAttrPool();
+    const SfxPoolItem* pItem;
+    USHORT nMaxItems = rPool.GetItemCount( RES_PAGEDESC );
+    for( USHORT n = 0; n < nMaxItems; ++n )
+    {
+        if( 0 == (pItem = rPool.GetItem( RES_PAGEDESC, n ) ))
+            continue;
+
+        const SwFmtPageDesc *pDesc = (SwFmtPageDesc*)pItem;
+        if ( pDesc->GetNumOffset() && pDesc->GetDefinedIn() )
+        {
+            const SwModify *pMod = pDesc->GetDefinedIn();
+            SwVirtPageNumInfo aInfo( pPage );
+            pMod->GetInfo( aInfo );
+            if ( aInfo.GetPage() )
+            {
+                if ( !pVirtPage ||
+                      (pVirtPage &&
+                       aInfo.GetPage()->GetPhyPageNum() > pVirtPage->GetPhyPageNum()))
+                {
+                    pVirtPage = aInfo.GetPage();
+                    pFrm = aInfo.GetFrm();
+                }
+            }
+        }
+    }
+    if ( pVirtPage )
+        return nPhyPage - pFrm->GetPhyPageNum() + pFrm->GetAttrSet()->GetPageDesc().GetNumOffset();
+    return nPhyPage;
+}
+
+/*************************************************************************
+|*
+|*  SwRootFrm::MakeTblCrsrs()
+|*
+|*  Ersterstellung      MA 14. May. 93
+|*  Letzte Aenderung    MA 02. Feb. 94
+|*
+|*************************************************************************/
+//Ermitteln und einstellen derjenigen Zellen die von der Selektion
+//eingeschlossen sind.
+
+void SwRootFrm::MakeTblCrsrs( SwTableCursor& rTblCrsr )
+{
+    //Union-Rects und Tabellen (Follows) der Selektion besorgen.
+    ASSERT( rTblCrsr.GetCntntNode() && rTblCrsr.GetCntntNode( FALSE ),
+            "Tabselection nicht auf Cnt." );
+
+    Point aPtPt, aMkPt;
+    {
+        SwShellCrsr* pShCrsr =  rTblCrsr.operator SwShellCrsr*();
+        // Aufgrund eines CompilerBugs von Linux muss
+        // der Zeigeroperator explizit gerufen werden
+
+        if( pShCrsr )
+        {
+            aPtPt = pShCrsr->GetPtPos();
+            aMkPt = pShCrsr->GetMkPos();
+        }
+    }
+    const SwLayoutFrm *pStart = rTblCrsr.GetCntntNode()->GetFrm(
+                                            &aPtPt, 0, FALSE )->GetUpper(),
+                      *pEnd   = rTblCrsr.GetCntntNode(FALSE)->GetFrm(
+                                            &aMkPt, 0, FALSE )->GetUpper();
+    SwSelUnions aUnions;
+    ::MakeSelUnions( aUnions, pStart, pEnd );
+
+    SwSelBoxes aNew;
+
+    const FASTBOOL bReadOnlyAvailable = rTblCrsr.IsReadOnlyAvailable();
+
+    for ( USHORT i = 0; i < aUnions.Count(); ++i )
+    {
+        SwSelUnion *pUnion = aUnions[i];
+        const SwTabFrm *pTable = pUnion->GetTable();
+
+        SwLayoutFrm *pRow = (SwLayoutFrm*)pTable->Lower();
+        if ( pRow && pTable->IsFollow() &&
+             pTable->GetTable()->IsHeadlineRepeat() )
+            pRow = (SwLayoutFrm*)pRow->GetNext();
+        while ( pRow )
+        {
+            if ( pRow->Frm().IsOver( pUnion->GetUnion() ) )
+            {
+                const SwLayoutFrm *pCell = pRow->FirstCell();
+
+                while ( pCell && pRow->IsAnLower( pCell ) )
+                {
+                    ASSERT( pCell->IsCellFrm(), "Frame ohne Celle" );
+                    if( IsFrmInTblSel( pUnion->GetUnion(), pCell ) &&
+                        (bReadOnlyAvailable ||
+                         !pCell->GetFmt()->GetProtect().IsCntntProtected()) )
+                    {
+                        SwTableBox* pInsBox = (SwTableBox*)((SwCellFrm*)pCell)->GetTabBox();
+                        aNew.Insert( pInsBox );
+                    }
+                    if ( pCell->GetNext() )
+                    {
+                        pCell = (const SwLayoutFrm*)pCell->GetNext();
+                        if ( pCell->Lower()->IsRowFrm() )
+                            pCell = pCell->FirstCell();
+                    }
+                    else
+                    {
+                        const SwLayoutFrm* pLastCell = pCell;
+                        do
+                        {
+                            pCell = pCell->GetNextLayoutLeaf();
+                        } while ( pCell && pLastCell->IsAnLower( pCell ) );
+                        // Fuer (spaltige) Bereiche...
+                        if( pCell && pCell->IsInTab() )
+                        {
+                            while( !pCell->IsCellFrm() )
+                            {
+                                pCell = pCell->GetUpper();
+                                ASSERT( pCell, "Where's my cell?" );
+                            }
+                        }
+                    }
+                }
+            }
+            pRow = (SwLayoutFrm*)pRow->GetNext();
+        }
+    }
+
+    SwSelBoxes& rOld = (SwSelBoxes&)rTblCrsr.GetBoxes();
+    USHORT nOld = 0, nNew = 0;
+    while ( nOld < rOld.Count() && nNew < aNew.Count() )
+    {
+        const SwTableBox* pPOld = *( rOld.GetData() + nOld );
+        const SwTableBox* pPNew = *( aNew.GetData() + nNew );
+        if( pPOld == pPNew )
+        {
+            // diese Box bleibt erhalten
+            ++nOld;
+            aNew.Remove( nNew );
+        }
+        else if( pPOld->GetSttIdx() < pPNew->GetSttIdx() )
+            rTblCrsr.DeleteBox( nOld );
+        else
+        {
+            rTblCrsr.InsertBox( *pPNew );
+            ++nOld;
+            ++nNew;
+        }
+    }
+
+    while( nOld < rOld.Count() )
+        rTblCrsr.DeleteBox( nOld );
+
+    for( ; nNew < aNew.Count(); ++nNew )
+        rTblCrsr.InsertBox( **( aNew.GetData() + nNew ) );
+}
+
+
+/*************************************************************************
+|*
+|*  SwRootFrm::CalcFrmRects
+|*
+|*  Ersterstellung      MA 24. Aug. 92
+|*  Letzte Aenderung    MA 24. Aug. 93
+|*
+|*************************************************************************/
+
+/*
+ * nun koennen folgende Situationen auftreten:
+ *  1. Start und Ende liegen in einer Bildschirm - Zeile und im
+ *     gleichen Node
+ *      -> aus Start und End ein Rectangle, dann Ok
+ *  2. Start und Ende liegen in einem Frame (dadurch im gleichen Node!)
+ *      -> Start nach rechts, End nach links erweitern,
+ *         und bei mehr als 2 Bildschirm - Zeilen, das dazwischen
+ *         liegende berechnen
+ *  3. Start und Ende liegen in verschiedenen Frames
+ *      -> Start nach rechts erweitern, bis Frame-Ende Rect berechnen
+ *         Ende nach links erweitern, bis Frame-Start Rect berechnen
+ *         und bei mehr als 2 Frames von allen dazwischen liegenden
+ *         Frames die PrtArea dazu.
+ *  4. Wenn es sich um eine Tabellenselektion handelt wird fuer jeden
+ *     PaM im Ring der CellFrm besorgt, dessen PrtArea wird zu den
+ *     Rechtecken addiert.
+ *
+ * Grosser Umbau wg. der FlyFrm; denn diese muessen ausgespart werden.
+ * Ausnahmen: - Der Fly in dem die Selektion stattfindet (wenn sie in einem Fly
+ *              stattfindet).
+ *            - Die Flys, die vom Text unterlaufen werden.
+ * Arbeitsweise: Zuerst wird eine SwRegion mit der Root initialisiert.
+ *               Aus der Region werden die zu invertierenden Bereiche
+ *               ausgestantzt. Die Region wird Komprimiert und letztlich
+ *               invertiert. Damit liegen dann die zu invertierenden
+ *               Rechtecke vor.
+ *               Am Ende werden die Flys aus der Region ausgestanzt.
+ */
+
+inline void Sub( SwRegionRects& rRegion, const SwRect& rRect )
+{
+    if( rRect.Width() > 1 && rRect.Height() > 1 &&
+        rRect.IsOver( rRegion.GetOrigin() ))
+        rRegion -= rRect;
+}
+
+void SwRootFrm::CalcFrmRects( SwShellCrsr &rCrsr, BOOL bIsTblMode )
+{
+    ViewShell *pSh = GetShell();
+    SwRegionRects aRegion( pSh ? pSh->VisArea() : Frm() );
+    const SwNodes &rNds = GetFmt()->GetDoc()->GetNodes();
+
+    //Erstmal die CntntFrms zum Start und End besorgen, die brauch ich auf
+    //jedenfall.
+    SwPosition *pStartPos = rCrsr.Start(),
+               *pEndPos   = rCrsr.GetPoint() == pStartPos ?
+                                rCrsr.GetMark() : rCrsr.GetPoint();
+    const SwCntntFrm *pStartFrm = rNds[ pStartPos->nNode ]->
+        GetCntntNode()->GetFrm( &rCrsr.GetSttPos(), pStartPos );
+
+    const SwCntntFrm *pEndFrm   = rNds[ pEndPos->nNode ]->
+        GetCntntNode()->GetFrm( &rCrsr.GetEndPos(), pEndPos );
+
+    ASSERT( (pStartFrm && pEndFrm), "Keine CntntFrms gefunden." );
+
+    //Damit die FlyFrms, in denen selektierte Frames stecken, nicht
+    //abgezogen werden
+    SwSortDrawObjs aSortObjs;
+    if ( pStartFrm->IsInFly() )
+    {
+        const SdrObjectPtr pObj = (SdrObject*)pStartFrm->FindFlyFrm()->GetVirtDrawObj();
+        aSortObjs.Insert( pObj );
+        const SdrObjectPtr pObj2 = (SdrObject*)pEndFrm->FindFlyFrm()->GetVirtDrawObj();
+        aSortObjs.Insert( pObj2 );
+    }
+
+    //Fall 4: Tabellenselection
+    if( bIsTblMode )
+    {
+        const SwFrm *pCell = pStartFrm->GetUpper();
+        while ( !pCell->IsCellFrm() )
+            pCell = pCell->GetUpper();
+        SwRect aTmp( pCell->Prt() );
+        aTmp.Pos() += pCell->Frm().Pos();
+        aRegion.ChangeOrigin( aTmp );
+        aRegion.Remove( 0, aRegion.Count() );
+        aRegion.Insert( aTmp, 0 );
+    }
+    else
+    {
+        // falls eine nicht erlaubte Selection besteht, dann korrigiere das
+        // nicht erlaubt ist Header/Footer/TableHeadline ueber 2 Seiten
+        do {    // middle check loop
+            const SwLayoutFrm* pSttLFrm = pStartFrm->GetUpper();
+            const USHORT cHdFtTblHd = FRM_HEADER | FRM_FOOTER | FRM_TAB;
+            while( pSttLFrm &&
+                ! (cHdFtTblHd & pSttLFrm->GetType() ))
+                pSttLFrm = pSttLFrm->GetUpper();
+            if( !pSttLFrm )
+                break;
+            const SwLayoutFrm* pEndLFrm = pEndFrm->GetUpper();
+            while( pEndLFrm &&
+                ! (cHdFtTblHd & pEndLFrm->GetType() ))
+                pEndLFrm = pEndLFrm->GetUpper();
+            if( !pEndLFrm )
+                break;
+
+            ASSERT( pEndLFrm->GetType() == pSttLFrm->GetType(),
+                    "Selection ueber unterschiedliche Inhalte" );
+            switch( pSttLFrm->GetType() )
+            {
+            case FRM_HEADER:
+            case FRM_FOOTER:
+                // auf unterschiedlichen Seiten ??
+                // dann immer auf die Start-Seite
+                if( pEndLFrm->FindPageFrm() != pSttLFrm->FindPageFrm() )
+                {
+                    // End- auf den Start-CntntFrame setzen
+                    if( pStartPos == rCrsr.GetPoint() )
+                        pEndFrm = pStartFrm;
+                    else
+                        pStartFrm = pEndFrm;
+                }
+                break;
+            case FRM_TAB:
+                // auf unterschiedlichen Seiten ??
+                // existiert
+                // dann teste auf Tabelle-Headline
+                {
+                    const SwTabFrm* pTabFrm = (SwTabFrm*)pSttLFrm;
+                    if( ( pTabFrm->GetFollow() ||
+                        ((SwTabFrm*)pEndLFrm)->GetFollow() ) &&
+                        pTabFrm->GetTable()->IsHeadlineRepeat() &&
+                        pTabFrm->GetLower() !=
+                            ((SwTabFrm*)pEndLFrm)->GetLower() )
+                    {
+                        // End- auf den Start-CntntFrame setzen
+                        if( pStartPos == rCrsr.GetPoint() )
+                            pEndFrm = pStartFrm;
+                        else
+                            pStartFrm = pEndFrm;
+                    }
+                }
+                break;
+            }
+        } while( FALSE );
+
+        //CntntRects zu Start- und EndFrms.
+        SwRect aStRect, aEndRect;
+        pStartFrm->GetCharRect( aStRect, *pStartPos ),
+        pEndFrm->GetCharRect  ( aEndRect,*pEndPos );
+
+        //Fall 1: (Gleicher Frame und gleiche Zeile)
+        if( pStartFrm == pEndFrm && aStRect.Top() == aEndRect.Top() )
+        {
+            SwRect aTmp( aStRect.Pos(),
+                            Point( aEndRect.Left(), aEndRect.Bottom() ));
+            // Bug 34888: falls Inhalt selektiert ist, der keinen Platz
+            //            einnimmt (z.B. PostIts,RefMarks, TOXMarks),
+            //            dann mindestens die Breite des Crsr setzen.
+            if( 1 == aTmp.Width() && pStartPos->nContent.GetIndex() !=
+                pEndPos->nContent.GetIndex() )
+            {
+                OutputDevice* pOut = pSh->GetOut();
+                long nCrsrWidth = pOut->GetSettings().GetStyleSettings().
+                                    GetCursorSize();
+                aTmp.Width( pOut->PixelToLogic( Size( nCrsrWidth, 0 ) ).Width() );
+            }
+            Sub( aRegion, aTmp );
+        }
+        //Fall 2: (Gleicher Frame ueber mehr als eine Zeile)
+        else if( pStartFrm == pEndFrm )
+        {
+            SwTwips lLeft = pStartFrm->Frm().Left() + pStartFrm->Prt().Left(),
+                    lRight= pStartFrm->Frm().Left() + pStartFrm->Prt().Right();
+
+            //Erste Zeile
+            Sub( aRegion, SwRect( aStRect.Pos(),Point( lRight, aStRect.Bottom())));
+
+            //Wenn mindestens ein Twips zwischen Start- und Endzeile liegt,
+            //so wird halt alles dazwischenliegende mit aufgenommen.
+            if( (aStRect.Pos().Y()+aStRect.SSize().Height()) != aEndRect.Top() )
+                Sub( aRegion, SwRect( Point( lLeft,
+                                   (aStRect.Pos().Y()+aStRect.SSize().Height()) ),
+                                   Point( lRight, aEndRect.Top()-1 )));
+
+            //und die letzte Zeile
+            Sub( aRegion, SwRect( Point( lLeft, aEndRect.Top() ),
+                               Point( aEndRect.Left(), aEndRect.Bottom() )));
+        }
+        //Fall 3: (Unterschiedliche Frm's, moeglicherweise auch welche
+        //         dazwischen)
+        else
+        {
+            SwRect aStFrm ( pStartFrm->Prt() );
+            SwRect aEndFrm( pEndFrm->Prt() );
+            aStFrm.Pos()  += pStartFrm->Frm().Pos();
+            aEndFrm.Pos() += pEndFrm->Frm().Pos();
+
+                //Erst den StartFrm verknurpseln...
+            Sub( aRegion, SwRect( aStRect.Pos(),
+                            Point( aStFrm.Right(), aStRect.Bottom())));
+
+            if( aStFrm.Bottom() != aStRect.Bottom() )
+                Sub( aRegion, SwRect( Point( aStFrm.Left(),
+                                    (aStRect.Pos().Y()+aStRect.SSize().Height()) ),
+                                Point( aStFrm.Right(), aStFrm.Bottom() )));
+
+                //Nun alles dazwischenliegende (kann auch nix sein)...
+            BOOL bBody = pStartFrm->IsInDocBody();
+            const SwCntntFrm *pCntnt = pStartFrm->GetNextCntntFrm();
+            SwRect aPrvRect;
+
+// JP - 24.11.93:
+// wie kann man die Schleife noch optimieren, damit nur die Frames, die
+// in der VisArea liegen, beachtet werden
+
+            while ( pCntnt != pEndFrm )
+            {
+                if ( pCntnt->IsInFly() )
+                {
+                    const SdrObjectPtr pObj = (SdrObject*)pCntnt->FindFlyFrm()->GetVirtDrawObj();
+                    aSortObjs.Insert( pObj );
+                }
+
+                //Wenn ich im DocumentBody war, so beachte ich nur Frm's
+                //die im Body liegen und umgekehrt.
+                if ( bBody == pCntnt->IsInDocBody() )
+                {
+                    SwRect aCRect( pCntnt->Prt() );
+                    aCRect.Pos() += pCntnt->Frm().Pos();
+                    if( aCRect.IsOver( aRegion.GetOrigin() ))
+                    {
+                        SwRect aTmp( aPrvRect );
+                        aTmp.Union( aCRect );
+                        if ( (aPrvRect.Height() * aPrvRect.Width() +
+                            aCRect.Height()   * aCRect.Width()) ==
+                            (aTmp.Height() * aTmp.Width()) )
+                        {
+                            aPrvRect.Union( aCRect );
+                        }
+                        else
+                        {
+                            if ( aPrvRect.HasArea() )
+                                Sub( aRegion, aPrvRect );
+                            aPrvRect = aCRect;
+                        }
+                    }
+                }
+                pCntnt = pCntnt->GetNextCntntFrm();
+            }
+            if ( aPrvRect.HasArea() )
+                Sub( aRegion, aPrvRect );
+
+                //Jetzt den EndFrm...
+            if ( aEndFrm.Top() != aEndRect.Top() )
+                Sub( aRegion, SwRect( aEndFrm.Pos(),
+                                Point( aEndFrm.Right(), aEndRect.Top()-1 ) ));
+
+            Sub( aRegion, SwRect( aEndFrm.Pos(),
+                               Point( aEndRect.Left(), aEndRect.Bottom() )));
+
+        }
+//      aRegion.Compress( FALSE );
+        aRegion.Invert();
+    }
+
+    //Flys mit Durchlauf ausstanzen. Nicht ausgestanzt werden Flys:
+    //- die Lower des StartFrm/EndFrm sind (FlyInCnt und alle Flys die wiederum
+    //  darin sitzen)
+    //- in der Z-Order ueber denjenigen Flys stehen in denen sich der StartFrm
+    //  befindet.
+    const SwPageFrm *pPage      = pStartFrm->FindPageFrm();
+    const SwPageFrm *pEndPage   = pEndFrm->FindPageFrm();
+    const SwFlyFrm  *pStartFly  = pStartFrm->FindFlyFrm();
+    const SwFlyFrm  *pEndFly    = pEndFrm->FindFlyFrm();
+    while ( pPage )
+    {
+        if ( pPage->GetSortedObjs() )
+        {
+            const SwSortDrawObjs &rObjs = *pPage->GetSortedObjs();
+            for ( USHORT i = 0; i < rObjs.Count(); ++i )
+            {
+                SdrObject *pO = rObjs[i];
+                if ( !pO->IsWriterFlyFrame() )
+                    continue;
+                const SwVirtFlyDrawObj *pObj = (SwVirtFlyDrawObj*)pO;
+                const SwLayoutFrm *pFly = pObj->GetFlyFrm();
+                const SwFmtSurround &rSur = pFly->GetFmt()->GetSurround();
+                if ( !pFly->IsAnLower( pStartFrm ) &&
+                     (rSur.GetSurround() != SURROUND_THROUGHT &&
+                      !rSur.IsContour()) )
+                {
+                    if ( USHRT_MAX != aSortObjs.Seek_Entry( pO ) )
+                        continue;
+
+                    FASTBOOL bSub = TRUE;
+                    const UINT32 nPos = pObj->GetOrdNum();
+                    for ( USHORT k = 0; bSub && k < aSortObjs.Count(); ++k )
+                    {
+                        SwFlyFrm *pTmp = ((SwVirtFlyDrawObj*)aSortObjs[k])->GetFlyFrm();
+                        do
+                        {   if ( nPos < pTmp->GetVirtDrawObj()->GetOrdNumDirect() )
+                                bSub = FALSE;
+                            else
+                                pTmp = pTmp->GetAnchor()->FindFlyFrm();
+                        } while ( bSub && pTmp );
+                    }
+                    if ( bSub )
+                        Sub( aRegion, pFly->Frm() );
+                }
+            }
+        }
+        if ( pPage == pEndPage )
+            break;
+        else
+            pPage = (SwPageFrm*)pPage->GetNext();
+    }
+
+    //Weil's besser aussieht noch die DropCaps ausschliessen.
+    SwRect aDropRect;
+    if ( pStartFrm->IsTxtFrm() )
+    {
+        if ( ((SwTxtFrm*)pStartFrm)->GetDropRect( aDropRect ) )
+            Sub( aRegion, aDropRect );
+    }
+    if ( pEndFrm != pStartFrm && pEndFrm->IsTxtFrm() )
+    {
+        if ( ((SwTxtFrm*)pEndFrm)->GetDropRect( aDropRect ) )
+            Sub( aRegion, aDropRect );
+    }
+
+    rCrsr.Remove( 0, rCrsr.Count() );
+    rCrsr.Insert( &aRegion, 0 );
+}
+
+
diff --git a/sw/source/core/layout/unusedf.cxx b/sw/source/core/layout/unusedf.cxx
new file mode 100644
index 000000000000..8ee5196a13a4
--- /dev/null
+++ b/sw/source/core/layout/unusedf.cxx
@@ -0,0 +1,122 @@
+/*************************************************************************
+ *
+ *  $RCSfile: unusedf.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:22 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "rootfrm.hxx"
+#include "cntfrm.hxx"
+#include "flyfrm.hxx"
+#include "errhdl.hxx"
+
+
+void SwFrm::Format( const SwBorderAttrs * )
+{
+    ASSERT( FALSE, "Format() der Basisklasse gerufen." );
+}
+
+void SwFrm::Paint(const SwRect &) const
+{
+    ASSERT( FALSE, "Paint() der Basisklasse gerufen." );
+}
+
+BOOL SwCntntFrm::WouldFit( SwTwips &, BOOL& )
+{
+    ASSERT( FALSE, "WouldFit des CntntFrm gerufen." );
+    return FALSE;
+}
+
+BOOL SwFrm::GetCrsrOfst( SwPosition *, Point&, const SwCrsrMoveState*  ) const
+{
+    ASSERT( FALSE, "GetCrsrOfst der Basisklasse, hi!" );
+    return FALSE;
+}
+
+#ifndef PRODUCT
+
+void SwRootFrm::Cut()
+{
+    ASSERT( FALSE, "Cut() des RootFrm gerufen." );
+}
+
+void SwRootFrm::Paste( SwFrm *, SwFrm * )
+{
+    ASSERT( FALSE, "Paste() des RootFrm gerufen." );
+}
+
+void SwFlyFrm::Paste( SwFrm *, SwFrm * )
+{
+    ASSERT( FALSE, "Paste() des FlyFrm gerufen." );
+}
+
+#endif
+
+BOOL SwFrm::GetCharRect( SwRect&, const SwPosition&,
+                         SwCrsrMoveState* ) const
+{
+    ASSERT( FALSE, "GetCharRect() der Basis gerufen." );
+    return FALSE;
+}
+
+
diff --git a/sw/source/core/layout/virtoutp.cxx b/sw/source/core/layout/virtoutp.cxx
new file mode 100644
index 000000000000..d3374723399b
--- /dev/null
+++ b/sw/source/core/layout/virtoutp.cxx
@@ -0,0 +1,247 @@
+/*************************************************************************
+ *
+ *  $RCSfile: virtoutp.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:22 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _SV_WINDOW_HXX //autogen
+#include 
+#endif
+
+#include "hintids.hxx"
+#include "viewsh.hxx"
+#include "virtoutp.hxx"
+#include "viewopt.hxx"
+#include "rootfrm.hxx"
+
+static const ViewShell *pVsh = 0;
+
+#ifndef PRODUCT
+
+/*************************************************************************
+ *                          class DbgRect
+ *************************************************************************/
+
+class DbgRect
+{
+        OutputDevice *pOut;
+public:
+        DbgRect( OutputDevice *pOut, const Rectangle &rRect,
+                 const ColorData eColor = COL_LIGHTBLUE );
+};
+
+inline DbgRect::DbgRect( OutputDevice *pOutDev, const Rectangle &rRect,
+                         const ColorData eColor )
+   :pOut( pOutDev )
+{
+    if( pOut )
+    {
+        pOut->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR );
+        pOut->SetLineColor( eColor );
+        pOut->SetFillColor();
+        pOut->DrawRect( rRect );
+        pOut->Pop();
+    }
+}
+
+#endif
+
+/* class SwLayVout verwaltet das virtuelle Outputdevice
+ * Es gibt von dieser Klasse einen statischen Member am RootFrm,
+ * dieser wird in _FrmInit angelegt und in _FrmFinit zerstoert.
+ * */
+
+BOOL SwRootFrm::FlushVout()
+{
+    if( SwRootFrm::pVout->IsFlushable() )
+    {
+        SwRootFrm::pVout->_Flush();
+        return TRUE;
+    }
+    return FALSE;
+}
+
+BOOL SwRootFrm::HasSameRect( const SwRect& rRect )
+{
+    if( SwRootFrm::pVout->IsFlushable() )
+        return ( rRect == SwRootFrm::pVout->GetOrgRect() );
+    return FALSE;
+}
+
+/*************************************************************************
+ *                          SwVOut::DoesFit()
+ *************************************************************************/
+
+// rSize muss in Pixel-Koordinaten vorliegen!
+BOOL SwLayVout::DoesFit( const Size &rNew )
+{
+    if( rNew.Height() > 50 )
+        return FALSE;
+    if( rNew.Width() <= 0 || rNew.Height() <= 0 )
+        return FALSE;
+    if( rNew.Width() <= aSize.Width() )
+        return TRUE;
+    if( !pVirDev )
+    {
+        pVirDev = new VirtualDevice();
+        pVirDev->SetLineColor();
+        if( pOut )
+        {
+            if( pVirDev->GetFillColor() != pOut->GetFillColor() )
+                pVirDev->SetFillColor( pOut->GetFillColor() );
+        }
+    }
+
+    if( rNew.Width() > aSize.Width() )
+    {
+        aSize.Width() = rNew.Width();
+        if( !pVirDev->SetOutputSizePixel( aSize ) )
+        {
+            delete pVirDev;
+            pVirDev = NULL;
+            aSize.Width() = 0;
+            return FALSE;
+        }
+    }
+    return TRUE;
+}
+
+/*************************************************************************
+ *                         SwLayVout::Enter
+ *************************************************************************/
+
+void SwLayVout::Enter(  ViewShell *pShell, const SwRect &rRect, BOOL bOn )
+{
+    Flush();
+
+#ifndef PRODUCT
+        if( pShell->GetViewOptions()->IsTest3() )
+            return;
+#endif
+
+    bOn = bOn && !nCount && rRect.HasArea() && pShell->GetWin();
+    ++nCount;
+    if( bOn )
+    {
+        pSh = pShell;
+        pOut = NULL;
+        OutputDevice *pO = pSh->GetOut();
+// Auf dem Drucker oder einem virt. Outputdevice wird nicht getrickst...
+        if( OUTDEV_WINDOW != pO->GetOutDevType() )
+            return;
+
+        pOut = pO;
+        Size aPixSz( pOut->PixelToLogic( Size( 1,1 )) );
+        SwRect aTmp( rRect );
+        aTmp.SSize().Width() += aPixSz.Width()/2 + 1;
+        aTmp.SSize().Height()+= aPixSz.Height()/2 + 1;
+        Rectangle aTmpRect( pO->LogicToPixel( aTmp.SVRect() ) );
+
+        ASSERT( aTmpRect.GetWidth() <=
+                pSh->GetWin()->GetOutputSizePixel().Width() + 2,
+                "Paintwidth bigger than visarea?" );
+        // Passt das Rechteck in unseren Buffer ?
+        if( !DoesFit( aTmpRect.GetSize() ) )
+        {
+            pOut = NULL;
+            return;
+        }
+
+        aRect = SwRect( pO->PixelToLogic( aTmpRect ) );
+
+#ifdef USED
+        Rectangle aBla( rRect.SVRect() );
+        DbgRect aDbg1( pO, aBla, COL_LIGHTRED );
+#endif
+        SetOutDev( pSh, pVirDev );
+
+        if( pVirDev->GetFillColor() != pOut->GetFillColor() )
+            pVirDev->SetFillColor( pOut->GetFillColor() );
+
+        MapMode aMapMode( pOut->GetMapMode() );
+        aMapMode.SetOrigin( Point(0,0) - aRect.Pos() );
+        if( aMapMode != pVirDev->GetMapMode() )
+            pVirDev->SetMapMode( aMapMode );
+    }
+}
+
+/*************************************************************************
+ *                         SwLayVout::Flush()
+ *************************************************************************/
+
+void SwLayVout::_Flush()
+{
+    ASSERT( pVirDev, "SwLayVout::DrawOut: nothing left Toulouse" );
+    Rectangle aTmp( aRect.SVRect() );
+#ifdef USED
+    DbgRect aDbg1( pOut, aTmp );
+    DbgRect aDbg2( pVirDev, aTmp, COL_YELLOW );
+#endif
+    pOut->DrawOutDev( aRect.Pos(), aRect.SSize(),
+                      aRect.Pos(), aRect.SSize(), *pVirDev );
+    SetOutDev( pSh, pOut );
+    pOut = NULL;
+}
+
+
diff --git a/sw/source/core/layout/virtoutp.hxx b/sw/source/core/layout/virtoutp.hxx
new file mode 100644
index 000000000000..77202f94fe56
--- /dev/null
+++ b/sw/source/core/layout/virtoutp.hxx
@@ -0,0 +1,108 @@
+/*************************************************************************
+ *
+ *  $RCSfile: virtoutp.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:22 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _VIRTOUTP_HXX
+#define _VIRTOUTP_HXX
+
+#ifndef _SV_VIRDEV_HXX //autogen
+#include 
+#endif
+
+#include "swtypes.hxx"      // UCHAR
+#include "swrect.hxx"       // SwRect
+
+class ViewShell;
+
+/*************************************************************************
+ *                      class SwTxtVout
+ *************************************************************************/
+
+class SwLayVout
+{
+    friend void _FrmFinit();    //loescht das Vout
+private:
+    ViewShell*      pSh;
+    OutputDevice*   pOut;
+    VirtualDevice*  pVirDev;
+    SwRect          aRect;
+    SwRect          aOrgRect;
+    Size            aSize;
+    USHORT          nCount;
+
+    BOOL DoesFit( const Size &rOut );
+
+public:
+    SwLayVout() : pVirDev( NULL ), pOut( 0 ), aSize( 0, 50 ), nCount( 0 ) {}
+    ~SwLayVout() { delete pVirDev; }
+
+    void Enter( ViewShell *pShell, const SwRect &rRect, BOOL bOn );
+    void Leave() { --nCount; Flush(); }
+
+    void SetOrgRect( SwRect &rRect ) { aOrgRect = rRect; }
+    const SwRect& GetOrgRect() const { return aOrgRect; }
+
+    BOOL IsFlushable() { return 0 != pOut; }
+    void _Flush();
+    void Flush() { if( pOut ) _Flush(); }
+};
+
+
+
+#endif
diff --git a/sw/source/core/layout/wsfrm.cxx b/sw/source/core/layout/wsfrm.cxx
new file mode 100644
index 000000000000..d1393ad6c623
--- /dev/null
+++ b/sw/source/core/layout/wsfrm.cxx
@@ -0,0 +1,3113 @@
+/*************************************************************************
+ *
+ *  $RCSfile: wsfrm.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:23 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _PSTM_HXX
+#include 
+#endif
+#ifndef _SFXITEMITER_HXX //autogen
+#include 
+#endif
+#ifndef _FMTORNT_HXX //autogen
+#include 
+#endif
+
+#include "pagefrm.hxx"
+#include "section.hxx"      // SwSection
+#include "rootfrm.hxx"
+#include "cntfrm.hxx"
+#include "viewsh.hxx"
+#include "viewimp.hxx"
+#include "doc.hxx"
+#include "fesh.hxx"
+#include "docsh.hxx"
+#include "flyfrm.hxx"
+#include "frmtool.hxx"
+#include "frmfmt.hxx"
+#include "ftninfo.hxx"
+#include "dflyobj.hxx"
+#include "hints.hxx"
+#include "errhdl.hxx"
+#ifndef _SVX_BRSHITEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _FMTCLBL_HXX
+#include 
+#endif
+#ifndef _FMTFORDR_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFSIZE_HXX //autogen
+#include 
+#endif
+#ifndef _FMTPDSC_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_KEEPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BRKITEM_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFTN_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFTN_HXX //autogen
+#include 
+#endif
+
+#include "ftnfrm.hxx"
+#include "tabfrm.hxx"
+#include "swtable.hxx"
+#include "htmltbl.hxx"
+#include "flyfrms.hxx"
+#include "frmsh.hxx"
+#include "sectfrm.hxx"
+#include "fmtclds.hxx"
+#include "txtfrm.hxx"
+#include "dbg_lay.hxx"
+
+#ifdef DEBUG
+
+static void CheckRootSize( SwFrm *pRoot )
+{
+    SwTwips nHeight = 0;
+    const SwFrm *pPage = pRoot->GetLower();
+    while ( pPage )
+    {
+        if ( pPage->GetPrev() && pPage->GetPrev()->GetLower() )
+            nHeight += DOCUMENTBORDER/2;
+        nHeight += pPage->Frm().Height();
+        pPage = pPage->GetNext();
+    }
+    ASSERT( nHeight == pRoot->Frm().Height(), ":-) Roothoehe verschaetzt.");
+}
+#define CHECKROOTSIZE( pRoot ) ::CheckRootSize( pRoot );
+#else
+#define CHECKROOTSIZE( pRoot )
+#endif
+
+
+/*************************************************************************
+|*
+|*  SwFrm::SwFrm()
+|*
+|*  Ersterstellung      AK 12-Feb-1991
+|*  Letzte Aenderung    MA 05. Apr. 94
+|*
+|*************************************************************************/
+
+
+SwFrm::SwFrm( SwModify *pMod ) :
+    SwClient( pMod ),
+    pPrev( 0 ),
+    pNext( 0 ),
+    pUpper( 0 ),
+    pDrawObjs( 0 )
+#ifndef PRODUCT
+    , nFrmId( SwFrm::nLastFrmId++ )
+#endif
+{
+#ifndef PRODUCT
+#ifdef DEBUG
+    static USHORT nStopAt = USHRT_MAX;
+    if ( nFrmId == nStopAt )
+    {
+        int bla = 5;
+    }
+#endif
+#endif
+
+    ASSERT( pMod, "Kein Frameformat uebergeben." );
+    bValidPos = bValidPrtArea = bValidSize = bValidLineNum = bRetouche =
+    bFixHeight = bFixWidth = bColLocked = FALSE;
+    bCompletePaint = bInfInvalid = bVarHeight = TRUE;
+}
+
+/*************************************************************************
+|*
+|*  SwFrm::Modify()
+|*
+|*  Ersterstellung      AK 01-Mar-1991
+|*  Letzte Aenderung    MA 20. Jun. 96
+|*
+|*************************************************************************/
+void SwFrm::Modify( SfxPoolItem * pOld, SfxPoolItem * pNew )
+{
+    BYTE nInvFlags = 0;
+
+    if( pNew && RES_ATTRSET_CHG == pNew->Which() )
+    {
+        SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() );
+        SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() );
+        while( TRUE )
+        {
+            _UpdateAttr( (SfxPoolItem*)aOIter.GetCurItem(),
+                         (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags );
+            if( aNIter.IsAtEnd() )
+                break;
+            aNIter.NextItem();
+            aOIter.NextItem();
+        }
+    }
+    else
+        _UpdateAttr( pOld, pNew, nInvFlags );
+
+    if ( nInvFlags != 0 )
+    {
+        SwPageFrm *pPage = FindPageFrm();
+        InvalidatePage( pPage );
+        if ( nInvFlags & 0x01 )
+        {
+            _InvalidatePrt();
+            if( !GetPrev() && IsTabFrm() && IsInSct() )
+                FindSctFrm()->_InvalidatePrt();
+        }
+        if ( nInvFlags & 0x02 )
+            _InvalidateSize();
+        if ( nInvFlags & 0x04 )
+            _InvalidatePos();
+        if ( nInvFlags & 0x08 )
+            SetCompletePaint();
+        SwFrm *pNxt;
+        if ( nInvFlags & 0x30 && 0 != (pNxt = GetNext()) )
+        {
+            pNxt->InvalidatePage( pPage );
+            if ( nInvFlags & 0x10 )
+                pNxt->_InvalidatePos();
+            if ( nInvFlags & 0x20 )
+                pNxt->SetCompletePaint();
+        }
+    }
+}
+
+void SwFrm::_UpdateAttr( SfxPoolItem *pOld, SfxPoolItem *pNew,
+                         BYTE &rInvFlags )
+{
+    USHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
+    switch( nWhich )
+    {
+        case RES_BOX:
+        case RES_SHADOW:
+            Prepare( PREP_FIXSIZE_CHG );
+            // hier kein break !
+        case RES_LR_SPACE:
+        case RES_UL_SPACE:
+            rInvFlags |= 0x0B;
+            break;
+
+        case RES_BACKGROUND:
+            rInvFlags |= 0x28;
+            break;
+
+        case RES_KEEP:
+            rInvFlags |= 0x04;
+            break;
+
+        case RES_FRM_SIZE:
+            ReinitializeFrmSizeAttrFlags();
+            rInvFlags |= 0x13;
+            break;
+
+        case RES_FMT_CHG:
+            rInvFlags |= 0x0F;
+            break;
+
+        case RES_COL:
+            ASSERT( FALSE, "Spalten fuer neuen FrmTyp?" );
+            break;
+
+        default:
+            /* do Nothing */;
+    }
+}
+
+/*************************************************************************
+|*
+|*    SwFrm::Prepare()
+|*    Ersterstellung    MA 13. Apr. 93
+|*    Letzte Aenderung  MA 26. Jun. 96
+|*
+|*************************************************************************/
+void SwFrm::Prepare( const PrepareHint, const void *, BOOL )
+{
+    /* Do nothing */
+}
+
+/*************************************************************************
+|*
+|*    SwFrm::InvalidatePage()
+|*    Beschreibung:     Invalidiert die Seite, in der der Frm gerade steht.
+|*      Je nachdem ob es ein Layout, Cntnt oder FlyFrm ist wird die Seite
+|*      entsprechend Invalidiert.
+|*    Ersterstellung    MA 22. Jul. 92
+|*    Letzte Aenderung  MA 14. Oct. 94
+|*
+|*************************************************************************/
+void SwFrm::InvalidatePage( const SwPageFrm *pPage ) const
+{
+#if defined(DEBUG) && !defined(PRODUCT)
+    static USHORT nStop = 0;
+    if ( nStop == GetFrmId() )
+    {
+        int bla = 5;
+    }
+#endif
+
+    if ( !pPage )
+        pPage = FindPageFrm();
+
+    if ( pPage && pPage->GetUpper() )
+    {
+        if ( pPage->GetFmt()->GetDoc()->IsInDtor() )
+            return;
+
+        SwRootFrm *pRoot = (SwRootFrm*)pPage->GetUpper();
+        const SwFlyFrm *pFly = FindFlyFrm();
+        if ( IsCntntFrm() )
+        {
+            if ( pRoot->IsTurboAllowed() )
+            {
+                // JP 21.09.95: wenn sich der ContentFrame 2 mal eintragen
+                //              will, kann es doch eine TurboAction bleiben.
+                //  ODER????
+                if ( !pRoot->GetTurbo() || this == pRoot->GetTurbo() )
+                    pRoot->SetTurbo( (const SwCntntFrm*)this );
+                else
+                {
+                    pRoot->DisallowTurbo();
+                    //Die Seite des Turbo koennte eine andere als die meinige
+                    //sein, deshalb muss sie invalidiert werden.
+                    const SwFrm *pTmp = pRoot->GetTurbo();
+                    pRoot->ResetTurbo();
+                    pTmp->InvalidatePage();
+                }
+            }
+            if ( !pRoot->GetTurbo() )
+            {
+                if ( pFly )
+                {   if( !pFly->IsLocked() )
+                    {
+                        if ( pFly->IsFlyInCntFrm() )
+                        {   pPage->InvalidateFlyInCnt();
+                            ((SwFlyInCntFrm*)pFly)->InvalidateCntnt();
+                            pFly->GetAnchor()->InvalidatePage();
+                        }
+                        else
+                            pPage->InvalidateFlyCntnt();
+                    }
+                }
+                else
+                    pPage->InvalidateCntnt();
+            }
+        }
+        else
+        {
+            pRoot->DisallowTurbo();
+            if ( pFly )
+            {   if( !pFly->IsLocked() )
+                {
+                    if ( pFly->IsFlyInCntFrm() )
+                    {   pPage->InvalidateFlyInCnt();
+                        ((SwFlyInCntFrm*)pFly)->InvalidateLayout();
+                        pFly->GetAnchor()->InvalidatePage();
+                    }
+                    else
+                        pPage->InvalidateFlyLayout();
+                }
+            }
+            else
+                pPage->InvalidateLayout();
+
+            if ( pRoot->GetTurbo() )
+            {   const SwFrm *pTmp = pRoot->GetTurbo();
+                pRoot->ResetTurbo();
+                pTmp->InvalidatePage();
+            }
+        }
+        pRoot->SetIdleFlags();
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFrm::ChgSize()
+|*
+|*  Ersterstellung      AK 15-Feb-1991
+|*  Letzte Aenderung    MA 18. Nov. 98
+|*
+|*************************************************************************/
+void SwFrm::ChgSize( const Size& aNewSize )
+{
+    bFixHeight = bVarHeight;
+    bFixWidth  = !bVarHeight;
+
+    const Size aOldSize( Frm().SSize() );
+    if ( aNewSize == aOldSize )
+        return;
+
+    const SzPtr pVar = pVARSIZE;
+    const SzPtr pFix = pFIXSIZE;
+
+    aFrm.SSize().*pFix = aNewSize.*pFix;
+
+    if ( GetUpper() )
+    {
+        long nDiff = aNewSize.*pVar - aFrm.SSize().*pVar;
+        if( nDiff )
+        {
+            if ( GetUpper()->IsFtnBossFrm() && HasFixSize( pVar ) &&
+                 NA_GROW_SHRINK !=
+                 ((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this ) )
+            {
+                aFrm.SSize().*pVar = aNewSize.*pVar;
+                SwTwips nReal = ((SwLayoutFrm*)this)->AdjustNeighbourhood( nDiff );
+                if ( nReal != nDiff )
+                    aFrm.SSize().*pVar -= nDiff - nReal;
+            }
+            else
+            {
+                if ( nDiff > 0 )
+                    Grow( nDiff, pVar );
+                else
+                    Shrink( -nDiff, pVar );
+                // Auch wenn das Grow/Shrink noch nicht die gewuenschte Breite eingestellt hat,
+                // wie z.B. beim Aufruf durch ChgColumns, um die Spaltenbreiten einzustellen,
+                // wird die Breite jetzt gesetzt.
+                aFrm.SSize().*pVar = aNewSize.*pVar;
+            }
+        }
+    }
+    else
+        aFrm.SSize().*pVar = aNewSize.*pVar;
+
+    if ( Frm().SSize() != aOldSize )
+    {
+        SwPageFrm *pPage = FindPageFrm();
+        if ( GetNext() )
+        {
+            GetNext()->_InvalidatePos();
+            GetNext()->InvalidatePage( pPage );
+        }
+        if ( IsLayoutFrm() && ((SwLayoutFrm*)this)->Lower() )
+            ((SwLayoutFrm*)this)->Lower()->_InvalidateSize();
+        _InvalidatePrt();
+        _InvalidateSize();
+        InvalidatePage( pPage );
+        if ( GetUpper() )
+            GetUpper()->_InvalidateSize();
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFrm::InsertBefore()
+|*
+|*  Beschreibung        SwFrm wird in eine bestehende Struktur eingefuegt
+|*                      Eingefuegt wird unterhalb des Parent und entweder
+|*                      vor pBehind oder am Ende der Kette wenn pBehind
+|*                      leer ist.
+|*  Letzte Aenderung    MA 06. Aug. 99
+|*
+|*************************************************************************/
+void SwFrm::InsertBefore( SwLayoutFrm* pParent, SwFrm* pBehind )
+{
+    ASSERT( pParent, "Kein Parent fuer Insert." );
+    ASSERT( (!pBehind || (pBehind && pParent == pBehind->GetUpper())),
+            "Framebaum inkonsistent." );
+
+    pUpper = pParent;
+    pNext = pBehind;
+    if( pBehind )
+    {   //Einfuegen vor pBehind.
+        if( 0 != (pPrev = pBehind->pPrev) )
+            pPrev->pNext = this;
+        else
+            pUpper->pLower = this;
+        pBehind->pPrev = this;
+    }
+    else
+    {   //Einfuegen am Ende, oder als ersten Node im Unterbaum
+        pPrev = pUpper->Lower();
+        if ( pPrev )
+        {
+            while( pPrev->pNext )
+                pPrev = pPrev->pNext;
+            pPrev->pNext = this;
+        }
+        else
+            pUpper->pLower = this;
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFrm::InsertBehind()
+|*
+|*  Beschreibung        SwFrm wird in eine bestehende Struktur eingefuegt
+|*                      Eingefuegt wird unterhalb des Parent und entweder
+|*                      hinter pBefore oder am Anfang der Kette wenn pBefore
+|*                      leer ist.
+|*  Letzte Aenderung    MA 06. Aug. 99
+|*
+|*************************************************************************/
+void SwFrm::InsertBehind( SwLayoutFrm *pParent, SwFrm *pBefore )
+{
+    ASSERT( pParent, "Kein Parent fuer Insert." );
+    ASSERT( (!pBefore || (pBefore && pParent == pBefore->GetUpper())),
+            "Framebaum inkonsistent." );
+
+    pUpper = pParent;
+    pPrev = pBefore;
+    if ( pBefore )
+    {
+        //Einfuegen hinter pBefore
+        if ( 0 != (pNext = pBefore->pNext) )
+            pNext->pPrev = this;
+        pBefore->pNext = this;
+    }
+    else
+    {
+        //Einfuegen am Anfang der Kette
+        pNext = pParent->Lower();
+        if ( pParent->Lower() )
+            pParent->Lower()->pPrev = this;
+        pParent->pLower = this;
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFrm::InsertGroup()
+|*
+|*  Beschreibung        Eine Kette von SwFrms wird in eine bestehende Struktur
+|*                      eingefuegt
+|*  Letzte Aenderung    AMA 9. Dec. 97
+|*
+|*  Bisher wird dies genutzt, um einen SectionFrame, der ggf. schon Geschwister
+|*  mit sich bringt, in eine bestehende Struktur einzufuegen.
+|*
+|*  Wenn man den dritten Parameter als NULL uebergibt, entspricht
+|*  diese Methode dem SwFrm::InsertBefore(..), nur eben mit Geschwistern.
+|*
+|*  Wenn man einen dritten Parameter uebergibt, passiert folgendes:
+|*  this wird pNext von pParent,
+|*  pSct wird pNext vom Letzten der this-Kette,
+|*  pBehind wird vom pParent an den pSct umgehaengt.
+|*  Dies dient dazu: ein SectionFrm (this) wird nicht als
+|*  Kind an einen anderen SectionFrm (pParent) gehaengt, sondern pParent
+|*  wird in zwei Geschwister aufgespalten (pParent+pSct) und this dazwischen
+|*  eingebaut.
+|*
+|*************************************************************************/
+void SwFrm::InsertGroupBefore( SwFrm* pParent, SwFrm* pBehind, SwFrm* pSct )
+{
+    ASSERT( pParent, "Kein Parent fuer Insert." );
+    ASSERT( (!pBehind || (pBehind && ( pParent == pBehind->GetUpper())
+            || ( pParent->IsSctFrm() && pBehind->GetUpper()->IsColBodyFrm() ) ) ),
+            "Framebaum inkonsistent." );
+    if( pSct )
+    {
+        pUpper = pParent->GetUpper();
+        SwFrm *pLast = this;
+        while( pLast->GetNext() )
+        {
+            pLast = pLast->GetNext();
+            pLast->pUpper = GetUpper();
+        }
+        if( pBehind )
+        {
+            pLast->pNext = pSct;
+            pSct->pPrev = pLast;
+            pSct->pNext = pParent->GetNext();
+        }
+        else
+        {
+            pLast->pNext = pParent->GetNext();
+            if( pLast->GetNext() )
+                pLast->GetNext()->pPrev = pLast;
+        }
+        pParent->pNext = this;
+        pPrev = pParent;
+        if( pSct->GetNext() )
+            pSct->GetNext()->pPrev = pSct;
+        while( pLast->GetNext() )
+        {
+            pLast = pLast->GetNext();
+            pLast->pUpper = GetUpper();
+        }
+        if( pBehind )
+        {   //Einfuegen vor pBehind.
+            if( pBehind->GetPrev() )
+                pBehind->GetPrev()->pNext = NULL;
+            else
+                pBehind->GetUpper()->pLower = NULL;
+            pBehind->pPrev = NULL;
+            SwLayoutFrm* pTmp = (SwLayoutFrm*)pSct;
+            if( pTmp->Lower() )
+            {
+                ASSERT( pTmp->Lower()->IsColumnFrm(), "InsertGrp: Used SectionFrm" );
+                pTmp = (SwLayoutFrm*)((SwLayoutFrm*)pTmp->Lower())->Lower();
+                ASSERT( pTmp, "InsertGrp: Missing ColBody" );
+            }
+            pBehind->pUpper = pTmp;
+            pBehind->GetUpper()->pLower = pBehind;
+            pLast = pBehind->GetNext();
+            while ( pLast )
+            {
+                pLast->pUpper = pBehind->GetUpper();
+                pLast = pLast->GetNext();
+            };
+        }
+        else
+        {
+            ASSERT( pSct->IsSctFrm(), "InsertGroup: For SectionFrms only" );
+            delete ((SwSectionFrm*)pSct);
+        }
+    }
+    else
+    {
+        pUpper = (SwLayoutFrm*)pParent;
+        SwFrm *pLast = this;
+        while( pLast->GetNext() )
+        {
+            pLast = pLast->GetNext();
+            pLast->pUpper = GetUpper();
+        }
+        pLast->pNext = pBehind;
+        if( pBehind )
+        {   //Einfuegen vor pBehind.
+            if( 0 != (pPrev = pBehind->pPrev) )
+                pPrev->pNext = this;
+            else
+                pUpper->pLower = this;
+            pBehind->pPrev = pLast;
+        }
+        else
+        {   //Einfuegen am Ende, oder des ersten Nodes im Unterbaum
+            pPrev = pUpper->Lower();
+            if ( pPrev )
+            {
+                while( pPrev->pNext )
+                    pPrev = pPrev->pNext;
+                pPrev->pNext = this;
+            }
+            else
+                pUpper->pLower = this;
+        }
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFrm::Remove()
+|*
+|*  Ersterstellung      AK 01-Mar-1991
+|*  Letzte Aenderung    MA 07. Dec. 95
+|*
+|*************************************************************************/
+void SwFrm::Remove()
+{
+    ASSERT( pUpper, "Removen ohne Upper?" );
+
+    if( pPrev )
+        // einer aus der Mitte wird removed
+        pPrev->pNext = pNext;
+    else
+    {   // der erste in einer Folge wird removed
+        ASSERT( pUpper->pLower == this, "Layout inkonsistent." );
+        pUpper->pLower = pNext;
+    }
+    if( pNext )
+        pNext->pPrev = pPrev;
+
+    // Verbindung kappen.
+    pNext  = pPrev  = 0;
+    pUpper = 0;
+}
+/*************************************************************************
+|*
+|*  SwCntntFrm::Paste()
+|*
+|*  Ersterstellung      MA 23. Feb. 94
+|*  Letzte Aenderung    MA 09. Sep. 98
+|*
+|*************************************************************************/
+void SwCntntFrm::Paste( SwFrm* pParent, SwFrm* pSibling)
+{
+    ASSERT( pParent, "Kein Parent fuer Paste." );
+    ASSERT( pParent->IsLayoutFrm(), "Parent ist CntntFrm." );
+    ASSERT( pParent != this, "Bin selbst der Parent." );
+    ASSERT( pSibling != this, "Bin mein eigener Nachbar." );
+    ASSERT( !GetPrev() && !GetNext() && !GetUpper(),
+            "Bin noch irgendwo angemeldet." );
+
+    //In den Baum einhaengen.
+    InsertBefore( (SwLayoutFrm*)pParent, pSibling );
+
+    SwPageFrm *pPage = FindPageFrm();
+    _InvalidateAll();
+    InvalidatePage( pPage );
+
+    if( pPage )
+    {
+        pPage->InvalidateSpelling();
+        pPage->InvalidateAutoCompleteWords();
+    }
+
+    if ( GetNext() )
+    {
+        SwFrm* pNxt = GetNext();
+        pNxt->_InvalidatePrt();
+        pNxt->_InvalidatePos();
+        pNxt->InvalidatePage( pPage );
+        if( pNxt->IsSctFrm() )
+            pNxt = ((SwSectionFrm*)pNxt)->ContainsCntnt();
+        if( pNxt && pNxt->IsTxtFrm() && pNxt->IsInFtn() )
+            pNxt->Prepare( PREP_FTN, 0, FALSE );
+    }
+
+    if ( Frm().Height() )
+        pParent->Grow( Frm().Height(), pHeight );
+
+    if ( Frm().Width() != pParent->Prt().Width() )
+        Prepare( PREP_FIXSIZE_CHG );
+
+    if ( GetPrev() )
+    {
+        if ( IsFollow() )
+            //Ich bin jetzt direkter Nachfolger meines Masters geworden
+            ((SwCntntFrm*)GetPrev())->Prepare( PREP_FOLLOW_FOLLOWS );
+        else
+        {
+            if ( GetPrev()->Frm().Height() !=
+                 GetPrev()->Prt().Height() + GetPrev()->Prt().Top() )
+                //Umrandung zu beruecksichtigen?
+                GetPrev()->_InvalidatePrt();
+            GetPrev()->InvalidatePage( pPage );
+        }
+    }
+    if ( IsInFtn() )
+    {
+        SwFrm* pFrm = GetIndPrev();
+        if( pFrm && pFrm->IsSctFrm() )
+            pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
+        if( pFrm )
+            pFrm->Prepare( PREP_QUOVADIS, 0, FALSE );
+        if( !GetNext() )
+        {
+            pFrm = FindFtnFrm()->GetNext();
+            if( pFrm && 0 != (pFrm=((SwLayoutFrm*)pFrm)->ContainsAny()) )
+                pFrm->_InvalidatePrt();
+        }
+    }
+
+    _InvalidateLineNum();
+    SwFrm *pNxt = FindNextCnt();
+    if ( pNxt  )
+    {
+        while ( pNxt && pNxt->IsInTab() )
+        {
+            if( 0 != (pNxt = pNxt->FindTabFrm()) )
+                pNxt = pNxt->FindNextCnt();
+        }
+        if ( pNxt )
+        {
+            pNxt->_InvalidateLineNum();
+            if ( pNxt != GetNext() )
+                pNxt->InvalidatePage();
+        }
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwCntntFrm::Cut()
+|*
+|*  Ersterstellung      AK 14-Feb-1991
+|*  Letzte Aenderung    MA 09. Sep. 98
+|*
+|*************************************************************************/
+void SwCntntFrm::Cut()
+{
+    ASSERT( GetUpper(), "Cut ohne Upper()." );
+
+    SwPageFrm *pPage = FindPageFrm();
+    InvalidatePage( pPage );
+    SwFrm *pFrm = GetIndPrev();
+    if( pFrm )
+    {
+        if( pFrm->IsSctFrm() )
+            pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
+        if ( pFrm && pFrm->IsCntntFrm() )
+        {
+            pFrm->_InvalidatePrt();
+            if( IsInFtn() )
+                pFrm->Prepare( PREP_QUOVADIS, 0, FALSE );
+        }
+    }
+
+    SwFrm *pNxt = FindNextCnt();
+    if ( pNxt )
+    {
+        while ( pNxt && pNxt->IsInTab() )
+        {
+            if( 0 != (pNxt = pNxt->FindTabFrm()) )
+                pNxt = pNxt->FindNextCnt();
+        }
+        if ( pNxt )
+        {
+            pNxt->_InvalidateLineNum();
+            if ( pNxt != GetNext() )
+                pNxt->InvalidatePage();
+        }
+    }
+
+    if( 0 != (pFrm = GetIndNext()) )
+    {   //Der alte Nachfolger hat evtl. einen Abstand zum Vorgaenger
+        //berechnet, der ist jetzt, wo er der erste wird obsolet bzw. anders.
+        pFrm->_InvalidatePrt();
+        pFrm->_InvalidatePos();
+        pFrm->InvalidatePage( pPage );
+        if( pFrm->IsSctFrm() )
+        {
+            pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
+            if( pFrm )
+            {
+                pFrm->_InvalidatePrt();
+                pFrm->_InvalidatePos();
+                pFrm->InvalidatePage( pPage );
+            }
+        }
+        if( pFrm && IsInFtn() )
+            pFrm->Prepare( PREP_ERGOSUM, 0, FALSE );
+        if( IsInSct() && !GetPrev() )
+        {
+            SwSectionFrm* pSct = FindSctFrm();
+            if( !pSct->IsFollow() )
+            {
+                pSct->_InvalidatePrt();
+                pSct->InvalidatePage( pPage );
+            }
+        }
+    }
+    else
+    {
+        InvalidateNextPos();
+        //Einer muss die Retusche uebernehmen: Vorgaenger oder Upper
+        if ( 0 != (pFrm = GetPrev()) )
+        {   pFrm->SetRetouche();
+            pFrm->Prepare( PREP_WIDOWS_ORPHANS );
+            pFrm->_InvalidatePos();
+            pFrm->InvalidatePage( pPage );
+        }
+        //Wenn ich der einzige CntntFrm in meinem Upper bin (war), so muss
+        //er die Retouche uebernehmen.
+        //Ausserdem kann eine Leerseite entstanden sein.
+        else
+        {   SwRootFrm *pRoot = FindRootFrm();
+            if ( pRoot )
+            {
+                pRoot->SetSuperfluous();
+                GetUpper()->SetCompletePaint();
+                GetUpper()->InvalidatePage( pPage );
+            }
+            if( IsInSct() )
+            {
+                SwSectionFrm* pSct = FindSctFrm();
+                if( !pSct->IsFollow() )
+                {
+                    pSct->_InvalidatePrt();
+                    pSct->InvalidatePage( pPage );
+                }
+            }
+        }
+    }
+    //Erst removen, dann Upper Shrinken.
+    SwLayoutFrm *pUp = GetUpper();
+    Remove();
+    if ( pUp )
+    {
+        SwSectionFrm *pSct;
+        if ( !pUp->Lower() && ( ( pUp->IsFtnFrm() && !pUp->IsColLocked() )
+            || ( pUp->IsInSct() && !(pSct = pUp->FindSctFrm())->ContainsCntnt() ) ) )
+        {
+            if ( pUp->GetUpper() )
+            {
+                if( pUp->IsFtnFrm() )
+                {
+                    if( pUp->GetNext() && !pUp->GetPrev() )
+                    {
+                        SwFrm* pTmp = ((SwLayoutFrm*)pUp->GetNext())->ContainsAny();
+                        if( pTmp )
+                            pTmp->_InvalidatePrt();
+                    }
+                    pUp->Cut();
+                    delete pUp;
+                }
+                else
+                {
+                    if( pSct->IsColLocked() || !pSct->IsInFtn() )
+                    {
+                        pSct->DelEmpty( FALSE );
+                    // Wenn ein gelockter Bereich nicht geloescht werden darf,
+                    // so ist zumindest seine Groesse durch das Entfernen seines
+                    // letzten Contents ungueltig geworden.
+                        pSct->_InvalidateSize();
+                    }
+                    else
+                    {
+                        pSct->DelEmpty( TRUE );
+                        delete pSct;
+                    }
+                }
+            }
+        }
+        else if ( Frm().Height() )
+            pUp->Shrink( Frm().Height(), pHeight );
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwLayoutFrm::Paste()
+|*
+|*  Ersterstellung      MA 23. Feb. 94
+|*  Letzte Aenderung    MA 23. Feb. 94
+|*
+|*************************************************************************/
+void SwLayoutFrm::Paste( SwFrm* pParent, SwFrm* pSibling)
+{
+    ASSERT( pParent, "Kein Parent fuer Paste." );
+    ASSERT( pParent->IsLayoutFrm(), "Parent ist CntntFrm." );
+    ASSERT( pParent != this, "Bin selbst der Parent." );
+    ASSERT( pSibling != this, "Bin mein eigener Nachbar." );
+    ASSERT( !GetPrev() && !GetNext() && !GetUpper(),
+            "Bin noch irgendwo angemeldet." );
+
+    //In den Baum einhaengen.
+    InsertBefore( (SwLayoutFrm*)pParent, pSibling );
+
+    //ggf. die Memberpointer korrigieren.
+    const SwFmtFillOrder &rFill =
+                        ((SwLayoutFrm*)pParent)->GetFmt()->GetFillOrder();
+    if ( rFill.GetFillOrder() == ATT_BOTTOM_UP ||
+         rFill.GetFillOrder() == ATT_TOP_DOWN )
+        bVarHeight = TRUE;
+    else
+        bVarHeight = FALSE;
+    const SzPtr pFix = pFIXSIZE;
+    const SzPtr pVar = pVARSIZE;
+    if( Frm().SSize().*pFix != pParent->Prt().SSize().*pFix )
+        _InvalidateSize();
+    _InvalidatePos();
+    const SwPageFrm *pPage = FindPageFrm();
+    InvalidatePage( pPage );
+    SwFrm *pFrm;
+    if( !IsColumnFrm() )
+    {
+        if( 0 != ( pFrm = GetIndNext() ) )
+        {
+            pFrm->_InvalidatePos();
+            if( IsInFtn() )
+            {
+                if( pFrm->IsSctFrm() )
+                    pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
+                if( pFrm )
+                    pFrm->Prepare( PREP_ERGOSUM, 0, FALSE );
+            }
+        }
+        if ( IsInFtn() && 0 != ( pFrm = GetIndPrev() ) )
+        {
+            if( pFrm->IsSctFrm() )
+                pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
+            if( pFrm )
+                pFrm->Prepare( PREP_QUOVADIS, 0, FALSE );
+        }
+    }
+
+    if ( Frm().SSize().*pVar )
+    {
+        // AdjustNeighbourhood wird jetzt auch in Spalten aufgerufen,
+        // die sich nicht in Rahmen befinden
+        BYTE nAdjust = GetUpper()->IsFtnBossFrm() ?
+                ((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this )
+                : NA_GROW_SHRINK;
+        SwTwips nGrow = Frm().SSize().*pVar;
+        if( NA_ONLY_ADJUST == nAdjust )
+            AdjustNeighbourhood( nGrow );
+        else
+        {
+            SwTwips nReal = 0;
+            if( NA_ADJUST_GROW == nAdjust )
+                nReal = AdjustNeighbourhood( nGrow );
+            if( nReal < nGrow )
+                nReal += pParent->Grow( nGrow - nReal, pVar );
+            if( NA_GROW_ADJUST == nAdjust && nReal < nGrow )
+                AdjustNeighbourhood( nGrow - nReal );
+        }
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwLayoutFrm::Cut()
+|*
+|*  Ersterstellung      MA 23. Feb. 94
+|*  Letzte Aenderung    MA 23. Feb. 94
+|*
+|*************************************************************************/
+void SwLayoutFrm::Cut()
+{
+    if ( GetNext() )
+        GetNext()->_InvalidatePos();
+
+    const SzPtr pVar = pVARSIZE;
+    SwTwips nShrink = Frm().SSize().*pVar;
+
+    //Erst removen, dann Upper Shrinken.
+    SwLayoutFrm *pUp = GetUpper();
+
+    // AdjustNeighbourhood wird jetzt auch in Spalten aufgerufen,
+    // die sich nicht in Rahmen befinden
+
+    // Remove must not be called before a AdjustNeighbourhood, but it has to
+    // be called before the upper-shrink-call, if the upper-shrink takes care
+    // of his content
+    if ( pUp && nShrink )
+    {
+        if( pUp->IsFtnBossFrm() )
+        {
+            BYTE nAdjust= ((SwFtnBossFrm*)pUp)->NeighbourhoodAdjustment( this );
+            if( NA_ONLY_ADJUST == nAdjust )
+                AdjustNeighbourhood( -nShrink );
+            else
+            {
+                SwTwips nReal = 0;
+                if( NA_ADJUST_GROW == nAdjust )
+                    nReal = -AdjustNeighbourhood( -nShrink );
+                if( nReal < nShrink )
+                {
+                    SwTwips nOldHeight = Frm().Height();
+                    Frm().Height( 0 );
+                    nReal += pUp->Shrink( nShrink - nReal, pVar );
+                    Frm().Height( nOldHeight );
+                }
+                if( NA_GROW_ADJUST == nAdjust && nReal < nShrink )
+                    AdjustNeighbourhood( nReal - nShrink );
+            }
+            Remove();
+        }
+        else
+        {
+            Remove();
+            pUp->Shrink( nShrink, pVar );
+        }
+    }
+    else
+        Remove();
+
+    if( pUp && !pUp->Lower() )
+    {
+        pUp->SetCompletePaint();
+        pUp->InvalidatePage();
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwFrm::Grow()
+|*
+|*  Ersterstellung      AK 19-Feb-1991
+|*  Letzte Aenderung    MA 05. May. 94
+|*
+|*************************************************************************/
+SwTwips SwFrm::Grow( SwTwips nDist, const SzPtr pDirection,
+                     BOOL bTst, BOOL bInfo )
+{
+    ASSERT( nDist >= 0, "Negatives Wachstum?" );
+
+    PROTOCOL_ENTER( this, bTst ? PROT_GROW_TST : PROT_GROW, 0, &nDist )
+
+    if ( nDist )
+    {
+        if ( Prt().SSize().*pDirection > 0 &&
+             nDist > (LONG_MAX - Prt().SSize().*pDirection) )
+            nDist = LONG_MAX - Prt().SSize().*pDirection;
+
+        if ( IsFlyFrm() )
+            return ((SwFlyFrm*)this)->_Grow( nDist, pDirection, bTst );
+        else if( IsSctFrm() )
+            return ((SwSectionFrm*)this)->_Grow( nDist, pDirection, bTst );
+        else
+        {
+            const SwTwips nReal = GrowFrm( nDist, pDirection, bTst, bInfo );
+            if( !bTst )
+                Prt().SSize().*pDirection += IsCntntFrm() ? nDist : nReal;
+            return nReal;
+        }
+    }
+    return 0L;
+}
+/*************************************************************************
+|*
+|*  SwFrm::Shrink()
+|*
+|*  Ersterstellung      AK 14-Feb-1991
+|*  Letzte Aenderung    MA 05. May. 94
+|*
+|*************************************************************************/
+SwTwips SwFrm::Shrink( SwTwips nDist, const SzPtr pDirection,
+                       BOOL bTst, BOOL bInfo )
+{
+    ASSERT( nDist >= 0, "Negative Verkleinerung?" );
+
+    PROTOCOL_ENTER( this, bTst ? PROT_SHRINK_TST : PROT_SHRINK, 0, &nDist )
+
+    if ( nDist )
+    {
+        if ( IsFlyFrm() )
+            return ((SwFlyFrm*)this)->_Shrink( nDist, pDirection, bTst );
+        else if( IsSctFrm() )
+            return ((SwSectionFrm*)this)->_Shrink( nDist, pDirection, bTst );
+        else
+        {
+            SwTwips nReal = Frm().SSize().*pDirection;
+            ShrinkFrm( nDist, pDirection, bTst, bInfo );
+            nReal -= Frm().SSize().*pDirection;
+            if( !bTst )
+                Prt().SSize().*pDirection -= IsCntntFrm() ? nDist : nReal;
+            return nReal;
+        }
+    }
+    return 0L;
+}
+/*************************************************************************
+|*
+|*  SwFrm::AdjustNeighbourhood()
+|*
+|*  Beschreibung        Wenn sich die Groesse eines Frm's direkt unterhalb
+|*      eines Fussnotenbosses (Seite/Spalte) veraendert hat, so muss dieser
+|*      "Normalisiert" werden.
+|*      Es gibt dort immer einen Frame, der den "maximal moeglichen" Raum
+|*      einnimmt (der Frame, der den Body.Text enhaelt) und keinen oder
+|*      mehrere Frames die den Platz einnehmen den sie halt brauchen
+|*      (Kopf-/Fussbereich, Fussnoten).
+|*      Hat sich einer der Frames veraendert, so muss der Body-Text-Frame
+|*      entsprechen wachsen oder schrumpfen; unabhaegig davon, dass er fix ist.
+|*      !! Ist es moeglich dies allgemeiner zu loesen, also nicht auf die
+|*      Seite beschraenkt und nicht auf einen Speziellen Frame, der den
+|*      maximalen Platz einnimmt (gesteuert ueber Attribut FrmSize)? Probleme:
+|*      Was ist wenn mehrere Frames nebeneinander stehen, die den maximalen
+|*      Platz einnehmen?
+|*      Wie wird der Maximale Platz berechnet?
+|*      Wie klein duerfen diese Frames werden?
+|*
+|*      Es wird auf jeden Fall nur so viel Platz genehmigt, dass ein
+|*      Minimalwert fuer die Hoehe des Bodys nicht unterschritten wird.
+|*
+|*  Parameter: nDiff ist der Betrag, um den Platz geschaffen werden muss
+|*
+|*  Ersterstellung      MA 07. May. 92
+|*  Letzte Aenderung    AMA 02. Nov. 98
+|*
+|*************************************************************************/
+SwTwips SwFrm::AdjustNeighbourhood( SwTwips nDiff, BOOL bTst )
+{
+    PROTOCOL_ENTER( this, PROT_ADJUSTN, 0, &nDiff );
+
+    if ( !nDiff || !GetUpper()->IsFtnBossFrm() ) // nur innerhalb von Seiten/Spalten
+        return 0L;
+
+    FASTBOOL bBrowse = GetUpper()->GetFmt()->GetDoc()->IsBrowseMode();
+
+    //Der (Page)Body veraendert sich nur im BrowseMode, aber nicht wenn er
+    //Spalten enthaelt.
+    if ( IsPageBodyFrm() && (!bBrowse ||
+          (((SwLayoutFrm*)this)->Lower() &&
+           ((SwLayoutFrm*)this)->Lower()->IsColumnFrm())) )
+        return 0L;
+
+    //In der BrowseView kann der PageFrm selbst ersteinmal einiges von den
+    //Wuenschen abfangen.
+    long nBrowseAdd = 0;
+    if ( bBrowse && GetUpper()->IsPageFrm() ) // nur (Page)BodyFrms
+    {
+        ViewShell *pSh = GetShell();
+        SwLayoutFrm *pUp = GetUpper();
+        long nChg;
+        const long nUpPrtBottom = pUp->Frm().Height() -
+                                  pUp->Prt().Height() - pUp->Prt().Top();
+        SwRect aInva( pUp->Frm() );
+        if ( pSh )
+        {
+            aInva.Pos().X() = pSh->VisArea().Left();
+            aInva.Width( pSh->VisArea().Width() );
+        }
+        if ( nDiff > 0 )
+        {
+            nChg = BROWSE_HEIGHT - pUp->Frm().Height();
+            nChg = Min( nDiff, nChg );
+
+            if ( !IsBodyFrm() )
+            {
+                SetCompletePaint();
+                if ( !pSh || pSh->VisArea().Height() >= pUp->Frm().Height() )
+                {
+                    //Ersteinmal den Body verkleinern. Der waechst dann schon
+                    //wieder.
+                    SwFrm *pBody = ((SwFtnBossFrm*)pUp)->FindBodyCont();
+                    const long nTmp = nChg - pBody->Prt().Height();
+                    if ( !bTst )
+                    {
+                        pBody->Frm().Height(Max( 0L, pBody->Frm().Height() - nChg ));
+                        pBody->_InvalidatePrt();
+                        pBody->_InvalidateSize();
+                        if ( pBody->GetNext() )
+                            pBody->GetNext()->_InvalidatePos();
+                        if ( !IsHeaderFrm() )
+                            pBody->SetCompletePaint();
+                    }
+                    nChg = nTmp <= 0 ? 0 : nTmp;
+                }
+            }
+
+            const long nTmp = nUpPrtBottom + 20;
+            aInva.Top( aInva.Bottom() - nTmp );
+            aInva.Height( nChg + nTmp );
+        }
+        else
+        {
+            //Die Seite kann bis auf 0 schrumpfen. Die erste Seite bleibt
+            //mindestens so gross wie die VisArea.
+            nChg = nDiff;
+            long nInvaAdd = 0;
+            if ( pSh && !pUp->GetPrev() &&
+                 pUp->Frm().Height() + nDiff < pSh->VisArea().Height() )
+            {
+                //Das heisst aber wiederum trotzdem, das wir geeignet invalidieren
+                //muessen.
+                nChg = pSh->VisArea().Height() - pUp->Frm().Height();
+                nInvaAdd = -(nDiff - nChg);
+            }
+
+            //Invalidieren inklusive unterem Rand.
+            long nBorder = nUpPrtBottom + 20;
+            nBorder -= nChg;
+            aInva.Top( aInva.Bottom() - (nBorder+nInvaAdd) );
+            if ( !IsBodyFrm() )
+            {
+                SetCompletePaint();
+                if ( !IsHeaderFrm() )
+                    ((SwFtnBossFrm*)pUp)->FindBodyCont()->SetCompletePaint();
+            }
+            //Wegen der Rahmen die Seite invalidieren. Dadurch wird die Seite
+            //wieder entsprechend gross wenn ein Rahmen nicht passt. Das
+            //funktioniert anderfalls nur zufaellig fuer absatzgebundene Rahmen
+            //(NotifyFlys).
+            pUp->InvalidateSize();
+        }
+        if ( !bTst )
+        {
+            //Unabhaengig von nChg
+            if ( pSh && aInva.HasArea() && pUp->GetUpper() )
+                pSh->InvalidateWindows( aInva );
+        }
+        if ( !bTst && nChg )
+        {
+            const SwRect aOldRect( pUp->Frm() );
+            pUp->Frm().SSize().Height() += nChg;
+            pUp->Prt().SSize().Height() += nChg;
+            if ( pSh )
+                pSh->Imp()->SetFirstVisPageInvalid();
+
+            if ( GetNext() )
+                GetNext()->_InvalidatePos();
+
+            //Ggf. noch ein Repaint ausloesen.
+            const SvxGraphicPosition ePos = pUp->GetFmt()->GetBackground().GetGraphicPos();
+            if ( ePos != GPOS_NONE && ePos != GPOS_TILED )
+                pSh->InvalidateWindows( pUp->Frm() );
+
+            if ( pUp->GetUpper() )
+            {
+                if ( pUp->GetNext() )
+                    pUp->GetNext()->InvalidatePos();
+
+                //Mies aber wahr: im Notify am ViewImp wird evtl. ein Calc
+                //auf die Seite und deren Lower gerufen. Die Werte sollten
+                //unverandert bleiben, weil der Aufrufer bereits fuer die
+                //Anpassung von Frm und Prt sorgen wird.
+                const long nOldFrmHeight = Frm().Height();
+                const long nOldPrtHeight = Prt().Height();
+                const BOOL bOldComplete = IsCompletePaint();
+                if ( IsBodyFrm() )
+                    Prt().SSize().Height() = nOldFrmHeight;
+                ((SwPageFrm*)pUp)->AdjustRootSize( CHG_CHGPAGE, &aOldRect );
+                Frm().SSize().Height() = nOldFrmHeight;
+                Prt().SSize().Height() = nOldPrtHeight;
+                bCompletePaint = bOldComplete;
+            }
+            if ( !IsBodyFrm() )
+                pUp->_InvalidateSize();
+            InvalidatePage( (SwPageFrm*)pUp );
+        }
+        nDiff -= nChg;
+        if ( !nDiff )
+            return nChg;
+        else
+            nBrowseAdd = nChg;
+    }
+
+    const SwFtnBossFrm *pBoss = (SwFtnBossFrm*)GetUpper();
+
+    SwTwips nReal = 0,
+            nAdd  = 0;
+    SwFrm *pFrm = 0;
+    const SzPtr pVar = pVARSIZE;
+
+    if( IsBodyFrm() )
+    {
+        if( IsInSct() )
+        {
+            SwSectionFrm *pSect = FindSctFrm();
+            if( nDiff > 0 && pSect->IsEndnAtEnd() && GetNext() &&
+                GetNext()->IsFtnContFrm() )
+            {
+                SwFtnContFrm* pCont = (SwFtnContFrm*)GetNext();
+                SwTwips nMinH = 0;
+                SwFtnFrm* pFtn = (SwFtnFrm*)pCont->Lower();
+                BOOL bFtn = FALSE;
+                while( pFtn )
+                {
+                    if( !pFtn->GetAttr()->GetFtn().IsEndNote() )
+                    {
+                        nMinH += pFtn->Frm().Height();
+                        bFtn = TRUE;
+                    }
+                    pFtn = (SwFtnFrm*)pFtn->GetNext();
+                }
+                if( bFtn )
+                    nMinH += pCont->Prt().Top();
+                nReal = pCont->Frm().Height() - nMinH;
+                if( nReal > nDiff )
+                    nReal = nDiff;
+                if( nReal > 0 )
+                    pFrm = GetNext();
+                else
+                    nReal = 0;
+            }
+            if( !bTst && !pSect->IsColLocked() )
+                pSect->InvalidateSize();
+        }
+        if( !pFrm )
+            return nBrowseAdd;
+    }
+    else
+    {
+        const BOOL bFtnPage = pBoss->IsPageFrm() && ((SwPageFrm*)pBoss)->IsFtnPage();
+        if ( bFtnPage && !IsFtnContFrm() )
+            pFrm = (SwFrm*)pBoss->FindFtnCont();
+        if ( !pFrm )
+            pFrm = (SwFrm*)pBoss->FindBodyCont();
+
+        if ( !pFrm )
+            return 0;
+
+        //Wenn ich keinen finde eruebrigt sich alles weitere.
+        nReal = pFrm->Frm().SSize().*pVar - nDiff < 0 ?
+                                            pFrm->Frm().SSize().*pVar : nDiff;
+        if( !bFtnPage )
+        {
+            //Minimalgrenze beachten!
+            if( nReal )
+            {
+                const SwTwips nMax = pBoss->GetVarSpace();
+                if ( nReal > nMax )
+                    nReal = nMax;
+            }
+            if( !IsFtnContFrm() && nDiff > nReal &&
+                pFrm->GetNext() && pFrm->GetNext()->IsFtnContFrm() )
+            {
+                //Wenn der Body nicht genuegend her gibt, kann ich noch mal
+                //schauen ob es eine Fussnote gibt, falls ja kann dieser
+                //entsprechend viel gemopst werden.
+                const SwTwips nAddMax = pFrm->GetNext()->Frm().Height();
+                nAdd = nDiff - nReal;
+                if ( nAdd > nAddMax )
+                    nAdd = nAddMax;
+                if ( !bTst )
+                {
+                    pFrm->GetNext()->Frm().SSize().*pVar -= nAdd;
+                    pFrm->GetNext()->InvalidatePrt();
+                    if ( pFrm->GetNext()->GetNext() )
+                        pFrm->GetNext()->GetNext()->_InvalidatePos();
+                }
+            }
+        }
+    }
+
+    if ( !bTst && nReal )
+    {
+        pFrm->Frm().SSize().*pVar -= nReal;
+        pFrm->InvalidatePrt();
+        if ( pFrm->GetNext() )
+            pFrm->GetNext()->_InvalidatePos();
+        if( nReal < 0 && pFrm->IsInSct() )
+        {
+            SwLayoutFrm* pUp = pFrm->GetUpper();
+            if( pUp && 0 != ( pUp = pUp->GetUpper() ) && pUp->IsSctFrm() &&
+                !pUp->IsColLocked() )
+                pUp->InvalidateSize();
+        }
+        if( ( IsHeaderFrm() || IsFooterFrm() ) && pBoss->GetDrawObjs() )
+        {
+            const SwDrawObjs &rObjs = *pBoss->GetDrawObjs();
+            ASSERT( pBoss->IsPageFrm(), "Header/Footer out of page?" );
+            SwPageFrm *pPage = (SwPageFrm*)pBoss;
+            for ( USHORT i = 0; i < rObjs.Count(); ++i )
+            {
+                SdrObject *pObj = rObjs[i];
+                if ( pObj->IsWriterFlyFrame() )
+                {
+                    SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+                    ASSERT( !pFly->IsFlyInCntFrm(), "FlyInCnt at Page?" );
+                    const SwFmtVertOrient &rVert =
+                                        pFly->GetFmt()->GetVertOrient();
+                   // Wann muss invalidiert werden?
+                   // Wenn ein Rahmen am SeitenTextBereich ausgerichtet ist,
+                   // muss bei Aenderung des Headers ein TOP, MIDDLE oder NONE,
+                   // bei Aenderung des Footers ein BOTTOM oder MIDDLE
+                   // ausgerichteter Rahmen seine Position neu berechnen.
+                    if( ( rVert.GetRelationOrient() == PRTAREA ||
+                          rVert.GetRelationOrient() == REL_PG_PRTAREA ) &&
+                        ((IsHeaderFrm() && rVert.GetVertOrient()!=VERT_BOTTOM) ||
+                         (IsFooterFrm() && rVert.GetVertOrient()!=VERT_NONE &&
+                          rVert.GetVertOrient() != VERT_TOP)) )
+                    {
+                        pFly->_InvalidatePos();
+                        pFly->_Invalidate();
+                    }
+                }
+            }
+        }
+    }
+    return (nBrowseAdd + nReal + nAdd);
+}
+
+/*************************************************************************
+|*
+|*  SwFrm::ImplInvalidateSize(), ImplInvalidatePrt(), ImplInvalidatePos(),
+|*         ImplInvalidateLineNum()
+|*
+|*  Ersterstellung      MA 15. Oct. 92
+|*  Letzte Aenderung    MA 24. Mar. 94
+|*
+|*************************************************************************/
+void SwFrm::ImplInvalidateSize()
+{
+    bValidSize = FALSE;
+    if ( IsFlyFrm() )
+        ((SwFlyFrm*)this)->_Invalidate();
+    else
+        InvalidatePage();
+}
+
+void SwFrm::ImplInvalidatePrt()
+{
+    bValidPrtArea = FALSE;
+    if ( IsFlyFrm() )
+        ((SwFlyFrm*)this)->_Invalidate();
+    else
+        InvalidatePage();
+}
+
+void SwFrm::ImplInvalidatePos()
+{
+    bValidPos = FALSE;
+    if ( IsFlyFrm() )
+        ((SwFlyFrm*)this)->_Invalidate();
+    else
+        InvalidatePage();
+}
+
+void SwFrm::ImplInvalidateLineNum()
+{
+    bValidLineNum = FALSE;
+    ASSERT( IsTxtFrm(), "line numbers are implemented for text only" );
+    InvalidatePage();
+}
+
+/*************************************************************************
+|*
+|*  SwFrm::ReinitializeFrmSizeAttrFlags
+|*
+|*  Ersterstellung      MA 15. Oct. 96
+|*  Letzte Aenderung    MA 15. Oct. 96
+|*
+|*************************************************************************/
+void SwFrm::ReinitializeFrmSizeAttrFlags()
+{
+    const SwFmtFrmSize &rFmtSize = GetAttrSet()->GetFrmSize();
+    if ( ATT_VAR_SIZE == rFmtSize.GetSizeType() ||
+         ATT_MIN_SIZE == rFmtSize.GetSizeType())
+    {
+        bFixHeight = bFixWidth = FALSE;
+        if ( GetType() & (FRM_HEADER | FRM_FOOTER | FRM_ROW) )
+        {
+            SwFrm *pFrm = ((SwLayoutFrm*)this)->Lower();
+            while ( pFrm )
+            {   pFrm->_InvalidateSize();
+                pFrm->_InvalidatePrt();
+                pFrm = pFrm->GetNext();
+            }
+            SwCntntFrm *pCnt = ((SwLayoutFrm*)this)->ContainsCntnt();
+            pCnt->InvalidatePage();
+            do
+            {   pCnt->Prepare( PREP_ADJUST_FRM );
+                pCnt->_InvalidateSize();
+                pCnt = pCnt->GetNextCntntFrm();
+            } while ( ((SwLayoutFrm*)this)->IsAnLower( pCnt ) );
+        }
+    }
+    else if ( rFmtSize.GetSizeType() == ATT_FIX_SIZE )
+    {   if ( bVarHeight ) {
+            bFixHeight = FALSE;
+            ChgSize( Size( Frm().Width(), rFmtSize.GetHeight()));
+        }
+        else {
+            bFixWidth = TRUE;
+            ChgSize( Size( rFmtSize.GetWidth(), Frm().Height()));
+        }
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwCntntFrm::GrowFrm()
+|*
+|*  Ersterstellung      MA 30. Jul. 92
+|*  Letzte Aenderung    MA 25. Mar. 99
+|*
+|*************************************************************************/
+SwTwips SwCntntFrm::GrowFrm( SwTwips nDist, const SzPtr pDirection,
+                             BOOL bTst, BOOL bInfo )
+{
+    ASSERT( pDirection == pHeight, "VarSize eines Cntnt ist Breite !?!" );
+
+    if ( Frm().SSize().Height() > 0 &&
+         nDist > (LONG_MAX - Frm().SSize().Height()) )
+        nDist = LONG_MAX - Frm().SSize().Height();
+
+    //Abkuerzung, damit der Growbetrag fuer den Upper nicht umstaendlich
+    //ermittelt werden muss. Die Abfrage korrespondiert mit derjenigen im
+    //SwLayoutFrm::GrowFrm() (wo das Grow fuer alle direkten Upper von CntntFrms
+    //durchlaufen sollte) und trifft genau dann zu, wenn das Grow auf den Upper
+    //sowieso abgeleht wuerde.
+    const FASTBOOL bBrowse = GetUpper()->GetFmt()->GetDoc()->IsBrowseMode();
+    const USHORT nType = bBrowse ? 0x2084: 0x2004; //Row+Cell, Browse mit Body
+    if( !(GetUpper()->GetType() & nType) &&
+        GetUpper()->HasFixSize( pDirection ) )
+    {
+        if ( !bTst )
+        {
+            Frm().SSize().Height() += nDist;
+            if ( GetNext() )
+                GetNext()->InvalidatePos();
+        }
+        return 0;
+    }
+
+    //Der Upper wird nur soweit wie notwendig gegrowed. In nReal wird erstmal
+    //die bereits zur Verfuegung stehende Strecke bereitgestellt.
+    SwTwips nReal = 0;
+
+    //Es bleibt hier beim scheinbar unguenstigen Algorithmus des
+    //Aufzaddierens der Einzelwerte. Alles andere birgt Risiken die jetzt
+    //(04. Jan. 94) nicht vertretbar sind. Die Aufwendigsten und
+    //Haeufigsten Faelle sind oben abgefangen und somit nicht mehr relevant.
+    nReal = GetUpper()->Prt().Height();
+    SwFrm *pFrm = GetUpper()->Lower();
+    while ( pFrm && nReal > 0 )         //MA, #63881# ">0": Genug ist Genug
+    {   nReal -= pFrm->Frm().Height();
+        pFrm = pFrm->GetNext();
+    }
+
+    if ( !bTst )
+    {
+        //Cntnts werden immer auf den gewuenschten Wert gebracht.
+        long nOld = Frm().Height();
+        Frm().SSize().Height() += nDist;
+        if ( nOld && IsInTab() )
+        {
+            SwTabFrm *pTab = FindTabFrm();
+            if ( pTab->GetTable()->GetHTMLTableLayout() &&
+                 !pTab->IsJoinLocked() &&
+                 !pTab->GetFmt()->GetDoc()->GetDocShell()->IsReadOnly() )
+            {
+                pTab->InvalidatePos();
+                pTab->SetResizeHTMLTable();
+            }
+        }
+    }
+
+    //Upper nur growen wenn notwendig.
+    if ( nReal < nDist )
+        nReal = GetUpper() ? GetUpper()->Grow( nDist - (nReal > 0 ? nReal : 0),
+                                               pDirection, bTst, bInfo ) : 0;
+    else
+        nReal = nDist;
+
+    if ( !bTst && GetNext() )
+        GetNext()->InvalidatePos();
+
+    return nReal;
+}
+/*************************************************************************
+|*
+|*  SwCntntFrm::ShrinkFrm()
+|*
+|*  Ersterstellung      MA 30. Jul. 92
+|*  Letzte Aenderung    MA 05. May. 94
+|*
+|*************************************************************************/
+SwTwips SwCntntFrm::ShrinkFrm( SwTwips nDist, const SzPtr pDirection,
+                               BOOL bTst, BOOL bInfo )
+{
+    ASSERT( nDist >= 0, "nDist < 0" );
+    ASSERT( nDist <= Frm().SSize().*pDirection,
+            "nDist > als aktuelle Grosse." );
+    ASSERT( pDirection == pHeight, "VarSize eines Cntnt ist Breite !?!" );
+
+    if ( !bTst )
+    {
+        SwTwips nRstHeight = GetUpper() ? GetUpper()->Frm().Top()
+                            + GetUpper()->Prt().Top()
+                            + GetUpper()->Prt().Height()
+                            - Frm().Top() - Frm().Height() : 0;
+        if( nRstHeight < 0 )
+            nRstHeight = nDist + nRstHeight;
+        else
+            nRstHeight = nDist;
+        Frm().SSize().Height() -= nDist;
+        nDist = nRstHeight;
+        if ( IsInTab() )
+        {
+            SwTabFrm *pTab = FindTabFrm();
+            if ( pTab->GetTable()->GetHTMLTableLayout() &&
+                 !pTab->IsJoinLocked() &&
+                 !pTab->GetFmt()->GetDoc()->GetDocShell()->IsReadOnly() )
+            {
+                pTab->InvalidatePos();
+                pTab->SetResizeHTMLTable();
+            }
+        }
+    }
+
+    const SwTwips nReal = GetUpper() && nDist > 0 ?
+            GetUpper()->Shrink( nDist, pDirection, bTst, bInfo ) : 0;
+
+    if ( !bTst )
+    {
+        //Die Position des naechsten Frm's veraendert sich auf jeden Fall.
+        InvalidateNextPos();
+
+        //Wenn ich keinen Nachfolger habe, so muss ich mich eben selbst um
+        //die Retusche kuemmern.
+        if ( !GetNext() )
+            SetRetouche();
+    }
+    return nReal;
+}
+
+/*************************************************************************
+|*
+|*    SwCntntFrm::Modify()
+|*
+|*    Beschreibung
+|*    Ersterstellung    AK 05-Mar-1991
+|*    Letzte Aenderung  MA 13. Oct. 95
+|*
+|*************************************************************************/
+void SwCntntFrm::Modify( SfxPoolItem * pOld, SfxPoolItem * pNew )
+{
+    BYTE nInvFlags = 0;
+
+    if( pNew && RES_ATTRSET_CHG == pNew->Which() )
+    {
+        SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() );
+        SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() );
+        SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld );
+        SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew );
+        while( TRUE )
+        {
+            _UpdateAttr( (SfxPoolItem*)aOIter.GetCurItem(),
+                         (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags,
+                         &aOldSet, &aNewSet );
+            if( aNIter.IsAtEnd() )
+                break;
+            aNIter.NextItem();
+            aOIter.NextItem();
+        }
+        if ( aOldSet.Count() || aNewSet.Count() )
+            SwFrm::Modify( &aOldSet, &aNewSet );
+    }
+    else
+        _UpdateAttr( pOld, pNew, nInvFlags );
+
+    if ( nInvFlags != 0 )
+    {
+        SwPageFrm *pPage = FindPageFrm();
+        InvalidatePage( pPage );
+        if ( nInvFlags & 0x01 )
+            SetCompletePaint();
+        if ( nInvFlags & 0x02 )
+            _InvalidatePos();
+        if ( nInvFlags & 0x04 )
+            _InvalidateSize();
+        if ( nInvFlags & 0x88 )
+        {
+            if( IsInSct() && !GetPrev() )
+            {
+                SwSectionFrm *pSect = FindSctFrm();
+                if( pSect->ContainsAny() == this )
+                {
+                    pSect->_InvalidatePrt();
+                    pSect->InvalidatePage( pPage );
+                }
+            }
+            _InvalidatePrt();
+        }
+        SwFrm *pTmp;
+        if ( 0 != (pTmp = GetIndNext()) && nInvFlags & 0x10)
+        {
+            pTmp->_InvalidatePrt();
+            pTmp->InvalidatePage( pPage );
+        }
+        if ( nInvFlags & 0x80 && pTmp )
+            pTmp->SetCompletePaint();
+        if ( nInvFlags & 0x20 && 0 != (pTmp = GetPrev()) )
+        {
+            pTmp->_InvalidatePrt();
+            pTmp->InvalidatePage( pPage );
+        }
+        if ( nInvFlags & 0x40 )
+            InvalidateNextPos();
+    }
+}
+
+void SwCntntFrm::_UpdateAttr( SfxPoolItem* pOld, SfxPoolItem* pNew,
+                              BYTE &rInvFlags,
+                            SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet )
+{
+    BOOL bClear = TRUE;
+    USHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
+    switch ( nWhich )
+    {
+        case RES_FMT_CHG:
+            rInvFlags = 0xFF;
+            /* kein break hier */
+
+        case RES_PAGEDESC:                      //Attributaenderung (an/aus)
+            if ( IsInDocBody() && !IsInTab() )
+            {
+                rInvFlags |= 0x02;
+                SwPageFrm *pPage = FindPageFrm();
+                if ( !GetPrev() )
+                    CheckPageDescs( pPage );
+                if ( pPage && GetAttrSet()->GetPageDesc().GetNumOffset() )
+                    ((SwRootFrm*)pPage->GetUpper())->SetVirtPageNum( TRUE );
+                SwDocPosUpdate aMsgHnt( pPage->Frm().Top() );
+                pPage->GetFmt()->GetDoc()->UpdatePageFlds( &aMsgHnt );
+            }
+            break;
+
+        case RES_UL_SPACE:
+            {
+                if( IsInFtn() && !GetIndNext() )
+                {
+                    SwFrm* pNxt = FindNext();
+                    if( pNxt )
+                    {
+                        SwPageFrm* pPg = pNxt->FindPageFrm();
+                        pNxt->InvalidatePage( pPg );
+                        pNxt->_InvalidatePrt();
+                        if( pNxt->IsSctFrm() )
+                        {
+                            SwFrm* pCnt = ((SwSectionFrm*)pNxt)->ContainsAny();
+                            if( pCnt )
+                            {
+                                pCnt->_InvalidatePrt();
+                                pCnt->InvalidatePage( pPg );
+                            }
+                        }
+                        pNxt->SetCompletePaint();
+                    }
+                }
+                Prepare( PREP_UL_SPACE );   //TxtFrm muss Zeilenabst. korrigieren.
+                rInvFlags |= 0x80;
+                /* kein Break hier */
+            }
+        case RES_LR_SPACE:
+        case RES_BOX:
+        case RES_SHADOW:
+            Prepare( PREP_FIXSIZE_CHG );
+            SwFrm::Modify( pOld, pNew );
+            rInvFlags |= 0x30;
+            break;
+
+        case RES_BREAK:
+            {
+                rInvFlags |= 0x42;
+                if( GetAttrSet()->GetDoc()->IsParaSpaceMax() ||
+                    GetAttrSet()->GetDoc()->IsParaSpaceMaxAtPages() )
+                {
+                    rInvFlags |= 0x1;
+                    SwFrm* pNxt = FindNext();
+                    if( pNxt )
+                    {
+                        SwPageFrm* pPg = pNxt->FindPageFrm();
+                        pNxt->InvalidatePage( pPg );
+                        pNxt->_InvalidatePrt();
+                        if( pNxt->IsSctFrm() )
+                        {
+                            SwFrm* pCnt = ((SwSectionFrm*)pNxt)->ContainsAny();
+                            if( pCnt )
+                            {
+                                pCnt->_InvalidatePrt();
+                                pCnt->InvalidatePage( pPg );
+                            }
+                        }
+                        pNxt->SetCompletePaint();
+                    }
+                }
+            }
+            break;
+
+        case RES_PARATR_TABSTOP:
+        case RES_CHRATR_PROPORTIONALFONTSIZE:
+        case RES_CHRATR_SHADOWED:
+        case RES_CHRATR_AUTOKERN:
+        case RES_CHRATR_UNDERLINE:
+        case RES_CHRATR_KERNING:
+        case RES_CHRATR_FONT:
+        case RES_CHRATR_FONTSIZE:
+        case RES_CHRATR_ESCAPEMENT:
+        case RES_CHRATR_CONTOUR:
+            rInvFlags |= 0x01;
+            break;
+
+
+        case RES_FRM_SIZE:
+            rInvFlags |= 0x01;
+            /* no break here */
+
+        default:
+            bClear = FALSE;
+    }
+    if ( bClear )
+    {
+        if ( pOldSet || pNewSet )
+        {
+            if ( pOldSet )
+                pOldSet->ClearItem( nWhich );
+            if ( pNewSet )
+                pNewSet->ClearItem( nWhich );
+        }
+        else
+            SwFrm::Modify( pOld, pNew );
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwLayoutFrm::SwLayoutFrm()
+|*
+|*  Ersterstellung      AK 14-Feb-1991
+|*  Letzte Aenderung    MA 12. May. 95
+|*
+|*************************************************************************/
+SwLayoutFrm::SwLayoutFrm( SwFrmFmt* pFmt ):
+    SwFrm( pFmt ),
+    pLower( 0 )
+{
+    nType = FRM_LAYOUT;
+
+    const SwFmtFrmSize &rFmtSize = pFmt->GetFrmSize();
+    if ( rFmtSize.GetSizeType() == ATT_FIX_SIZE )
+        bFixHeight = TRUE;
+}
+
+/*-----------------10.06.99 09:42-------------------
+ * SwLayoutFrm::InnerHeight()
+ * --------------------------------------------------*/
+
+SwTwips SwLayoutFrm::InnerHeight() const
+{
+    if( !Lower() )
+        return 0;
+    SwTwips nRet = 0;
+    const SwFrm* pCnt = Lower();
+    if( pCnt->IsColumnFrm() || pCnt->IsCellFrm() )
+    {
+        do
+        {
+            SwTwips nTmp = ((SwLayoutFrm*)pCnt)->InnerHeight();
+            if( pCnt->GetValidPrtAreaFlag() )
+                nTmp += pCnt->Frm().Height() - pCnt->Prt().Height();
+            if( nRet < nTmp )
+                nRet = nTmp;
+            pCnt = pCnt->GetNext();
+        } while ( pCnt );
+    }
+    else
+    {
+        do
+        {
+            nRet += pCnt->Frm().Height();
+            if( pCnt->IsCntntFrm() && ((SwTxtFrm*)pCnt)->IsUndersized() )
+                nRet += ((SwTxtFrm*)pCnt)->GetParHeight() - pCnt->Prt().Height();
+            if( pCnt->IsLayoutFrm() && !pCnt->IsTabFrm() )
+                nRet += ((SwLayoutFrm*)pCnt)->InnerHeight()-pCnt->Prt().Height();
+            pCnt = pCnt->GetNext();
+        } while( pCnt );
+
+    }
+    return nRet;
+}
+
+/*************************************************************************
+|*
+|*  SwLayoutFrm::GrowFrm()
+|*
+|*  Ersterstellung      MA 30. Jul. 92
+|*  Letzte Aenderung    MA 23. Sep. 96
+|*
+|*************************************************************************/
+SwTwips SwLayoutFrm::GrowFrm( SwTwips nDist, const SzPtr pDirection,
+                              BOOL bTst, BOOL bInfo )
+{
+    //CellFrms geben das Grow auf jedenfall mal an ihren Upper weiter, sie
+    //zwar in jedem Fall in beiden Richtungen Fix, aber vielleicht schafft
+    //die Row ja den benoetigten Platz.
+    //Auch ColumnFrms koennen es auf einen Versuch ankommen lassen,
+    const FASTBOOL bBrowse = GetFmt()->GetDoc()->IsBrowseMode();
+    const USHORT nType = bBrowse ? 0x2084: 0x2004; //Row+Cell, Browse mit Body
+    if( !(GetType() & nType) && HasFixSize( pDirection ) )
+        return 0;
+
+    if ( Frm().SSize().*pDirection > 0 &&
+         nDist > (LONG_MAX - Frm().SSize().*pDirection) )
+        nDist = LONG_MAX - Frm().SSize().*pDirection;
+
+    SwTwips nMin = 0; //Bis zur Upper-Groesse kann ich auf jedenfall auffuellen.
+    if ( GetUpper() )
+    {
+        //Wenn die VarSize nicht der Direction entspricht, so ist
+        //es eben die FixSize; ich brauche dann nicht die Kette
+        //zu messen sondern muss lediglich den Upper betrachen.
+        if ( pDirection == (bVarHeight ? pHeight : pWidth) )
+        {
+            SwFrm *pFrm = GetUpper()->Lower();
+            while ( pFrm )
+            {   nMin += pFrm->Frm().SSize().*pDirection;
+                pFrm = pFrm->GetNext();
+            }
+        }
+        else
+            nMin = Frm().SSize().*pDirection;
+        nMin = GetUpper()->Prt().SSize().*pDirection - nMin;
+        if ( nMin < 0 )
+            nMin = 0;
+    }
+
+    if ( !bTst )
+        Frm().SSize().*pDirection += nDist;
+
+    //Natuerlich braucht der Upper nur soweit wie wirklich notwendig
+    //ge'grow'ed zu werden.
+    SwTwips nReal = nDist - nMin;
+
+    if ( nReal > 0 )
+    {
+        if ( GetUpper() )
+        {   // AdjustNeighbourhood jetzt auch in Spalten (aber nicht in Rahmen)
+            BYTE nAdjust = GetUpper()->IsFtnBossFrm() ?
+                ((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this )
+                : NA_GROW_SHRINK;
+            if( NA_ONLY_ADJUST == nAdjust )
+                nReal = AdjustNeighbourhood( nReal, bTst );
+            else
+            {
+                SwTwips nGrow = 0;
+                if( NA_ADJUST_GROW == nAdjust )
+                    nReal += AdjustNeighbourhood( nReal - nGrow, bTst );
+                if( nGrow < nReal )
+                    nGrow += GetUpper()->Grow( nReal - nGrow, pDirection,
+                                               bTst, bInfo );
+                if( NA_GROW_ADJUST == nAdjust && nGrow < nReal )
+                    nReal += AdjustNeighbourhood( nReal - nGrow, bTst );
+                if ( IsFtnFrm() && (nGrow != nReal) && GetNext() )
+                {
+                    //Fussnoten koennen ihre Nachfolger verdraengen.
+                    SwTwips nSpace = bTst ? 0 : -nDist;
+                    const SwFrm *pFrm = GetUpper()->Lower();
+                    do
+                    {   nSpace += pFrm->Frm().Height();
+                        pFrm = pFrm->GetNext();
+                    } while ( pFrm != GetNext() );
+                    nSpace = GetUpper()->Prt().Height() - nSpace;
+                    if ( nSpace < 0 )
+                        nSpace = 0;
+                    nSpace += nGrow;
+                    if ( nReal > nSpace )
+                        nReal = nSpace;
+                    if ( nReal && !bTst )
+                        ((SwFtnFrm*)this)->InvalidateNxtFtnCnts( FindPageFrm() );
+                }
+                else
+                    nReal = nGrow;
+            }
+        }
+        else
+            nReal = 0;
+
+        nReal += nMin;
+    }
+    else
+        nReal = nDist;
+
+    if ( !bTst )
+    {
+        if ( (nReal != nDist) &&
+             (!IsCellFrm() || (IsCellFrm() && (pDirection == pWidth))) )
+            //Den masslosen Wunsch koennen wir leider nur teilweise erfuellen,
+            //Zellen werden bei Veraenderungen der Hoehe direkt von der Row
+            //angepasst.
+            Frm().SSize().*pDirection -= (nDist - nReal);
+
+        if ( nReal )
+        {
+            SwPageFrm *pPage = FindPageFrm();
+            if ( GetNext() )
+            {
+                GetNext()->_InvalidatePos();
+                if ( GetNext()->IsCntntFrm() )
+                    GetNext()->InvalidatePage( pPage );
+            }
+            if ( !IsPageBodyFrm() )
+            {
+                _InvalidateAll();
+                InvalidatePage( pPage );
+            }
+            if ( !(GetType() & 0x1823) ) //Tab, Row, FtnCont, Root, Page
+                NotifyFlys();
+
+            if( IsCellFrm() )
+                InvaPercentLowers();
+
+            const SvxGraphicPosition ePos = GetFmt()->GetBackground().GetGraphicPos();
+            if ( GPOS_NONE != ePos && GPOS_TILED != ePos )
+                SetCompletePaint();
+        }
+    }
+    return nReal;
+}
+/*************************************************************************
+|*
+|*  SwLayoutFrm::ShrinkFrm()
+|*
+|*  Ersterstellung      MA 30. Jul. 92
+|*  Letzte Aenderung    MA 25. Mar. 99
+|*
+|*************************************************************************/
+SwTwips SwLayoutFrm::ShrinkFrm( SwTwips nDist, const SzPtr pDirection,
+                                BOOL bTst, BOOL bInfo )
+{
+    //CellFrms geben das Shrink auf jedenfall mal an ihren Upper weiter,
+    //sie sind zwar in beiden Richtungen fix, aber Upper wirds schon richten.
+    //Auch ColumnFrms koennen es auf einen Versuch ankommen lassen,
+    const FASTBOOL bBrowse = GetFmt()->GetDoc()->IsBrowseMode();
+    const USHORT nType = bBrowse ? 0x2084: 0x2004; //Row+Cell, Browse mit Body
+    if( !(GetType() & nType) && HasFixSize( pDirection ) )
+        return 0;
+
+    ASSERT( nDist >= 0, "nDist < 0" );
+
+    if ( nDist > Frm().SSize().*pDirection )
+        nDist = Frm().SSize().*pDirection;
+
+    //Es gilt eine unuebersichtliche Situation zu vermeiden:
+    //Der Inhalt kann nach dem Shrink noch immer groesser als der Frm
+    //bzw. seine PrtArea sein; in diesem Fall wird das Shrink auf den
+    //Inhalt beschraenkt bzw. abgelehnt wenn ein Wachtstum notwendig waere.
+    SwTwips nMin = 0;
+    if ( Lower() )
+    {
+        if ( pDirection == (Lower()->bVarHeight ? pHeight : pWidth) )
+        {   const SwFrm *pFrm = Lower();
+            const long nTmp = Prt().SSize().*pDirection; //MA #63881#: Genug ist Genug
+            while ( pFrm && nMin < nTmp )
+            {   nMin += pFrm->Frm().SSize().*pDirection;
+                pFrm = pFrm->GetNext();
+            }
+        }
+    }
+    SwTwips nReal = nDist;
+    if ( nReal > (Prt().SSize().*pDirection - nMin) )
+        nReal = Prt().SSize().*pDirection - nMin;
+    if ( nReal <= 0 )
+        return nDist;
+
+    SwTwips nRealDist = nReal;
+    if ( !bTst )
+        Frm().SSize().*pDirection -= nReal;
+
+    BYTE nAdjust = GetUpper() && GetUpper()->IsFtnBossFrm() ?
+                   ((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this )
+                   : NA_GROW_SHRINK;
+
+    // AdjustNeighbourhood auch in Spalten (aber nicht in Rahmen)
+    if( NA_ONLY_ADJUST == nAdjust )
+    {
+        if ( IsPageBodyFrm() && !bBrowse )
+            nReal = nDist;
+        else
+        {   nReal = AdjustNeighbourhood( -nReal, bTst );
+            nReal *= -1;
+            if ( !bTst && IsBodyFrm() && nReal < nRealDist )
+                Frm().SSize().*pDirection += nRealDist - nReal;
+        }
+    }
+    else if ( (IsCellFrm() && !(pDirection == pHeight)) || IsColumnFrm() || IsColBodyFrm() )
+    {   //Columns und auch ColumnBodies schrumpfen nur soweit wie es der Upper mitmacht.
+        //Zellen auch, in der Hoehe werden sie aber direkt vom Upper
+        //zurechtgewiesen, brauchen sich also hier nicht zu korrigieren.
+        SwTwips nTmp = GetUpper()->Shrink( nReal, pDirection, bTst, bInfo );
+        if ( nTmp != nReal )
+        {
+            Frm().SSize().*pDirection += nReal - nTmp;
+            nReal = nTmp;
+        }
+    }
+    else
+    {
+        SwTwips nShrink = nReal;
+        nReal = GetUpper() ?
+                    GetUpper()->Shrink( nShrink, pDirection, bTst, bInfo ) : 0;
+        if( ( NA_GROW_ADJUST == nAdjust || NA_ADJUST_GROW == nAdjust )
+            && nReal < nShrink )
+            AdjustNeighbourhood( nReal - nShrink );
+    }
+
+    if ( !bTst && (IsCellFrm() || IsColumnFrm() ? nReal : nRealDist) )
+    {
+        SwPageFrm *pPage = FindPageFrm();
+        if ( GetNext() )
+        {
+            GetNext()->_InvalidatePos();
+            if ( GetNext()->IsCntntFrm() )
+                GetNext()->InvalidatePage( pPage );
+            if ( IsTabFrm() )
+                ((SwTabFrm*)this)->SetComplete();
+        }
+        else
+        {   if ( IsRetoucheFrm() )
+                SetRetouche();
+            if ( IsTabFrm() )
+            {
+                if( IsTabFrm() )
+                    ((SwTabFrm*)this)->SetComplete();
+                if ( Lower() )  //Kann auch im Join stehen und leer sein!
+                    InvalidateNextPos();
+            }
+        }
+        if ( !IsBodyFrm() )
+        {
+            _InvalidateAll();
+            InvalidatePage( pPage );
+            const SvxGraphicPosition ePos = GetFmt()->GetBackground().GetGraphicPos();
+            if ( GPOS_NONE != ePos && GPOS_TILED != ePos )
+                SetCompletePaint();
+        }
+
+        if ( !(GetType() & 0x1823) ) //Tab, Row, FtnCont, Root, Page
+            NotifyFlys();
+
+        if( IsCellFrm() )
+            InvaPercentLowers();
+
+        if( IsFtnFrm() && !((SwFtnFrm*)this)->GetAttr()->GetFtn().IsEndNote() &&
+            ( GetFmt()->GetDoc()->GetFtnInfo().ePos != FTNPOS_CHAPTER ||
+              ( IsInSct() && FindSctFrm()->IsFtnAtEnd() ) ) )
+        {
+
+            SwCntntFrm *pCnt = ((SwFtnFrm*)this)->GetRef();
+            ASSERT( pCnt, "Ftn ohne Ref." );
+            if ( pCnt->IsFollow() )
+            {   // Wenn wir sowieso schon in einer anderen Spalte/Seite sitzen
+                // als der Frame mit der Referenz, dann brauchen wir nicht
+                // auch noch seinen Master zu invalidieren.
+                SwFrm *pTmp = pCnt->FindFtnBossFrm(TRUE) == FindFtnBossFrm(TRUE)
+                              ?  pCnt->FindMaster()->GetFrm() : pCnt;
+                pTmp->Prepare( PREP_ADJUST_FRM );
+                pTmp->InvalidateSize();
+            }
+            else
+                pCnt->InvalidatePos();
+        }
+    }
+    return nReal;
+}
+/*************************************************************************
+|*
+|*  SwLayoutFrm::ChgLowersProp()
+|*
+|*  Beschreibung        Aendert die Grosse der direkt untergeordneten Frm's
+|*      die eine Fixe Groesse haben, proportional zur Groessenaenderung der
+|*      PrtArea des Frm's.
+|*      Die Variablen Frm's werden auch proportional angepasst; sie werden
+|*      sich schon wieder zurechtwachsen/-schrumpfen.
+|*  Ersterstellung      MA 11.03.92
+|*  Letzte Aenderung    AMA 2. Nov. 98
+|*
+|*************************************************************************/
+void SwLayoutFrm::ChgLowersProp( const Size& rOldSize )
+{
+    if ( IsRootFrm() || !Lower() )
+        return;
+
+    BOOL bInvaCntnt = TRUE; //Einmal die Seite benachrichtigen.
+    SwFrm *pFrm = Lower();
+    const BOOL bHeightChgd = rOldSize.Height() != Prt().Height();
+    const BOOL bWidthChgd  = rOldSize.Width()  != Prt().Width();
+
+    //Abkuerzung fuer Body-Inhalt
+    if( IsBodyFrm() && IsInDocBody() && !Lower()->IsColumnFrm() && !bWidthChgd
+        && ( !IsInSct() || !FindSctFrm()->IsColLocked() ) )
+    {
+        SwPageFrm *pPage = FindPageFrm();
+        if( pFrm )
+        {
+            do
+            {
+                if( pFrm->IsSctFrm() &&((SwSectionFrm*)pFrm)->_ToMaximize() )
+                {
+                    pFrm->_InvalidateSize();
+                    pFrm->InvalidatePage( pPage );
+                }
+                if( pFrm->GetNext() )
+                    pFrm = pFrm->GetNext();
+                else
+                    break;
+            } while( TRUE );
+            while( pFrm->IsSctFrm() && !((SwSectionFrm*)pFrm)->GetSection() &&
+                   pFrm->GetPrev() )
+                pFrm = pFrm->GetPrev();
+            if( pFrm->IsSctFrm() )
+                pFrm = ((SwSectionFrm*)pFrm)->GetSection() &&
+                       !((SwSectionFrm*)pFrm)->ToMaximize( FALSE ) ?
+                       ((SwSectionFrm*)pFrm)->FindLastCntnt() : NULL;
+        }
+        if ( pFrm )
+        {
+            if ( pFrm->IsInTab() )
+                pFrm = pFrm->FindTabFrm();
+            if ( rOldSize.Height() < Prt().Height() )
+            {
+                //Wenn der Body gewachsen ist, genuegt es den auf den letzten
+                //und den darauf folgenden geeignet zu invalidieren.
+                pFrm->_InvalidateAll();
+                pFrm->InvalidatePage( pPage );
+                if( !pFrm->IsFlowFrm() ||
+                    !SwFlowFrm::CastFlowFrm( pFrm )->HasFollow() )
+                    pFrm->InvalidateNextPos( TRUE );
+                if ( pFrm->IsTxtFrm() )
+                    ((SwCntntFrm*)pFrm)->Prepare( PREP_ADJUST_FRM );
+                if ( pFrm->IsInSct() )
+                {
+                    pFrm = pFrm->FindSctFrm();
+                    if( IsAnLower( pFrm ) )
+                    {
+                        pFrm->_InvalidateSize();
+                        pFrm->InvalidatePage( pPage );
+                    }
+                }
+            }
+            else
+            {
+                //Anderfalls werden alle herausragenden in ihrer Position
+                //invalidiert und nur der letzte noch (teilweise) passende
+                //Adjustiert.
+                SwTwips nBot = Frm().Top() + Prt().Bottom();
+                while ( pFrm->GetPrev() && pFrm->Frm().Top() > nBot )
+                {
+                    pFrm->_InvalidateAll();
+                    pFrm->InvalidatePage( pPage );
+                    pFrm = pFrm->GetPrev();
+                }
+                if ( pFrm )
+                {
+                    pFrm->_InvalidateSize();
+                    pFrm->InvalidatePage( pPage );
+                    if ( pFrm->IsTxtFrm() )
+                        ((SwCntntFrm*)pFrm)->Prepare( PREP_ADJUST_FRM );
+                    if ( pFrm->IsInSct() )
+                    {
+                        pFrm = pFrm->FindSctFrm();
+                        if( IsAnLower( pFrm ) )
+                        {
+                            pFrm->_InvalidateSize();
+                            pFrm->InvalidatePage( pPage );
+                        }
+                    }
+                }
+            }
+        }
+        return;
+    }
+
+    BOOL  bFixChgd, bVarChgd;
+    if ( pFrm->bVarHeight )
+    {
+        bFixChgd = bWidthChgd;
+        bVarChgd = bHeightChgd;
+    }
+    else
+    {
+        bFixChgd = bHeightChgd;
+        bVarChgd = bWidthChgd;
+    }
+    while ( pFrm )
+    {   //TxtFrms werden invalidiert, andere werden nur proportional angepasst.
+        if ( pFrm->IsTxtFrm() )
+        {
+            if ( bFixChgd )
+                ((SwCntntFrm*)pFrm)->Prepare( PREP_FIXSIZE_CHG );
+            if ( bVarChgd )
+                ((SwCntntFrm*)pFrm)->Prepare( PREP_ADJUST_FRM );
+        }
+        else if ( !(pFrm->GetType() & (FRM_TAB|FRM_ROW|FRM_CELL|FRM_SECTION)) )
+        {
+            //Der Frame wird Proportional angepasst.
+            //Die FixSize des Lowers wird direkt an die neue Groesse
+            //angepasst, so werden Rundungsfehler vermieden.
+
+            //Neue Breite
+            if ( bWidthChgd )
+            {
+                if ( pFrm->bVarHeight )
+                    pFrm->Frm().Width( Prt().Width() );
+                else if ( (pFrm->GetType() & FRM_COLUMN) && rOldSize.Width() )
+                    pFrm->Frm().Width( (pFrm->Frm().Width() * Prt().Width()) /
+                                       rOldSize.Width() );
+            }
+            //Neue Hoehe
+            if ( bHeightChgd )
+            {
+                if ( !pFrm->bVarHeight )
+                    pFrm->Frm().Height( Prt().Height() );
+                else if ( (pFrm->GetType() & FRM_COLUMN) && rOldSize.Height() )
+                    pFrm->Frm().Height( (pFrm->Frm().Height() * Prt().Height()) /
+                                        rOldSize.Height() );
+            }
+        }
+        pFrm->_InvalidateAll();
+        if ( bInvaCntnt && pFrm->IsCntntFrm() )
+            pFrm->InvalidatePage();
+
+        if ( !pFrm->GetNext() && pFrm->IsRetoucheFrm() )
+        {
+            //Wenn ein Wachstum stattgefunden hat, und die untergeordneten
+            //zur Retouche faehig sind (derzeit Tab, Section und Cntnt), so
+            //trigger ich sie an.
+            if ( rOldSize.Height() < Prt().SSize().Height() ||
+                 rOldSize.Width() < Prt().SSize().Width() )
+                pFrm->SetRetouche();
+        }
+        pFrm = pFrm->GetNext();
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwLayoutFrm::Format()
+|*
+|*  Beschreibung:       "Formatiert" den Frame; Frm und PrtArea.
+|*                      Die Fixsize wird hier nicht eingestellt.
+|*  Ersterstellung      MA 28. Jul. 92
+|*  Letzte Aenderung    MA 21. Mar. 95
+|*
+|*************************************************************************/
+void SwLayoutFrm::Format( const SwBorderAttrs *pAttrs )
+{
+    ASSERT( pAttrs, "LayoutFrm::Format, pAttrs ist 0." );
+
+    if ( bValidPrtArea && bValidSize )
+        return;
+
+    const USHORT nLR = pAttrs->CalcLeft( this ) + pAttrs->CalcRight();
+    const USHORT nUL = pAttrs->CalcTop()  + pAttrs->CalcBottom();
+
+    if ( !bValidPrtArea )
+    {
+        bValidPrtArea = TRUE;
+
+        //Position einstellen.
+        aPrt.Left( pAttrs->CalcLeft( this ) );
+        aPrt.Top ( pAttrs->CalcTop()  );
+
+        //Sizes einstellen; die Groesse gibt der umgebende Frm vor, die
+        //die Raender werden einfach abgezogen.
+        aPrt.Width ( aFrm.Width() - nLR );
+        aPrt.Height( aFrm.Height()- nUL );
+    }
+
+    if ( !bValidSize )
+    {
+        const SzPtr pVarSz = pVARSIZE;
+        if ( !HasFixSize( pVarSz ) )
+        {
+            const SwTwips nBorder = bVarHeight ? nUL : nLR;
+            const PtPtr pVarPs = pVARPOS;
+            const SwFmtFrmSize &rSz = GetFmt()->GetFrmSize();
+            SwTwips nMinHeight = rSz.GetSizeType() == ATT_MIN_SIZE ? rSz.GetHeight() : 0;
+            do
+            {   bValidSize = TRUE;
+
+                //Die Groesse in der VarSize wird durch den Inhalt plus den
+                //Raendern bestimmt.
+                SwTwips nRemaining = 0;
+                SwFrm *pFrm = Lower();
+                while ( pFrm )
+                {   nRemaining += pFrm->Frm().SSize().*pVarSz;
+                    if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() )
+                    // Dieser TxtFrm waere gern ein bisschen groesser
+                        nRemaining += ((SwTxtFrm*)pFrm)->GetParHeight()
+                                      - pFrm->Prt().Height();
+                    else if( pFrm->IsSctFrm() && ((SwSectionFrm*)pFrm)->IsUndersized() )
+                        nRemaining += ((SwSectionFrm*)pFrm)->Undersize();
+                    pFrm = pFrm->GetNext();
+                }
+                nRemaining += nBorder;
+                nRemaining = Max( nRemaining, nMinHeight );
+                const SwTwips nDiff = nRemaining - Frm().SSize().*pVarSz;
+                const Point aOldPos = Frm().Pos();
+                if ( nDiff )
+                {
+                    if ( nDiff > 0 )
+                        Grow( nDiff, pVarSz );
+                    else
+                        Shrink( -nDiff, pVarSz );
+                    //Schnell auf dem kurzen Dienstweg die Position updaten.
+                    MakePos();
+                }
+                //Unterkante des Uppers nicht ueberschreiten.
+                if ( GetUpper() && Frm().SSize().*pVarSz )
+                {
+                    const SwTwips nDeadLine = GetUpper()->Frm().Top() +
+                        GetUpper()->Prt().Top() + GetUpper()->Prt().Height();
+                    const SwTwips nBot = Frm().Top() + Frm().Height();
+                    if ( nBot > nDeadLine )
+                    {
+                        Frm().Height( nDeadLine - Frm().Top() );
+                        Prt().SSize().Height() = Frm().SSize().Height() - nBorder;
+                        if ( Frm().Pos() == aOldPos )
+                            bValidSize = bValidPrtArea = TRUE;
+                    }
+                }
+            } while ( !bValidSize );
+        }
+        else if ( GetType() & 0x0018 )
+        {
+            do
+            {   if ( Frm().Height() != pAttrs->GetSize().Height() )
+                    ChgSize( Size( Frm().Width(), pAttrs->GetSize().Height()));
+                bValidSize = TRUE;
+                MakePos();
+            } while ( !bValidSize );
+        }
+        else
+            bValidSize = TRUE;
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwLayoutFrm::InvalidatePercentLowers()
+|*
+|*  Ersterstellung      MA 13. Jun. 96
+|*  Letzte Aenderung    MA 13. Jun. 96
+|*
+|*************************************************************************/
+static void InvaPercentFlys( SwFrm *pFrm )
+{
+    ASSERT( pFrm->GetDrawObjs(), "Can't find any Objects" );
+    for ( USHORT i = 0; i < pFrm->GetDrawObjs()->Count(); ++i )
+    {
+        SdrObject *pO = (*pFrm->GetDrawObjs())[i];
+        if ( pO->IsWriterFlyFrame() )
+        {
+            SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+            const SwFmtFrmSize &rSz = pFly->GetFmt()->GetFrmSize();
+            if ( rSz.GetWidthPercent() || rSz.GetHeightPercent() )
+                pFly->InvalidateSize();
+        }
+    }
+}
+
+void SwLayoutFrm::InvaPercentLowers()
+{
+    if ( GetDrawObjs() )
+        ::InvaPercentFlys( this );
+
+    SwFrm *pFrm = ContainsCntnt();
+    if ( pFrm )
+        do
+        {
+            if ( pFrm->IsInTab() && !IsTabFrm() )
+            {
+                SwFrm *pTmp = pFrm->FindTabFrm();
+                ASSERT( pTmp, "Where's my TabFrm?" );
+                if( IsAnLower( pTmp ) )
+                    pFrm = pTmp;
+            }
+
+            if ( pFrm->IsTabFrm() )
+            {
+                const SwFmtFrmSize &rSz = ((SwLayoutFrm*)pFrm)->GetFmt()->GetFrmSize();
+                if ( rSz.GetWidthPercent() || rSz.GetHeightPercent() )
+                    pFrm->InvalidatePrt();
+            }
+            else if ( pFrm->GetDrawObjs() )
+                ::InvaPercentFlys( pFrm );
+            pFrm = pFrm->FindNextCnt();
+        } while ( pFrm && IsAnLower( pFrm ) ) ;
+}
+
+/*************************************************************************
+|*
+|*  SwLayoutFrm::CalcRel()
+|*
+|*  Ersterstellung      MA 13. Jun. 96
+|*  Letzte Aenderung    MA 10. Oct. 96
+|*
+|*************************************************************************/
+long SwLayoutFrm::CalcRel( const SwFmtFrmSize &rSz, BOOL bWidth ) const
+{
+    ASSERT( bWidth, "NonFlys, CalcRel: width only" );
+
+    long nRet     = rSz.GetWidth(),
+         nPercent = rSz.GetWidthPercent();
+
+    if ( nPercent )
+    {
+        const SwFrm *pRel = GetUpper();
+        long nRel = LONG_MAX;
+        const ViewShell *pSh = GetShell();
+        if ( pRel->IsPageBodyFrm() && GetFmt()->GetDoc()->IsBrowseMode() &&
+             pSh && pSh->VisArea().Width())
+        {
+            nRel = pSh->VisArea().Width();
+            const Size aBorder = pSh->GetOut()->PixelToLogic( pSh->GetBrowseBorder() );
+            nRel -= 2*aBorder.Width();
+            long nDiff = nRel - pRel->Prt().Width();
+            if ( nDiff > 0 )
+                nRel -= nDiff;
+        }
+        nRel = Min( nRel, pRel->Prt().Width() );
+        nRet = nRel * nPercent / 100;
+    }
+    return nRet;
+}
+
+long MA_FASTCALL lcl_CalcMinColDiff( SwLayoutFrm *pLayFrm )
+{
+    long nDiff = 0, nFirstDiff = 0;
+    SwLayoutFrm *pCol = (SwLayoutFrm*)pLayFrm->Lower();
+    ASSERT( pCol, "Where's the columnframe?" );
+    SwFrm *pFrm = pCol->Lower();
+    do
+    {   if ( pFrm && pFrm->IsTxtFrm() )
+        {
+            const long nTmp = ((SwTxtFrm*)pFrm)->FirstLineHeight();
+            if ( nTmp != USHRT_MAX )
+            {
+                if ( pCol == pLayFrm->Lower() )
+                    nFirstDiff = nTmp;
+                else
+                    nDiff = nDiff ? Min( nDiff, nTmp ) : nTmp;
+            }
+        }
+        //Leere Spalten ueberspringen!
+        pCol = (SwLayoutFrm*)pCol->GetNext();
+        while ( pCol && 0 == (pFrm = pCol->Lower()) )
+            pCol = (SwLayoutFrm*)pCol->GetNext();
+
+    } while ( pFrm && pCol );
+
+    return nDiff ? nDiff : nFirstDiff ? nFirstDiff : 240;
+}
+
+BOOL lcl_IsFlyHeightClipped( SwLayoutFrm *pLay )
+{
+    SwFrm *pFrm = pLay->ContainsCntnt();
+    while ( pFrm )
+    {   if ( pFrm->IsInTab() )
+            pFrm = pFrm->FindTabFrm();
+
+        if ( pFrm->GetDrawObjs() )
+        {
+            USHORT nCnt = pFrm->GetDrawObjs()->Count();
+            for ( USHORT i = 0; i < nCnt; ++i )
+            {
+                SdrObject *pO = (*pFrm->GetDrawObjs())[i];
+                if ( pO->IsWriterFlyFrame() &&
+                     ((SwVirtFlyDrawObj*)pO)->GetFlyFrm()->IsHeightClipped() )
+                    return TRUE;
+            }
+        }
+        pFrm = pFrm->FindNextCnt();
+    }
+    return FALSE;
+}
+
+void SwLayoutFrm::FormatWidthCols( const SwBorderAttrs &rAttrs,
+    const SwTwips nBorder, const SwTwips nMinHeight )
+{
+    //Wenn Spalten im Spiel sind, so wird die Groesse an der
+    //letzten Spalte ausgerichtet.
+    //1. Inhalt formatieren.
+    //2. Hoehe der letzten Spalte ermitteln, wenn diese zu
+    //   zu gross ist muss der Fly wachsen.
+    //   Der Betrag um den der Fly waechst ist aber nicht etwa
+    //   der Betrag des Ueberhangs, denn wir muessen davon
+    //   ausgehen, dass etwas Masse zurueckfliesst und so
+    //   zusaetzlicher Platz geschaffen wird.
+    //   Im Ersten Ansatz ist der Betrag um den gewachsen wird
+    //   der Ueberhang geteilt durch die Spaltenanzahl oder
+    //   der Ueberhang selbst wenn er kleiner als die Spalten-
+    //   anzahl ist.
+    //3. Weiter mit 1. bis zur Stabilitaet.
+
+    const SwFmtCol &rCol = rAttrs.GetAttrSet().GetCol();
+    const USHORT nNumCols = rCol.GetNumCols();
+
+    FASTBOOL bEnd = FALSE;
+    FASTBOOL bBackLock = FALSE;
+    SwViewImp *pImp = GetShell() ? GetShell()->Imp() : 0;
+    {
+        // Zugrunde liegender Algorithmus
+        // Es wird versucht, eine optimale Hoehe fuer die Spalten zu finden.
+        // nMinimum beginnt mit der uebergebenen Mindesthoehe und wird dann als
+        // Maximum der Hoehen gepflegt, bei denen noch Spalteninhalt aus einer
+        // Spalte herausragt.
+        // nMaximum beginnt bei LONG_MAX und wird als Minimum der Hoehen gepflegt,
+        // bei denen der Inhalt gepasst hat.
+        // Bei spaltigen Bereichen beginnt nMaximum bei dem maximalen Wert, den
+        // die Umgebung vorgibt, dies kann natuerlich ein Wert sein, bei dem noch
+        // Inhalt heraushaengt.
+        // Es werden die Spalten formatiert, wenn Inhalt heraushaengt, wird nMinimum
+        // ggf. angepasst, dann wird gewachsen, mindestens um nMinDiff, aber nicht ueber
+        // ein groesseres nMaximum hinaus. Wenn kein Inhalt heraushaengt, sondern
+        // noch Luft in einer Spalte ist, schrumpfen wir entsprechend, mindestens um
+        // nMinDiff, aber nicht unter das nMinimum.
+        // Abgebrochen wird, wenn kein Inhalt mehr heraushaengt und das Minimum sich auf
+        // weniger als ein MinDiff dem Maximum angenaehert hat oder das von der
+        // Umgebung vorgegebene Maximum erreicht ist und trotzdem Inhalt heraus-
+        // haengt.
+
+        // Kritik an der Implementation
+        // 1. Es kann theoretisch Situationen geben, in denen der Inhalt in einer geringeren
+        // Hoehe passt und in einer groesseren Hoehe nicht passt. Damit der Code robust
+        // gegen solche Verhaeltnisse ist, sind ein paar Abfragen bezgl. Minimum und Maximum
+        // drin, die wahrscheinlich niemals zuschlagen koennen.
+        // 2. Es wird fuer das Schrumpfen das gleiche nMinDiff benutzt wie fuer das Wachstum,
+        // das nMinDiff ist allerdings mehr oder weniger die kleinste erste Zeilenhoehe und
+        // als Mindestwert fuer das Schrumpfen nicht unbedingt optimal.
+
+        long nMinimum = nMinHeight;
+        long nMaximum;
+        BOOL bNoBalance = FALSE;
+        if( IsSctFrm() )
+        {
+            nMaximum = GetUpper()->Frm().Top() + GetUpper()->Prt().Top()
+                       + GetUpper()->Prt().Height() - Frm().Top() - nBorder;
+            nMaximum += GetUpper()->Grow( LONG_MAX, pHeight, TRUE );
+            if( nMaximum < nMinimum )
+            {
+                if( nMaximum < 0 )
+                    nMinimum = nMaximum = 0;
+                else
+                    nMinimum = nMaximum;
+            }
+            if( nMaximum > BROWSE_HEIGHT )
+                nMaximum = BROWSE_HEIGHT;
+
+            bNoBalance = ((SwSectionFrm*)this)->GetSection()->GetFmt()->
+                         GetBalancedColumns().GetValue();
+            SwFrm* pAny = ContainsAny();
+            if( bNoBalance ||
+                ( !Frm().Height() && pAny ) ) // presumably a fresh one
+            {
+                Frm().Height( nMaximum );
+                if( Prt().Top() > Frm().Height() )
+                    Prt().Pos().Y() = Frm().Height();
+                Prt().Height( nMaximum - Prt().Top() );
+            }
+            if( !pAny && !((SwSectionFrm*)this)->IsFtnLock() )
+            {
+                SwFtnContFrm* pFtnCont = ((SwSectionFrm*)this)->ContainsFtnCont();
+                if( pFtnCont )
+                {
+                    SwFrm* pFtnAny = pFtnCont->ContainsAny();
+                    if( pFtnAny && pFtnAny->IsValid() )
+                    {
+                        bBackLock = TRUE;
+                        ((SwSectionFrm*)this)->SetFtnLock( TRUE );
+                    }
+                }
+            }
+        }
+        else
+            nMaximum = LONG_MAX;
+        do
+        {
+            //Kann eine Weile dauern, deshalb hier auf Waitcrsr pruefen.
+            if ( pImp )
+                pImp->CheckWaitCrsr();
+
+            bValidSize = TRUE;
+            //Erstmal die Spalten formatieren, das entlastet den
+            //Stack ein wenig.
+            //Bei der Gelegenheit stellen wir auch gleich mal die
+            //Breiten und Hoehen der Spalten ein (so sie denn falsch sind).
+            SwLayoutFrm *pCol = (SwLayoutFrm*)Lower();
+            SwTwips nAvail = Prt().Width();
+            for ( USHORT i = 0; i < nNumCols; ++i )
+            {
+                SwTwips nWidth = rCol.CalcColWidth( i, USHORT(Prt().Width()));
+                if ( i == (nNumCols - 1) ) //Dem Letzten geben wir wie
+                    nWidth = nAvail;       //immer den Rest.
+                if ( pCol->Frm().Width() != nWidth )
+                {
+                    pCol->Frm().Width( nWidth );
+                    pCol->_InvalidatePrt();
+                    if ( pCol->GetNext() )
+                        pCol->GetNext()->_InvalidatePos();
+                }
+                if ( pCol->Frm().Height() != Prt().Height() )
+                {
+                    pCol->Frm().Height( Prt().Height() );
+                    pCol->_InvalidatePrt();
+                }
+                pCol->Calc();
+                // ColumnFrms besitzen jetzt einen BodyFrm, der auch kalkuliert werden will
+                pCol->Lower()->Calc();
+                if( pCol->Lower()->GetNext() )
+                    pCol->Lower()->GetNext()->Calc();  // SwFtnCont
+                pCol = (SwLayoutFrm*)pCol->GetNext();
+                nAvail -= nWidth;
+            }
+
+            ::CalcCntnt( this );
+
+            pCol = (SwLayoutFrm*)Lower();
+            ASSERT( pCol && pCol->GetNext(), ":-( Spalten auf Urlaub?");
+            // bMinDiff wird gesetzt, wenn es keine leere Spalte gibt
+            BOOL bMinDiff = TRUE;
+            while ( bMinDiff && pCol && pCol->GetNext() )
+            {   // Zwischen Spalte und Inhalt ist jetzt noch der BodyFrm gekommen
+                bMinDiff = 0 != ((SwLayoutFrm*)pCol->Lower())->Lower();
+                pCol = (SwLayoutFrm*)pCol->GetNext();
+            }
+            pCol = (SwLayoutFrm*)Lower();
+            SwFrm *pLow;
+            SwTwips nDiff = 0;
+            SwTwips nMaxFree = 0;
+            SwTwips nAllFree = LONG_MAX;
+            // bFoundLower wird gesetzt, wenn es mind. eine nichtleere Spalte gibt
+            BOOL bFoundLower = FALSE;
+            while( pCol )
+            {
+                SwLayoutFrm* pLay = (SwLayoutFrm*)pCol->Lower();
+                SwTwips nInnerHeight = pLay->Frm().Height() - pLay->Prt().Height();
+                if( pLay->Lower() )
+                {
+                    bFoundLower = TRUE;
+                    nInnerHeight += pLay->InnerHeight();
+                }
+                else if( nInnerHeight < 0 )
+                    nInnerHeight = 0;
+
+                if( pLay->GetNext() )
+                {
+                    bFoundLower = TRUE;
+                    pLay = (SwLayoutFrm*)pLay->GetNext();
+                    ASSERT( pLay->IsFtnContFrm(),"FtnContainer exspected" );
+                    nInnerHeight += pLay->InnerHeight();
+                    nInnerHeight += pLay->Frm().Height() - pLay->Prt().Height();
+                }
+                nInnerHeight -= pCol->Prt().Height();
+                if( nInnerHeight > nDiff )
+                {
+                    nDiff = nInnerHeight;
+                    nAllFree = 0;
+                }
+                else
+                {
+                    if( nMaxFree < -nInnerHeight )
+                        nMaxFree = -nInnerHeight;
+                    if( nAllFree > -nInnerHeight )
+                        nAllFree = -nInnerHeight;
+                }
+                pCol = (SwLayoutFrm*)pCol->GetNext();
+            }
+
+            if ( bFoundLower || ( IsSctFrm() && ((SwSectionFrm*)this)->HasFollow() ) )
+            {
+                SwTwips nMinDiff = ::lcl_CalcMinColDiff( this );
+                // Hier wird entschieden, ob wir wachsen muessen, naemlich wenn
+                // ein Spalteninhalt (nDiff) oder ein Fly herausragt.
+                // Bei spaltigen Bereichen wird beruecksichtigt, dass mit dem
+                // Besitz eines nichtleeren Follows die Groesse festgelegt ist.
+                if ( nDiff || ::lcl_IsFlyHeightClipped( this ) ||
+                     ( IsSctFrm() && ((SwSectionFrm*)this)->CalcMinDiff( nMinDiff ) ) )
+                {
+                    // Das Minimum darf nicht kleiner sein als unsere PrtHeight,
+                    // solange noch etwas herausragt.
+                    if( nMinimum < Prt().Height() )
+                        nMinimum = Prt().Height();
+                    // Es muss sichergestellt sein, dass das Maximum nicht kleiner
+                    // als die PrtHeight ist, wenn noch etwas herausragt
+                    if( nMaximum < Prt().Height() )
+                        nMaximum = Prt().Height();  // Robust, aber kann das ueberhaupt eintreten?
+                    if( !nDiff ) // wenn nur Flys herausragen, wachsen wir um nMinDiff
+                        nDiff = nMinDiff;
+                    // Wenn wir um mehr als nMinDiff wachsen wollen, wird dies auf die
+                    // Spalten verteilt
+                    if ( Abs(nDiff - nMinDiff) > nNumCols && nDiff > (long)nNumCols )
+                        nDiff /= nNumCols;
+
+                    if ( bMinDiff )
+                    {   // Wenn es keinen leeren Spalten gibt, wollen wir mind. um nMinDiff
+                        // wachsen. Sonderfall: Wenn wir kleiner als die minimale Frmhoehe
+                        // sind und die PrtHeight kleiner als nMinDiff ist, wachsen wir so,
+                        // dass die PrtHeight hinterher genau nMinDiff ist.
+                        if ( Frm().Height() > nMinHeight || Prt().Height() >= nMinDiff )
+                            nDiff = Max( nDiff, nMinDiff );
+                        else if( nDiff < nMinDiff )
+                            nDiff = nMinDiff - Prt().Height() + 1;
+                    }
+                    // nMaximum ist eine Groesse, in der der Inhalt gepasst hat,
+                    // oder der von der Umgebung vorgegebene Wert, deshalb
+                    // brauchen wir nicht ueber diesen Wrt hinauswachsen.
+                    if( nDiff + Prt().Height() > nMaximum )
+                        nDiff = nMaximum - Prt().Height();
+                }
+                else if( nMaximum > nMinimum ) // Wir passen, haben wir auch noch Spielraum?
+                {
+                    if ( nMaximum < Prt().Height() )
+                        nDiff = nMaximum - Prt().Height(); // wir sind ueber eine funktionierende
+                        // Hoehe hinausgewachsen und schrumpfen wieder auf diese zurueck,
+                        // aber kann das ueberhaupt eintreten?
+                    else
+                    {   // Wir haben ein neues Maximum, eine Groesse, fuer die der Inhalt passt.
+                        nMaximum = Prt().Height();
+                        // Wenn der Freiraum in den Spalten groesser ist als nMinDiff und wir
+                        // nicht dadurch wieder unter das Minimum rutschen, wollen wir ein wenig
+                        // Luft herauslassen.
+                        if( !bNoBalance && ( nMaxFree >= nMinDiff && (!nAllFree
+                            || nMinimum < Prt().Height() - nMinDiff ) ) )
+                        {
+                            nMaxFree /= nNumCols; // auf die Spalten verteilen
+                            nDiff = nMaxFree < nMinDiff ? -nMinDiff : -nMaxFree; // mind. nMinDiff
+                            if( Prt().Height() + nDiff <= nMinimum ) // Unter das Minimum?
+                                nDiff = ( nMinimum - nMaximum ) / 2; // dann lieber die Mitte
+                        }
+                        else if( nAllFree )
+                        {
+                            nDiff = -nAllFree;
+                            if( Prt().Height() + nDiff <= nMinimum ) // Less than minimum?
+                                nDiff = ( nMinimum - nMaximum ) / 2; // Take the center
+                        }
+                    }
+                }
+                if( nDiff ) // jetzt wird geschrumpft oder gewachsen..
+                {
+                    Size aOldSz( Prt().SSize() );
+                    Prt().Height( Prt().Height() + nDiff );
+                    Frm().Height( Prt().Height() + nBorder);
+                    ChgLowersProp( aOldSz );
+                    NotifyFlys();
+
+                    //Es muss geeignet invalidiert werden, damit
+                    //sich die Frms huebsch ausbalancieren
+                    //- Der jeweils erste ab der zweiten Spalte bekommt
+                    //  ein InvalidatePos();
+                    pCol = (SwLayoutFrm*)Lower()->GetNext();
+                    while ( pCol )
+                    {
+                        pLow = pCol->Lower();
+                        if ( pLow )
+                            pLow->_InvalidatePos();
+                        pCol = (SwLayoutFrm*)pCol->GetNext();
+                    }
+                    if( IsSctFrm() && ((SwSectionFrm*)this)->HasFollow() )
+                    {
+                        // Wenn wir einen Follow erzeugt haben, muessen wir
+                        // seinem Inhalt die Chance geben, im CalcCntnt
+                        // zurueckzufliessen
+                        SwCntntFrm* pTmpCntnt =
+                            ((SwSectionFrm*)this)->GetFollow()->ContainsCntnt();
+                        if( pTmpCntnt )
+                            pTmpCntnt->_InvalidatePos();
+                    }
+                }
+                else
+                    bEnd = TRUE;
+            }
+            else
+                bEnd = TRUE;
+
+        } while ( !bEnd || !bValidSize );
+    }
+    ::CalcCntnt( this );
+    if( IsSctFrm() )
+    {
+        ::CalcCntnt( this, TRUE );
+        if( bBackLock )
+            ((SwSectionFrm*)this)->SetFtnLock( FALSE );
+    }
+}
+
+
+/*************************************************************************
+|*
+|*  SwRootFrm::InvalidateAllCntnt()
+|*
+|*  Ersterstellung      MA 13. Feb. 98
+|*  Letzte Aenderung    MA 12. Aug. 00
+|*
+|*************************************************************************/
+
+SwCntntFrm* lcl_InvalidateSection( SwFrm *pCnt, BYTE nInv )
+{
+    SwSectionFrm* pSect = pCnt->FindSctFrm();
+    // Wenn unser CntntFrm in einer Tabelle oder Fussnote steht, sind nur
+    // Bereiche gemeint, die ebenfalls innerhalb liegen.
+    // Ausnahme: Wenn direkt eine Tabelle uebergeben wird.
+    if( ( ( pCnt->IsInTab() && !pSect->IsInTab() ) ||
+        ( pCnt->IsInFtn() && !pSect->IsInFtn() ) ) && !pCnt->IsTabFrm() )
+        return NULL;
+    if( nInv & INV_SIZE )
+        pSect->_InvalidateSize();
+    if( nInv & INV_POS )
+        pSect->_InvalidatePos();
+    if( nInv & INV_PRTAREA )
+        pSect->_InvalidatePrt();
+    SwFlowFrm *pFoll = pSect->GetFollow();
+    // Temporary separation from follow
+    pSect->SetFollow( NULL );
+    SwCntntFrm* pRet = pSect->FindLastCntnt();
+    pSect->SetFollow( pFoll );
+    return pRet;
+}
+
+SwCntntFrm* lcl_InvalidateTable( SwTabFrm *pTable, BYTE nInv )
+{
+    if( ( nInv & INV_SECTION ) && pTable->IsInSct() )
+        lcl_InvalidateSection( pTable, nInv );
+    if( nInv & INV_SIZE )
+        pTable->_InvalidateSize();
+    if( nInv & INV_POS )
+        pTable->_InvalidatePos();
+    if( nInv & INV_PRTAREA )
+        pTable->_InvalidatePrt();
+    return pTable->FindLastCntnt();
+}
+
+void lcl_InvalidateAllCntnt( SwCntntFrm *pCnt, BYTE nInv );
+
+void lcl_InvalidateCntnt( SwCntntFrm *pCnt, BYTE nInv )
+{
+    SwCntntFrm *pLastTabCnt = NULL;
+    SwCntntFrm *pLastSctCnt = NULL;
+    while ( pCnt )
+    {
+        if( nInv & INV_SECTION )
+        {
+            if( pCnt->IsInSct() )
+            {
+                // Siehe oben bei Tabellen
+                if( !pLastSctCnt )
+                    pLastSctCnt = lcl_InvalidateSection( pCnt, nInv );
+                if( pLastSctCnt == pCnt )
+                    pLastSctCnt = NULL;
+            }
+#ifndef PRODUCT
+            else
+                ASSERT( !pLastSctCnt, "Where's the last SctCntnt?" );
+#endif
+        }
+        if( nInv & INV_TABLE )
+        {
+            if( pCnt->IsInTab() )
+            {
+                // Um nicht fuer jeden CntntFrm einer Tabelle das FindTabFrm() zu rufen
+                // und wieder die gleiche Tabelle zu invalidieren, merken wir uns den letzten
+                // CntntFrm der Tabelle und reagieren erst wieder auf IsInTab(), wenn wir
+                // an diesem vorbei sind.
+                // Beim Eintritt in die Tabelle wird der LastSctCnt auf Null gesetzt,
+                // damit Bereiche im Innern der Tabelle richtig invalidiert werden.
+                // Sollte die Tabelle selbst in einem Bereich stehen, so wird an
+                // diesem die Invalidierung bis zu dreimal durchgefuehrt, das ist vertretbar.
+                if( !pLastTabCnt )
+                {
+                    pLastTabCnt = lcl_InvalidateTable( pCnt->FindTabFrm(), nInv );
+                    pLastSctCnt = NULL;
+                }
+                if( pLastTabCnt == pCnt )
+                {
+                    pLastTabCnt = NULL;
+                    pLastSctCnt = NULL;
+                }
+            }
+#ifndef PRODUCT
+            else
+                ASSERT( !pLastTabCnt, "Where's the last TabCntnt?" );
+#endif
+        }
+
+        if( nInv & INV_SIZE )
+            pCnt->Prepare( PREP_CLEAR, 0, FALSE );
+        if( nInv & INV_POS )
+            pCnt->_InvalidatePos();
+        if( nInv & INV_PRTAREA )
+            pCnt->_InvalidatePrt();
+        if ( nInv & INV_LINENUM )
+            pCnt->InvalidateLineNum();
+        if ( pCnt->GetDrawObjs() )
+            lcl_InvalidateAllCntnt( pCnt, nInv );
+        pCnt = pCnt->GetNextCntntFrm();
+    }
+}
+
+void lcl_InvalidateAllCntnt( SwCntntFrm *pCnt, BYTE nInv )
+{
+    SwDrawObjs &rObjs = *pCnt->GetDrawObjs();
+    for ( USHORT i = 0; i < rObjs.Count(); ++i )
+    {
+        SdrObject *pO = rObjs[i];
+        if ( pO->IsWriterFlyFrame() )
+        {
+            SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+            if ( pFly->IsFlyInCntFrm() )
+                ::lcl_InvalidateCntnt( pFly->ContainsCntnt(), nInv );
+        }
+    }
+}
+
+void SwRootFrm::InvalidateAllCntnt( BYTE nInv )
+{
+    // Erst werden alle Seitengebundenen FlyFrms abgearbeitet.
+    SwPageFrm *pPage = (SwPageFrm*)Lower();
+    while( pPage )
+    {
+        pPage->InvalidateFlyLayout();
+        pPage->InvalidateFlyCntnt();
+        pPage->InvalidateFlyInCnt();
+        pPage->InvalidateLayout();
+        pPage->InvalidateCntnt();
+        pPage->InvalidatePage( pPage ); //Damit ggf. auch der Turbo verschwindet
+
+        if ( pPage->GetSortedObjs() )
+        {
+            const SwSortDrawObjs &rObjs = *pPage->GetSortedObjs();
+            for ( USHORT i = 0; i < rObjs.Count(); ++i )
+            {
+                SdrObject *pO = rObjs[i];
+                if ( pO->IsWriterFlyFrame() )
+                    ::lcl_InvalidateCntnt( ((SwVirtFlyDrawObj*)pO)->GetFlyFrm()->ContainsCntnt(),
+                                         nInv );
+            }
+        }
+        pPage = (SwPageFrm*)(pPage->GetNext());
+    }
+
+    //Hier den gesamten Dokumentinhalt und die zeichengebundenen Flys.
+    ::lcl_InvalidateCntnt( ContainsCntnt(), nInv );
+
+    if( nInv & INV_PRTAREA )
+    {
+        ViewShell *pSh  = GetShell();
+        if( pSh )
+            pSh->InvalidateWindows( Frm() );
+    }
+}
+
+
diff --git a/sw/source/core/makefile.mk b/sw/source/core/makefile.mk
new file mode 100644
index 000000000000..11fe10b4fe22
--- /dev/null
+++ b/sw/source/core/makefile.mk
@@ -0,0 +1,326 @@
+#*************************************************************************
+#
+#   $RCSfile: makefile.mk,v $
+#
+#   $Revision: 1.1.1.1 $
+#
+#   last change: $Author: hr $ $Date: 2000-09-19 00:08:15 $
+#
+#   The Contents of this file are made available subject to the terms of
+#   either of the following licenses
+#
+#          - GNU Lesser General Public License Version 2.1
+#          - Sun Industry Standards Source License Version 1.1
+#
+#   Sun Microsystems Inc., October, 2000
+#
+#   GNU Lesser General Public License Version 2.1
+#   =============================================
+#   Copyright 2000 by Sun Microsystems, Inc.
+#   901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+#   This library is free software; you can redistribute it and/or
+#   modify it under the terms of the GNU Lesser General Public
+#   License version 2.1, as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   Lesser General Public License for more details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+#   License along with this library; if not, write to the Free Software
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+#   MA  02111-1307  USA
+#
+#
+#   Sun Industry Standards Source License Version 1.1
+#   =================================================
+#   The contents of this file are subject to the Sun Industry Standards
+#   Source License Version 1.1 (the "License"); You may not use this file
+#   except in compliance with the License. You may obtain a copy of the
+#   License at http://www.openoffice.org/license.html.
+#
+#   Software provided under this License is provided on an "AS IS" basis,
+#   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+#   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+#   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+#   See the License for the specific provisions governing your rights and
+#   obligations concerning the Software.
+#
+#   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+#   Copyright: 2000 by Sun Microsystems, Inc.
+#
+#   All Rights Reserved.
+#
+#   Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..
+PRJNAME=sw
+
+TARGET=core
+
+PROJECTPCH=core_pch
+PDBTARGET=core_pch
+PROJECTPCHSOURCE=.\core_1st\core_pch
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE :  $(PRJ)$/inc$/swpre.mk
+.INCLUDE :  settings.mk
+.INCLUDE :  $(PRJ)$/inc$/sw.mk
+
+.IF "$(CALLTARGETS)"=="core"
+RC_SUBDIRS=
+.ENDIF
+
+.IF "$(GUI)" != "WNT"
+.IF "$(GUI)" != "MAC"
+.IF "$(COM)" != "BLC"
+.IF "$(COM)" != "WTC"
+LIBFLAGS=/NOI /NOE /PAGE:256
+.ENDIF
+.ENDIF
+.ENDIF
+.ENDIF
+
+.IF "$(COM)"=="WTC"
+LIBFLAGS=$(LIBFLAGS) /p=256
+.ENDIF
+
+# --- Files --------------------------------------------------------
+
+# fuer VC++/NT andere Label als die Verzeichnisnamen
+.IF "$(RC_SUBDIRS)" == ""
+SWSUBDIRS= \
+    core_1st \
+    attr \
+    bastyp \
+    crsr \
+    doc \
+    docnode \
+    draw \
+    edit \
+    fields \
+    frmedt \
+    graphic \
+    layout \
+    ole \
+    para \
+    sw3io \
+    swg \
+    text \
+    tox \
+    txtnode \
+       unocore \
+    undo \
+    view
+
+.IF "$(PRODUCT)" == ""
+SWSUBDIRS+= \
+    except
+.ENDIF
+.IF "$(COM)$(GUI)"=="MSCWIN"
+SWSUBDIRS+= \
+    rtlfix
+.ENDIF
+.ENDIF
+
+SUBLIBS1= \
+        $(SLB)$/graphic.lib \
+        $(SLB)$/para.lib \
+        $(SLB)$/attr.lib \
+        $(SLB)$/edit.lib \
+        $(SLB)$/crsr.lib \
+        $(SLB)$/view.lib \
+        $(SLB)$/frmedt.lib \
+        $(SLB)$/ole.lib \
+        $(SLB)$/fields.lib \
+        $(SLB)$/tox.lib \
+        $(SLB)$/undo.lib \
+        $(SLB)$/bastyp.lib
+
+
+SUBLIBS2= \
+        $(SLB)$/draw.lib \
+        $(SLB)$/sw3io.lib \
+        $(SLB)$/swg.lib \
+        $(SLB)$/layout.lib \
+        $(SLB)$/text.lib \
+        $(SLB)$/txtnode.lib \
+        $(SLB)$/doc.lib \
+        $(SLB)$/docnode.lib \
+        $(SLB)$/unocore.lib
+
+.IF "$(PRODUCT)" == ""
+SUBLIBS2+= \
+        $(SLB)$/except.lib
+.ENDIF
+
+#-------------------------------------------------------------------------
+
+.IF "$(RC_SUBDIRS)" == ""
+.IF "$(depend)" == ""
+core:						\
+    core_1st				\
+    $(SWSUBDIRS)				\
+    ALLTAR
+.ELSE
+core:
+    @+echo Doing nothing in source\core
+.ENDIF
+.ENDIF
+
+################################################################
+
+LIB1TARGET=$(SLB)$/core1.lib
+LIB1FILES= \
+        $(SUBLIBS1)
+
+LIB2TARGET=$(SLB)$/core2.lib
+LIB2FILES= \
+        $(SUBLIBS2)
+
+.INCLUDE :  target.mk
+
+################################################################
+
+#-------------------------------------------------------------------------
+
+.IF "$(dbutil)" != ""
+dbutilx="dbutil=true"
+.ENDIF
+.IF "$(debug)" != ""
+.IF "$(debug)" != "D_FORCE_OPT"
+dbutilx="debug=true"
+.ENDIF
+.ENDIF
+
+#-------------------------------------------------------------------------
+
+.IF "$(CALLTARGETS)"!="core"
+.IF "$(DOPLD)$(dopld)" == ""
+
+.IF "$(RC_SUBDIRS)" == ""
+#rule lib / subdir
+$(LB)$/%.lib : %
+    @echo @
+
+core_1st .SETDIR=core_1st:
+        @echo $@
+        @$(MAKECMD) -d $(MFLAGS) $(dbutilx) $(CALLMACROS)
+
+attr .SETDIR=attr:
+        @echo $@
+        @$(MAKECMD) -d $(MFLAGS) $(dbutilx) $(CALLMACROS)
+
+bastyp .SETDIR=bastyp:
+        @echo $@
+        @$(MAKECMD) -d $(MFLAGS) $(dbutilx) $(CALLMACROS)
+
+crsr .SETDIR=crsr:
+        @echo $@
+        @$(MAKECMD) -d $(MFLAGS) $(dbutilx) $(CALLMACROS)
+
+doc .SETDIR=doc:
+        @echo $@
+        @$(MAKECMD) -d $(MFLAGS) $(dbutilx) $(CALLMACROS)
+
+docnode .SETDIR=docnode:
+        @echo $@
+        @$(MAKECMD) -d $(MFLAGS) $(dbutilx) $(CALLMACROS)
+
+draw .SETDIR=draw:
+        @echo $@
+        @$(MAKECMD) -d $(MFLAGS) $(dbutilx) $(CALLMACROS)
+
+edit .SETDIR=edit:
+        @echo $@
+        @$(MAKECMD) -d $(MFLAGS) $(dbutilx) $(CALLMACROS)
+
+except .SETDIR=except:
+        @echo $@
+        @$(MAKECMD) -d $(MFLAGS) $(dbutilx) $(CALLMACROS)
+
+fields .SETDIR=fields:
+        @echo $@
+        @$(MAKECMD) -d $(MFLAGS) $(dbutilx) $(CALLMACROS)
+
+frmedt .SETDIR=frmedt:
+        @echo $@
+        @$(MAKECMD) -d $(MFLAGS) $(dbutilx) $(CALLMACROS)
+
+graphic .SETDIR=graphic:
+        @echo $@
+        @$(MAKECMD) -d $(MFLAGS) $(dbutilx) $(CALLMACROS)
+
+layout .SETDIR=layout:
+        @echo $@
+        @$(MAKECMD) -d $(MFLAGS) $(dbutilx) $(CALLMACROS)
+
+.IF "$(SOLAR_JAVA)" != ""
+javascrp .SETDIR=javascrp:
+        @echo $@
+        @$(MAKECMD) -d $(MFLAGS) $(dbutilx) $(CALLMACROS)
+.ENDIF
+
+ole .SETDIR=ole:
+        @echo $@
+        @$(MAKECMD) -d $(MFLAGS) $(dbutilx) $(CALLMACROS)
+
+para .SETDIR=para:
+        @echo $@
+        @$(MAKECMD) -d $(MFLAGS) $(dbutilx) $(CALLMACROS)
+
+rtlfix .SETDIR=rtlfix:
+        @echo $@
+        @$(MAKECMD) -d $(MFLAGS) $(dbutilx) $(CALLMACROS)
+
+sw3io .SETDIR=sw3io:
+        @echo $@
+        @$(MAKECMD) -d $(MFLAGS) $(dbutilx) $(CALLMACROS)
+
+swg .SETDIR=swg:
+        @echo $@
+        @$(MAKECMD) -d $(MFLAGS) $(dbutilx) $(CALLMACROS)
+
+text .SETDIR=text:
+        @echo $@
+        @$(MAKECMD) -d $(MFLAGS) $(dbutilx) $(CALLMACROS)
+
+tox .SETDIR=tox:
+        @echo $@
+        @$(MAKECMD) -d $(MFLAGS) $(dbutilx) $(CALLMACROS)
+
+txtnode .SETDIR=txtnode:
+        @echo $@
+        @$(MAKECMD) -d $(MFLAGS) $(dbutilx) $(CALLMACROS)
+
+undo .SETDIR=undo:
+        @echo $@
+        @$(MAKECMD) -d $(MFLAGS) $(dbutilx) $(CALLMACROS)
+
+unocore .SETDIR=unocore:
+        @echo $@
+        @$(MAKECMD) -d $(MFLAGS) $(dbutilx) $(CALLMACROS)
+
+view .SETDIR=view:
+        @echo $@
+        @$(MAKECMD) -d $(MFLAGS) $(dbutilx) $(CALLMACROS)
+
+.ENDIF
+.ELSE
+core_1st:
+    @echo nix
+.ENDIF
+.ENDIF
+
+kill:
+    +-$(RM) $(SLB)$/core1.lib
+    +-$(RM) $(SLB)$/core2.lib
+
diff --git a/sw/source/core/ole/makefile.mk b/sw/source/core/ole/makefile.mk
new file mode 100644
index 000000000000..5e695d41b284
--- /dev/null
+++ b/sw/source/core/ole/makefile.mk
@@ -0,0 +1,93 @@
+#*************************************************************************
+#
+#   $RCSfile: makefile.mk,v $
+#
+#   $Revision: 1.1.1.1 $
+#
+#   last change: $Author: hr $ $Date: 2000-09-19 00:08:23 $
+#
+#   The Contents of this file are made available subject to the terms of
+#   either of the following licenses
+#
+#          - GNU Lesser General Public License Version 2.1
+#          - Sun Industry Standards Source License Version 1.1
+#
+#   Sun Microsystems Inc., October, 2000
+#
+#   GNU Lesser General Public License Version 2.1
+#   =============================================
+#   Copyright 2000 by Sun Microsystems, Inc.
+#   901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+#   This library is free software; you can redistribute it and/or
+#   modify it under the terms of the GNU Lesser General Public
+#   License version 2.1, as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   Lesser General Public License for more details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+#   License along with this library; if not, write to the Free Software
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+#   MA  02111-1307  USA
+#
+#
+#   Sun Industry Standards Source License Version 1.1
+#   =================================================
+#   The contents of this file are subject to the Sun Industry Standards
+#   Source License Version 1.1 (the "License"); You may not use this file
+#   except in compliance with the License. You may obtain a copy of the
+#   License at http://www.openoffice.org/license.html.
+#
+#   Software provided under this License is provided on an "AS IS" basis,
+#   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+#   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+#   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+#   See the License for the specific provisions governing your rights and
+#   obligations concerning the Software.
+#
+#   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+#   Copyright: 2000 by Sun Microsystems, Inc.
+#
+#   All Rights Reserved.
+#
+#   Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sw
+TARGET=ole
+
+AUTOSEG=true
+
+PROJECTPCH=core_pch
+PDBTARGET=core_pch
+PROJECTPCHSOURCE=..\core_1st\core_pch
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE :  $(PRJ)$/inc$/swpre.mk
+.INCLUDE :  settings.mk
+.INCLUDE :  $(PRJ)$/inc$/sw.mk
+
+# --- Files --------------------------------------------------------
+
+CXXFILES = \
+        ndole.cxx
+
+
+
+SLOFILES =  \
+        $(SLO)$/ndole.obj
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE :  target.mk
+
diff --git a/sw/source/core/ole/ndole.cxx b/sw/source/core/ole/ndole.cxx
new file mode 100644
index 000000000000..5d168aaf724d
--- /dev/null
+++ b/sw/source/core/ole/ndole.cxx
@@ -0,0 +1,644 @@
+/*************************************************************************
+ *
+ *  $RCSfile: ndole.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:23 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _URLOBJ_HXX //autogen
+#include 
+#endif
+#ifndef _SFXDOCFILE_HXX //autogen
+#include 
+#endif
+#ifndef _SFXAPP_HXX //autogen
+#include 
+#endif
+#ifndef _SFXINIMGR_HXX //autogen
+#include 
+#endif
+#ifndef _SVXLINKMGR_HXX
+#include 
+#endif
+#ifndef _FMTANCHR_HXX
+#include 
+#endif
+#ifndef _FRMFMT_HXX //autogen
+#include 
+#endif
+
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _SECTION_HXX
+#include 
+#endif
+#ifndef _CNTFRM_HXX
+#include 
+#endif
+#ifndef _FRMATR_HXX
+#include 
+#endif
+#ifndef _DOCSH_HXX
+#include 
+#endif
+#ifndef _NDOLE_HXX
+#include 
+#endif
+#ifndef _SW3IO_HXX
+#include 
+#endif
+
+
+class SwOLELRUCache : private SvPtrarr
+{
+public:
+    SwOLELRUCache( USHORT nInitSize )
+        : SvPtrarr( nInitSize, 1 )
+    {
+    }
+
+    SvPtrarr::Count;
+
+    void Insert( SwOLEObj& rObj );
+    void Remove( SwOLEObj& rObj );
+
+    void RemovePtr( SwOLEObj* pObj )
+    {
+        USHORT nPos = SvPtrarr::GetPos( pObj );
+        if( USHRT_MAX != nPos )
+            SvPtrarr::Remove( nPos );
+    }
+};
+
+SwOLELRUCache* SwOLEObj::pOLELRU_Cache = 0;
+static USHORT nLRU_InitSize = 0;
+
+// --------------------
+// SwOLENode
+// --------------------
+
+SwOLENode::SwOLENode( const SwNodeIndex &rWhere,
+                    SvInPlaceObject *pObj,
+                    SwGrfFmtColl *pGrfColl,
+                    SwAttrSet* pAutoAttr ) :
+    SwNoTxtNode( rWhere, ND_OLENODE, pGrfColl, pAutoAttr ),
+    aOLEObj( pObj ),
+    bOLESizeInvalid( FALSE )
+{
+    aOLEObj.SetNode( this );
+}
+
+SwOLENode::SwOLENode( const SwNodeIndex &rWhere,
+                    const String &rString,
+                    SwGrfFmtColl *pGrfColl,
+                    SwAttrSet* pAutoAttr ) :
+    SwNoTxtNode( rWhere, ND_OLENODE, pGrfColl, pAutoAttr ),
+    aOLEObj( rString ),
+    bOLESizeInvalid( FALSE )
+{
+    aOLEObj.SetNode( this );
+}
+
+SwCntntNode *SwOLENode::SplitNode( const SwPosition & )
+{
+    // OLE-Objecte vervielfaeltigen ??
+    ASSERT( FALSE, "OleNode: can't split." );
+    return this;
+}
+
+// Laden eines in den Undo-Bereich verschobenen OLE-Objekts
+
+BOOL SwOLENode::RestorePersistentData()
+{
+    if( aOLEObj.IsOLELink() )
+    {
+        aOLEObj.GetLink()->SetVisible( GetDoc()->IsVisibleLinks() );
+        GetDoc()->GetLinkManager().InsertSoLink( *aOLEObj.GetLink() );
+    }
+    else if( aOLEObj.pOLERef && aOLEObj.pOLERef->Is() )
+    {
+        SvPersist* p = GetDoc()->GetPersist();
+        if( p )     // muss da sein
+        {
+            SvInfoObjectRef aRef( p->Find( aOLEObj.aName ) );
+            if( aRef.Is() )
+                aRef->SetDeleted( FALSE );
+        }
+    }
+
+// muss das sein????
+//  if( pOLELRU_Cache )
+//      pOLELRU_Cache->RemovePtr( &aOLEObj );
+    return TRUE;
+}
+
+// Sichern eines in den Undo-Bereich zu verschiebenden OLE-Objekts
+
+BOOL SwOLENode::SavePersistentData()
+{
+    if( aOLEObj.IsOLELink() )
+    {
+        GetDoc()->GetLinkManager().Remove( *aOLEObj.GetLink() );
+    }
+    else if( aOLEObj.pOLERef && aOLEObj.pOLERef->Is() )
+    {
+        SvPersist* p = GetDoc()->GetPersist();
+        if( p )     // muss da sein
+        {
+            SvInfoObjectRef aRef( p->Find( aOLEObj.aName ) );
+            if( aRef.Is() )
+                aRef->SetDeleted( TRUE );
+        }
+        (*aOLEObj.pOLERef)->DoClose();
+    }
+
+    if( SwOLEObj::pOLELRU_Cache )
+        SwOLEObj::pOLELRU_Cache->RemovePtr( &aOLEObj );
+
+    return TRUE;
+}
+
+
+SwOLENode * SwNodes::MakeOLENode( const SwNodeIndex & rWhere,
+                                    SvInPlaceObject *pObj,
+                                    SwGrfFmtColl* pGrfColl,
+                                    SwAttrSet* pAutoAttr )
+{
+    ASSERT( pGrfColl,"SwNodes::MakeOLENode: Formatpointer ist 0." );
+
+    SwOLENode *pNode =
+        new SwOLENode( rWhere, pObj, pGrfColl, pAutoAttr );
+
+#if 0
+JP 02.10.97 - OLE Objecte stehen immer alleine im Rahmen, also hat es
+                keinen Sinn, nach einem vorherigen/nachfolgenden
+                ContentNode zu suchen!
+
+    SwCntntNode *pCntntNd;
+    SwIndex aIdx( rWhere, -1 );
+    if ( (pCntntNd=(*this)[ rWhere ]->GetCntntNode()) != 0 )
+        pCntntNd->MakeFrms( rWhere, aIdx );
+    else
+    {
+        aIdx--;
+        if ( (pCntntNd=(*this)[aIdx]->GetCntntNode()) != 0 )
+        {
+            SwIndex aTmp( aIdx );
+            aIdx++;
+            pCntntNd->MakeFrms( aTmp, aIdx );
+        }
+    }
+#endif
+    return pNode;
+}
+
+
+SwOLENode * SwNodes::MakeOLENode( const SwNodeIndex & rWhere,
+                                    String &rName,
+                                    SwGrfFmtColl* pGrfColl,
+                                    SwAttrSet* pAutoAttr )
+{
+    ASSERT( pGrfColl,"SwNodes::MakeOLENode: Formatpointer ist 0." );
+
+    SwOLENode *pNode =
+        new SwOLENode( rWhere, rName, pGrfColl, pAutoAttr );
+
+#if 0
+JP 02.10.97 - OLE Objecte stehen immer alleine im Rahmen, also hat es
+                keinen Sinn, nach einem vorherigen/nachfolgenden
+                ContentNode zu suchen!
+    SwCntntNode *pCntntNd;
+    SwIndex aIdx( rWhere, -1 );
+    if ( (pCntntNd=(*this)[ rWhere ]->GetCntntNode()) != 0 )
+        pCntntNd->MakeFrms( rWhere, aIdx );
+    else
+    {
+        aIdx--;
+        if ( (pCntntNd=(*this)[aIdx]->GetCntntNode()) != 0 )
+        {
+            SwIndex aTmp( aIdx );
+            aIdx++;
+            pCntntNd->MakeFrms( aTmp, aIdx );
+        }
+    }
+#endif
+    return pNode;
+}
+
+
+Size SwOLENode::GetTwipSize() const
+{
+    SvInPlaceObjectRef xRef( ((SwOLENode*)this)->aOLEObj.GetOleRef() );
+    Size aSz( xRef->GetVisArea().GetSize() );
+    const MapMode aDest( MAP_TWIP );
+    const MapMode aSrc ( xRef->GetMapUnit() );
+    return OutputDevice::LogicToLogic( aSz, aSrc, aDest );
+}
+
+
+SwCntntNode* SwOLENode::MakeCopy( SwDoc* pDoc, const SwNodeIndex& rIdx ) const
+{
+    // Falls bereits eine SvPersist-Instanz existiert, nehmen wir diese
+    SvPersist* p = pDoc->GetPersist();
+    if( !p )
+    {
+        ASSERT( pDoc->GetRefForDocShell(),
+                        "wo ist die Ref-Klasse fuer die DocShell?")
+        p = new SwDocShell( pDoc, SFX_CREATE_MODE_INTERNAL );
+        *pDoc->GetRefForDocShell() = p;
+        p->DoInitNew( NULL );
+    }
+
+    // Wir hauen das Ding auf SvPersist-Ebene rein
+    String aNewName( Sw3Io::UniqueName( p->GetStorage(), "Obj" ) );
+    SvPersist* pSrc = GetDoc()->GetPersist();
+    SvInfoObjectRef refObj = pSrc->Find( aOLEObj.aName );
+    if( refObj.Is() )
+        p->Copy( aNewName, aNewName, refObj, pSrc );
+    SwOLENode* pOLENd = pDoc->GetNodes().MakeOLENode( rIdx, aNewName,
+                                    (SwGrfFmtColl*)pDoc->GetDfltGrfFmtColl(),
+                                    (SwAttrSet*)GetpSwAttrSet() );
+
+    if( aOLEObj.refLink.Is() )      // sollte es ein OLE-Link sein?
+    {
+        pOLENd->aOLEObj.refLink = new SwOLELink( *pOLENd,
+                                        pOLENd->aOLEObj.GetOleRef() );
+        // bei UNDO nie in den LinkManager uebernehmen
+        if( pOLENd->GetNodes().IsDocNodes() )
+        {
+            pOLENd->aOLEObj.GetLink()->SetVisible( pDoc->IsVisibleLinks() );
+            pDoc->GetLinkManager().InsertSoLink( *pOLENd->aOLEObj.refLink );
+// JP 19.01.96: warum Updaten??
+//          pOLENd->aOLEObj.refLink->Update();
+        }
+    }
+    pOLENd->SetChartTblName( GetChartTblName() );
+    pOLENd->SetAlternateText( GetAlternateText() );
+    pOLENd->SetContour( HasContour() );
+
+    pOLENd->SetOLESizeInvalid( TRUE );
+    pDoc->SetOLEPrtNotifyPending();
+
+    return pOLENd;
+}
+
+
+BOOL SwOLENode::IsInGlobalDocSection() const
+{
+    // suche den "Body Anchor"
+    ULONG nEndExtraIdx = GetNodes().GetEndOfExtras().GetIndex();
+    const SwNode* pAnchorNd = this;
+    do {
+        SwFrmFmt* pFlyFmt = pAnchorNd->GetFlyFmt();
+        if( !pFlyFmt )
+            return FALSE;
+
+        const SwFmtAnchor& rAnchor = pFlyFmt->GetAnchor();
+        if( !rAnchor.GetCntntAnchor() )
+            return FALSE;
+
+        pAnchorNd = &rAnchor.GetCntntAnchor()->nNode.GetNode();
+    } while( pAnchorNd->GetIndex() < nEndExtraIdx );
+
+    const SwSectionNode* pSectNd = pAnchorNd->FindSectionNode();
+    if( !pSectNd )
+        return FALSE;
+
+    while( pSectNd )
+    {
+        pAnchorNd = pSectNd;
+        pSectNd = pAnchorNd->FindStartNode()->FindSectionNode();
+    }
+
+    // in pAnchorNd steht der zuletzt gefundene Section Node. Der muss
+    // jetzt die Bedingung fuers GlobalDoc erfuellen.
+    pSectNd = (SwSectionNode*)pAnchorNd;
+    return FILE_LINK_SECTION == pSectNd->GetSection().GetType() &&
+            pSectNd->GetIndex() > nEndExtraIdx;
+}
+
+
+BOOL SwOLENode::IsOLEObjectDeleted() const
+{
+    BOOL bRet = FALSE;
+    if( !aOLEObj.IsOLELink() && aOLEObj.pOLERef && aOLEObj.pOLERef->Is() )
+    {
+        SvPersist* p = GetDoc()->GetPersist();
+        if( p )     // muss da sein
+        {
+            SvInfoObjectRef aRef( p->Find( aOLEObj.aName ) );
+            if( aRef.Is() )
+                bRet = aRef->IsDeleted();
+        }
+    }
+    return bRet;
+}
+
+
+SwOLEObj::SwOLEObj( SvInPlaceObject *pObj ) :
+    pOLERef( new SvInPlaceObjectRef( pObj ) ),
+    pOLENd( 0 )
+{
+}
+
+
+SwOLEObj::SwOLEObj( const String &rString ) :
+    pOLERef( 0 ),
+    pOLENd( 0 ),
+    aName( rString )
+{
+}
+
+
+SwOLEObj::~SwOLEObj()
+{
+    if( pOLERef && pOLERef->Is() )
+        //#41499# Kein DoClose(). Beim Beenden ruft der Sfx ein DoClose auf
+        //die offenen Objekte. Dadurch wird ggf. eine temp. OLE-Grafik wieder
+        //in eine Grafik gewandelt. Der OLE-Node wird zerstoert. Das DoClose
+        //wueder in das leere laufen, weil das Objekt bereits im DoClose steht.
+        //Durch das remove unten waere das DoClose aber nicht vollstaendig.
+        (*pOLERef)->GetProtocol().Reset();
+    delete pOLERef;
+    // Object aus dem Storage removen!!
+    if( pOLENd && !pOLENd->GetDoc()->IsInDtor() )   //NIcht notwendig im DTor (MM)
+    {
+        SvPersist* p = pOLENd->GetDoc()->GetPersist();
+        if( p )     // muss er existieren ?
+            p->Remove( aName );
+    }
+
+    if( pOLELRU_Cache )
+    {
+        pOLELRU_Cache->RemovePtr( this );
+        if( !pOLELRU_Cache->Count() )
+            // der letzte macht die Tuer zu
+            delete pOLELRU_Cache, pOLELRU_Cache = 0;
+    }
+}
+
+
+void SwOLEObj::SetNode( SwOLENode* pNode )
+{
+    pOLENd = pNode;
+    if ( pOLERef && !aName.Len() )
+    {
+        SwDoc* pDoc = pNode->GetDoc();
+
+        // Falls bereits eine SvPersist-Instanz existiert, nehmen wir diese
+        SvPersist* p = pDoc->GetPersist();
+        if( !p )
+        {
+            ASSERT( !this, "warum wird hier eine DocShell angelegt?" );
+            p = new SwDocShell( pDoc, SFX_CREATE_MODE_INTERNAL );
+            p->DoInitNew( NULL );
+        }
+        // Wir hauen das Ding auf SvPersist-Ebene rein
+        aName = Sw3Io::UniqueName( p->GetStorage(), "Obj" );
+        SvInfoObjectRef refObj = new SvEmbeddedInfoObject( *pOLERef, aName );
+
+//JP 05.02.96: solange das Move nicht richtig funktioniert muss der
+//             (Object-)Name gesetzt werden. Sonst wird Object nicht
+//              wiedergefunden
+//(*pOLERef)->SetName( new SvLinkName( aName ));
+
+        if ( !p->Move( refObj, aName ) ) // Eigentuemer Uebergang!
+            refObj.Clear();
+        else if( (*pOLERef)->IsLink() )
+        {
+            refLink = new SwOLELink( *pNode, &(*pOLERef) );
+            if( pNode->GetNodes().IsDocNodes() )
+            {
+                refLink->SetVisible( pDoc->IsVisibleLinks() );
+                pDoc->GetLinkManager().InsertSoLink( *refLink );
+                refLink->Update();
+            }
+        }
+        ASSERT( refObj.Is(), "InsertObject failed" );
+    }
+}
+
+BOOL SwOLEObj::IsOleRef() const
+{
+    return pOLERef && pOLERef->Is();
+}
+
+SvInPlaceObjectRef SwOLEObj::GetOleRef()
+{
+    if( !pOLERef || !pOLERef->Is() )
+    {
+        SvPersist* p = pOLENd->GetDoc()->GetPersist();
+        ASSERT( p, "kein SvPersist vorhanden" );
+
+        // MIB 18.5.97: DIe Base-URL wird jetzt gesetzt, damit Plugins
+        // nach dem Laden und vor dem Aktivieren des Frames korrekt
+        // geladen werden koennen
+        String sBaseURL( INetURLObject::GetBaseURL() );
+        const SwDocShell *pDocSh = pOLENd->GetDoc()->GetDocShell();
+        const SfxMedium *pMedium;
+        if( pDocSh && 0 != (pMedium = pDocSh->GetMedium()) &&
+            pMedium->GetName() != sBaseURL )
+                INetURLObject::SetBaseURL( pMedium->GetName() );
+
+        SvPersistRef xObj = p->GetObject( aName );
+        ASSERT( !pOLERef || !pOLERef->Is(),
+                "rekursiver Aufruf von GetOleRef() ist nicht erlaubt" )
+
+        INetURLObject::SetBaseURL( sBaseURL );
+
+        if ( !xObj.Is() )
+        {
+            //Das Teil konnte nicht geladen werden (wahrsch. Kaputt).
+            Rectangle aArea;
+            SwFrm *pFrm = pOLENd->GetFrm();
+            if ( pFrm )
+            {
+                Size aSz( pFrm->Frm().SSize() );
+                const MapMode aSrc ( MAP_TWIP );
+                const MapMode aDest( MAP_100TH_MM );
+                aSz = OutputDevice::LogicToLogic( aSz, aSrc, aDest );
+                aArea.SetSize( aSz );
+            }
+            else
+                aArea.SetSize( Size( 5000,  5000 ) );
+            xObj = new SvDeathObject( aArea );
+        }
+
+        if( pOLERef )
+            *pOLERef = &xObj;
+        else
+            pOLERef = new SvInPlaceObjectRef( xObj );
+    }
+
+    if( !pOLELRU_Cache )
+    {
+        // Init Size besorgen
+        if( !nLRU_InitSize )
+        {
+            nLRU_InitSize = SFX_APP()->GetIniManager()->Get(
+                SFX_GROUP_WORKINGSET_IMPL, String::CreateFromAscii(
+                RTL_CONSTASCII_STRINGPARAM( "MaxOLEObjectsInSWMemory" )))
+                    .ToInt32();
+
+            if( 20 > nLRU_InitSize )
+                nLRU_InitSize = 20;
+        }
+        pOLELRU_Cache = new SwOLELRUCache( nLRU_InitSize );
+    }
+    pOLELRU_Cache->Insert( *this );
+
+    return *pOLERef;
+}
+
+
+void SwOLEObj::ReleaseLink()
+{
+    if( refLink.Is() )
+    {
+        ((SwOLENode*)pOLENd)->GetDoc()->GetLinkManager().Remove( *refLink );
+        refLink.Clear();
+    }
+}
+
+void SwOLEObj::Unload()
+{
+    if( pOLERef && pOLELRU_Cache )
+        pOLELRU_Cache->Remove( *this );
+}
+
+BOOL SwOLEObj::RemovedFromLRU()
+{
+    BOOL bRet = TRUE;
+    //Nicht notwendig im Doc DTor (MM)
+    ASSERT( pOLERef && pOLERef->Is() && 1 < (*pOLERef)->GetRefCount(),
+            "Falscher RefCount fuers Unload" );
+    const SwDoc* pDoc;
+    if( pOLERef && pOLERef->Is() && pOLENd &&
+        !( pDoc = pOLENd->GetDoc())->IsInDtor() &&
+        SVOBJ_MISCSTATUS_ALWAYSACTIVATE != (*pOLERef)->GetMiscStatus() &&
+        1 < (*pOLERef)->GetRefCount() &&
+        !(*pOLERef)->GetProtocol().IsInPlaceActive() )
+    {
+        SvPersist* p = pDoc->GetPersist();
+        if( p )
+        {
+            if( pDoc->IsPurgeOLE() )
+            {
+                SvPersist* pO = *pOLERef;
+
+                if( pO->IsModified() && !pO->IsHandsOff() )
+                {
+                    pO->DoSave();
+                    pO->DoSaveCompleted();
+                }
+
+                pOLERef->Clear();
+                if( !p->Unload( pO ) )
+                    *pOLERef = pO;
+            }
+            else
+                bRet = FALSE;
+        }
+    }
+    return bRet;
+}
+
+
+void SwOLELRUCache::Insert( SwOLEObj& rObj )
+{
+    SwOLEObj* pObj = &rObj;
+    USHORT nPos = SvPtrarr::GetPos( pObj );
+    if( nPos )  // der auf der 0. Pos muss nicht verschoben werden!
+    {
+        if( USHRT_MAX != nPos )
+            SvPtrarr::Remove( nPos );
+
+        SvPtrarr::Insert( pObj, 0 );
+
+        nPos = SvPtrarr::Count();
+        while( nPos > nLRU_InitSize )
+        {
+            pObj = (SwOLEObj*) SvPtrarr::GetObject( --nPos );
+            if( pObj->RemovedFromLRU() )
+                SvPtrarr::Remove( nPos );
+        }
+    }
+}
+
+void SwOLELRUCache::Remove( SwOLEObj& rObj )
+{
+    USHORT nPos = SvPtrarr::GetPos( &rObj );
+    if( USHRT_MAX != nPos && rObj.RemovedFromLRU() )
+        SvPtrarr::Remove( nPos );
+}
+
+
+
diff --git a/sw/source/core/para/makefile.mk b/sw/source/core/para/makefile.mk
new file mode 100644
index 000000000000..a8abea25efa7
--- /dev/null
+++ b/sw/source/core/para/makefile.mk
@@ -0,0 +1,93 @@
+#*************************************************************************
+#
+#   $RCSfile: makefile.mk,v $
+#
+#   $Revision: 1.1.1.1 $
+#
+#   last change: $Author: hr $ $Date: 2000-09-19 00:08:23 $
+#
+#   The Contents of this file are made available subject to the terms of
+#   either of the following licenses
+#
+#          - GNU Lesser General Public License Version 2.1
+#          - Sun Industry Standards Source License Version 1.1
+#
+#   Sun Microsystems Inc., October, 2000
+#
+#   GNU Lesser General Public License Version 2.1
+#   =============================================
+#   Copyright 2000 by Sun Microsystems, Inc.
+#   901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+#   This library is free software; you can redistribute it and/or
+#   modify it under the terms of the GNU Lesser General Public
+#   License version 2.1, as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   Lesser General Public License for more details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+#   License along with this library; if not, write to the Free Software
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+#   MA  02111-1307  USA
+#
+#
+#   Sun Industry Standards Source License Version 1.1
+#   =================================================
+#   The contents of this file are subject to the Sun Industry Standards
+#   Source License Version 1.1 (the "License"); You may not use this file
+#   except in compliance with the License. You may obtain a copy of the
+#   License at http://www.openoffice.org/license.html.
+#
+#   Software provided under this License is provided on an "AS IS" basis,
+#   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+#   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+#   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+#   See the License for the specific provisions governing your rights and
+#   obligations concerning the Software.
+#
+#   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+#   Copyright: 2000 by Sun Microsystems, Inc.
+#
+#   All Rights Reserved.
+#
+#   Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sw
+TARGET=para
+
+AUTOSEG=true
+
+PROJECTPCH=core_pch
+PDBTARGET=core_pch
+PROJECTPCHSOURCE=..\core_1st\core_pch
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE :  $(PRJ)$/inc$/swpre.mk
+.INCLUDE :  settings.mk
+.INCLUDE :  $(PRJ)$/inc$/sw.mk
+
+# --- Files --------------------------------------------------------
+
+CXXFILES = \
+        paratr.cxx
+
+
+
+SLOFILES =  \
+        $(SLO)$/paratr.obj
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE :  target.mk
+
diff --git a/sw/source/core/para/paratr.cxx b/sw/source/core/para/paratr.cxx
new file mode 100644
index 000000000000..d2856c7a11ca
--- /dev/null
+++ b/sw/source/core/para/paratr.cxx
@@ -0,0 +1,349 @@
+/*************************************************************************
+ *
+ *  $RCSfile: paratr.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:23 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "hintids.hxx"
+#include 
+#include "unomid.h"
+#ifndef _COM_SUN_STAR_STYLE_LINESPACINGMODE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_STYLE_PARAGRAPHADJUST_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_STYLE_DROPCAPFORMAT_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_STYLE_LINESPACING_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_RELORIENTATION_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_VERTORIENTATION_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_HORIZONTALADJUST_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_DOCUMENTSTATISTIC_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_HORIORIENTATION_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_HORIORIENTATIONFORMAT_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_NOTEPRINTMODE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_SIZETYPE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_VERTORIENTATIONFORMAT_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_WRAPTEXTMODE_HPP_
+#include 
+#endif
+#ifndef _UNOSTYLE_HXX
+#include 
+#endif
+
+
+#include "errhdl.hxx"
+#include "paratr.hxx"
+#include "charfmt.hxx"
+#include "cmdid.h"
+
+using namespace ::com::sun::star;
+
+TYPEINIT2_AUTOFACTORY( SwFmtDrop, SfxPoolItem, SwClient);
+TYPEINIT1_AUTOFACTORY( SwRegisterItem, SfxBoolItem);
+TYPEINIT1_AUTOFACTORY( SwNumRuleItem, SfxStringItem);
+
+/*************************************************************************
+|*    Beschreibung      Methoden von SwFmtDrop
+|*    Ersterstellung    MS  19.02.91
+|*    Letzte Aenderung  JP 08.08.94
+*************************************************************************/
+
+
+
+SwFmtDrop::SwFmtDrop()
+    : SfxPoolItem( RES_PARATR_DROP ),
+    SwClient( 0 ),
+    nLines( 0 ),
+    nChars( 0 ),
+    nDistance( 0 ),
+    pDefinedIn( 0 ),
+    bWholeWord( sal_False ),
+    nReadFmt( USHRT_MAX )
+{
+}
+
+
+
+SwFmtDrop::SwFmtDrop( const SwFmtDrop &rCpy )
+    : SfxPoolItem( RES_PARATR_DROP ),
+    SwClient( rCpy.pRegisteredIn ),
+    nLines( rCpy.GetLines() ),
+    nChars( rCpy.GetChars() ),
+    nDistance( rCpy.GetDistance() ),
+    bWholeWord( rCpy.GetWholeWord() ),
+    pDefinedIn( 0 ),
+    nReadFmt( rCpy.nReadFmt )
+{
+}
+
+
+
+SwFmtDrop::~SwFmtDrop()
+{
+}
+
+
+
+void SwFmtDrop::SetCharFmt( SwCharFmt *pNew )
+{
+    //Ummelden
+    if ( pRegisteredIn )
+        pRegisteredIn->Remove( this );
+    pNew->Add( this );
+    nReadFmt = USHRT_MAX;
+}
+
+
+
+void SwFmtDrop::Modify( SfxPoolItem *pA, SfxPoolItem *pB )
+{
+    if( pDefinedIn )
+    {
+        if( !pDefinedIn->ISA( SwFmt ))
+            pDefinedIn->Modify( this, this );
+        else if( pDefinedIn->GetDepends() &&
+                !pDefinedIn->IsModifyLocked() )
+        {
+            // selbst den Abhaengigen vom Format bescheid sagen. Das
+            // Format selbst wuerde es nicht weitergeben, weil es ueber
+            // die Abpruefung nicht hinauskommt.
+            SwClientIter aIter( *pDefinedIn );
+            SwClient * pLast = aIter.GoStart();
+            if( pLast )     // konnte zum Anfang gesprungen werden ??
+                do {
+                    pLast->Modify( this, this );
+                    if( !pDefinedIn->GetDepends() ) // Baum schon Weg ??
+                        break;
+                } while( 0 != ( pLast = aIter++ ));
+        }
+    }
+}
+
+
+
+sal_Bool SwFmtDrop::GetInfo( SfxPoolItem& rInfo ) const
+{
+    // fuers UNDO: pruefe ob das Attribut wirklich in diesem Format steht
+#ifdef USED_30
+    if( pDefinedIn )
+    {
+        if( IS_TYPE( SwTxtNode, pDefinedIn )
+            && ((SwTxtNode*)pDefinedIn)->....... )
+            ;
+        else if( IS_TYPE( SwTxtFmtColl, pDefinedIn )
+            && ((SwTxtFmtColl*)pDefinedIn)->....... )
+            ;
+//   this == pFmt->GetAttr( RES_PARATR_DROP, sal_False ))
+//        return pFmt->GetInfo( rInfo );
+
+    }
+#endif
+    return sal_True;    // weiter
+}
+
+
+
+int SwFmtDrop::operator==( const SfxPoolItem& rAttr ) const
+{
+    ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" );
+    return ( nLines == ((SwFmtDrop&)rAttr).GetLines() &&
+             nChars == ((SwFmtDrop&)rAttr).GetChars() &&
+             nDistance ==  ((SwFmtDrop&)rAttr).GetDistance() &&
+             bWholeWord == ((SwFmtDrop&)rAttr).GetWholeWord() &&
+             GetCharFmt() == ((SwFmtDrop&)rAttr).GetCharFmt() &&
+             pDefinedIn == ((SwFmtDrop&)rAttr).pDefinedIn );
+}
+
+
+
+SfxPoolItem* SwFmtDrop::Clone( SfxItemPool* ) const
+{
+    return new SwFmtDrop( *this );
+}
+
+
+
+
+sal_Bool SwFmtDrop::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
+{
+    switch(nMemberId&~CONVERT_TWIPS)
+    {
+        case MID_DROPCAP_FORMAT:
+        {
+             style::DropCapFormat aDrop;
+            aDrop.Lines = nLines   ;
+            aDrop.Count = nChars   ;
+            aDrop.Distance  = TWIP_TO_MM100(nDistance);
+            rVal.setValue(&aDrop, ::getCppuType((const style::DropCapFormat*)0));
+        }
+        break;
+        case MID_DROPCAP_WHOLE_WORD:
+            rVal.setValue(&bWholeWord, ::getBooleanCppuType());
+        break;
+        case MID_DROPCAP_CHAR_STYLE_NAME :
+        {
+            rtl::OUString sName;
+            if(GetCharFmt())
+                sName = SwXStyleFamilies::GetProgrammaticName(
+                        GetCharFmt()->GetName(), SFX_STYLE_FAMILY_CHAR);
+            rVal <<= sName;
+        }
+        break;
+    }
+    return sal_True;
+}
+
+sal_Bool SwFmtDrop::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
+{
+    switch(nMemberId&~CONVERT_TWIPS)
+    {
+        case MID_DROPCAP_FORMAT:
+        {
+            if(rVal.getValueType()  == ::getCppuType((const style::DropCapFormat*)0))
+            {
+                const style::DropCapFormat* pDrop = (const style::DropCapFormat*)rVal.getValue();
+                nLines      = pDrop->Lines;
+                nChars      = pDrop->Count;
+                nDistance   = MM100_TO_TWIP(pDrop->Distance);
+            }
+            else
+                //exception( wrong_type)
+                ;
+        }
+        break;
+        case MID_DROPCAP_WHOLE_WORD:
+            bWholeWord = *(sal_Bool*)rVal.getValue();
+        break;
+        case MID_DROPCAP_CHAR_STYLE_NAME :
+            DBG_ERROR("char format cannot be set in PutValue()!")
+        break;
+    }
+    return sal_True;
+}
+
+// class SwRegisterItem -------------------------------------------------
+
+
+SfxPoolItem* SwRegisterItem::Clone( SfxItemPool * ) const
+{
+    return new SwRegisterItem( *this );
+}
+
+// class SwNumRuleItem -------------------------------------------------
+SfxPoolItem* SwNumRuleItem::Clone( SfxItemPool *pPool  ) const
+{
+    return new SwNumRuleItem( *this );
+}
+int SwNumRuleItem::operator==( const SfxPoolItem& rAttr ) const
+{
+    ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" );
+    return GetValue() == ((SwNumRuleItem&)rAttr).GetValue() &&
+            GetDefinedIn() == ((SwNumRuleItem&)rAttr).GetDefinedIn();
+}
+/* -----------------------------27.06.00 11:05--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL    SwNumRuleItem::QueryValue( com::sun::star::uno::Any& rVal, BYTE nMemberId ) const
+{
+    rtl::OUString sRet = SwXStyleFamilies::GetProgrammaticName(GetValue(), SFX_STYLE_FAMILY_PSEUDO);
+    rVal <<= sRet;
+    return TRUE;
+}
+/* -----------------------------27.06.00 11:05--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL    SwNumRuleItem::PutValue( const com::sun::star::uno::Any& rVal, BYTE nMemberId )
+{
+    rtl::OUString uName;
+    rVal >>= uName;
+    SetValue(SwXStyleFamilies::GetUIName(uName, SFX_STYLE_FAMILY_PSEUDO));
+    return TRUE;
+}
+
+
+
+
diff --git a/sw/source/core/sw3io/makefile.mk b/sw/source/core/sw3io/makefile.mk
new file mode 100644
index 000000000000..016610d7dc8f
--- /dev/null
+++ b/sw/source/core/sw3io/makefile.mk
@@ -0,0 +1,136 @@
+#*************************************************************************
+#
+#   $RCSfile: makefile.mk,v $
+#
+#   $Revision: 1.1.1.1 $
+#
+#   last change: $Author: hr $ $Date: 2000-09-19 00:08:23 $
+#
+#   The Contents of this file are made available subject to the terms of
+#   either of the following licenses
+#
+#          - GNU Lesser General Public License Version 2.1
+#          - Sun Industry Standards Source License Version 1.1
+#
+#   Sun Microsystems Inc., October, 2000
+#
+#   GNU Lesser General Public License Version 2.1
+#   =============================================
+#   Copyright 2000 by Sun Microsystems, Inc.
+#   901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+#   This library is free software; you can redistribute it and/or
+#   modify it under the terms of the GNU Lesser General Public
+#   License version 2.1, as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   Lesser General Public License for more details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+#   License along with this library; if not, write to the Free Software
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+#   MA  02111-1307  USA
+#
+#
+#   Sun Industry Standards Source License Version 1.1
+#   =================================================
+#   The contents of this file are subject to the Sun Industry Standards
+#   Source License Version 1.1 (the "License"); You may not use this file
+#   except in compliance with the License. You may obtain a copy of the
+#   License at http://www.openoffice.org/license.html.
+#
+#   Software provided under this License is provided on an "AS IS" basis,
+#   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+#   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+#   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+#   See the License for the specific provisions governing your rights and
+#   obligations concerning the Software.
+#
+#   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+#   Copyright: 2000 by Sun Microsystems, Inc.
+#
+#   All Rights Reserved.
+#
+#   Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sw
+TARGET=sw3io
+
+AUTOSEG=true
+
+PROJECTPCH=core_pch
+PDBTARGET=core_pch
+PROJECTPCHSOURCE=..$/core_1st$/core_pch
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE :  $(PRJ)$/inc$/swpre.mk
+.INCLUDE :  settings.mk
+.INCLUDE :  $(PRJ)$/inc$/sw.mk
+
+.IF "$(GUI)$(COM)" == "WINMSC"
+LIBFLAGS=/NOI /NOE /PAGE:512
+.ENDIF
+
+# --- Files --------------------------------------------------------
+
+CXXFILES = \
+    sw3io.cxx		\
+    sw3attr.cxx 	\
+    swacorr.cxx 	\
+    sw3block.cxx	\
+    sw3doc.cxx		\
+    sw3field.cxx	\
+    sw3fmts.cxx 	\
+    sw3frame.cxx	\
+    sw3frmio.cxx	\
+    sw3imp.cxx		\
+    sw3misc.cxx 	\
+    sw3nodes.cxx	\
+    sw3npool.cxx	\
+    sw3num.cxx		\
+    sw3page.cxx 	\
+    sw3redln.cxx 	\
+    sw3sectn.cxx	\
+    sw3style.cxx	\
+    sw3table.cxx	\
+    sw3gsect.cxx	\
+    swacorr.cxx 	\
+    crypter.cxx
+
+SLOFILES = \
+    $(SLO)$/sw3io.obj	\
+    $(SLO)$/sw3attr.obj	\
+    $(SLO)$/sw3block.obj \
+    $(SLO)$/sw3doc.obj	\
+    $(SLO)$/sw3field.obj \
+    $(SLO)$/sw3fmts.obj	\
+    $(SLO)$/sw3frame.obj \
+    $(SLO)$/sw3frmio.obj \
+    $(SLO)$/sw3imp.obj	\
+    $(SLO)$/sw3misc.obj	\
+    $(SLO)$/sw3nodes.obj \
+    $(SLO)$/sw3npool.obj \
+    $(SLO)$/sw3num.obj	\
+    $(SLO)$/sw3page.obj	\
+    $(SLO)$/sw3redln.obj	\
+    $(SLO)$/sw3sectn.obj \
+    $(SLO)$/sw3style.obj \
+    $(SLO)$/sw3table.obj \
+    $(SLO)$/sw3gsect.obj \
+    $(SLO)$/swacorr.obj	\
+    $(SLO)$/crypter.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE :  target.mk
+
diff --git a/sw/source/core/sw3io/swacorr.cxx b/sw/source/core/sw3io/swacorr.cxx
new file mode 100644
index 000000000000..41900a40ab9b
--- /dev/null
+++ b/sw/source/core/sw3io/swacorr.cxx
@@ -0,0 +1,145 @@
+/*************************************************************************
+ *
+ *  $RCSfile: swacorr.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:23 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _URLOBJ_HXX //autogen
+#include 
+#endif
+
+#include "swacorr.hxx"
+#include "swblocks.hxx"
+#include "swerror.h"
+#include "docsh.hxx"
+#include "editsh.hxx"
+
+
+
+TYPEINIT1( SwAutoCorrect, SvxAutoCorrect );
+
+
+    //  - return den Ersetzungstext (nur fuer SWG-Format, alle anderen
+    //      koennen aus der Wortliste herausgeholt werden!)
+    //      rShort ist der Stream-Name - gecryptet!
+BOOL SwAutoCorrect::GetLongText( SvStorage& rStg,
+                            const String& rShort, String& rLong )
+{
+    Sw3TextBlocks aBlk( rStg );
+    ULONG nRet = aBlk.GetText( rShort, rLong );
+    return !IsError( nRet ) && rLong.Len();
+}
+
+
+    //  - Text mit Attributierung (kann nur der SWG - SWG-Format!)
+    //      rShort ist der Stream-Name - gecryptet!
+BOOL SwAutoCorrect::PutText( SvStorage& rStg, const String& rShort,
+                            SfxObjectShell& rObjSh, String& rLong )
+{
+    if( !rObjSh.IsA( TYPE(SwDocShell) ) )
+        return FALSE;
+
+    SwDocShell& rDShell = (SwDocShell&)rObjSh;
+    Sw3TextBlocks aBlk( rStg );
+
+    SwDoc* pDoc = aBlk.GetDoc();
+
+    // Bis es eine Option dafuer gibt, base URL loeschen
+    const String aOldURL( INetURLObject::GetBaseURL() );
+    INetURLObject::SetBaseURL( aEmptyStr );
+
+    ULONG nRet = aBlk.BeginPutDoc( rShort, rShort );
+    if( !IsError( nRet ) )
+    {
+        ((SwEditShell*)rDShell.GetWrtShell())->_CopySelToDoc( pDoc );
+        nRet = aBlk.PutDoc();
+        if( !IsError( nRet ) )
+            nRet = aBlk.GetText( rShort, rLong );
+    }
+
+    INetURLObject::SetBaseURL( aOldURL );
+
+    return !IsError( nRet );
+}
+
+
+SwAutoCorrect::SwAutoCorrect( const String& rAutocorrFile )
+    : SvxAutoCorrect( rAutocorrFile )
+{
+    SwEditShell::SetAutoFmtFlags(&GetSwFlags());
+    // Konvertierung ??
+}
+
+SwAutoCorrect::SwAutoCorrect( const SvxAutoCorrect& rACorr )
+    : SvxAutoCorrect( rACorr )
+{
+    SwEditShell::SetAutoFmtFlags(&GetSwFlags());
+}
+
+SwAutoCorrect::~SwAutoCorrect()
+{
+}
+
+
+
diff --git a/sw/source/core/swg/makefile.mk b/sw/source/core/swg/makefile.mk
new file mode 100644
index 000000000000..c26d14c5f0f9
--- /dev/null
+++ b/sw/source/core/swg/makefile.mk
@@ -0,0 +1,124 @@
+#*************************************************************************
+#
+#   $RCSfile: makefile.mk,v $
+#
+#   $Revision: 1.1.1.1 $
+#
+#   last change: $Author: hr $ $Date: 2000-09-19 00:08:23 $
+#
+#   The Contents of this file are made available subject to the terms of
+#   either of the following licenses
+#
+#          - GNU Lesser General Public License Version 2.1
+#          - Sun Industry Standards Source License Version 1.1
+#
+#   Sun Microsystems Inc., October, 2000
+#
+#   GNU Lesser General Public License Version 2.1
+#   =============================================
+#   Copyright 2000 by Sun Microsystems, Inc.
+#   901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+#   This library is free software; you can redistribute it and/or
+#   modify it under the terms of the GNU Lesser General Public
+#   License version 2.1, as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   Lesser General Public License for more details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+#   License along with this library; if not, write to the Free Software
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+#   MA  02111-1307  USA
+#
+#
+#   Sun Industry Standards Source License Version 1.1
+#   =================================================
+#   The contents of this file are subject to the Sun Industry Standards
+#   Source License Version 1.1 (the "License"); You may not use this file
+#   except in compliance with the License. You may obtain a copy of the
+#   License at http://www.openoffice.org/license.html.
+#
+#   Software provided under this License is provided on an "AS IS" basis,
+#   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+#   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+#   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+#   See the License for the specific provisions governing your rights and
+#   obligations concerning the Software.
+#
+#   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+#   Copyright: 2000 by Sun Microsystems, Inc.
+#
+#   All Rights Reserved.
+#
+#   Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sw
+TARGET=swg
+
+AUTOSEG=true
+
+PROJECTPCH=core_pch
+PDBTARGET=core_pch
+PROJECTPCHSOURCE=..$/core_1st$/core_pch
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE :  $(PRJ)$/inc$/swpre.mk
+.INCLUDE :  settings.mk
+.INCLUDE :  $(PRJ)$/inc$/sw.mk
+
+.IF "$(GUI)$(COM)" == "WINMSC"
+LIBFLAGS=/NOI /NOE /PAGE:512
+.ENDIF
+
+# --- Files --------------------------------------------------------
+
+CXXFILES = \
+        rdcont.cxx \
+        rdflds.cxx \
+        rdfmts.cxx \
+        rdhnt.cxx \
+        rdmisc.cxx \
+        rdnds.cxx \
+        rdnum.cxx \
+        rdpage.cxx \
+        rdswg.cxx \
+        rdtox.cxx \
+        swgpar.cxx \
+        swgstr.cxx \
+        sw2block.cxx \
+        swblocks.cxx
+
+SLOFILES =  \
+        $(SLO)$/rdcont.obj \
+        $(SLO)$/rdflds.obj \
+        $(SLO)$/rdfmts.obj \
+        $(SLO)$/rdhnt.obj \
+        $(SLO)$/rdmisc.obj \
+        $(SLO)$/rdnds.obj \
+        $(SLO)$/rdnum.obj \
+        $(SLO)$/rdpage.obj \
+        $(SLO)$/rdswg.obj \
+        $(SLO)$/rdtox.obj \
+        $(SLO)$/swgpar.obj \
+        $(SLO)$/swgstr.obj \
+        $(SLO)$/sw2block.obj \
+        $(SLO)$/swblocks.obj
+
+EXCEPTIONSFILES = \
+        $(SLO)$/swblocks.obj
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE :  target.mk
+
diff --git a/sw/source/core/swg/swblocks.cxx b/sw/source/core/swg/swblocks.cxx
new file mode 100644
index 000000000000..ae51f6af9025
--- /dev/null
+++ b/sw/source/core/swg/swblocks.cxx
@@ -0,0 +1,955 @@
+/*************************************************************************
+ *
+ *  $RCSfile: swblocks.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:24 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _SFX_DOCFILT_HACK_HXX //autogen
+#include 
+#endif
+#ifndef _SVSTOR_HXX //autogen
+#include 
+#endif
+#ifndef _URLOBJ_HXX
+#include 
+#endif
+#ifndef _COM_SUN_STAR_UCB_XCOMMANDENVIRONMENT_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_UCB_TRANSFERINFO_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_UCB_NAMECLASH_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_UTIL_DATETIME_HPP_
+#include 
+#endif
+#ifndef _UCBHELPER_CONTENT_HXX
+#include 
+#endif
+#ifndef _UNOTOOLS_CHARCLASS_HXX
+#include 
+#endif
+
+#ifndef _FRMFMT_HXX //autogen
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _SHELLIO_HXX
+#include 
+#endif
+#ifndef _SWBLOCKS_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _MDIEXP_HXX
+#include        // Progress
+#endif
+#ifndef _STATSTR_HRC
+#include 
+#endif
+#ifndef _SWSWERROR_H
+#include 
+#endif
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::uno;
+using namespace ::rtl;
+
+#define C2U(cChar) rtl::OUString::createFromAscii(cChar)
+SV_IMPL_OP_PTRARR_SORT( SwBlockNames, SwBlockName* );
+
+//////////////////////////////////////////////////////////////////////////
+
+// Hash-Code errechnen (muss nicht eindeutig sein)
+
+
+USHORT SwImpBlocks::Hash( const String& r )
+{
+    USHORT n = 0;
+    xub_StrLen nLen = r.Len();
+    if( nLen > 8 ) nLen = 8;
+    const sal_Unicode* p = (const sal_Unicode*) r.GetBuffer();
+    while( nLen-- ) n = ( n << 1 ) + *p++;
+    return n;
+}
+
+
+SwBlockName::SwBlockName( const String& rShort, const String& rLong, long n )
+    : aShort( rShort ), aLong( rLong ), nPos( n ),
+    bIsOnlyTxtFlagInit( FALSE ), bIsOnlyTxt( FALSE )
+{
+    nHashS = SwImpBlocks::Hash( rShort );
+    nHashL = SwImpBlocks::Hash( rLong );
+}
+
+
+// Ist die angegebene Datei ein Storage oder gibt es sie nicht?
+
+short SwImpBlocks::GetFileType( const String& rFile )
+{
+    BOOL bExist = FALSE;
+    try
+    {
+        ::ucb::Content aTestContent(
+            rFile,
+            uno::Reference< XCommandEnvironment >());
+        bExist = aTestContent.isDocument();
+    }
+    catch(...)
+    {
+        bExist = FALSE;
+    }
+
+    if( !bExist )
+        return SWBLK_NO_FILE;
+    if( SvStorage::IsStorageFile( rFile ) )
+        return SWBLK_SW3;
+    // Kein Storage: Ist es eine SWG-Datei?
+    const SfxFilter* pFltr = SwIoSystem::GetFileFilter( rFile, aEmptyStr );
+    return( pFltr && pFltr->GetUserData().EqualsAscii(FILTER_SWG) )
+                            ? SWBLK_SW2 : SWBLK_NONE;
+}
+
+
+SwImpBlocks::SwImpBlocks( const String& rFile, BOOL bMake )
+    : aFile( rFile ), bReadOnly( TRUE ), bInPutMuchBlocks( FALSE ),
+    nCur( (USHORT)-1 ), pDoc( 0 )
+{
+    try
+    {
+        ::ucb::Content aTestContent(
+        rFile,
+        uno::Reference< XCommandEnvironment >());
+        uno::Any aAny = aTestContent.getPropertyValue( C2U("DateModified") );
+        if(aAny.hasValue())
+        {
+            const util::DateTime* pDT = (util::DateTime*)aAny.getValue();
+            aDateModified = Date(pDT->Day, pDT->Month, pDT->Year);
+            aTimeModified = Time(pDT->Hours, pDT->Minutes, pDT->Seconds, pDT->HundredthSeconds);
+        }
+    }
+    catch(...)
+    {
+        DBG_ERROR("exception caught")
+    }
+    INetURLObject aObj(rFile);
+    aName = aObj.GetBase();
+    aName.Erase(aName.Len() - 4, 4); //remove extension
+//  aDEntry.SetExtension( aEmptyStr );
+//  aName = aDEntry.GetName();
+}
+
+
+SwImpBlocks::~SwImpBlocks()
+{
+    aNames.DeleteAndDestroy( 0, aNames.Count() );
+}
+
+// Loeschen des Inhaltes des Dokuments
+
+
+void SwImpBlocks::ClearDoc()
+{
+    pDoc->ClearDoc();
+}
+
+// Erzeugen eines PaMs, der das ganze Dokument umfasst
+
+
+SwPaM* SwImpBlocks::MakePaM()
+{
+    SwPaM* pPam = new SwPaM( pDoc->GetNodes().GetEndOfContent() );
+    pPam->Move( fnMoveBackward, fnGoDoc );
+    pPam->SetMark();
+    pPam->Move( fnMoveForward, fnGoDoc );
+    pPam->Exchange();
+    return pPam;
+}
+
+
+USHORT SwImpBlocks::GetCount() const
+{
+    return aNames.Count();
+}
+
+// Case Insensitive
+
+
+USHORT SwImpBlocks::GetIndex( const String& rShort ) const
+{
+    String s( GetAppCharClass().upper( rShort ) );
+    USHORT nHash = Hash( s );
+    for( USHORT i = 0; i < aNames.Count(); i++ )
+    {
+        SwBlockName* pName = aNames[ i ];
+        if( pName->nHashS == nHash
+         && pName->aShort == s )
+            return i;
+    }
+    return (USHORT) -1;
+}
+
+
+USHORT SwImpBlocks::GetLongIndex( const String& rLong ) const
+{
+    USHORT nHash = Hash( rLong );
+    for( USHORT i = 0; i < aNames.Count(); i++ )
+    {
+        SwBlockName* pName = aNames[ i ];
+        if( pName->nHashL == nHash
+         && pName->aLong == rLong )
+            return i;
+    }
+    return (USHORT) -1;
+}
+
+
+const String& SwImpBlocks::GetShortName( USHORT n ) const
+{
+    if( n < aNames.Count() )
+        return aNames[ n ]->aShort;
+    return aEmptyStr;
+}
+
+
+const String& SwImpBlocks::GetLongName( USHORT n ) const
+{
+    if( n < aNames.Count() )
+        return aNames[ n ]->aLong;
+    return aEmptyStr;
+}
+
+
+void SwImpBlocks::AddName( const String& rShort, const String& rLong,
+                            BOOL bOnlyTxt )
+{
+    USHORT nIdx = GetIndex( rShort );
+    if( nIdx != (USHORT) -1 )
+        aNames.DeleteAndDestroy( nIdx );
+    SwBlockName* pNew = new SwBlockName( rShort, rLong, 0L );
+    pNew->bIsOnlyTxtFlagInit = TRUE;
+    pNew->bIsOnlyTxt = bOnlyTxt;
+    aNames.C40_PTR_INSERT( SwBlockName, pNew );
+}
+
+
+BOOL SwImpBlocks::IsFileChanged() const
+{
+    Date aTempDateModified( aDateModified );
+    Time aTempTimeModified( aTimeModified );
+    try
+    {
+        ::ucb::Content aTestContent(
+        aFile,
+        uno::Reference< XCommandEnvironment >());
+        uno::Any aAny = aTestContent.getPropertyValue( C2U("DateModified") );
+        if(aAny.hasValue())
+        {
+            const util::DateTime* pDT = (util::DateTime*)aAny.getValue();
+            aTempDateModified = Date(pDT->Day, pDT->Month, pDT->Year);
+            aTempTimeModified = Time(pDT->Hours, pDT->Minutes, pDT->Seconds, pDT->HundredthSeconds);
+        }
+    }
+    catch(...)
+    {
+        DBG_ERROR("exception caught")
+    }
+    return aDateModified != aTempDateModified ||
+            aTimeModified != aTempTimeModified;
+}
+
+
+void SwImpBlocks::Touch()
+{
+    try
+    {
+        ::ucb::Content aTestContent(
+        aFile,
+        uno::Reference< XCommandEnvironment >());
+        uno::Any aAny = aTestContent.getPropertyValue( C2U("DateModified") );
+        if(aAny.hasValue())
+        {
+            const util::DateTime* pDT = (util::DateTime*)aAny.getValue();
+            aDateModified = Date(pDT->Day, pDT->Month, pDT->Year);
+            aTimeModified = Time(pDT->Hours, pDT->Minutes, pDT->Seconds, pDT->HundredthSeconds);
+        }
+    }
+    catch(...)
+    {
+        DBG_ERROR("exception caught")
+    }
+}
+
+BOOL SwImpBlocks::IsOnlyTextBlock( const String& ) const
+{
+    return FALSE;
+}
+
+ULONG SwImpBlocks::GetMacroTable( USHORT, SvxMacroTableDtor& )
+{
+    return 0;
+}
+
+BOOL SwImpBlocks::PutMuchEntries( BOOL bOn )
+{
+    return FALSE;
+}
+
+////////////////////////////////////////////////////////////////////////////
+
+
+SwTextBlocks::SwTextBlocks( const String& rFile )
+    : pImp( 0 ), nErr( 0 )
+{
+    INetURLObject aObj(rFile);
+    String sFileName = aObj.GetMainURL();
+    switch( SwImpBlocks::GetFileType( rFile ) )
+    {
+        case SWBLK_SW2:
+            pImp = new Sw2TextBlocks( sFileName ); break;
+        case SWBLK_SW3:
+            pImp = new Sw3TextBlocks( sFileName ); break;
+        case SWBLK_NO_FILE:
+            pImp = new Sw3TextBlocks( sFileName ); break;
+    }
+    if( !pImp )
+        nErr = ERR_SWG_FILE_FORMAT_ERROR;
+}
+
+
+SwTextBlocks::SwTextBlocks( SvStorage& rStg )
+    : nErr( 0 )
+{
+    pImp = new Sw3TextBlocks( rStg );
+}
+
+
+SwTextBlocks::~SwTextBlocks()
+{
+    delete pImp;
+}
+
+
+const String& SwTextBlocks::GetName()
+{
+    return pImp ? pImp->aName : aEmptyStr;
+}
+
+
+void SwTextBlocks::SetName( const String& r )
+{
+    if( pImp )
+        pImp->SetName( r );
+}
+
+
+BOOL SwTextBlocks::IsOld() const
+{
+    return pImp ? pImp->IsOld() : FALSE;
+}
+
+
+ULONG SwTextBlocks::ConvertToNew()
+{
+    // Wir nehmen die aktuelle Datei, benennen diese in .BAK um
+    // und kreieren den neuen Storage
+    if( IsOld() )
+    {
+        // Erst mal muessen wir die Datei freigeben
+        pImp->nCur = (USHORT) -1;
+        String aName( pImp->aFile );
+        delete pImp; pImp = NULL;
+        // Jetzt wird umbenannt
+        INetURLObject aOldFull( aName );
+        INetURLObject aNewFull( aName );
+        aOldFull.SetExtension( String::CreateFromAscii("bak") );
+        String aOld( aOldFull.GetFull() );
+        BOOL bError = FALSE;
+        try
+        {
+            String sMain(aOldFull.GetMainURL());
+            sal_Unicode cSlash = '/';
+            xub_StrLen nSlashPos = sMain.SearchBackward(cSlash);
+            sMain.Erase(nSlashPos);
+            ::ucb::Content aNewContent( sMain,
+                                        Reference< XCommandEnvironment > ());
+            Any aAny;
+            TransferInfo aInfo;
+            aInfo.NameClash = NameClash::OVERWRITE;
+            aInfo.NewTitle = aOldFull.GetName();
+            aInfo.SourceURL = aNewFull.GetMainURL();
+            aInfo.MoveData  = TRUE;
+            aAny <<= aInfo;
+            aNewContent.executeCommand( C2U( "transfer" ), aAny);
+        }
+        catch(...)
+        {
+            bError = TRUE;
+        }
+
+        if( bError )
+        {
+            pImp = new Sw2TextBlocks( aName );
+            return nErr = ERR_SWG_CANNOT_WRITE;
+        }
+
+        // Die Datei ist erfolgreich umbenannt. Jetzt wird der Storage
+        // aufgesetzt
+        Sw2TextBlocks* pOld = new Sw2TextBlocks( aOld );
+        Sw3TextBlocks* pNew = new Sw3TextBlocks( aName );
+        // Wir kopieren den Doc-Ptr in das alte System
+        // den alten SvPersist heben wir uns aber auf,
+        // da dieser die ganze Zeit leben bleibt
+        SvPersist* pPersist2 = pOld->pDoc->GetPersist();
+        delete pOld->pDoc; pOld->pDoc = pNew->pDoc;
+        // und lesen die Dateivorlagen erneut ein
+        nErr = pOld->LoadDoc();
+        if( !nErr && 0 == ( nErr = pNew->OpenFile( FALSE )) )
+        {
+            nErr = pNew->SetConvertMode( TRUE );
+            // jetzt werden die Bausteine einfach umkopiert!
+            if( !nErr )
+            {
+                pOld->StatLineStartPercent();
+                for( USHORT i = 0; i < pOld->GetCount(); i++ )
+                {
+                    pNew->ClearDoc();
+                    pNew->pDoc->SetPersist( pPersist2 );
+                    nErr = pOld->GetDoc( i );
+                    if( nErr )
+                        break;
+                    String aShort( pOld->GetShortName( i ) );
+                    String aLong( pOld->GetLongName( i ) );
+                    nErr = pNew->BeginPutDoc( aShort, aLong );
+                    if( nErr )
+                        break;
+                    nErr = pNew->PutDoc();
+                    if( nErr )
+                        break;
+                    pNew->AddName( aShort, aLong );
+                    pNew->pDoc->SetPersist( 0 );
+                }
+                ::EndProgress( pOld->pDoc->GetDocShell() );
+            }
+            if( !nErr )
+                nErr = pNew->SetConvertMode( FALSE );
+        }
+        // Haben wir es geschafft?
+        pOld->pDoc = NULL;
+        pNew->ClearDoc();
+        if( !nErr )
+        {
+            delete pOld;
+            pImp = pNew;
+            try
+            {
+                ::ucb::Content aOldContent(
+                        aOldFull.GetMainURL(),
+                        Reference< XCommandEnvironment > ());
+                aOldContent.executeCommand( C2U( "delete" ),
+                                    makeAny( sal_Bool( sal_True ) ) );
+            }
+            catch(...){}
+            pNew->MakeBlockList();
+        }
+        else
+        {
+            delete pOld; delete pNew;
+            try
+            {
+                String sMain(aNewFull.GetMainURL());
+                sal_Unicode cSlash = '/';
+                xub_StrLen nSlashPos = sMain.SearchBackward(cSlash);
+                sMain.Erase(nSlashPos);
+                ::ucb::Content aNewContent( sMain, Reference< XCommandEnvironment > ());
+                Any aAny;
+                TransferInfo aInfo;
+                aInfo.NameClash = NameClash::OVERWRITE;
+                aInfo.NewTitle = aNewFull.GetName();
+                aInfo.SourceURL = aOldFull.GetMainURL();
+                aInfo.MoveData  = TRUE;
+                aAny <<= aInfo;
+                aNewContent.executeCommand( C2U( "transfer" ), aAny);
+            }
+            catch(...){}
+            pImp = new Sw2TextBlocks( aName );
+        }
+        pNew->CloseFile();
+
+        try
+        {
+            ::ucb::Content aContent(
+                aNewFull.GetMainURL(), Reference< XCommandEnvironment > ());
+            aContent.executeCommand( C2U( "delete" ), makeAny( sal_Bool( sal_True ) ) );
+            uno::Any aAny = aContent.getPropertyValue( C2U("DateModified") );
+            if(aAny.hasValue())
+            {
+                const util::DateTime* pDT = (util::DateTime*)aAny.getValue();
+                pImp->aDateModified = Date(pDT->Day, pDT->Month, pDT->Year);
+                pImp->aTimeModified = Time(pDT->Hours, pDT->Minutes, pDT->Seconds, pDT->HundredthSeconds);
+            }
+        }
+        catch(...){}
+    }
+    return nErr;
+}
+
+
+USHORT SwTextBlocks::GetCount() const
+{
+    return pImp ? pImp->GetCount() : 0;
+}
+
+
+USHORT SwTextBlocks::GetIndex( const String& r ) const
+{
+    return pImp ? pImp->GetIndex( r ) : (USHORT) -1;
+}
+
+
+USHORT SwTextBlocks::GetLongIndex( const String& r ) const
+{
+    return pImp ? (USHORT)(pImp->GetLongIndex( r )) : (USHORT) -1;
+}
+
+
+const String& SwTextBlocks::GetShortName( USHORT n ) const
+{
+    if( pImp )
+        return pImp->GetShortName( n );
+    return aEmptyStr;
+}
+
+
+const String& SwTextBlocks::GetLongName( USHORT n ) const
+{
+    if( pImp )
+        return pImp->GetLongName( n );
+    return aEmptyStr;
+}
+
+
+BOOL SwTextBlocks::Delete( USHORT n )
+{
+    if( pImp && !pImp->bInPutMuchBlocks )
+    {
+        if( pImp->IsFileChanged() )
+            nErr = ERR_TXTBLOCK_NEWFILE_ERROR;
+        else if( 0 == (nErr = pImp->OpenFile( FALSE ) ))
+        {
+            nErr = pImp->Delete( n );
+            if( !nErr )
+                pImp->aNames.DeleteAndDestroy( n );
+            if( n == pImp->nCur )
+                pImp->nCur = (USHORT) -1;
+            if( !nErr )
+                nErr = pImp->MakeBlockList();
+        }
+        pImp->CloseFile();
+        pImp->Touch();
+
+        return BOOL( nErr == 0 );
+    }
+    return FALSE;
+}
+
+
+USHORT SwTextBlocks::Rename( USHORT n, const String* s, const String* l )
+{
+    USHORT nIdx = (USHORT)-1;
+    if( pImp && !pImp->bInPutMuchBlocks )
+    {
+        pImp->nCur = nIdx;
+        String aNew, aLong;
+        if( s )
+            aNew = aLong = *s;
+        if( l )
+            aLong = *l;
+        if( !aNew.Len() )
+        {
+            ASSERT( !this, "Kein Kurzname in Rename angegeben" );
+            nErr = ERR_SWG_INTERNAL_ERROR; return (USHORT) -1;
+        }
+
+        if( pImp->IsFileChanged() )
+            nErr = ERR_TXTBLOCK_NEWFILE_ERROR;
+        else if( 0 == ( nErr = pImp->OpenFile( FALSE )))
+        {
+            // Vorher den neuen Eintrag in die Liste setzen!
+            GetAppCharClass().toUpper( aNew );
+            nErr = pImp->Rename( n, aNew, aLong );
+            if( !nErr )
+            {
+                BOOL bOnlyTxt = pImp->aNames[ n ]->bIsOnlyTxt;
+                pImp->aNames.DeleteAndDestroy( n );
+                pImp->AddName( aNew, aLong, bOnlyTxt );
+                nErr = pImp->MakeBlockList();
+            }
+        }
+        pImp->CloseFile();
+        pImp->Touch();
+        if( !nErr )
+            nIdx = pImp->GetIndex( aNew );
+    }
+    return nIdx;
+}
+
+ULONG SwTextBlocks::CopyBlock( SwTextBlocks& rSource, String& rSrcShort,
+                                const String& rLong )
+{
+    if( rSource.IsOld() )
+        nErr = ERR_SWG_OLD_GLOSSARY;
+    else if( pImp->bInPutMuchBlocks )
+        nErr = ERR_SWG_INTERNAL_ERROR;
+    else
+        nErr = pImp->CopyBlock(*rSource.pImp, rSrcShort, rLong);
+    return nErr;
+}
+
+BOOL SwTextBlocks::BeginGetDoc( USHORT n )
+{
+    if( pImp && !pImp->bInPutMuchBlocks )
+    {
+// diese Optimierierung darf es nicht mehr geben. OLE-Objecte muessen auf
+// ihre SubStorages zugreifem koennen!
+//      if( n == pImp->nCur )
+//          return TRUE;
+
+        if( pImp->IsFileChanged() )
+            nErr = ERR_TXTBLOCK_NEWFILE_ERROR;
+        else if( 0 == ( nErr = pImp->OpenFile( TRUE )))
+        {
+            pImp->ClearDoc();
+            nErr = pImp->GetDoc( n );
+            if( nErr )
+                pImp->nCur = (USHORT)-1;
+            else
+                pImp->nCur = n;
+        }
+        return BOOL( nErr == 0 );
+    }
+    return FALSE;
+}
+
+
+void SwTextBlocks::EndGetDoc()
+{
+    if( pImp && !pImp->bInPutMuchBlocks )
+        pImp->CloseFile();
+}
+
+
+BOOL SwTextBlocks::BeginPutDoc( const String& s, const String& l )
+{
+    if( pImp )
+    {
+        BOOL bOk = pImp->bInPutMuchBlocks;
+        if( !bOk )
+        {
+            if( pImp->IsFileChanged() )
+                nErr = ERR_TXTBLOCK_NEWFILE_ERROR;
+            else
+                nErr = pImp->OpenFile( FALSE );
+            bOk = 0 == nErr;
+        }
+        if( bOk )
+        {
+            String aNew( s );
+            GetAppCharClass().toUpper( aNew );
+            nErr = pImp->BeginPutDoc( aNew, l );
+        }
+        if( nErr )
+            pImp->CloseFile();
+    }
+    return 0 == nErr;
+}
+
+
+USHORT SwTextBlocks::PutDoc()
+{
+    USHORT nIdx = (USHORT)-1;
+    if( pImp )
+    {
+        nErr = pImp->PutDoc();
+        if( !nErr )
+        {
+            pImp->nCur = GetIndex( pImp->aShort );
+            if( pImp->nCur != (USHORT) -1 )
+                pImp->aNames[ pImp->nCur ]->aLong = pImp->aLong;
+            else
+            {
+                pImp->AddName( pImp->aShort, pImp->aLong );
+                pImp->nCur = pImp->GetIndex( pImp->aShort );
+                if( !pImp->bInPutMuchBlocks )
+                    nErr = pImp->MakeBlockList();
+            }
+        }
+        if( !pImp->bInPutMuchBlocks )
+        {
+            pImp->CloseFile();
+            pImp->Touch();
+        }
+        nIdx = pImp->nCur;
+    }
+    return nIdx;
+}
+
+
+const String& SwTextBlocks::GetText( USHORT n )
+{
+    if( pImp && !pImp->bInPutMuchBlocks )
+    {
+        if( pImp->IsFileChanged() )
+            nErr = ERR_TXTBLOCK_NEWFILE_ERROR;
+        else if( 0 == ( nErr = pImp->OpenFile( TRUE )))
+        {
+            nErr = pImp->GetText( n, pImp->aCur );
+            pImp->CloseFile();
+            if( !nErr )
+                return pImp->aCur;
+        }
+    }
+    return aEmptyStr;
+}
+
+
+USHORT SwTextBlocks::PutText( const String& rShort, const String& rName,
+                              const String& rTxt )
+{
+    USHORT nIdx = (USHORT) -1;
+    if( pImp )
+    {
+        BOOL bOk = pImp->bInPutMuchBlocks;
+        if( !bOk )
+        {
+            if( pImp->IsFileChanged() )
+                nErr = ERR_TXTBLOCK_NEWFILE_ERROR;
+            else
+                nErr = pImp->OpenFile( FALSE );
+            bOk = 0 == nErr;
+        }
+        if( bOk )
+        {
+            String aNew( rShort );
+            GetAppCharClass().toUpper( aNew );
+            nErr = pImp->PutText( aNew, rName, rTxt );
+            pImp->nCur = (USHORT) -1;
+            if( !nErr )
+            {
+                nIdx = GetIndex( pImp->aShort );
+                if( nIdx != (USHORT) -1 )
+                    pImp->aNames[ nIdx ]->aLong = rName;
+                else
+                {
+                    pImp->AddName( pImp->aShort, rName, TRUE );
+                    nIdx = pImp->GetIndex( pImp->aShort );
+                    if( !pImp->bInPutMuchBlocks )
+                        nErr = pImp->MakeBlockList();
+                }
+            }
+        }
+        if( !pImp->bInPutMuchBlocks )
+        {
+            pImp->CloseFile();
+            pImp->Touch();
+        }
+    }
+    return nIdx;
+}
+
+
+SwDoc* SwTextBlocks::GetDoc()
+{
+    if( pImp )
+        return pImp->pDoc;
+    return 0;
+}
+
+
+void SwTextBlocks::ClearDoc()
+{
+    if( pImp )
+        pImp->ClearDoc();
+    pImp->nCur = (USHORT) -1;
+}
+
+
+const String& SwTextBlocks::GetFileName() const
+{
+    return pImp->GetFileName();
+}
+
+
+BOOL SwTextBlocks::IsReadOnly() const
+{
+    return pImp->bReadOnly;
+}
+
+BOOL SwTextBlocks::IsOnlyTextBlock( USHORT nIdx ) const
+{
+    BOOL bRet = FALSE;
+    if( pImp && !pImp->bInPutMuchBlocks )
+    {
+        SwBlockName* pBlkNm = pImp->aNames[ nIdx ];
+        if( !pBlkNm->bIsOnlyTxtFlagInit &&
+            !pImp->IsFileChanged() && !pImp->OpenFile( TRUE ) )
+        {
+            pBlkNm->bIsOnlyTxt = pImp->IsOnlyTextBlock( pBlkNm->aShort );
+            pBlkNm->bIsOnlyTxtFlagInit = TRUE;
+            pImp->CloseFile();
+        }
+        bRet = pBlkNm->bIsOnlyTxt;
+    }
+    return bRet;
+}
+
+BOOL SwTextBlocks::IsOnlyTextBlock( const String& rShort ) const
+{
+    USHORT nIdx = pImp->GetIndex( rShort );
+    if( USHRT_MAX != nIdx )
+    {
+        if( pImp->aNames[ nIdx ]->bIsOnlyTxtFlagInit )
+            return pImp->aNames[ nIdx ]->bIsOnlyTxt;
+        return IsOnlyTextBlock( nIdx );
+    }
+
+    ASSERT( !this, "ungueltiger Name" );
+    return FALSE;
+}
+
+BOOL SwTextBlocks::GetMacroTable( USHORT nIdx, SvxMacroTableDtor& rMacroTbl )
+{
+    return ( pImp && !pImp->bInPutMuchBlocks )
+                ? 0 == pImp->GetMacroTable( nIdx, rMacroTbl )
+                : TRUE;
+}
+
+
+String SwTextBlocks::GetValidShortCut( const String& rLong,
+                                         BOOL bCheckInBlock ) const
+{
+    String sRet;
+    xub_StrLen nLen = rLong.Len();
+    if( nLen )
+    {
+        xub_StrLen nStart = 0;
+        while( ' ' == rLong.GetChar( nStart ) )
+            if( ++nStart < nLen )
+                break;
+
+        if( nStart < nLen )
+        {
+            sal_Unicode cCurr, cPrev = rLong.GetChar( nStart );
+            sRet = cPrev;
+            for( ++nStart; nStart < nLen; ++nStart, cPrev = cCurr )
+                if( ' ' == cPrev &&
+                    ' ' != ( cCurr = rLong.GetChar( nStart )) )
+                    sRet += cCurr;
+        }
+        if( bCheckInBlock )
+        {
+            USHORT nCurPos = GetIndex( sRet );
+            nStart = 0;
+            nLen = sRet.Len();
+            while( (USHORT)-1 != nCurPos )
+            {
+                sRet.Erase( nLen ) +=
+                    String::CreateFromInt32( ++nStart );// add an Number to it
+                nCurPos = GetIndex( sRet );
+            }
+        }
+    }
+    return sRet;
+}
+
+BOOL SwTextBlocks::StartPutMuchBlockEntries()
+{
+    BOOL bRet = FALSE;
+    if( !IsOld() && pImp )
+        bRet = pImp->PutMuchEntries( TRUE );
+    return bRet;
+}
+
+void SwTextBlocks::EndPutMuchBlockEntries()
+{
+    if( pImp )
+        pImp->PutMuchEntries( FALSE );
+}
+
+
+
diff --git a/sw/source/core/text/blink.cxx b/sw/source/core/text/blink.cxx
new file mode 100644
index 000000000000..01a5668ebca9
--- /dev/null
+++ b/sw/source/core/text/blink.cxx
@@ -0,0 +1,205 @@
+/*************************************************************************
+ *
+ *  $RCSfile: blink.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:24 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _DEBUG_HXX //autogen
+#include 
+#endif
+#include "viewsh.hxx"
+#include "rootfrm.hxx"  // GetOleShell()
+#include "segmentc.hxx"
+
+#include "txtfrm.hxx"   // FindRootFrm()
+#include "blink.hxx"
+#include "porlin.hxx"
+#include "porlay.hxx"   // SwLineLayout
+
+// Sichtbare Zeit:
+#define BLINK_ON_TIME       2400L
+// Nihct sichtbare Zeit:
+#define BLINK_OFF_TIME      800L
+
+/*************************************************************************
+ * pBlink zeigt auf die Instanz, bei der sich blinkende Portions anmelden
+ * muessen, ggf. muss pBlink erst per new SwBlink angelegt werden.
+ * Diese werden dann rhythmisch zum Repaint angeregt und koennen abfragen,
+ * ob sie zur Zeit sichtbar oder unsichtbar sein sollen ( IsVisible() ).
+ *************************************************************************/
+SwBlink *pBlink = NULL;
+
+
+// Liste von blinkenden Portions
+SV_IMPL_OP_PTRARR_SORT( SwBlinkList, SwBlinkPortionPtr )
+
+SwBlink::SwBlink()
+{
+    bVisible = sal_True;
+    // Den Timer vorbereiten
+    aTimer.SetTimeout( BLINK_ON_TIME );
+    aTimer.SetTimeoutHdl( LINK(this, SwBlink, Blinker) );
+}
+
+SwBlink::~SwBlink( )
+{
+    aTimer.Stop();
+}
+
+/*************************************************************************
+ * SwBlink::Blinker (Timerablauf):
+ * Sichtbar/unsichtbar-Flag toggeln.
+ * Repaint-Rechtecke der Blinkportions ermitteln und an ihren OleShells
+ * invalidieren.
+ *************************************************************************/
+
+IMPL_LINK( SwBlink, Blinker, Timer *, pTimer )
+{
+    bVisible = !bVisible;
+    if( bVisible )
+        aTimer.SetTimeout( BLINK_ON_TIME );
+    else
+        aTimer.SetTimeout( BLINK_OFF_TIME );
+    if( aList.Count() )
+    {
+
+        for( MSHORT nPos = 0; nPos < aList.Count(); )
+        {
+            const SwBlinkPortion* pTmp = aList[ nPos ];
+            if( pTmp->GetRootFrm() &&
+                ((SwRootFrm*)pTmp->GetRootFrm())->GetCurrShell() )
+            {
+                ++nPos;
+                Rectangle aRefresh( Point( pTmp->GetPos().X(), pTmp->GetPos().Y()
+                                          - pTmp->GetPortion()->GetAscent() ),
+                                    pTmp->GetPortion()->SvLSize() );
+                aRefresh.Right() += ( aRefresh.Bottom()- aRefresh.Top() ) / 8;
+                ((SwRootFrm*)pTmp->GetRootFrm())
+                    ->GetCurrShell()->InvalidateWindows( aRefresh );
+            }
+            else // Portions ohne Shell koennen aus der Liste entfernt werden.
+                aList.Remove( nPos );
+        }
+    }
+    else // Wenn die Liste leer ist, kann der Timer gestoppt werden.
+        aTimer.Stop();
+    return sal_True;
+}
+
+void SwBlink::Insert( const SwLinePortion* pPor, const Point& rPoint,
+                      const SwTxtFrm *pTxtFrm )
+{
+    SwBlinkPortion *pBlinkPor = new SwBlinkPortion( pPor );
+    MSHORT nPos;
+    if( aList.Seek_Entry( pBlinkPor, &nPos ) )
+    {
+        aList[ nPos ]->SetPos( rPoint );
+        delete pBlinkPor;
+    }
+    else
+    {
+        pBlinkPor->SetPos( rPoint );
+        pBlinkPor->SetRootFrm( pTxtFrm->FindRootFrm() );
+        aList.Insert( pBlinkPor );
+        pTxtFrm->SetBlinkPor();
+        if( pPor->IsLayPortion() || pPor->IsParaPortion() )
+            ((SwLineLayout*)pPor)->SetBlinking( sal_True );
+
+        if( !aTimer.IsActive() )
+            aTimer.Start();
+    }
+}
+
+void SwBlink::Replace( const SwLinePortion* pOld, const SwLinePortion* pNew )
+{
+    SwBlinkPortion aBlink( pOld );
+    MSHORT nPos;
+    if( aList.Seek_Entry( &aBlink, &nPos ) )
+    {
+        SwBlinkPortion* pTmp = new SwBlinkPortion( aList[ nPos ], pNew );
+        aList.Remove( nPos );
+        aList.Insert( pTmp );
+    }
+}
+
+void SwBlink::Delete( const SwLinePortion* pPor )
+{
+    SwBlinkPortion aBlink( pPor );
+    MSHORT nPos;
+    if( aList.Seek_Entry( &aBlink, &nPos ) )
+        aList.Remove( nPos );
+}
+
+void SwBlink::FrmDelete( const SwRootFrm* pRoot )
+{
+    for( MSHORT nPos = 0; nPos < aList.Count(); )
+    {
+        if( pRoot == aList[ nPos ]->GetRootFrm() )
+            aList.Remove( nPos );
+        else
+            ++nPos;
+    }
+}
+
+
diff --git a/sw/source/core/text/frmcrsr.cxx b/sw/source/core/text/frmcrsr.cxx
new file mode 100644
index 000000000000..b9646d63870b
--- /dev/null
+++ b/sw/source/core/text/frmcrsr.cxx
@@ -0,0 +1,1240 @@
+/*************************************************************************
+ *
+ *  $RCSfile: frmcrsr.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:24 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "ndtxt.hxx"        // GetNode()
+#include "pam.hxx"          // SwPosition
+#include "frmtool.hxx"
+#include "doc.hxx"
+#include "viewopt.hxx"
+#include "paratr.hxx"
+#include "pagefrm.hxx"
+#include "colfrm.hxx"
+#include "txttypes.hxx"
+
+#ifndef _SFX_PRINTER_HXX //autogen
+#include 
+#endif
+
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _SVX_TSPTITEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _SVX_ULSPITEM_HXX //autogen
+#include 
+#endif
+
+#include "frmsh.hxx"
+#include "txtcfg.hxx"
+#include "txtfrm.hxx"       // SwTxtFrm
+#include "inftxt.hxx"       // SwTxtSizeInfo
+#include "itrtxt.hxx"       // SwTxtCursor
+#include "crstate.hxx"      // SwTxtCursor
+#include "viewsh.hxx"       // InvalidateWindows
+#include "swfntcch.hxx"     // SwFontAccess
+#include "flyfrm.hxx"
+
+#ifdef DEBUG
+#include "txtpaint.hxx"
+#endif
+
+#define MIN_OFFSET_STEP 10
+
+/*
+ * 1170-SurvivalKit: Wie gelangt man hinter das letzte Zeichen der Zeile.
+ * - RightMargin verzichtet auf den Positionsausgleich mit -1
+ * - GetCharRect liefert bei MV_RIGHTMARGIN ein GetEndCharRect
+ * - GetEndCharRect setzt bRightMargin auf sal_True
+ * - SwTxtCursor::bRightMargin wird per CharCrsrToLine auf sal_False gesetzt
+ */
+
+/*************************************************************************
+ *                      GetAdjFrmAtPos()
+ *************************************************************************/
+
+SwTxtFrm *GetAdjFrmAtPos( SwTxtFrm *pFrm, const SwPosition &rPos,
+                          const sal_Bool bRightMargin )
+{
+    // 8810: vgl. 1170, RightMargin in der letzten Masterzeile...
+    const xub_StrLen nOffset = rPos.nContent.GetIndex();
+    SwTxtFrm *pFrmAtPos = pFrm->GetFrmAtPos( rPos );
+    while( pFrm != pFrmAtPos )
+    {
+        pFrm = pFrmAtPos;
+        pFrm->GetFormatted();
+        pFrmAtPos = (SwTxtFrm*)pFrm->GetFrmAtPos( rPos );
+    }
+
+    if( nOffset && bRightMargin )
+    {
+        while( pFrmAtPos && pFrmAtPos->GetOfst() == nOffset )
+        {
+            pFrmAtPos->GetFormatted();
+            pFrmAtPos = pFrmAtPos->FindMaster();
+        }
+        ASSERT( pFrmAtPos, "+GetCharRect: no frame with my rightmargin" );
+    }
+    return pFrmAtPos ? pFrmAtPos : pFrm;
+}
+
+sal_Bool lcl_ChangeOffset( SwTxtFrm* pFrm, xub_StrLen nNew )
+{
+    // In Bereichen und ausserhalb von Flies wird nicht mehr gescrollt.
+    ASSERT( !pFrm->IsFollow(), "Illegal Scrolling by Follow!" );
+    if( pFrm->GetOfst() != nNew && !pFrm->IsInSct() )
+    {
+        SwFlyFrm *pFly = pFrm->FindFlyFrm();
+        // Vorsicht, wenn z.B. bei einem spaltigen Rahmen die Groesse noch invalide ist,
+        // duerfen wir nicht mal eben herumscrollen
+        if ( ( pFly && pFly->IsValid() &&
+             !pFly->GetNextLink() && !pFly->GetPrevLink() ) ||
+             ( !pFly && pFrm->IsInTab() ) )
+        {
+            ViewShell* pVsh = pFrm->GetShell();
+            if( pVsh )
+            {
+                if( pVsh->GetNext() != pVsh ||
+                    ( pFrm->GetDrawObjs() && pFrm->GetDrawObjs()->Count() ) )
+                {
+                    if( !pFrm->GetOfst() )
+                        return sal_False;
+                    nNew = 0;
+                }
+                pFrm->SetOfst( nNew );
+                pFrm->SetPara( 0 );
+                pFrm->GetFormatted();
+                pFrm->GetShell()->InvalidateWindows( pFrm->Frm() );
+                return sal_True;
+            }
+        }
+    }
+    return sal_False;
+}
+
+/*************************************************************************
+ *                      GetFrmAtOfst(), GetFrmAtPos()
+ *************************************************************************/
+
+SwTxtFrm *SwTxtFrm::GetFrmAtOfst( const xub_StrLen nWhere )
+{
+    SwTxtFrm *pRet = this;
+    while( pRet->HasFollow() && nWhere >= pRet->GetFollow()->GetOfst() )
+        pRet = pRet->GetFollow();
+    return pRet;
+}
+
+SwTxtFrm *SwTxtFrm::GetFrmAtPos( const SwPosition &rPos )
+{
+    SwTxtFrm *pFoll = (SwTxtFrm*)this;
+    while( pFoll->GetFollow() )
+    {
+        if( rPos.nContent.GetIndex() > pFoll->GetFollow()->GetOfst() )
+            pFoll = pFoll->GetFollow();
+        else
+        {
+            if( rPos.nContent.GetIndex() == pFoll->GetFollow()->GetOfst()
+                 && !SwTxtCursor::IsRightMargin() )
+                 pFoll = pFoll->GetFollow();
+            else
+                break;
+        }
+    }
+    if( rPos.nContent.GetIndex() < pFoll->GetOfst() && !pFoll->IsFollow() )
+    {
+        // Der Offset wird verschoben, bis die gewuenschte Position sichtbar
+        // wird und MIN_OFFSET_STEP weitere Zeichen.
+        xub_StrLen nNew = rPos.nContent.GetIndex();
+        if( nNew < MIN_OFFSET_STEP )
+            nNew = 0;
+        else
+            nNew -= MIN_OFFSET_STEP;
+        lcl_ChangeOffset( pFoll, nNew );
+    }
+    return pFoll;
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::GetCharRect()
+ *************************************************************************/
+
+/*
+ * GetCharRect() findet die Characterzelle des Characters, dass
+ * durch aPos beschrieben wird. GetCrsrOfst() findet den
+ * umgekehrten Weg: Von einer Dokumentkoordinate zu einem Pam.
+ * Beide sind virtuell in der Framebasisklasse und werden deshalb
+ * immer angezogen.
+ */
+
+sal_Bool SwTxtFrm::GetCharRect( SwRect& rOrig, const SwPosition &rPos,
+                            SwCrsrMoveState *pCMS ) const
+{
+    if( IsLocked() || IsHiddenNow() )
+        return sal_False;
+
+    //Erstmal den richtigen Frm finden, dabei muss beachtet werden, dass:
+    //- die gecachten Informationen verworfen sein koennen (GetPara() == 0)
+    //- das ein Follow gemeint sein kann
+    //- das die Kette der Follows dynamisch waechst; der in den wir
+    //  schliesslich gelangen muss aber Formatiert sein.
+
+    // opt: reading ahead erspart uns ein GetAdjFrmAtPos
+    const sal_Bool bRightMargin = pCMS && ( MV_RIGHTMARGIN == pCMS->eState );
+    SwTxtFrm *pFrm = GetAdjFrmAtPos( (SwTxtFrm*)this, rPos, bRightMargin );
+
+    pFrm->GetFormatted();
+    const SwFrm* pTmpFrm = (SwFrm*)pFrm->GetUpper();
+    SwTwips nUpperMaxY = pTmpFrm->Frm().Top() + pTmpFrm->Prt().Bottom();
+    SwTwips nMaxY = Min( pFrm->Frm().Top() + pFrm->Prt().Bottom(), nUpperMaxY );
+
+    if ( pFrm->IsEmpty() || !pFrm->Prt().Height() )
+    {
+        Point aPnt1 = pFrm->Frm().Pos() + pFrm->Prt().Pos();
+        SwTxtNode* pTxtNd = ((SwTxtFrm*)this)->GetTxtNode();
+        short nFirstOffset;
+        pTxtNd->GetFirstLineOfsWithNum( nFirstOffset );
+        if( nFirstOffset > 0 )
+            aPnt1.X() += nFirstOffset;
+        if( aPnt1.Y() > nMaxY )
+            aPnt1.Y() = nMaxY;
+        Point aPnt2( aPnt1.X(), aPnt1.Y() + pFrm->Prt().Height() );
+        if( aPnt2.Y() > nMaxY )
+            aPnt2.Y() = nMaxY;
+        rOrig = SwRect( aPnt1, aPnt2 );
+        if ( pCMS )
+        {
+            pCMS->aRealHeight.X() = 0;
+            pCMS->aRealHeight.Y() = rOrig.Height();
+        }
+        return sal_True;
+    }
+    else
+    {
+        if( !pFrm->HasPara() )
+            return sal_False;
+        sal_Bool bGoOn = sal_True;
+        sal_Bool bRet;
+        sal_Bool bPrvLine;
+        xub_StrLen nOffset = rPos.nContent.GetIndex();
+        xub_StrLen nNextOfst;
+        do
+        {
+            {
+                SwTxtSizeInfo aInf( pFrm );
+                SwTxtCursor  aLine( pFrm, &aInf );
+                nNextOfst = aLine.GetEnd();
+                // Siehe Kommentar in AdjustFrm
+                // 1170: das letzte Zeichen der Zeile mitnehmen?
+                bRet = bRightMargin ? aLine.GetEndCharRect( &rOrig, nOffset, pCMS, nMaxY )
+                                : aLine.GetCharRect( &rOrig, nOffset, pCMS, nMaxY );
+                bPrvLine = pCMS && aLine.GetPrev() && !pFrm->GetNext();
+
+            }
+            if( pFrm->IsUndersized() && bPrvLine && rOrig.Bottom() == nUpperMaxY &&
+                pFrm->GetOfst() < nOffset && !pFrm->IsFollow() )
+                bGoOn = lcl_ChangeOffset( pFrm, nNextOfst );
+            else
+                bGoOn = sal_False;
+        } while ( bGoOn );
+        return bRet;
+    }
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::GetAutoPos()
+ *************************************************************************/
+
+/*
+ * GetAutoPos() findet die Characterzelle des Characters, dass
+ * durch aPos beschrieben wird und wird von autopositionierten Rahmen genutzt.
+ */
+
+sal_Bool SwTxtFrm::GetAutoPos( SwRect& rOrig, const SwPosition &rPos ) const
+{
+    if( IsHiddenNow() )
+        return sal_False;
+
+    xub_StrLen nOffset = rPos.nContent.GetIndex();
+    SwTxtFrm *pFrm = ((SwTxtFrm*)this)->GetFrmAtOfst( nOffset );
+
+    pFrm->GetFormatted();
+    const SwFrm* pTmpFrm = (SwFrm*)pFrm->GetUpper();
+    SwTwips nUpperMaxY = pTmpFrm->Frm().Top() + pTmpFrm->Prt().Bottom();
+    SwTwips nMaxY = Min( pFrm->Frm().Top() + pFrm->Prt().Bottom(), nUpperMaxY );
+
+    if ( pFrm->IsEmpty() || !pFrm->Prt().Height() )
+    {
+        Point aPnt1 = pFrm->Frm().Pos() + pFrm->Prt().Pos();
+        if( aPnt1.Y() > nMaxY )
+            aPnt1.Y() = nMaxY;
+        Point aPnt2( aPnt1.X(), aPnt1.Y() + pFrm->Prt().Height() );
+        if( aPnt2.Y() > nMaxY )
+            aPnt2.Y() = nMaxY;
+        rOrig = SwRect( aPnt1, aPnt2 );
+        return sal_True;
+    }
+    else
+    {
+        if( !pFrm->HasPara() )
+            return sal_False;
+        SwTxtSizeInfo aInf( pFrm );
+        SwTxtCursor  aLine( pFrm, &aInf );
+        return aLine.GetCharRect( &rOrig, nOffset, NULL, nMaxY );
+    }
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::_GetCrsrOfst()
+ *************************************************************************/
+
+// Minimaler Abstand von nichtleeren Zeilen etwas weniger als 2 cm
+#define FILL_MIN_DIST 1100
+
+struct SwFillData
+{
+    SwRect aFrm;
+    const SwCrsrMoveState *pCMS;
+    SwPosition* pPos;
+    const Point& rPoint;
+    SwTwips nLineWidth;
+    sal_Bool bFirstLine : 1;
+    sal_Bool bInner     : 1;
+    sal_Bool bColumn    : 1;
+    sal_Bool bEmpty     : 1;
+    SwFillData( const SwCrsrMoveState *pC, SwPosition* pP, const SwRect& rR,
+        const Point& rPt ) : aFrm( rR ), pCMS( pC ), pPos( pP ), rPoint( rPt ),
+        nLineWidth( 0 ), bFirstLine( sal_True ), bInner( sal_False ), bColumn( sal_False ),
+        bEmpty( sal_True ){}
+    const SwFillMode Mode() const { return pCMS->pFill->eMode; }
+    const long X() const { return rPoint.X(); }
+    const long Y() const { return rPoint.Y(); }
+    const long Left() const { return aFrm.Left(); }
+    const long Right() const { return aFrm.Right(); }
+    const long Bottom() const { return aFrm.Bottom(); }
+    SwFillCrsrPos &Fill() const { return *pCMS->pFill; }
+    void SetTab( MSHORT nNew ) { pCMS->pFill->nTabCnt = nNew; }
+    void SetSpace( MSHORT nNew ) { pCMS->pFill->nSpaceCnt = nNew; }
+    void SetOrient( const SwHoriOrient eNew ){ pCMS->pFill->eOrient = eNew; }
+};
+
+sal_Bool SwTxtFrm::_GetCrsrOfst(SwPosition* pPos, const Point& rPoint,
+                    const sal_Bool bChgFrm, const SwCrsrMoveState* pCMS ) const
+{
+    // 8804: _GetCrsrOfst wird vom GetCrsrOfst und GetKeyCrsrOfst gerufen.
+    // In keinem Fall nur ein return sal_False.
+
+    if( IsLocked() || IsHiddenNow() )
+        return sal_False;
+
+    SwFillData *pFillData = ( pCMS && pCMS->pFill ) ?
+                            new SwFillData( pCMS, pPos, Frm(), rPoint ) : NULL;
+
+    ((SwTxtFrm*)this)->GetFormatted();
+    if ( IsEmpty() )
+    {
+        SwTxtNode* pTxtNd = ((SwTxtFrm*)this)->GetTxtNode();
+        pPos->nNode = *pTxtNd;
+        pPos->nContent.Assign( pTxtNd, 0 );
+        if( pCMS && pCMS->bFieldInfo )
+        {
+            SwTwips nDiff = rPoint.X() - Frm().Left() - Prt().Left();
+            if( nDiff > 50 || nDiff < 0 )
+                ((SwCrsrMoveState*)pCMS)->bPosCorr = sal_True;
+        }
+    }
+    else
+    {
+        SwTxtSizeInfo aInf( (SwTxtFrm*)this );
+        SwTxtCursor  aLine( ((SwTxtFrm*)this), &aInf );
+
+        // Siehe Kommentar in AdjustFrm()
+        SwTwips nMaxY = Frm().Top() + Prt().Top() + Prt().Height();
+        aLine.TwipsToLine( rPoint.Y() );
+        while( aLine.Y() + aLine.GetLineHeight() > nMaxY )
+        {
+            DBG_LOOP;
+            if( !aLine.Prev() )
+                break;
+        }
+
+        xub_StrLen nOffset = aLine.GetCrsrOfst( pPos, rPoint, bChgFrm, pCMS );
+
+        if( pCMS && pCMS->eState == MV_NONE && aLine.GetEnd() == nOffset )
+            ((SwCrsrMoveState*)pCMS)->eState = MV_RIGHTMARGIN;
+
+    // 6776: pPos ist ein reiner IN-Parameter, der nicht ausgewertet werden darf.
+    // Das pIter->GetCrsrOfst returnt aus einer Verschachtelung mit STRING_LEN.
+    // Wenn SwTxtIter::GetCrsrOfst von sich aus weitere GetCrsrOfst
+    // ruft, so aendert sich nNode der Position. In solchen Faellen
+    // darf pPos nicht berechnet werden.
+        if( STRING_LEN != nOffset )
+        {
+#ifdef USED
+            // 8626: bei Up/Down darf diese Zeile nicht verlassen werden.
+            if( pCMS && MV_UPDOWN == pCMS->eState )
+            {
+                const xub_StrLen nEnd = aLine.GetEnd();
+                if( nOffset >= nEnd && nEnd )
+                {
+                    // Man muss hinter das letzte Zeichen kommen duerfen?!
+                    nOffset = nEnd - 1;                 // UnitUp-Korrektur
+                }
+                else
+                    if( nOffset < aLine.GetStart() )
+                        nOffset = aLine.GetStart(); // UnitDown-Korrektur
+            }
+#endif
+            SwTxtNode* pTxtNd = ((SwTxtFrm*)this)->GetTxtNode();
+            pPos->nNode = *pTxtNd;
+            pPos->nContent.Assign( pTxtNd, nOffset );
+            if( pFillData )
+            {
+                if( pTxtNd->GetTxt().Len() > nOffset ||
+                    rPoint.Y() < Frm().Top() )
+                    pFillData->bInner = sal_True;
+                pFillData->bFirstLine = aLine.GetLineNr() < 2;
+                if( pTxtNd->GetTxt().Len() )
+                {
+                    pFillData->bEmpty = sal_False;
+                    pFillData->nLineWidth = aLine.GetCurr()->Width();
+                }
+            }
+
+        }
+    }
+    if( pFillData && FindPageFrm()->Frm().IsInside( rPoint ) )
+        FillCrsrPos( *pFillData );
+    return sal_True;
+}
+
+/*************************************************************************
+ *                 virtual SwTxtFrm::GetCrsrOfst()
+ *************************************************************************/
+
+sal_Bool SwTxtFrm::GetCrsrOfst(SwPosition* pPos, Point& rPoint,
+                            const SwCrsrMoveState* pCMS ) const
+{
+    MSHORT nChgFrm = 2;
+    if( pCMS )
+    {
+        if( MV_UPDOWN == pCMS->eState )
+            nChgFrm = 0;
+        else if( MV_SETONLYTEXT == pCMS->eState ||
+                 MV_TBLSEL == pCMS->eState )
+            nChgFrm = 1;
+    }
+    return _GetCrsrOfst( pPos, rPoint, nChgFrm, pCMS );
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::LeftMargin()
+ *************************************************************************/
+
+/*
+ * Layout-orientierte Cursorbewegungen
+ */
+
+/*
+ * an den Zeilenanfang
+ */
+
+sal_Bool SwTxtFrm::LeftMargin(SwPaM *pPam) const
+{
+    if( ((const SwNode*)pPam->GetNode()) != GetNode() )
+        pPam->pPoint->nNode = *((SwTxtFrm*)this)->GetTxtNode();
+
+    SwTxtFrm *pFrm = GetAdjFrmAtPos( (SwTxtFrm*)this, *(pPam->pPoint),
+                                     SwTxtCursor::IsRightMargin() );
+    pFrm->GetFormatted();
+    xub_StrLen nIndx;
+    if ( pFrm->IsEmpty() )
+        nIndx = 0;
+    else
+    {
+        SwTxtSizeInfo aInf( pFrm );
+        SwTxtCursor  aLine( pFrm, &aInf );
+
+        aLine.CharCrsrToLine(pPam->pPoint->nContent.GetIndex());
+        nIndx = aLine.GetStart();
+        if( pFrm->GetOfst() && !pFrm->IsFollow() && !aLine.GetPrev() )
+        {
+            lcl_ChangeOffset( pFrm, 0 );
+            nIndx = 0;
+        }
+    }
+    pPam->pPoint->nContent = SwIndex( pFrm->GetTxtNode(), nIndx );
+    SwTxtCursor::SetRightMargin( sal_False );
+    return sal_True;
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::RightMargin()
+ *************************************************************************/
+
+/*
+ * An das Zeilenende:Das ist die Position vor dem letzten
+ * Character in der Zeile. Ausnahme: In der letzten Zeile soll
+ * der Cursor auch hinter dem letzten Character stehen koennen,
+ * um Text anhaengen zu koennen.
+ *
+ */
+
+sal_Bool SwTxtFrm::RightMargin(SwPaM *pPam, sal_Bool bAPI) const
+{
+    if( ((const SwNode*)pPam->GetNode()) != GetNode() )
+        pPam->pPoint->nNode = *((SwTxtFrm*)this)->GetTxtNode();
+
+    SwTxtFrm *pFrm = GetAdjFrmAtPos( (SwTxtFrm*)this, *(pPam->pPoint),
+                                     SwTxtCursor::IsRightMargin() );
+    pFrm->GetFormatted();
+    xub_StrLen nRightMargin;
+    if ( IsEmpty() )
+        nRightMargin = 0;
+    else
+    {
+        SwTxtSizeInfo aInf( pFrm );
+        SwTxtCursor  aLine( pFrm, &aInf );
+
+        aLine.CharCrsrToLine(pPam->pPoint->nContent.GetIndex());
+        nRightMargin = aLine.GetStart() + aLine.GetCurr()->GetLen();
+
+        // Harte Zeilenumbrueche lassen wir hinter uns.
+        if( aLine.GetCurr()->GetLen() &&
+            CH_BREAK == aInf.GetTxt().GetChar( nRightMargin - 1 ) )
+            --nRightMargin;
+        if( !bAPI && (aLine.GetNext() || pFrm->GetFollow()) )
+        {
+            while( nRightMargin > aLine.GetStart() &&
+                ' ' == aInf.GetTxt().GetChar( nRightMargin - 1 ) )
+                --nRightMargin;
+        }
+    }
+    pPam->pPoint->nContent = SwIndex( pFrm->GetTxtNode(), nRightMargin );
+    SwTxtCursor::SetRightMargin( !bAPI );
+    return sal_True;
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::_UnitUp()
+ *************************************************************************/
+
+//Die beiden folgenden Methoden versuchen zunaechst den Crsr in die
+//nachste/folgende Zeile zu setzen. Gibt es im Frame keine vorhergehende/
+//folgende Zeile, so wird der Aufruf an die Basisklasse weitergeleitet.
+//Die Horizontale Ausrichtung des Crsr wird hinterher von der CrsrShell
+//vorgenommen.
+
+class SwSetToRightMargin
+{
+    sal_Bool bRight;
+public:
+    inline SwSetToRightMargin() : bRight( sal_False ) { }
+    inline ~SwSetToRightMargin() { SwTxtCursor::SetRightMargin( bRight ); }
+    inline void SetRight( const sal_Bool bNew ) { bRight = bNew; }
+};
+
+sal_Bool SwTxtFrm::_UnitUp( SwPaM *pPam, const SwTwips nOffset,
+                            sal_Bool bSetInReadOnly ) const
+{
+    // 8626: Im Notfall den RightMargin setzen.
+    SwSetToRightMargin aSet;
+
+    if( IsInTab() &&
+        pPam->GetNode( sal_True )->StartOfSectionNode() !=
+        pPam->GetNode( sal_False )->StartOfSectionNode() )
+    {
+        //Wenn der PaM in unterschiedlichen Boxen sitzt, so handelt es sich um
+        //eine Tabellenselektion; diese wird von der Basisklasse abgearbeitet.
+        return SwCntntFrm::UnitUp( pPam, nOffset, bSetInReadOnly );
+    }
+
+    ((SwTxtFrm*)this)->GetFormatted();
+    const xub_StrLen nPos = pPam->pPoint->nContent.GetIndex();
+    SwRect aCharBox;
+
+    if( !IsEmpty() && !IsHiddenNow() )
+    {
+        xub_StrLen nFormat = STRING_LEN;
+        do
+        {
+            if( nFormat != STRING_LEN && !IsFollow() )
+                lcl_ChangeOffset( ((SwTxtFrm*)this), nFormat );
+
+            SwTxtSizeInfo aInf( (SwTxtFrm*)this );
+            SwTxtCursor  aLine( ((SwTxtFrm*)this), &aInf );
+
+            // 8116: Flys ohne Umlauf und IsDummy(); hier wegoptimiert
+            if( nPos )
+                aLine.CharCrsrToLine( nPos );
+            else
+                aLine.Top();
+
+            const SwLineLayout *pPrevLine = aLine.GetPrevLine();
+            if( !pPrevLine && GetOfst() && !IsFollow() )
+            {
+                nFormat = GetOfst();
+                xub_StrLen nDiff = aLine.GetLength();
+                if( !nDiff )
+                    nDiff = MIN_OFFSET_STEP;
+                if( nFormat > nDiff )
+                    nFormat -= nDiff;
+                else
+                    nFormat = 0;
+                continue;
+            }
+            if( pPrevLine && pPrevLine != aLine.GetCurr() )
+            {
+                const xub_StrLen nStart = aLine.GetStart();
+                SwRect aCharBox;
+                aLine.GetCharRect( &aCharBox, nPos );
+                aLine.PrevLine();
+                while ( aLine.GetStart() == nStart &&
+                        0 != ( pPrevLine = aLine.GetPrevLine() ) &&
+                        pPrevLine != aLine.GetCurr() )
+                    aLine.PrevLine();
+                aCharBox.SSize().Width() /= 2;
+
+                // siehe Kommentar in SwTxtFrm::GetCrsrOfst()
+#ifndef PRODUCT
+                const xub_StrLen nOldNode = pPam->pPoint->nNode.GetIndex();
+#endif
+                // Der Node soll nicht gewechselt werden
+                xub_StrLen nOfst = aLine.GetCrsrOfst( pPam->pPoint,
+                                                    aCharBox.Pos(), sal_False );
+                ASSERT( nOldNode == pPam->pPoint->nNode.GetIndex(),
+                        "SwTxtFrm::UnitUp: illegal node change" )
+
+                // 7684: Wir stellen sicher, dass wir uns nach oben bewegen.
+                if( nOfst >= nStart && nStart )
+                {
+                    // nOfst = nStart - 1;
+                    nOfst = nStart;
+                    aSet.SetRight( sal_True );
+                }
+                pPam->pPoint->nContent =
+                      SwIndex( ((SwTxtFrm*)this)->GetTxtNode(), nOfst );
+                return sal_True;
+            }
+            if ( IsFollow() )
+            {
+                aLine.GetCharRect( &aCharBox, nPos );
+                aCharBox.SSize().Width() /= 2;
+            }
+            break;
+        } while ( sal_True );
+    }
+    /* Wenn this ein Follow ist und ein Prev miszlang, so
+     * muessen wir in die letzte Zeile des Master ... und der sind wir.
+     * Oder wir sind ein Follow mit Follow, dann muessen wir uns den
+     * Master extra besorgen...
+     */
+    if ( IsFollow() )
+    {
+        const SwTxtFrm *pPrev = FindMaster();
+        xub_StrLen nOffs = GetOfst();
+        if( pPrev )
+        {
+            ViewShell *pSh = GetShell();
+            sal_Bool bProtectedAllowed = pSh && pSh->GetViewOptions()->IsCursorInProtectedArea();
+            const SwTxtFrm *pPrevPrev = pPrev;
+            // Hier werden geschuetzte Frames und Frame ohne Inhalt ausgelassen
+            while( pPrevPrev && ( pPrevPrev->GetOfst() == nOffs ||
+                   ( !bProtectedAllowed && pPrevPrev->IsProtected() ) ) )
+            {
+                pPrev = pPrevPrev;
+                nOffs = pPrev->GetOfst();
+                if ( pPrevPrev->IsFollow() )
+                    pPrevPrev = pPrev->FindMaster();
+                else
+                    pPrevPrev = NULL;
+            }
+            if ( !pPrevPrev )
+                return pPrev->SwCntntFrm::UnitUp( pPam, nOffset, bSetInReadOnly );
+            aCharBox.Pos().Y() = pPrevPrev->Frm().Bottom() - 1;
+            return pPrevPrev->GetKeyCrsrOfst( pPam->pPoint, aCharBox.Pos() );
+        }
+    }
+    return SwCntntFrm::UnitUp( pPam, nOffset, bSetInReadOnly );
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::_UnitDown()
+ *************************************************************************/
+
+sal_Bool SwTxtFrm::_UnitDown(SwPaM *pPam, const SwTwips nOffset,
+                            sal_Bool bSetInReadOnly ) const
+{
+
+    if ( IsInTab() &&
+        pPam->GetNode( sal_True )->StartOfSectionNode() !=
+        pPam->GetNode( sal_False )->StartOfSectionNode() )
+    {
+        //Wenn der PaM in unterschiedlichen Boxen sitzt, so handelt es sich um
+        //eine Tabellenselektion; diese wird von der Basisklasse abgearbeitet.
+        return SwCntntFrm::UnitDown( pPam, nOffset, bSetInReadOnly );
+    }
+    ((SwTxtFrm*)this)->GetFormatted();
+    const xub_StrLen nPos = pPam->pPoint->nContent.GetIndex();
+    SwRect aCharBox;
+    const SwCntntFrm *pFollow;
+    if ( !IsEmpty() && !IsHiddenNow() )
+    {
+        xub_StrLen nFormat = STRING_LEN;
+        do
+        {
+            if( nFormat != STRING_LEN && !IsFollow() &&
+                !lcl_ChangeOffset( ((SwTxtFrm*)this), nFormat ) )
+                break;
+
+            SwTxtSizeInfo aInf( (SwTxtFrm*)this );
+            SwTxtCursor  aLine( ((SwTxtFrm*)this), &aInf );
+            nFormat = aLine.GetEnd();
+
+            aLine.CharCrsrToLine( nPos );
+            if( aLine.GetNextLine() )
+            {
+                const xub_StrLen nStart = aLine.GetStart();
+                SwRect aCharBox;
+                aLine.GetCharRect( &aCharBox, nPos );
+                aLine.NextLine();
+                aCharBox.SSize().Width() /= 2;
+#ifndef PRODUCT
+                // siehe Kommentar in SwTxtFrm::GetCrsrOfst()
+                const xub_StrLen nOldNode = pPam->pPoint->nNode.GetIndex();
+#endif
+                xub_StrLen nOfst = aLine.GetCrsrOfst( pPam->pPoint,
+                                 aCharBox.Pos(), sal_False );
+                ASSERT( nOldNode == pPam->pPoint->nNode.GetIndex(),
+                    "SwTxtFrm::UnitDown: illegal node change" )
+
+                // 7684: Wir stellen sicher, dass wir uns nach unten bewegen.
+                if( nOfst <= nStart )
+                    nOfst = nStart + 1;
+                pPam->pPoint->nContent =
+                      SwIndex( ((SwTxtFrm*)this)->GetTxtNode(), nOfst );
+                return sal_True;
+            }
+            if( 0 != ( pFollow = GetFollow() ) )
+            {   // geschuetzte Follows auslassen
+                const SwCntntFrm* pTmp = pFollow;
+                ViewShell *pSh = GetShell();
+                if( !pSh || !pSh->GetViewOptions()->IsCursorInProtectedArea() )
+                {
+                    while( pFollow && pFollow->IsProtected() )
+                    {
+                        pTmp = pFollow;
+                        pFollow = pFollow->GetFollow();
+                    }
+                }
+                if( !pFollow ) // nur noch geschuetzte
+                    return pTmp->SwCntntFrm::UnitDown( pPam, nOffset, bSetInReadOnly );
+                aLine.GetCharRect( &aCharBox, nPos );
+                aCharBox.SSize().Width() /= 2;
+            }
+            else if( !IsFollow() )
+            {
+                xub_StrLen nTmpLen = aInf.GetTxt().Len();
+                if( aLine.GetEnd() < nTmpLen )
+                {
+                    if( nFormat <= GetOfst() )
+                    {
+                        nFormat = Min( xub_StrLen( GetOfst() + MIN_OFFSET_STEP ),
+                                       nTmpLen );
+                        if( nFormat <= GetOfst() )
+                            break;
+                    }
+                    continue;
+                }
+            }
+            break;
+        } while( sal_True );
+    }
+    else
+        pFollow = GetFollow();
+
+    // Bei Follows schlagen wir eine Abkuerzung
+    if( pFollow )
+    {
+        aCharBox.Pos().Y() = pFollow->Frm().Top() + 1;
+        return ((SwTxtFrm*)pFollow)->GetKeyCrsrOfst( pPam->pPoint,
+                                                     aCharBox.Pos() );
+    }
+    return SwCntntFrm::UnitDown( pPam, nOffset, bSetInReadOnly );
+}
+
+/*************************************************************************
+ *                   virtual SwTxtFrm::UnitUp()
+ *************************************************************************/
+
+sal_Bool SwTxtFrm::UnitUp(SwPaM *pPam, const SwTwips nOffset,
+                            sal_Bool bSetInReadOnly ) const
+{
+    /* Im CrsrSh::Up() wird CntntNode::GetFrm() gerufen.
+     * Dies liefert _immer_ den Master zurueck.
+     * Um das Cursortravelling nicht zu belasten, korrigieren wir
+     * hier im SwTxtFrm.
+     * Wir ermittelt UnitUp fuer pFrm, pFrm ist entweder ein Master (=this)
+     * oder ein Follow (!=this)
+     */
+    const SwTxtFrm *pFrm = GetAdjFrmAtPos( (SwTxtFrm*)this, *(pPam->GetPoint()),
+                                           SwTxtCursor::IsRightMargin() );
+    const sal_Bool bRet = pFrm->_UnitUp( pPam, nOffset, bSetInReadOnly );
+
+    // 8626: kein SwTxtCursor::SetRightMargin( sal_False );
+    // statt dessen steht ein SwSetToRightMargin im _UnitUp
+    return bRet;
+}
+
+/*************************************************************************
+ *                   virtual SwTxtFrm::UnitDown()
+ *************************************************************************/
+
+sal_Bool SwTxtFrm::UnitDown(SwPaM *pPam, const SwTwips nOffset,
+                            sal_Bool bSetInReadOnly ) const
+{
+    const SwTxtFrm *pFrm = GetAdjFrmAtPos((SwTxtFrm*)this, *(pPam->GetPoint()),
+                                           SwTxtCursor::IsRightMargin() );
+    const sal_Bool bRet = pFrm->_UnitDown( pPam, nOffset, bSetInReadOnly );
+    SwTxtCursor::SetRightMargin( sal_False );
+    return bRet;
+}
+
+void SwTxtFrm::FillCrsrPos( SwFillData& rFill ) const
+{
+    if( !rFill.bColumn && GetUpper()->IsColBodyFrm() ) // ColumnFrms jetzt mit BodyFrm
+    {
+        const SwColumnFrm* pTmp =
+            (SwColumnFrm*)GetUpper()->GetUpper()->GetUpper()->Lower(); // die 1. Spalte
+        // der erste SwFrm im BodyFrm der ersten Spalte
+        const SwFrm* pFrm = ((SwLayoutFrm*)pTmp->Lower())->Lower();
+        MSHORT nNextCol = 0;
+        // In welcher Spalte landen wir?
+        while( rFill.X() > pTmp->Frm().Right() && pTmp->GetNext() )
+        {
+            pTmp = (SwColumnFrm*)pTmp->GetNext();
+            if( ((SwLayoutFrm*)pTmp->Lower())->Lower() ) // ColumnFrms jetzt mit BodyFrm
+            {
+                pFrm = ((SwLayoutFrm*)pTmp->Lower())->Lower();
+                nNextCol = 0;
+            }
+            else
+                ++nNextCol; // leere Spalten erfordern Spaltenumbrueche
+        }
+        if( pTmp != GetUpper()->GetUpper() ) // Sind wir in einer anderen Spalte gelandet?
+        {
+            if( !pFrm )
+                return;
+            if( nNextCol )
+            {
+                while( pFrm->GetNext() )
+                    pFrm = pFrm->GetNext();
+            }
+            else
+            {
+                while( pFrm->GetNext() && pFrm->Frm().Bottom() < rFill.Y() )
+                    pFrm = pFrm->GetNext();
+            }
+            // Kein Fuellen, wenn als letzter Frame in der anvisierten
+            // Spalte kein Absatz, sondern z.B. eine Tabelle steht
+            if( pFrm->IsTxtFrm() )
+            {
+                rFill.Fill().nColumnCnt = nNextCol;
+                rFill.bColumn = sal_True;
+                if( rFill.pPos )
+                {
+                    SwTxtNode* pTxtNd = ((SwTxtFrm*)pFrm)->GetTxtNode();
+                    rFill.pPos->nNode = *pTxtNd;
+                    rFill.pPos->nContent.Assign( pTxtNd, pTxtNd->GetTxt().Len() );
+                }
+                if( nNextCol )
+                {
+                    rFill.aFrm = pTmp->Prt();
+                    rFill.aFrm += pTmp->Frm().Pos();
+                }
+                else
+                    rFill.aFrm = pFrm->Frm();
+                ((SwTxtFrm*)pFrm)->FillCrsrPos( rFill );
+            }
+            return;
+        }
+    }
+    sal_Bool bFill = sal_True;
+    SwFont *pFnt;
+    SwTxtFmtColl* pColl = GetTxtNode()->GetTxtColl();
+    MSHORT nFirst = GetTxtNode()->GetSwAttrSet().GetULSpace().GetLower();
+    SwTwips nDiff = rFill.Y() - Frm().Bottom();
+    if( nDiff < nFirst )
+        nDiff = -1;
+    else
+        pColl = &pColl->GetNextTxtFmtColl();
+    SwAttrSet aSet( ((SwDoc*)GetTxtNode()->GetDoc())->GetAttrPool(), aTxtFmtCollSetRange );
+    const SwAttrSet* pSet = &pColl->GetAttrSet();
+    ViewShell *pSh = GetShell();
+    if( GetTxtNode()->HasSwAttrSet() )
+    {
+        aSet.Put( *GetTxtNode()->GetpSwAttrSet() );
+        aSet.SetParent( pSet );
+        pSet = &aSet;
+        pFnt = new SwFont( pSet );
+    }
+    else
+    {
+        SwFontAccess aFontAccess( pColl, pSh );
+        pFnt = new SwFont( *aFontAccess.Get()->GetFont() );
+        pFnt->ChkMagic( pSh, pFnt->GetActual() );
+    }
+    OutputDevice *pOut = pSh->GetOut();
+    if ( !GetTxtNode()->GetDoc()->IsBrowseMode() ||
+            ( pSh->GetViewOptions()->IsPrtFormat() ) )
+    {
+        Printer *pPrt = GetTxtNode()->GetDoc()->GetPrt();
+        if ( pPrt && pPrt->IsValid() )
+            pOut = pPrt;
+    }
+    pFnt->SetFntChg( sal_True );
+    pFnt->ChgPhysFnt( pSh, pOut );
+
+    SwTwips nLineHeight = pFnt->GetHeight( pSh, pOut );
+
+    if( nLineHeight )
+    {
+        const SvxULSpaceItem &rUL = pSet->GetULSpace();
+        SwTwips nDist = Max( rUL.GetLower(), rUL.GetUpper() );
+        if( rFill.Fill().nColumnCnt )
+        {
+            rFill.aFrm.Height( nLineHeight );
+            nDiff = rFill.Y() - rFill.Bottom();
+            nFirst = 0;
+        }
+        else if( nDist < nFirst )
+            nFirst -= nDist;
+        else
+            nFirst = 0;
+        nDist = Max( nDist, long( GetLineSpace() ) );
+        nDist += nLineHeight;
+        nDiff -= nFirst;
+
+        if( nDiff > 0 )
+        {
+            nDiff /= nDist;
+            rFill.Fill().nParaCnt = nDiff + 1;
+            rFill.nLineWidth = 0;
+            rFill.bInner = sal_False;
+            rFill.bEmpty = sal_True;
+            rFill.SetOrient( HORI_LEFT );
+        }
+        else
+            nDiff = -1;
+        if( rFill.bInner )
+            bFill = sal_False;
+        else
+        {
+            const SvxTabStopItem &rRuler = pSet->GetTabStops();
+            const SvxLRSpaceItem &rLRSpace = pSet->GetLRSpace();
+
+            SwRect &rRect = rFill.Fill().aCrsr;
+            rRect.Top( rFill.Bottom() + (nDiff+1) * nDist - nLineHeight );
+            if( nFirst && nDiff > -1 )
+                rRect.Top( rRect.Top() + nFirst );
+            rRect.Height( nLineHeight );
+            SwTwips nLeft = rFill.Left() + rLRSpace.GetLeft() +
+                            GetTxtNode()->GetLeftMarginWithNum( sal_False );
+            SwTwips nRight = rFill.Right() - rLRSpace.GetRight();
+            SwTwips nCenter = ( nLeft + nRight ) / 2;
+            rRect.Left( nLeft );
+            if( FILL_MARGIN == rFill.Mode() )
+            {
+                if( rFill.bEmpty )
+                {
+                    rFill.SetOrient( HORI_LEFT );
+                    if( rFill.X() < nCenter )
+                    {
+                        if( rFill.X() > ( nLeft + 2 * nCenter ) / 3 )
+                        {
+                            rFill.SetOrient( HORI_CENTER );
+                            rRect.Left( nCenter );
+                        }
+                    }
+                    else if( rFill.X() > ( nRight + 2 * nCenter ) / 3 )
+                    {
+                        rFill.SetOrient( HORI_RIGHT );
+                        rRect.Left( nRight );
+                    }
+                    else
+                    {
+                        rFill.SetOrient( HORI_CENTER );
+                        rRect.Left( nCenter );
+                    }
+                }
+                else
+                    bFill = sal_False;
+            }
+            else
+            {
+                SwTwips nSpace;
+                if( FILL_TAB != rFill.Mode() )
+                {
+static sal_Char __READONLY_DATA sDoubleSpace[] = "  ";
+                    const XubString aTmp( sDoubleSpace, RTL_TEXTENCODING_MS_1252 );
+                    nSpace = pFnt->_GetTxtSize( pSh, pOut, aTmp, 0, 2 ).Width()/2;
+                }
+                if( rFill.X() >= nRight )
+                {
+                    if( FILL_INDENT != rFill.Mode() && ( rFill.bEmpty ||
+                        rFill.X() > rFill.nLineWidth + FILL_MIN_DIST ) )
+                    {
+                        rFill.SetOrient( HORI_RIGHT );
+                        rRect.Left( nRight );
+                    }
+                    else
+                        bFill = sal_False;
+                }
+                else if( FILL_INDENT == rFill.Mode() )
+                {
+                    SwTwips nIndent = rFill.X();
+                    if( !rFill.bEmpty || nIndent > nRight )
+                        bFill = sal_False;
+                    else
+                    {
+                        nIndent -= rFill.Left();
+                        if( nIndent >= 0 && nSpace )
+                        {
+                            nIndent /= nSpace;
+                            nIndent *= nSpace;
+                            rFill.SetTab( MSHORT( nIndent ) );
+                            rRect.Left( nIndent + rFill.Left() );
+                        }
+                        else
+                            bFill = sal_False;
+                    }
+                }
+                else if( rFill.X() > nLeft )
+                {
+                    SwTwips nTxtLeft = rFill.Left() + rLRSpace.GetTxtLeft() +
+                                    GetTxtNode()->GetLeftMarginWithNum( sal_True );
+                    rFill.nLineWidth += rFill.bFirstLine ? nLeft : nTxtLeft;
+                    SwTwips nLeftTab = nLeft;
+                    SwTwips nRightTab = nLeft;
+                    MSHORT nSpaceCnt = 0;
+                    MSHORT nTabCnt = 0;
+                    MSHORT nIdx = 0;
+                    do
+                    {
+                        nLeftTab = nRightTab;
+                        if( nIdx < rRuler.Count() )
+                        {
+                            const SvxTabStop &rTabStop = rRuler.operator[](nIdx);
+                            nRightTab = nTxtLeft + rTabStop.GetTabPos();
+                            if( nLeftTab < nTxtLeft && nRightTab > nTxtLeft )
+                                nRightTab = nTxtLeft;
+                            else
+                                ++nIdx;
+                            if( nRightTab > rFill.nLineWidth )
+                                ++nTabCnt;
+                        }
+                        else
+                        {
+                            const SvxTabStopItem& rTab =
+                                (const SvxTabStopItem &)pSet->
+                                GetPool()->GetDefaultItem( RES_PARATR_TABSTOP );
+                            MSHORT nDefTabDist = (MSHORT)rTab.GetStart()->GetTabPos();
+                            nRightTab = nLeftTab - nTxtLeft;
+                            nRightTab /= nDefTabDist;
+                            nRightTab = nRightTab * nDefTabDist + nTxtLeft;
+                            while ( nRightTab <= nLeftTab )
+                                nRightTab += nDefTabDist;
+                            if( nRightTab > rFill.nLineWidth )
+                                ++nTabCnt;
+                            while ( nRightTab < rFill.X() )
+                            {
+                                nRightTab += nDefTabDist;
+                                if( nRightTab > rFill.nLineWidth )
+                                    ++nTabCnt;
+                            }
+                            if( nLeftTab < nRightTab - nDefTabDist )
+                                nLeftTab = nRightTab - nDefTabDist;
+                        }
+                        if( nRightTab > nRight )
+                            nRightTab = nRight;
+                    }
+                    while( rFill.X() > nRightTab );
+                    --nTabCnt;
+                    if( FILL_TAB != rFill.Mode() )
+                    {
+                        if( nSpace > 0 )
+                        {
+                            if( !nTabCnt )
+                                nLeftTab = rFill.nLineWidth;
+                            while( nLeftTab < rFill.X() )
+                            {
+                                nLeftTab += nSpace;
+                                ++nSpaceCnt;
+                            }
+                            if( nSpaceCnt )
+                            {
+                                nLeftTab -= nSpace;
+                                --nSpaceCnt;
+                            }
+                            if( rFill.X() - nLeftTab > nRightTab - rFill.X() )
+                            {
+                                nSpaceCnt = 0;
+                                ++nTabCnt;
+                                rRect.Left( nRightTab );
+                            }
+                            else
+                            {
+                                if( rFill.X() - nLeftTab > nSpace/2 )
+                                {
+                                    ++nSpaceCnt;
+                                    rRect.Left( nLeftTab + nSpace );
+                                }
+                                else
+                                    rRect.Left( nLeftTab );
+                            }
+                        }
+                        else if( rFill.X() - nLeftTab < nRightTab - rFill.X() )
+                            rRect.Left( nLeftTab );
+                        else
+                        {
+                            if( nRightTab >= nRight )
+                            {
+                                rFill.SetOrient( HORI_RIGHT );
+                                rRect.Left( nRight );
+                                nTabCnt = 0;
+                                nSpaceCnt = 0;
+                            }
+                            else
+                            {
+                                rRect.Left( nRightTab );
+                                ++nTabCnt;
+                            }
+                        }
+                    }
+                    else
+                    {
+                        if( rFill.X() - nLeftTab < nRightTab - rFill.X() )
+                            rRect.Left( nLeftTab );
+                        else
+                        {
+                            if( nRightTab >= nRight )
+                            {
+                                rFill.SetOrient( HORI_RIGHT );
+                                rRect.Left( nRight );
+                                nTabCnt = 0;
+                                nSpaceCnt = 0;
+                            }
+                            else
+                            {
+                                rRect.Left( nRightTab );
+                                ++nTabCnt;
+                            }
+                        }
+                    }
+                    rFill.SetTab( nTabCnt );
+                    rFill.SetSpace( nSpaceCnt );
+                    if( bFill )
+                    {
+                        if( Abs( rFill.X() - nCenter ) <=
+                            Abs( rFill.X() - rRect.Left() ) )
+                        {
+                            rFill.SetOrient( HORI_CENTER );
+                            rFill.SetTab( 0 );
+                            rFill.SetSpace( 0 );
+                            rRect.Left( nCenter );
+                        }
+                        if( !rFill.bEmpty )
+                            rFill.nLineWidth += FILL_MIN_DIST;
+                        if( rRect.Left() < rFill.nLineWidth )
+                            bFill = sal_False;
+                    }
+                }
+            }
+            // Gehen wir ueber die Unterkante der Seite/Spalte etc. hinaus?
+            const SwFrm* pUp = GetUpper();
+            if( pUp->IsInSct() )
+            {
+                if( pUp->IsSctFrm() )
+                    pUp = pUp->GetUpper();
+                else if( pUp->IsColBodyFrm() &&
+                         pUp->GetUpper()->GetUpper()->IsSctFrm() )
+                    pUp = pUp->GetUpper()->GetUpper()->GetUpper();
+            }
+            if( pUp->Frm().Top() + pUp->Prt().Bottom() < rRect.Bottom() )
+                bFill = sal_False;
+            else
+                rRect.Width( 1 );
+        }
+    }
+    else
+        bFill = sal_False;
+    ((SwCrsrMoveState*)rFill.pCMS)->bFillRet = bFill;
+    delete pFnt;
+}
+
+
diff --git a/sw/source/core/text/frmform.cxx b/sw/source/core/text/frmform.cxx
new file mode 100644
index 000000000000..14d9fcb1e7b1
--- /dev/null
+++ b/sw/source/core/text/frmform.cxx
@@ -0,0 +1,1919 @@
+/*************************************************************************
+ *
+ *  $RCSfile: frmform.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:24 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _SVX_KEEPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_HYZNITEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _PAGEFRM_HXX
+#include       // ChangeFtnRef
+#endif
+#ifndef _NDTXT_HXX
+#include         // MakeFrm()
+#endif
+#ifndef _DCONTACT_HXX
+#include      // SwDrawContact
+#endif
+#ifndef _DFLYOBJ_HXX
+#include       // SwVirtFlyDrawObj
+#endif
+#ifndef _FLYFRM_HXX
+#include 
+#endif
+#ifndef _FTNFRM_HXX
+#include        // SwFtnFrm
+#endif
+#ifndef _TXTFTN_HXX
+#include 
+#endif
+#ifndef _FMTFTN_HXX
+#include 
+#endif
+#ifndef _PARATR_HXX
+#include 
+#endif
+#ifndef _VIEWOPT_HXX
+#include       // SwViewOptions
+#endif
+#ifndef _VIEWSH_HXX
+#include        // ViewShell
+#endif
+#ifndef _FRMATR_HXX
+#include 
+#endif
+#ifndef _FLYFRMS_HXX
+#include 
+#endif
+#ifndef _FRMSH_HXX
+#include 
+#endif
+#ifndef _TXATBASE_HXX
+#include 
+#endif
+#ifndef _TXTCFG_HXX
+#include 
+#endif
+#ifndef _ITRFORM2_HXX
+#include      // SwTxtFormatter
+#endif
+#ifndef _TXTFRM_HXX
+#include        // SwTxtFrm
+#endif
+#ifndef _WIDORP_HXX
+#include        // Widows and Orphans
+#endif
+#ifndef _TXTCACHE_HXX
+#include 
+#endif
+#ifndef _PORRST_HXX
+#include        // SwEmptyPortion
+#endif
+#ifndef _BLINK_HXX
+#include         // pBlink
+#endif
+#ifndef _PORFLD_HXX
+#include        // SwFldPortion
+#endif
+#ifndef _SECTFRM_HXX
+#include       // SwSectionFrm
+#endif
+
+#ifndef PRODUCT
+#ifndef _FRMFMT_HXX
+#include        // SwFrmFmt
+#endif
+#endif
+
+extern FASTBOOL IsInProgress( const SwFlyFrm *pFly );
+
+class FormatLevel
+{
+    static MSHORT nLevel;
+public:
+    inline FormatLevel()  { ++nLevel; }
+    inline ~FormatLevel() { --nLevel; }
+    inline MSHORT GetLevel() const { return nLevel; }
+    static sal_Bool LastLevel() { return 10 < nLevel; }
+};
+MSHORT FormatLevel::nLevel = 0;
+
+/*************************************************************************
+ *                          ValidateTxt/Frm()
+ *************************************************************************/
+
+void ValidateTxt( SwFrm *pFrm )     // Freund vom Frame
+{
+    if ( pFrm->Frm().Width() == pFrm->GetUpper()->Prt().Width() )
+        pFrm->bValidSize = sal_True;
+/*
+    pFrm->bValidPrtArea = sal_True;
+    //Die Position validieren um nicht unnoetige (Test-)Moves zu provozieren.
+    //Dabei darf allerdings nicht eine tatsaechlich falsche Coordinate
+    //validiert werden.
+    if ( !pFrm->bValidPos )
+    {
+        //Leider muessen wir dazu die korrekte Position berechnen.
+        Point aOld( pFrm->Frm().Pos() );
+        pFrm->MakePos();
+        if ( aOld != pFrm->Pos() )
+        {
+            pFrm->Frm().Pos( aOld );
+            pFrm->bValidPos = sal_False;
+        }
+    }
+*/
+}
+
+void SwTxtFrm::ValidateFrm()
+{
+    // Umgebung validieren, um Oszillationen zu verhindern.
+
+    if ( !IsInFly() )
+    {   //Innerhalb eines Flys nur this validieren, der Rest sollte eigentlich
+        //nur fuer Fussnoten notwendig sein und die gibt es innerhalb von
+        //Flys nicht. Fix fuer 5544
+        SwSectionFrm* pSct = FindSctFrm();
+        if( pSct )
+        {
+            if( !pSct->IsColLocked() )
+                pSct->ColLock();
+            else
+                pSct = NULL;
+        }
+
+        SwFrm *pUp = GetUpper();
+        pUp->Calc();
+        if( pSct )
+            pSct->ColUnlock();
+    }
+    ValidateTxt( this );
+
+    //MA: mindestens das MustFit-Flag muessen wir retten!
+    ASSERT( HasPara(), "ResetPreps(), missing ParaPortion." );
+    SwParaPortion *pPara = GetPara();
+    const sal_Bool bMustFit = pPara->IsPrepMustFit();
+    ResetPreps();
+    pPara->SetPrepMustFit( bMustFit );
+}
+
+/*************************************************************************
+ *                          ValidateBodyFrm()
+ *************************************************************************/
+
+// nach einem RemoveFtn muss der BodyFrm und alle innenliegenden kalkuliert
+// werden, damit die DeadLine richtig sitzt.
+// Erst wird nach aussen hin gesucht, beim Rueckweg werden alle kalkuliert.
+
+void _ValidateBodyFrm( SwFrm *pFrm )
+{
+    if( pFrm )
+    {
+        if( !pFrm->IsBodyFrm() && pFrm->GetUpper() )
+            _ValidateBodyFrm( pFrm->GetUpper() );
+        if( !pFrm->IsSctFrm() )
+            pFrm->Calc();
+        else
+        {
+            sal_Bool bOld = ((SwSectionFrm*)pFrm)->IsCntntLocked();
+            ((SwSectionFrm*)pFrm)->SetCntntLock( sal_True );
+            pFrm->Calc();
+            if( !bOld )
+                ((SwSectionFrm*)pFrm)->SetCntntLock( sal_False );
+        }
+    }
+}
+
+void SwTxtFrm::ValidateBodyFrm()
+{
+     //siehe Kommtar in ValidateFrm()
+    if ( !IsInFly() && !( IsInSct() && FindSctFrm()->Lower()->IsColumnFrm() ) )
+        _ValidateBodyFrm( GetUpper() );
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::FindBodyFrm()
+ *************************************************************************/
+
+sal_Bool SwTxtFrm::_GetDropRect( SwRect &rRect ) const
+{
+    ASSERT( HasPara(), "SwTxtFrm::_GetDropRect: try again next year." );
+    SwTxtSizeInfo aInf( (SwTxtFrm*)this );
+    SwTxtMargin aLine( (SwTxtFrm*)this, &aInf );
+    if( aLine.GetDropLines() )
+    {
+        rRect.Top( aLine.Y() );
+        rRect.Left( aLine.GetLineStart() );
+        rRect.Height( aLine.GetDropHeight() );
+        rRect.Width( aLine.GetDropLeft() );
+        return sal_True;
+    }
+    return sal_False;
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::FindBodyFrm()
+ *************************************************************************/
+
+const SwBodyFrm *SwTxtFrm::FindBodyFrm() const
+{
+    if ( IsInDocBody() )
+    {
+        const SwFrm *pFrm = GetUpper();
+        while( pFrm && !pFrm->IsBodyFrm() )
+            pFrm = pFrm->GetUpper();
+        return (const SwBodyFrm*)pFrm;
+    }
+    return 0;
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::CalcFollow()
+ *************************************************************************/
+
+sal_Bool SwTxtFrm::CalcFollow( const xub_StrLen nTxtOfst )
+{
+    ASSERT( HasFollow(), "CalcFollow: missing Follow." );
+
+    SwTxtFrm *pFollow = GetFollow();
+
+    SwParaPortion *pPara = GetPara();
+    sal_Bool bFollowFld = pPara ? pPara->IsFollowField() : sal_False;
+
+    if( !pFollow->GetOfst() || pFollow->GetOfst() != nTxtOfst ||
+        bFollowFld || pFollow->IsFieldFollow() || !pFollow->Prt().Height() )
+    {
+#ifndef PRODUCT
+        const SwFrm *pOldUp = GetUpper();
+#endif
+
+        SwTwips nOldBottom = GetUpper()->Frm().Bottom();
+        SwTwips nMyPos = Frm().Top();
+
+        const SwPageFrm *pPage = 0;
+        sal_Bool  bOldInvaCntnt,
+              bOldInvaLayout;
+        if ( !IsInFly() && GetNext() )
+        {
+            pPage = FindPageFrm();
+            //Minimieren - sprich ggf. zuruecksetzen - der Invalidierungen s.u.
+            bOldInvaCntnt  = pPage->IsInvalidCntnt();
+            bOldInvaLayout = pPage->IsInvalidLayout();
+        }
+
+        pFollow->_SetOfst( nTxtOfst );
+        pFollow->SetFieldFollow( bFollowFld );
+        if( HasFtn() || pFollow->HasFtn() )
+        {
+            ValidateFrm();
+            ValidateBodyFrm();
+            if( pPara )
+            {
+                *(pPara->GetReformat()) = SwCharRange();
+                *(pPara->GetDelta()) = 0;
+            }
+        }
+
+        //Der Fussnotenbereich darf sich keinesfalls vergrossern.
+        SwSaveFtnHeight aSave( FindFtnBossFrm( sal_True ), LONG_MAX );
+
+        ((SwTxtFrm*)pFollow)->CalcFtnFlag();
+        if ( !pFollow->GetNext() && !pFollow->HasFtn() )
+            nOldBottom = LONG_MAX;
+
+        while( sal_True )
+        {
+            if( !FormatLevel::LastLevel() )
+            {
+                // Weenn der Follow in einem spaltigen Bereich oder einem
+                // spaltigen Rahmen steckt, muss zunaechst dieser kalkuliert
+                // werden, da das FormatWidthCols() nicht funktioniert, wenn
+                // es aus dem MakeAll des _gelockten_ Follows heraus gerufen
+                // wird.
+                SwSectionFrm* pSct = pFollow->FindSctFrm();
+                if( pSct && !pSct->IsAnLower( this ) )
+                {
+                    if( pSct->GetFollow() )
+                        pSct->SimpleFormat();
+                    else if( !pSct->Frm().Height() )
+                        break;
+                }
+                pFollow->Calc();
+
+                // Der Follow merkt anhand seiner Frm().Height(), dass was schief
+                // gelaufen ist.
+                ASSERT( !pFollow->GetPrev(), "SwTxtFrm::CalcFollow: cheesy follow" );
+                if( pFollow->GetPrev() )
+                {
+                    pFollow->Prepare( PREP_CLEAR );
+                    pFollow->Calc();
+                    ASSERT( !pFollow->GetPrev(), "SwTxtFrm::CalcFollow: very cheesy follow" );
+                }
+
+                //Sicherstellen, dass der Follow gepaintet wird.
+                pFollow->SetCompletePaint();
+            }
+
+            pPara = GetPara();
+            //Solange der Follow wg. Orphans Zeilen angefordert, bekommt er
+            //diese und wird erneut formatiert, falls moeglich.
+            if( pPara && pPara->IsPrepWidows() )
+                CalcPreps();
+            else
+                break;
+        }
+
+        if( HasFtn() || pFollow->HasFtn() )
+        {
+            ValidateBodyFrm();
+            ValidateFrm();
+            if( pPara )
+            {
+                *(pPara->GetReformat()) = SwCharRange();
+                *(pPara->GetDelta()) = 0;
+            }
+        }
+
+        if ( pPage )
+        {
+            if ( !bOldInvaCntnt )
+                pPage->ValidateCntnt();
+            if ( !bOldInvaLayout && !IsInSct() )
+                pPage->ValidateLayout();
+        }
+
+#ifndef PRODUCT
+        ASSERT( pOldUp == GetUpper(), "SwTxtFrm::CalcFollow: heavy follow" );
+#endif
+
+        if( nOldBottom < GetUpper()->Frm().Bottom()  && !GetUpper()->IsSctFrm()
+            && GetUpper()->Frm().Bottom() - nOldBottom != Frm().Top() - nMyPos )
+            return sal_True;
+    }
+    return sal_False;
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::AdjustFrm()
+ *************************************************************************/
+
+void SwTxtFrm::AdjustFrm( const SwTwips nChgHght, sal_Bool bHasToFit )
+{
+    if( IsUndersized() )
+    {
+        if( GetOfst() && !IsFollow() ) // ein gescrollter Absatz (undersized)
+            return;
+        SetUndersized( nChgHght == 0 || bHasToFit );
+    }
+    // Die Size-Variable des Frames wird durch Grow inkrementiert
+    // oder durch Shrink dekrementiert. Wenn die Groesse
+    // unveraendert ist, soll nichts passieren!
+    if( nChgHght >= 0)
+    {
+        if( nChgHght && !bHasToFit )
+        {
+            if( IsInFtn() && !IsInSct() )
+            {
+                SwTwips nReal = Grow( nChgHght, pHeight, sal_True );
+                if( nReal < nChgHght )
+                {
+                    SwTwips nBot = Frm().Top() + Frm().Height() + nChgHght
+                                   - nReal;
+                    SwFrm* pCont = FindFtnFrm()->GetUpper();
+                    if( nBot > pCont->Frm().Top() + pCont->Frm().Height() )
+                    {
+                        Frm().SSize().Height() += nChgHght;
+                        Prt().SSize().Height() += nChgHght;
+                        return;
+                    }
+                }
+            }
+
+            Grow( nChgHght, pHeight );
+
+            if ( IsInFly() )
+            {
+                //MA 06. May. 93: Wenn einer der Upper ein Fly ist, so ist es
+                //sehr wahrscheinlich, dass dieser Fly durch das Grow seine
+                //Position veraendert - also muss auch meine Position korrigiert
+                //werden (sonst ist die Pruefung s.u. nicht aussagekraeftig).
+                //Die Vorgaenger muessen berechnet werden, damit die Position
+                //korrekt berechnet werden kann.
+                if ( GetPrev() )
+                {
+                    SwFrm *pPre = GetUpper()->Lower();
+                    do
+                    {   pPre->Calc();
+                        pPre = pPre->GetNext();
+                    } while ( pPre && pPre != this );
+                }
+                const Point aOldPos( Frm().Pos() );
+                MakePos();
+                if ( aOldPos != Frm().Pos() )
+                    CalcFlys( sal_True );   //#43679# Fly in Fly in ...
+            }
+        }
+        // Ein Grow() wird von der Layout-Seite immer akzeptiert,
+        // also auch, wenn die FixSize des umgebenden Layoutframes
+        // dies nicht zulassen sollte. Wir ueberpruefen diesen
+        // Fall und korrigieren die Werte.
+        // MA 06. May. 93: Der Frm darf allerdings auch im Notfall nicht
+        // weiter geschrumpft werden als es seine Groesse zulaesst.
+        SwTwips nRstHeight = GetUpper()->Frm().Top()
+                            + GetUpper()->Prt().Top()
+                            + GetUpper()->Prt().Height()
+                            - Frm().Top();
+        //In Tabellenzellen kann ich mir evtl. noch ein wenig dazuholen, weil
+        //durch eine vertikale Ausrichtung auch oben noch Raum sein kann.
+        if ( IsInTab() )
+        {
+            long nAdd = GetUpper()->Lower()->Frm().Top() -
+                            (GetUpper()->Frm().Top() + GetUpper()->Prt().Top());
+            nRstHeight += nAdd;
+        }
+
+/* ------------------------------------
+ * #50964#: nRstHeight < 0 bedeutet, dass der TxtFrm komplett ausserhalb seines
+ * Upper liegt. Dies kann passieren, wenn er innerhalb eines FlyAtCntFrm liegt, der
+ * durch das Grow() die Seite gewechselt hat. In so einem Fall ist es falsch, der
+ * folgenden Grow-Versuch durchzufuehren. Im Bugfall fuehrte dies sogar zur
+ * Endlosschleife.
+ * -----------------------------------*/
+        if( nRstHeight < Frm().Height() )
+        {
+            //Kann sein, dass ich die richtige Grosse habe, der Upper aber zu
+            //klein ist und der Upper noch Platz schaffen kann.
+            if( ( nRstHeight > 0 || ( IsInFtn() && IsInSct() ) ) && !bHasToFit )
+                nRstHeight += GetUpper()->Grow( Frm().Height()-nRstHeight, pHeight );
+            // In spaltigen Bereichen wollen wir moeglichst nicht zu gross werden, damit
+            // nicht ueber GetNextSctLeaf weitere Bereiche angelegt werden. Stattdessen
+            // schrumpfen wir und notieren bUndersized, damit FormatWidthCols die richtige
+            // Spaltengroesse ermitteln kann.
+            if ( nRstHeight < Frm().Height() )
+            {
+                if( bHasToFit || !IsMoveable() ||
+                    ( IsInSct() && !FindSctFrm()->MoveAllowed(this) ) )
+                {
+                    SetUndersized( sal_True );
+                    Shrink( Min( (Frm().Height() - nRstHeight), Prt().Height()),
+                                  pHeight );
+                }
+                else
+                    SetUndersized( sal_False );
+            }
+        }
+    }
+    else if ( nChgHght )
+        Shrink( -nChgHght, pHeight );
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::AdjustFollow()
+ *************************************************************************/
+
+/* AdjustFollow erwartet folgende Situation:
+ * Der SwTxtIter steht am unteren Ende des Masters, der Offset wird
+ * im Follow eingestellt.
+ * nOffset haelt den Offset im Textstring, ab dem der Master abschliesst
+ * und der Follow beginnt. Wenn er 0 ist, wird der FolgeFrame geloescht.
+ */
+
+void SwTxtFrm::_AdjustFollow( SwTxtFormatter &rLine,
+                             const xub_StrLen nOffset, const xub_StrLen nEnd,
+                             const sal_uInt8 nMode )
+{
+    // Wir haben den Rest der Textmasse: alle Follows loeschen
+    // Sonderfall sind DummyPortions()
+    if( HasFollow() && !(nMode & 1) && nOffset == nEnd )
+    {
+        while( GetFollow() )
+        {
+            if( ((SwTxtFrm*)GetFollow())->IsLocked() )
+            {
+                ASSERT( sal_False, "+SwTxtFrm::JoinFrm: Follow ist locked." );
+                return;
+            }
+            JoinFrm();
+        }
+        return;
+    }
+
+    // Tanz auf dem Vulkan: Wir formatieren eben schnell noch einmal
+    // die letzte Zeile fuer das QuoVadis-Geraffel. Selbstverstaendlich
+    // kann sich dadurch auch der Offset verschieben:
+    const xub_StrLen nNewOfst = ( IsInFtn() && ( !GetIndNext() || HasFollow() ) ) ?
+                            rLine.FormatQuoVadis(nOffset) : nOffset;
+
+    if( !(nMode & 1) )
+    {
+        // Wir klauen unseren Follows Textmasse, dabei kann es passieren,
+        // dass wir einige Follows Joinen muessen.
+        while( GetFollow() && GetFollow()->GetFollow() &&
+               nNewOfst >= GetFollow()->GetFollow()->GetOfst() )
+        {
+            DBG_LOOP;
+            JoinFrm();
+        }
+    }
+
+    // Der Ofst hat sich verschoben.
+    if( GetFollow() )
+    {
+#ifdef DEBUG
+        static sal_Bool bTest = sal_False;
+        if( !bTest || ( nMode & 1 ) )
+#endif
+        if ( nMode )
+            GetFollow()->ManipOfst( 0 );
+
+        if ( CalcFollow( nNewOfst ) )   // CalcFollow erst zum Schluss, dort erfolgt ein SetOfst
+            rLine.SetOnceMore( sal_True );
+    }
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::JoinFrm()
+ *************************************************************************/
+
+SwCntntFrm *SwTxtFrm::JoinFrm()
+{
+    ASSERT( GetFollow(), "+SwTxtFrm::JoinFrm: no follow" );
+    SwTxtFrm  *pFoll = GetFollow();
+
+    SwTxtFrm *pNxt = pFoll->GetFollow();
+
+    // Alle Fussnoten des zu zerstoerenden Follows werden auf uns
+    // umgehaengt.
+    xub_StrLen nStart = pFoll->GetOfst();
+    if ( pFoll->HasFtn() )
+    {
+        const SwpHints *pHints = pFoll->GetTxtNode()->GetpSwpHints();
+        if( pHints )
+        {
+            SwFtnBossFrm *pFtnBoss = 0;
+            SwFtnBossFrm *pEndBoss = 0;
+            for( MSHORT i = 0; i < pHints->Count(); ++i )
+            {
+                const SwTxtAttr *pHt = (*pHints)[i];
+                if( RES_TXTATR_FTN==pHt->Which() && *pHt->GetStart()>=nStart )
+                {
+                    if( pHt->GetFtn().IsEndNote() )
+                    {
+                        if( !pEndBoss )
+                            pEndBoss = pFoll->FindFtnBossFrm();
+                        pEndBoss->ChangeFtnRef( pFoll, (SwTxtFtn*)pHt, this );
+                    }
+                    else
+                    {
+                        if( !pFtnBoss )
+                            pFtnBoss = pFoll->FindFtnBossFrm( sal_True );
+                        pFtnBoss->ChangeFtnRef( pFoll, (SwTxtFtn*)pHt, this );
+                    }
+                    SetFtn( sal_True );
+                }
+            }
+        }
+    }
+
+#ifndef PRODUCT
+    else
+    {
+        pFoll->CalcFtnFlag();
+        ASSERT( !pFoll->HasFtn(), "Missing FtnFlag." );
+    }
+#endif
+
+    pFoll->MoveFlyInCnt( this, nStart, STRING_LEN );
+    pFoll->Cut();
+    delete pFoll;
+    pFollow = pNxt;
+    return pNxt;
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::SplitFrm()
+ *************************************************************************/
+
+SwCntntFrm *SwTxtFrm::SplitFrm( const xub_StrLen nTxtPos )
+{
+    // Durch das Paste wird ein Modify() an mich verschickt.
+    // Damit meine Daten nicht verschwinden, locke ich mich.
+    SwTxtFrmLocker aLock( this );
+    SwTxtFrm *pNew = (SwTxtFrm *)(GetTxtNode()->MakeFrm());
+    pNew->bIsFollow = sal_True;
+
+    pNew->SetFollow( GetFollow() );
+    SetFollow( pNew );
+
+    pNew->Paste( GetUpper(), GetNext() );
+
+    // Wenn durch unsere Aktionen Fussnoten in pNew landen,
+    // so muessen sie umgemeldet werden.
+    if ( HasFtn() )
+    {
+        const SwpHints *pHints = GetTxtNode()->GetpSwpHints();
+        if( pHints )
+        {
+            SwFtnBossFrm *pFtnBoss = 0;
+            SwFtnBossFrm *pEndBoss = 0;
+            for( MSHORT i = 0; i < pHints->Count(); ++i )
+            {
+                const SwTxtAttr *pHt = (*pHints)[i];
+                if( RES_TXTATR_FTN==pHt->Which() && *pHt->GetStart()>=nTxtPos )
+                {
+                    if( pHt->GetFtn().IsEndNote() )
+                    {
+                        if( !pEndBoss )
+                            pEndBoss = FindFtnBossFrm();
+                        pEndBoss->ChangeFtnRef( this, (SwTxtFtn*)pHt, pNew );
+                    }
+                    else
+                    {
+                        if( !pFtnBoss )
+                            pFtnBoss = FindFtnBossFrm( sal_True );
+                        pFtnBoss->ChangeFtnRef( this, (SwTxtFtn*)pHt, pNew );
+                    }
+                    pNew->SetFtn( sal_True );
+                }
+            }
+        }
+    }
+
+#ifndef PRODUCT
+    else
+    {
+        CalcFtnFlag( nTxtPos-1 );
+        ASSERT( !HasFtn(), "Missing FtnFlag." );
+    }
+#endif
+
+    MoveFlyInCnt( pNew, nTxtPos, STRING_LEN );
+
+    // Kein SetOfst oder CalcFollow, weil gleich ohnehin ein AdjustFollow folgt.
+#ifdef USED
+    CalcFollow( nNewOfst );
+#endif
+
+    pNew->ManipOfst( nTxtPos );
+    return pNew;
+}
+
+
+/*************************************************************************
+ *                      virtual SwTxtFrm::SetOfst()
+ *************************************************************************/
+
+void SwTxtFrm::_SetOfst( const xub_StrLen nNewOfst )
+{
+#ifdef DBGTXT
+    // Es gibt tatsaechlich einen Sonderfall, in dem ein SetOfst(0)
+    // zulaessig ist: bug 3496
+    ASSERT( nNewOfst, "!SwTxtFrm::SetOfst: missing JoinFrm()." );
+#endif
+
+    // Die Invalidierung unseres Follows ist nicht noetig.
+    // Wir sind ein Follow, werden gleich formatiert und
+    // rufen von dort aus das SetOfst() !
+    nOfst = nNewOfst;
+    SwParaPortion *pPara = GetPara();
+    if( pPara )
+    {
+        SwCharRange &rReformat = *(pPara->GetReformat());
+        rReformat.Start() = 0;
+        rReformat.Len() = GetTxt().Len();
+        *(pPara->GetDelta()) = rReformat.Len();
+    }
+    InvalidateSize();
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::CalcPreps
+ *************************************************************************/
+
+sal_Bool SwTxtFrm::CalcPreps()
+{
+    SwParaPortion *pPara = GetPara();
+    if ( !pPara )
+        return sal_False;
+    sal_Bool bPrep = pPara->IsPrep();
+    sal_Bool bPrepWidows = pPara->IsPrepWidows();
+    sal_Bool bPrepAdjust = pPara->IsPrepAdjust();
+    sal_Bool bPrepMustFit = pPara->IsPrepMustFit();
+    ResetPreps();
+
+    sal_Bool bRet = sal_False;
+    if( bPrep && !pPara->GetReformat()->Len() )
+    {
+        // PREP_WIDOWS bedeutet, dass im Follow die Orphans-Regel
+        // zuschlug.
+        // Es kann in unguenstigen Faellen vorkommen, dass auch ein
+        // PrepAdjust vorliegt (3680)!
+        if( bPrepWidows )
+        {
+            if( !GetFollow() )
+            {
+                ASSERT( GetFollow(), "+SwTxtFrm::CalcPreps: no credits" );
+                return sal_False;
+            }
+
+            // Wir muessen uns auf zwei Faelle einstellen:
+            // Wir konnten dem Follow noch ein paar Zeilen abgeben,
+            // -> dann muessen wir schrumpfen
+            // oder wir muessen auf die naechste Seite
+            // -> dann lassen wir unseren Frame zu gross werden.
+
+            SwTwips nChgHeight = GetParHeight();
+            if( nChgHeight >= Prt().Height() )
+            {
+                if( bPrepMustFit )
+                {
+                    GetFollow()->SetJustWidow( sal_True );
+                    GetFollow()->Prepare( PREP_CLEAR );
+                }
+                else
+                {
+                    SwTwips nTmp  = LONG_MAX - (Frm().Top()+10000);
+                    SwTwips nDiff = nTmp - Frm().Height();
+                    Frm().Height( nTmp );
+                    Prt().Height( Prt().Height() + nDiff );
+                    SetWidow( sal_True );
+                }
+            }
+            else
+            {
+                ASSERT( nChgHeight < Prt().Height(),
+                        "+SwTxtFrm::CalcPrep: wanna shrink" );
+                nChgHeight = Prt().Height() - nChgHeight;
+                GetFollow()->SetJustWidow( sal_True );
+                GetFollow()->Prepare( PREP_CLEAR );
+                Shrink( nChgHeight, pHeight );
+                SwRect &rRepaint = *(pPara->GetRepaint());
+                rRepaint.Chg( Frm().Pos() + Prt().Pos(), Prt().SSize() );
+                // 6792: Rrand < LRand und Repaint
+                if( 0 >= rRepaint.Width() )
+                    rRepaint.Width(1);
+            }
+            bRet = sal_True;
+        }
+
+        else if ( bPrepAdjust )
+        {
+            if ( HasFtn() )
+            {
+                if( !CalcPrepFtnAdjust() )
+                {
+                    if( bPrepMustFit )
+                    {
+                        SwTxtLineAccess aAccess( this );
+                        aAccess.GetPara()->SetPrepMustFit( sal_True );
+                    }
+                    return sal_False;
+                }
+            }
+
+            SwTxtFormatInfo aInf( this );
+            SwTxtFormatter aLine( this, &aInf );
+
+            WidowsAndOrphans aFrmBreak( this );
+            // Egal was die Attribute meinen, bei MustFit wird
+            // der Absatz im Notfall trotzdem gesplittet...
+            if( bPrepMustFit )
+            {
+                aFrmBreak.SetKeep( sal_False );
+                aFrmBreak.ClrOrphLines();
+            }
+            // Bevor wir FormatAdjust aufrufen muessen wir dafuer
+            // sorgen, dass die Zeilen, die unten raushaengen
+            // auch tatsaechlich abgeschnitten werden.
+            sal_Bool bBreak = aFrmBreak.IsBreakNow( aLine );
+            bRet = sal_True;
+            while( !bBreak && aLine.Next() )
+                bBreak = aFrmBreak.IsBreakNow( aLine );
+            if( bBreak )
+            {
+                // Es gibt Komplikationen: wenn TruncLines gerufen wird,
+                // veraendern sich ploetzlich die Bedingungen in
+                // IsInside, so dass IsBreakNow andere Ergebnisse
+                // liefern kann. Aus diesem Grund wird rFrmBreak bekannt
+                // gegeben, dass da wo rLine steht, das Ende erreicht
+                // ist. Mal sehen, ob's klappt ...
+                aLine.TruncLines();
+                aFrmBreak.SetRstHeight( aLine );
+                FormatAdjust( aLine, aFrmBreak, aInf.GetTxt().Len(), aInf.IsStop() );
+            }
+            else
+            {
+                if( !GetFollow() )
+                    FormatAdjust( aLine, aFrmBreak,
+                                  aInf.GetTxt().Len(), aInf.IsStop() );
+                else if ( !aFrmBreak.IsKeepAlways() )
+                {
+                    // Siehe Bug: 2320
+                    // Vor dem Master wird eine Zeile geloescht, der Follow
+                    // koennte eine Zeile abgeben.
+                    const SwCharRange aFollowRg( GetFollow()->GetOfst(), 1 );
+                    *(pPara->GetReformat()) += aFollowRg;
+                    // Es soll weitergehen!
+                    bRet = sal_False;
+                }
+            }
+
+            // Eine letzte Ueberpruefung, falls das FormatAdjust() nichts
+            // brachte, muessen wir amputieren.
+            if( bPrepMustFit )
+            {
+                const SwTwips nMust = GetUpper()->Frm().Top()
+                    + GetUpper()->Prt().Top() + GetUpper()->Prt().Height();
+                const SwTwips nIs   = Frm().Top() + Frm().Height();
+                if( nIs > nMust )
+                {
+                    Shrink( nIs - nMust, pHeight );
+                    if( Prt().Height() < 0 )
+                        Prt().Height( 0 );
+                    SetUndersized( sal_True );
+                }
+            }
+        }
+    }
+    pPara->SetPrepMustFit( bPrepMustFit );
+    return bRet;
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::FormatAdjust()
+ *************************************************************************/
+
+// Hier werden die Fussnoten und "als Zeichen"-gebundenen Objekte umgehaengt
+#define CHG_OFFSET( pFrm, nNew )\
+    {\
+        if( pFrm->GetOfst() < nNew )\
+            pFrm->MoveFlyInCnt( this, 0, nNew );\
+        else if( pFrm->GetOfst() > nNew )\
+            MoveFlyInCnt( pFrm, nNew, STRING_LEN );\
+    }
+
+void SwTxtFrm::FormatAdjust( SwTxtFormatter &rLine,
+                             WidowsAndOrphans &rFrmBreak,
+                             const xub_StrLen nStrLen, const sal_Bool bDummy )
+{
+    SwParaPortion *pPara = rLine.GetInfo().GetParaPortion();
+
+    xub_StrLen nEnd = rLine.GetStart();
+
+    // Wir muessen fuer eindeutige Verhaeltnisse sorgen
+    // rFrmBreak.SetRstHeight( rLine );
+
+    // rLine.GetStart(): die letzte Zeile von rLine,
+    // ist bereits die Zeile, die nicht
+    // mehr passte. Ihr Anfang ist das Ende des Masters.
+    // @@@if( !GetFollow() && nEnd < nStrLen )
+    // (nEnd < nStrLen || rFrmBreak.IsBreakNow(rLine));
+
+    sal_Bool bHasToFit = pPara->IsPrepMustFit();
+
+    // Das StopFlag wird durch Fussnoten gesetzt,
+    // die auf die naechste Seite wollen.
+    sal_uInt8 nNew = ( !GetFollow() && nEnd < nStrLen &&
+        ( rLine.IsStop() || ( bHasToFit ?
+        ( rLine.GetLineNr() > 1 && !rFrmBreak.IsInside( rLine ) )
+        : rFrmBreak.IsBreakNow( rLine ) ) ) ) ? 1 : 0;
+    if( nNew )
+        SplitFrm( nEnd );
+
+    const SwFrm *pBodyFrm = (const SwFrm*)(FindBodyFrm());
+    const long nBodyHeight = pBodyFrm ? pBodyFrm->Frm().Height() : 0;
+
+    // Wenn die aktuellen Werte berechnet wurden, anzeigen, dass
+    // sie jetzt gueltig sind.
+    *(pPara->GetReformat()) = SwCharRange();
+    sal_Bool bDelta = *pPara->GetDelta() != 0;
+    *(pPara->GetDelta()) = 0;
+
+    if( rLine.IsStop() )
+    {
+        rLine.TruncLines( sal_True );
+        nNew = 1;
+    }
+
+    // FindBreak schneidet die letzte Zeile ab.
+    if( !rFrmBreak.FindBreak( this, rLine, bHasToFit ) )
+    {
+        // Wenn wir bis zum Ende durchformatiert haben, wird nEnd auf das Ende
+        // gesetzt. In AdjustFollow wird dadurch ggf. JoinFrm() ausgefuehrt.
+        // Ansonsten ist nEnd das Ende der letzten Zeile im Master.
+        xub_StrLen nOld = nEnd;
+        nEnd = rLine.GetEnd();
+        if( GetFollow() )
+        {
+            if( nNew && nOld < nEnd )
+                RemoveFtn( nOld, nEnd - nOld );
+            CHG_OFFSET( GetFollow(), nEnd )
+            if( !bDelta )
+                GetFollow()->ManipOfst( nEnd );
+        }
+    }
+    else
+    {   // Wenn wir Zeilen abgeben, darf kein Join auf den Folows gerufen werden,
+        // im Gegenteil, es muss ggf. sogar ein Follow erzeugt werden.
+        // Dies muss auch geschehen, wenn die Textmasse komplett im Master
+        // bleibt, denn es könnte ja ein harter Zeilenumbruch noch eine weitere
+        // Zeile (ohne Textmassse) notwendig machen!
+        nEnd = rLine.GetEnd();
+        if( GetFollow() )
+        {
+            if( GetFollow()->GetOfst() != nEnd || GetFollow()->IsFieldFollow() )
+                nNew |= 3;
+            CHG_OFFSET( GetFollow(), nEnd )
+            GetFollow()->ManipOfst( nEnd );
+        }
+        else
+        {
+            SplitFrm( nEnd );
+            nNew |= 3;
+        }
+        // Wenn sich die Resthoehe geaendert hat, z.B. durch RemoveFtn()
+        // dann muessen wir auffuellen, um Oszillationen zu vermeiden!
+        if( bDummy && pBodyFrm && nBodyHeight < pBodyFrm->Frm().Height() )
+            rLine.MakeDummyLine();
+    }
+
+    // In AdjustFrm() stellen wir uns selbst per Grow/Shrink ein,
+    // in AdjustFollow() stellen wir unseren FolgeFrame ein.
+
+    const SwTwips nDocPrtTop = Frm().Top() + Prt().Top();
+    const SwTwips nOldHeight = Prt().SSize().Height();
+    const SwTwips nChg = rLine.CalcBottomLine() - nDocPrtTop - nOldHeight;
+
+    AdjustFrm( nChg, bHasToFit );
+
+    if( HasFollow() || IsInFtn() )
+        _AdjustFollow( rLine, nEnd, nStrLen, nNew );
+    pPara->SetPrepMustFit( sal_False );
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::FormatLine()
+ *************************************************************************/
+
+// bPrev zeigt an, ob Reformat.Start() wegen Prev() vorgezogen wurde.
+// Man weiss sonst nicht, ob man Repaint weiter einschraenken kann oder nicht.
+
+
+sal_Bool SwTxtFrm::FormatLine( SwTxtFormatter &rLine, const sal_Bool bPrev )
+{
+    SwParaPortion *pPara = rLine.GetInfo().GetParaPortion();
+    // Nach rLine.FormatLine() haelt nStart den neuen Wert,
+    // waehrend in pOldStart der alte Offset gepflegt wird.
+    // Ueber diesen Weg soll das nDelta ersetzt werden.
+    // *pOldStart += rLine.GetCurr()->GetLen();
+    const SwLineLayout *pOldCur = rLine.GetCurr();
+    const xub_StrLen nOldLen    = pOldCur->GetLen();
+    const KSHORT nOldAscent = pOldCur->GetAscent();
+    const KSHORT nOldHeight = pOldCur->Height();
+    const KSHORT nOldWidth  = pOldCur->Width();
+    const sal_Bool bOldHyph = pOldCur->IsEndHyph();
+    SwTwips nOldTop = 0;
+    SwTwips nOldBottom;
+    if( rLine.GetCurr()->IsClipping() )
+        rLine.CalcUnclipped( nOldTop, nOldBottom );
+
+    const xub_StrLen nNewStart = rLine.FormatLine( rLine.GetStart() );
+
+    ASSERT( Frm().Pos() + Prt().Pos() == rLine.GetFirstPos(),
+            "SwTxtFrm::FormatLine: frame leaves orbit." );
+    ASSERT( rLine.GetCurr()->Height(),
+            "SwTxtFrm::FormatLine: line height is zero" );
+
+    // Das aktuelle Zeilenumbruchobjekt.
+    const SwLineLayout *pNew = rLine.GetCurr();
+
+    sal_Bool bUnChg = nOldLen == pNew->GetLen() &&
+                  bOldHyph == pNew->IsEndHyph();
+    if ( bUnChg && !bPrev )
+    {
+        // 6672: Toleranz von SLOPPY_TWIPS (5 Twips); vgl. 6922
+        const KSHORT nWidthDiff = nOldWidth > pNew->Width()
+                                ? nOldWidth - pNew->Width()
+                                : pNew->Width() - nOldWidth;
+        bUnChg = nOldHeight == pNew->Height() &&
+                 nOldAscent == pNew->GetAscent() &&
+                 nWidthDiff <= SLOPPY_TWIPS;
+    }
+
+    // rRepaint wird berechnet:
+    const SwTwips nBottom = rLine.Y() + rLine.GetLineHeight();
+    SwRepaint &rRepaint = *(pPara->GetRepaint());
+    if( bUnChg && rRepaint.Top() == rLine.Y()
+               && (bPrev || nNewStart <= pPara->GetReformat()->Start())
+               && ( nNewStart < GetTxtNode()->GetTxt().Len() ) )
+    {
+        rRepaint.Top( nBottom );
+        rRepaint.Height( 0 );
+    }
+    else
+    {
+        if( nOldTop )
+        {
+            if( nOldTop < rRepaint.Top() )
+                rRepaint.Top( nOldTop );
+            if( !rLine.IsUnclipped() || nOldBottom > rRepaint.Bottom() )
+            {
+                rRepaint.Bottom( nOldBottom - 1 );
+                rLine.SetUnclipped( sal_True );
+            }
+        }
+        if( rLine.GetCurr()->IsClipping() && rLine.IsFlyInCntBase() )
+        {
+            SwTwips nTmpTop, nTmpBottom;
+            rLine.CalcUnclipped( nTmpTop, nTmpBottom );
+            if( nTmpTop < rRepaint.Top() )
+                rRepaint.Top( nTmpTop );
+            if( !rLine.IsUnclipped() || nTmpBottom > rRepaint.Bottom() )
+            {
+                rRepaint.Bottom( nTmpBottom - 1 );
+                rLine.SetUnclipped( sal_True );
+            }
+        }
+        else
+        {
+            if( !rLine.IsUnclipped() || nBottom > rRepaint.Bottom() )
+            {
+                rRepaint.Bottom( nBottom - 1 );
+                rLine.SetUnclipped( sal_False );
+            }
+        }
+        if ( rRepaint.GetOfst() )
+        {
+            SwTwips nRght = Max( nOldWidth, pNew->Width() );
+            ViewShell *pSh = GetShell();
+            const SwViewOption *pOpt = pSh ? pSh->GetViewOptions() : 0;
+            if( pOpt && (pOpt->IsParagraph() || pOpt->IsLineBreak()) )
+                nRght += ( Max( nOldAscent, pNew->GetAscent() ) );
+            else
+                nRght += ( Max( nOldAscent, pNew->GetAscent() ) / 4);
+            rRepaint.SetRightOfst( rLine.GetLeftMargin() + nRght );
+        }
+    }
+    if( !bUnChg )
+        rLine.SetChanges();
+
+    // Die gute, alte nDelta-Berechnung:
+    *(pPara->GetDelta()) -= long(pNew->GetLen()) - long(nOldLen);
+
+    // Stop!
+    if( rLine.IsStop() )
+        return sal_False;
+
+    // Unbedingt noch eine Zeile
+    if( rLine.IsNewLine() )
+        return sal_True;
+
+    // bis zum Ende des Strings ?
+    if( nNewStart >= GetTxtNode()->GetTxt().Len() )
+        return sal_False;
+
+    if( rLine.GetInfo().IsShift() )
+        return sal_True;
+
+    // Ende des Reformats erreicht ?
+    const xub_StrLen nEnd = pPara->GetReformat()->Start() +
+                        pPara->GetReformat()->Len();
+
+    if( nNewStart <= nEnd )
+        return sal_True;
+
+    return 0 != *(pPara->GetDelta());
+
+// Dieser Bereich ist so sensibel, da behalten wir mal die alte Version:
+#ifdef USED
+    // nDelta abgearbeitet ?
+    if( 0 == *(pPara->GetDelta()) )
+        return sal_False;
+
+    // Wenn die Zeilen ausgeglichen sind, ist alles ok.
+    if( bUnChg )
+        return sal_False;
+
+    return sal_True;
+#endif
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::_Format()
+ *************************************************************************/
+
+void SwTxtFrm::_Format( SwTxtFormatter &rLine, SwTxtFormatInfo &rInf,
+                        const sal_Bool bAdjust )
+{
+    SwParaPortion *pPara = rLine.GetInfo().GetParaPortion();
+    rLine.SetUnclipped( sal_False );
+
+    // Das war dem C30 zu kompliziert: aString( GetTxt() );
+    const XubString &rString = GetTxtNode()->GetTxt();
+    const xub_StrLen nStrLen = rString.Len();
+
+    SwCharRange &rReformat = *(pPara->GetReformat());
+    SwRepaint   &rRepaint = *(pPara->GetRepaint());
+    SwRepaint *pFreeze = NULL;
+
+    // Aus Performancegruenden wird in Init() rReformat auf STRING_LEN gesetzt.
+    // Fuer diesen Fall wird rReformat angepasst.
+    if( rReformat.Len() > nStrLen )
+        rReformat.Len() = nStrLen;
+
+    // Optimiert:
+    xub_StrLen nEnd = rReformat.Start() + rReformat.Len();
+    if( nEnd > nStrLen )
+    {
+        rReformat.Len() = nStrLen - rReformat.Start();
+        nEnd = nStrLen;
+    }
+
+    SwTwips nOldBottom;
+    if( GetOfst() && !IsFollow() )
+    {
+        rLine.Bottom();
+        nOldBottom = rLine.Y();
+        rLine.Top();
+    }
+    else
+        nOldBottom = 0;
+    rLine.CharToLine( rReformat.Start() );
+
+    // Worte koennen durch Fortfall oder Einfuegen eines Space
+    // auf die Zeile vor der editierten hinausgezogen werden,
+    // deshalb muss diese ebenfalls formatiert werden.
+    // Optimierung: Wenn rReformat erst hinter dem ersten Wort der
+    // Zeile beginnt, so kann diese Zeile die vorige nicht mehr beeinflussen.
+    // AMA: Leider doch, Textgroessenaenderungen + FlyFrames, die Rueckwirkung
+    // kann im Extremfall mehrere Zeilen (Frames!!!) betreffen!
+
+    sal_Bool bPrev = rLine.GetPrev() &&
+                     ( FindBrk( rString, rLine.GetStart(),
+                                rReformat.Start() + 1 ) >= rReformat.Start() ||
+                       rLine.GetCurr()->IsRest() );
+    if( bPrev )
+    {
+        while( rLine.Prev() )
+            if( rLine.GetCurr()->GetLen() && !rLine.GetCurr()->IsRest() )
+            {
+                if( !rLine.GetStart() )
+                    rLine.Top(); // damit NumDone nicht durcheinander kommt
+                break;
+            }
+        xub_StrLen nNew = rLine.GetStart() + rLine.GetLength();
+        if( nNew )
+        {
+            --nNew;
+            if( CH_BREAK == rString.GetChar( nNew ) )
+            {
+                ++nNew;
+                rLine.Next();
+                bPrev = sal_False;
+            }
+        }
+        rReformat.Len()  += rReformat.Start() - nNew;
+        rReformat.Start() = nNew;
+    }
+
+    rRepaint.SetOfst( 0 );
+    rRepaint.SetRightOfst( 0 );
+    rRepaint.Chg( Frm().Pos() + Prt().Pos(), Prt().SSize() );
+    rRepaint.Top( rLine.Y() );
+    // 6792: Rrand < LRand und Repaint
+    if( 0 >= rRepaint.Width() )
+        rRepaint.Width(1);
+    WidowsAndOrphans aFrmBreak( this, rInf.IsTest() ? 1 : 0 );
+
+    // rLine steht jetzt auf der ersten Zeile, die formatiert werden
+    // muss. Das Flag bFirst sorgt dafuer, dass nicht Next() gerufen wird.
+    // Das ganze sieht verdreht aus, aber es muss sichergestellt werden,
+    // dass bei IsBreakNow rLine auf der Zeile zum stehen kommt, die
+    // nicht mehr passt.
+    sal_Bool bFirst  = sal_True;
+    sal_Bool bFormat = sal_True;
+
+    // 5383: Das CharToLine() kann uns auch in den roten Bereich fuehren.
+    // In diesem Fall muessen wir zurueckwandern, bis die Zeile, die
+    // nicht mehr passt in rLine eingestellt ist. Ansonsten geht Textmasse
+    // verloren, weil der Ofst im Follow falsch eingestellt wird.
+
+    sal_Bool bBreak = ( !pPara->IsPrepMustFit() || rLine.GetLineNr() > 1 )
+                    && aFrmBreak.IsBreakNow( rLine );
+    if( bBreak )
+    {
+        sal_Bool bPrevDone = 0 != rLine.Prev();
+        while( bPrevDone && aFrmBreak.IsBreakNow(rLine) )
+            bPrevDone = 0 != rLine.Prev();
+        if( bPrevDone )
+        {
+            aFrmBreak.SetKeep( sal_False );
+            rLine.Next();
+        }
+        rLine.TruncLines();
+
+        // auf Nummer sicher:
+        bBreak = aFrmBreak.IsBreakNow(rLine) &&
+                  ( !pPara->IsPrepMustFit() || rLine.GetLineNr() > 1 );
+    }
+
+ /* Bedeutung der folgenden Flags:
+    Ist das Watch(End/Mid)Hyph-Flag gesetzt, so muss formatiert werden, wenn
+    eine Trennung am (Zeilenende/Fly) vorliegt, sofern MaxHyph erreicht ist.
+    Das Jump(End/Mid)Flag bedeutet, dass die naechste Zeile, bei der keine
+    Trennung (Zeilenende/Fly) vorliegt, formatiert werden muss, da jetzt
+    umgebrochen werden koennte, was vorher moeglicherweise durch MaxHyph
+    verboten war.
+    Watch(End/Mid)Hyph wird gesetzt, wenn die letzte formatierte Zeile eine
+    Trennstelle erhalten hat, vorher aber keine hatte,
+    Jump(End/Mid)Hyph, wenn eine Trennstelle verschwindet.
+ */
+    sal_Bool bJumpEndHyph  = sal_False,
+         bWatchEndHyph = sal_False,
+         bJumpMidHyph  = sal_False,
+         bWatchMidHyph = sal_False;
+
+    const SwAttrSet& rAttrSet = GetTxtNode()->GetSwAttrSet();
+    sal_Bool bMaxHyph = ( 0 !=
+        ( rInf.MaxHyph() = rAttrSet.GetHyphenZone().GetMaxHyphens() ) );
+    if ( bMaxHyph )
+        rLine.InitCntHyph();
+
+    if( IsFollow() && IsFieldFollow() && rLine.GetStart() == GetOfst() )
+    {
+        SwFldPortion* pRest = rLine.GetFieldRest( rInf );
+        if( pRest )
+        {
+            SwTxtFrm *pMaster = FindMaster();
+            ASSERT( pMaster, "SwTxtFrm::Format: homeless follow" );
+            const SwFldPortion *pFld = pMaster->GetRestPortion();
+            if( pFld )
+            {
+                pRest->TakeNextOffset( pFld );
+                rInf.SetRest( pRest );
+            }
+            else
+                delete pRest;
+        }
+        else
+            SetFieldFollow( sal_False );
+    }
+
+    /* Zum Abbruchkriterium:
+     * Um zu erkennen, dass eine Zeile nicht mehr auf die Seite passt,
+     * muss sie formatiert werden. Dieser Ueberhang wird z.B. in AdjustFollow
+     * wieder entfernt.
+     * Eine weitere Komplikation: wenn wir der Master sind, so muessen
+     * wir die Zeilen durchgehen, da es ja sein kann, dass eine Zeile
+     * vom Follow in den Master rutschen kann.
+     */
+    do
+    {
+        DBG_LOOP;
+        if( bFirst )
+            bFirst = sal_False;
+        else
+        {
+            if ( bMaxHyph )
+            {
+                if ( rLine.GetCurr()->IsEndHyph() )
+                    rLine.CntEndHyph()++;
+                else
+                    rLine.CntEndHyph() = 0;
+                if ( rLine.GetCurr()->IsMidHyph() )
+                    rLine.CntMidHyph()++;
+                else
+                    rLine.CntMidHyph() = 0;
+            }
+            if( !rLine.Next() )
+            {
+                if( !bFormat )
+                    rLine.MakeRestPortion();
+                rLine.Insert( new SwLineLayout() );
+                rLine.Next();
+                bFormat = sal_True;
+            }
+        }
+        if ( !bFormat && bMaxHyph &&
+              (bWatchEndHyph || bJumpEndHyph || bWatchMidHyph || bJumpMidHyph) )
+        {
+            if ( rLine.GetCurr()->IsEndHyph() )
+            {
+                if ( bWatchEndHyph )
+                    bFormat = ( rLine.CntEndHyph() == rInf.MaxHyph() );
+            }
+            else
+            {
+                bFormat = bJumpEndHyph;
+                bWatchEndHyph = sal_False;
+                bJumpEndHyph = sal_False;
+            }
+            if ( rLine.GetCurr()->IsMidHyph() )
+            {
+                if ( bWatchMidHyph && !bFormat )
+                    bFormat = ( rLine.CntEndHyph() == rInf.MaxHyph() );
+            }
+            else
+            {
+                bFormat = bFormat || bJumpMidHyph;
+                bWatchMidHyph = sal_False;
+                bJumpMidHyph = sal_False;
+            }
+        }
+        if( bFormat )
+        {
+            sal_Bool bOldEndHyph = rLine.GetCurr()->IsEndHyph();
+            sal_Bool bOldMidHyph = rLine.GetCurr()->IsMidHyph();
+            bFormat = FormatLine( rLine, bPrev );
+            //9334: Es kann nur ein bPrev geben... (???)
+            bPrev = sal_False;
+            if ( bMaxHyph )
+            {
+                if ( rLine.GetCurr()->IsEndHyph() != bOldEndHyph )
+                {
+                    bWatchEndHyph = !bOldEndHyph;
+                    bJumpEndHyph = bOldEndHyph;
+                }
+                if ( rLine.GetCurr()->IsMidHyph() != bOldMidHyph )
+                {
+                    bWatchMidHyph = !bOldMidHyph;
+                    bJumpMidHyph = bOldMidHyph;
+                }
+            }
+        }
+
+        if( !rInf.IsNewLine() )
+        {
+            if( !bFormat )
+                 bFormat = 0 != rInf.GetRest();
+            if( rInf.IsStop() || rInf.GetIdx() >= nStrLen )
+                break;
+            if( !bFormat && ( !bMaxHyph || ( !bWatchEndHyph &&
+                    !bJumpEndHyph && !bWatchMidHyph && !bJumpMidHyph ) ) )
+            {
+                if( GetFollow() )
+                {
+                    while( rLine.Next() )
+                        ; //Nothing
+                    pFreeze = new SwRepaint( rRepaint ); // to minimize painting
+                }
+                else
+                    break;
+            }
+        }
+        bBreak = aFrmBreak.IsBreakNow(rLine);
+    }while( !bBreak );
+
+    if( pFreeze )
+    {
+        rRepaint = *pFreeze;
+        delete pFreeze;
+    }
+
+    if( !rLine.IsStop() )
+    {
+        // Wurde aller Text formatiert und gibt es noch weitere
+        // Zeilenobjekte, dann sind diese jetzt ueberfluessig,
+        // weil der Text kuerzer geworden ist.
+        if( rLine.GetStart() + rLine.GetLength() >= nStrLen &&
+            rLine.GetCurr()->GetNext() )
+        {
+            rLine.TruncLines();
+            rLine.SetTruncLines( sal_True );
+        }
+    }
+
+    if( !rInf.IsTest() )
+    {
+        // Bei OnceMore lohnt sich kein FormatAdjust
+        if( bAdjust || !rLine.GetDropFmt() || !rLine.CalcOnceMore() )
+            FormatAdjust( rLine, aFrmBreak, nStrLen, rInf.IsStop() );
+        if( rRepaint.HasArea() )
+            SetRepaint();
+        rLine.SetTruncLines( sal_False );
+        if( nOldBottom )                    // Bei "gescollten" Absaetzen wird
+        {                                   // noch ueberprueft, ob durch Schrumpfen
+            rLine.Bottom();                 // das Scrolling ueberfluessig wurde.
+            SwTwips nNewBottom = rLine.Y();
+            if( nNewBottom < nOldBottom )
+                _SetOfst( 0 );
+        }
+    }
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::Format()
+ *************************************************************************/
+
+void SwTxtFrm::FormatOnceMore( SwTxtFormatter &rLine, SwTxtFormatInfo &rInf )
+{
+    SwParaPortion *pPara = rLine.GetInfo().GetParaPortion();
+    if( !pPara )
+        return;
+
+    // ggf gegen pPara
+    KSHORT nOld  = ((const SwTxtMargin&)rLine).GetDropHeight();
+    sal_Bool bShrink = sal_False,
+         bGrow   = sal_False,
+         bGoOn   = rLine.IsOnceMore();
+    sal_uInt8 nGo    = 0;
+    while( bGoOn )
+    {
+#ifdef DBGTXT
+        aDbstream << "OnceMore!" << endl;
+#endif
+        ++nGo;
+        rInf.Init();
+        rLine.Top();
+        if( !rLine.GetDropFmt() )
+            rLine.SetOnceMore( sal_False );
+        SwCharRange aRange( 0, rInf.GetTxt().Len() );
+        *(pPara->GetReformat()) = aRange;
+        _Format( rLine, rInf );
+
+        bGoOn = rLine.IsOnceMore();
+        if( bGoOn )
+        {
+            const KSHORT nNew = ((const SwTxtMargin&)rLine).GetDropHeight();
+            if( nOld == nNew )
+                bGoOn = sal_False;
+            else
+            {
+                if( nOld > nNew )
+                    bShrink = sal_True;
+                else
+                    bGrow = sal_True;
+
+                if( bShrink == bGrow || 5 < nGo )
+                    bGoOn = sal_False;
+
+                nOld = nNew;
+            }
+
+            // 6107: Wenn was schief ging, muss noch einmal formatiert werden.
+            if( !bGoOn )
+            {
+                rInf.CtorInit( this );
+                rLine.CtorInit( this, &rInf );
+                rLine.SetDropLines( 1 );
+                rLine.CalcDropHeight( 1 );
+                SwCharRange aRange( 0, rInf.GetTxt().Len() );
+                *(pPara->GetReformat()) = aRange;
+                _Format( rLine, rInf, sal_True );
+                // 8047: Wir painten alles...
+                SetCompletePaint();
+            }
+        }
+    }
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::_Format()
+ *************************************************************************/
+
+
+void SwTxtFrm::_Format( SwParaPortion *pPara )
+{
+    const xub_StrLen nStrLen = GetTxt().Len();
+
+    // AMA: Wozu soll das gut sein? Scheint mir zuoft zu einem kompletten
+    // Formatieren und Repainten zu fuehren???
+//  if ( !(*pPara->GetDelta()) )
+//      *(pPara->GetDelta()) = nStrLen;
+//  else
+    if ( !nStrLen )
+    {
+        // Leere Zeilen werden nicht lange gequaelt:
+        // pPara wird blank geputzt
+        // entspricht *pPara = SwParaPortion;
+        sal_Bool bMustFit = pPara->IsPrepMustFit();
+        pPara->Truncate();
+        pPara->FormatReset();
+        if( pBlink && pPara->IsBlinking() )
+            pBlink->Delete( pPara );
+        pPara->ResetFlags();
+        pPara->SetPrepMustFit( bMustFit );
+    }
+
+    SwTxtFormatInfo aInf( this );
+    SwTxtFormatter  aLine( this, &aInf );
+
+    _Format( aLine, aInf );
+
+    if( aLine.IsOnceMore() )
+        FormatOnceMore( aLine, aInf );
+
+    if( 1 < aLine.GetDropLines() )
+    {
+        if( SVX_ADJUST_LEFT != aLine.GetAdjust() &&
+            SVX_ADJUST_BLOCK != aLine.GetAdjust() )
+        {
+            aLine.CalcDropAdjust();
+            aLine.SetPaintDrop( sal_True );
+        }
+
+        if( aLine.IsPaintDrop() )
+        {
+            aLine.CalcDropRepaint();
+            aLine.SetPaintDrop( sal_False );
+        }
+    }
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::Format()
+ *************************************************************************/
+
+/*
+ * Format berechnet die Groesse des Textframes und ruft, wenn
+ * diese feststeht, Shrink() oder Grow(), um die Framegroesse dem
+ * evtl. veraenderten Platzbedarf anzupassen.
+ */
+
+void SwTxtFrm::Format( const SwBorderAttrs * )
+{
+    DBG_LOOP;
+#ifdef DEBUG
+    const XubString aXXX = GetTxtNode()->GetTxt();
+    const SwTwips nDbgY = Frm().Top();
+    const SwPageFrm *pDbgPage = FindPageFrm();
+    const MSHORT nDbgPageNr = pDbgPage->GetPhyPageNum();
+    // Um zu gucken, ob es einen Ftn-Bereich gibt.
+    const SwFrm *pDbgFtnCont = (const SwFrm*)(FindPageFrm()->FindFtnCont());
+
+#ifndef PRODUCT
+    // nStopAt laesst sich vom CV bearbeiten.
+    static MSHORT nStopAt = 0;
+    if( nStopAt == GetFrmId() )
+    {
+        int i = GetFrmId();
+    }
+#endif
+#endif
+
+#ifdef DEBUG_FTN
+    //Fussnote darf nicht auf einer Seite vor ihrer Referenz stehen.
+    if( IsInFtn() )
+    {
+        const SwFtnFrm *pFtn = (SwFtnFrm*)GetUpper();
+        const SwPageFrm *pFtnPage = pFtn->GetRef()->FindPageFrm();
+        const MSHORT nFtnPageNr = pFtnPage->GetPhyPageNum();
+        if( !IsLocked() )
+        {
+            if( nFtnPageNr > nDbgPageNr )
+            {
+                SwTxtFrmLocker aLock(this);
+                ASSERT( nFtnPageNr <= nDbgPageNr, "!Ftn steht vor der Referenz." );
+                MSHORT i = 0;
+            }
+        }
+    }
+#endif
+
+    MSHORT nRepeat = 0;
+    do
+    {
+        // Vom Berichtsautopiloten oder ueber die BASIC-Schnittstelle kommen
+        // gelegentlich TxtFrms mit einer Breite <=0.
+        if( Prt().Width() <= 0 )
+        {
+            // Wenn MustFit gesetzt ist, schrumpfen wir ggf. auf die Unterkante
+            // des Uppers, ansonsten nehmen wir einfach eine Standardgroesse
+            // von 12 Pt. ein (240 Twip).
+            SwTxtLineAccess aAccess( this );
+            if( aAccess.GetPara()->IsPrepMustFit() )
+            {
+                const SwTwips nMust = GetUpper()->Frm().Top()
+                                    + GetUpper()->Frm().Height();
+                const SwTwips nIs   = Frm().Top() + Frm().Height();
+                if( nIs > nMust )
+                    Shrink( nIs - nMust, pHeight );
+            }
+            else if( 240 < Frm().Height() )
+                Shrink( Frm().Height() - 240, pHeight );
+            else if( 240 > Frm().Height() )
+                Grow( 240 - Frm().Height(), pHeight );
+            if( Prt().Top() > Frm().Height() )
+                Prt().Top( Frm().Height() );
+            if( Prt().Height() < 0 )
+                Prt().Height( 0 );
+            return;
+        }
+        sal_Bool bChkAtCnt = sal_False;
+        const xub_StrLen nStrLen = GetTxtNode()->GetTxt().Len();
+        if ( nStrLen || !FormatEmpty() )
+        {
+
+            SetEmpty( sal_False );
+        // Um nicht durch verschachtelte Formats irritiert zu werden.
+            FormatLevel aLevel;
+            if( 12 == aLevel.GetLevel() )
+                return;
+
+            // Die Formatinformationen duerfen u.U. nicht veraendert werden.
+            if( IsLocked() )
+                return;
+
+            // Waehrend wir formatieren, wollen wir nicht gestoert werden.
+            SwTxtFrmLocker aLock(this);
+
+#ifdef DEBUG
+    //MA 25. Jan. 94 Das Flag stimmt sehr haufig beim Eintritt nicht. Das muss
+    //             bei naechster Gelegenheit geprueft und gefixt werden.
+            const sal_Bool bOldFtnFlag = HasFtn();
+            CalcFtnFlag();
+            if ( bOldFtnFlag != HasFtn() )
+                {int bla = 5;}
+#endif
+
+            // 8708: Vorsicht, das Format() kann auch durch GetFormatted()
+            // angestossen werden.
+            if( IsHiddenNow() )
+            {
+                if( Prt().Height() )
+                {
+                    HideHidden();
+                    Shrink( Prt().Height(), pHeight );
+                }
+                ChgThisLines();
+                return;
+            }
+
+            SwTxtLineAccess aAccess( this );
+            const sal_Bool bNew = !aAccess.SwTxtLineAccess::IsAvailable();
+
+            if( CalcPreps() )
+                ; // nothing
+            // Wir returnen, wenn schon formatiert wurde, nicht aber, wenn
+            // der TxtFrm gerade erzeugt wurde und ueberhaupt keine Format-
+            // informationen vorliegen.
+            else if( !bNew && !aAccess.GetPara()->GetReformat()->Len() )
+            {
+                if( GetTxtNode()->GetSwAttrSet().GetRegister().GetValue() )
+                {
+                    aAccess.GetPara()->SetPrepAdjust( sal_True );
+                    aAccess.GetPara()->SetPrep( sal_True );
+                    CalcPreps();
+                }
+                SetWidow( sal_False );
+            }
+            else if( GetOfst() && GetOfst() > GetTxtNode()->GetTxt().Len() )
+            {
+                SwTxtFrm *pMaster = FindMaster();
+                ASSERT( pMaster, "SwTxtFrm::Format: homeless follow" );
+                if( pMaster )
+                    pMaster->Prepare( PREP_FOLLOW_FOLLOWS );
+            }
+            else
+            {
+                const sal_Bool bOrphan = IsWidow();
+                _Format( aAccess.GetPara() );
+                if( bOrphan )
+                {
+                    ValidateFrm();
+                    SetWidow( sal_False );
+                }
+                bChkAtCnt = sal_True;
+            }
+            if( IsEmptyMaster() )
+            {
+                SwFrm* pPre = GetPrev();
+                if( pPre && pPre->GetAttrSet()->GetKeep().GetValue() )
+                    pPre->InvalidatePos();
+            }
+        }
+        MSHORT nMaxRepeat = 2;
+        if( bChkAtCnt && nRepeat < nMaxRepeat )
+        {
+            sal_Bool bRepeat = sal_False;
+            MSHORT nRepAdd = 0;
+            SwDrawObjs *pObjs;
+            SwTxtFrm *pMaster = IsFollow() ? FindMaster() : this;
+            if( pMaster )
+            {
+                if ( 0 != (pObjs = pMaster->GetDrawObjs()) )
+                {
+                    MSHORT nAutoCnt = 0;
+                    for ( int i = 0; i < int(pObjs->Count()); ++i )
+                    {
+                        SdrObject *pO = (*pObjs)[MSHORT(i)];
+                        if ( pO->IsWriterFlyFrame() )
+                        {
+                            SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+                            if( pFly->IsAutoPos() && !::IsInProgress( pFly ) )
+                            {
+                                ++nAutoCnt;
+                                ASSERT( pFly->IsFlyAtCntFrm(), "Not at content, but autopos.?" );
+                                ((SwFlyAtCntFrm*)pFly)->CheckCharRect();
+                                if( !pFly->IsValid() )
+                                {
+                                    SwTwips nOldTop = pFly->Frm().Top();
+                                    pFly->Calc();
+                                    bRepeat = sal_True;
+                                    if( !nRepAdd && nOldTop >= pFly->Frm().Top() )
+                                        nRepAdd = 1;
+                                }
+                            }
+                        }
+                    }
+                    if( nAutoCnt > 11 )
+                        nMaxRepeat = nAutoCnt/4;
+                }
+            }
+            if( bRepeat )
+                nRepeat += nRepAdd;
+            else
+                nRepeat = 0;
+        }
+        else
+            nRepeat = 0;
+    } while( nRepeat );
+
+    ChgThisLines();
+
+#ifdef DEBUG
+    // Hier ein Instrumentarium, um ungewoehnlichen Master/Follow-Kombinationen,
+    // insbesondere bei Fussnoten, auf die Schliche zu kommen
+    if( IsFollow() || GetFollow() )
+    {
+        SwTxtFrm *pTmpFrm = IsFollow() ? FindMaster() : this;
+        const SwPageFrm *pTmpPage = pTmpFrm->FindPageFrm();
+        MSHORT nPgNr = pTmpPage->GetPhyPageNum();
+        MSHORT nLast;
+        MSHORT nDummy = 0; // nur zum Breakpoint setzen
+        while( pTmpFrm->GetFollow() )
+        {
+            pTmpFrm = pTmpFrm->GetFollow();
+            nLast = nPgNr;
+            pTmpPage = pTmpFrm->FindPageFrm();
+            nPgNr = pTmpPage->GetPhyPageNum();
+            if( nLast > nPgNr )
+                ++nDummy; // schon fast eine Assertion wert
+            else if( nLast == nPgNr )
+                ++nDummy; // bei Spalten voellig normal, aber sonst!?
+            else if( nLast < nPgNr - 1 )
+                ++nDummy; // kann schon mal temporaer vorkommen
+        }
+    }
+#endif
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::FormatQuick()
+ *************************************************************************/
+// 6995:
+// return sal_False: Prepare(), HasPara(), InvalidateRanges(),
+
+sal_Bool SwTxtFrm::FormatQuick()
+{
+    DBG_LOOP;
+#ifdef DEBUG
+    const XubString aXXX = GetTxtNode()->GetTxt();
+    const SwTwips nDbgY = Frm().Top();
+#ifndef PRODUCT
+    // nStopAt laesst sich vom CV bearbeiten.
+    static MSHORT nStopAt = 0;
+    if( nStopAt == GetFrmId() )
+    {
+        int i = GetFrmId();
+    }
+#endif
+#endif
+
+    if( IsEmpty() && FormatEmpty() )
+        return sal_True;
+    // Wir sind sehr waehlerisch:
+    if( HasPara() || IsWidow() || IsLocked()
+        || !GetValidSizeFlag() || (Prt().Height() && IsHiddenNow()) )
+        return sal_False;
+
+    SwTxtLineAccess aAccess( this );
+    SwParaPortion *pPara = aAccess.GetPara();
+    if( !pPara )
+        return sal_False;
+
+    SwTxtFrmLocker aLock(this);
+    SwTxtFormatInfo aInf( this, sal_False, sal_True );
+    if( 0 != aInf.MaxHyph() )   // 27483: MaxHyphen beachten!
+        return sal_False;
+
+    SwTxtFormatter  aLine( this, &aInf );
+
+    // DropCaps sind zu kompliziert...
+    if( aLine.GetDropFmt() )
+        return sal_False;
+
+    xub_StrLen nStart = GetOfst();
+    const xub_StrLen nEnd = GetFollow()
+                      ? GetFollow()->GetOfst() : aInf.GetTxt().Len();
+    do
+    {   DBG_LOOP;
+        nStart = aLine.FormatLine( nStart );
+        if( aInf.IsNewLine() || (!aInf.IsStop() && nStart < nEnd) )
+            aLine.Insert( new SwLineLayout() );
+    } while( aLine.Next() );
+
+    // Last exit: die Hoehen muessen uebereinstimmen.
+    Point aTopLeft( Frm().Pos() );
+    aTopLeft += Prt().Pos();
+    const SwTwips nNewHeight = aLine.Y() + aLine.GetLineHeight();
+    const SwTwips nOldHeight = aTopLeft.Y() + Prt().Height();
+    if( nNewHeight != nOldHeight && !IsUndersized() )
+    {
+#ifdef DEBUG
+//  Achtung: Durch FormatLevel==12 kann diese Situation auftreten, don't panic!
+//      ASSERT( nNewHeight == nOldHeight, "!FormatQuick: rosebud" );
+#endif
+        xub_StrLen nStrt = GetOfst();
+        _InvalidateRange( SwCharRange( nStrt, nEnd - nStrt) );
+        return sal_False;
+    }
+
+    if( pFollow && nStart != ((SwTxtFrm*)pFollow)->GetOfst() )
+        return sal_False; // kann z.B. durch Orphans auftreten (35083,35081)
+
+    // Geschafft, wir sind durch ...
+
+    // Repaint setzen
+    pPara->GetRepaint()->Pos( aTopLeft );
+    pPara->GetRepaint()->SSize( Prt().SSize() );
+
+    // Reformat loeschen
+    *(pPara->GetReformat()) = SwCharRange();
+    *(pPara->GetDelta()) = 0;
+
+    return sal_True;
+}
+
+
diff --git a/sw/source/core/text/frminf.cxx b/sw/source/core/text/frminf.cxx
new file mode 100644
index 000000000000..444928fd9c68
--- /dev/null
+++ b/sw/source/core/text/frminf.cxx
@@ -0,0 +1,409 @@
+/*************************************************************************
+ *
+ *  $RCSfile: frminf.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:24 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _PAM_HXX
+#include           // GetSpaces
+#endif
+#ifndef _TXTCFG_HXX
+#include 
+#endif
+#ifndef _FRMINF_HXX
+#include        // SwTxtFrminfo
+#endif
+#ifndef _ITRTXT_HXX
+#include        // SwTxtMargin
+#endif
+#ifndef _SWFONT_HXX
+#include        // IsBullet()
+#endif
+
+
+/*************************************************************************
+ *                   SwTxtMargin::GetTxtStart()
+ *************************************************************************/
+
+xub_StrLen SwTxtMargin::GetTxtStart() const
+{
+    const XubString &rTxt = GetInfo().GetTxt();
+    const xub_StrLen nPos = nStart;
+    const xub_StrLen nEnd = nPos + pCurr->GetLen();
+    for( xub_StrLen i = nPos; i < nEnd; ++i )
+    {
+        const xub_Unicode aChar = rTxt.GetChar( i );
+        if( CH_TAB != aChar && ' ' != aChar )
+            return i;
+    }
+    return i;
+}
+
+/*************************************************************************
+ *                   SwTxtMargin::GetTxtEnd()
+ *************************************************************************/
+
+xub_StrLen SwTxtMargin::GetTxtEnd() const
+{
+    const XubString &rTxt = GetInfo().GetTxt();
+    const xub_StrLen nPos = nStart;
+    const xub_StrLen nEnd = nPos + pCurr->GetLen();
+    for( long i = nEnd - 1; i >= nPos; --i )
+    {
+        xub_Unicode aChar = rTxt.GetChar( i );
+        if( CH_TAB != aChar && CH_BREAK != aChar && ' ' != aChar )
+            return i + 1;
+    }
+    return i + 1;
+}
+
+/*************************************************************************
+ *                   SwTxtFrmInfo::IsOneLine()
+ *************************************************************************/
+
+// Passt der Absatz in eine Zeile?
+sal_Bool SwTxtFrmInfo::IsOneLine() const
+{
+    const SwLineLayout *pLay = pFrm->GetPara();
+    if( !pLay )
+        return sal_False;
+    else
+    {
+        // 6575: bei Follows natuerlich sal_False
+        if( pFrm->GetFollow() )
+            return sal_False;
+        pLay = pLay->GetNext();
+        while( pLay )
+        {
+            if( pLay->GetLen() )
+                return sal_False;
+            pLay = pLay->GetNext();
+        }
+        return sal_True;
+    }
+}
+
+/*************************************************************************
+ *                   SwTxtFrmInfo::IsFilled()
+ *************************************************************************/
+
+// Ist die Zeile zu X% gefuellt?
+sal_Bool SwTxtFrmInfo::IsFilled( const sal_uInt8 nPercent ) const
+{
+    const SwLineLayout *pLay = pFrm->GetPara();
+    if( !pLay )
+        return sal_False;
+    else
+    {
+        long nWidth = pFrm->Prt().Width();
+        nWidth *= nPercent;
+        nWidth /= 100;
+        return KSHORT(nWidth) <= pLay->Width();
+    }
+}
+
+/*************************************************************************
+ *                   SwTxtFrmInfo::GetLineStart()
+ *************************************************************************/
+
+// Wo beginnt der Text (ohne whitespaces)? ( Dokument global )
+SwTwips SwTxtFrmInfo::GetLineStart( const SwTxtCursor &rLine ) const
+{
+    SwTwips nTxtStart = rLine.GetTxtStart();
+    SwTwips nStart;
+    if( rLine.GetStart() == nTxtStart )
+        nStart = rLine.GetLineStart();
+    else
+    {
+        SwRect aRect;
+        if( ((SwTxtCursor&)rLine).GetCharRect( &aRect, nTxtStart ) )
+            nStart = aRect.Left();
+        else
+            nStart = rLine.GetLineStart();
+    }
+    return nStart;
+}
+
+
+/*************************************************************************
+ *                   SwTxtFrmInfo::GetLineStart()
+ *************************************************************************/
+
+// Wo beginnt der Text (ohne whitespaces)? (rel. im Frame)
+SwTwips SwTxtFrmInfo::GetLineStart() const
+{
+    SwTxtSizeInfo aInf( (SwTxtFrm*)pFrm );
+    SwTxtCursor aLine( (SwTxtFrm*)pFrm, &aInf );
+    return GetLineStart( aLine ) - pFrm->Frm().Left() - pFrm->Prt().Left();
+}
+
+// errechne die Position des Zeichens und gebe die Mittelposition zurueck
+SwTwips SwTxtFrmInfo::GetCharPos( xub_StrLen nChar, sal_Bool bCenter ) const
+{
+    SwTxtSizeInfo aInf( (SwTxtFrm*)pFrm );
+    SwTxtCursor aLine( (SwTxtFrm*)pFrm, &aInf );
+
+    SwTwips nStt, nNext;
+    SwRect aRect;
+    if( ((SwTxtCursor&)aLine).GetCharRect( &aRect, nChar ) )
+        nStt = aRect.Left();
+    else
+        nStt = aLine.GetLineStart();
+
+    if( !bCenter )
+        return nStt - pFrm->Frm().Left();
+
+    if( ((SwTxtCursor&)aLine).GetCharRect( &aRect, nChar+1 ) )
+        nNext = aRect.Left();
+    else
+        nNext = aLine.GetLineStart();
+
+    return (( nNext + nStt ) / 2 ) - pFrm->Frm().Left();
+}
+
+/*************************************************************************
+ *                   SwTxtFrmInfo::GetSpaces()
+ *************************************************************************/
+
+SwPaM *AddPam( SwPaM *pPam, const SwTxtFrm* pTxtFrm,
+                const xub_StrLen nPos, const xub_StrLen nLen )
+{
+    if( nLen )
+    {
+        // Es koennte auch der erste sein.
+        if( pPam->HasMark() )
+        {
+            // liegt die neue Position genau hinter der aktuellen, dann
+            // erweiter den Pam einfach
+            if( nPos == pPam->GetPoint()->nContent.GetIndex() )
+            {
+                pPam->GetPoint()->nContent += nLen;
+                return pPam;
+            }
+            pPam = new SwPaM( *pPam );
+        }
+
+        SwIndex &rContent = pPam->GetPoint()->nContent;
+        rContent.Assign( (SwTxtNode*)pTxtFrm->GetTxtNode(), nPos );
+        pPam->SetMark();
+        rContent += nLen;
+    }
+    return pPam;
+}
+
+// Sammelt die whitespaces am Zeilenbeginn und -ende im Pam
+void SwTxtFrmInfo::GetSpaces( SwPaM &rPam, sal_Bool bWithLineBreak ) const
+{
+    SwTxtSizeInfo aInf( (SwTxtFrm*)pFrm );
+    SwTxtMargin aLine( (SwTxtFrm*)pFrm, &aInf );
+    SwPaM *pPam = &rPam;
+    sal_Bool bFirstLine = sal_True;
+    do {
+
+        if( aLine.GetCurr()->GetLen() )
+        {
+            xub_StrLen nPos = aLine.GetTxtStart();
+            // Bug 49649: von der ersten Line die Blanks/Tabs NICHT
+            //              mit selektieren
+            if( !bFirstLine && nPos > aLine.GetStart() )
+                pPam = AddPam( pPam, pFrm, aLine.GetStart(),
+                                nPos - aLine.GetStart() );
+
+            // Bug 49649: von der letzten Line die Blanks/Tabs NICHT
+            //              mit selektieren
+            if( aLine.GetNext() )
+            {
+                nPos = aLine.GetTxtEnd();
+
+                if( nPos < aLine.GetEnd() )
+                {
+                    MSHORT nOff = !bWithLineBreak && CH_BREAK ==
+                                aLine.GetInfo().GetChar( aLine.GetEnd() - 1 )
+                                ? 1 : 0;
+                    pPam = AddPam( pPam, pFrm, nPos, aLine.GetEnd() - nPos - nOff );
+                }
+            }
+        }
+        bFirstLine = sal_False;
+    }
+    while( aLine.Next() );
+}
+
+/*************************************************************************
+ *                   SwTxtFrmInfo::IsBullet()
+ *************************************************************************/
+
+// Ist an der Textposition ein Bullet/Symbol etc?
+// Fonts: CharSet, SYMBOL und DONTKNOW
+sal_Bool SwTxtFrmInfo::IsBullet( xub_StrLen nTxtStart ) const
+{
+    SwTxtSizeInfo aInf( (SwTxtFrm*)pFrm );
+    SwTxtMargin aLine( (SwTxtFrm*)pFrm, &aInf );
+    aInf.SetIdx( nTxtStart );
+    return aLine.IsSymbol( nTxtStart );
+}
+
+/*************************************************************************
+ *                   SwTxtFrmInfo::GetFirstIndent()
+ *************************************************************************/
+
+// Ermittelt Erstzeileneinzug
+// Voraussetzung fuer pos. oder neg. EZE ist, dass alle
+// Zeilen ausser der ersten Zeile den selben linken Rand haben.
+// Wir wollen nicht so knauserig sein und arbeiten mit einer Toleranz
+// von TOLERANCE Twips.
+
+#define TOLERANCE 20
+
+SwTwips SwTxtFrmInfo::GetFirstIndent() const
+{
+    SwTxtSizeInfo aInf( (SwTxtFrm*)pFrm );
+    SwTxtCursor aLine( (SwTxtFrm*)pFrm, &aInf );
+    const SwTwips nFirst = GetLineStart( aLine );
+    if( !aLine.Next() )
+        return 0;
+
+    SwTwips nLeft = GetLineStart( aLine );
+    while( aLine.Next() )
+    {
+        if( aLine.GetCurr()->GetLen() )
+        {
+            const SwTwips nCurrLeft = GetLineStart( aLine );
+            if( nLeft + TOLERANCE < nCurrLeft ||
+                nLeft - TOLERANCE > nCurrLeft )
+                return 0;
+        }
+    }
+
+    // Vorerst wird nur +1, -1 und 0 returnt.
+    if( nLeft == nFirst )
+        return 0;
+    else
+        if( nLeft > nFirst )
+            return -1;
+        else
+            return +1;
+}
+
+/*************************************************************************
+ *                   SwTxtFrmInfo::GetBigIndent()
+ *************************************************************************/
+
+KSHORT SwTxtFrmInfo::GetBigIndent( xub_StrLen& rFndPos,
+                                    const SwTxtFrm *pNextFrm ) const
+{
+    SwTxtSizeInfo aInf( (SwTxtFrm*)pFrm );
+    SwTxtCursor aLine( (SwTxtFrm*)pFrm, &aInf );
+    SwTwips nNextIndent = 0;
+
+    if( pNextFrm )
+    {
+        // ich bin einzeilig
+        SwTxtSizeInfo aNxtInf( (SwTxtFrm*)pNextFrm );
+        SwTxtCursor aNxtLine( (SwTxtFrm*)pNextFrm, &aNxtInf );
+        nNextIndent = GetLineStart( aNxtLine );
+    }
+    else
+    {
+        // ich bin mehrzeilig
+        if( aLine.Next() )
+        {
+            nNextIndent = GetLineStart( aLine );
+            aLine.Prev();
+        }
+    }
+
+    if( nNextIndent <= GetLineStart( aLine ) )
+        return 0;
+
+    const Point aPoint( nNextIndent, aLine.Y() );
+    rFndPos = aLine.GetCrsrOfst( 0, aPoint, sal_False );
+    if( 1 >= rFndPos )
+        return 0;
+
+    // steht vor einem "nicht Space"
+    const XubString& rTxt = aInf.GetTxt();
+    xub_Unicode aChar = rTxt.GetChar( rFndPos );
+    if( CH_TAB == aChar || CH_BREAK == aChar || ' ' == aChar ||
+        (( CH_TXTATR_BREAKWORD == aChar || CH_TXTATR_INWORD == aChar ) &&
+            aInf.HasHint( rFndPos ) ) )
+        return 0;
+
+    // und hinter einem "Space"
+    aChar = rTxt.GetChar( rFndPos - 1 );
+    if( CH_TAB != aChar && CH_BREAK != aChar &&
+        ( ( CH_TXTATR_BREAKWORD != aChar && CH_TXTATR_INWORD != aChar ) ||
+            !aInf.HasHint( rFndPos - 1 ) ) &&
+        // mehr als 2 Blanks !!
+        ( ' ' != aChar || ' ' != rTxt.GetChar( rFndPos - 2 ) ) )
+        return 0;
+
+    SwRect aRect;
+    return aLine.GetCharRect( &aRect, rFndPos )
+            ? KSHORT( aRect.Left() - pFrm->Frm().Left() - pFrm->Prt().Left())
+            : 0;
+}
+
+
+
diff --git a/sw/source/core/text/frmpaint.cxx b/sw/source/core/text/frmpaint.cxx
new file mode 100644
index 000000000000..964d5a73bdb9
--- /dev/null
+++ b/sw/source/core/text/frmpaint.cxx
@@ -0,0 +1,738 @@
+/*************************************************************************
+ *
+ *  $RCSfile: frmpaint.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:24 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _SV_SOUND_HXX //autogen
+#include 
+#endif
+#ifndef _SV_SYSTEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _SHL_HXX
+#include  // SW_MOD
+#endif
+
+#ifndef _FMTLINE_HXX
+#include 
+#endif
+#ifndef _LINEINFO_HXX
+#include 
+#endif
+#ifndef _CHARFMT_HXX
+#include 
+#endif
+#ifndef _PAGEFRM_HXX
+#include 
+#endif
+#ifndef _VIEWSH_HXX
+#include    // ViewShell
+#endif
+#ifndef _VIEWIMP_HXX
+#include   // SwViewImp
+#endif
+#ifndef _VIEWOPT_HXX
+#include   // SwViewOption
+#endif
+#ifndef _FRMTOOL_HXX
+#include   // DrawGraphic
+#endif
+#ifndef _FRMSH_HXX
+#include 
+#endif
+#ifndef _TXTCFG_HXX
+#include 
+#endif
+#ifndef _TXTFRM_HXX
+#include        // SwTxtFrm
+#endif
+#ifndef _ITRPAINT_HXX
+#include      // SwTxtPainter
+#endif
+#ifndef _TXTPAINT_HXX
+#include      // SwSaveClip
+#endif
+#ifndef _TXTCACHE_HXX
+#include  // SwTxtLineAccess
+#endif
+#ifndef _SWFNTCCH_HXX
+#include  // SwFontAccess
+#endif
+#ifndef _DRAWFONT_HXX
+#include  // SwDrawTextInfo
+#endif
+#ifndef _FLYFRM_HXX
+#include    // SwFlyFrm
+#endif
+#ifndef _REDLNITR_HXX
+#include  // SwRedlineItr
+#endif
+#ifndef _DOC_HXX
+#include       // SwDoc
+#endif
+#ifndef _SWMODULE_HXX
+#include  // SW_MOD
+#endif
+#ifndef _TABFRM_HXX
+#include    // SwTabFrm (Redlining)
+#endif
+#include "scrrect.hxx"
+
+// steht im number.cxx
+extern const sal_Char __FAR_DATA sBulletFntName[];
+
+extern FASTBOOL bOneBeepOnly;
+
+sal_Bool bInitFont = sal_True;
+
+#define REDLINE_DISTANCE 567/4
+#define REDLINE_MINDIST  567/10
+
+class SwExtraPainter
+{
+    SwSaveClip aClip;
+    SwRect aRect;
+    ViewShell *pSh;
+    SwFont* pFnt;
+    const SwLineNumberInfo &rLineInf;
+    SwTwips nX;
+    SwTwips nRedX;
+    ULONG nLineNr;
+    MSHORT nDivider;
+    sal_Bool bGoLeft;
+    sal_Bool bLineNum;
+    inline sal_Bool IsClipChg() { return aClip.IsChg(); }
+public:
+    SwExtraPainter( const SwTxtFrm *pFrm, ViewShell *pVwSh,
+        const SwLineNumberInfo &rLnInf, const SwRect &rRct, MSHORT nStart,
+        SwHoriOrient eHor, sal_Bool bLnNm );
+    ~SwExtraPainter() { delete pFnt; }
+    inline SwFont* GetFont() const { return pFnt; }
+    inline void IncLineNr() { ++nLineNr; }
+    inline sal_Bool HasNumber() { return !( nLineNr % rLineInf.GetCountBy() ); }
+    inline HasDivider() { if( !nDivider ) return sal_False;
+        return !(nLineNr % rLineInf.GetDividerCountBy()); }
+
+    void PaintExtra( SwTwips nY, long nAsc, long nMax, sal_Bool bRed );
+    void PaintRedline( SwTwips nY, long nMax );
+};
+
+
+SwExtraPainter::SwExtraPainter( const SwTxtFrm *pFrm, ViewShell *pVwSh,
+    const SwLineNumberInfo &rLnInf, const SwRect &rRct, MSHORT nStart,
+    SwHoriOrient eHor, sal_Bool bLnNm )
+    : pSh( pVwSh ), pFnt( 0 ), rLineInf( rLnInf ), aRect( rRct ),
+      aClip( pVwSh->GetWin() || pFrm->IsUndersized() ? pVwSh->GetOut() : 0 ),
+      nLineNr( 1L ), bLineNum( bLnNm )
+{
+    if( pFrm->IsUndersized() )
+    {
+        SwTwips nBottom = pFrm->Frm().Bottom();
+        if( aRect.Bottom() > nBottom )
+            aRect.Bottom( nBottom );
+    }
+    MSHORT nVirtPageNum = 0;
+    if( bLineNum )
+    {   /* initialisiert die Member, die bei Zeilennumerierung notwendig sind:
+
+            nDivider,   wie oft ist ein Teilerstring gewuenscht, 0 == nie;
+            nX,         X-Position der Zeilennummern;
+            pFnt,       der Font der Zeilennummern;
+            nLineNr,    die erste Zeilennummer;
+        bLineNum wird ggf.wieder auf sal_False gesetzt, wenn die Numerierung sich
+        komplett ausserhalb des Paint-Rechtecks aufhaelt. */
+        nDivider = rLineInf.GetDivider().Len() ? rLineInf.GetDividerCountBy() : 0;
+        nX = pFrm->Frm().Left();
+        SwCharFmt* pFmt = rLineInf.GetCharFmt( *((SwDoc*)pFrm->GetNode()->GetDoc()) );
+        ASSERT( pFmt, "PaintExtraData without CharFmt" );
+        pFnt = new SwFont( &pFmt->GetAttrSet() );
+        pFnt->Invalidate();
+        pFnt->ChgPhysFnt( pSh, pSh->GetOut() );
+        nLineNr += pFrm->GetAllLines() - pFrm->GetThisLines();
+        LineNumberPosition ePos = rLineInf.GetPos();
+        if( ePos != LINENUMBER_POS_LEFT && ePos != LINENUMBER_POS_RIGHT )
+        {
+            nVirtPageNum = pFrm->FindPageFrm()->GetVirtPageNum();
+            if( nVirtPageNum % 2 )
+                ePos = ePos == LINENUMBER_POS_INSIDE ?
+                        LINENUMBER_POS_LEFT : LINENUMBER_POS_RIGHT;
+            else
+                ePos = ePos == LINENUMBER_POS_OUTSIDE ?
+                        LINENUMBER_POS_LEFT : LINENUMBER_POS_RIGHT;
+        }
+        if( LINENUMBER_POS_LEFT == ePos )
+        {
+            bGoLeft = sal_True;
+            nX -= rLineInf.GetPosFromLeft();
+            if( nX < aRect.Left() )
+                bLineNum = sal_False;
+        }
+        else
+        {
+            bGoLeft = sal_False;
+            nX += pFrm->Frm().Width() + rLineInf.GetPosFromLeft();
+            if( nX > aRect.Right() )
+                bLineNum = sal_False;
+        }
+    }
+    if( eHor != HORI_NONE )
+    {
+        if( HORI_INSIDE == eHor || HORI_OUTSIDE == eHor )
+        {
+            if( !nVirtPageNum )
+                nVirtPageNum = pFrm->FindPageFrm()->GetVirtPageNum();
+            if( nVirtPageNum % 2 )
+                eHor = eHor == HORI_INSIDE ? HORI_LEFT : HORI_RIGHT;
+            else
+                eHor = eHor == HORI_OUTSIDE ? HORI_LEFT : HORI_RIGHT;
+        }
+        const SwFrm* pTmpFrm = pFrm->FindTabFrm();
+        if( !pTmpFrm )
+            pTmpFrm = pFrm;
+        nRedX = HORI_LEFT == eHor ? pTmpFrm->Frm().Left() - REDLINE_DISTANCE :
+            pTmpFrm->Frm().Right() + REDLINE_DISTANCE;
+    }
+}
+
+/*************************************************************************
+ * SwExtraPainter::PaintExtra()
+ **************************************************************************/
+
+void SwExtraPainter::PaintExtra( SwTwips nY, long nAsc, long nMax, sal_Bool bRed )
+{
+    //Zeilennummer ist staerker als der Teiler
+    XubString aTmp( HasNumber() ? rLineInf.GetNumType().GetNumStr( nLineNr )
+                                : rLineInf.GetDivider() );
+
+    SwDrawTextInfo aDrawInf( pSh, *pSh->GetOut(), aTmp, 0, aTmp.Len(), 0, sal_False );
+    aDrawInf.SetSpace( 0 );
+    aDrawInf.SetWrong( NULL );
+    aDrawInf.SetLeft( 0 );
+    aDrawInf.SetRight( LONG_MAX );
+    sal_Bool bTooBig = pFnt->GetSize( pFnt->GetActual() ).Height() > nMax &&
+                pFnt->GetHeight( pSh, pSh->GetOut() ) > nMax;
+    SwFont* pTmpFnt;
+    if( bTooBig )
+    {
+        pTmpFnt = new SwFont( *GetFont() );
+        if( nMax >= 20 )
+        {
+            nMax *= 17;
+            nMax /= 20;
+        }
+        pTmpFnt->SetSize( Size( 0, nMax ), pTmpFnt->GetActual() );
+    }
+    else
+        pTmpFnt = GetFont();
+    Point aTmpPos( nX, nY + nAsc );
+    if( !IsClipChg() )
+    {
+        Size aSize = pTmpFnt->_GetTxtSize( pSh, pSh->GetOut(), aTmp );
+        if( bGoLeft )
+            aTmpPos.X() -= aSize.Width();
+        SwRect aRct( aTmpPos, aSize );
+        if( !aRect.IsInside( aRct ) && !aRct.Intersection( aRect ).IsEmpty() )
+            aClip.ChgClip( aRect );
+    }
+    else if( bGoLeft )
+        aTmpPos.X() -= pTmpFnt->_GetTxtSize( pSh, pSh->GetOut(), aTmp ).Width();
+    aDrawInf.SetPos( aTmpPos );
+    pTmpFnt->_DrawText( aDrawInf );
+    if( bTooBig )
+        delete pTmpFnt;
+    if( bRed )
+    {
+        long nDiff = bGoLeft ? nRedX - nX : nX - nRedX;
+        if( nDiff > REDLINE_MINDIST )
+            PaintRedline( nY, nMax );
+    }
+}
+
+void SwExtraPainter::PaintRedline( SwTwips nY, long nMax )
+{
+    Point aStart( nRedX, nY );
+    Point aEnd( nRedX, nY + nMax );
+    if( !IsClipChg() )
+    {
+        SwRect aRct( aStart, aEnd );
+        if( !aRect.IsInside( aRct ) && !aRct.Intersection( aRect ).IsEmpty() )
+            aClip.ChgClip( aRect );
+    }
+    const Color aOldCol( pSh->GetOut()->GetLineColor() );
+    pSh->GetOut()->SetLineColor( SW_MOD()->GetRedlineMarkColor() );
+    pSh->GetOut()->DrawLine( aStart, aEnd );
+    pSh->GetOut()->SetLineColor( aOldCol );
+}
+
+void SwTxtFrm::PaintExtraData( const SwRect &rRect ) const
+{
+    if( Frm().Top() > rRect.Bottom() || Frm().Bottom() < rRect.Top() )
+        return;
+    const SwTxtNode& rTxtNode = *GetTxtNode();
+    const SwLineNumberInfo &rLineInf = rTxtNode.GetDoc()->GetLineNumberInfo();
+    const SwFmtLineNumber &rLineNum = GetAttrSet()->GetLineNumber();
+    sal_Bool bLineNum = !IsInTab() && rLineInf.IsPaintLineNumbers() &&
+               ( !IsInFly() || rLineInf.IsCountInFlys() ) && rLineNum.IsCount();
+    SwHoriOrient eHor = (SwHoriOrient)SW_MOD()->GetRedlineMarkPos();
+    sal_Bool bRedLine = eHor != HORI_NONE;
+    if ( bLineNum || bRedLine )
+    {
+        if( IsLocked() || IsHiddenNow() || !Prt().Height() )
+            return;
+        ViewShell *pSh = GetShell();
+        SwExtraPainter aExtra( this, pSh, rLineInf, rRect,
+            rLineNum.GetStartValue(), eHor, bLineNum );
+
+        if( HasPara() )
+        {
+            SwTxtFrmLocker aLock((SwTxtFrm*)this);
+
+            SwTxtLineAccess aAccess( (SwTxtFrm*)this );
+            SwParaPortion *pPara = aAccess.GetPara();
+
+            OutputDevice *pOldRef = pSh->GetReferenzDevice();
+            pSh->SetReferenzDevice( NULL );
+            SwTxtPaintInfo aInf( (SwTxtFrm*)this, rRect );
+            pSh->SetReferenzDevice( pOldRef );
+
+            SwTxtPainter  aLine( (SwTxtFrm*)this, &aInf );
+            sal_Bool bNoDummy = !aLine.GetNext(); // Nur eine Leerzeile!
+
+            while( aLine.Y() + aLine.GetLineHeight() <= rRect.Top() )
+            {
+                if( !aLine.GetCurr()->IsDummy() &&
+                    ( rLineInf.IsCountBlankLines() ||
+                      aLine.GetCurr()->HasCntnt() ) )
+                    aExtra.IncLineNr();
+                if( !aLine.Next() )
+                    return;
+            }
+
+            long nBottom = rRect.Bottom();
+
+            sal_Bool bNoPrtLine;
+            if( !( bNoPrtLine = 0 == GetMinPrtLine() ) )
+            {
+                while ( aLine.Y() < GetMinPrtLine() )
+                {
+                    if( ( rLineInf.IsCountBlankLines() || aLine.GetCurr()->HasCntnt() )
+                        && !aLine.GetCurr()->IsDummy() )
+                        aExtra.IncLineNr();
+                    if( !aLine.Next() )
+                        break;
+                }
+                bNoPrtLine = aLine.Y() >= GetMinPrtLine();
+            }
+            if( bNoPrtLine )
+            {
+                do
+                {
+                    if( bNoDummy || !aLine.GetCurr()->IsDummy() )
+                    {
+                        sal_Bool bRed = bRedLine && aLine.GetCurr()->HasRedline();
+                        if( rLineInf.IsCountBlankLines() || aLine.GetCurr()->HasCntnt() )
+                        {
+                            if( bLineNum &&
+                                ( aExtra.HasNumber() || aExtra.HasDivider() ) )
+                            {
+                                KSHORT nTmpHeight, nTmpAscent;
+                                aLine.CalcAscentAndHeight( nTmpAscent, nTmpHeight );
+                                aExtra.PaintExtra( aLine.Y(), nTmpAscent,
+                                    nTmpHeight, bRed );
+                                bRed = sal_False;
+                            }
+                            aExtra.IncLineNr();
+                        }
+                        if( bRed )
+                            aExtra.PaintRedline( aLine.Y(), aLine.GetLineHeight() );
+                    }
+                } while( aLine.Next() && aLine.Y() <= nBottom );
+            }
+        }
+        else
+        {
+            bRedLine &= (MSHRT_MAX!=rTxtNode.GetDoc()->GetRedlinePos(rTxtNode));
+
+            if( bLineNum && rLineInf.IsCountBlankLines() &&
+                ( aExtra.HasNumber() || aExtra.HasDivider() ) )
+            {
+                aExtra.PaintExtra( Frm().Top()+Prt().Top(), aExtra.GetFont()
+                    ->GetAscent( pSh, pSh->GetOut() ), Prt().Height(), bRedLine );
+            }
+            else if( bRedLine )
+                aExtra.PaintRedline( Frm().Top()+Prt().Top(), Prt().Height() );
+        }
+    }
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::Paint()
+ *************************************************************************/
+
+SwRect SwTxtFrm::Paint()
+{
+#ifdef DEBUG
+    const SwTwips nDbgY = Frm().Top();
+#endif
+
+    // finger layout
+    ASSERT( GetValidPosFlag(), "+SwTxtFrm::Paint: no Calc()" );
+
+    SwRect aRet( Prt() );
+    if ( IsEmpty() || !HasPara() )
+        aRet += Frm().Pos();
+    else
+    {
+        // AMA: Wir liefern jetzt mal das richtige Repaintrechteck zurueck,
+        //      d.h. als linken Rand den berechneten PaintOfst!
+        SwRepaint *pRepaint = GetPara()->GetRepaint();
+        long l;
+        if( pRepaint->GetOfst() )
+        {
+            pRepaint->Left( pRepaint->GetOfst() );
+            pRepaint->SetOfst( 0 );
+            l = pRepaint->GetRightOfst();
+            if ( l && l < pRepaint->Right() )
+                 pRepaint->Right( l );
+        }
+        l = Frm().Bottom();
+        if ( pRepaint->Bottom() > l )
+            pRepaint->Bottom( l );
+        aRet = *pRepaint;
+    }
+    ResetRepaint();
+    return aRet;
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::Paint()
+ *************************************************************************/
+
+sal_Bool SwTxtFrm::PaintEmpty( const SwRect &rRect, sal_Bool bCheck ) const
+{
+    ViewShell *pSh = GetShell();
+    if( pSh && ( pSh->GetViewOptions()->IsParagraph() || bInitFont ) )
+    {
+        bInitFont = sal_False;
+        SwTxtFly aTxtFly( this );
+        aTxtFly.SetTopRule();
+        SwRect aRect;
+        if( bCheck && aTxtFly.IsOn() && aTxtFly.IsAnyObj( aRect ) )
+            return sal_False;
+        else if( OUTDEV_PRINTER != pSh->GetOut()->GetOutDevType() )
+        {
+            SwFont *pFnt;
+            const SwTxtNode& rTxtNode = *GetTxtNode();
+            if ( rTxtNode.HasSwAttrSet() )
+            {
+                const SwAttrSet *pAttrSet = &( rTxtNode.GetSwAttrSet() );
+                pFnt = new SwFont( pAttrSet );
+            }
+            else
+            {
+//FEATURE::CONDCOLL
+//                  SwFontAccess aFontAccess( GetTxtNode()->GetFmtColl() );
+                SwFontAccess aFontAccess( &rTxtNode.GetAnyFmtColl(), pSh );
+//FEATURE::CONDCOLL
+                pFnt = new SwFont( *aFontAccess.Get()->GetFont() );
+            }
+
+            const SwDoc* pDoc = rTxtNode.GetDoc();
+            if( ::IsShowChanges( pDoc->GetRedlineMode() ) )
+            {
+                MSHORT nRedlPos = pDoc->GetRedlinePos( rTxtNode );
+                if( MSHRT_MAX != nRedlPos )
+                    SwRedlineItr aRedln( rTxtNode, *pFnt, nRedlPos, sal_True );
+            }
+
+            if( pSh->GetViewOptions()->IsParagraph() && Prt().Height() )
+            {
+                const sal_Bool bAlter =
+                    ( RTL_TEXTENCODING_SYMBOL == pFnt->GetCharSet( SW_LATIN ) )
+#if defined( PM2 )
+                            || ( System::GetCharSet() != CHARSET_IBMPC_850 )
+#endif
+                    ;
+
+                if( bAlter && COMPARE_EQUAL !=
+                    pFnt->GetName( SW_LATIN ).CompareToAscii( sBulletFntName ) )
+                {
+                    pFnt->SetFamily( FAMILY_DONTKNOW, SW_LATIN );
+                    pFnt->SetName( XubString( sBulletFntName,
+                        RTL_TEXTENCODING_MS_1252 ), SW_LATIN );
+                    pFnt->SetStyleName( aEmptyStr, SW_LATIN );
+                    pFnt->SetCharSet( RTL_TEXTENCODING_SYMBOL, SW_LATIN );
+                }
+                pFnt->Invalidate();
+                pFnt->ChgPhysFnt( pSh, pSh->GetOut() );
+                Point aPos = Frm().Pos() + Prt().Pos();
+                SwSaveClip *pClip;
+                if( IsUndersized() )
+                {
+                    pClip = new SwSaveClip( pSh->GetOut() );
+                    pClip->ChgClip( rRect );
+                }
+                else
+                    pClip = NULL;
+                aPos.Y() += pFnt->GetAscent( pSh, pSh->GetOut() );
+                const XubString aTmp( sal_Char( bAlter ? CH_PAR_ALTER : CH_PAR ),
+                    RTL_TEXTENCODING_MS_1252 );
+                SwDrawTextInfo aDrawInf( pSh, *pSh->GetOut(), aTmp, 0, 1, 0,
+                                            sal_False );
+                aDrawInf.SetLeft( rRect.Left() );
+                aDrawInf.SetRight( rRect.Right() );
+                aDrawInf.SetPos( aPos );
+                aDrawInf.SetSpace( 0 );
+                aDrawInf.SetWrong( NULL );
+                pFnt->_DrawText( aDrawInf );
+                delete pClip;
+            }
+            delete pFnt;
+            return sal_True;
+        }
+    }
+    else
+        return sal_True;
+    return sal_False;
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::Paint()
+ *************************************************************************/
+
+void SwTxtFrm::Paint(const SwRect &rRect ) const
+{
+    ResetRepaint();
+    DBG_LOOP_RESET;
+    if( !IsEmpty() || !PaintEmpty( rRect, sal_True ) )
+    {
+#ifdef DEBUG
+        const SwTwips nDbgY = Frm().Top();
+#endif
+
+#ifdef DBGTXT
+        if( IsDbg( this ) )
+            DBTXTFRM << "Paint()" << endl;
+#endif
+        if( IsLocked() || IsHiddenNow() || !Prt().Height() )
+            return;
+
+        //Kann gut sein, dass mir der IdleCollector mir die gecachten
+        //Informationen entzogen hat.
+        if( !HasPara() )
+        {
+            ASSERT( GetValidPosFlag(), "+SwTxtFrm::Paint: no Calc()" );
+            ((SwTxtFrm*)this)->GetFormatted();
+            if( IsEmpty() )
+            {
+                PaintEmpty( rRect, sal_False );
+                return;
+            }
+            if( !HasPara() )
+            {
+                ASSERT( !this, "+SwTxtFrm::Paint: missing format information" );
+                return;
+            }
+        }
+
+        // Waehrend wir painten, wollen wir nicht gestoert werden.
+        // Aber erst hinter dem Format() !
+        SwTxtFrmLocker aLock((SwTxtFrm*)this);
+
+        //Hier wird ggf. nur der Teil des TxtFrm ausgegeben, der sich veraendert
+        //hat und der in dem Bereich liegt, dessen Ausgabe angefordert wurde.
+        //Man kann jetzt auf die Idee kommen, dass der Bereich rRect ausgegeben
+        //werden _muss_ obwohl rRepaint gesetzt ist; in der Tat kann dieses
+        //Problem nicht formal vermieden werden. Gluecklicherweise koennen
+        //wir davon ausgehen, dass rRepaint immer dann leer ist, wenn der Frm
+        //komplett gepainted werden muss.
+        SwTxtLineAccess aAccess( (SwTxtFrm*)this );
+        SwParaPortion *pPara = aAccess.GetPara();
+
+        SwRepaint &rRepaint = *(pPara->GetRepaint());
+
+        // Das Recycling muss abgeschaltet werden, wenn wir uns im
+        // FlyCntFrm befinden, weil ein DrawRect fuer die Retusche der
+        // Zeile aufgerufen wird.
+        if( rRepaint.GetOfst() )
+        {
+            const SwFlyFrm *pFly = FindFlyFrm();
+            if( pFly && pFly->IsFlyInCntFrm() )
+                rRepaint.SetOfst( 0 );
+        }
+
+        // Hier holen wir uns den String fuer die Ausgabe, besonders
+        // die Laenge ist immer wieder interessant.
+
+        ViewShell *pSh = GetShell();
+        OutputDevice *pOldRef = pSh->GetReferenzDevice();
+        pSh->SetReferenzDevice( NULL );
+        SwTxtPaintInfo aInf( (SwTxtFrm*)this, rRect );
+        pSh->SetReferenzDevice( pOldRef );
+        aInf.SetWrongList( ( (SwTxtNode*)GetTxtNode() )->GetWrong() );
+        aInf.GetTxtFly()->SetTopRule();
+
+        SwTxtPainter  aLine( (SwTxtFrm*)this, &aInf );
+        // Eine Optimierung, die sich lohnt: wenn kein freifliegender Frame
+        // in unsere Zeile ragt, schaltet sich der SwTxtFly einfach ab:
+        aInf.GetTxtFly()->Relax();
+
+        OutputDevice *pOut = aInf.GetOut();
+        const sal_Bool bOnWin = pSh->GetWin() != 0;
+
+        SwSaveClip aClip( bOnWin || IsUndersized() ? pOut : 0 );
+
+        // Ausgabeschleife: Fuer jede Zeile ... (die noch zu sehen ist) ...
+        // rRect muss angepasst werden (Top+1, Bottom-1), weil der Iterator
+        // die Zeilen nahtlos aneinanderfuegt.
+        aLine.TwipsToLine( rRect.Top() + 1 );
+        long nBottom = rRect.Bottom();
+
+        sal_Bool bNoPrtLine;
+        if( !( bNoPrtLine = 0 == GetMinPrtLine() ) )
+        {
+            while ( aLine.Y() < GetMinPrtLine() && aLine.Next() )
+                ;
+            bNoPrtLine = aLine.Y() >= GetMinPrtLine();
+        }
+        if( bNoPrtLine )
+        {
+            do
+            {   DBG_LOOP;
+                aLine.DrawTextLine( rRect, aClip, IsUndersized() );
+
+            } while( aLine.Next() && aLine.Y() <= nBottom );
+        }
+
+        // Einmal reicht:
+        if( aLine.IsPaintDrop() )
+        {
+#if NIE
+            if( !bRetouche )
+            {
+                const SvxBrushItem *pItem; SwRect aOrigRect;
+                GetBackgroundBrush( pItem, aOrigRect, sal_False, sal_True );
+                aInf.SetBack( pItem, aOrigRect );
+            }
+#endif
+            aLine.PaintDropPortion();
+        }
+
+#ifdef USED
+        if( pSh && pSh->GetViewOptions()->IsTest2() )
+            aInf.GetTxtFly()->ShowContour( pOut );
+#endif
+
+        // "Beep"
+        if( bOneBeepOnly && bOnWin &&
+            Frm().Top() + Prt().Top() + Prt().Height() < aLine.Y() &&
+            ( GetFollow() || IsFollow() || GetNext() ) )
+        {
+            bOneBeepOnly = sal_False;
+            Sound::Beep();
+        }
+        if( rRepaint.HasArea() )
+            rRepaint.Clear();
+    }
+}
+
+void SwTxtFrm::CriticalLines( const OutputDevice& rOut, SwStripes &rStripes,
+    long nOffs)
+{
+    GetFormatted();
+    if( HasPara() )
+    {
+        SwStripe aStripe( Frm().Top(), Prt().Top() );
+        if( Prt().Top() )
+        {
+            rStripes.Insert( aStripe, rStripes.Count() );
+            aStripe.Y() += Prt().Top();
+        }
+        SwLineLayout* pLay = GetPara();
+        do
+        {
+            SwTwips nBase = aStripe.GetY() + pLay->GetAscent();
+            if( rOut.LogicToPixel( Point( 0, nBase ) ).Y() !=
+                rOut.LogicToPixel( Point( 0, nBase - nOffs ) ).Y() +
+                rOut.LogicToPixel( Size( 0, nOffs ) ).Height() )
+            {
+                aStripe.Height() = pLay->GetRealHeight();
+                rStripes.Insert( aStripe, rStripes.Count() );
+            }
+            aStripe.Y() += pLay->GetRealHeight();
+            pLay = pLay->GetNext();
+        } while( pLay );
+        if( Prt().Top() + Prt().Height() < Frm().Height() )
+        {
+            aStripe.Height() = Frm().Height() - Prt().Top() - Prt().Height();
+            rStripes.Insert( aStripe, rStripes.Count() );
+        }
+    }
+    else if( Frm().Height() )
+        rStripes.Insert(SwStripe(Frm().Top(),Frm().Height()), rStripes.Count());
+}
+
+
diff --git a/sw/source/core/text/guess.cxx b/sw/source/core/text/guess.cxx
new file mode 100644
index 000000000000..83f3420666ec
--- /dev/null
+++ b/sw/source/core/text/guess.cxx
@@ -0,0 +1,492 @@
+/*************************************************************************
+ *
+ *  $RCSfile: guess.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include 
+
+#include "errhdl.hxx"   // ASSERTs
+#include "segmentc.hxx"
+
+#include "txtcfg.hxx"
+#include "guess.hxx"
+#include "inftxt.hxx"   // SwTxtSizeInfo, SwTxtFormatInfo
+#include "swfont.hxx"
+#include "breakit.hxx"
+#include "viewsh.hxx"
+
+#ifndef _COM_SUN_STAR_TEXT_BREAKTYPE_HPP_
+#include 
+#endif
+
+#ifndef _WORDSEL_HXX //autogen
+#include 
+#endif
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::linguistic;
+
+inline sal_Bool IsDelim( const xub_Unicode cCh )
+{
+    return ' ' == cCh;
+}
+
+/*************************************************************************
+ *                      SwTxtGuess::IsWordEnd
+ *************************************************************************/
+
+
+sal_Bool SwTxtGuess::IsWordEnd( const SwTxtSizeInfo &rInf, const xub_StrLen nPos )
+{
+    const xub_StrLen nEnd = rInf.GetIdx() + rInf.GetLen();
+
+    ASSERT( nPos <= nEnd, "WordEnd hinter Text?" );
+
+    // Das letzte Zeichen gilt immer als Wortende
+    if ( nPos >= nEnd )
+        return sal_True;
+
+    const XubString& rTxt = rInf.GetTxt();
+    xub_Unicode aChr = rTxt.GetChar( nPos );
+    xub_Unicode aChr1 = rTxt.GetChar( nPos + 1 );
+
+    // Bindestriche sind potentielle Wortenden mit folgenden Ausnahmen:
+    // es folgt ein weiterer Bindestrich
+    // es folgt Textmasse, vor dem Bindestrich sind nur Bindestriche und
+    // davor ein Blank ...
+    if( '-' == aChr )
+    {
+        if ( IsDelim( aChr1 ) )
+            return sal_True;
+        if ( !nPos || '-' == aChr1 )
+            return sal_False;
+        for ( xub_StrLen nCnt = nPos; nCnt && '-' == aChr; )
+            aChr = rTxt.GetChar( --nCnt );
+        return ( !IsDelim( aChr ) && '-' != aChr );
+    }
+
+    // sal_True, wenn nPos kein Blank ist, aber der darauffolgende
+    if( !IsDelim( aChr ) && IsDelim( aChr1 ) )
+        return sal_True;
+    else
+        return sal_False;
+}
+
+
+/*************************************************************************
+ *                      _GetFwdWordEnd()
+ *
+ * Es wird die letzte Position im Wort zurueckgeliefert:
+ * Aus "123 456" wird "123" nicht "123 " !!!
+ * Sonderfaelle bei "-"
+ *************************************************************************/
+
+xub_StrLen _GetFwdWordEnd( const XubString& rTxt, xub_StrLen nFound,
+                           const xub_StrLen nMaxPos )
+{
+    if( nFound == nMaxPos )
+        return nMaxPos;
+
+    // Suche von links nach rechts
+    // Die Spaces vor einem Wort gehoeren dazu:
+    for( ++nFound; nFound < nMaxPos && IsDelim( rTxt.GetChar( nFound ) ); ++nFound )
+        ;
+
+    if ( nFound == nMaxPos )
+        return nMaxPos;
+
+    // Sonderfall: Bindestrich
+    if ( '-' == rTxt.GetChar( nFound ) )
+    {
+        // Mal gucken, was vor den Bindestrichen los ist
+        for ( ; nFound && '-' == rTxt.GetChar( nFound ); --nFound )
+            ;
+        // Ist vor uns ein Wortteil oder Nichts?
+        const sal_Bool bPartOfWord = nFound && !IsDelim( rTxt.GetChar( nFound ) );
+        // Und wieder hinter die Bindestriche
+        for ( ++nFound; nFound && '-' == rTxt.GetChar( nFound ); ++nFound )
+            ;
+        if ( nFound > nMaxPos )
+            return nMaxPos;
+        if ( bPartOfWord || IsDelim( rTxt.GetChar( nFound ) ) )
+            return nFound - 1;
+    }
+
+    // Beim naechsten Space ist Schluss
+    for( ; nFound < nMaxPos; ++nFound )
+    {
+         if( IsDelim( rTxt.GetChar( nFound ) ) )
+            return nFound - 1;
+         if( '-' == rTxt.GetChar( nFound ) )
+         {
+            while ( '-' == rTxt.GetChar( nFound ) )
+                ++nFound;
+            if ( nFound > nMaxPos )
+                return nMaxPos;
+            else
+                return nFound - 1;
+        }
+    }
+    return nFound;
+}
+
+/*************************************************************************
+ *                      _GetBwdWordEnd()
+ *
+ * Es wird die letzte Position im Wort zurueckgeliefert:
+ * Aus "123 456" wird "123" nicht "123 " !!!
+ * Sonderfaelle bei "-"
+ *************************************************************************/
+
+xub_StrLen _GetBwdWordEnd( const XubString& rTxt, xub_StrLen nFound,
+                           const xub_StrLen nMin )
+{
+    const xub_StrLen nStart = nFound;
+    if( !nFound )
+        return 0;
+
+    // Suche von rechts nach links
+    // Bloede Striche
+    for( ; nFound && '-' == rTxt.GetChar( nFound ); --nFound )
+        ;
+
+    // Bis zum Anfang der Textmasse.
+    for( ; nFound && !IsDelim( rTxt.GetChar( nFound ) ); --nFound )
+    {
+        if( '-' == rTxt.GetChar(nFound) && !ispunct( rTxt.GetChar(nFound+1) ) )
+            break;
+    }
+
+    if ( '-' == rTxt.GetChar( nFound ) )
+    {
+        xub_StrLen nOldFound = nFound;
+        // Mal gucken, was vor den Bindestrichen los ist
+        for ( ; nFound && '-' == rTxt.GetChar( nFound ); --nFound )
+            ;
+        // Ist vor uns ein Wortteil?
+        if( nFound && !IsDelim( rTxt.GetChar( nFound ) ) )
+            return nOldFound;
+    }
+
+    // Die Spaces hinter einem Wort gehoeren nicht dazu:
+    for( ; nFound > nMin; --nFound )
+    {
+        if( !IsDelim( rTxt.GetChar( nFound ) ) )
+            break;
+    }
+    if( nMin == nFound )
+    {
+        if( IsDelim( rTxt.GetChar( nFound ) ) )
+        {
+            while( ++nFound < nStart && IsDelim( rTxt.GetChar( nFound ) ) )
+                ;
+            --nFound;
+        }
+        else if( nMin )
+            --nFound;
+    }
+
+    return nFound;
+}
+
+/*************************************************************************
+ *                      SwTxtGuess::GetWordEnd
+ *************************************************************************/
+
+// Liefert die Wortgrenze je nach Suchrichtung zurueck.
+// Wortdelimitter sind (nach dem letzten Projekt-Parteitag) nur
+// noch Blanks.
+// Fuehrende Blanks gehoeren zum Wort, aus "XXX   YYY" wird
+// "XXX" und "   YYY".
+
+xub_StrLen SwTxtGuess::GetWordEnd( const SwTxtFormatInfo &rInf,
+                                const xub_StrLen nPos, const sal_Bool bFwd ) const
+{
+    const xub_StrLen nMaxPos = rInf.GetIdx() + rInf.GetLen() - 1;
+    const xub_StrLen nIdx = nPos < nMaxPos ? nPos : nMaxPos;
+    return  bFwd ? _GetFwdWordEnd( rInf.GetTxt(), nIdx, nMaxPos )
+                 : _GetBwdWordEnd( rInf.GetTxt(), nIdx, rInf.GetLineStart() );
+}
+
+/*************************************************************************
+ *                      SwTxtGuess::Guess
+ *
+ * Nach Guess muessen folgende Verhaeltnisse vorliegen:
+ * Bsp: "XXX   YYY", Umbruch beim 2.Space
+ * GetLeftPos() liefert das Ende des noch passenden Wortes: "XXX", 3
+ * GetRightPos() liefert den Beginn des nicht mehr passenden Wortes: " YYY"
+ * Wenn das Wort ganz passte, dann ist GetLeftPos() == GetRightPos().
+ * Etwas Verwirrung stiftet der Unterschied zwischen Position und Laenge:
+ * GetWord() arbeitet ausschliesslich mit String-Positionen, waehrend
+ * die Breiten per GetTxtSize() und damit ueber Laengen ermittelt werden.
+ * Die Laenge ist (nach Abzug des Offsets) immer genau um 1 groesser
+ * als die Position.
+ * Liefert zurueck, ob es noch passte...
+ *************************************************************************/
+
+sal_Bool SwTxtGuess::Guess( const SwTxtFormatInfo &rInf, const KSHORT nPorHeight )
+{
+    nLeftPos = nRightPos = rInf.GetIdx();
+    // Leere Strings sind immer 0
+    if( !rInf.GetLen() || !rInf.GetTxt().Len() )
+    {
+        nHeight = rInf.GetTxtHeight();
+        return sal_False;
+    }
+    ASSERT( rInf.GetIdx() < rInf.GetTxt().Len(),
+            "+SwTxtGuess::Guess: invalid SwTxtFormatInfo" );
+
+    nHeight = nPorHeight;
+
+    KSHORT nLineWidth = rInf.Width() - rInf.X();
+    const xub_StrLen nMaxLen = Min( xub_StrLen(rInf.GetTxt().Len() - rInf.GetIdx()),
+                                rInf.GetLen() );
+    // Sonderfall: Zeichen breiter als Zeile
+    if( !nMaxLen || !nLineWidth )
+    {
+        nHeight = rInf.GetTxtHeight();
+        return sal_False;
+    }
+
+    if( !nHeight )
+    {
+        ASSERT( nHeight, "+SwTxtGuess::Guess: no height" );
+        nHeight = rInf.GetTxtHeight();
+        if( !nHeight )
+            nHeight = 1;
+    }
+
+    KSHORT nItalic = 0;
+    if( ITALIC_NONE != rInf.GetFont()->GetItalic() && !rInf.NotEOL() )
+    {
+#ifdef DEBUG
+        static MSHORT nDiv = 12;
+        nItalic = nHeight / nDiv;
+#else
+#ifdef MAC
+        nItalic = nHeight / 4;
+#else
+        nItalic = nHeight / 12;
+#endif
+#endif
+        if( nItalic >= nLineWidth )
+        {
+            nLeftWidth = nRightWidth = nItalic;
+            nLeftPos = nRightPos = rInf.GetIdx();
+            return sal_False;
+        }
+        else
+            nLineWidth -= nItalic;
+    }
+
+    // Kein GetTextBreak, wenn vermutlich alles passt
+    if ( long ( nLineWidth ) * 2 > long ( nMaxLen ) * nHeight )
+    {
+        nLeftWidth = rInf.GetTxtSize( rInf.GetIdx(), nMaxLen ).Width();
+
+        if ( nLeftWidth <= nLineWidth )
+        {
+            // Die Vermutung hat sich bewahrheitet
+            nLeftPos = nRightPos = rInf.GetIdx() + nMaxLen - 1;
+            nHeight = rInf.GetTxtHeight();
+            if( nItalic && ( nLeftPos + 1 ) >= rInf.GetTxt().Len() )
+                nLeftWidth += nItalic;
+            nRightWidth = nLeftWidth;
+            return sal_True;
+        }
+#ifdef DEBUG
+        nRightWidth = nLeftWidth; // nur zum Breakpoint setzen,
+                                  // Vermutung schlug fehl, teuer!
+#endif
+    }
+
+    nHeight = rInf.GetTxtHeight();
+
+    sal_Bool bHyph = rInf.IsHyphenate() && !rInf.IsHyphForbud();
+    xub_StrLen nHyphPos = 0;
+
+    if( bHyph )
+        nRightPos = rInf.GetTxtBreak( nLineWidth, rInf.GetIdx(), nMaxLen,
+                                       nHyphPos );
+    else
+        nRightPos = rInf.GetTxtBreak( nLineWidth, rInf.GetIdx(), nMaxLen );
+
+    if( nRightPos > rInf.GetIdx() + nMaxLen )
+    {
+        // passt noch auf die Zeile
+        nLeftPos = nRightPos = rInf.GetIdx() + nMaxLen - 1;
+        if( bHyph )
+            nHyphPos = nLeftPos;
+        nLeftWidth = nRightWidth =
+            rInf.GetTxtSize( rInf.GetIdx(), nMaxLen ).Width();
+        // Der folgende Vergleich sollte eigenlich immer sal_True ergeben, sonst
+        // hat es wohl bei GetTxtBreak einen Pixel-Rundungsfehler gegeben...
+        if ( nLeftWidth <= nLineWidth )
+        {
+            if( nItalic && ( nLeftPos + 1 ) >= rInf.GetTxt().Len() )
+            {
+                nLeftWidth += nItalic;
+                nRightWidth = nLeftWidth;
+            }
+            return sal_True;
+        }
+    }
+
+    if( IsDelim( rInf.GetChar( nRightPos ) ) )
+    {
+        nLeftPos = nRightPos;
+        while( nRightPos && IsDelim( rInf.GetChar( --nRightPos ) ) )
+            --nLeftPos;
+    }
+    else
+    {
+        nLeftPos = nRightPos;
+        if( pBreakIt->xBreak.is() )
+        {
+            LineBreakHyphenationOptions aHyphOpt;
+            Reference< XHyphenator >  xHyph;
+            if( bHyph )
+            {
+                xHyph = rInf.GetVsh() ? rInf.GetVsh()->GetHyphenator()
+                                      : ::GetHyphenator();
+                aHyphOpt = LineBreakHyphenationOptions( xHyph, nHyphPos );
+            }
+            LineBreakResults aResult = pBreakIt->xBreak->getLineBreak( rInf.GetTxt(),
+                nRightPos, pBreakIt->GetLocale( rInf.GetFont()->GetLanguage() ),
+                rInf.GetIdx(), aHyphOpt, LineBreakUserOptions() );
+            nLeftPos = aResult.breakIndex;
+            if( nLeftPos == STRING_LEN )
+                nLeftPos = 0;
+            bHyph = aResult.breakType == BreakType::HYPHENATION;
+            if( bHyph )
+                xHyphWord = aResult.rHyphenatedWord;
+            else
+                xHyphWord = NULL;
+
+            if( nLeftPos )
+            {
+#ifdef DEBUG
+                static BOOL bTest = FALSE;
+                if( bTest && bHyph && nHyphPos )
+                {
+                    WordSelection::ResetWordDelimiter();
+                    xub_StrLen nWrdStart = WordSelection::GoStartWord( rInf.GetTxt(), nHyphPos );
+                    xub_StrLen nLen = WordSelection::GoEndWord( rInf.GetTxt(), nWrdStart ) - nWrdStart;
+                    if( nLen )
+
+                    {
+                        XubString aSelTxt( rInf.GetTxt().Copy(nWrdStart, nLen) );
+                        MSHORT nMinTrail = 0;
+                        if( nWrdStart + nLen > nHyphPos )
+                            nMinTrail = nWrdStart + nLen - nHyphPos - 1;
+                        xHyphWord = ((SwTxtFormatInfo&)rInf).HyphWord( aSelTxt, nMinTrail );
+                        if( xHyphWord.is() )
+                            nHyphPos = xHyphWord->getHyphenationPos() + nWrdStart;
+                    }
+                }
+                else
+#endif
+                {
+                    xub_StrLen nX = nLeftPos;
+                    while( nX && IsDelim( rInf.GetChar( --nX ) ) )
+                        nLeftPos = nX;
+                }
+            }
+        }
+    }
+    // nLeftPos = GetPrevEnd( rInf, nRightPos ); OLD_ITERATOR
+
+    if ( nLeftPos < rInf.GetIdx() )
+        nLeftPos = rInf.GetIdx();
+
+    if( !SwTxtGuess::IsWordEnd( rInf, nRightPos ) )
+        nRightPos = GetNextEnd( rInf, nRightPos );
+
+    nLeftWidth =
+    rInf.GetTxtSize( rInf.GetIdx(), nLeftPos - rInf.GetIdx() ).Width();
+    // OLD_ITERATOR
+    // rInf.GetTxtSize( rInf.GetIdx(), nLeftPos - rInf.GetIdx() + 1 ).Width();
+
+    bHyph = bHyph && ( nHyphPos > nLeftPos );
+
+    // Sicher ist sicher, robust gg. Rundungfehler in GetTxtBreak ...
+    if ( nLeftWidth > nLineWidth )
+    {
+        rInf.GetTxtSize( rInf.GetIdx(), nLeftPos - rInf.GetIdx() + 1 ).Width();
+        bHyph = sal_False;
+        nLeftPos = GetPrevEnd( rInf, nLeftPos );
+        if ( nLeftPos < rInf.GetIdx() )
+            nLeftPos = rInf.GetIdx();
+        nRightPos = GetNextEnd( rInf, nLeftPos );
+        nLeftWidth =
+            rInf.GetTxtSize( rInf.GetIdx(), nLeftPos - rInf.GetIdx() + 1 ).Width();
+    }
+    nLeftWidth += nItalic;
+    nRightWidth = nLeftWidth;
+    return sal_False;
+}
+
+
diff --git a/sw/source/core/text/guess.hxx b/sw/source/core/text/guess.hxx
new file mode 100644
index 000000000000..32a13fb09ce2
--- /dev/null
+++ b/sw/source/core/text/guess.hxx
@@ -0,0 +1,123 @@
+/*************************************************************************
+ *
+ *  $RCSfile: guess.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _GUESS_HXX
+#define _GUESS_HXX
+
+#ifndef _SOLAR_H
+#include 
+#endif
+#ifndef _STRING_HXX //autogen
+#include 
+#endif
+#ifndef _COM_SUN_STAR_LINGUISTIC_XHYPHENATEDWORD_HPP_
+#include 
+#endif
+
+#include "txttypes.hxx"
+#include "breakit.hxx"
+
+class SwTxtSizeInfo;
+class SwTxtFormatInfo;
+
+using namespace ::com::sun::star;
+
+/*************************************************************************
+ *                      class SwTxtGuess
+ *************************************************************************/
+
+class SwTxtGuess
+{
+    uno::Reference< linguistic::XHyphenatedWord >  xHyphWord;
+    xub_StrLen nLeftPos;        // untere Kante: Idx
+    xub_StrLen nRightPos;       // obere  Kante: Idx
+    KSHORT nLeftWidth;          // untere Kante: Width
+    KSHORT nRightWidth;         // obere  Kante: Width
+    KSHORT nHeight;             // die GetTxtSize()-Hoehe.
+    xub_StrLen GetWordEnd( const SwTxtFormatInfo &rInf,
+                        const xub_StrLen nPos, const sal_Bool bFwd = sal_True ) const;
+public:
+    inline SwTxtGuess(): nLeftPos(0), nLeftWidth(0), nRightPos(0),
+                         nRightWidth(0), nHeight(0)
+
+        { }
+
+    // liefert zuerueck, ob es noch passte
+    sal_Bool Guess( const SwTxtFormatInfo &rInf, const KSHORT nHeight );
+
+    inline xub_StrLen LeftPos() const { return nLeftPos; }
+    inline KSHORT LeftWidth() const { return nLeftWidth; }
+    inline xub_StrLen RightPos() const { return nRightPos; }
+    inline KSHORT RightWidth() const { return nRightWidth; }
+    inline KSHORT Height() const { return nHeight; }
+    inline uno::Reference< linguistic::XHyphenatedWord > HyphWord() const
+        { return xHyphWord; }
+
+    inline xub_StrLen GetPrevEnd( const SwTxtFormatInfo &rInf,
+                                  const xub_StrLen nPos ) const
+        { return GetWordEnd( rInf, nPos, sal_False ); }
+    inline xub_StrLen GetNextEnd( const SwTxtFormatInfo &rInf,
+                                  const xub_StrLen nPos ) const
+        { return GetWordEnd( rInf, nPos, sal_True ); }
+    static sal_Bool IsWordEnd( const SwTxtSizeInfo &rInf, const xub_StrLen nPos );
+};
+
+
+#endif
diff --git a/sw/source/core/text/inftxt.cxx b/sw/source/core/text/inftxt.cxx
new file mode 100644
index 000000000000..54572000cdc6
--- /dev/null
+++ b/sw/source/core/text/inftxt.cxx
@@ -0,0 +1,1176 @@
+/*************************************************************************
+ *
+ *  $RCSfile: inftxt.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _SFX_PRINTER_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_HYZNITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_ESCPITEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _SVX_SPLWRAP_HXX
+#include 
+#endif
+#ifndef _OFF_APP_HXX
+#include 
+#endif
+#ifndef _LINGU_LNGPROPS_HHX_
+#include 
+#endif
+#ifndef _UNO_LINGU_HXX
+#include 
+#endif
+
+#ifndef _TXATBASE_HXX //autogen
+#include 
+#endif
+#ifndef _FMTINFMT_HXX //autogen
+#include 
+#endif
+#ifndef _SWMODULE_HXX //autogen
+#include 
+#endif
+#ifndef _SV_SVAPP_HXX //autogen
+#include 
+#endif
+#ifndef _SV_WRKWIN_HXX //autogen
+#include 
+#endif
+#ifndef _SHL_HXX //autogen
+#include 
+#endif
+#ifndef _SV_SYSTEM_HXX //autogen
+#include 
+#endif
+#ifndef _VIEWSH_HXX
+#include    // ViewShell
+#endif
+#ifndef _VIEWOPT_HXX
+#include   // SwViewOptions
+#endif
+#ifndef _FRMTOOL_HXX
+#include   // DrawGraphic
+#endif
+#ifndef _DOC_HXX
+#include       // SwDoc
+#endif
+#ifndef _PARATR_HXX
+#include    // SwFmtDrop
+#endif
+#ifndef _ROOTFRM_HXX
+#include   // SwRootFrm
+#endif
+#ifndef _INFTXT_HXX
+#include    // SwTxtInfo
+#endif
+#ifndef _SWFONT_HXX
+#include    // SwFont
+#endif
+#ifndef _TXTFLY_HXX
+#include    // SwTxtPaintInfo
+#endif
+#ifndef _BLINK_HXX
+#include     // SwBlink
+#endif
+#ifndef _NOTEURL_HXX
+#include   // SwNoteURL
+#endif
+#ifndef _DRAWFONT_HXX
+#include  // SwDrawTextInfo
+#endif
+#ifndef _PORFTN_HXX
+#include    // SwFtnPortion
+#endif
+#ifndef _FRMSH_HXX
+#include 
+#endif
+
+using namespace ::com::sun::star;
+#define C2U(cChar) rtl::OUString::createFromAscii(cChar)
+
+// steht im number.cxx
+extern const sal_Char __FAR_DATA sBulletFntName[];
+
+extern void MA_FASTCALL SwAlignRect( SwRect &rRect, ViewShell *pSh );
+
+#ifndef PRODUCT
+// Test2: WYSIWYG++
+// Test4: WYSIWYG debug
+static sal_Bool bDbgLow = sal_False;
+#endif
+
+#ifndef PRODUCT
+
+sal_Bool SwTxtSizeInfo::IsOptCalm() const { return !GetOpt().IsTest3(); }
+
+sal_Bool SwTxtSizeInfo::IsOptLow() const { return bDbgLow; }
+
+sal_Bool SwTxtSizeInfo::IsOptDbg() const { return GetOpt().IsTest4(); }
+
+sal_Bool SwTxtSizeInfo::IsOptTest1() const { return GetOpt().IsTest1(); }
+
+sal_Bool SwTxtSizeInfo::IsOptTest2() const { return GetOpt().IsTest2(); }
+
+sal_Bool SwTxtSizeInfo::IsOptTest3() const { return GetOpt().IsTest3(); }
+
+sal_Bool SwTxtSizeInfo::IsOptTest4() const { return GetOpt().IsTest4(); }
+
+sal_Bool SwTxtSizeInfo::IsOptTest5() const { return GetOpt().IsTest5(); }
+
+sal_Bool SwTxtSizeInfo::IsOptTest6() const { return GetOpt().IsTest6(); }
+
+sal_Bool SwTxtSizeInfo::IsOptTest7() const { return GetOpt().IsTest7(); }
+
+sal_Bool SwTxtSizeInfo::IsOptTest8() const { return GetOpt().IsTest8(); }
+
+#endif
+
+/*************************************************************************
+ *                      SwLineInfo::SwLineInfo()
+ *************************************************************************/
+
+void SwLineInfo::CtorInit( const SwAttrSet& rAttrSet )
+{
+    pRuler = &rAttrSet.GetTabStops();
+    pSpace = &rAttrSet.GetLineSpacing();
+    nDefTabStop = MSHRT_MAX;
+}
+
+/*************************************************************************
+ *                      SwTxtInfo::CtorInit()
+ *************************************************************************/
+
+void SwTxtInfo::CtorInit( SwTxtFrm *pFrm )
+{
+    pPara = pFrm->GetPara();
+    nTxtStart = pFrm->GetOfst();
+    if( !pPara )
+    {
+        ASSERT( pPara, "+SwTxtInfo::CTOR: missing paragraph information" );
+        pFrm->Format();
+        pPara = pFrm->GetPara();
+    }
+}
+
+SwTxtInfo::SwTxtInfo( const SwTxtInfo &rInf )
+    : pPara( ((SwTxtInfo&)rInf).GetParaPortion() ),
+      nTxtStart( rInf.GetTxtStart() )
+{ }
+
+#ifndef PRODUCT
+/*************************************************************************
+ *                      ChkOutDev()
+ *************************************************************************/
+// Sonderbehandlung: wenn pVsh->GetPrt() null ist, ist alles erlaubt
+
+void ChkOutDev( const SwTxtSizeInfo &rInf )
+{
+    const OutputDevice *pOut = rInf.GetOut();
+    const OutputDevice *pWin = rInf.GetWin();
+    const OutputDevice *pPrt = rInf.GetPrt();
+    ASSERT( pOut &&
+            ( !(rInf.GetVsh() && rInf.GetVsh()->GetPrt()) ||
+              (!pWin || OUTDEV_WINDOW  == pWin->GetOutDevType()
+                     || OUTDEV_VIRDEV  == pWin->GetOutDevType() ) &&
+              (!pPrt || pPrt == pWin || OUTDEV_PRINTER == pPrt->GetOutDevType())
+                     || ( OUTDEV_VIRDEV == pOut->GetOutDevType() ) ),
+            "ChkOutDev: invalid output device" );
+}
+#endif  // PRODUCT
+
+inline xub_StrLen GetMinLen( const SwTxtSizeInfo &rInf )
+{
+    const xub_StrLen nInfLen = rInf.GetIdx() + rInf.GetLen();
+    return Min( rInf.GetTxt().Len(), nInfLen );
+}
+
+SwTxtSizeInfo::SwTxtSizeInfo( const SwTxtSizeInfo &rNew )
+    : SwTxtInfo( rNew ),
+      pVsh(((SwTxtSizeInfo&)rNew).GetVsh()),
+      pOut(((SwTxtSizeInfo&)rNew).GetOut()),
+      pWin(((SwTxtSizeInfo&)rNew).GetWin()),
+      pPrt(((SwTxtSizeInfo&)rNew).GetPrt()),
+      pFnt(((SwTxtSizeInfo&)rNew).GetFont()),
+      pFrm(rNew.pFrm),
+      pOpt(&rNew.GetOpt()),
+      pTxt(&rNew.GetTxt()),
+      nIdx(rNew.GetIdx()),
+      nLen(rNew.GetLen()),
+      bOnWin( rNew.OnWin() ),
+      bNotEOL( rNew.NotEOL() ),
+      bURLNotify( rNew.URLNotify() ),
+      bStopUnderFlow( rNew.StopUnderFlow() )
+{
+#ifndef PRODUCT
+    ChkOutDev( *this );
+#endif
+}
+
+void SwTxtSizeInfo::_SelectOut()
+{
+    ASSERT( pVsh, "Where's my ViewShell?" );
+    pOut = pVsh->GetOut();
+    if( bOnWin )
+        pWin = pOut;
+}
+
+void SwTxtSizeInfo::CtorInit( SwTxtFrm *pFrame, SwFont *pNewFnt,
+                   const xub_StrLen nNewIdx, const xub_StrLen nNewLen )
+{
+    pFrm = pFrame;
+    SwTxtInfo::CtorInit( pFrm );
+    const SwTxtNode *pNd = pFrm->GetTxtNode();
+    pVsh = pFrm->GetShell();
+    if ( pVsh )
+        pOut = pVsh->GetOut();
+    else
+    {
+        //Zugriff ueber StarONE, es muss keine Shell existieren oder aktiv sein.
+        if ( pNd->GetDoc()->IsBrowseMode() ) //?!?!?!?
+            //in Ermangelung eines Besseren kann hier ja wohl nur noch das
+            //AppWin genommen werden?
+            pOut = GetpApp()->GetDefaultDevice();
+        else
+            pOut = pNd->GetDoc()->GetPrt(); //Muss es geben (oder sal_True uebergeben?)
+    }
+    pOpt = pVsh ? pVsh->GetViewOptions() : SW_MOD()->GetViewOption(pNd->GetDoc()->IsHTMLMode());//Options vom Module wg. StarONE
+    //Hier auf GetWin() abfragen nicht auf GetOut != PRINTER (SwFlyFrmFmt::MakeGraphic)
+    bOnWin = pVsh && ( pVsh->GetWin() ||
+        ( pOut && OUTDEV_PRINTER != pOut->GetOutDevType() && pOpt->IsPrtFormat() ) );
+    pWin = bOnWin ? pOut : 0;
+
+    // bURLNotify wird gesetzt, wenn MakeGraphic dies vorbereitet
+    bURLNotify = pNoteURL && !bOnWin
+        && (pOut && OUTDEV_PRINTER != pOut->GetOutDevType());
+
+
+    pFnt = pNewFnt;
+
+    if( 0 == ( pPrt = pVsh ? pVsh->GetReferenzDevice():0 ) )
+        pPrt = pNd->GetDoc()->GetPrt();
+    else
+    {
+        ASSERT( !bOnWin, "SwTxtSizeInfo: Funny ReferenzDevice" );
+        if( ((Printer*)pPrt)->IsValid() )
+            pOut = pPrt;
+    }
+    if ( pPrt && !((Printer*)pPrt)->IsValid() )
+        pPrt = 0;
+    pTxt = &pNd->GetTxt();
+#ifndef PRODUCT
+    ChkOutDev( *this );
+#endif
+    if( pVsh && pNd->GetDoc()->IsBrowseMode() &&
+        !pVsh->GetViewOptions()->IsPrtFormat() )
+        pPrt = pOut;
+    nIdx = nNewIdx;
+    nLen = nNewLen;
+    bNotEOL = sal_False;
+    bStopUnderFlow = sal_False;
+    bSpecialUnderline = sal_False;
+    SetLen( GetMinLen( *this ) );
+}
+
+SwTxtSizeInfo::SwTxtSizeInfo( const SwTxtSizeInfo &rNew, const XubString &rTxt,
+                              const xub_StrLen nIdx, const xub_StrLen nLen )
+    : SwTxtInfo( rNew ),
+      pVsh(((SwTxtSizeInfo&)rNew).GetVsh()),
+      pOut(((SwTxtSizeInfo&)rNew).GetOut()),
+      pWin(((SwTxtSizeInfo&)rNew).GetWin()),
+      pPrt(((SwTxtSizeInfo&)rNew).GetPrt()),
+      pFnt(((SwTxtSizeInfo&)rNew).GetFont()),
+      pFrm( rNew.pFrm ),
+      pOpt(&rNew.GetOpt()),
+      pTxt(&rTxt),
+      nIdx(nIdx),
+      nLen(nLen),
+      bOnWin( rNew.OnWin() ),
+      bNotEOL( rNew.NotEOL() ),
+      bURLNotify( rNew.URLNotify() ),
+      bStopUnderFlow( rNew.StopUnderFlow() )
+{
+#ifndef PRODUCT
+    ChkOutDev( *this );
+#endif
+    SetLen( GetMinLen( *this ) );
+}
+
+/*************************************************************************
+ *                      SwTxtSizeInfo::SelectFont()
+ *************************************************************************/
+
+void SwTxtSizeInfo::SelectFont()
+{
+    // 8731: Der Weg muss ueber ChgPhysFnt gehen, sonst geraet
+    // der FontMetricCache durcheinander. In diesem Fall steht pLastMet
+    // auf dem alten Wert.
+    // Falsch: GetOut()->SetFont( GetFont()->GetFnt() );
+    GetFont()->Invalidate();
+    GetFont()->ChgPhysFnt( pVsh, GetOut() );
+}
+
+/*************************************************************************
+ *                      SwTxtSizeInfo::_NoteAnimation()
+ *************************************************************************/
+
+void SwTxtSizeInfo::_NoteAnimation()
+{
+    ASSERT( bOnWin, "NoteAnimation: Wrong Call" );
+    if( SwRootFrm::FlushVout() )
+    {
+        pOut = pVsh->GetOut();
+        pWin = pOut;
+    }
+}
+
+/*************************************************************************
+ *                     SwTxtPaintInfo::CtorInit()
+ *************************************************************************/
+
+void SwTxtPaintInfo::CtorInit( SwTxtFrm *pFrame, const SwRect &rPaint )
+{
+    SwTxtSizeInfo::CtorInit( pFrame );
+    aTxtFly.CtorInit( pFrame ),
+    aPaintRect = rPaint;
+    nSpaceIdx = 0;
+    pSpaceAdd = NULL;
+    pWrongList = NULL;
+#ifdef PRODUCT
+    pBrushItem = 0;
+#else
+    pBrushItem = ((SvxBrushItem*)-1);
+#endif
+}
+
+SwTxtPaintInfo::SwTxtPaintInfo( const SwTxtPaintInfo &rInf, const XubString &rTxt )
+    : SwTxtSizeInfo( rInf, rTxt ),
+      aTxtFly( *rInf.GetTxtFly() ),
+      aPos( rInf.GetPos() ),
+      aPaintRect( rInf.GetPaintRect() ),
+      nSpaceIdx( rInf.GetSpaceIdx() ),
+      pSpaceAdd( rInf.GetpSpaceAdd() ),
+      pWrongList( rInf.GetpWrongList() ),
+      pBrushItem( rInf.GetBrushItem() )
+{ }
+
+SwTxtPaintInfo::SwTxtPaintInfo( const SwTxtPaintInfo &rInf )
+    : SwTxtSizeInfo( rInf ),
+      aTxtFly( *rInf.GetTxtFly() ),
+      aPos( rInf.GetPos() ),
+      aPaintRect( rInf.GetPaintRect() ),
+      nSpaceIdx( rInf.GetSpaceIdx() ),
+      pSpaceAdd( rInf.GetpSpaceAdd() ),
+      pWrongList( rInf.GetpWrongList() ),
+      pBrushItem( rInf.GetBrushItem() )
+{ }
+
+/*************************************************************************
+ *                     SwTxtPaintInfo::_DrawText()
+ *************************************************************************/
+
+void SwTxtPaintInfo::_DrawText( const XubString &rText, const SwLinePortion &rPor,
+                            const xub_StrLen nStart, const xub_StrLen nLen,
+                            const sal_Bool bKern, const sal_Bool bWrong )
+{
+    if( !nLen )
+        return;
+    if( GetFont()->IsBlink() && OnWin() && rPor.Width() )
+    {
+        if( !pBlink )
+            pBlink = new SwBlink();
+        pBlink->Insert( &rPor, aPos, GetTxtFrm() );
+        if( !pBlink->IsVisible() )
+            return;
+    }
+
+    short nSpaceAdd = ( rPor.IsBlankPortion() || rPor.IsDropPortion() ||
+                        rPor.InNumberGrp() ) ? 0 : GetSpaceAdd();
+
+    const sal_Bool bBullet = OnWin() && GetOpt().IsBlank() && IsNoSymbol();
+    sal_Bool bTmpWrong = bWrong && OnWin() && GetOpt().IsOnlineSpell()
+                             && !GetOpt().IsHideSpell();
+    SwDrawTextInfo aDrawInf( pFrm->GetShell(), *pOut,
+                             rText, nStart, nLen, rPor.Width(), bBullet );
+    aDrawInf.SetLeft( GetPaintRect().Left() );
+    aDrawInf.SetRight( GetPaintRect().Right() );
+    aDrawInf.SetSpecialUnderline( bSpecialUnderline );
+    aDrawInf.SetSpace( nSpaceAdd );
+
+    if( GetTxtFly()->IsOn() )
+    {
+        // aPos muss als TopLeft vorliegen, weil die ClipRects sonst
+        // nicht berechnet werden koennen.
+        const Point aPoint( aPos.X(), aPos.Y() - rPor.GetAscent() );
+        const Size aSize( rPor.Width(), rPor.Height() );
+        aDrawInf.SetFont( pFnt );
+        aDrawInf.SetPos( aPoint );
+        aDrawInf.SetSize( aSize );
+        aDrawInf.SetAscent( rPor.GetAscent() );
+        aDrawInf.SetKern( bKern ? rPor.Width() : 0 );
+        aDrawInf.SetSpace( nSpaceAdd );
+        aDrawInf.SetWrong( bTmpWrong ? pWrongList : NULL );
+        GetTxtFly()->DrawTextOpaque( aDrawInf );
+    }
+    else
+    {
+        aDrawInf.SetPos( aPos );
+        if( bKern )
+            pFnt->_DrawStretchText( aDrawInf );
+        else
+        {
+            aDrawInf.SetWrong( bTmpWrong ? pWrongList : NULL );
+            aDrawInf.SetSpace( nSpaceAdd );
+            pFnt->_DrawText( aDrawInf );
+        }
+    }
+}
+
+/*************************************************************************
+ *                          GetDrawPos()
+ *************************************************************************/
+inline Point GetDrawPos( const Point &rPos, const SwLinePortion &rPor )
+{
+    // Bei Baselineausgabe muss der Ascent der Portion abgezogen werden.
+    // DrawRects sind immer per TopLeft.
+    return Point( rPos.X(), rPos.Y() - rPor.GetAscent() );
+}
+
+/*************************************************************************
+ *                     SwTxtPaintInfo::DrawRect()
+ *************************************************************************/
+
+void SwTxtPaintInfo::DrawRect( const SwRect &rRect, sal_Bool bNoGraphic,
+                               sal_Bool bRetouche ) const
+{
+    if ( OnWin() || !bRetouche )
+    {
+        if( aTxtFly.IsOn() )
+            ((SwTxtPaintInfo*)this)->GetTxtFly()->
+                DrawFlyRect( pOut, rRect, *this, bNoGraphic );
+        else if ( bNoGraphic )
+            pOut->DrawRect( rRect.SVRect() );
+        else
+        {
+            ASSERT( ((SvxBrushItem*)-1) != pBrushItem, "DrawRect: Uninitialized BrushItem!" );
+            ::DrawGraphic( pBrushItem, pOut, aItemRect, rRect );
+        }
+    }
+}
+
+/*************************************************************************
+ *                     SwTxtPaintInfo::DrawRect()
+ *************************************************************************/
+
+void SwTxtPaintInfo::DrawRect( const SwLinePortion &rPor ) const
+{
+    const Size aSize( rPor.Width(), rPor.Height() );
+    const SwRect aRect( GetDrawPos( aPos, rPor ), aSize );
+    DrawRect( aRect );
+}
+
+/*************************************************************************
+ *                     SwTxtPaintInfo::DrawTab()
+ *************************************************************************/
+
+void SwTxtPaintInfo::DrawTab( const SwLinePortion &rPor ) const
+{
+    if( OnWin() )
+    {
+        const Size aSize( rPor.Width(), rPor.Height() );
+        const Rectangle aRect( GetDrawPos( aPos, rPor ), aSize );
+#ifndef PRODUCT
+#ifdef DEBUG
+        if( IsOptDbg() )
+            pWin->DrawRect( aRect );
+#endif
+#endif
+        pOpt->PaintTab( pWin, aRect );
+    }
+}
+
+/*************************************************************************
+ *                     SwTxtPaintInfo::DrawLineBreak()
+ *************************************************************************/
+
+void SwTxtPaintInfo::DrawLineBreak( const SwLinePortion &rPor ) const
+{
+    if( OnWin() )
+    {
+        const Size aSize( pOpt->GetLineBreakWidth(pWin), rPor.Height() );
+        const Rectangle aRect( GetDrawPos( aPos, rPor ), aSize );
+        pOpt->PaintLineBreak( pWin, aRect );
+    }
+}
+
+/*************************************************************************
+ *                     SwTxtPaintInfo::DrawPostIts()
+ *************************************************************************/
+
+void SwTxtPaintInfo::DrawPostIts( const SwLinePortion &rPor, sal_Bool bScript ) const
+{
+    if( OnWin() && pOpt->IsPostIts() )
+    {
+        const Size aSize( pOpt->GetPostItsWidth( pWin ),
+            pFnt->GetHeight( pVsh, GetOut() ) );
+        const Point aTmp( aPos.X(), aPos.Y() - pFnt->GetAscent( pVsh, GetOut() ) );
+        const Rectangle aRect( aTmp, aSize );
+        pOpt->PaintPostIts( pWin, aRect, bScript ? COL_LIGHTGREEN : COL_YELLOW );
+    }
+}
+
+/*************************************************************************
+ *                     SwTxtPaintInfo::DrawBackGround()
+ *************************************************************************/
+
+SwRect lcl_CalcRect( const SwTxtPaintInfo *pInf, const SwLinePortion &rPor )
+{
+    SwRect aRect( GetDrawPos( pInf->GetPos(), rPor ),
+                  Size( rPor.Width(), rPor.Height() ) );
+    if( rPor.InTxtGrp() && pInf->GetSpaceAdd() )
+        aRect.Width( aRect.Width() +
+            ((SwTxtPortion&)rPor).CalcSpacing( pInf->GetSpaceAdd(), *pInf ) );
+
+    if( aRect.HasArea() )
+    {
+        ::SwAlignRect( aRect, (ViewShell*)pInf->GetVsh() );
+
+        if ( pInf->GetOut()->IsClipRegion() )
+        {
+            SwRect aClip( pInf->GetOut()->GetClipRegion().GetBoundRect() );
+            aRect.Intersection( aClip );
+        }
+    }
+    return aRect;
+}
+
+void SwTxtPaintInfo::DrawBackground( const SwLinePortion &rPor ) const
+{
+    ASSERT( OnWin(), "SwTxtPaintInfo::DrawBackground: printer polution ?" );
+
+    SwRect aRect = lcl_CalcRect( this, rPor );
+
+    if ( aRect.HasArea() )
+    {
+        OutputDevice *pOut = (OutputDevice*)GetOut();
+        Color aCol( COL_LIGHTGRAY );
+        const Color aOldColor( pOut->GetFillColor() );
+        sal_Bool bChgBrsh;
+        if( 0 != (bChgBrsh = aOldColor != aCol) )
+            pOut->SetFillColor( aCol );
+
+        DrawRect( aRect, sal_True );
+
+        if ( bChgBrsh )
+            pOut->SetFillColor( aOldColor );
+    }
+}
+
+void SwTxtPaintInfo::_DrawBackBrush( const SwLinePortion &rPor ) const
+{
+    ASSERT( pFnt->GetBackColor(), "DrawBackBrush: Lost Color" );
+    SwRect aRect = lcl_CalcRect( this, rPor );
+
+    if( GetSpaceAdd() < 0 )
+    {
+        if( !rPor.GetPortion() || rPor.GetPortion()->InFixMargGrp() )
+            aRect.Width( aRect.Width() + GetSpaceAdd() );
+    }
+
+    if ( aRect.HasArea() )
+    {
+        OutputDevice *pOut = (OutputDevice*)GetOut();
+        const Color aOldColor( pOut->GetFillColor() );
+        sal_Bool bChgColor;
+        if( 0 != ( bChgColor = aOldColor != *pFnt->GetBackColor() ) )
+            pOut->SetFillColor( *pFnt->GetBackColor() );
+        DrawRect( aRect, sal_True, sal_False );
+        if( bChgColor )
+            pOut->SetFillColor( aOldColor );
+    }
+}
+
+/*************************************************************************
+ *                     SwTxtPaintInfo::DrawViewOpt()
+ *************************************************************************/
+
+void SwTxtPaintInfo::DrawViewOpt( const SwLinePortion &rPor,
+                                  const MSHORT nWhich ) const
+{
+    if( OnWin() )
+    {
+        sal_Bool bDraw = sal_False;
+        switch( nWhich )
+        {
+            case POR_FTN:       if ( GetOpt().IsFootNote() )bDraw = sal_True; break;
+            case POR_TOX:       if ( GetOpt().IsTox() )     bDraw = sal_True; break;
+            case POR_REF:       if ( GetOpt().IsRef() )     bDraw = sal_True; break;
+            case POR_QUOVADIS:
+            case POR_NUMBER:
+            case POR_FLD:
+            case POR_URL:
+            case POR_HIDDEN:    if ( GetOpt().IsField() )   bDraw = sal_True; break;
+            case POR_TAB:       if ( GetOpt().IsTab() )     bDraw = sal_True; break;
+            case POR_SOFTHYPH:  if ( GetOpt().IsSoftHyph() )bDraw = sal_True; break;
+            case POR_BLANK:     if ( GetOpt().IsHardBlank())bDraw = sal_True; break;
+            default:
+            {
+                ASSERT( !this, "SwTxtPaintInfo::DrawViewOpt: don't know how to draw this" );
+                break;
+            }
+        }
+        if ( bDraw )
+            DrawBackground( rPor );
+    }
+}
+
+/*************************************************************************
+ *                     SwTxtPaintInfo::_NotifyURL()
+ *************************************************************************/
+
+void SwTxtPaintInfo::_NotifyURL( const SwLinePortion &rPor ) const
+{
+    ASSERT( pNoteURL, "NotifyURL: pNoteURL gone with the wind!" );
+    SwRect aRect = lcl_CalcRect( this, rPor );
+    if( aRect.HasArea() )
+    {
+        SwTxtNode *pNd = (SwTxtNode*)GetTxtFrm()->GetTxtNode();
+        SwIndex aIndex( pNd, GetIdx() );
+        SwTxtAttr *pAttr = pNd->GetTxtAttr( aIndex, RES_TXTATR_INETFMT );
+        if( pAttr )
+        {
+            const SwFmtINetFmt& rFmt = pAttr->GetINetFmt();
+            pNoteURL->InsertURLNote( rFmt.GetValue(), rFmt.GetTargetFrame(),
+                aRect );
+        }
+    }
+}
+
+/*************************************************************************
+ *                  SwTxtFormatInfo::InitHyph()
+ *************************************************************************/
+
+sal_Bool SwTxtFormatInfo::InitHyph( const sal_Bool bAutoHyph )
+{
+    const SwAttrSet& rAttrSet = GetTxtFrm()->GetTxtNode()->GetSwAttrSet();
+    const SvxHyphenZoneItem &rAttr = rAttrSet.GetHyphenZone();
+    MaxHyph() = rAttr.GetMaxHyphens();
+    sal_Bool bAuto = bAutoHyph || rAttr.IsHyphen();
+    if( bAuto || bInterHyph )
+    {
+        uno::Reference< beans::XPropertySet > xProp( ::GetLinguPropertySet() );
+        nHyphStart = nHyphWrdStart = STRING_LEN;
+        nHyphWrdLen = 0;
+
+        // save hyphenation relevant Lingu properties for later restoration
+        // before changing them
+        if( xProp.is() && !bRestoreHyphOptions )
+        {
+            // paraex.hxx zeigt, dass im Attribut nMinLead = nMinTrail = 0
+            // initialisiert wird.
+
+            sal_Int16 nTemp;
+            xProp->getPropertyValue( C2U(UPN_HYPH_MIN_LEADING) ) >>= nTemp;
+            nMinLeading = nTemp;
+            xProp->getPropertyValue( C2U(UPN_HYPH_MIN_LEADING) ) >>= nTemp;
+            nMinTrailing = nTemp;
+            // nMinWordLength = ; noch nicht am Absatz verwendet
+            INT16 nNewMinLeading  = Max(rAttr.GetMinLead(), sal_uInt8(2));
+            INT16 nNewMinTrailing = rAttr.GetMinTrail();
+            bRestoreHyphOptions = (nMinLeading  != nNewMinLeading) ||
+                                  (nMinTrailing != nNewMinTrailing);
+
+            if (bRestoreHyphOptions)
+            {
+                uno::Any aTemp;
+                aTemp <<= nNewMinLeading;
+                xProp->setPropertyValue( C2U(UPN_HYPH_MIN_LEADING), aTemp );
+                aTemp <<= nNewMinTrailing;
+                xProp->setPropertyValue( C2U(UPN_HYPH_MIN_TRAILING), aTemp );
+            }
+        }
+    }
+    return bAuto;
+}
+/*************************************************************************
+ *                  SwTxtFormatInfo::RestoreHyphOptions()
+ *************************************************************************/
+
+void SwTxtFormatInfo::RestoreHyphOptions()
+{
+    uno::Reference< beans::XPropertySet >  xProp( ::GetLinguPropertySet() );
+    if (xProp.is())
+    {
+        uno::Any aVal;
+        aVal <<= (sal_Int16)nMinLeading;
+        xProp->setPropertyValue( C2U(UPN_HYPH_MIN_LEADING), aVal );
+        aVal <<= (sal_Int16)nMinTrailing;
+        xProp->setPropertyValue( C2U(UPN_HYPH_MIN_TRAILING), aVal );
+        //xProp->setPropertyValue( C2U(UPN_HYPH_MIN_WORDLENGTH),  );
+    }
+}
+
+/*************************************************************************
+ *                  SwTxtFormatInfo::CtorInit()
+ *************************************************************************/
+
+void SwTxtFormatInfo::CtorInit( SwTxtFrm *pNewFrm, const sal_Bool bNewInterHyph,
+                                const sal_Bool bNewQuick, const sal_Bool bTst )
+{
+    SwTxtPaintInfo::CtorInit( pNewFrm, SwRect() );
+    bQuick = bNewQuick;
+    bInterHyph = bNewInterHyph;
+
+    //! needs to be done in this order
+    nMinLeading     = 2;
+    nMinTrailing    = 2;
+    nMinWordLength  = 0;
+    bRestoreHyphOptions = sal_False;
+    bAutoHyph = InitHyph();
+
+    bIgnoreFly = sal_False;
+    bShift = sal_False;
+    bDropInit = sal_False;
+    bTestFormat = bTst;
+    nLeft = 0;
+    nRight = 0;
+    nFirst = 0;
+    nRealWidth = 0;
+    nForcedLeftMargin = 0;
+    pRest = 0;
+    nLineHeight = 0;
+    SetLineStart(0);
+    Init();
+}
+
+/*************************************************************************
+ *                  SwTxtFormatInfo::IsHyphenate()
+ *************************************************************************/
+// Trennen oder nicht trennen, das ist hier die Frage:
+// - in keinem Fall trennen, wenn der Hyphenator ERROR zurueckliefert,
+//   oder wenn als Sprache NOLANGUAGE eingestellt ist.
+// - ansonsten immer trennen, wenn interaktive Trennung vorliegt
+// - wenn keine interakt. Trennung, dann nur trennen, wenn im ParaFmt
+//   automatische Trennung eingestellt ist.
+
+sal_Bool SwTxtFormatInfo::IsHyphenate() const
+{
+    if( !bInterHyph && !bAutoHyph )
+        return sal_False;
+
+    LanguageType eTmp = GetFont()->GetLanguage();
+    if( LANGUAGE_DONTKNOW == eTmp || LANGUAGE_NONE == eTmp )
+        return sal_False;
+    uno::Reference< linguistic::XHyphenator > xHyph = GetVsh() ? GetVsh()->GetHyphenator() :
+                           OFF_APP()->GetHyphenator();
+
+    if (bInterHyph && xHyph.is())
+        SvxSpellWrapper::CheckHyphLang( xHyph, eTmp );
+
+    if( !xHyph.is() || !xHyph->hasLocale( SvxCreateLocale(eTmp) ) )
+        return sal_False;
+    return sal_True;
+}
+
+/*************************************************************************
+ *                  SwTxtFormatInfo::GetDropFmt()
+ *************************************************************************/
+
+// Dropcaps vom SwTxtFormatter::CTOR gerufen.
+const SwFmtDrop *SwTxtFormatInfo::GetDropFmt() const
+{
+    const SwFmtDrop *pDrop = &GetTxtFrm()->GetTxtNode()->GetSwAttrSet().GetDrop();
+    if( 1 >= pDrop->GetLines() ||
+        ( !pDrop->GetChars() && !pDrop->GetWholeWord() ) )
+        pDrop = 0;
+    return pDrop;
+}
+
+/*************************************************************************
+ *                      SwTxtFormatInfo::Init()
+ *************************************************************************/
+
+void SwTxtFormatInfo::Init()
+{
+    // Nicht initialisieren: pRest, nLeft, nRight, nFirst, nRealWidth
+    X(0);
+    bArrowDone = bFull = bFtnDone = bErgoDone = bNumDone = bNoEndHyph =
+        bNoMidHyph = bStop = bNewLine = bUnderFlow = sal_False;
+    pRoot = 0;
+    pLast = 0;
+    pFly = 0;
+    pLastFld = 0;
+    pLastTab = 0;
+    pUnderFlow = 0;
+    cTabDecimal = 0;
+    nWidth = nRealWidth;
+    nForcedLeftMargin = 0;
+    nSoftHyphPos = 0;
+    cHookChar = 0;
+    SetIdx(0);
+    SetLen( GetTxt().Len() );
+    SetPaintOfst(0);
+}
+
+/*************************************************************************
+ *                 SwTxtFormatInfo::_CheckFtnPortion()
+ *************************************************************************/
+
+sal_Bool SwTxtFormatInfo::_CheckFtnPortion( SwLineLayout* pCurr )
+{
+    KSHORT nHeight = pCurr->GetRealHeight();
+    SwLinePortion *pPor = pCurr->GetPortion();
+    sal_Bool bRet = sal_False;
+    while( pPor )
+    {
+        if( pPor->IsFtnPortion() && nHeight > ((SwFtnPortion*)pPor)->Orig() )
+        {
+            bRet = sal_True;
+            SetLineHeight( nHeight );
+            break;
+        }
+        pPor = pPor->GetPortion();
+    }
+    return bRet;
+}
+
+
+
+
+/*************************************************************************
+ *                 SwTxtFormatInfo::ScanPortionEnd()
+ *************************************************************************/
+xub_StrLen SwTxtFormatInfo::ScanPortionEnd( const xub_StrLen nEnd, sal_Bool bSkip )
+{
+    cHookChar = 0;
+    const xub_Unicode cTabDec = GetLastTab() ? (sal_Unicode)GetTabDecimal() : 0;
+    xub_StrLen i = GetIdx();
+    if ( bSkip && i < nEnd )
+        ++i;
+
+    for( ; i < nEnd; ++i )
+    {
+        const xub_Unicode cPos = GetChar( i );
+        switch( cPos )
+        {
+        case CH_TXTATR_BREAKWORD:
+        case CH_TXTATR_INWORD:
+            if( !HasHint( i ))
+                break;
+            // no break;
+
+        case CHAR_SOFTHYPHEN:
+        case CHAR_HARDHYPHEN:
+        case CHAR_HARDBLANK:
+        case CH_TAB:
+        case CH_BREAK:
+            cHookChar = cPos;
+            return i;
+
+        default:
+            if( cTabDec == cPos )
+            {
+                cHookChar = cPos;
+                return i;
+            }
+        }
+    }
+/*
+JP 07.08.00: old
+    if ( cTabDec )
+        for( ; i < nEnd; ++i )
+        {
+            const xub_Unicode cPos = GetChar( i );
+            if( cTabDec == cPos || CH_TAB == cPos || CH_BREAK == cPos ||
+                (( CH_TXTATR_BREAKWORD == cPos || CH_TXTATR_INWORD == cPos )
+                    && HasHint( i ) ) )
+            {
+                cHookChar = cPos;
+                return i;
+            }
+        }
+    else
+        for( ; i < nEnd; ++i )
+        {
+            const xub_Unicode cPos = GetChar( i );
+            if( CH_TAB == cPos || CH_BREAK == cPos ||
+                ( ( CH_TXTATR_BREAKWORD == cPos || CH_TXTATR_INWORD == cPos )
+                    && HasHint( i ) ) )
+            {
+                cHookChar = cPos;
+                return i;
+            }
+        }
+*/
+    return i;
+}
+
+/*************************************************************************
+ *                      class SwTxtSlot
+ *************************************************************************/
+
+SwTxtSlot::SwTxtSlot( const SwTxtSizeInfo *pNew, const SwLinePortion *pPor )
+{
+    bOn = pPor->GetExpTxt( *pNew, aTxt );
+
+    // Der Text wird ausgetauscht...
+    if( bOn )
+    {
+        pInf = (SwTxtSizeInfo*)pNew;
+        nIdx = pInf->GetIdx();
+        nLen = pInf->GetLen();
+        pInf->SetLen( pPor->GetLen() );
+        pOldTxt = &(pInf->GetTxt());
+        pInf->SetTxt( aTxt );
+        pInf->SetIdx( 0 );
+    }
+}
+
+/*************************************************************************
+ *                       SwTxtSlot::~SwTxtSlot()
+ *************************************************************************/
+
+SwTxtSlot::~SwTxtSlot()
+{
+    if( bOn )
+    {
+        pInf->SetTxt( *pOldTxt );
+        pInf->SetIdx( nIdx );
+        pInf->SetLen( nLen );
+    }
+}
+
+/*************************************************************************
+ *                      class SwTxtSlotLen
+ *************************************************************************/
+
+SwTxtSlotLen::SwTxtSlotLen( const SwTxtSizeInfo *pNew, const SwLinePortion *pPor,
+    const sal_Char *pCh )
+{
+    if( pCh )
+    {
+        aTxt = XubString( pCh, RTL_TEXTENCODING_MS_1252 );
+        bOn = sal_True;
+    }
+    else
+        bOn = pPor->GetExpTxt( *pNew, aTxt );
+
+    // Der Text wird ausgetauscht...
+    if( bOn )
+    {
+        pInf = (SwTxtSizeInfo*)pNew;
+        nIdx = pInf->GetIdx();
+        nLen = pInf->GetLen();
+        pOldTxt = &(pInf->GetTxt());
+        pInf->SetTxt( aTxt );
+        pInf->SetIdx( 0 );
+        pInf->SetLen( pInf->GetTxt().Len() );
+    }
+}
+
+/*************************************************************************
+ *                       SwTxtSlotLen::~SwTxtSlotLen()
+ *************************************************************************/
+
+SwTxtSlotLen::~SwTxtSlotLen()
+{
+    if( bOn )
+    {
+        pInf->SetTxt( *pOldTxt );
+        pInf->SetIdx( nIdx );
+        pInf->SetLen( nLen );
+    }
+}
+
+/*************************************************************************
+ *                     SwFontSave::SwFontSave()
+ *************************************************************************/
+
+SwFontSave::SwFontSave( const SwTxtSizeInfo &rInf, SwFont *pNewFnt )
+        : pFnt( pNewFnt ? ((SwTxtSizeInfo&)rInf).GetFont() : 0 )
+{
+    if( pFnt )
+    {
+        pInf = &((SwTxtSizeInfo&)rInf);
+        if( pFnt->DifferentMagic( pNewFnt, pFnt->GetActual() ) )
+        {
+            pNewFnt->SetTransparent( sal_True );
+            pNewFnt->SetAlign( ALIGN_BASELINE );
+            pInf->SetFont( pNewFnt );
+        }
+        else
+            pFnt = 0;
+        pNewFnt->Invalidate();
+        pNewFnt->ChgPhysFnt( pInf->GetVsh(), pInf->GetOut() );
+    }
+}
+
+/*************************************************************************
+ *                     SwFontSave::~SwFontSave()
+ *************************************************************************/
+
+SwFontSave::~SwFontSave()
+{
+    if( pFnt )
+    {
+        // SwFont zurueckstellen
+        pFnt->Invalidate();
+        pInf->SetFont( pFnt );
+    }
+}
+
+/*************************************************************************
+ *                     SwDefFontSave::SwDefFontSave()
+ *************************************************************************/
+
+SwDefFontSave::SwDefFontSave( const SwTxtSizeInfo &rInf )
+        : pFnt( ((SwTxtSizeInfo&)rInf).GetFont()  )
+{
+    bAlter = pFnt->GetFixKerning() ||
+             ( RTL_TEXTENCODING_SYMBOL == pFnt->GetCharSet(pFnt->GetActual()) )
+#if defined( PM2 )
+             || ( System::GetCharSet() != CHARSET_IBMPC_850 )
+#endif
+        ;
+
+    if( bAlter && COMPARE_EQUAL !=
+        pFnt->GetName( pFnt->GetActual() ).CompareToAscii( sBulletFntName ) )
+    {
+        pNewFnt = new SwFont( *pFnt );
+        pNewFnt->SetFamily( FAMILY_DONTKNOW, pFnt->GetActual() );
+        pNewFnt->SetName( XubString( sBulletFntName,
+                          RTL_TEXTENCODING_MS_1252 ), pFnt->GetActual() );
+        pNewFnt->SetStyleName( aEmptyStr, pFnt->GetActual() );
+        pNewFnt->SetCharSet( RTL_TEXTENCODING_SYMBOL, pFnt->GetActual() );
+        pNewFnt->SetFixKerning( 0 );
+        pInf = &((SwTxtSizeInfo&)rInf);
+        pNewFnt->Invalidate();
+        pInf->SetFont( pNewFnt );
+    }
+    else
+    {
+        pFnt = 0;
+        pNewFnt = 0;
+    }
+}
+
+/*************************************************************************
+ *                     SwDefFontSave::~SwDefFontSave()
+ *************************************************************************/
+
+SwDefFontSave::~SwDefFontSave()
+{
+    if( pFnt )
+    {
+        delete pNewFnt;
+        // SwFont zurueckstellen
+        pFnt->Invalidate();
+        pInf->SetFont( pFnt );
+    }
+}
+
+/*************************************************************************
+ *                     SwFtnSave::~SwFtnSave()
+ *************************************************************************/
+
+SwFtnSave::~SwFtnSave()
+{
+    if( pFnt )
+    {
+        // SwFont zurueckstellen
+        *pFnt = *pOld;
+        pFnt->GetTox() = pOld->GetTox();
+        pFnt->ChgPhysFnt( pInf->GetVsh(), pInf->GetOut() );
+        delete pOld;
+    }
+}
+
+/*************************************************************************
+ *                  SwTxtFormatInfo::ChgHyph()
+ *************************************************************************/
+
+sal_Bool SwTxtFormatInfo::ChgHyph( const sal_Bool bNew )
+{
+    const sal_Bool bOld = bAutoHyph;
+    if( bAutoHyph != bNew )
+    {
+        bAutoHyph = bNew;
+        InitHyph( bNew );
+        // 5744: Sprache am Hyphenator einstellen.
+        if( pFnt )
+            pFnt->ChgPhysFnt( pVsh, pOut );
+    }
+    return bOld;
+}
+
+
diff --git a/sw/source/core/text/inftxt.hxx b/sw/source/core/text/inftxt.hxx
new file mode 100644
index 000000000000..914c7e163237
--- /dev/null
+++ b/sw/source/core/text/inftxt.hxx
@@ -0,0 +1,807 @@
+/*************************************************************************
+ *
+ *  $RCSfile: inftxt.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _INFTXT_HXX
+#define _INFTXT_HXX
+
+#include 
+
+#include "swtypes.hxx"
+#include "txttypes.hxx"
+#include "swrect.hxx"
+
+#include "txtfly.hxx"
+#include "swfont.hxx"
+#include "porlay.hxx"
+#include "txtfrm.hxx"
+#include "ndtxt.hxx"
+#include "txttypes.hxx"
+
+class Font;
+class OutputDevice;
+class SvxBrushItem;
+class SvxLineSpacingItem;
+class SvxTabStop;
+class SvxTabStopItem;
+class SwAttrSet;
+class SwField;
+class SwFldPortion;
+class SwFlyPortion;
+class SwFmtDrop;
+class SwFtnPortion;
+class SwLineHeightRule;
+class SwLineLayout;
+class SwLinePortion;
+class SwLineSpaceRule;
+class SwParaPortion;
+class SwTabPortion;
+class SwTxtFrm;
+class SwTxtSizeInfo;
+class SwViewOption;
+class ViewShell;
+class SwTxtFtn;
+
+/* Minimum: Prozentwert fuers kernen */
+#define MINKERNPERCENT 5
+#define ARROW_WIDTH 200
+
+#ifndef PRODUCT
+#define OPTCALM( rInf )  (rInf).IsOptCalm()
+#define OPTLOW( rInf )   (rInf).IsOptLow()
+#define OPTDBG( rInf )   (rInf).IsOptDbg()
+#else
+#define OPTCALM( rInf )  sal_True
+#define OPTLOW( rInf )   sal_False
+#define OPTDBG( rInf )   sal_False
+#endif
+
+/*************************************************************************
+ *                      class SwLineInfo
+ *************************************************************************/
+
+// Beruecksichtigt das Attribut LineSpace bei der Hoehen/Ascentberechnung.
+
+class SwLineInfo
+{
+    friend class SwTxtIter;
+
+    const SvxTabStopItem    *pRuler;
+    const SvxLineSpacingItem *pSpace;
+    KSHORT nDefTabStop;
+    void CtorInit( const SwAttrSet& rAttrSet );
+    inline SwLineInfo() {}
+public:
+    inline SwLineInfo( const SwAttrSet& rAttrSet )
+           { CtorInit( rAttrSet ); }
+    // Liefert den Tabstop, der auf LinePos folgt, oder 0.
+    const SvxTabStop *GetTabStop( const KSHORT nLinePos,
+                                 const KSHORT nLeft,
+                                 const KSHORT nRight ) const;
+    inline const SvxLineSpacingItem *GetLineSpacing() const { return pSpace; }
+    inline KSHORT GetDefTabStop() const { return nDefTabStop; }
+    inline void SetDefTabStop( KSHORT nNew ) const
+        { ( (SwLineInfo*)this )->nDefTabStop = nNew; }
+//  friend ostream &operator<<( ostream &rOS, const SwLineInfo &rInf );
+    friend SvStream &operator<<( SvStream &rOS, const SwLineInfo &rInf );
+};
+
+/*************************************************************************
+ *                      class SwTxtInfo
+ *************************************************************************/
+
+class SwTxtInfo
+{
+    // Implementation in txthyph.cxx
+    friend void SetParaPortion( SwTxtInfo *pInf, SwParaPortion *pRoot );
+    SwParaPortion *pPara;
+    xub_StrLen nTxtStart;                 // TxtOfst bei Follows
+
+protected:
+    inline SwTxtInfo() { }
+public:
+    void CtorInit( SwTxtFrm *pFrm );
+    SwTxtInfo( const SwTxtInfo &rInf );
+    inline SwTxtInfo( SwTxtFrm *pFrm ) { CtorInit( pFrm ); }
+    inline SwParaPortion *GetParaPortion() { return pPara; }
+    inline const SwParaPortion *GetParaPortion() const { return pPara; }
+    inline xub_StrLen GetTxtStart() const { return nTxtStart; }
+
+    friend SvStream &operator<<( SvStream &rOS, const SwTxtInfo &rInf );
+};
+
+/*************************************************************************
+ *                      class SwTxtSizeInfo
+ *************************************************************************/
+
+class SwTxtSizeInfo : public SwTxtInfo
+{
+protected:
+    ViewShell    *pVsh;
+    OutputDevice *pOut;
+    OutputDevice *pWin;
+    OutputDevice *pPrt;
+    SwFont *pFnt;
+    SwTxtFrm *pFrm;
+    const SwViewOption *pOpt;
+    const XubString *pTxt;
+    xub_StrLen nIdx, nLen;
+    sal_Bool bOnWin     : 1;
+    sal_Bool bNotEOL    : 1;
+    sal_Bool bURLNotify : 1;
+    sal_Bool bStopUnderFlow : 1;// Underflow gestoppt z.B. von einer FlyPortion
+    sal_Bool bSpecialUnderline : 1; // Hoch/Tief-Unterstreichung auf der Grundlinie
+    sal_Bool bArrowDone : 1;    // Pfeil nach links bei gescrollten Absaetzen
+    sal_Bool bFtnInside : 1;    // the current line contains a footnote
+
+protected:
+    void _NoteAnimation();
+    void CtorInit( SwTxtFrm *pFrm, SwFont *pFnt = 0,
+                   const xub_StrLen nIdx = 0,
+                   const xub_StrLen nLen = STRING_LEN );
+    SwTxtSizeInfo() {}
+    void _SelectOut();
+public:
+    SwTxtSizeInfo( const SwTxtSizeInfo &rInf );
+    SwTxtSizeInfo( const SwTxtSizeInfo &rInf, const XubString &rTxt,
+                   const xub_StrLen nIdx = 0,
+                   const xub_StrLen nLen = STRING_LEN );
+
+    inline SwTxtSizeInfo( SwTxtFrm *pFrm, SwFont *pFnt = 0,
+                   const xub_StrLen nIdx = 0,
+                   const xub_StrLen nLen = STRING_LEN )
+           { CtorInit( pFrm, pFnt, nIdx, nLen ); }
+
+    inline sal_Bool OnWin() const { return bOnWin; }
+    inline void SetOnWin( const sal_Bool bNew ) { bOnWin = bNew; }
+    inline sal_Bool NotEOL() const { return bNotEOL; }
+    inline void SetNotEOL( const sal_Bool bNew ) { bNotEOL = bNew; }
+    inline sal_Bool URLNotify() const { return bURLNotify; }
+    inline void SetURLNotify( const sal_Bool bNew ) { bURLNotify = bNew; }
+    inline sal_Bool StopUnderFlow() const { return bStopUnderFlow; }
+    inline void SetStopUnderFlow( const sal_Bool bNew ) { bStopUnderFlow = bNew; }
+    inline sal_Bool SpecialUnderline() const { return bSpecialUnderline; }
+    inline void SetSpecialUnderline( const sal_Bool bNew )
+        { bSpecialUnderline = bNew; }
+    inline ViewShell *GetVsh() { return pVsh; }
+    inline const ViewShell *GetVsh() const { return pVsh; }
+    inline OutputDevice *GetOut() { return pOut; }
+    inline const OutputDevice *GetOut() const { return pOut; }
+    inline OutputDevice *GetWin() { return pWin; }
+    inline const OutputDevice *GetWin() const { return pWin; }
+    inline OutputDevice *GetPrt() { return pPrt; }
+    inline const OutputDevice *GetPrt() const { return pPrt; }
+    inline void SetWin( OutputDevice *pNewWin );
+    inline void SetPrt( OutputDevice *pNewPrt );
+    inline void SetPrtOut() { pOut = pPrt; bOnWin = sal_False; }
+    inline void SetWinOut() { pOut = pWin; bOnWin = sal_True; }
+    inline SwFont *GetFont() { return pFnt; }
+    inline const SwFont *GetFont() const { return pFnt; }
+    inline void SetFont( SwFont *pNew ) { pFnt = pNew; }
+    void SelectFont();
+    inline void SelectOut() const
+    { if( pVsh ) ((SwTxtSizeInfo*)this)->_SelectOut(); }
+
+    inline const  SwViewOption &GetOpt() const { return *pOpt; }
+    inline const XubString &GetTxt() const { return *pTxt; }
+    inline const xub_Unicode GetChar( const xub_StrLen nPos ) const
+        { return pTxt->GetChar( nPos ); }
+
+    inline KSHORT      GetTxtHeight() const;
+    inline SwPosSize   GetTxtSize( const OutputDevice *pOut,
+                                   const XubString &rTxt, const xub_StrLen nIdx,
+                                   const xub_StrLen nLen ) const;
+    inline SwPosSize GetTxtSize() const;
+    inline SwPosSize GetTxtSize( const xub_StrLen nIdx, const xub_StrLen nLen )
+           const;
+    inline SwPosSize GetTxtSize( const XubString &rTxt ) const;
+    inline xub_StrLen GetTxtBreak( long nTxtWidth, const xub_StrLen nNewIdx,
+                               const xub_StrLen nNewLen ) const;
+    inline xub_StrLen GetTxtBreak( long nTxtWidth, const xub_StrLen nNewIdx,
+           const xub_StrLen nNewLen, xub_StrLen& rExtraCharPos ) const;
+    inline KSHORT GetAscent() const;
+
+    inline xub_StrLen GetIdx() const { return nIdx; }
+    inline void SetIdx( const xub_StrLen nNew ) { nIdx = nNew; }
+    inline xub_StrLen GetLen() const { return nLen; }
+    inline void SetLen( const xub_StrLen nNew ) { nLen = nNew; }
+    inline void SetTxt( const XubString &rNew ){ pTxt = &rNew; }
+
+    friend SvStream &operator<<( SvStream &rOS, const SwTxtSizeInfo &rInf );
+
+// 7780: Keine Bullets beim Symbol-Zeichensatz!
+    inline sal_Bool IsNoSymbol() const
+    { return RTL_TEXTENCODING_SYMBOL != pFnt->GetCharSet( pFnt->GetActual() ); }
+
+    inline void NoteAnimation() const
+        { if( OnWin() ) ((SwTxtSizeInfo*)this)->_NoteAnimation(); }
+    // Home is where Your heart is...
+    inline SwTxtFrm *GetTxtFrm() { return pFrm; }
+    inline const SwTxtFrm *GetTxtFrm() const { return pFrm; }
+
+    inline sal_Bool HasHint( xub_StrLen nPos ) const
+        { return _HasHint( pFrm->GetTxtNode(), nPos ); }
+    static sal_Bool _HasHint( const SwTxtNode* pTxtNode, xub_StrLen nPos );
+
+#ifndef PRODUCT
+    sal_Bool IsOptCalm() const;
+    sal_Bool IsOptLow() const;
+    sal_Bool IsOptDbg() const;
+    sal_Bool IsOptTest1() const;
+    sal_Bool IsOptTest2() const;
+    sal_Bool IsOptTest3() const;
+    sal_Bool IsOptTest4() const;
+    sal_Bool IsOptTest5() const;
+    sal_Bool IsOptTest6() const;
+    sal_Bool IsOptTest7() const;
+    sal_Bool IsOptTest8() const;
+#endif
+};
+
+/*************************************************************************
+ *                      class SwTxtPaintInfo
+ *************************************************************************/
+
+class SwTxtPaintInfo : public SwTxtSizeInfo
+{
+    SwWrongList *pWrongList;
+    SvShorts    *pSpaceAdd;
+    const SvxBrushItem *pBrushItem; // Fuer den Hintergrund
+    SwRect      aItemRect;          // ebenfalls fuer den Hintergrund
+    SwTxtFly    aTxtFly;    // FlyFrm-Berechnung
+    Point       aPos;       // Ausgabeposition
+    SwRect      aPaintRect; // Original Ausgaberechteck (aus Layout-Paint)
+
+    MSHORT nSpaceIdx;
+    void _DrawText( const XubString &rText, const SwLinePortion &rPor,
+                   const xub_StrLen nIdx, const xub_StrLen nLen,
+                   const sal_Bool bKern, const sal_Bool bWrong = sal_False );
+
+    SwTxtPaintInfo &operator=(const SwTxtPaintInfo&);
+    void _NotifyURL( const SwLinePortion &rPor ) const;
+    void _DrawBackBrush( const SwLinePortion &rPor ) const;
+
+protected:
+#ifdef PRODUCT
+    SwTxtPaintInfo() { pFrm = 0; pWrongList = 0; pSpaceAdd = 0; pBrushItem = 0; }
+#else
+    SwTxtPaintInfo() { pFrm = 0; pWrongList = 0; pSpaceAdd = 0;
+                       pBrushItem = ((SvxBrushItem*)-1); }
+#endif
+public:
+    SwTxtPaintInfo( const SwTxtPaintInfo &rInf );
+    SwTxtPaintInfo( const SwTxtPaintInfo &rInf, const XubString &rTxt );
+
+    void CtorInit( SwTxtFrm *pFrame, const SwRect &rPaint );
+
+    void SetBack( const SvxBrushItem *pItem,
+                  const SwRect &rRect ) { pBrushItem = pItem; aItemRect = rRect;}
+    const SvxBrushItem *GetBrushItem() const { return pBrushItem; }
+    const SwRect       &GetBrushRect() const { return aItemRect;  }
+
+    inline SwTxtPaintInfo( SwTxtFrm *pFrame, const SwRect &rPaint )
+           { CtorInit( pFrame, rPaint ); }
+
+    inline SwTwips X() const { return aPos.X(); }
+    inline void X( const long nNew ) { aPos.X() = nNew; }
+    inline SwTwips Y() const { return aPos.Y(); }
+    inline void Y( const SwTwips nNew ) { aPos.Y() = nNew; }
+
+    inline SwTxtFly *GetTxtFly() { return &aTxtFly; }
+    inline const SwTxtFly *GetTxtFly() const { return &aTxtFly; }
+    inline void DrawText( const XubString &rText, const SwLinePortion &rPor,
+                          const xub_StrLen nIdx = 0,
+                          const xub_StrLen nLen = STRING_LEN,
+                          const sal_Bool bKern = sal_False) const;
+    inline void DrawText( const SwLinePortion &rPor, const xub_StrLen nLen,
+                          const sal_Bool bKern = sal_False ) const;
+    inline void DrawWrongText( const SwLinePortion &rPor, const xub_StrLen nLen,
+                          const sal_Bool bKern = sal_False ) const;
+    void DrawRect( const SwRect &rRect, sal_Bool bNoGraphic = sal_False,
+                   sal_Bool bRetouche = sal_True ) const;
+    void DrawRect( const SwLinePortion &rPor ) const;
+    void DrawTab( const SwLinePortion &rPor ) const;
+    void DrawLineBreak( const SwLinePortion &rPor ) const;
+    void DrawPostIts( const SwLinePortion &rPor, sal_Bool bScript ) const;
+    void DrawBackground( const SwLinePortion &rPor ) const;
+    void DrawViewOpt( const SwLinePortion &rPor, const MSHORT nWhich ) const;
+    inline void DrawBackBrush( const SwLinePortion &rPor ) const
+        { if( pFnt->GetBackColor() ) _DrawBackBrush( rPor ); }
+
+    inline void NotifyURL( const SwLinePortion &rPor ) const
+        { if( URLNotify() ) _NotifyURL( rPor ); }
+
+    inline SwTwips GetPaintOfst() const;
+    inline void SetPaintOfst( const SwTwips nNew );
+    inline const Point &GetPos() const { return aPos; }
+    inline void SetPos( const Point &rNew ) { aPos = rNew; }
+
+    inline const SwRect &GetPaintRect() const { return aPaintRect; }
+    inline void SetPaintRect( const SwRect &rNew ) { aPaintRect = rNew; }
+
+    friend SvStream &operator<<( SvStream &rOS, const SwTxtPaintInfo &rInf );
+
+    inline const MSHORT GetSpaceIdx() const { return nSpaceIdx; }
+    inline void ResetSpaceIdx(){nSpaceIdx = 0; }
+    inline void IncSpaceIdx() { ++nSpaceIdx; }
+    inline void SetSpaceAdd( SvShorts *pNew ){ pSpaceAdd = pNew; }
+    inline SvShorts* GetpSpaceAdd() const { return pSpaceAdd; }
+    inline const short GetSpaceAdd() const
+        { return ( pSpaceAdd && nSpaceIdx < pSpaceAdd->Count() )
+                   ? (*pSpaceAdd)[nSpaceIdx] : 0; }
+    inline void SetWrongList( SwWrongList *pNew ){ pWrongList = pNew; }
+    inline SwWrongList* GetpWrongList() const { return pWrongList; }
+
+};
+
+/*************************************************************************
+ *                      class SwTxtFormatInfo
+ *************************************************************************/
+
+class SwTxtFormatInfo : public SwTxtPaintInfo
+{
+    SwLineLayout    *pRoot;       // die Root der aktuellen Zeile (pCurr)
+    SwLinePortion   *pLast;       // die letzte Portion
+    SwFlyPortion    *pFly;        // die nachfolgende FlyPortion
+    SwFldPortion    *pLastFld;    // umgebrochenes Feld
+    SwLinePortion   *pUnderFlow;  // Unterlaufsituation: letzte Portion
+    SwLinePortion   *pRest;       // Rest ist der Beginn der naechsten Zeile
+
+    SwTabPortion    *pLastTab;     // die _letzte_ TabPortion
+
+    xub_StrLen nSoftHyphPos;    // SoftHyphPos fuer Hyphenate
+    xub_StrLen nHyphStart;      // TxtPos, an der die interakt.Tr.z.Z. steht
+    xub_StrLen nHyphWrdStart;   // gefundene Wort-Position
+    xub_StrLen nHyphWrdLen;     // gefundene Wort-Laenge
+    xub_StrLen nLineStart;      // aktueller Zeilenbeginn im rTxt
+    KSHORT nLeft;           // linker Rand
+    KSHORT nRight;          // rechter Rand
+    KSHORT nFirst;          // EZE
+    KSHORT nRealWidth;      // "echte" Zeilenbreite
+    KSHORT nWidth;          // "virtuelle" Zeilenbreite
+    KSHORT nLineHeight;     // endgueltige Hoehe nach CalcLine
+    KSHORT nForcedLeftMargin;   // Verschiebung des linken Rands wg. Rahmen
+
+    INT16  nMinLeading;     // minimum number of chars before hyphenation point
+    INT16  nMinTrailing;    // minimum number of chars after hyphenation point
+    INT16  nMinWordLength;  // minimum length of word to be hyphenated
+    sal_Bool bRestoreHyphOptions : 1;
+    sal_Bool bFull   : 1;      // Zeile ist voll
+    sal_Bool bFtnDone  : 1;    // Ftn bereits formatiert
+    sal_Bool bErgoDone : 1;    // ErgoDone bereits formatiert
+    sal_Bool bNumDone  : 1;    // bNumDone bereits formatiert
+    sal_Bool bStop   : 1;      // Sofort abbrechen, Zeile verwerfen.
+    sal_Bool bNewLine  : 1;    // Noch eine weitere Zeile formatieren.
+    sal_Bool bShift  : 1;      // Positionsaend.: Repaint bis auf Weiteres
+    sal_Bool bUnderFlow : 1;       // Kontext: UnderFlow() ?
+    sal_Bool bInterHyph: 1;    // interaktive Trennung ?
+    sal_Bool bAutoHyph : 1;    // automatische Trennung ?
+    sal_Bool bDropInit : 1;    // DropWidth einstellen.
+    sal_Bool bQuick  : 1;      // FormatQuick()
+    sal_Bool bNoEndHyph  : 1;  // Trennung am Zeilenende abgeschaltet wg. MaxHyphens
+    sal_Bool bNoMidHyph  : 1;  // Trennung vor Flies abgeschaltet wg. MaxHyphens
+    sal_Bool bIgnoreFly: 1;    // FitToContent ignoriert Flies
+
+    xub_Unicode   cTabDecimal;  // das _aktuelle_ Dezimalzeichen
+    xub_Unicode   cHookChar;    // fuer Tabs in Feldern etc.
+    sal_uInt8   nMaxHyph;       // max. Zeilenanz. aufeinanderfolg. Trenn.
+    sal_Bool   bTestFormat;     // Testformatierung aus WouldFit, keine Benachrichtigungen etc.
+
+    // Hyphenating ...
+    sal_Bool InitHyph( const sal_Bool bAuto = sal_False );
+    sal_Bool _CheckFtnPortion( SwLineLayout* pCurr );
+
+public:
+    void CtorInit( SwTxtFrm *pFrm,
+                   const sal_Bool bInterHyph = sal_False, const sal_Bool bQuick = sal_False, const sal_Bool bTst = sal_False );
+    inline SwTxtFormatInfo( SwTxtFrm *pFrame, const sal_Bool bInterHyph = sal_False, const sal_Bool bQuick = sal_False,
+            const sal_Bool bTst = sal_False )
+           { CtorInit( pFrame, bInterHyph, bQuick, bTst ); }
+
+    inline KSHORT Width() const { return nWidth; }
+    inline void Width( const KSHORT nNew ) { nWidth = nNew; }
+           void Init();
+
+    // liefert die erste veraenderte Position im Absatz zurueck
+    inline xub_StrLen GetReformatStart() const;
+
+    // Raender
+    inline KSHORT Left() const { return nLeft; }
+    inline void Left( const KSHORT nNew ) { nLeft = nNew; }
+    inline KSHORT Right() const { return nRight; }
+    inline void Right( const KSHORT nNew ) { nRight = nNew; }
+    inline KSHORT First() const { return nFirst; }
+    inline void First( const KSHORT nNew ) { nFirst = nNew; }
+    inline KSHORT CurrLeft() const { return (nLineStart ? nLeft : nFirst); }
+    inline KSHORT RealWidth() const { return nRealWidth; }
+    inline void RealWidth( const KSHORT nNew ) { nRealWidth = nNew; }
+    inline KSHORT ForcedLeftMargin() const { return nForcedLeftMargin; }
+    inline void ForcedLeftMargin( const KSHORT nN ) { nForcedLeftMargin = nN; }
+
+    inline sal_uInt8 &MaxHyph() { return nMaxHyph; }
+    inline const sal_uInt8 &MaxHyph() const { return nMaxHyph; }
+
+    inline SwLineLayout *GetRoot() { return pRoot; }
+    inline const SwLineLayout *GetRoot() const { return pRoot; }
+
+    inline void SetRoot( SwLineLayout *pNew ) { pRoot = pNew; }
+    inline SwLinePortion *GetLast() { return pLast; }
+    inline void SetLast( SwLinePortion *pNewLast ) { pLast = pNewLast; }
+    inline sal_Bool IsFull() const { return bFull; }
+    inline void SetFull( const sal_Bool bNew ) { bFull = bNew; }
+    inline sal_Bool IsHyphForbud() const
+        { return pFly ? bNoMidHyph : bNoEndHyph; }
+    inline void SetHyphForbud( const sal_Bool bNew )
+        { if ( pFly ) bNoMidHyph = bNew; else bNoEndHyph = bNew; }
+    inline void ChkNoHyph( const sal_uInt8 bEnd, const sal_uInt8 bMid )
+        { bNoEndHyph = (nMaxHyph && bEnd >= nMaxHyph);
+          bNoMidHyph = (nMaxHyph && bMid >= nMaxHyph); }
+    inline sal_Bool IsIgnoreFly() const { return bIgnoreFly; }
+    inline void SetIgnoreFly( const sal_Bool bNew ) { bIgnoreFly = bNew; }
+    inline sal_Bool IsStop() const { return bStop; }
+    inline void SetStop( const sal_Bool bNew ) { bStop = bNew; }
+    inline SwLinePortion *GetRest() { return pRest; }
+    inline void SetRest( SwLinePortion *pNewRest ) { pRest = pNewRest; }
+    inline sal_Bool IsNewLine() const { return bNewLine; }
+    inline void SetNewLine( const sal_Bool bNew ) { bNewLine = bNew; }
+    inline sal_Bool IsShift() const { return bShift; }
+    inline void SetShift( const sal_Bool bNew ) { bShift = bNew; }
+    inline sal_Bool IsInterHyph() const { return bInterHyph; }
+    inline sal_Bool IsAutoHyph() const { return bAutoHyph; }
+    inline sal_Bool IsUnderFlow() const { return bUnderFlow; }
+    inline void ClrUnderFlow() { bUnderFlow = sal_False; }
+    inline sal_Bool IsDropInit() const { return bDropInit; }
+    inline void SetDropInit( const sal_Bool bNew ) { bDropInit = bNew; }
+    inline sal_Bool IsQuick() const { return bQuick; }
+    inline sal_Bool IsTest() const { return bTestFormat; }
+
+    inline xub_StrLen GetLineStart() const { return nLineStart; }
+    inline void SetLineStart( const xub_StrLen nNew ) { nLineStart = nNew; }
+    inline KSHORT GetLineHeight() const { return nLineHeight; }
+    inline void SetLineHeight( const KSHORT nNew ) { nLineHeight = nNew; }
+
+    inline const SwLinePortion *GetUnderFlow() const { return pUnderFlow; }
+    inline SwLinePortion *GetUnderFlow() { return pUnderFlow; }
+    inline void SetUnderFlow( SwLinePortion *pNew )
+           { pUnderFlow = pNew; bUnderFlow = sal_True; }
+    inline xub_StrLen GetSoftHyphPos() const { return nSoftHyphPos; }
+    inline void SetSoftHyphPos( const xub_StrLen nNew ) { nSoftHyphPos = nNew; }
+
+    inline void SetParaFtn();
+
+    // FlyFrms
+    inline SwFlyPortion *GetFly() { return pFly; }
+    inline void SetFly( SwFlyPortion *pNew ) { pFly = pNew; }
+
+    inline const SwAttrSet& GetCharAttr() const;
+
+    // Tabs
+    inline SwTabPortion *GetLastTab() { return pLastTab; }
+    inline void SetLastTab( SwTabPortion *pNew ) { pLastTab = pNew; }
+    inline xub_Unicode GetTabDecimal() const { return cTabDecimal; }
+    inline void SetTabDecimal( const xub_Unicode cNew ) { cTabDecimal = cNew;}
+
+    // Last*
+    inline SwFldPortion *GetLastFld() { return pLastFld; }
+    inline void SetLastFld( SwFldPortion *pNew ) { pLastFld = pNew; }
+
+    inline void ClearHookChar() { cHookChar = 0; }
+    inline void SetHookChar( const xub_Unicode cNew ) { cHookChar = cNew; }
+    inline xub_Unicode GetHookChar() const { return cHookChar; }
+
+    // Done-Flags
+    inline sal_Bool IsFtnDone() const { return bFtnDone; }
+    inline void SetFtnDone( const sal_Bool bNew ) { bFtnDone = bNew; }
+    inline sal_Bool IsErgoDone() const { return bErgoDone; }
+    inline void SetErgoDone( const sal_Bool bNew ) { bErgoDone = bNew; }
+    inline sal_Bool IsNumDone() const { return bNumDone; }
+    inline void SetNumDone( const sal_Bool bNew ) { bNumDone = bNew; }
+    inline sal_Bool IsArrowDone() const { return bArrowDone; }
+    inline void SetArrowDone( const sal_Bool bNew ) { bArrowDone = bNew; }
+    inline sal_Bool IsFtnInside() const { return bFtnInside; }
+    inline void SetFtnInside( const sal_Bool bNew ) { bFtnInside = bNew; }
+
+
+    // Fuer SwTxtPortion::Hyphenate
+    inline sal_Bool IsSoftHyph( const xub_StrLen nPos ) const;
+    sal_Bool ChgHyph( const sal_Bool bNew );
+
+    // Soll die Trennhilfe angeschmissen werden?
+    sal_Bool IsHyphenate() const;
+    inline void SetHyphStart( const xub_StrLen nNew ) { nHyphStart = nNew; }
+    inline xub_StrLen GetHyphStart() const { return nHyphStart; }
+    inline void SetHyphWrdStart( const xub_StrLen nNew ) { nHyphWrdStart = nNew; }
+    inline xub_StrLen GetHyphWrdStart() const { return nHyphWrdStart; }
+    inline void SetHyphWrdLen( const xub_StrLen nNew ) { nHyphWrdLen = nNew; }
+    inline xub_StrLen GetHyphWrdLen() const { return nHyphWrdLen; }
+
+    inline sal_Bool IsRestoreHyphOptions() const    { return bRestoreHyphOptions; }
+    void        RestoreHyphOptions();
+    // ruft HyphenateWord() des Hyphenators
+    ::com::sun::star::uno::Reference< ::com::sun::star::linguistic::XHyphenatedWord>
+        HyphWord( const String &rTxt, const USHORT nMinTrail );
+
+    sal_Bool CheckFtnPortion( SwLineLayout* pCurr )
+        { return IsFtnInside() && _CheckFtnPortion( pCurr ); }
+
+    // Dropcaps vom SwTxtFormatter::CTOR gerufen.
+    const SwFmtDrop *GetDropFmt() const;
+
+    // setzt die FormatInfo wieder in den Anfangszustand
+    void Reset( const SwTxtFrm *pFrame); // , const sal_Bool bAll );
+
+    // Sucht ab nIdx bis nEnd nach Tabs, TabDec, TXTATR und BRK.
+    // Return: gefundene Position, setzt ggf. cHookChar
+    xub_StrLen ScanPortionEnd( const xub_StrLen nEnd, sal_Bool bSkip = sal_False );
+
+//  friend ostream &operator<<( ostream &rOS, const SwTxtFormatInfo &rInf );
+    friend SvStream &operator<<( SvStream &rOS, const SwTxtFormatInfo &rInf );
+};
+
+/*************************************************************************
+ *                      class SwTxtSlot
+ *************************************************************************/
+
+// Fuer die Textersetzung und Restaurierung der SwTxtSizeInfo.
+// Die Art und Weise ist etwas kriminell, rInf ist const und wird
+// trotzdem veraendert. Da rInf im DTOR wieder restauriert wird,
+// ist dies zulaessig, es handelt sich um ein "logisches const".
+// Die beiden Klassen SwTxtSlot und SwTxtSlotLen sind Zwillinge, sie
+// unterscheiden sich nur im Ctor in der Zuweisung der Textlaenge
+// an pInf. Aenderungen muessen in beiden gepflegt werden!
+
+class SwTxtSlot
+{
+    const XubString *pOldTxt;
+    XubString aTxt;
+    xub_StrLen nIdx;
+    xub_StrLen nLen;
+    sal_Bool bOn;
+protected:
+    SwTxtSizeInfo *pInf;
+public:
+    SwTxtSlot( const SwTxtSizeInfo *pNew, const SwLinePortion *pPor );
+    ~SwTxtSlot();
+    inline sal_Bool IsOn() const { return bOn; }
+};
+
+class SwTxtSlotLen
+{
+    const XubString *pOldTxt;
+    XubString aTxt;
+    xub_StrLen nIdx;
+    xub_StrLen nLen;
+    sal_Bool bOn;
+protected:
+    SwTxtSizeInfo *pInf;
+public:
+    // Der Ersetzungstring kommt wahlweise aus der Portion via GetExpText()
+    // oder aus dem char Pointer pCh, wenn dieser ungleich NULL ist.
+    SwTxtSlotLen( const SwTxtSizeInfo *pNew, const SwLinePortion *pPor,
+                  const sal_Char *pCh = NULL );
+    ~SwTxtSlotLen();
+    inline sal_Bool IsOn() const { return bOn; }
+};
+
+/*************************************************************************
+ *                      class SwFontSave
+ *************************************************************************/
+
+class SwFontSave
+{
+    SwTxtSizeInfo *pInf;
+    SwFont        *pFnt;
+    SwFont        *pNewFnt;
+public:
+    SwFontSave( const SwTxtSizeInfo &rInf, SwFont *pFnt );
+   ~SwFontSave();
+};
+
+/*************************************************************************
+ *                      class SwDefFontSave
+ *************************************************************************/
+
+class SwDefFontSave
+{
+    SwTxtSizeInfo *pInf;
+    SwFont        *pFnt;
+    SwFont        *pNewFnt;
+    sal_Bool           bAlter;
+public:
+    SwDefFontSave( const SwTxtSizeInfo &rInf );
+   ~SwDefFontSave();
+    inline sal_Bool IsAlter(){ return bAlter; }
+};
+
+/*************************************************************************
+ *                      class SwFtnSave
+ *************************************************************************/
+
+class SwFtnSave
+{
+    SwTxtSizeInfo *pInf;
+    SwFont       *pFnt;
+    SwFont       *pOld;
+    short        nEsc;
+    sal_uInt8        nPropr;
+public:
+    SwFtnSave( const SwTxtSizeInfo &rInf, const SwTxtFtn *pTxtFtn );
+   ~SwFtnSave();
+};
+
+/*************************************************************************
+ *                       Inline-Implementationen
+ *************************************************************************/
+
+inline KSHORT SwTxtSizeInfo::GetAscent() const
+{
+    return ((SwFont*)GetFont())->GetAscent( pVsh, GetOut() );
+}
+
+inline KSHORT SwTxtSizeInfo::GetTxtHeight() const
+{
+    return ((SwFont*)GetFont())->GetHeight( pVsh, GetOut() );
+}
+
+inline SwPosSize SwTxtSizeInfo::GetTxtSize( const OutputDevice *pOutDev,
+                                     const XubString &rTxt,
+                                     const xub_StrLen nIdx,
+                                     const xub_StrLen nLen ) const
+{
+    return pFnt->_GetTxtSize( pVsh, pOutDev, rTxt, nIdx, nLen );
+}
+
+inline void SwTxtSizeInfo::SetWin( OutputDevice *pNewWin )
+{
+    if( pOut == pWin )
+        pOut = pNewWin;
+    pWin = pNewWin;
+}
+
+inline void SwTxtSizeInfo::SetPrt( OutputDevice *pNewPrt )
+{
+    if( pOut == pPrt )
+        pOut = pNewPrt;
+    pPrt = pNewPrt;
+}
+
+inline SwPosSize SwTxtSizeInfo::GetTxtSize() const
+{
+    return GetTxtSize( pOut, *pTxt, nIdx, nLen );
+}
+
+inline SwPosSize SwTxtSizeInfo::GetTxtSize( const XubString &rTxt ) const
+{
+    return GetTxtSize( pOut, rTxt, 0, rTxt.Len() );
+}
+
+inline SwPosSize SwTxtSizeInfo::GetTxtSize( const xub_StrLen nNewIdx,
+                                            const xub_StrLen nNewLen ) const
+{
+    return GetTxtSize( pOut, *pTxt, nNewIdx, nNewLen );
+}
+
+inline xub_StrLen SwTxtSizeInfo::GetTxtBreak( long nTxtWidth,
+                const xub_StrLen nNewIdx, const xub_StrLen nNewLen ) const
+{
+    return pFnt->GetTxtBreak( pVsh, pOut, *pTxt, nTxtWidth, nNewIdx, nNewLen );
+}
+
+inline xub_StrLen SwTxtSizeInfo::GetTxtBreak( long nTxtWidth, const xub_StrLen
+        nNewIdx, const xub_StrLen nNewLen, xub_StrLen& rExtraCharPos ) const
+{
+    return pFnt->GetTxtBreak( pVsh, pOut, *pTxt, nTxtWidth, rExtraCharPos,
+        nNewIdx, nNewLen );
+}
+
+inline SwTwips SwTxtPaintInfo::GetPaintOfst() const
+{
+    return GetParaPortion()->GetRepaint()->GetOfst();
+}
+
+inline void SwTxtPaintInfo::SetPaintOfst( const SwTwips nNew )
+{
+    GetParaPortion()->GetRepaint()->SetOfst( nNew );
+}
+
+
+inline void SwTxtPaintInfo::DrawText( const XubString &rText,
+                            const SwLinePortion &rPor,
+                            const xub_StrLen nStart, const xub_StrLen nLen,
+                            const sal_Bool bKern ) const
+{
+    ((SwTxtPaintInfo*)this)->_DrawText( rText, rPor, nStart, nLen, bKern );
+}
+
+inline void SwTxtPaintInfo::DrawText( const SwLinePortion &rPor,
+        const xub_StrLen nLen, const sal_Bool bKern ) const
+{
+    ((SwTxtPaintInfo*)this)->_DrawText( *pTxt, rPor, nIdx, nLen, bKern );
+}
+
+inline void SwTxtPaintInfo::DrawWrongText( const SwLinePortion &rPor,
+                                const xub_StrLen nLen, const sal_Bool bKern ) const
+{
+    ((SwTxtPaintInfo*)this)->_DrawText( *pTxt, rPor, nIdx, nLen, bKern, sal_True );
+}
+
+inline xub_StrLen SwTxtFormatInfo::GetReformatStart() const
+{
+    return GetParaPortion()->GetReformat()->Start();
+}
+
+inline const SwAttrSet& SwTxtFormatInfo::GetCharAttr() const
+{
+    return GetTxtFrm()->GetTxtNode()->GetSwAttrSet();
+}
+
+inline void SwTxtFormatInfo::SetParaFtn()
+{
+    GetTxtFrm()->SetFtn( sal_True );
+}
+
+inline sal_Bool SwTxtFormatInfo::IsSoftHyph( const xub_StrLen nPos ) const
+{
+    return CHAR_SOFTHYPHEN == GetTxtFrm()->GetTxtNode()->GetTxt().GetChar(nPos);
+}
+
+
+
+#endif
+
diff --git a/sw/source/core/text/itradj.cxx b/sw/source/core/text/itradj.cxx
new file mode 100644
index 000000000000..6d247d5f8cc7
--- /dev/null
+++ b/sw/source/core/text/itradj.cxx
@@ -0,0 +1,578 @@
+/*************************************************************************
+ *
+ *  $RCSfile: itradj.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "frame.hxx"       // CalcFlyAdjust()
+#include "paratr.hxx"
+#ifdef DEBUG
+# include "ndtxt.hxx"        // pSwpHints, Ausgabeoperator
+#endif
+#include "segmentc.hxx"
+
+#include "txtcfg.hxx"
+#include "itrtxt.hxx"
+#include "porglue.hxx"
+#include "porlay.hxx"
+#include "porfly.hxx"       // CalcFlyAdjust()
+#include "pordrop.hxx"       // CalcFlyAdjust()
+
+
+/*************************************************************************
+ *                    SwTxtAdjuster::FormatBlock()
+ *************************************************************************/
+
+void SwTxtAdjuster::FormatBlock( )
+{
+    // In der letzten Zeile gibt's keinen Blocksatz.
+    // Und bei Tabulatoren aus Tradition auch nicht.
+    // 7701: wenn Flys im Spiel sind, geht's weiter
+
+    const SwLinePortion *pFly = 0;
+
+    sal_Bool bSkip = !IsLastBlock() &&
+        nStart + pCurr->GetLen() >= GetInfo().GetTxt().Len();
+
+    // ????: mehrzeilige Felder sind fies: wir muessen kontrollieren,
+    // ob es noch andere Textportions im Absatz gibt.
+    if( bSkip )
+    {
+        const SwLineLayout *pLay = pCurr->GetNext();
+        while( pLay && !pLay->GetLen() )
+        {
+            const SwLinePortion *pPor = pCurr->GetFirstPortion();
+            while( pPor && bSkip )
+            {
+                if( pPor->InTxtGrp() )
+                    bSkip = sal_False;
+                pPor = pPor->GetPortion();
+            }
+            pLay = bSkip ? pLay->GetNext() : 0;
+        }
+    }
+
+    if( bSkip )
+    {
+        if( !GetInfo().GetParaPortion()->HasFly() )
+        {
+            if( IsLastCenter() )
+                CalcFlyAdjust( pCurr );
+            pCurr->FinishSpaceAdd();
+            return;
+        }
+        else
+        {
+            const SwLinePortion *pTmpFly = NULL;
+
+            // 7701: beim letzten Fly soll Schluss sein
+            const SwLinePortion *pPos = pCurr->GetFirstPortion();
+            while( pPos )
+            {
+                // Ich suche jetzt den letzten Fly, hinter dem noch Text ist:
+                if( pPos->IsFlyPortion() )
+                    pTmpFly = pPos; // Ein Fly wurde gefunden
+                else if ( pTmpFly && pPos->InTxtGrp() )
+                {
+                    pFly = pTmpFly; // Ein Fly mit nachfolgendem Text!
+                    pTmpFly = NULL;
+                }
+                pPos = pPos->GetPortion();
+            }
+            // 8494: Wenn keiner gefunden wurde, ist sofort Schluss!
+            if( !pFly )
+            {
+                if( IsLastCenter() )
+                    CalcFlyAdjust( pCurr );
+                pCurr->FinishSpaceAdd();
+                return;
+            }
+        }
+    }
+
+    const nOldIdx = GetInfo().GetIdx();
+    GetInfo().SetIdx( nStart );
+    CalcNewBlock( pCurr, pFly );
+    GetInfo().SetIdx( nOldIdx );
+    GetInfo().GetParaPortion()->GetRepaint()->SetOfst(0);
+}
+
+/*************************************************************************
+ *                    SwTxtAdjuster::CalcBlockAdjust()
+ *
+ * CalcBlockAdjust() darf erst nach CalcLine() gerufen werden !
+ * Aufgespannt wird immer zwischen zwei RandPortions oder FixPortions
+ * (Tabs und Flys). Dabei werden die Glues gezaehlt und ExpandBlock gerufen.
+ *************************************************************************/
+
+void SwTxtAdjuster::CalcNewBlock( SwLineLayout *pCurr,
+                                  const SwLinePortion *pStopAt )
+{
+    ASSERT( SVX_ADJUST_BLOCK == GetAdjust(), "CalcNewBlock: Why?" );
+    ASSERT( pCurr->Height(), "SwTxtAdjuster::CalcBlockAdjust: missing CalcLine()" );
+
+    pCurr->InitSpaceAdd();
+    MSHORT nNull = 0;
+    xub_StrLen nGluePortion = 0;
+    xub_StrLen nCharCnt = 0;
+    MSHORT nSpaceIdx = 0;
+
+    // Nicht vergessen:
+    // CalcRightMargin() setzt pCurr->Width() auf die Zeilenbreite !
+    CalcRightMargin( pCurr );
+
+    SwLinePortion *pPos = pCurr->GetPortion();
+
+    while( pPos )
+    {
+        if ( pPos->IsBreakPortion() && !IsLastBlock() )
+        {
+            pCurr->FinishSpaceAdd();
+            break;
+        }
+        if ( pPos->InTxtGrp() )
+            nGluePortion += ((SwTxtPortion*)pPos)->GetSpaceCnt( GetInfo(), nCharCnt );
+
+        if( pPos->InGlueGrp() )
+        {
+            if( pPos->InFixMargGrp() )
+            {
+                if ( nSpaceIdx == pCurr->GetSpaceAdd().Count() )
+                    pCurr->GetSpaceAdd().Insert( nNull, nSpaceIdx );
+                if( nGluePortion )
+                {
+                    ( pCurr->GetSpaceAdd() )[nSpaceIdx] =
+                         ( (SwGluePortion*)pPos )->GetPrtGlue() / nGluePortion;
+                    pPos->Width( ( (SwGluePortion*)pPos )->GetFixWidth() );
+                }
+                else if ( IsOneBlock() && nCharCnt > 1 )
+                {
+                    ( pCurr->GetSpaceAdd() )[nSpaceIdx] =
+                        - ( (SwGluePortion*)pPos )->GetPrtGlue() / (nCharCnt-1);
+                    pPos->Width( ( (SwGluePortion*)pPos )->GetFixWidth() );
+                }
+                nSpaceIdx++;
+                nGluePortion = 0;
+                nCharCnt = 0;
+            }
+            else
+                ++nGluePortion;
+        }
+        GetInfo().SetIdx( GetInfo().GetIdx() + pPos->GetLen() );
+        if ( pPos == pStopAt )
+        {
+            if ( nSpaceIdx == pCurr->GetSpaceAdd().Count() )
+                pCurr->GetSpaceAdd().Insert( nNull, nSpaceIdx );
+            else
+                pCurr->GetSpaceAdd()[nSpaceIdx] = 0;
+            break;
+        }
+        pPos = pPos->GetPortion();
+    }
+}
+
+/*************************************************************************
+ *                    SwTxtAdjuster::CalcRightMargin()
+ *************************************************************************/
+
+SwMarginPortion *SwTxtAdjuster::CalcRightMargin( SwLineLayout *pCurr )
+{
+    const long nRealWidth = GetLineWidth();
+    const long nHeight = GetLineHeight();
+    KSHORT nPrtWidth = pCurr->PrtWidth();
+
+    SwLinePortion *pLast = pCurr->FindLastPortion();
+
+    // Fuer jeden FlyFrm, der in den rechten Rand hineinragt,
+    // wird eine FlyPortion angelegt.
+    const long nLeftMar = GetLeftMargin();
+    SwRect aCurrRect( nLeftMar + nPrtWidth, Y(),
+                      nRealWidth - nPrtWidth, nHeight );
+
+    SwFlyPortion *pFly = CalcFlyPortion( nRealWidth, aCurrRect );
+    while( pFly && long( nPrtWidth )< nRealWidth )
+    {
+        pLast->Append( pFly );
+        pLast = pFly;
+        if( pFly->Fix() > nPrtWidth )
+            pFly->Width( ( pFly->Fix() - nPrtWidth) + pFly->Width() + 1);
+        nPrtWidth += pFly->Width() + 1;
+        aCurrRect.Left( nLeftMar + nPrtWidth );
+        pFly = CalcFlyPortion( nRealWidth, aCurrRect );
+    }
+    if( pFly )
+        delete pFly;
+
+    SwMarginPortion *pRight = new SwMarginPortion( 0 );
+    pLast->Append( pRight );
+
+    if( long( nPrtWidth )< nRealWidth )
+        pRight->PrtWidth( KSHORT( nRealWidth - nPrtWidth ) );
+
+    // pCurr->Width() wird auf die reale Groesse gesetzt,
+    // da jetzt die MarginPortions eingehaengt sind.
+    // Dieser Trick hat wundersame Auswirkungen.
+    // Wenn pCurr->Width() == nRealWidth ist, dann wird das gesamte
+    // Adjustment implizit ausgecontert. GetLeftMarginAdjust() und
+    // IsBlocksatz() sind der Meinung, sie haetten eine mit Zeichen
+    // gefuellte Zeile.
+
+    pCurr->PrtWidth( KSHORT( nRealWidth ) );
+    return pRight;
+}
+
+/*************************************************************************
+ *                    SwTxtAdjuster::CalcFlyAdjust()
+ *************************************************************************/
+
+void SwTxtAdjuster::CalcFlyAdjust( SwLineLayout *pCurr )
+{
+    const SwRect aLineRect( GetLeftMargin(), Y(),
+                            ((SwFrm*)pFrm)->Prt().Width(), GetLineHeight() );
+    // 1) Es wird ein linker Rand eingefuegt:
+    SwMarginPortion *pLeft = pCurr->CalcLeftMargin();
+    SwGluePortion *pGlue = pLeft;       // die letzte GluePortion
+
+
+    // 2) Es wird ein rechter Rand angehaengt:
+    // CalcRightMargin berechnet auch eventuelle Ueberlappungen mit
+    // FlyFrms.
+    CalcRightMargin( pCurr );
+
+#ifdef USED
+    pCurr->PackFlys();
+#endif
+
+    SwLinePortion *pPos = pLeft->GetPortion();
+    xub_StrLen nLen = 0;
+
+    // Wenn wir nur eine Zeile vorliegen haben und die Textportion zusammen
+    // haengend ist und wenn zentriert wird, dann ...
+
+    sal_Bool bComplete = 0 == nStart;
+
+    while( pPos )
+    {
+        if( pPos->InFixMargGrp() )
+        {
+            if( SVX_ADJUST_RIGHT == GetAdjust() )
+            {
+                ((SwGluePortion*)pPos)->MoveAllGlue( pGlue );
+            }
+            else
+            {
+                // Eine schlaue Idee von MA:
+                // Fuer die erste Textportion wird rechtsbuendig eingestellt,
+                // fuer die letzte linksbuendig.
+
+                // Die erste Textportion kriegt den ganzen Glue
+                // Aber nur, wenn wir mehr als eine Zeile besitzen.
+                if( bComplete && GetInfo().GetTxt().Len() == nLen )
+                {
+                    ((SwGluePortion*)pPos)->MoveHalfGlue( pGlue );
+                }
+                else
+                {
+                    if( pLeft == pGlue )
+                    {
+                        // Wenn es nur einen linken und rechten Rand gibt,
+                        // dann teilen sich die Raender den Glue.
+                        if( nLen + pPos->GetLen() >= pCurr->GetLen() )
+                            ((SwGluePortion*)pPos)->MoveHalfGlue( pGlue );
+                        else
+                            ((SwGluePortion*)pPos)->MoveAllGlue( pGlue );
+                    }
+                    else
+                    {
+                        // Die letzte Textportion behaelt sein Glue
+                        if( !pPos->IsMarginPortion() )
+                            ((SwGluePortion*)pPos)->MoveHalfGlue( pGlue );
+                    }
+                }
+            }
+            pGlue = (SwFlyPortion*)pPos;
+            bComplete = sal_False;
+        }
+        nLen += pPos->GetLen();
+        pPos = pPos->GetPortion();
+    }
+
+    if( SVX_ADJUST_RIGHT == GetAdjust() )
+        pLeft->AdjustRight();
+
+#ifdef DEBUG
+    // um einen Breakpoint setzen zu koennen:
+    nLen = 0;
+#endif
+}
+
+/*************************************************************************
+ *                  SwTxtAdjuster::CalcAdjLine()
+ *************************************************************************/
+
+void SwTxtAdjuster::CalcAdjLine( SwLineLayout *pCurr )
+{
+    ASSERT( pCurr->IsFormatAdj(), "CalcAdjLine: Why?" );
+
+    pCurr->SetFormatAdj(sal_False);
+    switch( GetAdjust() )
+    {
+        case SVX_ADJUST_RIGHT:
+        case SVX_ADJUST_CENTER:
+        {
+            CalcFlyAdjust( pCurr );
+            GetInfo().GetParaPortion()->GetRepaint()->SetOfst( 0 );
+            break;
+        }
+        case SVX_ADJUST_BLOCK:
+        {
+            // 8311: In Zeilen mit LineBreaks gibt es keinen Blocksatz!
+            if( pCurr->GetLen() &&
+                CH_BREAK == GetInfo().GetChar( nStart + pCurr->GetLen() - 1 ) &&
+                !IsLastBlock() )
+            {
+                if( IsLastCenter() )
+                {
+                    CalcFlyAdjust( pCurr );
+                    GetInfo().GetParaPortion()->GetRepaint()->SetOfst( 0 );
+                    break;
+                }
+                return;
+            }
+            FormatBlock();
+            break;
+        }
+        default : return;
+    }
+
+#ifdef DEBUG
+/*
+    if( OPTDBG( *pInf ) )
+    {
+        pCurr->DebugPortions( aDbstream, pInf->GetTxt(), nStart );
+        if( GetHints() )
+        {
+            const SwpHints &rHt = *GetHints();
+            aDbstream << rHt;
+            SwAttrIter::Dump( aDbstream );
+        }
+    }
+ */
+#endif
+}
+
+/*************************************************************************
+ *                    SwTxtAdjuster::CalcFlyPortion()
+ *
+ * Die Berechnung hat es in sich: nCurrWidth geibt die Breite _vor_ dem
+ * aufaddieren des Wortes das noch auf die Zeile passt! Aus diesem Grund
+ * stimmt die Breite der FlyPortion auch, wenn die Blockierungssituation
+ * bFirstWord && !WORDFITS eintritt.
+ *************************************************************************/
+
+SwFlyPortion *SwTxtAdjuster::CalcFlyPortion( const long nRealWidth,
+                                             const SwRect &rCurrRect )
+{
+    SwTxtFly aTxtFly( (SwCntntFrm*)GetTxtFrm() );
+
+    const KSHORT nCurrWidth = pCurr->PrtWidth();
+    SwFlyPortion *pFlyPortion = 0;
+    // aFlyRect ist dokumentglobal !
+
+    SwRect aFlyRect( aTxtFly.GetFrm( rCurrRect ) );
+
+    // Wenn ein Frame ueberlappt, wird eine Portion eroeffnet.
+    if( aFlyRect.HasArea() )
+    {
+        // aLocal ist framelokal
+        SwRect aLocal( aFlyRect );
+        aLocal.Pos( aLocal.Left() - GetLeftMargin(), aLocal.Top() );
+        if( nCurrWidth > KSHORT( aLocal.Left() ) )
+            aLocal.Left( nCurrWidth );
+
+        // Wenn das Rechteck breiter als die Zeile ist, stutzen
+        // wir es ebenfalls zurecht.
+        KSHORT nLocalWidth = KSHORT( aLocal.Left() + aLocal.Width() );
+        if( nRealWidth < long( nLocalWidth ) )
+            aLocal.Width( nRealWidth - aLocal.Left() );
+        GetInfo().GetParaPortion()->SetFly( sal_True );
+        pFlyPortion = new SwFlyPortion( aLocal );
+        pFlyPortion->Height( KSHORT( rCurrRect.Height() ) );
+        // Die Width koennte kleiner sein als die FixWidth, daher:
+        pFlyPortion->AdjFixWidth();
+    }
+    return pFlyPortion;
+}
+
+/*************************************************************************
+ *                SwTxtPainter::_CalcDropAdjust()
+ *************************************************************************/
+
+// 6721: Drops und Adjustment
+// CalcDropAdjust wird ggf. am Ende von Format() gerufen.
+
+void SwTxtAdjuster::CalcDropAdjust()
+{
+    ASSERT( 1IsDummy() || NextLine() )
+    {
+        // Erst adjustieren.
+        GetAdjusted();
+
+        SwLinePortion *pPor = pCurr->GetFirstPortion();
+
+        // 2) Sicherstellen, dass die DropPortion dabei ist.
+        // 3) pLeft: Die GluePor vor der DropPor
+        if( pPor->InGlueGrp() && pPor->GetPortion()
+              && pPor->GetPortion()->IsDropPortion() )
+        {
+            const SwLinePortion *pDropPor = (SwDropPortion*) pPor->GetPortion();
+            SwGluePortion *pLeft = (SwGluePortion*) pPor;
+
+            // 4) pRight: Die GluePor hinter der DropPor suchen
+            pPor = pPor->GetPortion();
+            while( pPor && !pPor->InFixMargGrp() )
+                pPor = pPor->GetPortion();
+
+            SwGluePortion *pRight = ( pPor && pPor->InGlueGrp() ) ?
+                                    (SwGluePortion*) pPor : 0;
+            if( pRight && pRight != pLeft )
+            {
+                // 5) nMinLeft berechnen. Wer steht am weitesten links?
+                const KSHORT nDropLineStart =
+                    KSHORT(GetLineStart()) + pLeft->Width() + pDropPor->Width();
+                KSHORT nMinLeft = nDropLineStart;
+                for( MSHORT i = 1; i < GetDropLines(); ++i )
+                {
+                    if( NextLine() )
+                    {
+                        // Erst adjustieren.
+                        GetAdjusted();
+
+                        pPor = pCurr->GetFirstPortion();
+                        const SwMarginPortion *pMar = pPor->IsMarginPortion() ?
+                                                      (SwMarginPortion*)pPor : 0;
+                        if( !pMar )
+                            nMinLeft = 0;
+                        else
+                        {
+                            const KSHORT nLineStart =
+                                KSHORT(GetLineStart()) + pMar->Width();
+                            if( nMinLeft > nLineStart )
+                                nMinLeft = nLineStart;
+                        }
+                    }
+                }
+
+                // 6) Den Glue zwischen pLeft und pRight neu verteilen.
+                if( nMinLeft < nDropLineStart )
+                {
+                    // Glue wird immer von pLeft nach pRight abgegeben,
+                    // damit der Text nach links wandert.
+                    const short nGlue = nDropLineStart - nMinLeft;
+                    if( !nMinLeft )
+                        pLeft->MoveAllGlue( pRight );
+                    else
+                        pLeft->MoveGlue( pRight, nGlue );
+#ifdef DBGTXT
+                    aDbstream << "Drop adjusted: " << nGlue << endl;
+#endif
+                }
+            }
+        }
+    }
+
+    if( nLineNr != GetLineNr() )
+    {
+        Top();
+        while( nLineNr != GetLineNr() && Next() )
+            ;
+    }
+}
+
+/*************************************************************************
+ *                SwTxtAdjuster::CalcDropRepaint()
+ *************************************************************************/
+
+void SwTxtAdjuster::CalcDropRepaint()
+{
+    Top();
+    SwRepaint &rRepaint = *GetInfo().GetParaPortion()->GetRepaint();
+    if( rRepaint.Top() > Y() )
+        rRepaint.Top( Y() );
+    for( MSHORT i = 1; i < GetDropLines(); ++i )
+        NextLine();
+    const SwTwips nBottom = Y() + GetLineHeight() - 1;
+    if( rRepaint.Bottom() < nBottom )
+        rRepaint.Bottom( nBottom );
+}
+
+
diff --git a/sw/source/core/text/itratr.cxx b/sw/source/core/text/itratr.cxx
new file mode 100644
index 000000000000..1fe21f20d74c
--- /dev/null
+++ b/sw/source/core/text/itratr.cxx
@@ -0,0 +1,833 @@
+/*************************************************************************
+ *
+ *  $RCSfile: itratr.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _SFX_PRINTER_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _WINDOW_HXX //autogen
+#include 
+#endif
+#ifndef _SV_SVAPP_HXX
+#include 
+#endif
+
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFSIZE_HXX //autogen
+#include 
+#endif
+#ifndef _FMTORNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFLCNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTCNTNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFTN_HXX //autogen
+#include 
+#endif
+#ifndef _FMTHBSH_HXX //autogen
+#include 
+#endif
+#ifndef _FRMATR_HXX
+#include 
+#endif
+#ifndef _FRMFMT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFLD_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _VIEWSH_HXX
+#include    // ViewShell
+#endif
+#ifndef _ROOTFRM_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _DCONTACT_HXX
+#include 
+#endif
+#ifndef _FLDBAS_HXX
+#include       // SwField
+#endif
+#ifndef _PAM_HXX
+#include          // SwPosition        (lcl_MinMaxNode)
+#endif
+#ifndef _TXATBASE_HXX
+#include 
+#endif
+#ifndef _ITRATR_HXX
+#include 
+#endif
+#ifndef _SWFONT_HXX
+#include 
+#endif
+#ifndef _HTMLTBL_HXX
+#include 
+#endif
+#ifndef _SWTABLE_HXX
+#include 
+#endif
+#ifndef _REDLNITR_HXX
+#include 
+#endif
+#ifndef _FMTSRND_HXX
+#include 
+#endif
+
+/*************************************************************************
+ *                      SwAttrIter::Chg()
+ *************************************************************************/
+
+void SwAttrIter::Chg( SwTxtAttr *pHt )
+{
+    if( pRedln && pRedln->IsOn() )
+        pRedln->ChangeTxtAttr( pFnt, *pHt, sal_True );
+    else
+        pHt->ChgFnt( pFnt );
+    nChgCnt++;
+}
+
+/*************************************************************************
+ *                      SwAttrIter::Rst()
+ *************************************************************************/
+
+void SwAttrIter::Rst( SwTxtAttr *pHt )
+{
+    if( pRedln && pRedln->IsOn() )
+        pRedln->ChangeTxtAttr( pFnt, *pHt, sal_False );
+    else
+        pHt->RstFnt( pFnt );
+    nChgCnt--;
+}
+
+/*************************************************************************
+ *              virtual SwAttrIter::~SwAttrIter()
+ *************************************************************************/
+
+SwAttrIter::~SwAttrIter()
+{
+    delete pRedln;
+    delete pFnt;
+}
+
+/*************************************************************************
+ *                      SwAttrIter::GetAttr()
+ *
+ * Liefert fuer eine Position das Attribut, wenn das Attribut genau auf
+ * der Position nPos liegt und kein EndIndex besitzt.
+ * GetAttr() wird fuer Attribute benoetigt, die die Formatierung beeinflussen
+ * sollen, ohne dabei den Inhalt des Strings zu veraendern. Solche "entarteten"
+ * Attribute sind z.B. Felder (die expandierten Text bereit halten) und
+ * zeilengebundene Frames. Um Mehrdeutigkeiten zwischen verschiedenen
+ * solcher Attribute zu vermeiden, werden beim Anlegen eines Attributs
+ * an der Startposition ein Sonderzeichen in den String einfuegt.
+ * Der Formatierer stoesst auf das Sonderzeichen und holt sich per
+ * GetAttr() das entartete Attribut.
+ *************************************************************************/
+
+SwTxtAttr *SwAttrIter::GetAttr( const xub_StrLen nPos ) const
+{
+    if( pHints )
+    {
+        for( MSHORT i = 0; i < pHints->Count(); ++i )
+        {
+            SwTxtAttr *pPos = pHints->GetHt(i);
+            xub_StrLen nStart = *pPos->GetStart();
+            if( nPos < nStart )
+                return 0;
+            if( nPos == nStart && !pPos->GetEnd() )
+                return pPos;
+        }
+    }
+    return 0;
+}
+
+/*************************************************************************
+ *                        SwAttrIter::SeekAndChg()
+ *************************************************************************/
+
+sal_Bool SwAttrIter::SeekAndChg( const xub_StrLen nNewPos, OutputDevice *pOut )
+{
+    sal_Bool bChg = nStartIndex && nNewPos == nPos ? pFnt->IsFntChg() : Seek( nNewPos );
+    if ( pLastOut != pOut )
+    {
+        pLastOut = pOut;
+        pFnt->SetFntChg( sal_True );
+        bChg = sal_True;
+    }
+    if( bChg )
+    {
+        // wenn der Aenderungszaehler auf Null ist, kennen wir die MagicNo
+        // des gewuenschten Fonts ...
+        if ( !nChgCnt )
+            pFnt->SetMagic( pMagicNo, nFntIdx, pFnt->GetActual() );
+        pFnt->ChgPhysFnt( pShell, pOut );
+    }
+    return bChg;
+}
+
+sal_Bool SwAttrIter::IsSymbol( const xub_StrLen nNewPos )
+{
+    Seek( nNewPos );
+    if ( !nChgCnt )
+        pFnt->SetMagic( pMagicNo, nFntIdx, pFnt->GetActual() );
+    return pFnt->IsSymbol( pShell );
+}
+
+/*************************************************************************
+ *                        SwAttrIter::SeekStartAndChg()
+ *************************************************************************/
+
+sal_Bool SwAttrIter::SeekStartAndChg( OutputDevice *pOut, const sal_Bool bParaFont )
+{
+    // Gehe zurueck auf Start ...
+    pFnt->SetFnt( pAttrSet );
+    pFnt->GetTox() = 0;
+    pFnt->GetRef() = 0;
+    nStartIndex = nEndIndex = nPos = nChgCnt = 0;
+    if( pRedln )
+    {
+        pRedln->Clear( pFnt );
+        if( !bParaFont )
+            nChgCnt += pRedln->Seek( *pFnt, 0, STRING_LEN );
+        else
+            pRedln->Reset();
+    }
+
+    if ( pHints && !bParaFont )
+    {
+        SwTxtAttr *pTxtAttr;
+        // Solange wir noch nicht am Ende des StartArrays angekommen sind &&
+        // das TextAttribut an Position 0 beginnt ...
+        while ( ( nStartIndex < pHints->GetStartCount() ) &&
+                !(*(pTxtAttr=pHints->GetStart(nStartIndex))->GetStart()) )
+        {
+            // oeffne die TextAttribute
+            Chg( pTxtAttr );
+            nStartIndex++;
+        }
+    }
+
+    register sal_Bool bChg = pFnt->IsFntChg();
+    if ( pLastOut != pOut )
+    {
+        pLastOut = pOut;
+        pFnt->SetFntChg( sal_True );
+        bChg = sal_True;
+    }
+    if( bChg )
+    {
+        // wenn der Aenderungszaehler auf Null ist, kennen wir die MagicNo
+        // des gewuenschten Fonts ...
+        if ( !nChgCnt )
+            pFnt->SetMagic( pMagicNo, nFntIdx, pFnt->GetActual() );
+        pFnt->ChgPhysFnt( pShell, pOut );
+    }
+    return bChg;
+}
+
+/*************************************************************************
+ *                       SwAttrIter::SeekFwd()
+ *************************************************************************/
+
+// AMA: Neuer AttrIter Nov 94
+
+void SwAttrIter::SeekFwd( const xub_StrLen nNewPos )
+{
+    SwTxtAttr *pTxtAttr;
+
+    if ( nStartIndex ) // wenn ueberhaupt schon Attribute geoeffnet wurden...
+    {
+        // Schliesse Attr, die z. Z. geoeffnet sind, vor nNewPos+1 aber enden.
+
+        // Solange wir noch nicht am Ende des EndArrays angekommen sind &&
+        // das TextAttribut vor oder an der neuen Position endet ...
+        while ( ( nEndIndex < pHints->GetEndCount() ) &&
+                (*(pTxtAttr=pHints->GetEnd(nEndIndex))->GetAnyEnd()<=nNewPos))
+        {
+            // schliesse die TextAttribute, deren StartPos vor
+            // oder an der alten nPos lag, die z.Z. geoeffnet sind.
+            if (*pTxtAttr->GetStart() <= nPos)  Rst( pTxtAttr );
+            nEndIndex++;
+        }
+    }
+    else // ueberlies die nicht geoeffneten Enden
+    {
+        while ( ( nEndIndex < pHints->GetEndCount() ) &&
+                (*(pTxtAttr=pHints->GetEnd(nEndIndex))->GetAnyEnd()<=nNewPos))
+        {
+            nEndIndex++;
+        }
+    }
+    // Solange wir noch nicht am Ende des StartArrays angekommen sind &&
+    // das TextAttribut vor oder an der neuen Position beginnt ...
+    while ( ( nStartIndex < pHints->GetStartCount() ) &&
+           (*(pTxtAttr=pHints->GetStart(nStartIndex))->GetStart()<=nNewPos))
+    {
+        // oeffne die TextAttribute, deren Ende hinter der neuen Position liegt
+        if ( *pTxtAttr->GetAnyEnd() > nNewPos )  Chg( pTxtAttr );
+        nStartIndex++;
+    }
+
+}
+
+/*************************************************************************
+ *                       SwAttrIter::Seek()
+ *************************************************************************/
+
+sal_Bool SwAttrIter::Seek( const xub_StrLen nNewPos )
+{
+    if( pHints )
+    {
+        if( !nNewPos || nNewPos < nPos )
+        {
+            // Gehe zurueck auf Start ...
+            if( pRedln )
+                pRedln->Clear( NULL );
+            pFnt->SetFnt( pAttrSet );
+            pFnt->GetTox() = 0;
+            pFnt->GetRef() = 0;
+            nStartIndex = nEndIndex = nPos = 0;
+            nChgCnt = 0;
+        }
+        SeekFwd( nNewPos );
+    }
+    if( pRedln )
+        nChgCnt += pRedln->Seek( *pFnt, nNewPos, nPos );
+    nPos = nNewPos;
+    return pFnt->IsFntChg();
+}
+
+/*************************************************************************
+ *                      SwAttrIter::GetNextAttr()
+ *************************************************************************/
+
+xub_StrLen SwAttrIter::GetNextAttr( ) const
+{
+    xub_StrLen nNext = STRING_LEN;
+    if( pHints )
+    {
+        if (pHints->GetStartCount() > nStartIndex) // Gibt es noch Starts?
+           nNext = (*pHints->GetStart(nStartIndex)->GetStart());
+        if (pHints->GetEndCount() > nEndIndex) // Gibt es noch Enden?
+        {
+            xub_StrLen nNextEnd = (*pHints->GetEnd(nEndIndex)->GetAnyEnd());
+            if ( nNextEndGetNextRedln( nNext );
+    return nNext;
+}
+
+#ifdef DEBUG
+/*************************************************************************
+ *                      SwAttrIter::Dump()
+ *************************************************************************/
+
+void SwAttrIter::Dump( SvStream &rOS ) const
+{
+// Noch nicht an den neuen Attributiterator angepasst ...
+}
+
+#endif
+
+class SwMinMaxArgs
+{
+public:
+    OutputDevice *pOut;
+    ULONG &rMin;
+    ULONG &rMax;
+    ULONG &rAbsMin;
+    long nRowWidth;
+    long nWordWidth;
+    long nWordAdd;
+    SwMinMaxArgs( OutputDevice *pOutI, ULONG& rMinI, ULONG &rMaxI, ULONG &rAbsI )
+        : pOut( pOutI ), rMin( rMinI ), rMax( rMaxI ), rAbsMin( rAbsI )
+        { nRowWidth = nWordWidth = nWordAdd = 0; }
+    void Minimum( long nNew ) { if( (long)rMin < nNew ) rMin = nNew; }
+    void NewWord() { nWordAdd = nWordWidth = 0; }
+};
+
+sal_Bool lcl_MinMaxString( SwMinMaxArgs& rArg, SwFont* pFnt, const XubString &rTxt,
+    xub_StrLen nIdx, xub_StrLen nEnd )
+{
+    sal_Bool bRet = sal_False;
+    while( nIdx < nEnd )
+    {
+        xub_StrLen nStop = nIdx;
+        while( nStop < nEnd && CH_BLANK != rTxt.GetChar( nStop ) )
+            ++nStop;
+        sal_Bool bClear = nStop == nIdx;
+        if ( bClear )
+        {
+            rArg.NewWord();
+            while( nStop < nEnd && CH_BLANK == rTxt.GetChar( nStop ) )
+                ++nStop;
+        }
+        long nAktWidth = pFnt->_GetTxtSize( 0, rArg.pOut, rTxt, nIdx,
+                                        nStop - nIdx ).Width();
+        rArg.nRowWidth += nAktWidth;
+        if( bClear )
+            rArg.NewWord();
+        else
+        {
+            rArg.nWordWidth += nAktWidth;
+            if( (long)rArg.rAbsMin < rArg.nWordWidth )
+                rArg.rAbsMin = rArg.nWordWidth;
+            rArg.Minimum( rArg.nWordWidth + rArg.nWordAdd );
+            bRet = sal_True;
+        }
+        nIdx = nStop;
+    }
+    return bRet;
+}
+
+sal_Bool SwTxtNode::IsSymbol( const xub_StrLen nBegin ) const
+{
+    sal_Bool bRet = sal_False;
+    OutputDevice *pOut = GetDoc()->GetPrt();
+    if( !pOut )
+        pOut = GetpApp()->GetDefaultDevice();
+    if( pOut )
+    {
+        SwAttrIter aIter( *(SwTxtNode*)this );
+        aIter.SeekAndChg( nBegin, pOut );
+        bRet = aIter.GetFnt()->IsSymbol( GetDoc()->GetRootFrm() ?
+                GetDoc()->GetRootFrm()->GetCurrShell() : 0 );
+    }
+    return bRet;
+}
+
+class SwMinMaxNodeArgs
+{
+public:
+    ULONG nMaxWidth;    // Summe aller Rahmenbreite
+    long nMinWidth;     // Breitester Rahmen
+    long nLeftRest;     // noch nicht von Rahmen ueberdeckter Platz im l. Rand
+    long nRightRest;    // noch nicht von Rahmen ueberdeckter Platz im r. Rand
+    long nLeftDiff;     // Min/Max-Differenz des Rahmens im linken Rand
+    long nRightDiff;    // Min/Max-Differenz des Rahmens im rechten Rand
+    ULONG nIndx;        // Indexnummer des Nodes
+    void Minimum( long nNew ) { if( nNew > nMinWidth ) nMinWidth = nNew; }
+};
+
+sal_Bool lcl_MinMaxNode( const SwFrmFmtPtr& rpNd, void* pArgs )
+{
+    const SwFmtAnchor& rFmtA = ((SwFrmFmt*)rpNd)->GetAnchor();
+    if ( (FLY_AT_CNTNT == rFmtA.GetAnchorId() ||
+          FLY_AUTO_CNTNT == rFmtA.GetAnchorId()) &&
+        ((SwMinMaxNodeArgs*)pArgs)->nIndx ==
+            rFmtA.GetCntntAnchor()->nNode.GetIndex() )
+    {
+        long nMin, nMax;
+        SwHTMLTableLayout *pLayout = 0;
+        MSHORT nWhich = ((SwFrmFmt*)rpNd)->Which();
+        if( RES_DRAWFRMFMT != nWhich )
+        {
+            // Enthaelt der Rahmen zu Beginn oder am Ende eine Tabelle?
+            SwDoc *pDoc = ((SwFrmFmt*)rpNd)->GetDoc();
+
+            const SwFmtCntnt& rFlyCntnt = ((SwFrmFmt*)rpNd)->GetCntnt();
+            ULONG nStt = rFlyCntnt.GetCntntIdx()->GetIndex();
+            SwTableNode* pTblNd = pDoc->GetNodes()[nStt+1]->GetTableNode();
+            if( !pTblNd )
+            {
+                SwNode *pNd = pDoc->GetNodes()[nStt];
+                pNd = pDoc->GetNodes()[pNd->EndOfSectionIndex()-1];
+                if( pNd->IsEndNode() )
+                    pTblNd = pNd->StartOfSectionNode()->GetTableNode();
+            }
+
+            if( pTblNd )
+                pLayout = pTblNd->GetTable().GetHTMLTableLayout();
+        }
+
+        const SwFmtHoriOrient& rOrient = ((SwFrmFmt*)rpNd)->GetHoriOrient();
+        SwHoriOrient eHoriOri = rOrient.GetHoriOrient();
+
+        long nDiff;
+        if( pLayout )
+        {
+            nMin = pLayout->GetMin();
+            nMax = pLayout->GetMax();
+            nDiff = nMax - nMin;
+        }
+        else
+        {
+            if( RES_DRAWFRMFMT == nWhich )
+            {
+                const SdrObject* pSObj = rpNd->FindSdrObject();
+                if( pSObj )
+                    nMin = pSObj->GetBoundRect().GetWidth();
+                else
+                nMin = 0;
+
+            }
+            else
+            {
+                const SwFmtFrmSize &rSz = ( (SwFrmFmt*)rpNd )->GetFrmSize();
+                nMin = rSz.GetWidth();
+            }
+            nMax = nMin;
+            nDiff = 0;
+        }
+
+        const SvxLRSpaceItem &rLR = ( (SwFrmFmt*)rpNd )->GetLRSpace();
+        nMin += rLR.GetLeft();
+        nMin += rLR.GetRight();
+        nMax += rLR.GetLeft();
+        nMax += rLR.GetRight();
+
+        if( SURROUND_THROUGHT == ((SwFrmFmt*)rpNd)->GetSurround().GetSurround() )
+        {
+            ( (SwMinMaxNodeArgs*)pArgs )->Minimum( nMin );
+            return sal_True;
+        }
+
+        // Rahmen, die recht bzw. links ausgerichtet sind, gehen nur
+        // teilweise in die Max-Berechnung ein, da der Rand schon berueck-
+        // sichtigt wird. Nur wenn die Rahmen in den Textkoerper ragen,
+        // wird dieser Teil hinzuaddiert.
+        switch( eHoriOri )
+        {
+            case HORI_RIGHT:
+            {
+                if( nDiff )
+                {
+                    ((SwMinMaxNodeArgs*)pArgs)->nRightRest -=
+                        ((SwMinMaxNodeArgs*)pArgs)->nRightDiff;
+                    ((SwMinMaxNodeArgs*)pArgs)->nRightDiff = nDiff;
+                }
+                if( FRAME!=rOrient.GetRelationOrient() )
+                {
+                    if( ((SwMinMaxNodeArgs*)pArgs)->nRightRest > 0 )
+                        ((SwMinMaxNodeArgs*)pArgs)->nRightRest = 0;
+                }
+                ((SwMinMaxNodeArgs*)pArgs)->nRightRest -= nMin;
+                break;
+            }
+            case HORI_LEFT:
+            {
+                if( nDiff )
+                {
+                    ((SwMinMaxNodeArgs*)pArgs)->nLeftRest -=
+                        ((SwMinMaxNodeArgs*)pArgs)->nLeftDiff;
+                    ((SwMinMaxNodeArgs*)pArgs)->nLeftDiff = nDiff;
+                }
+                if( FRAME!=rOrient.GetRelationOrient() &&
+                    ((SwMinMaxNodeArgs*)pArgs)->nLeftRest < 0 )
+                    ((SwMinMaxNodeArgs*)pArgs)->nLeftRest = 0;
+                ((SwMinMaxNodeArgs*)pArgs)->nLeftRest -= nMin;
+                break;
+            }
+            default:
+            {
+                ( (SwMinMaxNodeArgs*)pArgs )->nMaxWidth += nMax;
+                ( (SwMinMaxNodeArgs*)pArgs )->Minimum( nMin );
+            }
+        }
+    }
+    return sal_True;
+}
+
+#define FLYINCNT_MIN_WIDTH 284
+
+void SwTxtNode::GetMinMaxSize( ULONG nIndex, ULONG& rMin, ULONG &rMax,
+                               ULONG& rAbsMin, OutputDevice* pOut ) const
+{
+    if( !pOut )
+    {
+        ViewShell* pSh;
+        GetDoc()->GetEditShell( &pSh );
+        if( pSh )
+            pOut = pSh->GetWin();
+        if( !pOut )
+            pOut = GetpApp()->GetDefaultDevice();
+    }
+
+    MapMode aOldMap( pOut->GetMapMode() );
+    pOut->SetMapMode( MapMode( MAP_TWIP ) );
+
+    rMin = 0;
+    rMax = 0;
+    rAbsMin = 0;
+
+    const SvxLRSpaceItem &rSpace = GetSwAttrSet().GetLRSpace();
+    long nLROffset = rSpace.GetTxtLeft() + GetLeftMarginWithNum( sal_True );
+    short nFLOffs;
+    // Bei Numerierung ist ein neg. Erstzeileneinzug vermutlich
+    // bereits gefuellt...
+    if( !GetFirstLineOfsWithNum( nFLOffs ) || nFLOffs > nLROffset )
+        nLROffset = nFLOffs;
+
+    SwMinMaxNodeArgs aNodeArgs;
+    aNodeArgs.nMinWidth = 0;
+    aNodeArgs.nMaxWidth = 0;
+    aNodeArgs.nLeftRest = nLROffset;
+    aNodeArgs.nRightRest = rSpace.GetRight();
+    aNodeArgs.nLeftDiff = 0;
+    aNodeArgs.nRightDiff = 0;
+    if( nIndex )
+    {
+        SwSpzFrmFmts* pTmp = (SwSpzFrmFmts*)GetDoc()->GetSpzFrmFmts();
+        if( pTmp )
+        {
+            aNodeArgs.nIndx = nIndex;
+            pTmp->ForEach( &lcl_MinMaxNode, &aNodeArgs );
+        }
+    }
+    if( aNodeArgs.nLeftRest < 0 )
+        aNodeArgs.Minimum( nLROffset - aNodeArgs.nLeftRest );
+    aNodeArgs.nLeftRest -= aNodeArgs.nLeftDiff;
+    if( aNodeArgs.nLeftRest < 0 )
+        aNodeArgs.nMaxWidth -= aNodeArgs.nLeftRest;
+
+    if( aNodeArgs.nRightRest < 0 )
+        aNodeArgs.Minimum( rSpace.GetRight() - aNodeArgs.nRightRest );
+    aNodeArgs.nRightRest -= aNodeArgs.nRightDiff;
+    if( aNodeArgs.nRightRest < 0 )
+        aNodeArgs.nMaxWidth -= aNodeArgs.nRightRest;
+
+    SwAttrIter aIter( *(SwTxtNode*)this );
+    xub_StrLen nIdx = 0;
+    aIter.SeekAndChg( nIdx, pOut );
+    xub_StrLen nLen = aText.Len();
+    long nAktWidth = 0;
+    MSHORT nAdd = 0;
+    SwMinMaxArgs aArg( pOut, rMin, rMax, rAbsMin );
+    while( nIdx < nLen )
+    {
+        xub_StrLen nNextChg = aIter.GetNextAttr();
+        xub_StrLen nStop = nIdx;
+        SwTxtAttr *pHint = NULL;
+        xub_Unicode cChar = CH_BLANK;
+        while( nStop < nLen && nStop < nNextChg &&
+               CH_TAB != ( cChar = aText.GetChar( nStop ) ) &&
+               CH_BREAK != cChar && !pHint )
+        {
+            if( ( CH_TXTATR_BREAKWORD != cChar && CH_TXTATR_INWORD != cChar )
+                || ( 0 == ( pHint = aIter.GetAttr( nStop ) ) ) )
+                ++nStop;
+        }
+        if( lcl_MinMaxString( aArg, aIter.GetFnt(), aText, nIdx, nStop ) )
+            nAdd = 20;
+        nIdx = nStop;
+        aIter.SeekAndChg( nIdx, pOut );
+        switch( cChar )
+        {
+            case CH_BREAK  :
+            {
+                if( (long)rMax < aArg.nRowWidth )
+                    rMax = aArg.nRowWidth;
+                aArg.nRowWidth = 0;
+                aArg.NewWord();
+                aIter.SeekAndChg( ++nIdx, pOut );
+            }
+            break;
+            case CH_TAB    :
+            {
+                aArg.NewWord();
+                aIter.SeekAndChg( ++nIdx, pOut );
+            }
+            break;
+
+            case CH_TXTATR_BREAKWORD:
+            case CH_TXTATR_INWORD:
+            {
+                if( !pHint )
+                    break;
+                long nOldWidth = aArg.nWordWidth;
+                long nOldAdd = aArg.nWordAdd;
+                aArg.NewWord();
+
+                switch( pHint->Which() )
+                {
+                    case RES_TXTATR_FLYCNT :
+                    {
+                        SwFrmFmt *pFrmFmt = pHint->GetFlyCnt().GetFrmFmt();
+                        const SvxLRSpaceItem &rLR = pFrmFmt->GetLRSpace();
+                        if( RES_DRAWFRMFMT == pFrmFmt->Which() )
+                        {
+                            const SdrObject* pSObj = pFrmFmt->FindSdrObject();
+                            if( pSObj )
+                                nAktWidth = pSObj->GetBoundRect().GetWidth();
+                            else
+                                nAktWidth = 0;
+                        }
+                        else
+                        {
+                            const SwFmtFrmSize& rTmpSize = pFrmFmt->GetFrmSize();
+                            if( RES_FLYFRMFMT == pFrmFmt->Which()
+                                && rTmpSize.GetWidthPercent() )
+                            {
+/*-----------------24.01.97 14:09----------------------------------------------
+ * Hier ein HACK fuer folgende Situation: In dem Absatz befindet sich
+ * ein Textrahmen mit relativer Groesse. Dann nehmen wir mal als minimale
+ * Breite 0,5 cm und als maximale KSHRT_MAX.
+ * Sauberer und vielleicht spaeter notwendig waere es, ueber den Inhalt
+ * des Textrahmens zu iterieren und GetMinMaxSize rekursiv zu rufen.
+ * --------------------------------------------------------------------------*/
+                                nAktWidth = FLYINCNT_MIN_WIDTH; // 0,5 cm
+                                if( (long)rMax < KSHRT_MAX )
+                                    rMax = KSHRT_MAX;
+                            }
+                            else
+                                nAktWidth = pFrmFmt->GetFrmSize().GetWidth();
+                        }
+                        nAktWidth += rLR.GetLeft();
+                        nAktWidth += rLR.GetRight();
+                        aArg.nWordAdd = nOldWidth + nOldAdd;
+                        aArg.nWordWidth = nAktWidth;
+                        aArg.nRowWidth += nAktWidth;
+                        if( (long)rAbsMin < aArg.nWordWidth )
+                            rAbsMin = aArg.nWordWidth;
+                        aArg.Minimum( aArg.nWordWidth + aArg.nWordAdd );
+                        break;
+                    }
+                    case RES_TXTATR_FTN :
+                    {
+                        const XubString aTxt = pHint->GetFtn().GetNumStr();
+                        if( lcl_MinMaxString( aArg, aIter.GetFnt(), aTxt, 0,
+                            aTxt.Len() ) )
+                            nAdd = 20;
+                        break;
+                    }
+                    case RES_TXTATR_FIELD :
+                    {
+                        SwField *pFld = (SwField*)pHint->GetFld().GetFld();
+                        const String aTxt = pFld->GetCntnt( FALSE );
+                        if( lcl_MinMaxString( aArg, aIter.GetFnt(), aTxt, 0,
+                            aTxt.Len() ) )
+                            nAdd = 20;
+                        break;
+                    }
+                    case RES_TXTATR_HARDBLANK :
+                    {
+                        XubString sTmp( pHint->GetHardBlank().GetChar() );
+                        nAktWidth = aIter.GetFnt()->_GetTxtSize(
+                                GetDoc()->GetRootFrm() ? GetDoc()->GetRootFrm()->GetCurrShell() : 0,
+                                pOut, sTmp, 0, 1 ).Width();
+                        aArg.nWordWidth = nOldWidth + nAktWidth;
+                        aArg.nWordAdd = nOldAdd;
+                        aArg.nRowWidth += nAktWidth;
+                        if( (long)rAbsMin < aArg.nWordWidth )
+                            rAbsMin = aArg.nWordWidth;
+                        aArg.Minimum( aArg.nWordWidth + aArg.nWordAdd );
+                        break;
+                    }
+                    default: aArg.nWordWidth = nOldWidth;
+                             aArg.nWordAdd = nOldAdd;
+
+                }
+                aIter.SeekAndChg( ++nIdx, pOut );
+            }
+            break;
+        }
+    }
+    if( (long)rMax < aArg.nRowWidth )
+        rMax = aArg.nRowWidth;
+
+    nLROffset += rSpace.GetRight();
+
+    rAbsMin += nLROffset;
+    rAbsMin += nAdd;
+    rMin += nLROffset;
+    rMin += nAdd;
+    if( (long)rMin < aNodeArgs.nMinWidth )
+        rMin = aNodeArgs.nMinWidth;
+    if( (long)rAbsMin < aNodeArgs.nMinWidth )
+        rAbsMin = aNodeArgs.nMinWidth;
+    rMax += aNodeArgs.nMaxWidth;
+    rMax += nLROffset;
+    rMax += nAdd;
+    if( rMax < rMin ) // z.B. Rahmen mit Durchlauf gehen zunaechst nur
+        rMax = rMin;  // in das Minimum ein
+    pOut->SetMapMode( aOldMap );
+}
+
+
diff --git a/sw/source/core/text/itratr.hxx b/sw/source/core/text/itratr.hxx
new file mode 100644
index 000000000000..8e608164471b
--- /dev/null
+++ b/sw/source/core/text/itratr.hxx
@@ -0,0 +1,149 @@
+/*************************************************************************
+ *
+ *  $RCSfile: itratr.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _ITRATR_HXX
+#define _ITRATR_HXX
+
+
+#ifndef _SOLAR_H
+#include 
+#endif
+#include "txttypes.hxx"
+
+class OutputDevice;
+class SwFont;
+class SwpHints;
+class SwTxtAttr;
+class SwAttrSet;
+class SwTxtNode;
+class SwRedlineItr;
+class ViewShell;
+
+/*************************************************************************
+ *                      class SwAttrIter
+ *************************************************************************/
+
+class SwAttrIter
+{
+protected:
+    ViewShell *pShell;
+    SwFont *pFnt;
+    SwpHints  *pHints;
+    const SwAttrSet* pAttrSet;       // das Char-Attribut-Set
+
+private:
+    xub_StrLen nStartIndex, nEndIndex, nPos;
+    MSHORT nChgCnt, nFntIdx;
+    const void* pMagicNo;
+    OutputDevice *pLastOut;
+    SwRedlineItr *pRedln;
+    void SeekFwd( const xub_StrLen nPos );
+
+protected:
+    void Chg( SwTxtAttr *pHt );
+    void Rst( SwTxtAttr *pHt );
+    void CtorInit( SwTxtNode& rTxtNode );
+    inline SwAttrIter() : pFnt(0), pLastOut(0), pMagicNo(0), nChgCnt(0),
+        nFntIdx(0), pShell(0), pRedln( 0 ) { }
+
+public:
+    // Konstruktor, Destruktor
+    inline SwAttrIter( SwTxtNode& rTxtNode )
+           : pFnt(0), pLastOut(0), pMagicNo(0), nChgCnt(0), pRedln(0), nFntIdx(0)
+           { CtorInit( rTxtNode ); }
+
+    virtual ~SwAttrIter();
+
+    inline SwRedlineItr *GetRedln() { return pRedln; }
+    // Liefert im Parameter die Position des naechsten Wechsels vor oder an
+    // der uebergebenen Characterposition zurueck. Liefert sal_False, wenn vor
+    // oder an dieser Position kein Wechsel mehr erfolgt, sal_True sonst.
+    xub_StrLen GetNextAttr( ) const;
+    // Macht die an der Characterposition i gueltigen Attribute im
+    // logischen Font wirksam.
+    sal_Bool Seek( const xub_StrLen nPos );
+    // Bastelt den Font an der gew. Position via Seek und fragt ihn,
+    // ob er ein Symbolfont ist.
+    sal_Bool IsSymbol( const xub_StrLen nPos );
+
+    // Fuehrt ChgPhysFnt aus, wenn Seek() sal_True zurueckliefert.
+    sal_Bool SeekAndChg( const xub_StrLen nPos, OutputDevice *pOut );
+    sal_Bool SeekStartAndChg( OutputDevice *pOut, const sal_Bool bParaFont = sal_False );
+
+    // Gibt es ueberhaupt Attributwechsel ?
+    inline sal_Bool HasHints() const { return 0 != pHints; }
+
+    // liefert fuer eine Position das Attribut
+    SwTxtAttr *GetAttr( const xub_StrLen nPos ) const;
+
+    inline const SwAttrSet* GetAttrSet() const { return pAttrSet; }
+
+//  inline SwpHints *GetHints() { return pHints; }
+    inline const SwpHints *GetHints() const { return pHints; }
+
+    inline SwFont *GetFnt() { return pFnt; }
+    inline const SwFont *GetFnt() const { return pFnt; }
+#ifdef DEBUG
+    void Dump( SvStream &rOS ) const;
+#endif
+};
+
+
+#endif
diff --git a/sw/source/core/text/itrcrsr.cxx b/sw/source/core/text/itrcrsr.cxx
new file mode 100644
index 000000000000..974cb4d40619
--- /dev/null
+++ b/sw/source/core/text/itrcrsr.cxx
@@ -0,0 +1,923 @@
+/*************************************************************************
+ *
+ *  $RCSfile: itrcrsr.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "hintids.hxx"
+#include "errhdl.hxx"
+#include "ndtxt.hxx"
+#include "frmfmt.hxx"
+#include "paratr.hxx"
+#include "flyfrm.hxx"
+
+#ifndef _SVX_PROTITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_ADJITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_LSPCITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _FRMATR_HXX
+#include 
+#endif
+#include "txtcfg.hxx"
+#include "itrtxt.hxx"
+
+#include "txtfrm.hxx"
+#include "flyfrms.hxx"
+#include "porglue.hxx"      // SwFlyCnt
+#include "porfld.hxx"       // SwFldPortion::IsFollow()
+#include "porfly.hxx"       // GetFlyCrsrOfst()
+#include "pordrop.hxx"
+#include "crstate.hxx"      // SwCrsrMoveState
+
+// Nicht reentrant !!!
+// wird in GetCharRect gesetzt und im UnitUp/Down ausgewertet.
+sal_Bool SwTxtCursor::bRightMargin = sal_False;
+
+/*************************************************************************
+ *                SwTxtMargin::CtorInit()
+ *************************************************************************/
+void SwTxtMargin::CtorInit( SwTxtFrm *pFrm, SwTxtSizeInfo *pNewInf )
+{
+    SwTxtIter::CtorInit( pFrm, pNewInf );
+
+    pInf = pNewInf;
+    GetInfo().SetFont( GetFnt() );
+    SwTxtNode *pNode = pFrm->GetTxtNode();
+
+    const SvxLRSpaceItem &rSpace =
+        pFrm->GetTxtNode()->GetSwAttrSet().GetLRSpace();
+    nRight = pFrm->Frm().Left() + pFrm->Prt().Left() + pFrm->Prt().Width();
+    nLeft = Max( long( rSpace.GetTxtLeft() + pNode->GetLeftMarginWithNum(sal_True)),
+                 pFrm->Prt().Left() ) + pFrm->Frm().Left();
+    if( nLeft >= nRight )
+        nLeft = pFrm->Prt().Left() + pFrm->Frm().Left();
+    if( nLeft >= nRight ) // z.B. bei grossen Absatzeinzuegen in schmalen Tabellenspalten
+        nRight = nLeft + 1; // einen goennen wir uns immer
+    if( pFrm->IsFollow() && pFrm->GetOfst() )
+        nFirst = nLeft;
+    else
+    {
+        short nFLOfst;
+        long nFirstLineOfs;
+        if( !pNode->GetFirstLineOfsWithNum( nFLOfst ) &&
+            rSpace.IsAutoFirst() )
+        {
+            nFirstLineOfs = GetFnt()->GetSize( GetFnt()->GetActual() ).Height();
+            const SvxLineSpacingItem *pSpace = aLineInf.GetLineSpacing();
+            if( pSpace )
+            {
+                switch( pSpace->GetLineSpaceRule() )
+                {
+                    case SVX_LINE_SPACE_AUTO:
+                    break;
+                    case SVX_LINE_SPACE_MIN:
+                    {
+                        if( nFirstLineOfs < KSHORT( pSpace->GetLineHeight() ) )
+                            nFirstLineOfs = pSpace->GetLineHeight();
+                        break;
+                    }
+                    case SVX_LINE_SPACE_FIX:
+                        nFirstLineOfs = pSpace->GetLineHeight();
+                    break;
+                    default: ASSERT( sal_False, ": unknown LineSpaceRule" );
+                }
+                switch( pSpace->GetInterLineSpaceRule() )
+                {
+                    case SVX_INTER_LINE_SPACE_OFF:
+                    break;
+                    case SVX_INTER_LINE_SPACE_PROP:
+                    {
+                        long nTmp = pSpace->GetPropLineSpace();
+                        // 50% ist das Minimum, bei 0% schalten wir auf
+                        // den Defaultwert 100% um ...
+                        if( nTmp < 50 )
+                            nTmp = nTmp ? 50 : 100;
+
+                        nTmp *= nFirstLineOfs;
+                        nTmp /= 100;
+                        if( !nTmp )
+                            ++nTmp;
+                        nFirstLineOfs = (KSHORT)nTmp;
+                        break;
+                    }
+                    case SVX_INTER_LINE_SPACE_FIX:
+                    {
+                        nFirstLineOfs += pSpace->GetInterLineSpace();
+                        break;
+                    }
+                    default: ASSERT( sal_False, ": unknown InterLineSpaceRule" );
+                }
+            }
+        }
+        else
+            nFirstLineOfs = nFLOfst;
+        nFirst = Max( rSpace.GetTxtLeft() + pNode->GetLeftMarginWithNum( sal_True )
+            + nFirstLineOfs, pFrm->Prt().Left() ) + pFrm->Frm().Left();
+        if( nFirst >= nRight )
+            nFirst = nRight - 1;
+    }
+    const SvxAdjustItem& rAdjust = pFrm->GetTxtNode()->GetSwAttrSet().GetAdjust();
+    nAdjust = rAdjust.GetAdjust();
+    bOneBlock = rAdjust.GetOneWord() == SVX_ADJUST_BLOCK;
+    bLastBlock = rAdjust.GetLastBlock() == SVX_ADJUST_BLOCK;
+    bLastCenter = rAdjust.GetLastBlock() == SVX_ADJUST_CENTER;
+#ifdef DEBUG
+    static sal_Bool bOne = sal_False;
+    static sal_Bool bLast = sal_False;
+    static sal_Bool bCenter = sal_False;
+    bOneBlock |= bOne;
+    bLastBlock |= bLast;
+    bLastCenter |= bCenter;
+#endif
+    DropInit();
+}
+
+/*************************************************************************
+ *                SwTxtMargin::DropInit()
+ *************************************************************************/
+void SwTxtMargin::DropInit()
+{
+    nDropLeft = nDropLines = nDropHeight = nDropDescent = 0;
+    const SwParaPortion *pPara = GetInfo().GetParaPortion();
+    if( pPara )
+    {
+        const SwDropPortion *pPorDrop = pPara->FindDropPortion();
+        if ( pPorDrop )
+        {
+            nDropLeft = pPorDrop->GetDropLeft();
+            nDropLines = pPorDrop->GetLines();
+            nDropHeight = pPorDrop->GetDropHeight();
+            nDropDescent = pPorDrop->GetDropDescent();
+        }
+    }
+}
+
+/*************************************************************************
+ *                SwTxtMargin::GetLineStart()
+ *************************************************************************/
+
+// Unter Beruecksichtigung des Erstzeileneinzuges und der angebenen Breite.
+SwTwips SwTxtMargin::GetLineStart() const
+{
+    SwTwips nRet = GetLeftMargin();
+    if( GetAdjust() != SVX_ADJUST_LEFT &&
+        !pCurr->GetFirstPortion()->IsMarginPortion() )
+    {
+        // Wenn die erste Portion ein Margin ist, dann wird das
+        // Adjustment durch die Portions ausgedrueckt.
+        if( GetAdjust() == SVX_ADJUST_RIGHT )
+            nRet = Right() - CurrWidth();
+        else if( GetAdjust() == SVX_ADJUST_CENTER )
+            nRet += (GetLineWidth() - CurrWidth()) / 2;
+    }
+    return nRet;
+}
+
+/*************************************************************************
+ *                      SwTxtCursor::CtorInit()
+ *************************************************************************/
+void SwTxtCursor::CtorInit( SwTxtFrm *pFrm, SwTxtSizeInfo *pInf )
+{
+    SwTxtMargin::CtorInit( pFrm, pInf );
+    // 6096: Vorsicht, die Iteratoren sind abgeleitet!
+    // GetInfo().SetOut( GetInfo().GetWin() );
+}
+
+/*************************************************************************
+ *                      SwTxtCursor::GetEndCharRect()
+ *************************************************************************/
+
+// 1170: Antikbug: Shift-Ende vergisst das letzte Zeichen ...
+
+sal_Bool SwTxtCursor::GetEndCharRect( SwRect* pOrig, const xub_StrLen nOfst,
+                                  SwCrsrMoveState* pCMS, const long nMax )
+{
+    // 1170: Mehrdeutigkeit von Dokumentpositionen
+    bRightMargin = sal_True;
+    CharCrsrToLine(nOfst);
+
+    // Etwas verdreht: nOfst bezeichnet die Position hinter dem letzten
+    // Zeichen der letzten Zeile == Position vor dem ersten Zeichen der
+    // Zeile in der wir gerade stehen:
+    if( nOfst != GetStart() || !pCurr->GetLen() )
+    {
+        // 8810: Masterzeile RightMargin, danach LeftMargin
+        const sal_Bool bRet = GetCharRect( pOrig, nOfst, pCMS, nMax );
+        bRightMargin = nOfst >= GetEnd() && nOfst < GetInfo().GetTxt().Len();
+        return bRet;
+    }
+
+    if( !GetPrev() || !GetPrev()->GetLen() || !PrevLine() )
+        return GetCharRect( pOrig, nOfst, pCMS, nMax );
+
+    // Adjustierung ggf. nachholen
+    GetAdjusted();
+
+    KSHORT nX = 0;
+    KSHORT nLast = 0;
+    SwLinePortion *pPor = pCurr->GetFirstPortion();
+
+    KSHORT nTmpHeight, nTmpAscent;
+    CalcAscentAndHeight( nTmpAscent, nTmpHeight );
+    KSHORT nPorHeight = nTmpHeight;
+    KSHORT nPorAscent = nTmpAscent;
+
+    // Die letzte Text/EndPortion der Zeile suchen
+    while( pPor )
+    {
+        nX += pPor->Width();
+        if( pPor->InTxtGrp() || ( pPor->GetLen() && !pPor->IsFlyPortion()
+            && !pPor->IsHolePortion() ) || pPor->IsBreakPortion() )
+        {
+            nLast = nX;
+            nPorHeight = pPor->Height();
+            nPorAscent = pPor->GetAscent();
+        }
+        pPor = pPor->GetPortion();
+    }
+
+    const Size aCharSize( 1, nTmpHeight );
+    pOrig->Pos( GetTopLeft() );
+    pOrig->SSize( aCharSize );
+    pOrig->Pos().X() += nLast;
+    const SwTwips nRight = Right() - 1;
+    if( pOrig->Left() > nRight )
+        pOrig->Pos().X() = nRight;
+
+    if ( pCMS && pCMS->bRealHeight )
+    {
+        if ( nTmpAscent > nPorAscent )
+            pCMS->aRealHeight.X() = nTmpAscent - nPorAscent;
+        else
+            pCMS->aRealHeight.X() = 0;
+        ASSERT( nPorHeight, "GetCharRect: Missing Portion-Height" );
+        pCMS->aRealHeight.Y() = nPorHeight;
+    }
+
+    return sal_True;
+}
+
+/*************************************************************************
+ *                      SwTxtCursor::GetCharRect()
+ *
+ * Tabs: Ist das aktuelle Zeichen das Tabzeichen, dann liefert
+ * GetCharRect() das SwRect hinter dem letzten Character in
+ * der vorhergehenden Portion. Ist das aktuelle Zeichen das
+ * Zeichen nach dem Tabzeichen, so wird das SwRect am Anfang
+ * der Portion-Box geliefert, weil das Tabzeichen selber
+ * unsichtbar ist. Oder andersherum: Wenn eine Portion mit einem
+ * Tabzeichen beginnt, dann darf dieses Tabzeichen bei der
+ * Berechnung des x-Offset der Characterbox innerhalb der Portion
+ * nicht beruecksichtigt werden.
+ *
+ *************************************************************************/
+sal_Bool SwTxtCursor::GetCharRect( SwRect* pOrig, const xub_StrLen nOfst,
+                               SwCrsrMoveState* pCMS, const long nMax )
+{
+    BOOL bDropIt = pCMS && pCMS->bDropIt;
+    CharCrsrToLine(nOfst);
+
+    // Adjustierung ggf. nachholen
+    GetAdjusted();
+
+    const XubString &rText = GetInfo().GetTxt();
+    SwTxtSizeInfo aInf( GetInfo(), rText, nStart );
+    KSHORT nTmpAscent, nTmpHeight;  // Zeilenhoehe
+    CalcAscentAndHeight( nTmpAscent, nTmpHeight );
+    const Size  aCharSize( 1, nTmpHeight );
+    const Point aCharPos( GetTopLeft() );
+    pOrig->Pos( aCharPos );
+    pOrig->SSize( aCharSize );
+    sal_Bool bRet = sal_True;
+    if( !pCurr->GetLen() && !pCurr->Width() )
+    {
+        if ( pCMS && pCMS->bRealHeight )
+        {
+            pCMS->aRealHeight.X() = 0;
+            pCMS->aRealHeight.Y() = nTmpHeight;
+        }
+    }
+    else
+    {
+        KSHORT nPorHeight = nTmpHeight;
+        KSHORT nPorAscent = nTmpAscent;
+        KSHORT nX = 0;
+        KSHORT nFirst = 0;
+        SwLinePortion *pPor = pCurr->GetFirstPortion();
+        SvShorts *pSpaceAdd = pCurr->GetpSpaceAdd();
+        MSHORT nSpaceIdx = 0;
+        short nSpaceAdd = pSpaceAdd ? (*pSpaceAdd)[0] : 0;
+        sal_Bool bNoTxt = sal_True;
+
+        // Zuerst werden alle Portions ohne Len am Zeilenanfang uebersprungen.
+        // Ausnahme bilden die fiesen Spezialportions aus WhichFirstPortion:
+        // Num, ErgoSum, FtnNum, FeldReste
+        // 8477: aber auch die einzige Textportion einer leeren Zeile mit
+        // Right/Center-Adjustment! Also nicht nur pPor->GetExpandPortion() ...
+
+        while( pPor && !pPor->GetLen() )
+        {
+            nX += pPor->Width();
+            if ( pPor->InTxtGrp() && nSpaceAdd )
+                nX += ( (SwTxtPortion*)pPor )->CalcSpacing( nSpaceAdd, aInf );
+            if( bNoTxt )
+                nFirst = nX;
+            // 8670: EndPortions zaehlen hier einmal als TxtPortions.
+            if( pPor->InTxtGrp() || pPor->IsBreakPortion() )
+            {
+                bNoTxt = sal_False;
+                nFirst = nX;
+            }
+            if( pPor->InFixMargGrp() )
+            {
+                if( pPor->IsMarginPortion() )
+                    bNoTxt = sal_False;
+                if( pSpaceAdd )
+                {
+                    if( nSpaceAdd < 0 )
+                        nX += nSpaceAdd;
+                    if ( ++nSpaceIdx < pSpaceAdd->Count() )
+                        nSpaceAdd = (*pSpaceAdd)[nSpaceIdx];
+                    else
+                        nSpaceAdd = 0;
+                }
+            }
+            pPor = pPor->GetPortion();
+        }
+
+        if( !pPor )
+        {
+            // Es sind nur Spezialportions unterwegs.
+            nX = nFirst;
+        }
+        else
+        {
+            if( !pPor->IsMarginPortion() && !pPor->IsPostItsPortion() &&
+                (!pPor->InFldGrp() || pPor->GetAscent() ) )
+            {
+                nPorHeight = pPor->Height();
+                nPorAscent = pPor->GetAscent();
+            }
+            while( pPor && aInf.GetIdx() < nOfst && !pPor->IsBreakPortion() )
+            {
+                if( !pPor->IsMarginPortion() && !pPor->IsPostItsPortion() &&
+                    (!pPor->InFldGrp() || pPor->GetAscent() ) )
+                {
+                    nPorHeight = pPor->Height();
+                    nPorAscent = pPor->GetAscent();
+                }
+                if ( aInf.GetIdx() + pPor->GetLen() <= nOfst )
+                {
+                    if ( pPor->InTxtGrp() && nSpaceAdd )
+                        nX += pPor->PrtWidth() + ( (SwTxtPortion*)pPor )->
+                            CalcSpacing( nSpaceAdd, aInf );
+                    else
+                    {
+                        if( pPor->InFixMargGrp() && pSpaceAdd )
+                        {
+                            if( nSpaceAdd < 0 )
+                                nX += nSpaceAdd;
+                            if ( ++nSpaceIdx < pSpaceAdd->Count() )
+                                nSpaceAdd = (*pSpaceAdd)[nSpaceIdx];
+                            else
+                                nSpaceAdd = 0;
+                        }
+                        if ( !pPor->IsFlyPortion() || ( pPor->GetPortion() &&
+                                !pPor->GetPortion()->IsMarginPortion() ) )
+                            nX += pPor->PrtWidth();
+                    }
+                    aInf.SetIdx( aInf.GetIdx() + pPor->GetLen() );
+                    pPor = pPor->GetPortion();
+                }
+                else
+                {
+                    if ( pPor->PrtWidth() )
+                    {
+                        xub_StrLen nOldLen = pPor->GetLen();
+                        pPor->SetLen( nOfst - aInf.GetIdx() );
+                        aInf.SetLen( pPor->GetLen() );
+                        if( nX || ( !pPor->InNumberGrp() &&
+                            ( bDropIt || !pPor->IsDropPortion() ) ) )
+                        {
+                            SeekAndChg( aInf );
+                            const sal_Bool bOldOnWin = aInf.OnWin();
+                            aInf.SetOnWin( sal_False ); // keine BULLETs!
+                            nX += pPor->GetTxtSize( aInf ).Width();
+                            aInf.SetOnWin( bOldOnWin );
+                            if ( pPor->InTxtGrp() && nSpaceAdd )
+                                nX += ( (SwTxtPortion*)pPor )->CalcSpacing(
+                                                                    nSpaceAdd, aInf );
+                        }
+                        pPor->SetLen( nOldLen );
+                    }
+                    break;
+                }
+            }
+        }
+
+        if( pPor )
+        {
+            // Bei manchen Portions gibts es kein links (Number, DropCap)
+            if( pPor->InNumberGrp() || ( pPor->IsDropPortion() && !bDropIt ) )
+            {
+                nX += pPor->Width();
+                if( pPor->GetPortion() && pPor->GetPortion()->IsMarginPortion() )
+                {
+                    nX += pPor->GetPortion()->Width();
+                    nPorHeight = pPor->GetPortion()->Height();
+                    nPorAscent = pPor->GetPortion()->GetAscent();
+                }
+                else
+                    bRet = sal_False;
+            }
+            else
+            {
+                sal_Bool bEmptyFld = sal_False;
+                if( pPor->InFldGrp() && pPor->GetLen() )
+                {
+                    SwFldPortion *pTmp = (SwFldPortion*)pPor;
+                    while( pTmp->HasFollow() && !pTmp->GetExp().Len() )
+                    {
+                        KSHORT nAddX = pTmp->Width();
+                        SwLinePortion *pNext = pTmp->GetPortion();
+                        while( pNext && !pNext->InFldGrp() )
+                        {
+                            if( pNext->GetLen() )
+                                pNext = NULL; // Gibt's das ueberhaupt?
+                            else
+                            {
+                                nAddX += pNext->Width();
+                                pNext = pNext->GetPortion();
+                            }
+                        }
+                        if( !pNext )
+                            break;
+                        pTmp = (SwFldPortion*)pNext;
+                        nPorHeight = pTmp->Height();
+                        nPorAscent = pTmp->GetAscent();
+                        nX += nAddX;
+                        bEmptyFld = sal_True;
+                    }
+                }
+                // 8513: Felder im Blocksatz, ueberspringen
+                while( pPor && !pPor->GetLen() && ( pPor->IsFlyPortion() ||
+                       ( !bEmptyFld && pPor->InFldGrp() ) ) )
+                {
+                    if ( pPor->InTxtGrp() && nSpaceAdd )
+                        nX += pPor->PrtWidth() + ( (SwTxtPortion*)pPor )->
+                            CalcSpacing( nSpaceAdd, aInf );
+                    else
+                    {
+                        if( pPor->InFixMargGrp() && pSpaceAdd )
+                        {
+                            if( nSpaceAdd < 0 )
+                                nX += nSpaceAdd;
+                            if ( ++nSpaceIdx < pSpaceAdd->Count() )
+                                nSpaceAdd = (*pSpaceAdd)[nSpaceIdx];
+                            else
+                                nSpaceAdd = 0;
+                        }
+                        if ( !pPor->IsFlyPortion() || ( pPor->GetPortion() &&
+                                !pPor->GetPortion()->IsMarginPortion() ) )
+                            nX += pPor->PrtWidth();
+                    }
+                    if( !pPor->IsFlyPortion() )
+                    {
+                        nPorHeight = pPor->Height();
+                        nPorAscent = pPor->GetAscent();
+                    }
+                    pPor = pPor->GetPortion();
+                }
+            }
+
+            if( aInf.GetIdx() == nOfst && pPor && pPor->InHyphGrp() &&
+                pPor->GetPortion() && pPor->GetPortion()->InFixGrp() )
+            {
+                // Alle Sonderportions muessen uebersprungen werden
+                // Beispiel: zu-[FLY]sammen, 'u' == 19, 's' == 20; Right()
+                // Ohne den Ausgleich landen wir vor '-' mit dem
+                // Ausgleich vor 's'.
+                while( pPor && !pPor->GetLen() )
+                {
+                    DBG_LOOP;
+                    nX += pPor->Width();
+                    if( !pPor->IsMarginPortion() )
+                    {
+                        nPorHeight = pPor->Height();
+                        nPorAscent = pPor->GetAscent();
+                    }
+                    pPor = pPor->GetPortion();
+                }
+            }
+            if( pPor && pCMS )
+            {
+                if( pCMS->bFieldInfo && pPor->InFldGrp() && pPor->Width() )
+                    pOrig->Width( pPor->Width() );
+                if( pPor->IsDropPortion() && bDropIt )
+                    pOrig->Height( ((SwDropPortion*)pPor)->GetDropHeight() +
+                                   ((SwDropPortion*)pPor)->GetDropDescent());
+            }
+        }
+        // Es darf nicht vorzeitig returnt werden.
+        // 6798: nicht auf pOrig->Right() rumhuehnern.
+        pOrig->Pos().X() += nX;
+
+        // Hier muesste eigentlich "-1 LogicToPixel" stehen, dies erscheint
+        // mir aber zu teuer, deshalb ein Wert (-12), mit dem es sich hoffentlich
+        // leben laesst?
+        const SwTwips nRight = Right() - 12;
+
+        if( pOrig->Left() > nRight )
+            pOrig->Pos().X() = nRight;
+
+        if ( pCMS && pCMS->bRealHeight )
+        {
+            if ( nTmpAscent > nPorAscent )
+                pCMS->aRealHeight.X() = nTmpAscent - nPorAscent;
+            else
+                pCMS->aRealHeight.X() = 0;
+            ASSERT( nPorHeight, "GetCharRect: Missing Portion-Height" );
+            if ( nTmpHeight > nPorHeight )
+                pCMS->aRealHeight.Y() = nPorHeight;
+            else
+                pCMS->aRealHeight.Y() = nTmpHeight;
+        }
+    }
+    if( nMax )
+    {
+        if( pOrig->Bottom() > nMax )
+        {
+            if( pOrig->Top() > nMax )
+                pOrig->Top( nMax );
+            pOrig->Bottom( nMax );
+        }
+        if ( pCMS && pCMS->bRealHeight )
+        {
+            long nTmp = pCMS->aRealHeight.X() + pOrig->Top();
+            if( nTmp >= nMax )
+            {
+                pCMS->aRealHeight.X() = nMax - pOrig->Top();
+                pCMS->aRealHeight.Y() = 0;
+            }
+            else if( nTmp + pCMS->aRealHeight.Y() > nMax )
+                pCMS->aRealHeight.Y() = nMax - nTmp;
+        }
+    }
+    long nOut = pOrig->Right() - GetTxtFrm()->Frm().Right();
+    if( nOut > 0 )
+    {
+        if( GetTxtFrm()->Frm().Width() < GetTxtFrm()->Prt().Left()
+                                   + GetTxtFrm()->Prt().Width() )
+            nOut += GetTxtFrm()->Frm().Width() - GetTxtFrm()->Prt().Left()
+                    - GetTxtFrm()->Prt().Width();
+        if( nOut > 0 )
+            pOrig->Pos().X() -= nOut + 10;
+    }
+    return bRet;
+}
+
+/*************************************************************************
+ *                      SwTxtCursor::GetCrsrOfst()
+ *
+ * Return: Offset im String
+ *************************************************************************/
+xub_StrLen SwTxtCursor::GetCrsrOfst( SwPosition *pPos, const Point &rPoint,
+                     const MSHORT nChgNode, const SwCrsrMoveState* pCMS ) const
+{
+    // Adjustierung ggf. nachholen
+    GetAdjusted();
+
+    const XubString &rText = GetInfo().GetTxt();
+    xub_StrLen nOffset = 0;
+
+    // x ist der horizontale Offset innerhalb der Zeile.
+    SwTwips x = rPoint.X();
+    CONST SwTwips nLeftMargin  = GetLineStart();
+    SwTwips nRightMargin = GetLineEnd();
+    if( nRightMargin == nLeftMargin )
+        nRightMargin += 30;
+
+    if(x < nLeftMargin)
+        x = nLeftMargin;
+    sal_Bool bRightOver = x > nRightMargin;
+    if( bRightOver )
+        x = nRightMargin;
+
+    sal_Bool bRightAllowed = pCMS && ( pCMS->eState == MV_NONE );
+
+    // Bis hierher in Dokumentkoordinaten.
+    x -= nLeftMargin;
+
+    KSHORT nX = KSHORT( x );
+
+    // Wenn es in der Zeile Attributwechsel gibt, den Abschnitt
+    // suchen, in dem nX liegt.
+    SwLinePortion *pPor = pCurr->GetFirstPortion();
+    xub_StrLen nCurrStart  = nStart;
+    sal_Bool bLastPortion;
+    sal_Bool bHolePortion = sal_False;
+    sal_Bool bLastHyph = sal_False;
+
+    SvShorts *pSpaceAdd = pCurr->GetpSpaceAdd();
+    xub_StrLen nOldIdx = GetInfo().GetIdx();
+    MSHORT nSpaceIdx = 0;
+    short nSpaceAdd = pSpaceAdd ? (*pSpaceAdd)[0] : 0;
+
+    // nWidth ist die Breite der Zeile, oder die Breite des
+    // Abschnitts mit dem Fontwechsel, in dem nX liegt.
+
+    KSHORT nWidth = pPor->Width();
+    if ( pSpaceAdd )
+    {
+        if ( pPor->InTxtGrp() && nSpaceAdd )
+        {
+            ((SwTxtSizeInfo&)GetInfo()).SetIdx( nCurrStart );
+            nWidth += ((SwTxtPortion*)pPor)->CalcSpacing( nSpaceAdd, GetInfo() );
+        }
+        else if( pPor->InFixMargGrp() )
+        {
+            if ( ++nSpaceIdx < pSpaceAdd->Count() )
+                nSpaceAdd = (*pSpaceAdd)[nSpaceIdx];
+            else
+                nSpaceAdd = 0;
+        }
+
+    }
+
+    KSHORT nWidth30 = !nWidth && pPor->GetLen() && pPor->InToxRefOrFldGrp()
+        ? 30 : nWidth;
+
+    while(!(bLastPortion = (0 == pPor->GetPortion())) && nWidth30 < nX &&
+        !pPor->IsBreakPortion() )
+    {
+        if ( pPor->IsPostItsPortion() && pPor->GetViewWidth( GetInfo() )/2 > nX )
+            break;
+
+        nX -= nWidth;
+        nCurrStart += pPor->GetLen();
+        bHolePortion = pPor->IsHolePortion();
+        pPor = pPor->GetPortion();
+        nWidth = pPor->Width();
+        if ( pSpaceAdd )
+        {
+            if ( pPor->InTxtGrp() && nSpaceAdd )
+            {
+                ((SwTxtSizeInfo&)GetInfo()).SetIdx( nCurrStart );
+                nWidth += ((SwTxtPortion*)pPor)->CalcSpacing( nSpaceAdd, GetInfo() );
+            }
+            else if( pPor->InFixMargGrp() )
+            {
+                if ( ++nSpaceIdx < pSpaceAdd->Count() )
+                    nSpaceAdd = (*pSpaceAdd)[nSpaceIdx];
+                else
+                    nSpaceAdd = 0;
+            }
+        }
+        nWidth30 = !nWidth && pPor->GetLen() && ( pPor->InToxRefOrFldGrp() ||
+                    pPor->IsPostItsPortion() ) ? 30 : nWidth;
+        if( !pPor->IsFlyPortion() && !pPor->IsMarginPortion() )
+            bLastHyph = pPor->InHyphGrp();
+    }
+
+    if( nX==nWidth )
+    {
+        SwLinePortion *pNextPor = pPor->GetPortion();
+        while( pNextPor && pNextPor->InFldGrp() && !pNextPor->Width() )
+        {
+            nCurrStart += pPor->GetLen();
+            pPor = pNextPor;
+            if( !pPor->IsFlyPortion() && !pPor->IsMarginPortion() )
+                bLastHyph = pPor->InHyphGrp();
+            pNextPor = pPor->GetPortion();
+        }
+    }
+
+    ((SwTxtSizeInfo&)GetInfo()).SetIdx( nOldIdx );
+
+    xub_StrLen nLength = pPor->GetLen();
+
+    sal_Bool bFieldInfo = pCMS && pCMS->bFieldInfo;
+
+    if( bFieldInfo && ( nWidth30 < nX || bRightOver ||
+        ( pPor->InNumberGrp() && !pPor->IsFtnNumPortion() ) ||
+        ( pPor->IsMarginPortion() && nWidth > nX + 30 ) ) )
+        ((SwCrsrMoveState*)pCMS)->bPosCorr = sal_True;
+
+    // 7684: Wir sind genau auf der HyphPortion angelangt und muessen dafuer
+    // sorgen, dass wir in dem String landen.
+    // 7993: Wenn die Laenge 0 ist muessen wir raus...
+    if( !nLength )
+    {
+        if( pCMS )
+        {
+            if( pPor->IsFlyPortion() && bFieldInfo )
+                ((SwCrsrMoveState*)pCMS)->bPosCorr = sal_True;
+
+            if( pPor->IsFtnNumPortion() && !bRightOver && nX )
+                ((SwCrsrMoveState*)pCMS)->bFtnNoInfo = sal_True;
+        }
+        if( !nCurrStart )
+            return 0;
+
+         // 7849, 7816: auf pPor->GetHyphPortion kann nicht verzichtet werden!
+        if( bHolePortion || ( !bRightAllowed && bLastHyph ) ||
+            ( pPor->IsMarginPortion() && !pPor->GetPortion() &&
+            // 46598: In der letzten Zeile eines zentrierten Absatzes wollen
+            // wir auch mal hinter dem letzten Zeichen landen.
+              nCurrStart < rText.Len() ) )
+            --nCurrStart;
+        else if( pPor->InFldGrp() && ((SwFldPortion*)pPor)->IsFollow()
+                 && nWidth > nX )
+        {
+            if( bFieldInfo )
+                --nCurrStart;
+            else
+            {
+                KSHORT nHeight = pPor->Height();
+                if ( !nHeight || nHeight > nWidth )
+                    nHeight = nWidth;
+                if( nChgNode && nWidth - nHeight/2 > nX )
+                    --nCurrStart;
+            }
+        }
+        return nCurrStart;
+    }
+    if ( 1 == nLength )
+    {
+        if ( nWidth )
+        {
+            // Sonst kommen wir nicht mehr in zeichengeb. Rahmen hinein...
+            if( !( nChgNode && pPos && pPor->IsFlyCntPortion() ) )
+            {
+                if ( pPor->InFldGrp() )
+                {
+                    KSHORT nHeight = 0;
+                    if( !bFieldInfo )
+                    {
+                        nHeight = pPor->Height();
+                        if ( !nHeight || nHeight > nWidth )
+                            nHeight = nWidth;
+                    }
+                    if( !((SwFldPortion*)pPor)->HasFollow() &&
+                        nWidth - nHeight/2 <= nX )
+                        ++nCurrStart;
+                }
+                else if( ( !pPor->IsFlyPortion() || ( pPor->GetPortion() &&
+                    !pPor->GetPortion()->IsMarginPortion() &&
+                    !pPor->GetPortion()->IsHolePortion() ) )
+                         && ( nWidth/2 < nX ) && !bFieldInfo
+                         && ( bRightAllowed || !bLastHyph ))
+                    ++nCurrStart;
+                return nCurrStart;
+            }
+        }
+        else
+        {
+            if ( pPor->IsPostItsPortion() || pPor->IsBreakPortion() ||
+                 pPor->InToxRefGrp() )
+                return nCurrStart;
+            if ( pPor->InFldGrp() )
+            {
+                if( bRightOver && !((SwFldPortion*)pPor)->HasFollow() )
+                    ++nCurrStart;
+                return nCurrStart;
+            }
+        }
+    }
+
+    if( bLastPortion && (pCurr->GetNext() || pFrm->GetFollow() ) )
+        --nLength;
+
+    if( nWidth > nX )
+    {
+        if( pPor->InTxtGrp() )
+        {
+            SwTxtSizeInfo aSizeInf( GetInfo(), rText, nCurrStart );
+            ((SwTxtCursor*)this)->SeekAndChg( aSizeInf );
+            SwTxtSlot aDiffTxt( &aSizeInf, ((SwTxtPortion*)pPor) );
+//          nLength = aSizeInf.GetCrsrOfst( nX, nSpaceAdd );
+            nLength = aSizeInf.GetFont()->_GetCrsrOfst( aSizeInf.GetVsh(),
+                                    aSizeInf.GetOut(),
+                                    aSizeInf.GetTxt(), nX, aSizeInf.GetIdx(),
+                                    pPor->GetLen(), nSpaceAdd );
+            if( bFieldInfo && nLength == pPor->GetLen() )
+                --nLength;
+        }
+        else
+        {
+            if( nChgNode && pPos && pPor->IsFlyCntPortion()
+                && !( (SwFlyCntPortion*)pPor )->IsDraw() )
+            {
+                // JP 24.11.94: liegt die Pos nicht im Fly, dann
+                //              darf nicht mit STRING_LEN returnt werden!
+                //              (BugId: 9692 + Aenderung in feshview)
+                SwFlyInCntFrm *pTmp = ( (SwFlyCntPortion*)pPor )->GetFlyFrm();
+                sal_Bool bChgNode = 1 < nChgNode;
+                if( !bChgNode )
+                {
+                    SwFrm* pLower = pTmp->GetLower();
+                    if( pLower && (pLower->IsTxtFrm() || pLower->IsLayoutFrm()) )
+                        bChgNode = sal_True;
+                }
+                if( bChgNode && pTmp->Frm().IsInside( rPoint ) &&
+                    !( pTmp->IsProtected() ) )
+                {
+                    nLength = ((SwFlyCntPortion*)pPor)->
+                              GetFlyCrsrOfst( nX, rPoint, pPos, pCMS );
+                    // Sobald der Frame gewechselt wird, muessen wir aufpassen, dass
+                    // unser Font wieder im OutputDevice steht.
+                    // vgl. Paint und new SwFlyCntPortion !
+                    ((SwTxtSizeInfo*)pInf)->SelectFont();
+
+                    // 6776: Das pIter->GetCrsrOfst returnt
+                    // aus einer Verschachtelung mit STRING_LEN.
+                    return STRING_LEN;
+                }
+            }
+            else
+                nLength = pPor->GetCrsrOfst( nX );
+        }
+    }
+    nOffset = nCurrStart + nLength;
+
+    // 7684: Wir sind vor der HyphPortion angelangt und muessen dafuer
+    // sorgen, dass wir in dem String landen.
+    // Bei Zeilenenden vor FlyFrms muessen ebenso behandelt werden.
+
+    if( nOffset && pPor->GetLen() == nLength && pPor->GetPortion() &&
+        !pPor->GetPortion()->GetLen() && pPor->GetPortion()->InHyphGrp() )
+        --nOffset;
+
+    return nOffset;
+}
+
diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx
new file mode 100644
index 000000000000..454f81b70085
--- /dev/null
+++ b/sw/source/core/text/itrform2.cxx
@@ -0,0 +1,1491 @@
+/*************************************************************************
+ *
+ *  $RCSfile: itrform2.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _LAYFRM_HXX
+#include        // GetFrmRstHeight, etc
+#endif
+#ifndef _VIEWSH_HXX
+#include 
+#endif
+#ifndef _VIEWOPT_HXX
+#include       // SwViewOptions
+#endif
+#ifndef _PARATR_HXX
+#include        // SwFmtDrop
+#endif
+#ifndef _HINTIDS_HXX
+#include       // CH_TXTATR
+#endif
+#ifndef _TXTCFG_HXX
+#include 
+#endif
+#ifndef _ITRFORM2_HXX
+#include 
+#endif
+#ifndef _SWFONT_HXX
+#include        // IsTox, IsRef, SetLingu
+#endif
+#ifndef _PORRST_HXX
+#include 
+#endif
+#ifndef _PORTAB_HXX
+#include        // pLastTab->
+#endif
+#ifndef _PORFLY_HXX
+#include        // CalcFlyWidth
+#endif
+#ifndef _PORTOX_HXX
+#include        // WhichTxtPortion
+#endif
+#ifndef _PORREF_HXX
+#include        // WhichTxtPortion
+#endif
+#ifndef _PORFLD_HXX
+#include        // SwNumberPortion fuer CalcAscent()
+#endif
+#ifndef _PORFTN_HXX
+#include        // SwFtnPortion
+#endif
+#ifndef _POREXP_HXX
+#include 
+#endif
+#ifndef _PORHYPH_HXX
+#include 
+#endif
+#ifndef _GUESS_HXX
+#include         // Recycle()
+#endif
+#ifndef _TXTFRM_HXX
+#include        // GetFrmRstHeight, etc
+#endif
+#ifndef _BLINK_HXX
+#include         // pBlink
+#endif
+#ifndef _FTNFRM_HXX
+#include        // WhichFirstPortion() -> mal Verlagern.
+#endif
+#ifndef _REDLNITR_HXX
+#include      // SwRedlineItr
+#endif
+
+#ifdef DEBUG
+#ifndef _NDTXT_HXX
+#include         // pSwpHints, Ausgabeoperator
+#endif
+#endif
+
+
+
+#define MAX_TXTPORLEN 300
+
+inline void ClearFly( SwTxtFormatInfo &rInf )
+{
+    if( rInf.GetFly() )
+    {
+        delete rInf.GetFly();
+        rInf.SetFly(0);
+    }
+}
+
+/*************************************************************************
+ *                  SwTxtFormatter::CtorInit()
+ *************************************************************************/
+
+void SwTxtFormatter::CtorInit( SwTxtFrm *pFrm, SwTxtFormatInfo *pNewInf )
+{
+    SwTxtPainter::CtorInit( pFrm, pNewInf );
+    pInf = pNewInf;
+    pDropFmt = GetInfo().GetDropFmt();
+
+    bOnceMore = sal_False;
+    bChanges = sal_False;
+    bTruncLines = sal_False;
+    nNextChg = 0;
+    nCntEndHyph = 0;
+    nCntMidHyph = 0;
+
+    if( nStart > GetInfo().GetTxt().Len() )
+    {
+        ASSERT( !this, "+SwTxtFormatter::CTOR: bad offset" );
+        nStart = GetInfo().GetTxt().Len();
+    }
+
+}
+
+/*************************************************************************
+ *                      SwTxtFormatter::DTOR
+ *************************************************************************/
+
+SwTxtFormatter::~SwTxtFormatter()
+{
+    // restore hyphenation options if necessary
+    if (GetInfo().IsRestoreHyphOptions())
+    {
+        GetInfo().RestoreHyphOptions();
+    }
+
+    // Auesserst unwahrscheinlich aber denkbar.
+    // z.B.: Feld spaltet sich auf, Widows schlagen zu
+    if( GetInfo().GetRest() )
+    {
+        delete GetInfo().GetRest();
+        GetInfo().SetRest(0);
+    }
+}
+
+/*************************************************************************
+ *                      SwTxtFormatter::Insert()
+ *************************************************************************/
+
+void SwTxtFormatter::Insert( SwLineLayout *pLay )
+{
+    // Einfuegen heute mal ausnahmsweise hinter dem aktuellen Element.
+    if ( pCurr )
+    {
+        pLay->SetNext( pCurr->GetNext() );
+        pCurr->SetNext( pLay );
+    }
+    else
+        pCurr = pLay;
+}
+
+/*************************************************************************
+ *                  SwTxtFormatter::GetFrmRstHeight()
+ *************************************************************************/
+
+KSHORT SwTxtFormatter::GetFrmRstHeight() const
+{
+    // 8725: Uns interessiert die Resthoehe bezogen auf die Seite.
+    // Wenn wir in einer Tabelle stehen, dann ist pFrm->GetUpper() nicht
+    // die Seite. GetFrmRstHeight() wird im Zusammenhang mit den Ftn
+    // gerufen.
+    // Falsch: const SwFrm *pUpper = pFrm->GetUpper();
+    const SwFrm *pPage = (const SwFrm*)pFrm->FindPageFrm();
+    const SwTwips nHeight = pPage->Frm().Top()
+                          + pPage->Prt().Top()
+                          + pPage->Prt().Height() - Y();
+    if( 0 > nHeight )
+        return pCurr->Height();
+    else
+        return KSHORT( nHeight );
+}
+
+/*************************************************************************
+ *                      SwTxtFormatter::Recycle()
+ *************************************************************************/
+
+/* Recycle dient nicht nur der Optimierung, sondern soll gleichzeitig
+ * unsere Probleme mit dem WYSIWYG (flackern und tanzen) loesen helfen.
+ * Recycle betrachtet den Bereich einer Zeile _vor_ nReformat.
+ * 4 Faelle koennen auftreten:
+ * 1) pCurr ist hinter nReformat
+ *    Init, sal_False
+ * 2) pCurr wurde nagelneu angelegt
+ *    -> pPos == 0, sal_False
+ * 3) pCurr hatte Portions und nReformat liegt in der Zeile
+ *    -> pPos != 0, sal_True
+ * 4) pCurr hatte Portions und nReformat liegt aber _nicht_ in der Zeile
+ *    -> pPos == 0, sal_True
+ * Fall 4 sollte u.U. in ein ASSERT laufen.
+ *
+ * sal_True, wenn recyclet wurde ...
+ */
+
+void SwTxtFormatter::Recycle( SwTxtFormatInfo &rInf )
+{
+#ifndef PRODUCT
+    // Durch das 0 setzen wird Recycle() ausgelassen.
+    if( OPTLOW( rInf ) )
+        pCurr->SetLen(0);
+#endif
+    // GetRest() liefert den (Feld-)Ueberhang der vorigen Zeile zurueck.
+    // Dann gibt es natuerlich nichts zu recyclen ..
+    if( rInf.GetRest() || HasChanges() )
+    {
+        FormatReset( rInf );
+        return;
+    }
+
+    // Optimierung fuer Zeilen, die aus dem Rennen sind
+    xub_StrLen nReformat = rInf.GetReformatStart();
+
+    // Bei rechtsbuendig, zentriert und Blocksatz wird returnt ...
+    sal_Bool bRecycle = IsFirstReformat() && pCurr->GetLen();
+    if( bRecycle )
+    {
+        switch( GetAdjust() )
+        {
+            case SVX_ADJUST_BLOCK:
+            {
+                if( IsLastBlock() || IsLastCenter() )
+                    bRecycle = sal_False;
+                else
+                {
+                    // ????: Blank in der letzten Masterzeile (blocksat.sdw)
+                    bRecycle = 0 == pCurr->GetNext() && !pFrm->GetFollow();
+                    if ( bRecycle )
+                    {
+                        SwLinePortion *pPos = pCurr->GetFirstPortion();
+                        while ( pPos && !pPos->IsFlyPortion() )
+                            pPos = pPos->GetPortion();
+                        bRecycle = !pPos;
+                    }
+                }
+            }
+            break;
+            case SVX_ADJUST_CENTER:
+            case SVX_ADJUST_RIGHT:
+            {
+                bRecycle = sal_False;
+            }
+            break;
+            default: ;
+        }
+    }
+
+    // Schon wieder ein Sonderfall: unsichtbare SoftHyphs
+    if( bRecycle && STRING_LEN != nReformat )
+    {
+        const xub_Unicode cCh = rInf.GetTxt().GetChar( nReformat );
+        bRecycle = ( CH_TXTATR_BREAKWORD != cCh && CH_TXTATR_INWORD != cCh )
+                    || !rInf.HasHint( nReformat );
+    }
+
+    if( !bRecycle )
+    {
+        FormatReset( rInf );
+        return;
+    }
+
+    // alle Portions retten, die vor nReformat liegen.
+    // pPos kann nie 0 werden.
+    SwLinePortion *pPos = pCurr->GetFirstPortion();
+    SwLinePortion *pLast = pPos;
+
+    // bTabFlag warnt uns vor rechtsbdg. Tabs
+    sal_Bool bTabFlag = pPos->InTabGrp() && !pPos->IsTabLeftPortion();
+
+    while( pPos->GetPortion() && rInf.GetIdx() + pPos->GetLen() < nReformat )
+    {
+        DBG_LOOP;
+        pPos->Move( rInf );
+        pLast = pPos;
+        pPos = pPos->GetPortion();
+
+        if ( bTabFlag )
+            bTabFlag = !( pLast->IsTabLeftPortion() || pLast->IsFlyPortion() );
+
+        bTabFlag = bTabFlag || (pPos->InTabGrp() && !pPos->IsTabLeftPortion());
+        if( pPos->IsFtnPortion() )
+            rInf.SetFtnInside( sal_True );
+    }
+
+    // bBrkBefore ist sal_True, wenn die BrkPos vor oder auf nReformat liegt,
+    // d.h. dass die pPos in jedem Fall neuformatiert werden muss.
+    SwTxtGuess aGuess;
+    rInf.SetLen( nReformat );
+
+    // 6736: Worte hinter Flys, Blank einfuegen.
+    // 6820: Rechtstabs und Blanks
+    xub_StrLen nPrevEnd = nReformat ?
+        aGuess.GetPrevEnd( rInf, nReformat - 1 ) + 1: 0;
+    if ( 1 == nPrevEnd )
+        --nPrevEnd;
+
+    const sal_Bool bBrkBefore = bTabFlag || pLast->InTabnLftGrp() ||
+        pPos->IsQuoVadisPortion() ||
+        ( pLast->IsFlyPortion() && (!nReformat || rInf.GetIdx() >= nPrevEnd) );
+    // Wenn pLast nicht recyclebar ist (R/Z/D-Tabs und SoftHyphs etc)
+    // dann muss diese Portion mit in die Neuformatierung aufgenommen
+    // werden. D.h: pLast wandert um einen zurueck und rInf muss
+    // um den entsprechenden Betrag zurueckgestellt werden.
+
+    if( bBrkBefore )
+    {
+        // 13713: Bei nicht recyclebaren Tabs (rechtsbdg. etc.) muss man
+        // bis zur letzten Nichttextportion zurueckgehen!
+        if( pPos == pLast )
+            pLast = pLast->FindPrevPortion( pCurr );
+        while( pLast != pCurr &&
+              ( !pLast->MayRecycle() || pPos->IsFlyPortion() || bTabFlag ) )
+        {
+            if ( bTabFlag )
+                bTabFlag = pLast->InTxtGrp();
+            else
+                bTabFlag = pLast->InTabGrp();
+
+            rInf.SetIdx( rInf.GetIdx() - pLast->GetLen() );
+            rInf.X( rInf.X() - pLast->Width() );
+            pPos = pLast;
+            pLast = pLast->FindPrevPortion( pCurr );
+        }
+    }
+
+    // Wunder der Technik: der PaintOfst ist die Position in der
+    // Zeile, wo es gleich weiter geht.
+    long nPOfst = 0;
+
+    if ( pPos->InTxtGrp() && rInf.GetIdx() < nPrevEnd &&
+         rInf.GetIdx() + pPos->GetLen() > nPrevEnd )
+    {
+        SwRect aRect;
+        GetCharRect( &aRect, nPrevEnd );
+        nPOfst = aRect.Left();
+    }
+    else
+        nPOfst = rInf.X() + GetLeftMargin();
+
+// AMA-Test: Problem, wenn diese Portion in die naechste Zeile rutscht,
+// behauptet IsFirstReformat, dass die Zeile recycled werden kann, weil
+// Reformat-Start in der Zeile liegt ( aber erst durch das Rutschen! ).
+// Loesung: wir drehen am Reformat-Start
+    rInf.GetParaPortion()->GetReformat()->LeftMove( rInf.GetIdx() );
+#ifdef DEBUG
+    SwTwips nOffset =  rInf.X() + GetLeftMargin();
+#endif
+    pPos = pLast == pPos ? pCurr : pLast;
+
+    // nach pPos die Sintflut
+    pPos->Truncate();
+
+    // 9118: pLast ist eine NumPortion, SetNumDone ist nicht sal_True
+    // Alternative: alle Flags setzen...
+    if( pPos == pCurr || !rInf.GetIdx() || pPos->IsErgoSumPortion() )
+    {
+        if( pPos->IsGrfNumPortion() )
+        {
+            if( nReformat && !((SwGrfNumPortion*)pPos)->IsHide() )
+                rInf.SetNumDone( sal_True );
+            else
+            {
+                nPOfst = 0;
+                FormatReset( rInf );
+            }
+        }
+        else
+            FormatReset( rInf );
+    }
+
+    if ( nPOfst )
+        rInf.SetPaintOfst( nPOfst );
+    rInf.SetLen(0);
+
+    // Wir muessen die pCurr-Daten, die sonst waehrend der Fahrt
+    // in NewTxtPortion() ermittelt werden, auf Vordermann bringen.
+    pLast = pCurr->GetPortion();
+    if( pLast )
+    {
+        pCurr->Init( pLast );
+        while( pLast )
+        {
+            DBG_LOOP;
+            if( pCurr->Height() < pLast->Height() )
+                pCurr->Height( pLast->Height() );
+            if( pCurr->GetAscent() < pLast->GetAscent() )
+                pCurr->SetAscent( pLast->GetAscent() );
+            pLast = pLast->GetPortion();
+        }
+    }
+}
+
+/*************************************************************************
+ *                  SwTxtFormatter::UnderFlow()
+ *************************************************************************/
+
+SwLinePortion *SwTxtFormatter::UnderFlow( SwTxtFormatInfo &rInf )
+{
+    // Werte sichern und rInf initialisieren.
+    SwLinePortion *pUnderFlow = rInf.GetUnderFlow();
+    if( !pUnderFlow )
+        return 0;
+
+    // Wir formatieren rueckwaerts, d.h. dass Attributwechsel in der
+    // naechsten Zeile durchaus noch einmal drankommen koennen.
+    // Zu beobachten in 8081.sdw, wenn man in der ersten Zeile Text eingibt.
+    nNextChg = 0;
+
+    const xub_StrLen nSoftHyphPos = rInf.GetSoftHyphPos();
+
+    // 8358, 8359: Flys sichern und auf 0 setzen, sonst GPF
+    // 3983: Nicht ClearFly(rInf) !
+    SwFlyPortion *pFly = rInf.GetFly();
+    rInf.SetFly( 0 );
+
+    FeedInf( rInf );
+    rInf.SetLast( pCurr );
+    // pUnderFlow braucht nicht deletet werden, weil es im folgenden
+    // Truncate() untergehen wird.
+    rInf.SetUnderFlow(0);
+    rInf.SetSoftHyphPos( nSoftHyphPos );
+
+    // Wir suchen die Portion mit der Unterlaufposition
+    SwLinePortion *pPor = pCurr->GetFirstPortion();
+    if( pPor != pUnderFlow )
+    {
+        // pPrev wird die letzte Portion vor pUnderFlow,
+        // die noch eine echte Breite hat.
+        // Ausnahme: SoftHyphPortions duerfen dabei natuerlich
+        // nicht vergessen werden, obwohl sie keine Breite haben.
+        SwLinePortion *pPrev = pPor;
+        while( pPor && pPor != pUnderFlow )
+        {
+            DBG_LOOP;
+            if( pPor->Width() || pPor->IsSoftHyphPortion() )
+            {
+                while( pPrev != pPor )
+                {
+                    pPrev->Move( rInf );
+                    rInf.SetLast( pPrev );
+                    pPrev = pPrev->GetPortion();
+                    ASSERT( pPrev, "UnderFlow: Loosing control!" );
+                };
+            }
+            pPor = pPor->GetPortion();
+        }
+        pPor = pPrev;
+        if( pPor && // Flies + Initialen werden nicht beim UnderFlow mitgenommen
+            ( pPor->IsFlyPortion() || pPor->IsDropPortion() ||
+              pPor->IsFlyCntPortion() ) )
+        {
+            pPor->Move( rInf );
+            rInf.SetLast( pPor );
+            rInf.SetStopUnderFlow( sal_True );
+            pPor = pUnderFlow;
+        }
+    }
+
+    // Was? Die Unterlaufsituation ist nicht in der Portion-Kette ?
+    ASSERT( pPor, "SwTxtFormatter::UnderFlow: overflow but underflow" );
+
+    if( rInf.IsFtnInside() && pPor && !rInf.IsQuick() )
+    {
+        SwLinePortion *pTmp = pPor->GetPortion();
+        while( pTmp )
+        {
+            if( pTmp->IsFtnPortion() )
+                ((SwFtnPortion*)pTmp)->ClearFtn();
+            pTmp = pTmp->GetPortion();
+        }
+    }
+
+    /*-----------------14.12.94 09:45-------------------
+     * 9849: Schnellschuss
+     * --------------------------------------------------*/
+    if ( pPor==rInf.GetLast() )
+    {
+        // Hier landen wir, wenn die UnderFlow-ausloesende Portion sich
+        // ueber die ganze Zeile erstreckt, z. B. wenn ein Wort ueber
+        // mehrere Zeilen geht und in der zweiten Zeile in einen Fly
+        // hineinlaeuft!
+        rInf.SetFly( pFly ); // wg. 28300
+        pPor->Truncate();
+        return pPor; // Reicht das?
+    }
+    /*---------------------------------------------------
+     * Ende des Schnellschusses wg. 9849
+     * --------------------------------------------------*/
+
+    // 4656: X + Width == 0 bei SoftHyph > Zeile ?!
+    if( !pPor || !(rInf.X() + pPor->Width()) )
+    {
+        delete pFly;
+        return 0;
+    }
+
+    // Vorbereitungen auf's Format()
+    // Wir muessen die Kette hinter pLast abknipsen, weil
+    // nach dem Format() ein Insert erfolgt.
+    SeekAndChg( rInf );
+
+    rInf.Width( rInf.X() + (pPor->Width() ? pPor->Width() - 1 : 0) );
+    rInf.SetLen( pPor->GetLen() );
+    rInf.SetFull( sal_False );
+    if( pFly )
+    {
+        // Aus folgendem Grund muss die FlyPortion neu berechnet werden:
+        // Wenn durch einen grossen Font in der Mitte der Zeile die Grundlinie
+        // abgesenkt wird und dadurch eine Ueberlappung mit eine Fly entsteht,
+        // so hat die FlyPortion eine falsche Groesse/Fixsize.
+        rInf.SetFly( pFly );
+        CalcFlyWidth( rInf );
+    }
+    rInf.GetLast()->SetPortion(0);
+
+    // Eine Ausnahme bildet das SwLineLayout, dass sich beim
+    // ersten Portionwechsel aufspaltet. Hier nun der umgekehrte Weg:
+    if( rInf.GetLast() == pCurr )
+    {
+        if( pPor->InTxtGrp() && !pPor->InExpGrp() )
+        {
+            MSHORT nOldWhich = pCurr->GetWhichPor();
+            *(SwLinePortion*)pCurr = *pPor;
+            pCurr->SetPortion( pPor->GetPortion() );
+            pCurr->SetWhichPor( nOldWhich );
+            pPor->SetPortion( 0 );
+            delete pPor;
+            pPor = pCurr;
+        }
+    }
+    pPor->Truncate();
+    delete rInf.GetRest();
+    rInf.SetRest(0);
+    return pPor;
+}
+
+/*************************************************************************
+ *                      SwTxtFormatter::InsertPortion()
+ *************************************************************************/
+
+void SwTxtFormatter::InsertPortion( SwTxtFormatInfo &rInf,
+                                    SwLinePortion *pPor ) const
+{
+    // Die neue Portion wird eingefuegt,
+    // bei dem LineLayout ist allerdings alles anders...
+    if( pPor == pCurr )
+    {
+        if( pCurr->GetPortion() )
+            pPor = pCurr->GetPortion();
+    }
+    else
+    {
+        SwLinePortion *pLast = rInf.GetLast();
+        if( pLast->GetPortion() )
+        {
+            while( pLast->GetPortion() )
+                pLast = pLast->GetPortion();
+            rInf.SetLast( pLast );
+        }
+        pLast->Insert( pPor );
+
+        // Maxima anpassen:
+        // Der PaintOfst muss zurueckgesetzt werden.
+        // Unterlaufsituation in Kombination mit Recycle()
+        if( pCurr->Height() < pPor->Height() )
+        {
+            pCurr->Height( pPor->Height() );
+            if( IsFirstReformat() )
+                rInf.SetPaintOfst(0);
+        }
+        if( pCurr->GetAscent() < pPor->GetAscent() )
+        {
+            pCurr->SetAscent( pPor->GetAscent() );
+            if( IsFirstReformat() )
+                rInf.SetPaintOfst(0);
+        }
+    }
+
+    // manchmal werden ganze Ketten erzeugt (z.B. durch Hyphenate)
+    rInf.SetLast( pPor );
+    while( pPor )
+    {
+        DBG_LOOP;
+        pPor->Move( rInf );
+        rInf.SetLast( pPor );
+        pPor = pPor->GetPortion();
+    }
+}
+
+/*************************************************************************
+ *                      SwTxtFormatter::BuildPortion()
+ *************************************************************************/
+
+void SwTxtFormatter::BuildPortions( SwTxtFormatInfo &rInf )
+{
+    ASSERT( rInf.GetTxt().Len() < STRING_LEN,
+            "SwTxtFormatter::BuildPortions: bad text length in info" );
+
+    rInf.ChkNoHyph( CntEndHyph(), CntMidHyph() );
+
+    // Es durchaus sein, dass pCurr durch Recycle() Daten enthaelt.
+    // Erst NewTxtPortion() entscheidet, ob pCurr in pPor landet.
+    // Wir muessen in jedem Fall dafuer sorgen, dass der Font eingestellt
+    // wird. In CalcAscent geschieht dies automatisch.
+    rInf.SetLast( pCurr->FindLastPortion() );
+    rInf.ForcedLeftMargin( 0 );
+    if( rInf.GetLast() == pCurr )
+    {
+        if( !pCurr->GetAscent() && !pCurr->Height() )
+            CalcAscent( rInf, pCurr );
+
+        SeekAndChg( rInf );
+
+        // In CalcFlyWidth wird Width() verkuerzt, wenn eine FlyPortion vorliegt.
+        ASSERT( !rInf.X(), "SwTxtFormatter::BuildPortion X=0?" );
+        CalcFlyWidth( rInf );
+        SwFlyPortion *pFly = rInf.GetFly();
+        if( pFly )
+        {
+            if ( 0 < pFly->Fix() )
+                ClearFly( rInf );
+            else
+                rInf.SetFull(sal_True);
+        }
+    }
+
+    SwLinePortion *pPor = NewPortion( rInf );
+    sal_Bool bFull;
+    rInf.Y( Y() );
+
+    while( pPor && !rInf.IsStop() )
+    {
+        ASSERT( rInf.GetLen() < STRING_LEN &&
+                rInf.GetIdx() <= rInf.GetTxt().Len(),
+                "SwTxtFormatter::BuildPortions: bad length in info" );
+        DBG_LOOP;
+        bFull = pPor->Format( rInf );
+
+        // Vorsicht: ein Fly im Blocksatz, dann kann das Repaint nur komplett
+        // hinter ihm oder vom Zeilenbeginn sein.
+#ifdef DEBUG
+        KSHORT nWhere = rInf.X();
+        long nLeft = GetLeftMargin();
+        SwTwips nPaintOfs = rInf.GetPaintOfst();
+#endif
+        if ( pPor->IsFlyPortion() && ( SVX_ADJUST_BLOCK == GetAdjust() )
+             && ( rInf.X() + GetLeftMargin() >= rInf.GetPaintOfst() ) )
+            rInf.SetPaintOfst( 0 );
+
+        if ( pPor->IsFlyCntPortion() )
+            SetFlyInCntBase();
+
+        rInf.SetFull( bFull );
+        // 5964: bUnderFlow muss zurueckgesetzt werden, sonst wird beim
+        //       naechsten Softhyphen wieder umgebrochen!
+        if ( !bFull )
+            rInf.ClrUnderFlow();
+
+        // Restportions von mehrzeiligen Feldern haben bisher noch
+        // nicht den richtigen Ascent.
+        if ( !pPor->GetLen() && !pPor->IsFlyPortion()
+            && !pPor->IsGrfNumPortion() )
+            CalcAscent( rInf, pPor );
+
+        InsertPortion( rInf, pPor );
+        pPor = NewPortion( rInf );
+    }
+
+    if( !rInf.IsStop() )
+    {
+        // der letzte rechte, zentrierte, dezimale Tab
+        SwTabPortion *pLastTab = rInf.GetLastTab();
+        if( pLastTab )
+            pLastTab->FormatEOL( rInf );
+        else if( rInf.GetLast() && rInf.GetLast()->IsKernPortion() )
+            rInf.GetLast()->FormatEOL( rInf );
+    }
+    if( pCurr->GetPortion() && pCurr->GetPortion()->InNumberGrp()
+        && ((SwNumberPortion*)pCurr->GetPortion())->IsHide() )
+        rInf.SetNumDone( sal_False );
+
+    // 3260, 3860: Fly auf jeden Fall loeschen!
+    ClearFly( rInf );
+}
+
+/*************************************************************************
+ *                 SwTxtFormatter::CalcAdjustLine()
+ *************************************************************************/
+
+void SwTxtFormatter::CalcAdjustLine( SwLineLayout *pCurr )
+{
+    if( SVX_ADJUST_LEFT != GetAdjust() )
+    {
+        pCurr->SetFormatAdj(sal_True);
+        if( IsFlyInCntBase() )
+        {
+            CalcAdjLine( pCurr );
+            // 23348: z.B. bei zentrierten Flys muessen wir den RefPoint
+            // auf jeden Fall umsetzen, deshalb bAllWays = sal_True
+            UpdatePos( pCurr, sal_True );
+        }
+    }
+}
+
+/*************************************************************************
+ *                      SwTxtFormatter::CalcAscent()
+ *************************************************************************/
+
+void SwTxtFormatter::CalcAscent( SwTxtFormatInfo &rInf, SwLinePortion *pPor )
+{
+    if ( pPor->InFldGrp() && ((SwFldPortion*)pPor)->GetFont() )
+    {
+        // Numerierungen + InterNetFlds koennen einen eigenen Font beinhalten,
+        // dann ist ihre Groesse unabhaengig von harten Attributierungen.
+        SwFont* pFldFnt = ((SwFldPortion*)pPor)->pFnt;
+        SwFontSave aSave( rInf, pFldFnt );
+        ((SwFldPortion*)pPor)->Height( pFldFnt->GetHeight( rInf.GetVsh(), rInf.GetOut() ) );
+        ((SwFldPortion*)pPor)->SetAscent( pFldFnt->GetAscent( rInf.GetVsh(), rInf.GetOut() ) );
+    }
+    else
+    {
+        const SwLinePortion *pLast = rInf.GetLast();
+        sal_Bool bChg;
+
+        // Fallunterscheidung: in leeren Zeilen werden die Attribute
+        // per SeekStart angeschaltet.
+        const sal_Bool bFirstPor = rInf.GetLineStart() == rInf.GetIdx();
+        if ( pPor->IsQuoVadisPortion() )
+            bChg = SeekStartAndChg( rInf, sal_True );
+        else
+        {
+            if( bFirstPor )
+            {
+                if( rInf.GetTxt().Len() )
+                {
+                    if ( pPor->GetLen() || !rInf.GetIdx()
+                         || ( pCurr != pLast && !pLast->IsFlyPortion() )
+                         || !pCurr->IsRest() ) // statt !rInf.GetRest()
+                        bChg = SeekAndChg( rInf );
+                    else
+                        bChg = SeekAndChgBefore( rInf );
+                }
+                else
+                    bChg = SeekStartAndChg( rInf );
+            }
+            else
+                bChg = SeekAndChg( rInf );
+        }
+        if( bChg || bFirstPor || !pPor->GetAscent()
+            || !rInf.GetLast()->InTxtGrp() )
+        {
+            pPor->SetAscent( rInf.GetAscent()  );
+            pPor->Height( rInf.GetTxtHeight() );
+        }
+        else
+        {
+            pPor->Height( pLast->Height() );
+            pPor->SetAscent( pLast->GetAscent() );
+        }
+    }
+}
+
+/*************************************************************************
+ *                      SwTxtFormatter::WhichTxtPor()
+ *************************************************************************/
+
+SwTxtPortion *SwTxtFormatter::WhichTxtPor( SwTxtFormatInfo &rInf ) const
+{
+    SwTxtPortion *pPor = 0;
+    if( GetFnt()->IsTox() )
+        pPor = new SwToxPortion;
+    else
+    {
+        if( GetFnt()->IsRef() )
+            pPor = new SwRefPortion;
+        else
+        {
+            // Erst zum Schluss !
+            // Wenn pCurr keine Breite hat, kann sie trotzdem schon Inhalt haben,
+            // z.B. bei nicht darstellbaren Zeichen.
+            if( !rInf.X() && !pCurr->GetPortion() && !pCurr->GetLen() &&
+                !GetFnt()->IsURL() )
+                pPor = pCurr;
+            else
+            {
+                pPor = new SwTxtPortion;
+                if( GetFnt()->IsURL() )
+                    pPor->SetWhichPor( POR_URL );
+            }
+        }
+    }
+    return pPor;
+}
+
+/*************************************************************************
+ *                      SwTxtFormatter::NewTxtPortion()
+ *************************************************************************/
+// Die Laenge wird ermittelt, folgende Portion-Grenzen sind definiert:
+// 1) Tabs
+// 2) Linebreaks
+// 3) CH_TXTATR_BREAKWORD / CH_TXTATR_INWORD
+// 4) naechster Attributwechsel
+
+SwTxtPortion *SwTxtFormatter::NewTxtPortion( SwTxtFormatInfo &rInf )
+{
+    // Wenn wir am Zeilenbeginn stehen, nehmen wir pCurr
+    // Wenn pCurr nicht von SwTxtPortion abgeleitet ist,
+    // muessen wir duplizieren ...
+    Seek( rInf.GetIdx() );
+    SwTxtPortion *pPor = WhichTxtPor( rInf );
+
+    nNextChg = 0;
+
+//  if( nNextChg <= rInf.GetIdx() )
+    {
+        // maximal bis zum naechsten Attributwchsel.
+        xub_StrLen nNextAttr = GetNextAttr();
+        nNextChg = Min( nNextAttr, rInf.GetTxt().Len() );
+        if ( nNextChg > 1 + rInf.GetIdx() && ' ' == rInf.GetChar( nNextChg-1 ) )
+            --nNextChg;
+
+#define GUESS_NEXTCHG
+#ifdef  GUESS_NEXTCHG
+        // 7515, 7516, 3470, 6441 : Turbo-Boost
+        // Es wird unterstellt, dass die Buchstaben eines Fonts nicht
+        // groesser als doppelt so breit wie hoch sind.
+        // 7659: Ganz verrueckt: man muss sich auf den Ascent beziehen.
+        // Falle: GetSize() enthaelt die Wunschhoehe, die reale Hoehe
+        // ergibt sich erst im CalcAscent!
+        // 7697: Das Verhaeltnis ist noch krasser: ein Blank im Times
+        // New Roman besitzt einen Ascent von 182, eine Hoehe von 200
+        // und eine Breite von 53! Daraus folgt, dass eine Zeile mit
+        // vielen Blanks falsch eingeschaetzt wird. Wir erhoehen von
+        // Faktor 2 auf 8 (wg. negativen Kernings).
+
+//        if( !pPor->GetAscent() )
+        pPor->SetLen(1);
+        CalcAscent( rInf, pPor );
+
+        const SwFont* pFnt = rInf.GetFont();
+        KSHORT nExpect = Min( KSHORT( ((Font *)pFnt)->GetSize().Height() ),
+                              KSHORT( pPor->GetAscent() ) ) / 8;
+        if ( !nExpect )
+            nExpect = 1;
+        nExpect = rInf.GetIdx() + ((rInf.Width() - rInf.X()) / nExpect);
+        if( nExpect > rInf.GetIdx() && nNextChg > nExpect )
+            nNextChg = Min( nExpect, rInf.GetTxt().Len() );
+
+#endif /* GUESS_NEXTCHG */
+
+        // 4294: Vorsicht vor STRING_LEN-Ueberrundungen !
+        if( MAX_TXTPORLEN < nNextChg && STRING_LEN - MAX_TXTPORLEN > rInf.GetIdx() )
+        {
+            const xub_StrLen nMaxChg = rInf.GetIdx() + MAX_TXTPORLEN;
+            if( nMaxChg < nNextChg )
+            {
+                // 6441: uebel ist, wenn die Portion passt...
+                const KSHORT nWidth =
+                      rInf.GetTxtSize(rInf.GetIdx(), MAX_TXTPORLEN ).Width();
+                if( nWidth > rInf.Width() )
+                    nNextChg = Min( nMaxChg, rInf.GetTxt().Len() );
+            }
+        }
+        nNextChg = rInf.ScanPortionEnd( nNextChg );
+    }
+    pPor->SetLen( nNextChg - rInf.GetIdx() );
+    rInf.SetLen( pPor->GetLen() );
+    return pPor;
+}
+
+
+/*************************************************************************
+ *                 SwTxtFormatter::WhichFirstPortion()
+ *************************************************************************/
+
+SwLinePortion *SwTxtFormatter::WhichFirstPortion(SwTxtFormatInfo &rInf) const
+{
+    SwLinePortion *pPor = 0;
+
+    if( rInf.GetRest() )
+    {
+        // 5010: Tabs und Felder
+        if( '\0' != rInf.GetHookChar() )
+            return 0;
+
+        pPor = rInf.GetRest();
+        if( pPor->IsErgoSumPortion() )
+            rInf.SetErgoDone(sal_True);
+        else
+            if( pPor->IsFtnNumPortion() )
+                rInf.SetFtnDone(sal_True);
+            else
+                if( pPor->InNumberGrp() )
+                    rInf.SetNumDone(sal_True);
+        if( pPor )
+        {
+            rInf.SetRest(0);
+            pCurr->SetRest( sal_True );
+            return pPor;
+        }
+    }
+
+    // ???? und ????: im Follow duerfen wir schon stehen,
+    // entscheidend ist, ob pFrm->GetOfst() == 0 ist!
+    if( rInf.GetIdx() )
+    {
+        // Nun koennen auch FtnPortions und ErgoSumPortions
+        // verlaengert werden.
+
+        // 1) Die ErgoSumTexte
+        if( !rInf.IsErgoDone() )
+        {
+            if( pFrm->IsInFtn() && !pFrm->GetIndPrev() )
+                pPor = (SwLinePortion*)NewErgoSumPortion( rInf );
+            rInf.SetErgoDone( sal_True );
+        }
+        if( !pPor && !rInf.IsArrowDone() )
+        {
+            if( pFrm->GetOfst() && !pFrm->IsFollow() &&
+                rInf.GetIdx() == pFrm->GetOfst() )
+                pPor = new SwArrowPortion( *pCurr );
+            rInf.SetArrowDone( sal_True );
+        }
+
+        // 2) Die Zeilenreste (mehrzeilige Felder)
+        if( !pPor )
+        {
+            pPor = rInf.GetRest();
+            // 6922: Nur bei pPor natuerlich.
+            if( pPor )
+            {
+                pCurr->SetRest( sal_True );
+                rInf.SetRest(0);
+            }
+        }
+    }
+    else
+    {
+        // 1) Die Fussnotenzahlen
+        if( !rInf.IsFtnDone() )
+        {
+            sal_Bool bFtnNum = pFrm->IsFtnNumFrm();
+            rInf.GetParaPortion()->SetFtnNum( bFtnNum );
+            if( bFtnNum )
+                pPor = (SwLinePortion*)NewFtnNumPortion( rInf );
+            rInf.SetFtnDone( sal_True );
+        }
+
+        // 2) Die ErgoSumTexte gibt es natuerlich auch im TextMaster,
+        // entscheidend ist, ob der SwFtnFrm ein Follow ist.
+        if( !rInf.IsErgoDone() && !pPor )
+        {
+            if( pFrm->IsInFtn() && !pFrm->GetIndPrev() )
+                pPor = (SwLinePortion*)NewErgoSumPortion( rInf );
+            rInf.SetErgoDone( sal_True );
+        }
+
+        // 3) Die Numerierungen
+        if( !rInf.IsNumDone() && !pPor )
+        {
+            // Wenn wir im Follow stehen, dann natuerlich nicht.
+            if( GetTxtFrm()->GetTxtNode()->GetNum() ||
+                GetTxtFrm()->GetTxtNode()->GetOutlineNum() )
+            {
+                pPor = (SwLinePortion*)NewNumberPortion( rInf );
+            }
+            rInf.SetNumDone( sal_True );
+        }
+        // 3) Die DropCaps
+        if( !pPor && GetDropFmt() )
+            pPor = (SwLinePortion*)NewDropPortion( rInf );
+    }
+    return pPor;
+}
+
+sal_Bool lcl_OldFieldRest( const SwLineLayout* pCurr )
+{
+    if( !pCurr->GetNext() )
+        return sal_False;
+    const SwLinePortion *pPor = pCurr->GetNext()->GetPortion();
+    sal_Bool bRet = sal_False;
+    while( pPor && !bRet && !pPor->GetLen() )
+    {
+        bRet = pPor->InFldGrp();
+        pPor = pPor->GetPortion();
+    }
+    return bRet;
+}
+
+/*************************************************************************
+ *                      SwTxtFormatter::NewPortion()
+ *************************************************************************/
+
+/* NewPortion stellt rInf.nLen ein.
+ * Eine SwTxtPortion wird begrenzt durch ein tab, break, txtatr,
+ * attrwechsel.
+ * Drei Faelle koennen eintreten:
+ * 1) Die Zeile ist voll und der Umbruch wurde nicht emuliert
+ *    -> return 0;
+ * 2) Die Zeile ist voll und es wurde ein Umbruch emuliert
+ *    -> Breite neu einstellen und return new FlyPortion
+ * 3) Es muss eine neue Portion gebaut werden.
+ *    -> CalcFlyWidth emuliert ggf. die Breite und return Portion
+ */
+
+SwLinePortion *SwTxtFormatter::NewPortion( SwTxtFormatInfo &rInf )
+{
+
+    // Underflow hat Vorrang
+    rInf.SetStopUnderFlow( sal_False );
+    if( rInf.GetUnderFlow() )
+    {
+        ASSERT( rInf.IsFull(), "SwTxtFormatter::NewPortion: underflow but not full" );
+        return UnderFlow( rInf );
+    }
+
+    // Wenn die Zeile voll ist, koennten noch Flys oder
+    // UnderFlow-LinePortions warten ...
+    if( rInf.IsFull() )
+    {
+        // ????: LineBreaks und Flys (bug05.sdw)
+        // 8450: IsDummy()
+        if( rInf.IsNewLine() && (!rInf.GetFly() || !pCurr->IsDummy()) )
+            return 0;
+
+        // Wenn der Text an den Fly gestossen ist, oder wenn
+        // der Fly als erstes drankommt, weil er ueber dem linken
+        // Rand haengt, wird GetFly() returnt.
+        // Wenn IsFull() und kein GetFly() vorhanden ist, gibt's
+        // naturgemaesz eine 0.
+        if( rInf.GetFly() )
+        {
+            if( rInf.GetLast()->IsBreakPortion() )
+            {
+                delete rInf.GetFly();
+                rInf.SetFly( 0 );
+            }
+            return rInf.GetFly();
+        }
+        // Ein fieser Sonderfall: ein Rahmen ohne Umlauf kreuzt den
+        // Ftn-Bereich. Wir muessen die Ftn-Portion als Zeilenrest
+        // bekanntgeben, damit SwTxtFrm::Format nicht abbricht
+        // (die Textmasse wurde ja durchformatiert).
+        if( rInf.GetRest() )
+            rInf.SetNewLine( sal_True );
+        else
+        {
+            // Wenn die naechste Zeile mit einem Rest eines Feldes beginnt,
+            // jetzt aber kein Rest mehr anliegt,
+            // muss sie auf jeden Fall neu formatiert werden!
+            if( lcl_OldFieldRest( GetCurr() ) )
+                rInf.SetNewLine( sal_True );
+            else
+            {
+                SwLinePortion *pFirst = WhichFirstPortion( rInf );
+                if( pFirst )
+                {
+                    rInf.SetNewLine( sal_True );
+                    if( pFirst->InNumberGrp() )
+                        rInf.SetNumDone( sal_False) ;
+                    delete pFirst;
+                }
+            }
+        }
+
+        // Wenn die Zeile voll ist und ein Blank am Zeilenende
+        // steht, dann muss es in einer HolePortion verborgen werden
+        // (trailing blank).
+        // 8518: keine HolePortions bei mehrzeiligen Feldern.
+        if( rInf.GetIdx() < rInf.GetTxt().Len() &&
+            rInf.GetIdx() && ' ' == rInf.GetChar( rInf.GetIdx() )
+            && !rInf.GetLast()->IsHolePortion() && !rInf.GetRest()
+            && CH_BREAK != rInf.GetChar( rInf.GetIdx() - 1 ) )
+        {
+            SwHolePortion *pHole = new SwHolePortion( *rInf.GetLast() );
+            xub_StrLen nCnt = rInf.GetIdx();
+            xub_StrLen nLen = rInf.GetTxt().Len();
+            while ( nCnt < nLen && ' ' == rInf.GetChar( nCnt ) )
+                nCnt++;
+            pHole->SetLen( nCnt - rInf.GetIdx() );
+            return pHole;
+        }
+        return 0;
+    }
+
+    SwLinePortion *pPor = WhichFirstPortion( rInf );
+    if( !pPor )
+    {
+        // 5010: Tabs und Felder
+        xub_Unicode cChar = rInf.GetHookChar();
+
+        if( cChar )
+        {
+            /* Wir holen uns nocheinmal cChar, um sicherzustellen, dass das
+             * Tab jetzt wirklich ansteht und nicht auf die naechste Zeile
+             * gewandert ist ( so geschehen hinter Rahmen ).
+             * Wenn allerdings eine FldPortion im Rest wartet, muessen wir
+             * das cChar natuerlich aus dem Feldinhalt holen, z.B. bei
+             * DezimalTabs und Feldern (22615)
+            */
+            if( !rInf.GetRest() || !rInf.GetRest()->InFldGrp() )
+                cChar = rInf.GetChar( rInf.GetIdx() );
+            rInf.SetHookChar(0);
+        }
+        else
+        {
+            if( rInf.GetIdx() >= rInf.GetTxt().Len() )
+            {
+                rInf.SetFull(sal_True);
+                CalcFlyWidth( rInf );
+                return pPor;
+            }
+            cChar = rInf.GetChar( rInf.GetIdx() );
+        }
+
+        switch( cChar )
+        {
+            case CH_TAB    : pPor = NewTabPortion( rInf );  break;
+            case CH_BREAK  : pPor = new SwBreakPortion( *rInf.GetLast() ); break;
+
+            case CHAR_SOFTHYPHEN:                   // soft hyphen
+                pPor = new SwSoftHyphPortion; break;
+
+            case CHAR_HARDBLANK:                    // no-break space
+                pPor = new SwBlankPortion( ' ' ); break;
+            case CHAR_HARDHYPHEN:               // non-breaking hyphen
+                pPor = new SwBlankPortion( '-' ); break;
+
+            case CH_TXTATR_BREAKWORD:
+            case CH_TXTATR_INWORD:
+                            if( rInf.HasHint( rInf.GetIdx() ) )
+                            {
+                                pPor = NewExtraPortion( rInf );
+                                break;
+                            }
+                            // No break
+            default        :
+            {
+                if( rInf.GetLastTab() && cChar == rInf.GetTabDecimal() )
+                    rInf.SetFull( rInf.GetLastTab()->Format( rInf ) );
+
+                if( rInf.GetRest() )
+                {
+                    if( rInf.IsFull() )
+                    {
+                        rInf.SetNewLine(sal_True);
+                        return 0;
+                    }
+                    pPor = rInf.GetRest();
+                    rInf.SetRest(0);
+                }
+                else
+                {
+                    if( rInf.IsFull() )
+                        return 0;
+                    pPor = NewTxtPortion( rInf );
+                }
+                break;
+            }
+        }
+
+        // Wenn eine Portion erzeugt wird, obwohl eine RestPortion ansteht,
+        // dann haben wir es mit einem Feld zu tun, das sich aufgesplittet
+        // hat, weil z.B. ein Tab enthalten ist.
+        if( pPor && rInf.GetRest() )
+            pPor->SetLen( 0 );
+
+        // robust:
+        if( !pPor || rInf.IsStop() )
+        {
+            delete pPor;
+            return 0;
+        }
+    }
+
+    // Der Font wird im Outputdevice eingestellt,
+    // der Ascent und die Hoehe werden berechnet.
+    if( !pPor->GetAscent() && !pPor->Height() )
+        CalcAscent( rInf, pPor );
+    rInf.SetLen( pPor->GetLen() );
+
+    // In CalcFlyWidth wird Width() verkuerzt, wenn eine FlyPortion vorliegt.
+    CalcFlyWidth( rInf );
+
+    // Man darf nicht vergessen, dass pCurr als GetLast() vernuenftige
+    // Werte bereithalten muss:
+    if( !pCurr->Height() )
+    {
+        ASSERT( pCurr->Height(), "SwTxtFormatter::NewPortion: limbo dance" );
+        pCurr->Height( pPor->Height() );
+        pCurr->SetAscent( pPor->GetAscent() );
+    }
+
+    ASSERT( !pPor || pPor->Height(),
+            "SwTxtFormatter::NewPortion: something went wrong");
+    if( pPor->IsPostItsPortion() && rInf.X() >= rInf.Width() && rInf.GetFly() )
+    {
+        delete pPor;
+        pPor = rInf.GetFly();
+    }
+    return pPor;
+}
+
+/*************************************************************************
+ *                      SwTxtFormatter::FormatLine()
+ *************************************************************************/
+
+xub_StrLen SwTxtFormatter::FormatLine( const xub_StrLen nStart )
+{
+    SwHookOut aHook( &GetInfo() );
+    if( GetInfo().GetLen() < GetInfo().GetTxt().Len() )
+        GetInfo().SetLen( GetInfo().GetTxt().Len() );
+
+    sal_Bool bBuild = sal_True;
+    SetFlyInCntBase( sal_False );
+    GetInfo().SetLineHeight( 0 );
+    GetInfo().SetPaintOfst( 0 );
+
+    // Recycling muss bei geaenderter Zeilenhoehe unterdrueckt werden
+    // und auch bei geaendertem Ascent (Absenken der Grundlinie).
+    const KSHORT nOldHeight = pCurr->Height();
+    const KSHORT nOldAscent = pCurr->GetAscent();
+
+    pCurr->SetEndHyph( sal_False );
+    pCurr->SetMidHyph( sal_False );
+
+    // Hier folgt bald die Unterlaufpruefung.
+    while( bBuild )
+    {
+        sal_Bool bOldNumDone = GetInfo().IsNumDone();
+        sal_Bool bOldArrowDone = GetInfo().IsArrowDone();
+        GetInfo().SetFtnInside( sal_False );
+        FeedInf( GetInfo() );
+        Recycle( GetInfo() );   // initialisiert sich oder rettet Portions
+        if( bOldNumDone )
+            GetInfo().SetNumDone( sal_True );
+        if( bOldArrowDone )
+            GetInfo().SetArrowDone( sal_True );
+        BuildPortions( GetInfo() );
+        if( GetInfo().IsStop() )
+        {
+            pCurr->SetLen( 0 );
+            pCurr->Height( GetFrmRstHeight() + 1 );
+            pCurr->SetRealHeight( GetFrmRstHeight() + 1 );
+            pCurr->Width(0);
+            pCurr->Truncate();
+            return nStart;
+        }
+        else if( GetInfo().IsDropInit() )
+        {
+            DropInit();
+            GetInfo().SetDropInit( sal_False );
+        }
+
+        pCurr->CalcLine( *this );
+        CalcRealHeight( GetInfo().IsNewLine() );
+
+        if ( IsFlyInCntBase() && !IsQuick() )
+        {
+            KSHORT nTmpAscent, nTmpHeight;
+            CalcAscentAndHeight( nTmpAscent, nTmpHeight );
+            AlignFlyInCntBase( Y() + long( nTmpAscent ) );
+            pCurr->CalcLine( *this );
+            CalcRealHeight();
+        }
+
+        // bBuild entscheidet, ob noch eine Ehrenrunde gedreht wird
+        bBuild = !GetInfo().GetLineHeight() &&
+                ( GetInfo().GetTxtFly()->IsOn() && ChkFlyUnderflow( GetInfo() )
+                || GetInfo().CheckFtnPortion( pCurr ) );
+        if( bBuild )
+        {
+            GetInfo().SetNumDone( bOldNumDone );
+            pCurr->SetLen( 0 );
+            pCurr->Width(0);
+            pCurr->Truncate();
+        }
+    }
+
+    xub_StrLen nNewStart = nStart + pCurr->GetLen();
+    CalcAdjustLine( pCurr );
+
+    if( nOldHeight != pCurr->Height() || nOldAscent != pCurr->GetAscent() )
+    {
+        SetFlyInCntBase();
+        GetInfo().SetPaintOfst( 0 ); //geaenderte Zeilenhoehe => kein Recycling
+        // alle weiteren Zeilen muessen gepaintet und, wenn Flys im Spiel sind
+        // auch formatiert werden.
+        GetInfo().SetShift( sal_True );
+    }
+
+    if ( IsFlyInCntBase() && !IsQuick() )
+        UpdatePos( pCurr );
+
+    return nNewStart;
+}
+
+/*************************************************************************
+ *                      SwTxtFormatter::FeedInf()
+ *************************************************************************/
+
+void SwTxtFormatter::FeedInf( SwTxtFormatInfo &rInf ) const
+{
+    // 3260, 3860: Fly auf jeden Fall loeschen!
+    ClearFly( rInf );
+    rInf.Init();
+
+    rInf.ChkNoHyph( CntEndHyph(), CntMidHyph() );
+    rInf.SetRoot( pCurr );
+    rInf.SetLineStart( nStart );
+    rInf.SetIdx( nStart );
+    rInf.Left( KSHORT(Left()) );
+    rInf.Right( KSHORT(Right()) );
+    rInf.First( short(FirstLeft()) );
+    rInf.RealWidth( KSHORT(rInf.Right()) - KSHORT(GetLeftMargin()) );
+    rInf.Width( rInf.RealWidth() );
+    if( ((SwTxtFormatter*)this)->GetRedln() )
+    {
+        ((SwTxtFormatter*)this)->GetRedln()->Clear( ((SwTxtFormatter*)this)->GetFnt() );
+        ((SwTxtFormatter*)this)->GetRedln()->Reset();
+    }
+}
+
+/*************************************************************************
+ *                      SwTxtFormatter::FormatReset()
+ *************************************************************************/
+
+void SwTxtFormatter::FormatReset( SwTxtFormatInfo &rInf )
+{
+    pCurr->Truncate();
+    pCurr->Init();
+    if( pBlink && pCurr->IsBlinking() )
+        pBlink->Delete( pCurr );
+    pCurr->ResetFlags();
+    FeedInf( rInf );
+}
+
+/*************************************************************************
+ *                SwTxtFormatter::CalcOnceMore()
+ *************************************************************************/
+
+sal_Bool SwTxtFormatter::CalcOnceMore()
+{
+    if( pDropFmt )
+    {
+        const KSHORT nOldDrop = GetDropHeight();
+        CalcDropHeight( pDropFmt->GetLines() );
+        bOnceMore = nOldDrop != GetDropHeight();
+    }
+    else
+        bOnceMore = sal_False;
+    return bOnceMore;
+}
+
+/*************************************************************************
+ *                SwTxtFormatter::CalcBottomLine()
+ *************************************************************************/
+
+SwTwips SwTxtFormatter::CalcBottomLine() const
+{
+    SwTwips nRet = Y() + GetLineHeight();
+    SwTwips nMin = GetInfo().GetTxtFly()->GetMinBottom();
+    if( nMin && ++nMin > nRet )
+    {
+        SwTwips nDist = pFrm->Frm().Height() - pFrm->Prt().Height()
+                        - pFrm->Prt().Top();
+        if( nRet + nDist < nMin )
+        {
+            sal_Bool bRepaint = HasTruncLines() &&
+                GetInfo().GetParaPortion()->GetRepaint()->Bottom() == nRet-1;
+            nRet = nMin - nDist;
+            if( bRepaint )
+            {
+                ((SwRepaint*)GetInfo().GetParaPortion()
+                    ->GetRepaint())->Bottom( nRet-1 );
+                ((SwTxtFormatInfo&)GetInfo()).SetPaintOfst( 0 );
+            }
+        }
+    }
+    return nRet;
+}
+
+/*************************************************************************
+ *                SwTxtFormatter::_CalcFitToContent()
+ *************************************************************************/
+
+KSHORT SwTxtFormatter::_CalcFitToContent()
+{
+    GetInfo().SetRoot( pCurr );
+
+    GetInfo().First( KSHORT(FirstLeft()) );
+    GetInfo().Left( KSHORT(Left()) );
+
+    SeekAndChg( GetInfo() );
+    GetInfo().SetLast( GetInfo().GetRoot() );
+
+    SwLinePortion *pPor = NewPortion( GetInfo() );
+
+    long nMaxWidth = 0;
+    long nWidth = 0;
+    long nMargin = FirstLeft();
+    sal_Bool bFull = sal_False;
+    while( pPor && !IsStop() && !bFull)
+    {
+        bFull = pPor->Format( GetInfo() );
+        GetInfo().SetLast( pPor );
+        while( pPor )
+        {
+            nWidth += pPor->Width();
+            pPor->Move( GetInfo() );
+            GetInfo().SetLast( pPor );
+            pPor = pPor->GetPortion();
+        }
+        if( bFull && 0 != ( pPor = GetInfo().GetLast() ) && pPor->IsBreakPortion() )
+        {
+            if ( nWidth && (nMaxWidth < nWidth+nMargin ) )
+                nMaxWidth = nWidth + nMargin;
+            nWidth = 0;
+            nMargin = Left();
+            bFull = sal_False;
+            GetInfo().X( KSHORT(nMargin) );
+        }
+        pPor = NewPortion( GetInfo() );
+    }
+    if ( nWidth && ( nMaxWidth < nWidth + nMargin ) )
+        nMaxWidth = nWidth + nMargin;
+    return KSHORT(nMaxWidth);
+}
+
diff --git a/sw/source/core/text/itrform2.hxx b/sw/source/core/text/itrform2.hxx
new file mode 100644
index 000000000000..a908b7c072d2
--- /dev/null
+++ b/sw/source/core/text/itrform2.hxx
@@ -0,0 +1,236 @@
+/*************************************************************************
+ *
+ *  $RCSfile: itrform2.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _ITRFORM2_HXX
+#define _ITRFORM2_HXX
+
+#include "itrpaint.hxx"
+
+class SwFlyCntPortion;
+class SwInterHyphInfo;
+class SwDropPortion;
+class SwFmtDrop;
+class SwDrawObjs;
+class SwTxtAttr;
+class SwNumberPortion;
+class SwErgoSumPortion;
+class SwExpandPortion;
+
+/*************************************************************************
+ *                      class SwTxtFormatter
+ *************************************************************************/
+
+class SwTxtFormatter : public SwTxtPainter
+{
+    const SwFmtDrop *pDropFmt;
+    xub_StrLen nNextChg;
+    sal_uInt8 nCntEndHyph;  // zaehlt aufeinanderfolgende Hyphens am Zeilenende
+    sal_uInt8 nCntMidHyph;  // zaehlt aufeinanderfolgende Hyphens vor Flies
+    sal_Bool bOnceMore : 1; // noch 'ne Runde?
+    sal_Bool bFlyInCntBase : 1; // Base-Referenz der zeichengeb. Rahmen setzen
+    sal_Bool bChanges : 1; // Flag, fuer die Berechnung des Repaint-Rechtecks
+    sal_Bool bTruncLines : 1; // Flag, Repaint-Rechtecks ggf. erweitern
+    sal_Bool bUnclipped : 1; // Flag, ob Repaint groesser als feste Zeilenhoehe
+    SwLinePortion *NewPortion( SwTxtFormatInfo &rInf );
+    SwTxtPortion  *NewTxtPortion( SwTxtFormatInfo &rInf );
+    SwLinePortion *NewExtraPortion( SwTxtFormatInfo &rInf );
+    SwTabPortion *NewTabPortion( SwTxtFormatInfo &rInf ) const;
+    SwNumberPortion *NewNumberPortion( SwTxtFormatInfo &rInf ) const;
+    SwDropPortion *NewDropPortion( SwTxtFormatInfo &rInf ) const;
+    SwNumberPortion *NewFtnNumPortion( SwTxtFormatInfo &rInf ) const;
+    SwErgoSumPortion *NewErgoSumPortion( SwTxtFormatInfo &rInf ) const;
+    SwExpandPortion *NewFldPortion( SwTxtFormatInfo &rInf, SwTxtAttr *pHt ) const;
+    SwFtnPortion *NewFtnPortion( SwTxtFormatInfo &rInf, SwTxtAttr *pHt );
+    SwFlyCntPortion *NewFlyCntPortion( SwTxtFormatInfo &rInf,
+                                       SwTxtAttr *pHt ) const;
+    SwLinePortion *WhichFirstPortion( SwTxtFormatInfo &rInf ) const;
+    SwTxtPortion *WhichTxtPor( SwTxtFormatInfo &rInf ) const;
+
+    // Das Herzstueck der Formatierung
+    void BuildPortions( SwTxtFormatInfo &rInf );
+
+    // Initialisierung oder Wiederverwertung alter Portions
+    void Recycle( SwTxtFormatInfo &rInf );
+
+
+    // Berechnung des emulierten rechten Rands
+    void CalcFlyWidth( SwTxtFormatInfo &rInf ) const;
+
+    // wird von SwTxtFormatter wegen UpdatePos ueberladen
+    void CalcAdjustLine( SwLineLayout *pCurr );
+
+    // uebertraegt die Daten nach rInf
+    void FeedInf( SwTxtFormatInfo &rInf ) const;
+
+    // behandelt die Unterlaufsituationen
+    SwLinePortion *UnderFlow( SwTxtFormatInfo &rInf );
+
+    // errechnet den Ascent und die Hoehe aus der Fontmetric
+    void CalcAscent( SwTxtFormatInfo &rInf, SwLinePortion *pPor );
+
+    // wird von Recycle() gerufen.
+    void FormatReset( SwTxtFormatInfo &rInf );
+
+    // Sind wir in der ersten zu formatierenden Zeile?
+    inline sal_Bool IsFirstReformat() const
+        { return GetInfo().GetIdx() < GetInfo().GetReformatStart(); }
+
+    // durch das Adjustment aendert sich die Position der Portions
+    void UpdatePos( SwLineLayout *pCurr, sal_Bool bAllWays = sal_False ) const;
+
+    // Setze alle FlyInCntFrms auf die uebergebene BaseLine
+    void AlignFlyInCntBase( long nBaseLine ) const;
+
+    // Unterlaufbedingungen bei Flys
+    sal_Bool ChkFlyUnderflow( SwTxtFormatInfo &rInf ) const;
+
+    // Portion einfuegen.
+    void InsertPortion( SwTxtFormatInfo &rInf, SwLinePortion *pPor ) const;
+
+    // schaetzt die Hoehe fuer die DropPortion
+    void GuessDropHeight( const MSHORT nLines );
+
+public:
+    // errechnet die Hoehe fuer die DropPortion
+    void CalcDropHeight( const MSHORT nLines );
+
+    // errechnet den Bottom des Absatzes, beruecksichtigt an diesem verankerte
+    // Objekte mit Umlauf 1. Absatz.
+    SwTwips CalcBottomLine() const;
+
+    // Beruecksichtigt zeichengebundene Objekte bei der Repaintrechteck-
+    // berechnung in Zeilen mit fester Zeilenhoehe
+    void CalcUnclipped( SwTwips& rTop, SwTwips& rBottom );
+
+    // u.a. fuer DropCaps
+    sal_Bool CalcOnceMore();
+
+    void CtorInit( SwTxtFrm *pFrm, SwTxtFormatInfo *pInf );
+    inline SwTxtFormatter( SwTxtFrm *pFrm, SwTxtFormatInfo *pInf )
+           { CtorInit( pFrm, pInf ); }
+    ~SwTxtFormatter();
+
+    xub_StrLen FormatLine( const xub_StrLen nStart );
+
+    // Wir formatieren eine Zeile fuer die interaktive Trennung
+    sal_Bool Hyphenate( SwInterHyphInfo &rInf );
+
+    // Spezialmethode fuer QuoVadis-Texte
+    // nErgo ist die Seitennummer der ErgoSum-Ftn
+    // Bei 0 ist es noch unklar.
+    xub_StrLen FormatQuoVadis( const xub_StrLen nStart );
+
+    // Die Notbremse: Formatierung abbrechen, Zeile verwerfen.
+    inline sal_Bool IsStop() const { return GetInfo().IsStop(); }
+
+    // Das Gegenstueck: Formatierung unbedingt fortsetzen.
+    inline sal_Bool IsNewLine() const { return GetInfo().IsNewLine(); }
+
+    // FormatQuick(); auffrischen von Formatinformationen
+    inline sal_Bool IsQuick() const { return GetInfo().IsQuick(); }
+
+    // erzeugt ggfs. ein SwLineLayout, dass Ftn/Fly--Oszillation unterbindet.
+    void MakeDummyLine();
+
+    // SwTxtIter-Funktionalitaet
+    void Insert( SwLineLayout *pLine );
+
+    // die noch verbleibende Hoehe bis zum Seitenrand
+    KSHORT GetFrmRstHeight() const;
+
+    // Wie breit waerest Du ohne rechte Begrenzungen (Flys etc.)?
+    KSHORT _CalcFitToContent( );
+
+    SwFldPortion *GetFieldRest( SwTxtFormatInfo &rInf ) const;
+    void MakeRestPortion();
+
+    inline const SwFmtDrop *GetDropFmt() const { return pDropFmt; }
+    inline void ClearDropFmt() { pDropFmt = 0; }
+
+    inline const sal_Bool IsOnceMore() const { return bOnceMore; }
+    inline void       SetOnceMore( sal_Bool bNew ) { bOnceMore = bNew; }
+
+    inline const sal_Bool HasChanges() const { return bChanges; }
+    inline void       SetChanges()       { bChanges = sal_True; }
+
+    inline const sal_Bool HasTruncLines() const { return bTruncLines; }
+    inline void       SetTruncLines( sal_Bool bNew ) { bTruncLines = bNew; }
+
+    inline const sal_Bool IsUnclipped() const { return bUnclipped; }
+    inline void       SetUnclipped( sal_Bool bNew ) { bUnclipped = bNew; }
+
+    inline const sal_Bool IsFlyInCntBase() const { return bFlyInCntBase; }
+    inline void  SetFlyInCntBase( sal_Bool bNew = sal_True ){ bFlyInCntBase = bNew; }
+
+    inline SwTxtFormatInfo &GetInfo()
+        { return (SwTxtFormatInfo&)SwTxtIter::GetInfo(); }
+    inline const SwTxtFormatInfo &GetInfo() const
+        { return (const SwTxtFormatInfo&)SwTxtIter::GetInfo(); }
+
+    inline void InitCntHyph() { CntHyphens( nCntEndHyph, nCntMidHyph ); }
+    inline const sal_uInt8 &CntEndHyph() const { return nCntEndHyph; }
+    inline const sal_uInt8 &CntMidHyph() const { return nCntMidHyph; }
+    inline sal_uInt8 &CntEndHyph() { return nCntEndHyph; }
+    inline sal_uInt8 &CntMidHyph() { return nCntMidHyph; }
+};
+
+
+
+#endif
diff --git a/sw/source/core/text/itrpaint.cxx b/sw/source/core/text/itrpaint.cxx
new file mode 100644
index 000000000000..885297f47f46
--- /dev/null
+++ b/sw/source/core/text/itrpaint.cxx
@@ -0,0 +1,548 @@
+/*************************************************************************
+ *
+ *  $RCSfile: itrpaint.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "hintids.hxx"
+#include "flyfrm.hxx"     // SwFlyInCntFrm
+#include "viewopt.hxx"  // SwViewOptions
+#include "errhdl.hxx"
+#include "txtatr.hxx"  // SwINetFmt
+
+#ifndef _SV_MULTISEL_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_ESCPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_UDLNITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _TXTINET_HXX //autogen
+#include 
+#endif
+#ifndef _FCHRFMT_HXX //autogen
+#include 
+#endif
+#ifndef _FRMATR_HXX
+#include 
+#endif
+#include "flyfrms.hxx"
+#include "viewsh.hxx"
+#include "txtcfg.hxx"
+#include "itrpaint.hxx"
+#include "txtfrm.hxx"   // pFrm
+#include "txtfly.hxx"
+#include "swfont.hxx"
+#include "txtpaint.hxx"
+#include "portab.hxx"   // SwTabPortion::IsFilled
+#include "porfly.hxx"     // SwFlyCntPortion
+#include "porfld.hxx"   // SwGrfNumPortion
+#include "frmfmt.hxx"   // LRSpace
+#include "txatbase.hxx" // SwTxtAttr
+#include "charfmt.hxx"  // SwFmtCharFmt
+#include "redlnitr.hxx" // SwRedlineItr
+#include "porrst.hxx"   // SwArrowPortion
+
+/*************************************************************************
+ *                  SwTxtPainter::CtorInit()
+ *************************************************************************/
+void SwTxtPainter::CtorInit( SwTxtFrm *pFrm, SwTxtPaintInfo *pNewInf )
+{
+    SwTxtCursor::CtorInit( pFrm, pNewInf );
+    pInf = pNewInf;
+    SwFont *pFnt = GetFnt();
+    GetInfo().SetFont( pFnt );
+#ifndef PRODUCT
+    if( ALIGN_BASELINE != pFnt->GetAlign() )
+    {
+        ASSERT( ALIGN_BASELINE == pFnt->GetAlign(),
+                "+SwTxtPainter::CTOR: font alignment revolution" );
+        pFnt->SetAlign( ALIGN_BASELINE );
+    }
+#endif
+    bPaintDrop = sal_False;
+}
+
+
+/*************************************************************************
+ *                    SwTxtPainter::CalcPaintOfst()
+ *************************************************************************/
+SwLinePortion *SwTxtPainter::CalcPaintOfst( const SwRect &rPaint )
+{
+    SwLinePortion *pPor = pCurr->GetFirstPortion();
+    GetInfo().SetPaintOfst( 0 );
+    SwTwips nPaintOfst = rPaint.Left();
+
+    // nPaintOfst wurde exakt auf das Ende eingestellt, deswegen <=
+    // nPaintOfst ist dokumentglobal, deswegen nLeftMar aufaddieren
+    // const KSHORT nLeftMar = KSHORT(GetLeftMargin());
+    // 8310: painten von LineBreaks in leeren Zeilen.
+    if( nPaintOfst && pCurr->Width() )
+    {
+        SwLinePortion *pLast = 0;
+        // 7529 und 4757: nicht <= nPaintOfst
+        while( pPor && GetInfo().X() + pPor->Width() + (pPor->Height()/2)
+                       < nPaintOfst )
+        {
+            DBG_LOOP;
+            if( pPor->InTxtGrp() && GetInfo().GetSpaceAdd() )
+            {
+                long nTmp = GetInfo().X() +pPor->Width() +((SwTxtPortion*)pPor)
+                    ->CalcSpacing( GetInfo().GetSpaceAdd(), GetInfo() );
+                if( nTmp + (pPor->Height()/2) >= nPaintOfst )
+                    break;
+                GetInfo().X( nTmp );
+                GetInfo().SetIdx( GetInfo().GetIdx() + pPor->GetLen() );
+            }
+            else
+                pPor->Move( GetInfo() );
+            pLast = pPor;
+            pPor = pPor->GetPortion();
+        }
+
+#ifndef USED
+        // 7529: bei PostIts auch pLast returnen.
+        if( pLast && !pLast->Width() && pLast->IsPostItsPortion() )
+        {
+            pPor = pLast;
+            GetInfo().SetIdx( GetInfo().GetIdx() - pPor->GetLen() );
+        }
+#endif
+    }
+    return pPor;
+}
+
+/*************************************************************************
+ *                    SwTxtPainter::DrawTextLine()
+ *
+ * Es gibt zwei Moeglichkeiten bei transparenten Font auszugeben:
+ * 1) DrawRect auf die ganze Zeile und die DrawText hinterher
+ *    (objektiv schnell, subjektiv langsam).
+ * 2) Fuer jede Portion ein DrawRect mit anschliessendem DrawText
+ *    ausgefuehrt (objektiv langsam, subjektiv schnell).
+ * Da der User in der Regel subjektiv urteilt, wird die 2. Methode
+ * als Default eingestellt.
+ *************************************************************************/
+void SwTxtPainter::DrawTextLine( const SwRect &rPaint, SwSaveClip &rClip,
+                                 const sal_Bool bUnderSz )
+{
+    // Adjustierung ggf. nachholen
+    GetAdjusted();
+    GetInfo().SetSpaceAdd( pCurr->GetpSpaceAdd() );
+    GetInfo().ResetSpaceIdx();
+    // Die Groesse des Frames
+    GetInfo().SetIdx( GetStart() );
+    GetInfo().SetPos( GetTopLeft() );
+
+    const sal_Bool bDrawInWindow = GetInfo().OnWin();
+
+    // 6882: Leerzeilen duerfen nicht wegoptimiert werden bei Paragraphzeichen.
+    const sal_Bool bEndPor = GetInfo().GetOpt().IsParagraph() && !GetInfo().GetTxt().Len();
+
+    SwLinePortion *pPor = bEndPor ? pCurr->GetFirstPortion() : CalcPaintOfst( rPaint );
+
+    // Optimierung!
+    const SwTwips nMaxRight = Min( rPaint.Right(), Right() );
+    const SwTwips nTmpLeft = GetInfo().X();
+    if( !bEndPor && nTmpLeft >= nMaxRight )
+        return;
+
+    // DropCaps!
+    // 7538: natuerlich auch auf dem Drucker
+    if( !bPaintDrop )
+    {
+        // 8084: Optimierung, weniger Painten.
+        // AMA: Durch 8084 wurde 7538 wiederbelebt!
+        // bDrawInWindow entfernt, damit DropCaps auch gedruckt werden
+        bPaintDrop = pPor == pCurr->GetFirstPortion()
+                     && GetDropLines() >= GetLineNr();
+    }
+
+    KSHORT nTmpHeight, nTmpAscent;
+    CalcAscentAndHeight( nTmpAscent, nTmpHeight );
+
+    // bClip entscheidet darueber, ob geclippt werden muss.
+    // Das Ganze muss vor der Retusche stehen
+
+    sal_Bool bClip = ( bDrawInWindow || bUnderSz ) && !rClip.IsChg();
+    if( bClip && pPor )
+    {
+        // Wenn TopLeft oder BottomLeft der Line ausserhalb liegen,
+        // muss geclippt werden. Die Ueberpruefung auf Right() erfolgt
+        // in der folgenden Ausgabeschleife...
+
+        if( GetInfo().GetPos().X() < rPaint.Left() ||
+            GetInfo().GetPos().Y() < rPaint.Top() ||
+            GetInfo().GetPos().Y() + nTmpHeight > rPaint.Top() + rPaint.Height() )
+        {
+            bClip = sal_False;
+            rClip.ChgClip( rPaint );
+        }
+#ifdef DEBUG
+        static sal_Bool bClipAlways = sal_False;
+        if( bClip && bClipAlways )
+        {   bClip = sal_False;
+            rClip.ChgClip( rPaint );
+        }
+#endif
+    }
+
+    // Alignment:
+    sal_Bool bPlus = sal_False;
+    OutputDevice *pOut = GetInfo().GetOut();
+    Point aPnt1( nTmpLeft, GetInfo().GetPos().Y() );
+    if ( aPnt1.X() < rPaint.Left() )
+        aPnt1.X() = rPaint.Left();
+    if ( aPnt1.Y() < rPaint.Top() )
+        aPnt1.Y() = rPaint.Top();
+    Point aPnt2( GetInfo().GetPos().X() + nMaxRight - GetInfo().X(),
+                 GetInfo().GetPos().Y() + nTmpHeight );
+    if ( aPnt2.X() > rPaint.Right() )
+        aPnt2.X() = rPaint.Right();
+    if ( aPnt2.Y() > rPaint.Bottom() )
+    {
+        aPnt2.Y() = rPaint.Bottom();
+        bPlus = sal_True;
+    }
+
+    const SwRect aLineRect( aPnt1, aPnt2 );
+
+    if( pCurr->IsClipping() )
+    {
+        rClip.ChgClip( aLineRect );
+        bClip = sal_False;
+    }
+
+    if( !pPor && !bEndPor )
+    {
+#ifdef DBGTXT
+        aDbstream << "PAINTER: done nothing" << endl;
+#endif
+        return;
+    }
+
+    // Baseline-Ausgabe auch bei nicht-TxtPortions (vgl. TabPor mit Fill)
+    const SwTwips nY = GetInfo().GetPos().Y() + nTmpAscent;
+    GetInfo().Y( nY );
+
+    // 7529: PostIts prepainten
+    if( GetInfo().OnWin() && pPor && !pPor->Width() )
+    {
+        SeekAndChg( GetInfo() );
+        pPor->PrePaint( GetInfo(), pPor );
+    }
+
+    // 7923: EndPortions geben auch Zeichen aus, deswegen den Fnt wechseln!
+    if( bEndPor )
+        SeekStartAndChg( GetInfo() );
+
+    sal_Bool bRest = pCurr->IsRest();
+    sal_Bool bFirst = sal_True;
+
+    SwArrowPortion *pArrow = NULL;
+
+    while( pPor )
+    {
+        DBG_LOOP;
+        sal_Bool bSeeked = sal_True;
+        GetInfo().SetLen( pPor->GetLen() );
+        GetInfo().SetSpecialUnderline( sal_False );
+        // Ein Sonderfall sind GluePortions, die Blanks ausgeben.
+
+        // 6168: Der Rest einer FldPortion zog sich die Attribute der naechsten
+        // Portion an, dies wird durch SeekAndChgBefore vermieden:
+        if( ( bRest && pPor->InFldGrp() && !pPor->GetLen() ) )
+            SeekAndChgBefore( GetInfo() );
+        else if ( pPor->IsQuoVadisPortion() )
+        {
+            xub_StrLen nOffset = GetInfo().GetIdx();
+            SeekStartAndChg( GetInfo(), sal_True );
+            if( GetRedln() && pCurr->HasRedline() )
+                GetRedln()->Seek( *pFnt, nOffset, 0 );
+        }
+        else if( pPor->InTxtGrp() || pPor->InFldGrp() || pPor->InTabGrp() )
+            SeekAndChg( GetInfo() );
+        else if ( !bFirst && pPor->IsBreakPortion() && GetInfo().GetOpt().IsParagraph() )
+        {
+            // Paragraphzeichen sollten den gleichen Font wie das Zeichen vor
+            // haben, es sei denn, es gibt Redlining in dem Absatz.
+            if( GetRedln() )
+                SeekAndChg( GetInfo() );
+            else
+                SeekAndChgBefore( GetInfo() );
+        }
+        else
+            bSeeked = sal_False;
+
+//      bRest = sal_False;
+
+        ASSERT( GetInfo().Y() == nY, "DrawTextLine: Y() has changed" );
+
+        // Wenn das Ende der Portion hinausragt, wird geclippt.
+        // Es wird ein Sicherheitsabstand von Height-Halbe aufaddiert,
+        // damit die TTF-"f" nicht im Seitenrand haengen...
+        if(bClip && GetInfo().X() + pPor->Width() + (pPor->Height()/2) > nMaxRight)
+        {   bClip = sal_False;
+            rClip.ChgClip( rPaint );
+        }
+
+        // Portions, die "unter" dem Text liegen wie PostIts
+        SwLinePortion *pNext = pPor->GetPortion();
+        if(GetInfo().OnWin() && pNext && !pNext->Width() )
+        {
+            // Fix 11289: Felder waren hier ausgeklammert wg. Last!=Owner beim
+            // Laden von Brief.sdw. Jetzt sind die Felder wieder zugelassen,
+            // durch bSeeked wird Last!=Owner vermieden.
+            if ( !bSeeked )
+                SeekAndChg( GetInfo() );
+            pNext->PrePaint( GetInfo(), pPor );
+        }
+
+        if( pFnt->GetEscapement() && UNDERLINE_NONE != pFnt->GetUnderline() )
+            CheckSpecialUnderline();
+
+        pPor->Paint( GetInfo() );
+
+        if( GetFnt()->IsURL() && pPor->InTxtGrp() )
+            GetInfo().NotifyURL( *pPor );
+
+        bFirst &= !pPor->GetLen();
+        if( pNext || !pPor->IsMarginPortion() )
+            pPor->Move( GetInfo() );
+        if( pPor->IsArrowPortion() && GetInfo().OnWin() && !pArrow )
+            pArrow = (SwArrowPortion*)pPor;
+
+        pPor = !bDrawInWindow && GetInfo().X() > nMaxRight ? 0 : pNext;
+    }
+    if( bDrawInWindow )
+    {
+        if( !GetNextLine() &&
+            GetInfo().GetVsh() && !GetInfo().GetVsh()->IsPreView() &&
+            GetInfo().GetOpt().IsParagraph() && !GetTxtFrm()->GetFollow() &&
+            GetInfo().GetIdx() >= GetInfo().GetTxt().Len() )
+        {
+            SwTmpEndPortion aEnd( *pCurr->GetFirstPortion() );
+            aEnd.Paint( GetInfo() );
+        }
+        if( bUnderSz )
+        {
+            if( GetInfo().GetVsh() && !GetInfo().GetVsh()->IsPreView() )
+            {
+                if( pArrow )
+                    pArrow->PaintIt( pOut );
+                if( !GetTxtFrm()->GetFollow() )
+                {
+                    SwTwips nDiff = GetInfo().Y() + nTmpHeight - nTmpAscent - GetTxtFrm()->Frm().Bottom();
+                    if( nDiff > 0 && ( GetEnd() < GetInfo().GetTxt().Len() ||
+                        ( nDiff > nTmpHeight/2 && GetPrevLine() ) ) )
+                    {
+                        SwArrowPortion aArrow( GetInfo() );
+                        aArrow.PaintIt( pOut );
+                    }
+                }
+            }
+        }
+    }
+    if( pCurr->IsClipping() )
+        rClip.ChgClip( rPaint );
+}
+
+void SwTxtPainter::CheckSpecialUnderline()
+{
+    sal_Bool bSpecial = sal_False;
+    if( HasHints() )
+    {
+        sal_Bool bINet = sal_False;
+        MSHORT nTmp = 0;
+        Range aRange( 0, GetInfo().GetTxt().Len() );
+        MultiSelection aUnderMulti( aRange );
+        if( bUnderPara )
+            aUnderMulti.SelectAll();
+        MultiSelection aEscMulti( aRange );
+        if( bEscPara )
+            aEscMulti.SelectAll();
+        SwTxtAttr* pTxtAttr;
+        sal_Bool bUnder = sal_False;
+        sal_Bool bEsc = sal_False;
+        while( nTmp < pHints->GetStartCount() )
+        {
+            pTxtAttr = pHints->GetStart( nTmp++ );
+            sal_Bool bUnderSelect;
+            sal_Bool bEscSelect;
+            switch ( pTxtAttr->Which() )
+            {
+                case RES_CHRATR_UNDERLINE:
+                {
+                    bUnder = sal_True;
+                    bUnderSelect = UNDERLINE_NONE != pTxtAttr->GetUnderline().
+                                                          GetUnderline();
+                }
+                break;
+                case RES_CHRATR_ESCAPEMENT:
+                {
+                    bEsc = sal_True;
+                    bEscSelect = 0 != pTxtAttr->GetEscapement().GetEsc();
+                }
+                break;
+                case RES_TXTATR_FTN:
+                {
+                    xub_StrLen nStrt = *pTxtAttr->GetStart();
+                    Range aRg( nStrt, nStrt + 1 );
+                    aEscMulti.Select( aRg );
+                }
+                break;
+                case RES_TXTATR_INETFMT: bINet = sal_True;
+                case RES_TXTATR_CHARFMT:
+                {
+                    SwCharFmt* pFmt;
+                    const SfxPoolItem* pItem;
+                    if( bINet )
+                    {
+                        pFmt = ((SwTxtINetFmt*)pTxtAttr)->GetCharFmt();
+                        bINet = sal_False;
+                    }
+                    else
+                        pFmt = pTxtAttr->GetCharFmt().GetCharFmt();
+                    if ( pFmt )
+                    {
+                        if( SFX_ITEM_SET == pFmt->GetAttrSet().
+                            GetItemState( RES_CHRATR_ESCAPEMENT, sal_True, &pItem) )
+                        {
+                            bEscSelect = 0 !=
+                                ((SvxEscapementItem *)pItem)->GetEsc();
+                            bEsc = sal_True;
+                        }
+                        if( SFX_ITEM_SET == pFmt->GetAttrSet().
+                            GetItemState( RES_CHRATR_UNDERLINE, sal_True, &pItem ) )
+                        {
+                            bUnderSelect = UNDERLINE_NONE !=
+                                 ((SvxUnderlineItem*)pItem)->GetUnderline();
+                            bUnder = sal_True;
+                        }
+                    }
+                }
+                break;
+            }
+            if( bUnder || bEsc )
+            {
+                xub_StrLen nSt = *pTxtAttr->GetStart();
+                xub_StrLen nEnd = *pTxtAttr->GetEnd();
+                if( nEnd > nSt )
+                {
+                    Range aTmp( nSt, nEnd - 1 );
+                    if( bUnder )
+                        aUnderMulti.Select( aTmp, bUnderSelect );
+                    if( bEsc )
+                        aEscMulti.Select( aTmp, bEscSelect );
+                }
+                bUnder = sal_False;
+                bEsc = sal_False;
+            }
+        }
+        MSHORT i;
+        xub_StrLen nEscStart = 0;
+        xub_StrLen nEscEnd = 0;
+        xub_StrLen nIndx = GetInfo().GetIdx();
+        MSHORT nCnt = (MSHORT)aEscMulti.GetRangeCount();
+        for( i = 0; i < nCnt; ++i )
+        {
+            const Range& rRange = aEscMulti.GetRange( i );
+            if( nEscEnd == rRange.Min() )
+                nEscEnd = rRange.Max();
+            else if( nIndx >= rRange.Min() )
+            {
+                nEscStart = rRange.Min();
+                nEscEnd = rRange.Max();
+            }
+            else
+                break;
+        }
+        xub_StrLen nUnderStart = 0;
+        xub_StrLen nUnderEnd = 0;
+        nCnt = (MSHORT)aUnderMulti.GetRangeCount();
+        for( i = 0; i < nCnt; ++i )
+        {
+            const Range& rRange = aUnderMulti.GetRange( i );
+            if( nUnderEnd == rRange.Min() )
+                nUnderEnd = rRange.Max();
+            else if( nIndx >= rRange.Min() )
+            {
+                nUnderStart = rRange.Min();
+                nUnderEnd = rRange.Max();
+            }
+            else
+                break;
+        }
+        bSpecial = nEscStart > nUnderStart || nEscEnd < nUnderEnd;
+    }
+    if( bSpecial || ( GetRedln() && GetRedln()->ChkSpecialUnderline() ) )
+        GetInfo().SetSpecialUnderline( sal_True );
+}
+
diff --git a/sw/source/core/text/itrpaint.hxx b/sw/source/core/text/itrpaint.hxx
new file mode 100644
index 000000000000..b403101a5fb7
--- /dev/null
+++ b/sw/source/core/text/itrpaint.hxx
@@ -0,0 +1,97 @@
+/*************************************************************************
+ *
+ *  $RCSfile: itrpaint.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _ITRPAINT_HXX
+#define _ITRPAINT_HXX
+
+#include "itrtxt.hxx"
+
+class SwSaveClip;          // SwTxtPainter
+
+/*************************************************************************
+ *                      class SwTxtPainter
+ *************************************************************************/
+
+class SwTxtPainter : public SwTxtCursor
+{
+    sal_Bool bPaintDrop;
+
+    SwLinePortion *CalcPaintOfst( const SwRect &rPaint );
+    void CheckSpecialUnderline();
+protected:
+    void CtorInit( SwTxtFrm *pFrm, SwTxtPaintInfo *pInf );
+    inline SwTxtPainter() { }
+public:
+    inline SwTxtPainter( SwTxtFrm *pFrm, SwTxtPaintInfo *pInf )
+           { CtorInit( pFrm, pInf ); }
+    void DrawTextLine( const SwRect &rPaint, SwSaveClip &rClip,
+                       const sal_Bool bUnderSz );
+    void PaintDropPortion();
+    inline void SetPaintDrop( const sal_Bool bNew ) { bPaintDrop = bNew; }
+    inline IsPaintDrop() const { return bPaintDrop; }
+    inline SwTxtPaintInfo &GetInfo()
+        { return (SwTxtPaintInfo&)SwTxtIter::GetInfo(); }
+    inline const SwTxtPaintInfo &GetInfo() const
+        { return (const SwTxtPaintInfo&)SwTxtIter::GetInfo(); }
+};
+
+
+
+#endif
diff --git a/sw/source/core/text/itrtxt.cxx b/sw/source/core/text/itrtxt.cxx
new file mode 100644
index 000000000000..5c297aaf7ee8
--- /dev/null
+++ b/sw/source/core/text/itrtxt.cxx
@@ -0,0 +1,489 @@
+/*************************************************************************
+ *
+ *  $RCSfile: itrtxt.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "hintids.hxx"
+#include "ndtxt.hxx"
+#include "flyfrm.hxx"
+#include "paratr.hxx"
+#include "errhdl.hxx"
+
+#ifndef _SVX_LSPCITEM_HXX //autogen
+#include 
+#endif
+#include "txtcfg.hxx"
+#include "itrtxt.hxx"
+#include "txtfrm.hxx"
+#include "porfly.hxx"
+
+#ifdef DEBUG
+# include "txtfrm.hxx"      // GetFrmID,
+#endif
+
+/*************************************************************************
+ *                      SwTxtIter::CtorInit()
+ *************************************************************************/
+
+void SwTxtIter::CtorInit( SwTxtFrm *pNewFrm, SwTxtInfo *pNewInf )
+{
+#ifdef DBGTXT
+    // nStopAt laesst sich vom CV bearbeiten.
+    static MSHORT nStopAt = 0;
+    if( nStopAt == pNewFrm->GetFrmId() )
+    {
+        int i = pNewFrm->GetFrmId();
+    }
+#endif
+
+    SwTxtNode *pNode = pNewFrm->GetTxtNode();
+    SwAttrIter::CtorInit( *pNode );
+    pFrm = pNewFrm;
+    pInf = pNewInf;
+    aLineInf.CtorInit( pNode->GetSwAttrSet() );
+    aTopLeft = pFrm->Frm().Pos() + pFrm->Prt().Pos();
+    SwTxtIter::Init();
+    if( pNode->GetSwAttrSet().GetRegister().GetValue() )
+        bRegisterOn = pFrm->FillRegister( nRegStart, nRegDiff );
+    else
+        bRegisterOn = sal_False;
+    bUnderPara = UNDERLINE_NONE != pFnt->GetUnderline();
+    bEscPara = 0 != pFnt->GetEscapement();
+}
+
+/*************************************************************************
+ *                      SwTxtIter::Init()
+ *************************************************************************/
+
+void SwTxtIter::Init()
+{
+    pCurr = pInf->GetParaPortion();
+    nStart = pInf->GetTxtStart();
+    nY = aTopLeft.Y();
+    bPrev = sal_True;
+    pPrev = 0;
+    nLineNr = 1;
+}
+
+/*************************************************************************
+ *                 SwTxtIter::_GetHeightAndAscent()
+ *************************************************************************/
+
+void SwTxtIter::CalcAscentAndHeight( KSHORT &rAscent, KSHORT &rHeight ) const
+{
+    rHeight = GetLineHeight();
+    rAscent = pCurr->GetAscent() + rHeight - pCurr->Height();
+}
+
+/*************************************************************************
+ *                    SwTxtIter::CalcRealHeight( sal_Bool bNewLine = sal_False )
+ *************************************************************************/
+
+void SwTxtIter::CalcRealHeight( sal_Bool bNewLine )
+{
+    KSHORT nLineHeight = pCurr->Height();
+    pCurr->SetClipping( sal_False );
+    // Das Dummyflag besitzen Zeilen, die nur Flyportions enthalten, diese
+    // sollten kein Register etc. beachten. Dummerweise hat kann es eine leere
+    // Zeile am Absatzende geben (bei leeren Abs„tzen oder nach einem
+    // Shift-Return), die das Register durchaus beachten soll.
+    if( !pCurr->IsDummy() || ( !pCurr->GetNext() &&
+        GetStart() >= GetTxtFrm()->GetTxt().Len() && !bNewLine ) )
+    {
+        const SvxLineSpacingItem *pSpace = aLineInf.GetLineSpacing();
+        if( pSpace )
+        {
+            switch( pSpace->GetLineSpaceRule() )
+            {
+                case SVX_LINE_SPACE_AUTO:
+                break;
+                case SVX_LINE_SPACE_MIN:
+                {
+                    if( nLineHeight < KSHORT( pSpace->GetLineHeight() ) )
+                        nLineHeight = pSpace->GetLineHeight();
+                    break;
+                }
+                case SVX_LINE_SPACE_FIX:
+                {
+                    nLineHeight = pSpace->GetLineHeight();
+                    KSHORT nAsc = ( 4 * nLineHeight ) / 5;  // 80%
+                    if( nAsc < pCurr->GetAscent() ||
+                        nLineHeight - nAsc < pCurr->Height() - pCurr->GetAscent() )
+                        pCurr->SetClipping( sal_True );
+                    pCurr->Height( nLineHeight );
+                    pCurr->SetAscent( nAsc );
+                    pInf->GetParaPortion()->SetFixLineHeight();
+                }
+                break;
+                default: ASSERT( sal_False, ": unknown LineSpaceRule" );
+            }
+            if( !IsParaLine() )
+                switch( pSpace->GetInterLineSpaceRule() )
+                {
+                    case SVX_INTER_LINE_SPACE_OFF:
+                    break;
+                    case SVX_INTER_LINE_SPACE_PROP:
+                    {
+                        long nTmp = pSpace->GetPropLineSpace();
+                        // 50% ist das Minimum, bei 0% schalten wir auf
+                        // den Defaultwert 100% um ...
+                        if( nTmp < 50 )
+                            nTmp = nTmp ? 50 : 100;
+
+                        nTmp *= nLineHeight;
+                        nTmp /= 100;
+                        if( !nTmp )
+                            ++nTmp;
+                        nLineHeight = (KSHORT)nTmp;
+                        break;
+                    }
+                    case SVX_INTER_LINE_SPACE_FIX:
+                    {
+                        nLineHeight += pSpace->GetInterLineSpace();
+                        break;
+                    }
+                    default: ASSERT( sal_False, ": unknown InterLineSpaceRule" );
+                }
+        }
+#ifdef DEBUG
+        KSHORT nDummy = nLineHeight + 1;
+#endif
+        if( IsRegisterOn() )
+        {
+            SwTwips nTmpY = Y() + pCurr->GetAscent()
+                            + nLineHeight - pCurr->Height() - RegStart();
+            KSHORT nDiff = KSHORT( nTmpY % RegDiff() );
+            if( nDiff )
+                nLineHeight += RegDiff() - nDiff;
+        }
+    }
+    pCurr->SetRealHeight( nLineHeight );
+}
+
+/*************************************************************************
+ *                    SwTxtIter::_GetPrev()
+ *************************************************************************/
+
+SwLineLayout *SwTxtIter::_GetPrev()
+{
+    pPrev = 0;
+    bPrev = sal_True;
+    SwLineLayout *pLay = pInf->GetParaPortion();
+    if( pCurr == pLay )
+        return 0;
+    while( pLay->GetNext() != pCurr )
+        pLay = pLay->GetNext();
+    return pPrev = pLay;
+}
+
+/*************************************************************************
+ *                    SwTxtIter::GetPrev()
+ *************************************************************************/
+
+const SwLineLayout *SwTxtIter::GetPrev()
+{
+    if(! bPrev)
+        _GetPrev();
+    return pPrev;
+}
+
+/*************************************************************************
+ *                    SwTxtIter::Prev()
+ *************************************************************************/
+
+const SwLineLayout *SwTxtIter::Prev()
+{
+    if( !bPrev )
+        _GetPrev();
+    if( pPrev )
+    {
+        bPrev = sal_False;
+        pCurr = pPrev;
+        nStart -= pCurr->GetLen();
+        nY -= GetLineHeight();
+        if( !pCurr->IsDummy() && !(--nLineNr) )
+            ++nLineNr;
+        return pCurr;
+    }
+    else
+        return 0;
+}
+
+/*************************************************************************
+ *                      SwTxtIter::Next()
+ *************************************************************************/
+
+const SwLineLayout *SwTxtIter::Next()
+{
+    if(pCurr->GetNext())
+    {
+        pPrev = pCurr;
+        bPrev = sal_True;
+        nStart += pCurr->GetLen();
+        nY += GetLineHeight();
+        if( pCurr->GetLen() || ( nLineNr>1 && !pCurr->IsDummy() ) )
+            ++nLineNr;
+        return pCurr = pCurr->GetNext();
+    }
+    else
+        return 0;
+}
+
+/*************************************************************************
+ *                      SwTxtIter::NextLine()
+ *************************************************************************/
+
+const SwLineLayout *SwTxtIter::NextLine()
+{
+    const SwLineLayout *pNext = Next();
+    while( pNext && pNext->IsDummy() && pNext->GetNext() )
+    {
+        DBG_LOOP;
+        pNext = Next();
+    }
+    return pNext;
+}
+
+/*************************************************************************
+ *                      SwTxtIter::GetNextLine()
+ *************************************************************************/
+
+const SwLineLayout *SwTxtIter::GetNextLine() const
+{
+    const SwLineLayout *pNext = pCurr->GetNext();
+    while( pNext && pNext->IsDummy() && pNext->GetNext() )
+    {
+        DBG_LOOP;
+        pNext = pNext->GetNext();
+    }
+    return (SwLineLayout*)pNext;
+}
+
+/*************************************************************************
+ *                      SwTxtIter::GetPrevLine()
+ *************************************************************************/
+
+const SwLineLayout *SwTxtIter::GetPrevLine()
+{
+    const SwLineLayout *pRoot = pInf->GetParaPortion();
+    if( pRoot == pCurr )
+        return 0;
+    const SwLineLayout *pLay = pRoot;
+
+    while( pLay->GetNext() != pCurr )
+        pLay = pLay->GetNext();
+
+    if( pLay->IsDummy() )
+    {
+        const SwLineLayout *pTmp = pRoot;
+        pLay = pRoot->IsDummy() ? 0 : pRoot;
+        while( pTmp->GetNext() != pCurr )
+        {
+            if( !pTmp->IsDummy() )
+                pLay = pTmp;
+            pTmp = pTmp->GetNext();
+        }
+    }
+
+    // Wenn sich nichts getan hat, dann gibt es nur noch Dummys
+    return (SwLineLayout*)pLay;
+}
+
+/*************************************************************************
+ *                      SwTxtIter::PrevLine()
+ *************************************************************************/
+
+const SwLineLayout *SwTxtIter::PrevLine()
+{
+    const SwLineLayout *pPrev = Prev();
+    if( !pPrev )
+        return 0;
+
+    const SwLineLayout *pLast = pPrev;
+    while( pPrev && pPrev->IsDummy() )
+    {
+        DBG_LOOP;
+        pLast = pPrev;
+        pPrev = Prev();
+    }
+    return (SwLineLayout*)(pPrev ? pPrev : pLast);
+}
+
+/*************************************************************************
+ *                      SwTxtIter::Bottom()
+ *************************************************************************/
+
+void SwTxtIter::Bottom()
+{
+    while( Next() )
+    {
+        DBG_LOOP;
+    }
+}
+
+/*************************************************************************
+ *                      SwTxtIter::RecalcRealHeight()
+ *************************************************************************/
+
+void SwTxtIter::RecalcRealHeight()
+{
+    sal_Bool bMore = sal_True;
+    while(bMore)
+    {
+        DBG_LOOP;
+        CalcRealHeight();
+        bMore = Next() != 0;
+    }
+}
+
+/*************************************************************************
+ *                      SwTxtIter::CharToLine()
+ *************************************************************************/
+
+void SwTxtIter::CharToLine(const xub_StrLen nChar)
+{
+    while( nStart + pCurr->GetLen() <= nChar && Next() )
+        ;
+    while( nStart > nChar && Prev() )
+        ;
+}
+
+/*************************************************************************
+ *                      SwTxtIter::CharCrsrToLine()
+ *************************************************************************/
+
+// 1170: beruecksichtigt Mehrdeutigkeiten:
+const SwLineLayout *SwTxtCursor::CharCrsrToLine( const xub_StrLen nPos )
+{
+    CharToLine( nPos );
+    if( nPos != nStart )
+        bRightMargin = sal_False;
+    sal_Bool bPrev = bRightMargin && pCurr->GetLen() && GetPrev() &&
+        GetPrev()->GetLen();
+    if( bPrev && nPos && CH_BREAK == GetInfo().GetChar( nPos-1 ) )
+        bPrev = sal_False;
+    return bPrev ? PrevLine() : pCurr;
+}
+
+/*************************************************************************
+ *                      SwTxtIter::TwipsToLine()
+ *************************************************************************/
+
+const SwLineLayout *SwTxtIter::TwipsToLine( const SwTwips y)
+{
+    while( nY + GetLineHeight() <= y && Next() )
+        ;
+    while( nY > y && Prev() )
+        ;
+    return pCurr;
+}
+
+/*************************************************************************
+ *                      SwTxtIter::TruncLines()
+ *************************************************************************/
+
+void SwTxtIter::TruncLines( sal_Bool bNoteFollow )
+{
+    SwLineLayout *pDel = pCurr->GetNext();
+    if( pDel )
+    {
+        pCurr->SetNext( 0 );
+        if( GetHints() && bNoteFollow )
+            GetInfo().GetParaPortion()->SetFollowField( pDel->IsRest() );
+        delete pDel;
+    }
+    if( GetHints() )
+        pFrm->RemoveFtn( nStart + pCurr->GetLen() );
+}
+
+/*************************************************************************
+ *                      SwTxtIter::CntHyphens()
+ *************************************************************************/
+
+void SwTxtIter::CntHyphens( sal_uInt8 &nEndCnt, sal_uInt8 &nMidCnt) const
+{
+    nEndCnt = 0;
+    nMidCnt = 0;
+    if ( bPrev && pPrev && !pPrev->IsEndHyph() && !pPrev->IsMidHyph() )
+         return;
+    SwLineLayout *pLay = pInf->GetParaPortion();
+    if( pCurr == pLay )
+        return;
+    while( pLay != pCurr )
+    {
+        DBG_LOOP;
+        if ( pLay->IsEndHyph() )
+            nEndCnt++;
+        else
+            nEndCnt = 0;
+        if ( pLay->IsMidHyph() )
+            nMidCnt++;
+        else
+            nMidCnt = 0;
+        pLay = pLay->GetNext();
+    }
+}
+
+
diff --git a/sw/source/core/text/itrtxt.hxx b/sw/source/core/text/itrtxt.hxx
new file mode 100644
index 000000000000..c77931272090
--- /dev/null
+++ b/sw/source/core/text/itrtxt.hxx
@@ -0,0 +1,363 @@
+/*************************************************************************
+ *
+ *  $RCSfile: itrtxt.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _ITRTXT_HXX
+#define _ITRTXT_HXX
+
+#include "swtypes.hxx"
+#include "itratr.hxx"
+#include "inftxt.hxx"
+
+class SwTxtFrm;
+struct SwPosition;
+struct SwCrsrMoveState;
+class SwMarginPortion;
+class SwFlyPortion;
+
+/*************************************************************************
+ *                      class SwTxtIter
+ *************************************************************************/
+
+class SwTxtIter : public SwAttrIter
+{
+protected:
+    SwLineInfo aLineInf;
+    Point aTopLeft;         // erste Ausgabeposition
+    SwTxtFrm  *pFrm;
+    SwTxtInfo *pInf;
+    SwLineLayout *pCurr;
+    SwLineLayout *pPrev;
+    SwTwips nY;
+    SwTwips nRegStart;          // Anfangsposition (Y) des Registers
+    xub_StrLen nStart;          // Start im Textstring, Ende = pCurr->GetLen()
+    KSHORT nRegDiff;            // Zeilenabstand des Registers
+    MSHORT nLineNr;             // Zeilennummer
+    sal_Bool bPrev          : 1;
+    sal_Bool bRegisterOn    : 1;    // Registerhaltigkeit
+    sal_Bool bOneBlock      : 1;    // Blocksatz: Einzelwoerter austreiben
+    sal_Bool bLastBlock     : 1;    // Blocksatz: Auch die letzte Zeile
+    sal_Bool bLastCenter    : 1;    // Blocksatz: Letzte Zeile zentrieren
+    sal_Bool bUnderPara     : 1;    // Absatz unterstrichen
+    sal_Bool bEscPara       : 1;    // Absatz mit Escapement
+
+    SwLineLayout *_GetPrev();
+
+    // Zuruecksetzen in die erste Zeile.
+    void Init();
+    void CtorInit( SwTxtFrm *pFrm, SwTxtInfo *pInf );
+    inline SwTxtIter() { }
+
+public:
+    inline SwTxtIter( SwTxtFrm *pFrm, SwTxtInfo *pInf )
+           { CtorInit( pFrm, pInf ); }
+    inline const SwLineLayout *GetCurr() const { return pCurr; } // niemals 0!
+    inline const SwLineLayout *GetNext() const { return pCurr->GetNext(); }
+           const SwLineLayout *GetPrev();
+    inline xub_StrLen GetLength() const { return pCurr->GetLen(); }
+    inline MSHORT GetLineNr() const { return nLineNr; }
+    inline xub_StrLen GetStart() const { return nStart; }
+    inline xub_StrLen GetEnd() const { return GetStart() + GetLength(); }
+    inline SwTwips Y() const { return nY; }
+
+    inline SwTwips RegStart() const { return nRegStart; }
+    inline KSHORT RegDiff() const { return nRegDiff; }
+    inline sal_Bool IsRegisterOn() const { return bRegisterOn; }
+
+    inline SwTxtInfo &GetInfo() { return *pInf; }
+    inline const SwTxtInfo &GetInfo() const { return *pInf; }
+
+    inline void Top() { Init(); }
+    void Bottom();
+    const SwLineLayout *Next();
+    const SwLineLayout *Prev();
+
+    void RecalcRealHeight();
+
+    // Ueberspringt die Dummyzeilen der FlyFrms
+    const SwLineLayout *NextLine();
+    const SwLineLayout *PrevLine();
+    const SwLineLayout *GetNextLine() const;
+    const SwLineLayout *GetPrevLine();
+
+    void CharToLine( const xub_StrLen );
+    const SwLineLayout *TwipsToLine(const SwTwips);
+
+    // schneidet ab pCurr alle ab.
+    void TruncLines( sal_Bool bNoteFollow = sal_False );
+
+    inline KSHORT GetLineHeight() const { return pCurr->GetRealHeight(); }
+    void CalcRealHeight( sal_Bool bNewLine = sal_False );
+    void CalcAscentAndHeight( KSHORT &rAscent, KSHORT &rHeight ) const;
+
+    // 5298, viel Aerger durch die Abfrage auf pCurr == pPara
+    inline sal_Bool IsFirstTxtLine() const
+    { return nStart == GetInfo().GetTxtStart() &&
+        !( pCurr->IsDummy() && GetNextLine() ); }
+
+    // Als Ersatz fuer das alte IsFirstLine()
+    inline sal_Bool IsParaLine() const
+        { return pCurr == pInf->GetParaPortion(); }
+
+    const SwLineInfo &GetLineInfo() const { return aLineInf; }
+    inline const Point &GetFirstPos() const { return aTopLeft; }
+
+    inline sal_Bool SeekAndChg( SwTxtSizeInfo &rInf );
+    inline sal_Bool SeekAndChgBefore( SwTxtSizeInfo &rInf );
+    inline sal_Bool SeekStartAndChg( SwTxtSizeInfo &rInf, const sal_Bool bPara=sal_False );
+
+    inline SwTxtFrm *GetTxtFrm() { return pFrm; }
+    inline const SwTxtFrm *GetTxtFrm() const { return pFrm; }
+
+    // zaehlt aufeinanderfolgende Trennungen, um MaxHyphens einzuhalten
+    void CntHyphens( sal_uInt8 &nEndCnt, sal_uInt8 &nMidCnt) const;
+};
+
+/*************************************************************************
+ *                      class SwTxtMargin
+ *************************************************************************/
+
+class SwTxtMargin : public SwTxtIter
+{
+private:
+          SwTwips nLeft;
+          SwTwips nRight;
+          SwTwips nFirst;
+          KSHORT  nDropLeft;
+          KSHORT  nDropHeight;
+          KSHORT  nDropDescent;
+          MSHORT  nDropLines;
+          MSHORT  nAdjust;
+
+protected:
+    // fuer FormatQuoVadis
+    inline void Right( const KSHORT nNew ) { nRight = nNew; }
+    // fuer CalcFlyAdjust
+    inline void SetDropLeft( const KSHORT nNew ) { nDropLeft = nNew; }
+
+    void CtorInit( SwTxtFrm *pFrm, SwTxtSizeInfo *pInf );
+    inline SwTxtMargin() { }
+public:
+    inline SwTxtMargin( SwTxtFrm *pFrm, SwTxtSizeInfo *pInf )
+           { CtorInit( pFrm, pInf ); }
+    inline SwTwips GetLeftMargin() const;
+    inline SwTwips Left() const;
+    inline SwTwips Right() const { return nRight; }
+    inline SwTwips FirstLeft() const { return nFirst; }
+    inline SwTwips CurrWidth() const { return pCurr->PrtWidth(); }
+           SwTwips GetLineStart() const;
+    inline SwTwips GetLineEnd() const { return GetLineStart() + CurrWidth(); }
+    inline Point GetTopLeft() const { return Point( GetLineStart(), Y() ); }
+    inline sal_Bool IsOneBlock() const { return bOneBlock; }
+    inline sal_Bool IsLastBlock() const { return bLastBlock; }
+    inline sal_Bool IsLastCenter() const { return bLastCenter; }
+    inline MSHORT GetAdjust() const { return nAdjust; }
+    inline KSHORT GetLineWidth() const
+           { return KSHORT( Right() - GetLeftMargin() + 1 ); }
+    inline SwTwips GetLeftMin() const { return nFirst < nLeft ? nFirst : nLeft; }
+    inline sal_Bool HasNegFirst() const { return nFirst < nLeft; }
+
+    // DropCaps
+    inline MSHORT GetDropLines() const { return nDropLines; }
+    inline void SetDropLines( const MSHORT nNew ) { nDropLines = nNew; }
+    inline KSHORT GetDropLeft() const { return nDropLeft; }
+    inline KSHORT GetDropHeight() const { return nDropHeight; }
+    inline void SetDropHeight( const KSHORT nNew ) { nDropHeight = nNew; }
+    inline KSHORT GetDropDescent() const { return nDropDescent; }
+    inline void SetDropDescent( const KSHORT nNew ) { nDropDescent = nNew; }
+    void DropInit();
+
+    // liefert TxtPos fuer Start und Ende der aktuellen Zeile ohne whitespaces
+    // In frminf.cxx implementiert.
+    xub_StrLen GetTxtStart() const;
+    xub_StrLen GetTxtEnd() const;
+
+    inline SwTxtSizeInfo &GetInfo()
+        { return (SwTxtSizeInfo&)SwTxtIter::GetInfo(); }
+    inline const SwTxtSizeInfo &GetInfo() const
+        { return (const SwTxtSizeInfo&)SwTxtIter::GetInfo(); }
+
+};
+
+
+/*************************************************************************
+ *                      class SwTxtAdjuster
+ *************************************************************************/
+
+class SwTxtAdjuster : public SwTxtMargin
+{
+    // Gleicht die Portions aus, wenn Adjustment und FlyFrms vorliegen.
+    void CalcFlyAdjust( SwLineLayout *pCurr );
+
+    // spannt beim Blocksatz die Glues auf.
+    void CalcNewBlock( SwLineLayout *pCurr, const SwLinePortion *pStopAt );
+    // ruft SplitGlues und CalcBlockAdjust
+    void FormatBlock( );
+
+    // Erstellt bei kurzen Zeilen die Glue-Kette.
+    SwMarginPortion *CalcRightMargin( SwLineLayout *pCurr );
+
+    // Berechnung des Adjustments (FlyPortions)
+    SwFlyPortion *CalcFlyPortion( const long nRealWidth,
+                                  const SwRect &rCurrRect );
+
+protected:
+    inline SwTxtAdjuster() { }
+public:
+    inline SwTxtAdjuster( SwTxtFrm *pFrm, SwTxtSizeInfo *pInf )
+           { SwTxtMargin::CtorInit( pFrm, pInf ); }
+
+    // wird von SwTxtFormatter wegen UpdatePos ueberladen
+    void CalcAdjLine( SwLineLayout *pCurr );
+
+    // sorgt fuer das nachtraegliche adjustieren
+    inline void GetAdjusted() const
+    {
+        if( pCurr->IsFormatAdj() )
+            ((SwTxtAdjuster*)this)->CalcAdjLine( pCurr );
+    }
+
+    // DropCaps-Extrawurst
+    void CalcDropAdjust();
+    void CalcDropRepaint();
+};
+
+/*************************************************************************
+ *                      class SwTxtCursor
+ *************************************************************************/
+
+class SwTxtCursor : public SwTxtAdjuster
+{
+    // 1170: Mehrdeutigkeiten
+    static sal_Bool bRightMargin;
+protected:
+    void CtorInit( SwTxtFrm *pFrm, SwTxtSizeInfo *pInf );
+    inline SwTxtCursor() { }
+public:
+    inline SwTxtCursor( SwTxtFrm *pFrm, SwTxtSizeInfo *pInf )
+           { CtorInit( pFrm, pInf ); }
+    sal_Bool GetCharRect(SwRect *, const xub_StrLen, SwCrsrMoveState* = 0,
+        const long nMax = 0 );
+    sal_Bool GetEndCharRect(SwRect *, const xub_StrLen, SwCrsrMoveState* = 0,
+        const long nMax = 0 );
+    xub_StrLen GetCrsrOfst( SwPosition *pPos, const Point &rPoint,
+                const MSHORT nChgNode, const SwCrsrMoveState* = 0 ) const;
+    // 1170: beruecksichtigt Mehrdeutigkeiten; Implementierung s.u.
+    const SwLineLayout *CharCrsrToLine( const xub_StrLen nPos );
+
+    static inline void SetRightMargin( const sal_Bool bNew ){ bRightMargin = bNew; }
+    static inline sal_Bool IsRightMargin() { return bRightMargin; }
+};
+
+/*************************************************************************
+ *                          SwHookOut
+ *************************************************************************/
+
+class SwHookOut
+{
+    SwTxtSizeInfo *pInf;
+public:
+    inline SwHookOut( SwTxtSizeInfo *pInfo )
+         : pInf(pInfo->OnWin() && pInfo->GetPrt() ? pInfo : 0)
+    {
+        if( pInf )
+            pInf->SetPrtOut();
+    }
+    inline ~SwHookOut()
+    {
+        if( pInf )
+            pInf->SetWinOut();
+    }
+};
+
+/*************************************************************************
+ *                      Inline-Implementierungen
+ *************************************************************************/
+
+inline sal_Bool SwTxtIter::SeekAndChg( SwTxtSizeInfo &rInf )
+{
+    return SwAttrIter::SeekAndChg( rInf.GetIdx(), rInf.GetOut() );
+}
+
+inline sal_Bool SwTxtIter::SeekAndChgBefore( SwTxtSizeInfo &rInf )
+{
+    if ( rInf.GetIdx() )
+        return SwAttrIter::SeekAndChg( rInf.GetIdx()-1, rInf.GetOut() );
+    else
+        return SwAttrIter::SeekAndChg( rInf.GetIdx(), rInf.GetOut() );
+}
+
+inline sal_Bool SwTxtIter::SeekStartAndChg( SwTxtSizeInfo &rInf, const sal_Bool bPara )
+{
+    return SwAttrIter::SeekStartAndChg( rInf.GetOut(), bPara );
+}
+
+inline SwTwips SwTxtMargin::GetLeftMargin() const
+{
+    return IsFirstTxtLine() ? nFirst : Left();
+}
+
+inline SwTwips SwTxtMargin::Left() const
+{
+    return (nDropLines >= nLineNr && 1 != nLineNr) ? nFirst + nDropLeft : nLeft;
+}
+
+
+
+#endif
diff --git a/sw/source/core/text/makefile.mk b/sw/source/core/text/makefile.mk
new file mode 100644
index 000000000000..a3039fb031a1
--- /dev/null
+++ b/sw/source/core/text/makefile.mk
@@ -0,0 +1,185 @@
+#*************************************************************************
+#
+#   $RCSfile: makefile.mk,v $
+#
+#   $Revision: 1.1.1.1 $
+#
+#   last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+#
+#   The Contents of this file are made available subject to the terms of
+#   either of the following licenses
+#
+#          - GNU Lesser General Public License Version 2.1
+#          - Sun Industry Standards Source License Version 1.1
+#
+#   Sun Microsystems Inc., October, 2000
+#
+#   GNU Lesser General Public License Version 2.1
+#   =============================================
+#   Copyright 2000 by Sun Microsystems, Inc.
+#   901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+#   This library is free software; you can redistribute it and/or
+#   modify it under the terms of the GNU Lesser General Public
+#   License version 2.1, as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   Lesser General Public License for more details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+#   License along with this library; if not, write to the Free Software
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+#   MA  02111-1307  USA
+#
+#
+#   Sun Industry Standards Source License Version 1.1
+#   =================================================
+#   The contents of this file are subject to the Sun Industry Standards
+#   Source License Version 1.1 (the "License"); You may not use this file
+#   except in compliance with the License. You may obtain a copy of the
+#   License at http://www.openoffice.org/license.html.
+#
+#   Software provided under this License is provided on an "AS IS" basis,
+#   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+#   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+#   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+#   See the License for the specific provisions governing your rights and
+#   obligations concerning the Software.
+#
+#   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+#   Copyright: 2000 by Sun Microsystems, Inc.
+#
+#   All Rights Reserved.
+#
+#   Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sw
+TARGET=text
+
+AUTOSEG=true
+
+PROJECTPCH=core_pch
+PDBTARGET=core_pch
+PROJECTPCHSOURCE=..$/core_1st$/core_pch
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE :  $(PRJ)$/inc$/swpre.mk
+.INCLUDE :  settings.mk
+.INCLUDE :  $(PRJ)$/inc$/sw.mk
+
+INCEXT=s:\solar\inc\hm
+
+.IF "$(mydebug)" != ""
+CDEFS+=-Dmydebug
+.ENDIF
+
+.IF "$(GUI)$(COM)" == "WINMSC"
+LIBFLAGS=/NOI /NOE /PAGE:512
+.ENDIF
+
+# --- Files --------------------------------------------------------
+
+CXXFILES = \
+        frmcrsr.cxx \
+        frmform.cxx \
+        frminf.cxx \
+        frmpaint.cxx \
+        guess.cxx \
+        inftxt.cxx \
+        itradj.cxx \
+        itratr.cxx \
+        itrcrsr.cxx \
+        itrform2.cxx \
+        itrpaint.cxx \
+        itrtxt.cxx \
+        porexp.cxx \
+        porfld.cxx \
+        porfly.cxx \
+        porglue.cxx \
+        porlay.cxx \
+        porlin.cxx \
+        porref.cxx \
+        porrst.cxx \
+        portox.cxx \
+        portxt.cxx \
+        redlnitr.cxx \
+        txtcache.cxx \
+        txtdrop.cxx \
+        txtfld.cxx \
+        txtfly.cxx \
+        txtfrm.cxx \
+        txtftn.cxx \
+        txthyph.cxx \
+        txtinit.cxx \
+        txtpaint.cxx \
+        txttab.cxx \
+        widorp.cxx \
+        blink.cxx \
+        noteurl.cxx \
+        wrong.cxx
+
+.IF "$(product)$(cap)" == ""
+CXXFILES += \
+        txtio.cxx
+.ENDIF
+
+
+
+SLOFILES =  \
+        $(SLO)$/frmcrsr.obj \
+        $(SLO)$/frmform.obj \
+        $(SLO)$/frminf.obj \
+        $(SLO)$/frmpaint.obj \
+        $(SLO)$/guess.obj \
+        $(SLO)$/inftxt.obj \
+        $(SLO)$/itradj.obj \
+        $(SLO)$/itratr.obj \
+        $(SLO)$/itrcrsr.obj \
+        $(SLO)$/itrform2.obj \
+        $(SLO)$/itrpaint.obj \
+        $(SLO)$/itrtxt.obj \
+        $(SLO)$/porexp.obj \
+        $(SLO)$/porfld.obj \
+        $(SLO)$/porfly.obj \
+        $(SLO)$/porglue.obj \
+        $(SLO)$/porlay.obj \
+        $(SLO)$/porlin.obj \
+        $(SLO)$/porref.obj \
+        $(SLO)$/porrst.obj \
+        $(SLO)$/portox.obj \
+        $(SLO)$/portxt.obj \
+        $(SLO)$/redlnitr.obj \
+        $(SLO)$/txtcache.obj \
+        $(SLO)$/txtdrop.obj \
+        $(SLO)$/txtfld.obj \
+        $(SLO)$/txtfly.obj \
+        $(SLO)$/txtfrm.obj \
+        $(SLO)$/txtftn.obj \
+        $(SLO)$/txthyph.obj \
+        $(SLO)$/txtinit.obj \
+        $(SLO)$/txtpaint.obj \
+        $(SLO)$/txttab.obj \
+        $(SLO)$/widorp.obj \
+        $(SLO)$/blink.obj \
+        $(SLO)$/noteurl.obj \
+        $(SLO)$/wrong.obj
+
+.IF "$(product)$(cap)" == ""
+SLOFILES +=  \
+        $(SLO)$/txtio.obj
+.ENDIF
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE :  target.mk
+
diff --git a/sw/source/core/text/noteurl.cxx b/sw/source/core/text/noteurl.cxx
new file mode 100644
index 000000000000..60be83e86711
--- /dev/null
+++ b/sw/source/core/text/noteurl.cxx
@@ -0,0 +1,129 @@
+/*************************************************************************
+ *
+ *  $RCSfile: noteurl.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "swtypes.hxx"
+
+#ifndef _SV_OUTDEV_HXX //autogen
+#include 
+#endif
+#ifndef _GOODIES_IMAPRECT_HXX
+#include 
+#endif
+#ifndef _IMAP_HXX //autogen
+#include 
+#endif
+
+#include "txttypes.hxx"
+#include "noteurl.hxx"
+
+// globale Variable, wird in noteurl.Hxx bekanntgegeben
+SwNoteURL *pNoteURL = NULL;
+
+SV_IMPL_PTRARR( SwURLNoteList, SwURLNotePtr )
+
+
+void SwNoteURL::InsertURLNote( const XubString& rURL, const XubString& rTarget,
+    const SwRect& rRect )
+{
+    MSHORT i;
+    MSHORT nCount = aList.Count();
+    for( i = 0; i < nCount; i++ )
+        if( rRect == aList.GetObject(i)->GetRect() )
+            break;
+    if( i == nCount )
+    {
+        SwURLNote *pNew = new SwURLNote( rURL, rTarget, rRect );
+        aList.Insert( pNew, nCount );
+    }
+}
+
+
+void SwNoteURL::FillImageMap( ImageMap *pMap, const Point &rPos,
+    const MapMode& rMap )
+{
+    ASSERT( pMap, "FillImageMap: No ImageMap, no cookies!" );
+    MSHORT nCount = Count();
+    if( nCount )
+    {
+        MapMode aMap( MAP_100TH_MM );
+        for( MSHORT i = 0; i < nCount; ++i )
+        {
+            const SwURLNote &rNote = GetURLNote( i );
+            SwRect aSwRect( rNote.GetRect() );
+            aSwRect -= rPos;
+            Rectangle aRect( OutputDevice::LogicToLogic( aSwRect.SVRect(),
+                                                         rMap, aMap ) );
+            IMapRectangleObject aObj( aRect, rNote.GetURL(), aEmptyStr,
+                                      rNote.GetTarget(), sal_True, sal_False );
+            pMap->InsertIMapObject( aObj );
+        }
+    }
+}
+
+
+
+
diff --git a/sw/source/core/text/pordrop.hxx b/sw/source/core/text/pordrop.hxx
new file mode 100644
index 000000000000..c8c7c41a0a66
--- /dev/null
+++ b/sw/source/core/text/pordrop.hxx
@@ -0,0 +1,122 @@
+/*************************************************************************
+ *
+ *  $RCSfile: pordrop.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _PORDROP_HXX
+#define _PORDROP_HXX
+
+#include "portxt.hxx"
+
+class SwFont;
+
+// DropCap-Cache, globale Variable, in txtinit.cxx initialisiert/zerstoert
+// und in txtdrop.cxx benutzt bei der Initialenberechnung
+
+class SwDropCapCache;
+extern SwDropCapCache *pDropCapCache;
+
+/*************************************************************************
+ *                      class SwDropPortion
+ *************************************************************************/
+
+class SwDropPortion : public SwTxtPortion
+{
+    friend class SwDropCapCache;
+    SwFont *pFnt;           // der Font
+    MSHORT nLines;          // Anzahl der Zeilen
+    KSHORT nDropHeight;     // Hoehe
+    KSHORT nDropDescent;    // Abstand zur naechsten Zeile
+    KSHORT nDistance;       // Abstand zum Text
+    KSHORT nFix;            // Fixposition
+    short nX;               // X-PaintOffset
+    short nY;               // Y-PaintOffset
+
+    sal_Bool FormatTxt( SwTxtFormatInfo &rInf );
+    void PaintTxt( const SwTxtPaintInfo &rInf /*, const sal_Bool bBack */) const;
+
+    inline void Fix( const KSHORT nNew ) { nFix = nNew; }
+public:
+    SwDropPortion( SwFont *pFnt, const MSHORT nLineCnt,
+                                 const KSHORT nDropHeight,
+                                 const KSHORT nDropDescent,
+                                 const KSHORT nDistance );
+    virtual ~SwDropPortion();
+
+    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+            void PaintDrop( const SwTxtPaintInfo &rInf ) const;
+    virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+    virtual SwPosSize GetTxtSize( const SwTxtSizeInfo &rInfo ) const;
+    virtual xub_StrLen GetCrsrOfst( const MSHORT nOfst ) const;
+#ifdef OLDRECYCLE
+    virtual sal_Bool MayRecycle() const;
+#endif
+
+    inline MSHORT GetLines() const { return nLines; }
+    inline KSHORT GetDistance() const { return nDistance; }
+    inline KSHORT GetDropHeight() const { return nDropHeight; }
+    inline KSHORT GetDropDescent() const { return nDropDescent; }
+    inline KSHORT GetDropLeft() const { return Width() + nFix; }
+
+    static void DeleteDropCapCache();
+
+    OUTPUT_OPERATOR
+};
+
+
+#endif
diff --git a/sw/source/core/text/porexp.cxx b/sw/source/core/text/porexp.cxx
new file mode 100644
index 000000000000..c2e688f59abe
--- /dev/null
+++ b/sw/source/core/text/porexp.cxx
@@ -0,0 +1,332 @@
+/*************************************************************************
+ *
+ *  $RCSfile: porexp.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _VIEWOPT_HXX
+#include   // SwViewOptions
+#endif
+#ifndef _INFTXT_HXX
+#include 
+#endif
+#ifndef _POREXP_HXX
+#include 
+#endif
+#ifndef _PORLAY_HXX
+#include 
+#endif
+
+/*************************************************************************
+ *                      class SwExpandPortion
+ *************************************************************************/
+
+xub_StrLen SwExpandPortion::GetCrsrOfst( const MSHORT nOfst ) const
+{ return SwLinePortion::GetCrsrOfst( nOfst ); }
+
+#ifdef OLDRECYCLE
+
+sal_Bool SwExpandPortion::MayRecycle() const { return sal_False; }
+
+#endif
+
+/*************************************************************************
+ *              virtual SwExpandPortion::GetExpTxt()
+ *************************************************************************/
+
+sal_Bool SwExpandPortion::GetExpTxt( const SwTxtSizeInfo &rInf,
+                                 XubString &rTxt ) const
+{
+    rTxt.Erase();
+    // Nicht etwa: return 0 != rTxt.Len();
+    // Weil: leere Felder ersetzen CH_TXTATR gegen einen Leerstring
+    return sal_True;
+}
+
+/*************************************************************************
+ *              virtual SwExpandPortion::GetTxtSize()
+ *************************************************************************/
+
+SwPosSize SwExpandPortion::GetTxtSize( const SwTxtSizeInfo &rInf ) const
+{
+    SwTxtSlot aDiffTxt( &rInf, this );
+    return rInf.GetTxtSize();
+}
+
+/*************************************************************************
+ *                 virtual SwExpandPortion::Format()
+ *************************************************************************/
+
+// 5010: Exp und Tabs
+
+sal_Bool SwExpandPortion::Format( SwTxtFormatInfo &rInf )
+{
+    SwTxtSlotLen aDiffTxt( &rInf, this );
+    const xub_StrLen nFullLen = rInf.GetLen();
+
+    // So komisch es aussieht, die Abfrage auf GetLen() muss wegen der
+    // ExpandPortions _hinter_ aDiffTxt (vgl. SoftHyphs)
+    // sal_False returnen wegen SetFull ...
+    if( !nFullLen )
+    {
+        // nicht Init(), weil wir Hoehe und Ascent brauchen
+        Width(0);
+        SetLen(0);
+        return sal_False;
+    }
+    return SwTxtPortion::Format( rInf );
+}
+
+/*************************************************************************
+ *              virtual SwExpandPortion::Paint()
+ *************************************************************************/
+
+void SwExpandPortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+    SwTxtSlotLen aDiffTxt( &rInf, this );
+    rInf.DrawBackBrush( *this );
+    rInf.DrawText( *this, rInf.GetLen(), sal_False );
+}
+
+/*************************************************************************
+ *                      class SwBlankPortion
+ *************************************************************************/
+
+SwLinePortion *SwBlankPortion::Compress() { return this; }
+
+/*************************************************************************
+ *                 SwBlankPortion::MayUnderFlow()
+ *************************************************************************/
+
+// 5497: Es gibt schon Gemeinheiten auf der Welt...
+// Wenn eine Zeile voll mit HardBlanks ist und diese ueberlaeuft,
+// dann duerfen keine Underflows generiert werden!
+// Komplikationen bei Flys...
+
+MSHORT SwBlankPortion::MayUnderFlow( const SwTxtFormatInfo &rInf,
+    xub_StrLen nIdx, sal_Bool bUnderFlow ) const
+{
+    if( rInf.StopUnderFlow() )
+        return 0;
+    const SwLinePortion *pPos = rInf.GetRoot();
+    if( pPos->GetPortion() )
+        pPos = pPos->GetPortion();
+    while( pPos && pPos->IsBlankPortion() )
+        pPos = pPos->GetPortion();
+    if( !pPos || !rInf.GetIdx() || ( !pPos->GetLen() && pPos == rInf.GetRoot() ) )
+        return 0; // Nur noch BlankPortions unterwegs
+    // Wenn vor uns ein Blank ist, brauchen wir kein Underflow ausloesen,
+    // wenn hinter uns ein Blank ist, brauchen wir kein Underflow weiterreichen
+    if( bUnderFlow && CH_BLANK == rInf.GetTxt().GetChar( nIdx + 1) )
+        return 0;
+    if( nIdx && !((SwTxtFormatInfo&)rInf).GetFly() )
+    {
+        while( pPos && !pPos->IsFlyPortion() )
+            pPos = pPos->GetPortion();
+        if( !pPos )
+        {
+        //Hier wird ueberprueft, ob es in dieser Zeile noch sinnvolle Umbrueche
+        //gibt, Blanks oder Felder etc., wenn nicht, kein Underflow.
+        //Wenn Flys im Spiel sind, lassen wir das Underflow trotzdem zu.
+            xub_StrLen nBlank = nIdx;
+            while( --nBlank > rInf.GetLineStart() )
+            {
+                const xub_Unicode cCh = rInf.GetChar( nBlank );
+                if( CH_BLANK == cCh ||
+                    (( CH_TXTATR_BREAKWORD == cCh || CH_TXTATR_INWORD == cCh )
+                        && rInf.HasHint( nBlank ) ) )
+                    break;
+            }
+            if( nBlank <= rInf.GetLineStart() )
+                return 0;
+        }
+    }
+    xub_Unicode cCh;
+    if( nIdx < 2 || CH_BLANK == (cCh = rInf.GetChar( nIdx - 1 )) )
+        return 1;
+    if( CH_BREAK == cCh )
+        return 0;
+    return 2;
+}
+
+/*************************************************************************
+ *                 virtual SwBlankPortion::FormatEOL()
+ *************************************************************************/
+// Format end of Line
+
+void SwBlankPortion::FormatEOL( SwTxtFormatInfo &rInf )
+{
+    MSHORT nMay = MayUnderFlow( rInf, rInf.GetIdx() - nLineLength, sal_True );
+    if( nMay )
+    {
+        if( nMay > 1 )
+        {
+            if( rInf.GetLast() == this )
+               rInf.SetLast( FindPrevPortion( rInf.GetRoot() ) );
+            rInf.X( rInf.X() - PrtWidth() );
+            rInf.SetIdx( rInf.GetIdx() - GetLen() );
+        }
+        Underflow( rInf );
+        if( rInf.GetLast()->IsKernPortion() )
+        {
+            rInf.SetLast( rInf.GetLast()->FindPrevPortion( rInf.GetRoot() ) );
+            rInf.SetUnderFlow( rInf.GetLast() );
+        }
+    }
+}
+
+/*************************************************************************
+ *                 virtual SwBlankPortion::Format()
+ *************************************************************************/
+
+// 7771: UnderFlows weiterreichen und selbst ausloesen!
+sal_Bool SwBlankPortion::Format( SwTxtFormatInfo &rInf )
+{
+    const sal_Bool bFull = rInf.IsUnderFlow() || SwExpandPortion::Format( rInf );
+    if( bFull && MayUnderFlow( rInf, rInf.GetIdx(), rInf.IsUnderFlow() ) )
+    {
+        Underflow( rInf );
+        if( rInf.GetLast()->IsKernPortion() )
+        {
+            rInf.SetLast( rInf.GetLast()->FindPrevPortion( rInf.GetRoot() ) );
+            rInf.SetUnderFlow( rInf.GetLast() );
+        }
+    }
+    return bFull;
+}
+
+/*************************************************************************
+ *                 virtual SwBlankPortion::Paint()
+ *************************************************************************/
+
+void SwBlankPortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+    rInf.DrawViewOpt( *this, POR_BLANK );
+    SwExpandPortion::Paint( rInf );
+}
+
+/*************************************************************************
+ *              virtual SwBlankPortion::GetExpTxt()
+ *************************************************************************/
+
+sal_Bool SwBlankPortion::GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const
+{
+    rTxt = cChar;
+    return sal_True;
+}
+
+
+/*************************************************************************
+ *                      class SwPostItsPortion
+ *************************************************************************/
+
+SwPostItsPortion::SwPostItsPortion( sal_Bool bScrpt )
+    : nViewWidth(0), bScript( bScrpt )
+{
+    nLineLength = 1;
+    SetWhichPor( POR_POSTITS );
+}
+
+void SwPostItsPortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+    if( rInf.OnWin() && Width() )
+        rInf.DrawPostIts( *this, IsScript() );
+}
+
+KSHORT SwPostItsPortion::GetViewWidth( const SwTxtSizeInfo &rInf ) const
+{
+    // Nicht zu fassen: PostIts sind immer zu sehen.
+    return rInf.OnWin() ?
+                (KSHORT)rInf.GetOpt().GetPostItsWidth( rInf.GetWin() ) : 0;
+}
+
+/*************************************************************************
+ *                 virtual SwPostItsPortion::Format()
+ *************************************************************************/
+
+sal_Bool SwPostItsPortion::Format( SwTxtFormatInfo &rInf )
+{
+    sal_Bool bRet = SwLinePortion::Format( rInf );
+    // 32749: PostIts sollen keine Auswirkung auf Zeilenhoehe etc. haben
+    SetAscent( 1 );
+    Height( 1 );
+    return bRet;
+}
+
+/*************************************************************************
+ *              virtual SwPostItsPortion::GetExpTxt()
+ *************************************************************************/
+
+sal_Bool SwPostItsPortion::GetExpTxt( const SwTxtSizeInfo &rInf,
+                                  XubString &rTxt ) const
+{
+    if( rInf.OnWin() && rInf.GetOpt().IsPostIts() )
+        rTxt = ' ';
+    else
+        rTxt.Erase();
+    return sal_True;
+}
+
+
+
diff --git a/sw/source/core/text/porexp.hxx b/sw/source/core/text/porexp.hxx
new file mode 100644
index 000000000000..39b05fbf364d
--- /dev/null
+++ b/sw/source/core/text/porexp.hxx
@@ -0,0 +1,131 @@
+/*************************************************************************
+ *
+ *  $RCSfile: porexp.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _POREXP_HXX
+#define _POREXP_HXX
+
+#include "portxt.hxx"
+
+/*************************************************************************
+ *                      class SwExpandPortion
+ *************************************************************************/
+
+class SwExpandPortion : public SwTxtPortion
+{
+public:
+    inline  SwExpandPortion() { SetWhichPor( POR_EXP ); }
+    virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+    virtual xub_StrLen GetCrsrOfst( const MSHORT nOfst ) const;
+    virtual sal_Bool GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const;
+    virtual SwPosSize GetTxtSize( const SwTxtSizeInfo &rInfo ) const;
+    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+#ifdef OLDRECYCLE
+    virtual sal_Bool MayRecycle() const;
+#endif
+    OUTPUT_OPERATOR
+};
+
+
+/*************************************************************************
+ *                      class SwBlankPortion
+ *************************************************************************/
+
+class SwBlankPortion : public SwExpandPortion
+{
+    xub_Unicode cChar;
+public:
+    inline  SwBlankPortion( xub_Unicode cCh )
+    { cChar = cCh; SetLen(1); SetWhichPor( POR_BLANK ); }
+    virtual SwLinePortion *Compress();
+    virtual sal_Bool GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const;
+    virtual void FormatEOL( SwTxtFormatInfo &rInf );
+    virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+    MSHORT MayUnderFlow( const SwTxtFormatInfo &rInf, xub_StrLen nIdx,
+        sal_Bool bUnderFlow ) const;
+    OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ *                      class SwPostItsPortion
+ *************************************************************************/
+
+class SwPostItsPortion : public SwExpandPortion
+{
+    KSHORT  nViewWidth;
+    sal_Bool    bScript;
+public:
+            SwPostItsPortion( sal_Bool bScrpt );
+    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+    virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+    virtual KSHORT GetViewWidth( const SwTxtSizeInfo &rInf ) const;
+    virtual sal_Bool GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const;
+    sal_Bool IsScript() const { return bScript; }
+    OUTPUT_OPERATOR
+};
+
+
+CLASSIO( SwExpandPortion )
+CLASSIO( SwBlankPortion )
+CLASSIO( SwPostItsPortion )
+
+
+#endif
diff --git a/sw/source/core/text/porfld.cxx b/sw/source/core/text/porfld.cxx
new file mode 100644
index 000000000000..5c590ee89574
--- /dev/null
+++ b/sw/source/core/text/porfld.cxx
@@ -0,0 +1,854 @@
+/*************************************************************************
+ *
+ *  $RCSfile: porfld.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _GRAPH_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BRSHITEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _FRMSH_HXX
+#include 
+#endif
+#ifndef _VIEWOPT_HXX
+#include   // SwViewOptions
+#endif
+#ifndef _ERRHDL_HXX
+#include 
+#endif
+#ifndef _TXTCFG_HXX
+#include 
+#endif
+#ifndef _PORLAY_HXX
+#include 
+#endif
+#ifndef _PORFLD_HXX
+#include 
+#endif
+#ifndef _INFTXT_HXX
+#include 
+#endif
+#ifndef _BLINK_HXX
+#include     // pBlink
+#endif
+#ifndef _FRMTOOL_HXX
+#include   // DrawGraphic
+#endif
+#ifndef _VIEWSH_HXX
+#include 
+#endif
+#ifndef _DOCSH_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+
+/*************************************************************************
+ *                      class SwFldPortion
+ *************************************************************************/
+
+SwLinePortion *SwFldPortion::Compress()
+{ return (GetLen() || aExpand.Len() || SwLinePortion::Compress()) ? this : 0; }
+
+SwFldPortion *SwFldPortion::Clone( const XubString &rExpand ) const
+{
+    SwFont *pNewFnt;
+    if( 0 != ( pNewFnt = pFnt ) )
+        pNewFnt = new SwFont( *pFnt );
+    return new SwFldPortion( rExpand, pNewFnt );
+}
+
+void SwFldPortion::TakeNextOffset( const SwFldPortion* pFld )
+{
+    ASSERT( pFld, "TakeNextOffset: Missing Source" );
+    nNextOffset = pFld->GetNextOffset();
+    aExpand.Erase( 0, nNextOffset );
+    bFollow = sal_True;
+}
+
+SwFldPortion::SwFldPortion( const XubString &rExpand, SwFont *pFnt )
+    : aExpand(rExpand), pFnt(pFnt), nViewWidth(0), nNextOffset(0),
+      bFollow( sal_False ), bHasFollow( sal_False )
+{
+    SetWhichPor( POR_FLD );
+}
+
+SwFldPortion::~SwFldPortion()
+{
+    delete pFnt;
+    if( pBlink )
+        pBlink->Delete( this );
+}
+
+/*************************************************************************
+ *               virtual SwFldPortion::GetViewWidth()
+ *************************************************************************/
+
+KSHORT SwFldPortion::GetViewWidth( const SwTxtSizeInfo &rInf ) const
+{
+    // Wir stehen zwar im const, aber nViewWidth sollte erst im letzten
+    // Moment errechnet werden:
+    SwFldPortion* pThis = (SwFldPortion*)this;
+    if( !Width() && rInf.OnWin() && rInf.GetOpt().IsField() )
+    {
+        if( !nViewWidth )
+            pThis->nViewWidth = rInf.GetTxtSize( ' ' ).Width();
+    }
+    else
+        pThis->nViewWidth = 0;
+    return nViewWidth;
+}
+
+/*************************************************************************
+ *                 virtual SwFldPortion::Format()
+ *************************************************************************/
+
+// 8653: in keinem Fall nur SetLen(0);
+
+/*************************************************************************
+ *   Hilfsklasse SwFldSlot
+ **************************************************************************/
+
+class SwFldSlot
+{
+    const XubString *pOldTxt;
+    XubString aTxt;
+    xub_StrLen nIdx;
+    xub_StrLen nLen;
+    sal_Bool bOn;
+    SwTxtSizeInfo *pInf;
+public:
+    SwFldSlot( const SwTxtSizeInfo *pNew, const SwFldPortion *pPor );
+    ~SwFldSlot();
+};
+
+SwFldSlot::SwFldSlot( const SwTxtSizeInfo *pNew, const SwFldPortion *pPor )
+{
+    bOn = pPor->GetExpTxt( *pNew, aTxt );
+
+    // Der Text wird ausgetauscht...
+    if( bOn )
+    {
+        pInf = (SwTxtSizeInfo*)pNew;
+        nIdx = pInf->GetIdx();
+        nLen = pInf->GetLen();
+        pOldTxt = &(pInf->GetTxt());
+        pInf->SetLen( aTxt.Len() );
+        if( pPor->IsFollow() )
+            pInf->SetIdx( 0 );
+        else
+        {
+            XubString aTmp( aTxt );
+            aTxt = *pOldTxt;
+            aTxt.Erase( nIdx, 1 );
+            aTxt.Insert( aTmp, nIdx );
+        }
+        pInf->SetTxt( aTxt );
+    }
+}
+
+SwFldSlot::~SwFldSlot()
+{
+    if( bOn )
+    {
+        pInf->SetTxt( *pOldTxt );
+        pInf->SetIdx( nIdx );
+        pInf->SetLen( nLen );
+    }
+}
+
+sal_Bool SwFldPortion::Format( SwTxtFormatInfo &rInf )
+{
+    // Scope wegen aDiffTxt::DTOR!
+    xub_StrLen nRest;
+    sal_Bool bFull;
+    sal_Bool bEOL = sal_False;
+    long nTxtRest = rInf.GetTxt().Len() - rInf.GetIdx();
+    {
+        SwFldSlot aDiffTxt( &rInf, this );
+        const xub_StrLen nOldFullLen = rInf.GetLen();
+        const MSHORT nFollow = IsFollow() ? 0 : 1;
+        xub_StrLen nFullLen;
+        // In Numerierungen kennen wir keine Platzhalter, sondern
+        // nur "normale" Zeichen.
+        if( InNumberGrp() )
+            nFullLen = nOldFullLen;
+        else
+        {
+            nFullLen = rInf.ScanPortionEnd( rInf.GetIdx() + nOldFullLen,
+                                            IsFollow() ) - rInf.GetIdx();
+            if( nFullLen && CH_BREAK == aExpand.GetChar( nFullLen - 1 ) )
+                --nFullLen;
+        }
+        rInf.SetLen( nFullLen );
+        SwFontSave aSave( rInf, pFnt );
+
+        // 8674: Laenge muss 0 sein, bei bFull nach Format ist die Laenge
+        // gesetzt und wird in nRest uebertragen. Ansonsten bleibt die
+        // Laenge erhalten und wuerde auch in nRest einfliessen!
+        SetLen(0);
+
+        // So komisch es aussieht, die Abfrage auf GetLen() muss wegen der
+        // ExpandPortions _hinter_ aDiffTxt (vgl. SoftHyphs)
+        // sal_False returnen wegen SetFull ...
+        if( !nFullLen )
+        {
+            // nicht Init(), weil wir Hoehe und Ascent brauchen
+            Width(0);
+            bFull = rInf.Width() <= rInf.GetPos().X();
+        }
+        else
+        {
+            xub_StrLen nOldLineStart = rInf.GetLineStart();
+            rInf.SetLineStart( 0 );
+            rInf.SetNotEOL( nFullLen == nOldFullLen && nTxtRest > nFollow );
+            bFull = SwTxtPortion::Format( rInf );
+            rInf.SetNotEOL( sal_False );
+            rInf.SetLineStart( nOldLineStart );
+        }
+        xub_StrLen nTmpLen = GetLen();
+        bEOL = !nTmpLen && nFollow && bFull;
+        nRest = nOldFullLen - nTmpLen;
+
+        // Das Zeichen wird in der ersten Portion gehalten.
+        // Unbedingt nach Format!
+        SetLen( nFollow );
+
+        if( nRest )
+        {
+            // aExpand ist noch nicht gekuerzt worden, der neue Ofst
+            // ergibt sich durch nRest.
+            xub_StrLen nNextOfst = aExpand.Len() - nRest;
+            XubString aNew( aExpand, nNextOfst, STRING_LEN );
+            aExpand.Erase( nNextOfst, STRING_LEN );
+
+            // Trailingspace et al. !
+            switch( aNew.GetChar( 0 ))
+            {
+                case CH_BREAK  : bFull = sal_True;
+                            // kein break;
+                case ' ' :
+                case CH_TAB    :
+                {
+                    aNew.Erase( 0, 1 );
+                    ++nNextOfst;
+                    break;
+                }
+                default: ;
+            }
+
+            if( aNew.Len() )
+            {
+                // sal_True, weil es ein FollowFeld ist
+                // SwFont *pFont = new SwFont( rInf.GetFont()->GetFnt() );
+                SwFldPortion *pFld = Clone( aNew );
+                if( !pFld->GetFont() )
+                {
+                    SwFont *pNewFnt = new SwFont( *rInf.GetFont() );
+                    pNewFnt->GoMagic( rInf.GetVsh(), pNewFnt->GetActual() );
+                    pFld->SetFont( pNewFnt );
+                }
+                pFld->SetFollow( sal_True );
+                SetHasFollow( sal_True );
+                // In nNextOffset steht bei einem neuangelegten Feld zunaechst
+                // der Offset, an dem es selbst im Originalstring beginnt.
+                // Wenn beim Formatieren ein FollowFeld angelegt wird, wird
+                // der Offset dieses FollowFelds in nNextOffset festgehalten.
+                nNextOffset += nNextOfst;
+                pFld->SetNextOffset( nNextOffset );
+                rInf.SetRest( pFld );
+            }
+        }
+        // 7634 mit ASSERT: bad ascent
+        if( pFnt && nTmpLen )
+            SetAscent( rInf.GetAscent() );
+    }
+
+    if( bFull && !nRest )
+    {
+        // 8788: BreakCut bei Feldern schleift
+        // vgl. BreakCut, Sonderfall Nr.2: Zeichen breiter als Zeile
+        // vgl. 5057 und 6721: Zeichen wird abgeschnitten.
+        if( 1 != GetLen() || Width() != rInf.RealWidth() )
+        {
+            aExpand.Erase();
+            SetLen(0);
+            // 7925: Wenn das Feld komplett auf die naechste Zeile muss
+            // dann wird in BreakUnderflow() ein FormatEOL() auf die
+            // TxtPortion gerufen. Der Text rInf.pTxt ist allerdings noch
+            // manipuliert, hier aber nicht.
+            bEOL = sal_True;
+        }
+    }
+    if( bEOL && rInf.GetLast() )
+        rInf.GetLast()->FormatEOL( rInf );
+    return bFull;
+}
+
+/*************************************************************************
+ *               virtual SwFldPortion::Paint()
+ *************************************************************************/
+
+void SwFldPortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+    SwFontSave aSave( rInf, pFnt );
+
+    ASSERT( GetLen() <= 1, "SwFldPortion::Paint: rest-portion polution?" );
+    if( Width() )
+    {
+        // Dies ist eine freizuegige Auslegung der Hintergrundbelegung ...
+        rInf.DrawViewOpt( *this, POR_FLD );
+        SwExpandPortion::Paint( rInf );
+    }
+}
+
+/*************************************************************************
+ *              virtual SwFldPortion::GetExpTxt()
+ *************************************************************************/
+
+sal_Bool SwFldPortion::GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const
+{
+    rTxt = aExpand;
+    if( !rTxt.Len() && rInf.OnWin() && rInf.GetOpt().IsField() && !HasFollow() )
+        rTxt = ' ';
+    return sal_True;
+}
+
+/*************************************************************************
+ *                virtual SwFldPortion::GetTxtSize()
+ *************************************************************************/
+
+SwPosSize SwFldPortion::GetTxtSize( const SwTxtSizeInfo &rInf ) const
+{
+    SwFontSave aSave( rInf, pFnt );
+    SwPosSize aSize( SwExpandPortion::GetTxtSize( rInf ) );
+    return aSize;
+}
+
+/*************************************************************************
+ *                      class SwHiddenPortion
+ *************************************************************************/
+
+SwFldPortion *SwHiddenPortion::Clone(const XubString &rExpand ) const
+{
+    SwFont *pNewFnt;
+    if( 0 != ( pNewFnt = pFnt ) )
+        pNewFnt = new SwFont( *pFnt );
+    return new SwHiddenPortion( rExpand, pNewFnt );
+}
+
+/*************************************************************************
+ *               virtual SwHiddenPortion::Paint()
+ *************************************************************************/
+
+void SwHiddenPortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+    if( Width() )
+    {
+        rInf.DrawViewOpt( *this, POR_HIDDEN );
+        SwExpandPortion::Paint( rInf );
+    }
+}
+
+/*************************************************************************
+ *              virtual SwHiddenPortion::GetExpTxt()
+ *************************************************************************/
+
+sal_Bool SwHiddenPortion::GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const
+{
+    // Nicht auf IsHidden() abfragen !
+    return SwFldPortion::GetExpTxt( rInf, rTxt );
+}
+
+/*************************************************************************
+ *                      class SwNumberPortion
+ *************************************************************************/
+
+SwNumberPortion::SwNumberPortion( const XubString &rExpand, SwFont *pFnt,
+                    const sal_Bool bLft, const sal_Bool bCntr, const KSHORT nMinDst )
+        : SwFldPortion( rExpand, pFnt ), nFixWidth(0), nMinDist( nMinDst )
+{
+    SetWhichPor( POR_NUMBER );
+    SetLeft( bLft );
+    SetHide( sal_False );
+    SetCenter( bCntr );
+}
+
+xub_StrLen SwNumberPortion::GetCrsrOfst( const MSHORT ) const
+{
+    return 0;
+}
+
+SwFldPortion *SwNumberPortion::Clone( const XubString &rExpand ) const
+{
+    SwFont *pNewFnt;
+    if( 0 != ( pNewFnt = pFnt ) )
+        pNewFnt = new SwFont( *pFnt );
+    return new SwNumberPortion( rExpand, pNewFnt, IsLeft(), IsCenter(),
+        nMinDist );
+}
+
+/*************************************************************************
+ *                 virtual SwNumberPortion::Format()
+ *************************************************************************/
+
+// 5010: Wir sind in der Lage, mehrzeilige NumFelder anzulegen!
+// 3689: Fies ist, wenn man in der Dialogbox soviel Davor-Text
+// eingibt, bis die Zeile ueberlaeuft.
+// Man muss die Fly-Ausweichmanoever beachten!
+
+sal_Bool SwNumberPortion::Format( SwTxtFormatInfo &rInf )
+{
+    SetHide( sal_False );
+    const sal_Bool bFull = SwFldPortion::Format( rInf );
+    SetLen( 0 );
+    nFixWidth = Width();
+    rInf.SetNumDone( !rInf.GetRest() );
+    if( rInf.IsNumDone() )
+    {
+        SetAscent( rInf.GetAscent() );
+        long nDiff = rInf.Left() - rInf.First() + rInf.ForcedLeftMargin();
+        // Ein Vorschlag von Juergen und Volkmar:
+        // Der Textteil hinter der Numerierung sollte immer
+        // mindestens beim linken Rand beginnen.
+        if( nDiff < 0 )
+            nDiff = 0;
+        else if ( nDiff > rInf.X() )
+            nDiff -= rInf.X();
+        if( nDiff < nFixWidth + nMinDist )
+            nDiff = nFixWidth + nMinDist;
+        // 2739: Numerierung weicht Fly aus, kein nDiff in der zweiten Runde
+        // fieser Sonderfall: FlyFrm liegt in dem Bereich,
+        // den wir uns gerade unter den Nagel reissen wollen.
+        // Die NumberPortion wird als verborgen markiert.
+        if( nDiff > rInf.Width() )
+        {
+            nDiff = rInf.Width();
+            SetHide( sal_True );
+        }
+
+        if( Width() < nDiff )
+            Width( KSHORT(nDiff) );
+    }
+    return bFull;
+}
+
+void SwNumberPortion::FormatEOL( SwTxtFormatInfo &rInf )
+{
+/*  Ein FormatEOL deutet daraufhin, dass der folgende Text
+ *  nicht mit auf die Zeile passte. Damit die Numerierung mitwandert,
+ *  wird diese NumberPortion verborgen.
+ */
+    SetHide( sal_True );
+}
+
+/*************************************************************************
+ *               virtual SwNumberPortion::Paint()
+ *************************************************************************/
+
+void SwNumberPortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+/*  Eine verborgene NumberPortion wird nicht angezeigt, es sei denn, es gibt
+ *  Textportions in dieser Zeile oder es gibt ueberhaupt nur eine einzige Zeile.
+ */
+    if ( IsHide() && rInf.GetParaPortion() && rInf.GetParaPortion()->GetNext() )
+    {
+        SwLinePortion *pTmp = GetPortion();
+        while ( pTmp && !pTmp->InTxtGrp() )
+            pTmp = pTmp->GetPortion();
+        if ( !pTmp )
+            return;
+    }
+
+    // Dies ist eine freizuegige Auslegung der Hintergrundbelegung ...
+    rInf.DrawViewOpt( *this, POR_NUMBER );
+
+    if( aExpand.Len() )
+    {
+        const SwFont *pTmpFnt = rInf.GetFont();
+        sal_Bool bPaintSpace = ( UNDERLINE_NONE != pTmpFnt->GetUnderline() ||
+                             STRIKEOUT_NONE != pTmpFnt->GetStrikeout() ) &&
+                            !pTmpFnt->IsWordLineMode();
+        if( bPaintSpace && pFnt )
+            bPaintSpace = ( UNDERLINE_NONE != pFnt->GetUnderline() ||
+                             STRIKEOUT_NONE != pFnt->GetStrikeout() ) &&
+                            !pFnt->IsWordLineMode();
+
+        SwFontSave aSave( rInf, pFnt );
+
+        if( nFixWidth == Width() )
+            SwExpandPortion::Paint( rInf );
+        else
+        {
+            // logisches const: Width wird wieder zurueckgesetzt
+            SwLinePortion *pThis = (SwLinePortion*)this;
+            const KSHORT nOldWidth = Width();
+            bPaintSpace = bPaintSpace && nFixWidth < nOldWidth;
+            KSHORT nSpaceOffs = nFixWidth;
+            pThis->Width( nFixWidth );
+            if( IsLeft() )
+                SwExpandPortion::Paint( rInf );
+            else
+            {
+                SwTxtPaintInfo aInf( rInf );
+                KSHORT nOffset = nOldWidth - nFixWidth;
+                if( nOffset < nMinDist )
+                    nOffset = 0;
+                else
+                {
+                    if( IsCenter() )
+                    {
+                        nOffset /= 2;
+                        if( nOffset < nMinDist )
+                            nOffset = nOldWidth - nFixWidth - nMinDist;
+                    }
+                    else
+                        nOffset -= nMinDist;
+                }
+                aInf.X( aInf.X() + nOffset );
+                SwExpandPortion::Paint( aInf );
+                if( bPaintSpace )
+                    nSpaceOffs += nOffset;
+            }
+            if( bPaintSpace && nOldWidth > nSpaceOffs )
+            {
+                SwTxtPaintInfo aInf( rInf );
+static sal_Char __READONLY_DATA sDoubleSpace[] = "  ";
+                aInf.X( aInf.X() + nSpaceOffs );
+                pThis->Width( nOldWidth - nSpaceOffs + 12 );
+                {
+                    SwTxtSlotLen aDiffTxt( &aInf, this, sDoubleSpace );
+                    aInf.DrawText( *this, aInf.GetLen(), sal_True );
+                }
+            }
+            pThis->Width( nOldWidth );
+        }
+    }
+}
+
+
+/*************************************************************************
+ *                      class SwBulletPortion
+ *************************************************************************/
+
+SwBulletPortion::SwBulletPortion( const xub_Unicode cBullet, SwFont *pFont,
+                    const sal_Bool bLft, const sal_Bool bCntr, const KSHORT nMinDst )
+    : SwNumberPortion( XubString( cBullet ), pFont, bLft, bCntr, nMinDst )
+{
+    SetWhichPor( POR_BULLET );
+}
+
+/*************************************************************************
+ *                      class SwGrfNumPortion
+ *************************************************************************/
+
+#define GRFNUM_SECURE 10
+
+SwGrfNumPortion::SwGrfNumPortion(
+        SwFrm *pFrm,
+        const SvxBrushItem* pGrfBrush,
+        const SwFmtVertOrient* pGrfOrient, const Size& rGrfSize,
+        const sal_Bool bLft, const sal_Bool bCntr, const KSHORT nMinDst ) :
+    SwNumberPortion( aEmptyStr, NULL, bLft, bCntr, nMinDst ),
+    pBrush( new SvxBrushItem() ), nId( 0 )
+{
+    SetWhichPor( POR_GRFNUM );
+    SetAnimated( sal_False );
+    bReplace = sal_False;
+    if( pGrfBrush )
+    {
+        *pBrush = *pGrfBrush;
+        SwDocShell *pSh = pFrm->GetShell()->GetDoc()->GetDocShell();
+        const Graphic* pGraph = pGrfBrush->GetGraphic( pSh );
+        if( pGraph )
+            SetAnimated( pGraph->IsAnimated() );
+        else
+            bReplace = sal_True;
+    }
+    if( pGrfOrient )
+    {
+        nYPos = pGrfOrient->GetPos();
+        eOrient = pGrfOrient->GetVertOrient();
+    }
+    else
+    {
+        nYPos = 0;
+        eOrient = VERT_TOP;
+    }
+    Width( rGrfSize.Width() + 2 * GRFNUM_SECURE );
+    nFixWidth = Width();
+    nGrfHeight = rGrfSize.Height() + 2 * GRFNUM_SECURE;
+    Height( nGrfHeight );
+    bNoPaint = sal_False;
+}
+
+SwGrfNumPortion::~SwGrfNumPortion()
+{
+    if ( IsAnimated() )
+        ( (Graphic*) pBrush->GetGraphic() )->StopAnimation( 0, nId );
+    delete pBrush;
+}
+
+void SwGrfNumPortion::StopAnimation( OutputDevice *pOut )
+{
+    if ( IsAnimated() )
+        ( (Graphic*) pBrush->GetGraphic() )->StopAnimation( pOut, nId );
+}
+
+sal_Bool SwGrfNumPortion::Format( SwTxtFormatInfo &rInf )
+{
+    SetHide( sal_False );
+    Width( nFixWidth );
+    const sal_Bool bFull = rInf.Width() < rInf.X() + Width();
+    const sal_Bool bFly = rInf.GetFly() ||
+        ( rInf.GetLast() && rInf.GetLast()->IsFlyPortion() );
+    SetAscent( GetRelPos() > 0 ? GetRelPos() : 0 );
+    if( GetAscent() > Height() )
+        Height( GetAscent() );
+
+    if( bFull )
+    {
+        Width( rInf.Width() - rInf.X() );
+        if( bFly )
+        {
+            SetLen( 0 );
+            SetNoPaint( sal_True );
+            rInf.SetNumDone( sal_False );
+            return sal_True;
+        }
+    }
+    rInf.SetNumDone( sal_True );
+    long nDiff = rInf.Left() - rInf.First() + rInf.ForcedLeftMargin();
+    // Ein Vorschlag von Juergen und Volkmar:
+    // Der Textteil hinter der Numerierung sollte immer
+    // mindestens beim linken Rand beginnen.
+    if( nDiff < 0 )
+        nDiff = 0;
+    else if ( nDiff > rInf.X() )
+        nDiff -= rInf.X();
+    if( nDiff < nFixWidth + nMinDist )
+        nDiff = nFixWidth + nMinDist;
+    // 2739: Numerierung weicht Fly aus, kein nDiff in der zweiten Runde
+    // fieser Sonderfall: FlyFrm liegt in dem Bereich,
+    // den wir uns gerade unter den Nagel reissen wollen.
+    // Die NumberPortion wird als verborgen markiert.
+    if( nDiff > rInf.Width() )
+    {
+        nDiff = rInf.Width();
+        if( bFly )
+            SetHide( sal_True );
+    }
+
+    if( Width() < nDiff )
+        Width( KSHORT(nDiff) );
+    return bFull;
+}
+
+void SwGrfNumPortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+    if( DontPaint() )
+        return;
+/*  Eine verborgene NumberPortion wird nicht angezeigt, es sei denn, es gibt
+ *  Textportions in dieser Zeile oder es gibt ueberhaupt nur eine einzige Zeile.
+ */
+    if ( IsHide() && rInf.GetParaPortion() && rInf.GetParaPortion()->GetNext() )
+    {
+        SwLinePortion *pTmp = GetPortion();
+        while ( pTmp && !pTmp->InTxtGrp() )
+            pTmp = pTmp->GetPortion();
+        if ( !pTmp )
+            return;
+    }
+    Point aPos( rInf.X() + GRFNUM_SECURE, rInf.Y() - GetRelPos() + GRFNUM_SECURE );
+    long nTmpWidth = Max( (long)0, (long)(nFixWidth - 2 * GRFNUM_SECURE) );
+    Size aSize( nTmpWidth, GetGrfHeight() - 2 * GRFNUM_SECURE );
+
+    if( nFixWidth < Width() && !IsLeft() )
+    {
+        KSHORT nOffset = Width() - nFixWidth;
+        if( nOffset < nMinDist )
+            nOffset = 0;
+        else
+        {
+            if( IsCenter() )
+            {
+                nOffset /= 2;
+                if( nOffset < nMinDist )
+                    nOffset = Width() - nFixWidth - nMinDist;
+            }
+            else
+                nOffset -= nMinDist;
+        }
+        aPos.X() += nOffset;
+    }
+
+    if( bReplace )
+    {
+        KSHORT nTmpH = GetPortion() ? GetPortion()->GetAscent() : 120;
+        aSize = Size( nTmpH, nTmpH );
+        aPos.Y() = rInf.Y() - nTmpH;
+    }
+    SwRect aTmp( aPos, aSize );
+
+    sal_Bool bDraw = sal_True;
+
+    if ( IsAnimated() )
+    {
+        bDraw = !rInf.GetOpt().IsGraphic();
+        if( !nId )
+        {
+            SetId( long( rInf.GetTxtFrm() ) );
+            rInf.GetTxtFrm()->SetAnimation();
+        }
+        if( aTmp.IsOver( rInf.GetPaintRect() ) && !bDraw )
+        {
+            rInf.NoteAnimation();
+            if( OUTDEV_VIRDEV == rInf.GetOut()->GetOutDevType() )
+            {
+                ( (Graphic*) pBrush->GetGraphic() )->StopAnimation(0,nId);
+                rInf.GetTxtFrm()->GetShell()->InvalidateWindows( aTmp );
+            }
+            else
+                ( (Graphic*) pBrush->GetGraphic() )->StartAnimation(
+                    (OutputDevice*)rInf.GetOut(), aPos, aSize, nId );
+        }
+        if( bDraw )
+            ( (Graphic*) pBrush->GetGraphic() )->StopAnimation( 0, nId );
+    }
+
+    if( bDraw && aTmp.HasArea() )
+        DrawGraphic( pBrush, (OutputDevice*)rInf.GetOut(),
+            aTmp, rInf.GetPaintRect(), bReplace ? GRFNUM_REPLACE : GRFNUM_YES );
+}
+
+void SwGrfNumPortion::SetBase( long nLnAscent, long nLnDescent,
+                               long nFlyAsc, long nFlyDesc )
+{
+    if ( GetOrient() != VERT_NONE )
+    {
+        SetRelPos( 0 );
+        if ( GetOrient() == VERT_CENTER )
+            SetRelPos( GetGrfHeight() / 2 );
+        else if ( GetOrient() == VERT_TOP )
+            SetRelPos( GetGrfHeight() - GRFNUM_SECURE );
+        else if ( GetOrient() == VERT_BOTTOM )
+            ;
+        else if ( GetOrient() == VERT_CHAR_CENTER )
+            SetRelPos( ( GetGrfHeight() + nLnAscent - nLnDescent ) / 2 );
+        else if ( GetOrient() == VERT_CHAR_TOP )
+            SetRelPos( nLnAscent );
+        else if ( GetOrient() == VERT_CHAR_BOTTOM )
+            SetRelPos( GetGrfHeight() - nLnDescent );
+        else
+        {
+            if( GetGrfHeight() >= nFlyAsc + nFlyDesc )
+            {
+                // wenn ich genauso gross bin wie die Zeile, brauche ich mich
+                // nicht an der Zeile nicht weiter ausrichten, ich lasse
+                // dann auch den max. Ascent der Zeile unveraendert
+
+                SetRelPos( nFlyAsc );
+            }
+            else if ( GetOrient() == VERT_LINE_CENTER )
+                SetRelPos( ( GetGrfHeight() + nFlyAsc - nFlyDesc ) / 2 );
+            else if ( GetOrient() == VERT_LINE_TOP )
+                SetRelPos( nFlyAsc );
+            else if ( GetOrient() == VERT_LINE_BOTTOM )
+                SetRelPos( GetGrfHeight() - nFlyDesc );
+        }
+    }
+}
+void SwTxtFrm::StopAnimation( OutputDevice *pOut )
+{
+    ASSERT( HasAnimation(), "SwTxtFrm::StopAnimation: Which Animation?" );
+    if( HasPara() )
+    {
+        SwLineLayout *pLine = GetPara();
+        while( pLine )
+        {
+            SwLinePortion *pPor = pLine->GetPortion();
+            while( pPor )
+            {
+                if( pPor->IsGrfNumPortion() )
+                    ((SwGrfNumPortion*)pPor)->StopAnimation( pOut );
+                // Die Numerierungsportion sitzt immer vor dem ersten Zeichen,
+                // deshalb koennen wir abbrechen, sobald wir eine Portion mit
+                // einer Laenge > 0 erreicht haben.
+                pPor = pPor->GetLen() ? 0 : pPor->GetPortion();
+            }
+            pLine = pLine->GetLen() ? 0 : pLine->GetNext();
+        }
+    }
+}
+
+
diff --git a/sw/source/core/text/porfld.hxx b/sw/source/core/text/porfld.hxx
new file mode 100644
index 000000000000..9570a90921f3
--- /dev/null
+++ b/sw/source/core/text/porfld.hxx
@@ -0,0 +1,240 @@
+/*************************************************************************
+ *
+ *  $RCSfile: porfld.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _PORFLD_HXX
+#define _PORFLD_HXX
+
+#include "swtypes.hxx"
+#include "porexp.hxx"
+#ifndef _FMTORNT_HXX //autogen
+#include 
+#endif
+
+class SwFont;
+class SvxBrushItem;
+class SwFmtVertOrient;
+class SwFrm;
+
+/*************************************************************************
+ *                      class SwFldPortion
+ *************************************************************************/
+
+class SwFldPortion : public SwExpandPortion
+{
+    friend class SwTxtFormatter;
+protected:
+    XubString  aExpand;            // das expandierte Feld
+    SwFont  *pFnt;              // Fuer mehrzeilige Felder
+    xub_StrLen nNextOffset;     // Offset des Follows im Originalstring
+    KSHORT  nViewWidth;         // Screenbreite fuer leere Felder
+    sal_Bool bFollow : 1;           // 2. oder weiterer Teil eines Feldes
+    sal_Bool bLeft : 1;             // wird von SwNumberPortion benutzt
+    sal_Bool bHide : 1;             // wird von SwNumberPortion benutzt
+    sal_Bool bCenter : 1;           // wird von SwNumberPortion benutzt
+    sal_Bool bHasFollow : 1;        // geht in der naechsten Zeile weiter
+    sal_Bool bAnimated : 1;         // wird von SwGrfNumPortion benutzt
+    sal_Bool bNoPaint : 1;          // wird von SwGrfNumPortion benutzt
+    sal_Bool bReplace : 1;          // wird von SwGrfNumPortion benutzt
+
+    inline void SetFont( SwFont *pNew ) { pFnt = pNew; }
+    inline const SwFont *GetFont() const { return pFnt; }
+public:
+    SwFldPortion( const XubString &rExpand, SwFont *pFnt = 0 );
+    ~SwFldPortion();
+
+    void TakeNextOffset( const SwFldPortion* pFld );
+
+    inline const XubString &GetExp() const { return aExpand; }
+    virtual sal_Bool GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const;
+    virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+
+    // leere Felder sind auch erlaubt
+    virtual SwLinePortion *Compress();
+
+    virtual KSHORT GetViewWidth( const SwTxtSizeInfo &rInf ) const;
+
+    inline sal_Bool IsFollow() const { return bFollow; }
+    inline void SetFollow( sal_Bool bNew ) { bFollow = bNew; }
+
+    inline sal_Bool IsLeft() const { return bLeft; }
+    inline void SetLeft( sal_Bool bNew ) { bLeft = bNew; }
+
+    inline sal_Bool IsHide() const { return bHide; }
+    inline void SetHide( sal_Bool bNew ) { bHide = bNew; }
+
+    inline sal_Bool IsCenter() const { return bCenter; }
+    inline void SetCenter( sal_Bool bNew ) { bCenter = bNew; }
+
+    inline sal_Bool HasFollow() const { return bHasFollow; }
+    inline void SetHasFollow( sal_Bool bNew ) { bHasFollow = bNew; }
+
+    inline xub_StrLen GetNextOffset() const { return nNextOffset; }
+    inline void SetNextOffset( xub_StrLen nNew ) { nNextOffset = nNew; }
+
+    // Felder-Cloner fuer SplitGlue
+    virtual SwFldPortion *Clone( const XubString &rExpand ) const;
+
+    // Extra-GetTxtSize wegen pFnt
+    virtual SwPosSize GetTxtSize( const SwTxtSizeInfo &rInfo ) const;
+
+    OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ *                      class SwHiddenPortion
+ *************************************************************************/
+// Unterscheidung nur fuer's Painten/verstecken.
+
+class SwHiddenPortion : public SwFldPortion
+{
+public:
+    inline SwHiddenPortion( const XubString &rExpand, SwFont *pFnt = 0 )
+         : SwFldPortion( rExpand, pFnt )
+        { SetLen(1); SetWhichPor( POR_HIDDEN ); }
+    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+    virtual sal_Bool GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const;
+
+    // Felder-Cloner fuer SplitGlue
+    virtual SwFldPortion *Clone( const XubString &rExpand ) const;
+    OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ *                      class SwNumberPortion
+ *************************************************************************/
+
+class SwNumberPortion : public SwFldPortion
+{
+protected:
+    KSHORT  nFixWidth;      // vgl. Glues
+    KSHORT  nMinDist;       // minimaler Abstand zum Text
+public:
+    SwNumberPortion( const XubString &rExpand, SwFont *pFnt,
+        const sal_Bool bLeft, const sal_Bool bCenter, const KSHORT nMinDst );
+    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+    virtual xub_StrLen GetCrsrOfst( const MSHORT nOfst ) const;
+    virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+
+    // Felder-Cloner fuer SplitGlue
+    virtual SwFldPortion *Clone( const XubString &rExpand ) const;
+    virtual void FormatEOL( SwTxtFormatInfo &rInf );
+
+    OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ *                      class SwBulletPortion
+ *************************************************************************/
+
+class SwBulletPortion : public SwNumberPortion
+{
+public:
+    SwBulletPortion( const xub_Unicode cCh, SwFont *pFnt, const sal_Bool bLeft,
+                     const sal_Bool bCenter, const KSHORT nMinDst );
+    OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ *                      class SwBmpBulletPortion
+ *************************************************************************/
+
+class SwGrfNumPortion : public SwNumberPortion
+{
+    SvxBrushItem* pBrush;
+    long            nId;    //fuer StopAnimation
+    SwTwips         nYPos;  //Enthaelt _immer_ die aktuelle RelPos.
+    SwTwips         nGrfHeight;
+    SwVertOrient    eOrient;
+public:
+    SwGrfNumPortion( SwFrm *pFrm, const SvxBrushItem* pGrfBrush,
+        const SwFmtVertOrient* pGrfOrient, const Size& rGrfSize,
+        const sal_Bool bLeft, const sal_Bool bCenter, const KSHORT nMinDst );
+    ~SwGrfNumPortion();
+    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+    virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+
+    void SetBase( long nLnAscent, long nLnDescent,
+        long nFlyAscent, long nFlyDescent );
+
+    void StopAnimation( OutputDevice *pOut );
+
+    inline sal_Bool IsAnimated() const { return bAnimated; }
+    inline void SetAnimated( sal_Bool bNew ) { bAnimated = bNew; }
+    inline sal_Bool DontPaint() const { return bNoPaint; }
+    inline void SetNoPaint( sal_Bool bNew ) { bNoPaint = bNew; }
+    inline void SetRelPos( SwTwips nNew ) { nYPos = nNew; }
+    inline void SetId( long nNew ) const
+        { ((SwGrfNumPortion*)this)->nId = nNew; }
+    inline SwTwips GetRelPos() const { return nYPos; }
+    inline SwTwips GetGrfHeight() const { return nGrfHeight; }
+    inline SwTwips GetId() const { return nId; }
+    inline SwVertOrient GetOrient() const { return eOrient; }
+
+    OUTPUT_OPERATOR
+};
+
+CLASSIO( SwHiddenPortion )
+CLASSIO( SwNumberPortion )
+CLASSIO( SwBulletPortion )
+CLASSIO( SwGrfNumPortion )
+
+
+#endif
diff --git a/sw/source/core/text/porfly.cxx b/sw/source/core/text/porfly.cxx
new file mode 100644
index 000000000000..0837908ea097
--- /dev/null
+++ b/sw/source/core/text/porfly.cxx
@@ -0,0 +1,585 @@
+/*************************************************************************
+ *
+ *  $RCSfile: porfly.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "dcontact.hxx" // SwDrawContact
+#include "dflyobj.hxx"  // SwVirtFlyDrawObj
+#include "pam.hxx"      // SwPosition
+#include "flyfrm.hxx"   // SwFlyInCntFrm
+#include "frmfmt.hxx"   // SwFrmFmt
+#include "viewsh.hxx"
+
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_ULSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFLCNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTORNT_HXX //autogen
+#include 
+#endif
+#ifndef _FRMATR_HXX
+#include 
+#endif
+#include "flyfrms.hxx"
+#include "txatbase.hxx" // SwTxtAttr
+#include "porfly.hxx"
+#include "porlay.hxx"   // SetFly
+#include "inftxt.hxx"   // SwTxtPaintInfo
+#include "frmsh.hxx"
+
+/*************************************************************************
+ *                class SwFlyPortion
+ *
+ * Wir erwarten ein framelokales SwRect !
+ *************************************************************************/
+
+#ifdef OLDRECYCLE
+
+sal_Bool SwFlyPortion::MayRecycle() const { return sal_False; }
+
+#endif
+
+void SwFlyPortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+}
+
+/*************************************************************************
+ *                 virtual SwFlyPortion::Format()
+ *************************************************************************/
+sal_Bool SwFlyPortion::Format( SwTxtFormatInfo &rInf )
+{
+    ASSERT( Fix() >= rInf.X(), "SwFlyPortion::Format: rush hour" );
+    // 8537: Tabs muessen expandiert werden.
+    if( rInf.GetLastTab() )
+        ((SwLinePortion*)rInf.GetLastTab())->FormatEOL( rInf );
+
+    // Der Glue wird aufgespannt.
+    rInf.GetLast()->FormatEOL( rInf );
+#ifdef USED
+    long nFirstDiff;
+
+    if( !Fix() )
+    {
+        nFirstDiff = rInf.Left() - long( rInf.First() );
+        if( rInf.GetLineStart() )
+        {
+            if( nFirstDiff < 0 )
+                nFirstDiff = 0;
+        }
+        else
+        {
+            if( nFirstDiff > 0 )
+                nFirstDiff = 0;
+            else
+                nFirstDiff = -nFirstDiff;
+        }
+        nFirstDiff += rInf.GetTxtFrm()->Prt().Left();
+    }
+    else
+        nFirstDiff = 0;
+    PrtWidth( (Fix() - rInf.X()) + PrtWidth() + nFirstDiff );
+#else
+    PrtWidth( (Fix() - rInf.X()) + PrtWidth() );
+#endif
+    if( !Width() )
+    {
+        ASSERT( Width(), "+SwFlyPortion::Format: a fly is a fly is a fly" );
+        Width(1);
+    }
+
+    // Restaurierung
+    rInf.SetFly( 0 );
+    rInf.Width( rInf.RealWidth() );
+    rInf.GetParaPortion()->SetFly( sal_True );
+
+    // trailing blank:
+    if( rInf.GetIdx() < rInf.GetTxt().Len() &&  1 < rInf.GetIdx()
+        && !rInf.GetRest()
+        && ' ' == rInf.GetChar( rInf.GetIdx() )
+        && ' ' != rInf.GetChar( rInf.GetIdx() - 1 )
+        && ( !rInf.GetLast() || !rInf.GetLast()->IsBreakPortion() ) )
+    {
+        SetBlankWidth( rInf.GetTxtSize( ' ' ).Width() );
+        SetLen( 1 );
+    }
+
+    const KSHORT nNewWidth = rInf.X() + PrtWidth();
+    if( rInf.Width() <= nNewWidth )
+    {
+        Truncate();
+        if( nNewWidth > rInf.Width() )
+        {
+            PrtWidth( nNewWidth - rInf.Width() );
+            SetFixWidth( PrtWidth() );
+        }
+        return sal_True;
+    }
+    return sal_False;
+}
+
+/*************************************************************************
+ *                 virtual SwFlyCntPortion::Format()
+ *************************************************************************/
+sal_Bool SwFlyCntPortion::Format( SwTxtFormatInfo &rInf )
+{
+    sal_Bool bFull = rInf.Width() < rInf.X() + PrtWidth();
+
+    if( bFull )
+    {
+        // 3924: wenn die Zeile voll ist und der zeichengebundene Frame am
+        // Anfang der Zeile steht.
+        // 5157: nicht wenn einem Fly ausgewichen werden kann!
+        if( !rInf.X() && !rInf.GetFly() )
+        {
+            Width( rInf.Width() );
+            bFull = sal_False; // Damit Notizen noch in dieser Zeile landen
+        }
+        else
+        {
+            if( !rInf.GetFly() )
+                rInf.SetNewLine( sal_True );
+            Width(0);
+            SetAscent(0);
+            SetLen(0);
+            return bFull;
+        }
+    }
+
+
+    rInf.GetParaPortion()->SetFly( sal_True );
+    return bFull;
+}
+
+/*************************************************************************
+ *  SwTxtFrm::MoveFlyInCnt() haengt jetzt die zeichengebundenen Objekte
+ *  innerhalb des angegebenen Bereichs um, damit koennen diese vom Master
+ *  zum Follow oder umgekehrt wandern.
+ *************************************************************************/
+void SwTxtFrm::MoveFlyInCnt( SwTxtFrm *pNew, xub_StrLen nStart, xub_StrLen nEnd )
+{
+    SwDrawObjs *pObjs;
+    if ( 0 != (pObjs = GetDrawObjs()) )
+    {
+        for ( int i = 0; GetDrawObjs() && i < int(pObjs->Count()); ++i )
+        {
+            SdrObject *pO = (*pObjs)[MSHORT(i)];
+            if ( pO->IsWriterFlyFrame() )
+            {
+                SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+                if( pFly->IsFlyInCntFrm() )
+                {
+                    const SwFmtAnchor &rAnch = pFly->GetFmt()->GetAnchor();
+                    const SwPosition *pPos = rAnch.GetCntntAnchor();
+                    xub_StrLen nIdx = pPos->nContent.GetIndex();
+                    if ( nIdx >= nStart && nEnd > nIdx )
+                    {
+                        RemoveFly( pFly );
+                        pNew->AppendFly( pFly );
+                        --i;
+                    }
+                }
+            }
+            else
+            {
+                SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pO);
+                const SwFmtAnchor &rAnch = pContact->GetFmt()->GetAnchor();
+                if ( FLY_IN_CNTNT == rAnch.GetAnchorId() )
+                {
+                    const SwPosition *pPos = rAnch.GetCntntAnchor();
+                    xub_StrLen nIdx = pPos->nContent.GetIndex();
+                    if ( nIdx >= nStart && nEnd > nIdx )
+                    {
+                        RemoveDrawObj( pContact );
+                        pNew->AppendDrawObj( pContact );
+                        --i;
+                    }
+                }
+            }
+        }
+    }
+}
+
+/*************************************************************************
+ *                SwTxtFrm::CalcFlyPos()
+ *************************************************************************/
+xub_StrLen SwTxtFrm::CalcFlyPos( SwFrmFmt* pSearch )
+{
+    SwpHints* pHints = GetTxtNode()->GetpSwpHints();
+    ASSERT( pHints, "CalcFlyPos: Why me?" );
+    if( !pHints )
+        return STRING_LEN;
+    SwTxtAttr* pFound = NULL;
+    for( MSHORT i = 0; i < pHints->Count(); i++)
+    {
+        SwTxtAttr *pHt = pHints->GetHt( i );
+        if( RES_TXTATR_FLYCNT == pHt->Which() )
+        {
+            SwFrmFmt* pFrmFmt = pHt->GetFlyCnt().GetFrmFmt();
+            if( pFrmFmt == pSearch )
+                pFound = pHt;
+        }
+    }
+    ASSERT( pHints, "CalcFlyPos: Not Found!" );
+    if( !pFound )
+        return STRING_LEN;
+    return *pFound->GetStart();
+}
+
+/*************************************************************************
+ *                 virtual SwFlyCntPortion::Paint()
+ *************************************************************************/
+void SwFlyCntPortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+    if( bDraw )
+    {
+        if( !((SwDrawContact*)pContact)->GetAnchor() )
+        {
+            Point aAnchorPos =
+                ((SwDrawContact*)pContact)->GetMaster()->GetAnchorPos();
+            ((SwDrawContact*)pContact)->ConnectToLayout();
+            ((SwDrawContact*)pContact)->GetMaster()->SetAnchorPos( aAnchorPos );
+        }
+    }
+    else
+    {
+        // Baseline-Ausgabe !
+        // 7922: Bei CompletePaint alles painten
+        if( (GetFlyFrm()->IsCompletePaint() ||
+             GetFlyFrm()->Frm().IsOver( rInf.GetPaintRect() )) &&
+             SwFlyFrm::IsPaint( (SdrObject*)GetFlyFrm()->GetVirtDrawObj(),
+                                GetFlyFrm()->GetShell() ))
+        {
+            SwRect aRect( GetFlyFrm()->Frm() );
+            if( !GetFlyFrm()->IsCompletePaint() )
+                aRect._Intersection( rInf.GetPaintRect() );
+
+            GetFlyFrm()->Paint( aRect );
+            // Es hilft alles nichts, im zeichengebundenen Frame kann wer weiss
+            // was am OutputDevice eingestellt sein, wir muessen unseren Font
+            // wieder hineinselektieren. Dass wir im const stehen, soll uns
+            // daran nicht hindern:
+            ((SwTxtPaintInfo&)rInf).SelectFont();
+            rInf.SelectOut();
+        }
+    }
+}
+
+/*************************************************************************
+ *                  SwFlyCntPortion::SwFlyCntPortion()
+ *
+ * Es werden die Masze vom pFly->OutRect() eingestellt.
+ * Es erfolgt ein SetBase() !
+ *************************************************************************/
+SwFlyCntPortion::SwFlyCntPortion( SwFlyInCntFrm *pFly, const Point &rBase,
+    long nLnAscent, long nLnDescent, long nFlyAsc, long nFlyDesc, sal_Bool bQuick ) :
+    pContact( pFly ),
+    bDraw( sal_False ),
+    bMax( sal_False ),
+    nAlign( 0 )
+{
+    ASSERT( pFly, "SwFlyCntPortion::SwFlyCntPortion: no SwFlyInCntFrm!" );
+    nLineLength = 1;
+    sal_uInt8 nFlags = SETBASE_ULSPACE | SETBASE_INIT;
+    if( bQuick )
+        nFlags |= SETBASE_QUICK;
+    SetBase( rBase, nLnAscent, nLnDescent, nFlyAsc, nFlyDesc, nFlags );
+    SetWhichPor( POR_FLYCNT );
+}
+SwFlyCntPortion::SwFlyCntPortion(  SwDrawContact *pDrawContact,
+        const Point &rBase, long nLnAscent, long nLnDescent,
+        long nFlyAsc, long nFlyDesc, sal_Bool bQuick ) :
+    pContact( pDrawContact ),
+    bDraw( sal_True ),
+    bMax( sal_False ),
+    nAlign( 0 )
+{
+    ASSERT( pDrawContact, "SwFlyCntPortion::SwFlyCntPortion: no SwDrawContact!" );
+    if( !pDrawContact->GetAnchor() )
+    {
+        if( bQuick )
+        {
+            Point aAnchorPos = pDrawContact->GetMaster()->GetAnchorPos();
+            pDrawContact->ConnectToLayout();
+            pDrawContact->GetMaster()->SetAnchorPos( aAnchorPos );
+        }
+        else
+            pDrawContact->ConnectToLayout();
+    }
+    nLineLength = 1;
+    sal_uInt8 nFlags = SETBASE_ULSPACE | SETBASE_INIT;
+    if( bQuick )
+        nFlags |= SETBASE_QUICK;
+    SetBase( rBase, nLnAscent, nLnDescent, nFlyAsc, nFlyDesc, nFlags );
+    SetWhichPor( POR_FLYCNT );
+}
+
+const SwFrmFmt *SwFlyCntPortion::GetFrmFmt() const
+{
+    if( bDraw )
+        return GetDrawContact()->GetFmt();
+    else
+        return GetFlyFrm()->GetFmt();
+}
+
+/*************************************************************************
+ *                  SwFlyCntPortion::SetBase()
+ *
+ * Nach dem Setzen des RefPoints muss der Ascent neu berechnet werden,
+ * da er von der RelPos abhaengt.
+ * pFly->GetRelPos().Y() bezeichnet die relative Position zur Baseline.
+ * Bei 0 liegt der obere Rand des FlyCnt auf der Baseline der Zeile.
+ *************************************************************************/
+
+void SwFlyCntPortion::SetBase( const Point &rBase, long nLnAscent,
+    long nLnDescent, long nFlyAsc, long nFlyDesc, sal_uInt8 nFlags )
+{
+    Point aBase( rBase );
+    const SwFrmFmt* pFmt = GetFrmFmt();
+    const SwFmtVertOrient &rVert = pFmt->GetVertOrient();
+    const SwVertOrient eOri = rVert.GetVertOrient();
+    const SvxLRSpaceItem &rLRSpace = pFmt->GetLRSpace();
+    const SvxULSpaceItem &rULSpace = pFmt->GetULSpace();
+
+    //Die vertikale Position wird berechnet, die relative horizontale
+    //Position ist stets 0.
+
+    Point aRelPos;
+    SdrObject *pSdrObj;
+    SwRect aBoundRect;
+    long nOldWidth;
+    if( bDraw )
+    {
+        pSdrObj = GetDrawContact()->GetMaster();
+        aBoundRect = pSdrObj->GetBoundRect();
+    }
+    else
+    {
+        aBoundRect = GetFlyFrm()->Frm();
+        nOldWidth = aBoundRect.Width();
+    }
+
+    if( nFlags & SETBASE_ULSPACE )
+        aBase.X() += rLRSpace.GetLeft();
+    aBase.Y() += rULSpace.GetUpper();
+    if( bDraw )
+    {
+        if( nFlags & SETBASE_ULSPACE )
+            aBase.X() += pSdrObj->GetSnapRect().Left() - aBoundRect.Left();
+        aBase.Y() += pSdrObj->GetSnapRect().Top() - aBoundRect.Top();
+    }
+    aBoundRect.Left( aBoundRect.Left() - rLRSpace.GetLeft() );
+    aBoundRect.Width( aBoundRect.Width() + rLRSpace.GetRight() );
+    aBoundRect.Top( aBoundRect.Top() - rULSpace.GetUpper() );
+    aBoundRect.Height( aBoundRect.Height() + rULSpace.GetLower() );
+
+    if ( eOri == VERT_NONE )
+        aRelPos.Y() = rVert.GetPos();
+    else
+    {
+        aRelPos.Y() = 0;
+        if ( eOri == VERT_CENTER )
+            aRelPos.Y() -= aBoundRect.Height() /  2;
+        else if ( eOri == VERT_TOP )
+            aRelPos.Y() -= aBoundRect.Height();
+        else if ( eOri == VERT_BOTTOM )
+            ;
+        else if ( eOri == VERT_CHAR_CENTER )
+            aRelPos.Y() -= ( aBoundRect.Height() + nLnAscent - nLnDescent ) / 2;
+        else if ( eOri == VERT_CHAR_TOP )
+            aRelPos.Y() -= nLnAscent;
+        else if ( eOri == VERT_CHAR_BOTTOM )
+            aRelPos.Y() += nLnDescent - aBoundRect.Height();
+        else
+        {
+            if( aBoundRect.Height() >= nFlyAsc + nFlyDesc )
+            {
+                // wenn ich genauso gross bin wie die Zeile, brauche ich mich
+                // nicht an der Zeile nicht weiter ausrichten, ich lasse
+                // dann auch den max. Ascent der Zeile zunaechst unveraendert
+                aRelPos.Y() -= nFlyAsc;
+                if ( eOri == VERT_LINE_CENTER )
+                    SetAlign( 2 );
+                else if ( eOri == VERT_LINE_TOP )
+                    SetAlign( 1 );
+                else if ( eOri == VERT_LINE_BOTTOM )
+                    SetAlign( 3 );
+            }
+            else if ( eOri == VERT_LINE_CENTER )
+            {
+                aRelPos.Y() -= ( aBoundRect.Height() +nFlyAsc -nFlyDesc ) / 2;
+                SetAlign( 2 );
+            }
+            else if ( eOri == VERT_LINE_TOP )
+            {
+                aRelPos.Y() -= nFlyAsc;
+                SetAlign( 1 );
+            }
+            else if ( eOri == VERT_LINE_BOTTOM )
+            {
+                aRelPos.Y() += nFlyDesc - aBoundRect.Height();
+                SetAlign( 3 );
+            }
+        }
+    }
+
+    if( nFlags & SETBASE_INIT && aRelPos.Y() < 0 && nFlyAsc < -aRelPos.Y() )
+        aBase.Y() -= nFlyAsc + aRelPos.Y();
+
+    if( bDraw )
+    {
+        if( !( nFlags & SETBASE_QUICK ) )
+        {
+            if( rVert.GetPos() != aRelPos.Y() && eOri != VERT_NONE )
+            {
+                // Das aRelPos wird gepflegt, weil sonst SwDrawContact::_Changed
+                // auf die Idee kommen koennte, auf VERT_NONE umzuschalten.
+                SwFmtVertOrient aVert( rVert );
+                aVert.SetPos( aRelPos.Y() );
+                ((SwFrmFmt*)pFmt)->LockModify();
+                ((SwFrmFmt*)pFmt)->SetAttr( aVert );
+                ((SwFrmFmt*)pFmt)->UnlockModify();
+            }
+            Point aDiff = aRelPos + aBase - pSdrObj->GetSnapRect().TopLeft();
+            pSdrObj->ImpSetAnchorPos( aBase );
+            pSdrObj->Move( Size( aDiff.X(), aDiff.Y() ) );
+        }
+    }
+    else
+    {
+        if ( !(nFlags & SETBASE_QUICK) && (aBase != GetFlyFrm()->GetRefPoint() ||
+                         aRelPos != GetFlyFrm()->GetCurRelPos()) )
+        {
+            GetFlyFrm()->SetRefPoint( aBase, aRelPos );
+            if( nOldWidth != GetFlyFrm()->Frm().Width() )
+            {
+                aBoundRect = GetFlyFrm()->Frm();
+                aBoundRect.Left( aBoundRect.Left() - rLRSpace.GetLeft() );
+                aBoundRect.Width( aBoundRect.Width() + rLRSpace.GetRight() );
+                aBoundRect.Top( aBoundRect.Top() - rULSpace.GetUpper() );
+                aBoundRect.Height( aBoundRect.Height() + rULSpace.GetLower() );
+            }
+        }
+        ASSERT( GetFlyFrm()->Frm().Height(),
+            "SwFlyCntPortion::SetBase: flyfrm has an invalid height" );
+    }
+    aRef = aBase;
+    SvLSize( aBoundRect.SSize() );
+    if( Height() )
+    {
+        if ( aRelPos.Y() < 0 )
+        {
+            nAscent = Abs( int( aRelPos.Y() ) );
+            if( nAscent > Height() )
+                Height( nAscent );
+        }
+        else
+        {
+            nAscent = 0;
+            Height( Height() + int( aRelPos.Y() ) );
+        }
+    }
+    else
+    {
+        Height( 1 );
+        nAscent = 0;
+    }
+}
+
+/*************************************************************************
+ *              virtual SwFlyCntPortion::GetFlyCrsrOfst()
+ *************************************************************************/
+
+xub_StrLen SwFlyCntPortion::GetFlyCrsrOfst( const KSHORT nOfst,
+    const Point &rPoint, SwPosition *pPos, const SwCrsrMoveState* pCMS ) const
+{
+    // Da die FlyCnt nicht an der Seite haengen, wird ihr
+    // GetCrsrOfst() nicht gerufen. Um die Layoutseite
+    // von unnoetiger Verwaltung zu entlasten, ruft der Absatz
+    // das GetCrsrOfst des FlyFrm, wenn es erforderlich ist.
+    Point aPoint( rPoint );
+    if( !pPos || bDraw || !( GetFlyFrm()->GetCrsrOfst( pPos, aPoint, pCMS ) ) )
+        return SwLinePortion::GetCrsrOfst( nOfst );
+    else
+        return 0;
+}
+
+/*************************************************************************
+ *              virtual SwFlyCntPortion::GetCrsrOfst()
+ *************************************************************************/
+
+xub_StrLen SwFlyCntPortion::GetCrsrOfst( const KSHORT nOfst ) const
+{
+    // ASSERT( !this, "SwFlyCntPortion::GetCrsrOfst: use GetFlyCrsrOfst()" );
+    return SwLinePortion::GetCrsrOfst( nOfst );
+}
+
diff --git a/sw/source/core/text/porfly.hxx b/sw/source/core/text/porfly.hxx
new file mode 100644
index 000000000000..896741ca997a
--- /dev/null
+++ b/sw/source/core/text/porfly.hxx
@@ -0,0 +1,140 @@
+/*************************************************************************
+ *
+ *  $RCSfile: porfly.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _PORFLY_HXX
+#define _PORFLY_HXX
+
+#include "porglue.hxx"
+
+class SwDrawContact;
+class SwFrmFmt;
+class SwFlyInCntFrm;
+
+/*************************************************************************
+ *                class SwFlyPortion
+ *************************************************************************/
+
+class SwFlyPortion : public SwFixPortion
+{
+    KSHORT nBlankWidth;
+public:
+    inline  SwFlyPortion( const SwRect &rFlyRect )
+        : SwFixPortion(rFlyRect), nBlankWidth( 0 ) { SetWhichPor( POR_FLY ); }
+    inline const KSHORT GetBlankWidth( ) const { return nBlankWidth; }
+    inline void SetBlankWidth( const KSHORT nNew ) { nBlankWidth = nNew; }
+    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+    virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+#ifdef OLDRECYCLE
+    virtual sal_Bool MayRecycle() const;
+#endif
+    OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ *                class SwFlyCntPortion
+ *************************************************************************/
+
+#define SETBASE_NOFLAG  0
+#define SETBASE_QUICK   1
+#define SETBASE_ULSPACE 2
+#define SETBASE_INIT    4
+
+class SwFlyCntPortion : public SwLinePortion
+{
+    void *pContact; // bDraw ? DrawContact : FlyInCntFrm
+    Point aRef;     // Relativ zu diesem Point wird die AbsPos berechnet.
+    sal_Bool bDraw : 1;  // DrawContact?
+    sal_Bool bMax : 1;   // Zeilenausrichtung und Hoehe == Zeilenhoehe
+    sal_uInt8 nAlign : 3; // Zeilenausrichtung? Nein, oben, mitte, unten
+    virtual xub_StrLen GetCrsrOfst( const KSHORT nOfst ) const;
+
+public:
+    SwFlyCntPortion( SwFlyInCntFrm *pFly, const Point &rBase, long nAscent,
+        long nDescent, long nFlyAsc, long nFlyDesc, sal_Bool bQuick = sal_False );
+    SwFlyCntPortion( SwDrawContact *pDrawContact, const Point &rBase,
+        long nAscent, long nDescent, long nFlyAsc, long nFlyDesc,
+        sal_Bool bQuick = sal_False );
+    inline const Point& GetRefPoint() const { return aRef; }
+    inline SwFlyInCntFrm *GetFlyFrm() { return (SwFlyInCntFrm*)pContact; }
+    inline const SwFlyInCntFrm *GetFlyFrm() const
+        { return (SwFlyInCntFrm*)pContact; }
+    inline SwDrawContact *GetDrawContact() { return (SwDrawContact*)pContact; }
+    inline const SwDrawContact* GetDrawContact() const
+        { return (SwDrawContact*)pContact; }
+    inline const sal_Bool IsDraw() const { return bDraw; }
+    inline const sal_Bool IsMax() const { return bMax; }
+    inline const sal_uInt8 GetAlign() const { return nAlign; }
+    inline void SetAlign( sal_uInt8 nNew ) { nAlign = nNew; }
+    inline void SetMax( sal_Bool bNew ) { bMax = bNew; }
+    void SetBase( const Point &rBase, long nLnAscent, long nLnDescent,
+        long nFlyAscent, long nFlyDescent, sal_uInt8 nFlags );
+    const SwFrmFmt *GetFrmFmt() const;
+    xub_StrLen GetFlyCrsrOfst( const KSHORT nOfst, const Point &rPoint,
+                        SwPosition *pPos, const SwCrsrMoveState* pCMS ) const;
+    virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+    OUTPUT_OPERATOR
+};
+
+CLASSIO( SwFlyPortion )
+CLASSIO( SwFlyCntPortion )
+
+
+#endif
diff --git a/sw/source/core/text/porftn.hxx b/sw/source/core/text/porftn.hxx
new file mode 100644
index 000000000000..9c2c92597388
--- /dev/null
+++ b/sw/source/core/text/porftn.hxx
@@ -0,0 +1,150 @@
+/*************************************************************************
+ *
+ *  $RCSfile: porftn.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _PORFTN_HXX
+#define _PORFTN_HXX
+
+#include "porfld.hxx"
+
+class SwTxtFrm;
+class SwTxtFtn;
+
+/*************************************************************************
+ *                      class SwFtnPortion
+ *************************************************************************/
+
+class SwFtnPortion : public SwExpandPortion
+{
+    XubString   aExpand;
+    SwTxtFrm *pFrm;         // um im Dtor RemoveFtn rufen zu koennen.
+    SwTxtFtn *pFtn;
+    KSHORT  nOrigHeight;
+public:
+            SwFtnPortion( const XubString &rExpand, SwTxtFrm *pFrm, SwTxtFtn *pFtn,
+                          KSHORT nOrig = KSHRT_MAX );
+    void ClearFtn();
+    inline KSHORT& Orig() { return nOrigHeight; }
+
+    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+    virtual sal_Bool GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const;
+    virtual SwPosSize GetTxtSize( const SwTxtSizeInfo &rInfo ) const;
+    virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+    OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ *                      class SwFtnNumPortion
+ *************************************************************************/
+
+class SwFtnNumPortion : public SwNumberPortion
+{
+public:
+    inline SwFtnNumPortion( const XubString &rExpand, SwFont *pFnt )
+         : SwNumberPortion( rExpand, pFnt, sal_True, sal_False, 0 )
+         { SetWhichPor( POR_FTNNUM ); }
+    sal_Bool DiffFont( SwFont* pFont );
+    OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ *                      class SwQuoVadisPortion
+ *************************************************************************/
+
+class SwQuoVadisPortion : public SwFldPortion
+{
+    XubString   aErgo;
+public:
+            SwQuoVadisPortion( const XubString &rExp, const XubString& rStr );
+    virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+    virtual sal_Bool GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const;
+
+    inline void SetNumber( const XubString& rStr ) { aErgo = rStr; }
+    inline const XubString &GetQuoTxt() const { return aExpand; }
+
+    // Felder-Cloner fuer SplitGlue
+    virtual SwFldPortion *Clone( const XubString &rExpand ) const;
+
+    OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ *                      class SwErgoSumPortion
+ *************************************************************************/
+
+class SwErgoSumPortion : public SwFldPortion
+{
+public:
+            SwErgoSumPortion( const XubString &rExp, const XubString& rStr );
+    virtual xub_StrLen GetCrsrOfst( const KSHORT nOfst ) const;
+    virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+
+    // Felder-Cloner fuer SplitGlue
+    virtual SwFldPortion *Clone( const XubString &rExpand ) const;
+    OUTPUT_OPERATOR
+};
+
+CLASSIO( SwFtnPortion )
+CLASSIO( SwFtnNumPortion )
+CLASSIO( SwQuoVadisPortion )
+CLASSIO( SwErgoSumPortion )
+
+
+#endif
diff --git a/sw/source/core/text/porglue.cxx b/sw/source/core/text/porglue.cxx
new file mode 100644
index 000000000000..e83af0cafbc4
--- /dev/null
+++ b/sw/source/core/text/porglue.cxx
@@ -0,0 +1,363 @@
+/*************************************************************************
+ *
+ *  $RCSfile: porglue.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "swrect.hxx"
+#include "paratr.hxx"   // pTabStop, ADJ*
+#include "viewopt.hxx"  // SwViewOptions
+#include "errhdl.hxx"   // ASSERT
+#include "segmentc.hxx"
+
+#include "txtcfg.hxx"
+#include "porglue.hxx"
+#include "inftxt.hxx"
+#include "porlay.hxx"   // SwParaPortion, SetFull
+#include "porfly.hxx"   // SwParaPortion, SetFull
+
+/*************************************************************************
+ *                      class SwGluePortion
+ *************************************************************************/
+
+#ifdef OLDRECYCLE
+
+sal_Bool SwGluePortion::MayRecycle() const { return sal_False; }
+
+#endif
+
+SwGluePortion::SwGluePortion( const KSHORT nInitFixWidth )
+    : nFixWidth( nInitFixWidth )
+{
+    PrtWidth( nFixWidth );
+    SetWhichPor( POR_GLUE );
+}
+
+/*************************************************************************
+ *                virtual SwGluePortion::GetCrsrOfst()
+ *************************************************************************/
+
+xub_StrLen SwGluePortion::GetCrsrOfst( const KSHORT nOfst ) const
+{
+    if( !GetLen() || nOfst > GetLen() || !Width() )
+        return SwLinePortion::GetCrsrOfst( nOfst );
+    else
+        return nOfst / (Width() / GetLen());
+}
+
+/*************************************************************************
+ *                virtual SwGluePortion::GetTxtSize()
+ *************************************************************************/
+
+SwPosSize SwGluePortion::GetTxtSize( const SwTxtSizeInfo &rInf ) const
+{
+    if( 1 >= GetLen() || rInf.GetLen() > GetLen() || !Width() || !GetLen() )
+        return SwPosSize(*this);
+    else
+        return SwPosSize( (Width() / GetLen()) * rInf.GetLen(), Height() );
+}
+
+/*************************************************************************
+ *              virtual SwGluePortion::GetExpTxt()
+ *************************************************************************/
+
+sal_Bool SwGluePortion::GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const
+{
+    if( GetLen() && rInf.OnWin() &&
+        rInf.GetOpt().IsBlank() && rInf.IsNoSymbol() )
+    {
+        rTxt.Fill( GetLen(), CH_BULLET );
+        return sal_True;
+    }
+    return sal_False;
+}
+
+/*************************************************************************
+ *                virtual SwGluePortion::Paint()
+ *************************************************************************/
+
+void SwGluePortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+    if( !GetLen() )
+        return;
+
+    if( rInf.GetFont()->IsPaintBlank() )
+    {
+        XubString aTxt;
+        aTxt.Fill( GetFixWidth() / GetLen(), ' ' );
+        SwTxtPaintInfo aInf( rInf, aTxt );
+        aInf.DrawText( *this, aTxt.Len(), sal_True );
+    }
+
+    if( rInf.OnWin() && rInf.GetOpt().IsBlank() && rInf.IsNoSymbol() )
+    {
+#ifndef PRODUCT
+        const xub_Unicode cChar = rInf.GetChar( rInf.GetIdx() );
+        ASSERT( CH_BLANK  == cChar || CH_BULLET == cChar,
+                "SwGluePortion::Paint: blank expected" );
+#endif
+        if( 1 == GetLen() )
+        {
+            String aBullet( CH_BULLET, RTL_TEXTENCODING_MS_1252 );
+            SwPosSize aBulletSize( rInf.GetTxtSize( aBullet ) );
+            Point aPos( rInf.GetPos() );
+            aPos.X() += (Width()/2) - (aBulletSize.Width()/2);
+            SwTxtPaintInfo aInf( rInf, aBullet );
+            aInf.SetPos( aPos );
+            SwTxtPortion aBulletPor;
+            aBulletPor.Width( aBulletSize.Width() );
+            aBulletPor.Height( aBulletSize.Height() );
+            aBulletPor.SetAscent( GetAscent() );
+            aInf.DrawText( aBulletPor, aBullet.Len(), sal_True );
+        }
+        else
+        {
+            SwTxtSlotLen aSlot( &rInf, this );
+            rInf.DrawText( *this, rInf.GetLen(), sal_True );
+        }
+    }
+}
+
+/*************************************************************************
+ *                      SwGluePortion::MoveGlue()
+ *************************************************************************/
+
+void SwGluePortion::MoveGlue( SwGluePortion *pTarget, const short nPrtGlue )
+{
+    short nPrt = Min( nPrtGlue, GetPrtGlue() );
+    if( 0 < nPrt )
+    {
+        pTarget->AddPrtWidth( nPrt );
+        SubPrtWidth( nPrt );
+    }
+}
+
+/*************************************************************************
+ *                void SwGluePortion::Join()
+ *************************************************************************/
+
+void SwGluePortion::Join( SwGluePortion *pVictim )
+{
+    // Die GluePortion wird ausgesogen und weggespuelt ...
+    AddPrtWidth( pVictim->PrtWidth() );
+    SetLen( pVictim->GetLen() + GetLen() );
+    if( Height() < pVictim->Height() )
+        Height( pVictim->Height() );
+
+    AdjFixWidth();
+    Cut( pVictim );
+    delete pVictim;
+}
+
+/*************************************************************************
+ *                class SwFixPortion
+ *************************************************************************/
+
+// Wir erwarten ein framelokales SwRect !
+SwFixPortion::SwFixPortion( const SwRect &rRect )
+       :SwGluePortion( KSHORT(rRect.Width()) ), nFix( KSHORT(rRect.Left()) )
+{
+    Height( KSHORT(rRect.Height()) );
+    SetWhichPor( POR_FIX );
+}
+
+SwFixPortion::SwFixPortion(const KSHORT nFixWidth, const KSHORT nFixPos)
+       : SwGluePortion(nFixWidth), nFix(nFixPos)
+{
+    SetWhichPor( POR_FIX );
+}
+
+/*************************************************************************
+ *                class SwMarginPortion
+ *************************************************************************/
+
+SwMarginPortion::SwMarginPortion( const KSHORT nFixWidth )
+    :SwGluePortion( nFixWidth )
+{
+    SetWhichPor( POR_MARGIN );
+}
+
+#ifdef OLDRECYCLE
+
+sal_Bool SwMarginPortion::MayRecycle() const { return sal_False; }
+
+#endif
+
+/*************************************************************************
+ *                SwMarginPortion::AdjustRight()
+ *
+ * In der umschliessenden Schleife werden alle Portions durchsucht,
+ * dabei werden erst die am Ende liegenden GluePortions verarbeitet.
+ * Das Ende wird nach jeder Schleife nach vorne verlegt, bis keine
+ * GluePortions mehr vorhanden sind.
+ * Es werden immer GluePortion-Paare betrachtet (pLeft und pRight),
+ * wobei Textportions zwischen pLeft und pRight hinter pRight verschoben
+ * werden, wenn pRight genuegend Glue besitzt. Bei jeder Verschiebung
+ * wandert ein Teil des Glues von pRight nach pLeft.
+ * Im naechsten Schleifendurchlauf ist pLeft das pRight und das Spiel
+ * beginnt von vorne.
+ *************************************************************************/
+
+void SwMarginPortion::AdjustRight()
+{
+    SwGluePortion *pRight = 0;
+    while( pRight != this )
+    {
+
+        // 1) Wir suchen den linken Glue
+        SwLinePortion *pPos = (SwLinePortion*)this;
+        SwGluePortion *pLeft = 0;
+        while( pPos )
+        {
+            DBG_LOOP;
+            if( pPos->InFixMargGrp() )
+                pLeft = (SwGluePortion*)pPos;
+            pPos = pPos->GetPortion();
+            if( pPos == pRight)
+                pPos = 0;
+        }
+
+        // Zwei nebeneinander liegende FlyPortions verschmelzen
+        if( pRight && pLeft->GetPortion() == pRight )
+        {
+            pRight->MoveAllGlue( pLeft );
+            pRight = 0;
+        }
+        KSHORT nRightGlue = pRight && 0 < pRight->GetPrtGlue()
+                          ? KSHORT(pRight->GetPrtGlue()) : 0;
+        // 2) linken und rechten Glue ausgleichen
+        //    Bei Tabs haengen wir nix um ...
+        if( pLeft && nRightGlue && !pRight->InTabGrp() )
+        {
+            // pPrev ist die Portion, die unmittelbar vor pRight liegt.
+            SwLinePortion *pPrev = pRight->FindPrevPortion( pLeft );
+
+            if ( pRight->IsFlyPortion() && pRight->GetLen() )
+            {
+                SwFlyPortion *pFly = (SwFlyPortion *)pRight;
+                if ( pFly->GetBlankWidth() < nRightGlue )
+                {
+                    // Hier entsteht eine neue TxtPortion, die dass zuvor
+                    // vom Fly verschluckte Blank reaktiviert.
+                    nRightGlue -= pFly->GetBlankWidth();
+                    pFly->SubPrtWidth( pFly->GetBlankWidth() );
+                    pFly->SetLen( 0 );
+                    SwTxtPortion *pNewPor = new SwTxtPortion;
+                    pNewPor->SetLen( 1 );
+                    pNewPor->Height( pFly->Height() );
+                    pNewPor->Width( pFly->GetBlankWidth() );
+                    pFly->Insert( pNewPor );
+                }
+                else
+                    pPrev = pLeft;
+            }
+            while( pPrev != pLeft )
+            {
+                DBG_LOOP;
+
+                if( pPrev->PrtWidth() >= nRightGlue || pPrev->InHyphGrp() )
+                {
+                    // Die Portion, die vor pRight liegt kann nicht
+                    // verschoben werden, weil kein Glue mehr vorhanden ist.
+                    // Wir fuehren die Abbruchbedingung herbei:
+                    pPrev = pLeft;
+                }
+                else
+                {
+                    nRightGlue -= pPrev->PrtWidth();
+                    // pPrev wird hinter pRight verschoben.
+                    // Dazu wird der Gluewert zwischen pRight und pLeft
+                    // ausgeglichen.
+                    pRight->MoveGlue( pLeft, short( pPrev->PrtWidth() ) );
+                    // Jetzt wird die Verkettung gerichtet.
+                    SwLinePortion *pPrevPrev = pPrev->FindPrevPortion( pLeft );
+                    pPrevPrev->SetPortion( pRight );
+                    pPrev->SetPortion( pRight->GetPortion() );
+                    pRight->SetPortion( pPrev );
+                    if ( pPrev->GetPortion() && pPrev->InTxtGrp()
+                         && pPrev->GetPortion()->IsHolePortion() )
+                    {
+                        SwHolePortion *pHolePor =
+                            (SwHolePortion*)pPrev->GetPortion();
+                        if ( !pHolePor->GetPortion() ||
+                             !pHolePor->GetPortion()->InFixMargGrp() )
+                        {
+                            pPrev->AddPrtWidth( pHolePor->GetBlankWidth() );
+                            pPrev->SetLen( pPrev->GetLen() + 1 );
+                            pPrev->SetPortion( pHolePor->GetPortion() );
+                            delete pHolePor;
+                        }
+                    }
+                    pPrev = pPrevPrev;
+                }
+            }
+        }
+        // Wenn es keinen linken Glue mehr gibt, wird die Abbruchbedingung
+        // herbeigefuehrt.
+        pRight = pLeft ? pLeft : (SwGluePortion*)this;
+    }
+}
+
+
+
diff --git a/sw/source/core/text/porglue.hxx b/sw/source/core/text/porglue.hxx
new file mode 100644
index 000000000000..8a2e0753c0cc
--- /dev/null
+++ b/sw/source/core/text/porglue.hxx
@@ -0,0 +1,174 @@
+/*************************************************************************
+ *
+ *  $RCSfile: porglue.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _PORGLUE_HXX
+#define _PORGLUE_HXX
+
+
+//#include 
+
+#include "porlin.hxx"
+
+class SwRect;
+struct SwPosition;
+
+/*************************************************************************
+ *                      class SwGluePortion
+ *************************************************************************/
+
+class SwGluePortion : public SwLinePortion
+{
+private:
+    KSHORT nFixWidth;
+public:
+                SwGluePortion( const KSHORT nInitFixWidth );
+
+    void Join( SwGluePortion *pVictim );
+
+    inline short GetPrtGlue() const;
+    inline KSHORT GetFixWidth() const { return nFixWidth; }
+    inline void SetFixWidth( const KSHORT nNew ) { nFixWidth = nNew; }
+    void MoveGlue( SwGluePortion *pTarget, const short nPrtGlue );
+    inline void MoveAllGlue( SwGluePortion *pTarget );
+    inline void MoveHalfGlue( SwGluePortion *pTarget );
+    inline void AdjFixWidth();
+#ifdef OLDRECYCLE
+    virtual sal_Bool MayRecycle() const;
+#endif
+    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+    virtual xub_StrLen GetCrsrOfst( const KSHORT nOfst ) const;
+    virtual SwPosSize GetTxtSize( const SwTxtSizeInfo &rInfo ) const;
+    virtual sal_Bool GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const;
+    OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ *                      class SwFixPortion
+ *************************************************************************/
+
+class SwFixPortion : public SwGluePortion
+{
+    KSHORT nFix;        // der Width-Offset in der Zeile
+public:
+        SwFixPortion( const SwRect &rFlyRect );
+        SwFixPortion( const KSHORT nFixWidth, const KSHORT nFixPos );
+    inline void   Fix( const KSHORT nNewFix ) { nFix = nNewFix; }
+    inline KSHORT Fix() const { return nFix; }
+    OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ *                class SwMarginPortion
+ *************************************************************************/
+
+class SwMarginPortion : public SwGluePortion
+{
+public:
+        SwMarginPortion( const KSHORT nFixWidth );
+        void AdjustRight();
+#ifdef OLDRECYCLE
+    virtual sal_Bool MayRecycle() const;
+#endif
+    OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ *                inline SwGluePortion::GetPrtGlue()
+ *************************************************************************/
+
+inline short SwGluePortion::GetPrtGlue() const
+{ return Width() - nFixWidth; }
+
+/*************************************************************************
+ *              inline SwGluePortion::AdjFixWidth()
+ * Die FixWidth darf niemals groesser sein als die Gesamtbreite !
+ *************************************************************************/
+
+inline void SwGluePortion::AdjFixWidth()
+{
+    if( nFixWidth > PrtWidth() )
+        nFixWidth = PrtWidth();
+}
+
+/*************************************************************************
+ *                 inline SwGluePortion::MoveGlue()
+ *************************************************************************/
+
+inline void SwGluePortion::MoveAllGlue( SwGluePortion *pTarget )
+{
+    MoveGlue( pTarget, GetPrtGlue() );
+}
+
+/*************************************************************************
+ *                inline SwGluePortion::MoveHalfGlue()
+ *************************************************************************/
+
+inline void SwGluePortion::MoveHalfGlue( SwGluePortion *pTarget )
+{
+    MoveGlue( pTarget, GetPrtGlue() / 2 );
+}
+
+CLASSIO( SwGluePortion )
+CLASSIO( SwFixPortion )
+CLASSIO( SwMarginPortion )
+
+
+#endif
+
diff --git a/sw/source/core/text/porhyph.hxx b/sw/source/core/text/porhyph.hxx
new file mode 100644
index 000000000000..474a261edb81
--- /dev/null
+++ b/sw/source/core/text/porhyph.hxx
@@ -0,0 +1,141 @@
+/*************************************************************************
+ *
+ *  $RCSfile: porhyph.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _PORHYPH_HXX
+#define _PORHYPH_HXX
+
+#include "porexp.hxx"
+
+/*************************************************************************
+ *                      class SwHyphPortion
+ *************************************************************************/
+
+class SwHyphPortion : public SwExpandPortion
+{
+public:
+    inline  SwHyphPortion( ) { SetWhichPor( POR_HYPH ); }
+    virtual sal_Bool GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const;
+    virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+    OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ *                      class SwHyphStrPortion
+ *************************************************************************/
+
+class SwHyphStrPortion : public SwHyphPortion
+{
+    XubString aExpand;
+public:
+    inline  SwHyphStrPortion( const XubString &rStr );
+    virtual sal_Bool GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const;
+    OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ *                      class SwSoftHyphPortion
+ *************************************************************************/
+
+class SwSoftHyphPortion : public SwHyphPortion
+{
+    sal_Bool    bExpand;
+    KSHORT  nViewWidth;
+    KSHORT  nHyphWidth;
+
+public:
+    SwSoftHyphPortion();
+    virtual sal_Bool GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const;
+    virtual SwLinePortion *Compress();
+    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+    virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+    virtual void FormatEOL( SwTxtFormatInfo &rInf );
+    inline void SetExpand( const sal_Bool bNew ) { bExpand = bNew; }
+    sal_Bool IsExpand() const { return bExpand; }
+
+    virtual KSHORT GetViewWidth( const SwTxtSizeInfo &rInf ) const;
+    OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ *                      class SwSoftHyphStrPortion
+ *************************************************************************/
+
+class SwSoftHyphStrPortion : public SwHyphStrPortion
+{
+public:
+    SwSoftHyphStrPortion( const XubString &rStr );
+    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+    OUTPUT_OPERATOR
+};
+
+inline  SwHyphStrPortion::SwHyphStrPortion( const XubString &rStr )
+        : aExpand( rStr )
+{
+    aExpand += '-';
+    SetWhichPor( POR_HYPHSTR );
+}
+
+CLASSIO( SwHyphPortion )
+CLASSIO( SwHyphStrPortion )
+CLASSIO( SwSoftHyphPortion )
+CLASSIO( SwSoftHyphStrPortion )
+
+
+#endif
diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx
new file mode 100644
index 000000000000..1742b744fa55
--- /dev/null
+++ b/sw/source/core/text/porlay.cxx
@@ -0,0 +1,504 @@
+/*************************************************************************
+ *
+ *  $RCSfile: porlay.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "errhdl.hxx"   // ASSERT
+
+#include "txtcfg.hxx"
+#include "porlay.hxx"
+#include "itrform2.hxx"
+#include "porglue.hxx"
+#include "porexp.hxx"   // SwQuoVadisPortion
+#include "blink.hxx"    // pBlink
+#include "redlnitr.hxx" // SwRedlineItr
+#include "porfly.hxx"   // SwFlyCntPortion
+
+
+/*************************************************************************
+ *                 SwLineLayout::~SwLineLayout()
+ *
+ * class SwLineLayout: Das Layout einer einzelnen Zeile. Dazu
+ * gehoeren vor allen Dingen die Dimension, die Anzahl der
+ * Character und der Wortzwischenraeume in der Zeile.
+ * Zeilenobjekte werden in einem eigenen Pool verwaltet, um zu
+ * erreichen, dass sie im Speicher moeglichst beeinander liegen
+ * (d.h. zusammen gepaged werden und den Speicher nicht
+ * fragmentieren).
+ *************************************************************************/
+
+SwLineLayout::~SwLineLayout()
+{
+    Truncate();
+    if( GetNext() )
+        delete GetNext();
+    if( pBlink )
+        pBlink->Delete( this );
+    delete pSpaceAdd;
+}
+
+/*************************************************************************
+ *                virtual SwLineLayout::Insert()
+ *************************************************************************/
+
+SwLinePortion *SwLineLayout::Insert( SwLinePortion *pIns )
+{
+    // Erster Attributwechsel, Masse und Laengen
+    // aus *pCurr in die erste Textportion kopieren.
+    if( !pPortion )
+    {
+        if( GetLen() )
+        {
+            pPortion = new SwTxtPortion( *(SwLinePortion*)this );
+            if( IsBlinking() && pBlink )
+            {
+                SetBlinking( sal_False );
+                pBlink->Replace( this, pPortion );
+            }
+        }
+        else
+        {
+            SetPortion( pIns );
+            return pIns;
+        }
+    }
+    // mit Skope aufrufen, sonst Rekursion !
+    return pPortion->SwLinePortion::Insert( pIns );
+}
+
+/*************************************************************************
+ *                virtual SwLineLayout::Append()
+ *************************************************************************/
+
+SwLinePortion *SwLineLayout::Append( SwLinePortion *pIns )
+{
+    // Erster Attributwechsel, Masse und Laengen
+    // aus *pCurr in die erste Textportion kopieren.
+    if( !pPortion )
+        pPortion = new SwTxtPortion( *(SwLinePortion*)this );
+    // mit Skope aufrufen, sonst Rekursion !
+    return pPortion->SwLinePortion::Append( pIns );
+}
+
+/*************************************************************************
+ *                virtual SwLineLayout::Format()
+ *************************************************************************/
+
+// fuer die Sonderbehandlung bei leeren Zeilen
+
+sal_Bool SwLineLayout::Format( SwTxtFormatInfo &rInf )
+{
+    if( GetLen() )
+        return SwTxtPortion::Format( rInf );
+    else
+    {
+        Height( rInf.GetTxtHeight() );
+        return sal_True;
+    }
+}
+
+/*************************************************************************
+ *                    SwLineLayout::CalcLeftMargin()
+ *
+ * Wir sammeln alle FlyPortions am Anfang der Zeile zu einer MarginPortion.
+ *************************************************************************/
+
+SwMarginPortion *SwLineLayout::CalcLeftMargin()
+{
+    SwMarginPortion *pLeft = (GetPortion() && GetPortion()->IsMarginPortion()) ?
+        (SwMarginPortion *)GetPortion() : 0;
+    if( !GetPortion() )
+         SetPortion( new SwTxtPortion( *(SwLinePortion*)this ) );
+    if( !pLeft )
+    {
+        pLeft = new SwMarginPortion( 0 );
+        pLeft->SetPortion( GetPortion() );
+        SetPortion( pLeft );
+    }
+    else
+    {
+        pLeft->Height( 0 );
+        pLeft->Width( 0 );
+        pLeft->SetLen( 0 );
+        pLeft->SetAscent( 0 );
+        pLeft->SetPortion( NULL );
+        pLeft->SetFixWidth(0);
+    }
+
+    SwLinePortion *pPos = pLeft->GetPortion();
+    while( pPos )
+    {
+        DBG_LOOP;
+        if( pPos->IsFlyPortion() )
+        {
+            // Die FlyPortion wird ausgesogen ...
+            pLeft->Join( (SwGluePortion*)pPos );
+            pPos = pLeft->GetPortion();
+        }
+        else
+            pPos = 0;
+    }
+    return pLeft;
+}
+
+/*************************************************************************
+ *                    SwLineLayout::CreateSpaceAdd()
+ *************************************************************************/
+
+void SwLineLayout::CreateSpaceAdd()
+{
+    MSHORT nNull = 0;
+    pSpaceAdd = new SvShorts;
+    pSpaceAdd->Insert( nNull, 0 );
+}
+
+/*************************************************************************
+ *                    SwLineLayout::CalcLine()
+ *
+ * Aus FormatLine() ausgelagert.
+ *************************************************************************/
+
+void SwLineLayout::CalcLine( SwTxtFormatter &rLine )
+{
+    SwTxtFormatInfo &rInf = rLine.GetInfo();
+    const KSHORT nLineWidth = rInf.RealWidth();
+
+    KSHORT nFlyAscent;
+    KSHORT nFlyHeight;
+    KSHORT nFlyDescent;
+    sal_Bool bOnlyPostIts = sal_True;
+
+    sal_Bool bTmpDummy = ( 0 == GetLen() );
+    SwFlyCntPortion* pFlyCnt = 0;
+    if( bTmpDummy )
+    {
+        nFlyAscent = 0;
+        nFlyHeight = 0;
+        nFlyDescent = 0;
+    }
+
+    if( pPortion )
+    {
+        SetCntnt( sal_False );
+        if( pPortion->IsBreakPortion() )
+        {
+            SetLen( pPortion->GetLen() );
+            if( GetLen() )
+                bTmpDummy = sal_False;
+        }
+        else
+        {
+            Init( GetPortion() );
+            SwLinePortion *pPos = pPortion;
+            SwLinePortion *pLast = this;
+            KSHORT nMaxDescent = 0;
+
+            //  Eine Gruppe ist ein Abschnitt in der Portion-Kette von
+            //  pCurr oder einer Fix-Portion bis zum Ende bzw. zur naechsten
+            //  Fix-Portion.
+            while( pPos )
+            {
+                DBG_LOOP;
+                ASSERT( POR_LIN != pPos->GetWhichPor(),
+                        "SwLineLayout::CalcLine: don't use SwLinePortions !" );
+                // Null-Portions werden eliminiert. Sie koennen entstehen,
+                // wenn zwei FlyFrms ueberlappen.
+                if( !pPos->Compress() )
+                {
+                    // 8110: Hoehe und Ascent nur uebernehmen, wenn sonst in der
+                    // Zeile nichts mehr los ist.
+                    if( !pPos->GetPortion() )
+                    {
+                        if( !Height() )
+                            Height( pPos->Height() );
+                        if( !GetAscent() )
+                            SetAscent( pPos->GetAscent() );
+                    }
+                    delete pLast->Cut( pPos );
+                    pPos = pLast->GetPortion();
+                    continue;
+                }
+
+                // Es gab Attributwechsel: Laengen und Masse aufaddieren;
+                // bzw.Maxima bilden.
+
+                nLineLength += pPos->GetLen();
+                KSHORT nPosHeight = pPos->Height();
+                KSHORT nPosAscent = pPos->GetAscent();
+
+                AddPrtWidth( pPos->Width() );
+
+                ASSERT( nPosHeight >= nPosAscent,
+                        "SwLineLayout::CalcLine: bad ascent or height" );
+
+
+                // Damit ein Paragraphende-Zeichen nicht durch ein Descent zu einer
+                // geaenderten Zeilenhoehe und zum Umformatieren fuehrt.
+                if ( !pPos->IsBreakPortion() || !Height() )
+                {
+                    bOnlyPostIts &= pPos->IsPostItsPortion();
+                    if( bTmpDummy && !nLineLength )
+                    {
+                        if( pPos->IsFlyPortion() )
+                        {
+                            if( nFlyHeight < nPosHeight )
+                                nFlyHeight = nPosHeight;
+                            if( nFlyAscent < nPosAscent )
+                                nFlyAscent = nPosAscent;
+                            if( nFlyDescent < nPosHeight - nPosAscent )
+                                nFlyDescent = nPosHeight - nPosAscent;
+                        }
+                        else
+                        {
+                            if( pPos->InNumberGrp() )
+                            {
+                                KSHORT nTmp = rInf.GetFont()->GetAscent(
+                                                rInf.GetVsh(), rInf.GetOut() );
+                                if( nTmp > nPosAscent )
+                                {
+                                    nPosHeight += nTmp - nPosAscent;
+                                    nPosAscent = nTmp;
+                                }
+                                nTmp = rInf.GetFont()->GetHeight( rInf.GetVsh(),
+                                                                rInf.GetOut() );
+                                if( nTmp > nPosHeight )
+                                    nPosHeight = nTmp;
+                            }
+                            Height( nPosHeight );
+                            nAscent = nPosAscent;
+                            nMaxDescent = nPosHeight - nPosAscent;
+                        }
+                    }
+                    else if( !pPos->IsFlyPortion() )
+                    {
+                        if( Height() < nPosHeight )
+                            Height( nPosHeight );
+                        if( pPos->IsFlyCntPortion() )
+                            rLine.SetFlyInCntBase();
+                        if( pPos->IsFlyCntPortion() &&
+                            ((SwFlyCntPortion*)pPos)->GetAlign() )
+                        {
+                            ((SwFlyCntPortion*)pPos)->SetMax( sal_False );
+                            if( !pFlyCnt || pPos->Height() > pFlyCnt->Height() )
+                                pFlyCnt = (SwFlyCntPortion*)pPos;
+                        }
+                        else
+                        {
+                            if( nAscent < nPosAscent )
+                                nAscent = nPosAscent;
+                            if( nMaxDescent < nPosHeight - nPosAscent )
+                                nMaxDescent = nPosHeight - nPosAscent;
+                        }
+                    }
+                }
+                else if( pPos->GetLen() )
+                    bTmpDummy = sal_False;
+                if( !HasCntnt() && !pPos->InNumberGrp() )
+                {
+                    if ( pPos->InExpGrp() )
+                    {
+                        XubString aTxt;
+                        if( pPos->GetExpTxt( rInf, aTxt ) && aTxt.Len() )
+                            SetCntnt( sal_True );
+                    }
+                    else if( pPos->InTxtGrp() && pPos->GetLen() )
+                        SetCntnt( sal_True );
+                }
+                bTmpDummy = bTmpDummy && !HasCntnt() &&
+                            ( !pPos->Width() || pPos->IsFlyPortion() );
+
+                pLast = pPos;
+                pPos = pPos->GetPortion();
+            }
+            if( pFlyCnt )
+            {
+                if( pFlyCnt->Height() == Height() )
+                {
+                    pFlyCnt->SetMax( sal_True );
+                    if( Height() > nMaxDescent + nAscent )
+                    {
+                        if( 3 == pFlyCnt->GetAlign() ) // Bottom
+                            nAscent = Height() - nMaxDescent;
+                        else if( 2 == pFlyCnt->GetAlign() ) // Center
+                            nAscent = ( Height() + nAscent - nMaxDescent ) / 2;
+                    }
+                    pFlyCnt->SetAscent( nAscent );
+                }
+            }
+            if( bTmpDummy && nFlyHeight )
+            {
+                nAscent = nFlyAscent;
+                if( nFlyDescent > nFlyHeight - nFlyAscent )
+                    Height( nFlyHeight + nFlyDescent );
+                else
+                    Height( nFlyHeight );
+            }
+            else if( nMaxDescent > Height() - nAscent )
+                Height( nMaxDescent + nAscent );
+            if( bOnlyPostIts )
+            {
+                Height( rInf.GetFont()->GetHeight( rInf.GetVsh(), rInf.GetOut() ) );
+                nAscent = rInf.GetFont()->GetAscent( rInf.GetVsh(), rInf.GetOut() );
+            }
+        }
+    }
+    else
+        SetCntnt( !bTmpDummy );
+    // Robust:
+    if( nLineWidth < Width() )
+        Width( nLineWidth );
+    ASSERT( nLineWidth >= Width(), "SwLineLayout::CalcLine: line is bursting" );
+    SetDummy( bTmpDummy );
+    SetRedline( rLine.GetRedln() &&
+        rLine.GetRedln()->CheckLine( rLine.GetStart(), rLine.GetEnd() ) );
+}
+
+/*************************************************************************
+ *                      class SwCharRange
+ *************************************************************************/
+
+SwCharRange &SwCharRange::operator+=(const SwCharRange &rRange)
+{
+    if(0 != rRange.nLen ) {
+        if(0 == nLen) {
+            nStart = rRange.nStart;
+            nLen = rRange.nLen ;
+        }
+        else {
+            if(rRange.nStart + rRange.nLen > nStart + nLen) {
+                nLen = rRange.nStart + rRange.nLen - nStart;
+            }
+            if(rRange.nStart < nStart) {
+                nLen += nStart - rRange.nStart;
+                nStart = rRange.nStart;
+            }
+        }
+    }
+    return *this;
+}
+
+/*************************************************************************
+ *                      class SwParaPortion
+ *************************************************************************/
+
+SwParaPortion::SwParaPortion()
+{
+    FormatReset();
+    bFlys = bFtnNum = sal_False;
+    SetWhichPor( POR_PARA );
+}
+
+/*************************************************************************
+ *                      SwParaPortion::GetParLen()
+ *************************************************************************/
+
+xub_StrLen SwParaPortion::GetParLen() const
+{
+    xub_StrLen nLen = 0;
+    const SwLineLayout *pLay = this;
+    while( pLay )
+    {
+        DBG_LOOP;
+        nLen += pLay->GetLen();
+        pLay = pLay->GetNext();
+    }
+    return nLen;
+}
+
+/*************************************************************************
+ *                      SwParaPortion::FindDropPortion()
+ *************************************************************************/
+
+const SwDropPortion *SwParaPortion::FindDropPortion() const
+{
+    const SwLineLayout *pLay = this;
+    while( pLay && pLay->IsDummy() )
+        pLay = pLay->GetNext();
+    while( pLay )
+    {
+        const SwLinePortion *pPos = pLay->GetPortion();
+        while ( pPos && !pPos->GetLen() )
+            pPos = pPos->GetPortion();
+        if( pPos && pPos->IsDropPortion() )
+            return (SwDropPortion *)pPos;
+        pLay = pLay->GetLen() ? NULL : pLay->GetNext();
+    }
+    return NULL;
+}
+
+/*************************************************************************
+ *                      SwLineLayout::Init()
+ *************************************************************************/
+
+void SwLineLayout::Init( SwLinePortion* pNextPortion )
+{
+    Height( 0 );
+    Width( 0 );
+    SetLen( 0 );
+    SetAscent( 0 );
+    SetPortion( pNextPortion );
+}
+
+
diff --git a/sw/source/core/text/porlay.hxx b/sw/source/core/text/porlay.hxx
new file mode 100644
index 000000000000..bbc6fc35cb85
--- /dev/null
+++ b/sw/source/core/text/porlay.hxx
@@ -0,0 +1,390 @@
+/*************************************************************************
+ *
+ *  $RCSfile: porlay.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _PORLAY_HXX
+#define _PORLAY_HXX
+
+#ifndef _SVSTDARR_HXX
+#define _SVSTDARR_SHORTS
+#include 
+#endif
+#ifndef _STRING_HXX //autogen
+#include 
+#endif
+
+#include "swrect.hxx"   // SwRepaint
+#include "portxt.hxx"
+
+class SwMarginPortion;
+class SwDropPortion;
+class SvStream;
+class SvUShorts;
+class SwTxtFormatter;
+
+/*************************************************************************
+ *                      class SwCharRange
+ *************************************************************************/
+
+class SwCharRange
+{
+    xub_StrLen nStart, nLen;
+public:
+    inline SwCharRange( const xub_StrLen nInitStart = 0,
+        const xub_StrLen nInitLen = 0): nStart( nInitStart ), nLen(nInitLen) {}
+    inline xub_StrLen &Start() { return nStart; }
+    inline const xub_StrLen &Start() const { return nStart; }
+    inline void LeftMove( xub_StrLen nNew )
+            { if ( nNew < nStart ) { nLen += nStart-nNew; nStart = nNew; } }
+    inline xub_StrLen End() const
+                { return nStart + nLen; }
+    inline xub_StrLen &Len() { return nLen; }
+    inline const xub_StrLen &Len() const { return nLen; }
+    inline sal_Bool operator<(const SwCharRange &rRange) const
+                { return nStart < rRange.nStart; }
+    inline sal_Bool operator>(const SwCharRange &rRange) const
+                { return nStart + nLen > rRange.nStart + rRange.nLen; }
+    inline sal_Bool operator!=(const SwCharRange &rRange) const
+                { return *this < rRange || *this > rRange; }
+    SwCharRange &operator+=(const SwCharRange &rRange);
+};
+
+/*************************************************************************
+ *                      class SwRepaint
+ *************************************************************************/
+
+// SwRepaint ist ein dokumentglobales SwRect mit einem nOfst der angibt,
+// ab wo in der ersten Zeile gepaintet werden soll
+// und einem nRightOfst, der den rechten Rand bestimmt
+class SwRepaint : public SwRect
+{
+    SwTwips nOfst;
+    SwTwips nRightOfst;
+public:
+    SwRepaint() : SwRect(), nOfst( 0 ), nRightOfst( 0 ) {}
+    SwRepaint( const SwRepaint& rRep ) : SwRect( rRep ), nOfst( rRep.nOfst ),
+        nRightOfst( rRep.nRightOfst ) {}
+
+    SwTwips GetOfst() const { return nOfst; }
+    void   SetOfst( const SwTwips nNew ) { nOfst = nNew; }
+    SwTwips GetRightOfst() const { return nRightOfst; }
+    void   SetRightOfst( const SwTwips nNew ) { nRightOfst = nNew; }
+};
+
+/*************************************************************************
+ *                      class SwLineLayout
+ *************************************************************************/
+
+class SwLineLayout : public SwTxtPortion
+{
+private:
+    SwLineLayout *pNext;// Die naechste Zeile.
+    SvShorts *pSpaceAdd;// Fuer den Blocksatz
+    KSHORT nRealHeight; // Die aus Zeilenabstand/Register resultierende Hoehe
+    sal_Bool bFormatAdj : 1;
+    sal_Bool bDummy     : 1;
+    sal_Bool bFntChg    : 1;
+    sal_Bool bEndHyph   : 1;
+    sal_Bool bMidHyph   : 1;
+    sal_Bool bTab       : 1;
+    sal_Bool bFly       : 1;
+    sal_Bool bFlyCnt    : 1;
+    sal_Bool bRest      : 1;
+    sal_Bool bBlinking  : 1;
+    sal_Bool bClipping  : 1; // Clipping erforderlich wg. exakter Zeilenhoehe
+    sal_Bool bContent   : 1; // enthaelt Text, fuer Zeilennumerierung
+    sal_Bool bRedline   : 1; // enthaelt Redlining
+    sal_Bool bForcedLeftMargin : 1; // vom Fly verschobener linker Einzug
+
+public:
+    // von SwLinePortion
+    virtual SwLinePortion *Insert( SwLinePortion *pPortion );
+    virtual SwLinePortion *Append( SwLinePortion *pPortion );
+    inline SwLinePortion *GetFirstPortion() const;
+
+    // Flags
+    inline void ResetFlags();
+    inline void SetFormatAdj( const sal_Bool bNew ) { bFormatAdj = bNew; }
+    inline sal_Bool IsFormatAdj() const { return bFormatAdj; }
+    inline void SetFntChg( const sal_Bool bNew ) { bFntChg = bNew; }
+    inline sal_Bool IsFntChg() const { return bFntChg; }
+    inline void SetEndHyph( const sal_Bool bNew ) { bEndHyph = bNew; }
+    inline sal_Bool IsEndHyph() const { return bEndHyph; }
+    inline void SetMidHyph( const sal_Bool bNew ) { bMidHyph = bNew; }
+    inline sal_Bool IsMidHyph() const { return bMidHyph; }
+    inline void SetTab( const sal_Bool bNew ) { bTab = bNew; }
+    inline sal_Bool IsTab() const { return bTab; }
+    inline void SetFly( const sal_Bool bNew ) { bFly = bNew; }
+    inline sal_Bool IsFly() const { return bFly; }
+    inline void SetFlyCnt( const sal_Bool bNew ) { bFlyCnt = bNew; }
+    inline sal_Bool IsFlyCnt() const { return bFlyCnt; }
+    inline void SetRest( const sal_Bool bNew ) { bRest = bNew; }
+    inline sal_Bool IsRest() const { return bRest; }
+    inline void SetBlinking( const sal_Bool bNew = sal_True ) { bBlinking = bNew; }
+    inline sal_Bool IsBlinking() const { return bBlinking; }
+    inline void SetCntnt( const sal_Bool bNew = sal_True ) { bContent = bNew; }
+    inline sal_Bool HasCntnt() const { return bContent; }
+    inline void SetRedline( const sal_Bool bNew = sal_True ) { bRedline = bNew; }
+    inline sal_Bool HasRedline() const { return bRedline; }
+    inline void SetForcedLeftMargin( const sal_Bool bNew = sal_True ) { bForcedLeftMargin = bNew; }
+    inline sal_Bool HasForcedLeftMargin() const { return bForcedLeftMargin; }
+
+    // Beruecksichtigung von Dummyleerzeilen
+    // 4147, 8221:
+    inline void SetDummy( const sal_Bool bNew ) { bDummy = bNew; }
+    inline sal_Bool IsDummy() const { return bDummy; }
+
+    inline void SetClipping( const sal_Bool bNew ) { bClipping = bNew; }
+    inline sal_Bool IsClipping() const { return bClipping; }
+
+    inline SwLineLayout();
+    virtual ~SwLineLayout();
+
+    inline SwLineLayout *GetNext() { return pNext; }
+    inline const SwLineLayout *GetNext() const { return pNext; }
+    inline void SetNext( SwLineLayout *pNew ) { pNext = pNew; }
+
+    void Init( SwLinePortion *pNextPortion = NULL);
+
+    // Sammelt die Daten fuer die Zeile.
+    void CalcLine( SwTxtFormatter &rLine );
+
+    inline void SetRealHeight( KSHORT nNew ) { nRealHeight = nNew; }
+    inline KSHORT GetRealHeight() const { return nRealHeight; }
+
+    // Erstellt bei kurzen Zeilen die Glue-Kette.
+    SwMarginPortion *CalcLeftMargin();
+
+    // fuer die Sonderbehandlung bei leeren Zeilen
+    virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+
+    inline sal_Bool IsNoSpaceAdd() { return pSpaceAdd == NULL; }
+    inline void InitSpaceAdd()
+    { if ( !pSpaceAdd ) CreateSpaceAdd(); else (*pSpaceAdd)[0] = 0; }
+    inline void FinishSpaceAdd() { delete pSpaceAdd; pSpaceAdd = NULL; }
+    inline SvShorts* GetpSpaceAdd() const { return pSpaceAdd; }
+    inline SvShorts &GetSpaceAdd() { return *pSpaceAdd; }
+    void CreateSpaceAdd();
+
+#ifndef PRODUCT
+    void DebugPortions( SvStream &rOs, const XubString &rTxt,
+                        const xub_StrLen nStart ); //$ ostream
+#endif
+
+    OUTPUT_OPERATOR
+    DECL_FIXEDMEMPOOL_NEWDEL(SwLineLayout)
+};
+
+class SwParaPortion : public SwLineLayout
+{
+    // neu zu paintender Bereich
+    SwRepaint aRepaint;
+    // neu zu formatierender Bereich
+    SwCharRange aReformat;
+    long nDelta;
+
+    // Wenn ein SwTxtFrm gelocked ist, werden keine Veraenderungen an den
+    // Formatierungsdaten (unter pLine) vorgenommen (vgl. ORPHANS)
+    sal_Bool bFlys          : 1; // Ueberlappen Flys ?
+    sal_Bool bPrep          : 1; // PREP_*
+    sal_Bool bPrepWidows    : 1; // PREP_WIDOWS
+    sal_Bool bPrepAdjust    : 1; // PREP_ADJUST_FRM
+    sal_Bool bPrepMustFit   : 1; // PREP_MUST_FIT
+    sal_Bool bFollowField   : 1; // Es steht noch ein Feldrest fuer den Follow an.
+
+    sal_Bool bFixLineHeight : 1; // Feste Zeilenhoehe
+    sal_Bool bFtnNum    : 1; // contents a footnotenumberportion
+    sal_Bool bFlag09    : 1; //
+
+    sal_Bool bFlag00    : 1; //
+    sal_Bool bFlag11    : 1; //
+    sal_Bool bFlag12    : 1; //
+    sal_Bool bFlag13    : 1; //
+    sal_Bool bFlag14    : 1; //
+    sal_Bool bFlag15    : 1; //
+    sal_Bool bFlag16    : 1; //
+
+public:
+            SwParaPortion();
+
+    // setzt alle Formatinformationen zurueck (ausser bFlys wg. 9916)
+    inline void FormatReset();
+
+    // Setzt die Flags zurueck
+    inline void ResetPreps();
+
+    // Get/Set-Methoden
+    inline SwRepaint *GetRepaint() { return &aRepaint; }
+    inline const SwRepaint *GetRepaint() const { return &aRepaint; }
+    inline SwCharRange *GetReformat() { return &aReformat; }
+    inline const SwCharRange *GetReformat() const { return &aReformat; }
+    inline long *GetDelta() { return &nDelta; }
+    inline const long *GetDelta() const { return &nDelta; }
+
+    // fuer SwTxtFrm::Format: liefert die aktuelle Laenge des Absatzes
+    xub_StrLen GetParLen() const;
+
+    // fuer Prepare()
+    sal_Bool UpdateQuoVadis( const XubString &rQuo );
+
+    // Flags
+    inline void SetFly( const sal_Bool bNew = sal_True ) { bFlys = bNew; }
+    inline sal_Bool HasFly() const { return bFlys; }
+
+    // Preps
+    inline void SetPrep( const sal_Bool bNew = sal_True ) { bPrep = bNew; }
+    inline sal_Bool IsPrep() const { return bPrep; }
+    inline void SetPrepWidows( const sal_Bool bNew = sal_True ) { bPrepWidows = bNew; }
+    inline sal_Bool IsPrepWidows() const { return bPrepWidows; }
+    inline void SetPrepMustFit( const sal_Bool bNew = sal_True ) { bPrepMustFit = bNew; }
+    inline sal_Bool IsPrepMustFit() const { return bPrepMustFit; }
+    inline void SetPrepAdjust( const sal_Bool bNew = sal_True ) { bPrepAdjust = bNew; }
+    inline sal_Bool IsPrepAdjust() const { return bPrepAdjust; }
+    inline void SetFollowField( const sal_Bool bNew = sal_True ) { bFollowField = bNew; }
+    inline sal_Bool IsFollowField() const { return bFollowField; }
+    inline void SetFixLineHeight( const sal_Bool bNew = sal_True ) { bFixLineHeight = bNew; }
+    inline sal_Bool  IsFixLineHeight() const { return bFixLineHeight; }
+
+    inline void SetFtnNum( const sal_Bool bNew = sal_True ) { bFtnNum = bNew; }
+    inline sal_Bool  IsFtnNum() const { return bFtnNum; }
+    inline void SetFlag09( const sal_Bool bNew = sal_True ) { bFlag09 = bNew; }
+    inline sal_Bool  IsFlag09() const { return bFlag09; }
+    inline void SetFlag00( const sal_Bool bNew = sal_True ) { bFlag00 = bNew; }
+    inline sal_Bool  IsFlag00() const { return bFlag00; }
+    inline void SetFlag11( const sal_Bool bNew = sal_True ) { bFlag11 = bNew; }
+    inline sal_Bool  IsFlag11() const { return bFlag11; }
+    inline void SetFlag12( const sal_Bool bNew = sal_True ) { bFlag12 = bNew; }
+    inline sal_Bool  IsFlag12() const { return bFlag12; }
+    inline void SetFlag13( const sal_Bool bNew = sal_True ) { bFlag13 = bNew; }
+    inline sal_Bool  IsFlag13() const { return bFlag13; }
+    inline void SetFlag14( const sal_Bool bNew = sal_True ) { bFlag14 = bNew; }
+    inline sal_Bool  IsFlag14() const { return bFlag14; }
+    inline void SetFlag15( const sal_Bool bNew = sal_True ) { bFlag15 = bNew; }
+    inline sal_Bool  IsFlag15() const { return bFlag15; }
+    inline void SetFlag16( const sal_Bool bNew = sal_True ) { bFlag16 = bNew; }
+    inline sal_Bool  IsFlag16() const { return bFlag16; }
+
+    // schneller, hoeher, weiter: Read/Write-Methoden fuer den SWG-Filter
+    SvStream &ReadSwg ( SvStream& rStream ); //$ istream
+    SvStream &WriteSwg( SvStream& rStream ); //$ ostream
+
+    // nErgo in der QuoVadisPortion setzen
+    void SetErgoSumNum( const XubString &rErgo );
+
+    const SwDropPortion *FindDropPortion() const;
+
+    OUTPUT_OPERATOR
+    DECL_FIXEDMEMPOOL_NEWDEL(SwParaPortion)
+};
+
+/*************************************************************************
+ *                      Inline-Implementierungen
+ *************************************************************************/
+
+inline void SwLineLayout::ResetFlags()
+{
+    bFormatAdj = bDummy = bFntChg = bTab = bEndHyph = bMidHyph = bFly = bFlyCnt
+    = bRest = bBlinking = bClipping = bContent = bRedline
+    = bForcedLeftMargin = sal_False;
+    pSpaceAdd = NULL;
+}
+
+inline SwLineLayout::SwLineLayout()
+    : pNext(0), nRealHeight(0)
+{
+    ResetFlags();
+    SetWhichPor( POR_LAY );
+}
+
+inline void SwParaPortion::ResetPreps()
+{
+    bPrep = bPrepWidows = bPrepAdjust = bPrepMustFit = sal_False;
+}
+
+inline void SwParaPortion::FormatReset()
+{
+    nDelta = 0;
+    aReformat = SwCharRange( 0, STRING_LEN );
+//  AMA 9916: bFlys muss in SwTxtFrm::_Format() erhalten bleiben, damit
+//  leere Absaetze, die Rahmen ohne Umfluss ausweichen mussten, sich
+//  neu formatieren, wenn der Rahmen aus dem Bereich verschwindet.
+//  bFlys = sal_False;
+    ResetPreps();
+    bFollowField = bFixLineHeight = sal_False;
+}
+
+#ifdef UNX
+// C30 ist mit dem ternaeren Ausdruck ueberfordert.
+inline SwLinePortion *SwLineLayout::GetFirstPortion() const
+{
+    register SwLinePortion *pTmp = pPortion;
+    if ( !pPortion )
+        pTmp = (SwLinePortion*)this;
+    return( pTmp );
+}
+#else
+inline SwLinePortion *SwLineLayout::GetFirstPortion() const
+{ return( pPortion ? pPortion : (SwLinePortion*)this ); }
+#endif
+
+CLASSIO( SwLineLayout )
+CLASSIO( SwParaPortion )
+
+
+#endif
diff --git a/sw/source/core/text/porlin.cxx b/sw/source/core/text/porlin.cxx
new file mode 100644
index 000000000000..c8973dfe821a
--- /dev/null
+++ b/sw/source/core/text/porlin.cxx
@@ -0,0 +1,405 @@
+/*************************************************************************
+ *
+ *  $RCSfile: porlin.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "errhdl.hxx"   // ASSERT
+#include "segmentc.hxx"
+
+#include "txtcfg.hxx"
+#include "porlin.hxx"
+#include "inftxt.hxx"
+#include "portxt.hxx"
+#include "porglue.hxx"
+#include "inftxt.hxx"
+#include "blink.hxx"
+
+#ifndef PRODUCT
+
+sal_Bool ChkChain( SwLinePortion *pStart )
+{
+    SwLinePortion *pPor = pStart->GetPortion();
+    MSHORT nCount = 0;
+    while( pPor )
+    {
+        ++nCount;
+        ASSERT( nCount < 200 && pPor != pStart,
+                "ChkChain(): lost in chains" );
+        if( nCount >= 200 || pPor == pStart )
+        {
+            // der Lebensretter
+            pPor = pStart->GetPortion();
+            pStart->SetPortion(0);
+            pPor->Truncate();
+            pStart->SetPortion( pPor );
+            return sal_False;
+        }
+        pPor = pPor->GetPortion();
+    }
+    return sal_True;
+}
+#endif
+
+#ifdef DEBUG
+const sal_Char *GetPortionName( const MSHORT nType );
+#endif
+
+SwLinePortion::~SwLinePortion()
+{
+    if( pBlink )
+        pBlink->Delete( this );
+}
+
+SwLinePortion *SwLinePortion::Compress()
+{
+    return GetLen() || Width() ? this : 0;
+}
+
+KSHORT SwLinePortion::GetViewWidth( const SwTxtSizeInfo & ) const
+{
+    return 0;
+}
+
+#ifdef OLDRECYCLE
+
+sal_Bool SwLinePortion::MayRecycle() const { return sal_True; }
+
+#endif
+
+/*************************************************************************
+ *               SwLinePortion::SwLinePortion( )
+ *************************************************************************/
+
+SwLinePortion::SwLinePortion( ) :
+    nLineLength( 0 ),
+    nAscent( 0 ),
+    pPortion( NULL )
+{
+}
+
+/*************************************************************************
+ *               virtual SwLinePortion::PrePaint()
+ *************************************************************************/
+
+void SwLinePortion::PrePaint( const SwTxtPaintInfo &rInf, SwLinePortion *pLast ) const
+{
+    ASSERT(rInf.OnWin(), "SwLinePortion::PrePaint: don't prepaint on a printer");
+    ASSERT( !Width(), "SwLinePortion::PrePaint: For Width()==0 only!");
+
+    const KSHORT nViewWidth = GetViewWidth( rInf );
+    if( !nViewWidth )
+        return;
+    const KSHORT nHalfView = nViewWidth / 2;
+
+    KSHORT nPos = rInf.X();
+    KSHORT pLastWidth = pLast->Width();
+    if ( pLast->InTxtGrp() && rInf.GetSpaceAdd() )
+        pLastWidth += ((SwTxtPortion*)pLast)->CalcSpacing( rInf.GetSpaceAdd(),
+                                                           rInf );
+    if( pLast && pLastWidth > nHalfView )
+        nPos += pLastWidth - nHalfView;
+
+    // logisches const, da wir den Wert wieder zuruecksetzen
+    SwLinePortion *pThis = (SwLinePortion*)this;
+    pThis->Width( nViewWidth );
+    SwTxtPaintInfo aInf( rInf );
+    aInf.X( nPos );
+    Paint( aInf );
+    pThis->Width(0);
+}
+
+/*************************************************************************
+ *                  SwLinePortion::CalcTxtSize()
+ *************************************************************************/
+
+void SwLinePortion::CalcTxtSize( const SwTxtSizeInfo &rInf )
+{
+    if( GetLen() == rInf.GetLen()  )
+        *((SwPosSize*)this) = GetTxtSize( rInf );
+    else
+    {
+        SwTxtSizeInfo aInf( rInf );
+        aInf.SetLen( GetLen() );
+        *((SwPosSize*)this) = GetTxtSize( aInf );
+    }
+}
+
+/*************************************************************************
+ *                  SwLinePortion::Truncate()
+ *
+ * Es werden alle nachfolgenden Portions geloescht.
+ *************************************************************************/
+
+void SwLinePortion::_Truncate()
+{
+    SwLinePortion *pPos = pPortion;
+    do
+    {   ASSERT( pPos != this, "SwLinePortion::Truncate: loop" );
+        SwLinePortion *pLast = pPos;
+        pPos = pPos->GetPortion();
+        pLast->SetPortion( 0 );
+        delete pLast;
+
+    } while( pPos );
+
+    pPortion = 0;
+}
+
+/*************************************************************************
+ *                virtual SwLinePortion::Insert()
+ *
+ * Es wird immer hinter uns eingefuegt.
+ *************************************************************************/
+
+SwLinePortion *SwLinePortion::Insert( SwLinePortion *pIns )
+{
+    pIns->FindLastPortion()->SetPortion( pPortion );
+    SetPortion( pIns );
+#ifndef PRODUCT
+    ChkChain( this );
+#endif
+    return pIns;
+}
+
+/*************************************************************************
+ *                  SwLinePortion::FindLastPortion()
+ *************************************************************************/
+
+SwLinePortion *SwLinePortion::FindLastPortion()
+{
+    register SwLinePortion *pPos = this;
+    // An das Ende wandern und pLinPortion an den letzten haengen ...
+    while( pPos->GetPortion() )
+    {
+        DBG_LOOP;
+        pPos = pPos->GetPortion();
+    }
+    return pPos;
+}
+
+/*************************************************************************
+ *                virtual SwLinePortion::Append()
+ *************************************************************************/
+
+SwLinePortion *SwLinePortion::Append( SwLinePortion *pIns )
+{
+    SwLinePortion *pPos = FindLastPortion();
+    pPos->SetPortion( pIns );
+    pIns->SetPortion( 0 );
+#ifndef PRODUCT
+    ChkChain( this );
+#endif
+    return pIns;
+}
+
+/*************************************************************************
+ *                virtual SwLinePortion::Cut()
+ *************************************************************************/
+
+SwLinePortion *SwLinePortion::Cut( SwLinePortion *pVictim )
+{
+    SwLinePortion *pPrev = pVictim->FindPrevPortion( this );
+    ASSERT( pPrev, "SwLinePortion::Cut(): can't cut" );
+    pPrev->SetPortion( pVictim->GetPortion() );
+    pVictim->SetPortion(0);
+    return pVictim;
+}
+
+/*************************************************************************
+ *                SwLinePortion::FindPrevPortion()
+ *************************************************************************/
+
+SwLinePortion *SwLinePortion::FindPrevPortion( const SwLinePortion *pRoot )
+{
+    ASSERT( pRoot != this, "SwLinePortion::FindPrevPortion(): invalid root" );
+    SwLinePortion *pPos = (SwLinePortion*)pRoot;
+    while( pPos->GetPortion() && pPos->GetPortion() != this )
+    {
+        DBG_LOOP;
+        pPos = pPos->GetPortion();
+    }
+    ASSERT( pPos->GetPortion(),
+            "SwLinePortion::FindPrevPortion: blowing in the wind");
+    return pPos;
+}
+
+/*************************************************************************
+ *                virtual SwLinePortion::GetCrsrOfst()
+ *************************************************************************/
+
+xub_StrLen SwLinePortion::GetCrsrOfst( const KSHORT nOfst ) const
+{
+    if( nOfst > ( PrtWidth() / 2 ) )
+        return GetLen();
+    else
+        return 0;
+}
+
+/*************************************************************************
+ *                virtual SwLinePortion::GetTxtSize()
+ *************************************************************************/
+
+SwPosSize SwLinePortion::GetTxtSize( const SwTxtSizeInfo & ) const
+{
+    ASSERT( !this, "SwLinePortion::GetTxtSize: don't ask me about sizes, "
+                   "I'm only a stupid SwLinePortion" );
+    return SwPosSize();
+}
+
+#ifndef PRODUCT
+
+/*************************************************************************
+ *                virtual SwLinePortion::Check()
+ *************************************************************************/
+
+sal_Bool SwLinePortion::Check( SvStream &, SwTxtSizeInfo & ) //$ ostream
+{
+#ifdef USED
+    SwPosSize aSize( GetTxtSize( rInfo ) );
+    if( Width() != aSize.Width() )
+    {
+        CONSTCHAR( pDbgTxt, "Error in width of SwLinePortion: " );
+        rOs << pDbgTxt << endl;
+        operator<<( rOs );
+        rOs << endl;
+        rOs << "Had: " << Width() << " And: " << aSize.Width();
+        return sal_False;
+    }
+#endif /* USED */
+    return sal_True;
+}
+#endif
+
+/*************************************************************************
+ *                 virtual SwLinePortion::Format()
+ *************************************************************************/
+
+sal_Bool SwLinePortion::Format( SwTxtFormatInfo &rInf )
+{
+    if( rInf.X() > rInf.Width() )
+    {
+        Truncate();
+        rInf.SetUnderFlow( this );
+        return sal_True;
+    }
+
+    register const SwLinePortion *pLast = rInf.GetLast();
+    Height( pLast->Height() );
+    SetAscent( pLast->GetAscent() );
+    const KSHORT nNewWidth = rInf.X() + PrtWidth();
+    // Nur Portions mit echter Breite koennen ein sal_True zurueckliefern
+    // Notizen beispielsweise setzen niemals bFull==sal_True
+    if( rInf.Width() <= nNewWidth && PrtWidth() )
+    {
+        Truncate();
+        if( nNewWidth > rInf.Width() )
+            PrtWidth( nNewWidth - rInf.Width() );
+        rInf.GetLast()->FormatEOL( rInf );
+        return sal_True;
+    }
+    return sal_False;
+}
+
+/*************************************************************************
+ *                 virtual SwLinePortion::FormatEOL()
+ *************************************************************************/
+
+// Format end of line
+
+void SwLinePortion::FormatEOL( SwTxtFormatInfo &rInf )
+{ }
+
+/*************************************************************************
+ *                      SwLinePortion::Move()
+ *************************************************************************/
+
+void SwLinePortion::Move( SwTxtPaintInfo &rInf )
+{
+    if ( InTxtGrp() && rInf.GetSpaceAdd() )
+        rInf.X( rInf.X() + PrtWidth() +
+            ( (SwTxtPortion*)this )->CalcSpacing( rInf.GetSpaceAdd(), rInf ) );
+    else
+    {
+        if( InFixMargGrp() )
+        {
+            if( rInf.GetSpaceAdd() < 0 )
+                rInf.X( rInf.X() + rInf.GetSpaceAdd() );
+            rInf.IncSpaceIdx();
+        }
+        rInf.X( rInf.X() + PrtWidth() );
+    }
+    rInf.SetIdx( rInf.GetIdx() + GetLen() );
+}
+
+/*************************************************************************
+ *              virtual SwLinePortion::GetExpTxt()
+ *************************************************************************/
+
+sal_Bool SwLinePortion::GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const
+{
+    return sal_False;
+}
+
+
diff --git a/sw/source/core/text/porlin.hxx b/sw/source/core/text/porlin.hxx
new file mode 100644
index 000000000000..c20c7f870d01
--- /dev/null
+++ b/sw/source/core/text/porlin.hxx
@@ -0,0 +1,329 @@
+/*************************************************************************
+ *
+ *  $RCSfile: porlin.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:26 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _PORLIN_HXX
+#define _PORLIN_HXX
+
+#include "possiz.hxx"       // SwPosSize
+
+class XubString;
+class SwTxtSizeInfo;
+class SwTxtPaintInfo;
+class SwTxtFormatInfo;
+
+// Die Ausgabeoperatoren der Portions sind virtuelle Methoden der Portion.
+// Das CLASSIO-Makro implementiert die 'freischwebende' Funktion.
+// Auf diese Weise erhaelt man beide Vorteile: virtuelle Ausgabeoperatoren
+// und allgemeine Verwendbarkeit.
+#ifndef PRODUCT
+#define OUTPUT_OPERATOR  virtual SvStream &operator<<( SvStream & aOs ) const;
+#else
+#define OUTPUT_OPERATOR
+#endif
+
+// Portiongruppen
+#define PORGRP_TXT      0x8000
+#define PORGRP_EXP      0x4000
+#define PORGRP_FLD      0x2000
+#define PORGRP_HYPH     0x1000
+#define PORGRP_NUMBER   0x0800
+#define PORGRP_GLUE     0x0400
+#define PORGRP_FIX      0x0200
+#define PORGRP_TAB      0x0100
+#define PORGRP_NOTRECY  0x0080
+// kleine Spezialgruppen
+#define PORGRP_FIXMARG  0x0040
+#define PORGRP_FLDGLU   0x0020
+#define PORGRP_TABNOTLFT 0x0010
+#define PORGRP_TOXREF   0x0008
+
+// Portiontypen
+#define POR_LIN         0x0000
+#define POR_FLYCNT      0x0001
+
+#define POR_HOLE        0x0080
+#define POR_TMPEND      0x0081
+#define POR_BRK         0x0082
+#define POR_KERN        0x0083
+#define POR_ARROW       0x0084
+
+#define POR_TXT         0x8000
+#define POR_LAY         0x8001
+#define POR_PARA        0x8002
+#define POR_URL         0x8003
+
+#define POR_DROP        0x8080
+#define POR_TOX         0x8089
+#define POR_ISOTOX      0x808a
+#define POR_REF         0x808b
+#define POR_ISOREF      0x808c
+
+#define POR_EXP         0xc080
+#define POR_BLANK       0xc081
+#define POR_FTN         0xc082
+#define POR_POSTITS     0xc083
+
+#define POR_HYPH        0xd080
+#define POR_HYPHSTR     0xd081
+#define POR_SOFTHYPH    0xd082
+#define POR_SOFTHYPHSTR 0xd083
+
+#define POR_FLD         0xe0a0
+#define POR_HIDDEN      0xe0a1
+#define POR_QUOVADIS    0xe0a2
+#define POR_ERGOSUM     0xe0a3
+
+#define POR_FTNNUM      0xe8a0
+#define POR_NUMBER      0xe8a1
+#define POR_BULLET      0xe8a2
+#define POR_GRFNUM      0xe8a3
+
+#define POR_GLUE        0x0480
+
+#define POR_MARGIN      0x04c0
+
+#define POR_FIX         0x06c0
+#define POR_FLY         0x06c1
+
+#define POR_TAB         0x0750
+
+#define POR_TABRIGHT    0x07d0
+#define POR_TABCENTER   0x07d1
+#define POR_TABDECIMAL  0x07d2
+
+#define POR_TABLEFT     0x0740
+
+/*************************************************************************
+ *                      class SwLinePortion
+ *************************************************************************/
+
+class SwLinePortion: public SwPosSize
+{
+protected:
+    // Hier gibt es Bereiche mit unterschiedlichen Attributen.
+    SwLinePortion *pPortion;
+    // Anzahl der Zeichen und Spaces auf der Zeile
+    xub_StrLen nLineLength;
+    KSHORT nAscent;      // Maximaler Ascender
+
+    SwLinePortion();
+private:
+    MSHORT nWhichPor;       // Who's who?
+
+    void _Truncate();
+
+public:
+    inline          SwLinePortion(const SwLinePortion &rPortion);
+           virtual ~SwLinePortion();
+
+    // Zugriffsmethoden
+    inline SwLinePortion *GetPortion() const { return( pPortion ); }
+    inline SwLinePortion &operator=(const SwLinePortion &rPortion);
+    inline sal_Bool operator==( const SwLinePortion &rPortion ) const;
+    inline const xub_StrLen GetLen() const { return nLineLength; }
+    inline void SetLen( const xub_StrLen nLen ) { nLineLength = nLen; }
+    inline void SetPortion( SwLinePortion *pNew ){ pPortion = pNew; }
+    inline KSHORT &GetAscent() { return nAscent; }
+    inline KSHORT GetAscent() const { return nAscent; }
+    inline void SetAscent( const KSHORT nNewAsc ) { nAscent = nNewAsc; }
+    inline void  PrtWidth( KSHORT nNewWidth ) { Width( nNewWidth ); }
+    inline KSHORT PrtWidth() const { return Width(); }
+    inline void AddPrtWidth( const KSHORT nNew ) { Width( Width() + nNew ); }
+    inline void SubPrtWidth( const KSHORT nNew ) { Width( Width() - nNew ); }
+
+    inline const SwPosSize &PrtSize() const { return *this; }
+
+    // Einfuegeoperationen:
+    virtual SwLinePortion *Insert( SwLinePortion *pPortion );
+    virtual SwLinePortion *Append( SwLinePortion *pPortion );
+            SwLinePortion *Cut( SwLinePortion *pVictim );
+    inline  void Truncate();
+
+    // liefert 0 zurueck, wenn keine Nutzdaten enthalten sind.
+    virtual SwLinePortion *Compress();
+
+    inline void SetWhichPor( const MSHORT nNew )    { nWhichPor = nNew; }
+    inline const MSHORT GetWhichPor( )          { return nWhichPor; }
+
+// Gruppenabfragen:
+    inline const sal_Bool MayRecycle()  const
+        { return nWhichPor & PORGRP_NOTRECY ? sal_False : sal_True; }
+    inline const sal_Bool InTxtGrp( )   const { return nWhichPor & PORGRP_TXT ? sal_True : sal_False; }
+    inline const sal_Bool InGlueGrp( )  const { return nWhichPor & PORGRP_GLUE ? sal_True : sal_False;}
+    inline const sal_Bool InTabGrp( )   const { return nWhichPor & PORGRP_TAB ? sal_True : sal_False; }
+    inline const sal_Bool InHyphGrp( )  const { return nWhichPor & PORGRP_HYPH ? sal_True : sal_False;}
+    inline const sal_Bool InNumberGrp( )const { return nWhichPor & PORGRP_NUMBER ? sal_True : sal_False;}
+    inline const sal_Bool InFixGrp( )   const { return nWhichPor & PORGRP_FIX ? sal_True : sal_False;  }
+    inline const sal_Bool InFldGrp( )   const { return nWhichPor & PORGRP_FLD ? sal_True : sal_False;  }
+    inline const sal_Bool InToxRefGrp( ) const { return nWhichPor & PORGRP_TOXREF ? sal_True : sal_False;  }
+    inline const sal_Bool InToxRefOrFldGrp( )   const { return nWhichPor &
+                                ( PORGRP_FLD | PORGRP_TOXREF ) ? sal_True : sal_False;  }
+    inline const sal_Bool InExpGrp( )   const { return nWhichPor & PORGRP_EXP ? sal_True : sal_False;  }
+    inline const sal_Bool InTabnLftGrp( ) const
+        { return nWhichPor & PORGRP_TABNOTLFT ? sal_True : sal_False;  }
+    inline const sal_Bool InFldGluGrp( )const
+        { return nWhichPor & PORGRP_FLDGLU ? sal_True : sal_False;  }
+    inline const sal_Bool InFixMargGrp( )const
+        { return nWhichPor & PORGRP_FIXMARG ? sal_True : sal_False;  }
+// Individuelle Abfragen:
+    inline const sal_Bool IsGrfNumPortion( )const{ return nWhichPor == POR_GRFNUM; }
+    inline const sal_Bool IsFlyCntPortion( )const{ return nWhichPor == POR_FLYCNT; }
+    inline const sal_Bool IsBlankPortion( ) const{ return nWhichPor == POR_BLANK; }
+    inline const sal_Bool IsBreakPortion( ) const{ return nWhichPor == POR_BRK; }
+    inline const sal_Bool IsErgoSumPortion()const{ return nWhichPor == POR_ERGOSUM;}
+    inline const sal_Bool IsQuoVadisPortion()const{ return nWhichPor==POR_QUOVADIS;}
+    inline const sal_Bool IsTabCntPortion( )const{ return nWhichPor==POR_TABCENTER;}
+    inline const sal_Bool IsTabLeftPortion()const{ return nWhichPor == POR_TABLEFT;}
+    inline const sal_Bool IsFtnNumPortion( )const{ return nWhichPor == POR_FTNNUM; }
+    inline const sal_Bool IsFtnPortion( )   const{ return nWhichPor == POR_FTN; }
+    inline const sal_Bool IsTmpEndPortion( )const{ return nWhichPor == POR_TMPEND; }
+    inline const sal_Bool IsDropPortion( )  const{ return nWhichPor == POR_DROP; }
+    inline const sal_Bool IsLayPortion( )   const{ return nWhichPor == POR_LAY; }
+    inline const sal_Bool IsParaPortion( )  const{ return nWhichPor == POR_PARA; }
+    inline const sal_Bool IsMarginPortion( )const{ return nWhichPor == POR_MARGIN; }
+    inline const sal_Bool IsFlyPortion( )   const{ return nWhichPor == POR_FLY; }
+    inline const sal_Bool IsHolePortion( )  const{ return nWhichPor == POR_HOLE; }
+    inline const sal_Bool IsSoftHyphPortion()const{ return nWhichPor==POR_SOFTHYPH;}
+    inline const sal_Bool IsPostItsPortion()const{ return nWhichPor == POR_POSTITS;}
+    inline const sal_Bool IsTextPortion( ) const{ return nWhichPor == POR_TXT; }
+    inline const sal_Bool IsURLPortion( ) const{ return nWhichPor == POR_URL; }
+    inline const sal_Bool IsKernPortion( ) const{ return nWhichPor == POR_KERN; }
+    inline const sal_Bool IsArrowPortion( ) const{ return nWhichPor == POR_ARROW; }
+
+    // Positionierung
+    SwLinePortion *FindPrevPortion( const SwLinePortion *pRoot );
+    SwLinePortion *FindLastPortion();
+
+    virtual xub_StrLen GetCrsrOfst( const KSHORT nOfst ) const;
+    virtual SwPosSize GetTxtSize( const SwTxtSizeInfo &rInfo ) const;
+    void CalcTxtSize( const SwTxtSizeInfo &rInfo );
+
+    // Ausgabe
+    virtual void Paint( const SwTxtPaintInfo &rInf ) const = 0;
+    void PrePaint( const SwTxtPaintInfo &rInf, SwLinePortion *pLast ) const;
+
+#ifndef PRODUCT
+    virtual sal_Bool Check( SvStream &rOs, SwTxtSizeInfo &rInfo ); //$ ostream
+#endif
+
+    virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+    // wird fuer die letzte Portion der Zeile extra gerufen
+    virtual void FormatEOL( SwTxtFormatInfo &rInf );
+            void Move( SwTxtPaintInfo &rInf );
+
+    // Fuer SwTxtSlot
+    virtual sal_Bool GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const;
+
+    // fuer SwFldPortion, SwSoftHyphPortion
+    virtual KSHORT GetViewWidth( const SwTxtSizeInfo &rInf ) const;
+
+    OUTPUT_OPERATOR
+};
+
+
+/*************************************************************************
+ *                  inline - Implementations
+ *************************************************************************/
+
+inline SwLinePortion &SwLinePortion::operator=(const SwLinePortion &rPortion)
+{
+    *(SwPosSize*)this = rPortion;
+    nLineLength = rPortion.nLineLength;
+    nAscent = rPortion.nAscent;
+    nWhichPor = rPortion.nWhichPor;
+    return *this;
+}
+
+inline sal_Bool SwLinePortion::operator==(const SwLinePortion &rPortion ) const
+{
+    return( *(SwPosSize*)this == rPortion &&
+            nLineLength == rPortion.GetLen() &&
+            nAscent == rPortion.GetAscent() );
+}
+
+inline SwLinePortion::SwLinePortion(const SwLinePortion &rPortion) :
+    SwPosSize( rPortion ),
+    pPortion( 0 ),
+    nLineLength( rPortion.nLineLength ),
+    nAscent( rPortion.nAscent ),
+    nWhichPor( rPortion.nWhichPor )
+{
+}
+
+inline void SwLinePortion::Truncate()
+{
+    if ( pPortion )
+        _Truncate();
+}
+
+
+//$ ostream
+#ifdef DBGTXT
+#define CLASSIO( class ) \
+    inline SvStream &operator<<( SvStream &rOs, const class &rClass ) {\
+            return rClass.operator<<( rOs );\
+    }
+#else
+#define CLASSIO( class )
+#endif
+
+CLASSIO( SwLinePortion )
+
+#endif
diff --git a/sw/source/core/text/porref.cxx b/sw/source/core/text/porref.cxx
new file mode 100644
index 000000000000..c82e5fad3262
--- /dev/null
+++ b/sw/source/core/text/porref.cxx
@@ -0,0 +1,139 @@
+/*************************************************************************
+ *
+ *  $RCSfile: porref.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:26 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "viewopt.hxx"  // SwViewOptions
+#include "segmentc.hxx"
+
+#include "txtcfg.hxx"
+#include "porref.hxx"
+#include "inftxt.hxx"       // GetTxtSize()
+
+/*************************************************************************
+ *               virtual SwRefPortion::Paint()
+ *************************************************************************/
+
+void SwRefPortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+    if( Width() )
+    {
+        rInf.DrawViewOpt( *this, POR_REF );
+        SwTxtPortion::Paint( rInf );
+    }
+}
+
+/*************************************************************************
+ *                      class SwIsoRefPortion
+ *************************************************************************/
+
+SwLinePortion *SwIsoRefPortion::Compress() { return this; }
+
+SwIsoRefPortion::SwIsoRefPortion() : nViewWidth(0)
+{
+    SetLen(1);
+    SetWhichPor( POR_ISOREF );
+}
+
+/*************************************************************************
+ *               virtual SwIsoRefPortion::GetViewWidth()
+ *************************************************************************/
+
+KSHORT SwIsoRefPortion::GetViewWidth( const SwTxtSizeInfo &rInf ) const
+{
+    // Wir stehen zwar im const, aber nViewWidth sollte erst im letzten
+    // Moment errechnet werden:
+    SwIsoRefPortion* pThis = (SwIsoRefPortion*)this;
+    if( !Width() && rInf.OnWin() && rInf.GetOpt().IsRef() )
+    {
+        if( !nViewWidth )
+            pThis->nViewWidth = rInf.GetTxtSize( ' ' ).Width();
+    }
+    else
+        pThis->nViewWidth = 0;
+    return nViewWidth;
+}
+
+/*************************************************************************
+ *                 virtual SwIsoRefPortion::Format()
+ *************************************************************************/
+
+sal_Bool SwIsoRefPortion::Format( SwTxtFormatInfo &rInf )
+{
+    const sal_Bool bFull = SwLinePortion::Format( rInf );
+    return bFull;
+}
+
+/*************************************************************************
+ *               virtual SwIsoRefPortion::Paint()
+ *************************************************************************/
+
+void SwIsoRefPortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+    if( Width() )
+        rInf.DrawViewOpt( *this, POR_REF );
+}
+
+
diff --git a/sw/source/core/text/porref.hxx b/sw/source/core/text/porref.hxx
new file mode 100644
index 000000000000..c251734b8d9b
--- /dev/null
+++ b/sw/source/core/text/porref.hxx
@@ -0,0 +1,106 @@
+/*************************************************************************
+ *
+ *  $RCSfile: porref.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:26 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _PORREF_HXX
+#define _PORREF_HXX
+
+#include "portxt.hxx"
+
+/*************************************************************************
+ *                      class SwRefPortion
+ *************************************************************************/
+
+class SwRefPortion : public SwTxtPortion
+{
+public:
+    inline  SwRefPortion(){ SetWhichPor( POR_REF ); }
+    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+#ifdef OLDRECYCLE
+    virtual sal_Bool MayRecycle() const { return sal_False; }
+#endif
+    OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ *                      class SwIsoRefPortion
+ *************************************************************************/
+
+class SwIsoRefPortion : public SwRefPortion
+{
+    KSHORT nViewWidth;
+
+public:
+            SwIsoRefPortion();
+    virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+    virtual SwLinePortion *Compress();
+    virtual KSHORT GetViewWidth( const SwTxtSizeInfo &rInf ) const;
+    OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ *                  inline - Implementations
+ *************************************************************************/
+
+CLASSIO( SwRefPortion )
+CLASSIO( SwIsoRefPortion )
+
+
+#endif
diff --git a/sw/source/core/text/porrst.cxx b/sw/source/core/text/porrst.cxx
new file mode 100644
index 000000000000..a1d42996aee2
--- /dev/null
+++ b/sw/source/core/text/porrst.cxx
@@ -0,0 +1,547 @@
+/*************************************************************************
+ *
+ *  $RCSfile: porrst.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:26 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _SFX_PRINTER_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_LSPCITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_TEXTCONV_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_ADJITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _WINDOW_HXX //autogen
+#include 
+#endif
+#ifndef _SV_SVAPP_HXX
+#include 
+#endif
+#ifndef _TEXTCONV_HXX //autogen
+#include 
+#endif
+
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _VIEWSH_HXX
+#include    // ViewShell
+#endif
+#ifndef _VIEWOPT_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include     // SwTxtNode
+#endif
+#ifndef _PAGEFRM_HXX
+#include   // SwPageFrm
+#endif
+#ifndef _PARATR_HXX
+#include 
+#endif
+#ifndef _ERRHDL_HXX
+#include    // ASSERT
+#endif
+#ifndef _TXTCFG_HXX
+#include 
+#endif
+#ifndef _PORRST_HXX
+#include 
+#endif
+#ifndef _INFTXT_HXX
+#include 
+#endif
+#ifndef _TXTPAINT_HXX
+#include  // ClipVout
+#endif
+#ifndef _TXTFRM_HXX
+#include    // SwTxtFrm
+#endif
+#ifndef _SWFNTCCH_HXX
+#include  // SwFontAccess
+#endif
+#ifndef _PAGEDESC_HXX
+#include  // SwPageDesc
+#endif
+#ifndef _FRMSH_HXX
+#include 
+#endif
+#ifndef _FRMATR_HXX
+#include 
+#endif
+#ifndef _REDLNITR_HXX
+#include  // SwRedlineItr
+#endif
+#ifndef _PORFLY_HXX
+#include    // SwFlyPortion
+#endif
+
+/*************************************************************************
+ *                      class SwTmpEndPortion
+ *************************************************************************/
+
+SwTmpEndPortion::SwTmpEndPortion( const SwLinePortion &rPortion )
+{
+    Height( rPortion.Height() );
+    SetAscent( rPortion.GetAscent() );
+    SetWhichPor( POR_TMPEND );
+}
+
+/*************************************************************************
+ *                 virtual SwTmpEndPortion::Paint()
+ *************************************************************************/
+
+void SwTmpEndPortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+    if( rInf.OnWin() && rInf.GetOpt().IsParagraph() )
+    {
+        SwDefFontSave aSave( rInf );
+        const XubString aTmp( sal_Char(aSave.IsAlter() ? CH_PAR_ALTER : CH_PAR),
+            RTL_TEXTENCODING_MS_1252 );
+        rInf.DrawText( aTmp, *this );
+    }
+}
+
+/*************************************************************************
+ *                      class SwBreakPortion
+ *************************************************************************/
+
+SwBreakPortion::SwBreakPortion( const SwLinePortion &rPortion )
+    : SwLinePortion( rPortion ), nViewWidth( 0 ), nRestWidth( 0 )
+{
+    nLineLength = 1;
+    SetWhichPor( POR_BRK );
+}
+
+xub_StrLen SwBreakPortion::GetCrsrOfst( const KSHORT ) const
+{ return 0; }
+
+KSHORT SwBreakPortion::GetViewWidth( const SwTxtSizeInfo &rInf ) const
+{ return 0; }
+
+SwLinePortion *SwBreakPortion::Compress()
+{ return (GetPortion() && GetPortion()->InTxtGrp() ? 0 : this); }
+
+void SwBreakPortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+    if( rInf.OnWin() && rInf.GetOpt().IsLineBreak() )
+    {
+        ((SwBreakPortion*)this)->CalcViewWidth( rInf );
+        if( nViewWidth && nViewWidth <= nRestWidth )
+            rInf.DrawLineBreak( *this );
+    }
+}
+
+/*************************************************************************
+ *                  SwBreakPortion::CalcViewWidth()
+ *************************************************************************/
+
+void SwBreakPortion::CalcViewWidth( const SwTxtSizeInfo &rInf )
+{
+    ASSERT( rInf.GetOpt().IsLineBreak(), "SwBreakPortion::CalcViewWidth: zombie" );
+    // Im Mormalfall folgt auf ein Break keine weitere Portion, nur wenn im Blocksatz
+    // auch die letzte Zeile im Blocksatz ist, folgt eine Marginportion der Breite 0,
+    // ist die Zeile zentriert, so folgt eine Marginportion mit Breite > 0.
+    if( GetPortion() )
+    {
+        if( GetPortion()->IsFlyPortion() )
+        {
+            short nTmp = ((SwFlyPortion*)GetPortion())->GetPrtGlue();
+            nRestWidth = nTmp > 0 ? nTmp : 0;
+        }
+        else
+            nRestWidth = GetPortion()->Width();
+    }
+    if( rInf.GetWin() && nRestWidth )
+    {
+        if( !nViewWidth )
+            nViewWidth = (KSHORT)rInf.GetOpt().GetLineBreakWidth( rInf.GetWin() );
+    }
+    else
+        nViewWidth = 0;
+}
+
+/*************************************************************************
+ *                 virtual SwBreakPortion::Format()
+ *************************************************************************/
+
+sal_Bool SwBreakPortion::Format( SwTxtFormatInfo &rInf )
+{
+    nRestWidth = rInf.Width() - rInf.X();
+    register const SwLinePortion *pRoot = rInf.GetRoot();
+    Width( 0 );
+    Height( pRoot->Height() );
+    SetAscent( pRoot->GetAscent() );
+    if ( rInf.GetIdx()+1 == rInf.GetTxt().Len() )
+        rInf.SetNewLine( sal_True );
+    return sal_True;
+}
+
+SwKernPortion::SwKernPortion( SwLinePortion &rPortion, short nKrn ) :
+    nKern( nKrn )
+{
+    Height( rPortion.Height() );
+    SetAscent( rPortion.GetAscent() );
+    nLineLength = 0;
+    SetWhichPor( POR_KERN );
+    if( nKern > 0 )
+        Width( nKern );
+    rPortion.Insert( this );
+}
+
+void SwKernPortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+    if( Width() )
+    {
+        rInf.DrawBackBrush( *this );
+        if( rInf.GetFont()->IsPaintBlank() )
+        {
+static sal_Char __READONLY_DATA sDoubleSpace[] = "  ";
+            // Tabs mit Fuellung
+            if( rInf.OnWin() ) // Keine Luecken am Bildschirm
+                ((SwKernPortion*)this)->Width( Width() + 12 );
+            XubString aTxt( sDoubleSpace, RTL_TEXTENCODING_MS_1252 );
+            rInf.DrawText( aTxt, *this, 0, 2, sal_True );
+            if( rInf.OnWin() )
+                ((SwKernPortion*)this)->Width( Width() - 12 );
+        }
+    }
+}
+
+void SwKernPortion::FormatEOL( SwTxtFormatInfo &rInf )
+{
+    if( rInf.GetLast() == this )
+        rInf.SetLast( FindPrevPortion( rInf.GetRoot() ) );
+    if( nKern < 0 )
+        Width( -nKern );
+    else
+        Width( 0 );
+    rInf.GetLast()->FormatEOL( rInf );
+}
+
+SwArrowPortion::SwArrowPortion( const SwLinePortion &rPortion ) :
+    bLeft( sal_True )
+{
+    Height( rPortion.Height() );
+    SetAscent( rPortion.GetAscent() );
+    nLineLength = 0;
+    SetWhichPor( POR_ARROW );
+}
+
+SwArrowPortion::SwArrowPortion( const SwTxtPaintInfo &rInf )
+    : bLeft( sal_False )
+{
+    Height( rInf.GetTxtFrm()->Prt().Height() );
+    aPos.X() = rInf.GetTxtFrm()->Frm().Left() +
+               rInf.GetTxtFrm()->Prt().Right();
+    aPos.Y() = rInf.GetTxtFrm()->Frm().Top() +
+               rInf.GetTxtFrm()->Prt().Bottom();
+}
+
+void SwArrowPortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+    ((SwArrowPortion*)this)->aPos = rInf.GetPos();
+}
+
+void SwArrowPortion::PaintIt( OutputDevice *pOut ) const
+{
+    Size aSize( 6, 12 );
+    aSize = pOut->PixelToLogic( aSize );
+    SwRect aRect( GetPos(), aSize );
+    if( bLeft )
+    {
+        aRect.Pos().Y() += 20 - GetAscent();
+        aRect.Pos().X() += 20;
+        if( aSize.Height() > Height() )
+            aRect.Height( Height() );
+    }
+    else
+    {
+        if( aSize.Height() > Height() )
+            aRect.Height( Height() );
+        aRect.Pos().Y() -= aRect.Height() + 20;
+        aRect.Pos().X() -= aRect.Width() + 20;
+    }
+
+    Color aCol( COL_LIGHTRED );
+    SvxFont::DrawArrow( *pOut, aRect.SVRect(), aSize, aCol, bLeft );
+}
+
+SwLinePortion *SwArrowPortion::Compress() { return this; }
+
+
+SwTwips SwTxtFrm::EmptyHeight() const
+{
+    SwFont *pFnt;
+    const SwTxtNode& rTxtNode = *GetTxtNode();
+    ViewShell *pSh = GetShell();
+    if ( rTxtNode.HasSwAttrSet() )
+    {
+        const SwAttrSet *pAttrSet = &( rTxtNode.GetSwAttrSet() );
+        pFnt = new SwFont( pAttrSet );
+    }
+    else
+    {
+        SwFontAccess aFontAccess( &rTxtNode.GetAnyFmtColl(), pSh);
+        pFnt = new SwFont( *aFontAccess.Get()->GetFont() );
+        pFnt->ChkMagic( pSh, pFnt->GetActual() );
+    }
+    OutputDevice *pOut = pSh ? pSh->GetOut() : 0;
+    if ( !pOut || !rTxtNode.GetDoc()->IsBrowseMode() ||
+         ( pSh->GetViewOptions()->IsPrtFormat() ) )
+    {
+        Printer *pPrt = rTxtNode.GetDoc()->GetPrt();
+        if( !pOut || ( pPrt && pPrt->IsValid() ) )
+            pOut = pPrt;
+    }
+
+    const SwDoc* pDoc = rTxtNode.GetDoc();
+    if( ::IsShowChanges( pDoc->GetRedlineMode() ) )
+    {
+        MSHORT nRedlPos = pDoc->GetRedlinePos( rTxtNode );
+        if( MSHRT_MAX != nRedlPos )
+            SwRedlineItr aRedln( rTxtNode, *pFnt, nRedlPos, sal_True );
+    }
+
+    SwTwips nRet;
+    if( !pOut )
+        nRet = Prt().SSize().Height() + 1;
+    else
+    {
+        pFnt->SetFntChg( sal_True );
+        pFnt->ChgPhysFnt( pSh, pOut );
+        nRet = pFnt->GetHeight( pSh, pOut );
+    }
+    delete pFnt;
+    return nRet;
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::FormatEmpty()
+ *************************************************************************/
+
+sal_Bool SwTxtFrm::FormatEmpty()
+{
+    if ( HasFollow() || GetTxtNode()->GetpSwpHints() ||
+        0 != GetTxtNode()->GetNumRule() ||
+        0 != GetTxtNode()->GetOutlineNum() ||
+         IsInFtn() || ( HasPara() && GetPara()->IsPrepMustFit() ) )
+        return sal_False;
+    const SwAttrSet& aSet = GetTxtNode()->GetSwAttrSet();
+    if( SVX_ADJUST_LEFT != aSet.GetAdjust().GetAdjust()
+        || aSet.GetRegister().GetValue() )
+        return sal_False;
+    const SvxLineSpacingItem &rSpacing = aSet.GetLineSpacing();
+    if( SVX_LINE_SPACE_MIN == rSpacing.GetLineSpaceRule() ||
+        SVX_LINE_SPACE_FIX == rSpacing.GetLineSpaceRule() ||
+        aSet.GetLRSpace().IsAutoFirst() )
+        return sal_False;
+    else
+    {
+        SwTxtFly aTxtFly( this );
+        SwRect aRect;
+        sal_Bool bFirstFlyCheck = 0 != Prt().Height();
+        if ( bFirstFlyCheck &&
+             aTxtFly.IsOn() && aTxtFly.IsAnyObj( aRect ) )
+            return sal_False;
+        else
+        {
+            SwTwips nHeight = EmptyHeight();
+
+            const SwTwips nChg = nHeight - Prt().SSize().Height();
+            if( !nChg )
+                SetUndersized( sal_False );
+            AdjustFrm( nChg );
+
+            if( HasBlinkPor() )
+            {
+                ClearPara();
+                ResetBlinkPor();
+            }
+            SetCacheIdx( MSHRT_MAX );
+            if( !IsEmpty() )
+            {
+                SetEmpty( sal_True );
+                SetCompletePaint();
+            }
+            if( !bFirstFlyCheck &&
+                 aTxtFly.IsOn() && aTxtFly.IsAnyObj( aRect ) )
+                 return sal_False;
+            return sal_True;
+        }
+    }
+}
+
+sal_Bool SwTxtFrm::FillRegister( SwTwips& rRegStart, KSHORT& rRegDiff )
+{
+    const SwFrm *pFrm = this;
+    rRegDiff = 0;
+    while( !( ( FRM_BODY | FRM_FLY )
+           & pFrm->GetType() ) && pFrm->GetUpper() )
+        pFrm = pFrm->GetUpper();
+    if( ( FRM_BODY| FRM_FLY ) & pFrm->GetType() )
+    {
+        rRegStart = pFrm->Frm().Top() + pFrm->Prt().Top();
+        pFrm = pFrm->FindPageFrm();
+        if( pFrm->IsPageFrm() )
+        {
+            SwPageDesc* pDesc = ((SwPageFrm*)pFrm)->FindPageDesc();
+            if( pDesc )
+            {
+                rRegDiff = pDesc->GetRegHeight();
+                if( !rRegDiff )
+                {
+                    const SwTxtFmtColl *pFmt = pDesc->GetRegisterFmtColl();
+                    if( pFmt )
+                    {
+                        const SvxLineSpacingItem &rSpace = pFmt->GetLineSpacing();
+                        if( SVX_LINE_SPACE_FIX == rSpace.GetLineSpaceRule() )
+                        {
+                            rRegDiff = rSpace.GetLineHeight();
+                            pDesc->SetRegHeight( rRegDiff );
+                            pDesc->SetRegAscent( ( 4 * rRegDiff ) / 5 );
+                        }
+                        else
+                        {
+                            ViewShell *pSh = GetShell();
+                            SwFontAccess aFontAccess( pFmt, pSh );
+                            SwFont aFnt( *aFontAccess.Get()->GetFont() );
+                            OutputDevice *pOut = 0;
+                            if( !GetTxtNode()->GetDoc()->IsBrowseMode() ||
+                                (pSh && pSh->GetViewOptions()->IsPrtFormat()) )
+                                pOut = GetTxtNode()->GetDoc()->GetPrt();
+                            if( (!pOut || !((Printer*)pOut)->IsValid()) && pSh )
+                                pOut = pSh->GetWin();
+                            if( !pOut )
+                                pOut = GetpApp()->GetDefaultDevice();
+                            MapMode aOldMap( pOut->GetMapMode() );
+                            pOut->SetMapMode( MapMode( MAP_TWIP ) );
+                            aFnt.ChgFnt( pSh, pOut );
+                            rRegDiff = aFnt.GetHeight( pSh, pOut );
+                            KSHORT nNettoHeight = rRegDiff;
+                            switch( rSpace.GetLineSpaceRule() )
+                            {
+                                case SVX_LINE_SPACE_AUTO:
+                                break;
+                                case SVX_LINE_SPACE_MIN:
+                                {
+                                    if( rRegDiff < KSHORT( rSpace.GetLineHeight() ) )
+                                        rRegDiff = rSpace.GetLineHeight();
+                                    break;
+                                }
+                                default: ASSERT(
+                                sal_False, ": unknown LineSpaceRule" );
+                            }
+                            switch( rSpace.GetInterLineSpaceRule() )
+                            {
+                                case SVX_INTER_LINE_SPACE_OFF:
+                                break;
+                                case SVX_INTER_LINE_SPACE_PROP:
+                                {
+                                    long nTmp = rSpace.GetPropLineSpace();
+                                    if( nTmp < 50 )
+                                        nTmp = nTmp ? 50 : 100;
+                                    nTmp *= rRegDiff;
+                                    nTmp /= 100;
+                                    if( !nTmp )
+                                        ++nTmp;
+                                    rRegDiff = (KSHORT)nTmp;
+                                    nNettoHeight = rRegDiff;
+                                    break;
+                                }
+                                case SVX_INTER_LINE_SPACE_FIX:
+                                {
+                                    rRegDiff += rSpace.GetInterLineSpace();
+                                    nNettoHeight = rRegDiff;
+                                    break;
+                                }
+                                default: ASSERT( sal_False, ": unknown InterLineSpaceRule" );
+                            }
+                            pDesc->SetRegHeight( rRegDiff );
+                            pDesc->SetRegAscent( rRegDiff - nNettoHeight +
+                                                 aFnt.GetAscent( pSh, pOut ) );
+                            pOut->SetMapMode( aOldMap );
+                        }
+                    }
+                }
+                rRegStart += pDesc->GetRegAscent() - rRegDiff;
+            }
+        }
+    }
+    return ( 0 != rRegDiff );
+}
+
+
diff --git a/sw/source/core/text/porrst.hxx b/sw/source/core/text/porrst.hxx
new file mode 100644
index 000000000000..7f48e9d53762
--- /dev/null
+++ b/sw/source/core/text/porrst.hxx
@@ -0,0 +1,149 @@
+/*************************************************************************
+ *
+ *  $RCSfile: porrst.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:26 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _PORRST_HXX
+#define _PORRST_HXX
+
+#ifndef _SVARRAY_HXX //autogen
+#include 
+#endif
+
+#include "porlay.hxx"
+#include "porexp.hxx"
+
+class SwTxtFormatInfo;
+
+/*************************************************************************
+ *                      class SwTmpEndPortion
+ *************************************************************************/
+
+class SwTmpEndPortion : public SwLinePortion
+{
+public:
+            SwTmpEndPortion( const SwLinePortion &rPortion );
+    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+    OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ *                      class SwBreakPortion
+ *************************************************************************/
+
+class SwBreakPortion : public SwLinePortion
+{
+    void CalcViewWidth( const SwTxtSizeInfo &rInf );
+protected:
+    KSHORT  nViewWidth;
+    KSHORT  nRestWidth;
+public:
+            SwBreakPortion( const SwLinePortion &rPortion );
+    // liefert 0 zurueck, wenn keine Nutzdaten enthalten sind.
+    virtual SwLinePortion *Compress();
+    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+    virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+    virtual KSHORT GetViewWidth( const SwTxtSizeInfo &rInf ) const;
+    virtual xub_StrLen GetCrsrOfst( const MSHORT nOfst ) const;
+    OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ *                      class SwKernPortion
+ *************************************************************************/
+
+class SwKernPortion : public SwLinePortion
+{
+    short nKern;
+public:
+            SwKernPortion( SwLinePortion &rPortion, short nKrn );
+    virtual void FormatEOL( SwTxtFormatInfo &rInf );
+    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+    OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ *                      class SwArrowPortion
+ *************************************************************************/
+
+class SwArrowPortion : public SwLinePortion
+{
+    Point aPos;
+    sal_Bool bLeft;
+public:
+            SwArrowPortion( const SwLinePortion &rPortion );
+            SwArrowPortion( const SwTxtPaintInfo &rInf );
+    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+    virtual SwLinePortion *Compress();
+    void PaintIt( OutputDevice *pOut ) const;
+    inline sal_Bool IsLeft() const { return bLeft; }
+    inline const Point& GetPos() const { return aPos; }
+    OUTPUT_OPERATOR
+};
+
+
+/*************************************************************************
+ *                  inline - Implementations
+ *************************************************************************/
+
+CLASSIO( SwBreakPortion )
+CLASSIO( SwEndPortion )
+CLASSIO( SwKernPortion )
+CLASSIO( SwArrowPortion )
+
+#endif
diff --git a/sw/source/core/text/portab.hxx b/sw/source/core/text/portab.hxx
new file mode 100644
index 000000000000..b0aca6dc8c55
--- /dev/null
+++ b/sw/source/core/text/portab.hxx
@@ -0,0 +1,159 @@
+/*************************************************************************
+ *
+ *  $RCSfile: portab.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:26 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _PORTAB_HXX
+#define _PORTAB_HXX
+
+#include "porglue.hxx"
+
+/*************************************************************************
+ *                      class SwTabPortion
+ *************************************************************************/
+
+class SwTabPortion : public SwFixPortion
+{
+    const KSHORT nTabPos;
+    const xub_Unicode cFill;
+
+    // Das Format() verzweigt entweder in Pre- oder PostFormat()
+    sal_Bool PreFormat( SwTxtFormatInfo &rInf );
+public:
+    SwTabPortion( const KSHORT nTabPos, const xub_Unicode cFill = '\0' );
+    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+    virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+    virtual void FormatEOL( SwTxtFormatInfo &rInf );
+    sal_Bool PostFormat( SwTxtFormatInfo &rInf );
+    inline  sal_Bool IsFilled() const { return 0 != cFill; }
+    inline  KSHORT GetTabPos() const { return nTabPos; }
+    OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ *                  class SwTabLeftPortion
+ *************************************************************************/
+
+class SwTabLeftPortion : public SwTabPortion
+{
+public:
+    inline SwTabLeftPortion( const KSHORT nTabPos, const xub_Unicode cFill='\0' )
+         : SwTabPortion( nTabPos, cFill )
+    { SetWhichPor( POR_TABLEFT ); }
+    OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ *                  class SwTabRightPortion
+ *************************************************************************/
+
+class SwTabRightPortion : public SwTabPortion
+{
+public:
+    inline SwTabRightPortion( const KSHORT nTabPos, const xub_Unicode cFill='\0' )
+         : SwTabPortion( nTabPos, cFill )
+    { SetWhichPor( POR_TABRIGHT ); }
+#ifdef OLDRECYCLE
+    virtual sal_Bool MayRecycle() const;
+#endif
+    OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ *                  class SwTabCenterPortion
+ *************************************************************************/
+
+class SwTabCenterPortion : public SwTabPortion
+{
+public:
+    inline SwTabCenterPortion( const KSHORT nTabPos, const xub_Unicode cFill='\0' )
+         : SwTabPortion( nTabPos, cFill )
+    { SetWhichPor( POR_TABCENTER ); }
+#ifdef OLDRECYCLE
+    virtual sal_Bool MayRecycle() const;
+#endif
+    OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ *                  class SwTabDecimalPortion
+ *************************************************************************/
+
+class SwTabDecimalPortion : public SwTabPortion
+{
+    const xub_Unicode cTab;
+public:
+    inline SwTabDecimalPortion( const KSHORT nTabPos, const xub_Unicode cTab,
+                                const xub_Unicode cFill = '\0' )
+         : SwTabPortion( nTabPos, cFill ), cTab(cTab)
+    { SetWhichPor( POR_TABDECIMAL ); }
+#ifdef OLDRECYCLE
+    virtual sal_Bool MayRecycle() const;
+#endif
+    inline xub_Unicode GetTabDecimal() const { return cTab; }
+    OUTPUT_OPERATOR
+};
+
+CLASSIO( SwTabPortion )
+CLASSIO( SwTabLeftPortion )
+CLASSIO( SwTabRightPortion )
+CLASSIO( SwTabCenterPortion )
+CLASSIO( SwTabDecimalPortion )
+
+
+#endif
diff --git a/sw/source/core/text/portox.cxx b/sw/source/core/text/portox.cxx
new file mode 100644
index 000000000000..64dd5c2cec7c
--- /dev/null
+++ b/sw/source/core/text/portox.cxx
@@ -0,0 +1,140 @@
+/*************************************************************************
+ *
+ *  $RCSfile: portox.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:26 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "viewopt.hxx"  // SwViewOptions
+#include "segmentc.hxx"
+
+#include "txtcfg.hxx"
+#include "portox.hxx"
+#include "inftxt.hxx"       // GetTxtSize()
+
+/*************************************************************************
+ *               virtual SwToxPortion::Paint()
+ *************************************************************************/
+
+void SwToxPortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+    if( Width() )
+    {
+        rInf.DrawViewOpt( *this, POR_TOX );
+        SwTxtPortion::Paint( rInf );
+    }
+}
+
+/*************************************************************************
+ *                      class SwIsoToxPortion
+ *************************************************************************/
+
+SwLinePortion *SwIsoToxPortion::Compress() { return this; }
+
+SwIsoToxPortion::SwIsoToxPortion() : nViewWidth(0)
+{
+    SetLen(1);
+    SetWhichPor( POR_ISOTOX );
+}
+
+/*************************************************************************
+ *               virtual SwIsoToxPortion::GetViewWidth()
+ *************************************************************************/
+
+KSHORT SwIsoToxPortion::GetViewWidth( const SwTxtSizeInfo &rInf ) const
+{
+    // Wir stehen zwar im const, aber nViewWidth sollte erst im letzten
+    // Moment errechnet werden:
+    SwIsoToxPortion* pThis = (SwIsoToxPortion*)this;
+    // nViewWidth muss errechnet werden.
+    if( !Width() && rInf.OnWin() && rInf.GetOpt().IsTox() )
+    {
+        if( !nViewWidth )
+            pThis->nViewWidth = rInf.GetTxtSize( ' ' ).Width();
+    }
+    else
+        pThis->nViewWidth = 0;
+    return nViewWidth;
+}
+
+/*************************************************************************
+ *                 virtual SwIsoToxPortion::Format()
+ *************************************************************************/
+
+sal_Bool SwIsoToxPortion::Format( SwTxtFormatInfo &rInf )
+{
+    const sal_Bool bFull = SwLinePortion::Format( rInf );
+    return bFull;
+}
+
+/*************************************************************************
+ *               virtual SwIsoToxPortion::Paint()
+ *************************************************************************/
+
+void SwIsoToxPortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+    if( Width() )
+        rInf.DrawViewOpt( *this, POR_TOX );
+}
+
+
diff --git a/sw/source/core/text/portox.hxx b/sw/source/core/text/portox.hxx
new file mode 100644
index 000000000000..993605c74a38
--- /dev/null
+++ b/sw/source/core/text/portox.hxx
@@ -0,0 +1,108 @@
+/*************************************************************************
+ *
+ *  $RCSfile: portox.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:26 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _PORTOX_HXX
+#define _PORTOX_HXX
+
+#include "portxt.hxx"
+//#include "porglue.hxx"
+
+/*************************************************************************
+ *                      class SwToxPortion
+ *************************************************************************/
+
+class SwToxPortion : public SwTxtPortion
+{
+public:
+    inline  SwToxPortion(){ SetWhichPor( POR_TOX ); }
+    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+#ifdef OLDRECYCLE
+    virtual sal_Bool MayRecycle() const { return sal_False; }
+#endif
+    OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ *                      class SwIsoToxPortion
+ *************************************************************************/
+
+class SwIsoToxPortion : public SwToxPortion
+{
+    KSHORT nViewWidth;
+
+public:
+            SwIsoToxPortion();
+    virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+    virtual SwLinePortion *Compress();
+    virtual KSHORT GetViewWidth( const SwTxtSizeInfo &rInf ) const;
+    OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ *                  inline - Implementations
+ *************************************************************************/
+
+CLASSIO( SwToxPortion )
+CLASSIO( SwIsoToxPortion )
+
+
+#endif
diff --git a/sw/source/core/text/portxt.cxx b/sw/source/core/text/portxt.cxx
new file mode 100644
index 000000000000..2016f11dee03
--- /dev/null
+++ b/sw/source/core/text/portxt.cxx
@@ -0,0 +1,745 @@
+/*************************************************************************
+ *
+ *  $RCSfile: portxt.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:26 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include 
+
+#ifndef _HINTIDS_HXX
+#include      // CH_TXTATR
+#endif
+#ifndef _ERRHDL_HXX
+#include    // ASSERT
+#endif
+#ifndef _TXTCFG_HXX
+#include 
+#endif
+#ifndef _PORLAY_HXX
+#include 
+#endif
+#ifndef _INFTXT_HXX
+#include 
+#endif
+#ifndef _GUESS_HXX
+#include     // SwTxtGuess, Zeilenumbruch
+#endif
+#ifndef _PORGLUE_HXX
+#include 
+#endif
+#ifndef _POREXP_HXX
+#include    // HyphPortion
+#endif
+#ifndef _PORRST_HXX
+#include    // SwKernPortion
+#endif
+#ifndef _WRONG_HXX
+#include 
+#endif
+
+#ifdef DEBUG
+const sal_Char *GetLangName( const MSHORT nLang );
+#endif
+
+/*************************************************************************
+ *                      class SwTxtPortion
+ *************************************************************************/
+
+
+
+SwTxtPortion::SwTxtPortion( const SwLinePortion &rPortion )
+  : SwLinePortion( rPortion )
+{
+    SetWhichPor( POR_TXT );
+}
+
+
+
+short SwTxtPortion::GetEscapement() const  { return 0; }
+
+/*************************************************************************
+ *                      SwTxtPortion::BreakCut()
+ *************************************************************************/
+
+
+
+// 4846: IsPunctUnderFlow() loest UnderFlow aus.
+
+sal_Bool SwTxtPortion::IsPunctUnderFlow( const SwTxtSizeInfo &rInf ) const
+{
+    const xub_Unicode cCh = rInf.GetChar( rInf.GetIdx() );
+    //JP 15.08.00: ispunct can't handle characters greater 255 !!! Bug: 77527
+    //              This Code must be changed to the new
+    //              character classification class!
+    return (cCh < 0xff && ispunct( cCh ))
+            && '-' != cCh;
+}
+
+/*************************************************************************
+ *                      SwTxtPortion::BreakCut()
+ *************************************************************************/
+
+
+
+void SwTxtPortion::BreakCut( SwTxtFormatInfo &rInf, const SwTxtGuess &rGuess )
+{
+    // Das Wort/Zeichen ist groesser als die Zeile
+    // Sonderfall Nr.1: Das Wort ist groesser als die Zeile
+    // Wir kappen...
+    const KSHORT nLineWidth = rInf.Width() - rInf.X();
+    xub_StrLen nLen = xub_StrLen( Max( 1L, long( rGuess.RightPos() + 1 - rInf.GetIdx() ) ) );
+    Width( KSHRT_MAX );
+
+    // Wer zu breit ist, den straft das Leben: auf aufwendige
+    // Optimierung wird hier verzichtet.
+    while( nLen && Width() > nLineWidth )
+    {
+        DBG_LOOP;
+        rInf.SetLen( nLen );
+        SetLen( nLen );
+        CalcTxtSize( rInf );
+        --nLen;
+    }
+
+    if( Width() > nLineWidth )
+    {
+        // Sonderfall Nr.2, Zeichen breiter als Zeile
+        // 5057: Am Zeilenanfang wir abgeschnitten, ansonsten
+        // rutscht die Portion in die naechste Zeile
+        // 6721: !rInf.GetIdx() fuer mehrzeilige Felder.
+        if( !rInf.GetIdx() || rInf.GetIdx() == rInf.GetLineStart() )
+            Width( nLineWidth );
+        else
+        {
+            Height( 0 );
+            Width( 0 );
+            SetLen( 0 );
+            SetAscent( 0 );
+            SetPortion( NULL );  // ????
+        }
+    }
+}
+
+/*************************************************************************
+ *                      SwTxtPortion::BreakUnderflow()
+ *************************************************************************/
+
+
+
+void SwTxtPortion::BreakUnderflow( SwTxtFormatInfo &rInf,
+                                   const SwTxtGuess &rGuess,
+                                   const sal_Bool bPunct )
+{
+    // 4846: FtnPortions nehmen das Wort davor mit
+    sal_Bool bUnderFlow = bPunct || rGuess.LeftPos() < rInf.GetIdx();
+    sal_Bool bFtn = sal_False;
+    sal_Bool bNullWidth = sal_False;
+    if( !bUnderFlow && rGuess.LeftPos() == rInf.GetIdx() && IsFtnPortion() )
+        bUnderFlow = bFtn = sal_True;
+    sal_Bool bSoftHyph = sal_False;
+    if( !bUnderFlow && rInf.GetIdx() && !rInf.GetLast()->IsFlyPortion() )
+    {
+        // SonderFall: Durch recycled Portions ist auch folgender
+        // Fall denkbar: {old}{ new}
+        // Bei SoftHyphens laufen wir ins Underflow, um die deutschen
+        // Sondertrennungen zu pruefen.
+        const xub_Unicode cCh = rInf.GetChar( rInf.GetIdx() );
+        bSoftHyph =  ' ' != cCh && rInf.GetLast()->IsSoftHyphPortion();
+        if( bSoftHyph )
+            bUnderFlow = sal_True;
+        else
+        {
+            xub_StrLen nIdx = rInf.GetIdx() - 1;
+            const xub_Unicode cLastCh = rInf.GetChar( nIdx );
+            bUnderFlow = (' ' != cCh && ' ' != cLastCh && CH_BREAK != cLastCh &&
+                            ( '-' != cLastCh ||
+                            !SwTxtGuess::IsWordEnd( rInf, nIdx ) ) );
+            if( bUnderFlow && ( CH_TXTATR_BREAKWORD == cLastCh ||
+                CH_TXTATR_INWORD == cLastCh ) && rInf.HasHint(nIdx) )
+                bUnderFlow = bNullWidth = !rInf.GetLast()->Width();
+        }
+    }
+
+    Truncate();
+
+    // Das ganze Wort passt nicht mehr auf die Zeile
+    if( !bUnderFlow )
+    {
+        // Wir rufen das FormatEOL der letzten Portion.
+        // Damit kommen HardBlanks, SoftHyphs und Tabs zum Zuge.
+        Height( 0 );
+        Width( 0 );
+        SetLen( 0 );
+        SetAscent( 0 );
+        SetPortion( NULL );  // ????
+        rInf.GetLast()->FormatEOL( rInf );
+    }
+    else
+    {
+        // Dieser Teil wird nur betreten, wenn eine Unterlaufsituation
+        // bei Attributen aufgetreten ist: in dem Wort, das nicht mehr
+        // passt, liegt ein Attributwechsel und damit Portionwechsel vor.
+        // Der Umbruch liegt demnach also vor der aktuellen Portion.
+        // Wir muessen uns in die Kette mit aufnehmen, weil
+        // SwTxtFormatter::UnderFlow() wissen muss, wo wieder neu
+        // aufgesetzt werden soll (naemlich vor uns).
+
+        // Wieder mal ein Sonderfall: wenn der Wordbeginn vor unserer Zeile
+        // oder genau am Zeilenbeginn ist, dann schneiden wir ab.
+        const xub_StrLen nWordStart = rGuess.GetPrevEnd(rInf, rGuess.LeftPos());
+        if( !bSoftHyph && (!bFtn || rInf.StopUnderFlow() )
+            && nWordStart <= rInf.GetLineStart() )
+        {
+            if( rInf.GetFly() || rInf.GetLast()->IsFlyPortion()
+                || rInf.IsDropInit() ||
+                ( rInf.StopUnderFlow() && rInf.GetLast()->IsFlyCntPortion() ) )
+            {
+                Height( 0 );
+                Width( 0 );
+                SetLen( 0 );
+                SetAscent( 0 );
+                SetPortion( NULL );  // ????
+                // 3983: {N}ikolaus, Fly rechts drueber haengen
+                if( rInf.GetFly() && nWordStart < rInf.GetIdx() )
+                    Underflow( rInf );
+                else
+                    rInf.GetLast()->FormatEOL( rInf );
+            }
+            else
+                BreakCut( rInf, rGuess );
+        }
+        else
+        {
+            Height( 0 );
+            Width( 0 );
+            SetLen( 0 );
+            SetAscent( 0 );
+            SetPortion( NULL );  // ????
+            if ( bNullWidth )
+            {
+                SwLinePortion *pPor = rInf.GetLast();
+                pPor->Truncate();
+                rInf.SetUnderFlow( pPor );
+            }
+            else
+                Underflow( rInf );
+        }
+    }
+}
+
+/*************************************************************************
+ *                      SwTxtPortion::BreakLine()
+ *************************************************************************/
+
+
+
+void SwTxtPortion::BreakLine( SwTxtFormatInfo &rInf, SwTxtGuess &rGuess )
+{
+    // Dieses Wort passt nicht mehr
+    // Hyphenator ...
+    // Wenn das Wort ueber den Rand hinausragt.
+
+    if( rGuess.HyphWord().is() && IsHyphenate( rInf, rGuess ) )
+    {
+        if ( rInf.GetFly() )
+            rInf.GetRoot()->SetMidHyph( sal_True );
+        else
+            rInf.GetRoot()->SetEndHyph( sal_True );
+        return;
+    }
+
+    // Drei Faelle muessen beachtet werden:
+    // "012 456"    Guess: "2 456"  I:0, L:2 -> " 456" in die naechste Zeile
+    // "{01}2 456"  Guess: "2 456", I:2, L:2 -> " 456" in die naechste Zeile
+    // "{012} 456"  Guess: " 456",  I:3, L:3 -> Underflow
+    // Wer weiss, was jetzt alles schief geht:
+    // old: win090: if( rInf.GetIdx() < rGuess.LeftPos() )
+
+    // Und schon ist es passiert:
+    // 4801: "{Drucken}, das" : "{Drucken}" passt "," ist zuviel ...
+    if( rInf.X() + rGuess.LeftWidth() <= rInf.Width() )
+    {
+        if( rInf.GetIdx() <  rGuess.LeftPos() ||
+           ( rInf.GetIdx() == rGuess.LeftPos() &&
+             rInf.GetIdx() > rInf.GetLineStart() &&
+            rGuess.IsWordEnd( rInf, rInf.GetIdx() ) ) )
+        {
+            // Es wurde noch eine Trennstelle gefunden, oder das Wort
+            // soll komplett in die naechste Zeile
+            Width( rGuess.LeftWidth() );
+            SetLen( rGuess.LeftPos() - rInf.GetIdx() );
+// OLD_ITERATOR
+//          SetLen( rGuess.LeftPos() - rInf.GetIdx() + 1 );
+            return;
+        }
+    }
+
+    // nTxtOfst ist der Original-GetIdx (s.Kommentar vom _Format())
+    // Nur wenn die Portion am Anfang der Zeile steht, dann liegt
+    // u.U. ein Sonderfall vor, der im else-Zweig bearbeitet wird.
+    // Wenn ein Zeilenumbruch emuliert wird (derzeit nur durch Flys),
+    // dann wollen wir aus kosmetischen Gruenden das Wort nicht kappen.
+
+    // Es gibt nur zwei Moeglichkeiten:
+    // BreakUnderFlow:  wir formatieren rueckwaerts.
+    // BreakCut: wir schneiden gnadenlos ab.
+
+
+    // 5010: Exp und Tabs
+    sal_Bool bFirstPor = sal_True;
+
+    // Nur bei Feldern muss noch einmal geprueft werden,
+    // ob wir pFirstPor sind.
+    if( InExpGrp() )
+    {
+        const SwLinePortion *pPor = rInf.GetRoot();
+        while( pPor && bFirstPor )
+        {
+            bFirstPor = 0 == pPor->GetLen();
+            pPor = pPor->GetPortion();
+        }
+    }
+    else
+        bFirstPor = rInf.GetLineStart() == rInf.GetIdx();
+
+    // 8790: erste Portion hat Vorrang vor bPunct, sonst wird
+    // fuer die ein "(xxx)" am Zeilenanfang ein Dauer-Underflow erzeugt.
+    // 8790: Flys emulieren Zeilenumbrueche, das bricht uns das Genick
+    // Robust:
+    if ( !rInf.GetLast() )
+        rInf.SetLast( rInf.GetRoot() );
+
+    bFirstPor = bFirstPor && !rInf.IsDropInit();
+
+    if( ( !bFirstPor || rInf.GetFly() || rInf.GetLast()->IsFlyPortion() ) &&
+        ( !rInf.GetLast()->IsBlankPortion() ||  ((SwBlankPortion*)
+          rInf.GetLast())->MayUnderFlow( rInf, rInf.GetIdx()-1, sal_True ) ) )
+    {
+        sal_Bool bPunct = !bFirstPor && IsPunctUnderFlow( rInf ) &&
+                      !rInf.GetLast()->IsFlyPortion();
+        BreakUnderflow( rInf, rGuess, bPunct );
+    }
+    else
+        BreakCut( rInf, rGuess );
+}
+
+/*************************************************************************
+ *                      SwTxtPortion::_Format()
+ *************************************************************************/
+// nTxtOfst ist das Original-GetIdx(). Wenn der Text ersetzt wurde, dann
+// sind nIdx und Len an den Ersatzstring angepasst. In BreakLine() muessen
+// wir jedoch entscheiden, ob ein Wort komplett in die naechste Zeile soll,
+// oder ob ein Sonderfall vorliegt.
+
+
+
+sal_Bool SwTxtPortion::_Format( SwTxtFormatInfo &rInf )
+{
+    // 5744: wenn nur der Trennstrich nicht mehr passt,
+    // muss trotzdem das Wort umgebrochen werden, ansonsten return sal_True!
+    if( rInf.IsUnderFlow() && rInf.GetSoftHyphPos() )
+        if( FormatHyph( rInf ) )
+            return sal_True;
+
+    SwTxtGuess aGuess;
+    const sal_Bool bFull = !aGuess.Guess( rInf, Height() );
+    if( !InExpGrp() || IsFtnPortion() )
+        Height( aGuess.Height() );
+    if( bFull )
+        BreakLine( rInf, aGuess );
+    else
+    {
+        Width( aGuess.LeftWidth() );
+        // Vorsicht !
+        if( !InExpGrp() || InFldGrp() )
+            SetLen( aGuess.LeftPos() - rInf.GetIdx() + 1 );
+#ifdef DBGTXT
+        const SwPosSize aSize( GetTxtSize( rInf ) );
+        if( aSize.Width() != Width() || aSize.Height() != Height() )
+        {
+            aDbstream << "Format: diff size: "
+                      << aSize.Width()  << "!=" << Width()  << ' '
+                      << aSize.Height() << "!=" << Height() << endl;
+        }
+#endif
+        short nKern = rInf.GetFont()->CheckKerning();
+        if( nKern > 0 && rInf.Width() < rInf.X() + Width() + nKern )
+        {
+            nKern = rInf.Width() - rInf.X() - Width();
+            if( nKern < 0 )
+                nKern = 0;
+        }
+        if( nKern )
+            new SwKernPortion( *this, nKern );
+    }
+    return bFull;
+}
+
+/*************************************************************************
+ *                 virtual SwTxtPortion::Format()
+ *************************************************************************/
+
+
+
+sal_Bool SwTxtPortion::Format( SwTxtFormatInfo &rInf )
+{
+#ifdef DEBUG
+    const XubString aDbgTxt( rInf.GetTxt().Copy( rInf.GetIdx(), rInf.GetLen() ) );
+#endif
+
+    if( rInf.X() > rInf.Width() || (!GetLen() && !InExpGrp()) )
+    {
+        Height( 0 );
+        Width( 0 );
+        SetLen( 0 );
+        SetAscent( 0 );
+        SetPortion( NULL );  // ????
+        return sal_True;
+    }
+
+    ASSERT( rInf.RealWidth() || (rInf.X() == rInf.Width()),
+        "SwTxtPortion::Format: missing real width" );
+    ASSERT( Height(), "SwTxtPortion::Format: missing height" );
+
+    return _Format( rInf );
+}
+
+/*************************************************************************
+ *                 virtual SwTxtPortion::FormatEOL()
+ *************************************************************************/
+
+// Format end of line
+// 5083: Es kann schon manchmal unguenstige Faelle geben...
+// "vom {Nikolaus}", Nikolaus bricht um "vom " wird im Blocksatz
+// zu "vom" und " ", wobei der Glue expandiert wird, statt in die
+// MarginPortion aufzugehen.
+// rInf.nIdx steht auf dem naechsten Wort, nIdx-1 ist der letzte
+// Buchstabe der Portion.
+
+
+
+void SwTxtPortion::FormatEOL( SwTxtFormatInfo &rInf )
+{
+#ifndef USED
+    if( ( !GetPortion() || ( GetPortion()->IsKernPortion() &&
+        !GetPortion()->GetPortion() ) ) && GetLen() &&
+        rInf.GetIdx() < rInf.GetTxt().Len() &&
+        1 < rInf.GetIdx() && ' ' == rInf.GetChar( rInf.GetIdx() - 1 )
+#else
+    if( !GetPortion() && 1 < GetLen() &&
+        rInf.GetIdx() < rInf.GetTxt().Len() &&
+        1 < rInf.GetIdx() && ' ' == rInf.GetTxt()[xub_StrLen(rInf.GetIdx()-1)]
+        && !rInf.GetFly()
+#endif
+
+        && !rInf.GetLast()->IsHolePortion() )
+    {
+        // Erst uns einstellen und dann Inserten, weil wir ja auch ein
+        // SwLineLayout sein koennten.
+        KSHORT nBlankSize;
+        if(1 == GetLen())
+            nBlankSize = Width();
+        else
+            nBlankSize = rInf.GetTxtSize( ' ' ).Width();
+        Width( Width() - nBlankSize );
+        rInf.X( rInf.X() - nBlankSize );
+        SetLen( GetLen() - 1 );
+        SwLinePortion *pHole = new SwHolePortion( *this );
+        ( (SwHolePortion *)pHole )->SetBlankWidth( nBlankSize );
+        Insert( pHole );
+    }
+}
+
+/*************************************************************************
+ *                 virtual SwTxtPortion::Underflow()
+ *************************************************************************/
+// Underflow() wird innerhalb des Formatierungsprozesses gerufen,
+// wenn diese Portion nicht mehr passt und die Vorgaengerportion
+// formatiert werden muss (haeufig bei HardBlank, SoftHyph).
+// Wir stellen rInf ein und initialisieren uns.
+
+
+
+sal_Bool SwTxtPortion::Underflow( SwTxtFormatInfo &rInf )
+{
+    Truncate();
+    rInf.SetUnderFlow( this );
+    return sal_True;
+}
+
+/*************************************************************************
+ *               virtual SwTxtPortion::GetCrsrOfst()
+ *************************************************************************/
+
+
+
+xub_StrLen SwTxtPortion::GetCrsrOfst( const KSHORT nOfst ) const
+{
+    ASSERT( !this, "SwTxtPortion::GetCrsrOfst: don't use this method!" );
+    return SwLinePortion::GetCrsrOfst( nOfst );
+}
+
+/*************************************************************************
+ *               SwTxtPortion::GetCrsrOfst()
+ *************************************************************************/
+
+
+
+xub_StrLen SwTxtPortion::GetCrsrOfst( const KSHORT nOfst,
+                                  SwTxtSizeInfo &rSizeInf ) const
+{
+    rSizeInf.SetLen( rSizeInf.GetTxtBreak( nOfst, rSizeInf.GetIdx(),
+        nLineLength ) - rSizeInf.GetIdx() );
+    return rSizeInf.GetLen();
+}
+
+/*************************************************************************
+ *                virtual SwTxtPortion::GetTxtSize()
+ *************************************************************************/
+// Das GetTxtSize() geht davon aus, dass die eigene Laenge korrekt ist
+
+
+
+SwPosSize SwTxtPortion::GetTxtSize( const SwTxtSizeInfo &rInf ) const
+{
+    return rInf.GetTxtSize();
+}
+
+/*************************************************************************
+ *               virtual SwTxtPortion::Paint()
+ *************************************************************************/
+
+
+
+void SwTxtPortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+    if( GetLen() )
+    {
+        rInf.DrawBackBrush( *this );
+        const SwWrongList *pWrongList = rInf.GetpWrongList();
+        if ( pWrongList )
+            rInf.DrawWrongText( *this, rInf.GetLen(), sal_False );
+        else
+            rInf.DrawText( *this, rInf.GetLen(), sal_False );
+    }
+}
+
+/*************************************************************************
+ *              virtual SwTxtPortion::GetExpTxt()
+ *************************************************************************/
+
+
+
+sal_Bool SwTxtPortion::GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const
+{
+    return sal_False;
+}
+
+/*************************************************************************
+ *        xub_StrLen SwTxtPortion::GetSpaceCnt()
+ *              long SwTxtPortion::CalcSpacing()
+ * sind fuer den Blocksatz zustaendig und ermitteln die Anzahl der Blanks
+ * und den daraus resultierenden zusaetzlichen Zwischenraum
+ *************************************************************************/
+
+
+
+xub_StrLen SwTxtPortion::GetSpaceCnt( const SwTxtSizeInfo &rInf,
+                                      xub_StrLen& rCharCnt ) const
+{
+    xub_StrLen nCnt = 0;
+    xub_StrLen nPos = 0;
+    if ( InExpGrp() )
+    {
+        if( !IsBlankPortion() && !InNumberGrp() )
+        {
+            // Bei OnWin() wird anstatt eines Leerstrings gern mal ein Blank
+            // zurueckgeliefert, das koennen wir hier aber gar nicht gebrauchen
+            sal_Bool bOldOnWin = rInf.OnWin();
+            ((SwTxtSizeInfo &)rInf).SetOnWin( sal_False );
+
+            XubString aStr( aEmptyStr );
+            GetExpTxt( rInf, aStr );
+            ((SwTxtSizeInfo &)rInf).SetOnWin( bOldOnWin );
+            for ( nPos = 0; nPos < aStr.Len(); ++nPos )
+            {
+                if( CH_BLANK == aStr.GetChar( nPos ) )
+                    ++nCnt;
+            }
+        }
+    }
+    else if( !IsDropPortion() )
+    {
+        xub_StrLen nEndPos = rInf.GetIdx() + GetLen();
+        for ( nPos = rInf.GetIdx(); nPos < nEndPos; ++nPos )
+        {
+            if( CH_BLANK == rInf.GetChar( nPos ) )
+                ++nCnt;
+        }
+        nPos = GetLen();
+    }
+    rCharCnt += nPos;
+    return nCnt;
+}
+
+
+
+long SwTxtPortion::CalcSpacing( short nSpaceAdd, const SwTxtSizeInfo &rInf ) const
+{
+    xub_StrLen nCnt = 0;
+    if ( InExpGrp() )
+    {
+        if( !IsBlankPortion() && !InNumberGrp() )
+        {
+            // Bei OnWin() wird anstatt eines Leerstrings gern mal ein Blank
+            // zurueckgeliefert, das koennen wir hier aber gar nicht gebrauchen
+            sal_Bool bOldOnWin = rInf.OnWin();
+            ((SwTxtSizeInfo &)rInf).SetOnWin( sal_False );
+
+            XubString aStr( aEmptyStr );
+            GetExpTxt( rInf, aStr );
+            ((SwTxtSizeInfo &)rInf).SetOnWin( bOldOnWin );
+            if( nSpaceAdd > 0 )
+            {
+                for ( xub_StrLen nPos = 0; nPos < aStr.Len(); ++nPos )
+                {
+                    if( CH_BLANK == aStr.GetChar( nPos ) )
+                        ++nCnt;
+                }
+            }
+            else
+            {
+                nSpaceAdd = -nSpaceAdd;
+                nCnt = aStr.Len();
+            }
+        }
+    }
+    else if( !IsDropPortion() )
+    {
+        if( nSpaceAdd > 0 )
+        {
+            xub_StrLen nEndPos = rInf.GetIdx() + GetLen();
+            for ( xub_StrLen nPos = rInf.GetIdx(); nPos < nEndPos; ++nPos )
+            {
+                if( CH_BLANK == rInf.GetChar( nPos ) )
+                    ++nCnt;
+            }
+        }
+        else
+        {
+            nSpaceAdd = -nSpaceAdd;
+            nCnt = GetLen();
+        }
+    }
+    return nCnt * nSpaceAdd;
+}
+
+/*************************************************************************
+ *                      class SwHolePortion
+ *************************************************************************/
+
+
+
+SwHolePortion::SwHolePortion( const SwTxtPortion &rPor )
+    : nBlankWidth( 0 )
+{
+    SetLen( 1 );
+    Height( rPor.Height() );
+    SetAscent( rPor.GetAscent() );
+    SetWhichPor( POR_HOLE );
+}
+
+#ifdef OLDRECYCLE
+
+
+
+sal_Bool SwHolePortion::MayRecycle() const { return sal_False; }
+
+#endif
+
+
+
+SwLinePortion *SwHolePortion::Compress() { return this; }
+
+/*************************************************************************
+ *               virtual SwHolePortion::Paint()
+ *************************************************************************/
+
+
+
+void SwHolePortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+}
+
+/*************************************************************************
+ *                 virtual SwHolePortion::Format()
+ *************************************************************************/
+
+
+
+sal_Bool SwHolePortion::Format( SwTxtFormatInfo &rInf )
+{
+    return rInf.IsFull() || rInf.X() >= rInf.Width();
+}
+
diff --git a/sw/source/core/text/portxt.hxx b/sw/source/core/text/portxt.hxx
new file mode 100644
index 000000000000..aff9a67d98e5
--- /dev/null
+++ b/sw/source/core/text/portxt.hxx
@@ -0,0 +1,139 @@
+/*************************************************************************
+ *
+ *  $RCSfile: portxt.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:26 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _PORTXT_HXX
+#define _PORTXT_HXX
+
+#ifdef GCC
+#include 
+#else
+#include     //fuer size_t, FIXEDMEM aus tools
+#endif
+#ifndef _SVMEMPOOL_HXX //autogen
+#include 
+#endif
+
+#include "porlin.hxx"
+
+class SwTxtGuess;
+
+/*************************************************************************
+ *                      class SwTxtPortion
+ *************************************************************************/
+
+class SwTxtPortion : public SwLinePortion
+{
+    sal_Bool IsPunctUnderFlow( const SwTxtSizeInfo &rInf ) const;
+    void BreakCut( SwTxtFormatInfo &rInf, const SwTxtGuess &rGuess );
+    void BreakUnderflow( SwTxtFormatInfo &rInf, const SwTxtGuess &rGuess,
+                         const sal_Bool bPunct );
+    void BreakLine( SwTxtFormatInfo &rInf, SwTxtGuess &rGuess );
+    sal_Bool FormatHyph( SwTxtFormatInfo &rInf );
+    sal_Bool _Format( SwTxtFormatInfo &rInf );
+
+public:
+    inline SwTxtPortion(){ SetWhichPor( POR_TXT ); }
+    SwTxtPortion( const SwLinePortion &rPortion );
+    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+    virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+    virtual void FormatEOL( SwTxtFormatInfo &rInf );
+    virtual sal_Bool Underflow( SwTxtFormatInfo &rInf );
+    virtual xub_StrLen GetCrsrOfst( const KSHORT nOfst ) const;
+    virtual SwPosSize GetTxtSize( const SwTxtSizeInfo &rInfo ) const;
+    virtual sal_Bool GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const;
+    virtual short GetEscapement() const;
+
+    // zaehlt die Spaces fuer Blocksatz
+    xub_StrLen GetSpaceCnt( const SwTxtSizeInfo &rInf, xub_StrLen& rCnt ) const;
+    long CalcSpacing( short nSpaceAdd, const SwTxtSizeInfo &rInf ) const;
+    xub_StrLen GetCrsrOfst( const KSHORT nOfst, SwTxtSizeInfo &rSizeInf ) const;
+
+    sal_Bool IsHyphenate( SwTxtFormatInfo &rInf, SwTxtGuess &rGuess );
+
+    OUTPUT_OPERATOR
+    DECL_FIXEDMEMPOOL_NEWDEL(SwTxtPortion)
+};
+
+/*************************************************************************
+ *                      class SwHolePortion
+ *************************************************************************/
+
+class SwHolePortion : public SwLinePortion
+{
+    KSHORT nBlankWidth;
+public:
+            SwHolePortion( const SwTxtPortion &rPor );
+    inline const KSHORT GetBlankWidth( ) const { return nBlankWidth; }
+    inline void SetBlankWidth( const KSHORT nNew ) { nBlankWidth = nNew; }
+#ifdef OLDRECYCLE
+    virtual sal_Bool MayRecycle() const;
+#endif
+    virtual SwLinePortion *Compress();
+    virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+    virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+    OUTPUT_OPERATOR
+    DECL_FIXEDMEMPOOL_NEWDEL(SwHolePortion)
+};
+
+CLASSIO( SwTxtPortion )
+CLASSIO( SwHolePortion )
+
+
+#endif
diff --git a/sw/source/core/text/possiz.hxx b/sw/source/core/text/possiz.hxx
new file mode 100644
index 000000000000..5a1fb2ad1ca1
--- /dev/null
+++ b/sw/source/core/text/possiz.hxx
@@ -0,0 +1,120 @@
+/*************************************************************************
+ *
+ *  $RCSfile: possiz.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:26 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _POSSIZ_HXX
+#define _POSSIZ_HXX
+
+
+#ifndef _GEN_HXX //autogen
+#include 
+#endif
+#include "txttypes.hxx"
+
+// Im Gegensazt zu den SV-Sizes ist die SwPosSize immer positiv
+class SwPosSize
+{
+    KSHORT nWidth;
+    KSHORT nHeight;
+public:
+    inline SwPosSize( const KSHORT nWidth = 0, const KSHORT nHeight = 0 )
+        : nWidth(nWidth), nHeight(nHeight) { }
+    inline SwPosSize( const Size &rSize )
+        : nWidth(KSHORT(rSize.Width())), nHeight(KSHORT(rSize.Height())){ }
+    inline KSHORT Height() const { return nHeight; }
+    inline void Height( const KSHORT nNew ) { nHeight = nNew; }
+    inline KSHORT Width() const { return nWidth; }
+    inline void Width( const KSHORT nNew ) { nWidth = nNew; }
+
+    inline Size SvLSize() const { return Size( nWidth, nHeight ); }
+    inline void SvLSize( const Size &rSize );
+    inline sal_Bool operator==( const SwPosSize &rSize ) const;
+    inline SwPosSize &operator=( const SwPosSize &rSize );
+    inline SwPosSize &operator=( const Size &rSize );
+};
+
+inline sal_Bool SwPosSize::operator==(const SwPosSize &rSize ) const
+{
+    return( Height() == rSize.Height() &&
+            Width() == rSize.Width() );
+}
+
+inline SwPosSize &SwPosSize::operator=(const SwPosSize &rSize )
+{
+    nWidth  = rSize.Width();
+    nHeight = rSize.Height();
+    return *this;
+}
+
+inline void SwPosSize::SvLSize( const Size &rSize )
+{
+    nWidth  = KSHORT(rSize.Width());
+    nHeight = KSHORT(rSize.Height());
+}
+
+inline SwPosSize &SwPosSize::operator=( const Size &rSize )
+{
+    nWidth  = KSHORT(rSize.Width());
+    nHeight = KSHORT(rSize.Height());
+    return *this;
+}
+
+
+#endif
+
diff --git a/sw/source/core/text/redlnitr.cxx b/sw/source/core/text/redlnitr.cxx
new file mode 100644
index 000000000000..1ea4aaa34394
--- /dev/null
+++ b/sw/source/core/text/redlnitr.cxx
@@ -0,0 +1,558 @@
+/*************************************************************************
+ *
+ *  $RCSfile: redlnitr.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:26 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "hintids.hxx"
+
+#ifndef _SFX_WHITER_HXX //autogen
+#include 
+#endif
+#ifndef _SHL_HXX
+#include 
+#endif
+
+#include "swmodule.hxx"
+
+#include "redline.hxx"      // SwRedline
+#include "txtatr.hxx"       // SwTxt ...
+#include "docary.hxx"       // SwRedlineTbl
+#include "itratr.hxx"       // SwAttrIter
+#include "ndtxt.hxx"        // SwTxtNode
+#include "swfntcch.hxx"     // SwFontAccess
+#include "doc.hxx"          // SwDoc
+#include "txatbase.hxx"     // SwTxtAttr
+#include "rootfrm.hxx"
+#include "frmsh.hxx"
+
+
+//////////////////////////
+
+#ifndef _SV_KEYCODES_HXX //autogen
+#include 
+#endif
+#ifndef _VCL_CMDEVT_HXX //autogen
+#include 
+#endif
+
+#ifndef _SV_SETTINGS_HXX //autogen
+#include 
+#endif
+
+#ifndef _APP_HXX //autogen
+#include 
+#endif
+
+#include "redlnitr.hxx"
+#include "extinput.hxx"
+
+/*************************************************************************
+ *                      SwAttrIter::CtorInit()
+ *************************************************************************/
+
+void SwAttrIter::CtorInit( SwTxtNode& rTxtNode )
+{
+    // Beim HTML-Import kann es vorkommen, dass kein Layout existiert.
+    SwRootFrm *pRootFrm = rTxtNode.GetDoc()->GetRootFrm();
+    pShell = pRootFrm ? pRootFrm->GetShell() : 0;
+
+    pAttrSet = &rTxtNode.GetSwAttrSet();
+    pHints = rTxtNode.GetpSwpHints();
+    delete pFnt;
+    if ( rTxtNode.HasSwAttrSet() )
+    {
+        // Hier wird noch ein weiterer Cache eingebaut werden,
+        // der ueber ein paar SfxItemSets sucht.
+        pFnt = new SwFont( pAttrSet );
+        pMagicNo = 0;
+    }
+    else
+    {
+//FEATURE::CONDCOLL
+//      SwFontAccess aFontAccess( rTxtNode.GetFmtColl() );
+        SwFontAccess aFontAccess( &rTxtNode.GetAnyFmtColl(), pShell );
+//FEATURE::CONDCOLL
+        pFnt = new SwFont( *aFontAccess.Get()->GetFont() );
+        pFnt->ChkMagic( pShell, pFnt->GetActual() );
+        pFnt->GetMagic( pMagicNo, nFntIdx, pFnt->GetActual() );
+    }
+    nStartIndex = nEndIndex = nPos = nChgCnt = 0;
+    SwDoc* pDoc = rTxtNode.GetDoc();
+
+    const SwExtTextInput* pExtInp = pDoc->GetExtTextInput( rTxtNode );
+    sal_Bool bShow = ::IsShowChanges( pDoc->GetRedlineMode() );
+    if( pExtInp || bShow || (SwHoriOrient)SW_MOD()->GetRedlineMarkPos() != HORI_NONE )
+    {
+        MSHORT nRedlPos = pDoc->GetRedlinePos( rTxtNode );
+        if( pExtInp || MSHRT_MAX != nRedlPos )
+        {
+            const SvUShorts* pArr = 0;
+            xub_StrLen nInputStt = 0;
+            if( pExtInp )
+            {
+                pArr = &pExtInp->GetAttrs();
+                nInputStt = pExtInp->Start()->nContent.GetIndex();
+            }
+
+            pRedln = new SwRedlineItr( rTxtNode, *pFnt, nRedlPos, bShow,
+                                        pArr, nInputStt );
+            if( pRedln->IsOn() )
+                ++nChgCnt;
+        }
+    }
+}
+
+/*************************************************************************
+ * SwRedlineItr - Der Redline-Iterator
+ *
+ * Folgende Informationen/Zustaende gibt es im RedlineIterator:
+ *
+ * nFirst ist der erste Index der RedlineTbl, der mit dem Absatz ueberlappt.
+ *
+ * nAct ist der zur Zeit aktive ( wenn bOn gesetzt ist ) oder der naechste
+ * in Frage kommende Index.
+ * nStart und nEnd geben die Grenzen des Objekts innerhalb des Absatzes an.
+ *
+ * Wenn bOn gesetzt ist, ist der Font entsprechend manipuliert worden.
+ *
+ * Wenn nAct auf MSHRT_MAX gesetzt wurde ( durch Reset() ), so ist zur Zeit
+ * kein Redline aktiv, nStart und nEnd sind invalid.
+ *************************************************************************/
+
+SwRedlineItr::SwRedlineItr( const SwTxtNode& rTxtNd, SwFont& rFnt, MSHORT nRed,
+    sal_Bool bShw, const SvUShorts *pArr, xub_StrLen nExtStart )
+    : rDoc( *rTxtNd.GetDoc() ), rNd( rTxtNd ),
+      nNdIdx( rTxtNd.GetIndex() ), nFirst( nRed ),
+      nAct( MSHRT_MAX ), bOn( sal_False ), pSet(0), bShow( bShw )
+{
+    if( pArr )
+        pExt = new SwExtend( *pArr, nExtStart );
+    else
+        pExt = NULL;
+    Seek( rFnt, 0, STRING_LEN );
+}
+
+SwRedlineItr::~SwRedlineItr()
+{
+    Clear( NULL );
+    delete pSet;
+    delete pExt;
+}
+
+void SwRedlineItr::CalcStartEnd()
+{
+    const SwRedline* pTmp = rDoc.GetRedlineTbl()[ nAct ];
+    const SwPosition *pRStt = pTmp->Start(), *pREnd = pTmp->End();
+    if( pRStt->nNode < nNdIdx )
+    {
+        if( pREnd->nNode > nNdIdx )
+        {
+            nStart = 0;             // Absatz ist komplett enthalten
+            nEnd = STRING_LEN;
+        }
+        else
+        {
+            ASSERT( pREnd->nNode == nNdIdx,
+                "SwRedlineItr::Seek: GetRedlinePos Error" );
+            nStart = 0;             // Absatz wird vorne ueberlappt
+            nEnd = pREnd->nContent.GetIndex();
+        }
+    }
+    else if( pRStt->nNode == nNdIdx )
+    {
+        nStart = pRStt->nContent.GetIndex();
+        if( pREnd->nNode == nNdIdx )
+            nEnd = pREnd->nContent.GetIndex(); // Innerhalb des Absatzes
+        else
+            nEnd = STRING_LEN;      // Absatz wird hinten ueberlappt
+    }
+    else
+    {
+        nStart = STRING_LEN;
+        nEnd = STRING_LEN;
+    }
+}
+
+// Der Return-Wert von SwRedlineItr::Seek gibt an, ob der aktuelle Font
+// veraendert wurde durch Verlassen (-1) oder Betreten eines Bereichs (+1)
+
+short SwRedlineItr::_Seek( SwFont& rFnt, xub_StrLen nNew, xub_StrLen nOld )
+{
+    short nRet = 0;
+    if( ExtOn() )
+    {
+        if( !LeaveExtend( rFnt, nNew ) )
+            return 0; // Abkuerzung: wenn wir innerhalb eines ExtendTextInputs sind
+            // kann es keine anderen Attributwechsel (auch nicht durch Redlining) geben
+        ++nRet;
+    }
+    if( bShow )
+    {
+        if( bOn )
+        {
+            if( nNew >= nEnd )
+            {
+                --nRet;
+                _Clear( &rFnt );    // Wir gehen hinter den aktuellen Bereich
+                ++nAct;             // und pruefen gleich den naechsten
+            }
+            else if( nNew < nStart )
+            {
+                --nRet;
+                _Clear( &rFnt );    // Wir gehen vor den aktuellen Bereich
+                if( nAct > nFirst )
+                    nAct = nFirst;  // Die Pruefung muss von vorne beginnen
+                else
+                    return nRet + EnterExtend( rFnt, nNew ); // Es gibt keinen vor uns.
+            }
+            else
+                return nRet + EnterExtend( rFnt, nNew ); // Wir sind im gleichen Bereich geblieben.
+        }
+        if( MSHRT_MAX == nAct || nOld > nNew )
+            nAct = nFirst;
+
+        nStart = STRING_LEN;
+        nEnd = STRING_LEN;
+
+        for( ; nAct < rDoc.GetRedlineTbl().Count() ; ++nAct )
+        {
+            CalcStartEnd();
+            if( nNew < nEnd )
+            {
+                if( nNew >= nStart ) // der einzig moegliche Kandidat
+                {
+                    bOn = sal_True;
+                    const SwRedline *pRed = rDoc.GetRedlineTbl()[ nAct ];
+
+                    if (pSet)
+                        pSet->ClearItem();
+                    else
+                    {
+                        SwAttrPool& rPool = (SwAttrPool& )rDoc.GetAttrPool();
+                        pSet = new SfxItemSet(rPool, RES_CHRATR_BEGIN, RES_CHRATR_END-1);
+                    }
+
+                    if( 1 < pRed->GetStackCount() )
+                        FillHints( pRed->GetAuthor( 1 ), pRed->GetType( 1 ) );
+                    FillHints( pRed->GetAuthor(), pRed->GetType() );
+
+                    SfxWhichIter aIter( *pSet );
+                    register MSHORT nWhich = aIter.FirstWhich();
+                    while( nWhich )
+                    {
+                        const SfxPoolItem* pItem;
+                        if( ( nWhich < RES_CHRATR_END ) &&
+                            ( SFX_ITEM_SET == pSet->GetItemState( nWhich, sal_True, &pItem ) ) )
+                        {
+                            SwTxtAttr* pAttr = ((SwTxtNode&)rNd).MakeTmpTxtAttr(*pItem);
+                            aHints.C40_INSERT( SwTxtAttr, pAttr, aHints.Count());
+                            pAttr->ChgFnt( &rFnt );
+                            if( RES_CHRATR_COLOR == nWhich )
+                                rFnt.SetNoCol( sal_True );
+                        }
+                        nWhich = aIter.NextWhich();
+                    }
+
+                    ++nRet;
+                }
+                break;
+            }
+            nStart = STRING_LEN;
+            nEnd = STRING_LEN;
+        }
+    }
+    return nRet + EnterExtend( rFnt, nNew );
+}
+
+void SwRedlineItr::FillHints( MSHORT nAuthor, SwRedlineType eType )
+{
+    switch ( eType )
+    {
+        case REDLINE_INSERT:
+            SW_MOD()->GetInsertAuthorAttr(nAuthor, *pSet);
+            break;
+        case REDLINE_DELETE:
+            SW_MOD()->GetDeletedAuthorAttr(nAuthor, *pSet);
+            break;
+        case REDLINE_FORMAT:
+        case REDLINE_FMTCOLL:
+            SW_MOD()->GetFormatAuthorAttr(nAuthor, *pSet);
+            break;
+    }
+}
+
+void SwRedlineItr::_ChangeTxtAttr( SwFont* pFnt, SwTxtAttr &rHt, sal_Bool bChg )
+{
+    ASSERT( IsOn(), "SwRedlineItr::ChangeTxtAttr: Off?" );
+    if( ExtOn() )
+        pExt->ChangeTxtAttr( rHt, bChg );
+    MSHORT nWhich = rHt.Which();
+    MSHORT i;
+    if( RES_TXTATR_CHARFMT == nWhich || RES_TXTATR_INETFMT == nWhich )
+    {
+        for( i = 0; i < aHints.Count(); ++i )
+            aHints[ i ]->RstFnt( pFnt );
+        if( bChg )
+            rHt.ChgFnt( pFnt );
+        else
+            rHt.RstFnt( pFnt );
+        for( i = 0; i < aHints.Count(); ++i )
+            aHints[ i ]->ChgFnt( pFnt );
+    }
+    else
+    {
+        for( i = 0; i < aHints.Count(); ++i )
+        {
+            SwTxtAttr *pPos = aHints[ i ];
+            if( pPos->Which() == nWhich )
+            {
+                if( bChg )
+                    rHt.ChgTxtAttr( *pPos );
+                else
+                    rHt.RstTxtAttr( *pPos );
+                return;
+            }
+        }
+        if( bChg )
+            rHt.ChgFnt( pFnt );
+        else
+            rHt.RstFnt( pFnt );
+    }
+}
+
+void SwRedlineItr::_Clear( SwFont* pFnt )
+{
+    ASSERT( bOn, "SwRedlineItr::Clear: Off?" );
+    bOn = sal_False;
+    while( aHints.Count() )
+    {
+        SwTxtAttr *pPos = aHints[ 0 ];
+        aHints.Remove(0);
+        if( pFnt )
+            pPos->RstFnt( pFnt );
+        delete pPos;
+    }
+    if( pFnt )
+        pFnt->SetNoCol( sal_False );
+}
+
+xub_StrLen SwRedlineItr::_GetNextRedln( xub_StrLen nNext )
+{
+    nNext = NextExtend( nNext );
+    if( !bShow || MSHRT_MAX == nFirst )
+        return nNext;
+    if( MSHRT_MAX == nAct )
+    {
+        nAct = nFirst;
+        CalcStartEnd();
+    }
+    if( bOn || !nStart )
+    {
+        if( nEnd < nNext )
+            nNext = nEnd;
+    }
+    else if( nStart < nNext )
+        nNext = nStart;
+    return nNext;
+}
+
+sal_Bool SwRedlineItr::_ChkSpecialUnderline() const
+{
+    // Wenn die Unterstreichung oder das Escapement vom Redling kommt,
+    // wenden wir immer das SpecialUnderlining, d.h. die Unterstreichung
+    // unter der Grundlinie an.
+    for( MSHORT i = 0; i < aHints.Count(); ++i )
+    {
+        SwTxtAttr *pPos = aHints[ i ];
+        MSHORT nWhich = aHints[i]->Which();
+        if( RES_CHRATR_UNDERLINE == nWhich ||
+            RES_CHRATR_ESCAPEMENT == nWhich )
+            return sal_True;
+    }
+    return sal_False;
+}
+
+sal_Bool SwRedlineItr::CheckLine( xub_StrLen nChkStart, xub_StrLen nChkEnd )
+{
+    if( nFirst == MSHRT_MAX )
+        return sal_False;
+    if( nChkEnd == nChkStart ) // Leerzeilen gucken ein Zeichen weiter.
+        ++nChkEnd;
+    xub_StrLen nOldStart = nStart;
+    xub_StrLen nOldEnd = nEnd;
+    xub_StrLen nOldAct = nAct;
+    sal_Bool bRet = sal_False;
+
+    for( nAct = nFirst; nAct < rDoc.GetRedlineTbl().Count() ; ++nAct )
+    {
+        CalcStartEnd();
+        if( nChkEnd < nStart )
+            break;
+        if( nChkStart <= nEnd && ( nChkEnd > nStart || STRING_LEN == nEnd ) )
+        {
+            bRet = sal_True;
+            break;
+        }
+    }
+
+    nStart = nOldStart;
+    nEnd = nOldEnd;
+    nAct = nOldAct;
+    return bRet;
+}
+
+void SwExtend::ActualizeFont( SwFont &rFnt, MSHORT nAttr )
+{
+    if ( nAttr & EXTTEXTINPUT_ATTR_UNDERLINE )
+        rFnt.SetUnderline( UNDERLINE_SINGLE );
+    else if ( nAttr & EXTTEXTINPUT_ATTR_BOLDUNDERLINE )
+        rFnt.SetUnderline( UNDERLINE_BOLD );
+    else if ( nAttr & EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE )
+        rFnt.SetUnderline( UNDERLINE_DOTTED );
+    else if ( nAttr & EXTTEXTINPUT_ATTR_DASHDOTUNDERLINE )
+        rFnt.SetUnderline( UNDERLINE_DOTTED );
+
+    if ( nAttr & EXTTEXTINPUT_ATTR_REDTEXT )
+        rFnt.SetColor( Color( COL_RED ) );
+
+    if ( nAttr & EXTTEXTINPUT_ATTR_HIGHLIGHT )
+    {
+        const StyleSettings& rStyleSettings = GetpApp()->GetSettings().GetStyleSettings();
+        rFnt.SetColor( rStyleSettings.GetHighlightTextColor() );
+        rFnt.SetFillColor( rStyleSettings.GetHighlightColor() );
+        rFnt.SetTransparent( sal_False );
+    }
+    if ( nAttr & EXTTEXTINPUT_ATTR_GRAYWAVELINE )
+        rFnt.SetGreyWave( sal_True );
+}
+
+short SwExtend::Enter( SwFont& rFnt, xub_StrLen nNew )
+{
+    ASSERT( !Inside(), "SwExtend: Enter without Leave" );
+    ASSERT( !pFnt, "SwExtend: Enter with Font" );
+    nPos = nNew;
+    if( Inside() )
+    {
+        pFnt = new SwFont( rFnt );
+        ActualizeFont( rFnt, rArr[ nPos - nStart ] );
+        return 1;
+    }
+    return 0;
+}
+
+sal_Bool SwExtend::_Leave( SwFont& rFnt, xub_StrLen nNew )
+{
+    ASSERT( Inside(), "SwExtend: Leave without Enter" );
+    MSHORT nOldAttr = rArr[ nPos - nStart ];
+    nPos = nNew;
+    if( Inside() )
+    {   // Wir sind innerhalb des ExtendText-Bereichs geblieben
+        MSHORT nAttr = rArr[ nPos - nStart ];
+        if( nOldAttr != nAttr ) // Gibt es einen (inneren) Attributwechsel?
+        {
+            rFnt = *pFnt;
+            ActualizeFont( rFnt, nAttr );
+        }
+    }
+    else
+    {
+        rFnt = *pFnt;
+        delete pFnt;
+        pFnt = NULL;
+        return sal_True;
+    }
+    return sal_False;
+}
+
+xub_StrLen SwExtend::Next( xub_StrLen nNext )
+{
+    if( nPos < nStart )
+    {
+        if( nNext > nStart )
+            nNext = nStart;
+    }
+    else if( nPos < nEnd )
+    {
+        MSHORT nIdx = nPos - nStart;
+        MSHORT nAttr = rArr[ nIdx ];
+        while( ++nIdx < rArr.Count() && nAttr == rArr[ nIdx ] )
+            ; //nothing
+        nIdx += nStart;
+        if( nNext > nIdx )
+            nNext = nIdx;
+    }
+    return nNext;
+}
+
+void SwExtend::ChangeTxtAttr( SwTxtAttr &rHt, sal_Bool bChg )
+{
+    ASSERT( pFnt, "SwExtend: No font, no fun." );
+    if( bChg )
+        rHt.ChgFnt( pFnt );
+    else
+        rHt.RstFnt( pFnt );
+}
+
+
diff --git a/sw/source/core/text/redlnitr.hxx b/sw/source/core/text/redlnitr.hxx
new file mode 100644
index 000000000000..87b4577d0033
--- /dev/null
+++ b/sw/source/core/text/redlnitr.hxx
@@ -0,0 +1,150 @@
+/*************************************************************************
+ *
+ *  $RCSfile: redlnitr.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:26 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _REDLNITR_HXX
+#define _REDLNITR_HXX
+
+#include "ndhints.hxx"
+#include "redlenum.hxx" // SwRedlineType
+#include "swfont.hxx"
+#ifndef _SVSTDARR_USHORTS
+#define _SVSTDARR_USHORTS
+#include 
+#endif
+
+class SwTxtNode;
+class SwDoc;
+class SfxItemSet;
+
+class SwExtend
+{
+    SwFont *pFnt;
+    const SvUShorts ⇒  // XAMA: Array of xub_StrLen
+    xub_StrLen nStart;
+    xub_StrLen nPos;
+    xub_StrLen nEnd;
+    sal_Bool _Leave( SwFont& rFnt, xub_StrLen nNew );
+    sal_Bool Inside() const { return ( nPos >= nStart && nPos < nEnd ); }
+    void ActualizeFont( SwFont &rFnt, xub_StrLen nAttr );
+public:
+    SwExtend( const SvUShorts &rA, xub_StrLen nSt ) : rArr( rA ), pFnt(0),
+        nStart( nSt ), nPos( STRING_LEN ), nEnd( nStart + rA.Count() ) {}
+    ~SwExtend() { delete pFnt; }
+    sal_Bool IsOn() const { return pFnt != 0; }
+    void Reset() { if( pFnt ) { delete pFnt; pFnt = NULL; } nPos = STRING_LEN; }
+    sal_Bool Leave( SwFont& rFnt, xub_StrLen nNew )
+        { if( pFnt ) return _Leave( rFnt, nNew ); return sal_False; }
+    short Enter( SwFont& rFnt, xub_StrLen nNew );
+    xub_StrLen Next( xub_StrLen nNext );
+    void ChangeTxtAttr( SwTxtAttr &rHt, sal_Bool bChg );
+};
+
+class SwRedlineItr
+{
+    SwpHtStart_SAR aHints;
+    const SwDoc& rDoc;
+    const SwTxtNode& rNd;
+    SfxItemSet *pSet;
+    SwExtend *pExt;
+    ULONG nNdIdx;
+    xub_StrLen nFirst;
+    xub_StrLen nAct;
+    xub_StrLen nStart;
+    xub_StrLen nEnd;
+    sal_Bool bOn;
+    sal_Bool bShow;
+
+    void _Clear( SwFont* pFnt );
+    void CalcStartEnd();
+    sal_Bool _ChkSpecialUnderline() const;
+    void FillHints( MSHORT nAuthor, SwRedlineType eType );
+    short _Seek( SwFont& rFnt, xub_StrLen nNew, xub_StrLen nOld );
+    xub_StrLen _GetNextRedln( xub_StrLen nNext );
+    void _ChangeTxtAttr( SwFont* pFnt, SwTxtAttr &rHt, sal_Bool bChg );
+    inline sal_Bool LeaveExtend( SwFont& rFnt, xub_StrLen nNew )
+        { return pExt->Leave(rFnt, nNew ); }
+    inline short EnterExtend( SwFont& rFnt, xub_StrLen nNew )
+        { if( pExt ) return pExt->Enter( rFnt, nNew ); return 0; }
+    inline xub_StrLen NextExtend( xub_StrLen nNext )
+        { if( pExt ) return pExt->Next( nNext ); return nNext; }
+    inline sal_Bool ExtOn() { if( pExt ) return pExt->IsOn(); return sal_False; }
+public:
+    SwRedlineItr( const SwTxtNode& rTxtNd, SwFont& rFnt, xub_StrLen nRedlPos,
+        sal_Bool bShw, const SvUShorts *pArr = 0, xub_StrLen nStart = STRING_LEN );
+    ~SwRedlineItr();
+    inline sal_Bool IsOn() const { return bOn || ( pExt && pExt->IsOn() ); }
+    inline void Clear( SwFont* pFnt ) { if( bOn ) _Clear( pFnt ); }
+    inline void ChangeTxtAttr( SwFont* pFnt, SwTxtAttr &rHt, sal_Bool bChg )
+        { if( bShow || pExt ) _ChangeTxtAttr( pFnt, rHt, bChg ); }
+    inline short Seek( SwFont& rFnt, xub_StrLen nNew, xub_StrLen nOld )
+        { if( bShow || pExt ) return _Seek( rFnt, nNew, nOld ); return 0; }
+    inline void Reset() { if( nAct != nFirst ) nAct = STRING_LEN;
+                          if( pExt ) pExt->Reset(); }
+    inline xub_StrLen GetNextRedln( xub_StrLen nNext )
+        { if( bShow || pExt ) return _GetNextRedln( nNext ); return nNext; }
+    inline sal_Bool ChkSpecialUnderline() const
+        { if ( IsOn() ) return _ChkSpecialUnderline(); return sal_False; }
+    sal_Bool CheckLine( xub_StrLen nChkStart, xub_StrLen nChkEnd );
+};
+
+
+#endif
+
diff --git a/sw/source/core/text/txtcache.cxx b/sw/source/core/text/txtcache.cxx
new file mode 100644
index 000000000000..a7a70341501b
--- /dev/null
+++ b/sw/source/core/text/txtcache.cxx
@@ -0,0 +1,277 @@
+/*************************************************************************
+ *
+ *  $RCSfile: txtcache.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:26 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "errhdl.hxx"
+#include "segmentc.hxx"
+
+#include "txtcache.hxx"
+#include "txtfrm.hxx"
+#include "porlay.hxx"
+
+/*************************************************************************
+|*
+|*  SwTxtLine::SwTxtLine(), ~SwTxtLine()
+|*
+|*  Ersterstellung      MA 16. Mar. 94
+|*  Letzte Aenderung    MA 16. Mar. 94
+|*
+|*************************************************************************/
+
+SwTxtLine::SwTxtLine( SwTxtFrm *pFrm, SwParaPortion *pNew ) :
+    SwCacheObj( (void*)pFrm ),
+    pLine( pNew )
+{
+}
+
+SwTxtLine::~SwTxtLine()
+{
+    delete pLine;
+}
+
+/*************************************************************************
+|*
+|*  SwTxtLineAccess::NewObj()
+|*
+|*  Ersterstellung      MA 16. Mar. 94
+|*  Letzte Aenderung    MA 16. Mar. 94
+|*
+|*************************************************************************/
+
+SwCacheObj *SwTxtLineAccess::NewObj()
+{
+    return new SwTxtLine( (SwTxtFrm*)pOwner );
+}
+
+/*************************************************************************
+|*
+|*  SwTxtLineAccess::GetPara()
+|*
+|*  Ersterstellung      MA 16. Mar. 94
+|*  Letzte Aenderung    MA 16. Mar. 94
+|*
+|*************************************************************************/
+
+SwParaPortion *SwTxtLineAccess::GetPara()
+{
+    SwTxtLine *pRet;
+    if ( pObj )
+        pRet = (SwTxtLine*)pObj;
+    else
+    {
+        pRet = (SwTxtLine*)Get();
+        ((SwTxtFrm*)pOwner)->SetCacheIdx( pRet->GetCachePos() );
+    }
+    if ( !pRet->GetPara() )
+        pRet->SetPara( new SwParaPortion );
+    return pRet->GetPara();
+}
+
+
+/*************************************************************************
+|*
+|*  SwTxtLineAccess::SwTxtLineAccess()
+|*
+|*  Ersterstellung      MA 16. Mar. 94
+|*  Letzte Aenderung    MA 16. Mar. 94
+|*
+|*************************************************************************/
+
+SwTxtLineAccess::SwTxtLineAccess( const SwTxtFrm *pOwner ) :
+    SwCacheAccess( *SwTxtFrm::GetTxtCache(), pOwner, pOwner->GetCacheIdx() )
+{
+}
+
+/*************************************************************************
+|*
+|*  SwTxtLineAccess::IsAvailable
+|*
+|*  Ersterstellung      MA 23. Mar. 94
+|*  Letzte Aenderung    MA 23. Mar. 94
+|*
+|*************************************************************************/
+
+sal_Bool SwTxtLineAccess::IsAvailable() const
+{
+    if ( pObj )
+        return ((SwTxtLine*)pObj)->GetPara() != 0;
+    return sal_False;
+}
+
+/*************************************************************************
+|*
+|*  SwTxtFrm::HasPara()
+|*
+|*  Ersterstellung      MA 16. Mar. 94
+|*  Letzte Aenderung    MA 22. Aug. 94
+|*
+|*************************************************************************/
+
+sal_Bool SwTxtFrm::_HasPara() const
+{
+    SwTxtLine *pTxtLine = (SwTxtLine*)SwTxtFrm::GetTxtCache()->
+                                            Get( this, GetCacheIdx(), sal_False );
+    if ( pTxtLine )
+    {
+        if ( pTxtLine->GetPara() )
+            return sal_True;
+    }
+    else
+        ((SwTxtFrm*)this)->nCacheIdx = MSHRT_MAX;
+
+    return sal_False;
+}
+
+/*************************************************************************
+|*
+|*  SwTxtFrm::GetPara()
+|*
+|*  Ersterstellung      MA 16. Mar. 94
+|*  Letzte Aenderung    MA 22. Aug. 94
+|*
+|*************************************************************************/
+
+SwParaPortion *SwTxtFrm::GetPara()
+{
+    if ( GetCacheIdx() != MSHRT_MAX )
+    {   SwTxtLine *pLine = (SwTxtLine*)SwTxtFrm::GetTxtCache()->
+                                        Get( this, GetCacheIdx(), sal_False );
+        if ( pLine )
+            return pLine->GetPara();
+        else
+            nCacheIdx = MSHRT_MAX;
+    }
+    return 0;
+}
+
+
+/*************************************************************************
+|*
+|*  SwTxtFrm::ClearPara()
+|*
+|*  Ersterstellung      MA 16. Mar. 94
+|*  Letzte Aenderung    MA 22. Aug. 94
+|*
+|*************************************************************************/
+
+void SwTxtFrm::ClearPara()
+{
+    ASSERT( !IsLocked(), "+SwTxtFrm::ClearPara: this is locked." );
+    if ( !IsLocked() && GetCacheIdx() != MSHRT_MAX )
+    {
+        SwTxtLine *pTxtLine = (SwTxtLine*)SwTxtFrm::GetTxtCache()->
+                                        Get( this, GetCacheIdx(), sal_False );
+        if ( pTxtLine )
+        {
+            delete pTxtLine->GetPara();
+            pTxtLine->SetPara( 0 );
+        }
+        else
+            nCacheIdx = MSHRT_MAX;
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwTxtFrm::SetPara()
+|*
+|*  Ersterstellung      MA 16. Mar. 94
+|*  Letzte Aenderung    MA 22. Aug. 94
+|*
+|*************************************************************************/
+
+void SwTxtFrm::SetPara( SwParaPortion *pNew, sal_Bool bDelete )
+{
+    if ( GetCacheIdx() != MSHRT_MAX )
+    {
+        //Nur die Information Auswechseln, das CacheObj bleibt stehen.
+        SwTxtLine *pTxtLine = (SwTxtLine*)SwTxtFrm::GetTxtCache()->
+                                        Get( this, GetCacheIdx(), sal_False );
+        if ( pTxtLine )
+        {
+            if( bDelete )
+                delete pTxtLine->GetPara();
+            pTxtLine->SetPara( pNew );
+        }
+        else
+        {
+            ASSERT( !pNew, "+SetPara: Losing SwParaPortion" );
+            nCacheIdx = MSHRT_MAX;
+        }
+    }
+    else if ( pNew )
+    {   //Einen neuen einfuegen.
+        SwTxtLine *pTxtLine = new SwTxtLine( this, pNew );
+        if ( SwTxtFrm::GetTxtCache()->Insert( pTxtLine ) )
+            nCacheIdx = pTxtLine->GetCachePos();
+        else
+        {
+            ASSERT( sal_False, "+SetPara: InsertCache failed." );
+        }
+    }
+}
+
+
diff --git a/sw/source/core/text/txtcache.hxx b/sw/source/core/text/txtcache.hxx
new file mode 100644
index 000000000000..d422eea2db04
--- /dev/null
+++ b/sw/source/core/text/txtcache.hxx
@@ -0,0 +1,113 @@
+/*************************************************************************
+ *
+ *  $RCSfile: txtcache.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:26 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _TXTCACHE_HXX
+#define _TXTCACHE_HXX
+
+#include 
+
+#ifndef _SVMEMPOOL_HXX //autogen
+#include 
+#endif
+#include "swcache.hxx"
+
+class SwParaPortion;
+class SwTxtFrm;
+
+class SwTxtLine : public SwCacheObj
+{
+    SwParaPortion *pLine;
+
+public:
+    DECL_FIXEDMEMPOOL_NEWDEL(SwTxtLine)
+
+    SwTxtLine( SwTxtFrm *pFrm, SwParaPortion *pNew = 0 );
+    virtual ~SwTxtLine();
+
+    inline       SwParaPortion *GetPara()       { return pLine; }
+    inline const SwParaPortion *GetPara() const { return pLine; }
+
+    inline void SetPara( SwParaPortion *pNew ) { pLine = pNew; }
+};
+
+
+class SwTxtLineAccess : public SwCacheAccess
+{
+
+protected:
+    virtual SwCacheObj *NewObj();
+
+public:
+    SwTxtLineAccess( const SwTxtFrm *pOwner );
+
+    SwParaPortion *GetPara();
+
+    inline SwTxtLine &GetTxtLine();
+
+    virtual sal_Bool IsAvailable() const;
+};
+
+
+inline SwTxtLine &SwTxtLineAccess::GetTxtLine()
+{
+    return *((SwTxtLine*)Get());
+}
+
+#endif
diff --git a/sw/source/core/text/txtcfg.hxx b/sw/source/core/text/txtcfg.hxx
new file mode 100644
index 000000000000..b1ba57c8cf9a
--- /dev/null
+++ b/sw/source/core/text/txtcfg.hxx
@@ -0,0 +1,209 @@
+/*************************************************************************
+ *
+ *  $RCSfile: txtcfg.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:26 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _TXTCFG_HXX
+#define _TXTCFG_HXX
+
+#ifdef DEBUG
+#include "dbgloop.hxx"  // DBG_LOOP
+#else
+#ifdef DBG_LOOP     //kann per precompiled hereinkommen
+#undef DBG_LOOP
+#undef DBG_LOOP_RESET
+#endif
+#define DBG_LOOP
+#define DBG_LOOP_RESET
+#endif
+
+// Toleranzwert in der Formatierung und Textausgabe.
+#define SLOPPY_TWIPS    5
+
+#define CONSTCHAR( name, string ) static const sal_Char __FAR_DATA name[] = string
+
+// Allgemeines ...
+
+#ifndef CONST
+#define CONST const
+#endif
+
+/*************************************************************************
+
+      $Log: not supported by cvs2svn $
+      Revision 1.37  2000/09/18 16:04:22  willem.vandorp
+      OpenOffice header added.
+
+      Revision 1.36  2000/09/08 13:25:44  willem.vandorp
+      Header and footer replaced
+
+      Revision 1.35  2000/04/13 09:59:17  ama
+      Unicode changes
+
+      Revision 1.34  1997/12/11 15:44:48  AMA
+      Fix: Text-Verzeichnis wieder mit DEBUG uebersetzbar
+
+
+      Rev 1.33   11 Dec 1997 16:44:48   AMA
+   Fix: Text-Verzeichnis wieder mit DEBUG uebersetzbar
+
+      Rev 1.32   05 Dec 1997 08:43:28   MA
+   includes
+
+      Rev 1.32   05 Dec 1997 08:41:28   MA
+   includes
+
+      Rev 1.31   15 Oct 1997 12:31:44   AMA
+   Opt: DBG_LOOP kann jetzt auch resetted werden
+
+      Rev 1.30   25 Jun 1996 20:36:02   MA
+   headerfiles
+
+      Rev 1.29   07 Feb 1996 08:57:46   OS
+   _GDIMTF_HXX definiert
+
+      Rev 1.28   19 Apr 1995 15:08:30   ER
+   kein define _unqidx_hxx mehr
+
+      Rev 1.27   18 Apr 1995 17:29:04   AMA
+   DBGLOOP nur noch bei DEBUG=sal_True
+
+      Rev 1.26   15 Dec 1994 20:51:38   SWG
+   *ARR* Ersetzungen, svmem, __far_data etc.
+
+      Rev 1.25   26 Apr 1994 17:39:20   BP
+   6922: Toleranz von SLOPPY_TWIPS
+
+      Rev 1.24   16 Nov 1993 14:10:04   BP
+   chg: Renovierung, mit win088h1_bp zusammengemischt
+
+      Rev 1.23   08 Nov 1993 14:26:00   BP
+   dbg: Umstellung auf dbgloop.hxx, Loop-Kontrolle bei not PRODUCT
+
+      Rev 1.21   05 Oct 1993 17:21:16   BP
+   chg: Aufraeumarbeiten nach dem final
+
+      Rev 1.20   14 Sep 1993 08:27:00   SWG
+   INLINE Definition wech
+
+      Rev 1.19   12 Jul 1993 13:53:14   ER
+   NEWTXT fuer MAC
+
+      Rev 1.18   02 Jul 1993 10:59:28   BP
+   new: PRODUCT mit NEWTXT verdrahtet, NEWTXT ohne SCRMET
+
+      Rev 1.17   27 Jun 1993 12:16:24   BP
+   chg: OLDTXT ist abhaengig von NEWTXT
+
+      Rev 1.16   22 Jun 1993 15:39:10   BP
+   new: OLDTXT enabled fuer neue und alte Textformatierung
+
+      Rev 1.15   08 Jun 1993 16:53:24   ER
+   else fuer DGB_LOOP
+
+      Rev 1.14   08 Jun 1993 15:58:28   BP
+   dbg: DBG_LOOP bemerkt Endlosschleifen.
+
+      Rev 1.13   14 May 1993 09:12:46   OK
+   Time Stamp rausgeflogen
+
+      Rev 1.12   27 Apr 1993 11:34:26   BP
+   chg: CONSTCHAR-Makro
+
+      Rev 1.11   20 Apr 1993 10:40:54   BP
+   del: DbgPen, DbgColor in TxtFrm
+
+      Rev 1.10   22 Mar 1993 10:58:40   BP
+   bug: falsche Umlaute fuer PM2
+
+      Rev 1.9   06 Mar 1993 17:51:36   SWG
+   const Behandlung fuer SUN auskommentiert
+
+      Rev 1.8   02 Mar 1993 09:33:56   BP
+   new: CONSTCHAR fuer Daten ins __FAR_DATA
+
+      Rev 1.7   21 Feb 1993 13:58:42   OK
+   Umlautr fuer Windows NT
+
+      Rev 1.6   29 Jan 1993 11:43:34   BP
+   new: NOINLINE schaltet alle INLINEs (gewinnt 20 KB im Textverzeichnis)
+
+      Rev 1.5   25 Jan 1993 15:29:36   BP
+   new: IS_CHAR-Makros aus dem trlib.hxx uebernommen.
+
+      Rev 1.4   18 Jan 1993 16:32:28   BP
+   chg: nun gibt's nur noch einen Schalter
+
+      Rev 1.3   15 Jan 1993 17:28:08   BP
+   chg: der SV-Bug ist zu fatal - Umstellung auf SOS_Kerning
+
+      Rev 1.2   15 Jan 1993 13:08:28   BP
+   new: KERNING aktiviert.
+   new: PAINTOFST
+
+      Rev 1.1   14 Jan 1993 14:24:18   BP
+   new: Schalter fuer SOS_Kerning
+   bug: SCRMET statt SCRMETRIC
+
+      Rev 1.0   14 Jan 1993 12:56:10   BP
+   Initial revision.
+
+*************************************************************************/
+
+#endif
diff --git a/sw/source/core/text/txtdrop.cxx b/sw/source/core/text/txtdrop.cxx
new file mode 100644
index 000000000000..b8f2aef96c88
--- /dev/null
+++ b/sw/source/core/text/txtdrop.cxx
@@ -0,0 +1,800 @@
+/*************************************************************************
+ *
+ *  $RCSfile: txtdrop.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:26 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _SV_METRIC_HXX //autogen
+#include 
+#endif
+#ifndef _WINDOW_HXX //autogen
+#include 
+#endif
+#ifndef _SV_SVAPP_HXX
+#include 
+#endif
+
+#ifndef _PARATR_HXX
+#include 
+#endif
+#ifndef _TXTFRM_HXX
+#include    // Format()
+#endif
+#ifndef _CHARFMT_HXX
+#include 
+#endif
+#ifndef _VIEWOPT_HXX
+#include   // SwViewOption
+#endif
+#ifndef _VIEWSH_HXX
+#include    // ViewShell
+#endif
+#ifndef _PORDROP_HXX
+#include 
+#endif
+#ifndef _ITRFORM2_HXX
+#include 
+#endif
+#ifndef _SWFONT_HXX
+#include 
+#endif
+#ifndef _TXTPAINT_HXX
+#include  // SwSaveClip
+#endif
+#ifndef _TXTFLY_HXX
+#include    // Format()
+#endif
+#ifndef _BLINK_HXX
+#include     // pBlink
+#endif
+#ifndef _TXATBASE_HXX
+#include 
+#endif
+
+/*************************************************************************
+ *                SwDropPortion CTor, DTor
+ *************************************************************************/
+
+SwDropPortion::SwDropPortion( SwFont *pF, const MSHORT nLineCnt,
+                                          const KSHORT nDropHeight,
+                                          const KSHORT nDropDescent,
+                                          const KSHORT nDistance )
+  : pFnt( pF ),
+    nLines( nLineCnt ),
+    nDropHeight(nDropHeight),
+    nDropDescent(nDropDescent),
+    nDistance(nDistance),
+    nX(0),
+    nY(0),
+    nFix(0)
+{
+    SetWhichPor( POR_DROP );
+}
+
+
+
+SwDropPortion::~SwDropPortion()
+{
+    delete pFnt;
+    if( pBlink )
+        pBlink->Delete( this );
+}
+
+sal_Bool SwTxtSizeInfo::_HasHint( const SwTxtNode* pTxtNode, xub_StrLen nPos )
+{
+    const SwpHints *pHints = pTxtNode->GetpSwpHints();
+    if( !pHints )
+        return sal_False;
+    for( MSHORT i = 0; i < pHints->Count(); ++i )
+    {
+        const SwTxtAttr *pPos = (*pHints)[i];
+        xub_StrLen nStart = *pPos->GetStart();
+        if( nPos < nStart )
+            return sal_False;
+        if( nPos == nStart && !pPos->GetEnd() )
+            return sal_True;
+    }
+    return sal_False;
+}
+
+/*************************************************************************
+ *                    SwTxtNode::GetDropLen()
+ *************************************************************************/
+
+MSHORT SwTxtNode::GetDropLen( MSHORT nWishLen ) const
+{
+    xub_StrLen nEnd = GetTxt().Len();
+    if( nWishLen && nWishLen < nEnd )
+        nEnd = nWishLen;
+    xub_StrLen i = 0;
+    for( ; i < nEnd; ++i )
+    {
+        xub_Unicode cChar = GetTxt().GetChar( i );
+        if( CH_TAB == cChar || CH_BREAK == cChar ||
+            ( !nWishLen && CH_BLANK == cChar ) ||
+            (( CH_TXTATR_BREAKWORD == cChar || CH_TXTATR_INWORD == cChar )
+                && SwTxtSizeInfo::_HasHint( this, i ) ) )
+            break;
+    }
+    return i;
+}
+
+/*************************************************************************
+ *                    SwDropPortion::PaintTxt()
+ *************************************************************************/
+
+// Die Breite manipulieren, sonst werden die Buchstaben gestretcht
+
+
+
+void SwDropPortion::PaintTxt( const SwTxtPaintInfo &rInf /*, const sal_Bool bBack*/ )
+    const
+{
+    if ( rInf.OnWin() )
+    {
+        if( rInf.GetOpt().IsField() )
+            rInf.DrawBackground( *this );
+//      else if ( bBack )
+//          rInf.DrawRect( *this );
+    }
+    ((SwDropPortion*)this)->Width( Width() - nDistance );
+    SwTxtPortion::Paint( rInf );
+    ((SwDropPortion*)this)->Width( Width() + nDistance );
+}
+
+/*************************************************************************
+ *                   SwDropPortion::Paint()
+ *************************************************************************/
+
+
+void SwDropPortion::PaintDrop( const SwTxtPaintInfo &rInf ) const
+{
+    // ganz normale Ausgabe
+    if( !nDropHeight || !pFnt || nLines == 1 )
+    {
+        SwFontSave aTmp( rInf, pFnt );
+        PaintTxt( rInf /*, sal_False */);
+        return;
+    }
+
+    // Luegenwerte einstellen!
+    const KSHORT nOldHeight = Height();
+    const KSHORT nOldWidth  = Width();
+    const KSHORT nOldAscent = GetAscent();
+    const SwTwips nOldPosY  = rInf.Y();
+    const KSHORT nOldPosX   = rInf.X();
+    const SwParaPortion *pPara = rInf.GetParaPortion();
+    const Point aOutPos( nOldPosX + nX, nOldPosY - pPara->GetAscent()
+                         - pPara->GetRealHeight() + pPara->Height() );
+    // Retusche nachholen.
+
+    ((SwTxtPaintInfo&)rInf).Y( aOutPos.Y() + nDropHeight + nY );
+    ((SwDropPortion*)this)->Height( nDropHeight+nDropDescent );
+    ((SwDropPortion*)this)->Width( Width() - nX );
+    ((SwDropPortion*)this)->SetAscent( nDropHeight + nY );
+
+    // Clipregion auf uns einstellen!
+    // Und zwar immer, und nie mit dem bestehenden ClipRect
+    // verrechnen, weil dies auf die Zeile eingestellt sein koennte.
+
+    SwRect aClipRect;
+    if ( rInf.OnWin() )
+    {
+        aClipRect = SwRect( aOutPos, SvLSize() );
+        aClipRect.Intersection( rInf.GetPaintRect() );
+    }
+    SwSaveClip aClip( (OutputDevice*)rInf.GetOut() );
+    aClip.ChgClip( aClipRect );
+
+    // Das machen, was man sonst nur macht ...
+    SwFontSave aSave( rInf, pFnt );
+    PaintTxt( rInf /*, sal_True */);
+
+    // Alte Werte sichern
+    ((SwDropPortion*)this)->Height( nOldHeight );
+    ((SwDropPortion*)this)->Width( nOldWidth );
+    ((SwDropPortion*)this)->SetAscent( nOldAscent );
+    ((SwTxtPaintInfo&)rInf).Y( nOldPosY );
+    ((SwTxtPaintInfo&)rInf).X( nOldPosX );
+
+}
+
+/*************************************************************************
+ *              virtual SwDropPortion::Paint()
+ *************************************************************************/
+
+
+void SwDropPortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+    // ganz normale Ausgabe wird hier erledigt.
+    if( !nDropHeight || !pFnt )
+        PaintTxt( rInf /*, sal_False */);
+}
+
+/*************************************************************************
+ *                virtual Format()
+ *************************************************************************/
+
+
+sal_Bool SwDropPortion::FormatTxt( SwTxtFormatInfo &rInf )
+{
+    const xub_StrLen nOldLen = GetLen();
+    const xub_StrLen nOldInfLen = rInf.GetLen();
+    const sal_Bool bFull = SwTxtPortion::Format( rInf );
+    if( bFull )
+    {
+        // sieht zwar Scheisse aus, aber was soll man schon machen?
+        rInf.SetUnderFlow( 0 );
+        Truncate();
+        SetLen( nOldLen );
+        rInf.SetLen( nOldInfLen );
+    }
+    return bFull;
+}
+
+/*************************************************************************
+ *                virtual GetTxtSize()
+ *************************************************************************/
+
+
+SwPosSize SwDropPortion::GetTxtSize( const SwTxtSizeInfo &rInf ) const
+{
+    SwFontSave aSave( rInf, pFnt );
+    return SwTxtPortion::GetTxtSize( rInf );
+}
+
+/*************************************************************************
+ *                virtual GetCrsrOfst()
+ *************************************************************************/
+
+xub_StrLen SwDropPortion::GetCrsrOfst( const KSHORT nOfst ) const
+{
+    return 0;
+}
+
+#ifdef OLDRECYCLE
+/*************************************************************************
+ *                virtual SwDropPortion::MayRecycle()
+ *************************************************************************/
+
+
+sal_Bool SwDropPortion::MayRecycle() const
+{
+    return sal_False;
+}
+#endif
+
+/*************************************************************************
+ *                SwTxtFormatter::CalcDropHeight()
+ *************************************************************************/
+
+
+
+void SwTxtFormatter::CalcDropHeight( const MSHORT nLines )
+{
+    const SwLinePortion *const pOldCurr = GetCurr();
+    KSHORT nDropHght = 0;
+    KSHORT nAscent = 0;
+    KSHORT nHeight = 0;
+    KSHORT nDropLns = 0;
+    sal_Bool bRegisterOld = IsRegisterOn();
+    bRegisterOn = sal_False;
+
+    Top();
+
+    while( GetCurr()->IsDummy() )
+    {
+        if ( !Next() )
+            break;
+    }
+
+    // Wenn wir nur eine Zeile haben returnen wir 0
+    if( GetNext() || GetDropLines() == 1 )
+    {
+        for( ; nDropLns < nLines; nDropLns++ )
+        {
+            if ( GetCurr()->IsDummy() )
+                break;
+            else
+            {
+                CalcAscentAndHeight( nAscent, nHeight );
+                nDropHght += nHeight;
+                bRegisterOn = bRegisterOld;
+            }
+            if ( !Next() )
+            {
+                nDropLns++; // Fix: 11356
+                break;
+            }
+        }
+
+        // In der letzten Zeile plumpsen wir auf den Zeilenascent!
+        nDropHght -= nHeight;
+        nDropHght += nAscent;
+        Top();
+    }
+    bRegisterOn = bRegisterOld;
+    SetDropDescent( nHeight - nAscent );
+    SetDropHeight( nDropHght );
+    SetDropLines( nDropLns );
+    // Alte Stelle wiederfinden!
+    while( pOldCurr != GetCurr() )
+    {
+        if( !Next() )
+        {
+            ASSERT( !this, "SwTxtFormatter::_CalcDropHeight: left Toulouse" );
+            break;
+        }
+    }
+}
+
+/*************************************************************************
+ *                SwTxtFormatter::GuessDropHeight()
+ *
+ *  Wir schaetzen mal, dass die Fonthoehe sich nicht aendert und dass
+ *  erst mindestens soviele Zeilen gibt, wie die DropCap-Einstellung angibt.
+ *
+ *************************************************************************/
+
+
+
+void SwTxtFormatter::GuessDropHeight( const MSHORT nLines )
+{
+    ASSERT( nLines, "GuessDropHeight: Give me more Lines!" );
+    KSHORT nAscent = 0;
+    KSHORT nHeight = 0;
+    SetDropLines( nLines );
+    if ( GetDropLines() > 1 )
+    {
+        CalcRealHeight();
+        CalcAscentAndHeight( nAscent, nHeight );
+    }
+    SetDropDescent( nHeight - nAscent );
+    SetDropHeight( nHeight * nLines - GetDropDescent() );
+}
+
+/*************************************************************************
+ *                SwTxtFormatter::NewDropPortion
+ *************************************************************************/
+
+
+SwDropPortion *SwTxtFormatter::NewDropPortion( SwTxtFormatInfo &rInf ) const
+{
+    if( !pDropFmt )
+        return 0;
+
+    xub_StrLen nPorLen = pDropFmt->GetWholeWord() ? 0 : pDropFmt->GetChars();
+    nPorLen = pFrm->GetTxtNode()->GetDropLen( nPorLen );
+    if( !nPorLen )
+    {
+        ((SwTxtFormatter*)this)->ClearDropFmt();
+        return 0;
+    }
+
+    SwDropPortion *pDropPor = 0;
+
+    // erste oder zweite Runde?
+    if ( !( GetDropHeight() || IsOnceMore() ) )
+    {
+        if ( GetNext() )
+            ((SwTxtFormatter*)this)->CalcDropHeight( pDropFmt->GetLines() );
+        else
+            ((SwTxtFormatter*)this)->GuessDropHeight( pDropFmt->GetLines() );
+    }
+    SwFont *pTmpFnt = new SwFont( pDropFmt->GetCharFmt()
+                                 ? &pDropFmt->GetCharFmt()->GetAttrSet()
+                                 : &rInf.GetCharAttr() );
+    if( GetDropHeight() )
+        pDropPor = new SwDropPortion( pTmpFnt, GetDropLines(),
+                                 GetDropHeight(), GetDropDescent(),
+                                 pDropFmt->GetDistance() );
+    else
+        pDropPor = new SwDropPortion( pTmpFnt,0,0,0,pDropFmt->GetDistance() );
+
+    pDropPor->SetLen( nPorLen );
+    ((SwTxtFormatter*)this)->SetPaintDrop( sal_True );
+    return pDropPor;
+}
+
+/*************************************************************************
+ *                SwTxtPainter::PaintDropPortion()
+ *************************************************************************/
+
+
+
+void SwTxtPainter::PaintDropPortion()
+{
+    const SwDropPortion *pDrop = GetInfo().GetParaPortion()->FindDropPortion();
+    ASSERT( pDrop, "DrapCop-Portion not available." );
+    if( !pDrop )
+        return;
+
+    const SwTwips nOldY = GetInfo().Y();
+
+    Top();
+
+    GetInfo().SetSpaceAdd( pCurr->GetpSpaceAdd() );
+    GetInfo().ResetSpaceIdx();
+
+    // 8047: Drops und Dummies
+    while( !pCurr->GetLen() && Next() )
+        ;
+
+    // MarginPortion und Adjustment!
+    const SwLinePortion *pPor = pCurr->GetFirstPortion();
+    KSHORT nX = 0;
+    while( pPor && !pPor->IsDropPortion() )
+    {
+        nX += pPor->Width();
+        pPor = pPor->GetPortion();
+    }
+    Point aLineOrigin( GetTopLeft() );
+
+#ifdef NIE
+    // Retusche nachholen...
+    if( nX )
+    {
+        const Point aPoint( Left(), Y() );
+        const Size  aSize( nX - 1, GetDropHeight()+GetDropDescent() );
+        SwRect aRetouche( aPoint, aSize );
+        GetInfo().DrawRect( aRetouche );
+    }
+#endif
+
+    aLineOrigin.X() += nX;
+    KSHORT nTmpAscent, nTmpHeight;
+    CalcAscentAndHeight( nTmpAscent, nTmpHeight );
+    aLineOrigin.Y() += nTmpAscent;
+    GetInfo().SetIdx( GetStart() );
+    GetInfo().SetPos( aLineOrigin );
+    GetInfo().SetLen( pDrop->GetLen() );
+
+    pDrop->PaintDrop( GetInfo() );
+
+    GetInfo().Y( nOldY );
+}
+
+/*************************************************************************
+ * Da die Berechnung der Fontgroesse der Initialen ein teures Geschaeft ist,
+ * wird dies durch einen DropCapCache geschleust.
+ *************************************************************************/
+
+#define DROP_CACHE_SIZE 10
+
+class SwDropCapCache
+{
+    long aMagicNo[ DROP_CACHE_SIZE ];
+    XubString aTxt[ DROP_CACHE_SIZE ];
+    Size aSize[ DROP_CACHE_SIZE ];
+    KSHORT aWishedHeight[ DROP_CACHE_SIZE ];
+    short aDescent[ DROP_CACHE_SIZE ];
+    MSHORT nIndex;
+public:
+    SwDropCapCache();
+    ~SwDropCapCache(){}
+    void CalcFontSize( SwDropPortion* pDrop, SwTxtFormatInfo &rInf );
+};
+
+
+
+SwDropCapCache::SwDropCapCache() : nIndex( 0 )
+{
+    memset( &aMagicNo, 0, sizeof(aMagicNo) );
+    memset( &aWishedHeight, 0, sizeof(aWishedHeight) );
+}
+
+
+
+void SwDropCapCache::CalcFontSize( SwDropPortion* pDrop, SwTxtFormatInfo &rInf )
+{
+    const void* pFntNo;
+    MSHORT nTmpIdx;
+    SwFont *pFnt = pDrop->pFnt;
+    pFnt->GetMagic( pFntNo, nTmpIdx, pFnt->GetActual() );
+    XubString aStr( rInf.GetTxt(), rInf.GetIdx(), pDrop->GetLen() );
+
+    nTmpIdx = 0;
+    while( nTmpIdx < DROP_CACHE_SIZE &&
+        ( aTxt[ nTmpIdx ] != aStr || aMagicNo[ nTmpIdx ] != long(pFntNo) ||
+          aWishedHeight[ nTmpIdx ] != pDrop->GetDropHeight() ) )
+        ++nTmpIdx;
+    if( nTmpIdx >= DROP_CACHE_SIZE )
+    {
+        ++nIndex;
+        nIndex %= DROP_CACHE_SIZE;
+        nTmpIdx = nIndex;
+
+        aMagicNo[ nTmpIdx ] = long(pFntNo);
+        aTxt[ nTmpIdx ] = aStr;
+        long nWishedHeight = pDrop->GetDropHeight();
+
+        Size aNewSize = Size( 0, nWishedHeight );
+
+        aSize[ nTmpIdx ] = aNewSize;
+
+        long nAscent = 0;
+        long nDescent = 0;
+
+        OutputDevice *pOut = rInf.GetOut();
+
+        xub_StrLen nLen = aStr.Len();
+
+        sal_Bool bGrow = ( nLen != 0 );
+#ifdef DEBUG
+        long nGrow = 0;
+#endif
+        long nMin, nMax = KSHRT_MAX;
+        nMin = aNewSize.Height()/2;
+
+        sal_Bool bWinUsed = sal_False;
+        Font aOldFnt;
+        MapMode aOldMap( MAP_TWIP );
+        OutputDevice *pWin;
+        if( rInf.GetVsh() && rInf.GetVsh()->GetWin() )
+            pWin = rInf.GetVsh()->GetWin();
+        else
+            pWin = GetpApp()->GetDefaultDevice();
+        while( bGrow )
+        {
+            pFnt->SetSize( aNewSize, pFnt->GetActual() );
+            pFnt->ChgPhysFnt( rInf.GetVsh(), pOut );
+            nAscent = pFnt->GetAscent( rInf.GetVsh(), pOut );
+
+            // Wir besorgen uns das alle Buchstaben umfassende Rechteck:
+            Rectangle aRect, aTmp;
+            sal_Bool bTakeRect = sal_False;
+            for ( xub_StrLen i = 0; i < nLen; i++ )
+            {
+                if( pOut->GetGlyphBoundRect( aStr.GetChar(i), aTmp, sal_False )
+                    && !aTmp.IsEmpty() )
+                {
+                    if ( bTakeRect )
+                        aRect.Union( aTmp );
+                    else
+                    {
+                        aRect = aTmp;
+                        bTakeRect = sal_True;
+                    }
+                }
+            }
+            if ( bTakeRect )
+            {
+                // Der tiefste Punkt der Buchstaben
+                nDescent = aRect.Bottom()-nAscent;
+                // Der hoechste Punkt der Buchstaben
+                nAscent = nAscent-aRect.Top();
+            }
+            // Wenn kein Rectangle ermittelt werden konnte, nehmen wir weiterhin
+            // einfach den Ascent mit all den bekannten Folgen (Q,g etc.)
+            else
+            {
+                if ( pWin )
+                {
+                    if ( bWinUsed )
+                        pWin->SetFont( pFnt->GetActualFont() );
+                    else
+                    {
+                        bWinUsed = sal_True;
+                        aOldMap = pWin->GetMapMode( );
+                        pWin->SetMapMode( MapMode( MAP_TWIP ) );
+                        aOldFnt = pWin->GetFont();
+                        pWin->SetFont( pFnt->GetActualFont() );
+                    }
+                    for ( xub_StrLen i = 0; i < nLen; i++ )
+                    {
+                        if( pWin->GetGlyphBoundRect( aStr.GetChar(i), aTmp, sal_False )
+                            && !aTmp.IsEmpty() )
+                        {
+                            if ( bTakeRect )
+                                aRect.Union( aTmp );
+                            else
+                            {
+                                aRect = aTmp;
+                                bTakeRect = sal_True;
+                            }
+                        }
+                    }
+                }
+                if ( bTakeRect )
+                {
+                    FontMetric aWinMet( pWin->GetFontMetric() );
+                    nAscent = (KSHORT) aWinMet.GetAscent();
+                    // Der tiefste Punkt der Buchstaben
+                    nDescent = aRect.Bottom()-nAscent;
+                    // Der hoechste Punkt der Buchstaben
+                    nAscent = nAscent-aRect.Top();
+                }
+                else
+                    nDescent = 0; // nAscent stimmt eh noch.
+            }
+            const long nHght = nAscent + nDescent;
+            if ( nHght )
+            {
+                if ( nHght > nWishedHeight )
+                    nMax = aNewSize.Height();
+                else
+                {
+                    aSize[ nTmpIdx ] = aNewSize;
+                    nMin = aNewSize.Height();
+                }
+                const long nNewHeight = ( aNewSize.Height() * nWishedHeight )
+                                        / nHght;
+                bGrow = ( nNewHeight > nMin ) && ( nNewHeight < nMax );
+#ifdef DEBUG
+                if ( bGrow )
+                    nGrow++;
+#endif
+                aNewSize.Height() = KSHORT( nNewHeight );
+            }
+            else
+                bGrow = sal_False;
+        }
+        if ( bWinUsed )
+        {
+            nDescent += pFnt->GetLeading( rInf.GetVsh(), pWin );
+            pWin->SetMapMode( aOldMap );
+            pWin->SetFont( aOldFnt );
+        }
+        else
+            nDescent += pFnt->GetLeading( rInf.GetVsh(), pOut );
+
+        aDescent[ nTmpIdx ] = -short( nDescent );
+        aWishedHeight[ nTmpIdx ] = KSHORT(nWishedHeight);
+    }
+    pDrop->nY = aDescent[ nTmpIdx ];
+    pFnt->SetSize( aSize[ nTmpIdx ], pFnt->GetActual() );
+}
+
+
+
+void SwDropPortion::DeleteDropCapCache()
+{
+    delete pDropCapCache;
+}
+
+/*************************************************************************
+ *                virtual Format()
+ *************************************************************************/
+
+
+sal_Bool SwDropPortion::Format( SwTxtFormatInfo &rInf )
+{
+    sal_Bool bFull = sal_False;
+    Fix( rInf.X() );
+    if( nDropHeight && pFnt && nLines!=1 )
+    {
+        pFnt->ChkMagic( rInf.GetVsh(), pFnt->GetActual() );
+        if( !pDropCapCache )
+            pDropCapCache = new SwDropCapCache();
+        pDropCapCache->CalcFontSize( this, rInf );
+        {
+            SwFontSave aSave( rInf, pFnt );
+            bFull = FormatTxt( rInf );
+            if( !bFull )
+            {
+                // 7631, 7633: bei Ueberlappungen mit Flys ist Schluss.
+                const SwTxtFly *pTxtFly = rInf.GetTxtFly();
+                if( pTxtFly && pTxtFly->IsOn() )
+                {
+                    SwRect aRect( rInf.GetTxtFrm()->Frm().Pos(), SvLSize() );
+                    aRect.Height( nDropHeight );
+                    aRect.Pos() += rInf.GetTxtFrm()->Prt().Pos();
+                    aRect.Pos().X() += rInf.X();
+                    aRect.Pos().Y() = rInf.Y();
+                    aRect = pTxtFly->GetFrm( aRect );
+                    bFull = aRect.HasArea();
+                }
+            }
+        }
+        if( bFull )
+        {
+            // Durch FormatTxt kann nHeight auf 0 gesetzt worden sein
+            if ( !Height() )
+                Height( rInf.GetTxtHeight() );
+
+            bFull = SwTxtPortion::Format( rInf );
+            if ( !bFull )
+            {
+                // Jetzt noch einmal der ganze Spass
+                nDropHeight = nLines = 0;
+                delete pFnt;
+                pFnt = NULL;
+            }
+//          bFull = FormatTxt( rInf );
+        }
+        else
+            rInf.SetDropInit( sal_True );
+
+        Height( rInf.GetTxtHeight() );
+        SetAscent( rInf.GetAscent() );
+    }
+    else
+        bFull = SwTxtPortion::Format( rInf );
+//      bFull = FormatTxt( rInf );
+
+    if( bFull )
+        nDistance = 0;
+    else
+    {
+        const KSHORT nWant = Width() + GetDistance();
+        const KSHORT nRest = rInf.Width() - rInf.X();
+        if( nWant > nRest )
+        //  Robust: Kann die gewuenschte Distance nicht eingehalten werden,
+        //          gibt es gar keine!
+        //  nDistance = nWant - nRest;
+            nDistance = 0;
+
+        Width( Width() + nDistance );
+    }
+    return bFull;
+}
+
+
+
+
diff --git a/sw/source/core/text/txtfld.cxx b/sw/source/core/text/txtfld.cxx
new file mode 100644
index 000000000000..cc7167770744
--- /dev/null
+++ b/sw/source/core/text/txtfld.cxx
@@ -0,0 +1,534 @@
+/*************************************************************************
+ *
+ *  $RCSfile: txtfld.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:26 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "hintids.hxx"
+
+#ifndef _FMTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _CHARFMT_HXX //autogen
+#include 
+#endif
+
+#include "viewsh.hxx"   // NewFldPortion, GetDoc()
+#include "doc.hxx"      // NewFldPortion, GetSysFldType()
+#include "rootfrm.hxx"  // Info ueber virt. PageNumber
+#include "pagefrm.hxx"  // NewFldPortion, GetVirtPageNum()
+#include "ndtxt.hxx"    // NewNumberPortion, pHints->GetNum()
+#include "fldbas.hxx"      // SwField
+#include "viewopt.hxx"  // SwViewOptions
+#include "flyfrm.hxx"   //IsInBody()
+#include "viewimp.hxx"
+#include "txtatr.hxx"   // SwTxtFld
+
+#include "txtcfg.hxx"
+
+#include "swfont.hxx"   // NewFldPortion, new SwFont
+#include "fntcache.hxx"   // NewFldPortion, SwFntAccess
+
+#include "porfld.hxx"
+#include "porftn.hxx"   // NewExtraPortion
+#include "porref.hxx"   // NewExtraPortion
+#include "portox.hxx"   // NewExtraPortion
+#include "porhyph.hxx"   // NewExtraPortion
+#include "porfly.hxx"   // NewExtraPortion
+#include "itrform2.hxx"   // SwTxtFormatter
+
+#include "chpfld.hxx"
+#include "dbfld.hxx"
+#include "expfld.hxx"
+#include "docufld.hxx"
+#include "pagedesc.hxx"  // NewFldPortion, GetNum()
+
+
+/*************************************************************************
+ *                      SwTxtFormatter::NewFldPortion()
+ *************************************************************************/
+
+
+sal_Bool lcl_IsInBody( SwFrm *pFrm )
+{
+    if ( pFrm->IsInDocBody() )
+        return sal_True;
+    else
+    {
+        SwFrm *pTmp = pFrm;
+        SwFlyFrm *pFly;
+        while ( 0 != (pFly = pTmp->FindFlyFrm()) )
+            pTmp = pFly->GetAnchor();
+        return pTmp->IsInDocBody();
+    }
+}
+
+
+SwExpandPortion *SwTxtFormatter::NewFldPortion( SwTxtFormatInfo &rInf,
+                                                SwTxtAttr *pHint ) const
+{
+    SwExpandPortion *pRet;
+    SwFrm *pFrame = (SwFrm*)pFrm;
+    SwField *pFld = (SwField*)pHint->GetFld().GetFld();
+    const sal_Bool bName = rInf.GetOpt().IsFldName();
+
+    SwCharFmt* pChFmt = 0;
+    sal_Bool bNewFlyPor = sal_False,
+         bINet = sal_False;
+
+    // Sprache setzen
+    ((SwTxtFormatter*)this)->SeekAndChg( rInf );
+    pFld->SetLanguage( GetFnt()->GetLanguage() );
+
+    ViewShell *pSh = rInf.GetVsh();
+
+    switch( pFld->GetTyp()->Which() )
+    {
+        case RES_SCRIPTFLD:
+        case RES_POSTITFLD:
+        {
+            pRet = new SwPostItsPortion( RES_SCRIPTFLD == pFld->GetTyp()->Which() );
+            break;
+        }
+        case RES_HIDDENTXTFLD:
+        {
+            pRet = new SwHiddenPortion(pFld->GetCntnt( bName ));
+            break;
+        }
+        case RES_CHAPTERFLD:
+        {
+            if( !bName && pSh && !pSh->Imp()->IsUpdateExpFlds() )
+            {
+                ((SwChapterField*)pFld)->ChangeExpansion( pFrame,
+                                        &((SwTxtFld*)pHint)->GetTxtNode() );
+            }
+            pRet = new SwFldPortion( pFld->GetCntnt( bName ) );
+            break;
+        }
+
+        case RES_DOCSTATFLD:
+            if( !bName && pSh && !pSh->Imp()->IsUpdateExpFlds() )
+                ((SwDocStatField*)pFld)->ChangeExpansion( pFrame );
+            pRet = new SwFldPortion( pFld->GetCntnt( bName ) );
+            break;
+
+        case RES_PAGENUMBERFLD:
+        {
+            if( !bName && pSh && !pSh->Imp()->IsUpdateExpFlds() )
+            {
+                SwDoc* pDoc = pSh->GetDoc();
+                SwPageNumberFieldType *pPageNr = (SwPageNumberFieldType *)
+                                pFld->GetTyp();
+//???                               pDoc->GetSysFldType( RES_PAGENUMBERFLD );
+
+//              SwPageFrm *pPage = pFrm->FindPageFrm();
+//              sal_Bool bVirt = pPage && pPage->GetNext();
+                sal_Bool bVirt = pSh->GetLayout()->IsVirtPageNum();
+
+                MSHORT nVirtNum = pFrame->GetVirtPageNum(),
+                       nNumPages = pDoc->GetRootFrm()->GetPageNum();
+                const SvxExtNumType* pNumFmt = SVX_NUM_PAGEDESC == pFld->GetFormat()
+                    ? &pFrame->FindPageFrm()->GetPageDesc()->GetNumType().eType
+                    : 0;
+
+                pPageNr->ChangeExpansion( pDoc, nVirtNum, nNumPages,
+                                            bVirt, pNumFmt );
+            }
+            pRet = new SwFldPortion( pFld->GetCntnt( bName ) );
+            break;
+        }
+        case RES_GETEXPFLD:
+        {
+            if( !bName && pSh && !pSh->Imp()->IsUpdateExpFlds() )
+            {
+                SwGetExpField* pExpFld = (SwGetExpField*)pFld;
+                if( !::lcl_IsInBody( pFrame ) )
+                {
+                    pExpFld->ChgBodyTxtFlag( sal_False );
+                    pExpFld->ChangeExpansion( *pFrame, *((SwTxtFld*)pHint) );
+                }
+                else if( !pExpFld->IsInBodyTxt() )
+                {
+                    // war vorher anders, also erst expandieren, dann umsetzen!!
+                    pExpFld->ChangeExpansion( *pFrame, *((SwTxtFld*)pHint) );
+                    pExpFld->ChgBodyTxtFlag( sal_True );
+                }
+            }
+            pRet = new SwFldPortion( pFld->GetCntnt( bName ) );
+            break;
+        }
+        case RES_DBFLD:
+        {
+            if( !bName )
+            {
+                SwDBField* pDBFld = (SwDBField*)pFld;
+                pDBFld->ChgBodyTxtFlag( ::lcl_IsInBody( pFrame ) );
+/* Solange das ChangeExpansion auskommentiert ist.
+ * Aktualisieren in Kopf/Fuszeilen geht aktuell nicht.
+                if( !::lcl_IsInBody( pFrame ) )
+                {
+                    pDBFld->ChgBodyTxtFlag( sal_False );
+                    pDBFld->ChangeExpansion( pFrame, (SwTxtFld*)pHint );
+                }
+                else if( !pDBFld->IsInBodyTxt() )
+                {
+                    // war vorher anders, also erst expandieren, dann umsetzen!!
+                    pDBFld->ChangeExpansion( pFrame, (SwTxtFld*)pHint );
+                    pDBFld->ChgBodyTxtFlag( sal_True );
+                }
+*/
+            }
+            pRet = new SwFldPortion( pFld->GetCntnt( bName ) );
+            break;
+        }
+        case RES_REFPAGEGETFLD:
+            if( !bName && pSh && !pSh->Imp()->IsUpdateExpFlds() )
+                ((SwRefPageGetField*)pFld)->ChangeExpansion( pFrame, (SwTxtFld*)pHint );
+            pRet = new SwFldPortion( pFld->GetCntnt( bName ) );
+            break;
+
+        case RES_JUMPEDITFLD:
+            if( !bName )
+                pChFmt =  ((SwJumpEditField*)pFld)->GetCharFmt();
+            bNewFlyPor = sal_True;
+            break;
+
+        default:
+        {
+            pRet = new SwFldPortion(pFld->GetCntnt( bName ) );
+        }
+    }
+
+    if( bNewFlyPor )
+    {
+        SwFont *pTmpFnt = 0;
+        if( !bName )
+        {
+            pTmpFnt = new SwFont( *pFnt );
+            if( bINet )
+            {
+                SwAttrPool* pPool = pChFmt->GetAttrSet().GetPool();
+                SfxItemSet aSet( *pPool, RES_CHRATR_BEGIN, RES_CHRATR_END );
+                SfxItemSet aTmpSet( aSet );
+                pFrm->GetTxtNode()->GetAttr(aSet,rInf.GetIdx(),rInf.GetIdx()+1);
+                aTmpSet.Set( pChFmt->GetAttrSet() );
+                aTmpSet.Differentiate( aSet );
+                if( aTmpSet.Count() )
+                    pTmpFnt->SetDiffFnt( &aTmpSet );
+            }
+            else
+                pTmpFnt->SetDiffFnt( &pChFmt->GetAttrSet() );
+        }
+        pRet = new SwFldPortion( pFld->GetCntnt( bName ), pTmpFnt );
+    }
+
+    return pRet;
+}
+
+
+SwFldPortion *SwTxtFormatter::GetFieldRest( SwTxtFormatInfo &rInf ) const
+{
+    if( !nStart )
+        return NULL;
+    SwTxtAttr *pHint = GetAttr( nStart - 1 );
+    SwFldPortion *pRet = NULL;
+    if( !pHint )
+        return pRet;
+
+    if( pHint->Which() == RES_TXTATR_FIELD )
+    {
+        SwExpandPortion* pNew = NewFldPortion( rInf, pHint );
+        if( pNew->InFldGrp() )
+            pRet = (SwFldPortion*)pNew;
+        else
+            delete pNew;
+    }
+    return pRet;
+}
+
+
+void SwTxtFormatter::MakeRestPortion()
+{
+    const SwFldPortion* pFld = NULL;
+    const SwLinePortion* pLine = GetCurr();
+    while( pLine )
+    {
+        if( pLine->InFldGrp() )
+            pFld = (SwFldPortion*)pLine;
+        pLine = pLine->GetPortion();
+    }
+    if( pFld && pFld->HasFollow() )
+    {
+        xub_StrLen nNext = nStart + GetCurr()->GetLen();
+        if( !nNext )
+            return;
+        SwTxtAttr *pHint = GetAttr( nNext - 1 );
+        if( !pHint )
+            return;
+        SwFldPortion *pRest = NULL;
+
+        if( pHint->Which() == RES_TXTATR_FIELD )
+        {
+            SwExpandPortion* pNew = NewFldPortion( GetInfo(), pHint );
+            if( pNew->InFldGrp() )
+                pRest = (SwFldPortion*)pNew;
+            else
+                delete pNew;
+        }
+        if( pRest )
+        {
+            pRest->TakeNextOffset( pFld );
+            GetInfo().SetRest( pRest );
+        }
+    }
+}
+
+/*************************************************************************
+ *                      SwTxtFormatter::NewExtraPortion()
+ *************************************************************************/
+
+
+SwLinePortion *SwTxtFormatter::NewExtraPortion( SwTxtFormatInfo &rInf )
+{
+    SwTxtAttr *pHint = GetAttr( rInf.GetIdx() );
+    SwLinePortion *pRet = 0;
+    if( !pHint )
+    {
+#ifdef DEBUG
+//        aDbstream << "NewExtraPortion: hint not found?" << endl;
+#endif
+        pRet = new SwTxtPortion;
+        pRet->SetLen( 1 );
+        rInf.SetLen( 1 );
+        return pRet;
+    }
+
+    switch( pHint->Which() )
+    {
+        case RES_TXTATR_FLYCNT :
+        {
+            pRet = NewFlyCntPortion( rInf, pHint );
+            break;
+        }
+        case RES_TXTATR_FTN :
+        {
+            pRet = NewFtnPortion( rInf, pHint );
+            break;
+        }
+        case RES_TXTATR_SOFTHYPH :
+        {
+            pRet = new SwSoftHyphPortion;
+            break;
+        }
+        case RES_TXTATR_HARDBLANK :
+        {
+            pRet = new SwBlankPortion( ((SwTxtHardBlank*)pHint)->GetChar() );
+            break;
+        }
+        case RES_TXTATR_FIELD :
+        {
+            pRet = NewFldPortion( rInf, pHint );
+            break;
+        }
+        case RES_TXTATR_REFMARK :
+        {
+            pRet = new SwIsoRefPortion;
+            break;
+        }
+        case RES_TXTATR_TOXMARK :
+        {
+            pRet = new SwIsoToxPortion;
+            break;
+        }
+        default: ;
+    }
+    if( !pRet )
+    {
+#ifdef DEBUG
+//        aDbstream << "NewExtraPortion: unknown hint" << endl;
+#endif
+        const XubString aNothing;
+        pRet = new SwFldPortion( aNothing );
+        rInf.SetLen( 1 );
+    }
+    return pRet;
+}
+
+/*************************************************************************
+ *                      SwTxtFormatter::NewNumberPortion()
+ *************************************************************************/
+
+
+SwNumberPortion *SwTxtFormatter::NewNumberPortion( SwTxtFormatInfo &rInf ) const
+{
+    if( rInf.IsNumDone() || rInf.GetTxtStart() != nStart
+                || rInf.GetTxtStart() != rInf.GetIdx() )
+        return 0;
+
+    SwNumberPortion *pRet = 0;
+    const SwTxtNode* pTxtNd = GetTxtFrm()->GetTxtNode();
+    const SwNumRule* pNumRule = pTxtNd->GetNumRule();
+    const SwNodeNum* pNum = pTxtNd->GetNum();
+
+    if( !pNumRule )     // oder sollte OutlineNum an sein?
+    {
+        pNum = pTxtNd->GetOutlineNum();
+        if( pNum )
+            pNumRule = pTxtNd->GetDoc()->GetOutlineNumRule();
+    }
+    // hat ein "gueltige" Nummer ?
+    if( pNumRule && pNum && MAXLEVEL > pNum->GetLevel() )
+    {
+        CONST SwNumFmt &rNumFmt = pNumRule->Get( pNum->GetLevel() );
+        const sal_Bool bLeft = SVX_ADJUST_LEFT == rNumFmt.GetAdjust();
+        const sal_Bool bCenter = SVX_ADJUST_CENTER == rNumFmt.GetAdjust();
+        const KSHORT nMinDist = rNumFmt.GetCharTextOffset();
+
+        if( SVX_NUM_BITMAP == rNumFmt.eType )
+        {
+            pRet = new SwGrfNumPortion( (SwFrm*)GetTxtFrm(),rNumFmt.GetGrfBrush(),
+                rNumFmt.GetGrfOrient(), rNumFmt.GetGrfSize(),
+                bLeft, bCenter, nMinDist );
+            long nTmpA = rInf.GetLast()->GetAscent();
+            long nTmpD = rInf.GetLast()->Height() - nTmpA;
+            if( !rInf.IsTest() )
+                ((SwGrfNumPortion*)pRet)->SetBase( nTmpA, nTmpD, nTmpA, nTmpD );
+        }
+        else
+        {
+            // Der SwFont wird dynamisch angelegt und im CTOR uebergeben,
+            // weil das CharFmt nur einen SV-Font zurueckliefert.
+            // Im Dtor vom SwNumberPortion wird der SwFont deletet.
+            SwFont *pNumFnt = 0;
+            const SwAttrSet* pFmt = rNumFmt.GetCharFmt() ?
+                &rNumFmt.GetCharFmt()->GetAttrSet() : NULL;
+            if( SVX_NUM_CHAR_SPECIAL == rNumFmt.eType )
+            {
+                const Font *pFmtFnt = rNumFmt.GetBulletFont();
+                pNumFnt = new SwFont( &rInf.GetCharAttr() );
+                if( pFmt )
+                    pNumFnt->SetDiffFnt( pFmt );
+                if ( pFmtFnt )
+                {
+                    const BYTE nAct = pNumFnt->GetActual();
+                    pNumFnt->SetFamily( pFmtFnt->GetFamily(), nAct );
+                    pNumFnt->SetName( pFmtFnt->GetName(), nAct );
+                    pNumFnt->SetStyleName( pFmtFnt->GetStyleName(), nAct );
+                    pNumFnt->SetCharSet( pFmtFnt->GetCharSet(), nAct );
+                    pNumFnt->SetPitch( pFmtFnt->GetPitch(), nAct );
+                }
+                pRet = new SwBulletPortion( rNumFmt.GetBulletChar(), pNumFnt, bLeft,
+                            bCenter, nMinDist );
+            }
+            else
+            {
+                XubString aTxt( pNumRule->MakeNumString( *pNum ) );
+
+                // 7974: Nicht nur eine Optimierung...
+                // Eine Numberportion ohne Text wird die Breite von 0
+                // erhalten. Die nachfolgende Textportion wird im BreakLine
+                // in das BreakCut laufen, obwohl rInf.GetLast()->GetFlyPortion()
+                // vorliegt!
+                if( aTxt.Len() )
+                {
+                    pNumFnt = new SwFont( &rInf.GetCharAttr() );
+                    if( pFmt )
+                        pNumFnt->SetDiffFnt( pFmt );
+                    // Die SSize muss erhalten bleiben
+                    // pNumFnt->ChangeSize( rInf.GetFont()->GetSize() );
+                    pRet = new SwNumberPortion( aTxt, pNumFnt, bLeft, bCenter,
+                                                nMinDist );
+                }
+            }
+        }
+    }
+    return pRet;
+}
+
+
+const SwFldPortion* SwTxtFrm::GetRestPortion()
+{
+    if( !HasPara() )
+        GetFormatted();
+    SwTxtSizeInfo aInf( this );
+    SwTxtIter aLine( this, &aInf );
+    aLine.Bottom();
+    SwFldPortion* pRet = NULL;
+    const SwLinePortion* pLine = aLine.GetCurr();
+    while( pLine )
+    {
+        if( pLine->InFldGrp() )
+            pRet = (SwFldPortion*)pLine;
+        pLine = pLine->GetPortion();
+    }
+    if( pRet && !pRet->HasFollow() )
+        pRet = NULL;
+    return pRet;
+}
+
+
+
diff --git a/sw/source/core/text/txtfly.cxx b/sw/source/core/text/txtfly.cxx
new file mode 100644
index 000000000000..f69da3586077
--- /dev/null
+++ b/sw/source/core/text/txtfly.cxx
@@ -0,0 +1,1913 @@
+/*************************************************************************
+ *
+ *  $RCSfile: txtfly.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:26 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "frmsh.hxx"
+#include "doc.hxx"
+#include "viewsh.hxx"
+#include "pagefrm.hxx"
+#include "rootfrm.hxx"
+#include "viewimp.hxx"      // SwViewImp
+#include "pam.hxx"          // SwPosition
+#include "swregion.hxx"     // SwRegionRects
+#include "dcontact.hxx"     // SwContact
+#include "dflyobj.hxx"      // SdrObject
+#include "flyfrm.hxx"     // SwFlyFrm
+#include "frmtool.hxx"    // ::DrawGraphic
+#include "porfld.hxx"       // SwGrfNumPortion
+
+#ifdef VERT_DISTANCE
+#include 
+#endif
+
+#ifndef _XPOLY_HXX //autogen
+#include 
+#endif
+
+#ifndef _E3D_OBJ3D_HXX //autogen
+#include 
+#endif
+
+#ifndef _TXTRANGE_HXX //autogen
+#include 
+#endif
+
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_ULSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFLCNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTSRND_HXX //autogen
+#include 
+#endif
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFLCNT_HXX //autogen
+#include 
+#endif
+#ifndef _FRMFMT_HXX //autogen
+#include 
+#endif
+
+#ifndef _OUTDEV_HXX //autogen
+#include 
+#endif
+
+#ifndef _VIRDEV_HXX //autogen
+#include 
+#endif
+
+#ifndef _POLY_HXX //autogen
+#include 
+#endif
+#include "txtfrm.hxx"     // SwTxtFrm
+#include "itrform2.hxx"   // SwTxtFormatter
+#include "porfly.hxx"     // NewFlyCntPortion
+#include "porfld.hxx"     // SwGrfNumPortion
+
+#include "txtfly.hxx"     // SwTxtFly
+#include "txtpaint.hxx"   // SwSaveClip
+
+#include "txtatr.hxx"     // SwTxtFlyCnt
+#include "txtcfg.hxx"
+#include "notxtfrm.hxx"
+#include "flyfrms.hxx"
+#include "drawfont.hxx" // SwDrawTextInfo
+#include "fmtcnct.hxx"  // SwFmtChain
+
+#ifndef PRODUCT
+#include "viewopt.hxx"  // SwViewOptions, nur zum Testen (Test2)
+#endif
+
+/*****************************************************************************
+ * Beschreibung:
+ * Die Klasse SwTxtFly soll die Universalschnittstelle zwischen der
+ * Formatierung/Textausgabe und den u.U. ueberlappenden freifliegenden
+ * Frames sein.
+ * Waehrend der Formatierung erkundigt sich der Formatierer beim SwTxtFly,
+ * ob ein bestimmter Bereich durch die Attribute eines ueberlappenden
+ * Frames vorliegt. Solche Bereiche werden in Form von Dummy-Portions
+ * abgebildet.
+ * Die gesamte Textausgabe und Retusche wird ebenfalls an ein SwTxtFly
+ * weitergeleitet. Dieser entscheidet, ob Textteile geclippt werden muessen
+ * und zerteilt z.B. die Bereiche bei einem DrawRect.
+ * Zu beachten ist, dass alle freifliegenden Frames in einem nach TopLeft
+ * sortiertem PtrArray an der Seite zu finden sind. Intern wird immer nur
+ * in dokumentglobalen Werten gerechnet. Die IN- und OUT-Parameter sind
+ * jedoch in den meisten Faellen an die Beduerfnisse des LineIters
+ * zugeschnitten, d.h. sie werden in frame- oder windowlokalen Koordinaten
+ * konvertiert.
+ * Wenn mehrere Frames mit Umlaufattributen in einer Zeile liegen,
+ * ergeben sich unterschiedliche Auswirkungen fuer den Textfluss:
+ *
+ *      L/R    P     L     R     K
+ *       P   -P-P- -P-L  -P R- -P K
+ *       L   -L P- -L L  -L R- -L K
+ *       R    R-P-  R-L   R R-  R K
+ *       K    K P-  K L   K R-  K K
+ *
+ * (P=parallel, L=links, R=rechts, K=kein Umlauf)
+ *
+ * Das Verhalten so beschreiben:
+ * Jeder Rahmen kann Text verdraengen, wobei der Einfluss allerdings nur
+ * bis zum naechsten Rahmen reicht.
+ *****************************************************************************/
+
+/*****************************************************************************
+ *
+ * lcl_TheAnchor liefert den SwFrm, an dem das Objekt verankert ist.
+ *
+ *****************************************************************************/
+
+const SwFrm* lcl_TheAnchor( const SdrObject* pObj )
+{
+    SwFrm* pRet = pObj->IsWriterFlyFrame() ?
+        ( (SwVirtFlyDrawObj*)pObj )->GetFlyFrm()->GetAnchor()
+        : ( (SwDrawContact*)GetUserCall(pObj) )->GetAnchor();
+    return pRet;
+}
+
+/*****************************************************************************
+ * lcl_MaxAscDescent liefert die max. Ascents und Descents in der Zeile ohne
+ * FlyPortions (abs. und seitengeb. Objekte), einmal mit und einmal ohne
+ * Beruecksichtigung der zeichengeb. Objekte.
+ * Diese Werte sind fuer das SetBase der zeichengebundenen Objekte wichtig,
+ * wenn diese an den Zeichen oder an der Zeile ausgerichtet werden sollen.
+ *****************************************************************************/
+
+void lcl_MaxAscDescent( SwLinePortion* pPos, long &rAscent, long &rDescent,
+     long &rFlyAscent, long &rFlyDescent, SwLinePortion* pNot = NULL )
+{
+    rAscent = 0;
+    rDescent = 0;
+    rFlyAscent = 0;
+    rFlyDescent = 0;
+
+    if( !pPos->GetLen() && ( pPos->IsParaPortion() || pPos->IsLayPortion() ) )
+        pPos = pPos->GetPortion();
+
+    while ( pPos )
+    {
+        if( !pPos->IsBreakPortion() && !pPos->IsFlyPortion() )
+        {
+            sal_Bool bFlyCmp = pPos->IsFlyCntPortion() ?
+                           ((SwFlyCntPortion*)pPos)->IsMax() :  pPos != pNot;
+            if( bFlyCmp )
+            {
+                rFlyAscent = Max( rFlyAscent, (long)pPos->GetAscent() );
+                rFlyDescent = Max( rFlyDescent,
+                        (long)( pPos->Height() - pPos->GetAscent() ) );
+            }
+            if( !pPos->IsFlyCntPortion() && !pPos->IsGrfNumPortion() )
+            {
+                rAscent = Max( rAscent, (long)pPos->GetAscent() );
+                rDescent = Max( rDescent,
+                    (long)( pPos->Height() - pPos->GetAscent() ) );
+            }
+        }
+        pPos = pPos->GetPortion();
+    }
+}
+
+void SwTxtFormatter::CalcUnclipped( SwTwips& rTop, SwTwips& rBottom )
+{
+    long nFlyAsc, nFlyDesc;
+    lcl_MaxAscDescent( pCurr, rTop, rBottom, nFlyAsc, nFlyDesc );
+    rTop = Y() + GetCurr()->GetAscent();
+    rBottom = rTop + nFlyDesc;
+    rTop -= nFlyAsc;
+}
+
+/*************************************************************************
+ * SwTxtFormatter::UpdatePos() aktualisiert die Referenzpunkte der zeichengeb.
+ * Objekte, z. B. nach Adjustierung ( rechtsbuendig, Blocksatz etc. )
+ * ( hauptsaechlich Korrrektur der X-Position )
+ *************************************************************************/
+
+void SwTxtFormatter::UpdatePos( SwLineLayout *pCurr, sal_Bool bAllWays ) const
+{
+    if( GetInfo().IsTest() )
+        return;
+    SwLinePortion *pFirst = pCurr->GetFirstPortion();
+    SwLinePortion *pPos = pFirst;
+    SwTxtPaintInfo aTmpInf( GetInfo() );
+    aTmpInf.SetSpaceAdd( pCurr->GetpSpaceAdd() );
+    aTmpInf.ResetSpaceIdx();
+    // Die Groesse des Frames
+    aTmpInf.SetIdx( GetStart() );
+    aTmpInf.SetPos( GetTopLeft() );
+
+    long nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc;
+    lcl_MaxAscDescent( pPos, nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc );
+    KSHORT nAscent, nTmpHeight;
+    CalcAscentAndHeight( nAscent, nTmpHeight );
+    long nTmpY = Y() + nAscent;
+
+    while( pPos )
+    {
+        // bislang ist mir nur ein Fall bekannt, wo die Positionsaenderung
+        // (verursacht durch das Adjustment) fuer eine Portion wichtig
+        // sein koennte: Bei FlyCntPortions muss ein SetRefPoint erfolgen.
+        if( ( pPos->IsFlyCntPortion() || pPos->IsGrfNumPortion() )
+            && ( bAllWays || !IsQuick() ) )
+        {
+            lcl_MaxAscDescent( pFirst, nTmpAscent, nTmpDescent,
+                               nFlyAsc, nFlyDesc, pPos );
+            if( pPos->IsGrfNumPortion() )
+            {
+                if( !nFlyAsc && !nFlyDesc )
+                {
+                    nTmpAscent = nAscent;
+                    nFlyAsc = nAscent;
+                    nTmpDescent = nTmpHeight - nAscent;
+                    nFlyDesc = nTmpDescent;
+                }
+                ((SwGrfNumPortion*)pPos)->SetBase( nTmpAscent, nTmpDescent,
+                                                   nFlyAsc, nFlyDesc );
+            }
+            else
+            {
+                const Point aBase( aTmpInf.X(), nTmpY );
+                ((SwFlyCntPortion*)pPos)->SetBase( aBase, nTmpAscent,
+                    nTmpDescent, nFlyAsc, nFlyDesc, SETBASE_ULSPACE );
+            }
+        }
+        pPos->Move( aTmpInf );
+        pPos = pPos->GetPortion();
+    }
+}
+
+/*************************************************************************
+ * SwTxtFormatter::AlignFlyInCntBase()
+ * richtet die zeichengeb. Objekte in Y-Richtung ggf. neu aus.
+ *************************************************************************/
+
+void SwTxtFormatter::AlignFlyInCntBase( long nBaseLine ) const
+{
+    if( GetInfo().IsTest() )
+        return;
+    SwLinePortion *pFirst = pCurr->GetFirstPortion();
+    SwLinePortion *pPos = pFirst;
+
+    long nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc;
+
+    while( pPos )
+    {
+        if( pPos->IsFlyCntPortion() || pPos->IsGrfNumPortion() )
+        {
+            lcl_MaxAscDescent( pFirst, nTmpAscent, nTmpDescent,
+                               nFlyAsc, nFlyDesc, pPos );
+            if( pPos->IsGrfNumPortion() )
+                ((SwGrfNumPortion*)pPos)->SetBase( nTmpAscent, nTmpDescent,
+                                                   nFlyAsc, nFlyDesc );
+            else
+            {
+                const Point aBase( ( (SwFlyCntPortion*)pPos)->GetRefPoint().X(),
+                                   nBaseLine );
+                ((SwFlyCntPortion*)pPos)->SetBase( aBase, nTmpAscent, nTmpDescent,
+                    nFlyAsc, nFlyDesc, SETBASE_NOFLAG );
+            }
+        }
+        pPos = pPos->GetPortion();
+    }
+}
+
+/*************************************************************************
+ * SwTxtFly::ChkFlyUnderflow()
+ * ueberprueft, ob Textportions der aktuellen Zeile mit Objekten
+ * (absatz/seitengeb.) ueberlappen.
+ * Dazu wird SwTxtFly.GetFrm(..) benutzt.
+ *************************************************************************/
+
+sal_Bool SwTxtFormatter::ChkFlyUnderflow( SwTxtFormatInfo &rInf ) const
+{
+    ASSERT( rInf.GetTxtFly()->IsOn(), "SwTxtFormatter::ChkFlyUnderflow: why?" );
+    if( GetCurr() )
+    {
+        // Erst pruefen wir, ob ueberhaupt ein Fly mit der Zeile ueberlappt.
+        const long nHeight = GetLineHeight();
+        SwRect aLine( GetLeftMargin(), Y(), rInf.RealWidth(), nHeight );
+        SwRect aInter( rInf.GetTxtFly()->GetFrm( aLine ) );
+        if( !aInter.HasArea() )
+            return sal_False;
+
+        // Nun ueberpruefen wir jede Portion, die sich haette senken koennen,
+        // ob sie mit dem Fly ueberlappt.
+        const SwLinePortion *pPos = GetCurr()->GetFirstPortion();
+        while( pPos )
+        {
+            if( !pPos->IsFlyPortion() )
+            {
+                aLine.Width( pPos->Width() );
+                aInter = rInf.GetTxtFly()->GetFrm( aLine );
+                if( aInter.IsOver( aLine ) )
+                {
+                    aInter._Intersection( aLine );
+                    if( aInter.HasArea() )
+                    {
+                        rInf.SetLineHeight( KSHORT(nHeight) );
+                        return sal_True;
+                    }
+                }
+            }
+            aLine.Left( aLine.Left() + pPos->Width() );
+            pPos = pPos->GetPortion();
+        }
+    }
+    return sal_False;
+}
+
+/*************************************************************************
+ * SwTxtFormatter::CalcFlyWidth()
+ * ermittelt das naechste Objekt, das in die restliche Zeile ragt und
+ * konstruiert die zugehoerige FlyPortion.
+ * Dazu wird SwTxtFly.GetFrm(..) benutzt.
+ *************************************************************************/
+
+// Durch Flys kann sich der rechte Rand verkuerzen.
+
+void SwTxtFormatter::CalcFlyWidth( SwTxtFormatInfo &rInf ) const
+{
+    SwTxtFly *pTxtFly = rInf.GetTxtFly();
+    if( !pTxtFly->IsOn() || rInf.IsIgnoreFly() )
+        return;
+
+    register const SwLinePortion *pLast = rInf.GetLast();
+
+    long nHeight;
+    long nAscent;
+    sal_Bool bOldFly = 0 != rInf.GetFly();
+    // aLine wird dokumentglobal
+    if( bOldFly )
+    {
+        // Wenn CalcFlyWidth aus Underflow() gerufen wird, kann eine FlyPortion
+        // gesetzt sein, die Breite muss neu berechnet werden, die Hoehe ist
+        // richtig und muss als Zeilenhoehe genutzt werden
+        nHeight = rInf.GetFly()->Height();
+        nAscent = rInf.GetFly()->GetAscent();
+        delete rInf.GetFly(); // Die alte FlyPortion hat ihre Schuldigkeit getan
+        rInf.SetFly( 0 );
+    }
+    else if( rInf.GetLineHeight() )
+    {
+        nHeight = rInf.GetLineHeight();
+        nAscent = pCurr->GetAscent();
+    }
+    else
+    {
+        nHeight = pLast->Height();
+        nAscent = pLast->GetAscent();
+    }
+    const long nLeftMar = GetLeftMargin();
+    const long nLeftMin = (rInf.X() || GetDropLeft()) ? nLeftMar : GetLeftMin();
+    SwRect aLine( rInf.X() + nLeftMin, Y(),  rInf.RealWidth() - rInf.X()
+                  + nLeftMar - nLeftMin , nHeight );
+
+    SwRect aInter( pTxtFly->GetFrm( aLine ) );
+
+    if( aInter.IsOver( aLine ) )
+    {
+        aLine.Left( rInf.X() + nLeftMar );
+        sal_Bool bForced = sal_False;
+        if( aInter.Left() <= nLeftMin )
+        {
+            SwTwips nFrmLeft = GetTxtFrm()->Frm().Left();
+            if( GetTxtFrm()->Prt().Left() < 0 )
+                nFrmLeft += GetTxtFrm()->Prt().Left();
+            if( aInter.Left() < nFrmLeft )
+                aInter.Left( nFrmLeft );
+            aInter.Width( aInter.Width() + nLeftMar - nFrmLeft );
+            // Bei negativem Erstzeileneinzug setzen wir das Flag,
+            // um anzuzeigen, dass der Einzug/Rand verschoben wurde
+            // Dies muss beim DefaultTab an der Nullposition beruecksichtigt
+            // werden.
+            if( IsFirstTxtLine() && HasNegFirst() )
+                bForced = sal_True;
+        }
+        aInter.Intersection( aLine );
+        if( !aInter.HasArea() )
+            return;
+
+        const sal_Bool bFullLine =  aLine.Left()  == aInter.Left() &&
+                                aLine.Right() == aInter.Right();
+
+        // Obwohl kein Text mehr da ist, muss eine weitere Zeile
+        // formatiert werden, weil auch leere Zeilen einem Fly
+        // ohne Umlauf ausweichen muessen.
+        if( bFullLine && rInf.GetIdx() == rInf.GetTxt().Len() )
+        {
+            rInf.SetNewLine( sal_True );
+            // 8221: Dummies erkennt man an Ascent == Height
+            pCurr->SetDummy(sal_True);
+        }
+
+        // aInter wird framelokal
+        aInter.Pos().X() -= nLeftMar;
+        SwFlyPortion *pFly = new SwFlyPortion( aInter );
+        if( bForced )
+        {
+            pCurr->SetForcedLeftMargin( sal_True );
+            rInf.ForcedLeftMargin( aInter.Width() );
+        }
+
+        if( bFullLine )
+        {
+            // 8110: wir muessen um Einheiten von Zeilenhoehen anwachsen,
+            // um nebeneinanderliegende Flys mit unterschiedlichen
+            // Umlaufattributen angemessen zu umfliessen.
+            // Die letzte ausweichende Zeile, sollte in der Hoehe angepasst
+            // sein, damit nicht der Eindruck von "Rahmenabstaenden" aufkommt.
+            // 8221: Wichtig ist, dass Ascent == Height ist, weil die FlyPortionWerte
+            // im CalcLine in pCurr uebertragen werden und IsDummy() darauf
+            // angewiesen ist.
+            // Es gibt meines Wissens nur zwei Stellen, in denen DummyLines
+            // entstehen koennen: hier und in MakeFlyDummies.
+            // Ausgewertet wird IsDummy() in IsFirstTxtLine() und
+            // beim Zeilenwandern und im Zusammenhang mit DropCaps.
+            pFly->Height( KSHORT(aInter.Height()) );
+
+            // In nNextTop steckt jetzt die Unterkante des Rahmens, dem wir
+            // ausweichen oder die Oberkante des naechsten Rahmens, den wir
+            // beachten muessen. Wir koennen also jetzt getrost bis zu diesem
+            // Wert anwachsen, so sparen wir einige Leerzeilen.
+            if( pTxtFly->GetNextTop() > aInter.Bottom() )
+            {
+                SwTwips nH = pTxtFly->GetNextTop() - aInter.Top();
+                if( nH < KSHRT_MAX )
+                    pFly->Height( KSHORT( nH ) );
+            }
+            if( nAscent < pFly->Height() )
+                pFly->SetAscent( KSHORT(nAscent) );
+            else
+                pFly->SetAscent( pFly->Height() );
+        }
+        else
+        {
+            if( rInf.GetIdx() == rInf.GetTxt().Len() )
+            {
+                // Nicht nHeight nehmen, sonst haben wir einen Riesendescent
+                pFly->Height( pLast->Height() );
+                pFly->SetAscent( pLast->GetAscent() );
+            }
+            else
+            {
+                pFly->Height( KSHORT(aInter.Height()) );
+                if( nAscent < pFly->Height() )
+                    pFly->SetAscent( KSHORT(nAscent) );
+                else
+                    pFly->SetAscent( pFly->Height() );
+            }
+        }
+
+        rInf.SetFly( pFly );
+        if( !bOldFly || pFly->Fix() < rInf.Width() )
+            rInf.Width( pFly->Fix() );
+    }
+}
+
+/*****************************************************************************
+ * SwTxtFormatter::NewFlyCntPortion
+ * legt eine neue Portion fuer ein zeichengebundenes Objekt an.
+ *****************************************************************************/
+
+SwFlyCntPortion *SwTxtFormatter::NewFlyCntPortion( SwTxtFormatInfo &rInf,
+                                                   SwTxtAttr *pHint ) const
+{
+    SwFlyCntPortion *pRet = 0;
+    const SwFrm *pFrame = (SwFrm*)pFrm;
+
+    SwFlyInCntFrm *pFly;
+    SwFrmFmt* pFrmFmt = ((SwTxtFlyCnt*)pHint)->GetFlyCnt().GetFrmFmt();
+    if( RES_FLYFRMFMT == pFrmFmt->Which() )
+        pFly = ((SwTxtFlyCnt*)pHint)->GetFlyFrm(pFrame);
+    else
+        pFly = NULL;
+    // aBase bezeichnet die dokumentglobale Position,
+    // ab der die neue Extraportion plaziert wird.
+    // aBase.X() = Offset in der Zeile,
+    //             hinter der aktuellen Portion
+    // aBase.Y() = LineIter.Y() + Ascent der aktuellen Portion
+
+    SwLinePortion *pPos = pCurr->GetFirstPortion();
+
+    long nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc;
+    lcl_MaxAscDescent( pPos, nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc );
+
+    // Wenn der Ascent des Rahmens groesser als der Ascent der akt. Portion
+    // ist, wird dieser bei der Base-Berechnung verwendet, sonst wuerde
+    // der Rahmen zunaechst zu weit nach oben gesetzt, um dann doch wieder
+    // nach unten zu rutschen und dabei ein Repaint in einem Bereich ausloesen,
+    // indem er niemals wirklich war.
+    KSHORT nAscent;
+    if ( IsQuick() || !pFly || !pFly->GetValidPosFlag() ||
+            !pFly->GetRefPoint().Y() ||
+            ( nAscent = Abs( int( pFly->GetRelPos().Y() ) ) )
+            < rInf.GetLast()->GetAscent() )
+        nAscent = rInf.GetLast()->GetAscent();
+    else if( nAscent > nFlyAsc )
+        nFlyAsc = nAscent;
+
+    Point aBase( GetLeftMargin() + rInf.X(), Y() + nAscent );
+
+    if( pFly )
+    {
+        pRet = new SwFlyCntPortion( pFly, aBase, nTmpAscent, nTmpDescent,
+                                    nFlyAsc, nFlyDesc, IsQuick() );
+        // Wir muessen sicherstellen, dass unser Font wieder im OutputDevice
+        // steht. Es koennte sein, dass der FlyInCnt frisch eingefuegt wurde,
+        // dann hat GetFlyFrm dazu gefuehrt, dass er neu angelegt wird.
+        // Dessen Frames werden sofort formatiert, die verstellen den Font
+        // und schon haben wir den Salat (3322).
+        rInf.SelectFont();
+        if( pRet->GetAscent() > nAscent )
+        {
+            aBase.Y() = Y() + pRet->GetAscent();
+            sal_uInt8 nMode = SETBASE_ULSPACE;
+            if( IsQuick() )
+                nMode |= SETBASE_QUICK;
+            if( !rInf.IsTest() )
+                pRet->SetBase( aBase, nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc,
+                               nMode );
+        }
+    }
+    else
+    {
+        pRet = new SwFlyCntPortion( (SwDrawContact*)pFrmFmt->FindContactObj(),
+           aBase, nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc, IsQuick() );
+    }
+    return pRet;
+}
+
+
+
+/*************************************************************************
+ *                      SwTxtFly::SwTxtFly()
+ *************************************************************************/
+
+SwTxtFly::SwTxtFly( const SwTxtFly& rTxtFly )
+{
+    pPage = rTxtFly.pPage;
+    pCurrFly = rTxtFly.pCurrFly;
+    pCurrFrm = rTxtFly.pCurrFrm;
+    pMaster = rTxtFly.pMaster;
+    if( rTxtFly.pFlyList )
+    {
+        pFlyList = new SwFlyList( rTxtFly.pFlyList->Count(), 10 );
+        pFlyList->Insert( rTxtFly.pFlyList, 0 );
+    }
+    else
+        pFlyList = NULL;
+    bOn = rTxtFly.bOn;
+    bLeftSide = rTxtFly.bLeftSide;
+    bTopRule = rTxtFly.bTopRule;
+}
+
+void SwTxtFly::CtorInit( const SwCntntFrm *pFrm )
+{
+    pPage = pFrm->FindPageFrm();
+    const SwFlyFrm* pTmp = pFrm->FindFlyFrm();
+    pCurrFly = pTmp ? pTmp->GetVirtDrawObj() : NULL;
+    pCurrFrm = pFrm;
+    pMaster = pCurrFrm->IsFollow() ? NULL : pCurrFrm;
+    pFlyList = NULL;
+    // Wenn wir nicht von einem Frame ueberlappt werden, oder wenn
+    // es gar keine FlyCollection gibt, dann schaltet wir uns fuer immer ab.
+    // Aber es koennte sein, dass waehrend der Formatierung eine Zeile
+    // hinzukommt, die in einen Frame hineinragt. Deswegen keine Optimierung
+    // per bOn = pSortedFlys && IsAnyFrm();
+    bOn = pPage->GetSortedObjs() != 0;
+    bTopRule = sal_True;
+    bLeftSide = sal_False;
+    nMinBottom = 0;
+    nIndex = ULONG_MAX;
+}
+
+/*************************************************************************
+ *                      SwTxtFly::_GetFrm()
+ *
+ * IN:  dokumentglobal  (rRect)
+ * OUT: framelokal      (return-Wert)
+ * Diese Methode wird waehrend der Formatierung vom LineIter gerufen.
+ * 1. um die naechste FlyPortion vorzubereiten
+ * 2. um nach Aenderung der Zeilenhoehe neue Ueberlappungen festzustellen
+ *************************************************************************/
+
+SwRect SwTxtFly::_GetFrm( const SwRect &rRect, sal_Bool bTop ) const
+{
+    SwRect aRet;
+    if( ForEach( rRect, &aRet, sal_True ) )
+    {
+        if( bTop )
+            aRet.Top( rRect.Top() );
+
+        // 8110: Bottom nicht immer anpassen.
+        if( aRet.Bottom() > rRect.Bottom() || 0 > aRet.Height() )
+            aRet.Bottom( rRect.Bottom() );
+    }
+    return aRet;
+}
+
+/*************************************************************************
+ *                      SwTxtFly::IsAnyFrm()
+ *
+ * IN: dokumentglobal
+ * fuer die Printarea des aktuellen Frame
+ *
+ * dient zum Abschalten des SwTxtFly, wenn keine Objekte ueberlappen (Relax)
+ *
+ *************************************************************************/
+
+sal_Bool SwTxtFly::IsAnyFrm() const
+{
+    ASSERT( bOn, "IsAnyFrm: Why?" );
+    SwRect aRect( pCurrFrm->Frm().Pos() + pCurrFrm->Prt().Pos(),
+        pCurrFrm->Prt().SSize() );
+    return ForEach( aRect, NULL, sal_False );
+}
+
+/*************************************************************************
+ *                      SwTxtFly::IsAnyObj()
+ *
+ * IN: dokumentglobal
+ * OUT: sal_True Wenn ein Rahmen oder DrawObj beruecksichtigt werden muss
+ * Nur wenn IsAnyObj sal_False liefert, koennen Optimierungen benutzt werden
+ * wie Paint/FormatEmpty fuer leere Absaetze
+ * und auch das virtuelle Outputdevice.
+ *************************************************************************/
+
+sal_Bool SwTxtFly::IsAnyObj( const SwRect &rRect ) const
+{
+    ASSERT ( bOn, "SwTxtFly::IsAnyObj: Who's knocking?" );
+
+    SwRect aRect( rRect );
+    if ( aRect.IsEmpty() )
+        aRect = SwRect( pCurrFrm->Frm().Pos() + pCurrFrm->Prt().Pos(),
+                        pCurrFrm->Prt().SSize() );
+
+    const SwSortDrawObjs *pSorted = pPage->GetSortedObjs();
+    if( pSorted ) // Eigentlich ist durch bOn sichergestellt, dass es an der
+    // Seite Objekte gibt, aber wer weiss, wer inzwischen etwas geloescht hat.
+    {
+        for ( MSHORT i = 0; i < pSorted->Count(); ++i )
+        {
+            const SdrObject *pObj = (*pSorted)[i];
+
+            const SwRect aBound( GetBoundRect( pObj ) );
+
+            // Optimierung
+            if( pObj->GetBoundRect().Left() > aRect.Right() )
+                continue;
+
+            if( pCurrFly != pObj && aBound.IsOver( aRect ) )
+                return sal_True;
+        }
+    }
+    return sal_False;
+}
+
+const SwCntntFrm* SwTxtFly::_GetMaster()
+{
+    pMaster = pCurrFrm;
+    while( pMaster->IsFollow() )
+        pMaster = (SwCntntFrm*)pMaster->FindMaster();
+    return pMaster;
+}
+
+/*************************************************************************
+ *                      SwTxtFly::DrawTextOpaque()
+ *
+ * IN: dokumentglobal
+ * DrawTextOpaque() wird von DrawText() gerufen.
+ * Die Clipregions werden so gesetzt, dass nur die Teile ausgegeben werden,
+ * die nicht in den Bereichen von FlyFrms liegen, die undurchsichtig und
+ * ueber dem aktuellen Frame liegen.
+ * Die On-Optimierung uebernimmt DrawText()!
+ *************************************************************************/
+
+#define UINT32_MAX 0xFFFFFFFF
+
+sal_Bool SwTxtFly::DrawTextOpaque( SwDrawTextInfo &rInf )
+{
+    SwSaveClip aClipSave( rInf.GetpOut() );
+    SwRect aRect( rInf.GetPos(), rInf.GetSize() );
+    if( rInf.GetSpace() )
+    {
+        xub_StrLen nTmpLen = STRING_LEN == rInf.GetLen() ? rInf.GetText().Len() :
+                                                      rInf.GetLen();
+        if( rInf.GetSpace() > 0 )
+        {
+            xub_StrLen nSpaceCnt = 0;
+            const xub_StrLen nEndPos = rInf.GetIdx() + nTmpLen;
+            for( xub_StrLen nPos = rInf.GetIdx(); nPos < nEndPos; ++nPos )
+            {
+                if( CH_BLANK == rInf.GetText().GetChar( nPos ) )
+                    ++nSpaceCnt;
+            }
+            if( nSpaceCnt )
+                aRect.Width( aRect.Width() + nSpaceCnt * rInf.GetSpace() );
+        }
+        else
+            aRect.Width( aRect.Width() - nTmpLen * rInf.GetSpace() );
+    }
+
+    if( aClipSave.IsOn() && rInf.GetOut().IsClipRegion() )
+    {
+        SwRect aClipRect( rInf.GetOut().GetClipRegion().GetBoundRect() );
+        aRect.Intersection( aClipRect );
+    }
+
+    SwRegionRects aRegion( aRect );
+
+    sal_Bool bOpaque = sal_False;
+    const UINT32 nCurrOrd = pCurrFly ? pCurrFly->GetOrdNum() : UINT32_MAX;
+    ASSERT( !bTopRule, "DrawTextOpaque: Wrong TopRule" );
+
+    MSHORT nCount;
+    if( bOn && ( 0 != ( nCount = GetFlyList()->Count() ) ) )
+    {
+        MSHORT nHellId = pPage->GetShell()->GetDoc()->GetHellId();
+        for( MSHORT i = 0; i < nCount; ++i )
+        {
+            const SdrObject *pTmp = (*pFlyList)[ i ];
+            if( pTmp->IsWriterFlyFrame() && pCurrFly != pTmp )
+            {
+                SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pTmp)->GetFlyFrm();
+                if( aRegion.GetOrigin().IsOver( pFly->Frm() ) )
+                {
+                    const SwFrmFmt *pFmt = pFly->GetFmt();
+                    const SwFmtSurround &rSur = pFmt->GetSurround();
+                    const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
+                        //Nur undurchsichtige und weiter oben liegende.
+                    if( ( SURROUND_THROUGHT == rSur.GetSurround() &&
+                          ( !rSur.IsAnchorOnly() ||
+                            GetMaster() == lcl_TheAnchor( pTmp ) ||
+                            ( FLY_AT_CNTNT != rAnchor.GetAnchorId() &&
+                              FLY_AUTO_CNTNT != rAnchor.GetAnchorId() ) ) &&
+                          pTmp->GetLayer() != nHellId &&
+                          nCurrOrd < pTmp->GetOrdNum() ) )
+                    {
+                        //Ausser der Inhalt ist Transparent
+                        const SwNoTxtFrm *pNoTxt =
+                                pFly->Lower() && pFly->Lower()->IsNoTxtFrm()
+                                                   ? (SwNoTxtFrm*)pFly->Lower()
+                                                   : 0;
+                        if ( !pNoTxt ||
+                             (!pNoTxt->IsTransparent() && !rSur.IsContour()) )
+                        {
+                            bOpaque = sal_True;
+                            aRegion -= pFly->Frm();
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    Point aPos( rInf.GetPos().X(), rInf.GetPos().Y() + rInf.GetAscent() );
+    const Point &rOld = rInf.GetPos();
+    rInf.SetPos( aPos );
+
+    if( !bOpaque )
+    {
+        if( rInf.GetKern() )
+            rInf.GetFont()->_DrawStretchText( rInf );
+        else
+            rInf.GetFont()->_DrawText( rInf );
+        rInf.SetPos( rOld );
+        return sal_False;
+    }
+    else if( aRegion.Count() )
+    {
+        // Was fuer ein Aufwand ...
+        SwSaveClip aClipVout( rInf.GetpOut() );
+        for( MSHORT i = 0; i < aRegion.Count(); ++i )
+        {
+            SwRect &rRect = aRegion[i];
+            if( rRect != aRegion.GetOrigin() )
+                aClipVout.ChgClip( rRect );
+            if( rInf.GetKern() )
+                rInf.GetFont()->_DrawStretchText( rInf );
+            else
+                rInf.GetFont()->_DrawText( rInf );
+        }
+    }
+    rInf.SetPos( rOld );
+    return sal_True;
+}
+
+/*************************************************************************
+ *                      SwTxtFly::DrawFlyRect()
+ *
+ * IN: windowlokal
+ * Zwei Feinheiten gilt es zu beachten:
+ * 1) DrawRect() oberhalb des ClipRects sind erlaubt !
+ * 2) FlyToRect() liefert groessere Werte als die Framedaten !
+ *************************************************************************/
+
+void SwTxtFly::DrawFlyRect( OutputDevice *pOut, const SwRect &rRect,
+        const SwTxtPaintInfo &rInf, sal_Bool bNoGraphic )
+{
+    SwRegionRects aRegion( rRect );
+    ASSERT( !bTopRule, "DrawFlyRect: Wrong TopRule" );
+    MSHORT nCount;
+    if( bOn && ( 0 != ( nCount = GetFlyList()->Count() ) ) )
+    {
+        MSHORT nHellId = pPage->GetShell()->GetDoc()->GetHellId();
+        Size aPixelSz = Size( 1, 1 );
+        aPixelSz = pOut->PixelToLogic( aPixelSz );
+        for( MSHORT i = 0; i < nCount; ++i )
+        {
+            const SdrObject *pTmp = (*pFlyList)[ i ];
+            if( pCurrFly != pTmp && pTmp->IsWriterFlyFrame() )
+            {
+                const SwFrmFmt *pFmt =
+                    ((SwContact*)GetUserCall(pTmp))->GetFmt();
+                const SwFmtSurround &rSur = pFmt->GetSurround();
+
+                if( ( SURROUND_THROUGHT == rSur.GetSurround() ) ?
+                    pTmp->GetLayer() != nHellId : !rSur.IsContour() )
+                {
+                    SwRect aFly( pTmp->GetBoundRect() );
+                    aFly.Left( aFly.Left() - aPixelSz.Width() );
+                    aFly.Top( aFly.Top() - aPixelSz.Height() );
+                    if( aFly.Width() > 0 && aFly.Height() > 0 )
+                        aRegion -= aFly;
+                }
+            }
+        }
+    }
+
+    for( MSHORT i = 0; i < aRegion.Count(); ++i )
+    {
+        if ( bNoGraphic )
+            pOut->DrawRect( aRegion[i].SVRect() );
+        else
+        {
+            ASSERT( ((SvxBrushItem*)-1) != rInf.GetBrushItem(),
+                    "DrawRect: Uninitialized BrushItem!" );
+            ::DrawGraphic( rInf.GetBrushItem(), pOut, rInf.GetBrushRect(),
+                       aRegion[i] );
+        }
+    }
+}
+
+/*************************************************************************
+ *                      SwTxtFly::GetTop()
+ *
+ * GetTop() ueberprueft, ob pNew ueber pCurrFly liegt (Z-Order).
+ * Es gilt, dass die unten liegenden die obenliegenden beachten nicht
+ * umgekehrt !
+ * Returnwert: pNew, wenn pNew ueber pCurrFly liegt, ansonsten 0.
+ * wird nur von InitFlyList benutzt, um die in Frage kommenden Objekte
+ * einzusammeln.
+ *************************************************************************/
+
+sal_Bool SwTxtFly::GetTop( const SdrObject *pNew, const sal_Bool bFooter )
+{
+    if( pNew != pCurrFly )
+    {
+        if( bFooter && bTopRule )
+        {
+            const SwFmtAnchor& rNewA =
+                ((SwContact*)GetUserCall(pNew))->GetFmt()->GetAnchor();
+            if( FLY_PAGE == rNewA.GetAnchorId() )
+                return sal_False; // Im Footer wird seitengeb. nicht ausgewichen
+        }
+        sal_Bool bEvade = !pCurrFly  //Selbst nicht im Fly -> allen ausweichen.
+                 //Den Lowern ist auszuweichen.
+            || Is_Lower_Of(((SwVirtFlyDrawObj*)pCurrFly)->GetFlyFrm(), pNew);
+        if ( !bEvade )
+        {
+            if ( !bTopRule )
+                bEvade = sal_True; // nur an der Paint-Ordnung interessiert
+            else
+            {
+                // innerhalb von verketteten Flys wird nur Lowern ausgewichen
+                const SwFmtChain &rChain = ((SwContact*)GetUserCall(pCurrFly))->GetFmt()->GetChain();
+                if ( !rChain.GetPrev() && !rChain.GetNext() )
+                {
+                    // Ausweichregel fuer Text:
+                    const SwFmtAnchor& rNewA =
+                        ((SwContact*)GetUserCall(pNew))->GetFmt()->GetAnchor();
+                    const SwFmtAnchor& rCurrA =
+                        ((SwContact*)GetUserCall(pCurrFly))->GetFmt()->GetAnchor();
+                    if( FLY_IN_CNTNT == rCurrA.GetAnchorId() )
+                        return sal_False; // Zeichengebundene weichen nur Lowern aus.
+                    if( FLY_PAGE == rNewA.GetAnchorId() )
+                    {   //Chg: Seitengebundenen wird nur noch von anderen
+                        // seitengebundenen ausgewichen!
+                        if( FLY_PAGE == rCurrA.GetAnchorId() )
+                            bEvade = sal_True;
+                        else
+                            return sal_False;
+                    }
+                    else if( FLY_PAGE == rCurrA.GetAnchorId() )
+                        return sal_False; // Seitengebundene weichen nur seitengeb. aus
+                    else if( FLY_AT_FLY == rNewA.GetAnchorId() )
+                        bEvade = sal_True; // Nicht seitengeb. weichen Rahmengeb. aus
+                    else if( FLY_AT_FLY == rCurrA.GetAnchorId() )
+                        return sal_False; // Rahmengebundene weichen abs.geb. nicht aus
+                    else // Zwei Flies mit (auto-)absatzgebunder Verankerung ...
+                    // ... entscheiden nach der Reihenfolge ihrer Anker im Dok.
+                        bEvade = rNewA.GetCntntAnchor()->nNode.GetIndex() <=
+                                rCurrA.GetCntntAnchor()->nNode.GetIndex();
+                }
+            }
+            // aber: es wird niemals einem hierarchisch untergeordnetem
+            // ausgewichen und ausserdem braucht nur bei Ueberlappung
+            // ausgewichen werden.
+            bEvade &= ( pCurrFly->GetOrdNum() < pNew->GetOrdNum() );
+            if( bEvade )
+            {
+                SwRect aTmp( GetBoundRect( pNew ) );
+                if( !aTmp.IsOver( pCurrFly->GetBoundRect() ) )
+                    bEvade = sal_False;
+            }
+        }
+        if ( bEvade )
+        {
+            const SwFmtAnchor& rNewA =
+                ((SwContact*)GetUserCall(pNew))->GetFmt()->GetAnchor();
+            ASSERT( FLY_IN_CNTNT != rNewA.GetAnchorId(), "Don't call GetTop with a FlyInCntFrm" );
+            if( FLY_PAGE == rNewA.GetAnchorId() )
+                return sal_True;  // Seitengebundenen wird immer ausgewichen.
+
+            // Wenn absatzgebundene Flys in einem FlyCnt gefangen sind, so
+            // endet deren Einflussbereich an den Grenzen des FlyCnt!
+            // Wenn wir aber gerade den Text des FlyCnt formatieren, dann
+            // muss er natuerlich dem absatzgebundenen Frm ausweichen!
+            // pCurrFrm ist der Anker von pNew?
+            const SwFrm* pTmp = lcl_TheAnchor( pNew );
+            if( pTmp == pCurrFrm )
+                return sal_True;
+            if( pTmp->IsTxtFrm() && ( pTmp->IsInFly() || pTmp->IsInFtn() ) )
+            {
+                Point aPos;
+                if( pNew->IsWriterFlyFrame() )
+                    aPos = ( (SwVirtFlyDrawObj*)pNew )->GetFlyFrm()->Frm().Pos();
+                else
+                    aPos = pNew->GetBoundRect().TopLeft();
+                pTmp = GetVirtualUpper( pTmp, aPos );
+            }
+            if( pCurrFrm->GetNext() != pTmp &&
+                IsFrmInSameKontext( pTmp, pCurrFrm ) )
+            {
+                if( FLY_AT_FLY == rNewA.GetAnchorId() ) // LAYER_IMPL
+                    return sal_True;  // Rahmengebundenen ausweichen.
+                // Den Index des anderen erhalten wir immer ueber das Ankerattr.
+                ULONG nTmpIndex = rNewA.GetCntntAnchor()->nNode.GetIndex();
+                // Jetzt wird noch ueberprueft, ob der aktuelle Absatz vor dem
+                // Anker des verdraengenden Objekts im Text steht, dann wird
+                // nicht ausgewichen.
+                // Der Index wird moeglichst ueber einen SwFmtAnchor ermittelt,
+                // da sonst recht teuer.
+                if( ULONG_MAX == nIndex )
+                    nIndex = pCurrFrm->GetNode()->GetIndex();
+
+                if( nIndex >= nTmpIndex )
+                    return sal_True;
+            }
+        }
+    }
+    return 0;
+}
+
+/*************************************************************************
+ * SwTxtFly::InitFlyList()
+ *
+ * fuellt die FlyList mit den Objekten, denen ggf. ausgwichen werden muss
+ *
+ *************************************************************************/
+
+SwFlyList *SwTxtFly::InitFlyList()
+{
+    ASSERT( pCurrFrm, "InitFlyList: No Frame, no FlyList" );
+    ASSERT( !pFlyList, "InitFlyList: FlyList already initialized" );
+
+    const SwSortDrawObjs *pSorted = pPage->GetSortedObjs();
+    const MSHORT nCount = pSorted ? pSorted->Count() : 0;
+    bOn = sal_False;
+    if( nCount )
+    {
+        pFlyList = new SwFlyList( 10, 10 );
+
+        SwRect aRect( pCurrFrm->Prt() );
+        aRect += pCurrFrm->Frm().Pos();
+        // Wir machen uns etwas kleiner als wir sind,
+        // damit Ein-Twip-Ueberlappungen ignoriert werden. (#49532)
+        const long nRight = aRect.Right() - 1;
+        const long nLeft = aRect.Left() + 1;
+        const sal_Bool bFooter = pCurrFrm->IsInFtn();
+
+        for( MSHORT i = 0; i < nCount; i++ )
+        {
+            SdrObject *pO = (*pSorted)[ i ];
+            const SwRect aBound( GetBoundRect( pO ) );
+            if( nRight < aBound.Left() || aRect.Top() > aBound.Bottom() ||
+                nLeft > aBound.Right() )
+                continue;
+            if( GetTop( pO, bFooter ) )
+            {
+                MSHORT nPos = pFlyList->Count();
+                while( nPos )
+                {
+                    SdrObject *pTmp = (*pFlyList)[ --nPos ];
+                    const SwRect aTmpBound( GetBoundRect( pTmp ) );
+                    if( aTmpBound.Left() <= aBound.Left() )
+                    {
+                        ++nPos;
+                        break;
+                    }
+                }
+                pFlyList->C40_INSERT( SdrObject, pO, nPos );
+
+                SwContact *pContact = (SwContact*)GetUserCall(pO);
+                const SwFmtSurround &rFlyFmt = pContact->GetFmt()->GetSurround();
+                if( rFlyFmt.IsAnchorOnly() && lcl_TheAnchor( pO ) == GetMaster() )
+                {
+                    const SwFmtVertOrient &rTmpFmt = pContact->GetFmt()->GetVertOrient();
+                    if( VERT_BOTTOM != rTmpFmt.GetVertOrient() )
+                        nMinBottom = Max( nMinBottom, aBound.Bottom() );
+                }
+
+                bOn = sal_True;
+            }
+        }
+        if( nMinBottom )
+        {
+            SwTwips nMax = pCurrFrm->GetUpper()->Frm().Top() +
+                           pCurrFrm->GetUpper()->Prt().Bottom();
+            if( nMinBottom > nMax )
+                nMinBottom = nMax;
+        }
+    }
+    else
+        pFlyList = new SwFlyList( 0, 10 );
+    return pFlyList;
+}
+
+SwTwips SwTxtFly::CalcMinBottom() const
+{
+    SwTwips nRet = 0;
+    const SwDrawObjs *pDrawObj = GetMaster()->GetDrawObjs();
+    const MSHORT nCount = pDrawObj ? pDrawObj->Count() : 0;
+    if( nCount )
+    {
+        SwTwips nEndOfFrm = pCurrFrm->Frm().Bottom();
+        for( MSHORT i = 0; i < nCount; i++ )
+        {
+            SdrObject *pO = (*pDrawObj)[ i ];
+            SwContact *pContact = (SwContact*)GetUserCall(pO);
+            const SwFmtSurround &rFlyFmt = pContact->GetFmt()->GetSurround();
+            if( rFlyFmt.IsAnchorOnly() )
+            {
+                const SwFmtVertOrient &rTmpFmt = pContact->GetFmt()->GetVertOrient();
+                if( VERT_BOTTOM != rTmpFmt.GetVertOrient() )
+                {
+                    const SwRect aBound( GetBoundRect( pO ) );
+                    if( aBound.Top() < nEndOfFrm )
+                        nRet = Max( nRet, aBound.Bottom() );
+                }
+            }
+        }
+        SwTwips nMax = pCurrFrm->GetUpper()->Frm().Top() +
+                       pCurrFrm->GetUpper()->Prt().Bottom();
+        if( nRet > nMax )
+            nRet = nMax;
+    }
+    return nRet;
+}
+
+/*************************************************************************
+ * Hier erfolgt die Berechnung der Kontur ...
+ * CalcBoundRect(..) und andere
+ *************************************************************************/
+
+/*************************************************************************
+ * class SwContourCache
+ *************************************************************************/
+
+SwContourCache::SwContourCache() :
+    nObjCnt( 0 ), nPntCnt( 0 )
+{
+    memset( (SdrObject**)pSdrObj, 0, sizeof(pSdrObj) );
+    memset( pTextRanger, 0, sizeof(pTextRanger) );
+}
+
+SwContourCache::~SwContourCache()
+{
+    for( MSHORT i = 0; i < nObjCnt; delete pTextRanger[ i++ ] )
+        ;
+}
+
+void SwContourCache::ClrObject( MSHORT nPos )
+{
+    ASSERT( pTextRanger[ nPos ], "ClrObject: Allready cleared. Good Bye!" );
+    nPntCnt -= pTextRanger[ nPos ]->GetPointCount();
+    delete pTextRanger[ nPos ];
+    --nObjCnt;
+    memmove( (SdrObject**)pSdrObj + nPos, pSdrObj + nPos + 1,
+             ( nObjCnt - nPos ) * sizeof( SdrObject* ) );
+    memmove( pTextRanger + nPos, pTextRanger + nPos + 1,
+             ( nObjCnt - nPos ) * sizeof( TextRanger* ) );
+}
+
+void ClrContourCache( const SdrObject *pObj )
+{
+    if( pContourCache && pObj )
+        for( MSHORT i = 0; i < pContourCache->GetCount(); ++i )
+            if( pObj == pContourCache->GetObject( i ) )
+            {
+                pContourCache->ClrObject( i );
+                break;
+            }
+}
+
+void ClrContourCache()
+{
+    if( pContourCache )
+    {
+        for( MSHORT i = 0; i < pContourCache->GetCount();
+             delete pContourCache->pTextRanger[ i++ ] )
+             ;
+        pContourCache->nObjCnt = 0;
+        pContourCache->nPntCnt = 0;
+    }
+}
+
+/*************************************************************************
+ * SwContourCache::CalcBoundRect
+ * berechnet das Rechteck, welches vom Objekt in der angegebenen Zeile
+ * ueberdeckt wird.
+ * Bei _nicht_ konturumflossenen Objekten ist dies einfach die Ueber-
+ * lappung von BoundRect (inkl. Abstand!) und Zeile,
+ * bei Konturumfluss wird das Polypolygon des Objekts abgeklappert
+ *************************************************************************/
+
+const SwRect SwContourCache::CalcBoundRect( const SdrObject* pObj,
+    const SwRect &rLine, const long nXPos, const sal_Bool bRight )
+{
+    SwRect aRet;
+    const SwFmt *pFmt =
+        ((SwContact*)GetUserCall(pObj))->GetFmt();
+    if( pFmt->GetSurround().IsContour() &&
+        ( !pObj->IsWriterFlyFrame() ||
+          ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->Lower() &&
+          ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->Lower()->IsNoTxtFrm() ) )
+    {
+        const SvxLRSpaceItem &rLRSpace = pFmt->GetLRSpace();
+        const SvxULSpaceItem &rULSpace = pFmt->GetULSpace();
+        aRet = pObj->GetBoundRect();
+        aRet.Left( aRet.Left() - rLRSpace.GetLeft() );
+        aRet.Width( aRet.Width() + rLRSpace.GetRight() );
+        aRet.Top( aRet.Top() - rULSpace.GetUpper() );
+        aRet.Height( aRet.Height() + rULSpace.GetLower() );
+        if( aRet.IsOver( rLine ) )
+        {
+            if( !pContourCache )
+                pContourCache = new SwContourCache;
+            aRet = pContourCache->ContourRect( pFmt, pObj, rLine, nXPos, bRight );
+        }
+        else
+            aRet.Width( 0 );
+    }
+    else
+    {
+        const SvxLRSpaceItem &rLRSpace = pFmt->GetLRSpace();
+        aRet = pObj->GetBoundRect();
+        aRet.Left( aRet.Left() - rLRSpace.GetLeft() );
+        aRet.Width( aRet.Width() + rLRSpace.GetRight() );
+    }
+    const SvxULSpaceItem &rULSpace = pFmt->GetULSpace();
+    aRet.Top( aRet.Top() - rULSpace.GetUpper() );
+    aRet.Height( aRet.Height() + rULSpace.GetLower() );
+    return aRet;
+}
+
+const SwRect SwContourCache::ContourRect( const SwFmt* pFmt,
+    const SdrObject* pObj, const SwRect &rLine,
+    const long nXPos, const sal_Bool bRight )
+{
+    SwRect aRet;
+    MSHORT nPos = 0; // Suche im Cache ...
+    while( nPos < GetCount() && pObj != pSdrObj[ nPos ] )
+        ++nPos;
+    if( GetCount() == nPos ) // nicht gefunden
+    {
+        if( nObjCnt == POLY_CNT )
+        {
+            nPntCnt -= pTextRanger[ --nObjCnt ]->GetPointCount();
+            delete pTextRanger[ nObjCnt ];
+        }
+        XPolyPolygon aXPoly;
+        XPolyPolygon *pXPoly = NULL;
+        if ( pObj->IsWriterFlyFrame() )
+        {
+            // Vorsicht #37347: Das GetContour() fuehrt zum Laden der Grafik,
+            // diese aendert dadurch ggf. ihre Groesse, ruft deshalb ein
+            // ClrObject() auf.
+            PolyPolygon aPoly;
+            if( !((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->GetContour( aPoly ) )
+                aPoly = PolyPolygon( ((SwVirtFlyDrawObj*)pObj)->
+                                     GetFlyFrm()->Frm().SVRect() );
+            aXPoly = XPolyPolygon( aPoly );
+        }
+        else
+        {
+            if( !pObj->ISA( E3dObject ) )
+                pObj->TakeXorPoly( aXPoly, sal_True );
+            pXPoly = new XPolyPolygon();
+            pObj->TakeContour( *pXPoly );
+        }
+        const SvxLRSpaceItem &rLRSpace = pFmt->GetLRSpace();
+        const SvxULSpaceItem &rULSpace = pFmt->GetULSpace();
+        memmove( pTextRanger + 1, pTextRanger, nObjCnt * sizeof( TextRanger* ) );
+        memmove( (SdrObject**)pSdrObj + 1, pSdrObj, nObjCnt++ * sizeof( SdrObject* ) );
+        pSdrObj[ 0 ] = pObj; // Wg. #37347 darf das Object erst nach dem
+                             // GetContour() eingetragen werden.
+        pTextRanger[ 0 ] = new TextRanger( aXPoly, pXPoly, 20,
+            rLRSpace.GetLeft(), rLRSpace.GetRight(),
+            pFmt->GetSurround().IsOutside(), sal_False );
+        pTextRanger[ 0 ]->SetUpper( rULSpace.GetUpper() );
+        pTextRanger[ 0 ]->SetLower( rULSpace.GetLower() );
+        delete pXPoly;
+        // UPPER_LOWER_TEST
+#ifndef PRODUCT
+        if( pFmt->GetDoc()->GetRootFrm()->GetCurrShell() )
+        {
+            sal_Bool bT2 =  pFmt->GetDoc()->GetRootFrm()->GetCurrShell()->GetViewOptions()->IsTest2();
+            sal_Bool bT6 = pFmt->GetDoc()->GetRootFrm()->GetCurrShell()->GetViewOptions()->IsTest6();
+            if( bT2 || bT6 )
+            {
+                if( bT2 )
+                    pTextRanger[ 0 ]->SetFlag7( sal_True );
+                else
+                    pTextRanger[ 0 ]->SetFlag6( sal_True );
+            }
+        }
+#endif
+        nPntCnt += pTextRanger[ 0 ]->GetPointCount();
+        while( nPntCnt > POLY_MAX && nObjCnt > POLY_MIN )
+        {
+            nPntCnt -= pTextRanger[ --nObjCnt ]->GetPointCount();
+            delete pTextRanger[ nObjCnt ];
+        }
+    }
+    else if( nPos )
+    {
+        const SdrObject* pTmpObj = pSdrObj[ nPos ];
+        TextRanger* pTmpRanger = pTextRanger[ nPos ];
+        memmove( (SdrObject**)pSdrObj + 1, pSdrObj, nPos * sizeof( SdrObject* ) );
+        memmove( pTextRanger + 1, pTextRanger, nPos * sizeof( TextRanger* ) );
+        pSdrObj[ 0 ] = pTmpObj;
+        pTextRanger[ 0 ] = pTmpRanger;
+    }
+    Range aRange( rLine.Top(), rLine.Bottom() );
+    SvLongs *pTmp = pTextRanger[ 0 ]->GetTextRanges( aRange );
+
+    MSHORT nCount;
+    if( 0 != ( nCount = pTmp->Count() ) )
+    {
+        MSHORT nIdx = 0;
+        while( nIdx < nCount && (*pTmp)[ nIdx ] < nXPos )
+            ++nIdx;
+        sal_Bool bOdd = nIdx % 2 ? sal_True : sal_False;
+        sal_Bool bSet = sal_True;
+        if( bOdd )
+            --nIdx; // innerhalb eines Intervalls
+        else if( !bRight && ( nIdx >= nCount || (*pTmp)[ nIdx ] != nXPos ) )
+        {
+            if( nIdx )
+                nIdx -= 2; // ein Intervall nach links gehen
+            else
+                bSet = sal_False; // vor dem erstem Intervall
+        }
+
+        if( bSet && nIdx < nCount )
+        {
+            aRet.Top( rLine.Top() );
+            aRet.Height( rLine.Height() );
+            aRet.Left( (*pTmp)[ nIdx ] );
+            aRet.Right( (*pTmp)[ nIdx + 1 ] );
+        }
+    }
+    return aRet;
+}
+
+/*************************************************************************
+ *                      SwContourCache::ShowContour()
+ * zeichnet die PolyPolygone des Caches zu Debugzwecken.
+ *************************************************************************/
+#ifndef PRODUCT
+
+void SwContourCache::ShowContour( OutputDevice* pOut, const SdrObject* pObj,
+    const Color& rClosedColor, const Color& rOpenColor )
+{
+    MSHORT nPos = 0; // Suche im Cache ...
+    while( nPos < POLY_CNT && pObj != pSdrObj[ nPos ] )
+        ++nPos;
+    if( POLY_CNT != nPos )
+    {
+        const PolyPolygon* pPol = pTextRanger[ nPos ]->GetLinePolygon();
+        if( !pPol )
+            pPol = &(pTextRanger[ nPos ]->GetPolyPolygon());
+        for( MSHORT i = 0; i < pPol->Count(); ++i )
+        {
+            pOut->SetLineColor( rOpenColor );
+            const Polygon& rPol = (*pPol)[ i ];
+            MSHORT nCount = rPol.GetSize();
+            if( nCount > 1 && rPol[ 0 ] == rPol[ nCount - 1 ] )
+                pOut->SetLineColor( rClosedColor );
+            pOut->DrawPolygon( rPol );
+        }
+#ifdef DEBUG
+        static KSHORT nRadius = 0;
+        if( nRadius )
+        {
+            KSHORT nHalf = nRadius / 2;
+            Size aSz( nRadius, nRadius );
+            for( MSHORT i = 0; i < pPol->Count(); ++i )
+            {
+                const Polygon& rPol = (*pPol)[ i ];
+                MSHORT nCount = rPol.GetSize();
+                for( MSHORT k = 0; k < nCount; ++k )
+                {
+                    Point aPt( rPol[ k ] );
+                    aPt.X() -= nHalf;
+                    aPt.Y() -= nHalf;
+                    Rectangle aTmp( aPt, aSz );
+                    pOut->DrawEllipse( aTmp );
+                }
+            }
+        }
+#endif
+    }
+}
+#endif
+
+/*************************************************************************
+ *                      SwTxtFly::ShowContour()
+ * zeichnet die PolyPolygone des Caches zu Debugzwecken.
+ *************************************************************************/
+#ifndef PRODUCT
+
+void SwTxtFly::ShowContour( OutputDevice* pOut )
+{
+    MSHORT nFlyCount;
+    if( bOn && ( 0 != ( nFlyCount = GetFlyList()->Count() ) ) )
+    {
+        static ULONG nWidth = 20;
+        Color aRedColor( COL_LIGHTRED );
+        Color aGreenColor( COL_LIGHTGREEN );
+        Color aSaveColor( pOut->GetLineColor() );
+        for( MSHORT j = 0; j < nFlyCount; ++j )
+        {
+            const SdrObject *pObj = (*pFlyList)[ j ];
+            if( !((SwContact*)GetUserCall(pObj))->GetFmt()->GetSurround().IsContour() )
+            {
+                Rectangle aRect = pObj->GetBoundRect();
+                pOut->DrawRect( aRect );
+                continue;
+            }
+            pContourCache->ShowContour( pOut, pObj, aRedColor, aGreenColor );
+        }
+        pOut->SetLineColor( aSaveColor );
+    }
+}
+#endif
+
+/*************************************************************************
+ *                      SwTxtFly::ForEach()
+ *
+ * sucht nach dem ersten Objekt, welches mit dem Rechteck ueberlappt
+ *
+ *************************************************************************/
+
+sal_Bool SwTxtFly::ForEach( const SwRect &rRect, SwRect* pRect, sal_Bool bAvoid ) const
+{
+    sal_Bool bRet = sal_False;
+    MSHORT nCount;
+    if( bOn && ( 0 != ( nCount = GetFlyList()->Count() ) ) )
+    {
+        for( MSHORT i = 0; i < nCount; ++i )
+        {
+            const SdrObject *pObj = (*pFlyList)[ i ];
+            SwRect aRect( GetBoundRect( pObj ) );
+            // Optimierung
+            if( aRect.Left() > rRect.Right() )
+                break;
+            if( pCurrFly != pObj && aRect.IsOver( rRect ) )
+            {
+                const SwFmt *pFmt = ((SwContact*)GetUserCall(pObj))->GetFmt();
+                const SwFmtSurround &rSur = pFmt->GetSurround();
+                if( bAvoid )
+                {
+                    // Wenn der Text drunter durchlaeuft, bleibt die
+                    // Formatierung unbeeinflusst. Im LineIter::DrawText()
+                    // muessen "nur" geschickt die ClippingRegions gesetzt werden ...
+                    const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
+                    if( ( SURROUND_THROUGHT == rSur.GetSurround() &&
+                          ( !rSur.IsAnchorOnly() ||
+                            GetMaster() == lcl_TheAnchor( pObj ) ||
+                            ( FLY_AT_CNTNT != rAnchor.GetAnchorId() &&
+                              FLY_AUTO_CNTNT != rAnchor.GetAnchorId() ) ) )
+                        || aRect.Top() == WEIT_WECH )
+                        continue;
+                }
+                if( pRect )
+                {
+                    SwRect aFly = FlyToRect( pObj, rRect );
+                    if( aFly.IsEmpty() || !aFly.IsOver( rRect ) )
+                        continue;
+                    if( !bRet || aFly.Left() < pRect->Left() )
+                        *pRect = aFly;
+                    if( rSur.IsContour() )
+                    {
+                        bRet = sal_True;
+                        continue;
+                    }
+                }
+                bRet = sal_True;
+                break;
+            }
+        }
+    }
+    return bRet;
+}
+
+/*************************************************************************
+ *                      SwTxtFly::GetPos()
+ *
+ * liefert die Position im sorted Array zurueck
+ *************************************************************************/
+
+MSHORT SwTxtFly::GetPos( const SdrObject *pObj ) const
+{
+    MSHORT nCount = GetFlyList()->Count();
+    MSHORT nRet = 0;
+    while( nRet < nCount && pObj != (*pFlyList)[ nRet ] )
+        ++nRet;
+    return nRet;
+}
+
+/*************************************************************************
+ *                      SwTxtFly::CalcRightMargin()
+ *
+ * pObj ist das Object, der uns gerade ueberlappt.
+ * pCurrFrm ist der aktuelle Textframe, der ueberlappt wird.
+ * Der rechte Rand ist der rechte Rand oder
+ * er wird durch das naechste Object, welches in die Zeile ragt, bestimmt.
+ *************************************************************************/
+
+void SwTxtFly::CalcRightMargin( SwRect &rFly, MSHORT nFlyPos,
+                                  const SwRect &rLine ) const
+{
+    // Normalerweise ist der rechte Rand der rechte Rand der Printarea.
+    SwTwips nRight = pCurrFrm->Frm().Left() + pCurrFrm->Prt().Right() + 1;
+    SwTwips nFlyRight = rFly.Right();
+    SwRect aLine( rLine );
+    aLine.Right( nRight );
+    aLine.Left( rFly.Left() );
+
+    // Es koennte aber sein, dass in die gleiche Zeile noch ein anderes
+    // Object hineinragt, welches _ueber_ uns liegt.
+    // Wunder der Technik: Flys mit Durchlauf sind fuer die darunterliegenden
+    // unsichtbar, das heisst, dass sie bei der Berechnung der Raender
+    // anderer Flys ebenfalls nicht auffallen.
+    // 3301: pNext->Frm().IsOver( rLine ) ist noetig
+    _FlyCntnt eOrder;
+
+    sal_Bool bStop = sal_False;
+    MSHORT nPos = 0;
+
+    while( nPos < pFlyList->Count() && !bStop )
+    {
+        if( nPos == nFlyPos )
+        {
+            ++nPos;
+            continue;
+        }
+        const SdrObject *pNext = (*pFlyList)[ nPos++ ];
+        if( pNext == pCurrFly )
+            continue;
+        eOrder = GetOrder( pNext );
+        if( SURROUND_THROUGHT == eOrder )
+            continue;
+        const SwRect aTmp( SwContourCache::CalcBoundRect
+            ( pNext, aLine, nFlyRight, sal_True ) );
+        SwTwips nTmpRight = aTmp.Right();
+
+        // Optimierung:
+        // In nNextTop wird notiert, an welcher Y-Positon mit Aenderung der
+        // Rahmenverhaeltnisse gerechnet werden muss. Dies dient dazu, dass,
+        // obwohl nur die Rahmen in der aktuellen Zeilenhoehe betrachtet werden,
+        // bei Rahmen ohne Umlauf die Zeilenhoehe so erhoeht wird, dass mit einer
+        // einzigen Zeile die Unterkante das Rahmens oder ggf. die Oberkante des
+        // naechsten Rahmen erreicht wird.
+        // Insbesondere bei HTML-Dokumenten kommen oft (Dummy-)Absaetze in einer
+        // 2-Pt.-Schrift vor, bis diese einem groesseren Rahmen ausgewichen sind,
+        // erforderte es frueher Unmengen von Leerzeilen.
+        if( aLine.Top() < aTmp.Top() )
+        {
+            if( aTmp.Top() < nNextTop )
+                SetNextTop( aTmp.Top() ); // Die Oberkante des "naechsten" Rahmens
+        }
+        else if( !aTmp.Width() ) // Typisch fuer Objekte mit Konturumlauf
+        {   // Bei Objekten mit Konturumlauf, die vor der aktuellen Zeile beginnen
+            // und hinter ihr enden, trotzdem aber nicht mit ihr ueberlappen,
+            // muss die Optimierung ausgeschaltet werden, denn bereits in der
+            // naechsten Zeile kann sich dies aendern.
+            if( !aTmp.Height() || aTmp.Bottom() > aLine.Top() )
+                SetNextTop( 0 );
+        }
+
+        if( aTmp.IsOver( aLine ) && nTmpRight > nFlyRight )
+        {
+            nFlyRight = nTmpRight;
+            switch( eOrder )
+            {
+                case SURROUND_RIGHT :
+                case SURROUND_PARALLEL :
+                {
+                    // der FlyFrm wird ueberstimmt.
+                    if( nRight > nFlyRight )
+                        nRight = nFlyRight;
+                    bStop = sal_True;
+                    break;
+                }
+            }
+        }
+    }
+    rFly.Right( nRight );
+}
+
+/*************************************************************************
+ *                      SwTxtFly::CalcLeftMargin()
+ *
+ * pFly ist der FlyFrm, der uns gerade ueberlappt.
+ * pCurrFrm ist der aktuelle Textframe, der ueberlappt wird.
+ * Der linke Rand ist der linke Rand der aktuellen PrintArea oder
+ * er wird durch den vorigen FlyFrm, der in die Zeile ragt, bestimmt.
+ *************************************************************************/
+
+void SwTxtFly::CalcLeftMargin( SwRect &rFly, MSHORT nFlyPos,
+                                  const SwRect &rLine ) const
+{
+    // Normalerweise ist der linke Rand der linke Rand der Printarea.
+    SwTwips nLeft = pCurrFrm->Frm().Left() + pCurrFrm->Prt().Left();
+    if( nLeft > rFly.Left() )
+        nLeft = rFly.Left();
+    SwRect aLine( rLine );
+    aLine.Left( nLeft );
+
+    // Es koennte aber sein, dass in die gleiche Zeile noch ein anderes
+    // Object hineinragt, welches _ueber_ uns liegt.
+    // Wunder der Technik: Flys mit Durchlauf sind fuer die darunterliegenden
+    // unsichtbar, das heisst, dass sie bei der Berechnung der Raender
+    // anderer Flys ebenfalls nicht auffallen.
+    // 3301: pNext->Frm().IsOver( rLine ) ist noetig
+
+    MSHORT nMyPos = nFlyPos;
+    while( ++nFlyPos < pFlyList->Count() )
+    {
+        const SdrObject *pNext = (*pFlyList)[ nFlyPos ];
+        const SwRect aTmp( GetBoundRect( pNext ) );
+        if( aTmp.Left() >= rFly.Left() )
+            break;
+    }
+
+    while( nFlyPos )
+    {
+        if( --nFlyPos == nMyPos )
+            continue;
+        const SdrObject *pNext = (*pFlyList)[ nFlyPos ];
+        if( pNext == pCurrFly )
+            continue;
+        _FlyCntnt eOrder = GetOrder( pNext );
+        if( SURROUND_THROUGHT == eOrder )
+            continue;
+        const SwRect aTmp( SwContourCache::CalcBoundRect
+            ( pNext, aLine, rFly.Left(), sal_False ) );
+        if( aTmp.Left() < rFly.Left() && aTmp.IsOver( aLine ) )
+        {
+            SwTwips nTmpRight = aTmp.Right();
+            if( nLeft <= nTmpRight )
+                nLeft = nTmpRight + 1;
+            break;
+        }
+    }
+    rFly.Left( nLeft );
+}
+
+/*************************************************************************
+ *                      SwTxtFly::FlyToRect()
+ *
+ * IN:  dokumentglobal  (rRect)
+ * OUT: dokumentglobal  (return-Wert)
+ * Liefert zu einem SwFlyFrm das von ihm in Anspruch genommene Rechteck
+ * unter Beruecksichtigung der eingestellten Attribute fuer den Abstand
+ * zum Text zurueck.
+ *************************************************************************/
+
+SwRect SwTxtFly::FlyToRect( const SdrObject *pObj, const SwRect &rLine ) const
+{
+    SwRect aFly = SwContourCache::CalcBoundRect( pObj, rLine,
+        rLine.Left(), sal_True );
+    if( !aFly.Width() )
+        return aFly;
+
+    SetNextTop( aFly.Bottom() ); // Damit die Zeile ggf. bis zur Unterkante
+                                 // des Rahmens waechst.
+    MSHORT nFlyPos = GetPos( pObj );
+
+    // Bei LEFT und RIGHT vergroessern wir das Rechteck.
+    // Hier gibt es einige Probleme, wenn mehrere Frames zu sehen sind.
+    // Zur Zeit wird nur der einfachste Fall angenommen:
+    // LEFT bedeutet, dass der Text links vom Frame fliessen soll,
+    // d.h. der Frame blaeht sich bis zum rechten Rand der Printarea
+    // oder bis zum naechsten Frame auf.
+    // Bei RIGHT ist es umgekehrt.
+    // Ansonsten wird immer der eingestellte Abstand zwischen Text
+    // und Frame aufaddiert.
+    switch( GetOrder( pObj ) )
+    {
+        case SURROUND_LEFT :
+        {
+            CalcRightMargin( aFly, nFlyPos, rLine );
+            break;
+        }
+        case SURROUND_RIGHT :
+        {
+            CalcLeftMargin( aFly, nFlyPos, rLine );
+            break;
+        }
+        case SURROUND_NONE :
+        {
+            CalcRightMargin( aFly, nFlyPos, rLine );
+            CalcLeftMargin( aFly, nFlyPos, rLine );
+            break;
+        }
+    }
+    return aFly;
+}
+
+
+/*************************************************************************
+ *                      SwTxtFly::CalcSmart()
+ *
+ * CalcSmart() liefert die Umlaufform zurueck.
+ *
+ * Auf beiden Seiten ist weniger als 2 cm Platz fuer den Text
+ *   => kein Umlauf ( SURROUND_NONE )
+ * Auf genau einer Seite ist mehr als 2 cm Platz
+ *   => Umlauf auf dieser Seite ( SURROUND_LEFT / SURROUND_RIGHT )
+ * Auf beiden Seiten ist mehr als 2 cm Platz, das Objekt ist breiter als 1,5 cm
+ *   => Umlauf auf der breiteren Seite ( SURROUND_LEFT / SURROUND_RIGHT )
+ * Auf beiden Seiten ist mehr als 2 cm Platz, das Objekt ist schmaler als 1,5 cm
+ *   => beidseitiger Umlauf ( SURROUND_PARALLEL )
+ *
+ *************************************************************************/
+
+// Umfluss nur auf Seiten mit mindestens 2 cm Platz fuer den Text
+#define TEXT_MIN 1134
+// Beidseitiger Umfluss bis zu einer Rahmenbreite von maximal 1,5 cm
+#define FRAME_MAX 850
+
+_FlyCntnt SwTxtFly::CalcSmart( const SdrObject *pObj ) const
+{
+    _FlyCntnt eOrder;
+
+    // 11839: Nur die X-Positionen sind interessant, die Y-Positionen des
+    // CurrentFrames koennen sich noch aendern (wachsen).
+
+    const long nCurrLeft = pCurrFrm->Prt().Left() + pCurrFrm->Frm().Left();
+    const long nCurrRight = pCurrFrm->Prt().Right() + pCurrFrm->Frm().Left();
+    const SwRect aRect( GetBoundRect( pObj ) );
+    long nFlyLeft = aRect.Left();
+    long nFlyRight = aRect.Right();
+
+    if ( nFlyRight < nCurrLeft || nFlyLeft > nCurrRight )
+        eOrder = SURROUND_PARALLEL;
+    else
+    {
+#ifndef USED
+        long nLeft = nFlyLeft - nCurrLeft;
+        long nRight = nCurrRight - nFlyRight;
+        if( nFlyRight - nFlyLeft > FRAME_MAX )
+        {
+            if( nLeft < nRight )
+                nLeft = 0;
+            else
+                nRight = 0;
+        }
+        if( nLeft < TEXT_MIN )
+            nLeft = 0;
+        if( nRight < TEXT_MIN )
+            nRight = 0;
+        if( nLeft )
+            eOrder = nRight ? SURROUND_PARALLEL : SURROUND_LEFT;
+        else
+            eOrder = nRight ? SURROUND_RIGHT: SURROUND_NONE;
+#else
+        if ( nFlyRight > nCurrRight )
+            nFlyRight = nCurrRight;
+        if ( nFlyLeft < nCurrLeft )
+            nFlyLeft = nCurrLeft;
+        const long nCurrPart = ( nCurrRight - nCurrLeft )/3;
+        const long nFlyWidth = nFlyRight - nFlyLeft;
+
+        if( nFlyWidth < nCurrPart )
+            eOrder = SURROUND_PARALLEL;
+        else
+        {
+            if( nFlyWidth > (nCurrPart * 2) )
+                eOrder = SURROUND_NONE;
+            else
+            {
+                const long nHalfCurr = ( nCurrRight + nCurrLeft ) / 2;
+                const long nHalfFly  = ( nFlyRight + nFlyLeft ) / 2 ;
+                if ( nHalfFly == nHalfCurr )
+                    eOrder = SURROUND_COLUMN;
+                else
+                    eOrder = nHalfFly < nHalfCurr ?
+                             SURROUND_RIGHT : SURROUND_LEFT;
+            }
+        }
+#endif
+    }
+
+    return eOrder;
+}
+
+/*************************************************************************
+ *                      SwTxtFly::GetOrder()
+ *************************************************************************/
+
+_FlyCntnt SwTxtFly::GetOrder( const SdrObject *pObj ) const
+{
+    const SwFrmFmt *pFmt = ((SwContact*)GetUserCall(pObj))->GetFmt();
+    const SwFmtSurround &rFlyFmt = pFmt->GetSurround();
+    _FlyCntnt eOrder = rFlyFmt.GetSurround();
+
+    if( rFlyFmt.IsAnchorOnly() && lcl_TheAnchor( pObj ) != GetMaster() )
+    {
+        const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
+        if( FLY_AT_CNTNT == rAnchor.GetAnchorId() ||
+            FLY_AUTO_CNTNT == rAnchor.GetAnchorId() )
+            return SURROUND_NONE;
+    }
+
+    // Beim Durchlauf und Nowrap wird smart ignoriert.
+    if( SURROUND_THROUGHT == eOrder || SURROUND_NONE == eOrder )
+        return eOrder;
+
+    // "idealer Seitenumlauf":
+    if( SURROUND_IDEAL == eOrder )
+        eOrder = CalcSmart( pObj ); //Bei SMART wird die Order automatisch berechnet:
+
+    return eOrder;
+}
+
+/*************************************************************************
+ *                      SwTxtFly::IsAnyFrm( SwRect )
+ *
+ * IN: dokumentglobal
+ *
+ * dient zum Abschalten des SwTxtFly, wenn keine Objekte ueberlappen (Relax)
+ *
+ *************************************************************************/
+
+sal_Bool SwTxtFly::IsAnyFrm( const SwRect &rLine ) const
+{
+    ASSERT( bOn, "IsAnyFrm: Why?" );
+    return ForEach( rLine, NULL, sal_False );
+}
+
+const SwFrmFmt* SwTxtFrm::IsFirstBullet()
+{
+    GetFormatted();
+    const SwLineLayout *pLayout = GetPara();
+    if( !pLayout ||
+        ( !pLayout->GetLen() && !pLayout->GetPortion() && !pLayout->GetNext() ) )
+        return NULL;
+
+    SwLinePortion* pPor = pLayout->GetFirstPortion();
+    while( pPor->IsFlyPortion() && pPor->GetPortion() )
+        pPor = pPor->GetPortion();
+    SwLinePortion* pTmp;
+    do
+    {
+        pTmp = pLayout->GetFirstPortion();
+        while( pTmp && !pTmp->InTxtGrp() )
+            pTmp = pTmp->GetPortion();
+        pLayout = pLayout->GetNext();
+    } while( !pTmp && pLayout );
+    long nMaxHeight = pTmp ? ( pTmp->Height() * 15 ) / 10 : 0;
+    if( !nMaxHeight )
+        return NULL;
+
+    long nMaxWidth = 2*pTmp->Height();
+    if( pPor->IsFlyCntPortion() &&
+        ( pPor->Height() < nMaxHeight && pPor->Width() < nMaxWidth ) )
+        return ((SwFlyCntPortion*)pPor)->GetFrmFmt();
+
+    const SwFrmFmt* pRet = NULL;
+
+    SwPageFrm* pPage = FindPageFrm();
+    const SwSortDrawObjs *pSorted = pPage->GetSortedObjs();
+    if( pSorted )
+    {
+        for ( MSHORT i = 0; i < pSorted->Count(); ++i )
+        {
+            const SdrObject *pObj = (*pSorted)[i];
+            if( this == lcl_TheAnchor( pObj ) )
+            {
+                SwRect aBound( GetBoundRect( pObj ) );
+                if( aBound.Top() > Frm().Top() + Prt().Top() )
+                    aBound.Top( Frm().Top() + Prt().Top() );
+                if( aBound.Left() > Frm().Left() + Prt().Left() )
+                    aBound.Left( Frm().Left() + Prt().Left() );
+                if( aBound.Height() < nMaxHeight && aBound.Width() < nMaxWidth )
+                {
+                    pRet = ((SwContact*)GetUserCall(pObj))->GetFmt();
+                    _FlyCntnt eOrder = pRet->GetSurround().GetSurround();
+                    if( SURROUND_THROUGHT == eOrder || SURROUND_NONE == eOrder )
+                        pRet = NULL;
+                    else
+                        break;
+                }
+            }
+        }
+    }
+    return pRet;
+}
+
+
diff --git a/sw/source/core/text/txtfly.hxx b/sw/source/core/text/txtfly.hxx
new file mode 100644
index 000000000000..a056650a43e7
--- /dev/null
+++ b/sw/source/core/text/txtfly.hxx
@@ -0,0 +1,275 @@
+/*************************************************************************
+ *
+ *  $RCSfile: txtfly.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:26 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _TXTFLY_HXX
+#define _TXTFLY_HXX
+
+#ifndef _SVARRAY_HXX //autogen
+#include 
+#endif
+
+#include "swtypes.hxx"
+#include "swrect.hxx"
+
+class OutputDevice;
+class VirtualDevice;
+class SwFont;
+class SwCntntFrm;
+class SwFlyFrm;
+class SwPageFrm;
+class SwTxtFly;
+class SdrObject;
+class SwWrongList;
+class SwTxtPaintInfo;
+class SwFmt;
+class PolyPolygon;
+class TextRanger;
+class Color;
+
+// eine kleine Schweinerei, weil enums nicht forward-deklariert werden koennen.
+typedef MSHORT _FlyCntnt;
+
+SV_DECL_PTRARR( SwFlyList, SdrObject*, 10, 10 )
+
+/*************************************************************************
+ *                      class SwFlyIter
+ *************************************************************************/
+enum PAGESIDE { LEFT_SIDE, RIGHT_SIDE, DONTKNOW_SIDE };
+
+/*************************************************************************
+ *                      class SwContourCache
+ *************************************************************************/
+
+class SwDrawTextInfo;
+// Contour-Cache, globale Variable, in txtinit.cxx initialisiert/zerstoert
+// und in txtfly.cxx benutzt bei Konturumfluss
+class SwContourCache;
+extern SwContourCache *pContourCache;
+
+#define POLY_CNT 20
+#define POLY_MIN 5
+#define POLY_MAX 4000
+
+class SwContourCache
+{
+    friend void ClrContourCache();
+    const SdrObject *pSdrObj[ POLY_CNT ];
+    TextRanger *pTextRanger[ POLY_CNT ];
+    long nPntCnt;
+    MSHORT nObjCnt;
+    const SwRect ContourRect( const SwFmt* pFmt, const SdrObject* pObj,
+        const SwRect &rLine, const long nXPos, const sal_Bool bRight );
+public:
+    SwContourCache();
+    ~SwContourCache();
+    const SdrObject* GetObject( MSHORT nPos ){ return pSdrObj[ nPos ]; }
+    MSHORT GetCount() const { return nObjCnt; }
+    void ClrObject( MSHORT nPos );
+    static const SwRect CalcBoundRect( const SdrObject* pObj,
+        const SwRect &rLine, const long nXPos, const sal_Bool bRight );
+#ifndef PRODUCT
+    void ShowContour( OutputDevice* pOut, const SdrObject* pObj,
+                      const Color& rClosedColor, const Color& rOpenColor );
+#endif
+};
+
+/*************************************************************************
+ *                      class SwTxtFly
+ *************************************************************************/
+
+class SwTxtFly
+{
+    const SwPageFrm     *pPage;
+    const SdrObject     *pCurrFly;
+    const SwCntntFrm    *pCurrFrm;
+    const SwCntntFrm    *pMaster;
+    SwFlyList           *pFlyList;
+    long nMinBottom;
+    long nNextTop; // Hier wird die Oberkante des "naechsten" Rahmens gespeichert
+    ULONG nIndex;
+    sal_Bool bOn : 1;
+    sal_Bool bLeftSide : 1;
+    sal_Bool bTopRule: 1;
+    SwRect _GetFrm( const SwRect &rPortion, sal_Bool bTop ) const;
+    SwFlyList* InitFlyList();
+    // iteriert ueber die Fly-Liste
+    sal_Bool ForEach( const SwRect &rRect, SwRect* pRect, sal_Bool bAvoid ) const;
+    _FlyCntnt CalcSmart( const SdrObject *pObj ) const;
+    // liefert die Order eines FlyFrms
+    _FlyCntnt GetOrder( const SdrObject *pObj ) const;
+    void CalcRightMargin( SwRect &rFly, MSHORT nPos, const SwRect &rLine ) const;
+    void CalcLeftMargin( SwRect &rFly, MSHORT nPos, const SwRect &rLine ) const;
+    MSHORT GetPos( const SdrObject *pObj ) const;
+    sal_Bool GetTop( const SdrObject *pNew, const sal_Bool bFooter );
+    SwTwips CalcMinBottom() const;
+    const SwCntntFrm* _GetMaster();
+
+public:
+    inline SwTxtFly() { pFlyList = 0; pMaster = 0; }
+    inline SwTxtFly( const SwCntntFrm *pFrm ) { CtorInit( pFrm ); }
+    SwTxtFly( const SwTxtFly& rTxtFly );
+    inline ~SwTxtFly() { delete pFlyList; }
+    void CtorInit( const SwCntntFrm *pFrm );
+    void SetTopRule(){ bTopRule = sal_False; }
+
+    SwFlyList* GetFlyList() const
+        { return pFlyList ? pFlyList : ((SwTxtFly*)this)->InitFlyList(); }
+    inline SwRect GetFrm( const SwRect &rPortion, sal_Bool bTop = sal_True ) const;
+    inline sal_Bool IsOn() const { return bOn; }
+    inline sal_Bool Relax( const SwRect &rRect );
+    inline sal_Bool Relax();
+    inline SwTwips GetMinBottom() const
+        { return pFlyList ? nMinBottom : CalcMinBottom(); }
+    inline const SwCntntFrm* GetMaster() const
+        { return pMaster ? pMaster : ((SwTxtFly*)this)->_GetMaster(); }
+    inline long GetNextTop() const { return nNextTop; }
+    // Diese temporaere Variable darf auch in const-Methoden manipuliert werden
+    inline void SetNextTop( long nNew ) const
+        { ((SwTxtFly*)this)->nNextTop = nNew;   }
+
+    // Liefert zu einem SdrObject das von ihm _beanspruchte_ Rect
+    // (unter Beruecksichtigung der Order) zurueck.
+    SwRect FlyToRect( const SdrObject *pObj, const SwRect &rRect ) const;
+
+    // Die Drawmethoden stellen sicher, dass ueberlappende Frames
+    // (ausser bei transparenten Frames) nicht uebergepinselt werden.
+    sal_Bool DrawTextOpaque( SwDrawTextInfo &rInf );
+
+    void DrawFlyRect( OutputDevice *pOut, const SwRect &rRect,
+                      const SwTxtPaintInfo &rInf, sal_Bool bNoGraphic = sal_False );
+
+    // Liefert zurueck, ob die Zeile von einem Frame ueberlappt wird.
+    sal_Bool IsAnyFrm( const SwRect &rLine ) const;
+    sal_Bool IsAnyFrm() const;
+    //Das Rechteck kann leer sein, es gilt dann der Frm.
+    sal_Bool IsAnyObj( const SwRect& ) const;
+
+#ifndef PRODUCT
+    void ShowContour( OutputDevice* pOut );
+#endif
+};
+
+// Wenn in das rRect (meist die aktuelle Zeile) kein freifliegender
+// Frame ragt, dann schalten wir uns ab.
+// rRect ist dokumentglobal !
+inline sal_Bool SwTxtFly::Relax( const SwRect &rRect )
+{
+    return 0 != (bOn = bOn && IsAnyFrm( rRect ));
+}
+
+inline sal_Bool SwTxtFly::Relax()
+{
+    return 0 != (bOn = bOn && IsAnyFrm());
+}
+
+inline SwRect SwTxtFly::GetFrm( const SwRect &rRect, sal_Bool bTop ) const
+{
+    return bOn ? _GetFrm( rRect, bTop ) : SwRect();
+}
+
+/*************************************************************************
+
+      $Log: not supported by cvs2svn $
+      Revision 1.105  2000/09/18 16:04:23  willem.vandorp
+      OpenOffice header added.
+
+      Revision 1.104  2000/09/08 13:25:45  willem.vandorp
+      Header and footer replaced
+
+      Revision 1.103  2000/04/13 09:59:17  ama
+      Unicode changes
+
+      Revision 1.102  2000/03/03 15:17:21  os
+      StarView remainders removed
+
+      Revision 1.101  1999/04/06 12:13:32  AMA
+      Fix #64178#: Geringe Zeilenhoehe und grosse Rahmen ohne Umlauf
+
+
+      Rev 1.100   06 Apr 1999 14:13:32   AMA
+   Fix #64178#: Geringe Zeilenhoehe und grosse Rahmen ohne Umlauf
+
+      Rev 1.99   01 Apr 1998 11:17:46   AMA
+   Fix #48894#: Bei AnchorOnly muss natuerlich der Master verglichen werden!
+
+      Rev 1.98   28 Jan 1998 13:41:56   MA
+   ueberfluessiges Hell-Paint vom Text entfernt
+
+      Rev 1.97   20 Nov 1997 17:33:20   MA
+   includes
+
+      Rev 1.96   09 Oct 1997 16:16:10   JP
+   Umstellung NodeIndex/-Array/BigPtrArray
+
+      Rev 1.95   26 Sep 1997 14:44:12   AMA
+   Opt: IsAnyObj meldet Ueberlappung mit Objekten ohne Kontur/Umlauf-Feinheiten
+
+      Rev 1.94   24 Sep 1997 09:46:24   AMA
+   Opt: Weniger Flackern durch Nutzung eines virtuellen OutputDevices
+
+      Rev 1.93   23 Sep 1997 12:03:44   AMA
+   Opt: Weniger Flackern durch Nutzung eines virtuellen OutputDevices
+
+      Rev 1.92   23 Jul 1997 13:07:36   AMA
+   Fix #41891#: Fuer Fly/Footer-Loops wird MakeFlyDummy reanimiert und optimiert
+
+*************************************************************************/
+
+#endif
diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx
new file mode 100644
index 000000000000..ee91f0e144bf
--- /dev/null
+++ b/sw/source/core/text/txtfrm.cxx
@@ -0,0 +1,1834 @@
+/*************************************************************************
+ *
+ *  $RCSfile: txtfrm.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:26 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _SFX_PRINTER_HXX //autogen
+#include 
+#endif
+
+#ifndef _SFX_SFXUNO_HXX
+#include 
+#endif
+#ifndef _SVX_LANGITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_LSPCITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_ULSPITEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _DOC_HXX
+#include       // GetDoc()
+#endif
+#ifndef _PAGEFRM_HXX
+#include   // InvalidateSpelling
+#endif
+#ifndef _VIEWSH_HXX
+#include    // ViewShell
+#endif
+#ifndef _PAM_HXX
+#include       // SwPosition
+#endif
+#ifndef _NDTXT_HXX
+#include         // SwTxtNode
+#endif
+#ifndef _TXTATR_HXX
+#include 
+#endif
+#ifndef _PARATR_HXX
+#include 
+#endif
+#ifndef _HINTS_HXX
+#include         // SwInsChr
+#endif
+#ifndef _VIEWOPT_HXX
+#include 
+#endif
+#ifndef _DFLYOBJ_HXX
+#include 
+#endif
+#ifndef _FLYFRM_HXX
+#include 
+#endif
+#ifndef _TABFRM_HXX
+#include 
+#endif
+#ifndef _FRMTOOL_HXX
+#include 
+#endif
+#ifndef _DBG_LAY_HXX
+#include 
+#endif
+#ifndef _FMTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFTN_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFTN_HXX //autogen
+#include 
+#endif
+#ifndef _FRMATR_HXX
+#include 
+#endif
+#ifndef _CHARATR_HXX
+#include 
+#endif
+#ifndef _FTNINFO_HXX //autogen
+#include 
+#endif
+#ifndef _FMTLINE_HXX
+#include 
+#endif
+#ifndef _TXTFRM_HXX
+#include        // SwTxtFrm
+#endif
+#ifndef _SECTFRM_HXX
+#include       // SwSectFrm
+#endif
+#ifndef _TXTCFG_HXX
+#include        // DBG_LOOP
+#endif
+#ifndef _ITRFORM2_HXX
+#include        // Iteratoren
+#endif
+#ifndef _WIDORP_HXX
+#include        // SwFrmBreak
+#endif
+#ifndef _TXTCACHE_HXX
+#include 
+#endif
+#ifndef _SWFONT_HXX
+#include        // GetLineSpace benutzt SwFonts
+#endif
+#ifndef _FNTCACHE_HXX
+#include      // GetLineSpace benutzt pLastFont
+#endif
+#ifndef _FRMSH_HXX
+#include 
+#endif
+#ifndef _WRONG_HXX
+#include         // SwWrongList
+#endif
+#ifndef _LINEINFO_HXX
+#include 
+#endif
+
+#ifdef DEBUG
+#ifndef _TXTPAINT_HXX
+#include      // DbgRect
+#endif
+extern const sal_Char *GetPrepName( const enum PrepareHint ePrep );
+#endif
+
+TYPEINIT1( SwTxtFrm, SwCntntFrm );
+
+
+/*************************************************************************
+ *                      SwTxtFrm::Init()
+ *************************************************************************/
+
+void SwTxtFrm::Init()
+{
+    ASSERT( !IsLocked(), "+SwTxtFrm::Init: this ist locked." );
+    if( !IsLocked() )
+    {
+        ClearPara();
+        ResetBlinkPor();
+        //Die Flags direkt setzen um ResetPreps und damit ein unnuetzes GetPara
+        //einzusparen.
+        // Nicht bOrphan, bLocked oder bWait auf sal_False setzen !
+        // bOrphan = bFlag7 = bFlag8 = sal_False;
+    }
+}
+
+/*************************************************************************
+|*  SwTxtFrm::CTORen/DTOR
+|*************************************************************************/
+
+void SwTxtFrm::InitCtor()
+{
+    nCacheIdx = MSHRT_MAX;
+    nOfst = 0;
+    nAllLines = 0;
+    nThisLines = 0;
+    nType = FRM_TXT;
+    bLocked = bFormatted = bWidow = bUndersized = bJustWidow =
+        bEmpty = bInFtnConnect = bFtn = bRepaint = bBlinkPor =
+        bFieldFollow = bHasAnimation = sal_False;
+}
+
+
+SwTxtFrm::SwTxtFrm(SwTxtNode * const pNode)
+    : SwCntntFrm(pNode)
+{
+    InitCtor();
+}
+
+const XubString& SwTxtFrm::GetTxt() const
+{
+    return GetTxtNode()->GetTxt();
+}
+
+void SwTxtFrm::ResetPreps()
+{
+    if ( GetCacheIdx() != MSHRT_MAX )
+    {
+        SwParaPortion *pPara;
+        if( 0 != (pPara = GetPara()) )
+            pPara->ResetPreps();
+    }
+}
+
+/*************************************************************************
+ *                        SwTxtFrm::IsHiddenNow()
+ *************************************************************************/
+// liefert nur sal_True zurueck, wenn das Outputdevice ein Printer ist
+// und bHidden gesetzt ist.
+
+sal_Bool SwTxtFrm::IsHiddenNow() const
+{
+    if( !Frm().Width() && IsValid() && GetUpper()->IsValid() )
+                                       //bei Stackueberlauf (StackHack) invalid!
+    {
+        ASSERT( Frm().Width(), "SwTxtFrm::IsHiddenNow: thin frame" );
+        return sal_True;
+    }
+
+    if( !GetTxtNode()->IsVisible() )
+    {
+        const ViewShell *pVsh = GetShell();
+        if ( !pVsh )
+            return sal_False;
+        return OUTDEV_PRINTER == pVsh->GetOut()->GetOutDevType() ||
+               (!pVsh->GetViewOptions()->IsShowHiddenPara()      &&
+                !pVsh->GetViewOptions()->IsFldName());
+    }
+    else
+        return sal_False;
+}
+
+
+/*************************************************************************
+ *                        SwTxtFrm::HideHidden()
+ *************************************************************************/
+// Entfernt die Anhaengsel des Textfrms wenn dieser hidden ist
+
+void SwTxtFrm::HideHidden()
+{
+    ASSERT( IsHiddenNow(), "HideHidden on visible frame" );
+
+    //Erst die Fussnoten
+    const SwpHints *pHints = GetTxtNode()->GetpSwpHints();
+    if( pHints )
+    {
+        const MSHORT nSize = pHints->Count();
+        const xub_StrLen nEnd = GetFollow() ? GetFollow()->GetOfst():STRING_LEN;
+        SwPageFrm *pPage = 0;
+        for( MSHORT i = 0; i < nSize; ++i )
+        {
+            const SwTxtAttr *pHt = (*pHints)[i];
+            if ( pHt->Which() == RES_TXTATR_FTN )
+            {
+                const xub_StrLen nIdx = *pHt->GetStart();
+                if ( nEnd < nIdx )
+                    break;
+                if( GetOfst() <= nIdx )
+                {
+                    if( !pPage )
+                        pPage = FindPageFrm();
+                    pPage->RemoveFtn( this, (SwTxtFtn*)pHt );
+                }
+            }
+        }
+    }
+    //Dann die zeichengebundenen Rahmen
+    if ( GetDrawObjs() )
+    {
+        for ( int i = GetDrawObjs()->Count()-1; i >= 0; --i )
+        {
+            SdrObject *pObj = (*GetDrawObjs())[i];
+            SwFlyFrm *pFly;
+            if ( pObj->IsWriterFlyFrame() &&
+                 (pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm())->IsFlyInCntFrm())
+            {
+                pFly->GetAnchor()->RemoveFly( pFly );
+                delete pFly;
+            }
+        }
+    }
+    //Die Formatinfos sind jetzt obsolete
+    ClearPara();
+}
+
+
+/*************************************************************************
+ *                      SwTxtFrm::FindBrk()
+ *
+ * Liefert die erste Trennmoeglichkeit in der aktuellen Zeile zurueck.
+ * Die Methode wird in SwTxtFrm::Format() benutzt, um festzustellen, ob
+ * die Vorgaengerzeile mitformatiert werden muss.
+ * nFound ist <= nEndLine.
+ *************************************************************************/
+
+xub_StrLen SwTxtFrm::FindBrk( const XubString &rTxt,
+                          const xub_StrLen nStart, const xub_StrLen nEnd ) const
+{
+    xub_StrLen nFound = nStart;
+    const xub_StrLen nEndLine = Min( nEnd, rTxt.Len() );
+
+    // Wir ueberlesen erst alle Blanks am Anfang der Zeile (vgl. Bug 2235).
+    while( nFound <= nEndLine && ' ' == rTxt.GetChar( nFound ) )
+         ++nFound;
+
+    // Eine knifflige Sache mit den TxtAttr-Dummy-Zeichen (hier "$"):
+    // "Dr.$Meyer" am Anfang der zweiten Zeile. Dahinter ein Blank eingegeben
+    // und das Wort rutscht nicht in die erste Zeile, obwohl es ginge.
+    // Aus diesem Grund nehmen wir das Dummy-Zeichen noch mit.
+    while( nFound <= nEndLine && ' ' != rTxt.GetChar( nFound ) )
+        ++nFound;
+
+    return nFound;
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::IsIdxInside()
+ *************************************************************************/
+
+sal_Bool SwTxtFrm::IsIdxInside( const xub_StrLen nPos, const xub_StrLen nLen ) const
+{
+    if( GetOfst() > nPos + nLen ) // d.h., der Bereich liegt komplett vor uns.
+        return sal_False;
+
+    if( !GetFollow() )         // der Bereich liegt nicht komplett vor uns,
+        return sal_True;           // nach uns kommt niemand mehr.
+
+    const xub_StrLen nMax = GetFollow()->GetOfst();
+
+    // der Bereich liegt nicht komplett hinter uns bzw.
+    // unser Text ist geloescht worden.
+    if( nMax > nPos || nMax > GetTxt().Len() )
+        return sal_True;
+
+    // WICHTIG: Nun kann es noch sein, dass das erste Wort unseres Follows
+    // in uns hochrutschen koennte:
+    const xub_StrLen nNewPos = FindBrk( GetTxt(), nMax, nPos + 1 );
+    return nNewPos >= nPos;
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::InvalidateRange()
+ *************************************************************************/
+inline void SwTxtFrm::InvalidateRange(const SwCharRange &aRange, const long nD)
+{
+    if ( IsIdxInside( aRange.Start(), aRange.Len() ) )
+        _InvalidateRange( aRange, nD );
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::_InvalidateRange()
+ *************************************************************************/
+
+void SwTxtFrm::_InvalidateRange( const SwCharRange &aRange, const long nD)
+{
+    if ( !HasPara() )
+    {   InvalidateSize();
+        return;
+    }
+
+    SetWidow( sal_False );
+    SwParaPortion *pPara = GetPara();
+
+    sal_Bool bInv = sal_False;
+    if( 0 != nD )
+    {
+        //Auf nDelta werden die Differenzen zwischen alter und
+        //neuer Zeilenlaenge aufaddiert, deshalb ist es negativ,
+        //wenn Zeichen eingefuegt wurden, positiv, wenn Zeichen
+        //geloescht wurden.
+        *(pPara->GetDelta()) += nD;
+        bInv = sal_True;
+    }
+    SwCharRange &rReformat = *(pPara->GetReformat());
+    if(aRange != rReformat) {
+        if( STRING_LEN == rReformat.Len() )
+            rReformat = aRange;
+        else
+            rReformat += aRange;
+        bInv = sal_True;
+    }
+    if(bInv)
+    {
+        if( GetFollow() )
+            ((SwTxtFrm*)GetFollow())->InvalidateRange( aRange, nD );
+        InvalidateSize();
+    }
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::CalcLineSpace()
+ *************************************************************************/
+
+void SwTxtFrm::CalcLineSpace()
+{
+    if( IsLocked() || !HasPara() )
+        return;
+
+    SwParaPortion *pPara;
+    if( GetDrawObjs() ||
+        GetTxtNode()->GetSwAttrSet().GetLRSpace().IsAutoFirst() ||
+        ( pPara = GetPara() )->IsFixLineHeight() )
+    {
+        Init();
+        return;
+    }
+
+    Size aNewSize( Prt().SSize() );
+    SwTxtFormatInfo aInf( this );
+    SwTxtFormatter aLine( this, &aInf );
+    if( aLine.GetDropLines() )
+    {
+        Init();
+        return;
+    }
+
+    aLine.Top();
+    aLine.RecalcRealHeight();
+
+    aNewSize.Height() = (aLine.Y() - Frm().Top()) + aLine.GetLineHeight();
+
+    SwTwips nDelta = aNewSize.Height() - Prt().Height();
+    // 4291: Unterlauf bei Flys
+    if( aInf.GetTxtFly()->IsOn() )
+    {
+        SwRect aFrm( Frm() );
+        if( nDelta < 0 )
+            aFrm.Height( Prt().Height() );
+        else
+            aFrm.Height( aNewSize.Height() );
+        if( aInf.GetTxtFly()->Relax( aFrm ) )
+        {
+            Init();
+            return;
+        }
+    }
+
+    if( nDelta )
+    {
+        SwTxtFrmBreak aBreak( this );
+        if( GetFollow() || aBreak.IsBreakNow( aLine ) )
+        {
+            // Wenn es einen Follow() gibt, oder wenn wir an dieser
+            // Stelle aufbrechen muessen, so wird neu formatiert.
+            Init();
+        }
+        else
+        {
+            // Alles nimmt seinen gewohnten Gang ...
+            pPara->SetPrepAdjust();
+            pPara->SetPrep();
+#ifdef USED
+            if (nDelta > 0)
+                Grow(nDelta,pHeight);
+            else
+                Shrink(-nDelta,pHeight);
+            ASSERT( GetPara(), "+SwTxtFrm::CalcLineSpace: missing format information" );
+            if( pPara )
+                pPara->GetRepaint()->SSize( Prt().SSize() );
+#endif
+        }
+    }
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::Modify()
+ *************************************************************************/
+
+#define SET_WRONG( nPos, nCnt, fnFunc )\
+    if( GetTxtNode()->GetWrong() && !IsFollow() )\
+        GetTxtNode()->GetWrong()->fnFunc( nPos, nCnt );\
+    GetNode()->SetWrongDirty( sal_True );\
+    GetNode()->SetAutoCompleteWordDirty(  sal_True );\
+    SwPageFrm *pPage = FindPageFrm();\
+    if( pPage ) {  \
+        pPage->InvalidateSpelling(); \
+        pPage->InvalidateAutoCompleteWords(); \
+    }
+
+void lcl_ModifyOfst( SwTxtFrm* pFrm, xub_StrLen nPos, xub_StrLen nLen )
+{
+    if( nLen < 0 )
+        nPos -= nLen;
+    while( pFrm && pFrm->GetOfst() <= nPos )
+        pFrm = pFrm->GetFollow();
+    while( pFrm )
+    {
+        pFrm->ManipOfst( pFrm->GetOfst() + nLen );
+        pFrm = pFrm->GetFollow();
+    }
+}
+
+void SwTxtFrm::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew )
+{
+    const MSHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
+
+    //Wuensche die FrmAttribute betreffen werden von der Basisklasse
+    //verarbeitet.
+    if( IsInRange( aFrmFmtSetRange, nWhich ) || RES_FMT_CHG == nWhich )
+    {
+        SwCntntFrm::Modify( pOld, pNew );
+        if( nWhich == RES_FMT_CHG && GetShell() )
+        {
+            // Collection hat sich geaendert
+            Prepare( PREP_CLEAR );
+            _InvalidatePrt();
+            SET_WRONG( 0, STRING_LEN, Invalidate );
+            InvalidateLineNum();
+        }
+        return;
+    }
+
+    // Im gelockten Zustand werden keine Bestellungen angenommen.
+    if( IsLocked() )
+        return;
+
+    // Dies spart Stack, man muss nur aufpassen,
+    // dass sie Variablen gesetzt werden.
+    xub_StrLen nPos, nLen;
+    sal_Bool bSetFldsDirty = sal_False;
+    sal_Bool bRecalcFtnFlag = sal_False;
+
+    switch( nWhich )
+    {
+        case RES_LINENUMBER:
+        {
+            InvalidateLineNum();
+        }
+        break;
+        case RES_INS_CHR:
+        {
+            nPos = ((SwInsChr*)pNew)->nPos;
+            InvalidateRange( SwCharRange( nPos, 1 ), 1 );
+            SET_WRONG( nPos, 1, Move )
+            bSetFldsDirty = sal_True;
+            if( HasFollow() )
+                lcl_ModifyOfst( this, nPos, 1 );
+        }
+        break;
+        case RES_INS_TXT:
+        {
+            nPos = ((SwInsTxt*)pNew)->nPos;
+            nLen = ((SwInsTxt*)pNew)->nLen;
+            if( IsIdxInside( nPos, nLen ) )
+            {
+                if( !nLen )
+                {
+                    // 6969: Aktualisierung der NumPortions auch bei leeren Zeilen!
+                    if( nPos )
+                        InvalidateSize();
+                    else
+                        Prepare( PREP_CLEAR );
+                }
+                else
+                    _InvalidateRange( SwCharRange( nPos, nLen ), nLen );
+            }
+            SET_WRONG( nPos, nLen, Move )
+            bSetFldsDirty = sal_True;
+            if( HasFollow() )
+                lcl_ModifyOfst( this, nPos, nLen );
+        }
+        break;
+        case RES_DEL_CHR:
+        {
+            nPos = ((SwDelChr*)pNew)->nPos;
+            InvalidateRange( SwCharRange( nPos, 1 ), -1 );
+            SET_WRONG( nPos, -1, Move )
+            bSetFldsDirty = bRecalcFtnFlag = sal_True;
+            if( HasFollow() )
+                lcl_ModifyOfst( this, nPos, -1 );
+        }
+        break;
+        case RES_DEL_TXT:
+        {
+            nPos = ((SwDelTxt*)pNew)->nStart;
+            nLen = ((SwDelTxt*)pNew)->nLen;
+            long m = nLen;
+            m *= -1;
+            if( IsIdxInside( nPos, nLen ) )
+            {
+                if( !nLen )
+                    InvalidateSize();
+                else
+                    InvalidateRange( SwCharRange( nPos, 1 ), m );
+            }
+            SET_WRONG( nPos, m, Move )
+            bSetFldsDirty = bRecalcFtnFlag = sal_True;
+            if( HasFollow() )
+                lcl_ModifyOfst( this, nPos, nLen );
+        }
+        break;
+        case RES_UPDATE_ATTR:
+        {
+            nPos = ((SwUpdateAttr*)pNew)->nStart;
+            nLen = ((SwUpdateAttr*)pNew)->nEnd - nPos;
+            if( IsIdxInside( nPos, nLen ) )
+            {
+                // Es muss in jedem Fall neu formatiert werden,
+                // auch wenn der invalidierte Bereich null ist.
+                // Beispiel: leere Zeile, 14Pt einstellen !
+                // if( !nLen ) nLen = 1;
+
+                // 6680: FtnNummern muessen formatiert werden.
+                if( !nLen )
+                    nLen = 1;
+
+                _InvalidateRange( SwCharRange( nPos, nLen) );
+                MSHORT nTmp = ((SwUpdateAttr*)pNew)->nWhichAttr;
+                if( !nTmp || RES_CHRATR_LANGUAGE == nTmp ||
+                    RES_TXTATR_CHARFMT == nTmp )
+                    SET_WRONG( nPos, nPos + nLen, Invalidate );
+            }
+        }
+        break;
+        case RES_OBJECTDYING:
+        break;
+
+        case RES_PARATR_LINESPACING:
+            {
+                CalcLineSpace();
+                InvalidateSize();
+                _InvalidatePrt();
+                if( IsInSct() && !GetPrev() )
+                {
+                    SwSectionFrm *pSect = FindSctFrm();
+                    if( pSect->ContainsAny() == this )
+                        pSect->InvalidatePrt();
+                }
+                SwFrm* pNxt;
+                if ( 0 != ( pNxt = GetIndNext() ) )
+                {
+                    pNxt->_InvalidatePrt();
+                    if ( pNxt->IsLayoutFrm() )
+                        pNxt->InvalidatePage();
+                }
+                SetCompletePaint();
+            }
+            break;
+        case RES_TXTATR_FIELD:
+        {
+            nPos = *((SwFmtFld*)pNew)->GetTxtFld()->GetStart();
+            if( IsIdxInside( nPos, 1 ) )
+            {
+                if( pNew == pOld )
+                {
+                    // Nur repainten
+                    // opt: invalidate aufs Window ?
+                    InvalidatePage();
+                    SetCompletePaint();
+                }
+                else
+                    _InvalidateRange( SwCharRange( nPos, 1 ) );
+            }
+            bSetFldsDirty = sal_True;
+        }
+        break;
+        case RES_TXTATR_FTN :
+        {
+            nPos = *((SwFmtFtn*)pNew)->GetTxtFtn()->GetStart();
+            if( IsInFtn() || IsIdxInside( nPos, 1 ) )
+                Prepare( PREP_FTN, ((SwFmtFtn*)pNew)->GetTxtFtn() );
+            break;
+        }
+
+        case RES_ATTRSET_CHG:
+        {
+            InvalidateLineNum();
+
+            SwAttrSet& rNewSet = *((SwAttrSetChg*)pNew)->GetChgSet();
+            const SfxPoolItem* pItem;
+            int nClear = 0;
+            MSHORT nCount = rNewSet.Count();
+
+            if( SFX_ITEM_SET == rNewSet.GetItemState( RES_TXTATR_FTN,
+                sal_False, &pItem ))
+            {
+                nPos = *((SwFmtFtn*)pItem)->GetTxtFtn()->GetStart();
+                if( IsIdxInside( nPos, 1 ) )
+                    Prepare( PREP_FTN, pNew );
+                nClear = 0x01;
+                --nCount;
+            }
+
+            if( SFX_ITEM_SET == rNewSet.GetItemState( RES_TXTATR_FIELD,
+                sal_False, &pItem ))
+            {
+                nPos = *((SwFmtFld*)pItem)->GetTxtFld()->GetStart();
+                if( IsIdxInside( nPos, 1 ) )
+                {
+                    const SfxPoolItem& rOldItem = ((SwAttrSetChg*)pOld)->
+                                        GetChgSet()->Get( RES_TXTATR_FIELD );
+                    if( pItem == &rOldItem )
+                    {
+                        // Nur repainten
+                        // opt: invalidate aufs Window ?
+                        InvalidatePage();
+                        SetCompletePaint();
+                    }
+                    else
+                        _InvalidateRange( SwCharRange( nPos, 1 ) );
+                }
+                nClear |= 0x02;
+                --nCount;
+            }
+            sal_Bool bLineSpace = SFX_ITEM_SET == rNewSet.GetItemState(
+                                            RES_PARATR_LINESPACING, sal_False ),
+                     bRegister  = SFX_ITEM_SET == rNewSet.GetItemState(
+                                            RES_PARATR_REGISTER, sal_False );
+            if ( bLineSpace || bRegister )
+            {
+                Prepare( bRegister ? PREP_REGISTER : PREP_ADJUST_FRM );
+                CalcLineSpace();
+                InvalidateSize();
+                _InvalidatePrt();
+                SwFrm* pNxt;
+                if ( 0 == ( pNxt = GetIndNext() ) &&
+                     bLineSpace && IsInFtn() )
+                    pNxt = FindNext();
+                if( pNxt )
+                {
+                    pNxt->_InvalidatePrt();
+                    if ( pNxt->IsLayoutFrm() )
+                    {
+                        if( pNxt->IsSctFrm() )
+                        {
+                            SwFrm* pCnt = ((SwSectionFrm*)pNxt)->ContainsAny();
+                            if( pCnt )
+                                pCnt->_InvalidatePrt();
+                        }
+                        pNxt->InvalidatePage();
+                    }
+                }
+
+                SetCompletePaint();
+                nClear |= 0x04;
+                if ( bLineSpace )
+                {
+                    --nCount;
+                    if( IsInSct() && !GetPrev() )
+                    {
+                        SwSectionFrm *pSect = FindSctFrm();
+                        if( pSect->ContainsAny() == this )
+                            pSect->InvalidatePrt();
+                    }
+                }
+                if ( bRegister )
+                    --nCount;
+            }
+            if ( SFX_ITEM_SET == rNewSet.GetItemState( RES_PARATR_SPLIT,
+                                                       sal_False ))
+            {
+                if ( GetPrev() )
+                    CheckKeep();
+                Prepare( PREP_CLEAR );
+                InvalidateSize();
+                nClear |= 0x08;
+                --nCount;
+            }
+
+            if ( SFX_ITEM_SET == rNewSet.GetItemState( RES_CHRATR_LANGUAGE,
+                                                       sal_False ) ||
+                 SFX_ITEM_SET == rNewSet.GetItemState( RES_TXTATR_CHARFMT,
+                                                       sal_False ) )
+                SET_WRONG( 0, STRING_LEN, Invalidate );
+
+            if( nCount )
+            {
+                if( GetShell() )
+                {
+                    Prepare( PREP_CLEAR );
+                    _InvalidatePrt();
+                }
+
+                if( nClear )
+                {
+                    SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld );
+                    SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew );
+
+                    if( 0x01 & nClear )
+                    {
+                        aOldSet.ClearItem( RES_TXTATR_FTN );
+                        aNewSet.ClearItem( RES_TXTATR_FTN );
+                    }
+                    if( 0x02 & nClear )
+                    {
+                        aOldSet.ClearItem( RES_TXTATR_FIELD );
+                        aNewSet.ClearItem( RES_TXTATR_FIELD );
+                    }
+                    if ( 0x04 & nClear )
+                    {
+                        if ( bLineSpace )
+                        {
+                            aOldSet.ClearItem( RES_PARATR_LINESPACING );
+                            aNewSet.ClearItem( RES_PARATR_LINESPACING );
+                        }
+                        if ( bRegister )
+                        {
+                            aOldSet.ClearItem( RES_PARATR_REGISTER );
+                            aNewSet.ClearItem( RES_PARATR_REGISTER );
+                        }
+                    }
+                    if ( 0x08 & nClear )
+                    {
+                        aOldSet.ClearItem( RES_PARATR_SPLIT );
+                        aNewSet.ClearItem( RES_PARATR_SPLIT );
+                    }
+                    SwCntntFrm::Modify( &aOldSet, &aNewSet );
+                }
+                else
+                    SwCntntFrm::Modify( pOld, pNew );
+            }
+        }
+        break;
+
+/* Seit dem neuen Blocksatz muessen wir immer neu formatieren:
+        case RES_PARATR_ADJUST:
+        {
+            if( GetShell() )
+            {
+                Prepare( PREP_CLEAR );
+            }
+            break;
+        }
+*/
+        // 6870: SwDocPosUpdate auswerten.
+        case RES_DOCPOS_UPDATE:
+        {
+            if( pOld && pNew )
+            {
+                const SwDocPosUpdate *pDocPos = (const SwDocPosUpdate*)pOld;
+                if( pDocPos->nDocPos <= aFrm.Top() )
+                {
+                    const SwFmtFld *pFld = (const SwFmtFld *)pNew;
+                    InvalidateRange(
+                        SwCharRange( *pFld->GetTxtFld()->GetStart(), 1 ) );
+                }
+            }
+            break;
+        }
+        case RES_PARATR_SPLIT:
+            if ( GetPrev() )
+                CheckKeep();
+            Prepare( PREP_CLEAR );
+            bSetFldsDirty = sal_True;
+            break;
+
+        default:
+        {
+            Prepare( PREP_CLEAR );
+            _InvalidatePrt();
+            if ( !nWhich )
+            {
+                //Wird z.B. bei HiddenPara mit 0 gerufen.
+                SwFrm *pNxt;
+                if ( 0 != (pNxt = FindNext()) )
+                    pNxt->InvalidatePrt();
+            }
+        }
+    } // switch
+
+    if( bSetFldsDirty )
+        GetNode()->GetDoc()->SetFieldsDirty( sal_True, GetNode(), 1 );
+
+    if ( bRecalcFtnFlag )
+        CalcFtnFlag();
+}
+
+sal_Bool SwTxtFrm::GetInfo( SfxPoolItem &rHnt ) const
+{
+    if ( RES_VIRTPAGENUM_INFO == rHnt.Which() && IsInDocBody() )
+    {
+        SwVirtPageNumInfo &rInfo = (SwVirtPageNumInfo&)rHnt;
+        const SwPageFrm *pPage = FindPageFrm();
+        if ( pPage  )
+        {
+            if ( pPage == rInfo.GetOrigPage() && !GetPrev() )
+            {
+                //Das sollte er sein (kann allenfalls temporaer anders sein,
+                //                    sollte uns das beunruhigen?)
+                rInfo.SetInfo( pPage, this );
+                return sal_False;
+            }
+            if ( pPage->GetPhyPageNum() < rInfo.GetOrigPage()->GetPhyPageNum() &&
+                 (!rInfo.GetPage() || pPage->GetPhyPageNum() > rInfo.GetPage()->GetPhyPageNum()))
+            {
+                //Das koennte er sein.
+                rInfo.SetInfo( pPage, this );
+            }
+        }
+    }
+    return sal_True;
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::PrepWidows()
+ *************************************************************************/
+
+void SwTxtFrm::PrepWidows( const MSHORT nNeed, sal_Bool bNotify )
+{
+    ASSERT(GetFollow() && nNeed, "+SwTxtFrm::Prepare: lost all friends");
+
+    SwParaPortion *pPara = GetPara();
+    if ( !pPara )
+        return;
+    pPara->SetPrepWidows( sal_True );
+
+    // returnen oder nicht ist hier die Frage.
+    // Ohne IsLocked() ist 5156 gefaehrlich,
+    // ohne IsFollow() werden die Orphans unterdrueckt: 6968.
+    // Abfrage auf IsLocked erst hier, weil das Flag gesetzt werden soll.
+    if( IsLocked() && IsFollow() )
+        return;
+
+    MSHORT nHave = nNeed;
+
+    // Wir geben ein paar Zeilen ab und schrumpfen im CalcPreps()
+    SwTxtSizeInfo aInf( this );
+    SwTxtMargin aLine( this, &aInf );
+    aLine.Bottom();
+    xub_StrLen nTmpLen = aLine.GetCurr()->GetLen();
+    while( nHave && aLine.PrevLine() )
+    {
+        if( nTmpLen )
+            --nHave;
+        nTmpLen = aLine.GetCurr()->GetLen();
+    }
+    // In dieser Ecke tummelten sich einige Bugs: 7513, 7606.
+    // Wenn feststeht, dass Zeilen abgegeben werden koennen,
+    // muss der Master darueber hinaus die Widow-Regel ueberpruefen.
+    if( !nHave )
+    {
+        sal_Bool bSplit;
+        if( !IsFollow() )   //Nur ein Master entscheidet ueber Orphans
+        {
+            const WidowsAndOrphans aWidOrp( this );
+            bSplit = ( aLine.GetLineNr() >= aWidOrp.GetOrphansLines() &&
+                       aLine.GetLineNr() >= aLine.GetDropLines() );
+        }
+        else
+            bSplit = sal_True;
+
+        if( bSplit )
+        {
+            GetFollow()->SetOfst( aLine.GetEnd() );
+            aLine.TruncLines( sal_True );
+            if( pPara->IsFollowField() )
+                GetFollow()->SetFieldFollow( sal_True );
+        }
+    }
+    if ( bNotify )
+    {
+        _InvalidateSize();
+        InvalidatePage();
+    }
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::Prepare
+ *************************************************************************/
+
+sal_Bool lcl_ErgoVadis( SwTxtFrm* pFrm, xub_StrLen &rPos, const PrepareHint ePrep )
+{
+    const SwFtnInfo &rFtnInfo = pFrm->GetNode()->GetDoc()->GetFtnInfo();
+    if( ePrep == PREP_ERGOSUM )
+    {
+        if( !rFtnInfo.aErgoSum.Len() )
+            return sal_False;;
+        rPos = pFrm->GetOfst();
+    }
+    else
+    {
+        if( !rFtnInfo.aQuoVadis.Len() )
+            return sal_False;
+        if( pFrm->HasFollow() )
+            rPos = pFrm->GetFollow()->GetOfst();
+        else
+            rPos = pFrm->GetTxt().Len();
+        if( rPos )
+            --rPos; // unser letztes Zeichen
+    }
+    return sal_True;
+}
+
+void SwTxtFrm::Prepare( const PrepareHint ePrep, const void* pVoid,
+                        sal_Bool bNotify )
+{
+#ifdef DEBUG
+    const SwTwips nDbgY = Frm().Top();
+#endif
+
+    if ( IsEmpty() )
+    {
+        switch ( ePrep )
+        {
+            case PREP_BOSS_CHGD:
+            case PREP_WIDOWS_ORPHANS:
+            case PREP_WIDOWS:
+            case PREP_FTN_GONE :    return;
+
+            case PREP_POS_CHGD :
+            {   // Auch in (spaltigen) Bereichen ist ein InvalidateSize notwendig,
+                // damit formatiert wird und ggf. das bUndersized gesetzt wird.
+                if( IsInFly() || IsInSct() )
+                {
+                    SwTwips nTmpBottom = GetUpper()->Frm().Top() +
+                        GetUpper()->Prt().Bottom();
+                    if( nTmpBottom < Frm().Bottom() )
+                        break;
+                }
+                // Gibt es ueberhaupt Flys auf der Seite ?
+                SwTxtFly aTxtFly( this );
+                if( aTxtFly.IsOn() )
+                {
+                    // Ueberlappt irgendein Fly ?
+                    aTxtFly.Relax();
+                    if ( aTxtFly.IsOn() || IsUndersized() )
+                        break;
+                }
+                if( GetTxtNode()->GetSwAttrSet().GetRegister().GetValue())
+                    break;
+                return;
+            }
+        }
+    }
+
+    if( !HasPara() && PREP_MUST_FIT != ePrep )
+    {
+        ASSERT( !IsLocked(), "SwTxtFrm::Prepare: three of a perfect pair" );
+        if ( bNotify )
+            InvalidateSize();
+        else
+            _InvalidateSize();
+        return;
+    }
+
+    //Objekt mit Locking aus dem Cache holen.
+    SwTxtLineAccess aAccess( this );
+    SwParaPortion *pPara = aAccess.GetPara();
+
+    switch( ePrep )
+    {
+        case PREP_MOVEFTN :     Frm().Height(0);
+                                Prt().Height(0);
+                                _InvalidatePrt();
+                                _InvalidateSize();
+                                // KEIN break
+        case PREP_ADJUST_FRM :  pPara->SetPrepAdjust( sal_True );
+                                if( IsFtnNumFrm() != pPara->IsFtnNum() ||
+                                    IsUndersized() )
+                                {
+                                    InvalidateRange( SwCharRange( 0, 1 ), 1);
+                                    if( GetOfst() && !IsFollow() )
+                                        _SetOfst( 0 );
+                                }
+                                break;
+        case PREP_MUST_FIT :        pPara->SetPrepMustFit( sal_True );
+            /* no break here */
+        case PREP_WIDOWS_ORPHANS :  pPara->SetPrepAdjust( sal_True );
+                                    break;
+
+        case PREP_WIDOWS :
+            // MustFit ist staerker als alles anderes
+            if( pPara->IsPrepMustFit() )
+                return;
+            // Siehe Kommentar in WidowsAndOrphans::FindOrphans und CalcPreps()
+            PrepWidows( *(const MSHORT *)pVoid, bNotify );
+            break;
+
+        case PREP_FTN :
+        {
+            SwTxtFtn *pFtn = (SwTxtFtn *)pVoid;
+            if( IsInFtn() )
+            {
+                // Bin ich der erste TxtFrm einer Fussnote ?
+                if( !GetPrev() )
+                    // Wir sind also ein TxtFrm der Fussnote, die
+                    // die Fussnotenzahl zur Anzeige bringen muss.
+                    // Oder den ErgoSum-Text...
+                    InvalidateRange( SwCharRange( 0, 1 ), 1);
+
+                if( !GetNext() )
+                {
+                    // Wir sind der letzte Ftn, jetzt muessten die
+                    // QuoVadis-Texte geupdated werden.
+                    const SwFtnInfo &rFtnInfo = GetNode()->GetDoc()->GetFtnInfo();
+                    if( !pPara->UpdateQuoVadis( rFtnInfo.aQuoVadis ) )
+                    {
+                        xub_StrLen nPos = pPara->GetParLen();
+                        if( nPos )
+                            --nPos;
+                        InvalidateRange( SwCharRange( nPos, 1 ), 1);
+                    }
+                }
+            }
+            else
+            {
+                // Wir sind also der TxtFrm _mit_ der Fussnote
+                const xub_StrLen nPos = *pFtn->GetStart();
+                InvalidateRange( SwCharRange( nPos, 1 ), 1);
+            }
+            break;
+        }
+        case PREP_BOSS_CHGD :
+        {
+            if( HasFollow() )
+            {
+                xub_StrLen nNxtOfst = GetFollow()->GetOfst();
+                if( nNxtOfst )
+                    --nNxtOfst;
+                InvalidateRange( SwCharRange( nNxtOfst, 1 ), 1);
+            }
+            if( IsInFtn() )
+            {
+                xub_StrLen nPos;
+                if( lcl_ErgoVadis( this, nPos, PREP_QUOVADIS ) )
+                    InvalidateRange( SwCharRange( nPos, 1 ), 0 );
+                if( lcl_ErgoVadis( this, nPos, PREP_ERGOSUM ) )
+                    InvalidateRange( SwCharRange( nPos, 1 ), 0 );
+            }
+            // 4739: Wenn wir ein Seitennummernfeld besitzen, muessen wir
+            // die Stellen invalidieren.
+            SwpHints *pHints = GetTxtNode()->GetpSwpHints();
+            if( pHints )
+            {
+                const MSHORT nSize = pHints->Count();
+                const xub_StrLen nEnd = GetFollow() ?
+                                    GetFollow()->GetOfst() : STRING_LEN;
+                for( MSHORT i = 0; i < nSize; ++i )
+                {
+                    const SwTxtAttr *pHt = (*pHints)[i];
+                    const xub_StrLen nStart = *pHt->GetStart();
+                    if( nStart >= GetOfst() )
+                    {
+                        if( nStart >= nEnd )
+                            i = nSize;          // fuehrt das Ende herbei
+                        else
+                        {
+                // 4029: wenn wir zurueckfliessen und eine Ftn besitzen, so
+                // fliesst die Ftn in jedem Fall auch mit. Damit sie nicht im
+                // Weg steht, schicken wir uns ein ADJUST_FRM.
+                // pVoid != 0 bedeutet MoveBwd()
+                            const MSHORT nWhich = pHt->Which();
+                            if( RES_TXTATR_FIELD == nWhich ||
+                                (HasFtn() && pVoid && RES_TXTATR_FTN == nWhich))
+                            InvalidateRange( SwCharRange( nStart, 1 ), 1 );
+                        }
+                    }
+                }
+            }
+            // A new boss, a new chance for growing
+            if( IsUndersized() )
+            {
+                _InvalidateSize();
+                InvalidateRange( SwCharRange( GetOfst(), 1 ), 1);
+            }
+            break;
+        }
+
+        case PREP_POS_CHGD :
+        {
+            // Falls wir mit niemandem ueberlappen:
+            // Ueberlappte irgendein Fly _vor_ der Positionsaenderung ?
+            sal_Bool bFormat = pPara->HasFly();
+            if( !bFormat )
+            {
+                if( IsInFly() )
+                {
+                    SwTwips nTmpBottom = GetUpper()->Frm().Top() +
+                        GetUpper()->Prt().Bottom();
+                    if( nTmpBottom < Frm().Bottom() )
+                        bFormat = sal_True;
+                }
+                if( !bFormat )
+                {
+                    if ( GetDrawObjs() )
+                    {
+                        MSHORT nCnt = GetDrawObjs()->Count();
+                        for ( MSHORT i = 0; i < nCnt; ++i )
+                        {
+                            SdrObject *pO = (*GetDrawObjs())[i];
+                            if ( pO->IsWriterFlyFrame() )
+                            {
+                                SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+                                if( pFly->IsAutoPos() )
+                                {
+                                    bFormat = sal_True;
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                    if( !bFormat )
+                    {
+                        // Gibt es ueberhaupt Flys auf der Seite ?
+                        SwTxtFly aTxtFly( this );
+                        if( aTxtFly.IsOn() )
+                        {
+                            // Ueberlappt irgendein Fly ?
+                            aTxtFly.Relax();
+                            bFormat = aTxtFly.IsOn() || IsUndersized();
+                        }
+                    }
+                }
+            }
+
+            if( bFormat )
+            {
+                if( !IsLocked() )
+                {
+                    if( pPara->GetRepaint()->HasArea() )
+                        SetCompletePaint();
+                    Init();
+                    pPara = 0;
+                    _InvalidateSize();
+                }
+            }
+            else
+            {
+                if( GetTxtNode()->GetSwAttrSet().GetRegister().GetValue() )
+                    Prepare( PREP_REGISTER, 0, bNotify );
+                // Durch Positionsverschiebungen mit Ftns muessen die
+                // Frames neu adjustiert werden.
+                else if( HasFtn() )
+                {
+                    Prepare( PREP_ADJUST_FRM, 0, bNotify );
+                    _InvalidateSize();
+                }
+                else
+                    return;     // damit kein SetPrep() erfolgt.
+            }
+            break;
+        }
+        case PREP_REGISTER:
+            if( GetTxtNode()->GetSwAttrSet().GetRegister().GetValue() )
+            {
+                pPara->SetPrepAdjust( sal_True );
+                CalcLineSpace();
+                InvalidateSize();
+                _InvalidatePrt();
+                SwFrm* pNxt;
+                if ( 0 != ( pNxt = GetIndNext() ) )
+                {
+                    pNxt->_InvalidatePrt();
+                    if ( pNxt->IsLayoutFrm() )
+                        pNxt->InvalidatePage();
+                }
+                SetCompletePaint();
+            }
+            break;
+        case PREP_FTN_GONE :
+            {
+                // Wenn ein Follow uns ruft, weil eine Fussnote geloescht wird, muss unsere
+                // letzte Zeile formatiert werden, damit ggf. die erste Zeile des Follows
+                // hochrutschen kann, die extra auf die naechste Seite gerutscht war, um mit
+                // der Fussnote zusammen zu sein, insbesondere bei spaltigen Bereichen.
+                ASSERT( GetFollow(), "PREP_FTN_GONE darf nur vom Follow gerufen werden" );
+                xub_StrLen nPos = GetFollow()->GetOfst();
+                if( IsFollow() && GetOfst() == nPos )       // falls wir gar keine Textmasse besitzen,
+                    FindMaster()->Prepare( PREP_FTN_GONE ); // rufen wir das Prepare unseres Masters
+                if( nPos )
+                    --nPos; // das Zeichen vor unserem Follow
+                InvalidateRange( SwCharRange( nPos, 1 ), 0 );
+                return;
+            }
+        case PREP_ERGOSUM:
+        case PREP_QUOVADIS:
+            {
+                xub_StrLen nPos;
+                if( lcl_ErgoVadis( this, nPos, ePrep ) )
+                    InvalidateRange( SwCharRange( nPos, 1 ), 0 );
+            }
+            break;
+        case PREP_FLY_ATTR_CHG:
+        {
+            if( pVoid )
+            {
+                xub_StrLen nWhere = CalcFlyPos( (SwFrmFmt*)pVoid );
+                ASSERT( STRING_LEN != nWhere, "Prepare: Why me?" );
+                InvalidateRange( SwCharRange( nWhere, 1 ) );
+                return;
+            }
+            // else ... Laufe in den Default-Switch
+        }
+        case PREP_CLEAR:
+        default:
+        {
+#ifdef WARN_LOCK
+            ASSERT(!IsLocked(), "+SwTxtFrm::Prepare: this is locked (warning)");
+#endif
+            if( !IsLocked() )
+            {
+                if( pPara->GetRepaint()->HasArea() )
+                    SetCompletePaint();
+                Init();
+                pPara = 0;
+                if( GetOfst() && !IsFollow() )
+                    _SetOfst( 0 );
+                if ( bNotify )
+                    InvalidateSize();
+                else
+                    _InvalidateSize();
+            }
+            return;     // damit kein SetPrep() erfolgt.
+        }
+    }
+    if( pPara )
+        pPara->SetPrep( sal_True );
+}
+
+/* -----------------11.02.99 17:56-------------------
+ * Kleine Hilfsklasse mit folgender Funktion:
+ * Sie soll eine Probeformatierung vorbereiten.
+ * Der Frame wird in Groesse und Position angepasst, sein SwParaPortion zur Seite
+ * gestellt und eine neue erzeugt, dazu wird formatiert mit gesetztem bTestFormat.
+ * Im Dtor wird der TxtFrm wieder in seinen alten Zustand zurueckversetzt.
+ *
+ * --------------------------------------------------*/
+
+class SwTestFormat
+{
+    SwTxtFrm *pFrm;
+    SwParaPortion *pOldPara;
+    SwRect aOldFrm, aOldPrt;
+public:
+    SwTestFormat( SwTxtFrm* pTxtFrm, const SwFrm* pPrv, SwTwips nMaxHeight );
+    ~SwTestFormat();
+};
+
+SwTestFormat::SwTestFormat( SwTxtFrm* pTxtFrm, const SwFrm* pPre, SwTwips nMaxHeight )
+    : pFrm( pTxtFrm )
+{
+    aOldFrm = pFrm->Frm();
+    aOldPrt = pFrm->Prt();
+    SwTwips nLower = aOldFrm.Height() - aOldPrt.Height() - aOldPrt.Top();
+    pFrm->Frm() = pFrm->GetUpper()->Prt();
+    pFrm->Frm() += pFrm->GetUpper()->Frm().Pos();
+    if( pFrm->GetPrev() )
+        pFrm->Frm().Top( pFrm->GetPrev()->Frm().Bottom() );
+    pFrm->Frm().Height( nMaxHeight );
+    SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFrm );
+    const SwBorderAttrs &rAttrs = *aAccess.Get();
+    pFrm->Prt().Pos().X() = rAttrs.CalcLeft( pFrm );
+    if( pPre )
+    {
+        SwTwips nUpper = pFrm->CalcUpperSpace( &rAttrs, pPre );
+        pFrm->Prt().Pos().Y() = nUpper;
+    }
+    pFrm->Prt().Height( Max( 0L , pFrm->Frm().Height() - pFrm->Prt().Top() - nLower ) );
+    pFrm->Prt().Width( pFrm->Frm().Width() - (rAttrs.CalcLeft( pFrm ) + rAttrs.CalcRight()) );
+    pOldPara = pFrm->HasPara() ? pFrm->GetPara() : NULL;
+    pFrm->SetPara( new SwParaPortion(), sal_False );
+    SwTxtFormatInfo aInf( pFrm, sal_False, sal_True, sal_True );
+    SwTxtFormatter  aLine( pFrm, &aInf );
+    pFrm->_Format( aLine, aInf );
+}
+
+SwTestFormat::~SwTestFormat()
+{
+    pFrm->Frm() = aOldFrm;
+    pFrm->Prt() = aOldPrt;
+    pFrm->SetPara( pOldPara );
+}
+
+sal_Bool SwTxtFrm::TestFormat( const SwFrm* pPrv, SwTwips &rMaxHeight, sal_Bool &bSplit )
+{
+    PROTOCOL_ENTER( this, PROT_TESTFORMAT, 0, 0 )
+
+    if( IsLocked() && GetUpper()->Prt().Width() <= 0 )
+        return sal_False;
+
+    SwTestFormat aSave( this, pPrv, rMaxHeight );
+
+    return SwTxtFrm::WouldFit( rMaxHeight, bSplit );
+}
+
+
+/*************************************************************************
+ *                      SwTxtFrm::WouldFit()
+ *************************************************************************/
+
+/* SwTxtFrm::WouldFit()
+ * sal_True: wenn ich aufspalten kann.
+ * Es soll und braucht nicht neu formatiert werden.
+ * Wir gehen davon aus, dass bereits formatiert wurde und dass
+ * die Formatierungsdaten noch aktuell sind.
+ * Wir gehen davon aus, dass die Framebreiten des evtl. Masters und
+ * Follows gleich sind. Deswegen wird kein FindBreak() mit FindOrphans()
+ * gerufen.
+ * Die benoetigte Hoehe wird von nMaxHeight abgezogen!
+ */
+
+sal_Bool SwTxtFrm::WouldFit( SwTwips &rMaxHeight, sal_Bool &bSplit )
+{
+    if( IsLocked() )
+        return sal_False;
+
+    //Kann gut sein, dass mir der IdleCollector mir die gecachten
+    //Informationen entzogen hat.
+    if( !IsEmpty() )
+        GetFormatted();
+
+    if ( IsEmpty() )
+    {
+        bSplit = sal_False;
+        SwTwips nHeight = Prt().SSize().Height();
+        if( rMaxHeight < nHeight )
+            return sal_False;
+        else
+        {
+            rMaxHeight -= nHeight;
+            return sal_True;
+        }
+    }
+
+    // In sehr unguenstigen Faellen kann GetPara immer noch 0 sein.
+    // Dann returnen wir sal_True, um auf der neuen Seite noch einmal
+    // anformatiert zu werden.
+    ASSERT( HasPara() || IsHiddenNow(), "WouldFit: GetFormatted() and then !HasPara()" );
+    if( !HasPara() || (!Frm().Height() && IsHiddenNow() ) )
+        return sal_True;
+
+    // Da das Orphan-Flag nur sehr fluechtig existiert, wird als zweite
+    // Bedingung  ueberprueft, ob die Rahmengroesse durch CalcPreps
+    // auf riesengross gesetzt wird, um ein MoveFwd zu erzwingen.
+    if( IsWidow() || LONG_MAX - 20000 < Frm().Bottom() )
+    {
+        SetWidow(sal_False);
+        if ( GetFollow() )
+        {
+            // Wenn wir hier durch eine Widow-Anforderung unseres Follows gelandet
+            // sind, wird ueberprueft, ob es ueberhaupt einen Follow mit einer
+            // echten Hoehe gibt, andernfalls (z.B. in neu angelegten SctFrms)
+            // ignorieren wir das IsWidow() und pruefen doch noch, ob wir
+            // genung Platz finden.
+            if( LONG_MAX - 20000 >= Frm().Bottom() && !GetFollow()->Frm().Height() )
+            {
+                SwTxtFrm* pFoll = GetFollow()->GetFollow();
+                while( pFoll && !pFoll->Frm().Height() )
+                    pFoll = pFoll->GetFollow();
+                if( pFoll )
+                    return sal_False;
+            }
+            else
+                return sal_False;
+        }
+    }
+
+    SwTxtSizeInfo aInf( this );
+    SwTxtMargin aLine( this, &aInf );
+
+    WidowsAndOrphans aFrmBreak( this, rMaxHeight, bSplit );
+
+    register sal_Bool bRet = sal_True;
+
+    aLine.Bottom();
+    // Ist Aufspalten ueberhaupt notwendig?
+    if ( 0 != ( bSplit = !aFrmBreak.IsInside( aLine ) ) )
+        bRet = !aFrmBreak.IsKeepAlways() && aFrmBreak.WouldFit( aLine, rMaxHeight );
+    else
+    {
+        //Wir brauchen die Gesamthoehe inklusive der aktuellen Zeile
+        aLine.Top();
+        do
+        {
+            rMaxHeight -= aLine.GetLineHeight();
+        } while ( aLine.Next() );
+    }
+    return bRet;
+}
+
+
+/*************************************************************************
+ *                      SwTxtFrm::GetParHeight()
+ *************************************************************************/
+
+KSHORT SwTxtFrm::GetParHeight() const
+{
+    if( !HasPara() )
+    {   // Fuer nichtleere Absaetze ist dies ein Sonderfall, da koennen wir
+        // bei UnderSized ruhig nur 1 Twip mehr anfordern.
+        KSHORT nRet = Prt().SSize().Height();
+        if( IsUndersized() )
+        {
+            if( IsEmpty() )
+                nRet = EmptyHeight();
+            else
+                ++nRet;
+        }
+        return nRet;
+    }
+    SwTxtFrm *pThis = (SwTxtFrm*)this;
+    SwTxtSizeInfo aInf( pThis );
+    SwTxtIter aLine( pThis, &aInf );
+    KSHORT nHeight = aLine.GetLineHeight();
+    if( GetOfst() && !IsFollow() )          // Ist dieser Absatz gescrollt? Dann ist unsere
+        nHeight += aLine.GetLineHeight();   // bisherige Hoehe mind. eine Zeilenhoehe zu gering
+    while( aLine.Next() )
+        nHeight += aLine.GetLineHeight();
+    return nHeight;
+}
+
+
+/*************************************************************************
+ *                      SwTxtFrm::GetFormatted()
+ *************************************************************************/
+
+// returnt this _immer_ im formatierten Zustand!
+SwTxtFrm *SwTxtFrm::GetFormatted()
+{
+    //Kann gut sein, dass mir der IdleCollector mir die gecachten
+    //Informationen entzogen hat. Calc() ruft unser Format.
+                      //Nicht bei leeren Absaetzen!
+    if( !HasPara() && !(IsValid() && IsEmpty()) )
+    {
+        // Calc() muss gerufen werden, weil unsere Frameposition
+        // nicht stimmen muss.
+        const sal_Bool bFormat = GetValidSizeFlag();
+        Calc();
+        // Es kann durchaus sein, dass Calc() das Format()
+        // nicht anstiess (weil wir einst vom Idle-Zerstoerer
+        // aufgefordert wurden unsere Formatinformationen wegzuschmeissen).
+        // 6995: Optimierung mit FormatQuick()
+        if( bFormat && !FormatQuick() )
+            Format();
+    }
+    return this;
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::CalcFitToContent()
+ *************************************************************************/
+
+KSHORT SwTxtFrm::CalcFitToContent( )
+{
+    sal_Bool bNoPara = !HasPara();
+    if ( bNoPara )
+    {
+        SwParaPortion *pDummy = new SwParaPortion();
+        SetPara( pDummy );
+    }
+
+    SwTxtFormatInfo aInf( this );
+    aInf.Right( KSHRT_MAX );
+    aInf.Width( KSHRT_MAX );
+    aInf.RealWidth( KSHRT_MAX );
+    aInf.SetIgnoreFly( sal_True );
+
+    SwTxtFormatter  aLine( this, &aInf );
+    SwTxtFormatInfo *pInf = &aInf;
+
+    SwHookOut aHook( pInf );
+    KSHORT nMax = aLine._CalcFitToContent( );
+    if ( nMax )
+        nMax -= KSHORT( GetLeftMargin() );
+
+    if ( bNoPara )
+        ClearPara( );  // Dummy-Paraportion wieder loeschen
+    else
+        SetPara( NULL ); // Die Einzeilen-Formatinformation wegwerfen!
+
+    return nMax;
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::GetLineSpace()
+ *************************************************************************/
+
+KSHORT SwTxtFrm::GetLineSpace() const
+{
+    KSHORT nRet = 0;
+    long nTmp;
+
+    const SwAttrSet* pSet = GetAttrSet();
+    const SvxLineSpacingItem &rSpace = pSet->GetLineSpacing();
+
+    switch( rSpace.GetInterLineSpaceRule() )
+    {
+        case SVX_INTER_LINE_SPACE_PROP:
+        {
+            ViewShell* pVsh = (ViewShell*)GetShell();
+            if ( !pVsh )
+                break;
+            OutputDevice *pOut = pVsh->GetOut();
+            if( !pVsh->GetDoc()->IsBrowseMode() ||
+                pVsh->GetViewOptions()->IsPrtFormat() )
+            {
+                OutputDevice* pPrt = GetTxtNode()->GetDoc()->GetPrt();
+                if ( pPrt && ((Printer*)pPrt)->IsValid() )
+                    pOut = pPrt;
+            }
+            SwFont aFont( pSet );
+            // Wir muessen dafuer sorgen, dass am OutputDevice der Font
+            // korrekt restauriert wird, sonst droht ein Last!=Owner.
+            if ( pLastFont )
+            {
+                SwFntObj *pOldFont = pLastFont;
+                pLastFont = NULL;
+                aFont.SetFntChg( sal_True );
+                aFont.ChgPhysFnt( pVsh, pOut );
+                nRet = aFont.GetHeight( pVsh, pOut );
+                pLastFont->Unlock();
+                pLastFont = pOldFont;
+                pLastFont->SetDevFont( pVsh, pOut );
+            }
+            else
+            {
+                Font aOldFont = pOut->GetFont();
+                aFont.SetFntChg( sal_True );
+                aFont.ChgPhysFnt( pVsh, pOut );
+                nRet = aFont.GetHeight( pVsh, pOut );
+                pLastFont->Unlock();
+                pLastFont = NULL;
+                pOut->SetFont( aOldFont );
+            }
+            nTmp = nRet;
+            nTmp *= rSpace.GetPropLineSpace();
+            nTmp /= 100;
+            nTmp -= nRet;
+            if ( nTmp > 0 )
+                nRet = (KSHORT)nTmp;
+            else
+                nRet = 0;
+        }
+            break;
+        case SVX_INTER_LINE_SPACE_FIX:
+            if ( rSpace.GetInterLineSpace() > 0 )
+                nRet = (KSHORT)rSpace.GetInterLineSpace();
+    }
+    return nRet;
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::FirstLineHeight()
+ *************************************************************************/
+
+KSHORT SwTxtFrm::FirstLineHeight() const
+{
+    if ( !HasPara() )
+    {
+        if( IsEmpty() && IsValid() )
+            return Prt().Height();
+        return KSHRT_MAX;
+    }
+    const SwParaPortion *pPara = GetPara();
+    if ( !pPara )
+        return KSHRT_MAX;
+
+    return pPara->Height();
+}
+
+MSHORT SwTxtFrm::GetLineCount( xub_StrLen nPos )
+{
+    MSHORT nRet = 0;
+    GetFormatted();
+    if( HasPara() )
+    {
+        SwTxtFrm *pFrm = this;
+        do
+        {
+            SwTxtSizeInfo aInf( pFrm );
+            SwTxtMargin aLine( pFrm, &aInf );
+            if( STRING_LEN == nPos )
+                aLine.Bottom();
+            else
+                aLine.CharToLine( nPos );
+            nRet += aLine.GetLineNr();
+            pFrm = pFrm->GetFollow();
+        } while ( pFrm && pFrm->GetOfst() <= nPos );
+    }
+    return nRet;
+}
+
+void SwTxtFrm::ChgThisLines()
+{
+    //not necassary to format here (GerFormatted etc.), because we have to come from there!
+
+    ULONG nNew = 0;
+    const SwLineNumberInfo &rInf = GetNode()->GetDoc()->GetLineNumberInfo();
+    if ( GetTxt().Len() && HasPara() )
+    {
+        SwTxtSizeInfo aInf( this );
+        SwTxtMargin aLine( this, &aInf );
+        if ( rInf.IsCountBlankLines() )
+        {
+            aLine.Bottom();
+            nNew = (ULONG)aLine.GetLineNr();
+        }
+        else
+        {
+            do
+            {
+                if( aLine.GetCurr()->HasCntnt() )
+                    ++nNew;
+            } while ( aLine.NextLine() );
+        }
+    }
+    else if ( rInf.IsCountBlankLines() )
+        nNew = 1;
+
+    if ( nNew != nThisLines )
+    {
+        if ( GetAttrSet()->GetLineNumber().IsCount() )
+        {
+            nAllLines -= nThisLines;
+            nThisLines = nNew;
+            nAllLines  += nThisLines;
+            SwFrm *pNxt = GetNextCntntFrm();
+            while( pNxt && pNxt->IsInTab() )
+            {
+                if( 0 != (pNxt = pNxt->FindTabFrm()) )
+                    pNxt = pNxt->FindNextCnt();
+            }
+            if( pNxt )
+                pNxt->InvalidateLineNum();
+
+            //Extend repaint to the bottom.
+            if ( HasPara() )
+            {
+                SwRepaint *pRepaint = GetPara()->GetRepaint();
+                pRepaint->Bottom( Max( pRepaint->Bottom(),
+                                       Frm().Top()+Prt().Bottom()));
+            }
+        }
+        else //Paragraphs which are not counted should not manipulate the AllLines.
+            nThisLines = nNew;
+    }
+}
+
+
+void SwTxtFrm::RecalcAllLines()
+{
+    ValidateLineNum();
+
+    const SwAttrSet *pAttrSet = GetAttrSet();
+
+    if ( !IsInTab() )
+    {
+        const ULONG nOld = GetAllLines();
+        const SwFmtLineNumber &rLineNum = pAttrSet->GetLineNumber();
+        ULONG nNewNum;
+
+        if ( !IsFollow() && rLineNum.GetStartValue() && rLineNum.IsCount() )
+            nNewNum = rLineNum.GetStartValue() - 1;
+        //If it is a follow or not has not be considered if it is a restart at each page; the
+        //restart should also take affekt at follows.
+        else if ( pAttrSet->GetDoc()->GetLineNumberInfo().IsRestartEachPage() &&
+                  FindPageFrm()->FindFirstBodyCntnt() == this )
+        {
+            nNewNum = 0;
+        }
+        else
+        {
+            SwCntntFrm *pPrv = GetPrevCntntFrm();
+            while ( pPrv &&
+                    (pPrv->IsInTab() || pPrv->IsInDocBody() != IsInDocBody()) )
+                pPrv = pPrv->GetPrevCntntFrm();
+
+            nNewNum = pPrv ? ((SwTxtFrm*)pPrv)->GetAllLines() : 0;
+        }
+        if ( rLineNum.IsCount() )
+            nNewNum += GetThisLines();
+
+        if ( nOld != nNewNum )
+        {
+            nAllLines = nNewNum;
+            SwCntntFrm *pNxt = GetNextCntntFrm();
+            while ( pNxt &&
+                    (pNxt->IsInTab() || pNxt->IsInDocBody() != IsInDocBody()) )
+                pNxt = pNxt->GetNextCntntFrm();
+            if ( pNxt )
+            {
+                if ( pNxt->GetUpper() != GetUpper() )
+                    pNxt->InvalidateLineNum();
+                else
+                    pNxt->_InvalidateLineNum();
+            }
+        }
+    }
+}
+
+
diff --git a/sw/source/core/text/txtftn.cxx b/sw/source/core/text/txtftn.cxx
new file mode 100644
index 000000000000..3cadfdbea1eb
--- /dev/null
+++ b/sw/source/core/text/txtftn.cxx
@@ -0,0 +1,1542 @@
+/*************************************************************************
+ *
+ *  $RCSfile: txtftn.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:26 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "viewsh.hxx"
+#include "doc.hxx"
+#include "pagefrm.hxx"
+#include "ndtxt.hxx"
+#include "txtatr.hxx"
+
+#ifndef _TXTFTN_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFTN_HXX //autogen
+#include 
+#endif
+#ifndef _FTNINFO_HXX //autogen
+#include 
+#endif
+#ifndef _CHARFMT_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BRSHITEM_HXX //autogen
+#include 
+#endif
+
+#include "txtcfg.hxx"
+#include "swfont.hxx"   // new SwFont
+#include "porftn.hxx"
+#include "porfly.hxx"
+#include "porlay.hxx"
+#include "txtfrm.hxx"
+#include "itrform2.hxx"
+#include "frmsh.hxx"
+#include "ftnfrm.hxx"   // FindErgoSumFrm(), FindQuoVadisFrm(),
+#include "pagedesc.hxx"
+#include "redlnitr.hxx" // SwRedlnItr
+#include "sectfrm.hxx"  // SwSectionFrm
+#include "layouter.hxx" // Endnote-Collection
+#include "frmtool.hxx"
+#include "ndindex.hxx"
+
+
+/*************************************************************************
+ *                              _IsFtnNumFrm()
+ *************************************************************************/
+
+sal_Bool SwTxtFrm::_IsFtnNumFrm() const
+{
+    const SwFtnFrm* pFtn = FindFtnFrm()->GetMaster();
+    while( pFtn && !pFtn->ContainsCntnt() )
+        pFtn = pFtn->GetMaster();
+    return !pFtn;
+}
+
+/*************************************************************************
+ *                              FindFtn()
+ *************************************************************************/
+
+// Sucht innerhalb einer Master-Follow-Kette den richtigen TxtFrm zum SwTxtFtn
+
+SwTxtFrm *SwTxtFrm::FindFtnRef( const SwTxtFtn *pFtn )
+{
+    SwTxtFrm *pFrm = this;
+    const sal_Bool bFwd = *pFtn->GetStart() >= GetOfst();
+    while( pFrm )
+    {
+        if( SwFtnBossFrm::FindFtn( pFrm, pFtn ) )
+            return pFrm;
+        pFrm = bFwd ? pFrm->GetFollow() :
+                      pFrm->IsFollow() ? pFrm->FindMaster() : 0;
+    }
+    return pFrm;
+}
+
+/*************************************************************************
+ *                              CalcFtnFlag()
+ *************************************************************************/
+
+#ifdef PRODUCT
+void SwTxtFrm::CalcFtnFlag()
+#else
+void SwTxtFrm::CalcFtnFlag( xub_StrLen nStop )//Fuer den Test von SplitFrm
+#endif
+{
+    bFtn = sal_False;
+
+    const SwpHints *pHints = GetTxtNode()->GetpSwpHints();
+    if( !pHints )
+        return;
+
+    const MSHORT nSize = pHints->Count();
+
+#ifdef PRODUCT
+    const xub_StrLen nEnd = GetFollow() ? GetFollow()->GetOfst() : STRING_LEN;
+#else
+    const xub_StrLen nEnd = nStop != STRING_LEN ? nStop
+                        : GetFollow() ? GetFollow()->GetOfst() : STRING_LEN;
+#endif
+
+    for( MSHORT i = 0; i < nSize; ++i )
+    {
+        const SwTxtAttr *pHt = (*pHints)[i];
+        if ( pHt->Which() == RES_TXTATR_FTN )
+        {
+            const xub_StrLen nIdx = *pHt->GetStart();
+            if ( nEnd < nIdx )
+                break;
+            if( GetOfst() <= nIdx )
+            {
+                bFtn = sal_True;
+                break;
+            }
+        }
+    }
+}
+
+/*************************************************************************
+ *                              CalcPrepFtnAdjust()
+ *************************************************************************/
+
+sal_Bool SwTxtFrm::CalcPrepFtnAdjust()
+{
+    ASSERT( HasFtn(), "Wer ruft mich da?" );
+    SwFtnBossFrm *pBoss = FindFtnBossFrm( sal_True );
+    const SwFtnFrm *pFtn = pBoss->FindFirstFtn( this );
+    if( pFtn && FTNPOS_CHAPTER != GetNode()->GetDoc()->GetFtnInfo().ePos &&
+        ( !pBoss->GetUpper()->IsSctFrm() ||
+        !((SwSectionFrm*)pBoss->GetUpper())->IsFtnAtEnd() ) )
+    {
+        const SwFtnContFrm *pCont = pBoss->FindFtnCont();
+        sal_Bool bReArrange = sal_True;
+        if ( pCont && pCont->Frm().Top() > Frm().Bottom() )
+        {
+            pBoss->RearrangeFtns( Frm().Height() + Frm().Top(), sal_False,
+                                  pFtn->GetAttr() );
+            ValidateBodyFrm();
+            ValidateFrm();
+            pFtn = pBoss->FindFirstFtn( this );
+        }
+        else
+            bReArrange = sal_False;
+        if( !pCont || !pFtn || bReArrange != (pFtn->FindFtnBossFrm() == pBoss) )
+        {
+            SwTxtFormatInfo aInf( this );
+            SwTxtFormatter aLine( this, &aInf );
+            aLine.TruncLines();
+            SetPara( 0 );       //Wird ggf. geloescht!
+            ResetPreps();
+            return sal_False;
+        }
+    }
+    return sal_True;
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::GetFtnLine()
+ *************************************************************************/
+
+SwTwips SwTxtFrm::GetFtnLine( const SwTxtFtn *pFtn, sal_Bool bLocked ) const
+{
+    SwTxtFrm *pThis = (SwTxtFrm*)this;
+
+    if( !HasPara() )
+    {
+        // Es sieht ein wenig gehackt aus, aber man riskiert einen Haufen
+        // Aerger, wenn man versucht, per pThis->GetFormatted() doch
+        // noch an den richtigen Wert heranzukommen. Durch das PREP_ADJUST
+        // stellen wir sicher, dass wir noch einmal drankommen, dann aber
+        // von der Ref aus!
+        // Trotzdem wollen wir nichts unversucht lassen und geben die
+        // Unterkante des Frames zurueck.
+        if( !bLocked )
+            pThis->Prepare( PREP_ADJUST_FRM );
+        return Frm().Bottom();
+    }
+
+    SwTxtInfo aInf( pThis );
+    SwTxtIter aLine( pThis, &aInf );
+    const xub_StrLen nPos = *pFtn->GetStart();
+    aLine.CharToLine( nPos );
+    return aLine.Y() + SwTwips(aLine.GetLineHeight());
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::GetFtnRstHeight()
+ *************************************************************************/
+
+// Ermittelt die max. erreichbare Hoehe des TxtFrm im Ftn-Bereich.
+// Sie wird eingeschraenkt durch den unteren Rand der Zeile mit
+// der Ftn-Referenz.
+
+SwTwips SwTxtFrm::_GetFtnFrmHeight() const
+{
+    ASSERT( !IsFollow() && IsInFtn(), "SwTxtFrm::SetFtnLine: moon walk" );
+
+    const SwFtnFrm *pFtnFrm = FindFtnFrm();
+    const SwTxtFrm *pRef = (const SwTxtFrm *)pFtnFrm->GetRef();
+    const SwFtnBossFrm *pBoss = FindFtnBossFrm();
+    if( pBoss != pRef->FindFtnBossFrm( !pFtnFrm->GetAttr()->
+                                        GetFtn().IsEndNote() ) )
+        return 0;
+
+    SwTwips nHeight = pRef->IsInFtnConnect() ?
+                            1 : pRef->GetFtnLine( pFtnFrm->GetAttr(), sal_False );
+    if( nHeight )
+    {
+        // So komisch es aussehen mag: Die erste Ftn auf der Seite darf sich
+        // nicht mit der Ftn-Referenz beruehren, wenn wir im Ftn-Bereich Text
+        // eingeben.
+        const SwFrm *pCont = pFtnFrm->GetUpper();
+        //Hoehe innerhalb des Cont, die ich mir 'eh noch genehmigen darf.
+        SwTwips nTmp = pCont->Frm().Top() + pCont->Prt().Top() +
+                       pCont->Prt().Height() - Frm().Top();
+#ifndef PRODUCT
+        if( nTmp < 0 )
+        {
+            sal_Bool bInvalidPos = sal_False;
+            const SwFrm* pTmp = GetUpper();
+            while( !bInvalidPos && pTmp )
+            {
+                bInvalidPos = !pTmp->GetValidPosFlag();
+                if( pTmp == pCont )
+                    break;
+                pTmp = pTmp->GetUpper();
+            }
+            ASSERT( bInvalidPos, "Hanging below FtnCont" );
+        }
+#endif
+        if( pCont->Frm().Top() > nHeight )
+        {
+            //Wachstumspotential den Containers.
+            if ( !pRef->IsInFtnConnect() )
+            {
+                SwSaveFtnHeight aSave( (SwFtnBossFrm*)pBoss, nHeight  );
+                nHeight = ((SwFtnContFrm*)pCont)->Grow( LONG_MAX, pHeight, sal_True );
+            }
+            else
+                nHeight = ((SwFtnContFrm*)pCont)->Grow( LONG_MAX, pHeight, sal_True );
+
+            nHeight += nTmp;
+            if( nHeight < 0 )
+                nHeight = 0;
+        }
+        else
+        {   // The container has to shrink
+            nTmp += pCont->Frm().Top() - nHeight;
+            if( nTmp > 0 )
+                nHeight = nTmp;
+            else
+                nHeight = 0;
+        }
+    }
+    return nHeight;
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::FindErgoSumFrm()
+ *************************************************************************/
+
+SwTxtFrm *SwTxtFrm::FindErgoSumFrm()
+{
+    // Erstmal feststellen, ob wir in einem FtnFrm stehen:
+    if( !IsInFtn() )
+        return 0;
+
+    // Zum folgenden FtnFrm
+    SwFtnFrm *pFtnFrm = FindFtnFrm()->GetFollow();
+
+    // Nun den ersten Cntnt:
+    return pFtnFrm ? (SwTxtFrm*)(pFtnFrm->ContainsCntnt()) : 0;
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::FindQuoVadisFrm()
+ *************************************************************************/
+
+SwTxtFrm *SwTxtFrm::FindQuoVadisFrm()
+{
+    // Erstmal feststellen, ob wir in einem FtnFrm stehen:
+    if( GetIndPrev() || !IsInFtn() )
+        return 0;
+
+    // Zum Vorgaenger-FtnFrm
+    SwFtnFrm *pFtnFrm = FindFtnFrm()->GetMaster();
+    if( !pFtnFrm )
+        return 0;
+
+    // Nun den letzten Cntnt:
+    const SwCntntFrm *pCnt = pFtnFrm->ContainsCntnt();
+    if( !pCnt )
+        return NULL;
+    const SwCntntFrm *pLast;
+    do
+    {   pLast = pCnt;
+        pCnt = pCnt->GetNextCntntFrm();
+    } while( pCnt && pFtnFrm->IsAnLower( pCnt ) );
+    return (SwTxtFrm*)pLast;
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::SetErgoSumNum()
+ *************************************************************************/
+
+void SwTxtFrm::SetErgoSumNum( const MSHORT nErgo )
+{
+    SwParaPortion *pPara = GetPara();
+    if( pPara )
+    {
+        XubString aStr( nErgo );
+        pPara->SetErgoSumNum( aStr );
+    }
+}
+
+sal_Bool lcl_Apres( SwLayoutFrm* pFirst, SwLayoutFrm* pSecond )
+{
+    SwPageFrm *pPg1 = pFirst->FindPageFrm();
+    SwPageFrm *pPg2 = pSecond->FindPageFrm();
+    if( pPg1 != pPg2 )
+        return pPg1->GetPhyPageNum() < pPg2->GetPhyPageNum();
+    SwLayoutFrm *pUp = pFirst;
+    while( pUp->GetUpper() && !pUp->GetUpper()->IsAnLower( pSecond ) )
+        pUp = pUp->GetUpper();
+    if( !pUp->GetUpper() )
+        return sal_False;
+    do
+    {
+        pUp = (SwLayoutFrm*)pUp->GetNext();
+    } while( pUp && !pUp->IsAnLower( pSecond ) );
+    return 0 != pUp;
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::RemoveFtn()
+ *************************************************************************/
+
+void SwTxtFrm::RemoveFtn( const xub_StrLen nStart, const xub_StrLen nLen )
+{
+    if ( !IsFtnAllowed() )
+        return;
+
+    SwpHints *pHints = GetTxtNode()->GetpSwpHints();
+    if( !pHints )
+        return;
+
+    sal_Bool bRollBack = nLen != STRING_LEN;
+    MSHORT nSize = pHints->Count();
+    xub_StrLen nEnd;
+    SwTxtFrm* pSource;
+    if( bRollBack )
+    {
+        nEnd = nStart + nLen;
+        pSource = GetFollow();
+        if( !pSource )
+            return;
+    }
+    else
+    {
+        nEnd = STRING_LEN;
+        pSource = this;
+    }
+
+    if( nSize )
+    {
+        SwPageFrm* pUpdate = NULL;
+        sal_Bool bRemove = sal_False;
+        SwFtnBossFrm *pFtnBoss = 0;
+        SwFtnBossFrm *pEndBoss = 0;
+        sal_Bool bFtnEndDoc
+            = FTNPOS_CHAPTER == GetNode()->GetDoc()->GetFtnInfo().ePos;
+        for( MSHORT i = nSize; i; )
+        {
+            SwTxtAttr *pHt = pHints->GetHt(--i);
+            if ( RES_TXTATR_FTN != pHt->Which() )
+                continue;
+
+            const xub_StrLen nIdx = *pHt->GetStart();
+            if( nStart > nIdx )
+                break;
+
+            if( nEnd >= nIdx )
+            {
+                SwTxtFtn *pFtn = (SwTxtFtn*)pHt;
+                sal_Bool bEndn = pFtn->GetFtn().IsEndNote();
+
+                if( bEndn )
+                {
+                    if( !pEndBoss )
+                        pEndBoss = pSource->FindFtnBossFrm();
+                }
+                else
+                {
+                    if( !pFtnBoss )
+                    {
+                        pFtnBoss = pSource->FindFtnBossFrm( sal_True );
+                        if( pFtnBoss->GetUpper()->IsSctFrm() )
+                        {
+                            SwSectionFrm* pSect = (SwSectionFrm*)
+                                                  pFtnBoss->GetUpper();
+                            if( pSect->IsFtnAtEnd() )
+                                bFtnEndDoc = sal_False;
+                        }
+                    }
+                }
+
+                // Wir loeschen nicht, sondern wollen die Ftn verschieben.
+                // Drei Faelle koennen auftreten:
+                // 1) Es gibt weder Follow noch PrevFollow
+                //    -> RemoveFtn()  (vielleicht sogar ein ASSERT wert)
+                // 2) nStart > GetOfst, ich habe einen Follow
+                //    -> Ftn wandert in den Follow
+                // 3) nStart < GetOfst, ich bin ein Follow
+                //    -> Ftn wandert in den PrevFollow
+                // beide muessen auf einer Seite/in einer Spalte stehen.
+
+                SwFtnFrm *pFtnFrm = bEndn ? pEndBoss->FindFtn( pSource, pFtn ) :
+                                            pFtnBoss->FindFtn( pSource, pFtn );
+
+                if( pFtnFrm )
+                {
+                    const sal_Bool bEndDoc = bEndn ? sal_True : bFtnEndDoc;
+                    if( bRollBack )
+                    {
+                        while ( pFtnFrm )
+                        {
+                            pFtnFrm->SetRef( this );
+                            pFtnFrm = pFtnFrm->GetFollow();
+                            SetFtn( sal_True );
+                        }
+                    }
+                    else if( GetFollow() )
+                    {
+                        SwCntntFrm *pDest = GetFollow();
+                        while( pDest->GetFollow() && ((SwTxtFrm*)pDest->
+                               GetFollow())->GetOfst() <= nIdx )
+                            pDest = pDest->GetFollow();
+                        ASSERT( !pDest->FindFtnBossFrm( !bEndn )->FindFtn(
+                            pDest,pFtn),"SwTxtFrm::RemoveFtn: footnote exists");
+
+                        //Nicht ummelden sondern immer Moven.
+                        if( bEndDoc || !lcl_Apres( pFtnFrm->FindFtnBossFrm(),
+                                            pDest->FindFtnBossFrm( !bEndn ) ) )
+                        {
+                            SwPageFrm* pTmp = pFtnFrm->FindPageFrm();
+                            if( pUpdate && pUpdate != pTmp )
+                                pUpdate->UpdateFtnNum();
+                            pUpdate = pTmp;
+                            while ( pFtnFrm )
+                            {
+                                pFtnFrm->SetRef( pDest );
+                                pFtnFrm = pFtnFrm->GetFollow();
+                            }
+                        }
+                        else
+                        {
+                            if( bEndn )
+                                pEndBoss->MoveFtns( this, pDest, pFtn );
+                            else
+                                pFtnBoss->MoveFtns( this, pDest, pFtn );
+                            bRemove = sal_True;
+                        }
+                        ((SwTxtFrm*)pDest)->SetFtn( sal_True );
+
+                        ASSERT( pDest->FindFtnBossFrm( !bEndn )->FindFtn( pDest,
+                           pFtn),"SwTxtFrm::RemoveFtn: footnote ChgRef failed");
+                    }
+                    else
+                    {
+                        if( !bEndDoc || ( !bEndn && pEndBoss->IsInSct() ) )
+                        {
+                            if( bEndn )
+                                pEndBoss->RemoveFtn( this, pFtn );
+                            else
+                                pFtnBoss->RemoveFtn( this, pFtn );
+                            bRemove = bRemove || !bEndDoc;
+                            ASSERT( bEndn ? !pEndBoss->FindFtn( this, pFtn ) :
+                                    !pFtnBoss->FindFtn( this, pFtn ),
+                            "SwTxtFrm::RemoveFtn: can't get off that footnote" );
+                        }
+                    }
+                }
+            }
+        }
+        if( pUpdate )
+            pUpdate->UpdateFtnNum();
+        // Wir bringen die Oszillation zum stehen:
+        if( bRemove && !bFtnEndDoc && HasPara() )
+        {
+            ValidateBodyFrm();
+            ValidateFrm();
+        }
+    }
+    // Folgendes Problem: Aus dem FindBreak heraus wird das RemoveFtn aufgerufen,
+    // weil die letzte Zeile an den Follow abgegeben werden soll. Der Offset
+    // des Follows ist aber veraltet, er wird demnaechst gesetzt. CalcFntFlag ist
+    // auf einen richtigen Follow-Offset angewiesen. Deshalb wird hier kurzfristig
+    // der Follow-Offset manipuliert.
+    xub_StrLen nOldOfst = STRING_LEN;
+    if( HasFollow() && nStart > GetOfst() )
+    {
+        nOldOfst = GetFollow()->GetOfst();
+        GetFollow()->ManipOfst( nStart + ( bRollBack ? nLen : 0 ) );
+    }
+    pSource->CalcFtnFlag();
+    if( nOldOfst < STRING_LEN )
+        GetFollow()->ManipOfst( nOldOfst );
+}
+
+/*************************************************************************
+ *                      SwTxtFormatter::ConnectFtn()
+ *************************************************************************/
+// sal_False, wenn irgendetwas schief gegangen ist.
+// Es gibt eigentlich nur zwei Moeglichkeiten:
+// a) Die Ftn ist bereits vorhanden
+// => dann wird sie gemoved, wenn ein anderer pSrcFrm gefunden wurde
+// b) Die Ftn ist nicht vorhanden
+// => dann wird sie fuer uns angelegt.
+// Ob die Ftn schliesslich auf unserer Spalte/Seite landet oder nicht,
+// spielt in diesem Zusammenhang keine Rolle.
+// Optimierungen bei Endnoten.
+// Noch ein Problem: wenn die Deadline im Ftn-Bereich liegt, muss die
+// Ftn verschoben werden.
+
+void SwTxtFrm::ConnectFtn( SwTxtFtn *pFtn, const SwTwips nDeadLine )
+{
+    bFtn = sal_True;
+    bInFtnConnect = sal_True;   //Bloss zuruecksetzen!
+    sal_Bool bEnd = pFtn->GetFtn().IsEndNote();
+
+    // Wir brauchen immer einen Boss (Spalte/Seite)
+    SwSectionFrm *pSect;
+    SwCntntFrm *pCntnt = this;
+    if( bEnd && IsInSct() )
+    {
+        pSect = FindSctFrm();
+        if( pSect->IsEndnAtEnd() )
+            pCntnt = pSect->FindLastCntnt( FINDMODE_ENDNOTE );
+        if( !pCntnt )
+            pCntnt = this;
+    }
+
+    SwFtnBossFrm *pBoss = pCntnt->FindFtnBossFrm( !bEnd );
+
+#ifdef DEBUG
+    SwTwips nRstHeight = GetRstHeight();
+#endif
+
+    pSect = pBoss->FindSctFrm();
+    sal_Bool bDocEnd = bEnd ? !( pSect && pSect->IsEndnAtEnd() ) :
+                   ( !( pSect && pSect->IsFtnAtEnd() ) &&
+                       FTNPOS_CHAPTER == GetNode()->GetDoc()->GetFtnInfo().ePos );
+    //Ftn kann beim Follow angemeldet sein.
+    SwCntntFrm *pSrcFrm = FindFtnRef( pFtn );
+
+    if( bDocEnd )
+    {
+        if( pSect && pSrcFrm )
+        {
+            SwFtnFrm *pFtnFrm = pBoss->FindFtn( pSrcFrm, pFtn );
+            if( pFtnFrm && pFtnFrm->IsInSct() )
+            {
+                pBoss->RemoveFtn( pSrcFrm, pFtn );
+                pSrcFrm = 0;
+            }
+        }
+    }
+    else if( bEnd && pSect )
+    {
+        SwFtnFrm *pFtnFrm = pSrcFrm ? pBoss->FindFtn( pSrcFrm, pFtn ) : NULL;
+        if( pFtnFrm && !pFtnFrm->GetUpper() )
+            pFtnFrm = NULL;
+        SwDoc *pDoc = GetNode()->GetDoc();
+        if( SwLayouter::Collecting( pDoc, pSect, pFtnFrm ) )
+        {
+            if( !pSrcFrm )
+            {
+                SwFtnFrm *pNew = new SwFtnFrm(pDoc->GetDfltFrmFmt(),this,pFtn);
+                 SwNodeIndex aIdx( *pFtn->GetStartNode(), 1 );
+                 ::_InsertCnt( pNew, pDoc, aIdx.GetIndex() );
+                pDoc->GetLayouter()->CollectEndnote( pNew );
+            }
+            else if( pSrcFrm != this )
+                pBoss->ChangeFtnRef( pSrcFrm, pFtn, this );
+            bInFtnConnect = sal_False;
+            return;
+        }
+        else if( pSrcFrm )
+        {
+            SwFtnBossFrm *pFtnBoss = pFtnFrm->FindFtnBossFrm();
+            if( !pFtnBoss->IsInSct() ||
+                pFtnBoss->ImplFindSctFrm()->GetSection()!=pSect->GetSection() )
+            {
+                pBoss->RemoveFtn( pSrcFrm, pFtn );
+                pSrcFrm = 0;
+            }
+        }
+    }
+
+    if( bDocEnd || bEnd )
+    {
+        if( !pSrcFrm )
+            pBoss->AppendFtn( this, pFtn );
+        else if( pSrcFrm != this )
+            pBoss->ChangeFtnRef( pSrcFrm, pFtn, this );
+        bInFtnConnect = sal_False;
+        return;
+    }
+
+    SwSaveFtnHeight aHeight( pBoss, nDeadLine );
+
+    if( !pSrcFrm )      // Es wurde ueberhaupt keine Ftn gefunden.
+        pBoss->AppendFtn( this, pFtn );
+    else
+    {
+        SwFtnFrm *pFtnFrm = pBoss->FindFtn( pSrcFrm, pFtn );
+        SwFtnBossFrm *pFtnBoss = pFtnFrm->FindFtnBossFrm();
+
+        sal_Bool bBrutal = sal_False;
+
+        if( pFtnBoss == pBoss ) // Ref und Ftn sind auf der selben Seite/Spalte.
+        {
+            SwFrm *pCont = pFtnFrm->GetUpper();
+
+            if( pCont->Frm().Top() >= nDeadLine )//Ref und Ftn passen auf die Seite
+            {
+                //Wenn die Fussnote bei einem Follow angemeldet ist, so ist
+                //es jetzt an der Zeit sie umzumelden.
+                if ( pSrcFrm != this )
+                    pBoss->ChangeFtnRef( pSrcFrm, pFtn, this );
+                //Es steht Platz zur Verfuegung, also kann die Fussnote evtl.
+                //wachsen.
+                if ( pFtnFrm->GetFollow() && pCont->Frm().Top() > nDeadLine )
+                {
+                    SwTwips nHeight = pCont->Frm().Height();
+                    pBoss->RearrangeFtns( nDeadLine, sal_False, pFtn );
+                    ValidateBodyFrm();
+                    ValidateFrm();
+                    ViewShell *pSh = GetShell();
+                    if ( pSh && nHeight == pCont->Frm().Height() )
+                        //Damit uns nix durch die Lappen geht.
+                        pSh->InvalidateWindows( pCont->Frm() );
+                }
+                bInFtnConnect = sal_False;
+                return;
+            }
+            else
+                bBrutal = sal_True;
+        }
+        else
+        {
+            // Ref und Ftn sind nicht auf einer Seite, Move-Versuch ist noetig.
+            SwFrm* pTmp = this;
+            while( pTmp->GetNext() && pSrcFrm != pTmp )
+                pTmp = pTmp->GetNext();
+            if( pSrcFrm == pTmp )
+                bBrutal = sal_True;
+            else
+            {   // Wenn unser Boss in einem spaltigen Bereich sitzt, es aber auf
+                // der Seite schon einen FtnContainer gibt, hilft nur die brutale
+                // Methode
+                if( pSect && pSect->FindFtnBossFrm( !bEnd )->FindFtnCont() )
+                    bBrutal = sal_True;
+                else if( !pFtnFrm->GetPrev() || lcl_Apres( pFtnBoss, pBoss ) )
+                {
+                    SwFtnBossFrm *pSrcBoss = pSrcFrm->FindFtnBossFrm( !bEnd );
+                    pSrcBoss->MoveFtns( pSrcFrm, this, pFtn );
+                }
+                else
+                    pBoss->ChangeFtnRef( pSrcFrm, pFtn, this );
+            }
+        }
+
+        // Die brutale Loesung: Fussnote entfernen und appenden.
+        // Es muss SetFtnDeadLine() gerufen werden, weil nach
+        // RemoveFtn die nMaxFtnHeight evtl. besser auf unsere Wuensche
+        // eingestellt werden kann.
+        if( bBrutal )
+        {
+            pBoss->RemoveFtn( pSrcFrm, pFtn, sal_False );
+            SwSaveFtnHeight *pHeight = bEnd ? NULL :
+                new SwSaveFtnHeight( pBoss, nDeadLine );
+            pBoss->AppendFtn( this, pFtn );
+            delete pHeight;
+        }
+    }
+
+    // In spaltigen Bereichen, die noch nicht bis zum Seitenrand gehen,
+    // ist kein RearrangeFtns sinnvoll, da der Fussnotencontainer noch
+    // nicht kalkuliert worden ist.
+    if( !pSect || !pSect->Growable() )
+    {
+        // Umgebung validieren, um Oszillationen zu verhindern.
+        SwSaveFtnHeight aNochmal( pBoss, nDeadLine );
+        ValidateBodyFrm();
+        pBoss->RearrangeFtns( nDeadLine, sal_True );
+        ValidateFrm();
+    }
+    else if( pSect->IsFtnAtEnd() )
+    {
+        ValidateBodyFrm();
+        ValidateFrm();
+    }
+
+#ifdef DEBUG
+    // pFtnFrm kann sich durch Calc veraendert haben ...
+    SwFtnFrm *pFtnFrm = pBoss->FindFtn( this, pFtn );
+    if( pFtnFrm && pBoss != pFtnFrm->FindFtnBossFrm( !bEnd ) )
+    {
+        int bla = 5;
+    }
+    nRstHeight = GetRstHeight();
+#endif
+    bInFtnConnect = sal_False;
+    return;
+}
+
+/*************************************************************************
+ *                      SwTxtFormatter::NewFtnPortion()
+ *************************************************************************/
+
+// Die Portion fuer die Ftn-Referenz im Text
+SwFtnPortion *SwTxtFormatter::NewFtnPortion( SwTxtFormatInfo &rInf,
+                                             SwTxtAttr *pHint )
+{
+    if( !pFrm->IsFtnAllowed() )
+        return 0;
+
+    SwTxtFtn  *pFtn = (SwTxtFtn*)pHint;
+    SwFmtFtn& rFtn = (SwFmtFtn&)pFtn->GetFtn();
+    SwDoc *pDoc = pFrm->GetNode()->GetDoc();
+
+    if( rInf.IsTest() )
+        return new SwFtnPortion( rFtn.GetViewNumStr( *pDoc ), pFrm, pFtn );
+
+    KSHORT nReal;
+    {
+        KSHORT nOldReal = pCurr->GetRealHeight();
+        KSHORT nOldAscent = pCurr->GetAscent();
+        KSHORT nOldHeight = pCurr->Height();
+        ((SwTxtFormatter*)this)->CalcRealHeight();
+        nReal = pCurr->GetRealHeight();
+        if( nReal < nOldReal )
+            nReal = nOldReal;
+        pCurr->SetRealHeight( nOldReal );
+        pCurr->Height( nOldHeight );
+        pCurr->SetAscent( nOldAscent );
+    }
+
+    SwTwips nLower = Y() + nReal;
+    SwFrm* pPrtFrm;
+    if( pFrm->IsInTab() && (!pFrm->IsInSct() || pFrm->FindSctFrm()->IsInTab()) )
+    {
+        SwFrm *pRow = pFrm;
+        while( !pRow->IsRowFrm() || !pRow->GetUpper()->IsTabFrm() )
+            pRow = pRow->GetUpper();
+        SwTwips nMin = pRow->Frm().Top() + pRow->Frm().Height();
+        if( nMin > nLower )
+            nLower = nMin;
+        pPrtFrm = pRow->GetUpper();
+    }
+    else
+        pPrtFrm = pFrm;
+    SwTwips nAdd =
+        pPrtFrm->Frm().Height() -pPrtFrm->Prt().Height() -pPrtFrm->Prt().Top();
+    if( nAdd > 0 )
+        nLower += nAdd;
+        //6995: Wir frischen nur auf. Das Connect tut fuer diesen Fall nix
+        //Brauchbares, sondern wuerde stattdessen fuer diesen Fall meist die
+        //Ftn wegwerfen und neu erzeugen.
+    if( !rInf.IsQuick() )
+        pFrm->ConnectFtn( pFtn, nLower );
+
+    SwTxtFrm *pScrFrm = pFrm->FindFtnRef( pFtn );
+    SwFtnBossFrm *pBoss = pFrm->FindFtnBossFrm( !rFtn.IsEndNote() );
+    SwFtnFrm *pFtnFrm = NULL;
+    if( pScrFrm )
+    {
+        pFtnFrm = pBoss->FindFtn( pScrFrm, pFtn );
+        if( pFtnFrm && pFtnFrm->Lower() )
+        {
+            SwTxtFrm *pTxtFrm = NULL;
+            if( pFtnFrm->Lower()->IsTxtFrm() )
+                pTxtFrm = (SwTxtFrm*)pFtnFrm->Lower();
+            else if( pFtnFrm->Lower()->IsSctFrm() )
+            {
+                SwFrm* pCntnt = ((SwSectionFrm*)pFtnFrm->Lower())->ContainsCntnt();
+                if( pCntnt && pCntnt->IsTxtFrm() )
+                    pTxtFrm = (SwTxtFrm*)pCntnt;
+            }
+            if ( pTxtFrm && pTxtFrm->HasPara() )
+            {
+                SwParaPortion *pPara = pTxtFrm->GetPara();
+                SwLinePortion *pTmp = pPara->GetPortion();
+                while( pTmp )
+                {
+                    if( pTmp->IsFtnNumPortion() )
+                    {
+                        SeekAndChg( rInf );
+                        if( ((SwFtnNumPortion*)pTmp)->DiffFont( rInf.GetFont() ) )
+                            pTxtFrm->Prepare(PREP_FTN);
+                        break;
+                    }
+                    pTmp = pTmp->GetPortion();
+                }
+            }
+        }
+    }
+    // Wir erkundigen uns, ob durch unser Append irgendeine
+    // Fussnote noch auf der Seite/Spalte steht. Wenn nicht verschwindet
+    // auch unsere Zeile. Dies fuehrt zu folgendem erwuenschten
+    // Verhalten: Ftn1 pass noch auf die Seite/Spalte, Ftn2 nicht mehr.
+    // Also bleibt die Ftn2-Referenz auf der Seite/Spalte stehen. Die
+    // Fussnote selbst folgt aber erst auf der naechsten Seite/Spalte.
+    // Ausnahme: Wenn keine weitere Zeile auf diese Seite/Spalte passt,
+    // so sollte die Ftn2-Referenz auch auf die naechste wandern.
+    if( !rFtn.IsEndNote() )
+    {
+        SwSectionFrm *pSct = pBoss->FindSctFrm();
+        sal_Bool bAtSctEnd = pSct && pSct->IsFtnAtEnd();
+        if( FTNPOS_CHAPTER != pDoc->GetFtnInfo().ePos || bAtSctEnd )
+        {
+            SwFrm* pFtnCont = pBoss->FindFtnCont();
+            // Wenn der Boss in einem Bereich liegt, kann es sich nur um eine
+            // Spalte dieses Bereichs handeln. Wenn dies nicht die erste Spalte
+            // ist, duerfen wir ausweichen
+            if( !pFrm->IsInTab() && ( GetLineNr() > 1 || pFrm->GetPrev() ||
+                ( !bAtSctEnd && pFrm->GetIndPrev() ) ||
+                ( pSct && pBoss->GetPrev() ) ) )
+            {
+                if( !pFtnCont )
+                {
+                    rInf.SetStop( sal_True );
+                    return 0;
+                }
+                else
+                {
+                    // Es darf keine Fussnotencontainer in spaltigen Bereichen und
+                    // gleichzeitig auf der Seite/Seitenspalte geben
+                    if( pSct && !bAtSctEnd ) // liegt unser Container in einem (spaltigen) Bereich?
+                    {
+                        SwFtnBossFrm* pTmp = pBoss->FindSctFrm()->FindFtnBossFrm( sal_True );
+                        SwFtnContFrm* pFtnC = pTmp->FindFtnCont();
+                        if( pFtnC )
+                        {
+                            SwFtnFrm* pTmp = (SwFtnFrm*)pFtnC->Lower();
+                            if( pTmp && *pTmp < pFtn )
+                            {
+                                rInf.SetStop( sal_True );
+                                return 0;
+                            }
+                        }
+                    }
+                    // Ist dies die letzte passende Zeile?
+                    if( pScrFrm && Y() + nReal*2 > pFtnCont->Frm().Top() )
+                    {
+                        if( pFtnFrm )
+                        {
+                            SwFtnBossFrm *pFtnBoss = pFtnFrm->FindFtnBossFrm();
+                            if( pFtnBoss != pBoss )
+                            {
+                                // Wir sind in der letzte Zeile und die Fussnote
+                                // ist auf eine andere Seite gewandert, dann wollen
+                                // wir mit ...
+                                rInf.SetStop( sal_True );
+                                return 0;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    // Endlich: FtnPortion anlegen und raus hier...
+    SwFtnPortion *pRet = new SwFtnPortion( rFtn.GetViewNumStr( *pDoc ),
+                                            pFrm, pFtn, nReal );
+    rInf.SetFtnInside( sal_True );
+    return pRet;
+ }
+
+/*************************************************************************
+ *                      SwTxtFormatter::NewFtnNumPortion()
+ *************************************************************************/
+
+// Die Portion fuer die Ftn-Nummerierung im Ftn-Bereich
+
+SwNumberPortion *SwTxtFormatter::NewFtnNumPortion( SwTxtFormatInfo &rInf ) const
+{
+    ASSERT( pFrm->IsInFtn() && !pFrm->GetIndPrev() && !rInf.IsFtnDone(),
+            "This is the wrong place for a ftnnumber" );
+    if( rInf.GetTxtStart() != nStart ||
+        rInf.GetTxtStart() != rInf.GetIdx() )
+        return 0;
+
+    const SwFtnFrm *pFtnFrm = pFrm->FindFtnFrm();
+    const SwTxtFtn *pFtn = pFtnFrm->GetAttr();
+
+    // Aha, wir sind also im Fussnotenbereich
+    SwFmtFtn& rFtn = (SwFmtFtn&)pFtn->GetFtn();
+
+    SwDoc *pDoc = pFrm->GetNode()->GetDoc();
+    XubString aFtnTxt( rFtn.GetViewNumStr( *pDoc, sal_True ));
+
+    const SwEndNoteInfo* pInfo;
+    if( rFtn.IsEndNote() )
+        pInfo = &pDoc->GetEndNoteInfo();
+    else
+        pInfo = &pDoc->GetFtnInfo();
+    const SwAttrSet& rSet = pInfo->GetCharFmt(*pDoc)->GetAttrSet();
+
+    const SwAttrSet* pParSet = &rInf.GetCharAttr();
+    SwFont *pFnt = new SwFont( pParSet );
+    pFnt->SetDiffFnt(&rSet);
+    SwTxtFtn* pTxtFtn = rFtn.GetTxtFtn();
+    if( pTxtFtn )
+    {
+        SwAttrIter aIter( (SwTxtNode&)pTxtFtn->GetTxtNode() );
+        aIter.Seek( *pTxtFtn->GetStart() );
+        // Achtung: Wenn die Kriterien, nach denen der FtnReferenz-Font
+        // auf den FtnNumerierungsfont wirkt, geaendert werden, muss die
+        // untenstehende Methode SwFtnNumPortion::DiffFont() angepasst
+        // werden.
+        if( aIter.GetFnt()->IsSymbol(rInf.GetVsh()) || aIter.GetFnt()->GetCharSet() !=
+            pFnt->GetCharSet() )
+        {
+            const BYTE nAct = pFnt->GetActual();
+            pFnt->SetName( aIter.GetFnt()->GetName(), nAct );
+            pFnt->SetStyleName( aIter.GetFnt()->GetStyleName(), nAct );
+            pFnt->SetFamily( aIter.GetFnt()->GetFamily(),nAct );
+            pFnt->SetCharSet( aIter.GetFnt()->GetCharSet(), nAct );
+        }
+    }
+    return new SwFtnNumPortion( aFtnTxt, pFnt );
+}
+
+/*************************************************************************
+ *                  SwTxtFormatter::NewErgoSumPortion()
+ *************************************************************************/
+
+XubString lcl_GetPageNumber( const SwPageFrm* pPage )
+{
+    ASSERT( pPage, "GetPageNumber: Homeless TxtFrm" );
+    MSHORT nVirtNum = pPage->GetVirtPageNum();
+    const SwNumType& rNum = pPage->GetPageDesc()->GetNumType();
+    return rNum.GetNumStr( nVirtNum );
+}
+
+SwErgoSumPortion *SwTxtFormatter::NewErgoSumPortion( SwTxtFormatInfo &rInf ) const
+{
+    // Wir koennen nicht davon ausgehen, dass wir ein Follow sind
+    // 7983: GetIdx() nicht nStart
+    if( !pFrm->IsInFtn()  || pFrm->GetPrev() ||
+        rInf.IsErgoDone() || rInf.GetIdx() != pFrm->GetOfst() ||
+        pFrm->ImplFindFtnFrm()->GetAttr()->GetFtn().IsEndNote() )
+        return 0;
+
+    // Aha, wir sind also im Fussnotenbereich
+    const SwFtnInfo &rFtnInfo = pFrm->GetNode()->GetDoc()->GetFtnInfo();
+    SwTxtFrm *pQuoFrm = pFrm->FindQuoVadisFrm();
+    if( !pQuoFrm )
+        return 0;
+    const SwPageFrm* pPage = pFrm->FindPageFrm();
+    const SwPageFrm* pQuoPage = pQuoFrm->FindPageFrm();
+    if( pPage == pQuoFrm->FindPageFrm() )
+        return 0; // Wenn der QuoVadis auf der selben (spaltigen) Seite steht
+    const XubString aPage = lcl_GetPageNumber( pPage );
+    SwParaPortion *pPara = pQuoFrm->GetPara();
+    if( pPara )
+        pPara->SetErgoSumNum( aPage );
+    if( !rFtnInfo.aErgoSum.Len() )
+        return 0;
+    SwErgoSumPortion *pErgo = new SwErgoSumPortion( rFtnInfo.aErgoSum,
+                                lcl_GetPageNumber( pQuoPage ) );
+    return pErgo;
+}
+
+/*************************************************************************
+ *                  SwTxtFormatter::FormatQuoVadis()
+ *************************************************************************/
+
+xub_StrLen SwTxtFormatter::FormatQuoVadis( const xub_StrLen nOffset )
+{
+    if( !pFrm->IsInFtn() || pFrm->ImplFindFtnFrm()->GetAttr()->GetFtn().IsEndNote() )
+        return nOffset;
+
+    const SwFrm* pErgoFrm = pFrm->FindFtnFrm()->GetFollow();
+    if( !pErgoFrm && pFrm->HasFollow() )
+        pErgoFrm = pFrm->GetFollow();
+    if( !pErgoFrm )
+        return nOffset;
+
+    if( pErgoFrm == pFrm->GetNext() )
+    {
+        SwFrm *pCol = pFrm->FindColFrm();
+        while( pCol && !pCol->GetNext() )
+            pCol = pCol->GetUpper()->FindColFrm();
+        if( pCol )
+            return nOffset;
+    }
+    else
+    {
+        const SwPageFrm* pPage = pFrm->FindPageFrm();
+        const SwPageFrm* pErgoPage = pErgoFrm->FindPageFrm();
+        if( pPage == pErgoFrm->FindPageFrm() )
+            return nOffset; // Wenn der ErgoSum auf der selben Seite steht
+    }
+
+    SwTxtFormatInfo &rInf = GetInfo();
+    const SwFtnInfo &rFtnInfo = pFrm->GetNode()->GetDoc()->GetFtnInfo();
+    if( !rFtnInfo.aQuoVadis.Len() )
+        return nOffset;
+
+    // Ein Wort zu QuoVadis/ErgoSum:
+    // Fuer diese Texte wird der am Absatz eingestellte Font verwendet.
+    // Wir initialisieren uns also:
+//  ResetFont();
+    FeedInf( rInf );
+    SeekStartAndChg( rInf, sal_True );
+    if( GetRedln() && pCurr->HasRedline() )
+        GetRedln()->Seek( *pFnt, nOffset, 0 );
+
+    // Ein fieser Sonderfall: Flyfrms reichen in die Zeile und stehen
+    // natuerlich da, wo wir unseren Quovadis Text reinsetzen wollen.
+    // Erst mal sehen, ob es so schlimm ist:
+    SwLinePortion *pPor = pCurr->GetFirstPortion();
+    KSHORT nLastLeft = 0;
+    while( pPor )
+    {
+        if ( pPor->IsFlyPortion() )
+            nLastLeft = ( (SwFlyPortion*) pPor)->Fix() +
+                        ( (SwFlyPortion*) pPor)->Width();
+        pPor = pPor->GetPortion();
+    }
+    // Das alte Spiel: wir wollen, dass die Zeile an einer bestimmten
+    // Stelle umbricht, also beeinflussen wir die Width.
+    // nLastLeft ist jetzt quasi der rechte Rand.
+    const KSHORT nOldRealWidth = rInf.RealWidth();
+    rInf.RealWidth( nOldRealWidth - nLastLeft );
+
+    XubString aErgo = lcl_GetPageNumber( pErgoFrm->FindPageFrm() );
+    SwQuoVadisPortion *pQuo = new SwQuoVadisPortion(rFtnInfo.aQuoVadis, aErgo );
+    pQuo->SetAscent( rInf.GetAscent()  );
+    pQuo->Height( rInf.GetTxtHeight() );
+    pQuo->Format( rInf );
+
+    // Wir nutzen das Recycling-Feature aus und suchen die Stelle,
+    // ab der wir den QuoVadis-Text einfuegen wollen.
+    nLastLeft = nOldRealWidth - pQuo->Width();
+    pPor = pCurr->GetFirstPortion();
+    while( pPor && nLastLeft > rInf.X() + pPor->Width() )
+    {
+        pPor->Move( rInf );
+        pPor = pPor->GetPortion();
+    }
+    if( pPor )
+        rInf.GetParaPortion()->GetReformat()->Start() = rInf.GetIdx();
+
+    // Jetzt wird formatiert
+    Right( KSHORT(Right()) - pQuo->Width() );
+    const xub_StrLen nRet = FormatLine( nStart );
+    Right( rInf.Left() + nOldRealWidth - 1 );
+
+    nLastLeft = nOldRealWidth - pCurr->Width();
+    FeedInf( rInf );
+#ifdef USED
+    ASSERT( nOldRealWidth == rInf.RealWidth() && nLastLeft >= pQuo->Width(),
+            "SwTxtFormatter::FormatQuoVadis: crime doesn't pay" );
+#endif
+    if( pQuo->Width() > nLastLeft )
+        pQuo->Width( nLastLeft );
+
+    // Es kann durchaus sein, dass am Ende eine Marginportion steht,
+    // die beim erneuten Aufspannen nur Aerger bereiten wuerde.
+    pPor = pCurr->FindLastPortion();
+    SwGluePortion *pGlue = pPor->IsMarginPortion() ?
+        (SwMarginPortion*) pPor : 0;
+    if( pGlue )
+    {
+        pGlue->Height( 0 );
+        pGlue->Width( 0 );
+        pGlue->SetLen( 0 );
+        pGlue->SetAscent( 0 );
+        pGlue->SetPortion( NULL );
+        pGlue->SetFixWidth(0);
+    }
+
+    // Luxus: Wir sorgen durch das Aufspannen von Glues dafuer,
+    // dass der QuoVadis-Text rechts erscheint:
+    long nQuoWidth = pQuo->Width();
+    nLastLeft -= pQuo->Width();
+    if( nLastLeft )
+    {
+        if( nLastLeft > pQuo->GetAscent() ) // Mindestabstand
+        {
+            switch( GetAdjust() )
+            {
+                case SVX_ADJUST_BLOCK:
+                {
+                    if( !pCurr->GetLen() ||
+                        CH_BREAK != GetInfo().GetChar(nStart+pCurr->GetLen()-1))
+                        nLastLeft = pQuo->GetAscent();
+                    nQuoWidth += nLastLeft;
+                    break;
+                }
+                case SVX_ADJUST_RIGHT:
+                {
+                    nLastLeft = pQuo->GetAscent();
+                    nQuoWidth += nLastLeft;
+                    break;
+                }
+                case SVX_ADJUST_CENTER:
+                {
+                    nQuoWidth += pQuo->GetAscent();
+                    long nDiff = nLastLeft - nQuoWidth;
+                    if( nDiff < 0 )
+                    {
+                        nLastLeft = pQuo->GetAscent();
+                        nQuoWidth = -nDiff + nLastLeft;
+                    }
+                    else
+                    {
+                        nQuoWidth = 0;
+                        nLastLeft = ( pQuo->GetAscent() + nDiff ) / 2;
+                    }
+                    break;
+                }
+                default:
+                    nQuoWidth += nLastLeft;
+            }
+        }
+        else
+            nQuoWidth += nLastLeft;
+        if( nLastLeft )
+        {
+            pGlue = new SwGluePortion(0);
+            pGlue->Width( nLastLeft );
+            pPor->Append( pGlue );
+            pPor = pPor->GetPortion();
+        }
+    }
+
+    // Jetzt aber: die QuoVadis-Portion wird angedockt:
+    pPor->Append( pQuo );
+    pCurr->Width( pCurr->Width() + KSHORT( nQuoWidth ) );
+
+    // Und noch einmal adjustieren wegen des Adjustment und nicht zu Letzt
+    // wegen folgendem Sonderfall: In der Zeile hat der DummUser durchgaengig
+    // einen kleineren Font eingestellt als der vom QuoVadis-Text ...
+    CalcAdjustLine( pCurr );
+
+#ifdef DEBUG
+    if( OPTDBG( rInf ) )
+    {
+//        aDbstream << "FormatQuoVadis:" << endl;
+//        pCurr->DebugPortions( aDbstream, rInf.GetTxt(), nStart );
+    }
+#endif
+
+    // Uff...
+    return nRet;
+}
+
+
+/*************************************************************************
+ *                  SwTxtFormatter::MakeDummyLine()
+ *************************************************************************/
+
+// MakeDummyLine() erzeugt eine Line, die bis zum unteren Seitenrand
+// reicht. DummyLines bzw. DummyPortions sorgen dafuer, dass Oszillationen
+// zum stehen kommen, weil Rueckflussmoeglichkeiten genommen werden.
+// Sie werden bei absatzgebundenen Frames in Fussnoten und bei Ftn-
+// Oszillationen verwendet.
+
+void SwTxtFormatter::MakeDummyLine()
+{
+    KSHORT nRstHeight = GetFrmRstHeight();
+    if( pCurr && nRstHeight > pCurr->Height() )
+    {
+        SwLineLayout *pLay = new SwLineLayout;
+        nRstHeight -= pCurr->Height();
+        pLay->Height( nRstHeight );
+        pLay->SetAscent( nRstHeight );
+        Insert( pLay );
+        Next();
+    }
+}
+
+/*************************************************************************
+ *                     SwFtnSave::SwFtnSave()
+ *************************************************************************/
+
+SwFtnSave::SwFtnSave( const SwTxtSizeInfo &rInf, const SwTxtFtn* pTxtFtn )
+    : pInf( &((SwTxtSizeInfo&)rInf) )
+{
+    if( pTxtFtn && rInf.GetTxtFrm() )
+    {
+        pFnt = ((SwTxtSizeInfo&)rInf).GetFont();
+          pOld = new SwFont( *pFnt );
+        pOld->GetTox() = pFnt->GetTox();
+        pFnt->GetTox() = 0;
+        SwFmtFtn& rFtn = (SwFmtFtn&)pTxtFtn->GetFtn();
+        const SwDoc *pDoc = rInf.GetTxtFrm()->GetNode()->GetDoc();
+
+        const SwEndNoteInfo* pInfo;
+        if( rFtn.IsEndNote() )
+            pInfo = &pDoc->GetEndNoteInfo();
+        else
+            pInfo = &pDoc->GetFtnInfo();
+        const SwAttrSet& rSet = pInfo->GetAnchorCharFmt((SwDoc&)*pDoc)->GetAttrSet();
+        pFnt->SetDiffFnt( &rSet );
+        pFnt->ChgPhysFnt( pInf->GetVsh(), pInf->GetOut() );
+        const SfxPoolItem* pItem;
+        if( SFX_ITEM_SET == rSet.GetItemState( RES_CHRATR_BACKGROUND,
+            sal_True, &pItem ))
+            pFnt->SetBackColor( new Color( ((SvxBrushItem*)pItem)->GetColor() ) );
+    }
+    else
+        pFnt = NULL;
+}
+
+/*************************************************************************
+ *                      SwFtnPortion::SwFtnPortion()
+ *************************************************************************/
+
+SwFtnPortion::SwFtnPortion( const XubString &rExpand,
+                            SwTxtFrm *pFrm, SwTxtFtn *pFtn, KSHORT nReal )
+        : aExpand( rExpand ), pFrm(pFrm), pFtn(pFtn), nOrigHeight( nReal )
+{
+    SetLen(1);
+    SetWhichPor( POR_FTN );
+}
+
+/*************************************************************************
+ *                      SwFtnPortion::GetExpTxt()
+ *************************************************************************/
+
+sal_Bool SwFtnPortion::GetExpTxt( const SwTxtSizeInfo &, XubString &rTxt ) const
+{
+    rTxt = aExpand;
+    return sal_True;
+}
+
+void SwFtnPortion::ClearFtn()
+{
+    if( pFrm && (!pFrm->IsInSct() ||
+        !SwLayouter::Collecting( pFrm->GetNode()->GetDoc(),
+                                 pFrm->FindSctFrm(), NULL ) ) )
+        pFrm->FindFtnBossFrm( !pFtn->GetFtn().IsEndNote() )
+                              ->RemoveFtn( pFrm, pFtn );
+}
+
+
+/*************************************************************************
+ *                 virtual SwFtnPortion::Format()
+ *************************************************************************/
+
+sal_Bool SwFtnPortion::Format( SwTxtFormatInfo &rInf )
+{
+    SwFtnSave aFtnSave( rInf, pFtn );
+    sal_Bool bFull = SwExpandPortion::Format( rInf );
+    SetAscent( rInf.GetAscent() );
+    rInf.SetFtnDone( !bFull );
+    if( !bFull )
+        rInf.SetParaFtn();
+    return bFull;
+}
+
+/*************************************************************************
+ *               virtual SwFtnPortion::Paint()
+ *************************************************************************/
+
+void SwFtnPortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+    SwFtnSave aFtnSave( rInf, pFtn );
+    rInf.DrawViewOpt( *this, POR_FTN );
+    SwExpandPortion::Paint( rInf );
+}
+
+/*************************************************************************
+ *               virtual SwFtnPortion::GetTxtSize()
+ *************************************************************************/
+
+SwPosSize SwFtnPortion::GetTxtSize( const SwTxtSizeInfo &rInfo ) const
+{
+    SwFtnSave aFtnSave( rInfo, pFtn );
+    return SwExpandPortion::GetTxtSize( rInfo );
+}
+
+/*************************************************************************
+ *                      class SwQuoVadisPortion
+ *************************************************************************/
+
+SwFldPortion *SwQuoVadisPortion::Clone( const XubString &rExpand ) const
+{ return new SwQuoVadisPortion( rExpand, aErgo ); }
+
+SwQuoVadisPortion::SwQuoVadisPortion( const XubString &rExp, const XubString& rStr )
+    : SwFldPortion( rExp ), aErgo(rStr)
+{
+    SetLen(0);
+    SetWhichPor( POR_QUOVADIS );
+}
+
+/*************************************************************************
+ *                 virtual SwQuoVadisPortion::Format()
+ *************************************************************************/
+
+sal_Bool SwQuoVadisPortion::Format( SwTxtFormatInfo &rInf )
+{
+    // erster Versuch, vielleicht passt der Text
+    sal_Bool bFull = SwFldPortion::Format( rInf );
+    SetLen( 0 );
+
+    if( bFull )
+    {
+        // zweiter Versuch, wir kuerzen den String:
+        aExpand = XubString( "...", RTL_TEXTENCODING_MS_1252 );
+        bFull = SwFldPortion::Format( rInf );
+        SetLen( 0 );
+        if( bFull  )
+            // dritter Versuch, es langt: jetzt wird gestaucht:
+            Width( rInf.Width() - rInf.X() );
+
+        // 8317: keine mehrzeiligen Felder bei QuoVadis und ErgoSum
+        if( rInf.GetRest() )
+        {
+            delete rInf.GetRest();
+            rInf.SetRest( 0 );
+        }
+    }
+    return bFull;
+}
+
+/*************************************************************************
+ *               virtual SwQuoVadisPortion::GetExpTxt()
+ *************************************************************************/
+
+sal_Bool SwQuoVadisPortion::GetExpTxt( const SwTxtSizeInfo &, XubString &rTxt ) const
+{
+    rTxt = aExpand;
+    rTxt += aErgo;
+    return sal_True;
+}
+
+/*************************************************************************
+ *               virtual SwQuoVadisPortion::Paint()
+ *************************************************************************/
+
+void SwQuoVadisPortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+    // Wir wollen _immer_ per DrawStretchText ausgeben,
+    // weil nErgo schnell mal wechseln kann.
+    if( PrtWidth() )
+    {
+        rInf.DrawViewOpt( *this, POR_QUOVADIS );
+        SwTxtSlotLen aDiffTxt( &rInf, this );
+        rInf.DrawText( *this, rInf.GetLen(), sal_True );
+    }
+}
+
+/*************************************************************************
+ *                      class SwErgoSumPortion
+ *************************************************************************/
+
+SwFldPortion *SwErgoSumPortion::Clone( const XubString &rExpand ) const
+{
+#ifdef ENABLEUNICODE
+    UniString aTmp = UniString::CreateFromInt32( 0 );
+#else
+    XubString aTmp( MSHORT(0) );
+#endif
+    return new SwErgoSumPortion( rExpand, aTmp );
+}
+
+SwErgoSumPortion::SwErgoSumPortion( const XubString &rExp, const XubString& rStr )
+    : SwFldPortion( rExp )
+{
+    SetLen(0);
+    aExpand += rStr;
+
+    // 7773: sinnvolle Massnahme: ein Blank Abstand zum Text
+    aExpand += ' ';
+    SetWhichPor( POR_ERGOSUM );
+}
+
+xub_StrLen SwErgoSumPortion::GetCrsrOfst( const KSHORT ) const
+{
+    return 0;
+}
+
+/*************************************************************************
+ *                 virtual SwErgoSumPortion::Format()
+ *************************************************************************/
+
+sal_Bool SwErgoSumPortion::Format( SwTxtFormatInfo &rInf )
+{
+    sal_Bool bFull = SwFldPortion::Format( rInf );
+    SetLen( 0 );
+    rInf.SetErgoDone( 0 != Width() );
+
+    // 8317: keine mehrzeiligen Felder bei QuoVadis und ErgoSum
+    if( rInf.GetRest() )
+    {
+        delete rInf.GetRest();
+        rInf.SetRest( 0 );
+    }
+    return bFull;
+}
+
+/*************************************************************************
+ * sal_Bool SwFtnNumPortion::DiffFont()
+ *  liefert sal_True, wenn der Font der FtnReferenz (pFont) eine Aenderung
+ *  des Fonts der FtnNumerierung (pFnt) erforderlich macht.
+ *  Die Bedingungen sind ein Spiegel dessen, was in NewFtnNumPortion steht
+ *************************************************************************/
+
+sal_Bool SwFtnNumPortion::DiffFont( SwFont* pFont )
+{
+    if( pFnt->GetName() != pFont->GetName() ||
+        pFnt->GetStyleName() != pFont->GetStyleName() ||
+        pFnt->GetFamily() != pFont->GetFamily() ||
+        pFont->GetCharSet() != pFnt->GetCharSet() )
+        return sal_True;
+    return sal_False;
+}
+
+/*************************************************************************
+ *                      SwParaPortion::SetErgoSumNum()
+ *************************************************************************/
+
+void SwParaPortion::SetErgoSumNum( const XubString& rErgo )
+{
+    SwLineLayout *pLay = this;
+    while( pLay->GetNext() )
+    {
+        DBG_LOOP;
+        pLay = pLay->GetNext();
+    }
+    SwLinePortion     *pPor = pLay;
+    SwQuoVadisPortion *pQuo = 0;
+    while( pPor && !pQuo )
+    {
+        if ( pPor->IsQuoVadisPortion() )
+            pQuo = (SwQuoVadisPortion*)pPor;
+        pPor = pPor->GetPortion();
+    }
+    if( pQuo )
+        pQuo->SetNumber( rErgo );
+}
+
+/*************************************************************************
+ *                      SwParaPortion::UpdateQuoVadis()
+ *
+ * Wird im SwTxtFrm::Prepare() gerufen
+ *************************************************************************/
+
+sal_Bool SwParaPortion::UpdateQuoVadis( const XubString &rQuo )
+{
+    SwLineLayout *pLay = this;
+    while( pLay->GetNext() )
+    {
+        DBG_LOOP;
+        pLay = pLay->GetNext();
+    }
+    SwLinePortion     *pPor = pLay;
+    SwQuoVadisPortion *pQuo = 0;
+    while( pPor && !pQuo )
+    {
+        if ( pPor->IsQuoVadisPortion() )
+            pQuo = (SwQuoVadisPortion*)pPor;
+        pPor = pPor->GetPortion();
+    }
+
+    if( !pQuo )
+        return sal_False;
+
+    return pQuo->GetQuoTxt() == rQuo;
+}
+
+
+
diff --git a/sw/source/core/text/txthyph.cxx b/sw/source/core/text/txthyph.cxx
new file mode 100644
index 000000000000..84c7e914eb6d
--- /dev/null
+++ b/sw/source/core/text/txthyph.cxx
@@ -0,0 +1,910 @@
+/*************************************************************************
+ *
+ *  $RCSfile: txthyph.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:26 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _WORDSEL_HXX //autogen
+#include 
+#endif
+#ifndef _UNO_LINGU_HXX
+#include 
+#endif
+
+#ifndef _VIEWOPT_HXX
+#include   // SwViewOptions
+#endif
+#ifndef _VIEWSH_HXX
+#include 
+#endif
+#ifndef _ERRHDL_HXX
+#include 
+#endif
+#ifndef _TXTCFG_HXX
+#include 
+#endif
+#ifndef _PORHYPH_HXX
+#include   //
+#endif
+#ifndef _INFTXT_HXX
+#include 
+#endif
+#ifndef _TXTFRM_HXX
+#include 
+#endif
+#ifndef _ITRFORM2_HXX
+#include  //
+#endif
+#ifndef _GUESS_HXX
+#include     //
+#endif
+#ifndef _SPLARGS_HXX
+#include   // SwInterHyphInfo
+#endif
+#ifndef _PORRST_HXX
+#include    // SwKernPortion
+#endif
+
+#ifndef PRODUCT
+extern const sal_Char *GetLangName( const MSHORT nLang );
+#endif
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::linguistic;
+
+/*************************************************************************
+ *                      SwTxtFormatInfo::HyphWord()
+ *************************************************************************/
+
+Reference< XHyphenatedWord >  SwTxtFormatInfo::HyphWord(
+                                const XubString &rTxt, const MSHORT nMinTrail )
+{
+    if( rTxt.Len() < 4 || pFnt->IsSymbol(pVsh) )
+        return 0;
+    ASSERT( IsHyphenate(), "SwTxtFormatter::HyphWord: why?" );
+    Reference< XHyphenator >  xHyph = GetVsh() ? GetVsh()->GetHyphenator() :
+        ::GetHyphenator();
+    Reference< XHyphenatedWord >    xHyphWord;
+
+    if( xHyph.is() )
+        xHyphWord = xHyph->hyphenate( OUString(rTxt),
+                            SvxCreateLocale( pFnt->GetLanguage() ),
+                            rTxt.Len() - nMinTrail );
+    return xHyphWord;
+
+}
+
+/*************************************************************************
+ *                      SwTxtFrm::Hyphenate
+ *
+ * Wir formatieren eine Zeile fuer die interaktive Trennung
+ *************************************************************************/
+
+sal_Bool SwTxtFrm::Hyphenate( SwInterHyphInfo &rHyphInf )
+{
+    // Wir machen den Laden erstmal dicht:
+    ASSERT( !IsLocked(), "SwTxtFrm::Hyphenate: this is locked" );
+    // 4935: Der ::com::sun::star::frame::Frame muss eine gueltige SSize haben!
+    Calc();
+    GetFormatted();
+
+    sal_Bool bRet = sal_False;
+    if( !IsEmpty() )
+    {
+        // Wir muessen die Trennung immer einschalten.
+        // Keine Angst, der SwTxtIter sichert im Hyphenate die alte Zeile.
+        SwTxtFrmLocker aLock( this );
+        SwTxtFormatInfo aInf( this, sal_True );     // sal_True fuer interactive hyph!
+        SwTxtFormatter aLine( this, &aInf );
+        aLine.CharToLine( rHyphInf.nStart );
+        // Wenn wir innerhalb des ersten Wortes einer Zeile stehen, so koennte
+        // dieses in der vorherigen getrennt werden, deshalb gehen wir ein Zeile
+        // zurueck.
+        if( aLine.Prev() )
+        {
+            SwLinePortion *pPor = aLine.GetCurr()->GetFirstPortion();
+            while( pPor->GetPortion() )
+                pPor = pPor->GetPortion();
+            if( pPor->GetWhichPor() == POR_SOFTHYPH ||
+                pPor->GetWhichPor() == POR_SOFTHYPHSTR )
+                aLine.Next();
+        }
+
+        const xub_StrLen nEnd = rHyphInf.GetEnd();
+        while( !bRet && aLine.GetStart() < nEnd )
+        {
+            DBG_LOOP;
+            bRet = aLine.Hyphenate( rHyphInf );
+            if( !aLine.Next() )
+                break;
+        }
+    }
+    return bRet;
+}
+
+/*************************************************************************
+ *                      SwTxtFormatter::Hyphenate
+ *
+ * Wir formatieren eine Zeile fuer die interaktive Trennung
+ *************************************************************************/
+// Wir koennen davon ausgehen, dass bereits formatiert wurde.
+// Fuer die CeBIT'93 gehen wir den einfachen, sicheren Weg:
+// Die Zeile wird einfach neu formatiert, der Hyphenator wird dann
+// so vorbereitet, wie ihn die UI erwartet.
+// Hier stehen natuerlich enorme Optimierungsmoeglichkeiten offen.
+
+void SetParaPortion( SwTxtInfo *pInf, SwParaPortion *pRoot )
+{
+    ASSERT( pRoot, "SetParaPortion: no root anymore" );
+    pInf->pPara = pRoot;
+}
+
+sal_Bool SwTxtFormatter::Hyphenate( SwInterHyphInfo &rHyphInf )
+{
+    SwTxtFormatInfo &rInf = GetInfo();
+    sal_Bool bRet = sal_False;
+
+    // In der letzten Zeile gibt es nie etwas zu trennen.
+    // Es sei denn, es befindet sich eine FlyPortion darin,
+    // oder es ist die letzte Zeile des Masters
+    if( !GetNext() && !rInf.GetTxtFly()->IsOn() && !pFrm->GetFollow() )
+        return bRet;
+
+    xub_StrLen nWrdStart = nStart;
+
+    // Wir muessen die alte Zeile erhalten. Ein Beispiel:
+    // Das Attribut fuer Trennung wurde nicht gesetzt,
+    // in SwTxtFrm::Hyphenate wird es jedoch immer gesetzt,
+    // weil wir Trennpositionen im Hyphenator einstellen wollen.
+    SwLineLayout *pOldCurr = pCurr;
+
+    InitCntHyph();
+
+    // 5298: IsParaLine() (ex.IsFirstLine) fragt auf GetParaPortion() ab.
+    // wir muessen gleiche Bedingungen schaffen: in der ersten
+    // Zeile formatieren wir SwParaPortions...
+    if( pOldCurr->IsParaPortion() )
+    {
+        SwParaPortion *pPara = new SwParaPortion();
+        SetParaPortion( &rInf, pPara );
+        pCurr = pPara;
+        ASSERT( IsParaLine(), "SwTxtFormatter::Hyphenate: not the first" );
+    }
+    else
+        pCurr = new SwLineLayout();
+
+    nWrdStart = FormatLine( nWrdStart );
+
+    // Man muss immer im Hinterkopf behalten, dass es z.B.
+    // Felder gibt, die aufgetrennt werden koennen ...
+    if( pCurr->PrtWidth() && pCurr->GetLen() )
+    {
+        // Wir muessen uns darauf einstellen, dass in der Zeile
+        // FlyFrms haengen, an denen auch umgebrochen werden darf.
+        // Wir suchen also die erste HyphPortion in dem angegebenen
+        // Bereich.
+
+        SwLinePortion *pPos = pCurr->GetPortion();
+        const xub_StrLen nPamStart = rHyphInf.nStart;
+        nWrdStart = nStart;
+        const xub_StrLen nEnd = rHyphInf.GetEnd();
+        while( pPos )
+        {
+            // Entweder wir liegen drueber oder wir laufen gerade auf eine
+            // Hyphportion die am Ende der Zeile oder vor einem Flys steht.
+            if( nWrdStart >= nEnd )
+            {
+                nWrdStart = 0;
+                break;
+            }
+
+            if( nWrdStart >= nPamStart && pPos->InHyphGrp()
+                && ( !pPos->IsSoftHyphPortion()
+                     || ((SwSoftHyphPortion*)pPos)->IsExpand() ) )
+            {
+                break;
+            }
+
+            nWrdStart += pPos->GetLen();
+            pPos = pPos->GetPortion();
+        }
+        // Wenn pPos 0 ist, wurde keine Trennstelle ermittelt.
+        if( !pPos )
+            nWrdStart = 0;
+    }
+
+    // Das alte LineLayout wird wieder eingestellt ...
+    delete pCurr;
+    pCurr = pOldCurr;
+
+    if( pOldCurr->IsParaPortion() )
+    {
+        SetParaPortion( &rInf, (SwParaPortion*)pOldCurr );
+        ASSERT( IsParaLine(), "SwTxtFormatter::Hyphenate: even not the first" );
+    }
+
+    if( nWrdStart )
+    {
+        // nWrdStart bezeichnet nun die Position im String, der
+        // fuer eine Trennung zur Debatte steht.
+        // Start() hangelt sich zum End()
+        rHyphInf.nWordStart = nWrdStart;
+
+        xub_StrLen nLen = 0;
+        const xub_StrLen nEnd = nWrdStart;
+
+        // Wir suchen vorwaerts
+        Reference< XHyphenatedWord > xHyphWord;
+        WordSelection::ResetWordDelimiter();
+        nWrdStart = WordSelection::GoStartWord( rInf.GetTxt(), nWrdStart );
+        nLen = WordSelection::GoEndWord( rInf.GetTxt(), nWrdStart ) - nWrdStart;
+        bRet = 0 != nLen;
+        if( bRet )
+        {
+            XubString aSelTxt( rInf.GetTxt().Copy(nWrdStart, nLen) );
+            xub_StrLen nCnt = 0;
+            for( xub_StrLen i = 0; i < nLen; ++i )
+            {
+                sal_Unicode cCh = aSelTxt.GetChar(i);
+                if( (CH_TXTATR_BREAKWORD == cCh || CH_TXTATR_INWORD == cCh )
+                     && rInf.HasHint( nWrdStart + i ) )
+                {
+                    aSelTxt.Erase( i , 1 );
+                    nCnt++;
+                    --nLen;
+                    if( i )
+                        --i;
+                }
+            }
+            {
+                MSHORT nMinTrail = 0;
+                if( nWrdStart + nLen > nEnd )
+                    nMinTrail = nWrdStart + nLen - nEnd - 1;
+
+                //!! rHyphInf.SetHyphWord( ... ) muß hier geschehen
+                xHyphWord = rInf.HyphWord( aSelTxt, nMinTrail );
+                bRet = xHyphWord.is();
+                if ( !rHyphInf.IsCheck() && sal_False == bRet )
+                    rHyphInf.SetNoLang( sal_True );
+            }
+
+            if( bRet )
+            {
+                rHyphInf.SetHyphWord( xHyphWord );
+                rHyphInf.nWordStart = nWrdStart;
+                rHyphInf.nWordLen   = nLen+nCnt;
+                rHyphInf.SetNoLang( sal_False );
+                rHyphInf.SetCheck( sal_True );
+            }
+#ifdef DEBUGGY
+            if( OPTDBG( rInf ) )
+            {
+                ASSERT( aSelTxt == aHyphWord,
+                        "!SwTxtFormatter::Hyphenate: different words, different planets" );
+                aDbstream << "Diff: \"" << aSelTxt.GetStr() << "\" != \""
+                          << aHyphWord.GetStr() << "\"" << endl;
+                ASSERT( bRet, "!SwTxtFormatter::Hyphenate: three of a perfect pair" );
+                aDbstream << "Hyphenate: ";
+            }
+#endif
+        }
+    }
+    return bRet;
+}
+
+/*************************************************************************
+ *                      SwTxtPortion::FormatHyph()
+ *************************************************************************/
+
+sal_Bool SwTxtPortion::FormatHyph( SwTxtFormatInfo &rInf )
+{
+    sal_Bool bFull = sal_False;
+    const sal_Bool bHyph = rInf.ChgHyph( sal_True );
+    if( rInf.IsHyphenate() )
+    {
+        SwTxtGuess aGuess;
+        // const KSHORT nOldWidth = rInf.Width();
+        // Fly-Situationen muessen noch behandelt werden.
+        // rInf.Width( rInf.RealWidth() );
+        bFull = IsHyphenate( rInf, aGuess );
+        // rInf.Width( nOldWidth );
+    }
+    rInf.ChgHyph( bHyph );
+#ifdef DEBUG
+    // alles schon gesehen, z.B: "Schiff{-}fahrt", SoftHyph mit der
+    // Hand eingeben, und auf einmal passt "Schiff-" ...
+//  ASSERT( bFull, "!SwTxtPortion::FormatHyph: not full" );
+#endif
+    return bFull;
+}
+
+/*************************************************************************
+ *                      lcl_AdjSoftHyph(...)
+ *************************************************************************/
+
+xub_StrLen lcl_AdjSoftHyph( SwTxtSizeInfo& rInf, const XubString aOrgTxt,
+                        const xub_StrLen nPos, const xub_StrLen nWordStart )
+{
+    xub_StrLen nNewPos = 0;
+    const xub_StrLen nEnd = Min( aOrgTxt.Len(), nPos );
+    for( xub_StrLen i = 0; i < nEnd; ++i )
+    {
+        sal_Unicode cCh = aOrgTxt.GetChar(i);
+        if( ( CH_TXTATR_BREAKWORD == cCh || CH_TXTATR_INWORD == cCh )
+            && rInf.HasHint( nWordStart + i ) )
+            ++nNewPos;
+        ++nNewPos;
+    }
+    return nNewPos;
+}
+
+/*************************************************************************
+ *                      SwTxtPortion::IsHyphenate()
+ *************************************************************************/
+
+sal_Bool SwTxtPortion::IsHyphenate( SwTxtFormatInfo &rInf, SwTxtGuess &rGuess )
+{
+    ASSERT( !pPortion, "SwTxtPortion::Hyphenate: another portion, another planet..." );
+    if( rInf.IsHyphForbud() ||
+        pPortion || // robust
+        // Mehrzeilige Felder duerfen nicht interaktiv getrennt werden.
+        ( rInf.IsInterHyph() && InFldGrp() ) )
+        return sal_False;
+
+    const sal_Bool bDoSoftHyph = rInf.IsUnderFlow() && rInf.GetSoftHyphPos();
+
+    KSHORT nWidth = bDoSoftHyph ? rInf.RealWidth() : rInf.Width();
+
+    if( nWidth <= rInf.X() )
+    {
+        // robust
+        ASSERT( !this, "+SwTxtPortion::Hyphenate: La quenta por favor." );
+        return sal_False;
+    }
+    nWidth -= rInf.X();
+
+    // Ab hier beginnt das 'alte' Hyphenate()
+
+    // Die Breite des Trennstriches muss beruecksichtigt werden, wenn fest-
+    // gestellt werden soll, ob das Wort auf die Zeile passt.
+    SwHyphPortion aHyphPor;
+    aHyphPor.SetLen( 1 );
+
+    static const void* pLastMagicNo = 0;
+//  static SwPosSize aMiniCache;
+    static KSHORT aMiniCacheH = 0, aMiniCacheW = 0;
+    const void* pTmpMagic;
+    MSHORT nFntIdx;
+    rInf.GetFont()->GetMagic( pTmpMagic, nFntIdx, rInf.GetFont()->GetActual() );
+    if( !pLastMagicNo || pLastMagicNo != pTmpMagic )
+    {
+        pLastMagicNo = pTmpMagic;
+//      aMiniCache = aHyphPor.GetTxtSize( rInf );
+        (SwPosSize&)aHyphPor = aHyphPor.GetTxtSize( rInf );
+        aMiniCacheH = aHyphPor.Height(), aMiniCacheW = aHyphPor.Width();
+    }
+//  (SwPosSize&)aHyphPor = aMiniCache;
+    else
+        aHyphPor.Height( aMiniCacheH ), aHyphPor.Width( aMiniCacheW );
+
+    aHyphPor.SetLen( 0 );
+    if( !aHyphPor.Width() )
+    {   // robust
+        ASSERT( aHyphPor.Width(), "+SwTxtPortion::Hyphenate: annorectic HyphPor" );
+        return sal_False;
+    }
+
+    // Wenn der Trennstrich breiter als der zur Verfuegung stehende Platz ist...
+    if( nWidth <= aHyphPor.Width() )
+        return sal_False;
+
+    SwTxtSizeInfo aInf( rInf );
+
+    xub_StrLen nLastChar;
+    // Wir machen uns breit und tun so, als ob wir noch passen wuerden.
+    const KSHORT nOldWidth = Width();
+    const xub_StrLen nOldLen   = GetLen();
+    if( bDoSoftHyph )
+        nLastChar = rInf.GetSoftHyphPos() + 1;
+    else
+    {
+        Width( rGuess.LeftWidth() );
+        SetLen( rGuess.RightPos() - rInf.GetIdx() + 1 );
+        nLastChar = rGuess.HyphWord()->getHyphenationPos();
+        if( !nLastChar )
+            nLastChar = rInf.GetIdx() +
+                            GetCrsrOfst( nWidth - aHyphPor.Width(), aInf );
+        else
+            nLastChar += rGuess.LeftPos() + 1;
+        Width( nOldWidth);
+        SetLen( nOldLen );
+
+        // "Hunde. XXX", LeftPos auf ".", GetWord: "Hunde"
+        // "spuerbar erweitert", LeftPos auf "r", LastChar auf " "
+        if( rInf.GetIdx() + GetLen() != nLastChar &&
+            rGuess.LeftPos() + 1 >= nLastChar )
+            return sal_False;
+    }
+
+    xub_StrLen nWordStart, nWordLen;
+    WordSelection::ResetWordDelimiter();
+    nWordStart = WordSelection::GoStartWord( rInf.GetTxt(), nLastChar );
+    nWordLen = WordSelection::GoEndWord( rInf.GetTxt(), nLastChar ) -nWordStart;
+
+    // Textabschnitte unter 2 Zeichen trennen wir nicht mehr
+    if( 2 > nWordLen )
+        return sal_False;
+
+    // Das gefundene Wort muss natuerlich im scope liegen:
+    // (kann schon mal vorkommen, dass es nicht so ist, kein ASSERT!)
+    if( rInf.GetIdx() + 2 >= nWordStart + nWordLen )
+        return sal_False;
+
+    const XubString aOrgTxt( rInf.GetTxt().Copy( nWordStart, nWordLen ) );
+    XubString aTxt( aOrgTxt );
+    xub_StrLen nDel = 0;
+
+    // Der Hyphenator kriegt nie SoftHyphs zu sehen. Den ganzen Aerger
+    // muss die TxtPortion ausbaden. Es ist ein Spiel mit dem Feuer:
+    // In dem Moment, wo Laengen in Portions eingestellt werden oder
+    // die HyphPos herausgereicht wird, muessen die SoftHyphs miteinbezogen
+    // werden.
+    for( xub_StrLen i = 0; i < nWordLen; ++i )
+    {
+        sal_Unicode cCh = aOrgTxt.GetChar(i);
+        if( ( CH_TXTATR_BREAKWORD == cCh || CH_TXTATR_INWORD == cCh )
+            && rInf.HasHint( nWordStart + i ) )
+        {
+            aTxt.Erase( i - nDel, 1 );
+            const xub_StrLen nWordPos = nWordStart + i;
+            if( nWordPos - nDel < nLastChar )
+                --nLastChar;
+            ++nDel;
+
+            // Wenn in unserem Wort ein SoftHyphen steht,
+            // dann hat das Vorrang, wir returnen sal_False,
+            // es sei denn wir sind in der interaktiven Trennung!
+            if ( rInf.IsSoftHyph( nWordPos ) && nWordPos < rInf.GetIdx()
+                 && !rInf.IsInterHyph() )
+                    return sal_False;
+        }
+    }
+
+    nWordLen -= nDel;
+    xub_StrLen nHyphPos = 0;
+
+    // MinTrail uebersteuert das Absatzattribut fuer nMinTrail.
+    // (Anzahl der Zeichen die auf die naechste Zeile muessen)
+    MSHORT nMinTrail = 0;
+    if(nWordStart + nWordLen > nLastChar)
+        nMinTrail = nWordStart + nWordLen - nLastChar;
+
+    if( bDoSoftHyph && aTxt.Len() > nMinTrail )
+    {
+        //! make softhyphens work for alternative spellings where the text length
+        //! changes eg "Schiffahrt" (old german spelling)
+        Reference< XHyphenator >  xHyph( ::GetHyphenator() );
+        DBG_ASSERT( xHyph.is(), "Hyphenator is missing");
+        if (xHyph.is())
+        {
+            xub_StrLen nHyphenationPos = aTxt.Len() - nMinTrail - 1;
+                //! subtract 1 since the UNO-interface is 0 based
+            Reference< XAlternativeSpelling >
+                    xAlt = xHyph->queryAlternativeSpelling( OUString(aTxt),
+                            SvxCreateLocale( rInf.GetFont()->GetLanguage() ),
+                            nHyphenationPos );
+            if (xAlt.is())
+            {
+                nMinTrail -= xAlt->getHyphenPos() - nHyphenationPos;
+            }
+        }
+    }
+
+    Reference< XHyphenatedWord >  xHyphWord = rGuess.HyphWord();
+            // rInf.HyphWord( aTxt, nMinTrail );
+    sal_Bool bRet = xHyphWord.is();
+    if( !bRet )
+        return sal_False;
+
+    // Die Laenge ist nicht der Index !
+    CONST sal_Bool bAlter = xHyphWord.is() &&
+                        xHyphWord->getAlternativeSpelling().is();
+
+    // Wenn kein Alternativwort gefunden wurde und ein SoftHyph
+    // gerade die zweite Runde dreht, dann wollen wir uns nicht
+    // einmischen.
+    if( IsSoftHyphPortion() )
+    {
+        // check for: bAlter => xHyphWord.is()
+        DBG_ASSERT(!bAlter || xHyphWord.is(), "NULL pointer");
+
+        if ( bAlter &&
+             rInf.GetIdx() - nWordStart - 1 == xHyphWord->getHyphenationPos() )
+            return sal_True;
+        else
+            return sal_False;
+    }
+//  nWordLen = xHyphWord->getHyphenationPos() + 1;
+    nWordLen = xHyphWord->getHyphenPos() + 1;
+
+    if( 2 > nWordLen )
+        return sal_False;
+    nHyphPos = lcl_AdjSoftHyph( rInf, aOrgTxt, nWordLen, nWordStart );
+
+    // Wir muessen mit dem schlimmsten rechnen, z.B., dass die
+    // gefundene Trennstelle vor unserer Portion liegt.
+
+    if( (nWordStart + nHyphPos) < (rInf.GetIdx() + 2) ||
+        nWordLen >= aTxt.Len() )
+        return sal_False;
+
+    SwHyphPortion *pHyphPor;
+    if( bAlter )
+    {
+        // check for: bAlter => xHyphWord.is()
+        DBG_ASSERT(!bAlter || xHyphWord.is(), "NULL pointer");
+
+        Reference< XAlternativeSpelling > xAltSpl( xHyphWord->getAlternativeSpelling() );
+        DBG_ASSERT( xAltSpl.is(), "NULL pointer" );
+
+        XubString  aAlt      = xAltSpl->getReplacement();
+        xub_StrLen nTxtStart = xAltSpl->getChangedPos();
+        xub_StrLen nTxtEnd   = xAltSpl->getChangedLength() + nTxtStart;
+
+        if( bDoSoftHyph )
+            pHyphPor = new SwSoftHyphStrPortion( aAlt );
+        else
+            pHyphPor = new SwHyphStrPortion( aAlt );
+        // pHyphPor wird auf die Laenge eingestellt, die im Original-
+        // String ersetzt werden soll.
+        nTxtStart = lcl_AdjSoftHyph( rInf, aOrgTxt, nTxtStart, nWordStart );
+        nTxtEnd   = lcl_AdjSoftHyph( rInf, aOrgTxt, nTxtEnd, nWordStart );
+        ASSERT(nTxtEnd >= nTxtStart, "SwTxtPortion::Hyphenate: time to die.");
+        const xub_StrLen nTmpLen = pHyphPor->GetLen();
+        pHyphPor->SetLen( aAlt.Len() + 1 );
+        (SwPosSize&)(*pHyphPor) = pHyphPor->GetTxtSize( rInf );
+        pHyphPor->SetLen( nTxtEnd - nTxtStart + nTmpLen );
+        nWordLen = nTxtStart;
+        if( !aAlt.Len() )  // Beim Wrapper Debuggen beobachtet: angebliche
+            ++nWordLen;    // Alternativtrennstelle ohne Unterschied zum
+                           // Originaltext ( Zukkerbackerei )
+    }
+    else
+    {
+        nWordLen = lcl_AdjSoftHyph( rInf, aOrgTxt, nWordLen, nWordStart );
+        // Vorsicht: der benutzte Ctor von SwTxtPortion verstellt nWhichPor!
+        pHyphPor = new SwHyphPortion( aHyphPor );
+        pHyphPor->SetWhichPor( POR_HYPH );
+    }
+
+    aInf.SetLen( (nWordStart + nWordLen) - rInf.GetIdx() );
+    pHyphPor->SetAscent( GetAscent() );
+    SetLen( aInf.GetLen()  );
+    CalcTxtSize( aInf );
+
+    // Die absolute Notbremse:
+    if( nWidth < Width() + pHyphPor->Width() || !GetLen() )
+    {
+        delete pHyphPor;
+        nHyphPos = rInf.GetIdx();
+        Width( nOldWidth);
+        SetLen( nOldLen );
+        return sal_False;
+    }
+    else
+    {
+        Insert( pHyphPor );
+        short nKern = rInf.GetFont()->CheckKerning();
+        if( nKern )
+            new SwKernPortion( *this, nKern );
+    }
+
+    return sal_True;
+}
+
+/*************************************************************************
+ *              virtual SwHyphPortion::GetExpTxt()
+ *************************************************************************/
+
+sal_Bool SwHyphPortion::GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const
+{
+    rTxt = '-';
+    return sal_True;
+}
+
+/*************************************************************************
+ *                 virtual SwHyphPortion::Format()
+ *************************************************************************/
+
+sal_Bool SwHyphPortion::Format( SwTxtFormatInfo &rInf )
+{
+    register const SwLinePortion *pLast = rInf.GetLast();
+    Height( pLast->Height() );
+    SetAscent( pLast->GetAscent() );
+    XubString aTxt;
+
+    if( !GetExpTxt( rInf, aTxt ) )
+        return sal_False;
+
+    PrtWidth( rInf.GetTxtSize( aTxt ).Width() );
+    const sal_Bool bFull = rInf.Width() <= rInf.X() + PrtWidth();
+    if( bFull && !rInf.IsUnderFlow() )
+        Underflow( rInf );
+
+    return bFull;
+}
+
+/*************************************************************************
+ *              virtual SwHyphStrPortion::GetExpTxt()
+ *************************************************************************/
+
+sal_Bool SwHyphStrPortion::GetExpTxt( const SwTxtSizeInfo &, XubString &rTxt ) const
+{
+    rTxt = aExpand;
+    return sal_True;
+}
+
+/*************************************************************************
+ *                      class SwSoftHyphPortion
+ *************************************************************************/
+
+SwLinePortion *SwSoftHyphPortion::Compress() { return this; }
+
+SwSoftHyphPortion::SwSoftHyphPortion() :
+    bExpand(sal_False), nViewWidth(0), nHyphWidth(0)
+{
+    SetLen(1);
+    SetWhichPor( POR_SOFTHYPH );
+}
+
+KSHORT SwSoftHyphPortion::GetViewWidth( const SwTxtSizeInfo &rInf ) const
+{
+    // Wir stehen zwar im const, aber nViewWidth sollte erst im letzten
+    // Moment errechnet werden:
+    if( !Width() && rInf.OnWin() && rInf.GetOpt().IsSoftHyph() && !IsExpand() )
+    {
+        if( !nViewWidth )
+            ((SwSoftHyphPortion*)this)->nViewWidth
+                = rInf.GetTxtSize( '-' ).Width();
+    }
+    else
+        ((SwSoftHyphPortion*)this)->nViewWidth = 0;
+    return nViewWidth;
+}
+
+/*  Faelle:
+ *  1) SoftHyph steht in der Zeile, ViewOpt aus.
+ *     -> unsichtbar, Nachbarn unveraendert
+ *  2) SoftHyph steht in der Zeile, ViewOpt an.
+ *     -> sichtbar, Nachbarn veraendert
+ *  3) SoftHyph steht am Zeilenende, ViewOpt aus/an.
+ *     -> immer sichtbar, Nachbarn unveraendert
+ */
+
+void SwSoftHyphPortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+    if( Width() )
+    {
+        rInf.DrawViewOpt( *this, POR_SOFTHYPH );
+        SwExpandPortion::Paint( rInf );
+    }
+}
+
+/*************************************************************************
+ *                 virtual SwSoftHyphPortion::Format()
+ *************************************************************************/
+
+/* Die endgueltige Breite erhalten wir im FormatEOL().
+ * In der Underflow-Phase stellen wir fest, ob ueberhaupt ein
+ * alternatives Spelling vorliegt. Wenn ja ...
+ *
+ * Fall 1: "Au-to"
+ * 1) {Au}{-}{to}, {to} passt nicht mehr => Underflow
+ * 2) {-} ruft Hyphenate => keine Alternative
+ * 3) FormatEOL() und bFull = sal_True
+ *
+ * Fall 2: "Zuc-ker"
+ * 1) {Zuc}{-}{ker}, {ker} passt nicht mehr => Underflow
+ * 2) {-} ruft Hyphenate => Alternative!
+ * 3) Underflow() und bFull = sal_True
+ * 4) {Zuc} ruft Hyphenate => {Zuk}{-}{ker}
+ */
+
+sal_Bool SwSoftHyphPortion::Format( SwTxtFormatInfo &rInf )
+{
+    sal_Bool bFull = sal_True;
+
+    // Aufstand fuer die deutsche Sondertrennung
+    if( rInf.IsUnderFlow()  )
+    {
+        if( rInf.GetSoftHyphPos() )
+            return sal_True;
+
+        const sal_Bool bHyph = rInf.ChgHyph( sal_True );
+        if( rInf.IsHyphenate() )
+        {
+            SwTxtGuess aGuess;
+
+            rInf.SetSoftHyphPos( rInf.GetIdx() );
+
+            Width(0);
+
+            // Hyphenate liefert fuer uns zurueck, ob
+            // eine alternative Trennstelle vorliegt.
+            // Wenn nicht alternativ getrennt wird,
+            // akzeptieren wir die Stelle...
+            bFull = rInf.IsInterHyph() || !IsHyphenate( rInf, aGuess );
+        }
+        rInf.ChgHyph( bHyph );
+
+        if( bFull && !rInf.IsHyphForbud() )
+        {
+            rInf.SetSoftHyphPos(0);
+            FormatEOL( rInf );
+            if ( rInf.GetFly() )
+                rInf.GetRoot()->SetMidHyph( sal_True );
+            else
+                rInf.GetRoot()->SetEndHyph( sal_True );
+        }
+        else
+        {
+            rInf.SetSoftHyphPos( rInf.GetIdx() );
+            Underflow( rInf );
+        }
+        return sal_True;
+    }
+
+    rInf.SetSoftHyphPos(0);
+    SetExpand( sal_True );
+    bFull = SwHyphPortion::Format( rInf );
+    SetExpand( sal_False );
+    if( !bFull )
+    {
+        // default-maessig besitzen wir keine Breite, aber eine Hoehe
+        nHyphWidth = Width();
+        Width(0);
+    }
+    return bFull;
+}
+
+/*************************************************************************
+ *                 virtual SwSoftHyphPortion::FormatEOL()
+ *************************************************************************/
+// Format end of Line
+
+void SwSoftHyphPortion::FormatEOL( SwTxtFormatInfo &rInf )
+{
+    if( !IsExpand() )
+    {
+        SetExpand( sal_True );
+        if( rInf.GetLast() == this )
+            rInf.SetLast( FindPrevPortion( rInf.GetRoot() ) );
+
+        // 5964: alte Werte muessen wieder zurueckgesetzt werden.
+        const KSHORT nOldX   = rInf.X();
+        const xub_StrLen nOldIdx = rInf.GetIdx();
+        rInf.X( rInf.X() - PrtWidth() );
+        rInf.SetIdx( rInf.GetIdx() - GetLen() );
+        const sal_Bool bFull = SwHyphPortion::Format( rInf );
+        nHyphWidth = Width();
+
+        // 6976: Eine truebe Sache: Wir werden erlaubterweise breiter,
+        // aber gleich wird noch ein Fly verarbeitet, der eine korrekte
+        // X-Position braucht.
+        if( bFull || !rInf.GetFly() )
+            rInf.X( nOldX );
+        else
+            rInf.X( nOldX + Width() );
+        rInf.SetIdx( nOldIdx );
+    }
+}
+
+/*************************************************************************
+ *              virtual SwSoftHyphPortion::GetExpTxt()
+ *
+ * Wir expandieren:
+ * - wenn die Sonderzeichen sichtbar sein sollen
+ * - wenn wir am Ende der Zeile stehen.
+ * - wenn wir vor einem (echten/emuliertem) Zeilenumbruch stehen
+ *************************************************************************/
+
+sal_Bool SwSoftHyphPortion::GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const
+{
+    if( IsExpand() || ( rInf.OnWin() && rInf.GetOpt().IsSoftHyph() ) ||
+        ( GetPortion() && ( GetPortion()->InFixGrp() ||
+          GetPortion()->IsDropPortion() || GetPortion()->IsLayPortion() ||
+          GetPortion()->IsParaPortion() || GetPortion()->IsBreakPortion() ) ) )
+    {
+        return SwHyphPortion::GetExpTxt( rInf, rTxt );
+    }
+    return sal_False;
+}
+
+/*************************************************************************
+ *                      SwSoftHyphStrPortion::Paint
+ *************************************************************************/
+
+void SwSoftHyphStrPortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+    // Bug oder feature?:
+    // {Zu}{k-}{ker}, {k-} wird grau statt {-}
+    rInf.DrawViewOpt( *this, POR_SOFTHYPH );
+    SwHyphStrPortion::Paint( rInf );
+}
+
+SwSoftHyphStrPortion::SwSoftHyphStrPortion( const XubString &rStr )
+    : SwHyphStrPortion( rStr )
+{
+    SetLen( 1 );
+    SetWhichPor( POR_SOFTHYPHSTR );
+}
+
+
+
diff --git a/sw/source/core/text/txtinit.cxx b/sw/source/core/text/txtinit.cxx
new file mode 100644
index 000000000000..662703443c10
--- /dev/null
+++ b/sw/source/core/text/txtinit.cxx
@@ -0,0 +1,151 @@
+/*************************************************************************
+ *
+ *  $RCSfile: txtinit.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:26 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "errhdl.hxx"
+#include "txtcfg.hxx"
+#include "swcache.hxx"
+#include "fntcache.hxx"     // pFntCache  ( SwFont/ScrFont-PrtFont Cache )
+#include "swfntcch.hxx"     // pSwFontCache  ( SwAttrSet/SwFont Cache )
+#include "txtfrm.hxx"
+#include "txtcache.hxx"
+#include "porlay.hxx"
+#include "porglue.hxx"
+#include "porexp.hxx"
+#include "porrst.hxx"
+#include "portab.hxx"
+#include "porfly.hxx"
+#include "portox.hxx"
+#include "porref.hxx"
+#include "porftn.hxx"
+#include "porhyph.hxx"
+#include "pordrop.hxx"
+#include "tempauto.hxx" // Temporaere Autokorrekturliste
+#include "blink.hxx"    // Blink-Manager
+#include "init.hxx"   // Deklarationen fuer _TextInit() und _TextFinit()
+#include "txtfly.hxx"   // SwContourCache
+#include "dbg_lay.hxx"  // Layout Debug Fileausgabe
+
+SwCache *SwTxtFrm::pTxtCache = 0;
+long SwTxtFrm::nMinPrtLine = 0;
+SwContourCache *pContourCache = 0;
+SwDropCapCache *pDropCapCache = 0;
+
+#ifndef PROFILE
+// Code zum Initialisieren von Statics im eigenen Code-Segment
+#pragma code_seg( "SWSTATICS" )
+#endif
+
+IMPL_FIXEDMEMPOOL_NEWDEL( SwTxtLine,      50,  50 )
+IMPL_FIXEDMEMPOOL_NEWDEL( SwParaPortion,  50,  50 ) //Absaetze
+IMPL_FIXEDMEMPOOL_NEWDEL( SwLineLayout,  150, 150 ) //Zeilen
+IMPL_FIXEDMEMPOOL_NEWDEL( SwHolePortion, 150, 150 ) //z.B. Blanks am Zeilenende
+IMPL_FIXEDMEMPOOL_NEWDEL( SwTxtPortion,  200, 100 ) //Attributwechsel
+
+#ifndef PROFILE
+#pragma code_seg()
+#endif
+
+/*************************************************************************
+ *                  _TextInit(), _TextFinit()
+ *************************************************************************/
+
+// Werden _nur_ in init.cxx verwendet, dort stehen extern void _TextFinit()
+// und extern void _TextInit(...)
+
+void _TextInit()
+{
+    pFntCache = new SwFntCache;
+    pSwFontCache = new SwFontCache;
+    pSpellCol = new Color( COL_LIGHTRED );
+    pWaveCol = new Color( COL_GRAY );
+
+    //Pauschale groesse 250, plus 100 pro Shell
+    SwCache *pTxtCache = new SwCache( 250, 100
+#ifndef PRODUCT
+    , "static SwTxtFrm::pTxtCache"
+#endif
+    );
+    SwTxtFrm::SetTxtCache( pTxtCache );
+    PROTOCOL_INIT
+}
+
+void _TextFinit()
+{
+    delete SwTxtFrm::GetTxtCache();
+    delete pSwFontCache;
+    delete pFntCache;
+    delete pTempAuto;
+    delete pBlink;
+    delete pSpellCol;
+    delete pWaveCol;
+    delete pContourCache;
+    SwDropPortion::DeleteDropCapCache();
+    PROTOCOL_STOP
+}
+
+
+
diff --git a/sw/source/core/text/txtio.cxx b/sw/source/core/text/txtio.cxx
new file mode 100644
index 000000000000..f1e8ef5020c7
--- /dev/null
+++ b/sw/source/core/text/txtio.cxx
@@ -0,0 +1,1134 @@
+/*************************************************************************
+ *
+ *  $RCSfile: txtio.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:26 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "viewsh.hxx"       // IsDbg()
+#include "viewopt.hxx"      // IsDbg()
+#include "txtatr.hxx"
+#include "errhdl.hxx"
+
+#ifdef PRODUCT
+#error Wer fummelt denn an den makefiles?
+#endif
+
+#include "txtcfg.hxx"
+
+#include "txtfrm.hxx"       // IsDbg()
+#include "flyfrms.hxx"
+#include "inftxt.hxx"
+#include "porexp.hxx"
+#include "porfld.hxx"
+#include "porfly.hxx"
+#include "porftn.hxx"
+#include "porglue.hxx"
+#include "porhyph.hxx"
+#include "porlay.hxx"
+#include "porlin.hxx"
+#include "porref.hxx"
+#include "porrst.hxx"
+#include "portab.hxx"
+#include "portox.hxx"
+#include "portxt.hxx"
+#include "pordrop.hxx"
+#include "ndhints.hxx"
+#include "frmsh.hxx"
+
+// So kann man die Layoutstruktur ausgeben lassen
+// #define AMA_LAYOUT
+#ifdef AMA_LAYOUT
+#include           // sprintf
+#include          // getenv()
+#include 
+#include 
+#ifndef _SVDOBJ_HXX //autogen
+#include 
+#endif
+#ifndef _DFLYOBJ_HXX //autogen
+#include 
+#endif
+
+
+void lcl_OutFollow( XubString &rTmp, const SwFrm* pFrm )
+{
+    if( pFrm->IsFlowFrm() )
+    {
+        const SwFlowFrm *pFlow = SwFlowFrm::CastFlowFrm( pFrm );
+        if( pFlow->IsFollow() || pFlow->GetFollow() )
+        {
+            rTmp += "(";
+            if( pFlow->IsFollow() )
+                rTmp += ".";
+            if( pFlow->GetFollow() )
+            {
+                MSHORT nFrmId = pFlow->GetFollow()->GetFrm()->GetFrmId();
+                rTmp += nFrmId;
+            }
+            rTmp += ")";
+        }
+    }
+}
+
+void lcl_OutFrame( SvFileStream& rStr, const SwFrm* pFrm, ByteString& rSp, sal_Bool bNxt )
+{
+    if( !pFrm )
+        return;
+    KSHORT nSpc = 0;
+    MSHORT nFrmId = pFrm->GetFrmId();
+    ByteString aTmp;
+    if( pFrm->IsLayoutFrm() )
+    {
+        if( pFrm->IsRootFrm() )
+            aTmp = "R";
+        else if( pFrm->IsPageFrm() )
+            aTmp = "P";
+        else if( pFrm->IsBodyFrm() )
+            aTmp = "B";
+        else if( pFrm->IsColumnFrm() )
+            aTmp = "C";
+        else if( pFrm->IsTabFrm() )
+            aTmp = "Tb";
+        else if( pFrm->IsRowFrm() )
+            aTmp = "Rw";
+        else if( pFrm->IsCellFrm() )
+            aTmp = "Ce";
+        else if( pFrm->IsSctFrm() )
+            aTmp = "S";
+        else if( pFrm->IsFlyFrm() )
+        {
+            aTmp = "F";
+            const SwFlyFrm *pFly = (SwFlyFrm*)pFrm;
+            if( pFly->IsFlyInCntFrm() )
+                aTmp += "in";
+            else if( pFly->IsFlyAtCntFrm() )
+            {
+                aTmp += "a";
+                if( pFly->IsAutoPos() )
+                    aTmp += "u";
+                else
+                    aTmp += "t";
+            }
+            else
+                aTmp += "l";
+        }
+        else if( pFrm->IsHeaderFrm() )
+            aTmp = "H";
+        else if( pFrm->IsFooterFrm() )
+            aTmp = "Fz";
+        else if( pFrm->IsFtnContFrm() )
+            aTmp = "Fc";
+        else if( pFrm->IsFtnFrm() )
+            aTmp = "Fn";
+        else
+            aTmp = "?L?";
+        aTmp += nFrmId;
+        lcl_OutFollow( aTmp, pFrm );
+        aTmp += " ";
+        rStr << aTmp;
+        nSpc = aTmp.Len();
+        rSp.Expand( nSpc + rSp.Len() );
+        lcl_OutFrame( rStr, ((SwLayoutFrm*)pFrm)->Lower(), rSp, sal_True );
+    }
+    else
+    {
+        if( pFrm->IsTxtFrm() )
+            aTmp = "T";
+        else if( pFrm->IsNoTxtFrm() )
+            aTmp = "N";
+        else
+            aTmp = "?C?";
+        aTmp += nFrmId;
+        lcl_OutFollow( aTmp, pFrm );
+        aTmp += " ";
+        rStr << aTmp;
+        nSpc = aTmp.Len();
+        rSp.Expand( nSpc + rSp.Len() );
+    }
+    if( pFrm->IsPageFrm() )
+    {
+        const SwPageFrm* pPg = (SwPageFrm*)pFrm;
+        const SwSortDrawObjs *pSorted = pPg->GetSortedObjs();
+        const MSHORT nCnt = pSorted ? pSorted->Count() : 0;
+        if( nCnt )
+        {
+            for( MSHORT i=0; i < nCnt; ++i )
+            {
+                SdrObject *pObj = (*pSorted)[ i ];
+                if( pObj->IsWriterFlyFrame() )
+                {
+                    SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+                    lcl_OutFrame( rStr, pFly, rSp, sal_False );
+                }
+                else
+                {
+                    aTmp = pObj->IsUnoObj() ? "UNO" : "Drw";
+                    rStr << aTmp;
+                }
+                if( i < nCnt - 1 )
+                    rStr << endl << rSp;
+            }
+        }
+    }
+    else if( pFrm->GetDrawObjs() )
+    {
+        MSHORT nCnt = pFrm->GetDrawObjs()->Count();
+        if( nCnt )
+        {
+            for( MSHORT i=0; i < nCnt; ++i )
+            {
+                SdrObject *pObj = (*pFrm->GetDrawObjs())[ i ];
+                if( pObj->IsWriterFlyFrame() )
+                {
+                    SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+                    lcl_OutFrame( rStr, pFly, rSp, sal_False );
+                }
+                else
+                {
+                    aTmp = pObj->IsUnoObj() ? "UNO" : "Drw";
+                    rStr << aTmp;
+                }
+                if( i < nCnt - 1 )
+                    rStr << endl << rSp;
+            }
+        }
+    }
+    if( nSpc )
+        rSp.Erase( rSp.Len() - nSpc );
+    if( bNxt && pFrm->GetNext() )
+    {
+        do
+        {
+            pFrm = pFrm->GetNext();
+            rStr << endl << rSp;
+            lcl_OutFrame( rStr, pFrm, rSp, sal_False );
+        } while ( pFrm->GetNext() );
+    }
+}
+
+#ifdef USED
+        IsFtnContFrm()
+        IsFtnFrm()
+#endif
+
+void LayOutPut( const SwFrm* pFrm )
+{
+#ifndef MAC
+    static char *pOutName = 0;
+    const sal_Bool bFirstOpen = pOutName ? sal_False : sal_True;
+    if( bFirstOpen )
+    {
+        char *pPath = getenv( "TEMP" );
+        char *pName = "layout.txt";
+        if( !pPath )
+            pOutName = pName;
+        else
+        {
+            const int nLen = strlen(pPath);
+            // fuer dieses new wird es kein delete geben.
+            pOutName = new char[nLen + strlen(pName) + 3];
+            if(nLen && (pPath[nLen-1] == '\\') || (pPath[nLen-1] == '/'))
+                sprintf( pOutName, "%s%s", pPath, pName );
+            else
+                sprintf( pOutName, "%s/%s", pPath, pName );
+        }
+    }
+    SvFileStream aStream( pOutName, (bFirstOpen
+                                        ? STREAM_WRITE | STREAM_TRUNC
+                                        : STREAM_WRITE ));
+
+    if( !aStream.GetError() )
+    {
+        if ( bFirstOpen )
+            aStream << "Layout-Struktur";
+        else
+            aStream.Seek( STREAM_SEEK_TO_END );
+        aStream << endl;
+        aStream << "---------------------------------------------" << endl;
+        XubString aSpace;
+        lcl_OutFrame( aStream, pFrm, aSpace, sal_False );
+    }
+#endif
+}
+
+#endif
+
+SvStream &operator<<( SvStream &rOs, const SwpHints &rHints ) //$ ostream
+{
+    rOs << " {HINTS:";
+#ifdef JP_NEWCORE
+    for( MSHORT i = 0; i < rHints.GetSize(); ++i)
+    {
+        SwTxtHint *pHint = (SwTxtHint*) rHints[i];
+
+        if(0 != GetCharWidth(pHint))
+            rOs << "CHARWIDTH" << ' '; // << GetCharWidth(pHint)->frCPI;
+        else if(0 != GetColor(pHint))
+            rOs << "COLOR" << ' ' ; // << GetColor(pHint)->aColor;
+        else if(0 != GetCrossedOut(pHint))
+            rOs << "CROSSEDOUT" << ' ' << (MSHORT)(GetCrossedOut(pHint)->nState);
+        else if(0 != GetAttrFont(pHint))
+            rOs << "ATTRFONT" << ' ' <<
+            (const char *)(GetAttrFont(pHint)->sFamilyName) << ',' <<
+            ((MSHORT) GetAttrFont(pHint)->eFamily);
+        else if(0 != GetPosture(pHint))
+            rOs << "POSTURE" << ' ' << GetPosture(pHint)->nPosture;
+        else if(0 != GetFontSize(pHint))
+            rOs << "FONTSIZE" << ' ' << GetFontSize(pHint)->nSize;
+        else if(0 != GetUnderline(pHint))
+            rOs << "UNDERLINE" << ' ' << (MSHORT)(GetUnderline(pHint)->nState);
+        else if(0 != GetWeight(pHint))
+            rOs << "WEIGHT" << ' ' << GetWeight(pHint)->nWeight;
+        else if(0 != GetContour(pHint))
+            rOs << "CONTOUR" << ' ' << GetContour(pHint)->nState;
+        else if(0 != GetShadowed(pHint))
+            rOs << "SHADOWED" << ' ' << GetShadowed(pHint)->nState;
+        else if(0 != GetAutoKern(pHint))
+            rOs << "AUTOKERN" << ' ' << GetAutoKern(pHint)->nState;
+        else if(0 != GetWordLineMode(pHint))
+            rOs << "WORDLINEMODE" << ' ' << GetWordLineMode(pHint)->nState;
+        else
+            rOs << pHint->Which();
+
+        rOs << ',' << pHint->GetStart()->GetIndex()
+                << '-'
+                << (pHint->GetEnd() ? pHint->GetEnd()->GetIndex() : STRING_LEN)
+                << "\n";
+    }
+#endif
+    // JP_NEWCORE
+
+    rOs << '}';
+    return rOs;
+}
+
+/*************************************************************************
+ *                          IsDbg()
+ *************************************************************************/
+
+sal_Bool IsDbg( const SwTxtFrm *pFrm )
+{
+    if( pFrm && pFrm->GetShell() )
+        return pFrm->GetShell()->GetViewOptions()->IsTest4();
+    else
+        return sal_False;
+}
+
+#ifndef DEBUG
+
+static void Error()
+{
+    // wegen PM und BCC
+    sal_Bool bFalse = sal_False;
+    ASSERT( bFalse, "txtio: No debug version" );
+}
+
+#define IMPL_OUTOP(class) \
+        SvStream &class::operator<<( SvStream &rOs ) const /*$ostream*/\
+        { \
+            Error(); \
+            return rOs; \
+        }
+
+IMPL_OUTOP( SwTxtPortion )
+IMPL_OUTOP( SwLinePortion )
+IMPL_OUTOP( SwBreakPortion )
+IMPL_OUTOP( SwGluePortion )
+IMPL_OUTOP( SwFldPortion )
+IMPL_OUTOP( SwHiddenPortion )
+IMPL_OUTOP( SwHyphPortion )
+IMPL_OUTOP( SwFixPortion )
+IMPL_OUTOP( SwFlyPortion )
+IMPL_OUTOP( SwFlyCntPortion )
+IMPL_OUTOP( SwMarginPortion )
+IMPL_OUTOP( SwNumberPortion )
+IMPL_OUTOP( SwBulletPortion )
+IMPL_OUTOP( SwGrfNumPortion )
+IMPL_OUTOP( SwLineLayout )
+IMPL_OUTOP( SwParaPortion )
+IMPL_OUTOP( SwFtnPortion )
+IMPL_OUTOP( SwFtnNumPortion )
+IMPL_OUTOP( SwTmpEndPortion )
+IMPL_OUTOP( SwHyphStrPortion )
+IMPL_OUTOP( SwExpandPortion )
+IMPL_OUTOP( SwBlankPortion )
+IMPL_OUTOP( SwToxPortion )
+IMPL_OUTOP( SwRefPortion )
+IMPL_OUTOP( SwIsoToxPortion )
+IMPL_OUTOP( SwIsoRefPortion )
+IMPL_OUTOP( SwSoftHyphPortion )
+IMPL_OUTOP( SwSoftHyphStrPortion )
+IMPL_OUTOP( SwTabPortion )
+IMPL_OUTOP( SwTabLeftPortion )
+IMPL_OUTOP( SwTabRightPortion )
+IMPL_OUTOP( SwTabCenterPortion )
+IMPL_OUTOP( SwTabDecimalPortion )
+IMPL_OUTOP( SwPostItsPortion )
+IMPL_OUTOP( SwQuoVadisPortion )
+IMPL_OUTOP( SwErgoSumPortion )
+IMPL_OUTOP( SwHolePortion )
+IMPL_OUTOP( SwDropPortion )
+IMPL_OUTOP( SwKernPortion )
+IMPL_OUTOP( SwArrowPortion )
+
+const char *GetPortionName( const MSHORT nType )
+{
+    return 0;
+}
+
+const char *GetPrepName( const PrepareHint ePrep )
+{
+    return 0;
+}
+
+void SwLineLayout::DebugPortions( SvStream &rOs, const XubString &rTxt, //$ ostream
+                                                const xub_StrLen nStart )
+{
+}
+
+const char *GetLangName( const MSHORT nLang )
+{
+    return 0;
+}
+
+#else
+# include 
+# include 
+# include "swtypes.hxx"      // ZTCCONST
+# include "swfont.hxx"     // SwDropPortion
+
+CONSTCHAR( pClose, "} " );
+
+/*************************************************************************
+ *                    GetPortionName()
+ *************************************************************************/
+
+CONSTCHAR( pPOR_LIN, "LIN" );
+CONSTCHAR( pPOR_TXT, "TXT" );
+CONSTCHAR( pPOR_SHADOW, "SHADOW" );
+CONSTCHAR( pPOR_TAB, "TAB" );
+CONSTCHAR( pPOR_TABLEFT, "TABLEFT" );
+CONSTCHAR( pPOR_TABRIGHT, "TABRIGHT" );
+CONSTCHAR( pPOR_TABCENTER, "TABCENTER" );
+CONSTCHAR( pPOR_TABDECIMAL, "TABDECIMAL" );
+CONSTCHAR( pPOR_EXP, "EXP" );
+CONSTCHAR( pPOR_HYPH, "HYPH" );
+CONSTCHAR( pPOR_HYPHSTR, "HYPHSTR" );
+CONSTCHAR( pPOR_FLD, "FLD" );
+CONSTCHAR( pPOR_FIX, "FIX" );
+CONSTCHAR( pPOR_FLY, "FLY" );
+CONSTCHAR( pPOR_FLYCNT, "FLYCNT" );
+CONSTCHAR( pPOR_MARGIN, "MARGIN" );
+CONSTCHAR( pPOR_GLUE, "GLUE" );
+CONSTCHAR( pPOR_HOLE, "HOLE" );
+CONSTCHAR( pPOR_END, "END" );
+CONSTCHAR( pPOR_BRK, "BRK" );
+CONSTCHAR( pPOR_LAY, "LAY" );
+CONSTCHAR( pPOR_BLANK, "BLANK" );
+CONSTCHAR( pPOR_FTN, "FTN" );
+CONSTCHAR( pPOR_FTNNUM, "FTNNUM" );
+CONSTCHAR( pPOR_POSTITS, "POSTITS" );
+CONSTCHAR( pPOR_SOFTHYPH, "SOFTHYPH" );
+CONSTCHAR( pPOR_SOFTHYPHSTR, "SOFTHYPHSTR" );
+CONSTCHAR( pPOR_TOX, "TOX" );
+CONSTCHAR( pPOR_REF, "REF" );
+
+CONSTCHAR( pPOR_ISOTOX, "ISOTOX" );
+CONSTCHAR( pPOR_ISOREF, "ISOREF" );
+CONSTCHAR( pPOR_HIDDEN, "Hidden" );
+CONSTCHAR( pPOR_QUOVADIS, "QuoVadis" );
+CONSTCHAR( pPOR_ERGOSUM, "ErgoSum" );
+CONSTCHAR( pPOR_NUMBER, "NUMBER" );
+CONSTCHAR( pPOR_BULLET, "BULLET" );
+CONSTCHAR( pPOR_UNKW, "UNKW" );
+CONSTCHAR( pPOR_PAR, "PAR" );
+
+const char *GetPortionName( const MSHORT nType )
+{
+#ifdef USED
+    // Kurz und schmerzlos:
+    const char *ppNameArr[PORTYPE_END] = {
+      pPOR_LIN, pPOR_TXT, pPOR_HOLE, pPOR_SHADOW,
+      pPOR_TAB, pPOR_TABLEFT, pPOR_TABRIGHT, pPOR_TABCENTER, pPOR_TABDECIMAL,
+      pPOR_EXP, pPOR_HYPH, pPOR_HYPHSTR, pPOR_FLD,
+      pPOR_FIX, pPOR_FLY, pPOR_FLYCNT, pPOR_MARGIN,
+      pPOR_GLUE, pPOR_END, pPOR_BRK, pPOR_LAY,
+      pPOR_BLANK, pPOR_FTN, pPOR_FTNNUM,
+      pPOR_POSTITS, pPOR_SOFTHYPH, pPOR_SOFTHYPHSTR,
+      pPOR_TOX, pPOR_REF, pPOR_ISOTOX, pPOR_ISOREF,
+      pPOR_HIDDEN, pPOR_QUOVADIS, pPOR_ERGOSUM,
+      pPOR_NUMBER, pPOR_BULLET, pPOR_UNKW, pPOR_PAR
+    };
+    ASSERT( eType < PORTYPE_END, "GetPortionName: bad type" );
+    return( ppNameArr[eType] );
+#else
+    return 0;
+#endif
+}
+
+CONSTCHAR( pPREP_CLEAR, "CLEAR" );
+CONSTCHAR( pPREP_WIDOWS_ORPHANS, "WIDOWS_ORPHANS" );
+CONSTCHAR( pPREP_FIXSIZE_CHG, "FIXSIZE_CHG" );
+CONSTCHAR( pPREP_FOLLOW_FOLLOWS, "FOLLOW_FOLLOWS" );
+CONSTCHAR( pPREP_ADJUST_FRM, "ADJUST_FRM" );
+CONSTCHAR( pPREP_FREE_SPACE, "FREE_SPACE" );
+CONSTCHAR( pPREP_FLY_CHGD, "FLY_CHGD" );
+CONSTCHAR( pPREP_FLY_ATTR_CHG, "FLY_ATTR_CHG" );
+CONSTCHAR( pPREP_FLY_ARRIVE, "FLY_ARRIVE" );
+CONSTCHAR( pPREP_FLY_LEAVE, "FLY_LEAVE" );
+CONSTCHAR( pPREP_VIEWOPT, "VIEWOPT" );
+CONSTCHAR( pPREP_FTN, "FTN" );
+CONSTCHAR( pPREP_POS_CHGD, "POS" );
+CONSTCHAR( pPREP_UL_SPACE, "UL_SPACE" );
+CONSTCHAR( pPREP_MUST_FIT, "MUST_FIT" );
+CONSTCHAR( pPREP_WIDOWS, "ORPHANS" );
+CONSTCHAR( pPREP_QUOVADIS, "QUOVADIS" );
+CONSTCHAR( pPREP_PAGE, "PAGE" );
+
+const char *GetPrepName( const PrepareHint ePrep )
+{
+    // Kurz und schmerzlos:
+    const char *ppNameArr[PREP_END] =
+    {
+        pPREP_CLEAR, pPREP_WIDOWS_ORPHANS, pPREP_FIXSIZE_CHG,
+        pPREP_FOLLOW_FOLLOWS, pPREP_ADJUST_FRM, pPREP_FREE_SPACE,
+        pPREP_FLY_CHGD, pPREP_FLY_ATTR_CHG, pPREP_FLY_ARRIVE,
+        pPREP_FLY_LEAVE, pPREP_VIEWOPT, pPREP_FTN, pPREP_POS_CHGD,
+        pPREP_UL_SPACE, pPREP_MUST_FIT, pPREP_WIDOWS, pPREP_QUOVADIS,
+        pPREP_PAGE
+    };
+    ASSERT( ePrep < PREP_END, "GetPrepName: unknown PrepareHint" );
+    return( ppNameArr[ePrep] );
+}
+
+/*************************************************************************
+ *                    SwLineLayout::DebugPortions()
+ *
+ * DebugPortion() iteriert ueber alle Portions einer Zeile und deckt die
+ * internen Strukturen auf.
+ * Im Gegensatz zum Ausgabe-Operator werden auch die Textteile ausgegeben.
+ *************************************************************************/
+
+void SwLineLayout::DebugPortions( SvStream &rOs, const XubString &rTxt, //$ ostream
+                                                const xub_StrLen nStart )
+{
+    SwLinePortion *pPortion = GetPortion();
+
+    xub_StrLen nPos = 0;
+    MSHORT nNr = 0;
+    KSHORT nPrtWidth, nLastPrt;
+    nPrtWidth = nLastPrt = 0;
+
+    SwLinePortion::operator<<( rOs );
+    rOs << '\"' << endl;
+
+    while( pPortion )
+    {
+        DBG_LOOP;
+        SwTxtPortion *pTxtPor = pPortion->InTxtGrp() ?
+                                (SwTxtPortion *)pPortion : NULL ;
+        ++nNr;
+        nLastPrt = nPrtWidth;
+        nPrtWidth += pPortion->PrtWidth();
+        rOs << "\tNr:"  << nNr
+            << " Pos:" << nPos
+            << " Org:" << nLastPrt
+            << endl;
+
+        rOs << "\t";
+        pPortion->operator<<( rOs );
+        rOs << endl;
+        nPos += pPortion->GetLen();
+        pPortion = pPortion->GetPortion();
+    }
+}
+
+#ifdef USED
+CONSTCHAR( pRES_LNG_ALBANIAN, "ALBANIAN" );
+CONSTCHAR( pRES_LNG_ARABIC, "ARABIC" );
+CONSTCHAR( pRES_LNG_AUS_ENGLISH, "AUS_ENGLISH" );
+CONSTCHAR( pRES_LNG_BAHASA, "BAHASA" );
+CONSTCHAR( pRES_LNG_BELGIAN_DUTCH, "BELGIAN_DUTCH" );
+CONSTCHAR( pRES_LNG_BELGIAN_FRENCH, "BELGIAN_FRENCH" );
+CONSTCHAR( pRES_LNG_BRAZIL_PORT, "BRAZIL_PORT" );
+CONSTCHAR( pRES_LNG_BULGARIAN, "BULGARIAN" );
+CONSTCHAR( pRES_LNG_CANADA_FRENCH, "CANADA_FRENCH" );
+CONSTCHAR( pRES_LNG_CAST_SPANISH, "CAST_SPANISH" );
+CONSTCHAR( pRES_LNG_CATALAN, "CATALAN" );
+CONSTCHAR( pRES_LNG_CROATO_SERBIAN, "CROATO_SERBIAN" );
+CONSTCHAR( pRES_LNG_CZECH, "CZECH" );
+CONSTCHAR( pRES_LNG_DANISH, "DANISH" );
+CONSTCHAR( pRES_LNG_DUTCH, "DUTCH" );
+CONSTCHAR( pRES_LNG_FINNISH, "FINNISH" );
+CONSTCHAR( pRES_LNG_FRENCH, "FRENCH" );
+CONSTCHAR( pRES_LNG_GERMAN, "GERMAN" );
+CONSTCHAR( pRES_LNG_GREEK, "GREEK" );
+CONSTCHAR( pRES_LNG_HEBREW, "HEBREW" );
+CONSTCHAR( pRES_LNG_HUNGARIAN, "HUNGARIAN" );
+CONSTCHAR( pRES_LNG_ICELANDIC, "ICELANDIC" );
+CONSTCHAR( pRES_LNG_ITALIAN, "ITALIAN" );
+CONSTCHAR( pRES_LNG_JAPANESE, "JAPANESE" );
+CONSTCHAR( pRES_LNG_KOREAN, "KOREAN" );
+CONSTCHAR( pRES_LNG_MEXICAN_SPANISH, "MEXICAN_SPANISH" );
+CONSTCHAR( pRES_LNG_NORWEG_BOKMAL, "NORWEG_BOKMAL" );
+CONSTCHAR( pRES_LNG_NORWEG_NYNORSK, "NORWEG_NYNORSK" );
+CONSTCHAR( pRES_LNG_POLISH, "POLISH" );
+CONSTCHAR( pRES_LNG_PORTUGUESE, "PORTUGUESE" );
+CONSTCHAR( pRES_LNG_RHAETO_ROMANIC, "RHAETO_ROMANIC" );
+CONSTCHAR( pRES_LNG_ROMANIAN, "ROMANIAN" );
+CONSTCHAR( pRES_LNG_RUSSIAN, "RUSSIAN" );
+CONSTCHAR( pRES_LNG_SERBO_CROATIAN, "SERBO_CROATIAN" );
+CONSTCHAR( pRES_LNG_SIM_CHINESE, "SIM_CHINESE" );
+CONSTCHAR( pRES_LNG_SLOVAKIAN, "SLOVAKIAN" );
+CONSTCHAR( pRES_LNG_SWEDISH, "SWEDISH" );
+CONSTCHAR( pRES_LNG_SWISS_FRENCH, "SWISS_FRENCH" );
+CONSTCHAR( pRES_LNG_SWISS_GERMAN, "SWISS_GERMAN" );
+CONSTCHAR( pRES_LNG_SWISS_ITALIAN, "SWISS_ITALIAN" );
+CONSTCHAR( pRES_LNG_THAI, "THAI" );
+CONSTCHAR( pRES_LNG_TRD_CHINESE, "TRD_CHINESE" );
+CONSTCHAR( pRES_LNG_TURKISH, "TURKISH" );
+CONSTCHAR( pRES_LNG_UK_ENGLISH, "UK_ENGLISH" );
+CONSTCHAR( pRES_LNG_URDU, "URDU" );
+CONSTCHAR( pRES_LNG_US_ENGLISH, "US_ENGLISH" );
+CONSTCHAR( pRES_LNG_NOLANGUAGE, "NOLANGUAGE" );
+
+const char *GetLangName( const MSHORT nLang )
+{
+    switch( nLang )
+    {
+        case 0x041c : return pRES_LNG_ALBANIAN;
+        case 0x0401 : return pRES_LNG_ARABIC;
+        case 0x0c09 : return pRES_LNG_AUS_ENGLISH;
+        case 0x0421 : return pRES_LNG_BAHASA;
+        case 0x0813 : return pRES_LNG_BELGIAN_DUTCH;
+        case 0x080c : return pRES_LNG_BELGIAN_FRENCH;
+        case 0x0416 : return pRES_LNG_BRAZIL_PORT;
+        case 0x0402 : return pRES_LNG_BULGARIAN;
+        case 0x0c0c : return pRES_LNG_CANADA_FRENCH;
+        case 0x040a : return pRES_LNG_CAST_SPANISH;
+        case 0x0403 : return pRES_LNG_CATALAN;
+        case 0x041a : return pRES_LNG_CROATO_SERBIAN;
+        case 0x0405 : return pRES_LNG_CZECH;
+        case 0x0406 : return pRES_LNG_DANISH;
+        case 0x0413 : return pRES_LNG_DUTCH;
+        case 0x040b : return pRES_LNG_FINNISH;
+        case 0x040c : return pRES_LNG_FRENCH;
+        case 0x0407 : return pRES_LNG_GERMAN;
+        case 0x0408 : return pRES_LNG_GREEK;
+        case 0x040d : return pRES_LNG_HEBREW;
+        case 0x040e : return pRES_LNG_HUNGARIAN;
+        case 0x040f : return pRES_LNG_ICELANDIC;
+        case 0x0410 : return pRES_LNG_ITALIAN;
+        case 0x0411 : return pRES_LNG_JAPANESE;
+        case 0x0412 : return pRES_LNG_KOREAN;
+        case 0x080a : return pRES_LNG_MEXICAN_SPANISH;
+        case 0x0414 : return pRES_LNG_NORWEG_BOKMAL;
+        case 0x0814 : return pRES_LNG_NORWEG_NYNORSK;
+        case 0x0415 : return pRES_LNG_POLISH;
+        case 0x0816 : return pRES_LNG_PORTUGUESE;
+        case 0x0417 : return pRES_LNG_RHAETO_ROMANIC;
+        case 0x0418 : return pRES_LNG_ROMANIAN;
+        case 0x0419 : return pRES_LNG_RUSSIAN;
+        case 0x081a : return pRES_LNG_SERBO_CROATIAN;
+        case 0x0804 : return pRES_LNG_SIM_CHINESE;
+        case 0x041b : return pRES_LNG_SLOVAKIAN;
+        case 0x041d : return pRES_LNG_SWEDISH;
+        case 0x100c : return pRES_LNG_SWISS_FRENCH;
+        case 0x0807 : return pRES_LNG_SWISS_GERMAN;
+        case 0x0810 : return pRES_LNG_SWISS_ITALIAN;
+        case 0x041e : return pRES_LNG_THAI;
+        case 0x0404 : return pRES_LNG_TRD_CHINESE;
+        case 0x041f : return pRES_LNG_TURKISH;
+        case 0x0809 : return pRES_LNG_UK_ENGLISH;
+        case 0x0420 : return pRES_LNG_URDU;
+        case 0x0409 : return pRES_LNG_US_ENGLISH;
+        default     : return pRES_LNG_NOLANGUAGE;
+    }
+}
+#else
+
+const char *GetLangName( const MSHORT nLang )
+{
+    return "???";
+}
+#endif
+
+SvStream &SwLinePortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    rOs << " {";
+    rOs <<  "L:" << nLineLength;
+    rOs << " H:" << Height();
+    rOs << " W:" << PrtWidth();
+    rOs << " A:" << nAscent;
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwTxtPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {TXT:" );
+    rOs << pTxt;
+    SwLinePortion::operator<<( rOs );
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwTmpEndPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {END:" );
+    rOs << pTxt;
+    SwLinePortion::operator<<( rOs );
+    if( PrtWidth() )
+        rOs << "(view)";
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwBreakPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {BREAK:" );
+    rOs << pTxt;
+    SwLinePortion::operator<<( rOs );
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwKernPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {KERN:" );
+    rOs << pTxt;
+    SwLinePortion::operator<<( rOs );
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwArrowPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {ARROW:" );
+    rOs << pTxt;
+    SwLinePortion::operator<<( rOs );
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwLineLayout::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {LINE:" );
+    rOs << pTxt;
+    SwLinePortion::operator<<( rOs );
+    SwLinePortion *pPos = GetPortion();
+    while( pPos )
+    {
+        DBG_LOOP;
+        rOs << "\t";
+        pPos->operator<<( rOs );
+        pPos = pPos->GetPortion();
+    }
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwGluePortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {GLUE:" );
+    rOs << pTxt;
+    SwLinePortion::operator<<( rOs );
+    rOs << " F:" << GetFixWidth();
+    rOs << " G:" << GetPrtGlue();
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwFixPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {FIX:" );
+    rOs << pTxt;
+    SwGluePortion::operator<<( rOs );
+    rOs << " Fix:" << nFix;
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwFlyPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {FLY:" );
+    rOs << pTxt;
+    SwFixPortion::operator<<( rOs );
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwMarginPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {MAR:" );
+    rOs << pTxt;
+    SwGluePortion::operator<<( rOs );
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwFlyCntPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {FLYCNT:" );
+    rOs << pTxt;
+    SwLinePortion::operator<<( rOs );
+    if( bDraw )
+    {
+        CONSTCHAR( pTxt, " {DRAWINCNT" );
+        rOs << pTxt;
+        rOs << pClose;
+    }
+    else
+    {
+        CONSTCHAR( pTxt, " {FRM:" );
+        rOs << pTxt;
+        rOs << " {FRM:" << GetFlyFrm()->Frm() << pClose;
+        rOs << " {PRT:" << GetFlyFrm()->Prt() << pClose;
+        rOs << pClose;
+    }
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwExpandPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {EXP:" );
+    rOs << pTxt;
+    SwLinePortion::operator<<( rOs );
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwFtnPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {FTN:" );
+    rOs << pTxt;
+    SwExpandPortion::operator<<( rOs );
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwFtnNumPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {FTNNUM:" );
+    rOs << pTxt;
+    SwNumberPortion::operator<<( rOs );
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwNumberPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {NUMBER:" );
+    rOs << pTxt;
+    SwExpandPortion::operator<<( rOs );
+    rOs << " Exp:\"" << '\"';
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwBulletPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {BULLET:" );
+    rOs << pTxt;
+    SwNumberPortion::operator<<( rOs );
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwGrfNumPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {GRFNUM:" );
+    rOs << pTxt;
+    SwGrfNumPortion::operator<<( rOs );
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwHiddenPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {Hidden:" );
+    rOs << pTxt;
+    SwFldPortion::operator<<( rOs );
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwToxPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {TOX:" );
+    rOs << pTxt;
+    SwTxtPortion::operator<<( rOs );
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwRefPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {Ref:" );
+    rOs << pTxt;
+    SwTxtPortion::operator<<( rOs );
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwIsoToxPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {ISOTOX:" );
+    rOs << pTxt;
+    SwToxPortion::operator<<( rOs );
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwIsoRefPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {ISOREF:" );
+    rOs << pTxt;
+    SwRefPortion::operator<<( rOs );
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwHyphPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {HYPH:" );
+    rOs << pTxt;
+    SwExpandPortion::operator<<( rOs );
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwHyphStrPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {HYPHSTR:" );
+    rOs << pTxt;
+    SwExpandPortion::operator<<( rOs );
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwSoftHyphPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {SOFTHYPH:" );
+    rOs << pTxt;
+    SwHyphPortion::operator<<( rOs );
+    rOs << (IsExpand() ? " on" : " off");
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwSoftHyphStrPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {SOFTHYPHSTR:" );
+    rOs << pTxt;
+    SwHyphStrPortion::operator<<( rOs );
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwBlankPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {BLANK:" );
+    rOs << pTxt;
+    SwExpandPortion::operator<<( rOs );
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwFldPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {FLD:" );
+    rOs << pTxt;
+    SwLinePortion::operator<<( rOs );
+    if( IsFollow() )
+        rOs << " F!";
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwPostItsPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {POSTITS" );
+    rOs << pTxt;
+    SwLinePortion::operator<<( rOs );
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwTabPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {TAB" );
+    rOs << pTxt;
+    SwFixPortion::operator<<( rOs );
+    rOs << " T:" << nTabPos;
+    if( IsFilled() )
+        rOs << " \"" << cFill << '\"';
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwTabLeftPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {TABLEFT" );
+    rOs << pTxt;
+    SwTabPortion::operator<<( rOs );
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwTabRightPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {TABRIGHT" );
+    rOs << pTxt;
+    SwTabPortion::operator<<( rOs );
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwTabCenterPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {TABCENTER" );
+    rOs << pTxt;
+    SwTabPortion::operator<<( rOs );
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwTabDecimalPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {TABDECIMAL" );
+    rOs << pTxt;
+    SwTabPortion::operator<<( rOs );
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwParaPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {PAR" );
+    rOs << pTxt;
+    SwLineLayout::operator<<( rOs );
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwHolePortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {HOLE" );
+    rOs << pTxt;
+    SwLinePortion::operator<<( rOs );
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwQuoVadisPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {QUOVADIS" );
+    rOs << pTxt;
+    SwFldPortion::operator<<( rOs );
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwErgoSumPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {ERGOSUM" );
+    rOs << pTxt;
+    SwFldPortion::operator<<( rOs );
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &operator<<( SvStream &rOs, const SwTxtSizeInfo &rInf ) //$ ostream
+{
+    CONSTCHAR( pTxt, " {SIZEINFO:" );
+    rOs << pTxt;
+    rOs << ' ' << (rInf.OnWin() ? "WIN:" : "PRT:" );
+    rOs << " Idx:" << rInf.GetIdx();
+    rOs << " Len:" << rInf.GetLen();
+    rOs << pClose;
+    return rOs;
+}
+
+SvStream &SwDropPortion::operator<<( SvStream &rOs ) const //$ ostream
+{
+    CONSTCHAR( pTxt, " {DROP:" );
+    rOs << pTxt;
+    SwTxtPortion::operator<<( rOs );
+    if( pFnt && nDropHeight )
+    {
+        rOs << " H:" << nDropHeight;
+        rOs << " L:" << nLines;
+        rOs <<" Fnt:" << pFnt->GetHeight();
+        if( nX || nY )
+            rOs << " [" << nX << '/' << nY << ']';
+    }
+    rOs << pClose;
+    return rOs;
+}
+
+#endif /* DEBUG */
+
+
diff --git a/sw/source/core/text/txtpaint.cxx b/sw/source/core/text/txtpaint.cxx
new file mode 100644
index 000000000000..1dcf5163ff21
--- /dev/null
+++ b/sw/source/core/text/txtpaint.cxx
@@ -0,0 +1,144 @@
+/*************************************************************************
+ *
+ *  $RCSfile: txtpaint.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:26 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+
+#include "txtpaint.hxx"
+#include "swrect.hxx"
+#include "rootfrm.hxx"
+
+/*************************************************************************
+ *                      SwSaveClip::_ChgClip()
+ *************************************************************************/
+
+void SwSaveClip::Reset()
+{
+    // Der alte Zustand wird wieder hergestellt.
+    if( pOut && bChg )
+    {
+        if ( pOut->GetConnectMetaFile() )
+            pOut->Pop();
+        else
+        {
+            if( bOn )
+                pOut->SetClipRegion( aClip );
+            else
+                pOut->SetClipRegion();
+        }
+        bChg = sal_False;
+    }
+}
+
+/*************************************************************************
+ *                      SwSaveClip::_ChgClip()
+ *************************************************************************/
+
+void SwSaveClip::_ChgClip( const SwRect &rRect )
+{
+    if ( !pOut || (!rRect.HasArea() && !pOut->IsClipRegion()) )
+        return;
+
+    if ( !bChg )
+    {
+        if ( pOut->GetConnectMetaFile() )
+            pOut->Push();
+        else if ( bOn )
+            aClip = pOut->GetClipRegion();
+    }
+
+    if ( !rRect.HasArea() )
+        pOut->SetClipRegion();
+    else
+    {
+        const Rectangle aRect( rRect.SVRect() );
+
+        // Wenn das ClipRect identisch ist, passiert nix.
+        if(pOut->IsClipRegion()) // kein && wg Mac
+          if (aRect == pOut->GetClipRegion().GetBoundRect())
+            return;
+
+        if( SwRootFrm::HasSameRect( rRect ) )
+            pOut->SetClipRegion();
+        else
+        {
+            const Region aClipRegion( aRect );
+            pOut->SetClipRegion( aClipRegion );
+        }
+#ifdef DEBUG
+#ifndef PRODUCT
+        static sal_Bool bDbg = sal_False;
+        if( bDbg )
+        {
+            DbgBackColor aDbg( pOut, bDbg, COL_RED );
+            pOut->DrawRect( aRect );
+        }
+#endif
+#endif
+    }
+    bChg = sal_True;
+}
+
+
diff --git a/sw/source/core/text/txtpaint.hxx b/sw/source/core/text/txtpaint.hxx
new file mode 100644
index 000000000000..9de36f88a92f
--- /dev/null
+++ b/sw/source/core/text/txtpaint.hxx
@@ -0,0 +1,259 @@
+/*************************************************************************
+ *
+ *  $RCSfile: txtpaint.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:26 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _TXTPAINT_HXX
+#define _TXTPAINT_HXX
+
+#ifndef _SV_REGION_HXX //autogen
+#include 
+#endif
+#ifndef _SV_OUTDEV_HXX //autogen
+#include 
+#endif
+
+
+class SwRect;               // SwSaveClip
+
+/*************************************************************************
+ *                      class SwSaveClip
+ *************************************************************************/
+
+class SwSaveClip
+{
+    Region   aClip;
+    const sal_Bool     bOn;
+          sal_Bool     bChg;
+protected:
+    OutputDevice *pOut;
+    void _ChgClip( const SwRect &rRect );
+public:
+    inline SwSaveClip( OutputDevice *pOut );
+    inline ~SwSaveClip();
+    inline void ChgClip( const SwRect &rRect ) { if( pOut ) _ChgClip( rRect ); }
+           void Reset();
+    inline sal_Bool IsOn()  const { return bOn; }
+    inline sal_Bool IsChg() const { return bChg; }
+    inline sal_Bool IsOut() const { return 0 != pOut; }
+    inline OutputDevice *GetOut() { return pOut; }
+};
+
+inline SwSaveClip::SwSaveClip( OutputDevice *pOut ) :
+    pOut(pOut),
+    bOn( pOut && pOut->IsClipRegion() ),
+    bChg( sal_False )
+{}
+
+inline SwSaveClip::~SwSaveClip()
+{
+    Reset();
+}
+
+#ifndef PRODUCT
+
+/*************************************************************************
+ *                          class SwDbgOut
+ *************************************************************************/
+
+class SwDbgOut
+{
+protected:
+        OutputDevice *pOut;
+public:
+        inline SwDbgOut( OutputDevice *pOutDev, const sal_Bool bOn = sal_True );
+};
+
+/*************************************************************************
+ *                          class DbgPen
+ *************************************************************************/
+
+//class DbgPen : public SwDbgOut
+//{
+//      Pen aPen;
+//public:
+//      inline DbgPen( OutputDevice *pOutDev, const sal_Bool bOn = sal_True,
+//                     const ColorName eColor = COL_BLACK );
+//      inline ~DbgPen();
+//};
+
+/*************************************************************************
+ *                          class DbgColor
+ *************************************************************************/
+
+class DbgColor
+{
+    Font *pFnt;
+    Color aColor;
+public:
+        inline DbgColor( Font *pFont, const sal_Bool bOn = sal_True,
+                         const ColorData eColor = COL_BLUE );
+        inline ~DbgColor();
+};
+
+/*************************************************************************
+ *                          class DbgBrush
+ *************************************************************************/
+
+class DbgBackColor : public SwDbgOut
+{
+        Color   aOldFillColor;
+public:
+        DbgBackColor( OutputDevice *pOut, const sal_Bool bOn = sal_True,
+                  ColorData nColor = COL_YELLOW );
+       ~DbgBackColor();
+};
+
+/*************************************************************************
+ *                          class DbgRect
+ *************************************************************************/
+
+class DbgRect : public SwDbgOut
+{
+public:
+        DbgRect( OutputDevice *pOut, const Rectangle &rRect,
+                 const sal_Bool bOn = sal_True,
+                 ColorData eColor = COL_LIGHTBLUE );
+};
+
+/*************************************************************************
+ *                      Inline-Implementierung
+ *************************************************************************/
+
+inline SwDbgOut::SwDbgOut( OutputDevice *pOutDev, const sal_Bool bOn )
+               :pOut( bOn ? pOutDev : 0 )
+{ }
+
+//inline DbgPen::DbgPen( OutputDevice *pOutDev, const sal_Bool bOn,
+//             const ColorName eColor )
+//  : SwDbgOut( pOutDev, bOn)
+//{
+//  if( pOut )
+//  {
+//      const Color aColor( eColor );
+//      Pen aTmpPen( aColor );
+//      aPen = pOut->GetPen( );
+//      pOut->SetPen( aTmpPen );
+//  }
+//}
+
+//inline DbgPen::~DbgPen()
+//{
+//  if( pOut )
+//      pOut->SetPen(aPen);
+//}
+
+inline DbgColor::DbgColor( Font *pFont, const sal_Bool bOn,
+                 const ColorData eColor )
+    :pFnt( bOn ? pFont : 0 )
+{
+    if( pFnt )
+    {
+        aColor = pFnt->GetColor();
+        pFnt->SetColor( Color( eColor ) );
+    }
+}
+
+inline DbgColor::~DbgColor()
+{
+    if( pFnt )
+        pFnt->SetColor( aColor );
+}
+
+inline DbgBackColor::DbgBackColor( OutputDevice *pOutDev, const sal_Bool bOn,
+                           ColorData eColor )
+    :SwDbgOut( pOutDev, bOn )
+{
+    if( pOut )
+    {
+        aOldFillColor = pOut->GetFillColor();
+        pOut->SetFillColor( Color(eColor) );
+    }
+}
+
+inline DbgBackColor::~DbgBackColor()
+{
+    if( pOut )
+    {
+        pOut->SetFillColor( aOldFillColor );
+    }
+}
+
+inline DbgRect::DbgRect( OutputDevice *pOutDev, const Rectangle &rRect,
+                         const sal_Bool bOn,
+                         ColorData eColor )
+    : SwDbgOut( pOutDev, bOn )
+{
+    if( pOut )
+    {
+        const Color aColor( eColor );
+        Color aLineColor = pOut->GetLineColor();
+        pOut->SetLineColor( aColor );
+        Color aFillColor = pOut->GetFillColor();
+        pOut->SetFillColor( Color(COL_TRANSPARENT) );
+        pOut->DrawRect( rRect );
+        pOut->SetLineColor( aLineColor );
+        pOut->SetFillColor( aFillColor );
+    }
+}
+
+#endif
+
+
+
+#endif
diff --git a/sw/source/core/text/txttab.cxx b/sw/source/core/text/txttab.cxx
new file mode 100644
index 000000000000..5834ff3503a0
--- /dev/null
+++ b/sw/source/core/text/txttab.cxx
@@ -0,0 +1,537 @@
+/*************************************************************************
+ *
+ *  $RCSfile: txttab.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:26 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "hintids.hxx"
+
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_TSTPITEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _FRMATR_HXX
+#include 
+#endif
+#include "viewopt.hxx"  // SwViewOptions
+#include "txtcfg.hxx"
+#include "portab.hxx"
+#include "inftxt.hxx"
+#include "itrform2.hxx"
+#include "txtfrm.hxx"
+
+
+/*************************************************************************
+ *                    SwLineInfo::GetTabStop()
+ *************************************************************************/
+
+/* Die Werte in SvxTabStop::nTabPos liegen immer relativ zum linken PrtRand
+ * vor. Tabs, die im Bereich des Erstzeileneinzugs liegen, sind also negativ.
+ * nLeft  ist der linke PrtRand
+ * nRight ist der rechte PrtRand
+ * nLinePos die aktuelle Position.
+ * Es wird der erste Tabstop returnt, der groesser ist als nLinePos.
+ */
+
+
+
+const SvxTabStop *SwLineInfo::GetTabStop( const KSHORT nLinePos,
+    const KSHORT nLeft, const KSHORT nRight ) const
+{
+    // Mit den KSHORTs aufpassen, falls nLinePos < nLeft
+    SwTwips nPos = nLinePos;
+    nPos -= nLeft;
+    for( MSHORT i = 0; i < pRuler->Count(); ++i )
+    {
+        const SvxTabStop &rTabStop = pRuler->operator[](i);
+        if( rTabStop.GetTabPos() > SwTwips(nRight) )
+        {
+            if ( i )
+                return 0;
+            else
+                return &rTabStop;
+        }
+        if( rTabStop.GetTabPos() > nPos )
+            return &rTabStop;
+    }
+    return 0;
+}
+
+/*************************************************************************
+ *                      SwTxtFormatter::NewTabPortion()
+ *************************************************************************/
+
+
+
+SwTabPortion *SwTxtFormatter::NewTabPortion( SwTxtFormatInfo &rInf ) const
+{
+    SwTabPortion *pTabPor;
+    SwTabPortion  *pLastTab = rInf.GetLastTab();
+    if( pLastTab && pLastTab->IsTabCntPortion() )
+        if( pLastTab->PostFormat( rInf ) )
+            return 0;
+
+    // Wir suchen den naechsten Tab. Wenn gerade ein rechts-Tab unterwegs
+    // ist, so koennen wir uns nicht auf rInf.X() beziehen.
+    KSHORT nTabPos = rInf.GetLastTab() ? rInf.GetLastTab()->GetTabPos() : 0;
+    if( nTabPos < rInf.X() )
+        nTabPos = rInf.X();
+
+    xub_Unicode cFill, cDec;
+    SvxTabAdjust eAdj;
+
+    KSHORT nNewTabPos;
+    {
+       /*
+        nPos ist der Offset in der Zeile.
+        Die Tabulatoren haben ihren 0-Punkt bei Frm().Left().
+        Die Zeilen beginnen ab Frm.Left() + Prt.Left().
+        In dieser Methode wird zwischen beiden Koordinatensystemen
+        konvertiert (vgl. rInf.GetTabPos).
+       */
+        const KSHORT nTabLeft = KSHORT(pFrm->Frm().Left()) +
+                     KSHORT(pFrm->GetAttrSet()->GetLRSpace().GetTxtLeft());
+                //    + KSHORT(pFrm->GetTxtNode()->GetLeftMarginWithNum( sal_True ));
+        const KSHORT nLinePos = KSHORT(GetLeftMargin());
+        const KSHORT nLineTab = nLinePos + nTabPos;
+        const KSHORT nRight = KSHORT(Right());
+        SwTwips nNextPos;
+        const SvxTabStop* pTabStop =
+            aLineInf.GetTabStop( nLineTab, nTabLeft, nRight );
+        if( pTabStop )
+        {
+            cFill = ' ' != pTabStop->GetFill() ? pTabStop->GetFill() : 0;
+            cDec = pTabStop->GetDecimal();
+            eAdj = pTabStop->GetAdjustment();
+            nNextPos = pTabStop->GetTabPos();
+        }
+        else
+        {
+            KSHORT nDefTabDist = aLineInf.GetDefTabStop();
+            if( KSHRT_MAX == nDefTabDist )
+            {
+                const SvxTabStopItem& rTab =
+                    (const SvxTabStopItem &)pFrm->GetAttrSet()->
+                    GetPool()->GetDefaultItem( RES_PARATR_TABSTOP );
+                if( rTab.Count() )
+                    nDefTabDist = (KSHORT)rTab.GetStart()->GetTabPos();
+                else
+                    nDefTabDist = SVX_TAB_DEFDIST;
+                aLineInf.SetDefTabStop( nDefTabDist );
+            }
+            SwTwips nCount = nLineTab;
+            nCount -= nTabLeft;
+            // Bei negativen Werten rundet "/" auf, "%" liefert negative Reste,
+            // bei positiven Werten rundet "/" ab, "%" liefert positvie Reste!
+            KSHORT nPlus = nCount < 0 ? 0 : 1;
+            nCount /= nDefTabDist;
+            nNextPos = ( nCount + nPlus ) * nDefTabDist ;
+            if( nNextPos + nTabLeft <= nLineTab + 50 )
+                nNextPos += nDefTabDist;
+            cFill = 0;
+            eAdj = SVX_TAB_ADJUST_LEFT;
+        }
+        long nForced = 0;
+        if( pCurr->HasForcedLeftMargin() )
+        {
+            SwLinePortion* pPor = pCurr->GetPortion();
+            while( pPor && !pPor->IsFlyPortion() )
+                pPor = pPor->GetPortion();
+            if( pPor )
+                nForced = pPor->Width();
+        }
+        if( nTabLeft + nForced > nLineTab && nNextPos > 0 )
+        {
+            eAdj = SVX_TAB_ADJUST_DEFAULT;
+            cFill = 0;
+            nNextPos = nForced;
+        }
+        nNextPos += nTabLeft;
+        nNextPos -= nLinePos;
+        ASSERT( nNextPos >= 0, "GetTabStop: Don't go back!" );
+        nNewTabPos = KSHORT(nNextPos);
+    }
+
+    switch( eAdj )
+    {
+        case SVX_TAB_ADJUST_RIGHT :
+        {
+            pTabPor = new SwTabRightPortion( nNewTabPos, cFill );
+            break;
+        }
+        case SVX_TAB_ADJUST_CENTER :
+        {
+            pTabPor = new SwTabCenterPortion( nNewTabPos, cFill );
+            break;
+        }
+        case SVX_TAB_ADJUST_DECIMAL :
+        {
+            pTabPor = new SwTabDecimalPortion( nNewTabPos, cDec, cFill );
+            break;
+        }
+        default:
+        {
+            ASSERT( SVX_TAB_ADJUST_LEFT == eAdj || SVX_TAB_ADJUST_DEFAULT == eAdj,
+                    "+SwTxtFormatter::NewTabPortion: unknown adjustment" );
+            pTabPor = new SwTabLeftPortion( nNewTabPos, cFill );
+            break;
+        }
+    }
+
+    // Vorhandensein von Tabulatoren anzeigen ... ist nicht mehr noetig
+    // pCurr->SetTabulation();
+    // Aus Sicherheitsgruenden lassen wir uns die Daten errechnen
+    // pTabPor->Height( pLast->Height() );
+    // pTabPor->SetAscent( pLast->GetAscent() );
+    return pTabPor;
+}
+
+/*************************************************************************
+ *                SwTabPortion::SwTabPortion()
+ *************************************************************************/
+
+// Die Basisklasse wird erstmal ohne alles initialisiert.
+
+
+SwTabPortion::SwTabPortion( const KSHORT nTabPos, const xub_Unicode cFill )
+    : SwFixPortion( 0, 0 ), nTabPos(nTabPos), cFill(cFill)
+{
+    nLineLength = 1;
+#ifndef PRODUCT
+    if( IsFilled() )
+    {
+        ASSERT( ' ' != cFill, "SwTabPortion::CTOR: blanks ?!" );
+    }
+#endif
+    SetWhichPor( POR_TAB );
+}
+
+/*************************************************************************
+ *                 virtual SwTabPortion::Format()
+ *************************************************************************/
+
+
+
+sal_Bool SwTabPortion::Format( SwTxtFormatInfo &rInf )
+{
+    SwTabPortion *pLastTab = rInf.GetLastTab();
+    if( pLastTab == this )
+        return PostFormat( rInf );
+    if( pLastTab )
+        pLastTab->PostFormat( rInf );
+    return PreFormat( rInf );
+}
+
+/*************************************************************************
+ *                 virtual SwTabPortion::FormatEOL()
+ *************************************************************************/
+
+
+
+void SwTabPortion::FormatEOL( SwTxtFormatInfo &rInf )
+{
+    if( rInf.GetLastTab() == this && !IsTabLeftPortion() )
+        PostFormat( rInf );
+}
+
+/*************************************************************************
+ *                    SwTabPortion::PreFormat()
+ *************************************************************************/
+
+
+
+sal_Bool SwTabPortion::PreFormat( SwTxtFormatInfo &rInf )
+{
+    ASSERT( rInf.X() <= GetTabPos(), "SwTabPortion::PreFormat: rush hour" );
+
+    // Hier lassen wir uns nieder...
+    Fix( rInf.X() );
+
+    // Die Mindestbreite eines Tabs ist immer mindestens ein Blank
+    {
+        XubString aTmp( ' ' );
+        SwTxtSizeInfo aInf( rInf, aTmp );
+        PrtWidth( aInf.GetTxtSize().Width() );
+    }
+
+    // 8532: CenterTabs, deren Blankbreite nicht mehr in die Zeile passt
+    sal_Bool bFull = rInf.Width() <= rInf.X() + PrtWidth();
+
+    if( !bFull )
+    {
+        const MSHORT nWhich = GetWhichPor();
+        switch( nWhich )
+        {
+            case POR_TABRIGHT:
+            case POR_TABDECIMAL:
+            case POR_TABCENTER:
+            {
+                if( POR_TABDECIMAL == nWhich )
+                    rInf.SetTabDecimal(
+                        ((SwTabDecimalPortion*)this)->GetTabDecimal());
+                rInf.SetLastTab( this );
+                break;
+            }
+            case POR_TABLEFT:
+            {
+                PrtWidth( GetTabPos() - rInf.X() );
+                bFull = rInf.Width() <= rInf.X() + PrtWidth();
+                break;
+            }
+            default: ASSERT( !this, "SwTabPortion::PreFormat: unknown adjustment" );
+        }
+    }
+
+    if( bFull )
+    {
+        // Wir muessen aufpassen, dass wir nicht endlos schleifen,
+        // wenn die Breite kleiner ist, als ein Blank ...
+        if( rInf.GetIdx() == rInf.GetLineStart() )
+        {
+            PrtWidth( rInf.Width() - rInf.X() );
+            SetFixWidth( PrtWidth() );
+        }
+        else
+        {
+            Height( 0 );
+            Width( 0 );
+            SetLen( 0 );
+            SetAscent( 0 );
+            SetPortion( NULL ); //?????
+        }
+        return sal_True;
+    }
+    else
+    {
+        // Ein Kunstgriff mit Effekt: Die neuen Tabportions verhalten sich nun
+        // so, wie FlyFrms, die in der Zeile stehen - inklusive Adjustment !
+        SetFixWidth( PrtWidth() );
+        return sal_False;
+    }
+}
+
+/*************************************************************************
+ *                      SwTabPortion::PostFormat()
+ *************************************************************************/
+
+
+
+sal_Bool SwTabPortion::PostFormat( SwTxtFormatInfo &rInf )
+{
+    const KSHORT nRight = Min( GetTabPos(), rInf.Width() );
+    const SwLinePortion *pPor = GetPortion();
+    KSHORT nPorWidth = 0;
+    while( pPor )
+    {
+        DBG_LOOP;
+        nPorWidth += pPor->Width();
+        pPor = pPor->GetPortion();
+    }
+
+    const MSHORT nWhich = GetWhichPor();
+    ASSERT( POR_TABLEFT != nWhich, "SwTabPortion::PostFormat: already formatted" );
+    const KSHORT nDiffWidth = nRight - Fix();
+
+    if( POR_TABCENTER == nWhich )
+    {
+        // zentrierte Tabs bereiten Probleme:
+        // Wir muessen den Anteil herausfinden, der noch auf die Zeile passt.
+        KSHORT nNewWidth = nPorWidth /2;
+        if( nNewWidth > rInf.Width() - nRight )
+            nNewWidth = nPorWidth - (rInf.Width() - nRight);
+        nPorWidth = nNewWidth;
+    }
+
+    if( nDiffWidth > nPorWidth )
+    {
+        const KSHORT nOldWidth = GetFixWidth();
+        const KSHORT nAdjDiff = nDiffWidth - nPorWidth;
+        if( nAdjDiff > GetFixWidth() )
+            PrtWidth( nAdjDiff );
+        // Nicht erschrecken: wir muessen rInf weiterschieben.
+        // Immerhin waren wir als Rechtstab bislang nur ein Blank breit.
+        // Da wir uns jetzt aufgespannt haben, muss der Differenzbetrag
+        // auf rInf.X() addiert werden !
+        rInf.X( rInf.X() + PrtWidth() - nOldWidth );
+    }
+    SetFixWidth( PrtWidth() );
+    // letzte Werte zuruecksetzen
+    rInf.SetLastTab(0);
+    if( POR_TABDECIMAL == nWhich )
+        rInf.SetTabDecimal(0);
+
+    return rInf.Width() <= rInf.X();
+}
+
+/*************************************************************************
+ *                virtual SwTabPortion::Paint()
+ *
+ * Ex: LineIter::DrawTab()
+ *************************************************************************/
+
+
+
+void SwTabPortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+#ifndef PRODUCT
+    // Wir wollen uns die Fixbreite anzeigen
+    if( rInf.OnWin() && OPTDBG( rInf ) && rInf.GetOpt().IsField() )
+    {
+        const KSHORT nWidth = PrtWidth();
+        ((SwTabPortion*)this)->PrtWidth( GetFixWidth() );
+        rInf.DrawViewOpt( *this, POR_TAB );
+        ((SwTabPortion*)this)->PrtWidth( nWidth );
+    }
+#endif
+
+    rInf.DrawBackBrush( *this );
+    // Darstellung von Sonderzeichen
+    if( rInf.OnWin() && rInf.GetOpt().IsTab() )
+    {
+        // gefuellte Tabs werden grau hinterlegt.
+        if( IsFilled() )
+            rInf.DrawViewOpt( *this, POR_TAB );
+        else
+            rInf.DrawTab( *this );
+    }
+
+    // 6842: Tabs sollen auf einmal wieder unterstrichen werden.
+    if( rInf.GetFont()->IsPaintBlank() )
+    {
+        // Tabs mit Fuellung
+        XubString aTxt( ' ' );
+        const KSHORT nCharWidth = rInf.GetTxtSize( aTxt ).Width();
+        // robust:
+        if( nCharWidth )
+        {
+            // 6864: immer mit Kerning, auch auf dem Drucker!
+            KSHORT nChar = Width() / nCharWidth;
+            rInf.DrawText( aTxt.Fill( nChar, ' ' ), *this, 0, nChar, sal_True );
+        }
+    }
+
+    // Ausgabe von Fuellzeichen
+    if( IsFilled() )
+    {
+        // Tabs mit Fuellung
+        XubString aTxt( cFill );
+        const KSHORT nCharWidth = rInf.GetTxtSize( aTxt ).Width();
+#ifdef DEBUG
+        ASSERT( nCharWidth, "!SwTabPortion::Paint: sophisticated tabchar" );
+#endif
+        // robust:
+        if( nCharWidth )
+        {
+            // 6864: immer mit Kerning, auch auf dem Drucker!
+            KSHORT nChar = Width() / nCharWidth;
+            if ( cFill == '_' )
+                ++nChar; // damit keine Luecken entstehen (Bug 13430)
+            rInf.DrawText( aTxt.Fill( nChar, cFill ), *this, 0, nChar, sal_True );
+        }
+    }
+}
+
+
+/*************************************************************************
+ *                class SwTabRightPortion
+ *************************************************************************/
+
+#ifdef OLDRECYCLE
+
+
+
+sal_Bool SwTabRightPortion::MayRecycle() const { return sal_False; }
+
+#endif
+
+/*************************************************************************
+ *                class SwTabCenterPortion
+ *************************************************************************/
+
+#ifdef OLDRECYCLE
+
+
+
+sal_Bool SwTabCenterPortion::MayRecycle() const { return sal_False; }
+
+#endif
+
+/*************************************************************************
+ *                class SwTabDecimalPortion
+ *************************************************************************/
+
+#ifdef OLDRECYCLE
+
+
+
+sal_Bool SwTabDecimalPortion::MayRecycle() const { return sal_False; }
+
+#endif
+
+
+
+
diff --git a/sw/source/core/text/widorp.cxx b/sw/source/core/text/widorp.cxx
new file mode 100644
index 000000000000..c8760ecbb2d1
--- /dev/null
+++ b/sw/source/core/text/widorp.cxx
@@ -0,0 +1,525 @@
+/*************************************************************************
+ *
+ *  $RCSfile: widorp.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:26 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "hintids.hxx"
+
+#include "frmsh.hxx"
+#include "layfrm.hxx"
+#include "ftnboss.hxx"
+#include "segmentc.hxx"
+#include "ndtxt.hxx"
+#include "paratr.hxx"
+#ifndef PRODUCT
+#include "viewsh.hxx"   // ViewShell
+#include "viewopt.hxx"  // SwViewOption
+#endif
+
+#ifndef _SVX_ORPHITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_WIDWITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_KEEPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_SPLTITEM_HXX //autogen
+#include 
+#endif
+#ifndef _FRMATR_HXX
+#include 
+#endif
+#ifndef _TXTFTN_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFTN_HXX //autogen
+#include 
+#endif
+
+#include "txtcfg.hxx"
+#include "widorp.hxx"
+#include "txtfrm.hxx"
+#include "itrtxt.hxx"
+#include "sectfrm.hxx"  //SwSectionFrm
+#include "ftnfrm.hxx"
+
+#undef WIDOWTWIPS
+
+
+/*************************************************************************
+ *                  inline IsNastyFollow()
+ *************************************************************************/
+// Ein Follow, der auf der selben Seite steht, wie sein Master ist nasty.
+inline sal_Bool IsNastyFollow( const SwTxtFrm *pFrm )
+{
+    ASSERT( !pFrm->IsFollow() || !pFrm->GetPrev() ||
+            ((const SwTxtFrm*)pFrm->GetPrev())->GetFollow() == pFrm,
+            "IsNastyFollow: Was ist denn hier los?" );
+    return  pFrm->IsFollow() && pFrm->GetPrev();
+}
+
+/*************************************************************************
+ *                  SwTxtFrmBreak::SwTxtFrmBreak()
+ *************************************************************************/
+
+SwTxtFrmBreak::SwTxtFrmBreak( SwTxtFrm *pFrm, const SwTwips nRst )
+    : pFrm(pFrm), nRstHeight(nRst),
+      nOrigin( pFrm->Frm().Top() + pFrm->Prt().Top() )
+{
+    SwSectionFrm* pSct;
+    bKeep = !pFrm->IsMoveable() || IsNastyFollow( pFrm ) ||
+            ( pFrm->IsInSct() && (pSct=pFrm->FindSctFrm())->Lower()->IsColumnFrm()
+              && !pSct->MoveAllowed( pFrm ) ) ||
+            !pFrm->GetTxtNode()->GetSwAttrSet().GetSplit().GetValue() ||
+            pFrm->GetTxtNode()->GetSwAttrSet().GetKeep().GetValue();
+    bBreak = sal_False;
+
+    if( !nRstHeight && !pFrm->IsFollow() && pFrm->IsInFtn() && pFrm->HasPara() )
+    {
+        nRstHeight = pFrm->GetFtnFrmHeight();
+        nRstHeight += pFrm->Prt().Height() - pFrm->Frm().Height();
+        if( nRstHeight < 0 )
+            nRstHeight = 0;
+    }
+}
+
+/* BP 18.6.93: Widows.
+ * Im Gegensatz zur ersten Implementierung werden die Widows nicht
+ * mehr vorausschauend berechnet, sondern erst beim Formatieren des
+ * gesplitteten Follows festgestellt. Im Master faellt die Widows-
+ * Berechnung also generell weg (nWidows wird manipuliert).
+ * Wenn der Follow feststellt, dass die Widowsregel zutrifft,
+ * verschickt er an seinen Vorgaenger ein Prepare.
+ * Ein besonderes Problem ergibt sich, wenn die Widows zuschlagen,
+ * aber im Master noch ein paar Zeilen zur Verfuegung stehen.
+ *
+ */
+
+/*************************************************************************
+ *                  SwTxtFrmBreak::IsInside()
+ *************************************************************************/
+
+/* BP(22.07.92): Berechnung von Witwen und Waisen.
+ * Die Methode liefert sal_True zurueck, wenn eine dieser Regelung zutrifft.
+ *
+ * Eine Schwierigkeit gibt es im Zusammenhang mit Widows und
+ * unterschiedlichen Formaten zwischen Master- und Folgeframes:
+ * Beispiel: Wenn die erste Spalte 3cm und die zweite 4cm breit ist
+ * und Widows auf sagen wir 3 gesetzt ist, so ist erst bei der Formatierung
+ * des Follows entscheidbar, ob die Widowsbedingung einhaltbar ist oder
+ * nicht. Leider ist davon abhaengig, ob der Absatz als Ganzes auf die
+ * naechste Seite rutscht.
+ */
+
+const sal_Bool SwTxtFrmBreak::IsInside( SwTxtMargin &rLine ) const
+{
+    register sal_Bool bFit = sal_False;
+    SwTwips nLineHeight = rLine.Y() - nOrigin + rLine.GetLineHeight();
+
+    // 7455 und 6114: Raum fuer die Umrandung unten einkalkulieren.
+    nLineHeight += pFrm->Frm().Height() - pFrm->Prt().Height()
+                   - pFrm->Prt().Top();
+
+    if( nRstHeight )
+        bFit = nRstHeight >= nLineHeight;
+    else
+    {
+        // Der Frm besitzt eine Hoehe, mit der er auf die Seite passt.
+        SwTwips nHeight = pFrm->GetUpper()->Frm().Top()
+                        + pFrm->GetUpper()->Prt().Top()
+                        + pFrm->GetUpper()->Prt().Height() - nOrigin;
+
+        // Wenn sich alles innerhalb des bestehenden Frames abspielt,
+        // ist das Ergebnis sal_True;
+        bFit = nHeight >= nLineHeight;
+        if( !bFit )
+        {
+            // Die LineHeight sprengt die aktuelle Frm-Hoehe.
+            // Nun rufen wir ein Probe-Grow, um zu ermitteln, ob der
+            // Frame um den gewuenschten Bereich wachsen wuerde.
+            nHeight += pFrm->GrowTst( LONG_MAX );
+
+            // Das Grow() returnt die Hoehe, um die der Upper des TxtFrm
+            // den TxtFrm wachsen lassen wuerde.
+            // Der TxtFrm selbst darf wachsen wie er will.
+            bFit = nHeight >= nLineHeight;
+        }
+    }
+    return bFit;
+}
+
+/*************************************************************************
+ *                  SwTxtFrmBreak::IsBreakNow()
+ *************************************************************************/
+
+sal_Bool SwTxtFrmBreak::IsBreakNow( SwTxtMargin &rLine )
+{
+    // bKeep ist staerker als IsBreakNow()
+    // Ist noch genug Platz ?
+    if( bKeep || IsInside( rLine ) )
+        bBreak = sal_False;
+    else
+    {
+        /* Diese Klasse geht davon aus, dass der SwTxtMargin von Top nach Bottom
+         * durchgearbeitet wird. Aus Performancegruenden wird in folgenden
+         * Faellen der Laden fuer das weitere Aufspalten dicht gemacht:
+         * Wenn eine einzige Zeile nicht mehr passt.
+         * Sonderfall: bei DummyPortions ist LineNr == 1, obwohl wir splitten
+         * wollen.
+         */
+        // 6010: DropLines mit einbeziehen
+
+        sal_Bool bFirstLine = 1 == rLine.GetLineNr() && !rLine.GetPrev();
+        bBreak = sal_True;
+        if( ( bFirstLine && pFrm->GetIndPrev() )
+            || ( rLine.GetLineNr() <= rLine.GetDropLines() ) )
+        {
+            bKeep = sal_True;
+            bBreak = sal_False;
+        }
+        else if(bFirstLine && pFrm->IsInFtn() && !pFrm->FindFtnFrm()->GetPrev())
+        {
+            SwLayoutFrm* pTmp = pFrm->FindFtnBossFrm()->FindBodyCont();
+            if( !pTmp || !pTmp->Lower() )
+                bBreak = sal_False;
+        }
+    }
+    return bBreak;
+}
+
+
+/*MA ehemals fuer COMPACT
+// WouldFit() liefert sal_True, wenn der Absatz ganz oder teilweise passen wuerde
+
+sal_Bool SwTxtFrmBreak::WouldFit( SwTxtMargin &rLine )
+{
+    rLine.Bottom();
+    if( IsInside( rLine ) )
+        return sal_True;
+
+    rLine.Top();
+    // Suche die erste Trennmoeglichkeit ...
+    while( !IsBreakNow( rLine ) )
+    {
+        DBG_LOOP;
+        if( !rLine.NextLine() )
+            return sal_False;
+    }
+    return sal_True;
+}
+*/
+
+/*************************************************************************
+ *                  WidowsAndOrphans::WidowsAndOrphans()
+ *************************************************************************/
+
+WidowsAndOrphans::WidowsAndOrphans( SwTxtFrm *pFrm, const SwTwips nRst,
+    sal_Bool bChkKeep   )
+    : SwTxtFrmBreak( pFrm, nRst ), nOrphLines( 0 ), nWidLines( 0 )
+{
+    if( bKeep )
+    {
+        // 5652: bei Absaetzen, die zusammengehalten werden sollen und
+        // groesser sind als die Seite wird bKeep aufgehoben.
+        if( bChkKeep && !pFrm->GetPrev() && !pFrm->IsInFtn() &&
+            pFrm->IsMoveable() &&
+            ( !pFrm->IsInSct() || pFrm->FindSctFrm()->MoveAllowed(pFrm) ) )
+            bKeep = sal_False;
+        //Auch bei gesetztem Keep muessen Orphans beachtet werden,
+        //z.B. bei verketteten Rahmen erhaelt ein Follow im letzten Rahmen ein Keep,
+        //da er nicht (vorwaerts) Moveable ist,
+        //er darf aber trotzdem vom Master Zeilen anfordern wg. der Orphanregel.
+        if( pFrm->IsFollow() )
+            nWidLines = pFrm->GetTxtNode()->GetSwAttrSet().GetWidows().GetValue();
+    }
+    else
+    {
+        const SwAttrSet& rSet = pFrm->GetTxtNode()->GetSwAttrSet();
+        const SvxOrphansItem  &rOrph = rSet.GetOrphans();
+        if ( rOrph.GetValue() > 1 )
+            nOrphLines = rOrph.GetValue();
+        if ( pFrm->IsFollow() )
+            nWidLines = rSet.GetWidows().GetValue();
+
+    }
+    if( pFrm->IsInFtn() && !pFrm->GetIndPrev() &&
+        ( bKeep || nWidLines || nOrphLines ) )
+    {
+        // Innerhalb von Fussnoten gibt es gute Gruende, das Keep-Attribut und
+        // die Widows/Orphans abzuschalten.
+        SwFtnFrm *pFtn = pFrm->FindFtnFrm();
+        sal_Bool bFt = !pFtn->GetAttr()->GetFtn().IsEndNote();
+        if( !pFtn->GetPrev() &&
+            pFtn->FindFtnBossFrm( bFt ) != pFtn->GetRef()->FindFtnBossFrm( bFt )
+            && ( !pFrm->IsInSct() || pFrm->FindSctFrm()->MoveAllowed(pFrm) ) )
+        {
+            bKeep = sal_False;
+            nOrphLines = 0;
+            nWidLines = 0;
+        }
+    }
+}
+
+/*************************************************************************
+ *                  WidowsAndOrphans::FindBreak()
+ *************************************************************************/
+
+/* Die Find*-Methoden suchen nicht nur, sondern stellen den SwTxtMargin auf
+ * die Zeile ein, wo der Absatz gebrochen werden soll und kuerzen ihn dort.
+ * FindBreak()
+ */
+
+sal_Bool WidowsAndOrphans::FindBreak( SwTxtFrm *pFrm, SwTxtMargin &rLine,
+    sal_Bool bHasToFit )
+{
+    sal_Bool bRet = sal_True;
+    MSHORT nOldOrphans = nOrphLines;
+    if( bHasToFit )
+        nOrphLines = 0;
+    rLine.Bottom();
+    if( !IsBreakNow( rLine ) )
+        bRet = sal_False;
+    if( !FindWidows( pFrm, rLine ) )
+    {
+        sal_Bool bBack = sal_False;
+        while( IsBreakNow( rLine ) )
+        {
+            if( rLine.PrevLine() )
+                bBack = sal_True;
+            else
+                break;
+        }
+        // Eigentlich werden bei HasToFit Schusterjungen (Orphans) nicht
+        // beruecksichtigt, wenn allerdings Dummy-Lines im Spiel sind und
+        // die Orphansregel verletzt wird, machen wir mal eine Ausnahme:
+        // Wir lassen einfach eine Dummyline zurueck und wandern mit dem Text
+        // komplett auf die naechste Seite/Spalte.
+        if( bHasToFit && bRet && rLine.GetLineNr() <= nOldOrphans &&
+            rLine.GetInfo().GetParaPortion()->IsDummy() )
+            rLine.Top();
+        rLine.TruncLines( sal_True );
+        bRet = bBack;
+    }
+    nOrphLines = nOldOrphans;
+    return bRet;
+}
+
+/*************************************************************************
+ *                  WidowsAndOrphans::FindWidows()
+ *************************************************************************/
+
+/*  FindWidows positioniert den SwTxtMargin des Masters auf die umzubrechende
+ *  Zeile, indem der Follow formatiert und untersucht wird.
+ *  Liefert sal_True zurueck, wenn die Widows-Regelung in Kraft tritt,
+ *  d.h. der Absatz _zusammengehalten_ werden soll !
+ */
+
+sal_Bool WidowsAndOrphans::FindWidows( SwTxtFrm *pFrm, SwTxtMargin &rLine )
+{
+    if( !nWidLines || !pFrm->IsFollow() )
+        return sal_False;
+
+    rLine.Bottom();
+
+    // Wir koennen noch was abzwacken
+    SwTxtFrm *pMaster = pFrm->FindMaster();
+    ASSERT(pMaster, "+WidowsAndOrphans::FindWidows: Widows in a master?");
+    if( !pMaster )
+        return sal_False;
+
+    // 5156: Wenn die erste Zeile des Follows nicht passt, wird der Master
+    // wohl voll mit Dummies sein. In diesem Fall waere ein PREP_WIDOWS fatal.
+    if( pMaster->GetOfst() == pFrm->GetOfst() )
+        return sal_False;
+
+    // Resthoehe des Masters
+    const SwTwips nDocPrtTop = pFrm->Frm().Top() + pFrm->Prt().Top();
+    const SwTwips nOldHeight = pFrm->Prt().SSize().Height();
+    const SwTwips nChg = rLine.Y() + rLine.GetLineHeight()
+                         - nDocPrtTop - nOldHeight;
+
+    // Unterhalb der Widows-Schwelle...
+    if( rLine.GetLineNr() >= nWidLines )
+    {
+        // 8575: Follow to Master I
+        // Wenn der Follow *waechst*, so besteht fuer den Master die Chance,
+        // Zeilen entgegenzunehmen, die er vor Kurzem gezwungen war an den
+        // Follow abzugeben: Prepare(Need); diese Abfrage unterhalb von nChg!
+        // (0W, 2O, 2M, 2F) + 1F = 3M, 2F
+        if( rLine.GetLineNr() > nWidLines && pFrm->IsJustWidow() )
+        {
+            // Wenn der Master gelockt ist, so hat er vermutlich gerade erst
+            // eine Zeile an uns abgegeben, diese geben nicht zurueck, nur
+            // weil bei uns daraus mehrere geworden sind (z.B. durch Rahmen).
+            if( !pMaster->IsLocked() &&
+                pMaster->GetRstHeight() - pMaster->Frm().Height() >=
+                SwTwips(rLine.GetInfo().GetParaPortion()->Height()) )
+            {
+                pMaster->Prepare( PREP_ADJUST_FRM );
+                pMaster->_InvalidateSize();
+                pMaster->InvalidatePage();
+            }
+            pFrm->SetJustWidow( sal_False );
+        }
+        return sal_False;
+    }
+
+    // Master to Follow
+    // Wenn der Follow nach seiner Formatierung weniger Zeilen enthaelt
+    // als Widows, so besteht noch die Chance, einige Zeilen des Masters
+    // abzuzwacken. Wenn dadurch die Orphans-Regel des Masters in Kraft
+    // tritt muss im CalcPrep() des Master-Frame der Frame so vergroessert
+    // werden, dass er nicht mehr auf seine urspruengliche Seite passt.
+    // Wenn er noch ein paar Zeilen entbehren kann, dann muss im CalcPrep()
+    // ein Shrink() erfolgen, der Follow mit dem Widows rutscht dann auf
+    // die Seite des Masters, haelt sich aber zusammen, so dass er (endlich)
+    // auf die naechste Seite rutscht. - So die Theorie!
+
+    // Wir fordern nur noch ein Zeile zur Zeit an, weil eine Zeile des Masters
+    // bei uns durchaus mehrere Zeilen ergeben koennten.
+    // Dafuer behaelt CalcFollow solange die Kontrolle, bis der Follow alle
+    // notwendigen Zeilen bekommen hat.
+    MSHORT nNeed = 1; // frueher: nWidLines - rLine.GetLineNr();
+
+    // 8575: Follow to Master II
+    // Wenn der Follow *schrumpft*, so besteht fuer den Master die Chance,
+    // den kompletten Orphan zu inhalieren.
+    // (0W, 2O, 2M, 1F) - 1F = 3M, 0F     -> PREP_ADJUST_FRM
+    // (0W, 2O, 3M, 2F) - 1F = 2M, 2F     -> PREP_WIDOWS
+
+    if( 0 > nChg && !pMaster->IsLocked() &&
+        pMaster->GetRstHeight() - pMaster->Frm().Height() >=
+        SwTwips(rLine.GetInfo().GetParaPortion()->Height()) )
+    {
+        pMaster->Prepare( PREP_ADJUST_FRM );
+        pMaster->_InvalidateSize();
+        pMaster->InvalidatePage();
+        pFrm->SetJustWidow( sal_False );
+        return sal_False;
+    }
+    pMaster->Prepare( PREP_WIDOWS, (void*)&nNeed );
+    return sal_True;
+}
+
+/*************************************************************************
+ *                  WidowsAndOrphans::WouldFit()
+ *************************************************************************/
+
+sal_Bool WidowsAndOrphans::WouldFit( SwTxtMargin &rLine, SwTwips &rMaxHeight )
+{
+    // Wir erwarten, dass rLine auf der letzten Zeile steht!!
+    ASSERT( !rLine.GetNext(), "WouldFit: aLine::Bottom missed!" );
+    MSHORT nLineCnt = rLine.GetLineNr();
+
+    // Erstmal die Orphansregel und den Initialenwunsch erfuellen ...
+#ifndef USED
+    const MSHORT nMinLines = Max( GetOrphansLines(), rLine.GetDropLines() );
+#else
+    const MSHORT nMinLines = rLine.GetDropLines();
+#endif
+    if ( nLineCnt < nMinLines )
+        return sal_False;
+
+    rLine.Top();
+    SwTwips nLineSum = rLine.GetLineHeight();
+
+    while( nMinLines > rLine.GetLineNr() )
+    {
+        DBG_LOOP;
+        if( !rLine.NextLine() )
+            return sal_False;
+        nLineSum += rLine.GetLineHeight();
+    }
+
+    // Wenn wir jetzt schon nicht mehr passen ...
+    if( !IsInside( rLine ) )
+        return sal_False;
+
+    // Jetzt noch die Widows-Regel ueberpruefen
+    if( !nWidLines && !pFrm->IsFollow() )
+    {
+        // I.A. brauchen Widows nur ueberprueft werden, wenn wir ein Follow
+        // sind. Bei WouldFit muss aber auch fuer den Master die Regel ueber-
+        // prueft werden, weil wir ja gerade erst die Trennstelle ermitteln.
+        // Im Ctor von WidowsAndOrphans wurde nWidLines aber nur fuer Follows
+        // aus dem AttrSet ermittelt, deshalb holen wir es hier nach:
+        const SwAttrSet& rSet = pFrm->GetTxtNode()->GetSwAttrSet();
+        nWidLines = rSet.GetWidows().GetValue();
+    }
+
+    // Sind nach Orphans/Initialen noch genug Zeilen fuer die Widows uebrig?
+    if( nLineCnt - nMinLines >= GetWidowsLines() )
+    {
+        if( rMaxHeight >= nLineSum )
+        {
+            rMaxHeight -= nLineSum;
+            return sal_True;
+        }
+    }
+    return sal_False;
+}
+
diff --git a/sw/source/core/text/widorp.hxx b/sw/source/core/text/widorp.hxx
new file mode 100644
index 000000000000..697acb879bda
--- /dev/null
+++ b/sw/source/core/text/widorp.hxx
@@ -0,0 +1,125 @@
+/*************************************************************************
+ *
+ *  $RCSfile: widorp.hxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:26 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _WIDORP_HXX
+#define _WIDORP_HXX
+
+class SwTxtFrm;
+
+#include "swtypes.hxx"
+#include "itrtxt.hxx"
+
+class SwTxtFrmBreak
+{
+private:
+          SwTwips  nRstHeight;
+    const SwTwips  nOrigin;
+protected:
+    SwTxtFrm *pFrm;
+    sal_Bool     bBreak;
+    sal_Bool     bKeep;
+public:
+    SwTxtFrmBreak( SwTxtFrm *pFrm, const SwTwips nRst = 0  );
+    sal_Bool IsBreakNow( SwTxtMargin &rLine );
+
+    const sal_Bool IsBroken() const     { return bBreak; }
+    const sal_Bool IsKeepAlways() const { return bKeep; }
+          void Keep()               { bKeep = sal_True; }
+          void Break()              { bKeep = sal_False; bBreak = sal_True; }
+
+    inline sal_Bool GetKeep() const { return bKeep; }
+    inline void SetKeep( const sal_Bool bNew ) { bKeep = bNew; }
+
+    const sal_Bool IsInside( SwTxtMargin &rLine ) const;
+
+    // Um Sonderfaelle mit Ftn behandeln zu koennen.
+    // Mit SetRstHeight wird dem SwTxtFrmBreak die Resthoehe eingestellt,
+    // Um TruncLines() rufen zu koennen, ohne dass IsBreakNow() einen
+    // anderen Wert zurueckliefert.
+    // Es wird dabei davon ausgegangen, dass rLine auf der letzten Zeile
+    // steht, die nicht mehr passt.
+    void    SetRstHeight( const SwTxtMargin &rLine ) { nRstHeight = rLine.Y() - nOrigin; }
+    SwTwips GetRstHeight() const { return nRstHeight; }
+};
+
+class WidowsAndOrphans : public SwTxtFrmBreak
+{
+private:
+    MSHORT   nWidLines, nOrphLines;
+
+public:
+    WidowsAndOrphans( SwTxtFrm *pFrm, const SwTwips nRst = 0,
+        sal_Bool bCheckKeep = sal_True );
+    sal_Bool FindWidows( SwTxtFrm *pFrm, SwTxtMargin &rLine );
+    const MSHORT GetWidowsLines() const
+    { return nWidLines; }
+    const MSHORT GetOrphansLines() const
+    { return nOrphLines; }
+    void ClrOrphLines(){ nOrphLines = 0; }
+
+    sal_Bool FindBreak( SwTxtFrm *pFrm, SwTxtMargin &rLine, sal_Bool bHasToFit );
+    sal_Bool WouldFit( SwTxtMargin &rLine, SwTwips &rMaxHeight );
+    sal_Bool IsBreakNow( SwTxtMargin &rLine )
+    {   return ( rLine.GetLineNr() > nOrphLines ) &&
+                 SwTxtFrmBreak::IsBreakNow( rLine ); }
+};
+
+
+#endif
diff --git a/sw/source/core/text/wrong.cxx b/sw/source/core/text/wrong.cxx
new file mode 100644
index 000000000000..f50fb57e5dfd
--- /dev/null
+++ b/sw/source/core/text/wrong.cxx
@@ -0,0 +1,370 @@
+/*************************************************************************
+ *
+ *  $RCSfile: wrong.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:26 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _STRING_HXX //autogen
+#include 
+#endif
+#include "errhdl.hxx"
+#include "swtypes.hxx"
+#include "txttypes.hxx"
+
+#include "wrong.hxx"
+
+/*************************************************************************
+ * sal_Bool SwWrongList::InWrongWord() gibt den Anfang und die Laenge des Wortes
+ * zurueck, wenn es als falsch markiert ist.
+ *************************************************************************/
+sal_Bool SwWrongList::InWrongWord( xub_StrLen &rChk, xub_StrLen &rLn ) const
+{
+    MSHORT nPos = GetPos( rChk );
+    xub_StrLen nWrPos;
+    if( nPos < Count() && ( nWrPos = WRPOS( nPos ) ) <= rChk )
+    {
+        rLn = WRLEN( nPos );
+        if( nWrPos + rLn <= rChk )
+            return sal_False;
+        rChk = nWrPos;
+        return sal_True;
+    }
+    return sal_False;
+}
+
+/*************************************************************************
+ * sal_Bool SwWrongList::Check() liefert den ersten falschen Bereich
+ *************************************************************************/
+sal_Bool SwWrongList::Check( xub_StrLen &rChk, xub_StrLen &rLn ) const
+{
+    MSHORT nPos = GetPos( rChk );
+    rLn += rChk;
+    xub_StrLen nWrPos;
+
+    if( nPos == Count() )
+        return sal_False;
+
+    xub_StrLen nEnd = WRLEN( nPos );
+    nEnd += ( nWrPos = WRPOS( nPos ) );
+    if( nEnd == rChk )
+    {
+        ++nPos;
+        if( nPos == Count() )
+            return sal_False;
+        else
+        {
+            nEnd = WRLEN( nPos );
+            nEnd += ( nWrPos = WRPOS( nPos ) );
+        }
+    }
+    if( nEnd > rChk && nWrPos < rLn )
+    {
+        if( nWrPos > rChk )
+            rChk = nWrPos;
+        if( nEnd < rLn )
+            rLn = nEnd;
+        rLn -= rChk;
+        return 0 != rLn;
+    }
+    return sal_False;
+}
+
+/*************************************************************************
+ * xub_StrLen SwWrongList::NextWrong() liefert die naechste Fehlerposition
+ *************************************************************************/
+
+xub_StrLen SwWrongList::NextWrong( xub_StrLen nChk ) const
+{
+    xub_StrLen nRet;
+    xub_StrLen nPos = GetPos( nChk );
+    if( nPos < Count() )
+    {
+        nRet = WRPOS( nPos );
+        if( nRet < nChk && nRet + WRLEN( nPos ) <= nChk )
+        {
+            if( ++nPos < Count() )
+                nRet = WRPOS( nPos );
+            else
+                nRet = STRING_LEN;
+        }
+    }
+    else
+        nRet = STRING_LEN;
+    if( nRet > GetBeginInv() && nChk < GetEndInv() )
+        nRet = nChk > GetBeginInv() ? nChk : GetBeginInv();
+    return nRet;
+}
+
+/*************************************************************************
+ * xub_StrLen SwWrongList::LastWrong() liefert die letzte Fehlerposition
+ *************************************************************************/
+
+xub_StrLen SwWrongList::LastWrong( xub_StrLen nChk ) const
+{
+    xub_StrLen nPos = GetPos( nChk );
+    xub_StrLen nRet;
+    if( nPos >= Count() || ( nRet = WRPOS( nPos ) ) >= nChk )
+        nRet = nPos ? WRPOS( --nPos ) : STRING_LEN;
+    if( nChk > GetBeginInv() && ( nRet == STRING_LEN || nRet < GetEndInv() ) )
+        nRet = nChk > GetEndInv() ? GetEndInv() : nChk;
+    return nRet;
+}
+
+/*************************************************************************
+ *                 MSHORT SwWrongList::GetPos( xub_StrLen nValue )
+ *  sucht die erste Position im Array, die groessergleich nValue ist,
+ * dies kann natuerlich auch hinter dem letzten Element sein!
+ *************************************************************************/
+
+MSHORT SwWrongList::GetPos( xub_StrLen nValue ) const
+{
+    register MSHORT nOben = Count(), nMitte, nUnten = 0;
+    if( nOben > 0 )
+    {
+        --nOben;
+        while( nUnten <= nOben )
+        {
+            nMitte = nUnten + ( nOben - nUnten ) / 2;
+            xub_StrLen nTmp = WRPOS( nMitte );
+            if( nTmp == nValue )
+                return nMitte;
+            else if( nTmp < nValue )
+            {
+                if( nTmp + WRLEN( nMitte ) >= nValue )
+                    return nMitte;
+                nUnten = nMitte + 1;
+            }
+            else if( nMitte == 0 )
+                return nUnten;
+            else
+                nOben = nMitte - 1;
+        }
+    }
+    return nUnten;
+}
+
+/*************************************************************************
+ *                 void SwWrongList::Invalidate()
+ *************************************************************************/
+
+void SwWrongList::_Invalidate( xub_StrLen nBegin, xub_StrLen nEnd )
+{
+    if ( nBegin < GetBeginInv() )
+        nBeginInvalid = nBegin;
+    if ( nEnd > GetEndInv() )
+        nEndInvalid = nEnd;
+}
+
+/*************************************************************************
+ *                      SwWrongList::Move( xub_StrLen nPos, long nDiff )
+ *  veraendert alle Positionen ab nPos um den angegebenen Wert,
+ *  wird nach Einfuegen oder Loeschen von Buchstaben benoetigt.
+ *************************************************************************/
+
+void SwWrongList::Move( xub_StrLen nPos, long nDiff )
+{
+    MSHORT i = GetPos( nPos );
+    if( nDiff < 0 )
+    {
+        xub_StrLen nEnd = nPos + xub_StrLen( -nDiff );
+        MSHORT nLst = i;
+        xub_StrLen nWrPos;
+        xub_StrLen nWrLen;
+        sal_Bool bJump = sal_False;
+        while( nLst < Count() && WRPOS( nLst ) < nEnd )
+            ++nLst;
+        if( nLst > i && ( nWrPos = WRPOS( nLst - 1 ) ) <= nPos &&
+            nWrPos + ( nWrLen = WRLEN( nLst - 1 ) ) >= nEnd )
+        {
+            nWrLen += (short)nDiff;
+            if( nWrLen )
+            {
+                GetObject( --nLst ) = nWrPos;
+                aLen.GetObject( nLst ) = nWrLen;
+                bJump = sal_True;
+            }
+        }
+        Remove( i, nLst - i );
+        aLen.Remove( i, nLst - i );
+        if ( bJump )
+            ++i;
+        if( STRING_LEN == GetBeginInv() )
+            SetInvalid( nPos ? nPos - 1 : nPos, nPos );
+        else
+        {
+            ShiftLeft( nBeginInvalid, nPos, nEnd );
+            ShiftLeft( nEndInvalid, nPos, nEnd );
+            _Invalidate( nPos ? nPos - 1 : nPos, nPos );
+        }
+    }
+    else
+    {
+        xub_StrLen nWrPos;
+        xub_StrLen nEnd = nPos + xub_StrLen( nDiff );
+        if( STRING_LEN != GetBeginInv() )
+        {
+            if( nBeginInvalid > nPos )
+                nBeginInvalid += xub_StrLen( nDiff );
+            if( nEndInvalid >= nPos )
+                nEndInvalid += xub_StrLen( nDiff );
+        }
+        // Wenn wir mitten in einem falschen Wort stehen, muss vom Wortanfang
+        // invalidiert werden.
+        if( i < Count() && nPos >= ( nWrPos = WRPOS( i ) ) )
+        {
+            Invalidate( nWrPos, nEnd );
+            xub_StrLen nWrLen = WRLEN( i ) + xub_StrLen( nDiff );
+            aLen.GetObject( i++ ) = nWrLen;
+        }
+        else
+            Invalidate( nPos, nEnd );
+    }
+    while( i < Count() )
+    {
+        xub_StrLen nTmp = nDiff + GetObject( i );
+        GetObject( i++ ) = nTmp;
+    }
+}
+
+/*************************************************************************
+ *                      SwWrongList::Clear()/( xub_StrLen nBegin, xub_StrLen nEnd )
+ *  loescht das Array im angegebenen Bereich
+ *************************************************************************/
+
+void SwWrongList::Clear()
+{
+    Remove( 0, Count() );
+    aLen.Remove( 0, aLen.Count() );
+}
+
+void SwWrongList::Clear( xub_StrLen nBegin, xub_StrLen nEnd )
+{
+    MSHORT nFirst = 0;
+    while( nFirst < Count() && WRPOS( nFirst ) < nBegin )
+        ++nFirst;
+    MSHORT i = nFirst;
+    while( i < Count() && WRPOS( i++ ) <= nEnd )
+        ;
+    Remove( nFirst, i - nFirst );
+    aLen.Remove( nFirst, i - nFirst );
+}
+
+sal_Bool SwWrongList::Fresh( xub_StrLen &rStart, xub_StrLen &rEnd, xub_StrLen nPos,
+                         xub_StrLen nLen, MSHORT nIndex, xub_StrLen nCursorPos )
+{
+    sal_Bool bRet = nCursorPos > nPos + nLen || nCursorPos < nPos;
+    xub_StrLen nWrPos;
+    xub_StrLen nWrEnd = rEnd;
+    MSHORT nCnt = nIndex;
+    if( nIndex < Count() && ( nWrPos = WRPOS( nIndex ) ) < nPos )
+    {
+        nWrEnd = nWrPos + WRLEN( nCnt++ );
+        if( rStart > nWrPos )
+            rStart = nWrPos;
+    }
+    while( nCnt < Count() && ( nWrPos = WRPOS( nCnt ) ) < nPos )
+        nWrEnd = nWrPos + WRLEN( nCnt++ );
+    if( nCnt < Count() && nWrPos == nPos && WRLEN( nCnt ) == nLen )
+    {
+        ++nCnt;
+        bRet = sal_True;
+    }
+    else
+    {
+        if( bRet )
+        {
+            if( rStart > nPos )
+                rStart = nPos;
+            nWrEnd = nPos + nLen;
+        }
+    }
+    nPos += nLen;
+    if( nCnt < Count() && ( nWrPos = WRPOS( nCnt ) ) < nPos )
+    {
+        nWrEnd = nWrPos + WRLEN( nCnt++ );
+        if( rStart > nWrPos )
+            rStart = nWrPos;
+    }
+    while( nCnt < Count() && ( nWrPos = WRPOS( nCnt ) ) < nPos )
+        nWrEnd = nWrPos + WRLEN( nCnt++ );
+    if( rEnd < nWrEnd )
+        rEnd = nWrEnd;
+    Remove( nIndex, nCnt - nIndex );
+    aLen.Remove( nIndex, nCnt - nIndex );
+    return bRet;
+}
+
+sal_Bool SwWrongList::InvalidateWrong( )
+{
+    if( Count() )
+    {
+        xub_StrLen nFirst = WRPOS( 0 );
+        xub_StrLen nLast = WRPOS( Count() - 1 ) + WRLEN( Count() - 1 );
+        Invalidate( nFirst, nLast );
+        return sal_True;
+    }
+    else
+        return sal_False;
+}
+
diff --git a/sw/source/core/tox/makefile.mk b/sw/source/core/tox/makefile.mk
new file mode 100644
index 000000000000..7ca51fd0db6b
--- /dev/null
+++ b/sw/source/core/tox/makefile.mk
@@ -0,0 +1,103 @@
+#*************************************************************************
+#
+#   $RCSfile: makefile.mk,v $
+#
+#   $Revision: 1.1.1.1 $
+#
+#   last change: $Author: hr $ $Date: 2000-09-19 00:08:26 $
+#
+#   The Contents of this file are made available subject to the terms of
+#   either of the following licenses
+#
+#          - GNU Lesser General Public License Version 2.1
+#          - Sun Industry Standards Source License Version 1.1
+#
+#   Sun Microsystems Inc., October, 2000
+#
+#   GNU Lesser General Public License Version 2.1
+#   =============================================
+#   Copyright 2000 by Sun Microsystems, Inc.
+#   901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+#   This library is free software; you can redistribute it and/or
+#   modify it under the terms of the GNU Lesser General Public
+#   License version 2.1, as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   Lesser General Public License for more details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+#   License along with this library; if not, write to the Free Software
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+#   MA  02111-1307  USA
+#
+#
+#   Sun Industry Standards Source License Version 1.1
+#   =================================================
+#   The contents of this file are subject to the Sun Industry Standards
+#   Source License Version 1.1 (the "License"); You may not use this file
+#   except in compliance with the License. You may obtain a copy of the
+#   License at http://www.openoffice.org/license.html.
+#
+#   Software provided under this License is provided on an "AS IS" basis,
+#   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+#   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+#   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+#   See the License for the specific provisions governing your rights and
+#   obligations concerning the Software.
+#
+#   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+#   Copyright: 2000 by Sun Microsystems, Inc.
+#
+#   All Rights Reserved.
+#
+#   Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sw
+TARGET=tox
+
+AUTOSEG=true
+
+PROJECTPCH=core_pch
+PDBTARGET=core_pch
+PROJECTPCHSOURCE=..$/core_1st$/core_pch
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE :  $(PRJ)$/inc$/swpre.mk
+.INCLUDE :  settings.mk
+.INCLUDE :  $(PRJ)$/inc$/sw.mk
+
+.IF "$(mydebug)" != ""
+CDEFS+=-Dmydebug
+.ENDIF
+
+.IF "$(GUI)$(COM)" == "WINMSC"
+LIBFLAGS=/NOI /NOE /PAGE:128
+.ENDIF
+
+# --- Files --------------------------------------------------------
+
+CXXFILES = \
+        tox.cxx \
+        txmsrt.cxx
+
+
+
+SLOFILES =  \
+        $(SLO)$/tox.obj \
+        $(SLO)$/txmsrt.obj
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE :  target.mk
+
diff --git a/sw/source/core/tox/tox.cxx b/sw/source/core/tox/tox.cxx
new file mode 100644
index 000000000000..74b83b564bf7
--- /dev/null
+++ b/sw/source/core/tox/tox.cxx
@@ -0,0 +1,1261 @@
+/*************************************************************************
+ *
+ *  $RCSfile: tox.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:26 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+
+#ifndef _TOOLS_RESID_HXX
+#include 
+#endif
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+#ifndef _SWTYPES_HXX
+#include 
+#endif
+#ifndef _ERRHDL_HXX
+#include 
+#endif
+#ifndef _TXTATR_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _TXTTXMRK_HXX //autogen
+#include 
+#endif
+#ifndef _TOX_HXX
+#include 
+#endif
+#ifndef _POOLFMT_HRC
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _PARATR_HXX
+#include 
+#endif
+#ifndef _SVX_TSPTITEM_HXX
+#include 
+#endif
+
+
+const sal_Char* SwForm::aFormEntry      = "";
+const sal_Char* SwForm::aFormTab        = "";
+const sal_Char* SwForm::aFormPageNums   = "<#>";
+const sal_Char* SwForm::aFormLinkStt    = "";
+const sal_Char* SwForm::aFormLinkEnd    = "";
+const sal_Char* SwForm::aFormEntryNum   = "";
+const sal_Char* SwForm::aFormEntryTxt   = "";
+const sal_Char* SwForm::aFormChapterMark= "";
+const sal_Char* SwForm::aFormText       = "";
+const sal_Char* SwForm::aFormAuth       = "";
+BYTE SwForm::nFormTabLen            = 3;
+BYTE SwForm::nFormEntryLen          = 3;
+BYTE SwForm::nFormPageNumsLen       = 3;
+BYTE SwForm::nFormLinkSttLen        = 4;
+BYTE SwForm::nFormLinkEndLen        = 4;
+BYTE SwForm::nFormEntryNumLen       = 4;
+BYTE SwForm::nFormEntryTxtLen       = 4;
+BYTE SwForm::nFormChapterMarkLen    = 3;
+BYTE SwForm::nFormTextLen           = 3;
+BYTE SwForm::nFormAuthLen           = 5;
+
+
+SV_IMPL_PTRARR(SwTOXMarks, SwTOXMark*)
+
+TYPEINIT2( SwTOXMark, SfxPoolItem, SwClient );    // fuers rtti
+
+/* -----------------23.09.99 14:09-------------------
+    includes plain text at a given position into
+     the appropriate token
+ --------------------------------------------------*/
+USHORT lcl_ConvertTextIntoPattern( String& rPattern,
+                                    xub_StrLen nStart, xub_StrLen nEnd )
+{
+    String sTmp; sTmp.AssignAscii( RTL_CONSTASCII_STRINGPARAM( " 0)
+        {
+            sRet.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ", " ));
+            lcl_ConvertTextIntoPattern(sRet, sRet.Len() - 2, sRet.Len());
+        }
+        sRet += sAuth;
+        sTmp = String::CreateFromInt32( nVals[ i ] );
+        if(sTmp.Len() < 2)
+            sTmp.Insert('0', 0);
+        sRet.Insert(sTmp, sRet.Len() - 2);
+    }
+    return sRet;
+}
+/*--------------------------------------------------------------------
+     Beschreibung:  Verzeichnis-Markierungen D/Ctor
+ --------------------------------------------------------------------*/
+
+
+    // Konstruktor fuers Default vom Attribut-Pool
+SwTOXMark::SwTOXMark()
+    : SfxPoolItem( RES_TXTATR_TOXMARK ),
+    SwClient( 0 ),
+    pTxtAttr( 0 ),
+    bAutoGenerated(FALSE),
+    bMainEntry(FALSE)
+{
+}
+
+
+SwTOXMark::SwTOXMark( const SwTOXType* pTyp )
+    : SfxPoolItem( RES_TXTATR_TOXMARK ),
+    SwClient( (SwModify*)pTyp ),
+    pTxtAttr( 0 ), nLevel( 0 ),
+    bAutoGenerated(FALSE),
+    bMainEntry(FALSE)
+{
+}
+
+
+SwTOXMark::SwTOXMark( const SwTOXMark& rCopy )
+    : SfxPoolItem( RES_TXTATR_TOXMARK ),
+    SwClient((SwModify*)rCopy.GetRegisteredIn()),
+    pTxtAttr( 0 ), nLevel( rCopy.nLevel ),
+    aPrimaryKey( rCopy.aPrimaryKey ), aSecondaryKey( rCopy.aSecondaryKey ),
+    bAutoGenerated( rCopy.bAutoGenerated),
+    bMainEntry(rCopy.bMainEntry)
+{
+    // AlternativString kopieren
+    aAltText = rCopy.aAltText;
+}
+
+
+SwTOXMark::~SwTOXMark()
+{
+}
+
+
+int SwTOXMark::operator==( const SfxPoolItem& rAttr ) const
+{
+    ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" );
+    return GetRegisteredIn() == ((SwTOXMark&)rAttr).GetRegisteredIn();
+}
+
+
+SfxPoolItem* SwTOXMark::Clone( SfxItemPool* ) const
+{
+    return new SwTOXMark( *this );
+}
+
+
+String SwTOXMark::GetText() const
+{
+    String aStr;
+    if( aAltText.Len() )
+        aStr = aAltText;
+    else if( pTxtAttr && pTxtAttr->GetpTxtNd() )
+    {
+        xub_StrLen* pEndIdx = pTxtAttr->GetEnd();
+        ASSERT( pEndIdx, "TOXMark ohne Mark!!");
+        if( pEndIdx )
+        {
+            const xub_StrLen nStt = *pTxtAttr->GetStart();
+            aStr = pTxtAttr->GetpTxtNd()->GetExpandTxt( nStt, *pEndIdx-nStt );
+        }
+    }
+    return aStr;
+}
+
+/*--------------------------------------------------------------------
+     Beschreibung: Typen von Verzeichnissen verwalten
+ --------------------------------------------------------------------*/
+
+SwTOXType::SwTOXType( TOXTypes eTyp, const String& rName )
+    : SwModify(0),
+    aName(rName),
+    eType(eTyp)
+{
+}
+
+
+SwTOXType::SwTOXType(const SwTOXType& rCopy)
+    : SwModify( (SwModify*)rCopy.GetRegisteredIn() ),
+    aName(rCopy.aName),
+    eType(rCopy.eType)
+{
+}
+
+/*--------------------------------------------------------------------
+    Beschreibung: Formen bearbeiten
+  --------------------------------------------------------------------*/
+
+
+SwForm::SwForm( USHORT nTyp )
+    : nType( nTyp ), nFormMaxLevel( SwForm::GetFormMaxLevel( nTyp )),
+//  nFirstTabPos( lNumIndent ),
+    bCommaSeparated(FALSE)
+{
+    //bHasFirstTabPos =
+    bGenerateTabPos = FALSE;
+    bIsRelTabPos = TRUE;
+
+    // Inhaltsverzeichnis hat entsprechend Anzahl Headlines + Ueberschrift
+    // Benutzer hat 10 Ebenen + Ueberschrift
+    // Stichwort hat 3 Ebenen + Ueberschrift + Trenner
+    // indexes of tables, objects illustrations and authorities consist of a heading and one level
+
+    USHORT nPoolId;
+    switch( nType )
+    {
+    case TOX_INDEX:         nPoolId = STR_POOLCOLL_TOX_IDXH;    break;
+    case TOX_USER:          nPoolId = STR_POOLCOLL_TOX_USERH;   break;
+    case TOX_CONTENT:       nPoolId = STR_POOLCOLL_TOX_CNTNTH;  break;
+    case TOX_ILLUSTRATIONS: nPoolId = STR_POOLCOLL_TOX_ILLUSH;  break;
+    case TOX_OBJECTS      : nPoolId = STR_POOLCOLL_TOX_OBJECTH; break;
+    case TOX_TABLES       : nPoolId = STR_POOLCOLL_TOX_TABLESH; break;
+    case TOX_AUTHORITIES  : nPoolId = STR_POOLCOLL_TOX_AUTHORITIESH;    break;
+    default:
+        ASSERT( !this, "ungueltiger TOXTyp");
+        return ;
+    }
+
+    String sStr;
+    {
+        ByteString sBStr;
+        if( TOX_CONTENT == nType )
+            ( sBStr = SwForm::aFormEntryNum ) += SwForm::aFormEntryTxt;
+        else
+            sBStr = SwForm::aFormEntry;
+        if( TOX_AUTHORITIES != nType)
+        {
+            sBStr += SwForm::aFormTab;
+            ByteString sTmp( RTL_CONSTASCII_STRINGPARAM( " ,65535,0," ));
+            if(TOX_CONTENT == nType)
+            {
+                //the most right tab stop is "most_right_aligned"
+                sTmp += ByteString::CreateFromInt32( SVX_TAB_ADJUST_END );
+                //and has a dot as FillChar
+                sTmp.Append( RTL_CONSTASCII_STRINGPARAM( ",." ));
+                sBStr.Insert(sTmp, sBStr.Len() - 1);
+            }
+            else
+            {
+                sTmp += ByteString::CreateFromInt32( SVX_TAB_ADJUST_LEFT );
+                //and has a space as FillChar
+                sTmp.Append( RTL_CONSTASCII_STRINGPARAM( ", " ));
+            }
+            sBStr.Insert( sTmp, sBStr.Len() - 1);
+            sBStr += SwForm::aFormPageNums;
+        }
+        sStr.AppendAscii( sBStr.GetBuffer(), sBStr.Len() );
+    }
+
+    SetTemplate( 0, SW_RESSTR( nPoolId++ ));
+
+    if(TOX_INDEX == nType)
+    {
+        for( USHORT i = 1; i < 5; ++i  )
+        {
+            if(1 == i)
+            {
+                String sTmp; sTmp.AssignAscii( SwForm::aFormEntry );
+                sTmp.Insert(' ', SwForm::nFormEntryLen - 1);
+                SetPattern( i, sTmp );
+                SetTemplate( i, SW_RESSTR( STR_POOLCOLL_TOX_IDXBREAK    ));
+            }
+            else
+            {
+                SetPattern( i, sStr );
+                SetTemplate( i, SW_RESSTR( STR_POOLCOLL_TOX_IDX1 + i - 2 ));
+            }
+        }
+    }
+    else
+        for( USHORT i = 1; i < GetFormMax(); ++i, ++nPoolId )    // Nr 0 ist der Titel
+        {
+            if(TOX_AUTHORITIES == nType)
+                SetPattern(i, lcl_GetAuthPattern(i));
+            else
+                SetPattern( i, sStr );
+
+            if( TOX_CONTENT == nType && 6 == i )
+                nPoolId = STR_POOLCOLL_TOX_CNTNT6;
+            else if( TOX_USER == nType && 6 == i )
+                nPoolId = STR_POOLCOLL_TOX_USER6;
+            else if( TOX_AUTHORITIES == nType )
+                nPoolId = STR_POOLCOLL_TOX_AUTHORITIES1;
+            SetTemplate( i, SW_RESSTR( nPoolId ) );
+        }
+}
+
+
+SwForm::SwForm(const SwForm& rForm)
+    : nType( rForm.nType )
+{
+    *this = rForm;
+}
+
+
+SwForm& SwForm::operator=(const SwForm& rForm)
+{
+    nType = rForm.nType;
+    nFormMaxLevel = rForm.nFormMaxLevel;
+//  nFirstTabPos = rForm.nFirstTabPos;
+//  bHasFirstTabPos = rForm.bHasFirstTabPos;
+    bGenerateTabPos = rForm.bGenerateTabPos;
+    bIsRelTabPos = rForm.bIsRelTabPos;
+    bCommaSeparated = rForm.bCommaSeparated;
+    for(USHORT i=0; i < nFormMaxLevel; ++i)
+    {
+        aPattern[i] = rForm.aPattern[i];
+        aTemplate[i] = rForm.aTemplate[i];
+    }
+    return *this;
+}
+
+USHORT SwForm::GetFormMaxLevel( USHORT nType )
+{
+    USHORT nRet = 0;
+    switch( nType )
+    {
+        case TOX_INDEX:         nRet = 5;                   break;
+        case TOX_USER:          nRet = MAXLEVEL+1;          break;
+        case TOX_CONTENT:       nRet = MAXLEVEL+1;          break;
+        case TOX_ILLUSTRATIONS:
+        case TOX_OBJECTS      :
+        case TOX_TABLES       : nRet = 2; break;
+        case TOX_AUTHORITIES  : nRet = AUTH_TYPE_END + 1;       break;
+    }
+    return nRet;
+}
+/* -----------------15.06.99 13:39-------------------
+    compatibilty methods: Version 5.0 and 5.1 need
+    a value for the first tab stop
+ --------------------------------------------------*/
+USHORT lcl_GetPatternCount( const String& rPattern, const sal_Char* pToken )
+{
+    USHORT nRet = 0;
+    String aSearch; aSearch.AssignAscii( pToken );
+    aSearch.Erase( aSearch.Len() - 1, 1 );
+    xub_StrLen nFound = rPattern.Search( aSearch );
+    while( STRING_NOTFOUND != nFound )
+        if( STRING_NOTFOUND != ( nFound = rPattern.Search( '>', nFound ) ))
+        {
+            ++nRet;
+            nFound = rPattern.Search( aSearch, nFound );
+        }
+    return nRet;
+}
+
+String lcl_GetPattern( const String& rPattern, const sal_Char* pToken )
+{
+    String sRet;
+    String aSearch; aSearch.AssignAscii( pToken );
+    aSearch.Erase( aSearch.Len() - 1, 1 );
+
+    xub_StrLen nEnd, nFound = rPattern.Search( aSearch );
+    if( STRING_NOTFOUND != nFound &&
+        STRING_NOTFOUND != ( nEnd = rPattern.Search( '>', nFound )) )
+        sRet = rPattern.Copy( nFound, nEnd - nFound + 1 );
+    return sRet;
+}
+
+USHORT SwForm::GetFirstTabPos() const   //{ return nFirstTabPos; }
+{
+    DBG_WARNING("compatibility")
+    String sFirstLevelPattern = aPattern[ 1 ];
+    USHORT nRet = 0;
+    if( 2 <= ::lcl_GetPatternCount( sFirstLevelPattern, SwForm::aFormTab ))
+    {
+        //sTab is in the Form "" where value is the tab position an may be empty
+        String sTab = lcl_GetPattern( sFirstLevelPattern, SwForm::aFormTab );
+        if( 3 <= sTab.GetTokenCount(',') )
+        {
+            sTab = sTab.GetToken( 2, ',');
+            sTab.Erase( sTab.Len() - 1, 1 );
+            nRet = sTab.ToInt32();
+        }
+    }
+    return nRet;
+}
+void SwForm::SetFirstTabPos( USHORT n )     //{ nFirstTabPos = n; }
+{
+    // the tab stop token looks like:   
+    //for loading only: all levels get a first tab stop at the given position
+    String sVal( String::CreateFromInt32(  n ));
+    String sTmp; sTmp.AssignAscii( SwForm::aFormTab );
+    sTmp.Insert(sVal, 2);
+
+    for(USHORT i = 0; i < MAXLEVEL; i++)
+    {
+        //if two tabstops then exchange
+        String& rPattern = aPattern[ i + 1];
+        if( 2 <= lcl_GetPatternCount( rPattern, SwForm::aFormTab ))
+        {
+            //change existing tab
+            xub_StrLen nStart = rPattern.SearchAscii( "', nStart );
+            String sTmp( rPattern.Copy( nStart, nEnd - nStart + 1 ));
+            rPattern.Erase( nStart, nEnd - nStart + 1 );
+
+            // if TabAlign is set
+            String sTabAlign;
+            if(sTmp.GetTokenCount(',') >= 4)
+            {
+                sTabAlign = sTmp.GetToken(3, ',');
+                sTabAlign.Erase(sTabAlign.Len() - 1, 1);
+            }
+            String sTabFillChar;
+            if(sTmp.GetTokenCount(',') >= 5)
+            {
+                sTabFillChar = sTmp.GetToken(4, ',');
+                sTabFillChar.Erase(sTabAlign.Len() - 1, 1);
+            }
+            sTmp.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "');
+            String sTmp;
+            sTmp.AssignAscii( SwForm::aFormTab );
+            sTmp.InsertAscii( " ,,", nFormTabLen - 1);
+            sTmp.Insert( sVal, nFormTabLen + 2 );
+            rPattern.Insert( sTmp, nIndex + 1 );
+        }
+    }
+}
+/* -----------------------------28.02.00 09:48--------------------------------
+    if the templates contain settings of the tab positions (<5.1) then
+    they must be imported into the pattern
+ ---------------------------------------------------------------------------*/
+BOOL lcl_FindTabToken( const String& rPattern, xub_StrLen nSearchFrom,
+                    xub_StrLen& rFoundStart, xub_StrLen& rFoundEnd)
+{
+    // search for 
+    // special handling of 
+
+    BOOL bRet = FALSE;
+    String sToFind; sToFind.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "', nFoundPos +1);
+            bRet = TRUE;
+            break;
+        }
+        nFoundPos = rPattern.Search( sToFind, nSearchFrom );
+    }
+    return bRet;
+}
+//-----------------------------------------------------------------------------
+void SwForm::AdjustTabStops(SwDoc& rDoc)
+{
+    for(USHORT nLevel = 1; nLevel < GetFormMax(); nLevel++)
+    {
+        const String& sTemplateName = GetTemplate(nLevel);
+
+        SwTxtFmtColl* pColl = rDoc.FindTxtFmtCollByName( sTemplateName );
+        if( !pColl )
+        {
+            USHORT nId = rDoc.GetPoolId( sTemplateName, GET_POOLID_TXTCOLL );
+            if( USHRT_MAX != nId )
+                pColl = rDoc.GetTxtCollFromPool( nId );
+        }
+        if( pColl )
+        {
+            const SvxTabStopItem& rTabStops = pColl->GetTabStops( FALSE );
+            USHORT nTabCount = rTabStops.Count();
+            String sCurrentPattern = GetPattern(nLevel);
+            xub_StrLen nLastTabFoundEndPos = 0;
+            BOOL bChanged = FALSE;
+            for(USHORT nTab = 0; nTab < nTabCount; nTab++)
+            {
+                bChanged = TRUE;
+                const SvxTabStop& rTab = rTabStops[nTab];
+                xub_StrLen nStart, nEnd;
+                if( ::lcl_FindTabToken( sCurrentPattern, nLastTabFoundEndPos,
+                                        nStart, nEnd ))
+                {
+                    sCurrentPattern.Erase( nStart, nEnd - nStart + 1 );
+                    // should look like: T ,,12345,2,_
+                    long nPosition = rTab.GetTabPos();
+                    USHORT eAlign =  rTab.GetAdjustment();
+                    sal_Unicode cFillChar = rTab.GetFill();
+                    //create new token
+                    String sNewToken;
+                    sNewToken.AssignAscii( RTL_CONSTASCII_STRINGPARAM("') == rSource.GetTokenCount('<'),
+                "count of '<' and '>' not identical")
+//  simple task - convert tokens
+//   -> 
+//   -> 
+//   -> 
+//  <#> -> <# >
+//   -> 
+//   -> 
+//   -> 
+    for( xub_StrLen nFound = 0;
+        STRING_NOTFOUND != ( nFound = sRet.Search( '>', nFound )); )
+    {
+        sRet.Insert( ' ', nFound );
+        nFound += 2;                    // skip over the blank and '>'
+    }
+
+    //more complicated: convert text between >TEXT< to 
+    xub_StrLen nOpenStart = 0;
+    xub_StrLen nCloseStart = 0;
+    xub_StrLen nClosePos = sRet.Search('>', nCloseStart);
+    xub_StrLen nOpenPos = sRet.Search('<', nOpenStart);
+    if(nOpenPos != STRING_NOTFOUND && nOpenPos > 0)
+    {
+        USHORT nOffset = lcl_ConvertTextIntoPattern( sRet, 0, nOpenPos);
+        nCloseStart += nOffset;
+        nClosePos += nOffset;
+        nOpenStart = nClosePos;
+    }
+    else
+        nOpenStart = nClosePos;
+    nOpenPos = sRet.Search('<', ++nOpenStart);
+    while(nOpenPos != STRING_NOTFOUND)
+    {
+        if(nClosePos < nOpenPos - 1)
+        {
+            USHORT nOffset = lcl_ConvertTextIntoPattern(sRet, nClosePos + 1, nOpenPos);
+            nOpenStart += nOffset;
+            nCloseStart = nOpenStart;
+        }
+        else
+        {
+            nCloseStart = nClosePos;
+            nOpenStart = nOpenPos;
+        }
+        nClosePos = sRet.Search('>', ++nCloseStart);
+        nOpenPos = sRet.Search('<', ++nOpenStart);
+    }
+    //is there any text at the end?
+    if(nClosePos != STRING_NOTFOUND && nClosePos < sRet.Len() - 1)
+        lcl_ConvertTextIntoPattern(sRet, nClosePos + 1, sRet.Len());
+    if(eType != TOX_INDEX)
+    {
+        // set most left tab stop to right alignment and FillChar == '.'
+        String sTabSearch;
+        sTabSearch.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "GetTOXTypes().GetPos( pType ))
+    {
+        // type not in pDoc, so create it now
+        const SwTOXTypes& rTypes = pDoc->GetTOXTypes();
+        BOOL bFound = FALSE;
+        for( USHORT n = rTypes.Count(); n; )
+        {
+            const SwTOXType* pCmp = rTypes[ --n ];
+            if( pCmp->GetType() == pType->GetType() &&
+                pCmp->GetTypeName() == pType->GetTypeName() )
+            {
+                pType = (SwTOXType*)pCmp;
+                bFound = TRUE;
+                break;
+            }
+        }
+
+        if( !bFound )
+            pType = (SwTOXType*)pDoc->InsertTOXType( *pType );
+    }
+    pType->Add( this );
+
+    nCreateType = rSource.nCreateType;
+    aTitle      = rSource.aTitle;
+    aForm       = rSource.aForm;
+    bProtected  = rSource.bProtected;
+    bFromChapter = rSource.bFromChapter;
+    bFromObjectNames = rSource.bFromObjectNames;
+    sMainEntryCharStyle = rSource.sMainEntryCharStyle;
+    sSequenceName = rSource.sSequenceName;
+    eCaptionDisplay = rSource.eCaptionDisplay;
+    nOLEOptions = rSource.nOLEOptions;
+
+    for( USHORT i = 0; i < MAXLEVEL; ++i )
+        aStyleNames[i] = rSource.aStyleNames[i];
+
+    // its the same data type!
+    aData.nOptions =  rSource.aData.nOptions;
+
+    if( !pDoc || pDoc->IsCopyIsMove() )
+        aName = rSource.GetTOXName();
+    else
+        aName = pDoc->GetUniqueTOXBaseName( *pType, &rSource.GetTOXName() );
+
+    return *this;
+}
+
+/* -----------------30.06.99 14:46-------------------
+    Check if any style names are set in the array
+ --------------------------------------------------*/
+BOOL    SwTOXBase::HasAnyStyleNames() const
+{
+    for(USHORT i = 0; i < MAXLEVEL; i++)
+        if(aStyleNames[i].Len())
+            return TRUE;
+    return FALSE;
+}
+
+/*--------------------------------------------------------------------
+     Beschreibung: Verzeichnisspezifische Funktionen
+ --------------------------------------------------------------------*/
+
+SwTOXBase::~SwTOXBase()
+{
+//    if( GetTOXType()->GetType() == TOX_USER  )
+//        delete aData.pTemplateName;
+}
+
+/* -----------------16.07.99 16:02-------------------
+
+ --------------------------------------------------*/
+SwFormTokenEnumerator::SwFormTokenEnumerator( const String& rPattern )
+    : sPattern( rPattern ), nCurPatternPos( 0  ), nCurPatternLen( 0 )
+{
+#ifdef DBG_UTIL
+    DBG_ASSERT( !sPattern.Len() ||
+                (sPattern.GetChar(0) == '<' &&
+                sPattern.GetChar(sPattern.Len() - 1) == '>'),
+                "Pattern incorrect!" )
+
+
+    // strip all characters included in TOX_STYLE_DELIMITER
+    String sTmp( sPattern );
+    xub_StrLen nFoundStt = sTmp.Search(TOX_STYLE_DELIMITER);
+    while(nFoundStt != STRING_NOTFOUND)
+    {
+        xub_StrLen nFoundEnd = sTmp.Search(TOX_STYLE_DELIMITER, nFoundStt + 1);
+        DBG_ASSERT(STRING_NOTFOUND != nFoundEnd, "Pattern incorrect")
+        sTmp.Erase(nFoundStt, nFoundEnd - nFoundStt + 1);
+        nFoundStt = sTmp.Search(TOX_STYLE_DELIMITER);
+    }
+    DBG_ASSERT( sTmp.GetTokenCount('<') == sTmp.GetTokenCount('>'),
+                            "Pattern incorrect!")
+#endif
+}
+
+/* -----------------29.06.99 11:55-------------------
+
+ --------------------------------------------------*/
+SwFormToken SwFormTokenEnumerator::GetNextToken()
+{
+    xub_StrLen nTokenLen, nEnd;
+    nCurPatternPos += nCurPatternLen;
+    FormTokenType eTokenType = _SearchNextToken( nCurPatternPos, nEnd,
+                                                &nTokenLen );
+    nCurPatternLen = nEnd - nCurPatternPos;
+    return BuildToken( eTokenType, nTokenLen );
+}
+
+SwFormToken SwFormTokenEnumerator::GetCurToken() const
+{
+    xub_StrLen nTokenLen, nEnd;
+    FormTokenType eTokenType = _SearchNextToken( nCurPatternPos, nEnd,
+                                                    &nTokenLen );
+    return BuildToken( eTokenType, nTokenLen );
+}
+
+SwFormToken SwFormTokenEnumerator::BuildToken( FormTokenType eTokenType,
+                                                  xub_StrLen nTokenLen ) const
+{
+    String sToken( sPattern.Copy( nCurPatternPos, nCurPatternLen ));
+
+    // at this point sPattern contains the
+    // character style name, the PoolId, tab stop position, tab stop alignment, chapter info format
+    // the form is: CharStyleName, PoolId[, TabStopPosition|ChapterInfoFormat[, TabStopAlignment[, TabFillChar]]]
+    // in text tokens the form differs from the others: CharStyleName, PoolId[,\0xffinserted text\0xff]
+    SwFormToken eRet( eTokenType );
+    String sAuthFieldEnum = sToken.Copy( 2, 2 );
+    sToken = sToken.Copy( nTokenLen, sToken.Len() - nTokenLen - 1);
+
+    eRet.sCharStyleName = sToken.GetToken( 0, ',');
+    String sTmp( sToken.GetToken( 1, ',' ));
+    if( sTmp.Len() )
+        eRet.nPoolId = sTmp.ToInt32();
+
+    switch( eTokenType )
+    {
+    case TOKEN_TEXT:
+        {
+            xub_StrLen nStartText = sToken.Search( TOX_STYLE_DELIMITER );
+            if( STRING_NOTFOUND != nStartText )
+            {
+                xub_StrLen nEndText = sToken.Search( TOX_STYLE_DELIMITER,
+                                                nStartText + 1);
+                if( STRING_NOTFOUND != nEndText )
+                {
+                    eRet.sText = sToken.Copy( nStartText + 1,
+                                                nEndText - nStartText - 1);
+                }
+            }
+        }
+        break;
+
+    case TOKEN_TAB_STOP:
+        if( (sTmp = sToken.GetToken( 2, ',' ) ).Len() )
+            eRet.nTabStopPosition = sTmp.ToInt32();
+
+        if( (sTmp = sToken.GetToken( 3, ',' ) ).Len() )
+            eRet.eTabAlign = sTmp.ToInt32();
+
+        if( (sTmp = sToken.GetToken( 4, ',' ) ).Len() )
+            eRet.cTabFillChar = sTmp.GetChar(0);
+        break;
+
+    case TOKEN_CHAPTER_INFO:
+        if( (sTmp = sToken.GetToken( 2, ',' ) ).Len() )
+            eRet.nChapterFormat = sTmp.ToInt32(); //SwChapterFormat;
+        break;
+
+    case TOKEN_AUTHORITY:
+        eRet.nAuthorityField = sAuthFieldEnum.ToInt32();
+        break;
+    }
+    return eRet;
+}
+
+FormTokenType SwFormTokenEnumerator::_SearchNextToken( xub_StrLen nStt,
+                            xub_StrLen& rEnd, xub_StrLen* pTokenLen ) const
+{
+    //it's not so easy - it doesn't work if the text part contains a '>'
+    //USHORT nTokenEnd = sPattern.Search('>');
+    rEnd = sPattern.Search( '>', nStt );
+    if( STRING_NOTFOUND == rEnd )
+    {
+        rEnd = sPattern.Len();
+        return TOKEN_END;
+    }
+
+    xub_StrLen nTextSeparatorFirst = sPattern.Search( TOX_STYLE_DELIMITER, nStt );
+    if( STRING_NOTFOUND != nTextSeparatorFirst )
+    {
+        xub_StrLen nTextSeparatorSecond = sPattern.Search( TOX_STYLE_DELIMITER,
+                                                nTextSeparatorFirst + 1 );
+        if( STRING_NOTFOUND != nTextSeparatorSecond &&
+            rEnd > nTextSeparatorFirst )
+            rEnd = sPattern.Search( '>', nTextSeparatorSecond );
+    }
+
+    ++rEnd;
+    String sToken( sPattern.Copy( nStt, rEnd - nStt ) );
+
+    static struct
+    {
+        const sal_Char* pNm;
+        USHORT nLen;
+        USHORT nOffset;
+        FormTokenType eToken;
+    } __READONLY_DATA aTokenArr[] = {
+        SwForm::aFormTab,       SwForm::nFormEntryLen,      1, TOKEN_TAB_STOP,
+        SwForm::aFormPageNums,  SwForm::nFormPageNumsLen,   1, TOKEN_PAGE_NUMS,
+        SwForm::aFormLinkStt,   SwForm::nFormLinkSttLen,    1, TOKEN_LINK_START,
+        SwForm::aFormLinkEnd,   SwForm::nFormLinkEndLen,    1, TOKEN_LINK_END,
+        SwForm::aFormEntryNum,  SwForm::nFormEntryNumLen,   1, TOKEN_ENTRY_NO,
+        SwForm::aFormEntryTxt,  SwForm::nFormEntryTxtLen,   1, TOKEN_ENTRY_TEXT,
+        SwForm::aFormChapterMark,SwForm::nFormChapterMarkLen,1,TOKEN_CHAPTER_INFO,
+        SwForm::aFormText,      SwForm::nFormTextLen,       1, TOKEN_TEXT,
+        SwForm::aFormEntry,     SwForm::nFormEntryLen,      1, TOKEN_ENTRY,
+        SwForm::aFormAuth,      SwForm::nFormAuthLen,       3, TOKEN_AUTHORITY,
+        0,                      0,                          0, TOKEN_END
+    };
+
+    FormTokenType eTokenType = TOKEN_TEXT;
+    xub_StrLen nTokenLen = 0;
+    const sal_Char* pNm;
+    for( int i = 0; 0 != ( pNm = aTokenArr[ i ].pNm ); ++i )
+        if( COMPARE_EQUAL == sToken.CompareToAscii( pNm,
+                            aTokenArr[ i ].nLen - aTokenArr[ i ].nOffset ))
+        {
+            eTokenType = aTokenArr[ i ].eToken;
+            nTokenLen = aTokenArr[ i ].nLen;
+            break;
+        }
+
+    ASSERT( pNm, "wrong token" );
+    if( pTokenLen )
+        *pTokenLen = nTokenLen;
+    return eTokenType;
+}
+
+FormTokenType SwFormTokenEnumerator::GetCurTokenType()
+{
+    xub_StrLen nEnd;
+    return _SearchNextToken( nCurPatternPos, nEnd );
+}
+
+FormTokenType SwFormTokenEnumerator::GetNextTokenType()
+{
+    xub_StrLen nEnd;
+    nCurPatternPos += nCurPatternLen;
+    FormTokenType eTokenType;
+    if( nCurPatternPos < sPattern.Len() )
+    {
+        eTokenType = _SearchNextToken( nCurPatternPos, nEnd );
+        nCurPatternLen = nEnd - nCurPatternPos;
+    }
+    else
+    {
+        eTokenType = TOKEN_END;
+        nCurPatternLen = 0;
+    }
+    return eTokenType;
+}
+
+FormTokenType SwFormTokenEnumerator::GetPrevTokenType()
+{
+    FormTokenType eTokenType = TOKEN_END;
+    if( nCurPatternPos )
+    {
+        xub_StrLen nStt = 0, nEnd;
+        do {
+            eTokenType = _SearchNextToken( nStt, nEnd );
+            if( nEnd == nCurPatternPos )
+            {
+                nCurPatternPos = nStt;
+                nCurPatternLen = nEnd - nStt;
+                break;
+            }
+            nStt = nEnd;
+            if( nStt >= sPattern.Len() )
+            {
+                eTokenType = TOKEN_END;
+                break;
+            }
+        } while( TRUE );
+    }
+    return eTokenType;
+}
+
+void SwFormTokenEnumerator::RemoveCurToken()
+{
+    if( nCurPatternLen )
+    {
+        sPattern.Erase( nCurPatternPos, nCurPatternLen );
+        nCurPatternLen = 0;
+        GetNextTokenType();
+    }
+}
+
+void SwFormTokenEnumerator::InsertToken( const SwFormToken& rToken )
+{
+    String sIns( rToken.GetString() );
+    if( sIns.Len() )
+    {
+        sPattern.Insert( sIns, nCurPatternPos );
+        nCurPatternLen = sIns.Len();
+        GetNextTokenType();
+    }
+}
+
+String SwFormToken::GetString() const
+{
+    String sRet;
+
+    BOOL bAppend = TRUE;
+    switch( eTokenType )
+    {
+        case TOKEN_ENTRY_NO:
+            sRet.AssignAscii( SwForm::aFormEntryNum );
+        break;
+        case TOKEN_ENTRY_TEXT:
+            sRet.AssignAscii( SwForm::aFormEntryTxt );
+        break;
+        case TOKEN_ENTRY:
+            sRet.AssignAscii( SwForm::aFormEntry );
+        break;
+        case TOKEN_TAB_STOP:
+            sRet.AssignAscii( SwForm::aFormTab );
+        break;
+        case TOKEN_TEXT:
+            sRet.AssignAscii( SwForm::aFormText );
+        break;
+        case TOKEN_PAGE_NUMS:
+            sRet.AssignAscii( SwForm::aFormPageNums );
+        break;
+        case TOKEN_CHAPTER_INFO:
+            sRet.AssignAscii( SwForm::aFormChapterMark );
+        break;
+        case TOKEN_LINK_START:
+            sRet.AssignAscii( SwForm::aFormLinkStt );
+        break;
+        case TOKEN_LINK_END:
+            sRet.AssignAscii( SwForm::aFormLinkEnd );
+        break;
+        case TOKEN_AUTHORITY:
+        {
+            sRet.AssignAscii( SwForm::aFormAuth );
+            String sTmp( String::CreateFromInt32( nAuthorityField ));
+            if( sTmp.Len() < 2 )
+                sTmp.Insert('0', 0);
+            sRet.Insert( sTmp, 2 );
+        }
+        break;
+    }
+    sRet.Erase( sRet.Len() - 1 );
+    sRet += ' ';
+    sRet += sCharStyleName;
+    sRet += ',';
+    sRet += String::CreateFromInt32( nPoolId );
+    sRet += ',';
+
+    // TabStopPosition and TabAlign or ChapterInfoFormat
+    if(TOKEN_TAB_STOP == eTokenType)
+    {
+        sRet += String::CreateFromInt32( nTabStopPosition );
+        sRet += ',';
+        sRet += String::CreateFromInt32( eTabAlign );
+        sRet += ',';
+        sRet += cTabFillChar;
+    }
+    else if(TOKEN_CHAPTER_INFO == eTokenType)
+    {
+        sRet += String::CreateFromInt32( nChapterFormat );
+    }
+    else if(TOKEN_TEXT == eTokenType)
+    {
+        //append Text if Len() > 0 only!
+        if( sText.Len() )
+        {
+            sRet += TOX_STYLE_DELIMITER;
+            String sTmp( sText );
+            sTmp.EraseAllChars( TOX_STYLE_DELIMITER );
+            sRet += sTmp;
+            sRet += TOX_STYLE_DELIMITER;
+        }
+        else
+            bAppend = FALSE;
+    }
+    if(bAppend)
+    {
+        sRet += '>';
+    }
+    else
+    {
+        // don't append empty text tokens
+        sRet.Erase();
+    }
+
+    return sRet;
+}
+
+
+
+
diff --git a/sw/source/core/tox/txmsrt.cxx b/sw/source/core/tox/txmsrt.cxx
new file mode 100644
index 000000000000..aad7e3626480
--- /dev/null
+++ b/sw/source/core/tox/txmsrt.cxx
@@ -0,0 +1,818 @@
+/*************************************************************************
+ *
+ *  $RCSfile: txmsrt.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:27 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _INTN_HXX //autogen
+#include 
+#endif
+#ifndef _TOOLS_RESID_HXX
+#include 
+#endif
+#ifndef _URLOBJ_HXX
+#include 
+#endif
+
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _CNTFRM_HXX
+#include 
+#endif
+#ifndef _NODE_HXX
+#include 
+#endif
+#ifndef _FRMATR_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _TXTTXMRK_HXX //autogen
+#include 
+#endif
+#ifndef _FRMFMT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFLD_HXX
+#include 
+#endif
+#ifndef _TXMSRT_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _TXTATR_HXX
+#include 
+#endif
+#ifndef _FMTCOL_HXX
+#include 
+#endif
+#ifndef _SWTABLE_HXX
+#include 
+#endif
+#ifndef _EXPFLD_HXX
+#include 
+#endif
+#ifndef _NUMRULE_HXX
+#include 
+#endif
+#ifndef _AUTHFLD_HXX
+#include 
+#endif
+
+#ifndef _COMCORE_HRC
+#include 
+#endif
+
+extern BOOL IsFrameBehind( const SwTxtNode& rMyNd, xub_StrLen nMySttPos,
+                           const SwTxtNode& rBehindNd, xub_StrLen nSttPos );
+
+/*--------------------------------------------------------------------
+    Beschreibung: Strings initialisieren
+ --------------------------------------------------------------------*/
+
+USHORT SwTOXSortTabBase::nOpt = 0;
+
+SV_IMPL_VARARR( SwTOXSources, SwTOXSource )
+
+
+/*--------------------------------------------------------------------
+     Beschreibung:  SortierElement fuer Verzeichniseintraege
+ --------------------------------------------------------------------*/
+
+
+SwTOXSortTabBase::SwTOXSortTabBase( TOXSortType nTyp, const SwCntntNode* pNd,
+                                    const SwTxtTOXMark* pMark,
+                                    const International* pInter )
+    : pTxtMark( pMark ), pTOXNd( 0 ), nPos( 0 ), nType( nTyp ),
+    pIntl( pInter ), bValidTxt( FALSE ), nCntPos( 0 )
+{
+    if( pNd )
+    {
+        xub_StrLen n = 0;
+        if( pTxtMark )
+            n = *pTxtMark->GetStart();
+        SwTOXSource aTmp( pNd, n,
+                    pTxtMark ? pTxtMark->GetTOXMark().IsMainEntry() : FALSE );
+        aTOXSources.Insert( aTmp, aTOXSources.Count() );
+
+        nPos = pNd->GetIndex();
+
+        switch( nTyp )
+        {
+        case TOX_SORT_CONTENT:
+        case TOX_SORT_PARA:
+        case TOX_SORT_TABLE:
+            // falls sie in Sonderbereichen stehen, sollte man die
+            // Position im Body besorgen
+            if( nPos < pNd->GetNodes().GetEndOfExtras().GetIndex() )
+            {
+                // dann die "Anker" (Body) Position holen.
+                Point aPt;
+                const SwCntntFrm* pFrm = pNd->GetFrm( &aPt, 0, FALSE );
+                if( pFrm )
+                {
+                    SwPosition aPos( *pNd );
+                    const SwDoc& rDoc = *pNd->GetDoc();
+#ifndef PRODUCT
+                    ASSERT( GetBodyTxtNode( rDoc, aPos, *pFrm ),
+                            "wo steht der Absatz" );
+#else
+                    GetBodyTxtNode( rDoc, aPos, *pFrm );
+#endif
+                    nPos = aPos.nNode.GetIndex();
+                    nCntPos = aPos.nContent.GetIndex();
+                }
+            }
+            else
+                nCntPos = n;
+            break;
+        }
+    }
+}
+
+
+String SwTOXSortTabBase::GetURL() const
+{
+    return aEmptyStr;
+}
+
+void SwTOXSortTabBase::FillText( SwTxtNode& rNd, const SwIndex& rInsPos,
+                                    USHORT ) const
+{
+    rNd.Insert( GetTxt(), rInsPos );
+}
+
+BOOL SwTOXSortTabBase::operator==( const SwTOXSortTabBase& rCmp )
+{
+    BOOL bRet = nPos == rCmp.nPos && nCntPos == rCmp.nCntPos &&
+            (!aTOXSources[0].pNd || !rCmp.aTOXSources[0].pNd ||
+            aTOXSources[0].pNd == rCmp.aTOXSources[0].pNd );
+
+    if( TOX_SORT_CONTENT == nType )
+    {
+        bRet = bRet && pTxtMark && rCmp.pTxtMark &&
+                *pTxtMark->GetStart() == *rCmp.pTxtMark->GetStart();
+
+        if( bRet )
+        {
+            // beide Pointer vorhanden -> vergleiche Text
+            // beide Pointer nicht vorhanden -> vergleiche AlternativText
+            const xub_StrLen *pEnd  = pTxtMark->GetEnd(),
+                                *pEndCmp = rCmp.pTxtMark->GetEnd();
+
+            bRet = ( ( pEnd && pEndCmp ) || ( !pEnd && !pEndCmp ) ) &&
+                    COMPARE_EQUAL == pIntl->Compare( GetTxt(),
+                                rCmp.GetTxt(), INTN_COMPARE_IGNORECASE );
+        }
+    }
+    return bRet;
+}
+
+BOOL SwTOXSortTabBase::operator<( const SwTOXSortTabBase& rCmp )
+{
+    if( nPos < rCmp.nPos )
+        return TRUE;
+
+    if( nPos == rCmp.nPos )
+    {
+        if( nCntPos < rCmp.nCntPos )
+            return TRUE;
+
+        if( nCntPos == rCmp.nCntPos )
+        {
+            const SwNode* pFirst = aTOXSources[0].pNd;
+            const SwNode* pNext = rCmp.aTOXSources[0].pNd;
+
+            if( pFirst && pFirst == pNext )
+            {
+                if( TOX_SORT_CONTENT == nType && pTxtMark && rCmp.pTxtMark )
+                {
+                    if( *pTxtMark->GetStart() < *rCmp.pTxtMark->GetStart() )
+                        return TRUE;
+
+                    if( *pTxtMark->GetStart() == *rCmp.pTxtMark->GetStart() )
+                    {
+                        const xub_StrLen *pEnd = pTxtMark->GetEnd(),
+                                            *pEndCmp = rCmp.pTxtMark->GetEnd();
+
+                        // beide Pointer vorhanden -> vergleiche Text
+                        // beide Pointer nicht vorhanden -> vergleiche AlternativText
+                        if( ( pEnd && pEndCmp ) || ( !pEnd && !pEndCmp ) )
+                            return COMPARE_LESS == pIntl->Compare( GetTxt(),
+                                    rCmp.GetTxt(), INTN_COMPARE_IGNORECASE );
+
+                        if( pEnd && !pEndCmp )
+                            return TRUE;
+                    }
+                }
+            }
+            else if( pFirst && pFirst->IsTxtNode() &&
+                     pNext && pNext->IsTxtNode() )
+                    return ::IsFrameBehind( *(SwTxtNode*)pNext, nCntPos,
+                                            *(SwTxtNode*)pFirst, nCntPos );
+        }
+    }
+    return FALSE;
+}
+
+
+/*--------------------------------------------------------------------
+     Beschreibung: sortierter Stichworteintrag
+ --------------------------------------------------------------------*/
+
+
+SwTOXIndex::SwTOXIndex( const SwTxtNode& rNd,
+                                const SwTxtTOXMark* pMark, USHORT nOptions,
+                                BYTE nKyLevel,
+                                const International& rIntl )
+    : SwTOXSortTabBase( TOX_SORT_INDEX, &rNd, pMark, &rIntl ),
+    nKeyLevel(nKyLevel)
+{
+    nPos = rNd.GetIndex();
+    nOpt = nOptions;
+}
+
+//
+// Stichworte vergleichen. Bezieht sich nur auf den Text
+//
+
+
+BOOL SwTOXIndex::operator==( const SwTOXSortTabBase& rCmpBase )
+{
+    SwTOXIndex& rCmp = (SwTOXIndex&)rCmpBase;
+
+    // In Abhaengigkeit von den Optionen Grosskleinschreibung beachten
+    BOOL bRet;
+    if(GetLevel() != rCmp.GetLevel() || nKeyLevel != rCmp.nKeyLevel)
+        return FALSE;
+
+    String sMyTxt( GetTxt() ), sOtherTxt( rCmp.GetTxt() );
+    sMyTxt.Insert( pIntl->GetIndexChar( sMyTxt ), 0 );
+    sOtherTxt.Insert( pIntl->GetIndexChar( sOtherTxt ), 0 );
+
+    USHORT nCmpFlags;
+    if( GetOptions() & TOI_CASE_SENSITIVE )
+        nCmpFlags = 0;
+    else
+        nCmpFlags = INTN_COMPARE_IGNORECASE;
+    bRet = COMPARE_EQUAL == pIntl->Compare( sMyTxt, sOtherTxt, nCmpFlags );
+
+    // Wenn nicht zusammengefasst wird muss die Pos aus gewertet werden
+    if(bRet && !(GetOptions() & TOI_SAME_ENTRY))
+        bRet = nPos == rCmp.nPos;
+
+    return bRet;
+}
+
+//
+// kleiner haengt nur vom Text ab
+
+
+//
+
+BOOL SwTOXIndex::operator<( const SwTOXSortTabBase& rCmpBase )
+{
+    SwTOXIndex& rCmp = (SwTOXIndex&)rCmpBase;
+
+    USHORT nFlag = GetOptions() & TOI_CASE_SENSITIVE ? 0 : INTN_COMPARE_IGNORECASE;
+
+    String sMyTxt( GetTxt() ), sOtherTxt( rCmp.GetTxt() );
+    sMyTxt.Insert( pIntl->GetIndexChar( sMyTxt ), 0 );
+    sOtherTxt.Insert( pIntl->GetIndexChar( sOtherTxt ), 0 );
+
+    BOOL bRet = COMPARE_LESS == pIntl->Compare( sMyTxt, sOtherTxt, nFlag ) &&
+                GetLevel() == rCmp.GetLevel();
+
+    // Wenn nicht zusammengefasst wird muss die Pos aus gewertet werden
+    if( !bRet && !(GetOptions() & TOI_SAME_ENTRY) )
+        bRet =  COMPARE_EQUAL == pIntl->Compare( sMyTxt, sOtherTxt, nFlag ) &&
+                nPos < rCmp.nPos;
+
+    return bRet;
+}
+
+//
+// Das Stichwort selbst
+
+
+//
+
+void SwTOXIndex::_GetText( String& rTxt )
+{
+    ASSERT(pTxtMark, "pTxtMark == 0, Kein Stichwort");
+    const SwTOXMark& rTOXMark = pTxtMark->GetTOXMark();
+    switch(nKeyLevel)
+    {
+        case FORM_PRIMARY_KEY    :
+            rTxt = rTOXMark.GetPrimaryKey();
+        break;
+        case FORM_SECONDARY_KEY  :
+            rTxt = rTOXMark.GetSecondaryKey();
+        break;
+        case FORM_ENTRY          :
+            rTxt = rTOXMark.GetText();
+        break;
+    }
+    // if TOI_INITIAL_CAPS is set, first character is to be capitalized
+    if(TOI_INITIAL_CAPS&nOpt && pIntl)
+    {
+        rTxt.SetChar(0, pIntl->Upper(rTxt.GetChar(0)));
+    }
+}
+
+void SwTOXIndex::FillText( SwTxtNode& rNd, const SwIndex& rInsPos, USHORT ) const
+{
+    const xub_StrLen* pEnd = pTxtMark->GetEnd();
+    String sTmp;
+    if( pEnd && !pTxtMark->GetTOXMark().IsAlternativeText() &&
+            0 == (GetOptions() & TOI_KEY_AS_ENTRY))
+    {
+        sTmp = ((SwTxtNode*)aTOXSources[0].pNd)->GetExpandTxt(
+                            *pTxtMark->GetStart(),
+                            *pEnd - *pTxtMark->GetStart());
+        if(TOI_INITIAL_CAPS&nOpt && pIntl)
+        {
+            sTmp.SetChar(0, pIntl->Upper(sTmp.GetChar(0)));
+        }
+    }
+    else
+        sTmp = GetTxt();
+
+    rNd.Insert( sTmp, rInsPos );
+}
+
+
+
+USHORT SwTOXIndex::GetLevel() const
+{
+    ASSERT(pTxtMark, "pTxtMark == 0, Kein Stichwort");
+
+    USHORT nForm = FORM_PRIMARY_KEY;
+
+    if( 0 == (GetOptions() & TOI_KEY_AS_ENTRY)&&
+        pTxtMark->GetTOXMark().GetPrimaryKey().Len() )
+    {
+        nForm = FORM_SECONDARY_KEY;
+        if( pTxtMark->GetTOXMark().GetSecondaryKey().Len() )
+            nForm = FORM_ENTRY;
+    }
+    return nForm;
+}
+
+/*--------------------------------------------------------------------
+     Beschreibung: Schluessel und Trennzeichen
+ --------------------------------------------------------------------*/
+
+
+SwTOXCustom::SwTOXCustom(const String& rStr, USHORT nLevel,
+                            const International& rIntl )
+    : SwTOXSortTabBase( TOX_SORT_CUSTOM, 0, 0, &rIntl ),
+    aKey(rStr), nLev(nLevel)
+{
+}
+
+
+BOOL SwTOXCustom::operator==(const SwTOXSortTabBase& rCmpBase)
+{
+    return COMPARE_EQUAL == pIntl->Compare( GetTxt(), rCmpBase.GetTxt() ) &&
+            GetLevel() == rCmpBase.GetLevel();
+}
+
+
+BOOL SwTOXCustom::operator < (const SwTOXSortTabBase& rCmpBase)
+{
+    return COMPARE_LESS == pIntl->Compare( GetTxt(), rCmpBase.GetTxt() ) &&
+            GetLevel() <= rCmpBase.GetLevel();
+}
+
+
+USHORT SwTOXCustom::GetLevel() const
+{
+    return nLev;
+}
+
+
+void SwTOXCustom::_GetText( String& rTxt )
+{
+    rTxt = aKey;
+}
+
+/*--------------------------------------------------------------------
+     Beschreibung: sortierter Inhaltsverz. Eintrag
+ --------------------------------------------------------------------*/
+
+
+SwTOXContent::SwTOXContent( const SwTxtNode& rNd, const SwTxtTOXMark* pMark,
+                        const International& rIntl)
+    : SwTOXSortTabBase( TOX_SORT_CONTENT, &rNd, pMark, &rIntl )
+{
+}
+
+
+//  Der Text des Inhalts
+//
+
+void SwTOXContent::_GetText( String& rTxt )
+{
+    const xub_StrLen* pEnd = pTxtMark->GetEnd();
+    if( pEnd && !pTxtMark->GetTOXMark().IsAlternativeText() )
+        rTxt = ((SwTxtNode*)aTOXSources[0].pNd)->GetExpandTxt(
+                                     *pTxtMark->GetStart(),
+                                     *pEnd - *pTxtMark->GetStart() );
+    else
+        rTxt = pTxtMark->GetTOXMark().GetAlternativeText();
+}
+
+void SwTOXContent::FillText( SwTxtNode& rNd, const SwIndex& rInsPos, USHORT ) const
+{
+    const xub_StrLen* pEnd = pTxtMark->GetEnd();
+    if( pEnd && !pTxtMark->GetTOXMark().IsAlternativeText() )
+        ((SwTxtNode*)aTOXSources[0].pNd)->GetExpandTxt( rNd, &rInsPos,
+                                    *pTxtMark->GetStart(),
+                                    *pEnd - *pTxtMark->GetStart() );
+    else
+        rNd.Insert( GetTxt(), rInsPos );
+}
+
+//
+// Die Ebene fuer Anzeige
+//
+
+
+USHORT SwTOXContent::GetLevel() const
+{
+    return pTxtMark->GetTOXMark().GetLevel();
+}
+
+/*--------------------------------------------------------------------
+     Beschreibung: Verzeichnis aus Absaetzen zusammengesammelt
+ --------------------------------------------------------------------*/
+
+// bei Sortierung von OLE/Grafiken aufpassen !!!
+// Die Position darf nicht die im Dokument,
+// sondern muss die vom "Henkel" sein  !!
+
+
+SwTOXPara::SwTOXPara( const SwCntntNode& rNd, SwTOXElement eT, USHORT nLevel )
+    : SwTOXSortTabBase( TOX_SORT_PARA, &rNd, 0, 0 ),
+    eType( eT ),
+    m_nLevel(nLevel),
+    nStartIndex(0),
+    nEndIndex(STRING_LEN)
+{
+}
+
+
+void SwTOXPara::_GetText( String& rTxt )
+{
+    const SwCntntNode* pNd = aTOXSources[0].pNd;
+    switch( eType )
+    {
+    case TOX_SEQUENCE:
+    case TOX_TEMPLATE:
+        {
+            xub_StrLen nStt = nStartIndex;
+/* JP 22.01.98:
+    Tabs ueberspringen - macht aber keinen Sinn, solange in der TOX-Form
+    nicht die KapitelNummer eingestellt werden kann
+            const String& rTmp = ((SwTxtNode*)pNd)->GetTxt();
+            while( '\t' == rTmp.GetChar( nStt ) && nStt < rTmp.Len() )
+                ++nStt;
+*/
+            rTxt = ((SwTxtNode*)pNd)->GetExpandTxt(
+                    nStt,
+                    STRING_NOTFOUND == nEndIndex ? STRING_LEN : nEndIndex - nStt);
+        }
+        break;
+
+    case TOX_OLE:
+    case TOX_GRAPHIC:
+    case TOX_FRAME:
+        {
+            // suche das FlyFormat, dort steht der Object/Grafik-Name
+            SwFrmFmt* pFly = pNd->GetFlyFmt();
+            if( pFly )
+                rTxt = pFly->GetName();
+            else
+            {
+                ASSERT( !this, "Grafik/Object ohne Namen" )
+                USHORT nId = TOX_OLE == eType
+                                ? STR_OBJECT_DEFNAME
+                                : TOX_GRAPHIC == eType
+                                    ? STR_GRAPHIC_DEFNAME
+                                    : STR_FRAME_DEFNAME;
+                rTxt = SW_RESSTR( nId );
+            }
+        }
+        break;
+    }
+}
+
+void SwTOXPara::FillText( SwTxtNode& rNd, const SwIndex& rInsPos, USHORT ) const
+{
+    if( TOX_TEMPLATE == eType || TOX_SEQUENCE == eType )
+    {
+        SwTxtNode* pSrc = (SwTxtNode*)aTOXSources[0].pNd;
+        xub_StrLen nStt = nStartIndex;
+/* JP 22.01.98:
+    Tabs ueberspringen - macht aber keinen Sinn, solange in der TOX-Form
+    nicht die KapitelNummer eingestellt werden kann
+        const String& rTxt = pSrc->GetTxt();
+        while( '\t' == rTxt.GetChar( nStt ) && nStt < rTxt.Len() )
+            ++nStt;
+*/
+        pSrc->GetExpandTxt( rNd, &rInsPos, nStt,
+                nEndIndex == STRING_LEN ? STRING_LEN : nEndIndex - nStt );
+    }
+    else
+        rNd.Insert( GetTxt(), rInsPos );
+}
+
+
+USHORT SwTOXPara::GetLevel() const
+{
+    USHORT nRet = m_nLevel;
+    const SwCntntNode*  pNd = aTOXSources[0].pNd;
+
+    if( TOX_TEMPLATE == eType && pNd->GetTxtNode() )
+    {
+        USHORT nTmp = ((SwTxtNode*)pNd)->GetTxtColl()->GetOutlineLevel();
+        if(nTmp < NO_NUMBERING)
+            nRet = nTmp + 1;
+    }
+    return nRet;
+}
+
+
+String SwTOXPara::GetURL() const
+{
+    String aTxt;
+    const SwCntntNode* pNd = aTOXSources[0].pNd;
+    switch( eType )
+    {
+    case TOX_TEMPLATE:
+        {
+            aTxt = '#';
+            const SwNodeNum* pNum = ((SwTxtNode*)pNd)->GetOutlineNum();
+            if( pNum && pNd->GetDoc()->GetOutlineNumRule() )
+            {
+                // dann noch die rel. Nummer davor setzen
+                const SwNumRule& rRule = *pNd->GetDoc()->GetOutlineNumRule();
+                for( int n = 0; n <= pNum->GetLevel(); ++n )
+                {
+                    int nNum = pNum->GetLevelVal()[ n ];
+                    nNum -= ( rRule.Get( n ).GetStartValue() - 1 );
+                    ( aTxt += String::CreateFromInt32( nNum )) += '.';
+                }
+            }
+            aTxt += INetURLObject::createFragment(
+                                ((SwTxtNode*)pNd)->GetExpandTxt() );
+            ( aTxt += cMarkSeperator ).AppendAscii( pMarkToOutline );
+        }
+        break;
+
+    case TOX_OLE:
+    case TOX_GRAPHIC:
+    case TOX_FRAME:
+        {
+            // suche das FlyFormat, dort steht der Object/Grafik-Name
+            SwFrmFmt* pFly = pNd->GetFlyFmt();
+            if( pFly )
+            {
+                (( aTxt = '#' ) += pFly->GetName() ) += cMarkSeperator;
+                const sal_Char* pStr;
+                switch( eType )
+                {
+                case TOX_OLE:       pStr = pMarkToOLE; break;
+                case TOX_GRAPHIC:   pStr = pMarkToGraphic; break;
+                case TOX_FRAME:     pStr = pMarkToFrame; break;
+                default:            pStr = 0;
+                }
+                if( pStr )
+                    aTxt.AppendAscii( pStr );
+            }
+        }
+        break;
+    }
+    return aTxt;
+}
+
+
+/*--------------------------------------------------------------------
+    Beschreibung: Tabelle
+ --------------------------------------------------------------------*/
+
+
+SwTOXTable::SwTOXTable( const SwCntntNode& rNd )
+    : SwTOXSortTabBase( TOX_SORT_TABLE, &rNd, 0, 0 ),
+    nLevel(FORM_ALPHA_DELIMITTER)
+{
+}
+
+
+void SwTOXTable::_GetText( String& rTxt )
+{
+    const SwNode* pNd = aTOXSources[0].pNd;
+    if( pNd && 0 != ( pNd = pNd->FindTableNode() ) )
+    {
+        rTxt = ((SwTableNode*)pNd)->GetTable().GetFrmFmt()->GetName();
+    }
+    else
+    {
+        ASSERT( !this, "Wo ist meine Tabelle geblieben?" )
+        rTxt = SW_RESSTR( STR_TABLE_DEFNAME );
+    }
+}
+
+
+USHORT SwTOXTable::GetLevel() const
+{
+    return nLevel;
+}
+
+
+String SwTOXTable::GetURL() const
+{
+    String aTxt;
+    const SwNode* pNd = aTOXSources[0].pNd;
+    if( pNd && 0 != ( pNd = pNd->FindTableNode() ) )
+    {
+        aTxt = ((SwTableNode*)pNd)->GetTable().GetFrmFmt()->GetName();
+        if( aTxt.Len() )
+        {
+            ( aTxt.Insert( '#', 0 ) += cMarkSeperator ).
+                                            AppendAscii( pMarkToTable );
+        }
+    }
+    return aTxt;
+}
+/*-- 15.09.99 14:28:08---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+
+SwTOXAuthority::SwTOXAuthority( const SwCntntNode& rNd,
+                SwFmtFld& rField, const International& rIntl ) :
+    SwTOXSortTabBase( TOX_SORT_AUTHORITY, &rNd, 0, &rIntl ),
+    m_rField(rField)
+{
+}
+
+USHORT  SwTOXAuthority::GetLevel() const
+{
+    String sText(((SwAuthorityField*)m_rField.GetFld())->
+                        GetFieldText(AUTH_FIELD_AUTHORITY_TYPE));
+    USHORT nRet = 0;
+    if( pIntl->IsNumeric( sText ) )
+    {
+        nRet = sText.ToInt32();
+        nRet++;
+    }
+    if(nRet >= AUTH_TYPE_END)
+        nRet = 0;
+    return nRet;
+}
+/*-- 15.09.99 14:28:08---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwTOXAuthority::_GetText( String& rToFill)
+{
+    //
+    rToFill = m_rField.GetFld()->Expand();
+}
+/* -----------------21.09.99 12:50-------------------
+
+ --------------------------------------------------*/
+void    SwTOXAuthority::FillText( SwTxtNode& rNd,
+                        const SwIndex& rInsPos, USHORT nAuthField ) const
+{
+    SwAuthorityField* pField = (SwAuthorityField*)m_rField.GetFld();
+    String sText;
+    if(AUTH_FIELD_IDENTIFIER == nAuthField)
+    {
+        sText = pField->Expand();
+        sText.Erase(0, 1);
+        sText.Erase(sText.Len() - 1, 1);
+    }
+    else if(AUTH_FIELD_AUTHORITY_TYPE == nAuthField)
+    {
+        USHORT nLevel = GetLevel();
+        if(nLevel)
+            sText = SwAuthorityFieldType::GetAuthTypeName((ToxAuthorityType) --nLevel);
+    }
+    else
+        sText = (pField->GetFieldText((ToxAuthorityField) nAuthField));
+    rNd.Insert( sText, rInsPos );
+}
+/* -----------------14.10.99 09:35-------------------
+
+ --------------------------------------------------*/
+BOOL    SwTOXAuthority::operator==( const SwTOXSortTabBase& rCmp)
+{
+    return nType == rCmp.nType &&
+            ((SwAuthorityField*)m_rField.GetFld())->GetHandle() ==
+                ((SwAuthorityField*)((SwTOXAuthority&)rCmp).m_rField.GetFld())->GetHandle();
+}
+/* -----------------21.10.99 09:52-------------------
+
+ --------------------------------------------------*/
+BOOL    SwTOXAuthority::operator<( const SwTOXSortTabBase& rBase)
+{
+    BOOL bRet = FALSE;
+    SwAuthorityField* pField = (SwAuthorityField*)m_rField.GetFld();
+    SwAuthorityFieldType* pType = (SwAuthorityFieldType*)
+                                                pField->GetTyp();
+    if(pType->IsSortByDocument())
+        bRet = SwTOXSortTabBase::operator<(rBase);
+    else
+    {
+        SwAuthorityField* pCmpField = (SwAuthorityField*)
+                        ((SwTOXAuthority&)rBase).m_rField.GetFld();
+
+        DBG_ASSERT(pIntl, "No International?")
+
+        for(USHORT i = 0; i < pType->GetSortKeyCount(); i++)
+        {
+            const SwTOXSortKey* pKey = pType->GetSortKey(i);
+            String sText1 = pField->GetFieldText(pKey->eField);
+            String sText2 = pCmpField->GetFieldText(pKey->eField);
+
+            StringCompare eComp = pIntl->Compare( sText1, sText2,
+                                             INTN_COMPARE_IGNORECASE);
+            if(COMPARE_EQUAL == eComp)
+                continue;
+            bRet = (COMPARE_LESS == eComp) == pKey->bSortAscending;
+            break;
+        }
+    }
+    return bRet;
+}
+
+
diff --git a/sw/source/core/txtnode/atrfld.cxx b/sw/source/core/txtnode/atrfld.cxx
new file mode 100644
index 000000000000..82106bfae339
--- /dev/null
+++ b/sw/source/core/txtnode/atrfld.cxx
@@ -0,0 +1,376 @@
+/*************************************************************************
+ *
+ *  $RCSfile: atrfld.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:27 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "doc.hxx"          // Update fuer UserFields
+#include "fldbas.hxx"          // fuer FieldType
+
+#ifndef _FMTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFLD_HXX //autogen
+#include 
+#endif
+#include "reffld.hxx"
+#include "ddefld.hxx"
+#include "usrfld.hxx"
+#include "expfld.hxx"
+#include "swfont.hxx"       // fuer GetFldsColor
+#include "ndtxt.hxx"        // SwTxtNode
+#include "calc.hxx"         // Update fuer UserFields
+#include "hints.hxx"
+
+TYPEINIT2( SwFmtFld, SfxPoolItem, SwClient )
+
+/****************************************************************************
+ *
+ *  class SwFmtFld
+ *
+ ****************************************************************************/
+
+    // Konstruktor fuers Default vom Attribut-Pool
+SwFmtFld::SwFmtFld()
+    : SfxPoolItem( RES_TXTATR_FIELD ),
+    SwClient( 0 ),
+    pField( 0 ),
+    pTxtAttr( 0 )
+{
+}
+
+SwFmtFld::SwFmtFld( const SwField &rFld )
+    : SfxPoolItem( RES_TXTATR_FIELD ),
+    SwClient( rFld.GetTyp() ),
+    pTxtAttr( 0 )
+{
+    pField = rFld.Copy();
+}
+
+SwFmtFld::SwFmtFld( const SwFmtFld& rAttr )
+    : SfxPoolItem( RES_TXTATR_FIELD ),
+    SwClient( rAttr.GetFld()->GetTyp() ),
+    pTxtAttr( 0 )
+{
+    pField = rAttr.GetFld()->Copy();
+}
+
+SwFmtFld::~SwFmtFld()
+{
+    SwFieldType* pType = pField ? pField->GetTyp() : 0;
+
+    if (pType && pType->Which() == RES_DBFLD)
+        pType = 0;  // DB-Feldtypen zerstoeren sich selbst
+
+    delete pField;
+
+    // bei einige FeldTypen muessen wir den FeldTypen noch loeschen
+    if( pType && pType->IsLastDepend() )
+    {
+        BOOL bDel = FALSE;
+        switch( pType->Which() )
+        {
+        case RES_USERFLD:
+            bDel = ((SwUserFieldType*)pType)->IsDeleted();
+            break;
+
+        case RES_SETEXPFLD:
+            bDel = ((SwSetExpFieldType*)pType)->IsDeleted();
+            break;
+
+        case RES_DDEFLD:
+            bDel = ((SwDDEFieldType*)pType)->IsDeleted();
+            break;
+        }
+
+        if( bDel )
+        {
+            // vorm loeschen erstmal austragen
+            pType->Remove( this );
+            delete pType;
+        }
+    }
+}
+
+int SwFmtFld::operator==( const SfxPoolItem& rAttr ) const
+{
+    ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" );
+    return pField->GetTyp() == ((SwFmtFld&)rAttr).GetFld()->GetTyp() &&
+           pField->GetFormat() == ((SwFmtFld&)rAttr).GetFld()->GetFormat();
+}
+
+SfxPoolItem* SwFmtFld::Clone( SfxItemPool* ) const
+{
+    return new SwFmtFld( *this );
+}
+
+void SwFmtFld::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew )
+{
+    if( !pTxtAttr )
+        return;
+
+    SwTxtNode* pTxtNd = (SwTxtNode*)&pTxtAttr->GetTxtNode();
+    ASSERT( pTxtNd, "wo ist denn mein Node?" );
+    if( pNew )
+    {
+        switch( pNew->Which() )
+        {
+        case RES_TXTATR_FLDCHG:
+                // "Farbe hat sich geaendert !"
+                // this, this fuer "nur Painten"
+                pTxtNd->Modify( this, this );
+                return;
+        case RES_REFMARKFLD_UPDATE:
+                // GetReferenz-Felder aktualisieren
+                if( RES_GETREFFLD == GetFld()->GetTyp()->Which() )
+                    ((SwGetRefField*)GetFld())->UpdateField();
+                break;
+        case RES_DOCPOS_UPDATE:
+                // Je nach DocPos aktualisieren (SwTxtFrm::Modify())
+                pTxtNd->Modify( pNew, this );
+                return;
+
+        case RES_ATTRSET_CHG:
+        case RES_FMT_CHG:
+                pTxtNd->Modify( pOld, pNew );
+                return;
+        }
+    }
+
+    switch (GetFld()->GetTyp()->Which())
+    {
+        case RES_HIDDENPARAFLD:
+            if( !pOld || RES_HIDDENPARA_PRINT != pOld->Which() )
+                break;
+        case RES_DBSETNUMBERFLD:
+        case RES_DBNUMSETFLD:
+        case RES_DBNEXTSETFLD:
+        case RES_DBNAMEFLD:
+            pTxtNd->Modify( 0, pNew);
+            return;
+    }
+
+    if( RES_USERFLD == GetFld()->GetTyp()->Which() )
+    {
+        SwUserFieldType* pType = (SwUserFieldType*)GetFld()->GetTyp();
+        if(!pType->IsValid())
+        {
+            SwCalc aCalc( *pTxtNd->GetDoc() );
+            pType->GetValue( aCalc );
+        }
+    }
+    pTxtAttr->Expand();
+}
+
+BOOL SwFmtFld::GetInfo( SfxPoolItem& rInfo ) const
+{
+    const SwTxtNode* pTxtNd;
+    if( RES_AUTOFMT_DOCNODE != rInfo.Which() ||
+        !pTxtAttr || 0 == ( pTxtNd = pTxtAttr->GetpTxtNode() ) ||
+        &pTxtNd->GetNodes() != ((SwAutoFmtGetDocNode&)rInfo).pNodes )
+        return TRUE;
+
+    ((SwAutoFmtGetDocNode&)rInfo).pCntntNode = pTxtNd;
+    return FALSE;
+}
+
+
+BOOL SwFmtFld::IsFldInDoc() const
+{
+    const SwTxtNode* pTxtNd;
+    return pTxtAttr && 0 != ( pTxtNd = pTxtAttr->GetpTxtNode() ) &&
+            pTxtNd->GetNodes().IsDocNodes();
+}
+
+BOOL SwFmtFld::IsProtect() const
+{
+    const SwTxtNode* pTxtNd;
+    return pTxtAttr && 0 != ( pTxtNd = pTxtAttr->GetpTxtNode() ) &&
+            pTxtNd->IsProtect();
+}
+
+/*************************************************************************
+|*
+|*                SwTxtFld::SwTxtFld()
+|*
+|*    Beschreibung      Attribut fuer automatischen Text, Ctor
+|*    Ersterstellung    BP 30.04.92
+|*    Letzte Aenderung  JP 15.08.94
+|*
+*************************************************************************/
+
+SwTxtFld::SwTxtFld( const SwFmtFld& rAttr, xub_StrLen nStart )
+    : SwTxtAttr( rAttr, nStart ),
+    aExpand( rAttr.GetFld()->Expand() ),
+    pMyTxtNd( 0 )
+{
+    ((SwFmtFld&)rAttr).pTxtAttr = this;
+}
+
+SwTxtFld::~SwTxtFld( )
+{
+}
+
+/*************************************************************************
+|*
+|*                SwTxtFld::Expand()
+|*
+|*    Beschreibung      exandiert das Feld und tauscht den Text im Node
+|*    Ersterstellung    BP 30.04.92
+|*    Letzte Aenderung  JP 15.08.94
+|*
+*************************************************************************/
+
+void SwTxtFld::Expand()
+{
+    // Wenn das expandierte Feld sich nicht veraendert hat, wird returnt
+    ASSERT( pMyTxtNd, "wo ist denn mein Node?" );
+
+    const SwField* pFld = GetFld().GetFld();
+    XubString aNewExpand( pFld->Expand() );
+
+    if( aNewExpand == aExpand )
+    {
+        // Bei Seitennummernfeldern
+        const USHORT nWhich = pFld->GetTyp()->Which();
+        if( RES_CHAPTERFLD != nWhich && RES_PAGENUMBERFLD != nWhich &&
+            RES_REFPAGEGETFLD != nWhich &&
+            ( RES_GETEXPFLD != nWhich ||
+                ((SwGetExpField*)pFld)->IsInBodyTxt() ) )
+        {
+            // BP: das muesste man noch optimieren!
+            //JP 12.06.97: stimmt, man sollte auf jedenfall eine Status-
+            //              aenderung an die Frames posten
+            if( pMyTxtNd->CalcVisibleFlag() )
+                pMyTxtNd->Modify( 0, 0 );
+            return;
+        }
+    }
+
+    aExpand = aNewExpand;
+
+    // 0, this fuer Formatieren
+    pMyTxtNd->Modify( 0, (SfxPoolItem*)&GetFld() );
+}
+
+/*************************************************************************
+ *                      SwTxtFld::CopyFld()
+ *************************************************************************/
+
+void SwTxtFld::CopyFld( SwTxtFld *pDest ) const
+{
+    ASSERT( pMyTxtNd, "wo ist denn mein Node?" );
+    ASSERT( pDest->pMyTxtNd, "wo ist denn mein Node?" );
+
+    SwDoc *pDoc = pMyTxtNd->GetDoc();
+    SwDoc *pDestDoc = pDest->pMyTxtNd->GetDoc();
+
+    SwFmtFld& rFmtFld = (SwFmtFld&)pDest->GetFld();
+    const USHORT nFldWhich = rFmtFld.GetFld()->GetTyp()->Which();
+
+    if( pDoc != pDestDoc )
+    {
+        // Die Hints stehen in unterschiedlichen Dokumenten,
+        // der Feldtyp muss im neuen Dokument angemeldet werden.
+        // Z.B: Kopieren ins ClipBoard.
+        SwFieldType* pFldType;
+        if( nFldWhich != RES_DBFLD && nFldWhich != RES_USERFLD &&
+            nFldWhich != RES_SETEXPFLD && nFldWhich != RES_DDEFLD &&
+            RES_AUTHORITY != nFldWhich )
+            pFldType = pDestDoc->GetSysFldType( (const RES_FIELDS)nFldWhich );
+        else
+            pFldType = pDestDoc->InsertFldType( *rFmtFld.GetFld()->GetTyp() );
+
+        // Sonderbehandlung fuer DDE-Felder
+        if( RES_DDEFLD == nFldWhich )
+        {
+            if( rFmtFld.GetTxtFld() )
+                ((SwDDEFieldType*)rFmtFld.GetFld()->GetTyp())->DecRefCnt();
+            ((SwDDEFieldType*)pFldType)->IncRefCnt();
+        }
+
+        ASSERT( pFldType, "unbekannter FieldType" );
+        pFldType->Add( &rFmtFld );          // ummelden
+        rFmtFld.GetFld()->ChgTyp( pFldType );
+    }
+
+    // Expressionfelder Updaten
+    if( nFldWhich == RES_SETEXPFLD || nFldWhich == RES_GETEXPFLD ||
+        nFldWhich == RES_HIDDENTXTFLD )
+    {
+        SwTxtFld* pFld = (SwTxtFld*)this;
+        pDestDoc->UpdateExpFlds( pFld );
+    }
+    // Tabellenfelder auf externe Darstellung
+    else if( RES_TABLEFLD == nFldWhich &&
+        ((SwTblField*)rFmtFld.GetFld())->IsIntrnlName() )
+    {
+        // erzeuge aus der internen (fuer CORE) die externe (fuer UI) Formel
+        const SwTableNode* pTblNd = pMyTxtNd->FindTableNode();
+        if( pTblNd )        // steht in einer Tabelle
+            ((SwTblField*)rFmtFld.GetFld())->PtrToBoxNm( &pTblNd->GetTable() );
+    }
+}
+
+
diff --git a/sw/source/core/txtnode/atrflyin.cxx b/sw/source/core/txtnode/atrflyin.cxx
new file mode 100644
index 000000000000..248722e83078
--- /dev/null
+++ b/sw/source/core/txtnode/atrflyin.cxx
@@ -0,0 +1,327 @@
+/*************************************************************************
+ *
+ *  $RCSfile: atrflyin.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:27 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "hintids.hxx"
+#include "cntfrm.hxx"       // _GetFly
+#include "doc.hxx"
+#include "pam.hxx"          // fuer SwTxtFlyCnt
+#include "flyfrm.hxx"       // fuer SwTxtFlyCnt
+#include "ndtxt.hxx"        // SwFlyFrmFmt
+#include "frmfmt.hxx"       // SwFlyFrmFmt
+
+#ifndef _FMTFLCNT_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFLCNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#include "swfont.hxx"
+#include "txtfrm.hxx"
+#include "flyfrms.hxx"
+
+SwFmtFlyCnt::SwFmtFlyCnt( SwFrmFmt *pFrmFmt )
+    : SfxPoolItem( RES_TXTATR_FLYCNT ),
+    pFmt( pFrmFmt ),
+    pTxtAttr( 0 )
+{
+}
+
+int __EXPORT SwFmtFlyCnt::operator==( const SfxPoolItem& rAttr ) const
+{
+    ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" );
+    return( pTxtAttr && ((SwFmtFlyCnt&)rAttr).pTxtAttr &&
+            *pTxtAttr->GetStart() == *((SwFmtFlyCnt&)rAttr).pTxtAttr->GetStart() &&
+            pFmt == ((SwFmtFlyCnt&)rAttr).GetFrmFmt() );
+}
+
+SfxPoolItem* __EXPORT SwFmtFlyCnt::Clone( SfxItemPool* ) const
+{
+    return new SwFmtFlyCnt( pFmt );
+}
+
+SwTxtFlyCnt::SwTxtFlyCnt( const SwFmtFlyCnt& rAttr, xub_StrLen nStart )
+    : SwTxtAttr( rAttr, nStart )
+{
+    ((SwFmtFlyCnt&)rAttr).pTxtAttr = this;
+}
+
+
+
+/*************************************************************************
+ *                  SwTxtFlyCnt::MakeTxtHint()
+ *
+ * An dieser Stelle soll einmal der Gesamtzusammenhang bei der Erzeugung
+ * eines neuen SwTxtFlyCnt erlaeutert werden.
+ * Das MakeTxtHint() wird z.B. im SwTxtNode::Copy() gerufen.
+ * Fuer die komplette Verdopplung sind folgende Schritte notwendig:
+ * 1) Duplizieren des pFmt incl. Inhalt, Attributen etc.
+ * 2) Setzen des Ankers
+ * 3) Benachrichtigung
+ * Da fuer die Bewaeltigung der Aufgaben nicht immer alle Informationen
+ * bereitstehen und darueber hinaus bestimmte Methoden erst zu einem
+ * spaeteren Zeitpunkt gerufen werden duerfen (weil nocht nicht alle
+ * Nodeinformationen vorliegen), verteilt sich der Ablauf.
+ * ad 1) MakeTxtHint() wird durch den Aufruf von SwDoc::CopyLayout()
+ * der das neue FlyFrmFmt erzeugt und mit dem duplizierten Inhalt des
+ * FlyFrm verbunden.
+ * ad 2) SetAnchor() wird von SwTxtNode::Insert() gerufen und sorgt fuer das
+ * setzen des Ankers (die SwPosition des Dummy-Zeichens wird dem FlyFrmFmt
+ * per SetAttr bekannt gegeben). Dies kann nicht im MakeTxtHint erledigt
+ * werden, da der Zielnode unbestimmt ist.
+ * ad 3) _GetFlyFrm() wird im Formatierungsprozess vom LineIter gerufen
+ * und sucht den FlyFrm zum Dummyzeichen des aktuellen CntntFrm. Wird keiner
+ * gefunden, so wird ein neuer FlyFrm angelegt.
+ * Kritisch an diesem Vorgehen ist, dass das pCntnt->AppendFly() eine
+ * sofortige Neuformatierung von pCntnt anstoesst. Die Rekursion kommt
+ * allerdings durch den Lockmechanismus in SwTxtFrm::Format() nicht
+ * zu stande.
+ * Attraktiv ist der Umstand, dass niemand ueber die vom Node abhaengigen
+ * CntntFrms iterieren braucht, um die FlyInCntFrm anzulegen. Dies geschieht
+ * bei der Arbeit.
+ *************************************************************************/
+
+void SwTxtFlyCnt::CopyFlyFmt( SwDoc* pDoc )
+{
+    SwFrmFmt* pFmt = GetFlyCnt().GetFrmFmt();
+    ASSERT( pFmt, "von welchem Format soll ich eine Kopie erzeugen?" )
+    // Das FlyFrmFmt muss dupliziert werden.
+    // In CopyLayoutFmt (siehe doclay.cxx) wird das FlyFrmFmt erzeugt
+    // und der Inhalt dupliziert.
+
+    // fuers kopieren vom Attribut das Undo immer abschalten
+    BOOL bUndo = pDoc->DoesUndo();
+    pDoc->DoUndo( FALSE );
+    SwFmtAnchor aAnchor( pFmt->GetAnchor() );
+    if( FLY_PAGE != aAnchor.GetAnchorId() &&
+        pDoc != pFmt->GetDoc() )        // Unterschiedliche Docs?
+    {
+        // JP 03.06.96: dann sorge dafuer, das der koperierte Anker auf
+        //              gueltigen Content zeigt! Die Umsetzung auf die
+        //              richtige Position erfolgt spaeter.
+        SwNodeIndex aIdx( pDoc->GetNodes().GetEndOfExtras(), +2 );
+        SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
+        if( !pCNd )
+            pCNd = pDoc->GetNodes().GoNext( &aIdx );
+
+        SwPosition* pPos = (SwPosition*)aAnchor.GetCntntAnchor();
+        pPos->nNode = aIdx;
+        if( FLY_IN_CNTNT == aAnchor.GetAnchorId() )
+            pPos->nContent.Assign( pCNd, 0 );
+        else
+        {
+            pPos->nContent.Assign( 0, 0 );
+            ASSERT( !this, "CopyFlyFmt: Was fuer ein Anker?" );
+        }
+    }
+
+    SwFrmFmt* pNew = pDoc->CopyLayoutFmt( *pFmt, aAnchor, FALSE, FALSE );
+    pDoc->DoUndo( bUndo );
+    ((SwFmtFlyCnt&)GetFlyCnt()).SetFlyFmt( pNew );
+}
+
+/*************************************************************************
+ *                  SwTxtFlyCnt::SetAnchor()
+ *
+ * SetAnchor() wird von SwTxtNode::Insert() gerufen und sorgt fuer das
+ * setzen des Ankers (die SwPosition des Dummy-Zeichens wird dem FlyFrmFmt
+ * per SetAttr bekannt gegeben). Dies kann nicht im MakeTxtHint erledigt
+ * werden, da der Zielnode unbestimmt ist.
+ * (siehe Kommentar in SwTxtFlyCnt::MakeTxtHint)
+ *************************************************************************/
+
+void SwTxtFlyCnt::SetAnchor( const SwTxtNode *pNode )
+{
+    // fuers Undo muss der neue Anker schon bekannt sein !
+
+    // Wir ermitteln den Index im Nodesarray zum Node
+
+    SwDoc* pDoc = (SwDoc*)pNode->GetDoc();
+
+    SwIndex aIdx( (SwTxtNode*)pNode, *GetStart() );
+    SwPosition aPos( *pNode->StartOfSectionNode(), aIdx );
+    SwFrmFmt* pFmt = GetFlyCnt().GetFrmFmt();
+    SwFmtAnchor aAnchor( pFmt->GetAnchor() );
+
+    if( !aAnchor.GetCntntAnchor() ||
+        !aAnchor.GetCntntAnchor()->nNode.GetNode().GetNodes().IsDocNodes() ||
+        &aAnchor.GetCntntAnchor()->nNode.GetNode() != (SwNode*)pNode )
+        aPos.nNode = *pNode;
+    else
+        aPos.nNode = aAnchor.GetCntntAnchor()->nNode;
+
+    aAnchor.SetType( FLY_IN_CNTNT );        // defaulten !!
+    aAnchor.SetAnchor( &aPos );
+
+    // beim Ankerwechsel werden immer alle FlyFrms vom Attribut geloescht
+    // JP 25.04.95: wird innerhalb des SplitNodes die Frames verschoben
+    //              koennen die Frames erhalten bleiben.
+    if( ( !pNode->GetpSwpHints() || !pNode->GetpSwpHints()->IsInSplitNode() )
+        && RES_DRAWFRMFMT != pFmt->Which() )
+        pFmt->DelFrms();
+
+    // stehen wir noch im falschen Dokument ?
+    if( pDoc != pFmt->GetDoc() )
+    {
+        // fuers kopieren vom Attribut das Undo immer abschalten
+        BOOL bUndo = pDoc->DoesUndo();
+        pDoc->DoUndo( FALSE );
+        SwFrmFmt* pNew = pDoc->CopyLayoutFmt( *pFmt, aAnchor, FALSE, FALSE );
+        pDoc->DoUndo( bUndo );
+
+        bUndo = pFmt->GetDoc()->DoesUndo();
+        pFmt->GetDoc()->DoUndo( FALSE );
+        pFmt->GetDoc()->DelLayoutFmt( pFmt );
+        pFmt->GetDoc()->DoUndo( bUndo );
+        ((SwFmtFlyCnt&)GetFlyCnt()).SetFlyFmt( pNew );
+    }
+    else if( pNode->GetpSwpHints() &&
+            pNode->GetpSwpHints()->IsInSplitNode() &&
+            RES_DRAWFRMFMT != pFmt->Which() )
+    {
+        pFmt->LockModify();
+        pFmt->SetAttr( aAnchor );       // nur den Anker neu setzen
+        pFmt->UnlockModify();
+    }
+    else
+        pFmt->SetAttr( aAnchor );       // nur den Anker neu setzen
+
+    // Am Node haengen u.a. abhaengige CntFrms.
+    // Fuer jeden CntFrm wird ein SwFlyInCntFrm angelegt.
+}
+
+/*************************************************************************
+ *                      SwTxtFlyCnt::_GetFlyFrm()
+ *
+ * _GetFlyFrm() wird im Formatierungsprozess vom LineIter gerufen
+ * und sucht den FlyFrm zum Dummyzeichen des aktuellen CntntFrm. Wird keiner
+ * gefunden, so wird ein neuer FlyFrm angelegt.
+ * (siehe Kommentar ind SwTxtFlyCnt::MakeTxtHint)
+ *************************************************************************/
+
+SwFlyInCntFrm *SwTxtFlyCnt::_GetFlyFrm( const SwFrm *pCurrFrm )
+{
+    SwFrmFmt* pFrmFmt = GetFlyCnt().GetFrmFmt();
+    if( RES_DRAWFRMFMT == pFrmFmt->Which() )
+    {
+        ASSERT(  !this, "SwTxtFlyCnt::_GetFlyFrm: DrawInCnt-Baustelle!" );
+        return NULL;
+    }
+
+    SwClientIter aIter( *GetFlyCnt().pFmt );
+    ASSERT( pCurrFrm->IsTxtFrm(), "SwTxtFlyCnt::_GetFlyFrm for TxtFrms only." );
+
+    if( aIter.GoStart() )
+    {
+        SwTxtFrm *pFirst = (SwTxtFrm*)pCurrFrm;
+        while ( pFirst->IsFollow() )
+            pFirst = pFirst->FindMaster();
+        do
+        {   SwFrm * pFrm = PTR_CAST( SwFrm, aIter() );
+            if ( pFrm )
+            {
+                SwTxtFrm *pTmp = pFirst;
+                do
+                {   if( ( (SwFlyFrm*)pFrm )->GetAnchor() == (SwFrm*) pTmp )
+                    {
+                        if ( pTmp != pCurrFrm )
+                        {
+                            pTmp->RemoveFly( (SwFlyFrm*)pFrm );
+                            ((SwTxtFrm*)pCurrFrm)->AppendFly( (SwFlyFrm*)pFrm );
+                        }
+                        return (SwFlyInCntFrm*)pFrm;
+                    }
+                    pTmp = pTmp->GetFollow();
+                } while ( pTmp );
+            }
+        } while( aIter++ );
+    }
+
+    // Wir haben keinen passenden FlyFrm gefunden, deswegen wird ein
+    // neuer angelegt.
+    // Dabei wird eine sofortige Neuformatierung von pCurrFrm angestossen.
+    // Die Rekursion wird durch den Lockmechanismus in SwTxtFrm::Format()
+    // abgewuergt.
+    SwFlyInCntFrm *pFly = new SwFlyInCntFrm( (SwFlyFrmFmt*)pFrmFmt, (SwFrm*)pCurrFrm );
+    ((SwFrm*)pCurrFrm)->AppendFly( pFly );
+    pFly->RegistFlys();
+
+    // 7922: Wir muessen dafuer sorgen, dass der Inhalt des FlyInCnt
+    // nach seiner Konstruktion stramm durchformatiert wird.
+    SwCntntFrm *pFrm = pFly->ContainsCntnt();
+    while( pFrm )
+    {
+        pFrm->Calc();
+        pFrm = pFrm->GetNextCntntFrm();
+    }
+
+    return pFly;
+}
+
+
diff --git a/sw/source/core/txtnode/atrftn.cxx b/sw/source/core/txtnode/atrftn.cxx
new file mode 100644
index 000000000000..f6f5331d4d75
--- /dev/null
+++ b/sw/source/core/txtnode/atrftn.cxx
@@ -0,0 +1,554 @@
+/*************************************************************************
+ *
+ *  $RCSfile: atrftn.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:27 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#define _SVSTDARR_USHORTS
+#define _SVSTDARR_USHORTSSORT
+#include 
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _CNTFRM_HXX
+#include        // ASSERT in ~SwTxtFtn()
+#endif
+#ifndef _PAGEFRM_HXX
+#include       // RemoveFtn()
+#endif
+#ifndef _FMTFTN_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFTN_HXX //autogen
+#include 
+#endif
+#ifndef _FTNIDX_HXX //autogen
+#include 
+#endif
+#ifndef _FTNINFO_HXX //autogen
+#include 
+#endif
+#ifndef _SWFONT_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _POOLFMT_HXX
+#include 
+#endif
+#ifndef _FTNFRM_HXX
+#include 
+#endif
+#ifndef _NDINDEX_HXX
+#include 
+#endif
+#ifndef _FMTFTNTX_HXX //autogen
+#include 
+#endif
+#ifndef _SECTION_HXX
+#include 
+#endif
+
+/*************************************************************************
+|*
+|*    class SwFmtFtn
+|*
+|*    Beschreibung
+|*    Ersterstellung    JP 09.08.94
+|*    Letzte Aenderung  JP 08.08.94
+|*
+*************************************************************************/
+
+
+SwFmtFtn::SwFmtFtn( BOOL bEN )
+    : SfxPoolItem( RES_TXTATR_FTN ),
+    nNumber( 0 ),
+    pTxtAttr( 0 ),
+    bEndNote( bEN )
+{
+}
+
+
+int SwFmtFtn::operator==( const SfxPoolItem& rAttr ) const
+{
+    ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" );
+    return nNumber  == ((SwFmtFtn&)rAttr).nNumber &&
+           aNumber  == ((SwFmtFtn&)rAttr).aNumber &&
+           bEndNote == ((SwFmtFtn&)rAttr).bEndNote;
+}
+
+
+SfxPoolItem* SwFmtFtn::Clone( SfxItemPool* ) const
+{
+    SwFmtFtn* pNew  = new SwFmtFtn;
+    pNew->aNumber   = aNumber;
+    pNew->nNumber   = nNumber;
+    pNew->bEndNote  = bEndNote;
+    return pNew;
+}
+
+void SwFmtFtn::SetEndNote( BOOL b )
+{
+    if ( b != bEndNote )
+    {
+        if ( GetTxtFtn() )
+            GetTxtFtn()->DelFrms();
+        bEndNote = b;
+    }
+}
+
+SwFmtFtn::~SwFmtFtn()
+{
+}
+
+
+void SwFmtFtn::GetFtnText( XubString& rStr ) const
+{
+    if( pTxtAttr->GetStartNode() )
+    {
+        SwNodeIndex aIdx( *pTxtAttr->GetStartNode(), 1 );
+        SwCntntNode* pCNd = aIdx.GetNode().GetTxtNode();
+        if( !pCNd )
+            pCNd = aIdx.GetNodes().GoNext( &aIdx );
+
+        if( pCNd->IsTxtNode() )
+            rStr = ((SwTxtNode*)pCNd)->GetExpandTxt();
+    }
+}
+
+    // returnt den anzuzeigenden String der Fuss-/Endnote
+XubString SwFmtFtn::GetViewNumStr( const SwDoc& rDoc, BOOL bInclStrings ) const
+{
+    XubString sRet( GetNumStr() );
+    if( !sRet.Len() )
+    {
+        // dann ist die Nummer von Interesse, also ueber die Info diese
+        // besorgen.
+        BOOL bMakeNum = TRUE;
+        const SwSectionNode* pSectNd = pTxtAttr
+                    ? SwUpdFtnEndNtAtEnd::FindSectNdWithEndAttr( *pTxtAttr )
+                    : 0;
+
+        if( pSectNd )
+        {
+            const SwFmtFtnEndAtTxtEnd& rFtnEnd = (SwFmtFtnEndAtTxtEnd&)
+                pSectNd->GetSection().GetFmt()->GetAttr(
+                    IsEndNote() ? RES_END_AT_TXTEND : RES_FTN_AT_TXTEND );
+
+            if( FTNEND_ATTXTEND_OWNNUMANDFMT == rFtnEnd.GetValue() )
+            {
+                bMakeNum = FALSE;
+                sRet = rFtnEnd.GetSwNumType().GetNumStr( GetNumber() );
+                if( bInclStrings )
+                {
+                    sRet.Insert( rFtnEnd.GetPrefix(), 0 );
+                    sRet += rFtnEnd.GetSuffix();
+                }
+            }
+        }
+
+        if( bMakeNum )
+        {
+            const SwEndNoteInfo* pInfo;
+            if( IsEndNote() )
+                pInfo = &rDoc.GetEndNoteInfo();
+            else
+                pInfo = &rDoc.GetFtnInfo();
+            sRet = pInfo->aFmt.GetNumStr( GetNumber() );
+            if( bInclStrings )
+            {
+                sRet.Insert( pInfo->GetPrefix(), 0 );
+                sRet += pInfo->GetSuffix();
+            }
+        }
+    }
+    return sRet;
+}
+
+/*************************************************************************
+ *                      class SwTxt/FmtFnt
+ *************************************************************************/
+
+SwTxtFtn::SwTxtFtn( const SwFmtFtn& rAttr, xub_StrLen nStart )
+    : SwTxtAttr( rAttr, nStart ),
+    pMyTxtNd( 0 ),
+    pStartNode( 0 ),
+    nSeqNo( USHRT_MAX )
+{
+    ((SwFmtFtn&)rAttr).pTxtAttr = this;
+}
+
+
+SwTxtFtn::~SwTxtFtn()
+{
+    SetStartNode( 0 );
+}
+
+
+
+void SwTxtFtn::SetStartNode( const SwNodeIndex *pNewNode, BOOL bDelNode )
+{
+    if( pNewNode )
+    {
+        if( !pStartNode )
+            pStartNode = new SwNodeIndex( *pNewNode );
+        else
+            *pStartNode = *pNewNode;
+    }
+    else if( pStartNode )
+    {
+        // Zwei Dinge muessen erledigt werden:
+        // 1) Die Fussnoten muessen bei ihren Seiten abgemeldet werden
+        // 2) Die Fussnoten-Sektion in den Inserts muss geloescht werden.
+        SwDoc* pDoc;
+        if( pMyTxtNd )
+            pDoc = pMyTxtNd->GetDoc();
+        else
+        {
+            //JP 27.01.97: der sw3-Reader setzt einen StartNode aber das
+            //              Attribut ist noch nicht im TextNode verankert.
+            //              Wird es geloescht (z.B. bei Datei einfuegen mit
+            //              Ftn in einen Rahmen), muss auch der Inhalt
+            //              geloescht werden
+            pDoc = pStartNode->GetNodes().GetDoc();
+        }
+
+        // Wir duerfen die Fussnotennodes nicht loeschen
+        // und brauchen die Fussnotenframes nicht loeschen, wenn
+        // wir im ~SwDoc() stehen.
+        if( !pDoc->IsInDtor() )
+        {
+            if( bDelNode )
+            {
+                // 1) Die Section fuer die Fussnote wird beseitigt
+                // Es kann sein, dass die Inserts schon geloescht wurden.
+                pDoc->DeleteSection( &pStartNode->GetNode() );
+            }
+            else
+                // Werden die Nodes nicht geloescht mussen sie bei den Seiten
+                // abmeldet (Frms loeschen) werden, denn sonst bleiben sie
+                // stehen (Undo loescht sie nicht!)
+                DelFrms();
+        }
+        DELETEZ( pStartNode );
+
+        // loesche die Fussnote noch aus dem Array am Dokument
+        for( USHORT n = 0; n < pDoc->GetFtnIdxs().Count(); ++n )
+            if( this == pDoc->GetFtnIdxs()[n] )
+            {
+                pDoc->GetFtnIdxs().Remove( n );
+                // gibt noch weitere Fussnoten
+                if( !pDoc->IsInDtor() && n < pDoc->GetFtnIdxs().Count() )
+                {
+                    SwNodeIndex aTmp( pDoc->GetFtnIdxs()[n]->GetTxtNode() );
+                    pDoc->GetFtnIdxs().UpdateFtn( aTmp );
+                }
+                break;
+            }
+    }
+}
+
+
+void SwTxtFtn::SetNumber( const USHORT nNewNum, const XubString* pStr )
+{
+    SwFmtFtn& rFtn = (SwFmtFtn&)GetFtn();
+    if( pStr && pStr->Len() )
+        rFtn.aNumber = *pStr;
+    else
+    {
+        rFtn.nNumber = nNewNum;
+        rFtn.aNumber = aEmptyStr;
+    }
+
+    ASSERT( pMyTxtNd, "wo ist mein TextNode?" );
+    SwNodes &rNodes = pMyTxtNd->GetDoc()->GetNodes();
+    pMyTxtNd->Modify( 0, &rFtn );
+    if( pStartNode )
+    {
+        // Wir muessen ueber alle TxtNodes iterieren, wegen der
+        // Fussnoten, die auf anderen Seiten stehen.
+        SwNode* pNd;
+        ULONG nSttIdx = pStartNode->GetIndex() + 1,
+              nEndIdx = pStartNode->GetNode().EndOfSectionIndex();
+        for( ; nSttIdx < nEndIdx; ++nSttIdx )
+        {
+            // Es koennen ja auch Grafiken in der Fussnote stehen ...
+            if( ( pNd = rNodes[ nSttIdx ] )->IsTxtNode() )
+                ((SwTxtNode*)pNd)->Modify( 0, &rFtn );
+        }
+    }
+}
+
+// Die Fussnoten duplizieren
+void SwTxtFtn::CopyFtn( SwTxtFtn *pDest )
+{
+    if( pStartNode && pDest->GetStartNode() )
+    {
+        // die Fussnoten koennen in unterschiedlichen Dokumenten stehen !!
+        SwNodes &rSrcNodes = pMyTxtNd->GetDoc()->GetNodes();
+        SwDoc* pDstDoc = pDest->pMyTxtNd->GetDoc();
+        SwNodes &rDstNodes = pDstDoc->GetNodes();
+
+        // Wir kopieren nur den Inhalt der Sektion
+        SwNodeRange aRg( *pStartNode, 1,
+                    *pStartNode->GetNode().EndOfSectionNode() );
+
+        // Wir fuegen auf dem Ende von pDest ein, d.h. die Nodes
+        // werden angehaengt. nDestLen haelt die Anzahl der CntNodes
+        // in pDest _vor_ dem Kopieren.
+        SwNodeIndex aStart( *(pDest->GetStartNode()) );
+        SwNodeIndex aEnd( *aStart.GetNode().EndOfSectionNode() );
+        ULONG  nDestLen = aEnd.GetIndex() - aStart.GetIndex() - 1;
+
+        pMyTxtNd->GetDoc()->CopyWithFlyInFly( aRg, aEnd, TRUE );
+
+        // Wenn die Dest-Sektion nicht leer war, so muessen die alten
+        // Nodes geloescht werden:
+        // Vorher:   Src: SxxxE,  Dst: SnE
+        // Nachher:  Src: SxxxE,  Dst: SnxxxE
+        // und       Src: SxxxE,  Dst: SxxxE
+        aStart++;
+        rDstNodes.Delete( aStart, nDestLen );
+    }
+
+    // Der benutzerdefinierte String muss auch uebertragen werden.
+    if( GetFtn().aNumber.Len() )
+        ((SwFmtFtn&)pDest->GetFtn()).aNumber = GetFtn().aNumber;
+}
+
+
+    // lege eine neue leere TextSection fuer diese Fussnote an
+void SwTxtFtn::MakeNewTextSection( SwNodes& rNodes )
+{
+    if( pStartNode )
+        return;
+
+    // Nun verpassen wir dem TxtNode noch die Fussnotenvorlage.
+    SwTxtFmtColl *pFmtColl;
+    const SwEndNoteInfo* pInfo;
+    USHORT nPoolId;
+
+    if( GetFtn().IsEndNote() )
+    {
+        pInfo = &rNodes.GetDoc()->GetEndNoteInfo();
+        nPoolId = RES_POOLCOLL_ENDNOTE;
+    }
+    else
+    {
+        pInfo = &rNodes.GetDoc()->GetFtnInfo();
+        nPoolId = RES_POOLCOLL_FOOTNOTE;
+    }
+
+    if( 0 == (pFmtColl = pInfo->GetFtnTxtColl() ) )
+        pFmtColl = rNodes.GetDoc()->GetTxtCollFromPool( nPoolId );
+
+    SwStartNode* pSttNd = rNodes.MakeTextSection( SwNodeIndex( rNodes.GetEndOfInserts() ),
+                                        SwFootnoteStartNode, pFmtColl );
+    pStartNode = new SwNodeIndex( *pSttNd );
+}
+
+
+void SwTxtFtn::DelFrms()
+{
+    // loesche die Ftn-Frames aus den Seiten
+    ASSERT( pMyTxtNd, "wo ist mein TextNode?" );
+    if( !pMyTxtNd )
+        return ;
+
+    BOOL bFrmFnd = FALSE;
+    {
+        SwClientIter aIter( *pMyTxtNd );
+        for( SwCntntFrm* pFnd = (SwCntntFrm*)aIter.First( TYPE( SwCntntFrm ));
+                pFnd; pFnd = (SwCntntFrm*)aIter.Next() )
+        {
+            pFnd->FindPageFrm()->RemoveFtn( pFnd, this );
+            bFrmFnd = TRUE;
+        }
+    }
+    //JP 13.05.97: falls das Layout vorm loeschen der Fussnoten entfernt
+    //              wird, sollte man das ueber die Fussnote selbst tun
+    if( !bFrmFnd && pStartNode )
+    {
+        SwNodeIndex aIdx( *pStartNode );
+        SwCntntNode* pCNd = pMyTxtNd->GetNodes().GoNext( &aIdx );
+        if( pCNd )
+        {
+            SwClientIter aIter( *pCNd );
+            for( SwCntntFrm* pFnd = (SwCntntFrm*)aIter.First( TYPE( SwCntntFrm ));
+                    pFnd; pFnd = (SwCntntFrm*)aIter.Next() )
+            {
+                SwPageFrm* pPage = pFnd->FindPageFrm();
+
+                SwFrm *pFrm = pFnd->GetUpper();
+                while ( pFrm && !pFrm->IsFtnFrm() )
+                    pFrm = pFrm->GetUpper();
+
+                SwFtnFrm *pFtn = (SwFtnFrm*)pFrm;
+                while ( pFtn && pFtn->GetMaster() )
+                    pFtn = pFtn->GetMaster();
+                ASSERT( pFtn->GetAttr() == this, "Ftn mismatch error." );
+
+                while ( pFtn )
+                {
+                    SwFtnFrm *pFoll = pFtn->GetFollow();
+                    pFtn->Cut();
+                    delete pFtn;
+                    pFtn = pFoll;
+                }
+                pPage->UpdateFtnNum();
+            }
+        }
+    }
+}
+
+
+USHORT SwTxtFtn::SetSeqRefNo()
+{
+    if( !pMyTxtNd )
+        return USHRT_MAX;
+
+    SwDoc* pDoc = pMyTxtNd->GetDoc();
+    if( pDoc->IsInReading() )
+        return USHRT_MAX;
+
+    USHORT n, nFtnCnt = pDoc->GetFtnIdxs().Count();
+
+    BYTE nTmp = 255 < nFtnCnt ? 255 : nFtnCnt;
+    SvUShortsSort aArr( nTmp, nTmp );
+
+    // dann testmal, ob die Nummer schon vergeben ist oder ob eine neue
+    // bestimmt werden muss.
+    SwTxtFtn* pTxtFtn;
+    for( n = 0; n < nFtnCnt; ++n )
+        if( (pTxtFtn = pDoc->GetFtnIdxs()[ n ]) != this )
+            aArr.Insert( pTxtFtn->nSeqNo );
+
+    // teste erstmal ob die Nummer schon vorhanden ist:
+    if( USHRT_MAX != nSeqNo )
+    {
+        for( n = 0; n < aArr.Count(); ++n )
+            if( aArr[ n ] > nSeqNo )
+                return nSeqNo;          // nicht vorhanden -> also benutzen
+            else if( aArr[ n ] == nSeqNo )
+                break;                  // schon vorhanden -> neue erzeugen
+
+        if( n == aArr.Count() )
+            return nSeqNo;          // nicht vorhanden -> also benutzen
+    }
+
+    // alle Nummern entsprechend geflag, also bestimme die richtige Nummer
+    for( n = 0; n < aArr.Count(); ++n )
+        if( n != aArr[ n ] )
+            break;
+
+    return nSeqNo = n;
+}
+
+void SwTxtFtn::SetUniqueSeqRefNo( SwDoc& rDoc )
+{
+    USHORT n, nStt = 0, nFtnCnt = rDoc.GetFtnIdxs().Count();
+
+    BYTE nTmp = 255 < nFtnCnt ? 255 : nFtnCnt;
+    SvUShortsSort aArr( nTmp, nTmp );
+
+    // dann alle Nummern zusammensammeln die schon existieren
+    SwTxtFtn* pTxtFtn;
+    for( n = 0; n < nFtnCnt; ++n )
+        if( USHRT_MAX != (pTxtFtn = rDoc.GetFtnIdxs()[ n ])->nSeqNo )
+            aArr.Insert( pTxtFtn->nSeqNo );
+
+
+    for( n = 0; n < nFtnCnt; ++n )
+        if( USHRT_MAX == (pTxtFtn = rDoc.GetFtnIdxs()[ n ])->nSeqNo )
+        {
+            for( ; nStt < aArr.Count(); ++nStt )
+                if( nStt != aArr[ nStt ] )
+                {
+
+                    pTxtFtn->nSeqNo = nStt;
+                    break;
+                }
+
+            if( USHRT_MAX == pTxtFtn->nSeqNo )
+                break;  // nichts mehr gefunden
+        }
+
+    // alle Nummern schon vergeben, also mit nStt++ weitermachen
+    for( ; n < nFtnCnt; ++n )
+        if( USHRT_MAX == (pTxtFtn = rDoc.GetFtnIdxs()[ n ])->nSeqNo )
+            pTxtFtn->nSeqNo = nStt++;
+}
+
+void SwTxtFtn::CheckCondColl()
+{
+//FEATURE::CONDCOLL
+    if( GetStartNode() )
+        ((SwStartNode&)GetStartNode()->GetNode()).CheckSectionCondColl();
+//FEATURE::CONDCOLL
+}
+
+
+
+
diff --git a/sw/source/core/txtnode/atrref.cxx b/sw/source/core/txtnode/atrref.cxx
new file mode 100644
index 000000000000..2568d1816c4a
--- /dev/null
+++ b/sw/source/core/txtnode/atrref.cxx
@@ -0,0 +1,151 @@
+/*************************************************************************
+ *
+ *  $RCSfile: atrref.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:27 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include 
+
+#ifndef _TXTRFMRK_HXX //autogen
+#include 
+#endif
+#ifndef _FMTRFMRK_HXX //autogen
+#include 
+#endif
+#include "swfont.hxx"
+
+
+/****************************************************************************
+ *
+ *  class SwFmtRefMark
+ *
+ ****************************************************************************/
+
+SwFmtRefMark::~SwFmtRefMark( )
+{
+}
+
+SwFmtRefMark::SwFmtRefMark( const XubString& rName )
+    : SfxPoolItem( RES_TXTATR_REFMARK ),
+    aRefName( rName ),
+    pTxtAttr( 0 )
+{
+}
+
+SwFmtRefMark::SwFmtRefMark( const SwFmtRefMark& rAttr )
+    : SfxPoolItem( RES_TXTATR_REFMARK ),
+    aRefName( rAttr.aRefName ),
+    pTxtAttr( 0 )
+{
+}
+
+int SwFmtRefMark::operator==( const SfxPoolItem& rAttr ) const
+{
+    ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" );
+    return aRefName == ((SwFmtRefMark&)rAttr).aRefName;
+}
+
+SfxPoolItem* SwFmtRefMark::Clone( SfxItemPool* ) const
+{
+    return new SwFmtRefMark( *this );
+}
+
+/*************************************************************************
+ *                      class SwTxtRefMark
+ *************************************************************************/
+
+// Attribut fuer Inhalts-/Positions-Referenzen im Text
+
+SwTxtRefMark::SwTxtRefMark( const SwFmtRefMark& rAttr,
+                    xub_StrLen nStart, xub_StrLen* pEnde )
+    : SwTxtAttrEnd( rAttr, nStart, nStart ),
+    pEnd( 0 ),
+    pMyTxtNd( 0 )
+{
+    ((SwFmtRefMark&)rAttr).pTxtAttr = this;
+    if( pEnde )
+    {
+        nEnd = *pEnde;
+        pEnd = &nEnd;
+    }
+}
+
+xub_StrLen* SwTxtRefMark::GetEnd()
+{
+    return pEnd;
+}
+
+void SwTxtRefMark::ChgFnt( SwFont * pFont )
+{
+    ASSERT( pFont->GetRef()<255, "ChgFnt: Ref-Schachtelungstiefe zu gross" );
+    pFont->GetRef()++;
+}
+
+void SwTxtRefMark::RstFnt( SwFont * pFont )
+{
+    ASSERT( pFont->GetRef(), "RstFnt: Ref-Rst ohne Ref-Chg?" );
+    pFont->GetRef()--;
+}
+
+
diff --git a/sw/source/core/txtnode/atrtox.cxx b/sw/source/core/txtnode/atrtox.cxx
new file mode 100644
index 000000000000..fe4edac36b0a
--- /dev/null
+++ b/sw/source/core/txtnode/atrtox.cxx
@@ -0,0 +1,144 @@
+/*************************************************************************
+ *
+ *  $RCSfile: atrtox.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:27 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "doc.hxx"
+
+#ifndef _TXTTXMRK_HXX //autogen
+#include 
+#endif
+#include "swfont.hxx"
+#include "tox.hxx"
+#include "ndtxt.hxx"
+
+SwTxtTOXMark::SwTxtTOXMark( const SwTOXMark& rAttr,
+                    xub_StrLen nStart, xub_StrLen* pEnde )
+    : SwTxtAttrEnd( rAttr, nStart, nStart ),
+    pEnd( 0 ),
+    pMyTxtNd( 0 )
+{
+    ((SwTOXMark&)rAttr).pTxtAttr = this;
+    if( !rAttr.GetAlternativeText().Len() )
+    {
+        nEnd = *pEnde;
+        pEnd = &nEnd;
+    }
+}
+
+SwTxtTOXMark::~SwTxtTOXMark()
+{
+}
+
+xub_StrLen* SwTxtTOXMark::GetEnd()
+{
+    return pEnd;
+}
+
+void SwTxtTOXMark::ChgFnt(SwFont *pFont)
+{
+    ASSERT( pFont->GetTox()<255, "ChgFnt: Tox-Schachtelungstiefe zu gross" );
+    pFont->GetTox()++;
+}
+
+void SwTxtTOXMark::RstFnt(SwFont *pFont)
+{
+    ASSERT( pFont->GetTox(), "RstFnt: Tox-Rst ohne Tox-Chg?" );
+    pFont->GetTox()--;
+}
+
+void SwTxtTOXMark::CopyTOXMark( SwDoc* pDoc )
+{
+    SwTOXMark& rTOX = (SwTOXMark&)GetTOXMark();
+    TOXTypes    eType   = rTOX.GetTOXType()->GetType();
+    USHORT      nCount  = pDoc->GetTOXTypeCount( eType );
+    const SwTOXType* pType = 0;
+    const XubString& rNm = rTOX.GetTOXType()->GetTypeName();
+
+    // kein entsprechender Verzeichnistyp vorhanden -> anlegen
+    // sonst verwenden
+    for(USHORT i=0; i < nCount; ++i)
+    {
+        const SwTOXType* pSrcType = pDoc->GetTOXType(eType, i);
+        if(pSrcType->GetTypeName() == rNm )
+        {
+            pType = pSrcType;
+            break;
+        }
+    }
+    // kein entsprechender Typ vorhanden -> neu erzeugen
+    //
+    if(!pType)
+    {
+        pDoc->InsertTOXType( SwTOXType( eType, rNm ) );
+        pType = pDoc->GetTOXType(eType, 0);
+    }
+    // Verzeichnistyp umhaengen
+    //
+    ((SwTOXType*)pType)->Add( &rTOX );
+}
+
+
+
diff --git a/sw/source/core/txtnode/chrfmt.cxx b/sw/source/core/txtnode/chrfmt.cxx
new file mode 100644
index 000000000000..788bb7b5f4b9
--- /dev/null
+++ b/sw/source/core/txtnode/chrfmt.cxx
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ *  $RCSfile: chrfmt.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:27 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _CHARFMT_HXX
+#include 
+#endif
+
+
+TYPEINIT1( SwCharFmt, SwFmt );  //rtti fuer SwCharFmt
+
+
+
diff --git a/sw/source/core/txtnode/fmtatr1.cxx b/sw/source/core/txtnode/fmtatr1.cxx
new file mode 100644
index 000000000000..61b1f69c42f7
--- /dev/null
+++ b/sw/source/core/txtnode/fmtatr1.cxx
@@ -0,0 +1,133 @@
+/*************************************************************************
+ *
+ *  $RCSfile: fmtatr1.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:27 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include 
+#ifndef _ERRHDL_HXX //autogen
+#include 
+#endif
+#ifndef _FMTHBSH_HXX //autogen
+#include 
+#endif
+
+
+/*************************************************************************
+|*
+|*    class SwFmtHardBlank
+|*
+|*    Beschreibung      Dokument 1.20
+|*    Ersterstellung    JP 23.11.90
+|*    Letzte Aenderung  JP 20.02.91
+|*
+*************************************************************************/
+
+SwFmtHardBlank::SwFmtHardBlank( sal_Unicode cCh, BOOL bCheck )
+    : SfxPoolItem( RES_TXTATR_HARDBLANK ),
+    cChar( cCh )
+{
+    ASSERT( !bCheck || (' ' != cCh && '-' != cCh),
+            "Invalid character for the HardBlank attribute - "
+            "must be a normal unicode character" );
+}
+
+int SwFmtHardBlank::operator==( const SfxPoolItem& rAttr ) const
+{
+    ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" );
+    return cChar == ((SwFmtHardBlank&)rAttr).GetChar();
+}
+
+SfxPoolItem* SwFmtHardBlank::Clone( SfxItemPool* ) const
+{
+    return new SwFmtHardBlank( *this );
+}
+
+/*************************************************************************
+|*
+|*    class SwFmtSoftHyph
+|*
+|*    Beschreibung      Dokument 1.20
+|*    Ersterstellung    JP 23.11.90
+|*    Letzte Aenderung  JP 20.02.91
+|*
+*************************************************************************/
+
+SwFmtSoftHyph::SwFmtSoftHyph()
+    : SfxPoolItem( RES_TXTATR_SOFTHYPH )
+{
+}
+
+int SwFmtSoftHyph::operator==( const SfxPoolItem& rAttr ) const
+{
+    ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" );
+    return TRUE;
+}
+
+SfxPoolItem* SwFmtSoftHyph::Clone( SfxItemPool* ) const
+{
+    return new SwFmtSoftHyph( *this );
+}
+
+
diff --git a/sw/source/core/txtnode/fmtatr2.cxx b/sw/source/core/txtnode/fmtatr2.cxx
new file mode 100644
index 000000000000..299b7a27a869
--- /dev/null
+++ b/sw/source/core/txtnode/fmtatr2.cxx
@@ -0,0 +1,381 @@
+/*************************************************************************
+ *
+ *  $RCSfile: fmtatr2.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:27 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "hintids.hxx"
+#include "unomid.h"
+
+#ifndef __SBX_SBXVARIABLE_HXX //autogen
+#include 
+#endif
+#ifndef _SFXMACITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SFXSTRITEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _FCHRFMT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTINFMT_HXX //autogen
+#include 
+#endif
+#ifndef _TXTATR_HXX //autogen
+#include 
+#endif
+#include "cmdid.h"
+#include "charfmt.hxx"
+#include "hints.hxx"        // SwUpdateAttr
+#ifndef _COM_SUN_STAR_UNO_ANY_H_
+#include 
+#endif
+#ifndef _UNOSTYLE_HXX
+#include 
+#endif
+
+
+using namespace ::com::sun::star;
+using namespace ::rtl;
+
+/*************************************************************************
+|*
+|*    class SwFmtCharFmt
+|*    Beschreibung
+|*    Ersterstellung    JP 23.11.90
+|*    Letzte Aenderung  JP 09.08.94
+|*
+*************************************************************************/
+
+
+
+SwFmtCharFmt::SwFmtCharFmt( SwCharFmt *pFmt )
+    : SfxPoolItem( RES_TXTATR_CHARFMT ),
+    SwClient(pFmt),
+    pTxtAttr( 0 )
+{
+}
+
+
+
+SwFmtCharFmt::SwFmtCharFmt( const SwFmtCharFmt& rAttr )
+    : SfxPoolItem( RES_TXTATR_CHARFMT ),
+    SwClient( rAttr.GetCharFmt() ),
+    pTxtAttr( 0 )
+{
+}
+
+
+
+SwFmtCharFmt::~SwFmtCharFmt() {}
+
+
+
+int SwFmtCharFmt::operator==( const SfxPoolItem& rAttr ) const
+{
+    ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" );
+    return GetCharFmt() == ((SwFmtCharFmt&)rAttr).GetCharFmt();
+}
+
+
+
+SfxPoolItem* SwFmtCharFmt::Clone( SfxItemPool* ) const
+{
+    return new SwFmtCharFmt( *this );
+}
+
+
+
+// weiterleiten an das TextAttribut
+void SwFmtCharFmt::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew )
+{
+    if( pTxtAttr )
+        pTxtAttr->Modify( pOld, pNew );
+}
+
+
+
+// weiterleiten an das TextAttribut
+BOOL SwFmtCharFmt::GetInfo( SfxPoolItem& rInfo ) const
+{
+    return pTxtAttr ? pTxtAttr->GetInfo( rInfo ) : FALSE;
+}
+BOOL SwFmtCharFmt::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+    XubString sCharFmtName;
+    if(GetCharFmt())
+        sCharFmtName = SwXStyleFamilies::GetProgrammaticName(GetCharFmt()->GetName(), SFX_STYLE_FAMILY_CHAR );
+    rVal <<= OUString( sCharFmtName );
+    return TRUE;
+}
+BOOL SwFmtCharFmt::PutValue( const uno::Any& rVal, BYTE nMemberId  )
+{
+    DBG_ERROR("Zeichenvorlage kann mit PutValue nicht gesetzt werden!")
+    return FALSE;
+}
+
+/*************************************************************************
+|*
+|*    class SwFmtINetFmt
+|*    Beschreibung
+|*    Ersterstellung    AMA 02.08.96
+|*    Letzte Aenderung  AMA 02.08.96
+|*
+*************************************************************************/
+
+
+
+SwFmtINetFmt::SwFmtINetFmt( const XubString& rURL, const XubString& rTarget )
+    : SfxPoolItem( RES_TXTATR_INETFMT ),
+    aURL( rURL ),
+    aTargetFrame( rTarget ),
+    pTxtAttr( 0 ),
+    pMacroTbl( 0 ),
+    nINetId( 0 ),
+    nVisitedId( 0 )
+{
+}
+
+
+
+SwFmtINetFmt::SwFmtINetFmt( const SwFmtINetFmt& rAttr )
+    : SfxPoolItem( RES_TXTATR_INETFMT ),
+    aURL( rAttr.GetValue() ),
+    aName( rAttr.aName ),
+    aTargetFrame( rAttr.aTargetFrame ),
+    aINetFmt( rAttr.aINetFmt ),
+    aVisitedFmt( rAttr.aVisitedFmt ),
+    pTxtAttr( 0 ),
+    pMacroTbl( 0 ),
+    nINetId( rAttr.nINetId ),
+    nVisitedId( rAttr.nVisitedId )
+{
+    if( rAttr.GetMacroTbl() )
+        pMacroTbl = new SvxMacroTableDtor( *rAttr.GetMacroTbl() );
+}
+
+
+
+SwFmtINetFmt::~SwFmtINetFmt()
+{
+    delete pMacroTbl;
+}
+
+
+
+int SwFmtINetFmt::operator==( const SfxPoolItem& rAttr ) const
+{
+    ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" );
+    BOOL bRet = SfxPoolItem::operator==( (SfxPoolItem&) rAttr )
+                && aURL == ((SwFmtINetFmt&)rAttr).aURL
+                && aName == ((SwFmtINetFmt&)rAttr).aName
+                && aTargetFrame == ((SwFmtINetFmt&)rAttr).aTargetFrame
+                && aINetFmt == ((SwFmtINetFmt&)rAttr).aINetFmt
+                && aVisitedFmt == ((SwFmtINetFmt&)rAttr).aVisitedFmt
+                && nINetId == ((SwFmtINetFmt&)rAttr).nINetId
+                && nVisitedId == ((SwFmtINetFmt&)rAttr).nVisitedId;
+
+    if( !bRet )
+        return FALSE;
+
+    const SvxMacroTableDtor* pOther = ((SwFmtINetFmt&)rAttr).pMacroTbl;
+    if( !pMacroTbl )
+        return ( !pOther || !pOther->Count() );
+    if( !pOther )
+        return 0 == pMacroTbl->Count();
+
+    const SvxMacroTableDtor& rOwn = *pMacroTbl;
+    const SvxMacroTableDtor& rOther = *pOther;
+
+    // Anzahl unterschiedlich => auf jeden Fall ungleich
+    if( rOwn.Count() != rOther.Count() )
+        return FALSE;
+
+    // einzeln vergleichen; wegen Performance ist die Reihenfolge wichtig
+    for( USHORT nNo = 0; nNo < rOwn.Count(); ++nNo )
+    {
+        const SvxMacro *pOwnMac = rOwn.GetObject(nNo);
+        const SvxMacro *pOtherMac = rOther.GetObject(nNo);
+        if (    rOwn.GetKey(pOwnMac) != rOther.GetKey(pOtherMac)  ||
+                pOwnMac->GetLibName() != pOtherMac->GetLibName() ||
+                pOwnMac->GetMacName() != pOtherMac->GetMacName() )
+            return FALSE;
+    }
+    return TRUE;
+}
+
+
+
+SfxPoolItem* SwFmtINetFmt::Clone( SfxItemPool* ) const
+{
+    return new SwFmtINetFmt( *this );
+}
+
+
+
+void SwFmtINetFmt::SetMacroTbl( const SvxMacroTableDtor* pNewTbl )
+{
+    if( pNewTbl )
+    {
+        if( pMacroTbl )
+            *pMacroTbl = *pNewTbl;
+        else
+            pMacroTbl = new SvxMacroTableDtor( *pNewTbl );
+    }
+    else if( pMacroTbl )
+        delete pMacroTbl, pMacroTbl = 0;
+}
+
+
+
+void SwFmtINetFmt::SetMacro( USHORT nEvent, const SvxMacro& rMacro )
+{
+    if( !pMacroTbl )
+        pMacroTbl = new SvxMacroTableDtor;
+
+    SvxMacro *pOldMacro;
+    if( 0 != ( pOldMacro = pMacroTbl->Get( nEvent )) )
+    {
+        delete pOldMacro;
+        pMacroTbl->Replace( nEvent, new SvxMacro( rMacro ) );
+    }
+    else
+        pMacroTbl->Insert( nEvent, new SvxMacro( rMacro ) );
+}
+
+
+
+const SvxMacro* SwFmtINetFmt::GetMacro( USHORT nEvent ) const
+{
+    const SvxMacro* pRet = 0;
+    if( pMacroTbl && pMacroTbl->IsKeyValid( nEvent ) )
+        pRet = pMacroTbl->Get( nEvent );
+    return pRet;
+}
+
+
+
+BOOL SwFmtINetFmt::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
+{
+    BOOL bRet = TRUE;
+    XubString sVal;
+    switch(nMemberId)
+    {
+        case MID_URL_URL:
+            sVal = aURL;
+        break;
+        case MID_URL_TARGET:
+            sVal = aTargetFrame;
+        break;
+        case MID_URL_HYPERLINKNAME:
+            sVal = aName;
+        break;
+        case MID_URL_VISITED_FMT    :
+            sVal = aVisitedFmt;
+        break;
+        case MID_URL_UNVISITED_FMT   :
+            sVal = aINetFmt;
+        break;
+        default:
+            bRet = FALSE;
+    }
+    rVal <<= OUString(sVal);
+    return bRet;
+}
+BOOL SwFmtINetFmt::PutValue( const uno::Any& rVal, BYTE nMemberId  )
+{
+    BOOL bRet = TRUE;
+    if(rVal.getValueType() != ::getCppuType((rtl::OUString*)0))
+        return FALSE;
+    XubString sVal = *(rtl::OUString*)rVal.getValue();
+    switch(nMemberId)
+    {
+        case MID_URL_URL:
+            aURL = sVal;
+        break;
+        case MID_URL_TARGET:
+            aTargetFrame = sVal;
+        break;
+        case MID_URL_HYPERLINKNAME:
+             aName = sVal;
+        break;
+        case MID_URL_VISITED_FMT:
+            aVisitedFmt = sVal;
+            nVisitedId = USHRT_MAX;
+        break;
+        case MID_URL_UNVISITED_FMT:
+            aINetFmt = sVal;
+            nINetId = USHRT_MAX;
+        break;
+        default:
+            bRet = FALSE;
+    }
+    return bRet;
+}
+
+
+
+
diff --git a/sw/source/core/txtnode/fntcache.cxx b/sw/source/core/txtnode/fntcache.cxx
new file mode 100644
index 000000000000..cff18949a6c2
--- /dev/null
+++ b/sw/source/core/txtnode/fntcache.cxx
@@ -0,0 +1,1208 @@
+/*************************************************************************
+ *
+ *  $RCSfile: fntcache.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:27 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _OUTDEV_HXX //autogen
+#include 
+#endif
+#ifndef _PRINT_HXX //autogen
+#include 
+#endif
+#ifndef _METRIC_HXX //autogen
+#include 
+#endif
+#ifndef _WINDOW_HXX //autogen
+#include 
+#endif
+#ifndef _SV_SVAPP_HXX
+#include 
+#endif
+
+#ifndef _VIEWSH_HXX
+#include        // Bildschirmabgleich
+#endif
+#ifndef _VIEWOPT_HXX
+#include       // Bildschirmabgleich abschalten, ViewOption
+#endif
+#ifndef _FNTCACHE_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _SWFONT_HXX
+#include        // CH_BLANK + CH_BULLET
+#endif
+#ifndef _WRONG_HXX
+#include 
+#endif
+#ifndef _DRAWFONT_HXX
+#include      // SwDrawTextInfo
+#endif
+
+
+// Enable this to use the helpclass SwRVPMark
+#ifdef DEBUG
+#ifndef _RVP_MARK_HXX
+#include 
+#endif
+#endif
+
+// globale Variablen, werden in FntCache.Hxx bekanntgegeben
+// Der FontCache wird in TxtInit.Cxx _TXTINIT erzeugt und in _TXTEXIT geloescht
+SwFntCache *pFntCache = NULL;
+// Letzter Font, der durch ChgFntCache eingestellt wurde.
+SwFntObj *pLastFont = NULL;
+// Die "MagicNumber", die den Fonts zur Identifizierung verpasst wird
+BYTE* pMagicNo = NULL;
+
+Color *pSpellCol = 0;
+Color *pWaveCol = 0;
+
+long SwFntObj::nPixWidth;
+MapMode* SwFntObj::pPixMap = NULL;
+OutputDevice* SwFntObj::pPixOut = NULL;
+
+#ifdef _RVP_MARK_HXX
+
+void SwRVPMarker::Mark( const OutputDevice* pOut )
+{
+    if( pOut )
+    {
+        Color aOldCol = pOut->GetLineColor();
+        Color aBlack = Color( COL_BLACK );
+        if( aOldCol != aBlack )
+        {
+            ((OutputDevice*)pOut)->SetLineColor( aBlack );
+            ((OutputDevice*)pOut)->DrawChord( Rectangle(0,1,0,1),
+                                              Point(), Point() );
+            ((OutputDevice*)pOut)->SetLineColor( aOldCol );
+        }
+        else
+            ((OutputDevice*)pOut)->DrawChord( Rectangle(0,1,0,1),
+                                              Point(), Point() );
+    }
+}
+
+#endif
+
+/*************************************************************************
+|*
+|*  SwFntCache::Flush()
+|*
+|*  Ersterstellung      AMA 16. Dez. 94
+|*  Letzte Aenderung    AMA 16. Dez. 94
+|*
+|*************************************************************************/
+
+void SwFntCache::Flush( )
+{
+    if ( pLastFont )
+    {
+        pLastFont->Unlock();
+        pLastFont = NULL;
+    }
+    SwCache::Flush( );
+}
+
+/*************************************************************************
+|*
+|*  SwFntObj::SwFntObj(), ~SwFntObj()
+|*
+|*  Ersterstellung      AMA 7. Nov. 94
+|*  Letzte Aenderung    AMA 7. Nov. 94
+|*
+|*************************************************************************/
+
+SwFntObj::SwFntObj( const Font &rFont, const void *pOwner, ViewShell *pSh ) :
+    SwCacheObj( (void*)pOwner ),
+    pScrFont( NULL ),
+    pPrinter( NULL ),
+    aFont( rFont )
+{
+    nZoom = pSh ? pSh->GetViewOptions()->GetZoom() : USHRT_MAX;
+    nLeading = USHRT_MAX;
+    nPrtAscent = USHRT_MAX;
+    nPrtHeight = USHRT_MAX;
+    bPaintBlank = ( UNDERLINE_NONE != aFont.GetUnderline()
+                  || STRIKEOUT_NONE != aFont.GetStrikeout() )
+                  && !aFont.IsWordLineMode();
+}
+
+SwFntObj::~SwFntObj()
+{
+    if ( pScrFont != &aFont )
+        delete pScrFont;
+}
+
+/*************************************************************************
+ *
+ *  USHORT SwFntObj::GetAscent( const OutputDevice *pOut )
+ *
+ *  Ersterstellung      AMA 7. Nov. 94
+ *  Letzte Aenderung    AMA 7. Nov. 94
+ *
+ *  Beschreibung: liefern den Ascent des Fonts auf dem
+ *  gewuenschten Outputdevice zurueck, ggf. muss der Bildschirmfont erst
+ *  erzeugt werden. Dies wird in CheckScrFont ueberprueft und in
+ *  CreateScrFont erledigt.
+ *
+ *************************************************************************/
+
+USHORT SwFntObj::GetAscent( ViewShell *pSh, const OutputDevice *pOut )
+{
+    if( OUTDEV_PRINTER == pOut->GetOutDevType() )
+    {
+        if ( nPrtAscent == USHRT_MAX ) // DruckerAscent noch nicht bekannt?
+        {
+            const Font aOldFnt( pOut->GetFont() );
+            ( (OutputDevice *)pOut )->SetFont( aFont );
+            const FontMetric aWinMet( pOut->GetFontMetric() );
+            nPrtAscent = (USHORT) aWinMet.GetAscent();
+            ( (OutputDevice *)pOut )->SetFont( aOldFnt );
+        }
+        return nPrtAscent + nLeading;
+    }
+    CheckScrFont( pSh, pOut );  // eventuell Bildschirmanpassung durchfuehren
+    return nScrAscent;
+}
+
+USHORT SwFntObj::GetHeight( ViewShell *pSh, const OutputDevice *pOut )
+{
+    if( OUTDEV_PRINTER == pOut->GetOutDevType() )
+    {
+        if ( nPrtHeight == USHRT_MAX ) // PrinterHeight noch nicht bekannt?
+        {
+            const Font aOldFnt( pOut->GetFont() );
+            ( (OutputDevice *)pOut )->SetFont( aFont );
+            nPrtHeight = (USHORT) pOut->GetTextHeight();
+            ((OutputDevice *)pOut)->SetFont( aOldFnt );
+        }
+        return nPrtHeight + nLeading;
+    }
+    CheckScrFont( pSh, pOut );  // eventuell Bildschirmanpassung durchfuehren
+    if ( nScrHeight == USHRT_MAX ) // ScreenHeight noch nicht bekannt?
+    {
+        const Font aOldFnt( pOut->GetFont() );
+        ((OutputDevice *)pOut)->SetFont( aFont );
+        nScrHeight = (USHORT) pOut->GetTextHeight();
+        ((OutputDevice *)pOut)->SetFont( aOldFnt );
+    }
+    return nScrHeight;
+}
+
+/*************************************************************************
+ *
+ *  void SwFntObj::CreateScrFont( const OutputDevice *pOut ),
+ *  void SwFntObj::ChooseFont( const OutputDevice *pOut )
+ *
+ *  Ersterstellung      AMA 7. Nov. 94
+ *  Letzte Aenderung    AMA 7. Nov. 94
+ *
+ *  Beschreibung: CreateScrFont ermittelt mittels ChooseFont den fuer die
+ *  Bildschirmdarstellung optimalen Font und haelt Ascent, Leading und die
+ *  Buchstabenbreiten fest.
+ *
+ *************************************************************************/
+
+// Es wird jetzt der im OutputDevice eingestellte Font mit dem ueber Drucker-
+// abgleich einstellbaren verglichen. Derjenige, der dichter am Druckerfont
+// liegt, wird eingestellt, wobei ein zu schmaler Font gegenueber einem zu
+// breiten bevorzugt wird.
+
+BOOL SwFntObj::ChooseFont( ViewShell *pSh, OutputDevice *pOut )
+{
+static sal_Char __READONLY_DATA sStandardString[] = "Dies ist der Teststring";
+
+    nScrHeight = USHRT_MAX;
+    BOOL bRet = FALSE;
+
+    Printer *pPrt;
+    // "No screen adj"
+    if( pSh && ( !pSh->GetDoc()->IsBrowseMode() ||
+                  pSh->GetViewOptions()->IsPrtFormat() ) &&
+        ( 0 != ( pPrt = (Printer *)(pSh->GetDoc()->GetPrt() ) ) ) &&
+        pPrt->IsValid() )
+#ifdef MAC
+        pPrinter = pPrt;
+    bSymbol = CHARSET_SYMBOL == aFont.GetCharSet();
+    nLeading = 0;
+#else
+    {
+        pPrinter = pPrt;
+        Font aOldFnt( pPrt->GetFont() );
+        pPrt->SetFont( aFont );
+        FontMetric aMet = pPrt->GetFontMetric( );
+        bSymbol = RTL_TEXTENCODING_SYMBOL == aMet.GetCharSet();
+        if ( nLeading == USHRT_MAX )
+        {
+            long nTmpLeading = (long)aMet.GetLeading();
+            if ( nTmpLeading < 5 )
+            {
+                GetAscent( pSh, pPrt );
+                GuessLeading( pSh, aMet );
+            }
+            else
+                nLeading = 0;
+        }
+#ifdef DEBUG
+        const XubString aDbgTxt1(aFont.GetName());
+        const XubString aDbgTxt2( aMet.GetName() );
+#endif
+        if ( aMet.IsDeviceFont( ) )
+        {
+            if ( (RTL_TEXTENCODING_DONTKNOW == aFont.GetCharSet() ||
+                  FAMILY_DONTKNOW  == aFont.GetFamily()  ||
+                  PITCH_DONTKNOW   == aFont.GetPitch()     ) &&
+                 (RTL_TEXTENCODING_DONTKNOW == aMet.GetCharSet()  ||
+                  FAMILY_DONTKNOW  == aMet.GetFamily()   ||
+                  PITCH_DONTKNOW   == aMet.GetPitch()      )    )
+            {
+                // Das folgende ist teuer, aber selten: ein unbekannter Font
+                // kann vom Drucker nicht vernuenftig zugeordnet werden. Dann
+                // nehmen wir eben das Mapping des Bildschirms in Anspruch und
+                // setzen den Familyname, Charset und Pitch wie dort. Dieser
+                // Font wird nun nochmals auf dem Drucker eingestellt.
+                Font aFnt1 = pOut->GetFontMetric();
+                Font aFnt2( aFont );
+                aFnt2.SetCharSet( aFnt1.GetCharSet() );
+                aFnt2.SetFamily( aFnt1.GetFamily() );
+                aFnt2.SetPitch( aFnt1.GetPitch() );
+                pPrt->SetFont( aFnt2 );
+                aMet = pPrt->GetFontMetric( );
+            }
+            const XubString aStandardStr( sStandardString,
+                RTL_TEXTENCODING_MS_1252 );
+            long nOWidth = pPrt->GetTextWidth( aStandardStr );
+            long nSWidth = nOWidth - pOut->GetTextWidth( aStandardStr );
+            nScrHeight = (USHORT) pOut->GetTextHeight();
+            // Um Aerger mit dem Generic Printer aus dem Wege zu gehen.
+            if( aMet.GetSize().Height() )
+            {
+                BOOL bScrSymbol;
+                CharSet ePrtChSet = aMet.GetCharSet();
+                // NoSymbol bedeutet, dass der Drucker sich fuer einen
+                // Nicht-Symbol-Font entschieden hat.
+                BOOL bNoSymbol = ( RTL_TEXTENCODING_DONTKNOW != ePrtChSet &&
+                                   RTL_TEXTENCODING_SYMBOL != ePrtChSet );
+                if ( bNoSymbol )
+                    bScrSymbol = RTL_TEXTENCODING_SYMBOL ==
+                                 pOut->GetFontMetric().GetCharSet();
+                pOut->SetFont( aMet );  // Druckerabgleich
+                if( bNoSymbol && ( bScrSymbol != ( RTL_TEXTENCODING_SYMBOL ==
+                                        pOut->GetFontMetric().GetCharSet() ) ) )
+                {
+                    // Hier landen wir, wenn der Drucker keinen Symbolfont waehlt,
+                    // aber genau einer der beiden Screenfonts ein Symbolfont ist.
+                    // Wir nehmen dann eben den anderen.
+                    if ( bScrSymbol )
+                        bRet = TRUE; // mit Abgleich
+                    else
+                        pOut->SetFont( aFont ); // ohne Abgleich
+                }
+                else
+                {
+                    long nPWidth =
+                        nOWidth - pOut->GetTextWidth( aStandardStr );
+                    // lieber schmaler als breiter
+                    if ( nSWidth<0 ) { nSWidth *= -2; }
+                    if ( nPWidth<0 ) { nPWidth *= -2; }
+                    if ( nSWidth < nPWidth )
+                        pOut->SetFont( aFont ); // ohne Abgleich
+                    else
+                        bRet = TRUE; // mit Abgleich
+                }
+            }
+        }
+
+        pPrt->SetFont( aOldFnt );
+    }
+    else
+    {
+        bSymbol = RTL_TEXTENCODING_SYMBOL == aFont.GetCharSet();
+        if ( nLeading == USHRT_MAX )
+            nLeading = 0;
+    }
+#endif
+    // Zoomfaktor ueberpruefen, z.B. wg. PrtOle2 beim Speichern
+    {
+        // Sollte der Zoomfaktor des OutputDevices nicht mit dem der View-
+        // Options uebereinstimmen, so darf dieser Font nicht gecacht
+        // werden, deshalb wird der Zoomfaktor auf einen "ungueltigen" Wert
+        // gesetzt.
+        long nTmp;
+        if( pOut->GetMapMode().GetScaleX().IsValid() &&
+            pOut->GetMapMode().GetScaleY().IsValid() &&
+            pOut->GetMapMode().GetScaleX() == pOut->GetMapMode().GetScaleY() )
+        {
+            nTmp = ( 100 * pOut->GetMapMode().GetScaleX().GetNumerator() ) /
+                     pOut->GetMapMode().GetScaleX().GetDenominator();
+        }
+        else
+            nTmp = 0;
+        if( nTmp != nZoom )
+            nZoom = USHRT_MAX - 1;
+    }
+    return bRet;
+}
+
+void SwFntObj::CreateScrFont( ViewShell *pSh, const OutputDevice *pOut )
+{
+    Font aOldFnt( pOut->GetFont() );
+    ((OutputDevice *)pOut)->SetFont( aFont );
+    // Jetzt wird der "bessere" Font eingestellt.
+    const BOOL bChoosePrt = ChooseFont( pSh, (OutputDevice *)pOut );
+    const FontMetric aMet = pOut->GetFontMetric( );
+    if ( bChoosePrt )
+        pScrFont = new Font( aMet );
+    else
+        pScrFont = &aFont;
+    nScrAscent = (USHORT) aMet.GetAscent( );
+    ((OutputDevice *)pOut)->SetFont( aOldFnt );
+}
+
+void SwFntObj::GuessLeading( ViewShell *pSh, const FontMetric& rMet )
+{
+//  Wie waere es mit 50% des Descents (StarMath??):
+//  nLeading = USHORT( aMet.GetDescent() / 2 );
+
+#if defined(WNT) || defined(WIN) || defined(PM2)
+    OutputDevice *pWin = ( pSh && pSh->GetWin() ) ? pSh->GetWin() :
+                         GetpApp()->GetDefaultDevice();
+    if ( pWin )
+    {
+        MapMode aTmpMap( MAP_TWIP );
+        MapMode aOldMap = pWin->GetMapMode( );
+        pWin->SetMapMode( aTmpMap );
+        const Font aOldFnt( pWin->GetFont() );
+        pWin->SetFont( aFont );
+        const FontMetric aWinMet( pWin->GetFontMetric() );
+        const USHORT nWinHeight = USHORT( aWinMet.GetSize().Height() );
+        if( aFont.GetName().Search( aWinMet.GetName() ) < USHRT_MAX )
+        {
+            // Wenn das Leading auf dem Window auch 0 ist, dann
+            // muss es auch so bleiben (vgl. StarMath!).
+            long nTmpLeading = (long)aWinMet.GetLeading();
+             // einen Versuch haben wir noch wg. 31003:
+            if( nTmpLeading <= 0 )
+            {
+                pWin->SetFont( rMet );
+                nTmpLeading = (long)pWin->GetFontMetric().GetLeading();
+                if( nTmpLeading < 0 )
+                    nLeading = 0;
+                else
+                    nLeading = USHORT(nTmpLeading);
+            }
+            else
+            {
+                nLeading = USHORT(nTmpLeading);
+                // Manta-Hack #50153#:
+                // Wer beim Leading luegt, luegt moeglicherweise auch beim
+                // Ascent/Descent, deshalb wird hier ggf. der Font ein wenig
+                // tiefergelegt, ohne dabei seine Hoehe zu aendern.
+                long nDiff = Min( rMet.GetDescent() - aWinMet.GetDescent(),
+                    aWinMet.GetAscent() - rMet.GetAscent() - nTmpLeading );
+                if( nDiff > 0 )
+                {
+                    ASSERT( nPrtAscent < USHRT_MAX, "GuessLeading: PrtAscent-Fault" );
+                    nPrtAscent += ( 2 * nDiff ) / 5;
+                }
+            }
+        }
+        else
+        {
+            // Wenn alle Stricke reissen, nehmen wir 15% der
+            // Hoehe, ein von CL empirisch ermittelter Wert.
+            nLeading = (nWinHeight * 15) / 100;
+        }
+        pWin->SetFont( aOldFnt );
+        pWin->SetMapMode( aOldMap );
+    }
+    else
+#endif
+#ifdef MAC
+        nLeading = (aFont.GetSize().Height() * 15) / 100;
+#else
+        nLeading = 0;
+#endif
+}
+
+/*************************************************************************
+ *
+ *  void SwFntObj::SetDeviceFont( const OutputDevice *pOut ),
+ *
+ *  Ersterstellung      AMA 7. Nov. 94
+ *  Letzte Aenderung    AMA 7. Nov. 94
+ *
+ *  Beschreibung: stellt den Font am gewuenschten OutputDevice ein,
+ *  am Bildschirm muss eventuell erst den Abgleich durchgefuehrt werden.
+ *
+ *************************************************************************/
+
+void SwFntObj::SetDevFont( ViewShell *pSh, OutputDevice *pOut )
+{
+    if( OUTDEV_PRINTER != pOut->GetOutDevType() )
+    {
+        CheckScrFont( pSh, pOut );        // Bildschirm/Druckerabgleich
+        if( !GetScrFont()->IsSameInstance( pOut->GetFont() ) )
+            pOut->SetFont( *pScrFont );
+        if( pPrinter && ( !GetFont()->IsSameInstance( pPrinter->GetFont() ) ) )
+            pPrinter->SetFont(aFont);
+    }
+    else
+    {
+        if( !pLastFont->GetFont()->IsSameInstance( pOut->GetFont() ) )
+            pOut->SetFont( aFont );
+        if ( nLeading == USHRT_MAX )
+        {
+            FontMetric aMet( pOut->GetFontMetric() );
+            bSymbol = RTL_TEXTENCODING_SYMBOL == aMet.GetCharSet();
+            long nTmpLead = (long)aMet.GetLeading();
+            if ( nTmpLead < 5 )
+            {
+                GetAscent( pSh, pOut );
+                GuessLeading( pSh, aMet );
+            }
+            else
+                nLeading = 0;
+        }
+    }
+}
+
+#define WRONG_SHOW_MIN 5
+#define WRONG_SHOW_SMALL 11
+#define WRONG_SHOW_MEDIUM 15
+
+/*************************************************************************
+ *
+ * void SwFntObj::DrawText( ... )
+ *
+ *  Ersterstellung      AMA 16. Dez. 94
+ *  Letzte Aenderung    AMA 16. Dez. 94
+ *
+ *  Beschreibung: Textausgabe
+ *                  auf dem Bildschirm          => DrawTextArray
+ *                  auf dem Drucker, !Kerning   => DrawText
+ *                  auf dem Drucker + Kerning   => DrawStretchText
+ *
+ *************************************************************************/
+
+// ER 09.07.95 20:34
+// mit -Ox Optimierung stuerzt's unter win95 ab
+// JP 12.07.95: unter WNT auch (i386);       Alpha ??
+// global optimization off
+#if defined( WNT ) && defined( MSC ) //&& defined( W40 )
+#pragma optimize("g",off)
+#endif
+
+void SwFntObj::DrawText( SwDrawTextInfo &rInf )
+{
+static sal_Char __READONLY_DATA sDoubleSpace[] = "  ";
+    BOOL bPrt = OUTDEV_PRINTER == rInf.GetOut().GetOutDevType();
+    Font* pTmpFont = bPrt ? GetFont() : GetScrFont();
+    // HACK: UNDERLINE_WAVE darf nicht mehr missbraucht werden, daher
+    // wird die graue Wellenlinie des ExtendedAttributSets zunaechst
+    // in der Fontfarbe erscheinen.
+
+    Point aPos( rInf.GetPos() );
+    if( !bPrt )
+    {
+        if( rInf.GetpOut() != pPixOut || rInf.GetOut().GetMapMode() != *pPixMap )
+        {
+            *pPixMap = rInf.GetOut().GetMapMode();
+            pPixOut = rInf.GetpOut();
+            Size aTmp( 1, 1 );
+            nPixWidth = rInf.GetOut().PixelToLogic( aTmp ).Width();
+        }
+        aPos.X() += nPixWidth;
+    }
+    Color aOldColor;
+    if( bPrt && rInf.GetShell()->GetViewOptions()->IsBlackFont() &&
+        COL_BLACK != (aOldColor = pTmpFont->GetColor()).GetColor() )
+    {
+        Color aBlack( COL_BLACK );
+        pTmpFont->SetColor( aBlack );
+        if( !pLastFont->GetFont()->IsSameInstance( rInf.GetOut().GetFont() ) )
+            rInf.GetOut().SetFont( *pTmpFont );
+        pTmpFont->SetColor( aOldColor );
+    }
+    else if( !pTmpFont->IsSameInstance( rInf.GetOut().GetFont() ) )
+        rInf.GetOut().SetFont( *pTmpFont );
+
+    if ( STRING_LEN == rInf.GetLen() )
+        rInf.SetLen( rInf.GetText().Len() );
+    // "No screen adj"
+    if ( bPrt || (
+        rInf.GetShell()->GetDoc()->IsBrowseMode() &&
+        !rInf.GetShell()->GetViewOptions()->IsPrtFormat() &&
+        !rInf.GetBullet() && ( rInf.GetSpace() || !rInf.GetKern() ) &&
+        !rInf.GetWrong() && !rInf.GetGreyWave() ) )
+    {
+        const Fraction aTmp( 1, 1 );
+        BOOL bStretch = rInf.GetWidth() && ( rInf.GetLen() > 1 ) && bPrt
+                        && ( aTmp != rInf.GetOut().GetMapMode().GetScaleX() );
+        if( rInf.GetSpace() )
+        // Hack, solange DrawStretchText auf Druckern nicht funktioniert:
+        //  || bStretch || rInf.GetKern() )
+        {
+            long *pKernArray = new long[rInf.GetLen()];
+            rInf.GetOut().GetTextArray( rInf.GetText(), pKernArray,
+                                         rInf.GetIdx(), rInf.GetLen() );
+            if( bStretch )
+            {
+                xub_StrLen nZwi = rInf.GetLen() - 1;
+                long nDiff = rInf.GetWidth() - pKernArray[ nZwi ]
+                             - rInf.GetLen() * rInf.GetKern();
+                long nRest = nDiff % nZwi;
+                long nAdd;
+                if( nRest < 0 )
+                {
+                    nAdd = -1;
+                    nRest += nZwi;
+                }
+                else
+                {
+                    nAdd = +1;
+                    nRest = nZwi - nRest;
+                }
+                nDiff /= nZwi;
+                long nSum = nDiff;
+                for( xub_StrLen i = 0; i < nZwi; )
+                {
+                    pKernArray[ i ] += nSum;
+                    if( ++i == nRest )
+                        nDiff += nAdd;
+                    nSum += nDiff;
+                }
+            }
+            long nKernSum = rInf.GetKern();
+
+            if ( bStretch || bPaintBlank || rInf.GetKern() )
+            {
+                for( xub_StrLen i = 0; i < rInf.GetLen(); i++,
+                     nKernSum += rInf.GetKern() )
+                {
+                    if ( CH_BLANK == rInf.GetText().GetChar(rInf.GetIdx()+i) )
+                        nKernSum += rInf.GetSpace();
+                    pKernArray[i] += nKernSum;
+                }
+
+                // Bei durch/unterstr. Blocksatz erfordert ein Blank am Ende
+                // einer Textausgabe besondere Massnahmen:
+                if( bPaintBlank && rInf.GetLen() && ( CH_BLANK ==
+                    rInf.GetText().GetChar( rInf.GetIdx()+rInf.GetLen()-1 ) ) )
+                {
+                    // Wenn es sich um ein singulaeres, unterstrichenes Space
+                    // handelt, muessen wir zwei ausgeben:
+                    if( 1 == rInf.GetLen() )
+                    {
+                        pKernArray[0] = rInf.GetSpace();
+                        rInf.GetOut().DrawTextArray( aPos, XubString( sDoubleSpace,
+                            RTL_TEXTENCODING_MS_1252 ), pKernArray, 0, 2 );
+                    }
+                    else
+                    {
+                        pKernArray[ rInf.GetLen() - 2 ] += rInf.GetSpace();
+                        rInf.GetOut().DrawTextArray( aPos, rInf.GetText(),
+                            pKernArray, rInf.GetIdx(), rInf.GetLen() );
+                    }
+                }
+                else
+                    rInf.GetOut().DrawTextArray( aPos, rInf.GetText(),
+                        pKernArray, rInf.GetIdx(), rInf.GetLen() );
+            }
+            else
+            {
+                Point aTmpPos( aPos );
+                xub_StrLen j = 0;
+                xub_StrLen i;
+                for( i = 0; i < rInf.GetLen(); i++ )
+                {
+                    if( CH_BLANK == rInf.GetText().GetChar( rInf.GetIdx()+i ) )
+                    {
+                        nKernSum += rInf.GetSpace();
+                        if( j < i )
+                            rInf.GetOut().DrawText( aTmpPos, rInf.GetText(),
+                                                    rInf.GetIdx() + j, i - j );
+                        j = i + 1;
+                        aTmpPos.X() = aPos.X() + pKernArray[ i ] + nKernSum;
+                    }
+                }
+                if( j < i )
+                    rInf.GetOut().DrawText( aTmpPos, rInf.GetText(),
+                                            rInf.GetIdx() + j, i - j );
+            }
+            delete[] pKernArray;
+        }
+        else if( bStretch )
+        {
+            USHORT nTmpWidth = rInf.GetWidth();
+            if( rInf.GetKern() && rInf.GetLen() && nTmpWidth > rInf.GetKern() )
+                nTmpWidth -= rInf.GetKern();
+            rInf.GetOut().DrawStretchText( aPos, nTmpWidth,
+                             rInf.GetText(), rInf.GetIdx(), rInf.GetLen() );
+        }
+        else if( rInf.GetKern() )
+        {
+            long nTmpWidth =
+                GetTextSize( rInf.GetShell(),
+                             rInf.GetpOut(), rInf.GetText(), rInf.GetIdx(),
+                             rInf.GetLen(), rInf.GetKern() ).Width();
+            rInf.GetOut().DrawStretchText( aPos, (USHORT)nTmpWidth,
+                               rInf.GetText(), rInf.GetIdx(), rInf.GetLen() );
+        }
+        else
+            rInf.GetOut().DrawText( aPos, rInf.GetText(),
+                                    rInf.GetIdx(), rInf.GetLen() );
+    }
+    else
+    {
+        const String* pStr = &rInf.GetText();
+        String aStr( aEmptyStr );
+        BOOL bBullet = rInf.GetBullet();
+        if( bSymbol )
+            bBullet = FALSE;
+        long *pKernArray = new long[ rInf.GetLen() ];
+        CheckScrFont( rInf.GetShell(), rInf.GetpOut() );
+        long nScrPos;
+        xub_Unicode cCh = rInf.GetText().GetChar( rInf.GetIdx() );
+        rInf.GetOut().GetCharWidth( cCh, cCh, &nScrPos );
+
+        if ( pPrinter )
+        {
+            if( !GetFont()->IsSameInstance( pPrinter->GetFont() ) )
+                pPrinter->SetFont( aFont );
+            pPrinter->GetTextArray( rInf.GetText(), pKernArray, rInf.GetIdx(),
+                                    rInf.GetLen() );
+        }
+        else
+            rInf.GetOut().GetTextArray( rInf.GetText(), pKernArray,
+                                        rInf.GetIdx(), rInf.GetLen() );
+        if( bBullet )
+        {
+            aStr = rInf.GetText().Copy( rInf.GetIdx(), rInf.GetLen() );
+            pStr = &aStr;
+            for( xub_StrLen i = 0; i < aStr.Len(); ++i )
+                if( CH_BLANK == aStr.GetChar( i ) )
+                    aStr.SetChar( i, CH_BULLET );
+        }
+
+        xub_StrLen nCnt = rInf.GetText().Len();
+        if ( nCnt < rInf.GetIdx() )
+            nCnt = 0;
+        else
+            nCnt -= rInf.GetIdx();
+        nCnt = Min( nCnt, rInf.GetLen() );
+        long nKernSum = rInf.GetKern();
+        xub_Unicode cChPrev = rInf.GetText().GetChar( rInf.GetIdx() );
+
+        // Wenn es sich um ein singulaeres, unterstrichenes Space
+        // im Blocksatz handelt, muessen wir zwei ausgeben:
+        if ( ( nCnt == 1 ) && rInf.GetSpace() && ( cChPrev == CH_BLANK ) )
+        {
+            pKernArray[0] = rInf.GetSpace() + rInf.GetKern();
+            rInf.GetOut().DrawTextArray( aPos, XubString( sDoubleSpace,
+                RTL_TEXTENCODING_MS_1252 ), pKernArray, 0, 2 );
+            if( bBullet )
+                rInf.GetOut().DrawTextArray( aPos, *pStr, pKernArray,
+                                              0, 1 );
+        }
+        else
+        {
+            xub_Unicode nCh;
+
+            // Bei Pairkerning waechst der Printereinfluss auf die Positionierung
+            USHORT nMul = 3;
+            if ( aFont.IsKerning() )
+                nMul = 1;
+            const USHORT nDiv = nMul+1;
+            // In nSpaceSum wird der durch Blocksatz auf die Spaces verteilte
+            // Zwischenraum aufsummiert.
+            // Die Spaces selbst werden im Normalfall in der Mitte des
+            // Zwischenraums positioniert, deshalb die nSpace/2-Mimik.
+            // Bei wortweiser Unterstreichung muessen sie am Anfang des
+            // Zwischenraums stehen, damit dieser nicht unterstrichen wird.
+            // Ein Space am Anfang oder am Ende des Textes muss allerdings
+            // vor bzw. hinter den kompletten Zwischenraum gesetzt werden,
+            // sonst wuerde das Durch-/Unterstreichen Luecken aufweisen.
+            long nSpaceSum = 0;
+            USHORT nHalfSpace = aFont.IsWordLineMode() ? 0 : rInf.GetSpace()/2;
+            USHORT nOtherHalf = rInf.GetSpace() - nHalfSpace;
+            if ( rInf.GetSpace() && ( cChPrev == CH_BLANK ) )
+                nSpaceSum = nHalfSpace;
+            for ( xub_StrLen i=1; iCheck( nStart, nWrLen ) )
+                    {
+                        long nHght = rInf.GetOut().LogicToPixel(
+                                                    aFont.GetSize() ).Height();
+                        if( WRONG_SHOW_MIN < nHght )
+                        {
+                            pKernArray[ rInf.GetLen() - 1 ] += nKernSum + nSpaceSum;
+                            if ( rInf.GetOut().GetConnectMetaFile() )
+                                rInf.GetOut().Push();
+
+                            USHORT nWave =
+                                WRONG_SHOW_MEDIUM < nHght ? WAVE_NORMAL :
+                                ( WRONG_SHOW_SMALL < nHght ? WAVE_SMALL :
+                                WAVE_FLAT );
+                            Color aCol( rInf.GetOut().GetLineColor() );
+                            BOOL bColSave = aCol != *pSpellCol;
+                            if ( bColSave )
+                                rInf.GetOut().SetLineColor( *pSpellCol );
+
+                            do
+                            {
+                                nStart -= rInf.GetIdx();
+                                Point aStart = nStart ?
+                                    Point( rInf.GetPos().X() + pKernArray[ USHORT(nStart-1) ],
+                                           rInf.GetPos().Y() ) : rInf.GetPos();
+                                nStart += nWrLen;
+                                long nX = rInf.GetPos().X() + pKernArray[ USHORT(nStart-1) ];
+                                if( nStart < nCnt
+                                    && CH_BLANK == rInf.GetText().GetChar( rInf.GetIdx() + nStart ) )
+                                {
+                                    if( nStart + 1 == nCnt )
+                                        nX -= rInf.GetSpace();
+                                    else
+                                        nX -= nHalfSpace;
+                                }
+                                Point aEnd( nX, rInf.GetPos().Y() );
+                                rInf.GetOut().DrawWaveLine( aStart, aEnd, nWave );
+                                nStart += rInf.GetIdx();
+                                nWrLen = rInf.GetIdx() + rInf.GetLen() - nStart;
+                            }
+                            while( nWrLen && rInf.GetWrong()->Check( nStart, nWrLen ) );
+
+                            if ( bColSave )
+                                rInf.GetOut().SetLineColor( aCol );
+
+                            if ( rInf.GetOut().GetConnectMetaFile() )
+                                rInf.GetOut().Pop();
+                        }
+                    }
+                }
+            }
+            xub_StrLen nOffs = 0;
+            xub_StrLen nLen = rInf.GetLen();
+#ifdef COMING_SOON
+            if( aPos.X() < rInf.GetLeft() )
+            {
+                while( nOffs < nLen &&
+                    aPos.X() + pKernArray[ nOffs ] < rInf.GetLeft() )
+                    ++nOffs;
+                if( nOffs < nLen )
+                {
+                    --nLen;
+                    while( nLen > nOffs &&
+                        aPos.X() + pKernArray[ nLen ] > rInf.GetRight() )
+                        --nLen;
+                    ++nLen;
+                    if( nOffs )
+                        --nOffs;
+                }
+                if( nOffs )
+                {
+                    long nDiff = pKernArray[ nOffs - 1 ];
+                    aPos.X() += nDiff;
+                    for( xub_StrLen nX = nOffs; nX < nLen; ++nX )
+                        pKernArray[ nX ] -= nDiff;
+                }
+            }
+#endif
+            if( nOffs < nLen )
+            {
+                register xub_StrLen nTmpIdx = bBullet ? 0 : rInf.GetIdx();
+                rInf.GetOut().DrawTextArray( aPos, *pStr, pKernArray + nOffs,
+                                    nTmpIdx + nOffs , nLen - nOffs );
+            }
+        }
+        delete[] pKernArray;
+    }
+}
+
+// Optimierung war fuer DrawText() ausgeschaltet
+#if defined( WNT ) && defined( MSC )    // && defined( W40 )
+#pragma optimize("",on)
+#endif
+
+/*************************************************************************
+ *
+ *  Size SwFntObj::GetTextSize( const OutputDevice *pOut, const String &rTxt,
+ *           const USHORT nIdx, const USHORT nLen, const short nKern = 0 );
+ *
+ *  Ersterstellung      AMA 16. Dez. 94
+ *  Letzte Aenderung    AMA 16. Dez. 94
+ *
+ *  Beschreibung: ermittelt die TextSize (des Druckers)
+ *
+ *************************************************************************/
+
+Size SwFntObj::GetTextSize( ViewShell *pSh,
+             const OutputDevice *pOut, const String &rTxt,
+             const xub_StrLen nIdx, const xub_StrLen nLen, const short nKern )
+{
+    Size aTxtSize;
+    if ( OUTDEV_PRINTER != pOut->GetOutDevType() && pPrinter )
+    {
+        if( pPrinter && ( !GetFont()->IsSameInstance( pPrinter->GetFont() ) ) )
+            pPrinter->SetFont(aFont);
+        aTxtSize.Width() = pPrinter->GetTextWidth( rTxt, nIdx, nLen );
+        aTxtSize.Height() = pPrinter->GetTextHeight();
+        const xub_StrLen nLn = ( STRING_LEN != nLen ) ? nLen : rTxt.Len();
+        long *pKernArray = new long[nLen];
+        CheckScrFont( pSh, pOut );
+        if( !GetScrFont()->IsSameInstance( pOut->GetFont() ) )
+            ( (OutputDevice*)pOut )->SetFont( *pScrFont );
+        long nScrPos;
+        xub_Unicode cCh = rTxt.GetChar( nIdx );
+        pOut->GetCharWidth( cCh, cCh, &nScrPos );
+
+        pPrinter->GetTextArray( rTxt, pKernArray, nIdx, nLen);
+
+        xub_StrLen nCnt = rTxt.Len();
+        if ( nCnt < nIdx )
+            nCnt=0;
+        else
+            nCnt -= nIdx;
+        nCnt = Min (nCnt, nLn);
+        xub_Unicode nChPrev = rTxt.GetChar( nIdx );
+
+        xub_Unicode nCh;
+
+        // Bei Pairkerning waechst der Printereinfluss auf die Positionierung
+        USHORT nMul = 3;
+        if ( aFont.IsKerning() )
+            nMul = 1;
+        const USHORT nDiv = nMul+1;
+        for( xub_StrLen i=1; iGetCharWidth( nCh, nCh, &nScr );
+
+            if ( nCh == CH_BLANK )
+                nScrPos = pKernArray[i-1]+nScr;
+            else
+            {
+                if ( nChPrev == CH_BLANK || nChPrev == '-' )
+                    nScrPos = pKernArray[i-1]+nScr;
+                else
+                {
+                    nScrPos += nScr;
+                    nScrPos = ( nMul * nScrPos + pKernArray[i] ) / nDiv;
+                }
+            }
+            nChPrev = nCh;
+            pKernArray[i-1] = nScrPos - nScr;
+        }
+        delete[] pKernArray;
+        aTxtSize.Width() = nScrPos;
+    }
+    else
+    {
+        if( !pLastFont->GetFont()->IsSameInstance( pOut->GetFont() ) )
+            ( (OutputDevice*)pOut )->SetFont( aFont );
+        aTxtSize.Width() = pOut->GetTextWidth( rTxt, nIdx, nLen );
+        aTxtSize.Height() = pOut->GetTextHeight();
+    }
+    if ( nKern && nLen )
+        aTxtSize.Width() += ( nLen - 1 ) * long( nKern );
+    aTxtSize.Height() += nLeading;
+    return aTxtSize;
+}
+
+xub_StrLen SwFntObj::GetCrsrOfst( const OutputDevice *pOut, const String &rTxt,
+             const USHORT nOfst, const xub_StrLen nIdx, const xub_StrLen nLen,
+             short nKern, short nSpaceAdd )
+{
+    if( nSpaceAdd < 0 )
+    {
+        nKern -= nSpaceAdd;
+        nSpaceAdd = 0;
+    }
+    long *pKernArray = new long[nLen];
+
+    if ( pPrinter )
+        pPrinter->GetTextArray( rTxt, pKernArray, nIdx, nLen);
+    else
+        pOut->GetTextArray( rTxt, pKernArray, nIdx, nLen);
+
+    long nLeft = 0;
+    long nRight = 0;
+    xub_StrLen nCnt = 0;
+    xub_StrLen nSpaceSum = 0;
+    long nKernSum = 0;
+
+    while ( ( nRight < long(nOfst) ) && ( nCnt < nLen ) )
+    {
+        nLeft = nRight;
+        if ( nSpaceAdd && ( rTxt.GetChar( nCnt + nIdx ) == CH_BLANK ) )
+            nSpaceSum += nSpaceAdd;
+        nRight = pKernArray[ nCnt++ ] + nKernSum + nSpaceSum;
+        nKernSum += nKern;
+    }
+    if ( nCnt && ( nRight > long(nOfst) ) && ( nRight - nOfst > nOfst - nLeft ) )
+      --nCnt;
+
+    delete[] pKernArray;
+    return nCnt;
+}
+
+/*************************************************************************
+|*
+|*  SwFntAccess::SwFntAccess()
+|*
+|*  Ersterstellung      AMA 9. Nov. 94
+|*  Letzte Aenderung    AMA 9. Nov. 94
+|*
+|*************************************************************************/
+
+SwFntAccess::SwFntAccess( const void* &rMagic,
+                USHORT &rIndex, const void *pOwner, ViewShell *pSh,
+                BOOL bCheck ) :
+  SwCacheAccess( *pFntCache, rMagic, rIndex ),
+  pShell( pSh )
+{
+    // Der benutzte CTor von SwCacheAccess sucht anhand rMagic+rIndex im Cache
+    if ( IsAvail() )
+    {
+        // Der schnellste Fall: ein bekannter Font ( rMagic ),
+        // bei dem Drucker und Zoom nicht ueberprueft werden brauchen.
+        if ( !bCheck )
+            return;
+
+        // Hier ist zwar der Font bekannt, muss aber noch ueberprueft werden.
+
+    }
+    else
+        // Hier ist der Font nicht bekannt, muss also gesucht werden.
+        bCheck = FALSE;
+
+    {
+        // Erstmal den Drucker besorgen
+        Printer *pOut = 0;
+        USHORT nZoom = USHRT_MAX;
+        if ( pSh )
+        {
+            // "No screen adj"
+            if ( !pSh->GetDoc()->IsBrowseMode() ||
+                  pSh->GetViewOptions()->IsPrtFormat() )
+            {
+                pOut = (Printer*)( pSh->GetDoc()->GetPrt() );
+                if ( pOut && !pOut->IsValid() )
+                    pOut = 0;
+            }
+            nZoom = pSh->GetViewOptions()->GetZoom();
+        }
+
+        SwFntObj *pFntObj;
+        if ( bCheck )
+        {
+            pFntObj = Get( );
+            if ( ( pFntObj->GetZoom( ) == nZoom ) &&
+                 ( pFntObj->pPrinter == pOut ) )
+                return; // Die Ueberpruefung ergab: Drucker+Zoom okay.
+            pFntObj->Unlock( ); // Vergiss dies Objekt, es wurde leider
+            pObj = NULL;        // eine Drucker/Zoomaenderung festgestellt.
+        }
+
+        //Jetzt muss ueber Font-Vergleiche gesucht werden, relativ teuer!
+        pFntObj = pFntCache->First();
+        // Suchen nach gleichem Font und gleichem Drucker
+        while ( pFntObj && !( (pFntObj->aFont)==(*(Font *)pOwner) &&
+                  ( pFntObj->GetZoom( )==nZoom ) &&
+                ( (!pFntObj->pPrinter) || ((pFntObj->pPrinter)==pOut) ) ) )
+            pFntObj = pFntCache->Next( pFntObj );
+        if( pFntObj && pFntObj->pPrinter != pOut )
+        {
+            // Wir haben zwar einen ohne Drucker gefunden, mal sehen, ob es
+            // auch noch einen mit identischem Drucker gibt.
+            SwFntObj *pTmpObj = pFntObj;
+            while( pTmpObj && !( (pTmpObj->aFont)==(*(Font *)pOwner) &&
+                   pTmpObj->GetZoom()==nZoom && pTmpObj->pPrinter==pOut ) )
+                pTmpObj = pFntCache->Next( pTmpObj );
+            if( pTmpObj )
+                pFntObj = pTmpObj;
+        }
+
+        if ( !pFntObj ) // nichts gefunden, also anlegen
+        {
+            // Das Objekt muss neu angelegt werden, deshalb muss der Owner ein
+            // SwFont sein, spaeter wird als Owner die "MagicNumber" gehalten.
+            SwCacheAccess::pOwner = pOwner;
+            pFntObj = Get( ); // hier wird via NewObj() angelegt und gelockt.
+            ASSERT(pFntObj, "No Font, no Fun.");
+        }
+        else  // gefunden, also locken
+        {
+            pFntObj->Lock();
+            if( pFntObj->pPrinter != pOut ) // Falls bis dato kein Drucker bekannt
+            {
+                ASSERT( !pFntObj->pPrinter, "SwFntAccess: Printer Changed" );
+                pFntObj->pPrinter = pOut;
+                pFntObj->pScrFont = NULL;
+                pFntObj->nLeading = USHRT_MAX;
+            }
+            pObj = pFntObj;
+        }
+        // egal, ob neu oder gefunden, ab jetzt ist der Owner vom Objekt eine
+        // MagicNumber und wird auch dem aufrufenden SwFont bekanntgegeben,
+        // ebenso der Index fuer spaetere direkte Zugriffe
+        rMagic = pFntObj->GetOwner();
+        SwCacheAccess::pOwner = rMagic;
+        rIndex = pFntObj->GetCachePos();
+    }
+}
+
+SwFntObj *SwFntAccess::Get( )
+{
+    return (SwFntObj *) SwCacheAccess::Get( );
+}
+
+SwCacheObj *SwFntAccess::NewObj( )
+{
+    // Ein neuer Font, eine neue "MagicNumber".
+    return new SwFntObj( *(Font *)pOwner, ++pMagicNo, pShell );
+}
+
+
diff --git a/sw/source/core/txtnode/fntcap.cxx b/sw/source/core/txtnode/fntcap.cxx
new file mode 100644
index 000000000000..077654158e3d
--- /dev/null
+++ b/sw/source/core/txtnode/fntcap.cxx
@@ -0,0 +1,658 @@
+/*************************************************************************
+ *
+ *  $RCSfile: fntcap.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:27 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _OUTDEV_HXX //autogen
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_CHARTYPE_HDL
+#include 
+#endif
+#ifndef _PRINT_HXX //autogen
+#include 
+#endif
+
+#include "errhdl.hxx"
+#include "fntcache.hxx"
+#include "swfont.hxx"
+#include "drawfont.hxx"
+#include "breakit.hxx"
+
+using namespace ::com::sun::star::text;
+
+
+#define KAPITAELCHENPROP 66
+
+/*************************************************************************
+ *                      class SwDoCapitals
+ *************************************************************************/
+
+class SwDoCapitals
+{
+protected:
+    SwDrawTextInfo &rInf;
+public:
+    SwDoCapitals ( SwDrawTextInfo &rInfo ) : rInf( rInfo ) { }
+    virtual void Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont ) = 0;
+    virtual void Do() = 0;
+    inline OutputDevice *GetOut() { return rInf.GetpOut(); }
+    inline SwDrawTextInfo& GetInf() { return rInf; }
+};
+
+/*************************************************************************
+ *                    class SwDoGetCapitalSize
+ *************************************************************************/
+
+class SwDoGetCapitalSize : public SwDoCapitals
+{
+protected:
+    Size aTxtSize;
+public:
+    SwDoGetCapitalSize( SwDrawTextInfo &rInfo ) : SwDoCapitals ( rInfo ) { }
+    virtual void Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont );
+    virtual void Do();
+    const Size &GetSize() const { return aTxtSize; }
+};
+
+void SwDoGetCapitalSize::Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont )
+{
+    aTxtSize.Height() = 0;
+    aTxtSize.Width() = 0;
+}
+
+void SwDoGetCapitalSize::Do()
+{
+    aTxtSize.Width() += rInf.GetSize().Width();
+    if( rInf.GetUpper() )
+        aTxtSize.Height() = rInf.GetSize().Height();
+}
+
+/*************************************************************************
+ *                    SwSubFont::GetCapitalSize()
+ *************************************************************************/
+
+Size SwSubFont::GetCapitalSize( ViewShell *pSh,
+                             const OutputDevice *pOut, const XubString &rTxt,
+                             const xub_StrLen nIdx, const xub_StrLen nLen )
+{
+    // Start:
+    Point aPos( 0, 0 );
+    SwDrawTextInfo aInfo( pSh, *(OutputDevice *)pOut, rTxt, nIdx, nLen, 0, FALSE );
+    aInfo.SetPos( aPos );
+    aInfo.SetWrong( NULL );
+    aInfo.SetDrawSpace( FALSE );
+    aInfo.SetKern( CheckKerning() );
+    aInfo.SetSpace( 0 );
+    SwDoGetCapitalSize aDo( aInfo );
+    DoOnCapitals( aDo );
+    Size aTxtSize( aDo.GetSize() );
+
+    // End:
+    if( !aTxtSize.Height() )
+    {
+        SV_STAT( nGetTextSize );
+        aTxtSize.Height() = short ( pOut->GetTextHeight() );
+    }
+    return aTxtSize;
+}
+
+/*************************************************************************
+ *                    class SwDoGetCapitalBreak
+ *************************************************************************/
+
+class SwDoGetCapitalBreak : public SwDoCapitals
+{
+protected:
+    xub_StrLen *pExtraPos;
+    long nTxtWidth;
+    xub_StrLen nBreak;
+public:
+    SwDoGetCapitalBreak( SwDrawTextInfo &rInfo, long nWidth, xub_StrLen *pExtra)
+        :   SwDoCapitals ( rInfo ), nTxtWidth( nWidth ),
+            nBreak( STRING_LEN ), pExtraPos( pExtra )
+        { }
+    virtual void Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont );
+    virtual void Do();
+    const xub_StrLen GetBreak() const { return nBreak; }
+};
+
+void SwDoGetCapitalBreak::Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont )
+{
+}
+
+void SwDoGetCapitalBreak::Do()
+{
+    if ( nTxtWidth )
+    {
+        if ( rInf.GetSize().Width() < nTxtWidth )
+            nTxtWidth -= rInf.GetSize().Width();
+        else
+        {
+            xub_StrLen nEnd = rInf.GetEnd();
+            if( pExtraPos )
+            {
+                nBreak = GetOut()->GetTextBreak( rInf.GetText(), nTxtWidth, '-',
+                     *pExtraPos, rInf.GetIdx(), rInf.GetLen(), rInf.GetKern() );
+                if( *pExtraPos > nEnd )
+                    *pExtraPos = nEnd;
+            }
+            else
+                nBreak = GetOut()->GetTextBreak( rInf.GetText(), nTxtWidth,
+                               rInf.GetIdx(), rInf.GetLen(), rInf.GetKern() );
+            if( nBreak > nEnd )
+                nBreak = nEnd;
+            nTxtWidth = 0;
+        }
+    }
+}
+
+/*************************************************************************
+ *                    SwFont::GetCapitalSize()
+ *************************************************************************/
+
+xub_StrLen SwFont::GetCapitalBreak( ViewShell *pSh, const OutputDevice *pOut,
+        const XubString &rTxt, long nTextWidth, xub_StrLen *pExtra,
+        const xub_StrLen nIdx, const xub_StrLen nLen )
+{
+    // Start:
+    Point aPos( 0, 0 );
+    SwDrawTextInfo aInfo(pSh, *(OutputDevice*)pOut, rTxt, nIdx, nLen, 0, FALSE);
+    aInfo.SetPos( aPos );
+    aInfo.SetSpace( 0 );
+    aInfo.SetWrong( NULL );
+    aInfo.SetDrawSpace( FALSE );
+    aInfo.SetKern( CheckKerning() );
+    SwDoGetCapitalBreak aDo( aInfo, nTextWidth, pExtra );
+    DoOnCapitals( aDo );
+    return aDo.GetBreak();
+}
+
+/*************************************************************************
+ *                     class SwDoDrawCapital
+ *************************************************************************/
+
+class SwDoDrawCapital : public SwDoCapitals
+{
+protected:
+    SwFntObj *pUpperFnt;
+    SwFntObj *pLowerFnt;
+public:
+    SwDoDrawCapital( SwDrawTextInfo &rInfo ) :
+        SwDoCapitals( rInfo )
+        { }
+    virtual void Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont );
+    virtual void Do();
+    void DrawSpace( Point &rPos );
+};
+
+void SwDoDrawCapital::Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont )
+{
+    pUpperFnt = pUpperFont;
+    pLowerFnt = pLowerFont;
+}
+
+void SwDoDrawCapital::Do()
+{
+    SV_STAT( nDrawText );
+    USHORT nOrgWidth = rInf.GetWidth();
+    rInf.SetWidth( USHORT(rInf.GetSize().Width()) );
+    if ( rInf.GetUpper() )
+        pUpperFnt->DrawText( rInf );
+    else
+    {
+        BOOL bOldBullet = rInf.GetBullet();
+        rInf.SetBullet( FALSE );
+        pLowerFnt->DrawText( rInf );
+        rInf.SetBullet( bOldBullet );
+    }
+    rInf.ShiftX();
+    rInf.SetWidth( nOrgWidth );
+}
+
+/*************************************************************************
+ *                    SwDoDrawCapital::DrawSpace()
+ *************************************************************************/
+
+void SwDoDrawCapital::DrawSpace( Point &rPos )
+{
+    static sal_Char __READONLY_DATA sDoubleSpace[] = "  ";
+    const USHORT nDiff = (USHORT)( rInf.GetPos().X() - rPos.X() );
+    if ( nDiff )
+        GetOut()->DrawStretchText( rPos, nDiff,
+            XubString( sDoubleSpace, RTL_TEXTENCODING_MS_1252 ), 0, 2 );
+    rPos.X() = rInf.GetPos().X() + rInf.GetWidth();
+}
+
+/*************************************************************************
+ *                    SwSubFont::DrawCapital()
+ *************************************************************************/
+
+void SwSubFont::DrawCapital( SwDrawTextInfo &rInf )
+{
+    // Es wird vorausgesetzt, dass rPos bereits kalkuliert ist!
+    // hochgezogen in SwFont: const Point aPos( CalcPos(rPos) );
+    rInf.SetDrawSpace( GetUnderline() != UNDERLINE_NONE ||
+                       GetStrikeout() != STRIKEOUT_NONE );
+    SwDoDrawCapital aDo( rInf );
+    DoOnCapitals( aDo );
+}
+
+/*************************************************************************
+ *                     class SwDoDrawCapital
+ *************************************************************************/
+
+class SwDoCapitalCrsrOfst : public SwDoCapitals
+{
+protected:
+    SwFntObj *pUpperFnt;
+    SwFntObj *pLowerFnt;
+    xub_StrLen nCrsr;
+    USHORT nOfst;
+public:
+    SwDoCapitalCrsrOfst( SwDrawTextInfo &rInfo, const USHORT nOfs ) :
+        SwDoCapitals( rInfo ), nOfst( nOfs ), nCrsr( 0 )
+        { }
+    virtual void Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont );
+    virtual void Do();
+
+    void DrawSpace( const Point &rPos );
+    inline xub_StrLen GetCrsr(){ return nCrsr; }
+};
+
+void SwDoCapitalCrsrOfst::Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont )
+{
+    pUpperFnt = pUpperFont;
+    pLowerFnt = pLowerFont;
+}
+
+void SwDoCapitalCrsrOfst::Do()
+{
+    if ( nOfst )
+    {
+        if ( nOfst > rInf.GetSize().Width() )
+        {
+            nOfst -= USHORT(rInf.GetSize().Width());
+            nCrsr += rInf.GetLen();
+        }
+        else
+        {
+            if ( rInf.GetUpper() )
+                nCrsr += pUpperFnt->GetCrsrOfst( rInf.GetpOut(), rInf.GetText(),
+                         nOfst, rInf.GetIdx(), rInf.GetLen(), rInf.GetKern() );
+            else
+                nCrsr += pLowerFnt->GetCrsrOfst( rInf.GetpOut(), rInf.GetText(),
+                         nOfst, rInf.GetIdx(), rInf.GetLen(), rInf.GetKern(),
+                         rInf.GetSpace() );
+            nOfst = 0;
+        }
+    }
+}
+
+/*************************************************************************
+ *                    SwSubFont::GetCapitalCrsrOfst()
+ *************************************************************************/
+
+xub_StrLen SwSubFont::GetCapitalCrsrOfst( ViewShell *pSh,
+    OutputDevice *pOut, const XubString &rTxt, const USHORT nOfst,
+    const xub_StrLen nIdx, const xub_StrLen nLen, const short nSpaceAdd )
+{
+    Point aPos( 0, 0 );
+    SwDrawTextInfo aInfo(pSh, *(OutputDevice*)pOut, rTxt, nIdx, nLen, 0, FALSE);
+    aInfo.SetPos( aPos );
+    aInfo.SetWrong( NULL );
+    aInfo.SetDrawSpace( FALSE );
+    aInfo.SetKern( CheckKerning() );
+    aInfo.SetSpace( nSpaceAdd );
+    SwDoCapitalCrsrOfst aDo( aInfo, nOfst );
+    DoOnCapitals( aDo );
+    return aDo.GetCrsr();
+}
+
+/*************************************************************************
+ *                    class SwDoDrawStretchCapital
+ *************************************************************************/
+
+class SwDoDrawStretchCapital : public SwDoDrawCapital
+{
+    const xub_StrLen nStrLen;
+    const USHORT nCapWidth;
+    const USHORT nOrgWidth;
+public:
+    virtual void Do();
+
+    SwDoDrawStretchCapital( SwDrawTextInfo &rInfo, const USHORT nCapWidth )
+            : SwDoDrawCapital( rInfo ),
+              nCapWidth( nCapWidth ),
+              nOrgWidth( rInfo.GetWidth() ),
+              nStrLen( rInfo.GetLen() )
+        { }
+};
+
+/*************************************************************************
+ *                    SwDoDrawStretchCapital
+ *************************************************************************/
+
+void SwDoDrawStretchCapital::Do()
+{
+    SV_STAT( nDrawStretchText );
+    USHORT nPartWidth = USHORT(rInf.GetSize().Width());
+
+    if( rInf.GetLen() )
+    {
+        // 4023: Kapitaelchen und Kerning.
+        long nDiff = long(nOrgWidth) - long(nCapWidth);
+        if( nDiff )
+        {
+            nDiff *= rInf.GetLen();
+            nDiff /= (long) nStrLen;
+            nDiff += nPartWidth;
+            if( 0 < nDiff )
+                nPartWidth = USHORT(nDiff);
+        }
+
+        // Optimierung:
+        if( 1 >= rInf.GetLen() )
+            GetOut()->DrawText( rInf.GetPos(), rInf.GetText(), rInf.GetIdx(),
+                rInf.GetLen() );
+        else
+            GetOut()->DrawStretchText( rInf.GetPos(), nPartWidth,
+                                rInf.GetText(), rInf.GetIdx(), rInf.GetLen() );
+    }
+    ((Point&)rInf.GetPos()).X() += nPartWidth;
+}
+
+/*************************************************************************
+ *                    SwSubFont::DrawStretchCapital()
+ *************************************************************************/
+
+void SwSubFont::DrawStretchCapital( SwDrawTextInfo &rInf )
+{
+    // Es wird vorausgesetzt, dass rPos bereits kalkuliert ist!
+    // hochgezogen in SwFont: const Point aPos( CalcPos(rPos) );
+
+    // 4023: nie das Kerning draufrechnen, weil wir die
+    // unmanipulierte Width brauchen.
+    const USHORT nCapWidth = (USHORT)( GetCapitalSize( rInf.GetShell(),
+        rInf.GetpOut(), rInf.GetText(), rInf.GetIdx(), rInf.GetLen() ) ).Width();
+    if( rInf.GetLen() == STRING_LEN )
+        rInf.SetLen( rInf.GetText().Len() );
+    rInf.SetDrawSpace( GetUnderline() != UNDERLINE_NONE ||
+                       GetStrikeout() != STRIKEOUT_NONE );
+    SwDoDrawStretchCapital aDo( rInf, nCapWidth );
+    DoOnCapitals( aDo );
+}
+
+/*************************************************************************
+ *                  SwSubFont::DoOnCapitals() const
+ *************************************************************************/
+
+void SwSubFont::DoOnCapitals( SwDoCapitals &rDo )
+{
+    ASSERT( pLastFont, "SwFont::DoOnCapitals: No LastFont?!" );
+
+    Size aPartSize;
+    const XubString aTxt( CalcCaseMap( rDo.GetInf().GetText() ) );
+    xub_StrLen nMaxPos = Min( USHORT(rDo.GetInf().GetText().Len()
+                            - rDo.GetInf().GetIdx()), rDo.GetInf().GetLen() );
+    rDo.GetInf().SetLen( nMaxPos );
+
+    const XubString& rOldText = rDo.GetInf().GetText();
+    rDo.GetInf().SetText( aTxt );
+    rDo.GetInf().SetSize( aPartSize );
+    xub_StrLen nPos = rDo.GetInf().GetIdx();
+    xub_StrLen nOldPos = nPos;
+    nMaxPos += nPos;
+
+    SwFntObj *pOldLast = pLastFont;
+    SwFntAccess *pBigFontAccess = NULL;
+    SwFntObj *pBigFont;
+    SwFntAccess *pSpaceFontAccess = NULL;
+    SwFntObj *pSpaceFont = NULL;
+
+    const void *pMagic2 = NULL;
+    USHORT nIndex2 = 0;
+    SwSubFont aFont( *this );
+    Point aStartPos( rDo.GetInf().GetPos() );
+
+    const BOOL bUnderStriked = aFont.GetUnderline() != UNDERLINE_NONE
+                            || aFont.GetStrikeout() != STRIKEOUT_NONE;
+    const BOOL bWordWise = bUnderStriked && aFont.IsWordLineMode() &&
+                           rDo.GetInf().GetDrawSpace();
+    const short nKern = rDo.GetInf().GetKern();
+
+    if ( bUnderStriked )
+    {
+        if ( bWordWise )
+        {
+            aFont.SetWordLineMode( FALSE );
+            pSpaceFontAccess = new SwFntAccess( pMagic2, nIndex2, &aFont,
+                                                rDo.GetInf().GetShell() );
+            pSpaceFont = pSpaceFontAccess->Get();
+        }
+        else
+            pSpaceFont = pLastFont;
+
+        // Wir basteln uns einen Font fuer die Grossbuchstaben:
+        aFont.SetUnderline( UNDERLINE_NONE );
+        aFont.SetStrikeout( STRIKEOUT_NONE );
+        pMagic2 = NULL;
+        nIndex2 = 0;
+        pBigFontAccess = new SwFntAccess( pMagic2, nIndex2, &aFont,
+                                          rDo.GetInf().GetShell() );
+        pBigFont = pBigFontAccess->Get();
+    }
+    else
+        pBigFont = pLastFont;
+
+    // Hier entsteht der Kleinbuchstabenfont:
+    aFont.SetProportion( BYTE( (aFont.GetPropr()*KAPITAELCHENPROP) / 100L) );
+    pMagic2 = NULL;
+    nIndex2 = 0;
+    SwFntAccess *pSmallFontAccess = new SwFntAccess( pMagic2, nIndex2, &aFont,
+                                                     rDo.GetInf().GetShell() );
+    SwFntObj *pSmallFont = pSmallFontAccess->Get();
+
+    rDo.Init( pBigFont, pSmallFont );
+    OutputDevice* pOutSize = pSmallFont->GetPrt();
+    if( !pOutSize )
+        pOutSize = rDo.GetOut();
+
+    const LanguageType eLng = LANGUAGE_DONTKNOW == GetLanguage()
+                            ? LANGUAGE_SYSTEM : GetLanguage();
+
+    if( nPos < nMaxPos )
+    {
+        nPos = pBreakIt->xBreak->endOfCharBlock( rOldText, nPos,
+            pBreakIt->GetLocale( eLng ), CharType::LOWER_CASE_CHAR );
+        if( nPos == STRING_LEN )
+            nPos = nOldPos;
+        else if( nPos > nMaxPos )
+            nPos = nMaxPos;
+    }
+
+    while( nOldPos < nMaxPos )
+    {
+
+        //  The lower ones...
+        if( nOldPos != nPos )
+        {
+            SV_STAT( nGetTextSize );
+            pLastFont = pSmallFont;
+            pLastFont->SetDevFont( rDo.GetInf().GetShell(), rDo.GetOut() );
+            rDo.GetInf().SetIdx( nOldPos );
+            rDo.GetInf().SetLen( nPos - nOldPos );
+            rDo.GetInf().SetUpper( FALSE );
+            aPartSize = pSmallFont->GetTextSize( rDo.GetInf().GetShell(),
+                 pOutSize, rDo.GetInf().GetText(), rDo.GetInf().GetIdx(),
+                 rDo.GetInf().GetLen(), rDo.GetInf().GetKern() );
+            if( nKern && nPos < nMaxPos )
+                aPartSize.Width() += nKern;
+            rDo.Do();
+            nOldPos = nPos;
+        }
+        nPos = pBreakIt->xBreak->nextCharBlock( rOldText, nPos,
+               pBreakIt->GetLocale( eLng ), CharType::LOWER_CASE_CHAR );
+        if( nPos == STRING_LEN || nPos > nMaxPos )
+            nPos = nMaxPos;
+        ASSERT( nPos, "nextCharBlock not implemented?" );
+#ifndef PRODUCT
+        if( !nPos )
+            nPos = nMaxPos;
+#endif
+        // The upper ones...
+        if( nOldPos != nPos )
+        {
+            do
+            {
+                rDo.GetInf().SetUpper( TRUE );
+                pLastFont = pBigFont;
+                pLastFont->SetDevFont( rDo.GetInf().GetShell(), rDo.GetOut() );
+                xub_StrLen nTmp;
+                if( bWordWise )
+                {
+                    nTmp = nOldPos;
+                    while( nTmp < nPos && CH_BLANK == rOldText.GetChar( nTmp ) )
+                        ++nTmp;
+                    if( nOldPos < nTmp )
+                    {
+                        pLastFont = pSpaceFont;
+                        pLastFont->SetDevFont( rDo.GetInf().GetShell(),
+                                               rDo.GetOut() );
+                        ((SwDoDrawCapital&)rDo).DrawSpace( aStartPos );
+                        pLastFont = pBigFont;
+                        pLastFont->SetDevFont( rDo.GetInf().GetShell(),
+                                               rDo.GetOut() );
+                        rDo.GetInf().SetIdx( nOldPos );
+                        rDo.GetInf().SetLen( nTmp - nOldPos );
+                        aPartSize = pBigFont->GetTextSize( rDo.GetInf().
+                            GetShell(), pOutSize, aTxt, rDo.GetInf().GetIdx(),
+                              rDo.GetInf().GetLen(), rDo.GetInf().GetKern() );
+                        if( rDo.GetInf().GetSpace() )
+                            aPartSize.Width() += rDo.GetInf().GetSpace() *
+                                                 ( nTmp - nOldPos );
+                        if( nKern && nPos < nMaxPos )
+                            aPartSize.Width() += nKern;
+                        rDo.Do();
+                        aStartPos = rDo.GetInf().GetPos();
+                        nOldPos = nTmp;
+                    }
+                    while( nTmp < nPos && CH_BLANK != rOldText.GetChar( nTmp ) )
+                        ++nTmp;
+                }
+                else
+                    nTmp = nPos;
+                if( nTmp > nOldPos )
+                {
+                    rDo.GetInf().SetIdx( nOldPos );
+                    rDo.GetInf().SetLen( nTmp - nOldPos );
+                    aPartSize = pBigFont->GetTextSize( rDo.GetInf().GetShell(),
+                                  pOutSize, aTxt, rDo.GetInf().GetIdx(),
+                                  rDo.GetInf().GetLen(), rDo.GetInf().GetKern() );
+                    if( !bWordWise && rDo.GetInf().GetSpace() )
+                        for( xub_StrLen nI = nOldPos; nI < nPos; ++nI )
+                            if( CH_BLANK == rOldText.GetChar( nI ) )
+                            aPartSize.Width() += rDo.GetInf().GetSpace();
+                    if( nKern && nPos < nMaxPos )
+                        aPartSize.Width() += nKern;
+                    rDo.Do();
+                    nOldPos = nTmp;
+                }
+            } while( nOldPos != nPos );
+        }
+        nPos = pBreakIt->xBreak->endOfCharBlock( rOldText, nPos,
+               pBreakIt->GetLocale( eLng ), CharType::LOWER_CASE_CHAR );
+        if( nPos == STRING_LEN || nPos > nMaxPos )
+            nPos = nMaxPos;
+        ASSERT( nPos, "endOfCharBlock not implemented?" );
+#ifndef PRODUCT
+        if( !nPos )
+            nPos = nMaxPos;
+#endif
+    }
+
+    // Aufraeumen:
+    if( pBigFont != pOldLast )
+        delete pBigFontAccess;
+
+    if( bUnderStriked )
+    {
+        if( rDo.GetInf().GetDrawSpace() )
+        {
+            pLastFont = pSpaceFont;
+            pLastFont->SetDevFont( rDo.GetInf().GetShell(), rDo.GetOut() );
+            ( (SwDoDrawCapital&) rDo ).DrawSpace( aStartPos );
+        }
+        if ( bWordWise )
+            delete pSpaceFontAccess;
+    }
+    pLastFont = pOldLast;
+    pLastFont->SetDevFont( rDo.GetInf().GetShell(), rDo.GetOut() );
+
+    delete pSmallFontAccess;
+    rDo.GetInf().SetText( rOldText );
+}
+
+
diff --git a/sw/source/core/txtnode/makefile.mk b/sw/source/core/txtnode/makefile.mk
new file mode 100644
index 000000000000..abc0391e6798
--- /dev/null
+++ b/sw/source/core/txtnode/makefile.mk
@@ -0,0 +1,145 @@
+#*************************************************************************
+#
+#   $RCSfile: makefile.mk,v $
+#
+#   $Revision: 1.1.1.1 $
+#
+#   last change: $Author: hr $ $Date: 2000-09-19 00:08:27 $
+#
+#   The Contents of this file are made available subject to the terms of
+#   either of the following licenses
+#
+#          - GNU Lesser General Public License Version 2.1
+#          - Sun Industry Standards Source License Version 1.1
+#
+#   Sun Microsystems Inc., October, 2000
+#
+#   GNU Lesser General Public License Version 2.1
+#   =============================================
+#   Copyright 2000 by Sun Microsystems, Inc.
+#   901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+#   This library is free software; you can redistribute it and/or
+#   modify it under the terms of the GNU Lesser General Public
+#   License version 2.1, as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   Lesser General Public License for more details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+#   License along with this library; if not, write to the Free Software
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+#   MA  02111-1307  USA
+#
+#
+#   Sun Industry Standards Source License Version 1.1
+#   =================================================
+#   The contents of this file are subject to the Sun Industry Standards
+#   Source License Version 1.1 (the "License"); You may not use this file
+#   except in compliance with the License. You may obtain a copy of the
+#   License at http://www.openoffice.org/license.html.
+#
+#   Software provided under this License is provided on an "AS IS" basis,
+#   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+#   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+#   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+#   See the License for the specific provisions governing your rights and
+#   obligations concerning the Software.
+#
+#   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+#   Copyright: 2000 by Sun Microsystems, Inc.
+#
+#   All Rights Reserved.
+#
+#   Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sw
+TARGET=txtnode
+
+AUTOSEG=true
+
+PROJECTPCH=core_pch
+PDBTARGET=core_pch
+PROJECTPCHSOURCE=..$/core_1st$/core_pch
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE :  $(PRJ)$/inc$/swpre.mk
+.INCLUDE :  settings.mk
+.INCLUDE :  $(PRJ)$/inc$/sw.mk
+
+INCEXT=s:$/solar$/inc$/hm
+
+.IF "$(mydebug)" != ""
+CDEFS+=-Dmydebug
+.ENDIF
+
+.IF "$(GUI)$(COM)" == "WINMSC"
+LIBFLAGS=/NOI /NOE /PAGE:512
+.ENDIF
+
+# --- Files --------------------------------------------------------
+
+CXXFILES = \
+        atrfld.cxx \
+        atrflyin.cxx \
+        atrftn.cxx \
+        atrref.cxx \
+        atrtox.cxx \
+        chrfmt.cxx \
+        fmtatr1.cxx \
+        fmtatr2.cxx \
+        fntcap.cxx \
+        fntcache.cxx \
+        swfntcch.cxx \
+        ndhints.cxx \
+        ndtxt.cxx \
+        swfont.cxx \
+        thints.cxx \
+        txatbase.cxx \
+        txtatr0.cxx \
+        txtatr1.cxx \
+        txtatr2.cxx \
+        txtedt.cxx
+
+
+
+SLOFILES =  \
+        $(SLO)$/atrfld.obj \
+        $(SLO)$/atrflyin.obj \
+        $(SLO)$/atrftn.obj \
+        $(SLO)$/atrref.obj \
+        $(SLO)$/atrtox.obj \
+        $(SLO)$/chrfmt.obj \
+        $(SLO)$/fmtatr1.obj \
+        $(SLO)$/fmtatr2.obj \
+        $(SLO)$/fntcap.obj \
+        $(SLO)$/fntcache.obj \
+        $(SLO)$/swfntcch.obj \
+        $(SLO)$/ndhints.obj \
+        $(SLO)$/ndtxt.obj \
+        $(SLO)$/swfont.obj \
+        $(SLO)$/thints.obj \
+        $(SLO)$/txatbase.obj \
+        $(SLO)$/txtatr0.obj \
+        $(SLO)$/txtatr1.obj \
+        $(SLO)$/txtatr2.obj \
+        $(SLO)$/txtedt.obj
+
+.IF "$(dbutil)" != ""
+OFILES+=$(SLO)$/dbchratr.$(QBJX)
+.ENDIF
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE :  target.mk
+
diff --git a/sw/source/core/txtnode/ndhints.cxx b/sw/source/core/txtnode/ndhints.cxx
new file mode 100644
index 000000000000..18fe16067991
--- /dev/null
+++ b/sw/source/core/txtnode/ndhints.cxx
@@ -0,0 +1,464 @@
+/*************************************************************************
+ *
+ *  $RCSfile: ndhints.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:27 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "txatbase.hxx"
+#include "ndhints.hxx"
+
+#ifndef PRODUCT
+#define CHECK   Check();
+#else
+#define CHECK
+#endif
+
+_SV_IMPL_SORTAR_ALG( SwpHtStart, SwTxtAttr* )
+_SV_IMPL_SORTAR_ALG( SwpHtEnd, SwTxtAttr* )
+
+#ifdef NIE
+
+void DumpHints( const SwpHtStart &rHtStart,
+                const SwpHtEnd &rHtEnd )
+{
+#ifndef PRODUCT
+    aDbstream << "DumpHints:" << endl;
+    (aDbstream << "\tStarts:" ).WriteNumber(rHtStart.Count()) << endl;
+    for( USHORT i = 0; i < rHtStart.Count(); ++i )
+    {
+        const SwTxtAttr *pHt = rHtStart[i];
+        ((((aDbstream << '\t').WriteNumber( i )<< " [").WriteNumber( pHt->Which() )
+            << ']' << '\t').WriteNumber( long( pHt ) )
+                  << '\t').WriteNumber( *pHt->GetStart() );
+        if( pHt->GetEnd() )
+            (aDbstream << " -> " ).WriteNumber( *pHt->GetEnd() );
+        aDbstream << endl;
+    }
+    (aDbstream << "\tEnds:").WriteNumber( rHtEnd.Count() )<< endl;
+    for( i = 0; i < rHtEnd.Count(); ++i )
+    {
+        const SwTxtAttr *pHt = rHtEnd[i];
+        (((aDbstream << '\t').WriteNumber( i )<< " [").WriteNumber( pHt->Which() )
+            << ']' << '\t' ).WriteNumber( long( pHt ) );
+        if( pHt->GetEnd() )
+            (aDbstream << '\t').WriteNumber( *pHt->GetEnd() )<< " <- ";
+        aDbstream.WriteNumber( *pHt->GetStart() )<< endl;
+    }
+    aDbstream << endl;
+#endif
+}
+#else
+inline void DumpHints(const SwpHtStart &, const SwpHtEnd &) { }
+#endif
+
+/*************************************************************************
+ *                        inline IsEqual()
+ *************************************************************************/
+
+inline BOOL IsEqual( const SwTxtAttr &rHt1, const SwTxtAttr &rHt2 )
+{
+    return (long)(&rHt1) == (long)(&rHt2);
+}
+
+/*************************************************************************
+ *                      IsLessStart()
+ *************************************************************************/
+
+// SV_IMPL_OP_PTRARR_SORT( SwpHtStart, SwTxtAttr* )
+// kein SV_IMPL_PTRARR_SORT( name,ArrElement )
+// unser SEEK_PTR_TO_OBJECT_NOTL( name,ArrElement )
+
+// Sortierreihenfolge: Start, Ende (umgekehrt!), Which-Wert (umgekehrt!),
+//                     als letztes die Adresse selbst
+
+BOOL lcl_IsLessStart( const SwTxtAttr &rHt1, const SwTxtAttr &rHt2 )
+{
+    if ( *rHt1.GetStart() == *rHt2.GetStart() )
+    {
+        xub_StrLen nHt1 = *rHt1.GetAnyEnd();
+        xub_StrLen nHt2 = *rHt2.GetAnyEnd();
+        if ( nHt1 == nHt2 )
+        {
+            nHt1 = rHt1.Which();
+            nHt2 = rHt2.Which();
+            return nHt1 > nHt2 ||
+                (nHt1 == nHt2 && (long)&rHt1 < (long)&rHt2);
+        }
+        else
+            return ( nHt1 > nHt2 );
+    }
+    return ( *rHt1.GetStart() < *rHt2.GetStart() );
+}
+
+/*************************************************************************
+ *                      inline IsLessEnd()
+ *************************************************************************/
+
+// Zuerst nach Ende danach nach Ptr
+#ifdef HP9000
+BOOL lcl_IsLessEnd( const SwTxtAttr &rHt1, const SwTxtAttr &rHt2 )
+#else
+inline BOOL lcl_IsLessEnd( const SwTxtAttr &rHt1, const SwTxtAttr &rHt2 )
+#endif
+{
+    xub_StrLen nHt1 = *rHt1.GetAnyEnd();
+    xub_StrLen nHt2 = *rHt2.GetAnyEnd();
+    if ( nHt1 == nHt2 )
+    {
+        if ( *rHt1.GetStart() == *rHt2.GetStart() )
+        {
+            nHt1 = rHt1.Which();
+            nHt2 = rHt2.Which();
+            return nHt1 < nHt2 ||
+                (nHt1 == nHt2 && (long)&rHt1 > (long)&rHt2);
+        }
+        else
+            return ( *rHt1.GetStart() > *rHt2.GetStart() );
+    }
+    return ( nHt1 < nHt2 );
+}
+
+/*************************************************************************
+ *                      SwpHtStart::Seek_Entry()
+ *************************************************************************/
+
+BOOL SwpHtStart::Seek_Entry( const SwTxtAttr *pElement, USHORT *pPos ) const
+{
+    register USHORT nOben = Count(), nMitte, nUnten = 0;
+    if( nOben > 0 )
+    {
+        nOben--;
+        while( nUnten <= nOben )
+        {
+            nMitte = nUnten + ( nOben - nUnten ) / 2;
+            const SwTxtAttr *pMitte = (*this)[nMitte];
+            if( IsEqual( *pMitte, *pElement ) )
+            {
+                *pPos = nMitte;
+                return TRUE;
+            }
+            else
+                if( lcl_IsLessStart( *pMitte, *pElement ) )
+                    nUnten = nMitte + 1;
+                else
+                    if( nMitte == 0 )
+                    {
+                        *pPos = nUnten;
+                        return FALSE;
+                    }
+                    else
+                        nOben = nMitte - 1;
+        }
+    }
+    *pPos = nUnten;
+    return FALSE;
+}
+
+/*************************************************************************
+ *                      SwpHtEnd::Seek_Entry()
+ *************************************************************************/
+
+BOOL SwpHtEnd::Seek_Entry( const SwTxtAttr *pElement, USHORT *pPos ) const
+{
+    register USHORT nOben = Count(), nMitte, nUnten = 0;
+    if( nOben > 0 )
+    {
+        nOben--;
+        while( nUnten <= nOben )
+        {
+            nMitte = nUnten + ( nOben - nUnten ) / 2;
+            const SwTxtAttr *pMitte = (*this)[nMitte];
+            if( IsEqual( *pMitte, *pElement ) )
+            {
+                *pPos = nMitte;
+                return TRUE;
+            }
+            else
+                if( lcl_IsLessEnd( *pMitte, *pElement ) )
+                    nUnten = nMitte + 1;
+                else
+                    if( nMitte == 0 )
+                    {
+                        *pPos = nUnten;
+                        return FALSE;
+                    }
+                    else
+                        nOben = nMitte - 1;
+        }
+    }
+    *pPos = nUnten;
+    return FALSE;
+}
+
+/*************************************************************************
+ *                      class SwpHintsArr
+ *************************************************************************/
+
+void SwpHintsArr::Insert( const SwTxtAttr *pHt )
+{
+    Resort();
+#ifndef PRODUCT
+    USHORT nPos;
+    ASSERT(!SwpHtStart::Seek_Entry( pHt, &nPos ), "Insert: hint already in HtStart");
+    ASSERT(!aHtEnd.Seek_Entry( pHt, &nPos ), "Insert: hint already in HtEnd");
+#endif
+    SwpHtStart::Insert( pHt );
+    aHtEnd.Insert( pHt );
+#ifndef PRODUCT
+#ifdef NIE
+    (aDbstream << "Insert: " ).WriteNumber( long( pHt ) )<< endl;
+    DumpHints( *this, aHtEnd );
+#endif
+#endif
+    CHECK;
+}
+
+void SwpHintsArr::DeleteAtPos( const USHORT nPos )
+{
+    // Optimierung: nPos bezieht sich auf die Position im StartArray, also:
+    const SwTxtAttr *pHt = SwpHtStart::operator[]( nPos );
+    SwpHtStart::Remove( nPos );
+
+    Resort();
+
+    USHORT nEndPos;
+    aHtEnd.Seek_Entry( pHt, &nEndPos );
+    aHtEnd.Remove( nEndPos );
+#ifndef PRODUCT
+#ifdef NIE
+    (aDbstream << "DeleteAtPos: " ).WriteNumber( long( pHt ) )<< endl;
+    DumpHints( *this, aHtEnd );
+#endif
+#endif
+    CHECK;
+}
+
+#ifndef PRODUCT
+
+/*************************************************************************
+ *                      SwpHintsArr::Check()
+ *************************************************************************/
+
+
+#define CHECK_ERR(cond, text) \
+        if(!(cond)) \
+        { \
+            ASSERT(!this, text); \
+            DumpHints(*(SwpHtStart*)this,aHtEnd); \
+            const BOOL bErr = 0 == (cond); /* fuer den CV */ \
+            return !((SwpHintsArr*)this)->Resort(); \
+        }
+
+BOOL SwpHintsArr::Check() const
+{
+    // 1) gleiche Anzahl in beiden Arrays
+    CHECK_ERR( Count() == aHtEnd.Count(), "HintsCheck: wrong sizes" );
+    xub_StrLen nLastStart = 0;
+    xub_StrLen nLastEnd   = 0;
+
+    const SwTxtAttr *pLastStart = 0;
+    const SwTxtAttr *pLastEnd = 0;
+
+    for( USHORT i = 0; i < Count(); ++i )
+    {
+        // --- Start-Kontrolle ---
+
+        // 2a) gueltiger Pointer? vgl. DELETEFF
+        const SwTxtAttr *pHt = (*this)[i];
+        CHECK_ERR( 0xFF != *(char*)pHt, "HintsCheck: start ptr was deleted" );
+
+        // 3a) Stimmt die Start-Sortierung?
+        xub_StrLen nIdx = *pHt->GetStart();
+        CHECK_ERR( nIdx >= nLastStart, "HintsCheck: starts are unsorted" );
+
+        // 4a) IsLessStart-Konsistenz
+        if( pLastStart )
+            CHECK_ERR( lcl_IsLessStart( *pLastStart, *pHt ), "HintsCheck: IsLastStart" );
+
+        nLastStart = nIdx;
+        pLastStart = pHt;
+
+        // --- End-Kontrolle ---
+
+        // 2b) gueltiger Pointer? vgl. DELETEFF
+        const SwTxtAttr *pHtEnd = aHtEnd[i];
+        CHECK_ERR( 0xFF != *(char*)pHtEnd, "HintsCheck: end ptr was deleted" );
+
+        // 3b) Stimmt die End-Sortierung?
+        nIdx = *pHtEnd->GetAnyEnd();
+        CHECK_ERR( nIdx >= nLastEnd, "HintsCheck: ends are unsorted" );
+        nLastEnd = nIdx;
+
+        // 4b) IsLessEnd-Konsistenz
+        if( pLastEnd )
+            CHECK_ERR( lcl_IsLessEnd( *pLastEnd, *pHtEnd ), "HintsCheck: IsLastEnd" );
+
+        nLastEnd = nIdx;
+        pLastEnd = pHtEnd;
+
+        // --- Ueberkreuzungen ---
+
+        // 5) gleiche Pointer in beiden Arrays
+        nIdx = GetStartOf( pHtEnd );
+        CHECK_ERR( STRING_LEN != nIdx, "HintsCheck: no GetStartOf" );
+
+        // 6) gleiche Pointer in beiden Arrays
+        nIdx = GetEndOf( pHt );
+        CHECK_ERR( STRING_LEN != nIdx, "HintsCheck: no GetEndOf" );
+    }
+    return TRUE;
+}
+
+#endif      /* PRODUCT */
+
+/*************************************************************************
+ *                          SwpHintsArr::Resort()
+ *************************************************************************/
+
+// Resort() wird vor jedem Insert und Delete gerufen.
+// Wenn Textmasse geloescht wird, so werden die Indizes in
+// ndtxt.cxx angepasst. Leider erfolgt noch keine Neusortierung
+// auf gleichen Positionen.
+
+BOOL SwpHintsArr::Resort()
+{
+    BOOL bResort = FALSE;
+    const SwTxtAttr *pLast = 0;
+    for( USHORT i = 0; i < SwpHtStart::Count(); ++i )
+    {
+        const SwTxtAttr *pHt = (*this)[i];
+        if( pLast && !lcl_IsLessStart( *pLast, *pHt ) )
+        {
+#ifdef NIE
+#ifndef PRODUCT
+//            ASSERT( bResort, "!Resort/Start: correcting hints-array" );
+            aDbstream << "Resort: Starts" << endl;
+            DumpHints( *this, aHtEnd );
+#endif
+#endif
+            // Aufpassen: nicht die unsere SwpHintsArr-Methoden rufen,
+            // weil dort ein Resort steht!
+            // AMA: Bisher ( -> USED ) wurde ein Arrayinhalt [3,4,4,3] nur in
+            //      [3,4,3,4] sortiert, nicht in [3,3,4,4]
+#ifdef USED
+            SwpHtStart::Delete( i - 1 );
+            SwpHtStart::Insert( pLast );
+            USHORT nPos;
+            if( SwpHtStart::Seek_Entry( pLast, &nPos ) && nPos > i )
+                --i;
+#else
+            SwpHtStart::Remove( i );
+            SwpHtStart::Insert( pHt );
+            pHt = (*this)[i];
+            if ( pHt != pLast )
+                --i;
+#endif //!USED
+            bResort = TRUE;
+        }
+        pLast = pHt;
+    }
+
+    pLast = 0;
+    for( i = 0; i < aHtEnd.Count(); ++i )
+    {
+        const SwTxtAttr *pHt = aHtEnd[i];
+        if( pLast && !lcl_IsLessEnd( *pLast, *pHt ) )
+        {
+#ifdef NIE
+#ifndef PRODUCT
+//            ASSERT( bResort, "!Resort/Ends: correcting hints-array" );
+            aDbstream << "Resort: Ends" << endl;
+            DumpHints( *this, aHtEnd );
+#endif
+#endif
+// AMA: siehe oben
+#ifdef USED
+            aHtEnd.Delete( i - 1 );
+            aHtEnd.Insert( pLast );
+            USHORT nPos;
+            if( aHtEnd.Seek_Entry( pLast, &nPos ) && nPos > i )
+                --i;
+#else
+            aHtEnd.Remove( i );
+            aHtEnd.Insert( pHt );
+            pHt = aHtEnd[i]; // normalerweise == pLast
+            // Wenn die Unordnung etwas groesser ist (24200),
+            // muessen wir Position i erneut vergleichen.
+            if ( pLast != pHt )
+                --i;
+#endif //!USED
+            bResort = TRUE;
+        }
+        pLast = pHt;
+    }
+#ifndef PRODUCT
+#ifdef NIE
+    aDbstream << "Resorted:" << endl;
+    DumpHints( *this, aHtEnd );
+#endif
+#endif
+    return bResort;
+}
+
+
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
new file mode 100644
index 000000000000..16d55d204c46
--- /dev/null
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -0,0 +1,2738 @@
+/*************************************************************************
+ *
+ *  $RCSfile: ndtxt.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:27 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include 
+
+#ifndef _SVX_FONTITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BRKITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_ESCPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef SVTOOLS_URIHELPER_HXX
+#include 
+#endif
+
+#ifndef _TXTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _TXTINET_HXX //autogen
+#include 
+#endif
+#ifndef _FMTINFMT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTPDSC_HXX //autogen
+#include 
+#endif
+#ifndef _TXTATR_HXX //autogen
+#include 
+#endif
+#ifndef _FMTHBSH_HXX //autogen
+#include 
+#endif
+#ifndef _FMTRFMRK_HXX //autogen
+#include 
+#endif
+#ifndef _TXTTXMRK_HXX //autogen
+#include 
+#endif
+#ifndef _FCHRFMT_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFTN_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFLCNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _FRMATR_HXX
+#include 
+#endif
+#ifndef _CHARATR_HXX
+#include 
+#endif
+#ifndef _FTNIDX_HXX //autogen
+#include 
+#endif
+#ifndef _FTNINFO_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFTN_HXX //autogen
+#include 
+#endif
+#ifndef _CHARFMT_HXX //autogen
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include                   // fuer SwPosition
+#endif
+#ifndef _FLDBAS_HXX
+#include 
+#endif
+#ifndef _ERRHDL_HXX
+#include 
+#endif
+#ifndef _FMTCOL_HXX
+#include 
+#endif
+#ifndef _PARATR_HXX
+#include 
+#endif
+#ifndef _TXTFRM_HXX
+#include 
+#endif
+#ifndef _FTNFRM_HXX
+#include 
+#endif
+#ifndef _FTNBOSS_HXX
+#include 
+#endif
+#ifndef _HINTS_HXX
+#include                 // fuer SwFmtChg in ChgTxtColl
+#endif
+#ifndef _PAGEDESC_HXX
+#include              // fuer SwPageDesc
+#endif
+#ifndef _EXPFLD_HXX
+#include                // fuer SwTblField
+#endif
+#ifndef _SECTION_HXX
+#include               // fuer SwSection
+#endif
+#ifndef _MVSAVE_HXX
+#include 
+#endif
+#ifndef _SWCACHE_HXX
+#include 
+#endif
+#ifndef _WRONG_HXX
+#include                 // fuer die WrongList des OnlineSpellings
+#endif
+#ifndef _DCONTACT_HXX
+#include 
+#endif
+#ifndef _REDLINE_HXX
+#include 
+#endif
+#ifndef _DOCTXM_HXX
+#include 
+#endif
+#ifndef _BOOKMRK_HXX
+#include 
+#endif
+
+
+
+SV_DECL_PTRARR( TmpHints, SwTxtAttr*, 0, 4 )
+
+TYPEINIT1( SwTxtNode, SwCntntNode )
+
+SV_DECL_PTRARR(SwpHts,SwTxtAttr*,1,1)
+
+// Leider ist das SwpHints nicht ganz wasserdicht:
+// Jeder darf an den Hints rumfummeln, ohne die Sortierreihenfolge
+// und Verkettung sicherstellen zu muessen.
+#ifndef PRODUCT
+#define CHECK_SWPHINTS(pNd)  { if(pNd->GetpSwpHints()) \
+                                  pNd->GetpSwpHints()->Check(); }
+#else
+#define CHECK_SWPHINTS(pNd)
+#endif
+
+SwTxtNode *SwNodes::MakeTxtNode( const SwNodeIndex & rWhere,
+                                 SwTxtFmtColl *pColl,
+                                 SwAttrSet* pAutoAttr )
+{
+    ASSERT( pColl, "Collectionpointer ist 0." );
+
+    SwTxtNode *pNode = new SwTxtNode( rWhere, pColl, pAutoAttr );
+
+    SwNodeIndex aIdx( *pNode );
+
+    if( pColl && NO_NUMBERING != pColl->GetOutlineLevel() && IsDocNodes() )
+        UpdateOutlineNode( *pNode, NO_NUMBERING, pColl->GetOutlineLevel() );
+
+    //Wenn es noch kein Layout gibt oder in einer versteckten Section
+    // stehen, brauchen wir uns um das MakeFrms nicht bemuehen.
+    const SwSectionNode* pSectNd;
+    if( !GetDoc()->GetRootFrm() ||
+        ( 0 != (pSectNd = pNode->FindSectionNode()) &&
+            pSectNd->GetSection().IsHiddenFlag() ))
+        return pNode;
+
+    SwNodeIndex aTmp( rWhere );
+    do {
+        // max. 2 Durchlaeufe:
+        // 1. den Nachfolger nehmen
+        // 2. den Vorgaenger
+
+        SwNode *pNd;
+        switch( ( pNd = (*this)[aTmp] )->GetNodeType() )
+        {
+        case ND_TABLENODE:
+            ((SwTableNode*)pNd)->MakeFrms( aIdx );
+            return pNode;
+
+        case ND_SECTIONNODE:
+            if( ((SwSectionNode*)pNd)->GetSection().IsHidden() ||
+                ((SwSectionNode*)pNd)->IsCntntHidden() )
+            {
+                SwNodeIndex aTmpIdx( *pNode );
+                pNd = FindPrvNxtFrmNode( aTmpIdx, pNode );
+                if( !pNd )
+                    return pNode;
+                aTmp = *pNd;
+                break;
+            }
+            ((SwSectionNode*)pNd)->MakeFrms( aIdx );
+            return pNode;
+
+        case ND_TEXTNODE:
+        case ND_GRFNODE:
+        case ND_OLENODE:
+            ((SwCntntNode*)pNd)->MakeFrms( *pNode );
+            return pNode;
+
+        case ND_ENDNODE:
+            if( pNd->FindStartNode()->IsSectionNode() &&
+                aTmp.GetIndex() < rWhere.GetIndex() )
+            {
+                if( pNd->FindStartNode()->GetSectionNode()->GetSection().IsHiddenFlag())
+                {
+                    if( !GoPrevSection( &aTmp, TRUE, FALSE ) ||
+                        aTmp.GetNode().FindTableNode() !=
+                            pNode->FindTableNode() )
+                        return pNode;       // schade, das wars
+                }
+                else
+                    aTmp = *pNd->FindStartNode();
+                break;
+            }
+            else if( pNd->FindStartNode()->IsTableNode() &&
+                    aTmp.GetIndex() < rWhere.GetIndex() )
+            {
+                // wir stehen hinter einem TabellenNode
+                aTmp = *pNd->FindStartNode();
+                break;
+            }
+            // kein break !!!
+        default:
+            if( rWhere == aTmp )
+                aTmp -= 2;
+            else
+                return pNode;
+            break;
+        }
+    } while( TRUE );
+}
+
+
+
+// --------------------
+// SwTxtNode
+// --------------------
+
+SwTxtNode::SwTxtNode( const SwNodeIndex &rWhere,
+                      SwTxtFmtColl *pTxtColl,
+                      SwAttrSet* pAutoAttr )
+    : SwCntntNode( rWhere, ND_TEXTNODE, pTxtColl ),
+      pSwpHints( 0 ), pWrong( 0 ), pNdNum( 0 ), pNdOutl( 0 )
+{
+    // soll eine Harte-Attributierung gesetzt werden?
+    if( pAutoAttr )
+        SwCntntNode::SetAttr( *pAutoAttr );
+
+    const SfxPoolItem* pItem;
+    if( GetNodes().IsDocNodes() &&
+        SFX_ITEM_SET == GetSwAttrSet().GetItemState( RES_PARATR_NUMRULE,
+        TRUE, &pItem ) && ((SwNumRuleItem*)pItem)->GetValue().Len() )
+    {
+        pNdNum = new SwNodeNum( 0 );
+        SwNumRule* pRule = GetDoc()->FindNumRulePtr(
+                                    ((SwNumRuleItem*)pItem)->GetValue() );
+        if( pRule )
+            pRule->SetInvalidRule( TRUE );
+    }
+}
+
+SwTxtNode::~SwTxtNode()
+{
+    // delete loescht nur die Pointer, nicht die Arrayelemente!
+    if( pSwpHints )
+    {
+        // damit Attribute die ihren Inhalt entfernen nicht doppelt
+        // geloescht werden.
+        SwpHints* pTmpHints = pSwpHints;
+        pSwpHints = 0;
+
+        for( register USHORT j = pTmpHints->Count(); j; )
+            // erst muss das Attribut aus dem Array entfernt werden,
+            // denn sonst wuerde es sich selbst loeschen (Felder) !!!!
+            DestroyAttr( pTmpHints->GetHt( --j ) );
+
+        delete pTmpHints;
+    }
+    delete pWrong;
+    // Achtung. im Dtor von SwCntntNode kann DelFrms gerufen werden, wo
+    // ggf. pWrong nochmal deletet wird, deshalb diese Zuweisung
+    pWrong = NULL; // hier nicht wegoptimieren!
+
+    delete pNdNum, pNdNum = 0;      // ggfs. wird in der BasisKlasse noch
+    delete pNdOutl, pNdOutl = 0;    // darauf zugegriffen??
+}
+
+SwCntntFrm *SwTxtNode::MakeFrm()
+{
+    SwCntntFrm *pFrm = new SwTxtFrm(this);
+    return pFrm;
+}
+
+xub_StrLen SwTxtNode::Len() const
+{
+    return aText.Len();
+}
+
+/*---------------------------------------------------------------------------
+ * lcl_ChangeFtnRef
+ *  After a split node, it's necessary to actualize the ref-pointer of the
+ *  ftnfrms.
+ * --------------------------------------------------------------------------*/
+
+void lcl_ChangeFtnRef( SwTxtNode &rNode )
+{
+    SwpHints *pSwpHints = rNode.GetpSwpHints();
+    if( pSwpHints && rNode.GetDoc()->GetRootFrm() )
+    {
+        SwTxtAttr* pHt;
+        SwCntntFrm* pFrm = NULL;
+        for( register USHORT j = pSwpHints->Count(); j; )
+            if( RES_TXTATR_FTN == (pHt = pSwpHints->GetHt(--j))->Which() )
+            {
+                if( !pFrm )
+                {
+                    SwClientIter aNew( rNode );
+                    pFrm = (SwCntntFrm*)aNew.First( TYPE(SwCntntFrm) );
+//JP 11.07.00: the assert's shows incorrect an error when nodes are converted
+//              to a table. Then no layout exist!
+//                  ASSERT( pFrm, "lcl_ChangeFtnRef: No TxtFrm" );
+//                  ASSERT( pFrm && !aNew.Next(),"lcl_ChangeFtnRef: Doublefault");
+                    if( !pFrm )
+                        return;
+                }
+                SwTxtFtn *pAttr = (SwTxtFtn*)pHt;
+                ASSERT( pAttr->GetStartNode(), "FtnAtr ohne StartNode." );
+                SwNodeIndex aIdx( *pAttr->GetStartNode(), 1 );
+                SwCntntNode *pNd = aIdx.GetNode().GetCntntNode();
+                if ( !pNd )
+                    pNd = pFrm->GetAttrSet()->GetDoc()->
+                            GetNodes().GoNextSection( &aIdx, TRUE, FALSE );
+                if ( !pNd )
+                    continue;
+                SwClientIter aIter( *pNd );
+                SwCntntFrm* pCntnt = (SwCntntFrm*)aIter.First(TYPE(SwCntntFrm));
+                if( pCntnt )
+                {
+                    ASSERT( pCntnt->FindRootFrm() == pFrm->FindRootFrm(),
+                            "lcl_ChangeFtnRef: Layout double?" );
+                    SwFtnFrm *pFtn = pCntnt->FindFtnFrm();
+                    if( pFtn && pFtn->GetAttr() == pAttr )
+                    {
+                        while( pFtn->GetMaster() )
+                            pFtn = pFtn->GetMaster();
+                        while ( pFtn )
+                        {
+                            pFtn->SetRef( pFrm );
+                            pFtn = pFtn->GetFollow();
+                            ((SwTxtFrm*)pFrm)->SetFtn( TRUE );
+                        }
+                    }
+#ifndef PRODUCT
+                    while( 0 != (pCntnt = (SwCntntFrm*)aIter.Next()) )
+                    {
+                        SwFtnFrm *pFtn = pCntnt->FindFtnFrm();
+                        ASSERT( !pFtn || pFtn->GetRef() == pFrm,
+                                "lcl_ChangeFtnRef: Who's that guy?" );
+                    }
+#endif
+                }
+            }
+    }
+}
+
+SwCntntNode *SwTxtNode::SplitNode( const SwPosition &rPos )
+{
+    // lege den Node "vor" mir an
+    register xub_StrLen nSplitPos = rPos.nContent.GetIndex(),
+                    nTxtLen = aText.Len();
+    SwTxtNode* pNode = _MakeNewTxtNode( rPos.nNode, FALSE, nSplitPos==nTxtLen );
+
+    if( GetDepends() && aText.Len() && (nTxtLen / 2) < nSplitPos )
+    {
+// JP 25.04.95: Optimierung fuer SplitNode:
+//              Wird am Ende vom Node gesplittet, dann verschiebe die
+//              Frames vom akt. auf den neuen und erzeuge fuer den akt.
+//              neue. Dadurch entfaellt das neu aufbauen vom Layout.
+
+        LockModify();   // Benachrichtigungen abschalten
+
+        // werden FlyFrames mit verschoben, so muessen diese nicht ihre
+        // Frames zerstoeren. Im SwTxtFly::SetAnchor wird es abgefragt!
+        if( pSwpHints )
+        {
+            if( !pNode->pSwpHints )
+                pNode->pSwpHints = new SwpHints;
+            pNode->pSwpHints->bInSplitNode = TRUE;
+        }
+
+        //Ersten Teil des Inhalts in den neuen Node uebertragen und
+        //im alten Node loeschen.
+        SwIndex aIdx( this );
+        Cut( pNode, aIdx, nSplitPos );
+
+        if( GetWrong() )
+            GetWrong()->Move( 0, -nSplitPos );
+        SetWrongDirty( TRUE );
+
+        if( pNode->pSwpHints )
+        {
+            if ( pNode->pSwpHints->CanBeDeleted() )
+            {
+                delete pNode->pSwpHints;
+                pNode->pSwpHints = 0;
+            }
+            else
+                pNode->pSwpHints->bInSplitNode = FALSE;
+
+            // alle zeichengebundenen Rahmen, die im neuen Absatz laden
+            // muessen aus den alten Frame entfernt werden:
+            // JP 01.10.96: alle leeren und nicht zu expandierenden
+            //              Attribute loeschen
+            if( pSwpHints )
+            {
+                SwTxtAttr* pHt;
+                xub_StrLen* pEnd;
+                for( register USHORT j = pSwpHints->Count(); j; )
+                    if( RES_TXTATR_FLYCNT == ( pHt = pSwpHints->GetHt( --j ) )->Which()
+                        && RES_DRAWFRMFMT != pHt->GetFlyCnt().GetFrmFmt()->Which() )
+                        pHt->GetFlyCnt().GetFrmFmt()->DelFrms();
+                    else if( pHt->DontExpand() && 0 != ( pEnd = pHt->GetEnd() )
+                            && *pHt->GetStart() == *pEnd )
+                    {
+                        // loeschen!
+                        pSwpHints->DeleteAtPos( j );
+                        DestroyAttr( pHt );
+                    }
+            }
+
+        }
+
+        SwClientIter aIter( *this );
+        SwClient* pLast = aIter.GoStart();
+        if( pLast )
+            do
+            {   SwCntntFrm *pFrm = PTR_CAST( SwCntntFrm, pLast );
+                if ( pFrm )
+                {
+                    pNode->Add( pFrm );
+                    if( pFrm->IsTxtFrm() && !pFrm->IsFollow() &&
+                        ((SwTxtFrm*)pFrm)->GetOfst() )
+                        ((SwTxtFrm*)pFrm)->SetOfst( 0 );
+                }
+            } while( 0 != ( pLast = aIter++ ));
+
+        if ( IsInCache() )
+        {
+            SwFrm::GetCache().Delete( this );
+            SetInCache( FALSE );
+        }
+
+        UnlockModify(); // Benachrichtigungen wieder freischalten
+
+        if( nTxtLen != nSplitPos )
+        {
+            // dann sage den Frames noch, das am Ende etwas "geloescht" wurde
+            if( 1 == nTxtLen - nSplitPos )
+            {
+                SwDelChr aHint( nSplitPos );
+                pNode->SwModify::Modify( 0, &aHint );
+            }
+            else
+            {
+                SwDelTxt aHint( nSplitPos, nTxtLen - nSplitPos );
+                pNode->SwModify::Modify( 0, &aHint );
+            }
+        }
+        if( pSwpHints )
+            MoveTxtAttr_To_AttrSet();
+        pNode->MakeFrms( *this );       // neue Frames anlegen.
+        lcl_ChangeFtnRef( *this );
+    }
+    else
+    {
+        //Ersten Teil des Inhalts in den neuen Node uebertragen und
+        //im alten Node loeschen.
+        SwIndex aIdx( this );
+        Cut( pNode, aIdx, rPos.nContent.GetIndex() );
+
+        // JP 01.10.96: alle leeren und nicht zu expandierenden
+        //              Attribute loeschen
+        if( pSwpHints )
+        {
+            SwTxtAttr* pHt;
+            xub_StrLen* pEnd;
+            for( register USHORT j = pSwpHints->Count(); j; )
+                if( ( pHt = pSwpHints->GetHt( --j ) )->DontExpand() &&
+                    0 != ( pEnd = pHt->GetEnd() ) && *pHt->GetStart() == *pEnd )
+                {
+                    // loeschen!
+                    pSwpHints->DeleteAtPos( j );
+                    DestroyAttr( pHt );
+                }
+            MoveTxtAttr_To_AttrSet();
+        }
+
+        if ( GetDepends() )
+            MakeFrms( *pNode );     // neue Frames anlegen.
+        lcl_ChangeFtnRef( *pNode );
+    }
+
+    {
+        //Hint fuer Pagedesc versenden. Das mueste eigntlich das Layout im
+        //Paste der Frames selbst erledigen, aber das fuehrt dann wiederum
+        //zu weiteren Folgefehlern, die mit Laufzeitkosten geloest werden
+        //muesten. #56977# #55001# #56135#
+        const SfxPoolItem *pItem;
+        if( GetDepends() && SFX_ITEM_SET == pNode->GetSwAttrSet().
+            GetItemState( RES_PAGEDESC, TRUE, &pItem ) )
+            pNode->Modify( (SfxPoolItem*)pItem, (SfxPoolItem*)pItem );
+    }
+    return pNode;
+}
+
+void SwTxtNode::MoveTxtAttr_To_AttrSet()
+{
+    ASSERT( pSwpHints, "MoveTxtAttr_To_AttrSet without SwpHints?" );
+    for( USHORT i = 0; pSwpHints && i < pSwpHints->Count(); ++i )
+    {
+        SwTxtAttr *pHt = pSwpHints->GetHt(i);
+
+        if( *pHt->GetStart() )
+            break;
+
+        const xub_StrLen* pHtEndIdx = pHt->GetEnd();
+
+        if( !pHtEndIdx )
+            continue;
+
+        const USHORT nWhich = pHt->Which();
+
+        if( *pHtEndIdx < aText.Len() || nWhich == RES_TXTATR_CHARFMT
+                                     || nWhich == RES_TXTATR_INETFMT )
+            break;
+
+        if( nWhich == RES_TXTATR_TOXMARK || nWhich == RES_TXTATR_REFMARK )
+            continue;
+
+        if( SwCntntNode::SetAttr( pHt->GetAttr() ) )
+        {
+            pSwpHints->DeleteAtPos(i);
+            DestroyAttr( pHt );
+            --i;
+        }
+    }
+
+}
+
+SwCntntNode *SwTxtNode::JoinNext()
+{
+    SwNodes& rNds = GetNodes();
+    SwNodeIndex aIdx( *this );
+    if( SwCntntNode::CanJoinNext( &aIdx ) )
+    {
+        SwDoc* pDoc = rNds.GetDoc();
+        SvULongs aBkmkArr( 15, 15 );
+        _SaveCntntIdx( pDoc, aIdx.GetIndex(), USHRT_MAX, aBkmkArr, SAVEFLY );
+        SwTxtNode *pTxtNode = aIdx.GetNode().GetTxtNode();
+        xub_StrLen nOldLen = aText.Len();
+        { // wg. SwIndex
+            pTxtNode->Cut( this, SwIndex(pTxtNode), pTxtNode->Len() );
+        }
+        // verschiebe noch alle Bookmarks/TOXMarks
+        if( aBkmkArr.Count() )
+            _RestoreCntntIdx( pDoc, aBkmkArr, GetIndex(), nOldLen );
+
+        if( pTxtNode->HasAnyIndex() )
+        {
+            // alle Crsr/StkCrsr/UnoCrsr aus dem Loeschbereich verschieben
+            pDoc->CorrAbs( aIdx, SwPosition( *this ), nOldLen, TRUE );
+        }
+        rNds.Delete(aIdx);
+        InvalidateNumRule();
+    }
+    else
+        ASSERT( FALSE, "kein TxtNode." );
+
+    return this;
+}
+
+SwCntntNode *SwTxtNode::JoinPrev()
+{
+    SwNodes& rNds = GetNodes();
+    SwNodeIndex aIdx( *this );
+    if( SwCntntNode::CanJoinPrev( &aIdx ) )
+    {
+        SwDoc* pDoc = rNds.GetDoc();
+        SvULongs aBkmkArr( 15, 15 );
+        _SaveCntntIdx( pDoc, aIdx.GetIndex(), USHRT_MAX, aBkmkArr, SAVEFLY );
+        SwTxtNode *pTxtNode = aIdx.GetNode().GetTxtNode();
+        xub_StrLen nLen = pTxtNode->Len();
+        { // wg. SwIndex
+            pTxtNode->Cut( this, SwIndex( this ), SwIndex(pTxtNode), nLen );
+        }
+        // verschiebe noch alle Bookmarks/TOXMarks
+        if( aBkmkArr.Count() )
+            _RestoreCntntIdx( pDoc, aBkmkArr, GetIndex() );
+
+        if( pTxtNode->HasAnyIndex() )
+        {
+            // alle Crsr/StkCrsr/UnoCrsr aus dem Loeschbereich verschieben
+            pDoc->CorrAbs( aIdx, SwPosition( *this ), nLen, TRUE );
+        }
+        rNds.Delete(aIdx);
+        InvalidateNumRule();
+    }
+    else
+        ASSERT( FALSE, "kein TxtNode." );
+
+    return this;
+}
+
+// erzeugt einen AttrSet mit Bereichen fuer Frame-/Para/Char-Attributen
+void SwTxtNode::NewAttrSet( SwAttrPool& rPool )
+{
+    ASSERT( !pAttrSet, "AttrSet ist doch gesetzt" );
+    pAttrSet = new SwAttrSet( rPool, aTxtNodeSetRange );
+//FEATURE::CONDCOLL
+//  pAttrSet->SetParent( &GetFmtColl()->GetAttrSet() );
+    pAttrSet->SetParent( &GetAnyFmtColl().GetAttrSet() );
+//FEATURE::CONDCOLL
+}
+
+
+// change the URL in the attribut - if it is a valid URL!
+void lcl_CheckURLChanged( const SwFmtINetFmt& rURLAttr, const String& rText,
+                            xub_StrLen nStt, xub_StrLen nEnd )
+{
+    if( nStt < nEnd )
+    {
+        xub_StrLen nS = nStt, nE = nEnd;
+        String sNew( URIHelper::FindFirstURLInText( rText, nS, nE,
+                                                    GetAppCharClass() ));
+        if( sNew.Len() && nS == nStt && nE == nEnd )
+        {
+            // it is an valid URL, so set it to the URL Object
+            ((SwFmtINetFmt&)rURLAttr).SetValue( rText.Copy( nS, nE - nS ));
+        }
+    }
+}
+
+// Ueberladen der virtuellen Update-Methode von SwIndexReg. Dadurch
+// benoetigen die Text-Attribute nur xub_StrLen statt SwIndizies!
+void SwTxtNode::Update( const SwIndex & aPos, xub_StrLen nLen,
+                        BOOL bNegativ )
+{
+    SetAutoCompleteWordDirty( TRUE );
+
+    TmpHints* pCollector = NULL;
+    if( pSwpHints )
+    {
+        xub_StrLen nPos = aPos.GetIndex();
+        xub_StrLen* pIdx;
+        SwTxtAttr* pHt;
+        if( bNegativ )
+        {
+            xub_StrLen nMax = nPos + nLen;
+            for( USHORT n = 0; n < pSwpHints->Count(); ++n )
+            {
+                BOOL bCheckURL = FALSE, bSttBefore = FALSE;
+                pHt = pSwpHints->GetHt(n);
+                pIdx = pHt->GetStart();
+                if( *pIdx >= nPos )
+                {
+                    if( *pIdx > nMax )
+                         *pIdx -= nLen;
+                    else
+                    {
+                        if( *pIdx < nMax )
+                             bCheckURL = TRUE;
+                         *pIdx = nPos;
+                    }
+                }
+                else
+                    bSttBefore = TRUE;
+
+                if( 0 == (pIdx = pHt->GetEnd()) )
+                    continue;
+
+                if( *pIdx >= nPos )
+                {
+                    if( *pIdx > nMax )
+                         *pIdx -= nLen;
+                    else if( *pIdx != nPos )
+                    {
+                        *pIdx = nPos;
+                        if( bSttBefore )
+                            bCheckURL = TRUE;
+                    }
+                }
+
+                if( bCheckURL && RES_TXTATR_INETFMT == pHt->Which() )
+                {
+                    // reset the URL in the attribut - if it is a valid URL!
+                    lcl_CheckURLChanged( pHt->GetINetFmt(), aText,
+                                        *pHt->GetStart(), *pHt->GetEnd() );
+                }
+
+//JP 01.10.96: fuers SplitNode sollte das Flag nicht geloescht werden!
+//              pHt->SetDontExpand( FALSE );
+            }
+            // AMA: Durch das Loeschen koennen Attribute gleiche Start-
+            //      und/oder Endwerte erhalten, die vorher echt ungleich
+            //      waren. Dadurch kann die Sortierung durcheinander geraten,
+            //      die bei gleichen Start/Endwerten den Pointer selbst
+            //      vergleicht, also ClearDummies ...
+            pSwpHints->ClearDummies( *this );
+            if ( !pSwpHints->Merge( *this ) )
+                ((SwpHintsArr*)pSwpHints)->Resort();
+        }
+        else
+        {
+            xub_StrLen* pEnd;
+            BOOL bNoExp = FALSE;
+            const USHORT coArrSz = RES_TXTATR_WITHEND_END - RES_CHRATR_BEGIN +
+                                ( RES_UNKNOWNATR_END - RES_UNKNOWNATR_BEGIN );
+
+            BOOL aDontExp[ coArrSz ];
+            memset( &aDontExp, 0, coArrSz * sizeof(BOOL) );
+
+            for( USHORT n = 0; n < pSwpHints->Count(); ++n )
+            {
+                BOOL bCheckURL = FALSE;
+                pHt = pSwpHints->GetHt(n);
+                pIdx = pHt->GetStart();
+                if( *pIdx >= nPos )
+                {
+                    *pIdx += nLen;
+                    if( 0 != ( pEnd = pHt->GetEnd() ) )
+                        *pEnd += nLen;
+                }
+                else if( 0 != ( pEnd = pHt->GetEnd() ) && *pEnd >= nPos )
+                {
+                    if( *pEnd > nPos )
+                    {
+                        bCheckURL = TRUE;
+                        *pEnd += nLen;
+                    }
+                    else
+                    {
+                        USHORT nWhPos, nWhich = pHt->Which();
+
+                        if( RES_CHRATR_BEGIN <= nWhich &&
+                            nWhich < RES_TXTATR_WITHEND_END )
+                             nWhPos = nWhich - RES_CHRATR_BEGIN;
+                        else if( RES_UNKNOWNATR_BEGIN <= nWhich &&
+                                nWhich < RES_UNKNOWNATR_END )
+                            nWhPos = nWhich - RES_UNKNOWNATR_BEGIN +
+                                ( RES_TXTATR_WITHEND_END - RES_CHRATR_BEGIN );
+                        else
+                            continue;
+
+                        if( aDontExp[ nWhPos ] )
+                            continue;
+                        BOOL bCharFmt = ( nWhich == RES_TXTATR_CHARFMT ||
+                                          nWhich == RES_TXTATR_INETFMT );
+                        if( pHt->DontExpand() )
+                        {
+                            pHt->SetDontExpand( FALSE );
+                            if( bCharFmt )
+                            {
+                                bNoExp = TRUE;
+                                aDontExp[ RES_TXTATR_CHARFMT -RES_CHRATR_BEGIN ]
+                                    = TRUE;
+                                aDontExp[ RES_TXTATR_INETFMT -RES_CHRATR_BEGIN ]
+                                    = TRUE;
+                            }
+                            else
+                                aDontExp[ nWhPos ] = TRUE;
+                        }
+                        else if( bNoExp )
+                        {
+                             if( !pCollector )
+                                pCollector = new TmpHints;
+                             USHORT nCollCnt = pCollector->Count();
+                             for( USHORT i = 0; i < nCollCnt; ++i )
+                             {
+                                SwTxtAttr *pTmp = (*pCollector)[ i ];
+                                if( nWhich == pTmp->Which() )
+                                {
+                                    pCollector->Remove( i );
+                                    delete pTmp;
+                                    break;
+                                }
+                             }
+                             SwTxtAttr *pTmp = MakeTxtAttr( pHt->GetAttr(),
+                                                nPos, nPos + nLen );
+                             pCollector->C40_INSERT( SwTxtAttr, pTmp, pCollector->Count() );
+                        }
+                        else
+                        {
+                            *pEnd += nLen;
+                            bCheckURL = TRUE;
+                        }
+                    }
+                }
+
+                if( bCheckURL && RES_TXTATR_INETFMT == pHt->Which() )
+                {
+                    // reset the URL in the attribut - if it is a valid URL!
+                    lcl_CheckURLChanged( pHt->GetINetFmt(), aText,
+                                        *pHt->GetStart(), *pHt->GetEnd() );
+                }
+            }
+        }
+    }
+
+    SwIndexReg aTmpIdxReg;
+    if( !bNegativ )
+    {
+        SwIndex* pIdx;
+        const SwRedlineTbl& rTbl = GetDoc()->GetRedlineTbl();
+        if( rTbl.Count() )
+            for( USHORT i = 0; i < rTbl.Count(); ++i )
+            {
+                SwRedline* pRedl = rTbl[ i ];
+                if( pRedl->HasMark() )
+                {
+                    if(( this == &pRedl->GetBound(TRUE).nNode.GetNode() ||
+                         this == &pRedl->GetBound(FALSE).nNode.GetNode() ) &&
+                        *pRedl->GetPoint() != *pRedl->GetMark() &&
+                        aPos.GetIndex() == (pIdx = &pRedl->End()->
+                            nContent)->GetIndex() )
+                        pIdx->Assign( &aTmpIdxReg, pIdx->GetIndex() );
+                }
+                else if( this == &pRedl->GetPoint()->nNode.GetNode() &&
+                        aPos.GetIndex() == (pIdx = &pRedl->GetPoint()->
+                            nContent)->GetIndex() )
+                {
+                    pIdx->Assign( &aTmpIdxReg, pIdx->GetIndex() );
+                    if( &pRedl->GetBound( TRUE ) == pRedl->GetPoint() )
+                    {
+                        pRedl->GetBound( FALSE ) = pRedl->GetBound( TRUE );
+                        pIdx = &pRedl->GetBound( FALSE ).nContent;
+                    }
+                    else
+                    {
+                        pRedl->GetBound( TRUE ) = pRedl->GetBound( FALSE );
+                        pIdx = &pRedl->GetBound( TRUE ).nContent;
+                    }
+                    pIdx->Assign( &aTmpIdxReg, pIdx->GetIndex() );
+                }
+            }
+
+        const SwBookmarks& rBkmk = GetDoc()->GetBookmarks();
+        if( rBkmk.Count() )
+            for( USHORT i = 0; i < rBkmk.Count(); ++i )
+            {
+                SwBookmark* pBkmk = rBkmk[ i ];
+                if( (this == &pBkmk->GetPos().nNode.GetNode() &&
+                     aPos.GetIndex() == (pIdx = (SwIndex*)&pBkmk->GetPos().
+                            nContent)->GetIndex() ) ||
+                    ( pBkmk->GetOtherPos() &&
+                      this == &pBkmk->GetOtherPos()->nNode.GetNode() &&
+                      aPos.GetIndex() == (pIdx = (SwIndex*)&pBkmk->
+                              GetOtherPos()->nContent)->GetIndex() ) )
+                        pIdx->Assign( &aTmpIdxReg, pIdx->GetIndex() );
+            }
+    }
+    SwIndexReg::Update( aPos, nLen, bNegativ );
+    if( pCollector )
+    {
+        USHORT nCount = pCollector->Count();
+        for( USHORT i = 0; i < nCount; ++i )
+            pSwpHints->Insert( (*pCollector)[ i ], *this, FALSE );
+        delete pCollector;
+    }
+
+    aTmpIdxReg.MoveTo( *this );
+}
+
+SwFmtColl* SwTxtNode::ChgFmtColl( SwFmtColl *pNewColl )
+{
+    ASSERT( pNewColl,"ChgFmtColl: Collectionpointer ist 0." );
+    ASSERT( HAS_BASE( SwTxtFmtColl, pNewColl ),
+                "ChgFmtColl: ist kein Text-Collectionpointer." );
+
+    SwTxtFmtColl *pOldColl = GetTxtColl();
+    if( pNewColl != pOldColl )
+        SwCntntNode::ChgFmtColl( pNewColl );
+    // nur wenn im normalen Nodes-Array
+    if( GetNodes().IsDocNodes() )
+        _ChgTxtCollUpdateNum( pOldColl, (SwTxtFmtColl*)pNewColl );
+    return  pOldColl;
+}
+
+void SwTxtNode::_ChgTxtCollUpdateNum( const SwTxtFmtColl *pOldColl,
+                                        const SwTxtFmtColl *pNewColl)
+{
+    SwDoc* pDoc = GetDoc();
+    ASSERT( pDoc, "Kein Doc?" );
+    // erfrage die OutlineLevel und update gegebenenfalls das Nodes-Array,
+    // falls sich die Level geaendert haben !
+    const BYTE nOldLevel = pOldColl ? pOldColl->GetOutlineLevel():NO_NUMBERING;
+    const BYTE nNewLevel = pNewColl ? pNewColl->GetOutlineLevel():NO_NUMBERING;
+
+    SwNodes& rNds = GetNodes();
+    if( nOldLevel != nNewLevel )
+    {
+        delete pNdOutl, pNdOutl = 0;
+        // Numerierung aufheben, falls sie aus der Vorlage kommt
+        // und nicht nicht aus der neuen
+        if( NO_NUMBERING != nNewLevel && pNdNum && ( !GetpSwAttrSet() ||
+            SFX_ITEM_SET != GetpSwAttrSet()->GetItemState(
+                RES_PARATR_NUMRULE, FALSE )) &&
+            (!pNewColl || SFX_ITEM_SET != pNewColl->GetItemState(
+                RES_PARATR_NUMRULE )) )
+            delete pNdNum, pNdNum = 0;
+        if( rNds.IsDocNodes() )
+            rNds.UpdateOutlineNode( *this, nOldLevel, nNewLevel );
+    }
+
+    // Update beim Level 0 noch die Fussnoten !!
+    if( (!nNewLevel || !nOldLevel) && pDoc->GetFtnIdxs().Count() &&
+        FTNNUM_CHAPTER == pDoc->GetFtnInfo().eNum &&
+        rNds.IsDocNodes() )
+    {
+        SwNodeIndex aTmpIndex( rNds, GetIndex());
+
+        pDoc->GetFtnIdxs().UpdateFtn( aTmpIndex);
+    }
+
+//FEATURE::CONDCOLL
+    if( /*pOldColl != pNewColl && pNewColl && */
+        RES_CONDTXTFMTCOLL == pNewColl->Which() )
+    {
+        // Erfrage die akt. Condition des TextNodes:
+        ChkCondColl();
+    }
+//FEATURE::CONDCOLL
+}
+
+// Wennn man sich genau am Ende einer Text- bzw. INetvorlage befindet,
+// bekommt diese das DontExpand-Flag verpasst
+
+BOOL SwTxtNode::DontExpandFmt( const SwIndex& rIdx, BOOL bFlag,
+                                BOOL bFmtToTxtAttributes )
+{
+    const xub_StrLen nIdx = rIdx.GetIndex();
+    if( bFmtToTxtAttributes && nIdx == aText.Len() )
+        FmtToTxtAttr( this );
+    if( !pSwpHints )
+        return FALSE;
+    const USHORT nEndCnt = pSwpHints->GetEndCount();
+    USHORT nPos = nEndCnt;
+    BOOL bRet = FALSE;
+    while( nPos )
+    {
+        SwTxtAttr *pTmp = pSwpHints->GetEnd( --nPos );
+        xub_StrLen *pEnd = pTmp->GetEnd();
+        if( !pEnd || *pEnd > nIdx )
+            continue;
+        if( nIdx != *pEnd )
+            nPos = 0;
+        else if( bFlag != pTmp->DontExpand() && *pEnd > *pTmp->GetStart() )
+        {
+            bRet = TRUE;
+            pSwpHints->NoteInHistory( pTmp );
+            pTmp->SetDontExpand( bFlag );
+        }
+    }
+    return bRet;
+}
+
+
+// gebe das vorgegebene Attribut, welches an der TextPosition (rIdx)
+// gesetzt ist, zurueck. Gibt es keines, returne 0-Pointer.
+// (gesetzt heisst, je nach bExpand ?
+//                                    Start < rIdx <= End
+//                                  : Start <= rIdx < End )
+
+SwTxtAttr* SwTxtNode::GetTxtAttr( const SwIndex& rIdx, USHORT nWhichHt,
+                                  BOOL bExpand ) const
+{
+    const SwTxtAttr* pRet = 0;
+    const SwTxtAttr* pHt = 0;
+    const xub_StrLen *pEndIdx = 0;
+    const xub_StrLen nIdx = rIdx.GetIndex();
+    const USHORT  nSize = pSwpHints ? pSwpHints->Count() : 0;
+
+    for( USHORT i = 0; i < nSize; ++i )
+    {
+        // ist der Attribut-Anfang schon groesser als der Idx ?
+        if( nIdx < *((pHt = (*pSwpHints)[i])->GetStart()) )
+            break;          // beenden, kein gueltiges Attribut
+
+        // ist es das gewuenschte Attribut ?
+        if( pHt->Which() != nWhichHt )
+            continue;       // nein, weiter
+
+        pEndIdx = pHt->GetEnd();
+        // liegt innerhalb des Bereiches ??
+        if( !pEndIdx )
+        {
+            if( *pHt->GetStart() == nIdx )
+            {
+                pRet = pHt;
+                break;
+            }
+        }
+        else if( *pHt->GetStart() <= nIdx && nIdx <= *pEndIdx )
+        {
+            // Wenn bExpand gesetzt ist, wird das Verhalten bei Eingabe
+            // simuliert, d.h. der Start wuede verschoben, das Ende expandiert,
+            if( bExpand )
+            {
+                if( *pHt->GetStart() < nIdx )
+                    pRet = pHt;
+            }
+            else
+            {
+                if( nIdx < *pEndIdx )
+                    pRet = pHt;     // den am dichtesten liegenden
+            }
+        }
+    }
+    return (SwTxtAttr*)pRet;        // kein gueltiges Attribut gefunden !!
+}
+
+/*************************************************************************
+ *                          CopyHint()
+ *************************************************************************/
+
+SwCharFmt* lcl_FindCharFmt( const SwCharFmts* pCharFmts, const XubString& rName )
+{
+    if( rName.Len() )
+    {
+        SwCharFmt* pFmt;
+        USHORT nArrLen = pCharFmts->Count();
+        for( USHORT i = 1; i < nArrLen; i++ )
+        {
+            pFmt = (*pCharFmts)[ i ];
+            if( pFmt->GetName().CompareTo( rName ) == COMPARE_EQUAL )
+                return pFmt;
+        }
+    }
+    return NULL;
+}
+
+void lcl_CopyHint( const USHORT nWhich, const SwTxtAttr *pHt,
+                    SwTxtAttr *pNewHt, SwDoc* pOtherDoc, SwTxtNode *pDest )
+{
+    ASSERT( nWhich == pHt->Which(), "Falsche Hint-Id" );
+    switch( nWhich )
+    {
+        // Wenn wir es mit einem Fussnoten-Attribut zu tun haben,
+        // muessen wir natuerlich auch den Fussnotenbereich kopieren.
+        case RES_TXTATR_FTN :
+            ((SwTxtFtn*)pHt)->CopyFtn( (SwTxtFtn*)pNewHt );
+            break;
+
+        // Beim Kopieren von Feldern in andere Dokumente
+        // muessen die Felder bei ihren neuen Feldtypen angemeldet werden.
+
+        // TabellenFormel muessen relativ kopiert werden.
+        case RES_TXTATR_FIELD :
+            {
+                const SwFmtFld& rFld = pHt->GetFld();
+                if( pOtherDoc )
+                    ((SwTxtFld*)pHt)->CopyFld( (SwTxtFld*)pNewHt );
+
+                // Tabellenformel ??
+                if( RES_TABLEFLD == rFld.GetFld()->GetTyp()->Which()
+                    && ((SwTblField*)rFld.GetFld())->IsIntrnlName() )
+                {
+                    // wandel die interne in eine externe Formel um
+                    const SwTableNode* pDstTblNd = ((SwTxtFld*)pHt)->
+                                            GetTxtNode().FindTableNode();
+                    if( pDstTblNd )
+                    {
+                        SwTblField* pTblFld = (SwTblField*)
+                                                pNewHt->GetFld().GetFld();
+                        pTblFld->PtrToBoxNm( &pDstTblNd->GetTable() );
+                    }
+                }
+            }
+            break;
+
+        case RES_TXTATR_TOXMARK :
+            if( pOtherDoc && pDest && pDest->GetpSwpHints()
+                && USHRT_MAX != pDest->GetpSwpHints()->GetPos( pNewHt ) )
+                // Beim Kopieren von TOXMarks(Client) in andere Dokumente
+                // muss der Verzeichnis (Modify) ausgetauscht werden
+                ((SwTxtTOXMark*)pNewHt)->CopyTOXMark( pOtherDoc );
+            break;
+
+        case RES_TXTATR_CHARFMT :
+            // Wenn wir es mit einer Zeichenvorlage zu tun haben,
+            // muessen wir natuerlich auch die Formate kopieren.
+            if( pDest && pDest->GetpSwpHints()
+                && USHRT_MAX != pDest->GetpSwpHints()->GetPos( pNewHt ) )
+            {
+                SwCharFmt* pFmt = (SwCharFmt*)pHt->GetCharFmt().GetCharFmt();
+
+                if( pFmt && pOtherDoc )
+                    pFmt = pOtherDoc->CopyCharFmt( *pFmt );
+                ((SwFmtCharFmt&)pNewHt->GetCharFmt()).SetCharFmt( pFmt );
+            }
+            break;
+        case RES_TXTATR_INETFMT :
+            // Wenn wir es mit benutzerdefinierten INet-Zeichenvorlagen
+            // zu tun haben, muessen wir natuerlich auch die Formate kopieren.
+            if( pOtherDoc && pDest && pDest->GetpSwpHints()
+                && USHRT_MAX != pDest->GetpSwpHints()->GetPos( pNewHt ) )
+            {
+                const SwDoc* pDoc;
+                if( 0!=( pDoc = ((SwTxtINetFmt*)pHt)->GetTxtNode().GetDoc() ) )
+                {
+                    const SwCharFmts* pCharFmts = pDoc->GetCharFmts();
+                    const SwFmtINetFmt& rFmt = pHt->GetINetFmt();
+                    SwCharFmt* pFmt;
+                    pFmt = lcl_FindCharFmt( pCharFmts, rFmt.GetINetFmt() );
+                    if( pFmt )
+                        pOtherDoc->CopyCharFmt( *pFmt );
+                    pFmt = lcl_FindCharFmt( pCharFmts, rFmt.GetVisitedFmt() );
+                    if( pFmt )
+                        pOtherDoc->CopyCharFmt( *pFmt );
+                }
+            }
+            //JP 24.04.98: Bug 49753 - ein TextNode muss am Attribut
+            //              gesetzt sein, damit die Vorlagen erzeugt
+            //              werden koenne
+            if( !((SwTxtINetFmt*)pNewHt)->GetpTxtNode() )
+                ((SwTxtINetFmt*)pNewHt)->ChgTxtNode( pDest );
+
+            //JP 22.10.97: Bug 44875 - Verbindung zum Format herstellen
+            ((SwTxtINetFmt*)pNewHt)->GetCharFmt();
+            break;
+    }
+}
+
+/*************************************************************************
+|*  SwTxtNode::CopyAttr()
+|*  Beschreibung    kopiert Attribute an der Position nStart in pDest.
+|*  BP 7.6.93:      Es werden mit Absicht nur die Attribute _mit_ EndIdx
+|*                  kopiert! CopyAttr wird vornehmlich dann gerufen,
+|*                  wenn Attribute fuer einen Node mit leerem String
+|*                  gesetzt werden sollen.
+*************************************************************************/
+
+void SwTxtNode::CopyAttr( SwTxtNode *pDest, const xub_StrLen nTxtStartIdx,
+                          const xub_StrLen nOldPos )
+{
+    if( pSwpHints )        // keine Attribute, keine Kekse
+    {
+        const xub_StrLen *pEndIdx = 0;
+        const SwTxtAttr *pHt = 0;
+        SwTxtAttr *pNewHt = 0;
+        xub_StrLen nAttrStartIdx = 0;
+        USHORT nWhich;
+
+        SwDoc* pOtherDoc = pDest->GetDoc();
+        if( pOtherDoc == GetDoc() )
+            pOtherDoc = 0;
+
+        for( USHORT i = 0; i < pSwpHints->Count(); i++ )
+        {
+            pHt = (*pSwpHints)[i];
+            if( nTxtStartIdx < ( nAttrStartIdx = *pHt->GetStart() ) )
+                break;      // ueber das Textende, da nLen == 0
+
+            pEndIdx = pHt->GetEnd();
+            if( pEndIdx )
+            {
+                if( ( *pEndIdx > nTxtStartIdx ||
+                      ( *pEndIdx == nTxtStartIdx &&
+                        nAttrStartIdx == nTxtStartIdx ) ) )
+                {
+                    if( RES_TXTATR_REFMARK != ( nWhich = pHt->Which()) )
+                    {
+                        // Attribut liegt im Bereich, also kopieren
+                        if( 0 != ( pNewHt = pDest->Insert( pHt->GetAttr(),
+                                                nOldPos, nOldPos ) ) )
+                            lcl_CopyHint( nWhich, pHt, pNewHt, pOtherDoc, pDest );
+                    }
+                    else if( !pOtherDoc ? GetDoc()->IsCopyIsMove()
+                                        : 0 == pOtherDoc->GetRefMark(
+                                        pHt->GetRefMark().GetRefName() ) )
+                        pDest->Insert( pHt->GetAttr(), nOldPos, nOldPos );
+                }
+            }
+        }
+    }
+
+    if( this != pDest )
+    {
+        // Frames benachrichtigen, sonst verschwinden die Ftn-Nummern
+        SwUpdateAttr aHint( nOldPos, nOldPos, 0 );
+        pDest->Modify( 0, &aHint );
+    }
+}
+
+/*************************************************************************
+|*  SwTxtNode::Copy()
+|*  Beschreibung        kopiert Zeichen und Attibute in pDest,
+|*                      wird angehaengt
+*************************************************************************/
+
+void SwTxtNode::Copy( SwTxtNode *pDest, const SwIndex &rStart, xub_StrLen nLen )
+{
+    SwIndex aIdx( pDest, pDest->aText.Len() );
+    Copy( pDest, aIdx, rStart, nLen );
+}
+
+void SwTxtNode::Copy( SwTxtNode *pDest, const SwIndex &rDestStart,
+                      const SwIndex &rStart, xub_StrLen nLen)
+{
+    xub_StrLen nTxtStartIdx = rStart.GetIndex();
+    xub_StrLen nDestStart = rDestStart.GetIndex();      // alte Pos merken
+
+    if( !nLen )
+    {
+        // wurde keine Laenge angegeben, dann Kopiere die Attribute
+        // an der Position rStart.
+        CopyAttr( pDest, nTxtStartIdx, nDestStart );
+
+        // harte Absatz umspannende Attribute kopieren
+        if( GetpSwAttrSet() )
+        {
+            // alle, oder nur die CharAttribute ?
+            if( nDestStart || pDest->GetpSwAttrSet() ||
+                nLen != pDest->GetTxt().Len() )
+            {
+                SfxItemSet aCharSet( pDest->GetDoc()->GetAttrPool(),
+                                    RES_CHRATR_BEGIN, RES_CHRATR_END-1,
+                                    RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT,
+                                    RES_TXTATR_INETFMT, RES_TXTATR_INETFMT,
+                                    RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1,
+                                    0 );
+                aCharSet.Put( *GetpSwAttrSet() );
+                if( aCharSet.Count() )
+                    pDest->SetAttr( aCharSet, nDestStart, nDestStart );
+            }
+            else
+                GetpSwAttrSet()->CopyToModify( *pDest );
+        }
+
+        return;
+    }
+
+    // 1. Text kopieren
+    xub_StrLen i = pDest->aText.Len() - nDestStart;
+    //JP 15.02.96: Bug 25537 - Attributbehandlung am Ende fehlt! Darum
+    //              ueber die InsertMethode den Text einfuegen und nicht
+    //              selbst direkt
+    pDest->Insert( aText.Copy( nTxtStartIdx, nLen ), rDestStart,
+                                                    INS_EMPTYEXPAND );
+
+    // um reale Groesse Updaten !
+    nLen = pDest->aText.Len() - nDestStart - i;
+    if( !nLen )                                 // String nicht gewachsen ??
+        return;
+
+    i = 0;
+    const xub_StrLen *pEndIdx = 0;
+    xub_StrLen nAttrStartIdx = 0;
+    const SwTxtAttr *pHt = 0;
+    SwTxtAttr *pNewHt = 0;
+
+    SwDoc* pOtherDoc = pDest->GetDoc();
+    if( pOtherDoc == GetDoc() )
+        pOtherDoc = 0;
+
+    // harte Absatz umspannende Attribute kopieren
+    if( GetpSwAttrSet() )
+    {
+        // alle, oder nur die CharAttribute ?
+        if( nDestStart || pDest->GetpSwAttrSet() ||
+            nLen != pDest->GetTxt().Len() )
+        {
+            SfxItemSet aCharSet( pDest->GetDoc()->GetAttrPool(),
+                                RES_CHRATR_BEGIN, RES_CHRATR_END-1,
+                                RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT,
+                                RES_TXTATR_INETFMT, RES_TXTATR_INETFMT,
+                                RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1,
+                                0 );
+            aCharSet.Put( *GetpSwAttrSet() );
+            if( aCharSet.Count() )
+                pDest->SetAttr( aCharSet, nDestStart, nDestStart + nLen );
+        }
+        else
+            GetpSwAttrSet()->CopyToModify( *pDest );
+    }
+
+
+    const BOOL bUndoNodes = !pOtherDoc && GetDoc()->GetUndoNds() == &GetNodes();
+
+    // Ende erst jetzt holen, weil beim Kopieren in sich selbst der
+    // Start-Index und alle Attribute vorher aktualisiert werden.
+    nTxtStartIdx = rStart.GetIndex();
+    xub_StrLen nEnd = nTxtStartIdx + nLen;
+
+    // 2. Attribute kopieren
+    // durch das Attribute-Array, bis der Anfang des Geltungsbereiches
+    // des Attributs hinter dem zu kopierenden Bereich liegt
+    USHORT nWhich, nSize = pSwpHints ? pSwpHints->Count() : 0;
+    xub_StrLen nAttrStt, nAttrEnd;
+
+    // wird in sich selbst kopiert, dann kann beim Einfuegen ein
+    // Attribut geloescht werden. Darum erst ins Tmp-Array kopieren und
+    // dann erst ins eigene uebertragen.
+    SwpHts aArr( 5 );
+
+    // Del-Array fuer alle RefMarks ohne Ausdehnung
+    SwpHts aRefMrkArr;
+
+        //Achtung: kann ungueltig sein!!
+    while( ( i < nSize ) &&
+           ((nAttrStartIdx = *(*pSwpHints)[i]->GetStart()) < nEnd) )
+    {
+        pHt = (*pSwpHints)[i];
+        pNewHt = 0;
+        pEndIdx = pHt->GetEnd();
+        nWhich = pHt->Which();
+
+        // JP 26.04.94: REFMARK's werden nie kopiert. Hat das Refmark aber
+        //              keinen Bereich umspannt, so steht im Text ein 255
+        //              dieses muss entfernt werden. Trick: erst kopieren,
+        //              erkennen und sammeln, nach dem kopieren Loeschen.
+        //              Nimmt sein Zeichen mit ins Grab !!
+        // JP 14.08.95: Duerfen RefMarks gemovt werden?
+        int bCopyRefMark = RES_TXTATR_REFMARK == nWhich && ( bUndoNodes ||
+                           (!pOtherDoc ? GetDoc()->IsCopyIsMove()
+                                      : 0 == pOtherDoc->GetRefMark(
+                                        pHt->GetRefMark().GetRefName() )));
+
+        if( pEndIdx && RES_TXTATR_REFMARK == nWhich && !bCopyRefMark )
+        {
+            ++i;
+            continue;
+        }
+
+        if( nAttrStartIdx < nTxtStartIdx )
+        {
+            // Anfang liegt vor dem Bereich
+            if( pEndIdx && ( nAttrEnd = *pEndIdx ) > nTxtStartIdx )
+            {
+                // Attribut mit einem Bereich
+                // und das Ende des Attribut liegt im Bereich
+                nAttrStt = nDestStart;
+                nAttrEnd = nAttrEnd > nEnd
+                            ? rDestStart.GetIndex()
+                            : nDestStart + nAttrEnd - nTxtStartIdx;
+            }
+            else
+            {
+                ++i;
+                continue;
+            }
+        }
+        else
+        {
+            // der Anfang liegt innerhalb des Bereiches
+            nAttrStt = nDestStart + ( nAttrStartIdx - nTxtStartIdx );
+            if( pEndIdx )
+                nAttrEnd = *pEndIdx > nEnd
+                            ? rDestStart.GetIndex()
+                            : nDestStart + ( *pEndIdx - nTxtStartIdx );
+            else
+                nAttrEnd = nAttrStt;
+        }
+
+        if( pDest == this )
+        {
+            // die Daten kopieren
+            pNewHt = MakeTxtAttr( pHt->GetAttr(), nAttrStt, nAttrEnd );
+
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+//JP 23.04.95:  erstmal so gesondert hier behandeln. Am Besten ist es
+//              aber im CopyFtn wenn die pDestFtn keinen StartNode hat,
+//              sich diesen dann anlegt.
+//              Aber so kurz vor der BETA besser nicht anfassen.
+            if( RES_TXTATR_FTN == nWhich )
+            {
+                SwTxtFtn* pFtn = (SwTxtFtn*)pNewHt;
+                pFtn->ChgTxtNode( this );
+                pFtn->MakeNewTextSection( GetNodes() );
+                lcl_CopyHint( nWhich, pHt, pFtn, 0, 0 );
+                pFtn->ChgTxtNode( 0 );
+            }
+            else
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+            {
+                lcl_CopyHint( nWhich, pHt, pNewHt, 0, pDest );
+            }
+            aArr.C40_INSERT( SwTxtAttr, pNewHt, aArr.Count() );
+        }
+        else
+        {
+            pNewHt = pDest->Insert( pHt->GetAttr(), nAttrStt,
+                                    nAttrEnd, SETATTR_NOTXTATRCHR );
+            if( pNewHt )
+                lcl_CopyHint( nWhich, pHt, pNewHt, pOtherDoc, pDest );
+            else if( !pEndIdx )
+            {
+                // Attribut wurde nicht kopiert, hat seinen Inhalt mitgenommen!
+                // Damit der rest aber korrekt kopiert werden kann, muss das
+                // Zeichen wieder an der Position stehen. Darum hier ein
+                // "Dummy-TextAttribut" einfuegen, wird am Ende wieder entfernt!
+                pNewHt = pDest->Insert( SwFmtHardBlank( 0xB7 ), nAttrStt, 0
+                                        /*???, INS_NOHINTEXPAND*/ );
+                aRefMrkArr.C40_INSERT( SwTxtAttr, pNewHt, aRefMrkArr.Count() );
+            }
+        }
+
+        if( RES_TXTATR_REFMARK == nWhich && !pEndIdx && !bCopyRefMark )
+        {
+            aRefMrkArr.C40_INSERT( SwTxtAttr, pNewHt, aRefMrkArr.Count() );
+        }
+
+        ++i;
+    }
+
+    // nur falls im Array Attribute stehen (kann nur beim Kopieren
+    // sich selbst passieren!!)
+    for( i = 0; i < aArr.Count(); ++i )
+        Insert( aArr[ i ], SETATTR_NOTXTATRCHR );
+
+    if( pDest->GetpSwpHints() )
+        for( i = 0; i < aRefMrkArr.Count(); ++i )
+        {
+            pNewHt = aRefMrkArr[i];
+            if( pNewHt->GetEnd() )
+            {
+                pDest->GetpSwpHints()->Delete( pNewHt );
+                pDest->DestroyAttr( pNewHt );
+            }
+            else
+            {
+                const SwIndex aIdx( pDest, *pNewHt->GetStart() );
+                pDest->Erase( aIdx, 1 );
+            }
+        }
+
+    CHECK_SWPHINTS(this);
+}
+
+
+/*
+ * Rudimentaeres Editieren, damit die SwDoc-Insert-Methoden
+ * funktionieren.
+ */
+
+SwTxtNode& SwTxtNode::Insert( const XubString   &rStr,
+                              const SwIndex &rIdx, const USHORT nMode )
+{
+    ASSERT( rIdx <= aText.Len(), "Array ueberindiziert." );
+    ASSERT( (ULONG)aText.Len() + (ULONG)rStr.Len() <= STRING_LEN,
+            "STRING_LEN ueberschritten." );
+    xub_StrLen aPos = rIdx.GetIndex();
+    xub_StrLen nLen = aText.Len() - aPos;
+    aText.Insert( rStr, aPos );
+    nLen = aText.Len() - aPos - nLen;
+    if( !nLen )                         // String nicht gewachsen ??
+        return *this;
+    Update( rIdx, nLen );       // um reale Groesse Updaten !
+
+    // analog zu Insert(char) in txtedt.cxx:
+    // 1) bei bHintExp leere Hints an rIdx.GetIndex suchen und aufspannen
+    // 2) bei bHintExp == FALSE mitgezogene Feldattribute zuruecksetzen
+
+    register USHORT i;
+
+    if( pSwpHints )
+    {
+        for( i = 0; i < pSwpHints->Count() &&
+                rIdx >= *(*pSwpHints)[i]->GetStart(); ++i )
+        {
+            SwTxtAttr *pHt = pSwpHints->GetHt( i );
+            xub_StrLen* pEndIdx = pHt->GetEnd();
+            if( !pEndIdx )
+                continue;
+
+            if( rIdx == *pEndIdx )
+            {
+                if( nMode & INS_NOHINTEXPAND || pHt->DontExpand() )
+                {
+                    // bei leeren Attributen auch Start veraendern
+                    if( rIdx == *pHt->GetStart() )
+                        *pHt->GetStart() -= nLen;
+                    *pEndIdx -= nLen;
+                }
+                    // leere Hints an rIdx.GetIndex ?
+                else if( nMode & INS_EMPTYEXPAND &&
+                        *pEndIdx == *pHt->GetStart() )
+                {
+                    *pHt->GetStart() -= nLen;
+
+                    // 8484: Symbol von 0-4, Roman von 4-6,
+                    //       neuer Hint: Roman 4-4
+
+                    // - while ... die Vorgaenger ueberpruefen:
+                    // wenn gleiches Ende und gleicher Which
+                    // => das Ende des gefundenen zuruecksetzen
+                    const USHORT nWhich = pHt->Which();
+                    SwTxtAttr *pFound;
+                    xub_StrLen *pFoundEnd;
+                    for( USHORT j = 0; j < i; ++j )
+                        if( 0 != (pFound = pSwpHints->GetHt( j )) &&
+                            nWhich == pFound->Which() &&
+                            0 != ( pFoundEnd = pFound->GetEnd() ) &&
+                            rIdx == *pFoundEnd )
+                        {
+                            *pFoundEnd -= nLen;
+                            const USHORT nAktHtLen = pSwpHints->Count();
+                            pSwpHints->DeleteAtPos(j);
+                            Insert( pFound, SETATTR_NOHINTADJUST );
+                            // AMA: Sicher ist sicher, falls pFound weiter hinten
+                            // einsortiert wurde, koennte sonst die neue Position
+                            // j vergessen werden!
+                            if ( j ) --j;
+                            // falls Attribute zusammengefasst werden, steht
+                            // der "Index" ins Array falsch !
+                            i -= nAktHtLen - pSwpHints->Count();
+                            // Insert und Delete ?
+                        }
+
+                    // ist unser Attribut ueberhaupt noch vorhanden ?
+                    if( pHt == pSwpHints->GetHt( i ) )
+                    {
+                        const USHORT nAktLen = pSwpHints->Count();
+                        pSwpHints->DeleteAtPos(i);
+                        Insert( pHt, SETATTR_NOHINTADJUST );
+                        if( nAktLen > pSwpHints->Count() && i )
+                            --i;
+                    }
+                    continue;
+                }
+                else
+                    continue;
+                pSwpHints->DeleteAtPos(i);
+                Insert( pHt, SETATTR_NOHINTADJUST );
+            }
+            if ( !(nMode & INS_NOHINTEXPAND) &&
+                 rIdx == nLen && *pHt->GetStart() == rIdx.GetIndex() )
+            {
+                // Kein Feld, am Absatzanfang, HintExpand
+                pSwpHints->DeleteAtPos(i);
+                *pHt->GetStart() -= nLen;
+                Insert( pHt, SETATTR_NOHINTADJUST );
+            }
+        }
+        if ( pSwpHints->CanBeDeleted() )
+            DELETEZ( pSwpHints );
+    }
+
+    if ( GetDepends() )
+    {
+        SwInsTxt aHint( aPos, nLen );
+        SwModify::Modify( 0, &aHint );
+    }
+
+    CHECK_SWPHINTS(this);
+    return *this;
+}
+
+/*************************************************************************
+|*
+|*  SwTxtNode::Cut()
+|*
+|*  Beschreibung        text.doc
+|*  Ersterstellung      VB 20.03.91
+|*  Letzte Aenderung    JP 11.08.94
+|*
+*************************************************************************/
+
+void SwTxtNode::Cut( SwTxtNode *pDest, const SwIndex &rStart, xub_StrLen nLen )
+{
+    if(pDest)
+    {
+        SwIndex aDestStt( pDest, pDest->GetTxt().Len() );
+        _Cut( pDest, aDestStt, rStart, nLen, FALSE );
+    }
+    else
+        Erase( rStart, nLen );
+}
+
+
+void SwTxtNode::_Cut( SwTxtNode *pDest, const SwIndex& rDestStart,
+                     const SwIndex &rStart, xub_StrLen nLen, BOOL bUpdate )
+{
+    if(!pDest)
+    {
+        Erase( rStart, nLen );
+        return;
+    }
+
+    // nicht im Dokument verschieben ?
+    if( GetDoc() != pDest->GetDoc() )
+    {
+        Copy( pDest, rDestStart, rStart, nLen);
+        Erase(rStart,nLen);
+        return;
+    }
+
+    if( !nLen )
+    {
+        // wurde keine Laenge angegeben, dann Kopiere die Attribute
+        // an der Position rStart.
+        CopyAttr( pDest, rStart.GetIndex(), rDestStart.GetIndex() );
+        return;
+    }
+
+    xub_StrLen nTxtStartIdx = rStart.GetIndex();
+    xub_StrLen nDestStart = rDestStart.GetIndex();      // alte Pos merken
+    xub_StrLen nInitSize = pDest->aText.Len();
+
+    xub_StrLen *pEndIdx = 0;
+    xub_StrLen nAttrStartIdx = 0;
+    SwTxtAttr *pHt = 0;
+    SwTxtAttr *pNewHt = 0;
+
+    // wird in sich selbst verschoben, muss es gesondert behandelt werden !!
+    if( pDest == this )
+    {
+        aText.Insert( aText, nTxtStartIdx, nLen, nDestStart );
+        aText.Erase( nTxtStartIdx + (nDestStartCount() &&
+                (nAttrStartIdx = *(pHt = pSwpHints->GetHt(nAttrCnt))->
+                                    GetStart()) < nEnd )
+        {
+            pNewHt = 0;
+            pEndIdx = pHt->GetEnd();
+
+            if(nAttrStartIdx < nTxtStartIdx)
+            {
+                // Anfang liegt vor dem Bereich
+                if( RES_TXTATR_REFMARK != ( nWhich = pHt->Which() ) &&
+                    pEndIdx && *pEndIdx > nTxtStartIdx )
+                {
+                    // Attribut mit einem Bereich
+                    // und das Ende des Attribut liegt im Bereich
+                    pNewHt = MakeTxtAttr( pHt->GetAttr(), 0,
+                                        *pEndIdx > nEnd
+                                            ? nLen
+                                            : *pEndIdx - nTxtStartIdx );
+                }
+            }
+            else
+            {
+                // der Anfang liegt vollstaendig im Bereich
+                if( !pEndIdx || *pEndIdx < nEnd )
+                {
+                    // Attribut verschieben
+                    pSwpHints->Delete( pHt );
+                    // die Start/End Indicies neu setzen
+                    *pHt->GetStart() = nAttrStartIdx - nTxtStartIdx;
+                    if( pEndIdx )
+                        *pHt->GetEnd() = *pEndIdx - nTxtStartIdx;
+                    aArr.C40_INSERT( SwTxtAttr, pHt, aArr.Count() );
+                    continue;           // while-Schleife weiter, ohne ++ !
+                }
+                    // das Ende liegt dahinter
+                else if( RES_TXTATR_REFMARK != ( nWhich = pHt->Which() ))
+                {
+                    pNewHt = MakeTxtAttr( pHt->GetAttr(),
+                            nAttrStartIdx - nTxtStartIdx,
+                            !pEndIdx ? 0
+                                     : ( *pEndIdx > nEnd
+                                            ? nLen
+                                            : *pEndIdx - nTxtStartIdx ));
+                }
+            }
+            if( pNewHt )
+            {
+                // die Daten kopieren
+                lcl_CopyHint( nWhich, pHt, pNewHt, 0, this );
+                aArr.C40_INSERT( SwTxtAttr, pNewHt, aArr.Count() );
+            }
+            ++nAttrCnt;
+        }
+
+        if( bUpdate )
+            // Update aller Indizies
+            Update( rDestStart, nLen );
+#ifdef CUTNOEXPAND
+        else
+            // wird am Ende eingefuegt, nur die Attribut-Indizies verschieben
+            if( 0 < nLen && 0 < nInitSize && pSwpHints )
+            {
+                // siehe nach, ob an der Einfuegeposition das Ende eines
+                // Attributes stand. Ist es kein Feld, muss es expandiert werden !!!
+                for( n = 0; n < pSwpHints->Count(); n++ )
+                {
+                    pHt = pSwpHints->GetHt(n);
+                    if( 0 != ( pEndIdx = pHt->GetEnd() ) &&
+                        *pEndIdx == nInitSize )
+                        *pEndIdx += nLen;
+                }
+            }
+#endif
+        CHECK_SWPHINTS(this);
+
+        Update( rStart, nLen, TRUE );
+
+        CHECK_SWPHINTS(this);
+
+        // dann setze die kopierten/geloeschten Attribute in den Node
+        if( nDestStart <= nTxtStartIdx )
+            nTxtStartIdx += nLen;
+        else
+            nDestStart -= nLen;
+
+        for( n = 0; n < aArr.Count(); ++n )
+        {
+            pNewHt = aArr[n];
+            *pNewHt->GetStart() = nDestStart + *pNewHt->GetStart();
+            if( 0 != ( pEndIdx = pNewHt->GetEnd() ))
+                *pEndIdx = nDestStart + *pEndIdx;
+            Insert( pNewHt, SETATTR_NOTXTATRCHR );
+        }
+    }
+    else
+    {
+        xub_StrLen i = nInitSize - nDestStart;
+        pDest->aText.Insert( aText, nTxtStartIdx, nLen, nDestStart );
+        aText.Erase( nTxtStartIdx, nLen );
+        nLen = pDest->aText.Len() - nDestStart - i;  // um reale Groesse Updaten !
+        if( !nLen )                 // String nicht gewachsen ??
+            return;
+
+        i = 0;
+
+        if( bUpdate )
+            // Update aller Indizies
+            pDest->Update( rDestStart, nLen);
+#ifdef CUTNOEXPAND
+        else
+            // wird am Ende eingefuegt, nur die Attribut-Indizies verschieben
+            if( 0 < nLen && 0 < nInitSize && pDest->pSwpHints )
+            {
+                // siehe nach, ob an der Einfuegeposition das Ende eines
+                // Attributes stand. Ist es kein Feld, muss es expandiert werden !!!
+                for( USHORT n = 0; n < pDest->pSwpHints->Count(); n++ )
+                {
+                    pHt = pDest->pSwpHints->GetHt(n);
+                    if( 0 != ( pEndIdx = pHt->GetEnd() ) &&
+                        *pEndIdx == nInitSize )
+                        *pEndIdx += nLen;
+                }
+            }
+#endif
+        CHECK_SWPHINTS(pDest);
+
+        USHORT nEnd = rStart.GetIndex() + nLen;
+        SwDoc* pOtherDoc = pDest->GetDoc();
+        if( pOtherDoc == GetDoc() )
+            pOtherDoc = 0;
+        const BOOL bUndoNodes = !pOtherDoc && GetDoc()->GetUndoNds() == &GetNodes();
+
+        // harte Absatz umspannende Attribute kopieren
+        if( GetpSwAttrSet() )
+        {
+            // alle, oder nur die CharAttribute ?
+            if( nInitSize || pDest->GetpSwAttrSet() ||
+                nLen != pDest->GetTxt().Len() )
+            {
+                SfxItemSet aCharSet( pDest->GetDoc()->GetAttrPool(),
+                                    RES_CHRATR_BEGIN, RES_CHRATR_END-1,
+                                    RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT,
+                                    RES_TXTATR_INETFMT, RES_TXTATR_INETFMT,
+                                    RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1,
+                                    0 );
+                aCharSet.Put( *GetpSwAttrSet() );
+                if( aCharSet.Count() )
+                    pDest->SetAttr( aCharSet, nDestStart, nDestStart + nLen );
+            }
+            else
+                GetpSwAttrSet()->CopyToModify( *pDest );
+        }
+
+        // 2. Attribute verschieben
+        // durch das Attribute-Array, bis der Anfang des Geltungsbereiches
+        // des Attributs hinter dem zu verschiebenden Bereich liegt
+        USHORT nAttrCnt = 0, nWhich;
+        while( pSwpHints && nAttrCnt < pSwpHints->Count() &&
+                ( (nAttrStartIdx = *(pHt = pSwpHints->GetHt(nAttrCnt))->
+                                    GetStart()) < nEnd ) )
+        {
+            pNewHt = 0;
+            pEndIdx = pHt->GetEnd();
+
+            if(nAttrStartIdx < nTxtStartIdx)
+            {
+                // Anfang liegt vor dem Bereich
+                if( ( RES_TXTATR_REFMARK != ( nWhich = pHt->Which() )
+                    || bUndoNodes ) && pEndIdx && *pEndIdx > nTxtStartIdx )
+                {
+                    // Attribut mit einem Bereich
+                    // und das Ende des Attribut liegt im Bereich
+                    pNewHt = pDest->MakeTxtAttr( pHt->GetAttr(), nDestStart,
+                                        nDestStart + (
+                                        *pEndIdx > nEnd
+                                            ? nLen
+                                            : *pEndIdx - nTxtStartIdx ) );
+                }
+            }
+            else
+            {
+                // der Anfang liegt vollstaendig im Bereich
+                nWhich = pHt->Which();
+                if( !pEndIdx || *pEndIdx < nEnd ||
+                    ( !pOtherDoc && !bUndoNodes && RES_TXTATR_REFMARK
+                        == nWhich ) )
+                {
+                    // Attribut verschieben
+                    pSwpHints->Delete( pHt );
+                    // die Start/End Indicies neu setzen
+                    *pHt->GetStart() =
+                            nDestStart + (nAttrStartIdx - nTxtStartIdx);
+                    if( pEndIdx )
+                        *pHt->GetEnd() = nDestStart + (
+                                        *pEndIdx > nEnd
+                                            ? nLen
+                                            : *pEndIdx - nTxtStartIdx );
+                    pDest->Insert( pHt, SETATTR_NOTXTATRCHR | SETATTR_DONTREPLACE );
+                    continue;           // while-Schleife weiter, ohne ++ !
+                }
+                    // das Ende liegt dahinter
+                else if( RES_TXTATR_REFMARK != nWhich || bUndoNodes )
+                {
+                    pNewHt = MakeTxtAttr( pHt->GetAttr(),
+                            nDestStart + (nAttrStartIdx - nTxtStartIdx),
+                            !pEndIdx ? 0
+                                     : nDestStart + ( *pEndIdx > nEnd
+                                            ? nLen
+                                            : *pEndIdx - nTxtStartIdx ));
+                }
+            }
+            if ( pNewHt )
+            {
+                if( pDest->Insert( pNewHt, SETATTR_NOTXTATRCHR | SETATTR_DONTREPLACE ))
+                    lcl_CopyHint( nWhich, pHt, pNewHt, pOtherDoc, pDest );
+            }
+            ++nAttrCnt;
+        }
+        // sollten jetzt noch leere Attribute rumstehen, dann haben diese
+        // eine hoehere Praezedenz. Also herausholen und das Array updaten.
+        // Die dabei entstehenden leeren Hints werden von den gesicherten
+        // "uebergeplaettet".   (Bug: 6977)
+        if( pSwpHints && nAttrCnt < pSwpHints->Count() )
+        {
+            SwpHts aArr( 5 );
+            for( ; nAttrCnt < pSwpHints->Count() &&
+                    nEnd == *(pHt = pSwpHints->GetHt(nAttrCnt))->GetStart();
+                   ++nAttrCnt )
+            {
+                if( 0 != ( pEndIdx = pHt->GetEnd() ) && *pEndIdx == nEnd )
+                {
+                    aArr.C40_INSERT( SwTxtAttr, pHt, aArr.Count() );
+                    pSwpHints->Delete( pHt );
+                    --nAttrCnt;
+                }
+            }
+            Update( rStart, nLen, TRUE );
+
+            for( nAttrCnt = 0; nAttrCnt < aArr.Count(); ++nAttrCnt )
+            {
+                pHt = aArr[ nAttrCnt ];
+                *pHt->GetStart() = *pHt->GetEnd() = rStart.GetIndex();
+                Insert( pHt );
+            }
+        }
+        else
+            Update( rStart, nLen, TRUE );
+
+        CHECK_SWPHINTS(this);
+    }
+
+    if( pSwpHints && pSwpHints->CanBeDeleted() )
+        DELETEZ( pSwpHints );
+
+    // Frames benachrichtigen;
+    SwInsTxt aInsHint( nDestStart, nLen );
+    pDest->SwCntntNode::Modify( 0, &aInsHint );
+    SwDelTxt aDelHint( nTxtStartIdx, nLen );
+    SwCntntNode::Modify( 0, &aDelHint );
+}
+
+
+SwTxtNode& SwTxtNode::Erase(const SwIndex &rIdx, xub_StrLen nCount,
+                            const USHORT nMode )
+{
+    ASSERT( rIdx <= aText.Len(), "Array ueberindiziert." );
+
+    const xub_StrLen nCnt = STRING_LEN == nCount
+                      ? aText.Len() - rIdx.GetIndex() : nCount;
+    aText.Erase( rIdx.GetIndex(), nCnt );
+
+    /* GCAttr(); alle leeren weggwerfen ist zu brutal.
+     * Es duerfen nur die wegggeworfen werden,
+     * die im Bereich liegen und nicht am Ende des Bereiches liegen
+     */
+
+    // Abfrage auf pSwpHints weil TextFelder und FlyFrames Text loeschen
+    // (Rekursion)!!
+    for( USHORT i = 0; pSwpHints && i < pSwpHints->Count(); ++i )
+    {
+        SwTxtAttr *pHt = pSwpHints->GetHt(i);
+
+        const xub_StrLen nHtStt = *pHt->GetStart();
+
+        if( nHtStt < rIdx.GetIndex() )
+            continue;
+
+        // TextFelder und FlyFrames loeschen Text (Rekursion)!!
+        const xub_StrLen nEndIdx = rIdx.GetIndex() + nCnt;
+        if( nHtStt > nEndIdx )
+            // die Hints sind nach Ende sortiert, also ist Start
+            // vom Hint groesser als EndIdx dann Abbrechen
+            break;
+
+        const xub_StrLen* pHtEndIdx = pHt->GetEnd();
+        const USHORT nWhich = pHt->Which();
+
+        if( !pHtEndIdx )
+        {
+            // TxtHints ohne EndIndex werden natuerlich auch geloescht:
+            if( RES_TXTATR_BEGIN <= nWhich && RES_TXTATR_END > nWhich &&
+                nHtStt >= rIdx.GetIndex() && nHtStt < nEndIdx )
+            {
+                pSwpHints->DeleteAtPos(i);
+                // Damit im Dtor der TxtAttr ohne End die CH_TXTATR nicht
+                // geloescht werden...
+                *(pHt->GetStart()) = USHRT_MAX;
+                DestroyAttr( pHt );
+                --i;
+            }
+            continue;
+        }
+
+        if( *pHtEndIdx >= nEndIdx && !(
+            !(INS_EMPTYEXPAND & nMode) && *pHtEndIdx == nEndIdx &&
+            (nWhich == RES_TXTATR_TOXMARK || nWhich == RES_TXTATR_REFMARK)) )
+            continue;
+
+        pSwpHints->DeleteAtPos(i);
+        DestroyAttr( pHt );
+        --i;
+    }
+
+    if ( pSwpHints && pSwpHints->CanBeDeleted() )
+        DELETEZ( pSwpHints );
+
+    Update( rIdx, nCnt, TRUE );
+
+    if( 1 == nCnt )
+    {
+        SwDelChr aHint( rIdx.GetIndex() );
+        SwModify::Modify( 0, &aHint );
+    }
+    else
+    {
+        SwDelTxt aHint( rIdx.GetIndex(), nCnt );
+        SwModify::Modify( 0, &aHint );
+    }
+
+    CHECK_SWPHINTS(this);
+    return *this;
+}
+
+/***********************************************************************
+#*  Class       :   SwTxtNode
+#*  Methode     :   GCAttr
+#*
+#*  Beschreibung
+#*                  text.doc
+#*
+#*  Datum       :   MS 28.11.90
+#*  Update      :   VB 24.07.91
+#***********************************************************************/
+
+void SwTxtNode::GCAttr()
+{
+    if ( !pSwpHints )
+        return;
+
+    const SwTxtAttr *pHt = 0;
+    const xub_StrLen *pEndIdx = 0;
+    BOOL   bChanged = FALSE;
+    USHORT nMin = aText.Len(),
+           nMax = 0;
+    BOOL bAll = nMin != 0; // Bei leeren Absaetzen werden nur die
+                           // INet-Formate entfernt.
+
+    for ( USHORT i = 0; pSwpHints && i < pSwpHints->Count(); ++i )
+    {
+        pHt = (*pSwpHints)[i];
+
+        // wenn Ende und Start gleich sind --> loeschen
+        pEndIdx = pHt->GetEnd();
+        if( pEndIdx && (*pEndIdx == *pHt->GetStart())
+            && ( bAll || pHt->Which() == RES_TXTATR_INETFMT ) )
+        {
+            bChanged = TRUE;
+            nMin = Min( nMin, *pHt->GetStart() );
+            nMax = Max( nMax, *pHt->GetEnd() );
+            DestroyAttr( pSwpHints->Cut(i) );
+            --i;
+        }
+        else
+            ((SwTxtAttr*)pHt)->SetDontExpand( FALSE );
+    }
+    if ( pSwpHints && pSwpHints->CanBeDeleted() )
+        DELETEZ( pSwpHints );
+
+    if(bChanged)
+    {
+        //TxtFrm's reagieren auf aHint, andere auf aNew
+        SwUpdateAttr aHint( nMin, nMax, 0 );
+        SwModify::Modify( 0, &aHint );
+        SwFmtChg aNew( GetTxtColl() );
+        SwModify::Modify( 0, &aNew );
+    }
+}
+
+const SwNodeNum* SwTxtNode::UpdateNum( const SwNodeNum& rNum )
+{
+    if( NO_NUMBERING == rNum.GetLevel() )       // kein Nummerierung mehr ?
+    {
+        if( !pNdNum )
+            return 0;
+        delete pNdNum, pNdNum = 0;
+    }
+    else
+    {
+        if( !pNdNum )
+            pNdNum = new SwNodeNum( rNum );
+        else if( !( *pNdNum == rNum ))
+            *pNdNum = rNum;
+    }
+    NumRuleChgd();
+    return pNdNum;
+}
+
+const SwNumRule* SwTxtNode::GetNumRule() const
+{
+    const SwNumRule* pRet = 0;
+    const SfxPoolItem* pItem = GetNoCondAttr( RES_PARATR_NUMRULE, TRUE );
+    if( pItem && ((SwNumRuleItem*)pItem)->GetValue().Len() )
+        pRet = GetDoc()->FindNumRulePtr( ((SwNumRuleItem*)pItem)->GetValue() );
+    return pRet;
+}
+
+void SwTxtNode::NumRuleChgd()
+{
+#ifndef NUM_RELSPACE
+
+    // 6969: Aktualisierung der NumPortions auch bei leeren Zeilen!
+    SwInsTxt aHint( 0, 0 );
+    SwModify::Modify( 0, &aHint );
+
+#else
+
+    if( IsInCache() )
+    {
+        SwFrm::GetCache().Delete( this );
+        SetInCache( FALSE );
+    }
+    SetInSwFntCache( FALSE );
+
+    SvxLRSpaceItem& rLR = (SvxLRSpaceItem&)GetSwAttrSet().GetLRSpace();
+    SwModify::Modify( &rLR, &rLR );
+
+#endif
+}
+
+const SwNodeNum* SwTxtNode::UpdateOutlineNum( const SwNodeNum& rNum )
+{
+    if( NO_NUMBERING == rNum.GetLevel() )       // kein Nummerierung mehr ?
+    {
+        if( !pNdOutl )
+            return 0;
+        delete pNdOutl, pNdOutl = 0;
+    }
+    else
+    {
+        if( !pNdOutl )
+            pNdOutl = new SwNodeNum( rNum );
+        else if( !( *pNdOutl == rNum ))
+            *pNdOutl = rNum;
+    }
+
+    // 6969: Aktualisierung der NumPortions auch bei leeren Zeilen!
+    NumRuleChgd();
+    return pNdOutl;
+}
+
+SwTxtNode* SwTxtNode::_MakeNewTxtNode( const SwNodeIndex& rPos, BOOL bNext,
+                                        BOOL bChgFollow )
+{
+    /* hartes PageBreak/PageDesc/ColumnBreak aus AUTO-Set ignorieren */
+    SwAttrSet* pNewAttrSet = 0;
+    if( GetpSwAttrSet() )
+    {
+        pNewAttrSet = new SwAttrSet( *GetpSwAttrSet() );
+        SwAttrSet* pTmpSet = GetpSwAttrSet();
+
+        if( bNext )     // der naechste erbt keine Breaks!
+            pTmpSet = pNewAttrSet;
+
+        // PageBreaks/PageDesc/ColBreak rausschmeissen.
+        BOOL bRemoveFromCache = 0 != pTmpSet->ClearItem( RES_PAGEDESC );
+        if( SFX_ITEM_SET == pTmpSet->GetItemState( RES_BREAK, FALSE ) )
+        {
+            pTmpSet->ClearItem( RES_BREAK );
+            bRemoveFromCache = TRUE;
+        }
+        if( !bNext && bRemoveFromCache && IsInCache() )
+        {
+            SwFrm::GetCache().Delete( this );
+            SetInCache( FALSE );
+        }
+    }
+    SwNodes& rNds = GetNodes();
+
+    SwTxtFmtColl* pColl = GetTxtColl();
+
+    SwTxtNode *pNode = new SwTxtNode( rPos, pColl, pNewAttrSet );
+
+    if( pNewAttrSet )
+        delete pNewAttrSet;
+
+    const SwNumRule* pRule = GetNumRule();
+    if( pRule && rNds.IsDocNodes() )
+    {
+        // ist am Node eine Nummerierung gesetzt und wird dieser vor dem
+        // alten eingefuegt, so kopiere die Nummer
+        if( !bNext && pNdNum && NO_NUMBERING != pNdNum->GetLevel() )
+        {
+            if( pNode->pNdNum )
+                *pNode->pNdNum = *pNdNum;
+            else
+                pNode->pNdNum = new SwNodeNum( *pNdNum );
+
+            // SetValue immer auf default zurueck setzem
+            pNdNum->SetSetValue( USHRT_MAX );
+            if( pNdNum->IsStart() )
+            {
+                pNdNum->SetStart( FALSE );
+                pNode->pNdNum->SetStart( TRUE );
+            }
+
+            // Ein SplitNode erzeugt !!immer!! einen neuen Level, NO_NUM
+            // kann nur ueber eine entsprechende Methode erzeugt werden !!
+            if( NO_NUMLEVEL & pNdNum->GetLevel() )
+            {
+                pNdNum->SetLevel( pNdNum->GetLevel() & ~NO_NUMLEVEL );
+#ifndef NUM_RELSPACE
+                SetNumLSpace( TRUE );
+#endif
+            }
+        }
+        rNds.GetDoc()->UpdateNumRule( pRule->GetName(), pNode->GetIndex() );
+    }
+
+    // jetzt kann es sein, das durch die Nummerierung dem neuen Node eine
+    // Vorlage aus dem Pool zugewiesen wurde. Dann darf diese nicht
+    // nochmal uebergeplaettet werden !!
+    if( pColl != pNode->GetTxtColl() ||
+        ( bChgFollow && pColl != GetTxtColl() ))
+        return pNode;       // mehr duerfte nicht gemacht werden oder ????
+
+    pNode->_ChgTxtCollUpdateNum( 0, pColl ); // fuer Nummerierung/Gliederung
+    if( bNext || !bChgFollow )
+        return pNode;
+
+    SwTxtFmtColl *pNextColl = &pColl->GetNextTxtFmtColl();
+    ChgFmtColl( pNextColl );
+
+    return pNode;
+}
+
+SwCntntNode* SwTxtNode::AppendNode( const SwPosition & rPos )
+{
+    // Position hinter dem eingefuegt wird
+    SwNodeIndex aIdx( rPos.nNode, 1 );
+    SwTxtNode* pNew = _MakeNewTxtNode( aIdx, TRUE );
+    if( GetDepends() )
+        MakeFrms( *pNew );
+    return pNew;
+}
+
+/*************************************************************************
+ *                      SwTxtNode::GetTxtAttr
+ *
+ * Diese Methode liefert nur Textattribute auf der Position nIdx
+ * zurueck, die kein EndIdx besitzen und denselben Which besitzen.
+ * Ueblicherweise steht an dieser Position ein CH_TXTATR.
+ * Bei RES_TXTATR_END entfaellt die Pruefung auf den Which-Wert.
+ *************************************************************************/
+
+SwTxtAttr *SwTxtNode::GetTxtAttr( const xub_StrLen nIdx,
+                                  const USHORT nWhichHt ) const
+{
+    if( pSwpHints )
+    {
+        for( USHORT i = 0; i < pSwpHints->Count(); ++i )
+        {
+            SwTxtAttr *pPos = pSwpHints->GetHt(i);
+            const xub_StrLen nStart = *pPos->GetStart();
+            if( nIdx < nStart )
+                return 0;
+            if( nIdx == nStart && !pPos->GetEnd() )
+            {
+                if( RES_TXTATR_END == nWhichHt || nWhichHt == pPos->Which() )
+                    return pPos;
+                else
+                    return 0;
+            }
+        }
+    }
+    return 0;
+}
+
+/*************************************************************************
+ *                      SwTxtNode::GetExpandTxt
+ *************************************************************************/
+// Felder werden expandiert:
+
+XubString SwTxtNode::GetNumString() const
+{
+    const SwNodeNum* pNum;
+    const SwNumRule* pRule;
+    if( (( 0 != ( pNum = GetNum() ) &&
+            0 != ( pRule = GetNumRule() )) ||
+            ( 0 != ( pNum = GetOutlineNum() ) &&
+            0 != ( pRule = GetDoc()->GetOutlineNumRule() ) ) ) &&
+        pNum->GetLevel() < MAXLEVEL &&
+        pRule->Get( pNum->GetLevel() ).IsTxtFmt() )
+        return pRule->MakeNumString( *pNum );
+    return aEmptyStr;
+}
+
+long SwTxtNode::GetLeftMarginWithNum( BOOL bTxtLeft ) const
+{
+    long nOffset;
+    const SwNodeNum* pNum;
+    const SwNumRule* pRule;
+    if( (( 0 != ( pNum = GetNum() ) &&
+            0 != ( pRule = GetNumRule() )) ||
+            ( 0 != ( pNum = GetOutlineNum() ) &&
+            0 != ( pRule = GetDoc()->GetOutlineNumRule() ) ) ) &&
+            pNum->GetLevel() < NO_NUM )
+    {
+        const SwNumFmt& rFmt = pRule->Get( GetRealLevel( pNum->GetLevel() ) );
+        nOffset = rFmt.GetAbsLSpace();
+
+        if( !bTxtLeft )
+        {
+            if( 0 > rFmt.GetFirstLineOffset() &&
+                nOffset > -rFmt.GetFirstLineOffset() )
+                nOffset += rFmt.GetFirstLineOffset();
+            else
+                nOffset = 0;
+        }
+
+        if( pRule->IsAbsSpaces() )
+            nOffset -= GetSwAttrSet().GetLRSpace().GetLeft();
+    }
+    else
+        nOffset = 0;
+    return nOffset;
+}
+
+BOOL SwTxtNode::GetFirstLineOfsWithNum( short& rFLOffset ) const
+{
+    const SwNodeNum* pNum;
+    const SwNumRule* pRule;
+    if( (( 0 != ( pNum = GetNum() ) &&
+            0 != ( pRule = GetNumRule() )) ||
+            ( 0 != ( pNum = GetOutlineNum() ) &&
+            0 != ( pRule = GetDoc()->GetOutlineNumRule() ) ) ) &&
+            pNum->GetLevel() < NO_NUM )
+    {
+        if( NO_NUMLEVEL & pNum->GetLevel() )
+            rFLOffset = 0;
+        else
+            rFLOffset = pRule->Get( pNum->GetLevel() ).GetFirstLineOffset();
+        return TRUE;
+    }
+    rFLOffset = GetSwAttrSet().GetLRSpace().GetTxtFirstLineOfst();
+    return FALSE;
+}
+
+void SwTxtNode::Replace0xFF( XubString& rTxt, xub_StrLen& rTxtStt,
+                            xub_StrLen nEndPos, BOOL bExpandFlds ) const
+{
+    if( GetpSwpHints() )
+    {
+        sal_Unicode cSrchChr = CH_TXTATR_BREAKWORD;
+        for( int nSrchIter = 0; 2 > nSrchIter; ++nSrchIter,
+                                cSrchChr = CH_TXTATR_INWORD )
+        {
+            xub_StrLen nPos = rTxt.Search( cSrchChr );
+            while( STRING_NOTFOUND != nPos && nPos < nEndPos )
+            {
+                const SwTxtAttr* pAttr = GetTxtAttr( rTxtStt + nPos );
+                if( pAttr )
+                {
+                    switch( pAttr->Which() )
+                    {
+                    case RES_TXTATR_FIELD:
+                        rTxt.Erase( nPos, 1 );
+                        if( bExpandFlds )
+                        {
+                            const XubString aExpand( ((SwTxtFld*)pAttr)->GetFld().
+                                                    GetFld()->Expand() );
+                            rTxt.Insert( aExpand, nPos );
+                            nPos += aExpand.Len();
+                            nEndPos += aExpand.Len();
+                            rTxtStt -= aExpand.Len();
+                        }
+                        ++rTxtStt;
+                        break;
+                    case RES_TXTATR_HARDBLANK:
+                        rTxt.SetChar( nPos, ((SwTxtHardBlank*)pAttr)->GetChar() );
+                        ++nPos;
+                        ++nEndPos;
+                        break;
+                    case RES_TXTATR_FTN:
+                        rTxt.Erase( nPos, 1 );
+                        if( bExpandFlds )
+                        {
+                            const SwFmtFtn& rFtn = pAttr->GetFtn();
+                            XubString sExpand;
+                            if( rFtn.GetNumStr().Len() )
+                                sExpand = rFtn.GetNumStr();
+                            else if( rFtn.IsEndNote() )
+                                sExpand = GetDoc()->GetEndNoteInfo().aFmt.
+                                                GetNumStr( rFtn.GetNumber() );
+                            else
+                                sExpand = GetDoc()->GetFtnInfo().aFmt.
+                                                GetNumStr( rFtn.GetNumber() );
+                            rTxt.Insert( sExpand, nPos );
+                            nPos += sExpand.Len();
+                            nEndPos += sExpand.Len();
+                            rTxtStt -= sExpand.Len();
+                        }
+                        ++rTxtStt;
+                        break;
+                    default:
+                        rTxt.Erase( nPos, 1 );
+                        ++rTxtStt;
+                    }
+                }
+                else
+                    ++nPos, ++nEndPos;
+                nPos = rTxt.Search( cSrchChr, nPos );
+            }
+        }
+    }
+}
+
+XubString SwTxtNode::GetExpandTxt( const xub_StrLen nIdx, const xub_StrLen nLen,
+                                const BOOL bWithNum  ) const
+{
+    XubString aTxt( GetTxt().Copy( nIdx, nLen ) );
+    xub_StrLen nTxtStt = nIdx;
+    Replace0xFF( aTxt, nTxtStt, aTxt.Len(), TRUE );
+
+    if( bWithNum )
+        aTxt.Insert( GetNumString(), 0 );
+
+    return aTxt;
+}
+
+BOOL SwTxtNode::GetExpandTxt( SwTxtNode& rDestNd, const SwIndex* pDestIdx,
+                        xub_StrLen nIdx, xub_StrLen nLen, BOOL bWithNum ) const
+{
+    if( &rDestNd == this )
+        return FALSE;
+
+    SwIndex aDestIdx( &rDestNd, rDestNd.GetTxt().Len() );
+    if( pDestIdx )
+        aDestIdx = *pDestIdx;
+    xub_StrLen nDestStt = aDestIdx.GetIndex();
+
+    // Text einfuegen
+    rDestNd.Insert( GetTxt().Copy( nIdx, nLen ), aDestIdx );
+    nLen = aDestIdx.GetIndex() - nDestStt;
+
+    // alle FontAttribute mit CHARSET Symbol in dem Bereich setzen
+    if( pSwpHints )
+    {
+        xub_StrLen nInsPos = nDestStt - nIdx;
+        for( USHORT i = 0; i < pSwpHints->Count(); i++ )
+        {
+            const SwTxtAttr* pHt = (*pSwpHints)[i];
+            xub_StrLen nAttrStartIdx;
+            USHORT nWhich = pHt->Which();
+            if( nIdx + nLen <= ( nAttrStartIdx = *pHt->GetStart() ) )
+                break;      // ueber das Textende
+
+            const SvxFontItem* pFont;
+            const xub_StrLen *pEndIdx = pHt->GetEnd();
+            if( pEndIdx && *pEndIdx > nIdx && (
+                ( RES_CHRATR_FONT == nWhich &&
+                  RTL_TEXTENCODING_SYMBOL == (pFont = &pHt->GetFont())->GetCharSet() ) ||
+                ( RES_TXTATR_CHARFMT == nWhich &&
+                  RTL_TEXTENCODING_SYMBOL == (pFont = &pHt->GetCharFmt().
+                      GetCharFmt()->GetFont())->GetCharSet() )))
+            {
+                // Attribut liegt im Bereich, also kopieren
+                rDestNd.Insert( *pFont, nInsPos + nAttrStartIdx,
+                                        nInsPos + *pEndIdx );
+            }
+            else if( !pEndIdx && nAttrStartIdx >= nIdx )
+            {
+                aDestIdx = nInsPos + nAttrStartIdx;
+                switch( nWhich )
+                {
+                case RES_TXTATR_FIELD:
+                    {
+                        const XubString aExpand( ((SwTxtFld*)pHt)->GetFld().GetFld()->Expand() );
+                        if( aExpand.Len() )
+                        {
+                            aDestIdx++;     // dahinter einfuegen;
+                            rDestNd.Insert( aExpand, aDestIdx );
+                            aDestIdx = nInsPos + nAttrStartIdx;
+                            nInsPos += aExpand.Len();
+                        }
+                        rDestNd.Erase( aDestIdx, 1 );
+                        --nInsPos;
+                    }
+                    break;
+
+                case RES_TXTATR_HARDBLANK:
+                    rDestNd.aText.SetChar( nInsPos + nAttrStartIdx,
+                                ((SwTxtHardBlank*)pHt)->GetChar() );
+                    break;
+
+                case RES_TXTATR_FTN:
+                    {
+                        const SwFmtFtn& rFtn = pHt->GetFtn();
+                        XubString sExpand;
+                        if( rFtn.GetNumStr().Len() )
+                            sExpand = rFtn.GetNumStr();
+                        else if( rFtn.IsEndNote() )
+                            sExpand = GetDoc()->GetEndNoteInfo().aFmt.
+                                            GetNumStr( rFtn.GetNumber() );
+                        else
+                            sExpand = GetDoc()->GetFtnInfo().aFmt.
+                                            GetNumStr( rFtn.GetNumber() );
+                        if( sExpand.Len() )
+                        {
+                            aDestIdx++;     // dahinter einfuegen;
+                            rDestNd.Insert( SvxEscapementItem(
+                                    SVX_ESCAPEMENT_SUPERSCRIPT ),
+                                    aDestIdx.GetIndex(),
+                                    aDestIdx.GetIndex() );
+                            rDestNd.Insert( sExpand, aDestIdx, INS_EMPTYEXPAND );
+                            aDestIdx = nInsPos + nAttrStartIdx;
+                            nInsPos += sExpand.Len();
+                        }
+                        rDestNd.Erase( aDestIdx, 1 );
+                        --nInsPos;
+                    }
+                    break;
+
+                default:
+                    rDestNd.Erase( aDestIdx, 1 );
+                    --nInsPos;
+                }
+            }
+        }
+    }
+
+    if( bWithNum )
+    {
+        aDestIdx = nDestStt;
+        rDestNd.Insert( GetNumString(), aDestIdx );
+    }
+    return TRUE;
+}
+
+
+XubString SwTxtNode::GetRedlineTxt( xub_StrLen nIdx, xub_StrLen nLen,
+                                BOOL bExpandFlds, BOOL bWithNum ) const
+{
+    SvUShorts aRedlArr;
+    const SwDoc* pDoc = GetDoc();
+    USHORT nRedlPos = pDoc->GetRedlinePos( *this, REDLINE_DELETE );
+    if( USHRT_MAX != nRedlPos )
+    {
+        // es existiert fuer den Node irgendein Redline-Delete-Object
+        const ULONG nNdIdx = GetIndex();
+        for( ; nRedlPos < pDoc->GetRedlineTbl().Count() ; ++nRedlPos )
+        {
+            const SwRedline* pTmp = pDoc->GetRedlineTbl()[ nRedlPos ];
+            if( REDLINE_DELETE == pTmp->GetType() )
+            {
+                const SwPosition *pRStt = pTmp->Start(), *pREnd = pTmp->End();
+                if( pRStt->nNode < nNdIdx )
+                {
+                    if( pREnd->nNode > nNdIdx )
+                        // Absatz ist komplett geloescht
+                        return aEmptyStr;
+                    else if( pREnd->nNode == nNdIdx )
+                    {
+                        // von 0 bis nContent ist alles geloescht
+                        aRedlArr.Insert( xub_StrLen(0), aRedlArr.Count() );
+                        aRedlArr.Insert( pREnd->nContent.GetIndex(), aRedlArr.Count() );
+                    }
+                }
+                else if( pRStt->nNode == nNdIdx )
+                {
+                    aRedlArr.Insert( pRStt->nContent.GetIndex(), aRedlArr.Count() );
+                    if( pREnd->nNode == nNdIdx )
+                        aRedlArr.Insert( pREnd->nContent.GetIndex(), aRedlArr.Count() );
+                    else
+                    {
+                        aRedlArr.Insert( GetTxt().Len(), aRedlArr.Count() );
+                        break;      // mehr kann nicht kommen
+                    }
+                }
+                else
+                    break;      // mehr kann nicht kommen
+            }
+        }
+    }
+
+    XubString aTxt( GetTxt().Copy( nIdx, nLen ) );
+
+    xub_StrLen nTxtStt = nIdx, nIdxEnd = nIdx + aTxt.Len();
+    for( USHORT n = 0; n < aRedlArr.Count(); n += 2 )
+    {
+        xub_StrLen nStt = aRedlArr[ n ], nEnd = aRedlArr[ n+1 ];
+        if( ( nIdx <= nStt && nStt <= nIdxEnd ) ||
+            ( nIdx <= nEnd && nEnd <= nIdxEnd ))
+        {
+            if( nStt < nIdx ) nStt = nIdx;
+            if( nIdxEnd < nEnd ) nEnd = nIdxEnd;
+            xub_StrLen nDelCnt = nEnd - nStt;
+            aTxt.Erase( nStt - nTxtStt, nDelCnt );
+            Replace0xFF( aTxt, nTxtStt, nStt - nTxtStt, bExpandFlds );
+            nTxtStt += nDelCnt;
+        }
+        else if( nStt >= nIdxEnd )
+            break;
+    }
+    Replace0xFF( aTxt, nTxtStt, aTxt.Len(), bExpandFlds );
+
+    if( bWithNum )
+        aTxt.Insert( GetNumString(), 0 );
+    return aTxt;
+}
+
+/*************************************************************************
+ *                      SwTxtNode::GetExpandTxt
+ *************************************************************************/
+// Felder werden expandiert:
+
+void SwTxtNode::Replace( const SwIndex& rStart, xub_Unicode cCh )
+{
+
+    ASSERT( rStart.GetIndex() < aText.Len(), "ausserhalb des Strings" );
+    SwTxtAttr* pHt;
+    if( ( CH_TXTATR_BREAKWORD == aText.GetChar( rStart.GetIndex() ) ||
+          CH_TXTATR_INWORD == aText.GetChar( rStart.GetIndex() )) &&
+        0 != ( pHt = GetTxtAttr( rStart.GetIndex() ) ))
+    {
+        Delete( pHt );
+        aText.Insert( cCh, rStart.GetIndex() );
+    }
+    else
+        aText.SetChar( rStart.GetIndex(), cCh );
+
+    SwDelTxt aDelHint( rStart.GetIndex(), 1 );
+    SwModify::Modify( 0, &aDelHint );
+
+    SwInsTxt aHint( rStart.GetIndex(), 1 );
+    SwModify::Modify( 0, &aHint );
+}
+
+
+void SwTxtNode::Replace( const SwIndex& rStart, xub_StrLen nLen,
+                            const XubString& rText )
+{
+    ASSERT( rStart.GetIndex() < aText.Len() &&
+            rStart.GetIndex() + nLen <= aText.Len(),
+            "ausserhalb des Strings" );
+    SwTxtAttr* pHt;
+    xub_StrLen nStart = rStart.GetIndex();
+    xub_StrLen nEnde = nStart + nLen;
+    xub_StrLen nDelLen = nLen;
+    for( xub_StrLen nPos = nStart; nPos < nEnde; ++nPos )
+        if( ( CH_TXTATR_BREAKWORD == aText.GetChar( nPos ) ||
+              CH_TXTATR_INWORD == aText.GetChar( nPos )) &&
+            0 != ( pHt = GetTxtAttr( nPos ) ))
+        {
+            Delete( pHt );
+            --nEnde;
+            --nLen;
+        }
+
+    if( nLen && rText.Len() )
+    {
+        // dann das 1. Zeichen ersetzen den Rest loschen und einfuegen
+        // Dadurch wird die Attributierung des 1. Zeichen expandiert!
+        aText.SetChar( nStart, rText.GetChar( 0 ) );
+
+        ((SwIndex&)rStart)++;
+        aText.Erase( rStart.GetIndex(), nLen - 1 );
+        Update( rStart, nLen - 1, TRUE );
+
+        XubString aTmpTxt( rText ); aTmpTxt.Erase( 0, 1 );
+        aText.Insert( aTmpTxt, rStart.GetIndex() );
+        Update( rStart, aTmpTxt.Len(), FALSE );
+    }
+    else
+    {
+        aText.Erase( nStart, nLen );
+        Update( rStart, nLen, TRUE );
+
+        aText.Insert( rText, nStart );
+        Update( rStart, rText.Len(), FALSE );
+    }
+    SwDelTxt aDelHint( nStart, nDelLen );
+    SwModify::Modify( 0, &aDelHint );
+
+    SwInsTxt aHint( nStart, rText.Len() );
+    SwModify::Modify( 0, &aHint );
+}
+
+void SwTxtNode::Modify( SfxPoolItem* pOldValue, SfxPoolItem* pNewValue )
+{
+    // Bug 24616/24617:
+    //      Modify ueberladen, damit beim Loeschen von Vorlagen diese
+    //      wieder richtig verwaltet werden (Outline-Numerierung!!)
+    //  Bug25481:
+    //      bei Nodes im Undo nie _ChgTxtCollUpdateNum rufen.
+    if( pOldValue && pNewValue && RES_FMT_CHG == pOldValue->Which() &&
+        pRegisteredIn == ((SwFmtChg*)pNewValue)->pChangedFmt &&
+        GetNodes().IsDocNodes() )
+        _ChgTxtCollUpdateNum(
+                        (SwTxtFmtColl*)((SwFmtChg*)pOldValue)->pChangedFmt,
+                        (SwTxtFmtColl*)((SwFmtChg*)pNewValue)->pChangedFmt );
+
+    SwCntntNode::Modify( pOldValue, pNewValue );
+}
+
+
+
diff --git a/sw/source/core/txtnode/swfntcch.cxx b/sw/source/core/txtnode/swfntcch.cxx
new file mode 100644
index 000000000000..111e27171734
--- /dev/null
+++ b/sw/source/core/txtnode/swfntcch.cxx
@@ -0,0 +1,123 @@
+/*************************************************************************
+ *
+ *  $RCSfile: swfntcch.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:27 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "swfntcch.hxx"
+#include "fmtcol.hxx"
+#include "swfont.hxx"
+
+// globale Variablen, werden in SwFntCch.Hxx bekanntgegeben
+// Der FontCache wird in TxtInit.Cxx _TXTINIT erzeugt und in _TXTEXIT geloescht
+SwFontCache *pSwFontCache = NULL;
+
+/*************************************************************************
+|*
+|*  SwFontObj::SwFontObj(), ~SwFontObj()
+|*
+|*  Ersterstellung      AMA 25. Jun. 95
+|*  Letzte Aenderung    AMA 25. Jun. 95
+|*
+|*************************************************************************/
+
+SwFontObj::SwFontObj( const void *pOwner, ViewShell *pSh ) :
+    SwCacheObj( (void*)pOwner ),
+    aSwFont( &((SwTxtFmtColl *)pOwner)->GetAttrSet() )
+{
+    aSwFont.GoMagic( pSh, aSwFont.GetActual() );
+}
+
+SwFontObj::~SwFontObj()
+{
+}
+
+/*************************************************************************
+|*
+|*  SwFontAccess::SwFontAccess()
+|*
+|*  Ersterstellung      AMA 25. Jun. 95
+|*  Letzte Aenderung    AMA 25. Jun. 95
+|*
+|*************************************************************************/
+
+SwFontAccess::SwFontAccess( const void *pOwner, ViewShell *pSh ) :
+    SwCacheAccess( *pSwFontCache, pOwner,
+            (BOOL) ((SwTxtFmtColl*)pOwner)->IsInSwFntCache() ),
+    pShell( pSh )
+{
+}
+
+SwFontObj *SwFontAccess::Get( )
+{
+    return (SwFontObj *) SwCacheAccess::Get( );
+}
+
+SwCacheObj *SwFontAccess::NewObj( )
+{
+    ((SwTxtFmtColl*)pOwner)->SetInSwFntCache( TRUE );
+    return new SwFontObj( pOwner, pShell );
+}
+
+
diff --git a/sw/source/core/txtnode/swfont.cxx b/sw/source/core/txtnode/swfont.cxx
new file mode 100644
index 000000000000..b312f85167e5
--- /dev/null
+++ b/sw/source/core/txtnode/swfont.cxx
@@ -0,0 +1,1103 @@
+/*************************************************************************
+ *
+ *  $RCSfile: swfont.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:27 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "hintids.hxx"
+
+#ifndef _SYSTEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BRSHITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_WRLMITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BLNKITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_NHYPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_KERNITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_CMAPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_LANGITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_ESCPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_AKRNITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_SHDDITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_CNTRITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_COLRITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_CSCOITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_CRSDITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_UDLNITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_WGHTITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_POSTITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_FHGTITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_FONTITEM_HXX //autogen
+#include 
+#endif
+#ifndef _CHARATR_HXX
+#include 
+#endif
+#ifndef _SWATRSET_HXX //autogen
+#include 
+#endif
+#ifndef _APP_HXX //autogen
+#include 
+#endif
+#ifndef _OUTDEV_HXX //autogen
+#include 
+#endif
+
+
+#include "viewsh.hxx"       // Bildschirmabgleich
+#include "swfont.hxx"
+#include "fntcache.hxx"     // FontCache
+#include "drawfont.hxx"     // SwDrawTextInfo
+
+#if defined(WIN) || defined(WNT) || defined(PM2)
+#define FNT_LEADING_HACK
+#endif
+
+#if defined(WIN) || defined(WNT)
+#define FNT_ATM_HACK
+#endif
+
+#ifndef PRODUCT
+// globale Variable
+SvStatistics aSvStat;
+#endif
+
+/************************************************************************
+ * Hintergrundbrush setzen, z.B. bei Zeichenvorlagen
+ ***********************************************************************/
+
+void SwFont::SetBackColor( Color* pNewColor )
+{
+    delete pBackColor;
+    pBackColor = pNewColor;
+    bFntChg = TRUE;
+    aSub[SW_LATIN].pMagic = aSub[SW_CJK].pMagic = aSub[SW_CTL].pMagic = 0;
+}
+
+/************************************************************************
+ * Hintergrundbrush setzen,
+ * die alte Brush wird _nicht_ destruiert, sondern ist der Rueckgabewert.
+ ***********************************************************************/
+
+Color* SwFont::XChgBackColor( Color* pNewColor )
+{
+    Color* pRet = pBackColor;
+    pBackColor = pNewColor;
+    bFntChg = TRUE;
+    aSub[SW_LATIN].pMagic = aSub[SW_CJK].pMagic = aSub[SW_CTL].pMagic = 0;
+    return pRet;
+}
+
+/*************************************************************************
+ Escapement:
+    frEsc:  Fraction, Grad des Escapements
+    Esc = resultierendes Escapement
+    A1 = Original-Ascent            (nOrgAscent)
+    A2 = verkleinerter Ascent       (nEscAscent)
+    Ax = resultierender Ascent      (GetAscent())
+    H1 = Original-Hoehe             (nOrgHeight)
+    H2 = verkleinerter Hoehe        (nEscHeight)
+    Hx = resultierender Hoehe       (GetHeight())
+    Bx = resultierende Baseline fuer die Textausgabe (CalcPos())
+         (Vorsicht: Y - A1!)
+
+    Escapement:
+        Esc = H1 * frEsc;
+
+    Hochstellung:
+        Ax = A2 + Esc;
+        Hx = H2 + Esc;
+        Bx = A1 - Esc;
+
+    Tiefstellung:
+        Ax = A1;
+        Hx = A1 + Esc + (H2 - A2);
+        Bx = A1 + Esc;
+
+*************************************************************************/
+
+/*************************************************************************
+ *                  SwSubFont::CalcEscAscent( const USHORT nOldAscent )
+ *************************************************************************/
+
+// nEsc ist der Prozentwert
+USHORT SwSubFont::CalcEscAscent( const USHORT nOldAscent ) const
+{
+    if( DFLT_ESC_AUTO_SUPER != GetEscapement() &&
+        DFLT_ESC_AUTO_SUB != GetEscapement() )
+    {
+        const long nAscent = nOldAscent +
+                             ( (long) nOrgHeight * GetEscapement() ) / 100L;
+        if ( nAscent>0 )
+            return ( Max( USHORT (nAscent), nOrgAscent ));
+    }
+    return nOrgAscent;
+}
+
+/*************************************************************************
+ *                      SwSubFont::SetFnt()
+ *************************************************************************/
+
+void SwSubFont::SetFnt( const SvxFont &rFont )
+{
+    *((SvxFont*)this) = rFont;
+    if ( 100 == GetPropr() )
+        aSize = Font::GetSize();
+    else
+        aSize = Size( (long) Font::GetSize().Width() * 100L / GetPropr(),
+                      (long) Font::GetSize().Height() * 100L / GetPropr() );
+    pMagic = 0;
+    ASSERT( IsTransparent(), "SwSubFont: Transparent revolution" );
+}
+
+/*************************************************************************
+ *                      SwFont::SetFnt()
+ *************************************************************************/
+
+void SwFont::SetFnt( const SwAttrSet *pAttrSet )
+{
+    if( pAttrSet )
+    {
+        {   // Latin
+            const SvxFontItem& rFont = pAttrSet->GetFont();
+            aSub[SW_LATIN].SetFamily( rFont.GetFamily() );
+            aSub[SW_LATIN].Font::SetName( rFont.GetFamilyName() );
+            aSub[SW_LATIN].Font::SetStyleName( rFont.GetStyleName() );
+            aSub[SW_LATIN].Font::SetPitch( rFont.GetPitch() );
+            aSub[SW_LATIN].Font::SetCharSet( rFont.GetCharSet() );
+            aSub[SW_LATIN].SvxFont::SetPropr( 100 );
+            aSub[SW_LATIN].aSize = aSub[SW_LATIN].Font::GetSize();
+            Size aTmpSize = aSub[SW_LATIN].aSize;
+            aTmpSize.Height() = pAttrSet->GetSize().GetHeight();
+            aSub[SW_LATIN].SetSize( aTmpSize );
+            aSub[SW_LATIN].Font::SetItalic( pAttrSet->GetPosture().GetPosture() );
+            aSub[SW_LATIN].Font::SetWeight( pAttrSet->GetWeight().GetWeight() );
+            aSub[SW_LATIN].SetLanguage( pAttrSet->GetLanguage().GetLanguage() );
+        }
+        {   // CJK
+            const SvxFontItem& rFont = pAttrSet->GetCJKFont();
+            aSub[SW_CJK].SetFamily( rFont.GetFamily() );
+            aSub[SW_CJK].Font::SetName( rFont.GetFamilyName() );
+            aSub[SW_CJK].Font::SetStyleName( rFont.GetStyleName() );
+            aSub[SW_CJK].Font::SetPitch( rFont.GetPitch() );
+            aSub[SW_CJK].Font::SetCharSet( rFont.GetCharSet() );
+            aSub[SW_CJK].SvxFont::SetPropr( 100 );
+            aSub[SW_CJK].aSize = aSub[SW_CJK].Font::GetSize();
+            Size aTmpSize = aSub[SW_CJK].aSize;
+            aTmpSize.Height() = pAttrSet->GetCJKSize().GetHeight();
+            aSub[SW_CJK].SetSize( aTmpSize );
+            aSub[SW_CJK].Font::SetItalic( pAttrSet->GetCJKPosture().GetPosture() );
+            aSub[SW_CJK].Font::SetWeight( pAttrSet->GetCJKWeight().GetWeight() );
+            aSub[SW_CJK].SetLanguage( pAttrSet->GetCJKLanguage().GetLanguage() );
+        }
+        {   // CTL
+            const SvxFontItem& rFont = pAttrSet->GetCTLFont();
+            aSub[SW_CTL].SetFamily( rFont.GetFamily() );
+            aSub[SW_CTL].Font::SetName( rFont.GetFamilyName() );
+            aSub[SW_CTL].Font::SetStyleName( rFont.GetStyleName() );
+            aSub[SW_CTL].Font::SetPitch( rFont.GetPitch() );
+            aSub[SW_CTL].Font::SetCharSet( rFont.GetCharSet() );
+            aSub[SW_CTL].SvxFont::SetPropr( 100 );
+            aSub[SW_CTL].aSize = aSub[SW_CTL].Font::GetSize();
+            Size aTmpSize = aSub[SW_CTL].aSize;
+            aTmpSize.Height() = pAttrSet->GetCTLSize().GetHeight();
+            aSub[SW_CTL].SetSize( aTmpSize );
+            aSub[SW_CTL].Font::SetItalic( pAttrSet->GetCTLPosture().GetPosture() );
+            aSub[SW_CTL].Font::SetWeight( pAttrSet->GetCTLWeight().GetWeight() );
+            aSub[SW_CTL].SetLanguage( pAttrSet->GetCTLLanguage().GetLanguage() );
+        }
+        SetUnderline( pAttrSet->GetUnderline().GetUnderline() );
+        SetStrikeout( pAttrSet->GetCrossedOut().GetStrikeout() );
+        SetColor( pAttrSet->GetColor().GetValue() );
+        SetTransparent( TRUE );
+        SetAlign( ALIGN_BASELINE );
+        SetOutline( pAttrSet->GetContour().GetValue() );
+        SetShadow( pAttrSet->GetShadowed().GetValue() );
+        SetAutoKern( pAttrSet->GetAutoKern().GetValue() );
+        SetWordLineMode( pAttrSet->GetWordLineMode().GetValue() );
+        const SvxEscapementItem &rEsc = pAttrSet->GetEscapement();
+        SetEscapement( rEsc.GetEsc() );
+        if( aSub[SW_LATIN].IsEsc() )
+            SetProportion( rEsc.GetProp() );
+        SetCaseMap( pAttrSet->GetCaseMap().GetCaseMap() );
+        SetFixKerning( pAttrSet->GetKerning().GetValue() );
+        bNoHyph = pAttrSet->GetNoHyphenHere().GetValue();
+        bBlink = pAttrSet->GetBlink().GetValue();
+    }
+    else
+    {
+        aSub[SW_LATIN].pMagic = aSub[SW_CJK].pMagic = aSub[SW_CTL].pMagic = 0;
+        Invalidate();
+        bNoHyph = FALSE;
+        bBlink = FALSE;
+    }
+    bPaintBlank = FALSE;
+    bPaintWrong = FALSE;
+    bURL = bGreyWave = bNoColReplace = FALSE;
+    ASSERT( aSub[SW_LATIN].IsTransparent(), "SwFont: Transparent revolution" );
+}
+
+/*************************************************************************
+ *                      SwFont::SetFnt()
+ *************************************************************************/
+
+void SwFont::SetDiffFnt( const SfxItemSet *pAttrSet )
+{
+    if( pAttrSet )
+    {
+        const SfxPoolItem* pItem;
+        if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_FONT,
+            TRUE, &pItem ))
+        {
+            const SvxFontItem *pFont = (const SvxFontItem *)pItem;
+            aSub[SW_LATIN].SetFamily( pFont->GetFamily() );
+            aSub[SW_LATIN].Font::SetName( pFont->GetFamilyName() );
+            aSub[SW_LATIN].Font::SetStyleName( pFont->GetStyleName() );
+            aSub[SW_LATIN].Font::SetPitch( pFont->GetPitch() );
+            aSub[SW_LATIN].Font::SetCharSet( pFont->GetCharSet() );
+        }
+        if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_FONTSIZE,
+            TRUE, &pItem ))
+        {
+            const SvxFontHeightItem *pHeight = (const SvxFontHeightItem *)pItem;
+            aSub[SW_LATIN].SvxFont::SetPropr( 100 );
+            aSub[SW_LATIN].aSize = aSub[SW_LATIN].Font::GetSize();
+            Size aTmpSize = aSub[SW_LATIN].aSize;
+            aTmpSize.Height() = pHeight->GetHeight();
+            aSub[SW_LATIN].SetSize( aTmpSize );
+        }
+        if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_POSTURE,
+            TRUE, &pItem ))
+            aSub[SW_LATIN].Font::SetItalic( ((SvxPostureItem*)pItem)->GetPosture() );
+        if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_WEIGHT,
+            TRUE, &pItem ))
+            aSub[SW_LATIN].Font::SetWeight( ((SvxWeightItem*)pItem)->GetWeight() );
+        if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_LANGUAGE,
+            TRUE, &pItem ))
+            aSub[SW_LATIN].SetLanguage( ((SvxLanguageItem*)pItem)->GetLanguage() );
+
+        if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CJK_FONT,
+            TRUE, &pItem ))
+        {
+            const SvxFontItem *pFont = (const SvxFontItem *)pItem;
+            aSub[SW_CJK].SetFamily( pFont->GetFamily() );
+            aSub[SW_CJK].Font::SetName( pFont->GetFamilyName() );
+            aSub[SW_CJK].Font::SetStyleName( pFont->GetStyleName() );
+            aSub[SW_CJK].Font::SetPitch( pFont->GetPitch() );
+            aSub[SW_CJK].Font::SetCharSet( pFont->GetCharSet() );
+        }
+        if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CJK_FONTSIZE,
+            TRUE, &pItem ))
+        {
+            const SvxFontHeightItem *pHeight = (const SvxFontHeightItem *)pItem;
+            aSub[SW_CJK].SvxFont::SetPropr( 100 );
+            aSub[SW_CJK].aSize = aSub[SW_CJK].Font::GetSize();
+            Size aTmpSize = aSub[SW_CJK].aSize;
+            aTmpSize.Height() = pHeight->GetHeight();
+            aSub[SW_CJK].SetSize( aTmpSize );
+        }
+        if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CJK_POSTURE,
+            TRUE, &pItem ))
+            aSub[SW_CJK].Font::SetItalic( ((SvxPostureItem*)pItem)->GetPosture() );
+        if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CJK_WEIGHT,
+            TRUE, &pItem ))
+            aSub[SW_CJK].Font::SetWeight( ((SvxWeightItem*)pItem)->GetWeight() );
+        if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CJK_LANGUAGE,
+            TRUE, &pItem ))
+            aSub[SW_CJK].SetLanguage( ((SvxLanguageItem*)pItem)->GetLanguage() );
+
+        if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CTL_FONT,
+            TRUE, &pItem ))
+        {
+            const SvxFontItem *pFont = (const SvxFontItem *)pItem;
+            aSub[SW_CTL].SetFamily( pFont->GetFamily() );
+            aSub[SW_CTL].Font::SetName( pFont->GetFamilyName() );
+            aSub[SW_CTL].Font::SetStyleName( pFont->GetStyleName() );
+            aSub[SW_CTL].Font::SetPitch( pFont->GetPitch() );
+            aSub[SW_CTL].Font::SetCharSet( pFont->GetCharSet() );
+        }
+        if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CTL_FONTSIZE,
+            TRUE, &pItem ))
+        {
+            const SvxFontHeightItem *pHeight = (const SvxFontHeightItem *)pItem;
+            aSub[SW_CTL].SvxFont::SetPropr( 100 );
+            aSub[SW_CTL].aSize = aSub[SW_CTL].Font::GetSize();
+            Size aTmpSize = aSub[SW_CTL].aSize;
+            aTmpSize.Height() = pHeight->GetHeight();
+            aSub[SW_CTL].SetSize( aTmpSize );
+        }
+        if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CTL_POSTURE,
+            TRUE, &pItem ))
+            aSub[SW_CTL].Font::SetItalic( ((SvxPostureItem*)pItem)->GetPosture() );
+        if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CTL_WEIGHT,
+            TRUE, &pItem ))
+            aSub[SW_CTL].Font::SetWeight( ((SvxWeightItem*)pItem)->GetWeight() );
+        if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CTL_LANGUAGE,
+            TRUE, &pItem ))
+            aSub[SW_CTL].SetLanguage( ((SvxLanguageItem*)pItem)->GetLanguage() );
+
+        if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_UNDERLINE,
+            TRUE, &pItem ))
+            SetUnderline( ((SvxUnderlineItem*)pItem)->GetUnderline() );
+        if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CROSSEDOUT,
+            TRUE, &pItem ))
+            SetStrikeout( ((SvxCrossedOutItem*)pItem)->GetStrikeout() );
+        if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_COLOR,
+            TRUE, &pItem ))
+            SetColor( ((SvxColorItem*)pItem)->GetValue() );
+        SetTransparent( TRUE );
+        SetAlign( ALIGN_BASELINE );
+        if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CONTOUR,
+            TRUE, &pItem ))
+            SetOutline( ((SvxContourItem*)pItem)->GetValue() );
+        if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_SHADOWED,
+            TRUE, &pItem ))
+            SetShadow( ((SvxShadowedItem*)pItem)->GetValue() );
+        if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_AUTOKERN,
+            TRUE, &pItem ))
+            SetAutoKern( ((SvxAutoKernItem*)pItem)->GetValue() );
+        if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_WORDLINEMODE,
+            TRUE, &pItem ))
+            SetWordLineMode( ((SvxWordLineModeItem*)pItem)->GetValue() );
+
+        if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_ESCAPEMENT,
+            TRUE, &pItem ))
+        {
+            const SvxEscapementItem *pEsc = (const SvxEscapementItem *)pItem;
+            SetEscapement( pEsc->GetEsc() );
+            if( aSub[SW_LATIN].IsEsc() )
+                SetProportion( pEsc->GetProp() );
+        }
+        if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CASEMAP,
+            TRUE, &pItem ))
+            SetCaseMap( ((SvxCaseMapItem*)pItem)->GetCaseMap() );
+        if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_KERNING,
+            TRUE, &pItem ))
+            SetFixKerning( ((SvxKerningItem*)pItem)->GetValue() );
+        if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_NOHYPHEN,
+            TRUE, &pItem ))
+            SetNoHyph( ((SvxNoHyphenItem*)pItem)->GetValue() );
+        if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_BLINK,
+            TRUE, &pItem ))
+            SetBlink( ((SvxBlinkItem*)pItem)->GetValue() );
+    }
+    else
+    {
+        Invalidate();
+        bNoHyph = FALSE;
+        bBlink = FALSE;
+    }
+    bPaintBlank = FALSE;
+    bPaintWrong = FALSE;
+    ASSERT( aSub[SW_LATIN].IsTransparent(), "SwFont: Transparent revolution" );
+}
+
+/*************************************************************************
+ *                      class SwFont
+ *************************************************************************/
+
+SwFont::SwFont( const SwFont &rFont )
+{
+    aSub[SW_LATIN] = rFont.aSub[SW_LATIN];
+    aSub[SW_CJK] = rFont.aSub[SW_CJK];
+    aSub[SW_CTL] = rFont.aSub[SW_CTL];
+    nActual = rFont.nActual;
+    pBackColor = rFont.pBackColor ? new Color( *rFont.pBackColor ) : NULL;
+    nToxCnt = nRefCnt = 0;
+    bFntChg = rFont.bFntChg;
+    bOrgChg = rFont.bOrgChg;
+    bPaintBlank = rFont.bPaintBlank;
+    bPaintWrong = FALSE;
+    bURL = rFont.bURL;
+    bGreyWave = rFont.bGreyWave;
+    bNoColReplace = rFont.bNoColReplace;
+    bNoHyph = rFont.bNoHyph;
+    bBlink = rFont.bBlink;
+}
+
+SwFont::SwFont( const SwAttrSet* pAttrSet )
+{
+    nActual = SW_LATIN;
+    nToxCnt = nRefCnt = 0;
+    bPaintBlank = FALSE;
+    bPaintWrong = FALSE;
+    bURL = FALSE;
+    bGreyWave = FALSE;
+    bNoColReplace = FALSE;
+    bNoHyph = pAttrSet->GetNoHyphenHere().GetValue();
+    bBlink = pAttrSet->GetBlink().GetValue();
+    {
+        const SvxFontItem& rFont = pAttrSet->GetFont();
+        aSub[SW_LATIN].SetFamily( rFont.GetFamily() );
+        aSub[SW_LATIN].SetName( rFont.GetFamilyName() );
+        aSub[SW_LATIN].SetStyleName( rFont.GetStyleName() );
+        aSub[SW_LATIN].SetPitch( rFont.GetPitch() );
+        aSub[SW_LATIN].SetCharSet( rFont.GetCharSet() );
+        aSub[SW_LATIN].SvxFont::SetPropr( 100 );   // 100% der FontSize
+        Size aTmpSize = aSub[SW_LATIN].aSize;
+        aTmpSize.Height() = pAttrSet->GetSize().GetHeight();
+        aSub[SW_LATIN].SetSize( aTmpSize );
+        aSub[SW_LATIN].SetItalic( pAttrSet->GetPosture().GetPosture() );
+        aSub[SW_LATIN].SetWeight( pAttrSet->GetWeight().GetWeight() );
+        aSub[SW_LATIN].SetLanguage( pAttrSet->GetLanguage().GetLanguage() );
+    }
+
+    {
+        const SvxFontItem& rFont = pAttrSet->GetCJKFont();
+        aSub[SW_CJK].SetFamily( rFont.GetFamily() );
+        aSub[SW_CJK].SetName( rFont.GetFamilyName() );
+        aSub[SW_CJK].SetStyleName( rFont.GetStyleName() );
+        aSub[SW_CJK].SetPitch( rFont.GetPitch() );
+        aSub[SW_CJK].SetCharSet( rFont.GetCharSet() );
+        aSub[SW_CJK].SvxFont::SetPropr( 100 );   // 100% der FontSize
+        Size aTmpSize = aSub[SW_CJK].aSize;
+        aTmpSize.Height() = pAttrSet->GetCJKSize().GetHeight();
+        aSub[SW_CJK].SetSize( aTmpSize );
+        aSub[SW_CJK].SetItalic( pAttrSet->GetCJKPosture().GetPosture() );
+        aSub[SW_CJK].SetWeight( pAttrSet->GetCJKWeight().GetWeight() );
+        aSub[SW_CJK].SetLanguage( pAttrSet->GetCJKLanguage().GetLanguage() );
+    }
+
+    {
+        const SvxFontItem& rFont = pAttrSet->GetCJKFont();
+        aSub[SW_CTL].SetFamily( rFont.GetFamily() );
+        aSub[SW_CTL].SetName( rFont.GetFamilyName() );
+        aSub[SW_CTL].SetStyleName( rFont.GetStyleName() );
+        aSub[SW_CTL].SetPitch( rFont.GetPitch() );
+        aSub[SW_CTL].SetCharSet( rFont.GetCharSet() );
+        aSub[SW_CTL].SvxFont::SetPropr( 100 );   // 100% der FontSize
+        Size aTmpSize = aSub[SW_CTL].aSize;
+        aTmpSize.Height() = pAttrSet->GetCJKSize().GetHeight();
+        aSub[SW_CTL].SetSize( aTmpSize );
+        aSub[SW_CTL].SetItalic( pAttrSet->GetCJKPosture().GetPosture() );
+        aSub[SW_CTL].SetWeight( pAttrSet->GetCJKWeight().GetWeight() );
+        aSub[SW_CTL].SetLanguage( pAttrSet->GetCJKLanguage().GetLanguage() );
+    }
+
+    SetUnderline( pAttrSet->GetUnderline().GetUnderline() );
+    SetStrikeout( pAttrSet->GetCrossedOut().GetStrikeout() );
+    SetColor( pAttrSet->GetColor().GetValue() );
+    SetTransparent( TRUE );
+    SetAlign( ALIGN_BASELINE );
+    SetOutline( pAttrSet->GetContour().GetValue() );
+    SetShadow( pAttrSet->GetShadowed().GetValue() );
+    SetAutoKern( pAttrSet->GetAutoKern().GetValue() );
+    SetWordLineMode( pAttrSet->GetWordLineMode().GetValue() );
+    const SvxEscapementItem &rEsc = pAttrSet->GetEscapement();
+    SetEscapement( rEsc.GetEsc() );
+    if( aSub[SW_LATIN].IsEsc() )
+        SetProportion( rEsc.GetProp() );
+    SetCaseMap( pAttrSet->GetCaseMap().GetCaseMap() );
+    SetFixKerning( pAttrSet->GetKerning().GetValue() );
+    const SfxPoolItem* pItem;
+    if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_BACKGROUND,
+        TRUE, &pItem ))
+        pBackColor = new Color( ((SvxBrushItem*)pItem)->GetColor() );
+    else
+        pBackColor = NULL;
+}
+
+SwSubFont& SwSubFont::operator=( const SwSubFont &rFont )
+{
+    SvxFont::operator=( rFont );
+    pMagic = rFont.pMagic;
+    nFntIndex = rFont.nFntIndex;
+    nOrgHeight = rFont.nOrgHeight;
+    nOrgAscent = rFont.nOrgAscent;
+    aSize = rFont.aSize;
+    return *this;
+}
+
+SwFont& SwFont::operator=( const SwFont &rFont )
+{
+    aSub[SW_LATIN] = rFont.aSub[SW_LATIN];
+    aSub[SW_CJK] = rFont.aSub[SW_CJK];
+    aSub[SW_CTL] = rFont.aSub[SW_CTL];
+    nActual = rFont.nActual;
+    delete pBackColor;
+    pBackColor = rFont.pBackColor ? new Color( *rFont.pBackColor ) : NULL;
+    nToxCnt = nRefCnt = 0;
+    bFntChg = rFont.bFntChg;
+    bOrgChg = rFont.bOrgChg;
+    bPaintBlank = rFont.bPaintBlank;
+    bPaintWrong = FALSE;
+    bURL = rFont.bURL;
+    bGreyWave = rFont.bGreyWave;
+    bNoColReplace = rFont.bNoColReplace;
+    bNoHyph = rFont.bNoHyph;
+    bBlink = rFont.bBlink;
+    return *this;
+}
+
+/*************************************************************************
+ *                      SwFont::GoMagic()
+ *************************************************************************/
+
+void SwFont::GoMagic( ViewShell *pSh, BYTE nWhich )
+{
+    SwFntAccess aFntAccess( aSub[nWhich].pMagic, aSub[nWhich].nFntIndex,
+                            &aSub[nWhich], pSh, TRUE );
+}
+
+/*************************************************************************
+ *                      SwSubFont::IsSymbol()
+ *************************************************************************/
+
+BOOL SwSubFont::IsSymbol( ViewShell *pSh )
+{
+    SwFntAccess aFntAccess( pMagic, nFntIndex, this, pSh, FALSE );
+    return aFntAccess.Get()->IsSymbol();
+}
+
+/*************************************************************************
+ *                      SwFont::SetSystemLang()
+ *************************************************************************/
+
+LanguageType GetSystemLang( )
+{
+    // Hier wird bei LANGUAGE_SYSTEM die Sprache ermittelt.
+    // 1.Versuch: Was sagt die Applikation?
+    LanguageType eTmp = GetpApp()->GetAppInternational().GetLanguage();
+    if ( ( eTmp == LANGUAGE_SYSTEM ) &&
+        // Was sagt die Systemumgebung?
+         ( (eTmp = ::GetSystemLanguage()) == LANGUAGE_SYSTEM ) )
+        eTmp = LANGUAGE_DONTKNOW; // also unbekannt
+    return eTmp;
+}
+
+/*************************************************************************
+ *                      SwSubFont::ChgFnt()
+ *************************************************************************/
+
+BOOL SwSubFont::ChgFnt( ViewShell *pSh, OutputDevice *pOut )
+{
+    if ( pLastFont )
+        pLastFont->Unlock();
+    SwFntAccess aFntAccess( pMagic, nFntIndex, this, pSh, TRUE );
+    SV_STAT( nChangeFont );
+
+    pLastFont = aFntAccess.Get();
+
+    pLastFont->SetDevFont( pSh, pOut );
+
+    pLastFont->Lock();
+    return UNDERLINE_NONE != GetUnderline() || STRIKEOUT_NONE != GetStrikeout();
+}
+
+/*************************************************************************
+ *                    SwFont::ChgPhysFnt()
+ *************************************************************************/
+
+void SwFont::ChgPhysFnt( ViewShell *pSh, OutputDevice *pOut )
+{
+    ASSERT( pOut, "SwFont:;ChgPhysFnt, not OutDev." );
+
+    if( bOrgChg && aSub[nActual].IsEsc() )
+    {
+        const BYTE nOldProp = aSub[nActual].GetPropr();
+        SetProportion( 100 );
+        ChgFnt( pSh, pOut );
+        SwFntAccess aFntAccess( aSub[nActual].pMagic, aSub[nActual].nFntIndex,
+                                &aSub[nActual], pSh );
+        aSub[nActual].nOrgHeight = aFntAccess.Get()->GetHeight( pSh, pOut );
+        aSub[nActual].nOrgAscent = aFntAccess.Get()->GetAscent( pSh, pOut );
+        SetProportion( nOldProp );
+        bOrgChg = FALSE;
+    }
+
+    if( bFntChg )
+    {
+        ChgFnt( pSh, pOut );
+        bFntChg = bOrgChg;
+    }
+}
+
+/*************************************************************************
+ *                      SwFont::CalcEscHeight()
+ *         Height = MaxAscent + MaxDescent
+ *      MaxAscent = Max (T1_ascent, T2_ascent + (Esc * T1_height) );
+ *     MaxDescent = Max (T1_height-T1_ascent,
+ *                       T2_height-T2_ascent - (Esc * T1_height)
+ *************************************************************************/
+
+USHORT SwSubFont::CalcEscHeight( const USHORT nOldHeight,
+                              const USHORT nOldAscent  ) const
+{
+    if( DFLT_ESC_AUTO_SUPER != GetEscapement() &&
+        DFLT_ESC_AUTO_SUB != GetEscapement() )
+    {
+        long nDescent = nOldHeight - nOldAscent -
+                             ( (long) nOrgHeight * GetEscapement() ) / 100L;
+        const USHORT nDesc = ( nDescent>0 ) ? Max ( USHORT(nDescent),
+                   USHORT(nOrgHeight - nOrgAscent) ) : nOrgHeight - nOrgAscent;
+        return ( nDesc + CalcEscAscent( nOldAscent ) );
+    }
+    return nOrgHeight;
+}
+
+short SwSubFont::_CheckKerning( )
+{
+#ifdef DEBUG
+    static nTst = 6;
+    short nKernx = - short( Font::GetSize().Height() / nTst );
+#else
+    short nKernx = - short( Font::GetSize().Height() / 6 );
+#endif
+    if ( nKernx < GetFixKerning() )
+        return GetFixKerning();
+    return nKernx;
+}
+
+/*************************************************************************
+ *                    SwFont::GetLeading()
+ *************************************************************************/
+
+USHORT SwFont::GetLeading( ViewShell *pSh, const OutputDevice *pOut )
+{
+    if( OUTDEV_PRINTER != pOut->GetOutDevType() )
+        return 0;
+    else
+    {
+        SwFntAccess aFntAccess( aSub[nActual].pMagic, aSub[nActual].nFntIndex,
+                                &aSub[nActual], pSh );
+        return aFntAccess.Get()->GetLeading();
+    }
+}
+
+/*************************************************************************
+ *                    SwSubFont::GetAscent()
+ *************************************************************************/
+
+USHORT SwSubFont::GetAscent( ViewShell *pSh, const OutputDevice *pOut )
+{
+    register USHORT nAscent;
+    SwFntAccess aFntAccess( pMagic, nFntIndex, this, pSh );
+    nAscent = aFntAccess.Get()->GetAscent( pSh, pOut );
+    if( GetEscapement() )
+        nAscent = CalcEscAscent( nAscent );
+    return nAscent;
+}
+
+/*************************************************************************
+ *                    SwSubFont::GetHeight()
+ *************************************************************************/
+
+USHORT SwSubFont::GetHeight( ViewShell *pSh, const OutputDevice *pOut )
+{
+    SV_STAT( nGetTextSize );
+    SwFntAccess aFntAccess( pMagic, nFntIndex, this, pSh );
+    const USHORT nHeight = aFntAccess.Get()->GetHeight( pSh, pOut );
+    if ( GetEscapement() )
+    {
+        const USHORT nAscent = aFntAccess.Get()->GetAscent( pSh, pOut );
+        return CalcEscHeight( nHeight, nAscent ); // + nLeading;
+    }
+    return nHeight; // + nLeading;
+}
+
+/*************************************************************************
+ *                    SwSubFont::_GetTxtSize()
+ *************************************************************************/
+
+Size SwSubFont::_GetTxtSize( ViewShell *pSh,
+                         const OutputDevice *pOut, const XubString &rTxt,
+                         const xub_StrLen nIdx, const xub_StrLen nLen )
+{
+    // Robust: Eigentlich sollte der Font bereits eingestellt sein, aber
+    // sicher ist sicher ...
+    if ( !pLastFont || pLastFont->GetOwner()!=pMagic ||
+         !IsSameInstance( pOut->GetFont() ) )
+        ChgFnt( pSh, (OutputDevice *)pOut );
+
+    Size aTxtSize;
+    xub_StrLen nLn = ( nLen==STRING_LEN ? rTxt.Len() : nLen );
+    if( IsCapital() && nLn )
+        aTxtSize = GetCapitalSize( pSh, pOut, rTxt, nIdx, nLn );
+    else
+    {
+        SV_STAT( nGetTextSize );
+        if ( !IsCaseMap() )
+            aTxtSize = pLastFont->GetTextSize( pSh, pOut, rTxt,
+                                               nIdx, nLn, CheckKerning() );
+        else
+            aTxtSize = pLastFont->GetTextSize( pSh, pOut, CalcCaseMap( rTxt ),
+                                               nIdx, nLn, CheckKerning() );
+        // 15142: Ein Wort laenger als eine Zeile, beim Zeilenumbruch
+        //        hochgestellt, muss seine effektive Hoehe melden.
+        if( GetEscapement() )
+        {
+            const USHORT nAscent = pLastFont->GetAscent( pSh, pOut );
+            aTxtSize.Height() =
+                (long)CalcEscHeight( (USHORT)aTxtSize.Height(), nAscent);
+        }
+    }
+    return aTxtSize;
+}
+
+/*************************************************************************
+ *                    SwFont::GetTxtBreak()
+ *************************************************************************/
+
+xub_StrLen SwFont::GetTxtBreak( ViewShell *pSh, const OutputDevice *pOut,
+    const XubString &rTxt, long nTextWidth,
+    const xub_StrLen nIdx, const xub_StrLen nLen )
+{
+     ChgFnt( pSh, (OutputDevice *)pOut );
+
+    USHORT nTxtBreak = 0;
+
+    USHORT nLn = ( nLen == STRING_LEN ? rTxt.Len() : nLen );
+    if( aSub[nActual].IsCapital() && nLn )
+        nTxtBreak = GetCapitalBreak( pSh, pOut, rTxt, nTextWidth, 0, nIdx, nLn );
+    else
+    {
+        if ( !aSub[nActual].IsCaseMap() )
+            nTxtBreak = pOut->GetTextBreak( rTxt, nTextWidth,
+                                               nIdx, nLn, CheckKerning() );
+        else
+            nTxtBreak = pOut->GetTextBreak( aSub[nActual].CalcCaseMap( rTxt ),
+                        nTextWidth, nIdx, nLn, CheckKerning() );
+    }
+    return nTxtBreak;
+}
+
+/*************************************************************************
+ *                    SwFont::GetTxtBreak()
+ *************************************************************************/
+
+xub_StrLen SwFont::GetTxtBreak( ViewShell *pSh,
+   const OutputDevice *pOut, const XubString &rTxt, long nTextWidth,
+   xub_StrLen& rExtraCharPos, const xub_StrLen nIdx, const xub_StrLen nLen)
+{
+    // Robust ...
+    if ( !pLastFont || pLastFont->GetOwner()!= aSub[nActual].pMagic )
+        ChgFnt( pSh, (OutputDevice *)pOut );
+
+    xub_StrLen nTxtBreak = 0;
+
+    xub_StrLen nLn = ( nLen == STRING_LEN ? rTxt.Len() : nLen );
+    if( aSub[nActual].IsCapital() && nLn )
+            nTxtBreak = GetCapitalBreak( pSh, pOut, rTxt, nTextWidth,
+                                &rExtraCharPos, nIdx, nLn );
+    else
+    {
+        if ( !aSub[nActual].IsCaseMap() )
+            nTxtBreak = pOut->GetTextBreak( rTxt, nTextWidth,
+                            '-', rExtraCharPos, nIdx, nLn, CheckKerning() );
+        else
+            nTxtBreak = pOut->GetTextBreak( aSub[nActual].CalcCaseMap( rTxt ),
+                nTextWidth, '-', rExtraCharPos, nIdx, nLn, CheckKerning() );
+    }
+    return nTxtBreak;
+}
+
+/*************************************************************************
+ *                    SwSubFont::_DrawText()
+ *************************************************************************/
+
+void SwSubFont::_DrawText( SwDrawTextInfo &rInf, const BOOL bGrey )
+{
+    rInf.SetGreyWave( bGrey );
+    xub_StrLen nLn = rInf.GetText().Len();
+    if( !rInf.GetLen() || !nLn )
+        return;
+    if( STRING_LEN == rInf.GetLen() )
+        rInf.SetLen( nLn );
+
+    FontUnderline nOldUnder;
+
+    if( rInf.GetSpecialUnderline() )
+    {
+        nOldUnder = GetUnderline();
+        SetUnderline( UNDERLINE_NONE );
+    }
+
+    if( !pLastFont || pLastFont->GetOwner()!=pMagic )
+        ChgFnt( rInf.GetShell(), rInf.GetpOut() );
+
+    Point aPos( rInf.GetPos() );
+    const Point &rOld = rInf.GetPos();
+    rInf.SetPos( aPos );
+
+    if( GetEscapement() )
+    {
+        if( DFLT_ESC_AUTO_SUB == GetEscapement() )
+            aPos.Y() += nOrgHeight - nOrgAscent -
+                    pLastFont->GetHeight( rInf.GetShell(), rInf.GetpOut() ) +
+                    pLastFont->GetAscent( rInf.GetShell(), rInf.GetpOut() );
+        else if( DFLT_ESC_AUTO_SUPER == GetEscapement() )
+        {
+            aPos.Y() += pLastFont->GetAscent( rInf.GetShell(), rInf.GetpOut() );
+            aPos.Y() -= nOrgAscent;
+        }
+        else
+            aPos.Y() -= short( ((long)nOrgHeight * GetEscapement()) / 100L );
+    }
+    rInf.SetKern( CheckKerning() + rInf.GetSperren() );
+
+    if( IsCapital() )
+        DrawCapital( rInf );
+    else
+    {
+        SV_STAT( nDrawText );
+        if ( !IsCaseMap() )
+            pLastFont->DrawText( rInf );
+        else
+        {
+            XubString aString( CalcCaseMap( rInf.GetText() ) );
+            const XubString &rOldStr = rInf.GetText();
+            rInf.SetText( aString );
+            pLastFont->DrawText( rInf );
+            rInf.SetText( rOldStr );
+        }
+    }
+    rInf.SetPos( rOld );
+
+    if( rInf.GetSpecialUnderline() )
+    {
+static sal_Char __READONLY_DATA sDoubleSpace[] = "  ";
+        Size aSize = _GetTxtSize( rInf.GetShell(), rInf.GetpOut(), rInf.GetText(),
+                                  rInf.GetIdx(), rInf.GetLen() );
+        const XubString &rOldStr = rInf.GetText();
+        XubString aStr( sDoubleSpace, RTL_TEXTENCODING_MS_1252 );
+        short nOldEsc = GetEscapement();
+        BYTE nOldProp = GetPropr();
+        BOOL bOldWord = IsWordLineMode();
+        SetWordLineMode( FALSE );
+        xub_StrLen nOldIdx = rInf.GetIdx();
+        xub_StrLen nOldLen = rInf.GetLen();
+        long nSpace = 0;
+        if( rInf.GetSpace() )
+        {
+            xub_StrLen nTmpEnd = nOldIdx + nOldLen;
+            if( nTmpEnd > rOldStr.Len() )
+                nTmpEnd = rOldStr.Len();
+            for( xub_StrLen nTmp = nOldIdx; nTmp < nTmpEnd; ++nTmp )
+                if( CH_BLANK == rOldStr.GetChar( nTmp ) )
+                    ++nSpace;
+            nSpace *= rInf.GetSpace();
+        }
+        rInf.SetText( aStr );
+        rInf.SetIdx( 0 );
+        rInf.SetLen( 2 );
+        SetProportion( 100 );
+        SetEscapement( 0 );
+        SetUnderline( nOldUnder );
+        rInf.SetWidth( USHORT(aSize.Width() + nSpace) );
+        rInf.SetSpecialUnderline( FALSE );
+        _DrawStretchText( rInf );
+        rInf.SetSpecialUnderline( TRUE );
+        rInf.SetText( rOldStr );
+        SetProportion( nOldProp );
+        SetEscapement( nOldEsc );
+        rInf.SetIdx( nOldIdx );
+        rInf.SetLen( nOldLen );
+        SetWordLineMode( bOldWord );
+    }
+}
+
+void SwSubFont::_DrawStretchText( SwDrawTextInfo &rInf )
+{
+    if( !rInf.GetLen() || !rInf.GetText().Len() )
+        return;
+
+    FontUnderline nOldUnder;
+
+    if( rInf.GetSpecialUnderline() )
+    {
+        nOldUnder = GetUnderline();
+        SetUnderline( UNDERLINE_NONE );
+    }
+
+    if ( !pLastFont || pLastFont->GetOwner() != pMagic )
+        ChgFnt( rInf.GetShell(), rInf.GetpOut() );
+
+    Point aPos( rInf.GetPos() );
+
+    if( GetEscapement() )
+    {
+        if( DFLT_ESC_AUTO_SUB == GetEscapement() )
+            aPos.Y() += nOrgHeight - nOrgAscent -
+                    pLastFont->GetHeight( rInf.GetShell(), rInf.GetpOut() ) +
+                    pLastFont->GetAscent( rInf.GetShell(), rInf.GetpOut() );
+        else if( DFLT_ESC_AUTO_SUPER == GetEscapement() )
+            aPos.Y() += pLastFont->GetAscent( rInf.GetShell(), rInf.GetpOut())-
+                        nOrgAscent;
+        else
+            aPos.Y() -= short( ((long)nOrgHeight * GetEscapement()) / 100L );
+    }
+    rInf.SetKern( CheckKerning() + rInf.GetSperren() );
+
+    if( IsCapital() )
+    {
+        const Point &rOld = rInf.GetPos();
+        rInf.SetPos( aPos );
+        DrawStretchCapital( rInf );
+        rInf.SetPos( rOld );
+    }
+    else
+    {
+        SV_STAT( nDrawStretchText );
+        if ( !IsCaseMap() )
+            rInf.GetOut().DrawStretchText( aPos, rInf.GetWidth(),
+                            rInf.GetText(), rInf.GetIdx(), rInf.GetLen() );
+        else
+            rInf.GetOut().DrawStretchText( aPos, rInf.GetWidth(), CalcCaseMap(
+                            rInf.GetText() ), rInf.GetIdx(), rInf.GetLen() );
+    }
+
+    if( rInf.GetSpecialUnderline() )
+    {
+static sal_Char __READONLY_DATA sDoubleSpace[] = "  ";
+        const XubString &rOldStr = rInf.GetText();
+        XubString aStr( sDoubleSpace, RTL_TEXTENCODING_MS_1252 );
+        short nOldEsc = GetEscapement();
+        BYTE nOldProp = GetPropr();
+        BOOL bOldWord = IsWordLineMode();
+        SetWordLineMode( FALSE );
+        xub_StrLen nOldIdx = rInf.GetIdx();
+        xub_StrLen nOldLen = rInf.GetLen();
+        rInf.SetText( aStr );
+        rInf.SetIdx( 0 );
+        rInf.SetLen( 2 );
+        SetProportion( 100 );
+        SetEscapement( 0 );
+        SetUnderline( nOldUnder );
+        rInf.SetSpecialUnderline( FALSE );
+        _DrawStretchText( rInf );
+        rInf.SetSpecialUnderline( TRUE );
+        rInf.SetText( rOldStr );
+        SetProportion( nOldProp );
+        SetEscapement( nOldEsc );
+        rInf.SetIdx( nOldIdx );
+        rInf.SetLen( nOldLen );
+        SetWordLineMode( bOldWord );
+    }
+}
+
+/*************************************************************************
+ *                    SwSubFont::_GetCrsrOfst()
+ *************************************************************************/
+
+xub_StrLen SwSubFont::_GetCrsrOfst( ViewShell *pSh,
+                             OutputDevice *pOut, const XubString &rTxt,
+                             const USHORT nOfst, const xub_StrLen nIdx,
+                             const xub_StrLen nLen, const short nSpaceAdd )
+{
+    if ( !pLastFont || pLastFont->GetOwner()!=pMagic )
+        ChgFnt( pSh, pOut );
+
+    xub_StrLen nLn = ( nLen==STRING_LEN ? rTxt.Len() : nLen );
+    xub_StrLen nCrsr = 0;
+    if( IsCapital() && nLn )
+        nCrsr = GetCapitalCrsrOfst( pSh, pOut, rTxt, nOfst, nIdx, nLn, nSpaceAdd );
+    else
+    {
+        SV_STAT( nGetTextSize );
+        if ( !IsCaseMap() )
+            nCrsr = pLastFont->GetCrsrOfst( pOut, rTxt, nOfst,
+                                      nIdx, nLn, CheckKerning(), nSpaceAdd );
+        else
+            nCrsr = pLastFont->GetCrsrOfst( pOut, CalcCaseMap( rTxt ), nOfst,
+                                      nIdx, nLn, CheckKerning(), nSpaceAdd );
+    }
+    return nCrsr;
+}
+
diff --git a/sw/source/core/txtnode/thints.cxx b/sw/source/core/txtnode/thints.cxx
new file mode 100644
index 000000000000..6cb182eff8c8
--- /dev/null
+++ b/sw/source/core/txtnode/thints.cxx
@@ -0,0 +1,2138 @@
+/*************************************************************************
+ *
+ *  $RCSfile: thints.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:27 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _SOT_FACTORY_HXX
+#include 
+#endif
+
+#ifndef _XMLOFF_XMLCNITM_HXX
+#include 
+#endif
+
+#ifndef _SFX_WHITER_HXX //autogen
+#include 
+#endif
+#ifndef _SFXITEMITER_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_FONTITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_LANGITEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _TXTINET_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFLCNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _FMTINFMT_HXX //autogen
+#include 
+#endif
+#ifndef _TXTATR_HXX //autogen
+#include 
+#endif
+#ifndef _FCHRFMT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFLCNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFTN_HXX //autogen
+#include 
+#endif
+#ifndef _TXTTXMRK_HXX //autogen
+#include 
+#endif
+#ifndef _TXTRFMRK_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFTN_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _CHARATR_HXX
+#include 
+#endif
+#ifndef _CHARFMT_HXX //autogen
+#include 
+#endif
+#ifndef _FRMFMT_HXX //autogen
+#include 
+#endif
+#ifndef _FTNIDX_HXX //autogen
+#include 
+#endif
+
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _ERRHDL_HXX
+#include 
+#endif
+#ifndef _FLDBAS_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _TXTFRM_HXX
+#include 
+#endif
+#ifndef _CALBCK_HXX
+#include 
+#endif
+#ifndef _HINTS_HXX
+#include             // fuer SwFmtChg
+#endif
+#ifndef _ROLBCK_HXX
+#include            // fuer SwRegHistory
+#endif
+#ifndef _DDEFLD_HXX
+#include 
+#endif
+#ifndef _DOCUFLD_HXX
+#include 
+#endif
+#ifndef _EXPFLD_HXX
+#include 
+#endif
+#ifndef _USRFLD_HXX
+#include 
+#endif
+#ifndef _POOLFMT_HXX
+#include 
+#endif
+
+
+#ifndef PRODUCT
+#define CHECK    Check();
+#else
+#define CHECK
+#endif
+
+
+/*************************************************************************
+ *                      SwTxtNode::MakeTxtAttr()
+ *************************************************************************/
+
+    // lege ein neues TextAttribut an und fuege es SwpHints-Array ein
+SwTxtAttr* SwTxtNode::MakeTxtAttr( const SfxPoolItem& rAttr,
+                                   xub_StrLen nStt, xub_StrLen nEnd, BOOL bPool )
+{
+    // das neue Attribut im Pool anlegen
+    const SfxPoolItem& rNew = bPool ? GetDoc()->GetAttrPool().Put( rAttr ) :
+                              rAttr;
+
+    SwTxtAttr* pNew = 0;
+    switch( rNew.Which() )
+    {
+    case RES_CHRATR_CASEMAP:
+        pNew = new SwTxtCaseMap( (SvxCaseMapItem&)rNew, nStt, nEnd );
+        break;
+    case RES_CHRATR_COLOR:
+        pNew = new SwTxtColor( (SvxColorItem&)rNew, nStt, nEnd );
+        break;
+    case RES_CHRATR_CHARSETCOLOR:
+        pNew = new SwTxtCharSetColor( (SvxCharSetColorItem&)rNew, nStt, nEnd );
+        break;
+    case RES_CHRATR_CONTOUR:
+        pNew = new SwTxtContour( (SvxContourItem&)rNew, nStt, nEnd );
+        break;
+    case RES_CHRATR_CROSSEDOUT:
+        pNew = new SwTxtCrossedOut( (SvxCrossedOutItem&)rNew, nStt, nEnd );
+        break;
+    case RES_CHRATR_ESCAPEMENT:
+        pNew = new SwTxtEscapement( (SvxEscapementItem&)rNew, nStt, nEnd );
+        break;
+    case RES_CHRATR_FONT:
+        pNew = new SwTxtFont( (SvxFontItem&)rNew, nStt, nEnd );
+        break;
+    case RES_CHRATR_FONTSIZE:
+        pNew = new SwTxtSize( (SvxFontHeightItem&)rNew, nStt, nEnd );
+        break;
+    case RES_CHRATR_KERNING:
+        pNew = new SwTxtKerning( (SvxKerningItem&)rNew, nStt, nEnd );
+        break;
+    case RES_CHRATR_LANGUAGE:
+        pNew = new SwTxtLanguage( (SvxLanguageItem&)rNew, nStt, nEnd );
+        break;
+    case RES_CHRATR_POSTURE:
+        pNew = new SwTxtPosture( (SvxPostureItem&)rNew, nStt, nEnd );
+        break;
+    case RES_CHRATR_SHADOWED:
+        pNew = new SwTxtShadowed( (SvxShadowedItem&)rNew, nStt, nEnd );
+        break;
+    case RES_CHRATR_AUTOKERN:
+        pNew = new SwTxtAutoKern( (SvxAutoKernItem&)rNew, nStt, nEnd );
+        break;
+    case RES_CHRATR_WORDLINEMODE:
+        pNew = new SwTxtWordLineMode( (SvxWordLineModeItem&)rNew, nStt, nEnd );
+        break;
+    case RES_CHRATR_UNDERLINE:
+        pNew = new SwTxtUnderline( (SvxUnderlineItem&)rNew, nStt, nEnd );
+        break;
+    case RES_CHRATR_WEIGHT:
+        pNew = new SwTxtWeight( (SvxWeightItem&)rNew, nStt, nEnd );
+        break;
+    case RES_TXTATR_CHARFMT:
+        {
+            SwFmtCharFmt &rFmtCharFmt = (SwFmtCharFmt&) rNew;
+            if( !rFmtCharFmt.GetCharFmt() )
+                rFmtCharFmt.SetCharFmt( GetDoc()->GetDfltCharFmt() );
+
+            pNew = new SwTxtCharFmt( rFmtCharFmt, nStt, nEnd );
+        }
+        break;
+    case RES_TXTATR_INETFMT:
+        pNew = new SwTxtINetFmt( (SwFmtINetFmt&)rNew, nStt, nEnd );
+        break;
+    case RES_TXTATR_FIELD:
+        pNew = new SwTxtFld( (SwFmtFld&)rNew, nStt );
+        break;
+    case RES_TXTATR_FLYCNT:
+        {
+            // erst hier wird das Frame-Format kopiert (mit Inhalt) !!
+            pNew = new SwTxtFlyCnt( (SwFmtFlyCnt&)rNew, nStt );
+            // Kopie von einem Text-Attribut
+            if( ((SwFmtFlyCnt&)rAttr).GetTxtFlyCnt() )
+                // dann muss das Format Kopiert werden
+                ((SwTxtFlyCnt*)pNew)->CopyFlyFmt( GetDoc() );
+        }
+        break;
+    case RES_TXTATR_FTN:
+        pNew = new SwTxtFtn( (SwFmtFtn&)rNew, nStt );
+        // ggfs. SeqNo kopieren
+        if( ((SwFmtFtn&)rAttr).GetTxtFtn() )
+            ((SwTxtFtn*)pNew)->SetSeqNo( ((SwFmtFtn&)rAttr).GetTxtFtn()->GetSeqRefNo() );
+        break;
+    case RES_TXTATR_HARDBLANK:
+        pNew = new SwTxtHardBlank( (SwFmtHardBlank&)rNew, nStt );
+        break;
+    case RES_CHRATR_NOHYPHEN:
+        pNew = new SwTxtNoHyphenHere( (SvxNoHyphenItem&)rNew, nStt, nEnd );
+        break;
+    case RES_CHRATR_BLINK:
+        pNew = new SwTxtBlink( (SvxBlinkItem&)rNew, nStt, nEnd );
+        break;
+    case RES_CHRATR_BACKGROUND:
+        pNew = new SwTxtBackground( (SvxBrushItem&)rNew, nStt, nEnd );
+        break;
+    case RES_TXTATR_REFMARK:
+        pNew = nStt == nEnd
+                ? new SwTxtRefMark( (SwFmtRefMark&)rNew, nStt )
+                : new SwTxtRefMark( (SwFmtRefMark&)rNew, nStt, &nEnd );
+        break;
+    case RES_TXTATR_TOXMARK:
+        pNew = new SwTxtTOXMark( (SwTOXMark&)rNew, nStt, &nEnd );
+        break;
+    case RES_UNKNOWNATR_CONTAINER:
+        pNew = new SwTxtXMLAttrContainer( (SvXMLAttrContainerItem&)rNew,
+                                        nStt, nEnd );
+        break;
+    }
+    ASSERT( pNew, "was fuer ein TextAttribut soll hier angelegt werden?" );
+    return pNew;
+}
+
+// loesche das Text-Attribut (muss beim Pool abgemeldet werden!)
+void SwTxtNode::DestroyAttr( SwTxtAttr* pAttr )
+{
+    if( pAttr )
+    {
+        // einige Sachen muessen vorm Loeschen der "Format-Attribute" erfolgen
+        SwDoc* pDoc = GetDoc();
+        switch( pAttr->Which() )
+        {
+        case RES_TXTATR_FLYCNT:
+            {
+                // siehe auch die Anmerkung "Loeschen von Formaten
+                // zeichengebundener Frames" in fesh.cxx, SwFEShell::DelFmt()
+                SwFrmFmt* pFmt = pAttr->GetFlyCnt().GetFrmFmt();
+                if( pFmt )      // vom Undo auf 0 gesetzt ??
+                    pDoc->DelLayoutFmt( (SwFlyFrmFmt*)pFmt );
+            }
+            break;
+
+        case RES_TXTATR_FTN:
+            ((SwTxtFtn*)pAttr)->SetStartNode( 0 );
+            break;
+
+        case RES_TXTATR_FIELD:
+            if( !pDoc->IsInDtor() )
+            {
+                // Wenn wir ein HiddenParaField sind, dann muessen wir
+                // ggf. fuer eine Neuberechnung des Visible-Flags sorgen.
+                const SwField* pFld = pAttr->GetFld().GetFld();
+
+                //JP 06-08-95: DDE-Felder bilden eine Ausnahme
+                ASSERT( RES_DDEFLD == pFld->GetTyp()->Which() ||
+                        this == ((SwTxtFld*)pAttr)->GetpTxtNode(),
+                        "Wo steht denn dieses Feld?" )
+
+                // bestimmte Felder mussen am Doc das Calculations-Flag updaten
+                switch( pFld->GetTyp()->Which() )
+                {
+                case RES_HIDDENPARAFLD:
+                    SetCalcVisible();
+                    // kein break !
+                case RES_DBSETNUMBERFLD:
+                case RES_GETEXPFLD:
+                case RES_DBFLD:
+                case RES_SETEXPFLD:
+                case RES_HIDDENTXTFLD:
+                case RES_DBNUMSETFLD:
+                case RES_DBNEXTSETFLD:
+                    if( !pDoc->IsNewFldLst() && GetNodes().IsDocNodes() )
+                        pDoc->InsDelFldInFldLst( FALSE, *(SwTxtFld*)pAttr );
+                    break;
+                case RES_DDEFLD:
+                    if( GetNodes().IsDocNodes() &&
+                        ((SwTxtFld*)pAttr)->GetpTxtNode() )
+                        ((SwDDEFieldType*)pFld->GetTyp())->DecRefCnt();
+                    break;
+                }
+            }
+            break;
+
+        }
+        pAttr->RemoveFromPool( pDoc->GetAttrPool() );
+        delete pAttr;
+    }
+}
+
+/*************************************************************************
+ *                      SwTxtNode::Insert()
+ *************************************************************************/
+
+// lege ein neues TextAttribut an und fuege es ins SwpHints-Array ein
+SwTxtAttr* SwTxtNode::Insert( const SfxPoolItem& rAttr,
+                              xub_StrLen nStt, xub_StrLen nEnd, USHORT nMode )
+{
+    SwTxtAttr* pNew = MakeTxtAttr( rAttr, nStt, nEnd );
+    return (pNew && Insert( pNew, nMode )) ? pNew : 0;
+}
+
+
+// uebernehme den Pointer auf das Text-Attribut
+
+BOOL SwTxtNode::Insert( SwTxtAttr *pAttr, USHORT nMode )
+{
+    BOOL bHiddenPara = FALSE;
+
+    ASSERT( *pAttr->GetStart() <= Len(), "StartIdx hinter Len!" );
+
+    if( !pAttr->GetEnd() )
+    {
+        USHORT nInsMode = nMode;
+        switch( pAttr->Which() )
+        {
+            case RES_TXTATR_FLYCNT:
+            {
+                SwTxtFlyCnt *pFly = (SwTxtFlyCnt *)pAttr;
+                SwFrmFmt* pFmt = pAttr->GetFlyCnt().GetFrmFmt();
+                if( !(SETATTR_NOTXTATRCHR & nInsMode) )
+                {
+                    // Wir muessen zuerst einfuegen, da in SetAnchor()
+                    // dem FlyFrm GetStart() uebermittelt wird.
+                    //JP 11.05.98: falls das Anker-Attribut schon richtig
+                    // gesetzt ist, dann korrigiere dieses nach dem Einfuegen
+                    // des Zeichens. Sonst muesste das immer  ausserhalb
+                    // erfolgen (Fehleranfaellig !)
+                    const SwFmtAnchor* pAnchor = 0;
+                    pFmt->GetItemState( RES_ANCHOR, FALSE,
+                                            (const SfxPoolItem**)&pAnchor );
+
+                    SwIndex aIdx( this, *pAttr->GetStart() );
+                    Insert( GetCharOfTxtAttr(*pAttr), aIdx );
+                    nInsMode |= SETATTR_NOTXTATRCHR;
+
+                    if( pAnchor && FLY_IN_CNTNT == pAnchor->GetAnchorId() &&
+                        pAnchor->GetCntntAnchor() &&
+                        pAnchor->GetCntntAnchor()->nNode == *this &&
+                        pAnchor->GetCntntAnchor()->nContent == aIdx )
+                        ((SwIndex&)pAnchor->GetCntntAnchor()->nContent)--;
+                }
+                pFly->SetAnchor( this );
+
+                // Format-Pointer kann sich im SetAnchor geaendert haben!
+                // (Kopieren in andere Docs!)
+                pFmt = pAttr->GetFlyCnt().GetFrmFmt();
+                SwDoc *pDoc = pFmt->GetDoc();
+
+                if( RES_DRAWFRMFMT == pFmt->Which() &&
+                    pDoc->IsInHeaderFooter(
+                        pFmt->GetAnchor().GetCntntAnchor()->nNode ) )
+                {
+                    // das soll nicht meoglich sein; hier verhindern
+                    // Der Dtor des TxtHints loescht nicht das Zeichen.
+                    // Wenn ein CH_TXTATR_.. vorliegt, dann muss man
+                    // dieses explizit loeschen
+                    if( SETATTR_NOTXTATRCHR & nInsMode )
+                    {
+                        // loesche das Zeichen aus dem String !
+                        ASSERT( ( CH_TXTATR_BREAKWORD ==
+                                        aText.GetChar(*pAttr->GetStart() ) ||
+                                  CH_TXTATR_INWORD ==
+                                          aText.GetChar(*pAttr->GetStart())),
+                                "where is my attribu character" );
+                        aText.Erase( *pAttr->GetStart(), 1 );
+                        // Indizies Updaten
+                        SwIndex aTmpIdx( this, *pAttr->GetStart() );
+                        Update( aTmpIdx, 1, TRUE );
+                    }
+                    // Format loeschen nicht ins Undo aufnehmen!!
+                    BOOL bUndo = pDoc->DoesUndo();
+                    pDoc->DoUndo( FALSE );
+                    DestroyAttr( pAttr );
+                    pDoc->DoUndo( bUndo );
+                    return FALSE;
+                }
+                break;
+            }
+            case RES_TXTATR_FTN :
+            {
+                // Fussnoten, man kommt an alles irgendwie heran.
+                // CntntNode erzeugen und in die Inserts-Section stellen
+                SwDoc *pDoc = GetDoc();
+                SwNodes &rNodes = pDoc->GetNodes();
+
+                // FussNote in nicht Content-/Redline-Bereich einfuegen ??
+                if( StartOfSectionIndex() < rNodes.GetEndOfAutotext().GetIndex() )
+                {
+                    // das soll nicht meoglich sein; hier verhindern
+                    // Der Dtor des TxtHints loescht nicht das Zeichen.
+                    // Wenn ein CH_TXTATR_.. vorliegt, dann muss man
+                    // dieses explizit loeschen
+                    if( SETATTR_NOTXTATRCHR & nInsMode )
+                    {
+                        // loesche das Zeichen aus dem String !
+                        ASSERT( ( CH_TXTATR_BREAKWORD ==
+                                        aText.GetChar(*pAttr->GetStart() ) ||
+                                  CH_TXTATR_INWORD ==
+                                          aText.GetChar(*pAttr->GetStart())),
+                                "where is my attribu character" );
+                        aText.Erase( *pAttr->GetStart(), 1 );
+                        // Indizies Updaten
+                        SwIndex aTmpIdx( this, *pAttr->GetStart() );
+                        Update( aTmpIdx, 1, TRUE );
+                    }
+                    DestroyAttr( pAttr );
+                    return FALSE;
+                }
+
+                // wird eine neue Fussnote eingefuegt ??
+                BOOL bNewFtn = 0 == ((SwTxtFtn*)pAttr)->GetStartNode();
+                if( bNewFtn )
+                    ((SwTxtFtn*)pAttr)->MakeNewTextSection( GetNodes() );
+                else if ( !GetpSwpHints() || !GetpSwpHints()->IsInSplitNode() )
+                {
+                    // loesche alle Frames der Section, auf die der StartNode zeigt
+                    ULONG nSttIdx =
+                        ((SwTxtFtn*)pAttr)->GetStartNode()->GetIndex();
+                    ULONG nEndIdx = rNodes[ nSttIdx++ ]->EndOfSectionIndex();
+                    SwCntntNode* pCNd;
+                    for( ; nSttIdx < nEndIdx; ++nSttIdx )
+                        if( 0 != ( pCNd = rNodes[ nSttIdx ]->GetCntntNode() ))
+                            pCNd->DelFrms();
+                }
+
+                if( !(SETATTR_NOTXTATRCHR & nInsMode) )
+                {
+                    // Wir muessen zuerst einfuegen, da sonst gleiche Indizes
+                    // entstehen koennen und das Attribut im _SortArr_ am
+                    // Dokument nicht eingetrage wird.
+                    SwIndex aNdIdx( this, *pAttr->GetStart() );
+                    Insert( GetCharOfTxtAttr(*pAttr), aNdIdx );
+                    nInsMode |= SETATTR_NOTXTATRCHR;
+                }
+
+                // Wir tragen uns am FtnIdx-Array des Docs ein ...
+                SwTxtFtn* pTxtFtn = 0;
+                if( !bNewFtn )
+                {
+                    // eine alte Ftn wird umgehaengt (z.B. SplitNode)
+                    for( USHORT n = 0; n < pDoc->GetFtnIdxs().Count(); ++n )
+                        if( pAttr == pDoc->GetFtnIdxs()[n] )
+                        {
+                            // neuen Index zuweisen, dafuer aus dem SortArray
+                            // loeschen und neu eintragen
+                            pTxtFtn = pDoc->GetFtnIdxs()[n];
+                            pDoc->GetFtnIdxs().Remove( n );
+                            break;
+                        }
+                    // wenn ueber Undo der StartNode gesetzt wurde, kann
+                    // der Index noch gar nicht in der Verwaltung stehen !!
+                }
+                if( !pTxtFtn )
+                    pTxtFtn = (SwTxtFtn*)pAttr;
+
+                // fuers Update der Nummern und zum Sortieren
+                // muss der Node gesetzt sein.
+                ((SwTxtFtn*)pAttr)->ChgTxtNode( this );
+
+                // FussNote im Redline-Bereich NICHT ins FtnArray einfuegen!
+                if( StartOfSectionIndex() > rNodes.GetEndOfRedlines().GetIndex() )
+                {
+#ifndef PRODUCT
+                    const BOOL bSuccess =
+#endif
+                        pDoc->GetFtnIdxs().Insert( pTxtFtn );
+#ifndef PRODUCT
+                    ASSERT( bSuccess, "FtnIdx nicht eingetragen." );
+#endif
+                }
+                SwNodeIndex aTmpIndex( *this );
+                pDoc->GetFtnIdxs().UpdateFtn( aTmpIndex);
+                ((SwTxtFtn*)pAttr)->SetSeqRefNo();
+            }
+            break;
+
+            case RES_TXTATR_FIELD:
+                {
+                    // fuer HiddenParaFields Benachrichtigungsmechanismus
+                    // anwerfen
+                    if( RES_HIDDENPARAFLD ==
+                        pAttr->GetFld().GetFld()->GetTyp()->Which() )
+                    bHiddenPara = TRUE;
+                }
+                break;
+
+        }
+        // Fuer SwTxtHints ohne Endindex werden CH_TXTATR_..
+        // eingefuegt, aStart muss danach um einen zurueckgesetzt werden.
+        // Wenn wir im SwTxtNode::Copy stehen, so wurde das Zeichen bereits
+        // mitkopiert. In solchem Fall ist SETATTR_NOTXTATRCHR angegeben worden.
+        if( !(SETATTR_NOTXTATRCHR & nInsMode) )
+        {
+            SwIndex aIdx( this, *pAttr->GetStart() );
+            Insert( GetCharOfTxtAttr(*pAttr), aIdx );
+        }
+    }
+    else
+        ASSERT( *pAttr->GetEnd() <= Len(), "EndIdx hinter Len!" );
+
+    if ( !pSwpHints )
+        pSwpHints = new SwpHints();
+
+    // 4263: AttrInsert durch TextInsert => kein Adjust
+    pSwpHints->Insert( pAttr, *this, nMode );
+
+    // 47375: In pSwpHints->Insert wird u.a. Merge gerufen und das Hints-Array
+    // von ueberfluessigen Hints befreit, dies kann u.U. sogar der frisch
+    // eingefuegte Hint pAttr sein, der dann zerstoert wird!!
+    if( USHRT_MAX == pSwpHints->GetPos( pAttr ) )
+        return FALSE;
+
+    if(bHiddenPara)
+        SetCalcVisible();
+    return TRUE;
+}
+
+
+/*************************************************************************
+ *                      SwTxtNode::Delete()
+ *************************************************************************/
+
+void SwTxtNode::Delete( SwTxtAttr *pAttr, BOOL bThisOnly )
+{
+    if ( !pSwpHints )
+        return;
+    if( bThisOnly )
+    {
+        xub_StrLen* pEndIdx = pAttr->GetEnd();
+        if( !pEndIdx )
+        {
+            // hat es kein Ende kann es nur das sein, was hier steht!
+            // Unbedingt Copy-konstruieren!
+            const SwIndex aIdx( this, *pAttr->GetStart() );
+            Erase( aIdx, 1 );
+        }
+        else
+        {
+            // den MsgHint jetzt fuettern, weil gleich sind
+            // Start und End weg.
+            SwUpdateAttr aHint( *pAttr->GetStart(), *pEndIdx, pAttr->Which() );
+            pSwpHints->Delete( pAttr );
+            pAttr->RemoveFromPool( GetDoc()->GetAttrPool() );
+            delete pAttr;
+            SwModify::Modify( 0, &aHint );     // die Frames benachrichtigen
+
+            if( pSwpHints && pSwpHints->CanBeDeleted() )
+                DELETEZ( pSwpHints );
+        }
+
+        return;
+    }
+    Delete( pAttr->Which(), *pAttr->GetStart(), *pAttr->GetAnyEnd() );
+}
+
+/*************************************************************************
+ *                      SwTxtNode::Delete()
+ *************************************************************************/
+
+void SwTxtNode::Delete( USHORT nTxtWhich, xub_StrLen nStart, xub_StrLen nEnd )
+{
+    if ( !pSwpHints )
+        return;
+
+    const xub_StrLen *pEndIdx;
+    const xub_StrLen *pSttIdx;
+    SwTxtAttr* pTxtHt;
+
+    for( USHORT nPos = 0; pSwpHints && nPos < pSwpHints->Count(); nPos++ )
+    {
+        pTxtHt = pSwpHints->GetHt( nPos );
+        const USHORT nWhich = pTxtHt->Which();
+        if( nWhich == nTxtWhich &&
+            *( pSttIdx = pTxtHt->GetStart()) == nStart )
+        {
+            pEndIdx = pTxtHt->GetEnd();
+
+            // Text-Attribute sind voellig dynamisch, so dass diese nur
+            // mit ihrer Start-Position verglichen werden.
+            if( !pEndIdx )
+            {
+                // Unbedingt Copy-konstruieren!
+                const SwIndex aIdx( this, *pSttIdx );
+                Erase( aIdx, 1 );
+                break;
+            }
+            else if( *pEndIdx == nEnd )
+            {
+                // den MsgHint jetzt fuettern, weil gleich sind
+                // Start und End weg.
+                // Das CalcVisibleFlag bei HiddenParaFields entfaellt,
+                // da dies das Feld im Dtor selbst erledigt.
+                SwUpdateAttr aHint( *pSttIdx, *pEndIdx, nTxtWhich );
+                pSwpHints->DeleteAtPos( nPos );    // gefunden, loeschen,
+                pTxtHt->RemoveFromPool( GetDoc()->GetAttrPool() );
+                delete pTxtHt;
+                SwModify::Modify( 0, &aHint );     // die Frames benachrichtigen
+                break;
+            }
+        }
+    }
+    if( pSwpHints && pSwpHints->CanBeDeleted() )
+        DELETEZ( pSwpHints );
+}
+
+/*************************************************************************
+ *                      SwTxtNode::DelSoftHyph()
+ *************************************************************************/
+
+void SwTxtNode::DelSoftHyph( const xub_StrLen nStart, const xub_StrLen nEnd )
+{
+    xub_StrLen nFndPos = nStart, nEndPos = nEnd;
+    while( STRING_NOTFOUND !=
+            ( nFndPos = aText.Search( CHAR_SOFTHYPHEN, nFndPos )) &&
+            nFndPos < nEndPos )
+    {
+        aText.Erase( nFndPos, 1 );
+        --nEndPos;
+    }
+}
+
+// setze diese Attribute am TextNode. Wird der gesamte Bereich umspannt,
+// dann setze sie nur im AutoAttrSet (SwCntntNode:: SetAttr)
+BOOL SwTxtNode::SetAttr( const SfxItemSet& rSet, xub_StrLen nStt,
+                         xub_StrLen nEnd, USHORT nMode )
+{
+    if( !rSet.Count() )
+        return FALSE;
+
+    // teil die Sets auf (fuer Selektion in Nodes)
+    const SfxItemSet* pSet = &rSet;
+    SfxItemSet aTxtSet( *rSet.GetPool(), RES_TXTATR_BEGIN, RES_TXTATR_END-1 );
+
+    // gesamter Bereich
+    if( !nStt && nEnd == aText.Len() && !(nMode & SETATTR_NOFORMATATTR ) )
+    {
+        // sind am Node schon Zeichenvorlagen gesetzt, muss man diese Attribute
+        // (rSet) immer als TextAttribute setzen, damit sie angezeigt werden.
+        int bHasCharFmts = FALSE;
+        if( pSwpHints )
+        {
+            USHORT nWhich;
+            for( USHORT n = 0; !bHasCharFmts && n < pSwpHints->Count(); ++n )
+            {
+                nWhich = (*pSwpHints)[ n ]->Which();
+                bHasCharFmts = ( RES_TXTATR_CHARFMT == nWhich ||
+                                 RES_TXTATR_INETFMT == nWhich );
+            }
+        }
+
+        if( !bHasCharFmts )
+        {
+            aTxtSet.Put( rSet );
+            if( aTxtSet.Count() != rSet.Count() )
+            {
+                BOOL bRet = SwCntntNode::SetAttr( rSet );
+                if( !aTxtSet.Count() )
+                    return bRet;
+            }
+            pSet = &aTxtSet;
+        }
+    }
+
+    if ( !pSwpHints )
+        pSwpHints = new SwpHints();
+
+    USHORT nWhich, nCount = 0;
+    SwTxtAttr* pNew;
+    SfxItemIter aIter( *pSet );
+    const SfxPoolItem* pItem = aIter.GetCurItem();
+    do {
+        if( pItem && (SfxPoolItem*)-1 != pItem &&
+            (( RES_CHRATR_BEGIN <= ( nWhich = pItem->Which()) &&
+              RES_CHRATR_END > nWhich ) ||
+            ( RES_TXTATR_BEGIN <= nWhich && RES_TXTATR_END > nWhich ) ||
+            ( RES_UNKNOWNATR_BEGIN <= nWhich && RES_UNKNOWNATR_END > nWhich )) )
+        {
+            if( RES_TXTATR_CHARFMT == pItem->Which() &&
+                GetDoc()->GetDfltCharFmt()==((SwFmtCharFmt*)pItem)->GetCharFmt())
+            {
+                SwIndex aIndex( this, nStt );
+                RstAttr( aIndex, nEnd - nStt, RES_TXTATR_CHARFMT, 0 );
+                DontExpandFmt( aIndex );
+            }
+            else
+            {
+                pNew = MakeTxtAttr( *pItem, nStt, nEnd );
+                if( pNew )
+                {
+                    // Attribut ohne Ende, aber Bereich markiert ?
+                    if( nEnd != nStt && !pNew->GetEnd() )
+                    {
+                        ASSERT( !this, "Attribut ohne Ende aber Bereich vorgegeben" );
+                        DestroyAttr( pNew );        // nicht einfuegen
+                    }
+                    else if( Insert( pNew, nMode ))
+                        ++nCount;
+                }
+            }
+        }
+        if( aIter.IsAtEnd() )
+            break;
+        pItem = aIter.NextItem();
+    } while( TRUE );
+
+    if( pSwpHints && pSwpHints->CanBeDeleted() )
+        DELETEZ( pSwpHints );
+
+    return nCount ? TRUE : FALSE;
+}
+
+BOOL lcl_Included( const USHORT nWhich, const SwTxtAttr *pAttr )
+{
+#ifdef DEBUG
+    static long nTest = 0;
+    ++nTest;
+#endif
+    BOOL bRet;
+    SwCharFmt* pFmt = RES_TXTATR_INETFMT == pAttr->Which() ?
+                        ((SwTxtINetFmt*)pAttr)->GetCharFmt() :
+                        pAttr->GetCharFmt().GetCharFmt();
+    if( pFmt )
+        bRet = SFX_ITEM_SET == pFmt->GetAttrSet().GetItemState( nWhich, TRUE );
+    else
+        bRet = FALSE;
+    return bRet;
+}
+
+void lcl_MergeAttr( SfxItemSet& rSet, const SfxPoolItem& rAttr )
+{
+    rSet.Put( rAttr );
+}
+
+void lcl_MergeAttr_ExpandChrFmt( SfxItemSet& rSet, const SfxPoolItem& rAttr )
+{
+    if( RES_TXTATR_CHARFMT == rAttr.Which() ||
+        RES_TXTATR_INETFMT == rAttr.Which() )
+    {
+        // aus der Vorlage die Attribute holen:
+        SwCharFmt* pFmt = RES_TXTATR_INETFMT == rAttr.Which() ?
+                        ((SwFmtINetFmt&)rAttr).GetTxtINetFmt()->GetCharFmt() :
+                        ((SwFmtCharFmt&)rAttr).GetCharFmt();
+        if( pFmt )
+        {
+            const SfxItemSet& rCFSet = pFmt->GetAttrSet();
+            SfxWhichIter aIter( rCFSet );
+            register USHORT nWhich = aIter.FirstWhich();
+            while( nWhich )
+            {
+                if( ( nWhich < RES_CHRATR_END ) &&
+                    ( SFX_ITEM_SET == rCFSet.GetItemState( nWhich, TRUE ) ) )
+                    rSet.Put( rCFSet.Get( nWhich ) );
+                nWhich = aIter.NextWhich();
+            }
+#if 0
+            SfxItemSet aTmpSet( *rSet.GetPool(), rSet.GetRanges() );
+            aTmpSet.Set( pFmt->GetAttrSet(), TRUE );
+/*
+????? JP 31.01.95 ????  wie jetzt ???
+            rSet.MergeValues( aTmpSet );
+
+            // jetzt alle zusammen "mergen"
+            rSet.Differentiate( aTmpSet );
+*/
+            rSet.Put( aTmpSet );
+#endif
+        }
+    }
+
+    // aufnehmen als MergeWert (falls noch nicht gesetzt neu setzen!)
+#if 0
+/* wenn mehrere Attribute ueberlappen werden diese gemergt !!
+ z.B
+            1234567890123456789
+              |------------|        Font1
+                 |------|           Font2
+                    ^  ^
+                    |--|        Abfragebereich: -> uneindeutig
+*/
+    else if( SFX_ITEM_DEFAULT == rSet.GetItemState( rAttr.Which(), FALSE ))
+        rSet.Put( rAttr );
+    else
+        rSet.MergeValue( rAttr );
+#else
+/* wenn mehrere Attribute ueberlappen gewinnt der letze !!
+ z.B
+            1234567890123456789
+              |------------|        Font1
+                 |------|           Font2
+                    ^  ^
+                    |--|        Abfragebereich: -> Gueltig ist Font2
+*/
+        rSet.Put( rAttr );
+#endif
+}
+
+// erfrage die Attribute vom TextNode ueber den Bereich
+BOOL SwTxtNode::GetAttr( SfxItemSet& rSet, xub_StrLen nStart, xub_StrLen nEnd,
+                            BOOL bOnlyTxtAttr, BOOL bGetFromChrFmt ) const
+{
+    if( pSwpHints )
+    {
+        /* stelle erstmal fest, welche Text-Attribut in dem Bereich gueltig
+         * sind. Dabei gibt es folgende Faelle:
+         *  UnEindeutig wenn: (wenn != Format-Attribut)
+         *      - das Attribut liegt vollstaendig im Bereich
+         *      - das Attributende liegt im Bereich
+         *      - der Attributanfang liegt im Bereich:
+         * Eindeutig (im Set mergen):
+         *      - das Attrib umfasst den Bereich
+         * nichts tun:
+         *      das Attribut liegt ausserhalb des Bereiches
+         */
+
+        void (*fnMergeAttr)( SfxItemSet&, const SfxPoolItem& )
+            = bGetFromChrFmt ? &lcl_MergeAttr_ExpandChrFmt
+                             : &lcl_MergeAttr;
+
+        // dann besorge mal die Auto-(Fmt)Attribute
+        SfxItemSet aFmtSet( *rSet.GetPool(), rSet.GetRanges() );
+        if( !bOnlyTxtAttr )
+            SwCntntNode::GetAttr( aFmtSet );
+
+        const USHORT nSize = pSwpHints->Count();
+        register USHORT n;
+        register xub_StrLen nAttrStart;
+        register const xub_StrLen* pAttrEnd;
+
+        if( nStart == nEnd )                // kein Bereich:
+        {
+            for( n = 0; n < nSize; ++n )        //
+            {
+                const SwTxtAttr* pHt = (*pSwpHints)[n];
+                nAttrStart = *pHt->GetStart();
+                if( nAttrStart > nEnd )         // ueber den Bereich hinaus
+                    break;
+
+                if( 0 == ( pAttrEnd = pHt->GetEnd() ))      // nie Attribute ohne Ende
+                    continue;
+
+                if( ( nAttrStart < nStart &&
+                        ( pHt->DontExpand() ? nStart < *pAttrEnd
+                                            : nStart <= *pAttrEnd )) ||
+                    ( nStart == nAttrStart &&
+                        ( nAttrStart == *pAttrEnd || !nStart )))
+                    (*fnMergeAttr)( rSet, pHt->GetAttr() );
+            }
+        }
+        else                            // es ist ein Bereich definiert
+        {
+            SwTxtAttr** aAttrArr = 0;
+            const USHORT coArrSz = RES_TXTATR_WITHEND_END - RES_CHRATR_BEGIN +
+                                    ( RES_UNKNOWNATR_END -
+                                                    RES_UNKNOWNATR_BEGIN );
+
+            for( n = 0; n < nSize; ++n )
+            {
+                const SwTxtAttr* pHt = (*pSwpHints)[n];
+                nAttrStart = *pHt->GetStart();
+                if( nAttrStart > nEnd )         // ueber den Bereich hinaus
+                    break;
+
+                if( 0 == ( pAttrEnd = pHt->GetEnd() ))      // nie Attribute ohne Ende
+                    continue;
+
+                BOOL bChkInvalid = FALSE;
+                if( nAttrStart <= nStart )      // vor oder genau Start
+                {
+                    if( *pAttrEnd <= nStart )   // liegt davor
+                        continue;
+
+                    if( nEnd <= *pAttrEnd )     // hinter oder genau Ende
+                        (*fnMergeAttr)( aFmtSet, pHt->GetAttr() );
+                    else
+//                  else if( pHt->GetAttr() != aFmtSet.Get( pHt->Which() ) )
+                        // uneindeutig
+                        bChkInvalid = TRUE;
+                }
+                else if( nAttrStart < nEnd      // reicht in den Bereich
+)//                      && pHt->GetAttr() != aFmtSet.Get( pHt->Which() ) )
+                    bChkInvalid = TRUE;
+
+                if( bChkInvalid )
+                {
+                    // uneindeutig ?
+                    if( !aAttrArr )
+                    {
+                        aAttrArr = new SwTxtAttr* [ coArrSz ];
+                        memset( aAttrArr, 0, sizeof( SwTxtAttr* ) * coArrSz );
+                    }
+
+                    const SwTxtAttr** ppPrev;
+                    if( RES_CHRATR_BEGIN <= pHt->Which() &&
+                        pHt->Which() < RES_TXTATR_WITHEND_END )
+                         ppPrev = (const SwTxtAttr**)&aAttrArr[
+                                        pHt->Which() - RES_CHRATR_BEGIN ];
+                    else if( RES_UNKNOWNATR_BEGIN <= pHt->Which() &&
+                        pHt->Which() < RES_UNKNOWNATR_END )
+                         ppPrev = (const SwTxtAttr**)&aAttrArr[
+                                        pHt->Which() - RES_UNKNOWNATR_BEGIN
+                                        + ( RES_TXTATR_WITHEND_END -
+                                            RES_CHRATR_BEGIN ) ];
+                    else
+                        ppPrev = 0;
+
+                    if( !*ppPrev )
+                    {
+                        if( nAttrStart > nStart )
+                        {
+                            rSet.InvalidateItem( pHt->Which() );
+                            *ppPrev = (SwTxtAttr*)-1;
+                        }
+                        else
+                            *ppPrev = pHt;
+                    }
+                    else if( (SwTxtAttr*)-1 != *ppPrev )
+                    {
+                        if( *(*ppPrev)->GetEnd() == nAttrStart &&
+                            (*ppPrev)->GetAttr() == pHt->GetAttr() )
+                            *ppPrev = pHt;
+                        else
+                        {
+                            rSet.InvalidateItem( pHt->Which() );
+                            *ppPrev = (SwTxtAttr*)-1;
+                        }
+                    }
+                }
+            }
+            if( aAttrArr )
+            {
+                const SwTxtAttr* pAttr;
+                for( n = 0; n < coArrSz; ++n )
+                    if( 0 != ( pAttr = aAttrArr[ n ] ) &&
+                        (SwTxtAttr*)-1 != pAttr )
+                    {
+                        USHORT nWh;
+                        if( n < (RES_TXTATR_WITHEND_END -
+                                            RES_CHRATR_BEGIN ))
+                            nWh = n + RES_CHRATR_BEGIN;
+                        else
+                            nWh = n - ( RES_TXTATR_WITHEND_END -
+                                                  RES_CHRATR_BEGIN ) +
+                                                RES_UNKNOWNATR_BEGIN;
+
+                        if( nEnd <= *pAttr->GetEnd() )  // hinter oder genau Ende
+                        {
+                            if( pAttr->GetAttr() != aFmtSet.Get( nWh ) )
+                                (*fnMergeAttr)( rSet, pAttr->GetAttr() );
+                        }
+                        else
+                            // uneindeutig
+                            rSet.InvalidateItem( nWh );
+                    }
+                __DELETE( coArrSz ) aAttrArr;
+            }
+        }
+        if( aFmtSet.Count() )
+        {
+            // aus dem Format-Set alle entfernen, die im TextSet auch gesetzt sind
+            aFmtSet.Differentiate( rSet );
+            // jetzt alle zusammen "mergen"
+            rSet.Put( aFmtSet );
+        }
+    }
+    else if( !bOnlyTxtAttr )
+        // dann besorge mal die Auto-(Fmt)Attribute
+        SwCntntNode::GetAttr( rSet );
+
+    return rSet.Count() ? TRUE : FALSE;
+}
+
+int lcl_IsNewAttrInSet( const SwpHints& rHints, const SfxPoolItem& rItem,
+    const xub_StrLen nEnd )
+{
+    int bIns = TRUE;
+    for( USHORT i = 0; i < rHints.Count(); ++i )
+    {
+        const SwTxtAttr *pOther = rHints[ i ];
+        if( *pOther->GetStart() )
+            break;
+
+        if( pOther->GetEnd() &&
+            *pOther->GetEnd() == nEnd &&
+            (  RES_TXTATR_CHARFMT == pOther->Which() ||
+               RES_TXTATR_INETFMT == pOther->Which() ||
+               pOther->Which() == rItem.Which() ) )
+        {
+            bIns = FALSE;
+            break;
+        }
+    }
+    return bIns;
+}
+
+void SwTxtNode::FmtToTxtAttr( SwTxtNode* pNd )
+{
+    SfxItemSet aThisSet( GetDoc()->GetAttrPool(), aCharFmtSetRange );
+    if( GetpSwAttrSet() && GetpSwAttrSet()->Count() )
+        aThisSet.Put( *GetpSwAttrSet() );
+
+    if ( !pSwpHints )
+        pSwpHints = new SwpHints();
+
+    if( pNd == this )
+    {
+        if( aThisSet.Count() )
+        {
+            SfxItemIter aIter( aThisSet );
+            const SfxPoolItem* pItem = aIter.GetCurItem();
+            while( TRUE )
+            {
+                if( lcl_IsNewAttrInSet( *pSwpHints, *pItem, GetTxt().Len() ) )
+                {
+                    pSwpHints->SwpHintsArr::Insert(
+                            MakeTxtAttr( *pItem, 0, GetTxt().Len() ) );
+                    GetpSwAttrSet()->ClearItem( pItem->Which() );
+                }
+
+                if( aIter.IsAtEnd() )
+                    break;
+                pItem = aIter.NextItem();
+            }
+        }
+
+    }
+    else
+    {
+        SfxItemSet aNdSet( pNd->GetDoc()->GetAttrPool(), aCharFmtSetRange );
+        if( pNd->GetpSwAttrSet() && pNd->GetpSwAttrSet()->Count() )
+            aNdSet.Put( *pNd->GetpSwAttrSet() );
+
+        if ( !pNd->pSwpHints )
+            pNd->pSwpHints = new SwpHints();
+
+        if( aThisSet.Count() )
+        {
+            SfxItemIter aIter( aThisSet );
+            const SfxPoolItem* pItem = aIter.GetCurItem(), *pNdItem;
+            while( TRUE )
+            {
+                if( ( SFX_ITEM_SET != aNdSet.GetItemState( pItem->Which(), FALSE,
+                    &pNdItem ) || *pItem != *pNdItem ) &&
+                    lcl_IsNewAttrInSet( *pSwpHints, *pItem, GetTxt().Len() ) )
+                {
+                    pSwpHints->SwpHintsArr::Insert(
+                            MakeTxtAttr( *pItem, 0, GetTxt().Len() ) );
+                    GetpSwAttrSet()->ClearItem( pItem->Which() );
+                }
+                aNdSet.ClearItem( pItem->Which() );
+
+                if( aIter.IsAtEnd() )
+                    break;
+                pItem = aIter.NextItem();
+            }
+        }
+
+        if( aNdSet.Count() )
+        {
+            SfxItemIter aIter( aNdSet );
+            const SfxPoolItem* pItem = aIter.GetCurItem();
+            while( TRUE )
+            {
+                if( lcl_IsNewAttrInSet( *pNd->pSwpHints, *pItem, pNd->GetTxt().Len() ) )
+                    pNd->pSwpHints->SwpHintsArr::Insert(
+                            pNd->MakeTxtAttr( *pItem, 0, pNd->GetTxt().Len() ) );
+                pNd->GetpSwAttrSet()->ClearItem( pItem->Which() );
+
+                if( aIter.IsAtEnd() )
+                    break;
+                pItem = aIter.NextItem();
+            }
+
+            SwFmtChg aTmp1( pNd->GetFmtColl() );
+            pNd->SwModify::Modify( &aTmp1, &aTmp1 );
+        }
+    }
+
+    if( pNd->pSwpHints->CanBeDeleted() )
+        DELETEZ( pNd->pSwpHints );
+}
+
+/*************************************************************************
+ *                      SwpHints::CalcFlags()
+ *************************************************************************/
+
+void SwpHints::CalcFlags()
+{
+    bDDEFlds = bFtn = FALSE;
+    const USHORT nSize = Count();
+    const SwTxtAttr* pAttr;
+    for( USHORT nPos = 0; nPos < nSize; ++nPos )
+        switch( ( pAttr = (*this)[ nPos ])->Which() )
+        {
+        case RES_TXTATR_FTN:
+            bFtn = TRUE;
+            if( bDDEFlds )
+                return;
+            break;
+        case RES_TXTATR_FIELD:
+            {
+                const SwField* pFld = pAttr->GetFld().GetFld();
+                if( RES_DDEFLD == pFld->GetTyp()->Which() )
+                {
+                    bDDEFlds = TRUE;
+                    if( bFtn )
+                        return;
+                }
+            }
+            break;
+        }
+}
+
+/*************************************************************************
+ *                      SwpHints::CalcVisibleFlag()
+ *************************************************************************/
+
+BOOL SwpHints::CalcVisibleFlag()
+{
+    BOOL bOldVis = bVis;
+    bCalcVis = FALSE;
+    BOOL            bNewVis  = TRUE;
+    const USHORT    nSize = Count();
+    const SwTxtAttr *pTxtHt;
+
+    for( USHORT nPos = 0; nPos < nSize; ++nPos )
+    {
+        pTxtHt = (*this)[ nPos ];
+        const USHORT nWhich = pTxtHt->Which();
+
+        if( RES_TXTATR_FIELD == nWhich )
+        {
+            const SwFmtFld& rFld = pTxtHt->GetFld();
+            if( RES_HIDDENPARAFLD == rFld.GetFld()->GetTyp()->Which())
+            {
+                if( !((SwHiddenParaField*)rFld.GetFld())->IsHidden() )
+                {
+                    SetVisible(TRUE);
+                    return !bOldVis;
+                }
+                else
+                    bNewVis = FALSE;
+            }
+        }
+    }
+    SetVisible( bNewVis );
+    return bOldVis != bNewVis;
+}
+
+
+/*************************************************************************
+ *                      SwpHints::Resort()
+ *************************************************************************/
+
+// Ein Hint hat seinen Anfangswert geaendert.
+// Hat sich dadurch die Sortierreihenfolge
+// geaendert, so wird solange umsortiert, bis
+// sie wieder stimmt.
+
+BOOL SwpHints::Resort( const USHORT nPos )
+{
+    const SwTxtAttr *pTmp;
+
+    if ( ( nPos+1 < Count() &&
+           *(*this)[nPos]->GetStart() > *(*this)[nPos+1]->GetStart() ) ||
+         ( nPos > 0 &&
+           *(*this)[nPos]->GetStart() < *(*this)[nPos-1]->GetStart() ) )
+    {
+        pTmp = (*this)[nPos];
+        DeleteAtPos( nPos );
+        SwpHintsArr::Insert( pTmp );
+        // Wenn tatsaechlich umsortiert wurde, muss die
+        // Position i nochmal bearbeitet werden.
+        return TRUE;
+    }
+    return FALSE;
+}
+
+/*************************************************************************
+ *                      SwpHints::GetLang()
+ *************************************************************************/
+
+USHORT SwpHints::GetLang( const xub_StrLen nBegin, const xub_StrLen nLen) const
+{
+    USHORT nRet = LANGUAGE_DONTKNOW;
+    xub_StrLen nEnd = nBegin + nLen;
+    for( USHORT i = 0, nSize = Count(); i < nSize; ++i )
+    {
+        // ist der Attribut-Anfang schon groesser als der Idx ?
+        const SwTxtAttr *pHt = operator[](i);
+        xub_StrLen nAttrStart = *pHt->GetStart();
+        if( nEnd < nAttrStart )
+            break;
+
+        const USHORT nWhich = pHt->Which();
+
+        if( ( ( RES_TXTATR_CHARFMT == nWhich || RES_TXTATR_INETFMT == nWhich )
+              && lcl_Included( RES_CHRATR_LANGUAGE, pHt ) )
+            || RES_CHRATR_LANGUAGE == nWhich )
+        {
+            const xub_StrLen *pEndIdx = pHt->GetEnd();
+            // Ueberlappt das Attribut den Bereich?
+
+
+            if( pEndIdx &&
+                nLen ? ( nAttrStart < nEnd && nBegin < *pEndIdx )
+                     : (( nAttrStart < nBegin &&
+                            ( pHt->DontExpand() ? nBegin < *pEndIdx
+                                                : nBegin <= *pEndIdx )) ||
+                        ( nBegin == nAttrStart &&
+                            ( nAttrStart == *pEndIdx || !nBegin ))) )
+            {
+                USHORT nLng;
+                if( RES_TXTATR_CHARFMT == nWhich )
+                    nLng = pHt->GetCharFmt().GetCharFmt()->GetLanguage().GetLanguage();
+                else if( RES_TXTATR_INETFMT == nWhich )
+                    nLng = ((SwTxtINetFmt*)pHt)->GetCharFmt()->GetLanguage().GetLanguage();
+                else
+                    nLng = (USHORT)pHt->GetLanguage().GetLanguage();
+
+                // Umfasst das Attribut den Bereich komplett?
+                if( nAttrStart <= nBegin && nEnd <= *pEndIdx )
+                    nRet = nLng;
+                else if( LANGUAGE_DONTKNOW == nRet )
+                    nRet = nLng; // partielle Ueberlappung, der 1. gewinnt
+            }
+        }
+    }
+    return nRet;
+}
+
+/*************************************************************************
+ *                      SwpHints::NoteInHistory()
+ *************************************************************************/
+
+void SwpHints::NoteInHistory( SwTxtAttr *pAttr, const BOOL bNew )
+{
+    if ( pHistory )
+        pHistory->Add( pAttr, bNew );
+}
+
+/*************************************************************************
+ *                      SwpHints::ClearDummies()
+ *************************************************************************/
+
+/*
+ * ClearDummies: Hints, die genau den gleichen Bereich umfassen wie
+ * ein nachfolgender mit gleichem Attribut oder eine nachfolgende Zeichen-
+ * vorlage, muessen entfernt werden.
+ * Solche Hints entstehen, wenn sie urspruenglich einen groesseren, den
+ * Nachfolger umfassenden Bereich hatten, die Aussenanteile aber durch
+ * SwTxtNode::RstAttr oder SwTxtNode::Update geloescht wurden.
+ */
+
+void SwpHints::ClearDummies( SwTxtNode &rNode )
+{
+    USHORT i = 0;
+    while ( i < Count() )
+    {
+        SwTxtAttr *pHt = GetHt( i++ );
+        const USHORT nWhich = pHt->Which();
+        const xub_StrLen *pEnd = pHt->GetEnd();
+        if ( pEnd && RES_TXTATR_REFMARK != nWhich
+                  && RES_TXTATR_TOXMARK != nWhich
+                  && RES_TXTATR_CHARFMT != nWhich
+                  && RES_TXTATR_INETFMT != nWhich )
+            for( USHORT j = i; j < Count(); ++j  )
+            {
+                SwTxtAttr *pOther = GetHt(j);
+                if ( *pOther->GetStart() > *pHt->GetStart() )
+                    break;
+
+                if( pOther->Which() == nWhich ||
+                    RES_TXTATR_CHARFMT == pOther->Which() ||
+                    RES_TXTATR_INETFMT == pOther->Which() )
+                {
+                    //JP 03.10.95: nicht zusammenfassen, zu kompliziert
+                    //          fuer WIN95-Compiler!!
+                    if( *pEnd == *pOther->GetEnd() &&
+                        ( pOther->Which() == nWhich ||
+                          lcl_Included( nWhich, pOther ) ) )
+                    {
+                        // Vorsicht: Geloeschte Dummies wuerden bei einer
+                        // Undo-Aktion die Macht an sich reissen ...
+                        // if( pHistory ) pHistory->Add( pHt );
+                        rNode.DestroyAttr( Cut( --i ) );
+                        break;
+                    }
+                }
+            }
+    }
+}
+
+/*************************************************************************
+ *                      SwpHints::Merge( )
+ *************************************************************************/
+
+/*
+ * Merge: Gleichartigen, gleichwertige Hints, die aneinandergrenzen,
+ * koennen verschmolzen werden, wenn an ihrer gemeinsamen Kante nicht ein
+ * gleichartiges Attribut endet oder beginnt, welches einen von der beiden
+ * Kandidaten umfasst, auch Zeichenvorlage duerfen nicht ueberlappt werden.
+ */
+
+BOOL SwpHints::Merge( SwTxtNode &rNode )
+{
+    USHORT i = 0;
+    BOOL bMerged = FALSE;
+    while ( i < Count() )
+    {
+        SwTxtAttr *pHt = GetHt( i++ );
+        const USHORT nWhich = pHt->Which();
+        const xub_StrLen *pEnd = pHt->GetEnd();
+        if ( pEnd && nWhich != RES_TXTATR_REFMARK
+                  && nWhich != RES_TXTATR_TOXMARK )
+        {
+            for ( USHORT j = i; j < Count(); j++  )
+            {
+                SwTxtAttr *pOther = GetHt(j);
+                if ( *pOther->GetStart() > *pEnd )
+                    break;   // keine beruehrenden Attribute mehr vorhanden
+                if ( *pOther->GetStart() == *pEnd &&
+                     ( pOther->Which() == pHt->Which() ||
+                       RES_TXTATR_CHARFMT == pOther->Which() ||
+                       RES_TXTATR_INETFMT == pOther->Which() ||
+                       ( ( RES_TXTATR_CHARFMT == pHt->Which() ||
+                           RES_TXTATR_INETFMT == pHt->Which() ) &&
+                         RES_TXTATR_REFMARK != pOther->Which() &&
+                         RES_TXTATR_TOXMARK != pOther->Which() ) ) )
+                {
+                    // Beruehrendes Attribut gefunden mit gleichem Typ bzw.
+                    // Zeichenvorlage.
+                    // Bei Attribut mit anderem Wert bzw. Zeichenvorlage
+                    // ist keine Verschmelzung mehr moeglich
+                    if ( pOther->Which() == pHt->Which() &&
+                         pOther->GetAttr() == pHt->GetAttr() )
+                    {
+                        // Unser Partner pOther erfuellt alle Voraussetzungen,
+                        // jetzt muessen wir uns selbst noch ueberpruefen, ob wir
+                        // nicht von einem gleichartigen Attribut oder einer
+                        // Zeichenvorlage umfasst werden, die das gleiche Ende
+                        // wie wir selbst haben.
+                        BOOL bMerge = TRUE;
+                        for ( USHORT k = 0; k+1 < i; k++ )
+                        {
+                            SwTxtAttr *pAnOther = GetHt(k);
+                            if ( ( pAnOther->Which() == pHt->Which() ||
+                                   RES_TXTATR_CHARFMT == pAnOther->Which() ||
+                                   RES_TXTATR_CHARFMT == pHt->Which() ||
+                                   RES_TXTATR_INETFMT == pAnOther->Which() ||
+                                   RES_TXTATR_INETFMT == pHt->Which() )
+                                 && pAnOther->GetEnd()
+                                 && *pAnOther->GetEnd() == *pEnd )
+                            {
+                                bMerge = FALSE; // kein Verschmelzen von i+j
+                                break;
+                            }
+                        }
+                        if ( bMerge )
+                        {
+                            // Auch Verschmelzen muss der History mitgeteilt
+                            // werden, da sonst ein Delete sein Attribut nicht
+                            // mehr findet, wenn es verschmolzen wurde!
+                            if( pHistory )
+                            {
+                                pHistory->Add( pHt );
+                                pHistory->Add( pOther );
+                            }
+                            *pHt->GetEnd() = *pOther->GetEnd();
+                            pHt->SetDontExpand( FALSE );
+                            if( pHistory ) pHistory->Add( pHt, TRUE );
+                            rNode.DestroyAttr( Cut( j ) );
+                            --i;
+                            bMerged = TRUE;
+                        }
+                    }
+                    break;
+                }
+            }
+        }
+    }
+    if ( bMerged )
+        ClearDummies( rNode );
+    return bMerged;
+}
+
+/*************************************************************************
+ *                      SwpHints::Forget( ... )
+ *************************************************************************/
+
+/*
+ * Forget: Hints, die genau den gleichen Bereich umfassen wie
+ * ein nachfolgender mit gleichem Attribut oder eine nachfolgende Zeichen-
+ * vorlage, duerfen nicht eingefuegt werden.
+ * Solche Hints koennen entstehen, wenn durch SwTxtNode::RstAttr
+ * ein Attribut in zwei Teile zerlegt wird und der zweite Teil einen
+ * identischen Bereich mit einem inneren Attribut bekaeme.
+ */
+
+BOOL SwpHints::Forget( const USHORT i, const USHORT nWhich,
+                 const xub_StrLen nStrt, const xub_StrLen nEnd )
+{
+    BOOL bRet = FALSE;
+    for ( USHORT j = i+1; j < Count(); j++ )
+    {
+        SwTxtAttr *pHt = GetHt( j );
+        if ( *pHt->GetStart() > nStrt )
+            break;
+        const USHORT nWhch = pHt->Which();
+        const xub_StrLen *pEnd = pHt->GetEnd();
+        if ( pEnd && *pEnd == nEnd &&
+             ( nWhch == nWhich ||
+             ( ( nWhch == RES_TXTATR_CHARFMT || RES_TXTATR_INETFMT == nWhch )
+               && lcl_Included( nWhich, pHt ) ) ) )
+        {
+            bRet = TRUE;
+            break;
+        }
+    }
+    return bRet;
+}
+
+/*************************************************************************
+ *                      SwpHints::Insert()
+ *************************************************************************/
+
+/*
+ * Insert: Der neue Hint wird immer eingefuegt. Wenn dabei ein
+ * ueberlappender oder gleicher Hintbereich mit gleichem Attribut
+ * und Wert gefunden, wird der neue Hint entsprechend veraendert
+ * und der alte herausgenommen (und zerstoert:
+ * SwpHints::Destroy()).
+ */
+
+void SwpHints::Insert( SwTxtAttr *pHint, SwTxtNode &rNode, USHORT nMode )
+{
+    // Irgendwann ist immer Schluss
+    if( USHRT_MAX == Count() )
+        return;
+
+    // Felder bilden eine Ausnahme:
+    // 1) Sie koennen nie ueberlappen
+    // 2) Wenn zwei Felder genau aneinander liegen,
+    //    sollen sie nicht zu einem verschmolzen werden.
+    // Wir koennen also auf die while-Schleife verzichten
+
+    xub_StrLen *pHtEnd = pHint->GetEnd();
+    USHORT nWhich = pHint->Which();
+
+    switch( nWhich )
+    {
+    case RES_TXTATR_CHARFMT:
+        ((SwTxtCharFmt*)pHint)->ChgTxtNode( &rNode );
+        break;
+    case RES_TXTATR_INETFMT:
+        {
+            ((SwTxtINetFmt*)pHint)->ChgTxtNode( &rNode );
+            SwCharFmt* pFmt = rNode.GetDoc()->GetCharFmtFromPool( RES_POOLCHR_INET_NORMAL );
+            pFmt->Add( (SwTxtINetFmt*)pHint );
+        }
+        break;
+    case RES_TXTATR_FIELD:
+        {
+            BOOL bDelFirst = 0 != ((SwTxtFld*)pHint)->GetpTxtNode();
+            ((SwTxtFld*)pHint)->ChgTxtNode( &rNode );
+            SwDoc* pDoc = rNode.GetDoc();
+            const SwField* pFld = ((SwTxtFld*)pHint)->GetFld().GetFld();
+
+            if( !pDoc->IsNewFldLst() )
+            {
+                // was fuer ein Feld ist es denn ??
+                // bestimmte Felder mussen am Doc das Calculations-Flag updaten
+                switch( pFld->GetTyp()->Which() )
+                {
+                case RES_DBFLD:
+                case RES_SETEXPFLD:
+                case RES_HIDDENPARAFLD:
+                case RES_HIDDENTXTFLD:
+                case RES_DBNUMSETFLD:
+                case RES_DBNEXTSETFLD:
+                    {
+                        if( bDelFirst )
+                            pDoc->InsDelFldInFldLst( FALSE, *(SwTxtFld*)pHint );
+                        if( rNode.GetNodes().IsDocNodes() )
+                            pDoc->InsDelFldInFldLst( TRUE, *(SwTxtFld*)pHint );
+                    }
+                    break;
+                case RES_DDEFLD:
+                    if( rNode.GetNodes().IsDocNodes() )
+                        ((SwDDEFieldType*)pFld->GetTyp())->IncRefCnt();
+                    break;
+                }
+            }
+
+            // gehts ins normale Nodes-Array?
+            if( rNode.GetNodes().IsDocNodes() )
+            {
+                BOOL bInsFldType = FALSE;
+                switch( pFld->GetTyp()->Which() )
+                {
+                case RES_SETEXPFLD:
+                    bInsFldType = ((SwSetExpFieldType*)pFld->GetTyp())->IsDeleted();
+                    if( GSE_SEQ & ((SwSetExpFieldType*)pFld->GetTyp())->GetType() )
+                    {
+                        // bevor die ReferenzNummer gesetzt wird, sollte
+                        // das Feld am richtigen FeldTypen haengen!
+                        SwSetExpFieldType* pFldType = (SwSetExpFieldType*)
+                                    pDoc->InsertFldType( *pFld->GetTyp() );
+                        if( pFldType != pFld->GetTyp() )
+                        {
+                            SwFmtFld* pFmtFld = (SwFmtFld*)&((SwTxtFld*)pHint)
+                                                                ->GetFld();
+                            pFldType->Add( pFmtFld );          // ummelden
+                            pFmtFld->GetFld()->ChgTyp( pFldType );
+                        }
+                        pFldType->SetSeqRefNo( *(SwSetExpField*)pFld );
+                    }
+                    break;
+                case RES_USERFLD:
+                    bInsFldType = ((SwUserFieldType*)pFld->GetTyp())->IsDeleted();
+                    break;
+
+                case RES_DDEFLD:
+                    if( pDoc->IsNewFldLst() )
+                        ((SwDDEFieldType*)pFld->GetTyp())->IncRefCnt();
+                    bInsFldType = ((SwDDEFieldType*)pFld->GetTyp())->IsDeleted();
+                    break;
+                }
+                if( bInsFldType )
+                    pDoc->InsDeletedFldType( *pFld->GetTyp() );
+            }
+        }
+        break;
+    case RES_TXTATR_FTN :
+        ((SwTxtFtn*)pHint)->ChgTxtNode( &rNode );
+        break;
+    case RES_TXTATR_REFMARK:
+        ((SwTxtRefMark*)pHint)->ChgTxtNode( &rNode );
+        break;
+    case RES_TXTATR_TOXMARK:
+        ((SwTxtTOXMark*)pHint)->ChgTxtNode( &rNode );
+        break;
+    }
+
+    if( SETATTR_DONTEXPAND & nMode )
+        pHint->SetDontExpand( TRUE );
+
+    // SwTxtAttrs ohne Ende werden sonderbehandelt:
+    // Sie werden natuerlich in das Array insertet, aber sie werden nicht
+    // in die pPrev/Next/On/Off-Verkettung aufgenommen.
+    // Der Formatierer erkennt diese TxtHints an dem CH_TXTATR_.. im Text !
+    xub_StrLen nHtStart = *pHint->GetStart();
+    if( !pHtEnd )
+    {
+        SwpHintsArr::Insert( pHint );
+        CalcFlags();
+        CHECK;
+
+        // ... und die Abhaengigen benachrichtigen
+        if ( rNode.GetDepends() )
+        {
+            SwUpdateAttr aHint( nHtStart, nHtStart, nWhich );
+            rNode.Modify( 0, &aHint );
+        }
+        return;
+    }
+
+    // ----------------------------------------------------------------
+    // Ab hier gibt es nur noch pHint mit einem EndIdx !!!
+
+    if( *pHtEnd < nHtStart )
+    {
+        ASSERT( *pHtEnd >= nHtStart,
+                    "+SwpHints::Insert: invalid hint, end < start" );
+
+        // Wir drehen den Quatsch einfach um:
+        *pHint->GetStart() = *pHtEnd;
+        *pHtEnd = nHtStart;
+        nHtStart = *pHint->GetStart();
+    }
+
+    // AMA: Damit wir endlich mit ueberlappenden Hints fertig werden ...
+    //      das neue Verfahren:
+
+    if( !(SETATTR_NOHINTADJUST & nMode) &&
+        RES_TXTATR_TOXMARK != nWhich && RES_TXTATR_REFMARK != nWhich )
+    {
+        const SfxPoolItem* pParaItem;
+        xub_StrLen nMaxEnd = *pHtEnd;
+        xub_StrLen nHtEnd = *pHtEnd;
+        BOOL bParaAttr = rNode.GetpSwAttrSet() &&
+            ( SFX_ITEM_SET == rNode.GetpSwAttrSet()->GetItemState(
+            nWhich, FALSE, &pParaItem ) ) && ( pParaItem == &pHint->GetAttr() );
+        BOOL bReplace = !( SETATTR_DONTREPLACE & nMode );
+        SwpHtStart_SAR *pTmpHints = NULL;
+
+        USHORT i;
+        // Wir wollen zwar von nHtStart bis nMaxEnd, muessen aber ggf.
+        // stueckeln (Attribute duerfen keine Zeichenvorlagen ueberlappen).
+        // Das erste Stueck wird also von nHtStart bis zum ersten Start/Ende
+        // einer Zeichenvorlage gehen usw. bis nHtEnd = nMaxEnd erreicht ist.
+        do
+        {
+            BOOL bINet = nWhich == RES_TXTATR_INETFMT;
+            BOOL bForgetAttr = bParaAttr;
+            // Muessen wir uns aufspalten?
+            if ( !bINet )
+            {
+                // Ab der zweiten Runde muessen wir zunaechst einen neuen
+                // Hint erzeugen.
+                if ( nHtEnd != nMaxEnd )
+                {
+                    pHint = rNode.MakeTxtAttr( bParaAttr ? *pParaItem :
+                                                            pHint->GetAttr(),
+                                                nHtStart, nMaxEnd );
+                    nHtEnd = *pHint->GetEnd();
+                }
+
+                for ( i = 0; i < Count(); i++)
+                {
+                    SwTxtAttr *pOther = GetHt(i);
+                    // Wir suchen nach Zeichenvorlagen, die uns schneiden
+                    // oder in uns liegen
+                    BOOL bOtherFmt = pOther->Which() == RES_TXTATR_CHARFMT
+                                     || pOther->Which() == RES_TXTATR_INETFMT;
+                    if( bOtherFmt || ( RES_TXTATR_CHARFMT == nWhich
+                                       && pOther->GetEnd() ) )
+                    {
+                        if( bForgetAttr && bOtherFmt &&
+                            *pOther->GetStart() <= nHtStart &&
+                            *pOther->GetEnd() >= nHtStart )
+                            bForgetAttr = FALSE;
+                        /* Die Flags bCheckInclude und bOtherFmt sollen die
+                         * Anzahl der Aufrufe von lcl_Include minimieren, da
+                         * dieses wg. IsVisitedURL() teuer ist. */
+                        BOOL bCheckInclude = FALSE;
+                        if( *pOther->GetStart() > nHtStart
+                            && *pOther->GetStart() < nHtEnd
+                            && ( bReplace || *pOther->GetEnd() > nHtEnd ) )
+                        {
+                            if( !bOtherFmt )
+                            {
+                                bOtherFmt = !lcl_Included( pOther->Which(),
+                                                           pHint );
+                                bCheckInclude = TRUE;
+                            }
+                            if( bOtherFmt )
+                                nHtEnd = *pOther->GetStart();
+                        }
+                        if( *pOther->GetEnd() > nHtStart
+                            && *pOther->GetEnd() < nHtEnd
+                            && ( bReplace || *pOther->GetStart() < nHtStart ) )
+                        {
+                            if( bOtherFmt || ( !bCheckInclude &&
+                                    !lcl_Included( pOther->Which(), pHint ) ) )
+                                nHtEnd = *pOther->GetEnd();
+                        }
+                    }
+                }
+                *pHint->GetEnd() = nHtEnd;
+            }
+
+            i = 0;
+            while(i < Count())
+            {
+                BOOL bCheckInclude = FALSE;
+                SwTxtAttr *pOther = GetHt(i);
+                const USHORT nOtherWhich = pOther->Which();
+                BOOL bCharFmt = RES_TXTATR_CHARFMT == nOtherWhich;
+                if( nOtherWhich == nWhich ||
+                    ( bINet && ( bCharFmt ||
+                          TRUE == ( bCheckInclude = TRUE ) ) ) ||
+                    ( RES_TXTATR_CHARFMT == nWhich &&   // fix: 10411
+                        ( RES_TXTATR_INETFMT == nOtherWhich ||
+                          TRUE == ( bCheckInclude = TRUE ) ) ) )
+                {
+                    if(0 == pOther->GetEnd())
+                    {
+                        if( *pOther->GetStart() == nHtStart &&
+                            nOtherWhich == nWhich &&
+                            pOther->GetAttr() == pHint->GetAttr() )
+                        {
+                            // Gibts schon, alten raus.
+                            if( pHistory )
+                                pHistory->Add( pOther );
+                            rNode.DestroyAttr( Cut(i) );
+                        }
+                        else
+                            ++i;
+                        continue;
+                    }
+                    else
+                    {
+                    // Attribute mit Anfang und Ende.
+                        const Range aHintRg( nHtStart, nHtEnd );
+                        const Range aOtherRg( *pOther->GetStart(),
+                                                *pOther->GetEnd() );
+
+                        if( aOtherRg.IsInside( aHintRg.Min() )
+                            || aHintRg.IsInside( aOtherRg.Min() ) )
+                        {
+                            // aBig umspannt beide Ranges
+                            const Range aBig( Min( aHintRg.Min(), aOtherRg.Min()),
+                                              Max( aHintRg.Max(), aOtherRg.Max()));
+
+                            // Gleiches Attribut
+                            // oder Zeichenvorlage:
+                            //      Bereiche duerfen nicht ueberlappen.
+
+                            // Zuerst wurde geprueft, ob sich der neue mit dem
+                            // alten ueberschneidet, danach gibt es nur noch
+                            // drei Faelle zu beachten:
+                            // 1) der neue umschliesst den alten
+                            // 2) der neue ueberlappt den alten hinten
+                            // 3) der neue ueberlappt den alten vorne
+
+                            BOOL bNoINet = RES_TXTATR_INETFMT != nOtherWhich ||
+                                           nWhich == nOtherWhich;
+
+                            // 1) der neue umschliesst den alten
+                            if( aBig == aHintRg )
+                            {
+                                BOOL bTmpReplace = bReplace ||
+                                    ( aHintRg == aOtherRg &&
+                                      nWhich == nOtherWhich &&
+                                      RES_TXTATR_CHARFMT != nWhich &&
+                                      RES_TXTATR_INETFMT != nWhich );
+                                if( bNoINet && bTmpReplace &&
+                                    ( !bCharFmt || nWhich == nOtherWhich ) )
+                                {
+                                    if( !bCheckInclude ||
+                                        lcl_Included( nOtherWhich, pHint ) )
+                                    {
+                                        if( pHistory ) pHistory->Add( pOther );
+                                        rNode.DestroyAttr( Cut(i) );
+                                    }
+                                    else
+                                        ++i;
+                                    continue;
+                                }
+                            }
+                            else if( !bReplace && aBig == aOtherRg )
+                                bForgetAttr = FALSE;
+                            // 2) der neue ueberlappt hinten
+                            else if( aBig.Max() == aHintRg.Max() )
+                            {
+                                if( bNoINet &&
+                                    ( !bCharFmt || RES_TXTATR_CHARFMT != nWhich ) &&
+                                    ( bReplace || aHintRg.Max() != aOtherRg.Max() ) )
+                                {
+                                    if( ( bCheckInclude &&
+                                          lcl_Included( nOtherWhich, pHint ) ) ||
+                                          ( !bCheckInclude && !bCharFmt ) )
+                                    {
+                                        if( nMaxEnd == nHtStart )
+                                            bForgetAttr = FALSE;
+                                        if( pHistory ) pHistory->Add( pOther );
+                                        *pOther->GetEnd() = nHtStart;
+                                        if( pHistory ) pHistory->Add( pOther, TRUE );
+                                        // ChainDelEnd( pOther );
+                                        // ChainEnds( pOther );
+                                    }
+                                    else if( bINet &&
+                                             aHintRg.Max() != aOtherRg.Max() &&
+                                             aHintRg.Min() < aOtherRg.Max() )
+                                    {
+                                    // Wenn ein INetFmt eingefuegt wird, muss
+                                    // sich ein anderes Attribut ggf. aufspal-
+                                    // ten. Es wird beiseite gestellt und in
+                                    // einem spaeteren Durchgang eingefuegt.
+                                    // Beim Einfuegen spaltet es sich selbst.
+                                        if( pHistory ) pHistory->Add( pOther );
+                                        if( !pTmpHints )
+                                            pTmpHints = new SwpHtStart_SAR();
+                                        pTmpHints->C40_INSERT( SwTxtAttr, pOther,
+                                            pTmpHints->Count() );
+                                        Cut( i );
+                                        continue;
+                                    }
+                                }
+                            }
+                            else
+                            // 3) der neue ueberlappt vorne
+                            if( aBig.Min() == aHintRg.Min() )
+                            {
+                                if( bNoINet &&
+                                    ( RES_TXTATR_CHARFMT != nOtherWhich ||
+                                      RES_TXTATR_CHARFMT != nWhich ) &&
+                                    ( bReplace || aHintRg.Min() != aOtherRg.Min() ) )
+                                {
+                                    if( ( bCheckInclude &&
+                                          lcl_Included( nOtherWhich, pHint ) ) ||
+                                        ( !bCheckInclude && !bCharFmt ) )
+                                    {
+                                        if( pHistory ) pHistory->Add( pOther );
+
+                                        *pOther->GetStart() = nHtEnd;
+
+                                        if( pHistory ) pHistory->Add( pOther, TRUE );
+                                        // ChainDelStart( pOther );
+                                        // ChainStarts( pOther );
+
+                                        // nehme die History weg, damit beim Resort
+                                        // nicht doppelt eingetragen wird!
+
+                                        SwRegHistory * pSave = pHistory;
+                                        pHistory = 0;
+                                        const BOOL bOk = Resort(i);
+                                        pHistory = pSave;
+                                        if( bOk )
+                                            continue;
+                                    }
+                                    else if( bINet &&
+                                             aHintRg.Min() != aOtherRg.Min() &&
+                                             aHintRg.Max() > aOtherRg.Min() )
+                                    {
+                                    // Wenn ein INetFmt eingefuegt wird, muss
+                                    // sich ein anderes Attribut ggf. aufspal-
+                                    // ten. Es wird beiseite gestellt und in
+                                    // einem spaeteren Durchgang eingefuegt.
+                                    // Beim Einfuegen spaltet es sich selbst.
+                                        if( pHistory ) pHistory->Add( pOther );
+                                        if( !pTmpHints )
+                                            pTmpHints = new SwpHtStart_SAR();
+                                        pTmpHints->C40_INSERT( SwTxtAttr, pOther,
+                                            pTmpHints->Count() );
+                                        Cut( i );
+                                        continue;
+                                    }
+                                }
+                            }
+                            else
+                                bForgetAttr = FALSE;
+                        }
+                    }
+                }
+                ++i;
+            }
+
+            ClearDummies( rNode );
+            // Nur wenn wir nicht sowieso schon durch die Absatzattribute
+            // gueltig sind, werden wir eingefuegt ...
+            if( bForgetAttr )
+                rNode.DestroyAttr( pHint );
+            else
+            {
+                SwpHintsArr::Insert( pHint );
+                if ( pHistory )
+                    pHistory->Add( pHint, TRUE );
+            }
+            // InsertChain( pHint );
+
+            // ... und die Abhaengigen benachrichtigen
+            if ( rNode.GetDepends() )
+            {
+                SwUpdateAttr aHint( nHtStart, nHtEnd, nWhich );
+                rNode.Modify( 0, &aHint );
+            }
+            // Falls es noch 'ne Runde gibt:
+            nHtStart = nHtEnd;
+            if( nMaxEnd > nHtEnd )
+                continue;
+            if( !pTmpHints )
+                break;
+            pHint = pTmpHints->GetObject(0);
+            nWhich = pHint->Which();
+            nHtStart = *pHint->GetStart();
+            nHtEnd = *pHint->GetEnd();
+            nMaxEnd = nHtEnd;
+            bParaAttr = FALSE;
+            pTmpHints->Remove(0);
+            if( !pTmpHints->Count() )
+            {
+                delete pTmpHints;
+                pTmpHints = NULL;
+            }
+        } while ( TRUE );
+
+        // Jetzt wollen wir mal gucken, ob wir das SwpHintsArray nicht
+        // etwas vereinfachen koennen ...
+        Merge( rNode );
+    }
+    else
+    {
+        SwpHintsArr::Insert( pHint );
+        if ( pHistory )
+            pHistory->Add( pHint, TRUE );
+        // InsertChain( pHint );
+
+        // ... und die Abhaengigen benachrichtigen
+        if ( rNode.GetDepends() )
+        {
+            SwUpdateAttr aHint( nHtStart,
+                nHtStart == *pHtEnd ? *pHtEnd + 1 : *pHtEnd, nWhich );
+            rNode.Modify( 0, &aHint );
+        }
+    }
+}
+
+/*************************************************************************
+ *                      SwpHints::DeleteAtPos()
+ *************************************************************************/
+
+void SwpHints::DeleteAtPos( const USHORT nPos )
+{
+    SwTxtAttr *pHint = GetHt(nPos);
+    // ChainDelete( pHint );
+    if( pHistory ) pHistory->Add( pHint );
+    SwpHintsArr::DeleteAtPos( nPos );
+
+/* Node-Pointer werden im DTOR noch benutzt !!
+    switch( pHint->Which() )            // Node-Pointer zuruecksetzen
+    {
+    case RES_TXTATR_CHARFMT:
+            ((SwTxtCharFmt*)pHint)->ChgTxtNode( 0 );
+            break;
+    case RES_TXTATR_FIELD:
+            ((SwTxtFld*)pHint)->ChgTxtNode( 0 );
+            break;
+    case RES_TXTATR_FTN :
+            ((SwTxtFtn*)pHint)->ChgTxtNode( 0 );
+            break;
+    case RES_TXTATR_REFMARK:
+            ((SwTxtRefMark*)pHint)->ChgTxtNode( 0 );
+            break;
+    }
+*/
+    if( RES_TXTATR_FIELD == pHint->Which() )
+    {
+        SwFieldType* pFldTyp = ((SwTxtFld*)pHint)->GetFld().GetFld()->GetTyp();
+        if( RES_DDEFLD == pFldTyp->Which() )
+        {
+            const SwTxtNode* pNd = ((SwTxtFld*)pHint)->GetpTxtNode();
+            if( pNd && pNd->GetNodes().IsDocNodes() )
+                ((SwDDEFieldType*)pFldTyp)->DecRefCnt();
+            ((SwTxtFld*)pHint)->ChgTxtNode( 0 );
+        }
+        else if( !bVis && RES_HIDDENPARAFLD == pFldTyp->Which() )
+            bCalcVis = TRUE;
+    }
+    CalcFlags();
+    CHECK;
+}
+
+// Ist der Hint schon bekannt, dann suche die Position und loesche ihn.
+// Ist er nicht im Array, so gibt es ein ASSERT !!
+
+void SwpHints::Delete( SwTxtAttr* pTxtHt )
+{
+    // Attr 2.0: SwpHintsArr::Delete( pTxtHt );
+    const USHORT nPos = GetStartOf( pTxtHt );
+    ASSERT( USHRT_MAX != nPos, "Attribut nicht im Attribut-Array!" );
+    if( USHRT_MAX != nPos )
+        DeleteAtPos( nPos );
+}
+
+void SwTxtNode::ClearSwpHintsArr( int bDelAll, int bDelFields )
+{
+    if( pSwpHints )
+    {
+        USHORT nPos = 0;
+        while( nPos < pSwpHints->Count() )
+        {
+            SwTxtAttr* pDel = pSwpHints->GetHt( nPos );
+            BOOL bDel = bDelAll;
+            if( !bDelAll )
+                switch( pDel->Which() )
+                {
+                case RES_TXTATR_FLYCNT:
+                case RES_TXTATR_FTN:
+                    break;
+
+                case RES_TXTATR_FIELD:
+                case RES_TXTATR_HARDBLANK:
+                    if( bDelFields )
+                        bDel = TRUE;
+                    break;
+                default:
+                    bDel = TRUE; break;
+                }
+            if( bDel )
+            {
+                pSwpHints->SwpHintsArr::DeleteAtPos( nPos );
+                DestroyAttr( pDel );
+            }
+            else
+                ++nPos;
+        }
+    }
+}
+
+FASTBOOL SwTxtNode::IsInSymbolFont( xub_StrLen nPos ) const
+{
+    SfxItemSet aSet( (SfxItemPool&)GetDoc()->GetAttrPool(),
+                    RES_CHRATR_FONT, RES_CHRATR_FONT );
+    if( GetAttr( aSet, nPos, nPos ))
+        return RTL_TEXTENCODING_SYMBOL == ((SvxFontItem&)aSet.Get( RES_CHRATR_FONT ))
+                                    .GetCharSet();
+    return FALSE;
+
+//JP 07.10.95: waere so auch nicht schlecht!
+//  SwTxtFrmInfo aFInfo( GetFrm() );
+//  return aFInfo.IsBullet( nPos );
+}
+
+
+USHORT SwTxtNode::GetLang( const xub_StrLen nBegin, const xub_StrLen nLen) const
+{
+    USHORT nRet = pSwpHints ? pSwpHints->GetLang( nBegin, nLen )
+                            : LANGUAGE_DONTKNOW;
+
+    if( LANGUAGE_DONTKNOW == nRet )
+        nRet = GetSwAttrSet().GetLanguage().GetLanguage();
+    return nRet;
+}
+
+
+sal_Unicode GetCharOfTxtAttr( const SwTxtAttr& rAttr )
+{
+    sal_Unicode cRet = CH_TXTATR_BREAKWORD;
+    switch ( rAttr.Which() )
+    {
+    case RES_TXTATR_REFMARK:
+    case RES_TXTATR_TOXMARK:
+
+//  case RES_TXTATR_FIELD:          ??????
+//  case RES_TXTATR_FLYCNT,                             // 29
+
+    case RES_TXTATR_FTN:
+        cRet = CH_TXTATR_INWORD;
+        break;
+
+        // depends on the character ??
+//  case RES_TXTATR_HARDBLANK:
+//      cRet = CH_TXTATR_INWORD;
+//      break;
+    }
+    return cRet;
+}
+
+
diff --git a/sw/source/core/txtnode/txatbase.cxx b/sw/source/core/txtnode/txatbase.cxx
new file mode 100644
index 000000000000..f21dddff8041
--- /dev/null
+++ b/sw/source/core/txtnode/txatbase.cxx
@@ -0,0 +1,130 @@
+/*************************************************************************
+ *
+ *  $RCSfile: txatbase.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:27 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "swtypes.hxx"
+
+#ifndef _SFXITEMPOOL_HXX //autogen
+#include 
+#endif
+#include "txatbase.hxx"
+
+SwTxtAttr::~SwTxtAttr( )
+{
+}
+
+SwTxtAttr::SwTxtAttr( const SfxPoolItem& rAttr, xub_StrLen nStt )
+    : pAttr( &rAttr ), nStart( nStt )
+{
+    bDontExpand = FALSE;
+}
+
+xub_StrLen* SwTxtAttr::GetEnd()
+{
+    return 0;
+}
+
+    // RemoveFromPool muss immer vorm DTOR Aufruf erfolgen!!
+    // Meldet sein Attribut beim Pool ab
+void SwTxtAttr::RemoveFromPool( SfxItemPool& rPool )
+{
+    rPool.Remove( GetAttr() );
+    pAttr = 0;
+}
+
+int SwTxtAttr::operator==( const SwTxtAttr& rAttr ) const
+{
+    return GetAttr()  == rAttr.GetAttr();
+}
+
+void SwTxtAttr::ChgFnt(SwFont *)
+{
+}
+
+void SwTxtAttr::RstFnt(SwFont *)
+{
+}
+
+SwTxtAttrEnd::SwTxtAttrEnd( const SfxPoolItem& rAttr, xub_StrLen nS,
+    xub_StrLen nE ) : SwTxtAttr( rAttr, nS ), nEnd( nE )
+{
+}
+
+void SwTxtAttr::ChgTxtAttr( SwTxtAttr & )
+{
+}
+
+void SwTxtAttr::RstTxtAttr( SwTxtAttr & )
+{
+}
+
+xub_StrLen* SwTxtAttrEnd::GetEnd()
+{
+    return &nEnd;
+}
+
+
+
diff --git a/sw/source/core/txtnode/txtatr2.cxx b/sw/source/core/txtnode/txtatr2.cxx
new file mode 100644
index 000000000000..0d4c6b8a6b45
--- /dev/null
+++ b/sw/source/core/txtnode/txtatr2.cxx
@@ -0,0 +1,630 @@
+/*************************************************************************
+ *
+ *  $RCSfile: txtatr2.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:27 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _SFX_OBJSH_HXX //autogen
+#include 
+#endif
+
+#ifndef _XMLOFF_XMLCNITM_HXX
+#include 
+#endif
+
+#ifndef _SVX_LANGITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_KERNITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_NHYPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BLNKITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_CMAPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_ESCPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BRSHITEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _TXTINET_HXX //autogen
+#include 
+#endif
+#ifndef _TXTATR_HXX //autogen
+#include 
+#endif
+#ifndef _FCHRFMT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTINFMT_HXX //autogen
+#include 
+#endif
+#ifndef _CHARATR_HXX
+#include 
+#endif
+#ifndef _FRMATR_HXX
+#include 
+#endif
+#ifndef _CHARFMT_HXX //autogen
+#include 
+#endif
+#ifndef _SWFONT_HXX
+#include 
+#endif
+#ifndef _FNTCACHE_HXX
+#include      // SwFntAccess
+#endif
+#ifndef _NDTXT_HXX
+#include         // SwCharFmt, SwTxtNode
+#endif
+#ifndef _HINTS_HXX
+#include         // SwCharFmt, SwUpdateAttr
+#endif
+#ifndef _POOLFMT_HXX
+#include       // RES_POOLCHR_INET_...
+#endif
+#ifndef _DOC_HXX
+#include           // SwDoc
+#endif
+
+TYPEINIT1(SwTxtINetFmt,SwClient);
+
+/*************************************************************************
+ *                      class SwTxtCharFmt
+ *************************************************************************/
+
+SwTxtCharFmt::~SwTxtCharFmt( )
+{
+    delete pPrevFont;
+    delete pPrevColor;
+}
+
+
+SwTxtCharFmt::SwTxtCharFmt( const SwFmtCharFmt& rAttr,
+                    xub_StrLen nStart, xub_StrLen nEnd )
+    : SwTxtAttrEnd( rAttr, nStart, nEnd ),
+    pMyTxtNd( 0 ),
+    pPrevFont( 0 ),
+    pPrevColor( 0 )
+{
+    ((SwFmtCharFmt&)rAttr).pTxtAttr = this;
+}
+
+void SwTxtCharFmt::ChgFnt( SwFont *pFont )
+{
+    SwCharFmt* pFmt = SwTxtAttrEnd::GetCharFmt().GetCharFmt();
+    if ( pFmt )
+    {
+        // Das 0 != bNew-Geraffel bringt M80 zum Schweigen
+        if ( pPrevFont )
+            *pPrevFont = pFont->GetFnt( SW_LATIN );
+        else
+            pPrevFont = new SvxFont( pFont->GetFnt( SW_LATIN ) );
+        bPrevNoHyph = pFont->IsNoHyph();
+        bPrevBlink = pFont->IsBlink();
+        bPrevURL = pFont->IsURL();
+        pFont->GetMagic( pFontNo, nFntIndex, SW_LATIN );
+        pFont->SetDiffFnt( &pFmt->GetAttrSet() );
+        delete pPrevColor;
+        bColor = SFX_ITEM_SET ==
+                 pFmt->GetAttrSet().GetItemState( RES_CHRATR_BACKGROUND, TRUE );
+        if( bColor )
+        {
+            pPrevColor = new Color( pFmt->GetChrBackground().GetColor() );
+            pPrevColor = pFont->XChgBackColor( pPrevColor );
+        }
+        else
+            pPrevColor = NULL;
+    }
+}
+
+void SwTxtCharFmt::RstFnt(SwFont *pFont)
+{
+    if ( pPrevFont )
+    {
+        // Das 0 != bNew-Geraffel bringt M80 zum Schweigen
+        pFont->SetFnt( *pPrevFont, SW_LATIN );
+        pFont->SetMagic( pFontNo, nFntIndex, SW_LATIN );
+        pFont->SetBlink( bPrevBlink );
+        pFont->SetNoHyph( bPrevNoHyph );
+        pFont->SetURL( bPrevURL );
+        if( bColor )
+        {
+            pFont->SetBackColor( pPrevColor );
+            pPrevColor = NULL;
+        }
+    }
+}
+
+void SwTxtCharFmt::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew )
+{
+    USHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
+#ifndef PRODUCT
+    if ( (nWhichRES_CHRATR_END)
+            && (nWhich!=RES_OBJECTDYING)
+            && (nWhich!=RES_ATTRSET_CHG)
+            && (nWhich!=RES_FMT_CHG) )
+        ASSERT(!this, "SwTxtCharFmt::Modify(): unbekanntes Modify!");
+#endif
+
+    if( pMyTxtNd )
+    {
+        SwUpdateAttr aUpdateAttr( *GetStart(), *GetEnd(), nWhich );
+        pMyTxtNd->SwCntntNode::Modify( &aUpdateAttr, &aUpdateAttr );
+    }
+}
+
+    // erfrage vom Modify Informationen
+BOOL SwTxtCharFmt::GetInfo( SfxPoolItem& rInfo ) const
+{
+    if( RES_AUTOFMT_DOCNODE != rInfo.Which() || !pMyTxtNd ||
+        &pMyTxtNd->GetNodes() != ((SwAutoFmtGetDocNode&)rInfo).pNodes )
+        return TRUE;
+
+    ((SwAutoFmtGetDocNode&)rInfo).pCntntNode = pMyTxtNd;
+    return FALSE;
+}
+
+/*************************************************************************
+ *                      class SwTxtINetFmt
+ *************************************************************************/
+
+SwTxtINetFmt::~SwTxtINetFmt( )
+{
+    delete pPrevFont;
+    delete pPrevBackColor;
+}
+
+
+SwTxtINetFmt::SwTxtINetFmt( const SwFmtINetFmt& rAttr,
+                            xub_StrLen nStart, xub_StrLen nEnd )
+    : SwTxtAttrEnd( rAttr, nStart, nEnd ),
+    SwClient( 0 ),
+    pMyTxtNd( 0 ),
+    pPrevFont( 0 ),
+    pPrevBackColor( 0 )
+{
+    bValidVis = FALSE;
+    ((SwFmtINetFmt&)rAttr).pTxtAttr  = this;
+}
+
+void SwTxtINetFmt::ChgFnt( SwFont *pFont )
+{
+    const SwCharFmt* pFmt = GetCharFmt();
+    if( pFmt )
+    {
+        // Das 0 != bNew-Geraffel bringt M80 zum Schweigen
+        if ( pPrevFont )
+            *pPrevFont = pFont->GetFnt( SW_LATIN );
+        else
+            pPrevFont = new SvxFont( pFont->GetFnt( SW_LATIN ) );
+        bPrevNoHyph = pFont->IsNoHyph();
+        bPrevBlink = pFont->IsBlink();
+        bPrevURL = pFont->IsURL();
+        pFont->GetMagic( pFontNo, nFntIndex, SW_LATIN );
+        pFont->SetDiffFnt( &pFmt->GetAttrSet() );
+        pFont->SetURL( TRUE );
+        delete pPrevBackColor;
+        bColor = SFX_ITEM_SET ==
+                 pFmt->GetAttrSet().GetItemState( RES_CHRATR_BACKGROUND, TRUE );
+        if( bColor )
+        {
+            pPrevBackColor = new Color( pFmt->GetChrBackground().GetColor() );
+            pPrevBackColor = pFont->XChgBackColor( pPrevBackColor );
+        }
+        else
+            pPrevBackColor = NULL;
+    }
+}
+
+SwCharFmt* SwTxtINetFmt::GetCharFmt()
+{
+    const SwFmtINetFmt& rFmt = SwTxtAttrEnd::GetINetFmt();
+    SwCharFmt* pRet = NULL;
+
+    if( rFmt.GetValue().Len() )
+    {
+        const SwDoc* pDoc = GetTxtNode().GetDoc();
+        if( !IsValidVis() )
+        {
+            SetVisited( pDoc->IsVisitedURL( rFmt.GetValue() ) );
+            SetValidVis( TRUE );
+        }
+        USHORT nId;
+        const String& rStr = IsVisited() ? rFmt.GetVisitedFmt()
+                                           : rFmt.GetINetFmt();
+        if( rStr.Len() )
+            nId = IsVisited() ? rFmt.GetVisitedFmtId() : rFmt.GetINetFmtId();
+        else
+            nId = IsVisited() ? RES_POOLCHR_INET_VISIT : RES_POOLCHR_INET_NORMAL;
+
+        // JP 10.02.2000, Bug 72806: dont modify the doc for getting the
+        //      correct charstyle.
+        BOOL bResetMod = !pDoc->IsModified();
+        Link aOle2Lnk;
+        if( bResetMod )
+        {
+            aOle2Lnk = pDoc->GetOle2Link();
+            ((SwDoc*)pDoc)->SetOle2Link( Link() );
+        }
+
+        pRet = IsPoolUserFmt( nId )
+                ? ((SwDoc*)pDoc)->FindCharFmtByName( rStr )
+                : ((SwDoc*)pDoc)->GetCharFmtFromPool( nId );
+
+        if( bResetMod )
+        {
+            ((SwDoc*)pDoc)->ResetModified();
+            ((SwDoc*)pDoc)->SetOle2Link( aOle2Lnk );
+        }
+    }
+
+    if( pRet )
+        pRet->Add( this );
+    else if( GetRegisteredIn() )
+        pRegisteredIn->Remove( this );
+
+    return pRet;
+}
+
+void SwTxtINetFmt::RstFnt(SwFont *pFont)
+{
+    const SwFmtINetFmt& rFmt = SwTxtAttrEnd::GetINetFmt();
+    if( pPrevFont && rFmt.GetValue().Len() )
+    {
+        // Das 0 != bNew-Geraffel bringt M80 zum Schweigen
+        pFont->SetFnt( *pPrevFont, SW_LATIN );
+        pFont->SetMagic( pFontNo, nFntIndex, SW_LATIN );
+        pFont->SetBlink( bPrevBlink );
+        pFont->SetNoHyph( bPrevNoHyph );
+        pFont->SetURL( bPrevURL );
+        if( bColor )
+        {
+            pFont->SetBackColor( pPrevBackColor );
+            pPrevBackColor = NULL;
+        }
+        delete pPrevFont;
+        pPrevFont = NULL;
+    }
+}
+
+void SwTxtINetFmt::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew )
+{
+    USHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
+#ifndef PRODUCT
+    if ( (nWhichRES_CHRATR_END)
+            && (nWhich!=RES_OBJECTDYING)
+            && (nWhich!=RES_ATTRSET_CHG)
+            && (nWhich!=RES_FMT_CHG) )
+        ASSERT(!this, "SwTxtCharFmt::Modify(): unbekanntes Modify!");
+#endif
+
+    if( pMyTxtNd )
+    {
+        SwUpdateAttr aUpdateAttr( *GetStart(), *GetEnd(), nWhich );
+        pMyTxtNd->SwCntntNode::Modify( &aUpdateAttr, &aUpdateAttr );
+    }
+}
+
+    // erfrage vom Modify Informationen
+BOOL SwTxtINetFmt::GetInfo( SfxPoolItem& rInfo ) const
+{
+    if( RES_AUTOFMT_DOCNODE != rInfo.Which() || !pMyTxtNd ||
+        &pMyTxtNd->GetNodes() != ((SwAutoFmtGetDocNode&)rInfo).pNodes )
+        return TRUE;
+
+    ((SwAutoFmtGetDocNode&)rInfo).pCntntNode = pMyTxtNd;
+    return FALSE;
+}
+
+BOOL SwTxtINetFmt::IsProtect( ) const
+{
+    return pMyTxtNd && pMyTxtNd->IsProtect();
+}
+
+/*************************************************************************
+ *                      class SwTxtEscapement
+ *************************************************************************/
+
+SwTxtEscapement::SwTxtEscapement( const SvxEscapementItem& rAttr,
+                    USHORT nStart, USHORT nEnd )
+    : SwTxtAttrEnd( rAttr, nStart, nEnd )
+{}
+
+void SwTxtEscapement::ChgFnt(SwFont *pFont)
+{
+    short nNewEsc   = GetEscapement().GetEsc();
+    BYTE  nNewPropr = GetEscapement().GetProp();
+    if( !nNewEsc )
+        nNewPropr = 100;
+    nPrevEsc   = pFont->GetEscapement();
+    nPrevPropr = pFont->GetPropr();
+    pFont->SetEscapement( nNewEsc );
+    pFont->SetProportion( nNewPropr );
+}
+
+void SwTxtEscapement::RstFnt(SwFont *pFont)
+{
+    pFont->SetEscapement( nPrevEsc );
+    pFont->SetProportion( nPrevPropr );
+}
+
+void SwTxtEscapement::ChgTxtAttr( SwTxtAttr &rAttr )
+{
+    nPrevEsc = ((SwTxtEscapement&)rAttr).nPrevEsc;
+    nPrevPropr = ((SwTxtEscapement&)rAttr).nPrevPropr;
+    short nNewEsc   = GetEscapement().GetEsc();
+    BYTE  nNewPropr = GetEscapement().GetProp();
+    if( !nNewEsc )
+        nNewPropr = 100;
+    ((SwTxtEscapement&)rAttr).nPrevEsc = nNewEsc;
+    ((SwTxtEscapement&)rAttr).nPrevPropr = nNewPropr;
+}
+
+void SwTxtEscapement::RstTxtAttr( SwTxtAttr &rAttr )
+{
+    ((SwTxtEscapement&)rAttr).nPrevEsc = nPrevEsc;
+    ((SwTxtEscapement&)rAttr).nPrevPropr = nPrevPropr;
+}
+
+/*************************************************************************
+ *                      class SwTxtCaseMap
+ *************************************************************************/
+
+SwTxtCaseMap::SwTxtCaseMap( const SvxCaseMapItem& rAttr,
+                    xub_StrLen nStart, xub_StrLen nEnd )
+    : SwTxtAttrEnd( rAttr, nStart, nEnd )
+{}
+
+void SwTxtCaseMap::ChgFnt(SwFont *pFont)
+{
+    ePrevCaseMap = pFont->GetCaseMap();
+    pFont->SetCaseMap( GetCaseMap().GetCaseMap() );
+}
+
+void SwTxtCaseMap::RstFnt(SwFont *pFont)
+{
+    pFont->SetCaseMap( ePrevCaseMap );
+}
+
+void SwTxtCaseMap::ChgTxtAttr( SwTxtAttr &rAttr )
+{
+    ePrevCaseMap = ((SwTxtCaseMap&)rAttr).ePrevCaseMap;
+    ((SwTxtCaseMap&)rAttr).ePrevCaseMap = GetCaseMap().GetCaseMap();
+}
+
+void SwTxtCaseMap::RstTxtAttr( SwTxtAttr &rAttr )
+{
+    ((SwTxtCaseMap&)rAttr).ePrevCaseMap = ePrevCaseMap;
+}
+
+/*************************************************************************
+ *                      class SwTxtBlink
+ *************************************************************************/
+
+SwTxtBlink::SwTxtBlink( const SvxBlinkItem& rAttr,
+                    xub_StrLen nStart, xub_StrLen nEnd )
+    : SwTxtAttrEnd( rAttr, nStart, nEnd )
+{}
+
+void SwTxtBlink::ChgFnt(SwFont *pFont)
+{
+    bPrev = pFont->IsBlink();
+    pFont->SetBlink( GetBlink().GetValue() );
+}
+
+void SwTxtBlink::RstFnt(SwFont *pFont)
+{
+    pFont->SetBlink( bPrev );
+}
+
+void SwTxtBlink::ChgTxtAttr( SwTxtAttr &rAttr )
+{
+    bPrev = ((SwTxtBlink&)rAttr).bPrev;
+    ((SwTxtBlink&)rAttr).bPrev = GetBlink().GetValue();
+}
+
+void SwTxtBlink::RstTxtAttr( SwTxtAttr &rAttr )
+{
+    ((SwTxtBlink&)rAttr).bPrev = bPrev;
+}
+
+/*************************************************************************
+ *                      class SwTxtBackground
+ *************************************************************************/
+
+SwTxtBackground::SwTxtBackground( const SvxBrushItem& rAttr,
+                    xub_StrLen nStart, xub_StrLen nEnd )
+    : SwTxtAttrEnd( rAttr, nStart, nEnd ),
+    pPrevColor( NULL )
+{
+}
+
+SwTxtBackground::~SwTxtBackground( )
+{
+    delete pPrevColor;
+}
+
+void SwTxtBackground::ChgFnt(SwFont *pFont)
+{
+    delete pPrevColor;
+    pPrevColor = new Color( GetChrBackground().GetColor() );
+    pPrevColor = pFont->XChgBackColor( pPrevColor );
+}
+
+void SwTxtBackground::RstFnt(SwFont *pFont)
+{
+    pFont->SetBackColor( pPrevColor );
+    pPrevColor = NULL;
+}
+
+void SwTxtBackground::ChgTxtAttr( SwTxtAttr &rAttr )
+{
+    delete pPrevColor;
+    pPrevColor = ((SwTxtBackground&)rAttr).pPrevColor;
+    ((SwTxtBackground&)rAttr).pPrevColor =
+        new Color( GetChrBackground().GetColor() );
+}
+
+void SwTxtBackground::RstTxtAttr( SwTxtAttr &rAttr )
+{
+    delete ((SwTxtBackground&)rAttr).pPrevColor;
+    ((SwTxtBackground&)rAttr).pPrevColor = pPrevColor;
+    pPrevColor = NULL;
+}
+
+/*************************************************************************
+ *                      class SwTxtNoHyphHere
+ *************************************************************************/
+
+SwTxtNoHyphenHere::SwTxtNoHyphenHere( const SvxNoHyphenItem& rAttr,
+                    xub_StrLen nStart, xub_StrLen nEnd )
+    : SwTxtAttrEnd( rAttr, nStart, nEnd )
+{}
+
+void SwTxtNoHyphenHere::ChgFnt(SwFont *pFont)
+{
+    bPrev = pFont->IsNoHyph();
+    pFont->SetNoHyph( GetNoHyphenHere().GetValue() );
+}
+
+void SwTxtNoHyphenHere::RstFnt(SwFont *pFont)
+{
+    pFont->SetNoHyph( bPrev );
+}
+
+/*************************************************************************
+ *                      class SwTxtKerning
+ *************************************************************************/
+
+SwTxtKerning::SwTxtKerning( const SvxKerningItem& rAttr,
+                    xub_StrLen nStart, xub_StrLen nEnd )
+    : SwTxtAttrEnd( rAttr, nStart, nEnd )
+{}
+
+void SwTxtKerning::ChgFnt( SwFont *pFont )
+{
+    const SvxKerningItem& rAttr = GetKerning();
+    nPrevKern = pFont->GetFixKerning();
+    pFont->SetFixKerning( rAttr.GetValue() );
+}
+
+void SwTxtKerning::RstFnt( SwFont *pFont )
+{
+    pFont->SetFixKerning( nPrevKern );
+}
+
+void SwTxtKerning::ChgTxtAttr( SwTxtAttr &rAttr )
+{
+    nPrevKern = ((SwTxtKerning&)rAttr).nPrevKern;
+    ((SwTxtKerning&)rAttr).nPrevKern = GetKerning().GetValue();
+}
+
+void SwTxtKerning::RstTxtAttr( SwTxtAttr &rAttr )
+{
+    ((SwTxtKerning&)rAttr).nPrevKern = nPrevKern;
+}
+
+/*************************************************************************
+ *                      class SwTxtLanguage
+ *************************************************************************/
+
+SwTxtLanguage::SwTxtLanguage( const SvxLanguageItem& rAttr,
+                    xub_StrLen nStart, xub_StrLen nEnd )
+    : SwTxtAttrEnd( rAttr, nStart, nEnd )
+{}
+
+void SwTxtLanguage::ChgFnt( SwFont *pFont )
+{
+    ePrevLang = pFont->GetLanguage( SW_LATIN );
+    pFont->SetLanguage( GetLanguage().GetLanguage(), SW_LATIN );
+}
+
+void SwTxtLanguage::RstFnt( SwFont *pFont )
+{
+    pFont->SetLanguage( ePrevLang, SW_LATIN );
+}
+
+
+// ATT_XNLCONTAINERITEM ******************************
+
+SwTxtXMLAttrContainer::SwTxtXMLAttrContainer(
+                            const SvXMLAttrContainerItem& rAttr,
+                            xub_StrLen nStart, xub_StrLen nEnd )
+    : SwTxtAttrEnd( rAttr, nStart, nEnd )
+{}
+
+
+
diff --git a/sw/source/core/txtnode/txtedt.cxx b/sw/source/core/txtnode/txtedt.cxx
new file mode 100644
index 000000000000..fb085c114078
--- /dev/null
+++ b/sw/source/core/txtnode/txtedt.cxx
@@ -0,0 +1,1040 @@
+/*************************************************************************
+ *
+ *  $RCSfile: txtedt.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:27 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+
+// So kann man die Linguistik-Statistik ( (Tmp-Path)\swlingu.stk ) aktivieren:
+//#define LINGU_STATISTIK
+#ifdef LINGU_STATISTIK
+    #include           // in SwLinguStatistik::DTOR
+    #include          // getenv()
+    #include            // clock()
+    #include "viewsh.hxx"       // ViewShell::GetHyphenator
+#endif
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _SVX_SPLWRAP_HXX
+#include 
+#endif
+#ifndef _SVX_LANGITEM_HXX //autogen
+#include 
+#endif
+#ifndef _WORDSEL_HXX //autogen
+#include 
+#endif
+#ifndef _LINGU_LNGPROPS_HHX_
+#include 
+#endif
+#ifndef _STRING_HXX
+#include 
+#endif
+
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
+#include 
+#endif
+
+#ifndef _COM_SUN_STAR_TEXT_WORDTYPE_HPP_
+#include 
+#endif
+
+#ifndef _SPLARGS_HXX
+#include 
+#endif
+#ifndef _VIEWSH_HXX
+#include    // ViewShell
+#endif
+#ifndef _VIEWOPT_HXX
+#include 
+#endif
+#ifndef _ACMPLWRD_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include       // GetDoc()
+#endif
+
+#include "frmsh.hxx"
+#ifndef _TXATBASE_HXX //autogen
+#include 
+#endif
+#ifndef _CHARATR_HXX
+#include 
+#endif
+#ifndef _FLDBAS_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _SPLARGS_HXX
+#include 
+#endif
+#ifndef _HINTS_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _TXTFRM_HXX
+#include 
+#endif
+#ifndef _WRONG_HXX
+#include 
+#endif
+#ifndef _SWFONT_HXX
+#include    // GetSystemLang
+#endif
+#include "txttypes.hxx"
+#include "breakit.hxx"
+#include "crstate.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::text;
+
+#define C2U(cChar) rtl::OUString::createFromAscii(cChar)
+
+// Wir ersparen uns in Hyphenate ein GetFrm()
+// Achtung: in edlingu.cxx stehen die Variablen!
+extern const SwTxtNode *pLinguNode;
+extern       SwTxtFrm  *pLinguFrm;
+
+
+/*
+ * Ein Zeichen wurde eingefuegt.
+ */
+
+
+
+SwTxtNode& SwTxtNode::Insert( xub_Unicode c, const SwIndex &rIdx )
+{
+    xub_StrLen nOrigLen = aText.Len();
+
+    ASSERT( rIdx <= nOrigLen, "Array ueberindiziert." );
+    ASSERT( nOrigLen < STRING_LEN, "USHRT_MAX ueberschritten." );
+
+    if( nOrigLen == aText.Insert( c, rIdx.GetIndex() ).Len() )
+        return *this;
+
+    Update(rIdx,1);
+
+    // leere Hints und Feldattribute an rIdx.GetIndex suchen
+    if( pSwpHints )
+    {
+        USHORT* pEndIdx;
+        for( USHORT i=0; i < pSwpHints->Count() &&
+                rIdx >= *(*pSwpHints)[i]->GetStart(); ++i)
+        {
+            SwTxtAttr *pHt = pSwpHints->GetHt(i);
+            if( 0 != ( pEndIdx = pHt->GetEnd()) )
+            {
+                // leere Hints an rIdx.GetIndex ?
+                BOOL bEmpty = *pEndIdx == *pHt->GetStart()
+                            && rIdx == *pHt->GetStart();
+
+                if( bEmpty )
+                {
+                    pSwpHints->DeleteAtPos(i);
+                    if( bEmpty )
+                        *pHt->GetStart() -= 1;
+                    else
+                        *pEndIdx -= 1;
+                    Insert(pHt);
+                }
+            }
+        }
+        if ( pSwpHints->CanBeDeleted() )
+            DELETEZ( pSwpHints );
+    }
+    // den Frames Bescheid sagen
+    SwInsChr aHint( rIdx.GetIndex()-1 );
+    SwModify::Modify( 0, &aHint );
+    return *this;
+}
+
+inline BOOL InRange(xub_StrLen nIdx, xub_StrLen nStart, xub_StrLen nEnd) {
+    return ((nIdx >=nStart) && (nIdx <= nEnd));
+}
+
+/*
+ * void SwTxtNode::RstAttr(const SwIndex &rIdx, USHORT nLen)
+ *
+ * loescht alle Attribute ab der Position rIdx ueber eine Laenge
+ * von nLen.
+ */
+
+/* 5 Faelle:
+ * 1) Das Attribut liegt vollstaendig im Bereich:
+ *    -> loeschen
+ * 2) Das Attributende liegt im Bereich:
+ *    -> Loeschen, mit neuem Ende einfuegen
+ * 3) Der Attributanfang liegt im Bereich:
+ *    -> Loeschen, mit neuem Anfang einfuegen
+ * 4) Das Attrib umfasst den Bereich:
+ *       Aufsplitten, d.h.
+ *    -> Loeschen, mit alten Anfang und Anfang des Bereiches einfuegen
+ *    -> Neues Attribut mit Ende des Bereiches und altem Ende einfuegen
+ * 5) Das Attribut liegt ausserhalb des Bereiches
+ *     -> nichts tun.
+ */
+
+
+
+void SwTxtNode::RstAttr(const SwIndex &rIdx, xub_StrLen nLen, USHORT nWhich,
+                        const SfxItemSet* pSet, BOOL bInclRefToxMark )
+{
+    // Attribute?
+    if ( !GetpSwpHints() )
+        return;
+
+    USHORT i = 0;
+    xub_StrLen nStart = rIdx.GetIndex();
+    xub_StrLen nEnd = nStart + nLen;
+    xub_StrLen *pAttrEnd;
+    xub_StrLen nAttrStart;
+    SwTxtAttr *pHt;
+
+    BOOL    bChanged = FALSE;
+
+    // nMin und nMax werden invers auf das Maximum bzw. Minimum gesetzt.
+    xub_StrLen nMin = aText.Len();
+    xub_StrLen nMax = nStart;
+
+    const BOOL bNoLen = !nMin;
+
+    // durch das Attribute-Array, bis der Anfang des Geltungsbereiches
+    // des Attributs hinter dem Bereich liegt
+    while( (i < pSwpHints->Count()) &&
+                ((( nAttrStart = *(*pSwpHints)[i]->GetStart()) < nEnd )
+                    || nLen==0) )
+    {
+        pHt = pSwpHints->GetHt(i);
+
+        // Attribute ohne Ende bleiben drin!
+        if ( 0 == (pAttrEnd=pHt->GetEnd()) )
+        {
+            i++;
+            continue;
+        }
+
+        // loesche alle TextAttribute die als Attribut im Set vorhanden sind
+        if( pSet ? SFX_ITEM_SET != pSet->GetItemState( pHt->Which(), FALSE )
+                 : ( nWhich ? nWhich != pHt->Which()
+                            : (!bInclRefToxMark &&
+                                ( RES_TXTATR_REFMARK == pHt->Which() ||
+                                RES_TXTATR_TOXMARK == pHt->Which() ))))
+        {
+            // Es sollen nur Attribute mit nWhich beachtet werden
+            i++;
+            continue;
+        }
+
+
+        if( nStart <= nAttrStart )          // Faelle: 1,3,5
+        {
+            if( nEnd > nAttrStart
+                || ( nEnd == *pAttrEnd && nEnd==nAttrStart ) )
+            {
+                // Faelle: 1,3
+                if ( nMin > nAttrStart )
+                    nMin = nAttrStart;
+                if ( nMax < *pAttrEnd )
+                    nMax = *pAttrEnd;
+                // Falls wir nur ein nichtaufgespanntes Attribut entfernen,
+                // tun wir mal so, als ob sich nichts geaendert hat.
+                bChanged = bChanged || nEnd > nAttrStart || bNoLen;
+                if( *pAttrEnd <= nEnd )     // Fall: 1
+                {
+                    pSwpHints->DeleteAtPos(i);
+                    DestroyAttr( pHt );
+
+                    // falls das letzte Attribut ein Field ist, loescht
+                    // dieses das HintsArray !!!
+                    if( !pSwpHints )
+                        break;
+
+                    //JP 26.11.96:
+                    // beim DeleteAtPos wird ein Resort ausgefuehrt!!
+                    // darum muessen wir wieder bei 0 anfangen!!!
+                    // ueber den Fall 3 koennen Attribute nach hinten
+                    // verschoben worden sein; damit stimmt jetzt das i
+                    // nicht mehr!!!
+                    i = 0;
+
+                    continue;
+                }
+                else                        // Fall: 3
+                {
+                    pSwpHints->NoteInHistory( pHt );
+                    *pHt->GetStart() = nEnd;
+                    pSwpHints->NoteInHistory( pHt, TRUE );
+                    bChanged = TRUE;
+                }
+            }
+        }
+        else                                // Faelle: 2,4,5
+            if( *pAttrEnd > nStart )        // Faelle: 2,4
+            {
+                if( *pAttrEnd < nEnd )      // Fall: 2
+                {
+                    if ( nMin > nAttrStart )
+                        nMin = nAttrStart;
+                    if ( nMax < *pAttrEnd )
+                        nMax = *pAttrEnd;
+                    bChanged = TRUE;
+                    pSwpHints->NoteInHistory( pHt );
+                    *pAttrEnd = nStart;
+                    pSwpHints->NoteInHistory( pHt, TRUE );
+                }
+                else if( nLen )             // Fall: 4
+                {       // bei Lange 0 werden beide Hints vom Insert(Ht)
+                        // wieder zu einem zusammengezogen !!!!
+                    if ( nMin > nAttrStart )
+                        nMin = nAttrStart;
+                    if ( nMax < *pAttrEnd )
+                        nMax = *pAttrEnd;
+                    bChanged = TRUE;
+                    xub_StrLen nTmpEnd = *pAttrEnd;
+                    pSwpHints->NoteInHistory( pHt );
+                    *pAttrEnd = nStart;
+                    pSwpHints->NoteInHistory( pHt, TRUE );
+
+                    if( nEnd < nTmpEnd &&
+                        !pSwpHints->Forget( i, pHt->Which(), nEnd, nTmpEnd ) )
+                    {
+                        Insert( pHt->GetAttr(), nEnd, nTmpEnd,
+                                SETATTR_NOHINTADJUST );
+                        // jetzt kein i+1, weil das eingefuegte Attribut
+                        // ein anderes auf die Position geschoben hat !
+                        continue;
+                    }
+                }
+            }
+        ++i;
+    }
+
+    if ( pSwpHints && pSwpHints->CanBeDeleted() )
+        DELETEZ( pSwpHints );
+    if(bChanged)
+    {
+        if ( pSwpHints )
+        {
+            pSwpHints->ClearDummies( *this );
+            ((SwpHintsArr*)pSwpHints)->Resort();
+            pSwpHints->Merge( *this );
+        }
+        //TxtFrm's reagieren auf aHint, andere auf aNew
+        SwUpdateAttr aHint( nMin, nMax, 0 );
+        SwModify::Modify( 0, &aHint );
+        SwFmtChg aNew( GetFmtColl() );
+        SwModify::Modify( 0, &aNew );
+    }
+}
+
+
+
+/*************************************************************************
+ *                SwTxtNode::GetCurWord()
+ *
+ * Aktuelles Wort zurueckliefern:
+ * Wir suchen immer von links nach rechts, es wird also das Wort
+ * vor nPos gesucht. Es sei denn, wir befinden uns am Anfang des
+ * Absatzes, dann wird das erste Wort zurueckgeliefert.
+ * Wenn dieses erste Wort nur aus Whitespaces besteht, returnen wir
+ * einen leeren String.
+ *************************************************************************/
+
+
+
+XubString SwTxtNode::GetCurWord( xub_StrLen nPos )
+{
+    ASSERT( nPos<=aText.Len() , "SwTxtNode::GetCurWord: Pos hinter String?");
+    xub_StrLen nTxtLen = aText.Len();
+    if( !nTxtLen )
+        return aText;
+
+    xub_StrLen nBegin, nLen;
+
+    nBegin = WordSelection::GoStartWord( aText, nPos );
+    if( STRING_NOTFOUND == nBegin )
+    {
+        nBegin = 0;
+        nLen = 0;
+    }
+    else
+    {
+        nLen = WordSelection::GoEndWord( aText, nBegin ) - nBegin;
+
+        if( IsSymbol( nBegin ) )
+            nLen = 0;
+        else
+        {
+            // Sonderbehandlung von > ' <, z.B. doesn't
+            xub_StrLen nNewBegin = nBegin + nLen;
+            if ( nNewBegin < nTxtLen && '\'' == aText.GetChar( nNewBegin ) )
+            {
+                // ist das Zeichen hinter dem Wort ein > ' <
+                // dann eventuell das Wort verlaengern
+                xub_StrLen nNewLen;
+                nNewLen = WordSelection::GoEndWord( aText, nNewBegin );
+                nNewBegin = WordSelection::GoStartWord( aText, nNewLen );
+                if( STRING_NOTFOUND != nNewBegin )
+                {
+                    nNewLen -= nNewBegin;
+                    if( nNewBegin == nBegin + nLen + 1 )
+                        nLen += nNewLen + 1;
+                }
+            }
+        }
+    }
+    return aText.Copy( nBegin, nLen );
+}
+
+
+void SwTxtNode::SetWrong( SwWrongList *pNew )
+{
+    delete pWrong;
+    pWrong = pNew;
+}
+
+/*************************************************************************
+ *                class SwScanner
+ * Hilfsklasse, die beim Spellen die Worte im gewuenschten Bereich
+ * nacheinander zur Verfuegung stellt.
+ *************************************************************************/
+
+class SwScanner
+{
+    XubString aWord;
+    const SwWrongList* pWrong;
+    SwTxtNode* pNode;
+    xub_StrLen nEndPos;
+    xub_StrLen nBegin;
+    xub_StrLen nLen;
+    BOOL bReverse;
+    BOOL bStart;
+public:
+    SwScanner( SwTxtNode* pNd, const SwWrongList* pWrng, xub_StrLen nStart,
+                xub_StrLen nEnde, BOOL bRev );
+    BOOL NextWord( LanguageType aLang );
+    const XubString& GetWord() const    { return aWord; }
+    xub_StrLen GetBegin() const         { return nBegin; }
+    xub_StrLen GetEnd() const           { return nBegin + nLen; }
+    xub_StrLen GetLen() const           { return nLen; }
+};
+
+
+
+SwScanner::SwScanner( SwTxtNode* pNd, const SwWrongList* pWrng,
+                        xub_StrLen nStart, xub_StrLen nEnde, BOOL bRev )
+    : pNode( pNd ), pWrong( pWrng ), nLen( 0 ), bReverse( bRev ), bStart( TRUE )
+{
+    ASSERT( pNode->GetTxt().Len(), "SwScanner: EmptyString" );
+    if( bReverse )
+    {
+        nBegin = nEnde;
+        nEndPos = nStart;
+    }
+    else
+    {
+        nBegin = nStart;
+        nEndPos = nEnde;
+    }
+}
+
+BOOL SwScanner::NextWord( LanguageType aLang )
+{
+    const XubString& rText = pNode->GetTxt();
+    if( bReverse )
+    {
+        if( nBegin )
+        {
+            --nBegin;
+            if( pNode->GetpSwpHints() )
+            {
+                while( CH_TXTATR_BREAKWORD == rText.GetChar( nBegin ) ||
+                        CH_TXTATR_INWORD == rText.GetChar( nBegin ) )
+                {
+                    if( pNode->GetTxtAttr( nBegin ) )
+                    {
+                        if( nBegin )
+                            --nBegin;
+                        else
+                            return FALSE;
+                    }
+                    else
+                        break;
+                }
+            }
+        }
+        else
+            return FALSE;
+    }
+    else if( nBegin + nLen >= rText.Len() )
+        return FALSE;
+
+    if( pWrong )
+    {
+        nBegin = bReverse ? pWrong->LastWrong( nBegin )
+                          : pWrong->NextWrong( nBegin );
+        if( STRING_LEN == nBegin )
+            return FALSE;
+    }
+
+
+    Boundary aBound;
+    if( bStart )
+    {
+        aBound = pBreakIt->xBreak->getWordBoundary( rText, nBegin,
+            pBreakIt->GetLocale( aLang ), WordType::DICTIONARY_WORD, !bReverse );
+        bStart = aBound.startPos != aBound.endPos;
+        if( bStart )
+        {
+            if( bReverse )
+            {
+                if( nEndPos > aBound.startPos )
+                    nEndPos = aBound.startPos;
+            }
+            else if( nEndPos < aBound.endPos && nEndPos > aBound.startPos )
+                nEndPos = aBound.endPos;
+        }
+    }
+    if( !bStart )
+    {
+        if( bReverse )
+            aBound = pBreakIt->xBreak->previousWord( rText, nBegin,
+                    pBreakIt->GetLocale( aLang ), WordType::DICTIONARY_WORD );
+        else
+            aBound = pBreakIt->xBreak->nextWord( rText, nBegin,
+                    pBreakIt->GetLocale( aLang ), WordType::DICTIONARY_WORD );
+    }
+    else
+        bStart = FALSE;
+
+    nBegin = aBound.startPos;
+    nLen = aBound.endPos - nBegin;
+
+    aWord = rText.Copy( nBegin, nLen );
+    if( bReverse )
+    {
+        if( nBegin < nEndPos )
+            return FALSE;
+    }
+    else
+    {
+        if( nBegin + nLen > nEndPos )
+            return FALSE;
+    }
+    return TRUE;
+}
+
+USHORT SwTxtNode::Spell(SwSpellArgs* pArgs)
+{
+    // Die Aehnlichkeiten zu SwTxtFrm::_AutoSpell sind beabsichtigt ...
+    // ACHTUNG: Ev. Bugs in beiden Routinen fixen!
+
+    LanguageType eFmtLang = GetSwAttrSet().GetLanguage().GetLanguage();
+
+    BOOL bCheck = FALSE;
+    BOOL bNoLang = FALSE;
+    uno::Reference xProp( GetLinguPropertySet() );
+    BOOL bReverse = xProp.is() ?
+        *(sal_Bool*)xProp->getPropertyValue( C2U(UPN_IS_WRAP_REVERSE) ).getValue() : FALSE;
+
+    xub_StrLen nBegin, nEnd;
+
+    if ( pArgs->pStartNode != this )
+        nBegin = 0;
+    else
+        nBegin = pArgs->rStartIdx.GetIndex();
+
+    if ( pArgs->pEndNode != this )
+        nEnd = aText.Len();
+    else
+        nEnd = pArgs->rEndIdx.GetIndex();
+
+    pArgs->xSpellAlt = NULL;
+
+    if( ( IsWrongDirty() || GetWrong() ) && aText.Len() )
+    {
+        if( nBegin > aText.Len() )
+            nBegin = aText.Len();
+        if( nEnd > aText.Len() )
+            nEnd = aText.Len();
+        LanguageType eActLang = GetLang( nBegin );
+        SwScanner aScanner( this, GetWrong(), nBegin, nEnd, bReverse );
+        while( !pArgs->xSpellAlt.is() && aScanner.NextWord( eActLang ) )
+        {
+            const XubString& rWord = aScanner.GetWord();
+
+            if ( (USHORT)(eActLang=(LanguageType)GetLang(aScanner.GetBegin(),
+                          rWord.Len())) == USHRT_MAX )
+                eActLang=eFmtLang;
+
+            if( eActLang == LANGUAGE_SYSTEM )
+                eActLang = ::GetSystemLang();
+
+            if( rWord.Len() > 1 )
+            {
+                // Sobald bCheck gesetzt ist, hat eine echte Pruefung stattgefunden,
+                // solange dies nicht der Fall ist, bedeutet ein gesetztes bNoLang,
+                // dass ein Wort mit [Keine] "ueberprueft" wurde. Sollte dieses Flag
+                // am Ende des zu pruefenden Abschnitts immer noch gesetzt sein, wird
+                // der Anwender auf seinen Fehler hingewiesen.
+                if ( !bCheck )
+                {
+                    if ( eActLang == LANGUAGE_NONE )
+                        bNoLang = TRUE;
+                    else
+                    {
+                        bCheck = TRUE;
+                        bNoLang = FALSE;
+                    }
+                }
+
+                if (pArgs->xSpeller.is())
+                {
+                    SvxSpellWrapper::CheckSpellLang( pArgs->xSpeller, eActLang );
+                    pArgs->xSpellAlt = pArgs->xSpeller->spell( rWord, eActLang );
+                }
+                if( (pArgs->xSpellAlt).is() )
+                {
+                    if( IsSymbol( aScanner.GetBegin() ) )
+                    {
+                        pArgs->xSpellAlt = NULL;
+                    }
+                    else
+                    {
+                        pArgs->pStartNode = this;
+                        pArgs->pEndNode = this;
+                        pArgs->rStartIdx.Assign(this, aScanner.GetEnd() );
+                        pArgs->rEndIdx.Assign(this, aScanner.GetBegin() );
+                    }
+                }
+            }
+        }
+    }
+
+    return pArgs->xSpellAlt.is() ? 1 : 0;
+}
+
+SwRect SwTxtFrm::_AutoSpell( SwCntntNode* pActNode, xub_StrLen nActPos )
+{
+    SwRect aRect;
+#ifdef DEBUG
+    static BOOL bStop = FALSE;
+    if ( bStop )
+        return aRect;
+#endif
+    // Die Aehnlichkeiten zu SwTxtNode::Spell sind beabsichtigt ...
+    // ACHTUNG: Ev. Bugs in beiden Routinen fixen!
+    SwTxtNode *pNode = GetTxtNode();
+    if( pNode != pActNode || !nActPos )
+        nActPos = STRING_LEN;
+
+    SwAutoCompleteWord& rACW = pNode->GetDoc()->GetAutoCompleteWords();
+
+    LanguageType eFmtLang = pNode->GetSwAttrSet().GetLanguage().GetLanguage();
+
+    const XubString& rTxt = pNode->aText;
+
+    xub_StrLen nBegin;
+    xub_StrLen nEnd;
+    xub_StrLen nLen;
+    xub_StrLen nInsertPos = pNode->aText.Len();
+    xub_StrLen nChgStart = STRING_LEN;
+    xub_StrLen nChgEnd = 0;
+    xub_StrLen nInvStart = STRING_LEN;
+    xub_StrLen nInvEnd = 0;
+
+    BOOL bAddAutoCmpl = pNode->IsAutoCompleteWordDirty() &&
+                        GetShell()->GetViewOptions()->IsAutoCompleteWords();
+
+    if( pNode->GetWrong() )
+    {
+        if( STRING_LEN != ( nBegin = pNode->GetWrong()->GetBeginInv() ) )
+        {
+            nBegin = pNode->GetWrong()->GetBeginInv();
+            nEnd = pNode->GetWrong()->GetEndInv();
+            if ( nEnd > nInsertPos )
+                nEnd = nInsertPos;
+        }
+        else
+            nEnd = nInsertPos;
+        nInsertPos = pNode->GetWrong()->GetPos( nBegin );
+    }
+    else
+    {
+        nBegin = 0;
+        nEnd = nInsertPos;
+        nInsertPos = 0;
+    }
+
+    uno::Reference xSpell( GetSpellChecker() );
+
+    BOOL bFresh = nBegin < nEnd;
+    BOOL bACWDirty = FALSE;
+
+    if( nBegin < nEnd )
+    {
+        LanguageType eActLang = pNode->GetLang( nBegin );
+        SwScanner aScanner( pNode, NULL, nBegin, nEnd, FALSE );
+        while( aScanner.NextWord( eActLang ) )
+        {
+            const XubString& rWord = aScanner.GetWord();
+            nBegin = aScanner.GetBegin();
+            nLen = aScanner.GetLen();
+
+            if ( (USHORT)(eActLang=(LanguageType)pNode->GetLang(nBegin, nLen))
+                == USHRT_MAX )
+                eActLang = eFmtLang;
+
+            BOOL bSpell = TRUE;
+            BOOL bSoft = FALSE;
+            bSpell = xSpell.is() ? xSpell->hasLanguage( eActLang ) : FALSE;
+            if( bSpell && rWord.Len() > 1 )
+            {
+                // check for: bAlter => xHyphWord.is()
+                DBG_ASSERT(!bSpell || xSpell.is(), "NULL pointer");
+
+                if( !xSpell->isValid( rWord, eActLang ) )
+                {
+                    bACWDirty = TRUE;
+                    if( !pNode->GetWrong() )
+                    {
+                        pNode->SetWrong( new SwWrongList() );
+                        pNode->GetWrong()->SetInvalid( 0, nEnd );
+                    }
+                    if( pNode->GetWrong()->Fresh( nChgStart, nChgEnd,
+                        nBegin, nLen, nInsertPos, nActPos ) )
+                        pNode->GetWrong()->Insert( nBegin, nLen, nInsertPos++ );
+                    else
+                    {
+                        nInvStart = nBegin;
+                        nInvEnd = nBegin + nLen;
+                    }
+                }
+                else if( bAddAutoCmpl && rACW.GetMinWordLen() <= rWord.Len() )
+                    rACW.InsertWord( rWord );
+            }
+        }
+    }
+    if( pNode->GetWrong() )
+    {
+        if( bFresh )
+            pNode->GetWrong()->Fresh( nChgStart, nChgEnd,
+                                      nEnd, 0, nInsertPos, nActPos );
+        ViewShell *pSh = GetShell();
+        if( nChgStart < nChgEnd &&
+            (pSh && !GetShell()->GetViewOptions()->IsHideSpell()) )
+        {
+            SwNodeIndex aNdIdx( *pNode );
+            SwPosition aPos( aNdIdx, SwIndex( pNode, nChgEnd ) );
+            GetCharRect( aRect, aPos );
+            SwRect aTmp;
+            aPos = SwPosition( aNdIdx, SwIndex( pNode, nChgStart ) );
+            SwCrsrMoveState aTmpState( MV_NONE );
+            aTmpState.bDropIt = TRUE;
+            GetCharRect( aTmp, aPos, &aTmpState );
+            BOOL bSameFrame = TRUE;
+            SwTxtFrm* pStartFrm = this;
+            if( HasFollow() )
+            {
+                while( pStartFrm->HasFollow() &&
+                       nChgStart >= pStartFrm->GetFollow()->GetOfst() )
+                    pStartFrm = pStartFrm->GetFollow();
+                SwTxtFrm *pEndFrm = pStartFrm;
+                while( pEndFrm->HasFollow() &&
+                       nChgEnd >= pEndFrm->GetFollow()->GetOfst() )
+                    pEndFrm = pEndFrm->GetFollow();
+                if( pEndFrm != pStartFrm )
+                {
+                    bSameFrame = FALSE;
+                    aTmp.Left( pStartFrm->Frm().Left() );
+                    aTmp.Right( pStartFrm->Frm().Right() );
+                    aTmp.Bottom( pStartFrm->Frm().Bottom() );
+                    aRect.Top( pEndFrm->Frm().Top() );
+                    aRect.Left( pEndFrm->Frm().Left() );
+                    aRect.Right( pEndFrm->Frm().Right() );
+                    aRect.Union( aTmp );
+                    while( TRUE )
+                    {
+                        pStartFrm = pStartFrm->GetFollow();
+                        if( pStartFrm == pEndFrm )
+                            break;
+                        aRect.Union( pStartFrm->Frm() );
+                    }
+                }
+            }
+            if( bSameFrame )
+            {
+                if( aTmp.Top() == aRect.Top() )
+                    aRect.Left( aTmp.Left() );
+                else
+                {
+                    aRect.Left( pStartFrm->Frm().Left() );
+                    aRect.Right( pStartFrm->Frm().Right() );
+                    aRect.Top( aTmp.Top() );
+                }
+                if( aTmp.Height() > aRect.Height() )
+                    aRect.Height( aTmp.Height() );
+            }
+        }
+        pNode->GetWrong()->SetInvalid( nInvStart, nInvEnd );
+        pNode->SetWrongDirty( STRING_LEN != pNode->GetWrong()->GetBeginInv() );
+        if( !pNode->GetWrong()->Count() )
+            pNode->SetWrong( NULL );
+    }
+    else
+        pNode->SetWrongDirty( FALSE );
+
+    if( bAddAutoCmpl )
+        pNode->SetAutoCompleteWordDirty( FALSE );
+    return aRect;
+}
+
+// Wird vom CollectAutoCmplWords gerufen
+void SwTxtFrm::CollectAutoCmplWrds( SwCntntNode* pActNode, xub_StrLen nActPos,
+                                    BOOL bIsVisArea )
+{
+    SwTxtNode *pNode = GetTxtNode();
+    if( pNode != pActNode || !nActPos )
+        nActPos = STRING_LEN;
+
+    const XubString& rTxt = pNode->aText;
+    SwAutoCompleteWord& rACW = pNode->GetDoc()->GetAutoCompleteWords();
+
+    xub_StrLen nBegin = 0;
+    xub_StrLen nEnd = pNode->aText.Len();
+    xub_StrLen nLen;
+    BOOL bACWDirty = FALSE, bAnyWrd = FALSE;
+
+
+    if( nBegin < nEnd )
+    {
+        SwScanner aScanner( pNode, NULL, nBegin, nEnd, FALSE );
+        while( aScanner.NextWord( pNode->GetLang( nBegin ) ) )
+        {
+            nBegin = aScanner.GetBegin();
+            nLen = aScanner.GetLen();
+            if( rACW.GetMinWordLen() <= nLen )
+            {
+                const XubString& rWord = aScanner.GetWord();
+
+                if( nActPos < nBegin || ( nBegin + nLen ) < nActPos )
+                {
+// !!! ---> ggfs. das Flag bIsVisarea auswerten
+                    if( rACW.GetMinWordLen() <= rWord.Len() )
+                        rACW.InsertWord( rWord );
+// !!! ---> ggfs. das Flag bIsVisarea auswerten
+                    bAnyWrd = TRUE;
+                }
+                else
+                    bACWDirty = TRUE;
+            }
+        }
+    }
+
+    if( bAnyWrd && !bACWDirty )
+        pNode->SetAutoCompleteWordDirty( FALSE );
+}
+
+
+/*************************************************************************
+ *                      SwTxtNode::Hyphenate
+ *************************************************************************/
+// Findet den TxtFrm und sucht dessen CalcHyph
+
+
+
+BOOL SwTxtNode::Hyphenate( SwInterHyphInfo &rHyphInf )
+{
+    // Abkuerzung: am Absatz ist keine Sprache eingestellt:
+    if( LANGUAGE_NONE == USHORT( GetSwAttrSet().GetLanguage().GetLanguage() ) &&
+        USHRT_MAX == GetLang( 0, aText.Len() ) )
+    {
+        if( !rHyphInf.IsCheck() )
+            rHyphInf.SetNoLang( TRUE );
+        return FALSE;
+    }
+
+    if( pLinguNode != this )
+    {
+        pLinguNode = this;
+        pLinguFrm = (SwTxtFrm*)GetFrm( (Point*)(rHyphInf.GetCrsrPos()) );
+    }
+    SwTxtFrm *pFrm = pLinguFrm;
+    if( pFrm )
+        pFrm = pFrm->GetFrmAtOfst( rHyphInf.nStart );
+    else
+    {
+        // 4935: Seit der Trennung ueber Sonderbereiche sind Faelle
+        // moeglich, in denen kein Frame zum Node vorliegt.
+        // Also kein ASSERT!
+#ifdef DEBUG
+        ASSERT( pFrm, "!SwTxtNode::Hyphenate: can't find any frame" );
+#endif
+        return FALSE;
+    }
+
+    while( pFrm )
+    {
+        if( pFrm->Hyphenate( rHyphInf ) )
+        {
+            // Das Layout ist nicht robust gegen "Direktformatierung"
+            // (7821, 7662, 7408); vgl. layact.cxx,
+            // SwLayAction::_TurboAction(), if( !pCnt->IsValid() ...
+            pFrm->SetCompletePaint();
+            return TRUE;
+        }
+        pFrm = (SwTxtFrm*)(pFrm->GetFollow());
+        if( pFrm )
+        {
+            rHyphInf.nLen = rHyphInf.nLen - (pFrm->GetOfst() - rHyphInf.nStart);
+            rHyphInf.nStart = pFrm->GetOfst();
+        }
+    }
+    return FALSE;
+}
+
+#ifdef LINGU_STATISTIK
+
+// globale Variable
+SwLinguStatistik aSwLinguStat;
+
+
+void SwLinguStatistik::Flush()
+{
+    if ( !nWords )
+        return ;
+
+#ifndef MAC
+    static char *pLogName = 0;
+    const BOOL bFirstOpen = pLogName ? FALSE : TRUE;
+    if( bFirstOpen )
+    {
+        char *pPath = getenv( "TEMP" );
+        char *pName = "swlingu.stk";
+        if( !pPath )
+            pLogName = pName;
+        else
+        {
+            const int nLen = strlen(pPath);
+            // fuer dieses new wird es kein delete geben.
+            pLogName = new char[nLen + strlen(pName) + 3];
+            if(nLen && (pPath[nLen-1] == '\\') || (pPath[nLen-1] == '/'))
+                sprintf( pLogName, "%s%s", pPath, pName );
+            else
+                sprintf( pLogName, "%s/%s", pPath, pName );
+        }
+    }
+    SvFileStream aStream( pLogName, (bFirstOpen
+                                        ? STREAM_WRITE | STREAM_TRUNC
+                                        : STREAM_WRITE ));
+
+    if( !aStream.GetError() )
+    {
+        if ( bFirstOpen )
+            aStream << "\nLinguistik-Statistik\n";
+        aStream << endl << ++nFlushCnt << ". Messung\n";
+        aStream << "Rechtschreibung\n";
+        aStream << "gepruefte Worte: \t" << nWords << endl;
+        aStream << "als fehlerhaft erkannt:\t" << nWrong << endl;
+        aStream << "Alternativvorschlaege:\t" << nAlter << endl;
+        if ( nWrong )
+            aStream << "Durchschnitt:\t\t" << nAlter*1.0 / nWrong << endl;
+        aStream << "Dauer (msec):\t\t" << nSpellTime << endl;
+        aStream << "\nThesaurus\n";
+        aStream << "Synonyme gesamt:\t" << nSynonym << endl;
+        if ( nSynonym )
+            aStream << "Synonym-Durchschnitt:\t" <<
+                            nSynonym*1.0 / ( nWords - nNoSynonym ) << endl;
+        aStream << "ohne Synonyme:\t\t" << nNoSynonym << endl;
+        aStream << "Bedeutungen gesamt:\t" << nSynonym << endl;
+        aStream << "keine Bedeutungen:\t"<< nNoSynonym << endl;
+        aStream << "Dauer (msec):\t\t" << nTheTime << endl;
+        aStream << "\nHyphenator\n";
+        aStream << "Trennstellen gesamt:\t" << nHyphens << endl;
+        if ( nHyphens )
+            aStream << "Hyphen-Durchschnitt:\t" <<
+                    nHyphens*1.0 / ( nWords - nNoHyph - nHyphErr ) << endl;
+        aStream << "keine Trennstellen:\t" << nNoHyph << endl;
+        aStream << "Trennung verweigert:\t" << nHyphErr << endl;
+        aStream << "Dauer (msec):\t\t" << nHyphTime << endl;
+        aStream << "---------------------------------------------\n";
+    }
+    nWords = nWrong = nAlter = nSynonym = nNoSynonym =
+    nHyphens = nNoHyph = nHyphErr = nSpellTime = nTheTime =
+    nHyphTime = 0;
+    pThes = NULL;
+#endif
+}
+
+#endif
+
+
diff --git a/sw/source/core/undo/docundo.cxx b/sw/source/core/undo/docundo.cxx
new file mode 100644
index 000000000000..d457431d055e
--- /dev/null
+++ b/sw/source/core/undo/docundo.cxx
@@ -0,0 +1,807 @@
+/*************************************************************************
+ *
+ *  $RCSfile: docundo.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:27 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _SV_WRKWIN_HXX //autogen
+#include 
+#endif
+
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include        // fuer die UndoIds
+#endif
+#ifndef _UNDOBJ_HXX
+#include 
+#endif
+#ifndef _ROLBCK_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+
+USHORT SwDoc::nUndoActions = UNDO_ACTION_COUNT;     // anzahl von Undo-Action
+
+//MA: Zur Zeit nicht verwendet.
+//SV_IMPL_VARARR( SwUndoIds, USHORT )
+
+//#define _SHOW_UNDORANGE
+#ifdef _SHOW_UNDORANGE
+
+
+class UndoArrStatus : public WorkWindow
+{
+    USHORT nUndo, nUndoNds;
+    virtual void Paint( const Rectangle& );
+public:
+    UndoArrStatus();
+    void Set( USHORT, USHORT );
+};
+static UndoArrStatus* pUndoMsgWin = 0;
+
+
+UndoArrStatus::UndoArrStatus()
+    : WorkWindow( APP_GETAPPWINDOW() ), nUndo(0), nUndoNds(0)
+{
+    SetSizePixel( Size( 200, 100 ));
+    SetFont( Font( "Courier", Size( 0, 10 )) );
+    Show();
+}
+
+
+void UndoArrStatus::Set( USHORT n1, USHORT n2 )
+{
+    nUndo = n1; nUndoNds = n2;
+    Invalidate();
+}
+
+
+void UndoArrStatus::Paint( const Rectangle& )
+{
+    String s;
+    DrawRect( Rectangle( Point(0,0), GetOutputSize() ));
+    ( s = "Undos: " ) += nUndo;
+    DrawText( Point( 0, 0 ), s );
+    ( s = "UndoNodes: " ) += nUndoNds;
+    DrawText( Point( 0, 15 ), s );
+}
+
+#endif
+
+
+void SwDoc::AppendUndo(SwUndo* pUndo)
+{
+    ASSERT( pUndos->Count() == nUndoPos,
+            "das Undo-Array wurde nach einem Redo nicht geloescht!" );
+
+#ifdef COMPACT
+    DelUndoGroups( FALSE );     // nur die History loeschen !!
+#endif
+
+    if( REDLINE_NONE == pUndo->GetRedlineMode() )
+        pUndo->SetRedlineMode( GetRedlineMode() );
+
+    pUndos->Insert( pUndo, pUndos->Count() );
+    nUndoPos = pUndos->Count();
+    switch( pUndo->GetId() )
+    {
+    case UNDO_START:        ++nUndoSttEnd;
+                            break;
+
+    case UNDO_END:          ASSERT( nUndoSttEnd, "Undo-Ende ohne Start" );
+                            --nUndoSttEnd;
+
+                            // kein break !!!
+    default:                if( !nUndoSttEnd )
+                                ++nUndoCnt;
+                            break;
+    }
+
+#ifdef _SHOW_UNDORANGE
+    // zur Anzeige der aktuellen Undo-Groessen
+    if( !pUndoMsgWin )
+            pUndoMsgWin = new UndoArrStatus;
+    pUndoMsgWin->Set( pUndos->Count(), aUndoNodes.Count() );
+#endif
+
+    // noch eine offene Klammerung, kann man sich den Rest schenken
+    if( nUndoSttEnd )
+        return;
+
+    // folgende Array-Grenzen muessen ueberwacht werden:
+    //  - Undo,             Grenze: fester Wert oder USHRT_MAX - 1000
+    //  - UndoNodes,        Grenze:  USHRT_MAX - 1000
+    //  - AttrHistory       Grenze:  USHRT_MAX - 1000
+
+    USHORT nEnde = USHRT_MAX - 1000;
+
+// nur zum Testen der neuen DOC-Member
+#ifndef PRODUCT
+{
+    USHORT nId, nUndosCnt = 0, nSttEndCnt = 0;
+    for( USHORT nCnt = 0; nCnt < nUndoPos; ++nCnt )
+    {
+        if( UNDO_START == ( nId = (*pUndos)[ nCnt ]->GetId() ))
+            ++nSttEndCnt;
+        else if( UNDO_END == nId )
+            --nSttEndCnt;
+        if( !nSttEndCnt )
+            ++nUndosCnt;
+    }
+    ASSERT( nSttEndCnt == nUndoSttEnd, "Start-Ende Count ungleich" );
+    ASSERT( nUndosCnt == nUndoCnt, "Undo Count ungleich" );
+}
+#endif
+
+    if( SwDoc::nUndoActions < nUndoCnt )
+        // immer 1/10 loeschen
+        //JP 23.09.95: oder wenn neu eingestellt wurde um die Differenz
+        DelUndoObj( (nUndoCnt - SwDoc::nUndoActions) + nUndoCnt / 10 );
+    else
+    {
+        USHORT nUndosCnt = nUndoCnt;
+            // immer 1/10 loeschen bis der "Ausloeser" behoben ist
+        while( aUndoNodes.Count() && nEnde < aUndoNodes.Count() )
+            DelUndoObj( nUndosCnt / 10 );
+    }
+}
+
+
+
+void SwDoc::ClearRedo()
+{
+    if( DoesUndo() && nUndoPos != pUndos->Count() )
+    {
+        if( !nUndoSttEnd )
+        {
+            // setze UndoCnt auf den neuen Wert
+            SwUndo* pUndo;
+            for( USHORT nCnt = pUndos->Count(); nUndoPos < nCnt; --nUndoCnt )
+                // Klammerung ueberspringen
+                if( UNDO_END == (pUndo = (*pUndos)[ --nCnt ])->GetId() )
+                    nCnt -= ((SwUndoEnd*)pUndo)->GetSttOffset();
+        }
+
+        // loesche die Undo-Aktionen (immer von hinten !)
+        pUndos->DeleteAndDestroy( nUndoPos, pUndos->Count() - nUndoPos );
+    }
+}
+
+
+    // loescht die gesamten UndoObjecte
+void SwDoc::DelAllUndoObj()
+{
+    ClearRedo();
+
+    DoUndo( FALSE );
+
+    // Offene Undo-Klammerungen erhalten !!
+    SwUndo* pUndo;
+    USHORT nSize = pUndos->Count();
+    while( nSize )
+        if( UNDO_START != ( pUndo = (*pUndos)[ --nSize ] )->GetId() ||
+            ((SwUndoStart*)pUndo)->GetEndOffset() )
+            // keine offenen Gruppierung ?
+            pUndos->DeleteAndDestroy( nSize, 1 );
+
+    nUndoCnt = 0;
+    nUndoPos = pUndos->Count();
+
+/*
+    while( nUndoPos )
+        aUndos.DelDtor( --nUndoPos, 1 );
+    nUndoCnt = nUndoSttEnd = nUndoPos = 0;
+*/
+    nUndoSavePos = USHRT_MAX;
+    DoUndo( TRUE );
+}
+
+
+    // loescht alle UndoObjecte vom Anfang bis zum angegebenen Ende
+BOOL SwDoc::DelUndoObj( USHORT nEnde )
+{
+    if( !nEnde )                    // sollte mal 0 uebergeben werden,
+    {
+        if( !pUndos->Count() )
+            return FALSE;
+        ++nEnde;                    // dann korrigiere es auf 1
+    }
+
+    DoUndo( FALSE );
+
+    // pruefe erstmal, wo das Ende steht
+    USHORT nId = 0, nSttEndCnt = 0;
+    for( USHORT nCnt = 0; nEnde && nCnt < nUndoPos; ++nCnt )
+    {
+        if( UNDO_START == ( nId = (*pUndos)[ nCnt ]->GetId() ))
+            ++nSttEndCnt;
+        else if( UNDO_END == nId )
+            --nSttEndCnt;
+        if( !nSttEndCnt )
+            --nEnde, --nUndoCnt;
+    }
+
+    ASSERT( nCnt < nUndoPos || nUndoPos == pUndos->Count(),
+            "Undo-Del-Ende liegt in einer Redo-Aktion" );
+
+    // dann setze ab Ende bis Undo-Ende bei allen Undo-Objecte die Werte um
+    nSttEndCnt = nCnt;          // Position merken
+    if( nUndoSavePos < nSttEndCnt )     // SavePos wird aufgegeben
+        nUndoSavePos = USHRT_MAX;
+    else if( nUndoSavePos != USHRT_MAX )
+        nUndoSavePos -= nSttEndCnt;
+
+    while( nSttEndCnt )
+        pUndos->DeleteAndDestroy( --nSttEndCnt, 1 );
+    nUndoPos = pUndos->Count();
+
+    DoUndo( TRUE );
+    return TRUE;
+}
+
+/**************** UNDO ******************/
+
+
+BOOL SwDoc::HasUndoId(USHORT nId) const
+{
+    USHORT nSize = nUndoPos;
+    SwUndo * pUndo;
+    while( nSize-- )
+        if( ( pUndo = (*pUndos)[nSize])->GetId() == nId ||
+            ( UNDO_START == pUndo->GetId() &&
+                ((SwUndoStart*)pUndo)->GetUserId() == nId )
+            || ( UNDO_END == pUndo->GetId() &&
+                ((SwUndoEnd*)pUndo)->GetUserId() == nId ) )
+        {
+            return TRUE;
+        }
+
+    return FALSE;
+}
+
+
+BOOL SwDoc::Undo( SwUndoIter& rUndoIter )
+{
+    if ( (rUndoIter.GetId()!=0) && (!HasUndoId(rUndoIter.GetId())) )
+    {
+        rUndoIter.bWeiter = FALSE;
+        return FALSE;
+    }
+    if( !nUndoPos )
+    {
+        rUndoIter.bWeiter = FALSE;
+        return FALSE;
+    }
+
+    SwUndo *pUndo = (*pUndos)[ --nUndoPos ];
+
+    SwRedlineMode eOld = GetRedlineMode();
+    SwRedlineMode eTmpMode = (SwRedlineMode)pUndo->GetRedlineMode();
+    if( (REDLINE_SHOW_MASK & eTmpMode) != (REDLINE_SHOW_MASK & eOld) &&
+        UNDO_START != pUndo->GetId() && UNDO_END != pUndo->GetId() )
+        SetRedlineMode( eTmpMode );
+
+    SetRedlineMode_intern( eTmpMode | REDLINE_IGNORE );
+    // Undo ausfuehren
+
+    // zum spaeteren ueberpruefen
+    USHORT nAktId = pUndo->GetId();
+    //JP 11.05.98: FlyFormate ueber die EditShell selektieren, nicht aus dem
+    //              Undo heraus
+    if( UNDO_START != nAktId && UNDO_END != nAktId )
+        rUndoIter.ClearSelections();
+
+    pUndo->Undo( rUndoIter );
+
+    SetRedlineMode( eOld );
+
+    // Besonderheit von Undo-Replace (interne History)
+    if( UNDO_REPLACE == nAktId && ((SwUndoReplace*)pUndo)->nAktPos )
+    {
+        ++nUndoPos;
+        return TRUE;
+    }
+
+    // Objekt aus History entfernen und zerstoeren
+    if( nUndoPos && !rUndoIter.bWeiter &&
+        UNDO_START == ( pUndo = (*pUndos)[ nUndoPos-1 ] )->GetId() )
+        --nUndoPos;
+
+    // JP 29.10.96: Start und End setzen kein Modify-Flag.
+    //              Sonst gibt es Probleme mit der autom. Aufnahme von Ausnahmen
+    //              bei der Autokorrektur
+    if( UNDO_START != nAktId && UNDO_END != nAktId )
+        SetModified();      // default: immer setzen, kann zurueck gesetzt werden
+
+#ifdef COMPACT
+
+    // in der Compact-Version gibt es nur ein einstufiges Undo. Ueber das
+    // Flag wird erkannt, wann ein Dokument als unveraendert gekennzeichnet
+    // werden kann; nach einer Aktion und deren Undo
+    // Bei mehr als einer Aktion ist das Dokument immer veraendert.
+
+// wird nicht mehr beneotigt oder ???       Member am DOC geloescht
+//  if( UNDO_FIRST == eUndoFlag )
+//  {
+//      ResetModified();
+//      eUndoFlag = UNDO_INIT;
+//  }
+
+#else
+    // ist die History leer und wurde nicht wegen Speichermangel
+    // verworfen, so kann das Dokument als unveraendert gelten
+    if( nUndoSavePos == nUndoPos )
+        ResetModified();
+#endif
+    return TRUE;
+}
+
+
+// setzt Undoklammerung auf, liefert nUndoId der Klammerung
+
+
+USHORT SwDoc::StartUndo( USHORT nUndoId )
+{
+    if( !bUndo )
+        return 0;
+
+    if( !nUndoId )
+        nUndoId = UNDO_START;
+
+    ClearRedo();
+    AppendUndo( new SwUndoStart( nUndoId ));
+    return nUndoId;
+}
+// schliesst Klammerung der nUndoId, nicht vom UI benutzt
+
+
+USHORT SwDoc::EndUndo(USHORT nUndoId)
+{
+    USHORT nSize = pUndos->Count();
+    if( !bUndo || !nSize-- )
+        return 0;
+
+    if( UNDO_START == nUndoId || !nUndoId )
+        nUndoId = UNDO_END;
+
+    SwUndo* pUndo = (*pUndos)[ nSize ];
+    if( UNDO_START == pUndo->GetId() )
+    {
+        // leere Start/End-Klammerung ??
+        pUndos->DeleteAndDestroy( nSize );
+        nUndoPos = pUndos->Count();
+        --nUndoSttEnd;
+        return 0;
+    }
+
+    // suche den Anfang dieser Klammerung
+    USHORT nId;
+    while( nSize )
+        if( UNDO_START == ( nId = (pUndo = (*pUndos)[ --nSize ] )->GetId()) &&
+            !((SwUndoStart*)pUndo)->GetEndOffset() )
+            break;      // Start gefunden
+
+    if( nId != UNDO_START )
+    {
+        // kann eigentlich nur beim Abspielen von Macros passieren, die
+        // Undo/Redo/Repeat benutzen und die eine exitierende Selection
+        // durch Einfuegen loeschen
+        ASSERT( !this, "kein entsprechendes Ende gefunden" );
+        // kein entsprechenden Start gefunden -> Ende nicht einfuegen
+        // und die Member am Doc updaten
+
+        nUndoSttEnd = 0;
+        nUndoCnt = 0;
+        // setze UndoCnt auf den neuen Wert
+        SwUndo* pUndo;
+        for( USHORT nCnt = 0; nCnt < pUndos->Count(); ++nCnt, ++nUndoCnt )
+            // Klammerung ueberspringen
+            if( UNDO_START == (pUndo = (*pUndos)[ nCnt ])->GetId() )
+                nCnt += ((SwUndoStart*)pUndo)->GetEndOffset();
+        return 0;
+
+    }
+
+    // Klammerung um eine einzelne Action muss nicht sein!
+    // Aussnahme: es ist eine eigene ID definiert
+    if(  2 == pUndos->Count() - nSize &&
+        (UNDO_END == nUndoId || nUndoId == (*pUndos)[ nSize+1 ]->GetId() ))
+    {
+        pUndos->DeleteAndDestroy( nSize );
+        nUndoPos = pUndos->Count();
+        if( !--nUndoSttEnd )
+        {
+            ++nUndoCnt;
+            if( SwDoc::nUndoActions < nUndoCnt )
+                // immer 1/10 loeschen
+                //JP 23.09.95: oder wenn neu eingestellt wurde um die Differenz
+                DelUndoObj( (nUndoCnt - SwDoc::nUndoActions) + nUndoCnt / 10 );
+            else
+            {
+                USHORT nEnde = USHRT_MAX - 1000;
+                USHORT nUndosCnt = nUndoCnt;
+                    // immer 1/10 loeschen bis der "Ausloeser" behoben ist
+                while( aUndoNodes.Count() && nEnde < aUndoNodes.Count() )
+                    DelUndoObj( nUndosCnt / 10 );
+            }
+        }
+        return nUndoId;
+    }
+
+    // setze die Klammerung am Start/End-Undo
+    nSize = pUndos->Count() - nSize;
+    ((SwUndoStart*)pUndo)->SetEndOffset( nSize );
+
+    SwUndoEnd* pUndoEnd = new SwUndoEnd( nUndoId );
+    pUndoEnd->SetSttOffset( nSize );
+
+// nur zum Testen der Start/End-Verpointerung vom Start/End Undo
+#ifndef PRODUCT
+{
+    USHORT nEndCnt = 1, nCnt = pUndos->Count(), nId;
+    while( nCnt )
+    {
+        if( UNDO_START == ( nId = (*pUndos)[ --nCnt ]->GetId()) )
+        {
+            if( !nEndCnt )      // falls mal ein Start ohne Ende vorhanden ist
+                continue;
+            --nEndCnt;
+            if( !nEndCnt )      // hier ist der Anfang
+                break;
+        }
+        else if( UNDO_END == nId )
+            ++nEndCnt;
+        else if( !nEndCnt )
+            break;
+    }
+    ASSERT( nCnt == pUndos->Count() - nSize, "Start-Ende falsch geklammert" );
+}
+#endif
+
+    AppendUndo( pUndoEnd );
+    return nUndoId;
+}
+
+// liefert die Id der letzten Undofaehigen Aktion zurueck oder 0
+// fuellt ggf. VARARR mit User-UndoIds
+
+
+USHORT SwDoc::GetUndoIds( String* pStr, SwUndoIds *pUndoIds) const
+{
+    USHORT nSize = nUndoPos;
+    if ( nSize-- == 0 )
+        return 0;
+
+    USHORT nId;
+    SwUndo* pUndo;
+    while( UNDO_END == (nId = (pUndo = (*pUndos)[nSize])->GetId()) && nSize
+        && UNDO_END == (nId = ((SwUndoEnd*)pUndo)->GetUserId()) )
+        nSize--;
+
+    switch( pUndo->GetId() )
+    {
+    case UNDO_START:
+        nId = ((SwUndoStart*)pUndo)->GetUserId();
+        break;
+    case UNDO_REDLINE:
+        nId = ((SwUndoRedline*)pUndo)->GetUserId();
+        break;
+    case UNDO_DRAWUNDO:
+        if( pStr )
+            *pStr = ((SwSdrUndo*)pUndo)->GetComment();
+        break;
+    }
+
+    return ( !nSize && UNDO_END == nId ? 0 : nId );
+}
+
+#ifdef COMPACT
+
+BOOL SwDoc::DelUndoGroups( BOOL bDelUndoNds, BOOL bDelHistory )
+{
+    USHORT nEnd = 0, nStart = 0;
+    USHORT nSize = pUndos->GetSize();
+    SwUndo* pUndo;
+
+    if( !nSize )
+        return FALSE;
+
+    while( nSize-- )
+    {
+         pUndo = (*pUndos)[ nSize ];
+         if( UNDO_STD_END <= pUndo->GetId() || UNDO_END == pUndo->GetId() )
+            // es kann sich nur um ein Ende handeln
+            nEnd++;
+         else if( UNDO_START == pUndo->GetId() )
+            nStart++;
+    }
+
+    // eine vollstaendige Gruppe ist, wenn nStart und nEnd gleich sind
+    if( nStart != nEnd )
+        return TRUE;
+
+    // jetzt kommt erst das eigentliche loeschen
+    if( bDelHistory )
+        pUndos->DelDtor( 0, pUndos->GetSize() );        // die UndoListe
+
+    // loesche das Undo-Nodes-Array
+    if( bDelUndoNds )
+    {
+        // es wird aus dem Undo-Array der gesamte Inhalt geloescht
+        SwNodeIndex aIdx( *aUndoNodes.GetEndOfContent().StartOfSectionNode(), 1 );
+        SwTxtNode * pTxtNd = 0;
+        if( aIdx.GetIndex() + 1 < aUndoNodes.GetEndOfContent().GetIndex() ||
+            0 == ( pTxtNd = aIdx.GetNode().GetTxtNode() ))
+        {
+            // loesche alle Nodes und suche oder erzeuge einen neuen TextNode
+            while( aIdx < aUndoNodes.GetEndOfContent().GetIndex() )
+            {
+                aUndoNodes.Delete( aIdx , 1 );
+                if( !pTxtNd && 0 != ( pTxtNd = aIdx.GetNode().GetTxtNode()))
+                    aIdx++;
+            }
+            if( !pTxtNd )
+            {
+                // sollte eigentlich nie auftreten.
+                pTxtNd = aUndoNodes.MakeTxtNode( aIdx,
+                                    0, 0, 0, (*GetTxtFmtColls())[0] );
+            }
+        }
+        // es braucht nur noch der Inhalt aus dem Node geloescht werden
+        if( pTxtNd->Len() )
+        {
+            aIdx.Assign( pTxtNd, 0 );
+            pTxtNd->Erase( aIdx, pTxtNd->Len() );
+        }
+    }
+    nUndoPos = pUndos->GetSize();
+
+    if( nUndoSavePos > nUndoPos )       // SavePos wird aufgegeben
+        nUndoSavePos = USHRT_MAX;
+
+    return TRUE;
+}
+#endif
+
+/**************** REDO ******************/
+
+
+BOOL SwDoc::Redo( SwUndoIter& rUndoIter )
+{
+    if( rUndoIter.GetId() && !HasUndoId( rUndoIter.GetId() ) )
+    {
+        rUndoIter.bWeiter = FALSE;
+        return FALSE;
+    }
+    if( nUndoPos == pUndos->Count() )
+    {
+        rUndoIter.bWeiter = FALSE;
+        return FALSE;
+    }
+
+    SwUndo *pUndo = (*pUndos)[ nUndoPos++ ];
+
+    SwRedlineMode eOld = GetRedlineMode();
+    SwRedlineMode eTmpMode = (SwRedlineMode)pUndo->GetRedlineMode();
+    if( (REDLINE_SHOW_MASK & eTmpMode) != (REDLINE_SHOW_MASK & eOld) &&
+        UNDO_START != pUndo->GetId() && UNDO_END != pUndo->GetId() )
+        SetRedlineMode( eTmpMode );
+    SetRedlineMode_intern( eTmpMode | REDLINE_IGNORE );
+
+    //JP 11.05.98: FlyFormate ueber die EditShell selektieren, nicht aus dem
+    //              Undo heraus
+    if( UNDO_START != pUndo->GetId() && UNDO_END != pUndo->GetId() )
+        rUndoIter.ClearSelections();
+
+    pUndo->Redo( rUndoIter );
+
+    SetRedlineMode( eOld );
+
+    // Besonderheit von Undo-Replace (interne History)
+    if( UNDO_REPLACE == pUndo->GetId() &&
+        USHRT_MAX != ((SwUndoReplace*)pUndo)->nAktPos )
+    {
+        --nUndoPos;
+        return TRUE;
+    }
+
+    if( rUndoIter.bWeiter && nUndoPos >= pUndos->Count() )
+        rUndoIter.bWeiter = FALSE;
+
+    // ist die History leer und wurde nicht wegen Speichermangel
+    // verworfen, so kann das Dokument als unveraendert gelten
+    if( nUndoSavePos == nUndoPos )
+        ResetModified();
+    else
+        SetModified();
+    return TRUE;
+}
+
+
+// liefert die Id der letzten Redofaehigen Aktion zurueck oder 0
+// fuellt ggf. VARARR mit User-RedoIds
+
+
+USHORT SwDoc::GetRedoIds( String* pStr, SwUndoIds *pRedoIds ) const
+{
+    USHORT nSize, nId;
+    if( ( nSize = nUndoPos) == pUndos->Count() )
+        return 0;
+
+    SwUndo* pUndo;
+    if( UNDO_START != ( nId = ( pUndo = (*pUndos)[nSize] )->GetId() ) ||
+        UNDO_START != ( nId = ((SwUndoStart*)pUndo)->GetUserId() ) )
+    {
+        if( UNDO_REDLINE == nId )
+            nId = ((SwUndoRedline*)pUndo)->GetUserId();
+        else if( pStr && UNDO_DRAWUNDO == nId )
+            *pStr = ((SwSdrUndo*)pUndo)->GetComment();
+        return nId;
+    }
+
+    ASSERT( UNDO_END != nId, "falsches Ende der Undoklammerung!");
+
+    // auf den vorm Ende der Klammerung
+    nSize += ((SwUndoStart*)pUndo)->GetEndOffset();
+    while( nSize &&
+            UNDO_END == ( nId = ( pUndo = (*pUndos)[ --nSize ] )->GetId()) &&
+            UNDO_END == ( nId = ((SwUndoEnd*)pUndo)->GetUserId() ) )
+        ;
+
+    if( !nSize )
+        nId = 0;
+    else if( pStr && UNDO_DRAWUNDO == nId )
+        *pStr = ((SwSdrUndo*)pUndo)->GetComment();
+    else if( UNDO_REDLINE == nId )
+        nId = ((SwUndoRedline*)pUndo)->GetUserId();
+
+    return nId;
+}
+
+/**************** REPEAT ******************/
+
+
+BOOL SwDoc::Repeat( SwUndoIter& rUndoIter, USHORT nRepeatCnt )
+{
+    if( rUndoIter.GetId() && !HasUndoId( rUndoIter.GetId() ) )
+    {
+        rUndoIter.bWeiter = FALSE;
+        return FALSE;
+    }
+    USHORT nSize = nUndoPos;
+    if( !nSize )
+    {
+        rUndoIter.bWeiter = FALSE;
+        return FALSE;
+    }
+
+    // dann suche jetzt ueber die End/Start-Gruppen die gueltige Repeat-Aktion
+    SwUndo *pUndo = (*pUndos)[ --nSize ];
+    if( UNDO_END == pUndo->GetId() )
+        nSize -= ((SwUndoEnd*)pUndo)->GetSttOffset();
+
+    USHORT nEndCnt = nUndoPos;
+    BOOL bOneUndo = nSize + 1 == nUndoPos;
+
+    SwPaM* pTmpCrsr = rUndoIter.pAktPam;
+    if( pTmpCrsr != pTmpCrsr->GetNext() || !bOneUndo )  // Undo-Klammerung aufbauen
+        StartUndo( 0 );
+    do {        // dann durchlaufe mal den gesamten Ring
+        for( USHORT nRptCnt = nRepeatCnt; nRptCnt > 0; --nRptCnt )
+        {
+            rUndoIter.pLastUndoObj = 0;
+            for( USHORT nCnt = nSize; nCnt < nEndCnt; ++nCnt )
+                (*pUndos)[ nCnt ]->Repeat( rUndoIter );     // Repeat ausfuehren
+        }
+    } while( pTmpCrsr !=
+        ( rUndoIter.pAktPam = (SwPaM*)rUndoIter.pAktPam->GetNext() ));
+    if( pTmpCrsr != pTmpCrsr->GetNext() || !bOneUndo )
+        EndUndo( 0 );
+
+    return TRUE;
+}
+
+// liefert die Id der letzten Repeatfaehigen Aktion zurueck oder 0
+// fuellt ggf. VARARR mit User-RedoIds
+
+
+USHORT SwDoc::GetRepeatIds(String* pStr, SwUndoIds *pRepeatIds) const
+{
+    USHORT nRepeatId = GetUndoIds( pStr, pRepeatIds );
+    if( REPEAT_START <= nRepeatId && REPEAT_END > nRepeatId )
+        return nRepeatId;
+    return 0;
+}
+
+
+SwUndo* SwDoc::RemoveLastUndo( USHORT nUndoId )
+{
+    SwUndo* pUndo = (*pUndos)[ pUndos->Count() - 1 ];
+    if( nUndoId == pUndo->GetId() && nUndoPos == pUndos->Count() )
+    {
+        if( !nUndoSttEnd )
+            --nUndoCnt;
+        --nUndoPos;
+        pUndos->Remove( nUndoPos, 1 );
+    }
+    else
+    {
+        pUndo = 0;
+        ASSERT( !this, "falsches Undo-Object" );
+    }
+    return pUndo;
+}
+
+
+
diff --git a/sw/source/core/undo/makefile.mk b/sw/source/core/undo/makefile.mk
new file mode 100644
index 000000000000..12f209572dce
--- /dev/null
+++ b/sw/source/core/undo/makefile.mk
@@ -0,0 +1,135 @@
+#*************************************************************************
+#
+#   $RCSfile: makefile.mk,v $
+#
+#   $Revision: 1.1.1.1 $
+#
+#   last change: $Author: hr $ $Date: 2000-09-19 00:08:27 $
+#
+#   The Contents of this file are made available subject to the terms of
+#   either of the following licenses
+#
+#          - GNU Lesser General Public License Version 2.1
+#          - Sun Industry Standards Source License Version 1.1
+#
+#   Sun Microsystems Inc., October, 2000
+#
+#   GNU Lesser General Public License Version 2.1
+#   =============================================
+#   Copyright 2000 by Sun Microsystems, Inc.
+#   901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+#   This library is free software; you can redistribute it and/or
+#   modify it under the terms of the GNU Lesser General Public
+#   License version 2.1, as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   Lesser General Public License for more details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+#   License along with this library; if not, write to the Free Software
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+#   MA  02111-1307  USA
+#
+#
+#   Sun Industry Standards Source License Version 1.1
+#   =================================================
+#   The contents of this file are subject to the Sun Industry Standards
+#   Source License Version 1.1 (the "License"); You may not use this file
+#   except in compliance with the License. You may obtain a copy of the
+#   License at http://www.openoffice.org/license.html.
+#
+#   Software provided under this License is provided on an "AS IS" basis,
+#   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+#   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+#   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+#   See the License for the specific provisions governing your rights and
+#   obligations concerning the Software.
+#
+#   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+#   Copyright: 2000 by Sun Microsystems, Inc.
+#
+#   All Rights Reserved.
+#
+#   Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sw
+TARGET=undo
+
+AUTOSEG=true
+
+PROJECTPCH=core_pch
+PDBTARGET=core_pch
+PROJECTPCHSOURCE=..$/core_1st$/core_pch
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE :  $(PRJ)$/inc$/swpre.mk
+.INCLUDE :  settings.mk
+.INCLUDE :  $(PRJ)$/inc$/sw.mk
+
+.IF "$(GUI)$(COM)" == "WINMSC"
+LIBFLAGS=/NOI /NOE /PAGE:128
+.ENDIF
+
+# --- Files --------------------------------------------------------
+
+CXXFILES = \
+        docundo.cxx \
+        rolbck.cxx \
+        unattr.cxx \
+        unbkmk.cxx \
+        undel.cxx \
+        undobj.cxx \
+        undobj1.cxx \
+        undraw.cxx \
+        unfmco.cxx \
+        unins.cxx \
+        unmove.cxx \
+        unnum.cxx \
+        unoutl.cxx \
+        unovwr.cxx \
+        unredln.cxx \
+        unsect.cxx \
+        unsort.cxx \
+        unspnd.cxx \
+        untbl.cxx \
+        untblk.cxx
+
+
+
+SLOFILES =	\
+        $(SLO)$/docundo.obj \
+        $(SLO)$/rolbck.obj \
+        $(SLO)$/unattr.obj \
+        $(SLO)$/unbkmk.obj \
+        $(SLO)$/undel.obj \
+        $(SLO)$/undobj.obj \
+        $(SLO)$/undobj1.obj \
+        $(SLO)$/undraw.obj \
+        $(SLO)$/unfmco.obj \
+        $(SLO)$/unins.obj \
+        $(SLO)$/unmove.obj \
+        $(SLO)$/unnum.obj \
+        $(SLO)$/unoutl.obj \
+        $(SLO)$/unovwr.obj \
+        $(SLO)$/unredln.obj \
+        $(SLO)$/unsect.obj \
+        $(SLO)$/unsort.obj \
+        $(SLO)$/unspnd.obj \
+        $(SLO)$/untbl.obj \
+        $(SLO)$/untblk.obj
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE :  target.mk
+
diff --git a/sw/source/core/undo/rolbck.cxx b/sw/source/core/undo/rolbck.cxx
new file mode 100644
index 000000000000..3c180b7523d7
--- /dev/null
+++ b/sw/source/core/undo/rolbck.cxx
@@ -0,0 +1,1488 @@
+/*************************************************************************
+ *
+ *  $RCSfile: rolbck.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:27 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX //autogen
+#include 
+#endif
+
+#ifndef _SFXITEMITER_HXX //autogen
+#include 
+#endif
+
+#ifndef _FMTFTN_HXX //autogen
+#include 
+#endif
+#ifndef _FCHRFMT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFLCNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTRFMRK_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _FMTPDSC_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _TXTRFMRK_HXX //autogen
+#include 
+#endif
+#ifndef _TXTTXMRK_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFTN_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFLCNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTPDSC_HXX //autogen
+#include 
+#endif
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _FMTCNCT_HXX //autogen
+#include 
+#endif
+#ifndef _FRMFMT_HXX //autogen
+#include 
+#endif
+#ifndef _FTNIDX_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include               // SwDoc.GetNodes()
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include             // SwTxtNode
+#endif
+#ifndef _PARATR_HXX
+#include            //
+#endif
+#ifndef _CELLATR_HXX
+#include           //
+#endif
+#ifndef _FLDBAS_HXX
+#include            // fuer Felder
+#endif
+#ifndef _PAM_HXX
+#include               // fuer SwPaM
+#endif
+#ifndef _HINTS_HXX
+#include             // fuer SwHytrSetAttrSet
+#endif
+#ifndef _SWTABLE_HXX
+#include 
+#endif
+#ifndef _ROLBCK_HXX
+#include 
+#endif
+#ifndef _NDGRF_HXX
+#include             // SwGrfNode
+#endif
+#ifndef _UNDOBJ_HXX
+#include            // fuer UndoDelete
+#endif
+#ifndef _BOOKMRK_HXX
+#include           // fuer SwBookmark
+#endif
+#ifndef _NDINDEX_HXX
+#include           // fuer SwNodeIndex
+#endif
+
+
+
+
+SV_IMPL_PTRARR( SwpHstry, SwHstryHintPtr)
+
+
+SwSetFmtHint::SwSetFmtHint( const SfxPoolItem* pFmtHt, ULONG nNd )
+    :  SwHstryHint( HSTRY_SETFMTHNT ),
+    pAttr( pFmtHt->Clone() ), nNode( nNd ), nNumLvl( NO_NUMBERING ),
+    nSetStt( USHRT_MAX )
+{
+    switch( pAttr->Which() )
+    {
+    case RES_PAGEDESC:
+        ((SwFmtPageDesc*)pAttr)->ChgDefinedIn( 0 );
+        break;
+    case RES_PARATR_DROP:
+        ((SwFmtDrop*)pAttr)->ChgDefinedIn( 0 );
+        break;
+    case RES_BOXATR_FORMULA:
+        {
+            //JP 30.07.98: Bug 54295 - Formeln immer im Klartext speichern
+            SwTblBoxFormula& rNew = *(SwTblBoxFormula*)pAttr;
+            if( rNew.IsIntrnlName() )
+            {
+                const SwTblBoxFormula& rOld = *(SwTblBoxFormula*)pFmtHt;
+                const SwNode* pNd = rOld.GetNodeOfFormula();
+                if( pNd && 0 != (pNd = pNd->FindTableNode() ))
+                {
+                    SwTableFmlUpdate aMsgHnt( &((SwTableNode*)pNd)->GetTable() );
+                    aMsgHnt.eFlags = TBL_BOXNAME;
+                    rNew.ChgDefinedIn( rOld.GetDefinedIn() );
+                    rNew.ChangeState( &aMsgHnt );
+                }
+            }
+            rNew.ChgDefinedIn( 0 );
+        }
+        break;
+    case RES_PARATR_NUMRULE:
+        {
+            if( ((SwNumRuleItem*)pAttr)->GetDefinedIn() &&
+                ((SwNumRuleItem*)pAttr)->GetDefinedIn()->ISA( SwTxtNode ))
+            {
+                SwTxtNode* pTNd = (SwTxtNode*)((SwNumRuleItem*)pAttr)->GetDefinedIn();
+                if( pTNd->GetNum() )
+                {
+                    nNumLvl = pTNd->GetNum()->GetLevel();
+                    bNumStt = pTNd->GetNum()->IsStart();
+                    nSetStt = pTNd->GetNum()->GetSetValue();
+                }
+            }
+            ((SwNumRuleItem*)pAttr)->ChgDefinedIn( 0 );
+        }
+        break;
+    }
+}
+
+
+void SwSetFmtHint::SetInDoc( SwDoc* pDoc, BOOL bTmpSet )
+{
+    SwNode * pNode = pDoc->GetNodes()[ nNode ];
+    if( pNode->IsCntntNode() )
+    {
+        ((SwCntntNode*)pNode)->SetAttr( *pAttr );
+
+        if( RES_PARATR_NUMRULE == pAttr->Which() && NO_NUMBERING != nNumLvl &&
+            ((SwTxtNode*)pNode)->GetNum() )
+        {
+            SwNodeNum aNum( *((SwTxtNode*)pNode)->GetNum() );
+            aNum.SetLevel( nNumLvl );
+            aNum.SetStart( bNumStt );
+            aNum.SetSetValue( nSetStt );
+            ((SwTxtNode*)pNode)->UpdateNum( aNum );
+        }
+    }
+    else if( pNode->IsTableNode() )
+        ((SwTableNode*)pNode)->GetTable().GetFrmFmt()->SetAttr( *pAttr );
+    else if( pNode->IsStartNode() &&
+            SwTableBoxStartNode == ((SwStartNode*)pNode)->GetStartNodeType() )
+    {
+        SwTableNode* pTNd = pNode->FindTableNode();
+        SwTableBox* pBox;
+        if( pTNd && 0 != ( pBox = pTNd->GetTable().GetTblBox( nNode )))
+            pBox->ClaimFrmFmt()->SetAttr( *pAttr );
+    }
+
+    if( !bTmpSet )
+        DELETEZ( pAttr );
+}
+
+
+SwSetFmtHint::~SwSetFmtHint()
+{
+    delete pAttr;
+}
+
+
+SwResetFmtHint::SwResetFmtHint( const SfxPoolItem* pFmtHt, ULONG nNd )
+    : SwHstryHint( HSTRY_RESETFMTHNT ),
+    nWhich( pFmtHt->Which() ), nNode( nNd )
+{
+}
+
+
+void SwResetFmtHint::SetInDoc( SwDoc* pDoc, BOOL bTmpSet )
+{
+    SwNode * pNode = pDoc->GetNodes()[ nNode ];
+    if( pNode->IsCntntNode() )
+        ((SwCntntNode*)pNode)->ResetAttr( nWhich );
+    else if( pNode->IsTableNode() )
+        ((SwTableNode*)pNode)->GetTable().GetFrmFmt()->ResetAttr( nWhich );
+}
+
+
+SwSetTxtHint::SwSetTxtHint( SwTxtAttr* pTxtHt, ULONG nNodePos )
+    : SwHstryHint( HSTRY_SETTXTHNT )
+{
+    // !! Achtung: folgende Attribute erzeugen keine FormatAttribute:
+    //  - NoLineBreak, NoHypen, Inserted, Deleted
+    // Dafuer muessen Sonderbehandlungen gemacht werden !!!
+
+    // ein bisschen kompliziert, aber ist Ok so: erst vom default
+    // eine Kopie und dann die Werte aus dem Text Attribut zuweisen
+    USHORT nWhich = pTxtHt->Which();
+    if( RES_TXTATR_CHARFMT == nWhich )
+        pAttr = new SwFmtCharFmt( pTxtHt->GetCharFmt().GetCharFmt() );
+    else
+        pAttr = pTxtHt->GetAttr().Clone();
+    nNode = nNodePos;
+    nStart = *pTxtHt->GetStart();
+    nEnd = *pTxtHt->GetAnyEnd();
+}
+
+
+SwSetTxtHint::~SwSetTxtHint()
+{
+    delete pAttr;
+}
+
+
+void SwSetTxtHint::SetInDoc( SwDoc* pDoc, BOOL bTmpSet )
+{
+    if( !pAttr )
+        return;
+
+    if( RES_TXTATR_CHARFMT == pAttr->Which() )
+    {
+        // befrage das Doc, ob das CharFmt noch vorhanden ist !
+        if( USHRT_MAX == pDoc->GetCharFmts()->GetPos(
+                            ((SwFmtCharFmt*)pAttr)->GetCharFmt() ) )
+            return;     // nicht setzen, Format nicht vorhanden
+    }
+
+    SwTxtNode * pTxtNd = pDoc->GetNodes()[ nNode ]->GetTxtNode();
+    ASSERT( pTxtNd, "Undo-TxtAttr: kein TextNode" );
+
+    pTxtNd->Insert( *pAttr, nStart, nEnd,
+                    SETATTR_NOTXTATRCHR | SETATTR_NOHINTADJUST );
+}
+
+
+SwSetTxtFldHint::SwSetTxtFldHint( SwTxtFld* pTxtFld, ULONG nNodePos )
+    : SwHstryHint( HSTRY_SETTXTFLDHNT ), pFldType( 0 )
+{
+    pFld = new SwFmtFld( *pTxtFld->GetFld().GetFld() );
+
+    // nur kopieren wenn kein Sys-FieldType
+    SwDoc* pDoc = (SwDoc*)pTxtFld->GetTxtNode().GetDoc();
+
+    nFldWhich = pFld->GetFld()->GetTyp()->Which();
+    if( nFldWhich == RES_DBFLD ||
+        nFldWhich == RES_USERFLD ||
+        nFldWhich == RES_SETEXPFLD ||
+        nFldWhich == RES_DDEFLD ||
+        !pDoc->GetSysFldType( nFldWhich ))
+    {
+        pFldType = pFld->GetFld()->GetTyp()->Copy();
+        pFld->GetFld()->ChgTyp( pFldType );     // Fieldtype umsetzen
+    }
+    nNode = nNodePos;
+    nPos = *pTxtFld->GetStart();
+}
+
+
+SwSetTxtFldHint::~SwSetTxtFldHint()
+{
+    delete pFld;
+    delete pFldType;
+}
+
+
+void SwSetTxtFldHint::SetInDoc( SwDoc* pDoc, BOOL bTmpSet )
+{
+    if( !pFld )
+        return;
+
+    SwFieldType* pNewFldType = pFldType;
+    if( !pNewFldType )
+        pNewFldType = pDoc->GetSysFldType( nFldWhich );
+    else
+        // den Type am Dokuement anmelden
+        pNewFldType = pDoc->InsertFldType( *pFldType );
+
+    pFld->GetFld()->ChgTyp( pNewFldType );      // Fieldtype umsetzen
+
+    SwTxtNode * pTxtNd = pDoc->GetNodes()[ nNode ]->GetTxtNode();
+    ASSERT( pTxtNd, "Undo-TxtAttr: kein TextNode" );
+
+    pTxtNd->Insert( *pFld, nPos, nPos, SETATTR_NOTXTATRCHR );
+}
+
+
+
+SwSetRefMarkHint::SwSetRefMarkHint( SwTxtRefMark* pTxtHt, ULONG nNodePos )
+    : SwHstryHint( HSTRY_SETREFMARKHNT )
+{
+    aRefName = pTxtHt->GetRefMark().GetRefName();
+    nNode = nNodePos;
+    nStart = *pTxtHt->GetStart();
+    nEnd = *pTxtHt->GetAnyEnd();
+}
+
+
+void SwSetRefMarkHint::SetInDoc( SwDoc* pDoc, BOOL bTmpSet )
+{
+    SwTxtNode * pTxtNd = pDoc->GetNodes()[ nNode ]->GetTxtNode();
+    ASSERT( pTxtNd, "Undo-TxtAttr: kein TextNode" );
+
+    SwFmtRefMark aRefMark( aRefName );
+
+    // existiert hier schon eine Referenz-Markierung ohne Ende, so
+    // darf es nicht eingefuegt werden !!
+    if( nStart != nEnd || !pTxtNd->GetTxtAttr( nStart, RES_TXTATR_REFMARK ) )
+        pTxtNd->Insert( aRefMark, nStart, nEnd, SETATTR_NOTXTATRCHR );
+}
+
+
+SwSetTOXMarkHint::SwSetTOXMarkHint( SwTxtTOXMark* pTxtHt, ULONG nNodePos )
+    : SwHstryHint( HSTRY_SETTOXMARKHNT ), aTOXMark( pTxtHt->GetTOXMark() )
+{
+    aTOXName = aTOXMark.GetTOXType()->GetTypeName();
+    eTOXTypes = aTOXMark.GetTOXType()->GetType();
+    ((SwModify*)aTOXMark.GetRegisteredIn())->Remove( &aTOXMark );
+
+    nNode = nNodePos;
+    nStart = *pTxtHt->GetStart();
+    nEnd = *pTxtHt->GetAnyEnd();
+}
+
+
+void SwSetTOXMarkHint::SetInDoc( SwDoc* pDoc, BOOL bTmpSet )
+{
+    SwTxtNode * pTxtNd = pDoc->GetNodes()[ nNode ]->GetTxtNode();
+    ASSERT( pTxtNd, "Undo-TxtAttr: kein TextNode" );
+
+    // suche den entsprechenden Verzeichnistyp
+    USHORT nCnt = pDoc->GetTOXTypeCount( eTOXTypes );
+    const SwTOXType* pToxType = 0;
+    for( USHORT n = 0; n < nCnt; ++n )
+    {
+        pToxType = pDoc->GetTOXType( eTOXTypes, n );
+        if( pToxType->GetTypeName() == aTOXName )
+            break;
+        pToxType = 0;
+    }
+
+    if( !pToxType )     // Verzeichnistyp nicht gefunden, neu anlegen
+        pToxType = pDoc->InsertTOXType( SwTOXType( eTOXTypes, aTOXName ));
+
+    SwTOXMark aNew( aTOXMark );
+    ((SwTOXType*)pToxType)->Add( &aNew );
+
+    pTxtNd->Insert( aNew, nStart, nEnd, SETATTR_NOTXTATRCHR );
+}
+
+
+int SwSetTOXMarkHint::IsEqual( const SwTOXMark& rCmp ) const
+{
+    return aTOXName == rCmp.GetTOXType()->GetTypeName() &&
+           eTOXTypes == rCmp.GetTOXType()->GetType() &&
+           aTOXMark.GetAlternativeText() == rCmp.GetAlternativeText() &&
+           ( TOX_INDEX == eTOXTypes
+              ? ( aTOXMark.GetPrimaryKey() == rCmp.GetPrimaryKey() &&
+                 aTOXMark.GetSecondaryKey() == rCmp.GetSecondaryKey() )
+              : aTOXMark.GetLevel() == rCmp.GetLevel()
+           );
+}
+
+
+SwResetTxtHint::SwResetTxtHint( USHORT nWhich, xub_StrLen nAttrStt,
+                                xub_StrLen nAttrEnd, ULONG nNodePos )
+    : SwHstryHint( HSTRY_RESETTXTHNT ),
+    nAttr( nWhich ), nNode( nNodePos ), nStart( nAttrStt ), nEnd( nAttrEnd )
+{
+}
+
+
+void SwResetTxtHint::SetInDoc( SwDoc* pDoc, BOOL bTmpSet )
+{
+    SwTxtNode * pTxtNd = pDoc->GetNodes()[ nNode ]->GetTxtNode();
+    ASSERT( pTxtNd, "Undo-TxtAttr: kein TextNode" );
+
+    pTxtNd->Delete( nAttr, nStart, nEnd );
+}
+
+
+SwSetFtnHint::SwSetFtnHint( SwTxtFtn* pTxtFtn, ULONG nNodePos )
+    : SwHstryHint( HSTRY_SETFTNHNT ),
+    nNode( nNodePos ), nStart( *pTxtFtn->GetStart() )
+{
+    ASSERT( pTxtFtn->GetStartNode(), "Footnote ohne Section" );
+
+    aFtnStr = pTxtFtn->GetFtn().GetNumStr();
+    bEndNote = pTxtFtn->GetFtn().IsEndNote();
+
+    // merke die alte NodePos, denn wer weiss was alles in der SaveSection
+    // gespeichert (geloescht) wird
+    SwDoc* pDoc = (SwDoc*)pTxtFtn->GetTxtNode().GetDoc();
+    SwNode* pSaveNd = pDoc->GetNodes()[ nNode ];
+
+    //Pointer auf StartNode der FtnSection merken und erstmal den Pointer im
+    //Attribut zuruecksetzen -> Damit werden automatisch die Frms vernichtet.
+    SwNodeIndex aSttIdx( *pTxtFtn->GetStartNode() );
+    pTxtFtn->SetStartNode( 0, FALSE );
+
+    pUndo = new SwUndoSaveSection;
+    pUndo->SaveSection( pDoc, aSttIdx );
+    nNode = pSaveNd->GetIndex();
+}
+
+SwSetFtnHint::SwSetFtnHint( const SwTxtFtn &rTxtFtn ) :
+    SwHstryHint( HSTRY_SETFTNHNT ),
+    nNode( _SwTxtFtn_GetIndex( (&rTxtFtn) ) ),
+    nStart( *rTxtFtn.GetStart() ),
+    pUndo( 0 )
+{
+    ASSERT( rTxtFtn.GetStartNode(), "Footnote ohne Section" );
+
+    aFtnStr = rTxtFtn.GetFtn().GetNumStr();
+    bEndNote = rTxtFtn.GetFtn().IsEndNote();
+}
+
+
+SwSetFtnHint::~SwSetFtnHint()
+{
+    delete pUndo;
+}
+
+
+void SwSetFtnHint::SetInDoc( SwDoc* pDoc, BOOL bTmpSet )
+{
+    SwTxtNode * pTxtNd = pDoc->GetNodes()[ nNode ]->GetTxtNode();
+    ASSERT( pTxtNd, "Undo-TxtAttr: kein TextNode" );
+
+    if ( pUndo )
+    {
+        // setze die Fussnote im TextNode
+        SwFmtFtn& rNew = (SwFmtFtn&)pDoc->GetAttrPool().Put( SwFmtFtn( bEndNote ) );
+        if( aFtnStr.Len() )
+            rNew.SetNumStr( aFtnStr );
+        SwTxtFtn* pTxtFtn = new SwTxtFtn( rNew, nStart );
+
+        // erzeuge schon die Section der Fussnote
+        SwNodeIndex aIdx( *pTxtNd );
+        pUndo->RestoreSection( pDoc, &aIdx, SwFootnoteStartNode );
+        pTxtFtn->SetStartNode( &aIdx );
+        if( pUndo->GetHistory() )
+            // erst jetzt die Frames anlegen lassen
+            pUndo->GetHistory()->Rollback( pDoc );
+
+        pTxtNd->Insert( pTxtFtn );
+    }
+    else
+    {
+        SwTxtFtn *pFtn = (SwTxtFtn*)pTxtNd->GetTxtAttr( nStart );
+        SwFmtFtn &rFtn = (SwFmtFtn&)pFtn->GetFtn();
+        rFtn.SetNumStr( aFtnStr  );
+        if( rFtn.IsEndNote() != bEndNote )
+        {
+            rFtn.SetEndNote( bEndNote );
+            pFtn->CheckCondColl();
+        }
+    }
+}
+
+
+SwChgFmtColl::SwChgFmtColl( const SwFmtColl* pFmtColl, ULONG nNd,
+                            BYTE nNodeWhich )
+    : SwHstryHint( HSTRY_CHGFMTCOLL ),
+    pColl( pFmtColl ), nNode( nNd ), nNdWhich( nNodeWhich ),
+    nNumLvl( NO_NUMBERING ), nSetStt( USHRT_MAX )
+{
+    const SwDoc* pDoc = pFmtColl->GetDoc();
+    const SwTxtNode* pTxtNd = pDoc->GetNodes()[ nNode ]->GetTxtNode();
+    if( pTxtNd && pTxtNd->GetNum() )
+    {
+        nNumLvl = pTxtNd->GetNum()->GetLevel();
+        bNumStt = pTxtNd->GetNum()->IsStart();
+        nSetStt = pTxtNd->GetNum()->GetSetValue();
+    }
+}
+
+
+void SwChgFmtColl::SetInDoc( SwDoc* pDoc, BOOL bTmpSet )
+{
+    SwCntntNode * pCntntNd = pDoc->GetNodes()[ nNode ]->GetCntntNode();
+    ASSERT( pCntntNd, "Undo-ChgFmt: kein ContentNode" );
+
+    // prufe vor dem setzen des Formates, ob dieses ueberhaupt noch im
+    // Dokument vorhanden ist. Wurde es schon geloescht, gibt es kein Undo !!
+    if( nNdWhich == pCntntNd->GetNodeType() )
+    {
+        if( ND_TEXTNODE == nNdWhich )
+        {
+            if( USHRT_MAX != pDoc->GetTxtFmtColls()->GetPos( (SwTxtFmtColl*)pColl ))
+            {
+                pCntntNd->ChgFmtColl( (SwFmtColl*)pColl );
+                if( NO_NUMBERING != nNumLvl && ((SwTxtNode*)pCntntNd)->GetNum() )
+                {
+                    SwNodeNum aNum( *((SwTxtNode*)pCntntNd)->GetNum() );
+                    aNum.SetLevel( nNumLvl );
+                    aNum.SetStart( bNumStt );
+                    aNum.SetSetValue( nSetStt );
+                    ((SwTxtNode*)pCntntNd)->UpdateNum( aNum );
+                }
+            }
+        }
+        else if( USHRT_MAX != pDoc->GetGrfFmtColls()->GetPos( (SwGrfFmtColl*)pColl ))
+            pCntntNd->ChgFmtColl( (SwFmtColl*)pColl );
+    }
+}
+
+
+SwHstryTxtFlyCnt::SwHstryTxtFlyCnt( SwTxtFlyCnt* pTxtFly )
+    : SwHstryHint( HSTRY_FLYCNT )
+{
+    ASSERT( pTxtFly->GetFlyCnt().GetFrmFmt(), "FlyCntnt ohne Format" );
+    pUndo = new SwUndoDelLayFmt( pTxtFly->GetFlyCnt().GetFrmFmt() );
+    pUndo->ChgShowSel( FALSE );
+}
+
+
+SwHstryTxtFlyCnt::SwHstryTxtFlyCnt( SwFlyFrmFmt* pFlyFmt )
+    : SwHstryHint( HSTRY_FLYCNT )
+{
+    ASSERT( pFlyFmt, "kein Format" );
+    pUndo = new SwUndoDelLayFmt( pFlyFmt );
+    pUndo->ChgShowSel( FALSE );
+}
+
+
+SwHstryTxtFlyCnt::~SwHstryTxtFlyCnt()
+{
+    delete pUndo;
+}
+
+
+void SwHstryTxtFlyCnt::SetInDoc( SwDoc* pDoc, BOOL bTmpSet )
+{
+    SwPaM aPam( pDoc->GetNodes().GetEndOfPostIts() );
+    SwUndoIter aUndoIter( &aPam );
+    pUndo->Undo( aUndoIter );
+}
+
+
+
+// JP 21.03.94: jetzt auch die Bookmarks in die History aufnehmen
+SwHstryBookmark::SwHstryBookmark( const SwBookmark& rBkmk, BYTE nType )
+    : SwHstryHint( HSTRY_BOOKMARK ),
+    nTyp( nType ), nNode1( 0 ), nCntnt1( 0 ),
+    nNode2( rBkmk.GetOtherPos() ? 0 : ULONG_MAX ), nCntnt2( 0 )
+{
+    aName = rBkmk.GetName();
+    aShortName = rBkmk.GetShortName();
+    nKeyCode = rBkmk.GetKeyCode().GetCode() | rBkmk.GetKeyCode().GetModifier();
+
+    if( BKMK_POS & nTyp )
+    {
+        nNode1 = rBkmk.GetPos().nNode.GetIndex();
+        nCntnt1 = rBkmk.GetPos().nContent.GetIndex();
+    }
+    if( BKMK_OTHERPOS & nTyp )
+    {
+        nNode2 = rBkmk.GetOtherPos()->nNode.GetIndex();
+        nCntnt2 = rBkmk.GetOtherPos()->nContent.GetIndex();
+    }
+}
+
+
+void SwHstryBookmark::SetInDoc( SwDoc* pDoc, BOOL )
+{
+    BOOL bDoesUndo = pDoc->DoesUndo();
+    pDoc->DoUndo( FALSE );
+
+    SwNodes& rNds = pDoc->GetNodes();
+
+    if( ( BKMK_POS == nTyp && ULONG_MAX == nNode2 ) ||
+        ( BKMK_POS | BKMK_OTHERPOS ) == nTyp )
+    {
+        // voellig neu setzen
+        SwCntntNode * pCntntNd = rNds[ nNode1 ]->GetCntntNode();
+        ASSERT( pCntntNd, "Falscher Node fuer den Bookmark" );
+
+        SwPaM aPam( *pCntntNd, nCntnt1 );
+        if( ULONG_MAX != nNode2 )
+        {
+            aPam.SetMark();
+            aPam.GetMark()->nNode = nNode2;
+            pCntntNd = rNds[ aPam.GetMark()->nNode ]->GetCntntNode();
+            ASSERT( pCntntNd, "Falscher Node fuer den Bookmark" );
+            aPam.GetMark()->nContent.Assign( pCntntNd, nCntnt2 );
+        }
+        pDoc->MakeBookmark( aPam, KeyCode( nKeyCode ), aName, aShortName );
+    }
+    else
+    {
+        // dann muss das noch vorhandene manipuliert werden
+        SwBookmark* const* ppBkmks = pDoc->GetBookmarks().GetData();
+        for( USHORT n = pDoc->GetBookmarks().Count(); n; --n, ++ppBkmks )
+            if( (*ppBkmks)->GetName() == aName )
+            {
+                ULONG nNd;
+                USHORT nCnt;
+                SwPosition* pPos;
+                if( BKMK_POS == nTyp )
+                {
+                    if( !nNode2 && !(*ppBkmks)->GetOtherPos() )
+                    {
+                        // dann muss der neu angelegt werden.
+                        SwPaM aPam( (*ppBkmks)->GetPos() );
+                        aPam.SetMark();
+                        aPam.GetPoint()->nNode = nNode1;
+                        aPam.GetPoint()->nContent.Assign(
+                                rNds[ nNode1 ]->GetCntntNode(), nCntnt1 );
+
+                        pDoc->DelBookmark( pDoc->GetBookmarks().Count() - n );
+                        pDoc->MakeBookmark( aPam, KeyCode( nKeyCode ), aName, aShortName, BOOKMARK );
+                        break;
+
+                    }
+                    nNd = nNode1;
+                    nCnt = nCntnt1;
+                    pPos = (SwPosition*)&(*ppBkmks)->GetPos();
+                }
+                else
+                {
+                    if( !(*ppBkmks)->GetOtherPos() )
+                    {
+                        // dann muss der neu angelegt werden.
+                        SwPaM aPam( (*ppBkmks)->GetPos() );
+                        aPam.SetMark();
+                        aPam.GetMark()->nNode = nNode2;
+                        aPam.GetMark()->nContent.Assign(
+                                rNds[ nNode2 ]->GetCntntNode(), nCntnt2 );
+
+                        pDoc->DelBookmark( pDoc->GetBookmarks().Count() - n );
+                        pDoc->MakeBookmark( aPam, KeyCode( nKeyCode ), aName, aShortName, BOOKMARK );
+                        break;
+                    }
+                    nNd = nNode2;
+                    nCnt = nCntnt2;
+                    pPos = (SwPosition*)(*ppBkmks)->GetOtherPos();
+                }
+
+                pPos->nNode = nNd;
+                pPos->nContent.Assign( rNds[ pPos->nNode ]->GetCntntNode(),
+                                        nCnt );
+                break;
+            }
+    }
+
+    pDoc->DoUndo( bDoesUndo );
+}
+
+
+BOOL SwHstryBookmark::IsEqualBookmark( const SwBookmark& rBkmk )
+{
+    return nNode1 == rBkmk.GetPos().nNode.GetIndex() &&
+           nCntnt1 == rBkmk.GetPos().nContent.GetIndex() &&
+            aName == rBkmk.GetName() &&
+            aShortName == rBkmk.GetShortName() &&
+            nKeyCode == (rBkmk.GetKeyCode().GetCode() |
+                        rBkmk.GetKeyCode().GetModifier())
+            ? TRUE : FALSE;
+}
+
+/*************************************************************************/
+
+
+SwHstrySetAttrSet::SwHstrySetAttrSet( const SfxItemSet& rSet, ULONG nNodePos,
+                                        const SvUShortsSort& rSetArr )
+    : SwHstryHint( HSTRY_SETATTRSET ),
+    nNode( nNodePos ), aOldSet( rSet ), nNumLvl( NO_NUMBERING ),
+    nSetStt( USHRT_MAX ), aResetArr( 0, 4 )
+{
+    SfxItemIter aIter( aOldSet ), aOrigIter( rSet );
+    const SfxPoolItem* pItem = aIter.FirstItem(),
+                     * pOrigItem = aOrigIter.FirstItem();
+    do {
+        if( !rSetArr.Seek_Entry( pOrigItem->Which() ))
+        {
+            aResetArr.Insert( pOrigItem->Which(), aResetArr.Count() );
+            aOldSet.ClearItem( pOrigItem->Which() );
+        }
+        else
+        {
+            switch( pItem->Which() )
+            {
+            case RES_PAGEDESC:
+                ((SwFmtPageDesc*)pItem)->ChgDefinedIn( 0 );
+                break;
+
+            case RES_PARATR_DROP:
+                ((SwFmtDrop*)pItem)->ChgDefinedIn( 0 );
+                break;
+
+            case RES_BOXATR_FORMULA:
+                {
+                    //JP 20.04.98: Bug 49502 - wenn eine Formel gesetzt ist, nie den
+                    //              Value mit sichern. Der muss gegebenfalls neu
+                    //              errechnet werden!
+                    //JP 30.07.98: Bug 54295 - Formeln immer im Klartext speichern
+                    aOldSet.ClearItem( RES_BOXATR_VALUE );
+
+                    SwTblBoxFormula& rNew = *(SwTblBoxFormula*)pItem;
+                    if( rNew.IsIntrnlName() )
+                    {
+                        const SwTblBoxFormula& rOld = (SwTblBoxFormula&)rSet.Get( RES_BOXATR_FORMULA );
+                        const SwNode* pNd = rOld.GetNodeOfFormula();
+                        if( pNd && 0 != (pNd = pNd->FindTableNode() ))
+                        {
+                            SwTableFmlUpdate aMsgHnt( &((SwTableNode*)pNd)->GetTable() );
+                            aMsgHnt.eFlags = TBL_BOXNAME;
+                            rNew.ChgDefinedIn( rOld.GetDefinedIn() );
+                            rNew.ChangeState( &aMsgHnt );
+                        }
+                    }
+                    rNew.ChgDefinedIn( 0 );
+                }
+                break;
+
+            case RES_PARATR_NUMRULE:
+                if( ((SwNumRuleItem*)pItem)->GetDefinedIn() &&
+                    ((SwNumRuleItem*)pItem)->GetDefinedIn()->ISA( SwTxtNode ))
+                {
+                    SwTxtNode* pTNd = (SwTxtNode*)((SwNumRuleItem*)pItem)->GetDefinedIn();
+                    if( pTNd->GetNum() )
+                    {
+                        nNumLvl = pTNd->GetNum()->GetLevel();
+                        bNumStt = pTNd->GetNum()->IsStart();
+                        nSetStt = pTNd->GetNum()->GetSetValue();
+                    }
+                }
+                ((SwNumRuleItem*)pItem)->ChgDefinedIn( 0 );
+                break;
+            }
+        }
+
+        if( aIter.IsAtEnd() )
+            break;
+        pItem = aIter.NextItem();
+        pOrigItem = aOrigIter.NextItem();
+    } while( TRUE );
+}
+
+void SwHstrySetAttrSet::SetInDoc( SwDoc* pDoc, BOOL )
+{
+    BOOL bDoesUndo = pDoc->DoesUndo();
+    pDoc->DoUndo( FALSE );
+
+    SwNode * pNode = pDoc->GetNodes()[ nNode ];
+    if( pNode->IsCntntNode() )
+    {
+        ((SwCntntNode*)pNode)->SetAttr( aOldSet );
+        const SfxPoolItem* pItem;
+        if( ((SwCntntNode*)pNode)->GetpSwAttrSet() && SFX_ITEM_SET ==
+            ((SwCntntNode*)pNode)->GetpSwAttrSet()->GetItemState(
+            RES_PARATR_NUMRULE, FALSE, &pItem ) &&
+            NO_NUMBERING != nNumLvl &&
+            ((SwTxtNode*)pNode)->GetNum() )
+        {
+            SwNodeNum aNum( *((SwTxtNode*)pNode)->GetNum() );
+            aNum.SetLevel( nNumLvl );
+            aNum.SetStart( bNumStt );
+            aNum.SetSetValue( nSetStt );
+            ((SwTxtNode*)pNode)->UpdateNum( aNum );
+        }
+        if( aResetArr.Count() )
+            ((SwCntntNode*)pNode)->ResetAttr( aResetArr );
+    }
+    else if( pNode->IsTableNode() )
+    {
+        SwFmt& rFmt = *((SwTableNode*)pNode)->GetTable().GetFrmFmt();
+        rFmt.SetAttr( aOldSet );
+        if( aResetArr.Count() )
+            rFmt.ResetAttr( *aResetArr.GetData() );
+    }
+
+    pDoc->DoUndo( bDoesUndo );
+}
+
+/*************************************************************************/
+
+
+SwHstryResetAttrSet::SwHstryResetAttrSet( const SfxItemSet& rSet,
+                    ULONG nNodePos, xub_StrLen nAttrStt, xub_StrLen nAttrEnd )
+    : SwHstryHint( HSTRY_RESETATTRSET ),
+    nNode( nNodePos ), nStart( nAttrStt ), nEnd( nAttrEnd ),
+    aArr( (BYTE)rSet.Count() )
+{
+    SfxItemIter aIter( rSet );
+    while( TRUE )
+    {
+        aArr.Insert( aIter.GetCurItem()->Which() ,aArr.Count() );
+        if( aIter.IsAtEnd() )
+            break;
+        aIter.NextItem();
+    }
+}
+
+
+void SwHstryResetAttrSet::SetInDoc( SwDoc* pDoc, BOOL )
+{
+    BOOL bDoesUndo = pDoc->DoesUndo();
+    pDoc->DoUndo( FALSE );
+
+    SwCntntNode * pCntntNd = pDoc->GetNodes()[ nNode ]->GetCntntNode();
+    ASSERT( pCntntNd, "wo ist mein CntntNode" );
+
+    const USHORT* pArr = aArr.GetData();
+    if( USHRT_MAX == nEnd && USHRT_MAX == nStart )
+    {
+        // kein Bereich also Schnittstelle zum Content-Node
+        for( USHORT n = aArr.Count(); n; --n, ++pArr )
+            pCntntNd->ResetAttr( *pArr );
+    }
+    else
+    {
+        // Bereich: also Schnittstelle zum Text-Node
+        for( USHORT n = aArr.Count(); n; --n, ++pArr )
+            ((SwTxtNode*)pCntntNd)->Delete( *pArr, nStart, nEnd );
+    }
+
+    pDoc->DoUndo( bDoesUndo );
+}
+
+
+/*************************************************************************/
+
+
+SwHstryChgFlyAnchor::SwHstryChgFlyAnchor( const SwFrmFmt& rFmt )
+    : SwHstryHint( HSTRY_CHGFLYANCHOR ),
+    pFmt( (SwFrmFmt*)&rFmt )
+{
+    const SwFmtAnchor& rAnchor = rFmt.GetAnchor();
+    nOldPos = rAnchor.GetCntntAnchor()->nNode.GetIndex();
+    if( FLY_AUTO_CNTNT == rAnchor.GetAnchorId() )
+        nOldCnt = rAnchor.GetCntntAnchor()->nContent.GetIndex();
+    else
+        nOldCnt = STRING_MAXLEN;
+}
+
+
+void SwHstryChgFlyAnchor::SetInDoc( SwDoc* pDoc, BOOL bTmpSet )
+{
+    BOOL bDoesUndo = pDoc->DoesUndo();
+    pDoc->DoUndo( FALSE );
+
+    USHORT nPos = pDoc->GetSpzFrmFmts()->GetPos( pFmt );
+    if( USHRT_MAX != nPos )         // Format noch vorhanden
+    {
+        SwFmtAnchor aTmp( pFmt->GetAnchor() );
+
+        SwNode* pNd = pDoc->GetNodes()[ nOldPos  ];
+        SwPosition aPos( *pNd );
+        if( STRING_MAXLEN != nOldCnt )
+            aPos.nContent.Assign( (SwCntntNode*)pNd, nOldCnt );
+        aTmp.SetAnchor( &aPos );
+
+        // damit das Layout nicht durcheinander kommt!
+        SwCntntNode* pCNd = pNd->GetCntntNode();
+        if( !pCNd || !pCNd->GetFrm( 0, 0, FALSE ) )
+            pFmt->DelFrms();
+
+        pFmt->SetAttr( aTmp );
+    }
+    pDoc->DoUndo( bDoesUndo );
+}
+
+
+/*************************************************************************/
+
+SwHstryChgFlyChain::SwHstryChgFlyChain( const SwFlyFrmFmt& rFmt,
+                                        const SwFmtChain& rAttr )
+    : SwHstryHint( HSTRY_CHGFLYCHAIN ),
+    pPrevFmt( rAttr.GetPrev() ),
+    pNextFmt( rAttr.GetNext() ),
+    pFlyFmt( (SwFlyFrmFmt*)&rFmt )
+{
+}
+
+
+void SwHstryChgFlyChain::SetInDoc( SwDoc* pDoc, BOOL bTmpSet )
+{
+    if( USHRT_MAX != pDoc->GetSpzFrmFmts()->GetPos( pFlyFmt ) )
+    {
+        SwFmtChain aChain;
+        if( pPrevFmt && USHRT_MAX != pDoc->GetSpzFrmFmts()->GetPos( pPrevFmt ))
+        {
+            aChain.SetPrev( pPrevFmt );
+            SwFmtChain aTmp( pPrevFmt->GetChain() );
+            aTmp.SetNext( pFlyFmt );
+            pPrevFmt->SetAttr( aTmp );
+        }
+        if( pNextFmt && USHRT_MAX != pDoc->GetSpzFrmFmts()->GetPos( pNextFmt ))
+        {
+            aChain.SetNext( pNextFmt );
+            SwFmtChain aTmp( pNextFmt->GetChain() );
+            aTmp.SetPrev( pFlyFmt );
+            pNextFmt->SetAttr( aTmp );
+        }
+
+        if( aChain.GetNext() || aChain.GetPrev()  )
+            pFlyFmt->SetAttr( aChain );
+    }
+}
+
+
+
+/*  */
+
+
+SwHistory::SwHistory( USHORT nInitSz, USHORT nGrowSz )
+    : SwpHstry( (BYTE)nInitSz, (BYTE)nGrowSz ), nEndDiff( 0 )
+{}
+
+
+SwHistory::~SwHistory()
+{
+    Delete( 0 );
+}
+
+
+/*************************************************************************
+|*
+|*    void SwHistory::Add()
+|*
+|*    Beschreibung      Dokument 1.0
+|*    Ersterstellung    JP 18.02.91
+|*    Letzte Aenderung  JP 18.02.91
+|*
+*************************************************************************/
+
+
+void SwHistory::Add( const SfxPoolItem* pOldValue, const SfxPoolItem* pNewValue,
+                    ULONG nNodeIdx )
+{
+    ASSERT( !nEndDiff, "nach REDO wurde die History noch nicht geloescht" );
+
+    USHORT nWhich = pNewValue->Which();
+    if( (nWhich >= POOLATTR_END) || (nWhich == RES_TXTATR_FIELD) )
+        return;
+
+    // kein default Attribut ??
+    SwHstryHint * pHt;
+#ifdef JP_NEWCORE
+    if( pOldValue && pOldValue->GetFmt() &&
+        ( !pNewValue->GetFmt() || pOldValue->GetFmt()==pNewValue->GetFmt()) )
+#else
+    if( pOldValue && pOldValue != GetDfltAttr( pOldValue->Which() ) )
+#endif
+        pHt = new SwSetFmtHint( (SfxPoolItem*)pOldValue, nNodeIdx );
+    else
+        pHt = new SwResetFmtHint( (SfxPoolItem*)pNewValue, nNodeIdx );
+    Insert( pHt, Count() );
+}
+
+
+void SwHistory::Add( const SwTxtAttr* pHint, ULONG nNodeIdx, BOOL bNewAttr )
+{
+    ASSERT( !nEndDiff, "nach REDO wurde die History noch nicht geloescht" );
+
+    SwHstryHint * pHt;
+    USHORT nAttrWhich = pHint->Which();
+
+    if( !bNewAttr )
+    {
+        switch ( nAttrWhich )
+        {
+        case RES_TXTATR_FTN:
+        {
+            pHt = new SwSetFtnHint( (SwTxtFtn*)pHint, nNodeIdx );
+            const SwDoc* pDoc = ((SwTxtFtn*)pHint)->GetTxtNode().GetDoc();
+            SwModify* pCallBack = pDoc->GetUnoCallBack();
+            SwPtrMsgPoolItem aMsgHint( RES_FOOTNOTE_DELETED, (void*)pHint );
+            pCallBack->Modify(&aMsgHint, &aMsgHint );
+        }
+        break;
+        case RES_TXTATR_FLYCNT:
+            pHt = new SwHstryTxtFlyCnt( (SwTxtFlyCnt*)pHint );
+            break;
+        case RES_TXTATR_FIELD:
+            pHt = new SwSetTxtFldHint( (SwTxtFld*)pHint, nNodeIdx );
+            break;
+        case RES_TXTATR_TOXMARK:
+            pHt = new SwSetTOXMarkHint( (SwTxtTOXMark*)pHint, nNodeIdx );
+            break;
+        case RES_TXTATR_REFMARK:
+        {
+            pHt = new SwSetRefMarkHint( (SwTxtRefMark*)pHint, nNodeIdx );
+            const SwDoc* pDoc = ((SwTxtFtn*)pHint)->GetTxtNode().GetDoc();
+            SwModify* pCallBack = pDoc->GetUnoCallBack();
+            SwPtrMsgPoolItem aMsgHint( RES_REFMARK_DELETED, (void*)pHint );
+            pCallBack->Modify(&aMsgHint, &aMsgHint );
+        }
+        break;
+        default:
+            pHt = new SwSetTxtHint((SwTxtAttr*)pHint, nNodeIdx );
+        }
+    }
+    else
+    {
+        pHt = new SwResetTxtHint( pHint->Which(), *pHint->GetStart(),
+                                    *pHint->GetAnyEnd(), nNodeIdx );
+    }
+    Insert( pHt, Count() );
+}
+
+
+void SwHistory::Add( const SwFmtColl* pColl, ULONG nNodeIdx, BYTE nWhichNd )
+{
+    ASSERT( !nEndDiff, "nach REDO wurde die History noch nicht geloescht" );
+    SwHstryHint * pHt = new SwChgFmtColl( pColl, nNodeIdx, nWhichNd );
+    Insert( pHt, Count() );
+}
+
+
+void SwHistory::Add( const SwFmt* pFmt, ULONG nNodeIdx, BYTE nWhichNd )
+{
+    ASSERT( !nEndDiff, "nach REDO wurde die History noch nicht geloescht" );
+    SwHstryHint * pHt;
+    const USHORT nWh = pFmt->Which();
+    if( RES_FLYFRMFMT == nWh || RES_DRAWFRMFMT == nWh )
+    {
+        pHt = new SwHstryTxtFlyCnt( (SwFlyFrmFmt*)pFmt );
+        Insert( pHt, Count() );
+    }
+}
+
+
+
+// JP 21.03.94: Bookmarks jetzt auch in die History mitaufnehmen
+void SwHistory::Add( const SwBookmark& rBkmk, BYTE nTyp )
+{
+    ASSERT( !nEndDiff, "nach REDO wurde die History noch nicht geloescht" );
+    SwHstryHint * pHt = new SwHstryBookmark( rBkmk, nTyp );
+    Insert( pHt, Count() );
+}
+
+
+void SwHistory::Add( const SwFrmFmt& rFmt )
+{
+    SwHstryHint * pHt = new SwHstryChgFlyAnchor( rFmt );
+    Insert( pHt, Count() );
+}
+
+void SwHistory::Add( const SwFlyFrmFmt& rFmt, USHORT& rSetPos )
+{
+    ASSERT( !nEndDiff, "nach REDO wurde die History noch nicht geloescht" );
+    SwHstryHint * pHt;
+    const USHORT nWh = rFmt.Which();
+    if( RES_FLYFRMFMT == nWh || RES_DRAWFRMFMT == nWh )
+    {
+        pHt = new SwHstryTxtFlyCnt( (SwFlyFrmFmt*)&rFmt );
+        Insert( pHt, Count() );
+
+        const SwFmtChain* pChainItem;
+        if( SFX_ITEM_SET == rFmt.GetItemState( RES_CHAIN, FALSE,
+            (const SfxPoolItem**)&pChainItem ))
+        {
+            if( pChainItem->GetNext() || pChainItem->GetPrev() )
+            {
+                SwHstryHint * pHt = new SwHstryChgFlyChain( rFmt, *pChainItem );
+                Insert( pHt, rSetPos++ );
+                if ( pChainItem->GetNext() )
+                {
+                    SwFmtChain aTmp( pChainItem->GetNext()->GetChain() );
+                    aTmp.SetPrev( 0 );
+                    pChainItem->GetNext()->SetAttr( aTmp );
+                }
+                if ( pChainItem->GetPrev() )
+                {
+                    SwFmtChain aTmp( pChainItem->GetPrev()->GetChain() );
+                    aTmp.SetNext( 0 );
+                    pChainItem->GetPrev()->SetAttr( aTmp );
+                }
+            }
+            ((SwFlyFrmFmt&)rFmt).ResetAttr( RES_CHAIN );
+        }
+    }
+}
+
+void SwHistory::Add( const SwTxtFtn& rFtn )
+{
+    SwHstryHint *pHt = new SwSetFtnHint( rFtn );
+    Insert( pHt, Count() );
+}
+
+
+/*************************************************************************
+|*
+|*    BOOL SwHistory::Rollback()
+|*
+|*    Beschreibung      Dokument 1.0
+|*    Ersterstellung    JP 18.02.91
+|*    Letzte Aenderung  JP 18.02.91
+|*
+*************************************************************************/
+
+
+BOOL SwHistory::Rollback( SwDoc* pDoc, USHORT nStart )
+{
+    if( !Count() )
+        return FALSE;
+
+    SwHstryHint * pHHt;
+    USHORT i;
+    for( i = Count(); i > nStart ; )
+    {
+        pHHt = operator[]( --i );
+        pHHt->SetInDoc( pDoc, FALSE );
+        delete pHHt;
+    }
+    SwpHstry::Remove( nStart, Count() - nStart );
+    nEndDiff = 0;
+    return TRUE;
+}
+
+
+
+BOOL SwHistory::TmpRollback( SwDoc* pDoc, USHORT nStart, BOOL bToFirst )
+{
+    USHORT nEnd = Count() - nEndDiff;
+    if( !Count() || !nEnd || nStart >= nEnd )
+        return FALSE;
+
+    SwHstryHint * pHHt;
+    if( bToFirst )
+        for( ; nEnd > nStart; ++nEndDiff )
+        {
+            pHHt = operator[]( --nEnd );
+            pHHt->SetInDoc( pDoc, TRUE );
+        }
+    else
+        for( ; nStart < nEnd; ++nEndDiff, ++nStart )
+        {
+            pHHt = operator[]( nStart );
+            pHHt->SetInDoc( pDoc, TRUE );
+        }
+    return TRUE;
+}
+
+
+void SwHistory::Delete( USHORT nStart )
+{
+    for( USHORT n = Count(); n > nStart; )
+        SwpHstry::DeleteAndDestroy( --n, 1 );
+    nEndDiff = 0;
+}
+
+
+USHORT SwHistory::SetTmpEnd( USHORT nNewTmpEnd )
+{
+    ASSERT( nNewTmpEnd <= Count(),  "das temp. Ende ist zu gross" );
+
+    USHORT nOld = Count() - nEndDiff;
+    nEndDiff = Count() - nNewTmpEnd;
+
+    // rufe bei allen SwHstryFlyCnt das Redo vom UndoObject auf. Dadurch
+    // werden die Formate der Fly gesichert !!
+    for( USHORT n = nOld; n < nNewTmpEnd; n++ )
+        if( HSTRY_FLYCNT == (*this)[ n ]->Which() )
+            ((SwHstryTxtFlyCnt*)(*this)[ n ])->GetUDelLFmt()->Redo();
+
+    return nOld;
+}
+
+void SwHistory::CopyFmtAttr( const SfxItemSet& rSet, ULONG nNodeIdx )
+{
+    if( rSet.Count() )
+    {
+        SfxItemIter aIter( rSet );
+        do {
+            if( (SfxPoolItem*)-1 != aIter.GetCurItem() )
+            {
+                const SfxPoolItem* pNew = aIter.GetCurItem();
+                Add( pNew, pNew, nNodeIdx );
+            }
+            if( aIter.IsAtEnd() )
+                break;
+            aIter.NextItem();
+        } while( TRUE );
+    }
+}
+
+void SwHistory::CopyAttr( const SwpHints* pHts, ULONG nNodeIdx,
+                          xub_StrLen nStt, xub_StrLen nEnd, BOOL bFields )
+{
+    if( !pHts  )
+        return;
+
+    // kopiere alle Attribute aus dem TextNode die
+    // im Bereich von Position nStt bis Len liegen
+    const SwTxtAttr* pHt;
+    xub_StrLen nAttrStt;
+    const xub_StrLen * pEndIdx;
+    for( USHORT n = 0; n < pHts->Count(); n++ )
+    {
+        // BP: nAttrStt muss auch bei !pEndIdx gesetzt werden
+        nAttrStt = *(pHt = (*pHts)[n])->GetStart();
+// JP: ???? wieso nAttrStt >= nEnd
+//      if( 0 != ( pEndIdx = pHt->GetEnd() ) && nAttrStt >= nEnd )
+        if( 0 != ( pEndIdx = pHt->GetEnd() ) && nAttrStt > nEnd )
+            break;
+
+        // Flys und Ftn nie kopieren !!
+        BOOL bNextAttr = FALSE;
+        switch( pHt->Which() )
+        {
+        case RES_TXTATR_FIELD:
+        case RES_TXTATR_HARDBLANK:
+            // keine Felder, .. kopieren ??
+            if( !bFields )
+                bNextAttr = TRUE;
+            break;
+        case RES_TXTATR_FLYCNT:
+        case RES_TXTATR_FTN:
+            bNextAttr = TRUE;
+            break;
+        }
+
+        if( bNextAttr )
+           continue;
+
+        // alle Attribute, die irgendwie in diesem Bereich liegen speichern
+        if( nStt <= nAttrStt )
+        {
+            if( nEnd > nAttrStt
+// JP: ???? wieso nAttrStt >= nEnd
+//              || (nEnd == nAttrStt && (!pEndIdx || nEnd == pEndIdx->GetIndex()))
+            )
+                Add( pHt, nNodeIdx, FALSE );
+        }
+        else if( pEndIdx && nStt < *pEndIdx )
+            Add( pHt, nNodeIdx, FALSE );
+    }
+}
+
+
+/*************************************************************************/
+
+// Klasse zum Registrieren der History am Node, Format, HintsArray, ...
+
+SwRegHistory::SwRegHistory( SwHistory* pHst )
+    : SwClient( 0 ), pHstry( pHst ), nNodeIdx( ULONG_MAX )
+{
+    if( pHst )
+        _MakeSetWhichIds();
+}
+
+SwRegHistory::SwRegHistory( SwModify* pRegIn, const SwNode& rNd,
+                            SwHistory* pHst )
+    : SwClient( pRegIn ), pHstry( pHst ), nNodeIdx( rNd.GetIndex() )
+{
+    if( pHst )
+        _MakeSetWhichIds();
+}
+
+
+SwRegHistory::SwRegHistory( SwTxtNode* pTxtNode, SwTxtAttr* pTxtHt,
+                            USHORT nFlags, SwHistory* pHst )
+    : SwClient( 0 ), pHstry( pHst ), nNodeIdx( pTxtNode->GetIndex() )
+{
+    ASSERT( pTxtHt->Which() >= RES_TXTATR_BEGIN &&
+        pTxtHt->Which() < RES_TXTATR_END, "SwRegHistory: Falsches Attribut" );
+    if( !pTxtHt->GetEnd() )
+    {
+        if( pTxtNode->Insert( pTxtHt, nFlags ) && pHst )
+            pHst->Add( pTxtHt, nNodeIdx, TRUE );
+    }
+    else if( pTxtNode->GetpSwpHints() && pHst )
+    {
+        pTxtNode->GetpSwpHints()->Register( this );
+        pTxtNode->Insert( pTxtHt, nFlags );
+        pTxtNode->GetpSwpHints()->DeRegister();
+    }
+    else if( pTxtNode->Insert( pTxtHt, nFlags ) && pHst )
+        pHst->Add( pTxtHt, nNodeIdx, TRUE );
+}
+
+
+SwRegHistory::SwRegHistory( const SwNode& rNd, SwHistory* pHst )
+    : SwClient( 0 ), pHstry( pHst ), nNodeIdx( rNd.GetIndex() )
+{
+    if( pHstry )
+        _MakeSetWhichIds();
+}
+
+
+
+void SwRegHistory::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew )
+{
+    // Attribut erfragen ?? ( mal sehen )
+    if( pHstry && ( pOld || pNew ) )
+    {
+        if( pNew->Which() < POOLATTR_END )
+            pHstry->Add( pOld, pNew, nNodeIdx );
+        else if( RES_ATTRSET_CHG == pNew->Which() )
+        {
+            SwHstryHint* pNewHstr;
+            const SfxItemSet& rSet = *((SwAttrSetChg*)pOld)->GetChgSet();
+            if( 1 < rSet.Count() )
+                pNewHstr = new SwHstrySetAttrSet( rSet, nNodeIdx,
+                                                    aSetWhichIds );
+            else
+            {
+                const SfxPoolItem* pItem = SfxItemIter( rSet ).FirstItem();
+                if( aSetWhichIds.Seek_Entry( pItem->Which() ) )
+                    pNewHstr = new SwSetFmtHint( pItem, nNodeIdx );
+                else
+                    pNewHstr = new SwResetFmtHint( pItem, nNodeIdx );
+            }
+            pHstry->Insert( pNewHstr, pHstry->Count() );
+        }
+    }
+}
+
+
+
+void SwRegHistory::Add( SwTxtAttr* pHt, const BOOL bNew )
+{
+    pHstry->Add( pHt, nNodeIdx, bNew );
+}
+
+
+SwRegHistory::SwRegHistory( SwTxtNode* pTxtNode, const SfxItemSet& rSet,
+                            xub_StrLen nStart, xub_StrLen nEnd, USHORT nFlags,
+                            SwHistory* pHst )
+    : SwClient( pTxtNode ), pHstry( pHst ), nNodeIdx( pTxtNode->GetIndex() )
+{
+    if( !rSet.Count() )
+        return;
+
+    register BOOL bInsert;
+
+    if( pTxtNode->GetpSwpHints() && pHst )
+    {
+        pTxtNode->GetpSwpHints()->Register( this );
+        bInsert = pTxtNode->SetAttr( rSet, nStart, nEnd, nFlags );
+        // Achtung: Durch das Einfuegen eines Attributs kann das Array
+        // geloescht werden!!! Wenn das einzufuegende zunaechst ein vorhandenes
+        // loescht, selbst aber nicht eingefuegt werden braucht, weil die
+        // Absatzattribute identisch sind( -> bForgetAttr in SwpHints::Insert )
+        if ( pTxtNode->GetpSwpHints() )
+            pTxtNode->GetpSwpHints()->DeRegister();
+    }
+    else
+        bInsert = pTxtNode->SetAttr( rSet, nStart, nEnd, nFlags );
+
+    if( pHst && bInsert )
+    {
+        SwHstryHint* pNewHstr = new SwHstryResetAttrSet( rSet,
+                                    pTxtNode->GetIndex(), nStart, nEnd );
+        // !!! ----                     /|\
+        // !!! ----                    /|||\
+        // der NodeIndex kann verschoben sein !!
+
+        pHst->Insert( pNewHstr, pHst->Count() );
+    }
+}
+
+void SwRegHistory::RegisterInModify( SwModify* pRegIn, const SwNode& rNd )
+{
+    if( pHstry && pRegIn )
+    {
+        pRegIn->Add( this );
+        nNodeIdx = rNd.GetIndex();
+        _MakeSetWhichIds();
+    }
+    else if( aSetWhichIds.Count() )
+        aSetWhichIds.Remove( 0, aSetWhichIds.Count() );
+}
+
+void SwRegHistory::_MakeSetWhichIds()
+{
+    if( aSetWhichIds.Count() )
+        aSetWhichIds.Remove( 0, aSetWhichIds.Count() );
+
+    if( GetRegisteredIn() )
+    {
+        const SfxItemSet* pSet = 0;
+        if( GetRegisteredIn()->ISA( SwCntntNode ) )
+            pSet = ((SwCntntNode*)GetRegisteredIn())->GetpSwAttrSet();
+        else if( GetRegisteredIn()->ISA( SwFmt ) )
+            pSet = &((SwFmt*)GetRegisteredIn())->GetAttrSet();
+        if( pSet && pSet->Count() )
+        {
+            SfxItemIter aIter( *pSet );
+            USHORT nW = aIter.FirstItem()->Which();
+            while( TRUE )
+            {
+                aSetWhichIds.Insert( nW );
+                if( aIter.IsAtEnd() )
+                    break;
+                nW = aIter.NextItem()->Which();
+            }
+        }
+    }
+}
+
+
+
diff --git a/sw/source/core/undo/unattr.cxx b/sw/source/core/undo/unattr.cxx
new file mode 100644
index 000000000000..ac52cceebe7b
--- /dev/null
+++ b/sw/source/core/undo/unattr.cxx
@@ -0,0 +1,1356 @@
+/*************************************************************************
+ *
+ *  $RCSfile: unattr.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:27 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#define _SVSTDARR_USHORTS
+#define _SVSTDARR_USHORTSSORT
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _SVDMODEL_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_TSTPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVDPAGE_HXX //autogen
+#include 
+#endif
+#ifndef _SFXITEMITER_HXX //autogen
+#include 
+#endif
+
+
+#ifndef _FMTFLCNT_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFTN_HXX //autogen
+#include 
+#endif
+#ifndef _FMTORNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFSIZE_HXX //autogen
+#include 
+#endif
+#ifndef _FRMFMT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTCNTNT_HXX //autogen
+#include 
+#endif
+#ifndef _FTNIDX_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include            // fuer die UndoIds
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _HINTS_HXX
+#include 
+#endif
+#ifndef _SWATRSET_HXX
+#include 
+#endif
+#ifndef _SWTABLE_HXX
+#include 
+#endif
+#ifndef _UNDOBJ_HXX
+#include 
+#endif
+#ifndef _ROLBCK_HXX
+#include 
+#endif
+#ifndef _NDNOTXT_HXX
+#include 
+#endif
+#ifndef _DCONTACT_HXX
+#include 
+#endif
+#ifndef _FTNINFO_HXX
+#include 
+#endif
+#ifndef _REDLINE_HXX
+#include 
+#endif
+#ifndef _SECTION_HXX
+#include 
+#endif
+
+inline SwDoc& SwUndoIter::GetDoc() const
+{ return *pAktPam->GetDoc(); }
+
+// -----------------------------------------------------
+
+_UndoFmtAttr::_UndoFmtAttr( SwFmt& rFmt, BOOL bSvDrwPt )
+    : SwClient( &rFmt ), pUndo( 0 ), bSaveDrawPt( bSvDrwPt )
+{
+}
+
+void _UndoFmtAttr::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew )
+{
+    if( pOld && pNew )
+    {
+        if( POOLATTR_END >= pOld->Which() )
+        {
+            if( pUndo )
+                pUndo->PutAttr( *pOld );
+            else
+                pUndo = new SwUndoFmtAttr( *pOld, *(SwFmt*)pRegisteredIn,
+                                            bSaveDrawPt );
+        }
+        else if( RES_ATTRSET_CHG == pOld->Which() )
+        {
+            if( pUndo )
+            {
+                SfxItemIter aIter( *((SwAttrSetChg*)pOld)->GetChgSet() );
+                const SfxPoolItem* pItem = aIter.GetCurItem();
+                while( pItem )
+                {
+                    pUndo->PutAttr( *pItem );
+                    if( aIter.IsAtEnd() )
+                        break;
+                    pItem = aIter.NextItem();
+                }
+            }
+            else
+                pUndo = new SwUndoFmtAttr( *((SwAttrSetChg*)pOld)->GetChgSet(),
+                                        *(SwFmt*)pRegisteredIn, bSaveDrawPt );
+        }
+        else
+            SwClient::Modify( pOld, pNew );
+    }
+    else
+        SwClient::Modify( pOld, pNew );
+}
+
+SwUndoFmtAttr::SwUndoFmtAttr( const SfxItemSet& rSet, SwFmt& rChgFmt,
+                                BOOL bSvDrwPt )
+    : SwUndo( UNDO_INSFMTATTR ), pFmt( &rChgFmt ),
+    nFmtWhich( rChgFmt.Which() ), nNode( 0 ), bSaveDrawPt( bSvDrwPt )
+{
+    pOldSet = new SfxItemSet( rSet );
+    Init();
+}
+
+SwUndoFmtAttr::SwUndoFmtAttr( const SfxPoolItem& rItem, SwFmt& rChgFmt,
+                                BOOL bSvDrwPt )
+    : SwUndo( UNDO_INSFMTATTR ), pFmt( &rChgFmt ),
+    nFmtWhich( rChgFmt.Which() ), nNode( 0 ), bSaveDrawPt( bSvDrwPt )
+{
+    pOldSet = pFmt->GetAttrSet().Clone( FALSE );
+    pOldSet->Put( rItem );
+    Init();
+}
+
+void SwUndoFmtAttr::Init()
+{
+    // Ankerwechsel gesondert behandeln
+    if( SFX_ITEM_SET == pOldSet->GetItemState( RES_ANCHOR, FALSE ))
+        SaveFlyAnchor( bSaveDrawPt );
+    else if( RES_FRMFMT == nFmtWhich )
+    {
+        SwDoc* pDoc = pFmt->GetDoc();
+        if( USHRT_MAX !=
+            pDoc->GetTblFrmFmts()->GetPos( (const SwFrmFmtPtr)pFmt ))
+        {
+            // TabellenFormat -> Tabellen Index Position merken, TabellenFormate
+            //                      sind fluechtig!
+            SwClient* pTbl = SwClientIter( *pFmt ).First( TYPE( SwTable ));
+            if( pTbl )
+                nNode = ((SwTable*)pTbl)->GetTabSortBoxes()[ 0 ]->
+                            GetSttNd()->FindTableNode()->GetIndex();
+        }
+        else if( USHRT_MAX !=
+            pDoc->GetSections().GetPos( (const SwSectionFmtPtr)pFmt ))
+            nNode = pFmt->GetCntnt().GetCntntIdx()->GetIndex();
+    }
+}
+
+SwUndoFmtAttr::~SwUndoFmtAttr()
+{
+    delete pOldSet;
+}
+
+void SwUndoFmtAttr::Undo( SwUndoIter& rUndoIter)
+{
+    if( !pOldSet || !pFmt || !IsFmtInDoc( &rUndoIter.GetDoc() ))
+        return;
+
+    if( SFX_ITEM_SET == pOldSet->GetItemState( RES_ANCHOR, FALSE ))
+    {
+        RestoreFlyAnchor( rUndoIter );
+        SaveFlyAnchor();
+    }
+    else
+    {
+        _UndoFmtAttr aTmp( *pFmt, bSaveDrawPt );
+        pFmt->SetAttr( *pOldSet );
+        if( aTmp.pUndo )
+        {
+            delete pOldSet;
+            pOldSet = aTmp.pUndo->pOldSet;
+            aTmp.pUndo->pOldSet = 0;    // den Pointer auf 0 setzen (nicht
+                                        // doppelt loeschen) !!
+            delete aTmp.pUndo;          // Undo-Object wieder loeschen
+        }
+        else
+            pOldSet->ClearItem();
+
+        if( RES_FLYFRMFMT == nFmtWhich || RES_DRAWFRMFMT == nFmtWhich )
+            rUndoIter.pSelFmt = (SwFrmFmt*)pFmt;
+    }
+}
+
+int SwUndoFmtAttr::IsFmtInDoc( SwDoc* pDoc )
+{
+    // suche im Dokument nach dem Format. Ist es nicht mehr vorhanden
+    // so wird das Attribut nicht mehr gesetzt !
+    USHORT nPos = USHRT_MAX;
+    switch( nFmtWhich )
+    {
+    case RES_TXTFMTCOLL:
+        nPos = pDoc->GetTxtFmtColls()->GetPos(
+                                        (const SwTxtFmtCollPtr)pFmt );
+        break;
+
+    case RES_GRFFMTCOLL:
+        nPos = pDoc->GetGrfFmtColls()->GetPos(
+                                        (const SwGrfFmtCollPtr)pFmt );
+        break;
+    case RES_CHRFMT:
+        nPos = pDoc->GetCharFmts()->GetPos(
+                                    (const SwCharFmtPtr)pFmt );
+        break;
+
+    case RES_FRMFMT:
+        if( nNode && nNode < pDoc->GetNodes().Count() )
+        {
+            SwNode* pNd = pDoc->GetNodes()[ nNode ];
+            if( pNd->IsTableNode() )
+            {
+                pFmt = ((SwTableNode*)pNd)->GetTable().GetFrmFmt();
+                nPos = 0;
+                break;
+            }
+            else if( pNd->IsSectionNode() )
+            {
+                pFmt = ((SwSectionNode*)pNd)->GetSection().GetFmt();
+                nPos = 0;
+                break;
+            }
+        }
+        // kein break!
+    case RES_DRAWFRMFMT:
+    case RES_FLYFRMFMT:
+        if( USHRT_MAX == ( nPos = pDoc->GetSpzFrmFmts()->GetPos(
+                            (const SwFrmFmtPtr)pFmt )) )
+            nPos = pDoc->GetFrmFmts()->GetPos(
+                            (const SwFrmFmtPtr)pFmt );
+        break;
+    }
+
+    // Format nicht mehr vorhanden, zurueck
+    if( USHRT_MAX == nPos )
+        pFmt = 0;
+
+    return 0 != pFmt;
+}
+
+// prueft, ob es noch im Doc ist!
+SwFmt* SwUndoFmtAttr::GetFmt( SwDoc& rDoc )
+{
+    return pFmt && IsFmtInDoc( &rDoc ) ? pFmt : 0;
+}
+
+void SwUndoFmtAttr::Redo( SwUndoIter& rUndoIter)
+{
+    if( !pOldSet || !pFmt || !IsFmtInDoc( &rUndoIter.GetDoc() ))
+        return;
+
+    if( SFX_ITEM_SET == pOldSet->GetItemState( RES_ANCHOR, FALSE ))
+    {
+        RestoreFlyAnchor( rUndoIter );
+        SaveFlyAnchor();
+        return;     // der Rest passierte schon im RestoreFlyAnchor !!
+    }
+    else
+    {
+        _UndoFmtAttr aTmp( *pFmt, bSaveDrawPt );
+        pFmt->SetAttr( *pOldSet );
+        if( aTmp.pUndo )
+        {
+            delete pOldSet;
+            pOldSet = aTmp.pUndo->pOldSet;
+            aTmp.pUndo->pOldSet = 0;    // den Pointer auf 0 setzen (nicht
+                                        // doppelt loeschen) !!
+            delete aTmp.pUndo;          // Undo-Object wieder loeschen
+        }
+        else
+            pOldSet->ClearItem();
+
+        if( RES_FLYFRMFMT == nFmtWhich || RES_DRAWFRMFMT == nFmtWhich )
+            rUndoIter.pSelFmt = (SwFrmFmt*)pFmt;
+    }
+}
+
+void SwUndoFmtAttr::Repeat( SwUndoIter& rUndoIter)
+{
+    if( !pOldSet )
+        return;
+
+    SwUndoFmtAttr* pLast;
+    if( UNDO_INSFMTATTR == rUndoIter.GetLastUndoId() &&
+        ( pLast = ((SwUndoFmtAttr*)rUndoIter.pLastUndoObj))->pOldSet &&
+        pLast->pFmt )
+        return;
+
+    switch( nFmtWhich )
+    {
+    case RES_GRFFMTCOLL:
+        {
+            SwNoTxtNode * pNd = rUndoIter.pAktPam->GetNode()->GetNoTxtNode();
+            if( pNd )
+                rUndoIter.GetDoc().SetAttr( pFmt->GetAttrSet(),
+                                            *pNd->GetFmtColl() );
+        }
+        break;
+
+    case RES_TXTFMTCOLL:
+        {
+            SwTxtNode * pNd = rUndoIter.pAktPam->GetNode()->GetTxtNode();
+            if( pNd )
+                rUndoIter.GetDoc().SetAttr( pFmt->GetAttrSet(),
+                                            *pNd->GetFmtColl() );
+        }
+        break;
+
+//  case RES_CHRFMT:
+//  case RES_FRMFMT:
+
+    case RES_FLYFRMFMT:
+        {
+            // erstal pruefen, ob der Cursor ueberhaupt in einem fliegenden
+            // Rahmen steht. Der Weg ist: suche in allen FlyFrmFormaten
+            // nach dem FlyCntnt-Attribut und teste ob der Cursor in der
+            // entsprechenden Section liegt.
+            SwFrmFmt* pFly = rUndoIter.pAktPam->GetNode()->GetFlyFmt();
+            if( pFly )
+            {
+                // Bug 43672: es duerfen nicht alle Attribute gesetzt werden!
+                if( SFX_ITEM_SET == pFmt->GetAttrSet().GetItemState( RES_CNTNT ))
+                {
+                    SfxItemSet aTmpSet( pFmt->GetAttrSet() );
+                    aTmpSet.ClearItem( RES_CNTNT );
+                    if( aTmpSet.Count() )
+                        rUndoIter.GetDoc().SetAttr( aTmpSet, *pFly );
+                }
+                else
+                    rUndoIter.GetDoc().SetAttr( pFmt->GetAttrSet(), *pFly );
+            }
+            break;
+        }
+    }
+
+    rUndoIter.pLastUndoObj = this;
+}
+
+void SwUndoFmtAttr::PutAttr( const SfxPoolItem& rItem )
+{
+    pOldSet->Put( rItem );
+    if( RES_ANCHOR == rItem.Which() )
+        SaveFlyAnchor( bSaveDrawPt );
+}
+
+void SwUndoFmtAttr::SaveFlyAnchor( BOOL bSvDrwPt )
+{
+    // das Format ist gueltig, sonst wuerde man gar bis hier kommen
+    if( bSvDrwPt )
+    {
+        if( RES_DRAWFRMFMT == pFmt->Which() )
+        {
+            Point aPt( ((SwFrmFmt*)pFmt)->FindSdrObject()->GetRelativePos() );
+            // den alten Wert als zwischenspeichern. Attribut dafuer benutzen,
+            // dadurch bleibt der SwUndoFmtAttr klein.
+            pOldSet->Put( SwFmtFrmSize( ATT_VAR_SIZE, aPt.X(), aPt.Y() ) );
+        }
+/*      else
+        {
+            pOldSet->Put( pFmt->GetVertOrient() );
+            pOldSet->Put( pFmt->GetHoriOrient() );
+        }
+*/  }
+
+    const SwFmtAnchor& rAnchor = (SwFmtAnchor&)pOldSet->Get(
+                                                RES_ANCHOR, FALSE );
+    if( !rAnchor.GetCntntAnchor() )
+        return;
+
+    xub_StrLen nCntnt = 0;
+    switch( rAnchor.GetAnchorId() )
+    {
+    case FLY_IN_CNTNT:
+    case FLY_AUTO_CNTNT:
+        nCntnt = rAnchor.GetCntntAnchor()->nContent.GetIndex();
+    case FLY_AT_CNTNT:
+    case FLY_AT_FLY:
+        nNode = rAnchor.GetCntntAnchor()->nNode.GetIndex();
+        break;
+    default:
+        return;
+    }
+
+    SwFmtAnchor aAnchor( rAnchor.GetAnchorId(), nCntnt );
+    pOldSet->Put( aAnchor );
+}
+
+void SwUndoFmtAttr::RestoreFlyAnchor( SwUndoIter& rIter )
+{
+    SwDoc* pDoc = &rIter.GetDoc();
+    SwFlyFrmFmt* pFrmFmt = (SwFlyFrmFmt*)pFmt;
+    const SwFmtAnchor& rAnchor = (SwFmtAnchor&)pOldSet->Get(
+                                                RES_ANCHOR, FALSE );
+
+    SwFmtAnchor aNewAnchor( rAnchor.GetAnchorId() );
+    if( FLY_PAGE != rAnchor.GetAnchorId() )
+    {
+        SwNode* pNd = pDoc->GetNodes()[ nNode  ];
+
+        if( FLY_AT_FLY == rAnchor.GetAnchorId() ? ( !pNd->IsStartNode() ||
+            SwFlyStartNode != ((SwStartNode*)pNd)->GetStartNodeType() ) :
+            !pNd->IsTxtNode() )
+            return;     // ungueltige Position
+
+        SwPosition aPos( *pNd );
+        if( FLY_IN_CNTNT == rAnchor.GetAnchorId() ||
+            FLY_AUTO_CNTNT == rAnchor.GetAnchorId() )
+        {
+            aPos.nContent.Assign( (SwTxtNode*)pNd, rAnchor.GetPageNum() );
+            if( aPos.nContent.GetIndex() > ((SwTxtNode*)pNd)->GetTxt().Len() )
+                return;     // ungueltige Position
+        }
+        aNewAnchor.SetAnchor( &aPos );
+    }
+    else
+        aNewAnchor.SetPageNum( rAnchor.GetPageNum() );
+
+    Point aDrawSavePt, aDrawOldPt;
+    if( pDoc->GetRootFrm() )
+    {
+        if( RES_DRAWFRMFMT == pFrmFmt->Which() )
+        {
+            // den alten zwischengespeicherten Wert herausholen.
+            const SwFmtFrmSize& rOldSize = (const SwFmtFrmSize&)
+                                            pOldSet->Get( RES_FRM_SIZE );
+            aDrawSavePt.X() = rOldSize.GetWidth();
+            aDrawSavePt.Y() = rOldSize.GetHeight();
+            pOldSet->ClearItem( RES_FRM_SIZE );
+
+            // den akt. wieder zwischenspeichern
+            aDrawOldPt = pFrmFmt->FindSdrObject()->GetRelativePos();
+//JP 08.10.97: ist laut AMA/MA nicht mehr noetig
+//          pCont->DisconnectFromLayout();
+        }
+        else
+            pFrmFmt->DelFrms();         // Frms vernichten.
+    }
+
+    const SwFmtAnchor &rOldAnch = pFrmFmt->GetAnchor();
+    if( FLY_IN_CNTNT == rOldAnch.GetAnchorId() &&
+        FLY_IN_CNTNT != aNewAnchor.GetAnchorId() )
+    {
+        //Bei InCntnt's wird es spannend: Das TxtAttribut muss vernichtet
+        //werden. Leider reisst dies neben den Frms auch noch das Format mit
+        //in sein Grab. Um dass zu unterbinden loesen wir vorher die
+        //Verbindung zwischen Attribut und Format.
+        const SwPosition *pPos = rOldAnch.GetCntntAnchor();
+        SwTxtNode *pTxtNode = (SwTxtNode*)&pPos->nNode.GetNode();
+        ASSERT( pTxtNode->HasHints(), "Missing FlyInCnt-Hint." );
+        const xub_StrLen nIdx = pPos->nContent.GetIndex();
+        SwTxtAttr * pHnt = pTxtNode->GetTxtAttr( nIdx, RES_TXTATR_FLYCNT );
+#ifndef PRODUCT
+        ASSERT( pHnt && pHnt->Which() == RES_TXTATR_FLYCNT,
+                    "Missing FlyInCnt-Hint." );
+        ASSERT( pHnt && pHnt->GetFlyCnt().GetFrmFmt() == pFrmFmt,
+                    "Wrong TxtFlyCnt-Hint." );
+#endif
+        ((SwFmtFlyCnt&)pHnt->GetFlyCnt()).SetFlyFmt();
+
+        //Die Verbindung ist geloest, jetzt muss noch das Attribut vernichtet
+        //werden.
+        pTxtNode->Delete( RES_TXTATR_FLYCNT, nIdx, nIdx );
+    }
+
+    {
+        pOldSet->Put( aNewAnchor );
+        _UndoFmtAttr aTmp( *pFmt, bSaveDrawPt );
+        pFmt->SetAttr( *pOldSet );
+        if( aTmp.pUndo )
+        {
+            delete pOldSet;
+            nNode = aTmp.pUndo->nNode;
+            pOldSet = aTmp.pUndo->pOldSet;
+            aTmp.pUndo->pOldSet = 0;    // den Pointer auf 0 setzen (nicht
+                                        // doppelt loeschen) !!
+            delete aTmp.pUndo;          // Undo-Object wieder loeschen
+        }
+        else
+            pOldSet->ClearItem();
+    }
+
+    if( RES_DRAWFRMFMT == pFrmFmt->Which() )
+    {
+        SwDrawContact *pCont = (SwDrawContact*)pFrmFmt->FindContactObj();
+        // das Draw-Model hat auch noch ein Undo-Object fuer die
+        // richtige Position vorbereitet; dieses ist aber relativ.
+        // Darum verhinder hier, das durch setzen des Ankers das
+        // Contact-Object seine Position aendert.
+//JP 08.10.97: ist laut AMA/MA nicht mehr noetig
+//          pCont->ConnectToLayout();
+        SdrObject* pObj = pCont->GetMaster();
+
+        if( pCont->GetAnchor() && !pObj->IsInserted() )
+        {
+            ASSERT( pDoc->GetDrawModel(), "RestoreFlyAnchor without DrawModel" );
+            pDoc->GetDrawModel()->GetPage( 0 )->InsertObject( pObj );
+        }
+        pObj->SetRelativePos( aDrawSavePt );
+
+        // den alten Wert wieder zwischenspeichern.
+        pOldSet->Put( SwFmtFrmSize( ATT_VAR_SIZE, aDrawOldPt.X(), aDrawOldPt.Y() ) );
+    }
+
+    if( FLY_IN_CNTNT == aNewAnchor.GetAnchorId() )
+    {
+        const SwPosition* pPos = aNewAnchor.GetCntntAnchor();
+        SwTxtNode* pTxtNd = pPos->nNode.GetNode().GetTxtNode();
+        ASSERT( pTxtNd, "Kein Textnode an dieser Position" );
+        pTxtNd->Insert( SwFmtFlyCnt( pFrmFmt ), pPos->nContent.GetIndex(), 0 );
+    }
+
+
+    if( RES_DRAWFRMFMT != pFrmFmt->Which() )
+        pFrmFmt->MakeFrms();
+
+    rIter.pSelFmt = pFrmFmt;
+}
+
+/*  */
+
+SwUndoRstAttr::SwUndoRstAttr( const SwPaM& rRange, USHORT nFmt )
+    : SwUndo( UNDO_RESETATTR ), SwUndRng( rRange ), nFmtId( nFmt ),
+    pHistory( new SwHistory )
+{
+#ifdef COMPACT
+    ((SwDoc*)rRange.GetDoc())->DelUndoGroups();
+#endif
+}
+
+SwUndoRstAttr::SwUndoRstAttr( const SwDoc& rDoc, const SwPosition& rPos,
+                                USHORT nWhich )
+    : SwUndo( UNDO_RESETATTR ), nFmtId( nWhich ), pHistory( new SwHistory )
+{
+    nSttNode = nEndNode = rPos.nNode.GetIndex();
+    nSttCntnt = nEndCntnt = rPos.nContent.GetIndex();
+}
+
+SwUndoRstAttr::~SwUndoRstAttr()
+{
+    delete pHistory;
+}
+
+void SwUndoRstAttr::Undo( SwUndoIter& rUndoIter )
+{
+    // die alten Werte wieder zurueck
+    SwDoc& rDoc = rUndoIter.GetDoc();
+    pHistory->TmpRollback( &rDoc, 0 );
+    pHistory->SetTmpEnd( pHistory->Count() );
+
+    if( RES_CONDTXTFMTCOLL == nFmtId && nSttNode == nEndNode &&
+        nSttCntnt == nEndCntnt )
+    {
+        SwTxtNode* pTNd = rDoc.GetNodes()[ nSttNode ]->GetTxtNode();
+        if( pTNd )
+        {
+            SwIndex aIdx( pTNd, nSttCntnt );
+            pTNd->DontExpandFmt( aIdx, FALSE );
+        }
+    }
+
+    // setze noch den Cursor auf den Undo-Bereich
+    SetPaM( rUndoIter );
+}
+
+void SwUndoRstAttr::Redo( SwUndoIter& rUndoIter )
+{
+    // setze Attribut in dem Bereich:
+    SetPaM( rUndoIter );
+    SwDoc& rDoc = rUndoIter.GetDoc();
+    rUndoIter.pLastUndoObj = 0;
+    SvUShortsSort* pIdArr = aIds.Count() ? &aIds : 0;
+
+    switch( nFmtId )
+    {
+    case RES_CHRFMT:
+        rUndoIter.GetDoc().RstTxtAttr( *rUndoIter.pAktPam );
+        break;
+    case RES_TXTFMTCOLL:
+        rUndoIter.GetDoc().ResetAttr( *rUndoIter.pAktPam, FALSE, pIdArr );
+        break;
+    case RES_CONDTXTFMTCOLL:
+        rUndoIter.GetDoc().ResetAttr( *rUndoIter.pAktPam, TRUE, pIdArr );
+
+        break;
+    case RES_TXTATR_TOXMARK:
+        // Sonderbehandlung fuer TOXMarks
+        {
+            SwTOXMarks aArr;
+            SwNodeIndex aIdx( rDoc.GetNodes(), nSttNode );
+            SwPosition aPos( aIdx, SwIndex( aIdx.GetNode().GetCntntNode(),
+                                                                nSttCntnt ));
+
+            USHORT nCnt = rDoc.GetCurTOXMark( aPos, aArr );
+            if( nCnt )
+            {
+                if( 1 < nCnt )
+                {
+                    // dann den richtigen suchen
+                    SwHstryHint* pHHint = (*GetHistory())[ 0 ];
+                    if( pHHint && HSTRY_SETTOXMARKHNT == pHHint->Which() )
+                    {
+                        while( nCnt )
+                            if( ((SwSetTOXMarkHint*)pHHint)->IsEqual(
+                                    *aArr[ --nCnt ] ) )
+                            {
+                                ++nCnt;
+                                break;
+                            }
+                    }
+                    else
+                        nCnt = 0;
+                }
+                // gefunden, also loeschen
+                if( nCnt-- )
+                    rDoc.Delete( aArr[ nCnt ] );
+            }
+        }
+        break;
+    }
+    rUndoIter.pLastUndoObj = 0;
+}
+
+void SwUndoRstAttr::Repeat( SwUndoIter& rUndoIter )
+{
+    if( RES_FMT_BEGIN > nFmtId ||
+        ( UNDO_RESETATTR == rUndoIter.GetLastUndoId() &&
+         nFmtId == ((SwUndoRstAttr*)rUndoIter.pLastUndoObj)->nFmtId ))
+        return;
+
+    SvUShortsSort* pIdArr = aIds.Count() ? &aIds : 0;
+    switch( nFmtId )
+    {
+    case RES_CHRFMT:
+        rUndoIter.GetDoc().RstTxtAttr( *rUndoIter.pAktPam );
+        break;
+    case RES_TXTFMTCOLL:
+        rUndoIter.GetDoc().ResetAttr( *rUndoIter.pAktPam, FALSE, pIdArr );
+        break;
+    case RES_CONDTXTFMTCOLL:
+        rUndoIter.GetDoc().ResetAttr( *rUndoIter.pAktPam, TRUE, pIdArr );
+        break;
+    }
+    rUndoIter.pLastUndoObj = this;
+}
+
+
+void SwUndoRstAttr::SetAttrs( const SvUShortsSort& rArr )
+{
+    if( aIds.Count() )
+        aIds.Remove( 0, aIds.Count() );
+    aIds.Insert( &rArr );
+}
+
+// -----------------------------------------------------
+
+
+
+SwUndoAttr::SwUndoAttr( const SwPaM& rRange, const SfxPoolItem& rAttr,
+                        USHORT nFlags )
+    : SwUndo( UNDO_INSATTR ), SwUndRng( rRange ),
+    aSet( rRange.GetDoc()->GetAttrPool(), rAttr.Which(), rAttr.Which() ),
+    nInsFlags( nFlags ), pHistory( new SwHistory ),
+    pRedlData( 0 ), pRedlSaveData( 0 ),
+    nNdIdx( ULONG_MAX )
+{
+    aSet.Put( rAttr );
+#ifdef COMPACT
+    (SwDoc*)rRange.GetDoc()->DelUndoGroups();
+#endif
+}
+
+SwUndoAttr::SwUndoAttr( const SwPaM& rRange, const SfxItemSet& rSet,
+                        USHORT nFlags )
+    : SwUndo( UNDO_INSATTR ), SwUndRng( rRange ), aSet( rSet ),
+    nInsFlags( nFlags ), pHistory( new SwHistory ),
+    pRedlData( 0 ), pRedlSaveData( 0 ),
+    nNdIdx( ULONG_MAX )
+{
+#ifdef COMPACT
+    (SwDoc*)rRange.GetDoc()->DelUndoGroups();
+#endif
+}
+
+SwUndoAttr::~SwUndoAttr()
+{
+    delete pHistory;
+    delete pRedlData;
+    delete pRedlSaveData;
+}
+
+void SwUndoAttr::SaveRedlineData( const SwPaM& rPam, BOOL bIsCntnt )
+{
+    SwDoc* pDoc = rPam.GetDoc();
+    if( pDoc->IsRedlineOn() )
+        pRedlData = new SwRedlineData( bIsCntnt ? REDLINE_INSERT
+                                                : REDLINE_FORMAT,
+                                        pDoc->GetRedlineAuthor() );
+
+    pRedlSaveData = new SwRedlineSaveDatas;
+    if( !FillSaveDataForFmt( rPam, *pRedlSaveData ))
+        delete pRedlSaveData, pRedlSaveData = 0;
+
+    SetRedlineMode( pDoc->GetRedlineMode() );
+    if( bIsCntnt )
+        nNdIdx = rPam.GetPoint()->nNode.GetIndex();
+}
+
+void SwUndoAttr::Undo( SwUndoIter& rUndoIter )
+{
+    SwDoc* pDoc = &rUndoIter.GetDoc();
+
+    RemoveIdx( *pDoc );
+
+    if( IsRedlineOn( GetRedlineMode() ) )
+    {
+        SwPaM& rPam = *rUndoIter.pAktPam;
+        if( ULONG_MAX != nNdIdx )
+        {
+            rPam.DeleteMark();
+            rPam.GetPoint()->nNode = nNdIdx;
+            rPam.GetPoint()->nContent.Assign( rPam.GetCntntNode(), nSttCntnt );
+            rPam.SetMark();
+            rPam.GetPoint()->nContent++;
+            pDoc->DeleteRedline( rPam, FALSE );
+        }
+        else
+        {
+            // alle Format-Redlines entfernen, werden ggfs. neu gesetzt
+            SetPaM( rUndoIter );
+            pDoc->DeleteRedline( rPam, FALSE, REDLINE_FORMAT );
+            if( pRedlSaveData )
+                SetSaveData( *pDoc, *pRedlSaveData );
+        }
+    }
+
+    BOOL bToLast = 1 == aSet.Count() &&
+                   RES_TXTATR_FIELD <= *aSet.GetRanges() &&
+                   *aSet.GetRanges() <= RES_TXTATR_HARDBLANK;
+
+    // die alten Werte wieder zurueck
+    pHistory->TmpRollback( pDoc, 0, !bToLast );
+    pHistory->SetTmpEnd( pHistory->Count() );
+
+    // setze noch den Cursor auf den Undo-Bereich
+    SetPaM( rUndoIter );
+}
+
+void SwUndoAttr::Repeat( SwUndoIter& rUndoIter )
+{
+    // RefMarks sind nicht repeatfaehig
+    if( SFX_ITEM_SET != aSet.GetItemState( RES_TXTATR_REFMARK, FALSE ) )
+        rUndoIter.GetDoc().Insert( *rUndoIter.pAktPam, aSet, nInsFlags );
+    else if( 1 < aSet.Count() )
+    {
+        SfxItemSet aTmpSet( aSet );
+        aTmpSet.ClearItem( RES_TXTATR_REFMARK );
+        rUndoIter.GetDoc().Insert( *rUndoIter.pAktPam, aTmpSet, nInsFlags );
+    }
+    rUndoIter.pLastUndoObj = this;
+}
+
+void SwUndoAttr::Redo( SwUndoIter& rUndoIter )
+{
+    // setze Attribut in dem Bereich:
+    SetPaM( rUndoIter );
+    SwPaM& rPam = *rUndoIter.pAktPam;
+    SwDoc& rDoc = rUndoIter.GetDoc();
+
+    if( pRedlData && IsRedlineOn( GetRedlineMode() ) )
+    {
+        SwRedlineMode eOld = rDoc.GetRedlineMode();
+        rDoc.SetRedlineMode_intern( eOld & ~REDLINE_IGNORE );
+        rDoc.Insert( rPam, aSet, nInsFlags );
+
+        if( ULONG_MAX != nNdIdx )
+        {
+            rPam.SetMark();
+            if( rPam.Move( fnMoveBackward ) )
+                rDoc.AppendRedline( new SwRedline( *pRedlData, rPam ));
+            rPam.DeleteMark();
+        }
+        else
+            rDoc.AppendRedline( new SwRedline( *pRedlData, rPam ));
+
+        rDoc.SetRedlineMode_intern( eOld );
+    }
+    else
+        rDoc.Insert( rPam, aSet, nInsFlags );
+
+    rUndoIter.pLastUndoObj = 0;
+}
+
+
+void SwUndoAttr::RemoveIdx( SwDoc& rDoc )
+{
+    if( SFX_ITEM_SET != aSet.GetItemState( RES_TXTATR_FTN, FALSE ))
+        return ;
+
+    SwHstryHint* pHstHnt;
+    SwNodes& rNds = rDoc.GetNodes();
+    for( USHORT n = 0; n < pHistory->Count(); ++n )
+    {
+        xub_StrLen nCntnt;
+        ULONG nNode = 0;
+        switch( ( pHstHnt = (*pHistory)[ n ] )->Which() )
+        {
+        case HSTRY_RESETTXTHNT:
+            if( RES_TXTATR_FTN == ((SwResetTxtHint*)pHstHnt)->GetWhich() )
+            {
+                nNode = ((SwResetTxtHint*)pHstHnt)->GetNode();
+                nCntnt = ((SwResetTxtHint*)pHstHnt)->GetCntnt();
+            }
+            break;
+        case HSTRY_RESETATTRSET:
+            if( STRING_MAXLEN != ( nCntnt =
+                                ((SwHstryResetAttrSet*)pHstHnt)->GetCntnt() ))
+            {
+                const SvUShorts& rArr = ((SwHstryResetAttrSet*)pHstHnt)->GetArr();
+                for( USHORT i = rArr.Count(); i; )
+                    if( RES_TXTATR_FTN == rArr[ --i ] )
+                    {
+                        nNode = ((SwHstryResetAttrSet*)pHstHnt)->GetNode();
+                        break;
+                    }
+            }
+            break;
+        }
+
+        if( nNode )
+        {
+            SwTxtNode* pTxtNd = rNds[ nNode ]->GetTxtNode();
+            if( pTxtNd )
+            {
+                SwIndex aIdx( pTxtNd, nCntnt );
+                SwTxtAttr * pTxtHt = pTxtNd->GetTxtAttr( aIdx, RES_TXTATR_FTN );
+                if( pTxtHt )
+                {
+                    // ok, dann hole mal die Werte
+                    SwTxtFtn* pFtn = (SwTxtFtn*)pTxtHt;
+                    RemoveIdxFromSection( rDoc, pFtn->GetStartNode()->GetIndex() );
+                    return ;
+                }
+            }
+        }
+    }
+}
+
+/*  */
+
+SwUndoDefaultAttr::SwUndoDefaultAttr( const SfxItemSet& rSet )
+    : SwUndo( UNDO_SETDEFTATTR ), pOldSet( 0 ), pTabStop( 0 )
+{
+    const SfxPoolItem* pItem;
+    if( rSet.GetItemState( RES_PARATR_TABSTOP, FALSE, &pItem ) )
+    {
+        pTabStop = (SvxTabStopItem*)pItem->Clone();     // gesondert merken, aendert sich !!!
+        if( 1 != rSet.Count() )         // gibts noch mehr Attribute ?
+            pOldSet = new SfxItemSet( rSet );
+    }
+    else
+        pOldSet = new SfxItemSet( rSet );
+}
+
+SwUndoDefaultAttr::~SwUndoDefaultAttr()
+{
+    if( pOldSet )
+        delete pOldSet;
+    if( pTabStop )
+        delete pTabStop;
+}
+
+void SwUndoDefaultAttr::Undo( SwUndoIter& rUndoIter)
+{
+    SwDoc& rDoc = rUndoIter.GetDoc();
+    if( pOldSet )
+    {
+        _UndoFmtAttr aTmp( *(SwTxtFmtColl*)rDoc.GetDfltTxtFmtColl() );
+        rDoc.SetDefault( *pOldSet );
+        delete pOldSet;
+        if( aTmp.pUndo )
+        {
+            pOldSet = aTmp.pUndo->pOldSet;
+            aTmp.pUndo->pOldSet = 0;    // den Pointer auf 0 setzen (nicht
+                                        // doppelt loeschen) !!
+            delete aTmp.pUndo;          // Undo-Object wieder loeschen
+        }
+        else
+            pOldSet = 0;
+    }
+    if( pTabStop )
+    {
+        SvxTabStopItem* pOld = (SvxTabStopItem*)rDoc.GetDefault(
+                                                RES_PARATR_TABSTOP ).Clone();
+        rDoc.SetDefault( *pTabStop );
+        delete pTabStop;
+        pTabStop = pOld;
+    }
+}
+
+void SwUndoDefaultAttr::Redo( SwUndoIter& rUndoIter)
+{
+    Undo( rUndoIter );
+}
+
+/*  */
+
+SwUndoMoveLeftMargin::SwUndoMoveLeftMargin( const SwPaM& rPam, BOOL bFlag,
+                                            BOOL bMod )
+    : SwUndo( bFlag ? UNDO_INC_LEFTMARGIN : UNDO_DEC_LEFTMARGIN ),
+    SwUndRng( rPam ), bModulus( bMod )
+{
+    pHistory = new SwHistory;
+}
+
+SwUndoMoveLeftMargin::~SwUndoMoveLeftMargin()
+{
+    delete pHistory;
+}
+
+void SwUndoMoveLeftMargin::Undo( SwUndoIter& rIter )
+{
+    SwDoc* pDoc = &rIter.GetDoc();
+    BOOL bUndo = pDoc->DoesUndo();
+    pDoc->DoUndo( FALSE );
+
+    // die alten Werte wieder zurueck
+    pHistory->TmpRollback( pDoc, 0 );
+    pHistory->SetTmpEnd( pHistory->Count() );
+
+    pDoc->DoUndo( bUndo );
+    SetPaM( rIter );
+}
+
+void SwUndoMoveLeftMargin::Redo( SwUndoIter& rIter )
+{
+    SwDoc* pDoc = &rIter.GetDoc();
+    SetPaM( rIter );
+    pDoc->MoveLeftMargin( *rIter.pAktPam, GetId() == UNDO_INC_LEFTMARGIN, bModulus );
+}
+
+void SwUndoMoveLeftMargin::Repeat( SwUndoIter& rIter )
+{
+    SwDoc* pDoc = &rIter.GetDoc();
+    pDoc->MoveLeftMargin( *rIter.pAktPam, GetId() == UNDO_INC_LEFTMARGIN, bModulus );
+    rIter.pLastUndoObj = this;
+}
+
+/*  */
+
+SwUndoChgFtn::SwUndoChgFtn( const SwPaM& rRange, const String& rTxt,
+                            USHORT nNum, BOOL bIsEndNote )
+    : SwUndo( UNDO_CHGFTN ), SwUndRng( rRange ),
+    sTxt( rTxt ), nNo( nNum ), bEndNote( bIsEndNote ),
+    pHistory( new SwHistory() )
+{
+}
+
+SwUndoChgFtn::~SwUndoChgFtn()
+{
+    delete pHistory;
+}
+
+void SwUndoChgFtn::Undo( SwUndoIter& rIter )
+{
+    SwDoc& rDoc = rIter.GetDoc();
+    SetPaM( rIter );
+
+    BOOL bUndo = rDoc.DoesUndo();
+    rDoc.DoUndo( FALSE );
+
+    pHistory->TmpRollback( &rDoc, 0 );
+    pHistory->SetTmpEnd( pHistory->Count() );
+
+    rDoc.GetFtnIdxs().UpdateAllFtn();
+
+    SetPaM( rIter );
+    rDoc.DoUndo( bUndo );
+}
+
+void SwUndoChgFtn::Redo( SwUndoIter& rIter )
+{
+    SetPaM( rIter );
+    rIter.GetDoc().SetCurFtn( *rIter.pAktPam, sTxt, nNo, bEndNote );
+    SetPaM( rIter );
+}
+
+void SwUndoChgFtn::Repeat( SwUndoIter& rIter )
+{
+    SwDoc& rDoc = rIter.GetDoc();
+    rDoc.SetCurFtn( *rIter.pAktPam, sTxt, nNo, bEndNote );
+    rIter.pLastUndoObj = this;
+}
+
+
+/*  */
+
+
+SwUndoFtnInfo::SwUndoFtnInfo( const SwFtnInfo &rInfo ) :
+    SwUndo( UNDO_FTNINFO ),
+    pFtnInfo( new SwFtnInfo( rInfo ) )
+{
+}
+
+SwUndoFtnInfo::~SwUndoFtnInfo()
+{
+    delete pFtnInfo;
+}
+
+void SwUndoFtnInfo::Undo( SwUndoIter &rIter )
+{
+    SwDoc &rDoc = rIter.GetDoc();
+    SwFtnInfo *pInf = new SwFtnInfo( rDoc.GetFtnInfo() );
+    rDoc.SetFtnInfo( *pFtnInfo );
+    delete pFtnInfo;
+    pFtnInfo = pInf;
+}
+
+void SwUndoFtnInfo::Redo( SwUndoIter &rIter )
+{
+    SwDoc &rDoc = rIter.GetDoc();
+    SwFtnInfo *pInf = new SwFtnInfo( rDoc.GetFtnInfo() );
+    rDoc.SetFtnInfo( *pFtnInfo );
+    delete pFtnInfo;
+    pFtnInfo = pInf;
+}
+
+/*  */
+
+SwUndoEndNoteInfo::SwUndoEndNoteInfo( const SwEndNoteInfo &rInfo ) :
+    SwUndo( UNDO_FTNINFO ),
+    pEndNoteInfo( new SwEndNoteInfo( rInfo ) )
+{
+}
+
+SwUndoEndNoteInfo::~SwUndoEndNoteInfo()
+{
+    delete pEndNoteInfo;
+}
+
+void SwUndoEndNoteInfo::Undo( SwUndoIter &rIter )
+{
+    SwDoc &rDoc = rIter.GetDoc();
+    SwEndNoteInfo *pInf = new SwEndNoteInfo( rDoc.GetEndNoteInfo() );
+    rDoc.SetEndNoteInfo( *pEndNoteInfo );
+    delete pEndNoteInfo;
+    pEndNoteInfo = pInf;
+}
+
+void SwUndoEndNoteInfo::Redo( SwUndoIter &rIter )
+{
+    SwDoc &rDoc = rIter.GetDoc();
+    SwEndNoteInfo *pInf = new SwEndNoteInfo( rDoc.GetEndNoteInfo() );
+    rDoc.SetEndNoteInfo( *pEndNoteInfo );
+    delete pEndNoteInfo;
+    pEndNoteInfo = pInf;
+}
+
+/*  */
+
+SwUndoDontExpandFmt::SwUndoDontExpandFmt( const SwPosition& rPos )
+    : SwUndo( UNDO_DONTEXPAND ),
+    nNode( rPos.nNode.GetIndex() ), nCntnt( rPos.nContent.GetIndex() )
+{
+}
+
+void SwUndoDontExpandFmt::Undo( SwUndoIter& rIter )
+{
+    SwPaM* pPam = rIter.pAktPam;
+    SwDoc* pDoc = pPam->GetDoc();
+
+    SwPosition& rPos = *pPam->GetPoint();
+    rPos.nNode = nNode;
+    rPos.nContent.Assign( rPos.nNode.GetNode().GetCntntNode(), nCntnt );
+    pDoc->DontExpandFmt( rPos, FALSE );
+}
+
+
+void SwUndoDontExpandFmt::Redo( SwUndoIter& rIter )
+{
+    SwPaM* pPam = rIter.pAktPam;
+    SwDoc* pDoc = pPam->GetDoc();
+
+    SwPosition& rPos = *pPam->GetPoint();
+    rPos.nNode = nNode;
+    rPos.nContent.Assign( rPos.nNode.GetNode().GetCntntNode(), nCntnt );
+    pDoc->DontExpandFmt( rPos );
+}
+
+void SwUndoDontExpandFmt::Repeat( SwUndoIter& rIter )
+{
+    SwPaM* pPam = rIter.pAktPam;
+    SwDoc* pDoc = pPam->GetDoc();
+    pDoc->DontExpandFmt( *pPam->GetPoint() );
+}
+
+
+/*************************************************************************
+
+      Source Code Control System - Header
+
+      $Header: /zpool/svn/migration/cvs_rep_09_09_08/code/sw/source/core/undo/unattr.cxx,v 1.1.1.1 2000-09-19 00:08:27 hr Exp $
+
+      Source Code Control System - Update
+
+      $Log: not supported by cvs2svn $
+      Revision 1.80  2000/09/18 16:04:28  willem.vandorp
+      OpenOffice header added.
+
+      Revision 1.79  2000/05/09 10:03:54  jp
+      Changes for Unicode
+
+      Revision 1.78  1999/11/15 14:52:35  jp
+      SwUndoAttr:Undo: if undo of textattr without end, then TmpRolbck from first to last
+
+      Revision 1.77  1999/11/08 16:18:43  jp
+      UpdateAllFtn calls the Update at RootFrm
+
+      Revision 1.76  1999/03/30 07:15:24  JP
+      Task #63092#: ResetAttr - auch einzelne Attribute zuruecksetzen
+
+
+      Rev 1.75   30 Mar 1999 09:15:24   JP
+   Task #63092#: ResetAttr - auch einzelne Attribute zuruecksetzen
+
+      Rev 1.74   29 Mar 1999 18:45:56   JP
+   Task #63092#: ResetAttr - auch einzelne Attribute zuruecksetzen
+
+      Rev 1.73   25 Feb 1999 18:11:38   JP
+   Bug #62421#: ResetAttr - ohne Selektion zus. die Zeichenattribute stoppen
+
+      Rev 1.72   27 Jan 1999 18:52:30   JP
+   Task #61014#: FindSdrObject/FindContactObject als Methoden vom SwFrmFmt
+
+      Rev 1.71   15 Jan 1999 15:48:54   JP
+   Bug #60203#: MoveLeftMargin - optional um Betrag verschieben
+
+      Rev 1.70   02 Dec 1998 10:36:38   JP
+   Task #59951#: UnAttr fuer Sectionformate erweitert
+
+      Rev 1.69   12 May 1998 15:48:16   JP
+   rund um Flys/DrawObjs im Doc umgestellt/optimiert
+
+      Rev 1.68   02 Apr 1998 15:12:48   JP
+   Redo: Undo-Flag wird schon von der EditShell abgeschaltet
+
+      Rev 1.67   24 Mar 1998 20:54:14   JP
+   neu: Redlining fuer harte Attributierung
+
+      Rev 1.66   16 Jan 1998 11:11:22   JP
+   pAttrHistory am Doc entfernt, UndoAttr mit Redline
+
+      Rev 1.65   15 Dec 1997 19:36:18   JP
+   ResetAttr: die richtige Reset-Methode am Doc rufen
+
+      Rev 1.64   12 Dec 1997 14:47:36   MA
+   undo setftn korrigiert
+
+      Rev 1.63   10 Dec 1997 16:34:42   JP
+   neu: Undo fuers aendern der Fussnoten
+
+      Rev 1.62   08 Dec 1997 12:35:50   MA
+   vorb. Endnoten
+
+      Rev 1.61   20 Nov 1997 18:35:30   MA
+   includes
+
+      Rev 1.60   06 Nov 1997 15:31:20   JP
+   benutze neue Methode GetFlyFmt() vom SwNode
+
+      Rev 1.59   03 Nov 1997 13:06:16   MA
+   precomp entfernt
+
+      Rev 1.58   09 Oct 1997 15:45:56   JP
+   Umstellung NodeIndex/-Array/BigPtrArray
+
+      Rev 1.57   11 Sep 1997 12:35:02   JP
+   Bug #41975#: InsertLabel wurde undofaehig
+
+      Rev 1.56   10 Sep 1997 14:31:58   JP
+   Bug #43672#: FmtAttr::Repeat - ContentAttribut NIE setzen
+
+      Rev 1.55   03 Sep 1997 10:28:44   JP
+   zusaetzliches include von docary
+
+      Rev 1.54   18 Aug 1997 10:34:52   OS
+   includes
+
+      Rev 1.53   15 Aug 1997 12:37:38   OS
+   charatr/frmatr/txtatr aufgeteilt
+
+      Rev 1.52   11 Aug 1997 16:27:06   OS
+   Header-Umstellung
+
+      Rev 1.51   11 Jun 1997 10:42:44   JP
+   pure virtual Repeat wurde zur virtual Methode, Segment Pragma entfernt
+
+      Rev 1.50   17 Apr 1997 16:23:08   AMA
+   New: Rahmengebundene Rahmen
+
+      Rev 1.49   15 Apr 1997 14:51:38   AMA
+   New: Rahmengebundene Rahmen und auto.positionierte Rahmen
+
+      Rev 1.48   15 Jan 1997 19:54:04   JP
+   SwUndoRstAttr: loeschen von SwTOXMarks impl.
+
+      Rev 1.47   14 Jan 1997 14:46:56   JP
+   neu: SwUndoMoveLeftMargin - linken Rand stufen
+
+      Rev 1.46   07 Jan 1997 12:44:32   JP
+   UndoFmtAttr: TabellenFormate beachten
+
+      Rev 1.45   31 Oct 1996 16:19:06   MA
+   opt: Which nicht mehr virtuell, kann ISA ersetzen
+
+      Rev 1.44   29 Oct 1996 14:52:58   JP
+   am Doc ist das NodesArray nur noch ueber Get..() zugaenglich
+
+      Rev 1.43   25 Oct 1996 13:43:50   JP
+   InsertAttr/SetAttr: Mode uebergeben
+
+      Rev 1.42   23 Sep 1996 20:06:30   JP
+   SetTmpEnd: DocPtr entfernt
+
+      Rev 1.41   29 Aug 1996 10:18:50   OS
+   includes
+
+      Rev 1.40   07 Aug 1996 10:04:26   NF
+   includes
+
+      Rev 1.39   17 May 1996 15:04:22   AMA
+   Fix: Undo von zeichengebundenen Zeichenobjekten
+
+      Rev 1.38   24 Nov 1995 17:14:06   OM
+   PCH->PRECOMPILED
+
+      Rev 1.37   13 Nov 1995 12:09:00   MA
+   chg: static -> lcl_
+
+      Rev 1.36   03 Nov 1995 19:31:32   AMA
+   Opt.StartUp: DrawView/Model erst bei Bedarf.
+
+      Rev 1.35   08 Sep 1995 19:11:40   ER
+   _SFXUNDO_HXX --> _UNDO_HXX
+
+      Rev 1.34   22 Aug 1995 17:44:48   JP
+   Ankerwechsel: beachte die DrawObjecte
+
+      Rev 1.33   22 Jun 1995 19:33:18   JP
+   virt. Methode GetUndoRange vernichtet, Objecte rufen jetzt die Basis-Klasse
+
+      Rev 1.32   15 May 1995 17:00:36   JP
+   UndoAttrSet: beim Repeat Refmarks ausklammern
+
+      Rev 1.31   03 May 1995 12:22:04   JP
+   fehlendes Include zugefuegt
+
+*************************************************************************/
+
diff --git a/sw/source/core/undo/unbkmk.cxx b/sw/source/core/undo/unbkmk.cxx
new file mode 100644
index 000000000000..b1d6f277d9d1
--- /dev/null
+++ b/sw/source/core/undo/unbkmk.cxx
@@ -0,0 +1,225 @@
+/*************************************************************************
+ *
+ *  $RCSfile: unbkmk.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:27 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "doc.hxx"
+#include "docary.hxx"
+#include "swundo.hxx"           // fuer die UndoIds
+#include "pam.hxx"
+
+#include "undobj.hxx"
+#include "bookmrk.hxx"
+#include "rolbck.hxx"
+
+
+
+inline SwDoc& SwUndoIter::GetDoc() const { return *pAktPam->GetDoc(); }
+
+
+SwUndoBookmark::SwUndoBookmark( USHORT nUndoId, const SwBookmark& rBkmk )
+    : SwUndo( nUndoId )
+{
+    int nType = SwHstryBookmark::BKMK_POS;
+    if( rBkmk.GetOtherPos() )
+        nType |= SwHstryBookmark::BKMK_OTHERPOS;
+    pHBookmark = new SwHstryBookmark( rBkmk, nType );
+}
+
+
+
+SwUndoBookmark::~SwUndoBookmark()
+{
+    delete pHBookmark;
+}
+
+
+void SwUndoBookmark::SetInDoc( SwDoc* pDoc )
+{
+    pHBookmark->SetInDoc( pDoc, FALSE );
+}
+
+
+void SwUndoBookmark::ResetInDoc( SwDoc* pDoc )
+{
+    const SwBookmarks& rBkmkTbl = pDoc->GetBookmarks();
+    for( USHORT n = 0; n < rBkmkTbl.Count(); ++n )
+        if( pHBookmark->IsEqualBookmark( *rBkmkTbl[ n ] ) )
+        {
+                pDoc->DelBookmark( n );
+                break;
+        }
+}
+
+
+
+SwUndoDelBookmark::SwUndoDelBookmark( const SwBookmark& rBkmk )
+    : SwUndoBookmark( UNDO_DELBOOKMARK, rBkmk )
+{
+}
+
+
+void SwUndoDelBookmark::Undo( SwUndoIter& rUndoIter )
+{
+    SetInDoc( &rUndoIter.GetDoc() );
+}
+
+
+void SwUndoDelBookmark::Redo( SwUndoIter& rUndoIter )
+{
+    ResetInDoc( &rUndoIter.GetDoc() );
+}
+
+
+SwUndoInsBookmark::SwUndoInsBookmark( const SwBookmark& rBkmk )
+    : SwUndoBookmark( UNDO_INSBOOKMARK, rBkmk )
+{
+}
+
+
+void SwUndoInsBookmark::Undo( SwUndoIter& rUndoIter )
+{
+    ResetInDoc( &rUndoIter.GetDoc() );
+}
+
+
+void SwUndoInsBookmark::Redo( SwUndoIter& rUndoIter )
+{
+    SetInDoc( &rUndoIter.GetDoc() );
+}
+
+
+
+/*************************************************************************
+
+      Source Code Control System - Header
+
+      $Header: /zpool/svn/migration/cvs_rep_09_09_08/code/sw/source/core/undo/unbkmk.cxx,v 1.1.1.1 2000-09-19 00:08:27 hr Exp $
+
+      Source Code Control System - Update
+
+      $Log: not supported by cvs2svn $
+      Revision 1.24  2000/09/18 16:04:28  willem.vandorp
+      OpenOffice header added.
+
+      Revision 1.23  1998/04/02 13:12:48  JP
+      Redo: Undo-Flag wird schon von der EditShell abgeschaltet
+
+
+      Rev 1.22   02 Apr 1998 15:12:48   JP
+   Redo: Undo-Flag wird schon von der EditShell abgeschaltet
+
+      Rev 1.21   03 Nov 1997 13:06:16   MA
+   precomp entfernt
+
+      Rev 1.20   03 Sep 1997 10:29:10   JP
+   zusaetzliches include von docary
+
+      Rev 1.19   11 Jun 1997 10:42:46   JP
+   pure virtual Repeat wurde zur virtual Methode, Segment Pragma entfernt
+
+      Rev 1.18   24 Nov 1995 17:13:56   OM
+   PCH->PRECOMPILED
+
+      Rev 1.17   23 Nov 1995 12:05:42   AMA
+   Fix/Opt: BLC-Warnings.
+
+      Rev 1.16   26 Jun 1995 19:50:06   JP
+   UndoBookmark: nur wenn die 2. Position vorhanden ist, diese sichern
+
+      Rev 1.15   22 Jun 1995 19:33:34   JP
+   virt. Methode GetUndoRange vernichtet, Objecte rufen jetzt die Basis-Klasse
+
+      Rev 1.14   04 Mar 1995 13:29:22   MA
+   unnoetiges SEXPORT entfernt.
+
+      Rev 1.13   23 Feb 1995 23:00:58   ER
+   sexport
+
+      Rev 1.12   08 Feb 1995 23:52:34   ER
+   undo.hxx -> swundo.hxx wegen solar undo.hxx
+
+      Rev 1.11   15 Dec 1994 20:46:58   SWG
+   *ARR* Ersetzungen, svmem, __far_data etc.
+
+      Rev 1.10   25 Oct 1994 14:50:38   MA
+   PreHdr.
+
+      Rev 1.9   21 Mar 1994 18:20:32   JP
+   umgestellt und jetzt auch mit Undo vom InsertBookmark.
+
+      Rev 1.8   02 Mar 1994 19:50:20   MI
+   Underscore im Namen der #pragmas
+
+      Rev 1.7   17 Feb 1994 08:30:56   MI
+   SEG_FUNCDEFS ausgefuellt
+
+      Rev 1.6   16 Feb 1994 13:17:02   MI
+   Pragmas zurechtgerueckt
+
+*************************************************************************/
+
+
+
diff --git a/sw/source/core/undo/undel.cxx b/sw/source/core/undo/undel.cxx
new file mode 100644
index 000000000000..6a1c4bc6f277
--- /dev/null
+++ b/sw/source/core/undo/undel.cxx
@@ -0,0 +1,970 @@
+/*************************************************************************
+ *
+ *  $RCSfile: undel.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:27 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _WORDSEL_HXX
+#include 
+#endif
+#ifndef _SVX_BRKITEM_HXX //autogen
+#include 
+#endif
+#ifndef _FMTPDSC_HXX //autogen
+#include 
+#endif
+#ifndef _FRMFMT_HXX //autogen
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _SWTABLE_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include            // fuer die UndoIds
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _UNDOBJ_HXX
+#include 
+#endif
+#ifndef _ROLBCK_HXX
+#include 
+#endif
+#ifndef _POOLFMT_HXX
+#include 
+#endif
+#ifndef _MVSAVE_HXX
+#include 
+#endif
+#ifndef _REDLINE_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+
+inline SwDoc& SwUndoIter::GetDoc() const { return *pAktPam->GetDoc(); }
+
+
+// DELETE
+
+SwUndoDelete::SwUndoDelete( SwPaM& rPam, BOOL bFullPara )
+    : SwUndo(UNDO_DELETE), SwUndRng( rPam ),
+    pMvStt( 0 ), pSttStr(0), pEndStr(0), nNode( 0 ), nSectDiff( 0 ),
+    pRedlData( 0 ), pRedlSaveData( 0 )
+{
+    bMvAroundSectNd = bSectNdFnd = bGroup = bBackSp = bTblDelLastNd =
+        bResetPgDesc = bResetPgBrk = FALSE;
+
+    bDelFullPara = bFullPara;
+
+    SwDoc * pDoc = rPam.GetDoc();
+#ifdef COMPACT
+    pDoc->DelUndoGroups();
+#endif
+
+    if( !pDoc->IsIgnoreRedline() && pDoc->GetRedlineTbl().Count() )
+    {
+        pRedlSaveData = new SwRedlineSaveDatas;
+        if( !FillSaveData( rPam, *pRedlSaveData ))
+            delete pRedlSaveData, pRedlSaveData = 0;
+    }
+
+    if( !pHistory )
+        pHistory = new SwHistory;
+
+    // loesche erstmal alle Fussnoten
+    const SwPosition *pStt = rPam.Start(),
+                    *pEnd = rPam.GetPoint() == pStt
+                        ? rPam.GetMark()
+                        : rPam.GetPoint();
+
+    if( bDelFullPara )
+    {
+        ASSERT( rPam.HasMark(), "PaM ohne Mark" );
+        DelCntntIndex( *rPam.GetMark(), *rPam.GetPoint(),
+                        DelCntntType(DELCNT_ALL | DELCNT_CHKNOCNTNT) );
+
+        BOOL bDoesUndo = pDoc->DoesUndo();
+        pDoc->DoUndo( FALSE );
+        _DelBookmarks( pStt->nNode, pEnd->nNode );
+        pDoc->DoUndo( bDoesUndo );
+    }
+    else
+        DelCntntIndex( *rPam.GetMark(), *rPam.GetPoint() );
+    nSetPos = pHistory ? pHistory->Count() : 0;
+
+    // wurde schon was geloescht ??
+    nNdDiff = nSttNode - pStt->nNode.GetIndex();
+
+    bJoinNext = !bFullPara && pEnd == rPam.GetPoint();
+    bBackSp = !bFullPara && !bJoinNext;
+
+    SwTxtNode *pSttTxtNd = 0, *pEndTxtNd = 0;
+    if( !bFullPara )
+    {
+        pSttTxtNd = pStt->nNode.GetNode().GetTxtNode();
+        pEndTxtNd = nSttNode == nEndNode
+                    ? pSttTxtNd
+                    : pEndTxtNd = pEnd->nNode.GetNode().GetTxtNode();
+    }
+
+    BOOL bMoveNds = *pStt == *pEnd      // noch ein Bereich vorhanden ??
+                ? FALSE
+                : SaveCntnt( pStt, pEnd, pSttTxtNd, pEndTxtNd );
+
+    if( pSttTxtNd && pEndTxtNd && pSttTxtNd != pEndTxtNd )
+    {
+        // zwei unterschiedliche TextNodes, also speicher noch die
+        // TextFormatCollection fuers
+        pHistory->Add( pSttTxtNd->GetTxtColl(),pStt->nNode.GetIndex(), ND_TEXTNODE );
+        pHistory->Add( pEndTxtNd->GetTxtColl(),pEnd->nNode.GetIndex(), ND_TEXTNODE );
+
+        if( !bJoinNext )        // Selection von Unten nach Oben
+        {
+            // Beim JoinPrev() werden die AUTO-PageBreak's richtig
+            // kopiert. Um diese beim Undo wieder herzustellen, muss das
+            // Auto-PageBreak aus dem EndNode zurueckgesetzt werden.
+            // - fuer die PageDesc, ColBreak dito !
+            if( pEndTxtNd->GetpSwAttrSet() )
+            {
+                SwRegHistory aRegHist( *pEndTxtNd, pHistory );
+                if( SFX_ITEM_SET == pEndTxtNd->GetpSwAttrSet()->GetItemState(
+                        RES_BREAK, FALSE ) )
+                    pEndTxtNd->ResetAttr( RES_BREAK );
+                if( pEndTxtNd->GetpSwAttrSet() &&
+                    SFX_ITEM_SET == pEndTxtNd->GetpSwAttrSet()->GetItemState(
+                        RES_PAGEDESC, FALSE ) )
+                    pEndTxtNd->ResetAttr( RES_PAGEDESC );
+            }
+        }
+    }
+
+
+    // verschiebe jetzt noch den PaM !!!
+    // der SPoint steht am Anfang der SSelection
+    if( pEnd == rPam.GetPoint() && pSttTxtNd )
+        rPam.Exchange();
+
+    if( !pSttTxtNd && !pEndTxtNd )
+        rPam.GetPoint()->nNode--;
+    rPam.DeleteMark();          // der SPoint ist aus dem Bereich
+
+    if( !pEndTxtNd )
+        nEndCntnt = 0;
+    if( !pSttTxtNd )
+        nSttCntnt = 0;
+
+    if( bMoveNds )      // sind noch Nodes zu verschieben ?
+    {
+        // verschiebe jetzt den Rest, also die vollstaendigen Nodes
+        // ACHTUNG: pStt und pEnd koennen durch die Pam-Korrektur schon
+        // ungueltig sein !!
+        int nNdOff = 0;
+        if( pSttTxtNd && ( pEndTxtNd || pSttTxtNd->GetTxt().Len() ))
+            nNdOff++;
+
+        SwNodeRange aRg( pDoc->GetNodes(), nSttNode - nNdDiff + nNdOff,
+                         pDoc->GetNodes(), nEndNode - nNdDiff );
+        if( !bFullPara && !pEndTxtNd &&
+            &aRg.aEnd.GetNode() != &pDoc->GetNodes().GetEndOfContent() )
+            aRg.aEnd++;
+
+        SwNodes& rNds = (SwNodes&)*pDoc->GetUndoNds();
+        SwNodes& rDocNds = pDoc->GetNodes();
+        nNode = rNds.GetEndOfContent().GetIndex();
+
+        // habe wir SectionNodes (Start/Ende) als 1. oder letzten
+        // Nodes in der Selection ?
+        SwNode* pTmpNd;
+        if( bJoinNext )     // Selektion von oben -> unten
+        {
+            // Bedingung: - SectionNode und dessen Ende ist der naechste Node
+            //            - EndNode einer Section und der Start steht ausserhalb
+            if( pSttTxtNd && pEndTxtNd )
+            {
+                // am Ende erfolgt ein JoinNext, teste auf leere Sections
+                // Bedingung: - hinter dem EndTextNode steht ein SectionEndNd
+                //              dessen Start im Bereich liegt
+                //            - SectionSttNd und der Start steht ausserhalb
+                if( aRg.aEnd.GetIndex()+1 < rDocNds.Count() &&
+                    ( (pTmpNd = rDocNds[ aRg.aEnd.GetIndex()+1 ])->IsEndNode()
+                    && pTmpNd->FindStartNode()->IsSectionNode()
+                    && pTmpNd->StartOfSectionIndex() >= aRg.aStart.GetIndex())
+                )
+                {
+                    aRg.aEnd++;
+                    bSectNdFnd = TRUE;
+                }
+                else if( ((pTmpNd = rDocNds[ aRg.aEnd.GetIndex()-1 ])->IsSectionNode()
+                        && pTmpNd->EndOfSectionIndex()-1 == aRg.aEnd.GetIndex())
+                    || ( pTmpNd->IsEndNode() &&
+                    pTmpNd->FindStartNode()->IsSectionNode() &&
+                    pTmpNd->FindStartNode()->GetIndex() < aRg.aStart.GetIndex())
+                    )
+                {
+                    aRg.aEnd++;
+                    bSectNdFnd = TRUE;
+                }
+            }
+            while( aRg.aEnd.GetIndex() < rDocNds.Count()-1 &&
+                // entstehen leere Sections ???
+                ( (pTmpNd = &aRg.aEnd.GetNode())->IsEndNode() &&
+                pTmpNd->FindStartNode()->IsSectionNode() &&
+                pTmpNd->FindStartNode()->GetIndex()+1 >= aRg.aStart.GetIndex())
+                )
+            {
+                aRg.aEnd++;
+                bSectNdFnd = TRUE;
+            }
+        }
+        else
+        {
+            if( pSttTxtNd && pEndTxtNd )
+            {
+                // am Ende erfolgt ein JoinPrev, teste auf leere Sections
+                // Bedingung: - vor dem StartTextNode steht ein SectionSttNd
+                //              dessen Ende im Bereich liegt
+                //            - SectionEndNd und der Start steht ausserhalb
+                if( 2 < aRg.aStart.GetIndex() &&
+                    ( (pTmpNd = rDocNds[ aRg.aStart.GetIndex()-2 ])
+                        ->IsSectionNode() &&
+                    pTmpNd->EndOfSectionIndex() < aRg.aEnd.GetIndex())
+                )
+                {
+                    aRg.aStart = *pTmpNd;
+                    bSectNdFnd = TRUE;
+                    nSectDiff++;
+                }
+                else if( aRg.aStart.GetIndex() &&
+                    ((pTmpNd = &aRg.aStart.GetNode())->IsSectionNode()
+                    && pTmpNd->EndOfSectionIndex() > aRg.aEnd.GetIndex() ) ||
+                    (pTmpNd->IsEndNode() && pTmpNd->FindStartNode()->IsSectionNode() &&
+                    pTmpNd->FindStartNode()->GetIndex() < aRg.aStart.GetIndex() )
+                    )
+                {
+                    aRg.aStart--;
+                    bSectNdFnd = TRUE;
+                }
+            }
+            while( 1 < aRg.aStart.GetIndex() &&
+                // entstehen leere Sections ???
+                ( (pTmpNd = rDocNds[ aRg.aStart.GetIndex()-1 ])->IsSectionNode() &&
+                pTmpNd->EndOfSectionIndex() < aRg.aEnd.GetIndex())
+                )
+            {
+                aRg.aStart--;
+                bSectNdFnd = TRUE;
+            }
+        }
+
+        // ein Index auf den Start-/End-ContentNode, der mit verschoben wird,
+        // um wieder an der Position eine Kopie anzulegen.
+        if( bSectNdFnd && ( bJoinNext ? pEndTxtNd : pSttTxtNd ))
+        {
+            if( bJoinNext )
+            {
+                SwNodeRange aMvRg( *pEndTxtNd, 0, *pEndTxtNd, 1 );
+                rDocNds.MakeTxtNode( aMvRg.aStart, pEndTxtNd->GetTxtColl() );
+                rDocNds._MoveNodes( aMvRg, rDocNds, aRg.aStart );
+            }
+            else
+            {
+                SwNodeRange aMvRg( *pSttTxtNd, 0, *pSttTxtNd, 1 );
+                SwNode* pNew = rDocNds.MakeTxtNode( aMvRg.aEnd,
+                                            pSttTxtNd->GetTxtColl() );
+                if( nSectDiff )
+                {
+                    aMvRg.aEnd--;
+                    rDocNds._MoveNodes( aMvRg, rDocNds, aRg.aEnd );
+                    aRg.aEnd--;
+                }
+                else
+                    aRg.aStart = *pNew;
+            }
+        }
+
+        rDocNds._MoveNodes( aRg, rNds, SwNodeIndex( rNds.GetEndOfContent() ));
+        pMvStt = new SwNodeIndex( rNds, nNode );
+        bMvAroundSectNd = FALSE;
+
+        if( !bSectNdFnd )
+        {
+            nSectDiff = aRg.aEnd.GetIndex() - aRg.aStart.GetIndex();
+            bMvAroundSectNd = 0 != nSectDiff;
+        }
+
+        nNode = rNds.GetEndOfContent().GetIndex() - nNode;      // Differenz merken !
+    }
+    else
+        nNode = 0;      // kein Node verschoben -> keine Differenz zum Ende
+
+    // wurden davor noch Nodes geloescht ?? (FootNotes haben ContentNodes!)
+    if( !pSttTxtNd && !pEndTxtNd )
+    {
+        nNdDiff = nSttNode - rPam.GetPoint()->nNode.GetIndex() - (bFullPara ? 0 : 1);
+        rPam.Move( fnMoveForward, fnGoNode );
+    }
+    else
+        nNdDiff = nSttNode - rPam.GetPoint()->nNode.GetIndex();
+    if( bSectNdFnd )
+        nNdDiff -= nSectDiff;
+
+    if( !rPam.GetNode()->IsCntntNode() )
+        rPam.GetPoint()->nContent.Assign( 0, 0 );
+
+    // wird die History ueberhaupt benoetigt ??
+    if( pHistory && !pHistory->Count() )
+        DELETEZ( pHistory );
+}
+
+BOOL SwUndoDelete::SaveCntnt( const SwPosition* pStt, const SwPosition* pEnd,
+                    SwTxtNode* pSttTxtNd, SwTxtNode* pEndTxtNd )
+{
+    ULONG nNdIdx = pStt->nNode.GetIndex();
+    // 1 - kopiere den Anfang in den Start-String
+    if( pSttTxtNd )
+    {
+        BOOL bOneNode = nSttNode == nEndNode;
+        xub_StrLen nLen = bOneNode ? nEndCntnt - nSttCntnt
+                                : pSttTxtNd->GetTxt().Len() - nSttCntnt;
+        SwRegHistory aRHst( *pSttTxtNd, pHistory );
+        // immer alle TextAttribute sichern; ist fuers Undo mit voll-
+        // staendiger Attributierung am besten, wegen den evt.
+        // Ueberlappenden Bereichen von An/Aus.
+        pHistory->CopyAttr( pSttTxtNd->GetpSwpHints(), nNdIdx,
+                            0, pSttTxtNd->GetTxt().Len(), TRUE );
+        if( !bOneNode && pSttTxtNd->GetpSwAttrSet() )
+                pHistory->CopyFmtAttr( *pSttTxtNd->GetpSwAttrSet(), nNdIdx );
+
+        // die Laenge kann sich veraendert haben (!!Felder!!)
+        nLen = ( bOneNode ? pEnd->nContent.GetIndex() : pSttTxtNd->GetTxt().Len() )
+                - pStt->nContent.GetIndex();
+
+        // loesche jetzt noch den Text (alle Attribut-Aenderungen kommen in
+        // die Undo-History
+        pSttStr = (String*)new String( pSttTxtNd->GetTxt().Copy( nSttCntnt, nLen ));
+        pSttTxtNd->Erase( pStt->nContent, nLen );
+        if( pSttTxtNd->GetpSwpHints() )
+            pSttTxtNd->GetpSwpHints()->DeRegister();
+
+        if( bOneNode )
+            return FALSE;           // keine Nodes mehr verschieben
+    }
+
+
+    // 2 - kopiere das Ende in den End-String
+    if( pEndTxtNd )
+    {
+        SwIndex aEndIdx( pEndTxtNd );
+        nNdIdx = pEnd->nNode.GetIndex();
+        SwRegHistory aRHst( *pEndTxtNd, pHistory );
+
+        // immer alle TextAttribute sichern; ist fuers Undo mit voll-
+        // staendiger Attributierung am besten, wegen den evt.
+        // Ueberlappenden Bereichen von An/Aus.
+        pHistory->CopyAttr( pEndTxtNd->GetpSwpHints(), nNdIdx, 0,
+                            pEndTxtNd->GetTxt().Len(), TRUE );
+
+        if( pEndTxtNd->GetpSwAttrSet() )
+            pHistory->CopyFmtAttr( *pEndTxtNd->GetpSwAttrSet(), nNdIdx );
+
+        // loesche jetzt noch den Text (alle Attribut-Aenderungen kommen in
+        // die Undo-History
+        pEndStr = (String*)new String( pEndTxtNd->GetTxt().Copy( 0,
+                                    pEnd->nContent.GetIndex() ));
+        pEndTxtNd->Erase( aEndIdx, pEnd->nContent.GetIndex() );
+        if( pEndTxtNd->GetpSwpHints() )
+            pEndTxtNd->GetpSwpHints()->DeRegister();
+    }
+
+    // sind es nur zwei Nodes, dann ist schon alles erledigt.
+    if( ( pSttTxtNd || pEndTxtNd ) && nSttNode + 1 == nEndNode )
+        return FALSE;           // keine Nodes mehr verschieben
+
+    return TRUE;                // verschiebe die dazwischen liegenden Nodes
+}
+
+
+BOOL SwUndoDelete::CanGrouping( SwDoc* pDoc, const SwPaM& rDelPam )
+{
+    // ist das Undo groesser als 1 Node ? (sprich: Start und EndString)
+    if( pSttStr ? !pSttStr->Len() || pEndStr : TRUE )
+        return FALSE;
+
+    // es kann nur das Loeschen von einzelnen char's zusammengefasst werden
+    if( nSttNode != nEndNode || ( !bGroup && nSttCntnt+1 != nEndCntnt ))
+        return FALSE;
+
+    const SwPosition *pStt = rDelPam.Start(),
+                    *pEnd = rDelPam.GetPoint() == pStt
+                        ? rDelPam.GetMark()
+                        : rDelPam.GetPoint();
+
+    if( pStt->nNode != pEnd->nNode ||
+        pStt->nContent.GetIndex()+1 != pEnd->nContent.GetIndex() ||
+        pEnd->nNode != nSttNode )
+        return FALSE;
+
+    // untercheide zwischen BackSpace und Delete. Es muss dann das
+    // Undo-Array unterschiedlich aufgebaut werden !!
+    if( pEnd->nContent == nSttCntnt )
+    {
+        if( bGroup && !bBackSp ) return FALSE;
+        bBackSp = TRUE;
+    }
+    else if( pStt->nContent == nSttCntnt )
+    {
+        if( bGroup && bBackSp ) return FALSE;
+        bBackSp = FALSE;
+    }
+    else
+        return FALSE;
+
+    // sind die beiden Nodes (Nodes-/Undo-Array) ueberhaupt TextNodes?
+    SwTxtNode * pDelTxtNd = pStt->nNode.GetNode().GetTxtNode();
+    if( !pDelTxtNd ) return FALSE;
+
+    xub_StrLen nUChrPos = bBackSp ? 0 : pSttStr->Len()-1;
+    sal_Unicode cDelChar = pDelTxtNd->GetTxt().GetChar( pStt->nContent.GetIndex() );
+    if( ( CH_TXTATR_BREAKWORD == cDelChar && CH_TXTATR_INWORD == cDelChar ) ||
+        WordSelection::IsNormalChar( cDelChar ) !=
+        WordSelection::IsNormalChar( pSttStr->GetChar( nUChrPos ) ))
+        return FALSE;
+
+    {
+        SwRedlineSaveDatas* pTmpSav = new SwRedlineSaveDatas;
+        if( !FillSaveData( rDelPam, *pTmpSav, FALSE ))
+            delete pTmpSav, pTmpSav = 0;
+
+        BOOL bOk = ( !pRedlSaveData && !pTmpSav ) ||
+                   ( pRedlSaveData && pTmpSav &&
+                SwUndo::CanRedlineGroup( *pRedlSaveData, *pTmpSav, bBackSp ));
+        delete pTmpSav;
+        if( !bOk )
+            return FALSE;
+
+        pDoc->DeleteRedline( rDelPam, FALSE );
+    }
+
+    // Ok, die beiden 'Deletes' koennen zusammen gefasst werden, also
+    // 'verschiebe' das enstprechende Zeichen
+    if( bBackSp )
+        nSttCntnt--;    // BackSpace: Zeichen in Array einfuegen !!
+    else
+    {
+        nEndCntnt++;    // Delete: Zeichen am Ende anhaengen
+        nUChrPos++;
+    }
+    pSttStr->Insert( cDelChar, nUChrPos );
+    pDelTxtNd->Erase( pStt->nContent, 1 );
+
+    bGroup = TRUE;
+    return TRUE;
+}
+
+
+
+SwUndoDelete::~SwUndoDelete()
+{
+    delete pSttStr;
+    delete pEndStr;
+    if( pMvStt )        // loesche noch den Bereich aus dem UndoNodes Array
+    {
+        // Insert speichert den Inhalt in der IconSection
+        pMvStt->GetNode().GetNodes().Delete( *pMvStt, nNode );
+        delete pMvStt;
+    }
+    delete pRedlData;
+    delete pRedlSaveData;
+}
+
+
+
+void SwUndoDelete::Undo( SwUndoIter& rUndoIter )
+{
+    SwDoc* pDoc = &rUndoIter.GetDoc();
+    BOOL bUndo = pDoc->DoesUndo();
+    pDoc->DoUndo( FALSE );
+
+    ULONG nCalcStt = nSttNode - nNdDiff;
+    if( bSectNdFnd )
+        nCalcStt -= nSectDiff;
+    SwNodeIndex aIdx( pDoc->GetNodes(), nCalcStt );
+
+    // SectionNodes blieben stehen und es wurde danach zusammengefasst
+    if( bMvAroundSectNd && !bJoinNext && pSttStr && pEndStr )
+        pDoc->GetNodes().GoNext( &aIdx );
+    SwNode* pInsNd = &aIdx.GetNode();
+
+    {       // Block, damit der SwPosition beim loeschen vom Node
+            // abgemeldet ist
+        SwPosition aPos( aIdx );
+        if( !bDelFullPara )
+        {
+            if( pInsNd->IsTableNode() )
+            {
+                pInsNd = pDoc->GetNodes().MakeTxtNode( aIdx,
+                        (SwTxtFmtColl*)pDoc->GetDfltTxtFmtColl() );
+                aIdx--;
+                aPos.nNode = aIdx;
+                aPos.nContent.Assign( pInsNd->GetCntntNode(), nSttCntnt );
+            }
+            else
+            {
+                if( pInsNd->IsCntntNode() )
+                    aPos.nContent.Assign( (SwCntntNode*)pInsNd, nSttCntnt );
+#ifndef PRODUCT
+                else
+                    ASSERT( bSectNdFnd, "vor welchen Node kopieren?" );
+#endif
+                if( !bTblDelLastNd )
+                    pInsNd = 0;         // Node nicht loeschen !!
+            }
+        }
+        else
+            pInsNd = 0;         // Node nicht loeschen !!
+
+        SwNodes* pUNds = (SwNodes*)pDoc->GetUndoNds();
+        BOOL bNodeMove = 0 != nNode;
+
+        // damit nicht die Attribute aus dem "Start"-Node kopiert werden,
+        // splitte erstmal den Node (wenn noetig)
+        if( bSectNdFnd )
+        {
+            if( bJoinNext )
+                aPos.nNode++;
+        }
+        else if( pEndStr )
+        {
+            // alle Attribute verwerfen, wurden alle gespeichert!
+            SwTxtNode* pTxtNd = aPos.nNode.GetNode().GetTxtNode();
+            if( pTxtNd && pTxtNd->GetpSwAttrSet() )
+                pTxtNd->ResetAllAttr();
+
+            if( pTxtNd->GetpSwpHints() )
+                pTxtNd->ClearSwpHintsArr( FALSE );
+
+            if( pSttStr )
+            {
+                pDoc->SplitNode( aPos );
+                pTxtNd = aPos.nNode.GetNode().GetTxtNode();
+                if( bMvAroundSectNd )
+                {
+                    // leider muessen wir den Node noch verschieben
+                    SwNodeIndex aMvIdx( pDoc->GetNodes(), ( bJoinNext
+                            ? nEndNode - nNdDiff - nNode + nSectDiff + 1
+                            : nCalcStt )
+                            );
+                    if( bJoinNext )
+                        aPos.nNode++;       // auf den naechsten
+                    SwNodeRange aRg( aPos.nNode, -1, aPos.nNode );
+                    pDoc->GetNodes()._MoveNodes( aRg, pDoc->GetNodes(), aMvIdx, TRUE );
+
+                    if( !bJoinNext )
+                        aPos.nNode = aMvIdx;
+                }
+            }
+
+            pTxtNd->Insert( *pEndStr, aPos.nContent, INS_NOHINTEXPAND );
+            if( !bNodeMove && pSttStr )
+                aPos.nNode = nSttNode - nNdDiff;
+        }
+        else if( pSttStr && bNodeMove )
+        {
+            SwTxtNode * pNd = aPos.nNode.GetNode().GetTxtNode();
+            if( pNd )
+            {
+                if( nSttCntnt < pNd->GetTxt().Len() )
+                    pDoc->SplitNode( aPos );
+                else
+                    aPos.nNode++;
+            }
+        }
+
+
+        if( bNodeMove )
+        {
+            SwNodeRange aRg( *pMvStt, 0, *pMvStt, nNode );
+            SwNodeIndex aPrevIdx( aPos.nNode, -1 );
+            pUNds->_Copy( aRg, aPos.nNode );
+
+            // SectionNode-Modus und von unten nach oben selektiert:
+            //  -> im EndNode steht noch der Rest vom Join => loeschen
+            if( bSectNdFnd )
+            {
+                SwPosition aSpPos( bJoinNext ? aPrevIdx : aPos.nNode );
+                if( !bJoinNext && !nSectDiff )      // move to next content node
+                    pDoc->GetNodes().GoNext( &aSpPos.nNode );
+
+                aSpPos.nContent.Assign( aSpPos.nNode.GetNode().GetCntntNode(),
+                                        nSttCntnt );
+                pDoc->SplitNode( aSpPos );
+                if( bJoinNext )
+                {
+                    aPrevIdx = aPos.nNode;
+                    pDoc->GetNodes().GoPrevious( &aPrevIdx );
+                }
+                else
+                {
+                    aPrevIdx++;
+                    if( nSectDiff )
+                        aPrevIdx++;
+                    aSpPos.nNode--;
+                }
+                SwNodeRange aMvRg( aSpPos.nNode, 0, aSpPos.nNode, 1 );
+                pDoc->GetNodes()._MoveNodes( aMvRg, pDoc->GetNodes(),
+                                            aPrevIdx );
+                pDoc->GetNodes().Delete( aPrevIdx, 1 );
+
+                if( pEndStr )
+                {
+                    aPos.nNode = nEndNode - nNdDiff;    // am Anfang manipulieren
+                    SwTxtNode * pTxtNd = aPos.nNode.GetNode().GetTxtNode();
+                    if( pTxtNd->GetpSwAttrSet() )
+                        pTxtNd->ResetAllAttr();
+
+                    aPos.nContent.Assign( pTxtNd, 0 );
+                    pTxtNd->Insert( *pEndStr, aPos.nContent, INS_NOHINTEXPAND );
+                }
+            }
+
+            aPos.nNode = nSttNode - nNdDiff;    // am Anfang manipulieren
+        }
+        if( pSttStr )
+        {
+            SwTxtNode * pTxtNd = aPos.nNode.GetNode().GetTxtNode();
+            // wenn mehr als ein Node geloescht wurde, dann wurden auch
+            // alle "Node"-Attribute gespeichert
+            if( pTxtNd->GetpSwAttrSet() && bNodeMove && !pEndStr )
+                pTxtNd->ResetAllAttr();
+
+            if( pTxtNd->GetpSwpHints() )
+                pTxtNd->ClearSwpHintsArr( FALSE );
+
+            // SectionNode-Modus und von oben nach unten selektiert:
+            //  -> im StartNode steht noch der Rest vom Join => loeschen
+            aPos.nContent.Assign( pTxtNd, nSttCntnt );
+            pTxtNd->Insert( *pSttStr, aPos.nContent, INS_NOHINTEXPAND );
+        }
+
+        if( pHistory )
+        {
+            pHistory->TmpRollback( pDoc, nSetPos, FALSE );
+            if( nSetPos )       // es gab Fussnoten/FlyFrames
+            {
+                // gibts ausser diesen noch andere ?
+                if( nSetPos < pHistory->Count() )
+                {
+                    // dann sicher die Attribute anderen Attribute
+                    SwHistory aHstr;
+                    aHstr.Move( 0, pHistory, nSetPos );
+                    pHistory->Rollback( pDoc );
+                    pHistory->Move( 0, &aHstr );
+                }
+                else
+                {
+                    pHistory->Rollback( pDoc );
+                    DELETEZ( pHistory );
+                }
+            }
+        }
+
+        if( bResetPgDesc || bResetPgBrk )
+        {
+            USHORT nStt = bResetPgDesc ? RES_PAGEDESC : RES_BREAK;
+            USHORT nEnd = bResetPgBrk ? RES_BREAK : RES_PAGEDESC;
+
+            SwNode* pNode = pDoc->GetNodes()[ nEndNode + 1 ];
+            if( pNode->IsCntntNode() )
+                ((SwCntntNode*)pNode)->ResetAttr( nStt, nEnd );
+            else if( pNode->IsTableNode() )
+                ((SwTableNode*)pNode)->GetTable().GetFrmFmt()->ResetAttr( nStt, nEnd );
+        }
+    }
+
+    // den temp. eingefuegten Node noch loeschen !!
+    if( pInsNd )
+        pDoc->GetNodes().Delete( aIdx, 1 );
+
+    if( pRedlSaveData )
+        SetSaveData( *pDoc, *pRedlSaveData );
+
+    pDoc->DoUndo( bUndo );          // Undo wieder einschalten
+    SetPaM( rUndoIter, TRUE );
+}
+
+void SwUndoDelete::Redo( SwUndoIter& rUndoIter )
+{
+    rUndoIter.SetUpdateAttr( TRUE );
+
+    SwPaM& rPam = *rUndoIter.pAktPam;
+    SwDoc& rDoc = *rPam.GetDoc();
+
+    SetPaM( rPam );
+
+    if( pRedlSaveData )
+        rDoc.DeleteRedline( rPam, FALSE );
+
+    if( !bDelFullPara )
+    {
+        RemoveIdxFromRange( rPam, FALSE );
+        SetPaM( rPam );
+
+        if( !bJoinNext )            // Dann Selektion von unten nach oben
+            rPam.Exchange();        // wieder herstellen!
+    }
+
+    if( pHistory )      // wurden Attribute gesichert ?
+    {
+        pHistory->SetTmpEnd( pHistory->Count() );
+        SwHistory aHstr;
+        aHstr.Move( 0, pHistory );
+
+        if( bDelFullPara )
+        {
+            ASSERT( rPam.HasMark(), "PaM ohne Mark" );
+            DelCntntIndex( *rPam.GetMark(), *rPam.GetPoint(),
+                            DelCntntType(DELCNT_ALL | DELCNT_CHKNOCNTNT) );
+
+            _DelBookmarks( rPam.GetMark()->nNode, rPam.GetPoint()->nNode );
+        }
+        else
+            DelCntntIndex( *rPam.GetMark(), *rPam.GetPoint() );
+        nSetPos = pHistory ? pHistory->Count() : 0;
+
+        pHistory->Move( nSetPos, &aHstr );
+    }
+    else
+    {
+        if( bDelFullPara )
+        {
+            ASSERT( rPam.HasMark(), "PaM ohne Mark" );
+            DelCntntIndex( *rPam.GetMark(), *rPam.GetPoint(),
+                            DelCntntType(DELCNT_ALL | DELCNT_CHKNOCNTNT) );
+
+            _DelBookmarks( rPam.GetMark()->nNode, rPam.GetPoint()->nNode );
+        }
+        else
+            DelCntntIndex( *rPam.GetMark(), *rPam.GetPoint() );
+        nSetPos = pHistory ? pHistory->Count() : 0;
+    }
+
+    if( !pSttStr && !pEndStr )
+    {
+        SwNodeIndex& rSttIdx = ( bDelFullPara || bJoinNext )
+                                    ? rPam.GetMark()->nNode
+                                    : rPam.GetPoint()->nNode;
+        SwTableNode* pTblNd = rSttIdx.GetNode().GetTableNode();
+        if( pTblNd )
+        {
+            if( bTblDelLastNd )
+            {
+                // dann am Ende wieder einen Node einfuegen
+                const SwNodeIndex aTmpIdx( *pTblNd->EndOfSectionNode(), 1 );
+                rDoc.GetNodes().MakeTxtNode( aTmpIdx,
+                        rDoc.GetTxtCollFromPool( RES_POOLCOLL_STANDARD ) );
+            }
+
+            SwCntntNode* pNextNd = rDoc.GetNodes()[
+                    pTblNd->EndOfSectionIndex()+1 ]->GetCntntNode();
+            if( pNextNd )
+            {
+                SwFrmFmt* pTableFmt = pTblNd->GetTable().GetFrmFmt();
+                const SfxPoolItem *pItem;
+                if( SFX_ITEM_SET == pTableFmt->GetItemState( RES_PAGEDESC,
+                    FALSE, &pItem ) )
+                    pNextNd->SetAttr( *pItem );
+
+                if( SFX_ITEM_SET == pTableFmt->GetItemState( RES_BREAK,
+                    FALSE, &pItem ) )
+                    pNextNd->SetAttr( *pItem );
+            }
+            pTblNd->DelFrms();
+        }
+
+        rDoc.GetNodes().Delete( rSttIdx, nEndNode - nSttNode );
+
+        rPam.DeleteMark();
+        // setze den Cursor immer in einen ContentNode !!
+        if( !rPam.Move( fnMoveBackward, fnGoCntnt ) &&
+            !rPam.Move( fnMoveForward, fnGoCntnt ) )
+            rPam.GetPoint()->nContent.Assign( rPam.GetCntntNode(), 0 );
+    }
+    else if( bDelFullPara )
+    {
+        // der Pam wurde am Point( == Ende) um eins erhoeht, um einen
+        // Bereich fuers Undo zu haben. Der muss jetzt aber wieder entfernt
+        // werden!!!
+        rPam.End()->nNode--;
+        if( rPam.GetPoint()->nNode == rPam.GetMark()->nNode )
+            *rPam.GetMark() = *rPam.GetPoint();
+        rDoc.DelFullPara( rPam );
+    }
+    else
+        rDoc.DeleteAndJoin( rPam );
+}
+
+void SwUndoDelete::Repeat( SwUndoIter& rUndoIter )
+{
+    if( UNDO_DELETE == rUndoIter.GetLastUndoId() )
+        return;
+
+    SwPaM& rPam = *rUndoIter.pAktPam;
+    SwDoc& rDoc = *rPam.GetDoc();
+    BOOL bGroupUndo = rDoc.DoesGroupUndo();
+    rDoc.DoGroupUndo( FALSE );
+    if( !rPam.HasMark() )
+    {
+        rPam.SetMark();
+        rPam.Move( fnMoveForward, fnGoCntnt );
+    }
+    if( bDelFullPara )
+        rDoc.DelFullPara( rPam );
+    else
+        rDoc.DeleteAndJoin( rPam );
+    rDoc.DoGroupUndo( bGroupUndo );
+    rUndoIter.pLastUndoObj = this;
+}
+
+/*************************************************************************
+
+      Source Code Control System - Header
+
+      $Header: /zpool/svn/migration/cvs_rep_09_09_08/code/sw/source/core/undo/undel.cxx,v 1.1.1.1 2000-09-19 00:08:27 hr Exp $
+
+      Source Code Control System - Update
+
+      $Log: not supported by cvs2svn $
+      Revision 1.91  2000/09/18 16:04:28  willem.vandorp
+      OpenOffice header added.
+
+      Revision 1.90  2000/07/25 19:47:22  jp
+      Bug #73345#: Undo - restore the node inside the last section and in the first
+
+      Revision 1.89  2000/07/20 13:15:28  jp
+      change old txtatr-character to the two new characters
+
+      Revision 1.88  2000/05/19 12:53:32  jp
+      use WordSelection class for check chars
+
+      Revision 1.87  2000/05/09 10:03:58  jp
+      Changes for Unicode
+
+      Revision 1.86  1999/12/16 22:51:13  jp
+      Bug #70704#: content objects inside expanded ranges
+
+      Revision 1.85  1998/08/24 14:29:40  JP
+      Bug #55458#: SwUndoDelete - umsetzen vom PageDesc/-Break jetzt per Flag merken
+
+
+      Rev 1.84   24 Aug 1998 16:29:40   JP
+   Bug #55458#: SwUndoDelete - umsetzen vom PageDesc/-Break jetzt per Flag merken
+
+      Rev 1.83   02 Apr 1998 15:12:50   JP
+   Redo: Undo-Flag wird schon von der EditShell abgeschaltet
+
+      Rev 1.82   31 Mar 1998 15:44:46   JP
+   Redo: den richtigen NodeIndex beim Delete benutzen
+
+      Rev 1.81   11 Mar 1998 18:15:28   JP
+   Redo: Selektion sollte noch die richtige Richtung haben
+
+      Rev 1.80   09 Feb 1998 21:02:20   JP
+   Copy-Schnittstelle am Doc hat sich geaendert
+
+      Rev 1.79   06 Feb 1998 18:06:40   JP
+   SwUndoDel: nicht zuviele Nodes verschieben
+
+      Rev 1.78   16 Jan 1998 12:01:16   JP
+   Redlines beachten, auch wenns abgeschaltet ist
+
+      Rev 1.77   06 Jan 1998 16:26:04   JP
+   Redline beachten
+
+      Rev 1.76   19 Dec 1997 12:14:22   JP
+   Undo: Redlining beachten
+
+      Rev 1.75   17 Dec 1997 14:11:22   JP
+   Undo: Range nicht zu gross anlegen
+
+      Rev 1.74   10 Dec 1997 16:21:18   JP
+   Undo: ggfs. den ContentIndex abmelden
+
+      Rev 1.73   10 Dec 1997 16:04:02   AMA
+   New: SwSectionFrm-Einbau
+
+*************************************************************************/
+
diff --git a/sw/source/core/undo/undobj.cxx b/sw/source/core/undo/undobj.cxx
new file mode 100644
index 000000000000..3939018f6eea
--- /dev/null
+++ b/sw/source/core/undo/undobj.cxx
@@ -0,0 +1,1276 @@
+/*************************************************************************
+ *
+ *  $RCSfile: undobj.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:27 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _TXTFTN_HXX //autogen
+#include 
+#endif
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _FTNIDX_HXX //autogen
+#include 
+#endif
+#ifndef _FRMFMT_HXX //autogen
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include            // fuer die UndoIds
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _UNDOBJ_HXX
+#include 
+#endif
+#ifndef _ROLBCK_HXX
+#include 
+#endif
+#ifndef _NDNOTXT_HXX
+#include 
+#endif
+#ifndef _BOOKMRK_HXX
+#include 
+#endif
+#ifndef _MVSAVE_HXX
+#include 
+#endif
+#ifndef _REDLINE_HXX
+#include 
+#endif
+
+
+class SwRedlineSaveData : public SwUndRng, public SwRedlineData,
+                          private SwUndoSaveSection
+{
+public:
+    SwRedlineSaveData( SwComparePosition eCmpPos,
+                        const SwPosition& rSttPos, const SwPosition& rEndPos,
+                        SwRedline& rRedl, BOOL bCopyNext );
+    ~SwRedlineSaveData();
+    void RedlineToDoc( SwPaM& rPam );
+    SwNodeIndex* GetMvSttIdx() const
+        { return SwUndoSaveSection::GetMvSttIdx(); }
+};
+
+SV_IMPL_PTRARR( SwUndos, SwUndo*)
+SV_IMPL_PTRARR( SwRedlineSaveDatas, SwRedlineSaveDataPtr )
+
+SwUndoIter::SwUndoIter( SwPaM* pPam, USHORT nId )
+{
+    nUndoId = nId;
+    bWeiter = nId ? TRUE : FALSE;
+    bUpdateAttr = FALSE;
+    pAktPam = pPam;
+    nEndCnt = 0;
+    pSelFmt = 0;
+    pMarkList = 0;
+}
+inline SwDoc& SwUndoIter::GetDoc() const { return *pAktPam->GetDoc(); }
+
+//------------------------------------------------------------
+
+// Diese Klasse speichert den Pam als USHORT's und kann diese wieder zu
+
+// einem PaM zusammensetzen
+SwUndRng::SwUndRng()
+    : nSttNode( 0 ), nEndNode( 0 ), nSttCntnt( 0 ), nEndCntnt( 0 )
+{
+}
+
+SwUndRng::SwUndRng( const SwPaM& rPam )
+{
+    SetValues( rPam );
+}
+
+void SwUndRng::SetValues( const SwPaM& rPam )
+{
+    const SwPosition *pStt = rPam.Start();
+    if( rPam.HasMark() )
+    {
+        const SwPosition *pEnd = rPam.GetPoint() == pStt
+                        ? rPam.GetMark()
+                        : rPam.GetPoint();
+        nEndNode = pEnd->nNode.GetIndex();
+        nEndCntnt = pEnd->nContent.GetIndex();
+    }
+    else
+        // keine Selektion !!
+        nEndNode = 0, nEndCntnt = STRING_MAXLEN;
+
+    nSttNode = pStt->nNode.GetIndex();
+    nSttCntnt = pStt->nContent.GetIndex();
+}
+
+void SwUndRng::SetPaM( SwPaM & rPam, BOOL bCorrToCntnt ) const
+{
+    rPam.DeleteMark();
+    rPam.GetPoint()->nNode = nSttNode;
+    SwNode* pNd = rPam.GetNode();
+    if( pNd->IsCntntNode() )
+        rPam.GetPoint()->nContent.Assign( pNd->GetCntntNode(), nSttCntnt );
+    else if( bCorrToCntnt )
+        rPam.Move( fnMoveForward, fnGoCntnt );
+    else
+        rPam.GetPoint()->nContent.Assign( 0, 0 );
+
+    if( !nEndNode && STRING_MAXLEN == nEndCntnt )       // keine Selection
+        return ;
+
+    rPam.SetMark();
+    if( nSttNode == nEndNode && nSttCntnt == nEndCntnt )
+        return;                             // nichts mehr zu tun
+
+    rPam.GetPoint()->nNode = nEndNode;
+    if( (pNd = rPam.GetNode())->IsCntntNode() )
+        rPam.GetPoint()->nContent.Assign( pNd->GetCntntNode(), nEndCntnt );
+    else if( bCorrToCntnt )
+        rPam.Move( fnMoveBackward, fnGoCntnt );
+    else
+        rPam.GetPoint()->nContent.Assign( 0, 0 );
+}
+
+void SwUndRng::SetPaM( SwUndoIter& rIter, BOOL bCorrToCntnt ) const
+{
+    if( rIter.pAktPam )
+        SetPaM( *rIter.pAktPam, bCorrToCntnt );
+}
+
+//------------------------------------------------------------
+
+
+void SwUndo::RemoveIdxFromSection( SwDoc& rDoc, ULONG nSttIdx,
+                                    ULONG* pEndIdx )
+{
+    SwNodeIndex aIdx( rDoc.GetNodes(), nSttIdx );
+    SwNodeIndex aEndIdx( rDoc.GetNodes(), pEndIdx ? *pEndIdx
+                                    : aIdx.GetNode().EndOfSectionIndex() );
+    SwPosition aPos( rDoc.GetNodes().GetEndOfPostIts() );
+    rDoc.CorrAbs( aIdx, aEndIdx, aPos, TRUE );
+}
+
+void SwUndo::RemoveIdxFromRange( SwPaM& rPam, BOOL bMoveNext )
+{
+    const SwPosition* pEnd = rPam.End();
+    if( bMoveNext )
+    {
+        if( pEnd != rPam.GetPoint() )
+            rPam.Exchange();
+
+        SwNodeIndex aStt( rPam.GetMark()->nNode );
+        SwNodeIndex aEnd( rPam.GetPoint()->nNode );
+
+        if( !rPam.Move( fnMoveForward ) )
+        {
+            rPam.Exchange();
+            if( !rPam.Move( fnMoveBackward ) )
+            {
+                rPam.GetPoint()->nNode = rPam.GetDoc()->GetNodes().GetEndOfPostIts();
+                rPam.GetPoint()->nContent.Assign( 0, 0 );
+            }
+        }
+
+        rPam.GetDoc()->CorrAbs( aStt, aEnd, *rPam.GetPoint(), TRUE );
+    }
+    else
+        rPam.GetDoc()->CorrAbs( rPam, *pEnd, TRUE );
+}
+
+void SwUndo::RemoveIdxRel( ULONG nIdx, const SwPosition& rPos )
+{
+    // nur die Crsr verschieben; die Bookmarks/TOXMarks/.. werden vom
+    // entsp. JoinNext/JoinPrev erledigt!
+    SwNodeIndex aIdx( rPos.nNode.GetNode().GetNodes(), nIdx );
+    ::PaMCorrRel( aIdx, rPos );
+}
+
+SwUndo::~SwUndo()
+{
+}
+
+void SwUndo::Repeat( SwUndoIter& rIter )
+{
+    rIter.pLastUndoObj = this;
+}
+
+//------------------------------------------------------------
+
+SwUndoSaveCntnt::SwUndoSaveCntnt()
+    : pHistory( 0 )
+{}
+
+SwUndoSaveCntnt::~SwUndoSaveCntnt()
+{
+    delete pHistory;
+}
+
+    // wird fuer das Loeschen von Inhalt benoetigt. Fuer das ReDo werden
+    // Inhalte in das UndoNodesArray verschoben. Diese Methoden fuegen
+    // am Ende eines TextNodes fuer die Attribute einen Trenner ein.
+    // Dadurch werden die Attribute nicht expandiert.
+    // MoveTo..     verschiebt aus dem NodesArray in das UndoNodesArray
+    // MoveFrom..   verschiebt aus dem UndoNodesArray in das NodesArray
+
+    // 2.8.93:  ist pEndNdIdx angebenen, wird vom Undo/Redo -Ins/DelFly
+    //          aufgerufen. Dann soll die gesamte Section verschoben werden.
+
+void SwUndoSaveCntnt::MoveToUndoNds( SwPaM& rPaM, SwNodeIndex* pNodeIdx,
+                    SwIndex* pCntIdx, ULONG* pEndNdIdx, xub_StrLen* pEndCntIdx )
+{
+    SwDoc& rDoc = *rPaM.GetDoc();
+    BOOL bUndo = rDoc.DoesUndo();
+    rDoc.DoUndo( FALSE );
+
+    SwNoTxtNode* pCpyNd = rPaM.GetNode()->GetNoTxtNode();
+
+    // jetzt kommt das eigentliche Loeschen(Verschieben)
+    SwNodes& rNds = (SwNodes&)*rDoc.GetUndoNds();
+    SwPosition aPos( pEndNdIdx ? rNds.GetEndOfPostIts()
+                               : rNds.GetEndOfExtras() );
+    aPos.nNode--;
+
+    const SwPosition* pStt = rPaM.Start(), *pEnd = rPaM.End();
+
+    if( pCpyNd || pEndNdIdx || !aPos.nNode.GetNode().GetCntntNode() ||
+        (!pStt->nContent.GetIndex() && (pStt->nNode != pEnd->nNode ||
+                (!pStt->nNode.GetNode().GetCntntNode() ||
+                    pStt->nNode.GetNode().GetCntntNode()->Len() ==
+                        pEnd->nContent.GetIndex() ) ) ) )
+    {
+        aPos.nNode++;
+        aPos.nContent = 0;
+    }
+    else
+        aPos.nNode.GetNode().GetCntntNode()->MakeEndIndex( &aPos.nContent );
+
+    // als USHORT merken; die Indizies verschieben sich !!
+    ULONG nTmpMvNode = aPos.nNode.GetIndex();
+    xub_StrLen nTmpMvCntnt = aPos.nContent.GetIndex();
+
+    if( pCpyNd || pEndNdIdx )
+    {
+        SwNodeRange aRg( pStt->nNode, 0, pEnd->nNode, 1 );
+        rDoc.GetNodes()._MoveNodes( aRg, rNds, aPos.nNode, FALSE );
+        aPos.nContent = 0;
+        aPos.nNode--;
+    }
+    else
+    {
+        rDoc.GetNodes().Move( rPaM, aPos, rNds, FALSE );
+
+        SwTxtNode* pTxtNd = aPos.nNode.GetNode().GetTxtNode();
+        if( pTxtNd )        // fuege einen Trenner fuer die Attribute ein !
+        {
+            // weil aber beim Insert die Attribute angefasst/sprich
+            // aus dem Array geloescht und wieder eingefuegt werden, koennen
+            // dadurch Attribute verschwinden (z.B "Fett aus" von 10-20,
+            // "Fett an" von 12-15, dann wird durchs Insert/Delete das
+            // "Fett an" geloescht !! Ist hier aber nicht erwuenscht !!)
+            // DARUM: nicht die Hints anfassen, direct den String manipulieren
+
+            String& rStr = (String&)pTxtNd->GetTxt();
+            // Zur Sicherheit lieber nur wenn wirklich am Ende steht
+            if( rStr.Len() == aPos.nContent.GetIndex() )
+            {
+                rStr.Insert( ' ' );
+                ++aPos.nContent;
+            }
+            else
+                pTxtNd->Insert( ' ', aPos.nContent, INS_NOHINTEXPAND);
+        }
+    }
+    if( pEndNdIdx )
+        *pEndNdIdx = aPos.nNode.GetIndex();
+    if( pEndCntIdx )
+        *pEndCntIdx = aPos.nContent.GetIndex();
+
+    // alte Position
+    aPos.nNode = nTmpMvNode;
+    if( pNodeIdx )
+        *pNodeIdx = aPos.nNode;
+
+    if( pCntIdx )
+    {
+        SwCntntNode* pCNd = aPos.nNode.GetNode().GetCntntNode();
+        if( pCNd )
+            pCntIdx->Assign( pCNd, nTmpMvCntnt );
+        else
+            pCntIdx->Assign( 0, 0 );
+    }
+
+    rDoc.DoUndo( bUndo );
+}
+
+void SwUndoSaveCntnt::MoveFromUndoNds( SwDoc& rDoc, ULONG nNodeIdx,
+                            xub_StrLen nCntIdx, SwPosition& rInsPos,
+                            ULONG* pEndNdIdx, xub_StrLen* pEndCntIdx )
+{
+    // jetzt kommt das wiederherstellen
+    SwNodes& rNds = (SwNodes&)*rDoc.GetUndoNds();
+    if( nNodeIdx == rNds.GetEndOfPostIts().GetIndex() )
+        return;     // nichts gespeichert
+
+    BOOL bUndo = rDoc.DoesUndo();
+    rDoc.DoUndo( FALSE );
+
+    SwPaM aPaM( rInsPos );
+    if( pEndNdIdx )         // dann hole aus diesem den Bereich
+        aPaM.GetPoint()->nNode.Assign( rNds, *pEndNdIdx );
+    else
+    {
+        aPaM.GetPoint()->nNode = rNds.GetEndOfExtras();
+        GoInCntnt( aPaM, fnMoveBackward );
+    }
+
+    SwTxtNode* pTxtNd = aPaM.GetNode()->GetTxtNode();
+    if( !pEndNdIdx && pTxtNd )  // loesche den Trenner wieder
+    {
+        if( pEndCntIdx )
+            aPaM.GetPoint()->nContent.Assign( pTxtNd, *pEndCntIdx );
+        if( pTxtNd->GetTxt().Len() )
+        {
+            GoInCntnt( aPaM, fnMoveBackward );
+            pTxtNd->Erase( aPaM.GetPoint()->nContent, 1 );
+        }
+
+        aPaM.SetMark();
+        aPaM.GetPoint()->nNode = nNodeIdx;
+        aPaM.GetPoint()->nContent.Assign( aPaM.GetCntntNode(), nCntIdx );
+
+        _SaveRedlEndPosForRestore aRedlRest( rInsPos.nNode );
+
+        rNds.Move( aPaM, rInsPos, rDoc.GetNodes() );
+
+        // noch den letzen Node loeschen.
+        if( !aPaM.GetPoint()->nContent.GetIndex() ||
+            ( aPaM.GetPoint()->nNode++ &&       // noch leere Nodes am Ende ??
+            &rNds.GetEndOfExtras() != &aPaM.GetPoint()->nNode.GetNode() ))
+        {
+            aPaM.GetPoint()->nContent.Assign( 0, 0 );
+            aPaM.SetMark();
+            rNds.Delete( aPaM.GetPoint()->nNode,
+                        rNds.GetEndOfExtras().GetIndex() -
+                        aPaM.GetPoint()->nNode.GetIndex() );
+        }
+
+        aRedlRest.Restore();
+    }
+    else if( pEndNdIdx || !pTxtNd )
+    {
+        SwNodeRange aRg( rNds, nNodeIdx, rNds, (pEndNdIdx
+                        ? ((*pEndNdIdx) + 1)
+                        : rNds.GetEndOfExtras().GetIndex() ) );
+        rNds._MoveNodes( aRg, rDoc.GetNodes(), rInsPos.nNode, 0 == pEndNdIdx );
+
+    }
+    else
+        ASSERT( FALSE, "was ist es denn nun?" );
+
+    rDoc.DoUndo( bUndo );
+}
+
+// diese beiden Methoden bewegen den Point vom Pam zurueck/vor. Damit
+// kann fuer ein Undo/Redo ein Bereich aufgespannt werden. (Der
+// Point liegt dann vor dem manipuliertem Bereich !!)
+// Das Flag gibt an, ob noch vorm Point Inhalt steht.
+
+BOOL SwUndoSaveCntnt::MovePtBackward( SwPaM& rPam )
+{
+    rPam.SetMark();
+    if( rPam.Move( fnMoveBackward ))
+        return TRUE;
+
+    // gibt es nach vorne keinen Inhalt mehr, so setze den Point einfach
+    // auf die vorherige Position (Node und Content, damit der Content
+    // abgemeldet wird !!)
+    rPam.GetPoint()->nNode--;
+    rPam.GetPoint()->nContent.Assign( 0, 0 );
+    return FALSE;
+}
+
+void SwUndoSaveCntnt::MovePtForward( SwPaM& rPam, BOOL bMvBkwrd )
+{
+    // gab es noch Inhalt vor der Position ?
+    if( bMvBkwrd )
+        rPam.Move( fnMoveForward );
+    else
+    {                       // setzen Point auf die naechste Position
+        rPam.GetPoint()->nNode++;
+        SwCntntNode* pCNd = rPam.GetCntntNode();
+        if( pCNd )
+            pCNd->MakeStartIndex( &rPam.GetPoint()->nContent );
+        else
+            rPam.Move( fnMoveForward );
+    }
+}
+
+
+/*
+   JP 21.03.94: loesche alle Objecte, die ContentIndizies auf den ang.
+                Bereich besitzen.
+                Zur Zeit gibts folgende Objecte
+                    - Fussnoten
+                    - Flys
+                    - Bookmarks
+                    - Verzeichnisse
+*/
+
+void SwUndoSaveCntnt::DelCntntIndex( const SwPosition& rMark,
+                                     const SwPosition& rPoint,
+                                     DelCntntType nDelCntntType )
+{
+    const SwPosition *pStt = rMark < rPoint ? &rMark : &rPoint,
+                    *pEnd = &rMark == pStt ? &rPoint : &rMark;
+
+    SwDoc* pDoc = rMark.nNode.GetNode().GetDoc();
+    BOOL bDoesUndo = pDoc->DoesUndo();
+    pDoc->DoUndo( FALSE );
+
+    // 1. Fussnoten
+    if( DELCNT_FTN & nDelCntntType )
+    {
+        SwFtnIdxs& rFtnArr = pDoc->GetFtnIdxs();
+        if( rFtnArr.Count() )
+        {
+            const SwNode* pFtnNd;
+            USHORT nPos;
+            rFtnArr.SeekEntry( pStt->nNode, &nPos );
+            SwTxtFtn* pSrch;
+
+            // loesche erstmal alle, die dahinter stehen
+            while( nPos < rFtnArr.Count() && ( pFtnNd =
+                &( pSrch = rFtnArr[ nPos ] )->GetTxtNode())->GetIndex()
+                        <= pEnd->nNode.GetIndex() )
+            {
+                xub_StrLen nFtnSttIdx = *pSrch->GetStart();
+                if( (DELCNT_CHKNOCNTNT & nDelCntntType )
+                    ? (&pEnd->nNode.GetNode() == pFtnNd )
+                    : (( &pStt->nNode.GetNode() == pFtnNd &&
+                    pStt->nContent.GetIndex() > nFtnSttIdx) ||
+                    ( &pEnd->nNode.GetNode() == pFtnNd &&
+                    nFtnSttIdx >= pEnd->nContent.GetIndex() )) )
+                {
+                    ++nPos;     // weiter suchen
+                    continue;
+                }
+
+                // es muss leider ein Index angelegt werden. Sonst knallts im
+                // TextNode, weil im DTOR der SwFtn dieser geloescht wird !!
+                SwTxtNode* pTxtNd = (SwTxtNode*)pFtnNd;
+                if( !pHistory )
+                    pHistory = new SwHistory;
+                SwTxtAttr* pFtnHnt = pTxtNd->GetTxtAttr( nFtnSttIdx );
+                ASSERT( pFtnHnt, "kein FtnAttribut" );
+                SwIndex aIdx( pTxtNd, nFtnSttIdx );
+                pHistory->Add( pFtnHnt, pTxtNd->GetIndex(), FALSE );
+                pTxtNd->Erase( aIdx, 1 );
+            }
+
+            while( nPos-- && ( pFtnNd = &( pSrch = rFtnArr[ nPos ] )->
+                    GetTxtNode())->GetIndex() >= pStt->nNode.GetIndex() )
+            {
+                xub_StrLen nFtnSttIdx = *pSrch->GetStart();
+                if( !(DELCNT_CHKNOCNTNT & nDelCntntType) && (
+                    ( &pStt->nNode.GetNode() == pFtnNd &&
+                    pStt->nContent.GetIndex() > nFtnSttIdx ) ||
+                    ( &pEnd->nNode.GetNode() == pFtnNd &&
+                    nFtnSttIdx >= pEnd->nContent.GetIndex() )))
+                    continue;               // weiter suchen
+
+                // es muss leider ein Index angelegt werden. Sonst knallts im
+                // TextNode, weil im DTOR der SwFtn dieser geloescht wird !!
+                SwTxtNode* pTxtNd = (SwTxtNode*)pFtnNd;
+                if( !pHistory )
+                    pHistory = new SwHistory;
+                SwTxtAttr* pFtnHnt = pTxtNd->GetTxtAttr( nFtnSttIdx );
+                ASSERT( pFtnHnt, "kein FtnAttribut" );
+                SwIndex aIdx( pTxtNd, nFtnSttIdx );
+                pHistory->Add( pFtnHnt, pTxtNd->GetIndex(), FALSE );
+                pTxtNd->Erase( aIdx, 1 );
+            }
+        }
+    }
+
+    // 2. Flys
+    if( DELCNT_FLY & nDelCntntType )
+    {
+        USHORT nChainInsPos = pHistory ? pHistory->Count() : 0;
+        const SwSpzFrmFmts& rSpzArr = *pDoc->GetSpzFrmFmts();
+        if( rSpzArr.Count() )
+        {
+            const BOOL bDelFwrd = rMark.nNode.GetIndex() <= rPoint.nNode.GetIndex();
+            SwFlyFrmFmt* pFmt;
+            const SwFmtAnchor* pAnchor;
+            USHORT n = rSpzArr.Count();
+            const SwPosition* pAPos;
+
+            while( n && rSpzArr.Count() )
+            {
+                pFmt = (SwFlyFrmFmt*)rSpzArr[--n];
+                pAnchor = &pFmt->GetAnchor();
+                switch( pAnchor->GetAnchorId() )
+                {
+                case FLY_IN_CNTNT:
+                    if( 0 != (pAPos = pAnchor->GetCntntAnchor() ) &&
+                        (( DELCNT_CHKNOCNTNT & nDelCntntType )
+                        ? ( pStt->nNode <= pAPos->nNode &&
+                            pAPos->nNode < pEnd->nNode )
+                        : ( *pStt <= *pAPos && *pAPos < *pEnd )) )
+                    {
+                        if( !pHistory )
+                            pHistory = new SwHistory;
+                        SwTxtNode* pTxtNd = pDoc->GetNodes()[ pAPos->nNode]->GetTxtNode();
+                        SwTxtAttr* pFlyHnt = pTxtNd->GetTxtAttr( pAPos->nContent.GetIndex());
+                        ASSERT( pFlyHnt, "kein FlyAttribut" );
+                        pHistory->Add( pFlyHnt, 0, FALSE );
+                        // n wieder zurueck, damit nicht ein Format uebesprungen wird !
+                        n = n >= rSpzArr.Count() ? rSpzArr.Count() : n+1;
+                    }
+                    break;
+                case FLY_AT_CNTNT:
+
+                    if( 0 != (pAPos = pAnchor->GetCntntAnchor() ) &&
+                        (( DELCNT_CHKNOCNTNT & nDelCntntType )
+                        ? ( pStt->nNode <= pAPos->nNode &&
+                            pAPos->nNode < pEnd->nNode )
+                        : ( bDelFwrd
+                            ? rMark.nNode < pAPos->nNode &&
+                                        pAPos->nNode <= rPoint.nNode
+                            : rPoint.nNode <= pAPos->nNode &&
+                                        pAPos->nNode < rMark.nNode )) )
+                    {
+                        if( !pHistory )
+                            pHistory = new SwHistory;
+
+                        // nur den Anker verchieben ??
+                        if( !( DELCNT_CHKNOCNTNT & nDelCntntType ) &&
+                            rPoint.nNode.GetIndex() == pAPos->nNode.GetIndex())
+                        {
+                            pHistory->Add( *pFmt );
+
+                            SwFmtAnchor aAnch( *pAnchor );
+                            SwPosition aPos( rMark.nNode );
+                            aAnch.SetAnchor( &aPos );
+                            pFmt->SetAttr( aAnch );
+                        }
+                        else
+                        {
+                            pHistory->Add( *pFmt, nChainInsPos );
+                            // n wieder zurueck, damit nicht ein Format uebesprungen wird !
+                            n = n >= rSpzArr.Count() ? rSpzArr.Count() : n+1;
+                        }
+                    }
+                    break;
+                case FLY_AUTO_CNTNT:
+                    if( 0 != (pAPos = pAnchor->GetCntntAnchor() ) &&
+                        (( DELCNT_CHKNOCNTNT & nDelCntntType )
+                        ? ( pStt->nNode <= pAPos->nNode &&
+                            pAPos->nNode < pEnd->nNode )
+                        : ( *pStt <= *pAPos && *pAPos < *pEnd )) )
+                    {
+                        if( !pHistory )
+                            pHistory = new SwHistory;
+                        if( ( DELCNT_CHKNOCNTNT & nDelCntntType ) ||
+                            ( ( pAPos->nNode < pEnd->nNode ) &&
+                                ( pStt->nNode < pAPos->nNode ||
+                                  !pStt->nContent.GetIndex() ) ) )
+                        {
+                            pHistory->Add( *pFmt, nChainInsPos );
+                            n = n >= rSpzArr.Count() ? rSpzArr.Count() : n+1;
+                        }
+                        else
+                        {
+                            pHistory->Add( *pFmt );
+
+                            SwFmtAnchor aAnch( *pAnchor );
+                            aAnch.SetAnchor( &rMark );
+                            pFmt->SetAttr( aAnch );
+                        }
+                    }
+                    break;
+                case FLY_AT_FLY:
+
+                    if( 0 != (pAPos = pAnchor->GetCntntAnchor() ) &&
+                        pStt->nNode == pAPos->nNode )
+                    {
+                        if( !pHistory )
+                            pHistory = new SwHistory;
+
+                        pHistory->Add( *pFmt, nChainInsPos );
+
+                        // n wieder zurueck, damit nicht ein Format uebesprungen wird !
+                        n = n >= rSpzArr.Count() ? rSpzArr.Count() : n+1;
+                    }
+                    break;
+                }
+            }
+        }
+    }
+
+    // 3. Bookmarks
+    if( DELCNT_BKM & nDelCntntType )
+    {
+        const SwBookmarks& rBkmkTbl = pDoc->GetBookmarks();
+        if( rBkmkTbl.Count() )
+        {
+            const SwBookmark* pBkmk;
+
+            for( USHORT n = 0; n < rBkmkTbl.Count(); ++n )
+            {
+                BYTE nTyp = 0;
+                if( ( DELCNT_CHKNOCNTNT & nDelCntntType )
+                    ? (pStt->nNode <= ( pBkmk = rBkmkTbl[ n ])->GetPos().nNode &&
+                                    pBkmk->GetPos().nNode < pEnd->nNode )
+                    : (*pStt <= ( pBkmk = rBkmkTbl[ n ])->GetPos() &&
+                                    pBkmk->GetPos() < *pEnd ) )
+                    nTyp = SwHstryBookmark::BKMK_POS;
+
+                if( pBkmk->GetOtherPos() &&
+                    (( DELCNT_CHKNOCNTNT & nDelCntntType )
+                    ? (pStt->nNode <= pBkmk->GetOtherPos()->nNode &&
+                        pBkmk->GetOtherPos()->nNode < pEnd->nNode )
+                    : ( *pStt <= *pBkmk->GetOtherPos() &&
+                        *pBkmk->GetOtherPos() < *pEnd )) )
+                    nTyp |= SwHstryBookmark::BKMK_OTHERPOS;
+
+                if( nTyp )
+                {
+                    if( !pHistory )
+                        pHistory = new SwHistory;
+
+                    pHistory->Add( *pBkmk, nTyp );
+                    if( (SwHstryBookmark::BKMK_OTHERPOS|
+                        SwHstryBookmark::BKMK_POS) == nTyp ||
+                        ( SwHstryBookmark::BKMK_POS == nTyp
+                            && !pBkmk->GetOtherPos() ))
+                        pDoc->DelBookmark( n-- );
+                }
+            }
+        }
+    }
+
+    pDoc->DoUndo( bDoesUndo );
+}
+
+
+// sicher eine vollstaendige Section im Undo-Nodes-Array
+
+SwUndoSaveSection::SwUndoSaveSection()
+    : nStartPos( ULONG_MAX ), pMvStt( 0 ), nMvLen( 0 ), pRedlSaveData( 0 )
+{
+}
+
+SwUndoSaveSection::~SwUndoSaveSection()
+{
+    if( pMvStt )        // loesche noch den Bereich aus dem UndoNodes Array
+    {
+        // SaveSection speichert den Inhalt in der PostIt-Section
+        SwNodes& rUNds = pMvStt->GetNode().GetNodes();
+        rUNds.Delete( *pMvStt, nMvLen );
+
+        delete pMvStt;
+    }
+    delete pRedlSaveData;
+}
+
+void SwUndoSaveSection::SaveSection( SwDoc* pDoc, const SwNodeIndex& rSttIdx )
+{
+    SwNodeRange aRg( rSttIdx.GetNode(), *rSttIdx.GetNode().EndOfSectionNode() );
+    SaveSection( pDoc, aRg );
+}
+
+
+void SwUndoSaveSection::SaveSection( SwDoc* pDoc, const SwNodeRange& rRange )
+{
+    SwPaM aPam( rRange.aStart, rRange.aEnd );
+
+    // loesche alle Fussnoten / FlyFrames / Bookmarks / Verzeichnisse
+    DelCntntIndex( *aPam.GetMark(), *aPam.GetPoint() );
+
+    pRedlSaveData = new SwRedlineSaveDatas;
+    if( !SwUndo::FillSaveData( aPam, *pRedlSaveData, TRUE, TRUE ))
+        delete pRedlSaveData, pRedlSaveData = 0;
+
+    nStartPos = rRange.aStart.GetIndex();
+
+    aPam.GetPoint()->nNode--;
+    aPam.GetMark()->nNode++;
+
+    SwCntntNode* pCNd = aPam.GetCntntNode( FALSE );
+    if( pCNd )
+        aPam.GetMark()->nContent.Assign( pCNd, 0 );
+    if( 0 != ( pCNd = aPam.GetCntntNode( TRUE )) )
+        aPam.GetPoint()->nContent.Assign( pCNd, pCNd->Len() );
+
+    // Positionen als SwIndex merken, damit im DTOR dieser Bereich
+    // entfernt werden kann !!
+    ULONG nEnd;
+    pMvStt = new SwNodeIndex( rRange.aStart );
+    MoveToUndoNds( aPam, pMvStt, 0, &nEnd, 0 );
+    nMvLen = nEnd - pMvStt->GetIndex() + 1;
+}
+
+void SwUndoSaveSection::RestoreSection( SwDoc* pDoc, SwNodeIndex* pIdx,
+                                        USHORT nSectType )
+{
+    if( ULONG_MAX != nStartPos )        // gab es ueberhaupt Inhalt ?
+    {
+        // ueberpruefe, ob der Inhalt an der alten Position steht
+        SwNodeIndex aSttIdx( pDoc->GetNodes(), nStartPos );
+        ASSERT( !pDoc->GetNodes()[ aSttIdx ]->GetCntntNode(),
+                "Position in irgendeiner Section" );
+
+        // move den Inhalt aus dem UndoNodes-Array in den Fly
+        SwStartNode* pSttNd = pDoc->GetNodes().MakeEmptySection( aSttIdx,
+                                                (SwStartNodeType)nSectType );
+
+        RestoreSection( pDoc, SwNodeIndex( *pSttNd->EndOfSectionNode() ));
+
+        if( pIdx )
+            *pIdx = *pSttNd;
+    }
+}
+
+void SwUndoSaveSection::RestoreSection( SwDoc* pDoc, const SwNodeIndex& rInsPos )
+{
+    if( ULONG_MAX != nStartPos )        // gab es ueberhaupt Inhalt ?
+    {
+        SwPosition aInsPos( rInsPos );
+        ULONG nEnd = pMvStt->GetIndex() + nMvLen - 1;
+        MoveFromUndoNds( *pDoc, pMvStt->GetIndex(), 0, aInsPos, &nEnd, 0 );
+
+        // Indizies wieder zerstoren, Inhalt ist aus dem UndoNodes-Array
+        // entfernt worden.
+        DELETEZ( pMvStt );
+        nMvLen = 0;
+
+        if( pRedlSaveData )
+        {
+            SwUndo::SetSaveData( *pDoc, *pRedlSaveData );
+            delete pRedlSaveData, pRedlSaveData = 0;
+        }
+    }
+}
+
+
+// START
+SwUndoStart::SwUndoStart( USHORT nId )
+    : SwUndo( UNDO_START ), nUserId( nId ), nEndOffset( 0 )
+{
+}
+
+void SwUndoStart::Undo( SwUndoIter& rUndoIter )
+{
+    if( !( --rUndoIter.nEndCnt ) && rUndoIter.bWeiter &&
+        ( rUndoIter.GetId() ? ( rUndoIter.GetId() == nUserId ||
+        ( UNDO_END == rUndoIter.GetId() && UNDO_START == GetId() )) : TRUE ))
+        rUndoIter.bWeiter = FALSE;
+}
+
+void SwUndoStart::Redo( SwUndoIter& rUndoIter )
+{
+    rUndoIter.bWeiter = TRUE;
+    ++rUndoIter.nEndCnt;
+}
+
+void SwUndoStart::Repeat( SwUndoIter& rUndoIter )
+{
+    rUndoIter.bWeiter = FALSE;
+}
+
+
+// END
+SwUndoEnd::SwUndoEnd( USHORT nId )
+    : SwUndo( UNDO_END ), nUserId( nId ), nSttOffset( 0 )
+{
+}
+
+void SwUndoEnd::Undo( SwUndoIter& rUndoIter )
+{
+    if( rUndoIter.GetId() == GetId() || !rUndoIter.GetId() )
+        rUndoIter.bWeiter = TRUE;
+    if( rUndoIter.bWeiter )
+        ++rUndoIter.nEndCnt;
+}
+
+void SwUndoEnd::Redo( SwUndoIter& rUndoIter )
+{
+    if( !( --rUndoIter.nEndCnt ) && rUndoIter.bWeiter &&
+        ( rUndoIter.GetId() ? ( rUndoIter.GetId() == nUserId ||
+        ( UNDO_END == rUndoIter.GetId() && UNDO_START == GetId() )) : TRUE ))
+        rUndoIter.bWeiter = FALSE;
+}
+
+void SwUndoEnd::Repeat( SwUndoIter& rUndoIter )
+{
+    rUndoIter.bWeiter = FALSE;
+}
+
+/*  */
+        // sicher und setze die RedlineDaten
+
+SwRedlineSaveData::SwRedlineSaveData( SwComparePosition eCmpPos,
+                                        const SwPosition& rSttPos,
+                                        const SwPosition& rEndPos,
+                                        SwRedline& rRedl,
+                                        BOOL bCopyNext )
+    : SwUndRng( rRedl ),
+    SwRedlineData( rRedl.GetRedlineData(), bCopyNext )
+{
+    ASSERT( POS_OUTSIDE == eCmpPos ||
+            !rRedl.GetContentIdx(), "Redline mit Content" );
+
+    switch( eCmpPos )
+    {
+    case POS_OVERLAP_BEFORE:        // Pos1 ueberlappt Pos2 am Anfang
+        nEndNode = rEndPos.nNode.GetIndex();
+        nEndCntnt = rEndPos.nContent.GetIndex();
+        break;
+    case POS_OVERLAP_BEHIND:        // Pos1 ueberlappt Pos2 am Ende
+        nSttNode = rSttPos.nNode.GetIndex();
+        nSttCntnt = rSttPos.nContent.GetIndex();
+        break;
+
+    case POS_INSIDE:                // Pos1 liegt vollstaendig in Pos2
+        nSttNode = rSttPos.nNode.GetIndex();
+        nSttCntnt = rSttPos.nContent.GetIndex();
+        nEndNode = rEndPos.nNode.GetIndex();
+        nEndCntnt = rEndPos.nContent.GetIndex();
+        break;
+
+    case POS_OUTSIDE:               // Pos2 liegt vollstaendig in Pos1
+        if( rRedl.GetContentIdx() )
+        {
+            // dann den Bereich ins UndoArray verschieben und merken
+            SaveSection( rRedl.GetDoc(), *rRedl.GetContentIdx() );
+            rRedl.SetContentIdx( 0 );
+        }
+        break;
+
+    case POS_EQUAL:                 // Pos1 ist genauso gross wie Pos2
+        break;
+
+    default:
+        ASSERT( !this, "keine gueltigen Daten!" )
+    }
+}
+
+SwRedlineSaveData::~SwRedlineSaveData()
+{
+}
+
+void SwRedlineSaveData::RedlineToDoc( SwPaM& rPam )
+{
+    SwDoc& rDoc = *rPam.GetDoc();
+    SwRedline* pRedl = new SwRedline( *this, rPam );
+
+    if( GetMvSttIdx() )
+    {
+        SwNodeIndex aIdx( rDoc.GetNodes() );
+        RestoreSection( &rDoc, &aIdx, SwNormalStartNode );
+        if( GetHistory() )
+            GetHistory()->Rollback( &rDoc );
+        pRedl->SetContentIdx( &aIdx );
+    }
+    SetPaM( *pRedl );
+    // erstmal die "alten" entfernen, damit im Append keine unerwarteten
+    // Dinge passieren, wie z.B. eine Delete in eigenen Insert. Dann wird
+    // naehmlich das gerade restaurierte wieder geloescht - nicht das gewollte
+    rDoc.DeleteRedline( *pRedl, FALSE );
+    rDoc.AppendRedline( pRedl );
+}
+
+BOOL SwUndo::FillSaveData( const SwPaM& rRange, SwRedlineSaveDatas& rSData,
+                            BOOL bDelRange, BOOL bCopyNext )
+{
+    if( rSData.Count() )
+        rSData.DeleteAndDestroy( 0, rSData.Count() );
+
+    SwRedlineSaveData* pNewData;
+    const SwPosition *pStt = rRange.Start(), *pEnd = rRange.End();
+    const SwRedlineTbl& rTbl = rRange.GetDoc()->GetRedlineTbl();
+    USHORT n = 0;
+    rRange.GetDoc()->GetRedline( *pStt, &n );
+    for( ; n < rTbl.Count(); ++n )
+    {
+        SwRedline* pRedl = rTbl[ n ];
+        const SwPosition *pRStt = pRedl->Start(), *pREnd = pRedl->End();
+
+        SwComparePosition eCmpPos = ComparePosition( *pStt, *pEnd, *pRStt, *pREnd );
+        if( POS_BEFORE != eCmpPos && POS_BEHIND != eCmpPos )
+        {
+            pNewData = new SwRedlineSaveData( eCmpPos, *pStt, *pEnd,
+                                                *pRedl, bCopyNext );
+            rSData.Insert( pNewData, rSData.Count() );
+        }
+    }
+    if( rSData.Count() && bDelRange )
+        rRange.GetDoc()->DeleteRedline( rRange, FALSE );
+    return 0 != rSData.Count();
+}
+
+BOOL SwUndo::FillSaveDataForFmt( const SwPaM& rRange, SwRedlineSaveDatas& rSData )
+{
+    if( rSData.Count() )
+        rSData.DeleteAndDestroy( 0, rSData.Count() );
+
+    SwRedlineSaveData* pNewData;
+    const SwPosition *pStt = rRange.Start(), *pEnd = rRange.End();
+    const SwRedlineTbl& rTbl = rRange.GetDoc()->GetRedlineTbl();
+    USHORT n = 0;
+    rRange.GetDoc()->GetRedline( *pStt, &n );
+    for( ; n < rTbl.Count(); ++n )
+    {
+        SwRedline* pRedl = rTbl[ n ];
+        if( REDLINE_FORMAT == pRedl->GetType() )
+        {
+            const SwPosition *pRStt = pRedl->Start(), *pREnd = pRedl->End();
+
+            SwComparePosition eCmpPos = ComparePosition( *pStt, *pEnd, *pRStt, *pREnd );
+            if( POS_BEFORE != eCmpPos && POS_BEHIND != eCmpPos )
+            {
+                pNewData = new SwRedlineSaveData( eCmpPos, *pStt, *pEnd,
+                                                    *pRedl, TRUE );
+                rSData.Insert( pNewData, rSData.Count() );
+            }
+        }
+    }
+    return 0 != rSData.Count();
+}
+
+void SwUndo::SetSaveData( SwDoc& rDoc, const SwRedlineSaveDatas& rSData )
+{
+    SwRedlineMode eOld = rDoc.GetRedlineMode();
+    rDoc.SetRedlineMode_intern( ( eOld & ~REDLINE_IGNORE) | REDLINE_ON );
+    SwPaM aPam( rDoc.GetNodes().GetEndOfContent() );
+    for( USHORT n = rSData.Count(); n; )
+        rSData[ --n ]->RedlineToDoc( aPam );
+    rDoc.SetRedlineMode_intern( eOld );
+}
+
+BOOL SwUndo::HasHiddenRedlines( const SwRedlineSaveDatas& rSData )
+{
+    for( USHORT n = rSData.Count(); n; )
+        if( rSData[ --n ]->GetMvSttIdx() )
+            return TRUE;
+    return FALSE;
+}
+
+BOOL SwUndo::CanRedlineGroup( SwRedlineSaveDatas& rCurr,
+                        const SwRedlineSaveDatas& rCheck, BOOL bCurrIsEnd )
+{
+    BOOL bRet = FALSE;
+    if( rCurr.Count() == rCheck.Count() )
+    {
+        bRet = TRUE;
+        for( USHORT n = 0; n < rCurr.Count(); ++n )
+        {
+            const SwRedlineSaveData& rSet = *rCurr[ n ];
+            const SwRedlineSaveData& rGet = *rCheck[ n ];
+            if( rSet.nSttNode != rGet.nSttNode ||
+                rSet.GetMvSttIdx() || rGet.GetMvSttIdx() ||
+                ( bCurrIsEnd ? rSet.nSttCntnt != rGet.nEndCntnt
+                             : rSet.nEndCntnt != rGet.nSttCntnt ) ||
+                !rGet.CanCombine( rSet ) )
+            {
+                bRet = FALSE;
+                break;
+            }
+        }
+
+        if( bRet )
+            for( n = 0; n < rCurr.Count(); ++n )
+            {
+                SwRedlineSaveData& rSet = *rCurr[ n ];
+                const SwRedlineSaveData& rGet = *rCheck[ n ];
+                if( bCurrIsEnd )
+                    rSet.nSttCntnt = rGet.nSttCntnt;
+                else
+                    rSet.nEndCntnt = rGet.nEndCntnt;
+            }
+    }
+    return bRet;
+}
+
+/*************************************************************************
+
+   Source Code Control System - Header
+
+   $Header: /zpool/svn/migration/cvs_rep_09_09_08/code/sw/source/core/undo/undobj.cxx,v 1.1.1.1 2000-09-19 00:08:27 hr Exp $
+
+   Source Code Control System - Update
+
+   $Log: not supported by cvs2svn $
+   Revision 1.201  2000/09/18 16:04:29  willem.vandorp
+   OpenOffice header added.
+
+   Revision 1.200  2000/05/09 10:04:02  jp
+   Changes for Unicode
+
+   Revision 1.199  1999/07/27 18:24:30  JP
+   replace class SwTOXBaseRange with SwTOXBaseSection - TOX use now SwSections
+
+
+      Rev 1.198   27 Jul 1999 20:24:30   JP
+   replace class SwTOXBaseRange with SwTOXBaseSection - TOX use now SwSections
+
+      Rev 1.197   07 Jul 1999 16:16:54   JP
+   Bug #57068#: now we handle the seleection of SdrObjects after undo/redo ourselves
+
+      Rev 1.196   28 Jul 1998 13:00:42   JP
+   Bug #53951#: Redlines am Anfang vom Node Copy/Move Bereich sonderbehandeln
+
+      Rev 1.195   12 May 1998 15:47:12   JP
+   SwUndoIter: pSelFmt besagt, welcher Fly selektiert werden soll
+
+      Rev 1.194   06 May 1998 21:34:14   JP
+   MoveTo-/-FromUndoNodes: auch mit !CntntNodes klar kommen
+
+      Rev 1.193   26 Mar 1998 21:50:22   JP
+   RedlineToDoc: bevor ueber den Bereich das Redline gesetzt wird muss er von solchen befreit werden
+
+      Rev 1.192   24 Mar 1998 20:54:14   JP
+   neu: Redlining fuer harte Attributierung
+
+      Rev 1.191   20 Mar 1998 14:54:14   JP
+   Bug #48632# MoveFromUndoNds - Trener nur loeschen, wenn dieser vorhanen ist
+
+      Rev 1.190   27 Feb 1998 09:23:22   JP
+   PaMCorrAbs/Rel: statt der EditShell jetzt das Doc uebergeben
+
+      Rev 1.189   16 Feb 1998 12:41:18   HR
+   C40_INSERT
+
+      Rev 1.188   16 Feb 1998 12:34:00   JP
+   Umstellung fuer Solaric-Compiler
+
+      Rev 1.187   09 Feb 1998 21:02:50   JP
+   Save/RestoreSection auch mit einem NodeRange
+
+      Rev 1.186   03 Feb 1998 13:15:34   TJ
+   header
+
+      Rev 1.185   30 Jan 1998 19:33:56   JP
+   RedlineToDoc: SetPam erst nach dem restaurieren der versteckten Redl. rufen
+
+      Rev 1.184   29 Jan 1998 22:52:06   JP
+   FillSaveData: auch hidden Redlines sichern, rekursionen durch Flys/Ftn beachten
+
+      Rev 1.183   22 Jan 1998 20:53:10   JP
+   CTOR des SwPaM umgestellt
+
+      Rev 1.182   16 Jan 1998 12:00:00   JP
+   SwUndo: Methode Remove entfernt, FillRedlineData: DeleteRedline darf kein UndoObject erzeugen
+
+      Rev 1.181   13 Jan 1998 21:37:40   JP
+   FillSaveData: RedlineData nicht immer tief kopieren
+
+      Rev 1.180   08 Jan 1998 21:08:40   JP
+   SwDoc::GetRedlineTbl returnt jetzt eine Referenz
+
+      Rev 1.179   06 Jan 1998 16:27:06   JP
+   neu: CanRedlineGroup - Gruppierung fuers Redlining
+
+      Rev 1.178   19 Dec 1997 18:06:56   JP
+   neu: sichern/setzen von SwRedlines
+
+      Rev 1.177   19 Dec 1997 12:15:34   JP
+   MSG/NOTE entfernt
+
+      Rev 1.176   20 Nov 1997 18:37:48   MA
+   includes
+
+      Rev 1.175   18 Nov 1997 16:36:04   JP
+   Move..: Trenner nur einfuegen, wenn TeilNodes verschoben werden
+
+      Rev 1.174   17 Nov 1997 18:06:42   JP
+   SwFmtChain Attribut ins Undo aufnehmen
+
+      Rev 1.173   14 Nov 1997 16:39:16   AMA
+   Fix: Autopos. Rahmen nur loeschen, wenn ihr gesamter Absatz selektiert ist
+
+      Rev 1.172   03 Nov 1997 13:06:10   MA
+   precomp entfernt
+
+      Rev 1.171   13 Oct 1997 15:54:16   JP
+   pNext vom Ring wurde privat; zugriff ueber GetNext()
+
+      Rev 1.170   09 Oct 1997 15:45:52   JP
+   Umstellung NodeIndex/-Array/BigPtrArray
+
+      Rev 1.169   11 Sep 1997 19:40:02   JP
+   DelCntntIdx: richtig klammern
+
+      Rev 1.168   10 Sep 1997 10:42:44   JP
+   DelCntntType: neuer Typ - ggfs. nur auf Nodegrenze abpruefen
+
+      Rev 1.167   03 Sep 1997 10:29:22   JP
+   zusaetzliches include von docary
+
+      Rev 1.166   18 Aug 1997 10:34:54   OS
+   includes
+
+      Rev 1.165   15 Aug 1997 12:38:26   OS
+   charatr/frmatr/txtatr aufgeteilt
+
+      Rev 1.164   11 Jun 1997 10:43:46   JP
+   pure virtual Repeat wurde zur virtual Methode, Segment Pragma entfernt
+
+      Rev 1.163   29 May 1997 22:56:30   JP
+   CopyAttr/CopyFmtAttr von SwUndo zur SwHistory verschoben
+
+      Rev 1.162   15 Apr 1997 14:51:46   AMA
+   New: Rahmengebundene Rahmen und auto.positionierte Rahmen
+
+      Rev 1.161   19 Dec 1996 15:16:30   AMA
+   Fix: Auch beim Redo muss das UpdateAttr gepflegt werden
+
+      Rev 1.160   29 Oct 1996 14:53:28   JP
+   am Doc ist das NodesArray nur noch ueber Get..() zugaenglich
+
+      Rev 1.159   29 Aug 1996 10:09:28   JP
+   beim StartNode muss jetzt ein spz. Sectiontype gesetzt werden
+
+      Rev 1.158   30 Apr 1996 15:28:54   JP
+   Bug #27489#: CopyFmtAttr - fuers Undo kein Clone rufen!
+
+      Rev 1.157   22 Mar 1996 14:27:32   SWG
+   include hinzugefuegt
+
+      Rev 1.156   26 Feb 1996 20:52:42   JP
+   Bug #25662#: gesamten Bereich verschieben
+
+      Rev 1.155   12 Jan 1996 16:55:06   JP
+   SwUndoRng: Selection wiederherstellen
+
+      Rev 1.154   24 Nov 1995 17:13:58   OM
+   PCH->PRECOMPILED
+
+      Rev 1.153   07 Nov 1995 07:33:22   OS
+   DTOR hat keinen return type
+
+      Rev 1.152   06 Nov 1995 13:44:22   JP
+   virtuelle Methoden DTOR, Remove implementiert
+
+      Rev 1.151   01 Nov 1995 09:13:16   MA
+   opt: String
+
+      Rev 1.150   26 Sep 1995 18:55:18   JP
+   DelCntntIdx: speicher auch Fly-Anker Veraenderungen
+
+      Rev 1.149   31 Aug 1995 15:05:42   JP
+   extern def. von GoInCntnt entfernt
+
+      Rev 1.148   28 Jul 1995 14:08:44   JP
+   DelCntIdx: Bookmarks auch loeschen, wenn sie nur eine Position haben
+
+      Rev 1.147   24 Jun 1995 18:54:02   JP
+   RemoveIdxRel: verschiebt nur dir Crsrs
+
+      Rev 1.146   22 Jun 1995 19:33:26   JP
+   virt. Methode GetUndoRange vernichtet, Objecte rufen jetzt die Basis-Klasse
+
+      Rev 1.145   23 Feb 1995 23:02:02   ER
+   sexport
+
+      Rev 1.144   08 Feb 1995 23:52:46   ER
+   undo.hxx -> swundo.hxx wegen solar undo.hxx
+
+      Rev 1.143   07 Feb 1995 00:07:24   ER
+   add: frmatr.hxx
+
+      Rev 1.142   15 Dec 1994 20:47:30   SWG
+   *ARR* Ersetzungen, svmem, __far_data etc.
+
+      Rev 1.141   28 Oct 1994 19:19:24   MA
+   Reimport frmatr.
+
+      Rev 1.140   25 Oct 1994 14:50:42   MA
+   PreHdr.
+
+      Rev 1.139   07 Sep 1994 17:29:34   SWG
+   Umstellung Attribute
+
+      Rev 1.138   25 Aug 1994 18:05:56   JP
+   Umstellung Attribute (von SwHint -> SfxPoolItem)
+
+      Rev 1.137   04 Aug 1994 13:30:44   SWG
+   swg32: SED Size to SSize, LSize to Size etc.
+
+      Rev 1.136   29 Jul 1994 08:18:04   SWG
+   Update: const Attr-Pointer fuer lokolen Pointer.
+
+*************************************************************************/
+
diff --git a/sw/source/core/undo/undobj1.cxx b/sw/source/core/undo/undobj1.cxx
new file mode 100644
index 000000000000..a51d4dedff77
--- /dev/null
+++ b/sw/source/core/undo/undobj1.cxx
@@ -0,0 +1,778 @@
+/*************************************************************************
+ *
+ *  $RCSfile: undobj1.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:27 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _SFXITEMITER_HXX //autogen
+#include 
+#endif
+
+#ifndef _FMTFLCNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _FMTCNTNT_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFLCNT_HXX //autogen
+#include 
+#endif
+#ifndef _FRMFMT_HXX //autogen
+#include 
+#endif
+#ifndef _FLYFRM_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFLCNT_HXX //autogen
+#include 
+#endif
+#ifndef _UNDOBJ_HXX
+#include 
+#endif
+#ifndef _ROLBCK_HXX
+#include        // fuer die Attribut History
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _ROOTFRM_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include            // fuer die UndoIds
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _HINTS_HXX
+#include 
+#endif
+
+// Inline Methode vom UndoIter
+inline SwDoc& SwUndoIter::GetDoc() const { return *pAktPam->GetDoc(); }
+
+//---------------------------------------------------------------------
+
+SwUndoFlyBase::SwUndoFlyBase( SwFrmFmt* pFormat, USHORT nUndoId )
+    : SwUndo( nUndoId ), pFrmFmt( pFormat )
+{
+#ifdef COMPACT
+    pFormat->GetDoc()->DelUndoGroups();
+#endif
+}
+
+SwUndoFlyBase::~SwUndoFlyBase()
+{
+    if( bDelFmt )       // loeschen waehrend eines Undo's ??
+        delete pFrmFmt;
+}
+
+void SwUndoFlyBase::InsFly( SwUndoIter& rUndoIter, BOOL bShowSelFrm )
+{
+    SwDoc* pDoc = &rUndoIter.GetDoc();
+
+    // ins Array wieder eintragen
+    SwSpzFrmFmts& rFlyFmts = *(SwSpzFrmFmts*)pDoc->GetSpzFrmFmts();
+    rFlyFmts.Insert( pFrmFmt, rFlyFmts.Count() );
+    SwFmtAnchor aAnchor( (RndStdIds)nRndId );
+
+    if( FLY_PAGE == nRndId )
+        aAnchor.SetPageNum( (USHORT)nNdPgPos );
+    else
+    {
+        SwPosition aNewPos( *rUndoIter.pAktPam->GetPoint() );
+        aNewPos.nNode = nNdPgPos;
+        if( FLY_IN_CNTNT == nRndId || FLY_AUTO_CNTNT == nRndId )
+            aNewPos.nContent.Assign( aNewPos.nNode.GetNode().GetCntntNode(),
+                                    nCntPos );
+        aAnchor.SetAnchor( &aNewPos );
+    }
+
+    pFrmFmt->SetAttr( aAnchor );        // Anker neu setzen
+
+    if( RES_DRAWFRMFMT != pFrmFmt->Which() )
+    {
+        // Content holen und -Attribut neu setzen
+        SwNodeIndex aIdx( pDoc->GetNodes() );
+        RestoreSection( pDoc, &aIdx, SwFlyStartNode );
+        pFrmFmt->SetAttr( SwFmtCntnt( aIdx.GetNode().GetStartNode() ));
+    }
+
+    //JP 18.12.98: Bug 60505 - InCntntAttribut erst setzen, wenn der Inhalt
+    //              vorhanden ist! Sonst wuerde das Layout den Fly vorher
+    //              formatieren, aber keine Inhalt finden; so geschene bei
+    //              Grafiken aus dem Internet
+    if( FLY_IN_CNTNT == nRndId )
+    {
+        // es muss mindestens das Attribut im TextNode stehen
+        SwCntntNode* pCNd = aAnchor.GetCntntAnchor()->nNode.GetNode().GetCntntNode();
+        ASSERT( pCNd->IsTxtNode(), "Kein Textnode an dieser Position" );
+        ((SwTxtNode*)pCNd)->Insert( SwFmtFlyCnt(
+                                (SwFlyFrmFmt*)pFrmFmt ), nCntPos, nCntPos );
+    }
+
+    pFrmFmt->MakeFrms();
+
+    if( bShowSelFrm )
+        rUndoIter.pSelFmt = pFrmFmt;
+
+    if( GetHistory() )
+        GetHistory()->Rollback( pDoc );
+
+    switch( nRndId )
+    {
+    case FLY_IN_CNTNT:
+    case FLY_AUTO_CNTNT:
+        {
+            const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor();
+            nNdPgPos = rAnchor.GetCntntAnchor()->nNode.GetIndex();
+            nCntPos = rAnchor.GetCntntAnchor()->nContent.GetIndex();
+        }
+        break;
+    case FLY_AT_CNTNT:
+    case FLY_AT_FLY:
+        {
+            const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor();
+            nNdPgPos = rAnchor.GetCntntAnchor()->nNode.GetIndex();
+        }
+        break;
+    case FLY_PAGE:
+        break;
+    }
+    bDelFmt =  FALSE;
+}
+
+void SwUndoFlyBase::DelFly( SwDoc* pDoc )
+{
+    bDelFmt = TRUE;                     // im DTOR das Format loeschen
+    pFrmFmt->DelFrms();                 // Frms vernichten.
+
+    // alle Uno-Objecte sollten sich jetzt abmelden
+    {
+        SwPtrMsgPoolItem aMsgHint( RES_REMOVE_UNO_OBJECT, pFrmFmt );
+        pFrmFmt->Modify( &aMsgHint, &aMsgHint );
+    }
+
+    if ( RES_DRAWFRMFMT != pFrmFmt->Which() )
+    {
+        // gibt es ueberhaupt Inhalt, dann sicher diesen
+        const SwFmtCntnt& rCntnt = pFrmFmt->GetCntnt();
+        ASSERT( rCntnt.GetCntntIdx(), "Fly ohne Inhalt" );
+
+        SaveSection( pDoc, *rCntnt.GetCntntIdx() );
+        ((SwFmtCntnt&)rCntnt).SetNewCntntIdx( (const SwNodeIndex*)0 );
+    }
+
+    const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor();
+    const SwPosition* pPos = rAnchor.GetCntntAnchor();
+    // die Positionen im Nodes-Array haben sich verschoben
+    if( FLY_IN_CNTNT == ( nRndId = rAnchor.GetAnchorId() ) )
+    {
+        nNdPgPos = pPos->nNode.GetIndex();
+        nCntPos = pPos->nContent.GetIndex();
+        SwTxtNode *pTxtNd = pDoc->GetNodes()[ pPos->nNode ]->GetTxtNode();
+        ASSERT( pTxtNd, "Kein Textnode gefunden" );
+        SwTxtFlyCnt* pAttr = (SwTxtFlyCnt*)pTxtNd->GetTxtAttr( nCntPos );
+        // Attribut steht noch im TextNode, loeschen
+        if( pAttr && pAttr->GetFlyCnt().GetFrmFmt() == pFrmFmt )
+        {
+            // Pointer auf 0, nicht loeschen
+            ((SwFmtFlyCnt&)pAttr->GetFlyCnt()).SetFlyFmt();
+            SwIndex aIdx( pPos->nContent );
+            pTxtNd->Erase( aIdx, 1 );
+        }
+    }
+    else if( FLY_AUTO_CNTNT == nRndId )
+    {
+        nNdPgPos = pPos->nNode.GetIndex();
+        nCntPos = pPos->nContent.GetIndex();
+    }
+    else if( FLY_AT_CNTNT == nRndId || FLY_AT_FLY == nRndId )
+        nNdPgPos = pPos->nNode.GetIndex();
+    else
+        nNdPgPos = rAnchor.GetPageNum();
+
+    pFrmFmt->ResetAttr( RES_ANCHOR );       // Anchor loeschen
+
+
+    // aus dem Array austragen
+    SwSpzFrmFmts& rFlyFmts = *(SwSpzFrmFmts*)pDoc->GetSpzFrmFmts();
+    rFlyFmts.Remove( rFlyFmts.GetPos( pFrmFmt ));
+}
+
+// ----- Undo-InsertFly ------
+
+SwUndoInsLayFmt::SwUndoInsLayFmt( SwFrmFmt* pFormat )
+    : SwUndoFlyBase( pFormat,
+            RES_DRAWFRMFMT == pFormat->Which() ? UNDO_INSDRAWFMT : UNDO_INSLAYFMT )
+{
+    const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor();
+    nRndId = rAnchor.GetAnchorId();
+    bDelFmt = FALSE;
+    switch( nRndId )
+    {
+    case FLY_PAGE:
+        nNdPgPos = rAnchor.GetPageNum();
+        break;
+    case FLY_AT_CNTNT:
+    case FLY_AT_FLY:
+        nNdPgPos = rAnchor.GetCntntAnchor()->nNode.GetIndex();
+        break;
+    case FLY_IN_CNTNT:
+    case FLY_AUTO_CNTNT:
+        {
+            const SwPosition* pPos = rAnchor.GetCntntAnchor();
+            nCntPos = pPos->nContent.GetIndex();
+            nNdPgPos = pPos->nNode.GetIndex();
+        }
+        break;
+    default:
+        ASSERT( FALSE, "Was denn fuer ein FlyFrame?" );
+    }
+}
+
+void SwUndoInsLayFmt::Undo( SwUndoIter& rUndoIter )
+{
+    const SwFmtCntnt& rCntnt = pFrmFmt->GetCntnt();
+    if( rCntnt.GetCntntIdx() )  // kein Inhalt
+        RemoveIdxFromSection( rUndoIter.GetDoc(),
+                                rCntnt.GetCntntIdx()->GetIndex() );
+
+    DelFly( &rUndoIter.GetDoc() );
+}
+
+void SwUndoInsLayFmt::Redo( SwUndoIter& rUndoIter )
+{
+    rUndoIter.pLastUndoObj = 0;
+    InsFly( rUndoIter );
+}
+
+void SwUndoInsLayFmt::Repeat( SwUndoIter& rUndoIter )
+{
+    if( UNDO_INSLAYFMT == rUndoIter.GetLastUndoId() &&
+        pFrmFmt == ((SwUndoInsLayFmt*)rUndoIter.pLastUndoObj)->pFrmFmt )
+        return;
+
+    SwDoc* pDoc = &rUndoIter.GetDoc();
+    // erfrage und setze den Anker neu
+    SwFmtAnchor aAnchor( pFrmFmt->GetAnchor() );
+    if( FLY_AT_CNTNT == aAnchor.GetAnchorId() ||
+        FLY_AUTO_CNTNT == aAnchor.GetAnchorId() ||
+        FLY_IN_CNTNT == aAnchor.GetAnchorId() )
+    {
+        SwPosition aPos( *rUndoIter.pAktPam->GetPoint() );
+        if( FLY_AT_CNTNT == aAnchor.GetAnchorId() )
+            aPos.nContent.Assign( 0, 0 );
+        aAnchor.SetAnchor( &aPos );
+    }
+    else if( FLY_AT_FLY == aAnchor.GetAnchorId() )
+    {
+        const SwStartNode* pSttNd = rUndoIter.pAktPam->GetNode()->FindFlyStartNode();
+        if( pSttNd )
+        {
+            SwPosition aPos( *pSttNd );
+            aAnchor.SetAnchor( &aPos );
+        }
+        else
+        {
+            rUndoIter.pLastUndoObj = this;
+            return ;
+        }
+    }
+    else if( FLY_PAGE == aAnchor.GetAnchorId() )
+    {
+        aAnchor.SetPageNum( pDoc->GetRootFrm()->GetCurrPage(
+                                        rUndoIter.pAktPam ));
+    }
+    else
+        ASSERT( FALSE, "was fuer ein Anker ist es denn nun?" );
+
+    SwFrmFmt* pFlyFmt = pDoc->CopyLayoutFmt( *pFrmFmt, aAnchor );
+    rUndoIter.pSelFmt = pFlyFmt;
+
+    rUndoIter.pLastUndoObj = this;
+}
+
+// ----- Undo-DeleteFly ------
+
+SwUndoDelLayFmt::SwUndoDelLayFmt( SwFrmFmt* pFormat )
+    : SwUndoFlyBase( pFormat, UNDO_DELLAYFMT ), bShowSelFrm( TRUE )
+{
+    SwDoc* pDoc = pFormat->GetDoc();
+    DelFly( pDoc );
+
+    SwNodeIndex* pIdx = GetMvSttIdx();
+    SwNode* pNd;
+    if( 1 == GetMvNodeCnt() && pIdx &&
+        ( pNd = (*pDoc->GetUndoNds())[ *pIdx ] )->IsNoTxtNode() )
+    {
+        // dann setze eine andere Undo-ID; Grafik oder OLE
+        if( pNd->IsGrfNode() )
+            SetId( UNDO_DELGRF );
+        else if( pNd->IsOLENode() )
+            SetId( UNDO_DELOLE );
+    }
+}
+
+void SwUndoDelLayFmt::Undo( SwUndoIter& rUndoIter )
+{
+    InsFly( rUndoIter, bShowSelFrm );
+}
+
+void SwUndoDelLayFmt::Redo( SwUndoIter& rUndoIter )
+{
+    const SwFmtCntnt& rCntnt = pFrmFmt->GetCntnt();
+    if( rCntnt.GetCntntIdx() )  // kein Inhalt
+        RemoveIdxFromSection( rUndoIter.GetDoc(),
+                                rCntnt.GetCntntIdx()->GetIndex() );
+
+    DelFly( &rUndoIter.GetDoc() );
+}
+
+void SwUndoDelLayFmt::Redo()
+{
+    const SwFmtCntnt& rCntnt = pFrmFmt->GetCntnt();
+    if( rCntnt.GetCntntIdx() )  // kein Inhalt
+        RemoveIdxFromSection( *pFrmFmt->GetDoc(),
+                                rCntnt.GetCntntIdx()->GetIndex() );
+
+    DelFly( pFrmFmt->GetDoc() );
+}
+
+/*  */
+
+SwUndoSetFlyFmt::SwUndoSetFlyFmt( SwFrmFmt& rFlyFmt, SwFrmFmt& rNewFrmFmt )
+    : SwUndo( UNDO_SETFLYFRMFMT ), SwClient( &rFlyFmt ), pFrmFmt( &rFlyFmt ),
+    pNewFmt( &rNewFrmFmt ), pOldFmt( (SwFrmFmt*)rFlyFmt.DerivedFrom() ),
+    pItemSet( new SfxItemSet( *rFlyFmt.GetAttrSet().GetPool(),
+                                rFlyFmt.GetAttrSet().GetRanges() )),
+    nOldNode( 0 ), nOldCntnt( 0 ), nOldAnchorTyp( 0 ),
+    nNewNode( 0 ), nNewCntnt( 0 ), nNewAnchorTyp( 0 ), bAnchorChgd( FALSE )
+{
+}
+
+SwUndoSetFlyFmt::~SwUndoSetFlyFmt()
+{
+    delete pItemSet;
+}
+
+void SwUndoSetFlyFmt::GetAnchor( SwFmtAnchor& rAnchor,
+                                ULONG nNode, xub_StrLen nCntnt )
+{
+    RndStdIds nAnchorTyp = rAnchor.GetAnchorId();
+    if( FLY_PAGE != nAnchorTyp )
+    {
+        SwNode* pNd = pFrmFmt->GetDoc()->GetNodes()[ nNode ];
+
+        if( FLY_AT_FLY == nAnchorTyp
+                ? ( !pNd->IsStartNode() || SwFlyStartNode !=
+                    ((SwStartNode*)pNd)->GetStartNodeType() )
+                : !pNd->IsTxtNode() )
+            pNd = 0;                // ungueltige Position
+        else
+        {
+            SwPosition aPos( *pNd );
+            if( FLY_IN_CNTNT == nAnchorTyp ||
+                FLY_AUTO_CNTNT == nAnchorTyp )
+            {
+                if( nCntnt > ((SwTxtNode*)pNd)->GetTxt().Len() )
+                    pNd = 0;        // ungueltige Position
+                else
+                    aPos.nContent.Assign( (SwTxtNode*)pNd, nCntnt );
+            }
+            if( pNd )
+                rAnchor.SetAnchor( &aPos );
+        }
+
+        if( !pNd )
+        {
+            // ungueltige Position - setze auf 1. Seite
+            rAnchor.SetType( FLY_PAGE );
+            rAnchor.SetPageNum( 1 );
+        }
+    }
+    else
+        rAnchor.SetPageNum( nCntnt );
+}
+
+void SwUndoSetFlyFmt::Undo( SwUndoIter& rIter )
+{
+    SwDoc& rDoc = rIter.GetDoc();
+
+    // ist das neue Format noch vorhanden ??
+    if( USHRT_MAX != rDoc.GetFrmFmts()->GetPos( (const SwFrmFmtPtr)pOldFmt ) )
+    {
+        if( bAnchorChgd )
+            pFrmFmt->DelFrms();
+
+        if( pFrmFmt->DerivedFrom() != pOldFmt )
+            pFrmFmt->SetDerivedFrom( pOldFmt );
+
+        SfxItemIter aIter( *pItemSet );
+        const SfxPoolItem* pItem = aIter.GetCurItem();
+        while( pItem )
+        {
+            if( IsInvalidItem( pItem ))
+                pFrmFmt->ResetAttr( pItemSet->GetWhichByPos(
+                                        aIter.GetCurPos() ));
+            else
+                pFrmFmt->SetAttr( *pItem );
+
+            if( aIter.IsAtEnd() )
+                break;
+            pItem = aIter.NextItem();
+        }
+
+        if( bAnchorChgd )
+        {
+            const SwFmtAnchor& rOldAnch = pFrmFmt->GetAnchor();
+            if( FLY_IN_CNTNT == rOldAnch.GetAnchorId() )
+            {
+                // Bei InCntnt's wird es spannend: Das TxtAttribut muss
+                // vernichtet werden. Leider reisst dies neben den Frms
+                // auch noch das Format mit in sein Grab. Um dass zu
+                // unterbinden loesen wir vorher die Verbindung zwischen
+                // Attribut und Format.
+                const SwPosition *pPos = rOldAnch.GetCntntAnchor();
+                SwTxtNode *pTxtNode = pPos->nNode.GetNode().GetTxtNode();
+                ASSERT( pTxtNode->HasHints(), "Missing FlyInCnt-Hint." );
+                const xub_StrLen nIdx = pPos->nContent.GetIndex();
+                SwTxtAttr * pHnt = pTxtNode->GetTxtAttr( nIdx, RES_TXTATR_FLYCNT );
+#ifndef PRODUCT
+                ASSERT( pHnt && pHnt->Which() == RES_TXTATR_FLYCNT,
+                            "Missing FlyInCnt-Hint." );
+                ASSERT( pHnt && pHnt->GetFlyCnt().GetFrmFmt() == pFrmFmt,
+                            "Wrong TxtFlyCnt-Hint." );
+#endif
+                ((SwFmtFlyCnt&)pHnt->GetFlyCnt()).SetFlyFmt();
+
+                // Die Verbindung ist geloest, jetzt muss noch das Attribut
+                // vernichtet werden.
+                pTxtNode->Delete( RES_TXTATR_FLYCNT, nIdx, nIdx );
+            }
+
+            // Anker umsetzen
+            SwFmtAnchor aNewAnchor( (RndStdIds) nOldAnchorTyp );
+            GetAnchor( aNewAnchor, nOldNode, nOldCntnt );
+            pFrmFmt->SetAttr( aNewAnchor );
+
+            if( FLY_IN_CNTNT == aNewAnchor.GetAnchorId() )
+            {
+                SwPosition* pPos = (SwPosition*)aNewAnchor.GetCntntAnchor();
+                pPos->nNode.GetNode().GetTxtNode()->Insert(
+                        SwFmtFlyCnt( (SwFlyFrmFmt*)pFrmFmt ), nOldCntnt, 0 );
+            }
+
+            pFrmFmt->MakeFrms();
+        }
+        rIter.pSelFmt = pFrmFmt;
+    }
+}
+
+void SwUndoSetFlyFmt::Redo( SwUndoIter& rIter )
+{
+    SwDoc& rDoc = rIter.GetDoc();
+
+    // ist das neue Format noch vorhanden ??
+    if( USHRT_MAX != rDoc.GetFrmFmts()->GetPos( (const SwFrmFmtPtr)pNewFmt ) )
+    {
+
+        if( bAnchorChgd )
+        {
+            SwFmtAnchor aNewAnchor( (RndStdIds) nNewAnchorTyp );
+            GetAnchor( aNewAnchor, nNewNode, nNewCntnt );
+            SfxItemSet aSet( rDoc.GetAttrPool(), aFrmFmtSetRange );
+            aSet.Put( aNewAnchor );
+            rDoc.SetFrmFmtToFly( *pFrmFmt, *pNewFmt, &aSet );
+        }
+        else
+            rDoc.SetFrmFmtToFly( *pFrmFmt, *pNewFmt, 0 );
+
+        rIter.pSelFmt = pFrmFmt;
+    }
+}
+
+void SwUndoSetFlyFmt::PutAttr( USHORT nWhich, const SfxPoolItem* pItem )
+{
+    if( pItem && pItem != GetDfltAttr( nWhich ) )
+    {
+        // Sonderbehandlung fuer den Anchor
+        if( RES_ANCHOR == nWhich )
+        {
+            // nur den 1. Ankerwechsel vermerken
+            ASSERT( !bAnchorChgd, "mehrfacher Ankerwechsel nicht erlaubt!" );
+
+            bAnchorChgd = TRUE;
+
+            const SwFmtAnchor* pAnchor = (SwFmtAnchor*)pItem;
+            switch( nOldAnchorTyp = pAnchor->GetAnchorId() )
+            {
+            case FLY_IN_CNTNT:
+            case FLY_AUTO_CNTNT:
+                nOldCntnt = pAnchor->GetCntntAnchor()->nContent.GetIndex();
+            case FLY_AT_CNTNT:
+            case FLY_AT_FLY:
+                nOldNode = pAnchor->GetCntntAnchor()->nNode.GetIndex();
+                break;
+
+            default:
+                nOldCntnt = pAnchor->GetPageNum();
+            }
+
+            pAnchor = (SwFmtAnchor*)&pFrmFmt->GetAnchor();
+            switch( nNewAnchorTyp = pAnchor->GetAnchorId() )
+            {
+            case FLY_IN_CNTNT:
+            case FLY_AUTO_CNTNT:
+                nNewCntnt = pAnchor->GetCntntAnchor()->nContent.GetIndex();
+            case FLY_AT_CNTNT:
+            case FLY_AT_FLY:
+                nNewNode = pAnchor->GetCntntAnchor()->nNode.GetIndex();
+                break;
+
+            default:
+                nNewCntnt = pAnchor->GetPageNum();
+            }
+        }
+        else
+            pItemSet->Put( *pItem );
+    }
+    else
+        pItemSet->InvalidateItem( nWhich );
+}
+
+void SwUndoSetFlyFmt::Modify( SfxPoolItem* pOld, SfxPoolItem* )
+{
+    if( pOld )
+    {
+        USHORT nWhich = pOld->Which();
+
+        if( nWhich < POOLATTR_END )
+            PutAttr( nWhich, pOld );
+        else if( RES_ATTRSET_CHG == nWhich )
+        {
+            SfxItemIter aIter( *((SwAttrSetChg*)pOld)->GetChgSet() );
+            const SfxPoolItem* pItem = aIter.GetCurItem();
+            while( pItem )
+            {
+                PutAttr( pItem->Which(), pItem );
+                if( aIter.IsAtEnd() )
+                    break;
+                pItem = aIter.NextItem();
+            }
+        }
+    }
+}
+
+/*************************************************************************
+
+   $Log: not supported by cvs2svn $
+   Revision 1.55  2000/09/18 16:04:29  willem.vandorp
+   OpenOffice header added.
+
+   Revision 1.54  2000/05/09 10:04:08  jp
+   Changes for Unicode
+
+   Revision 1.53  1999/11/29 17:24:12  jp
+   some changes for the compat. attribut
+
+   Revision 1.52  1999/11/10 09:30:30  jp
+   DelFly: call to uno before change any attributes
+
+   Revision 1.51  1998/12/18 14:40:34  JP
+   Bug #60505#: InsFly - CntFly Attr erst setzen, wenn der Inhalt vorhanden ist
+
+
+      Rev 1.50   18 Dec 1998 15:40:34   JP
+   Bug #60505#: InsFly - CntFly Attr erst setzen, wenn der Inhalt vorhanden ist
+
+      Rev 1.49   12 May 1998 15:48:18   JP
+   rund um Flys/DrawObjs im Doc umgestellt/optimiert
+
+      Rev 1.48   24 Apr 1998 17:54:12   JP
+   neues UndoObject fuers Setzen von Rahmenvorlagen
+
+      Rev 1.47   02 Apr 1998 15:12:50   JP
+   Redo: Undo-Flag wird schon von der EditShell abgeschaltet
+
+      Rev 1.46   27 Feb 1998 09:23:02   JP
+   Vorm loeschen der FlyFrms aus dem SpzArray den UNO Objecten bescheid geben
+
+      Rev 1.45   27 Jan 1998 22:36:14   JP
+   GetNumDepend durch GetDepends ersetzt
+
+      Rev 1.44   19 Dec 1997 12:15:34   JP
+   MSG/NOTE entfernt
+
+      Rev 1.43   03 Nov 1997 13:06:08   MA
+   precomp entfernt
+
+      Rev 1.42   09 Oct 1997 15:45:30   JP
+   Umstellung NodeIndex/-Array/BigPtrArray
+
+      Rev 1.41   10 Sep 1997 14:33:16   JP
+   Bug #43672#: InsFly::Repeat - ggfs. die vom CopyLayoutFmt angelegten FlyFrms wieder entfernen
+
+      Rev 1.40   03 Sep 1997 10:29:32   JP
+   zusaetzliches include von docary
+
+      Rev 1.39   18 Aug 1997 10:34:52   OS
+   includes
+
+      Rev 1.38   15 Aug 1997 12:37:40   OS
+   charatr/frmatr/txtatr aufgeteilt
+
+      Rev 1.37   11 Jun 1997 10:43:44   JP
+   pure virtual Repeat wurde zur virtual Methode, Segment Pragma entfernt
+
+      Rev 1.36   15 Apr 1997 14:51:52   AMA
+   New: Rahmengebundene Rahmen und auto.positionierte Rahmen
+
+      Rev 1.35   31 Oct 1996 16:19:00   MA
+   opt: Which nicht mehr virtuell, kann ISA ersetzen
+
+      Rev 1.34   29 Oct 1996 14:53:46   JP
+   am Doc ist das NodesArray nur noch ueber Get..() zugaenglich
+
+      Rev 1.33   29 Aug 1996 10:09:28   JP
+   beim StartNode muss jetzt ein spz. Sectiontype gesetzt werden
+
+      Rev 1.32   29 May 1996 15:33:42   JP
+   Bug #28123#: Draw-Objecte nur selektieren wenns vorgegeben wurde
+
+      Rev 1.31   17 May 1996 15:04:42   AMA
+   Fix: Undo von zeichengebundenen Zeichenobjekten
+
+      Rev 1.30   04 Dec 1995 16:37:12   MA
+   chg: eigener Undotext fuer einfuegen Zeichenobjekt
+
+      Rev 1.29   24 Nov 1995 17:13:56   OM
+   PCH->PRECOMPILED
+
+      Rev 1.28   26 Sep 1995 18:53:20   JP
+   UndoDelFly: unterscheide die Inhaltsform (Rahmen/OLE/GRF)
+
+      Rev 1.27   08 Sep 1995 19:11:40   ER
+   _SFXUNDO_HXX --> _UNDO_HXX
+
+      Rev 1.26   22 Jun 1995 19:33:32   JP
+   virt. Methode GetUndoRange vernichtet, Objecte rufen jetzt die Basis-Klasse
+
+      Rev 1.25   31 Mar 1995 18:54:10   MA
+   include undo.hxx
+
+      Rev 1.24   04 Mar 1995 13:30:24   MA
+   unnoetiges SEXPORT entfernt.
+
+      Rev 1.23   23 Feb 1995 23:02:26   ER
+   sexport
+
+      Rev 1.22   23 Feb 1995 17:53:24   MA
+   Rudimentaer Undo/Redo fuer Zeichenobjekte.
+
+      Rev 1.21   08 Feb 1995 23:53:02   ER
+   undo.hxx -> swundo.hxx wegen solar undo.hxx
+
+      Rev 1.20   11 Jan 1995 19:06:52   MA
+   CurrShell statt OleShell.
+
+      Rev 1.19   15 Dec 1994 20:47:46   SWG
+   *ARR* Ersetzungen, svmem, __far_data etc.
+
+      Rev 1.18   28 Oct 1994 19:19:28   MA
+   Reimport frmatr.
+
+      Rev 1.17   25 Oct 1994 14:50:34   MA
+   PreHdr.
+
+      Rev 1.16   07 Sep 1994 17:29:44   SWG
+   Umstellung Attribute
+
+      Rev 1.15   25 Aug 1994 18:05:52   JP
+   Umstellung Attribute (von SwHint -> SfxPoolItem)
+
+      Rev 1.14   04 Aug 1994 13:29:54   SWG
+   swg32: SED Size to SSize, LSize to Size etc.
+
+      Rev 1.13   17 Feb 1994 08:31:08   MI
+   SEG_FUNCDEFS ausgefuellt
+
+      Rev 1.12   16 Feb 1994 13:19:16   MI
+   Pragmas zurechtgerueckt
+
+*************************************************************************/
+
diff --git a/sw/source/core/undo/undraw.cxx b/sw/source/core/undo/undraw.cxx
new file mode 100644
index 000000000000..a5fbdd5f2871
--- /dev/null
+++ b/sw/source/core/undo/undraw.cxx
@@ -0,0 +1,779 @@
+/*************************************************************************
+ *
+ *  $RCSfile: undraw.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:27 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include 
+
+#ifndef _RTL_MEMORY_H
+#include 
+#endif
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _RTL_STRING_H
+#include 
+#endif
+#ifndef _SVDOGRP_HXX //autogen
+#include 
+#endif
+#ifndef _SVDUNDO_HXX //autogen
+#include 
+#endif
+#ifndef _SVDPAGE_HXX //autogen
+#include 
+#endif
+#ifndef _SVDMARK_HXX //autogen wg. SdrMarkList
+#include 
+#endif
+
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFLCNT_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFLCNT_HXX //autogen
+#include 
+#endif
+#ifndef _FRMFMT_HXX //autogen
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _FRAME_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include            // fuer die UndoIds
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _UNDOBJ_HXX
+#include 
+#endif
+#ifndef _DCONTACT_HXX
+#include 
+#endif
+#ifndef _DVIEW_HXX
+#include 
+#endif
+#ifndef _HINTS_HXX
+#include 
+#endif
+#ifndef _ROOTFRM_HXX //autogen wg. SwRootFrm
+#include 
+#endif
+#ifndef _VIEWSH_HXX //autogen wg. ViewShell
+#include 
+#endif
+
+#pragma optimize("elg",off)
+
+struct SwUndoGroupObjImpl
+{
+    SwDrawFrmFmt* pFmt;
+    SdrObject* pObj;
+    ULONG nNodeIdx;
+
+    // longs statt einem Point benutzen (sonst legt der Compiler fuer
+    // diese Klasse einen eigenen CTOR an!)
+    long aRelPosX, aRelPosY, aAnchorPosX, aAnchorPosY;
+
+    void SetRelPos( const Point& rPt )
+                            { aRelPosX = rPt.X(), aRelPosY = rPt.Y(); }
+    void SetAnchorPos(const Point& rPt )
+                            { aAnchorPosX = rPt.X(), aAnchorPosY = rPt.Y(); }
+
+    Point& GetRelPos() const            { return *(Point*)(&aRelPosX); }
+    Point& GetAnchorPos() const         { return *(Point*)(&aAnchorPosX); }
+};
+
+
+inline SwDoc& SwUndoIter::GetDoc() const { return *pAktPam->GetDoc(); }
+
+// Draw-Objecte
+
+IMPL_LINK( SwDoc, AddDrawUndo, SdrUndoAction *, pUndo )
+{
+#ifdef DEBUG
+    USHORT nId = pUndo->GetId();
+    String sComment( pUndo->GetComment() );
+#endif
+
+    if( DoesUndo() && !IsNoDrawUndoObj() )
+    {
+        ClearRedo();
+        const SdrMarkList* pMarkList = 0;
+        ViewShell* pSh = GetRootFrm() ? GetRootFrm()->GetCurrShell() : 0;
+        if( pSh && pSh->HasDrawView() )
+            pMarkList = &pSh->GetDrawView()->GetMarkList();
+
+        AppendUndo( new SwSdrUndo( pUndo, pMarkList ) );
+    }
+    else
+        delete pUndo;
+    return 0;
+}
+
+SwSdrUndo::SwSdrUndo( SdrUndoAction* pUndo, const SdrMarkList* pMrkLst )
+    : SwUndo( UNDO_DRAWUNDO ), pSdrUndo( pUndo )
+{
+    if( pMrkLst && pMrkLst->GetMarkCount() )
+        pMarkList = new SdrMarkList( *pMrkLst );
+    else
+        pMarkList = 0;
+}
+
+SwSdrUndo::~SwSdrUndo()
+{
+    delete pSdrUndo;
+    delete pMarkList;
+}
+
+void SwSdrUndo::Undo( SwUndoIter& rUndoIter )
+{
+    pSdrUndo->Undo();
+    rUndoIter.pMarkList = pMarkList;
+}
+
+void SwSdrUndo::Redo( SwUndoIter& rUndoIter )
+{
+    pSdrUndo->Redo();
+    rUndoIter.pMarkList = pMarkList;
+}
+
+String SwSdrUndo::GetComment() const
+{
+    return pSdrUndo->GetComment();
+}
+
+//--------------------------------------------
+
+void lcl_SendRemoveToUno( SwFmt& rFmt )
+{
+    SwPtrMsgPoolItem aMsgHint( RES_REMOVE_UNO_OBJECT, &rFmt );
+    rFmt.Modify( &aMsgHint, &aMsgHint );
+}
+
+void lcl_SaveAnchor( SwFrmFmt* pFmt, ULONG& rNodePos )
+{
+    const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
+    if( FLY_AT_CNTNT == rAnchor.GetAnchorId() ||
+        FLY_AUTO_CNTNT == rAnchor.GetAnchorId() ||
+        FLY_AT_FLY == rAnchor.GetAnchorId() ||
+        FLY_IN_CNTNT == rAnchor.GetAnchorId() )
+    {
+        rNodePos = rAnchor.GetCntntAnchor()->nNode.GetIndex();
+        xub_StrLen nCntntPos = 0;
+
+        if( FLY_IN_CNTNT == rAnchor.GetAnchorId() )
+        {
+            nCntntPos = rAnchor.GetCntntAnchor()->nContent.GetIndex();
+
+            // TextAttribut zerstoeren
+            SwTxtNode *pTxtNd = pFmt->GetDoc()->GetNodes()[ rNodePos ]->GetTxtNode();
+            ASSERT( pTxtNd, "Kein Textnode gefunden" );
+            SwTxtFlyCnt* pAttr = (SwTxtFlyCnt*)pTxtNd->GetTxtAttr( nCntntPos );
+            // Attribut steht noch im TextNode, loeschen
+            if( pAttr && pAttr->GetFlyCnt().GetFrmFmt() == pFmt )
+            {
+                // Pointer auf 0, nicht loeschen
+                ((SwFmtFlyCnt&)pAttr->GetFlyCnt()).SetFlyFmt();
+                SwIndex aIdx( pTxtNd, nCntntPos );
+                pTxtNd->Erase( aIdx, 1 );
+            }
+        }
+        else if( FLY_AUTO_CNTNT == rAnchor.GetAnchorId() )
+            nCntntPos = rAnchor.GetCntntAnchor()->nContent.GetIndex();
+
+        pFmt->SetAttr( SwFmtAnchor( rAnchor.GetAnchorId(), nCntntPos ) );
+    }
+}
+
+void lcl_RestoreAnchor( SwFrmFmt* pFmt, ULONG& rNodePos )
+{
+    const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
+    if( FLY_AT_CNTNT == rAnchor.GetAnchorId() ||
+        FLY_AUTO_CNTNT == rAnchor.GetAnchorId() ||
+        FLY_AT_FLY == rAnchor.GetAnchorId() ||
+        FLY_IN_CNTNT == rAnchor.GetAnchorId() )
+    {
+        xub_StrLen nCntntPos = rAnchor.GetPageNum();
+        SwNodes& rNds = pFmt->GetDoc()->GetNodes();
+
+        SwNodeIndex aIdx( rNds, rNodePos );
+        SwPosition aPos( aIdx );
+
+        SwFmtAnchor aTmp( rAnchor.GetAnchorId() );
+        if( FLY_IN_CNTNT == rAnchor.GetAnchorId() ||
+            FLY_AUTO_CNTNT == rAnchor.GetAnchorId() )
+            aPos.nContent.Assign( aIdx.GetNode().GetCntntNode(), nCntntPos );
+        aTmp.SetAnchor( &aPos );
+        pFmt->SetAttr( aTmp );
+
+        if( FLY_IN_CNTNT == rAnchor.GetAnchorId() )
+        {
+            SwTxtNode *pTxtNd = aIdx.GetNode().GetTxtNode();
+            ASSERT( pTxtNd, "Kein Textnode gefunden" );
+            pTxtNd->Insert( SwFmtFlyCnt( (SwFrmFmt*)pFmt ),
+                            nCntntPos, nCntntPos );
+        }
+    }
+}
+
+SwUndoDrawGroup::SwUndoDrawGroup( USHORT nCnt )
+    : SwUndo( UNDO_DRAWGROUP ), nSize( nCnt + 1 ), bDelFmt( TRUE )
+{
+    pObjArr = new SwUndoGroupObjImpl[ nSize ];
+}
+
+SwUndoDrawGroup::~SwUndoDrawGroup()
+{
+    if( bDelFmt )
+    {
+        SwUndoGroupObjImpl* pTmp = pObjArr + 1;
+        for( USHORT n = 1; n < nSize; ++n, ++pTmp )
+            delete pTmp->pFmt;
+    }
+    else
+        delete pObjArr->pFmt;       // das GroupObject-Format
+
+    __DELETE ( nSize ) pObjArr;
+}
+
+void SwUndoDrawGroup::Undo( SwUndoIter& )
+{
+    bDelFmt = FALSE;
+
+    // das Group-Object sichern
+    SwDrawFrmFmt* pFmt = pObjArr->pFmt;
+    SwDrawContact* pContact = (SwDrawContact*)pFmt->FindContactObj();
+    SdrObject* pObj = pContact->GetMaster();
+    pObjArr->pObj = pObj;
+    pObjArr->SetAnchorPos( pObj->GetAnchorPos() );
+    pObjArr->SetRelPos( pObj->GetRelativePos() );
+
+    //loescht sich selbst!
+    pContact->Changed( *pObj, SDRUSERCALL_DELETE, pObj->GetBoundRect() );
+    pObj->SetUserCall( 0 );
+
+    ::lcl_SaveAnchor( pFmt, pObjArr->nNodeIdx );
+
+    // alle Uno-Objecte sollten sich jetzt abmelden
+    ::lcl_SendRemoveToUno( *pFmt );
+
+    // aus dem Array austragen
+    SwDoc* pDoc = pFmt->GetDoc();
+    SwSpzFrmFmts& rFlyFmts = *(SwSpzFrmFmts*)pDoc->GetSpzFrmFmts();
+    rFlyFmts.Remove( rFlyFmts.GetPos( pFmt ));
+
+    for( USHORT n = 1; n < nSize; ++n )
+    {
+        SwUndoGroupObjImpl& rSave = *( pObjArr + n );
+
+        ::lcl_RestoreAnchor( rSave.pFmt, rSave.nNodeIdx );
+        rFlyFmts.Insert( rSave.pFmt, rFlyFmts.Count() );
+
+        pObj = rSave.pObj;
+        Point aPos( pObj->GetRelativePos() );
+        pObj->NbcSetRelativePos( rSave.GetRelPos() );
+        rSave.SetRelPos( aPos );
+
+        aPos = pObj->GetAnchorPos();
+        pObj->NbcSetAnchorPos( rSave.GetAnchorPos() );
+        rSave.SetAnchorPos( aPos );
+
+        SwDrawContact *pContact = new SwDrawContact( rSave.pFmt, pObj );
+        pContact->ConnectToLayout();
+    }
+}
+
+void SwUndoDrawGroup::Redo( SwUndoIter& )
+{
+    bDelFmt = TRUE;
+
+    // aus dem Array austragen
+    SwDoc* pDoc = pObjArr->pFmt->GetDoc();
+    SwSpzFrmFmts& rFlyFmts = *(SwSpzFrmFmts*)pDoc->GetSpzFrmFmts();
+    SdrObject* pObj;
+
+    for( USHORT n = 1; n < nSize; ++n )
+    {
+        SwUndoGroupObjImpl& rSave = *( pObjArr + n );
+
+        pObj = rSave.pObj;
+        Point aPos( pObj->GetRelativePos() );
+        pObj->NbcSetRelativePos( rSave.GetRelPos() );
+        rSave.SetRelPos( aPos );
+
+        aPos = pObj->GetAnchorPos();
+        pObj->NbcSetAnchorPos( rSave.GetAnchorPos() );
+        rSave.SetAnchorPos( aPos );
+
+        SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj);
+        //loescht sich selbst!
+        pContact->Changed( *pObj, SDRUSERCALL_DELETE, pObj->GetBoundRect() );
+        pObj->SetUserCall( 0 );
+
+        ::lcl_SaveAnchor( rSave.pFmt, rSave.nNodeIdx );
+
+        // alle Uno-Objecte sollten sich jetzt abmelden
+        ::lcl_SendRemoveToUno( *rSave.pFmt );
+
+        rFlyFmts.Remove( rFlyFmts.GetPos( rSave.pFmt ));
+    }
+
+    // das Group-Object wieder einfuegen
+    ::lcl_RestoreAnchor( pObjArr->pFmt, pObjArr->nNodeIdx );
+    rFlyFmts.Insert( pObjArr->pFmt, rFlyFmts.Count() );
+
+    pObjArr->pObj->NbcSetAnchorPos( pObjArr->GetAnchorPos() );
+    pObjArr->pObj->NbcSetRelativePos( pObjArr->GetRelPos() );
+    SwDrawContact *pContact = new SwDrawContact( pObjArr->pFmt, pObjArr->pObj );
+//JP 07.07.99: no ConnectToLayout, because it recalc the ordnum new before
+//              the SdrUndo calls his Redo, and so SdrUndo never find his
+//              SdrObjects for the OrdNums.
+//  pContact->ConnectToLayout();
+}
+
+void SwUndoDrawGroup::AddObj( USHORT nPos, SwDrawFrmFmt* pFmt, SdrObject* pObj )
+{
+    SwUndoGroupObjImpl& rSave = *( pObjArr + nPos + 1 );
+    rSave.pObj = pObj;
+    rSave.pFmt = pFmt;
+    rSave.SetAnchorPos( pObj->GetAnchorPos() );
+    rSave.SetRelPos( pObj->GetRelativePos() );
+    ::lcl_SaveAnchor( pFmt, rSave.nNodeIdx );
+
+    // alle Uno-Objecte sollten sich jetzt abmelden
+    ::lcl_SendRemoveToUno( *pFmt );
+
+    // aus dem Array austragen
+    SwSpzFrmFmts& rFlyFmts = *(SwSpzFrmFmts*)pFmt->GetDoc()->GetSpzFrmFmts();
+    rFlyFmts.Remove( rFlyFmts.GetPos( pFmt ));
+}
+
+void SwUndoDrawGroup::SetGroupFmt( SwDrawFrmFmt* pFmt )
+{
+    pObjArr->pObj = 0;
+    pObjArr->pFmt = pFmt;
+}
+
+
+// ------------------------------
+
+SwUndoDrawUnGroup::SwUndoDrawUnGroup( SdrObjGroup* pObj )
+    : SwUndo( UNDO_DRAWUNGROUP ), bDelFmt( FALSE )
+{
+    nSize = (USHORT)pObj->GetSubList()->GetObjCount() + 1;
+    pObjArr = new SwUndoGroupObjImpl[ nSize ];
+
+    SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj);
+    SwDrawFrmFmt* pFmt = (SwDrawFrmFmt*)pContact->GetFmt();
+
+    pObjArr->pObj = pObj;
+    pObjArr->pFmt = pFmt;
+    pObjArr->SetRelPos( pObj->GetRelativePos() );
+    pObjArr->SetAnchorPos( pObj->GetAnchorPos() );
+
+    //loescht sich selbst!
+    pContact->Changed( *pObj, SDRUSERCALL_DELETE, pObj->GetBoundRect() );
+    pObj->SetUserCall( 0 );
+
+    ::lcl_SaveAnchor( pFmt, pObjArr->nNodeIdx );
+
+    // alle Uno-Objecte sollten sich jetzt abmelden
+    ::lcl_SendRemoveToUno( *pFmt );
+
+    // aus dem Array austragen
+    SwSpzFrmFmts& rFlyFmts = *(SwSpzFrmFmts*)pFmt->GetDoc()->GetSpzFrmFmts();
+    rFlyFmts.Remove( rFlyFmts.GetPos( pFmt ));
+}
+
+SwUndoDrawUnGroup::~SwUndoDrawUnGroup()
+{
+    if( bDelFmt )
+    {
+        SwUndoGroupObjImpl* pTmp = pObjArr + 1;
+        for( USHORT n = 1; n < nSize; ++n, ++pTmp )
+            delete pTmp->pFmt;
+    }
+    else
+        delete pObjArr->pFmt;       // das GroupObject-Format
+
+    __DELETE ( nSize ) pObjArr;
+}
+
+void SwUndoDrawUnGroup::Undo( SwUndoIter& rIter )
+{
+    bDelFmt = TRUE;
+
+    // aus dem Array austragen
+    SwDoc* pDoc = &rIter.GetDoc();
+    SwSpzFrmFmts& rFlyFmts = *(SwSpzFrmFmts*)pDoc->GetSpzFrmFmts();
+
+    for( USHORT n = 1; n < nSize; ++n )
+    {
+        SwUndoGroupObjImpl& rSave = *( pObjArr + n );
+
+        SwDrawContact* pContact = (SwDrawContact*)rSave.pFmt->FindContactObj();
+
+        rSave.pObj = pContact->GetMaster();
+        rSave.SetRelPos( rSave.pObj->GetRelativePos() );
+        rSave.SetAnchorPos( rSave.pObj->GetAnchorPos() );
+
+        //loescht sich selbst!
+        pContact->Changed( *rSave.pObj, SDRUSERCALL_DELETE,
+            rSave.pObj->GetBoundRect() );
+        rSave.pObj->SetUserCall( 0 );
+
+        ::lcl_SaveAnchor( rSave.pFmt, rSave.nNodeIdx );
+
+        // alle Uno-Objecte sollten sich jetzt abmelden
+        ::lcl_SendRemoveToUno( *rSave.pFmt );
+
+        rFlyFmts.Remove( rFlyFmts.GetPos( rSave.pFmt ));
+    }
+
+    // das Group-Object wieder einfuegen
+    ::lcl_RestoreAnchor( pObjArr->pFmt, pObjArr->nNodeIdx );
+    rFlyFmts.Insert( pObjArr->pFmt, rFlyFmts.Count() );
+
+    pObjArr->pObj->NbcSetRelativePos( pObjArr->GetRelPos() );
+    pObjArr->pObj->NbcSetAnchorPos( pObjArr->GetAnchorPos() );
+
+    SwDrawContact *pContact = new SwDrawContact( pObjArr->pFmt, pObjArr->pObj );
+    pContact->ConnectToLayout();
+}
+
+void SwUndoDrawUnGroup::Redo( SwUndoIter& )
+{
+    bDelFmt = FALSE;
+
+    // das Group-Object sichern
+    SwDrawFrmFmt* pFmt = pObjArr->pFmt;
+    SwDrawContact* pContact = (SwDrawContact*)pFmt->FindContactObj();
+
+    //loescht sich selbst!
+    pContact->Changed( *pObjArr->pObj, SDRUSERCALL_DELETE,
+        pObjArr->pObj->GetBoundRect() );
+    pObjArr->pObj->SetUserCall( 0 );
+
+    ::lcl_SaveAnchor( pFmt, pObjArr->nNodeIdx );
+
+    // alle Uno-Objecte sollten sich jetzt abmelden
+    ::lcl_SendRemoveToUno( *pFmt );
+
+    // aus dem Array austragen
+    SwDoc* pDoc = pFmt->GetDoc();
+    SwSpzFrmFmts& rFlyFmts = *(SwSpzFrmFmts*)pDoc->GetSpzFrmFmts();
+    rFlyFmts.Remove( rFlyFmts.GetPos( pFmt ));
+
+    for( USHORT n = 1; n < nSize; ++n )
+    {
+        SwUndoGroupObjImpl& rSave = *( pObjArr + n );
+
+        ::lcl_RestoreAnchor( rSave.pFmt, rSave.nNodeIdx );
+        rFlyFmts.Insert( rSave.pFmt, rFlyFmts.Count() );
+
+        SdrObject* pObj = rSave.pObj;
+        Point aPos( pObj->GetRelativePos() );
+        pObj->NbcSetRelativePos( rSave.GetRelPos() );
+        rSave.SetRelPos( aPos );
+
+        aPos = pObj->GetAnchorPos();
+        pObj->NbcSetAnchorPos( rSave.GetAnchorPos() );
+        rSave.SetAnchorPos( aPos );
+
+        SwDrawContact *pContact = new SwDrawContact( rSave.pFmt, rSave.pObj );
+        pContact->ConnectToLayout();
+    }
+}
+
+void SwUndoDrawUnGroup::AddObj( USHORT nPos, SwDrawFrmFmt* pFmt )
+{
+    SwUndoGroupObjImpl& rSave = *( pObjArr + nPos + 1 );
+    rSave.pFmt = pFmt;
+    rSave.pObj = 0;
+}
+
+//-------------------------------------
+
+SwUndoDrawDelete::SwUndoDrawDelete( USHORT nCnt )
+    : SwUndo( UNDO_DRAWDELETE ), nSize( nCnt ), bDelFmt( TRUE )
+{
+    pObjArr = new SwUndoGroupObjImpl[ nSize ];
+}
+
+SwUndoDrawDelete::~SwUndoDrawDelete()
+{
+    if ( bDelFmt )
+    {
+        SwUndoGroupObjImpl* pTmp = pObjArr;
+        for( USHORT n = 0; n < nSize; ++n, ++pTmp )
+            delete pTmp->pFmt;
+    }
+    __DELETE ( nSize ) pObjArr;
+}
+
+void SwUndoDrawDelete::Undo( SwUndoIter &rIter )
+{
+    bDelFmt = FALSE;
+    SwSpzFrmFmts& rFlyFmts = *rIter.GetDoc().GetSpzFrmFmts();
+    for( USHORT n = 0; n < nSize; ++n )
+    {
+        SwUndoGroupObjImpl& rSave = *( pObjArr + n );
+        ::lcl_RestoreAnchor( rSave.pFmt, rSave.nNodeIdx );
+        rFlyFmts.Insert( rSave.pFmt, rFlyFmts.Count() );
+        SdrObject *pObj = rSave.pObj;
+        SwDrawContact *pContact = new SwDrawContact( rSave.pFmt, pObj );
+        pContact->_Changed( *pObj, SDRUSERCALL_INSERTED, NULL );
+    }
+}
+
+void SwUndoDrawDelete::Redo( SwUndoIter &rIter )
+{
+    bDelFmt = TRUE;
+    SwSpzFrmFmts& rFlyFmts = *rIter.GetDoc().GetSpzFrmFmts();
+    for( USHORT n = 0; n < nSize; ++n )
+    {
+        SwUndoGroupObjImpl& rSave = *( pObjArr + n );
+        SdrObject *pObj = rSave.pObj;
+        SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj);
+        SwDrawFrmFmt *pFmt = (SwDrawFrmFmt*)pContact->GetFmt();
+        //loescht sich selbst!
+        pContact->Changed( *pObj, SDRUSERCALL_DELETE, pObj->GetBoundRect() );
+        pObj->SetUserCall( 0 );
+
+        // alle Uno-Objecte sollten sich jetzt abmelden
+        ::lcl_SendRemoveToUno( *pFmt );
+
+        rFlyFmts.Remove( rFlyFmts.GetPos( pFmt ));
+        ::lcl_SaveAnchor( pFmt, rSave.nNodeIdx );
+    }
+}
+
+void SwUndoDrawDelete::AddObj( USHORT nPos, SwDrawFrmFmt* pFmt, SdrObject* pObj )
+{
+    SwUndoGroupObjImpl& rSave = *( pObjArr + nPos );
+    rSave.pObj = pObj;
+    rSave.pFmt = pFmt;
+    ::lcl_SaveAnchor( pFmt, rSave.nNodeIdx );
+
+    // alle Uno-Objecte sollten sich jetzt abmelden
+    ::lcl_SendRemoveToUno( *pFmt );
+
+    // aus dem Array austragen
+    SwSpzFrmFmts& rFlyFmts = *(SwSpzFrmFmts*)pFmt->GetDoc()->GetSpzFrmFmts();
+    rFlyFmts.Remove( rFlyFmts.GetPos( pFmt ));
+}
+
+
+/*************************************************************************
+
+      Source Code Control System - Header
+
+      $Header: /zpool/svn/migration/cvs_rep_09_09_08/code/sw/source/core/undo/undraw.cxx,v 1.1.1.1 2000-09-19 00:08:27 hr Exp $
+
+      Source Code Control System - Update
+
+      $Log: not supported by cvs2svn $
+      Revision 1.40  2000/09/18 16:04:29  willem.vandorp
+      OpenOffice header added.
+
+      Revision 1.39  2000/05/09 10:04:13  jp
+      Changes for Unicode
+
+      Revision 1.38  1999/11/03 10:52:54  rt
+      #65293# include rtl/memory.h
+
+      Revision 1.37  1999/10/25 19:32:03  tl
+      ongoing ONE_LINGU implementation
+
+      Revision 1.36  1999/09/29 06:42:39  mh
+      chg: header
+
+      Revision 1.35  1999/07/07 17:26:20  JP
+      DrawGroup:Redo: no call of ConnectToLayout, because SdrUndo dont find his objects
+
+
+      Rev 1.34   07 Jul 1999 19:26:20   JP
+   DrawGroup:Redo: no call of ConnectToLayout, because SdrUndo dont find his objects
+
+      Rev 1.33   07 Jul 1999 16:16:56   JP
+   Bug #57068#: now we handle the seleection of SdrObjects after undo/redo ourselves
+
+      Rev 1.32   27 Jan 1999 18:52:32   JP
+   Task #61014#: FindSdrObject/FindContactObject als Methoden vom SwFrmFmt
+
+      Rev 1.31   07 Jul 1998 16:10:24   AMA
+   Fix #52317#: GPF durch Undo-Objekte innerhalb von Gruppen
+
+      Rev 1.30   27 Feb 1998 09:23:02   JP
+   Vorm loeschen der FlyFrms aus dem SpzArray den UNO Objecten bescheid geben
+
+      Rev 1.29   20 Nov 1997 18:32:20   MA
+   includes
+
+      Rev 1.28   03 Nov 1997 13:06:30   MA
+   precomp entfernt
+
+      Rev 1.27   09 Oct 1997 15:45:28   JP
+   Umstellung NodeIndex/-Array/BigPtrArray
+
+      Rev 1.26   03 Sep 1997 10:29:40   JP
+   zusaetzliches include von docary
+
+      Rev 1.25   18 Aug 1997 10:34:54   OS
+   includes
+
+      Rev 1.24   15 Aug 1997 12:37:42   OS
+   charatr/frmatr/txtatr aufgeteilt
+
+      Rev 1.23   11 Jun 1997 10:43:46   JP
+   pure virtual Repeat wurde zur virtual Methode, Segment Pragma entfernt
+
+      Rev 1.22   15 Apr 1997 14:52:00   AMA
+   New: Rahmengebundene Rahmen und auto.positionierte Rahmen
+
+      Rev 1.21   04 Apr 1997 16:44:56   MH
+   chg: header
+
+      Rev 1.20   30 Jan 1997 18:18:04   AMA
+   Fix: Beim Undo des Loeschens umflossener Objekte muss Bescheid gesagt werden
+
+      Rev 1.19   29 Oct 1996 14:54:00   JP
+   am Doc ist das NodesArray nur noch ueber Get..() zugaenglich
+
+      Rev 1.18   24 Oct 1996 12:51:14   AMA
+   Chg 342: Changed has changed.
+
+      Rev 1.17   24 Aug 1996 17:00:32   JP
+   svdraw.hxx entfernt
+
+      Rev 1.16   13 Jun 1996 16:07:38   MA
+   splitt si.hxx
+
+      Rev 1.15   10 Jun 1996 16:04:26   HJS
+   clooks etc.
+
+      Rev 1.14   29 May 1996 18:35:00   NF
+   define SDR_UNDO dazu...
+
+      Rev 1.13   23 May 1996 08:20:42   OS
+   Chg 319: Delete() -> Changed()
+
+      Rev 1.12   20 May 1996 16:02:04   AMA
+   Fix: Auch beim Redo muss das Objekt ggf. im TxtFrm verankert werden.
+
+      Rev 1.11   20 May 1996 10:44:14   JP
+   Save/Restore: TextAttribut zerstoeren/anlegen
+
+      Rev 1.10   17 May 1996 18:04:44   JP
+   DrawObjecte koennen auch zeichengebunden sein
+
+      Rev 1.9   06 Feb 1996 15:16:46   JP
+   Link Umstellung 305
+
+      Rev 1.8   03 Dec 1995 13:58:20   MA
+   fix(22938): UndoDrawDelete braucht doch ein bDelFmt
+
+      Rev 1.7   24 Nov 1995 17:14:06   OM
+   PCH->PRECOMPILED
+
+      Rev 1.6   15 Nov 1995 14:27:14   MA
+   chg: Undo fuer Zeichenobjekte jetzt richtig
+
+      Rev 1.5   13 Nov 1995 12:09:08   MA
+   chg: static -> lcl_
+
+      Rev 1.4   06 Nov 1995 13:43:58   JP
+   SwUndoGroupObjImpl: 2 Points gegen 4 longs ausgetauscht, erspart den CTOR
+
+      Rev 1.3   06 Sep 1995 15:52:40   MA
+   fix: Optimierung teilw. abgeschaltet
+
+      Rev 1.2   06 Sep 1995 12:13:22   MA
+   fix: includes
+
+      Rev 1.1   04 Sep 1995 10:18:04   MA
+   fix: fuer MSC verstaendlich impl.
+
+      Rev 1.0   22 Aug 1995 17:47:12   JP
+   Initial revision.
+
+*************************************************************************/
+
diff --git a/sw/source/core/undo/unfmco.cxx b/sw/source/core/undo/unfmco.cxx
new file mode 100644
index 000000000000..45a097891b00
--- /dev/null
+++ b/sw/source/core/undo/unfmco.cxx
@@ -0,0 +1,202 @@
+/*************************************************************************
+ *
+ *  $RCSfile: unfmco.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:27 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "doc.hxx"
+#include "swundo.hxx"           // fuer die UndoIds
+#include "pam.hxx"
+#include "ndtxt.hxx"
+
+#include "undobj.hxx"
+#include "rolbck.hxx"
+
+
+inline SwDoc& SwUndoIter::GetDoc() const { return *pAktPam->GetDoc(); }
+
+//--------------------------------------------------
+
+
+SwUndoFmtColl::SwUndoFmtColl( const SwPaM& rRange, SwFmtColl* pColl )
+    : SwUndo( UNDO_SETFMTCOLL ), SwUndRng( rRange ), pFmtColl( pColl ),
+    pHistory( new SwHistory )
+{
+#ifdef COMPACT
+    ((SwDoc*)rRange.GetDoc())->DelUndoGroups();
+#endif
+}
+
+
+SwUndoFmtColl::~SwUndoFmtColl()
+{
+    delete pHistory;
+}
+
+
+void SwUndoFmtColl::Undo( SwUndoIter& rUndoIter )
+{
+    // die alten Werte wieder zurueck
+    pHistory->TmpRollback( &rUndoIter.GetDoc(), 0 );
+    pHistory->SetTmpEnd( pHistory->Count() );
+
+    // setze noch den Cursor auf den Undo-Bereich
+    SetPaM( rUndoIter );
+}
+
+
+void SwUndoFmtColl::Redo( SwUndoIter& rUndoIter )
+{
+    // setze Attribut in dem Bereich:
+    SetPaM( rUndoIter );
+    rUndoIter.pLastUndoObj = 0;
+
+    Repeat( rUndoIter );    // Collection setzen
+
+    rUndoIter.pLastUndoObj = 0;
+}
+
+
+void SwUndoFmtColl::Repeat( SwUndoIter& rUndoIter )
+{
+    if( UNDO_SETFMTCOLL == rUndoIter.GetLastUndoId() &&
+        pFmtColl == ((SwUndoFmtColl*)rUndoIter.pLastUndoObj)->pFmtColl )
+        return;
+
+    // es kann nur eine TextFmtColl auf einen Bereich angewendet werden,
+    // also erfrage auch nur in dem Array
+    USHORT nPos = rUndoIter.GetDoc().GetTxtFmtColls()->GetPos(
+                                                     (SwTxtFmtColl*)pFmtColl );
+    // ist das Format ueberhaupt noch vorhanden?
+    if( USHRT_MAX != nPos )
+        rUndoIter.GetDoc().SetTxtFmtColl( *rUndoIter.pAktPam,
+                                        (SwTxtFmtColl*)pFmtColl );
+
+    rUndoIter.pLastUndoObj = this;
+}
+
+/*************************************************************************
+
+      Source Code Control System - Header
+
+      $Header: /zpool/svn/migration/cvs_rep_09_09_08/code/sw/source/core/undo/unfmco.cxx,v 1.1.1.1 2000-09-19 00:08:27 hr Exp $
+
+      Source Code Control System - Update
+
+      $Log: not supported by cvs2svn $
+      Revision 1.22  2000/09/18 16:04:29  willem.vandorp
+      OpenOffice header added.
+
+      Revision 1.21  1998/04/02 13:13:30  JP
+      Redo: Undo-Flag wird schon von der EditShell abgeschaltet
+
+
+      Rev 1.20   02 Apr 1998 15:13:30   JP
+   Redo: Undo-Flag wird schon von der EditShell abgeschaltet
+
+      Rev 1.19   16 Jan 1998 11:07:54   JP
+   pAttrHistory am Doc entfernt
+
+      Rev 1.18   03 Nov 1997 13:06:28   MA
+   precomp entfernt
+
+      Rev 1.17   11 Jun 1997 10:44:48   JP
+   pure virtual Repeat wurde zur virtual Methode, Segment Pragma entfernt
+
+      Rev 1.16   23 Sep 1996 20:06:28   JP
+   SetTmpEnd: DocPtr entfernt
+
+      Rev 1.15   24 Nov 1995 17:14:04   OM
+   PCH->PRECOMPILED
+
+      Rev 1.14   08 Feb 1995 23:52:36   ER
+   undo.hxx -> swundo.hxx wegen solar undo.hxx
+
+      Rev 1.13   28 Jan 1995 21:21:12   JP
+   UndoInsFmt enternt
+
+      Rev 1.12   20 Jan 1995 09:57:02   JP
+   Bug10011: erfrage am Dok. ob der Pointer auf Fmt/Coll gueltig ist
+
+      Rev 1.11   15 Dec 1994 20:47:52   SWG
+   *ARR* Ersetzungen, svmem, __far_data etc.
+
+      Rev 1.10   25 Oct 1994 14:50:34   MA
+   PreHdr.
+
+      Rev 1.9   25 Aug 1994 18:06:08   JP
+   Umstellung Attribute (von SwHint -> SfxPoolItem)
+
+      Rev 1.8   02 Mar 1994 19:48:54   MI
+   Underscore im Namen der #pragmas
+
+      Rev 1.7   17 Feb 1994 08:30:04   MI
+   SEG_FUNCDEFS ausgefuellt
+
+      Rev 1.6   16 Feb 1994 13:11:30   MI
+   Pragmas zurechtgerueckt
+
+*************************************************************************/
+
+
diff --git a/sw/source/core/undo/unins.cxx b/sw/source/core/undo/unins.cxx
new file mode 100644
index 000000000000..999a24749edf
--- /dev/null
+++ b/sw/source/core/undo/unins.cxx
@@ -0,0 +1,1214 @@
+/*************************************************************************
+ *
+ *  $RCSfile: unins.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:27 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _WORDSEL_HXX
+#include 
+#endif
+#ifndef _SVSTOR_HXX //autogen
+#include 
+#endif
+#ifndef _IPOBJ_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_KEEPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVDOBJ_HXX //autogen
+#include 
+#endif
+
+#ifndef _FMTCNTNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _FRMFMT_HXX //autogen
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include            // fuer die UndoIds
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _UNDOBJ_HXX
+#include 
+#endif
+#ifndef _ROLBCK_HXX
+#include 
+#endif
+#ifndef _NDGRF_HXX
+#include 
+#endif
+#ifndef _NDOLE_HXX
+#include 
+#endif
+#ifndef _GRFATR_HXX
+#include 
+#endif
+#ifndef _CNTFRM_HXX
+#include 
+#endif
+#ifndef _FLYFRM_HXX
+#include 
+#endif
+#ifndef _FESH_HXX
+#include 
+#endif
+#ifndef _SWTABLE_HXX
+#include 
+#endif
+#ifndef _REDLINE_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _ACORRECT_HXX
+#include 
+#endif
+#ifndef _DCONTACT_HXX //autogen
+#include 
+#endif
+
+class _UnReplaceData : private SwUndoSaveCntnt
+{
+    String sOld, sIns;
+    ULONG nSttNd, nEndNd, nOffset;
+    xub_StrLen nSttCnt, nEndCnt, nSetPos, nSelEnd;
+    BOOL bSplitNext : 1;
+    BOOL bRegExp : 1;
+
+public:
+    _UnReplaceData( const SwPaM& rPam, const String& rIns, BOOL bRegExp );
+    ~_UnReplaceData();
+
+    void Undo( SwUndoIter& rIter );
+    void Redo( SwUndoIter& rIter );
+    void SetEnd( const SwPaM& rPam );
+};
+
+
+SV_IMPL_PTRARR( _UnReplaceDatas, _UnReplaceData* )
+
+//------------------------------------------------------------------
+
+inline SwDoc& SwUndoIter::GetDoc() const { return *pAktPam->GetDoc(); }
+
+// zwei Zugriffs-Funktionen
+inline SwPosition* IterPt( SwUndoIter& rUIter )
+{   return rUIter.pAktPam->GetPoint();  }
+inline SwPosition* IterMk( SwUndoIter& rUIter )
+{   return rUIter.pAktPam->GetMark();   }
+
+//------------------------------------------------------------
+
+// INSERT
+
+SwUndoInsert::SwUndoInsert( const SwNodeIndex& rNd, xub_StrLen nCnt,
+                            xub_StrLen nL, BOOL bWDelim )
+    : SwUndo(UNDO_INSERT), nNode( rNd.GetIndex() ), nCntnt(nCnt), nLen(nL),
+        bIsWordDelim( bWDelim ), bIsAppend( FALSE ), pPos( 0 ), pTxt( 0 ),
+        pRedlData( 0 )
+{
+    // Redline beachten
+    SwDoc& rDoc = *rNd.GetNode().GetDoc();
+    if( rDoc.IsRedlineOn() )
+    {
+        pRedlData = new SwRedlineData( REDLINE_INSERT,
+                                        rDoc.GetRedlineAuthor() );
+        SetRedlineMode( rDoc.GetRedlineMode() );
+    }
+}
+
+SwUndoInsert::SwUndoInsert( const SwNodeIndex& rNd )
+    : SwUndo(UNDO_INSERT), nNode( rNd.GetIndex() ), nCntnt(0), nLen(1),
+        bIsWordDelim( FALSE ), bIsAppend( TRUE ), pPos( 0 ), pTxt( 0 ),
+        pRedlData( 0 )
+{
+    // Redline beachten
+    SwDoc& rDoc = *rNd.GetNode().GetDoc();
+    if( rDoc.IsRedlineOn() )
+    {
+        pRedlData = new SwRedlineData( REDLINE_INSERT,
+                                        rDoc.GetRedlineAuthor() );
+        SetRedlineMode( rDoc.GetRedlineMode() );
+    }
+}
+
+// stelle fest, ob das naechste Insert mit dem aktuellen zusammengefasst
+// werden kann. Wenn ja, dann aender die Laenge und die InsPos.
+// Dann wird von SwDoc::Insert kein neues Object in die Undoliste gestellt.
+
+BOOL SwUndoInsert::CanGrouping( const SwPosition& rInsPos, sal_Unicode cIns )
+{
+    BOOL bRet = FALSE;
+    if( !bIsAppend )
+    {
+        ++nCntnt;
+        bRet = CanGrouping( rInsPos );
+        --nCntnt;
+        if( bRet )
+            bRet = CanGrouping( cIns );
+    }
+    return bRet;
+}
+
+
+BOOL SwUndoInsert::CanGrouping( sal_Unicode cIns )
+{
+    if( !bIsAppend && bIsWordDelim == !WordSelection::IsNormalChar( cIns ) )
+    {
+        nLen++;
+        nCntnt++;
+        return TRUE;
+    }
+    return FALSE;
+}
+
+BOOL SwUndoInsert::CanGrouping( const SwPosition& rPos )
+{
+    BOOL bRet = FALSE;
+    if( nNode == rPos.nNode.GetIndex() &&
+        nCntnt == rPos.nContent.GetIndex() )
+    {
+        // Redline beachten
+        SwDoc& rDoc = *rPos.nNode.GetNode().GetDoc();
+        if( ( ~REDLINE_SHOW_MASK & rDoc.GetRedlineMode() ) ==
+            ( ~REDLINE_SHOW_MASK & GetRedlineMode() ) )
+        {
+            bRet = TRUE;
+
+            // dann war oder ist noch Redline an:
+            // pruefe, ob an der InsPosition ein anderer Redline
+            // rumsteht. Wenn der gleiche nur einmalig vorhanden ist,
+            // kann zusammen gefasst werden.
+            const SwRedlineTbl& rTbl = rDoc.GetRedlineTbl();
+            if( rTbl.Count() )
+            {
+                SwRedlineData aRData( REDLINE_INSERT, rDoc.GetRedlineAuthor() );
+                const SwIndexReg* pIReg = rPos.nContent.GetIdxReg();
+                SwIndex* pIdx;
+                for( USHORT i = 0; i < rTbl.Count(); ++i )
+                {
+                    SwRedline* pRedl = rTbl[ i ];
+                    if( pIReg == (pIdx = &pRedl->End()->nContent)->GetIdxReg() &&
+                        nCntnt == pIdx->GetIndex() )
+                    {
+                        if( !pRedl->HasMark() ||
+                            *pRedl != *pRedlData || *pRedl != aRData )
+                        {
+                            bRet = FALSE;
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return bRet;
+}
+
+SwUndoInsert::~SwUndoInsert()
+{
+    if( pPos )      // loesche noch den Bereich aus dem UndoNodes Array
+    {
+        // Insert speichert den Inhalt in der IconSection
+        SwNodes& rUNds = pPos->nNode.GetNode().GetNodes();
+        if( pPos->nContent.GetIndex() )         // nicht den gesamten Node loeschen
+        {
+            SwTxtNode* pTxtNd = pPos->nNode.GetNode().GetTxtNode();
+            ASSERT( pTxtNd, "kein TextNode, aus dem geloescht werden soll" );
+            pTxtNd->Erase( pPos->nContent );
+            pPos->nNode++;
+        }
+        pPos->nContent.Assign( 0, 0 );
+        rUNds.Delete( pPos->nNode, rUNds.GetEndOfExtras().GetIndex() -
+                                    pPos->nNode.GetIndex() );
+        delete pPos;
+    }
+    else if( pTxt )     // der eingefuegte Text
+        delete pTxt;
+    delete pRedlData;
+}
+
+
+
+void SwUndoInsert::Undo( SwUndoIter& rUndoIter )
+{
+    SwDoc* pDoc = &rUndoIter.GetDoc();
+
+    if( bIsAppend )
+    {
+        SwPaM* pPam = rUndoIter.pAktPam;
+        pPam->GetPoint()->nNode = nNode;
+
+        if( IsRedlineOn( GetRedlineMode() ))
+        {
+            pPam->GetPoint()->nContent.Assign( pPam->GetCntntNode(), 0 );
+            pPam->SetMark();
+            pPam->Move( fnMoveBackward );
+            pPam->Exchange();
+            pDoc->DeleteRedline( *pPam );
+        }
+        pPam->DeleteMark();
+        pDoc->DelFullPara( *pPam );
+        pPam->GetPoint()->nContent.Assign( pPam->GetCntntNode(), 0 );
+    }
+    else
+    {
+        ULONG nNd = nNode;
+        xub_StrLen nCnt = nCntnt;
+        if( nLen )
+        {
+            SwNodeIndex aNd( pDoc->GetNodes(), nNode);
+            SwCntntNode* pCNd = aNd.GetNode().GetCntntNode();
+            SwPaM aPaM( *pCNd, nCntnt );
+
+            aPaM.SetMark();
+
+            if( pCNd->IsTxtNode() )     // Text !!
+            {
+                aPaM.GetPoint()->nContent -= nLen;
+                if( IsRedlineOn( GetRedlineMode() ))
+                    pDoc->DeleteRedline( aPaM );
+                RemoveIdxFromRange( aPaM, FALSE );
+                pTxt = new String( ((SwTxtNode*)pCNd)->GetTxt().Copy(
+                                            nCntnt-nLen, nLen ) );
+                ((SwTxtNode*)pCNd)->Erase( aPaM.GetPoint()->nContent, nLen );
+            }
+            else                // ansonsten Grafik/OLE/Text/...
+            {
+                aPaM.Move(fnMoveBackward);
+                if( IsRedlineOn( GetRedlineMode() ))
+                    pDoc->DeleteRedline( aPaM );
+                RemoveIdxFromRange( aPaM, FALSE );
+            }
+
+            nNd = aPaM.GetPoint()->nNode.GetIndex();
+            nCnt = aPaM.GetPoint()->nContent.GetIndex();
+
+            if( !pTxt )
+            {
+                pPos = new SwPosition( *aPaM.GetPoint() );
+                MoveToUndoNds( aPaM, &pPos->nNode, &pPos->nContent );
+            }
+            nNode = aPaM.GetPoint()->nNode.GetIndex();
+            nCntnt = aPaM.GetPoint()->nContent.GetIndex();
+        }
+
+        // setze noch den Cursor auf den Undo-Bereich
+        rUndoIter.pAktPam->DeleteMark();
+
+        IterPt(rUndoIter)->nNode = nNd;
+        IterPt(rUndoIter)->nContent.Assign( pDoc->GetNodes()[
+                IterPt(rUndoIter)->nNode ]->GetCntntNode(), nCnt );
+        // SPoint und GetMark auf der gleichen Position
+    }
+}
+
+
+void SwUndoInsert::Redo( SwUndoIter& rUndoIter )
+{
+    // setze noch den Cursor auf den Redo-Bereich
+    SwPaM* pPam = rUndoIter.pAktPam;
+    SwDoc* pDoc = pPam->GetDoc();
+    pPam->DeleteMark();
+
+    if( bIsAppend )
+    {
+        pPam->GetPoint()->nNode = nNode - 1;
+        pDoc->AppendTxtNode( *pPam->GetPoint() );
+
+        pPam->SetMark();
+        pPam->Move( fnMoveBackward );
+        pPam->Exchange();
+
+        if( pRedlData && IsRedlineOn( GetRedlineMode() ))
+        {
+            SwRedlineMode eOld = pDoc->GetRedlineMode();
+            pDoc->SetRedlineMode_intern( eOld & ~REDLINE_IGNORE );
+            pDoc->AppendRedline( new SwRedline( *pRedlData, *pPam ));
+            pDoc->SetRedlineMode_intern( eOld );
+        }
+        else if( !( REDLINE_IGNORE & GetRedlineMode() ) &&
+                pDoc->GetRedlineTbl().Count() )
+            pDoc->SplitRedline( *pPam );
+
+        pPam->DeleteMark();
+    }
+    else
+    {
+        pPam->GetPoint()->nNode = nNode;
+        SwCntntNode* pCNd = pDoc->GetNodes()[ pPam->GetPoint()->nNode ]->GetCntntNode();
+        pPam->GetPoint()->nContent.Assign( pCNd, nCntnt );
+
+        if( nLen )
+        {
+            BOOL bMvBkwrd = MovePtBackward( *pPam );
+
+            if( pTxt )
+            {
+                ASSERT( pCNd->IsTxtNode(), "wo ist mein Textnode ??" );
+                ((SwTxtNode*)pCNd)->Insert( *pTxt, pPam->GetMark()->nContent,
+                                            INS_EMPTYEXPAND );
+                DELETEZ( pTxt );
+            }
+            else
+            {
+                // Inhalt wieder einfuegen. (erst pPos abmelden !!)
+                ULONG nMvNd = pPos->nNode.GetIndex();
+                xub_StrLen nMvCnt = pPos->nContent.GetIndex();
+                DELETEZ( pPos );
+                MoveFromUndoNds( *pDoc, nMvNd, nMvCnt, *pPam->GetMark() );
+            }
+            nNode = pPam->GetMark()->nNode.GetIndex();
+            nCntnt = pPam->GetMark()->nContent.GetIndex();
+
+            MovePtForward( *pPam, bMvBkwrd );
+            rUndoIter.pAktPam->Exchange();
+            if( pRedlData && IsRedlineOn( GetRedlineMode() ))
+            {
+                SwRedlineMode eOld = pDoc->GetRedlineMode();
+                pDoc->SetRedlineMode_intern( eOld & ~REDLINE_IGNORE );
+                pDoc->AppendRedline( new SwRedline( *pRedlData,
+                                            *rUndoIter.pAktPam ));
+                pDoc->SetRedlineMode_intern( eOld );
+            }
+            else if( !( REDLINE_IGNORE & GetRedlineMode() ) &&
+                    pDoc->GetRedlineTbl().Count() )
+                pDoc->SplitRedline( *rUndoIter.pAktPam );
+        }
+    }
+}
+
+
+void SwUndoInsert::Repeat( SwUndoIter& rUndoIter )
+{
+    rUndoIter.pLastUndoObj = this;
+    if( !nLen )
+        return;
+
+    SwDoc& rDoc = rUndoIter.GetDoc();
+    SwNodeIndex aNd( rDoc.GetNodes(), nNode );
+    SwCntntNode* pCNd = aNd.GetNode().GetCntntNode();;
+
+    if( !bIsAppend && 1 == nLen )       // >1 dann immer nur Text, ansonsten Grafik/OLE/Text/...
+    {
+        SwPaM aPaM( *pCNd, nCntnt );
+        aPaM.SetMark();
+        aPaM.Move(fnMoveBackward);
+        pCNd = aPaM.GetCntntNode();
+    }
+
+// Was passiert mit dem evt. selektierten Bereich ???
+
+    switch( pCNd->GetNodeType() )
+    {
+    case ND_TEXTNODE:
+        if( bIsAppend )
+            rDoc.AppendTxtNode( *rUndoIter.pAktPam->GetPoint() );
+        else
+        {
+            String aTxt( ((SwTxtNode*)pCNd)->GetTxt() );
+            BOOL bGroupUndo = rDoc.DoesGroupUndo();
+            rDoc.DoGroupUndo( FALSE );
+            rDoc.Insert( *rUndoIter.pAktPam, aTxt.Copy( nCntnt - nLen, nLen ));
+            rDoc.DoGroupUndo( bGroupUndo );
+            break;
+        }
+    case ND_GRFNODE:
+        {
+            SwGrfNode* pGrfNd = (SwGrfNode*)pCNd;
+            String sFile, sFilter;
+            if( pGrfNd->IsGrfLink() )
+                pGrfNd->GetFileFilterNms( &sFile, &sFilter );
+
+            rDoc.Insert( *rUndoIter.pAktPam, sFile, sFilter,
+                                &pGrfNd->GetGrf(),
+                                0/* Grafik-Collection*/ );
+        }
+        break;
+
+    case ND_OLENODE:
+        {
+            // StarView bietet noch nicht die Moeglichkeit ein StarOBJ zu kopieren
+            SvStorageRef aRef = new SvStorage( aEmptyStr );
+            SwOLEObj& rSwOLE = (SwOLEObj&)((SwOLENode*)pCNd)->GetOLEObj();
+            SvInPlaceObjectRef aNew((SvPersist*) rSwOLE.GetOleRef()->CopyObject( aRef ) );
+            rDoc.Insert( *rUndoIter.pAktPam, &aNew );
+            break;
+        }
+    }
+}
+
+
+/*  */
+
+SwUndoReplace::SwUndoReplace()
+    : SwUndo( UNDO_REPLACE ), nAktPos( USHRT_MAX )
+{
+}
+
+SwUndoReplace::~SwUndoReplace()
+{
+}
+
+void SwUndoReplace::Undo( SwUndoIter& rUndoIter )
+{
+    // war dieses nicht die letze Undo-Aktion, dann setze den
+    // Count neu
+    if( rUndoIter.pLastUndoObj != this )
+    {
+        nAktPos = aArr.Count();
+        rUndoIter.pLastUndoObj = this;
+        bOldIterFlag = rUndoIter.bWeiter;
+        rUndoIter.bWeiter = TRUE;
+    }
+
+    aArr[ --nAktPos ]->Undo( rUndoIter );
+
+    if( !nAktPos )      // alten Status wieder zurueck
+        rUndoIter.bWeiter = bOldIterFlag;
+}
+
+
+void SwUndoReplace::Redo( SwUndoIter& rUndoIter )
+{
+    // war dieses nicht die letze Undo-Aktion, dann setze den
+    // Count neu
+    if( rUndoIter.pLastUndoObj != this )
+    {
+        ASSERT( !nAktPos, "Redo ohne vorheriges Undo??" );
+        rUndoIter.pLastUndoObj = this;
+        bOldIterFlag = rUndoIter.bWeiter;
+        rUndoIter.bWeiter = TRUE;
+    }
+
+    aArr[ nAktPos ]->Redo( rUndoIter );
+
+    if( ++nAktPos >= aArr.Count() ) // alten Status wieder zurueck
+    {
+        nAktPos = USHRT_MAX;
+        rUndoIter.bWeiter = bOldIterFlag;
+    }
+}
+
+
+void SwUndoReplace::AddEntry( const SwPaM& rPam, const String& rInsert,
+                                BOOL bRegExp )
+{
+    _UnReplaceData* pNew = new _UnReplaceData( rPam, rInsert, bRegExp );
+    aArr.C40_INSERT(_UnReplaceData, pNew, aArr.Count() );
+}
+
+void SwUndoReplace::SetEntryEnd( const SwPaM& rPam )
+{
+    _UnReplaceData* pEntry = aArr[ aArr.Count()-1 ];
+    pEntry->SetEnd( rPam );
+}
+
+_UnReplaceData::_UnReplaceData( const SwPaM& rPam, const String& rIns,
+                                BOOL bRgExp )
+    : nOffset( 0 ), sIns( rIns )
+{
+    bRegExp = bRgExp;
+
+    const SwNodes& rNds = rPam.GetDoc()->GetNodes();
+    const SwPosition *pStt = rPam.Start(),
+                    *pEnd = rPam.GetPoint() == pStt
+                        ? rPam.GetMark()
+                        : rPam.GetPoint();
+
+    nSttNd = nEndNd = pStt->nNode.GetIndex();
+    nSttCnt = pStt->nContent.GetIndex();
+    nSelEnd = nEndCnt = pEnd->nContent.GetIndex();
+
+    bSplitNext = nSttNd != pEnd->nNode.GetIndex();
+
+    SwTxtNode* pNd = pStt->nNode.GetNode().GetTxtNode();
+    ASSERT( pNd, "wo ist der TextNode" );
+
+    pHistory = new SwHistory;
+    DelCntntIndex( *rPam.GetMark(), *rPam.GetPoint() );
+
+    nSetPos = pHistory->Count();
+
+    ULONG nNewPos = pStt->nNode.GetIndex();
+    nOffset = nSttNd - nNewPos;
+
+    if( pNd->GetpSwpHints() )
+        pHistory->CopyAttr( pNd->GetpSwpHints(), nNewPos, 0,
+                            pNd->GetTxt().Len(), TRUE );
+
+    if( bSplitNext )
+    {
+        if( pNd->GetpSwAttrSet() )
+            pHistory->CopyFmtAttr( *pNd->GetpSwAttrSet(), nNewPos );
+        pHistory->Add( pNd->GetTxtColl(), nNewPos, ND_TEXTNODE );
+
+        SwTxtNode* pNext = pEnd->nNode.GetNode().GetTxtNode();
+        ULONG nTmp = pNext->GetIndex();
+        pHistory->CopyAttr( pNext->GetpSwpHints(), nTmp, 0,
+                            pNext->GetTxt().Len(), TRUE );
+        if( pNext->GetpSwAttrSet() )
+            pHistory->CopyFmtAttr( *pNext->GetpSwAttrSet(), nTmp );
+        pHistory->Add( pNext->GetTxtColl(),nTmp, ND_TEXTNODE );
+    }
+
+    if( !pHistory->Count() )
+        delete pHistory, pHistory = 0;
+
+    xub_StrLen nECnt = bSplitNext ? pNd->GetTxt().Len() : pEnd->nContent.GetIndex();
+    sOld = pNd->GetTxt().Copy( nSttCnt, nECnt - nSttCnt );
+}
+
+_UnReplaceData::~_UnReplaceData()
+{
+}
+
+void _UnReplaceData::Undo( SwUndoIter& rIter )
+{
+    SwDoc* pDoc = &rIter.GetDoc();
+    SwPaM& rPam = *rIter.pAktPam;
+    rPam.DeleteMark();
+
+    SwTxtNode* pNd = pDoc->GetNodes()[ nSttNd - nOffset ]->GetTxtNode();
+    ASSERT( pNd, "Wo ist der TextNode geblieben?" )
+
+    SwAutoCorrExceptWord* pACEWord = pDoc->GetAutoCorrExceptWord();
+    if( pACEWord )
+    {
+        if( 1 == sIns.Len() && 1 == sOld.Len() )
+        {
+            SwPosition aPos( *pNd ); aPos.nContent.Assign( pNd, nSttCnt );
+            pACEWord->CheckChar( aPos, sOld.GetChar( 0 ) );
+        }
+        pDoc->SetAutoCorrExceptWord( 0 );
+    }
+
+    SwIndex aIdx( pNd, nSttCnt );
+    if( nSttNd == nEndNd )
+    {
+        pNd->Erase( aIdx, sIns.Len() );
+/*      if( bSplitNext )
+        {
+            SwPosition aPos( *pNd, aIdx );
+            pDoc->SplitNode( aPos, FALSE );
+            pNd = pDoc->GetNodes()[ nSttNd - nOffset ]->GetTxtNode();
+            aIdx.Assign( pNd, nSttCnt );
+        }
+*/  }
+    else
+    {
+        rPam.GetPoint()->nNode = *pNd;
+        rPam.GetPoint()->nContent.Assign( pNd, nSttCnt );
+        rPam.SetMark();
+        rPam.GetPoint()->nNode = nEndNd - nOffset;
+        rPam.GetPoint()->nContent.Assign( rPam.GetCntntNode(), nEndCnt );
+
+        pDoc->DeleteAndJoin( rPam );
+        rPam.DeleteMark();
+        pNd = rPam.GetNode()->GetTxtNode();
+        ASSERT( pNd, "Wo ist der TextNode geblieben?" );
+        aIdx.Assign( pNd, nSttCnt );
+    }
+
+    if( bSplitNext )
+    {
+        SwPosition aPos( *pNd, aIdx );
+        pDoc->SplitNode( aPos, FALSE );
+        pNd = pDoc->GetNodes()[ nSttNd - nOffset ]->GetTxtNode();
+        aIdx.Assign( pNd, nSttCnt );
+    }
+
+    if( sOld.Len() )
+        pNd->Insert( sOld, aIdx );
+
+    if( pHistory )
+    {
+        if( pNd->GetpSwpHints() )
+            pNd->ClearSwpHintsArr( FALSE );
+
+        pHistory->TmpRollback( pDoc, nSetPos, FALSE );
+        if( nSetPos )       // es gab Fussnoten/FlyFrames
+        {
+            // gibts ausser diesen noch andere ?
+            if( nSetPos < pHistory->Count() )
+            {
+                // dann sicher die Attribute anderen Attribute
+                SwHistory aHstr;
+                aHstr.Move( 0, pHistory, nSetPos );
+                pHistory->Rollback( pDoc );
+                pHistory->Move( 0, &aHstr );
+            }
+            else
+            {
+                pHistory->Rollback( pDoc );
+                DELETEZ( pHistory );
+            }
+        }
+    }
+
+    rPam.GetPoint()->nNode = nSttNd;
+    rPam.GetPoint()->nContent = aIdx;
+}
+
+void _UnReplaceData::Redo( SwUndoIter& rIter )
+{
+    SwDoc& rDoc = rIter.GetDoc();
+    BOOL bUndo = rDoc.DoesUndo();
+    rDoc.DoUndo( FALSE );
+
+    SwPaM& rPam = *rIter.pAktPam;
+    rPam.DeleteMark();
+    rPam.GetPoint()->nNode = nSttNd;
+
+    SwTxtNode* pNd = rPam.GetPoint()->nNode.GetNode().GetTxtNode();
+    ASSERT( pNd, "Wo ist der TextNode geblieben?" )
+    rPam.GetPoint()->nContent.Assign( pNd, nSttCnt );
+    rPam.SetMark();
+    if( bSplitNext )
+    {
+        rPam.GetPoint()->nNode = nSttNd + 1;
+        pNd = rPam.GetPoint()->nNode.GetNode().GetTxtNode();
+    }
+    rPam.GetPoint()->nContent.Assign( pNd, nSelEnd );
+
+    if( pHistory )
+    {
+        SwHistory* pSave = pHistory;
+        SwHistory aHst;
+        pHistory = &aHst;
+        DelCntntIndex( *rPam.GetMark(), *rPam.GetPoint() );
+        nSetPos = pHistory->Count();
+
+        pHistory = pSave;
+        pHistory->Move( 0, &aHst );
+    }
+    else
+    {
+        pHistory = new SwHistory;
+        DelCntntIndex( *rPam.GetMark(), *rPam.GetPoint() );
+        nSetPos = pHistory->Count();
+        if( !nSetPos )
+            delete pHistory, pHistory = 0;
+    }
+
+    rDoc.Replace( rPam, sIns, bRegExp );
+    rPam.DeleteMark();
+    rDoc.DoUndo( bUndo );
+}
+
+void _UnReplaceData::SetEnd( const SwPaM& rPam )
+{
+    if( rPam.GetPoint()->nNode != rPam.GetMark()->nNode )
+    {
+        // es wurden mehrere Absaetze eingefuegt
+        const SwPosition* pEnd = rPam.End();
+        nEndNd = nOffset + pEnd->nNode.GetIndex();
+        nEndCnt = pEnd->nContent.GetIndex();
+    }
+}
+
+/*  */
+
+
+SwUndoReRead::SwUndoReRead( const SwPaM& rPam, const SwGrfNode& rGrfNd )
+    : SwUndo( UNDO_REREAD ), nPos( rPam.GetPoint()->nNode.GetIndex() )
+{
+    SaveGraphicData( rGrfNd );
+}
+
+
+SwUndoReRead::~SwUndoReRead()
+{
+    delete pGrf;
+    delete pNm;
+    delete pFltr;
+}
+
+
+void SwUndoReRead::SetAndSave( SwUndoIter& rIter )
+{
+    SwDoc& rDoc = rIter.GetDoc();
+    SwGrfNode* pGrfNd = rDoc.GetNodes()[ nPos ]->GetGrfNode();
+
+    if( !pGrfNd )
+        return ;
+
+        // die alten Werte zwischen speichern
+    Graphic* pOldGrf = pGrf;
+    String* pOldNm = pNm;
+    String* pOldFltr = pFltr;
+    USHORT nOldMirr = nMirr;
+
+    SaveGraphicData( *pGrfNd );
+    if( pOldNm )
+    {
+        pGrfNd->ReRead( *pOldNm, pFltr ? *pFltr : aEmptyStr, 0, TRUE );
+        delete pOldNm;
+        delete pOldFltr;
+    }
+    else
+    {
+        pGrfNd->ReRead( aEmptyStr, aEmptyStr, pOldGrf, TRUE );
+        delete pOldGrf;
+    }
+
+    if( RES_DONT_MIRROR_GRF != nOldMirr )
+        pGrfNd->SetAttr( SwMirrorGrf() );
+}
+
+
+void SwUndoReRead::Undo( SwUndoIter& rIter )
+{
+    SetAndSave( rIter );
+}
+
+
+void SwUndoReRead::Redo( SwUndoIter& rIter )
+{
+    SetAndSave( rIter );
+}
+
+
+void SwUndoReRead::SaveGraphicData( const SwGrfNode& rGrfNd )
+{
+    if( rGrfNd.IsGrfLink() )
+    {
+        pNm = new String;
+        pFltr = new String;
+        rGrfNd.GetFileFilterNms( pNm, pFltr );
+        pGrf = 0;
+    }
+    else
+    {
+        ((SwGrfNode&)rGrfNd).SwapIn( TRUE );
+        pGrf = new Graphic( rGrfNd.GetGrf() );
+        pNm = pFltr = 0;
+    }
+    nMirr = rGrfNd.GetSwAttrSet().GetMirrorGrf().GetValue();
+}
+
+/*  */
+
+SwUndoInsertLabel::SwUndoInsertLabel( const SwLabelType eTyp,
+                                    const String &rTxt, const BOOL bBef,
+                                    const USHORT nId, const BOOL bCpyBorder )
+    : SwUndo( UNDO_INSERTLABEL ), eType( eTyp ), sText( rTxt ),
+    bBefore( bBef ), nFldId( nId ), aPos( 0, 0 ), nLayerId( 0 ),
+    bCpyBrd( bCpyBorder )
+{
+    bUndoKeep = FALSE;
+    OBJECT.pUndoFly = 0;
+    OBJECT.pUndoAttr = 0;
+}
+
+SwUndoInsertLabel::~SwUndoInsertLabel()
+{
+    if( LTYPE_OBJECT == eType || LTYPE_DRAW == eType )
+    {
+        delete OBJECT.pUndoFly;
+        delete OBJECT.pUndoAttr;
+    }
+    else
+        delete NODE.pUndoInsNd;
+}
+
+void SwUndoInsertLabel::Undo( SwUndoIter& rIter )
+{
+    SwDoc& rDoc = rIter.GetDoc();
+
+    if( LTYPE_OBJECT == eType || LTYPE_DRAW == eType )
+    {
+        ASSERT( OBJECT.pUndoAttr && OBJECT.pUndoFly, "Pointer nicht initialisiert" )
+        SwFrmFmt* pFmt;
+        SdrObject *pSdrObj;
+        if( OBJECT.pUndoAttr &&
+            0 != (pFmt = (SwFrmFmt*)OBJECT.pUndoAttr->GetFmt( rDoc )) &&
+            ( LTYPE_DRAW != eType ||
+              0 != (pSdrObj = pFmt->FindSdrObject()) ) )
+        {
+            OBJECT.pUndoAttr->Undo( rIter );
+            OBJECT.pUndoFly->Undo( rIter );
+            if( LTYPE_DRAW == eType )
+            {
+                pSdrObj->SetRelativePos( aPos );
+                pSdrObj->SetLayer( nLayerId );
+            }
+        }
+    }
+    else if( NODE.nNode )
+    {
+        if ( eType == LTYPE_TABLE && bUndoKeep )
+        {
+            SwTableNode *pNd = rDoc.GetNodes()[
+                        rDoc.GetNodes()[NODE.nNode-1]->StartOfSectionIndex()]->GetTableNode();
+            if ( pNd )
+                pNd->GetTable().GetFrmFmt()->ResetAttr( RES_KEEP );
+        }
+        SwPaM aPam( *rIter.pAktPam->GetPoint() );
+        aPam.GetPoint()->nNode = NODE.nNode;
+        aPam.SetMark();
+        aPam.GetPoint()->nNode = NODE.nNode + 1;
+        NODE.pUndoInsNd = new SwUndoDelete( aPam, TRUE );
+    }
+}
+
+
+void SwUndoInsertLabel::Redo( SwUndoIter& rIter )
+{
+    SwDoc& rDoc = rIter.GetDoc();
+
+    if( LTYPE_OBJECT == eType || LTYPE_DRAW == eType )
+    {
+        ASSERT( OBJECT.pUndoAttr && OBJECT.pUndoFly, "Pointer nicht initialisiert" )
+        SwFrmFmt* pFmt;
+        SdrObject *pSdrObj;
+        if( OBJECT.pUndoAttr &&
+            0 != (pFmt = (SwFrmFmt*)OBJECT.pUndoAttr->GetFmt( rDoc )) &&
+            ( LTYPE_DRAW != eType ||
+              0 != (pSdrObj = pFmt->FindSdrObject()) ) )
+        {
+            OBJECT.pUndoFly->Redo( rIter );
+            OBJECT.pUndoAttr->Redo( rIter );
+            if( LTYPE_DRAW == eType )
+            {
+                pSdrObj->SetRelativePos( Point(0,0) );
+                pSdrObj->SetLayer( nLayerId );
+                if( pSdrObj->GetLayer() == rDoc.GetHellId() )
+                    pSdrObj->SetLayer( rDoc.GetHeavenId() );
+            }
+        }
+    }
+    else if( NODE.pUndoInsNd )
+    {
+        if ( eType == LTYPE_TABLE && bUndoKeep )
+        {
+            SwTableNode *pNd = rDoc.GetNodes()[
+                        rDoc.GetNodes()[NODE.nNode-1]->StartOfSectionIndex()]->GetTableNode();
+            if ( pNd )
+                pNd->GetTable().GetFrmFmt()->SetAttr( SvxFmtKeepItem(TRUE) );
+        }
+        NODE.pUndoInsNd->Undo( rIter );
+        delete NODE.pUndoInsNd, NODE.pUndoInsNd = 0;
+    }
+}
+
+void SwUndoInsertLabel::Repeat( SwUndoIter& rIter )
+{
+    SwDoc& rDoc = rIter.GetDoc();
+    const SwPosition& rPos = *rIter.pAktPam->GetPoint();
+
+    ULONG nIdx = 0;
+
+    SwCntntNode* pCNd = rPos.nNode.GetNode().GetCntntNode();
+    if( pCNd )
+        switch( eType )
+        {
+        case LTYPE_TABLE:
+            {
+                const SwTableNode* pTNd = pCNd->FindTableNode();
+                if( pTNd )
+                    nIdx = pTNd->GetIndex();
+            }
+            break;
+
+        case LTYPE_FLY:
+        case LTYPE_OBJECT:
+            {
+                SwFlyFrm* pFly;
+                SwCntntFrm *pCnt = pCNd->GetFrm();
+                if( pCnt && 0 != ( pFly = pCnt->FindFlyFrm() ) )
+                    nIdx = pFly->GetFmt()->GetCntnt().GetCntntIdx()->GetIndex();
+            }
+            break;
+        }
+
+    if( nIdx )
+    {
+        rDoc.InsertLabel( eType, sText, bBefore, nFldId, nIdx, bCpyBrd );
+    }
+}
+
+void SwUndoInsertLabel::SetFlys( SwFrmFmt& rOldFly, SfxItemSet& rChgSet,
+                                SwFrmFmt& rNewFly )
+{
+    if( LTYPE_OBJECT == eType || LTYPE_DRAW == eType )
+    {
+        _UndoFmtAttr aTmp( rOldFly, FALSE );
+        rOldFly.SetAttr( rChgSet );
+        if( aTmp.pUndo )
+            OBJECT.pUndoAttr = aTmp.pUndo;
+        OBJECT.pUndoFly = new SwUndoInsLayFmt( &rNewFly );
+    }
+}
+
+void SwUndoInsertLabel::SetDrawObj( const Point& rPos, BYTE nLId )
+{
+    if( LTYPE_DRAW == eType )
+    {
+        aPos = rPos;
+        nLayerId = nLId;
+    }
+}
+
+/*************************************************************************
+
+      Source Code Control System - Header
+
+      $Header: /zpool/svn/migration/cvs_rep_09_09_08/code/sw/source/core/undo/unins.cxx,v 1.1.1.1 2000-09-19 00:08:27 hr Exp $
+
+      Source Code Control System - Update
+
+      $Log: not supported by cvs2svn $
+      Revision 1.65  2000/09/18 16:04:29  willem.vandorp
+      OpenOffice header added.
+
+      Revision 1.64  2000/05/19 12:53:39  jp
+      use WordSelection class for check chars
+
+      Revision 1.63  2000/05/09 10:04:17  jp
+      Changes for Unicode
+
+      Revision 1.62  2000/02/11 14:35:15  hr
+      #70473# changes for unicode ( patched by automated patchtool )
+
+      Revision 1.61  1999/06/25 15:26:42  JP
+      Bug #67155#: UndoInsert::Undo - set contentindex of pam into the node
+
+
+      Rev 1.60   25 Jun 1999 17:26:42   JP
+   Bug #67155#: UndoInsert::Undo - set contentindex of pam into the node
+
+      Rev 1.59   08 Jun 1999 21:31:50   JP
+   Bug #66732#: InsertLabel: weiteres Flag
+
+      Rev 1.58   01 Apr 1999 13:19:38   JP
+   Task #64260#: Suchen&Ersetzen - Absatzumbrueche als Ersetzung zulassen
+
+      Rev 1.57   27 Jan 1999 18:52:34   JP
+   Task #61014#: FindSdrObject/FindContactObject als Methoden vom SwFrmFmt
+
+      Rev 1.56   10 Dec 1998 09:53:42   MIB
+   #60060#: Beschriftungen fuer Zeichen-Objekte
+
+      Rev 1.55   12 Nov 1998 19:16:58   JP
+   Bug #59413#: beim Replace die Autokorrektur beachten
+
+      Rev 1.54   13 Jul 1998 19:40:36   JP
+   Bug #52740#: _UnReplaceData::Undo - Text vorm Splitten loeschen
+
+      Rev 1.53   02 Apr 1998 15:13:30   JP
+   Redo: Undo-Flag wird schon von der EditShell abgeschaltet
+
+      Rev 1.52   14 Mar 1998 12:15:54   JP
+   Bug #48266#: AppendTxtNode - Redlining beachten
+
+      Rev 1.51   16 Feb 1998 13:23:28   HR
+   C40_INSERT
+
+      Rev 1.50   29 Jan 1998 21:31:52   JP
+   GetEndOfIcons ersetzt durch GetEndOfExtras, das auf GetEndOfRedlines mappt
+
+      Rev 1.49   22 Jan 1998 20:53:10   JP
+   CTOR des SwPaM umgestellt
+
+      Rev 1.48   08 Jan 1998 20:56:00   JP
+   SwDoc::GetRedlineTbl returnt jetzt eine Referenz
+
+      Rev 1.47   19 Dec 1997 12:14:22   JP
+   Undo: Redlining beachten
+
+      Rev 1.46   20 Nov 1997 18:22:42   MA
+   includes
+
+      Rev 1.45   12 Nov 1997 18:54:34   MA
+   chg: Keep fuer Label bei Tabelle inkl. undo
+
+      Rev 1.44   03 Nov 1997 13:06:20   MA
+   precomp entfernt
+
+      Rev 1.43   13 Oct 1997 19:07:56   JP
+   Replace: Attribute merken, bei RegExp kann ein Node geloescht werden
+
+      Rev 1.42   13 Oct 1997 15:54:14   JP
+   pNext vom Ring wurde privat; zugriff ueber GetNext()
+
+      Rev 1.41   09 Oct 1997 15:45:30   JP
+   Umstellung NodeIndex/-Array/BigPtrArray
+
+      Rev 1.40   16 Sep 1997 10:53:38   JP
+   Bug #41879#: UndoReplace veraendert
+
+      Rev 1.39   11 Sep 1997 12:35:02   JP
+   Bug #41975#: InsertLabel wurde undofaehig
+
+      Rev 1.38   16 Jun 1997 11:20:22   JP
+   Undo: bei Append nicht -1
+
+      Rev 1.37   13 Jun 1997 13:51:38   JP
+   AppendTxtNode ist auch Undofaehig
+
+      Rev 1.36   11 Jun 1997 10:44:48   JP
+   pure virtual Repeat wurde zur virtual Methode, Segment Pragma entfernt
+
+      Rev 1.35   29 Oct 1996 14:54:14   JP
+   am Doc ist das NodesArray nur noch ueber Get..() zugaenglich
+
+      Rev 1.34   12 Sep 1996 14:16:02   JP
+   UndoReRead: Grafik immer rein swappen
+
+      Rev 1.33   28 Nov 1995 19:41:24   JP
+   MemPool impl. ins swtypes.cxx verschoben (StartUp Optimierung)
+
+      Rev 1.32   24 Nov 1995 17:14:00   OM
+   PCH->PRECOMPILED
+
+      Rev 1.31   17 Nov 1995 10:23:16   MA
+   Segmentierung
+
+      Rev 1.30   16 Nov 1995 19:46:54   MA
+   Segmentierung
+
+      Rev 1.29   31 Aug 1995 19:48:10   JP
+   neu: SwUndoReRead - Undo fuer Grafik ersetzen
+
+      Rev 1.28   08 Aug 1995 21:36:34   ER
+   impl_fixedmempool_newdel muss vor seg_eofglobals
+
+      Rev 1.27   22 Jun 1995 19:33:20   JP
+   virt. Methode GetUndoRange vernichtet, Objecte rufen jetzt die Basis-Klasse
+
+      Rev 1.26   19 Jun 1995 19:42:56   JP
+   Grafik-Node: Umstellung auf SvBaseLinks
+
+      Rev 1.25   16 Mar 1995 10:25:38   KH
+   Anpassung CFront
+
+      Rev 1.24   04 Mar 1995 13:30:46   MA
+   unnoetiges SEXPORT entfernt.
+
+      Rev 1.23   01 Mar 1995 11:21:08   MA
+   include von so2 aufgeloest.
+
+      Rev 1.22   23 Feb 1995 23:02:58   ER
+   sexport
+
+      Rev 1.21   08 Feb 1995 23:53:04   ER
+   undo.hxx -> swundo.hxx wegen solar undo.hxx
+
+      Rev 1.20   03 Feb 1995 12:20:56   MA
+   Undo fuer OleNode.
+
+      Rev 1.19   01 Feb 1995 16:40:22   MA
+   1.Runde Ole2 client.
+
+      Rev 1.18   15 Dec 1994 20:48:08   SWG
+   *ARR* Ersetzungen, svmem, __far_data etc.
+
+      Rev 1.17   25 Oct 1994 14:50:50   MA
+   PreHdr.
+
+      Rev 1.16   14 Sep 1994 19:00:50   MA
+   FixedMemPool eingesetzt.
+
+      Rev 1.15   04 Aug 1994 13:30:50   SWG
+   swg32: SED Size to SSize, LSize to Size etc.
+
+      Rev 1.14   04 Aug 1994 13:29:28   SWG
+   swg32: SED SSize to SSize, Size to SSize etc.
+
+      Rev 1.13   15 Mar 1994 11:33:58   JP
+   Undo-Insert: leere Hints aufspannen.
+
+      Rev 1.12   12 Mar 1994 16:54:18   JP
+   neu: Undo-Replace
+
+      Rev 1.11   02 Mar 1994 19:48:40   MI
+   Underscore im Namen der #pragmas
+
+      Rev 1.10   17 Feb 1994 08:31:14   MI
+   SEG_FUNCDEFS ausgefuellt
+
+      Rev 1.9   16 Feb 1994 13:21:40   MI
+   Pragmas zurechtgerueckt
+
+*************************************************************************/
+
diff --git a/sw/source/core/undo/unmove.cxx b/sw/source/core/undo/unmove.cxx
new file mode 100644
index 000000000000..01ac1b012a15
--- /dev/null
+++ b/sw/source/core/undo/unmove.cxx
@@ -0,0 +1,505 @@
+/*************************************************************************
+ *
+ *  $RCSfile: unmove.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:28 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include            // fuer die UndoIds
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _UNDOBJ_HXX
+#include 
+#endif
+#ifndef _ROLBCK_HXX
+#include 
+#endif
+
+
+inline SwDoc& SwUndoIter::GetDoc() const { return *pAktPam->GetDoc(); }
+
+// MOVE
+
+SwUndoMove::SwUndoMove( const SwPaM& rRange, const SwPosition& rMvPos )
+    : SwUndo( UNDO_MOVE ), SwUndRng( rRange ),
+    nMvDestNode( rMvPos.nNode.GetIndex() ),
+    nMvDestCntnt( rMvPos.nContent.GetIndex() )
+{
+    bMoveRange = bJoinNext = bJoinPrev = FALSE;
+
+    // StartNode vorm loeschen von Fussnoten besorgen!
+    SwDoc* pDoc = rRange.GetDoc();
+    SwTxtNode* pTxtNd = pDoc->GetNodes()[ nSttNode ]->GetTxtNode();
+    SwTxtNode* pEndTxtNd = pDoc->GetNodes()[ nEndNode ]->GetTxtNode();
+
+    pHistory = new SwHistory;
+
+    if( pTxtNd )
+    {
+        pHistory->Add( pTxtNd->GetTxtColl(), nSttNode, ND_TEXTNODE );
+        if( pTxtNd->GetpSwpHints() )
+            pHistory->CopyAttr( pTxtNd->GetpSwpHints(), nSttNode,
+                                0, pTxtNd->GetTxt().Len(), FALSE );
+        if( pTxtNd->GetpSwAttrSet() )
+            pHistory->CopyFmtAttr( *pTxtNd->GetpSwAttrSet(), nSttNode );
+    }
+    if( pEndTxtNd && pEndTxtNd != pTxtNd )
+    {
+        pHistory->Add( pEndTxtNd->GetTxtColl(), nEndNode, ND_TEXTNODE );
+        if( pEndTxtNd->GetpSwpHints() )
+            pHistory->CopyAttr( pEndTxtNd->GetpSwpHints(), nEndNode,
+                                0, pEndTxtNd->GetTxt().Len(), FALSE );
+        if( pEndTxtNd->GetpSwAttrSet() )
+            pHistory->CopyFmtAttr( *pEndTxtNd->GetpSwAttrSet(), nEndNode );
+    }
+
+    if( 0 != (pTxtNd = rRange.GetDoc()->GetNodes()[ rMvPos.nNode ]->GetTxtNode() ))
+    {
+        pHistory->Add( pTxtNd->GetTxtColl(), nMvDestNode, ND_TEXTNODE );
+        if( pTxtNd->GetpSwpHints() )
+            pHistory->CopyAttr( pTxtNd->GetpSwpHints(), nMvDestNode,
+                                0, pTxtNd->GetTxt().Len(), FALSE );
+        if( pTxtNd->GetpSwAttrSet() )
+            pHistory->CopyFmtAttr( *pTxtNd->GetpSwAttrSet(), nMvDestNode );
+    }
+
+
+    nFtnStt = pHistory->Count();
+    DelFtn( rRange );
+
+    if( pHistory && !pHistory->Count() )
+        DELETEZ( pHistory );
+}
+
+
+SwUndoMove::SwUndoMove( SwDoc* pDoc, const SwNodeRange& rRg,
+                        const SwNodeIndex& rMvPos )
+    : SwUndo( UNDO_MOVE ),
+    nMvDestNode( rMvPos.GetIndex() )
+{
+    bMoveRange = TRUE;
+    bJoinNext = bJoinPrev = FALSE;
+
+    nSttCntnt = nEndCntnt = nMvDestCntnt = STRING_MAXLEN;
+
+    nSttNode = rRg.aStart.GetIndex();
+    nEndNode = rRg.aEnd.GetIndex();
+
+//  DelFtn( rRange );
+
+    // wird aus dem CntntBereich in den Sonderbereich verschoben ?
+    ULONG nCntntStt = pDoc->GetNodes().GetEndOfAutotext().GetIndex();
+    if( nMvDestNode < nCntntStt && rRg.aStart.GetIndex() > nCntntStt )
+    {
+        // loesche alle Fussnoten. Diese sind dort nicht erwuenscht.
+        SwPosition aPtPos( rRg.aEnd );
+        SwCntntNode* pCNd = rRg.aEnd.GetNode().GetCntntNode();
+        if( pCNd )
+            aPtPos.nContent.Assign( pCNd, pCNd->Len() );
+        SwPosition aMkPos( rRg.aStart );
+        if( 0 != ( pCNd = aMkPos.nNode.GetNode().GetCntntNode() ))
+            aMkPos.nContent.Assign( pCNd, 0 );
+
+        DelCntntIndex( aMkPos, aPtPos, SwUndoSaveCntnt::DELCNT_FTN );
+
+        if( pHistory && !pHistory->Count() )
+            DELETEZ( pHistory );
+    }
+
+    nFtnStt = 0;
+}
+
+
+
+void SwUndoMove::SetDestRange( const SwPaM& rRange,
+                                const SwPosition& rInsPos,
+                                BOOL bJoin, BOOL bCorrPam )
+{
+    const SwPosition *pStt = rRange.Start(),
+                    *pEnd = rRange.GetPoint() == pStt
+                        ? rRange.GetMark()
+                        : rRange.GetPoint();
+
+    nDestSttNode    = pStt->nNode.GetIndex();
+    nDestSttCntnt   = pStt->nContent.GetIndex();
+    nDestEndNode    = pEnd->nNode.GetIndex();
+    nDestEndCntnt   = pEnd->nContent.GetIndex();
+
+    nInsPosNode     = rInsPos.nNode.GetIndex();
+    nInsPosCntnt    = rInsPos.nContent.GetIndex();
+
+    if( bCorrPam )
+    {
+        nDestSttNode--;
+        nDestEndNode--;
+    }
+
+    bJoinNext = nDestSttNode != nDestEndNode &&
+                pStt->nNode.GetNode().GetTxtNode() &&
+                pEnd->nNode.GetNode().GetTxtNode();
+    bJoinPrev = bJoin;
+}
+
+
+void SwUndoMove::SetDestRange( const SwNodeIndex& rStt,
+                                const SwNodeIndex& rEnd,
+                                const SwNodeIndex& rInsPos )
+{
+    nDestSttNode = rStt.GetIndex();
+    nDestEndNode = rEnd.GetIndex();
+    if( nDestSttNode > nDestEndNode )
+    {
+        nDestSttNode = nDestEndNode;
+        nDestEndNode = rStt.GetIndex();
+    }
+    nInsPosNode  = rInsPos.GetIndex();
+
+    nDestSttCntnt = nDestEndCntnt = nInsPosCntnt = STRING_MAXLEN;
+}
+
+
+void SwUndoMove::Undo( SwUndoIter& rUndoIter )
+{
+    SwDoc* pDoc = &rUndoIter.GetDoc();
+    BOOL bUndo = pDoc->DoesUndo();
+    pDoc->DoUndo( FALSE );
+
+    // Block, damit aus diesem gesprungen werden kann
+    do {
+        // erzeuge aus den Werten die Insert-Position und den Bereich
+        SwNodeIndex aIdx( pDoc->GetNodes(), nDestSttNode );
+
+        if( bMoveRange )
+        {
+            // nur ein Move mit SwRange
+            SwNodeRange aRg( aIdx, aIdx );
+            aRg.aEnd = nDestEndNode;
+            aIdx = nInsPosNode;
+            if( !pDoc->Move( aRg, aIdx ) )
+                break;
+        }
+        else
+        {
+            SwPaM aPam( aIdx.GetNode(), nDestSttCntnt,
+                        *pDoc->GetNodes()[ nDestEndNode ], nDestEndCntnt );
+
+            RemoveIdxFromRange( aPam, FALSE );
+
+            SwPosition aPos( *pDoc->GetNodes()[ nInsPosNode] );
+            SwCntntNode* pCNd = aPos.nNode.GetNode().GetCntntNode();
+            aPos.nContent.Assign( pCNd, nInsPosCntnt );
+
+            if( pCNd->GetpSwAttrSet() )
+                pCNd->ResetAllAttr();
+
+            if( pCNd->IsTxtNode() && ((SwTxtNode*)pCNd)->GetpSwpHints() )
+                ((SwTxtNode*)pCNd)->ClearSwpHintsArr( FALSE, FALSE );
+
+            // an der InsertPos erstmal alle Attribute entfernen,
+            if( !pDoc->Move( aPam, aPos ) )
+                break;
+
+            aPam.Exchange();
+            aPam.DeleteMark();
+//          pDoc->ResetAttr( aPam, FALSE );
+            if( aPam.GetNode()->IsCntntNode() )
+                aPam.GetNode()->GetCntntNode()->ResetAllAttr();
+            // der Pam wird jetzt aufgegeben.
+        }
+
+        SwTxtNode* pTxtNd = aIdx.GetNode().GetTxtNode();
+        if( bJoinNext )
+        {
+            {
+                RemoveIdxRel( aIdx.GetIndex() + 1, SwPosition( aIdx,
+                        SwIndex( pTxtNd, pTxtNd->GetTxt().Len() ) ) );
+            }
+            // sind keine Pams mehr im naechsten TextNode
+            pTxtNd->JoinNext();
+        }
+
+        if( bJoinPrev && pTxtNd->CanJoinPrev( &aIdx ) )
+        {
+            // ?? sind keine Pams mehr im naechsten TextNode ??
+            pTxtNd = aIdx.GetNode().GetTxtNode();
+            {
+                RemoveIdxRel( aIdx.GetIndex() + 1, SwPosition( aIdx,
+                        SwIndex( pTxtNd, pTxtNd->GetTxt().Len() ) ) );
+            }
+            pTxtNd->JoinNext();
+        }
+
+    } while( FALSE );
+
+    if( pHistory )
+    {
+        if( nFtnStt != pHistory->Count() )
+            pHistory->Rollback( pDoc, nFtnStt );
+        pHistory->TmpRollback( pDoc, 0 );
+        pHistory->SetTmpEnd( pHistory->Count() );
+    }
+
+    pDoc->DoUndo( bUndo );
+
+    // setze noch den Cursor auf den Undo-Bereich
+    if( !bMoveRange )
+        SetPaM( rUndoIter );
+}
+
+
+void SwUndoMove::Redo( SwUndoIter& rUndoIter )
+{
+    SwPaM* pPam = rUndoIter.pAktPam;
+    SwDoc& rDoc = *pPam->GetDoc();
+
+    SwNodes& rNds = rDoc.GetNodes();
+    SwNodeIndex aIdx( rNds, nMvDestNode );
+
+    if( bMoveRange )
+    {
+        // nur ein Move mit SwRange
+        SwNodeRange aRg( rNds, nSttNode, rNds, nEndNode );
+        rDoc.Move( aRg, aIdx );
+    }
+    else
+    {
+        SwPaM aPam( *pPam->GetPoint() );
+        SetPaM( aPam );
+        SwPosition aMvPos( aIdx, SwIndex( aIdx.GetNode().GetCntntNode(),
+                                        nMvDestCntnt ));
+
+        DelFtn( aPam );
+        RemoveIdxFromRange( aPam, FALSE );
+
+        aIdx = aPam.Start()->nNode;
+        BOOL bJoinTxt = aIdx.GetNode().IsTxtNode();
+
+        aIdx--;
+        rDoc.Move( aPam, aMvPos );
+
+        if( nSttNode != nEndNode && bJoinTxt )
+        {
+            aIdx++;
+            SwTxtNode * pTxtNd = aIdx.GetNode().GetTxtNode();
+            if( pTxtNd && pTxtNd->CanJoinNext() )
+            {
+                {
+                    RemoveIdxRel( aIdx.GetIndex() + 1, SwPosition( aIdx,
+                            SwIndex( pTxtNd, pTxtNd->GetTxt().Len() ) ) );
+                }
+                pTxtNd->JoinNext();
+            }
+        }
+        *pPam->GetPoint() = *aPam.GetPoint();
+        pPam->SetMark();
+        *pPam->GetMark() = *aPam.GetMark();
+    }
+}
+
+
+void SwUndoMove::DelFtn( const SwPaM& rRange )
+{
+    // wird aus dem CntntBereich in den Sonderbereich verschoben ?
+    SwDoc* pDoc = rRange.GetDoc();
+    ULONG nCntntStt = pDoc->GetNodes().GetEndOfAutotext().GetIndex();
+    if( nMvDestNode < nCntntStt &&
+        rRange.GetPoint()->nNode.GetIndex() >= nCntntStt )
+    {
+        // loesche alle Fussnoten. Diese sind dort nicht erwuenscht.
+        DelCntntIndex( *rRange.GetMark(), *rRange.GetPoint(),
+                            SwUndoSaveCntnt::DELCNT_FTN );
+
+        if( pHistory && !pHistory->Count() )
+            delete pHistory, pHistory = 0;
+    }
+}
+
+void SwUndoMove::AddTblMrgFlyHstry( SwHistory& rHstr )
+{
+    if( !pHistory )
+        pHistory = new SwHistory;
+
+    USHORT nInsPos = nFtnStt;
+    nFtnStt += rHstr.Count();
+    pHistory->Move( nInsPos, &rHstr );
+}
+
+/*************************************************************************
+
+      Source Code Control System - Header
+
+      $Header: /zpool/svn/migration/cvs_rep_09_09_08/code/sw/source/core/undo/unmove.cxx,v 1.1.1.1 2000-09-19 00:08:28 hr Exp $
+
+      Source Code Control System - Update
+
+      $Log: not supported by cvs2svn $
+      Revision 1.39  2000/09/18 16:04:29  willem.vandorp
+      OpenOffice header added.
+
+      Revision 1.38  2000/05/09 10:04:24  jp
+      Changes for Unicode
+
+      Revision 1.37  1999/07/08 17:18:46  JP
+      Bug #67507#: ClearSwpHintsArr - optional dont delete fields/hardblanks/softhyps
+
+
+      Rev 1.36   08 Jul 1999 19:18:46   JP
+   Bug #67507#: ClearSwpHintsArr - optional dont delete fields/hardblanks/softhyps
+
+      Rev 1.35   02 Apr 1998 15:13:32   JP
+   Redo: Undo-Flag wird schon von der EditShell abgeschaltet
+
+      Rev 1.34   27 Mar 1998 15:33:24   JP
+   UndoMove: GetHistory durch AddTblMrgFlyHstry ersetzt
+
+      Rev 1.33   22 Jan 1998 20:53:10   JP
+   CTOR des SwPaM umgestellt
+
+      Rev 1.32   13 Jan 1998 21:36:06   JP
+   Fussnoten in der IconSection zulassen (Redlining!)
+
+      Rev 1.31   19 Dec 1997 12:15:34   JP
+   MSG/NOTE entfernt
+
+      Rev 1.30   18 Nov 1997 16:36:48   JP
+   ResetAttr uber den Node und nicht uebers Doc rufen
+
+      Rev 1.29   03 Nov 1997 13:06:24   MA
+   precomp entfernt
+
+      Rev 1.28   09 Oct 1997 15:45:38   JP
+   Umstellung NodeIndex/-Array/BigPtrArray
+
+      Rev 1.27   17 Jun 1997 13:02:54   JP
+   SetDestRange: Schnittstelle geaendert
+
+      Rev 1.26   11 Jun 1997 10:44:48   JP
+   pure virtual Repeat wurde zur virtual Methode, Segment Pragma entfernt
+
+      Rev 1.25   29 May 1997 22:56:32   JP
+   CopyAttr/CopyFmtAttr von SwUndo zur SwHistory verschoben
+
+      Rev 1.24   03 Apr 1997 16:30:08   JP
+   Bug #35738#: Attribute/Vorlagen richtig restaurieren
+
+      Rev 1.23   31 Jan 1997 10:13:34   JP
+   Bug #35409#: Attribute von der InsPos beim Undo wieder herstellen
+
+      Rev 1.22   29 Oct 1996 14:54:30   JP
+   am Doc ist das NodesArray nur noch ueber Get..() zugaenglich
+
+      Rev 1.21   04 Oct 1996 12:52:28   JP
+   neu: GetHistory - legt ggf. das History-Object an
+
+      Rev 1.20   24 Sep 1996 10:27:20   JP
+   erweitert fuers Undo von Move( SwRanges ), Redo FEHLT!
+
+      Rev 1.19   24 Nov 1995 17:13:58   OM
+   PCH->PRECOMPILED
+
+      Rev 1.18   22 Jun 1995 19:33:08   JP
+   virt. Methode GetUndoRange vernichtet, Objecte rufen jetzt die Basis-Klasse
+
+      Rev 1.17   08 Feb 1995 23:52:58   ER
+   undo.hxx -> swundo.hxx wegen solar undo.hxx
+
+      Rev 1.16   24 Jan 1995 19:07:46   JP
+   JoinNext/-Prev: zus. Parameter - seine Position im NodesArray
+
+      Rev 1.15   15 Dec 1994 20:48:16   SWG
+   *ARR* Ersetzungen, svmem, __far_data etc.
+
+      Rev 1.14   25 Oct 1994 14:50:56   MA
+   PreHdr.
+
+      Rev 1.13   02 Aug 1994 16:49:56   JP
+   SwCntntNode::JoinNext/JoinPrev(): Nodes-Array nicht mehr als Parameter
+
+      Rev 1.12   07 Jun 1994 19:48:40   JP
+   UndoMove: Member nNdDiff wird nicht benoetigt
+
+      Rev 1.11   07 Jun 1994 19:01:04   JP
+   neu: wird Text in die "Sonderbereiche" verschoben und befinden sich
+       in diesem Fussnoten, dann muessen sie geloescht werden.
+
+      Rev 1.10   02 Mar 1994 19:50:28   MI
+   Underscore im Namen der #pragmas
+
+      Rev 1.9   17 Feb 1994 08:31:00   MI
+   SEG_FUNCDEFS ausgefuellt
+
+      Rev 1.8   16 Feb 1994 13:17:18   MI
+   Pragmas zurechtgerueckt
+
+*************************************************************************/
+
+
diff --git a/sw/source/core/undo/unnum.cxx b/sw/source/core/undo/unnum.cxx
new file mode 100644
index 000000000000..b0b34f458bb5
--- /dev/null
+++ b/sw/source/core/undo/unnum.cxx
@@ -0,0 +1,588 @@
+/*************************************************************************
+ *
+ *  $RCSfile: unnum.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:28 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include            // fuer die UndoIds
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _UNDOBJ_HXX
+#include 
+#endif
+#ifndef _NUMRULE_HXX
+#include 
+#endif
+#ifndef _ROLBCK_HXX
+#include 
+#endif
+
+
+SV_DECL_PTRARR_DEL( _SfxPoolItems, SfxPoolItem*, 16, 16 );
+SV_IMPL_PTRARR( _SfxPoolItems, SfxPoolItem* );
+
+inline SwDoc& SwUndoIter::GetDoc() const { return *pAktPam->GetDoc(); }
+
+SwUndoInsNum::SwUndoInsNum( const SwNumRule& rOldRule,
+                            const SwNumRule& rNewRule )
+    : SwUndo( UNDO_INSNUM ),
+    aNumRule( rNewRule ), pHistory( 0 ), nLRSavePos( 0 ),
+    nSttSet( ULONG_MAX ), pOldNumRule( new SwNumRule( rOldRule ))
+{
+    ASSERT( rOldRule.IsAutoRule(),
+            "darf nur fuer AutoNumRules gerufen werden" );
+}
+
+SwUndoInsNum::SwUndoInsNum( const SwPaM& rPam, const SwNumRule& rRule )
+    : SwUndo( UNDO_INSNUM ), SwUndRng( rPam ),
+    aNumRule( rRule ), pHistory( 0 ), nLRSavePos( 0 ),
+    nSttSet( ULONG_MAX ), pOldNumRule( 0 )
+{
+}
+
+SwUndoInsNum::SwUndoInsNum( const SwPosition& rPos, const SwNumRule& rRule,
+                            const String& rReplaceRule )
+    : SwUndo( UNDO_INSNUM ),
+    aNumRule( rRule ), pHistory( 0 ), nLRSavePos( 0 ),
+    nSttSet( ULONG_MAX ), pOldNumRule( 0 ),
+    sReplaceRule( rReplaceRule )
+{
+    // keine Selektion !!
+    nEndNode = 0, nEndCntnt = USHRT_MAX;
+    nSttNode = rPos.nNode.GetIndex();
+    nSttCntnt = rPos.nContent.GetIndex();
+}
+
+SwUndoInsNum::~SwUndoInsNum()
+{
+    delete pHistory;
+    delete pOldNumRule;
+}
+
+void SwUndoInsNum::Undo( SwUndoIter& rUndoIter )
+{
+    SwDoc& rDoc = rUndoIter.GetDoc();
+    if( nSttNode )
+        SetPaM( rUndoIter );
+
+    BOOL bUndo = rDoc.DoesUndo();
+    rDoc.DoUndo( FALSE );
+
+    if( pOldNumRule )
+        rDoc.ChgNumRuleFmts( *pOldNumRule );
+
+    if( pHistory )
+    {
+        SwTxtNode* pNd;
+        if( ULONG_MAX != nSttSet &&
+            0 != ( pNd = rDoc.GetNodes()[ nSttSet ]->GetTxtNode() ) &&
+            pNd->GetNum() )
+                ((SwNodeNum*)pNd->GetNum())->SetStart( TRUE );
+        else
+            pNd = 0;
+
+
+        if( nLRSavePos )
+        {
+            // sofort Updaten, damit eventuell "alte" LRSpaces wieder
+            // gueltig werden.
+            // !!! Dafuer suche aber erstmal den richtigen NumRule - Namen!
+            if( !pNd && nSttNode )
+                pNd = rDoc.GetNodes()[ nSttNode ]->GetTxtNode();
+
+            const SwNumRule* pNdRule;
+            if( pNd )
+                pNdRule = pNd->GetNumRule();
+            else
+                pNdRule = rDoc.FindNumRulePtr( aNumRule.GetName() );
+
+            pHistory->TmpRollback( &rDoc, nLRSavePos );
+            if( pNdRule )
+                rDoc.UpdateNumRule( pNdRule->GetName(), ULONG_MAX );
+        }
+        pHistory->TmpRollback( &rDoc, 0 );
+        pHistory->SetTmpEnd( pHistory->Count() );
+    }
+
+    if( nSttNode )
+        SetPaM( rUndoIter );
+    rDoc.DoUndo( bUndo );
+}
+
+
+void SwUndoInsNum::Redo( SwUndoIter& rUndoIter )
+{
+    SwDoc& rDoc = rUndoIter.GetDoc();
+
+    if( pOldNumRule )
+        rDoc.ChgNumRuleFmts( aNumRule );
+    else if( pHistory )
+    {
+        SetPaM( rUndoIter );
+        if( sReplaceRule.Len() )
+            rDoc.ReplaceNumRule( *rUndoIter.pAktPam->GetPoint(),
+                                sReplaceRule, aNumRule.GetName() );
+        else
+            rDoc.SetNumRule( *rUndoIter.pAktPam, aNumRule, FALSE );
+    }
+}
+
+void SwUndoInsNum::SetLRSpaceEndPos()
+{
+    if( pHistory )
+        nLRSavePos = pHistory->Count();
+}
+
+void SwUndoInsNum::Repeat( SwUndoIter& rUndoIter )
+{
+    if( nSttNode )
+    {
+        if( !sReplaceRule.Len() )
+            rUndoIter.GetDoc().SetNumRule( *rUndoIter.pAktPam, aNumRule, FALSE );
+    }
+    else
+        rUndoIter.GetDoc().ChgNumRuleFmts( aNumRule );
+}
+
+SwHistory* SwUndoInsNum::GetHistory()
+{
+    if( !pHistory )
+        pHistory = new SwHistory;
+    return pHistory;
+}
+
+void SwUndoInsNum::SaveOldNumRule( const SwNumRule& rOld )
+{
+    if( !pOldNumRule )
+        pOldNumRule = new SwNumRule( rOld );
+}
+
+/*  */
+
+
+SwUndoDelNum::SwUndoDelNum( const SwPaM& rPam )
+    : SwUndo( UNDO_DELNUM ), SwUndRng( rPam ),
+    aNodeIdx( BYTE( nEndNode - nSttNode > 255 ? 255 : nEndNode - nSttNode )),
+    aLevels( BYTE( nEndNode - nSttNode > 255 ? 255 : nEndNode - nSttNode ))
+#ifndef NUM_RELSPACE
+    , aRstLRSpaces( BYTE( nEndNode - nSttNode > 255 ? 255 : nEndNode - nSttNode ))
+#endif
+{
+    pHistory = new SwHistory;
+}
+
+
+SwUndoDelNum::~SwUndoDelNum()
+{
+    delete pHistory;
+}
+
+
+void SwUndoDelNum::Undo( SwUndoIter& rUndoIter )
+{
+    SwDoc& rDoc = rUndoIter.GetDoc();
+    SetPaM( rUndoIter );
+
+    BOOL bUndo = rDoc.DoesUndo();
+    rDoc.DoUndo( FALSE );
+
+    pHistory->TmpRollback( &rDoc, 0 );
+    pHistory->SetTmpEnd( pHistory->Count() );
+
+    for( USHORT n = 0; n < aNodeIdx.Count(); ++n )
+    {
+        SwTxtNode* pNd = rDoc.GetNodes()[ aNodeIdx[ n ] ]->GetTxtNode();
+        ASSERT( pNd, "wo ist der TextNode geblieben?" );
+        pNd->UpdateNum( SwNodeNum( aLevels[ n ] ));
+
+#ifndef NUM_RELSPACE
+        pNd->SetNumLSpace( aRstLRSpaces[ n ] );
+#endif
+
+        if( pNd->GetCondFmtColl() )
+            pNd->ChkCondColl();
+    }
+
+    SetPaM( rUndoIter );
+    rDoc.DoUndo( bUndo );
+}
+
+
+void SwUndoDelNum::Redo( SwUndoIter& rUndoIter )
+{
+    SetPaM( rUndoIter );
+    rUndoIter.GetDoc().DelNumRules( *rUndoIter.pAktPam );
+}
+
+
+void SwUndoDelNum::Repeat( SwUndoIter& rUndoIter )
+{
+    SetPaM( rUndoIter );
+    rUndoIter.GetDoc().DelNumRules( *rUndoIter.pAktPam );
+}
+
+void SwUndoDelNum::AddNode( const SwTxtNode& rNd, BOOL bFlag )
+{
+    if( rNd.GetNum() && NO_NUMBERING != rNd.GetNum()->GetLevel() )
+    {
+        register USHORT nIns = aNodeIdx.Count();
+        aNodeIdx.Insert( rNd.GetIndex(), nIns );
+        aLevels.Insert( rNd.GetNum()->GetLevel(), nIns );
+#ifndef NUM_RELSPACE
+        aRstLRSpaces.Insert( bFlag, nIns );
+#endif
+    }
+}
+
+
+/*  */
+
+
+SwUndoMoveNum::SwUndoMoveNum( const SwPaM& rPam, long nOff, BOOL bIsOutlMv )
+    : SwUndo( bIsOutlMv ? UNDO_OUTLINE_UD : UNDO_MOVENUM ),
+    SwUndRng( rPam ), nOffset( nOff ),
+    nNewStt( 0 )
+{
+    // nOffset: nach unten  =>  1
+    //          nach oben   => -1
+}
+
+
+void SwUndoMoveNum::Undo( SwUndoIter& rUndoIter )
+{
+    ULONG nTmpStt = nSttNode, nTmpEnd = nEndNode;
+
+    if( !nEndNode && USHRT_MAX == nEndCntnt )       // kein Bereich !
+        nEndNode = nSttNode;
+
+    if( nNewStt < nSttNode )        // nach vorne verschoben
+        nEndNode = nEndNode - ( nSttNode - nNewStt );
+    else
+        nEndNode = nEndNode + ( nNewStt - nSttNode );
+    nSttNode = nNewStt;
+
+//JP 22.06.95: wird wollen die Bookmarks/Verzeichnisse behalten, oder?
+//  SetPaM( rUndoIter );
+//  RemoveIdxFromRange( *rUndoIter.pAktPam, TRUE );
+
+    SetPaM( rUndoIter );
+    rUndoIter.GetDoc().MoveParagraph( *rUndoIter.pAktPam, -nOffset,
+                                        UNDO_OUTLINE_UD == GetId() );
+    nSttNode = nTmpStt;
+    nEndNode = nTmpEnd;
+}
+
+
+void SwUndoMoveNum::Redo( SwUndoIter& rUndoIter )
+{
+//JP 22.06.95: wird wollen die Bookmarks/Verzeichnisse behalten, oder?
+//  SetPaM( rUndoIter );
+//  RemoveIdxFromRange( *rUndoIter.pAktPam, TRUE );
+
+    SetPaM( rUndoIter );
+    rUndoIter.GetDoc().MoveParagraph( *rUndoIter.pAktPam, nOffset,
+                                        UNDO_OUTLINE_UD == GetId() );
+}
+
+
+void SwUndoMoveNum::Repeat( SwUndoIter& rUndoIter )
+{
+    if( UNDO_OUTLINE_UD == GetId() )
+        rUndoIter.GetDoc().MoveOutlinePara( *rUndoIter.pAktPam,
+                                            0 < nOffset ? 1 : -1 );
+    else
+        rUndoIter.GetDoc().MoveParagraph( *rUndoIter.pAktPam, nOffset, FALSE );
+}
+
+/*  */
+
+
+SwUndoNumUpDown::SwUndoNumUpDown( const SwPaM& rPam, short nOff )
+    : SwUndo( UNDO_NUMUPDOWN ), SwUndRng( rPam ), nOffset( nOff )
+{
+    // nOffset: Down    =>  1
+    //          Up      => -1
+}
+
+
+void SwUndoNumUpDown::Undo( SwUndoIter& rUndoIter )
+{
+    SetPaM( rUndoIter );
+    rUndoIter.GetDoc().NumUpDown( *rUndoIter.pAktPam, 1 != nOffset );
+}
+
+
+void SwUndoNumUpDown::Redo( SwUndoIter& rUndoIter )
+{
+    SetPaM( rUndoIter );
+    rUndoIter.GetDoc().NumUpDown( *rUndoIter.pAktPam, 1 == nOffset );
+}
+
+
+void SwUndoNumUpDown::Repeat( SwUndoIter& rUndoIter )
+{
+    rUndoIter.GetDoc().NumUpDown( *rUndoIter.pAktPam, 1 == nOffset );
+}
+
+/*  */
+
+
+SwUndoNumOrNoNum::SwUndoNumOrNoNum( const SwNodeIndex& rIdx, BOOL bDelete,
+                                    BOOL bOutln )
+    : SwUndo( UNDO_NUMORNONUM ), nIdx( rIdx.GetIndex() ), bDel( bDelete ),
+    bOutline( bOutln )
+{
+}
+
+
+void SwUndoNumOrNoNum::Undo( SwUndoIter& rUndoIter )
+{
+    SwNodeIndex aIdx( rUndoIter.GetDoc().GetNodes(), nIdx );
+    rUndoIter.GetDoc().NumOrNoNum( aIdx, !bDel, bOutline );
+}
+
+
+void SwUndoNumOrNoNum::Redo( SwUndoIter& rUndoIter )
+{
+    SwDoc& rDoc = rUndoIter.GetDoc();
+    SwNodeIndex aIdx( rDoc.GetNodes(), nIdx );
+    rDoc.NumOrNoNum( aIdx, bDel, bOutline );
+}
+
+
+void SwUndoNumOrNoNum::Repeat( SwUndoIter& rUndoIter )
+{
+    rUndoIter.GetDoc().NumOrNoNum( rUndoIter.pAktPam->GetPoint()->nNode,
+                                    bDel, bOutline );
+}
+
+/*  */
+
+SwUndoNumRuleStart::SwUndoNumRuleStart( const SwPosition& rPos, BOOL bFlg )
+    : SwUndo( UNDO_SETNUMRULESTART ),
+    nIdx( rPos.nNode.GetIndex() ), bFlag( bFlg ), bSetSttValue( FALSE ),
+    nNewStt( USHRT_MAX ), nOldStt( USHRT_MAX )
+{
+}
+
+SwUndoNumRuleStart::SwUndoNumRuleStart( const SwPosition& rPos, USHORT nStt )
+    : SwUndo( UNDO_SETNUMRULESTART ),
+    nIdx( rPos.nNode.GetIndex() ), bSetSttValue( TRUE ),
+    nNewStt( nStt ), nOldStt( USHRT_MAX )
+{
+    SwTxtNode* pTxtNd = rPos.nNode.GetNode().GetTxtNode();
+    if( pTxtNd && pTxtNd->GetNum() )
+        nOldStt = pTxtNd->GetNum()->GetSetValue();
+}
+
+
+void SwUndoNumRuleStart::Undo( SwUndoIter& rUndoIter )
+{
+    SwPosition aPos( *rUndoIter.GetDoc().GetNodes()[ nIdx ] );
+    if( bSetSttValue )
+        rUndoIter.GetDoc().SetNodeNumStart( aPos, nOldStt );
+    else
+        rUndoIter.GetDoc().SetNumRuleStart( aPos, !bFlag );
+}
+
+
+void SwUndoNumRuleStart::Redo( SwUndoIter& rUndoIter )
+{
+    SwDoc& rDoc = rUndoIter.GetDoc();
+
+    SwPosition aPos( *rDoc.GetNodes()[ nIdx ] );
+    if( bSetSttValue )
+        rDoc.SetNodeNumStart( aPos, nNewStt );
+    else
+        rDoc.SetNumRuleStart( aPos, bFlag );
+}
+
+
+void SwUndoNumRuleStart::Repeat( SwUndoIter& rUndoIter )
+{
+    if( bSetSttValue )
+        rUndoIter.GetDoc().SetNodeNumStart( *rUndoIter.pAktPam->GetPoint(), nNewStt );
+    else
+        rUndoIter.GetDoc().SetNumRuleStart( *rUndoIter.pAktPam->GetPoint(), bFlag );
+}
+
+/*************************************************************************
+
+      Source Code Control System - Header
+
+      $Header: /zpool/svn/migration/cvs_rep_09_09_08/code/sw/source/core/undo/unnum.cxx,v 1.1.1.1 2000-09-19 00:08:28 hr Exp $
+
+      Source Code Control System - Update
+
+      $Log: not supported by cvs2svn $
+      Revision 1.29  2000/09/18 16:04:29  willem.vandorp
+      OpenOffice header added.
+
+      Revision 1.28  1999/03/15 22:29:20  JP
+      Task #63049#: Numerierung mit rel. Einzuegen
+
+
+      Rev 1.27   15 Mar 1999 23:29:20   JP
+   Task #63049#: Numerierung mit rel. Einzuegen
+
+      Rev 1.26   11 Nov 1998 10:41:50   JP
+   Task #59308#: NoNum auch bei Outlines setzen
+
+      Rev 1.25   09 Nov 1998 17:34:22   JP
+   Bug #57903#: Flag fuers umsetzen der LRSpaces mit sichern
+
+      Rev 1.24   08 Apr 1998 15:37:16   JP
+   Bug #49140#: UndoInsNum - LRSpaces sichern
+
+      Rev 1.23   02 Apr 1998 15:13:32   JP
+   Redo: Undo-Flag wird schon von der EditShell abgeschaltet
+
+      Rev 1.22   26 Jan 1998 10:44:30   JP
+   neu: eigenen Startwert fuer die akt. Numerierung am Node setzen
+
+      Rev 1.21   23 Jan 1998 17:01:58   JP
+   SwUndoOutlineUpDown entfernt, wird durch MoveParagraph ersetzt
+
+      Rev 1.20   09 Dec 1997 16:49:50   JP
+   neu: ReplaceNumRule fuer MakeByExample fuer NumerierungsVorlagen
+
+      Rev 1.19   19 Nov 1997 09:59:22   JP
+   Undo fuer Set-/ChgNumRule implementiert
+
+      Rev 1.18   18 Nov 1997 16:34:12   JP
+   neues UndoObject, UndoDelNum an neue Num. angepasst
+
+      Rev 1.17   17 Nov 1997 09:46:24   JP
+   Umstellung Numerierung
+
+      Rev 1.16   03 Nov 1997 13:06:20   MA
+   precomp entfernt
+
+      Rev 1.15   09 Oct 1997 15:45:38   JP
+   Umstellung NodeIndex/-Array/BigPtrArray
+
+      Rev 1.14   11 Jun 1997 10:45:02   JP
+   pure virtual Repeat wurde zur virtual Methode, Segment Pragma entfernt
+
+      Rev 1.13   11 Mar 1997 16:21:58   AMA
+   New: Absaetze verschieben durch Strg + CursorUp/Down (auch ausserhalb von Num.)
+
+      Rev 1.12   04 Feb 1997 18:54:32   JP
+   SwUndoInsNum: bei keiner Selektion EndNode auf StartNode setzen
+
+      Rev 1.11   13 Dec 1996 14:58:24   JP
+   Bug #34497#: auf TextNode abpruefen
+
+      Rev 1.10   12 Dec 1996 13:10:40   JP
+   Bug #34429#: CTOR-UndoInNum: Selektion auf Anfang/Ende der Nodes setzen
+
+      Rev 1.9   29 Oct 1996 14:54:44   JP
+   am Doc ist das NodesArray nur noch ueber Get..() zugaenglich
+
+      Rev 1.8   26 Jul 1996 09:24:02   JP
+   SetNumRules - neues Flag fuers setzen des abs. Abstandes
+
+      Rev 1.7   11 Apr 1996 17:14:52   sdo
+   GCC, C40_INSERT
+
+      Rev 1.6   26 Mar 1996 15:26:14   JP
+   neu: SwUndoNumOrNoNum - Number an/aus schalten
+
+      Rev 1.5   26 Feb 1996 20:49:40   JP
+   UndoMoveNum: es muss kein Bereich vorhanden sein!
+
+      Rev 1.4   24 Nov 1995 17:14:00   OM
+   PCH->PRECOMPILED
+
+      Rev 1.3   17 Nov 1995 10:21:52   MA
+   Segmentierung
+
+      Rev 1.2   27 Jul 1995 08:45:42   mk
+   an SCC4.0.1a angepasst (MDA)
+
+      Rev 1.1   22 Jun 1995 19:33:30   JP
+   virt. Methode GetUndoRange vernichtet, Objecte rufen jetzt die Basis-Klasse
+
+      Rev 1.0   03 May 1995 14:17:52   JP
+   Initial revision.
+
+*************************************************************************/
+
+
diff --git a/sw/source/core/undo/unoutl.cxx b/sw/source/core/undo/unoutl.cxx
new file mode 100644
index 000000000000..f56c1267b660
--- /dev/null
+++ b/sw/source/core/undo/unoutl.cxx
@@ -0,0 +1,153 @@
+/*************************************************************************
+ *
+ *  $RCSfile: unoutl.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:28 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "doc.hxx"
+#include "swundo.hxx"           // fuer die UndoIds
+#include "pam.hxx"
+#include "ndtxt.hxx"
+
+#include "undobj.hxx"
+
+
+inline SwDoc& SwUndoIter::GetDoc() const { return *pAktPam->GetDoc(); }
+
+SwUndoOutlineLeftRight::SwUndoOutlineLeftRight( const SwPaM& rPam,
+                                                short nOff )
+    : SwUndo( UNDO_OUTLINE_LR ), SwUndRng( rPam ), nOffset( nOff )
+{
+}
+
+
+void SwUndoOutlineLeftRight::Undo( SwUndoIter& rUndoIter )
+{
+    SetPaM( rUndoIter );
+    rUndoIter.GetDoc().OutlineUpDown( *rUndoIter.pAktPam, -nOffset );
+}
+
+
+void SwUndoOutlineLeftRight::Redo( SwUndoIter& rUndoIter )
+{
+    SetPaM( rUndoIter );
+    rUndoIter.GetDoc().OutlineUpDown( *rUndoIter.pAktPam, nOffset );
+}
+
+
+void SwUndoOutlineLeftRight::Repeat( SwUndoIter& rUndoIter )
+{
+    rUndoIter.GetDoc().OutlineUpDown( *rUndoIter.pAktPam, nOffset );
+}
+
+
+/*************************************************************************
+
+      Source Code Control System - Header
+
+      $Header: /zpool/svn/migration/cvs_rep_09_09_08/code/sw/source/core/undo/unoutl.cxx,v 1.1.1.1 2000-09-19 00:08:28 hr Exp $
+
+      Source Code Control System - Update
+
+      $Log: not supported by cvs2svn $
+      Revision 1.11  2000/09/18 16:04:29  willem.vandorp
+      OpenOffice header added.
+
+      Revision 1.10  1998/04/02 13:13:32  JP
+      Redo: Undo-Flag wird schon von der EditShell abgeschaltet
+
+
+      Rev 1.9   02 Apr 1998 15:13:32   JP
+   Redo: Undo-Flag wird schon von der EditShell abgeschaltet
+
+      Rev 1.8   23 Jan 1998 17:01:58   JP
+   SwUndoOutlineUpDown entfernt, wird durch MoveParagraph ersetzt
+
+      Rev 1.7   03 Nov 1997 13:06:14   MA
+   precomp entfernt
+
+      Rev 1.6   09 Oct 1997 15:45:28   JP
+   Umstellung NodeIndex/-Array/BigPtrArray
+
+      Rev 1.5   11 Jun 1997 10:44:10   JP
+   pure virtual Repeat wurde zur virtual Methode, Segment Pragma entfernt
+
+      Rev 1.4   13 May 1997 15:03:26   JP
+   UndoMoveOutl: keine Selektion beachten
+
+      Rev 1.3   24 Nov 1995 17:14:04   OM
+   PCH->PRECOMPILED
+
+      Rev 1.2   22 Jun 1995 19:33:22   JP
+   virt. Methode GetUndoRange vernichtet, Objecte rufen jetzt die Basis-Klasse
+
+      Rev 1.1   08 Feb 1995 23:52:54   ER
+   undo.hxx -> swundo.hxx wegen solar undo.hxx
+
+      Rev 1.0   07 Feb 1995 19:34:34   JP
+   Undo fuers hoch/runter stufen/verschieben von Gliederung
+
+*************************************************************************/
+
+
diff --git a/sw/source/core/undo/unovwr.cxx b/sw/source/core/undo/unovwr.cxx
new file mode 100644
index 000000000000..716f09012ddb
--- /dev/null
+++ b/sw/source/core/undo/unovwr.cxx
@@ -0,0 +1,407 @@
+/*************************************************************************
+ *
+ *  $RCSfile: unovwr.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:28 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _WORDSEL_HXX
+#include 
+#endif
+
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include            // fuer die UndoIds
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _UNDOBJ_HXX
+#include 
+#endif
+#ifndef _ROLBCK_HXX
+#include 
+#endif
+#ifndef _ACORRECT_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+
+
+//------------------------------------------------------------------
+
+// zwei Zugriffs-Funktionen
+inline SwPosition* IterPt( SwUndoIter& rUIter )
+{   return rUIter.pAktPam->GetPoint();  }
+inline SwPosition* IterMk( SwUndoIter& rUIter )
+{   return rUIter.pAktPam->GetMark();   }
+
+inline SwDoc& SwUndoIter::GetDoc() const { return *pAktPam->GetDoc(); }
+
+//------------------------------------------------------------
+
+
+// OVERWRITE
+
+
+SwUndoOverwrite::SwUndoOverwrite( SwDoc* pDoc, SwPosition& rPos,
+                                    sal_Unicode cIns )
+    : SwUndo(UNDO_OVERWRITE), bGroup( FALSE ), pRedlSaveData( 0 )
+{
+#ifdef COMPACT
+    pDoc->DelUndoGroups();
+#endif
+
+    if( !pDoc->IsIgnoreRedline() && pDoc->GetRedlineTbl().Count() )
+    {
+        SwPaM aPam( rPos.nNode, rPos.nContent.GetIndex(),
+                    rPos.nNode, rPos.nContent.GetIndex()+1 );
+        pRedlSaveData = new SwRedlineSaveDatas;
+        if( !FillSaveData( aPam, *pRedlSaveData ))
+            delete pRedlSaveData, pRedlSaveData = 0;
+    }
+
+    nSttNode = rPos.nNode.GetIndex();
+    nSttCntnt = rPos.nContent.GetIndex();
+
+    SwTxtNode* pTxtNd = rPos.nNode.GetNode().GetTxtNode();
+    ASSERT( pTxtNd, "Overwrite nicht im TextNode?" );
+
+    bInsChar = TRUE;
+    if( nSttCntnt < pTxtNd->Len() )     // kein reines Einfuegen ?
+    {
+        aDelStr.Insert( pTxtNd->GetTxt().GetChar( nSttCntnt ) );
+        if( !pHistory )
+            pHistory = new SwHistory;
+        SwRegHistory aRHst( *pTxtNd, pHistory );
+        pHistory->CopyAttr( pTxtNd->GetpSwpHints(), nSttNode, 0,
+                            pTxtNd->Len(), FALSE );
+        rPos.nContent++;
+        bInsChar = FALSE;
+    }
+    pTxtNd->Insert( cIns, rPos.nContent );
+    aInsStr.Insert( cIns );
+
+    if( !bInsChar )
+    {
+        const SwIndex aTmpIndex( rPos.nContent, -2 );
+        pTxtNd->Erase( aTmpIndex, 1 );
+    }
+
+}
+
+SwUndoOverwrite::~SwUndoOverwrite()
+{
+    delete pRedlSaveData;
+}
+
+BOOL SwUndoOverwrite::CanGrouping( SwDoc* pDoc, SwPosition& rPos,
+                                    sal_Unicode cIns )
+{
+///  ?? was ist mit nur eingefuegten Charaktern ???
+
+    // es kann nur das Loeschen von einzelnen char's zusammengefasst werden
+    if( rPos.nNode != nSttNode || !aInsStr.Len()  ||
+        ( !bGroup && aInsStr.Len() != 1 ))
+        return FALSE;
+
+    // ist der Node ueberhaupt ein TextNode?
+    SwTxtNode * pDelTxtNd = rPos.nNode.GetNode().GetTxtNode();
+    if( !pDelTxtNd ||
+        ( pDelTxtNd->GetTxt().Len() != rPos.nContent.GetIndex() &&
+            rPos.nContent.GetIndex() != ( nSttCntnt + aInsStr.Len() )))
+        return FALSE;
+
+    // befrage das einzufuegende Charakter
+    if( ( CH_TXTATR_BREAKWORD == cIns && CH_TXTATR_INWORD == cIns ) ||
+        WordSelection::IsNormalChar( cIns ) !=
+        WordSelection::IsNormalChar( aInsStr.GetChar( aInsStr.Len()-1) ) )
+        return FALSE;
+
+    {
+        SwRedlineSaveDatas* pTmpSav = new SwRedlineSaveDatas;
+        SwPaM aPam( rPos.nNode, rPos.nContent.GetIndex(),
+                    rPos.nNode, rPos.nContent.GetIndex()+1 );
+
+        if( !FillSaveData( aPam, *pTmpSav, FALSE ))
+            delete pTmpSav, pTmpSav = 0;
+
+        BOOL bOk = ( !pRedlSaveData && !pTmpSav ) ||
+                   ( pRedlSaveData && pTmpSav &&
+                        SwUndo::CanRedlineGroup( *pRedlSaveData, *pTmpSav,
+                            nSttCntnt > rPos.nContent.GetIndex() ));
+        delete pTmpSav;
+        if( !bOk )
+            return FALSE;
+
+        pDoc->DeleteRedline( aPam, FALSE );
+    }
+
+    // Ok, die beiden 'Overwrites' koennen zusammen gefasst werden, also
+    // 'verschiebe' das enstprechende Zeichen
+    if( !bInsChar )
+    {
+        if( rPos.nContent.GetIndex() < pDelTxtNd->GetTxt().Len() )
+        {
+            aDelStr.Insert( pDelTxtNd->GetTxt().GetChar(rPos.nContent.GetIndex()) );
+            rPos.nContent++;
+        }
+        else
+            bInsChar = TRUE;
+    }
+    pDelTxtNd->Insert( cIns, rPos.nContent );
+    aInsStr.Insert( cIns );
+
+    if( !bInsChar )
+    {
+        const SwIndex aTmpIndex( rPos.nContent, -2 );
+        pDelTxtNd->Erase( aTmpIndex, 1 );
+    }
+
+    bGroup = TRUE;
+    return TRUE;
+}
+
+
+
+
+
+void SwUndoOverwrite::Undo( SwUndoIter& rUndoIter )
+{
+    SwPaM* pAktPam = rUndoIter.pAktPam;
+    SwDoc* pDoc = pAktPam->GetDoc();
+    pAktPam->DeleteMark();
+    pAktPam->GetPoint()->nNode = nSttNode;
+    SwTxtNode* pTxtNd = pAktPam->GetNode()->GetTxtNode();
+    ASSERT( pTxtNd, "Overwrite nicht im TextNode?" );
+    SwIndex& rIdx = pAktPam->GetPoint()->nContent;
+    rIdx.Assign( pTxtNd, nSttCntnt );
+
+    SwAutoCorrExceptWord* pACEWord = pDoc->GetAutoCorrExceptWord();
+    if( pACEWord )
+    {
+        if( 1 == aInsStr.Len() && 1 == aDelStr.Len() )
+            pACEWord->CheckChar( *pAktPam->GetPoint(), aDelStr.GetChar( 0 ) );
+        pDoc->SetAutoCorrExceptWord( 0 );
+    }
+
+    // wurde nicht nur ueberschieben sondern auch geinsertet, so loesche
+    // den Ueberhang
+    if( aInsStr.Len() > aDelStr.Len() )
+    {
+        rIdx += aDelStr.Len();
+        pTxtNd->Erase( rIdx, aInsStr.Len() - aDelStr.Len() );
+        rIdx = nSttCntnt;
+    }
+
+    if( aDelStr.Len() )
+    {
+        String aTmpStr( '1' );
+        sal_Unicode* pTmpStr = aTmpStr.GetBufferAccess();
+
+        rIdx++;
+        for( xub_StrLen n = 0; n < aDelStr.Len(); n++  )
+        {
+            // einzeln, damit die Attribute stehen bleiben !!!
+            *pTmpStr = aDelStr.GetChar( n );
+            pTxtNd->Insert( aTmpStr, rIdx /*???, SETATTR_NOTXTATRCHR*/ );
+            rIdx -= 2;
+            pTxtNd->Erase( rIdx, 1 );
+            rIdx += 2;
+        }
+        rIdx--;
+    }
+    if( pHistory )
+        pHistory->TmpRollback( pDoc, 0, FALSE );
+
+    if( pAktPam->GetMark()->nContent.GetIndex() != nSttCntnt )
+    {
+        pAktPam->SetMark();
+        pAktPam->GetMark()->nContent = nSttCntnt;
+    }
+
+    if( pRedlSaveData )
+        SetSaveData( *pDoc, *pRedlSaveData );
+}
+
+
+void SwUndoOverwrite::Repeat( SwUndoIter& rUndoIter )
+{
+    rUndoIter.pLastUndoObj = this;
+    SwPaM* pAktPam = rUndoIter.pAktPam;
+    if( !aInsStr.Len() || pAktPam->HasMark() )
+        return;
+
+    SwDoc& rDoc = *pAktPam->GetDoc();
+
+    BOOL bGroupUndo = rDoc.DoesGroupUndo();
+    rDoc.DoGroupUndo( FALSE );
+    rDoc.Overwrite( *pAktPam, aInsStr.GetChar( 0 ));
+    rDoc.DoGroupUndo( bGroupUndo );
+    for( xub_StrLen n = 1; n < aInsStr.Len(); ++n )
+        rDoc.Overwrite( *pAktPam, aInsStr.GetChar( n ) );
+}
+
+
+
+void SwUndoOverwrite::Redo( SwUndoIter& rUndoIter )
+{
+    SwPaM* pAktPam = rUndoIter.pAktPam;
+    SwDoc* pDoc = pAktPam->GetDoc();
+    pAktPam->DeleteMark();
+    pAktPam->GetPoint()->nNode = nSttNode;
+    SwTxtNode* pTxtNd = pAktPam->GetNode()->GetTxtNode();
+    ASSERT( pTxtNd, "Overwrite nicht im TextNode?" );
+    SwIndex& rIdx = pAktPam->GetPoint()->nContent;
+
+    if( pRedlSaveData )
+    {
+        rIdx.Assign( pTxtNd, nSttCntnt );
+        pAktPam->SetMark();
+        pAktPam->GetMark()->nContent += aInsStr.Len();
+        pDoc->DeleteRedline( *pAktPam, FALSE );
+        pAktPam->DeleteMark();
+    }
+    rIdx.Assign( pTxtNd, aDelStr.Len() ? nSttCntnt+1 : nSttCntnt );
+
+    for( xub_StrLen n = 0; n < aInsStr.Len(); n++  )
+    {
+        // einzeln, damit die Attribute stehen bleiben !!!
+        pTxtNd->Insert( aInsStr.GetChar( n ), rIdx );
+        if( n < aDelStr.Len() )
+        {
+            rIdx -= 2;
+            pTxtNd->Erase( rIdx, 1 );
+            rIdx += n+1 < aDelStr.Len() ? 2 : 1;
+        }
+    }
+
+    // alte Anfangs-Position vom UndoNodes-Array zurueckholen
+    if( pHistory )
+        pHistory->SetTmpEnd( pHistory->Count() );
+    if( pAktPam->GetMark()->nContent.GetIndex() != nSttCntnt )
+    {
+        pAktPam->SetMark();
+        pAktPam->GetMark()->nContent = nSttCntnt;
+    }
+}
+
+/*************************************************************************
+
+      Source Code Control System - Header
+
+      $Header: /zpool/svn/migration/cvs_rep_09_09_08/code/sw/source/core/undo/unovwr.cxx,v 1.1.1.1 2000-09-19 00:08:28 hr Exp $
+
+      Source Code Control System - Update
+
+      $Log: not supported by cvs2svn $
+      Revision 1.35  2000/09/18 16:04:29  willem.vandorp
+      OpenOffice header added.
+
+      Revision 1.34  2000/07/20 13:15:35  jp
+      change old txtatr-character to the two new characters
+
+      Revision 1.33  2000/05/19 12:53:47  jp
+      use WordSelection class for check chars
+
+      Revision 1.32  2000/05/09 10:04:28  jp
+      Changes for Unicode
+
+      Revision 1.31  1998/01/22 19:53:12  JP
+      CTOR des SwPaM umgestellt
+
+
+      Rev 1.30   22 Jan 1998 20:53:12   JP
+   CTOR des SwPaM umgestellt
+
+      Rev 1.29   16 Jan 1998 11:06:52   JP
+   Overwrite: Redlining beachten
+
+      Rev 1.28   19 Dec 1997 12:15:34   JP
+   MSG/NOTE entfernt
+
+      Rev 1.27   03 Nov 1997 13:06:16   MA
+   precomp entfernt
+
+      Rev 1.26   09 Oct 1997 15:45:40   JP
+   Umstellung NodeIndex/-Array/BigPtrArray
+
+      Rev 1.25   11 Jun 1997 10:44:08   JP
+   pure virtual Repeat wurde zur virtual Methode, Segment Pragma entfernt
+
+      Rev 1.24   29 May 1997 22:56:56   JP
+   CopyAttr/CopyFmtAttr von SwUndo zur SwHistory verschoben
+
+      Rev 1.23   29 Oct 1996 15:57:26   JP
+   Undo: autom. Aufnahme von Ausnahmen fuer die Autokorrektur anstossen
+
+*************************************************************************/
+
+
diff --git a/sw/source/core/undo/unredln.cxx b/sw/source/core/undo/unredln.cxx
new file mode 100644
index 000000000000..8cb7b6d99a9f
--- /dev/null
+++ b/sw/source/core/undo/unredln.cxx
@@ -0,0 +1,579 @@
+/*************************************************************************
+ *
+ *  $RCSfile: unredln.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:28 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+#ifndef _WORDSEL_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include            // fuer die UndoIds
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _UNDOBJ_HXX
+#include 
+#endif
+#ifndef _ROLBCK_HXX
+#include 
+#endif
+#ifndef _REDLINE_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _SORTOPT_HXX
+#include 
+#endif
+
+extern void lcl_JoinText( SwPaM& rPam, BOOL bJoinPrev );
+extern void lcl_GetJoinFlags( SwPaM& rPam, BOOL& rJoinTxt, BOOL& rJoinPrev );
+
+//------------------------------------------------------------------
+
+inline SwDoc& SwUndoIter::GetDoc() const { return *pAktPam->GetDoc(); }
+
+
+SwUndoRedline::SwUndoRedline( USHORT nUsrId, const SwPaM& rRange )
+    : SwUndo( UNDO_REDLINE ), SwUndRng( rRange ),
+    pRedlData( 0 ), pRedlSaveData( 0 ), nUserId( nUsrId ),
+    bHiddenRedlines( FALSE )
+{
+    // Redline beachten
+    SwDoc& rDoc = *rRange.GetDoc();
+    if( rDoc.IsRedlineOn() )
+    {
+        switch( nUserId )
+        {
+        case UNDO_DELETE:
+        case UNDO_REPLACE:
+            pRedlData = new SwRedlineData( REDLINE_DELETE, rDoc.GetRedlineAuthor() );
+            break;
+        }
+        SetRedlineMode( rDoc.GetRedlineMode() );
+    }
+
+    ULONG nEndExtra = rDoc.GetNodes().GetEndOfExtras().GetIndex();
+
+    pRedlSaveData = new SwRedlineSaveDatas;
+    if( !FillSaveData( rRange, *pRedlSaveData, FALSE,
+                        UNDO_REJECT_REDLINE != nUserId ))
+        delete pRedlSaveData, pRedlSaveData = 0;
+    else
+    {
+        bHiddenRedlines = HasHiddenRedlines( *pRedlSaveData );
+        if( bHiddenRedlines )           // dann muessen die NodeIndizies
+        {                               // vom SwUndRng korrigiert werden
+            nEndExtra -= rDoc.GetNodes().GetEndOfExtras().GetIndex();
+            nSttNode -= nEndExtra;
+            nEndNode -= nEndExtra;
+        }
+    }
+}
+
+SwUndoRedline::~SwUndoRedline()
+{
+    delete pRedlData;
+    delete pRedlSaveData;
+}
+
+void SwUndoRedline::Undo( SwUndoIter& rIter )
+{
+    SwDoc* pDoc = &rIter.GetDoc();
+    SetPaM( *rIter.pAktPam );
+
+// RedlineMode setzen?
+    _Undo( rIter );
+
+    if( pRedlSaveData )
+    {
+        ULONG nEndExtra = pDoc->GetNodes().GetEndOfExtras().GetIndex();
+        SetSaveData( *pDoc, *pRedlSaveData );
+        if( bHiddenRedlines )
+        {
+            pRedlSaveData->DeleteAndDestroy( 0, pRedlSaveData->Count() );
+
+            nEndExtra = pDoc->GetNodes().GetEndOfExtras().GetIndex() - nEndExtra;
+            nSttNode += nEndExtra;
+            nEndNode += nEndExtra;
+        }
+        SetPaM( *rIter.pAktPam, TRUE );
+    }
+}
+
+
+void SwUndoRedline::Redo( SwUndoIter& rIter )
+{
+    SwDoc* pDoc = &rIter.GetDoc();
+    SwRedlineMode eOld = pDoc->GetRedlineMode();
+    pDoc->SetRedlineMode_intern( ( eOld & ~REDLINE_IGNORE) | REDLINE_ON );
+
+    SetPaM( *rIter.pAktPam );
+    if( pRedlSaveData && bHiddenRedlines )
+    {
+        ULONG nEndExtra = pDoc->GetNodes().GetEndOfExtras().GetIndex();
+        FillSaveData( *rIter.pAktPam, *pRedlSaveData, FALSE,
+                        UNDO_REJECT_REDLINE != nUserId );
+
+        nEndExtra -= pDoc->GetNodes().GetEndOfExtras().GetIndex();
+        nSttNode -= nEndExtra;
+        nEndNode -= nEndExtra;
+    }
+    _Redo( rIter );
+
+    SetPaM( *rIter.pAktPam, TRUE );
+    pDoc->SetRedlineMode_intern( eOld );
+}
+
+// default ist leer
+void SwUndoRedline::_Undo( SwUndoIter& )
+{
+}
+
+// default ist Redlines entfernen
+void SwUndoRedline::_Redo( SwUndoIter& rIter )
+{
+    rIter.GetDoc().DeleteRedline( *rIter.pAktPam );
+}
+
+
+/*  */
+
+SwUndoRedlineDelete::SwUndoRedlineDelete( const SwPaM& rRange, USHORT nUsrId )
+    : SwUndoRedline( nUsrId = (nUsrId ? nUsrId : UNDO_DELETE), rRange ),
+    bIsDelim( FALSE ), bIsBackspace( FALSE ), bCanGroup( FALSE )
+{
+    const SwTxtNode* pTNd;
+    if( UNDO_DELETE == nUserId &&
+        nSttNode == nEndNode && nSttCntnt + 1 == nEndCntnt &&
+        0 != (pTNd = rRange.GetNode()->GetTxtNode()) )
+    {
+        sal_Unicode cCh = pTNd->GetTxt().GetChar( nSttCntnt );
+        if( CH_TXTATR_BREAKWORD != cCh && CH_TXTATR_INWORD != cCh )
+        {
+            bCanGroup = TRUE;
+            bIsDelim = !WordSelection::IsNormalChar( cCh );
+            bIsBackspace = nSttCntnt == rRange.GetPoint()->nContent.GetIndex();
+        }
+    }
+}
+
+void SwUndoRedlineDelete::_Undo( SwUndoIter& rIter )
+{
+    rIter.GetDoc().DeleteRedline( *rIter.pAktPam );
+}
+
+void SwUndoRedlineDelete::_Redo( SwUndoIter& rIter )
+{
+    rIter.GetDoc().AppendRedline( new SwRedline( *pRedlData,
+                                        *rIter.pAktPam ), FALSE );
+}
+
+BOOL SwUndoRedlineDelete::CanGrouping( const SwUndoRedlineDelete& rNext )
+{
+    BOOL bRet = FALSE;
+    if( UNDO_DELETE == nUserId && nUserId == rNext.nUserId &&
+        bCanGroup == rNext.bCanGroup &&
+        bIsDelim == rNext.bIsDelim &&
+        bIsBackspace == rNext.bIsBackspace &&
+        nSttNode == nEndNode &&
+        rNext.nSttNode == nSttNode &&
+        rNext.nEndNode == nEndNode )
+    {
+        int bIsEnd = 0;
+        if( rNext.nSttCntnt == nEndCntnt )
+            bIsEnd = 1;
+        else if( rNext.nEndCntnt == nSttCntnt )
+            bIsEnd = -1;
+
+        if( bIsEnd &&
+            (( !pRedlSaveData && !rNext.pRedlSaveData ) ||
+             ( pRedlSaveData && rNext.pRedlSaveData &&
+                SwUndo::CanRedlineGroup( *pRedlSaveData,
+                            *rNext.pRedlSaveData, 1 != bIsEnd )
+             )))
+        {
+            if( 1 == bIsEnd )
+                nEndCntnt = rNext.nEndCntnt;
+            else
+                nSttCntnt = rNext.nSttCntnt;
+            bRet = TRUE;
+        }
+    }
+    return bRet;
+}
+
+/*  */
+
+SwUndoRedlineSort::SwUndoRedlineSort( const SwPaM& rRange,
+                                    const SwSortOptions& rOpt )
+    : SwUndoRedline( UNDO_SORT_TXT, rRange ),
+    pOpt( new SwSortOptions( rOpt ) ),
+    nSaveEndNode( nEndNode ), nOffset( 0 ), nSaveEndCntnt( nEndCntnt )
+{
+}
+
+SwUndoRedlineSort::~SwUndoRedlineSort()
+{
+    delete pOpt;
+}
+
+void SwUndoRedlineSort::_Undo( SwUndoIter& rIter )
+{
+    // im rIter.pAktPam ist der sortiete Bereich,
+    // im aSaveRange steht der kopierte, sprich der originale.
+    SwDoc& rDoc = rIter.GetDoc();
+
+    if( 0 == ( REDLINE_SHOW_DELETE & rDoc.GetRedlineMode()) )
+    {
+        // die beiden Redline Objecte suchen und diese dann anzeigen lassen,
+        // damit die Nodes wieder uebereinstimmen!
+        // das Geloeschte ist versteckt, also suche das INSERT
+        // Redline Object. Dahinter steht das Geloeschte
+        USHORT nFnd = rDoc.GetRedlinePos(
+                            *rDoc.GetNodes()[ nSttNode + nOffset + 1 ],
+                            REDLINE_INSERT );
+        ASSERT( USHRT_MAX != nFnd && nFnd+1 < rDoc.GetRedlineTbl().Count(),
+                    "kein Insert Object gefunden" );
+        ++nFnd;
+        rDoc.GetRedlineTbl()[nFnd]->Show();
+        SetPaM( *rIter.pAktPam );
+    }
+
+    {
+        SwPaM aTmp( *rIter.pAktPam->GetMark() );
+        aTmp.SetMark();
+        aTmp.GetPoint()->nNode = nSaveEndNode;
+        aTmp.GetPoint()->nContent.Assign( aTmp.GetCntntNode(), nSaveEndCntnt );
+        rDoc.DeleteRedline( aTmp );
+    }
+
+    rDoc.DelFullPara( *rIter.pAktPam );
+    SetPaM( *rIter.pAktPam );
+}
+
+void SwUndoRedlineSort::_Redo( SwUndoIter& rIter )
+{
+    SwPaM& rPam = *rIter.pAktPam;
+    rIter.GetDoc().SortText( rPam, *pOpt );
+    SetPaM( rPam );
+    rPam.GetPoint()->nNode = nSaveEndNode;
+    rPam.GetPoint()->nContent.Assign( rPam.GetCntntNode(), nSaveEndCntnt );
+}
+
+void SwUndoRedlineSort::Repeat( SwUndoIter& rIter )
+{
+    rIter.GetDoc().SortText( *rIter.pAktPam, *pOpt );
+}
+
+void SwUndoRedlineSort::SetSaveRange( const SwPaM& rRange )
+{
+    const SwPosition& rPos = *rRange.End();
+    nSaveEndNode = rPos.nNode.GetIndex();
+    nSaveEndCntnt = rPos.nContent.GetIndex();
+}
+
+void SwUndoRedlineSort::SetOffset( const SwNodeIndex& rIdx )
+{
+    nOffset = rIdx.GetIndex() - nSttNode;
+}
+
+/*  */
+
+SwUndoAcceptRedline::SwUndoAcceptRedline( const SwPaM& rRange )
+    : SwUndoRedline( UNDO_ACCEPT_REDLINE, rRange )
+{
+}
+
+void SwUndoAcceptRedline::_Redo( SwUndoIter& rIter )
+{
+    rIter.GetDoc().AcceptRedline( *rIter.pAktPam, FALSE );
+}
+
+void SwUndoAcceptRedline::Repeat( SwUndoIter& rIter )
+{
+    rIter.GetDoc().AcceptRedline( *rIter.pAktPam );
+}
+
+SwUndoRejectRedline::SwUndoRejectRedline( const SwPaM& rRange )
+    : SwUndoRedline( UNDO_REJECT_REDLINE, rRange )
+{
+}
+
+void SwUndoRejectRedline::_Redo( SwUndoIter& rIter )
+{
+    rIter.GetDoc().RejectRedline( *rIter.pAktPam, FALSE );
+}
+
+void SwUndoRejectRedline::Repeat( SwUndoIter& rIter )
+{
+    rIter.GetDoc().RejectRedline( *rIter.pAktPam );
+}
+
+/*  */
+
+SwUndoCompDoc::SwUndoCompDoc( const SwPaM& rRg, BOOL bIns )
+    : SwUndo( UNDO_COMPAREDOC ), SwUndRng( rRg ), pRedlData( 0 ),
+    pUnDel( 0 ), pRedlSaveData( 0 ), bInsert( bIns )
+{
+    SwDoc* pDoc = (SwDoc*)rRg.GetDoc();
+    if( pDoc->IsRedlineOn() )
+    {
+        SwRedlineType eTyp = bInsert ? REDLINE_INSERT : REDLINE_DELETE;
+        pRedlData = new SwRedlineData( eTyp, pDoc->GetRedlineAuthor() );
+        SetRedlineMode( pDoc->GetRedlineMode() );
+    }
+}
+
+SwUndoCompDoc::SwUndoCompDoc( const SwRedline& rRedl )
+    : SwUndo( UNDO_COMPAREDOC ), SwUndRng( rRedl ), pRedlData( 0 ),
+    pUnDel( 0 ), pRedlSaveData( 0 ),
+    // fuers MergeDoc wird aber der jeweils umgekehrte Zweig benoetigt!
+    bInsert( REDLINE_DELETE == rRedl.GetType() )
+{
+    SwDoc* pDoc = (SwDoc*)rRedl.GetDoc();
+    if( pDoc->IsRedlineOn() )
+    {
+        pRedlData = new SwRedlineData( rRedl.GetRedlineData() );
+        SetRedlineMode( pDoc->GetRedlineMode() );
+    }
+
+    pRedlSaveData = new SwRedlineSaveDatas;
+    if( !FillSaveData( rRedl, *pRedlSaveData, FALSE, TRUE ))
+        delete pRedlSaveData, pRedlSaveData = 0;
+}
+
+SwUndoCompDoc::~SwUndoCompDoc()
+{
+    delete pRedlData;
+    delete pUnDel;
+    delete pRedlSaveData;
+}
+
+void SwUndoCompDoc::Undo( SwUndoIter& rIter )
+{
+    SwPaM* pPam = rIter.pAktPam;
+    SwDoc* pDoc = pPam->GetDoc();
+
+    SetPaM( *pPam );
+
+    if( !bInsert )
+    {
+        // die Redlines loeschen
+        SwRedlineMode eOld = pDoc->GetRedlineMode();
+        pDoc->SetRedlineMode_intern( ( eOld & ~REDLINE_IGNORE) | REDLINE_ON );
+
+        pDoc->DeleteRedline( *pPam );
+
+        pDoc->SetRedlineMode_intern( eOld );
+
+        BOOL bJoinTxt, bJoinPrev;
+        ::lcl_GetJoinFlags( *pPam, bJoinTxt, bJoinPrev );
+
+        pUnDel = new SwUndoDelete( *pPam, FALSE );
+
+        if( bJoinTxt )
+            ::lcl_JoinText( *pPam, bJoinPrev );
+    }
+    else
+    {
+        if( IsRedlineOn( GetRedlineMode() ))
+        {
+            pDoc->DeleteRedline( *pPam );
+
+            if( pRedlSaveData )
+                SetSaveData( *pDoc, *pRedlSaveData );
+        }
+    }
+}
+
+void SwUndoCompDoc::Redo( SwUndoIter& rIter )
+{
+    // setze noch den Cursor auf den Redo-Bereich
+    SwPaM* pPam = rIter.pAktPam;
+    SwDoc* pDoc = pPam->GetDoc();
+
+    rIter.pLastUndoObj = 0;
+
+    if( bInsert )
+    {
+        SetPaM( *pPam );
+
+        if( pRedlData && IsRedlineOn( GetRedlineMode() ))
+        {
+            SwRedline* pTmp = new SwRedline( *pRedlData, *pPam );
+            ((SwRedlineTbl&)pDoc->GetRedlineTbl()).Insert( pTmp );
+            pTmp->InvalidateRange();
+
+/*
+            SwRedlineMode eOld = pDoc->GetRedlineMode();
+            pDoc->SetRedlineMode_intern( eOld & ~REDLINE_IGNORE );
+            pDoc->AppendRedline( new SwRedline( *pRedlData, *pPam ));
+            pDoc->SetRedlineMode_intern( eOld );
+*/
+        }
+        else if( !( REDLINE_IGNORE & GetRedlineMode() ) &&
+                pDoc->GetRedlineTbl().Count() )
+            pDoc->SplitRedline( *pPam );
+    }
+    else
+    {
+//      SwRedlineMode eOld = pDoc->GetRedlineMode();
+//      pDoc->SetRedlineMode_intern( ( eOld & ~REDLINE_IGNORE) | REDLINE_ON );
+
+        pUnDel->Undo( rIter );
+        delete pUnDel, pUnDel = 0;
+
+        SwRedline* pTmp = new SwRedline( *pRedlData, *pPam );
+        ((SwRedlineTbl&)pDoc->GetRedlineTbl()).Insert( pTmp );
+        pTmp->InvalidateRange();
+
+//      pDoc->SetRedlineMode_intern( eOld );
+    }
+}
+
+/*************************************************************************
+
+      Source Code Control System - Header
+
+      $Header: /zpool/svn/migration/cvs_rep_09_09_08/code/sw/source/core/undo/unredln.cxx,v 1.1.1.1 2000-09-19 00:08:28 hr Exp $
+
+      Source Code Control System - Update
+
+      $Log: not supported by cvs2svn $
+      Revision 1.19  2000/09/18 16:04:29  willem.vandorp
+      OpenOffice header added.
+
+      Revision 1.18  2000/07/20 13:15:39  jp
+      change old txtatr-character to the two new characters
+
+      Revision 1.17  2000/05/19 12:53:54  jp
+      use WordSelection class for check chars
+
+      Revision 1.16  2000/05/09 10:04:31  jp
+      Changes for Unicode
+
+      Revision 1.15  1998/11/10 11:29:32  JP
+      Bug #59223#: Undo CompDoc - das Join der Nodes nicht vergessen
+
+
+      Rev 1.14   10 Nov 1998 12:29:32   JP
+   Bug #59223#: Undo CompDoc - das Join der Nodes nicht vergessen
+
+      Rev 1.13   22 Sep 1998 10:11:08   JP
+   Bug #55909#: SwUndoCompDoc - die alten Redlines im Bereich merken
+
+      Rev 1.12   07 Jul 1998 13:23:22   JP
+   DocComp: Undo/Redo muessen das Layout invalidieren (fuer die korrekte Redlineanzeige)
+
+      Rev 1.11   02 Apr 1998 15:14:10   JP
+   Redo: Undo-Flag wird schon von der EditShell abgeschaltet
+
+      Rev 1.10   05 Mar 1998 19:30:52   JP
+   UndoRedlineDelete: CanCombine nur wenn sich alles in einem Node abspielt
+
+      Rev 1.9   05 Mar 1998 12:57:56   JP
+   SwUndoCompareDoc: fuers Merge doch einen eigene CTOR
+
+      Rev 1.8   02 Mar 1998 09:50:12   JP
+   UndoCompare: fuers MergeDoc erweitert und umgestellt
+
+      Rev 1.7   12 Feb 1998 16:51:04   JP
+   neu: Undo fuer Dokumentvergleich
+
+      Rev 1.6   30 Jan 1998 19:34:50   JP
+   bei vorhandenen versteckten Redlines die NodeIndizies korrigieren
+
+      Rev 1.5   29 Jan 1998 22:50:26   JP
+   RedlSaveData muss in Redo neu besorgt werden, wenn versteckte Deletes existierten
+
+      Rev 1.4   28 Jan 1998 19:50:56   JP
+   nach Redo: Pam auf jedenfall in ContentNodes setzen
+
+      Rev 1.3   22 Jan 1998 20:53:12   JP
+   CTOR des SwPaM umgestellt
+
+      Rev 1.2   13 Jan 1998 21:38:10   JP
+   neu: Undo fuer Accept-/Reject-Redline
+
+      Rev 1.1   08 Jan 1998 21:09:28   JP
+   weitere Redlining Erweiterung
+
+      Rev 1.0   06 Jan 1998 16:27:40   JP
+   Initial revision.
+
+*************************************************************************/
+
diff --git a/sw/source/core/undo/unsect.cxx b/sw/source/core/undo/unsect.cxx
new file mode 100644
index 000000000000..c94d03aa422d
--- /dev/null
+++ b/sw/source/core/undo/unsect.cxx
@@ -0,0 +1,627 @@
+/*************************************************************************
+ *
+ *  $RCSfile: unsect.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:28 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _SVXLINKMGR_HXX
+#include 
+#endif
+
+#ifndef _FMTCNTNT_HXX //autogen
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include            // fuer die UndoIds
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _UNDOBJ_HXX
+#include 
+#endif
+#ifndef _SECTION_HXX
+#include 
+#endif
+#ifndef _ROLBCK_HXX
+#include 
+#endif
+#ifndef _REDLINE_HXX
+#include 
+#endif
+#ifndef _DOCTXM_HXX
+#include 
+#endif
+#ifndef _FTNIDX_HXX
+#include 
+#endif
+
+#ifndef _EDITSH_HXX
+#include 
+#endif
+
+
+inline SwDoc& SwUndoIter::GetDoc() const { return *pAktPam->GetDoc(); }
+
+SfxItemSet* lcl_GetAttrSet( const SwSection& rSect )
+{
+    // Attribute des Formate sichern (Spalten, Farbe, ... )
+    // Cntnt- und Protect- Items interessieren nicht (stehen schon in der
+    // Section), muessen also entfernen werden
+    SfxItemSet* pAttr = 0;
+    if( rSect.GetFmt() )
+    {
+        USHORT nCnt = 1;
+        if( rSect.IsProtect() )
+            ++nCnt;
+
+        if( nCnt < rSect.GetFmt()->GetAttrSet().Count() )
+        {
+            pAttr = new SfxItemSet( rSect.GetFmt()->GetAttrSet() );
+            pAttr->ClearItem( RES_PROTECT );
+            pAttr->ClearItem( RES_CNTNT );
+            if( !pAttr->Count() )
+                delete pAttr, pAttr = 0;
+        }
+    }
+    return pAttr;
+}
+
+SwUndoInsSection::SwUndoInsSection( const SwPaM& rPam, const SwSection& rNew,
+                                    const SfxItemSet* pSet )
+    : SwUndo( UNDO_INSSECTION ), SwUndRng( rPam ), nSectNodePos( 0 ),
+    pHistory( 0 ), pRedlData( 0 ), pAttr( 0 )
+{
+    if( rNew.ISA( SwTOXBaseSection ))
+    {
+        const SwTOXBase& rBase = (SwTOXBaseSection&)rNew;
+        pSection = new SwTOXBaseSection( rBase );
+    }
+    else
+        pSection = new SwSection( rNew.GetType(), rNew.GetName() );
+    *pSection = rNew;
+
+    SwDoc& rDoc = *(SwDoc*)rPam.GetDoc();
+    if( rDoc.IsRedlineOn() )
+    {
+        pRedlData = new SwRedlineData( REDLINE_INSERT,
+                                        rDoc.GetRedlineAuthor() );
+        SetRedlineMode( rDoc.GetRedlineMode() );
+    }
+
+    bSplitAtStt = FALSE;
+    bSplitAtEnd = FALSE;
+    bUpdateFtn = FALSE;
+
+    if( pSet && pSet->Count() )
+        pAttr = new SfxItemSet( *pSet );
+
+    if( !rPam.HasMark() )
+    {
+        const SwCntntNode* pCNd = rPam.GetPoint()->nNode.GetNode().GetCntntNode();
+        if( pCNd && pCNd->GetpSwAttrSet() && (
+            !rPam.GetPoint()->nContent.GetIndex() ||
+            rPam.GetPoint()->nContent.GetIndex() == pCNd->Len() ))
+        {
+            SfxItemSet aBrkSet( rDoc.GetAttrPool(), aBreakSetRange );
+            aBrkSet.Put( *pCNd->GetpSwAttrSet() );
+            if( aBrkSet.Count() )
+            {
+                pHistory = new SwHistory;
+                pHistory->CopyFmtAttr( aBrkSet, pCNd->GetIndex() );
+            }
+        }
+    }
+}
+
+
+SwUndoInsSection::~SwUndoInsSection()
+{
+    delete pSection;
+    delete pRedlData;
+    delete pAttr;
+
+    if( pHistory )
+        delete pHistory;
+}
+
+
+
+void SwUndoInsSection::Undo( SwUndoIter& rUndoIter )
+{
+    SwDoc& rDoc = rUndoIter.GetDoc();
+
+    RemoveIdxFromSection( rDoc, nSectNodePos );
+
+    SwSectionNode* pNd = rDoc.GetNodes()[ nSectNodePos ]->GetSectionNode();
+    ASSERT( pNd, "wo ist mein SectionNode?" );
+
+    if( IsRedlineOn( GetRedlineMode() ))
+        rDoc.DeleteRedline( *pNd );
+
+    // lag keine Selektion vor ??
+    SwNodeIndex aIdx( *pNd );
+    if( ( !nEndNode && STRING_MAXLEN == nEndCntnt ) ||
+        ( nSttNode == nEndNode && nSttCntnt == nEndCntnt ))
+        // loesche einfach alle Nodes
+        rDoc.GetNodes().Delete( aIdx, pNd->EndOfSectionIndex() -
+                                        aIdx.GetIndex() );
+    else
+        // einfach das Format loeschen, der Rest erfolgt automatisch
+        rDoc.DelSectionFmt( pNd->GetSection().GetFmt() );
+
+    // muessen wir noch zusammenfassen ?
+    if( bSplitAtStt )
+        Join( rDoc, nSttNode );
+
+    if( bSplitAtEnd )
+        Join( rDoc, nEndNode );
+
+    if( pHistory )
+        pHistory->TmpRollback( &rDoc, 0, FALSE );
+
+    if( bUpdateFtn )
+        rDoc.GetFtnIdxs().UpdateFtn( aIdx );
+
+    SetPaM( rUndoIter );
+}
+
+
+void SwUndoInsSection::Redo( SwUndoIter& rUndoIter )
+{
+    SwDoc& rDoc = rUndoIter.GetDoc();
+    SetPaM( rUndoIter );
+
+    const SwTOXBaseSection* pUpdateTOX = 0;
+    if( pSection->ISA( SwTOXBaseSection ))
+    {
+        const SwTOXBase& rBase = *(SwTOXBaseSection*)pSection;
+        pUpdateTOX = rDoc.InsertTableOf( *rUndoIter.pAktPam->GetPoint(),
+                                        rBase, pAttr, TRUE );
+    }
+    else
+        rDoc.Insert( *rUndoIter.pAktPam, *pSection, pAttr, TRUE );
+
+    if( pHistory )
+        pHistory->SetTmpEnd( pHistory->Count() );
+
+    SwSectionNode* pSectNd = rDoc.GetNodes()[ nSectNodePos ]->GetSectionNode();
+    if( pRedlData && IsRedlineOn( GetRedlineMode() ))
+    {
+        SwRedlineMode eOld = rDoc.GetRedlineMode();
+        rDoc.SetRedlineMode_intern( eOld & ~REDLINE_IGNORE );
+
+        SwPaM aPam( *pSectNd->EndOfSectionNode(), *pSectNd, 1 );
+        rDoc.AppendRedline( new SwRedline( *pRedlData, aPam ));
+        rDoc.SetRedlineMode_intern( eOld );
+    }
+    else if( !( REDLINE_IGNORE & GetRedlineMode() ) &&
+            rDoc.GetRedlineTbl().Count() )
+    {
+        SwPaM aPam( *pSectNd->EndOfSectionNode(), *pSectNd, 1 );
+        rDoc.SplitRedline( aPam );
+    }
+
+    if( pUpdateTOX )
+    {
+        // Formatierung anstossen
+        SwEditShell* pESh = rDoc.GetEditShell();
+        if( pESh )
+            pESh->CalcLayout();
+
+        // Seitennummern eintragen
+        ((SwTOXBaseSection*)pUpdateTOX)->UpdatePageNum();
+    }
+}
+
+
+void SwUndoInsSection::Repeat( SwUndoIter& rUndoIter )
+{
+    if( pSection->ISA( SwTOXBaseSection ))
+    {
+        const SwTOXBase& rBase = *(SwTOXBaseSection*)pSection;
+        rUndoIter.GetDoc().InsertTableOf( *rUndoIter.pAktPam->GetPoint(),
+                                            rBase, pAttr, TRUE );
+    }
+    else
+        rUndoIter.GetDoc().Insert( *rUndoIter.pAktPam, *pSection, pAttr );
+}
+
+
+void SwUndoInsSection::Join( SwDoc& rDoc, ULONG nNode )
+{
+    SwNodeIndex aIdx( rDoc.GetNodes(), nNode );
+    SwTxtNode* pTxtNd = aIdx.GetNode().GetTxtNode();
+    ASSERT( pTxtNd, "wo ist mein TextNode?" );
+
+    {
+        RemoveIdxRel( nNode + 1, SwPosition( aIdx,
+                            SwIndex( pTxtNd, pTxtNd->GetTxt().Len() )));
+    }
+    pTxtNd->JoinNext();
+
+    if( pHistory )
+    {
+        SwIndex aCntIdx( pTxtNd, 0 );
+        pTxtNd->RstAttr( aCntIdx, pTxtNd->GetTxt().Len() );
+    }
+}
+
+
+void SwUndoInsSection::SaveSplitNode( SwTxtNode* pTxtNd, BOOL bAtStt )
+{
+    if( pTxtNd->GetpSwpHints() )
+    {
+        if( !pHistory )
+            pHistory = new SwHistory;
+        pHistory->CopyAttr( pTxtNd->GetpSwpHints(), pTxtNd->GetIndex(), 0,
+                            pTxtNd->GetTxt().Len(), FALSE );
+    }
+
+    if( bAtStt )
+        bSplitAtStt = TRUE;
+    else
+        bSplitAtEnd = TRUE;
+}
+
+
+// -----------------------------
+
+SwUndoDelSection::SwUndoDelSection( const SwSectionFmt& rFmt )
+     : SwUndo( UNDO_DELSECTION )
+{
+    const SwSection& rSect = *rFmt.GetSection();
+    if( rSect.ISA( SwTOXBaseSection ))
+    {
+        const SwTOXBase& rBase = (SwTOXBaseSection&)rSect;
+        pSection = new SwTOXBaseSection( rBase );
+    }
+    else
+        pSection = new SwSection( rSect.GetType(), rSect.GetName() );
+    *pSection = rSect;
+
+    pAttr = ::lcl_GetAttrSet( rSect );
+
+    const SwNodeIndex* pIdx = rFmt.GetCntnt().GetCntntIdx();
+    nSttNd = pIdx->GetIndex();
+    nEndNd = pIdx->GetNode().EndOfSectionIndex();
+}
+
+
+SwUndoDelSection::~SwUndoDelSection()
+{
+    delete pSection;
+    delete pAttr;
+}
+
+
+void SwUndoDelSection::Undo( SwUndoIter& rUndoIter )
+{
+    SwDoc& rDoc = rUndoIter.GetDoc();
+
+    if( pSection->ISA( SwTOXBaseSection ))
+    {
+        const SwTOXBase& rBase = *(SwTOXBaseSection*)pSection;
+        SwTOXBaseSection* pBaseSect =  (SwTOXBaseSection*)rDoc.InsertTableOf(
+                                        nSttNd, nEndNd-2, rBase, pAttr );
+    }
+    else
+    {
+        SwNodeIndex aStt( rDoc.GetNodes(), nSttNd );
+        SwNodeIndex aEnd( rDoc.GetNodes(), nEndNd-2 );
+        SwSectionFmt* pFmt = rDoc.MakeSectionFmt( 0 );
+        if( pAttr )
+            pFmt->SetAttr( *pAttr );
+
+        rDoc.GetNodes().InsertSection( aStt, *pFmt, *pSection, &aEnd );
+
+        if( SFX_ITEM_SET == pFmt->GetItemState( RES_FTN_AT_TXTEND ) ||
+            SFX_ITEM_SET == pFmt->GetItemState( RES_END_AT_TXTEND ))
+            rDoc.GetFtnIdxs().UpdateFtn( aStt );
+
+    }
+}
+
+
+void SwUndoDelSection::Redo( SwUndoIter& rUndoIter )
+{
+    SwDoc& rDoc = rUndoIter.GetDoc();
+
+    SwSectionNode* pNd = rDoc.GetNodes()[ nSttNd ]->GetSectionNode();
+    ASSERT( pNd, "wo ist mein SectionNode?" );
+    // einfach das Format loeschen, der Rest erfolgt automatisch
+    rDoc.DelSectionFmt( pNd->GetSection().GetFmt() );
+}
+
+
+
+SwUndoChgSection::SwUndoChgSection( const SwSectionFmt& rFmt, BOOL bOnlyAttr )
+     : SwUndo( UNDO_CHGSECTION ), bOnlyAttrChgd( bOnlyAttr )
+{
+    const SwSection& rSect = *rFmt.GetSection();
+    pSection = new SwSection( rSect.GetType(), rSect.GetName() );
+    *pSection = rSect;
+
+    pAttr = ::lcl_GetAttrSet( rSect );
+
+    nSttNd = rFmt.GetCntnt().GetCntntIdx()->GetIndex();
+}
+
+
+SwUndoChgSection::~SwUndoChgSection()
+{
+    delete pSection;
+    delete pAttr;
+}
+
+
+void SwUndoChgSection::Undo( SwUndoIter& rUndoIter )
+{
+    SwDoc& rDoc = rUndoIter.GetDoc();
+    SwSectionNode* pSectNd = rDoc.GetNodes()[ nSttNd ]->GetSectionNode();
+    ASSERT( pSectNd, "wo ist mein SectionNode?" );
+
+    SwSection& rNdSect = pSectNd->GetSection();
+    SwFmt* pFmt = rNdSect.GetFmt();
+
+    SfxItemSet* pCur = ::lcl_GetAttrSet( rNdSect );
+    if( pAttr )
+    {
+        // das Content- und Protect-Item muss bestehen bleiben
+        const SfxPoolItem* pItem;
+        pAttr->Put( pFmt->GetAttr( RES_CNTNT ));
+        if( SFX_ITEM_SET == pFmt->GetItemState( RES_PROTECT, TRUE, &pItem ))
+            pAttr->Put( *pItem );
+        pFmt->DelDiffs( *pAttr );
+        pAttr->ClearItem( RES_CNTNT );
+        pFmt->SetAttr( *pAttr );
+        delete pAttr;
+    }
+    else
+    {
+        // dann muessen die alten entfernt werden
+        pFmt->ResetAttr( RES_FRMATR_BEGIN, RES_BREAK );
+        pFmt->ResetAttr( RES_HEADER, RES_OPAQUE );
+        pFmt->ResetAttr( RES_SURROUND, RES_FRMATR_END-1 );
+    }
+    pAttr = pCur;
+
+    if( !bOnlyAttrChgd )
+    {
+        BOOL bUpdate = (!rNdSect.IsLinkType() && pSection->IsLinkType() ) ||
+                            ( pSection->GetLinkFileName().Len() &&
+                                pSection->GetLinkFileName() !=
+                                rNdSect.GetLinkFileName());
+
+        SwSection* pTmp = new SwSection( CONTENT_SECTION, aEmptyStr );
+        *pTmp = rNdSect;        // das aktuelle sichern
+
+        rNdSect = *pSection;    // das alte setzen
+
+        delete pSection;
+        pSection = pTmp;        // das aktuelle ist jetzt das alte
+
+        if( bUpdate )
+            rNdSect.CreateLink( CREATE_UPDATE );
+        else if( CONTENT_SECTION == rNdSect.GetType() && rNdSect.IsConnected() )
+        {
+            rNdSect.Disconnect();
+            rDoc.GetLinkManager().Remove( rNdSect.GetBaseLink() );
+        }
+    }
+}
+
+
+void SwUndoChgSection::Redo( SwUndoIter& rUndoIter )
+{
+    Undo( rUndoIter );
+}
+
+
+
+SwUndoChgSectPsswd::SwUndoChgSectPsswd( const String& rOld )
+    : SwUndo( UNDO_CHGSECTIONPASSWD ), sPasswd( rOld )
+{
+}
+
+
+void SwUndoChgSectPsswd::Undo( SwUndoIter& rIter )
+{
+    SwDoc& rDoc = rIter.GetDoc();
+    String s( rDoc.GetSectionPasswd() );
+    rDoc.ChgSectionPasswd( sPasswd );
+    sPasswd = s;
+}
+
+
+void SwUndoChgSectPsswd::Redo( SwUndoIter& rUndoIter )
+{
+    Undo( rUndoIter );
+}
+
+
+/*************************************************************************
+
+      Source Code Control System - Header
+
+      $Header: /zpool/svn/migration/cvs_rep_09_09_08/code/sw/source/core/undo/unsect.cxx,v 1.1.1.1 2000-09-19 00:08:28 hr Exp $
+
+      Source Code Control System - Update
+
+      $Log: not supported by cvs2svn $
+      Revision 1.38  2000/09/18 16:04:29  willem.vandorp
+      OpenOffice header added.
+
+      Revision 1.37  2000/05/09 10:04:40  jp
+      Changes for Unicode
+
+      Revision 1.36  2000/01/03 16:57:35  jp
+      Bug #71369#: InsSection:Redo - call UpdatePageNum if the Section is a TOX
+
+      Revision 1.35  1999/12/21 11:53:59  jp
+      Bug #71137#: call UpdateFtn if the deleted section contains FtnEndAtEnd attributes
+
+      Revision 1.34  1999/12/17 14:01:01  jp
+      Bug #70995#: InsertSection - move PageDesc/Break attributes into the first Node of the Section
+
+      Revision 1.33  1999/11/04 17:12:46  jp
+      SwFmtFtn-/-EndAtTxtEnd: with own numbersequences
+
+      Revision 1.32  1999/09/09 17:13:06  jp
+      Redo: set attrset at TOX too
+
+      Revision 1.31  1999/08/17 11:57:20  OS
+      extended indexes: get/set section attributes
+
+
+      Rev 1.30   17 Aug 1999 13:57:20   OS
+   extended indexes: get/set section attributes
+
+      Rev 1.29   27 Jul 1999 20:24:32   JP
+   replace class SwTOXBaseRange with SwTOXBaseSection - TOX use now SwSections
+
+      Rev 1.28   28 Jan 1999 18:13:26   JP
+   Task #57749#: Undo von Bereichs-Attributen (Spalten, Hintergr...)
+
+      Rev 1.27   02 Apr 1998 15:14:10   JP
+   Redo: Undo-Flag wird schon von der EditShell abgeschaltet
+
+      Rev 1.26   06 Feb 1998 18:05:58   JP
+   neu: einfuegen Bereich beachtet Redlines
+
+      Rev 1.25   23 Jan 1998 15:59:38   MA
+   includes
+
+      Rev 1.24   28 Nov 1997 10:48:04   MA
+   includes
+
+      Rev 1.23   20 Nov 1997 18:28:20   MA
+   includes
+
+      Rev 1.22   03 Nov 1997 13:06:08   MA
+   precomp entfernt
+
+      Rev 1.21   09 Oct 1997 15:45:30   JP
+   Umstellung NodeIndex/-Array/BigPtrArray
+
+      Rev 1.20   15 Aug 1997 12:38:02   OS
+   charatr/frmatr/txtatr aufgeteilt
+
+      Rev 1.19   11 Jun 1997 10:44:08   JP
+   pure virtual Repeat wurde zur virtual Methode, Segment Pragma entfernt
+
+      Rev 1.18   29 May 1997 22:56:56   JP
+   CopyAttr/CopyFmtAttr von SwUndo zur SwHistory verschoben
+
+      Rev 1.17   29 Oct 1996 14:55:12   JP
+   am Doc ist das NodesArray nur noch ueber Get..() zugaenglich
+
+      Rev 1.16   23 Sep 1996 20:06:28   JP
+   SetTmpEnd: DocPtr entfernt
+
+      Rev 1.15   29 Aug 1996 10:18:48   OS
+   includes
+
+      Rev 1.14   30 May 1996 21:51:04   JP
+   Bug #28160#: BereichsPasswort aendern undofaehig gemacht
+
+      Rev 1.13   25 Mar 1996 17:16:36   MA
+   Umstellung soref
+
+      Rev 1.12   21 Mar 1996 14:42:22   JP
+   ChgSection: Links updaten
+
+      Rev 1.11   24 Nov 1995 17:14:00   OM
+   PCH->PRECOMPILED
+
+      Rev 1.10   23 Nov 1995 12:06:08   AMA
+   Fix/Opt: BLC-Warnings.
+
+      Rev 1.9   26 Jul 1995 18:50:46   JP
+   Bug16540: SectionFormat ueber Doc-SS loeschen
+
+      Rev 1.8   22 Jun 1995 19:33:22   JP
+   virt. Methode GetUndoRange vernichtet, Objecte rufen jetzt die Basis-Klasse
+
+      Rev 1.7   04 Mar 1995 13:31:06   MA
+   unnoetiges SEXPORT entfernt.
+
+      Rev 1.6   23 Feb 1995 23:03:26   ER
+   sexport
+
+      Rev 1.5   08 Feb 1995 23:52:38   ER
+   undo.hxx -> swundo.hxx wegen solar undo.hxx
+
+*************************************************************************/
+
+
diff --git a/sw/source/core/undo/unsort.cxx b/sw/source/core/undo/unsort.cxx
new file mode 100644
index 000000000000..ffbe437f001c
--- /dev/null
+++ b/sw/source/core/undo/unsort.cxx
@@ -0,0 +1,422 @@
+/*************************************************************************
+ *
+ *  $RCSfile: unsort.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:28 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include            // fuer die UndoIds
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _SWTABLE_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _NODE_HXX //autogen
+#include 
+#endif
+#ifndef _UNDOBJ_HXX
+#include 
+#endif
+#ifndef _SORTOPT_HXX
+#include 
+#endif
+#ifndef _DOCSORT_HXX
+#include 
+#endif
+#ifndef _REDLINE_HXX
+#include 
+#endif
+
+
+
+inline SwDoc& SwUndoIter::GetDoc() const { return *pAktPam->GetDoc(); }
+
+/*--------------------------------------------------------------------
+    Beschreibung:  Undo fuers Sorting
+ --------------------------------------------------------------------*/
+
+
+SV_IMPL_PTRARR(SwSortList, SwSortUndoElement*)
+SV_IMPL_PTRARR(SwUndoSortList, SwNodeIndex*)
+
+
+SwSortUndoElement::~SwSortUndoElement()
+{
+    // sind String Pointer gespeichert ??
+    if( 0xffffffff != SORT_TXT_TBL.TXT.nKenn )
+    {
+        delete SORT_TXT_TBL.TBL.pSource;
+        delete SORT_TXT_TBL.TBL.pTarget;
+    }
+}
+
+
+SwUndoSort::SwUndoSort(const SwPaM& rRg, const SwSortOptions& rOpt)
+    : SwUndo(UNDO_SORT_TXT), SwUndRng(rRg), pUndoTblAttr( 0 ),
+    pRedlData( 0 )
+{
+    pSortOpt = new SwSortOptions(rOpt);
+}
+
+
+SwUndoSort::SwUndoSort( ULONG nStt, ULONG nEnd, const SwTableNode& rTblNd,
+                        const SwSortOptions& rOpt, BOOL bSaveTable )
+    : SwUndo(UNDO_SORT_TBL), pUndoTblAttr( 0 ), pRedlData( 0 )
+{
+    nSttNode = nStt;
+    nEndNode = nEnd;
+    nTblNd   = rTblNd.GetIndex();
+
+    pSortOpt = new SwSortOptions(rOpt);
+    if( bSaveTable )
+        pUndoTblAttr = new SwUndoAttrTbl( rTblNd );
+}
+
+
+
+SwUndoSort::~SwUndoSort()
+{
+    delete pSortOpt;
+    delete pUndoTblAttr;
+    delete pRedlData;
+}
+
+
+
+void SwUndoSort::Undo( SwUndoIter& rIter)
+{
+    SwDoc&  rDoc = rIter.GetDoc();
+    if(pSortOpt->bTable)
+    {
+        // Undo Tabelle
+        RemoveIdxFromSection( rDoc, nSttNode, &nEndNode );
+
+        if( pUndoTblAttr )
+            pUndoTblAttr->Undo( rIter );
+
+        SwTableNode* pTblNd = rDoc.GetNodes()[ nTblNd ]->GetTableNode();
+        pTblNd->DelFrms();
+        SwNodeIndex aBehindIdx( *pTblNd->EndOfSectionNode() );
+        rDoc.GetNodes().GoNext( &aBehindIdx );          // Index in Cntnt, hinter der Tabelle
+        const SwTable& rTbl = pTblNd->GetTable();
+
+        SwMovedBoxes aMovedList;
+        for( USHORT i=0; i < aSortList.Count(); i++)
+        {
+            const SwTableBox* pSource = rTbl.GetTblBox(
+                    *aSortList[i]->SORT_TXT_TBL.TBL.pSource );
+            const SwTableBox* pTarget = rTbl.GetTblBox(
+                    *aSortList[i]->SORT_TXT_TBL.TBL.pTarget );
+
+            // zurueckverschieben
+            MoveCell(&rDoc, pTarget, pSource,
+                     USHRT_MAX != aMovedList.GetPos(pSource) );
+
+            // schon Verschobenen in der Liste merken
+            aMovedList.Insert(pTarget, aMovedList.Count() );
+        }
+        pTblNd->MakeFrms( &aBehindIdx);
+    }
+    else
+    {
+        // Undo Text
+        RemoveIdx( *rIter.pAktPam );
+
+        // fuer die sorted Positions einen Index anlegen.
+        // JP 25.11.97: Die IndexList muss aber nach SourcePosition
+        //              aufsteigend sortiert aufgebaut werden
+        SwUndoSortList aIdxList( (BYTE)aSortList.Count() );
+        for(USHORT i=0; i < aSortList.Count(); ++i)
+            for( USHORT ii=0; ii < aSortList.Count(); ++ii )
+                if( aSortList[ii]->SORT_TXT_TBL.TXT.nSource == nSttNode + i )
+                {
+                    SwNodeIndex* pIdx = new SwNodeIndex( rDoc.GetNodes(),
+                        aSortList[ii]->SORT_TXT_TBL.TXT.nTarget );
+                    aIdxList.C40_INSERT(SwNodeIndex, pIdx, i );
+                    break;
+                }
+
+        for(i=0; i < aSortList.Count(); ++i)
+        {
+            SwNodeIndex aIdx( rDoc.GetNodes(), nSttNode + i );
+            SwNodeRange aRg( *aIdxList[i], 0, *aIdxList[i], 1 );
+            rDoc.Move(aRg, aIdx);
+        }
+        // Indixes loeschen
+        aIdxList.DeleteAndDestroy(0, aIdxList.Count());
+        SetPaM( rIter, TRUE );
+    }
+}
+
+
+void SwUndoSort::Redo( SwUndoIter& rIter)
+{
+    SwDoc& rDoc = rIter.GetDoc();
+
+    if(pSortOpt->bTable)
+    {
+        // Redo bei Tabelle
+        RemoveIdxFromSection( rDoc, nSttNode, &nEndNode );
+
+        SwTableNode* pTblNd = rDoc.GetNodes()[ nTblNd ]->GetTableNode();
+        pTblNd->DelFrms();
+        SwNodeIndex aBehindIdx( *pTblNd->EndOfSectionNode() );
+        rDoc.GetNodes().GoNext( &aBehindIdx );            // Index in Cntnt, hinter der Tabelle
+        const SwTable& rTbl = pTblNd->GetTable();
+
+        SwMovedBoxes aMovedList;
+        for(USHORT i=0; i < aSortList.Count(); ++i)
+        {
+            const SwTableBox* pSource = rTbl.GetTblBox(
+                    (const String&) *aSortList[i]->SORT_TXT_TBL.TBL.pSource );
+            const SwTableBox* pTarget = rTbl.GetTblBox(
+                    (const String&) *aSortList[i]->SORT_TXT_TBL.TBL.pTarget );
+
+            // zurueckverschieben
+            MoveCell(&rDoc, pSource, pTarget,
+                     USHRT_MAX != aMovedList.GetPos( pTarget ) );
+            // schon Verschobenen in der Liste merken
+            aMovedList.Insert( pSource, aMovedList.Count() );
+        }
+
+        if( pUndoTblAttr )
+            pUndoTblAttr->Redo( rIter );
+
+        pTblNd->MakeFrms( &aBehindIdx );
+    }
+    else
+    {
+        // Redo bei Text
+        RemoveIdx( *rIter.pAktPam );
+
+        SwUndoSortList aIdxList( (BYTE)aSortList.Count() );
+        for(USHORT i=0; i < aSortList.Count(); ++i)
+        {   // aktuelle Pos ist die Ausgangslage
+            SwNodeIndex* pIdx = new SwNodeIndex( rDoc.GetNodes(),
+                    aSortList[i]->SORT_TXT_TBL.TXT.nSource);
+            aIdxList.C40_INSERT( SwNodeIndex, pIdx, i );
+        }
+
+        for(i=0; i < aSortList.Count(); ++i)
+        {
+            SwNodeIndex aIdx( rDoc.GetNodes(), nSttNode + i);
+            SwNodeRange aRg( *aIdxList[i], 0, *aIdxList[i], 1 );
+            rDoc.Move(aRg, aIdx);
+        }
+        // Indixes loeschen
+        aIdxList.DeleteAndDestroy(0, aIdxList.Count());
+        SetPaM( rIter, TRUE );
+        const SwTxtNode* pTNd = rIter.pAktPam->GetNode()->GetTxtNode();
+        if( pTNd )
+            rIter.pAktPam->GetPoint()->nContent = pTNd->GetTxt().Len();
+    }
+}
+
+
+void SwUndoSort::Repeat(SwUndoIter& rIter)
+{
+    if(!pSortOpt->bTable)
+    {
+        SwPaM* pPam = rIter.pAktPam;
+        SwDoc& rDoc = *pPam->GetDoc();
+
+        if( !rDoc.IsIdxInTbl( pPam->Start()->nNode ) )
+            rDoc.SortText(*pPam, *pSortOpt);
+    }
+    // Tabelle ist nicht Repeat-Faehig
+    rIter.pLastUndoObj = this;
+}
+
+
+void SwUndoSort::RemoveIdx( SwPaM& rPam )
+{
+    rPam.DeleteMark();
+    rPam.GetPoint()->nNode = nSttNode;
+
+    SwCntntNode* pCNd = rPam.GetCntntNode();
+    xub_StrLen nLen = pCNd->Len();
+    if( nLen >= nSttCntnt )
+        nLen = nSttCntnt;
+    rPam.GetPoint()->nContent.Assign(pCNd, nLen );
+    rPam.SetMark();
+
+    rPam.GetPoint()->nNode = nEndNode;
+    pCNd = rPam.GetCntntNode();
+    nLen = pCNd->Len();
+    if( nLen >= nEndCntnt )
+        nLen = nEndCntnt;
+    rPam.GetPoint()->nContent.Assign(pCNd, nLen );
+    RemoveIdxFromRange( rPam, TRUE );
+}
+
+
+void SwUndoSort::Insert( const String& rOrgPos, const String& rNewPos)
+{
+    SwSortUndoElement* pEle = new SwSortUndoElement(rOrgPos, rNewPos);
+    aSortList.C40_INSERT( SwSortUndoElement, pEle, aSortList.Count() );
+}
+
+
+void SwUndoSort::Insert( ULONG nOrgPos, ULONG nNewPos)
+{
+    SwSortUndoElement* pEle = new SwSortUndoElement(nOrgPos, nNewPos);
+    aSortList.C40_INSERT( SwSortUndoElement, pEle, aSortList.Count() );
+}
+
+
+/*************************************************************************
+
+      Source Code Control System - Header
+
+      $Header: /zpool/svn/migration/cvs_rep_09_09_08/code/sw/source/core/undo/unsort.cxx,v 1.1.1.1 2000-09-19 00:08:28 hr Exp $
+
+      Source Code Control System - Update
+
+      $Log: not supported by cvs2svn $
+      Revision 1.45  2000/09/18 16:04:29  willem.vandorp
+      OpenOffice header added.
+
+      Revision 1.44  2000/05/09 10:04:47  jp
+      Changes for Unicode
+
+      Revision 1.43  1998/04/02 13:14:10  JP
+      Redo: Undo-Flag wird schon von der EditShell abgeschaltet
+
+
+      Rev 1.42   02 Apr 1998 15:14:10   JP
+   Redo: Undo-Flag wird schon von der EditShell abgeschaltet
+
+      Rev 1.41   13 Feb 1998 10:31:48   JP
+   compiler error
+
+      Rev 1.40   12 Feb 1998 20:14:00   JP
+   ueberfluessige Code entfernt
+
+      Rev 1.39   12 Jan 1998 16:54:46   TJ
+   include
+
+      Rev 1.38   08 Jan 1998 21:09:28   JP
+   weitere Redlining Erweiterung
+
+      Rev 1.37   19 Dec 1997 12:14:24   JP
+   Undo: Redlining beachten
+
+      Rev 1.36   25 Nov 1997 12:34:50   JP
+   Bug #45167#: Undo auf Sort - die Move Reihenfolge muss beachtet werden
+
+      Rev 1.35   03 Nov 1997 13:06:08   MA
+   precomp entfernt
+
+      Rev 1.34   29 Oct 1997 17:04:12   JP
+   Bug #45167#: Redo-SortText - Source/Target vertauschen
+
+      Rev 1.33   09 Oct 1997 15:45:40   JP
+   Umstellung NodeIndex/-Array/BigPtrArray
+
+      Rev 1.32   11 Sep 1997 17:58:48   JP
+   Bug #41397#: Sortieren von Tabellen - Formeln/Werte der Boxen mitnehmen
+
+      Rev 1.31   18 Aug 1997 10:34:54   OS
+   includes
+
+      Rev 1.30   11 Jun 1997 10:44:08   JP
+   pure virtual Repeat wurde zur virtual Methode, Segment Pragma entfernt
+
+      Rev 1.29   29 Oct 1996 14:55:26   JP
+   am Doc ist das NodesArray nur noch ueber Get..() zugaenglich
+
+      Rev 1.28   14 May 1996 11:35:32   JP
+   jetzt der richtige fix fuer Bug #27768#
+
+      Rev 1.27   13 May 1996 18:19:20   JP
+   Bug #27768#: Redo: Code sollte der gleiche wie beim Undo sein
+
+      Rev 1.26   24 Apr 1996 15:55:56   TRI
+   WTC Anpassung
+
+      Rev 1.25   24 Nov 1995 17:13:56   OM
+   PCH->PRECOMPILED
+
+      Rev 1.24   17 Nov 1995 10:20:40   MA
+   Segmentierung
+
+      Rev 1.23   27 Jul 1995 08:48:28   mk
+   an SCC4.0.1a angepasst (MDA)
+
+      Rev 1.22   22 Jun 1995 19:33:14   JP
+   virt. Methode GetUndoRange vernichtet, Objecte rufen jetzt die Basis-Klasse
+
+      Rev 1.21   04 Mar 1995 13:31:24   MA
+   unnoetiges SEXPORT entfernt.
+
+*************************************************************************/
+
diff --git a/sw/source/core/undo/unspnd.cxx b/sw/source/core/undo/unspnd.cxx
new file mode 100644
index 000000000000..87aee2013568
--- /dev/null
+++ b/sw/source/core/undo/unspnd.cxx
@@ -0,0 +1,380 @@
+/*************************************************************************
+ *
+ *  $RCSfile: unspnd.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:28 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "doc.hxx"
+#include "pam.hxx"
+#include "swtable.hxx"
+#include "ndtxt.hxx"
+#include "swundo.hxx"           // fuer die UndoIds
+
+#ifndef _SVX_BRKITEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _FMTPDSC_HXX //autogen
+#include 
+#endif
+#ifndef _FRMFMT_HXX //autogen
+#include 
+#endif
+#include "undobj.hxx"
+#include "rolbck.hxx"
+#include "redline.hxx"
+#include "docary.hxx"
+
+
+inline SwDoc& SwUndoIter::GetDoc() const { return *pAktPam->GetDoc(); }
+
+
+//------------------------------------------------------------------
+
+// SPLITNODE
+
+
+SwUndoSplitNode::SwUndoSplitNode( SwDoc* pDoc, const SwPosition& rPos,
+                                    BOOL bChkTable )
+    : SwUndo( UNDO_SPLITNODE ), nNode( rPos.nNode.GetIndex() ),
+        nCntnt( rPos.nContent.GetIndex() ), pHistory( 0 ),
+        bTblFlag( FALSE ), bChkTblStt( bChkTable ), pRedlData( 0 )
+{
+    SwTxtNode* pTxtNd = pDoc->GetNodes()[ rPos.nNode ]->GetTxtNode();
+    ASSERT( pTxtNd, "nur beim TextNode rufen!" );
+    if( pTxtNd->GetpSwpHints() )
+    {
+        pHistory = new SwHistory;
+        pHistory->CopyAttr( pTxtNd->GetpSwpHints(), nNode, 0,
+                            pTxtNd->GetTxt().Len(), FALSE );
+        if( !pHistory->Count() )
+            DELETEZ( pHistory );
+    }
+    // Redline beachten
+    if( pDoc->IsRedlineOn() )
+    {
+        pRedlData = new SwRedlineData( REDLINE_INSERT, pDoc->GetRedlineAuthor() );
+        SetRedlineMode( pDoc->GetRedlineMode() );
+    }
+}
+
+
+
+
+SwUndoSplitNode::~SwUndoSplitNode()
+{
+    delete pHistory;
+    delete pRedlData;
+}
+
+
+
+void SwUndoSplitNode::Undo( SwUndoIter& rUndoIter )
+{
+    SwDoc* pDoc = &rUndoIter.GetDoc();
+    SwPaM& rPam = *rUndoIter.pAktPam;
+    rPam.DeleteMark();
+    if( bTblFlag )
+    {
+        // dann wurde direkt vor der akt. Tabelle ein TextNode eingefuegt.
+        SwNodeIndex& rIdx = rPam.GetPoint()->nNode;
+        rIdx = nNode;
+        SwTxtNode* pTNd;
+        SwNode* pCurrNd = pDoc->GetNodes()[ nNode + 1 ];
+        SwTableNode* pTblNd = pCurrNd->FindTableNode();
+        if( pCurrNd->IsCntntNode() && pTblNd &&
+            0 != ( pTNd = pDoc->GetNodes()[ pTblNd->GetIndex()-1 ]->GetTxtNode() ))
+        {
+            // verschiebe die BreakAttribute noch
+            SwFrmFmt* pTableFmt = pTblNd->GetTable().GetFrmFmt();
+            const SfxItemSet* pNdSet = pTNd->GetpSwAttrSet();
+            if( pNdSet )
+            {
+                const SfxPoolItem *pItem;
+                if( SFX_ITEM_SET == pNdSet->GetItemState( RES_PAGEDESC, FALSE,
+                    &pItem ) )
+                    pTableFmt->SetAttr( *pItem );
+
+                if( SFX_ITEM_SET == pNdSet->GetItemState( RES_BREAK, FALSE,
+                     &pItem ) )
+                    pTableFmt->SetAttr( *pItem );
+            }
+
+            // dann loesche den wieder
+            SwNodeIndex aDelNd( *pTblNd, -1 );
+            rPam.GetPoint()->nContent.Assign( (SwCntntNode*)pCurrNd, 0 );
+            RemoveIdxRel( aDelNd.GetIndex(), *rPam.GetPoint() );
+            pDoc->GetNodes().Delete( aDelNd );
+        }
+    }
+    else
+    {
+        SwTxtNode * pTNd = pDoc->GetNodes()[ nNode ]->GetTxtNode();
+        if( pTNd )
+        {
+            rPam.GetPoint()->nNode = *pTNd;
+            rPam.GetPoint()->nContent.Assign( pTNd, pTNd->GetTxt().Len() );
+
+            if( IsRedlineOn( GetRedlineMode() ))
+            {
+                rPam.SetMark();
+                rPam.GetMark()->nNode++;
+                rPam.GetMark()->nContent.Assign( rPam.GetMark()->
+                                    nNode.GetNode().GetCntntNode(), 0 );
+                pDoc->DeleteRedline( rPam );
+                rPam.DeleteMark();
+            }
+
+            RemoveIdxRel( nNode+1, *rPam.GetPoint() );
+
+            pTNd->JoinNext();
+            if( pHistory )
+            {
+                rPam.GetPoint()->nContent = 0;
+                rPam.SetMark();
+                rPam.GetPoint()->nContent = pTNd->GetTxt().Len();
+
+                pDoc->RstTxtAttr( rPam, TRUE );
+                pHistory->TmpRollback( pDoc, 0, FALSE );
+            }
+        }
+    }
+
+    // setze noch den Cursor auf den Undo-Bereich
+    rPam.DeleteMark();
+    rPam.GetPoint()->nNode = nNode;
+    rPam.GetPoint()->nContent.Assign( rPam.GetCntntNode(), nCntnt );
+}
+
+
+void SwUndoSplitNode::Repeat( SwUndoIter& rUndoIter )
+{
+    if( UNDO_SPLITNODE == rUndoIter.GetLastUndoId() )
+        return;
+    rUndoIter.GetDoc().SplitNode( *rUndoIter.pAktPam->GetPoint(), bChkTblStt );
+    rUndoIter.pLastUndoObj = this;
+}
+
+
+void SwUndoSplitNode::Redo( SwUndoIter& rUndoIter )
+{
+    SwPaM& rPam = *rUndoIter.pAktPam;
+    ULONG nOldNode = rPam.GetPoint()->nNode.GetIndex();
+    rPam.GetPoint()->nNode = nNode;
+    SwTxtNode * pTNd = rPam.GetNode()->GetTxtNode();
+    if( pTNd )              // sollte eigentlich immer ein TextNode sein !!
+    {
+        rPam.GetPoint()->nContent.Assign( pTNd, nCntnt );
+
+        SwDoc* pDoc = rPam.GetDoc();
+        pDoc->SplitNode( *rPam.GetPoint(), bChkTblStt );
+
+        if( pHistory )
+            pHistory->SetTmpEnd( pHistory->Count() );
+
+        if( ( pRedlData && IsRedlineOn( GetRedlineMode() )) ||
+            ( !( REDLINE_IGNORE & GetRedlineMode() ) &&
+                pDoc->GetRedlineTbl().Count() ))
+        {
+            rPam.SetMark();
+            if( rPam.Move( fnMoveBackward ))
+            {
+                if( pRedlData && IsRedlineOn( GetRedlineMode() ))
+                {
+                    SwRedlineMode eOld = pDoc->GetRedlineMode();
+                    pDoc->SetRedlineMode_intern( eOld & ~REDLINE_IGNORE );
+                    pDoc->AppendRedline( new SwRedline( *pRedlData, rPam ));
+                    pDoc->SetRedlineMode_intern( eOld );
+                }
+                else
+                    pDoc->SplitRedline( rPam );
+                rPam.Exchange();
+            }
+            rPam.DeleteMark();
+        }
+    }
+    else
+        rPam.GetPoint()->nNode = nOldNode;
+}
+
+
+/*************************************************************************
+
+      Source Code Control System - Header
+
+      $Header: /zpool/svn/migration/cvs_rep_09_09_08/code/sw/source/core/undo/unspnd.cxx,v 1.1.1.1 2000-09-19 00:08:28 hr Exp $
+
+      Source Code Control System - Update
+
+      $Log: not supported by cvs2svn $
+      Revision 1.41  2000/09/18 16:04:30  willem.vandorp
+      OpenOffice header added.
+
+      Revision 1.40  2000/07/03 19:25:15  jp
+      Bug #67696#: RstTxtAttr must delete TOX- and RefMarks
+
+      Revision 1.39  1998/04/02 13:14:10  JP
+      Redo: Undo-Flag wird schon von der EditShell abgeschaltet
+
+
+      Rev 1.38   02 Apr 1998 15:14:10   JP
+   Redo: Undo-Flag wird schon von der EditShell abgeschaltet
+
+      Rev 1.37   08 Jan 1998 20:56:02   JP
+   SwDoc::GetRedlineTbl returnt jetzt eine Referenz
+
+      Rev 1.36   19 Dec 1997 12:14:22   JP
+   Undo: Redlining beachten
+
+      Rev 1.35   03 Nov 1997 13:06:08   MA
+   precomp entfernt
+
+      Rev 1.34   30 Oct 1997 14:35:46   AMA
+   Chg: Kein AutoFlag mehr an Break bzw. PageDesc-Attributen
+
+      Rev 1.33   09 Oct 1997 15:45:40   JP
+   Umstellung NodeIndex/-Array/BigPtrArray
+
+      Rev 1.32   18 Aug 1997 10:34:54   OS
+   includes
+
+      Rev 1.31   15 Aug 1997 12:38:04   OS
+   charatr/frmatr/txtatr aufgeteilt
+
+      Rev 1.30   12 Aug 1997 12:36:46   OS
+   Header-Umstellung
+
+      Rev 1.29   07 Aug 1997 15:04:56   OM
+   Headerfile-Umstellung
+
+      Rev 1.28   07 Jul 1997 11:21:10   JP
+   Bug #41313#: SplitNode - Flag fuer Sonderbehandlung von 1.Box in 1.Tabelle
+
+      Rev 1.27   11 Jun 1997 10:44:08   JP
+   pure virtual Repeat wurde zur virtual Methode, Segment Pragma entfernt
+
+      Rev 1.26   29 May 1997 22:56:56   JP
+   CopyAttr/CopyFmtAttr von SwUndo zur SwHistory verschoben
+
+      Rev 1.25   06 May 1997 12:06:12   MA
+   swtablehxx aufgeteilt
+
+      Rev 1.24   06 Feb 1997 13:26:56   JP
+   BreakAttribute beachten
+
+      Rev 1.23   29 Jan 1997 14:57:02   JP
+   neu: Flag fuer Sonderbehandlung in Tabellen
+
+      Rev 1.22   29 Oct 1996 14:55:40   JP
+   am Doc ist das NodesArray nur noch ueber Get..() zugaenglich
+
+      Rev 1.21   23 Sep 1996 20:06:28   JP
+   SetTmpEnd: DocPtr entfernt
+
+      Rev 1.20   24 Nov 1995 17:14:02   OM
+   PCH->PRECOMPILED
+
+      Rev 1.19   23 Jun 1995 07:58:56   OS
+   +inline GetDoc
+
+      Rev 1.18   22 Jun 1995 19:33:36   JP
+   virt. Methode GetUndoRange vernichtet, Objecte rufen jetzt die Basis-Klasse
+
+      Rev 1.17   04 Mar 1995 13:31:44   MA
+   unnoetiges SEXPORT entfernt.
+
+      Rev 1.16   23 Feb 1995 23:04:22   ER
+   sexport
+
+      Rev 1.15   08 Feb 1995 23:52:32   ER
+   undo.hxx -> swundo.hxx wegen solar undo.hxx
+
+      Rev 1.14   24 Jan 1995 19:07:46   JP
+   JoinNext/-Prev: zus. Parameter - seine Position im NodesArray
+
+      Rev 1.13   15 Dec 1994 20:48:38   SWG
+   *ARR* Ersetzungen, svmem, __far_data etc.
+
+      Rev 1.12   25 Oct 1994 14:50:38   MA
+   PreHdr.
+
+      Rev 1.11   02 Aug 1994 16:48:08   JP
+   SwCntntNode::JoinNext/JoinPrev(): Nodes-Array nicht mehr als Parameter
+
+      Rev 1.10   15 Mar 1994 11:33:32   JP
+   TmpRollback: wenn vom gesamten Node die Attribute gesichert werden, dann
+       immer von vorne wieder setzen.
+
+      Rev 1.9   02 Mar 1994 19:50:34   MI
+   Underscore im Namen der #pragmas
+
+      Rev 1.8   17 Feb 1994 08:31:16   MI
+   SEG_FUNCDEFS ausgefuellt
+
+      Rev 1.7   16 Feb 1994 13:22:20   MI
+   Pragmas zurechtgerueckt
+
+*************************************************************************/
+
+
diff --git a/sw/source/core/undo/untbl.cxx b/sw/source/core/undo/untbl.cxx
new file mode 100644
index 000000000000..5066f68f25b9
--- /dev/null
+++ b/sw/source/core/undo/untbl.cxx
@@ -0,0 +1,3123 @@
+/*************************************************************************
+ *
+ *  $RCSfile: untbl.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:28 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#define ITEMID_BOXINFO      SID_ATTR_BORDER_INNER
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _SVX_BRKITEM_HXX //autogen
+#include 
+#endif
+
+#ifndef _FMTORNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTPDSC_HXX //autogen
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _NDARR_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _SWTABLE_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _CNTFRM_HXX
+#include 
+#endif
+#ifndef _TBLSEL_HXX
+#include 
+#endif
+#ifndef _HINTS_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include            // fuer die UndoIds
+#endif
+#ifndef _UNDOBJ_HXX
+#include 
+#endif
+#ifndef _ROLBCK_HXX
+#include 
+#endif
+#ifndef _DDEFLD_HXX
+#include 
+#endif
+#ifndef _TABCOL_HXX
+#include 
+#endif
+#ifndef _TABFRM_HXX
+#include 
+#endif
+#ifndef _ROWFRM_HXX
+#include 
+#endif
+#ifndef _CELLFRM_HXX
+#include 
+#endif
+#ifndef _SWCACHE_HXX
+#include 
+#endif
+#ifndef _TBLAFMT_HXX
+#include 
+#endif
+#ifndef _POOLFMT_HXX
+#include 
+#endif
+#ifndef _MVSAVE_HXX
+#include 
+#endif
+#ifndef _CELLATR_HXX
+#include 
+#endif
+#ifndef _SWTBLFMT_HXX
+#include 
+#endif
+#ifndef _SWDDETBL_HXX
+#include 
+#endif
+#ifndef _REDLINE_HXX
+#include 
+#endif
+#ifndef _NODE2LAY_HXX
+#include 
+#endif
+#ifndef _TBLRWCL_HXX
+#include 
+#endif
+#ifndef _FMTANCHR_HXX
+#include 
+#endif
+
+inline SwDoc& SwUndoIter::GetDoc() const { return *pAktPam->GetDoc(); }
+extern void ClearFEShellTabCols();
+
+typedef SfxItemSet* SfxItemSetPtr;
+SV_DECL_PTRARR_DEL( SfxItemSets, SfxItemSetPtr, 10, 5 )
+
+typedef SwUndoSaveSection* SwUndoSaveSectionPtr;
+SV_DECL_PTRARR_DEL( SwUndoSaveSections, SwUndoSaveSectionPtr, 0, 10 )
+
+typedef SwUndoMove* SwUndoMovePtr;
+SV_DECL_PTRARR_DEL( SwUndoMoves, SwUndoMovePtr, 0, 10 )
+
+struct SwTblToTxtSave;
+typedef SwTblToTxtSave* SwTblToTxtSavePtr;
+SV_DECL_PTRARR_DEL( SwTblToTxtSaves, SwTblToTxtSavePtr, 0, 10 )
+
+struct _UndoTblCpyTbl_Entry
+{
+    ULONG nBoxIdx, nOffset;
+    SfxItemSet* pBoxNumAttr;
+    SwUndoDelete* pUndo;
+
+    _UndoTblCpyTbl_Entry( const SwTableBox& rBox );
+    ~_UndoTblCpyTbl_Entry();
+};
+typedef _UndoTblCpyTbl_Entry* _UndoTblCpyTbl_EntryPtr;
+SV_DECL_PTRARR_DEL( _UndoTblCpyTbl_Entries, _UndoTblCpyTbl_EntryPtr, 0, 10 )
+
+class _SaveBox;
+class _SaveLine;
+
+class _SaveTable
+{
+    friend class _SaveBox;
+    friend class _SaveLine;
+    _SaveLine* pLine;
+    const SwTable* pSwTable;
+    SfxItemSets aSets;
+    SwFrmFmts aFrmFmts;
+    SfxItemSet aTblSet;
+    USHORT nLineCount;
+    BOOL bModifyBox : 1;
+    BOOL bSaveFormula : 1;
+
+public:
+    _SaveTable( const SwTable& rTbl, USHORT nLnCnt = USHRT_MAX,
+                BOOL bSaveFml = TRUE );
+    ~_SaveTable();
+
+    USHORT AddFmt( SwFrmFmt* pFmt );
+    void NewFrmFmt( const SwClient* pLnBx, BOOL bIsLine, USHORT nFmtPos,
+                    SwFrmFmt* pOldFmt );
+
+    void RestoreAttr( SwTable& rTbl, BOOL bModifyBox = FALSE );
+    void SaveCntntAttrs( SwDoc* pDoc );
+    void CreateNew( SwTable& rTbl, BOOL bCreateFrms = TRUE,
+                    BOOL bRestoreChart = TRUE );
+};
+
+class _SaveLine
+{
+    friend class _SaveTable;
+    friend class _SaveBox;
+
+    _SaveLine* pNext;
+    _SaveBox* pBox;
+    USHORT nItemSet;
+
+public:
+
+    _SaveLine( _SaveLine* pPrev, const SwTableLine& rLine, _SaveTable& rSTbl );
+    ~_SaveLine();
+
+    void RestoreAttr( SwTableLine& rLine, _SaveTable& rSTbl );
+    void SaveCntntAttrs( SwDoc* pDoc );
+
+    void CreateNew( SwTable& rTbl, SwTableBox& rParent, _SaveTable& rSTbl  );
+};
+
+class _SaveBox
+{
+    friend class _SaveLine;
+
+    _SaveBox* pNext;
+    ULONG nSttNode;
+    USHORT nItemSet;
+    union
+    {
+        SfxItemSets* pCntntAttrs;
+        _SaveLine* pLine;
+    } Ptrs;
+
+public:
+    _SaveBox( _SaveBox* pPrev, const SwTableBox& rBox, _SaveTable& rSTbl );
+    ~_SaveBox();
+
+    void RestoreAttr( SwTableBox& rBox, _SaveTable& rSTbl );
+    void SaveCntntAttrs( SwDoc* pDoc );
+
+    void CreateNew( SwTable& rTbl, SwTableLine& rParent, _SaveTable& rSTbl );
+};
+
+void InsertSort( SvUShorts& rArr, USHORT nIdx, USHORT* pInsPos = 0 );
+void InsertSort( SvULongs& rArr, ULONG nIdx, USHORT* pInsPos = 0 );
+
+#if defined( JP_DEBUG ) && !defined( PRODUCT )
+#include "shellio.hxx"
+void DumpDoc( SwDoc* pDoc, const String& rFileNm );
+void CheckTable( const SwTable& );
+#define DUMPDOC(p,s)    DumpDoc( p, s);
+#define CHECKTABLE(t) CheckTable( t );
+#else
+#define DUMPDOC(p,s)
+#define CHECKTABLE(t)
+#endif
+
+struct SwTblToTxtSave
+{
+    ULONG nNode;
+    xub_StrLen nCntnt;
+    SwHistory* pHstry;
+
+    SwTblToTxtSave( SwDoc& rDoc, ULONG nNd, xub_StrLen nCntnt = STRING_MAXLEN );
+    ~SwTblToTxtSave() { delete pHstry; }
+};
+
+SV_IMPL_PTRARR( SfxItemSets, SfxItemSetPtr )
+SV_IMPL_PTRARR( SwUndoSaveSections, SwUndoSaveSectionPtr )
+SV_IMPL_PTRARR( SwUndoMoves, SwUndoMovePtr )
+SV_IMPL_PTRARR( SwTblToTxtSaves, SwTblToTxtSavePtr )
+SV_IMPL_PTRARR( _UndoTblCpyTbl_Entries, _UndoTblCpyTbl_EntryPtr )
+
+USHORT __FAR_DATA aSave_BoxCntntSet[] = {
+    RES_CHRATR_COLOR, RES_CHRATR_CROSSEDOUT,
+    RES_CHRATR_FONT, RES_CHRATR_FONTSIZE,
+    RES_CHRATR_POSTURE, RES_CHRATR_POSTURE,
+    RES_CHRATR_SHADOWED, RES_CHRATR_WEIGHT,
+    RES_PARATR_ADJUST, RES_PARATR_ADJUST,
+    0 };
+
+
+
+SwUndoInsTbl::SwUndoInsTbl( const SwPosition& rPos, USHORT nCl, USHORT nRw,
+                            USHORT nAdj, USHORT nInsert,
+                            const SwTableAutoFmt* pTAFmt,
+                            const SvUShorts* pColArr )
+    : SwUndo( UNDO_INSTABLE ), nSttNode( rPos.nNode.GetIndex() ),
+    nRows( nRw ), nCols( nCl ), nAdjust( nAdj ), pDDEFldType( 0 ),
+    nInsTblFlags( nInsert ), pColWidth( 0 ), pRedlData( 0 ), pAutoFmt( 0 )
+{
+    if( pColArr )
+    {
+        pColWidth = new SvUShorts( 0, 1 );
+        pColWidth->Insert( pColArr, 0 );
+    }
+    if( pTAFmt )
+        pAutoFmt = new SwTableAutoFmt( *pTAFmt );
+
+    // Redline beachten
+    SwDoc& rDoc = *rPos.nNode.GetNode().GetDoc();
+    if( rDoc.IsRedlineOn() )
+    {
+        pRedlData = new SwRedlineData( REDLINE_INSERT, rDoc.GetRedlineAuthor() );
+        SetRedlineMode( rDoc.GetRedlineMode() );
+    }
+}
+
+
+SwUndoInsTbl::~SwUndoInsTbl()
+{
+    delete pDDEFldType;
+    delete pColWidth;
+    delete pRedlData;
+    delete pAutoFmt;
+}
+
+
+
+void SwUndoInsTbl::Undo( SwUndoIter& rUndoIter )
+{
+    SwDoc& rDoc = rUndoIter.GetDoc();
+    SwNodeIndex aIdx( rDoc.GetNodes(), nSttNode );
+
+    SwTableNode* pTblNd = aIdx.GetNode().GetTableNode();
+    ASSERT( pTblNd, "kein TabellenNode" );
+    pTblNd->DelFrms();
+
+    if( IsRedlineOn( GetRedlineMode() ))
+        rDoc.DeleteRedline( *pTblNd );
+    RemoveIdxFromSection( rDoc, nSttNode );
+
+    // harte SeitenUmbrueche am nachfolgenden Node verschieben
+    SwCntntNode* pNextNd = rDoc.GetNodes()[ pTblNd->EndOfSectionIndex()+1 ]->GetCntntNode();
+    if( pNextNd )
+    {
+        SwFrmFmt* pTableFmt = pTblNd->GetTable().GetFrmFmt();
+        const SfxPoolItem *pItem;
+
+        if( SFX_ITEM_SET == pTableFmt->GetItemState( RES_PAGEDESC,
+            FALSE, &pItem ) )
+            pNextNd->SetAttr( *pItem );
+
+        if( SFX_ITEM_SET == pTableFmt->GetItemState( RES_BREAK,
+            FALSE, &pItem ) )
+            pNextNd->SetAttr( *pItem );
+    }
+
+
+    sTblNm = pTblNd->GetTable().GetFrmFmt()->GetName();
+    if( pTblNd->GetTable().IsA( TYPE( SwDDETable )) )
+        pDDEFldType = (SwDDEFieldType*)((SwDDETable&)pTblNd->GetTable()).
+                                        GetDDEFldType()->Copy();
+
+    rDoc.GetNodes().Delete( aIdx, pTblNd->EndOfSectionIndex() -
+                                aIdx.GetIndex() + 1 );
+
+    rUndoIter.pAktPam->DeleteMark();
+    rUndoIter.pAktPam->GetPoint()->nNode = aIdx;
+    rUndoIter.pAktPam->GetPoint()->nContent.Assign(
+                            rUndoIter.pAktPam->GetCntntNode(), 0 );
+}
+
+
+void SwUndoInsTbl::Redo( SwUndoIter& rUndoIter )
+{
+    SwDoc& rDoc = rUndoIter.GetDoc();
+
+    SwPosition aPos( *rUndoIter.pAktPam->GetPoint() );
+    aPos.nNode = nSttNode;
+    const SwTable* pTbl = rDoc.InsertTable( aPos, nRows, nCols,
+                                    (SwHoriOrient)nAdjust,
+                                    nInsTblFlags, pAutoFmt, pColWidth );
+    ((SwFrmFmt*)pTbl->GetFrmFmt())->SetName( sTblNm );
+    SwTableNode* pTblNode = (SwTableNode*)rDoc.GetNodes()[nSttNode]->GetTableNode();
+
+    if( pDDEFldType )
+    {
+        SwDDEFieldType* pNewType = (SwDDEFieldType*)rDoc.InsertFldType(
+                                                            *pDDEFldType);
+        SwDDETable* pDDETbl = new SwDDETable( pTblNode->GetTable(), pNewType );
+        pTblNode->SetNewTable( pDDETbl );       // setze die DDE-Tabelle
+        delete pDDEFldType, pDDEFldType = 0;
+    }
+
+    if( (pRedlData && IsRedlineOn( GetRedlineMode() )) ||
+        ( !( REDLINE_IGNORE & GetRedlineMode() ) &&
+            rDoc.GetRedlineTbl().Count() ))
+    {
+        SwPaM aPam( *pTblNode->EndOfSectionNode(), *pTblNode, 1 );
+        SwCntntNode* pCNd = aPam.GetCntntNode( FALSE );
+        if( pCNd )
+            aPam.GetMark()->nContent.Assign( pCNd, 0 );
+
+        if( pRedlData && IsRedlineOn( GetRedlineMode() ) )
+        {
+            SwRedlineMode eOld = rDoc.GetRedlineMode();
+            rDoc.SetRedlineMode_intern( eOld & ~REDLINE_IGNORE );
+
+            rDoc.AppendRedline( new SwRedline( *pRedlData, aPam ));
+            rDoc.SetRedlineMode_intern( eOld );
+        }
+        else
+            rDoc.SplitRedline( aPam );
+    }
+}
+
+
+void SwUndoInsTbl::Repeat( SwUndoIter& rUndoIter )
+{
+    // keine Tabelle in Tabelle
+    if( !rUndoIter.pAktPam->GetNode()->FindTableNode() )
+        rUndoIter.GetDoc().InsertTable( *rUndoIter.pAktPam->GetPoint(),
+                                    nRows, nCols, (SwHoriOrient)nAdjust,
+                                    nInsTblFlags, pAutoFmt, pColWidth );
+}
+
+// -----------------------------------------------------
+
+SwTblToTxtSave::SwTblToTxtSave( SwDoc& rDoc, ULONG nNd, xub_StrLen nCnt )
+    : nNode( nNd ), nCntnt( nCnt ), pHstry( 0 )
+{
+    // Attributierung des gejointen Node merken.
+    if( USHRT_MAX != nCnt )
+        ++nNd;
+
+    SwTxtNode* pNd = rDoc.GetNodes()[ nNd ]->GetTxtNode();
+    if( pNd )
+    {
+        pHstry = new SwHistory;
+
+        pHstry->Add( pNd->GetTxtColl(), nNd, ND_TEXTNODE );
+        if( pNd->GetpSwpHints() )
+            pHstry->CopyAttr( pNd->GetpSwpHints(), nNd, 0,
+                        pNd->GetTxt().Len(), FALSE );
+        if( pNd->GetpSwAttrSet() )
+            pHstry->CopyFmtAttr( *pNd->GetpSwAttrSet(), nNd );
+
+        if( !pHstry->Count() )
+            delete pHstry, pHstry = 0;
+    }
+}
+
+SwUndoTblToTxt::SwUndoTblToTxt( const SwTable& rTbl, sal_Unicode cCh )
+    : SwUndo( UNDO_TABLETOTEXT ),
+    nSttNd( 0 ), nEndNd( 0 ), cTrenner( cCh ), pDDEFldType( 0 ),
+    nAdjust( rTbl.GetFrmFmt()->GetHoriOrient().GetHoriOrient() ),
+    sTblNm( rTbl.GetFrmFmt()->GetName() ),
+    bHdlnRpt( rTbl.IsHeadlineRepeat() ),
+    pHistory( 0 )
+{
+    pTblSave = new _SaveTable( rTbl );
+    pBoxSaves = new SwTblToTxtSaves( (BYTE)rTbl.GetTabSortBoxes().Count() );
+
+    if( rTbl.IsA( TYPE( SwDDETable ) ) )
+        pDDEFldType = (SwDDEFieldType*)((SwDDETable&)rTbl).GetDDEFldType()->Copy();
+
+    bCheckNumFmt = rTbl.GetFrmFmt()->GetDoc()->IsInsTblFormatNum();
+
+    pHistory = new SwHistory;
+    const SwTableNode* pTblNd = rTbl.GetTableNode();
+    ULONG nTblStt = pTblNd->GetIndex(), nTblEnd = pTblNd->EndOfSectionIndex();
+
+    const SwSpzFrmFmts& rFrmFmtTbl = *pTblNd->GetDoc()->GetSpzFrmFmts();
+    for( USHORT n = 0; n < rFrmFmtTbl.Count(); ++n )
+    {
+        const SwPosition* pAPos;
+        const SwFrmFmt* pFmt = rFrmFmtTbl[ n ];
+        const SwFmtAnchor* pAnchor = &pFmt->GetAnchor();
+        if( 0 != ( pAPos = pAnchor->GetCntntAnchor()) &&
+            ( FLY_AUTO_CNTNT == pAnchor->GetAnchorId() ||
+              FLY_AT_CNTNT == pAnchor->GetAnchorId() ) &&
+            nTblStt <= pAPos->nNode.GetIndex() &&
+            pAPos->nNode.GetIndex() < nTblEnd )
+        {
+            pHistory->Add( *pFmt );
+        }
+    }
+
+    if( !pHistory->Count() )
+        delete pHistory, pHistory = 0;
+}
+
+
+SwUndoTblToTxt::~SwUndoTblToTxt()
+{
+    delete pDDEFldType;
+    delete pTblSave;
+    delete pBoxSaves;
+    delete pHistory;
+}
+
+
+
+void SwUndoTblToTxt::Undo( SwUndoIter& rUndoIter )
+{
+    SwDoc& rDoc = rUndoIter.GetDoc();
+    SwPaM* pPam = rUndoIter.pAktPam;
+
+    SwNodeIndex aFrmIdx( rDoc.GetNodes(), nSttNd );
+    SwNodeIndex aEndIdx( rDoc.GetNodes(), nEndNd );
+
+    pPam->GetPoint()->nNode = aFrmIdx;
+    pPam->SetMark();
+    pPam->GetPoint()->nNode = aEndIdx;
+    rDoc.DelNumRules( *pPam );
+    pPam->DeleteMark();
+    SwNode2Layout* pNode2Layout = NULL;
+
+    // dann sammel mal alle Uppers ein
+    SwNode2Layout aNode2Layout( aFrmIdx.GetNode() );
+
+    // erzeuge die TabelleNode Structur
+    SwTableNode* pTblNd = rDoc.GetNodes().UndoTableToText( nSttNd, nEndNd,
+                                                            *pBoxSaves );
+    SwTableFmt* pTableFmt = rDoc.MakeTblFrmFmt( sTblNm, rDoc.GetDfltFrmFmt() );
+    pTableFmt->Add( &pTblNd->GetTable() );      // das Frame-Format setzen
+    pTblNd->GetTable().SetHeadlineRepeat( bHdlnRpt );
+
+    // erzeuge die alte Tabellen Struktur
+    pTblSave->CreateNew( pTblNd->GetTable() );
+
+    if( pDDEFldType )
+    {
+        SwDDEFieldType* pNewType = (SwDDEFieldType*)rDoc.InsertFldType(
+                                                            *pDDEFldType);
+        SwDDETable* pDDETbl = new SwDDETable( pTblNd->GetTable(), pNewType );
+        pTblNd->SetNewTable( pDDETbl );     // setze die DDE-Tabelle
+        delete pDDEFldType, pDDEFldType = 0;
+    }
+
+    if( bCheckNumFmt )
+    {
+        SwTableSortBoxes& rBxs = pTblNd->GetTable().GetTabSortBoxes();
+        for( USHORT nBoxes = rBxs.Count(); nBoxes; )
+            rDoc.ChkBoxNumFmt( *rBxs[ --nBoxes ], FALSE );
+    }
+
+    if( pHistory )
+    {
+        USHORT nTmpEnd = pHistory->GetTmpEnd();
+        pHistory->TmpRollback( &rDoc, 0 );
+        pHistory->SetTmpEnd( nTmpEnd );
+    }
+
+    aNode2Layout.RestoreUpperFrms( rDoc.GetNodes(),
+                                   pTblNd->GetIndex(), pTblNd->GetIndex()+1 );
+
+    // will man eine TabellenSelektion ??
+    pPam->DeleteMark();
+    pPam->GetPoint()->nNode = *pTblNd->EndOfSectionNode();
+    pPam->SetMark();
+    pPam->GetPoint()->nNode = *pPam->GetNode()->StartOfSectionNode();
+    pPam->Move( fnMoveForward, fnGoCntnt );
+    pPam->Exchange();
+    pPam->Move( fnMoveBackward, fnGoCntnt );
+
+    ClearFEShellTabCols();
+}
+
+    // steht im untbl.cxx und darf nur vom Undoobject gerufen werden
+SwTableNode* SwNodes::UndoTableToText( ULONG nSttNd, ULONG nEndNd,
+                                const SwTblToTxtSaves& rSavedData )
+{
+    SwNodeIndex aSttIdx( *this, nSttNd );
+    SwNodeIndex aEndIdx( *this, nEndNd+1 );
+
+    SwTableNode * pTblNd = new SwTableNode( aSttIdx );
+    SwEndNode* pEndNd = new SwEndNode( aEndIdx, *pTblNd  );
+
+    aEndIdx = *pEndNd;
+
+    // alle im Bereich liegdenden Nodes den TabellenNode als StartNode setzen
+    SwNode* pNd;
+    {
+        ULONG n, nTmpEnd = aEndIdx.GetIndex();
+        for( n = pTblNd->GetIndex() + 1; n < nTmpEnd; ++n )
+            if( ( pNd = (*this)[ n ] )->IsCntntNode() )
+                ((SwCntntNode*)pNd)->DelFrms();
+    }
+
+    // dann die Tabellen Struktur teilweise aufbauen. Erstmal eine Line
+    // in der alle Boxen stehen! Die korrekte Struktur kommt dann aus der
+    // SaveStruct
+    SwTableBoxFmt* pBoxFmt = GetDoc()->MakeTableBoxFmt();
+    SwTableLineFmt* pLineFmt = GetDoc()->MakeTableLineFmt();
+    SwTableLine* pLine = new SwTableLine( pLineFmt, rSavedData.Count(), 0 );
+    pTblNd->GetTable().GetTabLines().C40_INSERT( SwTableLine, pLine, 0 );
+
+    SvULongs aBkmkArr( 0, 4 );
+    for( USHORT n = rSavedData.Count(); n; )
+    {
+        SwTblToTxtSave* pSave = rSavedData[ --n ];
+        aSttIdx = pSave->nNode;
+        SwTxtNode* pTxtNd = aSttIdx.GetNode().GetTxtNode();
+        if( USHRT_MAX != pSave->nCntnt )
+        {
+            // an der ContentPosition splitten, das vorherige Zeichen
+            // loeschen (ist der Trenner!)
+            ASSERT( pTxtNd, "Wo ist der TextNode geblieben?" );
+            SwIndex aCntPos( pTxtNd, pSave->nCntnt - 1 );
+
+            pTxtNd->Erase( aCntPos, 1 );
+            SwCntntNode* pNewNd = pTxtNd->SplitNode(
+                                        SwPosition( aSttIdx, aCntPos ));
+            if( aBkmkArr.Count() )
+                _RestoreCntntIdx( aBkmkArr, *pNewNd, pSave->nCntnt,
+                                                    pSave->nCntnt + 1 );
+        }
+        else
+        {
+            if( aBkmkArr.Count() )
+                aBkmkArr.Remove( 0, aBkmkArr.Count() );
+            if( pTxtNd )
+                _SaveCntntIdx( GetDoc(), aSttIdx.GetIndex(),
+                                pTxtNd->GetTxt().Len(), aBkmkArr );
+        }
+
+        if( pTxtNd )
+        {
+            if( pTxtNd->GetpSwAttrSet() )
+                pTxtNd->ResetAllAttr();
+
+            if( pTxtNd->GetpSwpHints() )
+                pTxtNd->ClearSwpHintsArr( FALSE, FALSE );
+        }
+
+        if( pSave->pHstry )
+        {
+            USHORT nTmpEnd = pSave->pHstry->GetTmpEnd();
+            pSave->pHstry->TmpRollback( GetDoc(), 0 );
+            pSave->pHstry->SetTmpEnd( nTmpEnd );
+        }
+
+        SwStartNode* pSttNd = new SwStartNode( aSttIdx, ND_STARTNODE,
+                                                SwTableBoxStartNode );
+        pSttNd->pStartOfSection = pTblNd;
+        new SwEndNode( aEndIdx, *pSttNd );
+
+        for( ULONG i = aSttIdx.GetIndex(); i < aEndIdx.GetIndex()-1; ++i )
+        {
+            pNd = (*this)[ i ];
+            pNd->pStartOfSection = pSttNd;
+            if( pNd->IsStartNode() )
+                i = pNd->EndOfSectionIndex();
+        }
+
+        SwTableBox* pBox = new SwTableBox( pBoxFmt, *pSttNd, pLine );
+        pLine->GetTabBoxes().C40_INSERT( SwTableBox, pBox, 0 );
+        aEndIdx = *pSttNd;
+    }
+    return pTblNd;
+}
+
+
+void SwUndoTblToTxt::Redo( SwUndoIter& rUndoIter )
+{
+    SwDoc& rDoc = rUndoIter.GetDoc();
+    SwPaM* pPam = rUndoIter.pAktPam;
+
+
+    pPam->GetPoint()->nNode = nSttNd;
+    pPam->GetPoint()->nContent.Assign( 0, 0 );
+    SwNodeIndex aSaveIdx( pPam->GetPoint()->nNode, -1 );
+
+    pPam->SetMark();            // alle Indizies abmelden
+    pPam->DeleteMark();
+
+    SwTableNode* pTblNd = pPam->GetNode()->GetTableNode();
+    ASSERT( pTblNd, "keinen TableNode gefunden" );
+
+    if( pTblNd->GetTable().IsA( TYPE( SwDDETable )) )
+        pDDEFldType = (SwDDEFieldType*)((SwDDETable&)pTblNd->GetTable()).
+                                                GetDDEFldType()->Copy();
+
+    rDoc.TableToText( pTblNd, cTrenner );
+
+    aSaveIdx++;
+    SwCntntNode* pCNd = aSaveIdx.GetNode().GetCntntNode();
+    if( !pCNd && 0 == ( pCNd = rDoc.GetNodes().GoNext( &aSaveIdx ) ) &&
+        0 == ( pCNd = rDoc.GetNodes().GoPrevious( &aSaveIdx )) )
+        ASSERT( FALSE, "wo steht denn nun der TextNode" );
+
+    pPam->GetPoint()->nNode = aSaveIdx;
+    pPam->GetPoint()->nContent.Assign( pCNd, 0 );
+
+    pPam->SetMark();            // alle Indizies abmelden
+    pPam->DeleteMark();
+}
+
+
+void SwUndoTblToTxt::Repeat( SwUndoIter& rUndoIter )
+{
+    SwTableNode* pTblNd = rUndoIter.pAktPam->GetNode()->FindTableNode();
+    if( pTblNd )
+    {
+        // bewege den Cursor aus der Tabelle
+        SwPaM* pPam = rUndoIter.pAktPam;
+        pPam->GetPoint()->nNode = *pTblNd->EndOfSectionNode();
+        pPam->Move( fnMoveForward, fnGoCntnt );
+        pPam->SetMark();
+        pPam->DeleteMark();
+
+        rUndoIter.GetDoc().TableToText( pTblNd, cTrenner );
+    }
+}
+
+void SwUndoTblToTxt::SetRange( const SwNodeRange& rRg )
+{
+    nSttNd = rRg.aStart.GetIndex();
+    nEndNd = rRg.aEnd.GetIndex();
+}
+
+void SwUndoTblToTxt::AddBoxPos( SwDoc& rDoc, ULONG nNdIdx, xub_StrLen nCntntIdx )
+{
+    SwTblToTxtSave* pNew = new SwTblToTxtSave( rDoc, nNdIdx, nCntntIdx );
+    pBoxSaves->Insert( pNew, pBoxSaves->Count() );
+}
+
+// -----------------------------------------------------
+
+SwUndoTxtToTbl::SwUndoTxtToTbl( const SwPaM& rRg, sal_Unicode cCh, USHORT nAdj,
+                                USHORT nInsert, const SwTableAutoFmt* pAFmt )
+    : SwUndo( UNDO_TEXTTOTABLE ), SwUndRng( rRg ), pAutoFmt( 0 ),
+    nAdjust( nAdj ), cTrenner( cCh ), pDelBoxes( 0 ), nInsTblFlags( nInsert ),
+    pHistory( 0 )
+
+{
+    if( pAFmt )
+        pAutoFmt = new SwTableAutoFmt( *pAFmt );
+
+    const SwPosition* pEnd = rRg.End();
+    SwNodes& rNds = rRg.GetDoc()->GetNodes();
+    bSplitEnd = pEnd->nContent.GetIndex() && ( pEnd->nContent.GetIndex()
+                        != pEnd->nNode.GetNode().GetCntntNode()->Len() ||
+                pEnd->nNode.GetIndex() >= rNds.GetEndOfContent().GetIndex()-1 );
+}
+
+SwUndoTxtToTbl::~SwUndoTxtToTbl()
+{
+    delete pDelBoxes;
+    delete pAutoFmt;
+}
+
+void SwUndoTxtToTbl::Undo( SwUndoIter& rUndoIter )
+{
+    SwDoc& rDoc = rUndoIter.GetDoc();
+    ULONG nTblNd = nSttNode;
+    if( nSttCntnt )
+        ++nTblNd;       // Node wurde vorher gesplittet
+    SwNodeIndex aIdx( rDoc.GetNodes(), nTblNd );
+    SwTableNode* pTNd = rDoc.GetNodes()[ aIdx ]->GetTableNode();
+    ASSERT( pTNd, "keinen Tabellen-Node gefunden" );
+
+    RemoveIdxFromSection( rDoc, nTblNd );
+
+    sTblNm = pTNd->GetTable().GetFrmFmt()->GetName();
+
+    if( pHistory )
+    {
+        pHistory->TmpRollback( &rDoc, 0 );
+        pHistory->SetTmpEnd( pHistory->Count() );
+    }
+
+    if( pDelBoxes )
+    {
+        SwTable& rTbl = pTNd->GetTable();
+        for( USHORT n = pDelBoxes->Count(); n; )
+        {
+            SwTableBox* pBox = rTbl.GetTblBox( (*pDelBoxes)[ --n ] );
+            if( pBox )
+                ::_DeleteBox( rTbl, pBox, 0, FALSE, FALSE );
+            else
+                ASSERT( !this, "Wo ist die Box geblieben?" );
+        }
+    }
+
+    SwNodeIndex aEndIdx( *pTNd->EndOfSectionNode() );
+    rDoc.TableToText( pTNd, 0x0b == cTrenner ? 0x09 : cTrenner );
+
+    // am Start wieder zusammenfuegen ?
+    SwPosition* pPos = rUndoIter.pAktPam->GetPoint();
+    if( nSttCntnt )
+    {
+        pPos->nNode = nTblNd;
+        pPos->nContent.Assign( rDoc.GetNodes()[ pPos->nNode ]->GetCntntNode(), 0 );
+        if( rUndoIter.pAktPam->Move( fnMoveBackward, fnGoCntnt))
+        {
+            SwNodeIndex& rIdx = rUndoIter.pAktPam->GetPoint()->nNode;
+
+            // dann die Crsr/etc. nochmal relativ verschieben
+            RemoveIdxRel( rIdx.GetIndex()+1, *pPos );
+
+            rIdx.GetNode().GetCntntNode()->JoinNext();
+        }
+    }
+
+    // am Ende wieder zusammenfuegen ?
+    if( bSplitEnd )
+    {
+        SwNodeIndex& rIdx = pPos->nNode;
+        rIdx = nEndNode;
+        SwTxtNode* pTxtNd = rIdx.GetNode().GetTxtNode();
+        if( pTxtNd && pTxtNd->CanJoinNext() )
+        {
+            rUndoIter.pAktPam->GetMark()->nContent.Assign( 0, 0 );
+            rUndoIter.pAktPam->GetPoint()->nContent.Assign( 0, 0 );
+
+            // dann die Crsr/etc. nochmal relativ verschieben
+            pPos->nContent.Assign( pTxtNd, pTxtNd->GetTxt().Len() );
+            RemoveIdxRel( nEndNode + 1, *pPos );
+
+            pTxtNd->JoinNext();
+        }
+    }
+
+    SetPaM( rUndoIter );        // manipulierten Bereich selectieren
+}
+
+
+void SwUndoTxtToTbl::Redo( SwUndoIter& rUndoIter )
+{
+    SetPaM( rUndoIter );
+    RemoveIdxFromRange( *rUndoIter.pAktPam, FALSE );
+    SetPaM( rUndoIter );
+
+    const SwTable* pTable = rUndoIter.GetDoc().TextToTable(
+                *rUndoIter.pAktPam, cTrenner, (SwHoriOrient)nAdjust,
+                nInsTblFlags, pAutoFmt );
+    ((SwFrmFmt*)pTable->GetFrmFmt())->SetName( sTblNm );
+}
+
+
+void SwUndoTxtToTbl::Repeat( SwUndoIter& rUndoIter )
+{
+    // keine Tabelle in Tabelle
+    if( !rUndoIter.pAktPam->GetNode()->FindTableNode() )
+        rUndoIter.GetDoc().TextToTable( *rUndoIter.pAktPam, cTrenner,
+                            (SwHoriOrient)nAdjust, nInsTblFlags, pAutoFmt );
+}
+
+void SwUndoTxtToTbl::AddFillBox( const SwTableBox& rBox )
+{
+    if( !pDelBoxes )
+        pDelBoxes = new SvULongs;
+    pDelBoxes->Insert( rBox.GetSttIdx(), pDelBoxes->Count() );
+}
+
+SwHistory& SwUndoTxtToTbl::GetHistory()
+{
+    if( !pHistory )
+        pHistory = new SwHistory;
+    return *pHistory;
+}
+
+// -----------------------------------------------------
+
+SwUndoTblHeadline::SwUndoTblHeadline( const SwTable& rTbl, BOOL bOldHdl )
+    : SwUndo( UNDO_TABLEHEADLINE ),
+    bOldHeadline( bOldHdl )
+{
+    ASSERT( rTbl.GetTabSortBoxes().Count(), "Tabelle ohne Inhalt" );
+    const SwStartNode *pSttNd = rTbl.GetTabSortBoxes()[ 0 ]->GetSttNd();
+    ASSERT( pSttNd, "Box ohne Inhalt" );
+
+    nTblNd = pSttNd->StartOfSectionIndex();
+}
+
+
+void SwUndoTblHeadline::Undo( SwUndoIter& rUndoIter )
+{
+    SwDoc& rDoc = rUndoIter.GetDoc();
+    SwTableNode* pTNd = rDoc.GetNodes()[ nTblNd ]->GetTableNode();
+    ASSERT( pTNd, "keinen Tabellen-Node gefunden" );
+
+    rDoc.SetHeadlineRepeat( pTNd->GetTable(), bOldHeadline );
+}
+
+
+void SwUndoTblHeadline::Redo( SwUndoIter& rUndoIter )
+{
+    SwDoc& rDoc = rUndoIter.GetDoc();
+
+    SwTableNode* pTNd = rDoc.GetNodes()[ nTblNd ]->GetTableNode();
+    ASSERT( pTNd, "keinen Tabellen-Node gefunden" );
+
+    rDoc.SetHeadlineRepeat( pTNd->GetTable(), !bOldHeadline );
+}
+
+
+void SwUndoTblHeadline::Repeat( SwUndoIter& rUndoIter )
+{
+    SwTableNode* pTblNd = rUndoIter.pAktPam->GetNode()->FindTableNode();
+    if( pTblNd )
+        rUndoIter.GetDoc().SetHeadlineRepeat( pTblNd->GetTable(),
+                                                !bOldHeadline );
+}
+
+
+/*  */
+
+
+
+_SaveTable::_SaveTable( const SwTable& rTbl, USHORT nLnCnt, BOOL bSaveFml )
+    : aTblSet( *rTbl.GetFrmFmt()->GetAttrSet().GetPool(), aTableSetRange ),
+    nLineCount( nLnCnt ), pSwTable( &rTbl ), bSaveFormula( bSaveFml )
+{
+    bModifyBox = FALSE;
+    aTblSet.Put( rTbl.GetFrmFmt()->GetAttrSet() );
+    pLine = new _SaveLine( 0, *rTbl.GetTabLines()[ 0 ], *this );
+
+    _SaveLine* pLn = pLine;
+    if( USHRT_MAX == nLnCnt )
+        nLnCnt = rTbl.GetTabLines().Count();
+    for( USHORT n = 1; n < nLnCnt; ++n )
+        pLn = new _SaveLine( pLn, *rTbl.GetTabLines()[ n ], *this );
+
+    aFrmFmts.Remove( 0, aFrmFmts.Count() );
+    pSwTable = 0;
+}
+
+
+_SaveTable::~_SaveTable()
+{
+    delete pLine;
+}
+
+
+USHORT _SaveTable::AddFmt( SwFrmFmt* pFmt )
+{
+    USHORT nRet = aFrmFmts.GetPos( pFmt );
+    if( USHRT_MAX == nRet )
+    {
+        // Kopie vom ItemSet anlegen
+        SfxItemSet* pSet = new SfxItemSet( *pFmt->GetAttrSet().GetPool(),
+                                            aTableBoxSetRange );
+        pSet->Put( pFmt->GetAttrSet() );
+        //JP 20.04.98: Bug 49502 - wenn eine Formel gesetzt ist, nie den
+        //              Value mit sichern. Der muss gegebenfalls neu
+        //              errechnet werden!
+        //JP 30.07.98: Bug 54295 - Formeln immer im Klartext speichern
+        const SfxPoolItem* pItem;
+        if( SFX_ITEM_SET == pSet->GetItemState( RES_BOXATR_FORMULA, TRUE, &pItem ))
+        {
+            pSet->ClearItem( RES_BOXATR_VALUE );
+            if( pSwTable && bSaveFormula )
+            {
+                SwTableFmlUpdate aMsgHnt( pSwTable );
+                aMsgHnt.eFlags = TBL_BOXNAME;
+                ((SwTblBoxFormula*)pItem)->ChgDefinedIn( pFmt );
+                ((SwTblBoxFormula*)pItem)->ChangeState( &aMsgHnt );
+                ((SwTblBoxFormula*)pItem)->ChgDefinedIn( 0 );
+            }
+        }
+        aSets.Insert( pSet, (nRet = aSets.Count() ) );
+        aFrmFmts.Insert( pFmt, nRet );
+    }
+    return nRet;
+}
+
+
+void _SaveTable::RestoreAttr( SwTable& rTbl, BOOL bMdfyBox )
+{
+    bModifyBox = bMdfyBox;
+
+    // zuerst die Attribute des TabellenFrmFormates zurueck holen
+    SwFrmFmt* pFmt = rTbl.GetFrmFmt();
+    SfxItemSet& rFmtSet  = (SfxItemSet&)pFmt->GetAttrSet();
+    rFmtSet.ClearItem();
+    rFmtSet.Put( aTblSet );
+
+    if( pFmt->IsInCache() )
+    {
+        SwFrm::GetCache().Delete( pFmt );
+        pFmt->SetInCache( FALSE );
+    }
+
+    // zur Sicherheit alle Tableframes invalidieren
+    SwClientIter aIter( *pFmt );
+    for( SwClient* pLast = aIter.First( TYPE( SwFrm ) ); pLast; pLast = aIter.Next() )
+        if( ((SwTabFrm*)pLast)->GetTable() == &rTbl )
+        {
+            ((SwTabFrm*)pLast)->InvalidateAll();
+            ((SwTabFrm*)pLast)->SetCompletePaint();
+        }
+
+    // FrmFmts mit Defaults (0) fuellen
+    pFmt = 0;
+    for( USHORT n = aSets.Count(); n; --n )
+        aFrmFmts.Insert( pFmt, aFrmFmts.Count() );
+
+    USHORT nLnCnt = nLineCount;
+    if( USHRT_MAX == nLnCnt )
+        nLnCnt = rTbl.GetTabLines().Count();
+
+    _SaveLine* pLn = pLine;
+    for( n = 0; n < nLnCnt; ++n, pLn = pLn->pNext )
+    {
+        if( !pLn )
+        {
+            ASSERT( !this, "Anzahl der Lines hat sich veraendert" );
+            break;
+        }
+
+        pLn->RestoreAttr( *rTbl.GetTabLines()[ n ], *this );
+    }
+
+    aFrmFmts.Remove( 0, aFrmFmts.Count() );
+    bModifyBox = FALSE;
+}
+
+
+void _SaveTable::SaveCntntAttrs( SwDoc* pDoc )
+{
+    pLine->SaveCntntAttrs( pDoc );
+}
+
+
+void _SaveTable::CreateNew( SwTable& rTbl, BOOL bCreateFrms,
+                            BOOL bRestoreChart )
+{
+    _FndBox aTmpBox( 0, 0 );
+    if( bRestoreChart )
+        aTmpBox.SaveChartData( rTbl );
+    aTmpBox.DelFrms( rTbl );
+
+    // zuerst die Attribute des TabellenFrmFormates zurueck holen
+    SwFrmFmt* pFmt = rTbl.GetFrmFmt();
+    SfxItemSet& rFmtSet  = (SfxItemSet&)pFmt->GetAttrSet();
+    rFmtSet.ClearItem();
+    rFmtSet.Put( aTblSet );
+
+    if( pFmt->IsInCache() )
+    {
+        SwFrm::GetCache().Delete( pFmt );
+        pFmt->SetInCache( FALSE );
+    }
+
+    // SwTableBox muss ein Format haben!!
+    SwTableBox aParent( (SwTableBoxFmt*)pFmt, rTbl.GetTabLines().Count(), 0 );
+
+    // FrmFmts mit Defaults (0) fuellen
+    pFmt = 0;
+    for( USHORT n = aSets.Count(); n; --n )
+        aFrmFmts.Insert( pFmt, aFrmFmts.Count() );
+
+    pLine->CreateNew( rTbl, aParent, *this );
+    aFrmFmts.Remove( 0, aFrmFmts.Count() );
+
+    // die neuen Lines eintragen, die alten loeschen
+    USHORT nOldLines = nLineCount;
+    if( USHRT_MAX == nLineCount )
+        nOldLines = rTbl.GetTabLines().Count();
+
+    for( n = 0; n < aParent.GetTabLines().Count(); ++n )
+    {
+        SwTableLine* pLn = aParent.GetTabLines()[ n ];
+        pLn->SetUpper( 0 );
+        if( n < nOldLines )
+        {
+            SwTableLine* pOld = rTbl.GetTabLines()[ n ];
+            rTbl.GetTabLines().C40_REPLACE( SwTableLine, pLn, n );
+            delete pOld;
+        }
+        else
+            rTbl.GetTabLines().C40_INSERT( SwTableLine, pLn, n );
+    }
+    if( n < nOldLines )
+        rTbl.GetTabLines().DeleteAndDestroy( n, nOldLines - n );
+
+    aParent.GetTabLines().Remove( 0, n );
+
+    if( bCreateFrms )
+        aTmpBox.MakeFrms( rTbl );
+    if( bRestoreChart )
+        aTmpBox.RestoreChartData( rTbl );
+}
+
+
+void _SaveTable::NewFrmFmt( const SwClient* pLnBx, BOOL bIsLine,
+                            USHORT nFmtPos, SwFrmFmt* pOldFmt )
+{
+    SwDoc* pDoc = pOldFmt->GetDoc();
+
+    SwFrmFmt* pFmt = aFrmFmts[ nFmtPos ];
+    if( !pFmt )
+    {
+        if( bIsLine )
+            pFmt = pDoc->MakeTableLineFmt();
+        else
+            pFmt = pDoc->MakeTableBoxFmt();
+        pFmt->SetAttr( *aSets[ nFmtPos ] );
+        aFrmFmts.Replace( pFmt, nFmtPos );
+    }
+
+    //Erstmal die Frms ummelden.
+    SwClientIter aIter( *pOldFmt );
+    for( SwClient* pLast = aIter.First( TYPE( SwFrm ) ); pLast; pLast = aIter.Next() )
+        if( bIsLine ? pLnBx == ((SwRowFrm*)pLast)->GetTabLine()
+                    : pLnBx == ((SwCellFrm*)pLast)->GetTabBox() )
+        {
+            pFmt->Add( pLast );
+            ((SwFrm*)pLast)->InvalidateAll();
+            ((SwFrm*)pLast)->ReinitializeFrmSizeAttrFlags();
+        }
+
+    //Jetzt noch mich selbst ummelden.
+    pFmt->Add( (SwClient*)pLnBx );
+
+    if( bModifyBox && !bIsLine )
+    {
+        const SfxPoolItem& rOld = pOldFmt->GetAttr( RES_BOXATR_FORMAT ),
+                         & rNew = pFmt->GetAttr( RES_BOXATR_FORMAT );
+        if( rOld != rNew )
+            pFmt->Modify( (SfxPoolItem*)&rOld, (SfxPoolItem*)&rNew );
+    }
+
+    if( !pOldFmt->GetDepends() )
+        delete pOldFmt;
+
+}
+
+
+_SaveLine::_SaveLine( _SaveLine* pPrev, const SwTableLine& rLine, _SaveTable& rSTbl )
+    : pNext( 0 )
+{
+    if( pPrev )
+        pPrev->pNext = this;
+
+    nItemSet = rSTbl.AddFmt( rLine.GetFrmFmt() );
+
+    pBox = new _SaveBox( 0, *rLine.GetTabBoxes()[ 0 ], rSTbl );
+    _SaveBox* pBx = pBox;
+    for( USHORT n = 1; n < rLine.GetTabBoxes().Count(); ++n )
+        pBx = new _SaveBox( pBx, *rLine.GetTabBoxes()[ n ], rSTbl );
+}
+
+
+_SaveLine::~_SaveLine()
+{
+    delete pBox;
+    delete pNext;
+}
+
+
+void _SaveLine::RestoreAttr( SwTableLine& rLine, _SaveTable& rSTbl )
+{
+    rSTbl.NewFrmFmt( &rLine, TRUE, nItemSet, rLine.GetFrmFmt() );
+
+    _SaveBox* pBx = pBox;
+    for( USHORT n = 0; n < rLine.GetTabBoxes().Count(); ++n, pBx = pBx->pNext )
+    {
+        if( !pBx )
+        {
+            ASSERT( !this, "Anzahl der Boxen hat sich veraendert" );
+            break;
+        }
+        pBx->RestoreAttr( *rLine.GetTabBoxes()[ n ], rSTbl );
+    }
+}
+
+
+void _SaveLine::SaveCntntAttrs( SwDoc* pDoc )
+{
+    pBox->SaveCntntAttrs( pDoc );
+    if( pNext )
+        pNext->SaveCntntAttrs( pDoc );
+}
+
+
+void _SaveLine::CreateNew( SwTable& rTbl, SwTableBox& rParent, _SaveTable& rSTbl )
+{
+    SwTableLineFmt* pFmt = (SwTableLineFmt*)rSTbl.aFrmFmts[ nItemSet ];
+    if( !pFmt )
+    {
+        SwDoc* pDoc = rTbl.GetFrmFmt()->GetDoc();
+        pFmt = pDoc->MakeTableLineFmt();
+        pFmt->SetAttr( *rSTbl.aSets[ nItemSet ] );
+        rSTbl.aFrmFmts.Replace( pFmt, nItemSet );
+    }
+    SwTableLine* pNew = new SwTableLine( pFmt, 1, &rParent );
+    rParent.GetTabLines().C40_INSERT( SwTableLine, pNew, rParent.GetTabLines().Count() );
+
+    pBox->CreateNew( rTbl, *pNew, rSTbl );
+
+    if( pNext )
+        pNext->CreateNew( rTbl, rParent, rSTbl );
+}
+
+
+_SaveBox::_SaveBox( _SaveBox* pPrev, const SwTableBox& rBox, _SaveTable& rSTbl )
+    : nSttNode( ULONG_MAX ), pNext( 0 )
+{
+    Ptrs.pLine = 0;
+
+    if( pPrev )
+        pPrev->pNext = this;
+
+    nItemSet = rSTbl.AddFmt( rBox.GetFrmFmt() );
+
+    if( rBox.GetSttNd() )
+        nSttNode = rBox.GetSttIdx();
+    else
+    {
+        Ptrs.pLine = new _SaveLine( 0, *rBox.GetTabLines()[ 0 ], rSTbl );
+
+        _SaveLine* pLn = Ptrs.pLine;
+        for( USHORT n = 1; n < rBox.GetTabLines().Count(); ++n )
+            pLn = new _SaveLine( pLn, *rBox.GetTabLines()[ n ], rSTbl );
+    }
+}
+
+
+_SaveBox::~_SaveBox()
+{
+    if( ULONG_MAX == nSttNode )     // keine EndBox
+        delete Ptrs.pLine;
+    else
+        delete Ptrs.pCntntAttrs;
+    delete pNext;
+}
+
+
+void _SaveBox::RestoreAttr( SwTableBox& rBox, _SaveTable& rSTbl )
+{
+    rSTbl.NewFrmFmt( &rBox, FALSE, nItemSet, rBox.GetFrmFmt() );
+
+    if( ULONG_MAX == nSttNode )     // keine EndBox
+    {
+        if( !rBox.GetTabLines().Count() )
+        {
+            ASSERT( !this, "Anzahl der Lines hat sich veraendert" );
+        }
+        else
+        {
+            _SaveLine* pLn = Ptrs.pLine;
+            for( USHORT n = 0; n < rBox.GetTabLines().Count(); ++n, pLn = pLn->pNext )
+            {
+                if( !pLn )
+                {
+                    ASSERT( !this, "Anzahl der Lines hat sich veraendert" );
+                    break;
+                }
+
+                pLn->RestoreAttr( *rBox.GetTabLines()[ n ], rSTbl );
+            }
+        }
+    }
+    else if( rBox.GetSttNd() && rBox.GetSttIdx() == nSttNode )
+    {
+        if( Ptrs.pCntntAttrs )
+        {
+            SwNodes& rNds = rBox.GetFrmFmt()->GetDoc()->GetNodes();
+            USHORT nSet = 0;
+            ULONG nEnd = rBox.GetSttNd()->EndOfSectionIndex();
+            for( ULONG n = nSttNode + 1; n < nEnd; ++n )
+            {
+                SwCntntNode* pCNd = rNds[ n ]->GetCntntNode();
+                if( pCNd )
+                {
+                    SfxItemSet* pSet = (*Ptrs.pCntntAttrs)[ nSet++ ];
+                    if( pSet )
+                    {
+                        USHORT *pRstAttr = aSave_BoxCntntSet;
+                        while( *pRstAttr )
+                        {
+                            pCNd->ResetAttr( *pRstAttr, *(pRstAttr+1) );
+                            pRstAttr += 2;
+                        }
+                        pCNd->SetAttr( *pSet );
+                    }
+                    else
+                        pCNd->ResetAllAttr();
+                }
+            }
+        }
+    }
+    else
+    {
+        ASSERT( !this, "Box nicht mehr am gleichen Node" );
+    }
+}
+
+
+void _SaveBox::SaveCntntAttrs( SwDoc* pDoc )
+{
+    if( ULONG_MAX == nSttNode )     // keine EndBox
+    {
+        // weiter in der Line
+        Ptrs.pLine->SaveCntntAttrs( pDoc );
+    }
+    else
+    {
+        USHORT nSet = 0;
+        ULONG nEnd = pDoc->GetNodes()[ nSttNode ]->EndOfSectionIndex();
+        Ptrs.pCntntAttrs = new SfxItemSets( (BYTE)(nEnd - nSttNode - 1 ), 5 );
+        for( ULONG n = nSttNode + 1; n < nEnd; ++n )
+        {
+            SwCntntNode* pCNd = pDoc->GetNodes()[ n ]->GetCntntNode();
+            if( pCNd )
+            {
+                SfxItemSet* pSet = 0;
+                if( pCNd->GetpSwAttrSet() )
+                {
+                    pSet = new SfxItemSet( pDoc->GetAttrPool(),
+                                            aSave_BoxCntntSet );
+                    pSet->Put( *pCNd->GetpSwAttrSet() );
+                }
+
+                Ptrs.pCntntAttrs->Insert( pSet, Ptrs.pCntntAttrs->Count() );
+            }
+        }
+    }
+    if( pNext )
+        pNext->SaveCntntAttrs( pDoc );
+}
+
+
+void _SaveBox::CreateNew( SwTable& rTbl, SwTableLine& rParent, _SaveTable& rSTbl )
+{
+    SwTableBoxFmt* pFmt = (SwTableBoxFmt*)rSTbl.aFrmFmts[ nItemSet ];
+    if( !pFmt )
+    {
+        SwDoc* pDoc = rTbl.GetFrmFmt()->GetDoc();
+        pFmt = pDoc->MakeTableBoxFmt();
+        pFmt->SetAttr( *rSTbl.aSets[ nItemSet ] );
+        rSTbl.aFrmFmts.Replace( pFmt, nItemSet );
+    }
+
+    if( ULONG_MAX == nSttNode )     // keine EndBox
+    {
+        SwTableBox* pNew = new SwTableBox( pFmt, 1, &rParent );
+        rParent.GetTabBoxes().C40_INSERT( SwTableBox, pNew, rParent.GetTabBoxes().Count() );
+
+        Ptrs.pLine->CreateNew( rTbl, *pNew, rSTbl );
+    }
+    else
+    {
+        // Box zum StartNode in der alten Tabelle suchen
+        SwTableBox* pBox = rTbl.GetTblBox( nSttNode );
+        ASSERT( pBox, "Wo ist meine TabellenBox geblieben?" );
+
+        SwFrmFmt* pOld = pBox->GetFrmFmt();
+        pFmt->Add( pBox );
+        if( !pOld->GetDepends() )
+            delete pOld;
+
+        SwTableBoxes* pTBoxes = &pBox->GetUpper()->GetTabBoxes();
+        pTBoxes->Remove( pTBoxes->C40_GETPOS( SwTableBox, pBox ) );
+
+        pBox->SetUpper( &rParent );
+        pTBoxes = &rParent.GetTabBoxes();
+        pTBoxes->C40_INSERT( SwTableBox, pBox, pTBoxes->Count() );
+    }
+
+    if( pNext )
+        pNext->CreateNew( rTbl, rParent, rSTbl );
+}
+
+
+/*  */
+
+// UndoObject fuer Attribut Aenderung an der Tabelle
+
+
+SwUndoAttrTbl::SwUndoAttrTbl( const SwTableNode& rTblNd, BOOL bClearTabCols )
+    : SwUndo( UNDO_TABLE_ATTR ),
+    nSttNode( rTblNd.GetIndex() )
+{
+    bClearTabCol = bClearTabCols;
+    pSaveTbl = new _SaveTable( rTblNd.GetTable() );
+}
+
+
+SwUndoAttrTbl::~SwUndoAttrTbl()
+{
+    delete pSaveTbl;
+}
+
+
+
+void SwUndoAttrTbl::Undo( SwUndoIter& rUndoIter )
+{
+    SwDoc& rDoc = rUndoIter.GetDoc();
+    SwTableNode* pTblNd = rDoc.GetNodes()[ nSttNode ]->GetTableNode();
+    ASSERT( pTblNd, "kein TabellenNode" );
+
+    _SaveTable* pOrig = new _SaveTable( pTblNd->GetTable() );
+    pSaveTbl->RestoreAttr( pTblNd->GetTable() );
+    delete pSaveTbl;
+    pSaveTbl = pOrig;
+
+    if( bClearTabCol )
+        ClearFEShellTabCols();
+}
+
+
+void SwUndoAttrTbl::Redo( SwUndoIter& rUndoIter )
+{
+    Undo( rUndoIter );
+}
+
+
+/*  */
+
+// UndoObject fuer AutoFormat an der Tabelle
+
+
+SwUndoTblAutoFmt::SwUndoTblAutoFmt( const SwTableNode& rTblNd,
+                                    const SwTableAutoFmt& rAFmt )
+    : SwUndo( UNDO_TABLE_AUTOFMT ),
+    nSttNode( rTblNd.GetIndex() ),
+    bSaveCntntAttr( FALSE ), pUndos( 0 )
+{
+    pSaveTbl = new _SaveTable( rTblNd.GetTable() );
+
+    if( rAFmt.IsFont() || rAFmt.IsJustify() )
+    {
+        // dann auch noch ueber die ContentNodes der EndBoxen und
+        // und alle Absatz-Attribute zusammen sammeln
+        pSaveTbl->SaveCntntAttrs( (SwDoc*)rTblNd.GetDoc() );
+        bSaveCntntAttr = TRUE;
+    }
+}
+
+
+SwUndoTblAutoFmt::~SwUndoTblAutoFmt()
+{
+    delete pUndos;
+    delete pSaveTbl;
+}
+
+void SwUndoTblAutoFmt::SaveBoxCntnt( const SwTableBox& rBox )
+{
+    SwUndoTblNumFmt* p = new SwUndoTblNumFmt( rBox );
+    if( !pUndos )
+        pUndos = new SwUndos( 8, 8 );
+    pUndos->Insert( p, pUndos->Count() );
+}
+
+
+void SwUndoTblAutoFmt::UndoRedo( BOOL bUndo, SwUndoIter& rUndoIter )
+{
+    SwDoc& rDoc = rUndoIter.GetDoc();
+    SwTableNode* pTblNd = rDoc.GetNodes()[ nSttNode ]->GetTableNode();
+    ASSERT( pTblNd, "kein TabellenNode" );
+
+    _SaveTable* pOrig = new _SaveTable( pTblNd->GetTable() );
+        // dann auch noch ueber die ContentNodes der EndBoxen und
+        // und alle Absatz-Attribute zusammen sammeln
+    if( bSaveCntntAttr )
+        pOrig->SaveCntntAttrs( &rDoc );
+
+    if( pUndos && bUndo )
+        for( USHORT n = pUndos->Count(); n; )
+            pUndos->GetObject( --n )->Undo( rUndoIter );
+
+    pSaveTbl->RestoreAttr( pTblNd->GetTable(), !bUndo );
+    delete pSaveTbl;
+    pSaveTbl = pOrig;
+}
+
+void SwUndoTblAutoFmt::Undo( SwUndoIter& rUndoIter )
+{
+    UndoRedo( TRUE, rUndoIter );
+}
+
+
+void SwUndoTblAutoFmt::Redo( SwUndoIter& rUndoIter )
+{
+    UndoRedo( FALSE, rUndoIter );
+}
+
+
+/*  */
+
+
+SwUndoTblNdsChg::SwUndoTblNdsChg( USHORT nAction,
+                                    const SwSelBoxes& rBoxes,
+                                    const SwTableNode& rTblNd,
+                                    USHORT nCnt, BOOL bFlg )
+    : SwUndo( nAction ),
+    nSttNode( rTblNd.GetIndex() ),
+    aBoxes( rBoxes.Count() < 255 ? (BYTE)rBoxes.Count() : 255, 10 ),
+    nCount( nCnt ), nRelDiff( 0 ), nAbsDiff( 0 ),
+    nSetColType( USHRT_MAX ), nCurrBox( 0 ),
+    bFlag( bFlg )
+{
+    Ptrs.pNewSttNds = 0;
+
+    const SwTable& rTbl = rTblNd.GetTable();
+    pSaveTbl = new _SaveTable( rTbl );
+
+    // und die Selektion merken
+    for( USHORT n = 0; n < rBoxes.Count(); ++n )
+        aBoxes.Insert( rBoxes[n]->GetSttIdx(), n );
+}
+
+
+SwUndoTblNdsChg::SwUndoTblNdsChg( USHORT nAction,
+                                    const SwSelBoxes& rBoxes,
+                                    const SwTableNode& rTblNd )
+    : SwUndo( nAction ),
+    nSttNode( rTblNd.GetIndex() ),
+    aBoxes( rBoxes.Count() < 255 ? (BYTE)rBoxes.Count() : 255, 10 ),
+    nCount( 0 ), nRelDiff( 0 ), nAbsDiff( 0 ),
+    nSetColType( USHRT_MAX ), nCurrBox( 0 ),
+    bFlag( FALSE )
+{
+    Ptrs.pNewSttNds = 0;
+
+    const SwTable& rTbl = rTblNd.GetTable();
+    pSaveTbl = new _SaveTable( rTbl );
+
+    // und die Selektion merken
+    for( USHORT n = 0; n < rBoxes.Count(); ++n )
+        aBoxes.Insert( rBoxes[n]->GetSttIdx(), n );
+}
+
+
+SwUndoTblNdsChg::~SwUndoTblNdsChg()
+{
+    delete pSaveTbl;
+
+    if( UNDO_TABLE_DELBOX == GetId() )
+        delete Ptrs.pDelSects;
+    else
+        delete Ptrs.pNewSttNds;
+}
+
+
+
+void SwUndoTblNdsChg::SaveNewBoxes( const SwTableNode& rTblNd,
+                                    const SwTableSortBoxes& rOld )
+{
+    const SwTable& rTbl = rTblNd.GetTable();
+    const SwTableSortBoxes& rTblBoxes = rTbl.GetTabSortBoxes();
+
+    ASSERT( UNDO_TABLE_DELBOX != GetId(), "falsche Action" );
+    Ptrs.pNewSttNds = new SvULongs( (BYTE)(rTblBoxes.Count() - rOld.Count()), 5 );
+
+    for( USHORT n = 0, i = 0; n < rOld.Count(); ++i )
+    {
+        if( rOld[ n ] == rTblBoxes[ i ] )
+            ++n;
+        else
+            // neue Box: sortiert einfuegen!!
+            InsertSort( *Ptrs.pNewSttNds, rTblBoxes[ i ]->GetSttIdx() );
+    }
+
+    for( ; i < rTblBoxes.Count(); ++i )
+        // neue Box: sortiert einfuegen!!
+        InsertSort( *Ptrs.pNewSttNds, rTblBoxes[ i ]->GetSttIdx() );
+}
+
+
+void SwUndoTblNdsChg::SaveNewBoxes( const SwTableNode& rTblNd,
+                                    const SwTableSortBoxes& rOld,
+                                    const SwSelBoxes& rBoxes,
+                                    const SvULongs& rNodeCnts )
+{
+    const SwTable& rTbl = rTblNd.GetTable();
+    const SwTableSortBoxes& rTblBoxes = rTbl.GetTabSortBoxes();
+
+    ASSERT( UNDO_TABLE_DELBOX != GetId(), "falsche Action" );
+    Ptrs.pNewSttNds = new SvULongs( (BYTE)(rTblBoxes.Count() - rOld.Count()), 5 );
+
+    for( USHORT n = 0, i = 0; n < rOld.Count(); ++i )
+    {
+        if( rOld[ n ] == rTblBoxes[ i ] )
+            ++n;
+        else
+        {
+            // neue Box: sortiert einfuegen!!
+            USHORT nInsPos;
+            const SwTableBox* pBox = rTblBoxes[ i ];
+            InsertSort( *Ptrs.pNewSttNds, pBox->GetSttIdx(), &nInsPos );
+            // feststellen, an welcher Position die Line in der Box steht
+            const SwTableLine* pLn = pBox->GetUpper();
+            USHORT nLinePos = pLn->GetUpper()->GetTabLines().GetPos( pLn );
+            // 1. Box der 1. Line besorgen, ist die selektierte Box!
+            pBox = pBox->GetUpper()->GetUpper()->GetTabLines()[ 0 ]
+                                                        ->GetTabBoxes()[0];
+            // stelle fest, wieviele Nodes die Box hatte und ob
+            // die aktuelle davon einen bekommen hat
+            USHORT nNdsPos = 0;
+            while( rBoxes[ nNdsPos ] != pBox )
+                ++nNdsPos;
+            ULONG nNodes = rNodeCnts[ nNdsPos ];
+            // wurden Nodes verschoben und hat die akt. Box davon einen
+            // bekommen. Wenn ja, setze das Flag -> beim Undo darf der Inhalt
+            // dann nicht geloscht sondern muss verschoben werden!
+            BOOL bFlag = nNodes != pBox->GetSttNd()->EndOfSectionIndex() -
+                                   pBox->GetSttIdx()
+                && nNodes - 1 > nLinePos;
+            aMvBoxes.Insert( bFlag, nInsPos );
+        }
+    }
+
+    for( ; i < rTblBoxes.Count(); ++i )
+    {
+        // neue Box: sortiert einfuegen!!
+        USHORT nInsPos;
+        const SwTableBox* pBox = rTblBoxes[ i ];
+        InsertSort( *Ptrs.pNewSttNds, pBox->GetSttIdx(), &nInsPos );
+        // feststellen, an welcher Position die Line in der Box steht
+        const SwTableLine* pLn = pBox->GetUpper();
+        USHORT nLinePos = pLn->GetUpper()->GetTabLines().GetPos( pLn );
+        // 1. Box der 1. Line besorgen, ist die selektierte Box!
+        pBox = pBox->GetUpper()->GetUpper()->GetTabLines()[ 0 ]
+                                                    ->GetTabBoxes()[0];
+        // stelle fest, wieviele Nodes die Box hatte und ob
+        // die aktuelle davon einen bekommen hat
+        USHORT nNdsPos = 0;
+        while( rBoxes[ nNdsPos ] != pBox )
+            ++nNdsPos;
+        ULONG nNodes = rNodeCnts[ nNdsPos ];
+        // wurden Nodes verschoben und hat die akt. Box davon einen
+        // bekommen. Wenn ja, setze das Flag -> beim Undo darf der Inhalt
+        // dann nicht geloscht sondern muss verschoben werden!
+        BOOL bFlag = nNodes != pBox->GetSttNd()->EndOfSectionIndex() -
+                                pBox->GetSttIdx()
+            && nNodes - 1 > nLinePos;
+        aMvBoxes.Insert( bFlag, nInsPos );
+    }
+}
+
+
+void SwUndoTblNdsChg::SaveSection( SwStartNode* pSttNd )
+{
+    ASSERT( UNDO_TABLE_DELBOX == GetId(), "falsche Action" );
+    if( !Ptrs.pDelSects )
+        Ptrs.pDelSects = new SwUndoSaveSections( 10, 5 );
+
+    SwTableNode* pTblNd = pSttNd->FindTableNode();
+    SwUndoSaveSection* pSave = new SwUndoSaveSection;
+    pSave->SaveSection( pSttNd->GetDoc(), SwNodeIndex( *pSttNd ));
+
+    Ptrs.pDelSects->Insert( pSave, Ptrs.pDelSects->Count() );
+    nSttNode = pTblNd->GetIndex();
+}
+
+
+void SwUndoTblNdsChg::Undo( SwUndoIter& rUndoIter )
+{
+    SwDoc& rDoc = rUndoIter.GetDoc();
+    SwNodeIndex aIdx( rDoc.GetNodes(), nSttNode );
+
+    SwTableNode* pTblNd = rDoc.GetNodes()[ aIdx ]->GetTableNode();
+    ASSERT( pTblNd, "kein TabellenNode" );
+
+    SwTableFmlUpdate aMsgHnt( &pTblNd->GetTable() );
+    aMsgHnt.eFlags = TBL_BOXPTR;
+    rDoc.UpdateTblFlds( &aMsgHnt );
+
+    _FndBox aTmpBox( 0, 0 );
+    aTmpBox.SaveChartData( pTblNd->GetTable() );
+
+    if( UNDO_TABLE_DELBOX == GetId() )
+    {
+        // Trick: die fehlenden Boxen in irgendeine Line einfuegen, beim
+        // CreateNew werden sie korrekt verbunden.
+        SwTableBox* pCpyBox = pTblNd->GetTable().GetTabSortBoxes()[0];
+        SwTableBoxes& rLnBoxes = pCpyBox->GetUpper()->GetTabBoxes();
+
+        // die Sections wieder herstellen
+        for( USHORT n = Ptrs.pDelSects->Count(); n; )
+        {
+            SwUndoSaveSection* pSave = (*Ptrs.pDelSects)[ --n ];
+            pSave->RestoreSection( &rDoc, &aIdx, SwTableBoxStartNode );
+            if( pSave->GetHistory() )
+                pSave->GetHistory()->Rollback( &rDoc );
+            SwTableBox* pBox = new SwTableBox( (SwTableBoxFmt*)pCpyBox->GetFrmFmt(), aIdx,
+                                                pCpyBox->GetUpper() );
+            rLnBoxes.C40_INSERT( SwTableBox, pBox, rLnBoxes.Count() );
+        }
+        Ptrs.pDelSects->DeleteAndDestroy( 0, Ptrs.pDelSects->Count() );
+    }
+    else if( aMvBoxes.Count() )
+    {
+        // dann muessen Nodes verschoben und nicht geloescht werden!
+        // Dafuer brauchen wir aber ein temp Array
+        SvULongs aTmp( 0, 5);
+        aTmp.Insert( Ptrs.pNewSttNds, 0 );
+
+        // von hinten anfangen
+        for( USHORT n = aTmp.Count(); n; )
+        {
+            // Box aus der Tabellen-Struktur entfernen
+            ULONG nIdx = aTmp[ --n ];
+            SwTableBox* pBox = pTblNd->GetTable().GetTblBox( nIdx );
+            ASSERT( pBox, "Wo ist meine TabellenBox geblieben?" );
+
+            SwTableBoxes* pTBoxes = &pBox->GetUpper()->GetTabBoxes();
+            pTBoxes->Remove( pTBoxes->C40_GETPOS( SwTableBox, pBox ) );
+
+            if( aMvBoxes[ n ] )
+            {
+                SwNodeRange aRg( *pBox->GetSttNd(), 1,
+                            *pBox->GetSttNd()->EndOfSectionNode() );
+                SwNodeIndex aInsPos( *pBox->GetUpper()->GetUpper()->GetTabLines()[0]
+                                    ->GetTabBoxes()[ 0 ]->GetSttNd(), 2 );
+
+                // alle StartNode Indizies anpassen
+                USHORT i = n;
+                ULONG nSttIdx = aInsPos.GetIndex() - 2,
+                       nNdCnt = aRg.aEnd.GetIndex() - aRg.aStart.GetIndex();
+                while( i && aTmp[ --i ] > nSttIdx )
+                    aTmp[ i ] += nNdCnt;
+
+                // erst die Box loeschen
+                delete pBox;
+                // dann die Nodes verschieben,
+                rDoc.GetNodes()._MoveNodes( aRg, rDoc.GetNodes(), aInsPos, FALSE );
+            }
+            else
+            {
+                delete pBox;
+                rDoc.DeleteSection( rDoc.GetNodes()[ nIdx ] );
+            }
+        }
+    }
+    else
+        // die Nodes loeschen (von Hinten!!)
+        for( USHORT n = Ptrs.pNewSttNds->Count(); n; )
+        {
+            // Box aus der Tabellen-Struktur entfernen
+            ULONG nIdx = (*Ptrs.pNewSttNds)[ --n ];
+            SwTableBox* pBox = pTblNd->GetTable().GetTblBox( nIdx );
+            ASSERT( pBox, "Wo ist meine TabellenBox geblieben?" );
+
+            SwTableBoxes* pTBoxes = &pBox->GetUpper()->GetTabBoxes();
+            pTBoxes->Remove( pTBoxes->C40_GETPOS( SwTableBox, pBox ) );
+
+            delete pBox;
+            rDoc.DeleteSection( rDoc.GetNodes()[ nIdx ] );
+        }
+
+    pSaveTbl->CreateNew( pTblNd->GetTable(), TRUE, FALSE );
+
+    aTmpBox.RestoreChartData( pTblNd->GetTable() );
+
+    if( UNDO_TABLE_DELBOX == GetId() )
+        nSttNode = pTblNd->GetIndex();
+    ClearFEShellTabCols();
+}
+
+
+void SwUndoTblNdsChg::Redo( SwUndoIter& rUndoIter )
+{
+    SwDoc& rDoc = rUndoIter.GetDoc();
+
+    SwTableNode* pTblNd = rDoc.GetNodes()[ nSttNode ]->GetTableNode();
+    ASSERT( pTblNd, "kein TabellenNode" );
+
+    SwSelBoxes aSelBoxes;
+    for( USHORT n = 0; n < aBoxes.Count(); ++n )
+    {
+        SwTableBox* pBox = pTblNd->GetTable().GetTblBox( aBoxes[ n ] );
+        aSelBoxes.Insert( pBox );
+    }
+
+    // SelBoxes erzeugen und InsertCell/-Row/SplitTbl aufrufen
+    switch( GetId() )
+    {
+    case UNDO_TABLE_INSCOL:
+        if( USHRT_MAX == nSetColType )
+            rDoc.InsertCol( aSelBoxes, nCount, bFlag );
+        else
+        {
+            SwTableBox* pBox = pTblNd->GetTable().GetTblBox( nCurrBox );
+            rDoc.SetColRowWidthHeight( *pBox, nSetColType, nAbsDiff,
+                                        nRelDiff );
+        }
+        break;
+
+    case UNDO_TABLE_INSROW:
+        if( USHRT_MAX == nSetColType )
+            rDoc.InsertRow( aSelBoxes, nCount, bFlag );
+        else
+        {
+            SwTable& rTbl = pTblNd->GetTable();
+            SwTableBox* pBox = rTbl.GetTblBox( nCurrBox );
+            TblChgMode eOldMode = rTbl.GetTblChgMode();
+            rTbl.SetTblChgMode( (TblChgMode)nCount );
+            rDoc.SetColRowWidthHeight( *pBox, nSetColType, nAbsDiff, nRelDiff );
+            rTbl.SetTblChgMode( eOldMode );
+        }
+        break;
+
+    case UNDO_TABLE_SPLIT:
+        rDoc.SplitTbl( aSelBoxes, bFlag, nCount );
+        break;
+    case UNDO_TABLE_DELBOX:
+        if( USHRT_MAX == nSetColType )
+        {
+            SwTableFmlUpdate aMsgHnt( &pTblNd->GetTable() );
+            aMsgHnt.eFlags = TBL_BOXPTR;
+            rDoc.UpdateTblFlds( &aMsgHnt );
+
+            pTblNd->GetTable().DeleteSel( &rDoc, aSelBoxes, this, TRUE );
+        }
+        else
+        {
+            SwTable& rTbl = pTblNd->GetTable();
+
+            SwTableFmlUpdate aMsgHnt( &rTbl );
+            aMsgHnt.eFlags = TBL_BOXPTR;
+            rDoc.UpdateTblFlds( &aMsgHnt );
+
+            SwTableBox* pBox = rTbl.GetTblBox( nCurrBox );
+            TblChgMode eOldMode = rTbl.GetTblChgMode();
+            rTbl.SetTblChgMode( (TblChgMode)nCount );
+
+            rDoc.DoUndo( TRUE );        // wir brauchen die SaveSections!
+            SwUndoTblNdsChg* pUndo = 0;
+
+            switch( nSetColType & 0xff )
+            {
+            case WH_COL_LEFT:
+            case WH_COL_RIGHT:
+            case WH_CELL_LEFT:
+            case WH_CELL_RIGHT:
+                 rTbl.SetColWidth( *pBox, nSetColType, nAbsDiff,
+                                    nRelDiff, (SwUndo**)&pUndo );
+                break;
+            case WH_ROW_TOP:
+            case WH_ROW_BOTTOM:
+            case WH_CELL_TOP:
+            case WH_CELL_BOTTOM:
+                rTbl.SetRowHeight( *pBox, nSetColType, nAbsDiff,
+                                    nRelDiff, (SwUndo**)&pUndo );
+                break;
+            }
+
+            if( pUndo )
+            {
+                Ptrs.pDelSects->Insert( pUndo->Ptrs.pDelSects, 0 );
+                pUndo->Ptrs.pDelSects->Remove( 0, pUndo->Ptrs.pDelSects->Count() );
+
+                delete pUndo;
+            }
+            rDoc.DoUndo( FALSE );
+
+            rTbl.SetTblChgMode( eOldMode );
+        }
+        nSttNode = pTblNd->GetIndex();
+        break;
+    }
+    ClearFEShellTabCols();
+}
+
+
+/*  */
+
+
+SwUndoTblMerge::SwUndoTblMerge( const SwPaM& rTblSel )
+    : SwUndo( UNDO_TABLE_MERGE ), SwUndRng( rTblSel ), pHistory( 0 )
+{
+    const SwTableNode* pTblNd = rTblSel.GetNode()->FindTableNode();
+    ASSERT( pTblNd, "Wo ist TabllenNode" )
+    pSaveTbl = new _SaveTable( pTblNd->GetTable() );
+    pMoves = new SwUndoMoves;
+    nTblNode = pTblNd->GetIndex();
+}
+
+
+SwUndoTblMerge::~SwUndoTblMerge()
+{
+    delete pSaveTbl;
+    delete pMoves;
+    delete pHistory;
+}
+
+
+void SwUndoTblMerge::Undo( SwUndoIter& rUndoIter )
+{
+    SwDoc& rDoc = rUndoIter.GetDoc();
+    SwNodeIndex aIdx( rDoc.GetNodes(), nTblNode );
+
+    SwTableNode* pTblNd = rDoc.GetNodes()[ aIdx ]->GetTableNode();
+    ASSERT( pTblNd, "kein TabellenNode" );
+
+    SwTableFmlUpdate aMsgHnt( &pTblNd->GetTable() );
+    aMsgHnt.eFlags = TBL_BOXPTR;
+    rDoc.UpdateTblFlds( &aMsgHnt );
+
+    _FndBox aTmpBox( 0, 0 );
+    aTmpBox.SaveChartData( pTblNd->GetTable() );
+
+
+    // 1. die geloeschten Boxen wiederherstellen:
+
+    // Trick: die fehlenden Boxen in irgendeine Line einfuegen, beim
+    // CreateNew werden sie korrekt verbunden.
+    SwTableBox *pBox, *pCpyBox = pTblNd->GetTable().GetTabSortBoxes()[0];
+    SwTableBoxes& rLnBoxes = pCpyBox->GetUpper()->GetTabBoxes();
+
+DUMPDOC( &rDoc, "d:\\tmp\\tab_a.db" )
+CHECKTABLE(pTblNd->GetTable())
+
+    SwSelBoxes aSelBoxes;
+    SwTxtFmtColl* pColl = rDoc.GetTxtCollFromPool( RES_POOLCOLL_STANDARD );
+    for( USHORT n = 0; n < aBoxes.Count(); ++n )
+    {
+        aIdx = aBoxes[ n ];
+        SwStartNode* pSttNd = rDoc.GetNodes().MakeTextSection( aIdx,
+                                            SwTableBoxStartNode, pColl );
+        pBox = new SwTableBox( (SwTableBoxFmt*)pCpyBox->GetFrmFmt(), *pSttNd,
+                                pCpyBox->GetUpper() );
+        rLnBoxes.C40_INSERT( SwTableBox, pBox, rLnBoxes.Count() );
+
+        aSelBoxes.Insert( pBox );
+    }
+
+DUMPDOC( &rDoc, "d:\\tmp\\tab_b.db" )
+CHECKTABLE(pTblNd->GetTable())
+
+    // 2. die eingefuegten Boxen loeschen
+    // die Nodes loeschen (von Hinten!!)
+    for( n = aNewSttNds.Count(); n; )
+    {
+        // Box aus der Tabellen-Struktur entfernen
+        ULONG nIdx = aNewSttNds[ --n ];
+
+        if( !nIdx && n )
+        {
+            nIdx = aNewSttNds[ --n ];
+            pBox = pTblNd->GetTable().GetTblBox( nIdx );
+            ASSERT( pBox, "Wo ist meine TabellenBox geblieben?" );
+
+            rDoc.GetNodes().MakeTxtNode( SwNodeIndex(
+                    *pBox->GetSttNd()->EndOfSectionNode() ), pColl );
+
+            // das war der Trenner, -> die verschobenen herstellen
+            for( USHORT i = pMoves->Count(); i; )
+            {
+                SwTxtNode* pTxtNd;
+                USHORT nDelPos;
+                SwUndoMove* pUndo = (*pMoves)[ --i ];
+                if( !pUndo->IsMoveRange() )
+                {
+                    pTxtNd = rDoc.GetNodes()[ pUndo->GetDestSttNode() ]->GetTxtNode();
+                    nDelPos = pUndo->GetDestSttCntnt() - 1;
+                }
+                pUndo->Undo( rUndoIter );
+                if( pUndo->IsMoveRange() )
+                {
+                    // den ueberfluessigen Node loeschen
+                    aIdx = pUndo->GetEndNode();
+                    rDoc.GetNodes().Delete( aIdx, 1 );
+                }
+                else if( pTxtNd )
+                {
+                    // evt. noch ueberflussige Attribute loeschen
+                    SwIndex aIdx( pTxtNd, nDelPos );
+                    if( pTxtNd->GetpSwpHints() && pTxtNd->GetpSwpHints()->Count() )
+                        pTxtNd->RstAttr( aIdx, pTxtNd->GetTxt().Len() -
+                                                            nDelPos + 1 );
+                    // das Trennzeichen loeschen
+                    pTxtNd->Erase( aIdx, 1 );
+                }
+//              delete pUndo;
+DUMPDOC( &rDoc, String( "d:\\tmp\\tab_") + String( aNewSttNds.Count() - i ) +
+                String(".db") )
+            }
+//          pMoves->Remove( 0, pMoves->Count() );
+            nIdx = pBox->GetSttIdx();
+        }
+        else
+            pBox = pTblNd->GetTable().GetTblBox( nIdx );
+
+        SwTableBoxes* pTBoxes = &pBox->GetUpper()->GetTabBoxes();
+        pTBoxes->Remove( pTBoxes->C40_GETPOS( SwTableBox, pBox ) );
+
+
+        // Indizies aus dem Bereich loeschen
+        {
+            SwNodeIndex aIdx( *pBox->GetSttNd() );
+            rDoc.CorrAbs( SwNodeIndex( aIdx, 1 ),
+                        SwNodeIndex( *aIdx.GetNode().EndOfSectionNode() ),
+                        SwPosition( aIdx, SwIndex( 0, 0 )), TRUE );
+        }
+
+        delete pBox;
+        rDoc.DeleteSection( rDoc.GetNodes()[ nIdx ] );
+    }
+DUMPDOC( &rDoc, "d:\\tmp\\tab_z.db" )
+CHECKTABLE(pTblNd->GetTable())
+
+
+    pSaveTbl->CreateNew( pTblNd->GetTable(), TRUE, FALSE );
+
+    aTmpBox.RestoreChartData( pTblNd->GetTable() );
+
+    if( pHistory )
+    {
+        pHistory->TmpRollback( &rDoc, 0 );
+        pHistory->SetTmpEnd( pHistory->Count() );
+    }
+//  nTblNode = pTblNd->GetIndex();
+
+    SwPaM* pPam = rUndoIter.pAktPam;
+    pPam->DeleteMark();
+    pPam->GetPoint()->nNode = nSttNode;
+    pPam->GetPoint()->nContent.Assign( pPam->GetCntntNode(), nSttCntnt );
+    pPam->SetMark();
+    pPam->DeleteMark();
+
+CHECKTABLE(pTblNd->GetTable())
+    ClearFEShellTabCols();
+}
+
+
+void SwUndoTblMerge::Redo( SwUndoIter& rUndoIter )
+{
+    SwPaM* pPam = rUndoIter.pAktPam;
+    SwDoc& rDoc = *pPam->GetDoc();
+
+    SetPaM( *pPam );
+    rDoc.MergeTbl( *pPam );
+}
+
+
+void SwUndoTblMerge::MoveBoxCntnt( SwPaM& rPam, SwPosition& rPos,
+                                    const _SaveFlyArr& rArr )
+{
+    SwDoc* pDoc = rPam.GetDoc();
+    SwNodeIndex aIdx( rPam.GetPoint()->nNode );
+    SwNode* pNd = &aIdx.GetNode();
+
+    // alle verschobenen Flys in der History vom Move-Object merken.
+    // Hier erstmal zwischenspeichern, damit die alten NodeIdx richtig sind
+    SwHistory aHst;
+    for( USHORT n = 0; n < rArr.Count(); ++n )
+        aHst.Add( *rArr[ n ].pFrmFmt );
+
+    SwUndoMove* pUndoMove;
+    if( pDoc->Move( rPam, rPos ) )
+        pUndoMove = (SwUndoMove*)pDoc->RemoveLastUndo( UNDO_MOVE );
+    else
+    {
+        // wir muessen das Undo Object haben!
+        pUndoMove = new SwUndoMove( rPam, rPos );
+        SwPaM aPam( rPos );
+        pUndoMove->SetDestRange( aPam, rPos, FALSE, FALSE );
+    }
+    ASSERT( pUndoMove, "falsches Undo-Object" );
+
+    // alle verschobenen Flys in der History vom Move-Object merken
+    if( aHst.Count() )
+        pUndoMove->AddTblMrgFlyHstry( aHst );
+
+    pMoves->Insert( pUndoMove, pMoves->Count() );
+
+    const SwStartNode* pBoxNd = pNd->FindTableBoxStartNode();
+    ULONG nDelNds = pBoxNd->EndOfSectionIndex() - pBoxNd->GetIndex();
+    if( 2 < nDelNds )
+    {
+        // es darf nur ein Textnode in der Box verbleiben!
+        rPam.DeleteMark();
+
+        // Indizies aus dem Bereich loeschen
+        {
+            pDoc->CorrAbs( SwNodeIndex( *pBoxNd ),
+                            SwNodeIndex( *pBoxNd->EndOfSectionNode() ),
+                            SwPosition( aIdx,
+                                SwIndex( pNd->GetCntntNode(), 0 )), TRUE );
+        }
+
+//      rPam.GetBound1().nNode = rPam.GetBound2().nNode = aIdx;
+        if( aIdx.GetIndex() - 1  != pBoxNd->GetIndex() )
+        {
+            SwNodeIndex aTmp( *pBoxNd, 1 );
+            pDoc->GetNodes().Delete( aTmp, aIdx.GetIndex() - aTmp.GetIndex() );
+        }
+        aIdx++;
+        pDoc->GetNodes().Delete( aIdx, pBoxNd->EndOfSectionIndex() - aIdx.GetIndex() );
+    }
+}
+
+
+void SwUndoTblMerge::MoveBoxCntnt( SwDoc* pDoc, SwNodeRange& rRg, SwNodeIndex& rPos )
+{
+    SwNodeIndex aTmp( rRg.aStart, -1 ), aTmp2( rPos, -1 );
+    SwUndoMove* pUndo = new SwUndoMove( pDoc, rRg, rPos );
+    pDoc->Move( rRg, rPos );
+    aTmp++;
+    aTmp2++;
+    pUndo->SetDestRange( aTmp2, rPos, aTmp );
+
+    pMoves->Insert( pUndo, pMoves->Count() );
+}
+
+
+void SwUndoTblMerge::SetSelBoxes( const SwSelBoxes& rBoxes )
+{
+    // die Selektion merken
+    for( USHORT n = 0; n < rBoxes.Count(); ++n )
+        InsertSort( aBoxes, rBoxes[n]->GetSttIdx() );
+
+    // als Trennung fuers einfuegen neuer Boxen nach dem Verschieben!
+    aNewSttNds.Insert( (ULONG)0, aNewSttNds.Count() );
+
+    nTblNode = rBoxes[ 0 ]->GetSttNd()->FindTableNode()->GetIndex();
+}
+
+void SwUndoTblMerge::SaveCollection( const SwTableBox& rBox )
+{
+    if( !pHistory )
+        pHistory = new SwHistory;
+
+    SwNodeIndex aIdx( *rBox.GetSttNd(), 1 );
+    SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
+    if( !pCNd )
+        pCNd = aIdx.GetNodes().GoNext( &aIdx );
+
+    pHistory->Add( pCNd->GetFmtColl(), aIdx.GetIndex(), pCNd->GetNodeType());
+    if( pCNd->GetpSwAttrSet() )
+        pHistory->CopyFmtAttr( *pCNd->GetpSwAttrSet(), aIdx.GetIndex() );
+}
+
+/*  */
+
+
+SwUndoTblNumFmt::SwUndoTblNumFmt( const SwTableBox& rBox,
+                                    const SfxItemSet* pNewSet )
+    : SwUndo( UNDO_TBLNUMFMT ),
+    pBoxSet( 0 ), pHistory( 0 ), nFmtIdx( NUMBERFORMAT_TEXT )
+{
+    bNewFmt = bNewFml = bNewValue = FALSE;
+    nNode = rBox.GetSttIdx();
+
+    ULONG nNdPos = rBox.IsValidNumTxtNd( 0 == pNewSet );
+
+    if( ULONG_MAX != nNdPos )
+    {
+        SwDoc* pDoc = rBox.GetFrmFmt()->GetDoc();
+        SwTxtNode* pTNd = pDoc->GetNodes()[ nNdPos ]->GetTxtNode();
+
+        pHistory = new SwHistory;
+        SwRegHistory aRHst( *rBox.GetSttNd(), pHistory );
+        // immer alle TextAttribute sichern; ist fuers Undo mit voll-
+        // staendiger Attributierung am besten, wegen den evt.
+        // Ueberlappenden Bereichen von An/Aus.
+        pHistory->CopyAttr( pTNd->GetpSwpHints(), nNdPos, 0,
+                            pTNd->GetTxt().Len(), TRUE );
+
+        if( pTNd->GetpSwAttrSet() )
+            pHistory->CopyFmtAttr( *pTNd->GetpSwAttrSet(), nNdPos );
+
+        aStr = pTNd->GetTxt();
+        if( pTNd->GetpSwpHints() )
+            pTNd->GetpSwpHints()->DeRegister();
+
+        pBoxSet = new SfxItemSet( pDoc->GetAttrPool(), aTableBoxSetRange );
+        pBoxSet->Put( rBox.GetFrmFmt()->GetAttrSet() );
+
+        if( pNewSet )
+        {
+            const SfxPoolItem* pItem;
+            if( SFX_ITEM_SET == pNewSet->GetItemState( RES_BOXATR_FORMAT,
+                    FALSE, &pItem ))
+            {
+                bNewFmt = TRUE;
+                nNewFmtIdx = ((SwTblBoxNumFormat*)pItem)->GetValue();
+            }
+            if( SFX_ITEM_SET == pNewSet->GetItemState( RES_BOXATR_FORMULA,
+                    FALSE, &pItem ))
+            {
+                bNewFml = TRUE;
+                aNewFml = ((SwTblBoxFormula*)pItem)->GetFormula();
+            }
+            if( SFX_ITEM_SET == pNewSet->GetItemState( RES_BOXATR_VALUE,
+                    FALSE, &pItem ))
+            {
+                bNewValue = TRUE;
+                fNewNum = ((SwTblBoxValue*)pItem)->GetValue();
+            }
+        }
+    }
+
+    // wird die History ueberhaupt benoetigt ??
+    if( pHistory && !pHistory->Count() )
+        DELETEZ( pHistory );
+}
+
+
+SwUndoTblNumFmt::~SwUndoTblNumFmt()
+{
+    delete pHistory;
+    delete pBoxSet;
+}
+
+void SwUndoTblNumFmt::Undo( SwUndoIter& rIter )
+{
+    // konnte die Box veraendert werden ?
+    if( !pBoxSet )
+        return ;
+
+    SwDoc& rDoc = rIter.GetDoc();
+    SwStartNode* pSttNd = rDoc.GetNodes()[ nNode ]->
+                            FindSttNodeByType( SwTableBoxStartNode );
+    ASSERT( pSttNd, "ohne StartNode kein TabellenBox" );
+    SwTableBox* pBox = pSttNd->FindTableNode()->GetTable().GetTblBox(
+                                    pSttNd->GetIndex() );
+    ASSERT( pBox, "keine TabellenBox gefunden" );
+
+    SwTableBoxFmt* pFmt = rDoc.MakeTableBoxFmt();
+    pFmt->SetAttr( *pBoxSet );
+    pBox->ChgFrmFmt( pFmt );
+
+    SwTxtNode* pTxtNd = rDoc.GetNodes()[ nNode + 1 ]->GetTxtNode();
+    // wenn mehr als ein Node geloescht wurde, dann wurden auch
+    // alle "Node"-Attribute gespeichert
+    if( pTxtNd->GetpSwAttrSet() )
+        pTxtNd->ResetAllAttr();
+
+    if( pTxtNd->GetpSwpHints() )
+        pTxtNd->ClearSwpHintsArr( FALSE );
+
+    SwIndex aIdx( pTxtNd, 0 );
+    pTxtNd->Erase( aIdx );
+    if( aStr.Len() )
+        pTxtNd->Insert( aStr, aIdx, INS_NOHINTEXPAND );
+
+    if( pHistory )
+    {
+        USHORT nTmpEnd = pHistory->GetTmpEnd();
+        pHistory->TmpRollback( &rDoc, 0 );
+        pHistory->SetTmpEnd( nTmpEnd );
+    }
+
+    SwPaM* pPam = rIter.pAktPam;
+    pPam->DeleteMark();
+    pPam->GetPoint()->nNode = nNode + 1;
+    pPam->GetPoint()->nContent.Assign( pTxtNd, 0 );
+}
+
+
+void SwUndoTblNumFmt::Redo( SwUndoIter& rIter )
+{
+    // konnte die Box veraendert werden ?
+    if( !pBoxSet )
+        return ;
+
+    SwDoc& rDoc = rIter.GetDoc();
+
+    SwPaM* pPam = rIter.pAktPam;
+    pPam->DeleteMark();
+    pPam->GetPoint()->nNode = nNode;
+
+    SwNode* pNd = rDoc.GetNodes()[ pPam->GetPoint()->nNode ];
+    SwStartNode* pSttNd = pNd->FindSttNodeByType( SwTableBoxStartNode );
+    ASSERT( pSttNd, "ohne StartNode kein TabellenBox" );
+    SwTableBox* pBox = pSttNd->FindTableNode()->GetTable().GetTblBox(
+                                    pSttNd->GetIndex() );
+    ASSERT( pBox, "keine TabellenBox gefunden" );
+
+    SwFrmFmt* pBoxFmt = pBox->ClaimFrmFmt();
+    if( bNewFmt || bNewFml || bNewValue )
+    {
+        SfxItemSet aBoxSet( rDoc.GetAttrPool(),
+                                RES_BOXATR_FORMAT, RES_BOXATR_VALUE );
+
+        // JP 15.01.99: Nur Attribute zuruecksetzen reicht nicht.
+        //              Sorge dafuer, das der Text auch entsprechend
+        //              formatiert wird!
+        pBoxFmt->LockModify();
+
+        if( bNewFml )
+            aBoxSet.Put( SwTblBoxFormula( aNewFml ));
+        else
+            pBoxFmt->ResetAttr( RES_BOXATR_FORMULA );
+        if( bNewFmt )
+            aBoxSet.Put( SwTblBoxNumFormat( nNewFmtIdx ));
+        else
+            pBoxFmt->ResetAttr( RES_BOXATR_FORMAT );
+        if( bNewValue )
+            aBoxSet.Put( SwTblBoxValue( fNewNum ));
+        else
+            pBoxFmt->ResetAttr( RES_BOXATR_VALUE );
+        pBoxFmt->UnlockModify();
+
+        pBoxFmt->SetAttr( aBoxSet );
+    }
+    else if( NUMBERFORMAT_TEXT != nFmtIdx )
+    {
+        SfxItemSet aBoxSet( rDoc.GetAttrPool(),
+                            RES_BOXATR_FORMAT, RES_BOXATR_VALUE );
+
+        aBoxSet.Put( SwTblBoxNumFormat( nFmtIdx ));
+        aBoxSet.Put( SwTblBoxValue( fNum ));
+
+        // JP 15.01.99: Nur Attribute zuruecksetzen reicht nicht.
+        //              Sorge dafuer, das der Text auch entsprechend
+        //              formatiert wird!
+        pBoxFmt->LockModify();
+        pBoxFmt->ResetAttr( RES_BOXATR_FORMULA );
+        pBoxFmt->UnlockModify();
+
+        pBoxFmt->SetAttr( aBoxSet );
+    }
+    else
+    {
+        // es ist keine Zahl
+
+        // JP 15.01.99: Nur Attribute zuruecksetzen reicht nicht.
+        //              Sorge dafuer, das der Text auch entsprechend
+        //              formatiert wird!
+        pBoxFmt->SetAttr( *GetDfltAttr( RES_BOXATR_FORMAT ));
+
+        pBoxFmt->ResetAttr( RES_BOXATR_FORMAT, RES_BOXATR_VALUE );
+    }
+
+    if( bNewFml )
+    {
+        // egal was gesetzt wurde, ein Update der Tabelle macht sich immer gut
+        SwTableFmlUpdate aTblUpdate( &pSttNd->FindTableNode()->GetTable() );
+        rDoc.UpdateTblFlds( &aTblUpdate );
+    }
+
+    if( !pNd->IsCntntNode() )
+        pNd = rDoc.GetNodes().GoNext( &pPam->GetPoint()->nNode );
+    pPam->GetPoint()->nContent.Assign( (SwCntntNode*)pNd, 0 );
+}
+
+void SwUndoTblNumFmt::SetBox( const SwTableBox& rBox )
+{
+    nNode = rBox.GetSttIdx();
+}
+
+/*  */
+
+_UndoTblCpyTbl_Entry::_UndoTblCpyTbl_Entry( const SwTableBox& rBox )
+    : nBoxIdx( rBox.GetSttIdx() ), nOffset( 0 ),
+    pBoxNumAttr( 0 ), pUndo( 0 )
+{
+}
+
+_UndoTblCpyTbl_Entry::~_UndoTblCpyTbl_Entry()
+{
+    delete pUndo;
+    delete pBoxNumAttr;
+}
+
+
+SwUndoTblCpyTbl::SwUndoTblCpyTbl()
+    : SwUndo( UNDO_TBLCPYTBL ), pInsRowUndo( 0 )
+{
+    pArr = new _UndoTblCpyTbl_Entries;
+}
+
+SwUndoTblCpyTbl::~SwUndoTblCpyTbl()
+{
+    delete pArr;
+    delete pInsRowUndo;
+}
+
+void SwUndoTblCpyTbl::Undo( SwUndoIter& rIter )
+{
+    SwDoc& rDoc = rIter.GetDoc();
+
+    SwTableNode* pTblNd = 0;
+    for( USHORT n = pArr->Count(); n; )
+    {
+        _UndoTblCpyTbl_Entry* pEntry = (*pArr)[ --n ];
+        ULONG nSttPos = pEntry->nBoxIdx + pEntry->nOffset;
+        SwStartNode* pSNd = rDoc.GetNodes()[ nSttPos ]->FindStartNode();
+        if( !pTblNd )
+            pTblNd = pSNd->FindTableNode();
+
+        SwTableBox& rBox = *pTblNd->GetTable().GetTblBox( nSttPos );
+
+        SwNodeIndex aInsIdx( *rBox.GetSttNd(), 1 );
+        SwTxtNode* pNd = rDoc.GetNodes().MakeTxtNode( aInsIdx,
+                                (SwTxtFmtColl*)rDoc.GetDfltTxtFmtColl());
+        SwPaM aPam( aInsIdx.GetNode(), *rBox.GetSttNd()->EndOfSectionNode() );
+        SwUndoDelete* pUndo = new SwUndoDelete( aPam, TRUE );
+
+        if( pEntry->pUndo )
+        {
+            pEntry->pUndo->Undo( rIter );
+            delete pEntry->pUndo;
+        }
+        pEntry->pUndo = pUndo;
+
+        aInsIdx = rBox.GetSttIdx() + 1;
+        rDoc.GetNodes().Delete( aInsIdx, 1 );
+
+        SfxItemSet aTmpSet( rDoc.GetAttrPool(), RES_BOXATR_FORMAT, RES_BOXATR_VALUE,
+                                                RES_VERT_ORIENT, RES_VERT_ORIENT, 0 );
+        aTmpSet.Put( rBox.GetFrmFmt()->GetAttrSet() );
+        if( aTmpSet.Count() )
+        {
+            SwFrmFmt* pBoxFmt = rBox.ClaimFrmFmt();
+            pBoxFmt->ResetAttr( RES_BOXATR_FORMAT, RES_BOXATR_VALUE );
+            pBoxFmt->ResetAttr( RES_VERT_ORIENT );
+        }
+
+        if( pEntry->pBoxNumAttr )
+        {
+            rBox.ClaimFrmFmt()->SetAttr( *pEntry->pBoxNumAttr );
+            delete pEntry->pBoxNumAttr, pEntry->pBoxNumAttr = 0;
+        }
+
+        if( aTmpSet.Count() )
+        {
+            pEntry->pBoxNumAttr = new SfxItemSet( rDoc.GetAttrPool(),
+                                    RES_BOXATR_FORMAT, RES_BOXATR_VALUE,
+                                    RES_VERT_ORIENT, RES_VERT_ORIENT, 0 );
+            pEntry->pBoxNumAttr->Put( aTmpSet );
+        }
+
+        pEntry->nOffset = rBox.GetSttIdx() - pEntry->nBoxIdx;
+    }
+
+    if( pInsRowUndo )
+        pInsRowUndo->Undo( rIter );
+}
+
+void SwUndoTblCpyTbl::Redo( SwUndoIter& rIter )
+{
+    SwDoc& rDoc = rIter.GetDoc();
+
+    if( pInsRowUndo )
+        pInsRowUndo->Redo( rIter );
+
+    SwTableNode* pTblNd = 0;
+    for( USHORT n = 0; n < pArr->Count(); ++n )
+    {
+        _UndoTblCpyTbl_Entry* pEntry = (*pArr)[ n ];
+        ULONG nSttPos = pEntry->nBoxIdx + pEntry->nOffset;
+        SwStartNode* pSNd = rDoc.GetNodes()[ nSttPos ]->FindStartNode();
+        if( !pTblNd )
+            pTblNd = pSNd->FindTableNode();
+
+        SwTableBox& rBox = *pTblNd->GetTable().GetTblBox( nSttPos );
+
+        SwNodeIndex aInsIdx( *rBox.GetSttNd(), 1 );
+        SwTxtNode* pNd = rDoc.GetNodes().MakeTxtNode( aInsIdx,
+                                (SwTxtFmtColl*)rDoc.GetDfltTxtFmtColl());
+        SwPaM aPam( aInsIdx.GetNode(), *rBox.GetSttNd()->EndOfSectionNode());
+        SwUndoDelete* pUndo = new SwUndoDelete( aPam, TRUE );
+
+        if( pEntry->pUndo )
+        {
+            pEntry->pUndo->Undo( rIter );
+            delete pEntry->pUndo;
+        }
+        pEntry->pUndo = pUndo;
+
+        aInsIdx = rBox.GetSttIdx() + 1;
+        rDoc.GetNodes().Delete( aInsIdx, 1 );
+
+        SfxItemSet aTmpSet( rDoc.GetAttrPool(), RES_BOXATR_FORMAT, RES_BOXATR_VALUE,
+                                                RES_VERT_ORIENT, RES_VERT_ORIENT, 0 );
+        aTmpSet.Put( rBox.GetFrmFmt()->GetAttrSet() );
+        if( aTmpSet.Count() )
+        {
+            SwFrmFmt* pBoxFmt = rBox.ClaimFrmFmt();
+            pBoxFmt->ResetAttr( RES_BOXATR_FORMAT, RES_BOXATR_VALUE );
+            pBoxFmt->ResetAttr( RES_VERT_ORIENT );
+        }
+        if( pEntry->pBoxNumAttr )
+        {
+            rBox.ClaimFrmFmt()->SetAttr( *pEntry->pBoxNumAttr );
+            delete pEntry->pBoxNumAttr, pEntry->pBoxNumAttr = 0;
+        }
+
+        if( aTmpSet.Count() )
+        {
+            pEntry->pBoxNumAttr = new SfxItemSet( rDoc.GetAttrPool(),
+                                    RES_BOXATR_FORMAT, RES_BOXATR_VALUE,
+                                    RES_VERT_ORIENT, RES_VERT_ORIENT, 0 );
+            pEntry->pBoxNumAttr->Put( aTmpSet );
+        }
+
+        pEntry->nOffset = rBox.GetSttIdx() - pEntry->nBoxIdx;
+    }
+}
+
+void SwUndoTblCpyTbl::AddBoxBefore( const SwTableBox& rBox, BOOL bDelCntnt )
+{
+    if( pArr->Count() && !bDelCntnt )
+        return;
+
+    _UndoTblCpyTbl_Entry* pEntry = new _UndoTblCpyTbl_Entry( rBox );
+    pArr->Insert( pEntry, pArr->Count() );
+
+    SwDoc* pDoc = rBox.GetFrmFmt()->GetDoc();
+    if( bDelCntnt )
+    {
+        SwNodeIndex aInsIdx( *rBox.GetSttNd(), 1 );
+        SwTxtNode* pNd = pDoc->GetNodes().MakeTxtNode( aInsIdx,
+                                (SwTxtFmtColl*)pDoc->GetDfltTxtFmtColl());
+        SwPaM aPam( aInsIdx.GetNode(), *rBox.GetSttNd()->EndOfSectionNode() );
+        pEntry->pUndo = new SwUndoDelete( aPam, TRUE );
+
+    }
+
+    pEntry->pBoxNumAttr = new SfxItemSet( pDoc->GetAttrPool(),
+                                    RES_BOXATR_FORMAT, RES_BOXATR_VALUE,
+                                    RES_VERT_ORIENT, RES_VERT_ORIENT, 0 );
+    pEntry->pBoxNumAttr->Put( rBox.GetFrmFmt()->GetAttrSet() );
+    if( !pEntry->pBoxNumAttr->Count() )
+        delete pEntry->pBoxNumAttr, pEntry->pBoxNumAttr = 0;
+}
+
+void SwUndoTblCpyTbl::AddBoxAfter( const SwTableBox& rBox, BOOL bDelCntnt )
+{
+    _UndoTblCpyTbl_Entry* pEntry = (*pArr)[ pArr->Count() - 1 ];
+
+    // wurde der Inhalt geloescht, so loesche jetzt auch noch den temp.
+    // erzeugten Node
+    if( bDelCntnt && pEntry->pUndo )
+    {
+        SwNodeIndex aDelIdx( *rBox.GetSttNd(), 1 );
+        rBox.GetFrmFmt()->GetDoc()->GetNodes().Delete( aDelIdx, 1 );
+    }
+    pEntry->nOffset = rBox.GetSttIdx() - pEntry->nBoxIdx;
+}
+
+BOOL SwUndoTblCpyTbl::InsertRow( SwTable& rTbl, const SwSelBoxes& rBoxes,
+                                USHORT nCnt )
+{
+    SwTableNode* pTblNd = (SwTableNode*)rTbl.GetTabSortBoxes()[0]->
+                                GetSttNd()->FindTableNode();
+
+    SwTableSortBoxes aTmpLst( 0, 5 );
+    pInsRowUndo = new SwUndoTblNdsChg( UNDO_TABLE_INSROW, rBoxes, *pTblNd,
+                                        nCnt, TRUE );
+    aTmpLst.Insert( &rTbl.GetTabSortBoxes(), 0, rTbl.GetTabSortBoxes().Count() );
+
+    BOOL bRet = rTbl.InsertRow( rTbl.GetFrmFmt()->GetDoc(), rBoxes, nCnt, TRUE );
+    if( bRet )
+        pInsRowUndo->SaveNewBoxes( *pTblNd, aTmpLst );
+    else
+        delete pInsRowUndo, pInsRowUndo = 0;
+    return bRet;
+}
+
+BOOL SwUndoTblCpyTbl::IsEmpty() const
+{
+    return !pInsRowUndo && !pArr->Count();
+}
+
+/*  */
+
+SwUndoCpyTbl::SwUndoCpyTbl()
+    : SwUndo( UNDO_CPYTBL ), pDel( 0 ), nTblNode( 0 )
+{
+}
+
+SwUndoCpyTbl::~SwUndoCpyTbl()
+{
+    delete pDel;
+}
+
+void SwUndoCpyTbl::Undo( SwUndoIter& rIter )
+{
+    SwDoc& rDoc = rIter.GetDoc();
+    SwTableNode* pTNd = rDoc.GetNodes()[ nTblNode ]->GetTableNode();
+
+    // harte SeitenUmbrueche am nachfolgenden Node verschieben
+    SwCntntNode* pNextNd = rDoc.GetNodes()[ pTNd->EndOfSectionIndex()+1 ]->GetCntntNode();
+    if( pNextNd )
+    {
+        SwFrmFmt* pTableFmt = pTNd->GetTable().GetFrmFmt();
+        const SfxPoolItem *pItem;
+
+        if( SFX_ITEM_SET == pTableFmt->GetItemState( RES_PAGEDESC,
+            FALSE, &pItem ) )
+            pNextNd->SetAttr( *pItem );
+
+        if( SFX_ITEM_SET == pTableFmt->GetItemState( RES_BREAK,
+            FALSE, &pItem ) )
+            pNextNd->SetAttr( *pItem );
+    }
+
+    SwPaM aPam( *pTNd, *pTNd->EndOfSectionNode(), 0 , 1 );
+    pDel = new SwUndoDelete( aPam, TRUE );
+}
+
+void SwUndoCpyTbl::Redo( SwUndoIter& rIter )
+{
+    pDel->Undo( rIter );
+    delete pDel, pDel = 0;
+}
+
+
+/*  */
+
+SwUndoSplitTbl::SwUndoSplitTbl( const SwTableNode& rTblNd, USHORT eMode,
+                                BOOL bNewSize )
+    : SwUndo( UNDO_SPLIT_TABLE ), pSavTbl( 0 ),
+    nTblNode( rTblNd.GetIndex() ), nMode( eMode ), nOffset( 0 ), nFmlEnd( 0 ),
+    pHistory( 0 ), bCalcNewSize( bNewSize )
+{
+    switch( nMode )
+    {
+    case HEADLINE_BOXATRCOLLCOPY:
+            pHistory = new SwHistory;
+            // kein break;
+    case HEADLINE_BORDERCOPY:
+    case HEADLINE_BOXATTRCOPY:
+        pSavTbl = new _SaveTable( rTblNd.GetTable(), 1, FALSE );
+        break;
+    }
+}
+
+SwUndoSplitTbl::~SwUndoSplitTbl()
+{
+    delete pSavTbl;
+    delete pHistory;
+}
+
+void SwUndoSplitTbl::Undo( SwUndoIter& rIter )
+{
+    SwPaM* pPam = rIter.pAktPam;
+    SwDoc* pDoc = pPam->GetDoc();
+
+    pPam->DeleteMark();
+    SwNodeIndex& rIdx = pPam->GetPoint()->nNode;
+    rIdx = nTblNode + nOffset;
+
+    //Den implizit erzeugten Absatz wieder entfernen.
+    pDoc->GetNodes().Delete( rIdx, 1 );
+
+    rIdx = nTblNode + nOffset;
+    SwTableNode* pTblNd = rIdx.GetNode().GetTableNode();
+    SwTable& rTbl = pTblNd->GetTable();
+
+    SwTableFmlUpdate aMsgHnt( &rTbl );
+    aMsgHnt.eFlags = TBL_BOXPTR;
+    pDoc->UpdateTblFlds( &aMsgHnt );
+
+    switch( nMode )
+    {
+    case HEADLINE_BOXATRCOLLCOPY:
+        if( pHistory )
+            pHistory->TmpRollback( pDoc, nFmlEnd );
+
+        // kein break
+    case HEADLINE_BOXATTRCOPY:
+    case HEADLINE_BORDERCOPY:
+        {
+            pSavTbl->CreateNew( rTbl, FALSE );
+            pSavTbl->RestoreAttr( rTbl );
+        }
+        break;
+
+    case HEADLINE_CNTNTCOPY:
+        // die erzeugte 1. Line muss wieder entfernt werden
+        {
+            SwSelBoxes aSelBoxes;
+            SwTableBox* pBox = rTbl.GetTblBox( nTblNode + nOffset + 1 );
+            rTbl.SelLineFromBox( pBox, aSelBoxes, TRUE );
+            rTbl.DeleteSel( pDoc, aSelBoxes, 0, FALSE, FALSE );
+        }
+        break;
+    }
+
+    pDoc->GetNodes().MergeTable( rIdx );
+
+    if( pHistory )
+    {
+        pHistory->TmpRollback( pDoc, 0 );
+        pHistory->SetTmpEnd( pHistory->Count() );
+    }
+
+    ClearFEShellTabCols();
+}
+
+void SwUndoSplitTbl::Redo( SwUndoIter& rIter )
+{
+    SwPaM* pPam = rIter.pAktPam;
+    SwDoc* pDoc = pPam->GetDoc();
+
+    pPam->DeleteMark();
+    pPam->GetPoint()->nNode = nTblNode;
+    pDoc->SplitTable( *pPam->GetPoint(), nMode, bCalcNewSize );
+
+    ClearFEShellTabCols();
+}
+
+void SwUndoSplitTbl::Repeat( SwUndoIter& rIter )
+{
+    SwPaM* pPam = rIter.pAktPam;
+    SwDoc* pDoc = pPam->GetDoc();
+
+    pDoc->SplitTable( *pPam->GetPoint(), nMode, bCalcNewSize );
+    ClearFEShellTabCols();
+}
+
+void SwUndoSplitTbl::SaveFormula( SwHistory& rHistory )
+{
+    if( !pHistory )
+        pHistory = new SwHistory;
+
+    nFmlEnd = rHistory.Count();
+    pHistory->Move( 0, &rHistory );
+}
+
+/*  */
+
+SwUndoMergeTbl::SwUndoMergeTbl( const SwTableNode& rTblNd,
+                                const SwTableNode& rDelTblNd,
+                                BOOL bWithPrv, USHORT nMd )
+    : SwUndo( UNDO_MERGE_TABLE ), pSavTbl( 0 ),
+    pHistory( 0 ), bWithPrev( bWithPrv ), nMode( nMd )
+{
+    // Endnode der letzen Tabellenzelle merken, die auf der Position verbleibt
+    if( bWithPrev )
+        nTblNode = rDelTblNd.EndOfSectionIndex() - 1;
+    else
+        nTblNode = rTblNd.EndOfSectionIndex() - 1;
+
+    aName = rDelTblNd.GetTable().GetFrmFmt()->GetName();
+    pSavTbl = new _SaveTable( rDelTblNd.GetTable() );
+
+    pSavHdl = bWithPrev ? new _SaveTable( rTblNd.GetTable(), 1 ) : 0;
+}
+
+SwUndoMergeTbl::~SwUndoMergeTbl()
+{
+    delete pSavTbl;
+    delete pSavHdl;
+    delete pHistory;
+}
+
+void SwUndoMergeTbl::Undo( SwUndoIter& rIter )
+{
+    SwPaM* pPam = rIter.pAktPam;
+    SwDoc* pDoc = pPam->GetDoc();
+
+    pPam->DeleteMark();
+    SwNodeIndex& rIdx = pPam->GetPoint()->nNode;
+    rIdx = nTblNode;
+
+    SwTableNode* pTblNd = rIdx.GetNode().FindTableNode();
+    SwTable* pTbl = &pTblNd->GetTable();
+
+    SwTableFmlUpdate aMsgHnt( pTbl );
+    aMsgHnt.eFlags = TBL_BOXPTR;
+    pDoc->UpdateTblFlds( &aMsgHnt );
+
+    //Lines fuer das Layout-Update herausuchen.
+    _FndBox aFndBox( 0, 0 );
+    aFndBox.SetTableLines( *pTbl );
+    aFndBox.DelFrms( *pTbl );
+    aFndBox.SaveChartData( *pTbl );
+
+    SwTableNode* pNew = pDoc->GetNodes().SplitTable( rIdx, TRUE, FALSE );
+
+    //Layout updaten
+    aFndBox.MakeFrms( *pTbl );
+    aFndBox.RestoreChartData( *pTbl );
+
+    if( bWithPrev )
+    {
+        // den Namen umsetzen
+        pNew->GetTable().GetFrmFmt()->SetName( pTbl->GetFrmFmt()->GetName() );
+        pSavHdl->RestoreAttr( pNew->GetTable() );
+    }
+    else
+        pTbl = &pNew->GetTable();
+    pTbl->GetFrmFmt()->SetName( aName );
+
+//  pSavTbl->CreateNew( *pTbl, FALSE );
+    pSavTbl->RestoreAttr( *pTbl );
+
+
+    if( pHistory )
+    {
+        pHistory->TmpRollback( pDoc, 0 );
+        pHistory->SetTmpEnd( pHistory->Count() );
+    }
+
+    // fuer die neue Tabelle die Frames anlegen
+    SwNodeIndex aTmpIdx( *pNew );
+    pNew->MakeFrms( &aTmpIdx );
+
+    // Cursor  irgendwo in den Content stellen
+    SwCntntNode* pCNd = pDoc->GetNodes().GoNext( &rIdx );
+    pPam->GetPoint()->nContent.Assign( pCNd, 0 );
+
+    ClearFEShellTabCols();
+}
+
+void SwUndoMergeTbl::Redo( SwUndoIter& rIter )
+{
+    SwPaM* pPam = rIter.pAktPam;
+    SwDoc* pDoc = pPam->GetDoc();
+
+    pPam->DeleteMark();
+    pPam->GetPoint()->nNode = nTblNode;
+    if( bWithPrev )
+        pPam->GetPoint()->nNode = nTblNode + 3;
+    else
+        pPam->GetPoint()->nNode = nTblNode;
+
+    pDoc->MergeTable( *pPam->GetPoint(), bWithPrev, nMode );
+
+    ClearFEShellTabCols();
+}
+
+void SwUndoMergeTbl::Repeat( SwUndoIter& rIter )
+{
+    SwPaM* pPam = rIter.pAktPam;
+    SwDoc* pDoc = pPam->GetDoc();
+
+    pDoc->MergeTable( *pPam->GetPoint(), bWithPrev, nMode );
+    ClearFEShellTabCols();
+}
+
+void SwUndoMergeTbl::SaveFormula( SwHistory& rHistory )
+{
+    if( !pHistory )
+        pHistory = new SwHistory;
+    pHistory->Move( 0, &rHistory );
+}
+
+/*  */
+
+
+void InsertSort( SvUShorts& rArr, USHORT nIdx, USHORT* pInsPos )
+{
+    register USHORT nO  = rArr.Count(), nM, nU = 0;
+    if( nO > 0 )
+    {
+        nO--;
+        while( nU <= nO )
+        {
+            nM = nU + ( nO - nU ) / 2;
+            if( *(rArr.GetData() + nM) == nIdx )
+            {
+                ASSERT( FALSE, "Index ist schon vorhanden, darf nie sein!" );
+                return;
+            }
+            if( *(rArr.GetData() + nM) < nIdx )
+                nU = nM + 1;
+            else if( nM == 0 )
+                break;
+            else
+                nO = nM - 1;
+        }
+    }
+    rArr.Insert( nIdx, nU );
+    if( pInsPos )
+        *pInsPos = nU;
+}
+
+void InsertSort( SvULongs& rArr, ULONG nIdx, USHORT* pInsPos )
+{
+    register USHORT nO  = rArr.Count(), nM, nU = 0;
+    if( nO > 0 )
+    {
+        nO--;
+        while( nU <= nO )
+        {
+            nM = nU + ( nO - nU ) / 2;
+            if( *(rArr.GetData() + nM) == nIdx )
+            {
+                ASSERT( FALSE, "Index ist schon vorhanden, darf nie sein!" );
+                return;
+            }
+            if( *(rArr.GetData() + nM) < nIdx )
+                nU = nM + 1;
+            else if( nM == 0 )
+                break;
+            else
+                nO = nM - 1;
+        }
+    }
+    rArr.Insert( nIdx, nU );
+    if( pInsPos )
+        *pInsPos = nU;
+}
+
+#if defined( JP_DEBUG ) && !defined( PRODUCT )
+
+
+void DumpDoc( SwDoc* pDoc, const String& rFileNm )
+{
+    Writer* pWrt = SwIoSystem::GetWriter( "DEBUG" );
+    if( pWrt )
+    {
+        SvFileStream aStream( rFileNm, STREAM_STD_WRITE );
+        SwPaM* pPam = new SwPaM( pDoc, SwPosition( pDoc->GetNodes().EndOfContent ,
+                                                 pDoc->GetNodes().EndOfContent ));
+        pPam->Move( fnMoveBackward, fnGoDoc );
+        pPam->SetMark();
+        pPam->Move( fnMoveForward, fnGoDoc );
+
+        pWrt->Write( pPam, *pDoc, aStream, rFileNm.GetStr() );
+
+        delete pPam;
+    }
+}
+void CheckTable( const SwTable& rTbl )
+{
+    const SwNodes& rNds = rTbl.GetFrmFmt()->GetDoc()->GetNodes();
+    const SwTableSortBoxes& rSrtArr = pTblNd->GetTable().GetTabSortBoxes();
+    for( USHORT n = 0; n < rSrtArr.Count(); ++n )
+    {
+        const SwTableBox* pBox = rSrtArr[ n ];
+        const SwNode* pNd = pBox->GetSttNd();
+        ASSERT( rNds[ *pBox->GetSttIdx() ] == pNd, "Box mit falchem StartNode"  );
+    }
+}
+#endif
+
+/*************************************************************************
+
+      Source Code Control System - Header
+
+      $Header: /zpool/svn/migration/cvs_rep_09_09_08/code/sw/source/core/undo/untbl.cxx,v 1.1.1.1 2000-09-19 00:08:28 hr Exp $
+
+      Source Code Control System - Update
+
+      $Log: not supported by cvs2svn $
+      Revision 1.117  2000/09/18 16:04:30  willem.vandorp
+      OpenOffice header added.
+
+      Revision 1.116  2000/07/11 17:51:56  jp
+      Bug #76739#: SwUndoTblToTxt - save the HeadlineRepeat Flag
+
+      Revision 1.115  2000/05/09 10:04:51  jp
+      Changes for Unicode
+
+      Revision 1.114  2000/04/10 11:24:56  jp
+      Bug #74371#: SwUndoTblMerge:SaveColl - save hard format attributes too
+
+      Revision 1.113  1999/12/15 12:12:20  jp
+      Bug #70847#: SwUndoSplitTable - dont store formulas
+
+      Revision 1.112  1999/11/10 12:10:16  jp
+      Bug #66833#: save/restore fly by table to text
+
+      Revision 1.111  1999/10/25 12:44:43  jp
+      Bug #66833#: Text<->Table - set flys to the right position
+
+      Revision 1.110  1999/07/08 17:18:44  JP
+      Bug #67507#: ClearSwpHintsArr - optional dont delete fields/hardblanks/softhyps
+
+
+      Rev 1.109   08 Jul 1999 19:18:44   JP
+   Bug #67507#: ClearSwpHintsArr - optional dont delete fields/hardblanks/softhyps
+
+      Rev 1.108   30 Apr 1999 15:12:12   AMA
+   Fix #65184#: Undo von Tabelle<->Text
+
+      Rev 1.107   28 Apr 1999 22:43:46   JP
+   Bug #65491#: MoveBoxCntnt: InsPos gesondert merken, kann bei Bereichen verschoben werden
+
+      Rev 1.106   29 Mar 1999 16:28:36   JP
+   Bug #62847#: Parameter vom DeleteBox haben sich geaendert
+
+      Rev 1.105   23 Mar 1999 18:26:14   JP
+   Bug #63449#: SwUndoTblNumFmt:Redo - ggfs. die Tabellenformel entfernen
+
+      Rev 1.104   26 Feb 1999 15:35:56   JP
+   Bug #62500#: Tabellenmerge - bei Prev die Kopfzeile wieder restaurieren
+
+      Rev 1.103   25 Feb 1999 10:53:22   AMA
+   Fix #62257#: "Intelligenter" ClientIterator ueber Nodes
+
+      Rev 1.102   17 Feb 1999 21:10:22   JP
+   Task #61764#: neu: Tabellen zusammenfassen
+
+      Rev 1.101   17 Feb 1999 16:59:12   JP
+   Task #61764#: neue Undo Action fuers Tabellen zusammenfassen
+
+      Rev 1.100   11 Feb 1999 23:43:34   JP
+   Bug #55590#: Schnittstelle geaendert
+
+      Rev 1.99   26 Jan 1999 16:00:06   JP
+   Task #57749#: spaltige Bereiche - Save-/RestoreTblUpperFrms bekommen jetzt einen Node
+
+      Rev 1.98   15 Jan 1999 11:28:46   JP
+   Bug #60794#: Fehlererkennung beim Tabellenrechnen
+
+      Rev 1.97   30 Nov 1998 17:29:30   OM
+   #59770# Tabellenoptionen: Ueberschrift nur auf erster Seite
+
+      Rev 1.96   30 Nov 1998 16:16:58   JP
+   Bug #59720#: Tabellenoptionen auswerten
+
+      Rev 1.95   10 Nov 1998 19:51:52   JP
+   Task #58158#: InsertTable/TextToTable - Flags fuer HdlRepeat/LayoutSplit mitgeben
+
+      Rev 1.94   30 Jul 1998 17:03:24   JP
+   Bug #54295#: Formeln immer nur im Klartext sichern
+
+      Rev 1.93   16 Jul 1998 19:19:30   JP
+   Bug #52968#: Autoformat - NumFormat kann BoxInhalt veraendern, muss wieder herstellbar sein
+
+      Rev 1.92   30 Jun 1998 15:11:14   JP
+   Bug #51844#: SaveChart kann nur erfolgen, wenn die Tabelle mit den entsp. Daten vorliegt
+
+      Rev 1.91   15 Jun 1998 20:03:34   JP
+   TextToTable: Undo - vertikal Tab als Tab einfuegen
+
+      Rev 1.90   12 May 1998 23:39:30   JP
+   neu: InserTable/TextToTable mit optionalen AutoFormat, TextToTable: ggfs. DefBorder setzen
+
+      Rev 1.89   04 May 1998 15:23:50   JP
+   TblMerge: Redo wurde noch einfacher
+
+      Rev 1.88   29 Apr 1998 20:06:00   JP
+   SwDoc::MergeTbl: neue Schnittstelle
+
+      Rev 1.87   21 Apr 1998 17:12:28   JP
+   Bug #49288# SwUndoSplitTbl - Tabellenformeln sichern
+
+      Rev 1.86   20 Apr 1998 19:12:28   JP
+   Bug #49519#: bei Tabellenformeln nie den Wert mit speichern
+
+      Rev 1.85   02 Apr 1998 16:02:00   JP
+   Bug #49145#: UndoTblMerge::Undo - Cursor korrigieren vorm loeschen der Box
+
+      Rev 1.84   02 Apr 1998 15:14:14   JP
+   Redo: Undo-Flag wird schon von der EditShell abgeschaltet
+
+      Rev 1.83   27 Mar 1998 15:34:14   JP
+   UndoTblMerge: SaveCollection fuer leere Zellen einer Line
+
+      Rev 1.82   18 Mar 1998 21:12:38   JP
+   Bug #48744#: SplitTable um einen Modus erweitert
+
+      Rev 1.81   16 Mar 1998 23:17:24   JP
+   UndoSplitTable: um den Modus erweitert, CopyTable dafuer erweitert
+
+      Rev 1.80   25 Feb 1998 20:56:12   JP
+   UndoSplitTable: auch noch den erzeugten TextNode entfernen
+
+      Rev 1.79   25 Feb 1998 12:54:16   MA
+   new: SplitTable
+
+      Rev 1.78   16 Feb 1998 22:02:18   JP
+   neu: SplitTable - Tabelle an der vorgebenen Grundline aufsplitten (mit Undo)
+
+      Rev 1.77   06 Feb 1998 18:07:58   JP
+   UndoTblNum: beim Restaurieren einer Formel die Tabelle neu berechnen
+
+      Rev 1.76   29 Jan 1998 20:13:36   JP
+   UndoTblNumFmt: NodeOffset wird nicht benoetigt
+
+      Rev 1.75   28 Jan 1998 19:51:18   JP
+   CheckBoxNumFmt: BoxSttNode fuer Undo kann sich bei Redline noch veraendern
+
+      Rev 1.74   27 Jan 1998 22:36:14   JP
+   GetNumDepend durch GetDepends ersetzt
+
+      Rev 1.73   27 Jan 1998 15:26:34   JP
+   TableLine-/-BoxFormate direkt loeschen
+
+      Rev 1.72   22 Jan 1998 20:53:12   JP
+   CTOR des SwPaM umgestellt
+
+      Rev 1.71   08 Jan 1998 20:56:02   JP
+   SwDoc::GetRedlineTbl returnt jetzt eine Referenz
+
+      Rev 1.70   19 Dec 1997 12:14:22   JP
+   Undo: Redlining beachten
+
+      Rev 1.69   20 Nov 1997 18:26:46   MA
+   includes
+
+      Rev 1.68   17 Nov 1997 09:46:24   JP
+   Umstellung Numerierung
+
+      Rev 1.67   30 Oct 1997 14:36:04   AMA
+   Chg: Kein AutoFlag mehr an Break bzw. PageDesc-Attributen
+
+      Rev 1.66   09 Oct 1997 15:45:50   JP
+   Umstellung NodeIndex/-Array/BigPtrArray
+
+      Rev 1.65   12 Sep 1997 10:49:34   OS
+   ITEMID_* definiert
+
+      Rev 1.64   10 Sep 1997 10:43:42   JP
+   neu: Undo fuers kopieren von Tabellen & in Tabellen
+
+      Rev 1.63   03 Sep 1997 10:29:48   JP
+   zusaetzliches include von docary
+
+      Rev 1.62   15 Aug 1997 12:38:28   OS
+   charatr/frmatr/txtatr aufgeteilt
+
+      Rev 1.61   12 Aug 1997 12:36:44   OS
+   Header-Umstellung
+
+*************************************************************************/
+
+
diff --git a/sw/source/core/undo/untblk.cxx b/sw/source/core/undo/untblk.cxx
new file mode 100644
index 000000000000..f254a63fed0c
--- /dev/null
+++ b/sw/source/core/undo/untblk.cxx
@@ -0,0 +1,489 @@
+/*************************************************************************
+ *
+ *  $RCSfile: untblk.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:28 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _FRMFMT_HXX //autogen
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include            // fuer die UndoIds
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _UNDOBJ_HXX
+#include 
+#endif
+#ifndef _ROLBCK_HXX
+#include 
+#endif
+#ifndef _REDLINE_HXX
+#include 
+#endif
+
+
+
+SwUndoInserts::SwUndoInserts( USHORT nUndoId, const SwPaM& rPam )
+    : SwUndo( nUndoId ), SwUndRng( rPam ), nSetPos( 0 ),
+    pTxtFmtColl( 0 ), pLastNdColl(0), pPos( 0 ), nNdDiff( 0 ),
+    pFrmFmts( 0 ), pFlyUndos(0), pRedlData( 0 ), bSttWasTxtNd( TRUE )
+{
+    pHistory = new SwHistory;
+    SwDoc* pDoc = (SwDoc*)rPam.GetDoc();
+
+    SwTxtNode* pTxtNd = rPam.GetPoint()->nNode.GetNode().GetTxtNode();
+    if( pTxtNd )
+    {
+        pTxtFmtColl = pTxtNd->GetTxtColl();
+        pHistory->CopyAttr( pTxtNd->GetpSwpHints(), nSttNode,
+                            0, pTxtNd->GetTxt().Len(), FALSE );
+        if( pTxtNd->GetpSwAttrSet() )
+            pHistory->CopyFmtAttr( *pTxtNd->GetpSwAttrSet(), nSttNode );
+
+        if( !nSttCntnt )    // dann werden Flys mitgenommen !!
+        {
+            USHORT nArrLen = pDoc->GetSpzFrmFmts()->Count();
+            for( USHORT n = 0; n < nArrLen; ++n )
+            {
+                SwFrmFmt* pFmt = (*pDoc->GetSpzFrmFmts())[n];
+                const SwFmtAnchor* pAnchor = &pFmt->GetAnchor();
+                const SwPosition* pAPos;
+                if ( pAnchor->GetAnchorId() == FLY_AT_CNTNT &&
+                     0 != ( pAPos = pAnchor->GetCntntAnchor()) &&
+                     nSttNode == pAPos->nNode.GetIndex() )
+                {
+                    if( !pFrmFmts )
+                        pFrmFmts = new SvPtrarr;
+                    pFrmFmts->Insert( pFmt, pFrmFmts->Count() );
+                }
+            }
+        }
+    }
+    // Redline beachten
+    if( pDoc->IsRedlineOn() )
+    {
+        pRedlData = new SwRedlineData( REDLINE_INSERT, pDoc->GetRedlineAuthor() );
+        SetRedlineMode( pDoc->GetRedlineMode() );
+    }
+}
+
+// setze den Destination-Bereich nach dem Einlesen.
+
+void SwUndoInserts::SetInsertRange( const SwPaM& rPam, BOOL bScanFlys,
+                                    BOOL bSttIsTxtNd )
+{
+    nEndNode = rPam.End()->nNode.GetIndex();
+    nEndCntnt = rPam.End()->nContent.GetIndex();
+    if( rPam.HasMark() )
+    {
+        nSttNode = rPam.Start()->nNode.GetIndex();
+        nSttCntnt = rPam.Start()->nContent.GetIndex();
+
+        if( !bSttIsTxtNd )      // wird eine Tabellenselektion eingefuegt,
+        {
+            ++nSttNode;         // dann stimmt der CopyPam nicht ganz
+            bSttWasTxtNd = FALSE;
+        }
+    }
+
+    if( bScanFlys && !nSttCntnt )
+    {
+        // dann alle neuen Flys zusammen sammeln !!
+        SwDoc* pDoc = (SwDoc*)rPam.GetDoc();
+        pFlyUndos = new SwUndos();
+        USHORT nFndPos, nArrLen = pDoc->GetSpzFrmFmts()->Count();
+        for( USHORT n = 0; n < nArrLen; ++n )
+        {
+            SwFrmFmt* pFmt = (*pDoc->GetSpzFrmFmts())[n];
+            const SwFmtAnchor* pAnchor = &pFmt->GetAnchor();
+            const SwPosition* pAPos;
+            if( pAnchor->GetAnchorId() == FLY_AT_CNTNT &&
+                0 != ( pAPos = pAnchor->GetCntntAnchor()) &&
+                nSttNode == pAPos->nNode.GetIndex() )
+            {
+                if( !pFrmFmts ||
+                    USHRT_MAX == ( nFndPos = pFrmFmts->GetPos( pFmt ) ) )
+                {
+                    SwUndoInsLayFmt* pFlyUndo = new SwUndoInsLayFmt( pFmt );
+                    pFlyUndos->Insert( pFlyUndo, pFlyUndos->Count() );
+                }
+                else
+                    pFrmFmts->Remove( nFndPos );
+            }
+        }
+        delete pFrmFmts, pFrmFmts = 0;
+        if( !pFlyUndos->Count() )
+            delete pFlyUndos, pFlyUndos = 0;
+    }
+}
+
+
+SwUndoInserts::~SwUndoInserts()
+{
+    if( pPos )      // loesche noch den Bereich aus dem UndoNodes Array
+    {
+        // Insert speichert den Inhalt in der IconSection
+        SwNodes& rUNds = pPos->nNode.GetNodes();
+        if( pPos->nContent.GetIndex() )         // nicht den gesamten Node loeschen
+        {
+            SwTxtNode* pTxtNd = pPos->nNode.GetNode().GetTxtNode();
+            ASSERT( pTxtNd, "kein TextNode, aus dem geloescht werden soll" );
+            pTxtNd->Erase( pPos->nContent );
+            pPos->nNode++;
+        }
+        pPos->nContent.Assign( 0, 0 );
+        rUNds.Delete( pPos->nNode, rUNds.GetEndOfExtras().GetIndex() -
+                                    pPos->nNode.GetIndex() );
+        delete pPos;
+    }
+    delete pFrmFmts;
+    delete pFlyUndos;
+    delete pRedlData;
+}
+
+
+void SwUndoInserts::Undo( SwUndoIter& rUndoIter )
+{
+    SwPaM * pPam = rUndoIter.pAktPam;
+    SwDoc* pDoc = pPam->GetDoc();
+    SetPaM( rUndoIter );
+    BOOL bUndo = pDoc->DoesUndo();
+    pDoc->DoUndo( FALSE );
+
+    if( IsRedlineOn( GetRedlineMode() ))
+        pDoc->DeleteRedline( *pPam );
+
+    // sind an Point/Mark 2 unterschiedliche TextNodes, dann muss ein
+    // JoinNext ausgefuehrt werden.
+    BOOL bJoinNext = nSttNode != nEndNode &&
+                pPam->GetMark()->nNode.GetNode().GetTxtNode() &&
+                pPam->GetPoint()->nNode.GetNode().GetTxtNode();
+
+
+    // gibts ueberhaupt Inhalt ? (laden von Zeichenvorlagen hat kein Inhalt!)
+    if( nSttNode != nEndNode || nSttCntnt != nEndCntnt )
+    {
+        if( nSttNode != nEndNode )
+        {
+            SwTxtNode* pTxtNd = pDoc->GetNodes()[ nEndNode ]->GetTxtNode();
+            if( pTxtNd && pTxtNd->GetTxt().Len() == nEndCntnt )
+                pLastNdColl = pTxtNd->GetTxtColl();
+        }
+
+        RemoveIdxFromRange( *pPam, FALSE );
+        SetPaM( rUndoIter );
+
+        // sind Fussnoten oder CntntFlyFrames im Text ??
+        nSetPos = pHistory->Count();
+        nNdDiff = pPam->GetMark()->nNode.GetIndex();
+        DelCntntIndex( *pPam->GetMark(), *pPam->GetPoint() );
+        nNdDiff -= pPam->GetMark()->nNode.GetIndex();
+
+        if( *pPam->GetPoint() != *pPam->GetMark() )
+        {
+            pPos = new SwPosition( *pPam->GetPoint() );
+            MoveToUndoNds( *pPam, &pPos->nNode, &pPos->nContent );
+
+            if( !bSttWasTxtNd )
+                pPam->Move( fnMoveBackward, fnGoCntnt );
+        }
+    }
+
+    if( pFlyUndos )
+    {
+        ULONG nTmp = pPam->GetPoint()->nNode.GetIndex();
+        for( USHORT n = pFlyUndos->Count(); n; )
+            (*pFlyUndos)[ --n ]->Undo( rUndoIter );
+        nNdDiff += nTmp - pPam->GetPoint()->nNode.GetIndex();
+    }
+
+    SwNodeIndex& rIdx = pPam->GetPoint()->nNode;
+    SwTxtNode* pTxtNode = rIdx.GetNode().GetTxtNode();
+    if( pTxtNode )
+    {
+        if( !pTxtFmtColl )      // falls 0, dann war hier auch kein TextNode,
+        {                       // dann muss dieser geloescht werden,
+            SwNodeIndex aDelIdx( rIdx );
+            rIdx++;
+            SwCntntNode* pCNd = rIdx.GetNode().GetCntntNode();
+            xub_StrLen nCnt = 0; if( pCNd ) nCnt = pCNd->Len();
+            pPam->GetPoint()->nContent.Assign( pCNd, nCnt );
+            pPam->SetMark();
+            pPam->DeleteMark();
+
+            RemoveIdxRel( aDelIdx.GetIndex(), *pPam->GetPoint() );
+
+            pDoc->GetNodes().Delete( aDelIdx, 1 );
+        }
+        else
+        {
+            pDoc->RstTxtAttr( *pPam, TRUE );
+            if( bJoinNext && pTxtNode->CanJoinNext())
+            {
+                {
+                    RemoveIdxRel( rIdx.GetIndex()+1, SwPosition( rIdx,
+                            SwIndex( pTxtNode, pTxtNode->GetTxt().Len() )));
+                }
+                pTxtNode->JoinNext();
+            }
+
+            // setze alle Attribute im Node zurueck
+// ALT          pDoc->ResetAttr( *pPam, FALSE );
+            pTxtNode->SwCntntNode::ResetAllAttr();
+
+            if( USHRT_MAX != pDoc->GetTxtFmtColls()->GetPos( pTxtFmtColl ))
+                pTxtFmtColl = (SwTxtFmtColl*)pTxtNode->ChgFmtColl( pTxtFmtColl );
+
+            pHistory->SetTmpEnd( nSetPos );
+            pHistory->TmpRollback( pDoc, 0, FALSE );
+        }
+    }
+
+    pDoc->DoUndo( bUndo );
+    if( pPam != rUndoIter.pAktPam )
+        delete pPam;
+}
+
+void SwUndoInserts::Redo( SwUndoIter& rUndoIter )
+{
+    // setze noch den Cursor auf den Redo-Bereich
+    SwPaM* pPam = rUndoIter.pAktPam;
+    SwDoc* pDoc = pPam->GetDoc();
+    pPam->DeleteMark();
+    pPam->GetPoint()->nNode = nSttNode - nNdDiff;
+    SwCntntNode* pCNd = pPam->GetCntntNode();
+    pPam->GetPoint()->nContent.Assign( pCNd, nSttCntnt );
+
+    SwTxtFmtColl* pSavTxtFmtColl = pTxtFmtColl;
+    if( pTxtFmtColl && pCNd && pCNd->IsTxtNode() )
+        pSavTxtFmtColl = ((SwTxtNode*)pCNd)->GetTxtColl();
+
+    pHistory->SetTmpEnd( nSetPos );
+    pHistory->TmpRollback( pDoc, 0, FALSE );
+
+    // alte Anfangs-Position fuers Rollback zurueckholen
+    if( ( nSttNode != nEndNode || nSttCntnt != nEndCntnt ) && pPos )
+    {
+        BOOL bMvBkwrd = MovePtBackward( *pPam );
+
+        // Inhalt wieder einfuegen. (erst pPos abmelden !!)
+        ULONG nMvNd = pPos->nNode.GetIndex();
+        xub_StrLen nMvCnt = pPos->nContent.GetIndex();
+        DELETEZ( pPos );
+        MoveFromUndoNds( *pDoc, nMvNd, nMvCnt, *pPam->GetMark() );
+        if( bSttWasTxtNd )
+            MovePtForward( *pPam, bMvBkwrd );
+        pPam->Exchange();
+    }
+
+    if( USHRT_MAX != pDoc->GetTxtFmtColls()->GetPos( pTxtFmtColl ))
+    {
+        SwTxtNode* pTxtNd = pPam->GetMark()->nNode.GetNode().GetTxtNode();
+        if( pTxtNd )
+            pTxtNd->ChgFmtColl( pTxtFmtColl );
+    }
+    pTxtFmtColl = pSavTxtFmtColl;
+
+    if( pLastNdColl && USHRT_MAX != pDoc->GetTxtFmtColls()->GetPos( pLastNdColl ) &&
+        pPam->GetPoint()->nNode != pPam->GetMark()->nNode )
+    {
+        SwTxtNode* pTxtNd = pPam->GetPoint()->nNode.GetNode().GetTxtNode();
+        if( pTxtNd )
+            pTxtNd->ChgFmtColl( pLastNdColl );
+    }
+
+    if( pFlyUndos )
+        for( USHORT n = pFlyUndos->Count(); n; )
+            (*pFlyUndos)[ --n ]->Redo( rUndoIter );
+
+    pHistory->Rollback( pDoc, nSetPos );
+
+    if( pRedlData && IsRedlineOn( GetRedlineMode() ))
+    {
+        SwRedlineMode eOld = pDoc->GetRedlineMode();
+        pDoc->SetRedlineMode_intern( eOld & ~REDLINE_IGNORE );
+        pDoc->AppendRedline( new SwRedline( *pRedlData, *pPam ));
+        pDoc->SetRedlineMode_intern( eOld );
+    }
+    else if( !( REDLINE_IGNORE & GetRedlineMode() ) &&
+            pDoc->GetRedlineTbl().Count() )
+        pDoc->SplitRedline( *pPam );
+}
+
+void SwUndoInserts::Repeat( SwUndoIter& rUndoIter )
+{
+    if( GetId() == rUndoIter.GetLastUndoId() )
+        return;
+
+    SwPaM aPam( *rUndoIter.pAktPam->GetPoint() );
+    SetPaM( aPam );
+    aPam.GetDoc()->Copy( aPam, *rUndoIter.pAktPam->GetPoint() );
+
+    rUndoIter.pLastUndoObj = this;
+}
+
+
+/*  */
+
+
+SwUndoInsDoc::SwUndoInsDoc( const SwPaM& rPam )
+    : SwUndoInserts( UNDO_INSDOKUMENT, rPam )
+{
+}
+
+SwUndoCpyDoc::SwUndoCpyDoc( const SwPaM& rPam )
+    : SwUndoInserts( UNDO_COPY, rPam )
+{
+}
+
+/*************************************************************************
+
+      Source Code Control System - Header
+
+      $Header: /zpool/svn/migration/cvs_rep_09_09_08/code/sw/source/core/undo/untblk.cxx,v 1.1.1.1 2000-09-19 00:08:28 hr Exp $
+
+      Source Code Control System - Update
+
+      $Log: not supported by cvs2svn $
+      Revision 1.52  2000/09/18 16:04:30  willem.vandorp
+      OpenOffice header added.
+
+      Revision 1.51  2000/07/03 19:25:19  jp
+      Bug #67696#: RstTxtAttr must delete TOX- and RefMarks
+
+      Revision 1.50  2000/05/09 10:04:56  jp
+      Changes for Unicode
+
+      Revision 1.49  1999/03/18 18:41:22  JP
+      Bug #63715#: SetRange - nur absatzgebundene Fly einsammeln
+
+
+      Rev 1.48   18 Mar 1999 19:41:22   JP
+   Bug #63715#: SetRange - nur absatzgebundene Fly einsammeln
+
+      Rev 1.47   28 Jul 1998 13:00:44   JP
+   Bug #53951#: Redlines am Anfang vom Node Copy/Move Bereich sonderbehandeln
+
+      Rev 1.46   06 May 1998 21:33:36   JP
+   das einfuegen einer Tabelleselektion setzt den StartNode falsch
+
+      Rev 1.45   20 Mar 1998 14:53:22   JP
+   Bug #48632# Undo - nicht auf 0 Pointer zugreifen
+
+      Rev 1.44   12 Feb 1998 16:51:58   JP
+   kleinere Optimierungen
+
+      Rev 1.43   29 Jan 1998 21:31:52   JP
+   GetEndOfIcons ersetzt durch GetEndOfExtras, das auf GetEndOfRedlines mappt
+
+      Rev 1.42   22 Jan 1998 20:53:12   JP
+   CTOR des SwPaM umgestellt
+
+      Rev 1.41   08 Jan 1998 20:56:04   JP
+   SwDoc::GetRedlineTbl returnt jetzt eine Referenz
+
+      Rev 1.40   19 Dec 1997 12:14:24   JP
+   Undo: Redlining beachten
+
+      Rev 1.39   18 Nov 1997 16:36:46   JP
+   ResetAttr uber den Node und nicht uebers Doc rufen
+
+      Rev 1.38   03 Nov 1997 13:06:26   MA
+   precomp entfernt
+
+      Rev 1.37   09 Oct 1997 15:45:48   JP
+   Umstellung NodeIndex/-Array/BigPtrArray
+
+      Rev 1.36   03 Sep 1997 10:29:56   JP
+   zusaetzliches include von docary
+
+      Rev 1.35   18 Aug 1997 10:36:06   OS
+   includes
+
+      Rev 1.34   15 Aug 1997 12:38:00   OS
+   charatr/frmatr/txtatr aufgeteilt
+
+      Rev 1.33   11 Jun 1997 10:44:08   JP
+   pure virtual Repeat wurde zur virtual Methode, Segment Pragma entfernt
+
+*************************************************************************/
+
diff --git a/sw/source/core/unocore/makefile.mk b/sw/source/core/unocore/makefile.mk
new file mode 100644
index 000000000000..68c4039412b9
--- /dev/null
+++ b/sw/source/core/unocore/makefile.mk
@@ -0,0 +1,152 @@
+#*************************************************************************
+#
+#   $RCSfile: makefile.mk,v $
+#
+#   $Revision: 1.1.1.1 $
+#
+#   last change: $Author: hr $ $Date: 2000-09-19 00:08:28 $
+#
+#   The Contents of this file are made available subject to the terms of
+#   either of the following licenses
+#
+#          - GNU Lesser General Public License Version 2.1
+#          - Sun Industry Standards Source License Version 1.1
+#
+#   Sun Microsystems Inc., October, 2000
+#
+#   GNU Lesser General Public License Version 2.1
+#   =============================================
+#   Copyright 2000 by Sun Microsystems, Inc.
+#   901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+#   This library is free software; you can redistribute it and/or
+#   modify it under the terms of the GNU Lesser General Public
+#   License version 2.1, as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   Lesser General Public License for more details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+#   License along with this library; if not, write to the Free Software
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+#   MA  02111-1307  USA
+#
+#
+#   Sun Industry Standards Source License Version 1.1
+#   =================================================
+#   The contents of this file are subject to the Sun Industry Standards
+#   Source License Version 1.1 (the "License"); You may not use this file
+#   except in compliance with the License. You may obtain a copy of the
+#   License at http://www.openoffice.org/license.html.
+#
+#   Software provided under this License is provided on an "AS IS" basis,
+#   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+#   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+#   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+#   See the License for the specific provisions governing your rights and
+#   obligations concerning the Software.
+#
+#   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+#   Copyright: 2000 by Sun Microsystems, Inc.
+#
+#   All Rights Reserved.
+#
+#   Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sw
+TARGET=unocore
+
+AUTOSEG=true
+
+PROJECTPCH=core_pch
+PDBTARGET=core_pch
+PROJECTPCHSOURCE=..$/core_1st$/core_pch
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE :	$(PRJ)$/inc$/swpre.mk
+.INCLUDE :	settings.mk
+.INCLUDE :	$(PRJ)$/inc$/sw.mk
+
+.IF "$(GUI)$(COM)" == "WINMSC"
+LIBFLAGS=/NOI /NOE /PAGE:512
+.ENDIF
+
+
+
+# --- Files --------------------------------------------------------
+
+CXXFILES = \
+        unobkm.cxx \
+        unoclbck.cxx \
+        unocoll.cxx \
+        unodraw.cxx \
+        unofield.cxx \
+        unoframe.cxx \
+        unoidx.cxx \
+        unomap.cxx \
+        unoobj.cxx \
+        unoport.cxx \
+        unoprnms.cxx \
+        unorefmk.cxx \
+        unosett.cxx \
+        unosrch.cxx \
+        unostyle.cxx \
+        unotbl.cxx	\
+         unotext.cxx
+
+
+SLOFILES =	\
+        $(SLO)$/unobkm.obj\
+        $(SLO)$/unoclbck.obj\
+        $(SLO)$/unoftn.obj\
+        $(SLO)$/unorefmk.obj\
+        $(SLO)$/unosect.obj\
+        $(SLO)$/unosett.obj\
+        $(SLO)$/unocoll.obj\
+        $(SLO)$/unodraw.obj\
+        $(SLO)$/unofield.obj\
+        $(SLO)$/unoframe.obj\
+        $(SLO)$/unoidx.obj\
+        $(SLO)$/unomap.obj\
+        $(SLO)$/unoobj.obj\
+        $(SLO)$/unoport.obj\
+        $(SLO)$/unoprnms.obj\
+        $(SLO)$/unosrch.obj\
+        $(SLO)$/unostyle.obj\
+        $(SLO)$/unotbl.obj \
+        $(SLO)$/unotext.obj
+
+EXCEPTIONSFILES= \
+        $(SLO)$/unobkm.obj\
+        $(SLO)$/unoclbck.obj\
+        $(SLO)$/unoftn.obj\
+        $(SLO)$/unorefmk.obj\
+        $(SLO)$/unosect.obj\
+        $(SLO)$/unosett.obj\
+        $(SLO)$/unodraw.obj\
+        $(SLO)$/unofield.obj\
+        $(SLO)$/unoframe.obj\
+        $(SLO)$/unoidx.obj\
+        $(SLO)$/unomap.obj\
+        $(SLO)$/unoobj.obj\
+        $(SLO)$/unoport.obj\
+        $(SLO)$/unosrch.obj\
+        $(SLO)$/unostyle.obj\
+        $(SLO)$/unocoll.obj\
+        $(SLO)$/unotbl.obj \
+        $(SLO)$/unotext.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE :	target.mk
+
diff --git a/sw/source/core/unocore/unobkm.cxx b/sw/source/core/unocore/unobkm.cxx
new file mode 100644
index 000000000000..e13513a90e4a
--- /dev/null
+++ b/sw/source/core/unocore/unobkm.cxx
@@ -0,0 +1,431 @@
+/*************************************************************************
+ *
+ *  $RCSfile: unobkm.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:28 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _VOS_MUTEX_HXX_ //autogen
+#include 
+#endif
+#ifndef _SV_SVAPP_HXX //autogen
+#include 
+#endif
+#ifndef _UNOOBJ_HXX
+#include 
+#endif
+#ifndef _UNOMAP_HXX
+#include 
+#endif
+#ifndef _UNOPRNMS_HXX
+#include 
+#endif
+#ifndef _BOOKMRK_HXX //autogen
+#include 
+#endif
+#ifndef _DOC_HXX //autogen
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX //autogen
+#include 
+#endif
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::beans;
+using namespace ::rtl;
+
+/******************************************************************
+ * SwXBookmark
+ ******************************************************************/
+TYPEINIT1(SwXBookmark, SwClient)
+/* -----------------------------13.03.00 12:15--------------------------------
+
+ ---------------------------------------------------------------------------*/
+const uno::Sequence< sal_Int8 > & SwXBookmark::getUnoTunnelId()
+{
+    static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId();
+    return aSeq;
+}
+/* -----------------------------10.03.00 18:04--------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Int64 SAL_CALL SwXBookmark::getSomething( const uno::Sequence< sal_Int8 >& rId )
+    throw(uno::RuntimeException)
+{
+    if( rId.getLength() == 16
+        && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+                                        rId.getConstArray(), 16 ) )
+    {
+            return (sal_Int64)this;
+    }
+    return 0;
+}
+/* -----------------10.12.98 10:16-------------------
+ *
+ * --------------------------------------------------*/
+SwXBookmark::SwXBookmark(SwBookmark* pBkm, SwDoc* pDc) :
+        pDoc(pDc),
+        bIsDescriptor(0 == pBkm),
+        aLstnrCntnr( (text::XTextContent*)this)
+{
+    if(pBkm)
+        pBkm->Add(this);
+}
+/*-- 10.12.98 10:14:29---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXBookmark::~SwXBookmark()
+{
+
+}
+/*-- 10.12.98 10:14:39---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXBookmark::attachToRange(const uno::Reference< text::XTextRange > & xTextRange)
+                                        throw( lang::IllegalArgumentException, uno::RuntimeException )
+{
+    if(!bIsDescriptor)
+        throw uno::RuntimeException();
+
+    uno::Reference xRangeTunnel( xTextRange, uno::UNO_QUERY);
+    SwXTextRange* pRange = 0;
+    SwXTextCursor* pCursor = 0;
+    if(xRangeTunnel.is())
+    {
+
+        pRange = (SwXTextRange*)xRangeTunnel->getSomething(
+                                SwXTextRange::getUnoTunnelId());
+        pCursor = (SwXTextCursor*)xRangeTunnel->getSomething(
+                                SwXTextCursor::getUnoTunnelId());
+    }
+
+    SwDoc* pDc = pRange ? (SwDoc*)pRange->GetDoc() : pCursor ?
+        (SwDoc*)pCursor->GetDoc() : 0;
+    if(pDc)
+    {
+        pDoc = pDc;
+        SwUnoInternalPaM aPam(*pDoc);
+        //das muss jetzt sal_True liefern
+        SwXTextRange::XTextRangeToSwPaM(aPam, xTextRange);
+        UnoActionContext aCont(pDoc);
+        SwBookmark* pBkm = 0;
+        {
+            if(!m_aName.Len())
+                 m_aName =  C2S("Bookmark");
+            if( USHRT_MAX != pDoc->FindBookmark(m_aName) )
+                pDoc->MakeUniqueBookmarkName( m_aName );
+            KeyCode aCode;
+            pBkm = pDoc->MakeBookmark( aPam, aCode,
+                                                m_aName, aEmptyStr, BOOKMARK);
+            pBkm->Add(this);
+            bIsDescriptor = sal_False;
+        }
+    }
+    else
+        throw lang::IllegalArgumentException();
+}
+/* -----------------18.02.99 13:31-------------------
+ *
+ * --------------------------------------------------*/
+void SwXBookmark::attach(const uno::Reference< text::XTextRange > & xTextRange)
+                            throw( lang::IllegalArgumentException, uno::RuntimeException )
+{
+}
+/*-- 10.12.98 10:14:39---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< text::XTextRange >  SwXBookmark::getAnchor(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< text::XTextRange >  aRet;
+    SwBookmark* pBkm = GetBookmark();
+
+    if(pBkm)
+    {
+        const SwPosition& rPos = pBkm->GetPos();
+        const SwPosition* pMarkPos = pBkm->GetOtherPos();
+
+        aRet = CreateTextRangeFromPosition(pDoc, rPos, pMarkPos);
+    }
+    else
+        throw uno::RuntimeException();
+    return aRet;
+
+
+}
+/*-- 10.12.98 10:14:40---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXBookmark::dispose(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwBookmark* pBkm = GetBookmark();
+    if(pBkm)
+        GetDoc()->DelBookmark(getName());
+    else
+        throw uno::RuntimeException();
+}
+/*-- 10.12.98 10:14:40---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXBookmark::addEventListener(const uno::Reference< lang::XEventListener > & aListener)
+                                                throw( uno::RuntimeException )
+{
+    if(!GetRegisteredIn())
+        throw uno::RuntimeException();
+    aLstnrCntnr.AddListener(aListener);
+}
+/*-- 10.12.98 10:14:41---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXBookmark::removeEventListener(const uno::Reference< lang::XEventListener > & aListener)
+    throw( uno::RuntimeException )
+{
+    if(!GetRegisteredIn() || !aLstnrCntnr.RemoveListener(aListener))
+        throw uno::RuntimeException();
+}
+/*-- 10.12.98 10:14:41---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+OUString SwXBookmark::getName(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwBookmark* pBkm = GetBookmark();
+    OUString sRet;
+    if(pBkm)
+        sRet = pBkm->GetName();
+    else if(bIsDescriptor)
+        sRet = m_aName;
+    else
+        throw uno::RuntimeException();
+    return sRet;
+}
+/*-- 10.12.98 10:14:42---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXBookmark::setName(const OUString& rName) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwBookmark* pBkm = GetBookmark();
+    String sBkName(rName);
+    String sOldName = getName();
+    if(sOldName != sBkName && pBkm && USHRT_MAX == pDoc->FindBookmark(sBkName))
+    {
+        KeyCode aCode;
+        String sShortName;
+        SwPaM aPam(pBkm->GetPos());
+        if(pBkm->GetOtherPos())
+        {
+            aPam.SetMark();
+            *aPam.GetMark() = *pBkm->GetOtherPos();
+        }
+        pDoc->StartUndo(UNDO_INSERT);
+
+        SwBookmark* pMark = pDoc->MakeBookmark(aPam, aCode,
+                    sBkName, sShortName, BOOKMARK);
+        pMark->Add(this);
+        GetDoc()->DelBookmark( sOldName );
+
+        pDoc->EndUndo(UNDO_INSERT);
+    }
+    else if(bIsDescriptor)
+        m_aName = sBkName;
+    else
+        throw uno::RuntimeException();
+}
+
+/* -----------------02.11.99 11:30-------------------
+
+ --------------------------------------------------*/
+OUString SwXBookmark::getImplementationName(void) throw( uno::RuntimeException )
+{
+    return C2U("SwXBookmark");
+}
+/* -----------------02.11.99 11:30-------------------
+
+ --------------------------------------------------*/
+sal_Bool SwXBookmark::supportsService(const OUString& rServiceName) throw( uno::RuntimeException )
+{
+    return !rServiceName.compareToAscii("com.sun.star.text.Bookmark") ||
+                !rServiceName.compareToAscii("com.sun.star.document.LinkTarget") ||
+                    !rServiceName.compareToAscii("com.sun.star.text.TextContent");
+;
+}
+/* -----------------02.11.99 11:30-------------------
+
+ --------------------------------------------------*/
+uno::Sequence< OUString > SwXBookmark::getSupportedServiceNames(void) throw( uno::RuntimeException )
+{
+    uno::Sequence< OUString > aRet(3);
+    OUString* pArr = aRet.getArray();
+    pArr[0] = C2U("com.sun.star.text.Bookmark");
+    pArr[1] = C2U("com.sun.star.document.LinkTarget");
+    pArr[2] = C2U("com.sun.star.text.TextContent");
+    return aRet;
+}
+/*-- 10.12.98 10:14:42---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void    SwXBookmark::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew)
+{
+    ClientModify(this, pOld, pNew);
+    if(!GetBookmark())
+    {
+        pDoc = 0;
+        aLstnrCntnr.Disposing();
+    }
+}
+/*-- 30.03.99 16:02:58---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< beans::XPropertySetInfo >  SwXBookmark::getPropertySetInfo(void) throw( uno::RuntimeException )
+{
+    static uno::Reference< beans::XPropertySetInfo >  aRef;
+    if(!aRef.is())
+    {
+        const SfxItemPropertyMap* pMap = aSwMapProvider.GetPropertyMap(PROPERTY_MAP_BOOKMARK);
+        uno::Reference< beans::XPropertySetInfo >  xInfo = new SfxItemPropertySetInfo(pMap);
+        // extend PropertySetInfo!
+        const uno::Sequence aPropSeq = xInfo->getProperties();
+        aRef = new SfxExtItemPropertySetInfo(
+            aSwMapProvider.GetPropertyMap(PROPERTY_MAP_PARAGRAPH_EXTENSIONS),
+            aPropSeq );
+    }
+    return aRef;
+}
+/*-- 30.03.99 16:02:59---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXBookmark::setPropertyValue(const OUString& PropertyName, const uno::Any& aValue)
+    throw( beans::UnknownPropertyException, beans::PropertyVetoException,
+        lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    throw IllegalArgumentException();
+    //hier gibt es nichts zu setzen
+}
+/*-- 30.03.99 16:02:59---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXBookmark::getPropertyValue(const OUString& rPropertyName) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    uno::Any aRet;
+    if(!SwXParagraph::getDefaultTextContentValue(aRet, rPropertyName))
+    {
+        if(0 == rPropertyName.compareToAscii(UNO_LINK_DISPLAY_NAME))
+            aRet <<= getName();
+    }
+    return aRet;
+}
+/*-- 30.03.99 16:02:59---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXBookmark::addPropertyChangeListener(const OUString& PropertyName,
+    const uno::Reference< beans::XPropertyChangeListener > & aListener)
+        throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+}
+/*-- 30.03.99 16:02:59---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXBookmark::removePropertyChangeListener(const OUString& PropertyName,
+    const uno::Reference< beans::XPropertyChangeListener > & aListener)
+            throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+}
+/*-- 30.03.99 16:03:00---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXBookmark::addVetoableChangeListener(const OUString& PropertyName,
+    const uno::Reference< beans::XVetoableChangeListener > & aListener)
+            throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+}
+/*-- 30.03.99 16:03:00---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXBookmark::removeVetoableChangeListener(const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener > & aListener) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+}
+
+/*------------------------------------------------------------------------
+
+    $Log: not supported by cvs2svn $
+    Revision 1.3  2000/09/18 16:04:31  willem.vandorp
+    OpenOffice header added.
+
+    Revision 1.2  2000/09/12 11:42:57  os
+    #78682# support of service TextContent
+
+    Revision 1.1  2000/05/04 15:12:53  os
+    reduce size of unoobj.cxx
+
+
+------------------------------------------------------------------------*/
+
diff --git a/sw/source/core/unocore/unoclbck.cxx b/sw/source/core/unocore/unoclbck.cxx
new file mode 100644
index 000000000000..0b0f0eaf74cb
--- /dev/null
+++ b/sw/source/core/unocore/unoclbck.cxx
@@ -0,0 +1,230 @@
+/*************************************************************************
+ *
+ *  $RCSfile: unoclbck.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:28 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include 
+#include 
+
+#ifndef _TOOLS_DEBUG_HXX
+#include 
+#endif
+#ifndef _SFXPOOLITEM_HXX
+#include 
+#endif
+
+#ifndef _UNOOBJ_HXX
+#include 
+#endif
+#ifndef _UNOCLBCK_HXX
+#include 
+#endif
+#ifndef _TXTFTN_HXX
+#include 
+#endif
+#ifndef _FMTFTN_HXX
+#include 
+#endif
+#ifndef _HINTS_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _FMTRFMRK_HXX
+#include 
+#endif
+#ifndef _TXTRFMRK_HXX
+#include 
+#endif
+
+/* -----------------------------06.01.00 13:51--------------------------------
+
+ ---------------------------------------------------------------------------*/
+SwUnoCallBack::SwUnoCallBack(SwModify *pToRegisterIn)   :
+    SwModify(pToRegisterIn)
+{
+}
+/* -----------------------------06.01.00 13:51--------------------------------
+
+ ---------------------------------------------------------------------------*/
+SwUnoCallBack::~SwUnoCallBack()
+{
+}
+/* -----------------------------06.01.00 13:51--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SwUnoCallBack::Modify( SfxPoolItem *pOldValue, SfxPoolItem *pNewValue )
+{
+    switch( pOldValue ? pOldValue->Which() : 0 )
+    {
+        case  RES_FOOTNOTE_DELETED:
+        {
+            SwClientIter aIter( *this );
+            SwXFootnote* pxFootnote = (SwXFootnote*)aIter.First( TYPE( SwXFootnote ));
+            while(pxFootnote)
+            {
+                const SwFmtFtn* pFmt = pxFootnote->FindFmt();
+                if(!pFmt)
+                    pxFootnote->Invalidate();
+                else
+                {
+                    const SwTxtFtn *pTxtFtn = pFmt ? pFmt->GetTxtFtn() : 0;
+                    if(pTxtFtn && (void*)pTxtFtn == ((SwPtrMsgPoolItem *)pOldValue)->pObject)
+                    {
+                        pxFootnote->Invalidate();
+                        break;
+                    }
+                }
+                pxFootnote = (SwXFootnote*)aIter.Next( );
+            }
+        }
+        break;
+        case  RES_REFMARK_DELETED:
+        {
+            SwClientIter aIter( *this );
+            SwXReferenceMark* pxRefMark = (SwXReferenceMark*)aIter.First( TYPE( SwXReferenceMark ));
+            while(pxRefMark)
+            {
+                SwDoc* pDoc = pxRefMark->GetDoc();
+                if(pDoc)
+                {
+                    const SwFmtRefMark* pFmt = pDoc->GetRefMark(pxRefMark->GetMarkName());
+                    if(!pFmt)
+                        pxRefMark->Invalidate();
+                    else if(pFmt == pxRefMark->GetMark())
+                    {
+                        const SwTxtRefMark *pTxtRef = pFmt ? pFmt->GetTxtRefMark() : 0;
+                        if(pTxtRef && (void*)pTxtRef == ((SwPtrMsgPoolItem *)pOldValue)->pObject)
+                        {
+                            pxRefMark->Invalidate();
+                            break;
+                        }
+                    }
+                }
+                pxRefMark = (SwXReferenceMark*)aIter.Next( );
+            }
+
+        }
+        break;
+    }
+}
+/* -----------------------------01.09.00 12:03--------------------------------
+
+ ---------------------------------------------------------------------------*/
+SwXReferenceMark*   SwUnoCallBack::GetRefMark(const SwFmtRefMark& rMark)
+{
+    SwClientIter aIter( *this );
+    SwXReferenceMark* pxRefMark = (SwXReferenceMark*)aIter.First( TYPE( SwXReferenceMark ));
+    while(pxRefMark)
+    {
+        SwDoc* pDoc = pxRefMark->GetDoc();
+        if(pDoc)
+        {
+            const SwFmtRefMark* pFmt = pDoc->GetRefMark(pxRefMark->GetMarkName());
+            if(pFmt == &rMark)
+                return pxRefMark;
+        }
+        pxRefMark = (SwXReferenceMark*)aIter.Next( );
+    }
+    return 0;
+}
+/* -----------------------------05.09.00 12:38--------------------------------
+
+ ---------------------------------------------------------------------------*/
+SwXFootnote*    SwUnoCallBack::GetFootnote(const SwFmtFtn& rMark)
+{
+    SwClientIter aIter( *this );
+    SwXFootnote* pxFootnote = (SwXFootnote*)aIter.First( TYPE( SwXFootnote ));
+    while(pxFootnote)
+    {
+        SwDoc* pDoc = pxFootnote->GetDoc();
+        if(pDoc)
+        {
+            const SwFmtFtn* pFtn = pxFootnote->FindFmt();
+            if(pFtn == &rMark)
+                return pxFootnote;
+        }
+        pxFootnote = (SwXFootnote*)aIter.Next( );
+    }
+    return 0;
+}
+
+/*------------------------------------------------------------------------
+    $Log: not supported by cvs2svn $
+    Revision 1.4  2000/09/18 16:04:31  willem.vandorp
+    OpenOffice header added.
+
+    Revision 1.3  2000/09/05 15:12:22  os
+    new: GetFootnote()
+
+    Revision 1.2  2000/09/01 14:22:15  os
+    new::GetRefMark()
+
+    Revision 1.1  2000/01/07 13:49:03  os
+    #67019# #65681# SwXReferenceMarks/SwXFootnotes: Modify via UnoCallBack
+
+
+------------------------------------------------------------------------*/
+
diff --git a/sw/source/core/unocore/unocoll.cxx b/sw/source/core/unocore/unocoll.cxx
new file mode 100644
index 000000000000..8928659ce901
--- /dev/null
+++ b/sw/source/core/unocore/unocoll.cxx
@@ -0,0 +1,2408 @@
+/*************************************************************************
+ *
+ *  $RCSfile: unocoll.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:28 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include 
+#include 
+#include 
+#ifndef _SVX_SVXIDS_HRC //autogen
+#include 
+#endif
+#ifndef _DOC_HXX //autogen
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _FMTCOL_HXX //autogen
+#include 
+#endif
+#ifndef _POOLFMT_HXX
+#include 
+#endif
+#ifndef _UNOCOLL_HXX
+#include 
+#endif
+#ifndef _UNOSETT_HXX
+#include 
+#endif
+#ifndef _UNOCLBCK_HXX
+#include 
+#endif
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _NDTXT_HXX //autogen
+#include 
+#endif
+#ifndef _SECTION_HXX //autogen
+#include 
+#endif
+#ifndef _BOOKMRK_HXX //autogen
+#include 
+#endif
+#ifndef _FTNIDX_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFTN_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFTN_HXX //autogen
+#include 
+#endif
+#ifndef _FMTPDSC_HXX //autogen
+#include 
+#endif
+#ifndef _PAGEDESC_HXX //autogen
+#include 
+#endif
+#ifndef _OSL_MUTEX_HXX_ //autogen
+#include 
+#endif
+#ifndef _VOS_MUTEX_HXX_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XTEXTTABLECURSOR_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XTEXTTABLESSUPPLIER_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_TABLECOLUMNSEPARATOR_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XTEXTTABLE_HPP_
+#include 
+#endif
+#ifndef _FRMFMT_HXX
+#include 
+#endif
+#ifndef _UNOTBL_HXX
+#include 
+#endif
+#ifndef _UNOSTYLE_HXX
+#include 
+#endif
+#ifndef _UNOFIELD_HXX
+#include 
+#endif
+#ifndef _UNOIDX_HXX
+#include 
+#endif
+#ifndef _UNOFRAME_HXX
+#include 
+#endif
+#ifndef _SV_SVAPP_HXX //autogen
+#include 
+#endif
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+
+/******************************************************************************
+ *
+ ******************************************************************************/
+const char* __FAR_DATA aProvNames[] =
+    {
+        "com.sun.star.text.TextTable",          //SW_SERVICE_TYPE_TEXTTABLE
+        "com.sun.star.text.TextFrame",          //SW_SERVICE_TYPE_TEXTFRAME
+        "com.sun.star.text.GraphicObject",          //SW_SERVICE_TYPE_GRAPHIC
+        "com.sun.star.text.EmbeddedObject",         //SW_SERVICE_TYPE_OLE
+        "com.sun.star.text.Bookmark",           //SW_SERVICE_TYPE_BOOKMARK
+        "com.sun.star.text.Footnote",           //SW_SERVICE_TYPE_FOOTNOTE
+        "com.sun.star.text.Endnote",            //SW_SERVICE_TYPE_ENDNOTE
+        "com.sun.star.text.DocumentIndexMark",  //SW_SERVICE_TYPE_INDEXMARK
+        "com.sun.star.text.DocumentIndex",      //SW_SERVICE_TYPE_INDEX
+        "com.sun.star.text.ReferenceMark",      //SW_SERVICE_REFERENCE_MARK
+        "com.sun.star.style.CharacterStyle",    //SW_SERVICE_STYLE_CHARACTER_STYLE
+        "com.sun.star.style.ParagraphStyle",    //SW_SERVICE_STYLE_PARAGRAPH_STYLE
+        "com.sun.star.style.FrameStyle",        //SW_SERVICE_STYLE_FRAME_STYLE
+        "com.sun.star.style.PageStyle",             //SW_SERVICE_STYLE_PAGE_STYLE
+        "com.sun.star.style.NumberingStyle",    //SW_SERVICE_STYLE_NUMBERING_STYLE
+        "com.sun.star.text.ContentIndexMark",//SW_SERVICE_CONTENT_INDEX_MARK
+        "com.sun.star.text.ContentIndex",   //SW_SERVICE_CONTENT_INDEX
+        "com.sun.star.text.UserIndexMark",  //SW_SERVICE_USER_INDEX_MARK
+        "com.sun.star.text.UserIndex",      //SW_SERVICE_USER_INDEX
+        "com.sun.star.text.TextSection",//SW_SERVICE_TEXT_SECTION
+        "com.sun.star.text.TextField.DateTime",         //SW_SERVICE_FIELD_DATETIME
+        "com.sun.star.text.TextField.User",             //SW_SERVICE_FIELDTYPE_USER
+        "com.sun.star.text.TextField.SetExpression",        //SW_SERVICE_FIELDTYPE_SET_EXP
+        "com.sun.star.text.TextField.GetExpression",        //SW_SERVICE_FIELDTYPE_GET_EXP
+        "com.sun.star.text.TextField.FileName",         //SW_SERVICE_FIELDTYPE_FILE_NAME
+        "com.sun.star.text.TextField.PageNumber",       //SW_SERVICE_FIELDTYPE_PAGE_NUM
+        "com.sun.star.text.TextField.Author",           //SW_SERVICE_FIELDTYPE_AUTHOR
+        "com.sun.star.text.TextField.Chapter",          //SW_SERVICE_FIELDTYPE_CHAPTER
+        "", //SW_SERVICE_FIELDTYPE_DUMMY_0
+        "com.sun.star.text.TextField.GetReference",     //SW_SERVICE_FIELDTYPE_GET_REFERENCE
+        "com.sun.star.text.TextField.ConditionalText",  //SW_SERVICE_FIELDTYPE_CONDITIONED_TEXT
+        "com.sun.star.text.TextField.Annotation",       //SW_SERVICE_FIELDTYPE_ANNOTATION
+        "com.sun.star.text.TextField.Input",                    //SW_SERVICE_FIELDTYPE_INPUT
+        "com.sun.star.text.TextField.Macro",                    //SW_SERVICE_FIELDTYPE_MACRO
+#ifdef DDE_AVAILABLE
+        "com.sun.star.text.TextField.DDE",              //SW_SERVICE_FIELDTYPE_DDE
+#else
+        "",             //SW_SERVICE_FIELDTYPE_DDE
+#endif
+        "com.sun.star.text.TextField.HiddenParagraph",  //SW_SERVICE_FIELDTYPE_HIDDEN_PARA
+        "",//com.sun.star.text.TextField.DocumentInfo",     //SW_SERVICE_FIELDTYPE_DOC_INFO
+        "com.sun.star.text.TextField.TemplateName",     //SW_SERVICE_FIELDTYPE_TEMPLATE_NAME
+        "com.sun.star.text.TextField.ExtendedUser",     //SW_SERVICE_FIELDTYPE_USER_EXT
+        "com.sun.star.text.TextField.ReferencePageSet", //SW_SERVICE_FIELDTYPE_REF_PAGE_SET
+        "com.sun.star.text.TextField.ReferencePageGet", //SW_SERVICE_FIELDTYPE_REF_PAGE_GET
+        "com.sun.star.text.TextField.JumpEdit",         //SW_SERVICE_FIELDTYPE_JUMP_EDIT
+        "com.sun.star.text.TextField.Script",           //SW_SERVICE_FIELDTYPE_SCRIPT
+        "com.sun.star.text.TextField.DatabaseNextSet",  //SW_SERVICE_FIELDTYPE_DATABASE_NEXT_SET
+        "com.sun.star.text.TextField.DatabaseNumberOfSet",//SW_SERVICE_FIELDTYPE_DATABASE_NUM_SET
+        "com.sun.star.text.TextField.DatabaseSetNumber",    //SW_SERVICE_FIELDTYPE_DATABASE_SET_NUM
+        "com.sun.star.text.TextField.Database",         //SW_SERVICE_FIELDTYPE_DATABASE
+        "com.sun.star.text.TextField.DatabaseName",     //SW_SERVICE_FIELDTYPE_DATABASE_NAME
+        "",     //SW_SERVICE_FIELDTYPE_TABLEFIELD
+        "com.sun.star.text.TextField.PageCount",            //SW_SERVICE_FIELDTYPE_PAGE_COUNT
+        "com.sun.star.text.TextField.ParagraphCount",   //SW_SERVICE_FIELDTYPE_PARAGRAPH_COUNT
+        "com.sun.star.text.TextField.WordCount",            //SW_SERVICE_FIELDTYPE_WORD_COUNT
+        "com.sun.star.text.TextField.CharacterCount",   //SW_SERVICE_FIELDTYPE_CHARACTER_COUNT
+        "com.sun.star.text.TextField.TableCount",       //SW_SERVICE_FIELDTYPE_TABLE_COUNT
+        "com.sun.star.text.TextField.GraphicObjectCount",//SW_SERVICE_FIELDTYPE_GRAPHIC_OBJECT_COUNT
+        "com.sun.star.text.TextField.EmbeddedObjectCount",  //SW_SERVICE_FIELDTYPE_EMBEDDED_OBJECT_COUNT
+        "com.sun.star.text.TextField.DocInfo.ChangeAuthor", //SW_SERVICE_FIELDTYPE_DOCINFO_CHANGE_AUTHOR
+        "com.sun.star.text.TextField.DocInfo.ChangeDateTime",   //SW_SERVICE_FIELDTYPE_DOCINFO_CHANGE_DATE_TIME
+        "com.sun.star.text.TextField.DocInfo.EditTime",     //SW_SERVICE_FIELDTYPE_DOCINFO_EDIT_TIME
+        "com.sun.star.text.TextField.DocInfo.Description",  //SW_SERVICE_FIELDTYPE_DOCINFO_DESCRIPTION
+        "com.sun.star.text.TextField.DocInfo.CreateAuthor", //SW_SERVICE_FIELDTYPE_DOCINFO_CREATE_AUTHOR
+        "com.sun.star.text.TextField.DocInfo.CreateDateTime",//SW_SERVICE_FIELDTYPE_DOCINFO_CREATE_DATE_TIME
+        "com.sun.star.text.TextField.DocInfo.Info0",            //SW_SERVICE_FIELDTYPE_DOCINFO_INFO_0
+        "com.sun.star.text.TextField.DocInfo.Info1",            //SW_SERVICE_FIELDTYPE_DOCINFO_INFO_1
+        "com.sun.star.text.TextField.DocInfo.Info2",            //SW_SERVICE_FIELDTYPE_DOCINFO_INFO_2
+        "com.sun.star.text.TextField.DocInfo.Info3",            //SW_SERVICE_FIELDTYPE_DOCINFO_INFO_3
+        "com.sun.star.text.TextField.DocInfo.PrintAuthor",  //SW_SERVICE_FIELDTYPE_DOCINFO_PRINT_AUTHOR
+        "com.sun.star.text.TextField.DocInfo.PrintDateTime",    //SW_SERVICE_FIELDTYPE_DOCINFO_PRINT_DATE_TIME
+        "com.sun.star.text.TextField.DocInfo.KeyWords",     //SW_SERVICE_FIELDTYPE_DOCINFO_KEY_WORDS
+        "com.sun.star.text.TextField.DocInfo.Subject",      //SW_SERVICE_FIELDTYPE_DOCINFO_SUBJECT
+        "com.sun.star.text.TextField.DocInfo.Title",            //SW_SERVICE_FIELDTYPE_DOCINFO_TITLE
+        "com.sun.star.text.TextField.DocInfo.Revision",     //SW_SERVICE_FIELDTYPE_DOCINFO_REVISION
+        "",//SW_SERVICE_FIELDTYPE_DUMMY_1
+        "",//SW_SERVICE_FIELDTYPE_DUMMY_2
+        "",//SW_SERVICE_FIELDTYPE_DUMMY_3
+        "",//SW_SERVICE_FIELDTYPE_DUMMY_4
+        "",//SW_SERVICE_FIELDTYPE_DUMMY_5
+        "",//SW_SERVICE_FIELDTYPE_DUMMY_6
+        "",//SW_SERVICE_FIELDTYPE_DUMMY_7
+        "",//SW_SERVICE_FIELDTYPE_DUMMY_8
+        "com.sun.star.text.FieldMaster.User",//SW_SERVICE_FIELDMASTER_USER
+        "com.sun.star.text.FieldMaster.DDE",//SW_SERVICE_FIELDMASTER_DDE
+        "com.sun.star.text.FieldMaster.SetExpression",//SW_SERVICE_FIELDMASTER_SET_EXP
+        "com.sun.star.text.FieldMaster.Database",//SW_SERVICE_FIELDMASTER_DATABASE
+        "",//SW_SERVICE_FIELDMASTER_DUMMY1
+        "",//SW_SERVICE_FIELDMASTER_DUMMY2
+        "",//SW_SERVICE_FIELDMASTER_DUMMY3
+        "",//SW_SERVICE_FIELDMASTER_DUMMY4
+        "",//SW_SERVICE_FIELDMASTER_DUMMY5
+        "com.sun.star.text.IllustrationsIndex",//SW_SERVICE_INDEX_ILLUSTRATIONS
+        "com.sun.star.text.ObjectIndex",//SW_SERVICE_INDEX_OBJECTS
+        "com.sun.star.text.TableIndex",//SW_SERVICE_INDEX_TABLES
+        "com.sun.star.text.Bibliography",//SW_SERVICE_INDEX_BIBLIOGRAPHY
+        "com.sun.star.text.Paragraph",//SW_SERVICE_PARAGRAPH
+        "com.sun.star.text.TextField.InputUser",                    //SW_SERVICE_FIELDTYPE_INPUT_USER
+        "com.sun.star.text.TextField.HiddenText", //SW_SERVICE_FIELDTYPE_HIDDEN_TEXT
+        "com.sun.star.style.ConditionalParagraphStyle", //SW_SERVICE_STYLE_CONDITIONAL_PARAGRAPH_STYLE
+        "com.sun.star.text.NumberingRules"              //SW_SERVICE_NUMBERING_RULES
+    };
+/******************************************************************
+ * SwXServiceProvider
+ ******************************************************************/
+/*-- 13.01.99 13:31:44---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+OUString    SwXServiceProvider::GetProviderName(sal_uInt16 nObjectType)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    OUString sRet;
+    if(nObjectType <= SW_SERVICE_LAST)
+        sRet = C2U(aProvNames[nObjectType]);
+    return sRet;
+}
+/* -----------------11.03.99 12:05-------------------
+ *
+ * --------------------------------------------------*/
+uno::Sequence     SwXServiceProvider::GetAllServiceNames()
+{
+    uno::Sequence aRet(SW_SERVICE_LAST + 1);
+    OUString* pArray = aRet.getArray();
+    sal_uInt16 n = 0;
+    for(sal_uInt16 i = 0; i <= SW_SERVICE_LAST; i++)
+    {
+        String sProv(C2U(aProvNames[i]));
+        if(sProv.Len())
+        {
+            pArray[n] = sProv;
+            n++;
+        }
+    }
+    aRet.realloc(n);
+    return aRet;
+
+}
+
+/*-- 13.01.99 13:31:45---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_uInt16  SwXServiceProvider::GetProviderType(const OUString& rServiceName)
+{
+    for(sal_uInt16 i = 0; i <= SW_SERVICE_LAST; i++ )
+    {
+        if( COMPARE_EQUAL == rServiceName.compareToAscii(aProvNames[i]))
+            return i;
+    }
+    return SW_SERVICE_INVALID;
+}
+/* -----------------13.01.99 14:37-------------------
+ *
+ * --------------------------------------------------*/
+uno::Reference< uno::XInterface >   SwXServiceProvider::MakeInstance(sal_uInt16 nObjectType, SwDoc* pDoc)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< uno::XInterface >  xRet;
+    switch(nObjectType)
+    {
+        case  SW_SERVICE_TYPE_TEXTTABLE:
+        {
+            SwXTextTable* pTextTable = new SwXTextTable();
+            xRet =  (cppu::OWeakObject*)pTextTable;
+        }
+        break;
+        case  SW_SERVICE_TYPE_TEXTFRAME:
+        {
+            SwXTextFrame* pTextFrame = new SwXTextFrame();
+            xRet =  (cppu::OWeakObject*)(SwXFrame*)pTextFrame;
+        }
+        break;
+        case  SW_SERVICE_TYPE_GRAPHIC  :
+        {
+            SwXTextGraphicObject* pGraphic = new SwXTextGraphicObject();
+            xRet =  (cppu::OWeakObject*)(SwXFrame*)pGraphic;
+
+        }
+        break;
+        case  SW_SERVICE_TYPE_OLE      :
+        {
+            SwXTextEmbeddedObject* pOle = new SwXTextEmbeddedObject();
+            xRet =  (cppu::OWeakObject*)(SwXFrame*)pOle;
+        }
+        break;
+        case  SW_SERVICE_TYPE_BOOKMARK :
+        {
+            SwXBookmark* pBookmark = new SwXBookmark;
+            xRet =  (cppu::OWeakObject*)pBookmark;
+        }
+        break;
+        case  SW_SERVICE_TYPE_FOOTNOTE :
+            xRet =  (cppu::OWeakObject*)new SwXFootnote(sal_False);
+        break;
+        case  SW_SERVICE_TYPE_ENDNOTE  :
+            xRet =  (cppu::OWeakObject*)new SwXFootnote(sal_True);
+        break;
+        case  SW_SERVICE_CONTENT_INDEX_MARK :
+        case  SW_SERVICE_USER_INDEX_MARK    :
+        case  SW_SERVICE_TYPE_INDEXMARK:
+        {
+            TOXTypes eType = TOX_INDEX;
+            if(SW_SERVICE_CONTENT_INDEX_MARK== nObjectType)
+                eType = TOX_CONTENT;
+            else if(SW_SERVICE_USER_INDEX_MARK == nObjectType)
+                eType = TOX_USER;
+            xRet =  (cppu::OWeakObject*)new SwXDocumentIndexMark(eType);
+        }
+        break;
+        case  SW_SERVICE_CONTENT_INDEX      :
+        case  SW_SERVICE_USER_INDEX         :
+        case  SW_SERVICE_TYPE_INDEX    :
+        case SW_SERVICE_INDEX_ILLUSTRATIONS:
+        case SW_SERVICE_INDEX_OBJECTS      :
+        case SW_SERVICE_INDEX_TABLES:
+        case SW_SERVICE_INDEX_BIBLIOGRAPHY :
+        {
+            TOXTypes eType = TOX_INDEX;
+            if(SW_SERVICE_CONTENT_INDEX == nObjectType)
+                eType = TOX_CONTENT;
+            else if(SW_SERVICE_USER_INDEX == nObjectType)
+                eType = TOX_USER;
+            else if(SW_SERVICE_INDEX_ILLUSTRATIONS == nObjectType)
+            {
+                eType = TOX_ILLUSTRATIONS;
+            }
+            else if(SW_SERVICE_INDEX_OBJECTS       == nObjectType)
+            {
+                eType = TOX_OBJECTS;
+            }
+            else if(SW_SERVICE_INDEX_BIBLIOGRAPHY  == nObjectType)
+            {
+                eType = TOX_AUTHORITIES;
+            }
+            else if(SW_SERVICE_INDEX_TABLES == nObjectType)
+            {
+                eType = TOX_TABLES;
+            }
+            xRet =  (cppu::OWeakObject*)new SwXDocumentIndex(eType, *pDoc);
+        }
+        break;
+        case SW_SERVICE_TEXT_SECTION :
+            xRet = (cppu::OWeakObject*)new SwXTextSection();
+
+        break;
+        case SW_SERVICE_REFERENCE_MARK :
+            xRet =  (cppu::OWeakObject*)new SwXReferenceMark(0, 0);
+        break;
+        case SW_SERVICE_STYLE_CHARACTER_STYLE:
+        case SW_SERVICE_STYLE_PARAGRAPH_STYLE:
+        case SW_SERVICE_STYLE_CONDITIONAL_PARAGRAPH_STYLE:
+        case SW_SERVICE_STYLE_FRAME_STYLE:
+        case SW_SERVICE_STYLE_PAGE_STYLE:
+        case SW_SERVICE_STYLE_NUMBERING_STYLE:
+        {
+            SfxStyleFamily  eFamily = SFX_STYLE_FAMILY_CHAR;
+            switch(nObjectType)
+            {
+                case SW_SERVICE_STYLE_PARAGRAPH_STYLE:
+                case SW_SERVICE_STYLE_CONDITIONAL_PARAGRAPH_STYLE:
+                    eFamily = SFX_STYLE_FAMILY_PARA;
+                break;
+                case SW_SERVICE_STYLE_FRAME_STYLE:
+                    eFamily = SFX_STYLE_FAMILY_FRAME;
+                break;
+                case SW_SERVICE_STYLE_PAGE_STYLE:
+                    eFamily = SFX_STYLE_FAMILY_PAGE;
+                break;
+                case SW_SERVICE_STYLE_NUMBERING_STYLE:
+                    eFamily = SFX_STYLE_FAMILY_PSEUDO;
+                break;
+            }
+            SwXStyle* pNewStyle = SFX_STYLE_FAMILY_PAGE == eFamily ?
+                new SwXPageStyle(pDoc->GetDocShell()) :
+                new SwXStyle(eFamily, nObjectType == SW_SERVICE_STYLE_CONDITIONAL_PARAGRAPH_STYLE);
+            xRet = (cppu::OWeakObject*)pNewStyle;
+        }
+        break;
+//      SW_SERVICE_DUMMY_5
+//      SW_SERVICE_DUMMY_6
+//      SW_SERVICE_DUMMY_7
+//      SW_SERVICE_DUMMY_8
+//      SW_SERVICE_DUMMY_9
+        case SW_SERVICE_FIELDTYPE_DATETIME:
+        case SW_SERVICE_FIELDTYPE_USER:
+        case SW_SERVICE_FIELDTYPE_SET_EXP:
+        case SW_SERVICE_FIELDTYPE_GET_EXP:
+        case SW_SERVICE_FIELDTYPE_FILE_NAME:
+        case SW_SERVICE_FIELDTYPE_PAGE_NUM:
+        case SW_SERVICE_FIELDTYPE_AUTHOR:
+        case SW_SERVICE_FIELDTYPE_CHAPTER:
+        case SW_SERVICE_FIELDTYPE_GET_REFERENCE:
+        case SW_SERVICE_FIELDTYPE_CONDITIONED_TEXT:
+        case SW_SERVICE_FIELDTYPE_ANNOTATION:
+        case SW_SERVICE_FIELDTYPE_INPUT:
+        case SW_SERVICE_FIELDTYPE_MACRO:
+        case SW_SERVICE_FIELDTYPE_DDE:
+        case SW_SERVICE_FIELDTYPE_HIDDEN_PARA:
+        case SW_SERVICE_FIELDTYPE_DOC_INFO:
+        case SW_SERVICE_FIELDTYPE_TEMPLATE_NAME:
+        case SW_SERVICE_FIELDTYPE_USER_EXT:
+        case SW_SERVICE_FIELDTYPE_REF_PAGE_SET:
+        case SW_SERVICE_FIELDTYPE_REF_PAGE_GET:
+        case SW_SERVICE_FIELDTYPE_JUMP_EDIT:
+        case SW_SERVICE_FIELDTYPE_SCRIPT:
+        case SW_SERVICE_FIELDTYPE_DATABASE_NEXT_SET:
+        case SW_SERVICE_FIELDTYPE_DATABASE_NUM_SET:
+        case SW_SERVICE_FIELDTYPE_DATABASE_SET_NUM:
+        case SW_SERVICE_FIELDTYPE_DATABASE:
+        case SW_SERVICE_FIELDTYPE_DATABASE_NAME:
+        case SW_SERVICE_FIELDTYPE_PAGE_COUNT      :
+        case SW_SERVICE_FIELDTYPE_PARAGRAPH_COUNT :
+        case SW_SERVICE_FIELDTYPE_WORD_COUNT      :
+        case SW_SERVICE_FIELDTYPE_CHARACTER_COUNT :
+        case SW_SERVICE_FIELDTYPE_TABLE_COUNT     :
+        case SW_SERVICE_FIELDTYPE_GRAPHIC_OBJECT_COUNT    :
+        case SW_SERVICE_FIELDTYPE_EMBEDDED_OBJECT_COUNT   :
+        case SW_SERVICE_FIELDTYPE_DOCINFO_CHANGE_AUTHOR     :
+        case SW_SERVICE_FIELDTYPE_DOCINFO_CHANGE_DATE_TIME  :
+        case SW_SERVICE_FIELDTYPE_DOCINFO_EDIT_TIME         :
+        case SW_SERVICE_FIELDTYPE_DOCINFO_DESCRIPTION       :
+        case SW_SERVICE_FIELDTYPE_DOCINFO_CREATE_AUTHOR     :
+        case SW_SERVICE_FIELDTYPE_DOCINFO_CREATE_DATE_TIME  :
+        case SW_SERVICE_FIELDTYPE_DOCINFO_INFO_0            :
+        case SW_SERVICE_FIELDTYPE_DOCINFO_INFO_1            :
+        case SW_SERVICE_FIELDTYPE_DOCINFO_INFO_2            :
+        case SW_SERVICE_FIELDTYPE_DOCINFO_INFO_3            :
+        case SW_SERVICE_FIELDTYPE_DOCINFO_PRINT_AUTHOR      :
+        case SW_SERVICE_FIELDTYPE_DOCINFO_PRINT_DATE_TIME   :
+        case SW_SERVICE_FIELDTYPE_DOCINFO_KEY_WORDS         :
+        case SW_SERVICE_FIELDTYPE_DOCINFO_SUBJECT           :
+        case SW_SERVICE_FIELDTYPE_DOCINFO_TITLE             :
+        case SW_SERVICE_FIELDTYPE_DOCINFO_REVISION          :
+        case SW_SERVICE_FIELDTYPE_INPUT_USER                :
+        case SW_SERVICE_FIELDTYPE_HIDDEN_TEXT               :
+            xRet =  (cppu::OWeakObject*)new SwXTextField(nObjectType);
+        break;
+        case SW_SERVICE_FIELDMASTER_USER:
+        case SW_SERVICE_FIELDMASTER_DDE:
+        case SW_SERVICE_FIELDMASTER_SET_EXP :
+        case SW_SERVICE_FIELDMASTER_DATABASE:
+        {
+            sal_uInt16 nResId = USHRT_MAX;
+            switch(nObjectType)
+            {
+                case SW_SERVICE_FIELDMASTER_USER: nResId = RES_USERFLD; break;
+                case SW_SERVICE_FIELDMASTER_DDE:  nResId = RES_DDEFLD; break;
+                case SW_SERVICE_FIELDMASTER_SET_EXP : nResId = RES_SETEXPFLD; break;
+                case SW_SERVICE_FIELDMASTER_DATABASE: nResId = RES_DBFLD; break;
+            }
+            xRet =  (cppu::OWeakObject*)new SwXFieldMaster(pDoc, nResId);
+        }
+        break;
+        case SW_SERVICE_PARAGRAPH :
+            xRet = (cppu::OWeakObject*)new SwXParagraph();
+        break;
+        case SW_SERVICE_NUMBERING_RULES :
+            xRet = (cppu::OWeakObject*)new SwXNumberingRules(*pDoc);
+        break;
+//      case SW_SERVICE_FIELDTYPE_TABLEFIELD:
+        default:
+            throw uno::RuntimeException();
+    }
+    return xRet;
+}
+/******************************************************************
+ * SwXTextTables
+ ******************************************************************/
+//SMART_UNO_IMPLEMENTATION( SwXTextTables, UsrObject );
+
+/*-- 13.01.99 12:56:24---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextTables::SwXTextTables(SwDoc* pDc) :
+        SwUnoCollection(pDc)
+{
+
+}
+/*-- 13.01.99 12:56:25---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextTables::~SwXTextTables()
+{
+
+}
+/*-- 13.01.99 12:56:25---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Int32 SwXTextTables::getCount(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Int32 nRet = 0;
+    if(IsValid())
+        nRet = GetDoc()->GetTblFrmFmtCount(sal_True);
+    return nRet;
+}
+/*-- 13.01.99 12:56:26---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SAL_CALL SwXTextTables::getByIndex(sal_Int32 nIndex)
+        throw( IndexOutOfBoundsException, WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Any aRet;
+    if(IsValid())
+    {
+        if(GetDoc()->GetTblFrmFmtCount(sal_True) > nIndex)
+        {
+            SwFrmFmt& rFmt = GetDoc()->GetTblFrmFmt( nIndex, sal_True);
+            uno::Reference< XTextTable >  xTbl = SwXTextTables::GetObject(rFmt);
+            aRet.setValue( &xTbl,
+                ::getCppuType((uno::Reference< XTextTable>*)0));
+        }
+        else
+            throw IndexOutOfBoundsException();
+    }
+    else
+        throw uno::RuntimeException();
+    return aRet;
+}
+/*-- 13.01.99 12:56:26---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXTextTables::getByName(const OUString& rItemName)
+    throw( NoSuchElementException, WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Any aRet;
+    if(IsValid())
+    {
+        sal_uInt16 nCount = GetDoc()->GetTblFrmFmtCount(sal_True);
+        uno::Reference< XTextTable >  xTbl;
+        for( sal_uInt16 i = 0; i < nCount; i++)
+        {
+            String aName(rItemName);
+            SwFrmFmt& rFmt = GetDoc()->GetTblFrmFmt(i, sal_True);
+            if(aName == rFmt.GetName())
+            {
+                xTbl = SwXTextTables::GetObject(rFmt);
+                aRet.setValue(&xTbl,
+                    ::getCppuType(( uno::Reference< XTextTable >*)0));
+                break;
+            }
+        }
+        if(!xTbl.is())
+            throw NoSuchElementException();
+    }
+    else
+        throw uno::RuntimeException();
+    return aRet;
+}
+/*-- 13.01.99 12:56:26---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Sequence< OUString > SwXTextTables::getElementNames(void)
+        throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!IsValid())
+        throw uno::RuntimeException();
+    sal_uInt16 nCount = GetDoc()->GetTblFrmFmtCount(sal_True);
+    uno::Sequence aSeq(nCount);
+    if(nCount)
+    {
+        OUString* pArray = aSeq.getArray();
+        for( sal_uInt16 i = 0; i < nCount; i++)
+        {
+            SwFrmFmt& rFmt = GetDoc()->GetTblFrmFmt(i, sal_True);
+
+            pArray[i] = OUString(rFmt.GetName());
+        }
+    }
+    return aSeq;
+}
+/*-- 13.01.99 12:56:27---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextTables::hasByName(const OUString& rName)
+    throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Bool bRet= sal_False;
+    if(IsValid())
+    {
+        sal_uInt16 nCount = GetDoc()->GetTblFrmFmtCount(sal_True);
+        for( sal_uInt16 i = 0; i < nCount; i++)
+        {
+            String aName(rName);
+            SwFrmFmt& rFmt = GetDoc()->GetTblFrmFmt(i, sal_True);
+            if(aName == rFmt.GetName())
+            {
+                bRet = sal_True;
+                break;
+            }
+        }
+    }
+    else
+        throw uno::RuntimeException();
+    return bRet;
+}
+/*-- 13.01.99 12:56:27---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Type SAL_CALL
+    SwXTextTables::getElementType(  )
+        throw(uno::RuntimeException)
+{
+    return ::getCppuType((uno::Reference*)0);
+}
+/*-- 13.01.99 12:56:27---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextTables::hasElements(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!IsValid())
+        throw uno::RuntimeException();
+    return 0 != GetDoc()->GetTblFrmFmtCount(sal_True);
+}
+/* -----------------25.10.99 16:01-------------------
+
+ --------------------------------------------------*/
+OUString SwXTextTables::getImplementationName(void) throw( uno::RuntimeException )
+{
+    return C2U("SwXTextTables");
+}
+/* -----------------25.10.99 16:01-------------------
+
+ --------------------------------------------------*/
+sal_Bool SwXTextTables::supportsService(const OUString& rServiceName) throw( uno::RuntimeException )
+{
+    return rServiceName == C2U("com.sun.star.text.TextTables");
+}
+/* -----------------25.10.99 16:01-------------------
+
+ --------------------------------------------------*/
+uno::Sequence< OUString > SwXTextTables::getSupportedServiceNames(void) throw( uno::RuntimeException )
+{
+    uno::Sequence< OUString > aRet(1);
+    OUString* pArr = aRet.getArray();
+    pArr[0] = C2U("com.sun.star.text.TextTables");
+    return aRet;
+}
+/*-- 13.01.99 12:56:28---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+XTextTable* SwXTextTables::GetObject( SwFrmFmt& rFmt )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwXTextTable* pTbl = (SwXTextTable*)SwClientIter( rFmt ).
+                                    First( TYPE( SwXTextTable ));
+    if( !pTbl )
+        pTbl = new SwXTextTable(rFmt);
+    return pTbl ;
+}
+/******************************************************************
+ *  SwXFrames
+ ******************************************************************/
+/* -----------------------------06.04.00 12:41--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXFrames::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXFrames");
+}
+/* -----------------------------06.04.00 12:41--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXFrames::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.text.TextFrames") == rServiceName;
+}
+/* -----------------------------06.04.00 12:41--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXFrames::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.TextFrames");
+    return aRet;
+}
+
+/*-- 14.01.99 08:20:18---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXFrames::SwXFrames(SwDoc* pDoc, FlyCntType eSet) :
+    SwUnoCollection(pDoc),
+    eType(eSet)
+{
+}
+
+/*-- 14.01.99 08:20:18---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXFrames::~SwXFrames()
+{
+}
+
+/*-- 14.01.99 08:25:47---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Int32 SwXFrames::getCount(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_uInt16 nRet = 0;
+    if(IsValid())
+        nRet = GetDoc()->GetFlyCount(eType);
+    else
+        throw uno::RuntimeException();
+    return nRet;
+}
+/*-- 14.01.99 08:25:47---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXFrames::getByIndex(sal_Int32 nIndex)
+    throw( IndexOutOfBoundsException, WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Any aRet;
+    if(IsValid())
+    {
+        sal_uInt16 nCount = GetDoc()->GetFlyCount(eType);
+        if( nIndex < USHRT_MAX && nCount > nIndex)
+        {
+            SwFrmFmt* pFmt = GetDoc()->GetFlyNum((sal_uInt16) nIndex, eType);
+            SwXFrame* pFrm = SwXFrames::GetObject(*pFmt, eType);
+            switch(eType)
+            {
+                case FLYCNTTYPE_FRM:
+                {
+                    uno::Reference< XTextFrame >  xRef = (SwXTextFrame*)pFrm;
+                    aRet.setValue(&xRef, ::getCppuType((uno::Reference*)0));
+                }
+                break;
+                case FLYCNTTYPE_GRF:
+                {
+                    Reference< XTextContent >  xRef = (SwXTextGraphicObject*)pFrm;
+                    aRet.setValue(&xRef, ::getCppuType((uno::Reference*)0));
+                }
+                break;
+                case FLYCNTTYPE_OLE:
+                {
+                    uno::Reference< XTextEmbeddedObject >  xRef = (SwXTextEmbeddedObject*)pFrm;
+                    aRet.setValue(&xRef, ::getCppuType((uno::Reference*)0));
+                }
+                break;
+            }
+        }
+        else
+            throw IndexOutOfBoundsException();
+    }
+    else
+        throw uno::RuntimeException();
+    return aRet;
+}
+/*-- 14.01.99 08:25:47---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXFrames::getByName(const OUString& rName)
+    throw( NoSuchElementException, WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwXFrame* pFrm = 0;
+    if(IsValid())
+    {
+        sal_uInt16 nCount = GetDoc()->GetFlyCount(eType);
+        for( sal_uInt16 i = 0; i < nCount; i++)
+        {
+            String aName(rName);
+            SwFrmFmt* pFmt = GetDoc()->GetFlyNum(i, eType);
+            if(aName == pFmt->GetName() )
+            {
+                pFrm = SwXFrames::GetObject(*pFmt, eType);
+                break;
+            }
+        }
+    }
+    else
+        throw uno::RuntimeException();
+    if(!pFrm)
+        throw NoSuchElementException();
+    uno::Any aRet;
+    switch(eType)
+    {
+        case FLYCNTTYPE_FRM:
+        {
+            uno::Reference< XTextFrame >  xRef = (SwXTextFrame*)pFrm;
+            aRet.setValue(&xRef, ::getCppuType((uno::Reference*)0));
+        }
+        break;
+        case FLYCNTTYPE_GRF:
+        {
+            uno::Reference< XTextContent >  xRef = (SwXTextGraphicObject*)pFrm;
+            aRet.setValue(&xRef, ::getCppuType((uno::Reference*)0));
+        }
+        break;
+        case FLYCNTTYPE_OLE:
+        {
+            uno::Reference< XTextEmbeddedObject >  xRef = (SwXTextEmbeddedObject*)pFrm;
+            aRet.setValue(&xRef, ::getCppuType((uno::Reference*)0));
+        }
+        break;
+    }
+    return aRet;
+}
+/*-- 14.01.99 08:25:48---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Sequence< OUString > SwXFrames::getElementNames(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!IsValid())
+        throw uno::RuntimeException();
+    sal_uInt16 nCount = IsValid() ? GetDoc()->GetFlyCount(eType) : 0;
+    uno::Sequence aSeq(nCount);
+    if(nCount)
+    {
+        OUString* pArray = aSeq.getArray();
+        for( sal_uInt16 i = 0; i < nCount; i++)
+        {
+            SwFrmFmt* pFmt = GetDoc()->GetFlyNum(i, eType);
+            pArray[i] = pFmt->GetName();
+        }
+    }
+    return aSeq;
+}
+/*-- 14.01.99 08:25:48---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXFrames::hasByName(const OUString& rName) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!IsValid())
+        throw uno::RuntimeException();
+        sal_uInt16 nCount = GetDoc()->GetFlyCount(eType);
+    sal_Bool bRet = sal_False;
+    for( sal_uInt16 i = 0; i < nCount; i++)
+    {
+        String aName(rName);
+        SwFrmFmt* pFmt = GetDoc()->GetFlyNum(i, eType);
+        if(aName == pFmt->GetName() )
+        {
+            bRet = sal_True;
+            break;
+        }
+    }
+    return bRet;
+}
+/*-- 14.01.99 08:25:48---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Type SAL_CALL SwXFrames::getElementType() throw(uno::RuntimeException)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Type aRet;
+    switch(eType)
+    {
+        case FLYCNTTYPE_FRM:
+            aRet = ::getCppuType((uno::Reference*)0);
+
+        break;
+        case FLYCNTTYPE_GRF:
+            aRet = ::getCppuType((uno::Reference*)0);
+
+        break;
+        case FLYCNTTYPE_OLE:
+            aRet = ::getCppuType((uno::Reference*)0);
+        break;
+    }
+    return aRet;
+}
+/*-- 14.01.99 08:25:48---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXFrames::hasElements(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_uInt16 nRet = 0;
+    if(IsValid())
+        nRet = GetDoc()->GetFlyCount(eType);
+    else
+        throw uno::RuntimeException();
+    return nRet != 0;
+}
+/*-- 14.01.99 08:25:48---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXFrame*   SwXFrames::GetObject( SwFrmFmt& rFmt, FlyCntType eType )
+{
+    SwXFrame* pFrm = (SwXFrame*)SwClientIter( rFmt ).
+                                    First( TYPE( SwXFrame ));
+    if( !pFrm )
+    {
+        switch(eType)
+        {
+            case FLYCNTTYPE_FRM:
+                pFrm = new SwXTextFrame(rFmt);
+            break;
+            case FLYCNTTYPE_GRF:
+                pFrm = new SwXTextGraphicObject(rFmt);
+            break;
+            case FLYCNTTYPE_OLE:
+                pFrm = new SwXTextEmbeddedObject(rFmt);
+            break;
+        }
+    }
+    return pFrm;
+}
+/*-- 14.01.99 08:25:49---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXFrame*   SwXFrames::GetFrmByName( const String& rName )
+{
+    SwXFrame* pFrm = 0;
+    if(IsValid())
+    {
+        sal_uInt16 nCount = GetDoc()->GetFlyCount(eType);
+        for( sal_uInt16 i = 0; i < nCount; i++)
+        {
+            SwFrmFmt* pFmt = GetDoc()->GetFlyNum(i, eType);
+            if(rName == pFmt->GetName())
+                pFrm = SwXFrames::GetObject(*pFmt, eType);
+        }
+    }
+    return pFrm;
+}
+/*-- 14.01.99 08:25:49---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXFrame*   SwXFrames::GetFrmByIndex( sal_Int32 nIndex )
+{
+    SwXFrame* pFrm = 0;
+    if(IsValid())
+    {
+        sal_uInt16 nCount = GetDoc()->GetFlyCount(GetType());
+        if((sal_Int32)nCount > nIndex)
+        {
+            SwFrmFmt* pFmt = GetDoc()->GetFlyNum((sal_uInt16)nIndex, GetType());
+            pFrm = SwXFrames::GetObject(*pFmt, eType);
+        }
+    }
+    return pFrm;
+}
+/*-- 14.01.99 08:25:49---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFrames::RemoveFrame(const OUString& rName, FlyCntType eType)
+{
+    if(IsValid())
+    {
+        String sName(rName);
+        sal_uInt16 nCount = GetDoc()->GetFlyCount(eType);
+        for( sal_uInt16 i = 0; i < nCount; i++)
+        {
+            SwFrmFmt* pFrmFmt = GetDoc()->GetFlyNum(i, eType);
+            if(sName == pFrmFmt->GetName())
+            {
+                if( pFrmFmt->GetAnchor().GetAnchorId() == FLY_IN_CNTNT )
+                {
+                    const SwPosition &rPos = *(pFrmFmt->GetAnchor().GetCntntAnchor());
+                    SwTxtNode *pTxtNode = rPos.nNode.GetNode().GetTxtNode();
+                    const xub_StrLen nIdx = rPos.nContent.GetIndex();
+                    pTxtNode->Delete( RES_TXTATR_FLYCNT, nIdx, nIdx );
+                }
+                else
+                    GetDoc()->DelLayoutFmt(pFrmFmt);
+                break;
+            }
+        }
+    }
+}
+/******************************************************************
+ * SwXTextFrames
+ ******************************************************************/
+/* -----------------------------06.04.00 12:44--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXTextFrames::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXTextFrames");
+}
+/* -----------------------------06.04.00 12:44--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXTextFrames::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.text.TextFrames") == rServiceName;
+}
+/* -----------------------------06.04.00 12:44--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXTextFrames::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.TextFrames");
+    return aRet;
+}
+/*-- 14.01.99 08:06:16---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextFrames::SwXTextFrames(SwDoc* pDoc) :
+    SwXFrames(pDoc, FLYCNTTYPE_FRM)
+{
+}
+/*-- 14.01.99 08:06:17---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextFrames::~SwXTextFrames()
+{
+}
+
+/******************************************************************
+ *  SwXTextGraphicObjects
+ ******************************************************************/
+//SMART_UNO_IMPLEMENTATION( SwXTextGraphicObjects, UsrObject );
+
+/* -----------------------------06.04.00 12:44--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXTextGraphicObjects::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXTextGraphicObjects");
+}
+/* -----------------------------06.04.00 12:44--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXTextGraphicObjects::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.text.TextGraphicObjects") == rServiceName;
+}
+/* -----------------------------06.04.00 12:44--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXTextGraphicObjects::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.TextGraphicObjects");
+    return aRet;
+}
+/*-- 14.01.99 08:45:53---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextGraphicObjects::SwXTextGraphicObjects(SwDoc* pDoc) :
+    SwXFrames(pDoc, FLYCNTTYPE_GRF)
+{
+}
+/*-- 14.01.99 08:45:54---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextGraphicObjects::~SwXTextGraphicObjects()
+{
+}
+
+/******************************************************************
+ *  SwXTextEmbeddedObjects
+ ******************************************************************/
+/* -----------------------------06.04.00 12:44--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXTextEmbeddedObjects::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXTextEmbeddedObjects");
+}
+/* -----------------------------06.04.00 12:44--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXTextEmbeddedObjects::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.text.TextEmbeddedObjects") == rServiceName;
+}
+/* -----------------------------06.04.00 12:44--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXTextEmbeddedObjects::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.TextEmbeddedObjects");
+    return aRet;
+}
+/*-- 14.01.99 08:45:13---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextEmbeddedObjects::SwXTextEmbeddedObjects(SwDoc* pDoc) :
+        SwXFrames(pDoc, FLYCNTTYPE_OLE)
+{
+}
+/*-- 14.01.99 08:45:31---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextEmbeddedObjects::~SwXTextEmbeddedObjects()
+{
+}
+
+/******************************************************************
+ *
+ ******************************************************************/
+#define PASSWORD_STD_TIMEOUT 1000
+/* -----------------------------06.04.00 12:44--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXTextSections::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXTextSections");
+}
+/* -----------------------------06.04.00 12:44--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXTextSections::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.text.TextSections") == rServiceName;
+}
+/* -----------------------------06.04.00 12:44--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXTextSections::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.TextSections");
+    return aRet;
+}
+/*-- 14.01.99 09:06:05---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextSections::SwXTextSections(SwDoc* pDoc) :
+    SwUnoCollection(pDoc),
+    nWrongPasswd(0)
+{
+    aWrongPasswdTimer.SetTimeout(PASSWORD_STD_TIMEOUT);
+    aWrongPasswdTimer.SetTimeoutHdl(LINK(this, SwXTextSections, WrongPasswordTimerHdl));
+
+}
+/*-- 14.01.99 09:06:05---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextSections::~SwXTextSections()
+{
+}
+/*-- 14.01.99 09:06:05---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Int32 SwXTextSections::getCount(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!IsValid() || GetDoc()->GetSectionPasswd().Len())
+        throw uno::RuntimeException();
+    const SwSectionFmts& rSectFmts = GetDoc()->GetSections();
+    sal_uInt16 nCount = rSectFmts.Count();
+    for(sal_uInt16 i = nCount; i; i--)
+    {
+        if( !rSectFmts[i - 1]->IsInNodesArr())
+            nCount--;
+    }
+    return nCount;
+}
+/*-- 14.01.99 09:06:06---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXTextSections::getByIndex(sal_Int32 nIndex)
+    throw( IndexOutOfBoundsException, WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Any aRet;
+    if(IsValid() && !GetDoc()->GetSectionPasswd().Len())
+    {
+        SwSectionFmts& rFmts = GetDoc()->GetSections();
+
+        const SwSectionFmts& rSectFmts = GetDoc()->GetSections();
+        sal_uInt16 nCount = rSectFmts.Count();
+        for(sal_uInt16 i = 0; i < nCount; i++)
+        {
+            if( !rSectFmts[i]->IsInNodesArr())
+                nIndex ++;
+            else if(nIndex == i)
+                break;
+            if(nIndex == i)
+                break;
+        }
+        if(nIndex >= 0 && nIndex < rFmts.Count())
+        {
+            SwSectionFmt* pFmt = rFmts[(sal_uInt16)nIndex];
+            uno::Reference< XTextSection >  xSect = GetObject(*pFmt);
+            aRet.setValue(&xSect, ::getCppuType((uno::Reference*)0));
+        }
+        else
+            throw IndexOutOfBoundsException();
+    }
+    else
+        throw uno::RuntimeException();
+    return aRet;
+}
+/*-- 14.01.99 09:06:06---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXTextSections::getByName(const OUString& Name)
+    throw( NoSuchElementException, WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Any aRet;
+    if(IsValid()&& !GetDoc()->GetSectionPasswd().Len())
+    {
+        String aName(Name);
+        SwSectionFmts& rFmts = GetDoc()->GetSections();
+        uno::Reference< XTextSection >  xSect;
+        for(sal_uInt16 i = 0; i < rFmts.Count(); i++)
+        {
+            SwSectionFmt* pFmt = rFmts[i];
+            if(pFmt->IsInNodesArr() && aName == pFmt->GetSection()->GetName())
+            {
+                xSect = GetObject(*pFmt);
+                aRet.setValue(&xSect, ::getCppuType((uno::Reference*)0));
+                break;
+            }
+        }
+        if(!xSect.is())
+            throw NoSuchElementException();
+    }
+    else
+        throw uno::RuntimeException();
+    return aRet;
+}
+/*-- 14.01.99 09:06:06---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Sequence< OUString > SwXTextSections::getElementNames(void)
+    throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!IsValid() || GetDoc()->GetSectionPasswd().Len())
+        throw uno::RuntimeException();
+    sal_uInt16 nCount = GetDoc()->GetSections().Count();
+    SwSectionFmts& rSectFmts = GetDoc()->GetSections();
+    for(sal_uInt16 i = nCount; i; i--)
+    {
+        if( !rSectFmts[i - 1]->IsInNodesArr())
+            nCount--;
+    }
+
+    uno::Sequence aSeq(nCount);
+    if(nCount)
+    {
+        SwSectionFmts& rFmts = GetDoc()->GetSections();
+        OUString* pArray = aSeq.getArray();
+        sal_uInt16 nIndex = 0;
+        for( sal_uInt16 i = 0; i < nCount; i++, nIndex++)
+        {
+            const SwSectionFmt* pFmt = rFmts[nIndex];
+            while(!pFmt->IsInNodesArr())
+            {
+                pFmt = rFmts[++nIndex];
+            }
+            pArray[i] = pFmt->GetSection()->GetName();
+        }
+    }
+    return aSeq;
+}
+/*-- 14.01.99 09:06:06---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextSections::hasByName(const OUString& Name)
+    throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Bool bRet = sal_False;
+    String aName(Name);
+    if(IsValid()&& !GetDoc()->GetSectionPasswd().Len())
+    {
+        SwSectionFmts& rFmts = GetDoc()->GetSections();
+        for(sal_uInt16 i = 0; i < rFmts.Count(); i++)
+        {
+            const SwSectionFmt* pFmt = rFmts[i];
+            if(aName == pFmt->GetSection()->GetName())
+            {
+                bRet = sal_True;
+                break;
+            }
+        }
+    }
+    else
+    {
+        //Sonderbehandlung der dbg_ - Methoden
+        if( COMPARE_EQUAL != aName.CompareToAscii("dbg_", 4))
+            throw uno::RuntimeException();
+    }
+    return bRet;
+}
+/*-- 14.01.99 09:06:06---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Type SAL_CALL SwXTextSections::getElementType() throw(uno::RuntimeException)
+{
+    return ::getCppuType((uno::Reference*)0);
+}
+/*-- 14.01.99 09:06:06---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextSections::hasElements(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_uInt16 nCount = 0;
+    if(IsValid()&& !GetDoc()->GetSectionPasswd().Len())
+    {
+        SwSectionFmts& rFmts = GetDoc()->GetSections();
+        nCount = rFmts.Count();
+    }
+    else
+        throw uno::RuntimeException();
+    return nCount > 0;
+}
+/* -----------------19.04.99 09:38-------------------
+ *
+ * --------------------------------------------------*/
+void SwXTextSections::protect(const OUString& rPassword)
+                            throw( uno::RuntimeException )
+{
+    if(IsValid())
+    {
+        String sPasswdSect(GetDoc()->GetSectionPasswd());
+        if(sPasswdSect.Len())
+            throw uno::RuntimeException();
+        String sNewPasswd(rPassword);
+        GetDoc()->ChgSectionPasswd( sNewPasswd );
+    }
+    else
+        throw uno::RuntimeException();
+}
+/* -----------------19.04.99 09:38-------------------
+ *
+ * --------------------------------------------------*/
+void SwXTextSections::unprotect(const OUString& rPassword)
+                        throw( IllegalArgumentException, uno::RuntimeException )
+{
+    if(aWrongPasswdTimer.IsActive() || !IsValid())
+        throw uno::RuntimeException();
+    String sPasswdSect(GetDoc()->GetSectionPasswd());
+    String sNewPasswd(rPassword);
+    if(sPasswdSect != sNewPasswd)
+    {
+        //hier sollen noch illegale Aufrufe abgefangen werden.
+        //wird das Passwort zum vierten Mal falsch eingegeben, dann
+        //wird per Timer gebremst
+        nWrongPasswd++;
+        sal_uInt32 nTimeout = PASSWORD_STD_TIMEOUT;
+        if(nWrongPasswd > 3)
+        {
+            nTimeout *= nWrongPasswd;
+            aWrongPasswdTimer.SetTimeout(nTimeout);
+            aWrongPasswdTimer.Start();
+        }
+        throw IllegalArgumentException();
+    }
+    nWrongPasswd = 0;
+    aWrongPasswdTimer.SetTimeout(PASSWORD_STD_TIMEOUT);
+    GetDoc()->ChgSectionPasswd( aEmptyStr );
+}
+/* -----------------19.04.99 09:38-------------------
+ *
+ * --------------------------------------------------*/
+sal_Bool SwXTextSections::isProtected(void) throw( uno::RuntimeException )
+{
+    sal_Bool bRet = sal_False;
+    if(IsValid())
+    {
+        String sPasswdSect(GetDoc()->GetSectionPasswd());
+        bRet = sPasswdSect.Len() > 0;
+    }
+    else
+        throw uno::RuntimeException();
+    return bRet;
+}
+/* -----------------19.04.99 09:58-------------------
+ *
+ * --------------------------------------------------*/
+IMPL_LINK(SwXTextSections, WrongPasswordTimerHdl, Timer*, pTimer)
+{
+    if(nWrongPasswd)
+        nWrongPasswd--;
+    return 0;
+}
+/*-- 14.01.99 09:06:07---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+XTextSection*   SwXTextSections::GetObject( SwSectionFmt& rFmt )
+{
+    SwXTextSection* pSect = (SwXTextSection*)SwClientIter( rFmt ).
+                                    First( TYPE( SwXTextSection ));
+    if( !pSect )
+        pSect = new SwXTextSection(&rFmt);
+    return pSect;
+}
+/******************************************************************
+ *
+ ******************************************************************/
+/* -----------------------------06.04.00 12:44--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXBookmarks::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXBookmarks");
+}
+/* -----------------------------06.04.00 12:44--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXBookmarks::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.text.Bookmarks") == rServiceName;
+}
+/* -----------------------------06.04.00 12:44--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXBookmarks::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.Bookmarks");
+    return aRet;
+}
+/*-- 14.01.99 09:05:48---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXBookmarks::SwXBookmarks(SwDoc*   pDoc) :
+    SwUnoCollection(pDoc)
+{
+}
+/*-- 14.01.99 09:05:48---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXBookmarks::~SwXBookmarks()
+{
+}
+/*-- 14.01.99 09:05:49---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Int32 SwXBookmarks::getCount(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!IsValid())
+        throw uno::RuntimeException();
+    return GetDoc()->GetBookmarkCnt(sal_True);
+}
+/*-- 14.01.99 09:05:49---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXBookmarks::getByIndex(sal_Int32 nIndex)
+    throw( IndexOutOfBoundsException, WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Any aRet;
+    if(IsValid())
+    {
+        if(GetDoc()->GetBookmarkCnt(sal_True) > nIndex)
+        {
+            SwBookmark& rBkm = GetDoc()->GetBookmark((sal_uInt16) nIndex, sal_True);
+            uno::Reference< XTextContent >  xRef = GetObject(rBkm, GetDoc());
+            aRet.setValue(&xRef, ::getCppuType((uno::Reference*)0));
+        }
+        else
+            throw IndexOutOfBoundsException();
+    }
+    else
+        throw uno::RuntimeException();
+    return aRet;
+}
+/*-- 14.01.99 09:05:49---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXBookmarks::getByName(const rtl::OUString& rName)
+    throw( NoSuchElementException, WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Any aRet;
+    if(IsValid())
+    {
+        String aName(rName);
+        sal_uInt16 nCount = GetDoc()->GetBookmarkCnt(sal_True);
+        uno::Reference< XTextContent >  xRef;
+        for( sal_uInt16 i = 0; i < nCount; i++)
+        {
+            SwBookmark& rBkMk = GetDoc()->GetBookmark( i, sal_True );
+            if(rBkMk.GetName() == aName)
+            {
+                xRef = SwXBookmarks::GetObject(rBkMk, GetDoc());
+                aRet.setValue(&xRef, ::getCppuType((uno::Reference*)0));
+                break;
+            }
+        }
+        if(!xRef.is())
+            throw NoSuchElementException();
+    }
+    else
+        throw uno::RuntimeException();
+    return aRet;
+}
+/*-- 14.01.99 09:05:49---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Sequence< OUString > SwXBookmarks::getElementNames(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!IsValid())
+        throw uno::RuntimeException();
+    sal_uInt16 nCount = GetDoc()->GetBookmarkCnt(sal_True);
+    uno::Sequence aSeq(nCount);
+    if(nCount)
+    {
+        OUString* pArray = aSeq.getArray();
+        for( sal_uInt16 i = 0; i < nCount; i++)
+        {
+            SwBookmark& rBkMk = GetDoc()->GetBookmark( i, sal_True );
+            pArray[i] = rBkMk.GetName();
+        }
+    }
+    return aSeq;
+}
+/*-- 14.01.99 09:05:49---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXBookmarks::hasByName(const OUString& rName) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Bool bRet = sal_False;
+    if(IsValid())
+    {
+        String aName(rName);
+        sal_uInt16 nCount = GetDoc()->GetBookmarkCnt(sal_True);
+        for( sal_uInt16 i = 0; i < nCount; i++)
+        {
+            SwBookmark& rBkMk = GetDoc()->GetBookmark( i, sal_True );
+            if(rBkMk.GetName() == aName)
+            {
+                bRet = sal_True;
+                break;
+            }
+        }
+    }
+    else
+        throw uno::RuntimeException();
+    return bRet;
+}
+/*-- 14.01.99 09:05:50---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Type SAL_CALL SwXBookmarks::getElementType() throw(uno::RuntimeException)
+{
+    return ::getCppuType((uno::Reference*)0);
+}
+/*-- 14.01.99 09:05:50---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXBookmarks::hasElements(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!IsValid())
+        throw uno::RuntimeException();
+    return GetDoc()->GetBookmarkCnt(sal_True) != 0;
+}
+/*-- 14.01.99 09:05:50---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXBookmark*    SwXBookmarks::GetObject( SwBookmark& rBkm, SwDoc* pDoc )
+{
+    SwXBookmark* pBkm = (SwXBookmark*)SwClientIter( rBkm ).
+                                    First( TYPE( SwXBookmark ));
+    if( !pBkm )
+        pBkm = new SwXBookmark(&rBkm, pDoc);
+    return pBkm;
+}
+/******************************************************************
+ *
+ ******************************************************************/
+/* -----------------------------06.04.00 12:44--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXFootnotes::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXFootnotes");
+}
+/* -----------------------------06.04.00 12:44--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXFootnotes::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.text.Footnotes") == rServiceName;
+}
+/* -----------------------------06.04.00 12:44--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXFootnotes::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.Footnotes");
+    return aRet;
+}
+/*-- 14.01.99 09:03:52---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXFootnotes::SwXFootnotes(sal_Bool bEnd, SwDoc* pDoc) :
+    SwUnoCollection(pDoc),
+    bEndnote(bEnd)
+{
+}
+/*-- 14.01.99 09:03:52---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXFootnotes::~SwXFootnotes()
+{
+}
+/*-- 14.01.99 09:03:53---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Int32 SwXFootnotes::getCount(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!IsValid())
+        throw uno::RuntimeException();
+    sal_Int32 nCount = 0;
+    sal_uInt16 n, nFtnCnt = GetDoc()->GetFtnIdxs().Count();
+    SwTxtFtn* pTxtFtn;
+    for( n = 0; n < nFtnCnt; ++n )
+    {
+        pTxtFtn = GetDoc()->GetFtnIdxs()[ n ];
+        const SwFmtFtn& rFtn = pTxtFtn->GetFtn();
+        if ( rFtn.IsEndNote() != bEndnote )
+            continue;
+        nCount++;
+    }
+    return nCount;
+}
+/*-- 14.01.99 09:03:53---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXFootnotes::getByIndex(sal_Int32 nIndex)
+    throw( IndexOutOfBoundsException, WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Any aRet;
+    sal_uInt32 nCount = 0;
+    if(IsValid())
+    {
+        sal_uInt16 n, nFtnCnt = GetDoc()->GetFtnIdxs().Count();
+        SwTxtFtn* pTxtFtn;
+        uno::Reference< XFootnote >  xRef;
+        for( n = 0; n < nFtnCnt; ++n )
+        {
+            pTxtFtn = GetDoc()->GetFtnIdxs()[ n ];
+            const SwFmtFtn& rFtn = pTxtFtn->GetFtn();
+            if( rFtn.IsEndNote() != bEndnote )
+                continue;
+
+            if(nCount == nIndex)
+            {
+                xRef = new SwXFootnote(GetDoc(), rFtn);
+                aRet.setValue(&xRef, ::getCppuType((uno::Reference*)0));
+                break;
+            }
+            nCount++;
+        }
+        if(!xRef.is())
+            throw IndexOutOfBoundsException();
+    }
+    else
+        throw uno::RuntimeException();
+    return aRet;
+}
+/*-- 14.01.99 09:03:53---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Type SAL_CALL SwXFootnotes::getElementType() throw(uno::RuntimeException)
+{
+    return ::getCppuType((uno::Reference*)0);
+}
+/*-- 14.01.99 09:03:54---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXFootnotes::hasElements(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!IsValid())
+        throw uno::RuntimeException();
+    return GetDoc()->GetFtnIdxs().Count() > 0;
+}
+/* -----------------------------05.09.00 12:48--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Reference    SwXFootnotes::GetObject( SwDoc& rDoc, const SwFmtFtn& rFmt )
+{
+    Reference xContent = ((SwUnoCallBack*)rDoc.GetUnoCallBack())->
+                                                            GetFootnote(rFmt);
+    if(!xContent.is())
+        xContent = new SwXFootnote(&rDoc, rFmt);
+    Reference xRet(xContent, UNO_QUERY);
+    return xRet;
+}
+
+/******************************************************************
+ *
+ ******************************************************************/
+/* -----------------------------06.04.00 12:44--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXReferenceMarks::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXReferenceMarks");
+}
+/* -----------------------------06.04.00 12:44--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXReferenceMarks::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.text.ReferenceMarks") == rServiceName;
+}
+/* -----------------------------06.04.00 12:44--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXReferenceMarks::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.ReferenceMarks");
+    return aRet;
+}
+/*-- 14.01.99 09:03:16---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXReferenceMarks::SwXReferenceMarks(SwDoc* pDoc) :
+    SwUnoCollection(pDoc)
+{
+}
+/*-- 14.01.99 09:03:16---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXReferenceMarks::~SwXReferenceMarks()
+{
+}
+/*-- 14.01.99 09:03:17---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Int32 SwXReferenceMarks::getCount(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!IsValid())
+        throw uno::RuntimeException();
+    return GetDoc()->GetRefMarks();
+}
+/*-- 14.01.99 09:03:17---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXReferenceMarks::getByIndex(sal_Int32 nIndex)
+    throw( IndexOutOfBoundsException, WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Any aRet;
+    if(!IsValid())
+        throw uno::RuntimeException();
+    uno::Reference< XTextContent >  xRef;
+    if( nIndex < USHRT_MAX)
+    {
+        const SwFmtRefMark* pMark = GetDoc()->GetRefMark( (sal_uInt16) nIndex );
+        if(pMark)
+        {
+            xRef = SwXReferenceMarks::GetObject( GetDoc(), pMark );
+            aRet.setValue(&xRef, ::getCppuType((uno::Reference*)0));
+        }
+    }
+    if(!xRef.is())
+        throw IndexOutOfBoundsException();
+    return aRet;
+}
+/*-- 14.01.99 09:03:17---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXReferenceMarks::getByName(const OUString& rName)
+    throw( NoSuchElementException, WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Any aRet;
+    if(IsValid())
+    {
+        const SwFmtRefMark* pMark = GetDoc()->GetRefMark(rName);
+        if(pMark)
+        {
+            uno::Reference< XTextContent >  xRef = SwXReferenceMarks::GetObject( GetDoc(), pMark );
+            aRet.setValue(&xRef, ::getCppuType((uno::Reference*)0));
+        }
+        else
+            throw NoSuchElementException();
+    }
+    else
+        throw uno::RuntimeException();
+    return aRet;
+}
+/*-- 14.01.99 09:03:17---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Sequence< OUString > SwXReferenceMarks::getElementNames(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Sequence aRet;
+    if(IsValid())
+    {
+        SvStringsDtor aStrings;
+        sal_uInt16 nCount = GetDoc()->GetRefMarks( &aStrings );
+        aRet.realloc(nCount);
+        OUString* pNames = aRet.getArray();
+        for(sal_uInt16 i = 0; i < nCount; i++)
+            pNames[i] = *aStrings.GetObject(i);
+    }
+    else
+        throw uno::RuntimeException();
+    return aRet;
+}
+/*-- 14.01.99 09:03:17---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXReferenceMarks::hasByName(const OUString& rName) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!IsValid())
+        throw uno::RuntimeException();
+    return 0 != GetDoc()->GetRefMark( rName);
+}
+/*-- 14.01.99 09:03:18---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Type SAL_CALL SwXReferenceMarks::getElementType() throw(uno::RuntimeException)
+{
+    return ::getCppuType((uno::Reference*)0);
+}
+/*-- 14.01.99 09:03:18---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXReferenceMarks::hasElements(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!IsValid())
+        throw uno::RuntimeException();
+    return 0 != GetDoc()->GetRefMarks();
+}
+/*-- 14.01.99 09:03:19---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXReferenceMark* SwXReferenceMarks::GetObject( SwDoc* pDoc, const SwFmtRefMark* pMark )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwClientIter aIter( *pDoc->GetUnoCallBack() );
+    SwXReferenceMark* pxMark = (SwXReferenceMark*)aIter.First( TYPE( SwXReferenceMark ));
+    while(pxMark)
+    {
+        if(pxMark->GetMark() == pMark)
+            break;
+        pxMark = (SwXReferenceMark*)aIter.Next();
+    }
+    if( !pxMark )
+        pxMark = new SwXReferenceMark(pDoc, pMark);
+    return pxMark;
+}
+/******************************************************************
+ *
+ ******************************************************************/
+/* -----------------------------06.04.00 12:44--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXRedlines::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXRedlines");
+}
+/* -----------------------------06.04.00 12:44--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXRedlines::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.text.Redlines") == rServiceName;
+}
+/* -----------------------------06.04.00 12:44--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXRedlines::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.Redlines");
+    return aRet;
+}
+/*-- 14.01.99 09:02:36---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXRedlines::SwXRedlines(SwDoc* pDoc) :
+    SwUnoCollection(pDoc)
+{
+}
+/*-- 14.01.99 09:02:36---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXRedlines::~SwXRedlines()
+{
+}
+/*-- 14.01.99 09:02:37---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Int32 SwXRedlines::getCount(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!IsValid())
+        throw uno::RuntimeException();
+    return  GetDoc()->GetRedlineTbl().Count();
+}
+/*-- 14.01.99 09:02:37---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXRedlines::getByIndex(sal_Int32 nIndex) throw( IndexOutOfBoundsException, WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    //Definition der Redline existiert noch nicht
+    DBG_WARNING("not implemented")
+    return uno::Any();
+}
+/*-- 14.01.99 09:02:37---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Type SAL_CALL SwXRedlines::getElementType() throw(uno::RuntimeException)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    //Definition der Redline existiert noch nicht
+    DBG_WARNING("not implemented")
+    return ::getCppuVoidType();
+}
+/*-- 14.01.99 09:02:37---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXRedlines::hasElements(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!IsValid())
+        throw uno::RuntimeException();
+    return  0 != GetDoc()->GetRedlineTbl().Count();
+}
+/******************************************************************
+ *
+ ******************************************************************/
+/*-----------------11.03.98 11:18-------------------
+    Gueltigkeitspruefung
+--------------------------------------------------*/
+void SwUnoCollection::Invalidate()
+{
+    bObjectValid = sal_False;
+    pDoc = 0;
+}
+/*------------------------------------------------------------------------
+
+    $Log: not supported by cvs2svn $
+    Revision 1.122  2000/09/18 16:04:31  willem.vandorp
+    OpenOffice header added.
+
+    Revision 1.121  2000/09/15 07:20:32  os
+    service of graphic: ...text.GraphicObject
+
+    Revision 1.120  2000/09/05 15:18:41  os
+    new: SwXFootnotes::GetObject
+
+    Revision 1.119  2000/08/25 08:48:33  os
+    service NumberingRules added
+
+    Revision 1.118  2000/08/23 10:49:07  os
+    new service: ...style.ConditionalParagraphStyle
+
+    Revision 1.117  2000/08/17 10:08:24  os
+    several fixes/extensions for XML
+
+    Revision 1.116  2000/08/10 10:55:22  os
+    #76830# new service com.sun.star.TextField.InputUser
+
+    Revision 1.115  2000/07/11 13:43:42  os
+    #76708# insert/remove paragraphs before/behind tables
+
+    Revision 1.114  2000/06/29 15:00:42  os
+    SwXDocumentIndex holds a SwTOXBase in its descriptor
+
+    Revision 1.113  2000/05/30 13:41:03  os
+    #75867# typo corrected
+
+    Revision 1.112  2000/04/27 10:46:56  os
+    UNICODE
+
+    Revision 1.111  2000/04/26 11:35:19  os
+    GetName() returns String&
+
+    Revision 1.110  2000/04/11 08:31:03  os
+    UNICODE
+
+    Revision 1.109  2000/03/27 10:21:09  os
+    UNO III
+
+    Revision 1.108  2000/03/24 10:31:59  os
+    #65681# SwXReferenceMarks::getObject: search at UnoCallBack
+
+    Revision 1.107  2000/03/21 15:42:23  os
+    UNOIII
+
+    Revision 1.106  2000/02/11 14:35:20  hr
+    #70473# changes for unicode ( patched by automated patchtool )
+
+    Revision 1.105  1999/11/19 16:40:18  os
+    modules renamed
+
+    Revision 1.104  1999/11/10 14:47:45  os
+    new index types
+
+    Revision 1.103  1999/10/26 14:35:33  os
+    LinkTargetSupplier
+
+    Revision 1.102  1999/08/23 14:18:10  OS
+    #68353# create SwXPageStyle in ServiceProvider too
+
+
+      Rev 1.101   23 Aug 1999 16:18:10   OS
+   #68353# create SwXPageStyle in ServiceProvider too
+
+      Rev 1.100   30 Jul 1999 14:37:02   OS
+   TOXBase in sections
+
+      Rev 1.99   29 Jul 1999 13:35:06   OS
+   chg: ::util::XProtectable::getIsProtected -> isProtected
+
+      Rev 1.98   18 May 1999 15:24:24   OS
+   #62019# einzelne Services fuer DocInfo-Felder
+
+      Rev 1.97   23 Apr 1999 15:57:44   OS
+   #65257# Bereiche erzeugen
+
+      Rev 1.96   22 Apr 1999 16:13:38   OS
+   #65194# throw -> throw; #65124# not impl. nur noch warning; EventListener
+
+      Rev 1.95   21 Apr 1999 14:36:04   OS
+   #65098# Verzeichnisse und -eintraege
+
+      Rev 1.94   19 Apr 1999 13:11:00   OS
+   #63005# ::util::XProtectable an den Sections
+
+      Rev 1.93   08 Apr 1999 08:31:58   OS
+   #63865# DocumentStatistic-Felder vereinzelt
+
+      Rev 1.92   24 Mar 1999 07:45:58   OS
+   #63839# XServiceInfo nicht ueber ::XIndexAccess casten
+
+      Rev 1.91   15 Mar 1999 14:36:28   OS
+   #62845# Makro fuer ServiceInfo jetzt auch fuer OS/2
+
+      Rev 1.90   12 Mar 1999 09:41:04   OS
+   #62845# XServiceInfo impl.
+
+      Rev 1.89   09 Mar 1999 12:40:58   OS
+   #62008# Solar-Mutex
+
+      Rev 1.88   05 Mar 1999 14:25:38   OS
+   #62870# Schreibfehler
+
+      Rev 1.87   25 Feb 1999 13:32:50   OS
+   #62405# richtiges Split fuer Tabellen mit korrektem Namen
+
+      Rev 1.86   19 Feb 1999 18:11:30   HR
+   Ueberfluessiges S2U()-Makro entfernt
+
+      Rev 1.85   19 Feb 1999 09:35:12   OS
+   #62083# Styles per ServiceProvider anlegen
+
+      Rev 1.84   18 Feb 1999 07:07:56   OS
+   #52654# String->OUString
+
+      Rev 1.83   11 Feb 1999 11:23:28   OS
+   #52654# uno::Exception fuer TextSections an der richigen Stelle
+
+      Rev 1.82   09 Feb 1999 16:22:00   OS
+   #56371# .is() hat gefehlt
+
+      Rev 1.81   05 Feb 1999 07:28:58   OS
+   #56371# Service-Namen leicht veraendert
+
+      Rev 1.80   03 Feb 1999 11:47:10   OS
+   #56371# ::XElementAccess mitliefern
+
+      Rev 1.79   01 Feb 1999 15:50:06   OS
+   #56371# ServiceNames in der richtigen Reihenfolge
+
+      Rev 1.78   01 Feb 1999 08:22:42   OS
+   #56371# richtiger nIndex fuer ServiceProvider
+
+      Rev 1.77   28 Jan 1999 16:47:02   OS
+   #56371# richtige return-Werte
+
+      Rev 1.76   27 Jan 1999 12:06:58   OS
+   #56371# TF_ONE51
+
+      Rev 1.75   27 Jan 1999 09:47:46   OS
+   #56371# TF_ONE51
+
+      Rev 1.74   19 Jan 1999 14:50:38   OS
+   #56371# FieldMaster(s) vervollstaendigt
+
+      Rev 1.73   19 Jan 1999 08:04:42   OS
+    #56371# TF_ONE51: mehr services
+
+      Rev 1.72   15 Jan 1999 14:35:02   AWO
+   Include conver.hxx
+
+      Rev 1.71   14 Jan 1999 16:21:52   OS
+   #56371# TF_ONE51
+
+      Rev 1.70   13 Jan 1999 10:47:44   OS
+   #52654# ::XIndexAccess im queryInterface fuer XFootnotes
+
+
+      Rev 1.69   10 Dec 1998 15:53:08   OS
+   #56371# TF_ONE51 Zwischenstand
+
+      Rev 1.68   17 Nov 1998 16:29:48   OS
+   #59541# Assertions
+
+      Rev 1.67   12 Nov 1998 09:53:32   OS
+   #52654# Selektion vor dem einfuegen von Feldern loeschen
+
+      Rev 1.66   06 Nov 1998 14:03:44   OS
+   #59074# Assertion
+
+      Rev 1.65   14 Oct 1998 09:59:20   OS
+   #57871# IllegalArgumentException fuer falsche Tabellenangaben
+
+      Rev 1.64   13 Oct 1998 07:48:54   OS
+   #57871# addTextTable - Zeilen und Spalten pruefen
+
+      Rev 1.63   01 Oct 1998 11:55:12   OS
+   #52654# falsches IMPL-Macro berichtigt
+
+      Rev 1.62   30 Sep 1998 19:27:38   JP
+   Bug #57399#: nach InsertTable auf jedenfall mal die gesamte Tabelle tief formatieren
+
+      Rev 1.61   25 Sep 1998 15:49:26   OS
+   #52654# ReferenceMark nicht mehrfach erzeugen
+
+      Rev 1.60   17 Sep 1998 09:28:10   OS
+   #52654# richtige Groessenkonvertierung fuer Rahmen
+
+      Rev 1.59   14 Sep 1998 11:51:42   OS
+   #52654# alte DBG_ERROR entfernt
+
+      Rev 1.58   10 Sep 1998 12:51:20   OS
+   #52654# PROPERTY_NONE statt PROPERTY_BOUND
+
+      Rev 1.57   04 Sep 1998 15:13:58   TRI
+   ICC braucht.is()
+
+      Rev 1.56   03 Sep 1998 10:42:22   OS
+   52654 erste Schritte fuer Redline
+
+      Rev 1.55   28 Aug 1998 11:18:26   OS
+   #52654# RefMark(s)
+
+      Rev 1.54   28 Aug 1998 10:25:28   OS
+   #52654# RefMark(s)
+
+      Rev 1.53   12 Aug 1998 19:40:28   HR
+   #54781#: ::::getCppuType((const uno::Reference< uno::XInterface >*)0)() -> ( uno::XInterface*)0)->getSmartUik
+
+      Rev 1.52   20 Jul 1998 17:25:44   OS
+   Border im FrameDescriptor #52654#
+
+      Rev 1.51   10 Jul 1998 18:08:32   OS
+   PropertySetInfo und IdlClass static
+
+      Rev 1.50   09 Jul 1998 09:14:22   OS
+// automatisch auskommentiert - [getIdlClass(es) or queryInterface] - Bitte XTypeProvider benutzen!
+//   getElementBy* - queryInterface auf XInterface
+
+
+      Rev 1.49   01 Jul 1998 17:49:58   OS
+   Graphic/FrameName fuer Graphic/FrameDescriptor
+
+      Rev 1.48   30 Jun 1998 12:24:02   OS
+   MirrorPageToggle fuer GraphicDescriptor
+
+      Rev 1.47   29 Jun 1998 17:17:12   OS
+   Grafik einfuegen, Descriptor-Properties
+
+      Rev 1.46   27 Jun 1998 16:21:44   OS
+   SwXTextGraphicDescriptor
+
+      Rev 1.45   26 Jun 1998 18:17:34   OS
+   FmtLayoutSplit
+
+      Rev 1.44   26 Jun 1998 17:06:08   OS
+   TextTableDescriptor verwendbar
+
+      Rev 1.43   23 Jun 1998 10:24:38   OS
+   Verzeichnisse benutzbar, mit Descriptor, Tables/Frames mit Descriptor
+
+      Rev 1.42   18 Jun 1998 13:22:44   OS
+   include-Umstellung 396c
+
+      Rev 1.41   16 Jun 1998 16:52:20   OS
+   removeXXX -> removeXXXByName
+
+      Rev 1.40   12 Jun 1998 09:47:32   OS
+   TextTableDescriptor: erste Spalten, dann Zeilen
+
+      Rev 1.39   10 Jun 1998 09:54:44   OS
+   Package-Umstellung
+
+      Rev 1.38   09 Jun 1998 13:27:08   OS
+   insertTextTable mit Descriptor
+
+      Rev 1.37   05 Jun 1998 15:45:02   OS
+   addTextTable: keine Tabellen in Tabellen
+
+      Rev 1.36   04 Jun 1998 09:40:04   OS
+// automatisch auskommentiert - [getIdlClass(es) or queryInterface] - Bitte XTypeProvider benutzen!
+//   getIdlClasses
+
+
+      Rev 1.35   26 May 1998 12:32:38   OS
+   eigenes File fuer styles
+
+      Rev 1.34   25 May 1998 09:57:30   OS
+   ChapterNumbering -> unosett.cxx
+
+      Rev 1.33   14 May 1998 17:49:24   OS
+   div. Namensaenderungen
+
+      Rev 1.32   13 May 1998 15:29:18   OS
+   TextPosition-Auswertung verbessert
+
+      Rev 1.31   12 May 1998 16:03:06   JP
+   rund um Flys/DrawObjs im Doc/FESh umgestellt/optimiert
+
+      Rev 1.30   06 May 1998 16:17:40   OS
+   Shapes raus
+
+      Rev 1.29   05 May 1998 13:58:24   OS
+   XTextShapes
+
+      Rev 1.28   09 Apr 1998 15:10:52   OS
+   Uno-Umstellung
+
+      Rev 1.27   08 Apr 1998 12:53:18   OS
+   Remove fuer SwXFrames, SwXTextTables
+
+      Rev 1.26   07 Apr 1998 14:10:38   OS
+// automatisch auskommentiert - [getIdlClass(es) or queryInterface] - Bitte XTypeProvider benutzen!
+//   queryInterface fuer Graphic und EmbeddedObject vollstaendig
+
+
+      Rev 1.25   31 Mar 1998 15:37:02   OS
+   XTextPositionToPaM
+
+      Rev 1.24   30 Mar 1998 10:24:04   OS
+   neue Verzeichnistypen
+
+      Rev 1.23   27 Mar 1998 09:02:24   OS
+   NameAccess fuer SwXFrames inpl.
+
+      Rev 1.22   26 Mar 1998 14:09:54   OS
+   Felder und Feldtypen loeschen
+
+      Rev 1.21   21 Mar 1998 14:53:56   OS
+   SwXFootnotes
+
+      Rev 1.20   17 Mar 1998 08:54:30   TRI
+   ICC brauchte const
+
+      Rev 1.19   14 Mar 1998 15:57:12   OS
+   NewFlyFrame: SwFlyFrm*
+
+      Rev 1.18   13 Mar 1998 17:49:12   OS
+   Solaris-Fehler
+
+      Rev 1.17   13 Mar 1998 08:26:02   OS
+   Position von Shapes uebernehmen
+
+      Rev 1.16   12 Mar 1998 13:06:26   OS
+   Shape
+
+      Rev 1.15   11 Mar 1998 08:00:08   OS
+   Rahmen einfuegen
+
+      Rev 1.14   10 Mar 1998 12:27:46   OS
+   Sections und Bookmarks
+
+      Rev 1.13   09 Mar 1998 11:35:04   OS
+   GetPaM statt GetPosition
+
+      Rev 1.12   07 Mar 1998 16:12:46   OS
+   alte Feldtypen raus
+
+      Rev 1.11   05 Mar 1998 17:39:30   OS
+   HIDDEN_TEXT ->CONDITIONED_TEXT
+
+      Rev 1.10   03 Mar 1998 10:15:34   OS
+   XEmbeddedObject(s), XGraphicObject(s) im offmgr
+
+      Rev 1.9   02 Mar 1998 07:36:20   OS
+   erste Curosorschritte
+
+      Rev 1.8   26 Feb 1998 16:58:48   OS
+   Fieldtypes
+
+      Rev 1.7   24 Feb 1998 18:03:52   OS
+   sal_uInt32-cast
+
+      Rev 1.6   23 Feb 1998 09:14:52   OS
+   GetIdlClass
+
+      Rev 1.5   23 Feb 1998 07:31:20   OS
+   Bookmarks, Grafiken und OLE
+
+      Rev 1.4   19 Feb 1998 17:29:40   OS
+   getSmartUik, Fields-Interface veraendert
+
+      Rev 1.3   17 Feb 1998 08:52:52   OS
+   SwXTextFrames impl.
+
+      Rev 1.2   13 Feb 1998 16:11:54   OS
+   TextTables: Zugriffe verwendbar
+
+      Rev 1.1   12 Feb 1998 14:55:48   OS
+   Geruest aufgebaut
+
+      Rev 1.0   11 Feb 1998 16:19:50   OS
+   Initial revision.
+
+------------------------------------------------------------------------*/
+
+
diff --git a/sw/source/core/unocore/unodraw.cxx b/sw/source/core/unocore/unodraw.cxx
new file mode 100644
index 000000000000..478956814c3e
--- /dev/null
+++ b/sw/source/core/unocore/unodraw.cxx
@@ -0,0 +1,1420 @@
+/*************************************************************************
+ *
+ *  $RCSfile: unodraw.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:28 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include 
+#include 
+
+#include 
+#ifndef _UNODRAW_HXX
+#include 
+#endif
+#ifndef _UNOPRNMS_HXX
+#include 
+#endif
+#ifndef _SVX_UNOPRNMS_HXX
+#include 
+#endif
+#ifndef _UNOOBJ_HXX
+#include 
+#endif
+#ifndef _DOC_HXX //autogen
+#include 
+#endif
+#ifndef _UNOMAP_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX //autogen
+#include 
+#endif
+
+#ifndef _SVDVIEW_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_UNOSHAPE_HXX
+#include 
+#endif
+#ifndef _DCONTACT_HXX
+#include 
+#endif
+#ifndef _FMTORNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _FMTSRND_HXX //autogen
+#include 
+#endif
+#ifndef _ROOTFRM_HXX //autogen
+#include 
+#endif
+
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_ULSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _CRSTATE_HXX //autogen
+#include 
+#endif
+#ifndef _VOS_MUTEX_HXX_ //autogen
+#include 
+#endif
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::text;
+using namespace ::rtl;
+
+/* -----------------22.01.99 13:19-------------------
+ *
+ * --------------------------------------------------*/
+class SwShapeDescriptor_Impl
+{
+    SwFmtHoriOrient*    pHOrient;
+    SwFmtVertOrient*    pVOrient;
+    SwFmtAnchor*        pAnchor;
+    SwFmtSurround*      pSurround;
+    SvxULSpaceItem*     pULSpace;
+    SvxLRSpaceItem*     pLRSpace;
+    uno::Reference< XTextRange >        xTextRange;
+
+public:
+    SwShapeDescriptor_Impl() :
+     pHOrient(0),
+     pVOrient(0),
+     pAnchor(0),
+     pSurround(0),
+     pULSpace(0),
+     pLRSpace(0)
+     {}
+
+    ~SwShapeDescriptor_Impl()
+    {
+        delete pHOrient;
+        delete pVOrient;
+        delete pAnchor;
+        delete pSurround;
+        delete pULSpace;
+        delete pLRSpace;
+    }
+    SwFmtAnchor*    GetAnchor(sal_Bool bCreate = sal_False)
+        {
+            if(bCreate && !pAnchor)
+                pAnchor = new SwFmtAnchor(FLY_IN_CNTNT);
+            return pAnchor;
+        }
+    SwFmtHoriOrient* GetHOrient(sal_Bool bCreate = sal_False)
+        {
+            if(bCreate && !pHOrient)
+                pHOrient = new SwFmtHoriOrient();
+            return pHOrient;
+        }
+    SwFmtVertOrient* GetVOrient(sal_Bool bCreate = sal_False)
+        {
+            if(bCreate && !pVOrient)
+                pVOrient = new SwFmtVertOrient(0, VERT_TOP);
+            return pVOrient;
+        }
+
+    SwFmtSurround*  GetSurround(sal_Bool bCreate = sal_False)
+        {
+            if(bCreate && !pSurround)
+                pSurround = new SwFmtSurround();
+            return pSurround;
+        }
+    SvxLRSpaceItem* GetLRSpace(sal_Bool bCreate = sal_False)
+        {
+            if(bCreate && !pLRSpace)
+                pLRSpace = new SvxLRSpaceItem();
+            return pLRSpace;
+        }
+    SvxULSpaceItem* GetULSpace(sal_Bool bCreate = sal_False)
+        {
+            if(bCreate && !pULSpace)
+                pULSpace = new SvxULSpaceItem();
+            return pULSpace;
+        }
+    uno::Reference< XTextRange > &  GetTextRange()
+    {
+        return xTextRange;
+    }
+};
+/****************************************************************************
+    class SwFmDrawPage
+****************************************************************************/
+
+/* -----------------28.01.99 12:03-------------------
+ *
+ * --------------------------------------------------*/
+SwFmDrawPage::SwFmDrawPage( SdrPage* pPage ) :
+    SvxFmDrawPage( pPage ), pPageView(0)
+{
+}
+
+/*-- 22.01.99 11:13:07---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwFmDrawPage::~SwFmDrawPage()
+{
+    if(pPageView)
+        pView->HidePage( pPageView );
+}
+/*-- 22.01.99 11:13:07---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+const SdrMarkList&  SwFmDrawPage::PreGroup(const uno::Reference< drawing::XShapes > & xShapes)
+{
+    _SelectObjectsInView( xShapes, GetPageView() );
+    const SdrMarkList& rMarkList = pView->GetMarkList();
+    return rMarkList;
+}
+/*-- 22.01.99 11:13:08---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwFmDrawPage::PreUnGroup(const uno::Reference< drawing::XShapeGroup >  xShapeGroup)
+{
+    uno::Reference< drawing::XShape >  xShape(xShapeGroup, UNO_QUERY);
+    _SelectObjectInView( xShape, GetPageView() );
+}
+/*-- 22.01.99 11:13:08---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+/*void  SwFmDrawPage::PostGroup()
+{
+    pView->GroupMarked();
+}
+/*-- 22.01.99 11:13:08---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SdrPageView*    SwFmDrawPage::GetPageView()
+{
+    if(!pPageView)
+        pPageView = pView->ShowPage( pPage, Point() );
+    return pPageView;
+}
+/*-- 22.01.99 11:13:08---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void    SwFmDrawPage::RemovePageView()
+{
+    if(pPageView)
+        pView->HidePage( pPageView );
+    pPageView = 0;
+}
+/*-- 22.01.99 11:13:09---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< uno::XInterface >   SwFmDrawPage::GetInterface( SdrObject* pObj )
+{
+    uno::Reference< drawing::XShape >  xShape;
+    if( pObj )
+    {
+        //TODO: wenn bereits ein SwXShape am Format angemeldet ist, dann das herausreichen!
+        SwFrmFmt* pFmt = ::FindFrmFmt( pObj );
+        SwXShape* pxShape = (SwXShape*)SwClientIter( *pFmt ).
+                                                First( TYPE( SwXShape ));
+        if(pxShape)
+        {
+            xShape = uno::Reference< drawing::XShape >((cppu::OWeakObject*)pxShape, uno::UNO_QUERY);
+            pxShape->queryInterface(::getCppuType((const uno::Reference< drawing::XShape >*)0));
+        }
+        else
+            xShape = _CreateShape( pObj );
+    }
+    return xShape;
+}
+/*-- 22.01.99 11:13:09---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SdrObject* SwFmDrawPage::_CreateSdrObject( const uno::Reference< drawing::XShape > & xShape )
+{
+    //TODO: stimmt das so - kann die Methode weg?
+    return SvxFmDrawPage::_CreateSdrObject( xShape );
+}
+/*-- 22.01.99 11:13:09---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< drawing::XShape >  SwFmDrawPage::_CreateShape( SdrObject *pObj ) const
+{
+    uno::Reference< drawing::XShape >  xShape = SvxFmDrawPage::_CreateShape( pObj );
+    uno::Reference< XUnoTunnel > xShapeTunnel(xShape, uno::UNO_QUERY);
+    //don't create an SwXShape if it already exists
+    SwXShape* pShape = 0;
+    if(xShapeTunnel.is())
+        pShape = (SwXShape*)xShapeTunnel->getSomething(SwXShape::getUnoTunnelId());
+    if(!pShape)
+    {
+        uno::Reference< uno::XInterface > xCreate(xShape, uno::UNO_QUERY);
+        uno::Reference< XPropertySet >  xPrSet = new SwXShape( xCreate );
+        xShape = uno::Reference< drawing::XShape >(xPrSet, uno::UNO_QUERY);
+    }
+    return xShape;
+}
+
+/****************************************************************************
+    class SwXDrawPage
+****************************************************************************/
+/* -----------------------------06.04.00 13:14--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXDrawPage::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXDrawPage");
+}
+/* -----------------------------06.04.00 13:14--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXDrawPage::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.drawing.DrawPage") == rServiceName;
+}
+/* -----------------------------06.04.00 13:14--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXDrawPage::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.drawing.DrawPage");
+    return aRet;
+}
+/*-- 22.01.99 11:22:25---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXDrawPage::SwXDrawPage(SwDoc* pDc) :
+    pDoc(pDc),
+    pDrawPage(0)
+{
+}
+/*-- 22.01.99 11:22:25---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXDrawPage::~SwXDrawPage()
+{
+    if(xPageAgg.is())
+    {
+        uno::Reference< uno::XInterface >  xInt;
+        xPageAgg->setDelegator(xInt);
+    }
+}
+/* -----------------------------15.06.00 15:00--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Any SwXDrawPage::queryInterface( const Type& aType ) throw(RuntimeException)
+{
+    Any aRet = SwXDrawPageBaseClass::queryInterface(aType);
+    if(!aRet.hasValue())
+    {
+        aRet = GetSvxPage()->queryAggregation(aType);
+    }
+    return aRet;
+}
+/* -----------------------------15.06.00 15:01--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< Type > SwXDrawPage::getTypes(  ) throw(RuntimeException)
+{
+    Sequence< uno::Type > aPageTypes = SwXDrawPageBaseClass::getTypes();
+    Sequence< uno::Type > aSvxTypes = GetSvxPage()->getTypes();
+
+    long nIndex = aPageTypes.getLength();
+    aPageTypes.realloc(aPageTypes.getLength() + aSvxTypes.getLength() + 1);
+
+    uno::Type* pPageTypes = aPageTypes.getArray();
+    const uno::Type* pSvxTypes = aSvxTypes.getConstArray();
+    long nPos;
+    for(nPos = 0; nPos < aSvxTypes.getLength(); nPos++)
+    {
+        pPageTypes[nIndex++] = pSvxTypes[nPos];
+    }
+    pPageTypes[nIndex] = ::getCppuType((Reference< ::com::sun::star::form::XFormsSupplier>*)0);
+    return aPageTypes;
+}
+/*-- 22.01.99 11:33:44---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Int32 SwXDrawPage::getCount(void) throw( uno::RuntimeException )
+{
+    vos::OGuard  aGuard(Application::GetSolarMutex());
+    if(!pDoc)
+        throw uno::RuntimeException();
+    if(!pDoc->GetDrawModel())
+        return 0;
+    else
+    {
+        ((SwXDrawPage*)this)->GetSvxPage();
+        return pDrawPage->getCount();
+    }
+}
+/*-- 22.01.99 11:33:46---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXDrawPage::getByIndex(sal_Int32 nIndex)
+        throw( IndexOutOfBoundsException, WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard  aGuard(Application::GetSolarMutex());
+    if(!pDoc)
+        throw uno::RuntimeException();
+    if(!pDoc->GetDrawModel())
+    {
+        throw IndexOutOfBoundsException();
+    }
+    else
+    {
+         ((SwXDrawPage*)this)->GetSvxPage();
+         return pDrawPage->getByIndex( nIndex);
+    }
+    return uno::Any();
+}
+/* -----------------22.01.99 13:13-------------------
+ *
+ * --------------------------------------------------*/
+uno::Type  SwXDrawPage::getElementType(void) throw( uno::RuntimeException )
+{
+    return ::getCppuType((const uno::Reference*)0);
+}
+/* -----------------22.01.99 13:13-------------------
+ *
+ * --------------------------------------------------*/
+sal_Bool SwXDrawPage::hasElements(void) throw( uno::RuntimeException )
+{
+    vos::OGuard  aGuard(Application::GetSolarMutex());
+    if(!pDoc)
+        throw uno::RuntimeException();
+    if(!pDoc->GetDrawModel())
+        return sal_False;
+    else
+        return ((SwXDrawPage*)this)->GetSvxPage()->hasElements();
+}
+
+/* -----------------22.01.99 12:42-------------------
+ *
+ * --------------------------------------------------*/
+void SwXDrawPage::add(const uno::Reference< drawing::XShape > & xShape)
+    throw( uno::RuntimeException )
+{
+    vos::OGuard  aGuard(Application::GetSolarMutex());
+    if(!pDoc)
+        throw uno::RuntimeException();
+//  uno::Reference< uno::XInterface >  xInt(xShape, uno::UNO_QUERY);
+    uno::Reference< XUnoTunnel > xShapeTunnel(xShape, uno::UNO_QUERY);
+    SwXShape* pShape = 0;
+    SvxShape* pSvxShape = 0;
+    if(xShapeTunnel.is())
+    {
+        pShape = (SwXShape*)xShapeTunnel->getSomething(SwXShape::getUnoTunnelId());
+        pSvxShape = (SvxShape*)xShapeTunnel->getSomething(SvxShape::getUnoTunnelId());
+    }
+
+    if(!pShape)
+        throw uno::RuntimeException();
+    GetSvxPage()->add(xShape);
+
+    uno::Reference< uno::XAggregation >     xAgg = pShape->GetAggregationInterface();
+
+    DBG_ASSERT(pSvxShape, "warum gibt es hier kein SvxShape?")
+    //diese Position ist auf jeden Fall in 1/100 mm
+    awt::Point aMM100Pos(pSvxShape->getPosition());
+
+    //jetzt noch die Properties aus dem SwShapeDescriptor_Impl auswerten
+    SwShapeDescriptor_Impl* pDesc = pShape->GetDescImpl();
+
+    SfxItemSet aSet( pDoc->GetAttrPool(), RES_FRMATR_BEGIN,
+                                        RES_FRMATR_END-1 );
+    SwFmtAnchor aAnchor( FLY_IN_CNTNT );
+    if( pDesc )
+    {
+        if(pDesc->GetSurround())
+            aSet.Put( *pDesc->GetSurround());
+        //die Items sind schon in Twip gesetzt
+        if(pDesc->GetLRSpace())
+        {
+            aSet.Put(*pDesc->GetLRSpace());
+        }
+        if(pDesc->GetULSpace())
+        {
+            aSet.Put(*pDesc->GetULSpace());
+        }
+        if(pDesc->GetAnchor())
+            aAnchor = *pDesc->GetAnchor();
+
+        if(pDesc->GetHOrient())
+        {
+            if(pDesc->GetHOrient()->GetHoriOrient() == HORI_NONE)
+                aMM100Pos.X = TWIP_TO_MM100(pDesc->GetHOrient()->GetPos());
+            aSet.Put( *pDesc->GetHOrient() );
+        }
+        if(pDesc->GetVOrient())
+        {
+            if(pDesc->GetVOrient()->GetVertOrient() == VERT_NONE)
+                aMM100Pos.Y = TWIP_TO_MM100(pDesc->GetVOrient()->GetPos());
+            aSet.Put( *pDesc->GetVOrient() );
+        }
+
+        if(pDesc->GetSurround())
+            aSet.Put( *pDesc->GetSurround());
+    }
+
+    pSvxShape->setPosition(aMM100Pos);
+    SdrObject* pObj = pSvxShape->GetSdrObject();
+    pObj->SetLayer( pDoc->GetHeavenId() );
+
+    SwPaM* pPam = new SwPaM(pDoc->GetNodes().GetEndOfContent());
+    SwUnoInternalPaM* pInternalPam = 0;
+    uno::Reference< XTextRange >  xRg;
+    if( pDesc && (xRg = pDesc->GetTextRange()).is() )
+    {
+        pInternalPam = new SwUnoInternalPaM(*pDoc);
+        if(SwXTextRange::XTextRangeToSwPaM(*pInternalPam, xRg))
+        {
+            if(FLY_AT_FLY == aAnchor.GetAnchorId() &&
+                                !pInternalPam->GetNode()->FindFlyStartNode())
+                        aAnchor.SetType(FLY_IN_CNTNT);
+        }
+        else
+            throw uno::RuntimeException();
+    }
+    else if( aAnchor.GetAnchorId() != FLY_PAGE && pDoc->GetRootFrm() )
+    {
+        SwCrsrMoveState aState( MV_SETONLYTEXT );
+        Point aTmp(MM100_TO_TWIP(aMM100Pos.X), MM100_TO_TWIP(aMM100Pos.Y));
+        pDoc->GetRootFrm()->GetCrsrOfst( pPam->GetPoint(), aTmp, &aState );
+        aAnchor.SetAnchor( pPam->GetPoint() );
+
+        aSet.Put( SwFmtVertOrient( 0, VERT_TOP ) );
+    }
+    else
+    {
+        aAnchor.SetType(FLY_PAGE);
+         awt::Size aDescSize(xShape->getSize());
+
+        Point aTmp(MM100_TO_TWIP(aMM100Pos.X), MM100_TO_TWIP(aMM100Pos.Y));
+         Rectangle aRect( aTmp, Size(MM100_TO_TWIP(aDescSize.Width),
+                                    MM100_TO_TWIP(aDescSize.Height)));
+        pObj->SetLogicRect( aRect );
+        aSet.Put( SwFmtHoriOrient( aTmp.X(), HORI_NONE, FRAME ) );
+        aSet.Put( SwFmtVertOrient( aTmp.Y(), VERT_NONE, FRAME ) );
+    }
+    aSet.Put(aAnchor);
+    SwPaM* pTemp = pInternalPam;
+    if ( !pTemp )
+        pTemp = pPam;
+    UnoActionContext aAction(pDoc);
+    pDoc->Insert( *pTemp, *pObj, &aSet );
+    SwFrmFmt* pFmt = ::FindFrmFmt( pObj );
+    if(pFmt)
+        pFmt->Add(pShape);
+
+    delete pPam;
+    delete pInternalPam;
+}
+/* -----------------22.01.99 12:42-------------------
+ *
+ * --------------------------------------------------*/
+void SwXDrawPage::remove(const uno::Reference< drawing::XShape > & xShape) throw( uno::RuntimeException )
+{
+    vos::OGuard  aGuard(Application::GetSolarMutex());
+    if(!pDoc)
+        throw uno::RuntimeException();
+    GetSvxPage()->remove(xShape);
+}
+/* -----------------17.02.99 10:38-------------------
+ *
+ * --------------------------------------------------*/
+uno::Reference< drawing::XShapeGroup >  SwXDrawPage::group(const uno::Reference< drawing::XShapes > & xShapes) throw( uno::RuntimeException )
+{
+    vos::OGuard  aGuard(Application::GetSolarMutex());
+    if(!pDoc)
+        throw uno::RuntimeException();
+    uno::Reference< drawing::XShapeGroup >  xRet;
+    if(xPageAgg.is())
+    {
+
+        SwFmDrawPage* pPage = GetSvxPage();
+        if(pPage)//kann das auch Null sein?
+        {
+            //markieren und MarkList zurueckgeben
+            const SdrMarkList& rMarkList = pPage->PreGroup(xShapes);
+            if ( rMarkList.GetMarkCount() > 1 )
+            {
+                sal_Bool bFlyInCnt = sal_False;
+                for ( sal_uInt16 i = 0; !bFlyInCnt && i < rMarkList.GetMarkCount(); ++i )
+                {
+                    const SdrObject *pObj = rMarkList.GetMark( i )->GetObj();
+                    if ( FLY_IN_CNTNT == ::FindFrmFmt( (SdrObject*)pObj )->GetAnchor().GetAnchorId() )
+                        bFlyInCnt = sal_True;
+                }
+                if( bFlyInCnt )
+                    throw uno::RuntimeException();
+                if( !bFlyInCnt )
+                {
+                    UnoActionContext aContext(pDoc);
+                    pDoc->StartUndo( UNDO_START );
+
+                    SwDrawContact* pContact = pDoc->GroupSelection( *pPage->GetDrawView() );
+                    pDoc->ChgAnchor( pPage->GetDrawView()->GetMarkList(), FLY_AT_CNTNT/*int eAnchorId*/,
+                        sal_True, sal_False );
+
+                    pPage->GetDrawView()->UnmarkAll();
+                    if(pContact)
+                    {
+                        uno::Reference< uno::XInterface >  xInt = pPage->GetInterface( pContact->GetMaster() );
+                        uno::Reference< XPropertySet >  xTmp = new SwXShape(xInt);
+                        xRet = uno::Reference< drawing::XShapeGroup >(xTmp, UNO_QUERY);
+                    }
+                    pDoc->EndUndo( UNDO_END );
+                }
+            }
+            pPage->RemovePageView();
+        }
+    }
+    return xRet;
+}
+/* -----------------17.02.99 10:38-------------------
+ *
+ * --------------------------------------------------*/
+void SwXDrawPage::ungroup(const uno::Reference< drawing::XShapeGroup > & xShapeGroup) throw( uno::RuntimeException )
+{
+    vos::OGuard  aGuard(Application::GetSolarMutex());
+    if(!pDoc)
+        throw uno::RuntimeException();
+    if(xPageAgg.is())
+    {
+        SwFmDrawPage* pPage = GetSvxPage();
+        if(pPage)//kann das auch Null sein?
+        {
+            pPage->PreUnGroup(xShapeGroup);
+            UnoActionContext aContext(pDoc);
+            pDoc->StartUndo( UNDO_START );
+
+            pDoc->UnGroupSelection( *pPage->GetDrawView() );
+            pDoc->ChgAnchor( pPage->GetDrawView()->GetMarkList(), FLY_AT_CNTNT/*int eAnchorId*/,
+                        sal_True, sal_False );
+            pDoc->EndUndo( UNDO_END );
+        }
+        pPage->RemovePageView();
+    }
+}
+
+/* -----------------05.05.98 17:05-------------------
+ *
+ * --------------------------------------------------*/
+SwFmDrawPage*   SwXDrawPage::GetSvxPage()
+{
+    if(!xPageAgg.is() && pDoc)
+    {
+        SdrModel* pModel = pDoc->MakeDrawModel();
+        SdrPage* pPage = pModel->GetPage( 0 );
+
+        {
+            // waehrend des queryInterface braucht man ein Ref auf das
+            // Objekt, sonst wird es geloescht.
+            pDrawPage = new SwFmDrawPage(pPage);
+            uno::Reference< drawing::XDrawPage >  xPage = pDrawPage;
+            uno::Any aAgg = xPage->queryInterface(::getCppuType((uno::Reference< uno::XAggregation >*)0));
+            if(aAgg.getValueType() == ::getCppuType((uno::Reference< uno::XAggregation >*)0))
+                xPageAgg = *(uno::Reference< uno::XAggregation >*)aAgg.getValue();
+        }
+        if( xPageAgg.is() )
+            xPageAgg->setDelegator( (cppu::OWeakObject*)this );
+    }
+    return pDrawPage;
+}
+/****************************************************************************
+
+****************************************************************************/
+TYPEINIT1(SwXShape, SwClient);
+/* -----------------------------10.03.00 18:02--------------------------------
+
+ ---------------------------------------------------------------------------*/
+const uno::Sequence< sal_Int8 > & SwXShape::getUnoTunnelId()
+{
+    static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId();
+    return aSeq;
+}
+/* -----------------------------10.03.00 18:04--------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Int64 SAL_CALL SwXShape::getSomething( const uno::Sequence< sal_Int8 >& rId )
+    throw(uno::RuntimeException)
+{
+    if( rId.getLength() == 16
+        && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+                                        rId.getConstArray(), 16 ) )
+    {
+            return (sal_Int64)this;
+    }
+
+    if( xShapeAgg.is() )
+    {
+        const uno::Type& rTunnelType = ::getCppuType((uno::Reference*)0 );
+        uno::Any aAgg = xShapeAgg->queryAggregation( rTunnelType );
+        if(aAgg.getValueType() == rTunnelType)
+        {
+            uno::Reference xAggTunnel =
+                    *(uno::Reference*)aAgg.getValue();
+            if(xAggTunnel.is())
+                return xAggTunnel->getSomething(rId);
+        }
+    }
+    return 0;
+}
+/* -----------------01.02.99 11:38-------------------
+ *
+ * --------------------------------------------------*/
+SwXShape::SwXShape(uno::Reference< uno::XInterface > & xShape) :
+    aPropSet(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_SHAPE)),
+    _pMap(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_SHAPE)),
+    pImpl(new SwShapeDescriptor_Impl),
+    m_bDescriptor(sal_True)
+{
+    if(xShape.is())  // default Ctor
+    {
+        const uno::Type& rAggType = ::getCppuType((const uno::Reference< uno::XAggregation >*)0);
+        //aAgg contains a reference of the SvxShape!
+        {
+            uno::Any aAgg = xShape->queryInterface(rAggType);
+            if(aAgg.getValueType() == rAggType)
+                xShapeAgg = *(uno::Reference< uno::XAggregation >*)aAgg.getValue();
+        }
+        xShape = 0;
+        m_refCount++;
+        if( xShapeAgg.is() )
+            xShapeAgg->setDelegator( (cppu::OWeakObject*)this );
+        m_refCount--;
+
+        uno::Reference< XUnoTunnel > xShapeTunnel(xShapeAgg, uno::UNO_QUERY);
+        SvxShape* pShape = 0;
+        if(xShapeTunnel.is())
+            pShape = (SvxShape*)xShapeTunnel->getSomething(SvxShape::getUnoTunnelId());
+
+        SdrObject* pObj = pShape ? pShape->GetSdrObject() : 0;
+        if(pObj)
+        {
+            SwFrmFmt* pFmt = ::FindFrmFmt( pObj );
+            if(pFmt)
+                pFmt->Add(this);
+        }
+    }
+}
+
+/*-- 22.01.99 11:42:26---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXShape::~SwXShape()
+{
+    if (xShapeAgg.is())
+    {
+        uno::Reference< uno::XInterface >  xRef;
+        xShapeAgg->setDelegator(xRef);
+    }
+    delete pImpl;
+}
+/* -----------------------------16.06.00 12:21--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Any SwXShape::queryInterface( const uno::Type& aType ) throw(RuntimeException)
+{
+    Any aRet = SwXShapeBaseClass::queryInterface(aType);
+    if(!aRet.hasValue() && xShapeAgg.is())
+        aRet = xShapeAgg->queryAggregation(aType);
+    return aRet;
+}
+/* -----------------------------16.06.00 12:21--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< Type > SAL_CALL SwXShape::getTypes(  ) throw(RuntimeException)
+{
+    Sequence< uno::Type > aRet = SwXShapeBaseClass::getTypes();
+    if(xShapeAgg.is())
+    {
+        Any aProv = xShapeAgg->queryAggregation(::getCppuType((Reference< XTypeProvider >*)0));
+        if(aProv.hasValue())
+        {
+            Reference< XTypeProvider > xAggProv;
+            aProv >>= xAggProv;
+            Sequence< uno::Type > aAggTypes = xAggProv->getTypes();
+            const uno::Type* pAggTypes = aAggTypes.getConstArray();
+            long nIndex = aRet.getLength();
+
+            aRet.realloc(nIndex + aAggTypes.getLength());
+            uno::Type* pBaseTypes = aRet.getArray();
+
+            for(long i = 0; i < aAggTypes.getLength(); i++)
+                pBaseTypes[nIndex++] = pAggTypes[i];
+        }
+    }
+    return aRet;
+}
+/*-- 22.01.99 11:42:26---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XPropertySetInfo >  SwXShape::getPropertySetInfo(void) throw( uno::RuntimeException )
+{
+    vos::OGuard  aGuard(Application::GetSolarMutex());
+    uno::Reference< XPropertySetInfo >  aRet;
+    if(xShapeAgg.is())
+    {
+        const uno::Type& rPropSetType = ::getCppuType((const uno::Reference< XPropertySet >*)0);
+        uno::Any aPSet = xShapeAgg->queryAggregation( rPropSetType );
+        if(aPSet.getValueType() == rPropSetType && aPSet.getValue())
+        {
+            uno::Reference< XPropertySet >  xPrSet = *(uno::Reference< XPropertySet >*)aPSet.getValue();
+            uno::Reference< XPropertySetInfo >  xInfo = xPrSet->getPropertySetInfo();
+            // PropertySetInfo verlaengern!
+            const uno::Sequence aPropSeq = xInfo->getProperties();
+            aRet = new SfxExtItemPropertySetInfo( _pMap, aPropSeq );
+        }
+    }
+    if(!aRet.is())
+        aRet = new SfxItemPropertySetInfo( _pMap );
+    return aRet;
+}
+/*-- 22.01.99 11:42:27---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXShape::setPropertyValue(const OUString& rPropertyName, const uno::Any& aValue)
+    throw( UnknownPropertyException, PropertyVetoException,
+        IllegalArgumentException, WrappedTargetException, RuntimeException)
+{
+    vos::OGuard  aGuard(Application::GetSolarMutex());
+    SwFrmFmt*   pFmt = GetFrmFmt();
+    const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                                                _pMap, rPropertyName);
+    if(xShapeAgg.is())
+    {
+        if(pMap)
+        {
+            //mit Layout kann der Anker umgesetzt werden, ohne dass sich die Position aendert
+            if(pFmt)
+            {
+                SwAttrSet aSet(pFmt->GetAttrSet());
+                if(pFmt->GetDoc()->GetRootFrm() &&
+                    COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_ANCHOR_TYPE))
+                {
+                    UnoActionContext aCtx(pFmt->GetDoc());
+                    SdrObject* pObj = pFmt->FindSdrObject();
+                    SdrMarkList aList;
+                    SdrMark aMark(pObj);
+                    aList.InsertEntry(aMark);
+                    sal_Int16 nAnchor;
+                    aValue >>= nAnchor;
+                    pFmt->GetDoc()->ChgAnchor( aList, nAnchor, sal_False, sal_True );
+                }
+                else
+                {
+                    aPropSet.setPropertyValue(rPropertyName, aValue, aSet);
+                    pFmt->SetAttr(aSet);
+                }
+            }
+            else
+            {
+                SfxPoolItem* pItem = 0;
+                switch(pMap->nWID)
+                {
+                    case RES_ANCHOR:
+                        pItem = pImpl->GetAnchor(sal_True);
+                    break;
+                    case RES_HORI_ORIENT:
+                        pItem = pImpl->GetHOrient(sal_True);
+                    break;
+                    case RES_VERT_ORIENT:
+                        pItem = pImpl->GetVOrient(sal_True);
+                    break;
+                    case  RES_LR_SPACE:
+                        pItem = pImpl->GetLRSpace(sal_True);
+                    break;
+                    case  RES_UL_SPACE:
+                        pItem = pImpl->GetULSpace(sal_True);
+                    break;
+                    case  RES_SURROUND:
+                        pItem = pImpl->GetSurround(sal_True);
+                    break;
+                    case  FN_TEXT_RANGE:
+                    {
+                        const uno::Type rTextRangeType = ::getCppuType((uno::Reference< XTextRange>*)0);
+                        if(aValue.getValueType() == rTextRangeType)
+                        {
+                            uno::Reference< XTextRange > & rRange = pImpl->GetTextRange();
+                            rRange = *(uno::Reference< XTextRange > *)aValue.getValue();
+                        }
+                    }
+                    break;
+                }
+                if(pItem)
+                    ((SfxPoolItem*)pItem)->PutValue(aValue, pMap->nMemberId);
+            }
+        }
+        else
+        {
+            uno::Reference< XPropertySet >  xPrSet;
+            const uno::Type& rPSetType = ::getCppuType((const uno::Reference< XPropertySet >*)0);
+            uno::Any aPSet = xShapeAgg->queryAggregation(rPSetType);
+            if(aPSet.getValueType() != rPSetType || !aPSet.getValue())
+                throw uno::RuntimeException();
+            xPrSet = *(uno::Reference< XPropertySet >*)aPSet.getValue();
+            xPrSet->setPropertyValue(rPropertyName, aValue);
+        }
+    }
+}
+/*-- 22.01.99 11:42:27---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXShape::getPropertyValue(const OUString& rPropertyName)
+    throw( UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard  aGuard(Application::GetSolarMutex());
+    uno::Any aRet;
+    SwFrmFmt*   pFmt = GetFrmFmt();
+    //TODO: Descriptor interface
+    if(xShapeAgg.is())
+    {
+        const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                                    _pMap, rPropertyName);
+        if(pMap)
+        {
+            if(pFmt)
+            {
+                const SwAttrSet& rSet = pFmt->GetAttrSet();
+                aRet = aPropSet.getPropertyValue(rPropertyName, rSet);
+            }
+            else
+            {
+                SfxPoolItem* pItem = 0;
+                switch(pMap->nWID)
+                {
+                    case RES_ANCHOR:
+                        pItem = pImpl->GetAnchor();
+                    break;
+                    case RES_HORI_ORIENT:
+                        pItem = pImpl->GetHOrient();
+                    break;
+                    case RES_VERT_ORIENT:
+                        pItem = pImpl->GetVOrient();
+                    break;
+                    case  RES_LR_SPACE:
+                        pItem = pImpl->GetLRSpace();
+                    break;
+                    case  RES_UL_SPACE:
+                        pItem = pImpl->GetULSpace();
+                    break;
+                    case  RES_SURROUND:
+                        pItem = pImpl->GetSurround();
+                    break;
+                    case FN_TEXT_RANGE :
+                        aRet.setValue(&pImpl->GetTextRange(), ::getCppuType((Reference*)0));
+                    break;
+                }
+                if(pItem)
+                    pItem->QueryValue(aRet, pMap->nMemberId);
+            }
+        }
+        else
+        {
+            uno::Reference< XPropertySet >  xPrSet;
+            const uno::Type& rPSetType = ::getCppuType((const uno::Reference< XPropertySet >*)0);
+            uno::Any aPSet = xShapeAgg->queryAggregation(rPSetType);
+            if(aPSet.getValueType() != rPSetType || !aPSet.getValue())
+                throw uno::RuntimeException();
+            xPrSet = *(uno::Reference< XPropertySet >*)aPSet.getValue();
+            aRet = xPrSet->getPropertyValue(rPropertyName);
+        }
+    }
+    return aRet;
+}
+/*-- 22.01.99 11:42:27---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXShape::addPropertyChangeListener(const OUString& PropertyName, const uno::Reference< XPropertyChangeListener > & aListener) throw( UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 22.01.99 11:42:27---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXShape::removePropertyChangeListener(
+    const OUString& PropertyName,
+    const uno::Reference< XPropertyChangeListener > & aListener)
+    throw( UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 22.01.99 11:42:28---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXShape::addVetoableChangeListener(const OUString& PropertyName, const uno::Reference< XVetoableChangeListener > & aListener) throw( UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 22.01.99 11:42:28---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXShape::removeVetoableChangeListener(const OUString& PropertyName, const uno::Reference< XVetoableChangeListener > & aListener) throw( UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 22.01.99 11:42:28---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXShape::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew)
+{
+    ClientModify(this, pOld, pNew);
+}
+/* -----------------14.04.99 13:02-------------------
+ *
+ * --------------------------------------------------*/
+void SwXShape::attach(const uno::Reference< XTextRange > & xTextRange)
+    throw( IllegalArgumentException, uno::RuntimeException )
+{
+    //hier passiert nichts
+}
+/* -----------------14.04.99 13:02-------------------
+ *
+ * --------------------------------------------------*/
+uno::Reference< XTextRange >  SwXShape::getAnchor(void) throw( uno::RuntimeException )
+{
+    vos::OGuard  aGuard(Application::GetSolarMutex());
+    uno::Reference< XTextRange >  aRef;
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt)
+    {
+        if( pFmt->GetAnchor().GetAnchorId() != FLY_PAGE )
+        {
+            const SwPosition &rPos = *(pFmt->GetAnchor().GetCntntAnchor());
+            SwPaM aPam(rPos);
+            DBG_ERROR("ParentText ?")
+            uno::Reference< XText >  xText;
+            aRef = new SwXTextRange(aPam, xText);
+        }
+    }
+    else
+        aRef = pImpl->GetTextRange();
+    return aRef;
+}
+/* -----------------14.04.99 13:02-------------------
+ *
+ * --------------------------------------------------*/
+void SwXShape::dispose(void) throw( uno::RuntimeException )
+{
+    SvxShape* pSvxShape = GetSvxShape();
+    if(pSvxShape)
+            pSvxShape->dispose();
+}
+/* -----------------14.04.99 13:02-------------------
+ *
+ * --------------------------------------------------*/
+void SwXShape::addEventListener(const uno::Reference< XEventListener > & aListener) throw( uno::RuntimeException )
+{
+    uno::Reference< XUnoTunnel > xShapeTunnel(xShapeAgg, uno::UNO_QUERY);
+    SvxShape* pSvxShape = GetSvxShape();
+    if(pSvxShape)
+         pSvxShape->addEventListener(aListener);
+}
+/* -----------------14.04.99 13:02-------------------
+ *
+ * --------------------------------------------------*/
+void SwXShape::removeEventListener(const uno::Reference< XEventListener > & aListener) throw( uno::RuntimeException )
+{
+    SvxShape* pSvxShape = GetSvxShape();
+    if(pSvxShape)
+        pSvxShape->removeEventListener(aListener);
+}
+/* -----------------03.06.99 08:53-------------------
+ *
+ * --------------------------------------------------*/
+OUString SwXShape::getImplementationName(void) throw( uno::RuntimeException )
+{
+    return C2U("SwXShape");
+}
+/* -----------------03.06.99 08:53-------------------
+ *
+ * --------------------------------------------------*/
+sal_Bool SwXShape::supportsService(const OUString& rServiceName) throw( uno::RuntimeException )
+{
+    sal_Bool bRet = sal_False;
+    if(COMPARE_EQUAL == rServiceName.compareToAscii("com.sun.star.drawing.Shape"))
+        bRet = sal_True;
+    else if(xShapeAgg.is())
+    {
+        uno::Reference< XUnoTunnel > xShapeTunnel(xShapeAgg, uno::UNO_QUERY);
+        SvxShape* pSvxShape = GetSvxShape();
+        bRet = pSvxShape->supportsService(rServiceName);
+    }
+    return bRet;
+}
+/* -----------------03.06.99 08:53-------------------
+ *
+ * --------------------------------------------------*/
+uno::Sequence< OUString > SwXShape::getSupportedServiceNames(void) throw( uno::RuntimeException )
+{
+    uno::Sequence< OUString > aSeq;
+    if(xShapeAgg.is())
+    {
+        uno::Reference< XUnoTunnel > xShapeTunnel(xShapeAgg, uno::UNO_QUERY);
+        SvxShape* pSvxShape = GetSvxShape();
+        if(pSvxShape)
+            aSeq = pSvxShape->getSupportedServiceNames();
+    }
+    else
+    {
+        aSeq.realloc(1);
+        aSeq.getArray()[0] = C2U("com.sun.star.drawing.Shape");
+    }
+    return aSeq;
+}
+/* -----------------------------15.03.00 14:54--------------------------------
+
+ ---------------------------------------------------------------------------*/
+SvxShape*   SwXShape::GetSvxShape()
+{
+    SvxShape* pSvxShape = 0;
+    if(xShapeAgg.is())
+    {
+        uno::Reference< XUnoTunnel > xShapeTunnel(xShapeAgg, uno::UNO_QUERY);
+        if(xShapeTunnel.is())
+            pSvxShape = (SvxShape*)xShapeTunnel->getSomething(SvxShape::getUnoTunnelId());
+    }
+    return pSvxShape;
+}
+
+
+
+/*------------------------------------------------------------------------
+
+    $Log: not supported by cvs2svn $
+    Revision 1.86  2000/09/18 16:04:31  willem.vandorp
+    OpenOffice header added.
+
+    Revision 1.85  2000/09/11 09:56:01  os
+    #78642# getTypes corrected
+
+    Revision 1.84  2000/09/11 07:59:09  os
+    #77691# dont try to aggregate twice
+
+    Revision 1.83  2000/06/20 15:36:33  hr
+    syntax
+
+    Revision 1.82  2000/06/16 12:29:59  os
+    UNO3 errors removed
+
+    Revision 1.81  2000/05/16 09:14:54  os
+    project usr removed
+
+    Revision 1.80  2000/04/11 08:31:03  os
+    UNICODE
+
+    Revision 1.79  2000/03/27 10:21:09  os
+    UNO III
+
+    Revision 1.78  2000/03/21 15:42:24  os
+    UNOIII
+
+    Revision 1.77  2000/02/11 14:35:24  hr
+    #70473# changes for unicode ( patched by automated patchtool )
+
+    Revision 1.76  2000/02/01 16:02:38  os
+    #72517# aggregation: complete class hierarchy
+
+    Revision 1.75  2000/01/03 12:15:10  os
+    #71284# ::group: return SwXShape
+
+    Revision 1.74  1999/11/19 16:40:18  os
+    modules renamed
+
+    Revision 1.73  1999/07/21 10:29:36  OS
+    #65953# SwXDrawPage::group - uno::Exception if shapes are anchored in_content
+
+
+      Rev 1.72   21 Jul 1999 12:29:36   OS
+   #65953# SwXDrawPage::group - uno::Exception if shapes are anchored in_content
+
+      Rev 1.71   03 Jun 1999 12:15:10   OS
+   #66425# ServiceInfo des SvxShape weiterleiten
+
+      Rev 1.70   31 May 1999 08:00:20   OS
+   #66429# Shape-Properties schon vor den Einfuegen verfuegbar
+
+      Rev 1.69   23 Apr 1999 08:26:24   OS
+   #65194# Semikolon muss weg
+
+      Rev 1.68   22 Apr 1999 16:13:38   OS
+   #65194# throw -> throw; #65124# not impl. nur noch warning; EventListener
+
+      Rev 1.67   14 Apr 1999 14:57:14   OS
+   #64676# Shape auch per InsertTextContent einfuegen
+
+      Rev 1.66   15 Mar 1999 14:36:30   OS
+   #62845# Makro fuer ServiceInfo jetzt auch fuer OS/2
+
+      Rev 1.65   12 Mar 1999 09:41:06   OS
+   #62845# XServiceInfo impl.
+
+      Rev 1.64   09 Mar 1999 12:40:58   OS
+   #62008# Solar-Mutex
+
+      Rev 1.63   04 Mar 1999 15:01:30   OS
+   #62191# UINT nicht mehr verwenden
+
+      Rev 1.62   03 Mar 1999 12:52:54   MIB
+   #62566#: Position auch dann richtig, wenn sie direkt am Shape gesetzt wird
+
+      Rev 1.61   26 Feb 1999 07:40:06   OS
+   #62352# uno::Reference< drawing::XShape >  aggregieren: beim Format anmelden
+
+      Rev 1.60   23 Feb 1999 10:33:46   OS
+   #61968# Positionierung auch ohne Range richtig konvertieren
+
+      Rev 1.59   18 Feb 1999 15:51:02   OS
+   #61698# Positionierung berichtigt
+
+      Rev 1.58   17 Feb 1999 14:14:50   OS
+   #61957# chaos::Action fuer einfuegen und umankern
+
+      Rev 1.57   17 Feb 1999 11:52:02   OS
+   #52654# Gruppierung wieder geweckt
+
+      Rev 1.56   15 Feb 1999 11:22:42   OS
+   #52654# Aggragation fuer Shape besser
+
+      Rev 1.55   10 Feb 1999 11:10:18   OS
+   #52552# Returnwert fuer SvxDrawPage::_CreateShape geaendert
+
+      Rev 1.54   09 Feb 1999 16:50:10   HR
+   ?:-Operator erwartert gleiche Typen auf beiden Seiten des :
+
+      Rev 1.53   09 Feb 1999 15:04:36   OS
+   #56371# gehackte Speicherloecher
+
+      Rev 1.52   09 Feb 1999 15:00:46   OS
+   #56371# NAMESPACE ausgebaut
+
+      Rev 1.51   09 Feb 1999 14:15:04   OS
+   #56371# NAMESPACE ausgebaut
+
+      Rev 1.50   05 Feb 1999 15:08:56   OS
+   #56371# Hori/VertOrient wieder verfuegbar
+
+      Rev 1.49   05 Feb 1999 10:47:02   MIB
+   #56371#: Nur einmal in Twip umrechnen
+
+      Rev 1.48   04 Feb 1999 16:29:08   OS
+   #56371# Position richtig auswerten, existierende drawing::Shapes nicht neu anlegen
+
+      Rev 1.47   04 Feb 1999 09:19:10   OS
+   #56371# drawing::ShapeDescriptor funktioniert wieder
+
+      Rev 1.46   01 Feb 1999 15:49:36   OS
+   #56371# Descriptor-Ctor fuer SwXShape
+
+      Rev 1.45   29 Jan 1999 17:18:46   JP
+   Task #61014#: FindSdrObject/FindContactObject als Methoden vom SwFrmFmt
+
+      Rev 1.44   28 Jan 1999 16:15:28   JP
+   Task #61014#: FindSdrObject/FindContactObject als Methoden vom SwFrmFmt
+
+      Rev 1.43   28 Jan 1999 16:07:12   OS
+   #56371# richtige Aggregation
+
+      Rev 1.42   27 Jan 1999 12:29:46   OS
+   #56371# TF_ONE51 TextRange nicht in alter Version
+
+      Rev 1.41   27 Jan 1999 12:06:52   OS
+   #56371# TF_ONE51
+
+      Rev 1.40   22 Jan 1999 15:09:06   OS
+   #56371# Draw wieder verfuegbar
+
+      Rev 1.39   10 Dec 1998 15:53:10   OS
+   #56371# TF_ONE51 Zwischenstand
+
+      Rev 1.38   09 Nov 1998 14:44:32   OS
+   #58785# getSelection an der XTextView vollstaendig
+
+      Rev 1.37   04 Nov 1998 08:42:08   OS
+   #58749# Assertion fuer Multiselektion nur noch bei Bedarf
+
+      Rev 1.36   23 Oct 1998 12:29:38   OS
+   #58371# fuer jedes ShowPage auch ein HidePage rufen
+
+      Rev 1.35   17 Sep 1998 09:13:46   OS
+   #52654# Ankerwechsel mit ChgAnchor
+
+      Rev 1.34   03 Sep 1998 15:45:34   OS
+   #52552 SelectObjectsInView mit zweitem Parameter
+
+      Rev 1.33   16 Jul 1998 13:26:30   OS
+   Konvertierung Twip/1/100 mm #52654#
+
+      Rev 1.32   10 Jul 1998 18:09:02   OS
+   PropertySetInfo und IdlClass static
+
+      Rev 1.31   09 Jul 1998 09:15:02   OS
+   ChgAnchor jetzt am Doc
+
+      Rev 1.30   03 Jul 1998 16:58:58   OS
+   falsche Assertion raus
+
+      Rev 1.29   03 Jul 1998 16:17:08   OS
+   Ableitung von drawing::XShapeGrouper
+
+      Rev 1.28   30 Jun 1998 12:10:22   OS
+   Twip-Konvertierung wieder raus
+
+      Rev 1.27   27 Jun 1998 16:25:46   OS
+   PropertyMapProvider
+
+      Rev 1.26   24 Jun 1998 14:16:38   HR
+   Klammern bei Methodenaufruf vergessen
+
+      Rev 1.25   23 Jun 1998 14:13:18   MIB
+   XFormPage-Interface wegen Abhaengigkeit vom DrawModel
+
+      Rev 1.24   23 Jun 1998 13:09:34   OS
+   Einheitenkonvertierung
+
+      Rev 1.23   18 Jun 1998 08:08:30   OS
+   Syntax OS/2
+
+      Rev 1.22   15 Jun 1998 14:02:42   OS
+   InsertShape: Anker immer setzen
+
+      Rev 1.21   15 Jun 1998 13:58:52   MIB
+   getIdlClassen nun richtig
+
+
+      Rev 1.20   10 Jun 1998 09:54:46   OS
+   Package-Umstellung
+
+      Rev 1.19   08 Jun 1998 08:45:54   OS
+   insertShape->insertShapeAtTextPosition
+
+      Rev 1.18   05 Jun 1998 14:02:38   OS
+   getIdlClasses fuer Shape verwendet Aggregation
+
+
+      Rev 1.17   04 Jun 1998 16:10:08   MIB
+   insertShape: zeichengebundene Objekte bekommen Position (0,0)
+
+      Rev 1.16   04 Jun 1998 12:18:22   OS
+   getIdlClasses
+
+
+      Rev 1.15   02 Jun 1998 16:03:58   MIB
+   neue form-Control-Anbindung
+
+      Rev 1.14   29 May 1998 12:18:26   OS
+   getImplementation fuer SwXShape
+
+
+      Rev 1.13   19 May 1998 19:04:42   MIB
+   LRSpace und ULSpace berichtigt
+
+      Rev 1.12   19 May 1998 11:28:40   OS
+   mehr Attribute fuer den drawing::ShapeDescriptor
+
+      Rev 1.11   14 May 1998 10:27:02   OS
+   SfxExtItemPropertySet doch schon ab 390, Map berichtigt
+
+      Rev 1.10   14 May 1998 08:22:32   OS
+   FmPage aggregieren
+
+      Rev 1.9   13 May 1998 15:29:14   OS
+   TextPosition-Auswertung verbessert
+
+      Rev 1.8   12 May 1998 17:10:16   JP
+   rund um Flys/DrawObjs im Doc/FESh umgestellt/optimiert
+
+      Rev 1.7   12 May 1998 15:28:32   OS
+   alte Methoden raus
+
+      Rev 1.6   12 May 1998 12:48:34   OS
+   Properties verknuepft
+
+      Rev 1.5   11 May 1998 11:07:24   OS
+   Sonderzeichen geloescht
+
+      Rev 1.4   11 May 1998 10:48:00   OS
+   chaos::Action fuer InsertShape
+
+      Rev 1.3   11 May 1998 09:05:04   MIB
+   Aggregation statt Pointer
+
+      Rev 1.2   08 May 1998 08:07:18   MIB
+   form-Control-Integration
+
+      Rev 1.1   06 May 1998 17:05:30   OS
+   eigene Properties fuer drawing::ShapeDescriptor
+
+      Rev 1.0   06 May 1998 16:17:24   OS
+   Initial revision.
+
+------------------------------------------------------------------------*/
+
diff --git a/sw/source/core/unocore/unofield.cxx b/sw/source/core/unocore/unofield.cxx
new file mode 100644
index 000000000000..4e3bdd74f82b
--- /dev/null
+++ b/sw/source/core/unocore/unofield.cxx
@@ -0,0 +1,3230 @@
+/*************************************************************************
+ *
+ *  $RCSfile: unofield.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:28 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include 
+#include 
+#ifndef _DOC_HXX //autogen
+#include 
+#endif
+
+#ifndef _HINTS_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _NDTXT_HXX //autogen
+#include 
+#endif
+#ifndef _UNOMAP_HXX
+#include 
+#endif
+#ifndef _UNOPRNMS_HXX
+#include 
+#endif
+#ifndef _UNOOBJ_HXX
+#include 
+#endif
+#ifndef _UNOCOLL_HXX
+#include 
+#endif
+#ifndef _SFX_ITEMPROP_HXX //autogen
+#include 
+#endif
+#ifndef _SVXLINKMGR_HXX
+#include 
+#endif
+#ifndef _DOCSTAT_HXX //autogen
+#include 
+#endif
+#ifndef _COM_SUN_STAR_UTIL_TIME_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_UTIL_DATETIMERANGE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_UTIL_DATETIME_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_UTIL_DATE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUES_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_PROPERTYSTATE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSETINFO_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XMULTIPROPERTYSET_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XFASTPROPERTYSET_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XVETOABLECHANGELISTENER_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSTATE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSTATECHANGELISTENER_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTIESCHANGELISTENER_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYCHANGELISTENER_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYACCESS_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYCONTAINER_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_PROPERTYSTATECHANGEEVENT_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_PROPERTYCHANGEEVENT_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_SETVARIABLETYPE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_WRAPTEXTMODE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_TEXTCONTENTANCHORTYPE_HPP_
+#include 
+#endif
+#ifndef _UNOFIELD_HXX
+#include 
+#endif
+#ifndef _UNOCRSR_HXX
+#include 
+#endif
+#ifndef  _FLDBAS_HXX
+#include 
+#endif
+#ifndef  _FLDDAT_HXX
+#include 
+#endif
+#ifndef  _DBFLD_HXX
+#include 
+#endif
+#ifndef  _USRFLD_HXX
+#include 
+#endif
+#ifndef  _DOCUFLD_HXX
+#include 
+#endif
+#ifndef _EXPFLD_HXX
+#include 
+#endif
+#ifndef _CHPFLD_HXX
+#include 
+#endif
+#ifndef _POOLFMT_HXX
+#include 
+#endif
+#ifndef _PAGEDESC_HXX //autogen
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _REFFLD_HXX
+#include 
+#endif
+#ifndef _DDEFLD_HXX
+#include 
+#endif
+#define _SVSTDARR_STRINGS
+#include 
+#ifndef _VOS_MUTEX_HXX_ //autogen
+#include 
+#endif
+#ifndef _SV_SVAPP_HXX //autogen
+#include 
+#endif
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::rtl;
+
+
+/******************************************************************************
+ *
+ ******************************************************************************/
+//Abbildung der Properties auf den Descriptor
+#define FIELD_PROP_PAR1             10
+#define FIELD_PROP_PAR2             11
+#define FIELD_PROP_PAR3             12
+#define FIELD_PROP_FORMAT           13
+#define FIELD_PROP_SUBTYPE          14
+#define FIELD_PROP_BOOL1            15
+#define FIELD_PROP_BOOL2            16
+#define FIELD_PROP_DATE             17
+#define FIELD_PROP_USHORT1          18
+#define FIELD_PROP_USHORT2          19
+#define FIELD_PROP_BYTE1            20
+#define FIELD_PROP_DOUBLE           21
+#define FIELD_PROP_BOOL3            22
+#define FIELD_PROP_PAR4             23
+#define FIELD_PROP_SHORT1           24
+
+//static SfxItemPropertyMap aSetRefFieldPropMap     [] = {{0,0,0,0}};
+//static SfxItemPropertyMap aInetFieldPropMap       [] = {{0,0,0,0}};
+
+
+class SwFieldPropMapProvider
+{
+public:
+    static const SfxItemPropertyMap* GetPropertyMap(USHORT nServiceId);
+};
+/* -----------------------------27.03.00 09:59--------------------------------
+
+ ---------------------------------------------------------------------------*/
+const SfxItemPropertyMap* SwFieldPropMapProvider::GetPropertyMap(USHORT nServiceId)
+{
+    const SfxItemPropertyMap* pRet = 0;
+    switch(nServiceId)
+    {
+        case  SW_SERVICE_FIELDTYPE_DATETIME:
+        {
+            static SfxItemPropertyMap aDateTimeFieldPropMap[] =
+            {
+                {SW_PROP_NAME(UNO_NAME_ADJUST), FIELD_PROP_SUBTYPE,     &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_DATETIME),   FIELD_PROP_DOUBLE,  &::getCppuType((const Double*)0), PROPERTY_NONE,    0},
+                {SW_PROP_NAME(UNO_NAME_IS_FIXED),       FIELD_PROP_BOOL1,   &::getBooleanCppuType()  , PROPERTY_NONE,0},
+                {SW_PROP_NAME(UNO_NAME_IS_DATE),    FIELD_PROP_BOOL2,   &::getBooleanCppuType()  , PROPERTY_NONE,0},
+                {SW_PROP_NAME(UNO_NAME_NUMBER_FORMAT), FIELD_PROP_FORMAT,   &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, 0},
+                {0,0,0,0}
+            };
+            pRet = aDateTimeFieldPropMap;
+        }
+        break;
+        case  SW_SERVICE_FIELDTYPE_USER     :
+        {
+            static SfxItemPropertyMap aUserFieldPropMap[] =
+            {
+                {SW_PROP_NAME(UNO_NAME_IS_SHOW_FORMULA), FIELD_PROP_BOOL2,  &::getBooleanCppuType(), PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_IS_VISIBLE),     FIELD_PROP_BOOL1,   &::getBooleanCppuType(), PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_NUMBER_FORMAT),  FIELD_PROP_FORMAT,  &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, 0},
+                {0,0,0,0}
+            };
+
+            pRet = aUserFieldPropMap;
+        }
+        break;
+        case  SW_SERVICE_FIELDTYPE_SET_EXP  :
+        {
+            static SfxItemPropertyMap aSetExpFieldPropMap       [] =
+            {
+                {SW_PROP_NAME(UNO_NAME_CONTENT),            FIELD_PROP_PAR2,    &::getCppuType((const OUString*)0),   PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_CURRENT_PRESENTATION), FIELD_PROP_PAR4, &::getCppuType((const OUString*)0),  PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_HINT),               FIELD_PROP_PAR3, &::getCppuType((const OUString*)0),   PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_NUMBER_FORMAT),      FIELD_PROP_FORMAT,  &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_NUMBERING_TYPE),     FIELD_PROP_USHORT2, &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_IS_INPUT),       FIELD_PROP_BOOL1,   &::getBooleanCppuType(),    PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_IS_SHOW_FORMULA), FIELD_PROP_BOOL3,  &::getBooleanCppuType(), PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_IS_VISIBLE),       FIELD_PROP_BOOL2,   &::getBooleanCppuType(),    PROPERTY_NONE, 0},
+                //TODO: UNO_NAME_VARIABLE_NAME gibt es das wirklich?
+                {SW_PROP_NAME(UNO_NAME_SEQUENCE_VALUE), FIELD_PROP_USHORT1, &::getCppuType((const sal_Int16*)0),    PROPERTY_NONE,  0},
+                {SW_PROP_NAME(UNO_NAME_SUB_TYPE),           FIELD_PROP_SUBTYPE, &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_VALUE),          FIELD_PROP_DOUBLE,  &::getCppuType((const Double*)0),   PROPERTY_NONE,  0},
+                {SW_PROP_NAME(UNO_NAME_VARIABLE_NAME),  FIELD_PROP_PAR1,    &::getCppuType((const OUString*)0),   PropertyAttribute::READONLY, 0},
+                {0,0,0,0}
+            };
+            pRet = aSetExpFieldPropMap;
+        }
+        break;
+        case  SW_SERVICE_FIELDTYPE_GET_EXP  :
+        {
+            static SfxItemPropertyMap aGetExpFieldPropMap       [] =
+            {
+                {SW_PROP_NAME(UNO_NAME_CONTENT),            FIELD_PROP_PAR1,    &::getCppuType((const OUString*)0),   PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_CURRENT_PRESENTATION), FIELD_PROP_PAR4, &::getCppuType((const OUString*)0),  PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_IS_SHOW_FORMULA), FIELD_PROP_BOOL2,  &::getBooleanCppuType(), PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_NUMBER_FORMAT),  FIELD_PROP_FORMAT,  &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_SUB_TYPE),           FIELD_PROP_SUBTYPE, &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_VALUE),          FIELD_PROP_DOUBLE,  &::getCppuType((const Double*)0), PropertyAttribute::READONLY,  0},
+                {SW_PROP_NAME(UNO_NAME_VARIABLE_SUBTYPE),   FIELD_PROP_USHORT1, &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, 0},
+                {0,0,0,0}
+            };
+            pRet = aGetExpFieldPropMap;
+        }
+        break;
+        case  SW_SERVICE_FIELDTYPE_FILE_NAME:
+        {
+            static SfxItemPropertyMap aFileNameFieldPropMap [] =
+            {
+                {SW_PROP_NAME(UNO_NAME_CURRENT_PRESENTATION), FIELD_PROP_PAR3, &::getCppuType((const OUString*)0),  PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_FILE_FORMAT), FIELD_PROP_FORMAT, &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_IS_FIXED),   FIELD_PROP_BOOL2, &::getBooleanCppuType(),      PROPERTY_NONE, 0},
+                {0,0,0,0}
+            };
+            pRet = aFileNameFieldPropMap;
+        }
+        break;
+        case  SW_SERVICE_FIELDTYPE_PAGE_NUM :
+        {
+            static SfxItemPropertyMap aPageNumFieldPropMap      [] =
+            {
+                {SW_PROP_NAME(UNO_NAME_NUMBERING_TYPE),     FIELD_PROP_FORMAT,  &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_OFFSET),             FIELD_PROP_USHORT1, &::getCppuType((const sal_Int16*)0),  PROPERTY_NONE,    0},
+            // das ist mit dem Offset schon erledigt
+            //  {UNO_NAME_SUB_TYPE,             FIELD_PROP_SUBTYPE, &::getCppuType((const PageNumberType*)0), PROPERTY_NONE,    0},
+                {SW_PROP_NAME(UNO_NAME_USERTEXT),           FIELD_PROP_PAR1,    &::getCppuType((const OUString*)0), PROPERTY_NONE, 0},
+                {0,0,0,0}
+            };
+            pRet = aPageNumFieldPropMap;
+        }
+        break;
+        case  SW_SERVICE_FIELDTYPE_AUTHOR   :
+        {
+            static SfxItemPropertyMap aAuthorFieldPropMap       [] =
+            {
+                {SW_PROP_NAME(UNO_NAME_CONTENT),    FIELD_PROP_PAR1, &::getCppuType((const OUString*)0),    PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_CURRENT_PRESENTATION), FIELD_PROP_PAR1, &::getCppuType((const OUString*)0),  PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_IS_FIXED),   FIELD_PROP_BOOL2, &::getBooleanCppuType(),      PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_FULL_NAME),FIELD_PROP_BOOL1, &::getBooleanCppuType(),        PROPERTY_NONE, 0},
+                {0,0,0,0}
+            };
+            pRet = aAuthorFieldPropMap;
+        }
+        break;
+        case  SW_SERVICE_FIELDTYPE_CHAPTER  :
+        {
+            static SfxItemPropertyMap aChapterFieldPropMap      [] =
+            {
+                {SW_PROP_NAME(UNO_NAME_CHAPTER_FORMAT),FIELD_PROP_USHORT1,  &::getCppuType((const sal_Int16*)0),    PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_LEVEL        ),FIELD_PROP_BYTE1,         &::getCppuType((const sal_Int8*)0),     PROPERTY_NONE, 0},
+                {0,0,0,0}
+            };
+            pRet = aChapterFieldPropMap;
+        }
+        break;
+        case SW_SERVICE_FIELDTYPE_GET_REFERENCE         :
+        {
+            static SfxItemPropertyMap aGetRefFieldPropMap       [] =
+            {
+                {SW_PROP_NAME(UNO_NAME_CURRENT_PRESENTATION), FIELD_PROP_PAR3, &::getCppuType((const OUString*)0),  PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_REFERENCE_FIELD_PART),FIELD_PROP_USHORT1, &::getCppuType((const sal_Int16*)0),   PROPERTY_NONE,  0},
+                {SW_PROP_NAME(UNO_NAME_REFERENCE_FIELD_SOURCE),FIELD_PROP_USHORT2, &::getCppuType((const sal_Int16*)0),     PROPERTY_NONE,  0},
+                {SW_PROP_NAME(UNO_NAME_SEQUENCE_NUMBER),    FIELD_PROP_SHORT1,  &::getCppuType((const sal_Int16*)0),   PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_SOURCE_NAME),        FIELD_PROP_PAR1,    &::getCppuType((const OUString*)0),   PROPERTY_NONE, 0},
+                {0,0,0,0}
+            };
+            pRet = aGetRefFieldPropMap;
+        }
+        break;
+        case SW_SERVICE_FIELDTYPE_CONDITIONED_TEXT      :
+        {
+            static SfxItemPropertyMap aConditionedTxtFieldPropMap   [] =
+            {
+                {SW_PROP_NAME(UNO_NAME_CONDITION),      FIELD_PROP_PAR1, &::getCppuType((const OUString*)0),   PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_FALSE_CONTENT),  FIELD_PROP_PAR3, &::getCppuType((const OUString*)0),   PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_TRUE_CONTENT) ,  FIELD_PROP_PAR2, &::getCppuType((const OUString*)0),   PROPERTY_NONE, 0},
+                {0,0,0,0}
+            };
+            pRet = aConditionedTxtFieldPropMap;
+        }
+        break;
+        case SW_SERVICE_FIELDTYPE_HIDDEN_TEXT :
+        {
+            static SfxItemPropertyMap aHiddenTxtFieldPropMap    [] =
+            {
+                {SW_PROP_NAME(UNO_NAME_CONDITION),      FIELD_PROP_PAR1, &::getCppuType((const OUString*)0),   PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_CONTENT) ,       FIELD_PROP_PAR2, &::getCppuType((const OUString*)0),   PROPERTY_NONE, 0},
+                {0,0,0,0}
+            };
+            pRet = aHiddenTxtFieldPropMap;
+        }
+        break;
+        case SW_SERVICE_FIELDTYPE_ANNOTATION            :
+        {
+            static SfxItemPropertyMap aAnnotationFieldPropMap   [] =
+            {
+                {SW_PROP_NAME(UNO_NAME_AUTHOR), FIELD_PROP_PAR1,    &::getCppuType((const OUString*)0),   PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_CONTENT),    FIELD_PROP_PAR2,    &::getCppuType((const OUString*)0),   PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_DATE),   FIELD_PROP_DATE,    &::getCppuType((const util::Date*)0),   PROPERTY_NONE, 0},
+                {0,0,0,0}
+            };
+            pRet = aAnnotationFieldPropMap;
+        }
+        break;
+        case SW_SERVICE_FIELDTYPE_INPUT_USER:
+        case SW_SERVICE_FIELDTYPE_INPUT                 :
+        {
+            static SfxItemPropertyMap aInputFieldPropMap        [] =
+            {
+                {SW_PROP_NAME(UNO_NAME_CONTENT),    FIELD_PROP_PAR1, &::getCppuType((const OUString*)0),   PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_HINT),       FIELD_PROP_PAR2, &::getCppuType((const OUString*)0),   PROPERTY_NONE, 0},
+                {0,0,0,0}
+            };
+            pRet = aInputFieldPropMap;
+        }
+        break;
+        case SW_SERVICE_FIELDTYPE_MACRO                 :
+        {
+            static SfxItemPropertyMap aMacroFieldPropMap        [] =
+            {
+                {SW_PROP_NAME(UNO_NAME_HINT), FIELD_PROP_PAR2, &::getCppuType((const OUString*)0),   PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_MACRO),FIELD_PROP_PAR1, &::getCppuType((const OUString*)0),   PROPERTY_NONE, 0},
+                {0,0,0,0}
+            };
+            pRet = aMacroFieldPropMap;
+        }
+        break;
+        case SW_SERVICE_FIELDTYPE_DDE                   :
+        {
+            static SfxItemPropertyMap aDDEFieldPropMap          [] = {{0,0,0,0}};
+            pRet = aDDEFieldPropMap;
+        }
+        break;
+        case SW_SERVICE_FIELDTYPE_HIDDEN_PARA           :
+        {
+            static SfxItemPropertyMap aHiddenParaFieldPropMap   [] =
+            {
+                {SW_PROP_NAME(UNO_NAME_CONDITION),FIELD_PROP_PAR1, &::getCppuType((const OUString*)0),   PROPERTY_NONE, 0},
+                {0,0,0,0}
+            };
+            pRet = aHiddenParaFieldPropMap;
+        }
+        break;
+        case SW_SERVICE_FIELDTYPE_DOC_INFO              :
+        {
+            static SfxItemPropertyMap aDocInfoFieldPropMap      [] =
+            {
+                {SW_PROP_NAME(UNO_NAME_IS_FIXED),       FIELD_PROP_BOOL1,   &::getBooleanCppuType(),        PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_INFO_FORMAT),    FIELD_PROP_USHORT2, &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_INFO_TYPE),  FIELD_PROP_USHORT1, &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, 0},
+                {0,0,0,0}
+            };
+            pRet = aDocInfoFieldPropMap;
+        }
+        break;
+        case SW_SERVICE_FIELDTYPE_TEMPLATE_NAME         :
+        {
+            static SfxItemPropertyMap aTmplNameFieldPropMap [] =
+            {
+                {SW_PROP_NAME(UNO_NAME_FILE_FORMAT), FIELD_PROP_FORMAT, &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, 0},
+                {0,0,0,0}
+            };
+            pRet = aTmplNameFieldPropMap;
+        }
+        break;
+        case SW_SERVICE_FIELDTYPE_USER_EXT              :
+        {
+            static SfxItemPropertyMap aUsrExtFieldPropMap       [] =
+            {
+                {SW_PROP_NAME(UNO_NAME_CONTENT),            FIELD_PROP_PAR1,    &::getCppuType((const OUString*)0),   PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_CURRENT_PRESENTATION), FIELD_PROP_PAR1, &::getCppuType((const OUString*)0),  PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_IS_FIXED),           FIELD_PROP_BOOL1,   &::getBooleanCppuType(),        PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_USER_DATA_TYPE), FIELD_PROP_USHORT1, &::getCppuType((const sal_Int16*)0),    PROPERTY_NONE, 0},
+                {0,0,0,0}
+            };
+            pRet = aUsrExtFieldPropMap;
+        }
+        break;
+        case SW_SERVICE_FIELDTYPE_REF_PAGE_SET          :
+        {
+            static SfxItemPropertyMap aRefPgSetFieldPropMap [] =
+            {
+                {SW_PROP_NAME(UNO_NAME_OFFSET),     FIELD_PROP_USHORT1, &::getCppuType((const sal_Int16*)0),    PROPERTY_NONE,  0},
+                {SW_PROP_NAME(UNO_NAME_ON),     FIELD_PROP_BOOL1,   &::getBooleanCppuType(),        PROPERTY_NONE, 0},
+                {0,0,0,0}
+            };
+            pRet = aRefPgSetFieldPropMap;
+        }
+        break;
+        case SW_SERVICE_FIELDTYPE_REF_PAGE_GET          :
+        {
+            static SfxItemPropertyMap aRefPgGetFieldPropMap [] =
+            {
+                {SW_PROP_NAME(UNO_NAME_NUMBERING_TYPE),     FIELD_PROP_USHORT1, &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, 0},
+                {0,0,0,0}
+            };
+            pRet = aRefPgGetFieldPropMap;
+        }
+        break;
+        case SW_SERVICE_FIELDTYPE_JUMP_EDIT             :
+        {
+            static SfxItemPropertyMap aJumpEdtFieldPropMap      [] =
+            {
+                {SW_PROP_NAME(UNO_NAME_HINT),               FIELD_PROP_PAR1, &::getCppuType((const OUString*)0),   PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_PLACEHOLDER),        FIELD_PROP_PAR2, &::getCppuType((const OUString*)0),   PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_PLACEHOLDER_TYPE), FIELD_PROP_USHORT1, &::getCppuType((const sal_Int16*)0),  PROPERTY_NONE,  0},
+                {0,0,0,0}
+            };
+            pRet = aJumpEdtFieldPropMap;
+        }
+        break;
+        case SW_SERVICE_FIELDTYPE_SCRIPT                :
+        {
+            static SfxItemPropertyMap aScriptFieldPropMap       [] =
+            {
+                {SW_PROP_NAME(UNO_NAME_CONTENT),        FIELD_PROP_PAR2, &::getCppuType((const OUString*)0),   PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_SCRIPT_TYPE),    FIELD_PROP_PAR1, &::getCppuType((const OUString*)0),   PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_URL_CONTENT),    FIELD_PROP_BOOL1, &::getBooleanCppuType(),      PROPERTY_NONE, 0},
+                {0,0,0,0}
+            };
+            pRet = aScriptFieldPropMap;
+        }
+        break;
+        case SW_SERVICE_FIELDTYPE_DATABASE_NEXT_SET     :
+        {
+            static SfxItemPropertyMap aDBNextSetFieldPropMap    [] =
+            {
+                {SW_PROP_NAME(UNO_NAME_CONDITION)   ,     FIELD_PROP_PAR3, &::getCppuType((const OUString*)0),   PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_DATA_BASE_NAME ) , FIELD_PROP_PAR1, &::getCppuType((const OUString*)0),   PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_DATA_TABLE_NAME) , FIELD_PROP_PAR2, &::getCppuType((const OUString*)0),   PROPERTY_NONE, 0},
+                {0,0,0,0}
+            };
+            pRet = aDBNextSetFieldPropMap;
+        }
+        break;
+        case SW_SERVICE_FIELDTYPE_DATABASE_NUM_SET      :
+        {
+            static SfxItemPropertyMap aDBNumSetFieldPropMap [] =
+            {
+                {SW_PROP_NAME(UNO_NAME_CONDITION),        FIELD_PROP_PAR3, &::getCppuType((const OUString*)0),   PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_DATA_BASE_NAME   ), FIELD_PROP_PAR1, &::getCppuType((const OUString*)0),   PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_DATA_TABLE_NAME  ), FIELD_PROP_PAR2, &::getCppuType((const OUString*)0),   PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_SET_NUMBER       ), FIELD_PROP_FORMAT, &::getCppuType((const sal_Int32*)0), PROPERTY_NONE,   0},
+                {0,0,0,0}
+            };
+            pRet = aDBNumSetFieldPropMap;
+        }
+        break;
+        case SW_SERVICE_FIELDTYPE_DATABASE_SET_NUM      :
+        {
+            static SfxItemPropertyMap aDBSetNumFieldPropMap [] =
+            {
+                {SW_PROP_NAME(UNO_NAME_DATA_BASE_NAME ) , FIELD_PROP_PAR1, &::getCppuType((const OUString*)0),   PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_DATA_TABLE_NAME) , FIELD_PROP_PAR2, &::getCppuType((const OUString*)0),   PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_NUMBERING_TYPE),       FIELD_PROP_USHORT1, &::getCppuType((const sal_Int16*)0), PROPERTY_NONE,   0},
+                {SW_PROP_NAME(UNO_NAME_SET_NUMBER       ), FIELD_PROP_FORMAT, &::getCppuType((const sal_Int32*)0), PROPERTY_NONE,   0},
+                {0,0,0,0}
+            };
+            pRet = aDBSetNumFieldPropMap;
+        }
+        break;
+        case SW_SERVICE_FIELDTYPE_DATABASE              :
+        {
+            static SfxItemPropertyMap aDBFieldPropMap           [] =
+            {
+                {SW_PROP_NAME(UNO_NAME_CONTENT),            FIELD_PROP_PAR1,    &::getCppuType((const OUString*)0), PROPERTY_NONE,  0},
+                {SW_PROP_NAME(UNO_NAME_CURRENT_PRESENTATION), FIELD_PROP_PAR1, &::getCppuType((const OUString*)0),  PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_IS_DATA_BASE_FORMAT),FIELD_PROP_BOOL1, &::getBooleanCppuType()  , PROPERTY_NONE,0},
+                {SW_PROP_NAME(UNO_NAME_NUMBER_FORMAT),      FIELD_PROP_FORMAT, &::getCppuType((const sal_Int32*)0), PROPERTY_NONE,  0},
+                {0,0,0,0}
+            };
+            pRet = aDBFieldPropMap;
+        }
+        break;
+        case SW_SERVICE_FIELDTYPE_DATABASE_NAME         :
+        {
+            static SfxItemPropertyMap aDBNameFieldPropMap       [] =
+            {
+                {SW_PROP_NAME(UNO_NAME_DATA_BASE_NAME ) , FIELD_PROP_PAR1, &::getCppuType((const OUString*)0),   PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_DATA_TABLE_NAME) , FIELD_PROP_PAR2, &::getCppuType((const OUString*)0),   PROPERTY_NONE, 0},
+                {0,0,0,0}
+            };
+            pRet = aDBNameFieldPropMap;
+        }
+        break;
+        case SW_SERVICE_FIELDTYPE_PAGE_COUNT            :
+        case SW_SERVICE_FIELDTYPE_PARAGRAPH_COUNT       :
+        case SW_SERVICE_FIELDTYPE_WORD_COUNT            :
+        case SW_SERVICE_FIELDTYPE_CHARACTER_COUNT       :
+        case SW_SERVICE_FIELDTYPE_TABLE_COUNT           :
+        case SW_SERVICE_FIELDTYPE_GRAPHIC_OBJECT_COUNT  :
+        case SW_SERVICE_FIELDTYPE_EMBEDDED_OBJECT_COUNT :
+        {
+            static SfxItemPropertyMap aDocstatFieldPropMap      [] =
+            {
+                {SW_PROP_NAME(UNO_NAME_NUMBERING_TYPE),     FIELD_PROP_USHORT2, &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, 0},
+            //  {UNO_NAME_STATISTIC_TYPE_ID,FIELD_PROP_USHORT1, &::getCppuType((const sal_Int16*)0),    PROPERTY_NONE,  0},
+                {0,0,0,0}
+            };
+            pRet = aDocstatFieldPropMap;
+        }
+        break;
+        case SW_SERVICE_FIELDTYPE_DOCINFO_CHANGE_AUTHOR :
+        case SW_SERVICE_FIELDTYPE_DOCINFO_CREATE_AUTHOR :
+        case SW_SERVICE_FIELDTYPE_DOCINFO_PRINT_AUTHOR      :
+        {
+            static SfxItemPropertyMap aDocInfoAuthorPropMap         [] =
+            {
+                {SW_PROP_NAME(UNO_NAME_AUTHOR), FIELD_PROP_PAR1,    &::getCppuType((const OUString*)0), PROPERTY_NONE,  0},
+                {SW_PROP_NAME(UNO_NAME_CURRENT_PRESENTATION), FIELD_PROP_PAR3, &::getCppuType((const OUString*)0),  PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_IS_FIXED),   FIELD_PROP_BOOL1,   &::getBooleanCppuType()  , PROPERTY_NONE,0},
+                {0,0,0,0}
+            };
+            pRet = aDocInfoAuthorPropMap;
+        }
+        break;
+        case SW_SERVICE_FIELDTYPE_DOCINFO_PRINT_DATE_TIME   :
+        case SW_SERVICE_FIELDTYPE_DOCINFO_CHANGE_DATE_TIME:
+        case SW_SERVICE_FIELDTYPE_DOCINFO_CREATE_DATE_TIME:
+        {
+            static SfxItemPropertyMap aDocInfoDateTimePropMap           [] =
+            {
+                {SW_PROP_NAME(UNO_NAME_CURRENT_PRESENTATION), FIELD_PROP_PAR3, &::getCppuType((const OUString*)0),  PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_DATETIME),       FIELD_PROP_DOUBLE,  &::getCppuType((const Double*)0), PropertyAttribute::READONLY,  0},
+                {SW_PROP_NAME(UNO_NAME_IS_DATE),    FIELD_PROP_BOOL2,   &::getBooleanCppuType()  , PROPERTY_NONE,0},
+                {SW_PROP_NAME(UNO_NAME_NUMBER_FORMAT),FIELD_PROP_FORMAT,    &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_IS_FIXED),       FIELD_PROP_BOOL1,   &::getBooleanCppuType()  , PROPERTY_NONE,   0},
+                {0,0,0,0}
+            };
+            pRet = aDocInfoDateTimePropMap;
+        }
+        break;
+        case SW_SERVICE_FIELDTYPE_DOCINFO_EDIT_TIME     :
+        {
+            static SfxItemPropertyMap aDocInfoEditTimePropMap           [] =
+            {
+                {SW_PROP_NAME(UNO_NAME_CURRENT_PRESENTATION), FIELD_PROP_PAR3, &::getCppuType((const OUString*)0),  PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_DATETIME),       FIELD_PROP_DOUBLE,  &::getCppuType((const Double*)0), PropertyAttribute::READONLY,  0},
+                {SW_PROP_NAME(UNO_NAME_NUMBER_FORMAT),FIELD_PROP_FORMAT,    &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_IS_FIXED),       FIELD_PROP_BOOL1,   &::getBooleanCppuType()  , PROPERTY_NONE,   0},
+                {0,0,0,0}
+            };
+            pRet = aDocInfoEditTimePropMap;
+        }
+        break;
+        case SW_SERVICE_FIELDTYPE_DOCINFO_DESCRIPTION   :
+        case SW_SERVICE_FIELDTYPE_DOCINFO_INFO_0:
+        case SW_SERVICE_FIELDTYPE_DOCINFO_INFO_1:
+        case SW_SERVICE_FIELDTYPE_DOCINFO_INFO_2:
+        case SW_SERVICE_FIELDTYPE_DOCINFO_INFO_3:
+        case SW_SERVICE_FIELDTYPE_DOCINFO_KEY_WORDS         :
+        case SW_SERVICE_FIELDTYPE_DOCINFO_SUBJECT           :
+        case SW_SERVICE_FIELDTYPE_DOCINFO_TITLE             :
+        {
+            static SfxItemPropertyMap aDocInfoStringContentPropMap          [] =
+            {
+                {SW_PROP_NAME(UNO_NAME_CONTENT),    FIELD_PROP_PAR1,    &::getCppuType((const OUString*)0), PROPERTY_NONE,  0},
+                {SW_PROP_NAME(UNO_NAME_CURRENT_PRESENTATION), FIELD_PROP_PAR3, &::getCppuType((const OUString*)0),  PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_IS_FIXED),   FIELD_PROP_BOOL1,   &::getBooleanCppuType()  , PROPERTY_NONE,0},
+                {0,0,0,0}
+            };
+            pRet = aDocInfoStringContentPropMap;
+        }
+        break;
+        case SW_SERVICE_FIELDTYPE_DOCINFO_REVISION          :
+        {
+            static SfxItemPropertyMap aDocInfoRevisionPropMap   [] =
+            {
+                {SW_PROP_NAME(UNO_NAME_CURRENT_PRESENTATION), FIELD_PROP_PAR3, &::getCppuType((const OUString*)0),  PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_REVISION),   FIELD_PROP_USHORT1, &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_IS_FIXED),   FIELD_PROP_BOOL1,   &::getBooleanCppuType()  , PROPERTY_NONE,0},
+                {0,0,0,0}
+            };
+            pRet = aDocInfoRevisionPropMap;
+        }
+        break;
+        case SW_SERVICE_FIELDTYPE_DUMMY_0 :
+        case SW_SERVICE_FIELDTYPE_DUMMY_1:
+        case SW_SERVICE_FIELDTYPE_DUMMY_2:
+        case SW_SERVICE_FIELDTYPE_DUMMY_3:
+        case SW_SERVICE_FIELDTYPE_DUMMY_4:
+        case SW_SERVICE_FIELDTYPE_DUMMY_5:
+        case SW_SERVICE_FIELDTYPE_DUMMY_6:
+        case SW_SERVICE_FIELDTYPE_DUMMY_7:
+        case SW_SERVICE_FIELDTYPE_DUMMY_8:
+        case SW_SERVICE_FIELDTYPE_TABLEFIELD            :
+        {
+            static SfxItemPropertyMap aEmptyPropMap         [] =
+            {
+                {0,0,0,0}
+            };
+            pRet = aEmptyPropMap;
+        }
+        break;
+        case SW_SERVICE_FIELDMASTER_USER :
+        {
+            static SfxItemPropertyMap aUserFieldTypePropMap[] =
+            {
+#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) || (defined(__GNUC__) && defined(__APPLE__))
+                {SW_PROP_NAME(UNO_NAME_DEPENDENT_TEXT_FIELDS),  0,  new uno::Type(::getCppuType((Sequence >*)0)), PropertyAttribute::READONLY, 0},
+#else
+                {SW_PROP_NAME(UNO_NAME_DEPENDENT_TEXT_FIELDS),  0,  &::getCppuType((Sequence >*)0), PropertyAttribute::READONLY, 0},
+#endif
+                {SW_PROP_NAME(UNO_NAME_IS_EXPRESSION),      0,  &::getBooleanCppuType(), PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_NAME),               0,  &::getCppuType((const OUString*)0), PROPERTY_NONE,  0},
+                {SW_PROP_NAME(UNO_NAME_VALUE),          0,  &::getCppuType((const Double*)0), PROPERTY_NONE,    0},
+                {SW_PROP_NAME(UNO_NAME_CONTENT),            0,  &::getCppuType((const OUString*)0), PROPERTY_NONE,  0},
+                {0,0,0,0}
+            };
+            pRet = aUserFieldTypePropMap;
+        }
+        break;
+        case SW_SERVICE_FIELDMASTER_DDE         :
+        {
+            static SfxItemPropertyMap aDDEFieldTypePropMap[] =
+            {
+                {SW_PROP_NAME(UNO_NAME_DDE_COMMAND_ELEMENT ), 0,    &::getCppuType((const OUString*)0), PROPERTY_NONE,  0},
+                {SW_PROP_NAME(UNO_NAME_DDE_COMMAND_FILE    ), 0,    &::getCppuType((const OUString*)0), PROPERTY_NONE,  0},
+                {SW_PROP_NAME(UNO_NAME_DDE_COMMAND_TYPE    ), 0,    &::getCppuType((const OUString*)0), PROPERTY_NONE,  0},
+                {SW_PROP_NAME(UNO_NAME_IS_AUTOMATIC_UPDATE), 0,  &::getBooleanCppuType(), PROPERTY_NONE,    0},
+                {SW_PROP_NAME(UNO_NAME_NAME),               0,  &::getCppuType((const OUString*)0), PROPERTY_NONE,  0},
+                {0,0,0,0}
+            };
+            pRet = aDDEFieldTypePropMap;
+        }
+        break;
+        case SW_SERVICE_FIELDMASTER_SET_EXP     :
+        {
+            static SfxItemPropertyMap aSetExpFieldTypePropMap[] =
+            {
+                {SW_PROP_NAME(UNO_NAME_CHAPTER_NUMBERING_LEVEL),0,  &::getCppuType((sal_Int8*)0), PROPERTY_NONE,    0},
+#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) || (defined(__GNUC__) && defined(__APPLE__))
+                {SW_PROP_NAME(UNO_NAME_DEPENDENT_TEXT_FIELDS),  0,  new uno::Type(::getCppuType((Sequence >*)0)), PropertyAttribute::READONLY, 0},
+#else
+                {SW_PROP_NAME(UNO_NAME_DEPENDENT_TEXT_FIELDS),  0,  &::getCppuType((Sequence >*)0), PropertyAttribute::READONLY, 0},
+#endif
+                {SW_PROP_NAME(UNO_NAME_NAME),               0,  &::getCppuType((const OUString*)0), PROPERTY_NONE,  0},
+                {SW_PROP_NAME(UNO_NAME_NUMBERING_SEPARATOR), 0, &::getCppuType((const OUString*)0), PROPERTY_NONE,  0},
+                {SW_PROP_NAME(UNO_NAME_SUB_TYPE),           0,  &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, 0},
+                {0,0,0,0}
+            };
+            pRet = aSetExpFieldTypePropMap;
+        }
+        break;
+        case SW_SERVICE_FIELDMASTER_DATABASE    :
+        {
+            static SfxItemPropertyMap aDBFieldTypePropMap           [] =
+            {
+                {SW_PROP_NAME(UNO_NAME_DATA_BASE_NAME   ), 0, &::getCppuType((const OUString*)0),   PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_DATA_TABLE_NAME  ), 0, &::getCppuType((const OUString*)0),   PROPERTY_NONE, 0},
+                {SW_PROP_NAME(UNO_NAME_DATA_COLUMN_NAME ), 0, &::getCppuType((const OUString*)0),   PROPERTY_NONE, 0},
+#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) || (defined(__GNUC__) && defined(__APPLE__))
+                {SW_PROP_NAME(UNO_NAME_DEPENDENT_TEXT_FIELDS),  0,  new uno::Type(::getCppuType((Sequence >*)0)), PropertyAttribute::READONLY, 0},
+#else
+                {SW_PROP_NAME(UNO_NAME_DEPENDENT_TEXT_FIELDS),  0,  &::getCppuType((Sequence >*)0), PropertyAttribute::READONLY, 0},
+#endif
+                {0,0,0,0}
+            };
+            pRet = aDBFieldTypePropMap;
+        }
+        break;
+        case SW_SERVICE_FIELDMASTER_DUMMY1      :
+        case SW_SERVICE_FIELDMASTER_DUMMY2      :
+        case SW_SERVICE_FIELDMASTER_DUMMY3      :
+        case SW_SERVICE_FIELDMASTER_DUMMY4      :
+        case SW_SERVICE_FIELDMASTER_DUMMY5      :
+        {
+            static SfxItemPropertyMap aStandardFieldMasterMap[] =
+            {
+#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) || (defined(__GNUC__) && defined(__APPLE__))
+                {SW_PROP_NAME(UNO_NAME_DEPENDENT_TEXT_FIELDS),  0,  new uno::Type(::getCppuType((Sequence >*)0)), PropertyAttribute::READONLY, 0},
+#else
+                {SW_PROP_NAME(UNO_NAME_DEPENDENT_TEXT_FIELDS),  0,  &::getCppuType((Sequence >*)0), PropertyAttribute::READONLY, 0},
+#endif
+                {SW_PROP_NAME(UNO_NAME_NAME),               0,  &::getCppuType((const OUString*)0), PROPERTY_NONE,  0},
+                {0,0,0,0}
+            };
+            pRet = aStandardFieldMasterMap;
+        }
+        break;
+    }
+    DBG_ASSERT(pRet, "illegal service id")
+    return pRet;
+};
+
+const sal_uInt16 aDocInfoSubTypeFromService[] =
+{
+    DI_CHANGE|DI_SUB_AUTHOR,    //SW_SERVICE_FIELDTYPE_DOCINFO_CHANGE_AUTHOR
+    DI_CHANGE|DI_SUB_DATE,      //SW_SERVICE_FIELDTYPE_DOCINFO_CHANGE_DATE_TIME
+    DI_EDIT|DI_SUB_TIME,        //SW_SERVICE_FIELDTYPE_DOCINFO_EDIT_TIME
+    DI_COMMENT,                 //SW_SERVICE_FIELDTYPE_DOCINFO_DESCRIPTION
+    DI_CREATE|DI_SUB_AUTHOR,    //SW_SERVICE_FIELDTYPE_DOCINFO_CREATE_AUTHOR
+    DI_CREATE|DI_SUB_DATE,      //SW_SERVICE_FIELDTYPE_DOCINFO_CREATE_DATE_TIME
+    DI_INFO1,                   //SW_SERVICE_FIELDTYPE_DOCINFO_INFO_0
+    DI_INFO2,                   //SW_SERVICE_FIELDTYPE_DOCINFO_INFO_1
+    DI_INFO3,                   //SW_SERVICE_FIELDTYPE_DOCINFO_INFO_2
+    DI_INFO4,                   //SW_SERVICE_FIELDTYPE_DOCINFO_INFO_3
+    DI_PRINT|DI_SUB_AUTHOR,     //SW_SERVICE_FIELDTYPE_DOCINFO_PRINT_AUTHOR
+    DI_PRINT|DI_SUB_DATE,       //SW_SERVICE_FIELDTYPE_DOCINFO_PRINT_DATE_TIME
+    DI_KEYS,                    //SW_SERVICE_FIELDTYPE_DOCINFO_KEY_WORDS
+    DI_THEMA,                   //SW_SERVICE_FIELDTYPE_DOCINFO_SUBJECT
+    DI_TITEL,                   //SW_SERVICE_FIELDTYPE_DOCINFO_TITLE
+    DI_DOCNO                    //SW_SERVICE_FIELDTYPE_DOCINFO_REVISION
+};
+struct ServiceIdResId
+{
+    USHORT nResId;
+    USHORT nServiceId;
+};
+const ServiceIdResId aServiceToRes[] =
+{
+    {RES_DATETIMEFLD,   SW_SERVICE_FIELDTYPE_DATETIME               },
+    {RES_USERFLD,       SW_SERVICE_FIELDTYPE_USER                   },
+    {RES_SETEXPFLD,         SW_SERVICE_FIELDTYPE_SET_EXP            }    ,
+    {RES_GETEXPFLD,         SW_SERVICE_FIELDTYPE_GET_EXP            }    ,
+    {RES_FILENAMEFLD,   SW_SERVICE_FIELDTYPE_FILE_NAME              },
+    {RES_PAGENUMBERFLD,     SW_SERVICE_FIELDTYPE_PAGE_NUM           }    ,
+    {RES_AUTHORFLD,         SW_SERVICE_FIELDTYPE_AUTHOR             }    ,
+    {RES_CHAPTERFLD,    SW_SERVICE_FIELDTYPE_CHAPTER                },
+    {RES_GETREFFLD,         SW_SERVICE_FIELDTYPE_GET_REFERENCE      }    ,
+    {RES_HIDDENTXTFLD,  SW_SERVICE_FIELDTYPE_CONDITIONED_TEXT       },
+    {RES_POSTITFLD,         SW_SERVICE_FIELDTYPE_ANNOTATION         }    ,
+    {RES_INPUTFLD,      SW_SERVICE_FIELDTYPE_INPUT                  },
+    {RES_MACROFLD,      SW_SERVICE_FIELDTYPE_MACRO                  },
+    {RES_DDEFLD,        SW_SERVICE_FIELDTYPE_DDE                    },
+    {RES_HIDDENPARAFLD,     SW_SERVICE_FIELDTYPE_HIDDEN_PARA        }    ,
+    {RES_DOCINFOFLD,    SW_SERVICE_FIELDTYPE_DOC_INFO               },
+    {RES_TEMPLNAMEFLD,  SW_SERVICE_FIELDTYPE_TEMPLATE_NAME          },
+    {RES_EXTUSERFLD,    SW_SERVICE_FIELDTYPE_USER_EXT               },
+    {RES_REFPAGESETFLD,     SW_SERVICE_FIELDTYPE_REF_PAGE_SET       }    ,
+    {RES_REFPAGEGETFLD,     SW_SERVICE_FIELDTYPE_REF_PAGE_GET       }    ,
+    {RES_JUMPEDITFLD,   SW_SERVICE_FIELDTYPE_JUMP_EDIT              },
+    {RES_SCRIPTFLD,         SW_SERVICE_FIELDTYPE_SCRIPT             }    ,
+    {RES_DBNEXTSETFLD,  SW_SERVICE_FIELDTYPE_DATABASE_NEXT_SET      },
+    {RES_DBNUMSETFLD,   SW_SERVICE_FIELDTYPE_DATABASE_NUM_SET       },
+    {RES_DBSETNUMBERFLD, SW_SERVICE_FIELDTYPE_DATABASE_SET_NUM      } ,
+    {RES_DBFLD,             SW_SERVICE_FIELDTYPE_DATABASE           }    ,
+    {RES_DBNAMEFLD,     SW_SERVICE_FIELDTYPE_DATABASE_NAME          },
+    {RES_DOCSTATFLD,    SW_SERVICE_FIELDTYPE_PAGE_COUNT             },
+    {RES_DOCSTATFLD,    SW_SERVICE_FIELDTYPE_PARAGRAPH_COUNT        },
+    {RES_DOCSTATFLD,    SW_SERVICE_FIELDTYPE_WORD_COUNT             },
+    {RES_DOCSTATFLD,    SW_SERVICE_FIELDTYPE_CHARACTER_COUNT        },
+    {RES_DOCSTATFLD,    SW_SERVICE_FIELDTYPE_TABLE_COUNT            },
+    {RES_DOCSTATFLD,    SW_SERVICE_FIELDTYPE_GRAPHIC_OBJECT_COUNT   },
+    {RES_DOCSTATFLD,    SW_SERVICE_FIELDTYPE_EMBEDDED_OBJECT_COUNT  },
+    {RES_DOCINFOFLD,    SW_SERVICE_FIELDTYPE_DOCINFO_CHANGE_AUTHOR  },
+    {RES_DOCINFOFLD,        SW_SERVICE_FIELDTYPE_DOCINFO_CHANGE_DATE_TIME},
+    {RES_DOCINFOFLD,        SW_SERVICE_FIELDTYPE_DOCINFO_EDIT_TIME       },
+    {RES_DOCINFOFLD,        SW_SERVICE_FIELDTYPE_DOCINFO_DESCRIPTION     },
+    {RES_DOCINFOFLD,        SW_SERVICE_FIELDTYPE_DOCINFO_CREATE_AUTHOR   },
+    {RES_DOCINFOFLD,        SW_SERVICE_FIELDTYPE_DOCINFO_CREATE_DATE_TIME},
+    {RES_DOCINFOFLD,        SW_SERVICE_FIELDTYPE_DOCINFO_INFO_0          },
+    {RES_DOCINFOFLD,        SW_SERVICE_FIELDTYPE_DOCINFO_INFO_1          },
+    {RES_DOCINFOFLD,        SW_SERVICE_FIELDTYPE_DOCINFO_INFO_2          },
+    {RES_DOCINFOFLD,        SW_SERVICE_FIELDTYPE_DOCINFO_INFO_3          },
+    {RES_DOCINFOFLD,        SW_SERVICE_FIELDTYPE_DOCINFO_PRINT_AUTHOR    },
+    {RES_DOCINFOFLD,        SW_SERVICE_FIELDTYPE_DOCINFO_PRINT_DATE_TIME },
+    {RES_DOCINFOFLD,        SW_SERVICE_FIELDTYPE_DOCINFO_KEY_WORDS       },
+    {RES_DOCINFOFLD,        SW_SERVICE_FIELDTYPE_DOCINFO_SUBJECT         },
+    {RES_DOCINFOFLD,        SW_SERVICE_FIELDTYPE_DOCINFO_TITLE           },
+    {RES_INPUTFLD,      SW_SERVICE_FIELDTYPE_INPUT_USER                  },
+    {RES_HIDDENTXTFLD,  SW_SERVICE_FIELDTYPE_HIDDEN_TEXT                 },
+    {USHRT_MAX,         USHRT_MAX                                        }
+};
+//-----------------------------------------------------------------
+sal_uInt16 lcl_ServiceIdToResId(sal_uInt16 nServiceId)
+{
+    USHORT nIndex = 0;
+    while(aServiceToRes[nIndex].nServiceId != USHRT_MAX)
+    {
+        if(aServiceToRes[nIndex].nServiceId == nServiceId)
+            return aServiceToRes[nIndex].nResId;
+        nIndex++;
+    }
+    DBG_ERROR("service id not found")
+    return USHRT_MAX;
+}
+//-----------------------------------------------------------------
+sal_uInt16 lcl_GetServiceForResId(sal_uInt16 nWhich)
+{
+    USHORT nIndex = 0;
+    while(aServiceToRes[nIndex].nResId != USHRT_MAX)
+    {
+        if(aServiceToRes[nIndex].nResId == nWhich)
+            return aServiceToRes[nIndex].nServiceId;
+        nIndex++;
+    }
+    DBG_ERROR("resid id not found")
+    return USHRT_MAX;
+}
+/******************************************************************
+ * SwXFieldMaster
+ ******************************************************************/
+TYPEINIT1(SwXFieldMaster, SwClient);
+/* -----------------------------13.03.00 12:15--------------------------------
+
+ ---------------------------------------------------------------------------*/
+const ::com::sun::star::uno::Sequence< sal_Int8 > & SwXFieldMaster::getUnoTunnelId()
+{
+    static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId();
+    return aSeq;
+}
+/* -----------------------------10.03.00 18:04--------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Int64 SAL_CALL SwXFieldMaster::getSomething( const uno::Sequence< sal_Int8 >& rId )
+    throw(uno::RuntimeException)
+{
+    if( rId.getLength() == 16
+        && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+                                        rId.getConstArray(), 16 ) )
+    {
+            return (sal_Int64)this;
+    }
+    return 0;
+}
+/* -----------------------------06.04.00 13:22--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXFieldMaster::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXFieldMaster");
+}
+/* -----------------------------06.04.00 13:22--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXFieldMaster::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.text.FieldMaster") == rServiceName;
+}
+/* -----------------------------06.04.00 13:22--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXFieldMaster::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.FieldMaster");
+    return aRet;
+}
+/*-- 14.12.98 11:08:33---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXFieldMaster::SwXFieldMaster(SwDoc* pDoc, sal_uInt16 nResId) :
+    m_pDoc(pDoc),
+    aLstnrCntnr( (XPropertySet*)this),
+    nResTypeId(nResId),
+    m_bIsDescriptor(sal_True),
+    fParam1(0.),
+    bParam1(FALSE),
+    nParam1(-1)
+{
+
+}
+/*-- 14.12.98 11:08:33---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXFieldMaster::SwXFieldMaster(SwFieldType& rType, SwDoc* pDoc) :
+    SwClient(&rType),
+    aLstnrCntnr( (XPropertySet*)this),
+    m_pDoc(pDoc),
+    nResTypeId(rType.Which()),
+    m_bIsDescriptor(sal_False),
+    fParam1(0.),
+    nParam1(-1),
+    bParam1(FALSE)
+{
+
+}
+/*-- 14.12.98 11:08:34---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXFieldMaster::~SwXFieldMaster()
+{
+
+}
+/*-- 14.12.98 11:08:35---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XPropertySetInfo >  SwXFieldMaster::getPropertySetInfo(void)
+                                            throw( uno::RuntimeException )
+{
+    vos::OGuard  aGuard(Application::GetSolarMutex());
+    const SfxItemPropertyMap* pCreate = SwFieldPropMapProvider::GetPropertyMap(SW_SERVICE_FIELDMASTER_DUMMY1);
+    if(nResTypeId == RES_USERFLD)
+        pCreate = SwFieldPropMapProvider::GetPropertyMap(SW_SERVICE_FIELDMASTER_USER);
+    else if(nResTypeId == RES_DBFLD)
+        pCreate = SwFieldPropMapProvider::GetPropertyMap(SW_SERVICE_FIELDMASTER_DATABASE);
+    else if(nResTypeId == RES_SETEXPFLD)
+        pCreate = SwFieldPropMapProvider::GetPropertyMap(SW_SERVICE_FIELDMASTER_SET_EXP);
+    else if(nResTypeId == RES_DDEFLD)
+        pCreate = SwFieldPropMapProvider::GetPropertyMap(SW_SERVICE_FIELDMASTER_DDE);
+    uno::Reference< XPropertySetInfo >  aRef = new SfxItemPropertySetInfo(pCreate);
+    return aRef;
+}
+/*-- 14.12.98 11:08:35---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFieldMaster::setPropertyValue(const OUString& rPropertyName, const uno::Any& aValue)
+    throw( UnknownPropertyException, PropertyVetoException,
+            IllegalArgumentException, WrappedTargetException, uno::RuntimeException)
+{
+    vos::OGuard  aGuard(Application::GetSolarMutex());
+    SwFieldType* pType = GetFldType();
+    if(pType)
+    {
+        sal_Bool bSetValue = sal_True;
+        if(COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_SUB_TYPE))
+        {
+            const SvStringsDtor& rExtraArr = m_pDoc->GetExtraNmArray();
+            String sTypeName = pType->GetName();
+            static sal_uInt16 nIds[] =
+            {
+                RES_POOLCOLL_LABEL_DRAWING - RES_POOLCOLL_EXTRA_BEGIN,
+                RES_POOLCOLL_LABEL_ABB - RES_POOLCOLL_EXTRA_BEGIN,
+                RES_POOLCOLL_LABEL_TABLE - RES_POOLCOLL_EXTRA_BEGIN,
+                RES_POOLCOLL_LABEL_FRAME- RES_POOLCOLL_EXTRA_BEGIN,
+                0
+            };
+            for(const sal_uInt16 * pIds = nIds; *pIds; ++pIds)
+            {
+                if(sTypeName == *rExtraArr[ *pIds ] )
+                {
+                    bSetValue = sal_False;
+                    break;
+                }
+            }
+        }
+        if(bSetValue)
+            pType->PutValue(aValue, rPropertyName);
+    }
+    else if(!pType && m_pDoc &&
+        ( COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_NAME)
+            || COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_DATA_BASE_NAME)))
+    {
+        OUString uTmp;
+        aValue >>= uTmp;
+        String sTypeName(uTmp);
+        SwFieldType* pType = m_pDoc->GetFldType(nResTypeId, sTypeName);
+        if(pType)
+        {
+            throw IllegalArgumentException();
+        }
+        else
+        {
+            switch(nResTypeId)
+            {
+                case RES_USERFLD :
+                {
+                    SwUserFieldType aType(m_pDoc, sTypeName);
+                    pType = m_pDoc->InsertFldType(aType);
+                    ((SwUserFieldType*)pType)->SetContent(sParam1);
+                    ((SwUserFieldType*)pType)->SetValue(fParam1);
+                    ((SwUserFieldType*)pType)->SetType(bParam1 ? GSE_EXPR : GSE_STRING);
+                }
+                break;
+                case RES_DBFLD :
+                {
+                    String sDBName = sTypeName;//dbname
+                    sDBName += DB_DELIM;
+                    sDBName += sParam2; //table
+                    //sParam3 //column
+                    SwDBFieldType aType(m_pDoc, sParam3,  sDBName);
+                    pType = m_pDoc->InsertFldType(aType);
+                }
+                break;
+                case RES_DDEFLD :
+                {
+                    SwDDEFieldType aType(sTypeName, sParam1,
+                                bParam1 ? LINKUPDATE_ALWAYS : LINKUPDATE_ONCALL);
+                    pType = m_pDoc->InsertFldType(aType);
+                }
+                break;
+                case RES_SETEXPFLD :
+                {
+                    SwSetExpFieldType aType(m_pDoc, sTypeName);
+                    if(sParam1.Len())
+                        aType.SetDelimiter( sParam1.GetChar(0));
+                    if(nParam1 > -1 && nParam1 < MAXLEVEL)
+                        aType.SetOutlineLvl(nParam1);
+                    pType = m_pDoc->InsertFldType(aType);
+                }
+                break;
+            }
+            if(pType)
+                pType->Add(this);
+            else
+                throw uno::RuntimeException();
+        }
+
+        DBG_ASSERT(pType, "kein FieldType gefunden!" );
+        pType->Add(this);
+    }
+    else
+    {
+        if(nResTypeId == RES_USERFLD)
+        {
+            if(COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_CONTENT))
+            {
+                OUString uTmp;
+                aValue >>= uTmp;
+                sParam1 = String(uTmp);
+            }
+            else if(COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_VALUE ))
+            {
+                if(aValue.getValueType() != ::getCppuType((const Double*)0))
+                    throw IllegalArgumentException();
+                fParam1 = *(Double*)aValue.getValue();
+            }
+            else if(COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_IS_EXPRESSION ))
+            {
+                if(aValue.getValueType() != ::getBooleanCppuType())
+                    throw IllegalArgumentException();
+                bParam1 = *(sal_Bool*)aValue.getValue();
+            }
+        }
+        else if(RES_DBFLD == nResTypeId)
+        {
+            OUString uTmp;
+            aValue >>= uTmp;
+            String sTmp(uTmp);
+            if(COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_DATA_BASE_NAME))
+                sParam1 = sTmp;
+            if(COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_DATA_TABLE_NAME))
+                sParam2 = sTmp;
+            if(COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_DATA_COLUMN_NAME))
+                sParam3 = sTmp;
+        }
+        else if(RES_SETEXPFLD == nResTypeId)
+        {
+            if(COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_NUMBERING_SEPARATOR))
+            {
+                OUString uTmp;
+                aValue >>= uTmp;
+                sParam1 = uTmp;
+            }
+            else if(COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_CHAPTER_NUMBERING_LEVEL))
+            {
+                aValue >>= nParam1;
+            }
+        }
+        else if(RES_SETEXPFLD == nResTypeId)
+        {
+            USHORT nPart = COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_DDE_COMMAND_TYPE)  ? 0 :
+                COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_DDE_COMMAND_FILE)  ? 1 :
+                    COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_DDE_COMMAND_ELEMENT)  ? 2 :
+                    COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_IS_AUTOMATIC_UPDATE) ? 3 : USHRT_MAX;
+            if(nPart  < 3 )
+            {
+                OUString uTmp;
+                aValue >>= uTmp;
+                if(!sParam1.Len())
+                {
+                    sParam1 = cTokenSeperator;
+                    sParam1 += cTokenSeperator;
+                }
+                sParam1.SetToken(nPart, cTokenSeperator, uTmp);
+            }
+            else if(3 == nPart)
+            {
+                bParam1 = *(sal_Bool*)aValue.getValue();
+            }
+        }
+        else
+            throw UnknownPropertyException();
+    }
+
+}
+/*-- 14.12.98 11:08:36---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+typedef SwFmtFld* SwFmtFldPtr;
+SV_DECL_PTRARR(SwDependentFields, SwFmtFldPtr, 5, 5)
+SV_IMPL_PTRARR(SwDependentFields, SwFmtFldPtr)
+
+uno::Any SwXFieldMaster::getPropertyValue(const OUString& rPropertyName)
+        throw( UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard  aGuard(Application::GetSolarMutex());
+    uno::Any aRet;
+    SwFieldType* pType = GetFldType();
+    if(pType)
+    {
+        if(COMPARE_EQUAL == rPropertyName.compareToAscii("Name"))
+            aRet <<= OUString(pType->GetName());
+        else if(COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_DEPENDENT_TEXT_FIELDS))
+        {
+            //fill all text fields into a sequence
+            SwClientIter aIter( *pType );
+            SwDependentFields aFldArr;
+            SwFmtFldPtr pFld = (SwFmtFld*)aIter.First( TYPE( SwFmtFld ));
+            while(pFld)
+            {
+                if(pFld->IsFldInDoc())
+                    aFldArr.Insert(pFld, aFldArr.Count());
+                pFld = (SwFmtFld*)aIter.Next();
+            }
+            Sequence > aRetSeq(aFldArr.Count());
+            Reference* pRetSeq = aRetSeq.getArray();
+            SwXTextField* pInsert = 0;
+            for(int i = 0; i < aFldArr.Count(); i++)
+            {
+                pFld = aFldArr.GetObject(i);
+                SwXTextField* pTemp = (SwXTextField*)aIter.First(TYPE(SwXTextField));
+                while(pTemp)
+                {
+                    if(pTemp->GetFldFmt() == pFld)
+                    {
+                        pInsert = pTemp;
+                        break;
+                    }
+                    pTemp = (SwXTextField*)aIter.Next();
+                }
+                if(!pInsert)
+                    pInsert = new SwXTextField( *pFld, GetDoc());
+                pRetSeq[i] = Reference(pInsert);
+                pInsert = 0;
+            }
+            aRet <<= aRetSeq;
+        }
+        else if(pType)
+        {   //TODO: Properties fuer die uebrigen Feldtypen einbauen
+            pType->QueryValue(aRet, rPropertyName);
+        }
+    }
+    else
+        throw uno::RuntimeException();
+    return aRet;
+}
+/*-- 14.12.98 11:08:36---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFieldMaster::addPropertyChangeListener(const OUString& PropertyName, const uno::Reference< XPropertyChangeListener > & aListener) throw( UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 14.12.98 11:08:36---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFieldMaster::removePropertyChangeListener(const OUString& PropertyName, const uno::Reference< XPropertyChangeListener > & aListener) throw( UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 14.12.98 11:08:37---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFieldMaster::addVetoableChangeListener(const OUString& PropertyName, const uno::Reference< XVetoableChangeListener > & aListener) throw( UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 14.12.98 11:08:37---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFieldMaster::removeVetoableChangeListener(const OUString& PropertyName, const uno::Reference< XVetoableChangeListener > & aListener) throw( UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+
+/*-- 25.02.99 11:01:57---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFieldMaster::dispose(void)          throw( uno::RuntimeException )
+{
+    vos::OGuard  aGuard(Application::GetSolarMutex());
+    SwFieldType* pFldType = GetFldType();
+    if(pFldType)
+    {
+        sal_uInt16 nTypeIdx = USHRT_MAX;
+        const SwFldTypes* pTypes = GetDoc()->GetFldTypes();
+        for( sal_uInt16 i = 0; i < pTypes->Count(); i++ )
+        {
+            if((*pTypes)[i] == pFldType)
+                nTypeIdx = i;
+        }
+
+        // zuerst alle Felder loeschen
+        SwClientIter aIter( *pFldType );
+        SwFmtFld* pFld = (SwFmtFld*)aIter.First( TYPE( SwFmtFld ));
+        while(pFld)
+        {
+            // Feld im Undo?
+            SwTxtFld *pTxtFld = pFld->GetTxtFld();
+            if(pTxtFld && pTxtFld->GetTxtNode().GetNodes().IsDocNodes() )
+            {
+                SwTxtNode& rTxtNode = (SwTxtNode&)*pTxtFld->GetpTxtNode();
+                SwPaM aPam(rTxtNode, *pTxtFld->GetStart());
+                aPam.SetMark();
+                aPam.Move();
+                GetDoc()->DeleteAndJoin(aPam);
+            }
+            pFld = (SwFmtFld*)aIter.Next();
+        }
+        // dann den FieldType loeschen
+        GetDoc()->RemoveFldType(nTypeIdx);
+    }
+    else
+        throw uno::RuntimeException();
+}
+/*-- 25.02.99 11:02:00---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFieldMaster::addEventListener(const uno::Reference< XEventListener > & aListener)
+                                            throw( uno::RuntimeException )
+{
+    if(!GetRegisteredIn())
+        throw uno::RuntimeException();
+    aLstnrCntnr.AddListener(aListener);
+}
+/*-- 25.02.99 11:02:02---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFieldMaster::removeEventListener(const uno::Reference< XEventListener > & aListener)
+                                                    throw( uno::RuntimeException )
+{
+    if(!GetRegisteredIn() || !aLstnrCntnr.RemoveListener(aListener))
+        throw uno::RuntimeException();
+}
+
+/*-- 14.12.98 11:08:38---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFieldMaster::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew)
+{
+    ClientModify(this, pOld, pNew);
+    if(!GetRegisteredIn())
+    {
+        aLstnrCntnr.Disposing();
+        m_pDoc = 0;
+    }
+}
+/******************************************************************
+ *
+ ******************************************************************/
+struct SwFieldProperties_Impl
+{
+    String      sPar1;
+    String      sPar2;
+    String      sPar3;
+    String      sPar4;
+    sal_Int32       nSubType;
+    sal_Int32       nFormat;
+    sal_uInt16      nUSHORT1;
+    sal_uInt16      nUSHORT2;
+    sal_Int16       nSHORT1;
+    sal_Int8        nByte1;
+    sal_Bool        bBool1;
+    sal_Bool        bBool2;
+    sal_Bool        bBool3;
+    Date        aDate;
+    Double      fDouble;
+
+    SwFieldProperties_Impl():
+        nSubType(0),
+        nFormat(0),
+        nUSHORT1(0),
+        nUSHORT2(0),
+        nSHORT1(0),
+        nByte1(0),
+        fDouble(0.),
+        bBool1(sal_False),
+        bBool2(sal_False),
+        bBool3(sal_False)
+        {}
+};
+
+TYPEINIT1(SwXTextField, SwClient);
+/*-- 14.12.98 11:37:14---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+/*uno::Reference< uno::XInterface >  SwXTextField_NewInstance_Impl()
+{
+    return (UsrObject *)new SwXTextField(USHRT_MAX);
+};
+/* -----------------------------13.03.00 12:15--------------------------------
+
+ ---------------------------------------------------------------------------*/
+const ::com::sun::star::uno::Sequence< sal_Int8 > & SwXTextField::getUnoTunnelId()
+{
+    static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId();
+    return aSeq;
+}
+/* -----------------------------10.03.00 18:04--------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Int64 SAL_CALL SwXTextField::getSomething( const uno::Sequence< sal_Int8 >& rId )
+    throw(uno::RuntimeException)
+{
+    if( rId.getLength() == 16
+        && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+                                        rId.getConstArray(), 16 ) )
+    {
+            return (sal_Int64)this;
+    }
+    return 0;
+}
+/*-- 14.12.98 11:37:14---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextField::SwXTextField(sal_uInt16 nServiceId) :
+    pFmtFld(0),
+    aLstnrCntnr( (XTextContent*)this),
+    m_pDoc(0),
+    m_nServiceId(nServiceId),
+    m_bIsDescriptor(nServiceId != USHRT_MAX),
+    m_pProps(new SwFieldProperties_Impl)
+{
+    //Set visible as default!
+    if(SW_SERVICE_FIELDTYPE_SET_EXP == nServiceId)
+        m_pProps->bBool2 = sal_True;
+}
+/*-- 14.12.98 11:37:15---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextField::SwXTextField(const SwFmtFld& rFmt, SwDoc* pDc) :
+    pFmtFld(&rFmt),
+    aLstnrCntnr( (XTextContent*)this),
+    m_pDoc(pDc),
+    m_nServiceId(USHRT_MAX),
+    m_bIsDescriptor(sal_False),
+    m_pProps(0)
+{
+    pFmtFld->GetFld()->GetTyp()->Add(this);
+    //TODO: GetObject impl., darin soll das fuer dieses FmtFld bereits vorhandene
+    //Objekt gesucht werden
+    USHORT nResId(pFmtFld->GetFld()->GetTyp()->Which());
+    m_nServiceId = lcl_GetServiceForResId(nResId);
+    //special handling of SwInputField
+
+    if(RES_INPUTFLD == nResId && (((SwInputField*)pFmtFld->GetFld())->GetSubType()& 0x00ff) == INP_USR)
+        m_nServiceId = SW_SERVICE_FIELDTYPE_INPUT_USER;
+    else if(RES_DOCINFOFLD == nResId)
+    {
+        USHORT nSubType = ((SwDocInfoField*)pFmtFld->GetFld())->GetSubType();
+        if(DI_CHANGE == (nSubType & 0xff))
+        {
+            m_nServiceId = ((nSubType&0x300) == DI_SUB_AUTHOR) ?
+                SW_SERVICE_FIELDTYPE_DOCINFO_CHANGE_AUTHOR :
+                    SW_SERVICE_FIELDTYPE_DOCINFO_CHANGE_DATE_TIME;
+        }
+        else if(DI_CREATE == (nSubType & 0xff))
+        {
+            m_nServiceId = ((nSubType&0x300) == DI_SUB_AUTHOR) ?
+                SW_SERVICE_FIELDTYPE_DOCINFO_CREATE_AUTHOR :
+                    SW_SERVICE_FIELDTYPE_DOCINFO_CREATE_DATE_TIME;
+        }
+        else if(DI_PRINT == (nSubType & 0xff))
+        {
+            m_nServiceId = ((nSubType&0x300) == DI_SUB_AUTHOR) ?
+                SW_SERVICE_FIELDTYPE_DOCINFO_PRINT_AUTHOR :
+                    SW_SERVICE_FIELDTYPE_DOCINFO_PRINT_DATE_TIME;
+        }
+        else if(DI_EDIT == (nSubType & 0xff))
+            m_nServiceId = SW_SERVICE_FIELDTYPE_DOCINFO_EDIT_TIME;
+        else if(DI_COMMENT == (nSubType & 0xff))
+            m_nServiceId = SW_SERVICE_FIELDTYPE_DOCINFO_DESCRIPTION;
+        else if(DI_INFO1 == (nSubType & 0xff))
+            m_nServiceId = SW_SERVICE_FIELDTYPE_DOCINFO_INFO_0;
+        else if(DI_INFO2 == (nSubType & 0xff))
+            m_nServiceId = SW_SERVICE_FIELDTYPE_DOCINFO_INFO_1;
+        else if(DI_INFO3 == (nSubType & 0xff))
+            m_nServiceId = SW_SERVICE_FIELDTYPE_DOCINFO_INFO_2;
+        else if(DI_INFO4 == (nSubType & 0xff))
+            m_nServiceId = SW_SERVICE_FIELDTYPE_DOCINFO_INFO_3;
+        else if(DI_KEYS == (nSubType & 0xff))
+            m_nServiceId = SW_SERVICE_FIELDTYPE_DOCINFO_KEY_WORDS;
+        else if(DI_THEMA == (nSubType & 0xff))
+            m_nServiceId = SW_SERVICE_FIELDTYPE_DOCINFO_SUBJECT;
+        else if(DI_TITEL == (nSubType & 0xff))
+            m_nServiceId = SW_SERVICE_FIELDTYPE_DOCINFO_TITLE;
+        else if(DI_DOCNO == (nSubType & 0xff))
+            m_nServiceId = SW_SERVICE_FIELDTYPE_DOCINFO_REVISION;
+    }
+    else if(RES_HIDDENTXTFLD == nResId)
+    {
+        m_nServiceId = ((SwHiddenTxtField*)pFmtFld->GetFld())->GetSubType() == TYP_CONDTXTFLD ?
+            SW_SERVICE_FIELDTYPE_CONDITIONED_TEXT : SW_SERVICE_FIELDTYPE_HIDDEN_TEXT;
+    }
+    else if(RES_DOCSTATFLD == nResId)
+    {
+        switch(((SwDocStatField*)pFmtFld->GetFld())->GetSubType())
+        {
+            case DS_PAGE: m_nServiceId = SW_SERVICE_FIELDTYPE_PAGE_COUNT; break;
+            case DS_PARA: m_nServiceId = SW_SERVICE_FIELDTYPE_PARAGRAPH_COUNT; break;
+            case DS_WORD: m_nServiceId = SW_SERVICE_FIELDTYPE_WORD_COUNT     ; break;
+            case DS_CHAR: m_nServiceId = SW_SERVICE_FIELDTYPE_CHARACTER_COUNT; break;
+            case DS_TBL:  m_nServiceId = SW_SERVICE_FIELDTYPE_TABLE_COUNT    ; break;
+            case DS_GRF:  m_nServiceId = SW_SERVICE_FIELDTYPE_GRAPHIC_OBJECT_COUNT; break;
+            case DS_OLE:  m_nServiceId = SW_SERVICE_FIELDTYPE_EMBEDDED_OBJECT_COUNT; break;
+        }
+    }
+}
+/*-- 14.12.98 11:37:15---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextField::~SwXTextField()
+{
+    delete m_pProps;
+}
+/*-- 14.12.98 11:37:16---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextField::attachTextFieldMaster(const uno::Reference< XPropertySet > & xFieldMaster)
+                    throw( IllegalArgumentException, uno::RuntimeException )
+{
+    vos::OGuard  aGuard(Application::GetSolarMutex());
+    if(!m_bIsDescriptor)
+        throw uno::RuntimeException();
+    uno::Reference< XUnoTunnel > xMasterTunnel(xFieldMaster, uno::UNO_QUERY);
+    SwXFieldMaster* pMaster = (SwXFieldMaster*)xMasterTunnel->getSomething(
+                SwXFieldMaster::getUnoTunnelId());
+
+    SwFieldType* pFieldType = pMaster ? pMaster->GetFldType() : 0;
+    if(pFieldType && pFieldType->Which() == lcl_ServiceIdToResId(m_nServiceId))
+    {
+        m_sTypeName = pFieldType->GetName();
+    }
+    else
+        throw IllegalArgumentException();
+
+}
+/*-- 14.12.98 11:37:16---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XPropertySet >  SwXTextField::getTextFieldMaster(void) throw( uno::RuntimeException )
+{
+    vos::OGuard  aGuard(Application::GetSolarMutex());
+    SwFieldType* pType = GetFldType();
+    if(!pType)
+        throw uno::RuntimeException();
+    SwXFieldMaster* pMaster = (SwXFieldMaster*)
+                SwClientIter(*pType).First(TYPE(SwXFieldMaster));
+    if(!pMaster)
+        pMaster = new SwXFieldMaster(*pType, GetDoc());
+
+    return pMaster;
+}
+/*-- 14.12.98 11:37:16---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+OUString SwXTextField::getPresentation(sal_Bool bShowCommand) throw( uno::RuntimeException )
+{
+    vos::OGuard  aGuard(Application::GetSolarMutex());
+    OUString sRet;
+    const SwField* pField = GetField();
+    if(pField)
+        sRet = pField->GetCntnt(bShowCommand);
+    else
+        throw uno::RuntimeException();
+    return sRet;
+}
+/* -----------------18.02.99 13:39-------------------
+ *
+ * --------------------------------------------------*/
+void SwXTextField::attachToRange(
+        const uno::Reference< XTextRange > & xTextRange)
+    throw( IllegalArgumentException, uno::RuntimeException )
+{
+    vos::OGuard  aGuard(Application::GetSolarMutex());
+    if(!m_bIsDescriptor)
+        throw uno::RuntimeException();
+    uno::Reference xRangeTunnel( xTextRange, uno::UNO_QUERY);
+    SwXTextRange* pRange = 0;
+    SwXTextCursor* pCursor = 0;
+    if(xRangeTunnel.is())
+    {
+        pRange = (SwXTextRange*)xRangeTunnel->getSomething(
+                                SwXTextRange::getUnoTunnelId());
+        pCursor = (SwXTextCursor*)xRangeTunnel->getSomething(
+                                SwXTextCursor::getUnoTunnelId());
+    }
+
+    SwDoc* pDoc = pRange ? (SwDoc*)pRange->GetDoc() : pCursor ? (SwDoc*)pCursor->GetDoc() : 0;
+    //wurde ein FieldMaster attached, dann ist das Dokument schon festgelegt!
+    if(pDoc && (!m_pDoc || m_pDoc == pDoc))
+    {
+        SwUnoInternalPaM aPam(*pDoc);
+        //das muss jetzt sal_True liefern
+        SwXTextRange::XTextRangeToSwPaM(aPam, xTextRange);
+        SwField* pFld = 0;
+        switch(m_nServiceId)
+        {
+            case SW_SERVICE_FIELDTYPE_ANNOTATION:
+            {
+                SwFieldType* pFldType = pDoc->GetSysFldType(RES_POSTITFLD);
+                pFld = new SwPostItField((SwPostItFieldType*)pFldType,
+                        m_pProps->sPar1, m_pProps->sPar2,
+                        m_pProps->aDate);
+            }
+            break;
+            case SW_SERVICE_FIELDTYPE_SCRIPT:
+            {
+                SwFieldType* pFldType = pDoc->GetSysFldType(RES_SCRIPTFLD);
+                pFld = new SwScriptField((SwScriptFieldType*)pFldType,
+                        m_pProps->sPar1, m_pProps->sPar2,
+                        m_pProps->bBool1);
+            }
+            break;
+            case SW_SERVICE_FIELDTYPE_DATETIME:
+            {
+                sal_uInt16 nSub = 0;
+                if(m_pProps->bBool1)
+                    nSub |= FIXEDFLD;
+                if(m_pProps->bBool2)
+                    nSub |= DATEFLD;
+                else
+                    nSub |= TIMEFLD;
+                SwFieldType* pFldType = pDoc->GetSysFldType(RES_DATETIMEFLD);
+                pFld = new SwDateTimeField((SwDateTimeFieldType*)pFldType,
+                nSub, m_pProps->nFormat);
+                if(m_pProps->fDouble > 0.)
+                    ((SwDateTimeField*)pFld)->SetValue( m_pProps->fDouble );
+                ((SwDateTimeField*)pFld)->SetOffset(m_pProps->nSubType);
+            }
+            break;
+            case SW_SERVICE_FIELDTYPE_FILE_NAME:
+            {
+                SwFieldType* pFldType = pDoc->GetSysFldType(RES_FILENAMEFLD);
+                sal_Int32 nFormat = m_pProps->nFormat;
+                if(m_pProps->bBool2)
+                    nFormat |= FF_FIXED;
+                pFld = new SwFileNameField((SwFileNameFieldType*)pFldType, nFormat);
+                if(m_pProps->sPar3.Len())
+                    ((SwFileNameField*)pFld)->SetExpansion(m_pProps->sPar3);
+            }
+            break;
+            case SW_SERVICE_FIELDTYPE_TEMPLATE_NAME:
+            {
+                SwFieldType* pFldType = pDoc->GetSysFldType(RES_TEMPLNAMEFLD);
+                pFld = new SwTemplNameField((SwTemplNameFieldType*)pFldType,
+                                                    m_pProps->nFormat);
+            }
+            break;
+            case SW_SERVICE_FIELDTYPE_CHAPTER:
+            {
+                SwFieldType* pFldType = pDoc->GetSysFldType(RES_CHAPTERFLD);
+                pFld = new SwChapterField((SwChapterFieldType*)pFldType, m_pProps->nUSHORT1);
+                ((SwChapterField*)pFld)->SetLevel(m_pProps->nByte1);
+            }
+            break;
+            case SW_SERVICE_FIELDTYPE_AUTHOR:
+            {
+                long nFormat = m_pProps->bBool1 ? AF_NAME : AF_SHORTCUT;
+                if(m_pProps->bBool2)
+                    nFormat |= AF_FIXED;
+
+                SwFieldType* pFldType = pDoc->GetSysFldType(RES_AUTHORFLD);
+                pFld = new SwAuthorField((SwAuthorFieldType*)pFldType, nFormat);
+                ((SwAuthorField*)pFld)->SetExpansion(m_pProps->sPar1);
+            }
+            break;
+            case SW_SERVICE_FIELDTYPE_CONDITIONED_TEXT:
+            case SW_SERVICE_FIELDTYPE_HIDDEN_TEXT:
+            {
+                SwFieldType* pFldType = pDoc->GetSysFldType(RES_HIDDENTXTFLD);
+                pFld = new SwHiddenTxtField(((SwHiddenTxtFieldType*)pFldType),
+                        m_pProps->sPar1,
+                        m_pProps->sPar2, m_pProps->sPar3,
+                        SW_SERVICE_FIELDTYPE_HIDDEN_TEXT == m_nServiceId ?
+                             TYP_HIDDENTXTFLD :
+                                TYP_CONDTXTFLD);
+            }
+            break;
+            case SW_SERVICE_FIELDTYPE_HIDDEN_PARA:
+            {
+                SwFieldType* pFldType = pDoc->GetSysFldType(RES_HIDDENPARAFLD);
+                pFld = new SwHiddenParaField((SwHiddenParaFieldType*)pFldType,
+                                                m_pProps->sPar1);
+            }
+            break;
+            case SW_SERVICE_FIELDTYPE_GET_REFERENCE:
+            {
+                SwFieldType* pFldType = pDoc->GetSysFldType(RES_GETREFFLD);
+                pFld = new SwGetRefField((SwGetRefFieldType*)pFldType,
+                            m_pProps->sPar1,
+                            0,
+                            0,
+                            0);
+                if(m_pProps->sPar3.Len())
+                    ((SwGetRefField*)pFld)->SetExpand(m_pProps->sPar3);
+                Any aVal; aVal <<=(sal_Int16)m_pProps->nUSHORT1;
+                pFld->PutValue(aVal, C2U(UNO_NAME_REFERENCE_FIELD_PART));
+                aVal <<=(sal_Int16)m_pProps->nUSHORT2;
+                pFld->PutValue(aVal, C2U(UNO_NAME_REFERENCE_FIELD_SOURCE));
+                aVal <<=(sal_Int16)m_pProps->nSHORT1;
+                pFld->PutValue(aVal, C2U(UNO_NAME_SEQUENCE_NUMBER));
+            }
+            break;
+            case SW_SERVICE_FIELDTYPE_JUMP_EDIT:
+            {
+                SwFieldType* pFldType = pDoc->GetSysFldType(RES_JUMPEDITFLD);
+                pFld = new SwJumpEditField((SwJumpEditFieldType*)pFldType,
+                                m_pProps->nUSHORT1,
+                                m_pProps->sPar1,
+                                m_pProps->sPar2);
+            }
+            break;
+            case SW_SERVICE_FIELDTYPE_DOCINFO_CHANGE_AUTHOR     :
+            case SW_SERVICE_FIELDTYPE_DOCINFO_CHANGE_DATE_TIME  :
+            case SW_SERVICE_FIELDTYPE_DOCINFO_EDIT_TIME         :
+            case SW_SERVICE_FIELDTYPE_DOCINFO_DESCRIPTION       :
+            case SW_SERVICE_FIELDTYPE_DOCINFO_CREATE_AUTHOR     :
+            case SW_SERVICE_FIELDTYPE_DOCINFO_CREATE_DATE_TIME  :
+            case SW_SERVICE_FIELDTYPE_DOCINFO_INFO_0            :
+            case SW_SERVICE_FIELDTYPE_DOCINFO_INFO_1            :
+            case SW_SERVICE_FIELDTYPE_DOCINFO_INFO_2            :
+            case SW_SERVICE_FIELDTYPE_DOCINFO_INFO_3            :
+            case SW_SERVICE_FIELDTYPE_DOCINFO_PRINT_AUTHOR      :
+            case SW_SERVICE_FIELDTYPE_DOCINFO_PRINT_DATE_TIME   :
+            case SW_SERVICE_FIELDTYPE_DOCINFO_KEY_WORDS         :
+            case SW_SERVICE_FIELDTYPE_DOCINFO_SUBJECT           :
+            case SW_SERVICE_FIELDTYPE_DOCINFO_TITLE             :
+            case SW_SERVICE_FIELDTYPE_DOCINFO_REVISION          :
+            case SW_SERVICE_FIELDTYPE_DOC_INFO:
+            {
+                SwFieldType* pFldType = pDoc->GetSysFldType(RES_DOCINFOFLD);
+                sal_uInt16 nSubType = aDocInfoSubTypeFromService[
+                        m_nServiceId - SW_SERVICE_FIELDTYPE_DOCINFO_CHANGE_AUTHOR];
+                if(m_pProps->bBool2) //IsDate
+                {
+                    nSubType |= DI_SUB_DATE;
+                    nSubType &= ~DI_SUB_TIME;
+                }
+                else
+                {
+                    nSubType |= DI_SUB_TIME;
+                    nSubType &= ~DI_SUB_DATE;
+                }
+                if(m_pProps->bBool1)
+                    nSubType |= DI_SUB_FIXED;
+                pFld = new SwDocInfoField((SwDocInfoFieldType*)pFldType, nSubType, m_pProps->nFormat);
+                if(m_pProps->sPar3.Len())
+                    ((SwDocInfoField*)pFld)->SetExpansion(m_pProps->sPar3);
+            }
+            break;
+            case SW_SERVICE_FIELDTYPE_USER_EXT:
+            {
+                sal_Int32 nFormat = 0;
+                if(m_pProps->bBool1)
+                    nFormat = AF_FIXED;
+
+                SwFieldType* pFldType = pDoc->GetSysFldType(RES_EXTUSERFLD);
+                pFld = new SwExtUserField((SwExtUserFieldType*)pFldType, m_pProps->nUSHORT1, nFormat);
+                ((SwExtUserField*)pFld)->SetExpansion(m_pProps->sPar1);
+            }
+            break;
+            case SW_SERVICE_FIELDTYPE_USER:
+            {
+                SwFieldType* pFldType = pDoc->GetFldType(RES_USERFLD, m_sTypeName);
+                if(!pFldType)
+                    throw uno::RuntimeException();
+                USHORT nUserSubType = m_pProps->bBool1 ? SUB_INVISIBLE : 0;
+                if(m_pProps->bBool2)
+                    nUserSubType |= SUB_CMD;
+                pFld = new SwUserField((SwUserFieldType*)pFldType,
+                                    nUserSubType,
+                                    m_pProps->nFormat);
+            }
+            break;
+            case SW_SERVICE_FIELDTYPE_REF_PAGE_SET:
+            {
+                SwFieldType* pFldType = pDoc->GetSysFldType(RES_REFPAGESETFLD);
+                pFld = new SwRefPageSetField( (SwRefPageSetFieldType*)pFldType,
+                                    m_pProps->nUSHORT1,
+                                    m_pProps->bBool1 );
+            }
+            break;
+            case SW_SERVICE_FIELDTYPE_REF_PAGE_GET:
+            {
+                SwFieldType* pFldType = pDoc->GetSysFldType(RES_REFPAGEGETFLD);
+                pFld = new SwRefPageGetField( (SwRefPageGetFieldType*)pFldType,
+                                                m_pProps->nUSHORT1 );
+            }
+            break;
+            case SW_SERVICE_FIELDTYPE_PAGE_NUM:
+            {
+                SwFieldType* pFldType = pDoc->GetSysFldType(RES_PAGENUMBERFLD);
+                pFld = new SwPageNumberField((SwPageNumberFieldType*)pFldType,
+                                                PG_RANDOM,
+                                                m_pProps->nFormat,
+                                                m_pProps->nUSHORT1);
+                ((SwPageNumberField*)pFld)->SetUserString(m_pProps->sPar1);
+            }
+            break;
+#ifdef DDE_AVAILABLE
+            case SW_SERVICE_FIELDTYPE_DDE:
+            {
+                SwFieldType* pFldType = pDoc->GetFldType(RES_DDEFLD, m_sTypeName);
+                if(!pFldType)
+                    throw uno::RuntimeException();
+                pFld = new SwDDEField( (SwDDEFieldType*)pFldType );
+            }
+            break;
+#endif
+            case SW_SERVICE_FIELDTYPE_DATABASE_NAME:
+            {
+                SwFieldType* pFldType = pDoc->GetSysFldType(RES_DBNAMEFLD);
+                String sDBName(m_pProps->sPar1);
+                sDBName += DB_DELIM;
+                sDBName += m_pProps->sPar2;
+                pFld = new SwDBNameField((SwDBNameFieldType*)pFldType, sDBName);
+            }
+            break;
+            case SW_SERVICE_FIELDTYPE_DATABASE_NEXT_SET:
+            {
+                String sDBName(m_pProps->sPar1);
+                sDBName += DB_DELIM;
+                sDBName += m_pProps->sPar2;
+                SwFieldType* pFldType = pDoc->GetSysFldType(RES_DBNEXTSETFLD);
+                pFld = new SwDBNextSetField((SwDBNextSetFieldType*)pFldType,
+                        m_pProps->sPar3, aEmptyStr,
+                        sDBName);
+            }
+            break;
+            case SW_SERVICE_FIELDTYPE_DATABASE_NUM_SET:
+            {
+                String sDBName(m_pProps->sPar1);
+                sDBName += DB_DELIM;
+                sDBName += m_pProps->sPar2;
+                SwFieldType* pFldType = pDoc->GetSysFldType(RES_DBNUMSETFLD);
+                pFld = new SwDBNumSetField( (SwDBNumSetFieldType*)pFldType,
+                    m_pProps->sPar3, String::CreateFromInt32(m_pProps->nFormat), sDBName);
+            }
+            break;
+            case SW_SERVICE_FIELDTYPE_DATABASE_SET_NUM:
+            {
+                String sDBName(m_pProps->sPar1);
+                sDBName += DB_DELIM;
+                sDBName += m_pProps->sPar2;
+                SwFieldType* pFldType = pDoc->GetSysFldType(RES_DBSETNUMBERFLD);
+                pFld = new SwDBSetNumberField(
+                        (SwDBSetNumberFieldType*)pFldType,
+                        sDBName,
+                        m_pProps->nUSHORT1);
+                ((SwDBSetNumberField*)pFld)->SetSetNumber(m_pProps->nFormat);
+            }
+            break;
+            case SW_SERVICE_FIELDTYPE_DATABASE:
+            {
+                SwFieldType* pFldType = pDoc->GetFldType(RES_DBFLD, m_sTypeName);
+                if(!pFldType)
+                    throw uno::RuntimeException();
+                pFld = new SwDBField((SwDBFieldType*)pFldType, m_pProps->nFormat);
+                ((SwDBField*)pFld)->InitContent(m_pProps->sPar1);
+                pFld->SetSubType(pFld->GetSubType()&SUB_OWN_FMT);
+            }
+            break;
+            case SW_SERVICE_FIELDTYPE_SET_EXP:
+            {
+                SwFieldType* pFldType = pDoc->GetFldType(RES_SETEXPFLD, m_sTypeName);
+                if(!pFldType)
+                    throw uno::RuntimeException();
+                pFld = new SwSetExpField((SwSetExpFieldType*)pFldType,
+                    m_pProps->sPar2,
+                    m_pProps->nUSHORT2);
+
+                sal_uInt16  nSubType = pFld->GetSubType();
+                if(m_pProps->bBool2)
+                    nSubType &= ~SUB_INVISIBLE;
+                else
+                    nSubType |= SUB_INVISIBLE;
+                if(m_pProps->bBool3)
+                    nSubType |= SUB_CMD;
+                else
+                    nSubType &= ~SUB_CMD;
+                pFld->SetSubType(nSubType);
+                ((SwSetExpField*)pFld)->SetSeqNumber( m_pProps->nUSHORT1 );
+                ((SwSetExpField*)pFld)->SetInputFlag(m_pProps->bBool1);
+                ((SwSetExpField*)pFld)->SetPromptText(m_pProps->sPar3);
+                if(m_pProps->sPar4.Len())
+                    ((SwSetExpField*)pFld)->ChgExpStr(m_pProps->sPar4);
+
+            }
+            break;
+            case SW_SERVICE_FIELDTYPE_GET_EXP:
+            {
+                SwFieldType* pFldType = pDoc->GetSysFldType(RES_GETEXPFLD);
+                if(!pFldType)
+                    throw uno::RuntimeException();
+                sal_uInt16 nSubType;
+                switch(m_pProps->nSubType)
+                {
+                    case SetVariableType::STRING:   nSubType = GSE_STRING;  break;
+                    case SetVariableType::VAR:      nSubType = GSE_EXPR;  break;
+                    case SetVariableType::SEQUENCE: nSubType = GSE_SEQ;  break;
+                    case SetVariableType::FORMULA:  nSubType = GSE_FORMULA; break;
+                    default:
+                        DBG_ERROR("wrong value");
+                        nSubType = GSE_EXPR;
+                }
+                if(m_pProps->bBool2)
+                    nSubType |= SUB_CMD;
+                else
+                    nSubType &= ~SUB_CMD;
+                pFld = new SwGetExpField((SwGetExpFieldType*)pFldType,
+                        m_pProps->sPar1, nSubType, m_pProps->nFormat);
+                //TODO: SubType auswerten!
+                if(m_pProps->sPar4.Len())
+                    ((SwGetExpField*)pFld)->ChgExpStr(m_pProps->sPar4);
+            }
+            break;
+            case SW_SERVICE_FIELDTYPE_INPUT_USER:
+            case SW_SERVICE_FIELDTYPE_INPUT:
+            {
+                SwFieldType* pFldType = pDoc->GetFldType(RES_INPUTFLD, m_sTypeName);
+                if(!pFldType)
+                    throw uno::RuntimeException();
+                USHORT nInpSubType = SW_SERVICE_FIELDTYPE_INPUT_USER == m_nServiceId ? INP_USR : INP_TXT;
+                pFld = new SwInputField((SwInputFieldType*)pFldType,
+                        m_pProps->sPar1, m_pProps->sPar2, nInpSubType);
+            }
+            break;
+            case SW_SERVICE_FIELDTYPE_MACRO:
+            {
+                SwFieldType* pFldType = pDoc->GetSysFldType(RES_MACROFLD);
+                pFld = new SwMacroField((SwMacroFieldType*)pFldType,
+                            m_pProps->sPar1, m_pProps->sPar2);
+            }
+            break;
+            case SW_SERVICE_FIELDTYPE_PAGE_COUNT            :
+            case SW_SERVICE_FIELDTYPE_PARAGRAPH_COUNT       :
+            case SW_SERVICE_FIELDTYPE_WORD_COUNT            :
+            case SW_SERVICE_FIELDTYPE_CHARACTER_COUNT       :
+            case SW_SERVICE_FIELDTYPE_TABLE_COUNT           :
+            case SW_SERVICE_FIELDTYPE_GRAPHIC_OBJECT_COUNT  :
+            case SW_SERVICE_FIELDTYPE_EMBEDDED_OBJECT_COUNT :
+            {
+                sal_uInt16 nSubType = DS_PAGE;
+                switch(m_nServiceId)
+                {
+//                  case SW_SERVICE_FIELDTYPE_PAGE_COUNT            : break;
+                    case SW_SERVICE_FIELDTYPE_PARAGRAPH_COUNT       : nSubType = DS_PARA;break;
+                    case SW_SERVICE_FIELDTYPE_WORD_COUNT            : nSubType = DS_WORD;break;
+                    case SW_SERVICE_FIELDTYPE_CHARACTER_COUNT       : nSubType = DS_CHAR;break;
+                    case SW_SERVICE_FIELDTYPE_TABLE_COUNT           : nSubType = DS_TBL;break;
+                    case SW_SERVICE_FIELDTYPE_GRAPHIC_OBJECT_COUNT  : nSubType = DS_GRF;break;
+                    case SW_SERVICE_FIELDTYPE_EMBEDDED_OBJECT_COUNT : nSubType = DS_OLE;break;
+                }
+                SwFieldType* pFldType = pDoc->GetSysFldType(RES_DOCSTATFLD);
+                pFld = new SwDocStatField((SwDocStatFieldType*)pFldType, nSubType, m_pProps->nUSHORT2);
+            }
+            break;
+            default: DBG_ERROR("was ist das fuer ein Typ?");
+        }
+        if(pFld)
+        {
+            SwFmtFld aFmt( *pFld );
+
+            UnoActionContext aCont(pDoc);
+            SwTxtAttr* pTxtAttr = 0;
+            if(aPam.HasMark())
+                pDoc->DeleteAndJoin(aPam);
+            pDoc->Insert(aPam, aFmt);
+            SwUnoCrsr* pCrsr = pDoc->CreateUnoCrsr( *aPam.Start() );
+            pCrsr->SetMark();
+            pCrsr->Left(1);
+            pTxtAttr = pCrsr->GetNode()->GetTxtNode()->GetTxtAttr(pCrsr->GetPoint()->nContent, RES_TXTATR_FIELD);
+            delete pCrsr;
+
+            // was passiert mit dem Update der Felder ? (siehe fldmgr.cxx)
+            if(pTxtAttr)
+            {
+                const SwFmtFld& rFld = pTxtAttr->GetFld();
+                rFld.GetFld()->GetTyp()->Add(this);
+                pFmtFld = &rFld;
+            }
+        }
+        delete pFld;
+
+        m_pDoc = pDoc;
+        m_bIsDescriptor = sal_False;
+        DELETEZ(m_pProps);
+    }
+    else
+        throw IllegalArgumentException();
+
+}
+/*-- 14.12.98 11:37:18---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextField::attach(const uno::Reference< XTextRange > & xTextRange)
+    throw( IllegalArgumentException, uno::RuntimeException )
+{
+}
+/*-- 14.12.98 11:37:18---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XTextRange >  SwXTextField::getAnchor(void) throw( uno::RuntimeException )
+{
+    vos::OGuard  aGuard(Application::GetSolarMutex());
+    uno::Reference< XTextRange >   aRef;
+    SwField* pField = (SwField*)GetField();
+    if(pField)
+    {
+        const SwTxtFld* pTxtFld = pFmtFld->GetTxtFld();
+        const SwTxtNode& rTxtNode = pTxtFld->GetTxtNode();
+
+        SwPaM aPam(rTxtNode, *pTxtFld->GetStart() + 1, rTxtNode, *pTxtFld->GetStart());
+
+        aRef = ::CreateTextRangeFromPosition(m_pDoc,
+                                *aPam.GetPoint(), aPam.GetMark());
+    }
+    return aRef;
+
+}
+/*-- 14.12.98 11:37:18---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextField::dispose(void) throw( uno::RuntimeException )
+{
+    vos::OGuard  aGuard(Application::GetSolarMutex());
+    SwField* pField = (SwField*)GetField();
+    if(pField)
+    {
+        UnoActionContext aContext(GetDoc());
+        const SwTxtFld* pTxtFld = pFmtFld->GetTxtFld();
+        SwTxtNode& rTxtNode = (SwTxtNode&)*pTxtFld->GetpTxtNode();
+        SwPaM aPam(rTxtNode, *pTxtFld->GetStart());
+        aPam.SetMark();
+        aPam.Move();
+        GetDoc()->DeleteAndJoin(aPam);
+    }
+}
+/*-- 14.12.98 11:37:18---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextField::addEventListener(const uno::Reference< XEventListener > & aListener) throw( uno::RuntimeException )
+{
+    if(!GetRegisteredIn())
+        throw uno::RuntimeException();
+    aLstnrCntnr.AddListener(aListener);
+}
+/*-- 14.12.98 11:37:18---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextField::removeEventListener(const uno::Reference< XEventListener > & aListener) throw( uno::RuntimeException )
+{
+    if(!GetRegisteredIn() || !aLstnrCntnr.RemoveListener(aListener))
+        throw uno::RuntimeException();
+}
+/*-- 14.12.98 11:37:19---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XPropertySetInfo >  SwXTextField::getPropertySetInfo(void)
+        throw( uno::RuntimeException )
+{
+    vos::OGuard  aGuard(Application::GetSolarMutex());
+    //kein static
+    uno::Reference< XPropertySetInfo >  aRef;
+    sal_uInt16 nPos = USHRT_MAX;
+    if(GetFldType())
+    {
+        sal_uInt16 nResId = GetFldType()->Which();
+        switch(nResId)
+        {
+            case  RES_DBFLD         : nPos = SW_SERVICE_FIELDTYPE_DATABASE;break;
+            case  RES_USERFLD       : nPos = SW_SERVICE_FIELDTYPE_USER;break;
+            case  RES_FILENAMEFLD   : nPos = SW_SERVICE_FIELDTYPE_FILE_NAME;break;
+            case  RES_DBNAMEFLD     : nPos = SW_SERVICE_FIELDTYPE_DATABASE_NAME;break;
+            case  RES_DATEFLD       : break;
+            case  RES_TIMEFLD       : break;
+            case  RES_PAGENUMBERFLD : nPos = SW_SERVICE_FIELDTYPE_PAGE_NUM;break;
+            case  RES_AUTHORFLD     : nPos = SW_SERVICE_FIELDTYPE_AUTHOR;break;
+            case  RES_CHAPTERFLD    : nPos = SW_SERVICE_FIELDTYPE_CHAPTER;break;
+            case  RES_DOCSTATFLD    : //alle Statistik-Felder haben die gleiche PropertyMap
+                nPos = SW_SERVICE_FIELDTYPE_PAGE_COUNT;
+            break;
+            case  RES_GETEXPFLD     : nPos = SW_SERVICE_FIELDTYPE_GET_EXP;break;
+            case  RES_SETEXPFLD     : nPos = SW_SERVICE_FIELDTYPE_SET_EXP;break;
+            case  RES_GETREFFLD     : nPos = SW_SERVICE_FIELDTYPE_GET_REFERENCE;break;
+            case  RES_HIDDENTXTFLD  :
+                nPos = m_nServiceId;
+            break;
+            case  RES_POSTITFLD     : nPos = SW_SERVICE_FIELDTYPE_ANNOTATION;break;
+    //      case  RES_REGFLD        : nPos = ;break;
+    //      case  RES_VARREGFLD     : nPos = ;break;
+    //      case  RES_SETREFFLD     : nPos = ;break;
+            case  RES_INPUTFLD      : nPos = SW_SERVICE_FIELDTYPE_INPUT;break;
+            case  RES_MACROFLD      : nPos = SW_SERVICE_FIELDTYPE_MACRO;break;
+            case  RES_DDEFLD        : nPos = SW_SERVICE_FIELDTYPE_DDE;break;
+            case  RES_TABLEFLD      : nPos = SW_SERVICE_FIELDTYPE_TABLEFIELD;break;
+            case  RES_HIDDENPARAFLD : nPos = SW_SERVICE_FIELDTYPE_HIDDEN_PARA;break;
+            case  RES_DOCINFOFLD    : nPos = SW_SERVICE_FIELDTYPE_DOC_INFO;break;
+            case  RES_TEMPLNAMEFLD  : nPos = SW_SERVICE_FIELDTYPE_TEMPLATE_NAME;break;
+            case  RES_DBNEXTSETFLD  : nPos = SW_SERVICE_FIELDTYPE_DATABASE_NEXT_SET;break;
+            case  RES_DBNUMSETFLD   : nPos = SW_SERVICE_FIELDTYPE_DATABASE_NUM_SET;break;
+            case  RES_DBSETNUMBERFLD: nPos = SW_SERVICE_FIELDTYPE_DATABASE_SET_NUM;break;
+            case  RES_EXTUSERFLD    : nPos = SW_SERVICE_FIELDTYPE_USER_EXT;break;
+            case  RES_REFPAGESETFLD : nPos = SW_SERVICE_FIELDTYPE_REF_PAGE_SET;break;
+            case  RES_REFPAGEGETFLD : nPos = SW_SERVICE_FIELDTYPE_REF_PAGE_GET;break;
+            case  RES_INTERNETFLD   : 0;break;
+            case  RES_JUMPEDITFLD   : nPos = SW_SERVICE_FIELDTYPE_JUMP_EDIT;break;
+            case  RES_SCRIPTFLD     : nPos = SW_SERVICE_FIELDTYPE_SCRIPT;break;
+            case  RES_DATETIMEFLD   :
+            case  RES_FIXDATEFLD    :
+            case  RES_FIXTIMEFLD    : nPos = SW_SERVICE_FIELDTYPE_DATETIME; break;
+    //      case  RES_FIELDS_END    : nPos = ;break;
+        }
+    }
+    else
+        nPos = m_nServiceId;
+    if(nPos != USHRT_MAX)
+    {
+        const SfxItemPropertyMap* pMap = SwFieldPropMapProvider::GetPropertyMap(nPos);
+        uno::Reference< beans::XPropertySetInfo >  xInfo = new SfxItemPropertySetInfo(pMap);
+        // extend PropertySetInfo!
+        const uno::Sequence aPropSeq = xInfo->getProperties();
+        aRef = new SfxExtItemPropertySetInfo(
+            aSwMapProvider.GetPropertyMap(PROPERTY_MAP_PARAGRAPH_EXTENSIONS),
+            aPropSeq );
+    }
+    else
+        throw uno::RuntimeException();
+    return aRef;
+}
+/*-- 14.12.98 11:37:19---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextField::setPropertyValue(const OUString& rPropertyName, const uno::Any& aValue)
+    throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException,
+        WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard  aGuard(Application::GetSolarMutex());
+    SwField* pField = (SwField*)GetField();
+    const SfxItemPropertyMap* _pMap = SwFieldPropMapProvider::GetPropertyMap(m_nServiceId);
+    const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(_pMap, rPropertyName);
+    if(!pMap)
+        throw UnknownPropertyException();
+    if(pMap->nFlags & PropertyAttribute::READONLY)
+        throw IllegalArgumentException();
+    if(pField)
+    {
+        // Sonderbehandlung Serienbrieffeld
+        sal_uInt16 nWhich = GetFldType()->Which();
+        if( RES_DBFLD == nWhich &&
+            (COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_DATA_BASE_NAME) ||
+                COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_DATA_TABLE_NAME)||
+                    COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_DATA_COLUMN_NAME)))
+        {
+            // hier muss ein neuer Feldtyp angelegt werden und
+            // das Feld an den neuen Typ umgehaengt werden
+            DBG_WARNING("not implemented")
+        }
+        else
+            pField->PutValue(aValue, rPropertyName);
+    }
+    else if(m_pProps)
+    {
+        switch(pMap->nWID)
+        {
+            case FIELD_PROP_PAR1:
+            {
+                OUString uTmp;
+                aValue >>= uTmp;
+                m_pProps->sPar1 = String(uTmp);
+            }
+            break;
+            case FIELD_PROP_PAR2:
+            {
+                OUString uTmp;
+                aValue >>= uTmp;
+                m_pProps->sPar2 = String(uTmp);
+            }
+            break;
+            case FIELD_PROP_FORMAT:
+            {
+                aValue >>= m_pProps->nFormat;
+            }
+            break;
+            case FIELD_PROP_SUBTYPE:
+            {
+                aValue >>= m_pProps->nSubType;
+            }
+            break;
+            case FIELD_PROP_BYTE1 :
+                aValue >>= m_pProps->nByte1;
+            break;
+            case FIELD_PROP_BOOL1 :
+            {
+                if(aValue.getValueType() != getCppuBooleanType())
+                    throw IllegalArgumentException();
+                m_pProps->bBool1 = *(sal_Bool*)aValue.getValue();;
+            }
+            break;
+            case FIELD_PROP_BOOL2 :
+            {
+                if(aValue.getValueType() != getCppuBooleanType())
+                    throw IllegalArgumentException();
+                m_pProps->bBool2 = *(sal_Bool*)aValue.getValue();;
+            }
+            break;
+            case FIELD_PROP_BOOL3 :
+            {
+                if(aValue.getValueType() != getCppuBooleanType())
+                    throw IllegalArgumentException();
+                m_pProps->bBool3 = *(sal_Bool*)aValue.getValue();
+            }
+            break;
+            case FIELD_PROP_DATE :
+            {
+                if(aValue.getValueType() != ::getCppuType((const util::Date*)0))
+                    throw IllegalArgumentException();
+
+                util::Date aTemp = *(const util::Date*)aValue.getValue();
+                m_pProps->aDate = Date(aTemp.Day, aTemp.Month, aTemp.Year);
+            }
+            break;
+            case FIELD_PROP_USHORT1:
+            {
+                sal_Int16 nVal;
+                aValue >>= nVal;
+                m_pProps->nUSHORT1 = nVal;
+            }
+            break;
+            case FIELD_PROP_USHORT2:
+            {
+                sal_Int16 nVal;
+                aValue >>= nVal;
+                m_pProps->nUSHORT2 = nVal;
+            }
+            break;
+            case FIELD_PROP_SHORT1:
+            {
+                aValue >>= m_pProps->nSHORT1;
+            }
+            break;
+            case FIELD_PROP_DOUBLE:
+            {
+                if(aValue.getValueType() != ::getCppuType((const Double*)0))
+                    throw IllegalArgumentException();
+                m_pProps->fDouble = *(Double*)aValue.getValue();
+            }
+            break;
+        }
+    }
+    else
+        throw uno::RuntimeException();
+}
+/*-- 14.12.98 11:37:19---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXTextField::getPropertyValue(const OUString& rPropertyName)
+    throw( UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard  aGuard(Application::GetSolarMutex());
+    uno::Any aRet;
+    const SwField* pField = GetField();
+    const SfxItemPropertyMap* _pMap = SwFieldPropMapProvider::GetPropertyMap(m_nServiceId);
+    const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(_pMap, rPropertyName);
+    if(!pMap )
+    {
+        _pMap = aSwMapProvider.GetPropertyMap(PROPERTY_MAP_PARAGRAPH_EXTENSIONS);
+        pMap = SfxItemPropertyMap::GetByName(_pMap, rPropertyName);
+    }
+    if(!pMap )
+        throw UnknownPropertyException();
+    if(FN_UNO_TEXT_WRAP == pMap->nWID)
+    {
+        aRet <<= (INT16) WrapTextMode_NONE;
+    }
+    else if(FN_UNO_ANCHOR_TYPE == pMap->nWID)
+    {
+        aRet <<= (INT16) TextContentAnchorType_AT_PARAGRAPH;
+    }
+    else if(FN_UNO_ANCHOR_TYPES == pMap->nWID)
+    {
+        uno::Sequence aTypes(1);
+        TextContentAnchorType* pArray = aTypes.getArray();
+        pArray[0] = TextContentAnchorType_AT_PARAGRAPH;
+        aRet.setValue(&aTypes, ::getCppuType((uno::Sequence*)0));
+    }
+    else if(pField)
+        pField->QueryValue(aRet, rPropertyName);
+    else if(m_pProps)
+    {
+        switch(pMap->nWID)
+        {
+            case FIELD_PROP_PAR1:
+                aRet <<= OUString(m_pProps->sPar1);
+            break;
+            case FIELD_PROP_PAR2:
+                aRet <<= OUString(m_pProps->sPar2);
+            break;
+            case FIELD_PROP_FORMAT:
+                aRet <<= m_pProps->nFormat;
+            break;
+            case FIELD_PROP_SUBTYPE:
+                aRet <<= m_pProps->nSubType;
+            break;
+            case FIELD_PROP_BYTE1 :
+                aRet <<= m_pProps->nByte1;
+            break;
+            case FIELD_PROP_BOOL1 :
+                aRet.setValue(&m_pProps->bBool1, ::getCppuBooleanType());
+            break;
+            case FIELD_PROP_BOOL2 :
+                aRet.setValue(&m_pProps->bBool2, ::getCppuBooleanType());
+            break;
+            case FIELD_PROP_DATE :
+                aRet.setValue(&m_pProps->aDate, ::getCppuType((const util::Date*)0));
+            break;
+            case FIELD_PROP_USHORT1:
+                aRet <<= (sal_Int16)m_pProps->nUSHORT1;
+            break;
+            case FIELD_PROP_USHORT2:
+                aRet <<= (sal_Int16)m_pProps->nUSHORT2;
+            break;
+            case FIELD_PROP_SHORT1:
+                aRet <<= m_pProps->nSHORT1;
+            break;
+            case FIELD_PROP_DOUBLE:
+                aRet <<= m_pProps->fDouble;
+            break;
+        }
+    }
+    else
+        throw uno::RuntimeException();
+    return aRet;
+}
+/*-- 14.12.98 11:37:20---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextField::addPropertyChangeListener(const OUString& PropertyName, const uno::Reference< XPropertyChangeListener > & aListener) throw( UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 14.12.98 11:37:20---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextField::removePropertyChangeListener(const OUString& PropertyName, const uno::Reference< XPropertyChangeListener > & aListener) throw( UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 14.12.98 11:37:20---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextField::addVetoableChangeListener(const OUString& PropertyName, const uno::Reference< XVetoableChangeListener > & aListener) throw( UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 14.12.98 11:37:20---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextField::removeVetoableChangeListener(const OUString& PropertyName, const uno::Reference< XVetoableChangeListener > & aListener) throw( UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/* -----------------19.03.99 14:11-------------------
+ *
+ * --------------------------------------------------*/
+OUString SwXTextField::getImplementationName(void) throw( uno::RuntimeException )
+{
+    return C2U("SwXTextField");
+}
+/* -----------------19.03.99 14:11-------------------
+ *
+ * --------------------------------------------------*/
+sal_Bool SwXTextField::supportsService(const OUString& rServiceName) throw( uno::RuntimeException )
+{
+    OUString sServiceName = SwXServiceProvider::GetProviderName(m_nServiceId);
+    return sServiceName == rServiceName ||
+        !rServiceName.compareToAscii("com.sun.star.text.TextContent");
+}
+/* -----------------19.03.99 14:11-------------------
+ *
+ * --------------------------------------------------*/
+uno::Sequence< OUString > SwXTextField::getSupportedServiceNames(void) throw( uno::RuntimeException )
+{
+    uno::Sequence< OUString > aRet(2);
+    OUString* pArray = aRet.getArray();
+    OUString sServiceName = SwXServiceProvider::GetProviderName(m_nServiceId);
+    pArray[0] = sServiceName;
+    pArray[1] = C2U("com.sun.star.text.TextContent");
+    return aRet;
+}
+
+/* -----------------14.12.98 12:00-------------------
+ *
+ * --------------------------------------------------*/
+void SwXTextField::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew)
+{
+    ClientModify(this, pOld, pNew);
+    if(!GetFldType())
+    {
+        aLstnrCntnr.Disposing();
+        m_pDoc = 0;
+    }
+}
+/*-- 14.12.98 11:37:21---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+const SwField*  SwXTextField::GetField() const
+{
+    SwFieldType* pType = GetFldType();
+    if(pType && pFmtFld)
+    {
+        // simpler Test: das Feld wird am Typ gesucht
+        SwClientIter aIter(*pType);
+        SwFmtFld* pFld = (SwFmtFld*)aIter.First( TYPE( SwFmtFld ));
+        do
+        {
+            if(pFld == pFmtFld)
+                return pFld->GetFld();
+        }while(pFld && 0 != (pFld = (SwFmtFld*)aIter.Next()));
+    }
+    return 0;
+}
+/******************************************************************
+ *
+ ******************************************************************/
+/******************************************************************
+ * SwXTextFieldMasters
+ ******************************************************************/
+/* -----------------------------06.04.00 13:22--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXTextFieldMasters::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXTextFieldMasters");
+}
+/* -----------------------------06.04.00 13:22--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXTextFieldMasters::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.text.TextFieldMasters") == rServiceName;
+}
+/* -----------------------------06.04.00 13:22--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXTextFieldMasters::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.TextFieldMasters");
+    return aRet;
+}
+/*-- 21.12.98 10:37:14---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextFieldMasters::SwXTextFieldMasters(SwDoc* pDoc) :
+    SwUnoCollection(pDoc)
+{
+}
+/*-- 21.12.98 10:37:32---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextFieldMasters::~SwXTextFieldMasters()
+{
+
+}
+/*-- 21.12.98 10:37:33---------------------------------------------------
+    Iteration ueber nicht-Standard Feldtypen
+    USER/SETEXP/DDE/DATABASE
+    Der Name ist demnach:
+    "com.sun.star.text.FieldMaster.User" + 
+    "com.sun.star.text.FieldMaster.DDE" + 
+    "com.sun.star.text.FieldMaster.SetExpression" + 
+    "com.sun.star.text.FieldMaster.DataBase" + 
+
+    Falls wir grosszuegig werden wollen, dann koennte man com.sun.star.text
+    auch optional weglassen
+  -----------------------------------------------------------------------*/
+BOOL lcl_ConvertDatabaseName(String& rName)
+{
+    rName.Erase(0, 9); //DataBase.
+    USHORT nDotCount = rName.GetTokenCount('.');
+    if(nDotCount < 2)
+       return FALSE;
+    rName.SearchAndReplace('.', DB_DELIM);
+    xub_StrLen  nFound = rName.SearchBackward( '.' );
+        rName.SetChar(nFound, DB_DELIM);
+    rName.Insert(C2S("DataBase."), 0);
+    return TRUE;
+}
+//-----------------------------------------------------------------------------
+uno::Any SwXTextFieldMasters::getByName(const OUString& rName)
+    throw( NoSuchElementException, WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard  aGuard(Application::GetSolarMutex());
+    if(!GetDoc())
+        throw uno::RuntimeException();
+    String sName(rName);
+    if(COMPARE_EQUAL == sName.CompareToAscii("com.sun.star.text.FieldMaster.", 30))
+    {
+        sName.Erase(0, 30);
+    }
+    sal_uInt16 nResId = USHRT_MAX;
+    xub_StrLen nFound = 0;
+    String sTypeName = sName.GetToken(0, '.', nFound);
+    if(COMPARE_EQUAL == sTypeName.CompareToAscii("User"))
+        nResId = RES_USERFLD;
+    else if(COMPARE_EQUAL == sTypeName.CompareToAscii("DDE"))
+        nResId = RES_DDEFLD;
+    else if(COMPARE_EQUAL == sTypeName.CompareToAscii("SetExpression"))
+        nResId = RES_SETEXPFLD;
+    else if(COMPARE_EQUAL == sTypeName.CompareToAscii("DataBase"))
+    {
+        if(!lcl_ConvertDatabaseName(sName))
+            throw NoSuchElementException();
+        nResId = RES_DBFLD;
+    }
+    else
+        throw NoSuchElementException();
+
+    sName.Erase(0, nFound);
+    SwFieldType* pType = GetDoc()->GetFldType(nResId, sName);
+    if(!pType)
+        throw NoSuchElementException();
+    SwXFieldMaster* pMaster = (SwXFieldMaster*)
+                SwClientIter(*pType).First(TYPE(SwXFieldMaster));
+    if(!pMaster)
+        pMaster = new SwXFieldMaster(*pType, GetDoc());
+    uno::Reference< XPropertySet >  aRef = pMaster;
+    uno::Any aRet(&aRef, ::getCppuType((const uno::Reference*)0));
+    return aRet;
+}
+/*-- 21.12.98 10:37:33---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Sequence< OUString > SwXTextFieldMasters::getElementNames(void)
+    throw( uno::RuntimeException )
+{
+    vos::OGuard  aGuard(Application::GetSolarMutex());
+    if(!GetDoc())
+        throw uno::RuntimeException();
+
+    const SwFldTypes* pFldTypes = GetDoc()->GetFldTypes();
+    sal_uInt16 nCount = pFldTypes->Count();
+
+    SvStrings aFldNames;
+    String sPrefix(C2S("com.sun.star.text.FieldMaster."));
+    for( sal_uInt16 i = 0; i < nCount; i++)
+    {
+        SwFieldType& rFldType = *((*pFldTypes)[i]);
+        sal_uInt16 nWhich = rFldType.Which();
+        if(RES_USERFLD == nWhich)
+        {
+            String* pString = new String(sPrefix);
+            *pString +=  C2S("User.");
+            *pString += rFldType.GetName();
+            aFldNames.Insert(pString, aFldNames.Count());
+        }
+        if(RES_DDEFLD == nWhich)
+        {
+            String* pString = new String(sPrefix);
+            *pString += C2S("DDE.");
+            *pString += rFldType.GetName();
+            aFldNames.Insert(pString, aFldNames.Count());
+        }
+        if(RES_SETEXPFLD == nWhich)
+        {
+            String* pString = new String(sPrefix);
+            *pString += C2S("SetExpression.");
+            *pString += rFldType.GetName();
+            aFldNames.Insert(pString, aFldNames.Count());
+        }
+        if(RES_DBFLD == nWhich)
+        {
+            String* pString = new String(sPrefix);
+            *pString += C2S("DataBase.");
+            String sDBName(rFldType.GetName());
+            sDBName.SearchAndReplaceAll(DB_DELIM, '.');
+            *pString += sDBName;
+            aFldNames.Insert(pString, aFldNames.Count());
+        }
+    }
+
+    uno::Sequence< OUString > aSeq(aFldNames.Count());
+    OUString* pArray = aSeq.getArray();
+    for(i = 0; i < aFldNames.Count();i++)
+    {
+        pArray[i] = *aFldNames.GetObject(i);
+    }
+    aFldNames.DeleteAndDestroy(0, aFldNames.Count());
+
+    return aSeq;
+
+}
+/*-- 21.12.98 10:37:33---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextFieldMasters::hasByName(const OUString& rName) throw( RuntimeException )
+{
+    vos::OGuard  aGuard(Application::GetSolarMutex());
+    if(!GetDoc())
+        throw uno::RuntimeException();
+    String sName(rName);
+    if(sName.CompareToAscii("com.sun.star.text.FieldMaster.", 30) == COMPARE_EQUAL)
+        sName.Erase(0, 30);
+
+    sal_uInt16 nResId = USHRT_MAX;
+    xub_StrLen nFound = 0;
+    String sTypeName = sName.GetToken(0, '.', nFound);
+    if(COMPARE_EQUAL == sTypeName.CompareToAscii("User"))
+        nResId = RES_USERFLD;
+    else if(COMPARE_EQUAL == sTypeName.CompareToAscii("DDE"))
+        nResId = RES_DDEFLD;
+    else if(COMPARE_EQUAL == sTypeName.CompareToAscii("SetExpression"))
+        nResId = RES_SETEXPFLD;
+    else if(COMPARE_EQUAL == sTypeName.CompareToAscii("DataBase"))
+    {
+        if(!lcl_ConvertDatabaseName(sName))
+            throw NoSuchElementException();
+        nResId = RES_DBFLD;
+    }
+    sName.Erase(0, nFound);
+    sal_Bool bRet = nResId != USHRT_MAX && 0 != GetDoc()->GetFldType(nResId, sName);
+    return bRet;
+}
+/*-- 21.12.98 10:37:34---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Type  SwXTextFieldMasters::getElementType(void) throw( uno::RuntimeException )
+{
+    return ::getCppuType((const uno::Reference*)0);
+
+}
+/*-- 21.12.98 10:37:34---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextFieldMasters::hasElements(void) throw( uno::RuntimeException )
+{
+    vos::OGuard  aGuard(Application::GetSolarMutex());
+    if(!IsValid())
+        throw uno::RuntimeException();
+    return sal_True;
+}
+
+/******************************************************************
+ *
+ ******************************************************************/
+/* -----------------------------06.04.00 13:24--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXTextFieldTypes::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXTextFieldTypes");
+}
+/* -----------------------------06.04.00 13:24--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXTextFieldTypes::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.text.TextFieldTypes") == rServiceName;
+}
+/* -----------------------------06.04.00 13:24--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXTextFieldTypes::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.TextFieldTypes");
+    return aRet;
+}
+/*-- 21.12.98 10:35:15---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextFieldTypes::SwXTextFieldTypes(SwDoc* pDoc) :
+    SwUnoCollection(pDoc)
+{
+}
+/*-- 21.12.98 10:35:16---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextFieldTypes::~SwXTextFieldTypes()
+{
+}
+/*-- 21.12.98 10:35:17---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XEnumeration >  SwXTextFieldTypes::createEnumeration(void)
+    throw( uno::RuntimeException )
+{
+    vos::OGuard  aGuard(Application::GetSolarMutex());
+    if(!IsValid())
+        throw uno::RuntimeException();
+    return new SwXFieldEnumeration(GetDoc());
+}
+
+/*-- 21.12.98 10:35:17---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Type  SwXTextFieldTypes::getElementType(void) throw( uno::RuntimeException )
+{
+    return ::getCppuType((const uno::Reference*)0);
+}
+/*-- 21.12.98 10:35:17---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextFieldTypes::hasElements(void) throw( uno::RuntimeException )
+{
+    vos::OGuard  aGuard(Application::GetSolarMutex());
+    if(!IsValid())
+        throw uno::RuntimeException();
+    //es gibt sie immer
+    return sal_True;
+}
+/* -----------------24.02.99 16:19-------------------
+ *
+ * --------------------------------------------------*/
+void SwXTextFieldTypes::refresh(void)  throw( uno::RuntimeException )
+{
+    vos::OGuard  aGuard(Application::GetSolarMutex());
+    if(!IsValid())
+        throw uno::RuntimeException();
+    UnoActionContext aContext(GetDoc());
+    SwDocStat aDocStat;
+    GetDoc()->UpdateDocStat(aDocStat, 0);
+    GetDoc()->UpdateFlds(0, sal_False);
+}
+/* -----------------24.02.99 16:19-------------------
+ *
+ * --------------------------------------------------*/
+void SwXTextFieldTypes::addRefreshListener(const uno::Reference< util::XRefreshListener > & l)
+    throw( uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/* -----------------24.02.99 16:19-------------------
+ *
+ * --------------------------------------------------*/
+void SwXTextFieldTypes::removeRefreshListener(const uno::Reference< util::XRefreshListener > & l)
+     throw( uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/******************************************************************
+ * SwXFieldEnumeration
+ ******************************************************************/
+/* -----------------------------06.04.00 13:25--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXFieldEnumeration::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXFieldEnumeration");
+}
+/* -----------------------------06.04.00 13:25--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXFieldEnumeration::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.text.FieldEnumeration") == rServiceName;
+}
+/* -----------------------------06.04.00 13:25--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXFieldEnumeration::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.FieldEnumeration");
+    return aRet;
+}
+/* -----------------21.12.98 14:57-------------------
+ *
+ * --------------------------------------------------*/
+SwXFieldEnumeration::SwXFieldEnumeration(SwDoc* pDc) :
+    pDoc(pDc),
+    pLastFieldType(0),
+    pLastFieldFmt(0),
+    pNextFieldFmt(0),
+    pNextFieldType(0)
+{
+    pDoc->GetPageDescFromPool(RES_POOLPAGE_STANDARD)->Add(this);
+}
+/*-- 21.12.98 14:57:23---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXFieldEnumeration::~SwXFieldEnumeration()
+{
+
+}
+/*-- 21.12.98 14:57:42---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXFieldEnumeration::hasMoreElements(void) throw( uno::RuntimeException )
+{
+    vos::OGuard  aGuard(Application::GetSolarMutex());
+    sal_Bool bRet = sal_False;
+    pNextFieldFmt = 0;
+    if(pDoc)
+    {
+        const SwFldTypes* pFldTypes = pDoc->GetFldTypes();
+        sal_uInt16 nCount = pFldTypes->Count();
+        //wenn man noch nicht hier war, dann muss man nichts ueberspringen
+        sal_Bool bFieldTypeFound = pLastFieldType == 0;
+        sal_Bool bFieldFmtFound = pLastFieldFmt == 0;
+        for(sal_uInt16 nType = 0; nType < nCount; nType++)
+        {
+            const SwFieldType* pCurType = pFldTypes->GetObject(nType);
+            if(!bFieldTypeFound)
+            {
+                if(pCurType != pLastFieldType)
+                    continue;
+                bFieldTypeFound = sal_True;
+            }
+            //hier sind wir etwa da, wo wir das letzte Mal aufgehoert haben
+            //jetzt noch das richtige Feld
+            //pLastFieldFmt
+            SwClientIter aIter( *(SwFieldType*)pCurType );
+            SwFmtFld* pCurFldFmt = (SwFmtFld*)aIter.First( TYPE( SwFmtFld ));
+            sal_Int32 nRet = 0;
+            while( pCurFldFmt && !pNextFieldFmt)
+            {
+                if(!bFieldFmtFound)
+                {
+                    if(pCurFldFmt == pLastFieldFmt)
+                    {
+                        bFieldFmtFound = sal_True;
+
+                    }
+                }
+                else if(pCurFldFmt->GetTxtFld() && //keine TextAttr, dann schon geloescht
+                    pCurFldFmt->GetTxtFld()->GetpTxtNode()->GetNodes().IsDocNodes())
+                {
+                    pNextFieldFmt = pCurFldFmt;
+                    pNextFieldType = pCurType;
+                }
+                pCurFldFmt = (SwFmtFld*)aIter.Next();
+            }
+            if(pNextFieldFmt)
+            {
+                bRet = sal_True;
+                break;
+            }
+        }
+    }
+    else
+        throw uno::RuntimeException();
+    return bRet;
+}
+/*-- 21.12.98 14:57:42---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXFieldEnumeration::nextElement(void)
+    throw( NoSuchElementException, WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard  aGuard(Application::GetSolarMutex());
+    if(pDoc)
+    {
+        if(pNextFieldFmt || hasMoreElements())
+        {
+            const SwFldTypes* pFldTypes = pDoc->GetFldTypes();
+            sal_uInt16 nCount = pFldTypes->Count();
+            sal_Bool bTypeFound = sal_False;
+            for(sal_uInt16 nType = 0; nType < nCount; nType++)
+            {
+                if(pNextFieldType == pFldTypes->GetObject(nType))
+                {
+                    bTypeFound = sal_True;
+                    break;
+                }
+            }
+            if(!bTypeFound)
+                throw NoSuchElementException();
+            SwClientIter aIter(*(SwFieldType*)pNextFieldType);
+            SwFmtFld* pCurFldFmt = (SwFmtFld*)aIter.First( TYPE( SwFmtFld ));
+            while( pCurFldFmt)
+            {
+                if(pCurFldFmt == pNextFieldFmt)
+                    break;
+                pCurFldFmt = (SwFmtFld*)aIter.Next();
+            }
+            if(!pCurFldFmt)
+                throw NoSuchElementException();
+            //jetzt ist alles wiedergefunden, kann also benutzt werden
+            pLastFieldFmt = pNextFieldFmt;
+            pLastFieldType = pNextFieldType;
+            pNextFieldFmt = 0;
+            pNextFieldType = 0;
+        }
+        else
+            throw NoSuchElementException();
+    }
+    else
+        throw uno::RuntimeException();
+    uno::Reference< XTextField >  xFld = new SwXTextField(*pLastFieldFmt, pDoc);
+    uno::Any aRet(&xFld, ::getCppuType((const uno::Reference*)0));
+    return aRet;
+
+}
+/* -----------------21.12.98 15:08-------------------
+ *
+ * --------------------------------------------------*/
+void SwXFieldEnumeration::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew)
+{
+    ClientModify(this, pOld, pNew);
+    if(!GetRegisteredIn())
+        pDoc = 0;
+}
+
+
+/*------------------------------------------------------------------------
+
+    $Log: not supported by cvs2svn $
+    Revision 1.96  2000/09/18 16:04:31  willem.vandorp
+    OpenOffice header added.
+
+    Revision 1.95  2000/09/12 11:42:57  os
+    #78682# support of service TextContent
+
+    Revision 1.94  2000/09/11 12:05:29  os
+    #78606# references to footnotes
+
+    Revision 1.93  2000/09/05 15:15:42  os
+    string length available again
+
+    Revision 1.92  2000/08/31 15:07:29  os
+    new properties in ReferenceField
+
+    Revision 1.91  2000/08/31 10:04:27  os
+    DDECommand splitted into three parts
+
+    Revision 1.90  2000/08/30 07:57:45  os
+    PtrArr in UNIX style
+
+    Revision 1.89  2000/08/29 08:08:33  os
+    properties of DDEFieldType implemented
+
+    Revision 1.88  2000/08/25 07:57:41  os
+    service names of SwDocStatField
+
+    Revision 1.87  2000/08/23 11:26:29  os
+    Property Adjust in DateTimeField; Property IsDate in some of the DocInfoFields
+
+    Revision 1.86  2000/08/22 12:57:11  os
+    SwAuthorField: Content and CurrentPresentation merged
+
+    Revision 1.85  2000/08/22 12:45:58  os
+    Property CurrentPresentation
+
+    Revision 1.84  2000/08/22 10:04:50  os
+    Properties IsDate, IsFixed
+
+    Revision 1.83  2000/08/21 07:25:07  os
+    name access of database fields without DB_DELIM
+
+    Revision 1.82  2000/08/18 13:33:59  os
+    service names of docinfo fields now correct
+
+    Revision 1.81  2000/08/18 11:13:29  os
+    hidden/conditional text field corrected
+
+    Revision 1.80  2000/08/17 10:08:24  os
+    several fixes/extensions for XML
+
+    Revision 1.79  2000/08/11 13:36:01  os
+    IsShowFormula initialization corrected
+
+    Revision 1.78  2000/08/11 12:37:58  os
+    #76830# service name of ...InputUser corrected
+
+    Revision 1.77  2000/08/10 15:01:12  os
+    #76881##76926##76921# field API improvements for XML
+
+    Revision 1.76  2000/08/10 10:55:22  os
+    #76830# new service com.sun.star.TextField.InputUser
+
+    Revision 1.75  2000/08/04 12:20:18  dvo
+    - bugs fixed
+
+    Revision 1.74  2000/07/19 10:51:25  os
+    #76906# properties level and separator added
+
+    Revision 1.73  2000/07/13 13:51:12  os
+    SwGetExpressionField gets property Formula
+
+    Revision 1.72  2000/07/13 12:03:37  os
+    Hint-property at SetExpressionField
+
+    Revision 1.71  2000/07/12 15:18:38  os
+    SwSetExpField: NumberFormat property added
+
+    Revision 1.70  2000/06/29 10:38:58  os
+    #75853# Ctor call of SwDBFieldType corrected
+
+    Revision 1.69  2000/05/16 17:35:08  jp
+    Changes for Unicode
+
+    Revision 1.68  2000/04/11 08:31:03  os
+    UNICODE
+
+    Revision 1.67  2000/03/31 14:22:38  os
+    #74676# conditional text field now ok
+
+    Revision 1.66  2000/03/27 10:21:10  os
+    UNO III
+
+    Revision 1.65  2000/03/21 15:42:24  os
+    UNOIII
+
+    Revision 1.64  2000/02/25 15:15:27  os
+    #73195# visibility of SetExpressionField as descriptor enabled
+
+    Revision 1.63  2000/02/11 14:35:33  hr
+    #70473# changes for unicode ( patched by automated patchtool )
+
+    Revision 1.62  1999/12/14 15:14:43  os
+    #70234# IsVisible allowed
+
+    Revision 1.61  1999/12/03 11:09:56  os
+    #70234# initial fieldtypes mustn't be changed
+
+    Revision 1.60  1999/11/30 12:31:36  os
+    #70279# changed modules - string length changed, too
+
+    Revision 1.59  1999/11/19 16:40:18  os
+    modules renamed
+
+    Revision 1.58  1999/10/20 06:35:12  os
+    UnoActionContext added
+
+    Revision 1.57  1999/08/24 13:24:34  OS
+    #68359# create parent text via CreateTextRangeFromPosition
+
+
+      Rev 1.56   24 Aug 1999 15:24:34   OS
+   #68359# create parent text via CreateTextRangeFromPosition
+
+      Rev 1.55   09 Jun 1999 11:12:08   OS
+   return ServiceName of all text fields
+
+      Rev 1.54   18 May 1999 15:24:22   OS
+   #62019# einzelne Services fuer DocInfo-Felder
+
+      Rev 1.53   23 Apr 1999 08:26:34   OS
+   #65194# Semikolon muss weg
+
+      Rev 1.52   22 Apr 1999 16:13:40   OS
+   #65194# throw -> throw; #65124# not impl. nur noch warning; EventListener
+
+      Rev 1.51   20 Apr 1999 12:37:32   OS
+   #65040# XElementAccess im queryInterface
+
+
+      Rev 1.50   08 Apr 1999 08:32:12   OS
+   #63865# DocumentStatistic-Felder vereinzelt
+
+      Rev 1.49   29 Mar 1999 12:27:52   OS
+   #63853# Subtype beim Ctor des SwGetExpField umwandeln
+
+      Rev 1.48   25 Mar 1999 14:32:12   OS
+   #63853# SubType von Expressions auch per StarOne
+
+      Rev 1.47   22 Mar 1999 14:23:46   OS
+   #63785# Value fuer SetExpressionField
+
+      Rev 1.46   22 Mar 1999 09:13:18   OS
+   #62845# ServiceNames fur Felder: richtigen Feldtyp liefern
+
+      Rev 1.45   15 Mar 1999 14:36:34   OS
+   #62845# Makro fuer ServiceInfo jetzt auch fuer OS/2
+
+      Rev 1.44   12 Mar 1999 09:49:10   OS
+   #62845# XServiceInfo impl.
+
+      Rev 1.43   09 Mar 1999 12:41:02   OS
+   #62008# Solar-Mutex
+
+      Rev 1.42   04 Mar 1999 15:01:24   OS
+   #62191# UINT nicht mehr verwenden
+
+      Rev 1.41   25 Feb 1999 12:44:24   OS
+   #62355# Refreshable fuer FieldTypes
+
+      Rev 1.40   18 Feb 1999 14:26:46   OS
+   #52654# insertTextContent statt attach
+
+      Rev 1.39   16 Feb 1999 09:49:36   OS
+   #52654# TypeInfo fuer SwXTextField
+
+      Rev 1.38   15 Feb 1999 15:56:20   OS
+   #52654# Felder nach attach auch richtig initialisieren
+
+      Rev 1.37   10 Feb 1999 16:46:24   OS
+   #52654# Maps sortiert
+
+      Rev 1.36   09 Feb 1999 16:51:26   HR
+   U2S() eingefuegt
+
+      Rev 1.35   05 Feb 1999 14:29:54   OS
+   #56371##61522# keine uno::Exception im hasByName
+
+      Rev 1.34   04 Feb 1999 16:25:12   OS
+   #56371# FN_TEXT_RANGE: setPropertyValue am Master an den FieldType weiterleiten
+
+      Rev 1.33   03 Feb 1999 11:48:38   OS
+   #56371# fehlenden Punkt eingefuegt
+
+      Rev 1.32   02 Feb 1999 12:58:12   OS
+   #56371# mehr exceptions
+
+      Rev 1.31   01 Feb 1999 15:47:56   OS
+   #56371# Felder werden richtig eingefuegt
+
+      Rev 1.30   01 Feb 1999 08:22:18   OS
+   #56371# FieldMaster anlegen und mit Field verknuepfen
+
+      Rev 1.29   28 Jan 1999 16:47:14   OS
+   #56371# keine Objekte fuer DEBUG anlegen
+
+      Rev 1.28   21 Jan 1999 10:01:24   TJ
+   PROPERTY_READONLY
+
+      Rev 1.27   19 Jan 1999 14:50:36   OS
+   #56371# FieldMaster(s) vervollstaendigt
+
+      Rev 1.26   19 Jan 1999 08:03:46   OS
+    #56371# TF_ONE51: Descriptor-interfaces
+
+      Rev 1.25   21 Dec 1998 16:20:22   OS
+   #56371# TF_ONE51 Zwischenstand
+
+      Rev 1.24   21 Dec 1998 10:32:50   OS
+   #56371# Zwischenstand
+
+      Rev 1.23   10 Dec 1998 15:53:10   OS
+   #56371# TF_ONE51 Zwischenstand
+
+      Rev 1.22   10 Nov 1998 09:02:04   OS
+   #58821# IsHidden am UserField
+
+      Rev 1.21   02 Oct 1998 09:46:44   OS
+   #52654# ClassInfo fuer SwXNamedFieldType berichtigt
+
+      Rev 1.20   10 Sep 1998 12:52:10   OS
+   #52654# PROPERTY_NONE statt PROPERTY_BOUND
+
+      Rev 1.19   03 Sep 1998 12:21:14   OS
+   #52654# NamedFieldType muss auch XIndexAccess im queryInterface liefern
+
+
+      Rev 1.18   12 Aug 1998 19:41:40   HR
+   #54781#: ::::getCppuType((const uno::Reference< uno::XInterface >*)0)() -> ( uno::XInterface*)0)->getSmartUik()
+
+      Rev 1.17   10 Jul 1998 18:08:28   OS
+   PropertySetInfo und IdlClass static
+
+      Rev 1.16   09 Jul 1998 09:15:18   OS
+   getElementBy* - queryInterface auf uno::XInterface
+
+
+      Rev 1.15   06 Jul 1998 14:55:50   OS
+   getTextPositionCopy impl.
+
+      Rev 1.14   17 Jun 1998 16:10:34   MH
+   chg: Syntax OS2
+
+      Rev 1.13   04 Jun 1998 09:40:06   OS
+   getIdlClasses
+
+
+      Rev 1.12   02 Jun 1998 13:16:12   OS
+   DBG_ERROR zur Erinnerung
+
+      Rev 1.11   26 May 1998 11:34:56   OS
+   Properties fuer Benutzerfeldtyp berichtigt
+
+      Rev 1.10   14 May 1998 17:49:24   OS
+   div. Namensaenderungen
+
+      Rev 1.9   09 Apr 1998 15:10:50   OS
+   Uno-Umstellung
+
+      Rev 1.8   31 Mar 1998 15:36:32   OS
+   InputField: Propertyzuordnung berichtigt
+
+      Rev 1.7   26 Mar 1998 15:49:02   OS
+   Offset: sal_Int16
+
+      Rev 1.6   26 Mar 1998 14:11:42   OS
+   getImplementation fuer Feldtypen und Felder
+
+
+      Rev 1.5   24 Mar 1998 08:54:38   OS
+   DBG_ERROR zur Erinnerung
+
+      Rev 1.4   13 Mar 1998 08:26:54   OS
+   Property-Namen aus unoprset.hxx
+
+      Rev 1.3   12 Mar 1998 13:07:20   OS
+   NumType -> unsigned short
+
+      Rev 1.2   07 Mar 1998 16:10:50   OS
+   Properties fast vollstaendig
+
+      Rev 1.1   05 Mar 1998 17:39:06   OS
+   Properties fuer Felder
+
+      Rev 1.0   04 Mar 1998 09:14:34   OS
+   Initial revision.
+
+
+------------------------------------------------------------------------*/
+
diff --git a/sw/source/core/unocore/unoframe.cxx b/sw/source/core/unocore/unoframe.cxx
new file mode 100644
index 000000000000..eaa2ef2260eb
--- /dev/null
+++ b/sw/source/core/unocore/unoframe.cxx
@@ -0,0 +1,2669 @@
+/*************************************************************************
+ *
+ *  $RCSfile: unoframe.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:28 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include 
+#include 
+
+#ifndef _HINTS_HXX //autogen
+#include 
+#endif
+#ifndef _DOC_HXX //autogen
+#include 
+#endif
+#ifndef _DOCSH_HXX //autogen
+#include 
+#endif
+#ifndef _NDINDEX_HXX //autogen
+#include 
+#endif
+#ifndef _PAM_HXX //autogen
+#include 
+#endif
+#ifndef _NDNOTXT_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_UNOMID_HXX
+#include 
+#endif
+#ifndef _UNOCRSR_HXX //autogen
+#include 
+#endif
+#ifndef _DOCSTYLE_HXX //autogen
+#include 
+#endif
+#ifndef _FMTCNCT_HXX //autogen
+#include 
+#endif
+#ifndef _NDOLE_HXX //autogen
+#include 
+#endif
+#ifndef _UNOOBJ_HXX
+#include 
+#endif
+#ifndef _UNOMAP_HXX
+#include 
+#endif
+#ifndef _UNOPRNMS_HXX
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TABLE_BORDERLINE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_UTIL_XMODIFYBROADCASTER_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TABLE_SHADOWFORMAT_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_STYLE_GRAPHICLOCATION_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_FRAME_XMODEL_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_GRAPHICCROP_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_TEXTCONTENTANCHORTYPE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XTEXTCOLUMNS_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_
+#include 
+#endif
+#ifndef SW_UNOMID_HXX
+#include 
+#endif
+#ifndef _UNOSTYLE_HXX
+#include 
+#endif
+
+#ifndef _SVX_BRSHITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_PROTITEM_HXX //autogen
+#include 
+#endif
+#ifndef _FMTORNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTURL_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_ULSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BOXITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_OPAQITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_PRNTITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_SHADITEM_HXX //autogen
+#include 
+#endif
+#ifndef _FMTSRND_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFSIZE_HXX //autogen
+#include 
+#endif
+#ifndef _GRFATR_HXX //autogen
+#include 
+#endif
+#ifndef _UNOFRAME_HXX
+#include 
+#endif
+#ifndef _FMTANCHR_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _NDGRF_HXX
+#include 
+#endif
+#ifndef _VOS_MUTEX_HXX_ //autogen
+#include 
+#endif
+#ifndef _SV_SVAPP_HXX //autogen
+#include 
+#endif
+#ifndef _SVDOBJ_HXX //autogen
+#include 
+#endif
+#ifndef _RTL_UUID_H_
+#include 
+#endif
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::lang;
+using namespace ::rtl;
+
+
+// unterscheidet sich von der Rahmenbeschreibung durch eine XTextPosition
+//{ UNO_NAME_CLIENT_MAP     ,       RES_URL,                &::getBooleanCppuType(),            PROPERTY_MAYBEVOID ,MID_URL_CLIENTMAP        },
+const SfxItemPropertyMap* GetFrameDescMap()
+{
+    static SfxItemPropertyMap aFrameDescPropertyMap_Impl[] =
+    {
+        { SW_PROP_NAME(UNO_NAME_ANCHOR_PAGE_NO),            RES_ANCHOR,             &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE, MID_ANCHOR_PAGENUM       },
+        { SW_PROP_NAME(UNO_NAME_ANCHOR_TYPE   ),            RES_ANCHOR,             &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE, MID_ANCHOR_ANCHORTYPE},
+        { SW_PROP_NAME(UNO_NAME_BACK_COLOR    )  ,      RES_BACKGROUND,         &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_BACK_COLOR        },
+        { SW_PROP_NAME(UNO_NAME_CHAIN_NEXT_NAME),           RES_CHAIN,              &::getCppuType((const OUString*)0),         PropertyAttribute::MAYBEVOID ,MID_CHAIN_NEXTNAME},
+        { SW_PROP_NAME(UNO_NAME_CHAIN_PREV_NAME),           RES_CHAIN,              &::getCppuType((const OUString*)0),         PropertyAttribute::MAYBEVOID ,MID_CHAIN_PREVNAME},
+/*n.i.*/{ SW_PROP_NAME(UNO_NAME_CLIENT_MAP     )    ,       RES_URL,                &::getBooleanCppuType(),            PROPERTY_NONE ,MID_URL_CLIENTMAP         },
+        { SW_PROP_NAME(UNO_NAME_CONTENT_PROTECTED) ,        RES_PROTECT,            &::getBooleanCppuType(),            PROPERTY_NONE, MID_PROTECT_CONTENT   },
+        { SW_PROP_NAME(UNO_NAME_EDIT_IN_READONLY),      RES_EDIT_IN_READONLY,   &::getBooleanCppuType(),            PROPERTY_NONE, 0},
+        { SW_PROP_NAME(UNO_NAME_FRAME_STYLE_NAME),          0,                      &::getCppuType((const OUString*)0),         PROPERTY_NONE, 0},
+        { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_URL)      ,    RES_BACKGROUND,         &::getCppuType((const OUString*)0),         PROPERTY_NONE ,MID_GRAPHIC_URL    },
+        { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_FILTER)  ,     RES_BACKGROUND,         &::getCppuType((const OUString*)0),         PROPERTY_NONE ,MID_GRAPHIC_FILTER    },
+        { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_LOCATION)   ,  RES_BACKGROUND,         &::getCppuType((const style::GraphicLocation*)0), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+        { SW_PROP_NAME(UNO_NAME_LEFT_MARGIN),           RES_LR_SPACE,           &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE, MID_L_MARGIN|CONVERT_TWIPS},
+        { SW_PROP_NAME(UNO_NAME_RIGHT_MARGIN),          RES_LR_SPACE,           &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE, MID_R_MARGIN|CONVERT_TWIPS},
+        { SW_PROP_NAME(UNO_NAME_HEIGHT),                    RES_FRM_SIZE,           &::getCppuType((const sal_Int32*)0)  ,          PROPERTY_NONE, MID_FRMSIZE_HEIGHT|CONVERT_TWIPS         },
+        { SW_PROP_NAME(UNO_NAME_SIZE_TYPE),                 RES_FRM_SIZE,           &::getCppuType((const sal_Int16*)0)  ,          PROPERTY_NONE,   MID_FRMSIZE_SIZE_TYPE  },
+        { SW_PROP_NAME(UNO_NAME_HORI_ORIENT)     ,          RES_HORI_ORIENT,        &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE ,MID_HORIORIENT_ORIENT    },
+        { SW_PROP_NAME(UNO_NAME_HORI_ORIENT_POSITION),  RES_HORI_ORIENT,        &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_HORIORIENT_POSITION|CONVERT_TWIPS    },
+        { SW_PROP_NAME(UNO_NAME_HORI_ORIENT_RELATION),  RES_HORI_ORIENT,        &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE ,MID_HORIORIENT_RELATION  },
+        { SW_PROP_NAME(UNO_NAME_HYPER_LINK_U_R_L  ) ,       RES_URL,                &::getCppuType((const OUString*)0),         PROPERTY_NONE ,MID_URL_URL},
+        { SW_PROP_NAME(UNO_NAME_HYPER_LINK_TARGET ) ,       RES_URL,                &::getCppuType((const OUString*)0),         PROPERTY_NONE ,MID_URL_TARGET},
+        { SW_PROP_NAME(UNO_NAME_HYPER_LINK_NAME ),      RES_URL,                &::getCppuType((const OUString*)0),         PROPERTY_NONE ,MID_URL_HYPERLINKNAME     },
+        { SW_PROP_NAME(UNO_NAME_OPAQUE),                    RES_OPAQUE,             &::getBooleanCppuType(),            PROPERTY_NONE, 0},
+        { SW_PROP_NAME(UNO_NAME_PAGE_TOGGLE),               RES_HORI_ORIENT,        &::getBooleanCppuType(),            PROPERTY_NONE ,MID_HORIORIENT_PAGETOGGLE },
+        { SW_PROP_NAME(UNO_NAME_POSITION_PROTECTED),    RES_PROTECT,            &::getBooleanCppuType(),            PROPERTY_NONE, MID_PROTECT_POSITION},
+        { SW_PROP_NAME(UNO_NAME_PRINT),                     RES_PRINT,              &::getBooleanCppuType(),            PROPERTY_NONE, 0},
+        { SW_PROP_NAME(UNO_NAME_RELATIVE_HEIGHT),       RES_FRM_SIZE,           &::getCppuType((const sal_Int8*)0)  ,       PROPERTY_NONE,   MID_FRMSIZE_REL_HEIGHT },
+        { SW_PROP_NAME(UNO_NAME_RELATIVE_WIDTH),            RES_FRM_SIZE,           &::getCppuType((const sal_Int8*)0)  ,       PROPERTY_NONE,   MID_FRMSIZE_REL_WIDTH  },
+        { SW_PROP_NAME(UNO_NAME_SHADOW_FORMAT),             RES_SHADOW,             &::getCppuType((const table::ShadowFormat*)0),  PROPERTY_NONE, CONVERT_TWIPS},
+        { SW_PROP_NAME(UNO_NAME_SERVER_MAP)     ,       RES_URL,                &::getBooleanCppuType(),            PROPERTY_NONE ,MID_URL_SERVERMAP         },
+        { SW_PROP_NAME(UNO_NAME_SIZE),                  RES_FRM_SIZE,           &::getCppuType((const awt::Size*)0),            PROPERTY_NONE, MID_FRMSIZE_SIZE|CONVERT_TWIPS},
+        { SW_PROP_NAME(UNO_NAME_SIZE_PROTECTED)    ,    RES_PROTECT,            &::getBooleanCppuType(),            PROPERTY_NONE, MID_PROTECT_SIZE    },
+        { SW_PROP_NAME(UNO_NAME_SIZE_RELATIVE),             RES_FRM_SIZE,           &::getBooleanCppuType()  ,          PROPERTY_NONE,   MID_FRMSIZE_IS_SYNC_REL_SIZE   },
+        { SW_PROP_NAME(UNO_NAME_SURROUND  )               , RES_SURROUND,           &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE, MID_SURROUND_SURROUNDTYPE    },
+        { SW_PROP_NAME(UNO_NAME_SURROUND_ANCHORONLY),   RES_SURROUND,           &::getBooleanCppuType(),            PROPERTY_NONE, MID_SURROUND_ANCHORONLY      },
+        { SW_PROP_NAME(UNO_NAME_TEXT_COLUMNS),          RES_COL,                &::getCppuType((const uno::Reference*)0),    PROPERTY_NONE, MID_COLUMNS},
+        //MID_COLUMN_SEPARATOR_LINE ???
+        { SW_PROP_NAME(UNO_NAME_TOP_MARGIN),                RES_UL_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_UP_MARGIN|CONVERT_TWIPS},
+        { SW_PROP_NAME(UNO_NAME_BOTTOM_MARGIN),             RES_UL_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_LO_MARGIN|CONVERT_TWIPS},
+        { SW_PROP_NAME(UNO_NAME_TRANSPARENT_BACKGROUND) ,   RES_BACKGROUND,         &::getBooleanCppuType(),            PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT       },
+        { SW_PROP_NAME(UNO_NAME_VERT_ORIENT  ),             RES_VERT_ORIENT,        &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE ,MID_VERTORIENT_ORIENT    },
+        { SW_PROP_NAME(UNO_NAME_VERT_ORIENT_POSITION),  RES_VERT_ORIENT,        &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_VERTORIENT_POSITION|CONVERT_TWIPS    },
+        { SW_PROP_NAME(UNO_NAME_VERT_ORIENT_RELATION),  RES_VERT_ORIENT,        &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE ,MID_VERTORIENT_RELATION  },
+        { SW_PROP_NAME(UNO_NAME_WIDTH),                     RES_FRM_SIZE,           &::getCppuType((const sal_Int32*)0)  ,          PROPERTY_NONE, MID_FRMSIZE_WIDTH|CONVERT_TWIPS          },
+        { SW_PROP_NAME(UNO_NAME_TEXT_WRAP),                 RES_SURROUND,           &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE, MID_SURROUND_SURROUNDTYPE    },
+        { SW_PROP_NAME(UNO_NAME_LEFT_BORDER),               RES_BOX,                &::getCppuType((const table::BorderLine*)0),    0, LEFT_BORDER  |CONVERT_TWIPS },
+        { SW_PROP_NAME(UNO_NAME_RIGHT_BORDER),          RES_BOX,                &::getCppuType((const table::BorderLine*)0),    0, RIGHT_BORDER |CONVERT_TWIPS },
+        { SW_PROP_NAME(UNO_NAME_TOP_BORDER),                RES_BOX,                &::getCppuType((const table::BorderLine*)0),    0, TOP_BORDER   |CONVERT_TWIPS },
+        { SW_PROP_NAME(UNO_NAME_BOTTOM_BORDER),         RES_BOX,                &::getCppuType((const table::BorderLine*)0),    0, BOTTOM_BORDER|CONVERT_TWIPS },
+        { SW_PROP_NAME(UNO_NAME_BORDER_DISTANCE),         RES_BOX,              &::getCppuType((const sal_Int32*)0),    0, BORDER_DISTANCE|CONVERT_TWIPS },
+        {0,0,0,0}
+    };
+    #define FRM_PROP_COUNT 49
+    return aFrameDescPropertyMap_Impl;
+}
+// unterscheidet sich von der Rahmenbeschreibung durch eine XTextPosition
+const SfxItemPropertyMap* GetGraphicDescMap()
+{
+    static SfxItemPropertyMap aGraphicDescPropertyMap_Impl[] =
+    {
+        { SW_PROP_NAME(UNO_NAME_ALTERNATIVE_TEXT),      0,                      &::getCppuType((const OUString*)0),         PROPERTY_NONE , 0   },
+        { SW_PROP_NAME(UNO_NAME_ANCHOR_PAGE_NO),            RES_ANCHOR,             &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE, MID_ANCHOR_PAGENUM       },
+        { SW_PROP_NAME(UNO_NAME_ANCHOR_TYPE   ),            RES_ANCHOR,             &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE, MID_ANCHOR_ANCHORTYPE},
+        { SW_PROP_NAME(UNO_NAME_BACK_COLOR     )     ,      RES_BACKGROUND,         &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_BACK_COLOR        },
+        { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_FILTER)  ,     RES_BACKGROUND,         &::getCppuType((const OUString*)0),         PROPERTY_NONE ,MID_GRAPHIC_FILTER    },
+        { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_LOCATION)   ,  RES_BACKGROUND,         &::getCppuType((const style::GraphicLocation*)0), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+        { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_URL)      ,    RES_BACKGROUND,         &::getCppuType((const OUString*)0),         PROPERTY_NONE ,MID_GRAPHIC_URL    },
+        { SW_PROP_NAME(UNO_NAME_CLIENT_MAP     )    ,       RES_URL,                &::getBooleanCppuType(),            PROPERTY_NONE ,MID_URL_CLIENTMAP         },
+        { SW_PROP_NAME(UNO_NAME_CONTENT_PROTECTED) ,        RES_PROTECT,            &::getBooleanCppuType(),            PROPERTY_NONE, MID_PROTECT_CONTENT   },
+        { SW_PROP_NAME(UNO_NAME_CONTOUR_OUTSIDE),       RES_SURROUND,           &::getBooleanCppuType(),            PROPERTY_NONE, MID_SURROUND_CONTOUROUTSIDE  },
+        { SW_PROP_NAME(UNO_NAME_FRAME_STYLE_NAME),          0,                      &::getCppuType((const OUString*)0),         PROPERTY_NONE, 0},
+        { SW_PROP_NAME(UNO_NAME_GRAPHIC_CROP),          RES_GRFATR_CROPGRF,     &::getCppuType((const GraphicCrop*)0),  PROPERTY_NONE, CONVERT_TWIPS },
+        { SW_PROP_NAME(UNO_NAME_HORI_MIRRORED),             RES_GRFATR_MIRRORGRF,   &::getBooleanCppuType(),            PROPERTY_NONE,      MID_MIRROR_HORZ           },
+        { SW_PROP_NAME(UNO_NAME_HEIGHT),                    RES_FRM_SIZE,           &::getCppuType((const sal_Int32*)0)  ,          PROPERTY_NONE, MID_FRMSIZE_HEIGHT|CONVERT_TWIPS         },
+        { SW_PROP_NAME(UNO_NAME_HORI_ORIENT ) ,             RES_HORI_ORIENT,        &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE ,MID_HORIORIENT_ORIENT    },
+        { SW_PROP_NAME(UNO_NAME_HORI_ORIENT_POSITION),  RES_HORI_ORIENT,        &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_HORIORIENT_POSITION|CONVERT_TWIPS    },
+        { SW_PROP_NAME(UNO_NAME_HORI_ORIENT_RELATION),  RES_HORI_ORIENT,        &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE ,MID_HORIORIENT_RELATION  },
+        { SW_PROP_NAME(UNO_NAME_HYPER_LINK_U_R_L   ),       RES_URL,                &::getCppuType((const OUString*)0),         PROPERTY_NONE ,MID_URL_URL},
+        { SW_PROP_NAME(UNO_NAME_HYPER_LINK_TARGET  ),       RES_URL,                &::getCppuType((const OUString*)0),         PROPERTY_NONE ,MID_URL_TARGET},
+        { SW_PROP_NAME(UNO_NAME_HYPER_LINK_NAME ),      RES_URL,                &::getCppuType((const OUString*)0),         PROPERTY_NONE ,MID_URL_HYPERLINKNAME     },
+        { SW_PROP_NAME(UNO_NAME_LEFT_MARGIN),           RES_LR_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_L_MARGIN|CONVERT_TWIPS},
+        { SW_PROP_NAME(UNO_NAME_RIGHT_MARGIN),          RES_LR_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_R_MARGIN|CONVERT_TWIPS},
+        { SW_PROP_NAME(UNO_NAME_MIRROR_PAGE_TOGGLE),    RES_GRFATR_MIRRORGRF,   &::getBooleanCppuType(),            PROPERTY_NONE, MID_MIRROR_HORZ_PAGETOGGLE},
+        { SW_PROP_NAME(UNO_NAME_OPAQUE),                    RES_OPAQUE,             &::getBooleanCppuType(),            PROPERTY_NONE, 0},
+        { SW_PROP_NAME(UNO_NAME_PAGE_TOGGLE),               RES_VERT_ORIENT,        &::getBooleanCppuType(),            PROPERTY_NONE ,MID_HORIORIENT_PAGETOGGLE },
+        { SW_PROP_NAME(UNO_NAME_POSITION_PROTECTED),    RES_PROTECT,            &::getBooleanCppuType(),            PROPERTY_NONE, MID_PROTECT_POSITION},
+        { SW_PROP_NAME(UNO_NAME_PRINT),                     RES_PRINT,              &::getBooleanCppuType(),            PROPERTY_NONE, 0},
+        { SW_PROP_NAME(UNO_NAME_RELATIVE_HEIGHT),       RES_FRM_SIZE,           &::getCppuType((const sal_Int8*)0)  ,       PROPERTY_NONE,   MID_FRMSIZE_REL_HEIGHT },
+        { SW_PROP_NAME(UNO_NAME_RELATIVE_WIDTH),            RES_FRM_SIZE,           &::getCppuType((const sal_Int8*)0)  ,       PROPERTY_NONE,   MID_FRMSIZE_REL_WIDTH  },
+        { SW_PROP_NAME(UNO_NAME_SERVER_MAP )        ,       RES_URL,                &::getBooleanCppuType(),            PROPERTY_NONE ,MID_URL_SERVERMAP         },
+        { SW_PROP_NAME(UNO_NAME_SHADOW_FORMAT),             RES_SHADOW,             &::getCppuType((const table::ShadowFormat*)0),  PROPERTY_NONE, 0},
+        { SW_PROP_NAME(UNO_NAME_SIZE),                  RES_FRM_SIZE,           &::getCppuType((const awt::Size*)0),            PROPERTY_NONE, MID_FRMSIZE_SIZE|CONVERT_TWIPS},
+        { SW_PROP_NAME(UNO_NAME_SIZE_RELATIVE),             RES_FRM_SIZE,           &::getBooleanCppuType()  ,          PROPERTY_NONE,   MID_FRMSIZE_IS_SYNC_REL_SIZE   },
+        { SW_PROP_NAME(UNO_NAME_SIZE_PROTECTED)    ,    RES_PROTECT,            &::getBooleanCppuType(),            PROPERTY_NONE, MID_PROTECT_SIZE    },
+        { SW_PROP_NAME(UNO_NAME_SURROUND    )             , RES_SURROUND,           &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE, MID_SURROUND_SURROUNDTYPE    },
+        { SW_PROP_NAME(UNO_NAME_SURROUND_ANCHORONLY),   RES_SURROUND,           &::getBooleanCppuType(),            PROPERTY_NONE, MID_SURROUND_ANCHORONLY      },
+        { SW_PROP_NAME(UNO_NAME_SURROUND_CONTOUR )   ,  RES_SURROUND,           &::getBooleanCppuType(),            PROPERTY_NONE, MID_SURROUND_CONTOUR         },
+        { SW_PROP_NAME(UNO_NAME_TOP_MARGIN),                RES_UL_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_UP_MARGIN|CONVERT_TWIPS},
+        { SW_PROP_NAME(UNO_NAME_BOTTOM_MARGIN),             RES_UL_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_LO_MARGIN|CONVERT_TWIPS},
+        { SW_PROP_NAME(UNO_NAME_TRANSPARENT_BACKGROUND) ,   RES_BACKGROUND,         &::getBooleanCppuType(),            PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT       },
+        { SW_PROP_NAME(UNO_NAME_VERT_MIRRORED),         RES_GRFATR_MIRRORGRF,   &::getBooleanCppuType(),            PROPERTY_NONE,     MID_MIRROR_VERT            },
+        { SW_PROP_NAME(UNO_NAME_VERT_ORIENT  ),             RES_VERT_ORIENT,        &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE ,MID_VERTORIENT_ORIENT    },
+        { SW_PROP_NAME(UNO_NAME_VERT_ORIENT_POSITION),  RES_VERT_ORIENT,        &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_VERTORIENT_POSITION|CONVERT_TWIPS    },
+        { SW_PROP_NAME(UNO_NAME_VERT_ORIENT_RELATION),  RES_VERT_ORIENT,        &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE ,MID_VERTORIENT_RELATION  },
+        { SW_PROP_NAME(UNO_NAME_WIDTH),                     RES_FRM_SIZE,           &::getCppuType((const sal_Int32*)0)  ,          PROPERTY_NONE, MID_FRMSIZE_WIDTH            },
+        { SW_PROP_NAME(UNO_NAME_TEXT_WRAP),                 RES_SURROUND,           &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE, MID_SURROUND_SURROUNDTYPE    },
+        { SW_PROP_NAME(UNO_NAME_LEFT_BORDER),               RES_BOX,                &::getCppuType((const table::BorderLine*)0),    0, LEFT_BORDER  |CONVERT_TWIPS },
+        { SW_PROP_NAME(UNO_NAME_RIGHT_BORDER),          RES_BOX,                &::getCppuType((const table::BorderLine*)0),    0, RIGHT_BORDER |CONVERT_TWIPS },
+        { SW_PROP_NAME(UNO_NAME_TOP_BORDER),                RES_BOX,                &::getCppuType((const table::BorderLine*)0),    0, TOP_BORDER   |CONVERT_TWIPS },
+        { SW_PROP_NAME(UNO_NAME_BOTTOM_BORDER),         RES_BOX,                &::getCppuType((const table::BorderLine*)0),    0, BOTTOM_BORDER|CONVERT_TWIPS },
+        { SW_PROP_NAME(UNO_NAME_BORDER_DISTANCE),         RES_BOX,              &::getCppuType((const sal_Int32*)0),    0, BORDER_DISTANCE|CONVERT_TWIPS },
+        { SW_PROP_NAME(UNO_NAME_GRAPHIC_URL),               0,                      &::getCppuType((const OUString*)0), 0, 0 },
+        { SW_PROP_NAME(UNO_NAME_GRAPHIC_FILTER),            0,                      &::getCppuType((const OUString*)0), 0, 0 },
+        {0,0,0,0}
+    };
+    #define GRPH_PROP_COUNT 53
+    return aGraphicDescPropertyMap_Impl;
+}
+
+/****************************************************************************
+    Rahmenbeschreibung
+****************************************************************************/
+class BaseFrameProperties_Impl
+{
+    const SfxItemPropertyMap*   _pMap;
+public:
+
+    BaseFrameProperties_Impl(const SfxItemPropertyMap*  pMap) :
+        _pMap(pMap){}
+
+    virtual sal_Bool        SetProperty(const String& rName, uno::Any aVal) = 0;
+    virtual sal_Bool        GetProperty(const String& rName, uno::Any*& pAny )  = 0;
+
+    const SfxItemPropertyMap*   GetMap() const {return _pMap;}
+    sal_Bool                        FillBaseProperties(SfxItemSet& rSet);
+
+    virtual sal_Bool                AnyToItemSet(SfxItemSet& rFrmSet, SfxItemSet& rSet) = 0;
+
+};
+/* -----------------29.06.98 09:55-------------------
+ *
+ * --------------------------------------------------*/
+sal_Bool BaseFrameProperties_Impl::FillBaseProperties(SfxItemSet& rSet)
+{
+    sal_Bool bRet = sal_True;
+    //Anker kommt auf jeden Fall in den Set
+    SwFmtAnchor aAnchor;
+    {
+        uno::Any* pAnchorPgNo;
+        if(GetProperty(C2S(UNO_NAME_ANCHOR_PAGE_NO), pAnchorPgNo))
+            bRet &= ((SfxPoolItem&)aAnchor).PutValue(*pAnchorPgNo, MID_ANCHOR_PAGENUM);
+        uno::Any* pAnchorType;
+        if(GetProperty(C2S(UNO_NAME_ANCHOR_TYPE), pAnchorType))
+            bRet &= ((SfxPoolItem&)aAnchor).PutValue(*pAnchorType, MID_ANCHOR_ANCHORTYPE);
+    }
+    if(aAnchor.GetAnchorId() == FLY_PAGE && !aAnchor.GetPageNum())
+        aAnchor.SetPageNum(1);
+    rSet.Put(aAnchor);
+    {
+        uno::Any* pCol = 0;
+        GetProperty(C2S(UNO_NAME_BACK_COLOR), pCol );
+        uno::Any* pTrans = 0;
+        GetProperty(C2S(UNO_NAME_TRANSPARENT_BACKGROUND), pTrans );
+        uno::Any* pGrLoc = 0;
+        GetProperty(C2S(UNO_NAME_BACK_GRAPHIC_LOCATION), pGrLoc );
+        uno::Any* pGrURL = 0;
+        GetProperty(C2S(UNO_NAME_BACK_GRAPHIC_URL), pGrURL     );
+        uno::Any* pGrFilter = 0;
+        GetProperty(C2S(UNO_NAME_BACK_GRAPHIC_FILTER), pGrFilter     );
+
+        if(pCol || pTrans || pGrURL || pGrFilter || pGrLoc)
+        {
+            SvxBrushItem aBrush(RES_BACKGROUND);
+            if(pCol )
+                bRet &= ((SfxPoolItem&)aBrush).PutValue(*pCol,MID_BACK_COLOR    );
+            if(pTrans)
+                bRet &= ((SfxPoolItem&)aBrush).PutValue(*pTrans, MID_GRAPHIC_TRANSPARENT);
+            if(pGrURL)
+                bRet &= ((SfxPoolItem&)aBrush).PutValue(*pGrURL, MID_GRAPHIC_URL);
+            if(pGrFilter)
+                bRet &= ((SfxPoolItem&)aBrush).PutValue(*pGrFilter, MID_GRAPHIC_FILTER);
+            if(pGrLoc)
+                bRet &= ((SfxPoolItem&)aBrush).PutValue(*pGrLoc, MID_GRAPHIC_POSITION);
+            rSet.Put(aBrush);
+        }
+    }
+    {
+        uno::Any* pCont = 0;
+        GetProperty(C2S(UNO_NAME_CONTENT_PROTECTED), pCont );
+        uno::Any* pPos = 0;
+        GetProperty(C2S(UNO_NAME_POSITION_PROTECTED), pPos );
+        uno::Any* pName = 0;
+        GetProperty(C2S(UNO_NAME_SIZE_PROTECTED), pName );
+        if(pCont||pPos||pName)
+        {
+            SvxProtectItem aProt(RES_PROTECT);
+            if(pCont)
+                bRet &= ((SfxPoolItem&)aProt).PutValue(*pCont, MID_PROTECT_CONTENT);
+            if(pPos )
+                bRet &= ((SfxPoolItem&)aProt).PutValue(*pPos, MID_PROTECT_POSITION);
+            if(pName)
+                bRet &= ((SfxPoolItem&)aProt).PutValue(*pName, MID_PROTECT_SIZE);
+            rSet.Put(aProt);
+        }
+    }
+    {
+        uno::Any* pHori  = 0;
+        GetProperty(C2S(UNO_NAME_HORI_ORIENT), pHori );
+        uno::Any* pHoriP = 0;
+        GetProperty(C2S(UNO_NAME_HORI_ORIENT_POSITION), pHoriP );
+        uno::Any* pHoriR = 0;
+        GetProperty(C2S(UNO_NAME_HORI_ORIENT_RELATION), pHoriR );
+        uno::Any* pPageT = 0;
+        GetProperty(C2S(UNO_NAME_PAGE_TOGGLE), pPageT);
+        if(pHori||pHoriP||pHoriR||pPageT)
+        {
+            SwFmtHoriOrient aOrient;
+            if(pHori )
+                bRet &= ((SfxPoolItem&)aOrient).PutValue(*pHori, MID_HORIORIENT_ORIENT);
+            if(pHoriP)
+                bRet &= ((SfxPoolItem&)aOrient).PutValue(*pHoriP, MID_HORIORIENT_POSITION|CONVERT_TWIPS);
+            if(pHoriR)
+                bRet &= ((SfxPoolItem&)aOrient).PutValue(*pHoriR, MID_HORIORIENT_RELATION);
+            if(pPageT)
+                bRet &= ((SfxPoolItem&)aOrient).PutValue(*pPageT, MID_HORIORIENT_PAGETOGGLE);
+            rSet.Put(aOrient);
+        }
+    }
+
+    {
+        uno::Any* pVert  = 0;
+        GetProperty(C2S(UNO_NAME_VERT_ORIENT), pVert);
+        uno::Any* pVertP = 0;
+        GetProperty(C2S(UNO_NAME_VERT_ORIENT_POSITION), pVertP );
+        uno::Any* pVertR = 0;
+        GetProperty(C2S(UNO_NAME_VERT_ORIENT_RELATION), pVertR );
+        if(pVert||pVertP||pVertR)
+        {
+            SwFmtVertOrient aOrient;
+            if(pVert )
+                bRet &= ((SfxPoolItem&)aOrient).PutValue(*pVert, MID_VERTORIENT_ORIENT);
+            if(pVertP)
+                bRet &= ((SfxPoolItem&)aOrient).PutValue(*pVertP, MID_VERTORIENT_POSITION|CONVERT_TWIPS);
+            if(pVertR)
+                bRet &= ((SfxPoolItem&)aOrient).PutValue(*pVertR, MID_VERTORIENT_RELATION);
+            rSet.Put(aOrient);
+        }
+    }
+    {
+        uno::Any* pURL = 0;
+        GetProperty(C2S(UNO_NAME_HYPER_LINK_U_R_L), pURL );
+        uno::Any* pTarget = 0;
+        GetProperty(C2S(UNO_NAME_HYPER_LINK_TARGET), pTarget );
+        uno::Any* pHyLNm = 0;
+        GetProperty(C2S(UNO_NAME_HYPER_LINK_NAME), pHyLNm );
+        uno::Any* pHySMp = 0;
+        GetProperty(C2S(UNO_NAME_SERVER_MAP), pHySMp );
+        if(pURL||pTarget||pHyLNm||pHySMp)
+        {
+            SwFmtURL aURL;
+            if(pURL)
+                bRet &= ((SfxPoolItem&)aURL).PutValue(*pURL, MID_URL_URL);
+            if(pTarget)
+                bRet &= ((SfxPoolItem&)aURL).PutValue(*pTarget, MID_URL_TARGET);
+            if(pHyLNm)
+                bRet &= ((SfxPoolItem&)aURL).PutValue(*pHyLNm, MID_URL_HYPERLINKNAME  );
+            if(pHySMp)
+                bRet &= ((SfxPoolItem&)aURL).PutValue(*pHySMp, MID_URL_SERVERMAP);
+            rSet.Put(aURL);
+        }
+    }
+    uno::Any* pL = 0;
+    GetProperty(C2S(UNO_NAME_LEFT_MARGIN), pL );
+    uno::Any* pR = 0;
+    GetProperty(C2S(UNO_NAME_RIGHT_MARGIN), pR );
+    if(pL||pR)
+    {
+        SvxLRSpaceItem aLR(RES_LR_SPACE);
+        if(pL)
+            bRet &= ((SfxPoolItem&)aLR).PutValue(*pL, MID_L_MARGIN|CONVERT_TWIPS);
+        if(pR)
+            bRet &= ((SfxPoolItem&)aLR).PutValue(*pR, MID_R_MARGIN|CONVERT_TWIPS);
+        rSet.Put(aLR);
+    }
+    uno::Any* pT = 0;
+    GetProperty(C2S(UNO_NAME_TOP_MARGIN), pT );
+    uno::Any* pB = 0;
+    GetProperty(C2S(UNO_NAME_BOTTOM_MARGIN), pB );
+    if(pT||pB)
+    {
+        SvxULSpaceItem aTB(RES_UL_SPACE);
+        if(pT)
+            bRet &= ((SfxPoolItem&)aTB).PutValue(*pT, MID_UP_MARGIN|CONVERT_TWIPS);
+        if(pB)
+            bRet &= ((SfxPoolItem&)aTB).PutValue(*pB, MID_LO_MARGIN|CONVERT_TWIPS);
+        rSet.Put(aTB);
+    }
+    uno::Any* pOp;
+    if(GetProperty(C2S(UNO_NAME_OPAQUE), pOp))
+    {
+        SvxOpaqueItem aOp(RES_OPAQUE);
+        bRet &= ((SfxPoolItem&)aOp).PutValue(*pOp, 0);
+        rSet.Put(aOp);
+    }
+    uno::Any* pPrt;
+    if(GetProperty(C2S(UNO_NAME_PRINT), pPrt))
+    {
+        SvxPrintItem aPrt(RES_PRINT);
+        bRet &= ((SfxPoolItem&)aPrt).PutValue(*pPrt, 0);
+        rSet.Put(aPrt);
+    }
+    uno::Any* pSh;
+    if(GetProperty(C2S(UNO_NAME_SHADOW_FORMAT), pSh))
+    {
+        SvxShadowItem aSh(RES_SHADOW);
+        bRet &= ((SfxPoolItem&)aSh).PutValue(*pSh, CONVERT_TWIPS);
+        rSet.Put(aSh);
+    }
+    uno::Any* pSur   = 0;
+    GetProperty(C2S(UNO_NAME_SURROUND), pSur);
+    uno::Any* pSurAnch = 0;
+    GetProperty(C2S(UNO_NAME_SURROUND_ANCHORONLY), pSurAnch);
+    if(pSur || pSurAnch)
+    {
+        SwFmtSurround aSrnd;
+        if(pSur)
+            bRet &= ((SfxPoolItem&)aSrnd).PutValue(*pSur, MID_SURROUND_SURROUNDTYPE );
+        if(pSurAnch)
+            bRet &= ((SfxPoolItem&)aSrnd).PutValue(*pSurAnch, MID_SURROUND_ANCHORONLY);
+        rSet.Put(aSrnd);
+    }
+    uno::Any* pLeft         = 0;
+    GetProperty(C2S(UNO_NAME_LEFT_BORDER)  ,    pLeft  );
+    uno::Any* pRight        = 0;
+    GetProperty(C2S(UNO_NAME_RIGHT_BORDER) ,    pRight );
+    uno::Any* pTop      = 0;
+    GetProperty(C2S(UNO_NAME_TOP_BORDER)      , pTop   );
+    uno::Any* pBottom   = 0;
+    GetProperty(C2S(UNO_NAME_BOTTOM_BORDER),    pBottom);
+    uno::Any* pDistance     = 0;
+    GetProperty(C2S(UNO_NAME_BORDER_DISTANCE),  pDistance);
+    if( pLeft || pRight || pTop ||  pBottom || pDistance)
+    {
+        SvxBoxItem aBox;
+        if( pLeft )
+            bRet &= ((SfxPoolItem&)aBox).PutValue(*pLeft, CONVERT_TWIPS|LEFT_BORDER );
+        if( pRight )
+            bRet &= ((SfxPoolItem&)aBox).PutValue(*pRight, CONVERT_TWIPS|RIGHT_BORDER );
+        if( pTop )
+            bRet &= ((SfxPoolItem&)aBox).PutValue(*pTop, CONVERT_TWIPS|TOP_BORDER);
+        if( pBottom )
+            bRet &= ((SfxPoolItem&)aBox).PutValue(*pBottom, CONVERT_TWIPS|BOTTOM_BORDER);
+        if( pDistance )
+            bRet &= ((SfxPoolItem&)aBox).PutValue(*pDistance, CONVERT_TWIPS|BORDER_DISTANCE);
+        rSet.Put(aBox);
+    }
+    {
+        uno::Any* pRelH = 0;
+        GetProperty(C2S(UNO_NAME_RELATIVE_HEIGHT), pRelH);
+        uno::Any* pRelW = 0;
+        GetProperty(C2S(UNO_NAME_RELATIVE_WIDTH), pRelW);
+        uno::Any* pSzRel = 0;
+        GetProperty(C2S(UNO_NAME_SIZE_RELATIVE), pSzRel);
+        uno::Any* pWidth = 0;
+        GetProperty(C2S(UNO_NAME_WIDTH), pWidth);
+        uno::Any* pHeight = 0;
+        GetProperty(C2S(UNO_NAME_HEIGHT), pHeight);
+        uno::Any* pSize = 0;
+        GetProperty(C2S(UNO_NAME_SIZE), pSize);
+        uno::Any* pSizeType = 0;
+        GetProperty(C2S(UNO_NAME_SIZE_TYPE), pSizeType);
+        if(pWidth || pHeight ||pRelH || pRelW || pSzRel || pSize ||pSizeType)
+        {
+            SwFmtFrmSize aFrmSz;
+            if(pWidth)
+                bRet &= ((SfxPoolItem&)aFrmSz).PutValue(*pWidth, MID_FRMSIZE_WIDTH|CONVERT_TWIPS);
+            if(pHeight)
+                bRet &= ((SfxPoolItem&)aFrmSz).PutValue(*pHeight, MID_FRMSIZE_HEIGHT|CONVERT_TWIPS);
+            if(pRelH )
+                bRet &= ((SfxPoolItem&)aFrmSz).PutValue(*pRelH, MID_FRMSIZE_REL_HEIGHT);
+            if(pRelW )
+                bRet &= ((SfxPoolItem&)aFrmSz).PutValue(*pRelW, MID_FRMSIZE_REL_WIDTH);
+            if(pSzRel)
+                bRet &= ((SfxPoolItem&)aFrmSz).PutValue(*pSzRel, MID_FRMSIZE_IS_SYNC_REL_SIZE);
+            if(pSize)
+                bRet &= ((SfxPoolItem&)aFrmSz).PutValue(*pSize, MID_FRMSIZE_SIZE|CONVERT_TWIPS);
+            if(pSizeType)
+                bRet &= ((SfxPoolItem&)aFrmSz).PutValue(*pSizeType, MID_FRMSIZE_SIZE_TYPE|CONVERT_TWIPS);
+            rSet.Put(aFrmSz);
+        }
+        else
+        {
+            SwFmtFrmSize aFrmSz;
+            awt::Size aSize;
+            aSize.Width = MM50;
+            aSize.Height = MM50;
+            uno::Any aSizeVal;
+            aSizeVal <<= aSize;
+            ((SfxPoolItem&)aFrmSz).PutValue(aSizeVal, MID_FRMSIZE_SIZE|CONVERT_TWIPS);
+            rSet.Put(aFrmSz);
+        }
+    }
+    return bRet;
+}
+/* -----------------22.06.98 09:17-------------------
+ *
+ * --------------------------------------------------*/
+class SwFrameProperties_Impl : public BaseFrameProperties_Impl
+{
+    uno::Any*                   pAnyArr[FRM_PROP_COUNT];
+    sal_uInt16                      nArrLen;
+
+public:
+    SwFrameProperties_Impl();
+    ~SwFrameProperties_Impl();
+
+    virtual sal_Bool        SetProperty(const String& rName, uno::Any aVal);
+    virtual sal_Bool        GetProperty(const String& rName, uno::Any*& pAny );
+
+    virtual sal_Bool        AnyToItemSet(SfxItemSet& rFrmSet, SfxItemSet& rSet);
+};
+/* -----------------22.06.98 09:17-------------------
+ *
+ * --------------------------------------------------*/
+SwFrameProperties_Impl::SwFrameProperties_Impl() :
+    BaseFrameProperties_Impl(GetFrameDescMap()),
+    nArrLen(FRM_PROP_COUNT)
+{
+    for(sal_uInt16 i = 0; i < nArrLen; i++)
+        pAnyArr[i] = 0;
+}
+/* -----------------22.06.98 09:17-------------------
+ *
+ * --------------------------------------------------*/
+SwFrameProperties_Impl::~SwFrameProperties_Impl()
+{
+    for(sal_uInt16 i = 0; i < nArrLen; i++)
+        delete pAnyArr[i];
+}
+
+/* -----------------22.06.98 09:51-------------------
+ *
+ * --------------------------------------------------*/
+sal_Bool SwFrameProperties_Impl::SetProperty(const String& rName, uno::Any aVal)
+{
+    sal_uInt16 nPos = 0;
+    const SfxItemPropertyMap* pTemp = GetMap();
+    while( pTemp->pName )
+    {
+        if(COMPARE_EQUAL == rName.CompareToAscii(pTemp->pName))
+            break;
+        ++nPos;
+        ++pTemp;
+    }
+    if(nPos < nArrLen)
+    {
+        delete pAnyArr[nPos];
+        pAnyArr[nPos] = new uno::Any(aVal);
+    }
+    return nPos < nArrLen;
+}
+/* -----------------22.06.98 09:51-------------------
+ *
+ * --------------------------------------------------*/
+sal_Bool SwFrameProperties_Impl::GetProperty(const String& rName, uno::Any*& pAny)
+{
+    sal_uInt16 nPos = 0;
+    const SfxItemPropertyMap* pTemp = GetMap();
+    while( pTemp->pName )
+    {
+        if(COMPARE_EQUAL == rName.CompareToAscii(pTemp->pName))
+            break;
+        ++nPos;
+        ++pTemp;
+    }
+    if(nPos < nArrLen)
+        pAny = pAnyArr[nPos];
+    return nPos < nArrLen && pAny;
+}
+/* -----------------22.06.98 11:27-------------------
+ *
+ * --------------------------------------------------*/
+sal_Bool    SwFrameProperties_Impl::AnyToItemSet(SfxItemSet& rSet, SfxItemSet&)
+{
+    //Properties fuer alle Frames
+    sal_Bool bRet = FillBaseProperties(rSet);
+
+    uno::Any* pEdit;
+    if(GetProperty(C2S(UNO_NAME_EDIT_IN_READONLY), pEdit))
+    {
+        SfxBoolItem aBool(RES_EDIT_IN_READONLY);
+        ((SfxPoolItem&)aBool).PutValue(*pEdit, 0);
+        rSet.Put(aBool);
+    }
+    return bRet;
+}
+/****************************************************************************
+    Grafik-Descriptor
+****************************************************************************/
+class SwGraphicProperties_Impl : public BaseFrameProperties_Impl
+{
+    uno::Any*                   pAnyArr[GRPH_PROP_COUNT];
+    sal_uInt16                      nArrLen;
+
+public:
+    SwGraphicProperties_Impl();
+    ~SwGraphicProperties_Impl();
+
+    virtual sal_Bool        SetProperty(const String& rName, uno::Any aVal);
+    virtual sal_Bool        GetProperty(const String& rName, uno::Any*& pAny );
+
+    virtual sal_Bool                AnyToItemSet(SfxItemSet& rFrmSet, SfxItemSet& rSet);
+};
+/* -----------------27.06.98 14:53-------------------
+ *
+ * --------------------------------------------------*/
+SwGraphicProperties_Impl::SwGraphicProperties_Impl() :
+    BaseFrameProperties_Impl(GetGraphicDescMap()),
+    nArrLen(GRPH_PROP_COUNT)
+{
+    for(sal_uInt16 i = 0; i < nArrLen; i++)
+        pAnyArr[i] = 0;
+}
+/* -----------------27.06.98 14:54-------------------
+ *
+ * --------------------------------------------------*/
+SwGraphicProperties_Impl::~SwGraphicProperties_Impl()
+{
+    for(sal_uInt16 i = 0; i < nArrLen; i++)
+        delete pAnyArr[i];
+}
+/* -----------------27.06.98 14:53-------------------
+ *
+ * --------------------------------------------------*/
+sal_Bool SwGraphicProperties_Impl::SetProperty(const String& rName, uno::Any aVal)
+{
+    sal_uInt16 nPos = 0;
+    const SfxItemPropertyMap* pTemp = GetMap();
+    while( pTemp->pName )
+    {
+        if(rName.CompareToAscii(pTemp->pName) == COMPARE_EQUAL)
+            break;
+        ++nPos;
+        ++pTemp;
+    }
+    if(nPos < nArrLen)
+    {
+        delete pAnyArr[nPos];
+        pAnyArr[nPos] = new uno::Any(aVal);
+    }
+    return nPos < nArrLen;
+}
+/* -----------------27.06.98 14:53-------------------
+ *
+ * --------------------------------------------------*/
+sal_Bool SwGraphicProperties_Impl::GetProperty(const String& rName, uno::Any*& pAny)
+{
+    sal_uInt16 nPos = 0;
+    const SfxItemPropertyMap* pTemp = GetMap();
+    while( pTemp->pName )
+    {
+        if(COMPARE_EQUAL == rName.CompareToAscii(pTemp->pName))
+            break;
+        ++nPos;
+        ++pTemp;
+    }
+    if(nPos < nArrLen)
+        pAny = pAnyArr[nPos];
+    return pAny &&nPos < nArrLen;
+}
+/* -----------------27.06.98 14:40-------------------
+ *
+ * --------------------------------------------------*/
+sal_Bool    SwGraphicProperties_Impl::AnyToItemSet(
+            SfxItemSet& rFrmSet,
+            SfxItemSet& rGrSet)
+{
+    //Properties fuer alle Frames
+    sal_Bool bRet = FillBaseProperties(rFrmSet);
+
+    uno::Any* pHMirror = 0;
+    GetProperty(C2S(UNO_NAME_HORI_MIRRORED), pHMirror);
+    uno::Any* pVMirror = 0;
+    GetProperty(C2S(UNO_NAME_VERT_MIRRORED), pVMirror);
+    uno::Any* pPageToggle = 0;
+    GetProperty(C2S(UNO_NAME_MIRROR_PAGE_TOGGLE), pPageToggle);
+    if(pHMirror || pVMirror || pPageToggle)
+    {
+        SwMirrorGrf aMirror;
+        if(pHMirror)
+            bRet &= ((SfxPoolItem&)aMirror).PutValue(*pHMirror, MID_MIRROR_HORZ);
+        if(pVMirror)
+            bRet &= ((SfxPoolItem&)aMirror).PutValue(*pVMirror, MID_MIRROR_VERT);
+        if(pPageToggle)
+            bRet &= ((SfxPoolItem&)aMirror).PutValue(*pPageToggle, MID_MIRROR_HORZ_PAGETOGGLE);
+        rGrSet.Put(aMirror);
+    }
+    uno::Any* pCrop;
+    if(GetProperty(C2S(UNO_NAME_GRAPHIC_CROP), pCrop))
+    {
+        SwCropGrf aCrop;
+        bRet &= ((SfxPoolItem&)aCrop).PutValue(*pCrop);
+        rGrSet.Put(aCrop);
+    }
+    return bRet;
+}
+
+
+/******************************************************************
+ *  SwXFrame
+ ******************************************************************/
+/* -----------------------------10.03.00 18:02--------------------------------
+
+ ---------------------------------------------------------------------------*/
+const uno::Sequence< sal_Int8 > & SwXFrame::getUnoTunnelId()
+{
+    static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId();
+    return aSeq;
+}
+/* -----------------------------10.03.00 18:04--------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Int64 SAL_CALL SwXFrame::getSomething( const uno::Sequence< sal_Int8 >& rId )
+    throw(RuntimeException)
+{
+    if( rId.getLength() == 16
+        && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+                                        rId.getConstArray(), 16 ) )
+    {
+            return (sal_Int64)this;
+    }
+    return 0;
+}
+/*-----------------24.03.98 14:49-------------------
+
+--------------------------------------------------*/
+
+TYPEINIT1(SwXFrame, SwClient);
+/* -----------------------------06.04.00 14:20--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXFrame::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXFrame");
+}
+/* -----------------------------06.04.00 14:20--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXFrame::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.text.Frame") == rServiceName;
+}
+/* -----------------------------06.04.00 14:20--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXFrame::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.Frame");
+    return aRet;
+}
+/*-- 11.12.98 15:05:00---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXFrame::SwXFrame() :
+    eType(FLYCNTTYPE_FRM),
+    aLstnrCntnr( (container::XNamed*)this),
+    aPropSet(0),
+    _pMap(0),
+    bIsDescriptor(sal_False),
+    pProps(0)
+{
+
+}
+/*-- 14.01.99 11:31:52---------------------------------------------------
+    Dieser CTor legt den Frame als Descriptor an
+  -----------------------------------------------------------------------*/
+SwXFrame::SwXFrame(FlyCntType eSet, const SfxItemPropertyMap*   pMap) :
+    aLstnrCntnr( (container::XNamed*)this),
+    eType(eSet),
+    aPropSet(pMap),
+    _pMap(pMap),
+    bIsDescriptor(sal_True)
+{
+    switch(eType)
+    {
+        case FLYCNTTYPE_FRM:
+            pProps = new SwFrameProperties_Impl();
+        break;
+        case FLYCNTTYPE_GRF:
+            pProps = new SwGraphicProperties_Impl();
+        break;
+        case FLYCNTTYPE_OLE:
+            pProps = 0;
+        break;
+    }
+}
+
+/*-- 11.12.98 15:05:01---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXFrame::SwXFrame(SwFrmFmt& rFrmFmt, FlyCntType eSet, const SfxItemPropertyMap* pMap) :
+    eType(eSet),
+    SwClient( &rFrmFmt ),
+    aLstnrCntnr( (container::XNamed*)this),
+    aPropSet(pMap),
+    _pMap(pMap),
+    bIsDescriptor(sal_False),
+    pProps(0)
+{
+
+}
+/*-- 11.12.98 15:05:02---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXFrame::~SwXFrame()
+{
+    delete pProps;
+}
+/*-- 11.12.98 15:05:03---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+/*-- 11.12.98 15:05:03---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+OUString SwXFrame::getName(void) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    String sRet;
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt)
+        sRet = pFmt->GetName();
+    else if(bIsDescriptor)
+        sRet = sName;
+    else
+        throw RuntimeException();
+    return sRet;
+}
+/*-- 11.12.98 15:05:03---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFrame::setName(const OUString& rName) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwFrmFmt* pFmt = GetFrmFmt();
+    String sTmpName(rName);
+    if(pFmt)
+    {
+        pFmt->GetDoc()->SetFlyName((SwFlyFrmFmt&)*pFmt, sTmpName);
+        if(pFmt->GetName() != sTmpName)
+        {
+            throw RuntimeException();
+        }
+    }
+    else if(bIsDescriptor)
+        sName = sTmpName;
+    else
+        throw RuntimeException();
+}
+/*-- 11.12.98 15:05:03---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XPropertySetInfo >  SwXFrame::getPropertySetInfo(void) throw( RuntimeException )
+{
+    uno::Reference< XPropertySetInfo >  xRef;
+    static uno::Reference< XPropertySetInfo >  xFrmRef;
+    static uno::Reference< XPropertySetInfo >  xGrfRef;
+    static uno::Reference< XPropertySetInfo >  xOLERef;
+    switch(eType)
+    {
+    case FLYCNTTYPE_FRM:
+        if( !xFrmRef.is() )
+            xFrmRef = aPropSet.getPropertySetInfo();
+        xRef = xFrmRef;
+        break;
+    case FLYCNTTYPE_GRF:
+        if( !xGrfRef.is() )
+            xGrfRef = aPropSet.getPropertySetInfo();
+        xRef = xGrfRef;
+        break;
+    case FLYCNTTYPE_OLE:
+        if( !xOLERef.is() )
+            xOLERef = aPropSet.getPropertySetInfo();
+        xRef = xOLERef;
+        break;
+    }
+    return xRef;
+}
+/*-- 11.12.98 15:05:04---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFrame::setPropertyValue(const OUString& rPropertyName, const uno::Any& aValue)
+    throw( UnknownPropertyException, PropertyVetoException, lang::IllegalArgumentException, WrappedTargetException, RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt)
+    {
+        sal_Bool bNextFrame = sal_False;
+        const SfxItemPropertyMap* pCur = SfxItemPropertyMap::GetByName(_pMap, rPropertyName);
+        SwDoc* pDoc = pFmt->GetDoc();
+        if( eType == FLYCNTTYPE_GRF &&
+                    (COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_ALTERNATIVE_TEXT)||
+                    (pCur &&
+                    (pCur->nWID == RES_GRFATR_CROPGRF ||
+                        pCur->nWID == RES_GRFATR_MIRRORGRF))))
+        {
+            const SwNodeIndex* pIdx = pFmt->GetCntnt().GetCntntIdx();
+            if(pIdx)
+            {
+                SwNodeIndex aIdx(*pIdx, 1);
+                SwNoTxtNode* pNoTxt = aIdx.GetNode().GetNoTxtNode();
+                if(COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_ALTERNATIVE_TEXT))
+                {
+                    OUString uTemp;
+                    aValue >>= uTemp;
+                    pNoTxt->SetAlternateText(uTemp);
+                }
+                else
+                {
+                    SfxItemSet aSet(pNoTxt->GetSwAttrSet());
+                    aPropSet.setPropertyValue(rPropertyName, aValue, aSet);
+                    pNoTxt->SetAttr(aSet);
+                }
+            }
+        }
+        else if(COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_FRAME_STYLE_NAME))
+        {
+            SwDocShell* pDocSh = pFmt->GetDoc()->GetDocShell();
+            if(pDocSh)
+            {
+                OUString uTemp;
+                aValue >>= uTemp;
+                String sStyle(SwXStyleFamilies::GetUIName(uTemp, SFX_STYLE_FAMILY_FRAME));
+                SwDocStyleSheet* pStyle =
+                    (SwDocStyleSheet*)pDocSh->GetStyleSheetPool()->Find(sStyle, SFX_STYLE_FAMILY_FRAME);
+                if(pStyle)
+                {
+//                  pSh->SetFrmFmt( pStyle->GetFrmFmt() );
+                    UnoActionContext aAction(pFmt->GetDoc());
+                    pFmt->GetDoc()->SetFrmFmtToFly( *pFmt, *pStyle->GetFrmFmt());
+                }
+                else
+                    throw IllegalArgumentException();
+            }
+        }
+        else if( COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_GRAPHIC_URL) ||
+                COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_GRAPHIC_FILTER))
+        {
+            String sGrfName, sFltName;
+            pFmt->GetDoc()->GetGrfNms( *(SwFlyFrmFmt*)pFmt, &sGrfName, &sFltName );
+            OUString uTemp;
+            aValue >>= uTemp;
+            String sTmp(uTemp);
+            UnoActionContext aAction(pFmt->GetDoc());
+            if(COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_GRAPHIC_URL))
+                sGrfName = sTmp;
+            else
+                sFltName = sTmp;
+
+            const SwNodeIndex* pIdx = pFmt->GetCntnt().GetCntntIdx();
+            if(pIdx)
+            {
+                SwNodeIndex aIdx(*pIdx, 1);
+//              SwNoTxtNode* pNoTxt = aIdx.GetNode().GetNoTxtNode();
+                SwGrfNode* pGrfNode = aIdx.GetNode().GetGrfNode();
+                if(!pGrfNode)
+                    throw RuntimeException();
+                SwPaM aGrfPaM(*pGrfNode);
+                pFmt->GetDoc()->ReRead( aGrfPaM, sGrfName, sFltName, 0 );
+            }
+        }
+        else if(0 != (bNextFrame = (COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_CHAIN_NEXT_NAME)))
+            || COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_CHAIN_PREV_NAME))
+        {
+            OUString uTemp;
+            aValue >>= uTemp;
+            String sChainName(uTemp);
+            if(!sChainName.Len())
+            {
+                if(bNextFrame)
+                    pDoc->Unchain(*pFmt);
+                else
+                {
+                    SwFmtChain aChain( pFmt->GetChain() );
+                    SwFrmFmt *pPrev = aChain.GetPrev();
+                    if(pPrev)
+                        pDoc->Unchain(*pPrev);
+                }
+            }
+            else
+            {
+                sal_uInt16 nCount = pDoc->GetFlyCount(eType);
+
+                SwFrmFmt* pChain = 0;
+                for( sal_uInt16 i = 0; i < nCount; i++)
+                {
+                    SwFrmFmt* pFmt = pDoc->GetFlyNum(i, FLYCNTTYPE_FRM);
+                    if(sChainName == pFmt->GetName() )
+                    {
+                        pChain = pFmt;
+                        break;
+                    }
+                }
+                if(pChain)
+                {
+                    SwFrmFmt* pSource = bNextFrame ? pFmt : pChain;
+                    SwFrmFmt* pDest = bNextFrame ? pChain: pFmt;
+                    pDoc->Chain(*pSource, *pDest);
+                }
+            }
+        }
+        else
+        {
+            SfxItemSet aSet( pDoc->GetAttrPool(),
+                RES_FRMATR_BEGIN, RES_FRMATR_END - 1 );
+
+            aSet.SetParent(&pFmt->GetAttrSet());
+            aPropSet.setPropertyValue(rPropertyName, aValue, aSet);
+            if(COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_ANCHOR_TYPE))
+                pFmt->GetDoc()->SetFlyFrmAttr( *pFmt, aSet );
+            else
+                pFmt->SetAttr(aSet);
+        }
+    }
+    else if(IsDescriptor())
+    {
+        if(!pProps->SetProperty(rPropertyName, aValue))
+            throw IllegalArgumentException();
+    }
+    else
+        throw RuntimeException();
+}
+/*-- 11.12.98 15:05:04---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXFrame::getPropertyValue(const OUString& rPropertyName)
+    throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Any aAny;
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_ANCHOR_TYPES))
+    {
+        uno::Sequence aTypes(5);
+         TextContentAnchorType* pArray = aTypes.getArray();
+        pArray[0] = TextContentAnchorType_AT_PARAGRAPH;
+        pArray[1] = TextContentAnchorType_AS_CHARACTER;
+        pArray[2] = TextContentAnchorType_AT_PAGE;
+        pArray[3] = TextContentAnchorType_AT_FRAME;
+        pArray[4] = TextContentAnchorType_AT_CHARACTER;
+        aAny.setValue(&aTypes, ::getCppuType((uno::Sequence*)0));
+    }
+    else if(pFmt)
+    {
+        const SfxItemPropertyMap* pCur = SfxItemPropertyMap::GetByName(_pMap, rPropertyName);
+        if(eType == FLYCNTTYPE_GRF &&
+                pCur &&
+                (pCur->nWID == RES_GRFATR_CROPGRF ||
+                    pCur->nWID == RES_GRFATR_MIRRORGRF))
+        {
+            const SwNodeIndex* pIdx = pFmt->GetCntnt().GetCntntIdx();
+            if(pIdx)
+            {
+                SwNodeIndex aIdx(*pIdx, 1);
+                SwNoTxtNode* pNoTxt = aIdx.GetNode().GetNoTxtNode();
+                SfxItemSet aSet(pNoTxt->GetSwAttrSet());
+                aAny = aPropSet.getPropertyValue(rPropertyName, aSet);
+            }
+        }
+        else if( COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_GRAPHIC_URL)||
+            COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_GRAPHIC_FILTER))
+        {
+            String sGrfName, sFltName;
+            pFmt->GetDoc()->GetGrfNms( *(SwFlyFrmFmt*)pFmt, &sGrfName, &sFltName );
+            if(COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_GRAPHIC_URL))
+                aAny <<= OUString(sGrfName);
+            else
+                aAny <<= OUString(sFltName);
+        }
+        else if(COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_FRAME_STYLE_NAME))
+        {
+            aAny <<= OUString(SwXStyleFamilies::GetProgrammaticName(pFmt->DerivedFrom()->GetName(), SFX_STYLE_FAMILY_FRAME));
+        }
+        else if(eType == FLYCNTTYPE_GRF &&
+                (COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_ACTUAL_SIZE) ||
+                    COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_ALTERNATIVE_TEXT)))
+        {
+            const SwNodeIndex* pIdx = pFmt->GetCntnt().GetCntntIdx();
+            if(pIdx)
+            {
+                SwNodeIndex aIdx(*pIdx, 1);
+                SwNoTxtNode* pNoTxt = aIdx.GetNode().GetNoTxtNode();
+                if(COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_ALTERNATIVE_TEXT))
+                    aAny <<= OUString(pNoTxt->GetAlternateText());
+                else
+                {
+                     Size aActSize = ((SwGrfNode*)pNoTxt)->GetTwipSize();
+                    awt::Size aTmp;
+                    aTmp.Width = TWIP_TO_MM100(aActSize.Width());
+                    aTmp.Height = TWIP_TO_MM100(aActSize.Height());
+                    aAny.setValue(&aTmp, ::getCppuType((const awt::Size*)0));
+                }
+            }
+        }
+        else if(COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_LINK_DISPLAY_NAME))
+        {
+            aAny <<= OUString(pFmt->GetName());
+        }
+        else
+        {
+            const SwAttrSet& rSet = pFmt->GetAttrSet();
+            aAny = aPropSet.getPropertyValue(rPropertyName, rSet);
+        }
+    }
+    else if(IsDescriptor())
+    {
+        uno::Any* pAny = 0;
+        if(!pProps->GetProperty(rPropertyName, pAny))
+        {
+            throw IllegalArgumentException();
+        }
+        else if(pAny)
+            aAny = *pAny;
+    }
+    else
+        throw RuntimeException();
+    return aAny;
+}
+/*-- 11.12.98 15:05:04---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFrame::addPropertyChangeListener(const OUString& PropertyName,
+    const uno::Reference< XPropertyChangeListener > & aListener)
+    throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 11.12.98 15:05:05---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFrame::removePropertyChangeListener(const OUString& PropertyName,
+    const uno::Reference< XPropertyChangeListener > & aListener)
+    throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 11.12.98 15:05:05---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFrame::addVetoableChangeListener(const OUString& PropertyName,
+                                const uno::Reference< XVetoableChangeListener > & aListener)
+    throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 11.12.98 15:05:05---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFrame::removeVetoableChangeListener(
+    const OUString& PropertyName, const uno::Reference< XVetoableChangeListener > & aListener)
+        throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 12.09.00 14:04:53---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+PropertyState SwXFrame::getPropertyState( const OUString& rPropertyName )
+    throw(UnknownPropertyException, RuntimeException)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    Sequence< OUString > aPropertyNames(1);
+    OUString* pNames = aPropertyNames.getArray();
+    pNames[0] = rPropertyName;
+    Sequence< PropertyState > aStates = getPropertyStates(aPropertyNames);
+    return aStates.getConstArray()[0];
+}
+/*-- 12.09.00 14:04:54---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Sequence< PropertyState > SwXFrame::getPropertyStates(
+    const Sequence< OUString >& aPropertyNames )
+        throw(UnknownPropertyException, RuntimeException)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    Sequence< PropertyState > aStates(aPropertyNames.getLength());
+    PropertyState* pStates = aStates.getArray();
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt)
+    {
+        const OUString* pNames = aPropertyNames.getConstArray();
+        const SwAttrSet& rFmtSet = pFmt->GetAttrSet();
+        for(int i = 0; i < aPropertyNames.getLength(); i++)
+        {
+            const SfxItemPropertyMap* pCur = SfxItemPropertyMap::GetByName(_pMap, pNames[i]);
+            if(!pCur)
+                throw UnknownPropertyException();
+            if(pCur->nWID == FN_UNO_ANCHOR_TYPES||
+                pCur->nWID == FN_PARAM_LINK_DISPLAY_NAME||
+                COMPARE_EQUAL == pNames[i].compareToAscii(UNO_NAME_FRAME_STYLE_NAME)||
+                COMPARE_EQUAL == pNames[i].compareToAscii(UNO_NAME_GRAPHIC_URL)||
+                COMPARE_EQUAL == pNames[i].compareToAscii(UNO_NAME_GRAPHIC_FILTER)||
+                COMPARE_EQUAL == pNames[i].compareToAscii(UNO_NAME_ACTUAL_SIZE) ||
+                COMPARE_EQUAL == pNames[i].compareToAscii(UNO_NAME_ALTERNATIVE_TEXT))
+                pStates[i] = PropertyState_DIRECT_VALUE;
+            else
+            {
+                if(eType == FLYCNTTYPE_GRF &&
+                        pCur &&
+                        (pCur->nWID == RES_GRFATR_CROPGRF ||
+                            pCur->nWID == RES_GRFATR_MIRRORGRF))
+                {
+                    const SwNodeIndex* pIdx = pFmt->GetCntnt().GetCntntIdx();
+                    if(pIdx)
+                    {
+                        SwNodeIndex aIdx(*pIdx, 1);
+                        SwNoTxtNode* pNoTxt = aIdx.GetNode().GetNoTxtNode();
+                        SfxItemSet aSet(pNoTxt->GetSwAttrSet());
+                        aSet.GetItemState(pCur->nWID);
+                        if(SFX_ITEM_SET == aSet.GetItemState( pCur->nWID, FALSE ))
+                            pStates[i] = beans::PropertyState_DIRECT_VALUE;
+                    }
+                }
+                else
+                {
+                    if(SFX_ITEM_SET == rFmtSet.GetItemState( pCur->nWID, FALSE ))
+                        pStates[i] = beans::PropertyState_DIRECT_VALUE;
+                    else
+                        pStates[i] = beans::PropertyState_DEFAULT_VALUE;
+                }
+            }
+        }
+    }
+    else if(IsDescriptor())
+    {
+        for(int i = 0; i < aPropertyNames.getLength(); i++)
+            pStates[i] = PropertyState_DIRECT_VALUE;
+    }
+    else
+        throw RuntimeException();
+    return aStates;
+}
+/*-- 12.09.00 14:04:54---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFrame::setPropertyToDefault( const OUString& rPropertyName )
+    throw(UnknownPropertyException, RuntimeException)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt)
+    {
+        const SwAttrSet& rFmtSet = pFmt->GetAttrSet();
+        const SfxItemPropertyMap* pCur = SfxItemPropertyMap::GetByName(_pMap, rPropertyName);
+        if(!pCur)
+            throw UnknownPropertyException();
+        BOOL bNextFrame;
+        if( pCur->nWID &&
+            pCur->nWID != FN_UNO_ANCHOR_TYPES &&
+            pCur->nWID != FN_PARAM_LINK_DISPLAY_NAME)
+        {
+            if( eType == FLYCNTTYPE_GRF &&
+                        (COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_ALTERNATIVE_TEXT)||
+                        (pCur &&
+                        (pCur->nWID == RES_GRFATR_CROPGRF ||
+                            pCur->nWID == RES_GRFATR_MIRRORGRF))))
+            {
+                const SwNodeIndex* pIdx = pFmt->GetCntnt().GetCntntIdx();
+                if(pIdx)
+                {
+                    SwNodeIndex aIdx(*pIdx, 1);
+                    SwNoTxtNode* pNoTxt = aIdx.GetNode().GetNoTxtNode();
+                    if(COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_ALTERNATIVE_TEXT))
+                    {
+                        pNoTxt->SetAlternateText(aEmptyStr);
+                    }
+                    else
+                    {
+                        SfxItemSet aSet(pNoTxt->GetSwAttrSet());
+                        aSet.ClearItem(pCur->nWID);
+                        pNoTxt->SetAttr(aSet);
+                    }
+                }
+            }
+            else
+            {
+                SwDoc* pDoc = pFmt->GetDoc();
+                SfxItemSet aSet( pDoc->GetAttrPool(),
+                    RES_FRMATR_BEGIN, RES_FRMATR_END - 1 );
+                aSet.SetParent(&pFmt->GetAttrSet());
+                aSet.ClearItem(pCur->nWID);
+                if(COMPARE_EQUAL != rPropertyName.compareToAscii(UNO_NAME_ANCHOR_TYPE))
+                    pFmt->SetAttr(aSet);
+            }
+        }
+        else if(0 != (bNextFrame = (COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_CHAIN_NEXT_NAME)))
+                || COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_CHAIN_PREV_NAME))
+        {
+            SwDoc* pDoc = pFmt->GetDoc();
+            if(bNextFrame)
+                pDoc->Unchain(*pFmt);
+            else
+            {
+                SwFmtChain aChain( pFmt->GetChain() );
+                SwFrmFmt *pPrev = aChain.GetPrev();
+                if(pPrev)
+                    pDoc->Unchain(*pPrev);
+            }
+        }
+    }
+    else if(!IsDescriptor())
+        throw RuntimeException();
+
+}
+/*-- 12.09.00 14:04:55---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Any SwXFrame::getPropertyDefault( const OUString& rPropertyName )
+    throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    Any aRet;
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt)
+    {
+        const SfxItemPropertyMap* pCur = SfxItemPropertyMap::GetByName(_pMap, rPropertyName);
+        if(pCur)
+        {
+            if(pCur->nWID < RES_FRMATR_END)
+            {
+                const SfxPoolItem& rDefItem =
+                    pFmt->GetDoc()->GetAttrPool().GetDefaultItem(pCur->nWID);
+                rDefItem.QueryValue(aRet, pCur->nMemberId);
+            }
+        }
+        else
+            throw UnknownPropertyException();
+    }
+    else if(!IsDescriptor())
+        throw RuntimeException();
+    return aRet;
+}
+/* -----------------22.04.99 14:59-------------------
+ *
+ * --------------------------------------------------*/
+void SwXFrame::addEventListener(const uno::Reference< XEventListener > & aListener) throw( RuntimeException )
+{
+    if(!GetRegisteredIn())
+        throw RuntimeException();
+    aLstnrCntnr.AddListener(aListener);
+}
+/* -----------------22.04.99 14:59-------------------
+ *
+ * --------------------------------------------------*/
+void SwXFrame::removeEventListener(const uno::Reference< XEventListener > & aListener) throw( RuntimeException )
+{
+    if(!GetRegisteredIn() || !aLstnrCntnr.RemoveListener(aListener))
+        throw RuntimeException();
+}
+/*-- 11.12.98 15:05:06---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void    SwXFrame::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew)
+{
+    ClientModify(this, pOld, pNew);
+    if(!GetRegisteredIn())
+        aLstnrCntnr.Disposing();
+}
+
+/*-- 11.12.98 15:23:05---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFrame::dispose(void) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt)
+    {
+        if( pFmt->GetAnchor().GetAnchorId() == FLY_IN_CNTNT )
+            {
+                const SwPosition &rPos = *(pFmt->GetAnchor().GetCntntAnchor());
+                SwTxtNode *pTxtNode = rPos.nNode.GetNode().GetTxtNode();
+                const xub_StrLen nIdx = rPos.nContent.GetIndex();
+                pTxtNode->Delete( RES_TXTATR_FLYCNT, nIdx, nIdx );
+            }
+            else
+                pFmt->GetDoc()->DelLayoutFmt(pFmt);
+    }
+    else
+        throw RuntimeException();
+
+}
+/*-- 11.12.98 16:02:27---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XTextRange >  SwXFrame::getAnchor(void) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< XTextRange >  aRef;
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt)
+    {
+        if( pFmt->GetAnchor().GetAnchorId() != FLY_PAGE )
+        {
+            const SwPosition &rPos = *(pFmt->GetAnchor().GetCntntAnchor());
+            aRef = ::CreateTextRangeFromPosition(pFmt->GetDoc(), rPos, 0);
+        }
+    }
+    else
+        throw RuntimeException();
+    return aRef;
+}
+/* -----------------14.01.99 12:02-------------------
+ *
+ * --------------------------------------------------*/
+void SwXFrame::ResetDescriptor()
+{
+    bIsDescriptor = sal_False;
+    DELETEZ(pProps);
+}
+/* -----------------18.02.99 13:34-------------------
+ *
+ * --------------------------------------------------*/
+void SwXFrame::attachToRange(const uno::Reference< XTextRange > & xTextRange)
+            throw( IllegalArgumentException, RuntimeException )
+{
+    if(!IsDescriptor())
+        throw RuntimeException();
+    uno::Reference xRangeTunnel( xTextRange, uno::UNO_QUERY);
+    SwXTextRange* pRange = 0;
+    SwXTextCursor* pCursor = 0;
+    if(xRangeTunnel.is())
+    {
+        pRange = (SwXTextRange*)xRangeTunnel->getSomething(
+                                SwXTextRange::getUnoTunnelId());
+        pCursor = (SwXTextCursor*)xRangeTunnel->getSomething(
+                                SwXTextCursor::getUnoTunnelId());
+    }
+
+
+    SwDoc* pDoc = pRange ? (SwDoc*)pRange->GetDoc() : pCursor ? (SwDoc*)pCursor->GetDoc() : 0;
+    if(pDoc)
+    {
+        SwUnoInternalPaM aIntPam(*pDoc);
+        //das muss jetzt sal_True liefern
+        SwXTextRange::XTextRangeToSwPaM(aIntPam, xTextRange);
+
+        SwNode& rNode = pDoc->GetNodes().GetEndOfContent();
+        SwPaM aPam(rNode);
+        aPam.Move( fnMoveBackward, fnGoDoc );
+        static sal_uInt16 __READONLY_DATA aFrmAttrRange[] =
+        {
+            RES_FRMATR_BEGIN,       RES_FRMATR_END-1,
+            SID_ATTR_BORDER_INNER,  SID_ATTR_BORDER_INNER,
+            0
+        };
+        static sal_uInt16 __READONLY_DATA aGrAttrRange[] =
+        {
+            RES_GRFATR_BEGIN,       RES_GRFATR_END-1,
+            0
+        };
+        SfxItemSet aGrSet(pDoc->GetAttrPool(), aGrAttrRange );
+
+        SfxItemSet aFrmSet(pDoc->GetAttrPool(), aFrmAttrRange );
+        //jetzt muessen die passenden Items in den Set
+        if(!pProps->AnyToItemSet(aFrmSet, aGrSet))
+            throw IllegalArgumentException();
+        //der TextRange wird einzeln behandelt
+        *aPam.GetPoint() = *aIntPam.GetPoint();
+        if(aIntPam.HasMark())
+        {
+            aPam.SetMark();
+            *aPam.GetMark() = *aIntPam.GetMark();
+        }
+
+        const SfxPoolItem* pItem;
+        if(SFX_ITEM_SET == aFrmSet.GetItemState(RES_ANCHOR, sal_False, &pItem) &&
+            FLY_AT_FLY ==((const SwFmtAnchor*)pItem)->GetAnchorId() &&
+            !aPam.GetNode()->FindFlyStartNode())
+        {
+            //rahmengebunden geht nur dort, wo ein Rahmen ist!
+            SwFmtAnchor aAnchor(FLY_AT_CNTNT);
+            aFrmSet.Put(aAnchor);
+        }
+
+        SwFlyFrmFmt* pFmt = 0;
+        if( eType == FLYCNTTYPE_FRM)
+        {
+            UnoActionContext aCont(pDoc);
+            pFmt = pDoc->MakeFlySection( FLY_AT_CNTNT, aPam.GetPoint(), &aFrmSet );
+            if(pFmt)
+            {
+                pFmt->Add(this);
+                if(sName.Len())
+                    pDoc->SetFlyName((SwFlyFrmFmt&)*pFmt, sName);
+            }
+            //den SwXText wecken
+            ((SwXTextFrame*)this)->SetDoc(GetFrmFmt()->GetDoc());
+        }
+        else if( eType == FLYCNTTYPE_GRF)
+        {
+            UnoActionContext aCont(pDoc);
+            SwFlyFrmFmt* pFmt = 0;
+
+            uno::Any* pGraphicURL;
+            String sGraphicURL;
+            if(pProps->GetProperty(C2S(UNO_NAME_GRAPHIC_URL), pGraphicURL))
+            {
+                OUString uTemp;
+                (*pGraphicURL) >>= uTemp;
+                sGraphicURL = String(uTemp);
+            }
+
+            String sFltName;
+            uno::Any* pFilter;
+            if(pProps->GetProperty(C2S(UNO_NAME_GRAPHIC_FILTER), pFilter))
+            {
+                OUString uTemp;
+                (*pFilter) >>= uTemp;
+                sFltName = String(uTemp);
+            }
+
+            SwFlyFrmFmt* pGFmt =    pDoc->Insert(aPam,
+                                    sGraphicURL,
+                                    sFltName, 0, &aFrmSet, &aGrSet);
+            uno::Any* pAltText;
+            if(pGFmt)
+            {
+                pGFmt->Add(this);
+                if(sName.Len())
+                    pDoc->SetFlyName((SwFlyFrmFmt&)*pGFmt, sName);
+            }
+            if(pProps->GetProperty(C2S(UNO_NAME_ALTERNATIVE_TEXT), pAltText))
+                setPropertyValue(C2U(UNO_NAME_ALTERNATIVE_TEXT), *pAltText);
+        }
+        else
+        {
+            DBG_ERROR("EmbeddedObject: not implemented")
+            throw RuntimeException();
+        }
+    }
+    else
+        throw IllegalArgumentException();
+    //setzt das Flag zurueck und loescht den Descriptor-Pointer
+    ResetDescriptor();
+}
+
+/*-- 22.04.99 08:03:20---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+awt::Point SwXFrame::getPosition(void) throw( RuntimeException )
+{
+    throw RuntimeException();
+    return awt::Point();
+}
+/*-- 22.04.99 08:03:21---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFrame::setPosition(const awt::Point& aPosition) throw( RuntimeException )
+{
+    throw RuntimeException();
+}
+/*-- 22.04.99 08:03:21---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+awt::Size SwXFrame::getSize(void) throw( RuntimeException )
+{
+    uno::Any aVal = getPropertyValue(C2U("Size"));
+    awt::Size* pRet =  (awt::Size*)aVal.getValue();
+    return *pRet;
+}
+/*-- 22.04.99 08:03:21---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFrame::setSize(const awt::Size& aSize)
+    throw( PropertyVetoException, RuntimeException )
+{
+    uno::Any aVal(&aSize, ::getCppuType((const awt::Size*)0));
+    setPropertyValue(C2U("Size"), aVal);
+}
+/*-- 22.04.99 08:03:21---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+OUString SwXFrame::getShapeType(void) throw( RuntimeException )
+{
+    return C2U("FrameShape");
+}
+
+/******************************************************************
+ *  SwXTextFrame
+ ******************************************************************/
+/*-- 14.01.99 11:27:51---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextFrame::SwXTextFrame() :
+    SwXFrame(FLYCNTTYPE_FRM, aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_FRAME)),
+    SwXText(0, CURSOR_FRAME)
+{
+}
+/*-- 11.12.98 15:23:01---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextFrame::SwXTextFrame(SwFrmFmt& rFmt) :
+    SwXFrame(rFmt, FLYCNTTYPE_FRM, aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_FRAME)),
+    SwXText(rFmt.GetDoc(), CURSOR_FRAME)
+{
+
+}
+/*-- 11.12.98 15:23:02---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextFrame::~SwXTextFrame()
+{
+}
+/* -----------------------------15.03.00 16:30--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SAL_CALL SwXTextFrame::acquire(  )throw()
+{
+    SwXFrame::acquire();
+}
+/* -----------------------------15.03.00 16:30--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SAL_CALL SwXTextFrame::release(  )throw()
+{
+    SwXFrame::release();
+}
+/* -----------------------------15.03.00 16:30--------------------------------
+
+ ---------------------------------------------------------------------------*/
+uno::Any SAL_CALL SwXTextFrame::queryInterface( const uno::Type& aType )
+    throw (RuntimeException)
+{
+    uno::Any aRet = SwXText::queryInterface(aType);
+    if(aRet.getValueType() == ::getCppuVoidType())
+        aRet = SwXFrame::queryInterface(aType);
+    if(aRet.getValueType() == ::getCppuVoidType())
+        aRet = SwXTextFrameBaseClass::queryInterface(aType);
+    return aRet;
+}
+/* -----------------------------15.03.00 16:30--------------------------------
+
+ ---------------------------------------------------------------------------*/
+uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL SwXTextFrame::getTypes(  ) throw(RuntimeException)
+{
+    uno::Sequence< uno::Type > aTextFrameTypes = SwXTextFrameBaseClass::getTypes();
+    uno::Sequence< uno::Type > aFrameTypes = SwXFrame::getTypes();
+    uno::Sequence< uno::Type > aTextTypes = SwXText::getTypes();
+
+    long nIndex = aTextFrameTypes.getLength();
+    aTextFrameTypes.realloc(
+        aTextFrameTypes.getLength() +
+        aFrameTypes.getLength() +
+        aTextTypes.getLength());
+
+    uno::Type* pTextFrameTypes = aTextFrameTypes.getArray();
+    const uno::Type* pFrameTypes = aFrameTypes.getConstArray();
+    long nPos;
+    for(nPos = 0; nPos  SAL_CALL SwXTextFrame::getImplementationId(  ) throw(RuntimeException)
+{
+    static uno::Sequence< sal_Int8 > aId( 16 );
+    static BOOL bInit = FALSE;
+    if(!bInit)
+        rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
+    return aId;
+}
+/*-- 11.12.98 15:23:03---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XText >  SwXTextFrame::getText(void) throw( RuntimeException )
+{
+    return this;
+}
+/*-- 11.12.98 15:23:03---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XTextCursor >   SwXTextFrame::createCursor()
+{
+    return createTextCursor();
+}
+/*-- 11.12.98 15:23:03---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XTextCursor >  SwXTextFrame::createTextCursor(void) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< XTextCursor >  aRef;
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt)
+    {
+        SwPosition aPos(pFmt->GetCntnt().GetCntntIdx()->GetNode());
+        SwXTextCursor* pXCrsr = new SwXTextCursor(this, aPos, CURSOR_FRAME, pFmt->GetDoc());
+        aRef =  (XWordCursor*)pXCrsr;
+        SwUnoCrsr*  pUnoCrsr = pXCrsr->GetCrsr();
+        pUnoCrsr->Move(fnMoveForward, fnGoNode);
+//      // no Cursor in protected sections
+//      SwCrsrSaveState aSave( *pUnoCrsr );
+//      if(pUnoCrsr->IsInProtectTable( sal_True ) ||
+//          pUnoCrsr->IsSelOvr( SELOVER_TOGGLE | SELOVER_CHANGEPOS ))
+//          throw  RuntimeException() );
+    }
+    else
+        throw RuntimeException();
+    return aRef;
+}
+/*-- 11.12.98 15:23:03---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XTextCursor >  SwXTextFrame::createTextCursorByRange(const uno::Reference< XTextRange > & aTextPosition) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< XTextCursor >  aRef;
+    SwFrmFmt* pFmt = GetFrmFmt();
+    SwUnoInternalPaM aPam(*GetDoc());
+    if(pFmt && SwXTextRange::XTextRangeToSwPaM(aPam, aTextPosition))
+    {
+        SwNode& rNode = pFmt->GetCntnt().GetCntntIdx()->GetNode();
+#ifdef DEBUG
+        const SwStartNode* p1 = aPam.GetNode()->FindFlyStartNode();
+        const SwStartNode* p2 = rNode.FindFlyStartNode();
+#endif
+        if(aPam.GetNode()->FindFlyStartNode() == rNode.FindFlyStartNode())
+            aRef =  (XWordCursor*)new SwXTextCursor(this ,
+                *aPam.GetPoint(), CURSOR_FRAME, pFmt->GetDoc(), aPam.GetMark());
+    }
+    else
+        throw RuntimeException();
+    return aRef;
+}
+/*-- 11.12.98 15:23:03---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< container::XEnumeration >  SwXTextFrame::createEnumeration(void) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< container::XEnumeration >  aRef;
+    SwFrmFmt* pFmt = GetFrmFmt();
+ uno::XInterface* pRet = 0;
+    if(pFmt)
+    {
+        SwPosition aPos(pFmt->GetCntnt().GetCntntIdx()->GetNode());
+        SwUnoCrsr* pUnoCrsr = GetDoc()->CreateUnoCrsr(aPos, sal_False);
+        pUnoCrsr->Move( fnMoveForward, fnGoNode );
+//      // no Cursor in protected sections
+//      SwCrsrSaveState aSave( *pUnoCrsr );
+//      if(pUnoCrsr->IsInProtectTable( sal_True ) ||
+//          pUnoCrsr->IsSelOvr( SELOVER_TOGGLE | SELOVER_CHANGEPOS ))
+//          throw  RuntimeException() );
+        aRef = new SwXParagraphEnumeration(this, pUnoCrsr, CURSOR_FRAME);
+    }
+    return aRef;
+}
+/*-- 11.12.98 15:23:04---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Type  SwXTextFrame::getElementType(void) throw( RuntimeException )
+{
+    return ::getCppuType((uno::Reference*)0);
+}
+/*-- 11.12.98 15:23:04---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextFrame::hasElements(void) throw( RuntimeException )
+{
+    return sal_True;
+}
+/*-- 11.12.98 15:23:04---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextFrame::attach(const uno::Reference< XTextRange > & xTextRange)
+    throw( IllegalArgumentException, RuntimeException )
+{
+
+}
+/*-- 11.12.98 15:23:04---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XTextRange >  SwXTextFrame::getAnchor(void) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    return SwXFrame::getAnchor();
+}
+/*-- 11.12.98 15:23:05---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextFrame::dispose(void) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwXFrame::dispose();
+}
+/*-- 11.12.98 15:23:05---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextFrame::addEventListener(const uno::Reference< XEventListener > & aListener) throw( RuntimeException )
+{
+    SwXFrame::addEventListener(aListener);
+}
+/*-- 11.12.98 15:23:05---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextFrame::removeEventListener(const uno::Reference< XEventListener > & aListener) throw( RuntimeException )
+{
+    SwXFrame::removeEventListener(aListener);
+}
+/* -----------------03.05.99 12:28-------------------
+ *
+ * --------------------------------------------------*/
+OUString SwXTextFrame::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXTextFrame");
+}
+/* -----------------03.05.99 12:28-------------------
+ *
+ * --------------------------------------------------*/
+sal_Bool SwXTextFrame::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return COMPARE_EQUAL == rServiceName.compareToAscii("com.sun.star.text.Text")||
+            COMPARE_EQUAL == rServiceName.compareToAscii("com.sun.star.text.TextFrame")||
+                COMPARE_EQUAL == rServiceName.compareToAscii("com.sun.star.text.TextContent") ||
+                    COMPARE_EQUAL == rServiceName.compareToAscii("com.sun.star.document.LinkTarget");
+}
+/* -----------------03.05.99 12:28-------------------
+ *
+ * --------------------------------------------------*/
+uno::Sequence< OUString > SwXTextFrame::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    uno::Sequence < OUString > aRet(4);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.Frame");
+    pArray[1] = C2U("com.sun.star.text.TextContent");
+    pArray[2] = C2U("com.sun.star.text.Text");
+    pArray[3] = C2U("com.sun.star.document.LinkTarget");
+
+    return aRet;
+}
+/* -----------------------------20.06.00 10:02--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void * SAL_CALL SwXTextFrame::operator new( size_t t) throw()
+{
+    return SwXTextFrameBaseClass::operator new( t);
+}
+/* -----------------------------20.06.00 10:02--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SAL_CALL SwXTextFrame::operator delete( void * p) throw()
+{
+    SwXTextFrameBaseClass::operator delete(p);
+}
+/******************************************************************
+ *  SwXTextGraphicObject
+ ******************************************************************/
+/*-- 14.01.99 11:27:51---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextGraphicObject::SwXTextGraphicObject() :
+    SwXFrame(FLYCNTTYPE_GRF, aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_GRAPHIC))
+{
+}
+/*-- 11.12.98 16:02:25---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextGraphicObject::SwXTextGraphicObject(SwFrmFmt& rFmt) :
+    SwXFrame(rFmt, FLYCNTTYPE_GRF, aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_GRAPHIC))
+{
+
+}
+/*-- 11.12.98 16:02:26---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextGraphicObject::~SwXTextGraphicObject()
+{
+
+}
+/* -----------------------------15.03.00 16:30--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SAL_CALL SwXTextGraphicObject::acquire(  )throw()
+{
+    SwXFrame::acquire();
+}
+/* -----------------------------15.03.00 16:30--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SAL_CALL SwXTextGraphicObject::release(  )throw()
+{
+    SwXFrame::release();
+}
+/* -----------------------------15.03.00 16:30--------------------------------
+
+ ---------------------------------------------------------------------------*/
+uno::Any SAL_CALL SwXTextGraphicObject::queryInterface( const uno::Type& aType )
+    throw(RuntimeException)
+{
+    uno::Any aRet = SwXFrame::queryInterface(aType);
+    if(aRet.getValueType() == ::getCppuVoidType())
+        aRet = SwXTextGraphicObjectBaseClass::queryInterface(aType);
+    return aRet;
+}
+/* -----------------------------15.03.00 16:30--------------------------------
+
+ ---------------------------------------------------------------------------*/
+uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL
+    SwXTextGraphicObject::getTypes(  ) throw(RuntimeException)
+{
+    uno::Sequence< uno::Type > aGraphicTypes = SwXTextGraphicObjectBaseClass::getTypes();
+    uno::Sequence< uno::Type > aFrameTypes = SwXFrame::getTypes();
+
+    long nIndex = aGraphicTypes.getLength();
+    aGraphicTypes.realloc(
+        aGraphicTypes.getLength() +
+        aFrameTypes.getLength());
+
+    uno::Type* pGraphicTypes = aGraphicTypes.getArray();
+    const uno::Type* pFrameTypes = aFrameTypes.getConstArray();
+    long nPos;
+    for(nPos = 0; nPos  SAL_CALL SwXTextGraphicObject::getImplementationId(  ) throw(RuntimeException)
+{
+    static uno::Sequence< sal_Int8 > aId( 16 );
+    static BOOL bInit = FALSE;
+    if(!bInit)
+        rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
+    return aId;
+}
+/*-- 11.12.98 16:02:27---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextGraphicObject::attach(const uno::Reference< XTextRange > & xTextRange) throw( IllegalArgumentException, RuntimeException )
+{
+}
+/*-- 11.12.98 16:02:27---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XTextRange >  SwXTextGraphicObject::getAnchor(void) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    return SwXFrame::getAnchor();
+}
+/*-- 11.12.98 16:02:28---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextGraphicObject::dispose(void) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwXFrame::dispose();
+}
+/*-- 11.12.98 16:02:29---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextGraphicObject::addEventListener(const uno::Reference< XEventListener > & aListener)
+                                                    throw( RuntimeException )
+{
+    SwXFrame::addEventListener(aListener);
+}
+/*-- 11.12.98 16:02:29---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextGraphicObject::removeEventListener(const uno::Reference< XEventListener > & aListener)
+                                                    throw( RuntimeException )
+{
+    SwXFrame::removeEventListener(aListener);
+}
+/* -----------------03.05.99 12:28-------------------
+ *
+ * --------------------------------------------------*/
+OUString SwXTextGraphicObject::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXTextGraphicObject");
+}
+/* -----------------03.05.99 12:28-------------------
+ *
+ * --------------------------------------------------*/
+sal_Bool SwXTextGraphicObject::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return COMPARE_EQUAL == rServiceName.compareToAscii("com.sun.star.text.TextGraphicObject") ||
+            COMPARE_EQUAL == rServiceName.compareToAscii("com.sun.star.text.TextContent") ||
+                COMPARE_EQUAL == rServiceName.compareToAscii("com.sun.star.document.LinkTarget");
+}
+/* -----------------03.05.99 12:28-------------------
+ *
+ * --------------------------------------------------*/
+uno::Sequence< OUString > SwXTextGraphicObject::getSupportedServiceNames(void)
+        throw( RuntimeException )
+{
+    uno::Sequence < OUString > aRet(3);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.TextContent");
+    pArray[1] = C2U("com.sun.star.document.LinkTarget");
+    pArray[2] = C2U("com.sun.star.text.GraphicObject");
+
+    return aRet;
+}
+/* -----------------------------20.06.00 10:02--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void * SAL_CALL SwXTextGraphicObject::operator new( size_t t) throw()
+{
+    return SwXTextGraphicObjectBaseClass::operator new(t);
+}
+/* -----------------------------20.06.00 10:02--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SAL_CALL SwXTextGraphicObject::operator delete( void * p) throw()
+{
+    SwXTextGraphicObjectBaseClass::operator delete(p);
+}
+
+/******************************************************************
+ *
+ ******************************************************************/
+/*-- 11.12.98 16:16:53---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextEmbeddedObject::SwXTextEmbeddedObject() :
+    SwXFrame(FLYCNTTYPE_OLE, aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_FRAME))
+{
+
+}
+/*-- 11.12.98 16:16:53---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextEmbeddedObject::SwXTextEmbeddedObject(SwFrmFmt& rFmt) :
+    SwXFrame(rFmt, FLYCNTTYPE_OLE, aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_FRAME))
+{
+
+}
+/*-- 11.12.98 16:16:54---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextEmbeddedObject::~SwXTextEmbeddedObject()
+{
+
+}
+/*-- 11.12.98 16:16:54---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+/* -----------------------------15.03.00 16:32--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SAL_CALL SwXTextEmbeddedObject::acquire()throw()
+{
+    SwXFrame::acquire();
+}
+/* -----------------------------15.03.00 16:32--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SAL_CALL SwXTextEmbeddedObject::release()throw()
+{
+    SwXFrame::release();
+}
+/* -----------------------------15.03.00 16:32--------------------------------
+
+ ---------------------------------------------------------------------------*/
+uno::Any SAL_CALL SwXTextEmbeddedObject::queryInterface( const uno::Type& aType )
+    throw( RuntimeException)
+{
+    uno::Any aRet = SwXFrame::queryInterface(aType);;
+    if(aRet.getValueType() == ::getCppuVoidType())
+        aRet = SwXTextEmbeddedObjectBaseClass::queryInterface(aType);
+    return aRet;
+}
+/* -----------------------------15.03.00 16:32--------------------------------
+
+ ---------------------------------------------------------------------------*/
+uno::Sequence< uno::Type > SAL_CALL SwXTextEmbeddedObject::getTypes(  ) throw(RuntimeException)
+{
+    uno::Sequence< uno::Type > aTextEmbeddedTypes = SwXTextEmbeddedObjectBaseClass::getTypes();
+    uno::Sequence< uno::Type > aFrameTypes = SwXFrame::getTypes();
+
+    long nIndex = aTextEmbeddedTypes.getLength();
+    aTextEmbeddedTypes.realloc(
+        aTextEmbeddedTypes.getLength() +
+        aFrameTypes.getLength());
+
+    uno::Type* pTextEmbeddedTypes = aTextEmbeddedTypes.getArray();
+
+    const uno::Type* pFrameTypes = aFrameTypes.getConstArray();
+    long nPos;
+    for(nPos = 0; nPos  SAL_CALL SwXTextEmbeddedObject::getImplementationId(  ) throw(RuntimeException)
+{
+    static uno::Sequence< sal_Int8 > aId( 16 );
+    static BOOL bInit = FALSE;
+    if(!bInit)
+        rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
+    return aId;
+}
+/*-- 11.12.98 16:16:54---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextEmbeddedObject::attach(const uno::Reference< XTextRange > & xTextRange) throw( IllegalArgumentException, RuntimeException )
+{
+}
+/*-- 11.12.98 16:16:54---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XTextRange >  SwXTextEmbeddedObject::getAnchor(void) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    return SwXFrame::getAnchor();
+}
+/*-- 11.12.98 16:16:54---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextEmbeddedObject::dispose(void) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwXFrame::dispose();
+}
+/*-- 11.12.98 16:16:55---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextEmbeddedObject::addEventListener(const uno::Reference< XEventListener > & aListener) throw( RuntimeException )
+{
+    SwXFrame::addEventListener(aListener);
+}
+/*-- 11.12.98 16:16:55---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextEmbeddedObject::removeEventListener(const uno::Reference< XEventListener > & aListener) throw( RuntimeException )
+{
+    SwXFrame::removeEventListener(aListener);
+}
+/*-- 11.12.98 16:16:55---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+
+static uno::Reference< util::XModifyListener >  xSwXOLEListener;
+
+uno::Reference< XComponent >  SwXTextEmbeddedObject::getEmbeddedObject(void) throw( RuntimeException )
+{
+    uno::Reference< XComponent >  xRet;
+    SwFrmFmt*   pFmt = GetFrmFmt();
+    if(pFmt)
+    {
+        SwDoc* pDoc = pFmt->GetDoc();
+        const SwFmtCntnt* pCnt = &pFmt->GetCntnt();
+        DBG_ASSERT( pCnt->GetCntntIdx() &&
+                       pDoc->GetNodes()[ pCnt->GetCntntIdx()->
+                                        GetIndex() + 1 ]->GetOLENode(), "kein OLE-Node?")
+
+        SwOLENode* pOleNode =  pDoc->GetNodes()[ pCnt->GetCntntIdx()
+                                        ->GetIndex() + 1 ]->GetOLENode();
+        SvInPlaceObjectRef xIP( pOleNode->GetOLEObj().GetOleRef() );
+        if (xIP.Is())
+        {
+            SfxInPlaceObjectRef xSfxObj( xIP );
+            if(xSfxObj.Is())
+            {
+                SfxObjectShell* pObjSh = xSfxObj->GetObjectShell();
+                if( pObjSh )
+                {
+                    uno::Reference< frame::XModel > xModel = pObjSh->GetBaseModel();
+                    xRet = uno::Reference< XComponent >(xModel, uno::UNO_QUERY);
+
+                    uno::Reference< util::XModifyBroadcaster >  xBrdcst(xModel, uno::UNO_QUERY);
+                    if( xBrdcst.is() )
+                    {
+                        SwXOLEListener* pSwOLEListener = 0;
+                        if( !xSwXOLEListener.is() )
+                            xSwXOLEListener = pSwOLEListener = new SwXOLEListener;
+                        if( pSwOLEListener->AddOLEFmt( *pFmt ) )
+                            xBrdcst->addModifyListener( xSwXOLEListener );
+                    }
+                }
+            }
+        }
+    }
+    return xRet;
+}
+/*-- 11.12.98 16:16:56---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< uno::XInterface >  SwXTextEmbeddedObject::getObject(void) throw( RuntimeException )
+{
+    DBG_WARNING("not implemented")
+    return uno::Reference< uno::XInterface > ();
+}
+/*-- 11.12.98 16:16:56---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextEmbeddedObject::setObject(const uno::Reference< uno::XInterface > & xObject) throw( RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/* -----------------03.05.99 12:28-------------------
+ *
+ * --------------------------------------------------*/
+OUString SwXTextEmbeddedObject::getImplementationName(void) throw( RuntimeException )
+
+{
+    return C2U("SwXTextEmbeddedObject");
+}
+/* -----------------03.05.99 12:28-------------------
+ *
+ * --------------------------------------------------*/
+sal_Bool SwXTextEmbeddedObject::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return  COMPARE_EQUAL == rServiceName.compareToAscii("com.sun.star.text.TextEmbeddedObject")||
+            COMPARE_EQUAL == rServiceName.compareToAscii("com.sun.star.text.TextContent")||
+            COMPARE_EQUAL == rServiceName.compareToAscii("com.sun.star.document.LinkTarget");
+}
+/* -----------------03.05.99 12:28-------------------
+ *
+ * --------------------------------------------------*/
+uno::Sequence< OUString > SwXTextEmbeddedObject::getSupportedServiceNames(void)
+        throw( RuntimeException )
+{
+    uno::Sequence < OUString > aRet(3);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.TextContent");
+    pArray[1] = C2U("com.sun.star.document.LinkTarget");
+    pArray[2] = C2U("com.sun.star.text.TextEmbeddedObject");
+
+    return aRet;
+}
+/* -----------------------------20.06.00 10:02--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void * SAL_CALL SwXTextEmbeddedObject::operator new( size_t t) throw()
+{
+    return SwXTextEmbeddedObjectBaseClass::operator new(t);
+}
+/* -----------------------------20.06.00 10:02--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SAL_CALL SwXTextEmbeddedObject::operator delete( void * p) throw()
+{
+    SwXTextEmbeddedObjectBaseClass::operator delete(p);
+}
+
+
+/******************************************************************
+ *
+ ******************************************************************/
+
+void SwXOLEListener::modified( const EventObject& rEvent )
+                                        throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+
+    SwOLENode* pNd;
+    sal_uInt16 nFndPos = FindEntry( rEvent, &pNd );
+    if( USHRT_MAX != nFndPos && ( !pNd->GetOLEObj().IsOleRef() ||
+            !pNd->GetOLEObj().GetOleRef()->GetProtocol().IsInPlaceActive() ))
+    {
+        // if the OLE-Node is UI-Active do nothing
+        pNd->SetOLESizeInvalid( sal_True );
+        pNd->GetDoc()->SetOLEObjModified();
+    }
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SwXOLEListener::disposing( const EventObject& rEvent )
+                        throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+
+    uno::Reference< util::XModifyListener >  xListener( this );
+
+    SwOLENode* pNd;
+    sal_uInt16 nFndPos = FindEntry( rEvent, &pNd );
+    if( USHRT_MAX != nFndPos )
+    {
+        SwDepend* pDepend = (SwDepend*)aFmts[ nFndPos ];
+        aFmts.Remove( nFndPos, 1 );
+
+        uno::Reference< frame::XModel >  xModel( rEvent.Source, uno::UNO_QUERY );
+        uno::Reference< util::XModifyBroadcaster >  xBrdcst(xModel, uno::UNO_QUERY);
+
+        if( xBrdcst.is() )
+            xBrdcst->removeModifyListener( xListener );
+
+        delete pDepend;
+        if( !aFmts.Count() )
+        {
+            // we are the last?
+            // then can we delete us
+            xSwXOLEListener = 0;
+        }
+    }
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Bool SwXOLEListener::AddOLEFmt( SwFrmFmt& rFmt )
+{
+    for( sal_uInt16 n = 0, nCnt = aFmts.Count(); n < nCnt; ++n )
+        if( &rFmt == ((SwDepend*)aFmts[ n ])->GetRegisteredIn() )
+            return sal_False;       // is in the array
+
+    SwDepend* pNew = new SwDepend( this, &rFmt );
+    aFmts.Insert( pNew, aFmts.Count() );
+    return sal_True;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SwXOLEListener::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew )
+{
+    const SwClient* pClient = 0;
+
+    switch( pOld ? pOld->Which() : 0 )
+    {
+    case RES_REMOVE_UNO_OBJECT:
+    case RES_OBJECTDYING:
+        pClient = (SwClient*)((SwPtrMsgPoolItem *)pOld)->pObject;
+        break;
+
+    case RES_FMT_CHG:
+        // wurden wir an das neue umgehaengt und wird das alte geloscht?
+        if( ((SwFmtChg*)pOld)->pChangedFmt->IsFmtInDTOR() )
+        {
+            pClient = ((SwFmtChg*)pNew)->pChangedFmt;
+        }
+        break;
+    }
+
+    if( pClient )
+    {
+        uno::Reference< util::XModifyListener >  xListener( this );
+
+        SwDepend* pDepend;
+        for( sal_uInt16 n = 0, nCnt = aFmts.Count(); n < nCnt; ++n )
+        {
+            if( pClient == (pDepend = (SwDepend*)aFmts[ n ])->GetRegisteredIn() )
+            {
+                aFmts.Remove( n, 1 );
+
+                 uno::Reference xModel = GetModel( *(SwFmt*)pClient );
+                if( xModel.is() )
+                {
+                    uno::Reference< util::XModifyBroadcaster >  xBrdcst(xModel, uno::UNO_QUERY);
+                    if( xBrdcst.is() )
+                        xBrdcst->removeModifyListener( xListener );
+                }
+
+                delete pDepend;
+                if( !aFmts.Count() )
+                {
+                    // we are the last?
+                    // then can we delete us
+                    xSwXOLEListener = 0;
+                }
+                break;
+            }
+        }
+    }
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+uno::Reference< frame::XModel > SwXOLEListener::GetModel( const SwFmt& rFmt, SwOLENode** ppNd ) const
+{
+    SfxObjectShell* pObjSh = GetObjShell( rFmt, ppNd );
+    return pObjSh ? pObjSh->GetBaseModel() : (uno::Reference< frame::XModel >)0;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+SfxObjectShell* SwXOLEListener::GetObjShell( const SwFmt& rFmt,
+                                            SwOLENode** ppNd ) const
+{
+    SfxObjectShell* pShell = 0;
+    const SwFmtCntnt& rCnt = rFmt.GetCntnt();
+    if( rCnt.GetCntntIdx() )
+    {
+        SwNodeIndex aIdx( *rCnt.GetCntntIdx(), 1 );
+        SwOLENode* pOleNode = aIdx.GetNode().GetOLENode();
+        if( pOleNode && pOleNode->GetOLEObj().IsOleRef() )
+        {
+            SfxInPlaceObjectRef xIP( pOleNode->GetOLEObj().GetOleRef() );
+            if( xIP.Is() )
+                pShell = xIP->GetObjectShell();
+        }
+        if( ppNd )
+            *ppNd = pOleNode;
+    }
+    return pShell;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_uInt16 SwXOLEListener::FindEntry( const EventObject& rEvent,SwOLENode** ppNd)
+{
+    sal_uInt16 nRet = USHRT_MAX;
+    uno::Reference< frame::XModel >  xSrch( rEvent.Source, uno::UNO_QUERY );
+
+    for( sal_uInt16 n = 0, nCnt = aFmts.Count(); n < nCnt; ++n )
+    {
+        SwDepend* pDepend = (SwDepend*)aFmts[ n ];
+        SwFrmFmt* pFmt = (SwFrmFmt*)pDepend->GetRegisteredIn();
+        if( !pFmt )
+        {
+            ASSERT( pFmt, "wo ist das Format geblieben?" );
+            aFmts.Remove( n, 1 );
+            delete pDepend;
+            --n;
+            --nCnt;
+        }
+        else
+        {
+            uno::Reference< frame::XModel >  xFmt( GetModel( *pFmt, ppNd ), uno::UNO_QUERY);
+            if( xFmt == xSrch )
+            {
+                nRet = n;
+                break;
+            }
+        }
+    }
+    return nRet;
+}
+/******************************************************************
+ *
+ ******************************************************************/
+
+
+/*------------------------------------------------------------------------
+
+    $Log: not supported by cvs2svn $
+    Revision 1.89  2000/09/18 16:04:31  willem.vandorp
+    OpenOffice header added.
+
+    Revision 1.88  2000/09/18 11:44:20  mib
+    bug fix for getPropertySetInfo
+
+    Revision 1.87  2000/09/15 08:42:29  os
+    FrameStyle->FrameStyleName
+
+    Revision 1.86  2000/09/15 07:21:16  os
+    service of graphic: ...text.GraphicObject
+
+    Revision 1.85  2000/09/12 13:24:45  os
+    #78602# XPropertyState implemented
+
+    Revision 1.84  2000/09/11 14:05:07  os
+     data type
+
+    Revision 1.83  2000/09/05 15:14:11  os
+    string length available again
+
+    Revision 1.82  2000/09/04 07:14:44  os
+    #78413# graphic descriptor properties corrected
+
+    Revision 1.81  2000/08/18 11:15:48  os
+    #77775# set default size of frames
+
+    Revision 1.80  2000/07/21 14:14:03  os
+    #76829# getTypes corrected
+
+    Revision 1.79  2000/07/11 13:43:42  os
+    #76708# insert/remove paragraphs before/behind tables
+
+    Revision 1.78  2000/07/10 12:32:17  os
+    chg: acquire/release don't throw exceptions
+
+    Revision 1.77  2000/06/27 12:10:33  os
+    #76423# programmatic style names
+
+    Revision 1.76  2000/06/20 12:28:31  os
+    new/delete completed
+
+    Revision 1.75  2000/06/20 08:08:31  os
+    operator new/delete
+
+    Revision 1.74  2000/05/25 09:54:36  hr
+    ?: operator
+
+    Revision 1.73  2000/05/16 17:21:28  jp
+    Changes for Unicode
+
+    Revision 1.72  2000/04/27 10:46:56  os
+    UNICODE
+
+    Revision 1.71  2000/04/26 11:35:19  os
+    GetName() returns String&
+
+    Revision 1.70  2000/04/11 08:31:03  os
+    UNICODE
+
+    Revision 1.69  2000/03/27 10:21:10  os
+    UNO III
+
+    Revision 1.68  2000/03/21 15:42:24  os
+    UNOIII
+
+    Revision 1.67  2000/02/11 14:35:38  hr
+    #70473# changes for unicode ( patched by automated patchtool )
+
+    Revision 1.66  2000/01/28 15:18:18  os
+    #72213# Chg: XSimpleText;
+
+    Revision 1.65  1999/11/25 15:43:26  os
+    headers corrected
+
+    Revision 1.64  1999/11/19 16:40:18  os
+    modules renamed
+
+    Revision 1.63  1999/11/11 16:42:57  jp
+    Bug #67026#: register as listener in OLE Objects and repaint/-size them by modification
+
+    Revision 1.62  1999/11/02 11:07:56  os
+    hyperlink interface completed
+
+    Revision 1.61  1999/10/26 14:35:33  os
+    LinkTargetSupplier
+
+    Revision 1.60  1999/07/22 07:34:26  OS
+    #65519# AnchorTypes in TextFrame and GraphicObject
+
+
+
+------------------------------------------------------------------------*/
+
diff --git a/sw/source/core/unocore/unoftn.cxx b/sw/source/core/unocore/unoftn.cxx
new file mode 100644
index 000000000000..1d848dec63ae
--- /dev/null
+++ b/sw/source/core/unocore/unoftn.cxx
@@ -0,0 +1,644 @@
+/*************************************************************************
+ *
+ *  $RCSfile: unoftn.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:28 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _VOS_MUTEX_HXX_ //autogen
+#include 
+#endif
+#ifndef _SV_SVAPP_HXX //autogen
+#include 
+#endif
+#ifndef _RTL_UUID_H_
+#include 
+#endif
+#ifndef _UNOOBJ_HXX
+#include 
+#endif
+#ifndef _UNOMAP_HXX
+#include 
+#endif
+#ifndef _UNOPRNMS_HXX
+#include 
+#endif
+#ifndef _DOC_HXX //autogen
+#include 
+#endif
+#ifndef _FTNIDX_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFTN_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFTN_HXX //autogen
+#include 
+#endif
+#ifndef _NDTXT_HXX //autogen
+#include 
+#endif
+#ifndef _UNOCRSR_HXX
+#include 
+#endif
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::beans;
+using namespace ::rtl;
+
+/******************************************************************
+ *
+ ******************************************************************/
+/* -----------------------------13.03.00 12:15--------------------------------
+
+ ---------------------------------------------------------------------------*/
+const uno::Sequence< sal_Int8 > & SwXFootnote::getUnoTunnelId()
+{
+    static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId();
+    return aSeq;
+}
+/* -----------------------------10.03.00 18:04--------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Int64 SAL_CALL SwXFootnote::getSomething( const uno::Sequence< sal_Int8 >& rId )
+    throw(uno::RuntimeException)
+{
+    if( rId.getLength() == 16
+        && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+                                        rId.getConstArray(), 16 ) )
+    {
+            return (sal_Int64)this;
+    }
+    return 0;
+}
+/* -----------------------------06.04.00 16:36--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXFootnote::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXFootnote");
+}
+/* -----------------------------06.04.00 16:36--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXFootnote::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return !rServiceName.compareToAscii("com.sun.star.text.Footnote") ||
+        !rServiceName.compareToAscii("com.sun.star.text.TextContent") ||
+            (m_bIsEndnote && !rServiceName.compareToAscii("com.sun.star.text.Endnote"));
+;
+}
+/* -----------------------------06.04.00 16:36--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXFootnote::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(m_bIsEndnote ? 3 : 2);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.Footnote");
+    pArray[1] = C2U("com.sun.star.text.TextContent");
+    if(m_bIsEndnote)
+        pArray[2] = C2U("com.sun.star.text.Endnote");
+    return aRet;
+}
+/*-- 10.12.98 15:31:44---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+TYPEINIT1(SwXFootnote, SwClient);
+
+SwXFootnote::SwXFootnote(sal_Bool bEndnote) :
+    aLstnrCntnr( (text::XTextContent*)this),
+    SwXText(0, CURSOR_FOOTNOTE),
+    pFmtFtn(0),
+    m_bIsDescriptor(sal_True),
+    m_bIsEndnote(bEndnote)
+{
+
+}
+/*-- 10.12.98 15:31:45---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXFootnote::SwXFootnote(SwDoc* pDoc, const SwFmtFtn& rFmt) :
+    SwXText(pDoc, CURSOR_FOOTNOTE),
+    aLstnrCntnr( (text::XTextContent*)this),
+    pFmtFtn(&rFmt),
+    m_bIsDescriptor(sal_False),
+    m_bIsEndnote(rFmt.IsEndNote())
+{
+    GetDoc()->GetUnoCallBack()->Add(this);
+}
+/*-- 10.12.98 15:31:45---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXFootnote::~SwXFootnote()
+{
+
+}
+/* -----------------------------21.03.00 15:39--------------------------------
+
+ ---------------------------------------------------------------------------*/
+uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL SwXFootnote::getTypes(  ) throw(uno::RuntimeException)
+{
+    uno::Sequence< uno::Type > aFtnTypes = SwXFootnoteBaseClass::getTypes();
+    uno::Sequence< uno::Type > aTextTypes = SwXText::getTypes();
+
+    long nIndex = aFtnTypes.getLength();
+    aFtnTypes.realloc(  aFtnTypes.getLength() + aTextTypes.getLength());
+
+    uno::Type* pFtnTypes = aFtnTypes.getArray();
+    const uno::Type* pTextTypes = aTextTypes.getConstArray();
+    for(long nPos = 0; nPos < aTextTypes.getLength(); nPos++)
+        pFtnTypes[nIndex++] = pTextTypes[nPos];
+
+    return aFtnTypes;
+}
+
+/* -----------------------------21.03.00 15:39--------------------------------
+
+ ---------------------------------------------------------------------------*/
+uno::Sequence< sal_Int8 > SAL_CALL SwXFootnote::getImplementationId(  ) throw(uno::RuntimeException)
+{
+    static uno::Sequence< sal_Int8 > aId( 16 );
+    static BOOL bInit = FALSE;
+    if(!bInit)
+        rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
+    return aId;
+}
+/* -----------------------------21.03.00 15:46--------------------------------
+
+ ---------------------------------------------------------------------------*/
+uno::Any SAL_CALL SwXFootnote::queryInterface( const uno::Type& aType ) throw(uno::RuntimeException)
+{
+    uno::Any aRet = SwXFootnoteBaseClass::queryInterface(aType);
+    if(aRet.getValueType() == ::getCppuVoidType() )
+        aRet = SwXText::queryInterface(aType);
+    return aRet;
+}
+
+/*-- 10.12.98 15:31:47---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+OUString SwXFootnote::getLabel(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    String sRet;
+    const SwFmtFtn*  pFmt = SwXFootnote::FindFmt();
+    if(pFmt)
+        sRet = pFmt->GetNumStr();
+    else if(m_bIsDescriptor)
+        return m_sLabel;
+    else
+        throw uno::RuntimeException();
+    return sRet;
+}
+/*-- 10.12.98 15:31:48---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFootnote::setLabel(const OUString& aLabel) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    const SwFmtFtn*  pFmt = FindFmt();
+    if(pFmt)
+    {
+        const SwTxtFtn* pTxtFtn = pFmt->GetTxtFtn();
+        DBG_ASSERT(pTxtFtn, "kein TextNode?")
+        SwTxtNode& rTxtNode = (SwTxtNode&)pTxtFtn->GetTxtNode();
+
+        SwPaM aPam(rTxtNode, *pTxtFtn->GetStart());
+        GetDoc()->SetCurFtn(aPam, aLabel, pFmt->GetNumber(), pFmt->IsEndNote());
+    }
+    else if(m_bIsDescriptor)
+        m_sLabel = String(aLabel);
+    else
+        throw uno::RuntimeException();
+
+}
+/* -----------------18.02.99 13:32-------------------
+ *
+ * --------------------------------------------------*/
+void SwXFootnote::attachToRange(const uno::Reference< text::XTextRange > & xTextRange)
+            throw( lang::IllegalArgumentException, uno::RuntimeException )
+{
+    if(!m_bIsDescriptor)
+        throw uno::RuntimeException();
+    uno::Reference xRangeTunnel( xTextRange, uno::UNO_QUERY);
+    SwXTextRange* pRange = 0;
+    SwXTextCursor* pCursor = 0;
+    if(xRangeTunnel.is())
+    {
+        pRange = (SwXTextRange*)xRangeTunnel->getSomething(
+                                SwXTextRange::getUnoTunnelId());
+        pCursor = (SwXTextCursor*)xRangeTunnel->getSomething(
+                                SwXTextCursor::getUnoTunnelId());
+    }
+    SwDoc* pDoc = pRange ? (SwDoc*)pRange->GetDoc() : pCursor ? (SwDoc*)pCursor->GetDoc() : 0;
+    if(pDoc)
+    {
+        SwUnoInternalPaM aPam(*pDoc);
+        //das muss jetzt sal_True liefern
+        SwXTextRange::XTextRangeToSwPaM(aPam, xTextRange);
+
+        UnoActionContext aCont(pDoc);
+        SwTxtAttr* pTxtAttr = 0;
+        pDoc->DeleteAndJoin(aPam);
+        aPam.DeleteMark();
+        SwFmtFtn aFootNote(m_bIsEndnote);
+        if(m_sLabel.Len())
+            aFootNote.SetNumStr(m_sLabel);
+        SfxItemSet  aSet(pDoc->GetAttrPool(), RES_TXTATR_FTN, RES_TXTATR_FTN, 0L);
+        aSet.Put(aFootNote);
+        SwXTextCursor::SetCrsrAttr(aPam, aSet);
+
+        SwUnoCrsr* pCrsr = pDoc->CreateUnoCrsr( *aPam.Start() );
+        pCrsr->SetMark();
+        pCrsr->Left(1);
+        pTxtAttr = pCrsr->GetNode()->GetTxtNode()->GetTxtAttr(pCrsr->GetPoint()->nContent, RES_TXTATR_FTN);
+        delete pCrsr;
+        if(pTxtAttr)
+        {
+            const SwFmtFtn& rFtn = pTxtAttr->GetFtn();
+            pFmtFtn = &rFtn;
+            pDoc->GetUnoCallBack()->Add(this);
+        }
+        m_bIsDescriptor = sal_False;
+        SetDoc(pDoc);
+    }
+    else
+        throw lang::IllegalArgumentException();
+}
+/*-- 10.12.98 15:31:48---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFootnote::attach(const uno::Reference< text::XTextRange > & xTextRange)
+            throw( lang::IllegalArgumentException, uno::RuntimeException )
+{
+}
+/*-- 10.12.98 15:31:48---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< text::XTextRange >  SwXFootnote::getAnchor(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< text::XTextRange >  aRef;
+    const SwFmtFtn*  pFmt = FindFmt();
+    if(pFmt)
+    {
+        const SwTxtFtn* pTxtFtn = pFmt->GetTxtFtn();
+        SwPosition aPos( *pTxtFtn->GetStartNode() );
+        aRef = ::CreateTextRangeFromPosition((SwDoc*)GetDoc(), aPos, 0);
+    }
+    else
+        throw uno::RuntimeException();
+    return aRef;
+}
+/*-- 10.12.98 15:31:49---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFootnote::dispose(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    const SwFmtFtn*  pFmt = FindFmt();
+    if(pFmt)
+    {
+        const SwTxtFtn* pTxtFtn = pFmt->GetTxtFtn();
+        DBG_ASSERT(pTxtFtn, "kein TextNode?")
+        SwTxtNode& rTxtNode = (SwTxtNode&)pTxtFtn->GetTxtNode();
+
+        SwPaM aPam(rTxtNode, *pTxtFtn->GetStart());
+        SwCursor aCrsr(*aPam.Start());
+        aCrsr.SetMark();
+        aCrsr.LeftRight(sal_False, 1);
+        GetDoc()->DeleteAndJoin(aCrsr);
+    }
+    else
+        throw uno::RuntimeException();
+
+}
+/*-- 10.12.98 15:31:49---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFootnote::addEventListener(const uno::Reference< lang::XEventListener > & aListener) throw( uno::RuntimeException )
+{
+    if(!GetRegisteredIn())
+        throw uno::RuntimeException();
+    aLstnrCntnr.AddListener(aListener);
+}
+/*-- 10.12.98 15:31:50---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFootnote::removeEventListener(const uno::Reference< lang::XEventListener > & aListener) throw( uno::RuntimeException )
+{
+    if(!GetRegisteredIn() || !aLstnrCntnr.RemoveListener(aListener))
+        throw uno::RuntimeException();
+}
+/* -----------------06.05.99 15:31-------------------
+ *
+ * --------------------------------------------------*/
+uno::Reference< text::XTextCursor >   SwXFootnote::createCursor()
+{
+    return createTextCursor();
+}
+/*-- 10.12.98 15:31:50---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< text::XTextCursor >  SwXFootnote::createTextCursor(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< text::XTextCursor >  aRef;
+    const SwFmtFtn*  pFmt = FindFmt();
+    if(pFmt)
+    {
+        const SwTxtFtn* pTxtFtn = pFmt->GetTxtFtn();
+        SwPosition aPos( *pTxtFtn->GetStartNode() );
+        SwXTextCursor* pXCrsr = new SwXTextCursor(this, aPos, CURSOR_FOOTNOTE, GetDoc());
+        aRef =  (text::XWordCursor*)pXCrsr;
+        SwUnoCrsr*  pUnoCrsr = pXCrsr->GetCrsr();
+        pUnoCrsr->Move(fnMoveForward, fnGoNode);
+    }
+    else
+        throw uno::RuntimeException();
+    return aRef;
+}
+/*-- 10.12.98 15:31:51---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< text::XTextCursor >  SwXFootnote::createTextCursorByRange(
+    const uno::Reference< text::XTextRange > & aTextPosition)
+            throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    const SwFmtFtn*  pFmt = FindFmt();
+    uno::Reference< text::XTextCursor >  aRef;
+    SwUnoInternalPaM aPam(*GetDoc());
+    if(pFmt && SwXTextRange::XTextRangeToSwPaM(aPam, aTextPosition))
+    {
+        const SwTxtFtn* pTxtFtn = pFmt->GetTxtFtn();
+#ifdef DEBUG
+        const SwStartNode* p1 = aPam.GetNode()->FindFootnoteStartNode();
+        const SwNode& rStNode = pTxtFtn->GetStartNode()->GetNode();
+#endif
+        if(aPam.GetNode()->FindStartNode() == &pTxtFtn->GetStartNode()->GetNode())
+            aRef =  (text::XWordCursor*)new SwXTextCursor(this , *aPam.GetPoint(), CURSOR_FOOTNOTE, GetDoc(), aPam.GetMark());
+    }
+    else
+        throw uno::RuntimeException();
+    return aRef;
+}
+/*-- 13.06.00 14:28:23---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Reference< XEnumeration >  SwXFootnote::createEnumeration() throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< container::XEnumeration >  aRef;
+     uno::XInterface* pRet = 0;
+    const SwFmtFtn*  pFmt = FindFmt();
+    if(pFmt)
+    {
+        const SwTxtFtn* pTxtFtn = pFmt->GetTxtFtn();
+        SwPosition aPos( *pTxtFtn->GetStartNode() );
+        SwXTextCursor* pXCrsr = new SwXTextCursor(this, aPos, CURSOR_FOOTNOTE, GetDoc());
+        SwUnoCrsr*  pUnoCrsr = pXCrsr->GetCrsr();
+        pUnoCrsr->Move(fnMoveForward, fnGoNode);
+        aRef = new SwXParagraphEnumeration(this, pUnoCrsr, CURSOR_FOOTNOTE);
+    }
+    return aRef;
+}
+/*-- 13.06.00 14:28:24---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Type SwXFootnote::getElementType(  ) throw(RuntimeException)
+{
+    return ::getCppuType((Reference*)0);
+}
+/*-- 13.06.00 14:28:24---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXFootnote::hasElements(  ) throw(RuntimeException)
+{
+    return sal_True;
+}
+/*-----------------20.03.98 16:23-------------------
+
+--------------------------------------------------*/
+const SwFmtFtn*     SwXFootnote::FindFmt() const
+{
+    if(!GetDoc())
+        return 0;
+    const SwFtnIdxs& rIdxs = GetDoc()->GetFtnIdxs();
+    sal_uInt16 n, nFtnCnt = rIdxs.Count();
+    const SwTxtFtn* pTxtFtn;
+    for( n = 0; n < nFtnCnt; ++n )
+    {
+        pTxtFtn = rIdxs[ n ];
+        const SwFmtFtn& rFtn = pTxtFtn->GetFtn();
+        if( &rFtn == pFmtFtn )
+                return pFmtFtn;
+    }
+    return 0;
+}
+/* -----------------------------07.01.00 12:39--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void    SwXFootnote::Invalidate()
+{
+    if(GetRegisteredIn())
+    {
+        ((SwModify*)GetRegisteredIn())->Remove(this);
+        pFmtFtn = 0;
+        aLstnrCntnr.Disposing();
+        SetDoc(0);
+    }
+}
+/* -----------------18.01.99 09:12-------------------
+ *
+ * --------------------------------------------------*/
+void    SwXFootnote::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew)
+{
+    ClientModify(this, pOld, pNew);
+    if(!GetRegisteredIn())
+    {
+        aLstnrCntnr.Disposing();
+        SetDoc(0);
+    }
+}
+/*-- 11.09.00 13:12:03---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Reference< XPropertySetInfo > SwXFootnote::getPropertySetInfo(  )
+    throw(RuntimeException)
+{
+    static uno::Reference< beans::XPropertySetInfo >  xRef;
+    if(!xRef.is())
+    {
+        const SfxItemPropertyMap* pMap = aSwMapProvider.GetPropertyMap(PROPERTY_MAP_FOOTNOTE);
+        uno::Reference< beans::XPropertySetInfo >  xInfo = new SfxItemPropertySetInfo(pMap);
+        // extend PropertySetInfo!
+        const uno::Sequence aPropSeq = xInfo->getProperties();
+        xRef = new SfxExtItemPropertySetInfo(
+            aSwMapProvider.GetPropertyMap(PROPERTY_MAP_PARAGRAPH_EXTENSIONS),
+            aPropSeq );
+    }
+    return xRef;
+}
+/*-- 11.09.00 13:12:04---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFootnote::setPropertyValue( const ::rtl::OUString&,
+    const Any& )
+        throw(UnknownPropertyException, PropertyVetoException,
+            IllegalArgumentException, WrappedTargetException, RuntimeException)
+{
+    //no values to be set
+    throw IllegalArgumentException();
+}
+/*-- 11.09.00 13:12:04---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Any SwXFootnote::getPropertyValue( const OUString& rPropertyName )
+    throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    Any aRet;
+    if(!SwXParagraph::getDefaultTextContentValue(aRet, rPropertyName))
+    {
+        if(0 != rPropertyName.compareToAscii(UNO_NAME_REFERENCE_ID))
+            throw UnknownPropertyException();
+
+        const SwFmtFtn*  pFmt = FindFmt();
+        if(pFmt)
+        {
+            const SwTxtFtn* pTxtFtn = pFmt->GetTxtFtn();
+            DBG_ASSERT(pTxtFtn, "no TextNode?")
+            aRet <<= (sal_Int16)pTxtFtn->GetSeqRefNo();
+        }
+    }
+    return aRet;
+}
+/*-- 11.09.00 13:12:04---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFootnote::addPropertyChangeListener( const OUString& aPropertyName,
+    const Reference< XPropertyChangeListener >& xListener )
+        throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+/*-- 11.09.00 13:12:04---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFootnote::removePropertyChangeListener( const OUString& aPropertyName,
+    const Reference< XPropertyChangeListener >& aListener )
+        throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+/*-- 11.09.00 13:12:04---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFootnote::addVetoableChangeListener( const OUString& PropertyName,
+    const Reference< XVetoableChangeListener >& aListener )
+        throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+/*-- 11.09.00 13:12:05---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFootnote::removeVetoableChangeListener( const OUString& PropertyName,
+    const Reference< XVetoableChangeListener >& aListener )
+        throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+/*------------------------------------------------------------------------
+
+    $Log: not supported by cvs2svn $
+    Revision 1.8  2000/09/18 16:04:32  willem.vandorp
+    OpenOffice header added.
+
+    Revision 1.7  2000/09/12 11:42:58  os
+    #78682# support of service TextContent
+
+    Revision 1.6  2000/09/11 12:05:29  os
+    #78606# references to footnotes
+
+    Revision 1.5  2000/09/11 10:16:22  os
+    #78603# support of service com.sun.star.Endnote
+
+    Revision 1.4  2000/09/11 09:57:06  os
+    TYPEINFO
+
+    Revision 1.3  2000/08/24 11:17:29  os
+    #78051# getTypes corrected
+
+    Revision 1.2  2000/06/13 12:38:17  os
+    #76188##76191# XElementAccess and XEnumerationAccess at SwXFootnote now available
+
+    Revision 1.1  2000/05/04 15:14:01  os
+    reduce size of unoobj.cxx
+
+
+------------------------------------------------------------------------*/
+
+
diff --git a/sw/source/core/unocore/unoidx.cxx b/sw/source/core/unocore/unoidx.cxx
new file mode 100644
index 000000000000..83349f267a3f
--- /dev/null
+++ b/sw/source/core/unocore/unoidx.cxx
@@ -0,0 +1,2742 @@
+/*************************************************************************
+ *
+ *  $RCSfile: unoidx.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:28 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include 
+#include 
+#ifndef _TOOLS_DEBUG_HXX //autogen
+#include 
+#endif
+#ifndef _DOC_HXX //autogen
+#include 
+#endif
+#ifndef _DOCARY_HXX //autogen
+#include 
+#endif
+#ifndef _POOLFMT_HXX
+#include 
+#endif
+#ifndef _POOLFMT_HRC
+#include 
+#endif
+#ifndef _PAGEDESC_HXX //autogen
+#include 
+#endif
+#ifndef _UNOMAP_HXX
+#include 
+#endif
+#ifndef _UNOOBJ_HXX
+#include 
+#endif
+#ifndef _DOCTXM_HXX //autogen
+#include 
+#endif
+#ifndef _TXTTXMRK_HXX //autogen
+#include 
+#endif
+#ifndef _UNOCRSR_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX //autogen
+#include 
+#endif
+#ifndef _VOS_MUTEX_HXX_ //autogen
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_CHAPTERFORMAT_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_FRAME_XMODEL_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XTEXTDOCUMENT_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUES_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_PropertyAttribute_HPP_
+#include 
+#endif
+#ifndef _UNOIDX_HXX
+#include 
+#endif
+#ifndef _DOCSH_HXX //autogen
+#include 
+#endif
+#ifndef _SV_SVAPP_HXX //autogen
+#include 
+#endif
+#ifndef _CHPFLD_HXX
+#include 
+#endif
+#ifndef _HINTS_HXX
+#include 
+#endif
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::uno;
+using namespace ::rtl;
+
+//-----------------------------------------------------------------------------
+String lcl_AnyToString(uno::Any rVal) throw(IllegalArgumentException)
+{
+    if(rVal.getValueType() != ::getCppuType((OUString*)0))
+        throw IllegalArgumentException();
+    return String(*(OUString*)rVal.getValue());
+}
+//-----------------------------------------------------------------------------
+sal_Int16 lcl_AnyToInt16(uno::Any rVal) throw(IllegalArgumentException)
+{
+    if(rVal.getValueType() != ::getCppuType((sal_Int16*)0))
+        throw IllegalArgumentException();
+    sal_Int16 nRet;
+    rVal >>= nRet;
+    return nRet;
+}
+//-----------------------------------------------------------------------------
+sal_Bool lcl_AnyToBool(uno::Any rVal) throw(IllegalArgumentException)
+{
+    if(rVal.getValueType() != ::getCppuBooleanType())
+        throw IllegalArgumentException();
+    return *(sal_Bool*) rVal.getValue();
+}
+/******************************************************************************
+ *
+ ******************************************************************************/
+SwTOXMark* lcl_GetMark(SwTOXType* pType, const SwTOXMark* pOwnMark)
+{
+    SwClientIter aIter(*pType);
+    SwTOXMark* pMark = (SwTOXMark*)aIter.First(TYPE(SwTOXMark));
+    while( pMark )
+    {
+        if(pMark == pOwnMark)
+            return pMark;
+        else
+            pMark = (SwTOXMark*)aIter.Next();
+    }
+    return 0;
+}
+
+/******************************************************************
+ * SwXDocumentIndex
+ ******************************************************************/
+/* -----------------20.06.98 11:06-------------------
+ *
+ * --------------------------------------------------*/
+class SwDocIdxProperties_Impl
+{
+    SwTOXBase*      pTOXBase;
+public:
+    SwTOXBase&      GetTOXBase() {return *pTOXBase;}
+    SwDocIdxProperties_Impl(const SwTOXType* pType);
+    ~SwDocIdxProperties_Impl(){delete pTOXBase;}
+};
+/* -----------------20.06.98 11:41-------------------
+ *
+ * --------------------------------------------------*/
+SwDocIdxProperties_Impl::SwDocIdxProperties_Impl(const SwTOXType* pType)
+{
+    SwForm aForm(pType->GetType());
+    pTOXBase = new SwTOXBase(pType, aForm,
+                                TOX_MARK, pType->GetTypeName());
+}
+/* -----------------------------10.03.00 18:02--------------------------------
+
+ ---------------------------------------------------------------------------*/
+const uno::Sequence< sal_Int8 > & SwXDocumentIndex::getUnoTunnelId()
+{
+    static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId();
+    return aSeq;
+}
+/* -----------------------------10.03.00 18:04--------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Int64 SAL_CALL SwXDocumentIndex::getSomething( const uno::Sequence< sal_Int8 >& rId )
+    throw(RuntimeException)
+{
+    if( rId.getLength() == 16
+        && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+                                        rId.getConstArray(), 16 ) )
+    {
+            return (sal_Int64)this;
+    }
+    return 0;
+}
+/* -----------------------------06.04.00 15:01--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXDocumentIndex::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXDocumentIndex");
+}
+/* -----------------------------06.04.00 15:01--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXDocumentIndex::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.text.BaseIndex") == rServiceName ||
+                ( TOX_INDEX == eTOXType && C2U("com.sun.star.text.DocumentIndex") == rServiceName) ||
+                ( TOX_CONTENT == eTOXType && C2U("com.sun.star.text.ContentIndex") == rServiceName) ||
+                ( TOX_USER == eTOXType && C2U("com.sun.star.text.UserDefinedIndex") == rServiceName) ||
+                ( TOX_ILLUSTRATIONS == eTOXType && C2U("com.sun.star.text.IllustrationIndex") == rServiceName) ||
+                ( TOX_TABLES == eTOXType && C2U("com.sun.star.text.TableIndex") == rServiceName) ||
+                ( TOX_OBJECTS == eTOXType && C2U("com.sun.star.text.ObjectIndex") == rServiceName) ||
+                ( TOX_AUTHORITIES == eTOXType && C2U("com.sun.star.text.Bibliography") == rServiceName);
+}
+/* -----------------------------06.04.00 15:01--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXDocumentIndex::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(2);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.BaseIndex");
+    switch( eTOXType )
+    {
+        case TOX_INDEX:         pArray[1] = C2U("com.sun.star.text.DocumentIndex");break;
+        case TOX_CONTENT:       pArray[1] = C2U("com.sun.star.text.ContentIndex");break;
+        case TOX_TABLES:        pArray[1] = C2U("com.sun.star.text.TableIndex");break;
+        case TOX_ILLUSTRATIONS: pArray[1] = C2U("com.sun.star.text.IllustrationIndex");break;
+        case TOX_OBJECTS:       pArray[1] = C2U("com.sun.star.text.ObjectIndex");break;
+        case TOX_AUTHORITIES :  pArray[1] = C2U("com.sun.star.text.Bibliography");break;
+        //case TOX_USER:
+        default:
+            pArray[1] = C2U("com.sun.star.text.UserDefinedIndex");
+    }
+    return aRet;
+}
+/*-- 14.12.98 09:35:03---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXDocumentIndex::SwXDocumentIndex(const SwTOXBaseSection* pB, SwDoc* pDc) :
+    m_pDoc(pDc),
+    aLstnrCntnr( (text::XTextContent*)this),
+    pBase(pB),
+    pProps(0),
+    _pMap(0),
+    pStyleAccess(0),
+    pTokenAccess(0),
+    bIsDescriptor(sal_False),
+    eTOXType(TOX_USER)
+{
+    if(pBase && m_pDoc)
+    {
+        pBase->GetFmt()->Add(this);
+        sal_uInt16 PropertyId;
+        eTOXType = pBase->SwTOXBase::GetType();
+        switch( eTOXType )
+        {
+            case TOX_INDEX:     PropertyId = PROPERTY_MAP_INDEX_IDX; break;
+            case TOX_CONTENT:   PropertyId = PROPERTY_MAP_INDEX_CNTNT; break;
+            case TOX_TABLES:        PropertyId = PROPERTY_MAP_INDEX_TABLES; break;
+            case TOX_ILLUSTRATIONS: PropertyId = PROPERTY_MAP_INDEX_ILLUSTRATIONS; break;
+            case TOX_OBJECTS:       PropertyId = PROPERTY_MAP_INDEX_OBJECTS; break;
+            case TOX_AUTHORITIES :  PropertyId = PROPERTY_MAP_BIBLIOGRAPHY; break;
+            //case TOX_USER:
+            default:
+                PropertyId = PROPERTY_MAP_INDEX_USER;
+        }
+        _pMap = aSwMapProvider.GetPropertyMap(PropertyId);
+    }
+}
+/* -----------------15.01.99 14:59-------------------
+ *
+ * --------------------------------------------------*/
+SwXDocumentIndex::SwXDocumentIndex(TOXTypes eType, SwDoc& rDoc) :
+    m_pDoc(0),
+    aLstnrCntnr( (text::XTextContent*)this),
+    pBase(0),
+    pProps(new SwDocIdxProperties_Impl(rDoc.GetTOXType(eType, 0))),
+    pStyleAccess(0),
+    pTokenAccess(0),
+    bIsDescriptor(sal_True),
+    eTOXType(eType)
+{
+    sal_uInt16 PropertyId;
+    switch(eType)
+    {
+        case TOX_INDEX:     PropertyId = PROPERTY_MAP_INDEX_IDX; break;
+        case TOX_CONTENT:   PropertyId = PROPERTY_MAP_INDEX_CNTNT; break;
+        case TOX_TABLES:        PropertyId = PROPERTY_MAP_INDEX_TABLES; break;
+        case TOX_ILLUSTRATIONS: PropertyId = PROPERTY_MAP_INDEX_ILLUSTRATIONS; break;
+        case TOX_OBJECTS:       PropertyId = PROPERTY_MAP_INDEX_OBJECTS; break;
+        case TOX_AUTHORITIES :  PropertyId = PROPERTY_MAP_BIBLIOGRAPHY; break;
+        //case TOX_USER:
+        default:
+            PropertyId = PROPERTY_MAP_INDEX_USER;
+    }
+    _pMap = aSwMapProvider.GetPropertyMap(PropertyId);
+}
+
+/*-- 14.12.98 09:35:04---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXDocumentIndex::~SwXDocumentIndex()
+{
+    delete pProps;
+}
+/*-- 14.12.98 09:35:05---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+OUString SwXDocumentIndex::getServiceName(void) throw( RuntimeException )
+{
+    USHORT nObjectType = SW_SERVICE_TYPE_INDEX;
+    switch(eTOXType)
+    {
+//      case TOX_INDEX:             break;
+        case TOX_USER:              nObjectType = SW_SERVICE_USER_INDEX;break;
+        case TOX_CONTENT:           nObjectType = SW_SERVICE_CONTENT_INDEX;break;
+        case TOX_ILLUSTRATIONS:     nObjectType = SW_SERVICE_INDEX_ILLUSTRATIONS;break;
+        case TOX_OBJECTS:           nObjectType = SW_SERVICE_INDEX_OBJECTS;break;
+        case TOX_TABLES:            nObjectType = SW_SERVICE_INDEX_TABLES;break;
+        case TOX_AUTHORITIES:       nObjectType = SW_SERVICE_INDEX_BIBLIOGRAPHY;break;
+    }
+    return SwXServiceProvider::GetProviderName(nObjectType);
+}
+/*-- 14.12.98 09:35:05---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXDocumentIndex::update(void) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwTOXBase* pTOXBase = (SwTOXBaseSection*)GetFmt()->GetSection();
+    if(!pTOXBase)
+        throw RuntimeException();
+    ((SwTOXBaseSection*)pTOXBase)->Update();
+    // Seitennummern eintragen
+    ((SwTOXBaseSection*)pTOXBase)->UpdatePageNum();
+}
+/*-- 14.12.98 09:35:05---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Reference< XPropertySetInfo >  SwXDocumentIndex::getPropertySetInfo(void) throw( RuntimeException )
+{
+    Reference< XPropertySetInfo >  aRef = new SfxItemPropertySetInfo( _pMap );
+    return aRef;
+}
+/*-- 14.12.98 09:35:05---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXDocumentIndex::setPropertyValue(const OUString& rPropertyName,
+                                        const uno::Any& aValue)
+        throw( UnknownPropertyException, PropertyVetoException,
+                 IllegalArgumentException, WrappedTargetException, RuntimeException)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                                                        _pMap, rPropertyName);
+    if(!pMap)
+        throw UnknownPropertyException();
+    SwTOXBase* pTOXBase;
+    if(GetFmt())
+        pTOXBase = (SwTOXBaseSection*)GetFmt()->GetSection();
+    else if(bIsDescriptor)
+        pTOXBase = &pProps->GetTOXBase();
+    if(pTOXBase)
+    {
+        sal_uInt16 nCreate = pTOXBase->GetCreateType();
+        sal_uInt16 nTOIOptions = 0;
+        sal_uInt16 nOLEOptions = pTOXBase->GetOLEOptions();
+        TOXTypes eTxBaseType = pTOXBase->GetTOXType()->GetType();
+        if( eTxBaseType == TOX_INDEX )
+            nTOIOptions = pTOXBase->GetOptions();
+        SwForm  aForm(pTOXBase->GetTOXForm());
+        sal_Bool bForm = sal_False;
+        SfxItemSet* pAttrSet = 0;
+        switch(pMap->nWID)
+        {
+            case WID_IDX_TITLE  :    pTOXBase->SetTitle(lcl_AnyToString(aValue)); break;
+            case WID_LEVEL      :
+                pTOXBase->SetLevel(lcl_AnyToInt16(aValue));
+            break;
+            case WID_CREATE_FROM_MARKS                 :
+                nCreate = lcl_AnyToBool(aValue) ? nCreate | TOX_MARK: nCreate & ~TOX_MARK;
+            break;
+            case WID_CREATE_FROM_OUTLINE               :
+                nCreate = lcl_AnyToBool(aValue) ? nCreate | TOX_OUTLINELEVEL: nCreate & ~TOX_OUTLINELEVEL;
+            break;
+//          case WID_PARAGRAPH_STYLE_NAMES             :DBG_ERROR("not implemented")
+//          break;
+            case WID_CREATE_FROM_CHAPTER               :
+                pTOXBase->SetFromChapter(lcl_AnyToBool(aValue));
+            break;
+            case WID_CREATE_FROM_LABELS                :
+                nCreate = lcl_AnyToBool(aValue) ? nCreate | TOX_SEQUENCE : nCreate & ~TOX_SEQUENCE;
+            break;
+            case WID_PROTECTED                         :
+                pTOXBase->SetProtected(lcl_AnyToBool(aValue));
+            break;
+            case WID_USE_ALPHABETICAL_SEPARATORS:
+                nTOIOptions = lcl_AnyToBool(aValue) ?
+                    nTOIOptions | TOI_ALPHA_DELIMITTER : nTOIOptions & ~TOI_ALPHA_DELIMITTER;
+            break;
+            case WID_USE_KEY_AS_ENTRY                  :
+                nTOIOptions = lcl_AnyToBool(aValue) ?
+                    nTOIOptions | TOI_KEY_AS_ENTRY : nTOIOptions & ~TOI_KEY_AS_ENTRY;
+            break;
+            case WID_USE_COMBINED_ENTRIES              :
+                nTOIOptions = lcl_AnyToBool(aValue) ?
+                    nTOIOptions | TOI_SAME_ENTRY : nTOIOptions & ~TOI_SAME_ENTRY;
+            break;
+            case WID_IS_CASE_SENSITIVE                 :
+                nTOIOptions = lcl_AnyToBool(aValue) ?
+                    nTOIOptions | TOI_CASE_SENSITIVE : nTOIOptions & ~TOI_CASE_SENSITIVE;
+            break;
+            case WID_USE_P_P                           :
+                nTOIOptions = lcl_AnyToBool(aValue) ?
+                    nTOIOptions | TOI_FF : nTOIOptions & ~TOI_FF;
+            break;
+            case WID_USE_DASH                          :
+                nTOIOptions = lcl_AnyToBool(aValue) ?
+                    nTOIOptions | TOI_DASH : nTOIOptions & ~TOI_DASH;
+            break;
+            case WID_USE_UPPER_CASE                    :
+                nTOIOptions = lcl_AnyToBool(aValue) ?
+                    nTOIOptions | TOI_INITIAL_CAPS : nTOIOptions & ~TOI_INITIAL_CAPS;
+            break;
+            case WID_IS_COMMA_SEPARATED :
+                aForm.SetCommaSeparated(lcl_AnyToBool(aValue));
+            break;
+            case WID_LABEL_CATEGORY                    :
+                pTOXBase->SetSequenceName(lcl_AnyToString(aValue));
+            break;
+            case WID_LABEL_DISPLAY_TYPE                :
+            {
+                sal_Int16 nVal = lcl_AnyToInt16(aValue);
+                    sal_uInt16 nSet = CAPTION_COMPLETE;
+                    switch (nVal)
+                    {
+                        case text::ChapterFormat::NAME_NUMBER: nSet = CAPTION_COMPLETE;
+                        break;
+                        case text::ChapterFormat::NUMBER    : nSet = CAPTION_NUMBER;
+                        break;
+                        case text::ChapterFormat::NAME : nSet = CAPTION_TEXT;
+                        break;
+                        default:
+                            throw IllegalArgumentException();
+                    }
+                    pTOXBase->SetCaptionDisplay((SwCaptionDisplay)nVal);
+            }
+            break;
+            case WID_USE_LEVEL_FROM_SOURCE             :
+                pTOXBase->SetLevelFromChapter(lcl_AnyToBool(aValue));
+            break;
+//          case WID_LEVEL_FORMAT                      :
+//              object readonly
+//          break;
+//          case WID_LEVEL_PARAGRAPH_STYLES            :DBG_ERROR("not implemented")
+//              object readonly
+//          break;
+//          case WID_RECALC_TAB_STOPS                  :DBG_ERROR("not implemented")
+//              lcl_AnyToBool(aValue) ?
+//          break;
+            //case WID_???                             :
+            break;
+            case WID_MAIN_ENTRY_CHARACTER_STYLE_NAME   :
+                pTOXBase->SetMainEntryCharStyle(lcl_AnyToString(aValue));
+            break;
+            case WID_CREATE_FROM_TABLES                :
+                nCreate = lcl_AnyToBool(aValue) ? nCreate | TOX_TABLE : nCreate & ~TOX_TABLE;
+            break;
+            case WID_CREATE_FROM_TEXT_FRAMES           :
+                nCreate = lcl_AnyToBool(aValue) ? nCreate | TOX_FRAME : nCreate & ~TOX_FRAME;
+            break;
+            case WID_CREATE_FROM_GRAPHIC_OBJECTS       :
+                nCreate = lcl_AnyToBool(aValue) ? nCreate | TOX_GRAPHIC : nCreate & ~TOX_GRAPHIC;
+            break;
+            case WID_CREATE_FROM_EMBEDDED_OBJECTS      :
+                if(lcl_AnyToBool(aValue))
+                    nCreate |= TOX_OLE;
+                else
+                    nCreate &= ~TOX_OLE;
+            break;
+            case WID_CREATE_FROM_STAR_MATH:
+                nOLEOptions = lcl_AnyToBool(aValue) ? nOLEOptions | TOO_MATH : nOLEOptions & ~TOO_MATH;
+            break;
+            case WID_CREATE_FROM_STAR_IMAGE            :
+                nOLEOptions = lcl_AnyToBool(aValue) ? nOLEOptions | TOO_IMAGE : nOLEOptions & ~TOO_IMAGE;
+            break;
+            case WID_CREATE_FROM_STAR_CHART            :
+                nOLEOptions = lcl_AnyToBool(aValue) ? nOLEOptions | TOO_CHART : nOLEOptions & ~TOO_CHART;
+            break;
+            case WID_CREATE_FROM_STAR_CALC             :
+                nOLEOptions = lcl_AnyToBool(aValue) ? nOLEOptions | TOO_CALC : nOLEOptions & ~TOO_CALC;
+            break;
+            case WID_CREATE_FROM_STAR_DRAW             :
+                nOLEOptions = lcl_AnyToBool(aValue) ? nOLEOptions | TOO_DRAW_IMPRESS : nOLEOptions & ~TOO_DRAW_IMPRESS;
+            break;
+            case WID_CREATE_FROM_OTHER_EMBEDDED_OBJECTS:
+                nOLEOptions = lcl_AnyToBool(aValue) ? nOLEOptions | TOO_OTHER : nOLEOptions & ~TOO_OTHER;
+            break;
+            case WID_PARA_HEAD             :
+                bForm = sal_True;
+                //Header steht an Pos 0
+                aForm.SetTemplate( 0, lcl_AnyToString(aValue));
+            break;
+            case WID_PARA_SEP              :
+                bForm = sal_True;
+                aForm.SetTemplate( 1, lcl_AnyToString(aValue));
+            break;
+
+            case WID_PARA_LEV1             :
+            case WID_PARA_LEV2             :
+            case WID_PARA_LEV3             :
+            case WID_PARA_LEV4             :
+            case WID_PARA_LEV5             :
+            case WID_PARA_LEV6             :
+            case WID_PARA_LEV7             :
+            case WID_PARA_LEV8             :
+            case WID_PARA_LEV9             :
+            case WID_PARA_LEV10            :
+            {
+                bForm = sal_True;
+                // im sdbcx::Index beginnt Lebel 1 bei Pos 2 sonst bei Pos 1
+                sal_uInt16 nLPos = pTOXBase->GetType() == TOX_INDEX ? 2 : 1;
+                aForm.SetTemplate(nLPos + pMap->nWID - WID_PARA_LEV1, lcl_AnyToString(aValue));
+            }
+            break;
+            /*
+            case WID_FORM_SEP  :
+                bForm = sal_True;
+                //in Stichwort-Forms steht der Trenner an Pos 1
+                aForm.SetPattern(1, lcl_AnyToString(aValue));
+            break;
+            case WID_FORM_LEV1 :
+            case WID_FORM_LEV2 :
+            case WID_FORM_LEV3 :
+            case WID_FORM_LEV4 :
+            case WID_FORM_LEV5 :
+            case WID_FORM_LEV6 :
+            case WID_FORM_LEV7 :
+            case WID_FORM_LEV8 :
+            case WID_FORM_LEV9 :
+            case WID_FORM_LEV10:
+            {
+                bForm = sal_True;
+                // im sdbcx::Index beginnt Lebel 1 bei Pos 2 sonst bei Pos 1
+                sal_uInt16 nLPos = pTOXBase->GetType() == TOX_INDEX ? 2 : 1;
+                aForm.SetPattern(nLPos + pMap->nWID - WID_FORM_LEV1, lcl_AnyToString(aValue));
+            }
+            break;
+             */
+            default:
+                //this is for items only
+                if(WID_PRIMARY_KEY > pMap->nWID)
+                {
+                    SfxItemPropertySet aPropSet(_pMap);
+                    const SwAttrSet& rSet = m_pDoc->GetTOXBaseAttrSet(*pTOXBase);
+                    pAttrSet = new SfxItemSet(rSet);
+                    aPropSet.setPropertyValue(rPropertyName, aValue, *pAttrSet);
+
+                    const SwSectionFmts& rSects = m_pDoc->GetSections();
+                    const SwSectionFmt* pOwnFmt = GetFmt();
+                    for(sal_uInt16 i = 0; i < rSects.Count(); i++)
+                    {
+                        const SwSectionFmt* pTmpFmt = rSects[ i ];
+                        if(pTmpFmt == pOwnFmt)
+                        {
+                            m_pDoc->ChgSection( i, *(SwTOXBaseSection*)pTOXBase, pAttrSet );
+                            break;
+                        }
+                    }
+                }
+        }
+        pTOXBase->SetCreate(nCreate);
+        pTOXBase->SetOLEOptions(nOLEOptions);
+        if(pTOXBase->GetTOXType()->GetType() == TOX_INDEX)
+            pTOXBase->SetOptions(nTOIOptions);
+        if(bForm)
+            pTOXBase->SetTOXForm(aForm);
+        delete pAttrSet;
+    }
+    else
+        throw RuntimeException();
+
+}
+/*-- 14.12.98 09:35:05---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXDocumentIndex::getPropertyValue(const OUString& rPropertyName)
+    throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Any aRet;
+    const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                                                    _pMap, rPropertyName);
+    if(!pMap)
+        throw UnknownPropertyException();
+    SwTOXBase* pTOXBase;
+    if(GetFmt())
+        pTOXBase = (SwTOXBaseSection*)GetFmt()->GetSection();
+    else if(bIsDescriptor)
+        pTOXBase = &pProps->GetTOXBase();
+    if(pTOXBase)
+    {
+        sal_uInt16 nCreate = pTOXBase->GetCreateType();
+        sal_uInt16 nTOIOptions = 0;
+        sal_uInt16 nOLEOptions = pTOXBase->GetOLEOptions();
+        if(pTOXBase->GetTOXType()->GetType() == TOX_INDEX)
+            nTOIOptions = pTOXBase->GetOptions();
+        const SwForm& rForm = pTOXBase->GetTOXForm();
+        sal_Bool bBOOL = sal_True;
+        sal_Bool bRet = sal_False;
+        switch(pMap->nWID)
+        {
+            case WID_IDX_TITLE  :
+                bBOOL = sal_False;
+                aRet <<= OUString(pTOXBase->GetTitle());
+            break;
+            case WID_LEVEL      :
+                bBOOL = sal_False;
+                aRet <<= (sal_Int16)pTOXBase->GetLevel();
+            break;
+            case WID_CREATE_FROM_MARKS                 :
+                bRet = 0 != (nCreate & TOX_MARK);
+            break;
+            case WID_CREATE_FROM_OUTLINE               :
+                bRet = 0 != (nCreate & TOX_OUTLINELEVEL);
+            break;
+//          case WID_PARAGRAPH_STYLE_NAMES             :DBG_ERROR("not implemented")
+//          break;
+            case WID_CREATE_FROM_CHAPTER               :
+                bRet = pTOXBase->IsFromChapter();
+            break;
+            case WID_CREATE_FROM_LABELS                :
+                bRet = 0 != (nCreate & TOX_SEQUENCE);
+            break;
+            case WID_PROTECTED                         :
+                bRet = pTOXBase->IsProtected();
+            break;
+            case WID_USE_ALPHABETICAL_SEPARATORS:
+                bRet = 0 != (nTOIOptions & TOI_ALPHA_DELIMITTER);
+            break;
+            case WID_USE_KEY_AS_ENTRY                  :
+                bRet = 0 != (nTOIOptions & TOI_KEY_AS_ENTRY);
+            break;
+            case WID_USE_COMBINED_ENTRIES              :
+                bRet = 0 != (nTOIOptions & TOI_SAME_ENTRY);
+            break;
+            case WID_IS_CASE_SENSITIVE                 :
+                bRet = 0 != (nTOIOptions & TOI_CASE_SENSITIVE);
+            break;
+            case WID_USE_P_P:
+                bRet = 0 != (nTOIOptions & TOI_FF);
+            break;
+            case WID_USE_DASH                          :
+                bRet = 0 != (nTOIOptions & TOI_DASH);
+            break;
+            case WID_USE_UPPER_CASE                    :
+                bRet = 0 != (nTOIOptions & TOI_INITIAL_CAPS);
+            break;
+            case WID_IS_COMMA_SEPARATED :
+                bRet = rForm.IsCommaSeparated();
+            break;
+            case WID_LABEL_CATEGORY                    :
+                aRet <<= OUString(pTOXBase->GetSequenceName());
+                bBOOL = sal_False;
+            break;
+            case WID_LABEL_DISPLAY_TYPE                :
+            {
+                bBOOL = sal_False;
+                sal_Int16 nSet = text::ChapterFormat::NAME_NUMBER;
+                switch (pTOXBase->GetCaptionDisplay())
+                {
+                    case CAPTION_COMPLETE:  nSet = text::ChapterFormat::NAME_NUMBER;break;
+                    case CAPTION_NUMBER  :  nSet = text::ChapterFormat::NUMBER; break;
+                    case CAPTION_TEXT    :  nSet = text::ChapterFormat::NAME;      break;
+                }
+                aRet <<= nSet;
+            }
+            break;
+            case WID_USE_LEVEL_FROM_SOURCE             :
+                bRet = pTOXBase->IsLevelFromChapter();
+            break;
+            case WID_LEVEL_FORMAT                      :
+            {
+                Reference< container::XIndexReplace >  xTokenAcc =
+                                    ((SwXDocumentIndex*)this)->GetTokenAccess();
+                if(!xTokenAcc.is())
+                    xTokenAcc = new SwXIndexTokenAccess_Impl(*
+                                                (SwXDocumentIndex*)this);
+                aRet.setValue(&xTokenAcc, ::getCppuType((const Reference*)0));
+                bBOOL = sal_False;
+            }
+            break;
+            case WID_LEVEL_PARAGRAPH_STYLES            :
+            {
+                Reference< container::XIndexReplace >  xStyleAcc =
+                                    ((SwXDocumentIndex*)this)->GetStyleAccess();
+                if(!xStyleAcc.is())
+                    xStyleAcc = new SwXIndexStyleAccess_Impl(*
+                                                (SwXDocumentIndex*)this);
+                aRet.setValue(&xStyleAcc, ::getCppuType((const Reference*)0));
+                bBOOL = sal_False;
+            }
+            break;
+//          case WID_RECALC_TAB_STOPS                  :
+//              tab stops are alway recalculated
+//          break;
+            //case WID_???                             :
+            break;
+            case WID_MAIN_ENTRY_CHARACTER_STYLE_NAME   :
+                bBOOL = sal_False;
+                aRet <<= OUString(pTOXBase->GetMainEntryCharStyle());
+            break;
+            case WID_CREATE_FROM_TABLES                :
+                bRet = 0 != (nCreate & TOX_TABLE);
+            break;
+            case WID_CREATE_FROM_TEXT_FRAMES           :
+                bRet = 0 != (nCreate & TOX_FRAME);
+            break;
+            case WID_CREATE_FROM_GRAPHIC_OBJECTS       :
+                bRet = 0 != (nCreate & TOX_GRAPHIC);
+            break;
+            case WID_CREATE_FROM_EMBEDDED_OBJECTS      :
+                bRet = 0 != (nCreate &= TOX_OLE);
+            break;
+            case WID_CREATE_FROM_STAR_MATH:
+                bRet = 0 != (nOLEOptions & TOO_MATH);
+            break;
+            case WID_CREATE_FROM_STAR_IMAGE            :
+                bRet = 0 != (nOLEOptions & TOO_IMAGE);
+            break;
+            case WID_CREATE_FROM_STAR_CHART            :
+                bRet = 0 != (nOLEOptions & TOO_CHART);
+            break;
+            case WID_CREATE_FROM_STAR_CALC             :
+                bRet = 0 != (nOLEOptions & TOO_CALC);
+            break;
+            case WID_CREATE_FROM_STAR_DRAW             :
+                bRet = 0 != (nOLEOptions & TOO_DRAW_IMPRESS);
+            break;
+            case WID_CREATE_FROM_OTHER_EMBEDDED_OBJECTS:
+                bRet = 0 != (nOLEOptions & TOO_OTHER);
+            break;
+            case WID_PARA_HEAD             :
+                //Header steht an Pos 0
+                aRet <<= OUString(rForm.GetTemplate( 0 ));
+                bBOOL = sal_False;
+            break;
+            case WID_PARA_SEP              :
+                aRet <<= OUString(rForm.GetTemplate( 1 ));
+                bBOOL = sal_False;
+            break;
+            case WID_PARA_LEV1             :
+            case WID_PARA_LEV2             :
+            case WID_PARA_LEV3             :
+            case WID_PARA_LEV4             :
+            case WID_PARA_LEV5             :
+            case WID_PARA_LEV6             :
+            case WID_PARA_LEV7             :
+            case WID_PARA_LEV8             :
+            case WID_PARA_LEV9             :
+            case WID_PARA_LEV10            :
+            {
+                // im sdbcx::Index beginnt Lebel 1 bei Pos 2 sonst bei Pos 1
+                sal_uInt16 nLPos = pTOXBase->GetType() == TOX_INDEX ? 2 : 1;
+                aRet <<= OUString(rForm.GetTemplate(nLPos + pMap->nWID - WID_PARA_LEV1));
+                bBOOL = sal_False;
+            }
+            break;
+            default:
+                //this is for items only
+                bBOOL = sal_False;
+                if(WID_PRIMARY_KEY > pMap->nWID)
+                {
+                    SfxItemPropertySet aPropSet(_pMap);
+                    const SwAttrSet& rSet = m_pDoc->GetTOXBaseAttrSet(*pTOXBase);
+                    aRet = aPropSet.getPropertyValue(rPropertyName, rSet);
+                }
+        }
+        if(bBOOL)
+            aRet.setValue(&bRet, ::getCppuBooleanType());
+    }
+    return aRet;
+}
+/*-- 14.12.98 09:35:06---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXDocumentIndex::addPropertyChangeListener(const OUString& PropertyName, const Reference< XPropertyChangeListener > & aListener) throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 14.12.98 09:35:06---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXDocumentIndex::removePropertyChangeListener(const OUString& PropertyName, const Reference< XPropertyChangeListener > & aListener) throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 14.12.98 09:35:06---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXDocumentIndex::addVetoableChangeListener(const OUString& PropertyName, const Reference< XVetoableChangeListener > & aListener) throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 14.12.98 09:35:07---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXDocumentIndex::removeVetoableChangeListener(const OUString& PropertyName, const Reference< XVetoableChangeListener > & aListener) throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 14.12.98 09:35:07---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXDocumentIndex::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew)
+{
+    if(pOld && pOld->Which() == RES_REMOVE_UNO_OBJECT &&
+        (void*)GetRegisteredIn() == ((SwPtrMsgPoolItem *)pOld)->pObject )
+            ((SwModify*)GetRegisteredIn())->Remove(this);
+    else
+        ClientModify(this, pOld, pNew);
+    if(!GetRegisteredIn())
+        aLstnrCntnr.Disposing();
+}
+/* -----------------18.02.99 13:39-------------------
+ *
+ * --------------------------------------------------*/
+void SwXDocumentIndex::attachToRange(const Reference< text::XTextRange > & xTextRange)
+    throw( IllegalArgumentException, RuntimeException )
+{
+    if(!bIsDescriptor)
+        throw RuntimeException();
+    Reference xRangeTunnel( xTextRange, uno::UNO_QUERY);
+    SwXTextRange* pRange = 0;
+    SwXTextCursor* pCursor = 0;
+    if(xRangeTunnel.is())
+    {
+        pRange = (SwXTextRange*)xRangeTunnel->getSomething(
+                                SwXTextRange::getUnoTunnelId());
+        pCursor = (SwXTextCursor*)xRangeTunnel->getSomething(
+                                SwXTextCursor::getUnoTunnelId());
+    }
+
+    SwDoc* pDoc = pRange ? (SwDoc*)pRange->GetDoc() : pCursor ? (SwDoc*)pCursor->GetDoc() : 0;
+    if(pDoc )
+    {
+        SwUnoInternalPaM aPam(*pDoc);
+        //das muss jetzt sal_True liefern
+        SwXTextRange::XTextRangeToSwPaM(aPam, xTextRange);
+        //TODO: Unterscheidung innerhalb von Benutzerverzeichnissen einbauen
+//      const SwTOXType* pType = pDoc->GetTOXType(pProps->eToxType, 0);
+//      DBG_ASSERT(pType, "Wieso gibt es diesen Typ nicht?" )
+
+            const SwTOXBase* pOld = pDoc->GetCurTOX( *aPam.Start() );
+            if(!pOld)
+            {
+                UnoActionContext aAction(pDoc);
+                if(aPam.HasMark())
+                    pDoc->DeleteAndJoin(aPam);
+
+//              SwForm aForm(pType->GetType());
+//              SwTOXBase* pTOXBase = new SwTOXBase(pType, aForm,
+//                          TOX_MARK, pType->GetTypeName());
+                SwTOXBase& rTOXBase = pProps->GetTOXBase();
+                //TODO: Descriptor- interface!
+/*              sal_uInt16 nCreate = pTOXBase->GetCreateType();
+                sal_uInt16 nOLEOptions = pTOXBase->GetOLEOptions();
+                sal_uInt16 nTOIOptions = 0;
+                const SfxItemPropertyMap* pMap = _pMap;
+                while(pMap->nWID)
+                {
+                    // hier werden alle drei Typen verarbeitet, es sollten aber nie falsche Einstellungen m”glich sein
+                    switch(pMap->nWID)
+                    {
+                        case WID_IDX_TITLE:
+                            pTOXBase->SetTitle(pProps->sTitle);
+                        break;
+                        case WID_LEVEL                             :
+                            pTOXBase->SetLevel(pProps->nLevels);
+                        break;
+                        case WID_CREATE_FROM_MARKS                 :
+                            nCreate = pProps->bMarks ?
+                                nCreate | TOX_MARK: nCreate & ~TOX_MARK;
+                        break;
+                        case WID_CREATE_FROM_OUTLINE               :
+                            nCreate = pProps->bOutlines ?
+                                nCreate | TOX_OUTLINELEVEL: nCreate & ~TOX_OUTLINELEVEL;
+                        break;
+//                      case WID_PARAGRAPH_STYLE_NAMES             :
+//                          DBG_ERROR("not implemented")
+//                          //pProps->bParaStyles = lcl_AnyToBool(aValue);
+//                      break;
+                        case WID_CREATE_FROM_CHAPTER               :
+                            pTOXBase->SetFromChapter(pProps->bFromChapter);
+                        break;
+                        case WID_CREATE_FROM_LABELS                :
+                            nCreate = pProps->bFromLabels ?
+                                nCreate | TOX_SEQUENCE : nCreate & ~TOX_SEQUENCE;
+                        break;
+                        case WID_PROTECTED                         :
+                            pTOXBase->SetProtected(pProps->bProtected);
+                        break;
+                        case WID_USE_ALPHABETICAL_SEPARATORS:
+                            nTOIOptions = pProps->bUseAlphabeticalSeparators ?
+                                nTOIOptions | TOI_ALPHA_DELIMITTER : nTOIOptions & ~TOI_ALPHA_DELIMITTER;
+                        break;
+                        case WID_USE_KEY_AS_ENTRY                  :
+                            nTOIOptions = pProps->bKeyAsEntry ?
+                                nTOIOptions | TOI_KEY_AS_ENTRY : nTOIOptions & ~TOI_KEY_AS_ENTRY;
+                        break;
+                        case WID_USE_COMBINED_ENTRIES              :
+                            nTOIOptions = pProps->bCombineEntries ?
+                                nTOIOptions | TOI_SAME_ENTRY : nTOIOptions & ~TOI_SAME_ENTRY;
+                        break;
+                        case WID_IS_CASE_SENSITIVE                 :
+                            nTOIOptions = pProps->bCaseSensitive ?
+                                nTOIOptions | TOI_CASE_SENSITIVE :
+                                    nTOIOptions & ~TOI_CASE_SENSITIVE;
+                        break;
+                        case WID_USE_P_P                           :
+                            nTOIOptions = pProps->bUsePP ?
+                                nTOIOptions | TOI_FF : nTOIOptions & ~TOI_FF;
+                        break;
+                        case WID_USE_DASH                          :
+                            nTOIOptions = pProps->bUseDash ?
+                                nTOIOptions | TOI_DASH : nTOIOptions & ~TOI_DASH;
+                        break;
+                        case WID_USE_UPPER_CASE                    :
+                            nTOIOptions = pProps->bUseUpperCase ?
+                                nTOIOptions | TOI_INITIAL_CAPS : nTOIOptions & ~TOI_INITIAL_CAPS;
+                        break;
+                        case WID_IS_COMMA_SEPARATED :
+                            aForm.SetCommaSeparated(pProps->bIsCommaSeparated);
+                        break;
+                        case WID_LABEL_CATEGORY                    :
+                            pTOXBase->SetSequenceName(pProps->sLabelCategory);
+                        break;
+                        case WID_LABEL_DISPLAY_TYPE                :
+                            pTOXBase->SetCaptionDisplay((SwCaptionDisplay)pProps->nDisplayType);
+                        break;
+                        case WID_USE_LEVEL_FROM_SOURCE             :
+                            pTOXBase->SetFromChapter(pProps->bLevelFromChapter);
+                        break;
+                        case WID_LEVEL_PARAGRAPH_STYLES            :
+                        {
+                            for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
+                                pTOXBase->SetStyleNames(pProps->sStyleNames[i], i);
+                        }
+                        break;
+//                      case WID_RECALC_TAB_STOPS                  :
+//                          DBG_ERROR("not implemented")
+//                          now always recalculated
+//                      break;
+                        //case WID_???                             :
+                        break;
+                        case WID_MAIN_ENTRY_CHARACTER_STYLE_NAME   :
+                            pTOXBase->SetMainEntryCharStyle(pProps->sMainEntryStyleName);
+                        break;
+                        case WID_CREATE_FROM_TABLES                :
+                            nCreate = pProps->bTables ?
+                                nCreate | TOX_TABLE : nCreate & ~TOX_TABLE;
+                        break;
+                        case WID_CREATE_FROM_TEXT_FRAMES           :
+                            nCreate = pProps->bTextFrames ?
+                                nCreate | TOX_FRAME : nCreate & ~TOX_FRAME;
+                        break;
+                        case WID_CREATE_FROM_GRAPHIC_OBJECTS       :
+                            nCreate = pProps->bGraphics ?
+                                nCreate | TOX_GRAPHIC : nCreate & ~TOX_GRAPHIC;
+                        break;
+                        case WID_CREATE_FROM_EMBEDDED_OBJECTS      :
+                            nCreate = pProps->bEmbeddedObjects ?
+                                nCreate | TOX_OLE : nCreate &~ TOX_OLE;
+                        break;
+                        case WID_CREATE_FROM_STAR_MATH             :
+                            nOLEOptions = pProps->bFromStarMath ?
+                                nOLEOptions | TOO_MATH : nOLEOptions & ~TOO_MATH;
+                        break;
+                        case WID_CREATE_FROM_STAR_IMAGE            :
+                            nOLEOptions = pProps->bFromStarImage ?
+                                nOLEOptions | TOO_IMAGE : nOLEOptions & ~TOO_IMAGE;
+                        break;
+                        case WID_CREATE_FROM_STAR_CHART            :
+                            nOLEOptions = pProps->bFromStarChart ?
+                                nOLEOptions | TOO_CHART : nOLEOptions & ~TOO_CHART;
+                        break;
+                        case WID_CREATE_FROM_STAR_CALC             :
+                            nOLEOptions = pProps->bFromStarCalc ?
+                                nOLEOptions | TOO_CALC : nOLEOptions & ~TOO_CALC;
+                        break;
+                        case WID_CREATE_FROM_STAR_DRAW             :
+                            nOLEOptions = pProps->bFromStarDraw ?
+                                nOLEOptions | TOO_DRAW_IMPRESS : nOLEOptions & ~TOO_DRAW_IMPRESS;
+                        break;
+                        case WID_CREATE_FROM_OTHER_EMBEDDED_OBJECTS:
+                            nOLEOptions = pProps->bFromOtherEmbedded ?
+                                nOLEOptions | TOO_OTHER : nOLEOptions & ~TOO_OTHER;
+                        break;
+                        case WID_PARA_HEAD:
+                            //Header steht an Pos 0
+                            aForm.SetTemplate( 0, pProps->sParaStyleHeading);
+                        break;
+                        case WID_PARA_SEP              :
+                            //in Stichwort-Forms steht der Trenner an Pos 1
+                            aForm.SetTemplate( 1, pProps->sParaStyleSeparator);
+                        break;
+                        case WID_PARA_LEV1:
+                        case WID_PARA_LEV2:
+                        case WID_PARA_LEV3:
+                        case WID_PARA_LEV4:
+                        case WID_PARA_LEV5:
+                        case WID_PARA_LEV6:
+                        case WID_PARA_LEV7:
+                        case WID_PARA_LEV8:
+                        case WID_PARA_LEV9:
+                        case WID_PARA_LEV10:
+                        {
+                            // im sdbcx::Index beginnt Level 1 bei Pos 2 sonst bei Pos 0
+                            sal_uInt16 nLPos = pType->GetType() == TOX_INDEX ? 2 : 1;
+                            aForm.SetTemplate(nLPos + pMap->nWID - WID_PARA_LEV1,
+                                                        pProps->sParaStyles[pMap->nWID - WID_PARA_LEV1]);
+                        }
+                        break;
+                        case WID_LEVEL_FORMAT:
+                        {
+                            sal_uInt16 nStart = pType->GetType() == TOX_INDEX ? 2 : 1;
+                            for(sal_uInt16 i = nStart; i < aForm.GetFormMax(); i++)
+                            {
+                                aForm.SetPattern(i, pProps->sLevelPatterns[i - 1]);
+                            }
+                        }
+                        break;
+                    }
+                    pMap++;
+                }
+                switch(pType->GetType())
+                {
+                    case TOX_INDEX:
+                        pTOXBase->SetOptions(nTOIOptions);
+                    break;
+                    case TOX_CONTENT:
+                    //break;
+                    case TOX_USER:
+                        if(!nCreate)
+                            nCreate = TOX_MARK;
+                    break;
+                }
+                pTOXBase->SetOLEOptions(nOLEOptions);
+                pTOXBase->SetCreate(nCreate);
+                pTOXBase->SetTOXForm(aForm);
+                //TODO: apply Section attributes (columns and background)
+*/              const SwTOXBaseSection* pTOX = pDoc->InsertTableOf(
+                                    *aPam.GetPoint(), rTOXBase, 0, sal_True );
+
+//              if(pProps->sName.Len())
+//                  pDoc->SetTOXBaseName( *pTOX, pProps->sName );
+                    pDoc->SetTOXBaseName( *pTOX, pProps->GetTOXBase().GetTOXName() );
+
+
+                // Seitennummern eintragen
+                pBase = (const SwTOXBaseSection*)pTOX;
+                pBase->GetFmt()->Add(this);
+                ((SwTOXBaseSection*)pTOX)->UpdatePageNum();
+
+//              delete pTOXBase;
+            }
+            else
+                throw IllegalArgumentException();
+
+        DELETEZ(pProps);
+        m_pDoc = pDoc;
+        bIsDescriptor = sal_False;
+    }
+}
+/*-- 15.01.99 14:23:51---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXDocumentIndex::attach(const Reference< text::XTextRange > & xTextRange)
+    throw( IllegalArgumentException, RuntimeException )
+{
+}
+/*-- 15.01.99 14:23:56---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Reference< text::XTextRange >  SwXDocumentIndex::getAnchor(void) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    Reference< text::XTextRange >   xRet;
+    if(GetRegisteredIn())
+    {
+        SwSectionFmt*  pSectFmt = GetFmt();
+        const SwNodeIndex* pIdx;
+        if( 0 != ( pIdx = pSectFmt->GetCntnt().GetCntntIdx() ) &&
+            pIdx->GetNode().GetNodes().IsDocNodes() )
+        {
+            SwPaM aPaM(*pIdx);
+            aPaM.Move( fnMoveForward, fnGoCntnt );
+            aPaM.SetMark();
+            aPaM.GetPoint()->nNode = *pIdx->GetNode().EndOfSectionNode();
+            aPaM.Move( fnMoveBackward, fnGoCntnt );
+            xRet = ::CreateTextRangeFromPosition(pSectFmt->GetDoc(),
+                *aPaM.GetMark(), aPaM.GetPoint());
+        }
+    }
+    else
+        throw RuntimeException();
+    return xRet;
+}
+/*-- 15.01.99 15:46:48---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void lcl_RemoveChildSections(SwSectionFmt& rParentFmt)
+{
+    SwSections aTmpArr;
+    SwDoc* pDoc = rParentFmt.GetDoc();
+    sal_uInt16 nCnt = rParentFmt.GetChildSections(aTmpArr,SORTSECT_POS);
+    if( nCnt )
+    {
+        for( sal_uInt16 n = 0; n < nCnt; ++n )
+            if( aTmpArr[n]->GetFmt()->IsInNodesArr() )
+            {
+                SwSectionFmt* pFmt = aTmpArr[n]->GetFmt();
+                lcl_RemoveChildSections(*pFmt);
+                pDoc->DelSectionFmt( pFmt );
+            }
+    }
+}
+void SwXDocumentIndex::dispose(void) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(GetRegisteredIn())
+    {
+        SwSectionFmt*  pSectFmt = GetFmt();
+        pSectFmt->GetDoc()->DeleteTOX( *(SwTOXBaseSection*)pSectFmt->GetSection(), sal_True);
+    }
+    else
+        throw RuntimeException();
+}
+/*-- 15.01.99 15:46:49---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXDocumentIndex::addEventListener(const Reference< XEventListener > & aListener) throw( RuntimeException )
+{
+    if(!GetRegisteredIn())
+        throw RuntimeException();
+    aLstnrCntnr.AddListener(aListener);
+}
+/*-- 15.01.99 15:46:54---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXDocumentIndex::removeEventListener(const Reference< XEventListener > & aListener) throw( RuntimeException )
+{
+    if(!GetRegisteredIn() || !aLstnrCntnr.RemoveListener(aListener))
+        throw RuntimeException();
+}
+/* -----------------30.07.99 11:28-------------------
+
+ --------------------------------------------------*/
+OUString SwXDocumentIndex::getName(void) throw( RuntimeException )
+{
+    SwSectionFmt* pSectionFmt = GetFmt();
+    OUString uRet;
+    if(bIsDescriptor)
+    {
+        uRet = OUString(pProps->GetTOXBase().GetTOXName());
+    }
+    else if(pSectionFmt)
+    {
+        uRet = OUString(pSectionFmt->GetSection()->GetName());
+    }
+    else
+        throw RuntimeException();
+    return uRet;
+}
+/* -----------------30.07.99 11:28-------------------
+
+ --------------------------------------------------*/
+void SwXDocumentIndex::setName(const OUString& rName) throw( RuntimeException )
+{
+    SwSectionFmt* pSectionFmt = GetFmt();
+    String sNewName(rName);
+    sal_Bool bExcept = sal_False;
+    if(!sNewName.Len())
+        bExcept = sal_True;
+    else if(bIsDescriptor)
+    {
+        pProps->GetTOXBase().SetTOXName(sNewName);
+    }
+    else if(!pSectionFmt ||
+        !pSectionFmt->GetDoc()->SetTOXBaseName(
+                *(SwTOXBaseSection*)pSectionFmt->GetSection(), sNewName))
+        bExcept = sal_True;
+
+    if(bExcept)
+        throw RuntimeException();
+}
+
+/******************************************************************
+ * SwXDocumentIndexMark
+ ******************************************************************/
+/* -----------------------------10.03.00 18:02--------------------------------
+
+ ---------------------------------------------------------------------------*/
+const uno::Sequence< sal_Int8 > & SwXDocumentIndexMark::getUnoTunnelId()
+{
+    static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId();
+    return aSeq;
+}
+/* -----------------------------10.03.00 18:04--------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Int64 SAL_CALL SwXDocumentIndexMark::getSomething( const uno::Sequence< sal_Int8 >& rId )
+    throw(RuntimeException)
+{
+    if( rId.getLength() == 16
+        && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+                                        rId.getConstArray(), 16 ) )
+    {
+            return (sal_Int64)this;
+    }
+    return 0;
+}
+
+TYPEINIT1(SwXDocumentIndexMark, SwClient)
+/* -----------------------------06.04.00 15:07--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXDocumentIndexMark::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXDocumentIndexMark");
+}
+/* -----------------------------06.04.00 15:07--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXDocumentIndexMark::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return !rServiceName.compareToAscii("com.sun.star.text.DocumentIndexMark")||
+        !rServiceName.compareToAscii("com.sun.star.text.TextContent");
+}
+/* -----------------------------06.04.00 15:07--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXDocumentIndexMark::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.DocumentIndexMark");
+    pArray[1] = C2U("com.sun.star.text.TextContent");
+    return aRet;
+}
+/*-- 14.12.98 10:25:43---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXDocumentIndexMark::SwXDocumentIndexMark(TOXTypes eToxType) :
+    m_pDoc(0),
+    aLstnrCntnr( (text::XTextContent*)this),
+    m_pTOXMark(0),
+    nLevel(USHRT_MAX),
+    eType(eToxType),
+    bIsDescriptor(sal_True)
+{
+    InitMap(eToxType);
+}
+/*-- 14.12.98 10:25:44---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXDocumentIndexMark::SwXDocumentIndexMark(const SwTOXType* pType,
+                                    const SwTOXMark* pMark,
+                                    SwDoc* pDc) :
+    SwClient((SwTOXType*)pType),
+    aLstnrCntnr( (text::XTextContent*)this),
+    m_pDoc(pDc),
+    m_pTOXMark(pMark),
+    nLevel(USHRT_MAX),
+    eType(pType->GetType()),
+    bIsDescriptor(sal_False)
+{
+    InitMap(eType);
+}
+/*-- 14.12.98 10:25:44---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXDocumentIndexMark::~SwXDocumentIndexMark()
+{
+
+}
+/* -----------------21.04.99 09:36-------------------
+ *
+ * --------------------------------------------------*/
+void SwXDocumentIndexMark::InitMap(TOXTypes eToxType)
+{
+    sal_uInt16 nMapId = PROPERTY_MAP_USER_MARK; //case TOX_USER:
+    switch( eToxType )
+    {
+        case TOX_INDEX:
+            nMapId = PROPERTY_MAP_INDEX_MARK ;
+        break;
+        case TOX_CONTENT:
+            nMapId = PROPERTY_MAP_CNTIDX_MARK;
+        break;
+        //case TOX_USER:
+    }
+    _pMap = aSwMapProvider.GetPropertyMap(nMapId);
+}
+/*-- 14.12.98 10:25:45---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+OUString SwXDocumentIndexMark::getMarkEntry(void) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwTOXType* pType = ((SwXDocumentIndexMark*)this)->GetTOXType();
+    OUString sRet;
+    if(pType)
+    {
+        SwTOXMark* pCurMark = lcl_GetMark(pType, GetTOXMark());
+        SwTOXMark aMark(*pCurMark);
+        sRet = OUString(aMark.GetAlternativeText());
+    }
+    else if(bIsDescriptor)
+         sRet = sAltText;
+    else
+        throw RuntimeException();
+    return sRet;
+}
+/*-- 14.12.98 10:25:45---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXDocumentIndexMark::setMarkEntry(const OUString& rIndexEntry) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwTOXType* pType = ((SwXDocumentIndexMark*)this)->GetTOXType();
+    if(pType)
+    {
+        SwTOXMark* pCurMark = lcl_GetMark(pType, GetTOXMark());
+        SwTOXMark aMark(*pCurMark);
+        aMark.SetAlternativeText(rIndexEntry);
+        SwTxtTOXMark* pTxtMark = pCurMark->GetTxtTOXMark();
+        SwPaM aPam(pTxtMark->GetTxtNode(), *pTxtMark->GetStart());
+        aPam.SetMark();
+        if(pTxtMark->GetEnd())
+        {
+            aPam.GetPoint()->nContent = *pTxtMark->GetEnd();
+        }
+        else
+            aPam.GetPoint()->nContent++;
+
+        //die alte Marke loeschen
+        m_pDoc->Delete(pCurMark);
+        m_pTOXMark = pCurMark = 0;
+
+        sal_Bool bInsAtPos = aMark.IsAlternativeText();
+        const SwPosition *pStt = aPam.Start(),
+                            *pEnd = aPam.End();
+        SwUnoCrsr* pCrsr = 0;
+        if( bInsAtPos )
+        {
+            SwPaM aTmp( *pStt );
+            m_pDoc->Insert( aTmp, aMark, 0 );
+            pCrsr = m_pDoc->CreateUnoCrsr( *aTmp.Start() );
+            pCrsr->Left(1);
+        }
+        else if( *pEnd != *pStt )
+        {
+            m_pDoc->Insert( aPam, aMark, SETATTR_DONTEXPAND );
+            pCrsr = m_pDoc->CreateUnoCrsr( *aPam.Start() );
+        }
+        //und sonst - Marke geloescht?
+
+        if(pCrsr)
+        {
+            SwTxtAttr* pTxtAttr = pCrsr->GetNode()->GetTxtNode()->GetTxtAttr(
+                        pCrsr->GetPoint()->nContent, RES_TXTATR_TOXMARK);
+            if(pTxtAttr)
+                m_pTOXMark = &pTxtAttr->GetTOXMark();
+        }
+    }
+    else if(bIsDescriptor)
+    {
+        sAltText = rIndexEntry;
+    }
+    else
+        throw RuntimeException();
+}
+/* -----------------18.02.99 13:40-------------------
+ *
+ * --------------------------------------------------*/
+void SwXDocumentIndexMark::attachToRange(const Reference< text::XTextRange > & xTextRange)
+                throw( IllegalArgumentException, RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!bIsDescriptor)
+        throw RuntimeException();
+
+    Reference xRangeTunnel( xTextRange, uno::UNO_QUERY);
+    SwXTextRange* pRange = 0;
+    SwXTextCursor* pCursor = 0;
+    if(xRangeTunnel.is())
+    {
+        pRange = (SwXTextRange*)xRangeTunnel->getSomething(
+                                SwXTextRange::getUnoTunnelId());
+        pCursor = (SwXTextCursor*)xRangeTunnel->getSomething(
+                                SwXTextCursor::getUnoTunnelId());
+    }
+
+    SwDoc* pDoc = pRange ? (SwDoc*)pRange->GetDoc() : pCursor ? (SwDoc*)pCursor->GetDoc() : 0;
+
+    if(pDoc )
+    {
+        const SwTOXType* pTOXType = 0;
+        switch(eType)
+        {
+            case TOX_INDEX:
+            case TOX_CONTENT:
+                pTOXType = pDoc->GetTOXType( eType, 0 );
+            break;
+            case TOX_USER:
+            {
+                if(!sUserIndexName.Len())
+                    pTOXType = pDoc->GetTOXType( eType, 0 );
+                else
+                {
+                    sal_uInt16 nCount = pDoc->GetTOXTypeCount( eType);
+                    for(sal_uInt16 i = 0; i < nCount; i++)
+                    {
+                        const SwTOXType* pTemp = pDoc->GetTOXType( eType, i );
+                        if(sUserIndexName == pTemp->GetTypeName())
+                        {
+                            pTOXType = pTemp;
+                            break;
+                        }
+                    }
+                }
+            }
+            break;
+        }
+        if(!pTOXType)
+            throw IllegalArgumentException();
+        ((SwTOXType*)pTOXType)->Add(this);
+
+        SwUnoInternalPaM aPam(*pDoc);
+        //das muss jetzt sal_True liefern
+        SwXTextRange::XTextRangeToSwPaM(aPam, xTextRange);
+        SwTOXMark* pMark = new SwTOXMark(pTOXType);
+        if(sAltText.Len())
+            pMark->SetAlternativeText(sAltText);
+        switch(eType)
+        {
+            case TOX_INDEX:
+                if(sPrimaryKey.Len())
+                    pMark->SetPrimaryKey(sPrimaryKey);
+                if(sSecondaryKey.Len())
+                    pMark->SetSecondaryKey(sSecondaryKey);
+            break;
+            case TOX_CONTENT:
+                if(USHRT_MAX != nLevel)
+                    pMark->SetLevel(nLevel);
+            break;
+        }
+        UnoActionContext aAction(pDoc);
+        sal_Bool bMark = *aPam.GetPoint() != *aPam.GetMark();
+        // Marks ohne Alternativtext ohne selektierten Text koennen nicht eingefuegt werden,
+        // deshalb hier ein Leerzeichen - ob das die ideale Loesung ist?
+        if(!bMark && !pMark->GetAlternativeText().Len())
+            pMark->SetAlternativeText(String::CreateFromAscii(" "));
+        pDoc->Insert(aPam, *pMark, SETATTR_DONTEXPAND);
+        if(bMark && *aPam.GetPoint() > *aPam.GetMark())
+            aPam.Exchange();
+        SwUnoCrsr* pCrsr = pDoc->CreateUnoCrsr( *aPam.Start() );
+        if(!bMark)
+        {
+            pCrsr->SetMark();
+            pCrsr->Left(1);
+        }
+        SwTxtAttr* pTxtAttr = pCrsr->GetNode()->GetTxtNode()->GetTxtAttr(
+                        pCrsr->GetPoint()->nContent, RES_TXTATR_TOXMARK);
+        delete pCrsr;
+        if(pTxtAttr)
+        {
+            m_pTOXMark = &pTxtAttr->GetTOXMark();
+            m_pDoc = pDoc;
+            bIsDescriptor = sal_False;
+        }
+        else
+            throw RuntimeException();
+    }
+}
+/*-- 14.12.98 10:25:45---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXDocumentIndexMark::attach(const Reference< text::XTextRange > & xTextRange)
+                throw( IllegalArgumentException, RuntimeException )
+{
+}
+/*-- 14.12.98 10:25:45---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Reference< text::XTextRange >  SwXDocumentIndexMark::getAnchor(void) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    Reference< text::XTextRange >  aRet;
+    SwTOXType* pType = ((SwXDocumentIndexMark*)this)->GetTOXType();
+    if(pType)
+    {
+        SwTOXMark* pCurMark = lcl_GetMark(pType, GetTOXMark());
+        if(pCurMark && pCurMark->GetTxtTOXMark())
+        {
+            SwTxtTOXMark* pTxtMark = pCurMark->GetTxtTOXMark();
+            SwPaM aPam(pTxtMark->GetTxtNode(), *pTxtMark->GetStart());
+            aPam.SetMark();
+            if(pTxtMark->GetEnd())
+            {
+                aPam.GetPoint()->nContent = *pTxtMark->GetEnd();
+            }
+            else
+                aPam.GetPoint()->nContent++;
+            Reference< frame::XModel >  xModel = m_pDoc->GetDocShell()->GetBaseModel();
+            Reference< text::XTextDocument > xTDoc(xModel, uno::UNO_QUERY);
+            aRet = new SwXTextRange(aPam, xTDoc->getText());
+        }
+    }
+    if(!aRet.is())
+        throw RuntimeException();
+    return aRet;
+}
+/*-- 14.12.98 10:25:45---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXDocumentIndexMark::dispose(void) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwTOXType* pType = ((SwXDocumentIndexMark*)this)->GetTOXType();
+    if(pType)
+    {
+        SwTOXMark* pTMark = lcl_GetMark(pType, GetTOXMark());
+        m_pDoc->Delete(pTMark);
+    }
+    else
+        throw RuntimeException();
+}
+/*-- 14.12.98 10:25:45---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXDocumentIndexMark::addEventListener(const Reference< XEventListener > & aListener)
+    throw( RuntimeException )
+{
+    if(!GetRegisteredIn())
+        throw RuntimeException();
+    aLstnrCntnr.AddListener(aListener);
+}
+/*-- 14.12.98 10:25:46---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXDocumentIndexMark::removeEventListener(const Reference< XEventListener > & aListener)
+    throw( RuntimeException )
+{
+    if(!GetRegisteredIn() || !aLstnrCntnr.RemoveListener(aListener))
+        throw RuntimeException();
+}
+/*-- 14.12.98 10:25:46---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Reference< XPropertySetInfo >  SwXDocumentIndexMark::getPropertySetInfo(void)
+    throw( RuntimeException )
+{
+    uno::Reference< beans::XPropertySetInfo >  xInfo = new SfxItemPropertySetInfo(_pMap);
+    // extend PropertySetInfo!
+    const uno::Sequence aPropSeq = xInfo->getProperties();
+    Reference< XPropertySetInfo >  xRef = new SfxExtItemPropertySetInfo(
+        aSwMapProvider.GetPropertyMap(PROPERTY_MAP_PARAGRAPH_EXTENSIONS),
+        aPropSeq );
+    return xRef;
+}
+/*-- 14.12.98 10:25:46---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXDocumentIndexMark::setPropertyValue(const OUString& rPropertyName,
+                                            const uno::Any& aValue)
+    throw( UnknownPropertyException, PropertyVetoException,
+        IllegalArgumentException, WrappedTargetException, RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwTOXType* pType = ((SwXDocumentIndexMark*)this)->GetTOXType();
+    const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                                                        _pMap, rPropertyName);
+    if(!pMap)
+        throw UnknownPropertyException();
+    if(pMap->nFlags & PropertyAttribute::READONLY)
+        throw IllegalArgumentException();
+
+    if(pType)
+    {
+        SwTOXMark* pCurMark = lcl_GetMark(pType, GetTOXMark());
+        if(pCurMark)
+        {
+            SwTOXMark aMark(*pCurMark);
+            switch(pMap->nWID)
+            {
+//                  case WID_ALT_TEXT:
+//                      aMark.SetAlternativeText(lcl_AnyToString(aValue));
+//                  break;
+                case WID_LEVEL:
+                    aMark.SetLevel(min(MAXLEVEL, (sal_Int8)lcl_AnyToInt16(aValue)));
+                break;
+                case WID_PRIMARY_KEY  :
+                    aMark.SetPrimaryKey(lcl_AnyToString(aValue));
+                break;
+                case WID_SECONDARY_KEY:
+                    aMark.SetSecondaryKey(lcl_AnyToString(aValue));
+                break;
+            }
+
+            SwTxtTOXMark* pTxtMark = pCurMark->GetTxtTOXMark();
+            SwPaM aPam(pTxtMark->GetTxtNode(), *pTxtMark->GetStart());
+            aPam.SetMark();
+            if(pTxtMark->GetEnd())
+            {
+                aPam.GetPoint()->nContent = *pTxtMark->GetEnd();
+            }
+            else
+                aPam.GetPoint()->nContent++;
+
+            //die alte Marke loeschen
+            m_pDoc->Delete(pCurMark);
+            m_pTOXMark = pCurMark = 0;
+
+            sal_Bool bInsAtPos = aMark.IsAlternativeText();
+            const SwPosition *pStt = aPam.Start(),
+                                *pEnd = aPam.End();
+            SwUnoCrsr* pCrsr = 0;
+            if( bInsAtPos )
+            {
+                SwPaM aTmp( *pStt );
+                m_pDoc->Insert( aTmp, aMark, 0 );
+                pCrsr = m_pDoc->CreateUnoCrsr( *aTmp.Start() );
+                pCrsr->Left(1);
+            }
+            else if( *pEnd != *pStt )
+            {
+                m_pDoc->Insert( aPam, aMark, SETATTR_DONTEXPAND );
+                pCrsr = m_pDoc->CreateUnoCrsr( *aPam.Start() );
+            }
+            //und sonst - Marke geloescht?
+
+            if(pCrsr)
+            {
+                SwTxtAttr* pTxtAttr = pCrsr->GetNode()->GetTxtNode()->GetTxtAttr(
+                            pCrsr->GetPoint()->nContent, RES_TXTATR_TOXMARK);
+                if(pTxtAttr)
+                    m_pTOXMark = &pTxtAttr->GetTOXMark();
+            }
+        }
+    }
+    else if(bIsDescriptor)
+    {
+        switch(pMap->nWID)
+        {
+            case WID_ALT_TEXT:
+                sAltText = lcl_AnyToString(aValue);
+            break;
+            case WID_LEVEL:
+            {
+                sal_uInt16 nVal = lcl_AnyToInt16(aValue);
+                if(nVal >= 0 && nVal < MAXLEVEL)
+                    nLevel = nVal;
+                else
+                    throw IllegalArgumentException();
+            }
+            break;
+            case WID_PRIMARY_KEY  :
+                sPrimaryKey = lcl_AnyToString(aValue);
+            break;
+            case WID_SECONDARY_KEY:
+                sSecondaryKey = lcl_AnyToString(aValue);
+            break;
+            case WID_USER_IDX_NAME :
+                sUserIndexName = lcl_AnyToString(aValue);
+            break;
+        }
+    }
+    else
+        throw RuntimeException();
+}
+/*-- 14.12.98 10:25:46---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXDocumentIndexMark::getPropertyValue(const OUString& rPropertyName)
+    throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Any aRet;
+    SwTOXType* pType = ((SwXDocumentIndexMark*)this)->GetTOXType();
+    const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                                                        _pMap, rPropertyName);
+
+    if(!pMap)
+        throw UnknownPropertyException();
+     if(SwXParagraph::getDefaultTextContentValue(aRet, rPropertyName, pMap->nWID))
+        return aRet;
+    if(pType)
+    {
+        SwTOXMark* pCurMark = lcl_GetMark(pType, GetTOXMark());
+        if(pCurMark)
+        {
+            switch(pMap->nWID)
+            {
+                case WID_ALT_TEXT:
+                    aRet <<= OUString(pCurMark->GetAlternativeText());
+                break;
+                case WID_LEVEL:
+                    aRet <<= (sal_Int16)pCurMark->GetLevel();
+                break;
+                case WID_PRIMARY_KEY  :
+                    aRet <<= OUString(pCurMark->GetPrimaryKey());
+                break;
+                case WID_SECONDARY_KEY:
+                    aRet <<= OUString(pCurMark->GetSecondaryKey());
+                break;
+                case WID_USER_IDX_NAME :
+                    aRet <<= OUString(pType->GetTypeName());
+                break;
+            }
+        }
+    }
+    else if(bIsDescriptor)
+    {
+        switch(pMap->nWID)
+        {
+            case WID_ALT_TEXT:
+                aRet <<= OUString(sAltText);
+            break;
+            case WID_LEVEL:
+                aRet <<= (sal_Int16)nLevel;
+            break;
+            case WID_PRIMARY_KEY  :
+                aRet <<= OUString(sPrimaryKey);
+            break;
+            case WID_SECONDARY_KEY:
+                aRet <<= OUString(sSecondaryKey);
+            break;
+            case WID_USER_IDX_NAME :
+                aRet <<= OUString(sUserIndexName);
+            break;
+        }
+    }
+    else
+        throw RuntimeException();
+    return aRet;
+}
+/*-- 14.12.98 10:25:46---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXDocumentIndexMark::addPropertyChangeListener(const OUString& PropertyName, const Reference< XPropertyChangeListener > & aListener) throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 14.12.98 10:25:46---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXDocumentIndexMark::removePropertyChangeListener(const OUString& PropertyName, const Reference< XPropertyChangeListener > & aListener) throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 14.12.98 10:25:47---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXDocumentIndexMark::addVetoableChangeListener(const OUString& PropertyName, const Reference< XVetoableChangeListener > & aListener) throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 14.12.98 10:25:47---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXDocumentIndexMark::removeVetoableChangeListener(const OUString& PropertyName, const Reference< XVetoableChangeListener > & aListener) throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 14.12.98 10:25:47---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXDocumentIndexMark*   SwXDocumentIndexMark::GetObject(SwTOXType* pType,
+                                    const SwTOXMark* pMark, SwDoc* pDoc)
+{
+    SwClientIter aIter(*pType);
+    SwXDocumentIndexMark* pxMark = (SwXDocumentIndexMark*)
+                                            aIter.First(TYPE(SwXDocumentIndexMark));
+    while( pxMark )
+    {
+        if(pxMark->GetTOXMark() == pMark)
+            return pxMark;
+        pxMark = (SwXDocumentIndexMark*)aIter.Next();
+    }
+    return new SwXDocumentIndexMark(pType, pMark, pDoc);
+}
+/*-- 14.12.98 10:25:47---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXDocumentIndexMark::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew)
+{
+    ClientModify(this, pOld, pNew);
+    if(!GetRegisteredIn())
+        aLstnrCntnr.Disposing();
+}
+/* -----------------------------06.04.00 15:08--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXDocumentIndexes::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXDocumentIndexes");
+}
+/* -----------------------------06.04.00 15:08--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXDocumentIndexes::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.text.DocumentIndexes") == rServiceName;
+}
+/* -----------------------------06.04.00 15:08--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXDocumentIndexes::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.DocumentIndexes");
+    return aRet;
+}
+/*-- 05.05.99 13:14:59---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXDocumentIndexes::SwXDocumentIndexes(SwDoc* pDoc) :
+    SwUnoCollection(pDoc)
+{
+}
+/*-- 05.05.99 13:15:00---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXDocumentIndexes::~SwXDocumentIndexes()
+{
+}
+/*-- 05.05.99 13:15:01---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Int32 SwXDocumentIndexes::getCount(void) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!IsValid())
+        throw RuntimeException();
+
+    sal_uInt32 nRet = 0;
+    const SwSectionFmts& rFmts = GetDoc()->GetSections();
+    for( sal_uInt16 n = 0; n < rFmts.Count(); ++n )
+    {
+        const SwSection* pSect = rFmts[ n ]->GetSection();
+        if( TOX_CONTENT_SECTION == pSect->GetType() &&
+            pSect->GetFmt()->GetSectionNode() )
+            ++nRet;
+    }
+    return nRet;
+}
+/*-- 05.05.99 13:15:01---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXDocumentIndexes::getByIndex(sal_Int32 nIndex)
+    throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!IsValid())
+        throw RuntimeException();
+
+    uno::Any aRet;
+    sal_uInt32 nIdx = 0;
+
+    const SwSectionFmts& rFmts = GetDoc()->GetSections();
+    for( sal_uInt16 n = 0, nCnt = 0; n < rFmts.Count(); ++n )
+    {
+        const SwSection* pSect = rFmts[ n ]->GetSection();
+        if( TOX_CONTENT_SECTION == pSect->GetType() &&
+            pSect->GetFmt()->GetSectionNode() &&
+            nIdx++ == nIndex )
+            {
+               Reference< text::XDocumentIndex >  xTmp = new SwXDocumentIndex(
+                                    (SwTOXBaseSection*)pSect, GetDoc() );
+               aRet.setValue(&xTmp, ::getCppuType((Reference*)0));
+               return aRet;
+            }
+    }
+
+    throw IndexOutOfBoundsException();
+    return aRet;
+}
+
+/*-- 31.01.00 10:12:31---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXDocumentIndexes::getByName(const OUString& rName)
+    throw( container::NoSuchElementException, WrappedTargetException, RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!IsValid())
+        throw RuntimeException();
+
+    uno::Any aRet;
+    sal_uInt32 nIdx = 0;
+
+    String sToFind(rName);
+    const SwSectionFmts& rFmts = GetDoc()->GetSections();
+    for( sal_uInt16 n = 0, nCnt = 0; n < rFmts.Count(); ++n )
+    {
+        const SwSection* pSect = rFmts[ n ]->GetSection();
+        if( TOX_CONTENT_SECTION == pSect->GetType() &&
+            pSect->GetFmt()->GetSectionNode() &&
+                ((SwTOXBaseSection*)pSect)->GetTOXName() == sToFind)
+            {
+               Reference< text::XDocumentIndex >  xTmp = new SwXDocumentIndex(
+                                    (SwTOXBaseSection*)pSect, GetDoc() );
+               aRet.setValue(&xTmp, ::getCppuType((Reference*)0));
+               return aRet;
+            }
+    }
+    throw container::NoSuchElementException();
+    return aRet;
+}
+/*-- 31.01.00 10:12:31---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Sequence< OUString > SwXDocumentIndexes::getElementNames(void)
+    throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!IsValid())
+        throw RuntimeException();
+
+    const SwSectionFmts& rFmts = GetDoc()->GetSections();
+    sal_Int32 nCount = 0;
+    sal_uInt16 n;
+    for( n = 0; n < rFmts.Count(); ++n )
+    {
+        const SwSection* pSect = rFmts[ n ]->GetSection();
+        if( TOX_CONTENT_SECTION == pSect->GetType() &&
+            pSect->GetFmt()->GetSectionNode() )
+            ++nCount;
+    }
+
+    uno::Sequence< OUString > aRet(nCount);
+    OUString* pArray = aRet.getArray();
+    sal_uInt16 nCnt;
+    for( n = 0, nCnt = 0; n < rFmts.Count(); ++n )
+    {
+        const SwSection* pSect = rFmts[ n ]->GetSection();
+        if( TOX_CONTENT_SECTION == pSect->GetType() &&
+            pSect->GetFmt()->GetSectionNode())
+        {
+            pArray[nCnt++] = OUString(((SwTOXBaseSection*)pSect)->GetTOXName());
+        }
+    }
+    return aRet;
+}
+/*-- 31.01.00 10:12:31---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXDocumentIndexes::hasByName(const OUString& rName)
+    throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!IsValid())
+        throw RuntimeException();
+
+    String sToFind(rName);
+    const SwSectionFmts& rFmts = GetDoc()->GetSections();
+    for( sal_uInt16 n = 0, nCnt = 0; n < rFmts.Count(); ++n )
+    {
+        const SwSection* pSect = rFmts[ n ]->GetSection();
+        if( TOX_CONTENT_SECTION == pSect->GetType() &&
+            pSect->GetFmt()->GetSectionNode())
+        {
+            if(((SwTOXBaseSection*)pSect)->GetTOXName() == sToFind)
+                return sal_True;
+        }
+    }
+    return sal_False;
+}
+/*-- 05.05.99 13:15:01---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Type SwXDocumentIndexes::getElementType(void) throw( RuntimeException )
+{
+    return ::getCppuType((Reference< text::XDocumentIndex> *)0);
+}
+/*-- 05.05.99 13:15:02---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXDocumentIndexes::hasElements(void) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!IsValid())
+        throw RuntimeException();
+    return 0 != getCount();
+}
+
+/* -----------------------------06.04.00 15:08--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXIndexStyleAccess_Impl::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXIndexStyleAccess_Impl");
+}
+/* -----------------------------06.04.00 15:08--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXIndexStyleAccess_Impl::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.text.DocumentIndexParagraphStyles") == rServiceName;
+}
+/* -----------------------------06.04.00 15:08--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXIndexStyleAccess_Impl::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.DocumentIndexParagraphStyles");
+    return aRet;
+}
+/*-- 13.09.99 16:52:28---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXIndexStyleAccess_Impl::SwXIndexStyleAccess_Impl(SwXDocumentIndex& rParentIdx) :
+    rParent(rParentIdx),
+    xParent(&rParentIdx)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    rParent.SetStyleAccess(this);
+}
+/*-- 13.09.99 16:52:29---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXIndexStyleAccess_Impl::~SwXIndexStyleAccess_Impl()
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    rParent.SetStyleAccess(0);
+}
+/*-- 13.09.99 16:52:29---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXIndexStyleAccess_Impl::replaceByIndex(sal_Int32 nIndex, const uno::Any& rElement)
+    throw( IllegalArgumentException, IndexOutOfBoundsException,
+          WrappedTargetException, RuntimeException)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    const sal_Bool bDescriptor = rParent.IsDescriptor();
+    SwSectionFmt* pSectFmt = rParent.GetFmt();
+    if(!pSectFmt && !bDescriptor)
+        throw RuntimeException();
+    if(nIndex < 0 || nIndex > MAXLEVEL)
+        throw IndexOutOfBoundsException();
+    SwTOXBase* pTOXBase = bDescriptor ? &rParent.GetProperties_Impl()->GetTOXBase() :
+            (SwTOXBaseSection*)pSectFmt->GetSection();
+    if(rElement.getValueType() != ::getCppuType((uno::Sequence*)0))
+        throw IllegalArgumentException();
+    const uno::Sequence* pSeq = (const uno::Sequence*)rElement.getValue();
+
+    sal_uInt16 nStyles = pSeq->getLength();
+    const OUString* pStyles = pSeq->getConstArray();
+    String sSetStyles;
+    for(sal_uInt16 i = 0; i < nStyles; i++)
+    {
+        if(i)
+            sSetStyles += TOX_STYLE_DELIMITER;
+        sSetStyles += String(pStyles[i]);
+    }
+    pTOXBase->SetStyleNames(sSetStyles, (sal_uInt16) nIndex);
+}
+/*-- 13.09.99 16:52:29---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Int32 SwXIndexStyleAccess_Impl::getCount(void) throw( RuntimeException )
+{
+    return MAXLEVEL;
+}
+/*-- 13.09.99 16:52:30---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXIndexStyleAccess_Impl::getByIndex(sal_Int32 nIndex)
+    throw( IndexOutOfBoundsException, WrappedTargetException,
+                 RuntimeException)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    const sal_Bool bDescriptor = rParent.IsDescriptor();
+    SwSectionFmt* pSectFmt = rParent.GetFmt();
+    if(!pSectFmt && !bDescriptor)
+        throw RuntimeException();
+    if(nIndex < 0 || nIndex > MAXLEVEL)
+        throw IndexOutOfBoundsException();
+    SwTOXBase* pTOXBase = bDescriptor ? &rParent.GetProperties_Impl()->GetTOXBase() :
+                (SwTOXBaseSection*)pSectFmt->GetSection();
+
+    const String& rStyles = pTOXBase->GetStyleNames((sal_uInt16) nIndex);
+    sal_uInt16 nStyles = rStyles.GetTokenCount(TOX_STYLE_DELIMITER);
+    uno::Sequence aStyles(nStyles);
+    OUString* pStyles = aStyles.getArray();
+    for(sal_uInt16 i = 0; i < nStyles; i++)
+    {
+        pStyles[i] = OUString(rStyles.GetToken(i, TOX_STYLE_DELIMITER));
+    }
+    uno::Any aRet(&aStyles, ::getCppuType((uno::Sequence*)0));
+    return aRet;
+}
+/*-- 13.09.99 16:52:30---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Type SwXIndexStyleAccess_Impl::getElementType(void)
+    throw( RuntimeException )
+{
+    return ::getCppuType((uno::Sequence*)0);
+}
+/*-- 13.09.99 16:52:30---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXIndexStyleAccess_Impl::hasElements(void) throw( RuntimeException )
+{
+    return sal_True;
+}
+
+/* -----------------13.09.99 16:51-------------------
+
+ --------------------------------------------------*/
+/* -----------------------------06.04.00 15:08--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXIndexTokenAccess_Impl::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXIndexTokenAccess_Impl");
+}
+/* -----------------------------06.04.00 15:08--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXIndexTokenAccess_Impl::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.text.DocumentIndexLevelFormat") == rServiceName;
+}
+/* -----------------------------06.04.00 15:08--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXIndexTokenAccess_Impl::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.DocumentIndexLevelFormat");
+    return aRet;
+}
+/*-- 13.09.99 16:52:28---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXIndexTokenAccess_Impl::SwXIndexTokenAccess_Impl(SwXDocumentIndex& rParentIdx) :
+    rParent(rParentIdx),
+    xParent(&rParentIdx),
+    nCount(SwForm::GetFormMaxLevel(rParent.GetTOXType()))
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    rParent.SetTokenAccess(this);
+}
+/*-- 13.09.99 16:52:29---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXIndexTokenAccess_Impl::~SwXIndexTokenAccess_Impl()
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    rParent.SetTokenAccess(0);
+}
+/*-- 13.09.99 16:52:29---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXIndexTokenAccess_Impl::replaceByIndex(sal_Int32 nIndex, const uno::Any& rElement)
+    throw( IllegalArgumentException, IndexOutOfBoundsException,
+            WrappedTargetException, RuntimeException)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    const sal_Bool bDescriptor = rParent.IsDescriptor();
+    SwSectionFmt* pSectFmt = rParent.GetFmt();
+    if(!pSectFmt && !bDescriptor)
+        throw RuntimeException();
+
+    SwTOXBase* pTOXBase = bDescriptor ? &rParent.GetProperties_Impl()->GetTOXBase() :
+                            (SwTOXBaseSection*)pSectFmt->GetSection();
+    if(nIndex < 0 ||
+        (nIndex > pTOXBase->GetTOXForm().GetFormMax()))
+            throw IndexOutOfBoundsException();
+    if(rElement.getValueType() != ::getCppuType((uno::Sequence*)0))
+        throw IllegalArgumentException();
+    const uno::Sequence* pSeq = (uno::Sequence* )rElement.getValue();
+
+    String sPattern;
+    sal_uInt16 nTokens = pSeq->getLength();
+    const PropertyValues* pTokens = pSeq->getConstArray();
+    for(sal_uInt16 i = 0; i < nTokens; i++)
+    {
+        const PropertyValue* pProperties = pTokens[i].getConstArray();
+        sal_uInt16 nProperties = pTokens[i].getLength();
+        //create an invalid token
+        SwFormToken aToken(TOKEN_END);
+        for(sal_uInt16 j = 0; j < nProperties; j++)
+        {
+            if( COMPARE_EQUAL == pProperties[j].Name.compareToAscii("TokenType"))
+            {
+                const String sTokenType =
+                        lcl_AnyToString(pProperties[j].Value);
+                if(COMPARE_EQUAL == sTokenType.CompareToAscii("TokenEntryNumber"))
+                    aToken.eTokenType = TOKEN_ENTRY_NO;
+                else if(COMPARE_EQUAL == sTokenType.CompareToAscii("TokenEntryText" ))
+                    aToken.eTokenType = TOKEN_ENTRY_TEXT;
+                else if(COMPARE_EQUAL == sTokenType.CompareToAscii("TokenTabStop"   ))
+                    aToken.eTokenType = TOKEN_TAB_STOP;
+                else if(COMPARE_EQUAL == sTokenType.CompareToAscii("TokenText"      ))
+                    aToken.eTokenType = TOKEN_TEXT;
+                else if(COMPARE_EQUAL == sTokenType.CompareToAscii("TokenPageNumber"))
+                    aToken.eTokenType = TOKEN_PAGE_NUMS;
+                else if(COMPARE_EQUAL == sTokenType.CompareToAscii("TokenChapterInfo"      ))
+                    aToken.eTokenType = TOKEN_CHAPTER_INFO;
+                else if(COMPARE_EQUAL == sTokenType.CompareToAscii("TokenHyperlinkStart" ))
+                    aToken.eTokenType = TOKEN_LINK_START;
+                else if(COMPARE_EQUAL == sTokenType.CompareToAscii("TokenHyperlinkEnd"))
+                    aToken.eTokenType = TOKEN_LINK_END;
+                else if(COMPARE_EQUAL == sTokenType.CompareToAscii("TokenBibliographyDataField" ))
+                    aToken.eTokenType = TOKEN_AUTHORITY;
+            }
+            else if( COMPARE_EQUAL == pProperties[j].Name.compareToAscii("CharacterStyleName"  )  )
+            {
+                const String sCharStyleName =
+                    lcl_AnyToString(pProperties[j].Value);
+                aToken.sCharStyleName = sCharStyleName;
+                aToken.nPoolId = pSectFmt->GetDoc()->
+                            GetPoolId( sCharStyleName, GET_POOLID_CHRFMT );
+            }
+            else if( COMPARE_EQUAL == pProperties[j].Name.compareToAscii("TabStopRightAligned") )
+            {
+                sal_Bool bRight = lcl_AnyToBool(pProperties[j].Value);
+                aToken.eTabAlign = bRight ?
+                                    SVX_TAB_ADJUST_END : SVX_TAB_ADJUST_LEFT;
+            }
+            else if( COMPARE_EQUAL == pProperties[j].Name.compareToAscii("TabStopPosition"  ))
+            {
+                sal_Int32 nPosition;
+                if(pProperties[j].Value.getValueType() != ::getCppuType((sal_Int32*)0))
+                    throw IllegalArgumentException();
+                pProperties[j].Value >>= nPosition;
+                nPosition = MM100_TO_TWIP(nPosition);
+                if(nPosition < 0)
+                    throw IllegalArgumentException();
+                aToken.nTabStopPosition = nPosition;
+            }
+            else if( COMPARE_EQUAL == pProperties[j].Name.compareToAscii("TabStopFillCharacter" ))
+            {
+                const String sFillChar =
+                    lcl_AnyToString(pProperties[j].Value);
+                if(sFillChar.Len() > 1)
+                    throw IllegalArgumentException();
+                aToken.cTabFillChar = sFillChar.Len() ?
+                                sFillChar.GetChar(0) : ' ';
+            }
+
+            else if( COMPARE_EQUAL == pProperties[j].Name.compareToAscii("Text" ))
+               {
+                const String sText =
+                    lcl_AnyToString(pProperties[j].Value);
+                aToken.sText = sText;
+            }
+            else if( COMPARE_EQUAL == pProperties[j].Name.compareToAscii("ChapterFormat"    ))
+            {
+                sal_Int16 nFormat = lcl_AnyToInt16(pProperties[j].Value);
+                switch(nFormat)
+                {
+                    case text::ChapterFormat::NUMBER:           nFormat = CF_NUMBER;
+                    break;
+                    case text::ChapterFormat::NAME:             nFormat = CF_TITLE;
+                    break;
+                    case text::ChapterFormat::NAME_NUMBER:      nFormat = CF_NUM_TITLE;
+                    break;
+                    case text::ChapterFormat::NO_PREFIX_SUFFIX:nFormat = CF_NUMBER_NOPREPST;
+                    break;
+                    case text::ChapterFormat::DIGIT:           nFormat = CF_NUM_NOPREPST_TITLE;
+                    break;
+                    default:
+                        throw IllegalArgumentException();
+                }
+                aToken.nChapterFormat = nFormat;
+            }
+        }
+        //exception if wrong TokenType
+        if(TOKEN_END <= aToken.eTokenType )
+            throw IllegalArgumentException();
+        // set TokenType from TOKEN_ENTRY_TEXT to TOKEN_ENTRY if it is
+        // not a content index
+        if(TOKEN_ENTRY_TEXT == aToken.eTokenType &&
+            ((TOX_CONTENT != pTOXBase->GetType())) ||
+            TOKEN_ENTRY == aToken.eTokenType)
+            sPattern += aToken.GetString();
+    }
+    SwForm aForm(pTOXBase->GetTOXForm());
+    aForm.SetPattern((sal_uInt16) nIndex, sPattern);
+    pTOXBase->SetTOXForm(aForm);
+}
+/*-- 13.09.99 16:52:29---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Int32 SwXIndexTokenAccess_Impl::getCount(void) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    const sal_Bool bDescriptor = rParent.IsDescriptor();
+    SwSectionFmt* pSectFmt = rParent.GetFmt();
+    if(!pSectFmt && !bDescriptor)
+        throw RuntimeException();
+    sal_Int32 nRet = bDescriptor ?
+        nCount :
+        ((SwTOXBaseSection*)pSectFmt->GetSection())->
+                                            GetTOXForm().GetFormMax();
+    return nRet;
+}
+/*-- 13.09.99 16:52:30---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXIndexTokenAccess_Impl::getByIndex(sal_Int32 nIndex)
+    throw( IndexOutOfBoundsException, WrappedTargetException,
+         RuntimeException)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    const sal_Bool bDescriptor = rParent.IsDescriptor();
+    SwSectionFmt* pSectFmt = rParent.GetFmt();
+    if(!pSectFmt && !bDescriptor)
+        throw RuntimeException();
+    SwTOXBase* pTOXBase = bDescriptor ? &rParent.GetProperties_Impl()->GetTOXBase() :
+            (SwTOXBaseSection*)pSectFmt->GetSection();
+    if(nIndex < 0 ||
+    (nIndex > pTOXBase->GetTOXForm().GetFormMax()))
+        throw IndexOutOfBoundsException();
+
+    SwFormTokenEnumerator aEnumerator(pTOXBase->GetTOXForm().
+                                        GetPattern((sal_uInt16) nIndex));
+    sal_uInt16 nTokenCount = 0;
+    uno::Sequence< PropertyValues > aRetSeq;
+    while(aEnumerator.HasNextToken())
+    {
+        nTokenCount++;
+        aRetSeq.realloc(nTokenCount);
+        PropertyValues* pTokenProps = aRetSeq.getArray();
+        SwFormToken  aToken = aEnumerator.GetNextToken();
+        switch(aToken.eTokenType)
+        {
+            case TOKEN_ENTRY_NO     :
+            {
+                pTokenProps->realloc( 2 );
+                PropertyValue* pArr = pTokenProps->getArray();
+
+                pArr[0].Name = C2U("TokenType");
+                pArr[0].Value <<= OUString::createFromAscii("TokenEntryNumber");
+//              pArr[0].Value <<= C2U("TokenEntryNumber");
+
+                pArr[1].Name = C2U("CharacterStyleName");
+                pArr[1].Value <<= OUString(aToken.sCharStyleName);
+            }
+            break;
+            case TOKEN_ENTRY        :   // no difference between Entry and Entry Text
+            case TOKEN_ENTRY_TEXT   :
+            {
+                pTokenProps->realloc( 2 );
+                PropertyValue* pArr = pTokenProps->getArray();
+
+                pArr[0].Name = C2U("TokenType");
+                pArr[0].Value <<= OUString::createFromAscii("TokenEntryText");
+
+                pArr[1].Name = C2U("CharacterStyleName");
+                pArr[1].Value <<= OUString(aToken.sCharStyleName);
+            }
+            break;
+            case TOKEN_TAB_STOP     :
+            {
+                pTokenProps->realloc(3);
+                PropertyValue* pArr = pTokenProps->getArray();
+
+                pArr[0].Name = C2U("TokenType");
+                pArr[0].Value <<= OUString::createFromAscii("TokenTabStop");
+
+
+                if(SVX_TAB_ADJUST_END == aToken.eTabAlign)
+                {
+                    pArr[1].Name = C2U("TabStopRightAligned");
+                    BOOL bTemp = sal_True;
+                    pArr[1].Value.setValue(&bTemp, ::getCppuBooleanType());
+                }
+                else
+                {
+                    pArr[1].Name = C2U("TabStopPosition");
+                    pArr[1].Value <<= (sal_Int32)(TWIP_TO_MM100(aToken.nTabStopPosition));
+                }
+                pArr[2].Name = C2U("TabStopFillCharacter");
+                pArr[2].Value <<= OUString(aToken.cTabFillChar);
+            }
+            break;
+            case TOKEN_TEXT         :
+            {
+                pTokenProps->realloc( 3 );
+                PropertyValue* pArr = pTokenProps->getArray();
+
+                pArr[0].Name = C2U("TokenType");
+                pArr[0].Value <<= OUString::createFromAscii("TokenText");
+
+                pArr[1].Name = C2U("CharacterStyleName");
+                pArr[1].Value <<= OUString(aToken.sCharStyleName);
+
+                pArr[2].Name = C2U("Text");
+                pArr[2].Value <<= OUString(aToken.sText);
+            }
+            break;
+            case TOKEN_PAGE_NUMS    :
+            {
+                pTokenProps->realloc( 2 );
+                PropertyValue* pArr = pTokenProps->getArray();
+
+                pArr[0].Name = C2U("TokenType");
+                pArr[0].Value <<= OUString::createFromAscii("TokenPageNumber");
+
+                pArr[1].Name = C2U("CharacterStyleName");
+                pArr[1].Value <<= OUString(aToken.sCharStyleName);
+            }
+            break;
+            case TOKEN_CHAPTER_INFO :
+            {
+                pTokenProps->realloc( 3 );
+                PropertyValue* pArr = pTokenProps->getArray();
+
+                pArr[0].Name = C2U("TokenType");
+                pArr[0].Value <<= OUString::createFromAscii("TokenChapterInfo");
+
+                pArr[1].Name = C2U("CharacterStyleName");
+                pArr[1].Value <<= OUString(aToken.sCharStyleName);
+
+                pArr[2].Name = C2U("ChapterFormat");
+                sal_Int16 nVal = text::ChapterFormat::NUMBER;
+                switch(aToken.nChapterFormat)
+                {
+                    case CF_NUMBER:             nVal = text::ChapterFormat::NUMBER; break;
+                    case CF_TITLE:              nVal = text::ChapterFormat::NAME; break;
+                    case CF_NUM_TITLE:          nVal = text::ChapterFormat::NAME_NUMBER; break;
+                    case CF_NUMBER_NOPREPST:    nVal = text::ChapterFormat::NO_PREFIX_SUFFIX; break;
+                    case CF_NUM_NOPREPST_TITLE: nVal = text::ChapterFormat::DIGIT; break;
+                }
+                pArr[2].Value <<= (sal_Int16)nVal;
+            }
+            break;
+            case TOKEN_LINK_START   :
+            {
+                pTokenProps->realloc( 1 );
+                PropertyValue* pArr = pTokenProps->getArray();
+
+                pArr[0].Name = C2U("TokenType");
+                pArr[0].Value <<= OUString::createFromAscii("TokenHyperlinkStart");
+            }
+            break;
+            case TOKEN_LINK_END     :
+            {
+                pTokenProps->realloc( 1 );
+                PropertyValue* pArr = pTokenProps->getArray();
+
+                pArr[0].Name = C2U("TokenType");
+                pArr[0].Value <<= OUString::createFromAscii("TokenHyperlinkEnd");
+            }
+            break;
+            case TOKEN_AUTHORITY :
+                pTokenProps->realloc( 1 );
+                PropertyValue* pArr = pTokenProps->getArray();
+
+                pArr[0].Name = C2U("TokenType");
+                pArr[0].Value <<= OUString::createFromAscii("TokenBibliographyDataField");
+                DBG_ERROR("bibliography not implemented")
+            break;
+        }
+    }
+
+    uno::Any aRet(&aRetSeq, ::getCppuType((uno::Sequence< PropertyValues >*)0));
+
+    return aRet;
+}
+/*-- 13.09.99 16:52:30---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Type  SwXIndexTokenAccess_Impl::getElementType(void)
+    throw( RuntimeException )
+{
+    return ::getCppuType((uno::Sequence< PropertyValues >*)0);
+}
+/*-- 13.09.99 16:52:30---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXIndexTokenAccess_Impl::hasElements(void) throw( RuntimeException )
+{
+    return sal_True;
+}
+/*------------------------------------------------------------------------
+
+    $Log: not supported by cvs2svn $
+    Revision 1.66  2000/09/18 16:04:32  willem.vandorp
+    OpenOffice header added.
+
+    Revision 1.65  2000/09/12 11:42:58  os
+    #78682# support of service TextContent
+
+    Revision 1.64  2000/09/07 07:59:10  os
+    #78443# SetMarkEntry now works as desriptor too
+
+    Revision 1.63  2000/08/17 10:08:04  os
+    type of TabStopPosition corrected
+
+    Revision 1.62  2000/08/09 16:05:26  os
+    several new index services
+
+    Revision 1.61  2000/06/29 14:59:05  os
+    SwXDocumentIndex holds a SwTOXBase in its descriptor
+
+    Revision 1.60  2000/05/16 09:14:54  os
+    project usr removed
+
+    Revision 1.59  2000/04/26 11:35:19  os
+    GetName() returns String&
+
+    Revision 1.58  2000/04/11 08:31:03  os
+    UNICODE
+
+    Revision 1.57  2000/03/31 10:26:36  os
+    #74034# getServiceName: comply to documentation
+
+    Revision 1.56  2000/03/27 10:21:10  os
+    UNO III
+
+    Revision 1.55  2000/03/21 15:42:24  os
+    UNOIII
+
+    Revision 1.54  2000/02/28 15:36:40  hjs
+    #65293# include
+
+    Revision 1.53  2000/02/25 14:08:38  os
+    #72990# test script changes
+
+    Revision 1.52  2000/02/23 16:13:05  os
+    #72990# get/setPropertyValue and get/setName work as Descriptor, too
+
+    Revision 1.51  2000/02/14 13:20:14  os
+    #72990# service info added
+
+    Revision 1.50  2000/02/11 14:35:28  hr
+    #70473# changes for unicode ( patched by automated patchtool )
+
+    Revision 1.49  2000/01/31 09:56:01  os
+    #70889# SwXDocumentIndexes inherits container::XNameAccess
+
+    Revision 1.48  2000/01/19 09:23:19  os
+    #71955# setPropertyValues: template names corrected
+
+    Revision 1.47  2000/01/17 15:13:51  os
+    #71955# tab stop position as sal_Int32
+
+    Revision 1.46  1999/12/20 11:07:04  os
+    #70234# set pattern at the correct level
+
+    Revision 1.45  1999/12/09 14:53:02  os
+    #70234# index corrected
+
+    Revision 1.44  1999/12/03 11:10:42  os
+    #70234# wrong assignments corrected
+
+    Revision 1.43  1999/12/01 14:44:23  os
+    #70234# properties added
+
+    Revision 1.42  1999/11/29 15:46:16  os
+    #70234# some index errors corrected
+
+    Revision 1.41  1999/11/25 15:43:26  os
+    headers corrected
+
+    Revision 1.40  1999/11/19 16:40:18  os
+    modules renamed
+
+    Revision 1.39  1999/11/10 14:48:20  os
+    some index properties corrected
+
+    Revision 1.38  1999/09/20 12:49:52  hr
+    #65293#: .is()
+
+    Revision 1.37  1999/09/14 13:29:05  os
+    SwXDocumentIndex completed
+
+    Revision 1.36  1999/09/01 14:18:38  OS
+    new index properties
+
+
+      Rev 1.35   01 Sep 1999 16:18:38   OS
+   new index properties
+
+      Rev 1.34   17 Aug 1999 13:57:54   OS
+   extended indexes: get/set section attributes
+
+      Rev 1.33   30 Jul 1999 14:41:40   OS
+   container::XNamed in SwXDocumentIndex
+
+      Rev 1.32   27 Jul 1999 20:23:42   JP
+   replace class SwTOXBaseRange with SwTOXBaseSection - TOX use now SwSections
+
+      Rev 1.31   05 May 1999 14:07:22   OS
+   #64655# DocumentIndexes wiederbelebt
+
+      Rev 1.30   22 Apr 1999 16:13:42   OS
+   #65194# throw -> throw; #65124# not impl. nur noch warning; EventListener
+
+      Rev 1.29   21 Apr 1999 14:35:52   OS
+   #65098# Verzeichnisse und -eintraege
+
+      Rev 1.28   15 Mar 1999 14:36:40   OS
+   #62845# Makro fuer ServiceInfo jetzt auch fuer OS/2
+
+      Rev 1.27   12 Mar 1999 09:41:12   OS
+   #62845# XServiceInfo impl.
+
+      Rev 1.26   09 Mar 1999 12:41:06   OS
+   #62008# Solar-Mutex
+
+      Rev 1.25   04 Mar 1999 15:03:04   OS
+   #62191# UINT nicht mehr verwenden
+
+      Rev 1.24   18 Feb 1999 14:25:48   OS
+   #52654# insertTextContent statt attach
+
+      Rev 1.23   28 Jan 1999 16:45:06   OS
+   #56371# keine Objekte fuer DEBUG anlegen
+
+      Rev 1.22   22 Jan 1999 15:09:10   OS
+   #56371# Draw wieder verfuegbar
+
+      Rev 1.21   19 Jan 1999 08:04:16   OS
+    #56371# TF_ONE51: Descriptor-interfaces
+
+      Rev 1.20   14 Jan 1999 16:21:50   OS
+   #56371# TF_ONE51
+
+      Rev 1.19   15 Dec 1998 10:10:02   OS
+   #56371# TF_ONE51 Zwischenstand
+
+      Rev 1.18   10 Dec 1998 15:53:14   OS
+   #56371# TF_ONE51 Zwischenstand
+
+      Rev 1.17   17 Sep 1998 09:24:54   OS
+   #52654# IndexMark einfuegen auch ohne Markierung, Properties gerichtet
+
+      Rev 1.16   10 Jul 1998 18:08:30   OS
+   PropertySetInfo und IdlClass static
+
+      Rev 1.15   03 Jul 1998 16:18:00   OS
+   Verzeichnisse nicht verschachteln
+
+      Rev 1.14   26 Jun 1998 18:16:46   OS
+   Maps aus unomap
+
+      Rev 1.13   25 Jun 1998 11:15:54   OS
+   IndexMark::setPropertyValue : auch mit Alternativtext richtig umsetzen
+
+      Rev 1.12   23 Jun 1998 10:24:48   OS
+   Verzeichnisse benutzbar, mit Descriptor
+
+      Rev 1.11   19 Jun 1998 14:46:20   TJ
+   GetModel auskommentiert
+
+      Rev 1.10   17 Jun 1998 16:10:32   MH
+   chg: Syntax OS2
+
+      Rev 1.9   12 Jun 1998 13:49:14   OS
+   Package-Umstellung
+
+      Rev 1.8   04 Jun 1998 12:40:56   OS
+// automatisch auskommentiert - [getIdlClass(es) or queryInterface] - Bitte XTypeProvider benutzen!
+//   getIdlClasses
+
+
+      Rev 1.7   14 May 1998 17:49:40   OS
+   div. Namensaenderungen
+
+      Rev 1.6   13 May 1998 15:29:08   OS
+   TextPosition-Auswertung verbessert
+
+      Rev 1.5   06 May 1998 17:06:22   OS
+   XTextPosition ohne Doc anlegen
+
+      Rev 1.4   09 Apr 1998 15:10:52   OS
+   Uno-Umstellung
+
+      Rev 1.3   07 Apr 1998 14:09:42   OS
+   Properties der Vezeichnisse lesen
+
+      Rev 1.2   01 Apr 1998 07:28:48   OS
+   Syntaxfehler
+
+      Rev 1.1   31 Mar 1998 15:35:18   OS
+   Properties angefangen
+
+      Rev 1.0   30 Mar 1998 10:19:08   OS
+   Initial revision.
+
+------------------------------------------------------------------------*/
diff --git a/sw/source/core/unocore/unomap.cxx b/sw/source/core/unocore/unomap.cxx
new file mode 100644
index 000000000000..801700dfd60d
--- /dev/null
+++ b/sw/source/core/unocore/unomap.cxx
@@ -0,0 +1,1921 @@
+/*************************************************************************
+ *
+ *  $RCSfile: unomap.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:28 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include 
+#include 
+#include 
+
+
+#ifndef _SVX_SVXIDS_HRC //autogen
+#include 
+#endif
+#ifndef _SFXPOOLITEM_HXX //autogen
+#include 
+#endif
+#ifndef _UNOMAP_HXX
+#include 
+#endif
+
+#ifndef _UNOPRNMS_HXX
+#include 
+#endif
+#ifndef SW_UNOMID_HXX
+#include 
+#endif
+#ifndef _SVX_UNOMID_HXX
+#include 
+#endif
+#ifndef _COM_SUN_STAR_STYLE_LINESPACINGMODE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_STYLE_PARAGRAPHADJUST_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_STYLE_DROPCAPFORMAT_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_STYLE_LINESPACING_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_STYLE_TABSTOP_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_STYLE_TABALIGN_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_STYLE_PAGESTYLELAYOUT_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_STYLE_BREAKTYPE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XMODULE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XTEXTRANGEMOVER_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XFOOTNOTESSETTINGSSUPPLIER_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XFOOTNOTE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XFOOTNOTESSUPPLIER_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XENDNOTESSUPPLIER_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XENDNOTESSETTINGSSUPPLIER_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_FOOTNOTENUMBERING_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XTEXTSECTIONSSUPPLIER_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XTEXTSECTION_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_SECTIONFILELINK_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_RELORIENTATION_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_VERTORIENTATION_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_HORIZONTALADJUST_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_DOCUMENTSTATISTIC_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_HORIORIENTATION_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_HORIORIENTATIONFORMAT_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_NOTEPRINTMODE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_SIZETYPE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_VERTORIENTATIONFORMAT_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_WRAPTEXTMODE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_SETVARIABLETYPE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XTEXTFIELDSSUPPLIER_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_USERDATAPART_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_CHAPTERFORMAT_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XTEXTFIELD_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_PLACEHOLDERTYPE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_TEMPLATEDISPLAYFORMAT_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_USERFIELDFORMAT_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_PAGENUMBERTYPE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_REFERENCEFIELDPART_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_FILENAMEDISPLAYFORMAT_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XDEPENDENTTEXTFIELD_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_GRAPHICCROP_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XTEXTGRAPHICOBJECTSSUPPLIER_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XTEXTTABLECURSOR_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XTEXTTABLESSUPPLIER_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_TABLECOLUMNSEPARATOR_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XTEXTTABLE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XDOCUMENTINDEXMARK_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XDOCUMENTINDEXESSUPPLIER_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XDOCUMENTINDEX_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XTEXTCOLUMNS_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_TEXTCOLUMNSEQUENCE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XTEXTFRAMESSUPPLIER_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XTEXTFRAME_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUES_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_PROPERTYSTATE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSETINFO_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XMULTIPROPERTYSET_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XFASTPROPERTYSET_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XVETOABLECHANGELISTENER_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSTATE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSTATECHANGELISTENER_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_PropertyAttribute_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTIESCHANGELISTENER_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYCHANGELISTENER_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYACCESS_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYCONTAINER_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_PROPERTYSTATECHANGEEVENT_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_PROPERTYCHANGEEVENT_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_TEXTCONTENTANCHORTYPE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_AWT_FONTSLANT_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_AWT_SIZE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_AWT_XBITMAP_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_STYLE_GRAPHICLOCATION_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_CONTAINER_XINDEXREPLACE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TABLE_SHADOWFORMAT_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TABLE_BORDERLINE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TABLE_TABLEBORDER_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_CONTAINER_XNAMECONTAINER_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_LANG_LOCALE_HPP_
+#include 
+#endif
+#ifndef _SVX_PBINITEM_HXX //autogen
+#include 
+#endif
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::beans;
+using namespace ::rtl;
+
+SwUnoPropertyMapProvider aSwMapProvider;
+
+
+
+
+//  { SW_PROP_NAME(UNO_NAME_WIDTH),             FN_SET_TABLE_WIDTH, &::getCppuType((const long*)0), PROPERTY_NONE},
+//  { SW_PROP_NAME(UNO_NAME_GRAPHIC           ),        RES_BACKGROUND,         &,                              PROPERTY_NONE, MID_GRAPHIC
+//  { SW_PROP_NAME(UNO_NAME_PAGE_DESC_NAME),        RES_PAGEDESC,           &::getCppuType((const String*)0),           PROPERTY_NONE, MID_PAGEDESC_PAGEDESCNAME    },
+
+/******************************************************************************
+    UI-Maps
+******************************************************************************/
+/* -----------------24.06.98 18:12-------------------
+ *
+ * --------------------------------------------------*/
+SwUnoPropertyMapProvider::SwUnoPropertyMapProvider()
+{
+    for( sal_uInt16 i = 0; i < PROPERTY_MAP_END; i++ )
+    {
+        aMapArr[i] = 0;
+    }
+}
+/* -----------------19.02.99 08:31-------------------
+ *
+ * --------------------------------------------------*/
+SwUnoPropertyMapProvider::~SwUnoPropertyMapProvider()
+{
+    delete pCharStyleMap;
+    delete pParaStyleMap;
+    delete pFrameStyleMap;
+    delete pPageStyleMap;
+    delete pNumStyleMap;
+}
+/* -----------------19.02.99 08:31-------------------
+ *
+ * --------------------------------------------------*/
+SfxItemPropertySet& SwUnoPropertyMapProvider::GetPropertySet(sal_Int8 nPropSetId)
+{
+    SfxItemPropertySet* pRet = 0;
+    switch(nPropSetId)
+    {
+        case PROPERTY_SET_CHAR_STYLE:
+            if(!pCharStyleMap)
+                pCharStyleMap = new SwItemPropertySet(
+                    GetPropertyMap(PROPERTY_MAP_CHAR_STYLE ));
+            pRet = pCharStyleMap;
+        break;
+        case PROPERTY_SET_PARA_STYLE:
+            if(!pParaStyleMap)
+                pParaStyleMap = new SwItemPropertySet(
+                    GetPropertyMap(PROPERTY_MAP_PARA_STYLE ));
+            pRet = pParaStyleMap;
+        break;
+        case PROPERTY_SET_FRAME_STYLE:
+            if(!pFrameStyleMap)
+                pFrameStyleMap = new SwItemPropertySet(
+                GetPropertyMap(PROPERTY_MAP_FRAME_STYLE ));
+            pRet = pFrameStyleMap;
+        break;
+        case PROPERTY_SET_PAGE_STYLE:
+            if(!pPageStyleMap)
+            pPageStyleMap = new SwItemPropertySet(
+                GetPropertyMap(PROPERTY_MAP_PAGE_STYLE ));
+            pRet = pPageStyleMap;
+        break;
+        case PROPERTY_SET_NUM_STYLE:
+            if(!pNumStyleMap)
+                pNumStyleMap = new SwItemPropertySet(
+                    GetPropertyMap(PROPERTY_MAP_NUM_STYLE ));
+            pRet = pNumStyleMap;
+        break;
+    }
+    return *pRet;
+}
+/* -----------------25.06.98 07:19-------------------
+ *
+ * --------------------------------------------------*/
+EXTERN_C
+#if defined( PM2 ) && (!defined( CSET ) && !defined ( MTW ) && !defined( WTC ))
+int _stdcall
+#else
+#ifdef WNT
+int _cdecl
+#else
+int
+#endif
+#endif
+lcl_CompareMap(const void* pSmaller, const void* pBigger )
+{
+    int nDiff = strcmp( ((const SfxItemPropertyMap*)pSmaller)->pName, ((const SfxItemPropertyMap*)pBigger)->pName );
+    return nDiff;
+
+}
+/* -----------------24.06.98 18:12-------------------
+ *
+ * --------------------------------------------------*/
+void SwUnoPropertyMapProvider::Sort(sal_uInt16 nId)
+{
+    SfxItemPropertyMap* pTemp = aMapArr[nId];
+    sal_uInt16 i = 0;
+    while( pTemp[i].pName )
+    {
+        i++;
+    }
+    qsort(aMapArr[nId], i, sizeof(SfxItemPropertyMap), lcl_CompareMap);
+}
+
+
+/* -----------------24.06.98 18:12-------------------
+ *
+ * --------------------------------------------------*/
+const SfxItemPropertyMap*   SwUnoPropertyMapProvider::GetPropertyMap(sal_uInt16 nPropertyId)
+{
+    DBG_ASSERT(nPropertyId < PROPERTY_MAP_END, "Id ?" )
+    if(!aMapArr[nPropertyId])
+    {
+        switch(nPropertyId)
+        {
+            case PROPERTY_MAP_TEXT_CURSOR:
+            {
+                static SfxItemPropertyMap aCharAndParaMap_Impl[] =
+                {
+                    { SW_PROP_NAME(UNO_NAME_PARA_IS_HYPHENATION                ),   RES_PARATR_HYPHENZONE,      &::getBooleanCppuType(),    PropertyAttribute::MAYBEVOID, MID_IS_HYPHEN         },
+                    { SW_PROP_NAME(UNO_NAME_PARA_HYPHENATION_MAX_LEADING_CHARS ),   RES_PARATR_HYPHENZONE,      &::getCppuType((const sal_Int16*)0),    PropertyAttribute::MAYBEVOID, MID_HYPHEN_MIN_LEAD   },
+                    { SW_PROP_NAME(UNO_NAME_PARA_HYPHENATION_MAX_TRAILING_CHARS),   RES_PARATR_HYPHENZONE,      &::getCppuType((const sal_Int16*)0),    PropertyAttribute::MAYBEVOID, MID_HYPHEN_MIN_TRAIL  },
+                    { SW_PROP_NAME(UNO_NAME_PARA_HYPHENATION_MAX_HYPHENS       ),   RES_PARATR_HYPHENZONE,      &::getCppuType((const sal_Int16*)0),    PropertyAttribute::MAYBEVOID, MID_HYPHEN_MAX_HYPHENS},
+                    { SW_PROP_NAME(UNO_NAME_BREAK_TYPE),                RES_BREAK,              &::getCppuType((const style::BreakType*)0),             PropertyAttribute::MAYBEVOID, 0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_AUTO_KERNING),         RES_CHRATR_AUTOKERN  ,  &::getBooleanCppuType()  ,          PropertyAttribute::MAYBEVOID,     0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_BACK_COLOR),               RES_CHRATR_BACKGROUND,  &::getCppuType((const sal_Int32*)0),            PropertyAttribute::MAYBEVOID ,MID_BACK_COLOR         },
+                    { SW_PROP_NAME(UNO_NAME_PARA_BACK_COLOR),               RES_BACKGROUND,         &::getCppuType((const sal_Int32*)0),            PropertyAttribute::MAYBEVOID ,MID_BACK_COLOR         },
+                //  { SW_PROP_NAME(UNO_NAME_BOLD),                  RES_CHRATR_WEIGHT    ,  &::getBooleanCppuType()  ,              PropertyAttribute::MAYBEVOID, MID_BOLD},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_CASE_MAP),             RES_CHRATR_CASEMAP,     &::getCppuType((const sal_Int16*)0),            PropertyAttribute::MAYBEVOID, 0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_COLOR),                    RES_CHRATR_COLOR,       &::getCppuType((const sal_Int32*)0),            PropertyAttribute::MAYBEVOID, 0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_STRIKEOUT),            RES_CHRATR_CROSSEDOUT,  &::getCppuType((const sal_Int16*)0),                    PropertyAttribute::MAYBEVOID, MID_CROSS_OUT},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_CROSSED_OUT),          RES_CHRATR_CROSSEDOUT,  &::getBooleanCppuType()  ,          PropertyAttribute::MAYBEVOID, MID_CROSSED_OUT},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_ESCAPEMENT),           RES_CHRATR_ESCAPEMENT,  &::getCppuType((const sal_Int16*)0),            PropertyAttribute::MAYBEVOID, MID_ESC           },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_ESCAPEMENT_HEIGHT),        RES_CHRATR_ESCAPEMENT,  &::getCppuType((const sal_Int8*)0)  ,       PropertyAttribute::MAYBEVOID, MID_ESC_HEIGHT},
+                     { SW_PROP_NAME(UNO_NAME_CHAR_AUTO_ESCAPEMENT),             RES_CHRATR_ESCAPEMENT,  &::getBooleanCppuType()  ,              PropertyAttribute::MAYBEVOID, MID_AUTO_ESC  },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_FLASH              ),  RES_CHRATR_BLINK    ,   &::getBooleanCppuType()  ,          PropertyAttribute::MAYBEVOID,     0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_HEIGHT),                   RES_CHRATR_FONTSIZE  ,  &::getCppuType((const Float*)0),            PropertyAttribute::MAYBEVOID, MID_FONTHEIGHT|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_WEIGHT),                   RES_CHRATR_WEIGHT    ,  &::getCppuType((const Float*)0),            PropertyAttribute::MAYBEVOID, MID_WEIGHT},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_FONT_NAME),                RES_CHRATR_FONT,        &::getCppuType((const OUString*)0),  PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY_NAME },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_FONT_STYLE_NAME),          RES_CHRATR_FONT,        &::getCppuType((const OUString*)0), PropertyAttribute::MAYBEVOID, MID_FONT_STYLE_NAME },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_FONT_FAMILY),          RES_CHRATR_FONT,        &::getCppuType((const sal_Int16*)0),                    PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY   },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_FONT_CHAR_SET),            RES_CHRATR_FONT,        &::getCppuType((const sal_Int16*)0),    PropertyAttribute::MAYBEVOID, MID_FONT_CHAR_SET },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_FONT_PITCH),           RES_CHRATR_FONT,        &::getCppuType((const sal_Int16*)0),                    PropertyAttribute::MAYBEVOID, MID_FONT_PITCH   },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_POSTURE),              RES_CHRATR_POSTURE   ,  &::getCppuType((const awt::FontSlant*)0),       PropertyAttribute::MAYBEVOID, MID_POSTURE},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_UNDERLINE),            RES_CHRATR_UNDERLINE ,  &::getCppuType((const sal_Int16*)0),            PropertyAttribute::MAYBEVOID, MID_UNDERLINE},
+                    { SW_PROP_NAME(UNO_NAME_PARA_GRAPHIC_URL      ),        RES_BACKGROUND,         &::getCppuType((const OUString*)0),         PropertyAttribute::MAYBEVOID ,MID_GRAPHIC_URL    },
+                    { SW_PROP_NAME(UNO_NAME_PARA_GRAPHIC_FILTER  ),         RES_BACKGROUND,         &::getCppuType((const OUString*)0),         PropertyAttribute::MAYBEVOID ,MID_GRAPHIC_FILTER    },
+                    { SW_PROP_NAME(UNO_NAME_PARA_GRAPHIC_LOCATION),         RES_BACKGROUND,         &::getCppuType((const style::GraphicLocation*)0), PropertyAttribute::MAYBEVOID ,MID_GRAPHIC_POSITION},
+                    { SW_PROP_NAME(UNO_NAME_PARA_LEFT_MARGIN),          RES_LR_SPACE,           &::getCppuType((const sal_Int32*)0),            PropertyAttribute::MAYBEVOID, MID_L_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_PARA_RIGHT_MARGIN),             RES_LR_SPACE,           &::getCppuType((const sal_Int32*)0),            PropertyAttribute::MAYBEVOID, MID_R_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_PARA_FIRST_LINE_INDENT),        RES_LR_SPACE,           &::getCppuType((const sal_Int32*)0),            PropertyAttribute::MAYBEVOID, MID_FIRST_LINE_INDENT|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_KERNING            ),  RES_CHRATR_KERNING    , &::getCppuType((const sal_Int16*)0)  ,          PropertyAttribute::MAYBEVOID,   0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_LOCALE         ),      RES_CHRATR_LANGUAGE ,   &::getCppuType((const lang::Locale*)0)  ,       PropertyAttribute::MAYBEVOID,  MID_LANG_LOCALE },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_NO_HYPHENATION     ),  RES_CHRATR_NOHYPHEN ,   &::getBooleanCppuType()  ,          PropertyAttribute::MAYBEVOID,     0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_SHADOWED),             RES_CHRATR_SHADOWED  ,  &::getBooleanCppuType()  ,          PropertyAttribute::MAYBEVOID, 0},
+                //  { SW_PROP_NAME(UNO_NAME_UNDERLINED),                RES_CHRATR_UNDERLINE ,  &::getBooleanCppuType()  ,          PropertyAttribute::MAYBEVOID, MID_UNDERLINED},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_STYLE_NAME),           RES_TXTATR_CHARFMT,     &::getCppuType((const OUString*)0),         PropertyAttribute::MAYBEVOID,     0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_CONTOURED),                RES_CHRATR_CONTOUR,     &::getBooleanCppuType()  ,          PropertyAttribute::MAYBEVOID, 0},
+                    { SW_PROP_NAME(UNO_NAME_DROP_CAP_FORMAT),           RES_PARATR_DROP,        &::getCppuType((const style::DropCapFormat*)0)  , PropertyAttribute::MAYBEVOID, MID_DROPCAP_FORMAT|CONVERT_TWIPS    },
+                    { SW_PROP_NAME(UNO_NAME_DROP_CAP_WHOLE_WORD),       RES_PARATR_DROP,        &::getBooleanCppuType()  ,          PropertyAttribute::MAYBEVOID, MID_DROPCAP_WHOLE_WORD },
+                    { SW_PROP_NAME(UNO_NAME_DROP_CAP_CHAR_STYLE_NAME),  RES_PARATR_DROP,        &::getCppuType((const OUString*)0)  ,       PropertyAttribute::MAYBEVOID, MID_DROPCAP_CHAR_STYLE_NAME },
+                    { SW_PROP_NAME(UNO_NAME_PARA_KEEP_TOGETHER  ),      RES_KEEP,               &::getBooleanCppuType()  ,          PropertyAttribute::MAYBEVOID,     0},
+                    { SW_PROP_NAME(UNO_NAME_PARA_SPLIT      ),          RES_PARATR_SPLIT,       &::getBooleanCppuType()  ,          PropertyAttribute::MAYBEVOID,     0},
+                    { SW_PROP_NAME(UNO_NAME_PARA_WIDOWS),               RES_PARATR_WIDOWS,      &::getCppuType((const sal_Int8*)0),PropertyAttribute::MAYBEVOID,     0},
+                    { SW_PROP_NAME(UNO_NAME_PARA_ORPHANS),              RES_PARATR_ORPHANS,      &::getCppuType((const sal_Int8*)0),PropertyAttribute::MAYBEVOID,     0},
+                    { SW_PROP_NAME(UNO_NAME_PAGE_DESC_NAME),            RES_PAGEDESC,           &::getCppuType((const OUString*)0),         PropertyAttribute::MAYBEVOID, MID_PAGEDESC_PAGEDESCNAME },
+                    { SW_PROP_NAME(UNO_NAME_PAGE_NUMBER_OFFSET),            RES_PAGEDESC,           &::getCppuType((const sal_Int16*)0),        PropertyAttribute::MAYBEVOID, MID_PAGEDESC_PAGENUMOFFSET},
+                    { SW_PROP_NAME(UNO_NAME_PARA_ADJUST),                   RES_PARATR_ADJUST,      &::getCppuType((const sal_Int16*)0),        PropertyAttribute::MAYBEVOID, MID_PARA_ADJUST},
+                    { SW_PROP_NAME(UNO_NAME_PARA_EXPAND_SINGLE_WORD),   RES_PARATR_ADJUST,      &::getBooleanCppuType()  ,          PropertyAttribute::MAYBEVOID, MID_EXPAND_SINGLE   },
+                //  { SW_PROP_NAME(UNO_NAME_GRAPHIC           ),            RES_BACKGROUND,         &,                              PropertyAttribute::MAYBEVOID, MID_GRAPHIC
+                //  { SW_PROP_NAME(UNO_NAME_ITALIC),                    RES_CHRATR_POSTURE   ,  &::getBooleanCppuType()  ,          PropertyAttribute::MAYBEVOID, MID_ITALIC},
+                    { SW_PROP_NAME(UNO_NAME_PARA_LAST_LINE_ADJUST),       RES_PARATR_ADJUST, &::getCppuType((const sal_Int16*)0),               PropertyAttribute::MAYBEVOID, MID_LAST_LINE_ADJUST},
+                    { SW_PROP_NAME(UNO_NAME_PARA_LINE_NUMBER_COUNT  ),  RES_LINENUMBER,     &::getBooleanCppuType(),                PropertyAttribute::MAYBEVOID ,MID_LINENUMBER_COUNT      },
+                    { SW_PROP_NAME(UNO_NAME_PARA_LINE_NUMBER_START_VALUE),RES_LINENUMBER, &::getCppuType((const sal_Int32*)0),                  PropertyAttribute::MAYBEVOID ,MID_LINENUMBER_STARTVALUE},
+                    { SW_PROP_NAME(UNO_NAME_PARA_LINE_SPACING),             RES_PARATR_LINESPACING, &::getCppuType((const style::LineSpacing*)0),       PropertyAttribute::MAYBEVOID,     CONVERT_TWIPS},
+                //  { SW_PROP_NAME(UNO_NAME_NO_LINE_BREAK       ),      RES_CHRATR_NOLINEBREAK, &::getBooleanCppuType()  ,              PropertyAttribute::MAYBEVOID,     0},
+                //  { SW_PROP_NAME(UNO_NAME_PROP_FONT_HEIGHT    ),      RES_CHRATR_PROPORTIONALFONTSIZE,  &::getCppuType((const sal_Int16*)0),  PropertyAttribute::MAYBEVOID,   0},
+                    { SW_PROP_NAME(UNO_NAME_PARA_REGISTER_MODE_ACTIVE),     RES_PARATR_REGISTER,&::getBooleanCppuType()  ,              PropertyAttribute::MAYBEVOID, 0},
+                    { SW_PROP_NAME(UNO_NAME_PARA_TOP_MARGIN),           RES_UL_SPACE,           &::getCppuType((const sal_Int32*)0),            PropertyAttribute::MAYBEVOID, MID_UP_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_PARA_BOTTOM_MARGIN),            RES_UL_SPACE,           &::getCppuType((const sal_Int32*)0),            PropertyAttribute::MAYBEVOID, MID_LO_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_TRANSPARENT_BACKGROUND),   RES_CHRATR_BACKGROUND, &::getBooleanCppuType(),             PropertyAttribute::MAYBEVOID ,MID_GRAPHIC_TRANSPARENT        },
+                    { SW_PROP_NAME(UNO_NAME_PARA_TRANSPARENT_BACKGROUND),   RES_BACKGROUND, &::getBooleanCppuType(),                    PropertyAttribute::MAYBEVOID ,MID_GRAPHIC_TRANSPARENT        },
+                    { SW_PROP_NAME(UNO_NAME_PARA_STYLE_NAME),           FN_UNO_PARA_STYLE,      &::getCppuType((const OUString*)0),                 PropertyAttribute::MAYBEVOID,     0},
+                    { SW_PROP_NAME(UNO_NAME_PAGE_STYLE_NAME),                   FN_UNO_PAGE_STYLE,      &::getCppuType((const OUString*)0),         PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY,   0},
+                    { SW_PROP_NAME(UNO_NAME_NUMBERING_STYLE_NAME),      RES_PARATR_NUMRULE,     &::getCppuType((const OUString*)0),         PropertyAttribute::MAYBEVOID,   0},
+#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) || (defined(__GNUC__) && defined(__APPLE__))
+                    { SW_PROP_NAME(UNO_NAME_TABSTOPS),  RES_PARATR_TABSTOP,  new uno::Type(::getCppuType((uno::Sequence*)0)),       PropertyAttribute::MAYBEVOID, CONVERT_TWIPS},
+#else
+                    { SW_PROP_NAME(UNO_NAME_TABSTOPS),                  RES_PARATR_TABSTOP,     &::getCppuType((const uno::Sequence*)0),        PropertyAttribute::MAYBEVOID, CONVERT_TWIPS},
+#endif
+                    { SW_PROP_NAME(UNO_NAME_WORD_MODE           ),          RES_CHRATR_WORDLINEMODE,&::getBooleanCppuType()  ,          PropertyAttribute::MAYBEVOID,     0},
+                    { SW_PROP_NAME(UNO_NAME_NUMBERING_IS_NUMBER),       FN_UNO_IS_NUMBER,       &::getBooleanCppuType()  ,          PropertyAttribute::MAYBEVOID,     0},
+                    { SW_PROP_NAME(UNO_NAME_NUMBERING_LEVEL),           FN_UNO_NUM_LEVEL,       &::getCppuType((const sal_Int16*)0),            PropertyAttribute::MAYBEVOID, 0},
+                    { SW_PROP_NAME(UNO_NAME_NUMBERING_RULES),           FN_UNO_NUM_RULES,       &::getCppuType((const uno::Reference*)0),     PropertyAttribute::MAYBEVOID, CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_NUMBERING_START_VALUE),     FN_UNO_NUM_START_VALUE, &::getCppuType((const sal_Int16*)0),            PropertyAttribute::MAYBEVOID, CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_DOCUMENT_INDEX_MARK),           FN_UNO_DOCUMENT_INDEX_MARK, &::getCppuType((const uno::Reference*)0), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },
+                    { SW_PROP_NAME(UNO_NAME_DOCUMENT_INDEX),            FN_UNO_DOCUMENT_INDEX,  &::getCppuType((const uno::Reference*)0), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },
+                    { SW_PROP_NAME(UNO_NAME_TEXT_FIELD),                FN_UNO_TEXT_FIELD,      &::getCppuType((const uno::Reference*)0),     PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },
+                    { SW_PROP_NAME(UNO_NAME_TEXT_TABLE),                FN_UNO_TEXT_TABLE,      &::getCppuType((const uno::Reference*)0),     PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },
+                    { SW_PROP_NAME(UNO_NAME_CELL),                      FN_UNO_CELL,            &::getCppuType((uno::Reference*)0),           PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },
+                    { SW_PROP_NAME(UNO_NAME_TEXT_FRAME),                FN_UNO_TEXT_FRAME,      &::getCppuType((uno::Reference*)0),       PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },
+                    { SW_PROP_NAME(UNO_NAME_REFERENCE_MARK),            FN_UNO_REFERENCE_MARK,  &::getCppuType((uno::Reference*)0), PropertyAttribute::MAYBEVOID ,0 },
+                    { SW_PROP_NAME(UNO_NAME_TEXT_SECTION),              FN_UNO_TEXT_SECTION,    &::getCppuType((uno::Reference*)0), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },
+                    { SW_PROP_NAME(UNO_NAME_FOOTNOTE),                  FN_UNO_FOOTNOTE,        &::getCppuType((uno::Reference*)0),        PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },
+                    { SW_PROP_NAME(UNO_NAME_ENDNOTE),                       FN_UNO_ENDNOTE,         &::getCppuType((uno::Reference*)0),        PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },
+                    { SW_PROP_NAME(UNO_NAME_LEFT_BORDER),                   RES_BOX,                &::getCppuType((const table::BorderLine*)0),        PropertyAttribute::MAYBEVOID, LEFT_BORDER  |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_RIGHT_BORDER),              RES_BOX,                &::getCppuType((const table::BorderLine*)0),        PropertyAttribute::MAYBEVOID, RIGHT_BORDER |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_TOP_BORDER),                    RES_BOX,                &::getCppuType((const table::BorderLine*)0),        PropertyAttribute::MAYBEVOID, TOP_BORDER   |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_BOTTOM_BORDER),             RES_BOX,                &::getCppuType((const table::BorderLine*)0),        PropertyAttribute::MAYBEVOID, BOTTOM_BORDER|CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_BORDER_DISTANCE),           RES_BOX,                &::getCppuType((const sal_Int32*)0),            PropertyAttribute::MAYBEVOID, BORDER_DISTANCE|CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_LEFT_BORDER_DISTANCE),  RES_BOX,                &::getCppuType((const sal_Int32*)0),    0, LEFT_BORDER_DISTANCE  |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_RIGHT_BORDER_DISTANCE), RES_BOX,                &::getCppuType((const sal_Int32*)0),    0, RIGHT_BORDER_DISTANCE |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_TOP_BORDER_DISTANCE),       RES_BOX,                &::getCppuType((const sal_Int32*)0),    0, TOP_BORDER_DISTANCE   |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_BOTTOM_BORDER_DISTANCE),    RES_BOX,                &::getCppuType((const sal_Int32*)0),    0, BOTTOM_BORDER_DISTANCE|CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_HYPER_LINK_U_R_L   ),           RES_TXTATR_INETFMT,     &::getCppuType((const OUString*)0),         PROPERTY_NONE ,MID_URL_URL},
+                    { SW_PROP_NAME(UNO_NAME_HYPER_LINK_TARGET  ),           RES_TXTATR_INETFMT,     &::getCppuType((const OUString*)0),         PROPERTY_NONE ,MID_URL_TARGET},
+                    { SW_PROP_NAME(UNO_NAME_HYPER_LINK_NAME ),          RES_TXTATR_INETFMT,     &::getCppuType((const OUString*)0),         PROPERTY_NONE ,MID_URL_HYPERLINKNAME     },
+                    { SW_PROP_NAME(UNO_NAME_UNVISITED_CHAR_STYLE_NAME),   RES_TXTATR_INETFMT,     &::getCppuType((const OUString*)0),       PROPERTY_NONE ,MID_URL_VISITED_FMT       },
+                    { SW_PROP_NAME(UNO_NAME_VISITED_CHAR_STYLE_NAME),     RES_TXTATR_INETFMT,     &::getCppuType((const OUString*)0),           PROPERTY_NONE ,MID_URL_UNVISITED_FMT     },
+                    { SW_PROP_NAME(UNO_NAME_PARA_USER_DEFINED_ATTRIBUTES),  RES_TXTATR_UNKNOWN_CONTAINER, &::getCppuType((uno::Reference*)0), PropertyAttribute::MAYBEVOID, 0 },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_USER_DEFINED_ATTRIBUTES),  RES_UNKNOWNATR_CONTAINER, &::getCppuType((uno::Reference*)0), PropertyAttribute::MAYBEVOID, 0 },
+                    { SW_PROP_NAME(UNO_NAME_PARA_CHAPTER_NUMBERING_LEVEL), FN_UNO_PARA_CHAPTER_NUMBERING_LEVEL,&::getCppuType((const sal_Int8*)0),   PropertyAttribute::READONLY, 0},
+                    { SW_PROP_NAME(UNO_NAME_PARA_CONDITIONAL_STYLE_NAME),  FN_UNO_PARA_CONDITIONAL_STYLE_NAME, &::getCppuType((const OUString*)0),      PropertyAttribute::READONLY, 0},
+                    {0,0,0,0}
+                };
+                aMapArr[nPropertyId] = aCharAndParaMap_Impl;
+            }
+            break;
+            case PROPERTY_MAP_CHAR_STYLE :
+            {
+                static SfxItemPropertyMap aCharStyleMap [] =
+                {
+                    { SW_PROP_NAME(UNO_NAME_CHAR_AUTO_KERNING    ),         RES_CHRATR_AUTOKERN  ,  &::getBooleanCppuType()  ,          PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_TRANSPARENT_BACKGROUND),   RES_CHRATR_BACKGROUND,  &::getBooleanCppuType(),            PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT       },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_BACK_COLOR),               RES_CHRATR_BACKGROUND,  &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_BACK_COLOR        },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_CASE_MAP),             RES_CHRATR_CASEMAP,     &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_COLOR),                    RES_CHRATR_COLOR,       &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_STRIKEOUT),            RES_CHRATR_CROSSEDOUT,  &::getCppuType((const sal_Int16*)0),                    PropertyAttribute::MAYBEVOID, MID_CROSS_OUT},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_CROSSED_OUT),          RES_CHRATR_CROSSEDOUT,  &::getBooleanCppuType()  ,          PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_ESCAPEMENT),           RES_CHRATR_ESCAPEMENT,  &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE, MID_ESC          },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_ESCAPEMENT_HEIGHT),        RES_CHRATR_ESCAPEMENT,  &::getCppuType((const sal_Int8*)0)  ,       PROPERTY_NONE, MID_ESC_HEIGHT},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_FLASH           ),     RES_CHRATR_BLINK    ,   &::getBooleanCppuType()  ,          PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_HEIGHT),                   RES_CHRATR_FONTSIZE  ,  &::getCppuType((const Float*)0),            PROPERTY_NONE, MID_FONTHEIGHT|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_PROP_FONT_HEIGHT),     RES_CHRATR_FONTSIZE  ,  &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE,MID_FONTHEIGHT_PROP|CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_DIFF_FONT_HEIGHT),     RES_CHRATR_FONTSIZE  ,  &::getCppuType((const Float*)0),            PROPERTY_NONE,MID_FONTHEIGHT_DIFF|CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_FONT_NAME),                RES_CHRATR_FONT,        &::getCppuType((const OUString*)0),  PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY_NAME },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_FONT_STYLE_NAME),          RES_CHRATR_FONT,        &::getCppuType((const OUString*)0), PropertyAttribute::MAYBEVOID, MID_FONT_STYLE_NAME },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_FONT_FAMILY),          RES_CHRATR_FONT,        &::getCppuType((const sal_Int16*)0),                    PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY   },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_FONT_CHAR_SET),            RES_CHRATR_FONT,        &::getCppuType((const sal_Int16*)0),    PropertyAttribute::MAYBEVOID, MID_FONT_CHAR_SET },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_FONT_PITCH),           RES_CHRATR_FONT,        &::getCppuType((const sal_Int16*)0),                    PropertyAttribute::MAYBEVOID, MID_FONT_PITCH   },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_WEIGHT),                   RES_CHRATR_WEIGHT    ,  &::getCppuType((const Float*)0),    PROPERTY_NONE, MID_WEIGHT},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_POSTURE),              RES_CHRATR_POSTURE   ,  &::getCppuType((const awt::FontSlant*)0),   PROPERTY_NONE, MID_POSTURE},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_UNDERLINE),            RES_CHRATR_UNDERLINE ,  &::getCppuType((const sal_Int16*)0),    PROPERTY_NONE, MID_UNDERLINE},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_KERNING       ),           RES_CHRATR_KERNING    , &::getCppuType((const sal_Int16*)0)  ,          PROPERTY_NONE,  0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_LOCALE         ),      RES_CHRATR_LANGUAGE ,   &::getCppuType((const lang::Locale*)0)  ,       PropertyAttribute::MAYBEVOID,  MID_LANG_LOCALE },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_NO_HYPHENATION     ),      RES_CHRATR_NOHYPHEN ,   &::getBooleanCppuType()  ,          PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_SHADOWED),             RES_CHRATR_SHADOWED  ,  &::getBooleanCppuType()  ,          PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_CONTOURED),                RES_CHRATR_CONTOUR,     &::getBooleanCppuType()  ,          PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_WORD_MODE           ),          RES_CHRATR_WORDLINEMODE,&::getBooleanCppuType()  ,          PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_HYPER_LINK_U_R_L   ),           RES_TXTATR_INETFMT,     &::getCppuType((const OUString*)0),         PROPERTY_NONE ,MID_URL_URL},
+                    { SW_PROP_NAME(UNO_NAME_HYPER_LINK_TARGET  ),           RES_TXTATR_INETFMT,     &::getCppuType((const OUString*)0),         PROPERTY_NONE ,MID_URL_TARGET},
+                    { SW_PROP_NAME(UNO_NAME_HYPER_LINK_NAME ),          RES_TXTATR_INETFMT,     &::getCppuType((const OUString*)0),         PROPERTY_NONE ,MID_URL_HYPERLINKNAME     },
+                    { SW_PROP_NAME(UNO_NAME_UNVISITED_CHAR_STYLE_NAME),   RES_TXTATR_INETFMT,     &::getCppuType((const OUString*)0),       PROPERTY_NONE ,MID_URL_VISITED_FMT       },
+                    { SW_PROP_NAME(UNO_NAME_VISITED_CHAR_STYLE_NAME),     RES_TXTATR_INETFMT,     &::getCppuType((const OUString*)0),           PROPERTY_NONE ,MID_URL_UNVISITED_FMT     },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_USER_DEFINED_ATTRIBUTES),  RES_UNKNOWNATR_CONTAINER, &::getCppuType((uno::Reference*)0), PropertyAttribute::MAYBEVOID, 0 },
+                    { SW_PROP_NAME(UNO_NAME_IS_PHYSICAL),                  FN_UNO_IS_PHYSICAL,    &::getBooleanCppuType(), PropertyAttribute::READONLY, 0},
+                    { SW_PROP_NAME(UNO_NAME_DISPLAY_NAME),              FN_UNO_DISPLAY_NAME, &::getCppuType((const OUString*)0), PropertyAttribute::READONLY, 0},
+                    {0,0,0,0}
+                };
+                aMapArr[nPropertyId] = aCharStyleMap;
+            }
+            break;
+            case PROPERTY_MAP_PARA_STYLE :
+            {
+                static SfxItemPropertyMap aParaStyleMap [] =
+                {
+                    { SW_PROP_NAME(UNO_NAME_BREAK_TYPE),                    RES_BREAK,              &::getCppuType((const style::BreakType*)0),         PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_PAGE_DESC_NAME),            RES_PAGEDESC,           &::getCppuType((const OUString*)0),         PropertyAttribute::MAYBEVOID, MID_PAGEDESC_PAGEDESCNAME },
+                    { SW_PROP_NAME(UNO_NAME_PAGE_NUMBER_OFFSET),            RES_PAGEDESC,           &::getCppuType((const sal_Int16*)0),        PropertyAttribute::MAYBEVOID, MID_PAGEDESC_PAGENUMOFFSET},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_AUTO_KERNING    ),     RES_CHRATR_AUTOKERN  ,  &::getBooleanCppuType()  ,          PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_TRANSPARENT_BACKGROUND),   RES_CHRATR_BACKGROUND, &::getBooleanCppuType(),         PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT       },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_BACK_COLOR),               RES_CHRATR_BACKGROUND,  &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_BACK_COLOR        },
+                    { SW_PROP_NAME(UNO_NAME_PARA_BACK_COLOR      ),     RES_BACKGROUND,         &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_BACK_COLOR        },
+                    { SW_PROP_NAME(UNO_NAME_PARA_TRANSPARENT_BACKGROUND),   RES_BACKGROUND,         &::getBooleanCppuType(),            PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT       },
+                    { SW_PROP_NAME(UNO_NAME_PARA_GRAPHIC_URL      ),        RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_URL    },
+                    { SW_PROP_NAME(UNO_NAME_PARA_GRAPHIC_FILTER  ),         RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_FILTER    },
+                    { SW_PROP_NAME(UNO_NAME_PARA_GRAPHIC_LOCATION),     RES_BACKGROUND,         &::getCppuType((const style::GraphicLocation*)0), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_CASE_MAP),             RES_CHRATR_CASEMAP,     &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_COLOR),                    RES_CHRATR_COLOR,       &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_STRIKEOUT),            RES_CHRATR_CROSSEDOUT,  &::getCppuType((const sal_Int16*)0),                    PropertyAttribute::MAYBEVOID, MID_CROSS_OUT},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_CROSSED_OUT),          RES_CHRATR_CROSSEDOUT,  &::getBooleanCppuType()  ,          PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_ESCAPEMENT),           RES_CHRATR_ESCAPEMENT,  &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE, MID_ESC          },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_ESCAPEMENT_HEIGHT),        RES_CHRATR_ESCAPEMENT,  &::getCppuType((const sal_Int8*)0)  ,       PROPERTY_NONE, MID_ESC_HEIGHT},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_FLASH              ),  RES_CHRATR_BLINK    ,   &::getBooleanCppuType()  ,          PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_HEIGHT),                   RES_CHRATR_FONTSIZE  ,  &::getCppuType((const Float*)0),            PROPERTY_NONE, MID_FONTHEIGHT|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_PROP_FONT_HEIGHT),     RES_CHRATR_FONTSIZE  ,  &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE,MID_FONTHEIGHT_PROP|CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_DIFF_FONT_HEIGHT),     RES_CHRATR_FONTSIZE  ,  &::getCppuType((const Float*)0),            PROPERTY_NONE,MID_FONTHEIGHT_DIFF|CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_FONT_NAME),                RES_CHRATR_FONT,        &::getCppuType((const OUString*)0),  PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY_NAME },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_FONT_STYLE_NAME),          RES_CHRATR_FONT,        &::getCppuType((const OUString*)0), PropertyAttribute::MAYBEVOID, MID_FONT_STYLE_NAME },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_FONT_FAMILY),          RES_CHRATR_FONT,        &::getCppuType((const sal_Int16*)0),                    PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY   },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_FONT_CHAR_SET),            RES_CHRATR_FONT,        &::getCppuType((const sal_Int16*)0),    PropertyAttribute::MAYBEVOID, MID_FONT_CHAR_SET },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_FONT_PITCH),           RES_CHRATR_FONT,        &::getCppuType((const sal_Int16*)0),                    PropertyAttribute::MAYBEVOID, MID_FONT_PITCH   },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_WEIGHT),                   RES_CHRATR_WEIGHT    ,  &::getCppuType((const Float*)0),    PROPERTY_NONE, MID_WEIGHT},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_POSTURE),              RES_CHRATR_POSTURE   ,  &::getCppuType((const awt::FontSlant*)0),   PROPERTY_NONE, MID_POSTURE},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_UNDERLINE),            RES_CHRATR_UNDERLINE ,  &::getCppuType((const sal_Int16*)0),    PROPERTY_NONE, MID_UNDERLINE},
+                    { SW_PROP_NAME(UNO_NAME_PARA_LEFT_MARGIN),          RES_LR_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_L_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_PARA_RIGHT_MARGIN),             RES_LR_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_R_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_PARA_LEFT_MARGIN_RELATIVE),  RES_LR_SPACE,         &::getCppuType((const sal_Int16*)0), PROPERTY_NONE,     MID_L_REL_MARGIN},
+                    { SW_PROP_NAME(UNO_NAME_PARA_RIGHT_MARGIN_RELATIVE), RES_LR_SPACE,         &::getCppuType((const sal_Int16*)0), PROPERTY_NONE,     MID_R_REL_MARGIN},
+                    { SW_PROP_NAME(UNO_NAME_PARA_FIRST_LINE_INDENT),        RES_LR_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_FIRST_LINE_INDENT|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_PARA_FIRST_LINE_INDENT_RELATIVE),   RES_LR_SPACE,       &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_FIRST_LINE_REL_INDENT|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_KERNING            ),  RES_CHRATR_KERNING    , &::getCppuType((const sal_Int16*)0)  ,          PROPERTY_NONE,  0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_LOCALE         ),      RES_CHRATR_LANGUAGE ,   &::getCppuType((const lang::Locale*)0)  ,       PropertyAttribute::MAYBEVOID,  MID_LANG_LOCALE },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_NO_HYPHENATION     ),  RES_CHRATR_NOHYPHEN ,   &::getBooleanCppuType()  ,          PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_SHADOWED),             RES_CHRATR_SHADOWED  ,  &::getBooleanCppuType()  ,          PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_CONTOURED),                RES_CHRATR_CONTOUR,     &::getBooleanCppuType()  ,          PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_DROP_CAP_FORMAT),           RES_PARATR_DROP,        &::getCppuType((const style::DropCapFormat*)0)  , PROPERTY_NONE, MID_DROPCAP_FORMAT|CONVERT_TWIPS     },
+                    { SW_PROP_NAME(UNO_NAME_DROP_CAP_WHOLE_WORD),       RES_PARATR_DROP,        &::getBooleanCppuType()  ,          PROPERTY_NONE, MID_DROPCAP_WHOLE_WORD },
+                    { SW_PROP_NAME(UNO_NAME_DROP_CAP_CHAR_STYLE_NAME),  RES_PARATR_DROP,        &::getCppuType((const OUString*)0)  ,       PropertyAttribute::MAYBEVOID, MID_DROPCAP_CHAR_STYLE_NAME },
+                    { SW_PROP_NAME(UNO_NAME_PARA_KEEP_TOGETHER  ),      RES_KEEP,               &::getBooleanCppuType()  ,          PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_PARA_SPLIT      ),          RES_PARATR_SPLIT,       &::getBooleanCppuType()  ,          PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_PARA_WIDOWS),               RES_PARATR_WIDOWS,      &::getCppuType((const sal_Int8*)0),PropertyAttribute::MAYBEVOID,     0},
+                    { SW_PROP_NAME(UNO_NAME_PARA_ORPHANS),              RES_PARATR_ORPHANS,      &::getCppuType((const sal_Int8*)0),PropertyAttribute::MAYBEVOID,     0},
+                    { SW_PROP_NAME(UNO_NAME_PARA_EXPAND_SINGLE_WORD),     RES_PARATR_ADJUST,      &::getBooleanCppuType()  ,        PROPERTY_NONE, MID_EXPAND_SINGLE   },
+                    { SW_PROP_NAME(UNO_NAME_PARA_LAST_LINE_ADJUST),       RES_PARATR_ADJUST,      &::getCppuType((const sal_Int16*)0),          PROPERTY_NONE, MID_LAST_LINE_ADJUST},
+                    { SW_PROP_NAME(UNO_NAME_PARA_LINE_NUMBER_COUNT  ),  RES_LINENUMBER,         &::getBooleanCppuType(),            PROPERTY_NONE ,MID_LINENUMBER_COUNT     },
+                    { SW_PROP_NAME(UNO_NAME_PARA_LINE_NUMBER_START_VALUE),RES_LINENUMBER,       &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_LINENUMBER_STARTVALUE},
+                    { SW_PROP_NAME(UNO_NAME_PARA_LINE_SPACING),             RES_PARATR_LINESPACING, &::getCppuType((const style::LineSpacing*)0),PROPERTY_NONE,     CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_PARA_ADJUST),                   RES_PARATR_ADJUST,      &::getCppuType((const sal_Int16*)0),        PROPERTY_NONE, MID_PARA_ADJUST},
+                    { SW_PROP_NAME(UNO_NAME_PARA_REGISTER_MODE_ACTIVE),     RES_PARATR_REGISTER,    &::getBooleanCppuType()  ,          PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_PARA_TOP_MARGIN),           RES_UL_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_UP_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_PARA_BOTTOM_MARGIN),            RES_UL_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_LO_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_PARA_TOP_MARGIN_RELATIVE),    RES_UL_SPACE,         &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, MID_UP_REL_MARGIN},
+                    { SW_PROP_NAME(UNO_NAME_PARA_BOTTOM_MARGIN_RELATIVE), RES_UL_SPACE,         &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, MID_LO_REL_MARGIN},
+#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) || (defined(__GNUC__) && defined(__APPLE__))
+                    { SW_PROP_NAME(UNO_NAME_TABSTOPS),  RES_PARATR_TABSTOP,  new uno::Type(::getCppuType((uno::Sequence*)0)),       PropertyAttribute::MAYBEVOID, CONVERT_TWIPS},
+#else
+                    { SW_PROP_NAME(UNO_NAME_TABSTOPS),                  RES_PARATR_TABSTOP,     &::getCppuType((const uno::Sequence*)0),        PropertyAttribute::MAYBEVOID, CONVERT_TWIPS},
+#endif
+                    { SW_PROP_NAME(UNO_NAME_WORD_MODE           ),          RES_CHRATR_WORDLINEMODE,&::getBooleanCppuType()  ,          PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_LEFT_BORDER),               RES_BOX,                &::getCppuType((const table::BorderLine*)0),    0, LEFT_BORDER  |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_RIGHT_BORDER),          RES_BOX,                &::getCppuType((const table::BorderLine*)0),    0, RIGHT_BORDER |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_TOP_BORDER),                RES_BOX,                &::getCppuType((const table::BorderLine*)0),    0, TOP_BORDER   |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_BOTTOM_BORDER),         RES_BOX,                &::getCppuType((const table::BorderLine*)0),    0, BOTTOM_BORDER|CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_BORDER_DISTANCE),         RES_BOX,              &::getCppuType((const sal_Int32*)0),    0, BORDER_DISTANCE|CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_LEFT_BORDER_DISTANCE),  RES_BOX,                &::getCppuType((const sal_Int32*)0),    0, LEFT_BORDER_DISTANCE  |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_RIGHT_BORDER_DISTANCE), RES_BOX,                &::getCppuType((const sal_Int32*)0),    0, RIGHT_BORDER_DISTANCE |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_TOP_BORDER_DISTANCE),       RES_BOX,                &::getCppuType((const sal_Int32*)0),    0, TOP_BORDER_DISTANCE   |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_BOTTOM_BORDER_DISTANCE),    RES_BOX,                &::getCppuType((const sal_Int32*)0),    0, BOTTOM_BORDER_DISTANCE|CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_FOLLOW_STYLE),          FN_UNO_FOLLOW_STYLE,    &::getCppuType((const OUString*)0), PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_HYPER_LINK_U_R_L   ),           RES_TXTATR_INETFMT,     &::getCppuType((const OUString*)0),         PROPERTY_NONE ,MID_URL_URL},
+                    { SW_PROP_NAME(UNO_NAME_HYPER_LINK_TARGET  ),           RES_TXTATR_INETFMT,     &::getCppuType((const OUString*)0),         PROPERTY_NONE ,MID_URL_TARGET},
+                    { SW_PROP_NAME(UNO_NAME_HYPER_LINK_NAME ),          RES_TXTATR_INETFMT,     &::getCppuType((const OUString*)0),         PROPERTY_NONE ,MID_URL_HYPERLINKNAME     },
+                    { SW_PROP_NAME(UNO_NAME_UNVISITED_CHAR_STYLE_NAME),   RES_TXTATR_INETFMT,     &::getCppuType((const OUString*)0),       PROPERTY_NONE ,MID_URL_VISITED_FMT       },
+                    { SW_PROP_NAME(UNO_NAME_VISITED_CHAR_STYLE_NAME),     RES_TXTATR_INETFMT,     &::getCppuType((const OUString*)0),           PROPERTY_NONE ,MID_URL_UNVISITED_FMT     },
+                    { SW_PROP_NAME(UNO_NAME_PARA_IS_HYPHENATION                ),   RES_PARATR_HYPHENZONE,      &::getBooleanCppuType(),    PropertyAttribute::MAYBEVOID, MID_IS_HYPHEN         },
+                    { SW_PROP_NAME(UNO_NAME_PARA_HYPHENATION_MAX_LEADING_CHARS ),   RES_PARATR_HYPHENZONE,      &::getCppuType((const sal_Int16*)0),    PropertyAttribute::MAYBEVOID, MID_HYPHEN_MIN_LEAD   },
+                    { SW_PROP_NAME(UNO_NAME_PARA_HYPHENATION_MAX_TRAILING_CHARS),   RES_PARATR_HYPHENZONE,      &::getCppuType((const sal_Int16*)0),    PropertyAttribute::MAYBEVOID, MID_HYPHEN_MIN_TRAIL  },
+                    { SW_PROP_NAME(UNO_NAME_PARA_HYPHENATION_MAX_HYPHENS       ),   RES_PARATR_HYPHENZONE,      &::getCppuType((const sal_Int16*)0),    PropertyAttribute::MAYBEVOID, MID_HYPHEN_MAX_HYPHENS},
+                    { SW_PROP_NAME(UNO_NAME_NUMBERING_STYLE_NAME),          RES_PARATR_NUMRULE,     &::getCppuType((const OUString*)0),         PropertyAttribute::MAYBEVOID,   0},
+                    { SW_PROP_NAME(UNO_NAME_PARA_USER_DEFINED_ATTRIBUTES),  RES_TXTATR_UNKNOWN_CONTAINER, &::getCppuType((uno::Reference*)0), PropertyAttribute::MAYBEVOID, 0 },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_USER_DEFINED_ATTRIBUTES),  RES_UNKNOWNATR_CONTAINER, &::getCppuType((uno::Reference*)0), PropertyAttribute::MAYBEVOID, 0 },
+                    { SW_PROP_NAME(UNO_NAME_IS_PHYSICAL),                  FN_UNO_IS_PHYSICAL,    &::getBooleanCppuType(), PropertyAttribute::READONLY, 0},
+                    { SW_PROP_NAME(UNO_NAME_IS_AUTO_UPDATE),            FN_UNO_IS_AUTO_UPDATE, &::getBooleanCppuType(), PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_DISPLAY_NAME),              FN_UNO_DISPLAY_NAME, &::getCppuType((const OUString*)0), PropertyAttribute::READONLY, 0},
+                    { SW_PROP_NAME(UNO_NAME_CATEGORY),                  FN_UNO_CATEGORY,    &::getCppuType((sal_Int16*)0),          PROPERTY_NONE , 0 },
+                    {0,0,0,0}
+                };
+                aMapArr[nPropertyId] = aParaStyleMap;
+            }
+            break;
+            case PROPERTY_MAP_FRAME_STYLE:
+            {
+                static SfxItemPropertyMap aFrameStyleMap   [] =
+                {
+                    { SW_PROP_NAME(UNO_NAME_ANCHOR_PAGE_NO),            RES_ANCHOR,             &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE, MID_ANCHOR_PAGENUM       },
+                    { SW_PROP_NAME(UNO_NAME_ANCHOR_TYPE   ),            RES_ANCHOR,             &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE, MID_ANCHOR_ANCHORTYPE},
+                    { SW_PROP_NAME(UNO_NAME_BACK_COLOR       ),     RES_BACKGROUND,         &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_BACK_COLOR        },
+                //  { SW_PROP_NAME(UNO_NAME_CHAIN_NEXT_NAME),           RES_CHAIN,              &::getCppuType((const OUString*)0),         PROPERTY_NONE ,MID_CHAIN_NEXTNAME},
+                //  { SW_PROP_NAME(UNO_NAME_CHAIN_PREV_NAME),           RES_CHAIN,              &::getCppuType((const OUString*)0),         PROPERTY_NONE ,MID_CHAIN_PREVNAME},
+                /*not impl*/    { SW_PROP_NAME(UNO_NAME_CLIENT_MAP      ),      RES_URL,                &::getBooleanCppuType(),            PROPERTY_NONE ,MID_URL_CLIENTMAP         },
+                    { SW_PROP_NAME(UNO_NAME_CONTENT_PROTECTED ),        RES_PROTECT,            &::getBooleanCppuType(),            PROPERTY_NONE, MID_PROTECT_CONTENT   },
+                    { SW_PROP_NAME(UNO_NAME_EDIT_IN_READONLY),      RES_EDIT_IN_READONLY,   &::getBooleanCppuType(),            PROPERTY_NONE, 0},
+                //  { SW_PROP_NAME(UNO_NAME_GRAPHIC           ),        RES_BACKGROUND,         &,                              PROPERTY_NONE, MID_GRAPHIC
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_URL      ),        RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_URL    },
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_FILTER  ),         RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_FILTER    },
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_LOCATION    ),         RES_BACKGROUND,         &::getCppuType((const style::GraphicLocation*)0),           PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+                    { SW_PROP_NAME(UNO_NAME_LEFT_MARGIN),           RES_LR_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_L_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_RIGHT_MARGIN),          RES_LR_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_R_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_HORI_ORIENT  ),             RES_HORI_ORIENT,        &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE ,MID_HORIORIENT_ORIENT    },
+                    { SW_PROP_NAME(UNO_NAME_HORI_ORIENT_POSITION),  RES_HORI_ORIENT,        &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_HORIORIENT_POSITION|CONVERT_TWIPS    },
+                    { SW_PROP_NAME(UNO_NAME_HORI_ORIENT_RELATION),  RES_HORI_ORIENT,        &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE ,MID_HORIORIENT_RELATION  },
+                    { SW_PROP_NAME(UNO_NAME_HYPER_LINK_U_R_L   ),       RES_URL,                &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_URL_URL},
+                    { SW_PROP_NAME(UNO_NAME_HYPER_LINK_TARGET  ),       RES_URL,                &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_URL_TARGET},
+                    { SW_PROP_NAME(UNO_NAME_HYPER_LINK_NAME ),      RES_URL,                &::getCppuType((const OUString*)0),         PROPERTY_NONE ,MID_URL_HYPERLINKNAME     },
+                    { SW_PROP_NAME(UNO_NAME_OPAQUE),                    RES_OPAQUE,             &::getBooleanCppuType(),            PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_PAGE_TOGGLE),               RES_HORI_ORIENT,        &::getBooleanCppuType(),            PROPERTY_NONE ,MID_HORIORIENT_PAGETOGGLE },
+                    { SW_PROP_NAME(UNO_NAME_POSITION_PROTECTED),    RES_PROTECT,            &::getBooleanCppuType(),            PROPERTY_NONE, MID_PROTECT_POSITION},
+                    { SW_PROP_NAME(UNO_NAME_PRINT),                     RES_PRINT,              &::getBooleanCppuType(),            PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_HEIGHT),                    RES_FRM_SIZE,           &::getCppuType((const sal_Int32*)0)  ,          PROPERTY_NONE, MID_FRMSIZE_HEIGHT|CONVERT_TWIPS         },
+                    { SW_PROP_NAME(UNO_NAME_RELATIVE_HEIGHT),       RES_FRM_SIZE,           &::getCppuType((const sal_Int8*)0)  ,       PROPERTY_NONE,   MID_FRMSIZE_REL_HEIGHT },
+                    { SW_PROP_NAME(UNO_NAME_RELATIVE_WIDTH),            RES_FRM_SIZE,           &::getCppuType((const sal_Int8*)0)  ,       PROPERTY_NONE,   MID_FRMSIZE_REL_WIDTH  },
+                    { SW_PROP_NAME(UNO_NAME_SIZE_TYPE),                 RES_FRM_SIZE,           &::getCppuType((const sal_Int16*)0)  ,          PROPERTY_NONE,   MID_FRMSIZE_SIZE_TYPE  },
+                    { SW_PROP_NAME(UNO_NAME_SIZE),                  RES_FRM_SIZE,           &::getCppuType((const awt::Size*)0),            PROPERTY_NONE, MID_FRMSIZE_SIZE|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_SIZE_RELATIVE),             RES_FRM_SIZE,           &::getBooleanCppuType()  ,          PROPERTY_NONE,   MID_FRMSIZE_IS_SYNC_REL_SIZE   },
+                //  { SW_PROP_NAME(UNO_NAME_WIDTH),                     RES_FRM_SIZE,           &::getCppuType((const sal_Int32*)0)  ,          PROPERTY_NONE, MID_FRMSIZE_WIDTH            },
+                    { SW_PROP_NAME(UNO_NAME_SHADOW_FORMAT),             RES_SHADOW,             &::getCppuType((const table::ShadowFormat*)0),  PROPERTY_NONE, CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_SERVER_MAP      ),      RES_URL,                &::getBooleanCppuType(),            PROPERTY_NONE ,MID_URL_SERVERMAP         },
+                    { SW_PROP_NAME(UNO_NAME_SIZE_PROTECTED    ),    RES_PROTECT,            &::getBooleanCppuType(),            PROPERTY_NONE, MID_PROTECT_SIZE    },
+                    //Surround bleibt, weil es mit der 5.1 ausgeliefert wurde, obwohl es mit text::WrapTextMode identisch ist
+                    { SW_PROP_NAME(UNO_NAME_SURROUND                  ), RES_SURROUND,          &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE, MID_SURROUND_SURROUNDTYPE    },
+                    { SW_PROP_NAME(UNO_NAME_TEXT_WRAP),             RES_SURROUND,           &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE, MID_SURROUND_SURROUNDTYPE    },
+                    { SW_PROP_NAME(UNO_NAME_SURROUND_ANCHORONLY),   RES_SURROUND,           &::getBooleanCppuType(),            PROPERTY_NONE, MID_SURROUND_ANCHORONLY      },
+                    { SW_PROP_NAME(UNO_NAME_TEXT_COLUMNS),          RES_COL,                &::getCppuType((uno::Reference*)0),    PROPERTY_NONE, MID_COLUMNS},
+                    { SW_PROP_NAME(UNO_NAME_TOP_MARGIN),                RES_UL_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_UP_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_BOTTOM_MARGIN),             RES_UL_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_LO_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_TRANSPARENT_BACKGROUND ),   RES_BACKGROUND,         &::getBooleanCppuType(),            PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT       },
+                    { SW_PROP_NAME(UNO_NAME_VERT_ORIENT  ),             RES_VERT_ORIENT,        &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE ,MID_VERTORIENT_ORIENT    },
+                    { SW_PROP_NAME(UNO_NAME_VERT_ORIENT_POSITION),  RES_VERT_ORIENT,        &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_VERTORIENT_POSITION|CONVERT_TWIPS    },
+                    { SW_PROP_NAME(UNO_NAME_VERT_ORIENT_RELATION),  RES_VERT_ORIENT,        &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE ,MID_VERTORIENT_RELATION  },
+                    { SW_PROP_NAME(UNO_NAME_LEFT_BORDER),               RES_BOX,                &::getCppuType((const table::BorderLine*)0),    0, LEFT_BORDER  |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_RIGHT_BORDER),          RES_BOX,                &::getCppuType((const table::BorderLine*)0),    0, RIGHT_BORDER |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_TOP_BORDER),                RES_BOX,                &::getCppuType((const table::BorderLine*)0),    0, TOP_BORDER   |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_BOTTOM_BORDER),         RES_BOX,                &::getCppuType((const table::BorderLine*)0),    0, BOTTOM_BORDER|CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_BORDER_DISTANCE),         RES_BOX,    &::getCppuType((const sal_Int32*)0),  0, BORDER_DISTANCE|CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_LEFT_BORDER_DISTANCE),  RES_BOX,                &::getCppuType((const sal_Int32*)0),    0, LEFT_BORDER_DISTANCE  |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_RIGHT_BORDER_DISTANCE), RES_BOX,                &::getCppuType((const sal_Int32*)0),    0, RIGHT_BORDER_DISTANCE |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_TOP_BORDER_DISTANCE),       RES_BOX,                &::getCppuType((const sal_Int32*)0),    0, TOP_BORDER_DISTANCE   |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_BOTTOM_BORDER_DISTANCE),    RES_BOX,                &::getCppuType((const sal_Int32*)0),    0, BOTTOM_BORDER_DISTANCE|CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_USER_DEFINED_ATTRIBUTES),       RES_UNKNOWNATR_CONTAINER, &::getCppuType((uno::Reference*)0), PropertyAttribute::MAYBEVOID, 0 },
+                    { SW_PROP_NAME(UNO_NAME_IS_PHYSICAL),                  FN_UNO_IS_PHYSICAL,    &::getBooleanCppuType(), PropertyAttribute::READONLY, 0},
+                    { SW_PROP_NAME(UNO_NAME_IS_AUTO_UPDATE),            FN_UNO_IS_AUTO_UPDATE, &::getBooleanCppuType(), PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_DISPLAY_NAME),              FN_UNO_DISPLAY_NAME, &::getCppuType((const OUString*)0), PropertyAttribute::READONLY, 0},
+                    {0,0,0,0}
+                };
+                aMapArr[nPropertyId] = aFrameStyleMap;
+            }
+            break;
+            case PROPERTY_MAP_PAGE_STYLE :
+            {
+                static SfxItemPropertyMap aPageStyleMap [] =
+                {
+                    { SW_PROP_NAME(UNO_NAME_BACK_COLOR       ),     RES_BACKGROUND,         &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_BACK_COLOR        },
+                //  { SW_PROP_NAME(UNO_NAME_GRAPHIC           ),        RES_BACKGROUND,         &,                              PROPERTY_NONE, MID_GRAPHIC
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_URL      ),    RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_URL    },
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_FILTER  ),     RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_FILTER    },
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_LOCATION    ), RES_BACKGROUND,         &::getCppuType((const style::GraphicLocation*)0), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+                    { SW_PROP_NAME(UNO_NAME_LEFT_MARGIN),           RES_LR_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_L_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_RIGHT_MARGIN),          RES_LR_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_R_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_TRANSPARENT_BACKGROUND ),   RES_BACKGROUND,         &::getBooleanCppuType(),            PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT       },
+                    { SW_PROP_NAME(UNO_NAME_LEFT_BORDER),               RES_BOX,                &::getCppuType((const table::BorderLine*)0),    0, LEFT_BORDER  |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_RIGHT_BORDER),          RES_BOX,                &::getCppuType((const table::BorderLine*)0),    0, RIGHT_BORDER |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_TOP_BORDER),                RES_BOX,                &::getCppuType((const table::BorderLine*)0),    0, TOP_BORDER   |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_BOTTOM_BORDER),         RES_BOX,                &::getCppuType((const table::BorderLine*)0),    0, BOTTOM_BORDER|CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_BORDER_DISTANCE),         RES_BOX,    &::getCppuType((const sal_Int32*)0),  0, BORDER_DISTANCE|CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_LEFT_BORDER_DISTANCE),  RES_BOX,                &::getCppuType((const sal_Int32*)0),    0, LEFT_BORDER_DISTANCE  |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_RIGHT_BORDER_DISTANCE), RES_BOX,                &::getCppuType((const sal_Int32*)0),    0, RIGHT_BORDER_DISTANCE |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_TOP_BORDER_DISTANCE),       RES_BOX,                &::getCppuType((const sal_Int32*)0),    0, TOP_BORDER_DISTANCE   |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_BOTTOM_BORDER_DISTANCE),    RES_BOX,                &::getCppuType((const sal_Int32*)0),    0, BOTTOM_BORDER_DISTANCE|CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_SHADOW_FORMAT),             RES_SHADOW,             &::getCppuType((const table::ShadowFormat*)0),  PROPERTY_NONE, CONVERT_TWIPS},
+
+                    { SW_PROP_NAME(UNO_NAME_HEADER_BACK_COLOR        ),     FN_UNO_HEADER_BACKGROUND,   &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_BACK_COLOR        },
+                //  { SW_PROP_NAME(UNO_NAME_HEADER_GRAPHIC           ),         FN_UNO_HEADER_BACKGROUND,   &,                              PROPERTY_NONE, MID_GRAPHIC
+                    { SW_PROP_NAME(UNO_NAME_HEADER_GRAPHIC_URL      ),      RES_BACKGROUND,             &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_URL    },
+                    { SW_PROP_NAME(UNO_NAME_HEADER_GRAPHIC_FILTER  ),       RES_BACKGROUND,             &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_FILTER    },
+                    { SW_PROP_NAME(UNO_NAME_HEADER_GRAPHIC_LOCATION  ),         FN_UNO_HEADER_BACKGROUND,   &::getCppuType((const style::GraphicLocation*)0), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+                    { SW_PROP_NAME(UNO_NAME_HEADER_LEFT_MARGIN),                FN_UNO_HEADER_LR_SPACE,     &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_L_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_HEADER_RIGHT_MARGIN),           FN_UNO_HEADER_LR_SPACE,     &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_R_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_HEADER_TRANSPARENT_BACKGROUND), FN_UNO_HEADER_BACKGROUND,   &::getBooleanCppuType(),            PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT       },
+                    { SW_PROP_NAME(UNO_NAME_HEADER_LEFT_BORDER),                FN_UNO_HEADER_BOX,              &::getCppuType((const table::BorderLine*)0),    0, LEFT_BORDER  |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_HEADER_RIGHT_BORDER),               FN_UNO_HEADER_BOX,              &::getCppuType((const table::BorderLine*)0),    0, RIGHT_BORDER |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_HEADER_TOP_BORDER),             FN_UNO_HEADER_BOX,              &::getCppuType((const table::BorderLine*)0),    0, TOP_BORDER   |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_HEADER_BOTTOM_BORDER),          FN_UNO_HEADER_BOX,              &::getCppuType((const table::BorderLine*)0),    0, BOTTOM_BORDER|CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_HEADER_BORDER_DISTANCE),            FN_UNO_HEADER_BOX,    &::getCppuType((const sal_Int32*)0),  0, BORDER_DISTANCE|CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_HEADER_SHADOW_FORMAT),          FN_UNO_HEADER_SHADOW,       &::getCppuType((const table::ShadowFormat*)0),  PROPERTY_NONE, CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_HEADER_BODY_DISTANCE),          FN_UNO_HEADER_BODY_DISTANCE,&::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_LO_MARGIN|CONVERT_TWIPS       },
+                    { SW_PROP_NAME(UNO_NAME_HEADER_IS_DYNAMIC_DISTANCE),        FN_UNO_HEADER_IS_DYNAMIC_DISTANCE,&::getBooleanCppuType(),          PROPERTY_NONE ,0         },
+                    { SW_PROP_NAME(UNO_NAME_HEADER_SHARE_CONTENT),          FN_UNO_HEADER_SHARE_CONTENT,&::getBooleanCppuType(),            PROPERTY_NONE ,0         },
+                    { SW_PROP_NAME(UNO_NAME_HEADER_HEIGHT),                 FN_UNO_HEADER_HEIGHT,       &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_SIZE_HEIGHT|CONVERT_TWIPS         },
+                    { SW_PROP_NAME(UNO_NAME_HEADER_ON),                         FN_UNO_HEADER_ON,           &::getBooleanCppuType(),            PROPERTY_NONE ,0         },
+
+                    { SW_PROP_NAME(UNO_NAME_FOOTER_BACK_COLOR        ),     FN_UNO_FOOTER_BACKGROUND,   &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_BACK_COLOR        },
+                //  { SW_PROP_NAME(UNO_NAME_FOOTER_GRAPHIC           ),         FN_UNO_FOOTER_BACKGROUND,   &,                              PROPERTY_NONE, MID_GRAPHIC
+                    { SW_PROP_NAME(UNO_NAME_FOOTER_GRAPHIC_URL      ),      RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_URL    },
+                    { SW_PROP_NAME(UNO_NAME_FOOTER_GRAPHIC_FILTER  ),       RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_FILTER    },
+                    { SW_PROP_NAME(UNO_NAME_FOOTER_GRAPHIC_LOCATION  ),         FN_UNO_FOOTER_BACKGROUND,   &::getCppuType((const style::GraphicLocation*)0), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+                    { SW_PROP_NAME(UNO_NAME_FOOTER_LEFT_MARGIN),                FN_UNO_FOOTER_LR_SPACE,     &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_L_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_FOOTER_RIGHT_MARGIN),           FN_UNO_FOOTER_LR_SPACE,     &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_R_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_FOOTER_TRANSPARENT_BACKGROUND ),    FN_UNO_FOOTER_BACKGROUND,   &::getBooleanCppuType(),            PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT       },
+                    { SW_PROP_NAME(UNO_NAME_FOOTER_LEFT_BORDER),                RES_BOX,                &::getCppuType((const table::BorderLine*)0),    0, LEFT_BORDER  |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_FOOTER_RIGHT_BORDER),           RES_BOX,                &::getCppuType((const table::BorderLine*)0),    0, RIGHT_BORDER |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_FOOTER_TOP_BORDER),             RES_BOX,                &::getCppuType((const table::BorderLine*)0),    0, TOP_BORDER   |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_FOOTER_BOTTOM_BORDER),          RES_BOX,                &::getCppuType((const table::BorderLine*)0),    0, BOTTOM_BORDER|CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_FOOTER_BORDER_DISTANCE),         RES_BOX,    &::getCppuType((const sal_Int32*)0),   0, BORDER_DISTANCE|CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_FOOTER_SHADOW_FORMAT),          FN_UNO_FOOTER_SHADOW,       &::getCppuType((const table::ShadowFormat*)0),  PROPERTY_NONE, CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_FOOTER_BODY_DISTANCE),          FN_UNO_FOOTER_BODY_DISTANCE,&::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_UP_MARGIN|CONVERT_TWIPS       },
+                    { SW_PROP_NAME(UNO_NAME_FOOTER_IS_DYNAMIC_DISTANCE),FN_UNO_FOOTER_IS_DYNAMIC_DISTANCE,&::getBooleanCppuType(),          PROPERTY_NONE ,0         },
+                    { SW_PROP_NAME(UNO_NAME_FOOTER_SHARE_CONTENT),          FN_UNO_FOOTER_SHARE_CONTENT,&::getBooleanCppuType(),            PROPERTY_NONE ,0         },
+                    { SW_PROP_NAME(UNO_NAME_FOOTER_HEIGHT),                 FN_UNO_FOOTER_HEIGHT,       &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_SIZE_HEIGHT|CONVERT_TWIPS         },
+                    { SW_PROP_NAME(UNO_NAME_FOOTER_ON),                         FN_UNO_FOOTER_ON,           &::getBooleanCppuType(),            PROPERTY_NONE ,0         },
+
+
+                    { SW_PROP_NAME(UNO_NAME_LANDSCAPE),                 SID_ATTR_PAGE,          &::getBooleanCppuType(),            PROPERTY_NONE ,MID_PAGE_ORIENTATION   },
+                    { SW_PROP_NAME(UNO_NAME_NUMBERING_TYPE),            SID_ATTR_PAGE,          &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE , MID_PAGE_NUMTYPE       },
+                    { SW_PROP_NAME(UNO_NAME_PAGE_STYLE_LAYOUT),         SID_ATTR_PAGE,          &::getCppuType((const style::PageStyleLayout*)0),   PROPERTY_NONE ,MID_PAGE_LAYOUT     },
+                    { SW_PROP_NAME(UNO_NAME_PRINTER_PAPER_TRAY),        RES_PAPER_BIN,          &::getCppuType((const sal_Int8*)0),             PROPERTY_NONE , 0 },
+                    { SW_PROP_NAME(UNO_NAME_REGISTER_MODE_ACTIVE),  SID_SWREGISTER_MODE,    &::getBooleanCppuType(),            PROPERTY_NONE , 0 },
+                    { SW_PROP_NAME(UNO_NAME_REGISTER_PARAGRAPH_STYLE),SID_ATTR_PAGE_EXT1,   &::getCppuType((const OUString*)0),         PROPERTY_NONE , 0 },
+                    { SW_PROP_NAME(UNO_NAME_SIZE),                  SID_ATTR_PAGE_SIZE,     &::getCppuType((const awt::Size*)0),            PROPERTY_NONE, CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_TEXT_COLUMNS),          RES_COL,                &::getCppuType((uno::Reference*)0),    PROPERTY_NONE, MID_COLUMNS},
+                    { SW_PROP_NAME(UNO_NAME_TOP_MARGIN),            RES_UL_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_UP_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_BOTTOM_MARGIN),             RES_UL_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_LO_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_HEADER_TEXT),           FN_UNO_HEADER,          &::getCppuType((uno::Reference*)0),            PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},
+                    { SW_PROP_NAME(UNO_NAME_HEADER_TEXT_LEFT),      FN_UNO_HEADER_LEFT,     &::getCppuType((uno::Reference*)0),            PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},
+                    { SW_PROP_NAME(UNO_NAME_HEADER_TEXT_RIGHT),     FN_UNO_HEADER_RIGHT,    &::getCppuType((uno::Reference*)0),            PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},
+                    { SW_PROP_NAME(UNO_NAME_FOOTER_TEXT),           FN_UNO_FOOTER,          &::getCppuType((uno::Reference*)0),            PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},
+                    { SW_PROP_NAME(UNO_NAME_FOOTER_TEXT_LEFT),      FN_UNO_FOOTER_LEFT,     &::getCppuType((uno::Reference*)0),            PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},
+                    { SW_PROP_NAME(UNO_NAME_FOOTER_TEXT_RIGHT),     FN_UNO_FOOTER_RIGHT,    &::getCppuType((uno::Reference*)0),            PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},
+                    { SW_PROP_NAME(UNO_NAME_FOLLOW_STYLE),          FN_UNO_FOLLOW_STYLE,    &::getCppuType((const OUString*)0),         PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_USER_DEFINED_ATTRIBUTES),       RES_UNKNOWNATR_CONTAINER, &::getCppuType((uno::Reference*)0), PropertyAttribute::MAYBEVOID, 0 },
+                    { SW_PROP_NAME(UNO_NAME_IS_PHYSICAL),                  FN_UNO_IS_PHYSICAL,    &::getBooleanCppuType(), PropertyAttribute::READONLY, 0},
+                    { SW_PROP_NAME(UNO_NAME_DISPLAY_NAME),              FN_UNO_DISPLAY_NAME, &::getCppuType((const OUString*)0), PropertyAttribute::READONLY, 0},
+                    {0,0,0,0}
+                };
+                aMapArr[nPropertyId] = aPageStyleMap;
+            }
+            break;
+            case PROPERTY_MAP_NUM_STYLE  :
+            {
+                static SfxItemPropertyMap aNumStyleMap      [] =
+                {
+                    { SW_PROP_NAME(UNO_NAME_NUMBERING_RULES),       FN_UNO_NUM_RULES,   &::getCppuType((uno::Reference*)0), PROPERTY_NONE, CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_IS_PHYSICAL),           FN_UNO_IS_PHYSICAL,       &::getBooleanCppuType(), PropertyAttribute::READONLY, 0},
+                    { SW_PROP_NAME(UNO_NAME_DISPLAY_NAME),          FN_UNO_DISPLAY_NAME, &::getCppuType((const OUString*)0), PropertyAttribute::READONLY, 0},
+                    {0,0,0,0}
+                };
+                aMapArr[nPropertyId] = aNumStyleMap;
+            }
+            break;
+            case PROPERTY_MAP_TEXT_TABLE :
+            {
+                static SfxItemPropertyMap aTablePropertyMap_Impl[] =
+                {
+                    { SW_PROP_NAME(UNO_NAME_BACK_COLOR       ), RES_BACKGROUND,         &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE,MID_BACK_COLOR         },
+                    { SW_PROP_NAME(UNO_NAME_BREAK_TYPE),            RES_BREAK,              &::getCppuType((const style::BreakType*)0),         PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_URL      ),    RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_URL    },
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_FILTER  ),      RES_BACKGROUND,        &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_FILTER    },
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_LOCATION    ), RES_BACKGROUND,         &::getCppuType((const style::GraphicLocation*)0), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+                    { SW_PROP_NAME(UNO_NAME_LEFT_MARGIN),           RES_LR_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_L_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_RIGHT_MARGIN),          RES_LR_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_R_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_HORI_ORIENT  ),         RES_HORI_ORIENT,        &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE ,MID_HORIORIENT_ORIENT    },
+                    { SW_PROP_NAME(UNO_NAME_KEEP_TOGETHER),         RES_KEEP,               &::getBooleanCppuType()  ,          PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_SPLIT    ),             RES_LAYOUT_SPLIT,       &::getBooleanCppuType()  ,          PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_PAGE_NUMBER_OFFSET),    RES_PAGEDESC,           &::getCppuType((const sal_Int16*)0),        PropertyAttribute::MAYBEVOID, MID_PAGEDESC_PAGENUMOFFSET},
+                    { SW_PROP_NAME(UNO_NAME_PAGE_DESC_NAME),        RES_PAGEDESC,           &::getCppuType((const OUString*)0),         PROPERTY_NONE, 0xff},
+                    { SW_PROP_NAME(UNO_NAME_RELATIVE_WIDTH),        FN_TABLE_RELATIVE_WIDTH,&::getCppuType((const sal_Int16*)0)  ,          PROPERTY_NONE, 0xff },
+                    { SW_PROP_NAME(UNO_NAME_REPEAT_HEADLINE ),      FN_TABLE_HEADLINE_REPEAT,&::getBooleanCppuType(),       PROPERTY_NONE, 0xff},
+                    { SW_PROP_NAME(UNO_NAME_SHADOW_FORMAT),         RES_SHADOW,             &::getCppuType((const table::ShadowFormat*)0),  PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_SIZE_RELATIVE),         FN_TABLE_IS_RELATIVE_WIDTH,  &::getBooleanCppuType()  ,     PROPERTY_NONE, 0xff },
+                    { SW_PROP_NAME(UNO_NAME_TOP_MARGIN),            RES_UL_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_UP_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_BOTTOM_MARGIN),         RES_UL_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_LO_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_TRANSPARENT_BACKGROUND),    RES_BACKGROUND,     &::getBooleanCppuType(),            PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT       },
+                    { SW_PROP_NAME(UNO_NAME_WIDTH),                 FN_TABLE_WIDTH,         &::getCppuType((const sal_Int32*)0)  ,          PROPERTY_NONE, 0xff},
+                    { SW_PROP_NAME(UNO_NAME_CHART_ROW_AS_LABEL),        FN_UNO_RANGE_ROW_LABEL,         &::getBooleanCppuType(),            PROPERTY_NONE,  0},
+                    { SW_PROP_NAME(UNO_NAME_CHART_COLUMN_AS_LABEL),     FN_UNO_RANGE_COL_LABEL,         &::getBooleanCppuType()  ,          PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_TABLE_BORDER),          FN_UNO_TABLE_BORDER,            &::getCppuType((const table::TableBorder*)0),   PropertyAttribute::MAYBEVOID, CONVERT_TWIPS },
+#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) || (defined(__GNUC__) && defined(__APPLE__))
+                    { SW_PROP_NAME(UNO_NAME_TABLE_COLUMN_SEPARATORS),   FN_UNO_TABLE_COLUMN_SEPARATORS, new uno::Type(::getCppuType((const uno::Sequence*)0)),      PropertyAttribute::MAYBEVOID, 0 },
+#else
+                    { SW_PROP_NAME(UNO_NAME_TABLE_COLUMN_SEPARATORS),   FN_UNO_TABLE_COLUMN_SEPARATORS, &::getCppuType((const uno::Sequence*)0),    PropertyAttribute::MAYBEVOID, 0 },
+#endif
+                    { SW_PROP_NAME(UNO_NAME_TABLE_COLUMN_RELATIVE_SUM), FN_UNO_TABLE_COLUMN_RELATIVE_SUM,       &::getCppuType((const sal_Int16*)0),        PropertyAttribute::READONLY, 0 },
+                    { SW_PROP_NAME(UNO_NAME_ANCHOR_TYPE   ),            RES_ANCHOR,             &::getCppuType((const sal_Int16*)0),            PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0xff},
+#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) || (defined(__GNUC__) && defined(__APPLE__))
+                    { SW_PROP_NAME(UNO_NAME_ANCHOR_TYPES   ),   FN_UNO_ANCHOR_TYPES, new uno::Type(::getCppuType((uno::Sequence*)0)),PropertyAttribute::READONLY, 0xff},
+#else
+                    { SW_PROP_NAME(UNO_NAME_ANCHOR_TYPES   ),           FN_UNO_ANCHOR_TYPES,    &::getCppuType((const uno::Sequence*)0),PropertyAttribute::READONLY, 0xff},
+#endif
+                    { SW_PROP_NAME(UNO_NAME_TEXT_WRAP),                 FN_UNO_WRAP,    &::getCppuType((const sal_Int16*)0),                PropertyAttribute::READONLY, 0xff   },
+                    { SW_PROP_NAME(UNO_LINK_DISPLAY_NAME),          FN_PARAM_LINK_DISPLAY_NAME,     &::getCppuType((const OUString*)0), PropertyAttribute::READONLY, 0xff},
+                    { SW_PROP_NAME(UNO_NAME_USER_DEFINED_ATTRIBUTES),       RES_UNKNOWNATR_CONTAINER, &::getCppuType((uno::Reference*)0), PropertyAttribute::MAYBEVOID, 0 },
+                    {0,0}
+                };
+
+                aMapArr[nPropertyId] = aTablePropertyMap_Impl;
+            }
+            break;
+            case PROPERTY_MAP_TABLE_CELL :
+            {
+                static SfxItemPropertyMap aCellMap_Impl[] =
+                {
+                    { SW_PROP_NAME(UNO_NAME_BACK_COLOR       ),     RES_BACKGROUND,     &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE , MID_BACK_COLOR       },
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_URL      ),        RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_URL    },
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_FILTER  ),         RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_FILTER    },
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_LOCATION    ),     RES_BACKGROUND,         &::getCppuType((const style::GraphicLocation*)0), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+                    { SW_PROP_NAME(UNO_NAME_NUMBER_FORMAT),             RES_BOXATR_FORMAT,  &::getCppuType((const sal_Int32*)0),            PropertyAttribute::MAYBEVOID ,0             },
+                    { SW_PROP_NAME(UNO_NAME_TRANSPARENT_BACKGROUND),    RES_BACKGROUND,     &::getBooleanCppuType(),            PROPERTY_NONE , MID_GRAPHIC_TRANSPARENT      },
+                    { SW_PROP_NAME(UNO_NAME_LEFT_BORDER),               RES_BOX,    &::getCppuType((const table::BorderLine*)0),    0, LEFT_BORDER  |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_RIGHT_BORDER),          RES_BOX,    &::getCppuType((const table::BorderLine*)0),    0, RIGHT_BORDER |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_TOP_BORDER),                RES_BOX,    &::getCppuType((const table::BorderLine*)0),    0, TOP_BORDER   |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_BOTTOM_BORDER),         RES_BOX,    &::getCppuType((const table::BorderLine*)0),    0, BOTTOM_BORDER|CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_BORDER_DISTANCE),         RES_BOX,    &::getCppuType((const sal_Int32*)0),  0, BORDER_DISTANCE|CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_LEFT_BORDER_DISTANCE),  RES_BOX,                &::getCppuType((const sal_Int32*)0),    0, LEFT_BORDER_DISTANCE  |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_RIGHT_BORDER_DISTANCE), RES_BOX,                &::getCppuType((const sal_Int32*)0),    0, RIGHT_BORDER_DISTANCE |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_TOP_BORDER_DISTANCE),       RES_BOX,                &::getCppuType((const sal_Int32*)0),    0, TOP_BORDER_DISTANCE   |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_BOTTOM_BORDER_DISTANCE),    RES_BOX,                &::getCppuType((const sal_Int32*)0),    0, BOTTOM_BORDER_DISTANCE|CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_USER_DEFINED_ATTRIBUTES),       RES_UNKNOWNATR_CONTAINER, &::getCppuType((uno::Reference*)0), PropertyAttribute::MAYBEVOID, 0 },
+                    {0,0,0,0}
+                };
+                aMapArr[nPropertyId] = aCellMap_Impl;
+            }
+            break;
+            case PROPERTY_MAP_TABLE_RANGE:
+            {
+                static SfxItemPropertyMap aRangePropertyMap_Impl[] =
+                {
+                    { SW_PROP_NAME(UNO_NAME_CHAR_AUTO_KERNING       ),  RES_CHRATR_AUTOKERN  ,  &::getBooleanCppuType()  ,          PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_CASE_MAP),             RES_CHRATR_CASEMAP,     &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_STRIKEOUT),            RES_CHRATR_CROSSEDOUT,  &::getCppuType((const sal_Int16*)0),                    PropertyAttribute::MAYBEVOID, MID_CROSS_OUT},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_CROSSED_OUT),          RES_CHRATR_CROSSEDOUT,  &::getBooleanCppuType()  ,          PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_ESCAPEMENT),           RES_CHRATR_ESCAPEMENT,  &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE, MID_ESC          },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_ESCAPEMENT_HEIGHT),        RES_CHRATR_ESCAPEMENT,  &::getCppuType((const sal_Int8*)0)  ,       PROPERTY_NONE, MID_ESC_HEIGHT},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_FLASH              ),  RES_CHRATR_BLINK    ,   &::getBooleanCppuType()  ,          PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_HEIGHT),                   RES_CHRATR_FONTSIZE  ,  &::getCppuType((const Float*)0),            PROPERTY_NONE, MID_FONTHEIGHT},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_WEIGHT),                   RES_CHRATR_WEIGHT    ,  &::getCppuType((const Float*)0),    PROPERTY_NONE, MID_WEIGHT},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_FONT_NAME),                RES_CHRATR_FONT,        &::getCppuType((const OUString*)0),  PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY_NAME },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_FONT_STYLE_NAME),          RES_CHRATR_FONT,        &::getCppuType((const OUString*)0), PropertyAttribute::MAYBEVOID, MID_FONT_STYLE_NAME },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_FONT_FAMILY),          RES_CHRATR_FONT,        &::getCppuType((const sal_Int16*)0),                    PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY   },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_FONT_CHAR_SET),            RES_CHRATR_FONT,        &::getCppuType((const sal_Int16*)0),    PropertyAttribute::MAYBEVOID, MID_FONT_CHAR_SET },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_FONT_PITCH),           RES_CHRATR_FONT,        &::getCppuType((const sal_Int16*)0),                    PropertyAttribute::MAYBEVOID, MID_FONT_PITCH   },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_POSTURE),              RES_CHRATR_POSTURE   ,  &::getCppuType((const awt::FontSlant*)0),   PROPERTY_NONE, MID_POSTURE},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_UNDERLINE),            RES_CHRATR_UNDERLINE ,  &::getCppuType((const sal_Int16*)0),    PROPERTY_NONE, MID_UNDERLINE},
+                    { SW_PROP_NAME(UNO_NAME_PARA_LEFT_MARGIN),          RES_LR_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_L_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_PARA_RIGHT_MARGIN),             RES_LR_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_R_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_PARA_FIRST_LINE_INDENT),        RES_LR_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_FIRST_LINE_INDENT|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_KERNING            ),  RES_CHRATR_KERNING    , &::getCppuType((const sal_Int16*)0)  ,          PROPERTY_NONE,  0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_LOCALE         ),      RES_CHRATR_LANGUAGE ,   &::getCppuType((const lang::Locale*)0)  ,       PropertyAttribute::MAYBEVOID,  MID_LANG_LOCALE },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_NO_HYPHENATION     ),  RES_CHRATR_NOHYPHEN ,   &::getBooleanCppuType()  ,          PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_SHADOWED),             RES_CHRATR_SHADOWED  ,  &::getBooleanCppuType()  ,          PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_STYLE_NAME),           RES_TXTATR_CHARFMT,     &::getCppuType((const OUString*)0),         PropertyAttribute::MAYBEVOID,     0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_CONTOURED),            RES_CHRATR_CONTOUR,     &::getBooleanCppuType()  ,          PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_DROP_CAP_FORMAT),           RES_PARATR_DROP,        &::getCppuType((const style::DropCapFormat*)0)  , PROPERTY_NONE, MID_DROPCAP_FORMAT     },
+                    { SW_PROP_NAME(UNO_NAME_DROP_CAP_WHOLE_WORD),       RES_PARATR_DROP,        &::getBooleanCppuType()  ,          PROPERTY_NONE, MID_DROPCAP_WHOLE_WORD },
+                    { SW_PROP_NAME(UNO_NAME_DROP_CAP_CHAR_STYLE_NAME),  RES_PARATR_DROP,        &::getCppuType((const OUString*)0)  ,       PropertyAttribute::MAYBEVOID, MID_DROPCAP_CHAR_STYLE_NAME },
+                    { SW_PROP_NAME(UNO_NAME_PARA_KEEP_TOGETHER  ),      RES_KEEP,               &::getBooleanCppuType()  ,          PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_PARA_SPLIT      ),          RES_PARATR_SPLIT,       &::getBooleanCppuType()  ,          PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_PARA_WIDOWS),               RES_PARATR_WIDOWS,      &::getCppuType((const sal_Int8*)0),PropertyAttribute::MAYBEVOID,     0},
+                    { SW_PROP_NAME(UNO_NAME_PARA_ORPHANS),              RES_PARATR_ORPHANS,      &::getCppuType((const sal_Int8*)0),PropertyAttribute::MAYBEVOID,     0},
+                    { SW_PROP_NAME(UNO_NAME_NUMBER_FORMAT),                 RES_BOXATR_FORMAT,      &::getCppuType((const sal_Int32*)0),            PropertyAttribute::MAYBEVOID ,0             },
+                    { SW_PROP_NAME(UNO_NAME_PAGE_NUMBER_OFFSET),            RES_PAGEDESC,           &::getCppuType((const sal_Int16*)0),        PROPERTY_NONE, MID_PAGEDESC_PAGENUMOFFSET},
+                    { SW_PROP_NAME(UNO_NAME_PARA_ADJUST),                   RES_PARATR_ADJUST,      &::getCppuType((const sal_Int16*)0),        PROPERTY_NONE, MID_PARA_ADJUST},
+                    { SW_PROP_NAME(UNO_NAME_PARA_EXPAND_SINGLE_WORD),     RES_PARATR_ADJUST,      &::getBooleanCppuType()  ,        PROPERTY_NONE, MID_EXPAND_SINGLE   },
+                    { SW_PROP_NAME(UNO_NAME_PARA_LAST_LINE_ADJUST),       RES_PARATR_ADJUST,      &::getCppuType((const sal_Int16*)0),          PROPERTY_NONE, MID_LAST_LINE_ADJUST},
+                    { SW_PROP_NAME(UNO_NAME_PARA_LINE_NUMBER_COUNT  ),  RES_LINENUMBER,         &::getBooleanCppuType(),            PROPERTY_NONE ,MID_LINENUMBER_COUNT     },
+                    { SW_PROP_NAME(UNO_NAME_PARA_LINE_NUMBER_START_VALUE),RES_LINENUMBER,       &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_LINENUMBER_STARTVALUE},
+                    { SW_PROP_NAME(UNO_NAME_PARA_LINE_SPACING),             RES_PARATR_LINESPACING, &::getCppuType((const style::LineSpacing*)0),PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_REGISTER_MODE_ACTIVE),      RES_PARATR_REGISTER,    &::getBooleanCppuType()  ,          PROPERTY_NONE, 0},
+#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) || (defined(__GNUC__) && defined(__APPLE__))
+                    { SW_PROP_NAME(UNO_NAME_TABSTOPS),  RES_PARATR_TABSTOP,  new uno::Type(::getCppuType((uno::Sequence*)0)),       PropertyAttribute::MAYBEVOID, CONVERT_TWIPS},
+#else
+                    { SW_PROP_NAME(UNO_NAME_TABSTOPS),                  RES_PARATR_TABSTOP,     &::getCppuType((const uno::Sequence*)0),        PropertyAttribute::MAYBEVOID, CONVERT_TWIPS},
+#endif
+                    { SW_PROP_NAME(UNO_NAME_TOP_MARGIN),                RES_UL_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_UP_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_BOTTOM_MARGIN),             RES_UL_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_LO_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_WORD_MODE           ),          RES_CHRATR_WORDLINEMODE,&::getBooleanCppuType()  ,          PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_COLOR),                    RES_CHRATR_COLOR,       &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_BACK_COLOR      ),     RES_CHRATR_BACKGROUND,  &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE|PropertyAttribute::MAYBEVOID ,MID_BACK_COLOR       },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_TRANSPARENT_BACKGROUND),   RES_CHRATR_BACKGROUND,  &::getBooleanCppuType(),            PROPERTY_NONE|PropertyAttribute::MAYBEVOID ,MID_GRAPHIC_TRANSPARENT      },
+                    { SW_PROP_NAME(UNO_NAME_PARA_BACK_COLOR      ),     RES_BACKGROUND,         &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE|PropertyAttribute::MAYBEVOID ,MID_BACK_COLOR       },
+                    { SW_PROP_NAME(UNO_NAME_PARA_TRANSPARENT_BACKGROUND),   RES_BACKGROUND,         &::getBooleanCppuType(),            PROPERTY_NONE|PropertyAttribute::MAYBEVOID ,MID_GRAPHIC_TRANSPARENT      },
+                    { SW_PROP_NAME(UNO_NAME_PARA_GRAPHIC_URL      ),        RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_URL    },
+                    { SW_PROP_NAME(UNO_NAME_PARA_GRAPHIC_FILTER  ),         RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_FILTER    },
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_URL      ),            RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_URL    },
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_FILTER  ),             RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_FILTER    },
+                    { SW_PROP_NAME(UNO_NAME_PARA_GRAPHIC_LOCATION    ),     RES_BACKGROUND,         &::getCppuType((const style::GraphicLocation*)0), PROPERTY_NONE|PropertyAttribute::MAYBEVOID ,MID_GRAPHIC_POSITION},
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_LOCATION    ),             FN_UNO_TABLE_CELL_BACKGROUND,   &::getCppuType((const style::GraphicLocation*)0), PROPERTY_NONE|PropertyAttribute::MAYBEVOID ,MID_GRAPHIC_POSITION},
+                    { SW_PROP_NAME(UNO_NAME_BACK_COLOR       ),         FN_UNO_TABLE_CELL_BACKGROUND,   &::getCppuType((const sal_Int32*)0),    PROPERTY_NONE|PropertyAttribute::MAYBEVOID ,MID_BACK_COLOR       },
+                    { SW_PROP_NAME(UNO_NAME_TRANSPARENT_BACKGROUND ),       FN_UNO_TABLE_CELL_BACKGROUND,   &::getBooleanCppuType(),    PROPERTY_NONE|PropertyAttribute::MAYBEVOID ,MID_GRAPHIC_TRANSPARENT      },
+                    { SW_PROP_NAME(UNO_NAME_CHART_ROW_AS_LABEL),            FN_UNO_RANGE_ROW_LABEL, &::getBooleanCppuType(),            PROPERTY_NONE,  0},
+                    { SW_PROP_NAME(UNO_NAME_CHART_COLUMN_AS_LABEL),         FN_UNO_RANGE_COL_LABEL, &::getBooleanCppuType()  ,          PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_PARA_STYLE_NAME),           FN_UNO_PARA_STYLE,      &::getCppuType((const OUString*)0),         PROPERTY_NONE,     0},
+                    {0,0,0,0}
+                };
+                aMapArr[nPropertyId] = aRangePropertyMap_Impl;
+            }
+            break;
+            case PROPERTY_MAP_SECTION:
+            {
+                static SfxItemPropertyMap aSectionPropertyMap_Impl[] =
+                {
+                    { SW_PROP_NAME(UNO_NAME_CONDITION),         WID_SECT_CONDITION, &::getCppuType((const OUString*)0)  ,       PROPERTY_NONE,     0},
+                #ifdef DDE_AVAILABLE
+                    { SW_PROP_NAME(UNO_NAME_DDE_COMMAND_FILE),  WID_SECT_DDE_TYPE, &::getCppuType((const OUString*)0)  ,        PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_DDE_COMMAND_TYPE),  WID_SECT_DDE_FILE, &::getCppuType((const OUString*)0)  ,        PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_DDE_COMMAND_ELEMENT), WID_SECT_DDE_ELEMENT, &::getCppuType((const OUString*)0)  ,       PROPERTY_NONE,     0},
+                #endif
+                    { SW_PROP_NAME(UNO_NAME_FILE_LINK),         WID_SECT_LINK     , &::getCppuType((const text::SectionFileLink*)0),    PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_IS_VISIBLE),        WID_SECT_VISIBLE   , &::getBooleanCppuType(),           PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_IS_PROTECTED),  WID_SECT_PROTECTED, &::getBooleanCppuType(),            PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_LINK_REGION),   WID_SECT_REGION   , &::getCppuType((const OUString*)0)  ,       PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_TEXT_COLUMNS),          RES_COL,                &::getCppuType((uno::Reference*)0),    PROPERTY_NONE, MID_COLUMNS},
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_URL      ),    RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_URL    },
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_FILTER  ),     RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_FILTER    },
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_LOCATION    ), RES_BACKGROUND,         &::getCppuType((const style::GraphicLocation*)0),           PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+                    { SW_PROP_NAME(UNO_NAME_BACK_COLOR       ),     RES_BACKGROUND,         &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_BACK_COLOR        },
+                    { SW_PROP_NAME(UNO_NAME_TRANSPARENT_BACKGROUND ),   RES_BACKGROUND,         &::getBooleanCppuType(),            PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT       },
+                    { SW_PROP_NAME(UNO_LINK_DISPLAY_NAME),          FN_PARAM_LINK_DISPLAY_NAME,     &::getCppuType((const OUString*)0), PropertyAttribute::READONLY, 0xff},
+                    { SW_PROP_NAME(UNO_NAME_USER_DEFINED_ATTRIBUTES),       RES_UNKNOWNATR_CONTAINER, &::getCppuType((uno::Reference*)0), PropertyAttribute::MAYBEVOID, 0 },
+                    {0,0,0,0}
+                };
+                aMapArr[nPropertyId] = aSectionPropertyMap_Impl;
+            }
+            break;
+            case PROPERTY_MAP_TEXT_SEARCH:
+            {
+                static SfxItemPropertyMap aSearchPropertyMap_Impl[] =
+                {
+                    { SW_PROP_NAME(UNO_NAME_SEARCH_ALL),                    WID_SEARCH_ALL,         &::getBooleanCppuType()  ,      PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_SEARCH_BACKWARDS          ),    WID_BACKWARDS,          &::getBooleanCppuType()  ,      PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_SEARCH_CASE_SENSITIVE     ),    WID_CASE_SENSITIVE,     &::getBooleanCppuType()  ,      PROPERTY_NONE,     0},
+                //  { SW_PROP_NAME(UNO_NAME_SEARCH_IN_SELECTION       ),    WID_IN_SELECTION,       &::getBooleanCppuType()  ,      PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_SEARCH_REGULAR_EXPRESSION ),    WID_REGULAR_EXPRESSION, &::getBooleanCppuType()  ,      PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_SEARCH_SIMILARITY         ),    WID_SIMILARITY,         &::getBooleanCppuType()  ,      PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_SEARCH_SIMILARITY_ADD     ),    WID_SIMILARITY_ADD,     &::getCppuType((const sal_Int16*)0)  ,  PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_SEARCH_SIMILARITY_EXCHANGE),    WID_SIMILARITY_EXCHANGE,&::getCppuType((const sal_Int16*)0)  ,  PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_SEARCH_SIMILARITY_RELAX   ),    WID_SIMILARITY_RELAX,   &::getBooleanCppuType()  ,      PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_SEARCH_SIMILARITY_REMOVE  ),    WID_SIMILARITY_REMOVE,  &::getCppuType((const sal_Int16*)0)  ,  PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_SEARCH_STYLES             ),    WID_STYLES,             &::getBooleanCppuType()  ,      PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_SEARCH_WORDS                  ),    WID_WORDS,              &::getBooleanCppuType()  ,      PROPERTY_NONE,     0},
+                    {0,0,0,0}
+                };
+                aMapArr[nPropertyId] = aSearchPropertyMap_Impl;
+            }
+            break;
+            case PROPERTY_MAP_TEXT_FRAME:
+            {
+                static SfxItemPropertyMap aFramePropertyMap_Impl[] =
+                {
+                    { SW_PROP_NAME(UNO_NAME_ANCHOR_PAGE_NO),            RES_ANCHOR,             &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE, MID_ANCHOR_PAGENUM       },
+                    { SW_PROP_NAME(UNO_NAME_ANCHOR_TYPE   ),            RES_ANCHOR,             &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE, MID_ANCHOR_ANCHORTYPE},
+#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) || (defined(__GNUC__) && defined(__APPLE__))
+                    { SW_PROP_NAME(UNO_NAME_ANCHOR_TYPES   ),   FN_UNO_ANCHOR_TYPES, new uno::Type(::getCppuType((uno::Sequence*)0)),PropertyAttribute::READONLY, 0xff},
+#else
+                    { SW_PROP_NAME(UNO_NAME_ANCHOR_TYPES   ),           FN_UNO_ANCHOR_TYPES,    &::getCppuType((const uno::Sequence*)0),PropertyAttribute::READONLY, 0xff},
+#endif
+                    { SW_PROP_NAME(UNO_NAME_BACK_COLOR       ),     RES_BACKGROUND,         &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_BACK_COLOR        },
+                    { SW_PROP_NAME(UNO_NAME_CHAIN_NEXT_NAME),           RES_CHAIN,              &::getCppuType((const OUString*)0),         PropertyAttribute::MAYBEVOID ,MID_CHAIN_NEXTNAME},
+                    { SW_PROP_NAME(UNO_NAME_CHAIN_PREV_NAME),           RES_CHAIN,              &::getCppuType((const OUString*)0),         PropertyAttribute::MAYBEVOID ,MID_CHAIN_PREVNAME},
+                /*not impl*/    { SW_PROP_NAME(UNO_NAME_CLIENT_MAP      ),      RES_URL,                &::getBooleanCppuType(),            PROPERTY_NONE ,MID_URL_CLIENTMAP         },
+                    { SW_PROP_NAME(UNO_NAME_CONTENT_PROTECTED ),        RES_PROTECT,            &::getBooleanCppuType(),            PROPERTY_NONE, MID_PROTECT_CONTENT   },
+                    { SW_PROP_NAME(UNO_NAME_EDIT_IN_READONLY),      RES_EDIT_IN_READONLY,   &::getBooleanCppuType(),            PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_FRAME_STYLE_NAME),          0,                      &::getCppuType((const OUString*)0),         PROPERTY_NONE, 0},
+                //  { SW_PROP_NAME(UNO_NAME_GRAPHIC           ),        RES_BACKGROUND,         &,                              PROPERTY_NONE, MID_GRAPHIC
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_URL      ),    RES_BACKGROUND,         &::getCppuType((const OUString*)0),         PROPERTY_NONE ,MID_GRAPHIC_URL    },
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_FILTER  ),     RES_BACKGROUND,         &::getCppuType((const OUString*)0),         PROPERTY_NONE ,MID_GRAPHIC_FILTER    },
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_LOCATION    ), RES_BACKGROUND,         &::getCppuType((const style::GraphicLocation*)0), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+                    { SW_PROP_NAME(UNO_NAME_LEFT_MARGIN),           RES_LR_SPACE,           &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE, MID_L_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_RIGHT_MARGIN),          RES_LR_SPACE,           &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE, MID_R_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_HEIGHT),                    RES_FRM_SIZE,           &::getCppuType((const sal_Int32*)0)  ,          PROPERTY_NONE, MID_FRMSIZE_HEIGHT|CONVERT_TWIPS         },
+                    { SW_PROP_NAME(UNO_NAME_SIZE_TYPE),                 RES_FRM_SIZE,           &::getCppuType((const sal_Int16*)0)  ,          PROPERTY_NONE,   MID_FRMSIZE_SIZE_TYPE  },
+                    { SW_PROP_NAME(UNO_NAME_HORI_ORIENT  ),             RES_HORI_ORIENT,        &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE ,MID_HORIORIENT_ORIENT    },
+                    { SW_PROP_NAME(UNO_NAME_HORI_ORIENT_POSITION),  RES_HORI_ORIENT,        &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_HORIORIENT_POSITION|CONVERT_TWIPS    },
+                    { SW_PROP_NAME(UNO_NAME_HORI_ORIENT_RELATION),  RES_HORI_ORIENT,        &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE ,MID_HORIORIENT_RELATION  },
+                    { SW_PROP_NAME(UNO_NAME_HYPER_LINK_U_R_L   ),       RES_URL,                &::getCppuType((const OUString*)0),         PROPERTY_NONE ,MID_URL_URL},
+                    { SW_PROP_NAME(UNO_NAME_HYPER_LINK_TARGET  ),       RES_URL,                &::getCppuType((const OUString*)0),         PROPERTY_NONE ,MID_URL_TARGET},
+                    { SW_PROP_NAME(UNO_NAME_HYPER_LINK_NAME ),      RES_URL,                &::getCppuType((const OUString*)0),         PROPERTY_NONE ,MID_URL_HYPERLINKNAME     },
+                    { SW_PROP_NAME(UNO_NAME_OPAQUE),                    RES_OPAQUE,             &::getBooleanCppuType(),            PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_PAGE_TOGGLE),               RES_HORI_ORIENT,        &::getBooleanCppuType(),            PROPERTY_NONE ,MID_HORIORIENT_PAGETOGGLE },
+                    { SW_PROP_NAME(UNO_NAME_POSITION_PROTECTED),    RES_PROTECT,            &::getBooleanCppuType(),            PROPERTY_NONE, MID_PROTECT_POSITION},
+                    { SW_PROP_NAME(UNO_NAME_PRINT),                     RES_PRINT,              &::getBooleanCppuType(),            PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_RELATIVE_HEIGHT),       RES_FRM_SIZE,           &::getCppuType((const sal_Int8*)0)  ,       PROPERTY_NONE,   MID_FRMSIZE_REL_HEIGHT },
+                    { SW_PROP_NAME(UNO_NAME_RELATIVE_WIDTH),            RES_FRM_SIZE,           &::getCppuType((const sal_Int8*)0)  ,       PROPERTY_NONE,   MID_FRMSIZE_REL_WIDTH  },
+                    { SW_PROP_NAME(UNO_NAME_SHADOW_FORMAT),             RES_SHADOW,             &::getCppuType((const table::ShadowFormat*)0),  PROPERTY_NONE, CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_SERVER_MAP      ),      RES_URL,                &::getBooleanCppuType(),            PROPERTY_NONE ,MID_URL_SERVERMAP         },
+                    { SW_PROP_NAME(UNO_NAME_SIZE),                  RES_FRM_SIZE,           &::getCppuType((const awt::Size*)0),            PROPERTY_NONE, MID_FRMSIZE_SIZE|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_SIZE_PROTECTED    ),    RES_PROTECT,            &::getBooleanCppuType(),            PROPERTY_NONE, MID_PROTECT_SIZE    },
+                    { SW_PROP_NAME(UNO_NAME_SIZE_RELATIVE),             RES_FRM_SIZE,           &::getBooleanCppuType()  ,          PROPERTY_NONE,   MID_FRMSIZE_IS_SYNC_REL_SIZE   },
+                    { SW_PROP_NAME(UNO_NAME_TEXT_WRAP),                 RES_SURROUND,           &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE, MID_SURROUND_SURROUNDTYPE    },
+                    { SW_PROP_NAME(UNO_NAME_SURROUND                  ), RES_SURROUND,          &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE, MID_SURROUND_SURROUNDTYPE    },
+                    { SW_PROP_NAME(UNO_NAME_SURROUND_ANCHORONLY),   RES_SURROUND,           &::getBooleanCppuType(),            PROPERTY_NONE, MID_SURROUND_ANCHORONLY      },
+                    { SW_PROP_NAME(UNO_NAME_TEXT_COLUMNS),          RES_COL,                &::getCppuType((uno::Reference*)0),    PROPERTY_NONE, MID_COLUMNS},
+                    //MID_COLUMN_SEPARATOR_LINE ???
+                    { SW_PROP_NAME(UNO_NAME_TOP_MARGIN),                RES_UL_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_UP_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_BOTTOM_MARGIN),             RES_UL_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_LO_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_TRANSPARENT_BACKGROUND ),   RES_BACKGROUND,         &::getBooleanCppuType(),            PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT       },
+                    { SW_PROP_NAME(UNO_NAME_VERT_ORIENT  ),             RES_VERT_ORIENT,        &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE ,MID_VERTORIENT_ORIENT    },
+                    { SW_PROP_NAME(UNO_NAME_VERT_ORIENT_POSITION),  RES_VERT_ORIENT,        &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_VERTORIENT_POSITION|CONVERT_TWIPS    },
+                    { SW_PROP_NAME(UNO_NAME_VERT_ORIENT_RELATION),  RES_VERT_ORIENT,        &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE ,MID_VERTORIENT_RELATION  },
+                    { SW_PROP_NAME(UNO_NAME_WIDTH),                     RES_FRM_SIZE,           &::getCppuType((const sal_Int32*)0)  ,          PROPERTY_NONE, MID_FRMSIZE_WIDTH|CONVERT_TWIPS          },
+                    { SW_PROP_NAME(UNO_NAME_LEFT_BORDER),               RES_BOX,                &::getCppuType((const table::BorderLine*)0),    0, LEFT_BORDER  |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_RIGHT_BORDER),          RES_BOX,                &::getCppuType((const table::BorderLine*)0),    0, RIGHT_BORDER |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_TOP_BORDER),                RES_BOX,                &::getCppuType((const table::BorderLine*)0),    0, TOP_BORDER   |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_BOTTOM_BORDER),         RES_BOX,                &::getCppuType((const table::BorderLine*)0),    0, BOTTOM_BORDER|CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_BORDER_DISTANCE),         RES_BOX,              &::getCppuType((const sal_Int32*)0),    0, BORDER_DISTANCE|CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_LEFT_BORDER_DISTANCE),  RES_BOX,                &::getCppuType((const sal_Int32*)0),    0, LEFT_BORDER_DISTANCE  |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_RIGHT_BORDER_DISTANCE), RES_BOX,                &::getCppuType((const sal_Int32*)0),    0, RIGHT_BORDER_DISTANCE |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_TOP_BORDER_DISTANCE),       RES_BOX,                &::getCppuType((const sal_Int32*)0),    0, TOP_BORDER_DISTANCE   |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_BOTTOM_BORDER_DISTANCE),    RES_BOX,                &::getCppuType((const sal_Int32*)0),    0, BOTTOM_BORDER_DISTANCE|CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_LINK_DISPLAY_NAME),          FN_PARAM_LINK_DISPLAY_NAME,     &::getCppuType((const OUString*)0), PropertyAttribute::READONLY, 0xff},
+                    //next elements are part of the service description
+                    { MAP_CHAR_LEN("FrameHeightAbsolute"),          RES_FRM_SIZE,           &::getCppuType((const sal_Int32*)0),        PROPERTY_NONE, MID_FRMSIZE_HEIGHT|CONVERT_TWIPS         },
+                    { MAP_CHAR_LEN("FrameHeightPercent"),               RES_FRM_SIZE,           &::getCppuType((const sal_Int8*)0),         PROPERTY_NONE, MID_FRMSIZE_REL_HEIGHT   },
+                    { MAP_CHAR_LEN("FrameIsAutomaticHeight"),         RES_FRM_SIZE,         &::getBooleanCppuType(),        PROPERTY_NONE, MID_FRMSIZE_IS_AUTO_HEIGHT   },
+                    { MAP_CHAR_LEN("FrameWidthAbsolute"),           RES_FRM_SIZE,           &::getCppuType((const sal_Int32*)0),        PROPERTY_NONE, MID_FRMSIZE_WIDTH|CONVERT_TWIPS          },
+                    { MAP_CHAR_LEN("FrameWidthPercent"),                RES_FRM_SIZE,           &::getCppuType((const sal_Int8*)0),         PROPERTY_NONE, MID_FRMSIZE_REL_WIDTH    },
+                    { SW_PROP_NAME(UNO_NAME_USER_DEFINED_ATTRIBUTES),       RES_UNKNOWNATR_CONTAINER, &::getCppuType((uno::Reference*)0), PropertyAttribute::MAYBEVOID, 0 },
+                    {0,0,0,0}
+                };
+                aMapArr[nPropertyId] = aFramePropertyMap_Impl;
+            }
+            break;
+            case PROPERTY_MAP_TEXT_GRAPHIC:
+            {
+                static SfxItemPropertyMap aGraphicPropertyMap_Impl[] =
+                {
+                    { SW_PROP_NAME(UNO_NAME_ANCHOR_PAGE_NO),            RES_ANCHOR,             &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE, MID_ANCHOR_PAGENUM       },
+#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) || (defined(__GNUC__) && defined(__APPLE__))
+                    { SW_PROP_NAME(UNO_NAME_ANCHOR_TYPES   ),   FN_UNO_ANCHOR_TYPES, new uno::Type(::getCppuType((uno::Sequence*)0)),PropertyAttribute::READONLY, 0xff},
+#else
+                    { SW_PROP_NAME(UNO_NAME_ANCHOR_TYPES   ),           FN_UNO_ANCHOR_TYPES,    &::getCppuType((const uno::Sequence*)0),PropertyAttribute::READONLY, 0xff},
+#endif
+                    { SW_PROP_NAME(UNO_NAME_ANCHOR_TYPE   ),            RES_ANCHOR,             &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE, MID_ANCHOR_ANCHORTYPE},
+                    { SW_PROP_NAME(UNO_NAME_BACK_COLOR       ),     RES_BACKGROUND,         &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_BACK_COLOR        },
+                    { SW_PROP_NAME(UNO_NAME_CLIENT_MAP      ),      RES_URL,                &::getBooleanCppuType(),            PROPERTY_NONE ,MID_URL_CLIENTMAP         },
+                    { SW_PROP_NAME(UNO_NAME_CONTENT_PROTECTED ),        RES_PROTECT,            &::getBooleanCppuType(),            PROPERTY_NONE, MID_PROTECT_CONTENT   },
+                    { SW_PROP_NAME(UNO_NAME_CONTOUR_OUTSIDE),       RES_SURROUND,           &::getBooleanCppuType(),            PROPERTY_NONE, MID_SURROUND_CONTOUROUTSIDE  },
+                    { SW_PROP_NAME(UNO_NAME_FRAME_STYLE_NAME),          0,                      &::getCppuType((const OUString*)0),         PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_GRAPHIC_CROP),          RES_GRFATR_CROPGRF,     &::getCppuType((const text::GraphicCrop*)0),    PROPERTY_NONE, CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_HORI_MIRRORED),             RES_GRFATR_MIRRORGRF,   &::getBooleanCppuType(),            PROPERTY_NONE,      MID_MIRROR_HORZ           },
+                    { SW_PROP_NAME(UNO_NAME_HEIGHT),                    RES_FRM_SIZE,           &::getCppuType((const sal_Int32*)0)  ,          PROPERTY_NONE, MID_FRMSIZE_HEIGHT|CONVERT_TWIPS         },
+                    { SW_PROP_NAME(UNO_NAME_HORI_ORIENT  ),             RES_HORI_ORIENT,        &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE ,MID_HORIORIENT_ORIENT    },
+                    { SW_PROP_NAME(UNO_NAME_HORI_ORIENT_POSITION),  RES_HORI_ORIENT,        &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_HORIORIENT_POSITION|CONVERT_TWIPS    },
+                    { SW_PROP_NAME(UNO_NAME_HORI_ORIENT_RELATION),  RES_HORI_ORIENT,        &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE ,MID_HORIORIENT_RELATION  },
+                    { SW_PROP_NAME(UNO_NAME_HYPER_LINK_U_R_L   ),       RES_URL,                &::getCppuType((const OUString*)0),         PROPERTY_NONE ,MID_URL_URL},
+                    { SW_PROP_NAME(UNO_NAME_HYPER_LINK_TARGET  ),       RES_URL,                &::getCppuType((const OUString*)0),         PROPERTY_NONE ,MID_URL_TARGET},
+                    { SW_PROP_NAME(UNO_NAME_HYPER_LINK_NAME ),      RES_URL,                &::getCppuType((const OUString*)0),         PROPERTY_NONE ,MID_URL_HYPERLINKNAME     },
+                    { SW_PROP_NAME(UNO_NAME_LEFT_MARGIN),           RES_LR_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_L_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_RIGHT_MARGIN),          RES_LR_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_R_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_MIRROR_PAGE_TOGGLE),    RES_GRFATR_MIRRORGRF,   &::getBooleanCppuType(),            PROPERTY_NONE, MID_MIRROR_HORZ_PAGETOGGLE},
+                    { SW_PROP_NAME(UNO_NAME_OPAQUE),                    RES_OPAQUE,             &::getBooleanCppuType(),            PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_PAGE_TOGGLE),               RES_HORI_ORIENT,        &::getBooleanCppuType(),            PROPERTY_NONE ,MID_HORIORIENT_PAGETOGGLE },
+                    { SW_PROP_NAME(UNO_NAME_POSITION_PROTECTED),    RES_PROTECT,            &::getBooleanCppuType(),            PROPERTY_NONE, MID_PROTECT_POSITION},
+                    { SW_PROP_NAME(UNO_NAME_PRINT),                     RES_PRINT,              &::getBooleanCppuType(),            PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_RELATIVE_HEIGHT),       RES_FRM_SIZE,           &::getCppuType((const sal_Int8*)0)  ,       PROPERTY_NONE,   MID_FRMSIZE_REL_HEIGHT },
+                    { SW_PROP_NAME(UNO_NAME_RELATIVE_WIDTH),            RES_FRM_SIZE,           &::getCppuType((const sal_Int8*)0)  ,       PROPERTY_NONE,   MID_FRMSIZE_REL_WIDTH  },
+                    { SW_PROP_NAME(UNO_NAME_SERVER_MAP      ),      RES_URL,                &::getBooleanCppuType(),            PROPERTY_NONE ,MID_URL_SERVERMAP         },
+                    { SW_PROP_NAME(UNO_NAME_SHADOW_FORMAT),             RES_SHADOW,             &::getCppuType((const table::ShadowFormat*)0),  PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_SIZE),                  RES_FRM_SIZE,           &::getCppuType((const awt::Size*)0),            PROPERTY_NONE, MID_FRMSIZE_SIZE|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_SIZE_RELATIVE),             RES_FRM_SIZE,           &::getBooleanCppuType()  ,          PROPERTY_NONE,   MID_FRMSIZE_IS_SYNC_REL_SIZE   },
+                    { SW_PROP_NAME(UNO_NAME_SIZE_PROTECTED    ),    RES_PROTECT,            &::getBooleanCppuType(),            PROPERTY_NONE, MID_PROTECT_SIZE    },
+                    { SW_PROP_NAME(UNO_NAME_TEXT_WRAP),                 RES_SURROUND,           &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE, MID_SURROUND_SURROUNDTYPE    },
+                    { SW_PROP_NAME(UNO_NAME_SURROUND                  ), RES_SURROUND,          &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE, MID_SURROUND_SURROUNDTYPE    },
+                    { SW_PROP_NAME(UNO_NAME_SURROUND_ANCHORONLY),   RES_SURROUND,           &::getBooleanCppuType(),            PROPERTY_NONE, MID_SURROUND_ANCHORONLY      },
+                    { SW_PROP_NAME(UNO_NAME_SURROUND_CONTOUR     ),     RES_SURROUND,           &::getBooleanCppuType(),            PROPERTY_NONE, MID_SURROUND_CONTOUR         },
+                    { SW_PROP_NAME(UNO_NAME_TOP_MARGIN),                RES_UL_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_UP_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_BOTTOM_MARGIN),             RES_UL_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_LO_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_TRANSPARENT_BACKGROUND ),   RES_BACKGROUND,         &::getBooleanCppuType(),            PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT       },
+                    { SW_PROP_NAME(UNO_NAME_VERT_MIRRORED),         RES_GRFATR_MIRRORGRF,   &::getBooleanCppuType(),            PROPERTY_NONE,     MID_MIRROR_VERT            },
+                    { SW_PROP_NAME(UNO_NAME_VERT_ORIENT  ),             RES_VERT_ORIENT,        &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE ,MID_VERTORIENT_ORIENT    },
+                    { SW_PROP_NAME(UNO_NAME_VERT_ORIENT_POSITION),  RES_VERT_ORIENT,        &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_VERTORIENT_POSITION|CONVERT_TWIPS    },
+                    { SW_PROP_NAME(UNO_NAME_VERT_ORIENT_RELATION),  RES_VERT_ORIENT,        &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE ,MID_VERTORIENT_RELATION  },
+                    { SW_PROP_NAME(UNO_NAME_WIDTH),                     RES_FRM_SIZE,           &::getCppuType((const sal_Int32*)0)  ,          PROPERTY_NONE, MID_FRMSIZE_WIDTH            },
+                    { SW_PROP_NAME(UNO_NAME_LEFT_BORDER),               RES_BOX,                &::getCppuType((const table::BorderLine*)0),    0, LEFT_BORDER  |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_RIGHT_BORDER),          RES_BOX,                &::getCppuType((const table::BorderLine*)0),    0, RIGHT_BORDER |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_TOP_BORDER),                RES_BOX,                &::getCppuType((const table::BorderLine*)0),    0, TOP_BORDER   |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_BOTTOM_BORDER),         RES_BOX,                &::getCppuType((const table::BorderLine*)0),    0, BOTTOM_BORDER|CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_BORDER_DISTANCE),         RES_BOX,              &::getCppuType((const sal_Int32*)0),    0, BORDER_DISTANCE|CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_LEFT_BORDER_DISTANCE),  RES_BOX,                &::getCppuType((const sal_Int32*)0),    0, LEFT_BORDER_DISTANCE  |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_RIGHT_BORDER_DISTANCE), RES_BOX,                &::getCppuType((const sal_Int32*)0),    0, RIGHT_BORDER_DISTANCE |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_TOP_BORDER_DISTANCE),       RES_BOX,                &::getCppuType((const sal_Int32*)0),    0, TOP_BORDER_DISTANCE   |CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_BOTTOM_BORDER_DISTANCE),    RES_BOX,                &::getCppuType((const sal_Int32*)0),    0, BOTTOM_BORDER_DISTANCE|CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_GRAPHIC_URL),               0,                      &::getCppuType((const OUString*)0), 0, 0 },
+                    { SW_PROP_NAME(UNO_NAME_GRAPHIC_FILTER),            0,                      &::getCppuType((const OUString*)0), 0, 0 },
+                    { SW_PROP_NAME(UNO_NAME_ACTUAL_SIZE),           0,                      &::getCppuType((const awt::Size*)0),    PropertyAttribute::READONLY, CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_ALTERNATIVE_TEXT),      0,                      &::getCppuType((const OUString*)0),         PROPERTY_NONE , 0   },
+                    { SW_PROP_NAME(UNO_LINK_DISPLAY_NAME),          FN_PARAM_LINK_DISPLAY_NAME,     &::getCppuType((const OUString*)0), PropertyAttribute::READONLY, 0xff},
+                    { SW_PROP_NAME(UNO_NAME_USER_DEFINED_ATTRIBUTES),       RES_UNKNOWNATR_CONTAINER, &::getCppuType((uno::Reference*)0), PropertyAttribute::MAYBEVOID, 0 },
+                    {0,0,0,0}
+                };
+                aMapArr[nPropertyId] = aGraphicPropertyMap_Impl;
+            }
+            break;
+            case PROPERTY_MAP_TEXT_SHAPE:
+            {
+                static SfxItemPropertyMap aShapeMap_Impl[] =
+                {
+                    { SW_PROP_NAME(UNO_NAME_ANCHOR_PAGE_NO),            RES_ANCHOR,             &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE|PropertyAttribute::MAYBEVOID, MID_ANCHOR_PAGENUM      },
+                    { SW_PROP_NAME(UNO_NAME_ANCHOR_TYPE   ),            RES_ANCHOR,             &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE|PropertyAttribute::MAYBEVOID, MID_ANCHOR_ANCHORTYPE},
+                    { SW_PROP_NAME(UNO_NAME_HORI_ORIENT  ),             RES_HORI_ORIENT,        &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE|PropertyAttribute::MAYBEVOID ,MID_HORIORIENT_ORIENT   },
+                    { SW_PROP_NAME(UNO_NAME_HORI_ORIENT_POSITION),  RES_HORI_ORIENT,        &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE|PropertyAttribute::MAYBEVOID ,MID_HORIORIENT_POSITION|CONVERT_TWIPS   },
+                    { SW_PROP_NAME(UNO_NAME_HORI_ORIENT_RELATION),  RES_HORI_ORIENT,        &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE|PropertyAttribute::MAYBEVOID ,MID_HORIORIENT_RELATION },
+                    { SW_PROP_NAME(UNO_NAME_LEFT_MARGIN),           RES_LR_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE|PropertyAttribute::MAYBEVOID, MID_L_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_RIGHT_MARGIN),          RES_LR_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE|PropertyAttribute::MAYBEVOID, MID_R_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_SURROUND                  ), RES_SURROUND,          &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE|PropertyAttribute::MAYBEVOID, MID_SURROUND_SURROUNDTYPE   },
+                    { SW_PROP_NAME(UNO_NAME_TEXT_WRAP),                 RES_SURROUND,           &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE, MID_SURROUND_SURROUNDTYPE    },
+                    { SW_PROP_NAME(UNO_NAME_SURROUND_ANCHORONLY),   RES_SURROUND,           &::getBooleanCppuType(),            PROPERTY_NONE|PropertyAttribute::MAYBEVOID, MID_SURROUND_ANCHORONLY     },
+                    { SW_PROP_NAME(UNO_NAME_TOP_MARGIN),                RES_UL_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_UP_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_BOTTOM_MARGIN),             RES_UL_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_LO_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_VERT_ORIENT  ),             RES_VERT_ORIENT,        &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE|PropertyAttribute::MAYBEVOID ,MID_VERTORIENT_ORIENT   },
+                    { SW_PROP_NAME(UNO_NAME_VERT_ORIENT_POSITION),  RES_VERT_ORIENT,        &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE|PropertyAttribute::MAYBEVOID ,MID_VERTORIENT_POSITION|CONVERT_TWIPS   },
+                    { SW_PROP_NAME(UNO_NAME_VERT_ORIENT_RELATION),  RES_VERT_ORIENT,        &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE|PropertyAttribute::MAYBEVOID ,MID_VERTORIENT_RELATION },
+                    { SW_PROP_NAME(UNO_NAME_TEXT_RANGE),                FN_TEXT_RANGE,          &::getCppuType((uno::Reference*)0),       PROPERTY_NONE, 0},
+                    {0,0,0,0}
+                };
+                aMapArr[nPropertyId] = aShapeMap_Impl;
+            }
+            break;
+            case PROPERTY_MAP_INDEX_MARK:
+            {
+                static SfxItemPropertyMap aIdxMarkMap_Impl[] =
+                {
+                    { SW_PROP_NAME(UNO_NAME_ALTERNATIVE_TEXT),WID_ALT_TEXT,         &::getCppuType((const OUString*)0)  ,       PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_PRIMARY_KEY),       WID_PRIMARY_KEY,    &::getCppuType((const OUString*)0)  ,       PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_SECONDARY_KEY),   WID_SECONDARY_KEY,    &::getCppuType((const OUString*)0)  ,       PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_ANCHOR_TYPE   ),    0,  &::getCppuType((const sal_Int16*)0),                PropertyAttribute::READONLY, MID_ANCHOR_ANCHORTYPE},
+#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) || (defined(__GNUC__) && defined(__APPLE__))
+                    { SW_PROP_NAME(UNO_NAME_ANCHOR_TYPES   ),   FN_UNO_ANCHOR_TYPES, new uno::Type(::getCppuType((uno::Sequence*)0)),PropertyAttribute::READONLY, 0xff},
+#else
+                    { SW_PROP_NAME(UNO_NAME_ANCHOR_TYPES   ),           FN_UNO_ANCHOR_TYPES,    &::getCppuType((const uno::Sequence*)0),PropertyAttribute::READONLY, 0xff},
+#endif
+                    { SW_PROP_NAME(UNO_NAME_TEXT_WRAP),         0,  &::getCppuType((const sal_Int16*)0),                PropertyAttribute::READONLY, MID_SURROUND_SURROUNDTYPE  },
+                    {0,0,0,0}
+                };
+                aMapArr[nPropertyId] = aIdxMarkMap_Impl;
+            }
+            break;
+            case PROPERTY_MAP_CNTIDX_MARK:
+            {
+                static SfxItemPropertyMap aCntntMarkMap_Impl[] =
+                {
+                    { SW_PROP_NAME(UNO_NAME_ALTERNATIVE_TEXT),WID_ALT_TEXT,         &::getCppuType((const OUString*)0)  ,       PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_LEVEL        ),   WID_LEVEL        ,    &::getCppuType((const sal_Int16*)0)  ,      PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_ANCHOR_TYPE   ),    0,  &::getCppuType((const sal_Int16*)0),                PropertyAttribute::READONLY, MID_ANCHOR_ANCHORTYPE},
+#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) || (defined(__GNUC__) && defined(__APPLE__))
+                    { SW_PROP_NAME(UNO_NAME_ANCHOR_TYPES   ),   FN_UNO_ANCHOR_TYPES, new uno::Type(::getCppuType((uno::Sequence*)0)),PropertyAttribute::READONLY, 0xff},
+#else
+                    { SW_PROP_NAME(UNO_NAME_ANCHOR_TYPES   ),           FN_UNO_ANCHOR_TYPES,    &::getCppuType((const uno::Sequence*)0),PropertyAttribute::READONLY, 0xff},
+#endif
+                    { SW_PROP_NAME(UNO_NAME_TEXT_WRAP),         0,  &::getCppuType((const sal_Int16*)0),                PropertyAttribute::READONLY, MID_SURROUND_SURROUNDTYPE  },
+                    {0,0,0,0}
+                };
+                aMapArr[nPropertyId] = aCntntMarkMap_Impl;
+            }
+            break;
+            case PROPERTY_MAP_USER_MARK:
+            {
+                static SfxItemPropertyMap aUserMarkMap_Impl[] =
+                {
+                    { SW_PROP_NAME(UNO_NAME_ALTERNATIVE_TEXT),WID_ALT_TEXT,         &::getCppuType((const OUString*)0)  ,       PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_USER_INDEX_NAME), WID_USER_IDX_NAME,    &::getCppuType((const OUString*)0)  ,       PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_ANCHOR_TYPE   ),    0,  &::getCppuType((const sal_Int16*)0),                PropertyAttribute::READONLY, MID_ANCHOR_ANCHORTYPE},
+#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) || (defined(__GNUC__) && defined(__APPLE__))
+                    { SW_PROP_NAME(UNO_NAME_ANCHOR_TYPES   ),   FN_UNO_ANCHOR_TYPES, new uno::Type(::getCppuType((uno::Sequence*)0)),PropertyAttribute::READONLY, 0xff},
+#else
+                    { SW_PROP_NAME(UNO_NAME_ANCHOR_TYPES   ),           FN_UNO_ANCHOR_TYPES,    &::getCppuType((const uno::Sequence*)0),PropertyAttribute::READONLY, 0xff},
+#endif
+                    { SW_PROP_NAME(UNO_NAME_TEXT_WRAP),         0,  &::getCppuType((const sal_Int16*)0),                PropertyAttribute::READONLY, MID_SURROUND_SURROUNDTYPE  },
+                    {0,0,0,0}
+                };
+                aMapArr[nPropertyId] = aUserMarkMap_Impl;
+            }
+            break;
+            case PROPERTY_MAP_INDEX_IDX:
+            {
+                static SfxItemPropertyMap aTOXIndexMap_Impl[] =
+                {
+                    { SW_PROP_NAME(UNO_NAME_TITLE                                ),   WID_IDX_TITLE                                ,  &::getCppuType((const OUString*)0)  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_CREATE_FROM_CHAPTER               ),   WID_CREATE_FROM_CHAPTER                 ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_IS_PROTECTED                         ),   WID_PROTECTED                           ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_USE_ALPHABETICAL_SEPARATORS       ),   WID_USE_ALPHABETICAL_SEPARATORS         ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_USE_KEY_AS_ENTRY                  ),   WID_USE_KEY_AS_ENTRY                    ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_USE_COMBINED_ENTRIES              ),   WID_USE_COMBINED_ENTRIES                ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_IS_CASE_SENSITIVE                 ),   WID_IS_CASE_SENSITIVE                   ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_USE_P_P                           ),   WID_USE_P_P                             ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_USE_DASH                          ),   WID_USE_DASH                            ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_USE_UPPER_CASE                    ),   WID_USE_UPPER_CASE                      ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_LEVEL_FORMAT                      ),   WID_LEVEL_FORMAT                        ,  &::getCppuType((uno::Reference*)0)  , PROPERTY_NONE,    0},
+                //  { SW_PROP_NAME(UNO_NAME_???                               ),   WID_???                                 ,  &_getReflection  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_MAIN_ENTRY_CHARACTER_STYLE_NAME   ),   WID_MAIN_ENTRY_CHARACTER_STYLE_NAME     ,  &::getCppuType((const OUString*)0)  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_TEXT_COLUMNS),          RES_COL,                &::getCppuType((uno::Reference*)0),    PROPERTY_NONE, MID_COLUMNS},
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_URL      ),    RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_URL    },
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_FILTER  ),     RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_FILTER    },
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_LOCATION    ), RES_BACKGROUND,         &::getCppuType((const style::GraphicLocation*)0),           PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+                    { SW_PROP_NAME(UNO_NAME_BACK_COLOR       ),     RES_BACKGROUND,         &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_BACK_COLOR        },
+                    { SW_PROP_NAME(UNO_NAME_TRANSPARENT_BACKGROUND ),   RES_BACKGROUND,         &::getBooleanCppuType(),            PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT       },
+                    { MAP_CHAR_LEN("ParaStyleHeading"),                 WID_PARA_HEAD,          &::getCppuType((const OUString*)0)  , 0,     0},
+                    { MAP_CHAR_LEN("ParaStyleSeparator"),           WID_PARA_SEP,           &::getCppuType((const OUString*)0)  , 0,     0},
+                    { MAP_CHAR_LEN("ParaStyleLevel1"),              WID_PARA_LEV1,          &::getCppuType((const OUString*)0)  , 0,     0},
+                    { MAP_CHAR_LEN("ParaStyleLevel2"),              WID_PARA_LEV2,          &::getCppuType((const OUString*)0)  , 0,     0},
+                    { MAP_CHAR_LEN("ParaStyleLevel3"),              WID_PARA_LEV3,          &::getCppuType((const OUString*)0)  , 0,     0},
+                    { SW_PROP_NAME(UNO_NAME_IS_COMMA_SEPARATED),        WID_IS_COMMA_SEPARATED, &::getBooleanCppuType(),            PROPERTY_NONE ,0         },
+                    {0,0,0,0}
+                };
+                aMapArr[nPropertyId] = aTOXIndexMap_Impl;
+            }
+            break;
+            case PROPERTY_MAP_INDEX_CNTNT:
+            {
+                static SfxItemPropertyMap aTOXContentMap_Impl[] =
+                {
+                    { SW_PROP_NAME(UNO_NAME_TITLE                                ), WID_IDX_TITLE                                  ,  &::getCppuType((const OUString*)0)  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_LEVEL                             ), WID_LEVEL                               ,  &::getCppuType((const sal_Int16*)0)  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_CREATE_FROM_MARKS                 ), WID_CREATE_FROM_MARKS                   ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_CREATE_FROM_OUTLINE               ), WID_CREATE_FROM_OUTLINE                 ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                //  { SW_PROP_NAME(UNO_NAME_PARAGRAPH_STYLE_NAMES             ), WID_PARAGRAPH_STYLE_NAMES               ,  &::getCppuType((uno::Reference*)0)  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_CREATE_FROM_CHAPTER               ), WID_CREATE_FROM_CHAPTER                 ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_IS_PROTECTED                         ), WID_PROTECTED                           ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_LEVEL_FORMAT                      ), WID_LEVEL_FORMAT                        ,  &::getCppuType((uno::Reference*)0)  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_LEVEL_PARAGRAPH_STYLES            ), WID_LEVEL_PARAGRAPH_STYLES              ,  &::getCppuType((uno::Reference*)0)  , PropertyAttribute::READONLY,     0},
+                //  { SW_PROP_NAME(UNO_NAME_RECALC_TAB_STOPS                  ), WID_RECALC_TAB_STOPS                    ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                //  { SW_PROP_NAME(UNO_NAME_???                               ), WID_???                                 ,  &_getReflection  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_TEXT_COLUMNS),          RES_COL,                &::getCppuType((uno::Reference*)0),    PROPERTY_NONE, MID_COLUMNS},
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_URL      ),        RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_URL    },
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_FILTER  ),         RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_FILTER    },
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_LOCATION    ),     RES_BACKGROUND,         &::getCppuType((const style::GraphicLocation*)0),           PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+                    { SW_PROP_NAME(UNO_NAME_BACK_COLOR       ),     RES_BACKGROUND,         &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_BACK_COLOR        },
+                    { SW_PROP_NAME(UNO_NAME_TRANSPARENT_BACKGROUND ),   RES_BACKGROUND,         &::getBooleanCppuType(),            PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT       },
+                    { MAP_CHAR_LEN("ParaStyleHeading"),     WID_PARA_HEAD,  &::getCppuType((const OUString*)0)  , 0,     0},
+                    { MAP_CHAR_LEN("ParaStyleLevel1"),  WID_PARA_LEV1,  &::getCppuType((const OUString*)0)  , 0,     0},
+                    { MAP_CHAR_LEN("ParaStyleLevel2"),  WID_PARA_LEV2,  &::getCppuType((const OUString*)0)  , 0,     0},
+                    { MAP_CHAR_LEN("ParaStyleLevel3"),  WID_PARA_LEV3,  &::getCppuType((const OUString*)0)  , 0,     0},
+                    { MAP_CHAR_LEN("ParaStyleLevel4"),  WID_PARA_LEV4,  &::getCppuType((const OUString*)0)  , 0,     0},
+                    { MAP_CHAR_LEN("ParaStyleLevel5"),  WID_PARA_LEV5,  &::getCppuType((const OUString*)0)  , 0,     0},
+                    { MAP_CHAR_LEN("ParaStyleLevel6"),  WID_PARA_LEV6,  &::getCppuType((const OUString*)0)  , 0,     0},
+                    { MAP_CHAR_LEN("ParaStyleLevel7"),  WID_PARA_LEV7,  &::getCppuType((const OUString*)0)  , 0,     0},
+                    { MAP_CHAR_LEN("ParaStyleLevel8"),  WID_PARA_LEV8,  &::getCppuType((const OUString*)0)  , 0,     0},
+                    { MAP_CHAR_LEN("ParaStyleLevel9"),  WID_PARA_LEV9,  &::getCppuType((const OUString*)0)  , 0,     0},
+                    { MAP_CHAR_LEN("ParaStyleLevel10"),     WID_PARA_LEV10,     &::getCppuType((const OUString*)0)  , 0,     0},
+                    {0,0,0,0}
+                };
+                aMapArr[nPropertyId] = aTOXContentMap_Impl;
+            }
+            break;
+            case PROPERTY_MAP_INDEX_USER:
+            {
+                static SfxItemPropertyMap aTOXUserMap_Impl[] =
+                {
+                    { SW_PROP_NAME(UNO_NAME_TITLE                                ), WID_IDX_TITLE                                  ,  &::getCppuType((const OUString*)0)  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_CREATE_FROM_MARKS                 ), WID_CREATE_FROM_MARKS                   ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                //  { SW_PROP_NAME(UNO_NAME_PARAGRAPH_STYLE_NAMES             ), WID_PARAGRAPH_STYLE_NAMES               ,  &::getCppuType((uno::Reference*)0)  , PROPERTY_NONE,0},
+                    { SW_PROP_NAME(UNO_NAME_CREATE_FROM_CHAPTER               ), WID_CREATE_FROM_CHAPTER                 ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_IS_PROTECTED                         ), WID_PROTECTED                           ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_USE_LEVEL_FROM_SOURCE             ), WID_USE_LEVEL_FROM_SOURCE               ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_LEVEL_FORMAT                      ), WID_LEVEL_FORMAT                        ,  &::getCppuType((uno::Reference*)0)  , PROPERTY_NONE,0},
+                    { SW_PROP_NAME(UNO_NAME_LEVEL_PARAGRAPH_STYLES            ), WID_LEVEL_PARAGRAPH_STYLES              ,  &::getCppuType((uno::Reference*)0)  , PropertyAttribute::READONLY,0},
+                    { SW_PROP_NAME(UNO_NAME_CREATE_FROM_TABLES                ), WID_CREATE_FROM_TABLES                  ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_CREATE_FROM_TEXT_FRAMES           ), WID_CREATE_FROM_TEXT_FRAMES             ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_CREATE_FROM_GRAPHIC_OBJECTS       ), WID_CREATE_FROM_GRAPHIC_OBJECTS         ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_CREATE_FROM_EMBEDDED_OBJECTS      ), WID_CREATE_FROM_EMBEDDED_OBJECTS        ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_TEXT_COLUMNS),          RES_COL,                &::getCppuType((uno::Reference*)0),    PROPERTY_NONE, MID_COLUMNS},
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_URL      ),        RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_URL    },
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_FILTER  ),         RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_FILTER    },
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_LOCATION    ),         RES_BACKGROUND,         &::getCppuType((const style::GraphicLocation*)0),           PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+                    { SW_PROP_NAME(UNO_NAME_BACK_COLOR       ),     RES_BACKGROUND,         &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_BACK_COLOR        },
+                    { SW_PROP_NAME(UNO_NAME_TRANSPARENT_BACKGROUND ),   RES_BACKGROUND,         &::getBooleanCppuType(),            PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT       },
+                    { MAP_CHAR_LEN("ParaStyleHeading"),     WID_PARA_HEAD,  &::getCppuType((const OUString*)0)  , 0,     0},
+                    { MAP_CHAR_LEN("ParaStyleLevel1"),  WID_PARA_LEV1,  &::getCppuType((const OUString*)0)  , 0,     0},
+                    { MAP_CHAR_LEN("ParaStyleLevel2"),  WID_PARA_LEV2,  &::getCppuType((const OUString*)0)  , 0,     0},
+                    { MAP_CHAR_LEN("ParaStyleLevel3"),  WID_PARA_LEV3,  &::getCppuType((const OUString*)0)  , 0,     0},
+                    { MAP_CHAR_LEN("ParaStyleLevel4"),  WID_PARA_LEV4,  &::getCppuType((const OUString*)0)  , 0,     0},
+                    { MAP_CHAR_LEN("ParaStyleLevel5"),  WID_PARA_LEV5,  &::getCppuType((const OUString*)0)  , 0,     0},
+                    { MAP_CHAR_LEN("ParaStyleLevel6"),  WID_PARA_LEV6,  &::getCppuType((const OUString*)0)  , 0,     0},
+                    { MAP_CHAR_LEN("ParaStyleLevel7"),  WID_PARA_LEV7,  &::getCppuType((const OUString*)0)  , 0,     0},
+                    { MAP_CHAR_LEN("ParaStyleLevel8"),  WID_PARA_LEV8,  &::getCppuType((const OUString*)0)  , 0,     0},
+                    { MAP_CHAR_LEN("ParaStyleLevel9"),  WID_PARA_LEV9,  &::getCppuType((const OUString*)0)  , 0,     0},
+                    { MAP_CHAR_LEN("ParaStyleLevel10"),     WID_PARA_LEV10,     &::getCppuType((const OUString*)0)  , 0,     0},
+                    {0,0,0,0}
+                };
+                aMapArr[nPropertyId] = aTOXUserMap_Impl;
+            }
+            break;
+            case PROPERTY_MAP_INDEX_TABLES:
+            {
+                static SfxItemPropertyMap aTOXTablesMap_Impl[] =
+                {
+                    { SW_PROP_NAME(UNO_NAME_TITLE                                ), WID_IDX_TITLE                                  ,  &::getCppuType((const OUString*)0)  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_CREATE_FROM_CHAPTER               ), WID_CREATE_FROM_CHAPTER                 ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_CREATE_FROM_LABELS                ), WID_CREATE_FROM_LABELS                  ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_IS_PROTECTED                         ), WID_PROTECTED                           ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_LABEL_CATEGORY                    ), WID_LABEL_CATEGORY                      ,  &::getCppuType((const OUString*)0)  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_LABEL_DISPLAY_TYPE                ), WID_LABEL_DISPLAY_TYPE                  ,  &::getCppuType((const sal_Int16*)0)  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_LEVEL_FORMAT                      ), WID_LEVEL_FORMAT                        ,  &::getCppuType((uno::Reference*)0)  , PROPERTY_NONE,0},
+                    { SW_PROP_NAME(UNO_NAME_TEXT_COLUMNS),          RES_COL,                &::getCppuType((uno::Reference*)0),    PROPERTY_NONE, MID_COLUMNS},
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_URL      ),        RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_URL    },
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_FILTER  ),         RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_FILTER    },
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_LOCATION    ),         RES_BACKGROUND,         &::getCppuType((const style::GraphicLocation*)0),           PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+                    { SW_PROP_NAME(UNO_NAME_BACK_COLOR       ),     RES_BACKGROUND,         &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_BACK_COLOR        },
+                    { SW_PROP_NAME(UNO_NAME_TRANSPARENT_BACKGROUND ),   RES_BACKGROUND,         &::getBooleanCppuType(),            PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT       },
+                    { MAP_CHAR_LEN("ParaStyleHeading"),     WID_PARA_HEAD,  &::getCppuType((const OUString*)0)  , 0,     0},
+                    { MAP_CHAR_LEN("ParaStyleLevel1"),  WID_PARA_LEV1,  &::getCppuType((const OUString*)0)  , 0,     0},
+                    {0,0,0,0}
+                };
+                aMapArr[nPropertyId] = aTOXTablesMap_Impl;
+            }
+            break;
+            case PROPERTY_MAP_INDEX_OBJECTS:
+            {
+                static SfxItemPropertyMap aTOXObjectsMap_Impl[] =
+                {
+                    { SW_PROP_NAME(UNO_NAME_TITLE                                ), WID_IDX_TITLE                                  ,  &::getCppuType((const OUString*)0)  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_CREATE_FROM_CHAPTER               ), WID_CREATE_FROM_CHAPTER                 ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_IS_PROTECTED                         ), WID_PROTECTED                           ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_USE_ALPHABETICAL_SEPARATORS       ), WID_USE_ALPHABETICAL_SEPARATORS         ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_LEVEL_FORMAT                      ), WID_LEVEL_FORMAT                        ,  &::getCppuType((uno::Reference*)0)  , PROPERTY_NONE,0},
+                    { SW_PROP_NAME(UNO_NAME_CREATE_FROM_STAR_MATH             ), WID_CREATE_FROM_STAR_MATH               ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_CREATE_FROM_STAR_IMAGE            ), WID_CREATE_FROM_STAR_IMAGE              ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_CREATE_FROM_STAR_CHART            ), WID_CREATE_FROM_STAR_CHART              ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_CREATE_FROM_STAR_CALC             ), WID_CREATE_FROM_STAR_CALC               ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_CREATE_FROM_STAR_DRAW             ), WID_CREATE_FROM_STAR_DRAW               ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_CREATE_FROM_OTHER_EMBEDDED_OBJECTS), WID_CREATE_FROM_OTHER_EMBEDDED_OBJECTS  ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_TEXT_COLUMNS),          RES_COL,                &::getCppuType((uno::Reference*)0),    PROPERTY_NONE, MID_COLUMNS},
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_URL      ),        RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_URL    },
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_FILTER  ),         RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_FILTER    },
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_LOCATION    ),         RES_BACKGROUND,         &::getCppuType((const style::GraphicLocation*)0),           PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+                    { SW_PROP_NAME(UNO_NAME_BACK_COLOR       ),     RES_BACKGROUND,         &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_BACK_COLOR        },
+                    { SW_PROP_NAME(UNO_NAME_TRANSPARENT_BACKGROUND ),   RES_BACKGROUND,         &::getBooleanCppuType(),            PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT       },
+                    { MAP_CHAR_LEN("ParaStyleHeading"),     WID_PARA_HEAD,  &::getCppuType((const OUString*)0)  , 0,     0},
+                    { MAP_CHAR_LEN("ParaStyleLevel1"),  WID_PARA_LEV1,  &::getCppuType((const OUString*)0)  , 0,     0},
+                    {0,0,0,0}
+                };
+                aMapArr[nPropertyId] = aTOXObjectsMap_Impl;
+            }
+            break;
+            case PROPERTY_MAP_INDEX_ILLUSTRATIONS:
+            {
+                static SfxItemPropertyMap aTOXIllustrationsMap_Impl[] =
+                {
+                    { SW_PROP_NAME(UNO_NAME_TITLE                                ), WID_IDX_TITLE                                  ,  &::getCppuType((const OUString*)0)  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_CREATE_FROM_CHAPTER               ), WID_CREATE_FROM_CHAPTER                 ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_CREATE_FROM_LABELS                ), WID_CREATE_FROM_LABELS                  ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_IS_PROTECTED                         ), WID_PROTECTED                           ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_USE_ALPHABETICAL_SEPARATORS       ), WID_USE_ALPHABETICAL_SEPARATORS         ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_LABEL_CATEGORY                    ), WID_LABEL_CATEGORY                      ,  &::getCppuType((const OUString*)0)  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_LABEL_DISPLAY_TYPE                ), WID_LABEL_DISPLAY_TYPE                  ,  &::getCppuType((const sal_Int16*)0)  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_LEVEL_FORMAT                      ), WID_LEVEL_FORMAT                        ,  &::getCppuType((uno::Reference*)0)  , PROPERTY_NONE,0},
+                    { SW_PROP_NAME(UNO_NAME_TEXT_COLUMNS),          RES_COL,                &::getCppuType((uno::Reference*)0),    PROPERTY_NONE, MID_COLUMNS},
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_URL      ),        RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_URL    },
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_FILTER  ),         RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_FILTER    },
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_LOCATION    ),         RES_BACKGROUND,         &::getCppuType((const style::GraphicLocation*)0),           PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+                    { SW_PROP_NAME(UNO_NAME_BACK_COLOR       ),     RES_BACKGROUND,         &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_BACK_COLOR        },
+                    { SW_PROP_NAME(UNO_NAME_TRANSPARENT_BACKGROUND ),   RES_BACKGROUND,         &::getBooleanCppuType(),            PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT       },
+                    { MAP_CHAR_LEN("ParaStyleHeading"),     WID_PARA_HEAD,  &::getCppuType((const OUString*)0)  , 0,     0},
+                    { MAP_CHAR_LEN("ParaStyleLevel1"),  WID_PARA_LEV1,  &::getCppuType((const OUString*)0)  , 0,     0},
+                    {0,0,0,0}
+                };
+                aMapArr[nPropertyId] = aTOXIllustrationsMap_Impl;
+            }
+            break;
+            case PROPERTY_MAP_TEXT_TABLE_ROW:
+            {
+                static SfxItemPropertyMap aTableRowPropertyMap_Impl[] =
+                {
+                    { SW_PROP_NAME(UNO_NAME_BACK_COLOR       ),     RES_BACKGROUND,         &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_BACK_COLOR        },
+                    { SW_PROP_NAME(UNO_NAME_VERT_ORIENT  ),             RES_VERT_ORIENT,        &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE ,MID_VERTORIENT_ORIENT    },
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_URL      ),        RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_URL    },
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_FILTER  ),         RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_FILTER    },
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_LOCATION    ),         RES_BACKGROUND,         &::getCppuType((const style::GraphicLocation*)0),           PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+                    { SW_PROP_NAME(UNO_NAME_TRANSPARENT_BACKGROUND ),   RES_BACKGROUND,         &::getBooleanCppuType(),            PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT       },
+#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) || (defined(__GNUC__) && defined(__APPLE__))
+                    { SW_PROP_NAME(UNO_NAME_TABLE_COLUMN_SEPARATORS),   FN_UNO_TABLE_COLUMN_SEPARATORS, new uno::Type(::getCppuType((const uno::Sequence*)0)),      PropertyAttribute::MAYBEVOID, 0 },
+#else
+                    { SW_PROP_NAME(UNO_NAME_TABLE_COLUMN_SEPARATORS),   FN_UNO_TABLE_COLUMN_SEPARATORS, &::getCppuType((const uno::Sequence*)0),    PropertyAttribute::MAYBEVOID, 0 },
+#endif
+                    { SW_PROP_NAME(UNO_NAME_HEIGHT),                FN_UNO_ROW_HEIGHT,      &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,CONVERT_TWIPS },
+                    { SW_PROP_NAME(UNO_NAME_IS_AUTO_HEIGHT),            FN_UNO_ROW_AUTO_HEIGHT, &::getBooleanCppuType(),            PROPERTY_NONE , 0 },
+                    { SW_PROP_NAME(UNO_NAME_SIZE_TYPE),                 RES_FRM_SIZE,           &::getCppuType((const sal_Int16*)0)  ,          PROPERTY_NONE,   MID_FRMSIZE_SIZE_TYPE  },
+                //  { SW_PROP_NAME(UNO_NAME_HEIGHT),                    RES_FRM_SIZE,           &::getCppuType((const sal_Int32*)0)  ,          PROPERTY_NONE, MID_FRMSIZE_HEIGHT|CONVERT_TWIPS         },
+                //  { SW_PROP_NAME(UNO_NAME_SHADOW_FORMAT),             RES_SHADOW,             &::getCppuType((const table::ShadowFormat*)0),  PROPERTY_NONE, CONVERT_TWIPS},
+                    {0,0,0,0}
+                };
+                aMapArr[nPropertyId] = aTableRowPropertyMap_Impl;
+            }
+            break;
+            case PROPERTY_MAP_TEXT_TABLE_CURSOR:
+            {
+                // das PropertySet entspricht dem Range ohne Chart-Properties
+                static SfxItemPropertyMap aTableCursorPropertyMap_Impl [] =
+                {
+                    { SW_PROP_NAME(UNO_NAME_CHAR_AUTO_KERNING       ),  RES_CHRATR_AUTOKERN  ,  &::getBooleanCppuType()  ,          PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_CASE_MAP),             RES_CHRATR_CASEMAP,     &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_STRIKEOUT),            RES_CHRATR_CROSSEDOUT,  &::getCppuType((const sal_Int16*)0),                    PropertyAttribute::MAYBEVOID, MID_CROSS_OUT},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_CROSSED_OUT),          RES_CHRATR_CROSSEDOUT,  &::getBooleanCppuType()  ,          PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_ESCAPEMENT),           RES_CHRATR_ESCAPEMENT,  &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE, MID_ESC          },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_ESCAPEMENT_HEIGHT),        RES_CHRATR_ESCAPEMENT,  &::getCppuType((const sal_Int8*)0)  ,       PROPERTY_NONE, MID_ESC_HEIGHT},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_FLASH              ),  RES_CHRATR_BLINK    ,   &::getBooleanCppuType()  ,          PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_HEIGHT),                   RES_CHRATR_FONTSIZE  ,  &::getCppuType((const Float*)0),            PROPERTY_NONE, MID_FONTHEIGHT},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_FONT_NAME),                RES_CHRATR_FONT,        &::getCppuType((const OUString*)0),  PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY_NAME },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_FONT_STYLE_NAME),          RES_CHRATR_FONT,        &::getCppuType((const OUString*)0), PropertyAttribute::MAYBEVOID, MID_FONT_STYLE_NAME },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_FONT_FAMILY),          RES_CHRATR_FONT,        &::getCppuType((const sal_Int16*)0),                    PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY   },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_FONT_CHAR_SET),            RES_CHRATR_FONT,        &::getCppuType((const sal_Int16*)0),    PropertyAttribute::MAYBEVOID, MID_FONT_CHAR_SET },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_FONT_PITCH),           RES_CHRATR_FONT,        &::getCppuType((const sal_Int16*)0),                    PropertyAttribute::MAYBEVOID, MID_FONT_PITCH   },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_WEIGHT),                   RES_CHRATR_WEIGHT    ,  &::getCppuType((const Float*)0),    PROPERTY_NONE, MID_WEIGHT},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_POSTURE),              RES_CHRATR_POSTURE   ,  &::getCppuType((const awt::FontSlant*)0),   PROPERTY_NONE, MID_POSTURE},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_UNDERLINE),            RES_CHRATR_UNDERLINE ,  &::getCppuType((const sal_Int16*)0),    PROPERTY_NONE, MID_UNDERLINE},
+                    { SW_PROP_NAME(UNO_NAME_PARA_LEFT_MARGIN),          RES_LR_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_L_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_PARA_RIGHT_MARGIN),             RES_LR_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_R_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_PARA_FIRST_LINE_INDENT),        RES_LR_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_FIRST_LINE_INDENT|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_KERNING            ),  RES_CHRATR_KERNING    , &::getCppuType((const sal_Int16*)0)  ,          PROPERTY_NONE,  0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_LOCALE         ),      RES_CHRATR_LANGUAGE ,   &::getCppuType((const lang::Locale*)0)  ,       PropertyAttribute::MAYBEVOID,  MID_LANG_LOCALE },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_NO_HYPHENATION     ),  RES_CHRATR_NOHYPHEN ,   &::getBooleanCppuType()  ,          PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_SHADOWED),             RES_CHRATR_SHADOWED  ,  &::getBooleanCppuType()  ,          PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_STYLE_NAME),           RES_TXTATR_CHARFMT,     &::getCppuType((const OUString*)0),         PropertyAttribute::MAYBEVOID,     0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_CONTOURED),                RES_CHRATR_CONTOUR,     &::getBooleanCppuType()  ,          PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_DROP_CAP_FORMAT),           RES_PARATR_DROP,        &::getCppuType((const style::DropCapFormat*)0)  , PROPERTY_NONE, MID_DROPCAP_FORMAT     },
+                    { SW_PROP_NAME(UNO_NAME_DROP_CAP_WHOLE_WORD),       RES_PARATR_DROP,        &::getBooleanCppuType()  ,          PROPERTY_NONE, MID_DROPCAP_WHOLE_WORD },
+                    { SW_PROP_NAME(UNO_NAME_DROP_CAP_CHAR_STYLE_NAME),  RES_PARATR_DROP,        &::getCppuType((const OUString*)0)  ,       PropertyAttribute::MAYBEVOID, MID_DROPCAP_CHAR_STYLE_NAME },
+                    { SW_PROP_NAME(UNO_NAME_PARA_KEEP_TOGETHER  ),      RES_KEEP,               &::getBooleanCppuType()  ,          PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_PARA_SPLIT      ),          RES_PARATR_SPLIT,       &::getBooleanCppuType()  ,          PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_PARA_WIDOWS),               RES_PARATR_WIDOWS,      &::getCppuType((const sal_Int8*)0),PropertyAttribute::MAYBEVOID,     0},
+                    { SW_PROP_NAME(UNO_NAME_PARA_ORPHANS),              RES_PARATR_ORPHANS,      &::getCppuType((const sal_Int8*)0),PropertyAttribute::MAYBEVOID,     0},
+                    { SW_PROP_NAME(UNO_NAME_NUMBER_FORMAT),                 RES_BOXATR_FORMAT,      &::getCppuType((const sal_Int32*)0),            PropertyAttribute::MAYBEVOID ,0             },
+                    { SW_PROP_NAME(UNO_NAME_PAGE_NUMBER_OFFSET),            RES_PAGEDESC,           &::getCppuType((const sal_Int16*)0),        PROPERTY_NONE, MID_PAGEDESC_PAGENUMOFFSET},
+                    { SW_PROP_NAME(UNO_NAME_PARA_ADJUST),                   RES_PARATR_ADJUST,      &::getCppuType((const sal_Int16*)0),        PROPERTY_NONE, MID_PARA_ADJUST},
+                    { SW_PROP_NAME(UNO_NAME_PARA_EXPAND_SINGLE_WORD),     RES_PARATR_ADJUST,      &::getBooleanCppuType()  ,        PROPERTY_NONE, MID_EXPAND_SINGLE   },
+                    { SW_PROP_NAME(UNO_NAME_PARA_LAST_LINE_ADJUST),       RES_PARATR_ADJUST,      &::getCppuType((const sal_Int16*)0),          PROPERTY_NONE, MID_LAST_LINE_ADJUST},
+                    { SW_PROP_NAME(UNO_NAME_PARA_LINE_NUMBER_COUNT  ),  RES_LINENUMBER,         &::getBooleanCppuType(),            PROPERTY_NONE ,MID_LINENUMBER_COUNT     },
+                    { SW_PROP_NAME(UNO_NAME_PARA_LINE_NUMBER_START_VALUE),RES_LINENUMBER,       &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_LINENUMBER_STARTVALUE},
+                    { SW_PROP_NAME(UNO_NAME_PARA_LINE_SPACING),             RES_PARATR_LINESPACING, &::getCppuType((const style::LineSpacing*)0),PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_REGISTER_MODE_ACTIVE),      RES_PARATR_REGISTER,    &::getBooleanCppuType()  ,          PROPERTY_NONE, 0},
+#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) || (defined(__GNUC__) && defined(__APPLE__))
+                    { SW_PROP_NAME(UNO_NAME_TABSTOPS),  RES_PARATR_TABSTOP,  new uno::Type(::getCppuType((uno::Sequence*)0)),       PropertyAttribute::MAYBEVOID, CONVERT_TWIPS},
+#else
+                    { SW_PROP_NAME(UNO_NAME_TABSTOPS),                  RES_PARATR_TABSTOP,     &::getCppuType((const uno::Sequence*)0),        PropertyAttribute::MAYBEVOID, CONVERT_TWIPS},
+#endif
+                    { SW_PROP_NAME(UNO_NAME_TOP_MARGIN),                RES_UL_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_UP_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_BOTTOM_MARGIN),             RES_UL_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_LO_MARGIN|CONVERT_TWIPS},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_COLOR),                    RES_CHRATR_COLOR,       &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE, 0},
+                    { SW_PROP_NAME(UNO_NAME_CHAR_BACK_COLOR      ),     RES_CHRATR_BACKGROUND,  &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE|PropertyAttribute::MAYBEVOID ,MID_BACK_COLOR       },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_TRANSPARENT_BACKGROUND),   RES_CHRATR_BACKGROUND,  &::getBooleanCppuType(),            PROPERTY_NONE|PropertyAttribute::MAYBEVOID ,MID_GRAPHIC_TRANSPARENT      },
+                    { SW_PROP_NAME(UNO_NAME_PARA_BACK_COLOR      ),     RES_BACKGROUND,         &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE|PropertyAttribute::MAYBEVOID ,MID_BACK_COLOR       },
+                    { SW_PROP_NAME(UNO_NAME_PARA_TRANSPARENT_BACKGROUND),   RES_BACKGROUND,         &::getBooleanCppuType(),            PROPERTY_NONE|PropertyAttribute::MAYBEVOID ,MID_GRAPHIC_TRANSPARENT      },
+                    { SW_PROP_NAME(UNO_NAME_PARA_GRAPHIC_URL      ),        RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_URL    },
+                    { SW_PROP_NAME(UNO_NAME_PARA_GRAPHIC_FILTER  ),         RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_FILTER    },
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_URL      ),            RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_URL    },
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_FILTER  ),             RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_FILTER    },
+                    { SW_PROP_NAME(UNO_NAME_PARA_GRAPHIC_LOCATION    ),     RES_BACKGROUND,         &::getCppuType((const style::GraphicLocation*)0), PROPERTY_NONE|PropertyAttribute::MAYBEVOID ,MID_GRAPHIC_POSITION},
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_LOCATION    ),             FN_UNO_TABLE_CELL_BACKGROUND,   &::getCppuType((const style::GraphicLocation*)0), PROPERTY_NONE|PropertyAttribute::MAYBEVOID ,MID_GRAPHIC_POSITION},
+                    { SW_PROP_NAME(UNO_NAME_BACK_COLOR       ),         FN_UNO_TABLE_CELL_BACKGROUND,   &::getCppuType((const sal_Int32*)0),    PROPERTY_NONE|PropertyAttribute::MAYBEVOID ,MID_BACK_COLOR       },
+                    { SW_PROP_NAME(UNO_NAME_TRANSPARENT_BACKGROUND ),       FN_UNO_TABLE_CELL_BACKGROUND,   &::getBooleanCppuType(),    PROPERTY_NONE|PropertyAttribute::MAYBEVOID ,MID_GRAPHIC_TRANSPARENT      },
+                    { SW_PROP_NAME(UNO_NAME_WORD_MODE           ),          RES_CHRATR_WORDLINEMODE,&::getBooleanCppuType()  ,          PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_PARA_STYLE_NAME),           FN_UNO_PARA_STYLE,      &::getCppuType((const OUString*)0),         PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_PARA_USER_DEFINED_ATTRIBUTES),  RES_TXTATR_UNKNOWN_CONTAINER, &::getCppuType((uno::Reference*)0), PropertyAttribute::MAYBEVOID, 0 },
+                    { SW_PROP_NAME(UNO_NAME_CHAR_USER_DEFINED_ATTRIBUTES),      RES_UNKNOWNATR_CONTAINER, &::getCppuType((uno::Reference*)0), PropertyAttribute::MAYBEVOID, 0 },
+                    {0,0,0,0}
+                };
+                aMapArr[nPropertyId] = aTableCursorPropertyMap_Impl;
+            }
+            break;
+            case PROPERTY_MAP_BOOKMARK:
+            {
+                static SfxItemPropertyMap aBookmarkPropertyMap_Impl [] =
+                {
+                    { SW_PROP_NAME(UNO_NAME_ANCHOR_TYPE),   RES_ANCHOR, &::getCppuType((const sal_Int16*)0), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, MID_ANCHOR_ANCHORTYPE},
+                    { SW_PROP_NAME(UNO_LINK_DISPLAY_NAME),  FN_PARAM_LINK_DISPLAY_NAME,     &::getCppuType((const OUString*)0), PropertyAttribute::READONLY, 0xff},
+                    { SW_PROP_NAME(UNO_NAME_ANCHOR_TYPE   ),    0,  &::getCppuType((const sal_Int16*)0),                PropertyAttribute::READONLY, MID_ANCHOR_ANCHORTYPE},
+#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) || (defined(__GNUC__) && defined(__APPLE__))
+                    { SW_PROP_NAME(UNO_NAME_ANCHOR_TYPES   ),   FN_UNO_ANCHOR_TYPES, new uno::Type(::getCppuType((uno::Sequence*)0)),PropertyAttribute::READONLY, 0xff},
+#else
+                    { SW_PROP_NAME(UNO_NAME_ANCHOR_TYPES   ),           FN_UNO_ANCHOR_TYPES,    &::getCppuType((const uno::Sequence*)0),PropertyAttribute::READONLY, 0xff},
+#endif
+                    { SW_PROP_NAME(UNO_NAME_TEXT_WRAP),         0,  &::getCppuType((const sal_Int16*)0),                PropertyAttribute::READONLY, MID_SURROUND_SURROUNDTYPE  },
+                    {0,0,0,0}
+                };
+                aMapArr[nPropertyId] = aBookmarkPropertyMap_Impl;
+            }
+            break;
+            case PROPERTY_MAP_PARAGRAPH_EXTENSIONS:
+            {
+                static SfxItemPropertyMap aParagraphExtensionsMap_Impl[] =
+                {
+                    { SW_PROP_NAME(UNO_NAME_ANCHOR_TYPE   ),    FN_UNO_ANCHOR_TYPE, &::getCppuType((const sal_Int16*)0),                PropertyAttribute::READONLY, MID_ANCHOR_ANCHORTYPE},
+#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) || (defined(__GNUC__) && defined(__APPLE__))
+                    { SW_PROP_NAME(UNO_NAME_ANCHOR_TYPES   ),   FN_UNO_ANCHOR_TYPES, new uno::Type(::getCppuType((uno::Sequence*)0)),PropertyAttribute::READONLY, 0xff},
+#else
+                    { SW_PROP_NAME(UNO_NAME_ANCHOR_TYPES   ),   FN_UNO_ANCHOR_TYPES,    &::getCppuType((const uno::Sequence*)0),PropertyAttribute::READONLY, 0xff},
+#endif
+                    { SW_PROP_NAME(UNO_NAME_TEXT_WRAP),         FN_UNO_TEXT_WRAP,   &::getCppuType((const sal_Int16*)0),                PropertyAttribute::READONLY, MID_SURROUND_SURROUNDTYPE  },
+                    {0,0,0,0}
+                };
+
+                aMapArr[nPropertyId] = aParagraphExtensionsMap_Impl;
+            }
+            break;
+            case PROPERTY_MAP_BIBLIOGRAPHY :
+            {
+                static SfxItemPropertyMap aBibliographyMap_Impl[] =
+                {
+                    { SW_PROP_NAME(UNO_NAME_TITLE),                     WID_IDX_TITLE                                  ,  &::getCppuType((const OUString*)0)  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_IS_PROTECTED          ),    WID_PROTECTED                           ,  &::getBooleanCppuType()  , PROPERTY_NONE,     0},
+                    { SW_PROP_NAME(UNO_NAME_TEXT_COLUMNS),          RES_COL,                &::getCppuType((uno::Reference*)0),    PROPERTY_NONE, MID_COLUMNS},
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_URL      ),        RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_URL    },
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_FILTER  ),         RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_FILTER    },
+                    { SW_PROP_NAME(UNO_NAME_BACK_GRAPHIC_LOCATION    ),         RES_BACKGROUND,         &::getCppuType((const style::GraphicLocation*)0),           PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+                    { SW_PROP_NAME(UNO_NAME_BACK_COLOR       ),     RES_BACKGROUND,         &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE ,MID_BACK_COLOR        },
+                    { SW_PROP_NAME(UNO_NAME_TRANSPARENT_BACKGROUND ),   RES_BACKGROUND,         &::getBooleanCppuType(),            PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT       },
+                    { MAP_CHAR_LEN("ParaStyleHeading"),     WID_PARA_HEAD,  &::getCppuType((const OUString*)0)  , 0,     0},
+                    { MAP_CHAR_LEN("ParaStyleLevel1"),  WID_PARA_LEV1,  &::getCppuType((const OUString*)0)  , 0,     0},
+                    {0,0,0,0}
+                };
+                aMapArr[nPropertyId] = aBibliographyMap_Impl;
+            }
+            break;
+            case PROPERTY_MAP_TEXT_DOCUMENT:
+            {
+                static SfxItemPropertyMap aDocMap_Impl[] =
+                {
+                    { SW_PROP_NAME(UNO_NAME_CHAR_LOCALE),                   RES_CHRATR_LANGUAGE ,   &::getCppuType((const lang::Locale*)0)  ,PropertyAttribute::MAYBEVOID,  MID_LANG_LOCALE },
+                    { SW_PROP_NAME(UNO_NAME_CHARACTER_COUNT),               WID_DOC_CHAR_COUNT,         &::getCppuType((const sal_Int32*)0),    PropertyAttribute::READONLY,   0},
+                    { SW_PROP_NAME(UNO_NAME_INDEX_AUTO_MARK_FILE_U_R_L),    WID_DOC_AUTO_MARK_URL, &::getCppuType((const OUString*)0),  PROPERTY_NONE,   0},
+                    { SW_PROP_NAME(UNO_NAME_PARAGRAPH_COUNT),               WID_DOC_PARA_COUNT,         &::getCppuType((const sal_Int32*)0),    PropertyAttribute::READONLY,   0},
+                    { SW_PROP_NAME(UNO_NAME_RECORD_CHANGES),                WID_DOC_CHANGES_RECORD,     &::getBooleanCppuType(),    PROPERTY_NONE,   0},
+                    { SW_PROP_NAME(UNO_NAME_SHOW_CHANGES),                  WID_DOC_CHANGES_SHOW,       &::getBooleanCppuType(),    PROPERTY_NONE,   0},
+                    { SW_PROP_NAME(UNO_NAME_WORD_COUNT),                    WID_DOC_WORD_COUNT,         &::getCppuType((const sal_Int32*)0),    PropertyAttribute::READONLY,   0},
+                    { SW_PROP_NAME(UNO_NAME_WORD_SEPARATOR),                WID_DOC_WORD_SEPARATOR,     &::getCppuType((const OUString*)0), PROPERTY_NONE,   0},
+                    {0,0,0,0}
+                };
+                aMapArr[nPropertyId] = aDocMap_Impl;
+            }
+            break;
+            case PROPERTY_MAP_LINK_TARGET:
+            {
+                static SfxItemPropertyMap aLinkTargetMap_Impl[] =
+                {
+                    { SW_PROP_NAME(UNO_LINK_DISPLAY_BITMAP),            0,  &::getCppuType((const uno::Reference*)0), PropertyAttribute::READONLY, 0xff},
+                    { SW_PROP_NAME(UNO_LINK_DISPLAY_NAME),          0,  &::getCppuType((const OUString*)0), PropertyAttribute::READONLY, 0xff},
+                    {0,0,0,0}
+                };
+                aMapArr[nPropertyId] = aLinkTargetMap_Impl;
+            }
+            break;
+            case PROPERTY_MAP_AUTO_TEXT_GROUP :
+            {
+                static SfxItemPropertyMap aAutoTextGroupMap_Impl[] =
+                {
+                    { SW_PROP_NAME(UNO_NAME_FILE_PATH),     WID_GROUP_PATH,     &::getCppuType((const OUString*)0), PROPERTY_NONE,   PropertyAttribute::READONLY},
+                    { SW_PROP_NAME(UNO_NAME_TITLE),         WID_GROUP_TITLE, &::getCppuType((const OUString*)0),    PROPERTY_NONE,   0},
+                    {0,0,0,0}
+                };
+                aMapArr[nPropertyId] = aAutoTextGroupMap_Impl;
+            }
+            break;
+            case  PROPERTY_MAP_PRINT_SETTINGS:
+            {
+                static SfxItemPropertyMap aPrintSettingsMap_Impl[] =
+                {
+                    {SW_PROP_NAME(UNO_NAME_PRINT_ANNOTATION_MODE)  ,    WID_PRTSET_ANNOTATION_MODE , &::getCppuType((const sal_Int16*)0),  PROPERTY_NONE,   0},
+                    {SW_PROP_NAME(UNO_NAME_PRINT_BLACK_FONTS)      ,    WID_PRTSET_BLACK_FONTS     , &::getBooleanCppuType(),   PROPERTY_NONE,  0},
+                    {SW_PROP_NAME(UNO_NAME_PRINT_CONTROLS)         ,    WID_PRTSET_CONTROLS        , &::getBooleanCppuType(), PROPERTY_NONE,    0},
+                    {SW_PROP_NAME(UNO_NAME_PRINT_DRAWINGS)         ,    WID_PRTSET_DRAWINGS        , &::getBooleanCppuType(), PROPERTY_NONE,    0},
+                    {SW_PROP_NAME(UNO_NAME_PRINT_GRAPHICS)         ,    WID_PRTSET_GRAPHICS        , &::getBooleanCppuType(), PROPERTY_NONE,    0},
+                    {SW_PROP_NAME(UNO_NAME_PRINT_LEFT_PAGES)    ,       WID_PRTSET_LEFT_PAGES       ,   &::getBooleanCppuType(), PROPERTY_NONE, 0},
+                    {SW_PROP_NAME(UNO_NAME_PRINT_PAGE_BACKGROUND)  ,    WID_PRTSET_PAGE_BACKGROUND , &::getBooleanCppuType(), PROPERTY_NONE,    0},
+                    {SW_PROP_NAME(UNO_NAME_PRINT_PROSPECT)         ,    WID_PRTSET_PROSPECT        , &::getBooleanCppuType(), PROPERTY_NONE,    0},
+                    {SW_PROP_NAME(UNO_NAME_PRINT_REVERSED)    ,         WID_PRTSET_REVERSED         ,   &::getBooleanCppuType(), PROPERTY_NONE, 0},
+                    {SW_PROP_NAME(UNO_NAME_PRING_RIGHT_PAGES) ,         WID_PRTSET_RIGHT_PAGES      ,   &::getBooleanCppuType(), PROPERTY_NONE, 0},
+                    {SW_PROP_NAME(UNO_NAME_PRINT_TABLES)           ,    WID_PRTSET_TABLES          , &::getBooleanCppuType(), PROPERTY_NONE,    0},
+                    {0,0,0,0,0}
+                };
+                aMapArr[nPropertyId] = aPrintSettingsMap_Impl;
+            }
+            break;
+            case  PROPERTY_MAP_VIEW_SETTINGS:
+            {
+                static SfxItemPropertyMap aViewSettingsMap_Impl[] =
+                {
+                    {SW_PROP_NAME(UNO_NAME_SHOW_ANNOTATIONS          ),WID_VIEWSET_ANNOTATIONS          , &::getBooleanCppuType(),PROPERTY_NONE,    0},
+                    {SW_PROP_NAME(UNO_NAME_SHOW_BREAKS               ),WID_VIEWSET_BREAKS               , &::getBooleanCppuType(),PROPERTY_NONE,    0},
+                    {SW_PROP_NAME(UNO_NAME_SHOW_DRAWINGS             ),WID_VIEWSET_DRAWINGS             , &::getBooleanCppuType(),PROPERTY_NONE,    0},
+                    {SW_PROP_NAME(UNO_NAME_SHOW_FIELD_COMMANDS       ),WID_VIEWSET_FIELD_COMMANDS       , &::getBooleanCppuType(),PROPERTY_NONE,    0},
+                    {SW_PROP_NAME(UNO_NAME_SHOW_FOOTNOTE_BACKGROUND  ),WID_VIEWSET_FOOTNOTE_BACKGROUND  , &::getBooleanCppuType(),PROPERTY_NONE,    0},
+                    {SW_PROP_NAME(UNO_NAME_SHOW_GRAPHICS             ),WID_VIEWSET_GRAPHICS             , &::getBooleanCppuType(),PROPERTY_NONE,    0},
+                    {SW_PROP_NAME(UNO_NAME_SHOW_HIDDEN_PARAGRAPHS    ),WID_VIEWSET_HIDDEN_PARAGRAPHS    , &::getBooleanCppuType(),PROPERTY_NONE,    0},
+                    {SW_PROP_NAME(UNO_NAME_SHOW_HIDDEN_TEXT          ),WID_VIEWSET_HIDDEN_TEXT          , &::getBooleanCppuType(),PROPERTY_NONE,    0},
+                    {SW_PROP_NAME(UNO_NAME_SHOW_HORI_RULER          ),WID_VIEWSET_HRULER              , &::getBooleanCppuType(), PROPERTY_NONE, 0},
+                    {SW_PROP_NAME(UNO_NAME_SHOW_HORI_SCROLL_BAR     ),WID_VIEWSET_HSCROLL             , &::getBooleanCppuType(), PROPERTY_NONE, 0},
+                    {SW_PROP_NAME(UNO_NAME_SHOW_INDEX_MARK_BACKGROUND),WID_VIEWSET_INDEX_MARK_BACKGROUND, &::getBooleanCppuType(),PROPERTY_NONE,    0},
+                    {SW_PROP_NAME(UNO_NAME_SHOW_ONLINE_LAYOUT       ),WID_VIEWSET_ONLINE_LAYOUT       , &::getBooleanCppuType(),PropertyAttribute::MAYBEVOID,   0},
+                    {SW_PROP_NAME(UNO_NAME_SHOW_PARA_BREAKS          ),WID_VIEWSET_PARA_BREAKS          , &::getBooleanCppuType(),PROPERTY_NONE,    0},
+                    {SW_PROP_NAME(UNO_NAME_SHOW_PROTECTED_SPACES     ),WID_VIEWSET_PROTECTED_SPACES     , &::getBooleanCppuType(),PROPERTY_NONE,    0},
+                    {SW_PROP_NAME(UNO_NAME_SHOW_SOFT_HYPHENS         ),WID_VIEWSET_SOFT_HYPHENS         , &::getBooleanCppuType(),PROPERTY_NONE,    0},
+                    {SW_PROP_NAME(UNO_NAME_SHOW_SPACES               ),WID_VIEWSET_SPACES               , &::getBooleanCppuType(),PROPERTY_NONE,    0},
+                    {SW_PROP_NAME(UNO_NAME_SHOW_TABLE_BOUNDARIES     ),WID_VIEWSET_TABLE_BOUNDARIES     , &::getBooleanCppuType(),PROPERTY_NONE,    0},
+                    {SW_PROP_NAME(UNO_NAME_SHOW_TABLES               ),WID_VIEWSET_TABLES               , &::getBooleanCppuType(),PROPERTY_NONE,    0},
+                    {SW_PROP_NAME(UNO_NAME_SHOW_TABSTOPS             ),WID_VIEWSET_TABSTOPS             , &::getBooleanCppuType(),PROPERTY_NONE,    0},
+                    {SW_PROP_NAME(UNO_NAME_SHOW_TEXT_BOUNDARIES      ),WID_VIEWSET_TEXT_BOUNDARIES      , &::getBooleanCppuType(),PROPERTY_NONE,    0},
+                    {SW_PROP_NAME(UNO_NAME_SHOW_TEXT_FIELD_BACKGROUND),WID_VIEWSET_TEXT_FIELD_BACKGROUND, &::getBooleanCppuType(),PROPERTY_NONE,    0},
+                    {SW_PROP_NAME(UNO_NAME_SHOW_VERT_RULER          ),WID_VIEWSET_VRULER ,  &::getBooleanCppuType(), PROPERTY_NONE, 0},
+                    {SW_PROP_NAME(UNO_NAME_SHOW_VERT_SCROLL_BAR     ),WID_VIEWSET_VSCROLL,  &::getBooleanCppuType(), PROPERTY_NONE, 0},
+                    {SW_PROP_NAME(UNO_NAME_SMOOTH_SCROLLING          ),WID_VIEWSET_SMOOTH_SCROLLING     , &::getBooleanCppuType(),PROPERTY_NONE,    0},
+                    {SW_PROP_NAME(UNO_NAME_SOLID_MARK_HANDLES       ),WID_VIEWSET_SOLID_MARK_HANDLES      , &::getBooleanCppuType(),PROPERTY_NONE, 0},
+                    {SW_PROP_NAME(UNO_NAME_ZOOM_TYPE                 ),WID_VIEWSET_ZOOM_TYPE            , &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, 0},
+                    {SW_PROP_NAME(UNO_NAME_ZOOM_VALUE               ),WID_VIEWSET_ZOOM              , &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, 0},
+                    {0,0,0,0}
+                };
+                aMapArr[nPropertyId] = aViewSettingsMap_Impl;
+            }
+            break;
+            case PROPERTY_MAP_TEXTPORTION_EXTENSIONS:
+            {
+                static SfxItemPropertyMap aTextPortionExtensionMap_Impl[] =
+                {
+                    {SW_PROP_NAME(UNO_NAME_TEXT_PORTION_TYPE),  0, &::getCppuType((const OUString*)0),PropertyAttribute::READONLY,  0},
+                    {SW_PROP_NAME(UNO_NAME_CONTROL_CHARACTER ), 0, &::getCppuType((const sal_Int16*)0), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, MID_HYPHEN_MIN_LEAD   },
+                    {SW_PROP_NAME(UNO_NAME_BOOKMARK),           0, &::getCppuType((const uno::Reference*)0),    PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },
+                    {SW_PROP_NAME(UNO_NAME_IS_COLLAPSED),       0, &::getBooleanCppuType(),     PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0 },
+                    {SW_PROP_NAME(UNO_NAME_IS_START),           0, &::getBooleanCppuType(),     PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0 },
+                    {0,0,0,0}
+                };
+                aMapArr[nPropertyId] = aTextPortionExtensionMap_Impl;
+            }
+            break;
+            case PROPERTY_MAP_FOOTNOTE:
+            {
+                static SfxItemPropertyMap aFootnoteMap_Impl[] =
+                {
+                    {SW_PROP_NAME(UNO_NAME_REFERENCE_ID),   0, &::getCppuType((const sal_Int16*)0),PropertyAttribute::READONLY|PropertyAttribute::MAYBEVOID,    0},
+                    { SW_PROP_NAME(UNO_NAME_ANCHOR_TYPE   ),    0,  &::getCppuType((const sal_Int16*)0),                PropertyAttribute::READONLY, MID_ANCHOR_ANCHORTYPE},
+#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) || (defined(__GNUC__) && defined(__APPLE__))
+                    { SW_PROP_NAME(UNO_NAME_ANCHOR_TYPES   ),   FN_UNO_ANCHOR_TYPES, new uno::Type(::getCppuType((uno::Sequence*)0)),PropertyAttribute::READONLY, 0xff},
+#else
+                    { SW_PROP_NAME(UNO_NAME_ANCHOR_TYPES   ),           FN_UNO_ANCHOR_TYPES,    &::getCppuType((const uno::Sequence*)0),PropertyAttribute::READONLY, 0xff},
+#endif
+                    { SW_PROP_NAME(UNO_NAME_TEXT_WRAP),         0,  &::getCppuType((const sal_Int16*)0),                PropertyAttribute::READONLY, MID_SURROUND_SURROUNDTYPE  },
+                    {0,0,0,0}
+                };
+                aMapArr[nPropertyId] = aFootnoteMap_Impl;
+            }
+            break;
+        }
+        Sort(nPropertyId);
+    }
+    return aMapArr[nPropertyId];
+}
+/* -----------------04.07.98 11:42-------------------
+ *
+ * --------------------------------------------------*/
+sal_Bool SwItemPropertySet::FillItem(SfxItemSet& rSet, sal_uInt16 nWhich, sal_Bool bGetProperty) const
+{
+    sal_Bool bRet = sal_False;
+/*  if(nWhich == SID_ATTR_PAGE_PAPERBIN)
+    {
+        rSet.Put(SvxPaperBinItem(SID_ATTR_PAGE_PAPERBIN, 0));
+        bRet = sal_True;
+    }*/
+    return bRet;
+}
+
+/*------------------------------------------------------------------------
+    $Log: not supported by cvs2svn $
+    Revision 1.109  2000/09/18 16:04:32  willem.vandorp
+    OpenOffice header added.
+
+    Revision 1.108  2000/09/18 11:53:00  mib
+    bug fix for PageToggle
+
+    Revision 1.107  2000/09/15 07:21:53  os
+    FrameStyle->FrameStyleName
+
+    Revision 1.106  2000/09/12 11:42:58  os
+    #78682# support of service TextContent
+
+    Revision 1.105  2000/09/11 14:05:07  os
+     data type
+
+    Revision 1.104  2000/09/11 12:05:29  os
+    #78606# references to footnotes
+
+    Revision 1.103  2000/09/07 07:59:32  os
+    SwXTextPortion - new properties: IsCollapsed, IsStart
+
+    Revision 1.102  2000/09/05 15:14:52  os
+    string length available again
+
+    Revision 1.101  2000/09/04 12:50:47  os
+    TextPortionEnumeration almost completed
+
+    Revision 1.100  2000/09/01 14:33:51  os
+    properties added to SwXTextPortion
+
+    Revision 1.99  2000/08/31 15:08:34  os
+    DDECommand splitted into three parts
+
+    Revision 1.98  2000/08/29 08:04:50  os
+    Char/ParaUserDefinedAttributes
+
+    Revision 1.97  2000/08/25 08:46:33  os
+     +properties CharStrikeout, DropCapCharStyleName
+
+    Revision 1.96  2000/08/24 15:14:28  os
+    new Property: NumberingIsNumber
+
+    Revision 1.95  2000/08/22 12:58:36  os
+    Chg: ::getCppuType(Sequence<...>) workaround for Apple+GNUC too
+
+    Revision 1.94  2000/08/09 14:47:55  os
+    #77402# create a copy of uno::Type for getCppuType of Sequence<*>
+
+    Revision 1.93  2000/07/21 13:13:12  os
+    #76644# Category property at paragraph styles
+
+    Revision 1.92  2000/07/19 12:45:40  os
+    SvxEscapementItem: AutoEscapement property implemented
+
+    Revision 1.91  2000/07/19 10:58:22  os
+    properties added/renamed
+
+    Revision 1.90  2000/07/14 14:58:06  os
+    SwXStyle::which id of NumberingRules corrected
+
+    Revision 1.89  2000/07/11 13:44:26  os
+    new property: ParaFirstLineIndentRelative (paragraph style)
+
+    Revision 1.88  2000/07/03 13:27:04  os
+    #76457# SwXTextTable supports service TextContent
+
+    Revision 1.87  2000/06/29 12:20:14  os
+    new properties: Left/Right/Top/BottomMarginRelative
+
+    Revision 1.86  2000/06/28 15:42:40  os
+    new properties: CharFontStyleName/Family/CharSet/Pitch
+
+    Revision 1.85  2000/06/28 14:35:37  os
+    new properties: ParaWidows, ParaOrphans
+
+    Revision 1.84  2000/06/27 13:37:22  os
+    new Properties: IsAutoUpdate + DisplayName
+
+    Revision 1.83  2000/06/26 12:57:12  os
+    new Property: IsPhysical
+
+    Revision 1.82  2000/06/16 11:55:23  os
+    #75622# BackGraphicLocation/URL/Filter changed
+
+    Revision 1.81  2000/06/13 13:42:24  os
+    #75719# special handling of AnchorType of text tables
+
+    Revision 1.80  2000/05/26 07:21:48  os
+    old SW Basic API Slots removed
+
+    Revision 1.79  2000/03/27 10:21:10  os
+    UNO III
+
+    Revision 1.78  2000/03/21 15:42:24  os
+    UNOIII
+
+    Revision 1.77  2000/03/13 16:05:10  os
+    #73852# include
+
+    Revision 1.76  2000/03/13 14:36:59  os
+    #73852# CharLocale instead of CharLanguage
+
+    Revision 1.75  2000/02/14 14:34:23  jp
+    #70473# changes for unicode
+
+    Revision 1.73  2000/01/27 09:38:25  os
+    #70258# include
+
+    Revision 1.72  2000/01/26 15:55:13  os
+    #70258# new Property: UserDefinedAttributes
+
+    Revision 1.71  1999/12/16 10:23:25  os
+    #69273# Frame-Properties according to service description
+
+    Revision 1.70  1999/12/08 12:02:05  os
+    #70284# show Bitmaps in hyperlink insert dialog
+
+    Revision 1.69  1999/12/01 14:44:55  os
+    #70234# properties added
+
+
+
+------------------------------------------------------------------------*/
+
diff --git a/sw/source/core/unocore/unoobj.cxx b/sw/source/core/unocore/unoobj.cxx
new file mode 100644
index 000000000000..8f836c90b044
--- /dev/null
+++ b/sw/source/core/unocore/unoobj.cxx
@@ -0,0 +1,6024 @@
+/*************************************************************************
+ *
+ *  $RCSfile: unoobj.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:28 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+
+#ifndef _RTL_USTRBUF_HXX_
+#include 
+#endif
+#include 
+#include 
+#include 
+#ifndef _HINTS_HXX //autogen
+#include 
+#endif
+#ifndef _BOOKMRK_HXX //autogen
+#include 
+#endif
+#ifndef _FRMFMT_HXX //autogen
+#include 
+#endif
+#ifndef _DOC_HXX //autogen
+#include 
+#endif
+#ifndef _NDTXT_HXX //autogen
+#include 
+#endif
+#ifndef _NDNOTXT_HXX //autogen
+#include 
+#endif
+#ifndef _UNOCRSR_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX //autogen
+#include 
+#endif
+#ifndef _ROOTFRM_HXX //autogen
+#include 
+#endif
+#ifndef _FLYFRM_HXX //autogen
+#include 
+#endif
+#ifndef _FTNIDX_HXX //autogen
+#include 
+#endif
+#ifndef _LINKMGR_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _PARATR_HXX
+#include 
+#endif
+#ifndef _URLOBJ_HXX //autogen
+#include 
+#endif
+#include 
+#ifndef _SVARRAY_HXX //autogen
+#include 
+#endif
+#ifndef _CACHESTR_HXX //autogen
+#include 
+#endif
+#ifndef _SHELLIO_HXX //autogen
+#include 
+#endif
+#include 
+#ifndef _SWTBLFMT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTHBSH_HXX
+#include 
+#endif
+#ifndef _SWDOCSH_HXX //autogen
+#include 
+#endif
+#ifndef _SFXSTYLE_HXX //autogen
+#include 
+#endif
+#ifndef _DOCSTYLE_HXX //autogen
+#include 
+#endif
+#ifndef _CHARFMT_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFLD_HXX //autogen
+#include 
+#endif
+/*#ifndef _FMTHBSH_HXX //autogen
+#include 
+#endif
+*/#ifndef _FMTPDSC_HXX //autogen
+#include 
+#endif
+#ifndef _PAGEDESC_HXX //autogen
+#include 
+#endif
+#ifndef _POOLFMT_HRC
+#include 
+#endif
+#ifndef _POOLFMT_HXX
+#include 
+#endif
+#ifndef _EDIMP_HXX //autogen
+#include 
+#endif
+#ifndef _FCHRFMT_HXX //autogen
+#include 
+#endif
+#ifndef _CNTFRM_HXX //autogen
+#include 
+#endif
+#ifndef _PAGEFRM_HXX //autogen
+#include 
+#endif
+#ifndef _TOX_HXX
+#include 
+#endif
+#ifndef _SFX_DOCFILT_HACK_HXX //autogen
+#include 
+#endif
+#ifndef _SFXDOCFILE_HXX //autogen
+#include 
+#endif
+#ifndef _SFX_FCONTNR_HXX //autogen
+#include 
+#endif
+#ifndef _FMTRFMRK_HXX //autogen
+#include 
+#endif
+#ifndef _TXTRFMRK_HXX //autogen
+#include 
+#endif
+#ifndef _UNOCLBCK_HXX
+#include 
+#endif
+#ifndef _UNOOBJ_HXX
+#include 
+#endif
+#ifndef _UNOMAP_HXX
+#include 
+#endif
+#ifndef SW_UNOMID_HXX
+#include 
+#endif
+#ifndef _UNOSETT_HXX
+#include 
+#endif
+#ifndef _UNOPRNMS_HXX
+#include 
+#endif
+#ifndef _UNOTBL_HXX
+#include 
+#endif
+#ifndef _UNODRAW_HXX
+#include 
+#endif
+#ifndef _UNOCOLL_HXX
+#include 
+#endif
+#ifndef _UNOSTYLE_HXX
+#include 
+#endif
+#ifndef _UNOFIELD_HXX
+#include 
+#endif
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_FLSTITEM_HXX //autogen
+#include 
+#endif
+#ifndef _CTRLTOOL_HXX //autogen
+#include 
+#endif
+#ifndef _SFXENUMITEM_HXX
+#include 
+#endif
+#ifndef _FLYPOS_HXX
+#include 
+#endif
+#ifndef _TXTFTN_HXX //autogen
+#include 
+#endif
+#ifndef _SECTION_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFTN_HXX //autogen
+#include 
+#endif
+
+#ifndef _COM_SUN_STAR_TEXT_WRAPTEXTMODE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_TEXTCONTENTANCHORTYPE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_STYLE_PAGESTYLELAYOUT_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XTEXTDOCUMENT_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_STYLE_XSTYLEFAMILIESSUPPLIER_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_CONTAINER_XNAMECONTAINER_HPP_
+#include 
+#endif
+#ifndef _UNOIDX_HXX
+#include 
+#endif
+#ifndef _UNOFRAME_HXX
+#include 
+#endif
+#ifndef _FMTHDFT_HXX //autogen
+#include 
+#endif
+#ifndef _OSL_MUTEX_HXX_ //autogen
+#include 
+#endif
+#ifndef _VOS_MUTEX_HXX_ //autogen
+#include 
+#endif
+#ifndef _SV_SVAPP_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFLCNT_HXX //autogen
+#include 
+#endif
+#define _SVSTDARR_USHORTS
+#define _SVSTDARR_USHORTSSORT
+#include 
+#ifndef _SVX_BRSHITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SFXSTRITEM_HXX
+#include 
+#endif
+#ifndef _FMTCLDS_HXX //autogen
+#include 
+#endif
+#ifndef _RTL_UUID_H_
+#include 
+#endif
+
+//TODO: new Interface & new uno::Exception for protected content
+#define EXCEPT_ON_PROTECTION(rUnoCrsr)  \
+    if((rUnoCrsr).HasReadonlySel()) \
+        throw uno::RuntimeException();
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::beans;
+
+using namespace ::rtl;
+
+//collectn.cxx
+BOOL lcl_IsNumeric(const String&);
+/****************************************************************************
+    static methods
+****************************************************************************/
+::com::sun::star::uno::Sequence< sal_Int8 >  CreateUnoTunnelId()
+{
+    static osl::Mutex aCreateMutex;
+    osl::Guard aGuard( aCreateMutex );
+    uno::Sequence< sal_Int8 > aSeq( 16 );
+    rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+    return aSeq;
+}
+/****************************************************************************
+    Hilfsklassen
+****************************************************************************/
+class SwParaSelection
+{
+    SwUnoCrsr* pUnoCrsr;
+public:
+    SwParaSelection(SwUnoCrsr* pCrsr);
+    ~SwParaSelection();
+};
+
+SwParaSelection::SwParaSelection(SwUnoCrsr* pCrsr) :
+    pUnoCrsr(pCrsr)
+{
+    if(pUnoCrsr->HasMark())
+        pUnoCrsr->DeleteMark();
+    // steht er schon am Anfang?
+    if(pUnoCrsr->GetPoint()->nContent != 0)
+        pUnoCrsr->MovePara(fnParaCurr, fnParaStart);
+    // oder gleichzeitig am Ende?
+    if(pUnoCrsr->GetPoint()->nContent != pUnoCrsr->GetCntntNode()->Len())
+    {
+        pUnoCrsr->SetMark();
+        pUnoCrsr->MovePara(fnParaCurr, fnParaEnd);
+    }
+}
+
+SwParaSelection::~SwParaSelection()
+{
+    if(pUnoCrsr->GetPoint()->nContent != 0)
+    {
+        pUnoCrsr->DeleteMark();
+        pUnoCrsr->MovePara(fnParaCurr, fnParaStart);
+    }
+}
+/* -----------------13.05.98 12:15-------------------
+ *
+ * --------------------------------------------------*/
+SwUnoInternalPaM::SwUnoInternalPaM(SwDoc& rDoc) :
+    SwPaM(rDoc.GetNodes())
+{
+}
+SwUnoInternalPaM::~SwUnoInternalPaM()
+{
+    while( GetNext() != this)
+    {
+        delete GetNext();
+    }
+}
+
+SwUnoInternalPaM&   SwUnoInternalPaM::operator=(const SwPaM& rPaM)
+{
+    const SwPaM* pTmp = &rPaM;
+    *GetPoint() = *rPaM.GetPoint();
+    if(rPaM.HasMark())
+    {
+        SetMark();
+        *GetMark() = *rPaM.GetMark();
+    }
+    else
+        DeleteMark();
+    while(&rPaM != (pTmp = (const SwPaM*)pTmp->GetNext()))
+    {
+        if(pTmp->HasMark())
+            new SwPaM(*pTmp->GetMark(), *pTmp->GetPoint(), this);
+        else
+            new SwPaM(*pTmp->GetPoint(), this);
+    }
+    return *this;
+}
+/****************************************************************************
+    ActionContext
+****************************************************************************/
+UnoActionContext::UnoActionContext(SwDoc* pDc) :
+    pDoc(pDc)
+{
+    SwRootFrm* pRootFrm = pDoc->GetRootFrm();
+    if(pRootFrm)
+        pRootFrm->StartAllAction();
+}
+/*-----------------04.03.98 11:56-------------------
+
+--------------------------------------------------*/
+UnoActionContext::~UnoActionContext()
+{
+    //das Doc kann hier schon entfernt worden sein
+    if(pDoc)
+    {
+        SwRootFrm* pRootFrm = pDoc->GetRootFrm();
+        if(pRootFrm)
+            pRootFrm->EndAllAction();
+    }
+}
+
+/****************************************************************************
+    ActionRemoveContext
+****************************************************************************/
+UnoActionRemoveContext::UnoActionRemoveContext(SwDoc* pDc) :
+    pDoc(pDc)
+{
+    SwRootFrm* pRootFrm = pDoc->GetRootFrm();
+    if(pRootFrm)
+        pRootFrm->UnoRemoveAllActions();
+}
+/* -----------------07.07.98 12:05-------------------
+ *
+ * --------------------------------------------------*/
+UnoActionRemoveContext::~UnoActionRemoveContext()
+{
+    SwRootFrm* pRootFrm = pDoc->GetRootFrm();
+    if(pRootFrm)
+        pRootFrm->UnoRestoreAllActions();
+
+}
+
+/*-----------------09.03.98 08:29-------------------
+
+--------------------------------------------------*/
+void SwXTextCursor::SelectPam(SwPaM& rCrsr, sal_Bool bExpand)
+{
+    if(bExpand)
+    {
+        if(!rCrsr.HasMark())
+            rCrsr.SetMark();
+    }
+    else if(rCrsr.HasMark())
+        rCrsr.DeleteMark();
+
+}
+/* -----------------11.06.98 14:19-------------------
+ *
+ * --------------------------------------------------*/
+sal_Bool lcl_IsEndOfPara(SwPaM& rUnoCrsr)
+{
+    return rUnoCrsr.GetCntntNode() &&
+        rUnoCrsr.GetPoint()->nContent == rUnoCrsr.GetCntntNode()->Len();
+}
+
+/* -----------------11.06.98 14:19-------------------
+ *
+ * --------------------------------------------------*/
+inline sal_Bool lcl_IsStartOfPara(SwPaM& rUnoCrsr)
+{
+    return rUnoCrsr.GetPoint()->nContent == 0;
+}
+
+/* -----------------20.05.98 14:59-------------------
+ *
+ * --------------------------------------------------*/
+void lcl_Append(sal_Unicode*& pCurrent, const SVBT16* pStr, sal_uInt32 nLen)
+{
+    for(sal_uInt32 i = 0; i < nLen; i++)
+    {
+         sal_uInt16 nVal = SVBT16ToShort( *pStr );
+        pStr += 1;
+        *pCurrent++ = nVal;
+    }
+}
+
+void SwXTextCursor::getTextFromPam(SwPaM& aCrsr, OUString& rBuffer)
+{
+    if(!aCrsr.HasMark())
+        return;
+    SvCacheStream aStream(20480);
+    WriterRef xWrt;
+    SwIoSystem::GetWriter( C2S(FILTER_TEXT_DLG), xWrt );
+    if( xWrt.Is() )
+    {
+        SwWriter aWriter(aStream, aCrsr);
+        xWrt->bASCII_NoLastLineEnd = sal_True;
+        SwAsciiOptions aOpt = xWrt->GetAsciiOptions();
+        aOpt.SetCharSet( RTL_TEXTENCODING_UNICODE );
+        xWrt->SetAsciiOptions( aOpt );
+        xWrt->bUCS2_WithStartChar = FALSE;
+
+        if(!IsError( aWriter.Write( xWrt )))
+        {
+            long lLen  = aStream.GetSize();
+            lLen /= 2;
+            sal_Unicode* pUnicodeBuffer = new sal_Unicode[lLen],
+            *pCurrentBuffer = pUnicodeBuffer;
+            const void* pStr = aStream.GetBuffer();
+            if(pStr)
+            {
+                lcl_Append(pCurrentBuffer, (SVBT16*)pStr, lLen);
+            }
+            else
+            {
+                aStream.Seek( 0 );
+                aStream.ResetError();
+                char *pBuffer = new char[16384];
+                long lLocalLen  = lLen;
+                while(lLocalLen > 0)
+                {
+                    long nRead = aStream.Read( pBuffer, 16384 );
+                    lcl_Append(pCurrentBuffer, (SVBT16*)pBuffer, nRead / 2);
+                    lLocalLen -= nRead;
+                }
+                delete pBuffer;
+            }
+            rBuffer = OUString(pUnicodeBuffer, lLen);
+            delete pUnicodeBuffer;
+        }
+    }
+}
+
+/* -----------------21.07.98 11:36-------------------
+ *
+ * --------------------------------------------------*/
+void lcl_InsertFile(SwUnoCrsr* pUnoCrsr,
+    const String& rFileName,
+    const String& rFilterName,
+    const String& rFilterOption,
+    const String& rPassword)
+{
+    SfxMedium* pMed = 0;
+    SwDoc* pDoc = pUnoCrsr->GetDoc();
+    SwDocShell* pDocSh = pDoc->GetDocShell();
+    if(!pDocSh || !rFileName.Len())
+        return;
+
+    const SfxFilter* pFilter = 0;
+
+    SfxObjectFactory& rFact = pDocSh->GetFactory();
+    const sal_uInt16 nCount = rFact.GetFilterCount();
+    if(rFilterName.Len())
+        for( sal_uInt16 i = 0; i < nCount; i++ )
+        {
+            const SfxFilter* pFlt = rFact.GetFilter( i );
+            if( pFlt->GetName() == rFilterName ||
+                pFlt->GetFilterName() == rFilterName )
+            {
+                pFilter = pFlt;
+                break;
+            }
+        }
+    if ( !pFilter )
+    {
+        pMed = new SfxMedium(rFileName, STREAM_READ, sal_True, sal_True, 0, 0 );
+        SfxFilterMatcher aMatcher( rFact.GetFilterContainer() );
+        ErrCode nErr = aMatcher.GuessFilter( *pMed, &pFilter, sal_False );
+        if ( nErr || !pFilter)
+            DELETEZ(pMed);
+        else
+            pMed->SetFilter( pFilter );
+    }
+    else
+    {
+        pMed = new SfxMedium(rFileName, STREAM_READ, sal_True, sal_True,
+                    pFilter, 0);
+        if(rFilterOption.Len())
+        {
+            SfxItemSet* pSet =  pMed->GetItemSet();
+            SfxStringItem aOptionItem(SID_FILE_FILTEROPTIONS, rFilterOption);
+            pSet->Put(aOptionItem);
+        }
+    }
+
+    if( !pMed )
+        return;
+
+    SfxObjectShellRef aRef( pDocSh );
+
+    pDocSh->RegisterTransfer( *pMed );
+    pMed->DownLoad();   // ggfs. den DownLoad anstossen
+    if( aRef.Is() && 1 < aRef->GetRefCount() )  // noch gueltige Ref?
+    {
+        SwReader* pRdr;
+        SfxItemSet* pSet =  pMed->GetItemSet();
+        pSet->Put(SfxBoolItem(FN_API_CALL, sal_True));
+        if(rPassword.Len())
+            pSet->Put(SfxStringItem(SID_PASSWORD, rPassword));
+        Reader *pRead = pDocSh->StartConvertFrom( *pMed, &pRdr, 0, pUnoCrsr);
+        if( pRead )
+        {
+            String sTmpBaseURL( INetURLObject::GetBaseURL() );
+            INetURLObject::SetBaseURL( pMed->GetName() );
+
+            UnoActionContext aContext(pDoc);
+
+            if(pUnoCrsr->HasMark())
+                pDoc->DeleteAndJoin(*pUnoCrsr);
+
+            SwNodeIndex aSave(  pUnoCrsr->GetPoint()->nNode, -1 );
+            xub_StrLen nCntnt = pUnoCrsr->GetPoint()->nContent.GetIndex();
+
+            sal_uInt32 nErrno = pRdr->Read( *pRead );   // und Dokument einfuegen
+
+            if(!nErrno)
+            {
+                aSave++;
+                pUnoCrsr->SetMark();
+                pUnoCrsr->GetMark()->nNode = aSave;
+
+                SwCntntNode* pCntNode = aSave.GetNode().GetCntntNode();
+                if( !pCntNode )
+                    nCntnt = 0;
+                pUnoCrsr->GetMark()->nContent.Assign( pCntNode, nCntnt );
+            }
+
+            delete pRdr;
+
+            INetURLObject::SetBaseURL( sTmpBaseURL );
+
+            // ggfs. alle Verzeichnisse updaten:
+/*          if( pWrtShell->IsUpdateTOX() )
+            {
+                SfxRequest aReq( *this, FN_UPDATE_TOX );
+                Execute( aReq );
+                pWrtShell->SetUpdateTOX( sal_False );       // wieder zurueck setzen
+            }*/
+
+        }
+    }
+    delete pMed;
+}
+/* -----------------06.07.98 07:33-------------------
+ *
+ * --------------------------------------------------*/
+void lcl_setCharStyle(SwDoc* pDoc, const uno::Any aValue, SfxItemSet& rSet)
+     throw (lang::IllegalArgumentException)
+{
+    SwDocShell* pDocSh = pDoc->GetDocShell();
+    if(pDocSh)
+    {
+        OUString uStyle;
+        aValue >>= uStyle;
+        String sStyle(SwXStyleFamilies::GetUIName(uStyle, SFX_STYLE_FAMILY_CHAR));
+        SwDocStyleSheet* pStyle =
+            (SwDocStyleSheet*)pDocSh->GetStyleSheetPool()->Find(sStyle, SFX_STYLE_FAMILY_CHAR);
+        if(pStyle)
+        {
+            SwFmtCharFmt aFmt(pStyle->GetCharFmt());
+            rSet.Put(aFmt);
+        }
+        else
+        {
+             throw lang::IllegalArgumentException();
+        }
+
+    }
+};
+/* -----------------30.06.98 08:46-------------------
+ *
+ * --------------------------------------------------*/
+void lcl_SetTxtFmtColl(const uno::Any& rAny, SwPaM& rPaM)
+    throw (lang::IllegalArgumentException)
+{
+    SwDoc* pDoc = rPaM.GetDoc();
+    SwDocShell* pDocSh = pDoc->GetDocShell();
+    if(!pDocSh)
+        return;
+    OUString uStyle;
+    rAny >>= uStyle;
+    String sStyle(SwXStyleFamilies::GetUIName(uStyle, SFX_STYLE_FAMILY_PARA));
+    SwDocStyleSheet* pStyle =
+                    (SwDocStyleSheet*)pDocSh->GetStyleSheetPool()->Find(sStyle, SFX_STYLE_FAMILY_PARA);
+    if(pStyle)
+    {
+        SwTxtFmtColl *pLocal = pStyle->GetCollection();
+        UnoActionContext aAction(pDoc);
+        pDoc->StartUndo( UNDO_START );
+        FOREACHUNOPAM_START(&rPaM)
+            pDoc->SetTxtFmtColl(*PUNOPAM, pLocal);
+        FOREACHUNOPAM_END()
+        pDoc->EndUndo( UNDO_END );
+    }
+    else
+    {
+        throw lang::IllegalArgumentException();
+    }
+
+}
+/* -----------------06.07.98 07:38-------------------
+ *
+ * --------------------------------------------------*/
+ void lcl_setPageDesc(SwDoc* pDoc, const uno::Any& aValue, SfxItemSet& rSet)
+ {
+    if(aValue.getValueType() != ::getCppuType((const OUString*)0))
+        return;
+    SwFmtPageDesc* pNewDesc = 0;
+    const SfxPoolItem* pItem;
+    if(SFX_ITEM_SET == rSet.GetItemState( RES_PAGEDESC, sal_True, &pItem ) )
+    {
+        pNewDesc = new SwFmtPageDesc(*((SwFmtPageDesc*)pItem));
+    }
+    if(!pNewDesc)
+        pNewDesc = new SwFmtPageDesc();
+    OUString uDescName;
+    aValue >>= uDescName;
+    String sDescName(SwXStyleFamilies::GetUIName(uDescName, SFX_STYLE_FAMILY_PAGE));
+    if(!pNewDesc->GetPageDesc() || pNewDesc->GetPageDesc()->GetName() != sDescName)
+    {
+        sal_uInt16 nCount = pDoc->GetPageDescCnt();
+        sal_Bool bPut = sal_False;
+        if(sDescName.Len())
+        {
+            SwPageDesc* pPageDesc = ::GetPageDescByName_Impl(*pDoc, sDescName);
+            if(pPageDesc)
+            {
+                pPageDesc->Add( pNewDesc );
+                bPut = sal_True;
+            }
+            else
+            {
+                throw lang::IllegalArgumentException();
+            }
+        }
+        if(!bPut)
+        {
+            rSet.ClearItem(RES_BREAK);
+            rSet.Put(SwFmtPageDesc());
+        }
+        else
+            rSet.Put(*pNewDesc);
+    }
+
+    delete pNewDesc;
+}
+/* -----------------30.06.98 10:29-------------------
+ *
+ * --------------------------------------------------*/
+void lcl_SetNodeNumStart( SwPaM& rCrsr, uno::Any aValue )
+{
+    sal_Int16 nTmp;
+    aValue >>= nTmp;
+    sal_uInt16 nStt = (nTmp < 0 ? USHRT_MAX : (sal_uInt16)nTmp);
+    SwDoc* pDoc = rCrsr.GetDoc();
+    UnoActionContext aAction(pDoc);
+
+    if( rCrsr.GetNext() != &rCrsr )         // Mehrfachselektion ?
+    {
+        pDoc->StartUndo( UNDO_START );
+        SwPamRanges aRangeArr( rCrsr );
+        SwPaM aPam( *rCrsr.GetPoint() );
+        for( sal_uInt16 n = 0; n < aRangeArr.Count(); ++n )
+            pDoc->SetNodeNumStart( *aRangeArr.SetPam( n, aPam ).GetPoint(), nStt );
+        pDoc->EndUndo( UNDO_END );
+    }
+    else
+        pDoc->SetNodeNumStart( *rCrsr.GetPoint(), nStt );
+}
+
+/* -----------------30.06.98 10:30-------------------
+ *
+ * --------------------------------------------------*/
+sal_Int16 lcl_IsNodeNumStart(SwPaM& rPam, beans::PropertyState& eState)
+{
+    const SwTxtNode* pTxtNd = rPam.GetNode()->GetTxtNode();
+    if( pTxtNd && pTxtNd->GetNum() && pTxtNd->GetNumRule() )
+    {
+        eState = beans::PropertyState_DIRECT_VALUE;
+        sal_uInt16 nTmp = pTxtNd->GetNum()->GetSetValue();
+        return USHRT_MAX == nTmp ? -1 : (sal_Int16)nTmp;
+    }
+    eState = beans::PropertyState_DEFAULT_VALUE;
+    return -1;
+}
+/* -----------------25.05.98 11:41-------------------
+ *
+ * --------------------------------------------------*/
+void lcl_setNumberingProperty(const uno::Any& rValue, SwPaM& rPam)
+{
+    if(rValue.getValueType() == ::getCppuType((const uno::Reference*)0))
+    {
+        uno::Reference< XIndexReplace > * pxNum = (uno::Reference< XIndexReplace > *)rValue.getValue();
+        if(!(*pxNum).is())
+            return;
+        SwXNumberingRules* pSwNum = 0;
+
+        uno::Reference xNumTunnel((*pxNum), uno::UNO_QUERY);
+        if(xNumTunnel.is())
+        {
+            pSwNum = (SwXNumberingRules*)
+                xNumTunnel->getSomething( SwXNumberingRules::getUnoTunnelId() );
+        }
+
+        if(pSwNum && pSwNum->GetNumRule())
+        {
+            SwDoc* pDoc = rPam.GetDoc();
+            SwNumRule aRule(*pSwNum->GetNumRule());
+            const String* pNewCharStyles =  pSwNum->GetNewCharStyleNames();
+            const String* pBulletFontNames = pSwNum->GetBulletFontNames();
+            for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
+            {
+                SwNumFmt aFmt(aRule.Get( i ));
+                if( pNewCharStyles[i].Len() &&
+                    pNewCharStyles[i] != SwXNumberingRules::GetInvalidStyle() &&
+                    (!aFmt.GetCharFmt() || pNewCharStyles[i] != aFmt.GetCharFmt()->GetName()))
+                {
+                    if(!pNewCharStyles[i].Len())
+                        aFmt.SetCharFmt(0);
+                    else
+                    {
+
+                        // CharStyle besorgen und an der chaos::Rule setzen
+                        sal_uInt16 nChCount = pDoc->GetCharFmts()->Count();
+                        SwCharFmt* pCharFmt = 0;
+                        for(sal_uInt16 i = 0; i< nChCount; i++)
+                        {
+                            SwCharFmt& rChFmt = *((*(pDoc->GetCharFmts()))[i]);;
+                            if(rChFmt.GetName() == pNewCharStyles[i])
+                            {
+                                pCharFmt = &rChFmt;
+                                break;
+                            }
+                        }
+
+                        if(!pCharFmt)
+                        {
+                            SfxStyleSheetBasePool* pPool = pDoc->GetDocShell()->GetStyleSheetPool();
+                            SfxStyleSheetBase* pBase;
+                            pBase = pPool->Find(pNewCharStyles[i], SFX_STYLE_FAMILY_CHAR);
+                        // soll das wirklich erzeugt werden?
+                            if(!pBase)
+                                pBase = &pPool->Make(pNewCharStyles[i], SFX_STYLE_FAMILY_PAGE);
+                            pCharFmt = ((SwDocStyleSheet*)pBase)->GetCharFmt();
+                        }
+                        if(pCharFmt)
+                            aFmt.SetCharFmt(pCharFmt);
+                    }
+                }
+                //jetzt nochmal fuer Fonts
+                if(pBulletFontNames[i] != SwXNumberingRules::GetInvalidStyle() &&
+                    ((pBulletFontNames[i].Len() && !aFmt.GetBulletFont()) ||
+                    pBulletFontNames[i].Len() &&
+                            aFmt.GetBulletFont()->GetName() != pBulletFontNames[i] ))
+                {
+                    const SvxFontListItem* pFontListItem =
+                            (const SvxFontListItem* )pDoc->GetDocShell()
+                                                ->GetItem( SID_ATTR_CHAR_FONTLIST );
+                    const FontList*  pList = pFontListItem->GetFontList();
+
+                    FontInfo aInfo = pList->Get(
+                        pBulletFontNames[i],WEIGHT_NORMAL, ITALIC_NONE);
+                    Font aFont(aInfo);
+                    aFmt.SetBulletFont(&aFont);
+                }
+                aRule.Set( i, aFmt );
+            }
+            UnoActionContext aAction(rPam.GetDoc());
+            rPam.GetDoc()->SetNumRule( rPam, aRule );
+        }
+    }
+}
+
+/* -----------------17.09.98 09:44-------------------
+ *
+ * --------------------------------------------------*/
+sal_Bool lcl_setCrsrPropertyValue(const SfxItemPropertyMap* pMap,
+                                SwPaM& rPam,
+                                SfxItemSet& rSet,
+                                const uno::Any& aValue,
+                                sal_Bool& rPut ) throw (lang::IllegalArgumentException)
+{
+    sal_Bool bRet = sal_True;
+    rPut = sal_True;
+    if(aValue.getValueType() == ::getCppuVoidType())
+        bRet = sal_False;
+    else
+    {
+        switch(pMap->nWID)
+        {
+            case RES_TXTATR_CHARFMT:
+                lcl_setCharStyle(rPam.GetDoc(), aValue, rSet);
+            break;
+            case FN_UNO_PARA_STYLE :
+                lcl_SetTxtFmtColl(aValue, rPam);
+                rPut = sal_False;
+            break;
+            case FN_UNO_PAGE_STYLE :
+            break;
+            case FN_UNO_NUM_START_VALUE  :
+                lcl_SetNodeNumStart( rPam, aValue );
+            break;
+            case FN_UNO_NUM_LEVEL  :
+            case FN_UNO_IS_NUMBER  :
+            {
+                SwTxtNode* pTxtNd = rPam.GetNode()->GetTxtNode();
+                const SwNumRule* pRule = pTxtNd->GetNumRule();
+                // hier wird Multiselektion nicht beruecksichtigt
+                if( pRule && pTxtNd->GetNum() )
+                {
+                    if( FN_UNO_NUM_LEVEL == pMap->nWID)
+                    {
+                        sal_Int16 nLevel;
+                        aValue >>= nLevel;
+                        sal_Int16 nOldLevel = pTxtNd->GetNum()->GetLevel() & ~NO_NUMLEVEL;
+                        if(nLevel < MAXLEVEL && nOldLevel != nLevel)
+                        {
+                            UnoActionContext aAction(rPam.GetDoc());
+                            sal_Bool bDown = nLevel > nOldLevel;
+                            sal_Int8 nMove = (sal_Int8)(bDown ? nLevel - nOldLevel : nOldLevel - nLevel);
+                            while( nMove-- )
+                            {
+                                rPam.GetDoc()->NumUpDown( rPam, bDown );
+                            }
+                        }
+                    }
+                    else
+                    {
+                        BOOL bIsNumber = *(sal_Bool*) aValue.getValue();
+                        SwNodeNum aNum = *pTxtNd->GetNum();
+                        sal_Int16 nOldLevel = aNum.GetLevel() & ~NO_NUMLEVEL;
+                        if(!bIsNumber)
+                            nOldLevel |= NO_NUMLEVEL;
+                        aNum.SetLevel(nOldLevel);
+                        pTxtNd->UpdateNum( aNum );
+
+                    }
+                    rPut = sal_False;
+                }
+                //PROPERTY_MAYBEVOID!
+            }
+            break;
+            case FN_UNO_NUM_RULES:
+                lcl_setNumberingProperty(aValue, rPam);
+                rPut = sal_False;
+            break;
+            case RES_PARATR_DROP:
+            {
+                if( MID_DROPCAP_CHAR_STYLE_NAME == pMap->nMemberId)
+                {
+                    if(aValue.getValueType() == ::getCppuType((const OUString*)0))
+                    {
+                        SwFmtDrop* pDrop = 0;
+                        const SfxPoolItem* pItem;
+                        if(SFX_ITEM_SET == rSet.GetItemState( RES_PARATR_DROP, sal_True, &pItem ) )
+                            pDrop = new SwFmtDrop(*((SwFmtDrop*)pItem));
+                        if(!pDrop)
+                            pDrop = new SwFmtDrop();
+                        OUString uStyle;
+                        aValue >>= uStyle;
+                        String sStyle(SwXStyleFamilies::GetUIName(uStyle, SFX_STYLE_FAMILY_CHAR));
+                        SwDocStyleSheet* pStyle =
+                            (SwDocStyleSheet*)rPam.GetDoc()->GetDocShell()->GetStyleSheetPool()->Find(sStyle, SFX_STYLE_FAMILY_CHAR);
+                        if(pStyle)
+                            pDrop->SetCharFmt(pStyle->GetCharFmt());
+                        else
+                             throw lang::IllegalArgumentException();
+                        rSet.Put(*pDrop);
+                        delete pDrop;
+                    }
+                    else
+                        throw lang::IllegalArgumentException();
+                }
+                else
+                    bRet = sal_False;
+            }
+            break;
+            case RES_PAGEDESC      :
+            if(MID_PAGEDESC_PAGEDESCNAME == pMap->nMemberId )
+            {
+                lcl_setPageDesc(rPam.GetDoc(), aValue, rSet);
+                break;
+            }
+            //hier kein break
+            default: bRet = sal_False;
+        }
+    }
+return bRet;
+}
+/* -----------------30.03.99 10:52-------------------
+ * spezielle Properties am Cursor zuruecksetzen
+ * --------------------------------------------------*/
+void    lcl_resetCrsrPropertyValue(const SfxItemPropertyMap* pMap, SwPaM& rPam)
+{
+    SwDoc* pDoc = rPam.GetDoc();
+    switch(pMap->nWID)
+    {
+        case FN_UNO_PARA_STYLE :
+//          lcl_SetTxtFmtColl(aValue, pUnoCrsr);
+        break;
+        case FN_UNO_PAGE_STYLE :
+        break;
+        case FN_UNO_NUM_START_VALUE  :
+        {
+            UnoActionContext aAction(pDoc);
+
+            if( rPam.GetNext() != &rPam )           // Mehrfachselektion ?
+            {
+                pDoc->StartUndo( UNDO_START );
+                SwPamRanges aRangeArr( rPam );
+                SwPaM aPam( *rPam.GetPoint() );
+                for( sal_uInt16 n = 0; n < aRangeArr.Count(); ++n )
+                    pDoc->SetNodeNumStart( *aRangeArr.SetPam( n, aPam ).GetPoint(), 1 );
+                pDoc->EndUndo( UNDO_END );
+            }
+            else
+                pDoc->SetNodeNumStart( *rPam.GetPoint(), 0 );
+        }
+
+        break;
+        case FN_UNO_NUM_LEVEL  :
+        break;
+        case FN_UNO_NUM_RULES:
+//          lcl_setNumberingProperty(aValue, pUnoCrsr);
+        break;
+    }
+}
+
+/* -----------------30.06.98 08:39-------------------
+ *
+ * --------------------------------------------------*/
+SwFmtColl* SwXTextCursor::GetCurTxtFmtColl(SwPaM& rPam, BOOL bConditional)
+{
+    static const sal_uInt16 nMaxLookup = 255;
+    SwFmtColl *pFmt = 0;
+
+//  if ( GetCrsrCnt() > nMaxLookup )
+//      return 0;
+    sal_Bool bError = sal_False;
+    FOREACHUNOPAM_START(&rPam)
+
+        sal_uInt32 nSttNd = PUNOPAM->GetMark()->nNode.GetIndex(),
+              nEndNd = PUNOPAM->GetPoint()->nNode.GetIndex();
+        xub_StrLen nSttCnt = PUNOPAM->GetMark()->nContent.GetIndex(),
+                nEndCnt = PUNOPAM->GetPoint()->nContent.GetIndex();
+
+        if( nSttNd > nEndNd || ( nSttNd == nEndNd && nSttCnt > nEndCnt ))
+        {
+            sal_uInt32 nTmp = nSttNd; nSttNd = nEndNd; nEndNd = nTmp;
+            nTmp = nSttCnt; nSttCnt = nEndCnt; nEndCnt = (sal_uInt16)nTmp;
+        }
+
+        if( nEndNd - nSttNd >= nMaxLookup )
+        {
+            pFmt = 0;
+            break;
+        }
+
+        const SwNodes& rNds = rPam.GetDoc()->GetNodes();
+        for( sal_uInt32 n = nSttNd; n <= nEndNd; ++n )
+        {
+            const SwTxtNode* pNd = rNds[ n ]->GetTxtNode();
+            if( pNd )
+            {
+                SwFmtColl* pNdFmt = bConditional ? pNd->GetFmtColl()
+                                                    : &pNd->GetAnyFmtColl();
+                if( !pFmt )
+                    pFmt = pNdFmt;
+                else if( pFmt != pNdFmt )
+                {
+                    bError = sal_True;
+                    break;
+                }
+            }
+        }
+        if(bError)
+            break;
+    FOREACHUNOPAM_END()
+    return bError ? 0 : pFmt;
+}
+/* -----------------04.07.98 15:15-------------------
+ *
+ * --------------------------------------------------*/
+String lcl_GetCurPageStyle(SwPaM& rPaM)
+{
+    String sRet;
+    const SwPageFrm* pPage = rPaM.GetCntntNode()->GetFrm()->FindPageFrm();
+    if(pPage)
+    {
+        sRet = SwXStyleFamilies::GetProgrammaticName(
+                    pPage->GetPageDesc()->GetName(), SFX_STYLE_FAMILY_PAGE);
+    }
+    return sRet;
+}
+/* -----------------25.05.98 11:40-------------------
+ *
+ * --------------------------------------------------*/
+uno::Any  lcl_getNumberingProperty(SwPaM& rPam, beans::PropertyState& eState)
+{
+    uno::Any aAny;
+    const SwNumRule* pNumRule = rPam.GetDoc()->GetCurrNumRule( *rPam.GetPoint() );
+    if(pNumRule)
+    {
+        uno::Reference< container::XIndexReplace >  xNum = new SwXNumberingRules(*pNumRule);
+        aAny.setValue(&xNum, ::getCppuType((const uno::Reference*)0));
+        eState = beans::PropertyState_DIRECT_VALUE;
+    }
+    else
+        eState = beans::PropertyState_DEFAULT_VALUE;
+    return aAny;
+}
+
+/* -----------------16.09.98 12:27-------------------
+ *  Lesen spezieller Properties am Cursor
+ * --------------------------------------------------*/
+sal_Bool lcl_getCrsrPropertyValue(const SfxItemPropertyMap* pMap
+                                        , SwPaM& rPam
+                                        , const SfxItemSet& rSet
+                                        , uno::Any& rAny
+                                        , beans::PropertyState& eState )
+{
+
+    eState = beans::PropertyState_DIRECT_VALUE;
+//    PropertyState_DEFAULT_VALUE
+//    PropertyState_AMBIGUOUS_VALUE
+    sal_Bool bDone = sal_True;
+    switch(pMap->nWID)
+    {
+        case FN_UNO_PARA_CHAPTER_NUMBERING_LEVEL:
+        {
+            SwFmtColl* pFmt = SwXTextCursor::GetCurTxtFmtColl(rPam, FALSE);
+            sal_Int8 nRet = -1;
+            if(pFmt && ((SwTxtFmtColl*)pFmt)->GetOutlineLevel() != NO_NUMBERING)
+                nRet = ((SwTxtFmtColl*)pFmt)->GetOutlineLevel();
+            rAny <<= nRet;
+        }
+        break;
+        case FN_UNO_PARA_CONDITIONAL_STYLE_NAME:
+        case FN_UNO_PARA_STYLE :
+        {
+            String sVal;
+            SwFmtColl* pFmt = SwXTextCursor::GetCurTxtFmtColl(rPam, FN_UNO_PARA_CONDITIONAL_STYLE_NAME == pMap->nWID);
+            if(pFmt)
+                sVal = SwXStyleFamilies::GetProgrammaticName(pFmt->GetName(), SFX_STYLE_FAMILY_PARA);
+            rAny <<= OUString(sVal);
+            if(!sVal.Len())
+                eState = beans::PropertyState_AMBIGUOUS_VALUE;
+        }
+        break;
+        case FN_UNO_PAGE_STYLE :
+        {
+            String sVal = lcl_GetCurPageStyle(rPam);
+            rAny <<= OUString(sVal);
+            if(!sVal.Len())
+                eState = beans::PropertyState_AMBIGUOUS_VALUE;
+        }
+        break;
+        case FN_UNO_NUM_START_VALUE  :
+        {
+            sal_Int16 nValue = lcl_IsNodeNumStart(rPam, eState);
+            rAny <<= nValue;
+        }
+        break;
+        case FN_UNO_NUM_LEVEL  :
+        case FN_UNO_IS_NUMBER  :
+        {
+            const SwTxtNode* pTxtNd = rPam.GetNode()->GetTxtNode();
+            const SwNumRule* pRule = pTxtNd->GetNumRule();
+            // hier wird Multiselektion nicht beruecksichtigt
+            if( pRule && pTxtNd->GetNum() )
+            {
+                if(pMap->nWID == FN_UNO_NUM_LEVEL)
+                    rAny <<= (sal_Int16)(pTxtNd->GetNum()->GetLevel()&~NO_NUMLEVEL);
+                else
+                {
+                    BOOL bIsNumber = 0 == (pTxtNd->GetNum()->GetLevel() & NO_NUMLEVEL);
+                    rAny.setValue(&bIsNumber, ::getBooleanCppuType());
+                }
+            }
+            else
+                eState = beans::PropertyState_DEFAULT_VALUE;
+            //PROPERTY_MAYBEVOID!
+        }
+        break;
+        case FN_UNO_NUM_RULES  :
+            rAny = lcl_getNumberingProperty(rPam, eState);
+        break;
+        case RES_PAGEDESC      :
+        if(MID_PAGEDESC_PAGEDESCNAME == pMap->nMemberId )
+        {
+            const SfxPoolItem* pItem;
+            if(SFX_ITEM_SET == rSet.GetItemState( RES_PAGEDESC, sal_True, &pItem ) )
+            {
+                const SwPageDesc* pDesc = ((const SwFmtPageDesc*)pItem)->GetPageDesc();
+                if(pDesc)
+                    rAny <<= OUString(
+                        SwXStyleFamilies::GetProgrammaticName(pDesc->GetName(), SFX_STYLE_FAMILY_PAGE));
+            }
+            else
+                eState = beans::PropertyState_DEFAULT_VALUE;
+        }
+        else
+            bDone = sal_False;
+        break;
+        case FN_UNO_DOCUMENT_INDEX_MARK:
+        {
+            SwTxtAttr* pTxtAttr = rPam.GetNode()->GetTxtNode()->GetTxtAttr(
+                                rPam.GetPoint()->nContent, RES_TXTATR_TOXMARK);
+            if(pTxtAttr)
+            {
+                const SwTOXMark& rMark = pTxtAttr->GetTOXMark();
+                uno::Reference< XDocumentIndexMark >  xRef = SwXDocumentIndexMark::GetObject(
+                        (SwTOXType*)rMark.GetTOXType(), &rMark, rPam.GetDoc());
+                rAny.setValue(&xRef, ::getCppuType((uno::Reference*)0));
+            }
+            else
+                //auch hier - nicht zu unterscheiden
+                eState = beans::PropertyState_DEFAULT_VALUE;
+        }
+        break;
+        case FN_UNO_DOCUMENT_INDEX:
+        {
+            const SwTOXBase* pBase = rPam.GetDoc()->GetCurTOX(
+                                                    *rPam.Start() );
+            if( pBase )
+            {
+                uno::Reference< XDocumentIndex >  aRef = new SwXDocumentIndex(
+                        (const SwTOXBaseSection*)pBase, rPam.GetDoc() );
+                DBG_ERROR("kein Test auf mehrfache Erzeugung!")
+                rAny.setValue(&aRef, ::getCppuType((uno::Reference*)0));
+            }
+            else
+                eState = beans::PropertyState_DEFAULT_VALUE;
+        }
+        break;
+        case FN_UNO_TEXT_FIELD:
+        {
+            const SwPosition *pPos = rPam.Start();
+            const SwTxtNode *pTxtNd =
+                rPam.GetDoc()->GetNodes()[pPos->nNode.GetIndex()]->GetTxtNode();
+            SwTxtAttr* pTxtAttr =
+                pTxtNd ? pTxtNd->GetTxtAttr(pPos->nContent, RES_TXTATR_FIELD)
+                       : 0;
+            if(pTxtAttr)
+            {
+
+                const SwFmtFld& rFld = pTxtAttr->GetFld();
+                SwClientIter aIter(*rFld.GetFld()->GetTyp());
+                SwXTextField* pFld = 0;
+                SwXTextField* pTemp = (SwXTextField*)aIter.First(TYPE(SwXTextField));
+                while(pTemp && !pFld)
+                {
+                    if(pTemp->GetFldFmt() == &rFld)
+                        pFld = pTemp;
+                    pTemp = (SwXTextField*)aIter.Next();
+                }
+                if(!pFld)
+                    pFld = new SwXTextField( rFld, rPam.GetDoc());
+                uno::Reference< XTextField >  xRet = pFld;
+                rAny.setValue(&xRet, ::getCppuType((uno::Reference*)0));
+            }
+            else
+                eState = beans::PropertyState_DEFAULT_VALUE;
+        }
+        break;
+/*              laesst sich nicht feststellen
+*               case FN_UNO_BOOKMARK:
+        {
+            if()
+            {
+                uno::Reference< XBookmark >  xBkm = SwXBookmarks::GetObject(rBkm);
+                rAny.set(&xBkm, ::getCppuType((const XBookmark*)0)());
+            }
+        }
+        break;*/
+        case FN_UNO_TEXT_TABLE:
+        case FN_UNO_CELL:
+        {
+            SwStartNode* pSttNode = rPam.GetNode()->FindStartNode();
+            SwStartNodeType eType = pSttNode->GetStartNodeType();
+            if(SwTableBoxStartNode == eType)
+            {
+                const SwTableNode* pTblNode = pSttNode->FindTableNode();
+                SwFrmFmt* pTableFmt = (SwFrmFmt*)pTblNode->GetTable().GetFrmFmt();
+                SwTable& rTable = ((SwTableNode*)pSttNode)->GetTable();
+                if(FN_UNO_TEXT_TABLE == pMap->nWID)
+                {
+                    uno::Reference< XTextTable >  xTable = SwXTextTables::GetObject(*pTableFmt);
+                    rAny.setValue(&xTable, ::getCppuType((uno::Reference*)0));
+                }
+                else
+                {
+                    SwTableBox* pBox = pSttNode->GetTblBox();
+                    uno::Reference< table::XCell >  xCell = SwXCell::CreateXCell(pTableFmt, pBox);
+                    rAny.setValue(&xCell, ::getCppuType((uno::Reference*)0));
+                }
+            }
+            else
+                eState = beans::PropertyState_DEFAULT_VALUE;
+        }
+        break;
+        case FN_UNO_TEXT_FRAME:
+        {
+            SwStartNode* pSttNode = rPam.GetNode()->FindStartNode();
+            SwStartNodeType eType = pSttNode->GetStartNodeType();
+
+            SwFrmFmt* pFmt;
+            if(eType == SwFlyStartNode && 0 != (pFmt = pSttNode->GetFlyFmt()))
+            {
+                uno::Reference< XTextFrame >  xFrm = (SwXTextFrame*) SwXFrames::GetObject(*pFmt, FLYCNTTYPE_FRM);
+                rAny.setValue(&xFrm, ::getCppuType((uno::Reference*)0));
+            }
+            else
+                eState = beans::PropertyState_DEFAULT_VALUE;
+        }
+        break;
+        case FN_UNO_TEXT_SECTION:
+        {
+            SwSection* pSect = rPam.GetDoc()->GetCurrSection(*rPam.GetPoint());
+            if(pSect)
+            {
+                uno::Reference< XTextSection >  xSect = SwXTextSections::GetObject( *pSect->GetFmt() );
+                rAny.setValue(&xSect, ::getCppuType((uno::Reference*)0) );
+            }
+            else
+                eState = beans::PropertyState_DEFAULT_VALUE;
+        }
+        break;
+        case FN_UNO_ENDNOTE:
+        case FN_UNO_FOOTNOTE:
+        {
+            SwTxtAttr* pTxtAttr = rPam.GetNode()->GetTxtNode()->
+                                        GetTxtAttr(rPam.GetPoint()->nContent, RES_TXTATR_FTN);
+            if(pTxtAttr)
+            {
+                const SwFmtFtn& rFtn = pTxtAttr->GetFtn();
+                if(rFtn.IsEndNote() == (FN_UNO_ENDNOTE == pMap->nWID))
+                {
+                    uno::Reference< XFootnote >  xFoot = new SwXFootnote(rPam.GetDoc(), rFtn);
+                    rAny.setValue(&xFoot, ::getCppuType((uno::Reference*)0));
+                }
+                else
+                    eState = beans::PropertyState_DEFAULT_VALUE;
+            }
+            else
+                eState = beans::PropertyState_DEFAULT_VALUE;
+        }
+        break;
+        case FN_UNO_REFERENCE_MARK:
+        {
+            SwTxtAttr* pTxtAttr = rPam.GetNode()->GetTxtNode()->
+                                        GetTxtAttr(rPam.GetPoint()->nContent, RES_TXTATR_REFMARK);
+            if(pTxtAttr)
+            {
+                const SwFmtRefMark& rRef = pTxtAttr->GetRefMark();
+                uno::Reference< XTextContent >  xRef = SwXReferenceMarks::GetObject( rPam.GetDoc(), &rRef );
+                rAny.setValue(&xRef, ::getCppuType((uno::Reference*)0));
+            }
+            else
+                eState = beans::PropertyState_DEFAULT_VALUE;
+        }
+        break;
+        case RES_TXTATR_CHARFMT:
+        // kein break hier!
+        default: bDone = sal_False;
+    }
+    return bDone;
+}
+
+/* -----------------26.06.98 16:20-------------------
+ *  Hilfsfunktion fuer PageDesc
+ * --------------------------------------------------*/
+ SwPageDesc*    GetPageDescByName_Impl(SwDoc& rDoc, const String& rName)
+ {
+    SwPageDesc* pRet = 0;
+    sal_uInt16 nDCount = rDoc.GetPageDescCnt();
+    for( sal_uInt16 i = 0; i < nDCount; i++ )
+    {
+        SwPageDesc* pDsc = &rDoc._GetPageDesc( i );
+        if(pDsc->GetName() == rName)
+        {
+            pRet = pDsc;
+            break;
+        }
+    }
+    if(!pRet)
+    {
+        for(i = RC_POOLPAGEDESC_BEGIN; i <= STR_POOLPAGE_ENDNOTE; ++i)
+        {
+            const String aFmtName(SW_RES(i));
+            if(aFmtName == rName)
+            {
+                pRet = rDoc.GetPageDescFromPool( RES_POOLPAGE_BEGIN + i - RC_POOLPAGEDESC_BEGIN );
+                break;
+            }
+        }
+    }
+
+    return pRet;
+ }
+/******************************************************************************
+ ******************************************************************************
+ ******************************************************************************
+ * Taskforce ONE51
+ ******************************************************************************/
+/* -----------------24.02.99 14:18-------------------
+ * Der StartNode muss in einem existierenden Header/Footen liegen
+ * --------------------------------------------------*/
+sal_Bool lcl_IsStarNodeInFormat(sal_Bool bHeader, SwStartNode* pSttNode,
+    const SwFrmFmt* pFrmFmt, SwFrmFmt*& rpFormat)
+{
+    sal_Bool bRet = sal_False;
+    const SfxItemSet& rSet = pFrmFmt->GetAttrSet();
+    const SfxPoolItem* pItem;
+    SwFrmFmt* pHeadFootFmt;
+    if(SFX_ITEM_SET == rSet.GetItemState(bHeader ? RES_HEADER : RES_FOOTER, sal_True, &pItem) &&
+            0 != (pHeadFootFmt = bHeader ?
+                    ((SwFmtHeader*)pItem)->GetHeaderFmt() :
+                                ((SwFmtFooter*)pItem)->GetFooterFmt()))
+    {
+        const SwFmtCntnt& rFlyCntnt = pHeadFootFmt->GetCntnt();
+        const SwNode& rNode = rFlyCntnt.GetCntntIdx()->GetNode();
+        const SwStartNode* pCurSttNode = rNode.FindSttNodeByType(
+            bHeader ? SwHeaderStartNode : SwFooterStartNode);
+        if(pCurSttNode && pCurSttNode == pSttNode)
+        {
+            bRet = sal_True;
+            rpFormat = pHeadFootFmt;
+        }
+    }
+    return bRet;
+}
+
+/* -----------------03.11.98 15:58-------------------
+ *
+ * --------------------------------------------------*/
+uno::Reference< XTextRange >  CreateTextRangeFromPosition(SwDoc* pDoc,
+                        const SwPosition& rPos, const SwPosition* pMark)
+{
+    uno::Reference< XTextRange >  aRet;
+    SwUnoCrsr* pNewCrsr = pDoc->CreateUnoCrsr(rPos, sal_False);
+    if(pMark)
+    {
+        pNewCrsr->SetMark();
+        *pNewCrsr->GetMark() = *pMark;
+    }
+    uno::Reference< XText >  xParentText;
+    //jetzt besorgen wir uns mal den Parent:
+    SwStartNode* pSttNode = rPos.nNode.GetNode().FindStartNode();
+    while(pSttNode && pSttNode->IsSectionNode())
+    {
+        pSttNode = pSttNode->FindStartNode();
+    }
+    SwStartNodeType eType = pSttNode->GetStartNodeType();
+    switch(eType)
+    {
+        case SwTableBoxStartNode:
+        {
+            const SwTableNode* pTblNode = pSttNode->FindTableNode();
+            SwFrmFmt* pTableFmt = (SwFrmFmt*)pTblNode->GetTable().GetFrmFmt();
+            SwTableBox* pBox = pSttNode->GetTblBox();
+
+            if( pBox )
+                aRet = new SwXTextRange(*pTableFmt, *pBox, *pNewCrsr);
+            else
+                aRet = new SwXTextRange(*pTableFmt, *pSttNode, *pNewCrsr);
+        }
+        break;
+        case SwFlyStartNode:
+        {
+            SwFrmFmt* pFmt;
+            if(0 != (pFmt = pSttNode->GetFlyFmt()))
+            {
+                aRet = new SwXTextRange(*pFmt, *pNewCrsr);
+
+            }
+        }
+        break;
+        case SwHeaderStartNode:
+        case SwFooterStartNode:
+        {
+            sal_Bool bHeader = SwHeaderStartNode == eType;
+            sal_uInt16 nPDescCount = pDoc->GetPageDescCnt();
+            for(sal_uInt16 i = 0; i < nPDescCount; i++)
+            {
+                const SwPageDesc& rDesc = pDoc->GetPageDesc( i );
+                const SwFrmFmt* pFrmFmtMaster = &rDesc.GetMaster();
+                const SwFrmFmt* pFrmFmtLeft = &rDesc.GetLeft();
+
+                SwFrmFmt* pHeadFootFmt = 0;
+                if(!lcl_IsStarNodeInFormat(bHeader, pSttNode, pFrmFmtMaster, pHeadFootFmt))
+                    lcl_IsStarNodeInFormat(bHeader, pSttNode, pFrmFmtLeft, pHeadFootFmt);
+
+                if(pHeadFootFmt)
+                {
+                    SwXHeadFootText* pxHdFt = (SwXHeadFootText*)SwClientIter( *pHeadFootFmt ).
+                                    First( TYPE( SwXHeadFootText ));
+                    xParentText = pxHdFt;
+                    if(!pxHdFt)
+                        xParentText = new SwXHeadFootText(*pHeadFootFmt, bHeader);
+                    break;
+                }
+            }
+        }
+        break;
+        case SwFootnoteStartNode:
+        {
+            sal_uInt16 n, nFtnCnt = pDoc->GetFtnIdxs().Count();
+            SwTxtFtn* pTxtFtn;
+            uno::Reference< XFootnote >  xRef;
+            for( n = 0; n < nFtnCnt; ++n )
+            {
+                pTxtFtn = pDoc->GetFtnIdxs()[ n ];
+                const SwFmtFtn& rFtn = pTxtFtn->GetFtn();
+                const SwTxtFtn* pTxtFtn = rFtn.GetTxtFtn();
+#ifdef DEBUG
+                const SwStartNode* pTmpSttNode = pTxtFtn->GetStartNode()->GetNode().
+                                FindSttNodeByType(SwFootnoteStartNode);
+#endif
+
+                if(pSttNode == pTxtFtn->GetStartNode()->GetNode().
+                                    FindSttNodeByType(SwFootnoteStartNode))
+                {
+                    aRet = new SwXFootnote(pDoc, rFtn);
+                    break;
+                }
+            }
+        }
+        break;
+        default:
+        {
+            // dann ist es der Body-Text
+            uno::Reference xModel = pDoc->GetDocShell()->GetBaseModel();
+            uno::Reference< XTextDocument > xDoc(
+                xModel, uno::UNO_QUERY);
+            xParentText = xDoc->getText();
+        }
+    }
+    if(!aRet.is())
+        aRet = new SwXTextRange(*pNewCrsr, xParentText);
+    return aRet;
+}
+/******************************************************************
+ * SwXTextCursor
+ ******************************************************************/
+/*-----------------24.03.98 14:49-------------------
+
+--------------------------------------------------*/
+uno::Reference< uno::XInterface >  SwXTextCursor_NewInstance_Impl()
+{
+    return (cppu::OWeakObject*)new SwXTextCursor();
+};
+/*-- 09.12.98 14:19:19---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+OUString SwXTextCursor::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXTextCursor");
+}
+/*-- 09.12.98 14:19:19---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+BOOL SwXTextCursor::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    String sServiceName(rServiceName);
+    return sServiceName.EqualsAscii("com.sun.star.text.TextCursor") ||
+         sServiceName.EqualsAscii("com.sun.star.style.CharacterProperties")||
+         sServiceName.EqualsAscii("com.sun.star.style.ParagraphProperties");
+}
+/*-- 09.12.98 14:19:19---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Sequence< OUString > SwXTextCursor::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(3);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.TextCursor");
+     pArray[1] = C2U("com.sun.star.style.CharacterProperties");
+     pArray[2] = C2U("com.sun.star.style.ParagraphProperties");
+    return aRet;
+}
+/*-- 09.12.98 14:19:19---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextCursor::SwXTextCursor(uno::Reference< XText >  xParent, const SwPosition& rPos,
+                    CursorType eSet, SwDoc* pDoc, const SwPosition* pMark) :
+    aLstnrCntnr(( util::XSortable*)this),
+    xParentText(xParent),
+    aPropSet(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_CURSOR)),
+    pLastSortOptions(0),
+    eType(eSet)
+{
+    SwUnoCrsr* pUnoCrsr = pDoc->CreateUnoCrsr(rPos, sal_False);
+    if(pMark)
+    {
+        pUnoCrsr->SetMark();
+        *pUnoCrsr->GetMark() = *pMark;
+    }
+    pUnoCrsr->Add(this);
+}
+/*-- 09.12.98 14:19:19---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextCursor::SwXTextCursor(SwXText* pParent) :
+    xParentText(pParent),
+    aPropSet(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_CURSOR)),
+    pLastSortOptions(0),
+    eType(CURSOR_INVALID),
+    aLstnrCntnr( (util::XSortable*)this)
+{
+
+}
+/* -----------------04.03.99 09:02-------------------
+ *
+ * --------------------------------------------------*/
+SwXTextCursor::SwXTextCursor(uno::Reference< XText >  xParent,
+    SwUnoCrsr* pSourceCrsr, CursorType eSet) :
+    aLstnrCntnr( (util::XSortable*)this),
+    xParentText(xParent),
+    aPropSet(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_CURSOR)),
+    pLastSortOptions(0),
+    eType(eSet)
+{
+    SwUnoCrsr* pUnoCrsr = pSourceCrsr->GetDoc()->CreateUnoCrsr(*pSourceCrsr->GetPoint(), sal_False);
+    if(pSourceCrsr->HasMark())
+    {
+        pUnoCrsr->SetMark();
+        *pUnoCrsr->GetMark() = *pSourceCrsr->GetMark();
+    }
+    pUnoCrsr->Add(this);
+}
+
+/*-- 09.12.98 14:19:20---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextCursor::~SwXTextCursor()
+{
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    delete pUnoCrsr;
+    delete pLastSortOptions;
+}
+/*-- 09.12.98 14:19:18---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextCursor::DeleteAndInsert(const String& rText)
+{
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        // Start/EndAction
+        SwDoc* pDoc = pUnoCrsr->GetDoc();
+        UnoActionContext aAction(pDoc);
+        xub_StrLen nTxtLen = rText.Len();
+        pDoc->StartUndo(UNDO_INSERT);
+        SwCursor *_pStartCrsr = pUnoCrsr;
+        do
+        {
+            if(_pStartCrsr->HasMark())
+            {
+                pDoc->DeleteAndJoin(*_pStartCrsr);
+            }
+            if(nTxtLen)
+            {
+                //OPT: GetSystemCharSet
+                if( !pDoc->Insert(*_pStartCrsr, rText) )
+                    ASSERT( sal_False, "Doc->Insert(Str) failed." );
+                    SwXTextCursor::SelectPam(*pUnoCrsr, sal_True);
+                    _pStartCrsr->Left(rText.Len());
+            }
+        } while( (_pStartCrsr=(SwCursor*)_pStartCrsr->GetNext()) != pUnoCrsr );
+        pDoc->EndUndo(UNDO_INSERT);
+    }
+}
+/* -----------------------------10.03.00 18:02--------------------------------
+
+ ---------------------------------------------------------------------------*/
+const uno::Sequence< sal_Int8 > & SwXTextCursor::getUnoTunnelId()
+{
+    static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId();
+    return aSeq;
+}
+/* -----------------------------10.03.00 18:04--------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Int64 SAL_CALL SwXTextCursor::getSomething( const uno::Sequence< sal_Int8 >& rId )
+    throw(uno::RuntimeException)
+{
+    if( rId.getLength() == 16
+        && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+                                        rId.getConstArray(), 16 ) )
+    {
+            return (sal_Int64)this;
+    }
+    return 0;
+}
+
+/*-- 09.12.98 14:18:12---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextCursor::collapseToStart(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        if(*pUnoCrsr->GetPoint() < *pUnoCrsr->GetMark())
+            pUnoCrsr->Exchange();
+        if(pUnoCrsr->HasMark())
+            pUnoCrsr->DeleteMark();
+    }
+    else
+    {
+        throw uno::RuntimeException();
+    }
+}
+/*-- 09.12.98 14:18:14---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextCursor::collapseToEnd(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        if(pUnoCrsr->HasMark())
+        {
+            if(*pUnoCrsr->GetPoint() < *pUnoCrsr->GetMark())
+                pUnoCrsr->Exchange();
+            pUnoCrsr->DeleteMark();
+        }
+    }
+    else
+    {
+        throw uno::RuntimeException();
+    }
+}
+/*-- 09.12.98 14:18:41---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextCursor::isCollapsed(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Bool bRet = sal_True;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr && pUnoCrsr->GetMark())
+    {
+        bRet = (*pUnoCrsr->GetPoint() == *pUnoCrsr->GetMark());
+    }
+    return bRet;
+}
+/*-- 09.12.98 14:18:42---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextCursor::goLeft(sal_Int16 nCount, sal_Bool Expand) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Bool bRet = sal_False;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        SwXTextCursor::SelectPam(*pUnoCrsr, Expand);
+        bRet = pUnoCrsr->Left( nCount);
+    }
+    else
+    {
+        throw uno::RuntimeException();
+    }
+    return bRet;
+}
+/*-- 09.12.98 14:18:42---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextCursor::goRight(sal_Int16 nCount, sal_Bool Expand) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Bool bRet = sal_False;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        SwXTextCursor::SelectPam(*pUnoCrsr, Expand);
+        bRet = pUnoCrsr->Right(nCount);
+    }
+    else
+    {
+        throw uno::RuntimeException();
+    }
+    return bRet;
+}
+/*-- 09.12.98 14:18:43---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextCursor::gotoStart(sal_Bool Expand) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        SwXTextCursor::SelectPam(*pUnoCrsr, Expand);
+        if(eType == CURSOR_BODY)
+        {
+            pUnoCrsr->Move( fnMoveBackward, fnGoDoc );
+            //check, that the cursor is not in a table
+            SwTableNode* pTblNode = pUnoCrsr->GetNode()->FindTableNode();
+            SwCntntNode* pCont = 0;
+            while( pTblNode )
+            {
+                pUnoCrsr->GetPoint()->nNode = *pTblNode->EndOfSectionNode();
+                pCont = GetDoc()->GetNodes().GoNext(&pUnoCrsr->GetPoint()->nNode);
+                pTblNode = pCont->FindTableNode();
+            }
+            if(pCont)
+                pUnoCrsr->GetPoint()->nContent.Assign(pCont, 0);
+            const SwStartNode* pTmp = pUnoCrsr->GetNode()->FindStartNode();
+            if(pTmp->IsSectionNode())
+            {
+                SwSectionNode* pSectionStartNode = (SwSectionNode*)pTmp;
+                if(pSectionStartNode->GetSection().IsHiddenFlag())
+                {
+                    pCont = GetDoc()->GetNodes().GoNextSection(
+                                &pUnoCrsr->GetPoint()->nNode, sal_True, sal_False);
+                    if(pCont)
+                        pUnoCrsr->GetPoint()->nContent.Assign(pCont, 0);
+                }
+            }
+        }
+        else if(eType == CURSOR_FRAME ||
+                eType == CURSOR_TBLTEXT ||
+                eType == CURSOR_HEADER ||
+                eType == CURSOR_FOOTER ||
+                eType == CURSOR_FOOTNOTE)
+        {
+            pUnoCrsr->MoveSection( fnSectionCurr, fnSectionStart);
+        }
+        else
+            DBG_WARNING("not implemented")
+            ;
+    }
+    else
+    {
+        throw uno::RuntimeException();
+    }
+}
+/*-- 09.12.98 14:18:43---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextCursor::gotoEnd(sal_Bool Expand) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        SwXTextCursor::SelectPam(*pUnoCrsr, Expand);
+        if(eType == CURSOR_BODY)
+            pUnoCrsr->Move( fnMoveForward, fnGoDoc );
+        else if(eType == CURSOR_FRAME ||
+                eType == CURSOR_TBLTEXT ||
+                eType == CURSOR_HEADER ||
+                eType == CURSOR_FOOTER ||
+                eType == CURSOR_FOOTNOTE)
+        {
+            pUnoCrsr->MoveSection( fnSectionCurr, fnSectionEnd);
+        }
+        else
+            DBG_WARNING("not implemented");
+            ;
+    }
+    else
+    {
+        throw uno::RuntimeException();
+    }
+}
+/* -----------------05.03.99 07:27-------------------
+ *
+ * --------------------------------------------------*/
+void SwXTextCursor::gotoRange(const uno::Reference< XTextRange > & xRange, sal_Bool bExpand )
+                                throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwUnoCrsr* pOwnCursor = GetCrsr();
+    if(!pOwnCursor || !xRange.is())
+    {
+        throw uno::RuntimeException();
+    }
+
+    uno::Reference xRangeTunnel( xRange, uno::UNO_QUERY);
+    SwXTextRange* pRange = 0;
+    SwXTextCursor* pCursor = 0;
+    if(xRangeTunnel.is())
+    {
+        pRange = (SwXTextRange*)xRangeTunnel->getSomething(
+                                SwXTextRange::getUnoTunnelId());
+        pCursor = (SwXTextCursor*)xRangeTunnel->getSomething(
+                                SwXTextCursor::getUnoTunnelId());
+    }
+
+    SwStartNodeType eSearchNodeType = SwNormalStartNode;
+    switch(eType)
+    {
+        case CURSOR_FRAME:      eSearchNodeType = SwFlyStartNode;       break;
+        case CURSOR_TBLTEXT:    eSearchNodeType = SwTableBoxStartNode;  break;
+        case CURSOR_FOOTNOTE:   eSearchNodeType = SwFootnoteStartNode;  break;
+        case CURSOR_HEADER:     eSearchNodeType = SwHeaderStartNode;    break;
+        case CURSOR_FOOTER:     eSearchNodeType = SwFooterStartNode;    break;
+        //case CURSOR_INVALID:
+        //case CURSOR_BODY:
+    }
+    const SwStartNode* pOwnStartNode = pOwnCursor->GetNode()->
+                                            FindSttNodeByType(eSearchNodeType);
+
+    const SwNode* pSrcNode = 0;
+    if(pCursor && pCursor->GetCrsr())
+    {
+        pSrcNode = pCursor->GetCrsr()->GetNode();
+    }
+    else if(pRange && pRange->GetBookmark())
+    {
+        SwBookmark* pBkm = pRange->GetBookmark();
+        pSrcNode = &pBkm->GetPos().nNode.GetNode();
+    }
+    const SwStartNode* pTmp = pSrcNode ? pSrcNode->FindSttNodeByType(eSearchNodeType) : 0;
+
+    //SectionNodes ueberspringen
+    while(pTmp && pTmp->IsSectionNode())
+    {
+        pTmp = pTmp->FindStartNode();
+    }
+    if(pOwnStartNode != pTmp)
+    {
+        throw uno::RuntimeException();
+    }
+
+    //jetzt muss die Selektion erweitert werden
+    if(bExpand)
+    {
+        // der Cursor soll alles einschliessen, was bisher von ihm und dem uebergebenen
+        // Range eingeschlossen wurde
+        SwPosition aOwnLeft(*pOwnCursor->GetPoint());
+        SwPosition aOwnRight(pOwnCursor->HasMark() ? *pOwnCursor->GetMark() : aOwnLeft);
+        if(aOwnRight < aOwnLeft)
+        {
+            SwPosition aTmp = aOwnLeft;
+            aOwnLeft = aOwnRight;
+            aOwnRight = aTmp;
+        }
+        SwPosition* pParamLeft;
+        SwPosition* pParamRight;
+        if(pCursor)
+        {
+            const SwUnoCrsr* pTmp = pCursor->GetCrsr();
+            pParamLeft = new SwPosition(*pTmp->GetPoint());
+            pParamRight = new SwPosition(pTmp->HasMark() ? *pTmp->GetMark() : *pParamLeft);
+        }
+        else
+        {
+            SwBookmark* pBkm = pRange->GetBookmark();
+            pParamLeft = new SwPosition(pBkm->GetPos());
+            pParamRight = new SwPosition(pBkm->GetOtherPos() ? *pBkm->GetOtherPos() : *pParamLeft);
+        }
+        if(*pParamRight < *pParamLeft)
+        {
+            SwPosition* pTmp = pParamLeft;
+            pParamLeft = pParamRight;
+            pParamRight = pTmp;
+        }
+        // jetzt sind vier SwPositions da, zwei davon werden gebraucht, also welche?
+        if(aOwnRight < *pParamRight)
+            *pOwnCursor->GetPoint() = aOwnRight;
+        else
+            *pOwnCursor->GetPoint() = *pParamRight;
+        pOwnCursor->SetMark();
+        if(aOwnLeft < *pParamLeft)
+            *pOwnCursor->GetMark() = *pParamLeft;
+        else
+            *pOwnCursor->GetMark() = aOwnLeft;
+        delete pParamLeft;
+        delete pParamRight;
+    }
+    else
+    {
+        //der Cursor soll dem uebergebenen Range entsprechen
+        if(pCursor)
+        {
+            const SwUnoCrsr* pTmp = pCursor->GetCrsr();
+            *pOwnCursor->GetPoint() = *pTmp->GetPoint();
+            if(pTmp->HasMark())
+            {
+                pOwnCursor->SetMark();
+                *pOwnCursor->GetMark() = *pTmp->GetMark();
+            }
+            else
+                pOwnCursor->DeleteMark();
+        }
+        else
+        {
+            SwBookmark* pBkm = pRange->GetBookmark();
+            *pOwnCursor->GetPoint() = pBkm->GetPos();
+            if(pBkm->GetOtherPos())
+            {
+                pOwnCursor->SetMark();
+                *pOwnCursor->GetMark() = *pBkm->GetOtherPos();
+            }
+            else
+                pOwnCursor->DeleteMark();
+        }
+    }
+}
+
+/*-- 09.12.98 14:18:44---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextCursor::isStartOfWord(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Bool bRet = sal_False;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        bRet = pUnoCrsr->IsStartWord();
+    }
+    else
+    {
+        throw uno::RuntimeException();
+    }
+    return bRet;
+}
+/*-- 09.12.98 14:18:44---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextCursor::isEndOfWord(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Bool bRet = sal_False;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        bRet = pUnoCrsr->IsEndWord();
+    }
+    else
+    {
+        throw uno::RuntimeException();
+    }
+    return bRet;
+}
+/*-- 09.12.98 14:18:44---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextCursor::gotoNextWord(sal_Bool Expand) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    //Probleme gibt's noch mit einem Absatzanfang, an dem kein Wort beginnt.
+    sal_Bool bRet = sal_False;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        SwXTextCursor::SelectPam(*pUnoCrsr, Expand);
+        //Absatzende?
+        if(pUnoCrsr->GetCntntNode() &&
+                pUnoCrsr->GetPoint()->nContent == pUnoCrsr->GetCntntNode()->Len())
+                bRet = pUnoCrsr->Right();
+        else
+        {
+            bRet = pUnoCrsr->GoNextWord();
+            //if there is no next word within the current paragraph try to go to the start of the next paragraph
+            if(!bRet)
+                bRet = pUnoCrsr->MovePara(fnParaNext, fnParaStart);
+        }
+    }
+    else
+    {
+        throw uno::RuntimeException();
+    }
+    return bRet;
+}
+/*-- 09.12.98 14:18:45---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextCursor::gotoPreviousWord(sal_Bool Expand) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    // hier machen Leerzeichen am Absatzanfang Probleme
+    sal_Bool bRet = sal_False;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        SwXTextCursor::SelectPam(*pUnoCrsr, Expand);
+        //Absatzanfang ?
+        if(pUnoCrsr->GetPoint()->nContent == 0)
+            bRet = pUnoCrsr->Left();
+        else
+        {
+            bRet = pUnoCrsr->GoPrevWord();
+            if(pUnoCrsr->GetPoint()->nContent == 0)
+                pUnoCrsr->Left();
+        }
+    }
+    else
+    {
+        throw uno::RuntimeException();
+    }
+    return bRet;
+}
+/*-- 09.12.98 14:18:45---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextCursor::gotoEndOfWord(sal_Bool Expand) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Bool bRet = sal_False;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        SwXTextCursor::SelectPam(*pUnoCrsr, Expand);
+        if(!pUnoCrsr->IsEndWord())
+        {
+            bRet = pUnoCrsr->GoEndWord();
+        }
+    }
+    else
+    {
+        throw uno::RuntimeException();
+    }
+    return bRet;
+}
+/*-- 09.12.98 14:18:46---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextCursor::gotoStartOfWord(sal_Bool Expand) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    sal_Bool bRet = FALSE;
+    if(pUnoCrsr)
+    {
+        SwXTextCursor::SelectPam(*pUnoCrsr, Expand);
+        if(!pUnoCrsr->IsStartWord())
+        {
+            bRet = pUnoCrsr->GoStartWord();
+        }
+    }
+    else
+    {
+        throw uno::RuntimeException();
+    }
+    return bRet;
+}
+/*-- 09.12.98 14:18:46---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextCursor::isStartOfSentence(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Bool bRet = sal_False;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        // Absatzanfang?
+        bRet = pUnoCrsr->GetPoint()->nContent == 0;
+        // mitMarkierung ->kein Satzanfang
+        if(!bRet && !pUnoCrsr->HasMark())
+        {
+            SwCursor aCrsr(*pUnoCrsr->GetPoint());
+            aCrsr.LeftRight(sal_True, 1);
+            aCrsr.SetMark();
+            if(aCrsr.LeftRight(sal_True, 1))
+            {
+                SwTxtNode* pTxtNd = aCrsr.GetNode()->GetTxtNode();
+                if( pTxtNd )
+                {
+                    xub_StrLen nStt = aCrsr.Start()->nContent.GetIndex();
+                    String aTxt = pTxtNd->GetExpandTxt( nStt,
+                        aCrsr.End()->nContent.GetIndex() - nStt );
+                    char cChar = aTxt.GetChar(0);
+                    switch(cChar)
+                    {
+                        case ';':
+                        case '.':
+                        case ':':
+                        case '!':
+                        case '?':
+                            bRet = sal_True;
+                        break;
+                    }
+                }
+            }
+        }
+    }
+    else
+        throw uno::RuntimeException();
+    return bRet;
+}
+/*-- 09.12.98 14:18:47---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextCursor::isEndOfSentence(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Bool bRet = sal_False;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        //Absatzende?
+        bRet = pUnoCrsr->GetCntntNode() &&
+                pUnoCrsr->GetPoint()->nContent == pUnoCrsr->GetCntntNode()->Len();
+        // mitMarkierung ->kein Satzende
+        if(!bRet && !pUnoCrsr->HasMark())
+        {
+            SwCursor aCrsr(*pUnoCrsr->GetPoint());
+            aCrsr.SetMark();
+            if(aCrsr.LeftRight(sal_True, 1))
+            {
+                SwTxtNode* pTxtNd = aCrsr.GetNode()->GetTxtNode();
+                if( pTxtNd )
+                {
+                    xub_StrLen nStt = aCrsr.Start()->nContent.GetIndex();
+                    String aTxt = pTxtNd->GetExpandTxt( nStt,
+                        aCrsr.End()->nContent.GetIndex() - nStt );
+                    char cChar = aTxt.GetChar(0);
+                    switch(cChar)
+                    {
+                        case ';':
+                        case '.':
+                        case ':':
+                        case '!':
+                        case '?':
+                            bRet = sal_True;
+                        break;
+                    }
+                }
+            }
+        }
+    }
+    else
+        throw uno::RuntimeException();
+    return bRet;
+}
+/*-- 09.12.98 14:18:47---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextCursor::gotoNextSentence(sal_Bool Expand) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Bool bRet = sal_False;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        SwXTextCursor::SelectPam(*pUnoCrsr, Expand);
+        bRet = pUnoCrsr->GoSentence(SwCursor::NEXT_SENT);
+        if(!bRet)
+            bRet = pUnoCrsr->MovePara(fnParaNext, fnParaStart);
+    }
+    else
+        throw uno::RuntimeException();
+    return bRet;
+}
+/*-- 09.12.98 14:18:47---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextCursor::gotoPreviousSentence(sal_Bool Expand) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Bool bRet = sal_False;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        SwXTextCursor::SelectPam(*pUnoCrsr, Expand);
+        bRet = pUnoCrsr->GoSentence(SwCursor::PREV_SENT);
+        if(!bRet)
+        {
+            if(0 != (bRet = pUnoCrsr->MovePara(fnParaPrev, fnParaStart)))
+            {
+                pUnoCrsr->MovePara(fnParaCurr, fnParaEnd);
+                //at the end of a paragraph move to the sentence end again
+                //
+                pUnoCrsr->GoSentence(SwCursor::PREV_SENT);
+            }
+        }
+    }
+    else
+        throw uno::RuntimeException();
+    return bRet;
+}
+/* -----------------15.10.99 08:24-------------------
+
+ --------------------------------------------------*/
+sal_Bool SwXTextCursor::gotoStartOfSentence(sal_Bool Expand) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Bool bRet = sal_False;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        SwXTextCursor::SelectPam(*pUnoCrsr, Expand);
+        // if we're at the para start then we wont move
+        // but bRet is also true if GoSentence failed but
+        // the start of the sentence is reached
+        bRet = lcl_IsStartOfPara(*pUnoCrsr)
+            || pUnoCrsr->GoSentence(SwCursor::START_SENT) ||
+            lcl_IsStartOfPara(*pUnoCrsr);
+    }
+    else
+        throw uno::RuntimeException();
+    return bRet;
+}
+/* -----------------15.10.99 08:24-------------------
+
+ --------------------------------------------------*/
+sal_Bool SwXTextCursor::gotoEndOfSentence(sal_Bool Expand) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Bool bRet = sal_False;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        SwXTextCursor::SelectPam(*pUnoCrsr, Expand);
+        // bRet is true if GoSentence() succeeded or if the
+        // MovePara() succeeded while the end of the para is
+        // not reached already
+        sal_Bool bAlreadyParaEnd = lcl_IsEndOfPara(*pUnoCrsr);
+        bRet = !bAlreadyParaEnd &&
+                    (pUnoCrsr->GoSentence(SwCursor::END_SENT) ||
+                        pUnoCrsr->MovePara(fnParaCurr, fnParaEnd));
+
+    }
+    else
+        throw uno::RuntimeException();
+    return bRet;
+}
+
+/*-- 09.12.98 14:18:48---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextCursor::isStartOfParagraph(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Bool bRet = sal_False;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+        bRet = lcl_IsStartOfPara(*pUnoCrsr);
+    else
+        throw uno::RuntimeException();
+    return bRet;
+}
+/*-- 09.12.98 14:18:48---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextCursor::isEndOfParagraph(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Bool bRet = sal_False;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+        bRet = lcl_IsEndOfPara(*pUnoCrsr);
+    else
+        throw uno::RuntimeException();
+    return bRet;
+}
+/*-- 09.12.98 14:18:49---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextCursor::gotoStartOfParagraph(sal_Bool Expand) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Bool bRet = sal_False;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr )
+    {
+        SwXTextCursor::SelectPam(*pUnoCrsr, Expand);
+        bRet = lcl_IsStartOfPara(*pUnoCrsr);
+        if(!bRet)
+            bRet = pUnoCrsr->MovePara(fnParaCurr, fnParaStart);
+    }
+    else
+        throw uno::RuntimeException();
+    return bRet;
+}
+/*-- 09.12.98 14:18:49---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextCursor::gotoEndOfParagraph(sal_Bool Expand) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Bool bRet = sal_False;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        SwXTextCursor::SelectPam(*pUnoCrsr, Expand);
+        bRet = lcl_IsEndOfPara(*pUnoCrsr);
+        if(!bRet)
+            pUnoCrsr->MovePara(fnParaCurr, fnParaEnd);
+    }
+    else
+        throw uno::RuntimeException();
+    return bRet;
+}
+/*-- 09.12.98 14:18:50---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextCursor::gotoNextParagraph(sal_Bool Expand) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Bool bRet = sal_False;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        SwXTextCursor::SelectPam(*pUnoCrsr, Expand);
+        bRet = pUnoCrsr->MovePara(fnParaNext, fnParaStart);
+    }
+    else
+        throw uno::RuntimeException();
+    return bRet;
+}
+/*-- 09.12.98 14:18:50---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextCursor::gotoPreviousParagraph(sal_Bool Expand) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Bool bRet = sal_False;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        SwXTextCursor::SelectPam(*pUnoCrsr, Expand);
+        bRet = pUnoCrsr->MovePara(fnParaPrev, fnParaStart);
+    }
+    else
+        throw uno::RuntimeException();
+    return bRet;
+}
+/*-- 09.12.98 14:18:50---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XText >  SwXTextCursor::getText(void) throw( uno::RuntimeException )
+{
+    return xParentText;
+}
+/*-- 09.12.98 14:18:50---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XTextRange >  SwXTextCursor::getStart(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< XTextRange >  xRet;
+    SwUnoCrsr* pUnoCrsr = ((SwXTextCursor*)this)->GetCrsr();
+    if( pUnoCrsr)
+    {
+        SwPaM aPam(*pUnoCrsr->Start());
+        uno::Reference< XText >  xParent = getText();
+        xRet = new SwXTextRange(aPam, xParent);
+    }
+    else
+        throw uno::RuntimeException();
+    return xRet;
+}
+/*-- 09.12.98 14:18:51---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XTextRange >  SwXTextCursor::getEnd(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< XTextRange >  xRet;
+    SwUnoCrsr* pUnoCrsr = ((SwXTextCursor*)this)->GetCrsr();
+    if( pUnoCrsr)
+    {
+        SwPaM aPam(*pUnoCrsr->End());
+        uno::Reference< XText >  xParent = getText();
+        xRet = new SwXTextRange(aPam, xParent);
+    }
+    else
+        throw uno::RuntimeException();
+    return xRet;
+}
+/*-- 09.12.98 14:18:51---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+OUString SwXTextCursor::getString(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    OUString aTxt;
+    SwUnoCrsr* pUnoCrsr = ((SwXTextCursor*)this)->GetCrsr();
+    if( pUnoCrsr)
+    {
+/*      if( pUnoCrsr->GetPoint()->nNode.GetIndex() ==
+            pUnoCrsr->GetMark()->nNode.GetIndex() )
+        {
+            SwTxtNode* pTxtNd = pUnoCrsr->GetNode()->GetTxtNode();
+            if( pTxtNd )
+            {
+                sal_uInt16 nStt = pUnoCrsr->Start()->nContent.GetIndex();
+                aTxt = pTxtNd->GetExpandTxt( nStt,
+                        pUnoCrsr->End()->nContent.GetIndex() - nStt );
+            }
+        }
+        else
+*/      {
+            //Text ueber mehrere Absaetze
+            SwXTextCursor::getTextFromPam(*pUnoCrsr, aTxt);
+        }
+    }
+    else
+        throw uno::RuntimeException();
+    return aTxt;
+}
+/*-- 09.12.98 14:18:52---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextCursor::setString(const OUString& aString) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(!pUnoCrsr)
+        throw uno::RuntimeException();
+
+    EXCEPT_ON_PROTECTION(*pUnoCrsr)
+
+    DeleteAndInsert(aString);
+}
+/* -----------------------------03.05.00 12:56--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Any SwXTextCursor::GetPropertyValue(
+    SwPaM& rPaM, const SfxItemPropertySet& rPropSet, const OUString& rPropertyName)
+        throw( UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+    Any aAny;
+    SfxItemSet aSet(rPaM.GetDoc()->GetAttrPool(),
+        RES_CHRATR_BEGIN,   RES_PARATR_NUMRULE,
+        RES_UNKNOWNATR_CONTAINER, RES_UNKNOWNATR_CONTAINER,
+        RES_FILL_ORDER,     RES_FRMATR_END -1,
+        0L);
+    SwXTextCursor::GetCrsrAttr(rPaM, aSet);
+
+    String aPropertyName(rPropertyName);
+    const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                                rPropSet.getPropertyMap(), rPropertyName);
+    BOOL bDone = FALSE;
+    if(pMap)
+    {
+        PropertyState eTemp;
+        bDone = lcl_getCrsrPropertyValue(pMap, rPaM, aSet, aAny, eTemp );
+        if(!bDone)
+            aAny = rPropSet.getPropertyValue(aPropertyName, aSet);
+    }
+    else
+        throw UnknownPropertyException();
+    return aAny;
+}
+/* -----------------------------03.05.00 12:57--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SwXTextCursor::SetPropertyValue(
+    SwPaM& rPaM, const SfxItemPropertySet& rPropSet, const OUString& rPropertyName, const Any& aValue)
+        throw (UnknownPropertyException, PropertyVetoException,
+            IllegalArgumentException, WrappedTargetException, RuntimeException)
+{
+    Any aAny;
+    EXCEPT_ON_PROTECTION(rPaM)
+
+    SwDoc* pDoc = rPaM.GetDoc();
+    const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                            rPropSet.getPropertyMap(), rPropertyName);
+    if(pMap)
+    {
+        SfxItemSet rSet(pDoc->GetAttrPool(),
+            pMap->nWID, pMap->nWID);
+        SwXTextCursor::GetCrsrAttr(rPaM, rSet);
+        BOOL bDef = FALSE;
+        BOOL bPut;
+        if(!lcl_setCrsrPropertyValue(pMap, rPaM, rSet, aValue, bPut ))
+            rPropSet.setPropertyValue(rPropertyName, aValue, rSet);
+        if(bPut)
+            SwXTextCursor::SetCrsrAttr(rPaM, rSet);
+    }
+    else
+        throw UnknownPropertyException();
+}
+/* -----------------------------03.05.00 13:16--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< PropertyState > SwXTextCursor::GetPropertyStates(
+            SwPaM& rPaM, SfxItemPropertySet& rPropSet,
+            const Sequence< OUString >& PropertyNames)
+            throw(UnknownPropertyException, RuntimeException)
+{
+    const OUString* pNames = PropertyNames.getConstArray();
+    Sequence< PropertyState > aRet(PropertyNames.getLength());
+    PropertyState* pStates = aRet.getArray();
+    for(INT32 i = 0; i < PropertyNames.getLength(); i++)
+        pStates[i] = GetPropertyState(rPaM, rPropSet, pNames[i]);
+    return aRet;
+}
+/* -----------------------------03.05.00 13:17--------------------------------
+
+ ---------------------------------------------------------------------------*/
+PropertyState SwXTextCursor::GetPropertyState(
+    SwPaM& rPaM, SfxItemPropertySet& rPropSet, const OUString& rPropertyName)
+                        throw(UnknownPropertyException, RuntimeException)
+{
+    PropertyState eRet = PropertyState_DEFAULT_VALUE;
+    SfxItemSet aSet(rPaM.GetDoc()->GetAttrPool(),
+        RES_CHRATR_BEGIN,   RES_PARATR_NUMRULE,
+        RES_FILL_ORDER,     RES_FRMATR_END -1,
+        0L);
+    SwXTextCursor::GetCrsrAttr(rPaM, aSet, FALSE);
+    String aPropertyName(rPropertyName);
+    const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                            rPropSet.getPropertyMap(), rPropertyName);
+
+    if(pMap)
+    {
+        Any aAny;
+        BOOL bDone = lcl_getCrsrPropertyValue(pMap, rPaM, aSet, aAny, eRet );
+        if(!bDone)
+                eRet = rPropSet.getPropertyState(aPropertyName, aSet);
+        //try again to find out if a value has been inherited
+        if(beans::PropertyState_DIRECT_VALUE == eRet)
+        {
+            SfxItemSet aDirectSet(rPaM.GetDoc()->GetAttrPool(),
+                RES_CHRATR_BEGIN,   RES_PARATR_NUMRULE,
+                RES_FILL_ORDER,     RES_FRMATR_END -1,
+                0L);
+            SwXTextCursor::GetCrsrAttr(rPaM, aDirectSet, TRUE);
+            bDone = lcl_getCrsrPropertyValue(pMap, rPaM, aDirectSet, aAny, eRet );
+            if(!bDone)
+                    eRet = rPropSet.getPropertyState(aPropertyName, aDirectSet);
+        }
+    }
+    else
+        throw UnknownPropertyException();
+    return eRet;
+}
+/* -----------------------------03.05.00 13:20--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SwXTextCursor::SetPropertyToDefault(
+    SwPaM& rPaM, const SfxItemPropertySet& rPropSet,
+    const OUString& rPropertyName)
+    throw(UnknownPropertyException, RuntimeException)
+{
+    NAMESPACE_VOS(OGuard) aGuard(Application::GetSolarMutex());
+    SwDoc* pDoc = rPaM.GetDoc();
+    const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                            rPropSet.getPropertyMap(), rPropertyName);
+    if(pMap)
+    {
+        if(pMap->nWID < RES_FRMATR_END)
+        {
+            SvUShortsSort aWhichIds;
+            aWhichIds.Insert(pMap->nWID);
+            if(pMap->nWID < RES_PARATR_BEGIN)
+                pDoc->ResetAttr(rPaM, TRUE, &aWhichIds);
+            else
+            {
+                //fuer Absatzattribute muss die Selektion jeweils auf
+                //Absatzgrenzen erweitert werden
+                SwPosition aStart = *rPaM.Start();
+                SwPosition aEnd = *rPaM.End();
+                SwUnoCrsr* pTemp = pDoc->CreateUnoCrsr(aStart, FALSE);
+                if(!lcl_IsStartOfPara(*pTemp))
+                {
+                    pTemp->MovePara(fnParaCurr, fnParaStart);
+                }
+                pTemp->SetMark();
+                *pTemp->GetPoint() = aEnd;
+                //pTemp->Exchange();
+                SwXTextCursor::SelectPam(*pTemp, TRUE);
+                if(!lcl_IsEndOfPara(*pTemp))
+                {
+                    pTemp->MovePara(fnParaCurr, fnParaEnd);
+                }
+                pDoc->ResetAttr(*pTemp, TRUE, &aWhichIds);
+                delete pTemp;
+            }
+        }
+        else
+            lcl_resetCrsrPropertyValue(pMap, rPaM);
+    }
+    else
+        throw UnknownPropertyException();
+}
+/* -----------------------------03.05.00 13:19--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Any SwXTextCursor::GetPropertyDefault(
+    SwPaM& rPaM, const SfxItemPropertySet& rPropSet,
+    const OUString& rPropertyName)
+    throw( UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+    Any aRet;
+    SwDoc* pDoc = rPaM.GetDoc();
+    const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                            rPropSet.getPropertyMap(), rPropertyName);
+    if(pMap)
+    {
+        if(pMap->nWID < RES_FRMATR_END)
+        {
+            const SfxPoolItem& rDefItem =
+                pDoc->GetAttrPool().GetDefaultItem(pMap->nWID);
+            rDefItem.QueryValue(aRet, pMap->nMemberId);
+        }
+    }
+    else
+        throw UnknownPropertyException();
+    return aRet;
+}
+/*-- 09.12.98 14:18:54---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< beans::XPropertySetInfo >  SwXTextCursor::getPropertySetInfo(void) throw( uno::RuntimeException )
+{
+    static uno::Reference< beans::XPropertySetInfo >  xRef = aPropSet.getPropertySetInfo();
+    return xRef;
+}
+/*-- 09.12.98 14:18:54---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextCursor::setPropertyValue(const OUString& rPropertyName, const uno::Any& aValue)
+        throw( beans::UnknownPropertyException, beans::PropertyVetoException,
+             lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Any aAny;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        SetPropertyValue(*pUnoCrsr, aPropSet, rPropertyName, aValue);
+    }
+    else
+        throw uno::RuntimeException();
+
+}
+/*-- 09.12.98 14:18:55---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Any SwXTextCursor::getPropertyValue(const OUString& rPropertyName)
+    throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Any aAny;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        aAny = GetPropertyValue(*pUnoCrsr, aPropSet, rPropertyName);
+    }
+    else
+        throw uno::RuntimeException();
+    return aAny;
+
+}
+/*-- 09.12.98 14:18:55---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextCursor::addPropertyChangeListener(const OUString& PropertyName, const uno::Reference< beans::XPropertyChangeListener > & aListener) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 09.12.98 14:18:57---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextCursor::removePropertyChangeListener(const OUString& PropertyName, const uno::Reference< beans::XPropertyChangeListener > & aListener) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 09.12.98 14:18:57---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextCursor::addVetoableChangeListener(const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener > & aListener) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 09.12.98 14:18:58---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextCursor::removeVetoableChangeListener(const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener > & aListener) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 05.03.99 11:36:11---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+beans::PropertyState SwXTextCursor::getPropertyState(const OUString& rPropertyName)
+                        throw( beans::UnknownPropertyException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    beans::PropertyState eRet = beans::PropertyState_DEFAULT_VALUE;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        eRet = GetPropertyState(*pUnoCrsr, aPropSet, rPropertyName);
+    }
+    else
+        throw RuntimeException();
+    return eRet;
+}
+/*-- 05.03.99 11:36:11---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Sequence< beans::PropertyState > SwXTextCursor::getPropertyStates(
+            const uno::Sequence< OUString >& PropertyNames)
+            throw( beans::UnknownPropertyException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(!pUnoCrsr)
+        throw RuntimeException();
+    return GetPropertyStates(*pUnoCrsr, aPropSet, PropertyNames);
+}
+/*-- 05.03.99 11:36:12---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextCursor::setPropertyToDefault(const OUString& rPropertyName)
+    throw( beans::UnknownPropertyException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        SetPropertyToDefault(*pUnoCrsr, aPropSet, rPropertyName);
+    }
+    else
+        throw uno::RuntimeException();
+}
+/*-- 05.03.99 11:36:12---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXTextCursor::getPropertyDefault(const OUString& rPropertyName)
+    throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    uno::Any aRet;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        aRet = GetPropertyDefault(*pUnoCrsr, aPropSet, rPropertyName);
+    }
+    else
+        throw uno::RuntimeException();
+    return aRet;
+}
+/*-- 09.12.98 14:18:58---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextCursor::insertDocumentFromURL(const OUString& rURL,
+    const uno::Sequence< beans::PropertyValue >& aOptions)
+    throw( lang::IllegalArgumentException, io::IOException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        String sFilterName;
+        String sFilterOption;
+        String sPassword;
+        OUString uFilterName(C2U(   UNO_NAME_FILTER_NAME    ));
+        OUString uFilterOption(C2U( UNO_NAME_FILTER_OPTION  ));
+        OUString uPassword(C2U( UNO_NAME_PASSWORD ));
+        sal_Bool bIllegalArgument = sal_False;
+
+        for ( int n = 0; n < aOptions.getLength(); ++n )
+        {
+            // get Property-Value from options
+            const beans::PropertyValue &rProp = aOptions.getConstArray()[n];
+            uno::Any aValue( rProp.Value );
+
+            // FilterName-Property?
+            if ( rProp.Name == uFilterName )
+            {
+                if ( rProp.Value.getValueType() == ::getCppuType((const OUString*)0))
+                {
+                    OUString uFilterName;
+                    rProp.Value >>= uFilterName;
+                    sFilterName = String(uFilterName);
+                }
+                else if ( rProp.Value.getValueType() != ::getVoidCppuType() )
+                    bIllegalArgument = sal_True;
+            }
+            else if( rProp.Name == uFilterOption )
+            {
+                if ( rProp.Value.getValueType() == ::getCppuType((const OUString*)0))
+                {
+                    OUString uFilterOption;
+                    rProp.Value >>= uFilterOption;
+                    sFilterOption = String(uFilterOption) ;
+                }
+                else if ( rProp.Value.getValueType() != ::getVoidCppuType() )
+
+                    bIllegalArgument = sal_True;
+            }
+            else if( rProp.Name == uPassword )
+            {
+                if ( rProp.Value.getValueType() == ::getCppuType((const OUString*)0))
+                {
+                    OUString uPassword;
+                    rProp.Value >>= uPassword;
+                    sPassword = String(uPassword );
+                }
+                else if ( rProp.Value.getValueType() != ::getVoidCppuType() )
+                    bIllegalArgument = sal_True;
+            }
+            else if(rProp.Value.getValueType() != ::getVoidCppuType())
+                bIllegalArgument = sal_True;
+        }
+        if(bIllegalArgument)
+            throw lang::IllegalArgumentException();
+        lcl_InsertFile(pUnoCrsr, rURL, sFilterName, sFilterOption, sPassword);
+    }
+    else
+        throw uno::RuntimeException();
+}
+/*-- 09.12.98 14:18:58---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Sequence< beans::PropertyValue > SwXTextCursor::createSortDescriptor(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Sequence< beans::PropertyValue > aRet(12);
+    beans::PropertyValue* pArray = aRet.getArray();
+
+    uno::Any aVal;
+    sal_Bool bFalse = sal_False;
+    sal_Bool bTrue = sal_True;
+    aVal.setValue( &bFalse, ::getCppuBooleanType());
+    pArray[0] = beans::PropertyValue(C2U("IsSortInTable"), -1, aVal, beans::PropertyState_DIRECT_VALUE);
+
+    String sSpace(String::CreateFromAscii(" "));
+    sal_Unicode uSpace = sSpace.GetChar(0);
+    aVal.setValue( &uSpace, ::getCppuCharType());
+    pArray[1] = beans::PropertyValue(C2U("Delimiter"), -1, aVal, beans::PropertyState_DIRECT_VALUE);
+
+    aVal.setValue( &bTrue, ::getCppuBooleanType());
+    pArray[2] = beans::PropertyValue(C2U("SortColumns"), -1, aVal, beans::PropertyState_DIRECT_VALUE);
+
+    aVal <<= (INT16)1;
+    pArray[3] = beans::PropertyValue(C2U("SortRowOrColumnNo0"), -1, aVal, beans::PropertyState_DIRECT_VALUE);
+
+    aVal.setValue( &bTrue, ::getCppuBooleanType());
+    pArray[4] = beans::PropertyValue(C2U("IsSortNumeric0"), -1, aVal, beans::PropertyState_DIRECT_VALUE);
+
+    aVal.setValue( &bTrue, ::getCppuBooleanType());
+    pArray[5] = beans::PropertyValue(C2U("IsSortAscending0"), -1, aVal, beans::PropertyState_DIRECT_VALUE);
+
+    aVal <<= (INT16)1;
+    pArray[6] = beans::PropertyValue(C2U("SortRowOrColumnNo1"), -1, aVal, beans::PropertyState_DIRECT_VALUE);
+
+    aVal.setValue( &bTrue, ::getCppuBooleanType());
+    pArray[7] = beans::PropertyValue(C2U("IsSortNumeric1"), -1, aVal, beans::PropertyState_DIRECT_VALUE);
+
+    aVal.setValue( &bTrue, ::getCppuBooleanType());
+    pArray[8] = beans::PropertyValue(C2U("IsSortAscending1"), -1, aVal, beans::PropertyState_DIRECT_VALUE);
+
+    aVal <<= (INT16)1;
+    pArray[9] = beans::PropertyValue(C2U("SortRowOrColumnNo2"), -1, aVal, beans::PropertyState_DIRECT_VALUE);
+
+    aVal.setValue( &bTrue, ::getCppuBooleanType());
+    pArray[10] = beans::PropertyValue(C2U("IsSortNumeric2"), -1, aVal, beans::PropertyState_DIRECT_VALUE);
+
+    aVal.setValue( &bTrue, ::getCppuBooleanType());
+    pArray[11] = beans::PropertyValue(C2U("IsSortAscending2"), -1, aVal, beans::PropertyState_DIRECT_VALUE);
+    return aRet;
+}
+/*-- 09.12.98 14:19:00---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextCursor::sort(const uno::Sequence< beans::PropertyValue >& rDescriptor)
+        throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+
+    const beans::PropertyValue* pProperties = rDescriptor.getConstArray();
+    SwSortOptions aSortOpt;
+
+    aSortOpt.bTable = sal_False;
+    aSortOpt.nDeli = ' ';
+    aSortOpt.eDirection = SRT_COLUMNS;
+
+    aSortOpt.aKeys;
+    SwSortKey* pKey1 = new SwSortKey;
+    pKey1->nColumnId = USHRT_MAX;
+    pKey1->eSortKeyType = SRT_NUMERIC;
+    pKey1->eSortOrder   = SRT_ASCENDING;
+
+    SwSortKey* pKey2 = new SwSortKey;
+    pKey2->nColumnId = USHRT_MAX;
+    pKey2->eSortKeyType = SRT_NUMERIC;
+    pKey2->eSortOrder   = SRT_ASCENDING;
+
+    SwSortKey* pKey3 = new SwSortKey;
+    pKey3->nColumnId = USHRT_MAX;
+    pKey3->eSortKeyType = SRT_NUMERIC;
+    pKey3->eSortOrder   = SRT_ASCENDING;
+    SwSortKey* aKeys[3] = {pKey1, pKey2, pKey3};
+
+    for( int n = 0; n < rDescriptor.getLength(); ++n )
+    {
+        uno::Any aValue( pProperties[n].Value );
+//      String sPropName = pProperties[n].Name;
+        const OUString& rPropName = pProperties[n].Name;
+        if( COMPARE_EQUAL == rPropName.compareToAscii("IsSortInTable"))
+        {
+            if ( aValue.getValueType() == ::getBooleanCppuType() )
+            {
+                aValue >>= aSortOpt.bTable;
+            }
+            else
+                throw uno::RuntimeException();
+        }
+        else if(COMPARE_EQUAL == rPropName.compareToAscii("Delimiter"))
+        {
+            if ( aValue.getValueType() == ::getCppuType((sal_Unicode*)0))
+            {
+                sal_Unicode uChar;
+                aValue >>= uChar;
+                aSortOpt.nDeli = uChar;
+            }
+            else
+                throw uno::RuntimeException();
+        }
+        else if(COMPARE_EQUAL == rPropName.compareToAscii("SortColumns"))
+        {
+            if ( aValue.getValueType() == ::getBooleanCppuType() )
+            {
+                sal_Bool bTemp;
+                aValue >>= bTemp;
+                aSortOpt.eDirection = bTemp ? SRT_COLUMNS : SRT_ROWS;
+            }
+            else
+                throw uno::RuntimeException();
+        }
+        else if(COMPARE_EQUAL == rPropName.compareToAscii("SortRowOrColumnNo", 17) &&
+            rPropName.getLength() == 18 &&
+            (rPropName.getStr()[17] >= '0' && rPropName.getStr()[17] <= '9'))
+        {
+            sal_uInt16 nIndex = rPropName.getStr()[17];
+            nIndex -= '0';
+            sal_Int16 nCol = -1;
+            if( aValue.getValueType() == ::getCppuType((const sal_Int16*)0) && nIndex < 3)
+                aValue >>= nCol;
+            if( nCol >= 0 )
+            {
+                aKeys[nIndex]->nColumnId = nCol;
+            }
+            else
+                throw uno::RuntimeException();
+        }
+        else if(0 == rPropName.search(C2U("IsSortNumeric")) &&
+            rPropName.getLength() == 14 &&
+            (rPropName.getStr()[13] >= '0' && rPropName.getStr()[13] <= '9'))
+        {
+            sal_uInt16 nIndex = rPropName.getStr()[13];
+            nIndex = nIndex - '0';
+            if ( aValue.getValueType() == ::getBooleanCppuType() && nIndex < 3 )
+            {
+                sal_Bool bTemp;
+                aValue >>= bTemp;
+                aKeys[nIndex]->eSortKeyType = bTemp ? SRT_NUMERIC : SRT_APLHANUM;
+            }
+            else
+                throw uno::RuntimeException();
+        }
+        else if(0 == rPropName.search(C2U("IsSortAscending")) && rPropName.getLength() == 16 &&
+            lcl_IsNumeric(String(rPropName[(sal_uInt16)15])))
+        {
+            sal_uInt16 nIndex = rPropName.getStr()[13];
+            if ( aValue.getValueType() == ::getBooleanCppuType() && nIndex < 3 )
+            {
+                sal_Bool bTemp;
+                aValue >>= bTemp;
+                aKeys[nIndex]->eSortOrder = bTemp ? SRT_ASCENDING : SRT_DESCENDING;
+            }
+            else
+                throw uno::RuntimeException();
+        }
+    }
+    if(pKey1->nColumnId != USHRT_MAX)
+        aSortOpt.aKeys.C40_INSERT(SwSortKey, pKey1, aSortOpt.aKeys.Count());
+    if(pKey2->nColumnId != USHRT_MAX)
+        aSortOpt.aKeys.C40_INSERT(SwSortKey, pKey2, aSortOpt.aKeys.Count());
+    if(pKey3->nColumnId != USHRT_MAX)
+        aSortOpt.aKeys.C40_INSERT(SwSortKey, pKey3, aSortOpt.aKeys.Count());
+
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr && aSortOpt.aKeys.Count())
+    {
+        if(pUnoCrsr->HasMark())
+        {
+            UnoActionContext aContext( pUnoCrsr->GetDoc() );
+            pUnoCrsr->GetDoc()->SortText(*pUnoCrsr, aSortOpt);
+        }
+    }
+    else
+        throw uno::RuntimeException();
+}
+/*-- 10.12.98 11:52:15---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void ClientModify(SwClient* pClient, SfxPoolItem *pOld, SfxPoolItem *pNew)
+{
+    switch( pOld ? pOld->Which() : 0 )
+    {
+    case RES_REMOVE_UNO_OBJECT:
+    case RES_OBJECTDYING:
+        if( (void*)pClient->GetRegisteredIn() == ((SwPtrMsgPoolItem *)pOld)->pObject )
+            ((SwModify*)pClient->GetRegisteredIn())->Remove(pClient);
+        break;
+
+    case RES_FMT_CHG:
+        // wurden wir an das neue umgehaengt und wird das alte geloscht?
+        if( ((SwFmtChg*)pNew)->pChangedFmt == pClient->GetRegisteredIn() &&
+            ((SwFmtChg*)pOld)->pChangedFmt->IsFmtInDTOR() )
+            ((SwModify*)pClient->GetRegisteredIn())->Remove(pClient);
+        break;
+    }
+}
+
+/* -----------------------------03.04.00 09:11--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Reference< XEnumeration >  SAL_CALL SwXTextCursor::createContentEnumeration(const OUString& rServiceName) throw( RuntimeException )
+{
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if( !pUnoCrsr || 0 != rServiceName.compareToAscii("com.sun.star.text.TextContent") )
+        throw RuntimeException();
+
+    Reference< XEnumeration > xRet = new SwXParaFrameEnumeration(*pUnoCrsr, PARAFRAME_PORTION_TEXTRANGE);
+    return xRet;
+}
+/* -----------------------------03.04.00 09:11--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SAL_CALL SwXTextCursor::getAvailableServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = OUString::createFromAscii("com.sun.star.text.TextContent");
+    return aRet;
+}
+/*-- 09.12.98 14:19:00---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void    SwXTextCursor::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew)
+{
+    ClientModify(this, pOld, pNew);
+    if(!GetRegisteredIn())
+        aLstnrCntnr.Disposing();
+
+}
+/*-- 09.12.98 14:19:01---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+const SwPaM*    SwXTextCursor::GetPaM() const
+{
+    return GetCrsr() ? GetCrsr() : 0;
+}
+/*-- 09.12.98 14:19:02---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+const SwDoc* SwXTextCursor::GetDoc()const
+{
+    return   GetCrsr() ? GetCrsr()->GetDoc() : 0;
+}
+/* -----------------22.07.99 13:52-------------------
+
+ --------------------------------------------------*/
+SwDoc* SwXTextCursor::GetDoc()
+{
+    return   GetCrsr() ? GetCrsr()->GetDoc() : 0;
+}
+
+/*-- 09.12.98 14:19:03---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextCursor::SetCrsrAttr(SwPaM& rPam, const SfxItemSet& rSet, sal_Bool bTableMode)
+{
+    sal_uInt16 nFlags = 0;//???
+    SwDoc* pDoc = rPam.GetDoc();
+    //StartEndAction
+    UnoActionContext aAction(pDoc);
+    SwPaM* pCrsr = &rPam;
+    if( pCrsr->GetNext() != pCrsr )     // Ring von Cursorn
+    {
+        pDoc->StartUndo(UNDO_INSATTR);
+
+        SwPaM *_pStartCrsr = &rPam;
+        do
+        {
+            if( _pStartCrsr->HasMark() && ( bTableMode ||
+                *_pStartCrsr->GetPoint() != *_pStartCrsr->GetMark() ))
+                pDoc->Insert(*_pStartCrsr, rSet, nFlags );
+        } while( (_pStartCrsr=(SwPaM *)_pStartCrsr->GetNext()) != &rPam );
+
+        pDoc->EndUndo(UNDO_INSATTR);
+    }
+    else
+    {
+//          if( !HasSelection() )
+//              UpdateAttr();
+        pDoc->Insert( *pCrsr, rSet, nFlags );
+    }
+}
+/*-- 09.12.98 14:19:04---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextCursor::GetCrsrAttr(SwPaM& rPam, SfxItemSet& rSet, BOOL bCurrentAttrOnly)
+{
+static const sal_uInt16 nMaxLookup = 255;
+    SfxItemSet aSet( *rSet.GetPool(), rSet.GetRanges() );
+    SfxItemSet *pSet = &rSet;
+    SwPaM *_pStartCrsr = &rPam;
+    do
+    {
+        sal_uInt32 nSttNd = _pStartCrsr->GetMark()->nNode.GetIndex(),
+                    nEndNd = _pStartCrsr->GetPoint()->nNode.GetIndex();
+            xub_StrLen nSttCnt = _pStartCrsr->GetMark()->nContent.GetIndex(),
+                    nEndCnt = _pStartCrsr->GetPoint()->nContent.GetIndex();
+
+            if( nSttNd > nEndNd || ( nSttNd == nEndNd && nSttCnt > nEndCnt ))
+            {
+                sal_uInt32 nTmp = nSttNd; nSttNd = nEndNd; nEndNd = nTmp;
+                nTmp = nSttCnt; nSttCnt = nEndCnt; nEndCnt = (sal_uInt16)nTmp;
+            }
+
+            if( nEndNd - nSttNd >= nMaxLookup )
+            {
+                rSet.ClearItem();
+                rSet.InvalidateAllItems();
+                return;// uno::Any();
+            }
+
+            // beim 1.Node traegt der Node die Werte in den GetSet ein (Initial)
+            // alle weiteren Nodes werden zum GetSet zu gemergt
+            for( sal_uInt32 n = nSttNd; n <= nEndNd; ++n )
+            {
+                SwNode* pNd = rPam.GetDoc()->GetNodes()[ n ];
+                switch( pNd->GetNodeType() )
+                {
+                case ND_TEXTNODE:
+                    {
+                        xub_StrLen nStt = n == nSttNd ? nSttCnt : 0,
+                                nEnd = n == nEndNd ? nEndCnt
+                                            : ((SwTxtNode*)pNd)->GetTxt().Len();
+                        ((SwTxtNode*)pNd)->GetAttr( *pSet, nStt, nEnd, bCurrentAttrOnly, !bCurrentAttrOnly );
+                    }
+                    break;
+                case ND_GRFNODE:
+                case ND_OLENODE:
+                    ((SwCntntNode*)pNd)->GetAttr( *pSet );
+                    break;
+
+                default:
+                    pNd = 0;
+                }
+
+                if( pNd )
+                {
+                    if( pSet != &rSet )
+                        rSet.MergeValues( aSet );
+
+                    if( aSet.Count() )
+                        aSet.ClearItem();
+
+                }
+                pSet = &aSet;
+            }
+    } while( (_pStartCrsr=(SwPaM *)_pStartCrsr->GetNext()) != &rPam );
+}
+/******************************************************************
+ * SwXParagraphEnumeration
+ ******************************************************************/
+/* -----------------------------06.04.00 16:33--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXParagraphEnumeration::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXParagraphEnumeration");
+}
+/* -----------------------------06.04.00 16:33--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXParagraphEnumeration::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.text.ParagraphEnumeration") == rServiceName;
+}
+/* -----------------------------06.04.00 16:33--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXParagraphEnumeration::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.ParagraphEnumeration");
+    return aRet;
+}
+/*-- 10.12.98 11:52:12---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXParagraphEnumeration::SwXParagraphEnumeration(SwXText* pParent,
+                                                    SwPosition& rPos,
+                                                    CursorType eType) :
+        xParentText(pParent),
+        bFirstParagraph(sal_True),
+        eCursorType(eType)
+{
+    SwUnoCrsr* pUnoCrsr = pParent->GetDoc()->CreateUnoCrsr(rPos, sal_False);
+    pUnoCrsr->Add(this);
+}
+
+/*-- 10.12.98 11:52:12---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXParagraphEnumeration::SwXParagraphEnumeration(SwXText* pParent,
+                                                SwUnoCrsr*  pCrsr,
+                                                CursorType eType) :
+        SwClient(pCrsr),
+        xParentText(pParent),
+        bFirstParagraph(sal_True),
+        eCursorType(eType)
+{
+}
+/*-- 10.12.98 11:52:12---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXParagraphEnumeration::~SwXParagraphEnumeration()
+{
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+        delete pUnoCrsr;
+
+}
+/*-- 10.12.98 11:52:13---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXParagraphEnumeration::hasMoreElements(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Bool bRet = sal_False;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        if(bFirstParagraph)
+            bRet = sal_True;
+        else
+        {
+            SwPosition* pStart = pUnoCrsr->GetPoint();
+            SwUnoCrsr* pNewCrsr = pUnoCrsr->GetDoc()->CreateUnoCrsr(*pStart, sal_False);
+            //man soll hier auch in Tabellen landen duerfen
+            if(CURSOR_TBLTEXT != eCursorType)
+                pNewCrsr->SetRemainInSection( sal_False );
+
+            //was mache ich, wenn ich schon in einer Tabelle stehe?
+            SwStartNode* pSttNode = pUnoCrsr->GetNode()->FindStartNode();
+            SwStartNodeType eType = pSttNode->GetStartNodeType();
+            if(CURSOR_TBLTEXT != eCursorType &&
+                                SwTableBoxStartNode == eType)
+            {
+                // wir haben es mit einer Tabelle zu tun
+                FASTBOOL bMoved = pNewCrsr->MoveTable( fnTableCurr, fnTableEnd );
+            }
+            bRet = pNewCrsr->MovePara(fnParaNext, fnParaStart);
+            delete pNewCrsr;
+        }
+    }
+    return bRet;
+}
+/*-- 10.12.98 11:52:14---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXParagraphEnumeration::nextElement(void)
+    throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< XTextContent >  aRef;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+         XText* pText = xParentText.get();
+        sal_Bool bInTable = sal_False;
+        if(!bFirstParagraph)
+        {
+            //man soll hier auch in Tabellen landen duerfen
+            if(CURSOR_TBLTEXT != eCursorType)
+            {
+                pUnoCrsr->SetRemainInSection( sal_False );
+                //was mache ich, wenn ich schon in einer Tabelle stehe?
+                SwTableNode* pTblNode = pUnoCrsr->GetNode()->FindTableNode();
+                if(pTblNode)
+                {
+                    // wir haben es mit einer Tabelle zu tun - also ans Ende
+                    FASTBOOL bMoved = pUnoCrsr->MoveTable( fnTableCurr, fnTableEnd );
+                    pUnoCrsr->GetPoint()->nNode = pTblNode->EndOfSectionIndex();
+                    if(!pUnoCrsr->Move(fnMoveForward, fnGoNode))
+                    {
+                        throw container::NoSuchElementException();
+                    }
+                    else
+                        bInTable = sal_True;
+
+                }
+            }
+        }
+
+        if( bFirstParagraph || bInTable || pUnoCrsr->MovePara(fnParaNext, fnParaStart))
+        {
+            bFirstParagraph = sal_False;
+            SwPosition* pStart = pUnoCrsr->GetPoint();
+            //steht man nun in einer Tabelle, oder in einem einfachen Absatz?
+
+            SwTableNode* pTblNode = pUnoCrsr->GetNode()->FindTableNode();
+            if(CURSOR_TBLTEXT != eCursorType && pTblNode)
+            {
+                // wir haben es mit einer Tabelle zu tun
+                SwFrmFmt* pTableFmt = (SwFrmFmt*)pTblNode->GetTable().GetFrmFmt();
+             XTextTable* pTable = SwXTextTables::GetObject( *pTableFmt );
+                aRef =  (XTextContent*)(SwXTextTable*)pTable;
+            }
+            else
+            {
+                SwUnoCrsr* pNewCrsr = pUnoCrsr->GetDoc()->CreateUnoCrsr(*pStart, sal_False);
+                aRef =  (XTextContent*)new SwXParagraph((SwXText*)pText, pNewCrsr);
+            }
+        }
+        else
+            throw container::NoSuchElementException();
+
+    }
+    else
+        throw uno::RuntimeException();
+
+    uno::Any aRet(&aRef, ::getCppuType((uno::Reference*)0));
+    return aRet;
+}
+void SwXParagraphEnumeration::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew)
+{
+    ClientModify(this, pOld, pNew);
+}
+
+/******************************************************************
+ * SwXTextRange
+ ******************************************************************/
+TYPEINIT1(SwXTextRange, SwClient);
+
+/* -----------------10.12.98 13:19-------------------
+ *
+ * --------------------------------------------------*/
+/*uno::Reference< uno::XInterface >  SwXTextRange_NewInstance_Impl()
+{
+    return *new SwXTextRange();
+};
+/* -----------------------------10.03.00 18:02--------------------------------
+
+ ---------------------------------------------------------------------------*/
+const uno::Sequence< sal_Int8 > & SwXTextRange::getUnoTunnelId()
+{
+    static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId();
+    return aSeq;
+}
+/* -----------------------------10.03.00 18:02--------------------------------
+
+ ---------------------------------------------------------------------------*/
+    //XUnoTunnel
+sal_Int64 SAL_CALL SwXTextRange::getSomething(
+    const uno::Sequence< sal_Int8 >& rId )
+        throw(uno::RuntimeException)
+{
+    if( rId.getLength() == 16
+        && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+                                        rId.getConstArray(), 16 ) )
+        {
+                return (sal_Int64)this;
+        }
+    return 0;
+}
+/* -----------------------------06.04.00 16:34--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXTextRange::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXTextRange");
+}
+/* -----------------------------06.04.00 16:34--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXTextRange::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    String sServiceName(rServiceName);
+    return sServiceName.EqualsAscii("com.sun.star.text.TextRange") ||
+         sServiceName.EqualsAscii("com.sun.star.style.CharacterProperties")||
+         sServiceName.EqualsAscii("com.sun.star.style.ParagraphProperties");
+}
+/* -----------------------------06.04.00 16:34--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXTextRange::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(2);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.TextRange");
+     pArray[1] = C2U("com.sun.star.style.CharacterProperties");
+     pArray[2] = C2U("com.sun.star.style.ParagraphProperties");
+    return aRet;
+}
+/*-- 10.12.98 12:54:42---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextRange::SwXTextRange() :
+    aPropSet(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_CURSOR)),
+    pDoc(0),
+    aObjectDepend(this, 0),
+    pBox(0),
+    pBoxStartNode(0),
+    eRangePosition(RANGE_INVALID)
+{
+}
+/*-- 10.12.98 12:54:43---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextRange::SwXTextRange(SwPaM& rPam, const uno::Reference< XText > & rxParent) :
+    aPropSet(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_CURSOR)),
+    xParentText(rxParent),
+    aObjectDepend(this, 0),
+    pDoc(rPam.GetDoc()),
+    pBox(0),
+    pBoxStartNode(0),
+    eRangePosition(RANGE_IN_TEXT)
+{
+    //Bookmark an der anlegen
+    _CreateNewBookmark(rPam);
+}
+/*-- 10.12.98 12:54:43---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextRange::SwXTextRange(SwFrmFmt& rFmt, SwPaM& rPam) :
+    aPropSet(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_CURSOR)),
+    aObjectDepend(this, &rFmt),
+    pDoc(rPam.GetDoc()),
+    pBox(0),
+    pBoxStartNode(0),
+    eRangePosition(RANGE_IN_FRAME)
+{
+    //Bookmark an der anlegen
+    _CreateNewBookmark(rPam);
+}
+/*-- 10.12.98 12:54:44---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextRange::SwXTextRange(SwFrmFmt& rTblFmt, SwTableBox& rTblBox, SwPaM& rPam) :
+    aPropSet(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_CURSOR)),
+    pDoc(rPam.GetDoc()),
+    aObjectDepend(this, &rTblFmt),
+    pBox(&rTblBox),
+    pBoxStartNode(0),
+    eRangePosition(RANGE_IN_CELL)
+{
+    //Bookmark an der anlegen
+    _CreateNewBookmark(rPam);
+}
+/* -----------------------------09.08.00 16:07--------------------------------
+
+ ---------------------------------------------------------------------------*/
+SwXTextRange::SwXTextRange(SwFrmFmt& rTblFmt, const SwStartNode& rStartNode, SwPaM& rPam) :
+    aPropSet(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_CURSOR)),
+    pDoc(rPam.GetDoc()),
+    aObjectDepend(this, &rTblFmt),
+    pBox(0),
+    pBoxStartNode(&rStartNode),
+    eRangePosition(RANGE_IN_CELL)
+{
+    //Bookmark an der anlegen
+    _CreateNewBookmark(rPam);
+}
+/* -----------------19.02.99 11:39-------------------
+ *
+ * --------------------------------------------------*/
+SwXTextRange::SwXTextRange(SwFrmFmt& rTblFmt) :
+    aPropSet(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_CURSOR)),
+    aObjectDepend(this, &rTblFmt),
+    pDoc(rTblFmt.GetDoc()),
+    pBox(0),
+    pBoxStartNode(0),
+    eRangePosition(RANGE_IS_TABLE)
+{
+}
+
+/*-- 10.12.98 12:54:44---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextRange::~SwXTextRange()
+{
+    if(GetBookmark())
+        pDoc->DelBookmark( GetBookmark()->GetName() );
+}
+/*-- 10.12.98 12:54:44---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void    SwXTextRange::_CreateNewBookmark(SwPaM& rPam)
+{
+    SwBookmark* pBkm = GetBookmark();
+    if(pBkm)
+        pDoc->DelBookmark( pBkm->GetName() );
+    KeyCode aCode;
+    String sBookmarkName(C2S("SwXTextPosition"));
+    String sShortName;
+    rPam.GetDoc()->MakeUniqueBookmarkName(sBookmarkName);
+
+    SwBookmark* pMark = pDoc->MakeBookmark(rPam, aCode,
+                sBookmarkName, sShortName, UNO_BOOKMARK);
+    pMark->Add(this);
+}
+/*-- 10.12.98 12:54:45---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void    SwXTextRange::DeleteAndInsert(const String& rText) throw( uno::RuntimeException )
+{
+    SwBookmark* pBkm = GetBookmark();
+    if(pBkm )
+    {
+        const SwPosition& rPoint = pBkm->GetPos();
+        const SwPosition* pMark = pBkm->GetOtherPos();
+        SwCursor aNewCrsr( rPoint);
+        SwDoc* pDoc = aNewCrsr.GetDoc();
+        if(pMark)
+        {
+            aNewCrsr.SetMark();
+            *aNewCrsr.GetMark() = *pMark;
+        }
+        EXCEPT_ON_PROTECTION(aNewCrsr)
+
+        UnoActionContext aAction(aNewCrsr.GetDoc());
+        pDoc->StartUndo(UNDO_INSERT);
+        if(aNewCrsr.HasMark())
+            pDoc->DeleteAndJoin(aNewCrsr);
+
+        if(rText.Len())
+        {
+            if( !pDoc->Insert(aNewCrsr, rText) )
+                ASSERT( sal_False, "Doc->Insert(Str) failed." );
+            SwXTextCursor::SelectPam(aNewCrsr, sal_True);
+            aNewCrsr.Left(rText.Len());
+        }
+        _CreateNewBookmark(aNewCrsr);
+        pDoc->EndUndo(UNDO_INSERT);
+    }
+
+}
+
+/*-- 10.12.98 12:54:46---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XText >  SwXTextRange::getText(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!xParentText.is())
+    {
+        if(eRangePosition == RANGE_IN_FRAME &&
+            aObjectDepend.GetRegisteredIn())
+        {
+            SwFrmFmt* pFrmFmt = (SwFrmFmt*)aObjectDepend.GetRegisteredIn();
+            SwXTextFrame* pxFrm = (SwXTextFrame*)SwClientIter( *pFrmFmt ).
+                                                First( TYPE( SwXTextFrame ));
+            if(pxFrm)
+                ((SwXTextRange*)this)->xParentText = pxFrm;
+            else
+                ((SwXTextRange*)this)->xParentText = new SwXTextFrame(*pFrmFmt);
+            ((SwModify*)aObjectDepend.GetRegisteredIn())->
+                    Remove(&((SwXTextRange*)this)->aObjectDepend);
+
+        }
+        else if(eRangePosition == RANGE_IN_CELL &&
+            aObjectDepend.GetRegisteredIn())
+        {
+            const SwStartNode* pSttNd = pBoxStartNode ? pBoxStartNode : pBox->GetSttNd();
+            const SwTableNode* pTblNode = pSttNd->FindTableNode();
+            const SwFrmFmt* pTableFmt = pTblNode->GetTable().GetFrmFmt();
+            ((SwXTextRange*)this)->xParentText =
+                    pBox ? SwXCell::CreateXCell((SwFrmFmt*)pTableFmt, pBox)
+                         : new SwXCell( (SwFrmFmt*)pTableFmt, *pBoxStartNode );
+            ((SwModify*)aObjectDepend.GetRegisteredIn())->
+                    Remove(&((SwXTextRange*)this)->aObjectDepend);
+        }
+        else if(eRangePosition == RANGE_IN_CELL &&
+            aObjectDepend.GetRegisteredIn())
+        {
+            //die Tabelle muss schon einen Parent kennen!
+            DBG_WARNING("not implemented")
+        }
+        else
+        {
+            // jetzt noch alle Faelle finden, die nicht abgedeckt sind
+            // (Body, Kopf-/Fusszeilen, Fussnotentext )
+            DBG_WARNING("not implemented")
+        }
+    }
+    return xParentText;
+}
+/*-- 10.12.98 12:54:47---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XTextRange >  SwXTextRange::getStart(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< XTextRange >  xRet;
+    SwBookmark* pBkm = GetBookmark();
+    if(pBkm)
+    {
+        SwPaM aPam(pBkm->GetPos());
+        xRet = new SwXTextRange(aPam, xParentText);
+    }
+    else if(eRangePosition == RANGE_IS_TABLE)
+    {
+        //start und ende sind mit this identisch, wenn es eine Tabelle ist
+        xRet = this;
+    }
+    else
+        throw uno::RuntimeException();
+    return xRet;
+}
+/*-- 10.12.98 12:54:47---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XTextRange >  SwXTextRange::getEnd(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< XTextRange >  xRet;
+    SwBookmark* pBkm = GetBookmark();
+    if(pBkm)
+    {
+        SwPaM aPam(pBkm->GetOtherPos()? *pBkm->GetOtherPos() : pBkm->GetPos());
+        xRet = new SwXTextRange(aPam, xParentText);
+    }
+    else if(eRangePosition == RANGE_IS_TABLE)
+    {
+        //start und ende sind mit this identisch, wenn es eine Tabelle ist
+        xRet = this;
+    }
+    else
+        throw uno::RuntimeException();
+    return xRet;
+}
+/*-- 10.12.98 12:54:47---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+OUString SwXTextRange::getString(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwBookmark* pBkm = GetBookmark();
+    OUString sRet;
+    //fuer Tabellen gibt es keine Bookmark, also auch keinen Text
+    //evtl. koennte man hier die Tabelle als ASCII exportieren?
+    if(pBkm && pBkm->GetOtherPos())
+    {
+        const SwPosition& rPoint = pBkm->GetPos();
+        const SwPosition* pMark = pBkm->GetOtherPos();
+        SwPaM aCrsr(*pMark, rPoint);
+/*      if( rPoint.nNode.GetIndex() ==
+            pMark->nNode.GetIndex() )
+        {
+            SwTxtNode* pTxtNd = aCrsr.GetNode()->GetTxtNode();
+            if( pTxtNd )
+            {
+                sal_uInt16 nStt = aCrsr.Start()->nContent.GetIndex();
+                sRet = pTxtNd->GetExpandTxt( nStt,
+                        aCrsr.End()->nContent.GetIndex() - nStt );
+            }
+        }
+        else
+*/      {
+            SwXTextCursor::getTextFromPam(aCrsr, sRet);
+        }
+    }
+    return sRet;
+}
+/*-- 10.12.98 12:54:48---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextRange::setString(const OUString& aString)
+    throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(RANGE_IN_CELL == eRangePosition)
+    {
+        //setString in Tabellen kann nicht erlaubt werden
+        throw uno::RuntimeException();
+    }
+    else
+        DeleteAndInsert(aString);
+}
+/*-- 10.12.98 12:54:48---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextRange::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew)
+{
+    sal_Bool bAlreadyRegisterred = 0 != GetRegisteredIn();
+    ClientModify(this, pOld, pNew);
+    if(aObjectDepend.GetRegisteredIn())
+    {
+        ClientModify(&aObjectDepend, pOld, pNew);
+        // if the depend was removed then the range must be removed too
+        if(!aObjectDepend.GetRegisteredIn() && GetRegisteredIn())
+            ((SwModify*)GetRegisteredIn())->Remove(this);
+        // or if the range has been removed but the depend ist still
+        // connected then the depend must be removed
+        else if(bAlreadyRegisterred && !GetRegisteredIn() &&
+                aObjectDepend.GetRegisteredIn())
+            ((SwModify*)aObjectDepend.GetRegisteredIn())->Remove(&aObjectDepend);
+    }
+}
+/*-- 10.12.98 12:54:49---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool    SwXTextRange::GetPositions(SwPaM& rToFill) const
+{
+    sal_Bool bRet = sal_False;
+    SwBookmark* pBkm = GetBookmark();
+    if(pBkm)
+    {
+        *rToFill.GetPoint() = pBkm->GetPos();
+        if(pBkm->GetOtherPos())
+        {
+            rToFill.SetMark();
+            *rToFill.GetMark() = *pBkm->GetOtherPos();
+        }
+        else
+            rToFill.DeleteMark();
+        bRet = sal_True;
+    }
+    return bRet;
+}
+/*-- 10.12.98 12:54:49---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool        SwXTextRange::XTextRangeToSwPaM( SwUnoInternalPaM& rToFill,
+                            const uno::Reference< XTextRange > & xTextRange)
+{
+    sal_Bool bRet = sal_False;
+
+    uno::Reference xRangeTunnel( xTextRange, uno::UNO_QUERY);
+    SwXTextRange* pRange = 0;
+    SwXTextCursor* pCursor = 0;
+    if(xRangeTunnel.is())
+    {
+        pRange = (SwXTextRange*)xRangeTunnel->getSomething(
+                                SwXTextRange::getUnoTunnelId());
+        pCursor = (SwXTextCursor*)xRangeTunnel->getSomething(
+                                SwXTextCursor::getUnoTunnelId());
+    }
+
+    if(pRange && pRange->GetDoc() == rToFill.GetDoc())
+    {
+        bRet = pRange->GetPositions(rToFill);
+    }
+    else
+    {
+        const SwPaM* pPam = 0;
+        if(pCursor && pCursor->GetDoc() == rToFill.GetDoc() &&
+            0 != (pPam = pCursor->GetPaM()))
+            {
+                DBG_ASSERT((SwPaM*)pPam->GetNext() == pPam, "was machen wir mit Ringen?" )
+                bRet = sal_True;
+                *rToFill.GetPoint() = *pPam->GetPoint();
+                if(pPam->HasMark())
+                {
+                    rToFill.SetMark();
+                    *rToFill.GetMark() = *pPam->GetMark();
+                }
+                else
+                    rToFill.DeleteMark();
+            }
+    }
+    return bRet;
+}
+/* -----------------------------03.04.00 09:11--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Reference< XEnumeration >  SAL_CALL SwXTextRange::createContentEnumeration(
+        const OUString& rServiceName)
+                throw( RuntimeException )
+{
+    SwBookmark* pBkm = GetBookmark();
+    if( !pBkm || COMPARE_EQUAL != rServiceName.compareToAscii("com.sun.star.text.TextContent") )
+        throw RuntimeException();
+
+    const SwPosition& rPoint = pBkm->GetPos();
+    const SwPosition* pMark = pBkm->GetOtherPos();
+    SwUnoCrsr* pNewCrsr = pDoc->CreateUnoCrsr(rPoint, FALSE);
+    if(pMark && *pMark != rPoint)
+    {
+        pNewCrsr->SetMark();
+        *pNewCrsr->GetMark() = *pMark;
+    }
+    Reference< XEnumeration > xRet = new SwXParaFrameEnumeration(*pNewCrsr, PARAFRAME_PORTION_TEXTRANGE);
+    delete pNewCrsr;
+    return xRet;
+}
+/* -----------------------------03.04.00 09:11--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SAL_CALL SwXTextRange::getAvailableServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = OUString::createFromAscii("com.sun.star.text.TextContent");
+    return aRet;
+}
+/*-- 03.05.00 12:41:46---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Reference< XPropertySetInfo > SAL_CALL SwXTextRange::getPropertySetInfo(  ) throw(RuntimeException)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    static Reference< XPropertySetInfo > xRef =
+        aPropSet.getPropertySetInfo();
+    return xRef;
+}
+/*-- 03.05.00 12:41:47---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SAL_CALL SwXTextRange::setPropertyValue(
+    const OUString& rPropertyName, const Any& rValue )
+    throw(UnknownPropertyException, PropertyVetoException,
+        IllegalArgumentException, WrappedTargetException, RuntimeException)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!GetDoc() || !GetBookmark())
+        throw RuntimeException();
+    SwPaM aPaM(GetDoc()->GetNodes());
+    SwXTextRange::GetPositions(aPaM);
+    SwXTextCursor::SetPropertyValue(aPaM, aPropSet, rPropertyName, rValue);
+}
+/*-- 03.05.00 12:41:47---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Any SAL_CALL SwXTextRange::getPropertyValue( const OUString& rPropertyName )
+    throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!GetDoc() || !GetBookmark())
+        throw RuntimeException();
+    SwPaM aPaM(((SwDoc*)GetDoc())->GetNodes());
+    SwXTextRange::GetPositions(aPaM);
+    return SwXTextCursor::GetPropertyValue(aPaM, aPropSet, rPropertyName);
+}
+/*-- 03.05.00 12:41:47---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SAL_CALL SwXTextRange::addPropertyChangeListener(
+    const OUString& aPropertyName, const Reference< XPropertyChangeListener >& xListener )
+    throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 03.05.00 12:41:48---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SAL_CALL SwXTextRange::removePropertyChangeListener(
+    const OUString& aPropertyName, const Reference< XPropertyChangeListener >& aListener )
+        throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 03.05.00 12:41:48---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SAL_CALL SwXTextRange::addVetoableChangeListener(
+    const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener )
+    throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 03.05.00 12:41:48---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SAL_CALL SwXTextRange::removeVetoableChangeListener(
+    const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener )
+        throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 03.05.00 12:41:48---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+PropertyState SAL_CALL SwXTextRange::getPropertyState( const OUString& rPropertyName )
+    throw(UnknownPropertyException, RuntimeException)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!GetDoc() || !GetBookmark())
+        throw RuntimeException();
+    SwPaM aPaM(((SwDoc*)GetDoc())->GetNodes());
+    SwXTextRange::GetPositions(aPaM);
+    return SwXTextCursor::GetPropertyState(aPaM, aPropSet, rPropertyName);
+}
+/*-- 03.05.00 12:41:49---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Sequence< PropertyState > SAL_CALL SwXTextRange::getPropertyStates(
+    const Sequence< OUString >& rPropertyName ) throw(UnknownPropertyException, RuntimeException)
+{
+    NAMESPACE_VOS(OGuard) aGuard(Application::GetSolarMutex());
+    if(!GetDoc() || !GetBookmark())
+        throw RuntimeException();
+    SwPaM aPaM(((SwDoc*)GetDoc())->GetNodes());
+    SwXTextRange::GetPositions(aPaM);
+    return SwXTextCursor::GetPropertyStates(aPaM, aPropSet, rPropertyName);
+}
+/*-- 03.05.00 12:41:49---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SAL_CALL SwXTextRange::setPropertyToDefault( const OUString& rPropertyName )
+    throw(UnknownPropertyException, RuntimeException)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!GetDoc() || !GetBookmark())
+        throw RuntimeException();
+    SwPaM aPaM(((SwDoc*)GetDoc())->GetNodes());
+    SwXTextRange::GetPositions(aPaM);
+    SwXTextCursor::SetPropertyToDefault(aPaM, aPropSet, rPropertyName);
+}
+/*-- 03.05.00 12:41:50---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Any SAL_CALL SwXTextRange::getPropertyDefault( const OUString& rPropertyName )
+    throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!GetDoc() || !GetBookmark())
+        throw RuntimeException();
+    SwPaM aPaM(((SwDoc*)GetDoc())->GetNodes());
+    SwXTextRange::GetPositions(aPaM);
+    return SwXTextCursor::GetPropertyDefault(aPaM, aPropSet, rPropertyName);
+}
+
+/******************************************************************
+ * SwXTextRanges
+ ******************************************************************/
+/* -----------------------------13.03.00 12:15--------------------------------
+
+ ---------------------------------------------------------------------------*/
+const uno::Sequence< sal_Int8 > & SwXTextRanges::getUnoTunnelId()
+{
+    static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId();
+    return aSeq;
+}
+/* -----------------------------10.03.00 18:04--------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Int64 SAL_CALL SwXTextRanges::getSomething( const uno::Sequence< sal_Int8 >& rId )
+    throw(uno::RuntimeException)
+{
+    if( rId.getLength() == 16
+        && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+                                        rId.getConstArray(), 16 ) )
+    {
+            return (sal_Int64)this;
+    }
+    return 0;
+}
+/****************************************************************************
+ *  Text positions
+ *  Bis zum ersten Zugriff auf eine TextPosition wird ein SwCursor gehalten,
+ * danach wird ein Array mit uno::Reference< XTextPosition >  angelegt
+ *
+****************************************************************************/
+SV_IMPL_PTRARR(XTextRangeArr, XTextRangeRefPtr);
+/* -----------------------------06.04.00 16:36--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXTextRanges::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXTextRanges");
+}
+/* -----------------------------06.04.00 16:36--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXTextRanges::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.text.TextRanges") == rServiceName;
+}
+/* -----------------------------06.04.00 16:36--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXTextRanges::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.TextRanges");
+    return aRet;
+}
+/*-- 10.12.98 13:57:20---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextRanges::SwXTextRanges() :
+    pRangeArr(0)
+{
+
+}
+/*-- 10.12.98 13:57:21---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextRanges::SwXTextRanges( SwUnoCrsr* pCrsr, uno::Reference< XText >  xParent) :
+    SwClient(pCrsr),
+    xParentText(xParent),
+    pRangeArr(0)
+{
+
+}
+/*-- 10.12.98 13:57:22---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextRanges::SwXTextRanges(SwPaM* pCrsr) :
+    pRangeArr(0)
+{
+    SwUnoCrsr* pUnoCrsr = pCrsr->GetDoc()->CreateUnoCrsr(*pCrsr->GetPoint());
+    if(pCrsr->HasMark())
+    {
+        pUnoCrsr->SetMark();
+        *pUnoCrsr->GetMark() = *pCrsr->GetMark();
+    }
+    if(pCrsr->GetNext() != pCrsr)
+    {
+        SwPaM *_pStartCrsr = (SwPaM *)pCrsr->GetNext();
+        do
+        {
+            //neuen PaM erzeugen
+            SwPaM* pPaM = _pStartCrsr->HasMark() ?
+                        new SwPaM(*_pStartCrsr->GetMark(), *_pStartCrsr->GetPoint()) :
+                            new SwPaM(*_pStartCrsr->GetPoint());
+            //und in den Ring einfuegen
+            pPaM->MoveTo(pUnoCrsr);
+
+        } while( (_pStartCrsr=(SwPaM *)_pStartCrsr->GetNext()) != pCrsr );
+    }
+
+    pUnoCrsr->Add(this);
+}
+/*-- 10.12.98 13:57:22---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextRanges::~SwXTextRanges()
+{
+    SwUnoCrsr* pCrsr = GetCrsr();
+    delete pCrsr;
+    if(pRangeArr)
+    {
+        pRangeArr->DeleteAndDestroy(0, pRangeArr->Count());
+        delete pRangeArr;
+    }
+}
+/*-- 10.12.98 13:57:24---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Int32 SwXTextRanges::getCount(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Int32 nRet = 0;
+    SwUnoCrsr* pCrsr = GetCrsr();
+    if(pCrsr)
+    {
+        FOREACHUNOPAM_START(pCrsr)
+            nRet++;
+        FOREACHUNOPAM_END()
+    }
+    else if(pRangeArr)
+        nRet = pRangeArr->Count();
+    return nRet;
+}
+/*-- 10.12.98 13:57:25---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXTextRanges::getByIndex(sal_Int32 nIndex)
+    throw( lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< XTextRange >  aRef;
+    XTextRangeArr* pArr = ((SwXTextRanges*)this)->GetRangesArray();
+    if(pArr && pArr->Count() > nIndex)
+    {
+        XTextRangeRefPtr pRef = pArr->GetObject(nIndex);
+        aRef = *pRef;
+    }
+    else
+        throw lang::IndexOutOfBoundsException();
+    uno::Any aRet(&aRef, ::getCppuType((uno::Reference*)0));
+    return aRet;
+}
+/*-- 10.12.98 13:57:25---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Type  SwXTextRanges::getElementType(void) throw( uno::RuntimeException )
+{
+    return ::getCppuType((uno::Reference*)0);
+}
+/*-- 10.12.98 13:57:26---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextRanges::hasElements(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    return getCount() > 0;
+}
+/* -----------------10.12.98 14:25-------------------
+ *
+ * --------------------------------------------------*/
+XTextRangeArr*  SwXTextRanges::GetRangesArray()
+{
+    SwUnoCrsr* pCrsr = GetCrsr();
+    if(!pRangeArr && pCrsr)
+    {
+        pRangeArr = new XTextRangeArr();
+        FOREACHUNOPAM_START(pCrsr)
+            uno::Reference< XTextRange > * pPtr = new uno::Reference< XTextRange > ;
+            // in welcher Umgebung steht denn der PaM?
+            SwStartNode* pSttNode = PUNOPAM->GetNode()->FindStartNode();
+            SwStartNodeType eType = pSttNode->GetStartNodeType();
+            uno::Reference< XText >  xCurParentRef;
+            switch(eType)
+            {
+                case SwTableBoxStartNode:
+                {
+                    SwTableBox* pBox = pSttNode->GetTblBox();
+                    *pPtr = new SwXTextRange(*pBox->GetFrmFmt(), *pBox, *PUNOPAM);
+                }
+                break;
+                case SwFlyStartNode:
+                {
+                    SwFrmFmt* pFlyFmt = pSttNode->GetFlyFmt();
+                    SwXTextFrame* pxFrm = (SwXTextFrame*)SwClientIter( *pFlyFmt ).
+                                                First( TYPE( SwXTextFrame ));
+                    if(pxFrm)
+                        xCurParentRef = pxFrm;
+                    else
+                        *pPtr = new SwXTextRange(*pFlyFmt, *PUNOPAM);
+                }
+                break;
+                case SwFootnoteStartNode:
+                {
+                    const SwFtnIdxs& rIdxs = pCrsr->GetDoc()->GetFtnIdxs();
+                    sal_uInt16 n, nFtnCnt = rIdxs.Count();
+                    for( n = 0; n < nFtnCnt; ++n )
+                    {
+                        const SwTxtFtn* pFtn = rIdxs[ n ];
+
+                        const SwStartNode* pTemp = 0;
+                        const SwNode& rNode = pFtn->GetStartNode()->GetNode();
+                        if(rNode.GetNodeType() == ND_STARTNODE)
+                            pTemp = (const SwStartNode*)&rNode;
+                        if(pSttNode == pTemp)
+                        {
+                            const SwFmtFtn& rFtn = pFtn->GetFtn();
+                            //TODO: schon existierendes Fussnotenobjekt wiederfinden!
+                            xCurParentRef = new SwXFootnote(pCrsr->GetDoc(), rFtn);
+                            break;
+                        }
+                    }
+                }
+                break;
+                case SwHeaderStartNode:
+                case SwFooterStartNode:
+                {
+                    //PageStyle besorgen, HeaderText anlegen/erfragen,
+                    //und dann SwXTextPosition damit anlegen
+                    String sPageStyleName = lcl_GetCurPageStyle(*pCrsr);
+                    uno::Reference< style::XStyleFamiliesSupplier >  xStyleSupp(
+                        pCrsr->GetDoc()->GetDocShell()->GetBaseModel(), uno::UNO_QUERY);
+
+                    uno::Reference< container::XNameAccess >  xStyles = xStyleSupp->getStyleFamilies();
+                    uno::Any aStyleFamily = xStyles->getByName(C2U("PageStyles"));
+
+                    uno::Reference< container::XNameContainer > xFamily =
+                        *(uno::Reference< container::XNameContainer > *)aStyleFamily.getValue();
+                    uno::Any aStyle = xFamily->getByName(sPageStyleName);
+                    uno::Reference< style::XStyle >  xStyle = *(uno::Reference< style::XStyle > *)aStyle.getValue();
+
+                    uno::Reference< beans::XPropertySet >  xPropSet(xStyle, uno::UNO_QUERY);
+                    uno::Any aLayout = xPropSet->getPropertyValue(C2U(UNO_NAME_PAGE_STYLE_LAYOUT));
+
+                     style::PageStyleLayout eLayout = *(style::PageStyleLayout*)aLayout.getValue();
+                    uno::Any aShare = xPropSet->getPropertyValue(C2U(UNO_NAME_HEADER_SHARE_CONTENT));
+                    sal_Bool bShare;
+                    aShare >>= bShare;
+                    sal_Bool bLeft = sal_False;
+                    sal_Bool bRight = sal_False;
+                    //jetzt evtl. noch zw. linker/rechter Kopf-/Fusszeile unterscheiden
+                    if(!bShare && eLayout == style::PageStyleLayout_MIRRORED)
+                    {
+                        uno::Reference xTunnel(xStyle, uno::UNO_QUERY);
+                        SwXPageStyle* pStyle = (SwXPageStyle*)
+                            xTunnel->getSomething( SwXPageStyle::getUnoTunnelId());
+
+                        DBG_ASSERT(pStyle, "Was ist das fuer ein style::XStyle?")
+                        bLeft = pSttNode == pStyle->GetStartNode(eType == SwHeaderStartNode, sal_True);
+                        bRight = !bLeft;
+                    }
+                    uno::Any aParent;
+                    sal_Bool bFooter = eType == SwFooterStartNode;
+                    if(eLayout == style::PageStyleLayout_LEFT || bLeft)
+                        aParent = xPropSet->getPropertyValue(C2U(bFooter ? UNO_NAME_FOOTER_TEXT_LEFT : UNO_NAME_HEADER_TEXT_LEFT));
+                    else if(eLayout == style::PageStyleLayout_RIGHT)
+                        aParent = xPropSet->getPropertyValue(C2U(bFooter ? UNO_NAME_FOOTER_TEXT_RIGHT : UNO_NAME_HEADER_TEXT_RIGHT));
+                    else
+                        aParent = xPropSet->getPropertyValue(C2U(bFooter ? UNO_NAME_FOOTER_TEXT : UNO_NAME_HEADER_TEXT));
+
+                    if(aParent.getValueType() != ::getVoidCppuType())
+                    {
+                        uno::Reference< XText >  xText = *(uno::Reference< XText > *)aParent.getValue();
+                        xCurParentRef = xText;
+                    }
+                }
+
+
+                break;
+//              case SwNormalStartNode:
+                default:
+                {
+                    if(!xParentText.is())
+                    {
+                        uno::Reference< XTextDocument >  xDoc(
+                            pCrsr->GetDoc()->GetDocShell()->GetBaseModel(), uno::UNO_QUERY);
+                        xParentText = xDoc->getText();
+                    }
+                    xCurParentRef = xParentText;
+                }
+            }
+
+            if(xCurParentRef.is())
+                *pPtr = new SwXTextRange(*PUNOPAM, xCurParentRef);
+            if(pPtr->is())
+                pRangeArr->Insert(pPtr, pRangeArr->Count());
+        FOREACHUNOPAM_END()
+        pCrsr->Remove( this );
+    }
+    return pRangeArr;
+}
+/*-- 10.12.98 13:57:02---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void    SwXTextRanges::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew)
+{
+    ClientModify(this, pOld, pNew);
+}
+
+
+/******************************************************************
+ * SwXParagraph
+ ******************************************************************/
+/* -----------------------------11.07.00 12:10--------------------------------
+
+ ---------------------------------------------------------------------------*/
+SwXParagraph* SwXParagraph::GetImplementation(Reference< XInterface> xRef )
+{
+    uno::Reference xParaTunnel( xRef, uno::UNO_QUERY);
+    if(xParaTunnel.is())
+        return (SwXParagraph*)xParaTunnel->getSomething(SwXParagraph::getUnoTunnelId());
+    return 0;
+}
+/* -----------------------------13.03.00 12:15--------------------------------
+
+ ---------------------------------------------------------------------------*/
+const uno::Sequence< sal_Int8 > & SwXParagraph::getUnoTunnelId()
+{
+    static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId();
+    return aSeq;
+}
+/* -----------------------------10.03.00 18:04--------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Int64 SAL_CALL SwXParagraph::getSomething( const uno::Sequence< sal_Int8 >& rId )
+    throw(uno::RuntimeException)
+{
+    if( rId.getLength() == 16
+        && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+                                        rId.getConstArray(), 16 ) )
+    {
+            return (sal_Int64)this;
+    }
+    return 0;
+}
+/* -----------------------------06.04.00 16:37--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXParagraph::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXParagraph");
+}
+/* -----------------------------06.04.00 16:37--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXParagraph::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    String sServiceName(rServiceName);
+    return sServiceName.EqualsAscii("com.sun.star.text.TextContent") ||
+        sServiceName.EqualsAscii("com.sun.star.text.Paragraph") ||
+         sServiceName.EqualsAscii("com.sun.star.style.CharacterProperties")||
+         sServiceName.EqualsAscii("com.sun.star.style.ParagraphProperties");
+}
+/* -----------------------------06.04.00 16:37--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXParagraph::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(4);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.Paragraph");
+     pArray[1] = C2U("com.sun.star.style.CharacterProperties");
+     pArray[2] = C2U("com.sun.star.style.ParagraphProperties");
+     pArray[3] = C2U("com.sun.star.text.TextContent");
+    return aRet;
+}
+/*-- 11.12.98 08:12:47---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXParagraph::SwXParagraph() :
+    aLstnrCntnr( (XTextRange*)this),
+    xParentText(0),
+    aPropSet(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_CURSOR)),
+    m_bIsDescriptor(TRUE)
+{
+}
+
+/*-- 11.12.98 08:12:47---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXParagraph::SwXParagraph(SwXText* pParent, SwUnoCrsr* pCrsr) :
+    SwClient(pCrsr),
+    xParentText(pParent),
+    aLstnrCntnr( (XTextRange*)this),
+    aPropSet(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_CURSOR)),
+    m_bIsDescriptor(FALSE)
+{
+}
+/*-- 11.12.98 08:12:48---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXParagraph::~SwXParagraph()
+{
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+        delete pUnoCrsr;
+}
+/* -----------------------------11.07.00 14:48--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SwXParagraph::attachToText(SwXText* pParent, SwUnoCrsr* pCrsr)
+{
+    DBG_ASSERT(m_bIsDescriptor, "Paragraph is not a descriptor")
+    if(m_bIsDescriptor)
+    {
+        m_bIsDescriptor = FALSE;
+        pCrsr->Add(this);
+        xParentText = pParent;
+        if(m_sText.getLength())
+        {
+            try { setString(m_sText); }
+            catch(...){}
+            m_sText = OUString();
+        }
+    }
+}
+/*-- 11.12.98 08:12:49---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< beans::XPropertySetInfo >  SwXParagraph::getPropertySetInfo(void)
+                                            throw( uno::RuntimeException )
+{
+    static uno::Reference< beans::XPropertySetInfo >  xRef;
+    if(!xRef.is())
+    {
+        uno::Reference< beans::XPropertySetInfo >  xInfo = aPropSet.getPropertySetInfo();
+        // PropertySetInfo verlaengern!
+        const uno::Sequence aPropSeq = xInfo->getProperties();
+        xRef = new SfxExtItemPropertySetInfo(
+            aSwMapProvider.GetPropertyMap(PROPERTY_MAP_PARAGRAPH_EXTENSIONS),
+            aPropSeq );
+    }
+    return xRef;
+}
+/*-- 11.12.98 08:12:49---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXParagraph::setPropertyValue(const OUString& rPropertyName, const uno::Any& aValue)
+    throw( beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException,
+        lang::WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Any aAny;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        if(rPropertyName.equals(C2U(UNO_NAME_TEXT_WRAP)) ||
+            rPropertyName.equals(C2U(UNO_NAME_ANCHOR_TYPE)) ||
+                rPropertyName.equals(C2U(UNO_NAME_ANCHOR_TYPES)))
+        {
+            throw IllegalArgumentException();
+        }
+        SwParaSelection aParaSel(pUnoCrsr);
+        SwXTextCursor::SetPropertyValue(*pUnoCrsr, aPropSet, rPropertyName, aValue);
+    }
+    else
+        throw uno::RuntimeException();
+}
+/*-- 11.12.98 08:12:49---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXParagraph::getPropertyValue(const OUString& rPropertyName)
+    throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Any aAny;
+    SwUnoCrsr* pUnoCrsr = ((SwXParagraph*)this)->GetCrsr();
+    if(pUnoCrsr)
+    {
+        if(!SwXParagraph::getDefaultTextContentValue(aAny, rPropertyName))
+        {
+            SwParaSelection aParaSel(pUnoCrsr);
+            aAny = SwXTextCursor::GetPropertyValue(*pUnoCrsr, aPropSet, rPropertyName);
+        }
+    }
+    else
+        throw uno::RuntimeException();
+    return aAny;
+
+}
+/* -----------------------------12.09.00 11:09--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXParagraph::getDefaultTextContentValue(Any& rAny, const OUString& rPropertyName, USHORT nWID)
+{
+    if(!nWID)
+    {
+        if(0 == rPropertyName.compareToAscii(UNO_NAME_ANCHOR_TYPE))
+            nWID = FN_UNO_ANCHOR_TYPE;
+        else if(0 == rPropertyName.compareToAscii(UNO_NAME_ANCHOR_TYPES))
+            nWID = FN_UNO_ANCHOR_TYPES;
+        else if(0 == rPropertyName.compareToAscii(UNO_NAME_TEXT_WRAP))
+            nWID = FN_UNO_TEXT_WRAP;
+        else
+            return FALSE;
+    }
+
+    switch(nWID)
+    {
+        case FN_UNO_TEXT_WRAP:  rAny <<= WrapTextMode_NONE; break;
+        case FN_UNO_ANCHOR_TYPE: rAny <<= TextContentAnchorType_AT_PARAGRAPH; break;
+        case FN_UNO_ANCHOR_TYPES:
+        {   Sequence aTypes(1);
+            TextContentAnchorType* pArray = aTypes.getArray();
+            pArray[0] = TextContentAnchorType_AT_PARAGRAPH;
+            rAny.setValue(&aTypes, ::getCppuType((uno::Sequence*)0));
+        }
+        break;
+        default:
+            return FALSE;
+    }
+    return TRUE;
+}
+/*-- 11.12.98 08:12:50---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXParagraph::addPropertyChangeListener(
+    const OUString& PropertyName,
+    const uno::Reference< beans::XPropertyChangeListener > & aListener)
+        throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 11.12.98 08:12:50---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXParagraph::removePropertyChangeListener(const OUString& PropertyName, const uno::Reference< beans::XPropertyChangeListener > & aListener) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 11.12.98 08:12:50---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXParagraph::addVetoableChangeListener(const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener > & aListener) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 11.12.98 08:12:51---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXParagraph::removeVetoableChangeListener(const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener > & aListener)
+    throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+
+/*-- 05.03.99 11:37:30---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+beans::PropertyState SwXParagraph::getPropertyState(const OUString& rPropertyName)
+    throw( beans::UnknownPropertyException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    beans::PropertyState eRet = beans::PropertyState_DEFAULT_VALUE;
+    SwUnoCrsr* pUnoCrsr = ((SwXParagraph*)this)->GetCrsr();
+    if(pUnoCrsr)
+    {
+        // Absatz selektieren
+        SwParaSelection aParaSel(pUnoCrsr);
+        SfxItemSet aSet(pUnoCrsr->GetDoc()->GetAttrPool(),
+            RES_CHRATR_BEGIN,   RES_PARATR_NUMRULE,
+            RES_FILL_ORDER,     RES_FRMATR_END -1,
+            0L);
+        SwXTextCursor::GetCrsrAttr(*pUnoCrsr, aSet);
+        if(rPropertyName.equals(C2U(UNO_NAME_PAGE_DESC_NAME)))
+        {
+            // Sonderbehandlung RES_PAGEDESC
+            const SfxPoolItem* pItem;
+            if(SFX_ITEM_SET == aSet.GetItemState( RES_PAGEDESC, sal_True, &pItem ) )
+            {
+                eRet = beans::PropertyState_DIRECT_VALUE;
+            }
+        }
+        else if(rPropertyName.equals(C2U(UNO_NAME_NUMBERING_RULES)))
+        {
+            //wenn eine Numerierung gesetzt ist, dann hier herausreichen, sonst nichts tun
+            lcl_getNumberingProperty(*pUnoCrsr, eRet);
+        }
+        else if(rPropertyName.equals(C2U(UNO_NAME_PARA_STYLE_NAME)) ||
+            rPropertyName.equals(C2U(UNO_NAME_PARA_CONDITIONAL_STYLE_NAME)))
+        {
+            SwFmtColl* pFmt = SwXTextCursor::GetCurTxtFmtColl(*pUnoCrsr,
+                rPropertyName.equals(C2U(UNO_NAME_PARA_CONDITIONAL_STYLE_NAME)));
+            if(!pFmt)
+                eRet = beans::PropertyState_AMBIGUOUS_VALUE;
+        }
+        else if(rPropertyName.equals(C2U(UNO_NAME_PAGE_STYLE_NAME)))
+        {
+            String sVal = lcl_GetCurPageStyle(*pUnoCrsr);
+            if(!sVal.Len())
+                eRet = beans::PropertyState_AMBIGUOUS_VALUE;
+        }
+        else
+        {
+            eRet = aPropSet.getPropertyState(rPropertyName, aSet);
+        }
+    }
+    else
+        throw uno::RuntimeException();
+    return eRet;
+}
+/*-- 05.03.99 11:37:32---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Sequence< beans::PropertyState > SwXParagraph::getPropertyStates(
+        const uno::Sequence< OUString >& PropertyNames)
+        throw( beans::UnknownPropertyException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    const OUString* pNames = PropertyNames.getConstArray();
+    uno::Sequence< beans::PropertyState > aRet(PropertyNames.getLength());
+    beans::PropertyState* pStates = aRet.getArray();
+    for(sal_Int32 i = 0; i < PropertyNames.getLength(); i++)
+        pStates[i] = getPropertyState(pNames[i]);
+    return aRet;
+}
+/*-- 05.03.99 11:37:33---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXParagraph::setPropertyToDefault(const OUString& rPropertyName)
+        throw( beans::UnknownPropertyException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        // Absatz selektieren
+        SwParaSelection aParaSel(pUnoCrsr);
+        SwDoc* pDoc = pUnoCrsr->GetDoc();
+        const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                                aPropSet.getPropertyMap(), rPropertyName);
+        if(pMap)
+        {
+            if(pMap->nWID < RES_FRMATR_END)
+            {
+                SvUShortsSort aWhichIds;
+                aWhichIds.Insert(pMap->nWID);
+                if(pMap->nWID < RES_PARATR_BEGIN)
+                    pUnoCrsr->GetDoc()->ResetAttr(*pUnoCrsr, sal_True, &aWhichIds);
+                else
+                {
+                    //fuer Absatzattribute muss die Selektion jeweils auf
+                    //Absatzgrenzen erweitert werden
+                    SwPosition aStart = *pUnoCrsr->Start();
+                    SwPosition aEnd = *pUnoCrsr->End();
+                    SwUnoCrsr* pTemp = pUnoCrsr->GetDoc()->CreateUnoCrsr(aStart, sal_False);
+                    if(!lcl_IsStartOfPara(*pTemp))
+                    {
+                        pTemp->MovePara(fnParaCurr, fnParaStart);
+                    }
+                    pTemp->SetMark();
+                    *pTemp->GetPoint() = aEnd;
+                    //pTemp->Exchange();
+                    SwXTextCursor::SelectPam(*pTemp, sal_True);
+                    if(!lcl_IsEndOfPara(*pTemp))
+                    {
+                        pTemp->MovePara(fnParaCurr, fnParaEnd);
+                    }
+                    pTemp->GetDoc()->ResetAttr(*pTemp, sal_True, &aWhichIds);
+                    delete pTemp;
+                }
+            }
+            else
+                lcl_resetCrsrPropertyValue(pMap, *pUnoCrsr);
+        }
+        else
+            throw beans::UnknownPropertyException();
+    }
+    else
+        throw uno::RuntimeException();
+}
+/*-- 05.03.99 11:37:33---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXParagraph::getPropertyDefault(const OUString& rPropertyName)
+        throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    uno::Any aRet;
+    SwUnoCrsr* pUnoCrsr = ((SwXParagraph*)this)->GetCrsr();
+    if(pUnoCrsr)
+    {
+        SwDoc* pDoc = pUnoCrsr->GetDoc();
+        const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                                aPropSet.getPropertyMap(), rPropertyName);
+        if(pMap)
+        {
+            if(pMap->nWID < RES_FRMATR_END)
+            {
+                const SfxPoolItem& rDefItem =
+                    pUnoCrsr->GetDoc()->GetAttrPool().GetDefaultItem(pMap->nWID);
+                rDefItem.QueryValue(aRet, pMap->nMemberId);
+            }
+        }
+        else
+            throw beans::UnknownPropertyException();
+    }
+    else
+        throw uno::RuntimeException();
+
+    return aRet;
+}
+/*-- 11.12.98 08:12:51---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXParagraph::attach(const uno::Reference< XTextRange > & xTextRange)
+                    throw( lang::IllegalArgumentException, uno::RuntimeException )
+{
+
+}
+/*-- 11.12.98 08:12:51---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XTextRange >  SwXParagraph::getAnchor(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< XTextRange >  aRet;
+    SwUnoCrsr* pUnoCrsr = ((SwXParagraph*)this)->GetCrsr();
+    if(pUnoCrsr)
+    {
+        // Absatz selektieren
+        SwParaSelection aSelection(pUnoCrsr);
+        aRet = new SwXTextRange(*pUnoCrsr, xParentText);
+    }
+    else
+        throw uno::RuntimeException();
+    return aRet;
+}
+/*-- 11.12.98 08:12:52---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXParagraph::dispose(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwUnoCrsr* pUnoCrsr = ((SwXParagraph*)this)->GetCrsr();
+    if(pUnoCrsr)
+    {
+        // Absatz selektieren
+        SwParaSelection aSelection(pUnoCrsr);
+        pUnoCrsr->GetDoc()->DeleteAndJoin(*pUnoCrsr);
+        pUnoCrsr->Remove(this);
+    }
+    else
+        throw uno::RuntimeException();
+}
+/*-- 11.12.98 08:12:52---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXParagraph::addEventListener(const uno::Reference< lang::XEventListener > & aListener) throw( uno::RuntimeException )
+{
+    if(!GetRegisteredIn())
+        throw uno::RuntimeException();
+    aLstnrCntnr.AddListener(aListener);
+}
+/*-- 11.12.98 08:12:53---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXParagraph::removeEventListener(const uno::Reference< lang::XEventListener > & aListener) throw( uno::RuntimeException )
+{
+    if(!GetRegisteredIn() || !aLstnrCntnr.RemoveListener(aListener))
+        throw uno::RuntimeException();
+}
+/*-- 11.12.98 08:12:53---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< container::XEnumeration >  SwXParagraph::createEnumeration(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< container::XEnumeration >  aRef;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+        aRef = new SwXTextPortionEnumeration(*pUnoCrsr, xParentText);
+    else
+        throw uno::RuntimeException();
+    return aRef;
+
+}
+/*-- 11.12.98 08:12:54---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Type SwXParagraph::getElementType(void) throw( uno::RuntimeException )
+{
+    return ::getCppuType((uno::Reference*)0);
+}
+/*-- 11.12.98 08:12:54---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXParagraph::hasElements(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(((SwXParagraph*)this)->GetCrsr())
+        return sal_True;
+    else
+        return sal_False;
+}
+/*-- 11.12.98 08:12:55---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XText >  SwXParagraph::getText(void) throw( uno::RuntimeException )
+{
+    return xParentText;
+}
+/*-- 11.12.98 08:12:55---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XTextRange >  SwXParagraph::getStart(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< XTextRange >  xRet;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if( pUnoCrsr)
+    {
+        SwPaM aPam(*pUnoCrsr->Start());
+        uno::Reference< XText >  xParent = getText();
+        xRet = new SwXTextRange(aPam, xParent);
+    }
+    else
+        throw uno::RuntimeException();
+    return xRet;
+}
+/*-- 11.12.98 08:12:56---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XTextRange >  SwXParagraph::getEnd(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< XTextRange >  xRet;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if( pUnoCrsr)
+    {
+        SwPaM aPam(*pUnoCrsr->End());
+        uno::Reference< XText >  xParent = getText();
+        xRet = new SwXTextRange(aPam, xParent);
+    }
+    else
+        throw uno::RuntimeException();
+    return xRet;
+}
+/*-- 11.12.98 08:12:56---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+OUString SwXParagraph::getString(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    OUString aRet;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if( pUnoCrsr)
+        aRet = pUnoCrsr->GetNode()->GetTxtNode()->GetTxt();
+    else if(IsDescriptor())
+        aRet = m_sText;
+    else
+        throw uno::RuntimeException();
+    return aRet;
+}
+/* -----------------11.12.98 10:07-------------------
+ *
+ * --------------------------------------------------*/
+void SwXTextCursor::SetString(SwUnoCrsr& rUnoCrsr, const OUString& rString)
+{
+    // Start/EndAction
+    SwDoc* pDoc = rUnoCrsr.GetDoc();
+    UnoActionContext aAction(pDoc);
+    String aText(rString);
+    xub_StrLen nTxtLen = aText.Len();
+    pDoc->StartUndo(UNDO_INSERT);
+    if(rUnoCrsr.HasMark())
+        pDoc->DeleteAndJoin(rUnoCrsr);
+    if(nTxtLen)
+    {
+        //OPT: GetSystemCharSet
+        if( !pDoc->Insert(rUnoCrsr, aText) )
+            ASSERT( sal_False, "Doc->Insert(Str) failed." );
+        SwXTextCursor::SelectPam(rUnoCrsr, sal_True);
+        rUnoCrsr.Left(nTxtLen);
+    }
+    pDoc->EndUndo(UNDO_INSERT);
+}
+/*-- 11.12.98 08:12:57---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXParagraph::setString(const OUString& aString) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+
+    if(pUnoCrsr)
+    {
+        EXCEPT_ON_PROTECTION(*pUnoCrsr)
+        if(!lcl_IsStartOfPara(*pUnoCrsr))
+            pUnoCrsr->MovePara(fnParaCurr, fnParaStart);
+        SwXTextCursor::SelectPam(*pUnoCrsr, sal_True);
+        if(pUnoCrsr->GetNode()->GetTxtNode()->GetTxt().Len())
+            pUnoCrsr->MovePara(fnParaCurr, fnParaEnd);
+        SwXTextCursor::SetString(*pUnoCrsr, aString);
+        SwXTextCursor::SelectPam(*pUnoCrsr, sal_False);
+    }
+    else if(IsDescriptor())
+        m_sText = aString;
+    else
+        throw uno::RuntimeException();
+
+}
+/* -----------------23.03.99 12:49-------------------
+ *
+ * --------------------------------------------------*/
+uno::Reference< container::XEnumeration >  SwXParagraph::createContentEnumeration(const OUString& rServiceName)
+    throw( uno::RuntimeException )
+{
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if( !pUnoCrsr || COMPARE_EQUAL != rServiceName.compareToAscii("com.sun.star.text.TextContent") )
+        throw uno::RuntimeException();
+
+    uno::Reference< container::XEnumeration >  xRet = new SwXParaFrameEnumeration(*pUnoCrsr, PARAFRAME_PORTION_PARAGRAPH);
+    return xRet;
+}
+/* -----------------23.03.99 12:49-------------------
+ *
+ * --------------------------------------------------*/
+uno::Sequence< OUString > SwXParagraph::getAvailableServiceNames(void) throw( uno::RuntimeException )
+{
+    uno::Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.TextContent");
+    return aRet;
+}
+/*-- 11.12.98 08:12:58---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXParagraph::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew)
+{
+    ClientModify(this, pOld, pNew);
+    if(!GetRegisteredIn())
+        aLstnrCntnr.Disposing();
+}
+/******************************************************************
+ * SwXParaFrameEnumeration
+ ******************************************************************/
+SV_IMPL_PTRARR(SwDependArr, SwDepend*);
+/* -----------------------------06.04.00 16:39--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXParaFrameEnumeration::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXParaFrameEnumeration");
+}
+/* -----------------------------06.04.00 16:39--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXParaFrameEnumeration::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.util.ContentEnumeration") == rServiceName;
+}
+/* -----------------------------06.04.00 16:39--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXParaFrameEnumeration::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.util.ContentEnumeration");
+    return aRet;
+}
+/*-- 23.03.99 13:22:29---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXParaFrameEnumeration::SwXParaFrameEnumeration(const SwUnoCrsr& rUnoCrsr,
+                                                sal_uInt8 nParaFrameMode,
+                                                SwFrmFmt* pFmt)
+{
+    SwDoc* pDoc = rUnoCrsr.GetDoc();
+    SwUnoCrsr* pUnoCrsr = pDoc->CreateUnoCrsr(*rUnoCrsr.GetPoint(), sal_False);
+    if(rUnoCrsr.HasMark())
+    {
+        pUnoCrsr->SetMark();
+        *pUnoCrsr->GetMark() = *rUnoCrsr.GetMark();
+    }
+    pUnoCrsr->Add(this);
+
+    if(PARAFRAME_PORTION_PARAGRAPH == nParaFrameMode)
+    {
+        //alle Rahmen, Grafiken und OLEs suchen, die an diesem Absatz gebunden sind
+        sal_uInt16 nCount = pDoc->GetFlyCount();
+        for( sal_uInt16 i = 0; i < nCount; i++)
+        {
+            SwFrmFmt* pFmt = pDoc->GetFlyNum(i);
+            //steht der Anker in diesem Node und ist er absatzgebunden?
+            const SwNodeIndex nOwnNode = rUnoCrsr.GetPoint()->nNode;
+            if( pFmt->GetAnchor().GetAnchorId() == FLY_AT_CNTNT )
+            {
+                const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
+                const SwPosition* pAnchorPos = rAnchor.GetCntntAnchor();
+                if(pAnchorPos->nNode == nOwnNode)
+                {
+                    //jetzt einen SwDepend anlegen und in das Array einfuegen
+                    SwDepend* pNewDepend = new SwDepend(this, pFmt);
+                    aFrameArr.C40_INSERT(SwDepend, pNewDepend, aFrameArr.Count());
+                }
+            }
+        }
+    }
+    else if(pFmt)
+    {
+        //jetzt einen SwDepend anlegen und in das Array einfuegen
+        SwDepend* pNewDepend = new SwDepend(this, pFmt);
+        aFrameArr.C40_INSERT(SwDepend, pNewDepend, aFrameArr.Count());
+    }
+    else if((PARAFRAME_PORTION_CHAR == nParaFrameMode) || (PARAFRAME_PORTION_TEXTRANGE == nParaFrameMode))
+    {
+        SwPosFlyFrms aFlyFrms;
+        //get all frames that are bound at paragraph or at character
+        pDoc->GetAllFlyFmts(aFlyFrms, pUnoCrsr);//, bDraw);
+        for(USHORT i = 0; i < aFlyFrms.Count(); i++)
+        {
+            SwPosFlyFrm* pPosFly = aFlyFrms[i];
+            SwFrmFmt* pFrmFmt = (SwFrmFmt*)&pPosFly->GetFmt();
+            //jetzt einen SwDepend anlegen und in das Array einfuegen
+            SwDepend* pNewDepend = new SwDepend(this, pFrmFmt);
+            aFrameArr.C40_INSERT(SwDepend, pNewDepend, aFrameArr.Count());
+        }
+        //created from any text range
+        if(pUnoCrsr->HasMark())
+        {
+            if(pUnoCrsr->Start() != pUnoCrsr->GetPoint())
+                pUnoCrsr->Exchange();
+            do
+            {
+                FillFrame(*pUnoCrsr);
+                pUnoCrsr->Right();
+            }
+            while(*pUnoCrsr->Start() < *pUnoCrsr->End());
+        }
+        FillFrame(*pUnoCrsr);
+    }
+}
+/*-- 23.03.99 13:22:30---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXParaFrameEnumeration::~SwXParaFrameEnumeration()
+{
+    aFrameArr.DeleteAndDestroy(0, aFrameArr.Count());
+}
+/* -----------------------------03.04.00 10:15--------------------------------
+    Description: Search for a FLYCNT text attribute at the cursor point
+                and fill the frame into the array
+ ---------------------------------------------------------------------------*/
+void SwXParaFrameEnumeration::FillFrame(SwUnoCrsr& rUnoCrsr)
+{
+    // search for objects at the cursor - anchored at/as char
+    SwTxtAttr* pTxtAttr = rUnoCrsr.GetNode()->GetTxtNode()->GetTxtAttr(
+                    rUnoCrsr.GetPoint()->nContent, RES_TXTATR_FLYCNT);
+    if(pTxtAttr)
+    {
+        const SwFmtFlyCnt& rFlyCnt = pTxtAttr->GetFlyCnt();
+        SwFrmFmt* pFrmFmt = rFlyCnt.GetFrmFmt();
+        //jetzt einen SwDepend anlegen und in das Array einfuegen
+        SwDepend* pNewDepend = new SwDepend(this, pFrmFmt);
+        aFrameArr.C40_INSERT(SwDepend, pNewDepend, aFrameArr.Count());
+    }
+}
+/*-- 23.03.99 13:22:32---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXParaFrameEnumeration::hasMoreElements(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!GetCrsr())
+        throw uno::RuntimeException();
+    return xNextObject.is() ? sal_True : CreateNextObject();
+}
+/*-- 23.03.99 13:22:33---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXParaFrameEnumeration::nextElement(void)
+    throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!GetCrsr())
+        throw uno::RuntimeException();
+    if(!xNextObject.is() && aFrameArr.Count())
+    {
+        CreateNextObject();
+    }
+    if(!xNextObject.is())
+        throw container::NoSuchElementException();
+    uno::Any aRet(&xNextObject, ::getCppuType((uno::Reference*)0));
+    xNextObject = 0;
+    return aRet;
+}
+/* -----------------23.03.99 13:38-------------------
+ *
+ * --------------------------------------------------*/
+sal_Bool SwXParaFrameEnumeration::CreateNextObject()
+{
+    if(!aFrameArr.Count())
+        return sal_False;
+    SwDepend* pDepend = aFrameArr.GetObject(0);
+    aFrameArr.Remove(0);
+    SwFrmFmt* pFormat = (SwFrmFmt*)pDepend->GetRegisteredIn();
+    delete pDepend;
+    // das Format sollte hier immer vorhanden sein, sonst waere
+    // der Client im Modify geloescht worden
+    const SwNodeIndex* pIdx = pFormat->GetCntnt().GetCntntIdx();
+    const SwNode* pNd = GetCrsr()->GetDoc()->GetNodes()[ pIdx->GetIndex() + 1 ];
+
+    FlyCntType eType;
+    if(!pNd->IsNoTxtNode())
+        eType = FLYCNTTYPE_FRM;
+    else if(pNd->IsGrfNode())
+        eType = FLYCNTTYPE_GRF;
+    else
+        eType = FLYCNTTYPE_OLE;
+
+    uno::Reference< container::XNamed >  xFrame = SwXFrames::GetObject(*pFormat, eType);
+    xNextObject = uno::Reference< XTextContent >(xFrame, uno::UNO_QUERY);
+
+    return xNextObject.is();
+}
+
+/*-- 23.03.99 13:22:37---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void    SwXParaFrameEnumeration::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew)
+{
+    switch( pOld ? pOld->Which() : 0 )
+    {
+    case RES_REMOVE_UNO_OBJECT:
+    case RES_OBJECTDYING:
+        if( (void*)GetRegisteredIn() == ((SwPtrMsgPoolItem *)pOld)->pObject )
+            ((SwModify*)GetRegisteredIn())->Remove(this);
+        break;
+
+    case RES_FMT_CHG:
+        // wurden wir an das neue umgehaengt und wird das alte geloscht?
+        if( ((SwFmtChg*)pNew)->pChangedFmt == GetRegisteredIn() &&
+            ((SwFmtChg*)pOld)->pChangedFmt->IsFmtInDTOR() )
+            ((SwModify*)GetRegisteredIn())->Remove(this);
+        break;
+    }
+    if(!GetRegisteredIn())
+    {
+        aFrameArr.DeleteAndDestroy(0, aFrameArr.Count());
+        xNextObject = 0;
+    }
+    else
+    {
+        //dann war es vielleicht ein Frame am Absatz?
+        for(sal_uInt16 i = aFrameArr.Count(); i; i--)
+        {
+            SwDepend* pDepend = aFrameArr.GetObject(i-1);
+            if(!pDepend->GetRegisteredIn())
+            {
+                delete pDepend;
+                aFrameArr.Remove(i-1);
+            }
+        }
+    }
+}
+/******************************************************************
+ *  SwXTextPortionEnumeration
+ ******************************************************************/
+/* -----------------------------13.03.00 12:15--------------------------------
+
+ ---------------------------------------------------------------------------*/
+const uno::Sequence< sal_Int8 > & SwXTextPortionEnumeration::getUnoTunnelId()
+{
+    static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId();
+    return aSeq;
+}
+/* -----------------------------10.03.00 18:04--------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Int64 SAL_CALL SwXTextPortionEnumeration::getSomething( const uno::Sequence< sal_Int8 >& rId )
+    throw(uno::RuntimeException)
+{
+    if( rId.getLength() == 16
+        && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+                                        rId.getConstArray(), 16 ) )
+    {
+            return (sal_Int64)this;
+    }
+    return 0;
+}
+/* -----------------------------06.04.00 16:39--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXTextPortionEnumeration::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXTextPortionEnumeration");
+}
+/* -----------------------------06.04.00 16:39--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXTextPortionEnumeration::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.text.TextPortionEnumeration") == rServiceName;
+}
+/* -----------------------------06.04.00 16:39--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXTextPortionEnumeration::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.TextPortionEnumeration");
+    return aRet;
+}
+/*-- 27.01.99 10:44:43---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextPortionEnumeration::SwXTextPortionEnumeration(SwPaM& rParaCrsr, uno::Reference< XText >  xParentText) :
+    xParent(xParentText),
+    bAtEnd(sal_False),
+    bFirstPortion(sal_True)
+{
+    SwUnoCrsr* pUnoCrsr = rParaCrsr.GetDoc()->CreateUnoCrsr(*rParaCrsr.GetPoint(), sal_False);
+    pUnoCrsr->Add(this);
+
+    //alle Rahmen, Grafiken und OLEs suchen, die an diesem Absatz AM ZEICHEN gebunden sind
+    SwDoc* pDoc = pUnoCrsr->GetDoc();
+    sal_uInt16 nCount = pDoc->GetFlyCount();
+    const SwNodeIndex nOwnNode = pUnoCrsr->GetPoint()->nNode;
+    for( sal_uInt16 i = 0; i < nCount; i++)
+    {
+        SwFrmFmt* pFmt = pDoc->GetFlyNum(i);
+        //steht der Anker in diesem Node und ist er absatzgebunden?
+        if( pFmt->GetAnchor().GetAnchorId() == FLY_AUTO_CNTNT )
+        {
+            const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
+            const SwPosition* pAnchorPos = rAnchor.GetCntntAnchor();
+            if(pAnchorPos->nNode == nOwnNode)
+            {
+                //jetzt einen SwDepend anlegen und sortiert in das Array einfuegen
+                SwDepend* pNewDepend = new SwDepend(this, pFmt);
+                const SwFmtAnchor& rNewAnchor = pFmt->GetAnchor();
+                const SwPosition* pNewAnchorPos = rNewAnchor.GetCntntAnchor();
+                xub_StrLen nInsertIndex = pNewAnchorPos->nContent.GetIndex();
+
+                for(sal_uInt16 nFrame = 0; nFrame < aFrameArr.Count(); nFrame++)
+                {
+                    SwDepend* pCurDepend = aFrameArr.GetObject(nFrame);
+                    SwFrmFmt* pFormat = (SwFrmFmt*)pCurDepend->GetRegisteredIn();
+                    const SwFmtAnchor& rAnchor = pFormat->GetAnchor();
+                    const SwPosition* pAnchorPos = rAnchor.GetCntntAnchor();
+
+                    if(pAnchorPos->nContent.GetIndex() > nInsertIndex)
+                    {
+                        aFrameArr.C40_INSERT(SwDepend, pNewDepend, nFrame);
+                        pNewDepend = 0;
+                        break;
+                    }
+                }
+                if(pNewDepend)
+                    aFrameArr.C40_INSERT(SwDepend, pNewDepend, aFrameArr.Count());
+            }
+        }
+    }
+    CreatePortions();
+}
+/*-- 27.01.99 10:44:44---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextPortionEnumeration::~SwXTextPortionEnumeration()
+{
+    for(sal_uInt16 nFrame = aFrameArr.Count(); nFrame; nFrame--)
+    {
+        SwDepend* pCurDepend = aFrameArr.GetObject(nFrame - 1);
+        delete pCurDepend;
+        aFrameArr.Remove(nFrame - 1);
+    }
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    delete pUnoCrsr;
+}
+/*-- 27.01.99 10:44:44---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextPortionEnumeration::hasMoreElements(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    return aPortionArr.Count() > 0;
+}
+/*-- 27.01.99 10:44:45---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXTextPortionEnumeration::nextElement(void)
+    throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!aPortionArr.Count())
+        throw container::NoSuchElementException();
+    XTextRangeRefPtr pPortion = aPortionArr.GetObject(0);
+    Any aRet(pPortion, ::getCppuType((uno::Reference*)0));
+    aPortionArr.Remove(0);
+    delete pPortion;
+    return aRet;
+}
+/* -----------------------------31.08.00 14:28--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void lcl_InsertRefMarkPortion(
+    XTextRangeArr& rArr, SwUnoCrsr* pUnoCrsr, Reference xParent, SwTxtAttr* pAttr, BOOL bEnd)
+{
+    SwDoc* pDoc = pUnoCrsr->GetDoc();
+    SwFmtRefMark& rRefMark = ((SwFmtRefMark&)pAttr->GetAttr());
+    Reference xContent = ((SwUnoCallBack*)pDoc->GetUnoCallBack())->GetRefMark(rRefMark);
+    if(!xContent.is())
+        xContent = new SwXReferenceMark(pDoc, &rRefMark);
+
+    SwXTextPortion* pPortion;
+    if(!bEnd)
+    {
+        rArr.Insert(
+            new Reference< XTextRange >(pPortion = new SwXTextPortion(*pUnoCrsr, xParent, PORTION_REFMARK_START)),
+            rArr.Count());
+        pPortion->SetRefMark(xContent);
+        pPortion->SetIsCollapsed(pAttr->GetEnd() ? FALSE : TRUE);
+    }
+    else
+    {
+        rArr.Insert(
+            new Reference< XTextRange >(pPortion = new SwXTextPortion(*pUnoCrsr, xParent, PORTION_REFMARK_END)),
+            rArr.Count());
+        pPortion->SetRefMark(xContent);
+    }
+}
+//-----------------------------------------------------------------------------
+void lcl_InsertTOXMarkPortion(
+    XTextRangeArr& rArr, SwUnoCrsr* pUnoCrsr, Reference xParent, SwTxtAttr* pAttr, BOOL bEnd)
+{
+    SwDoc* pDoc = pUnoCrsr->GetDoc();
+    SwTOXMark& rTOXMark = ((SwTOXMark&)pAttr->GetAttr());
+
+    SwClientIter aIter(*(SwTOXType*)rTOXMark.GetTOXType());
+    SwXDocumentIndexMark* pxMark = (SwXDocumentIndexMark*)
+                                            aIter.First(TYPE(SwXDocumentIndexMark));
+    while( pxMark )
+    {
+        if(pxMark->GetTOXMark() == &rTOXMark)
+            break;
+        pxMark = (SwXDocumentIndexMark*)aIter.Next();
+    }
+
+    Reference xContent = pxMark;
+    if(!xContent.is())
+        xContent = new SwXDocumentIndexMark(rTOXMark.GetTOXType(), &rTOXMark, pDoc);
+
+    SwXTextPortion* pPortion;
+    if(!bEnd)
+    {
+        rArr.Insert(
+            new Reference< XTextRange >(pPortion = new SwXTextPortion(*pUnoCrsr, xParent, PORTION_TOXMARK_START)),
+            rArr.Count());
+        pPortion->SetTOXMark(xContent);
+        pPortion->SetIsCollapsed(pAttr->GetEnd() ? FALSE : TRUE);
+    }
+    if(bEnd)
+    {
+        rArr.Insert(
+            new Reference< XTextRange >(pPortion = new SwXTextPortion(*pUnoCrsr, xParent, PORTION_TOXMARK_END)),
+            rArr.Count());
+        pPortion->SetTOXMark(xContent);
+    }
+}
+//-----------------------------------------------------------------------------
+#define BKM_TYPE_START          0
+#define BKM_TYPE_END            1
+#define BKM_TYPE_START_END      2
+struct SwXBookmarkPortion_Impl
+{
+    SwXBookmark*                pBookmark;
+    Reference     xBookmark;
+    BYTE                        nBkmType;
+    ULONG                       nIndex;
+
+    SwXBookmarkPortion_Impl( SwXBookmark* pXMark, BYTE nType, ULONG nIdx) :
+        pBookmark(pXMark),
+        xBookmark(pXMark),
+        nBkmType(nType),
+        nIndex(nIdx){}
+
+    // compare by nIndex
+    BOOL operator < (const SwXBookmarkPortion_Impl &rCmp) const;
+    BOOL operator ==(const SwXBookmarkPortion_Impl &rCmp) const;
+
+};
+BOOL SwXBookmarkPortion_Impl::operator ==(const SwXBookmarkPortion_Impl &rCmp) const
+{
+    return nIndex == rCmp.nIndex;
+}
+
+BOOL SwXBookmarkPortion_Impl::operator < (const SwXBookmarkPortion_Impl &rCmp) const
+{
+    return nIndex < rCmp.nIndex;
+}
+
+typedef SwXBookmarkPortion_Impl* SwXBookmarkPortion_ImplPtr;
+SV_DECL_PTRARR_SORT(SwXBookmarkPortionArr, SwXBookmarkPortion_ImplPtr, 0, 2)
+SV_IMPL_OP_PTRARR_SORT(SwXBookmarkPortionArr, SwXBookmarkPortion_ImplPtr)
+//-----------------------------------------------------------------------------
+void lcl_ExportBookmark(
+    SwXBookmarkPortionArr& rBkmArr, ULONG nIndex,
+    SwUnoCrsr* pUnoCrsr, Reference xParent, XTextRangeArr& rPortionArr)
+{
+    SwXBookmarkPortion_ImplPtr pPtr;
+    while(rBkmArr.Count() && nIndex == (pPtr = rBkmArr.GetObject(0))->nIndex)
+    {
+        SwXTextPortion* pPortion;
+        if(BKM_TYPE_START == pPtr->nBkmType || BKM_TYPE_START_END == pPtr->nBkmType)
+        {
+            rPortionArr.Insert(
+                new Reference< XTextRange >(pPortion = new SwXTextPortion(*pUnoCrsr, xParent, PORTION_BOOKMARK_START)),
+                rPortionArr.Count());
+            pPortion->SetBookmark(pPtr->xBookmark);
+            pPortion->SetIsCollapsed(BKM_TYPE_START_END == pPtr->nBkmType ? TRUE : FALSE);
+
+        }
+        if(BKM_TYPE_END == pPtr->nBkmType)
+        {
+            rPortionArr.Insert(
+                new Reference< XTextRange >(pPortion = new SwXTextPortion(*pUnoCrsr, xParent, PORTION_BOOKMARK_END)),
+                rPortionArr.Count());
+            pPortion->SetBookmark(pPtr->xBookmark);
+        }
+        rBkmArr.Remove((USHORT)0);
+        delete pPtr;
+    }
+}
+//-----------------------------------------------------------------------------
+void SwXTextPortionEnumeration::CreatePortions()
+{
+    uno::Any aRet;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr /*&& !bAtEnd*/)
+    {
+        SwXBookmarkPortionArr aBkmArr;
+        SwDoc* pDoc = pUnoCrsr->GetDoc();
+        const SwNodeIndex nOwnNode = pUnoCrsr->GetPoint()->nNode;
+        //search for all bookmarks that start or end in this paragraph
+        const SwBookmarks& rMarks = pDoc->GetBookmarks();
+        sal_uInt16 nArrLen = rMarks.Count();
+        for( sal_uInt16 n = 0; n < nArrLen; ++n )
+        {
+            SwBookmark* pMark = rMarks.GetObject( n );
+            if( !pMark->IsBookMark() )
+                continue;
+
+            const SwPosition& rPos1 = pMark->GetPos();
+            const SwPosition* pPos2 = pMark->GetOtherPos();
+            BOOL bBackward = pPos2 ? rPos1 > *pPos2: FALSE;
+            if(rPos1.nNode == nOwnNode)
+            {
+                BYTE nType = bBackward ? BKM_TYPE_END : BKM_TYPE_START;
+                if(!pPos2)
+                {
+                    nType = BKM_TYPE_START_END;
+                }
+                SwXBookmarkPortion_ImplPtr pBkmPtr = new SwXBookmarkPortion_Impl(
+                    SwXBookmarks::GetObject( *pMark, pDoc ), nType, rPos1.nContent.GetIndex() );
+
+                aBkmArr.Insert(pBkmPtr);
+
+            }
+            if(pPos2 && pPos2->nNode == nOwnNode)
+            {
+                BYTE nType = bBackward ? BKM_TYPE_START : BKM_TYPE_END;
+                SwXBookmarkPortion_ImplPtr pBkmPtr = new SwXBookmarkPortion_Impl(
+                        SwXBookmarks::GetObject( *pMark, pDoc ), nType, pPos2->nContent.GetIndex() );
+                aBkmArr.Insert(pBkmPtr);
+            }
+        }
+#ifdef DEBUG
+        for(long i_debug = 0; i_debug HasMark())
+            {
+                if(*pUnoCrsr->GetPoint() < *pUnoCrsr->GetMark())
+                    pUnoCrsr->Exchange();
+                pUnoCrsr->DeleteMark();
+            }
+            if(!bFirstPortion   && pUnoCrsr->GetCntntNode() &&
+                    pUnoCrsr->GetPoint()->nContent == pUnoCrsr->GetCntntNode()->Len())
+            {
+                //hier sollte man nie ankommen!
+                bAtEnd = sal_True;
+            }
+            else
+            {
+                SwNode* pNode = pUnoCrsr->GetNode();
+                if(ND_TEXTNODE == pNode->GetNodeType())
+                {
+                    SwTxtNode* pTxtNode = (SwTxtNode*)pNode;
+                    SwpHints* pHints = pTxtNode->GetpSwpHints();
+                    SwTextPortionType ePortionType = PORTION_TEXT;
+                    xub_StrLen nCurrentIndex = pUnoCrsr->GetPoint()->nContent.GetIndex();
+                    xub_StrLen nFirstFrameIndex = STRING_MAXLEN;
+                    uno::Reference< XTextRange >  xRef;
+                    if(!pUnoCrsr->GetCntntNode()->Len())
+                    {
+                        if(pHints)
+                        {
+                            DBG_ERROR("hints not exported")
+                        }
+                        if(aBkmArr.Count())
+                        {
+                            lcl_ExportBookmark(aBkmArr, 0, pUnoCrsr, xParent, aPortionArr);
+                        }
+                        // der Absatz ist leer, also nur Portion erzeugen und raus
+                        xRef = new SwXTextPortion(*pUnoCrsr, xParent, ePortionType);
+                    }
+                    else
+                    {
+                        //falls schon Rahmen entsorgt wurden, dann raus hier
+                        for(sal_uInt16 nFrame = aFrameArr.Count(); nFrame; nFrame--)
+                        {
+                            SwDepend* pCurDepend = aFrameArr.GetObject(nFrame - 1);
+                            if(!pCurDepend->GetRegisteredIn())
+                            {
+                                delete pCurDepend;
+                                aFrameArr.Remove(nFrame - 1);
+                            }
+                        }
+
+                        //zunaechst den ersten Frame im aFrameArr finden (bezogen auf die Position im Absatz)
+                        SwDepend* pFirstFrameDepend = 0;
+                        //Eintraege im aFrameArr sind sortiert!
+                        if(aFrameArr.Count())
+                        {
+                            SwDepend* pCurDepend = aFrameArr.GetObject(0);
+                            SwFrmFmt* pFormat = (SwFrmFmt*)pCurDepend->GetRegisteredIn();
+                            const SwFmtAnchor& rAnchor = pFormat->GetAnchor();
+                            const SwPosition* pAnchorPos = rAnchor.GetCntntAnchor();
+                            pFirstFrameDepend = pCurDepend;
+                            nFirstFrameIndex = pAnchorPos->nContent.GetIndex();
+                        }
+
+                        SwXTextCursor::SelectPam(*pUnoCrsr, sal_True);
+
+                        //ist hier schon ein Rahmen faellig?
+                        if(nCurrentIndex == nFirstFrameIndex)
+                        {
+                            xRef = new SwXTextPortion(*pUnoCrsr, xParent,
+                                *(SwFrmFmt*)pFirstFrameDepend->GetRegisteredIn());
+                            SwDepend* pCurDepend = aFrameArr.GetObject(0);
+                            delete pCurDepend;
+                            aFrameArr.Remove(0);
+                        }
+                    }
+                    if(!xRef.is())
+                    {
+                        lcl_ExportBookmark(aBkmArr, nCurrentIndex, pUnoCrsr, xParent, aPortionArr);
+                        if(pHints)
+                        {
+                            sal_Bool bAttrFound = sal_False;
+                            //search for special text attributes - first some ends
+                            sal_uInt16 nEndIndex = 0;
+                            sal_uInt16 nNextEnd = 0;
+                            while(nEndIndex < pHints->GetEndCount() &&
+                                (!pHints->GetEnd(nEndIndex)->GetEnd() ||
+                                nCurrentIndex >= (nNextEnd = (*pHints->GetEnd(nEndIndex)->GetEnd()))))
+                            {
+                                if(pHints->GetEnd(nEndIndex)->GetEnd())
+                                {
+                                    SwTxtAttr* pAttr = pHints->GetEnd(nEndIndex);
+                                    USHORT nAttrWhich = pAttr->Which();
+                                    if(nNextEnd == nCurrentIndex &&
+                                        ( RES_TXTATR_TOXMARK == nAttrWhich ||
+                                                RES_TXTATR_REFMARK == nAttrWhich))
+                                    {
+                                        switch( nAttrWhich )
+                                        {
+                                            case RES_TXTATR_TOXMARK:
+                                                lcl_InsertTOXMarkPortion(
+                                                    aPortionArr, pUnoCrsr, xParent, pAttr, TRUE);
+                                                ePortionType = PORTION_TEXT;
+                                                DBG_ERROR("ToxMark");
+                                            break;
+                                            case RES_TXTATR_REFMARK:
+                                                lcl_InsertRefMarkPortion(
+                                                    aPortionArr, pUnoCrsr, xParent, pAttr, TRUE);
+                                                ePortionType = PORTION_TEXT;
+                                            break;
+
+                                        }
+                                    }
+                                }
+                                nEndIndex++;
+                            }
+                            //then som starts
+                            sal_uInt16 nStartIndex = 0;
+                            sal_uInt16 nNextStart = 0;
+                            while(nStartIndex < pHints->GetStartCount() &&
+                                nCurrentIndex >= (nNextStart = (*pHints->GetStart(nStartIndex)->GetStart())))
+                            {
+                                SwTxtAttr* pAttr = pHints->GetStart(nStartIndex);
+                                USHORT nAttrWhich = pAttr->Which();
+                                if(nNextStart == nCurrentIndex &&
+                                    (!pAttr->GetEnd() ||
+                                        RES_TXTATR_TOXMARK == nAttrWhich ||
+                                            RES_TXTATR_REFMARK == nAttrWhich))
+                                {
+                                    switch( nAttrWhich )
+                                    {
+                                        case RES_TXTATR_FIELD:
+                                            pUnoCrsr->Right(1);
+                                            bAttrFound = sal_True;
+                                            ePortionType = PORTION_FIELD;
+                                        break;
+                                        case RES_TXTATR_FLYCNT   :
+                                            pUnoCrsr->Right(1);
+                                            pUnoCrsr->Exchange();
+                                            bAttrFound = sal_True;
+                                            ePortionType = PORTION_FRAME;
+                                        break;
+                                        case RES_TXTATR_FTN      :
+                                        {
+                                            pUnoCrsr->Right(1);
+                                            SwXTextPortion* pPortion;
+                                            xRef =  pPortion = new SwXTextPortion(*pUnoCrsr, xParent, PORTION_FOOTNOTE);
+                                            Reference xContent =
+                                                Reference(
+                                                SwXFootnotes::GetObject(*pDoc, pAttr->SwTxtAttr::GetFtn()),
+                                                UNO_QUERY);
+                                            pPortion->SetFootnote(xContent);
+                                            bAttrFound = sal_True;
+                                            ePortionType = PORTION_TEXT;
+                                        }
+                                        break;
+                                        case RES_TXTATR_SOFTHYPH :
+                                        {
+                                            SwXTextPortion* pPortion;
+                                            aPortionArr.Insert(
+                                                new Reference< XTextRange >(
+                                                    pPortion = new SwXTextPortion(
+                                                        *pUnoCrsr, xParent, PORTION_CONTROL_CHAR)),
+                                                aPortionArr.Count());
+                                            pPortion->SetControlChar(3);
+                                            ePortionType = PORTION_TEXT;
+                                        }
+                                        break;
+                                        case RES_TXTATR_HARDBLANK:
+                                        {
+                                            ePortionType = PORTION_CONTROL_CHAR;
+                                            SwXTextPortion* pPortion;
+                                            aPortionArr.Insert(
+                                                new Reference< XTextRange >(
+                                                    pPortion = new SwXTextPortion(
+                                                        *pUnoCrsr, xParent, PORTION_CONTROL_CHAR)),
+                                                aPortionArr.Count());
+                                            const SwFmtHardBlank& rFmt = pAttr->GetHardBlank();
+                                            if(rFmt.GetChar() == '-')
+                                                pPortion->SetControlChar(2);//HARD_HYPHEN
+                                            else
+                                                pPortion->SetControlChar(4);//HARD_SPACE
+                                            ePortionType = PORTION_TEXT;
+                                        }
+                                        break;
+                                        case RES_TXTATR_TOXMARK:
+                                            lcl_InsertTOXMarkPortion(
+                                                aPortionArr, pUnoCrsr, xParent, pAttr, FALSE);
+                                            ePortionType = PORTION_TEXT;
+                                            DBG_ERROR("ToxMark");
+                                        break;
+                                        case RES_TXTATR_REFMARK:
+                                            lcl_InsertRefMarkPortion(
+                                                aPortionArr, pUnoCrsr, xParent, pAttr, FALSE);
+                                            ePortionType = PORTION_TEXT;
+                                        break;
+                                        default:
+                                            DBG_ERROR("was fuer ein Attribut?");
+                                    }
+
+                                }
+                                nStartIndex++;
+                            }
+
+                            if(!bAttrFound)
+                            {
+                                // hier wird nach Uebergaengen zwischen Attributen gesucht, die nach der
+                                // aktuellen Cursorposition liegen
+                                // wenn dabei ein Rahmen 'ueberholt' wird, dann muss auch in der TextPortion unterbrochen werden
+
+                                nStartIndex = 0;
+                                nNextStart = 0;
+                                while(nStartIndex < pHints->GetStartCount() &&
+                                    nCurrentIndex >= (nNextStart = (*pHints->GetStart(nStartIndex)->GetStart())))
+                                    nStartIndex++;
+
+                                sal_uInt16 nEndIndex = 0;
+                                sal_uInt16 nNextEnd = 0;
+                                while(nEndIndex < pHints->GetEndCount() &&
+                                    nCurrentIndex >= (nNextEnd = (*pHints->GetEnd(nEndIndex)->GetAnyEnd())))
+                                    nEndIndex++;
+                                //nMovePos legt die neue EndPosition fest
+                                sal_uInt16 nMovePos = nNextStart > nCurrentIndex && nNextStart < nNextEnd ? nNextStart : nNextEnd;
+
+                                if(aBkmArr.Count() && aBkmArr.GetObject(0)->nIndex < nMovePos)
+                                {
+                                    DBG_ASSERT(aBkmArr.GetObject(0)->nIndex > nCurrentIndex,
+                                        "forgotten bookmark(s)")
+                                    nMovePos = aBkmArr.GetObject(0)->nIndex;
+                                }
+                                // liegt die Endposition nach dem naechsten Rahmen, dann aufbrechen
+                                if(nFirstFrameIndex != USHRT_MAX && nMovePos > nFirstFrameIndex)
+                                    nMovePos = nFirstFrameIndex;
+
+                                if(nMovePos > nCurrentIndex)
+                                    pUnoCrsr->Right(nMovePos - nCurrentIndex);
+                                else
+                                    pUnoCrsr->MovePara(fnParaCurr, fnParaEnd);
+                            }
+                        }
+                        else if(USHRT_MAX != nFirstFrameIndex)
+                        {
+                            pUnoCrsr->Right(nFirstFrameIndex - nCurrentIndex);
+                        }
+                        else
+                        {
+                            lcl_ExportBookmark(aBkmArr, nCurrentIndex, pUnoCrsr, xParent, aPortionArr);
+                            if(!aBkmArr.Count())
+                                sal_Bool bMove = pUnoCrsr->MovePara(fnParaCurr, fnParaEnd);
+                            else
+                            {
+                                SwXBookmarkPortion_ImplPtr pPtr = aBkmArr.GetObject(0);
+                                sal_uInt16 nMovePos = pPtr->nIndex;
+                                DBG_ASSERT(nMovePos > nCurrentIndex, "wrong move index")
+                                pUnoCrsr->Right(nMovePos - nCurrentIndex);
+                            }
+                        }
+                    }
+                    if(!xRef.is())
+                        xRef = new SwXTextPortion(*pUnoCrsr, xParent, ePortionType);
+                    aPortionArr.Insert(new Reference(xRef), aPortionArr.Count());
+                }
+                else
+                {
+                    DBG_ERROR("kein TextNode - was nun?")
+                }
+            }
+            if(*pUnoCrsr->GetPoint() < *pUnoCrsr->GetMark())
+                    pUnoCrsr->Exchange();
+
+            // Absatzende ?
+            if(pUnoCrsr->GetCntntNode() &&
+                    pUnoCrsr->GetPoint()->nContent == pUnoCrsr->GetCntntNode()->Len())
+                bAtEnd = sal_True;
+        }
+    }
+}
+/*-- 27.01.99 10:44:45---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void    SwXTextPortionEnumeration::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew)
+{
+    ClientModify(this, pOld, pNew);
+}
+
+/* -----------------22.04.99 11:24-------------------
+ *
+ * --------------------------------------------------*/
+typedef uno::Reference< lang::XEventListener > *  XEventListenerPtr;
+SV_DECL_PTRARR(SwEvtLstnrArray, XEventListenerPtr, 4, 4);
+SV_IMPL_PTRARR(SwEvtLstnrArray, XEventListenerPtr);
+
+/*-- 22.04.99 11:24:59---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwEventListenerContainer::SwEventListenerContainer( uno::XInterface* pxParent) :
+    pListenerArr(0),
+    pxParent(pxParent)
+{
+}
+/*-- 22.04.99 11:24:59---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwEventListenerContainer::~SwEventListenerContainer()
+{
+    if(pListenerArr && pListenerArr->Count())
+    {
+        pListenerArr->DeleteAndDestroy(0, pListenerArr->Count());
+    }
+    delete pListenerArr;
+}
+/*-- 22.04.99 11:24:59---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void    SwEventListenerContainer::AddListener(const uno::Reference< lang::XEventListener > & rxListener)
+{
+    if(!pListenerArr)
+        pListenerArr = new SwEvtLstnrArray;
+    uno::Reference< lang::XEventListener > * pInsert = new uno::Reference< lang::XEventListener > ;
+    *pInsert = rxListener;
+    pListenerArr->Insert(pInsert, pListenerArr->Count());
+}
+/*-- 22.04.99 11:25:00---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool    SwEventListenerContainer::RemoveListener(const uno::Reference< lang::XEventListener > & rxListener)
+{
+    if(!pListenerArr)
+        return sal_False;
+    else
+    {
+         lang::XEventListener* pLeft = rxListener.get();
+        for(sal_uInt16 i = 0; i < pListenerArr->Count(); i++)
+        {
+            XEventListenerPtr pElem = pListenerArr->GetObject(i);
+             lang::XEventListener* pRight = pElem->get();
+            if(pLeft == pRight)
+            {
+                pListenerArr->Remove(i);
+                delete pElem;
+                return sal_True;
+            }
+        }
+    }
+    return sal_False;
+}
+/*-- 22.04.99 11:25:00---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void    SwEventListenerContainer::Disposing()
+{
+    if(!pListenerArr)
+        return;
+
+    lang::EventObject aObj(pxParent);
+    for(sal_uInt16 i = 0; i < pListenerArr->Count(); i++)
+    {
+        XEventListenerPtr pElem = pListenerArr->GetObject(i);
+        (*pElem)->disposing(aObj);
+    }
+    pListenerArr->DeleteAndDestroy(0, pListenerArr->Count());
+}
+/*------------------------------------------------------------------------
+
+    $Log: not supported by cvs2svn $
+    Revision 1.262  2000/09/18 16:04:33  willem.vandorp
+    OpenOffice header added.
+
+    Revision 1.261  2000/09/12 13:03:59  os
+    #78700# types of text content properties corrected
+
+    Revision 1.260  2000/09/12 11:42:58  os
+    #78682# support of service TextContent
+
+    Revision 1.259  2000/09/11 08:33:01  os
+    #76672# get page no corrected
+
+    Revision 1.258  2000/09/11 06:57:15  os
+    bookmarks start/end corrected
+
+    Revision 1.257  2000/09/07 07:57:47  os
+    SwXTextPortion - new properties: IsCollapsed, IsStart
+
+    Revision 1.256  2000/09/05 15:21:03  os
+    footnote property at SwTextPortion
+
+    Revision 1.255  2000/09/05 09:40:58  os
+    CreatePortions: create selected textportion for footnotes
+
+    Revision 1.254  2000/09/04 12:50:48  os
+    TextPortionEnumeration almost completed
+
+    Revision 1.253  2000/09/01 14:35:51  os
+    text portion generation almost completed
+
+    Revision 1.252  2000/08/31 15:01:59  os
+    SwXTextPortionEnumeration: Fill Array of portions in Ctor
+    getPropertyState corrected
+
+    Revision 1.251  2000/08/30 16:49:58  jp
+    use CharClass instead of international
+
+    Revision 1.250  2000/08/29 11:29:20  os
+    prevent reading of inherited properties
+
+    Revision 1.249  2000/08/25 08:46:58  os
+    +property DropCapCharStyleName
+
+    Revision 1.248  2000/08/24 15:14:27  os
+    new Property: NumberingIsNumber
+
+    Revision 1.247  2000/08/24 11:14:34  mib
+    bug fixes for XML import
+
+    Revision 1.246  2000/08/22 14:52:17  os
+    #77933# GotoNextWord: if GoNextWord fails goto next paragraph
+
+    Revision 1.245  2000/08/18 08:37:11  os
+    #77726# SwSriter - additional parameter
+
+    Revision 1.244  2000/08/09 14:50:16  os
+    create cell objects without SwTableBox*
+
+    Revision 1.243  2000/08/02 14:56:21  mib
+    - NumberingLevel, NumberingStartValue now sal_Int16
+    - TextField property fixed
+    - ParaStyleName and ParaConditionalStyleName fixed
+
+    Revision 1.242  2000/07/27 12:33:04  jp
+    GetCurTxtFmtColl(): returns the right Collection
+
+    Revision 1.241  2000/07/21 11:59:42  os
+    #76495# SwXParagraph: TextContent service corrected
+
+    Revision 1.240  2000/07/19 10:59:43  os
+    properties added/renamed
+
+    Revision 1.239  2000/07/11 13:43:43  os
+    #76708# insert/remove paragraphs before/behind tables
+
+    Revision 1.238  2000/06/29 09:18:05  os
+    #76417# gotoStartOfWord returns correctly
+
+    Revision 1.237  2000/06/29 08:48:43  os
+    #76365# SwXParagraph::set/getPropertyValue: call SwXTextCursor::Get/SetPropertyValue
+
+    Revision 1.236  2000/06/29 08:10:23  os
+    #76495# SwXParagraph::set/getPropertyValue corrected;
+
+    Revision 1.235  2000/06/27 12:10:33  os
+    #76423# programmatic style names
+
+    Revision 1.234  2000/05/30 11:20:14  os
+    #76026# SwXParagraph::XServiceInfo completed
+
+    Revision 1.233  2000/05/16 17:21:32  jp
+    Changes for Unicode
+
+    Revision 1.232  2000/05/16 09:14:55  os
+    project usr removed
+
+    Revision 1.231  2000/05/04 15:16:36  os
+    reduce size of unoobj.cxx
+
+    Revision 1.230  2000/05/04 08:58:12  os
+    #75145# XPropertySet/XPropertyState now available at SwXTextRange
+
+    Revision 1.229  2000/04/27 10:46:56  os
+    UNICODE
+
+    Revision 1.228  2000/04/26 11:35:19  os
+    GetName() returns String&
+
+    Revision 1.227  2000/04/19 13:35:30  os
+    UNICODE
+
+    Revision 1.226  2000/04/11 08:31:03  os
+    UNICODE
+
+    Revision 1.225  2000/04/04 15:08:03  os
+    #74484# XTextRangeCompare impl. #74483# ContentEnumeration available at SwXTextRange/SwXTextCursor
+
+    Revision 1.224  2000/03/27 10:21:10  os
+    UNO III
+
+    Revision 1.223  2000/03/24 10:31:52  os
+    #65681# SwXReferenceMark: always add to UnoCallBack
+
+    Revision 1.222  2000/03/21 15:42:24  os
+    UNOIII
+
+    Revision 1.221  2000/03/13 16:08:18  os
+    #74154# Exceptions have to be declared
+
+    Revision 1.220  2000/03/07 17:00:32  hjs
+    #65293# includes
+
+
+------------------------------------------------------------------------*/
+
diff --git a/sw/source/core/unocore/unoport.cxx b/sw/source/core/unocore/unoport.cxx
new file mode 100644
index 000000000000..c04bd5258c1d
--- /dev/null
+++ b/sw/source/core/unocore/unoport.cxx
@@ -0,0 +1,704 @@
+/*************************************************************************
+ *
+ *  $RCSfile: unoport.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:28 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _VOS_MUTEX_HXX_ //autogen
+#include 
+#endif
+#ifndef _SV_SVAPP_HXX //autogen
+#include 
+#endif
+#ifndef _UNOOBJ_HXX
+#include 
+#endif
+#ifndef _UNOMAP_HXX
+#include 
+#endif
+#ifndef _UNOPRNMS_HXX
+#include 
+#endif
+#ifndef _UNOCRSR_HXX
+#include 
+#endif
+#ifndef _TXTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _NDTXT_HXX //autogen
+#include 
+#endif
+#ifndef _DOC_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFLCNT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFLD_HXX //autogen
+#include 
+#endif
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::beans;
+using namespace ::rtl;
+
+//TODO: new Interface & new uno::Exception for protected content
+#define EXCEPT_ON_PROTECTION(rUnoCrsr)  \
+    if((rUnoCrsr).HasReadonlySel()) \
+        throw uno::RuntimeException();
+
+/******************************************************************
+ * SwXTextPortion
+ ******************************************************************/
+
+/*-- 11.12.98 09:56:52---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwFmtFld*   SwXTextPortion::GetFldFmt(sal_Bool bInit)
+{
+    SwFmtFld* pRet = 0;
+    // initial wird es immer gesucht, danach nur noch, wenn es bereits existierte
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr && (bInit || pFmtFld))
+    {
+        SwTxtNode *pNode = pUnoCrsr->GetPoint()->nNode.GetNode().GetTxtNode();
+        SwTxtFld *pTxtFld = 0;
+        if( pNode )
+            pTxtFld = pNode->GetTxtFld( pUnoCrsr->Start()->nContent );
+        if(pTxtFld)
+            pFmtFld = pRet = (SwFmtFld*)&pTxtFld->GetFld();
+    }
+    return pRet;
+}
+/*-- 11.12.98 09:56:55---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextPortion::SwXTextPortion(const SwUnoCrsr* pPortionCrsr, uno::Reference< XText >  xParent,
+        SwTextPortionType eType) :
+    aPropSet(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_CURSOR)),
+    aLstnrCntnr( (XTextRange*)this),
+    pFmtFld(0),
+    xParentText(xParent),
+    ePortionType(eType),
+    pFrameFmt(0),
+    aFrameDepend(this, 0),
+    bIsCollapsed(FALSE),
+    nControlChar(0)
+{
+    SwUnoCrsr* pUnoCrsr = pPortionCrsr->GetDoc()->CreateUnoCrsr(*pPortionCrsr->GetPoint());
+    if(pPortionCrsr->HasMark())
+    {
+        pUnoCrsr->SetMark();
+        *pUnoCrsr->GetMark() = *pPortionCrsr->GetMark();
+    }
+    pUnoCrsr->Add(this);
+    // erst nach ->Add()
+    if(ePortionType == PORTION_FIELD)
+        GetFldFmt(sal_True);
+//  else if(ePortionType == PORTION_FRAME)
+//      ...;
+}
+/* -----------------24.03.99 16:30-------------------
+ *
+ * --------------------------------------------------*/
+SwXTextPortion::SwXTextPortion(const SwUnoCrsr* pPortionCrsr, uno::Reference< XText >  xParent,
+                        SwFrmFmt& rFmt ) :
+    aPropSet(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_CURSOR)),
+    aLstnrCntnr( (XTextRange*)this),
+    pFrameFmt(&rFmt),
+    xParentText(xParent),
+    ePortionType(PORTION_FRAME),
+    pFmtFld(0),
+    aFrameDepend(this, &rFmt),
+    bIsCollapsed(FALSE),
+    nControlChar(0)
+{
+    SwUnoCrsr* pUnoCrsr = pPortionCrsr->GetDoc()->CreateUnoCrsr(*pPortionCrsr->GetPoint());
+    if(pPortionCrsr->HasMark())
+    {
+        pUnoCrsr->SetMark();
+        *pUnoCrsr->GetMark() = *pPortionCrsr->GetMark();
+    }
+    pUnoCrsr->Add(this);
+}
+
+/*-- 11.12.98 09:56:55---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextPortion::~SwXTextPortion()
+{
+}
+/*-- 11.12.98 09:56:56---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XText >  SwXTextPortion::getText(void) throw( uno::RuntimeException )
+{
+    return xParentText;
+}
+/*-- 11.12.98 09:56:56---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XTextRange >  SwXTextPortion::getStart(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< XTextRange >  xRet;
+    SwUnoCrsr* pUnoCrsr = ((SwXTextPortion*)this)->GetCrsr();
+    if(pUnoCrsr)
+    {
+        SwPaM aPam(*pUnoCrsr->Start());
+        uno::Reference< XText >  xParent = getText();
+        xRet = new SwXTextRange(aPam, xParent);
+    }
+    else
+        throw uno::RuntimeException();
+    return xRet;
+}
+/*-- 11.12.98 09:56:57---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XTextRange >  SwXTextPortion::getEnd(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< XTextRange >  xRet;
+    SwUnoCrsr* pUnoCrsr = ((SwXTextPortion*)this)->GetCrsr();
+    if(pUnoCrsr)
+    {
+        SwPaM aPam(*pUnoCrsr->End());
+        uno::Reference< XText >  xParent = getText();
+        xRet = new SwXTextRange(aPam, xParent);
+    }
+    else
+        throw uno::RuntimeException();
+    return xRet;
+}
+/*-- 11.12.98 09:56:57---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+OUString SwXTextPortion::getString(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    String aTxt;
+    SwUnoCrsr* pUnoCrsr = ((SwXTextPortion*)this)->GetCrsr();
+    if(pUnoCrsr)
+    {
+        //TextPortions liegen immer innerhalb eines Absatzes
+        SwTxtNode* pTxtNd = pUnoCrsr->GetNode()->GetTxtNode();
+        if( pTxtNd )
+        {
+            xub_StrLen nStt = pUnoCrsr->Start()->nContent.GetIndex();
+            aTxt = pTxtNd->GetExpandTxt( nStt,
+                    pUnoCrsr->End()->nContent.GetIndex() - nStt );
+        }
+    }
+    else
+        throw uno::RuntimeException();
+    return aTxt;
+}
+/*-- 11.12.98 09:56:57---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextPortion::setString(const OUString& aString) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwUnoCrsr* pUnoCrsr = ((SwXTextCursor*)this)->GetCrsr();
+    EXCEPT_ON_PROTECTION(*pUnoCrsr)
+    if(pUnoCrsr)
+        SwXTextCursor::SetString(*pUnoCrsr, aString);
+    else
+        throw uno::RuntimeException();
+}
+/*-- 11.12.98 09:56:57---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< beans::XPropertySetInfo >  SwXTextPortion::getPropertySetInfo(void) throw( uno::RuntimeException )
+{
+    static uno::Reference< beans::XPropertySetInfo >  xRef;
+    if(!xRef.is())
+    {
+        uno::Reference< beans::XPropertySetInfo >  xInfo = aPropSet.getPropertySetInfo();
+        // PropertySetInfo verlaengern!
+        const uno::Sequence aPropSeq = xInfo->getProperties();
+        xRef = new SfxExtItemPropertySetInfo(
+            aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXTPORTION_EXTENSIONS),
+            aPropSeq );
+    }
+    return xRef;
+
+}
+/*-- 11.12.98 09:56:57---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextPortion::setPropertyValue(const OUString& rPropertyName,
+    const uno::Any& aValue)
+    throw( beans::UnknownPropertyException,
+        beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwUnoCrsr* pUnoCrsr = ((SwXTextPortion*)this)->GetCrsr();
+    if(pUnoCrsr)
+    {
+        SwXTextCursor::SetPropertyValue(*pUnoCrsr, aPropSet, rPropertyName, aValue);
+    }
+    else
+        throw uno::RuntimeException();
+}
+/*-- 11.12.98 09:56:58---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXTextPortion::getPropertyValue(const OUString& rPropertyName) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Any aAny;
+    SwUnoCrsr* pUnoCrsr = ((SwXTextPortion*)this)->GetCrsr();
+    if(pUnoCrsr)
+    {
+        if(COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_TEXT_PORTION_TYPE))
+        {
+            OUString sRet;
+            switch (ePortionType)
+            {
+                case PORTION_TEXT:          sRet = C2U("Text");break;
+                case PORTION_FIELD:         sRet = C2U("TextField");break;
+                case PORTION_FRAME:         sRet = C2U("Frame");break;
+                case PORTION_FOOTNOTE:      sRet = C2U("Footnote");break;
+                case PORTION_CONTROL_CHAR:  sRet = C2U("ControlCharacter");break;
+                case PORTION_REFMARK_START:
+                case PORTION_REFMARK_END:       sRet = C2U(UNO_NAME_REFERENCE_MARK);break;
+                case PORTION_TOXMARK_START:
+                case PORTION_TOXMARK_END:       sRet = C2U(UNO_NAME_DOCUMENT_INDEX_MARK);break;
+                case PORTION_BOOKMARK_START :
+                case PORTION_BOOKMARK_END :  sRet = C2U(UNO_NAME_BOOKMARK);break;
+            }
+            aAny <<= sRet;
+        }
+        else if(COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_CONTROL_CHARACTER))
+        {
+            if(PORTION_CONTROL_CHAR == ePortionType)
+                aAny <<= (sal_Int16) nControlChar;
+        }
+        else if(COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_DOCUMENT_INDEX_MARK))
+            aAny <<= xTOXMark;
+        else if(COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_REFERENCE_MARK))
+            aAny <<= xRefMark;
+        else if(COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_BOOKMARK))
+            aAny <<= xBookmark;
+        else if(COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_FOOTNOTE))
+            aAny <<= xFootnote;
+        else if(COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_IS_COLLAPSED))
+        {
+            BOOL bStart = TRUE, bPut = TRUE;
+            switch (ePortionType)
+            {
+                case PORTION_REFMARK_START:
+                case PORTION_BOOKMARK_START :
+                case PORTION_TOXMARK_START:
+                case PORTION_REFMARK_END:
+                case PORTION_TOXMARK_END:
+                case PORTION_BOOKMARK_END :  ;
+                    aAny.setValue(&bIsCollapsed, ::getBooleanCppuType());
+                break;
+                default:
+                    bPut = FALSE;
+            }
+        }
+        else if(COMPARE_EQUAL == rPropertyName.compareToAscii(UNO_NAME_IS_START))
+        {
+            BOOL bStart = TRUE, bPut = TRUE;
+            switch (ePortionType)
+            {
+                case PORTION_REFMARK_START:
+                case PORTION_BOOKMARK_START :
+                case PORTION_TOXMARK_START:
+                break;
+                case PORTION_REFMARK_END:
+                case PORTION_TOXMARK_END:
+                case PORTION_BOOKMARK_END :  bStart = FALSE;
+                break;
+                default:
+                    bPut = FALSE;
+            }
+            if(bPut)
+                aAny.setValue(&bStart, ::getBooleanCppuType());
+        }
+        else
+            aAny = SwXTextCursor::GetPropertyValue(*pUnoCrsr, aPropSet, rPropertyName);
+    }
+    else
+        throw uno::RuntimeException();
+    return aAny;
+}
+/*-- 11.12.98 09:56:58---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextPortion::addPropertyChangeListener(const OUString& PropertyName, const uno::Reference< beans::XPropertyChangeListener > & aListener) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 11.12.98 09:56:58---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextPortion::removePropertyChangeListener(const OUString& PropertyName, const uno::Reference< beans::XPropertyChangeListener > & aListener) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 11.12.98 09:56:58---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextPortion::addVetoableChangeListener(const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener > & aListener) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 11.12.98 09:56:59---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextPortion::removeVetoableChangeListener(const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener > & aListener) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 08.03.99 09:41:43---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+beans::PropertyState SwXTextPortion::getPropertyState(const OUString& rPropertyName)
+            throw( beans::UnknownPropertyException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    beans::PropertyState eRet = beans::PropertyState_DEFAULT_VALUE;
+    SwUnoCrsr* pUnoCrsr = ((SwXTextPortion*)this)->GetCrsr();
+    if(pUnoCrsr)
+        eRet = SwXTextCursor::GetPropertyState(*pUnoCrsr, aPropSet, rPropertyName);
+    else
+        throw RuntimeException();
+    return eRet;
+}
+/*-- 08.03.99 09:41:47---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Sequence< beans::PropertyState > SwXTextPortion::getPropertyStates(
+        const uno::Sequence< OUString >& PropertyNames)
+        throw( beans::UnknownPropertyException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwUnoCrsr* pUnoCrsr = ((SwXTextPortion*)this)->GetCrsr();
+    if(!pUnoCrsr)
+        throw RuntimeException();
+    return SwXTextCursor::GetPropertyStates(*pUnoCrsr, aPropSet, PropertyNames);
+}
+/*-- 08.03.99 09:41:47---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextPortion::setPropertyToDefault(const OUString& rPropertyName)
+                throw( beans::UnknownPropertyException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        SwXTextCursor::SetPropertyToDefault(*pUnoCrsr, aPropSet, rPropertyName);
+    }
+    else
+        throw uno::RuntimeException();
+}
+/*-- 08.03.99 09:41:48---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXTextPortion::getPropertyDefault(const OUString& rPropertyName)
+        throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    uno::Any aRet;
+    SwUnoCrsr* pUnoCrsr = ((SwXTextPortion*)this)->GetCrsr();
+    if(pUnoCrsr)
+    {
+        aRet = SwXTextCursor::GetPropertyDefault(*pUnoCrsr, aPropSet, rPropertyName);
+    }
+    else
+        throw uno::RuntimeException();
+    return aRet;
+}
+/*-- 11.12.98 09:56:59---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+OUString SwXTextPortion::getPresentation(sal_Bool bShowCommand) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwUnoCrsr* pUnoCrsr = ((SwXTextPortion*)this)->GetCrsr();
+    String sRet;
+    SwFmtFld* pFmt = 0;
+    if(pUnoCrsr && 0 != (pFmt = GetFldFmt()))
+    {
+        const SwField* pField = pFmt->GetFld();
+        DBG_ERROR("bShowCommand auswerten!")
+        sRet = pField->Expand();
+    }
+    return sRet;
+}
+/*-- 11.12.98 09:56:59---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextPortion::attach(const uno::Reference< XTextRange > & xTextRange) throw( lang::IllegalArgumentException, uno::RuntimeException )
+{
+
+}
+/*-- 11.12.98 09:57:00---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XTextRange >  SwXTextPortion::getAnchor(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< XTextRange >  aRet;
+    SwUnoCrsr* pUnoCrsr = ((SwXTextPortion*)this)->GetCrsr();
+    if(pUnoCrsr)
+        aRet = new SwXTextRange(*pUnoCrsr, xParentText);
+    else
+        throw uno::RuntimeException();
+    return aRet;
+}
+/*-- 11.12.98 09:57:00---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextPortion::dispose(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwUnoCrsr* pUnoCrsr = ((SwXTextPortion*)this)->GetCrsr();
+    if(pUnoCrsr)
+    {
+        setString(aEmptyStr);
+        pUnoCrsr->Remove(this);
+    }
+    else
+        throw uno::RuntimeException();
+}
+/*-- 11.12.98 09:57:00---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextPortion::addEventListener(const uno::Reference< lang::XEventListener > & aListener) throw( uno::RuntimeException )
+{
+    if(!GetRegisteredIn())
+        throw uno::RuntimeException();
+    aLstnrCntnr.AddListener(aListener);
+}
+/*-- 11.12.98 09:57:01---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextPortion::removeEventListener(const uno::Reference< lang::XEventListener > & aListener) throw( uno::RuntimeException )
+{
+    if(!GetRegisteredIn() || !aLstnrCntnr.RemoveListener(aListener))
+        throw uno::RuntimeException();
+}
+/* -----------------24.03.99 13:30-------------------
+ *
+ * --------------------------------------------------*/
+uno::Reference< container::XEnumeration >  SwXTextPortion::createContentEnumeration(const OUString& aServiceName)
+        throw( uno::RuntimeException )
+{
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(!pUnoCrsr)
+        throw uno::RuntimeException();
+    uno::Reference< container::XEnumeration >  xRet = new SwXParaFrameEnumeration(*pUnoCrsr, PARAFRAME_PORTION_CHAR, pFrameFmt);
+    return xRet;
+
+}
+/* -----------------24.03.99 13:30-------------------
+ *
+ * --------------------------------------------------*/
+uno::Sequence< OUString > SwXTextPortion::getAvailableServiceNames(void) throw( uno::RuntimeException )
+{
+    uno::Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.TextContent");
+    return aRet;
+}
+/* -----------------25.03.99 10:30-------------------
+ *
+ * --------------------------------------------------*/
+OUString SwXTextPortion::getImplementationName(void) throw( uno::RuntimeException )
+{
+    return C2U("SwXTextPortion");
+}
+/* -----------------25.03.99 10:30-------------------
+ *
+ * --------------------------------------------------*/
+sal_Bool SwXTextPortion::supportsService(const OUString& rServiceName) throw( uno::RuntimeException )
+{
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(!pUnoCrsr)
+        throw uno::RuntimeException();
+
+    sal_Bool bRet = sal_False;
+    if(COMPARE_EQUAL == rServiceName.compareToAscii("com.sun.star.text.TextPortion"))
+        bRet = sal_True;
+    else if(COMPARE_EQUAL == rServiceName.compareToAscii("com.sun.star.text.TextField"))
+        bRet = 0 != GetFldFmt();
+    else
+    {
+        SwFrmFmt* pCurFrmFmt = pFrameFmt;
+        if(!pCurFrmFmt && !pUnoCrsr->HasMark() && pUnoCrsr->GetCntntNode()->Len())
+        {
+            // hier die zeichengebundenen am Cursor suchen - hier kann es nur einen geben
+            SwTxtAttr* pTxtAttr = pUnoCrsr->GetNode()->GetTxtNode()->GetTxtAttr(
+                            pUnoCrsr->GetPoint()->nContent, RES_TXTATR_FLYCNT);
+            DBG_ASSERT(pTxtAttr, "Hier muss doch ein Fly-Attribut zu finden sein!")
+            if(pTxtAttr)
+            {
+                const SwFmtFlyCnt& rFlyCnt = pTxtAttr->GetFlyCnt();
+                pCurFrmFmt = rFlyCnt.GetFrmFmt();
+            }
+        }
+        if(pCurFrmFmt)
+        {
+            const SwNodeIndex* pIdx = pCurFrmFmt->GetCntnt().GetCntntIdx();
+            const SwNode* pNd = GetCrsr()->GetDoc()->GetNodes()[ pIdx->GetIndex() + 1 ];
+
+            if((!pNd->IsNoTxtNode() && COMPARE_EQUAL == rServiceName.compareToAscii("com.sun.star.text.TextFrame"))||
+                (pNd->IsGrfNode() && COMPARE_EQUAL == rServiceName.compareToAscii("com.sun.star.text.TextGraphicObject")) ||
+                (pNd->IsOLENode() && COMPARE_EQUAL == rServiceName.compareToAscii("com.sun.star.text.TextEmbeddedObject")))
+                bRet = sal_True;
+        }
+    }
+    return bRet;
+}
+/* ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------*/
+uno::Sequence< OUString > SwXTextPortion::getSupportedServiceNames(void)
+                                                throw( uno::RuntimeException )
+{
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(!pUnoCrsr)
+        throw uno::RuntimeException();
+    sal_Bool bField = 0 != GetFldFmt();
+    sal_uInt16 nCount = bField ? 2 : 1;
+    uno::Sequence< OUString > aRet(nCount);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.TextPortion");
+    if(bField)
+        pArray[1] = C2U("com.sun.star.text.TextField");
+    else
+    {
+        SwFrmFmt* pCurFrmFmt = pFrameFmt;
+        if(!pCurFrmFmt && !pUnoCrsr->HasMark())
+        {
+            // hier die zeichengebundenen am Cursor suchen - hier kann es nur einen geben
+            SwTxtAttr* pTxtAttr = pUnoCrsr->GetNode()->GetTxtNode()->GetTxtAttr(
+                            pUnoCrsr->GetPoint()->nContent, RES_TXTATR_FLYCNT);
+            // if any - it could also be an empty paragraph
+            if(pTxtAttr)
+            {
+                const SwFmtFlyCnt& rFlyCnt = pTxtAttr->GetFlyCnt();
+                pCurFrmFmt = rFlyCnt.GetFrmFmt();
+            }
+        }
+        if(pCurFrmFmt)
+        {
+            aRet.realloc(2);
+            pArray = aRet.getArray();
+            const SwNodeIndex* pIdx = pCurFrmFmt->GetCntnt().GetCntntIdx();
+            const SwNode* pNd = GetCrsr()->GetDoc()->GetNodes()[ pIdx->GetIndex() + 1 ];
+            if(!pNd->IsNoTxtNode())
+                pArray[1] = C2U("com.sun.star.text.TextFrame");
+            else if(pNd->IsGrfNode())
+                pArray[1] = C2U("com.sun.star.text.TextGraphicObject");
+            else
+                pArray[1] = C2U("com.sun.star.text.TextEmbeddedObject");
+        }
+    }
+    return aRet;
+}
+/*-- 11.12.98 09:57:01---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextPortion::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew)
+{
+    ClientModify(this, pOld, pNew);
+    if(!aFrameDepend.GetRegisteredIn())
+        pFrameFmt = 0;
+}
+/*------------------------------------------------------------------------
+
+    $Log: not supported by cvs2svn $
+    Revision 1.6  2000/09/18 16:04:34  willem.vandorp
+    OpenOffice header added.
+
+    Revision 1.5  2000/09/07 07:57:19  os
+    new properties: IsCollapsed, IsStart
+
+    Revision 1.4  2000/09/05 15:20:12  os
+    footnote property at SwTextPortion
+
+    Revision 1.3  2000/09/04 12:50:47  os
+    TextPortionEnumeration almost completed
+
+    Revision 1.2  2000/09/01 14:31:57  os
+    properties added
+
+    Revision 1.1  2000/05/04 15:14:08  os
+    reduce size of unoobj.cxx
+
+
+------------------------------------------------------------------------*/
+
+
diff --git a/sw/source/core/unocore/unoprnms.cxx b/sw/source/core/unocore/unoprnms.cxx
new file mode 100644
index 000000000000..ed2bc313a5d9
--- /dev/null
+++ b/sw/source/core/unocore/unoprnms.cxx
@@ -0,0 +1,529 @@
+/*************************************************************************
+ *
+ *  $RCSfile: unoprnms.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:28 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#pragma hdrstop
+
+#ifndef _UNOPRNMS_HXX
+#include 
+#endif
+
+#ifndef _SFX_ITEMPROP_HXX
+#include 
+#endif
+
+//#define MAP_CHAR_LEN(cchar) cchar, sizeof(cchar) - 1
+
+//struct SwPropNameLen
+//{
+//  const char*                         pName;
+//  USHORT                              nNameLen;
+//};
+
+//extern const SwPropNameLen                UNO_NAME_FOLLOW_STYLE;
+const SwPropNameLen __FAR_DATA  UNO_NAME_FOLLOW_STYLE(MAP_CHAR_LEN("FollowStyle"));
+
+
+const SwPropNameLen __FAR_DATA  UNO_NAME_IS_PHYSICAL                            (MAP_CHAR_LEN("IsPhysical"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_IS_AUTO_UPDATE                         (MAP_CHAR_LEN("IsAutoUpdate"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_DISPLAY_NAME                           (MAP_CHAR_LEN("DisplayName"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHAR_FONT_NAME                         (MAP_CHAR_LEN("CharFontName"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHAR_FONT_STYLE_NAME                   (MAP_CHAR_LEN("CharFontStyleName"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHAR_FONT_FAMILY                       (MAP_CHAR_LEN("CharFontFamily"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHAR_FONT_CHAR_SET                     (MAP_CHAR_LEN("CharFontCharSet"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHAR_FONT_PITCH                        (MAP_CHAR_LEN("CharFontPitch"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_GRAPHIC_URL                       (MAP_CHAR_LEN("ParaBackGraphicURL"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_GRAPHIC_FILTER                    (MAP_CHAR_LEN("ParaBackGraphicFilter"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_HEADER_GRAPHIC_URL                     (MAP_CHAR_LEN("HeaderBackGraphicURL"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_HEADER_GRAPHIC_FILTER                  (MAP_CHAR_LEN("HeaderBackGraphicFilter"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FOOTER_GRAPHIC_URL                     (MAP_CHAR_LEN("FooterBackGraphicURL"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FOOTER_GRAPHIC_FILTER                  (MAP_CHAR_LEN("FooterBackGraphicFilter"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_BACK_GRAPHIC_URL                       (MAP_CHAR_LEN("BackGraphicURL"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_BACK_GRAPHIC_FILTER                    (MAP_CHAR_LEN("BackGraphicFilter"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_BACK_GRAPHIC_LOCATION                  (MAP_CHAR_LEN("BackGraphicLocation"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_BACK_GRAPHIC_BITMAP                    (MAP_CHAR_LEN("BackGraphicBitmap"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_GRAPHIC_URL                            (MAP_CHAR_LEN("GraphicURL"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_GRAPHIC_FILTER                         (MAP_CHAR_LEN("GraphicFilter"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_GRAPHIC_LOCATION                       (MAP_CHAR_LEN("GraphicLocation"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_GRAPHIC_SIZE                           (MAP_CHAR_LEN("GraphicSize"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_GRAPHIC_BITMAP                         (MAP_CHAR_LEN("GraphicBitmap"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_BULLET_FONT                            (MAP_CHAR_LEN("BulletFont"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_GRAPHIC_LOCATION                  (MAP_CHAR_LEN("ParaBackGraphicLocation"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_HEADER_GRAPHIC_LOCATION                (MAP_CHAR_LEN("HeaderBackGraphicLocation"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FOOTER_GRAPHIC_LOCATION                (MAP_CHAR_LEN("FooterBackGraphicLocation"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_LEFT_PARA_MARGIN                  (MAP_CHAR_LEN("ParaLeftParaMargin"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_RIGHT_PARA_MARGIN                 (MAP_CHAR_LEN("ParaRightParaMargin"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_LEFT_MARGIN                       (MAP_CHAR_LEN("ParaLeftMargin"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_RIGHT_MARGIN                      (MAP_CHAR_LEN("ParaRightMargin"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_LEFT_MARGIN_RELATIVE              (MAP_CHAR_LEN("ParaLeftMarginRelative"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_RIGHT_MARGIN_RELATIVE             (MAP_CHAR_LEN("ParaRightMarginRelative"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_FIRST_LINE_INDENT                 (MAP_CHAR_LEN("ParaFirstLineIndent"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_FIRST_LINE_INDENT_RELATIVE        (MAP_CHAR_LEN("ParaFirstLineIndentRelative"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_IS_HYPHENATION                    (MAP_CHAR_LEN("ParaIsHyphenation"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_HYPHENATION_MAX_LEADING_CHARS     (MAP_CHAR_LEN("HyphenationMaxLeadingChars"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_HYPHENATION_MAX_TRAILING_CHARS    (MAP_CHAR_LEN("HyphenationMaxTrailingChars"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_HYPHENATION_MAX_HYPHENS           (MAP_CHAR_LEN("HyphenationMaxHyphens"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_LEFT_MARGIN                            (MAP_CHAR_LEN("LeftMargin"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_RIGHT_MARGIN                           (MAP_CHAR_LEN("RightMargin"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_HEADER_LEFT_MARGIN                     (MAP_CHAR_LEN("HeaderLeftMargin"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_HEADER_RIGHT_MARGIN                    (MAP_CHAR_LEN("HeaderRightMargin"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FOOTER_LEFT_MARGIN                     (MAP_CHAR_LEN("FooterLeftMargin"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FOOTER_RIGHT_MARGIN                    (MAP_CHAR_LEN("FooterRightMargin"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_TEXT_RANGE                             (MAP_CHAR_LEN("TextRange"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_NAME                                   (MAP_CHAR_LEN("Name"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_NUMBERING_ALIGNMENT                    (MAP_CHAR_LEN("NumberingAlignment"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_BULLET_FONT_NAME                       (MAP_CHAR_LEN("BulletFontName"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_BULLET_ID                              (MAP_CHAR_LEN("BulletId"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHAR_STYLE_NAME                        (MAP_CHAR_LEN("CharStyleName"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_ANCHOR_CHAR_STYLE_NAME                 (MAP_CHAR_LEN("AnchorCharStyleName"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SUFFIX                                 (MAP_CHAR_LEN("Suffix"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PREFIX                                 (MAP_CHAR_LEN("Prefix"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARENT_NUMBERING                       (MAP_CHAR_LEN("ParentNumbering"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_START_WITH                             (MAP_CHAR_LEN("StartWith"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHAR_POSTURE                           (MAP_CHAR_LEN("CharPosture"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHAR_WEIGHT                            (MAP_CHAR_LEN("CharWeight"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHAR_AUTO_KERNING                      (MAP_CHAR_LEN("CharAutoKerning"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHAR_UNDERLINE                         (MAP_CHAR_LEN("CharUnderline"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHAR_ESCAPEMENT                        (MAP_CHAR_LEN("CharEscapement"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHAR_CASE_MAP                          (MAP_CHAR_LEN("CharCaseMap"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHAR_SHADOWED                          (MAP_CHAR_LEN("CharShadowed"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHAR_STRIKEOUT                         (MAP_CHAR_LEN("CharStrikeout"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHAR_CROSSED_OUT                       (MAP_CHAR_LEN("CharCrossedOut"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHAR_NO_HYPHENATION                    (MAP_CHAR_LEN("CharNoHyphenation"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHAR_AUTO_ESCAPEMENT                   (MAP_CHAR_LEN("CharAutoEscapement"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHAR_HEIGHT                            (MAP_CHAR_LEN("CharHeight"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHAR_PROP_FONT_HEIGHT                  (MAP_CHAR_LEN("CharPropFontHeight"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHAR_DIFF_FONT_HEIGHT                  (MAP_CHAR_LEN("CharDiffFontHeight"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHAR_ESCAPEMENT_HEIGHT                 (MAP_CHAR_LEN("CharEscapementHeight"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHAR_COLOR                             (MAP_CHAR_LEN("CharColor"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHAR_FLASH                             (MAP_CHAR_LEN("CharFlash"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHAR_KERNING                           (MAP_CHAR_LEN("CharKerning"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHAR_LOCALE                            (MAP_CHAR_LEN("CharLocale"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHAR_BACK_COLOR                        (MAP_CHAR_LEN("CharBackColor"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHAR_TRANSPARENT_BACKGROUND            (MAP_CHAR_LEN("CharBackTransparent"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_LINE_SPACING                      (MAP_CHAR_LEN("ParaLineSpacing"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_TOP_MARGIN                        (MAP_CHAR_LEN("ParaTopMargin"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_BOTTOM_MARGIN                     (MAP_CHAR_LEN("ParaBottomMargin"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_TOP_MARGIN_RELATIVE               (MAP_CHAR_LEN("ParaTopMarginRelative"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_BOTTOM_MARGIN_RELATIVE            (MAP_CHAR_LEN("ParaBottomMarginRelative"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_EXPAND_SINGLE_WORD                (MAP_CHAR_LEN("ParaExpandSingleWord"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_END_NOTICE                             (MAP_CHAR_LEN("EndNotice"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_EMBEDDED_OBJECTS                       (MAP_CHAR_LEN("EmbeddedObjects"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_ALPHABETICAL_SEPARATORS                (MAP_CHAR_LEN("AlphabeticalSeparators"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_BACKGROUND_COLOR                       (MAP_CHAR_LEN("BackgroundColor"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_BEGIN_NOTICE                           (MAP_CHAR_LEN("BeginNotice"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CASE_SENSITIVE                         (MAP_CHAR_LEN("CaseSensitive"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FRAME_STYLE_NAME                       (MAP_CHAR_LEN("FrameStyleName"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_NUMBERING_STYLE_NAME                   (MAP_CHAR_LEN("NumberingStyleName"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_NUMBERING_LEVEL                        (MAP_CHAR_LEN("NumberingLevel"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_NUMBERING_START_VALUE                  (MAP_CHAR_LEN("NumberingStartValue"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_NUMBERING_IS_NUMBER                    (MAP_CHAR_LEN("NumberingIsNumber"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_COMBINE_ENTRIES                        (MAP_CHAR_LEN("CombineEntries"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_COUNT_LINES_IN_FRAMES                  (MAP_CHAR_LEN("CountLinesInFrames"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_DDE_COMMAND_TYPE                       (MAP_CHAR_LEN("DDECommandType"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_DDE_COMMAND_FILE                       (MAP_CHAR_LEN("DDECommandFile"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_DDE_COMMAND_ELEMENT                    (MAP_CHAR_LEN("DDECommandElement"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_IS_AUTOMATIC_UPDATE                    (MAP_CHAR_LEN("IsAutomaticUpdate"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_DEFAULT_TABSTOP_DISTANCE               (MAP_CHAR_LEN("DefaultTabstopDistance"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_DISTANCE                               (MAP_CHAR_LEN("Distance"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_DROP_CAP_FORMAT                        (MAP_CHAR_LEN("DropCapFormat"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_DROP_CAP_WHOLE_WORD                    (MAP_CHAR_LEN("DropCapWholeWord"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_DROP_CAP_CHAR_STYLE_NAME               (MAP_CHAR_LEN("DropCapCharStyleName"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FILE_LINK                              (MAP_CHAR_LEN("FileLink"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_GRAPHIC                                (MAP_CHAR_LEN("Graphic"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_GRAPHICS                               (MAP_CHAR_LEN("Graphics"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_IS_PROTECTED                           (MAP_CHAR_LEN("IsProtected"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_KEY_AS_ENTRY                           (MAP_CHAR_LEN("KeyAsEntry"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_KEEP_TOGETHER                     (MAP_CHAR_LEN("ParaKeepTogether"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_KEEP_TOGETHER                          (MAP_CHAR_LEN("KeepTogether"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_LANDSCAPE                              (MAP_CHAR_LEN("Landscape"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_LINE_SEPARATOR                         (MAP_CHAR_LEN("LineSeparator"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_MARKS                                  (MAP_CHAR_LEN("Marks"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_NUMBER_POSITION                        (MAP_CHAR_LEN("NumberPosition"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_OUTLINES                               (MAP_CHAR_LEN("Outlines"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PAGE_STYLE_NAME                        (MAP_CHAR_LEN("PageStyleName"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PAGE_STYLE_LAYOUT                      (MAP_CHAR_LEN("PageStyleLayout"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_STYLES                            (MAP_CHAR_LEN("ParaStyles"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_ADJUST                            (MAP_CHAR_LEN("ParaAdjust"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_REGISTER_MODE_ACTIVE              (MAP_CHAR_LEN("ParaRegisterModeActive"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_STYLE_NAME                        (MAP_CHAR_LEN("ParaStyleName"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_LAST_LINE_ADJUST                  (MAP_CHAR_LEN("ParaLastLineAdjust"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_LINE_NUMBER_COUNT                 (MAP_CHAR_LEN("ParaLineNumberCount"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_LINE_NUMBER_START_VALUE           (MAP_CHAR_LEN("ParaLineNumberStartValue"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_BACK_COLOR                             (MAP_CHAR_LEN("BackColor"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_BACK_COLOR                        (MAP_CHAR_LEN("ParaBackColor"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_WIDOWS                            (MAP_CHAR_LEN("ParaWidows"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_ORPHANS                           (MAP_CHAR_LEN("ParaOrphans"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_TRANSPARENT_BACKGROUND            (MAP_CHAR_LEN("ParaBackTransparent"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_POSITION_END_OF_DOC                    (MAP_CHAR_LEN("PositionEndOfDoc"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_POSITION_PROTECTED                     (MAP_CHAR_LEN("PositionProtected"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_ALTERNATIVE_TEXT                       (MAP_CHAR_LEN("AlternativeText"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PRIMARY_KEY                            (MAP_CHAR_LEN("PrimaryKey"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PRINT_TABLES                           (MAP_CHAR_LEN("PrintTables"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PRINT_GRAPHICS                         (MAP_CHAR_LEN("PrintGraphics"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PRINT_REVERSED                         (MAP_CHAR_LEN("PrintReversed"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PRINT_PROSPECT                         (MAP_CHAR_LEN("PrintProspect"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PRINT_CONTROLS                         (MAP_CHAR_LEN("PrintControls"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PRINT_DRAWINGS                         (MAP_CHAR_LEN("PrintDrawings"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PRING_RIGHT_PAGES                      (MAP_CHAR_LEN("PrintRightPages"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PRINT_BLACK_FONTS                      (MAP_CHAR_LEN("PrintBlackFonts"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PRINTER_PAPER_TRAY                     (MAP_CHAR_LEN("PrinterPaperTray"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PRINT_PAGE_BACKGROUND                  (MAP_CHAR_LEN("PrintPageBackground"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PRINT_ANNOTATION_MODE                  (MAP_CHAR_LEN("PrintAnnotationMode"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_REGISTER_MODE_ACTIVE                   (MAP_CHAR_LEN("RegisterModeActive"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_RELATIVE_WIDTH                         (MAP_CHAR_LEN("RelativeWidth"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_RELATIVE_HEIGHT                        (MAP_CHAR_LEN("RelativeHeight"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_REPEAT_HEADLINE                        (MAP_CHAR_LEN("RepeatHeadline"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SEARCH_STYLES                          (MAP_CHAR_LEN("SearchStyles"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SEARCH_BACKWARDS                       (MAP_CHAR_LEN("SearchBackwards"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SEARCH_SIMILARITY                      (MAP_CHAR_LEN("SearchSimilarity"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SEARCH_IN_SELECTION                    (MAP_CHAR_LEN("SearchInSelection"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SEARCH_CASE_SENSITIVE                  (MAP_CHAR_LEN("SearchCaseSensitive"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SEARCH_SIMILARITY_ADD                  (MAP_CHAR_LEN("SearchSimilarityAdd"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SEARCH_SIMILARITY_RELAX                (MAP_CHAR_LEN("SearchSimilarityRelax"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SEARCH_SIMILARITY_REMOVE               (MAP_CHAR_LEN("SearchSimilarityRemove"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SEARCH_REGULAR_EXPRESSION              (MAP_CHAR_LEN("SearchRegularExpression"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SEARCH_SIMILARITY_EXCHANGE             (MAP_CHAR_LEN("SearchSimilarityExchange"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SECONDARY_KEY                          (MAP_CHAR_LEN("SecondaryKey"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SEPARATOR_LINE_DISTANCE                (MAP_CHAR_LEN("SeparatorLineDistance"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SHOW_BREAKS                            (MAP_CHAR_LEN("ShowBreaks"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SHOW_SPACES                            (MAP_CHAR_LEN("ShowSpaces"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SHOW_TABLES                            (MAP_CHAR_LEN("ShowTables"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SHOW_GRAPHICS                          (MAP_CHAR_LEN("ShowGraphics"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SHOW_DRAWINGS                          (MAP_CHAR_LEN("ShowDrawings"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SHOW_TABSTOPS                          (MAP_CHAR_LEN("ShowTabstops"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SHOW_VERT_RULER                        (MAP_CHAR_LEN("ShowVertRuler"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SHOW_PARA_BREAKS                       (MAP_CHAR_LEN("ShowParaBreaks"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SHOW_HIDDEN_TEXT                       (MAP_CHAR_LEN("ShowHiddenText"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SHOW_ANNOTATIONS                       (MAP_CHAR_LEN("ShowAnnotations"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SHOW_SOFT_HYPHENS                      (MAP_CHAR_LEN("ShowSoftHyphens"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SHOW_VERT_SCROLL_BAR                   (MAP_CHAR_LEN("ShowVertScrollBar"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SHOW_HORI_SCROLL_BAR                   (MAP_CHAR_LEN("ShowHoriScrollBar"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SHOW_FIELD_COMMANDS                    (MAP_CHAR_LEN("ShowFieldCommands"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SHOW_TEXT_BOUNDARIES                   (MAP_CHAR_LEN("ShowTextBoundaries"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SHOW_PROTECTED_SPACES                  (MAP_CHAR_LEN("ShowProtectedSpaces"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SHOW_TABLE_BOUNDARIES                  (MAP_CHAR_LEN("ShowTableBoundaries"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SHOW_HIDDEN_PARAGRAPHS                 (MAP_CHAR_LEN("ShowHiddenParagraphs"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SHOW_INDEX_MARK_BACKGROUND             (MAP_CHAR_LEN("ShowIndexMarkBacground"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SHOW_FOOTNOTE_BACKGROUND               (MAP_CHAR_LEN("ShowFootnoteBackground"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SHOW_TEXT_FIELD_BACKGROUND             (MAP_CHAR_LEN("ShowTextFieldBackground"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SIZE_RELATIVE                          (MAP_CHAR_LEN("SizeRelative"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SIZE_PROTECTED                         (MAP_CHAR_LEN("SizeProtected"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SMOOTH_SCROLLING                       (MAP_CHAR_LEN("SmoothScrolling"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SOLID_MARK_HANDLES                     (MAP_CHAR_LEN("SolidMarkHandles"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_TABLES                                 (MAP_CHAR_LEN("Tables"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_TEXT_FRAMES                            (MAP_CHAR_LEN("TextFrames"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_TEXT_COLUMNS                           (MAP_CHAR_LEN("TextColumns"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_TRANSPARENT_BACKGROUND                 (MAP_CHAR_LEN("BackTransparent"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_USE_PP                                 (MAP_CHAR_LEN("UsePP"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_USER_METRIC                            (MAP_CHAR_LEN("UserMetric"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_ANCHOR_TYPE                            (MAP_CHAR_LEN("AnchorType"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_ANCHOR_TYPES                           (MAP_CHAR_LEN("AnchorTypes"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_ANCHOR_PAGE_NO                         (MAP_CHAR_LEN("AnchorPageNo"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_AUTHOR                                 (MAP_CHAR_LEN("Author"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_BREAK_TYPE                             (MAP_CHAR_LEN("BreakType"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHAIN_NEXT_NAME                        (MAP_CHAR_LEN("ChainNextName"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHAIN_PREV_NAME                        (MAP_CHAR_LEN("ChainPrevName"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHAPTER_FORMAT                         (MAP_CHAR_LEN("ChapterFormat"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CLIENT_MAP                             (MAP_CHAR_LEN("ClientMap"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CONDITION                              (MAP_CHAR_LEN("Condition"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CONTENT                                (MAP_CHAR_LEN("Content"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHAR_CONTOURED                         (MAP_CHAR_LEN("CharContoured"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CONTOUR_OUTSIDE                        (MAP_CHAR_LEN("ContourOutside"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CONTENT_PROTECTED                      (MAP_CHAR_LEN("ContentProtected"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_COUNT_EMPTY_LINES                      (MAP_CHAR_LEN("CountEmptyLines"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_DATA_BASE_NAME                         (MAP_CHAR_LEN("DataBaseName"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_DATA_TABLE_NAME                        (MAP_CHAR_LEN("DataTableName"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_DATA_COLUMN_NAME                       (MAP_CHAR_LEN("DataColumnName"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_IS_DATA_BASE_FORMAT                    (MAP_CHAR_LEN("DataBaseFormat"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_DATE                                   (MAP_CHAR_LEN("Date"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_DATETIME                               (MAP_CHAR_LEN("DateTimeValue"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_IS_DATE                                (MAP_CHAR_LEN("IsDate"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_EDIT_IN_READONLY                       (MAP_CHAR_LEN("EditInReadonly"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FALSE_CONTENT                          (MAP_CHAR_LEN("FalseContent"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FILE_FORMAT                            (MAP_CHAR_LEN("FileFormat"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_IS_FIXED                               (MAP_CHAR_LEN("IsFixed"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FOOTNOTE_COUNTING                      (MAP_CHAR_LEN("FootnoteCounting"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FORMULA                                (MAP_CHAR_LEN("Formula"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FRAME_NAME                             (MAP_CHAR_LEN("FrameName"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_GRAPHIC_NAME                           (MAP_CHAR_LEN("GraphicName"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FULL_NAME                              (MAP_CHAR_LEN("FullName"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_HEIGHT                                 (MAP_CHAR_LEN("Height"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_IS_AUTO_HEIGHT                         (MAP_CHAR_LEN("IsAutoHeight"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SIZE_TYPE                              (MAP_CHAR_LEN("SizeType"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_HINT                                   (MAP_CHAR_LEN("Hint"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_HORI_ORIENT                            (MAP_CHAR_LEN("HoriOrient"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_HORI_MIRRORED                          (MAP_CHAR_LEN("HoriMirrored"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_HORI_ORIENT_RELATION                   (MAP_CHAR_LEN("HoriOrientRelation"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_HORI_ORIENT_POSITION                   (MAP_CHAR_LEN("HoriOrientPosition"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_HYPER_LINK_U_R_L                       (MAP_CHAR_LEN("HyperLinkURL"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_HYPER_LINK_TARGET                      (MAP_CHAR_LEN("HyperLinkTarget"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_HYPER_LINK_NAME                        (MAP_CHAR_LEN("HyperLinkName"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_INFO_TYPE                              (MAP_CHAR_LEN("InfoType"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_INFO_FORMAT                            (MAP_CHAR_LEN("InfoFormat"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_IS_INPUT                               (MAP_CHAR_LEN("Input"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_LEVEL                                  (MAP_CHAR_LEN("Level"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_LINE_INTERVAL                          (MAP_CHAR_LEN("LineInterval"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_LINK_REGION                            (MAP_CHAR_LEN("LinkRegion"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_MACRO                                  (MAP_CHAR_LEN("Macro"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_MIRROR_PAGE_TOGGLE                     (MAP_CHAR_LEN("MirrorPageToggle"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SPLIT                                  (MAP_CHAR_LEN("Split"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_SPLIT                             (MAP_CHAR_LEN("ParaSplit"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_NUMBER_FORMAT                          (MAP_CHAR_LEN("NumberFormat"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_NUMBERING_TYPE                         (MAP_CHAR_LEN("NumberingType"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_NUMBERING_RULES                        (MAP_CHAR_LEN("NumberingRules"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_OFFSET                                 (MAP_CHAR_LEN("Offset"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_ON                                     (MAP_CHAR_LEN("On"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_OPAQUE                                 (MAP_CHAR_LEN("Opaque"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PAGE_TOGGLE                            (MAP_CHAR_LEN("PageToggle"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PAGE_DESC_NAME                         (MAP_CHAR_LEN("PageDescName"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PAGE_NUMBER_OFFSET                     (MAP_CHAR_LEN("PageNumberOffset"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PLACEHOLDER                            (MAP_CHAR_LEN("PlaceHolder"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PLACEHOLDER_TYPE                       (MAP_CHAR_LEN("PlaceHolderType"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PRINT                                  (MAP_CHAR_LEN("Print"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PRINT_LEFT_PAGES                       (MAP_CHAR_LEN("PrintLeftPages"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_REFERENCE_FIELD_PART                   (MAP_CHAR_LEN("ReferenceFieldPart"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_REFERENCE_FIELD_SOURCE                 (MAP_CHAR_LEN("ReferenceFieldSource"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_REGISTER_PARAGRAPH_STYLE               (MAP_CHAR_LEN("RegisterParagraphStyle"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SCRIPT_TYPE                            (MAP_CHAR_LEN("ScriptType"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SEARCH_ALL                             (MAP_CHAR_LEN("SearchAll"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SEARCH_WORDS                           (MAP_CHAR_LEN("SearchWords"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SEQUENCE_VALUE                         (MAP_CHAR_LEN("SequenceValue"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SERVER_MAP                             (MAP_CHAR_LEN("ServerMap"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SET_NUMBER                             (MAP_CHAR_LEN("SetNumber"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SHADOW_FORMAT                          (MAP_CHAR_LEN("ShadowFormat"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SHOW_HORI_RULER                        (MAP_CHAR_LEN("ShowHoriRuler"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SIZE                                   (MAP_CHAR_LEN("Size"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_ACTUAL_SIZE                            (MAP_CHAR_LEN("ActualSize"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SOURCE_NAME                            (MAP_CHAR_LEN("SourceName"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_START_AT                               (MAP_CHAR_LEN("StartAt"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_STATISTIC_TYPE_ID                      (MAP_CHAR_LEN("StatisticTypeId"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SUB_TYPE                               (MAP_CHAR_LEN("SubType"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SURROUND                               (MAP_CHAR_LEN("Surround"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_IS_EXPRESSION                          (MAP_CHAR_LEN("IsExpression"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_IS_SHOW_FORMULA                        (MAP_CHAR_LEN("IsShowFormula"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_TEXT_WRAP                              (MAP_CHAR_LEN("TextWrap"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SURROUND_CONTOUR                       (MAP_CHAR_LEN("SurroundContour"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SURROUND_ANCHORONLY                    (MAP_CHAR_LEN("SurroundAnchorOnly"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_TABLE_NAME                             (MAP_CHAR_LEN("TableName"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_TABSTOPS                               (MAP_CHAR_LEN("ParaTabStops"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_TITLE                                  (MAP_CHAR_LEN("Title"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_TOP_MARGIN                             (MAP_CHAR_LEN("TopMargin"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_BOTTOM_MARGIN                          (MAP_CHAR_LEN("BottomMargin"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_TRUE_CONTENT                           (MAP_CHAR_LEN("TrueContent"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_URL_CONTENT                            (MAP_CHAR_LEN("URLContent"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_USERTEXT                               (MAP_CHAR_LEN("UserText"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_USER_DATA_TYPE                         (MAP_CHAR_LEN("UserDataType"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_VALUE                                  (MAP_CHAR_LEN("Value"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_VARIABLE_NAME                          (MAP_CHAR_LEN("VariableName"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_VARIABLE_SUBTYPE                       (MAP_CHAR_LEN("VariableSubtype"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_VERT_ORIENT                            (MAP_CHAR_LEN("VertOrient"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_VERT_MIRRORED                          (MAP_CHAR_LEN("VertMirrored"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_VERT_ORIENT_POSITION                   (MAP_CHAR_LEN("VertOrientPosition"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_VERT_ORIENT_RELATION                   (MAP_CHAR_LEN("VertOrientRelation"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_IS_VISIBLE                             (MAP_CHAR_LEN("IsVisible"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_WIDTH                                  (MAP_CHAR_LEN("Width"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_WORD_MODE                              (MAP_CHAR_LEN("CharWordMode"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_GRAPHIC_CROP                           (MAP_CHAR_LEN("GraphicCrop"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHARACTER_FORMAT_NONE                  (MAP_CHAR_LEN("CharacterFormatNone"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_TEXT_POSITION                          (MAP_CHAR_LEN("TextPosition"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_DOCUMENT_INDEX_MARK                    (MAP_CHAR_LEN("DocumentIndexMark"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_DOCUMENT_INDEX                         (MAP_CHAR_LEN("DocumentIndex"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_TEXT_FIELD                             (MAP_CHAR_LEN("TextField"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_BOOKMARK                               (MAP_CHAR_LEN("Bookmark"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_TEXT_TABLE                             (MAP_CHAR_LEN("TextTable"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CELL                                   (MAP_CHAR_LEN("Cell"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_TEXT_FRAME                             (MAP_CHAR_LEN("TextFrame"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_REFERENCE_MARK                         (MAP_CHAR_LEN("ReferenceMark"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_TEXT_SECTION                           (MAP_CHAR_LEN("TextSection"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FOOTNOTE                               (MAP_CHAR_LEN("Footnote"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_ENDNOTE                                (MAP_CHAR_LEN("Endnote"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHART_ROW_AS_LABEL                     (MAP_CHAR_LEN("ChartRowAsLabel"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHART_COLUMN_AS_LABEL                  (MAP_CHAR_LEN("ChartColumnAsLabel"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_TABLE_COLUMS                           (MAP_CHAR_LEN("TableColumns"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_LEFT_BORDER                            (MAP_CHAR_LEN("LeftBorder"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_RIGHT_BORDER                           (MAP_CHAR_LEN("RightBorder"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_TOP_BORDER                             (MAP_CHAR_LEN("TopBorder"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_BOTTOM_BORDER                          (MAP_CHAR_LEN("BottomBorder"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_BORDER_DISTANCE                        (MAP_CHAR_LEN("BorderDistance"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_LEFT_BORDER_DISTANCE                   (MAP_CHAR_LEN("LeftBorderDistance"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_RIGHT_BORDER_DISTANCE                  (MAP_CHAR_LEN("RightBorderDistance"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_TOP_BORDER_DISTANCE                    (MAP_CHAR_LEN("TopBorderDistance"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_BOTTOM_BORDER_DISTANCE                 (MAP_CHAR_LEN("BottomBorderDistance"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_TABLE_BORDER                           (MAP_CHAR_LEN("TableBorder"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_TABLE_COLUMN_SEPARATORS                (MAP_CHAR_LEN("TableColumnSeparators"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_TABLE_COLUMN_RELATIVE_SUM              (MAP_CHAR_LEN("TableColumnRelativeSum"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_HEADER_TEXT                            (MAP_CHAR_LEN("HeaderText"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_HEADER_TEXT_LEFT                       (MAP_CHAR_LEN("HeaderTextLeft"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_HEADER_TEXT_RIGHT                      (MAP_CHAR_LEN("HeaderTextRight"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FOOTER_TEXT                            (MAP_CHAR_LEN("FooterText"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FOOTER_TEXT_LEFT                       (MAP_CHAR_LEN("FooterTextLeft"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FOOTER_TEXT_RIGHT                      (MAP_CHAR_LEN("FooterTextRight"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_HEADER_BACK_COLOR                      (MAP_CHAR_LEN("HeaderBackColor"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_HEADER_GRAPHIC                         (MAP_CHAR_LEN("HeaderBackGraphic"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_HEADER_TRANSPARENT_BACKGROUND          (MAP_CHAR_LEN("HeaderBackTransparent"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_HEADER_LEFT_BORDER                     (MAP_CHAR_LEN("HeaderLeftBorder"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_HEADER_RIGHT_BORDER                    (MAP_CHAR_LEN("HeaderRightBorder"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_HEADER_TOP_BORDER                      (MAP_CHAR_LEN("HeaderTopBorder"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_HEADER_BOTTOM_BORDER                   (MAP_CHAR_LEN("HeaderBottomBorder"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_HEADER_BORDER_DISTANCE                 (MAP_CHAR_LEN("HeaderBorderDistance"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_HEADER_SHADOW_FORMAT                   (MAP_CHAR_LEN("HeaderShadowFormat"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_HEADER_BODY_DISTANCE                   (MAP_CHAR_LEN("HeaderBodyDistance"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_HEADER_IS_DYNAMIC_DISTANCE             (MAP_CHAR_LEN("HeaderIsDynamicDistance"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_HEADER_SHARE_CONTENT                   (MAP_CHAR_LEN("HeaderShareContent"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_HEADER_HEIGHT                          (MAP_CHAR_LEN("HeaderHeight"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_HEADER_ON                              (MAP_CHAR_LEN("HeaderOn"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FOOTER_BACK_COLOR                      (MAP_CHAR_LEN("FooterBackColor"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FOOTER_GRAPHIC                         (MAP_CHAR_LEN("FooterBackGraphic"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FOOTER_TRANSPARENT_BACKGROUND          (MAP_CHAR_LEN("FooterBackTransparent"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FOOTER_LEFT_BORDER                     (MAP_CHAR_LEN("FooterLeftBorder"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FOOTER_RIGHT_BORDER                    (MAP_CHAR_LEN("FooterRightBorder"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FOOTER_TOP_BORDER                      (MAP_CHAR_LEN("FooterTopBorder"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FOOTER_BOTTOM_BORDER                   (MAP_CHAR_LEN("FooterBottomBorder"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FOOTER_BORDER_DISTANCE                 (MAP_CHAR_LEN("FooterBorderDistance"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FOOTER_SHADOW_FORMAT                   (MAP_CHAR_LEN("FooterShadowFormat"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FOOTER_BODY_DISTANCE                   (MAP_CHAR_LEN("FooterBodyDistance"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FOOTER_IS_DYNAMIC_DISTANCE             (MAP_CHAR_LEN("FooterIsDynamicDistance"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FOOTER_SHARE_CONTENT                   (MAP_CHAR_LEN("FooterShareContent"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FOOTER_HEIGHT                          (MAP_CHAR_LEN("FooterHeight"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FOOTER_ON                              (MAP_CHAR_LEN("FooterOn"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_OVERWRITE_STYLES                       (MAP_CHAR_LEN("OverwriteStyles"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_LOAD_NUMBERING_STYLES                  (MAP_CHAR_LEN("LoadNumberingStyles"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_LOAD_PAGE_STYLES                       (MAP_CHAR_LEN("LoadPageStyles"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_LOAD_FRAME_STYLES                      (MAP_CHAR_LEN("LoadFrameStyles"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_LOAD_TEXT_STYLES                       (MAP_CHAR_LEN("LoadTextStyles"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FILE_NAME                              (MAP_CHAR_LEN("FileName"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FILTER_NAME                            (MAP_CHAR_LEN("FilterName"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FILTER_OPTION                          (MAP_CHAR_LEN("FilterOption"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PASSWORD                               (MAP_CHAR_LEN("Password"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_COPY_COUNT                             (MAP_CHAR_LEN("CopyCount"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_COLLATE                                (MAP_CHAR_LEN("Collate"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SORT                                   (MAP_CHAR_LEN("Sort"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PAGES                                  (MAP_CHAR_LEN("Pages"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FIRST_LINE_OFFSET                      (MAP_CHAR_LEN("FirstLineOffset"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SYMBOL_TEXT_DISTANCE                   (MAP_CHAR_LEN("SymbolTextDistance"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_USER_INDEX_NAME                        (MAP_CHAR_LEN("UserIndexName"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_REVISION                               (MAP_CHAR_LEN("Revision"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_UNVISITED_CHAR_STYLE_NAME              (MAP_CHAR_LEN("UnvisitedCharStyleName"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_VISITED_CHAR_STYLE_NAME                (MAP_CHAR_LEN("VisitedCharStyleName"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARAGRAPH_COUNT                        (MAP_CHAR_LEN("ParagraphCount"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_WORD_COUNT                             (MAP_CHAR_LEN("WordCount"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_WORD_SEPARATOR                         (MAP_CHAR_LEN("WordSeparator"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHARACTER_COUNT                        (MAP_CHAR_LEN("CharacterCount"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_ZOOM_VALUE                             (MAP_CHAR_LEN("ZoomValue"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_ZOOM_TYPE                              (MAP_CHAR_LEN("ZoomType"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CREATE_FROM_MARKS                      (MAP_CHAR_LEN("CreateFromMarks"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CREATE_FROM_OUTLINE                    (MAP_CHAR_LEN("CreateFromOutline"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARAGRAPH_STYLE_NAMES                  (MAP_CHAR_LEN("ParagraphStyleNames"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CREATE_FROM_CHAPTER                    (MAP_CHAR_LEN("CreateFromChapter"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CREATE_FROM_LABELS                     (MAP_CHAR_LEN("CreateFromLabels"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_USE_ALPHABETICAL_SEPARATORS            (MAP_CHAR_LEN("UseAlphabeticalSeparators"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_USE_KEY_AS_ENTRY                       (MAP_CHAR_LEN("UseKeyAsEntry"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_USE_COMBINED_ENTRIES                   (MAP_CHAR_LEN("UseCombinedEntries"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_IS_CASE_SENSITIVE                      (MAP_CHAR_LEN("IsCaseSensitive"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_USE_P_P                                (MAP_CHAR_LEN("UsePP"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_USE_DASH                               (MAP_CHAR_LEN("UseDash"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_USE_UPPER_CASE                         (MAP_CHAR_LEN("UseUpperCase"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_LABEL_CATEGORY                         (MAP_CHAR_LEN("LabelCategory"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_LABEL_DISPLAY_TYPE                     (MAP_CHAR_LEN("LabelDisplayType"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_USE_LEVEL_FROM_SOURCE                  (MAP_CHAR_LEN("UseLevelFromSource"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_LEVEL_FORMAT                           (MAP_CHAR_LEN("LevelFormat"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_LEVEL_PARAGRAPH_STYLES                 (MAP_CHAR_LEN("LevelParagraphStyles"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_RECALC_TAB_STOPS                       (MAP_CHAR_LEN("RecalcTabStops"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_MAIN_ENTRY_CHARACTER_STYLE_NAME        (MAP_CHAR_LEN("MainEntryCharacterStyleName"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CREATE_FROM_TABLES                     (MAP_CHAR_LEN("CreateFromTables"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CREATE_FROM_TEXT_FRAMES                (MAP_CHAR_LEN("CreateFromTextFrames"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CREATE_FROM_GRAPHIC_OBJECTS            (MAP_CHAR_LEN("CreateFromGraphicObjects"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CREATE_FROM_EMBEDDED_OBJECTS           (MAP_CHAR_LEN("CreateFromEmbeddedObjects"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CREATE_FROM_STAR_MATH                  (MAP_CHAR_LEN("CreateFromStarMath"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CREATE_FROM_STAR_IMAGE                 (MAP_CHAR_LEN("CreateFromStarImage"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CREATE_FROM_STAR_CHART                 (MAP_CHAR_LEN("CreateFromStarChart"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CREATE_FROM_STAR_CALC                  (MAP_CHAR_LEN("CreateFromStarCalc"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CREATE_FROM_STAR_DRAW                  (MAP_CHAR_LEN("CreateFromStarDraw"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CREATE_FROM_OTHER_EMBEDDED_OBJECTS     (MAP_CHAR_LEN("CreateFromOtherEmbeddedObjects"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_INDEX_AUTO_MARK_FILE_U_R_L             (MAP_CHAR_LEN("IndexAutoMarkFileURL"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_IS_COMMA_SEPARATED                     (MAP_CHAR_LEN("IsCommaSeparated"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SHOW_CHANGES                           (MAP_CHAR_LEN("ShowChanges"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_RECORD_CHANGES                         (MAP_CHAR_LEN("RecordChanges"));
+const SwPropNameLen __FAR_DATA  UNO_LINK_DISPLAY_NAME                           (MAP_CHAR_LEN("LinkDisplayName"));
+const SwPropNameLen __FAR_DATA  UNO_LINK_DISPLAY_BITMAP                         (MAP_CHAR_LEN("LinkDisplayBitmap"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_HEADING_STYLE_NAME                     (MAP_CHAR_LEN("HeadingStyleName"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_SHOW_ONLINE_LAYOUT                     (MAP_CHAR_LEN("ShowOnlineLayout"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_USER_DEFINED_ATTRIBUTES                (MAP_CHAR_LEN("UserDefinedAttributes"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_USER_DEFINED_ATTRIBUTES           (MAP_CHAR_LEN("ParaUserDefinedAttributes"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHAR_USER_DEFINED_ATTRIBUTES           (MAP_CHAR_LEN("CharUserDefinedAttributes"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_FILE_PATH                              (MAP_CHAR_LEN("FilePath"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_CHAPTER_NUMBERING_LEVEL           (MAP_CHAR_LEN("ParaChapterNumberingLevel"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_PARA_CONDITIONAL_STYLE_NAME            (MAP_CHAR_LEN("ParaConditionalStyleName"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CHAPTER_NUMBERING_LEVEL                (MAP_CHAR_LEN("ChapterNumberingLevel"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_NUMBERING_SEPARATOR                    (MAP_CHAR_LEN("NumberingSeparator"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_IS_CONTINUOUS_NUMBERING                (MAP_CHAR_LEN("IsContinuousNumbering"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_IS_AUTOMATIC                           (MAP_CHAR_LEN("IsAutomatic"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_IS_ABSOLUTE_MARGINS                    (MAP_CHAR_LEN("IsAbsoluteMargins"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CATEGORY                               (MAP_CHAR_LEN("Category"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_DEPENDENT_TEXT_FIELDS                  (MAP_CHAR_LEN("DependentTextFields"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_CURRENT_PRESENTATION                   (MAP_CHAR_LEN("CurrentPresentation"));
+const SwPropNameLen __FAR_DATA  UNO_NAME_ADJUST                                 (MAP_CHAR_LEN("Adjust"));
+
+const SwPropNameLen __FAR_DATA UNO_NAME_TEXT_PORTION_TYPE                       (MAP_CHAR_LEN("TextPortionType"));
+const SwPropNameLen __FAR_DATA UNO_NAME_CONTROL_CHARACTER                       (MAP_CHAR_LEN("ControlCharacter"));
+const SwPropNameLen __FAR_DATA UNO_NAME_IS_COLLAPSED                            (MAP_CHAR_LEN("IsCollapsed"));
+const SwPropNameLen __FAR_DATA UNO_NAME_IS_START                                (MAP_CHAR_LEN("IsStart"));
+const SwPropNameLen __FAR_DATA UNO_NAME_SEQUENCE_NUMBER                         (MAP_CHAR_LEN("SequenceNumber"));
+const SwPropNameLen __FAR_DATA UNO_NAME_REFERENCE_ID                            (MAP_CHAR_LEN("ReferenceId"));
diff --git a/sw/source/core/unocore/unorefmk.cxx b/sw/source/core/unocore/unorefmk.cxx
new file mode 100644
index 000000000000..7ac8d4ef8f56
--- /dev/null
+++ b/sw/source/core/unocore/unorefmk.cxx
@@ -0,0 +1,496 @@
+/*************************************************************************
+ *
+ *  $RCSfile: unorefmk.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:28 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _VOS_MUTEX_HXX_ //autogen
+#include 
+#endif
+#ifndef _SV_SVAPP_HXX //autogen
+#include 
+#endif
+#ifndef _UNOOBJ_HXX
+#include 
+#endif
+#ifndef _UNOMAP_HXX
+#include 
+#endif
+#ifndef _UNOCRSR_HXX
+#include 
+#endif
+#ifndef _DOC_HXX //autogen
+#include 
+#endif
+#ifndef _NDTXT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTRFMRK_HXX //autogen
+#include 
+#endif
+#ifndef _TXTRFMRK_HXX //autogen
+#include 
+#endif
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::beans;
+using namespace ::rtl;
+
+/******************************************************************
+ * SwXReferenceMark
+ ******************************************************************/
+
+/* -----------------------------13.03.00 12:15--------------------------------
+
+ ---------------------------------------------------------------------------*/
+const uno::Sequence< sal_Int8 > & SwXReferenceMark::getUnoTunnelId()
+{
+    static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId();
+    return aSeq;
+}
+/* -----------------------------10.03.00 18:04--------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Int64 SAL_CALL SwXReferenceMark::getSomething( const uno::Sequence< sal_Int8 >& rId )
+    throw(uno::RuntimeException)
+{
+    if( rId.getLength() == 16
+        && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+                                        rId.getConstArray(), 16 ) )
+    {
+            return (sal_Int64)this;
+    }
+    return 0;
+}
+/* -----------------------------06.04.00 16:41--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXReferenceMark::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXReferenceMark");
+}
+/* -----------------------------06.04.00 16:41--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXReferenceMark::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return !rServiceName.compareToAscii("com.sun.star.text.ReferenceMark")||
+                !rServiceName.compareToAscii("com.sun.star.text.TextContent");
+}
+/* -----------------------------06.04.00 16:41--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXReferenceMark::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(2);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.ReferenceMark");
+    pArray[1] = C2U("com.sun.star.text.TextContent");
+    return aRet;
+}
+/*-- 11.12.98 10:28:32---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+TYPEINIT1(SwXReferenceMark, SwClient);
+
+SwXReferenceMark::SwXReferenceMark(SwDoc* pDc, const SwFmtRefMark* pRefMark) :
+    aLstnrCntnr( (text::XTextContent*)this),
+    pDoc(pDc),
+    pMark(pRefMark),
+    m_bIsDescriptor(0 == pRefMark)
+{
+    if(pRefMark)
+        sMarkName = pRefMark->GetRefName();
+    if(pDoc)
+        pDoc->GetUnoCallBack()->Add(this);
+}
+/*-- 11.12.98 10:28:33---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXReferenceMark::~SwXReferenceMark()
+{
+
+}
+/* -----------------03.11.99 14:14-------------------
+
+ --------------------------------------------------*/
+void SwXReferenceMark::InsertRefMark(SwPaM& rPam, SwDoc* pDoc)
+{
+    UnoActionContext aCont(pDoc);
+    SwTxtAttr* pTxtAttr = 0;
+    SwFmtRefMark aRefMark(sMarkName);
+    SfxItemSet  aSet(pDoc->GetAttrPool(), RES_TXTATR_REFMARK, RES_TXTATR_REFMARK, 0L);
+    aSet.Put(aRefMark);
+    sal_Bool bMark = *rPam.GetPoint() != *rPam.GetMark();
+    SwXTextCursor::SetCrsrAttr(rPam, aSet);
+
+    if(bMark && *rPam.GetPoint() > *rPam.GetMark())
+        rPam.Exchange();
+    SwUnoCrsr* pCrsr = pDoc->CreateUnoCrsr( *rPam.Start() );
+    if(!bMark)
+    {
+        pCrsr->SetMark();
+        pCrsr->Left(1);
+    }
+    pTxtAttr = pCrsr->GetNode()->GetTxtNode()->GetTxtAttr(pCrsr->GetPoint()->nContent, RES_TXTATR_REFMARK);
+    delete pCrsr;
+    if(pTxtAttr)
+    {
+        pMark = &pTxtAttr->GetRefMark();
+    }
+    pDoc->GetUnoCallBack()->Add(this);
+}
+
+/* -----------------18.02.99 13:33-------------------
+ *
+ * --------------------------------------------------*/
+void SwXReferenceMark::attachToRange(const uno::Reference< text::XTextRange > & xTextRange)
+                throw( lang::IllegalArgumentException, uno::RuntimeException )
+{
+    if(!m_bIsDescriptor)
+        throw uno::RuntimeException();
+    uno::Reference xRangeTunnel( xTextRange, uno::UNO_QUERY);
+    SwXTextRange* pRange = 0;
+    SwXTextCursor* pCursor = 0;
+    if(xRangeTunnel.is())
+    {
+        pRange = (SwXTextRange*)xRangeTunnel->getSomething(
+                                SwXTextRange::getUnoTunnelId());
+        pCursor = (SwXTextCursor*)xRangeTunnel->getSomething(
+                                SwXTextCursor::getUnoTunnelId());
+    }
+    SwDoc* pDocument = pRange ? (SwDoc*)pRange->GetDoc() : pCursor ? (SwDoc*)pCursor->GetDoc() : 0;
+    if(pDocument)
+    {
+        SwUnoInternalPaM aPam(*pDocument);
+        //das muss jetzt sal_True liefern
+        SwXTextRange::XTextRangeToSwPaM(aPam, xTextRange);
+        InsertRefMark(aPam, pDocument);
+        m_bIsDescriptor = sal_False;
+        pDoc = pDocument;
+        pDoc->GetUnoCallBack()->Add(this);
+    }
+    else
+        throw lang::IllegalArgumentException();
+}
+/*-- 11.12.98 10:28:34---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXReferenceMark::attach(const uno::Reference< text::XTextRange > & xTextRange)
+                throw( lang::IllegalArgumentException, uno::RuntimeException )
+{
+}
+/*-- 11.12.98 10:28:34---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< text::XTextRange >  SwXReferenceMark::getAnchor(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< text::XTextRange >  xRet;
+    if(IsValid())
+    {
+        const SwFmtRefMark* pNewMark = pDoc->GetRefMark(sMarkName);
+        if(pNewMark && pNewMark == pMark)
+        {
+            const SwTxtRefMark* pTxtMark = pMark->GetTxtRefMark();
+            if(pTxtMark &&
+                &pTxtMark->GetTxtNode().GetNodes() == &pDoc->GetNodes())
+            {
+                SwTxtNode& rTxtNode = (SwTxtNode&)pTxtMark->GetTxtNode();
+                SwPaM* pPam  = pTxtMark->GetEnd() ?
+                                new SwPaM( rTxtNode, *pTxtMark->GetEnd(),
+                                    rTxtNode, *pTxtMark->GetStart()) :
+                                new SwPaM(  rTxtNode, *pTxtMark->GetStart());
+
+
+                xRet = ::CreateTextRangeFromPosition(pDoc,
+                        *pPam->Start(), pPam->End());
+                delete pPam;
+            }
+        }
+    }
+    return xRet;
+}
+/*-- 11.12.98 10:28:35---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXReferenceMark::dispose(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(IsValid())
+    {
+        const SwFmtRefMark* pNewMark = pDoc->GetRefMark(sMarkName);
+        if(pNewMark && pNewMark == pMark)
+        {
+            const SwTxtRefMark* pTxtMark = pMark->GetTxtRefMark();
+            if(pTxtMark &&
+                &pTxtMark->GetTxtNode().GetNodes() == &pDoc->GetNodes())
+            {
+                SwTxtNode& rTxtNode = (SwTxtNode&)pTxtMark->GetTxtNode();
+                SwPaM* pPam  = pTxtMark->GetEnd() ?
+                                new SwPaM( rTxtNode, *pTxtMark->GetEnd(),
+                                    rTxtNode, *pTxtMark->GetStart()) :
+                                new SwPaM(  rTxtNode, *pTxtMark->GetStart());
+
+                if(pPam->HasMark())
+                    pDoc->DeleteAndJoin(*pPam);
+                else
+                {
+                    SwCursor aCrsr(*pPam->Start());
+                    aCrsr.SetMark();
+                    aCrsr.LeftRight(sal_False, 1);
+                    pDoc->DeleteAndJoin(aCrsr);
+                }
+                delete pPam;
+            }
+        }
+    }
+    else
+        throw uno::RuntimeException();
+}
+/*-- 11.12.98 10:28:35---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXReferenceMark::addEventListener(const uno::Reference< lang::XEventListener > & aListener) throw( uno::RuntimeException )
+{
+    if(!GetRegisteredIn())
+        throw uno::RuntimeException();
+    aLstnrCntnr.AddListener(aListener);
+}
+/*-- 11.12.98 10:28:35---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXReferenceMark::removeEventListener(const uno::Reference< lang::XEventListener > & aListener) throw( uno::RuntimeException )
+{
+    if(!GetRegisteredIn() || !aLstnrCntnr.RemoveListener(aListener))
+        throw uno::RuntimeException();
+}
+/*-- 11.12.98 10:28:36---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+OUString SwXReferenceMark::getName(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!IsValid() || !pDoc->GetRefMark(sMarkName))
+    {
+        throw uno::RuntimeException();
+    }
+    return sMarkName;
+}
+/*-- 11.12.98 10:28:36---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXReferenceMark::setName(const OUString& Name_) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(m_bIsDescriptor)
+        sMarkName = String(Name_);
+    else
+    {
+        String sNewName(Name_);
+        if(!IsValid() || !pDoc->GetRefMark(sMarkName) || pDoc->GetRefMark(sNewName))
+        {
+            throw uno::RuntimeException();
+        }
+        const SwFmtRefMark* pCurMark = pDoc->GetRefMark(sMarkName);
+        if(sNewName != sMarkName && pCurMark && pCurMark == pMark)
+        {
+            SwDoc* pTempDoc = pDoc;
+            UnoActionContext aCont(pTempDoc);
+            const SwTxtRefMark* pTxtMark = pMark->GetTxtRefMark();
+            if(pTxtMark &&
+                &pTxtMark->GetTxtNode().GetNodes() == &pTempDoc->GetNodes())
+            {
+                SwTxtNode& rTxtNode = (SwTxtNode&)pTxtMark->GetTxtNode();
+                SwPaM* pPam  = pTxtMark->GetEnd() ?
+                                new SwPaM( rTxtNode, *pTxtMark->GetEnd(),
+                                    rTxtNode, *pTxtMark->GetStart()) :
+                                new SwPaM(  rTxtNode, *pTxtMark->GetStart());
+
+                //kill the old reference mark
+                if(pPam->HasMark())
+                    pTempDoc->DeleteAndJoin(*pPam);
+                else
+                {
+                    SwCursor aCrsr(*pPam->Start());
+                    aCrsr.SetMark();
+                    aCrsr.LeftRight(sal_False, 1);
+                    pDoc->DeleteAndJoin(aCrsr);
+                }
+                sMarkName = sNewName;
+                //create a new one
+                InsertRefMark(*pPam, pTempDoc);
+                delete pPam;
+                pDoc = pTempDoc;
+            }
+        }
+    }
+}
+/* -----------------------------07.01.00 12:51--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void    SwXReferenceMark::Invalidate()
+{
+    if(GetRegisteredIn())
+    {
+        ((SwModify*)GetRegisteredIn())->Remove(this);
+        aLstnrCntnr.Disposing();
+        pDoc = 0;
+        pMark = 0;
+    }
+}
+/*-- 11.12.98 10:28:37---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void    SwXReferenceMark::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew)
+{
+    ClientModify( this, pOld, pNew );
+    if(!GetRegisteredIn())
+        aLstnrCntnr.Disposing();
+}
+
+/*-- 12.09.00 12:58:20---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Reference< XPropertySetInfo > SwXReferenceMark::getPropertySetInfo(  ) throw(RuntimeException)
+{
+    static uno::Reference< beans::XPropertySetInfo >  xRef =
+        SfxItemPropertySet(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_PARAGRAPH_EXTENSIONS)).
+            getPropertySetInfo();
+    return xRef;
+}
+/*-- 12.09.00 12:58:20---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXReferenceMark::setPropertyValue(
+    const OUString& aPropertyName, const Any& aValue )
+        throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
+{
+    throw IllegalArgumentException();
+}
+/*-- 12.09.00 12:58:20---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Any SwXReferenceMark::getPropertyValue( const OUString& rPropertyName )
+    throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+    Any aRet;
+    if(!SwXParagraph::getDefaultTextContentValue(aRet, rPropertyName))
+        throw UnknownPropertyException();
+    return aRet;
+}
+/*-- 12.09.00 12:58:20---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXReferenceMark::addPropertyChangeListener(
+    const OUString& aPropertyName, const Reference< XPropertyChangeListener >& xListener )
+            throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+/*-- 12.09.00 12:58:20---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXReferenceMark::removePropertyChangeListener(
+    const OUString& aPropertyName, const Reference< XPropertyChangeListener >& aListener )
+            throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+/*-- 12.09.00 12:58:20---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXReferenceMark::addVetoableChangeListener( const OUString& PropertyName,
+    const Reference< XVetoableChangeListener >& aListener )
+        throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+/*-- 12.09.00 12:58:21---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXReferenceMark::removeVetoableChangeListener(
+    const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener )
+        throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+/*------------------------------------------------------------------------
+
+    $Log: not supported by cvs2svn $
+    Revision 1.4  2000/09/18 16:04:34  willem.vandorp
+    OpenOffice header added.
+
+    Revision 1.3  2000/09/12 11:42:59  os
+    #78682# support of service TextContent
+
+    Revision 1.2  2000/09/11 09:57:06  os
+    TYPEINFO
+
+    Revision 1.1  2000/05/04 15:14:14  os
+    reduce size of unoobj.cxx
+
+
+------------------------------------------------------------------------*/
+
diff --git a/sw/source/core/unocore/unosect.cxx b/sw/source/core/unocore/unosect.cxx
new file mode 100644
index 000000000000..d41e981a1bd7
--- /dev/null
+++ b/sw/source/core/unocore/unosect.cxx
@@ -0,0 +1,858 @@
+/*************************************************************************
+ *
+ *  $RCSfile: unosect.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:28 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _COM_SUN_STAR_TEXT_SECTIONFILELINK_HPP_
+#include 
+#endif
+
+#include 
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+#ifndef SVTOOLS_URIHELPER_HXX
+#include 
+#endif
+#ifndef _SVX_BRSHITEM_HXX //autogen
+#include 
+#endif
+#ifndef _LINKMGR_HXX
+#include 
+#endif
+#ifndef _VOS_MUTEX_HXX_ //autogen
+#include 
+#endif
+#ifndef _SV_SVAPP_HXX //autogen
+#include 
+#endif
+#ifndef _FMTCLDS_HXX //autogen
+#include 
+#endif
+#ifndef _UNOOBJ_HXX
+#include 
+#endif
+#ifndef _UNOMAP_HXX
+#include 
+#endif
+#ifndef _UNOCRSR_HXX
+#include 
+#endif
+#ifndef _SECTION_HXX //autogen
+#include 
+#endif
+#ifndef _DOC_HXX //autogen
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX //autogen
+#include 
+#endif
+#ifndef _HINTS_HXX //autogen
+#include 
+#endif
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::beans;
+using namespace ::rtl;
+
+/******************************************************************
+ *
+ ******************************************************************/
+TYPEINIT1(SwXTextSection, SwClient);
+struct SwTextSectionProperties_Impl
+{
+
+    String  sCondition;
+    String  sLinkFileName;
+    String  sSectionFilter;
+    String  sSectionRegion;
+
+    SwFmtCol*   pColItem;
+    SvxBrushItem* pBrushItem;
+    sal_Bool    bDDE;
+    sal_Bool    bHidden;
+    sal_Bool    bProtect;
+
+    SwTextSectionProperties_Impl() :
+        bDDE(0),
+        bHidden(0),
+        bProtect(0),
+        pColItem(0),
+        pBrushItem(0){}
+
+    ~SwTextSectionProperties_Impl()
+    {
+        delete pColItem;
+        delete pBrushItem;
+    }
+};
+/* -----------------------------11.07.00 12:10--------------------------------
+
+ ---------------------------------------------------------------------------*/
+SwXTextSection* SwXTextSection::GetImplementation(Reference< XInterface> xRef )
+{
+    uno::Reference xTunnel( xRef, uno::UNO_QUERY);
+    if(xTunnel.is())
+        return (SwXTextSection*)xTunnel->getSomething(SwXTextSection::getUnoTunnelId());
+    return 0;
+}
+
+/* -----------------------------13.03.00 12:15--------------------------------
+
+ ---------------------------------------------------------------------------*/
+const uno::Sequence< sal_Int8 > & SwXTextSection::getUnoTunnelId()
+{
+    static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId();
+    return aSeq;
+}
+/* -----------------------------10.03.00 18:04--------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Int64 SAL_CALL SwXTextSection::getSomething( const uno::Sequence< sal_Int8 >& rId )
+    throw(uno::RuntimeException)
+{
+    if( rId.getLength() == 16
+        && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+                                        rId.getConstArray(), 16 ) )
+    {
+            return (sal_Int64)this;
+    }
+    return 0;
+}
+/*-- 10.12.98 14:47:05---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextSection::SwXTextSection(SwSectionFmt* pFmt) :
+        SwClient(pFmt),
+        aLstnrCntnr( (text::XTextContent*)this),
+        aPropSet(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_SECTION)),
+//          _pMap(aSwMapProvider.getPropertyMap(PROPERTY_MAP_SECTION)),
+        m_bIsDescriptor(pFmt == 0),
+        pProps(pFmt ? 0 : new SwTextSectionProperties_Impl)
+{
+
+}
+/*-- 10.12.98 14:47:07---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextSection::~SwXTextSection()
+{
+    delete pProps;
+}
+/*-- 10.12.98 14:47:08---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< text::XTextSection >  SwXTextSection::getParentSection(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< text::XTextSection >  aRef;
+    SwSectionFmt*  pSectFmt = GetFmt();
+    if(pSectFmt)
+    {
+        SwSectionFmt* pParentFmt = pSectFmt->GetParent();
+        if(pParentFmt)
+        {
+            SwXTextSection* pxSect = (SwXTextSection*)SwClientIter(*pParentFmt).
+                                                        First(TYPE(SwXTextSection));
+            if(pxSect)
+                aRef = pxSect;
+            else
+                aRef = new SwXTextSection(pParentFmt);
+        }
+    }
+    else
+        throw uno::RuntimeException();
+    return aRef;
+}
+/*-- 10.12.98 14:47:08---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Sequence< uno::Reference< text::XTextSection >  > SwXTextSection::getChildSections(void)
+    throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Sequence > aSeq;
+    SwSectionFmt*  pSectFmt = GetFmt();
+    if(pSectFmt)
+    {
+        SwSections aChildren;
+        pSectFmt->GetChildSections(aChildren, SORTSECT_NOT, sal_False);
+        aSeq.realloc(aChildren.Count());
+        uno::Reference< text::XTextSection > * pArray = aSeq.getArray();
+        for(sal_uInt16 i = 0; i < aChildren.Count(); i++)
+        {
+            SwSectionFmt* pChild = aChildren.GetObject(i)->GetFmt();
+            SwXTextSection* pxSect = (SwXTextSection*)SwClientIter(*pChild).
+                                                        First(TYPE(SwXTextSection));
+            if(pxSect)
+                pArray[i] = pxSect;
+            else
+                pArray[i] = new SwXTextSection(pChild);
+        }
+    }
+    return aSeq;
+
+}
+/* -----------------18.02.99 13:31-------------------
+ *
+ * --------------------------------------------------*/
+void SwXTextSection::attachToRange(const uno::Reference< text::XTextRange > & xTextRange)
+    throw( lang::IllegalArgumentException, uno::RuntimeException )
+{
+    if(!m_bIsDescriptor)
+        throw uno::RuntimeException();
+
+    uno::Reference xRangeTunnel( xTextRange, uno::UNO_QUERY);
+    SwXTextRange* pRange = 0;
+    SwXTextCursor* pCursor = 0;
+    if(xRangeTunnel.is())
+    {
+        pRange = (SwXTextRange*)xRangeTunnel->getSomething(
+                                SwXTextRange::getUnoTunnelId());
+        pCursor = (SwXTextCursor*)xRangeTunnel->getSomething(
+                                SwXTextCursor::getUnoTunnelId());
+    }
+
+    SwDoc* pDoc = pRange ? (SwDoc*)pRange->GetDoc() : pCursor ? (SwDoc*)pCursor->GetDoc() : 0;
+    if(pDoc)
+    {
+        SwUnoInternalPaM aPam(*pDoc);
+        //das muss jetzt sal_True liefern
+        SwXTextRange::XTextRangeToSwPaM(aPam, xTextRange);
+        UnoActionContext aCont(pDoc);
+        pDoc->StartUndo( UNDO_INSSECTION );
+
+        sal_Bool bRet = sal_False;
+
+        SwSection* pRet = 0;
+        if(!m_sName.Len())
+            m_sName =  C2S("TextSection");
+        SwSection aSect(pProps->bDDE ? DDE_LINK_SECTION :
+            pProps->sLinkFileName.Len() || pProps->sSectionRegion.Len() ?  FILE_LINK_SECTION :
+                                                                CONTENT_SECTION,
+                                            pDoc->GetUniqueSectionName(&m_sName));
+        aSect.SetCondition(pProps->sCondition);
+        String sLinkName(pProps->sLinkFileName);
+        sLinkName += cTokenSeperator;
+        sLinkName += pProps->sSectionFilter;
+        sLinkName += cTokenSeperator;
+        sLinkName += pProps->sSectionRegion;
+        aSect.SetLinkFileName(sLinkName);
+
+        aSect.SetHidden(pProps->bHidden);
+        aSect.SetProtect(pProps->bProtect);
+        SfxItemSet aSet(pDoc->GetAttrPool(),
+                    RES_COL, RES_COL,
+                    RES_BACKGROUND, RES_BACKGROUND,
+                    0);
+            if(pProps->pBrushItem)
+                aSet.Put(*pProps->pBrushItem);
+            if(pProps->pColItem)
+                aSet.Put(*pProps->pColItem);
+        pRet = pDoc->Insert( aPam, aSect, aSet.Count() ? &aSet : 0 );
+        pRet->GetFmt()->Add(this);
+        // Undo-Klammerung hier beenden
+        pDoc->EndUndo( UNDO_INSSECTION );
+        DELETEZ(pProps);
+        m_bIsDescriptor = sal_False;
+    }
+    else
+        throw lang::IllegalArgumentException();
+}
+/*-- 10.12.98 14:47:09---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextSection::attach(const uno::Reference< text::XTextRange > & xTextRange)
+                    throw( lang::IllegalArgumentException, uno::RuntimeException )
+{
+}
+
+/*-- 10.12.98 14:47:09---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< text::XTextRange >  SwXTextSection::getAnchor(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< text::XTextRange >  xRet;
+    SwSectionFmt*  pSectFmt = GetFmt();
+    if(pSectFmt)
+    {
+        const SwSection* pSect;
+        const SwNodeIndex* pIdx;
+        if( 0 != ( pSect = pSectFmt->GetSection() ) &&
+            0 != ( pIdx = pSectFmt->GetCntnt().GetCntntIdx() ) &&
+            pIdx->GetNode().GetNodes().IsDocNodes() )
+        {
+            SwPaM aPaM(*pIdx);
+            aPaM.Move( fnMoveForward, fnGoCntnt );
+            SwCursor aCrsr(*aPaM.GetPoint());
+            aCrsr.SetMark();
+            aCrsr.MoveRegion( fnRegionCurr, fnRegionEnd );
+            xRet = ::CreateTextRangeFromPosition(pSectFmt->GetDoc(),
+                *aCrsr.Start(), aCrsr.End());
+        }
+    }
+    return xRet;
+}
+/*-- 10.12.98 14:47:09---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextSection::dispose(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwSectionFmt*  pSectFmt = GetFmt();
+    if(pSectFmt)
+        pSectFmt->GetDoc()->DelSectionFmt( pSectFmt );
+    else
+        throw uno::RuntimeException();
+}
+/*-- 10.12.98 14:47:10---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextSection::addEventListener(const uno::Reference< lang::XEventListener > & aListener) throw( uno::RuntimeException )
+{
+    if(!GetRegisteredIn())
+        throw uno::RuntimeException();
+    aLstnrCntnr.AddListener(aListener);
+}
+/*-- 10.12.98 14:47:10---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextSection::removeEventListener(const uno::Reference< lang::XEventListener > & aListener) throw( uno::RuntimeException )
+{
+    if(!GetRegisteredIn() || !aLstnrCntnr.RemoveListener(aListener))
+        throw uno::RuntimeException();
+}
+/*-- 10.12.98 14:47:11---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< beans::XPropertySetInfo >  SwXTextSection::getPropertySetInfo(void) throw( uno::RuntimeException )
+{
+    static uno::Reference< beans::XPropertySetInfo >  aRef = aPropSet.getPropertySetInfo();
+    return aRef;
+}
+/*-- 10.12.98 14:47:11---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextSection::setPropertyValue(
+    const OUString& rPropertyName, const uno::Any& aValue)
+    throw( beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwSectionFmt*   pFmt = GetFmt();
+    if(pFmt || m_bIsDescriptor)
+    {
+        SwSection   aSection(CONTENT_SECTION, aEmptyStr);
+        SwSection* pSect = pFmt ? pFmt->GetSection() : 0;
+        if(pFmt)
+            aSection = *pSect;
+        const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                                aPropSet.getPropertyMap(), rPropertyName);
+        if(pMap)
+        {
+            SfxItemSet* pNewAttrSet = 0;
+            switch(pMap->nWID)
+            {
+                case WID_SECT_CONDITION:
+                {
+                    OUString uTmp;
+                    aValue >>= uTmp;
+                    if(m_bIsDescriptor)
+                        pProps->sCondition = String(uTmp);
+                    else
+                        aSection.SetCondition(uTmp);
+                }
+                break;
+                case WID_SECT_DDE_TYPE      :
+                case WID_SECT_DDE_FILE      :
+                case WID_SECT_DDE_ELEMENT   :
+                {
+                    OUString uTmp;
+                    aValue >>= uTmp;
+                    String sTmp(uTmp);
+                    if(m_bIsDescriptor)
+                    {
+                        if(!pProps->bDDE)
+                        {
+                            pProps->sLinkFileName = cTokenSeperator;
+                            pProps->sLinkFileName += cTokenSeperator;
+                            pProps->bDDE = sal_True;
+                        }
+                        pProps->sLinkFileName.SetToken(pMap->nWID - WID_SECT_DDE_TYPE,cTokenSeperator,sTmp);
+                    }
+                    else
+                    {
+                        String sLinkFileName(aSection.GetLinkFileName());
+                        if(aSection.GetType() != DDE_LINK_SECTION)
+                        {
+                            sLinkFileName = cTokenSeperator;
+                            sLinkFileName += cTokenSeperator;
+                            aSection.SetType(DDE_LINK_SECTION);
+                        }
+                        sLinkFileName.SetToken(pMap->nWID - WID_SECT_DDE_TYPE,cTokenSeperator, sTmp);
+                        aSection.SetLinkFileName(sLinkFileName);
+                    }
+                }
+                break;
+                case WID_SECT_LINK     :
+                {
+                    if(aValue.getValueType() == ::getCppuType((const text::SectionFileLink*)0))
+                    {
+                         text::SectionFileLink* pLink =  (text::SectionFileLink*)   aValue.getValue();
+                        if(m_bIsDescriptor)
+                        {
+                            pProps->bDDE = sal_False;
+                            pProps->sLinkFileName = String(pLink->FileURL);
+                            pProps->sSectionFilter = String(pLink->FilterName);
+                        }
+                        else
+                        {
+                            if(aSection.GetType() != FILE_LINK_SECTION &&
+                                pLink->FileURL.len())
+                                aSection.SetType(FILE_LINK_SECTION);
+                            String sFileName(URIHelper::SmartRelToAbs( pLink->FileURL) );
+                            sFileName += cTokenSeperator;
+                            sFileName += String(pLink->FilterName);
+                            sFileName += cTokenSeperator;
+                            sFileName += aSection.GetLinkFileName().GetToken( 2, cTokenSeperator );
+                            aSection.SetLinkFileName(sFileName);
+                            if(sFileName.Len() < 3)
+                                aSection.SetType(CONTENT_SECTION);
+                        }
+                    }
+                    else
+                        throw lang::IllegalArgumentException();
+                }
+                break;
+                case WID_SECT_REGION :
+                {
+                    OUString uTmp;
+                    aValue >>= uTmp;
+                    String sLink(uTmp);
+                    if(m_bIsDescriptor)
+                    {
+                        pProps->bDDE = sal_False;
+                        pProps->sSectionRegion = sLink.GetToken(2, cTokenSeperator);
+                    }
+                    else
+                    {
+                        if(aSection.GetType() != FILE_LINK_SECTION &&
+                                sLink.Len())
+                                aSection.SetType(FILE_LINK_SECTION);
+                        String sSectLink(aSection.GetLinkFileName());
+                        while( 3 < sSectLink.GetTokenCount( cTokenSeperator ))
+                        {
+                            sSectLink += cTokenSeperator;
+                        }
+                        sSectLink.SetToken(2, cTokenSeperator, sLink);
+                        aSection.SetLinkFileName(sSectLink);
+                    }
+                }
+                break;
+                case WID_SECT_VISIBLE   :
+                {
+                    sal_Bool bVal = *(sal_Bool*)aValue.getValue();
+                    if(m_bIsDescriptor)
+                        pProps->bHidden = !bVal;
+                    else
+                        aSection.SetHidden(!bVal);
+                }
+                break;
+                case WID_SECT_PROTECTED:
+                {
+                    sal_Bool bVal = *(sal_Bool*)aValue.getValue();
+                    if(m_bIsDescriptor)
+                        pProps->bProtect = bVal;
+                    else
+                        aSection.SetProtect(bVal);
+                }
+                break;
+                default:
+                    if(pFmt)
+                    {
+                        const SfxItemSet& rOldAttrSet = pFmt->GetAttrSet();
+                        pNewAttrSet = new SfxItemSet(*rOldAttrSet.GetPool(),
+                                                    pMap->nWID, pMap->nWID, 0);
+                        pNewAttrSet->Put(rOldAttrSet);
+                        aPropSet.setPropertyValue(rPropertyName, aValue, *pNewAttrSet);
+                    }
+                    else
+                    {
+                        SfxPoolItem* pPutItem = 0;
+                        if(RES_COL == pMap->nWID)
+                        {
+                            if(!pProps->pColItem)
+                                pProps->pColItem = new SwFmtCol;
+                                pPutItem = pProps->pColItem;
+                        }
+                        else //if(RES_BACKGROUND == pMap->nWID)
+                        {
+                            if(!pProps->pBrushItem)
+                                pProps->pBrushItem = new SvxBrushItem;
+                            pPutItem = pProps->pBrushItem;
+                        }
+                        pPutItem->PutValue(aValue, pMap->nMemberId);
+                    }
+
+            }
+            if(pFmt)
+            {
+                const SwSectionFmts& rFmts = pFmt->GetDoc()->GetSections();
+                UnoActionContext aContext(pFmt->GetDoc());
+                for( sal_uInt16 i = 0; i < rFmts.Count(); i++ )
+                {
+                    if(rFmts[i]->GetSection()->GetName() == pSect->GetName())
+                    {
+                        pFmt->GetDoc()->ChgSection( i, aSection, pNewAttrSet);
+                        break;
+                    }
+                }
+                delete pNewAttrSet;
+            }
+        }
+        else
+            throw beans::UnknownPropertyException();
+    }
+    else
+        throw uno::RuntimeException();
+}
+/*-- 10.12.98 14:47:12---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXTextSection::getPropertyValue(const OUString& rPropertyName)
+    throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Any aRet;
+    SwSectionFmt*   pFmt = GetFmt();
+    if(pFmt||m_bIsDescriptor)
+    {
+        SwSection* pSect = pFmt ? pFmt->GetSection() : 0;
+        const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                                            aPropSet.getPropertyMap(), rPropertyName);
+        if(pMap)
+        {
+            switch(pMap->nWID)
+            {
+                case WID_SECT_CONDITION:
+                {
+                    OUString uTmp(
+                        m_bIsDescriptor ? pProps->sCondition : pSect->GetCondition());
+                    aRet <<= uTmp;
+                }
+                break;
+#ifdef DDE_AVAILABLE
+                case WID_SECT_DDE_TYPE      :
+                case WID_SECT_DDE_FILE      :
+                case WID_SECT_DDE_ELEMENT   :
+                {
+                    String sRet;
+                    if(m_bIsDescriptor)
+                    {
+                        if(pProps->bDDE)
+                            sRet = pProps->sLinkFileName;
+                    }
+                    else if( DDE_LINK_SECTION == pSect->GetType() )
+                    {
+                        sRet = pSect->GetLinkFileName();
+                    }
+                    sRet = sRet.GetToken(pMap->nWID - WID_SECT_DDE_TYPE, cTokenSeperator);
+                    aRet <<= OUString(sRet);
+                }
+                break;
+#endif
+                case WID_SECT_LINK     :
+                {
+                     text::SectionFileLink aLink;
+                    if(m_bIsDescriptor)
+                    {
+                        if(!pProps->bDDE)
+                        {
+                            aLink.FileURL = pProps->sLinkFileName;
+                            aLink.FilterName = pProps->sSectionFilter;
+                        }
+                    }
+                    else if( FILE_LINK_SECTION == pSect->GetType() )
+                    {
+                        String sRet( pSect->GetLinkFileName() );
+                        aLink.FileURL = sRet.GetToken(0, cTokenSeperator );
+                        aLink.FilterName = sRet.GetToken(1, cTokenSeperator );
+                    }
+                    aRet.setValue(&aLink, ::getCppuType((text::SectionFileLink*)0));
+                }
+                break;
+                case WID_SECT_REGION :
+                {
+                    String sRet;
+                    if(m_bIsDescriptor)
+                    {
+                        sRet = pProps->sSectionRegion;
+                    }
+                    else if( FILE_LINK_SECTION == pSect->GetType() )
+                        sRet = pSect->GetLinkFileName().GetToken(2, cTokenSeperator);
+                    aRet <<= OUString(sRet);
+                }
+                break;
+                case WID_SECT_VISIBLE   :
+                {
+                    sal_Bool bTemp = m_bIsDescriptor ? !pProps->bHidden : !pSect->IsHidden();
+                    aRet.setValue( &bTemp, ::getCppuBooleanType());
+                }
+                break;
+                case WID_SECT_PROTECTED:
+                {
+                    sal_Bool bTemp = m_bIsDescriptor ? pProps->bProtect : pSect->IsProtect();
+                    aRet.setValue( &bTemp, ::getCppuBooleanType());
+                }
+                break;
+                case  FN_PARAM_LINK_DISPLAY_NAME:
+                {
+                    if(pFmt)
+                        aRet <<= OUString(pFmt->GetSection()->GetName());
+                }
+                break;
+                default:
+                    if(pFmt)
+                        aRet = aPropSet.getPropertyValue(rPropertyName, pFmt->GetAttrSet());
+                    else
+                    {
+                        const SfxPoolItem* pQueryItem = 0;
+                        if(RES_COL == pMap->nWID)
+                        {
+                            if(!pProps->pColItem)
+                                pProps->pColItem = new SwFmtCol;
+                                pQueryItem = pProps->pColItem;
+                        }
+                        else //if(RES_BACKGROUND == pMap->nWID)
+                        {
+                            if(!pProps->pBrushItem)
+                                pProps->pBrushItem = new SvxBrushItem;
+                            pQueryItem = pProps->pBrushItem;
+                        }
+                        pQueryItem->QueryValue(aRet, pMap->nMemberId);
+                    }
+            }
+        }
+        else
+            throw beans::UnknownPropertyException();
+    }
+    else
+        throw uno::RuntimeException();
+    return aRet;
+}
+/*-- 10.12.98 14:47:13---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextSection::addPropertyChangeListener(const OUString& PropertyName, const uno::Reference< beans::XPropertyChangeListener > & aListener) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 10.12.98 14:47:13---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextSection::removePropertyChangeListener(const OUString& PropertyName, const uno::Reference< beans::XPropertyChangeListener > & aListener) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 10.12.98 14:47:14---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextSection::addVetoableChangeListener(const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener > & aListener) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 10.12.98 14:47:14---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextSection::removeVetoableChangeListener(const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener > & aListener) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 10.12.98 14:47:15---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+OUString SwXTextSection::getName(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    String sRet;
+    const SwSectionFmt* pFmt = GetFmt();
+    if(pFmt)
+        sRet = pFmt->GetSection()->GetName();
+    else if(m_bIsDescriptor)
+        sRet = m_sName;
+    else
+        throw uno::RuntimeException();
+    return sRet;
+}
+/*-- 10.12.98 14:47:16---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextSection::setName(const OUString& rName) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwSectionFmt*   pFmt = GetFmt();
+    if(pFmt)
+    {
+        SwSection   aSection(CONTENT_SECTION, aEmptyStr);
+        SwSection* pSect = pFmt->GetSection();
+        aSection = *pSect;
+        String sNewName(rName);
+        aSection.SetName(sNewName);
+
+        const SwSectionFmts& rFmts = pFmt->GetDoc()->GetSections();
+        sal_uInt16 nApplyPos = USHRT_MAX;
+        for( sal_uInt16 i = 0; i < rFmts.Count(); i++ )
+        {
+            if(rFmts[i]->GetSection() == pSect)
+                nApplyPos = i;
+            else if(sNewName == rFmts[i]->GetSection()->GetName())
+                throw uno::RuntimeException();
+        }
+        if(nApplyPos != USHRT_MAX)
+        {
+            UnoActionContext aContext(pFmt->GetDoc());
+            pFmt->GetDoc()->ChgSection( nApplyPos, aSection);
+        }
+    }
+    else if(m_bIsDescriptor)
+        m_sName = String(rName);
+    else
+        throw uno::RuntimeException();
+}
+/* -----------------02.11.99 11:30-------------------
+
+ --------------------------------------------------*/
+OUString SwXTextSection::getImplementationName(void) throw( uno::RuntimeException )
+{
+    return C2U("SwXTextSection");
+}
+/* -----------------02.11.99 11:30-------------------
+
+ --------------------------------------------------*/
+sal_Bool SwXTextSection::supportsService(const OUString& rServiceName) throw( uno::RuntimeException )
+{
+    return rServiceName == C2U("com.sun.star.text.TextSection") ||
+                rServiceName == C2U("com.sun.star.document.LinkTarget");
+}
+/* -----------------02.11.99 11:30-------------------
+
+ --------------------------------------------------*/
+uno::Sequence< OUString > SwXTextSection::getSupportedServiceNames(void) throw( uno::RuntimeException )
+{
+    uno::Sequence< OUString > aRet(2);
+    OUString* pArr = aRet.getArray();
+    pArr[0] = C2U("com.sun.star.text.TextSection");
+    pArr[1] = C2U("com.sun.star.document.LinkTarget");
+    return aRet;
+}
+
+/*-- 10.12.98 14:42:52---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextSection::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew)
+{
+    if(pOld && pOld->Which() == RES_REMOVE_UNO_OBJECT &&
+        (void*)GetRegisteredIn() == ((SwPtrMsgPoolItem *)pOld)->pObject )
+            ((SwModify*)GetRegisteredIn())->Remove(this);
+    else
+        ClientModify(this, pOld, pNew);
+    if(!GetRegisteredIn())
+        aLstnrCntnr.Disposing();
+}
+
+/*------------------------------------------------------------------------
+
+    $Log: not supported by cvs2svn $
+    Revision 1.7  2000/09/18 16:04:35  willem.vandorp
+    OpenOffice header added.
+
+    Revision 1.6  2000/09/05 15:23:19  os
+    operators corrected
+
+    Revision 1.5  2000/08/31 10:04:35  os
+    DDECommand splitted into three parts
+
+    Revision 1.4  2000/07/19 11:01:32  os
+    properties added/renamed
+
+    Revision 1.3  2000/07/11 13:43:44  os
+    #76708# insert/remove paragraphs before/behind tables
+
+    Revision 1.2  2000/06/26 13:01:08  os
+    INetURLObject::SmartRelToAbs removed
+
+    Revision 1.1  2000/05/04 15:14:57  os
+    reduce size of unoobj.cxx
+
+
+------------------------------------------------------------------------*/
+
diff --git a/sw/source/core/unocore/unosett.cxx b/sw/source/core/unocore/unosett.cxx
new file mode 100644
index 000000000000..3daaf7d7d848
--- /dev/null
+++ b/sw/source/core/unocore/unosett.cxx
@@ -0,0 +1,2528 @@
+/*************************************************************************
+ *
+ *  $RCSfile: unosett.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:29 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include 
+#include 
+#include 
+#include "poolfmt.hrc"
+#include "poolfmt.hxx"
+#ifndef _FMTCOL_HXX //autogen
+#include 
+#endif
+
+#ifndef _UNOMAP_HXX
+#include 
+#endif
+#ifndef _UNOSTYLE_HXX
+#include 
+#endif
+#ifndef _UNOSETT_HXX
+#include 
+#endif
+#ifndef _UNOPRNMS_HXX
+#include 
+#endif
+#ifndef _SFX_ITEMPROP_HXX
+#include 
+#endif
+#ifndef _FTNINFO_HXX //autogen
+#include 
+#endif
+#ifndef _DOC_HXX //autogen
+#include 
+#endif
+#ifndef _PAGEDESC_HXX //autogen
+#include 
+#endif
+#ifndef _CHARFMT_HXX //autogen
+#include 
+#endif
+#ifndef SW_LINEINFO_HXX //autogen
+#include 
+#endif
+#ifndef _SWDOCSH_HXX //autogen
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _DOCSTYLE_HXX //autogen
+#include 
+#endif
+#ifndef _FMTCLDS_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BRSHITEM_HXX //autogen
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XFOOTNOTESSETTINGSSUPPLIER_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XFOOTNOTE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XFOOTNOTESSUPPLIER_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XENDNOTESSUPPLIER_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_XENDNOTESSETTINGSSUPPLIER_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_FOOTNOTENUMBERING_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_HORIORIENTATION_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_STYLE_LINENUMBERPOSITION_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_AWT_XBITMAP_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_PropertyAttribute_HPP_
+#include 
+#endif
+
+#ifndef _UNOOBJ_HXX
+#include 
+#endif
+#ifndef _SV_FONT_HXX
+#include 
+#endif
+#ifndef _SVX_FLSTITEM_HXX
+#include 
+#endif
+#ifndef _SV_METRIC_HXX
+#include 
+#endif
+#ifndef _CTRLTOOL_HXX //autogen
+#include 
+#endif
+#ifndef _VOS_MUTEX_HXX_ //autogen
+#include 
+#endif
+#ifndef _SV_SVAPP_HXX //autogen
+#include 
+#endif
+#ifndef _TOOLKIT_UNOHLP_HXX
+#include 
+#endif
+#ifndef SVX_UNOFDESC_HXX
+#include 
+#endif
+#ifndef _SV_GRAPH_HXX
+#include 
+#endif
+#ifndef _RTL_STRING_HXX_
+#include 
+#endif
+#ifndef _FMTORNT_HXX
+#include 
+#endif
+#ifndef SW_UNOMID_HXX
+#include 
+#endif
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::text;
+
+struct PropValData
+{
+    uno::Any        aVal;
+    OUString            sPropName;
+    PropValData(void* pVal, const char* cPropName, uno::Type aType ) :
+        aVal(pVal, aType),
+        sPropName(OUString::createFromAscii(cPropName))
+        {}
+    PropValData(const uno::Any& rVal, const OUString& rPropName) :
+        aVal(rVal),
+        sPropName(rPropName)
+        {}
+};
+
+typedef PropValData* PropValDataPtr;
+SV_DECL_PTRARR(PropValDataArr, PropValDataPtr, 5, 5 );
+SV_IMPL_PTRARR(PropValDataArr, PropValDataPtr)
+
+
+#define WID_PREFIX                      0
+#define WID_SUFFIX                      1
+#define WID_NUMBERING_TYPE              2
+#define WID_START_AT                    3
+#define WID_FOOTNOTE_COUNTING           4
+#define WID_PARAGRAPH_STYLE             5
+#define WID_PAGE_STYLE                  6
+#define WID_CHARACTER_STYLE             7
+#define WID_POSITION_END_OF_DOC         8
+#define WID_END_NOTICE                  9
+#define WID_BEGIN_NOTICE                10
+#define WID_ANCHOR_CHARACTER_STYLE      11
+
+const SfxItemPropertyMap* GetFootnoteMap()
+{
+    static SfxItemPropertyMap aFootnoteMap_Impl[] =
+    {
+        { SW_PROP_NAME(UNO_NAME_ANCHOR_CHAR_STYLE_NAME),WID_ANCHOR_CHARACTER_STYLE, &::getCppuType((const OUString*)0), PROPERTY_NONE,     0},
+        { SW_PROP_NAME(UNO_NAME_BEGIN_NOTICE),          WID_BEGIN_NOTICE,       &::getCppuType((const OUString*)0), PROPERTY_NONE,     0},
+        { SW_PROP_NAME(UNO_NAME_CHAR_STYLE_NAME),       WID_CHARACTER_STYLE,    &::getCppuType((const OUString*)0), PROPERTY_NONE,     0},
+        { SW_PROP_NAME(UNO_NAME_END_NOTICE),            WID_END_NOTICE ,        &::getCppuType((const OUString*)0), PROPERTY_NONE,     0},
+        { SW_PROP_NAME(UNO_NAME_FOOTNOTE_COUNTING),     WID_FOOTNOTE_COUNTING,  &::getCppuType((const sal_Int16*)0), PROPERTY_NONE,     0},
+        { SW_PROP_NAME(UNO_NAME_NUMBERING_TYPE),        WID_NUMBERING_TYPE,     &::getCppuType((const sal_Int16*)0), PROPERTY_NONE,         0},
+        { SW_PROP_NAME(UNO_NAME_PAGE_STYLE_NAME),       WID_PAGE_STYLE,         &::getCppuType((const OUString*)0), PROPERTY_NONE,     0},
+        { SW_PROP_NAME(UNO_NAME_PARA_STYLE_NAME),       WID_PARAGRAPH_STYLE,    &::getCppuType((const OUString*)0), PROPERTY_NONE,     0},
+        { SW_PROP_NAME(UNO_NAME_POSITION_END_OF_DOC),   WID_POSITION_END_OF_DOC,&::getBooleanCppuType(), PROPERTY_NONE,         0},
+        { SW_PROP_NAME(UNO_NAME_PREFIX),                WID_PREFIX,             &::getCppuType((const OUString*)0), PROPERTY_NONE,     0},
+        { SW_PROP_NAME(UNO_NAME_START_AT),              WID_START_AT ,          &::getCppuType((const sal_Int16*)0), PROPERTY_NONE,         0},
+        { SW_PROP_NAME(UNO_NAME_SUFFIX),                WID_SUFFIX,             &::getCppuType((const OUString*)0), PROPERTY_NONE,     0},
+        {0,0,0,0}
+    };
+    return aFootnoteMap_Impl;
+}
+const SfxItemPropertyMap* GetEndnoteMap()
+{
+    static SfxItemPropertyMap aEndnoteMap_Impl[] =
+    {
+        { SW_PROP_NAME(UNO_NAME_ANCHOR_CHAR_STYLE_NAME),WID_ANCHOR_CHARACTER_STYLE, &::getCppuType((const OUString*)0), PROPERTY_NONE,     0},
+        { SW_PROP_NAME(UNO_NAME_CHAR_STYLE_NAME),       WID_CHARACTER_STYLE,    &::getCppuType((const OUString*)0), PROPERTY_NONE,     0},
+        { SW_PROP_NAME(UNO_NAME_NUMBERING_TYPE),        WID_NUMBERING_TYPE,     &::getCppuType((const sal_Int16*)0), PROPERTY_NONE,         0},
+        { SW_PROP_NAME(UNO_NAME_PAGE_STYLE_NAME),       WID_PAGE_STYLE,         &::getCppuType((const OUString*)0), PROPERTY_NONE,     0},
+        { SW_PROP_NAME(UNO_NAME_PARA_STYLE_NAME),       WID_PARAGRAPH_STYLE,    &::getCppuType((const OUString*)0), PROPERTY_NONE,     0},
+        { SW_PROP_NAME(UNO_NAME_PREFIX),                WID_PREFIX,     &::getCppuType((const OUString*)0), PROPERTY_NONE,     0},
+        { SW_PROP_NAME(UNO_NAME_START_AT),              WID_START_AT ,          &::getCppuType((const sal_Int16*)0), PROPERTY_NONE,         0},
+        { SW_PROP_NAME(UNO_NAME_SUFFIX),                WID_SUFFIX,     &::getCppuType((const OUString*)0), PROPERTY_NONE,     0},
+        {0,0,0,0}
+    };
+    return aEndnoteMap_Impl;
+}
+const SfxItemPropertyMap* GetNumberingRulesMap()
+{
+    static SfxItemPropertyMap aNumberingRulesMap_Impl[] =
+    {
+        { SW_PROP_NAME(UNO_NAME_IS_ABSOLUTE_MARGINS),       WID_IS_ABS_MARGINS, &::getBooleanCppuType(),            PROPERTY_NONE,     0},
+        { SW_PROP_NAME(UNO_NAME_IS_AUTOMATIC),              WID_IS_AUTOMATIC,   &::getBooleanCppuType(),            PROPERTY_NONE,     0},
+        { SW_PROP_NAME(UNO_NAME_IS_CONTINUOUS_NUMBERING),   WID_CONTINUOUS,     &::getBooleanCppuType(),            PROPERTY_NONE,     0},
+        { SW_PROP_NAME(UNO_NAME_NAME),                      WID_RULE_NAME   ,   &::getCppuType((const OUString*)0), PropertyAttribute::READONLY,     0},
+        {0,0,0,0}
+    };
+    return aNumberingRulesMap_Impl;
+}
+#define WID_NUM_ON                      0
+#define WID_SEPARATOR_LINE_DISTANCE     1
+#define WID_NUMBERING_TYPE              2
+#define WID_NUMBER_POSITION             3
+#define WID_DISTANCE                    4
+#define WID_LINE_INTERVAL               5
+#define WID_LINE_SEPARATOR              6
+//#define WID_CHARACTER_STYLE             7
+#define WID_COUNT_EMPTY_LINES           8
+#define WID_COUNT_LINES_IN_FRAMES       9
+
+const SfxItemPropertyMap* GetLineNumberingMap()
+{
+    static SfxItemPropertyMap aLineNumberingMap_Impl[] =
+    {
+        { SW_PROP_NAME(UNO_NAME_CHAR_STYLE_NAME),         WID_CHARACTER_STYLE,    &::getCppuType((const OUString*)0), PROPERTY_NONE,     0},
+        { SW_PROP_NAME(UNO_NAME_COUNT_EMPTY_LINES),       WID_COUNT_EMPTY_LINES , &::getBooleanCppuType(),PROPERTY_NONE,     0},
+        { SW_PROP_NAME(UNO_NAME_COUNT_LINES_IN_FRAMES),   WID_COUNT_LINES_IN_FRAMES, &::getBooleanCppuType(),PROPERTY_NONE,     0},
+        { SW_PROP_NAME(UNO_NAME_DISTANCE       ),         WID_DISTANCE       ,    &::getCppuType((const sal_Int32*)0),PROPERTY_NONE,     0},
+        { SW_PROP_NAME(UNO_NAME_LINE_INTERVAL  ),         WID_LINE_INTERVAL  ,    &::getCppuType((const sal_Int16*)0),PROPERTY_NONE,     0},
+        { SW_PROP_NAME(UNO_NAME_LINE_SEPARATOR ),         WID_LINE_SEPARATOR,     &::getCppuType((const OUString*)0), PROPERTY_NONE,     0},
+        { SW_PROP_NAME(UNO_NAME_NUMBER_POSITION),         WID_NUMBER_POSITION,    &::getCppuType((const sal_Int16*)0),PROPERTY_NONE,     0},
+        { SW_PROP_NAME(UNO_NAME_NUMBERING_TYPE),          WID_NUMBERING_TYPE ,    &::getCppuType((const sal_Int16*)0),PROPERTY_NONE,     0},
+        { SW_PROP_NAME(UNO_NAME_ON),                        WID_NUM_ON,             &::getBooleanCppuType()  ,          PROPERTY_NONE,     0},
+        { SW_PROP_NAME(UNO_NAME_SEPARATOR_LINE_DISTANCE), WID_SEPARATOR_LINE_DISTANCE, &::getCppuType((const sal_Int16*)0),PROPERTY_NONE,     0},
+        {0,0,0,0}
+    };
+    return aLineNumberingMap_Impl;
+}
+
+/* -----------------05.05.98 08:30-------------------
+ *
+ * --------------------------------------------------*/
+SwCharFmt* lcl_getCharFmt(SwDoc* pDoc, const uno::Any& aValue)
+{
+    SwCharFmt* pRet = 0;
+    String sStandard(SW_RES(STR_POOLCOLL_STANDARD));
+    OUString uTmp;
+    aValue >>= uTmp;
+    String sCharFmt(SwXStyleFamilies::GetUIName(uTmp, SFX_STYLE_FAMILY_CHAR));
+    if(sStandard != sCharFmt)
+    {
+        pRet = pDoc->FindCharFmtByName( sCharFmt );
+    }
+    if(!pRet)
+    {
+        sal_uInt16 nId = pDoc->GetPoolId(sCharFmt, GET_POOLID_CHRFMT);
+        if(USHRT_MAX != nId)
+            pRet = pDoc->GetCharFmtFromPool( nId );
+    }
+    return pRet;
+}
+/* -----------------05.05.98 08:30-------------------
+ *
+ * --------------------------------------------------*/
+SwTxtFmtColl* lcl_GetParaStyle(SwDoc* pDoc, const uno::Any& aValue)
+{
+    OUString uTmp;
+    aValue >>= uTmp;
+    String sParaStyle(SwXStyleFamilies::GetUIName(uTmp, SFX_STYLE_FAMILY_PARA));
+    SwTxtFmtColl* pRet = pDoc->FindTxtFmtCollByName( sParaStyle );
+    if( !pRet  )
+    {
+        sal_uInt16 nId = pDoc->GetPoolId( sParaStyle, GET_POOLID_TXTCOLL );
+        if( USHRT_MAX != nId  )
+            pRet = pDoc->GetTxtCollFromPool( nId );
+    }
+    return pRet;
+}
+/* -----------------05.05.98 08:30-------------------
+ *
+ * --------------------------------------------------*/
+SwPageDesc* lcl_GetPageDesc(SwDoc* pDoc, const uno::Any& aValue)
+{
+    SwPageDesc* pRet = 0;
+    sal_uInt16 nCount = pDoc->GetPageDescCnt();
+    OUString uTmp;
+    aValue >>= uTmp;
+    String sPageDesc(SwXStyleFamilies::GetUIName(uTmp, SFX_STYLE_FAMILY_PAGE));
+    for( sal_uInt16 i = 0; i < nCount; i++)
+    {
+        const SwPageDesc& rDesc = pDoc->GetPageDesc( i );
+        if(rDesc.GetName() == sPageDesc)
+        {
+            pRet = (SwPageDesc*)&rDesc;
+            break;
+        }
+    }
+    if(!pRet)
+    {
+        sal_uInt16 nId = pDoc->GetPoolId(sPageDesc, GET_POOLID_PAGEDESC);
+        if(USHRT_MAX != nId)
+            pRet = pDoc->GetPageDescFromPool( nId );
+    }
+    return pRet;
+}
+/******************************************************************************
+ *
+ ******************************************************************************/
+// Numerierung
+const unsigned short aSvxToUnoAdjust[] =
+{
+    text::HoriOrientation::LEFT,    //3
+    text::HoriOrientation::RIGHT,  //1
+    USHRT_MAX,
+    text::HoriOrientation::CENTER, //2
+    USHRT_MAX,
+    USHRT_MAX
+};
+
+const unsigned short aUnoToSvxAdjust[] =
+{
+    USHRT_MAX,
+    SVX_ADJUST_RIGHT,       // 1
+    SVX_ADJUST_CENTER,      // 3
+    SVX_ADJUST_LEFT,        // 0
+    USHRT_MAX,
+    USHRT_MAX
+};
+
+/******************************************************************
+ * SwXFootnoteProperties
+ ******************************************************************/
+/* -----------------------------06.04.00 11:43--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXFootnoteProperties::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXFootnoteProperties");
+}
+/* -----------------------------06.04.00 11:43--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXFootnoteProperties::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.text.FootnoteProperties") == rServiceName;
+}
+/* -----------------------------06.04.00 11:43--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXFootnoteProperties::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.FootnoteProperties");
+    return aRet;
+}
+/*-- 14.12.98 14:03:20---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXFootnoteProperties::SwXFootnoteProperties(SwDoc* pDc) :
+    pDoc(pDc),
+    _pMap(GetFootnoteMap())
+{
+}
+/*-- 14.12.98 14:03:20---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXFootnoteProperties::~SwXFootnoteProperties()
+{
+
+}
+/*-- 14.12.98 14:03:20---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< beans::XPropertySetInfo >  SwXFootnoteProperties::getPropertySetInfo(void)
+                                                                throw( uno::RuntimeException )
+{
+    static uno::Reference< beans::XPropertySetInfo >  aRef = new SfxItemPropertySetInfo( _pMap );
+    return aRef;
+}
+/*-- 14.12.98 14:03:20---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFootnoteProperties::setPropertyValue(const OUString& rPropertyName, const uno::Any& aValue)
+    throw( beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(pDoc)
+    {
+        const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                                                        _pMap, rPropertyName);
+        if(pMap)
+        {
+            SwFtnInfo aFtnInfo(pDoc->GetFtnInfo());
+            switch(pMap->nWID)
+            {
+                case WID_PREFIX:
+                {
+                    OUString uTmp;
+                    aValue >>= uTmp;
+                    aFtnInfo.SetPrefix(uTmp);
+                }
+                break;
+                case WID_SUFFIX:
+                {
+                    OUString uTmp;
+                    aValue >>= uTmp;
+                    aFtnInfo.SetSuffix(uTmp);
+                }
+                break;
+                case  WID_NUMBERING_TYPE :
+                {
+                    INT16 nTmp;
+                    aValue >>= nTmp;
+                    aFtnInfo.aFmt.eType = (SvxExtNumType)nTmp;
+                }
+                break;
+                case  WID_START_AT:
+                {
+                    INT16 nTmp;
+                    aValue >>= nTmp;
+                    aFtnInfo.nFtnOffset = nTmp;
+                }
+                break;
+                case  WID_FOOTNOTE_COUNTING  :
+                {
+                    sal_uInt16 nRet = 0;
+                    INT16 nTmp;
+                    aValue >>= nTmp;
+                    switch(nTmp)
+                    {
+                        case  text::FootnoteNumbering::PER_PAGE:
+                            aFtnInfo.eNum = FTNNUM_PAGE;
+                        break;
+                        case  text::FootnoteNumbering::PER_CHAPTER:
+                            aFtnInfo.eNum = FTNNUM_CHAPTER;
+                        break;
+                        case  text::FootnoteNumbering::PER_DOCUMENT:
+                            aFtnInfo.eNum = FTNNUM_DOC;
+                        break;
+                    }
+                }
+                break;
+                case  WID_PARAGRAPH_STYLE    :
+                {
+                    SwTxtFmtColl* pColl = lcl_GetParaStyle(pDoc, aValue);
+                    if(pColl)
+                        aFtnInfo.SetFtnTxtColl(*pColl);
+                }
+                break;
+                case  WID_PAGE_STYLE :
+                {
+                    SwPageDesc* pDesc = lcl_GetPageDesc(pDoc, aValue);
+                    if(pDesc)
+                        aFtnInfo.ChgPageDesc( pDesc );
+                }
+                break;
+                case WID_ANCHOR_CHARACTER_STYLE:
+                case  WID_CHARACTER_STYLE    :
+                {
+                    SwCharFmt* pFmt = lcl_getCharFmt(pDoc, aValue);
+                    if(pFmt)
+                    {
+                        if(pMap->nWID == WID_ANCHOR_CHARACTER_STYLE)
+                            aFtnInfo.SetAnchorCharFmt(pFmt);
+                        else
+                            aFtnInfo.SetCharFmt(pFmt);
+                    }
+                }
+                break;
+                case  WID_POSITION_END_OF_DOC:
+                {
+                    sal_Bool bVal = *(sal_Bool*)aValue.getValue();
+                    aFtnInfo.ePos = bVal ? FTNPOS_CHAPTER : FTNPOS_PAGE;
+                }
+                break;
+                case  WID_END_NOTICE         :
+                {
+                    OUString uTmp;
+                    aValue >>= uTmp;
+                    aFtnInfo.aQuoVadis = String(uTmp);
+                }
+                break;
+                case  WID_BEGIN_NOTICE       :
+                {
+                    OUString uTmp;
+                    aValue >>= uTmp;
+                    aFtnInfo.aErgoSum = String(uTmp);
+                }
+                break;
+            }
+            pDoc->SetFtnInfo(aFtnInfo);
+        }
+        else
+            throw lang::IllegalArgumentException();
+    }
+    else
+        throw uno::RuntimeException();
+}
+/*-- 14.12.98 14:03:21---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXFootnoteProperties::getPropertyValue(const OUString& rPropertyName)
+    throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Any aRet;
+    if(pDoc)
+    {
+        const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                                                        _pMap, rPropertyName);
+        if(pMap)
+        {
+            const SwFtnInfo& rFtnInfo = pDoc->GetFtnInfo();
+            switch(pMap->nWID)
+            {
+                case WID_PREFIX:
+                {
+                    aRet <<= OUString(rFtnInfo.GetPrefix());
+                }
+                break;
+                case WID_SUFFIX:
+                {
+                    aRet <<= OUString(rFtnInfo.GetSuffix());
+                }
+                break;
+                case  WID_NUMBERING_TYPE :
+                {
+                    aRet <<= (sal_Int16)rFtnInfo.aFmt.eType;
+                }
+                break;
+                case  WID_START_AT:
+                    aRet <<= (sal_Int16)rFtnInfo.nFtnOffset;
+                break;
+                case  WID_FOOTNOTE_COUNTING  :
+                {
+                    sal_Int16 nRet = 0;
+                    switch(rFtnInfo.eNum)
+                    {
+                        case  FTNNUM_PAGE:
+                            nRet = text::FootnoteNumbering::PER_PAGE;
+                        break;
+                        case  FTNNUM_CHAPTER:
+                            nRet = text::FootnoteNumbering::PER_CHAPTER;
+                        break;
+                        case  FTNNUM_DOC:
+                            nRet = text::FootnoteNumbering::PER_DOCUMENT;
+                        break;
+                    }
+                    aRet <<= nRet;
+                }
+                break;
+                case  WID_PARAGRAPH_STYLE    :
+                {
+                    SwTxtFmtColl* pColl = rFtnInfo.GetFtnTxtColl();
+                    OUString sRet;
+                    if(pColl)
+                        sRet = pColl->GetName();
+                    sRet = SwXStyleFamilies::GetProgrammaticName(sRet, SFX_STYLE_FAMILY_PARA);
+                    aRet <<= sRet;
+                }
+                break;
+                case  WID_PAGE_STYLE :
+                {
+                    aRet <<= OUString(
+                        SwXStyleFamilies::GetProgrammaticName(
+                            rFtnInfo.GetPageDesc( *pDoc )->GetName(),
+                            SFX_STYLE_FAMILY_PAGE));
+                }
+                break;
+                case WID_ANCHOR_CHARACTER_STYLE:
+                case WID_CHARACTER_STYLE:
+                {
+                    const SwCharFmt* pCharFmt = pMap->nWID == WID_ANCHOR_CHARACTER_STYLE ?
+                            rFtnInfo.GetAnchorCharFmt(*pDoc) : rFtnInfo.GetCharFmt(*pDoc);
+                    aRet <<= OUString(
+                        SwXStyleFamilies::GetProgrammaticName(pCharFmt->GetName(), SFX_STYLE_FAMILY_CHAR));
+                }
+                break;
+                case  WID_POSITION_END_OF_DOC:
+                {
+                    sal_Bool bTemp = FTNPOS_CHAPTER == rFtnInfo.ePos;
+                    aRet.setValue(&bTemp, ::getCppuBooleanType());
+                }
+                break;
+                case  WID_END_NOTICE         :
+                    aRet <<= OUString(rFtnInfo.aQuoVadis);
+                break;
+                case  WID_BEGIN_NOTICE       :
+                    aRet <<= OUString(rFtnInfo.aErgoSum);
+                break;
+            }
+        }
+        else
+            throw lang::IllegalArgumentException();
+
+    }
+    else
+        throw uno::RuntimeException();
+    return aRet;
+}
+/*-- 14.12.98 14:03:21---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFootnoteProperties::addPropertyChangeListener(
+    const OUString& PropertyName, const uno::Reference< beans::XPropertyChangeListener > & aListener)
+        throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 14.12.98 14:03:21---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFootnoteProperties::removePropertyChangeListener(
+    const OUString& PropertyName, const uno::Reference< beans::XPropertyChangeListener > & aListener)
+        throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 14.12.98 14:03:21---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFootnoteProperties::addVetoableChangeListener(
+    const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener > & aListener)
+        throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 14.12.98 14:03:22---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXFootnoteProperties::removeVetoableChangeListener(
+    const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener > & aListener)
+        throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+
+/******************************************************************
+ * SwXEndnoteProperties
+ ******************************************************************/
+/* -----------------------------06.04.00 11:45--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXEndnoteProperties::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXEndnoteProperties");
+}
+/* -----------------------------06.04.00 11:45--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXEndnoteProperties::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.text.EndnoteProperties") == rServiceName;
+}
+/* -----------------------------06.04.00 11:45--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXEndnoteProperties::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.EndnoteProperties");
+    return aRet;
+}
+/*-- 14.12.98 14:27:39---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXEndnoteProperties::SwXEndnoteProperties(SwDoc* pDc) :
+    pDoc(pDc),
+    _pMap(GetEndnoteMap())
+{
+
+}
+/*-- 14.12.98 14:27:39---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXEndnoteProperties::~SwXEndnoteProperties()
+{
+
+}
+/*-- 14.12.98 14:27:40---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< beans::XPropertySetInfo >  SwXEndnoteProperties::getPropertySetInfo(void) throw( uno::RuntimeException )
+{
+    static uno::Reference< beans::XPropertySetInfo >  aRef = new SfxItemPropertySetInfo( _pMap );
+    return aRef;
+}
+/*-- 14.12.98 14:27:40---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXEndnoteProperties::setPropertyValue(const OUString& rPropertyName, const uno::Any& aValue)
+    throw( beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException,
+        lang::WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(pDoc)
+    {
+        const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                                                        _pMap, rPropertyName);
+        if(pMap)
+        {
+            SwEndNoteInfo aEndInfo(pDoc->GetEndNoteInfo());
+            switch(pMap->nWID)
+            {
+                case WID_PREFIX:
+                {
+                    OUString uTmp;
+                    aValue >>= uTmp;
+                    aEndInfo.SetPrefix(uTmp);
+                }
+                break;
+                case WID_SUFFIX:
+                {
+                    OUString uTmp;
+                    aValue >>= uTmp;
+                    aEndInfo.SetSuffix(uTmp);
+                }
+                break;
+                case  WID_NUMBERING_TYPE :
+                {
+                    INT16 nTmp;
+                    aValue >>= nTmp;
+                    aEndInfo.aFmt.eType = (SvxExtNumType)nTmp;
+                }
+                break;
+                case  WID_START_AT:
+                {
+                    INT16 nTmp;
+                    aValue >>= nTmp;
+                    aEndInfo.nFtnOffset = nTmp;
+                }
+                break;
+                case  WID_PARAGRAPH_STYLE    :
+                {
+                    SwTxtFmtColl* pColl = lcl_GetParaStyle(pDoc, aValue);
+                    if(pColl)
+                        aEndInfo.SetFtnTxtColl(*pColl);
+                }
+                break;
+                case  WID_PAGE_STYLE :
+                {
+                    SwPageDesc* pDesc = lcl_GetPageDesc(pDoc, aValue);
+                    if(pDesc)
+                        aEndInfo.ChgPageDesc( pDesc );
+                }
+                break;
+                case  WID_CHARACTER_STYLE    :
+                {
+                    SwCharFmt* pFmt = lcl_getCharFmt(pDoc, aValue);
+                    if(pFmt)
+                        aEndInfo.SetCharFmt(pFmt);
+                }
+                break;
+            }
+            pDoc->SetEndNoteInfo(aEndInfo);
+        }
+    }
+}
+/*-- 14.12.98 14:27:41---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXEndnoteProperties::getPropertyValue(const OUString& rPropertyName)
+    throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Any aRet;
+    if(pDoc)
+    {
+        const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                                                        _pMap, rPropertyName);
+        if(pMap)
+        {
+            const SwEndNoteInfo& rEndInfo = pDoc->GetEndNoteInfo();
+            switch(pMap->nWID)
+            {
+                case WID_PREFIX:
+                    aRet <<= OUString(rEndInfo.GetPrefix());
+                break;
+                case WID_SUFFIX:
+                    aRet <<= OUString(rEndInfo.GetSuffix());
+                break;
+                case  WID_NUMBERING_TYPE :
+                    aRet <<= (sal_Int16)rEndInfo.aFmt.eType;
+                break;
+                case  WID_START_AT:
+                    aRet <<= (sal_Int16)rEndInfo.nFtnOffset;
+                break;
+                case  WID_PARAGRAPH_STYLE    :
+                {
+                    SwTxtFmtColl* pColl = rEndInfo.GetFtnTxtColl();
+                    OUString sRet;
+                    if(pColl)
+                        sRet = pColl->GetName();
+                    aRet <<= OUString(
+                        SwXStyleFamilies::GetProgrammaticName(sRet,
+                            SFX_STYLE_FAMILY_PARA));
+
+                }
+                break;
+                case  WID_PAGE_STYLE :
+                {
+                    aRet <<= OUString(
+                        SwXStyleFamilies::GetProgrammaticName(
+                            rEndInfo.GetPageDesc( *pDoc )->GetName(),
+                            SFX_STYLE_FAMILY_PAGE));
+                }
+                break;
+                case  WID_CHARACTER_STYLE    :
+                {
+                    const SwCharFmt* pCharFmt = rEndInfo.GetCharFmt(*pDoc);
+                    aRet <<= OUString(
+                        SwXStyleFamilies::GetProgrammaticName(pCharFmt->GetName(), SFX_STYLE_FAMILY_CHAR));
+                }
+                break;
+            }
+        }
+    }
+    return aRet;
+}
+/*-- 14.12.98 14:27:41---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXEndnoteProperties::addPropertyChangeListener(
+    const OUString& PropertyName, const uno::Reference< beans::XPropertyChangeListener > & aListener) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 14.12.98 14:27:41---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXEndnoteProperties::removePropertyChangeListener(const OUString& PropertyName,
+        const uno:: Reference< beans::XPropertyChangeListener > & aListener)
+        throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 14.12.98 14:27:41---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXEndnoteProperties::addVetoableChangeListener(const OUString& PropertyName,
+    const uno:: Reference< beans::XVetoableChangeListener > & aListener)
+    throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 14.12.98 14:27:42---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXEndnoteProperties::removeVetoableChangeListener(const OUString& PropertyName, const uno:: Reference< beans::XVetoableChangeListener > & aListener)
+    throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/******************************************************************
+ * SwXLineNumberingProperties
+ ******************************************************************/
+/* -----------------------------06.04.00 11:47--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXLineNumberingProperties::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXLineNumberingProperties");
+}
+/* -----------------------------06.04.00 11:47--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXLineNumberingProperties::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.text.LineNumberingSettings") == rServiceName;
+}
+/* -----------------------------06.04.00 11:47--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXLineNumberingProperties::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.LineNumberingSettings");
+    return aRet;
+}
+/*-- 14.12.98 14:33:36---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXLineNumberingProperties::SwXLineNumberingProperties(SwDoc* pDc) :
+    pDoc(pDc),
+    _pMap(GetLineNumberingMap())
+{
+
+}
+/*-- 14.12.98 14:33:37---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXLineNumberingProperties::~SwXLineNumberingProperties()
+{
+
+}
+/*-- 14.12.98 14:33:37---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< beans::XPropertySetInfo >  SwXLineNumberingProperties::getPropertySetInfo(void) throw( uno::RuntimeException )
+{
+    static uno::Reference< beans::XPropertySetInfo >  aRef = new SfxItemPropertySetInfo( _pMap );
+    return aRef;
+}
+/*-- 14.12.98 14:33:37---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXLineNumberingProperties::setPropertyValue(
+    const OUString& rPropertyName, const Any& aValue)
+        throw( UnknownPropertyException, PropertyVetoException,
+                IllegalArgumentException, WrappedTargetException, RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(pDoc)
+    {
+        const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                                                        _pMap, rPropertyName);
+        if(pMap)
+        {
+            SwLineNumberInfo  aInfo(pDoc->GetLineNumberInfo());
+            switch(pMap->nWID)
+            {
+                case WID_NUM_ON:
+                {
+                    sal_Bool bVal = *(sal_Bool*)aValue.getValue();
+                    aInfo.SetPaintLineNumbers(bVal);
+                }
+                break;
+                case WID_CHARACTER_STYLE :
+                {
+                    SwCharFmt* pFmt = lcl_getCharFmt(pDoc, aValue);
+                    if(pFmt)
+                        aInfo.SetCharFmt(pFmt);
+                }
+                break;
+                case WID_NUMBERING_TYPE  :
+                {
+                    SwNumType aNumType(aInfo.GetNumType());
+                    INT16 nTmp;
+                    aValue >>= nTmp;
+                    aNumType.eType = (SvxExtNumType)nTmp;
+                    aInfo.SetNumType(aNumType);
+                }
+                break;
+                case WID_NUMBER_POSITION :
+                {
+                    INT16 nTmp;
+                    aValue >>= nTmp;
+                    switch(nTmp)
+                    {
+                        case  style::LineNumberPosition::LEFT:
+                             aInfo.SetPos(LINENUMBER_POS_LEFT); ;
+                        break;
+                        case style::LineNumberPosition::RIGHT :
+                             aInfo.SetPos(LINENUMBER_POS_RIGHT);       ;
+                        break;
+                        case  style::LineNumberPosition::INSIDE:
+                            aInfo.SetPos(LINENUMBER_POS_INSIDE);      ;
+                        break;
+                        case  style::LineNumberPosition::OUTSIDE:
+                            aInfo.SetPos(LINENUMBER_POS_OUTSIDE);
+                        break;
+                    }
+                }
+                break;
+                case WID_DISTANCE        :
+                {
+                    INT32 nVal;
+                    aValue >>= nVal;
+                    aInfo.SetPosFromLeft(Min(nVal, sal_Int32(0xffff)));
+                }
+                break;
+                case WID_LINE_INTERVAL   :
+                {
+                    INT16 nTmp;
+                    aValue >>= nTmp;
+                    aInfo.SetCountBy(nTmp);
+                }
+                break;
+                case WID_LINE_SEPARATOR  :
+                {
+                    OUString uTmp;
+                    aValue >>= uTmp;
+                    aInfo.SetDivider(uTmp);
+                }
+                break;
+                case WID_SEPARATOR_LINE_DISTANCE:
+                {
+                    INT16 nTmp;
+                    aValue >>= nTmp;
+                    aInfo.SetDividerCountBy(nTmp);
+                }
+                break;
+                case WID_COUNT_EMPTY_LINES :
+                {
+                    sal_Bool bVal = *(sal_Bool*)aValue.getValue();
+                    aInfo.SetCountBlankLines(bVal);
+                }
+                break;
+                case WID_COUNT_LINES_IN_FRAMES :
+                {
+                    sal_Bool bVal = *(sal_Bool*)aValue.getValue();
+                    aInfo.SetCountInFlys(bVal);
+                }
+                break;
+            }
+            pDoc->SetLineNumberInfo(aInfo);
+        }
+        else
+            throw beans::UnknownPropertyException();
+    }
+    else
+        throw uno::RuntimeException();
+}
+/*-- 14.12.98 14:33:38---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Any SwXLineNumberingProperties::getPropertyValue(const OUString& rPropertyName)
+    throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    Any aRet;
+    if(pDoc)
+    {
+        const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                                                        _pMap, rPropertyName);
+        if(pMap)
+        {
+            const SwLineNumberInfo& rInfo = pDoc->GetLineNumberInfo();
+            switch(pMap->nWID)
+            {
+                case WID_NUM_ON:
+                {
+                    sal_Bool bTemp = rInfo.IsPaintLineNumbers();
+                    aRet.setValue(&bTemp, ::getCppuBooleanType());
+                }
+                break;
+                case WID_CHARACTER_STYLE :
+                    aRet <<= OUString(rInfo.GetCharFmt(*pDoc)->GetName());
+                break;
+                case WID_NUMBERING_TYPE  :
+                    aRet <<= (sal_Int16)rInfo.GetNumType().eType;
+                break;
+                case WID_NUMBER_POSITION :
+                {
+                    sal_Int16 nRet = 0;
+                    switch(rInfo.GetPos())
+                    {
+                        case  LINENUMBER_POS_LEFT:
+                            nRet = style::LineNumberPosition::LEFT;
+                        break;
+                        case LINENUMBER_POS_RIGHT :
+                            nRet = style::LineNumberPosition::RIGHT      ;
+                        break;
+                        case  LINENUMBER_POS_INSIDE:
+                            nRet = style::LineNumberPosition::INSIDE     ;
+                        break;
+                        case LINENUMBER_POS_OUTSIDE :
+                            nRet = style::LineNumberPosition::OUTSIDE    ;
+                        break;
+                    }
+                    aRet <<= nRet;
+                }
+                break;
+                case WID_DISTANCE        :
+                {
+                    sal_uInt32 nPos = rInfo.GetPosFromLeft();
+                    if(USHRT_MAX == nPos)
+                        nPos = 0;
+                    aRet <<= nPos;
+                }
+                break;
+                case WID_LINE_INTERVAL   :
+                    aRet <<= (sal_Int16)rInfo.GetCountBy();
+                break;
+                case WID_LINE_SEPARATOR  :
+                    aRet <<= OUString(rInfo.GetDivider());
+                break;
+                case WID_SEPARATOR_LINE_DISTANCE:
+                    aRet <<= (sal_Int16)rInfo.GetDividerCountBy();
+                break;
+                case WID_COUNT_EMPTY_LINES :
+                {
+                    sal_Bool bTemp = rInfo.IsCountBlankLines();
+                    aRet.setValue(&bTemp, ::getCppuBooleanType());
+                }
+                break;
+                case WID_COUNT_LINES_IN_FRAMES :
+                {
+                    sal_Bool bTemp = rInfo.IsCountInFlys();
+                    aRet.setValue(&bTemp, ::getCppuBooleanType());
+                }
+                break;
+            }
+        }
+        else
+            throw beans::UnknownPropertyException();
+    }
+    else
+        throw uno::RuntimeException();
+    return aRet;
+}
+/*-- 14.12.98 14:33:38---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXLineNumberingProperties::addPropertyChangeListener(const OUString& PropertyName, const uno:: Reference< beans::XPropertyChangeListener > & aListener) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+DBG_WARNING("not implemented")
+}
+/*-- 14.12.98 14:33:38---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXLineNumberingProperties::removePropertyChangeListener(const OUString& PropertyName, const uno:: Reference< beans::XPropertyChangeListener > & aListener) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+DBG_WARNING("not implemented")
+}
+/*-- 14.12.98 14:33:39---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXLineNumberingProperties::addVetoableChangeListener(const OUString& PropertyName, const uno:: Reference< beans::XVetoableChangeListener > & aListener) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+DBG_WARNING("not implemented")
+}
+/*-- 14.12.98 14:33:39---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXLineNumberingProperties::removeVetoableChangeListener(const OUString& PropertyName, const uno:: Reference< beans::XVetoableChangeListener > & aListener)
+    throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
+{
+DBG_WARNING("not implemented")
+}
+/******************************************************************
+ * SwXNumberingRules
+ ******************************************************************/
+String  SwXNumberingRules::sInvalidStyle(String::CreateFromAscii("__XXX___invalid"));
+
+const String&   SwXNumberingRules::GetInvalidStyle()
+{
+    return sInvalidStyle;
+}
+/* -----------------------------10.03.00 17:05--------------------------------
+
+ ---------------------------------------------------------------------------*/
+const uno::Sequence< sal_Int8 > & SwXNumberingRules::getUnoTunnelId()
+{
+    static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId();
+    return aSeq;
+}
+/* -----------------------------10.03.00 17:05--------------------------------
+
+ ---------------------------------------------------------------------------*/
+// return implementation specific data
+sal_Int64 SwXNumberingRules::getSomething( const uno::Sequence< sal_Int8 > & rId ) throw(::com::sun::star::uno::RuntimeException)
+{
+    if( rId.getLength() == 16
+        && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+                                        rId.getConstArray(), 16 ) )
+        {
+                return (sal_Int64)this;
+        }
+    return 0;
+}
+
+/* -----------------------------06.04.00 11:47--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXNumberingRules::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXNumberingRules");
+}
+/* -----------------------------06.04.00 11:47--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXNumberingRules::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.text.NumberingRules") == rServiceName;
+}
+/* -----------------------------06.04.00 11:47--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXNumberingRules::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.NumberingRules");
+    return aRet;
+}
+/*-- 14.12.98 14:57:56---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXNumberingRules::SwXNumberingRules() :
+    pNumRule(0),
+    pDoc(0),
+    pDocShell(0),
+    _pMap(GetNumberingRulesMap())
+{
+    for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
+    {
+        sNewCharStyleNames[i] = SwXNumberingRules::GetInvalidStyle();
+        sNewBulletFontNames[i] = SwXNumberingRules::GetInvalidStyle();
+    }
+
+}
+/*-- 14.12.98 14:57:57---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXNumberingRules::SwXNumberingRules(const SwNumRule& rRule) :
+    pNumRule(new SwNumRule(rRule)),
+    pDoc(0),
+    pDocShell(0),
+    _pMap(GetNumberingRulesMap())
+{
+    //erstmal das Doc organisieren; es haengt an den gesetzten Zeichenvorlagen - wenn
+    // keine gesetzt sind, muss es auch ohne gehen
+    for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
+    {
+        SwNumFmt rFmt(pNumRule->Get(i));
+        SwCharFmt* pCharFmt = rFmt.GetCharFmt();
+        if(pCharFmt)
+        {
+            pDoc = pCharFmt->GetDoc();
+            break;
+        }
+    }
+    if(pDoc)
+        pDoc->GetPageDescFromPool(RES_POOLPAGE_STANDARD)->Add(this);
+    for(i = 0; i < MAXLEVEL; i++)
+    {
+        sNewCharStyleNames[i] = SwXNumberingRules::GetInvalidStyle();
+        sNewBulletFontNames[i] = SwXNumberingRules::GetInvalidStyle();
+    }
+}
+/* -----------------22.02.99 16:35-------------------
+ *
+ * --------------------------------------------------*/
+SwXNumberingRules::SwXNumberingRules(SwDocShell& rDocSh) :
+    pDoc(0),
+    pNumRule(0),
+    pDocShell(&rDocSh),
+    _pMap(GetNumberingRulesMap())
+{
+    pDocShell->GetDoc()->GetPageDescFromPool(RES_POOLPAGE_STANDARD)->Add(this);
+}
+/* -----------------------------24.08.00 11:36--------------------------------
+
+ ---------------------------------------------------------------------------*/
+SwXNumberingRules::SwXNumberingRules(SwDoc& rDoc) :
+    pDoc(&rDoc),
+    pNumRule(0),
+    pDocShell(0),
+    _pMap(GetNumberingRulesMap())
+{
+    rDoc.GetPageDescFromPool(RES_POOLPAGE_STANDARD)->Add(this);
+    sCreatedNumRuleName = rDoc.GetUniqueNumRuleName();
+    sal_uInt16 nIndex = rDoc.MakeNumRule( sCreatedNumRuleName, 0 );
+}
+
+/* -----------------28.10.99 09:40-------------------
+
+ --------------------------------------------------*/
+SwXNumberingRules::SwXNumberingRules(SwDoc& rDoc, const String& rName) :
+    pNumRule(new SwNumRule(rName)),
+    pDoc(&rDoc),
+    pDocShell(0),
+    _pMap(GetNumberingRulesMap())
+{
+    pDoc->GetPageDescFromPool(RES_POOLPAGE_STANDARD)->Add(this);
+}
+/*-- 14.12.98 14:57:57---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXNumberingRules::~SwXNumberingRules()
+{
+    delete pNumRule;
+}
+/*-- 14.12.98 14:57:58---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXNumberingRules::replaceByIndex(sal_Int32 nIndex, const uno::Any& rElement)
+    throw( lang::IllegalArgumentException, lang::IndexOutOfBoundsException,
+                  lang::WrappedTargetException, uno::RuntimeException)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(rElement.getValueType().getTypeClass() != uno::TypeClass_SEQUENCE)
+        throw lang::IllegalArgumentException();
+    const uno::Sequence& rProperties =
+                    *(const uno::Sequence*)rElement.getValue();
+    if(pNumRule)
+        SwXNumberingRules::setNumberingRuleByIndex( *pNumRule,
+                            rProperties, nIndex);
+    else if(pDocShell)
+    {
+        const SwNumRule* pNumRule = pDocShell->GetDoc()->GetOutlineNumRule();
+        SwNumRule aNumRule(*pNumRule);
+        SwXNumberingRules::setNumberingRuleByIndex( aNumRule,
+                            rProperties, nIndex);
+        //hier noch die Zeichenformate bei Bedarf setzen
+        const SwCharFmts* pFmts = pDocShell->GetDoc()->GetCharFmts();
+        sal_uInt16 nChCount = pFmts->Count();
+        for(sal_uInt16 i = 0; i < MAXLEVEL;i++)
+        {
+            SwNumFmt aFmt(aNumRule.Get( i ));
+            if(sNewCharStyleNames[i].Len() &&
+                COMPARE_EQUAL != sNewCharStyleNames[i].CompareToAscii(UNO_NAME_CHARACTER_FORMAT_NONE) &&
+                   (!aFmt.GetCharFmt() ||
+                    aFmt.GetCharFmt()->GetName()!= sNewCharStyleNames[i] ))
+            {
+                SwCharFmt* pCharFmt = 0;
+                for(sal_uInt16 j = 0; j< nChCount; j++)
+                {
+                    SwCharFmt* pTmp = (*pFmts)[j];
+                    if(pTmp->GetName() == sNewCharStyleNames[i])
+                    {
+                        pCharFmt = pTmp;
+                        break;
+                    }
+                }
+                if(!pCharFmt)
+                {
+                    SfxStyleSheetBase* pBase;
+                    pBase = pDocShell->GetStyleSheetPool()->Find(sNewCharStyleNames[i],
+                                                                    SFX_STYLE_FAMILY_CHAR);
+                    if(!pBase)
+                        pBase = &pDocShell->GetStyleSheetPool()->Make(sNewCharStyleNames[i], SFX_STYLE_FAMILY_CHAR);
+                    pCharFmt = ((SwDocStyleSheet*)pBase)->GetCharFmt();
+
+                }
+                aFmt.SetCharFmt( pCharFmt );
+                aNumRule.Set( i, aFmt );
+            }
+        }
+        pDocShell->GetDoc()->SetOutlineNumRule( aNumRule );
+    }
+    else
+        throw uno::RuntimeException();
+
+}
+/*-- 14.12.98 14:57:58---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Int32 SwXNumberingRules::getCount(void) throw( uno::RuntimeException )
+{
+    return MAXLEVEL;
+}
+/*-- 14.12.98 14:57:58---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXNumberingRules::getByIndex(sal_Int32 nIndex)
+    throw( lang::IndexOutOfBoundsException, lang::WrappedTargetException,
+            uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Any aVal;
+    if(MAXLEVEL <= nIndex)
+        throw lang::IndexOutOfBoundsException();
+    if(pNumRule)
+    {
+        uno::Sequence aRet = getNumberingRuleByIndex(
+                                        *pNumRule, nIndex);
+        aVal.setValue(&aRet, ::getCppuType((uno::Sequence*)0));
+
+    }
+    else if(pDocShell)
+    {
+        uno::Sequence aRet = getNumberingRuleByIndex(
+                *pDocShell->GetDoc()->GetOutlineNumRule(), nIndex);
+        aVal.setValue(&aRet, ::getCppuType((uno::Sequence*)0));
+    }
+    else
+        throw uno::RuntimeException();
+    return aVal;
+}
+/*-- 14.12.98 14:57:59---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Type SwXNumberingRules::getElementType(void)
+    throw( uno::RuntimeException )
+{
+    return ::getCppuType((uno::Sequence*)0);
+}
+/*-- 14.12.98 14:57:59---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXNumberingRules::hasElements(void) throw( uno::RuntimeException )
+{
+    return sal_True;
+}
+/*-- 14.12.98 14:57:59---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Sequence SwXNumberingRules::getNumberingRuleByIndex(
+                const SwNumRule& rNumRule, sal_Int32 nIndex) const
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    const SwNumFmt& rFmt = rNumRule.Get( (sal_uInt16)nIndex );
+
+    sal_Bool bChapterNum = pDocShell != 0;
+
+    PropValDataArr  aPropertyValues;
+    //fill all properties into the array
+
+    //adjust
+    SvxAdjust eAdj = rFmt.GetAdjust();
+    sal_Int16 nINT16 = aSvxToUnoAdjust[(sal_uInt16)eAdj];
+    PropValData* pData = new PropValData((void*)&nINT16, "Adjust", ::getCppuType((const sal_Int16*)0) );
+    aPropertyValues.Insert(pData, aPropertyValues.Count());
+
+    //parentnumbering
+    nINT16 = rFmt.GetUpperLevel();
+    pData = new PropValData((void*)&nINT16, "ParentNumbering", ::getCppuType((const sal_Int16*)0));
+    aPropertyValues.Insert(pData, aPropertyValues.Count());
+
+    //prefix
+    OUString aUString = rFmt.GetPrefix();
+    pData = new PropValData((void*)&aUString, "Prefix", ::getCppuType((const OUString*)0));
+    aPropertyValues.Insert(pData, aPropertyValues.Count());
+
+    //suffix
+    aUString = rFmt.GetPostfix();
+    pData = new PropValData((void*)&aUString, "Suffix", ::getCppuType((const OUString*)0));
+    aPropertyValues.Insert(pData, aPropertyValues.Count());
+
+    //char style name
+    SwCharFmt* pCharFmt = rFmt.GetCharFmt();
+    String CharStyleName;
+    if(pCharFmt)
+        CharStyleName = pCharFmt->GetName();
+    //egal ob ein Style vorhanden ist oder nicht ueberschreibt der Array-Eintrag diesen String
+    if(sNewCharStyleNames[(sal_uInt16)nIndex].Len() &&
+        SwXNumberingRules::sInvalidStyle != sNewCharStyleNames[(sal_uInt16)nIndex])
+        CharStyleName = sNewCharStyleNames[(sal_uInt16)nIndex];
+
+    aUString = SwXStyleFamilies::GetProgrammaticName( CharStyleName,
+                                                      SFX_STYLE_FAMILY_CHAR );
+    pData = new PropValData((void*)&aUString, "CharStyleName", ::getCppuType((const OUString*)0));
+    aPropertyValues.Insert(pData, aPropertyValues.Count());
+
+    //startvalue
+    nINT16 = rFmt.GetStartValue();
+    pData = new PropValData((void*)&nINT16, "StartWith", ::getCppuType((const sal_Int16*)0));
+    aPropertyValues.Insert(pData, aPropertyValues.Count());
+
+    //leftmargin
+    sal_Int32 nINT32 = TWIP_TO_MM100(rFmt.GetAbsLSpace());
+    pData = new PropValData((void*)&nINT32, UNO_NAME_LEFT_MARGIN, ::getCppuType((const sal_Int32*)0));
+    aPropertyValues.Insert(pData, aPropertyValues.Count());
+
+    //chartextoffset
+    nINT32 = TWIP_TO_MM100(rFmt.GetCharTextOffset());
+    pData = new PropValData((void*)&nINT32, UNO_NAME_SYMBOL_TEXT_DISTANCE, ::getCppuType((const sal_Int32*)0));
+    aPropertyValues.Insert(pData, aPropertyValues.Count());
+
+    //firstlineoffset
+    nINT32 = TWIP_TO_MM100(rFmt.GetFirstLineOffset());
+    pData = new PropValData((void*)&nINT32, UNO_NAME_FIRST_LINE_OFFSET, ::getCppuType((const sal_Int32*)0));
+    aPropertyValues.Insert(pData, aPropertyValues.Count());
+
+    //TODO: Enum fuer NumberingType erweitern
+    //
+    nINT16 = rFmt.eType;
+    pData = new PropValData((void*)&nINT16, "NumberingType", ::getCppuType((const sal_Int16*)0));
+    aPropertyValues.Insert(pData, aPropertyValues.Count());
+
+    if(!bChapterNum)
+    {
+        if(SVX_NUM_CHAR_SPECIAL == rFmt.eType)
+        {
+            //BulletId
+            nINT16 = rFmt.GetBulletChar();
+            pData = new PropValData((void*)&nINT16, "BulletId", ::getCppuType((const sal_Int16*)0));
+            aPropertyValues.Insert(pData, aPropertyValues.Count());
+
+            const Font* pFont = rFmt.GetBulletFont();
+
+            //BulletChar
+            aUString = OUString(rFmt.GetBulletChar());
+            pData = new PropValData((void*)&aUString, "BulletChar", ::getCppuType((const OUString*)0));
+            aPropertyValues.Insert(pData, aPropertyValues.Count());
+
+            //BulletFontName
+            String sBulletFontName;
+            if(pFont)
+                sBulletFontName = pFont->GetStyleName();
+            aUString = sBulletFontName;
+            pData = new PropValData((void*)&aUString, "BulletFontName", ::getCppuType((const OUString*)0));
+            aPropertyValues.Insert(pData, aPropertyValues.Count());
+
+            //BulletFont
+            if(pFont)
+            {
+                 awt::FontDescriptor aDesc;
+                SvxUnoFontDescriptor::ConvertFromFont( *pFont, aDesc );
+                pData = new PropValData((void*)&aDesc, UNO_NAME_BULLET_FONT, ::getCppuType((const awt::FontDescriptor*)0));
+                aPropertyValues.Insert(pData, aPropertyValues.Count());
+            }
+        }
+        if(SVX_NUM_BITMAP == rFmt.eType)
+        {
+            //GraphicURL
+            String sGrURL;
+            const SvxBrushItem* pBrush = rFmt.GetGrfBrush();
+                if(pBrush && pBrush->GetGraphicLink())
+                sGrURL = *pBrush->GetGraphicLink();
+            aUString = sGrURL;
+            pData = new PropValData((void*)&aUString, UNO_NAME_GRAPHIC_URL, ::getCppuType((const OUString*)0));
+            aPropertyValues.Insert(pData, aPropertyValues.Count());
+
+            //graphicbitmap
+            const Graphic* pGraphic = 0;
+            if(pBrush )
+                pGraphic = pBrush->GetGraphic();
+            if(pGraphic)
+            {
+                uno::Reference xBmp = VCLUnoHelper::CreateBitmap( pGraphic->GetBitmapEx() );
+                pData = new PropValData((void*)&xBmp, UNO_NAME_GRAPHIC_BITMAP,
+                                ::getCppuType((const uno::Reference*)0));
+                aPropertyValues.Insert(pData, aPropertyValues.Count());
+            }
+             Size aSize = rFmt.GetGrfSize();
+            aSize.Width() = TWIP_TO_MM100( aSize.Width() );
+            aSize.Height() = TWIP_TO_MM100( aSize.Height() );
+            pData = new PropValData((void*)&aSize, UNO_NAME_GRAPHIC_SIZE, ::getCppuType((const awt::Size*)0));
+            aPropertyValues.Insert(pData, aPropertyValues.Count());
+
+            const SwFmtVertOrient* pOrient = rFmt.GetGrfOrient();
+            if(pOrient)
+            {
+                pData = new PropValData((void*)0, UNO_NAME_VERT_ORIENT, ::getCppuType((const sal_Int16*)0));
+                ((const SfxPoolItem*)pOrient)->QueryValue(pData->aVal, MID_VERTORIENT_ORIENT);
+                aPropertyValues.Insert(pData, aPropertyValues.Count());
+            }
+        }
+
+    }
+    else
+    {
+        //Vorlagenname
+        String sValue(SW_RES(STR_POOLCOLL_HEADLINE1 + nIndex));
+        const SwTxtFmtColls* pColls = pDocShell->GetDoc()->GetTxtFmtColls();
+        const sal_uInt16 nCount = pColls->Count();
+        for(sal_uInt16 i = 0; i < nCount;++i)
+        {
+            SwTxtFmtColl &rTxtColl = *pColls->operator[](i);
+            if(rTxtColl.IsDefault())
+                continue;
+
+            sal_Int8 nOutLevel = rTxtColl.GetOutlineLevel();
+            if(nOutLevel == nIndex)
+            {
+                sValue = rTxtColl.GetName();
+            }
+        }
+        aUString = sValue;
+        pData = new PropValData((void*)&aUString, UNO_NAME_HEADING_STYLE_NAME, ::getCppuType((const OUString*)0));
+        aPropertyValues.Insert(pData, aPropertyValues.Count());
+    }
+
+    uno::Sequence aSeq(aPropertyValues.Count());
+    beans::PropertyValue* pArray = aSeq.getArray();
+
+    for(sal_uInt16 i = 0; i < aPropertyValues.Count(); i++)
+    {
+        PropValDataPtr pData = aPropertyValues.GetObject(i);
+        pArray[i].Value = pData->aVal;
+        pArray[i].Name = pData->sPropName;
+        pArray[i].Handle = -1;
+    }
+    aPropertyValues.DeleteAndDestroy(0, aPropertyValues.Count());
+    return aSeq;
+}
+/*-- 14.12.98 14:57:59---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+PropValData* lcl_FindProperty(const char* cName, PropValDataArr&    rPropertyValues)
+{
+    OUString sCmp = C2U(cName);
+    for(sal_uInt16 i = 0; i < rPropertyValues.Count(); i++)
+    {
+        PropValData* pTemp = rPropertyValues.GetObject(i);
+        if(sCmp == pTemp->sPropName)
+            return pTemp;
+    }
+    return 0;
+}
+//-----------------------------------------------------------------------
+
+void SwXNumberingRules::setNumberingRuleByIndex(
+            SwNumRule& rNumRule,
+            const uno::Sequence& rProperties, sal_Int32 nIndex)
+    throw( uno::RuntimeException, lang::IllegalArgumentException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    // the order of the names is important!
+    const char* aNumPropertyNames[] =
+    {
+        "Adjust",                               //0
+        "ParentNumbering",                      //1
+        "Prefix",                               //2
+        "Suffix",                               //3
+        "CharStyleName",                        //4
+        "StartWith",                            //5
+        UNO_NAME_LEFT_MARGIN,                   //6
+        UNO_NAME_SYMBOL_TEXT_DISTANCE,          //7
+        UNO_NAME_FIRST_LINE_OFFSET,             //8
+        "NumberingType",                        //9
+        "BulletId",                             //10
+        UNO_NAME_BULLET_FONT,                   //11
+        "BulletFontName",                       //12
+        "BulletChar",                           //13
+        UNO_NAME_GRAPHIC_URL,                   //14
+        UNO_NAME_GRAPHIC_BITMAP,                //15
+        UNO_NAME_GRAPHIC_SIZE,                  //16
+        UNO_NAME_VERT_ORIENT,                   //17
+        UNO_NAME_HEADING_STYLE_NAME             //18
+    };
+    const sal_uInt16 nPropNameCount = 19;
+    const sal_uInt16 nNotInChapter = 10;
+
+
+    SwNumFmt aFmt(rNumRule.Get( (sal_uInt16)nIndex ));
+    const beans::PropertyValue* pPropArray = rProperties.getConstArray();
+    PropValDataArr  aPropertyValues;
+    sal_Bool bExcept = sal_False;
+    for(int i = 0; i < rProperties.getLength() && !bExcept; i++)
+    {
+        const beans::PropertyValue& rProp = pPropArray[i];
+        bExcept = sal_True;
+        for(sal_uInt16 j = 0; j < (pDocShell ? nPropNameCount : nPropNameCount - 1); j++)
+        {
+            //some values not in chapter numbering
+            if(pDocShell && j == nNotInChapter)
+                j = nPropNameCount - 1;
+            if(COMPARE_EQUAL == rProp.Name.compareToAscii(aNumPropertyNames[j]))
+            {
+                bExcept = sal_False;
+                break;
+            }
+        }
+        PropValData* pData = new PropValData(rProp.Value, rProp.Name );
+        aPropertyValues.Insert(pData, aPropertyValues.Count());
+    }
+    sal_Bool bWrongArg = sal_False;
+    if(!bExcept)
+       {
+        SvxBrushItem* pSetBrush = 0;
+        Size* pSetSize = 0;
+        SwFmtVertOrient* pSetVOrient = 0;
+
+        for(sal_uInt16 i = 0; i < nPropNameCount && !bExcept && !bWrongArg; i++)
+        {
+            PropValData* pData = lcl_FindProperty(aNumPropertyNames[i], aPropertyValues);
+            if(!pData)
+                continue;
+            switch(i)
+            {
+                case 0: //"Adjust"
+                {
+                    sal_Int16 nValue;
+                    pData->aVal >>= nValue;
+                    if(nValue > 0 &&
+                        nValue <= text::HoriOrientation::LEFT &&
+                            USHRT_MAX != aUnoToSvxAdjust[nValue])
+                    {
+                        aFmt.SetAdjust((SvxAdjust)aUnoToSvxAdjust[nValue]);
+                    }
+                    else
+                        bWrongArg = sal_True;
+                }
+                break;
+                case 1: //"ParentNumbering",
+                {
+                    sal_Int16 nSet;
+                    pData->aVal >>= nSet;
+                    if(nSet >= 0 && MAXLEVEL >= nSet)
+                        aFmt.SetUpperLevel(nSet);
+                }
+                break;
+                case 2: //"Prefix",
+                {
+                    OUString uTmp;
+                    pData->aVal >>= uTmp;
+                    aFmt.SetPrefix(uTmp);
+                }
+                break;
+                case 3: //"Suffix",
+                {
+                    OUString uTmp;
+                    pData->aVal >>= uTmp;
+                    aFmt.SetPostfix(uTmp);
+                }
+                break;
+                case 4: //"CharStyleName",
+                {
+                    OUString uTmp;
+                    pData->aVal >>= uTmp;
+                    String sCharFmtName(
+                        SwXStyleFamilies::GetUIName( uTmp,
+                                                    SFX_STYLE_FAMILY_CHAR ) );
+                    SwCharFmt* pCharFmt = 0;
+                    if(sCharFmtName.EqualsAscii(UNO_NAME_CHARACTER_FORMAT_NONE))
+                    {
+                        sNewCharStyleNames[(sal_uInt16)nIndex] = SwXNumberingRules::GetInvalidStyle();
+                        aFmt.SetCharFmt(0);
+                    }
+                    else if(pDocShell || pDoc)
+                    {
+                        SwDoc* pLocalDoc = pDoc ? pDoc : pDocShell->GetDoc();
+                        const SwCharFmts* pFmts = pLocalDoc->GetCharFmts();
+                        sal_uInt16 nChCount = pFmts->Count();
+
+                        SwCharFmt* pCharFmt = 0;
+                        for(sal_uInt16 j = 0; j< nChCount; j++)
+                        {
+                            SwCharFmt* pTmp = (*pFmts)[j];
+                            if(pTmp->GetName() == sCharFmtName)
+                            {
+                                pCharFmt = pTmp;
+                                break;
+                            }
+                        }
+                        if(!pCharFmt)
+                        {
+
+                            SfxStyleSheetBase* pBase;
+                            SfxStyleSheetBasePool* pPool = pLocalDoc->GetDocShell()->GetStyleSheetPool();
+                            pBase = ((SfxStyleSheetBasePool*)pPool)->Find(sCharFmtName, SFX_STYLE_FAMILY_CHAR);
+                            if(!pBase)
+                                pBase = &pPool->Make(sCharFmtName, SFX_STYLE_FAMILY_CHAR);
+                            pCharFmt = ((SwDocStyleSheet*)pBase)->GetCharFmt();
+                        }
+                        aFmt.SetCharFmt( pCharFmt );
+                        sNewCharStyleNames[(sal_uInt16)nIndex] = sCharFmtName;
+                     }
+                    else
+                        sNewCharStyleNames[(sal_uInt16)nIndex] = sCharFmtName;
+                }
+                break;
+                case 5: //"StartWith",
+                {
+                    INT16 nVal;
+                    pData->aVal >>= nVal;
+                    aFmt.SetStartValue(nVal);
+                }
+                break;
+                case 6: //UNO_NAME_LEFT_MARGIN,
+                {
+                    sal_Int32 nValue;
+                    pData->aVal >>= nValue;
+                    if(nValue >= 0)
+                        aFmt.SetAbsLSpace((sal_uInt16) MM100_TO_TWIP(nValue));
+                    else
+                        bWrongArg = sal_True;
+                }
+                break;
+                case 7: //UNO_NAME_SYMBOL_TEXT_DISTANCE,
+                {
+                    sal_Int32 nValue;
+                    pData->aVal >>= nValue;
+                    if(nValue >= 0)
+                        aFmt.SetCharTextOffset((sal_uInt16) MM100_TO_TWIP(nValue));
+                    else
+                        bWrongArg = sal_True;
+                }
+                break;
+                case 8: //UNO_NAME_FIRST_LINE_OFFSET,
+                {
+                    sal_Int32 nValue;
+                    pData->aVal >>= nValue;
+                    if(nValue <= 0)
+                    {
+                        nValue = MM100_TO_TWIP(nValue);
+                        if(-nValue > aFmt.GetAbsLSpace())
+                            aFmt.SetAbsLSpace(-nValue);
+                        aFmt.SetFirstLineOffset((short)nValue);
+                    }
+                    else
+                        bWrongArg = sal_True;
+                }
+                break;
+                case 9: //"NumberingType"
+                {
+                    sal_Int16 nSet;
+                    pData->aVal >>= nSet;
+                    if(nSet <= (sal_Int16)SVX_NUM_CHARS_LOWER_LETTER_N)
+                        aFmt.eType = (SvxExtNumType)nSet;
+                    else
+                        bWrongArg = sal_True;
+                }
+                break;
+                case 10: //"BulletId",
+                {
+                    sal_Int16 nSet;
+                    pData->aVal >>= nSet;
+                    if(nSet < 0xff)
+                        aFmt.SetBulletChar(nSet);
+                    else
+                        bWrongArg = sal_True;
+                }
+                break;
+                case 11: //UNO_NAME_BULLET_FONT,
+                {
+                     awt::FontDescriptor* pDesc =  (awt::FontDescriptor*)pData->aVal.getValue();
+                    if(pDesc)
+                    {
+                        Font aFont;
+                        SvxUnoFontDescriptor::ConvertToFont( *pDesc, aFont );
+                        aFmt.SetBulletFont(&aFont);
+                    }
+                    else
+                        bWrongArg = sal_True;
+                }
+                break;
+                case 12: //"BulletFontName",
+                {
+                    OUString uTmp;
+                    pData->aVal >>= uTmp;
+                    String sBulletFontName(uTmp);
+                    sNewBulletFontNames[(sal_uInt16)nIndex] = sBulletFontName;
+                }
+                break;
+                case 13: //"BulletChar",
+                {
+                    OUString aChar;
+                    pData->aVal >>= aChar;
+                    if(aChar.getLength() == 1)
+                    {
+                        aFmt.SetBulletChar(aChar.toChar());
+                    }
+                    else
+                        bWrongArg = sal_True;
+                }
+                break;
+                case 14: //UNO_NAME_GRAPHIC_URL,
+                {
+                    OUString sBrushURL;
+                    pData->aVal >>= sBrushURL;
+                    if(!pSetBrush)
+                    {
+                        const SvxBrushItem* pOrigBrush = aFmt.GetGrfBrush();
+                        if(pOrigBrush)
+                        {
+                            pSetBrush = new SvxBrushItem(*pOrigBrush);
+                        }
+                        else
+                            pSetBrush = new SvxBrushItem(sBrushURL, aEmptyStr, GPOS_AREA);
+                    }
+                    pSetBrush->SetGraphicLink( sBrushURL );
+                }
+                break;
+                case 15: //UNO_NAME_GRAPHIC_BITMAP,
+                {
+                    uno::Reference< awt::XBitmap >* pBitmap = (uno::Reference< awt::XBitmap > *)pData->aVal.getValue();
+                    if(pBitmap)
+                    {
+                        if(!pSetBrush)
+                        {
+                            const SvxBrushItem* pOrigBrush = aFmt.GetGrfBrush();
+                            if(pOrigBrush)
+                            {
+                                pSetBrush = new SvxBrushItem(*pOrigBrush);
+                            }
+                            else
+                                pSetBrush = new SvxBrushItem(aEmptyStr, aEmptyStr, GPOS_AREA);
+                        }
+
+                        BitmapEx aBmp = VCLUnoHelper::GetBitmap( *pBitmap );
+                        Graphic aNewGr(aBmp);
+                        pSetBrush->SetGraphic( aNewGr );
+                    }
+                    else
+                        bWrongArg = sal_True;
+                }
+                break;
+                case 16: //UNO_NAME_GRAPHIC_SIZE,
+                {
+                    if(!pSetSize)
+                        pSetSize = new Size;
+                    if(pData->aVal.getValueType() == ::getCppuType((awt::Size*)0))
+                    {
+                         awt::Size* pSize =  (awt::Size*)pData->aVal.getValue();
+                        pSize->Width = MM100_TO_TWIP(pSize->Width);
+                        pSize->Height = MM100_TO_TWIP(pSize->Height);
+                        pSetSize->Width() = pSize->Width;
+                        pSetSize->Height() = pSize->Height;
+                    }
+                    else
+                        bWrongArg = sal_True;
+                }
+                break;
+                case 17: //VertOrient
+                {
+                    if(!pSetVOrient)
+                    {
+                        if(aFmt.GetGrfOrient())
+                            pSetVOrient = (SwFmtVertOrient*)aFmt.GetGrfOrient()->Clone();
+                        else
+                            pSetVOrient = new SwFmtVertOrient;
+                    }
+                    ((SfxPoolItem*)pSetVOrient)->PutValue(pData->aVal, MID_VERTORIENT_ORIENT);
+                }
+                break;
+                case 18: //"HeadingStyleName"
+                {
+                    OUString uTmp;
+                    pData->aVal >>= uTmp;
+                    String sStyleName = uTmp;
+                    const SwTxtFmtColls* pColls = pDocShell->GetDoc()->GetTxtFmtColls();
+                    const sal_uInt16 nCount = pColls->Count();
+                    for(sal_uInt16 i = 0; i < nCount; ++i)
+                    {
+                        SwTxtFmtColl &rTxtColl = *pColls->operator[](i);
+                        if(rTxtColl.IsDefault())
+                            continue;
+                        if(rTxtColl.GetOutlineLevel() == nIndex &&
+                            rTxtColl.GetName() != sStyleName)
+                            rTxtColl.SetOutlineLevel(NO_NUMBERING);
+                        else if(rTxtColl.GetName() == sStyleName)
+                            rTxtColl.SetOutlineLevel(sal_Int8(nIndex));
+                    }
+                }
+                break;
+            }
+        }
+        if(!bExcept && !bWrongArg && (pSetBrush || pSetSize || pSetVOrient))
+        {
+            if(!pSetBrush && aFmt.GetGrfBrush())
+                pSetBrush = new SvxBrushItem(*aFmt.GetGrfBrush());
+
+            if(pSetBrush)
+            {
+                if(!pSetVOrient && aFmt.GetGrfOrient())
+                    pSetVOrient = new SwFmtVertOrient(*aFmt.GetGrfOrient());
+
+                if(!pSetSize)
+                {
+                    pSetSize = new Size(aFmt.GetGrfSize());
+                    if(!pSetSize->Width() || !pSetSize->Height())
+                    {
+                        const Graphic* pGraphic = pSetBrush->GetGraphic();
+                        *pSetSize = ::GetGraphicSizeTwip(*pGraphic, 0);
+                    }
+                }
+                aFmt.SetGrfBrush( pSetBrush, pSetSize, pSetVOrient );
+            }
+        }
+        delete pSetBrush;
+        delete pSetSize;
+        delete pSetVOrient;
+      }
+    aPropertyValues.DeleteAndDestroy(0, aPropertyValues.Count());
+
+    if(bWrongArg)
+        throw lang::IllegalArgumentException();
+    else if(bExcept)
+        throw uno::RuntimeException();
+    rNumRule.Set( (sal_uInt16)nIndex, aFmt );
+
+}
+/*-- 19.07.00 07:49:17---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Reference< XPropertySetInfo > SwXNumberingRules::getPropertySetInfo()
+    throw(RuntimeException)
+{
+    static uno::Reference< beans::XPropertySetInfo >  aRef = new SfxItemPropertySetInfo( _pMap );
+    return aRef;
+}
+/*-- 19.07.00 07:49:17---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXNumberingRules::setPropertyValue( const OUString& rPropertyName, const Any& rValue )
+    throw(UnknownPropertyException, PropertyVetoException,
+        IllegalArgumentException, WrappedTargetException, RuntimeException)
+{
+    Any aRet;
+    SwNumRule* pDocRule = 0;
+    if(!pNumRule && pDocShell)
+    {
+        pDocRule = new SwNumRule(*pDocShell->GetDoc()->GetOutlineNumRule());
+    }
+    if(!pNumRule && !pDocRule)
+        throw RuntimeException();
+
+
+    if(0 == rPropertyName.compareToAscii(UNO_NAME_IS_AUTOMATIC))
+    {
+        BOOL bVal = *(sal_Bool*)rValue.getValue();
+        pDocRule ? pDocRule->SetAutoRule(bVal) :pNumRule->SetAutoRule(bVal);
+    }
+    else if(0 == rPropertyName.compareToAscii(UNO_NAME_IS_CONTINUOUS_NUMBERING))
+    {
+        BOOL bVal = *(sal_Bool*)rValue.getValue();
+        pDocRule ? pDocRule->SetContinusNum(bVal) : pNumRule->SetContinusNum(bVal);
+    }
+    else if(0 == rPropertyName.compareToAscii(UNO_NAME_NAME))
+    {
+        delete pDocRule;
+        throw IllegalArgumentException();
+    }
+    else if(0 == rPropertyName.compareToAscii(UNO_NAME_IS_ABSOLUTE_MARGINS))
+    {
+        BOOL bVal = *(sal_Bool*)rValue.getValue();
+        pDocRule ? pDocRule->SetAbsSpaces(bVal) : pNumRule->SetAbsSpaces(bVal);
+    }
+    else
+        throw UnknownPropertyException();
+    if(pDocRule)
+    {
+        pDocShell->GetDoc()->SetOutlineNumRule(*pDocRule);
+        delete pDocRule;
+    }
+}
+/*-- 19.07.00 07:49:18---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Any SwXNumberingRules::getPropertyValue( const OUString& rPropertyName )
+    throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+    Any aRet;
+    const SwNumRule* pRule = pNumRule;
+    if(!pRule && pDocShell)
+        pRule = pDocShell->GetDoc()->GetOutlineNumRule();
+    if(!pRule)
+        throw RuntimeException();
+
+    if(0 == rPropertyName.compareToAscii(UNO_NAME_IS_AUTOMATIC))
+    {
+        BOOL bVal = pRule->IsAutoRule();
+        aRet.setValue(&bVal, ::getBooleanCppuType());
+    }
+    else if(0 == rPropertyName.compareToAscii(UNO_NAME_IS_CONTINUOUS_NUMBERING))
+    {
+        BOOL bVal = pRule->IsContinusNum();
+        aRet.setValue(&bVal, ::getBooleanCppuType());
+    }
+    else if(0 == rPropertyName.compareToAscii(UNO_NAME_NAME))
+        aRet <<= OUString(pRule->GetName());
+    else if(0 == rPropertyName.compareToAscii(UNO_NAME_IS_ABSOLUTE_MARGINS))
+    {
+        BOOL bVal = pRule->IsAbsSpaces();
+        aRet.setValue(&bVal, ::getBooleanCppuType());
+    }
+    else
+        throw UnknownPropertyException();
+    return aRet;
+}
+/*-- 19.07.00 07:49:18---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXNumberingRules::addPropertyChangeListener(
+    const OUString& aPropertyName, const Reference< XPropertyChangeListener >& xListener )
+        throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+/*-- 19.07.00 07:49:18---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXNumberingRules::removePropertyChangeListener(
+    const OUString& aPropertyName, const Reference< XPropertyChangeListener >& aListener )
+        throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+/*-- 19.07.00 07:49:18---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXNumberingRules::addVetoableChangeListener(
+    const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener )
+        throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+/*-- 19.07.00 07:49:18---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXNumberingRules::removeVetoableChangeListener(
+    const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener )
+        throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+}
+/*-- 14.12.98 14:58:00---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXNumberingRules::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew)
+{
+    ClientModify(this, pOld, pNew);
+    if(!GetRegisteredIn())
+    {
+        delete pNumRule;
+        pNumRule = 0;
+        pDoc = 0;
+    }
+}
+/* -----------------------------06.04.00 11:47--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXChapterNumbering::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXChapterNumbering");
+}
+/* -----------------------------06.04.00 11:47--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXChapterNumbering::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    String sServiceName(rServiceName);
+    return sServiceName.EqualsAscii("com.sun.star.text.ChapterNumbering") ||
+            sServiceName.EqualsAscii("com.sun.star.text.NumberingRules");
+}
+/* -----------------------------06.04.00 11:47--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXChapterNumbering::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(2);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.ChapterNumbering");
+    pArray[1] = C2U("com.sun.star.text.NumberingRules");
+    return aRet;
+}
+/* -----------------22.02.99 16:33-------------------
+ *
+ * --------------------------------------------------*/
+SwXChapterNumbering::SwXChapterNumbering(SwDocShell& rDocSh) :
+    SwXNumberingRules(rDocSh)
+{
+}
+/* -----------------22.02.99 16:33-------------------
+ *
+ * --------------------------------------------------*/
+SwXChapterNumbering::~SwXChapterNumbering()
+{
+}
+
+/******************************************************************
+ * SwXTextColumns
+ ******************************************************************/
+/* -----------------------------06.04.00 11:47--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXTextColumns::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXTextColumns");
+}
+/* -----------------------------06.04.00 11:47--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXTextColumns::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.text.XTextColumns") == rServiceName;
+}
+/* -----------------------------06.04.00 11:47--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXTextColumns::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.XTextColumns");
+    return aRet;
+}
+/*-- 16.12.98 14:06:53---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextColumns::SwXTextColumns(const SwFmtCol& rFmtCol) :
+    aTextColumns(rFmtCol.GetNumCols()),
+    nReference(0)
+{
+    TextColumn* pColumns = aTextColumns.getArray();
+    const SwColumns& rCols = rFmtCol.GetColumns();
+    for(sal_uInt16 i = 0; i < aTextColumns.getLength(); i++)
+    {
+        SwColumn* pCol = rCols[i];
+
+        pColumns[i].Width = pCol->GetWishWidth();
+        nReference += pColumns[i].Width;
+        pColumns[i].LeftMargin =    TWIP_TO_MM100(pCol->GetLeft ());
+        pColumns[i].RightMargin =   TWIP_TO_MM100(pCol->GetRight());
+    }
+    if(!aTextColumns.getLength())
+        nReference = USHRT_MAX;
+
+}
+/*-- 16.12.98 14:06:54---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextColumns::~SwXTextColumns()
+{
+
+}
+/*-- 16.12.98 14:06:54---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Int32 SwXTextColumns::getReferenceValue(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    return nReference;
+}
+/*-- 16.12.98 14:06:55---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Int16 SwXTextColumns::getColumnCount(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    return aTextColumns.getLength();
+}
+/*-- 16.12.98 14:06:55---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextColumns::setColumnCount(sal_Int16 nColumns) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(nColumns <= 0)
+        throw uno::RuntimeException();
+    aTextColumns.realloc(nColumns);
+ text::TextColumn* pCols = aTextColumns.getArray();
+    nReference = USHRT_MAX;
+    sal_uInt16 nWidth = nReference / nColumns;
+    sal_uInt16 nDiff = nReference - nWidth * nColumns;
+    for(sal_Int16 i = 0; i < nColumns; i++)
+    {
+        pCols[i].Width = nWidth;
+        pCols[i].LeftMargin = 0;
+        pCols[i].RightMargin = 0;
+    }
+    pCols[nColumns - 1].Width += nDiff;
+}
+/*-- 16.12.98 14:06:55---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Sequence< text::TextColumn > SwXTextColumns::getColumns(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    return aTextColumns;
+}
+/*-- 16.12.98 14:06:56---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextColumns::setColumns(const uno::Sequence< text::TextColumn >& rColumns)
+            throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_uInt16 nReferenceTemp = 0;
+    const text::TextColumn* prCols = rColumns.getConstArray();
+    for(long i = 0; i < rColumns.getLength(); i++)
+    {
+        //wenn die Breite Null ist, oder die Raender breiter als die Spalte werden -> exception
+        if(!prCols[i].Width ||
+            prCols[i].LeftMargin + prCols[i].RightMargin >= prCols[i].Width)
+            throw uno::RuntimeException();
+        nReferenceTemp += prCols[i].Width;
+    }
+    nReference = !nReferenceTemp ? USHRT_MAX : nReferenceTemp;
+    aTextColumns = rColumns;
+}
+/*------------------------------------------------------------------------
+
+    $Log: not supported by cvs2svn $
+    Revision 1.64  2000/09/18 16:04:35  willem.vandorp
+    OpenOffice header added.
+
+    Revision 1.63  2000/09/18 12:34:26  os
+    property AnchorCharStyleName in Footnotes/Endnotes
+
+    Revision 1.62  2000/09/05 15:17:55  os
+    string length available again
+
+    Revision 1.61  2000/08/25 09:03:37  os
+    service NumberingRules added
+
+    Revision 1.60  2000/08/24 11:14:34  mib
+    bug fixes for XML import
+
+    Revision 1.59  2000/08/10 08:25:05  mib
+    #74404#: NumberingCharStyleName now handles programmatic names
+
+    Revision 1.58  2000/08/07 09:16:51  os
+    #77157# service name LineNumberingSettings
+
+    Revision 1.57  2000/07/19 11:01:02  os
+    #76846# properties added
+
+    Revision 1.56  2000/07/05 09:00:26  os
+    #76619# service name added
+
+    Revision 1.55  2000/06/20 10:51:30  os
+    #70059# set character style name if pDocShell or pDoc is set
+
+    Revision 1.54  2000/05/25 09:55:12  hr
+    exception specification
+
+    Revision 1.53  2000/05/16 09:14:55  os
+    project usr removed
+
+    Revision 1.52  2000/04/26 11:35:20  os
+    GetName() returns String&
+
+    Revision 1.51  2000/04/19 13:35:31  os
+    UNICODE
+
+    Revision 1.50  2000/04/11 08:31:04  os
+    UNICODE
+
+    Revision 1.49  2000/03/31 06:06:48  os
+    UNO III: toolkit includes
+
+    Revision 1.48  2000/03/27 10:21:10  os
+    UNO III
+
+    Revision 1.47  2000/03/21 15:42:25  os
+    UNOIII
+
+    Revision 1.46  2000/02/11 14:35:52  hr
+    #70473# changes for unicode ( patched by automated patchtool )
+
+    Revision 1.45  2000/02/02 16:52:53  sub
+    #65293#: PropertyValue changes
+
+    Revision 1.44  1999/12/03 11:11:11  os
+    #70234# property name defined
+
+    Revision 1.43  1999/11/22 10:37:57  os
+    missing headers added
+
+    Revision 1.42  1999/11/19 16:40:19  os
+    modules renamed
+
+    Revision 1.41  1999/11/04 07:44:46  mib
+    SwXNumberingRule bug fixes
+
+    Revision 1.40  1999/11/01 11:40:21  mib
+    SwXNumberingRules bug fixes
+
+    Revision 1.39  1999/10/28 07:44:05  os
+    new properties/changes for XML
+
+    Revision 1.38  1999/07/07 05:41:04  OS
+    #67461# check index
+
+
+      Rev 1.37   07 Jul 1999 07:41:04   OS
+   #67461# check index
+
+      Rev 1.36   22 Jun 1999 11:00:00   OS
+   #66004# bullet and graphic properties not in chapter numbering
+
+      Rev 1.35   10 May 1999 11:16:00   OS
+   #66004# Zuordnung ChapterNumbering/NumberingRules berichtigt
+
+      Rev 1.34   22 Apr 1999 16:13:54   OS
+   #65194# throw -> throw; #65124# not impl. nur noch warning; EventListener
+
+      Rev 1.33   25 Mar 1999 14:36:44   OS
+   #63922# sal_Int32 statt sal_Int16 fuer Numerierungseinzuege
+
+      Rev 1.32   15 Mar 1999 14:37:48   OS
+   #62845# Makro fuer ServiceInfo jetzt auch fuer OS/2
+
+      Rev 1.31   12 Mar 1999 09:41:26   OS
+   #62845# lang::XServiceInfo impl.
+
+      Rev 1.30   09 Mar 1999 12:41:26   OS
+   #62008# Solar-Mutex
+
+      Rev 1.29   08 Mar 1999 07:45:20   MH
+   update 515
+
+      Rev 1.28   05 Mar 1999 13:52:08   OS
+   HoriOrientation - UPD515
+
+      Rev 1.27   04 Mar 1999 15:03:08   OS
+   #62191# UINT nicht mehr verwenden
+
+      Rev 1.26   23 Feb 1999 10:22:12   OS
+   #61767# Kapitelnumerierung funktioniert wieder
+
+      Rev 1.25   22 Feb 1999 15:38:32   OS
+   #60606# Numerierungsregel incl. Font richtig setzen;#62196 text::TextColumns: richtige Raender
+
+      Rev 1.24   19 Feb 1999 16:54:54   OS
+   #60606# Numerierungsregel setzbar
+
+      Rev 1.23   15 Feb 1999 11:25:02   OS
+   #52654# NumberingType in der NumberingRules
+
+      Rev 1.22   28 Jan 1999 16:45:02   OS
+   #56371# keine Objekte fuer DEBUG anlegen
+
+      Rev 1.21   21 Jan 1999 09:57:04   OS
+   #60971# Zeichenvorlagen der Numerierung an Absatzvorlagen setzen
+
+      Rev 1.20   05 Jan 1999 12:11:10   OS
+   #60606# #52654# Font fuer Numerierung setzen
+
+      Rev 1.19   16 Dec 1998 14:28:20   OS
+   #56371# Zwischenstand
+
+      Rev 1.18   10 Dec 1998 15:53:34   OS
+   #56371# TF_ONE51 Zwischenstand
+
+      Rev 1.17   17 Nov 1998 11:05:06   OS
+   #58263# NumType durch SvxExtNumType ersetzt
+
+      Rev 1.16   06 Nov 1998 13:11:24   OS
+   #52654##59069# Spalten vollstaendig
+
+      Rev 1.15   17 Sep 1998 16:01:08   OS
+   52654# ParagraphStyle->ParaStyle, CharacterStyle->CharStyle
+
+      Rev 1.14   10 Sep 1998 12:51:56   OS
+   #52654# PROPERTY_NONE statt PROPERTY_BOUND
+
+      Rev 1.13   10 Jul 1998 18:08:30   OS
+   PropertySetInfo und IdlClass static
+
+      Rev 1.12   27 Jun 1998 16:22:06   OS
+   SwXNumberingRule ist Client
+
+      Rev 1.11   18 Jun 1998 18:10:48   OS
+   Twip-mm-Konvertierung
+
+      Rev 1.10   18 Jun 1998 13:25:08   OS
+   queryInterface im ChapterNumbering
+
+
+      Rev 1.9   18 Jun 1998 08:53:56   MH
+   Chg: Syntax OS2
+
+      Rev 1.8   12 Jun 1998 13:49:14   OS
+   Package-Umstellung
+
+      Rev 1.7   04 Jun 1998 09:40:02   OS
+   getIdlClasses
+
+
+      Rev 1.6   29 May 1998 13:49:08   OS
+   Spalten eingebaut
+
+      Rev 1.5   26 May 1998 12:34:00   OS
+   SwXNumberingRules verbessert
+
+      Rev 1.4   25 May 1998 09:57:12   OS
+   +SwXNumberingRules, SwXChapterNumbering hierher verschoben
+
+      Rev 1.3   13 May 1998 15:27:02   OS
+   Umstellung der text::TextDocument-Interfaces
+
+      Rev 1.2   07 May 1998 14:56:18   MIB
+   Header
+
+      Rev 1.1   05 May 1998 10:04:00   OS
+   Properties vollstaendig
+
+      Rev 1.0   04 May 1998 13:41:04   OS
+   Initial revision.
+
+------------------------------------------------------------------------*/
+
diff --git a/sw/source/core/unocore/unosrch.cxx b/sw/source/core/unocore/unosrch.cxx
new file mode 100644
index 000000000000..b70024eaede0
--- /dev/null
+++ b/sw/source/core/unocore/unosrch.cxx
@@ -0,0 +1,889 @@
+/*************************************************************************
+ *
+ *  $RCSfile: unosrch.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:29 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "ui_pch.hxx"
+#endif
+
+#pragma hdrstop
+#ifndef _DOC_HXX //autogen
+#include 
+#endif
+#ifndef _HINTS_HXX //autogen
+#include 
+#endif
+#ifndef _UNOSRCH_HXX
+#include 
+#endif
+#ifndef _UNOMAP_HXX
+#include 
+#endif
+#ifndef _UNOOBJ_HXX
+#include 
+#endif
+#ifndef _VOS_MUTEX_HXX_ //autogen
+#include 
+#endif
+#ifndef _SV_SVAPP_HXX //autogen
+#include 
+#endif
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::rtl;
+/******************************************************************************
+ *
+ ******************************************************************************/
+
+/* -----------------23.06.99 12:19-------------------
+
+ --------------------------------------------------*/
+class SwSearchProperties_Impl
+{
+    beans::PropertyValue**          pValueArr; //
+    sal_uInt16                      nArrLen;
+public:
+    SwSearchProperties_Impl();
+    ~SwSearchProperties_Impl();
+
+    void    SetProperties(const Sequence< beans::PropertyValue >& aSearchAttribs)
+        throw( beans::UnknownPropertyException, lang::IllegalArgumentException, RuntimeException );
+    const Sequence< beans::PropertyValue > GetProperties() const;
+
+    void    FillItemSet(SfxItemSet& rSet, sal_Bool bIsValueSearch) const;
+    sal_Bool    HasAttributes() const;
+};
+/* -----------------23.06.99 13:08-------------------
+
+ --------------------------------------------------*/
+SwSearchProperties_Impl::SwSearchProperties_Impl() :
+    nArrLen(0)
+{
+    const SfxItemPropertyMap* pMap = aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_CURSOR);
+    while(pMap->nWID)
+    {
+        if(pMap->nWID < RES_FRMATR_END)
+            nArrLen++;
+        pMap++;
+    }
+    pValueArr = new beans::PropertyValue*[nArrLen];
+    *pValueArr = new beans::PropertyValue[nArrLen];
+    for(sal_uInt16 i = 0; i < nArrLen; i++)
+        pValueArr[i] = 0;
+}
+/* -----------------23.06.99 13:08-------------------
+
+ --------------------------------------------------*/
+SwSearchProperties_Impl::~SwSearchProperties_Impl()
+{
+    for(sal_uInt16 i = 0; i < nArrLen; i++)
+        delete pValueArr[i];
+    delete pValueArr;
+}
+/* -----------------23.06.99 13:09-------------------
+
+ --------------------------------------------------*/
+void    SwSearchProperties_Impl::SetProperties(const Sequence< beans::PropertyValue >& aSearchAttribs)
+                throw( beans::UnknownPropertyException, lang::IllegalArgumentException, RuntimeException )
+{
+    const SfxItemPropertyMap* pMap = aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_CURSOR);
+    long nLen = aSearchAttribs.getLength();
+    const beans::PropertyValue* pProps = aSearchAttribs.getConstArray();
+    //delete all existing values
+    for(long i = 0; i < nArrLen; i++)
+    {
+        delete pValueArr[i];
+        pValueArr[i] = 0;
+    }
+
+    for(i = 0; i < nLen; i++)
+    {
+        String sPropertyName(pProps[i].Name);
+        sal_uInt16 nIndex = 0;
+        const SfxItemPropertyMap* pTempMap = pMap;
+        while(pTempMap->nWID && !sPropertyName.EqualsAscii(pTempMap->pName))
+        {
+            pTempMap++;
+            nIndex++;
+        }
+        if(!pTempMap->nWID)
+            throw beans::UnknownPropertyException();
+        pValueArr[nIndex] = new beans::PropertyValue(pProps[i]);
+    }
+}
+/* -----------------23.06.99 13:08-------------------
+
+ --------------------------------------------------*/
+const Sequence< beans::PropertyValue > SwSearchProperties_Impl::GetProperties() const
+{
+    sal_uInt16 nPropCount = 0;
+    for(sal_uInt16 i = 0; i < nArrLen; i++)
+        if(pValueArr[i])
+            nPropCount++;
+
+    Sequence< beans::PropertyValue > aRet(nPropCount);
+    beans::PropertyValue* pProps = aRet.getArray();
+    nPropCount = 0;
+    for(i = 0; i < nArrLen; i++)
+    {
+        if(pValueArr[i])
+        {
+            pProps[nPropCount] = *(pValueArr[i]);
+        }
+        nPropCount++;
+    }
+    return aRet;
+}
+/* -----------------23.06.99 13:06-------------------
+
+ --------------------------------------------------*/
+void SwSearchProperties_Impl::FillItemSet(SfxItemSet& rSet, sal_Bool bIsValueSearch) const
+{
+    const SfxItemPropertyMap* pMap = aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_CURSOR);
+    //
+
+    SfxPoolItem* pBoxItem = 0,
+    *pBreakItem = 0,
+    *pAutoKernItem  = 0,
+    *pWLineItem   = 0,
+    *pTabItem  = 0,
+    *pSplitItem  = 0,
+    *pRegItem  = 0,
+    *pLineSpaceItem  = 0,
+    *pLineNumItem  = 0,
+    *pKeepItem  = 0,
+    *pLRItem  = 0,
+    *pULItem  = 0,
+    *pBackItem  = 0,
+    *pAdjItem  = 0,
+    *pDescItem  = 0,
+    *pInetItem  = 0,
+    *pDropItem  = 0,
+    *pWeightItem  = 0,
+    *pULineItem  = 0,
+    *pCharFmtItem  = 0,
+    *pShadItem  = 0,
+    *pPostItem  = 0,
+    *pNHyphItem  = 0,
+    *pLangItem  = 0,
+    *pKernItem  = 0,
+    *pFontSizeItem  = 0,
+    *pFontItem  = 0,
+    *pBlinkItem  = 0,
+    *pEscItem  = 0,
+    *pCrossedOutItem  = 0,
+    *pContourItem  = 0,
+    *pCharColorItem  = 0,
+    *pCasemapItem  = 0,
+    *pBrushItem  = 0;
+
+    for(sal_uInt16 i = 0; i < nArrLen; i++)
+    {
+        if(pValueArr[i])
+        {
+            const SfxItemPropertyMap*   pTempMap =  pMap + i;
+            SfxPoolItem* pTempItem = 0;
+            switch(pTempMap->nWID)
+            {
+                case  RES_BOX:
+                    if(!pBoxItem)
+                        pBoxItem = rSet.GetPool()->GetDefaultItem(pTempMap->nWID).Clone();
+                    pTempItem = pBoxItem;
+                break;
+                case  RES_BREAK:
+                    if(!pBreakItem)
+                        pBreakItem = rSet.GetPool()->GetDefaultItem(pTempMap->nWID).Clone();
+                    pTempItem = pBreakItem;
+                break;
+                case  RES_CHRATR_AUTOKERN:
+                    if(!pAutoKernItem)
+                        pAutoKernItem = rSet.GetPool()->GetDefaultItem(pTempMap->nWID).Clone();
+                    pTempItem = pAutoKernItem;
+                    break;
+                case  RES_CHRATR_BACKGROUND:
+                    if(!pBrushItem)
+                        pBrushItem = rSet.GetPool()->GetDefaultItem(pTempMap->nWID).Clone();
+                    pTempItem = pBrushItem;
+                break;
+                case  RES_CHRATR_CASEMAP:
+                    if(!pCasemapItem)
+                        pCasemapItem = rSet.GetPool()->GetDefaultItem(pTempMap->nWID).Clone();
+                    pTempItem = pCasemapItem;
+                break;
+                case  RES_CHRATR_COLOR:
+                    if(!pCharColorItem)
+                        pCharColorItem = rSet.GetPool()->GetDefaultItem(pTempMap->nWID).Clone();
+                    pTempItem = pCharColorItem;
+                break;
+                case  RES_CHRATR_CONTOUR:
+                    if(!pContourItem)
+                        pContourItem = rSet.GetPool()->GetDefaultItem(pTempMap->nWID).Clone();
+                    pTempItem = pContourItem;
+                break;
+                case  RES_CHRATR_CROSSEDOUT:
+                    if(!pCrossedOutItem)
+                        pCrossedOutItem = rSet.GetPool()->GetDefaultItem(pTempMap->nWID).Clone();
+                    pTempItem = pCrossedOutItem;
+                break;
+                case  RES_CHRATR_ESCAPEMENT:
+                    if(!pEscItem)
+                        pEscItem = rSet.GetPool()->GetDefaultItem(pTempMap->nWID).Clone();
+                    pTempItem = pEscItem;
+                break;
+                case  RES_CHRATR_BLINK:
+                    if(!pBlinkItem)
+                        pBlinkItem = rSet.GetPool()->GetDefaultItem(pTempMap->nWID).Clone();
+                    pTempItem = pBlinkItem;
+                break;
+                case  RES_CHRATR_FONT:
+                    if(!pFontItem)
+                        pFontItem = rSet.GetPool()->GetDefaultItem(pTempMap->nWID).Clone();
+                    pTempItem = pFontItem;
+                break;
+                case  RES_CHRATR_FONTSIZE:
+                    if(!pFontSizeItem)
+                        pFontSizeItem = rSet.GetPool()->GetDefaultItem(pTempMap->nWID).Clone();
+                    pTempItem = pFontSizeItem;
+                break;
+                case  RES_CHRATR_KERNING:
+                    if(!pKernItem)
+                        pKernItem = rSet.GetPool()->GetDefaultItem(pTempMap->nWID).Clone();
+                    pTempItem = pKernItem;
+                break;
+                case  RES_CHRATR_LANGUAGE:
+                    if(!pLangItem)
+                        pLangItem = rSet.GetPool()->GetDefaultItem(pTempMap->nWID).Clone();
+                    pTempItem = pLangItem;
+                break;
+                case  RES_CHRATR_NOHYPHEN:
+                    if(!pNHyphItem)
+                        pNHyphItem = rSet.GetPool()->GetDefaultItem(pTempMap->nWID).Clone();
+                    pTempItem = pNHyphItem;
+                break;
+                case  RES_CHRATR_POSTURE:
+                    if(!pPostItem)
+                        pPostItem = rSet.GetPool()->GetDefaultItem(pTempMap->nWID).Clone();
+                    pTempItem = pPostItem;
+                break;
+                case  RES_CHRATR_SHADOWED:
+                    if(!pShadItem)
+                        pShadItem = rSet.GetPool()->GetDefaultItem(pTempMap->nWID).Clone();
+                    pTempItem = pShadItem;
+                break;
+                case  RES_TXTATR_CHARFMT:
+                    if(!pCharFmtItem)
+                        pCharFmtItem = rSet.GetPool()->GetDefaultItem(pTempMap->nWID).Clone();
+                    pTempItem = pCharFmtItem;
+                break;
+                case  RES_CHRATR_UNDERLINE:
+                    if(!pULineItem)
+                        pULineItem = rSet.GetPool()->GetDefaultItem(pTempMap->nWID).Clone();
+                    pTempItem = pULineItem;
+                break;
+                case  RES_CHRATR_WEIGHT:
+                    if(!pWeightItem)
+                        pWeightItem = rSet.GetPool()->GetDefaultItem(pTempMap->nWID).Clone();
+                    pTempItem = pWeightItem;
+                break;
+                case  RES_PARATR_DROP:
+                    if(!pDropItem)
+                        pDropItem = rSet.GetPool()->GetDefaultItem(pTempMap->nWID).Clone();
+                    pTempItem = pDropItem;
+                break;
+                case  RES_TXTATR_INETFMT:
+                    if(!pInetItem)
+                        pInetItem = rSet.GetPool()->GetDefaultItem(pTempMap->nWID).Clone();
+                    pTempItem = pInetItem;
+                break;
+                case  RES_PAGEDESC:
+                    if(!pDescItem)
+                        pDescItem = rSet.GetPool()->GetDefaultItem(pTempMap->nWID).Clone();
+                    pTempItem = pDescItem;
+                break;
+                case  RES_PARATR_ADJUST:
+                    if(!pAdjItem)
+                        pAdjItem = rSet.GetPool()->GetDefaultItem(pTempMap->nWID).Clone();
+                    pTempItem = pAdjItem;
+                break;
+                case  RES_BACKGROUND:
+                    if(!pBackItem)
+                        pBackItem = rSet.GetPool()->GetDefaultItem(pTempMap->nWID).Clone();
+                    pTempItem = pBackItem;
+                break;
+                case  RES_UL_SPACE:
+                    if(!pULItem)
+                        pULItem = rSet.GetPool()->GetDefaultItem(pTempMap->nWID).Clone();
+                    pTempItem = pULItem;
+                break;
+                case  RES_LR_SPACE:
+                    if(!pLRItem)
+                        pLRItem = rSet.GetPool()->GetDefaultItem(pTempMap->nWID).Clone();
+                    pTempItem = pLRItem;
+                break;
+                case  RES_KEEP:
+                    if(!pKeepItem)
+                        pKeepItem = rSet.GetPool()->GetDefaultItem(pTempMap->nWID).Clone();
+                    pTempItem = pKeepItem;
+                break;
+                case  RES_LINENUMBER:
+                    if(!pLineNumItem)
+                        pLineNumItem = rSet.GetPool()->GetDefaultItem(pTempMap->nWID).Clone();
+                    pTempItem = pLineNumItem;
+                break;
+                case  RES_PARATR_LINESPACING:
+                    if(!pLineSpaceItem)
+                        pLineSpaceItem = rSet.GetPool()->GetDefaultItem(pTempMap->nWID).Clone();
+                    pTempItem = pLineSpaceItem;
+                break;
+                case  RES_PARATR_REGISTER:
+                    if(!pRegItem)
+                        pRegItem = rSet.GetPool()->GetDefaultItem(pTempMap->nWID).Clone();
+                    pTempItem = pRegItem;
+                break;
+                case  RES_PARATR_SPLIT:
+                    if(!pSplitItem)
+                        pSplitItem = rSet.GetPool()->GetDefaultItem(pTempMap->nWID).Clone();
+                    pTempItem = pSplitItem;
+                break;
+                case  RES_PARATR_TABSTOP:
+                    if(!pTabItem)
+                        pTabItem = rSet.GetPool()->GetDefaultItem(pTempMap->nWID).Clone();
+                    pTempItem = pTabItem;
+                break;
+                case  RES_CHRATR_WORDLINEMODE:
+                    if(!pWLineItem)
+                        pWLineItem = rSet.GetPool()->GetDefaultItem(pTempMap->nWID).Clone();
+                    pTempItem = pWLineItem;
+                break;
+            }
+            if(pTempItem)
+            {
+                if(bIsValueSearch)
+                {
+                    pTempItem->PutValue(pValueArr[i]->Value, pTempMap->nMemberId);
+                    rSet.Put(*pTempItem);
+                }
+                else
+                    rSet.InvalidateItem( pTempItem->Which() );
+            }
+        }
+    }
+    delete pBoxItem;
+    delete pBreakItem;
+    delete pBreakItem ;
+    delete pAutoKernItem ;
+    delete pWLineItem;
+    delete pTabItem;
+    delete pSplitItem;
+    delete pRegItem;
+    delete pLineSpaceItem ;
+    delete pLineNumItem  ;
+    delete pKeepItem;
+    delete pLRItem  ;
+    delete pULItem  ;
+    delete pBackItem;
+    delete pAdjItem;
+    delete pDescItem;
+    delete pInetItem;
+    delete pDropItem;
+    delete pWeightItem;
+    delete pULineItem;
+    delete pCharFmtItem  ;
+    delete pShadItem;
+    delete pPostItem;
+    delete pNHyphItem;
+    delete pLangItem;
+    delete pKernItem;
+    delete pFontSizeItem ;
+    delete pFontItem;
+    delete pBlinkItem;
+    delete pEscItem;
+    delete pCrossedOutItem;
+    delete pContourItem  ;
+    delete pCharColorItem;
+    delete pCasemapItem  ;
+    delete pBrushItem  ;
+}
+/* -----------------23.06.99 14:18-------------------
+
+ --------------------------------------------------*/
+sal_Bool    SwSearchProperties_Impl::HasAttributes() const
+{
+    for(sal_uInt16 i = 0; i < nArrLen; i++)
+        if(pValueArr[i])
+            return sal_True;
+    return sal_False;
+}
+
+/*-- 14.12.98 13:07:10    ---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextSearch::SwXTextSearch() :
+    _pMap(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_SEARCH)),
+    pSearchProperties( new SwSearchProperties_Impl),
+    pReplaceProperties( new SwSearchProperties_Impl),
+    bIsValueSearch(sal_True),
+    bAll(sal_False),
+    bWord(sal_False),
+    bBack(sal_False),
+    bExpr(sal_False),
+    bCase(sal_False),
+    bStyles(sal_False),
+    bSimilarity(sal_False),
+    bLevRelax(sal_False),
+    nLevExchange(2),
+    nLevAdd(2),
+    nLevRemove(2)
+{
+}
+/*-- 14.12.98 13:07:12    ---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextSearch::~SwXTextSearch()
+{
+    delete pSearchProperties;
+    delete pReplaceProperties;
+}
+/* -----------------------------10.03.00 18:02--------------------------------
+
+ ---------------------------------------------------------------------------*/
+const Sequence< sal_Int8 > & SwXTextSearch::getUnoTunnelId()
+{
+    static Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId();
+    return aSeq;
+}
+/* -----------------------------10.03.00 18:04--------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Int64 SAL_CALL SwXTextSearch::getSomething( const Sequence< sal_Int8 >& rId )
+    throw(RuntimeException)
+{
+    if( rId.getLength() == 16
+        && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+                                        rId.getConstArray(), 16 ) )
+    {
+            return (sal_Int64)this;
+    }
+    return 0;
+}
+/*-- 14.12.98 13:07:12---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+OUString SwXTextSearch::getSearchString(void) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    return sSearchText;
+}
+/*-- 14.12.98 13:07:12---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextSearch::setSearchString(const OUString& rString)
+                                        throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sSearchText = String(rString);
+}
+/*-- 14.12.98 13:07:12---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+OUString SwXTextSearch::getReplaceString(void) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    return sReplaceText;
+}
+/*-- 14.12.98 13:07:12---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextSearch::setReplaceString(const OUString& rReplaceString) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sReplaceText = String(rReplaceString);
+}
+/*-- 14.12.98 13:07:13---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Reference< beans::XPropertySetInfo >  SwXTextSearch::getPropertySetInfo(void) throw( RuntimeException )
+{
+    static Reference< beans::XPropertySetInfo >  aRef = new SfxItemPropertySetInfo(_pMap);
+    return aRef;
+}
+/*-- 14.12.98 13:07:13---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextSearch::setPropertyValue(const OUString& rPropertyName, const Any& aValue)
+    throw( beans::UnknownPropertyException, beans::PropertyVetoException,
+        lang::IllegalArgumentException, lang::WrappedTargetException, RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                                                _pMap, rPropertyName);
+    if(pMap)
+    {
+        sal_Bool bVal = FALSE;
+        if(aValue.getValueType() == ::getBooleanCppuType())
+            bVal = *(sal_Bool*)aValue.getValue();
+        switch(pMap->nWID)
+        {
+            case WID_SEARCH_ALL :           bAll        = bVal; break;
+            case WID_WORDS:                 bWord       = bVal; break;
+            case WID_BACKWARDS :            bBack       = bVal; break;
+            case WID_REGULAR_EXPRESSION :   bExpr       = bVal; break;
+            case WID_CASE_SENSITIVE  :      bCase       = bVal; break;
+            //case WID_IN_SELECTION  :      bInSel      = bVal; break;
+            case WID_STYLES          :      bStyles     = bVal; break;
+            case WID_SIMILARITY      :      bSimilarity = bVal; break;
+            case WID_SIMILARITY_RELAX:      bLevRelax   = bVal; break;
+            case WID_SIMILARITY_EXCHANGE:   aValue >>= nLevExchange; break;
+            case WID_SIMILARITY_ADD:        aValue >>= nLevAdd; break;
+            case WID_SIMILARITY_REMOVE :    aValue >>= nLevRemove;break;
+            break;
+        };
+    }
+}
+/*-- 14.12.98 13:07:13---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Any SwXTextSearch::getPropertyValue(const OUString& rPropertyName) throw( beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    Any aRet;
+
+    const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                                                _pMap, rPropertyName);
+    sal_Bool bSet = sal_False;
+    sal_Int16 nSet = 0;
+    if(pMap)
+        switch(pMap->nWID)
+        {
+            case WID_SEARCH_ALL :           bSet = bAll; goto SET_BOOL;
+            case WID_WORDS:                 bSet = bWord; goto SET_BOOL;
+            case WID_BACKWARDS :            bSet = bBack; goto SET_BOOL;
+            case WID_REGULAR_EXPRESSION :   bSet = bExpr; goto SET_BOOL;
+            case WID_CASE_SENSITIVE  :      bSet = bCase; goto SET_BOOL;
+            //case WID_IN_SELECTION  :      bSet = bInSel; goto SET_BOOL;
+            case WID_STYLES          :      bSet = bStyles; goto SET_BOOL;
+            case WID_SIMILARITY      :      bSet = bSimilarity; goto SET_BOOL;
+            case WID_SIMILARITY_RELAX:      bSet = bLevRelax;
+SET_BOOL:
+            aRet.setValue(&bSet, ::getBooleanCppuType());
+            break;
+            case WID_SIMILARITY_EXCHANGE:   nSet = nLevExchange; goto SET_UINT16;
+            case WID_SIMILARITY_ADD:        nSet = nLevAdd; goto SET_UINT16;
+            case WID_SIMILARITY_REMOVE :    nSet = nLevRemove;
+SET_UINT16:
+            aRet <<= nSet;
+            break;
+        };
+    return aRet;
+}
+/*-- 14.12.98 13:07:13---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextSearch::addPropertyChangeListener(const OUString& PropertyName, const Reference< beans::XPropertyChangeListener > & aListener) throw( beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 14.12.98 13:07:13---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextSearch::removePropertyChangeListener(const OUString& PropertyName, const Reference< beans::XPropertyChangeListener > & aListener) throw( beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 14.12.98 13:07:14---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextSearch::addVetoableChangeListener(const OUString& PropertyName, const Reference< beans::XVetoableChangeListener > & aListener) throw( beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 14.12.98 13:07:14---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextSearch::removeVetoableChangeListener(const OUString& PropertyName, const Reference< beans::XVetoableChangeListener > & aListener) throw( beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 14.12.98 13:07:14---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextSearch::getValueSearch(void) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    return bIsValueSearch;
+}
+/*-- 14.12.98 13:07:15---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextSearch::setValueSearch(sal_Bool ValueSearch_) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    bIsValueSearch = ValueSearch_;
+}
+/*-- 14.12.98 13:07:15---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Sequence< beans::PropertyValue > SwXTextSearch::getSearchAttributes(void) throw( RuntimeException )
+{
+    return  pSearchProperties->GetProperties();
+}
+/*-- 14.12.98 13:07:16---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextSearch::setSearchAttributes(const Sequence< beans::PropertyValue >& rSearchAttribs)
+    throw( beans::UnknownPropertyException, lang::IllegalArgumentException, RuntimeException )
+{
+    pSearchProperties->SetProperties(rSearchAttribs);
+}
+/*-- 14.12.98 13:07:16---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Sequence< beans::PropertyValue > SwXTextSearch::getReplaceAttributes(void)
+    throw( RuntimeException )
+{
+    return pReplaceProperties->GetProperties();
+}
+/*-- 14.12.98 13:07:17---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextSearch::setReplaceAttributes(const Sequence< beans::PropertyValue >& rReplaceAttribs)
+    throw( beans::UnknownPropertyException, lang::IllegalArgumentException, RuntimeException )
+{
+    pReplaceProperties->SetProperties(rReplaceAttribs);
+}
+/* -----------------23.06.99 14:13-------------------
+
+ --------------------------------------------------*/
+void    SwXTextSearch::FillSearchItemSet(SfxItemSet& rSet) const
+{
+    pSearchProperties->FillItemSet(rSet, bIsValueSearch);
+}
+/* -----------------23.06.99 14:14-------------------
+
+ --------------------------------------------------*/
+void    SwXTextSearch::FillReplaceItemSet(SfxItemSet& rSet) const
+{
+    pReplaceProperties->FillItemSet(rSet, bIsValueSearch);
+}
+/* -----------------23.06.99 14:17-------------------
+
+ --------------------------------------------------*/
+sal_Bool    SwXTextSearch::HasSearchAttributes() const
+{
+    return pSearchProperties->HasAttributes();
+}
+/* -----------------23.06.99 14:17-------------------
+
+ --------------------------------------------------*/
+sal_Bool    SwXTextSearch::HasReplaceAttributes() const
+{
+    return pReplaceProperties->HasAttributes();
+}
+/* -----------------------------19.04.00 14:43--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXTextSearch::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXTextSearch");
+}
+/* -----------------------------19.04.00 14:43--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXTextSearch::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.util.SearchDescriptor") == rServiceName ||
+            C2U("com.sun.star.util.ReplaceDescriptor") == rServiceName;
+}
+/* -----------------------------19.04.00 14:43--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXTextSearch::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(2);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.util.SearchDescriptor");
+    pArray[1] = C2U("com.sun.star.util.ReplaceDescriptor");
+    return aRet;
+}
+
+/*------------------------------------------------------------------------
+    $Log: not supported by cvs2svn $
+    Revision 1.38  2000/09/18 16:04:35  willem.vandorp
+    OpenOffice header added.
+
+    Revision 1.37  2000/06/13 13:33:29  os
+    #75482# ServiceInfo of SwXTextSearch completed
+
+    Revision 1.36  2000/05/16 09:14:55  os
+    project usr removed
+
+    Revision 1.35  2000/04/19 13:35:31  os
+    UNICODE
+
+    Revision 1.34  2000/04/11 08:31:04  os
+    UNICODE
+
+    Revision 1.33  2000/03/27 10:21:10  os
+    UNO III
+
+    Revision 1.32  2000/03/21 15:42:25  os
+    UNOIII
+
+    Revision 1.31  2000/02/11 14:35:55  hr
+    #70473# changes for unicode ( patched by automated patchtool )
+
+    Revision 1.30  1999/11/19 16:40:19  os
+    modules renamed
+
+    Revision 1.29  1999/06/24 07:19:34  OS
+    #67048# util::XPropertyReplace implemented
+
+
+      Rev 1.28   24 Jun 1999 09:19:34   OS
+   #67048# util::XPropertyReplace implemented
+
+      Rev 1.27   22 Apr 1999 16:13:56   OS
+   #65194# throw -> throw; #65124# not impl. nur noch warning; EventListener
+
+      Rev 1.26   15 Mar 1999 14:37:50   OS
+   #62845# Makro fuer ServiceInfo jetzt auch fuer OS/2
+
+      Rev 1.25   12 Mar 1999 09:41:28   OS
+   #62845# lang::XServiceInfo impl.
+
+      Rev 1.24   09 Mar 1999 12:41:26   OS
+   #62008# Solar-Mutex
+
+      Rev 1.23   04 Mar 1999 11:43:44   OS
+   #62459# Searchable funktioniert wieder
+
+      Rev 1.22   18 Feb 1999 13:44:30   HR
+   Typo in Makro
+
+      Rev 1.21   28 Jan 1999 16:45:00   OS
+   #56371# keine Objekte fuer DEBUG anlegen
+
+      Rev 1.20   22 Jan 1999 15:09:20   OS
+   #56371# Draw wieder verfuegbar
+
+      Rev 1.19   15 Dec 1998 10:10:02   OS
+   #56371# TF_ONE51 Zwischenstand
+
+      Rev 1.18   10 Dec 1998 15:53:36   OS
+   #56371# TF_ONE51 Zwischenstand
+
+      Rev 1.17   10 Jul 1998 18:09:02   OS
+   PropertySetInfo und IdlClass static
+
+      Rev 1.16   26 Jun 1998 18:17:12   OS
+   includes
+
+      Rev 1.15   25 Jun 1998 11:14:56   OS
+   PreopertyMaps nur noch vom PropertyMapProvider
+
+      Rev 1.14   23 Jun 1998 10:22:50   OS
+   search/replace funktioniert wieder
+
+      Rev 1.13   18 Jun 1998 13:22:44   OS
+   include-Umstellung 396c
+
+      Rev 1.12   17 Jun 1998 18:14:42   OS
+   search()/replace() nicht mehr am util::XSearchable
+
+      Rev 1.11   15 Jun 1998 14:04:58   OS
+   SwXContainer vergessen
+
+      Rev 1.10   15 Jun 1998 10:53:54   OS
+   Chg Container 396
+
+      Rev 1.9   05 Jun 1998 14:28:52   TJ
+   wieder eine Klammer
+
+      Rev 1.8   04 Jun 1998 09:40:04   OS
+// automatisch auskommentiert - [getIdlClass(es) or queryInterface] - Bitte XTypeProvider benutzen!
+//   getIdlClasses
+
+
+      Rev 1.7   22 May 1998 15:10:50   OS
+   include
+
+      Rev 1.6   18 May 1998 12:20:36   OS
+   Container fuer Suchergebnis
+
+      Rev 1.5   14 May 1998 17:48:52   OS
+   wiedererweckt
+
+      Rev 1.4   04 Feb 1998 17:27:14   OS
+   uebersetzbar
+
+      Rev 1.3   30 Jan 1998 15:10:46   OS
+   wieder uebersetzbar
+
+      Rev 1.2   19 Jan 1998 14:58:04   OS
+   wieder uebersetzbar
+
+      Rev 1.1   08 Jan 1998 12:56:50   OS
+   UsrUik -> Uik
+
+      Rev 1.0   05 Jan 1998 11:03:20   OS
+   Initial revision.
+
+------------------------------------------------------------------------*/
+
diff --git a/sw/source/core/unocore/unostyle.cxx b/sw/source/core/unocore/unostyle.cxx
new file mode 100644
index 000000000000..c60d1bf2b621
--- /dev/null
+++ b/sw/source/core/unocore/unostyle.cxx
@@ -0,0 +1,2861 @@
+/*************************************************************************
+ *
+ *  $RCSfile: unostyle.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:29 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _PAGEDESC_HXX //autogen
+#include 
+#endif
+#ifndef _DOC_HXX //autogen
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _CHARFMT_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_SVXIDS_HRC //autogen
+#include 
+#endif
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+#include 
+#ifndef _UNOSTYLE_HXX
+#include 
+#endif
+#ifndef _UNOMAP_HXX
+#include 
+#endif
+#ifndef _UNOSETT_HXX
+#include 
+#endif
+#ifndef _SFXSTYLE_HXX
+#include 
+#endif
+#ifndef _SWDOCSH_HXX //autogen
+#include 
+#endif
+#ifndef _SWSTYLE_H
+#include 
+#endif
+#ifndef _PARATR_HXX
+#include 
+#endif
+#ifndef SW_UNOMID_HXX
+#include 
+#endif
+#ifndef _UNOPRNMS_HXX
+#include 
+#endif
+#ifndef _SHELLIO_HXX //autogen
+#include 
+#endif
+#ifndef _SVSTOR_HXX //autogen
+#include 
+#endif
+#ifndef _DOCSTYLE_HXX //autogen
+#include 
+#endif
+#ifndef _UNOOBJ_HXX
+#include 
+#endif
+#ifndef _FMTHDFT_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_PAGEITEM_HXX //autogen
+#define ITEMID_SETITEM
+#include 
+#endif
+#ifndef _SVX_SIZEITEM_HXX //autogen
+#define ITEMID_SIZE SID_ATTR_PAGE_SIZE
+#include 
+#endif
+#ifndef _SVX_ULSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BOXITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_SHADITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BRSHITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_FLSTITEM_HXX //autogen
+#include 
+#endif
+#ifndef _CTRLTOOL_HXX //autogen
+#include 
+#endif
+#ifndef _VOS_MUTEX_HXX_ //autogen
+#include 
+#endif
+#ifndef _SV_SVAPP_HXX //autogen
+#include 
+#endif
+#ifndef _SFXSMPLHINT_HXX //autogen
+#include 
+#endif
+#ifndef _FMTPDSC_HXX //autogen wg. SwFmtPageDesc
+#include 
+#endif
+#ifndef _URLOBJ_HXX
+#include 
+#endif
+#ifndef _POOLFMT_HRC
+#include 
+#endif
+#ifndef _POOLFMT_HXX
+#include 
+#endif
+#ifndef _COM_SUN_STAR_STYLE_PARAGRAPHSTYLECATEGORY_HPP_
+#include 
+#endif
+
+
+#define STYLE_FAMILY_COUNT 5            // wir habe fuenf Familien
+
+#define TYPE_BOOL       0
+#define TYPE_SIZE       1
+#define TYPE_BRUSH      2
+#define TYPE_ULSPACE    3
+#define TYPE_SHADOW     4
+#define TYPE_LRSPACE    5
+#define TYPE_BOX        6
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::style;
+using namespace ::rtl;
+/******************************************************************************
+ *
+ ******************************************************************************/
+
+const unsigned short aStyleByIndex[] =
+{
+    SFX_STYLE_FAMILY_CHAR,
+    SFX_STYLE_FAMILY_PARA,
+    SFX_STYLE_FAMILY_PAGE     ,
+    SFX_STYLE_FAMILY_FRAME    ,
+    SFX_STYLE_FAMILY_PSEUDO
+};
+
+struct Programmatic2UIName
+{
+    String sProgrammaticName;
+    String sUIName;
+};
+const Programmatic2UIName* lcl_GetStyleNameTable(SfxStyleFamily eFamily)
+{
+    const Programmatic2UIName* pRet = 0;
+    switch(eFamily)
+    {
+        case SFX_STYLE_FAMILY_CHAR:
+        {
+            static BOOL bInitialized = FALSE;
+            static Programmatic2UIName aCharFamilyNames[(STR_POOLCHR_PRGM_CURRENT_END - RC_POOLCHRFMT_PRGM_BEGIN) +
+                                                        (STR_POOLCHR_PRGM_HTML_CURRENT_END - RC_POOLCHRFMT_PRGM_HTML_BEGIN) + 3];
+            if(!bInitialized)
+            {
+                bInitialized = TRUE;
+                int nUIResId;
+                int nProgrammaticResId;
+                int nName = 0;
+                for(nUIResId = RC_POOLCHRFMT_BEGIN, nProgrammaticResId = RC_POOLCHRFMT_PRGM_BEGIN;
+                    nProgrammaticResId <= STR_POOLCHR_PRGM_CURRENT_END; nUIResId++, nProgrammaticResId++)
+                {
+                    aCharFamilyNames[nName].sUIName = String(SW_RES(nUIResId));
+                    aCharFamilyNames[nName++].sProgrammaticName = String(SW_RES(nProgrammaticResId));
+                }
+                for(nUIResId = RC_POOLCHRFMT_HTML_BEGIN, nProgrammaticResId = RC_POOLCHRFMT_PRGM_HTML_BEGIN;
+                    nProgrammaticResId <= STR_POOLCHR_PRGM_HTML_CURRENT_END; nUIResId++, nProgrammaticResId++)
+                {
+                    aCharFamilyNames[nName].sUIName = String(SW_RES(nUIResId));
+                    aCharFamilyNames[nName++].sProgrammaticName = String(SW_RES(nProgrammaticResId));
+                }
+            }
+            pRet = &aCharFamilyNames[0];
+        }
+        break;
+        case SFX_STYLE_FAMILY_PARA:
+        {
+            static BOOL bInitialized = FALSE;
+            static Programmatic2UIName aParaFamilyNames[
+                    ( STR_POCO_PRGM_HEADLINE10    -  STR_POCO_PRGM_STANDARD     ) +
+                    ( STR_POCO_PRGM_BUL_NONUM5    -  STR_POCO_PRGM_NUMBUL_BASE   )+
+                    ( STR_POCO_PRGM_LABEL_DRAWING -  STR_POCO_PRGM_HEADER        )+
+                    ( STR_POCO_PRGM_TOX_USER10    -  STR_POCO_PRGM_REGISTER_BASE  )+
+                    ( STR_POCO_PRGM_DOC_SUBTITEL  -  STR_POCO_PRGM_DOC_TITEL     )+
+                    ( STR_POCO_PRGM_HTML_DT       -  STR_POCO_PRGM_HTML_BLOCKQUOTE)+
+                    + 7 ];
+
+
+            if(!bInitialized)
+            {
+                struct ParaIds
+                {
+                    USHORT nUIStart, nUIEnd, nProgStart;
+                };
+                ParaIds aParaIds[] =
+                {
+                    {STR_POOLCOLL_STANDARD,         STR_POOLCOLL_HEADLINE10,    STR_POCO_PRGM_STANDARD       },
+                    {STR_POOLCOLL_NUMBUL_BASE,      STR_POOLCOLL_BUL_NONUM5,    STR_POCO_PRGM_NUMBUL_BASE    },
+                    {STR_POOLCOLL_HEADER,           STR_POOLCOLL_LABEL_DRAWING, STR_POCO_PRGM_HEADER             },
+                    {STR_POOLCOLL_REGISTER_BASE,    STR_POOLCOLL_TOX_USER10,    STR_POCO_PRGM_REGISTER_BASE   },
+                    {STR_POOLCOLL_DOC_TITEL,        STR_POOLCOLL_DOC_SUBTITEL,  STR_POCO_PRGM_DOC_TITEL      },
+                    {STR_POOLCOLL_HTML_BLOCKQUOTE,  STR_POOLCOLL_HTML_DT,       STR_POCO_PRGM_HTML_BLOCKQUOTE },
+                };
+                bInitialized = TRUE;
+                int nUIResId;
+                int nProgrammaticResId;
+                int nName = 0;
+                for(USHORT nPart = 0; nPart < 6; nPart++)
+                    for(nUIResId = aParaIds[nPart].nUIStart, nProgrammaticResId = aParaIds[nPart].nProgStart;
+                        nUIResId <= aParaIds[nPart].nUIEnd; nUIResId++, nProgrammaticResId++)
+                    {
+                        aParaFamilyNames[nName].sUIName = String(SW_RES(nUIResId));
+                        aParaFamilyNames[nName++].sProgrammaticName = String(SW_RES(nProgrammaticResId));
+                    }
+            }
+            pRet = &aParaFamilyNames[0];
+        }
+        break;
+        case SFX_STYLE_FAMILY_FRAME:
+        {
+            static BOOL bInitialized = FALSE;
+            static Programmatic2UIName aFrameFamilyNames[(STR_POOLFRM_PRGM_LABEL - STR_POOLFRM_PRGM_FRAME) + 2];
+            if(!bInitialized)
+            {
+                bInitialized = TRUE;
+                int nUIResId;
+                int nProgrammaticResId;
+                int nName = 0;
+                for(nUIResId = STR_POOLFRM_FRAME, nProgrammaticResId = STR_POOLFRM_PRGM_FRAME;
+                    nProgrammaticResId <= STR_POOLFRM_PRGM_LABEL; nUIResId++, nProgrammaticResId++)
+                {
+                    aFrameFamilyNames[nName].sUIName = String(SW_RES(nUIResId));
+                    aFrameFamilyNames[nName++].sProgrammaticName = String(SW_RES(nProgrammaticResId));
+                }
+            }
+            pRet = &aFrameFamilyNames[0];
+        }
+        break;
+        case SFX_STYLE_FAMILY_PAGE:
+        {
+            static BOOL bInitialized = FALSE;
+            static Programmatic2UIName aPageFamilyNames[(STR_POOLPAGE_PRGM_ENDNOTE - STR_POOLPAGE_PRGM_STANDARD) + 2];
+            if(!bInitialized)
+            {
+                bInitialized = TRUE;
+                int nUIResId;
+                int nProgrammaticResId;
+                int nName = 0;
+                for(nUIResId = STR_POOLPAGE_STANDARD, nProgrammaticResId = STR_POOLPAGE_PRGM_STANDARD;
+                    nProgrammaticResId <= STR_POOLPAGE_PRGM_ENDNOTE; nUIResId++, nProgrammaticResId++)
+                {
+                    aPageFamilyNames[nName].sUIName = String(SW_RES(nUIResId));
+                    aPageFamilyNames[nName++].sProgrammaticName = String(SW_RES(nProgrammaticResId));
+                }
+            }
+            pRet = &aPageFamilyNames[0];
+        }
+        break;
+        case SFX_STYLE_FAMILY_PSEUDO:
+        {
+            static BOOL bInitialized = FALSE;
+            static Programmatic2UIName aNumFamilyNames[(STR_POOLNUMRULE_PRGM_BUL5 - STR_POOLNUMRULE_PRGM_NUM1) + 2];
+            if(!bInitialized)
+            {
+                bInitialized = TRUE;
+                int nUIResId;
+                int nProgrammaticResId;
+                int nName = 0;
+                for(nUIResId = STR_POOLNUMRULE_NUM1, nProgrammaticResId = STR_POOLNUMRULE_PRGM_NUM1;
+                    nProgrammaticResId <= STR_POOLNUMRULE_PRGM_BUL5; nUIResId++, nProgrammaticResId++)
+                {
+                    aNumFamilyNames[nName].sUIName = String(SW_RES(nUIResId));
+                    aNumFamilyNames[nName++].sProgrammaticName = String(SW_RES(nProgrammaticResId));
+                }
+            }
+            pRet = &aNumFamilyNames[0];
+        }
+        break;
+    }
+    return pRet;
+}
+const String&   SwXStyleFamilies::GetProgrammaticName(const String& rUIName, SfxStyleFamily eFamily)
+{
+    const Programmatic2UIName* pNames =lcl_GetStyleNameTable(eFamily);
+    DBG_ASSERT(pNames, "no mapping found!!!")
+    if(pNames)
+    do
+    {
+        if(pNames->sUIName == rUIName)
+            return pNames->sProgrammaticName;
+    }
+    while((++pNames)->sUIName.Len());
+    return rUIName;
+}
+const String&   SwXStyleFamilies::GetUIName(const String& rProgrammaticName, SfxStyleFamily eFamily)
+{
+    const Programmatic2UIName* pNames = lcl_GetStyleNameTable(eFamily);
+    do
+    {
+        if(pNames->sProgrammaticName == rProgrammaticName)
+            return pNames->sUIName;
+    }
+    while((++pNames)->sProgrammaticName.Len());
+    return rProgrammaticName;
+}
+
+/******************************************************************
+ * SwXStyleFamilies
+ ******************************************************************/
+/* -----------------------------06.04.00 11:24--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXStyleFamilies::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXStyleFamilies");
+}
+/* -----------------------------06.04.00 11:24--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXStyleFamilies::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.style.StyleFamilies") == rServiceName;
+}
+/* -----------------------------06.04.00 11:24--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXStyleFamilies::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.style.StyleFamilies");
+    return aRet;
+}
+/*-- 16.12.98 15:13:26---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXStyleFamilies::SwXStyleFamilies(SwDocShell& rDocShell) :
+    SwUnoCollection(rDocShell.GetDoc()),
+    pxCharStyles(0),
+    pxParaStyles(0),
+    pxFrameStyles(0),
+    pxPageStyles(0),
+    pxNumberingStyles(0),
+    pDocShell(&rDocShell),
+    bLoadStyleText(sal_True),
+    bLoadStyleFrame(sal_True),
+    bLoadStylePage(sal_True),
+    bLoadStyleOverwrite(sal_False),
+    bLoadStyleNumbering(sal_True)
+{
+
+}
+/*-- 16.12.98 15:13:26---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXStyleFamilies::~SwXStyleFamilies()
+{
+    delete pxCharStyles;
+    delete pxParaStyles;
+    delete pxFrameStyles;
+    delete pxPageStyles;
+    delete pxNumberingStyles;
+}
+/*-- 21.12.98 12:05:22---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Any SAL_CALL SwXStyleFamilies::getByName(const OUString& Name)
+    throw(
+        container::NoSuchElementException,
+        lang::WrappedTargetException,
+        RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+// der Index kommt aus const unsigned short aStyleByIndex[] =
+    Any aRet;
+    if(!IsValid())
+        throw RuntimeException();
+    if(Name.compareToAscii("CharacterStyles") == 0 )
+        aRet = getByIndex(0);
+    else if(Name.compareToAscii("ParagraphStyles") == 0)
+        aRet = getByIndex(1);
+    else if(Name.compareToAscii("FrameStyles") == 0 )
+        aRet = getByIndex(3);
+    else if(Name.compareToAscii("PageStyles") == 0 )
+        aRet = getByIndex(2);
+    else if(Name.compareToAscii("NumberingStyles") == 0 )
+        aRet = getByIndex(4);
+    else
+        throw container::NoSuchElementException();
+    return aRet;
+}
+/*-- 21.12.98 12:05:22---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Sequence< OUString > SwXStyleFamilies::getElementNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aNames(STYLE_FAMILY_COUNT);
+    OUString* pNames = aNames.getArray();
+    pNames[0] = C2U("CharacterStyles");
+    pNames[1] = C2U("ParagraphStyles");
+    pNames[2] = C2U("FrameStyles");
+    pNames[3] = C2U("PageStyles");
+    pNames[4] = C2U("NumberingStyles");
+    return aNames;
+}
+/*-- 21.12.98 12:05:22---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXStyleFamilies::hasByName(const OUString& Name) throw( RuntimeException )
+{
+    if( Name.compareToAscii("CharacterStyles") == 0 ||
+        Name.compareToAscii("ParagraphStyles") == 0 ||
+        Name.compareToAscii("FrameStyles") == 0 ||
+        Name.compareToAscii("PageStyles") == 0 ||
+        Name.compareToAscii("NumberingStyles") == 0 )
+        return sal_True;
+    else
+        return sal_False;
+}
+/*-- 16.12.98 15:13:27---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Int32 SwXStyleFamilies::getCount(void) throw( RuntimeException )
+{
+    return STYLE_FAMILY_COUNT;
+}
+/*-- 16.12.98 15:13:27---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Any SwXStyleFamilies::getByIndex(sal_Int32 nIndex)
+    throw( lang::IndexOutOfBoundsException, lang::WrappedTargetException, RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    Any aRet;
+    if(nIndex >= STYLE_FAMILY_COUNT)
+        throw lang::IndexOutOfBoundsException();
+    if(IsValid())
+    {
+        Reference< container::XNameContainer >  aRef;
+        sal_uInt16 nType = aStyleByIndex[nIndex];
+        switch( nType )
+        {
+            case SFX_STYLE_FAMILY_CHAR:
+            {
+                if(!pxCharStyles)
+                {
+                    ((SwXStyleFamilies*)this)->pxCharStyles = new Reference< container::XNameContainer > ();
+                    *pxCharStyles = new SwXStyleFamily(pDocShell, nType);
+                }
+                aRef = *pxCharStyles;
+            }
+            break;
+            case SFX_STYLE_FAMILY_PARA:
+            {
+                if(!pxParaStyles)
+                {
+                    ((SwXStyleFamilies*)this)->pxParaStyles = new Reference< container::XNameContainer > ();
+                    *pxParaStyles = new SwXStyleFamily(pDocShell, nType);
+                }
+                aRef = *pxParaStyles;
+            }
+            break;
+            case SFX_STYLE_FAMILY_PAGE     :
+            {
+                if(!pxPageStyles)
+                {
+                    ((SwXStyleFamilies*)this)->pxPageStyles = new Reference< container::XNameContainer > ();
+                    *pxPageStyles = new SwXStyleFamily(pDocShell, nType);
+                }
+                aRef = *pxPageStyles;
+            }
+            break;
+            case SFX_STYLE_FAMILY_FRAME    :
+            {
+                if(!pxFrameStyles)
+                {
+                    ((SwXStyleFamilies*)this)->pxFrameStyles = new Reference< container::XNameContainer > ();
+                    *pxFrameStyles = new SwXStyleFamily(pDocShell, nType);
+                }
+                aRef = *pxFrameStyles;
+            }
+            break;
+            case SFX_STYLE_FAMILY_PSEUDO:
+            {
+                if(!pxNumberingStyles)
+                {
+                    ((SwXStyleFamilies*)this)->pxNumberingStyles = new Reference< container::XNameContainer > ();
+                    *pxNumberingStyles = new SwXStyleFamily(pDocShell, nType);
+                }
+                aRef = *pxNumberingStyles;
+            }
+            break;
+        }
+        aRet.setValue(&aRef, ::getCppuType((const Reference*)0));
+    }
+    else
+        throw RuntimeException();
+    return aRet;
+}
+/*-- 16.12.98 15:13:27---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Type SwXStyleFamilies::getElementType(void)
+    throw( RuntimeException )
+{
+    return ::getCppuType((const Reference*)0);
+
+}
+/*-- 16.12.98 15:13:28---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXStyleFamilies::hasElements(void) throw( RuntimeException )
+{
+    return sal_True;
+}
+/*-- 16.12.98 15:13:28---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXStyleFamilies::loadStylesFromURL(const OUString& rURL,
+    const Sequence< beans::PropertyValue >& aOptions)
+    throw( io::IOException, RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(IsValid() && rURL.len())
+    {
+        int nCount = aOptions.getLength();
+        const beans::PropertyValue* pArray = aOptions.getConstArray();
+        for(int i = 0; i < nCount; i++)
+        {
+            String sName = pArray[i].Name;
+            const Any& rVal = pArray[i].Value;
+            if(rVal.getValueType() != ::getBooleanCppuType())
+                continue;
+            sal_Bool bVal = *(sal_Bool*)rVal.getValue();
+            if( sName.EqualsAscii(UNO_NAME_OVERWRITE_STYLES     ))
+                bLoadStyleOverwrite = bVal;
+            else if( sName.EqualsAscii(UNO_NAME_LOAD_NUMBERING_STYLES ))
+                bLoadStyleNumbering = bVal;
+            else if( sName.EqualsAscii(UNO_NAME_LOAD_PAGE_STYLES   ))
+                bLoadStylePage = bVal;
+            else if( sName.EqualsAscii(UNO_NAME_LOAD_FRAME_STYLES     ))
+                bLoadStyleFrame = bVal;
+            else if( sName.EqualsAscii(UNO_NAME_LOAD_TEXT_STYLES      ))
+                bLoadStyleText = bVal;
+        }
+
+        String aFileName(rURL);
+        INetURLObject aObj(aFileName);
+        aFileName = aObj.GetFull();
+        //bug SB
+        aFileName.SearchAndReplace('|', ':');
+        SvStorageRef pStor;
+        SvFileStream* pStream = 0;
+        SwRead pRead;
+        SwReader* pReader;
+        if( SvStorage::IsStorageFile( aFileName ))
+        {
+            pStor = new SvStorage( aFileName, STREAM_STD_READ );
+            pRead = ReadSw3;
+            SwNodeIndex aIdx(GetDoc()->GetNodes().GetEndOfContent(), -1);
+            SwPaM aPam(aIdx);
+            pReader = new SwReader(*pStor, aFileName,
+                                    aPam );
+        }
+        else
+        {
+            pStream = new SvFileStream(aFileName, STREAM_STD_READ);
+            pRead = ReadSwg;
+            pReader = new SwReader(*pStream, aFileName, GetDoc());
+        }
+        pRead->GetReaderOpt().SetAllFmtsOnly();
+        pRead->GetReaderOpt().SetTxtFmts(bLoadStyleText);
+        pRead->GetReaderOpt().SetFrmFmts(bLoadStyleFrame);
+        pRead->GetReaderOpt().SetPageDescs(bLoadStylePage);
+        pRead->GetReaderOpt().SetNumRules(bLoadStyleNumbering);
+        pRead->GetReaderOpt().SetMerge(!bLoadStyleOverwrite);
+
+        {
+            UnoActionContext aAction(GetDoc());
+            if( 0 != pReader->Read( *pRead ))
+                throw io::IOException();
+        }
+        delete pReader;
+        delete pStream;
+    }
+    else
+        throw RuntimeException();
+}
+/*-- 16.12.98 15:13:28---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Sequence< beans::PropertyValue > SwXStyleFamilies::getStyleLoaderOptions(void)
+        throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    Sequence< beans::PropertyValue > aSeq(5);
+    beans::PropertyValue* pArray = aSeq.getArray();
+    Any aVal;
+    sal_Bool bTemp = bLoadStyleText;
+    aVal.setValue(&bTemp, ::getCppuBooleanType());
+    pArray[0] = beans::PropertyValue(C2U(UNO_NAME_LOAD_TEXT_STYLES), -1, aVal, beans::PropertyState_DIRECT_VALUE);
+    bTemp = bLoadStyleFrame;
+    aVal.setValue(&bTemp, ::getCppuBooleanType());
+    pArray[1] = beans::PropertyValue(C2U(UNO_NAME_LOAD_FRAME_STYLES), -1, aVal, beans::PropertyState_DIRECT_VALUE);
+    bTemp = bLoadStylePage;
+    aVal.setValue(&bTemp, ::getCppuBooleanType());
+    pArray[2] = beans::PropertyValue(C2U(UNO_NAME_LOAD_PAGE_STYLES), -1, aVal, beans::PropertyState_DIRECT_VALUE);
+    bTemp = bLoadStyleNumbering;
+    aVal.setValue(&bTemp, ::getCppuBooleanType());
+    pArray[3] = beans::PropertyValue(C2U(UNO_NAME_LOAD_NUMBERING_STYLES), -1, aVal, beans::PropertyState_DIRECT_VALUE);
+    bTemp = bLoadStyleOverwrite;
+    aVal.setValue(&bTemp, ::getCppuBooleanType());
+    pArray[4] = beans::PropertyValue(C2U(UNO_NAME_OVERWRITE_STYLES), -1, aVal, beans::PropertyState_DIRECT_VALUE);
+    return aSeq;
+}
+
+/******************************************************************
+ * SwXStyleFamily
+ ******************************************************************/
+/* -----------------------------06.04.00 11:24--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXStyleFamily::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXStyleFamily");
+}
+/* -----------------------------06.04.00 11:24--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXStyleFamily::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.style.StyleFamily") == rServiceName;
+}
+/* -----------------------------06.04.00 11:24--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXStyleFamily::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.style.StyleFamily");
+    return aRet;
+}
+/*-- 16.12.98 16:03:56---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXStyleFamily::SwXStyleFamily(SwDocShell* pDocSh, sal_uInt16 nFamily) :
+        pBasePool(pDocSh->GetStyleSheetPool()),
+        pDocShell(pDocSh),
+        eFamily((SfxStyleFamily)nFamily)
+{
+/*  switch( nFamily )
+    {
+        case SFX_STYLE_FAMILY_CHAR:
+            _pPropMap = aSwMapProvider.GetPropertyMap(PROPERTY_MAP_CHAR_STYLE);
+        break;
+        case SFX_STYLE_FAMILY_PARA:
+            _pPropMap = aSwMapProvider.GetPropertyMap(PROPERTY_MAP_PARA_STYLE);
+        break;
+        case SFX_STYLE_FAMILY_PAGE:
+            _pPropMap = aSwMapProvider.GetPropertyMap(PROPERTY_MAP_PAGE_STYLE);
+        break;
+        case SFX_STYLE_FAMILY_FRAME:
+            _pPropMap = aSwMapProvider.GetPropertyMap(PROPERTY_MAP_FRAME_STYLE);
+        break;
+        case SFX_STYLE_FAMILY_PSEUDO:
+            _pPropMap = aSwMapProvider.GetPropertyMap(PROPERTY_MAP_NUM_STYLE);
+        break;
+    }*/
+    StartListening(*pBasePool);
+}
+/*-- 16.12.98 16:03:56---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXStyleFamily::~SwXStyleFamily()
+{
+
+}
+/*-- 16.12.98 16:03:57---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Int32 SwXStyleFamily::getCount(void) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Int32 nRet = 0;
+    if(pBasePool)
+    {
+        SfxStyleSheetIterator* pIterator = pBasePool->CreateIterator(eFamily, 0xffff);
+        nRet = pIterator->Count();
+        delete pIterator;
+    }
+    return nRet;
+}
+/*-- 16.12.98 16:03:57---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Any SwXStyleFamily::getByIndex(sal_Int32 nIndex)
+    throw( lang::IndexOutOfBoundsException, lang::WrappedTargetException, RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    Any aRet;
+    if(pBasePool)
+    {
+        SfxStyleSheetIterator* pIterator = pBasePool->CreateIterator(eFamily, 0xffff);
+        sal_uInt16 nCount= pIterator->Count();
+        if(nIndex < nCount)
+        {
+            SfxStyleSheetBase* pBase = (*pIterator)[(sal_uInt16) nIndex];
+            Reference< style::XStyle >  xStyle = _FindStyle(pBase->GetName());
+            if(!xStyle.is())
+            {
+                xStyle =
+                    eFamily == SFX_STYLE_FAMILY_PAGE ?
+                    new SwXPageStyle(*pBasePool, pDocShell, eFamily, pBase->GetName()):
+                    new SwXStyle(*pBasePool, eFamily, pDocShell->GetDoc(), pBase->GetName());
+            }
+            aRet.setValue(&xStyle, ::getCppuType((Reference*)0));
+        }
+        else
+            throw lang::IndexOutOfBoundsException();
+        delete pIterator;
+    }
+    else
+        throw RuntimeException();
+    return aRet;
+
+}
+/*-- 16.12.98 16:03:57---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Any SwXStyleFamily::getByName(const OUString& rName)
+    throw( container::NoSuchElementException, lang::WrappedTargetException, RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    Any aRet;
+    String sStyleName = SwXStyleFamilies::GetUIName(rName, eFamily);
+    if(pBasePool)
+    {
+        pBasePool->SetSearchMask(eFamily, SFXSTYLEBIT_ALL );
+        SfxStyleSheetBase* pBase = pBasePool->Find(sStyleName);
+        if(pBase)
+        {
+            Reference< style::XStyle >  xStyle;
+            xStyle = _FindStyle(sStyleName);
+            if(!xStyle.is())
+            {
+                xStyle = eFamily == SFX_STYLE_FAMILY_PAGE ?
+                    new SwXPageStyle(*pBasePool, pDocShell, eFamily, sStyleName) ://, _pPropMap) :
+                    new SwXStyle(*pBasePool, eFamily, pDocShell->GetDoc(), sStyleName);//, _pPropMap);
+            }
+            aRet.setValue(&xStyle, ::getCppuType((Reference*)0));
+        }
+        else
+            throw container::NoSuchElementException();
+    }
+    else
+        throw RuntimeException();
+    return aRet;
+
+}
+/*-- 16.12.98 16:03:57---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Sequence< OUString > SwXStyleFamily::getElementNames(void) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    Sequence< OUString > aRet;
+    if(pBasePool)
+    {
+        SfxStyleSheetIterator* pIterator = pBasePool->CreateIterator(eFamily, 0xffff);
+        sal_uInt16 nCount = pIterator->Count();
+        aRet.realloc(nCount);
+        OUString* pArray = aRet.getArray();
+        for(sal_uInt16 i = 0; i < nCount; i++)
+            pArray[i] = SwXStyleFamilies::GetProgrammaticName((*pIterator)[i]->GetName(), eFamily);
+        delete pIterator;
+    }
+    else
+        throw RuntimeException();
+    return aRet;
+}
+/*-- 16.12.98 16:03:57---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXStyleFamily::hasByName(const OUString& rName) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Bool bRet = sal_False;
+    if(pBasePool)
+    {
+        String sStyleName(SwXStyleFamilies::GetUIName(rName, eFamily));
+        pBasePool->SetSearchMask(eFamily, SFXSTYLEBIT_ALL );
+        SfxStyleSheetBase* pBase = pBasePool->Find(sStyleName);
+        bRet = 0 != pBase;
+    }
+    else
+        throw RuntimeException();
+    return bRet;
+
+}
+/*-- 16.12.98 16:03:58---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Type SwXStyleFamily::getElementType(void) throw( RuntimeException )
+{
+    return ::getCppuType((const Reference*)0);
+
+}
+/*-- 16.12.98 16:03:58---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXStyleFamily::hasElements(void) throw( RuntimeException )
+{
+    if(!pBasePool)
+        throw RuntimeException();
+    return sal_True;
+}
+/*-- 16.12.98 16:03:58---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXStyleFamily::insertByName(const OUString& rName, const Any& rElement)
+        throw( lang::IllegalArgumentException, container::ElementExistException, lang::WrappedTargetException, RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(pBasePool)
+    {
+        String sStyleName(rName);
+        pBasePool->SetSearchMask(eFamily, SFXSTYLEBIT_ALL );
+        SfxStyleSheetBase* pBase = pBasePool->Find(sStyleName);
+        SfxStyleSheetBase* pUINameBase = pBasePool->Find(SwXStyleFamilies::GetUIName(sStyleName, eFamily));
+        if(pBase || pUINameBase)
+            throw container::ElementExistException();
+        else
+        {
+            if(rElement.getValueType().getTypeClass() ==
+                                            TypeClass_INTERFACE)
+            {
+                Reference< XInterface > * pxRef =
+                    (Reference< XInterface > *)rElement.getValue();
+
+                Reference xStyleTunnel( *pxRef, UNO_QUERY);
+
+                SwXStyle* pNewStyle = 0;
+                if(xStyleTunnel.is())
+                {
+                    pNewStyle = (SwXStyle*)xStyleTunnel->getSomething(
+                                            SwXStyle::getUnoTunnelId());
+                }
+                if(!pNewStyle || !pNewStyle->IsDescriptor() ||
+                    pNewStyle->GetFamily() != eFamily)
+                        throw lang::IllegalArgumentException();
+                if(pNewStyle)
+                {
+                    USHORT nMask = 0xffff;
+                    if(eFamily == SFX_STYLE_FAMILY_PARA && !pNewStyle->IsConditional())
+                        nMask &= ~SWSTYLEBIT_CONDCOLL;
+                    SfxStyleSheetBase& rNewBase = pBasePool->Make(sStyleName, eFamily, nMask);
+                    pNewStyle->SetDoc(pDocShell->GetDoc(), pBasePool);
+                    pNewStyle->SetStyleName(sStyleName);
+                    String sParentStyleName(pNewStyle->GetParentStyleName());
+                    if(sParentStyleName.Len())
+                    {
+                        pBasePool->SetSearchMask(eFamily, SFXSTYLEBIT_ALL );
+                        SfxStyleSheetBase* pParentBase = pBasePool->Find(sParentStyleName);
+                        if(pParentBase && pParentBase->GetFamily() == eFamily &&
+                            &pParentBase->GetPool() == pBasePool)
+                            pBasePool->SetParent( eFamily, sStyleName,  sParentStyleName );
+
+                    }
+                    //so, jetzt sollten noch die Properties des Descriptors angewandt werden
+                    pNewStyle->ApplyDescriptorProperties();
+                }
+                else
+                    throw lang::IllegalArgumentException();
+            }
+            else
+                throw lang::IllegalArgumentException();
+        }
+    }
+    else
+        throw RuntimeException();
+}
+/*-- 16.12.98 16:03:59---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXStyleFamily::replaceByName(const OUString& rName, const Any& rElement)
+    throw( lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(pBasePool)
+    {
+        pBasePool->SetSearchMask(eFamily);
+        SfxStyleSheetBase* pBase = pBasePool->Find(rName);
+        //Ersetzung geht nur fuer benutzerdefinierte Styles
+        if(!pBase)
+            throw container::NoSuchElementException();
+        if(!pBase->IsUserDefined())
+            throw lang::IllegalArgumentException();
+        //if theres an object available to this style then it must be invalidated
+        Reference< style::XStyle >  xStyle = _FindStyle(pBase->GetName());
+        if(xStyle.is())
+        {
+            Reference xTunnel( xStyle, UNO_QUERY);
+            if(xTunnel.is())
+            {
+                SwXStyle* pStyle = (SwXStyle*)xTunnel->getSomething(
+                                                    SwXStyle::getUnoTunnelId());
+                pStyle->Invalidate();
+            }
+        }
+
+        pBasePool->Erase(pBase);
+        insertByName(rName, rElement);
+    }
+    else
+        throw RuntimeException();
+}
+/*-- 16.12.98 16:03:59---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXStyleFamily::removeByName(const OUString& rName) throw( container::NoSuchElementException, lang::WrappedTargetException, RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(pBasePool)
+    {
+        pBasePool->SetSearchMask(eFamily, SFXSTYLEBIT_ALL );
+        SfxStyleSheetBase* pBase = pBasePool->Find(SwXStyleFamilies::GetUIName(rName, eFamily));
+        if(pBase)
+            pBasePool->Erase(pBase);
+        else
+            throw container::NoSuchElementException();
+    }
+    else
+        throw RuntimeException();
+}
+/*-- 16.12.98 16:03:59---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXStyleFamily::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+    SfxSimpleHint *pHint = PTR_CAST( SfxSimpleHint, &rHint );
+    if( pHint && ( pHint->GetId() & SFX_HINT_DYING ) )
+    {
+        pBasePool = 0;
+        pDocShell = 0;
+        EndListening(rBC);
+    }
+}
+/*-- 16.12.98 16:03:59---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXStyle*   SwXStyleFamily::_FindStyle(const String& rStyleName)const
+{
+    sal_uInt16  nLCount = pBasePool->GetListenerCount();
+    SfxListener* pListener = 0;
+    for( sal_uInt16 i = 0; i < nLCount; i++)
+    {
+        pListener = pBasePool->GetListener( i );
+        if(PTR_CAST(SwXStyle, pListener) && ((SwXStyle*)pListener)->GetFamily() == eFamily && ((SwXStyle*)pListener)->GetStyleName() == rStyleName)
+        {
+            return (SwXStyle*)pListener;
+        }
+    }
+    return 0;
+}
+/******************************************************************
+ *
+ ******************************************************************/
+class SwStyleProperties_Impl
+{
+    const SfxItemPropertyMap*   _pMap;
+    Any**                   pAnyArr;
+    sal_uInt16                      nArrLen;
+
+public:
+    SwStyleProperties_Impl(const SfxItemPropertyMap* _pMap);
+    ~SwStyleProperties_Impl();
+
+    sal_Bool    SetProperty(const String& rName, Any aVal);
+    sal_Bool    GetProperty(const String& rName, Any*& rpAny);
+
+    const SfxItemPropertyMap*   GetPropertyMap() const {return _pMap;}
+};
+//--------------------------------------------------------------------
+//--------------------------------------------------------------------
+SwStyleProperties_Impl::SwStyleProperties_Impl(const SfxItemPropertyMap* pMap) :
+    _pMap(pMap),
+    nArrLen(0)
+{
+    const SfxItemPropertyMap* pTmp = _pMap;
+    while(pTmp[nArrLen].nWID)
+    {
+        nArrLen++;
+    }
+
+    pAnyArr = new Any*[nArrLen];
+    for(sal_uInt16 i = 0; i < nArrLen; i++)
+        pAnyArr[i] = 0;
+
+}
+//--------------------------------------------------------------------
+//--------------------------------------------------------------------
+SwStyleProperties_Impl::~SwStyleProperties_Impl()
+{
+    for(sal_uInt16 i = 0; i < nArrLen; i++)
+        delete pAnyArr[i];
+    delete pAnyArr;
+}
+
+//--------------------------------------------------------------------
+//--------------------------------------------------------------------
+sal_Bool SwStyleProperties_Impl::SetProperty(const String& rName, Any aVal)
+{
+    sal_uInt16 nPos = 0;
+    const SfxItemPropertyMap* pTemp = _pMap;
+    while( pTemp->pName )
+    {
+        if(rName.EqualsAscii(pTemp->pName))
+            break;
+        ++nPos;
+        ++pTemp;
+    }
+    if(nPos < nArrLen)
+    {
+        delete pAnyArr[nPos];
+        pAnyArr[nPos] = new Any(aVal);
+    }
+    return nPos < nArrLen;
+}
+//--------------------------------------------------------------------
+//--------------------------------------------------------------------
+sal_Bool SwStyleProperties_Impl::GetProperty(const String& rName, Any*& rpAny )
+{
+    sal_uInt16 nPos = 0;
+    const SfxItemPropertyMap* pTemp = _pMap;
+    while( pTemp->pName )
+    {
+        if(rName.EqualsAscii(pTemp->pName))
+            break;
+        ++nPos;
+        ++pTemp;
+    }
+    if(nPos < nArrLen)
+    {
+        rpAny = pAnyArr[nPos];
+    }
+    return rpAny && nPos < nArrLen;
+}
+
+/******************************************************************
+ *
+ ******************************************************************/
+/* -----------------------------10.03.00 18:02--------------------------------
+
+ ---------------------------------------------------------------------------*/
+const Sequence< sal_Int8 > & SwXStyle::getUnoTunnelId()
+{
+    static Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId();
+    return aSeq;
+}
+/* -----------------------------10.03.00 18:04--------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Int64 SAL_CALL SwXStyle::getSomething( const Sequence< sal_Int8 >& rId )
+    throw(RuntimeException)
+{
+    if( rId.getLength() == 16
+        && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+                                        rId.getConstArray(), 16 ) )
+    {
+            return (sal_Int64)this;
+    }
+    return 0;
+}
+
+TYPEINIT1(SwXStyle, SfxListener);
+/* -----------------------------06.04.00 11:24--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXStyle::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXStyle");
+}
+/* -----------------------------06.04.00 11:24--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXStyle::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    BOOL bRet = C2U("com.sun.star.style.Style") == rServiceName;
+    if(!bRet && SFX_STYLE_FAMILY_CHAR == eFamily)
+        bRet = C2U("com.sun.star.style.CharacterProperties") == rServiceName;
+    if(!bRet && SFX_STYLE_FAMILY_PARA == eFamily)
+        bRet = (C2U("com.sun.star.style.ParagraphStyle") == rServiceName)||
+            (C2U("com.sun.star.style.ParagraphProperties") == rServiceName);
+
+    return  bRet;
+}
+/* -----------------------------06.04.00 11:24--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXStyle::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    long nCount = 1;
+    if(SFX_STYLE_FAMILY_PARA == eFamily)
+    {
+        nCount = 3;
+        if(bIsConditional)
+            nCount++;
+    }
+    else if(SFX_STYLE_FAMILY_CHAR == eFamily)
+        nCount = 2;
+    Sequence< OUString > aRet(nCount);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.style.Style");
+    switch(eFamily)
+    {
+        case SFX_STYLE_FAMILY_CHAR:     pArray[1] = C2U("com.sun.star.style.CharacterProperties"); break;
+        case SFX_STYLE_FAMILY_PARA:
+            pArray[1] = C2U("com.sun.star.style.ParagraphStyle");
+            pArray[2] = C2U("com.sun.star.style.ParagraphProperties");
+        if(bIsConditional)
+            pArray[3] = C2U("com.sun.star.style.ConditionalParagraphStyle");
+        break;
+    }
+    return aRet;
+}
+/*-- 17.12.98 08:26:49---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXStyle::SwXStyle(SfxStyleFamily eFam, BOOL bConditional) :
+    m_pDoc(0),
+    bIsDescriptor(sal_True),
+    bIsConditional(bConditional),
+    eFamily(eFam),
+    pBasePool(0)
+{
+    sal_uInt16 nMapId = PROPERTY_MAP_CHAR_STYLE;
+    switch( eFamily )
+    {
+        //case SFX_STYLE_FAMILY_CHAR:   nMapId = PROPERTY_MAP_CHAR_STYLE;       break;
+        case SFX_STYLE_FAMILY_PARA: nMapId = PROPERTY_MAP_PARA_STYLE;       break;
+        case SFX_STYLE_FAMILY_PAGE: nMapId = PROPERTY_MAP_PAGE_STYLE;       break;
+        case SFX_STYLE_FAMILY_FRAME :   nMapId = PROPERTY_MAP_FRAME_STYLE;  break;
+        case SFX_STYLE_FAMILY_PSEUDO:   nMapId = PROPERTY_MAP_NUM_STYLE;    break;
+    }
+    pPropImpl = new SwStyleProperties_Impl(aSwMapProvider.GetPropertyMap(nMapId));
+}
+/*-- 17.12.98 08:26:50---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXStyle::SwXStyle(SfxStyleSheetBasePool& rPool, SfxStyleFamily eFam,
+        SwDoc*  pDoc,   const String& rStyleName) :
+    sStyleName(rStyleName),
+    pBasePool(&rPool),
+    eFamily(eFam),
+    m_pDoc(pDoc),
+    bIsDescriptor(sal_False),
+    bIsConditional(sal_False),
+    pPropImpl(0)
+{
+    StartListening(rPool);
+    if(eFam == SFX_STYLE_FAMILY_PARA)
+    {
+        pBasePool->SetSearchMask(eFamily, SFXSTYLEBIT_ALL );
+        SfxStyleSheetBase* pBase = pBasePool->Find(sStyleName);
+        DBG_ASSERT(pBase, "wo ist der Style?")
+        if(pBase)
+        {
+            const USHORT nId = pDoc->GetPoolId(sStyleName, GET_POOLID_TXTCOLL);
+            if(nId != USHRT_MAX)
+                ::IsConditionalByPoolId( nId );
+            else
+                bIsConditional = RES_CONDTXTFMTCOLL == ((SwDocStyleSheet*)pBase)->GetCollection()->Which();
+        }
+    }
+}
+/*-- 17.12.98 08:26:50---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXStyle::~SwXStyle()
+{
+    if(pBasePool)
+        EndListening(*pBasePool);
+    delete pPropImpl;
+}
+/*-- 17.12.98 08:26:51---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+OUString SwXStyle::getName(void) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    OUString sRet;
+    if(pBasePool)
+    {
+        pBasePool->SetSearchMask(eFamily, SFXSTYLEBIT_ALL );
+        SfxStyleSheetBase* pBase = pBasePool->Find(sStyleName);
+        DBG_ASSERT(pBase, "wo ist der Style?")
+        if(!pBase)
+            throw RuntimeException();
+        sRet = SwXStyleFamilies::GetProgrammaticName(pBase->GetName(), eFamily);
+    }
+    else
+        sRet = sStyleName;
+    return sRet;
+}
+/*-- 17.12.98 08:26:51---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXStyle::setName(const OUString& rName) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(pBasePool)
+    {
+        pBasePool->SetSearchMask(eFamily, SFXSTYLEBIT_ALL );
+        SfxStyleSheetBase* pBase = pBasePool->Find(sStyleName);
+        DBG_ASSERT(pBase, "wo ist der Style?")
+        sal_Bool bExcept = sal_True;
+        if(pBase && pBase->IsUserDefined())
+        {
+            SwDocStyleSheet aTmp( *(SwDocStyleSheet*)pBase );
+             bExcept = !aTmp.SetName(rName);
+            if(!bExcept)
+                sStyleName = String(rName);
+        }
+        if(bExcept)
+            throw RuntimeException();
+    }
+    else
+        sStyleName = String(rName);
+}
+/*-- 17.12.98 08:26:51---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXStyle::isUserDefined(void) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Bool bRet = sal_False;
+    if(pBasePool)
+    {
+        pBasePool->SetSearchMask(eFamily, SFXSTYLEBIT_ALL );
+        SfxStyleSheetBase* pBase = pBasePool->Find(sStyleName);
+        //if it is not found it must be non user defined
+        if(pBase)
+            bRet = pBase->IsUserDefined();
+    }
+    else
+        throw RuntimeException();
+    return bRet;
+}
+/*-- 17.12.98 08:26:51---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXStyle::isInUse(void) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Bool bRet = sal_False;
+    if(pBasePool)
+    {
+        pBasePool->SetSearchMask(eFamily, SFXSTYLEBIT_USED);
+        SfxStyleSheetBase* pBase = pBasePool->Find(sStyleName);
+        if(pBase)
+            bRet = pBase->IsUsed();
+    }
+    else
+        throw RuntimeException();
+    return bRet;
+}
+/*-- 17.12.98 08:26:52---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+OUString SwXStyle::getParentStyle(void) throw( RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    OUString sRet;
+    if(pBasePool)
+    {
+        pBasePool->SetSearchMask(eFamily, SFXSTYLEBIT_ALL);
+        SfxStyleSheetBase* pBase = pBasePool->Find(sStyleName);
+        if(pBase)
+            sRet = pBase->GetParent();
+    }
+    else if(bIsDescriptor)
+        sRet = sParentStyleName;
+    else
+        throw RuntimeException();
+    return SwXStyleFamilies::GetProgrammaticName(sRet, eFamily);
+}
+/*-- 17.12.98 08:26:52---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXStyle::setParentStyle(const OUString& rParentStyle)
+            throw( container::NoSuchElementException, RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    String sParentStyle = SwXStyleFamilies::GetUIName(rParentStyle, eFamily);
+    if(pBasePool)
+    {
+        pBasePool->SetSearchMask(eFamily);
+        BOOL bExcept = FALSE;
+        SfxStyleSheetBase* pBase = pBasePool->Find(sStyleName);
+        if(pBase)
+        {
+            SwDocStyleSheet aBase(*(SwDocStyleSheet*)pBase);
+            if(aBase.GetParent() != sParentStyle)
+            {
+                bExcept = !aBase.SetParent(sParentStyle);
+            }
+        }
+        else
+            bExcept = TRUE;
+        if(bExcept)
+            throw RuntimeException();
+    }
+    else if(bIsDescriptor)
+    {
+        sParentStyleName = String(sParentStyle);
+    }
+    else
+        throw RuntimeException();
+}
+/*-- 17.12.98 08:26:52---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Reference< beans::XPropertySetInfo >  SwXStyle::getPropertySetInfo(void)
+    throw( RuntimeException )
+{
+    Reference< beans::XPropertySetInfo >  xRet;
+    switch( eFamily )
+    {
+        case SFX_STYLE_FAMILY_CHAR:
+        {
+            static Reference< beans::XPropertySetInfo >  xCharRef;
+            if(!xCharRef.is())
+            {
+                SfxItemPropertySet aPropSet(
+                    aSwMapProvider.GetPropertyMap(PROPERTY_MAP_CHAR_STYLE));
+                xCharRef = aPropSet.getPropertySetInfo();
+            }
+            xRet = xCharRef;
+        }
+        break;
+        case SFX_STYLE_FAMILY_PARA:
+        {
+            static Reference< beans::XPropertySetInfo >  xParaRef;
+            if(!xParaRef.is())
+            {
+                SfxItemPropertySet aPropSet(
+                    aSwMapProvider.GetPropertyMap(PROPERTY_MAP_PARA_STYLE));
+                xParaRef = aPropSet.getPropertySetInfo();
+            }
+            xRet = xParaRef;
+        }
+        break;
+        case SFX_STYLE_FAMILY_PAGE     :
+        {
+            static Reference< beans::XPropertySetInfo >  xPageRef;
+            if(!xPageRef.is())
+            {
+                SfxItemPropertySet aPropSet(
+                    aSwMapProvider.GetPropertyMap(PROPERTY_MAP_PAGE_STYLE) );
+                xPageRef = aPropSet.getPropertySetInfo();
+            }
+            xRet = xPageRef;
+        }
+        break;
+        case SFX_STYLE_FAMILY_FRAME    :
+        {
+            static Reference< beans::XPropertySetInfo >  xFrameRef;
+            if(!xFrameRef.is())
+            {
+                SfxItemPropertySet aPropSet(
+                aSwMapProvider.GetPropertyMap(PROPERTY_MAP_FRAME_STYLE));
+                xFrameRef = aPropSet.getPropertySetInfo();
+            }
+            xRet = xFrameRef;
+        }
+        break;
+        case SFX_STYLE_FAMILY_PSEUDO:
+        {
+            static Reference< beans::XPropertySetInfo >  xNumRef;
+            if(!xNumRef.is())
+            {
+                SfxItemPropertySet aPropSet(
+                    aSwMapProvider.GetPropertyMap(PROPERTY_MAP_NUM_STYLE));
+                xNumRef = aPropSet.getPropertySetInfo();
+            }
+            xRet = xNumRef;
+        }
+        break;
+    }
+    return xRet;
+}
+/* -----------------23.04.99 13:28-------------------
+ *
+ * --------------------------------------------------*/
+void    SwXStyle::ApplyDescriptorProperties()
+{
+    bIsDescriptor = sal_False;
+    const SfxItemPropertyMap* pTemp = pPropImpl->GetPropertyMap();
+    while(pTemp->nWID)
+    {
+        Any* pAny;
+        String sPropName(C2S(pTemp->pName));
+        OUString sUPropName(sPropName);
+        pPropImpl->GetProperty(sPropName, pAny);
+        if(pAny)
+            setPropertyValue(sUPropName, *pAny);
+        pTemp++;
+    }
+}
+
+/*-- 17.12.98 08:26:53---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXStyle::setPropertyValue(const OUString& rPropertyName, const Any& aValue)
+    throw( beans::UnknownPropertyException,
+        beans::PropertyVetoException,
+        lang::IllegalArgumentException,
+         lang::WrappedTargetException,
+        RuntimeException)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Int8 nPropSetId = PROPERTY_SET_CHAR_STYLE;
+    switch(eFamily)
+    {
+        case SFX_STYLE_FAMILY_PARA: nPropSetId = PROPERTY_SET_PARA_STYLE  ; break;
+        case SFX_STYLE_FAMILY_FRAME: nPropSetId = PROPERTY_SET_FRAME_STYLE ;break;
+        case SFX_STYLE_FAMILY_PAGE: nPropSetId = PROPERTY_SET_PAGE_STYLE  ;break;
+        case SFX_STYLE_FAMILY_PSEUDO: nPropSetId = PROPERTY_SET_NUM_STYLE   ;break;
+    }
+    SfxItemPropertySet& aPropSet = aSwMapProvider.GetPropertySet(nPropSetId);
+
+    const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                                    aPropSet.getPropertyMap(), rPropertyName);
+    if(!pMap)
+        throw beans::UnknownPropertyException();
+    if(pBasePool)
+    {
+        pBasePool->SetSearchMask(eFamily);
+        SfxStyleSheetBase* pBase = pBasePool->Find(sStyleName);
+        DBG_ASSERT(pBase, "wo ist der Style?")
+        if(pBase)
+        {
+            SwDocStyleSheet aBase(*(SwDocStyleSheet*)pBase);
+            switch(pMap->nWID)
+            {
+                case  FN_UNO_NUM_RULES: //Sonderbehandlung fuer das SvxNumRuleItem:
+                {
+                    if(aValue.getValueType() == ::getCppuType((Reference< container::XIndexReplace>*)0) )
+                    {
+                        Reference< container::XIndexReplace > * pxRulesRef =
+                                (Reference< container::XIndexReplace > *)aValue.getValue();
+
+                        Reference xNumberTunnel( *pxRulesRef, UNO_QUERY);
+
+                        SwXNumberingRules* pSwXRules = 0;
+                        if(xNumberTunnel.is())
+                        {
+                            pSwXRules = (SwXNumberingRules*)
+                                xNumberTunnel->getSomething(
+                                                    SwXNumberingRules::getUnoTunnelId());
+                        }
+                        if(pSwXRules)
+                        {
+                            const String* pCharStyleNames = pSwXRules->GetNewCharStyleNames();
+                            const String* pBulletFontNames = pSwXRules->GetBulletFontNames();
+
+                            SwNumRule aSetRule(*pSwXRules->GetNumRule());
+                            const SwCharFmts* pFmts = m_pDoc->GetCharFmts();
+                            sal_uInt16 nChCount = pFmts->Count();
+                            for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
+                            {
+
+                                const SwNumFmt* pFmt = aSetRule.GetNumFmt( i );
+                                if(pFmt)
+                                {
+                                    SwNumFmt aFmt(*pFmt);
+                                    if(
+                                        pCharStyleNames[i] != SwXNumberingRules::GetInvalidStyle() &&
+                                        ((pCharStyleNames[i].Len() && !pFmt->GetCharFmt()) ||
+                                        pCharStyleNames[i].Len() &&
+                                                    pFmt->GetCharFmt()->GetName() != pCharStyleNames[i] ))
+                                    {
+
+                                        SwCharFmt* pCharFmt = 0;
+                                        if(pCharStyleNames[i].Len())
+                                        {
+                                            for(sal_uInt16 j = 0; j< nChCount; j++)
+                                            {
+                                                SwCharFmt* pTmp = (*pFmts)[j];
+                                                if(pTmp->GetName() == pCharStyleNames[i])
+                                                {
+                                                    pCharFmt = pTmp;
+                                                    break;
+                                                }
+                                            }
+                                            if(!pCharFmt)
+                                            {
+
+                                                SfxStyleSheetBase* pBase;
+                                                pBase = ((SfxStyleSheetBasePool*)pBasePool)->Find(pCharStyleNames[i], SFX_STYLE_FAMILY_CHAR);
+                                                if(!pBase)
+                                                    pBase = &pBasePool->Make(pCharStyleNames[i], SFX_STYLE_FAMILY_CHAR);
+                                                pCharFmt = ((SwDocStyleSheet*)pBase)->GetCharFmt();
+
+                                            }
+
+                                            aFmt.SetCharFmt( pCharFmt );
+                                        }
+                                    }
+                                    //jetzt nochmal fuer Fonts
+                                    if(pBulletFontNames[i] != SwXNumberingRules::GetInvalidStyle() &&
+                                        ((pBulletFontNames[i].Len() && !pFmt->GetBulletFont()) ||
+                                        pBulletFontNames[i].Len() &&
+                                                pFmt->GetBulletFont()->GetName() != pBulletFontNames[i] ))
+                                    {
+                                        const SvxFontListItem* pFontListItem =
+                                                (const SvxFontListItem* )m_pDoc->GetDocShell()
+                                                                    ->GetItem( SID_ATTR_CHAR_FONTLIST );
+                                        const FontList*  pList = pFontListItem->GetFontList();
+                                        FontInfo aInfo = pList->Get(
+                                            pBulletFontNames[i],WEIGHT_NORMAL, ITALIC_NONE);
+                                        Font aFont(aInfo);
+                                        aFmt.SetBulletFont(&aFont);
+                                    }
+                                    aSetRule.Set( i, &aFmt );
+                                }
+                            }
+                            aBase.SetNumRule(aSetRule);
+                        }
+                    }
+                    else
+                        throw lang::IllegalArgumentException();
+                }
+                break;
+                case FN_UNO_FOLLOW_STYLE:
+                {
+                    OUString sTmp;
+                    aValue >>= sTmp;
+                    aBase.SetFollow( SwXStyleFamilies::GetUIName(sTmp, eFamily)) ;
+                }
+                break;
+                case RES_PAGEDESC :
+                {
+                    // Sonderbehandlung RES_PAGEDESC
+                    if(aValue.getValueType() != ::getCppuType((const OUString*)0))
+                        throw lang::IllegalArgumentException();
+                    const SfxItemSet& rStyleSet = aBase.GetItemSet();
+                    SfxItemSet aSet(*rStyleSet.GetPool(), RES_PAGEDESC, RES_PAGEDESC);
+                    aSet.Put(rStyleSet);
+
+                    SwFmtPageDesc* pNewDesc = 0;
+                    const SfxPoolItem* pItem;
+                    if(SFX_ITEM_SET == aSet.GetItemState( RES_PAGEDESC, sal_True, &pItem ) )
+                    {
+                        pNewDesc = new SwFmtPageDesc(*((SwFmtPageDesc*)pItem));
+                    }
+                    if(!pNewDesc)
+                        pNewDesc = new SwFmtPageDesc();
+                    OUString uDescName;
+                    aValue >>= uDescName;
+                    String sDescName(uDescName);
+                    if(!pNewDesc->GetPageDesc() || pNewDesc->GetPageDesc()->GetName() != sDescName)
+                    {
+                        sal_uInt16 nCount = m_pDoc->GetPageDescCnt();
+                        sal_Bool bPut = sal_False;
+                        if(sDescName.Len())
+                        {
+                            SwPageDesc* pPageDesc = ::GetPageDescByName_Impl(*m_pDoc, sDescName);
+                            if(pPageDesc)
+                            {
+                                pPageDesc->Add( pNewDesc );
+                                bPut = sal_True;
+                            }
+                            else
+                            {
+                                throw lang::IllegalArgumentException();
+                            }
+                        }
+                        if(!bPut)
+                        {
+                            aSet.ClearItem(RES_BREAK);
+                            aSet.Put(SwFmtPageDesc());
+                        }
+                        else
+                            aSet.Put(*pNewDesc);
+                    }
+                    aBase.SetItemSet(aSet);
+                    delete pNewDesc;
+                }
+                break;
+                case FN_UNO_IS_AUTO_UPDATE:
+                {
+                    BOOL bAuto = *(sal_Bool*)aValue.getValue();
+                    if(SFX_STYLE_FAMILY_PARA == eFamily)
+                        aBase.GetCollection()->SetAutoUpdateFmt(bAuto);
+                    else if(SFX_STYLE_FAMILY_FRAME == eFamily)
+                        aBase.GetFrmFmt()->SetAutoUpdateFmt(bAuto);
+                }
+                break;
+                case FN_UNO_CATEGORY:
+                {
+                    if(!aBase.IsUserDefined())
+                        throw lang::IllegalArgumentException();
+                    short nSet;
+                    aValue >>= nSet;
+
+                    USHORT nId = aBase.GetCollection()->GetPoolFmtId() &
+                                    ~ ( COLL_GET_RANGE_BITS | POOLGRP_NOCOLLID );
+                    switch( nSet )
+                    {
+                        case ParagraphStyleCategory::TEXT:
+                            nId |= COLL_TEXT_BITS;
+                            break;
+                        case ParagraphStyleCategory::CHAPTER:
+                            nId |= COLL_DOC_BITS;
+                            break;
+                        case ParagraphStyleCategory::LIST:
+                            nId |= COLL_LISTS_BITS;
+                            break;
+                        case ParagraphStyleCategory::INDEX:
+                            nId |= COLL_REGISTER_BITS;
+                            break;
+                        case ParagraphStyleCategory::EXTRA:
+                            nId |= COLL_EXTRA_BITS;
+                            break;
+                        case ParagraphStyleCategory::HTML:
+                            nId |= COLL_HTML_BITS;
+                            break;
+                        default: throw lang::IllegalArgumentException();
+                    }
+                    aBase.GetCollection()->SetPoolFmtId( nId );
+                }
+                break;
+                case RES_PARATR_DROP:
+                {
+                    if( MID_DROPCAP_CHAR_STYLE_NAME == pMap->nMemberId)
+                    {
+                        if(aValue.getValueType() == ::getCppuType((const OUString*)0))
+                        {
+                            const SfxItemSet& rStyleSet = aBase.GetItemSet();
+                            SfxItemSet aSet(*rStyleSet.GetPool(), RES_PARATR_DROP, RES_PARATR_DROP);
+                            aSet.Put(rStyleSet);
+
+                            SwFmtDrop* pDrop = 0;
+                            const SfxPoolItem* pItem;
+                            if(SFX_ITEM_SET == aSet.GetItemState( RES_PARATR_DROP, sal_True, &pItem ) )
+                                pDrop = new SwFmtDrop(*((SwFmtDrop*)pItem));
+                            if(!pDrop)
+                                pDrop = new SwFmtDrop();
+                            OUString uStyle;
+                            aValue >>= uStyle;
+                            String sStyle(SwXStyleFamilies::GetUIName(uStyle, SFX_STYLE_FAMILY_CHAR));
+                            SwDocStyleSheet* pStyle =
+                                (SwDocStyleSheet*)m_pDoc->GetDocShell()->GetStyleSheetPool()->Find(sStyle, SFX_STYLE_FAMILY_CHAR);
+                            if(pStyle)
+                                pDrop->SetCharFmt(pStyle->GetCharFmt());
+                            else
+                                 throw lang::IllegalArgumentException();
+                            aSet.Put(*pDrop);
+                            aBase.SetItemSet(aSet);
+                            delete pDrop;
+                        }
+                        else
+                            throw lang::IllegalArgumentException();
+                        break;
+                    }
+                }
+                //no break!
+                default:
+                {
+                    SfxItemSet& rStyleSet = aBase.GetItemSet();
+                    SfxItemSet aSet(*rStyleSet.GetPool(), pMap->nWID, pMap->nWID);
+                    aSet.Put(rStyleSet);
+                    aPropSet.setPropertyValue(rPropertyName, aValue, aSet);
+
+                    aBase.SetItemSet(aSet);
+                }
+            }
+        }
+        else
+            throw RuntimeException();
+    }
+    else if(bIsDescriptor)
+    {
+        if(!pPropImpl->SetProperty(rPropertyName, aValue))
+            throw lang::IllegalArgumentException();
+    }
+    else
+        throw RuntimeException();
+}
+/*-- 17.12.98 08:26:53---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Any SwXStyle::getPropertyValue(const OUString& rPropertyName)
+    throw( beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    Any aRet;
+
+    sal_Int8 nPropSetId = PROPERTY_SET_CHAR_STYLE;
+    switch(eFamily)
+    {
+        case SFX_STYLE_FAMILY_PARA: nPropSetId = PROPERTY_SET_PARA_STYLE  ; break;
+        case SFX_STYLE_FAMILY_FRAME: nPropSetId = PROPERTY_SET_FRAME_STYLE ;break;
+        case SFX_STYLE_FAMILY_PAGE: nPropSetId = PROPERTY_SET_PAGE_STYLE  ;break;
+        case SFX_STYLE_FAMILY_PSEUDO: nPropSetId = PROPERTY_SET_NUM_STYLE   ;break;
+    }
+    SfxItemPropertySet& aPropSet = aSwMapProvider.GetPropertySet(nPropSetId);
+
+    const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                                    aPropSet.getPropertyMap(), rPropertyName);
+    if(!pMap)
+        throw beans::UnknownPropertyException();
+    if(pBasePool)
+    {
+        USHORT nSaveMask = pBasePool->GetSearchMask();
+        pBasePool->SetSearchMask(eFamily, SFXSTYLEBIT_ALL );
+        SfxStyleSheetBase* pBase = pBasePool->Find(sStyleName);
+        pBasePool->SetSearchMask(eFamily, nSaveMask );
+        if(FN_UNO_IS_PHYSICAL == pMap->nWID)
+        {
+            BOOL bPhys = pBase != 0;
+            if(pBase)
+            {
+                bPhys = ((SwDocStyleSheet*)pBase)->IsPhysical();
+                // The standard character format is not existing physically
+                if( bPhys && SFX_STYLE_FAMILY_CHAR == eFamily &&
+                    ((SwDocStyleSheet*)pBase)->GetCharFmt() &&
+                    ((SwDocStyleSheet*)pBase)->GetCharFmt()->IsDefault() )
+                    bPhys = FALSE;
+            }
+            aRet.setValue(&bPhys, ::getBooleanCppuType());
+        }
+        else if(pBase)
+        {
+            SwDocStyleSheet aStyle( *(SwDocStyleSheet*)pBase );
+            switch(pMap->nWID)
+            {
+                case  FN_UNO_NUM_RULES: //Sonderbehandlung fuer das SvxNumRuleItem:
+                {
+                    const SwNumRule* pRule = aStyle.GetNumRule();
+                    DBG_ASSERT(pRule, "Wo ist die NumRule?")
+                    Reference< container::XIndexReplace >  xRules = new SwXNumberingRules(*pRule);
+                    aRet.setValue(&xRules, ::getCppuType((Reference*)0));
+                }
+                break;
+                case FN_UNO_FOLLOW_STYLE:
+                    aRet <<= OUString(SwXStyleFamilies::GetProgrammaticName(aStyle.GetFollow(), eFamily));
+                break;
+                case RES_PAGEDESC :
+                {
+                    // Sonderbehandlung RES_PAGEDESC
+                    const SfxPoolItem* pItem;
+                    if(SFX_ITEM_SET == aStyle.GetItemSet().GetItemState( RES_PAGEDESC, sal_True, &pItem ) )
+                    {
+                        const SwPageDesc* pDesc = ((const SwFmtPageDesc*)pItem)->GetPageDesc();
+                        if(pDesc)
+                            aRet <<= OUString(pDesc->GetName());
+                    }
+                }
+                break;
+                case FN_UNO_IS_AUTO_UPDATE:
+                {
+                    BOOL bAuto = FALSE;
+                    if(SFX_STYLE_FAMILY_PARA == eFamily)
+                        bAuto = aStyle.GetCollection()->IsAutoUpdateFmt();
+                    else if(SFX_STYLE_FAMILY_FRAME == eFamily)
+                        bAuto = aStyle.GetFrmFmt()->IsAutoUpdateFmt();
+                    aRet.setValue(&bAuto, ::getBooleanCppuType());
+                }
+                break;
+                case FN_UNO_DISPLAY_NAME:
+                {
+                    OUString sName(aStyle.GetName());
+                    aRet <<= sName;
+                }
+                break;
+                case FN_UNO_CATEGORY:
+                {
+                    USHORT nPoolId = aStyle.GetCollection()->GetPoolFmtId();
+                    short nRet = -1;
+                    switch ( COLL_GET_RANGE_BITS & nPoolId )
+                    {
+                        case COLL_TEXT_BITS:
+                            nRet = ParagraphStyleCategory::TEXT;
+                            break;
+                        case COLL_DOC_BITS:
+                            nRet = ParagraphStyleCategory::CHAPTER;
+                            break;
+                        case COLL_LISTS_BITS:
+                            nRet = ParagraphStyleCategory::LIST;
+                            break;
+                        case COLL_REGISTER_BITS:
+                            nRet = ParagraphStyleCategory::INDEX;
+                            break;
+                        case COLL_EXTRA_BITS:
+                            nRet = ParagraphStyleCategory::EXTRA;
+                            break;
+                        case COLL_HTML_BITS:
+                            nRet = ParagraphStyleCategory::HTML;
+                            break;
+                    }
+                    aRet <<= nRet;
+                }
+                break;
+                default:
+                {
+                    SfxItemSet& rSet = aStyle.GetItemSet();
+                    aRet = aPropSet.getPropertyValue(rPropertyName, rSet);
+                }
+            }
+        }
+        else
+            throw RuntimeException();
+    }
+    else if(bIsDescriptor)
+    {
+        Any* pAny = 0;
+        if(!pPropImpl->GetProperty(rPropertyName, pAny))
+            throw lang::IllegalArgumentException();
+        else if(pAny)
+            aRet = *pAny;
+    }
+    else
+        throw RuntimeException();
+    return aRet;
+}
+/*-- 17.12.98 08:26:53---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXStyle::addPropertyChangeListener(const OUString& PropertyName,
+    const Reference< beans::XPropertyChangeListener > & aListener)
+    throw( beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 17.12.98 08:26:54---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXStyle::removePropertyChangeListener(const OUString& PropertyName,
+    const Reference< beans::XPropertyChangeListener > & aListener)
+    throw( beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 17.12.98 08:26:54---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXStyle::addVetoableChangeListener(const OUString& PropertyName,
+    const Reference< beans::XVetoableChangeListener > & aListener)
+    throw( beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 17.12.98 08:26:54---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXStyle::removeVetoableChangeListener(const OUString& PropertyName,
+    const Reference< beans::XVetoableChangeListener > & aListener)
+    throw( beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+
+/*-- 08.03.99 10:50:26---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+beans::PropertyState SwXStyle::getPropertyState(const OUString& rPropertyName)
+        throw( beans::UnknownPropertyException, RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    beans::PropertyState eRet = beans::PropertyState_DEFAULT_VALUE;
+    if(pBasePool)
+    {
+        pBasePool->SetSearchMask(eFamily );
+        SfxStyleSheetBase* pBase = pBasePool->Find(sStyleName);
+        DBG_ASSERT(pBase, "wo ist der Style?")
+
+        if(pBase)
+        {
+            SwDocStyleSheet aStyle( *(SwDocStyleSheet*)pBase );
+            String sPropName(rPropertyName);
+            //Sonderbehandlung fuer das SvxNumRuleItem:
+            if(sPropName.EqualsAscii(UNO_NAME_NUMBERING_RULES))
+            {
+                eRet = beans::PropertyState_DIRECT_VALUE;
+            }
+            else if(sPropName.EqualsAscii(UNO_NAME_FOLLOW_STYLE))
+            {
+                eRet = beans::PropertyState_DIRECT_VALUE;
+            }
+            else
+            {
+                sal_Int8 nPropSetId = PROPERTY_SET_CHAR_STYLE;
+                switch(eFamily)
+                {
+                    case SFX_STYLE_FAMILY_PARA: nPropSetId = PROPERTY_SET_PARA_STYLE  ; break;
+                    case SFX_STYLE_FAMILY_FRAME: nPropSetId = PROPERTY_SET_FRAME_STYLE ;break;
+                    case SFX_STYLE_FAMILY_PAGE: nPropSetId = PROPERTY_SET_PAGE_STYLE  ;break;
+                    case SFX_STYLE_FAMILY_PSEUDO: nPropSetId = PROPERTY_SET_NUM_STYLE   ;break;
+                }
+
+                SfxItemSet aSet = aStyle.GetItemSet();
+                eRet = aSwMapProvider.GetPropertySet(nPropSetId).
+                                    getPropertyState(sPropName, aSet);
+            }
+        }
+        else
+            throw RuntimeException();
+    }
+    else
+        throw RuntimeException();
+    return eRet;
+}
+/*-- 08.03.99 10:50:27---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Sequence< beans::PropertyState > SwXStyle::getPropertyStates(
+    const Sequence< OUString >& PropertyNames)
+    throw( beans::UnknownPropertyException, RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    const OUString* pNames = PropertyNames.getConstArray();
+    Sequence< beans::PropertyState > aRet(PropertyNames.getLength());
+    beans::PropertyState* pStates = aRet.getArray();
+    for(sal_Int32 i = 0; i < PropertyNames.getLength(); i++)
+        pStates[i] = getPropertyState(pNames[i]);
+    return aRet;
+}
+/*-- 08.03.99 10:50:27---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXStyle::setPropertyToDefault(const OUString& rPropertyName)
+        throw( beans::UnknownPropertyException, RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(pBasePool)
+    {
+        pBasePool->SetSearchMask(eFamily);
+        SfxStyleSheetBase* pBase = pBasePool->Find(sStyleName);
+        DBG_ASSERT(pBase, "wo ist der Style?")
+
+        if(pBase)
+        {
+            SwDocStyleSheet aStyle( *(SwDocStyleSheet*)pBase );
+            String sPropName(rPropertyName);
+            //Sonderbehandlung fuer das SvxNumRuleItem:
+            if(sPropName.EqualsAscii(UNO_NAME_NUMBERING_RULES))
+            {
+                throw RuntimeException();
+            }
+            else if(sPropName.EqualsAscii(UNO_NAME_FOLLOW_STYLE))
+            {
+                throw RuntimeException();
+            }
+            else
+            {
+                sal_Int8 nPropSetId = PROPERTY_SET_CHAR_STYLE;
+                switch(eFamily)
+                {
+                    case SFX_STYLE_FAMILY_PARA: nPropSetId = PROPERTY_SET_PARA_STYLE  ; break;
+                    case SFX_STYLE_FAMILY_FRAME: nPropSetId = PROPERTY_SET_FRAME_STYLE ;break;
+                    case SFX_STYLE_FAMILY_PAGE: nPropSetId = PROPERTY_SET_PAGE_STYLE  ;break;
+                    case SFX_STYLE_FAMILY_PSEUDO: nPropSetId = PROPERTY_SET_NUM_STYLE   ;break;
+                }
+
+                SfxItemSet aSet(aStyle.GetItemSet());
+                const SfxItemPropertyMap* _pMap = aSwMapProvider.GetPropertyMap(nPropSetId);
+                const SfxItemPropertyMap* pMap = SfxItemPropertyMap::GetByName(
+                                                            _pMap, rPropertyName);
+
+                aSet.InvalidateItem( pMap->nWID);
+                aStyle.SetItemSet(aSet);
+            }
+        }
+        else
+            throw RuntimeException();
+    }
+    else
+        throw RuntimeException();
+}
+/*-- 08.03.99 10:50:27---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Any SwXStyle::getPropertyDefault(const OUString& rPropertyName)
+    throw( beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    Any aRet;
+    if(pBasePool)
+    {
+        pBasePool->SetSearchMask(eFamily);
+        SfxStyleSheetBase* pBase = pBasePool->Find(sStyleName);
+        DBG_ASSERT(pBase, "wo ist der Style?")
+
+        if(pBase)
+        {
+            SwDocStyleSheet aStyle( *(SwDocStyleSheet*)pBase );
+            String sPropName(rPropertyName);
+            //Sonderbehandlung fuer das SvxNumRuleItem:
+            if(!sPropName.EqualsAscii(UNO_NAME_NUMBERING_RULES) &&
+                !sPropName.EqualsAscii(UNO_NAME_FOLLOW_STYLE))
+            {
+                sal_Int8 nPropSetId = PROPERTY_SET_CHAR_STYLE;
+                switch(eFamily)
+                {
+                    case SFX_STYLE_FAMILY_PARA: nPropSetId = PROPERTY_SET_PARA_STYLE  ; break;
+                    case SFX_STYLE_FAMILY_FRAME: nPropSetId = PROPERTY_SET_FRAME_STYLE ;break;
+                    case SFX_STYLE_FAMILY_PAGE: nPropSetId = PROPERTY_SET_PAGE_STYLE  ;break;
+                    case SFX_STYLE_FAMILY_PSEUDO: nPropSetId = PROPERTY_SET_NUM_STYLE   ;break;
+                }
+
+                SfxItemSet aSet = aStyle.GetItemSet();
+                const SfxItemPropertyMap* _pMap = aSwMapProvider.GetPropertyMap(nPropSetId);
+                const SfxItemPropertyMap* pMap = SfxItemPropertyMap::GetByName(
+                                                            _pMap, sPropName);
+                const SfxItemSet* pParentSet = aSet.GetParent();
+                if(pParentSet)
+                    aRet = aSwMapProvider.GetPropertySet(nPropSetId).
+                                    getPropertyValue(sPropName, *pParentSet);
+                else if(pMap->nWID != aSet.GetPool()->GetSlotId(pMap->nWID))
+                {
+                    const SfxPoolItem& rItem = aSet.GetPool()->GetDefaultItem(pMap->nWID);
+                    rItem.QueryValue(aRet, pMap->nMemberId);
+                }
+            }
+        }
+        else
+            throw RuntimeException();
+    }
+    else
+        throw RuntimeException();
+    return aRet;
+}
+/* -----------------21.01.99 13:08-------------------
+ *
+ * --------------------------------------------------*/
+void SwXStyle::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+    SfxSimpleHint *pHint = PTR_CAST( SfxSimpleHint, &rHint );
+    if( pHint )
+    {
+        if(( pHint->GetId() & SFX_HINT_DYING ) || ( pHint->GetId() & SFX_STYLESHEET_ERASED))
+        {
+            pBasePool = 0;
+            EndListening(rBC);
+        }
+        else if( pHint->GetId() &(SFX_STYLESHEET_CHANGED|SFX_STYLESHEET_ERASED) )
+        {
+            ((SfxStyleSheetPool&)rBC).SetSearchMask(eFamily);
+            SfxStyleSheetBase* pOwnBase = ((SfxStyleSheetPool&)rBC).Find(sStyleName);
+            if(!pOwnBase)
+            {
+                EndListening(rBC);
+                Invalidate();
+            }
+        }
+    }
+}
+/* -----------------------------15.08.00 11:35--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SwXStyle::Invalidate()
+{
+    sStyleName.Erase();
+    pBasePool = 0;
+    m_pDoc = 0;
+}
+/******************************************************************
+ * SwXPageStyle
+ ******************************************************************/
+/*-- 17.12.98 08:43:35---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXPageStyle::SwXPageStyle(SfxStyleSheetBasePool& rPool,
+        SwDocShell* pDocSh, SfxStyleFamily eFam,
+        const String& rStyleName)://, const SfxItemPropertyMap* _pMap) :
+    SwXStyle(rPool, eFam, pDocSh->GetDoc(), rStyleName),//, _pMap),
+    pDocShell(pDocSh)
+{
+
+}
+/* -----------------23.08.99 15:52-------------------
+
+ --------------------------------------------------*/
+SwXPageStyle::SwXPageStyle(SwDocShell* pDocSh) :
+    SwXStyle(SFX_STYLE_FAMILY_PAGE),
+    pDocShell(pDocSh)
+{
+}
+
+/*-- 17.12.98 08:43:35---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXPageStyle::~SwXPageStyle()
+{
+
+}
+/*-- 17.12.98 08:43:36---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+Any SwXPageStyle::getPropertyValue(const OUString& rPropertyName) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    Any aRet;
+    const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                    aSwMapProvider.GetPropertyMap(PROPERTY_MAP_PAGE_STYLE),
+                    rPropertyName);
+    if(GetBasePool())
+    {
+        sal_uInt16 nRes;
+        sal_Bool bHeader = sal_False, bAll = sal_False, bLeft = sal_False, bRight = sal_False;
+        switch(pMap->nWID)
+        {
+            case FN_UNO_HEADER_ON:
+            case FN_UNO_HEADER_BACKGROUND:
+            case FN_UNO_HEADER_BOX:
+            case FN_UNO_HEADER_LR_SPACE:
+            case FN_UNO_HEADER_SHADOW:
+            case FN_UNO_HEADER_BODY_DISTANCE:
+            case FN_UNO_HEADER_IS_DYNAMIC_DISTANCE:
+            case FN_UNO_HEADER_SHARE_CONTENT:
+            case FN_UNO_HEADER_HEIGHT:
+
+            case FN_UNO_FOOTER_ON:
+            case FN_UNO_FOOTER_BACKGROUND:
+            case FN_UNO_FOOTER_BOX:
+            case FN_UNO_FOOTER_LR_SPACE:
+            case FN_UNO_FOOTER_SHADOW:
+            case FN_UNO_FOOTER_BODY_DISTANCE:
+            case FN_UNO_FOOTER_IS_DYNAMIC_DISTANCE:
+            case FN_UNO_FOOTER_SHARE_CONTENT:
+            case FN_UNO_FOOTER_HEIGHT:
+            {
+                SfxStyleSheetBasePool* pBasePool = ((SwXPageStyle*)this)->GetBasePool();
+                pBasePool->SetSearchMask(GetFamily());
+                SfxStyleSheetBase* pBase = pBasePool->Find(GetStyleName());
+                if(pBase)
+                {
+                    SwDocStyleSheet aStyle( *(SwDocStyleSheet*)pBase );
+                    const SfxItemSet& rSet = aStyle.GetItemSet();
+                    sal_Bool bFooter = sal_False;
+                    sal_uInt16 nRes = 0;
+                    switch(pMap->nWID)
+                    {
+                        case FN_UNO_FOOTER_ON:
+                            bFooter = sal_True;
+                        // kein break!
+                        case FN_UNO_HEADER_ON:
+                        {
+                            //falls das SetItem nicht da ist, dann ist der Wert sal_False
+                            BOOL bRet = sal_False;
+                            aRet.setValue(&bRet, ::getCppuBooleanType());
+                            nRes = SID_ATTR_PAGE_ON;
+                        }
+                        break;
+                        case FN_UNO_FOOTER_BACKGROUND:      bFooter = sal_True;
+                        // kein break;
+                        case FN_UNO_HEADER_BACKGROUND:      nRes = RES_BACKGROUND;
+                        break;
+                        case FN_UNO_FOOTER_BOX:             bFooter = sal_True;
+                        // kein break;
+                        case FN_UNO_HEADER_BOX:             nRes = RES_BOX;
+                        break;
+                        case FN_UNO_FOOTER_LR_SPACE:        bFooter = sal_True;
+                        // kein break;
+                        case FN_UNO_HEADER_LR_SPACE:        nRes = RES_LR_SPACE;
+                        break;
+                        case FN_UNO_FOOTER_SHADOW:          bFooter = sal_True;
+                        // kein break;
+                        case FN_UNO_HEADER_SHADOW:          nRes = RES_SHADOW;
+                        break;
+                        case FN_UNO_FOOTER_BODY_DISTANCE:   bFooter = sal_True;
+                        // kein break;
+                        case FN_UNO_HEADER_BODY_DISTANCE:   nRes = RES_UL_SPACE;
+                        break;
+                        case FN_UNO_FOOTER_IS_DYNAMIC_DISTANCE: bFooter = sal_True;
+                        // kein break;
+                        case FN_UNO_HEADER_IS_DYNAMIC_DISTANCE: nRes = SID_ATTR_PAGE_DYNAMIC;
+                        break;
+                        case FN_UNO_FOOTER_SHARE_CONTENT:   bFooter = sal_True;
+                        // kein break;
+                        case FN_UNO_HEADER_SHARE_CONTENT:   nRes = SID_ATTR_PAGE_SHARED;
+                        break;
+                        case FN_UNO_FOOTER_HEIGHT:          bFooter = sal_True;
+                        // kein break;
+                        case FN_UNO_HEADER_HEIGHT:          nRes = SID_ATTR_PAGE_SIZE;
+                        break;
+                    }
+                    const SvxSetItem* pSetItem;
+                    if(SFX_ITEM_SET == rSet.GetItemState(
+                            bFooter ? SID_ATTR_PAGE_FOOTERSET : SID_ATTR_PAGE_HEADERSET,
+                            sal_False, (const SfxPoolItem**)&pSetItem))
+                    {
+                        const SfxItemSet& rSet = pSetItem->GetItemSet();
+                        const SfxPoolItem* pItem = 0;
+                        SfxItemState eState = rSet.GetItemState(nRes, sal_True, &pItem);
+                        if(!pItem && nRes != rSet.GetPool()->GetSlotId(nRes))
+                            pItem = &rSet.GetPool()->GetDefaultItem(nRes);
+                        if(pItem)
+                            pItem->QueryValue(aRet, pMap->nMemberId);
+                    }
+                }
+            }
+            break;
+            case  FN_UNO_HEADER       :
+                bAll = sal_True; goto Header;
+            case  FN_UNO_HEADER_LEFT  :
+                bLeft = sal_True; goto Header;
+            case  FN_UNO_HEADER_RIGHT :
+                bRight = sal_True; goto Header;
+Header:
+                bHeader = sal_True;
+                nRes = RES_HEADER; goto MakeObject;
+            case  FN_UNO_FOOTER       :
+                bAll = sal_True; goto Footer;
+            case  FN_UNO_FOOTER_LEFT  :
+                bLeft = sal_True; goto Footer;
+            case  FN_UNO_FOOTER_RIGHT :
+                bRight = sal_True;
+Footer:
+                nRes = RES_FOOTER;
+MakeObject:
+            {
+                SwDoc* pDoc = pDocShell->GetDoc();
+                sal_uInt16 nPDescCount = pDoc->GetPageDescCnt();
+                for(sal_uInt16 i = 0; i < nPDescCount; i++)
+                {
+                    const SwPageDesc& rDesc = pDoc->GetPageDesc( i );
+                    if(rDesc.GetName() == GetStyleName())
+                    {
+                        const SwFrmFmt* pFrmFmt = 0;
+                        sal_Bool bShare = bHeader && rDesc.IsHeaderShared()||
+                                        !bHeader && rDesc.IsFooterShared();
+                        UseOnPage eUse = rDesc.GetUseOn();
+                        if((bShare && (PD_ALL == eUse || PD_MIRROR == eUse))  //Share wirkt nur fuer Mirror oder All
+                            || (PD_ALL == eUse || PD_MIRROR == eUse) && (bAll || bRight) || //
+                                    bRight && PD_RIGHT == eUse && PD_LEFT != eUse)
+                            pFrmFmt = &rDesc.GetMaster();
+                        else if(bLeft && PD_RIGHT != eUse)
+                            pFrmFmt = &rDesc.GetLeft();
+                        if(pFrmFmt)
+                        {
+                            const SfxItemSet& rSet = pFrmFmt->GetAttrSet();
+                            const SfxPoolItem* pItem;
+                            SwFrmFmt* pHeadFootFmt;
+                            if(SFX_ITEM_SET == rSet.GetItemState(nRes, sal_True, &pItem) &&
+                             0 != (pHeadFootFmt = bHeader ?
+                                        ((SwFmtHeader*)pItem)->GetHeaderFmt() :
+                                            ((SwFmtFooter*)pItem)->GetFooterFmt()))
+                            {
+                                // gibt es schon ein Objekt dafuer?
+                                SwXHeadFootText* pxHdFt = (SwXHeadFootText*)SwClientIter( *pHeadFootFmt ).
+                                                First( TYPE( SwXHeadFootText ));
+                                Reference< text::XText >  xRet = pxHdFt;
+                                if(!pxHdFt)
+                                    xRet = new SwXHeadFootText(*pHeadFootFmt, bHeader);
+                                aRet.setValue(&xRet, ::getCppuType((Reference*)0));
+                            }
+                        }
+                        break;
+                    }
+                }
+
+            }
+            break;
+            default:
+                aRet = SwXStyle::getPropertyValue(rPropertyName);
+        }
+    }
+    return aRet;
+}
+/*-- 17.12.98 08:43:36---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXPageStyle::setPropertyValue(const OUString& rPropertyName, const Any& aValue)
+    throw( beans::UnknownPropertyException,
+        beans::PropertyVetoException,
+        lang::IllegalArgumentException,
+         lang::WrappedTargetException,
+        RuntimeException)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                        aSwMapProvider.GetPropertyMap(PROPERTY_MAP_PAGE_STYLE),
+                        rPropertyName);
+    if(GetBasePool())
+    {
+        switch(pMap->nWID)
+        {
+            case FN_UNO_HEADER_ON:
+            case FN_UNO_HEADER_BACKGROUND:
+            case FN_UNO_HEADER_BOX:
+            case FN_UNO_HEADER_LR_SPACE:
+            case FN_UNO_HEADER_SHADOW:
+            case FN_UNO_HEADER_BODY_DISTANCE:
+            case FN_UNO_HEADER_IS_DYNAMIC_DISTANCE:
+            case FN_UNO_HEADER_SHARE_CONTENT:
+            case FN_UNO_HEADER_HEIGHT:
+            case FN_UNO_FOOTER_ON:
+            case FN_UNO_FOOTER_BACKGROUND:
+            case FN_UNO_FOOTER_BOX:
+            case FN_UNO_FOOTER_LR_SPACE:
+            case FN_UNO_FOOTER_SHADOW:
+            case FN_UNO_FOOTER_BODY_DISTANCE:
+            case FN_UNO_FOOTER_IS_DYNAMIC_DISTANCE:
+            case FN_UNO_FOOTER_SHARE_CONTENT:
+            case FN_UNO_FOOTER_HEIGHT:
+            {
+                SfxStyleSheetBasePool* pBasePool = ((SwXPageStyle*)this)->GetBasePool();
+                pBasePool->SetSearchMask(GetFamily());
+                SfxStyleSheetBase* pBase = pBasePool->Find(GetStyleName());
+                if(pBase)
+                {
+                    SwDocStyleSheet aStyle( *(SwDocStyleSheet*)pBase );
+                    SfxItemSet aSet(aStyle.GetItemSet());
+                    sal_Bool bSetItem = sal_False;
+                    sal_Bool bFooter = sal_False;
+                    sal_uInt16 nItemType = TYPE_BOOL;
+                    sal_uInt16 nRes = 0;
+                    switch(pMap->nWID)
+                    {
+                        case FN_UNO_FOOTER_ON:                  bFooter = sal_True;
+                        //kein break;
+                        case FN_UNO_HEADER_ON:                  nRes = SID_ATTR_PAGE_ON;
+                        break;
+                        case FN_UNO_FOOTER_BACKGROUND:          bFooter = sal_True;
+                        // kein break;
+                        case FN_UNO_HEADER_BACKGROUND:          nRes = RES_BACKGROUND; nItemType = TYPE_BRUSH;
+                        break;
+                        case FN_UNO_FOOTER_BOX:                 bFooter = sal_True;
+                        // kein break;
+                        case FN_UNO_HEADER_BOX:                 nRes = RES_BOX; nItemType = TYPE_BOX;
+                        break;
+                        case FN_UNO_FOOTER_LR_SPACE:            bFooter = sal_True;
+                        // kein break;
+                        case FN_UNO_HEADER_LR_SPACE:            nRes = RES_LR_SPACE;nItemType = TYPE_LRSPACE;
+                        break;
+                        case FN_UNO_FOOTER_SHADOW:              bFooter = sal_True;
+                        // kein break;
+                        case FN_UNO_HEADER_SHADOW:              nRes = RES_SHADOW;nItemType = TYPE_SHADOW;
+                        break;
+                        case FN_UNO_FOOTER_BODY_DISTANCE:       bFooter = sal_True;
+                        // kein break;
+                        case FN_UNO_HEADER_BODY_DISTANCE:       nRes = RES_UL_SPACE;nItemType = TYPE_ULSPACE;
+                        break;
+                        case FN_UNO_FOOTER_IS_DYNAMIC_DISTANCE: bFooter = sal_True;
+                        // kein break;
+                        case FN_UNO_HEADER_IS_DYNAMIC_DISTANCE: nRes = SID_ATTR_PAGE_DYNAMIC;
+                        break;
+                        case FN_UNO_FOOTER_SHARE_CONTENT:       bFooter = sal_True;
+                        // kein break;
+                        case FN_UNO_HEADER_SHARE_CONTENT:       nRes = SID_ATTR_PAGE_SHARED;
+                        break;
+                        case FN_UNO_FOOTER_HEIGHT:              bFooter = sal_True;
+                        // kein break;
+                        case FN_UNO_HEADER_HEIGHT:              nRes = SID_ATTR_PAGE_SIZE;nItemType = TYPE_SIZE;
+                        break;
+
+                    }
+                    const SvxSetItem* pSetItem;
+                    if(SFX_ITEM_SET == aSet.GetItemState(
+                            bFooter ? SID_ATTR_PAGE_FOOTERSET : SID_ATTR_PAGE_HEADERSET,
+                            sal_False, (const SfxPoolItem**)&pSetItem))
+                    {
+                        SvxSetItem* pNewSetItem = (SvxSetItem*)pSetItem->Clone();
+                        SfxItemSet& rSetSet = pNewSetItem->GetItemSet();
+                        const SfxPoolItem* pItem = 0;
+                        SfxPoolItem* pNewItem = 0;
+                        SfxItemState eState = rSetSet.GetItemState(nRes, sal_True, &pItem);
+                        if(!pItem && nRes != rSetSet.GetPool()->GetSlotId(nRes))
+                            pItem = &rSetSet.GetPool()->GetDefaultItem(nRes);
+                        if(pItem)
+                        {
+                            pNewItem = pItem->Clone();
+                        }
+                        else
+                        {
+                            switch(nItemType)
+                            {
+                                case TYPE_BOOL: pNewItem = new SfxBoolItem(nRes);       break;
+                                case TYPE_SIZE: pNewItem = new SvxSizeItem(nRes);       break;
+                                case TYPE_BRUSH: pNewItem = new SvxBrushItem(nRes);     break;
+                                case TYPE_ULSPACE: pNewItem = new SvxULSpaceItem(nRes); break;
+                                case TYPE_SHADOW : pNewItem = new SvxShadowItem(nRes);  break;
+                                case TYPE_LRSPACE: pNewItem = new SvxLRSpaceItem(nRes); break;
+                                case TYPE_BOX: pNewItem = new SvxBoxItem(nRes);         break;
+                            }
+                        }
+                        bSetItem = pNewItem->PutValue(aValue, pMap->nMemberId);
+                        rSetSet.Put(*pNewItem);
+                        aSet.Put(*pNewSetItem);
+                        aStyle.SetItemSet(aSet);
+                        delete pNewItem;
+                        delete pNewSetItem;
+                    }
+                    else if(SID_ATTR_PAGE_ON == nRes )
+                    {
+                        sal_Bool bVal = *(sal_Bool*)aValue.getValue();
+                        if(bVal)
+                        {
+                            SfxItemSet aTempSet(*aSet.GetPool(),
+                                RES_BACKGROUND, RES_SHADOW,
+                                RES_LR_SPACE, RES_UL_SPACE,
+                                nRes, nRes,
+                                SID_ATTR_PAGE_SIZE, SID_ATTR_PAGE_SIZE,
+                                SID_ATTR_PAGE_DYNAMIC, SID_ATTR_PAGE_DYNAMIC,
+                                SID_ATTR_PAGE_SHARED, SID_ATTR_PAGE_SHARED,
+                                0 );
+                            aTempSet.Put(SfxBoolItem(nRes, sal_True));
+                            aTempSet.Put(SvxSizeItem(SID_ATTR_PAGE_SIZE, Size(MM50, MM50)));
+                            aTempSet.Put(SvxLRSpaceItem(RES_LR_SPACE));
+                            aTempSet.Put(SvxULSpaceItem(RES_UL_SPACE));
+                            aTempSet.Put(SfxBoolItem(SID_ATTR_PAGE_SHARED, sal_True));
+                            aTempSet.Put(SfxBoolItem(SID_ATTR_PAGE_DYNAMIC, sal_True));
+
+                            SvxSetItem aNewSetItem( bFooter ? SID_ATTR_PAGE_FOOTERSET : SID_ATTR_PAGE_HEADERSET,
+                                    aTempSet);
+                            aSet.Put(aNewSetItem);
+                            aStyle.SetItemSet(aSet);
+                        }
+                    }
+                }
+            }
+            break;
+            case  FN_UNO_HEADER       :
+            case  FN_UNO_HEADER_LEFT  :
+            case  FN_UNO_HEADER_RIGHT :
+            case  FN_UNO_FOOTER       :
+            case  FN_UNO_FOOTER_LEFT  :
+            case  FN_UNO_FOOTER_RIGHT :
+                throw lang::IllegalArgumentException();
+            break;
+            default:
+                SwXStyle::setPropertyValue(rPropertyName, aValue);
+        }
+    }
+}
+/* -----------------12.01.99 15:31-------------------
+ * Liefert den StartNode des Headers oder Footers der
+ * linken oder rechten Seite zurueck
+ * Kann auch Null liefern, wenn es keinen gibt
+ * --------------------------------------------------*/
+const SwStartNode* SwXPageStyle::GetStartNode(sal_Bool bHeader, sal_Bool bLeft)
+{
+    const SwStartNode* pRet = 0;
+    if(GetBasePool())
+    {
+        sal_uInt16 nRes = bHeader ? RES_HEADER : RES_FOOTER;
+        SwDoc* pDoc = pDocShell->GetDoc();
+        sal_uInt16 nPDescCount = pDoc->GetPageDescCnt();
+        for(sal_uInt16 i = 0; i < nPDescCount; i++)
+        {
+            const SwPageDesc& rDesc = pDoc->GetPageDesc( i );
+            if(rDesc.GetName() == GetStyleName())
+            {
+                const SwFrmFmt* pFrmFmt = 0;
+                sal_Bool bShare = bHeader && rDesc.IsHeaderShared()||
+                                        !bHeader && rDesc.IsFooterShared();
+                UseOnPage eUse = rDesc.GetUseOn();
+                if(bShare || !bLeft && PD_RIGHT == eUse && PD_LEFT != eUse)
+                    pFrmFmt = &rDesc.GetMaster();
+                else if(bLeft && PD_RIGHT != eUse)
+                        pFrmFmt = &rDesc.GetLeft();
+                if(pFrmFmt)
+                {
+                    const SfxItemSet& rSet = pFrmFmt->GetAttrSet();
+                    const SfxPoolItem* pItem;
+                    SwFrmFmt* pHeadFootFmt;
+                    if(SFX_ITEM_SET == rSet.GetItemState(nRes, sal_True, &pItem) &&
+                     0 != (pHeadFootFmt = bHeader ?
+                            ((SwFmtHeader*)pItem)->GetHeaderFmt() :
+                                ((SwFmtFooter*)pItem)->GetFooterFmt()))
+                    {
+                        const SwFmtCntnt& rFlyCntnt = pHeadFootFmt->GetCntnt();
+                        const SwNode& rNode = rFlyCntnt.GetCntntIdx()->GetNode();
+                        pRet = rNode.FindStartNode();
+                    }
+                }
+                break;
+            }
+        }
+    }
+    return pRet;
+}
+
+/*------------------------------------------------------------------------
+    $Log: not supported by cvs2svn $
+    Revision 1.96  2000/09/18 16:04:35  willem.vandorp
+    OpenOffice header added.
+
+    Revision 1.95  2000/09/01 14:23:40  os
+    #78380# Header and footer separated
+
+    Revision 1.94  2000/08/31 13:42:36  os
+    DropCap: WhichId corrected
+
+    Revision 1.93  2000/08/31 10:04:03  os
+    Detect conditional style by PoolId
+
+    Revision 1.92  2000/08/25 08:49:07  os
+    +property DropCapCharStyleName
+
+    Revision 1.91  2000/08/23 10:49:07  os
+    new service: ...style.ConditionalParagraphStyle
+
+    Revision 1.90  2000/08/15 10:06:51  os
+    #76785# invalidate style after removing via replaceByName
+
+    Revision 1.89  2000/08/10 10:55:15  os
+    solaris compiler bug
+
+    Revision 1.88  2000/08/02 14:53:57  mib
+    Standard char style now isn't present physically
+
+    Revision 1.87  2000/07/21 13:13:12  os
+    #76644# Category property at paragraph styles
+
+    Revision 1.86  2000/07/10 10:37:38  os
+    #76667# isUserDefined: search mask corrected
+
+    Revision 1.85  2000/07/10 07:47:41  os
+    #76697# create object of SwDocStyleSheet
+
+    Revision 1.84  2000/07/06 08:01:51  os
+    ::setParent: no exception if the parent is already set
+
+    Revision 1.83  2000/06/29 13:06:33  os
+    service ParagraphStyle
+
+    Revision 1.82  2000/06/28 14:05:06  os
+    ::getPropertyValue: search always for all styles
+
+    Revision 1.81  2000/06/28 12:29:32  os
+    #76403# SwXStyleFamilies::getByIndex: exception condition corrected
+
+    Revision 1.80  2000/06/28 09:24:00  os
+    IsPhysical: prevent style from creating
+
+    Revision 1.79  2000/06/27 13:37:22  os
+    new Properties: IsAutoUpdate + DisplayName
+
+    Revision 1.78  2000/06/27 12:10:33  os
+    #76423# programmatic style names
+
+    Revision 1.77  2000/06/26 12:56:42  os
+    new Property: IsPhysical
+
+    Revision 1.76  2000/05/25 09:55:12  hr
+    exception specification
+
+    Revision 1.75  2000/05/16 17:21:36  jp
+    Changes for Unicode
+
+    Revision 1.74  2000/05/16 09:14:55  os
+    project usr removed
+
+    Revision 1.73  2000/04/26 11:35:20  os
+    GetName() returns String&
+
+    Revision 1.72  2000/04/25 13:23:11  os
+    SwXPageStyle::setPropertyValue: throw exception for readonly properties
+
+    Revision 1.71  2000/04/19 13:35:31  os
+    UNICODE
+
+    Revision 1.70  2000/04/11 08:31:04  os
+    UNICODE
+
+    Revision 1.69  2000/03/27 10:21:10  os
+    UNO III
+
+    Revision 1.68  2000/03/21 15:42:25  os
+    UNOIII
+
+    Revision 1.67  2000/03/07 18:38:25  os
+    #73638# ::loadStyles.. : create Reader with PaM instead of Doc
+
+    Revision 1.66  2000/03/07 18:03:30  os
+    #73638# ::loadStyles.. : only file names are valid
+
+    Revision 1.65  2000/02/11 14:36:04  hr
+    #70473# changes for unicode ( patched by automated patchtool )
+
+    Revision 1.64  2000/02/04 08:56:48  jp
+    #72424# Chg: PropertyValue
+
+    Revision 1.63  2000/02/02 16:58:07  jp
+    Task #72579#: interface of SwReader is changed
+
+    Revision 1.62  2000/01/28 15:20:25  os
+    #69861# Chg: beans::Xbeans::PropertyState; #72424# Chg: PropertyValue
+
+    Revision 1.61  1999/11/25 15:31:53  os
+    #70144# ::setName - create a copy style sheet
+
+    Revision 1.60  1999/11/22 10:37:57  os
+    missing headers added
+
+    Revision 1.59  1999/11/19 16:40:19  os
+    modules renamed
+
+    Revision 1.58  1999/10/28 09:19:23  os
+    #69199# set/getName corrected
+
+    Revision 1.57  1999/08/23 14:17:54  OS
+    #68353# create SwXPageStyle in ServiceProvider too
+
+
+      Rev 1.56   23 Aug 1999 16:17:54   OS
+   #68353# create SwXPageStyle in ServiceProvider too
+
+      Rev 1.55   20 Jul 1999 14:55:08   OS
+   #67495# PageDescName property in paragraph styles
+
+      Rev 1.54   09 Jul 1999 09:22:52   OS
+   #67525#
+
+      Rev 1.53   07 Jul 1999 17:50:22   OS
+   #67343# re-enable setPropertyValue
+
+      Rev 1.52   18 Jun 1999 08:56:40   OS
+   #67037# SetItemSet: dont apply on full range
+
+      Rev 1.51   20 May 1999 08:51:40   OS
+   #65130# replaceByName impl.
+
+      Rev 1.50   12 May 1999 15:39:32   OS
+   #66150# nArrLen initialisiert!
+
+      Rev 1.49   07 May 1999 14:08:48   KZ
+   #include  eingefuegt
+
+      Rev 1.48   23 Apr 1999 15:29:28   OS
+   #65134# Properties schon am Style als Descriptor
+
+      Rev 1.47   23 Apr 1999 08:26:38   OS
+   #65194# Semikolon muss weg
+
+      Rev 1.46   22 Apr 1999 16:13:56   OS
+   #65194# throw -> throw; #65124# not impl. nur noch warning; EventListener
+
+      Rev 1.45   30 Mar 1999 12:47:54   OS
+   #64019# HeaderTextLeft/Right - neuer Versuch
+
+      Rev 1.44   15 Mar 1999 14:37:52   OS
+   #62845# Makro fuer ServiceInfo jetzt auch fuer OS/2
+
+      Rev 1.43   12 Mar 1999 09:41:28   OS
+   #62845# lang::XServiceInfo impl.
+
+      Rev 1.42   09 Mar 1999 12:41:28   OS
+    vos::OGuard aGuard(Application::GetSolarMutex());
+
+      Rev 1.41   08 Mar 1999 13:49:36   OS
+   #62461##62543 beans::Xbeans::PropertyState
+
+      Rev 1.40   26 Feb 1999 09:38:02   OS
+   #62454# SetItemSet immer rufen
+
+      Rev 1.39   23 Feb 1999 10:22:06   OS
+   #61767# Kapitelnumerierung funktioniert wieder
+
+      Rev 1.38   22 Feb 1999 13:23:42   OS
+   #60606# Numerierungsregel incl. Font richtig setzen
+
+      Rev 1.37   19 Feb 1999 16:34:48   OS
+   #62083# StyleName beim insert setzen
+
+      Rev 1.36   19 Feb 1999 09:35:10   OS
+   #62083# Styles per ServiceProvider anlegen
+
+      Rev 1.35   04 Feb 1999 16:23:40   OS
+   #56371# richtigen rechten Header/FooterText finden
+
+      Rev 1.34   03 Feb 1999 11:48:12   OS
+   #56371# ItemSet des StyleSheets kopieren
+
+      Rev 1.33   02 Feb 1999 12:52:22   OS
+   #56371# richtige IdlClasses
+
+      Rev 1.32   22 Jan 1999 15:09:24   OS
+   #56371# Draw wieder verfuegbar
+
+      Rev 1.31   21 Jan 1999 13:45:32   OS
+   #56371##52654# NumberingRule und FollowStyle
+
+      Rev 1.30   21 Jan 1999 09:57:06   OS
+   #60971# Zeichenvorlagen der Numerierung an Absatzvorlagen setzen
+
+      Rev 1.29   14 Jan 1999 16:21:46   OS
+   #56371# TF_ONE51
+
+      Rev 1.28   13 Jan 1999 10:49:04   OS
+   #52654# Start/Endnote fuer Kopf-/Fusszeile zurueckgeben
+
+      Rev 1.27   05 Jan 1999 10:10:54   OS
+   #60606# #52654# Numerierungsregel an Styles wieder korrekt
+
+      Rev 1.26   21 Dec 1998 16:22:30   OS
+   #56371# TF_ONE51 Zwischenstand
+
+      Rev 1.25   17 Dec 1998 09:21:02   OS
+   #56371# TF_ONE51 Zwischenstand
+
+      Rev 1.24   10 Dec 1998 15:53:38   OS
+   #56371# TF_ONE51 Zwischenstand
+
+      Rev 1.23   30 Oct 1998 16:32:06   OS
+   #52654# fehlende Initialisierung
+
+      Rev 1.22   23 Sep 1998 07:43:08   OS
+   #52654# syntax
+
+      Rev 1.21   18 Sep 1998 09:31:06   OS
+   52654# style::XStyleLoader
+
+      Rev 1.20   31 Aug 1998 14:56:32   OS
+   #52654# addStyle: richtige Parameter fuer 504
+
+      Rev 1.19   31 Aug 1998 14:40:00   OS
+   #52654# addStyle: nur noch mit dem Namen des parents aufrufen
+
+      Rev 1.18   27 Aug 1998 09:36:40   OS
+   #52654# Kopf- und Fusszeilen impl.
+
+      Rev 1.17   12 Aug 1998 19:43:48   HR
+   #54781#: ::::getCppuType((const Reference< XInterface >*)0)() -> ( XInterface*)0)->getSmartUik()
+
+      Rev 1.16   21 Jul 1998 17:00:32   OS
+   SwXStyle::getPropertySetInfo - abhaengigg von eFamily unterschiedliche Infos liefern #52654#
+
+      Rev 1.15   10 Jul 1998 18:08:28   OS
+   PropertySetInfo und IdlClass static
+
+      Rev 1.14   10 Jul 1998 14:43:58   HR
+   .is()
+
+      Rev 1.13   09 Jul 1998 09:13:56   OS
+   getElementBy* - queryInterface auf XInterface
+
+
+      Rev 1.12   25 Jun 1998 11:14:58   OS
+   PreopertyMaps nur noch vom PropertyMapProvider
+
+      Rev 1.11   23 Jun 1998 10:25:26   OS
+   CONVERT_TWIPS
+
+      Rev 1.10   19 Jun 1998 08:47:26   OS
+   Twip-Konvertierung
+
+      Rev 1.9   18 Jun 1998 18:09:58   OS
+// automatisch auskommentiert - [getIdlClass(es) or queryInterface] - Bitte XTypeProvider benutzen!
+//   queryInterface fuer style::StyleFamily/ies berichtigt
+
+
+      Rev 1.8   18 Jun 1998 08:11:10   OS
+   Property-Namen veraendert
+
+      Rev 1.7   16 Jun 1998 17:25:18   OS
+   Bold/Italic/Underlined ersetzt durch Weight, Posture, Underline
+
+      Rev 1.6   15 Jun 1998 12:46:12   OS
+   SwXContainer:: vergessen
+
+      Rev 1.5   10 Jun 1998 09:54:46   OS
+   Package-Umstellung
+
+      Rev 1.4   04 Jun 1998 09:40:04   OS
+// automatisch auskommentiert - [getIdlClass(es) or queryInterface] - Bitte XTypeProvider benutzen!
+//   getIdlClasses
+
+
+      Rev 1.3   29 May 1998 13:48:34   OS
+   Properties erweitern
+
+      Rev 1.2   27 May 1998 13:45:10   OS
+   grundsaetzlich vollstaendig
+
+      Rev 1.1   26 May 1998 16:59:08   OS
+   teilweise funktionstuechtig
+
+      Rev 1.0   26 May 1998 12:29:40   OS
+   Initial revision.
+
+------------------------------------------------------------------------*/
+
diff --git a/sw/source/core/unocore/unotbl.cxx b/sw/source/core/unocore/unotbl.cxx
new file mode 100644
index 000000000000..2d5836a2a82f
--- /dev/null
+++ b/sw/source/core/unocore/unotbl.cxx
@@ -0,0 +1,4783 @@
+/*************************************************************************
+ *
+ *  $RCSfile: unotbl.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:29 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#define ITEMID_BOXINFO SID_ATTR_BORDER_INNER
+#include 
+#include 
+#ifndef _UNOTBL_HXX
+#include 
+#endif
+#ifndef _UNOSTYLE_HXX
+#include 
+#endif
+
+#ifndef _UNOCRSR_HXX //autogen
+#include 
+#endif
+#ifndef SW_UNOMID_HXX
+#include 
+#endif
+#ifndef _SVX_UNOMID_HXX
+#include 
+#endif
+#ifndef _HINTS_HXX
+#include 
+#endif
+#ifndef _SWTBLFMT_HXX //autogen
+#include 
+#endif
+#ifndef _DOC_HXX //autogen
+#include 
+#endif
+#ifndef _SHELLRES_HXX
+#include 
+#endif
+#ifndef _DOCARY_HXX
+#include 
+#endif
+#ifndef _NDOLE_HXX //autogen
+#include 
+#endif
+#ifndef _IPOBJ_HXX //autogen
+#include 
+#endif
+
+#ifndef _FRAME_HXX //autogen
+#include 
+#endif
+#ifndef _SV_SVAPP_HXX //autogen
+#include 
+#endif
+#include 
+#ifndef _TBLAFMT_HXX //autogen
+#include 
+#endif
+#ifndef _TABCOL_HXX //autogen
+#include 
+#endif
+#ifndef _CELLATR_HXX
+#include 
+#endif
+#ifndef _FMTPDSC_HXX //autogen
+#include 
+#endif
+#ifndef _PAGEDESC_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_BOXITEM_HXX //autogen
+#include 
+#endif
+#define _SVSTDARR_STRINGS
+#include 
+#ifndef _VIEWSH_HXX //autogen
+#include 
+#endif
+#ifndef _TABFRM_HXX //autogen
+#include 
+#endif
+#ifndef _UNOMAP_HXX
+#include 
+#endif
+#ifndef _SCH_DLL_HXX
+#include 
+#endif
+#ifndef _SCH_MEMCHRT_HXX
+#include 
+#endif
+#ifndef _UNOPRNMS_HXX
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_WRAPTEXTMODE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_TEXTCONTENTANCHORTYPE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_TABLECOLUMNSEPARATOR_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TABLE_SHADOWFORMAT_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TABLE_TABLEBORDER_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_STYLE_PAGESTYLELAYOUT_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_STYLE_BREAKTYPE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_STYLE_GRAPHICLOCATION_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TABLE_BORDERLINE_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_BEANS_PropertyAttribute_HPP_
+#include 
+#endif
+#ifndef _UNOTBL_HXX
+#include 
+#endif
+#ifndef _UNOOBJ_HXX
+#include 
+#endif
+#ifndef _SVX_BRKITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_SHADITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_ULSPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _FMTORNT_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_KEEPITEM_HXX //autogen
+#include 
+#endif
+#ifndef _FMTTSPLT_HXX
+#include 
+#endif
+#ifndef _SWUNDO_HXX
+#include 
+#endif
+#ifndef _VOS_MUTEX_HXX_ //autogen
+#include 
+#endif
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::beans;
+using namespace ::rtl;
+//collectn.cxx
+BOOL lcl_IsNumeric(const String&);
+
+//-----------------------------------------------------------------------------
+//aus unoobj.cxx
+extern void lcl_SetTxtFmtColl(const uno::Any& rAny, SwPaM& rPaM)    throw (IllegalArgumentException);
+#define UNO_TABLE_COLUMN_SUM    10000
+
+#define EXCEPT_ON_PROTECTION(rUnoCrsr)  \
+    if((rUnoCrsr).HasReadonlySel()) \
+        throw uno::RuntimeException();
+
+#define EXCEPT_ON_TBL_PROTECTION(rUnoTblCrsr)   \
+    if((rUnoTblCrsr).HasReadOnlyBoxSel()) \
+        throw uno::RuntimeException();
+
+/* -----------------17.07.98 15:47-------------------
+ *
+ * --------------------------------------------------*/
+table::BorderLine lcl_SvxLineToLine(const SvxBorderLine* pLine)
+{
+     table::BorderLine aLine;
+    if(pLine)
+    {
+        aLine.Color          = pLine->GetColor().GetColor() ;
+        aLine.InnerLineWidth = pLine->GetInWidth()  ;
+        aLine.OuterLineWidth = pLine->GetOutWidth() ;
+        aLine.LineDistance   = pLine->GetDistance() ;
+    }
+    else
+        aLine.Color          = aLine.InnerLineWidth = aLine.OuterLineWidth = aLine.LineDistance  = 0;
+    return aLine;
+}
+/* -----------------17.07.98 15:52-------------------
+ *
+ * --------------------------------------------------*/
+sal_Bool lcl_LineToSvxLine(const table::BorderLine& rLine, SvxBorderLine& rSvxLine)
+{
+    rSvxLine.SetColor(   Color(rLine.Color));
+    rSvxLine.SetInWidth( rLine.InnerLineWidth  );
+    rSvxLine.SetOutWidth(rLine.OuterLineWidth  );
+    rSvxLine.SetDistance(rLine.LineDistance  );
+    sal_Bool bRet = rLine.InnerLineWidth > 0 || rLine.OuterLineWidth > 0;
+    return bRet;
+}
+/* -----------------11.12.98 14:22-------------------
+ *
+ * --------------------------------------------------*/
+void lcl_SetSpecialProperty(SwFrmFmt* pFmt, const SfxItemPropertyMap* pMap, const uno::Any& aValue)
+    throw (IllegalArgumentException)
+{
+    //Sonderbehandlung fuer "Nicht-Items"
+    switch(pMap->nWID)
+    {
+        case  FN_TABLE_HEADLINE_REPEAT:
+
+        {
+            SwTable* pTable = SwTable::FindTable( pFmt );
+            {
+                UnoActionContext aAction(pFmt->GetDoc());
+                sal_Bool bVal = *(sal_Bool*)aValue.getValue();
+                pFmt->GetDoc()->SetHeadlineRepeat( *pTable, bVal);
+            }
+        }
+        break;
+        case  FN_TABLE_IS_RELATIVE_WIDTH:
+        case  FN_TABLE_WIDTH:
+        case  FN_TABLE_RELATIVE_WIDTH:
+        {
+            sal_Int32 nWidth;
+            SwFmtFrmSize aSz( pFmt->GetFrmSize() );
+            if(FN_TABLE_WIDTH == pMap->nWID)
+            {
+                aValue >>= nWidth;
+                aSz.SetWidthPercent(0);
+            }
+            else if(FN_TABLE_RELATIVE_WIDTH == pMap->nWID)
+            {
+                sal_Int16 nSet;
+                aValue >>= nSet;
+                if(nSet && nSet <=100)
+                    aSz.SetWidthPercent( nSet );
+            }
+            else if(FN_TABLE_IS_RELATIVE_WIDTH == pMap->nWID)
+            {
+                sal_Bool bPercent = *(sal_Bool*)aValue.getValue();
+                if(!bPercent)
+                    aSz.SetWidthPercent(0);
+                else
+                    DBG_ERROR("relative Breite kann nicht per sal_Bool eingeschaltet werden");
+            }
+            pFmt->GetDoc()->SetAttr(aSz, *pFmt);
+
+        }
+        break;
+        case RES_PAGEDESC:
+        {
+            OUString uTemp;
+            aValue >>= uTemp;
+            String sPageStyle = uTemp;
+            const SwPageDesc* pDesc = 0;
+            if(sPageStyle.Len())
+            {
+                sPageStyle = SwXStyleFamilies::GetUIName(sPageStyle, SFX_STYLE_FAMILY_PAGE);
+                const SwPageDesc* pDesc = ::GetPageDescByName_Impl(*pFmt->GetDoc(), sPageStyle);
+                if(pDesc)
+                {
+                    SwFmtPageDesc aDesc( pDesc );
+//                      SwFmtPageDesc aDesc();
+//                      uno::Any* pPgNo = pProps->GetProperty(UNO_NAME_PAGE_NUMBER_OFFSET );
+//                      if(pPgNo)
+//                      {
+//                          aDesc.SetNumOffset( TypeConversion::toINT16(*pPgNo) );
+//                      }
+                    pFmt->GetDoc()->SetAttr(aDesc, *pFmt);
+                    break;
+                }
+            }
+        }
+        break;
+        default:
+            throw IllegalArgumentException();
+    }
+}
+
+/* -----------------27.04.98 08:50-------------------
+ *
+ * --------------------------------------------------*/
+uno::Any lcl_GetSpecialProperty(SwFrmFmt* pFmt, const SfxItemPropertyMap* pMap )
+{
+    uno::Any aRet;
+    switch(pMap->nWID)
+    {
+        case  FN_TABLE_HEADLINE_REPEAT:
+        {
+            SwTable* pTable = SwTable::FindTable( pFmt );
+            BOOL bTemp = pTable->IsHeadlineRepeat();
+            aRet.setValue(&bTemp, ::getCppuBooleanType());
+        }
+        break;
+        case  FN_TABLE_WIDTH:
+        case  FN_TABLE_IS_RELATIVE_WIDTH:
+        case  FN_TABLE_RELATIVE_WIDTH:
+        {
+            sal_uInt16* nPercent = 0;
+            DBG_WARNING("not implemented")
+//          SwTwips nWidth = ::GetTableWidth(pFmt, TabCols?, &nPercent);
+//          if(FN_TABLE_WIDTH = pMap->nWID)
+//              aRet.setINT32(nWidth);
+//          else if(FN_TABLE_RELATIVE_WIDTH)
+//              aRet.setINT16(nPercent);
+//          else
+//              aRet.SetBOOL( 0 != nPercent);
+        }
+        break;
+        case RES_PAGEDESC:
+        {
+            const SfxItemSet& rSet = pFmt->GetAttrSet();
+            const SfxPoolItem* pItem;
+            String sPDesc;
+            if(SFX_ITEM_SET == rSet.GetItemState(RES_PAGEDESC, sal_False, &pItem))
+            {
+                const SwPageDesc* pDsc = ((const SwFmtPageDesc*)pItem)->GetPageDesc();
+                if(pDsc)
+                {
+                   sPDesc = SwXStyleFamilies::GetProgrammaticName(pDsc->GetName(), SFX_STYLE_FAMILY_PAGE);
+                }
+            }
+            aRet <<= OUString(sPDesc);
+        }
+        break;
+        case RES_ANCHOR :
+            aRet <<= TextContentAnchorType_AT_PARAGRAPH;
+        break;
+        case FN_UNO_ANCHOR_TYPES :
+        {
+            uno::Sequence aTypes(1);
+             TextContentAnchorType* pArray = aTypes.getArray();
+            pArray[0] = TextContentAnchorType_AT_PARAGRAPH;
+            aRet <<= aTypes;
+        }
+        break;
+        case FN_UNO_WRAP :
+        {
+            aRet <<= WrapTextMode_NONE;
+        }
+        break;
+        case FN_PARAM_LINK_DISPLAY_NAME :
+            aRet <<= OUString(pFmt->GetName());
+        break;
+    }
+    return aRet;
+}
+/* -----------------25.06.98 08:32-------------------
+ *
+ * --------------------------------------------------*/
+String lcl_GetCellName(sal_Int16 nColumn, sal_Int16 nRow)
+{
+        String sCellName;
+        sal_uInt16 nDiv = nColumn;
+        sal_uInt16 nMod = 0;
+        sal_Bool bFirst = sal_True;
+        while( 0 != (nDiv -= nMod) || bFirst )
+        {
+            nMod = nDiv % 52;
+            sal_uInt16 nMod2 = nDiv % 26;
+            char cCol = nMod < 26 ? 'A' : 'a';
+            cCol += nMod2;
+            sCellName.Insert(cCol, 0);
+            bFirst = sal_False;
+        }
+        sCellName += String::CreateFromInt32(++nRow);
+        return sCellName;
+}
+/* -----------------06.10.99 14:46-------------------
+
+ --------------------------------------------------*/
+void lcl_GetRowCol(const String& rCellName, sal_uInt16& rRow, sal_uInt16& rCol)
+{
+    //make parts out of the cell name
+    // examples: B5, Aa34,  Cf97 ...
+    xub_StrLen nLen = rCellName.Len();
+    xub_StrLen nFirstPart = 1;
+    while(nFirstPart < nLen && !lcl_IsNumeric(String(rCellName.GetChar(nFirstPart))))
+    {
+        nFirstPart ++;
+    }
+    String sRow(rCellName.Copy(nFirstPart,nLen - nFirstPart));
+    String sCol(rCellName.Copy(0, nFirstPart));
+    rRow = sRow.ToInt32();
+    rRow -= 1;
+
+    rCol = 0;
+    nLen = sCol.Len();
+    if(!nLen)
+    {
+        rRow = -1;
+        rCol = -1;
+    }
+    else
+    {
+        sal_uInt16 nBase = 1;
+        do
+        {
+            char cChar = sCol.GetChar(nLen-1);
+
+            if( cChar <= 'Z' )
+                rCol += nBase * (cChar - 'A' + nBase > 1 ? 1 : 0  );
+            else
+                rCol += nBase * (cChar - 'a' + 25);
+
+            sCol.Erase(nLen -1, 1);
+            nLen = sCol.Len();
+            nBase *= 50;
+        }
+        while(nLen);
+    }
+}
+
+/* -----------------25.06.98 08:32-------------------
+ *
+ * --------------------------------------------------*/
+SwXCell* lcl_CreateXCell(SwFrmFmt* pFmt, sal_Int16 nColumn, sal_Int16 nRow)
+{
+    SwXCell* pXCell = 0;
+    String sCellName = lcl_GetCellName(nColumn, nRow);
+    SwTable* pTable = SwTable::FindTable( pFmt );
+    SwTableBox* pBox = (SwTableBox*)pTable->GetTblBox( sCellName );
+    if(pBox)
+    {
+        pXCell = SwXCell::CreateXCell(pFmt, pBox, &sCellName);
+    }
+    return pXCell;
+}
+/* -----------------20.07.98 12:35-------------------
+ *
+ * --------------------------------------------------*/
+void lcl_InspectLines(SwTableLines& rLines, SvStrings& rAllNames)
+{
+    for( sal_uInt16 i = 0; i < rLines.Count(); i++ )
+    {
+        SwTableLine* pLine = rLines[i];
+        SwTableBoxes& rBoxes = pLine->GetTabBoxes();
+        for(sal_uInt16 j = 0; j < rBoxes.Count(); j++)
+        {
+            SwTableBox* pBox = rBoxes[j];
+            if(pBox->GetName().Len())
+                rAllNames.Insert(new String(pBox->GetName()), rAllNames.Count());
+            SwTableLines& rBoxLines = pBox->GetTabLines();
+            if(rBoxLines.Count())
+            {
+                lcl_InspectLines(rBoxLines, rAllNames);
+            }
+        }
+    }
+}
+/* -----------------02.10.98 15:55-------------------
+ *
+ * --------------------------------------------------*/
+void lcl_FormatTable(SwFrmFmt* pTblFmt)
+{
+    SwClientIter aIter( *pTblFmt );
+    for( SwClient* pC = aIter.First( TYPE( SwFrm ));
+            pC; pC = aIter.Next() )
+    {
+        if( ((SwFrm*)pC)->IsTabFrm() )
+        {
+            if(((SwFrm*)pC)->IsValid())
+                ((SwFrm*)pC)->InvalidatePos();
+            ((SwTabFrm*)pC)->SetONECalcLowers();
+            ((SwTabFrm*)pC)->Calc();
+        }
+    }
+}
+/* -----------------20.07.98 13:15-------------------
+ *
+ * --------------------------------------------------*/
+void lcl_CrsrSelect(SwPaM* pCrsr, sal_Bool bExpand)
+{
+    if(bExpand)
+    {
+        if(!pCrsr->HasMark())
+            pCrsr->SetMark();
+    }
+    else if(pCrsr->HasMark())
+        pCrsr->DeleteMark();
+
+}
+/* -----------------17.07.98 14:36-------------------
+ *
+ * --------------------------------------------------*/
+void lcl_GetTblSeparators(uno::Any& rRet, SwTable* pTable, SwTableBox* pBox, sal_Bool bRow)
+{
+    SwTabCols aCols;
+    aCols.SetLeftMin ( 0 );
+    aCols.SetLeft    ( 0 );
+    aCols.SetRight   ( UNO_TABLE_COLUMN_SUM );
+    aCols.SetRightMax( UNO_TABLE_COLUMN_SUM );
+
+    pTable->GetTabCols( aCols, pBox, sal_False );
+
+    sal_uInt16 nSepCount = aCols.Count();
+    uno::Sequence< TableColumnSeparator> aColSeq(nSepCount);
+     TableColumnSeparator* pArray = aColSeq.getArray();
+    sal_Bool bError = sal_False;
+    for(sal_uInt16 i = 0; i < nSepCount; i++)
+    {
+        pArray[i].Position = aCols[i];
+        pArray[i].IsVisible = !aCols.IsHidden(i);
+        if(!bRow && !pArray[i].IsVisible)
+        {
+            bError = sal_True;
+            break;
+        }
+    }
+    if(!bError)
+        rRet.setValue(&aColSeq, ::getCppuType((uno::Sequence< TableColumnSeparator>*)0));
+
+}
+/* -----------------17.07.98 14:36-------------------
+ *
+ * --------------------------------------------------*/
+void lcl_SetTblSeparators(const uno::Any& rVal, SwTable* pTable, SwTableBox* pBox, sal_Bool bRow, SwDoc* pDoc)
+{
+    SwTabCols aOldCols;
+
+    aOldCols.SetLeftMin ( 0 );
+    aOldCols.SetLeft    ( 0 );
+    aOldCols.SetRight   ( UNO_TABLE_COLUMN_SUM );
+    aOldCols.SetRightMax( UNO_TABLE_COLUMN_SUM );
+
+    pTable->GetTabCols( aOldCols, pBox, sal_False );
+    sal_uInt16 nOldCount = aOldCols.Count();
+
+    const uno::Sequence< TableColumnSeparator>* pSepSeq =
+                (uno::Sequence< TableColumnSeparator>*) rVal.getValue();
+    if(pSepSeq && pSepSeq->getLength() == nOldCount)
+    {
+        SwTabCols aCols(aOldCols);
+        sal_Bool bError = sal_False;
+        const TableColumnSeparator* pArray = pSepSeq->getConstArray();
+        sal_uInt16 nLastValue = 0;
+        sal_uInt16 nTblWidth = aCols.GetRight() - aCols.GetLeft();
+        for(sal_uInt16 i = 0; i < nOldCount; i++)
+        {
+            aCols[i] = pArray[i].Position;
+            if(pArray[i].IsVisible == aCols.IsHidden(i) ||
+                !bRow && aCols.IsHidden(i) ||
+                long(aCols[i] - long(nLastValue)) < 0 ||
+                UNO_TABLE_COLUMN_SUM < aCols[i] )
+            {
+                bError = sal_True;
+                break;
+            }
+            nLastValue = aCols[i];
+        }
+        if(!bError)
+        {
+            pDoc->SetTabCols(*pTable, aCols, aOldCols, pBox, bRow );
+        }
+    }
+}
+
+/******************************************************************************
+ *
+ ******************************************************************************/
+
+const SfxItemPropertyMap* GetTableDescPropertyMap()
+{
+    static SfxItemPropertyMap aTableDescPropertyMap_Impl[] =
+    {
+        { SW_PROP_NAME(UNO_NAME_BACK_COLOR )         ,  RES_BACKGROUND,         &::getCppuType((const sal_Int32*)0),            PROPERTY_NONE,MID_BACK_COLOR         },
+        { SW_PROP_NAME(UNO_NAME_BREAK_TYPE),            RES_BREAK,              &::getCppuType((const style::BreakType*)0),         PROPERTY_NONE, 0},
+        { SW_PROP_NAME(UNO_NAME_GRAPHIC_URL      ),         RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_URL    },
+        { SW_PROP_NAME(UNO_NAME_GRAPHIC_FILTER  ),      RES_BACKGROUND,         &::getCppuType((const OUString*)0), PROPERTY_NONE ,MID_GRAPHIC_FILTER    },
+        { SW_PROP_NAME(UNO_NAME_GRAPHIC_LOCATION)    ,      RES_BACKGROUND,         &::getCppuType((const style::GraphicLocation*)0), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+        { SW_PROP_NAME(UNO_NAME_LEFT_MARGIN),           RES_LR_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_L_MARGIN},
+        { SW_PROP_NAME(UNO_NAME_RIGHT_MARGIN),          RES_LR_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_R_MARGIN},
+        { SW_PROP_NAME(UNO_NAME_HORI_ORIENT  ),         RES_HORI_ORIENT,        &::getCppuType((const sal_Int16*)0),            PROPERTY_NONE ,MID_HORIORIENT_ORIENT    },
+        { SW_PROP_NAME(UNO_NAME_KEEP_TOGETHER),         RES_KEEP,               &::getBooleanCppuType()  ,  PROPERTY_NONE, 0},
+        { SW_PROP_NAME(UNO_NAME_SPLIT    ),             RES_LAYOUT_SPLIT,       &::getBooleanCppuType()  ,  PROPERTY_NONE, 0},
+        { SW_PROP_NAME(UNO_NAME_PAGE_NUMBER_OFFSET),    RES_PAGEDESC,           &::getCppuType((const sal_Int16*)0),        PROPERTY_NONE, MID_PAGEDESC_PAGENUMOFFSET},
+        { SW_PROP_NAME(UNO_NAME_PAGE_STYLE_NAME),           0,                      &::getCppuType((const OUString*)0),         PROPERTY_NONE, 0},
+        { SW_PROP_NAME(UNO_NAME_RELATIVE_WIDTH),        FN_TABLE_RELATIVE_WIDTH,&::getCppuType((const sal_Int16*)0)  ,          PROPERTY_NONE, 0    },
+        { SW_PROP_NAME(UNO_NAME_REPEAT_HEADLINE) ,      FN_TABLE_HEADLINE_REPEAT,&::getBooleanCppuType(),       PROPERTY_NONE, 0},
+        { SW_PROP_NAME(UNO_NAME_SHADOW_FORMAT),         RES_SHADOW,             &::getCppuType((const table::ShadowFormat*)0),  PROPERTY_NONE, CONVERT_TWIPS},
+        { SW_PROP_NAME(UNO_NAME_SIZE_RELATIVE),         FN_TABLE_IS_RELATIVE_WIDTH,  &::getBooleanCppuType()  ,     PROPERTY_NONE, 0 },
+        { SW_PROP_NAME(UNO_NAME_TABLE_NAME),          0,                      &::getCppuType((const OUString*)0),       PROPERTY_NONE, 0 },
+        { SW_PROP_NAME(UNO_NAME_TOP_MARGIN),            RES_UL_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_UP_MARGIN|CONVERT_TWIPS},
+        { SW_PROP_NAME(UNO_NAME_BOTTOM_MARGIN),         RES_UL_SPACE,           &::getCppuType((const sal_Int32*)0), PROPERTY_NONE, MID_LO_MARGIN|CONVERT_TWIPS},
+        { SW_PROP_NAME(UNO_NAME_TRANSPARENT_BACKGROUND),    RES_BACKGROUND,     &::getBooleanCppuType(),            PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT       },
+        { SW_PROP_NAME(UNO_NAME_WIDTH),                 FN_TABLE_WIDTH,         &::getCppuType((const sal_Int32*)0)  ,          PROPERTY_NONE, 0},
+        { SW_PROP_NAME(UNO_NAME_CHART_ROW_AS_LABEL),        FN_UNO_RANGE_ROW_LABEL,         &::getBooleanCppuType(),            PROPERTY_NONE,  0},
+        { SW_PROP_NAME(UNO_NAME_CHART_COLUMN_AS_LABEL),     FN_UNO_RANGE_COL_LABEL,         &::getBooleanCppuType()  ,          PROPERTY_NONE,     0},
+        { SW_PROP_NAME(UNO_NAME_TABLE_BORDER),          FN_UNO_TABLE_BORDER,            &::getCppuType((const table::TableBorder*)0),   PropertyAttribute::MAYBEVOID, CONVERT_TWIPS },
+        {0,0}
+    };
+    #define TABLE_PROP_COUNT 24
+    return aTableDescPropertyMap_Impl;
+}
+/******************************************************************
+ * SwXCell
+ ******************************************************************/
+TYPEINIT1(SwXCell, SwClient);
+/*-- 11.12.98 10:56:23---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXCell::SwXCell(SwFrmFmt* pTblFmt, SwTableBox* pBx, const String& rCellName) :
+    SwXText(pTblFmt->GetDoc(), CURSOR_TBLTEXT),
+    sCellName(rCellName),
+    pBox(pBx),
+    pStartNode(0),
+    aPropSet(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TABLE_CELL)),
+    SwClient(pTblFmt)
+{
+}
+/* -----------------------------09.08.00 15:59--------------------------------
+
+ ---------------------------------------------------------------------------*/
+SwXCell::SwXCell(SwFrmFmt* pTblFmt, const SwStartNode& rStartNode) :
+    SwXText(pTblFmt->GetDoc(), CURSOR_TBLTEXT),
+    pBox(0),
+    pStartNode(&rStartNode),
+    aPropSet(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TABLE_CELL)),
+    SwClient(pTblFmt)
+{
+}
+
+/*-- 11.12.98 10:56:24---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXCell::~SwXCell()
+{
+
+}
+/* -----------------------------18.05.00 10:18--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< uno::Type > SAL_CALL SwXCell::getTypes(  ) throw(::com::sun::star::uno::RuntimeException)
+{
+    uno::Sequence< uno::Type > aCellTypes = SwXCellBaseClass::getTypes();
+    uno::Sequence< uno::Type > aTextTypes = SwXText::getTypes();
+
+    long nIndex = aCellTypes.getLength();
+    aCellTypes.realloc(
+        aCellTypes.getLength() +
+        aTextTypes.getLength());
+
+    uno::Type* pCellTypes = aCellTypes.getArray();
+
+    const uno::Type* pTextTypes = aTextTypes.getConstArray();
+    for(long nPos = 0; nPos  SAL_CALL SwXCell::getImplementationId(  ) throw(::com::sun::star::uno::RuntimeException)
+{
+    static uno::Sequence< sal_Int8 > aId( 16 );
+    static BOOL bInit = FALSE;
+    if(!bInit)
+        rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
+    return aId;
+}
+/* -----------------------------18.05.00 10:18--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SAL_CALL SwXCell::acquire(  ) throw()
+{
+    SwXCellBaseClass::acquire();
+}
+/* -----------------------------18.05.00 10:18--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SAL_CALL SwXCell::release(  ) throw()
+{
+    SwXCellBaseClass::release();
+}
+/* -----------------------------18.05.00 10:23--------------------------------
+
+ ---------------------------------------------------------------------------*/
+uno::Any SAL_CALL SwXCell::queryInterface( const uno::Type& aType )
+    throw (RuntimeException)
+{
+    uno::Any aRet = SwXText::queryInterface(aType);
+    if(aRet.getValueType() == ::getCppuVoidType())
+        aRet = SwXCellBaseClass::queryInterface(aType);
+    return aRet;
+}
+/*-- 11.12.98 10:56:24---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XTextCursor >   SwXCell::createCursor()
+{
+    return createTextCursor();
+}
+/*-- 11.12.98 10:56:24---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool    SwXCell::IsValid()
+{
+    SwFrmFmt* pTblFmt = pBox ? GetFrmFmt() : 0;
+    if(!pTblFmt)
+        pBox = 0;
+    else
+    {
+        SwTable* pTable = SwTable::FindTable( pTblFmt );
+        const SwTableBox* pFoundBox = sCellName.Len() ?
+                        pTable->GetTblBox( sCellName ) : SwXCell::FindBox(pTable, pBox);
+        if(pFoundBox != pBox)
+            pBox = 0;
+    }
+    return 0 != pBox;
+}
+/*-- 11.12.98 10:56:25---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+OUString SwXCell::getFormula(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    OUString sRet;
+    if(IsValid())
+    {
+        SwAttrSet aSet(pBox->ClaimFrmFmt()->GetAttrSet());
+        SwTblBoxFormula aFormula((const SwTblBoxFormula&)  aSet.Get( RES_BOXATR_FORMULA ));
+        SwTable* pTable = SwTable::FindTable( GetFrmFmt() );
+        aFormula.PtrToBoxNm( pTable );
+        sRet = aFormula.GetFormula();
+    }
+    return sRet;
+}
+/*-- 11.12.98 10:56:26---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXCell::setFormula(const OUString& rFormula) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(IsValid())
+    {
+        // Der Text muß zunaechst (vielleicht) geloescht werden
+        sal_uInt32 nNdPos = pBox->IsValidNumTxtNd( sal_True );
+        if(USHRT_MAX == nNdPos)
+            setString(OUString());
+        String sFml(rFormula);
+        if( sFml.EraseLeadingChars().Len() && '=' == sFml.GetChar( 0 ) )
+                    sFml.Erase( 0, 1 );
+        SwTblBoxFormula aFml( sFml );
+        SwDoc* pDoc = GetDoc();
+        UnoActionContext aAction(pDoc);
+        SfxItemSet aSet(pDoc->GetAttrPool(), RES_BOXATR_FORMAT, RES_BOXATR_FORMULA);
+        const SfxPoolItem* pItem;
+        SwFrmFmt* pBoxFmt = pBox->GetFrmFmt();
+        if(SFX_ITEM_SET != pBoxFmt->GetAttrSet().GetItemState(RES_BOXATR_FORMAT, sal_True, &pItem)
+            ||  pDoc->GetNumberFormatter()->IsTextFormat(((SwTblBoxNumFormat*)pItem)->GetValue()))
+        {
+            aSet.Put(SwTblBoxNumFormat(0));
+        }
+        aSet.Put(aFml);
+        GetDoc()->SetTblBoxFormulaAttrs( *pBox, aSet );
+        //Tabelle aktualisieren
+        SwTableFmlUpdate aTblUpdate( SwTable::FindTable( GetFrmFmt() ));
+        pDoc->UpdateTblFlds( &aTblUpdate );
+    }
+}
+/*-- 11.12.98 10:56:26---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+double SwXCell::getValue(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    double fRet = 0.;
+    if(IsValid())
+    {
+
+        SwAttrSet aSet(pBox->ClaimFrmFmt()->GetAttrSet());
+        fRet = ((SwTblBoxValue&)aSet.Get(RES_BOXATR_VALUE)).GetValue();
+    }
+    return fRet;
+}
+/*-- 11.12.98 10:56:26---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXCell::setValue(double rValue) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(IsValid())
+    {
+        // Der Text muß zunaechst (vielleicht) geloescht werden
+        sal_uInt32 nNdPos = pBox->IsValidNumTxtNd( sal_True );
+        if(USHRT_MAX == nNdPos)
+            setString(OUString());
+        SwDoc* pDoc = GetDoc();
+        UnoActionContext aAction(pDoc);
+        SwFrmFmt* pBoxFmt = pBox->GetFrmFmt();
+        SfxItemSet aSet(pDoc->GetAttrPool(), RES_BOXATR_FORMAT, RES_BOXATR_VALUE);
+        const SfxPoolItem* pItem;
+        if(SFX_ITEM_SET != pBoxFmt->GetAttrSet().GetItemState(RES_BOXATR_FORMAT, sal_True, &pItem)
+            ||  pDoc->GetNumberFormatter()->IsTextFormat(((SwTblBoxNumFormat*)pItem)->GetValue()))
+        {
+            aSet.Put(SwTblBoxNumFormat(0));
+        }
+
+        SwTblBoxValue aVal(rValue);
+        aSet.Put(aVal);
+        pDoc->SetTblBoxFormulaAttrs( *pBox, aSet );
+        //Tabelle aktualisieren
+        SwTableFmlUpdate aTblUpdate( SwTable::FindTable( GetFrmFmt() ));
+        pDoc->UpdateTblFlds( &aTblUpdate );
+    }
+}
+/*-- 11.12.98 10:56:26---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+table::CellContentType SwXCell::getType(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    DBG_WARNING("not implemented")
+    return  (table::CellContentType)0;
+}
+/* -----------------27.04.99 12:06-------------------
+ *
+ * --------------------------------------------------*/
+void SwXCell::setString(const OUString& aString) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(IsValid())
+    {
+        SwFrmFmt* pBoxFmt = pBox->GetFrmFmt();
+        pBoxFmt->LockModify();
+        pBoxFmt->ResetAttr( RES_BOXATR_FORMULA );
+        pBoxFmt->ResetAttr( RES_BOXATR_VALUE );
+        pBoxFmt->UnlockModify();
+    }
+    SwXText::setString(aString);
+}
+
+/*-- 11.12.98 10:56:27---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Int32 SwXCell::getError(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    OUString sContent = getString();
+    return sContent.equals(ViewShell::GetShellRes()->aCalc_Error);
+}
+/*-- 11.12.98 10:56:28---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XTextCursor >  SwXCell::createTextCursor(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< XTextCursor >   aRef;
+    if(pStartNode || IsValid())
+    {
+        const SwStartNode* pSttNd = pStartNode ? pStartNode : pBox->GetSttNd();
+        SwPosition aPos(*pSttNd);
+        SwXTextCursor* pCrsr = new SwXTextCursor(this, aPos, CURSOR_TBLTEXT, GetDoc());
+        SwUnoCrsr* pUnoCrsr = pCrsr->GetCrsr();
+        pUnoCrsr->Move(fnMoveForward, fnGoNode);
+        aRef =  (XWordCursor*)pCrsr;
+//      // no Cursor in protected sections
+//      SwCrsrSaveState aSave( *pUnoCrsr );
+//      if(pUnoCrsr->IsInProtectTable( sal_True ) ||
+//          pUnoCrsr->IsSelOvr( SELOVER_TOGGLE | SELOVER_CHANGEPOS ))
+//          throw( uno::RuntimeException() );
+    }
+    else
+        throw uno::RuntimeException();
+    return aRef;
+}
+/*-- 11.12.98 10:56:28---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XTextCursor >  SwXCell::createTextCursorByRange(const uno::Reference< XTextRange > & xTextPosition)
+                                                        throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< XTextCursor >  aRef;
+    SwUnoInternalPaM aPam(*GetDoc());
+    if((pStartNode || IsValid()) && SwXTextRange::XTextRangeToSwPaM(aPam, xTextPosition))
+    {
+        const SwStartNode* pSttNd = pStartNode ? pStartNode : pBox->GetSttNd();
+        if(aPam.GetNode()->FindStartNode() == pSttNd)
+            aRef =  (XWordCursor*)new SwXTextCursor(this , *aPam.GetPoint(), CURSOR_TBLTEXT, GetDoc(), aPam.GetMark());
+    }
+    else
+        throw uno::RuntimeException();
+    return aRef;
+}
+/*-- 11.12.98 10:56:33---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< beans::XPropertySetInfo >  SwXCell::getPropertySetInfo(void) throw( uno::RuntimeException )
+{
+    static uno::Reference< beans::XPropertySetInfo >  xRef = aPropSet.getPropertySetInfo();
+    return xRef;
+}
+/*-- 11.12.98 10:56:34---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXCell::setPropertyValue(const OUString& rPropertyName, const uno::Any& aValue) throw( beans::UnknownPropertyException, beans::PropertyVetoException, IllegalArgumentException, WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(IsValid())
+    {
+        SwFrmFmt* pBoxFmt = pBox->ClaimFrmFmt();
+        SwAttrSet aSet(pBoxFmt->GetAttrSet());
+        aPropSet.setPropertyValue(rPropertyName, aValue, aSet);
+        pBoxFmt->GetDoc()->SetAttr(aSet, *pBoxFmt);
+    }
+}
+/*-- 11.12.98 10:56:34---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXCell::getPropertyValue(const OUString& rPropertyName) throw( beans::UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Any aRet;
+    if(IsValid())
+    {
+        SwFrmFmt* pBoxFmt = pBox->ClaimFrmFmt();
+        const SwAttrSet& rSet = pBoxFmt->GetAttrSet();
+        aRet = aPropSet.getPropertyValue(rPropertyName, rSet);
+    }
+    return aRet;
+}
+/*-- 11.12.98 10:56:35---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXCell::addPropertyChangeListener(const OUString& PropertyName, const uno::Reference< beans::XPropertyChangeListener > & aListener) throw( beans::UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    DBG_WARNING("not implemented")
+}
+/*-- 11.12.98 10:56:35---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXCell::removePropertyChangeListener(const OUString& PropertyName, const uno::Reference< beans::XPropertyChangeListener > & aListener) throw( beans::UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    DBG_WARNING("not implemented")
+}
+/*-- 11.12.98 10:56:36---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXCell::addVetoableChangeListener(const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener > & aListener) throw( beans::UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    DBG_WARNING("not implemented")
+}
+/*-- 11.12.98 10:56:36---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXCell::removeVetoableChangeListener(const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener > & aListener) throw( beans::UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    DBG_WARNING("not implemented")
+}
+/*-- 11.12.98 10:56:37---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< container::XEnumeration >  SwXCell::createEnumeration(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< container::XEnumeration >  aRef;
+    if(IsValid())
+    {
+        const SwStartNode* pSttNd = pBox->GetSttNd();
+        SwPosition aPos(*pSttNd);
+        SwUnoCrsr* pUnoCrsr = GetDoc()->CreateUnoCrsr(aPos, sal_False);
+        pUnoCrsr->Move( fnMoveForward, fnGoNode );
+        aRef = new SwXParagraphEnumeration(this, pUnoCrsr, CURSOR_TBLTEXT);
+//      // no Cursor in protected sections
+//      SwCrsrSaveState aSave( *pUnoCrsr );
+//      if(pUnoCrsr->IsInProtectTable( sal_True ) ||
+//          pUnoCrsr->IsSelOvr( SELOVER_TOGGLE | SELOVER_CHANGEPOS ))
+//          throw( uno::RuntimeException() );
+    }
+    return aRef;
+}
+/*-- 11.12.98 10:56:38---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Type SAL_CALL SwXCell::getElementType(void) throw( uno::RuntimeException )
+{
+    return ::getCppuType((const uno::Reference*)0);
+
+}
+/*-- 11.12.98 10:56:38---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXCell::hasElements(void) throw( uno::RuntimeException )
+{
+    return sal_True;
+}
+/*-- 11.12.98 10:56:37---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXCell::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew)
+{
+    ClientModify(this, pOld, pNew);
+}
+/* -----------------12.06.98 07:54-------------------
+ *
+ * --------------------------------------------------*/
+SwXCell* SwXCell::CreateXCell(SwFrmFmt* pTblFmt, SwTableBox* pBox, const String* pCellName)
+{
+    SwXCell* pRet = 0;
+    if(pTblFmt && pBox)
+    {
+        SwTable* pTable = SwTable::FindTable( pTblFmt );
+        SwTableBox* pFoundBox = SwXCell::FindBox(pTable, pBox);
+        //wenn es die Box gibt, dann wird auch eine Zelle zurueckgegeben
+        if(pFoundBox)
+        {
+            SwClientIter aIter( *pTblFmt );
+            SwXCell* pXCell = (SwXCell*)aIter.
+                                    First( TYPE( SwXCell ));
+            while( pXCell )
+            {
+                // gibt es eine passende Zelle bereits?
+                if(pXCell->GetTblBox() == pBox)
+                    break;
+                pXCell = (SwXCell*)aIter.Next();
+            }
+            //sonst anlegen
+            if(!pXCell)
+                pXCell = new SwXCell(pTblFmt, pBox, pCellName? *pCellName : aEmptyStr);
+            pRet = pXCell;
+        }
+    }
+    return pRet;
+}
+/* -----------------12.06.98 07:37-------------------
+ *  exitstiert die Box in der angegebenen Tabelle?
+ * --------------------------------------------------*/
+SwTableBox* SwXCell::FindBox(SwTable* pTable, SwTableBox* pBox)
+{
+    if( pTable->GetTabSortBoxes().Seek_Entry( pBox ))
+        return pBox;
+    return 0;
+}
+/* -----------------------------19.04.00 15:20--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXCell::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXCell");
+}
+/* -----------------------------19.04.00 15:20--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXCell::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    String sServiceName(rServiceName);
+    return sServiceName.EqualsAscii("com.sun.star.table.Cell")||
+            sServiceName.EqualsAscii("com.sun.star.table.CellProperties");
+}
+/* -----------------------------19.04.00 15:20--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXCell::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(2);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.table.Cell");
+    pArray[1] = C2U("com.sun.star.table.CellProperties");
+    return aRet;
+}
+
+/******************************************************************
+ * SwXTextTableRow
+ ******************************************************************/
+/* -----------------------------19.04.00 15:20--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXTextTableRow::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXTextTableRow");
+}
+/* -----------------------------19.04.00 15:20--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXTextTableRow::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.text.TextTableRow") == rServiceName;
+}
+/* -----------------------------19.04.00 15:20--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXTextTableRow::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.TextTableRow");
+    return aRet;
+}
+TYPEINIT1(SwXTextTableRow, SwClient);
+/*-- 11.12.98 12:04:44---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextTableRow::SwXTextTableRow(SwFrmFmt* pFmt, SwTableLine* pLn) :
+    SwClient(pFmt),
+    aPropSet(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_TABLE_ROW)),
+    pLine(pLn)
+{
+
+}
+/*-- 11.12.98 12:04:45---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextTableRow::~SwXTextTableRow()
+{
+
+}
+/*-- 11.12.98 12:04:46---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< beans::XPropertySetInfo >  SwXTextTableRow::getPropertySetInfo(void) throw( uno::RuntimeException )
+{
+    static uno::Reference< beans::XPropertySetInfo >  xRef = aPropSet.getPropertySetInfo();
+    return xRef;
+}
+/*-- 11.12.98 12:04:46---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextTableRow::setPropertyValue(const OUString& rPropertyName,
+    const uno::Any& aValue)
+    throw( beans::UnknownPropertyException, beans::PropertyVetoException, IllegalArgumentException, WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt)
+    {
+        SwTable* pTable = SwTable::FindTable( pFmt );
+        SwTableLine* pLn = SwXTextTableRow::FindLine(pTable, pLine);
+        if(pLn)
+        {
+            const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                                    aPropSet.getPropertyMap(), rPropertyName);
+            SwDoc* pDoc = pFmt->GetDoc();
+            if(!pMap)
+                throw beans::UnknownPropertyException();
+            switch(pMap->nWID)
+            {
+                case FN_UNO_ROW_HEIGHT:
+                case FN_UNO_ROW_AUTO_HEIGHT:
+                {
+                    SwFmtFrmSize aFrmSize(pLn->GetFrmFmt()->GetFrmSize());
+                    if(FN_UNO_ROW_AUTO_HEIGHT== pMap->nWID)
+                    {
+                        sal_Bool bSet = *(sal_Bool*)aValue.getValue();
+                        aFrmSize.SetSizeType(bSet ? ATT_VAR_SIZE : ATT_FIX_SIZE);
+                    }
+                    else
+                    {
+                        sal_Int32 nHeight;
+                        aValue >>= nHeight;
+                         Size aSz(aFrmSize.GetSize());
+                        aSz.Height() = MM100_TO_TWIP(nHeight);
+                        aFrmSize.SetSize(aSz);
+                    }
+                    pDoc->SetAttr(aFrmSize, *pLn->ClaimFrmFmt());
+                }
+                break;
+                case FN_UNO_TABLE_COLUMN_SEPARATORS:
+                {
+                    SwTable* pTable = SwTable::FindTable( pFmt );
+                    lcl_SetTblSeparators(aValue, pTable, pLine->GetTabBoxes()[0], sal_True, pDoc);
+                }
+                break;
+                default:
+                {
+                    SwFrmFmt* pLnFmt = pLn->ClaimFrmFmt();
+                    SwAttrSet aSet(pLnFmt->GetAttrSet());
+                    aPropSet.setPropertyValue(rPropertyName, aValue, aSet);
+                    pDoc->SetAttr(aSet, *pLnFmt);
+                }
+            }
+        }
+    }
+}
+/*-- 11.12.98 12:04:47---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXTextTableRow::getPropertyValue(const OUString& rPropertyName) throw( beans::UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Any aRet;
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt)
+    {
+        SwTable* pTable = SwTable::FindTable( pFmt );
+        SwTableLine* pLn = SwXTextTableRow::FindLine(pTable, pLine);
+        if(pLn)
+        {
+            const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                                    aPropSet.getPropertyMap(), rPropertyName);
+            if(!pMap)
+                throw beans::UnknownPropertyException();
+            switch(pMap->nWID)
+            {
+                case FN_UNO_ROW_HEIGHT:
+                case FN_UNO_ROW_AUTO_HEIGHT:
+                {
+                    const SwFmtFrmSize& rSize = pLn->GetFrmFmt()->GetFrmSize();
+                    if(FN_UNO_ROW_AUTO_HEIGHT== pMap->nWID)
+                    {
+                        BOOL bTmp =  ATT_VAR_SIZE == rSize.GetSizeType();
+                        aRet.setValue(&bTmp, ::getCppuBooleanType());
+                    }
+                    else
+                        aRet <<= (sal_Int32)(TWIP_TO_MM100(rSize.GetSize().Height()));
+                }
+                break;
+                case FN_UNO_TABLE_COLUMN_SEPARATORS:
+                {
+                    lcl_GetTblSeparators(aRet, pTable, pLine->GetTabBoxes()[0], sal_True);
+                }
+                break;
+                default:
+                {
+                    const SwAttrSet& rSet = pLn->GetFrmFmt()->GetAttrSet();
+                    aRet = aPropSet.getPropertyValue(rPropertyName, rSet);
+                }
+            }
+        }
+    }
+    return aRet;
+}
+/*-- 11.12.98 12:04:47---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextTableRow::addPropertyChangeListener(const OUString& PropertyName, const uno::Reference< beans::XPropertyChangeListener > & aListener) throw( beans::UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 11.12.98 12:04:48---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextTableRow::removePropertyChangeListener(const OUString& PropertyName, const uno::Reference< beans::XPropertyChangeListener > & aListener) throw( beans::UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 11.12.98 12:04:48---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextTableRow::addVetoableChangeListener(const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener > & aListener) throw( beans::UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 11.12.98 12:04:49---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextTableRow::removeVetoableChangeListener(const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener > & aListener) throw( beans::UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 11.12.98 12:04:49---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextTableRow::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew)
+{
+    ClientModify(this, pOld, pNew);
+}
+/*-- 11.12.98 12:04:50---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwTableLine* SwXTextTableRow::FindLine(SwTable* pTable, SwTableLine* pLine)
+{
+    SwTableLine* pRet = 0;
+    SwTableLines &rLines = pTable->GetTabLines();
+    for(sal_uInt16 i = 0; i < rLines.Count(); i++)
+        if(rLines.GetObject(i) == pLine)
+        {
+            pRet = pLine;
+            break;
+        }
+    return pRet;
+}
+
+/******************************************************************
+ * SwXTextTableCursor
+ ******************************************************************/
+/* -----------------------------19.04.00 15:21--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXTextTableCursor::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXTextTableCursor");
+}
+/* -----------------------------19.04.00 15:21--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXTextTableCursor::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.text.TextTableCursor") == rServiceName;
+}
+/* -----------------------------19.04.00 15:21--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXTextTableCursor::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.TextTableCursor");
+    return aRet;
+}
+
+/*-- 11.12.98 12:16:13---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextTableCursor::SwXTextTableCursor(SwFrmFmt* pFmt, SwTableBox* pBox) :
+    SwClient(pFmt),
+    aPropSet(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_TABLE_CURSOR)),
+    aCrsrDepend(this, 0)
+{
+    SwDoc* pDoc = pFmt->GetDoc();
+    const SwStartNode* pSttNd = pBox->GetSttNd();
+    SwPosition aPos(*pSttNd);
+    SwUnoCrsr* pUnoCrsr = pDoc->CreateUnoCrsr(aPos, sal_True);
+    pUnoCrsr->Move( fnMoveForward, fnGoNode );
+    pUnoCrsr->Add(&aCrsrDepend);
+    SwUnoTableCrsr* pTblCrsr = *pUnoCrsr;
+    pTblCrsr->MakeBoxSels();
+}
+/*-- 11.12.98 12:16:14---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextTableCursor::SwXTextTableCursor(SwFrmFmt& rTableFmt, const SwTableCursor* pTableSelection) :
+    SwClient(&rTableFmt),
+    aPropSet(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_TABLE_CURSOR)),
+    aCrsrDepend(this, 0)
+{
+    SwUnoCrsr* pUnoCrsr = pTableSelection->GetDoc()->CreateUnoCrsr(*pTableSelection->GetPoint(), sal_True);
+    if(pTableSelection->HasMark())
+    {
+        pUnoCrsr->SetMark();
+        *pUnoCrsr->GetMark() = *pTableSelection->GetMark();
+    }
+    const SwSelBoxes& rBoxes = pTableSelection->GetBoxes();
+    SwTableCursor* pTableCrsr = (SwTableCursor*) *pUnoCrsr;
+    for(sal_uInt16 i = 0; i < rBoxes.Count(); i++)
+        pTableCrsr->InsertBox( *rBoxes.GetObject(i) );
+
+    pUnoCrsr->Add(&aCrsrDepend);
+    SwUnoTableCrsr* pTblCrsr = *pUnoCrsr;
+    pTblCrsr->MakeBoxSels();
+}
+/*-- 11.12.98 12:16:14---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextTableCursor::~SwXTextTableCursor()
+{
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+        delete pUnoCrsr;
+}
+/*-- 11.12.98 12:16:15---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+OUString SwXTextTableCursor::getRangeName(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    OUString aRet;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        SwUnoTableCrsr* pTblCrsr = *pUnoCrsr;
+        pTblCrsr->MakeBoxSels();
+        const SwStartNode* pStart = pTblCrsr->GetPoint()->nNode.GetNode().FindTableBoxStartNode();
+        const SwTable* pTable = SwTable::FindTable( GetFrmFmt() );
+        const SwTableBox* pBox = pTable->GetTblBox( pStart->GetIndex());
+        String sRet = pBox->GetName();
+
+        if(pTblCrsr->HasMark())
+        {
+            pStart = pTblCrsr->GetMark()->nNode.GetNode().FindTableBoxStartNode();
+            const SwTableBox* pEBox = pTable->GetTblBox( pStart->GetIndex());
+            if(pEBox != pBox)
+            {
+                sRet += ':';
+                sRet += pEBox->GetName();
+            }
+        }
+        aRet = sRet;
+    }
+    return aRet;
+}
+/*-- 11.12.98 12:16:15---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextTableCursor::gotoCellByName(const OUString& CellName, sal_Bool Expand)
+    throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Bool bRet = sal_False;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        SwUnoTableCrsr* pTblCrsr = *pUnoCrsr;
+        lcl_CrsrSelect( pTblCrsr, Expand );
+        String sCellName(CellName);
+        sCellName.ToUpperAscii();
+        bRet = pTblCrsr->GotoTblBox(sCellName);
+    }
+    return bRet;
+}
+/*-- 11.12.98 12:16:15---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextTableCursor::goLeft(sal_Int16 Count, sal_Bool Expand) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Bool bRet = sal_False;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        SwUnoTableCrsr* pTblCrsr = *pUnoCrsr;
+        lcl_CrsrSelect( pTblCrsr, Expand );
+        bRet = pTblCrsr->LeftRight(sal_True, Count);
+    }
+    return bRet;
+}
+/*-- 11.12.98 12:16:15---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextTableCursor::goRight(sal_Int16 Count, sal_Bool Expand) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Bool bRet = sal_False;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        SwUnoTableCrsr* pTblCrsr = *pUnoCrsr;
+        lcl_CrsrSelect( pTblCrsr, Expand );
+        bRet = pTblCrsr->LeftRight(sal_False, Count);
+    }
+    return bRet;
+}
+/*-- 11.12.98 12:16:16---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextTableCursor::goUp(sal_Int16 Count, sal_Bool Expand) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Bool bRet = sal_False;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        SwUnoTableCrsr* pTblCrsr = *pUnoCrsr;
+        lcl_CrsrSelect( pTblCrsr, Expand );
+        bRet = pTblCrsr->UpDown(sal_True, Count);
+    }
+    return bRet;
+}
+/*-- 11.12.98 12:16:16---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextTableCursor::goDown(sal_Int16 Count, sal_Bool Expand) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Bool bRet = sal_False;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        SwUnoTableCrsr* pTblCrsr = *pUnoCrsr;
+        lcl_CrsrSelect( pTblCrsr, Expand );
+        bRet = pTblCrsr->UpDown(sal_False, Count);
+    }
+    return bRet;
+}
+/*-- 11.12.98 12:16:16---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextTableCursor::gotoStart(sal_Bool Expand) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        SwUnoTableCrsr* pTblCrsr = *pUnoCrsr;
+        lcl_CrsrSelect( pTblCrsr, Expand );
+        pTblCrsr->MoveTable(fnTableCurr, fnTableStart);
+    }
+}
+/*-- 11.12.98 12:16:16---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextTableCursor::gotoEnd(sal_Bool Expand) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        SwUnoTableCrsr* pTblCrsr = *pUnoCrsr;
+        lcl_CrsrSelect( pTblCrsr, Expand );
+        pTblCrsr->MoveTable(fnTableCurr, fnTableEnd);
+    }
+}
+/*-- 11.12.98 12:16:16---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextTableCursor::mergeRange(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Bool bRet = sal_False;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        {
+            // hier muessen die Actions aufgehoben werden
+            UnoActionRemoveContext aRemoveContext(pUnoCrsr->GetDoc());
+        }
+        SwUnoTableCrsr* pTblCrsr = *pUnoCrsr;
+        pTblCrsr->MakeBoxSels();
+        EXCEPT_ON_TBL_PROTECTION(*pTblCrsr)
+
+        bRet = TBLMERGE_OK == pTblCrsr->GetDoc()->MergeTbl(*pTblCrsr);
+        pTblCrsr->MakeBoxSels();
+    }
+    return bRet;
+}
+/*-- 11.12.98 12:16:16---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTextTableCursor::splitRange(sal_Int16 Count, sal_Bool Horizontal) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Bool bRet = sal_False;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        {
+            // hier muessen die Actions aufgehoben werden
+            UnoActionRemoveContext aRemoveContext(pUnoCrsr->GetDoc());
+        }
+        SwUnoTableCrsr* pTblCrsr = *pUnoCrsr;
+        pTblCrsr->MakeBoxSels();
+        EXCEPT_ON_TBL_PROTECTION(*pTblCrsr)
+
+        bRet = pTblCrsr->GetDoc()->SplitTbl( pTblCrsr->GetBoxes(), !Horizontal, Count );
+        pTblCrsr->MakeBoxSels();
+    }
+    return bRet;
+}
+/*-- 11.12.98 12:16:17---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< beans::XPropertySetInfo >  SwXTextTableCursor::getPropertySetInfo(void) throw( uno::RuntimeException )
+{
+    static uno::Reference< beans::XPropertySetInfo >  xRef = aPropSet.getPropertySetInfo();
+    return xRef;
+}
+/*-- 11.12.98 12:16:17---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextTableCursor::setPropertyValue(const OUString& rPropertyName,
+                                                        const uno::Any& aValue)
+            throw( beans::UnknownPropertyException,
+                        beans::PropertyVetoException,
+                     IllegalArgumentException,
+                     WrappedTargetException,
+                     uno::RuntimeException)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        SwStartNode* pSttNode = pUnoCrsr->GetNode()->FindStartNode();
+        const SwTableNode* pTblNode = pSttNode->FindTableNode();
+        lcl_FormatTable((SwFrmFmt*)pTblNode->GetTable().GetFrmFmt());
+        SwUnoTableCrsr* pTblCrsr = *pUnoCrsr;
+        EXCEPT_ON_TBL_PROTECTION(*pTblCrsr)
+        const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                                                    aPropSet.getPropertyMap(), rPropertyName);
+        if(pMap)
+        {
+            pTblCrsr->MakeBoxSels();
+            SwDoc* pDoc = pUnoCrsr->GetDoc();
+            switch(pMap->nWID )
+            {
+                case FN_UNO_TABLE_CELL_BACKGROUND:
+                {
+                    SvxBrushItem aBrush;
+                    pDoc->GetBoxBackground( *pUnoCrsr, aBrush );
+                    aBrush.PutValue(aValue, pMap->nMemberId);
+                    pDoc->SetBoxAttr( *pUnoCrsr, aBrush );
+
+                }
+                break;
+                case RES_BOXATR_FORMAT:
+                {
+                    SfxUInt32Item aNumberFormat(RES_BOXATR_FORMAT);
+                    aNumberFormat.PutValue(aValue, 0);
+                    pDoc->SetBoxAttr( *pUnoCrsr, aNumberFormat);
+                }
+                break;
+                case FN_UNO_PARA_STYLE:
+                    lcl_SetTxtFmtColl(aValue, *pUnoCrsr);
+                break;
+                default:
+                {
+                    EXCEPT_ON_PROTECTION(*pUnoCrsr)
+
+                    SfxItemSet rSet(pDoc->GetAttrPool(),
+                        RES_CHRATR_BEGIN,       RES_FRMATR_END -1,
+                        RES_UNKNOWNATR_CONTAINER, RES_UNKNOWNATR_CONTAINER,
+                        0L);
+                    SwXTextCursor::GetCrsrAttr(pTblCrsr->GetSelRing(), rSet);
+                    aPropSet.setPropertyValue(rPropertyName, aValue, rSet);
+                    SwXTextCursor::SetCrsrAttr(pTblCrsr->GetSelRing(), rSet, sal_True);
+                }
+            }
+        }
+    }
+}
+/*-- 11.12.98 12:16:17---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXTextTableCursor::getPropertyValue(const OUString& rPropertyName)
+    throw( beans::UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Any aRet;
+    SwUnoCrsr* pUnoCrsr = GetCrsr();
+    if(pUnoCrsr)
+    {
+        SwStartNode* pSttNode = pUnoCrsr->GetNode()->FindStartNode();
+        const SwTableNode* pTblNode = pSttNode->FindTableNode();
+        lcl_FormatTable((SwFrmFmt*)pTblNode->GetTable().GetFrmFmt());
+        SwUnoTableCrsr* pTblCrsr = *pUnoCrsr;
+        const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                                                    aPropSet.getPropertyMap(), rPropertyName);
+        if(pMap)
+        {
+            pTblCrsr->MakeBoxSels();
+            switch(pMap->nWID )
+            {
+                case FN_UNO_TABLE_CELL_BACKGROUND:
+                {
+                    SvxBrushItem aBrush;
+                    if(pTblCrsr->GetDoc()->GetBoxBackground( *pUnoCrsr, aBrush ))
+                        aBrush.QueryValue(aRet, pMap->nMemberId);
+
+                }
+                break;
+                case RES_BOXATR_FORMAT:
+                    //GetAttr fuer Tabellenselektion am Doc fehlt noch
+                    DBG_WARNING("not implemented")
+                break;
+                case FN_UNO_PARA_STYLE:
+                {
+                    SwFmtColl* pFmt = SwXTextCursor::GetCurTxtFmtColl(*pUnoCrsr, FALSE);
+                    OUString sRet;
+                    if(pFmt)
+                        sRet = pFmt->GetName();
+                    aRet <<= sRet;
+                }
+                break;
+                default:
+                {
+                    SfxItemSet aSet(pTblCrsr->GetDoc()->GetAttrPool(),
+                        RES_CHRATR_BEGIN,       RES_FRMATR_END -1,
+                        RES_UNKNOWNATR_CONTAINER, RES_UNKNOWNATR_CONTAINER,
+                        0L);
+                    // erstmal die Attribute des Cursors
+                    SwXTextCursor::GetCrsrAttr(pTblCrsr->GetSelRing(), aSet);
+                    aRet = aPropSet.getPropertyValue(rPropertyName, aSet);
+                }
+            }
+        }
+    }
+    return aRet;
+}
+/*-- 11.12.98 12:16:18---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextTableCursor::addPropertyChangeListener(const OUString& PropertyName, const uno::Reference< beans::XPropertyChangeListener > & aListener) throw( beans::UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 11.12.98 12:16:18---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextTableCursor::removePropertyChangeListener(const OUString& PropertyName, const uno::Reference< beans::XPropertyChangeListener > & aListener) throw( beans::UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 11.12.98 12:16:18---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextTableCursor::addVetoableChangeListener(const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener > & aListener) throw( beans::UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 11.12.98 12:16:19---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextTableCursor::removeVetoableChangeListener(const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener > & aListener) throw( beans::UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 11.12.98 12:16:19---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextTableCursor::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew)
+{
+    ClientModify(this, pOld, pNew);
+}
+/******************************************************************
+ * SwXTextTable
+ ******************************************************************/
+/****************************************************************************
+    Tabellenbeschreibung
+****************************************************************************/
+
+class SwTableProperties_Impl
+{
+    const SfxItemPropertyMap*   _pMap;
+    uno::Any*                   pAnyArr[TABLE_PROP_COUNT];
+    sal_uInt16                      nArrLen;
+
+public:
+    SwTableProperties_Impl(const SfxItemPropertyMap* pMap);
+    ~SwTableProperties_Impl();
+
+    sal_Bool    SetProperty(const char* pName, uno::Any aVal);
+    sal_Bool    GetProperty(const char* pName, uno::Any*& rpAny);
+
+    const SfxItemPropertyMap*   GetMap() const {return _pMap;}
+    void                        ApplyTblAttr(const SwTable& rTbl, SwDoc& rDoc);
+};
+
+/* -----------------22.06.98 09:43-------------------
+ *
+ * --------------------------------------------------*/
+SwTableProperties_Impl::SwTableProperties_Impl(const SfxItemPropertyMap* pMap) :
+    _pMap(pMap),
+    nArrLen(TABLE_PROP_COUNT)
+{
+    const SfxItemPropertyMap* pTemp = _pMap;
+    for(sal_uInt16 i = 0; i < nArrLen; i++)
+        pAnyArr[i] = 0;
+
+}
+/* -----------------22.06.98 09:51-------------------
+ *
+ * --------------------------------------------------*/
+SwTableProperties_Impl::~SwTableProperties_Impl()
+{
+    for(sal_uInt16 i = 0; i < nArrLen; i++)
+        delete pAnyArr[i];
+}
+/* -----------------22.06.98 09:51-------------------
+ *
+ * --------------------------------------------------*/
+sal_Bool SwTableProperties_Impl::SetProperty(const char* pName, uno::Any aVal)
+{
+    sal_uInt16 nPos = 0;
+    const SfxItemPropertyMap* pTemp = _pMap;
+    String aName(C2S(pName));
+    while( pTemp->pName )
+    {
+        if( aName.EqualsAscii(pTemp->pName))
+            break;
+        ++nPos;
+        ++pTemp;
+    }
+    if(nPos < nArrLen)
+    {
+        delete pAnyArr[nPos];
+        pAnyArr[nPos] = new uno::Any(aVal);
+    }
+    return nPos < nArrLen;
+}
+/* -----------------22.06.98 09:51-------------------
+ *
+ * --------------------------------------------------*/
+sal_Bool SwTableProperties_Impl::GetProperty(const char* pName, uno::Any*& rpAny )
+{
+    sal_uInt16 nPos = 0;
+    const SfxItemPropertyMap* pTemp = _pMap;
+    String aName(C2S(pName));
+    while( pTemp->pName )
+    {
+        if(aName.EqualsAscii(pTemp->pName))
+            break;
+        ++nPos;
+        ++pTemp;
+    }
+    if(nPos < nArrLen)
+        rpAny = pAnyArr[nPos];
+    return rpAny && nPos < nArrLen;
+}
+/* -----------------13.01.99 15:42-------------------
+ *
+ * --------------------------------------------------*/
+void    SwTableProperties_Impl::ApplyTblAttr(const SwTable& rTbl, SwDoc& rDoc)
+{
+    SfxItemSet aSet(rDoc.GetAttrPool(),
+        RES_LAYOUT_SPLIT,   RES_LAYOUT_SPLIT,
+        RES_BACKGROUND,     RES_BACKGROUND,
+        RES_FRM_SIZE,       RES_UL_SPACE,
+        RES_HORI_ORIENT,    RES_HORI_ORIENT,
+        RES_BREAK,          RES_BREAK,
+        RES_KEEP,           RES_KEEP,
+        RES_SHADOW,         RES_SHADOW,
+        RES_PAGEDESC,       RES_PAGEDESC,
+        0
+        );
+    uno::Any* pRepHead;
+    if(GetProperty(UNO_NAME_REPEAT_HEADLINE, pRepHead ))
+    {
+        sal_Bool bVal = *(sal_Bool*)pRepHead->getValue();
+        ((SwTable&)rTbl).SetHeadlineRepeat(bVal);
+    }
+
+    uno::Any* pBackColor    = 0;
+    GetProperty(UNO_NAME_BACK_COLOR, pBackColor );
+    uno::Any* pBackTrans    = 0;
+    GetProperty(UNO_NAME_TRANSPARENT_BACKGROUND, pBackTrans );
+    uno::Any* pGrLoc        = 0;
+    GetProperty(UNO_NAME_GRAPHIC_LOCATION, pGrLoc   );
+    uno::Any* pGrURL        = 0;
+    GetProperty(UNO_NAME_GRAPHIC_URL, pGrURL     );
+    uno::Any* pGrFilter     = 0;
+    GetProperty(UNO_NAME_GRAPHIC_FILTER, pGrFilter     );
+
+    if(pBackColor||pBackTrans||pGrURL||pGrFilter||pGrLoc)
+    {
+        SvxBrushItem aBrush(RES_BACKGROUND);
+        if(pBackColor)
+            aBrush.PutValue(*pBackColor, MID_BACK_COLOR);
+        if(pBackTrans)
+            aBrush.PutValue(*pBackTrans, MID_GRAPHIC_TRANSPARENT);
+        if(pGrURL)
+            aBrush.PutValue(*pGrURL, MID_GRAPHIC_URL);
+        if(pGrFilter)
+            aBrush.PutValue(*pGrFilter, MID_GRAPHIC_FILTER);
+        if(pGrLoc)
+            aBrush.PutValue(*pGrLoc, MID_GRAPHIC_POSITION);
+        aSet.Put(aBrush);
+    }
+
+    sal_Bool bPutBreak = sal_True;
+    uno::Any* pPage;
+    if(GetProperty(UNO_NAME_PAGE_STYLE_NAME, pPage))
+    {
+        OUString uTmp;
+        (*pPage) >>= uTmp;
+        String sPageStyle = uTmp;
+        const SwPageDesc* pDesc = 0;
+        if(sPageStyle.Len())
+        {
+            sPageStyle = SwXStyleFamilies::GetUIName(sPageStyle, SFX_STYLE_FAMILY_PAGE);
+            const SwPageDesc* pDesc = ::GetPageDescByName_Impl(rDoc, sPageStyle);
+            if(pDesc)
+            {
+                SwFmtPageDesc aDesc( pDesc );
+                uno::Any* pPgNo;
+                if(GetProperty(UNO_NAME_PAGE_NUMBER_OFFSET, pPgNo ))
+                {
+                    INT16 nTmp;
+                    (*pPgNo) >>= nTmp;
+                    aDesc.SetNumOffset( nTmp );
+                }
+                aSet.Put(aDesc);
+                bPutBreak = sal_False;
+            }
+
+        }
+    }
+    uno::Any* pBreak;
+    if(bPutBreak && GetProperty(UNO_NAME_BREAK_TYPE, pBreak))
+    {
+        SvxFmtBreakItem aBreak;
+        aBreak.PutValue(*pBreak, 0);
+        aSet.Put(aBreak);
+    }
+    uno::Any* pShadow;
+    if(GetProperty(UNO_NAME_SHADOW_FORMAT, pShadow))
+    {
+        SvxShadowItem aShd(RES_SHADOW);
+        aShd.PutValue(*pShadow, CONVERT_TWIPS);
+        aSet.Put(aShd);
+    }
+    uno::Any* pKeep;
+    if(GetProperty(UNO_NAME_KEEP_TOGETHER, pKeep))
+    {
+        SvxFmtKeepItem aKeep(RES_KEEP);
+        aKeep.PutValue(*pKeep, 0);
+        aSet.Put(aKeep);
+    }
+
+    sal_Bool bFullAlign = sal_True;
+    uno::Any* pHOrient;
+    if(GetProperty(UNO_NAME_HORI_ORIENT, pHOrient))
+    {
+        SwFmtHoriOrient aOrient;
+        ((SfxPoolItem&)aOrient).PutValue(*pHOrient, MID_HORIORIENT_ORIENT|CONVERT_TWIPS);
+        bFullAlign = (aOrient.GetHoriOrient() == HORI_FULL);
+        aSet.Put(aOrient);
+    }
+
+
+    uno::Any* pSzRel        = 0;
+    GetProperty(UNO_NAME_SIZE_RELATIVE, pSzRel  );
+    uno::Any* pRelWidth     = 0;
+    GetProperty(UNO_NAME_RELATIVE_WIDTH, pRelWidth);
+    uno::Any* pWidth        = 0;
+    GetProperty(UNO_NAME_WIDTH, pWidth  );
+
+    sal_Bool bPutSize = pWidth != 0;
+    SwFmtFrmSize aSz( ATT_VAR_SIZE);
+    if(pWidth)
+    {
+        ((SfxPoolItem&)aSz).PutValue(*pWidth, MID_FRMSIZE_WIDTH);
+        bPutSize = sal_True;
+    }
+    sal_Bool bTemp = pSzRel ? *(sal_Bool*)pSzRel->getValue() : FALSE;
+    if(pSzRel && bTemp && pRelWidth)
+    {
+        ((SfxPoolItem&)aSz).PutValue(*pRelWidth, MID_FRMSIZE_REL_WIDTH|CONVERT_TWIPS);
+        bPutSize = sal_True;
+    }
+    if(bPutSize)
+    {
+        if(!aSz.GetWidth())
+            aSz.SetWidth(MINLAY);
+        aSet.Put(aSz);
+    }
+    uno::Any* pL        = 0;
+    GetProperty(UNO_NAME_LEFT_MARGIN, pL);
+    uno::Any* pR        = 0;
+    GetProperty(UNO_NAME_RIGHT_MARGIN, pR);
+    if(pL||pR)
+    {
+        SvxLRSpaceItem aLR(RES_LR_SPACE);
+        if(pL)
+            ((SfxPoolItem&)aLR).PutValue(*pL, MID_L_MARGIN|CONVERT_TWIPS);
+        if(pR)
+            ((SfxPoolItem&)aLR).PutValue(*pR, MID_R_MARGIN|CONVERT_TWIPS);
+        aSet.Put(aLR);
+    }
+    uno::Any* pU        = 0;
+    GetProperty(UNO_NAME_TOP_MARGIN, pU);
+    uno::Any* pLo   = 0;
+    GetProperty(UNO_NAME_BOTTOM_MARGIN, pLo);
+    if(pU||pLo)
+    {
+        SvxULSpaceItem aUL(RES_UL_SPACE);
+        if(pU)
+            ((SfxPoolItem&)aUL).PutValue(*pU, MID_UP_MARGIN|CONVERT_TWIPS);
+        if(pLo)
+            ((SfxPoolItem&)aUL).PutValue(*pLo, MID_LO_MARGIN|CONVERT_TWIPS);
+        aSet.Put(aUL);
+    }
+    uno::Any* pSplit;
+    if(GetProperty(UNO_NAME_SPLIT, pSplit ))
+    {
+        sal_Bool bTemp = *(sal_Bool*)pSplit->getValue();
+        SwFmtLayoutSplit aSp(bTemp);
+        aSet.Put(aSp);
+    }
+
+    //TODO: folgende Propertiers noch impl.
+//  FN_UNO_RANGE_ROW_LABEL
+//  FN_UNO_RANGE_COL_LABEL
+//  FN_UNO_TABLE_BORDER
+
+    if(aSet.Count())
+    {
+        rDoc.SetAttr( aSet, *rTbl.GetFrmFmt() );
+    }
+}
+/* -----------------------------11.07.00 12:14--------------------------------
+
+ ---------------------------------------------------------------------------*/
+SwXTextTable* SwXTextTable::GetImplementation(Reference< XInterface> xRef )
+{
+    uno::Reference xTunnel( xRef, uno::UNO_QUERY);
+    if(xTunnel.is())
+        return (SwXTextTable*)xTunnel->getSomething(SwXTextTable::getUnoTunnelId());
+    return 0;
+}
+/* -----------------------------10.03.00 18:02--------------------------------
+
+ ---------------------------------------------------------------------------*/
+const uno::Sequence< sal_Int8 > & SwXTextTable::getUnoTunnelId()
+{
+    static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId();
+    return aSeq;
+}
+/* -----------------------------10.03.00 18:04--------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Int64 SAL_CALL SwXTextTable::getSomething( const uno::Sequence< sal_Int8 >& rId )
+    throw(uno::RuntimeException)
+{
+    if( rId.getLength() == 16
+        && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+                                        rId.getConstArray(), 16 ) )
+    {
+            return (sal_Int64)this;
+    }
+    return 0;
+}
+/*-- 11.12.98 12:42:43---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+TYPEINIT1(SwXTextTable, SwClient)
+
+/*-- 11.12.98 12:42:43---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextTable::SwXTextTable() :
+    aPropSet(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_TABLE)),
+    aLstnrCntnr( (XTextTable*)this),
+    bFirstRowAsLabel(sal_False),
+    bFirstColumnAsLabel(sal_False),
+    pLastSortOptions(0),
+    _pMap(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_TABLE)),
+    bIsDescriptor(sal_True),
+    nRows(2),
+    nColumns(2),
+    pTableProps(new SwTableProperties_Impl(GetTableDescPropertyMap()))
+{
+
+}
+/*-- 11.12.98 12:42:44---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextTable::SwXTextTable(SwFrmFmt& rFrmFmt) :
+    SwClient( &rFrmFmt ),
+    aLstnrCntnr( (XTextTable*)this),
+    bFirstRowAsLabel(sal_False),
+    bFirstColumnAsLabel(sal_False),
+    aPropSet(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_TABLE)),
+    pLastSortOptions(0),
+    _pMap(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_TABLE)),
+    bIsDescriptor(sal_False),
+    nRows(0),
+    nColumns(0),
+    pTableProps(0)
+{
+
+}
+/*-- 11.12.98 12:42:44---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTextTable::~SwXTextTable()
+{
+    delete pLastSortOptions;
+    delete pTableProps;
+}
+/*-- 11.12.98 12:42:44---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextTable::initialize(sal_Int32 nR, sal_Int32 nC) throw( uno::RuntimeException )
+{
+    if(!bIsDescriptor || nR <= 0 || nC <= 0 || nR >= USHRT_MAX || nC >= USHRT_MAX )
+        throw uno::RuntimeException();
+    else
+    {
+        nRows = nR;
+        nColumns = nC;
+    }
+}
+/*-- 11.12.98 12:42:45---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< table::XTableRows >  SwXTextTable::getRows(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< table::XTableRows >  xRet;
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt)
+        xRet = new SwXTableRows(*pFmt);
+    else
+        throw uno::RuntimeException();
+    return xRet;
+}
+/*-- 11.12.98 12:42:45---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< table::XTableColumns >  SwXTextTable::getColumns(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< table::XTableColumns >  xRet;
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt)
+        xRet = new SwXTableColumns(*pFmt);
+    else
+        throw uno::RuntimeException();
+    return xRet;
+}
+/*-- 11.12.98 12:42:45---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< table::XCell >  SwXTextTable::getCellByName(const OUString& CellName) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< table::XCell >  xRet;
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt)
+    {
+        SwTable* pTable = SwTable::FindTable( pFmt );
+        String sCellName(CellName);
+        SwTableBox* pBox = (SwTableBox*)pTable->GetTblBox( sCellName );
+        if(pBox)
+        {
+            xRet = SwXCell::CreateXCell(pFmt, pBox, &sCellName);
+        }
+    }
+    else
+        throw uno::RuntimeException();
+    return xRet;
+}
+/*-- 11.12.98 12:42:45---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Sequence< OUString > SwXTextTable::getCellNames(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt)
+    {
+        SwTable* pTable = SwTable::FindTable( pFmt );
+          // gibts an der Tabelle und an allen Boxen
+        SwTableLines& rTblLines = pTable->GetTabLines();
+        SvStrings aAllNames;
+        lcl_InspectLines(rTblLines, aAllNames);
+        uno::Sequence< OUString > aRet(aAllNames.Count());
+        OUString* pArray = aRet.getArray();
+        for(sal_uInt16 i = aAllNames.Count(); i; i--)
+        {
+            String* pObject = aAllNames.GetObject(i-1);
+            pArray[i - 1] = *pObject;
+            aAllNames.Remove(i - 1);
+            delete pObject;
+        }
+        return aRet;
+    }
+    return uno::Sequence< OUString >();
+}
+/*-- 11.12.98 12:42:45---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XTextTableCursor >  SwXTextTable::createCursorByCellName(const OUString& CellName)
+    throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< XTextTableCursor >  xRet;
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt)
+    {
+        SwTable* pTable = SwTable::FindTable( pFmt );
+        String sCellName(CellName);
+        SwTableBox* pBox = (SwTableBox*)pTable->GetTblBox( sCellName );
+        if(pBox)
+        {
+            xRet = new SwXTextTableCursor(pFmt, pBox);
+        }
+    }
+    if(!xRet.is())
+        throw uno::RuntimeException();
+    return xRet;
+}
+/* -----------------18.02.99 13:36-------------------
+ *
+ * --------------------------------------------------*/
+void SwXTextTable::attachToRange(const uno::Reference< XTextRange > & xTextRange)
+    throw( IllegalArgumentException, uno::RuntimeException )
+{
+    uno::Reference xRangeTunnel( xTextRange, uno::UNO_QUERY);
+    SwXTextRange* pRange = 0;
+    SwXTextCursor* pCursor = 0;
+    if(xRangeTunnel.is())
+    {
+        pRange = (SwXTextRange*)xRangeTunnel->getSomething(
+                                SwXTextRange::getUnoTunnelId());
+        pCursor = (SwXTextCursor*)xRangeTunnel->getSomething(
+                                SwXTextCursor::getUnoTunnelId());
+    }
+    SwDoc* pDoc = pRange ? (SwDoc*)pRange->GetDoc() : pCursor ? (SwDoc*)pCursor->GetDoc() : 0;
+    if(pDoc && nRows && nColumns)
+    {
+        SwUnoInternalPaM aPam(*pDoc);
+        //das muss jetzt sal_True liefern
+        SwXTextRange::XTextRangeToSwPaM(aPam, xTextRange);
+        //keine Tabellen in Tabellen!
+        if(!aPam.GetNode()->FindTableNode())
+        {
+            UnoActionContext aCont( pDoc );
+
+            pDoc->StartUndo();
+            const SwTable *pTable = 0;
+            if( 0 != aPam.Start()->nContent.GetIndex() )
+            {
+                pDoc->SplitNode(*aPam.Start() );
+            }
+            //TODO: wenn es der letzte Absatz ist, dann muss noch ein Absatz angehaengt werden!
+            pDoc->DeleteAndJoin(aPam);
+            aPam.DeleteMark();
+            pTable = pDoc->InsertTable(
+                                        *aPam.GetPoint(),
+                                        nRows,
+                                        nColumns,
+                                        HORI_FULL,
+                                        HEADLINE|DEFAULT_BORDER);
+            if(pTable)
+            {
+                // hier muessen die Properties des Descriptors ausgewertet werden
+                pTableProps->ApplyTblAttr(*pTable, *pDoc);
+                SwFrmFmt* pTblFmt = pTable->GetFrmFmt();
+                SwClientIter aIter( *pTblFmt );
+                for( SwClient* pC = aIter.First( TYPE( SwFrm ));
+                        pC; pC = aIter.Next() )
+                {
+                    if( ((SwFrm*)pC)->IsTabFrm() )
+                    {
+                        if(((SwFrm*)pC)->IsValid())
+                            ((SwFrm*)pC)->InvalidatePos();
+                        ((SwTabFrm*)pC)->SetONECalcLowers();
+                        ((SwTabFrm*)pC)->Calc();
+                    }
+                }
+
+                pTblFmt->Add(this);
+                if(m_sTableName.Len())
+                {
+                    sal_uInt16 nIndex = 1;
+                    const String sTmpName(m_sTableName);
+                    String sTmpNameIndex(sTmpName);
+                    while(pDoc->FindTblFmtByName( sTmpNameIndex, sal_True ) && nIndex < USHRT_MAX)
+                    {
+                        sTmpNameIndex = sTmpName;
+                        sTmpNameIndex += nIndex++;
+                    }
+                    pDoc->SetTableName( *pTblFmt, sTmpNameIndex);
+                }
+
+                uno::Any* pName;
+                if(pTableProps->GetProperty(UNO_NAME_TABLE_NAME, pName))
+                {
+                    OUString sTmp;
+                    (*pName) >>= sTmp;
+                    setName(sTmp);
+                }
+                bIsDescriptor = sal_False;
+                DELETEZ(pTableProps);
+            }
+            pDoc->EndUndo( UNDO_END );
+        }
+    }
+    else
+        throw IllegalArgumentException();
+}
+/*-- 11.12.98 12:42:45---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextTable::attach(const uno::Reference< XTextRange > & xTextRange)
+        throw( IllegalArgumentException, uno::RuntimeException )
+{
+}
+/*-- 11.12.98 12:42:46---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XTextRange >  SwXTextTable::getAnchor(void)
+        throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(!pFmt)
+        throw uno::RuntimeException();
+    uno::Reference< XTextRange >  xRet = new SwXTextRange(*pFmt);
+    return xRet;
+}
+/*-- 11.12.98 12:42:46---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextTable::dispose(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt)
+    {
+        SwTable* pTable = SwTable::FindTable( pFmt );
+        SwTableSortBoxes& rBoxes = pTable->GetTabSortBoxes();
+        SwSelBoxes aSelBoxes;
+        aSelBoxes.Insert(rBoxes.GetData(), rBoxes.Count());
+        pFmt->GetDoc()->DeleteRowCol(aSelBoxes);
+    }
+    else
+        throw uno::RuntimeException();
+}
+/*-- 11.12.98 12:42:46---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextTable::addEventListener(const uno::Reference< XEventListener > & aListener) throw( uno::RuntimeException )
+{
+    if(!GetRegisteredIn())
+        throw uno::RuntimeException();
+    aLstnrCntnr.AddListener(aListener);
+}
+/*-- 11.12.98 12:42:46---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextTable::removeEventListener(const uno::Reference< XEventListener > & aListener) throw( uno::RuntimeException )
+{
+    if(!GetRegisteredIn() || !aLstnrCntnr.RemoveListener(aListener))
+        throw uno::RuntimeException();
+}
+/*-- 11.12.98 12:42:46---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< table::XCell >  SwXTextTable::getCellByPosition(sal_Int32 nColumn, sal_Int32 nRow)
+    throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< table::XCell >  aRef;
+    SwFrmFmt* pFmt = GetFrmFmt();
+    // Sheet interessiert nicht
+    if(nColumn >= 0 && nRow >= 0 && nColumn < USHRT_MAX && nRow < USHRT_MAX && pFmt)
+    {
+        SwXCell* pXCell = lcl_CreateXCell(pFmt,
+                        (sal_uInt16)nColumn, (sal_uInt16)nRow);
+        if(pXCell)
+            aRef = pXCell;
+    }
+    if(!aRef.is())
+        throw uno::RuntimeException();
+    return aRef;
+
+}
+/* -----------------11.12.98 13:26-------------------
+ *
+ * --------------------------------------------------*/
+uno::Reference< table::XCellRange >  SwXTextTable::GetRangeByName(SwFrmFmt* pFmt, SwTable* pTable,
+                    const String& sTLName, const String& sBRName,
+                    SwRangeDescriptor& rDesc)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< table::XCellRange >  aRef;
+    const SwTableBox* pTLBox = pTable->GetTblBox( sTLName );
+    if(pTLBox)
+    {
+        // hier muessen die Actions aufgehoben werden
+        UnoActionRemoveContext aRemoveContext(pFmt->GetDoc());
+        const SwStartNode* pSttNd = pTLBox->GetSttNd();
+        SwPosition aPos(*pSttNd);
+        // Cursor in die obere linke Zelle des Ranges setzen
+        SwUnoCrsr* pUnoCrsr = pFmt->GetDoc()->CreateUnoCrsr(aPos, sal_True);
+        pUnoCrsr->Move( fnMoveForward, fnGoNode );
+        pUnoCrsr->SetRemainInSection( sal_False );
+        const SwTableBox* pBRBox = pTable->GetTblBox( sBRName );
+        if(pBRBox)
+        {
+            pUnoCrsr->SetMark();
+            pUnoCrsr->GetPoint()->nNode = *pBRBox->GetSttNd();
+            pUnoCrsr->Move( fnMoveForward, fnGoNode );
+            SwUnoTableCrsr* pCrsr = *pUnoCrsr;
+            pCrsr->MakeBoxSels();
+            // pUnoCrsr wird uebergeben und nicht geloescht
+            SwXCellRange* pCellRange = new SwXCellRange(pUnoCrsr, *pFmt, rDesc);
+            aRef = pCellRange;
+        }
+        else
+            delete pUnoCrsr;
+    }
+    return aRef;
+}
+/*-- 11.12.98 12:42:46---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< table::XCellRange >  SwXTextTable::getCellRangeByPosition(sal_Int32 nLeft, sal_Int32 nTop,
+                sal_Int32 nRight, sal_Int32 nBottom)
+                throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< table::XCellRange >  aRef;
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt && nRight < USHRT_MAX && nBottom < USHRT_MAX &&
+        nLeft <= nRight && nTop <= nBottom &&
+            nLeft >= 0 && nRight >= 0 && nTop >= 0 && nBottom >= 0 )
+    {
+        SwTable* pTable = SwTable::FindTable( pFmt );
+        if(!pTable->IsTblComplex())
+        {
+            SwRangeDescriptor aDesc;
+            aDesc.nTop    = nTop;
+            aDesc.nBottom = nBottom;
+            aDesc.nLeft   = nLeft;
+            aDesc.nRight  = nRight;
+            String sTLName = lcl_GetCellName(aDesc.nLeft, aDesc.nTop);
+            String sBRName = lcl_GetCellName(aDesc.nRight, aDesc.nBottom);
+            aRef = GetRangeByName(pFmt, pTable, sTLName, sBRName, aDesc);
+        }
+    }
+    if(!aRef.is())
+        throw uno::RuntimeException();
+    return aRef;
+}
+/*-- 11.12.98 12:42:47---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< table::XCellRange >  SwXTextTable::getCellRangeByName(const OUString& aRange)
+    throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< table::XCellRange >  aRef;
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt)
+    {
+        SwTable* pTable = SwTable::FindTable( pFmt );
+        if(!pTable->IsTblComplex())
+        {
+            String sRange(aRange);
+            String sTLName(sRange.GetToken(0, ':'));
+            String sBRName(sRange.GetToken(1, ':'));
+            if(!sTLName.Len() || !sBRName.Len())
+                throw uno::RuntimeException();
+            SwRangeDescriptor aDesc;
+            aDesc.nTop = aDesc.nLeft =  aDesc.nBottom = aDesc.nRight = -1;
+            lcl_GetRowCol(sTLName, aDesc.nTop, aDesc.nLeft);
+            lcl_GetRowCol(sBRName, aDesc.nBottom, aDesc.nRight);
+            aRef = GetRangeByName(pFmt, pTable, sTLName, sBRName, aDesc);
+        }
+    }
+    if(!aRef.is())
+        throw uno::RuntimeException();
+    return aRef;
+}
+/*-- 11.12.98 12:42:47---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Sequence< uno::Sequence< double > > SwXTextTable::getData(void)
+                                        throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Int16 nRowCount = getRowCount();
+    sal_Int16 nColCount = getColumnCount();
+    //werden hier uno::Sequence > aColSeq(bFirstColumnAsLabel ? nColCount - 1 : nColCount);
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt)
+    {
+        uno::Sequence< double >* pColArray = aColSeq.getArray();
+
+        sal_uInt16 nColStart = bFirstColumnAsLabel ? 1 : 0;
+        for(sal_uInt16 nCol = nColStart; nCol < nColCount; nCol++)
+        {
+            uno::Sequence< double > aRowSeq(bFirstRowAsLabel ? nRowCount - 1 : nRowCount);
+            double * pArray = aRowSeq.getArray();
+            sal_uInt16 nRowStart = bFirstRowAsLabel ? 1 : 0;
+            for(sal_uInt16 nRow = nRowStart; nRow < nRowCount; nRow++)
+            {
+                uno::Reference< table::XCell >  xCell = getCellByPosition(nCol, nRow);
+                if(!xCell.is())
+                {
+                    throw uno::RuntimeException();
+                }
+                pArray[nRow - nRowStart] = xCell->getValue();
+            }
+            pColArray[nCol - nColStart] = aRowSeq;
+        }
+    }
+    else
+        throw uno::RuntimeException();
+    return aColSeq;
+}
+/*-- 11.12.98 12:42:47---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextTable::setData(const uno::Sequence< uno::Sequence< double > >& rData)
+                                        throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Int16 nRowCount = getRowCount();
+    sal_Int16 nColCount = getColumnCount();
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt )
+    {
+        sal_uInt16 nColStart = bFirstColumnAsLabel ? 1 : 0;
+        if(rData.getLength() < nColCount - nColStart)
+        {
+            throw uno::RuntimeException();
+        }
+        const uno::Sequence< double >* pColArray = rData.getConstArray();
+        for(sal_uInt16 nCol = nColStart; nCol < nColCount; nCol++)
+        {
+            const uno::Sequence< double >& rRowSeq = pColArray[nCol - nColStart];
+            sal_uInt16 nRowStart = bFirstRowAsLabel ? 1 : 0;
+            if(rRowSeq.getLength() < nRowCount - nRowStart)
+            {
+                throw uno::RuntimeException();
+            }
+            const double * pRowArray = rRowSeq.getConstArray();
+            for(sal_uInt16 nRow = nRowStart; nRow < nRowCount; nRow++)
+            {
+                uno::Reference< table::XCell >  xCell = getCellByPosition(nCol, nRow);
+                if(!xCell.is())
+                {
+                    throw uno::RuntimeException();
+                }
+                xCell->setValue(pRowArray[nRow - nRowStart]);
+            }
+        }
+    }
+}
+/*-- 11.12.98 12:42:47---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Sequence< OUString > SwXTextTable::getRowDescriptions(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Int16 nRowCount = getRowCount();
+    uno::Sequence< OUString > aRet(bFirstColumnAsLabel ? nRowCount - 1 : nRowCount);
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt)
+    {
+        OUString* pArray = aRet.getArray();
+        if(bFirstColumnAsLabel)
+        {
+            sal_uInt16 nStart = bFirstRowAsLabel ? 1 : 0;
+            for(sal_uInt16 i = nStart; i < nRowCount; i++)
+            {
+                uno::Reference< table::XCell >  xCell = getCellByPosition(0, i);
+                if(!xCell.is())
+                {
+                    //exception ...
+                    break;
+                }
+                Reference< XText >  xText(xCell, UNO_QUERY);
+                pArray[i - nStart] = xText->getString();
+            }
+        }
+        else
+        {
+            DBG_ERROR("Wo kommen die Labels her?")
+        }
+    }
+    else
+        throw uno::RuntimeException();
+    return aRet;
+}
+/*-- 11.12.98 12:42:47---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextTable::setRowDescriptions(const uno::Sequence< OUString >& rRowDesc) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt)
+    {
+        sal_Int16 nRowCount = getRowCount();
+        if(rRowDesc.getLength() < bFirstRowAsLabel ? nRowCount - 1 : nRowCount)
+        {
+            throw uno::RuntimeException();
+            return;
+        }
+        const OUString* pArray = rRowDesc.getConstArray();
+        if(bFirstColumnAsLabel)
+        {
+            sal_uInt16 nStart = bFirstRowAsLabel ? 1 : 0;
+            for(sal_uInt16 i = nStart; i < nRowCount; i++)
+            {
+                uno::Reference< table::XCell >  xCell = getCellByPosition(0, i);
+                if(!xCell.is())
+                {
+                    throw uno::RuntimeException();
+                    break;
+                }
+                uno::Reference< XText >  xText(xCell, UNO_QUERY);
+                xText->setString(pArray[i - nStart]);
+            }
+        }
+        else
+        {
+            DBG_ERROR("Wohin mit den Labels?")
+        }
+    }
+    else
+        throw uno::RuntimeException();
+}
+/*-- 11.12.98 12:42:48---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Sequence< OUString > SwXTextTable::getColumnDescriptions(void)
+                                                throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Int16 nColCount = getColumnCount();
+    uno::Sequence< OUString > aRet(bFirstRowAsLabel ? nColCount - 1 : nColCount);
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt)
+    {
+        OUString* pArray = aRet.getArray();
+        if(bFirstRowAsLabel)
+        {
+            sal_uInt16 nStart = bFirstColumnAsLabel ? 1 : 0;
+            for(sal_uInt16 i = nStart; i < nColCount; i++)
+            {
+                uno::Reference< table::XCell >  xCell = getCellByPosition(i, 0);
+                if(!xCell.is())
+                {
+                    throw uno::RuntimeException();
+                }
+                uno::Reference< XText >  xText(xCell, UNO_QUERY);
+
+                pArray[i - nStart] = xText->getString();
+            }
+        }
+        else
+        {
+            DBG_ERROR("Wo kommen die Labels her?")
+        }
+    }
+    else
+        throw uno::RuntimeException();
+    return aRet;
+}
+/*-- 11.12.98 12:42:48---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextTable::setColumnDescriptions(const uno::Sequence< OUString >& rColumnDesc) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Int16 nColCount = getColumnCount();
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt)
+    {
+        const OUString* pArray = rColumnDesc.getConstArray();
+        if(bFirstRowAsLabel && rColumnDesc.getLength() >= nColCount - bFirstColumnAsLabel ? 1 : 0)
+        {
+            sal_uInt16 nStart = bFirstColumnAsLabel ? 1 : 0;
+            for(sal_uInt16 i = nStart; i < nColCount; i++)
+            {
+                uno::Reference< table::XCell >  xCell = getCellByPosition(i, 0);
+                if(!xCell.is())
+                {
+                    throw uno::RuntimeException();
+                    break;
+                }
+                uno::Reference< XText >  xText(xCell, UNO_QUERY);
+                xText->setString(pArray[i - nStart]);
+            }
+        }
+        else
+        {
+            DBG_ERROR("Wo kommen die Labels her?")
+        }
+    }
+    else
+        throw uno::RuntimeException();
+}
+/*-- 11.12.98 12:42:48---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextTable::addChartDataChangeEventListener(const uno::Reference< chart::XChartDataChangeEventListener > & aListener) throw( uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 11.12.98 12:42:48---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextTable::removeChartDataChangeEventListener(const uno::Reference< chart::XChartDataChangeEventListener > & aListener) throw( uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/* -----------------08.03.99 15:33-------------------
+ *
+ * --------------------------------------------------*/
+sal_Bool SwXTextTable::isNotANumber(double nNumber) throw( uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+    return sal_False;
+
+}
+/* -----------------08.03.99 15:34-------------------
+ *
+ * --------------------------------------------------*/
+double SwXTextTable::getNotANumber(void) throw( uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+    return 0.;
+}
+/*-- 11.12.98 12:42:48---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Sequence< beans::PropertyValue > SwXTextTable::createSortDescriptor(void)
+    throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Sequence< beans::PropertyValue > aRet;
+    //XTextSortDescriptor noch nicht wieder definiert
+    DBG_WARNING("not implemented")
+    return aRet;
+    /*SwXTextSortDescriptor* pDesc = new SwXTextSortDescriptor(sal_True);
+    uno::Reference< XSortDescriptor >  xRet = pDesc;
+    if(!bEmpty && pLastSortOptions)
+        pDesc->SetSortOptions(*pLastSortOptions);
+    return xRet;*/
+}
+/*-- 11.12.98 12:42:49---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextTable::sort(const uno::Sequence< beans::PropertyValue >& xDescriptor)
+    throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    DBG_WARNING("not implemented")
+/*
+    SwFrmFmt* pFmt = GetFrmFmt();
+    SwXTextSortDescriptor* pDesc = (SwXTextSortDescriptor*)
+                        xDescriptor->getImplementation(::getCppuType((const SwXTextSortDescriptor*)0));
+
+    if(pFmt && pDesc && pDesc->GetSortOptions().aKeys.Count())
+    {
+        delete pLastSortOptions;
+        pLastSortOptions = new SwSortOptions(pDesc->GetSortOptions());
+        SwTable* pTable = SwTable::FindTable( pFmt );
+        SwSelBoxes aBoxes;
+        const SwTableSortBoxes& rTBoxes = pTable->GetTabSortBoxes();
+        for( sal_uInt16 n = 0; n < rTBoxes.Count(); ++n )
+        {
+            SwTableBox* pBox = rTBoxes[ n ];
+            aBoxes.Insert( pBox );
+        }
+        UnoActionContext aContext( pFmt->GetDoc() );
+        pFmt->GetDoc()->SortTbl(aBoxes, pDesc->GetSortOptions());
+    }
+
+ * */
+}
+/*-- 11.12.98 12:42:49---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextTable::autoFormat(const OUString& aName) throw( IllegalArgumentException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt)
+    {
+        SwTable* pTable = SwTable::FindTable( pFmt );
+        if(!pTable->IsTblComplex())
+        {
+
+            String sAutoFmtName(aName);
+
+            DBG_ERROR("AutoFormat: Dafuer sollte es eine autom. Aktualisierung geben!");
+
+            SwTableAutoFmtTbl aAutoFmtTbl;
+            aAutoFmtTbl.Load();
+            for( sal_uInt16 i = aAutoFmtTbl.Count(); i; )
+                if( sAutoFmtName == aAutoFmtTbl[ --i ]->GetName() )
+                {
+                    SwSelBoxes aBoxes;
+                    const SwTableSortBoxes& rTBoxes = pTable->GetTabSortBoxes();
+                    for( sal_uInt16 n = 0; n < rTBoxes.Count(); ++n )
+                    {
+                        SwTableBox* pBox = rTBoxes[ n ];
+                        aBoxes.Insert( pBox );
+                    }
+                    UnoActionContext aContext( pFmt->GetDoc() );
+                    pFmt->GetDoc()->SetTableAutoFmt( aBoxes, *aAutoFmtTbl[i] );
+                    break;
+                }
+        }
+    }
+    else
+        throw uno::RuntimeException();
+}
+/*-- 11.12.98 12:42:49---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< beans::XPropertySetInfo >  SwXTextTable::getPropertySetInfo(void) throw( uno::RuntimeException )
+{
+    static uno::Reference< beans::XPropertySetInfo >  xRef = aPropSet.getPropertySetInfo();
+    return xRef;
+}
+/*-- 11.12.98 12:42:50---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextTable::setPropertyValue(const OUString& rPropertyName,
+                                                    const uno::Any& aValue)
+        throw( beans::UnknownPropertyException, beans::PropertyVetoException,
+                IllegalArgumentException, WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(!aValue.hasValue())
+        throw IllegalArgumentException();
+    if(pFmt)
+    {
+        lcl_FormatTable(pFmt);
+        const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                                    _pMap, rPropertyName);
+        if(!pMap)
+            throw beans::UnknownPropertyException();
+        if(0xFF == pMap->nMemberId)
+        {
+            lcl_SetSpecialProperty(pFmt, pMap, aValue);
+        }
+        else
+        {
+            switch(pMap->nWID)
+            {
+                case FN_UNO_RANGE_ROW_LABEL:
+                {
+                    sal_Bool bTmp = *(sal_Bool*)aValue.getValue();
+                    if(bFirstRowAsLabel != bTmp)
+                    {
+                        DBG_ERROR("Listener am CharData-interface benachrichtigen")
+                        bFirstRowAsLabel = bTmp;
+                    }
+                }
+                break;
+                case FN_UNO_RANGE_COL_LABEL:
+                {
+                    sal_Bool bTmp = *(sal_Bool*)aValue.getValue();
+                    if(bFirstColumnAsLabel != bTmp)
+                    {
+                        DBG_ERROR("Listener am CharData-interface benachrichtigen")
+                        bFirstColumnAsLabel = bTmp;
+                    }
+                }
+                break;
+                case FN_UNO_TABLE_BORDER:
+                {
+                    const table::TableBorder* pBorder =
+                            (const table::TableBorder* )aValue.getValue();
+                    if(aValue.getValueType() == ::getCppuType((const table::TableBorder* )0)
+                        && pBorder)
+                    {
+                        SwDoc* pDoc = pFmt->GetDoc();
+                        SwClientIter aIter( *pFmt );
+                        //Tabellen ohne Layout (unsichtbare Header/Footer )
+                        if(0 != aIter.First( TYPE( SwFrm )))
+                        {
+                            SwTable* pTable = SwTable::FindTable( pFmt );
+                            SwTableLines &rLines = pTable->GetTabLines();
+
+
+                            // hier muessen die Actions aufgehoben werden
+                            UnoActionRemoveContext aRemoveContext(pDoc);
+                            SwTableBox* pTLBox = rLines[0]->GetTabBoxes()[0];
+                            const SwStartNode* pSttNd = pTLBox->GetSttNd();
+                            SwPosition aPos(*pSttNd);
+                            // Cursor in die obere linke Zelle des Ranges setzen
+                            SwUnoCrsr* pUnoCrsr = pDoc->CreateUnoCrsr(aPos, sal_True);
+                            pUnoCrsr->Move( fnMoveForward, fnGoNode );
+                            pUnoCrsr->SetRemainInSection( sal_False );
+
+                            SwTableLine* pLastLine = rLines[rLines.Count() - 1];
+                            SwTableBoxes &rBoxes = pLastLine->GetTabBoxes();
+                            const SwTableBox* pBRBox = rBoxes[rBoxes.Count() -1];
+                            pUnoCrsr->SetMark();
+                            pUnoCrsr->GetPoint()->nNode = *pBRBox->GetSttNd();
+                            pUnoCrsr->Move( fnMoveForward, fnGoNode );
+                            SwUnoTableCrsr* pCrsr = *pUnoCrsr;
+                            pCrsr->MakeBoxSels();
+
+                            SfxItemSet aSet(pDoc->GetAttrPool(),
+                                            RES_BOX, RES_BOX,
+                                            SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER,
+                                            0);
+
+                            SvxBoxItem aBox;
+                            SvxBoxInfoItem aBoxInfo;
+                            SvxBorderLine aLine;
+
+                            sal_Bool bSet = lcl_LineToSvxLine(pBorder->TopLine, aLine);
+                            aBox.SetLine(bSet ? &aLine : 0, BOX_LINE_TOP);
+                            aBoxInfo.SetValid(VALID_TOP, pBorder->IsTopLineValid);
+
+                            bSet = lcl_LineToSvxLine(pBorder->BottomLine, aLine);
+                            aBox.SetLine(bSet ? &aLine : 0, BOX_LINE_BOTTOM);
+                            aBoxInfo.SetValid(VALID_BOTTOM, pBorder->IsBottomLineValid);
+
+                            bSet = lcl_LineToSvxLine(pBorder->LeftLine, aLine);
+                            aBox.SetLine(bSet ? &aLine : 0, BOX_LINE_LEFT);
+                            aBoxInfo.SetValid(VALID_LEFT, pBorder->IsLeftLineValid);
+
+                            bSet = lcl_LineToSvxLine(pBorder->RightLine, aLine);
+                            aBox.SetLine(bSet ? &aLine : 0, BOX_LINE_RIGHT);
+                            aBoxInfo.SetValid(VALID_RIGHT, pBorder->IsRightLineValid);
+
+                            bSet = lcl_LineToSvxLine(pBorder->HorizontalLine, aLine);
+                            aBoxInfo.SetLine(bSet ? &aLine : 0, BOXINFO_LINE_HORI);
+                            aBoxInfo.SetValid(VALID_HORI, pBorder->IsHorizontalLineValid);
+
+                            bSet = lcl_LineToSvxLine(pBorder->VerticalLine, aLine);
+                            aBoxInfo.SetLine(bSet ? &aLine : 0, BOXINFO_LINE_VERT);
+                            aBoxInfo.SetValid(VALID_VERT, pBorder->IsVerticalLineValid);
+
+                            aBox.SetDistance(MM100_TO_TWIP(pBorder->Distance));
+                            aBoxInfo.SetValid(VALID_DISTANCE, pBorder->IsDistanceValid);
+
+                            aSet.Put(aBox);
+                            aSet.Put(aBoxInfo);
+
+                            pDoc->SetTabBorders(*pCrsr, aSet);
+                            delete pUnoCrsr;
+                        }
+                    }
+                }
+                break;
+                case FN_UNO_TABLE_COLUMN_SEPARATORS:
+                {
+                    UnoActionContext(pFmt->GetDoc());
+                    SwTable* pTable = SwTable::FindTable( pFmt );
+                    lcl_SetTblSeparators(aValue, pTable, pTable->GetTabLines()[0]->GetTabBoxes()[0], sal_False, pFmt->GetDoc());
+                }
+                break;
+                case FN_UNO_TABLE_COLUMN_RELATIVE_SUM:/*_readonly_*/ break;
+                default:
+                {
+                    SwAttrSet aSet(pFmt->GetAttrSet());
+                    aPropSet.setPropertyValue(rPropertyName, aValue, aSet);
+                    pFmt->GetDoc()->SetAttr(aSet, *pFmt);
+                }
+            }
+        }
+    }
+    else if(bIsDescriptor)
+    {
+        String aPropertyName(rPropertyName);
+        if(!pTableProps->SetProperty(ByteString(aPropertyName, RTL_TEXTENCODING_ASCII_US).GetBuffer(), aValue))
+            throw IllegalArgumentException();
+    }
+    else
+        throw uno::RuntimeException();
+}
+/*-- 11.12.98 12:42:51---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXTextTable::getPropertyValue(const OUString& rPropertyName) throw( beans::UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Any aRet;
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt)
+    {
+        lcl_FormatTable(pFmt);
+        const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                                    _pMap, rPropertyName);
+        if(!pMap)
+            throw beans::UnknownPropertyException();
+        if(0xFF == pMap->nMemberId)
+        {
+            aRet = lcl_GetSpecialProperty(pFmt, pMap );
+        }
+        else
+        {
+            switch(pMap->nWID)
+            {
+                case FN_UNO_RANGE_ROW_LABEL:
+                {
+                    sal_Bool bTemp = bFirstRowAsLabel;
+                    aRet.setValue(&bTemp, ::getCppuBooleanType());
+                }
+                break;
+                case FN_UNO_RANGE_COL_LABEL:
+                {
+                    sal_Bool bTemp = bFirstColumnAsLabel;
+                    aRet.setValue(&bTemp, ::getCppuBooleanType());
+                }
+                break;
+                case FN_UNO_TABLE_BORDER:
+                {
+                    SwDoc* pDoc = pFmt->GetDoc();
+                    SwClientIter aIter( *pFmt );
+                    //Tabellen ohne Layout (unsichtbare Header/Footer )
+                    if(0 != aIter.First( TYPE( SwFrm )))
+                    {
+                        SwTable* pTable = SwTable::FindTable( pFmt );
+                        SwTableLines &rLines = pTable->GetTabLines();
+
+                        // hier muessen die Actions aufgehoben werden
+                        UnoActionRemoveContext aRemoveContext(pDoc);
+                        SwTableBox* pTLBox = rLines[0]->GetTabBoxes()[0];
+                        const SwStartNode* pSttNd = pTLBox->GetSttNd();
+                        SwPosition aPos(*pSttNd);
+                        // Cursor in die obere linke Zelle des Ranges setzen
+                        SwUnoCrsr* pUnoCrsr = pDoc->CreateUnoCrsr(aPos, sal_True);
+                        pUnoCrsr->Move( fnMoveForward, fnGoNode );
+                        pUnoCrsr->SetRemainInSection( sal_False );
+
+                        SwTableLine* pLastLine = rLines[rLines.Count() - 1];
+                        SwTableBoxes &rBoxes = pLastLine->GetTabBoxes();
+                        const SwTableBox* pBRBox = rBoxes[rBoxes.Count() -1];
+                        pUnoCrsr->SetMark();
+                        pUnoCrsr->GetPoint()->nNode = *pBRBox->GetSttNd();
+                        pUnoCrsr->Move( fnMoveForward, fnGoNode );
+                        SwUnoTableCrsr* pCrsr = *pUnoCrsr;
+                        pCrsr->MakeBoxSels();
+
+                        SfxItemSet aSet(pDoc->GetAttrPool(),
+                                        RES_BOX, RES_BOX,
+                                        SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER,
+                                        0);
+                        aSet.Put(SvxBoxInfoItem());
+                        pDoc->GetTabBorders(*pCrsr, aSet);
+                        const SvxBoxInfoItem& rBoxInfoItem = (const SvxBoxInfoItem&)aSet.Get(SID_ATTR_BORDER_INNER);
+                        const SvxBoxItem& rBox = (const SvxBoxItem&)aSet.Get(RES_BOX);
+
+                         table::TableBorder aTableBorder;
+                        aTableBorder.TopLine                = lcl_SvxLineToLine(rBox.GetTop());
+                        aTableBorder.IsTopLineValid         = rBoxInfoItem.IsValid(VALID_TOP);
+                        aTableBorder.BottomLine             = lcl_SvxLineToLine(rBox.GetBottom());
+                        aTableBorder.IsBottomLineValid      = rBoxInfoItem.IsValid(VALID_BOTTOM);
+                        aTableBorder.LeftLine               = lcl_SvxLineToLine(rBox.GetLeft());
+                        aTableBorder.IsLeftLineValid        = rBoxInfoItem.IsValid(VALID_LEFT);
+                        aTableBorder.RightLine              = lcl_SvxLineToLine(rBox.GetRight());
+                        aTableBorder.IsRightLineValid       = rBoxInfoItem.IsValid(VALID_RIGHT );
+                        aTableBorder.HorizontalLine         = lcl_SvxLineToLine(rBoxInfoItem.GetHori());
+                        aTableBorder.IsHorizontalLineValid  = rBoxInfoItem.IsValid(VALID_HORI);
+                        aTableBorder.VerticalLine           = lcl_SvxLineToLine(rBoxInfoItem.GetVert());
+                        aTableBorder.IsVerticalLineValid    = rBoxInfoItem.IsValid(VALID_VERT);
+                        aTableBorder.Distance               = rBox.GetDistance();
+                        aTableBorder.IsDistanceValid        = rBoxInfoItem.IsValid(VALID_DISTANCE);
+                        aRet.setValue(&aTableBorder, ::getCppuType((const table::TableBorder*)0));
+                        delete pUnoCrsr;
+                    }
+                }
+                break;
+                case FN_UNO_TABLE_COLUMN_SEPARATORS:
+                {
+                    SwTable* pTable = SwTable::FindTable( pFmt );
+                    lcl_GetTblSeparators(aRet, pTable, pTable->GetTabLines()[0]->GetTabBoxes()[0], sal_False);
+                }
+                break;
+                case FN_UNO_TABLE_COLUMN_RELATIVE_SUM:
+                    aRet <<= (INT16) UNO_TABLE_COLUMN_SUM;
+                break;
+                case RES_ANCHOR:
+                    //AnchorType ist readonly und maybevoid und wird nicht geliefert
+                break;
+                default:
+                {
+                    const SwAttrSet& rSet = pFmt->GetAttrSet();
+                    aRet = aPropSet.getPropertyValue(rPropertyName, rSet);
+                }
+            }
+        }
+    }
+    else if(bIsDescriptor)
+    {
+        uno::Any* pAny = 0;
+        String aPropertyName(rPropertyName);
+        if(!pTableProps->GetProperty(ByteString(aPropertyName, RTL_TEXTENCODING_ASCII_US).GetBuffer(),
+                                                                                                pAny))
+            throw IllegalArgumentException();
+        else if(pAny)
+            aRet = *pAny;
+    }
+    else
+        throw uno::RuntimeException();
+    return aRet;
+}
+/*-- 11.12.98 12:42:51---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextTable::addPropertyChangeListener(const OUString& PropertyName, const uno::Reference< beans::XPropertyChangeListener > & aListener) throw( beans::UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 11.12.98 12:42:52---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextTable::removePropertyChangeListener(const OUString& PropertyName, const uno::Reference< beans::XPropertyChangeListener > & aListener) throw( beans::UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 11.12.98 12:42:58---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextTable::addVetoableChangeListener(const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener > & aListener) throw( beans::UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 11.12.98 12:42:58---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextTable::removeVetoableChangeListener(const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener > & aListener) throw( beans::UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 11.12.98 12:42:58---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+OUString SwXTextTable::getName(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    String sRet;
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(!pFmt && !bIsDescriptor)
+        throw uno::RuntimeException();
+    if(pFmt)
+    {
+        sRet = pFmt->GetName();
+    }
+    else
+        sRet = m_sTableName;
+    return sRet;
+}
+/*-- 11.12.98 12:42:59---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextTable::setName(const OUString& rName) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwFrmFmt* pFmt = GetFrmFmt();
+    String sNewTblName(rName);
+    if(!pFmt && !bIsDescriptor ||
+        !sNewTblName.Len() ||
+            STRING_NOTFOUND != sNewTblName.Search('.') ||
+                STRING_NOTFOUND != sNewTblName.Search(' ')  )
+        throw uno::RuntimeException();
+
+    if(pFmt)
+    {
+        const String aOldName( pFmt->GetName() );
+        sal_Bool bNameFound = sal_False;
+        SwFrmFmt* pTmpFmt;
+        const SwFrmFmts* pTbl = pFmt->GetDoc()->GetTblFrmFmts();
+        for( sal_uInt16 i = pTbl->Count(); i; )
+            if( !( pTmpFmt = (*pTbl)[ --i ] )->IsDefault() &&
+                pTmpFmt->GetName() == sNewTblName &&
+                            pFmt->GetDoc()->IsUsed( *pTmpFmt ))
+            {
+                bNameFound = sal_True;
+                break;
+            }
+
+        if(bNameFound)
+        {
+            throw uno::RuntimeException();
+        }
+        pFmt->SetName( sNewTblName );
+
+
+        SwStartNode *pStNd;
+        SwNodeIndex aIdx( *pFmt->GetDoc()->GetNodes().GetEndOfAutotext().StartOfSectionNode(), 1 );
+        while ( 0 != (pStNd = aIdx.GetNode().GetStartNode()) )
+        {
+            aIdx++;
+            SwNode *pNd = pFmt->GetDoc()->GetNodes()[aIdx];
+            if ( pNd->IsOLENode() &&
+                aOldName == ((SwOLENode*)pNd)->GetChartTblName() )
+            {
+                ((SwOLENode*)pNd)->SetChartTblName( sNewTblName );
+
+                SwOLEObj& rOObj = ((SwOLENode*)pNd)->GetOLEObj();
+                SchMemChart *pData = SchDLL::GetChartData( rOObj.GetOleRef() );
+                if ( pData )
+                {
+                    if ( aOldName == pData->GetMainTitle() )
+                    {
+                        pData->SetMainTitle( sNewTblName );
+//Window??
+                        SchDLL::Update( rOObj.GetOleRef(), pData, 0/*GetWin()*/ );
+                    }
+                    SwFrm *pFrm;
+                    SwClientIter aIter( *((SwOLENode*)pNd) );
+                    for( pFrm = (SwFrm*)aIter.First( TYPE(SwFrm) ); pFrm;
+                            pFrm = (SwFrm*)aIter.Next() )
+                    {
+//InvalidateWindows?
+//                        if ( pFrm->Frm().HasArea() )
+//                            ((ViewShell*)this)->InvalidateWindows( pFrm->Frm() );
+                    }
+                }
+            }
+            aIdx.Assign( *pStNd->EndOfSectionNode(), + 1 );
+        }
+        pFmt->GetDoc()->SetModified();
+    }
+    else
+        m_sTableName = sNewTblName;
+}
+/*-----------------11.02.98 09:58-------------------
+
+--------------------------------------------------*/
+sal_uInt16 SwXTextTable::getRowCount(void)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Int16 nRet = 0;
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt)
+    {
+        SwTable* pTable = SwTable::FindTable( pFmt );
+        if(!pTable->IsTblComplex())
+        {
+            nRet = pTable->GetTabLines().Count();
+        }
+    }
+    return nRet;
+}
+/*-----------------11.02.98 09:58-------------------
+
+--------------------------------------------------*/
+sal_uInt16 SwXTextTable::getColumnCount(void)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwFrmFmt* pFmt = GetFrmFmt();
+    sal_Int16 nRet = 0;
+    if(pFmt)
+    {
+        SwTable* pTable = SwTable::FindTable( pFmt );
+        if(!pTable->IsTblComplex())
+        {
+            SwTableLines& rLines = pTable->GetTabLines();
+            SwTableLine* pLine = rLines.GetObject(0);
+            nRet = pLine->GetTabBoxes().Count();
+        }
+    }
+    return nRet;
+}
+/*-- 11.12.98 12:42:59---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTextTable::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew)
+{
+    if(pOld && pOld->Which() == RES_REMOVE_UNO_OBJECT &&
+        (void*)GetRegisteredIn() == ((SwPtrMsgPoolItem *)pOld)->pObject )
+            ((SwModify*)GetRegisteredIn())->Remove(this);
+    else
+        ClientModify(this, pOld, pNew);
+    if(!GetRegisteredIn())
+        aLstnrCntnr.Disposing();
+}
+/* -----------------14.01.99 10:43-------------------
+ *
+ * --------------------------------------------------*/
+/*uno::Sequence< uno::Uik > SwXTextTable::getUiks()
+{
+    uno::Sequence< uno::Uik > aUiks(8);
+ uno::Uik* pArray = aUiks.getArray();
+    pArray[0] = ::getCppuType((const uno::Reference< XTextTable >*)0);
+    pArray[1] = ::getCppuType((const uno::Reference< beans::XPropertySet >*)0);
+    pArray[2] = ::getCppuType((const uno::Reference< container::XNamed >*)0);
+    pArray[3] = ::getCppuType((const uno::Reference< table::XCellRange >*)0);
+    pArray[4] = ::getCppuType((const uno::Reference< table::XAutoFormattable >*)0);
+    pArray[5] = ::getCppuType((const uno::Reference< util::XSortable >*)0);
+    pArray[6] = ::getCppuType((const uno::Reference< table::XAutoFormattable >*)0);
+    pArray[7] = ::getCppuType((const uno::Reference< chart::XChartData >*)0);
+    return aUiks;
+}
+/* -----------------25.10.99 15:12-------------------
+
+ --------------------------------------------------*/
+OUString SAL_CALL SwXTextTable::getImplementationName(void) throw( uno::RuntimeException )
+{
+    return C2U("SwXTextTable");
+}
+/* -----------------25.10.99 15:12-------------------
+
+ --------------------------------------------------*/
+sal_Bool SwXTextTable::supportsService(const OUString& rServiceName) throw( uno::RuntimeException )
+{
+    String sServiceName(rServiceName);
+    return (sServiceName.EqualsAscii("com.sun.star.document.LinkTarget")  ||
+                sServiceName.EqualsAscii("com.sun.star.text.TextTable")  ||
+                sServiceName.EqualsAscii("com.sun.star.text.TextContent"));
+}
+/* -----------------25.10.99 15:12-------------------
+
+ --------------------------------------------------*/
+uno::Sequence< OUString > SwXTextTable::getSupportedServiceNames(void) throw( uno::RuntimeException )
+{
+    uno::Sequence< OUString > aRet(3);
+    OUString* pArr = aRet.getArray();
+    pArr[0] = C2U("com.sun.star.text.TextTable");
+    pArr[1] = C2U("com.sun.star.document.LinkTarget");
+    pArr[2] = C2U("com.sun.star.text.TextContent");
+    return aRet;
+}
+
+/******************************************************************
+ *
+ ******************************************************************/
+/* -----------------------------10.03.00 18:02--------------------------------
+
+ ---------------------------------------------------------------------------*/
+const uno::Sequence< sal_Int8 > & SwXCellRange::getUnoTunnelId()
+{
+    static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId();
+    return aSeq;
+}
+/* -----------------------------10.03.00 18:04--------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Int64 SAL_CALL SwXCellRange::getSomething( const uno::Sequence< sal_Int8 >& rId )
+    throw(uno::RuntimeException)
+{
+    if( rId.getLength() == 16
+        && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+                                        rId.getConstArray(), 16 ) )
+    {
+            return (sal_Int64)this;
+    }
+    return 0;
+}
+/* -----------------28.04.98 10:29-------------------
+ *
+ * --------------------------------------------------*/
+TYPEINIT1(SwXCellRange, SwClient);
+/* -----------------------------19.04.00 15:21--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXCellRange::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXCellRange");
+}
+/* -----------------------------19.04.00 15:21--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXCellRange::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.table.CellRange") == rServiceName;
+}
+/* -----------------------------19.04.00 15:21--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXCellRange::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.table.CellRange");
+    return aRet;
+}
+/*-- 11.12.98 14:27:32---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXCellRange::SwXCellRange() :
+    aCursorDepend(this, 0),
+    pTblCrsr(0),
+    pLastSortOptions(0),
+    aPropSet(0),
+    bFirstRowAsLabel(sal_False),
+    bFirstColumnAsLabel(sal_False),
+    _pMap(0)
+{
+
+}
+/*-- 11.12.98 14:27:33---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXCellRange::SwXCellRange(SwUnoCrsr* pCrsr, SwFrmFmt& rFrmFmt,
+                                            SwRangeDescriptor& rDesc) :
+    SwClient(&rFrmFmt),
+    aCursorDepend(this, pCrsr),
+    aRgDesc(rDesc),
+    pTblCrsr(pCrsr),
+    aPropSet(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TABLE_RANGE)),
+    bFirstRowAsLabel(sal_False),
+    bFirstColumnAsLabel(sal_False),
+    pLastSortOptions(0),
+    _pMap(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TABLE_RANGE))
+{
+
+}
+/*-- 11.12.98 14:27:33---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXCellRange::~SwXCellRange()
+{
+    delete pLastSortOptions;
+    delete pTblCrsr;
+}
+/*-- 11.12.98 14:27:34---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< table::XCell >  SwXCellRange::getCellByPosition(sal_Int32 nColumn, sal_Int32 nRow)
+                                            throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< table::XCell >  aRet;
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt)
+    {
+        if(nColumn >= 0 && nRow >= 0 &&
+             getColumnCount() > nColumn && getRowCount() > nRow )
+        {
+            SwXCell* pXCell = lcl_CreateXCell(pFmt,
+                    aRgDesc.nLeft + nColumn, aRgDesc.nTop + nRow);
+            if(pXCell)
+                aRet = pXCell;
+        }
+    }
+    if(!aRet.is())
+        throw uno::RuntimeException();
+    return aRet;
+}
+/*-- 11.12.98 14:27:34---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< table::XCellRange >  SwXCellRange::getCellRangeByPosition(
+        sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom)
+        throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< table::XCellRange >  aRet;
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt && getColumnCount() > nRight && getRowCount() > nBottom &&
+        nLeft <= nRight && nTop <= nBottom)
+    {
+        SwTable* pTable = SwTable::FindTable( pFmt );
+        if(!pTable->IsTblComplex())
+        {
+            SwRangeDescriptor aNewDesc;
+            aNewDesc.nTop    = nTop + aRgDesc.nTop;
+            aNewDesc.nBottom = nBottom + aRgDesc.nTop;
+            aNewDesc.nLeft   = nLeft +  aRgDesc.nLeft;
+            aNewDesc.nRight  = nRight + aRgDesc.nLeft;
+            String sTLName = lcl_GetCellName(aNewDesc.nLeft, aNewDesc.nTop);
+            String sBRName = lcl_GetCellName(aNewDesc.nRight, aNewDesc.nBottom);
+            const SwTableBox* pTLBox = pTable->GetTblBox( sTLName );
+            if(pTLBox)
+            {
+                // hier muessen die Actions aufgehoben
+                UnoActionRemoveContext aRemoveContext(pFmt->GetDoc());
+                const SwStartNode* pSttNd = pTLBox->GetSttNd();
+                SwPosition aPos(*pSttNd);
+                // Cursor in die obere linke Zelle des Ranges setzen
+                SwUnoCrsr* pUnoCrsr = pFmt->GetDoc()->CreateUnoCrsr(aPos, sal_True);
+                pUnoCrsr->Move( fnMoveForward, fnGoNode );
+                pUnoCrsr->SetRemainInSection( sal_False );
+                const SwTableBox* pBRBox = pTable->GetTblBox( sBRName );
+                if(pBRBox)
+                {
+                    pUnoCrsr->SetMark();
+                    pUnoCrsr->GetPoint()->nNode = *pBRBox->GetSttNd();
+                    pUnoCrsr->Move( fnMoveForward, fnGoNode );
+                    SwUnoTableCrsr* pCrsr = *pUnoCrsr;
+                    pCrsr->MakeBoxSels();
+                    // pUnoCrsr wird uebergeben und nicht geloescht
+                    SwXCellRange* pCellRange = new SwXCellRange(pUnoCrsr, *pFmt, aNewDesc);
+                    aRet = pCellRange;
+                }
+                else
+                    delete pUnoCrsr;
+            }
+        }
+    }
+    if(!aRet.is())
+        throw uno::RuntimeException();
+    return aRet;
+
+}
+/*-- 11.12.98 14:27:34---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< table::XCellRange >  SwXCellRange::getCellRangeByName(const OUString& aRange) throw( uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+    return uno::Reference< table::XCellRange > ();
+}
+/*-- 11.12.98 14:27:35---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< beans::XPropertySetInfo >  SwXCellRange::getPropertySetInfo(void) throw( uno::RuntimeException )
+{
+    static uno::Reference< beans::XPropertySetInfo >  xRef = aPropSet.getPropertySetInfo();
+    return xRef;
+}
+/*-- 11.12.98 14:27:35---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXCellRange::setPropertyValue(const OUString& rPropertyName,
+    const uno::Any& aValue) throw( beans::UnknownPropertyException,
+        beans::PropertyVetoException, IllegalArgumentException,
+            WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt)
+    {
+        lcl_FormatTable(pFmt);
+        const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                                                    _pMap, rPropertyName);
+        if(pMap)
+        {
+            SwDoc* pDoc = pTblCrsr->GetDoc();
+            switch(pMap->nWID )
+            {
+                case FN_UNO_TABLE_CELL_BACKGROUND:
+                {
+                    SvxBrushItem aBrush;
+                    pDoc->GetBoxBackground( *pTblCrsr, aBrush );
+                    ((SfxPoolItem&)aBrush).PutValue(aValue, pMap->nMemberId);
+                    pDoc->SetBoxAttr( *pTblCrsr, aBrush );
+
+                }
+                break;
+                case RES_BOXATR_FORMAT:
+                {
+                    SwUnoTableCrsr* pCrsr = *pTblCrsr;
+                    SfxUInt32Item aNumberFormat(RES_BOXATR_FORMAT);
+                    ((SfxPoolItem&)aNumberFormat).PutValue(aValue, 0);
+                    pDoc->SetBoxAttr( *pCrsr, aNumberFormat);
+                }
+                break;
+                case FN_UNO_RANGE_ROW_LABEL:
+                {
+                    sal_Bool bTmp = *(sal_Bool*)aValue.getValue();
+                    if(bFirstRowAsLabel != bTmp)
+                    {
+                        DBG_ERROR("Listener am CharData-interface benachrichtigen")
+                        bFirstRowAsLabel = bTmp;
+                    }
+                }
+                break;
+                case FN_UNO_RANGE_COL_LABEL:
+                {
+                    sal_Bool bTmp = *(sal_Bool*)aValue.getValue();
+                    if(bFirstColumnAsLabel != bTmp)
+                    {
+                        DBG_ERROR("Listener am CharData-interface benachrichtigen")
+                        bFirstColumnAsLabel = bTmp;
+                    }
+                }
+                break;
+                case FN_UNO_PARA_STYLE:
+                    lcl_SetTxtFmtColl(aValue, *pTblCrsr);
+                break;
+                default:
+                {
+                    SfxItemSet rSet(pDoc->GetAttrPool(),
+                        RES_CHRATR_BEGIN,       RES_FRMATR_END -1,
+                        0L);
+                    SwUnoTableCrsr* pCrsr = *pTblCrsr;
+                    SwXTextCursor::GetCrsrAttr(pCrsr->GetSelRing(), rSet);
+                    aPropSet.setPropertyValue(rPropertyName, aValue, rSet);
+                    SwXTextCursor::SetCrsrAttr(pCrsr->GetSelRing(), rSet, sal_True);
+                }
+            }
+        }
+    }
+}
+/*-- 11.12.98 14:27:35---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXCellRange::getPropertyValue(const OUString& rPropertyName) throw( beans::UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Any aRet;
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt)
+    {
+        lcl_FormatTable(pFmt);
+        const SfxItemPropertyMap*   pMap = SfxItemPropertyMap::GetByName(
+                                                    _pMap, rPropertyName);
+        if(pMap)
+        {
+            switch(pMap->nWID )
+            {
+                case FN_UNO_TABLE_CELL_BACKGROUND:
+                {
+                    SvxBrushItem aBrush;
+                    if(pTblCrsr->GetDoc()->GetBoxBackground( *pTblCrsr, aBrush ))
+                        aBrush.QueryValue(aRet, pMap->nMemberId);
+
+                }
+                break;
+                case RES_BOXATR_FORMAT:
+                    //GetAttr fuer Tabellenselektion am Doc fehlt noch
+                    DBG_WARNING("not implemented")
+                break;
+                case FN_UNO_PARA_STYLE:
+                {
+                    SwFmtColl* pFmt = SwXTextCursor::GetCurTxtFmtColl(*pTblCrsr, FALSE);
+                    OUString sRet;
+                    if(pFmt)
+                        sRet = pFmt->GetName();
+                    aRet <<= sRet;
+                }
+                break;
+                case FN_UNO_RANGE_ROW_LABEL:
+                {
+                    sal_Bool bTemp = bFirstRowAsLabel;
+                    aRet.setValue(&bTemp, ::getCppuBooleanType());
+                }
+                break;
+                case FN_UNO_RANGE_COL_LABEL:
+                {
+                    sal_Bool bTemp = bFirstColumnAsLabel;
+                    aRet.setValue(&bTemp, ::getCppuBooleanType());
+                }
+                default:
+                {
+                    SfxItemSet aSet(pTblCrsr->GetDoc()->GetAttrPool(),
+                        RES_CHRATR_BEGIN,       RES_FRMATR_END -1,
+                        0L);
+                    // erstmal die Attribute des Cursors
+                    SwUnoTableCrsr* pCrsr = *pTblCrsr;
+                    SwXTextCursor::GetCrsrAttr(pCrsr->GetSelRing(), aSet);
+                    aRet = aPropSet.getPropertyValue(rPropertyName, aSet);
+                }
+            }
+        }
+    }
+    return aRet;
+}
+/*-- 11.12.98 14:27:35---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXCellRange::addPropertyChangeListener(const OUString& PropertyName, const uno::Reference< beans::XPropertyChangeListener > & aListener) throw( beans::UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 11.12.98 14:27:35---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXCellRange::removePropertyChangeListener(const OUString& PropertyName, const uno::Reference< beans::XPropertyChangeListener > & aListener) throw( beans::UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 11.12.98 14:27:36---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXCellRange::addVetoableChangeListener(const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener > & aListener) throw( beans::UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 11.12.98 14:27:36---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXCellRange::removeVetoableChangeListener(const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener > & aListener) throw( beans::UnknownPropertyException, WrappedTargetException, uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 11.12.98 14:27:36---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Sequence< uno::Sequence< double > > SwXCellRange::getData(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Int16 nRowCount = getRowCount();
+    sal_Int16 nColCount = getColumnCount();
+    //werden hier uno::Sequence > aColSeq(bFirstColumnAsLabel ? nColCount - 1 : nColCount);
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt)
+    {
+        uno::Sequence< double >* pColArray = aColSeq.getArray();
+
+        sal_uInt16 nColStart = bFirstColumnAsLabel ? 1 : 0;
+        for(sal_uInt16 nCol = nColStart; nCol < nColCount; nCol++)
+        {
+            uno::Sequence< double > aRowSeq(bFirstRowAsLabel ? nRowCount - 1 : nRowCount);
+            double * pArray = aRowSeq.getArray();
+            sal_uInt16 nRowStart = bFirstRowAsLabel ? 1 : 0;
+            for(sal_uInt16 nRow = nRowStart; nRow < nRowCount; nRow++)
+            {
+                uno::Reference< table::XCell >  xCell = getCellByPosition(nCol, nRow);
+                if(!xCell.is())
+                {
+                    //exception ...
+                    break;
+                }
+                pArray[nRow - nRowStart] = xCell->getValue();
+            }
+            pColArray[nCol - nColStart] = aRowSeq;
+        }
+    }
+    return aColSeq;
+}
+/*-- 11.12.98 14:27:37---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXCellRange::setData(const uno::Sequence< uno::Sequence< double > >& rData)
+                                                throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Int16 nRowCount = getRowCount();
+    sal_Int16 nColCount = getColumnCount();
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt )
+    {
+        sal_uInt16 nColStart = bFirstColumnAsLabel ? 1 : 0;
+        if(rData.getLength() < nColCount - nColStart)
+        {
+            throw uno::RuntimeException();
+            return;
+        }
+        const uno::Sequence< double >* pColArray = rData.getConstArray();
+        for(sal_uInt16 nCol = nColStart; nCol < nColCount; nCol++)
+        {
+            const uno::Sequence< double >& rRowSeq = pColArray[nCol - nColStart];
+            sal_uInt16 nRowStart = bFirstRowAsLabel ? 1 : 0;
+            if(rRowSeq.getLength() < nRowCount - nRowStart)
+            {
+                throw uno::RuntimeException();
+                return;
+            }
+            const double * pRowArray = rRowSeq.getConstArray();
+            for(sal_uInt16 nRow = nRowStart; nRow < nRowCount; nRow++)
+            {
+                uno::Reference< table::XCell >  xCell = getCellByPosition(nCol, nRow);
+                if(!xCell.is())
+                {
+                    throw uno::RuntimeException();
+                    break;
+                }
+                xCell->setValue(pRowArray[nRow - nRowStart]);
+            }
+        }
+    }
+}
+/*-- 11.12.98 14:27:37---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Sequence< OUString > SwXCellRange::getRowDescriptions(void)
+                                            throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Int16 nRowCount = getRowCount();
+    uno::Sequence< OUString > aRet(bFirstColumnAsLabel ? nRowCount - 1 : nRowCount);
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt)
+    {
+        OUString* pArray = aRet.getArray();
+        if(bFirstColumnAsLabel)
+        {
+            sal_uInt16 nStart = bFirstRowAsLabel ? 1 : 0;
+            for(sal_uInt16 i = nStart; i < nRowCount; i++)
+            {
+                uno::Reference< table::XCell >  xCell = getCellByPosition(0, i);
+                if(!xCell.is())
+                {
+                    throw uno::RuntimeException();
+                    break;
+                }
+                uno::Reference< XText >  xText(xCell, UNO_QUERY);
+                pArray[i - nStart] = xText->getString();
+            }
+        }
+        else
+        {
+            DBG_ERROR("Wo kommen die Labels her?")
+        }
+    }
+    else
+        throw uno::RuntimeException();
+    return aRet;
+}
+/*-- 11.12.98 14:27:37---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXCellRange::setRowDescriptions(const uno::Sequence< OUString >& rRowDesc)
+                                                    throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt)
+    {
+        sal_Int16 nRowCount = getRowCount();
+        if(rRowDesc.getLength() < bFirstRowAsLabel ? nRowCount - 1 : nRowCount)
+        {
+            throw uno::RuntimeException();
+            return;
+        }
+        const OUString* pArray = rRowDesc.getConstArray();
+        if(bFirstColumnAsLabel)
+        {
+            sal_uInt16 nStart = bFirstRowAsLabel ? 1 : 0;
+            for(sal_uInt16 i = nStart; i < nRowCount; i++)
+            {
+                uno::Reference< table::XCell >  xCell = getCellByPosition(0, i);
+                if(!xCell.is())
+                {
+                    throw uno::RuntimeException();
+                    break;
+                }
+                uno::Reference< XText >  xText(xCell, UNO_QUERY);
+                xText->setString(pArray[i - nStart]);
+            }
+        }
+        else
+        {
+            DBG_ERROR("Wohin mit den Labels?")
+        }
+    }
+}
+/*-- 11.12.98 14:27:37---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Sequence< OUString > SwXCellRange::getColumnDescriptions(void)
+                                        throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Int16 nColCount = getColumnCount();
+    uno::Sequence< OUString > aRet(bFirstRowAsLabel ? nColCount - 1 : nColCount);
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt)
+    {
+        OUString* pArray = aRet.getArray();
+        if(bFirstRowAsLabel)
+        {
+            sal_uInt16 nStart = bFirstColumnAsLabel ? 1 : 0;
+            for(sal_uInt16 i = nStart; i < nColCount; i++)
+            {
+                uno::Reference< table::XCell >  xCell = getCellByPosition(i, 0);
+                if(!xCell.is())
+                {
+                    throw uno::RuntimeException();
+                    break;
+                }
+                uno::Reference< XText >  xText(xCell, UNO_QUERY);
+                pArray[i - nStart] = xText->getString();
+            }
+        }
+        else
+        {
+            DBG_ERROR("Wo kommen die Labels her?")
+        }
+    }
+    else
+        throw uno::RuntimeException();
+    return aRet;
+}
+/*-- 11.12.98 14:27:37---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXCellRange::setColumnDescriptions(const uno::Sequence< OUString >& ColumnDesc)
+                                                        throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Int16 nColCount = getColumnCount();
+    SwFrmFmt* pFmt = GetFrmFmt();
+    if(pFmt)
+    {
+        const OUString* pArray = ColumnDesc.getConstArray();
+        if(bFirstRowAsLabel && ColumnDesc.getLength() >= nColCount - bFirstColumnAsLabel ? 1 : 0)
+        {
+            sal_uInt16 nStart = bFirstColumnAsLabel ? 1 : 0;
+            for(sal_uInt16 i = nStart; i < nColCount; i++)
+            {
+                uno::Reference< table::XCell >  xCell = getCellByPosition(i, 0);
+                if(!xCell.is())
+                {
+                    throw uno::RuntimeException();
+                    break;
+                }
+                uno::Reference< XText >  xText(xCell, UNO_QUERY);
+
+                xText->setString(pArray[i - nStart]);
+            }
+        }
+        else
+        {
+            DBG_ERROR("Wo kommen die Labels her?")
+        }
+    }
+}
+/*-- 11.12.98 14:27:38---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXCellRange::addChartDataChangeEventListener(const uno::Reference< chart::XChartDataChangeEventListener > & aListener) throw( uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/*-- 11.12.98 14:27:38---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXCellRange::removeChartDataChangeEventListener(const uno::Reference< chart::XChartDataChangeEventListener > & aListener) throw( uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+}
+/* -----------------08.03.99 15:36-------------------
+ *
+ * --------------------------------------------------*/
+sal_Bool SwXCellRange::isNotANumber(double nNumber) throw( uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+    return sal_False;
+
+}
+/* -----------------08.03.99 15:36-------------------
+ *
+ * --------------------------------------------------*/
+double SwXCellRange::getNotANumber(void) throw( uno::RuntimeException )
+{
+    DBG_WARNING("not implemented")
+    return 0.;
+}
+/*-- 11.12.98 14:27:38---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Sequence< beans::PropertyValue > SwXCellRange::createSortDescriptor(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    DBG_WARNING("not implemented")
+    uno::Sequence< beans::PropertyValue > aRet;
+    return aRet;
+    /*SwXTextSortDescriptor* pDesc = new SwXTextSortDescriptor(sal_True);
+    uno::Reference< XSortDescriptor >  xRet = pDesc;
+    if(!bEmpty && pLastSortOptions)
+        pDesc->SetSortOptions(*pLastSortOptions);
+    return xRet;*/
+}
+/*-- 11.12.98 14:27:39---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SAL_CALL SwXCellRange::sort(const uno::Sequence< beans::PropertyValue >& xDescriptor)
+    throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    DBG_WARNING("not implemented")
+    /*
+    SwFrmFmt* pFmt = GetFrmFmt();
+    SwXTextSortDescriptor* pDesc = (SwXTextSortDescriptor*)
+//                      xDescriptor->getImplementation(::getCppuType((const SwXTextSortDescriptor*)0));
+
+    if(pFmt && pDesc && pDesc->GetSortOptions().aKeys.Count())
+    {
+        delete pLastSortOptions;
+        pLastSortOptions = new SwSortOptions(pDesc->GetSortOptions());
+        SwUnoTableCrsr* pTableCrsr = *pTblCrsr;
+        pTableCrsr->MakeBoxSels();
+        UnoActionContext aContext( pFmt->GetDoc() );
+        pFmt->GetDoc()->SortTbl(pTableCrsr->GetBoxes(), pDesc->GetSortOptions());
+    }*/
+}
+/* -----------------27.04.98 16:54-------------------
+ *
+ * --------------------------------------------------*/
+sal_uInt16 SwXCellRange::getColumnCount(void)
+{
+    return aRgDesc.nRight - aRgDesc.nLeft + 1;
+}
+/* -----------------27.04.98 16:54-------------------
+ *
+ * --------------------------------------------------*/
+sal_uInt16 SwXCellRange::getRowCount(void)
+{
+    return aRgDesc.nBottom - aRgDesc.nTop + 1;
+}
+/*-- 11.12.98 14:27:39---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXCellRange::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew)
+{
+    ClientModify(this, pOld, pNew );
+    if(!aCursorDepend.GetRegisteredIn())
+        pTblCrsr = 0;
+}
+/******************************************************************
+ *  SwXTableRows
+ ******************************************************************/
+/* -----------------------------19.04.00 15:22--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXTableRows::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXTableRows");
+}
+/* -----------------------------19.04.00 15:22--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXTableRows::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.text.TableRows") == rServiceName;
+}
+/* -----------------------------19.04.00 15:22--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXTableRows::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.TableRows");
+    return aRet;
+}
+/*-- 03.02.99 07:37:41---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTableRows::SwXTableRows(SwFrmFmt& rFrmFmt) :
+    SwClient(&rFrmFmt)
+{
+}
+/*-- 03.02.99 07:37:41---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTableRows::~SwXTableRows()
+{
+}
+/*-- 03.02.99 07:37:41---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Int32 SwXTableRows::getCount(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Int32 nRet = 0;
+    SwFrmFmt* pFrmFmt = GetFrmFmt();
+    if(!pFrmFmt)
+        throw uno::RuntimeException();
+    else
+    {
+        SwTable* pTable = SwTable::FindTable( pFrmFmt );
+        nRet = pTable->GetTabLines().Count();
+    }
+    return nRet;
+}
+/*-- 03.02.99 07:37:41---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXTableRows::getByIndex(sal_Int32 nIndex)
+    throw( IndexOutOfBoundsException, WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Any aRet;
+    SwFrmFmt* pFrmFmt = GetFrmFmt();
+    if(!pFrmFmt || nIndex < 0 )
+        throw IndexOutOfBoundsException();
+    else
+    {
+        SwTable* pTable = SwTable::FindTable( pFrmFmt );
+        if(pTable->GetTabLines().Count() > nIndex)
+        {
+            SwTableLine* pLine = pTable->GetTabLines().GetObject(nIndex);
+            SwClientIter aIter( *pFrmFmt );
+            SwXTextTableRow* pXRow = (SwXTextTableRow*)aIter.
+                                    First( TYPE( SwXTextTableRow ));
+            while( pXRow )
+            {
+                // gibt es eine passende Zelle bereits?
+                if(pXRow->GetTblRow() == pLine)
+                    break;
+                pXRow = (SwXTextTableRow*)aIter.Next();
+            }
+            //sonst anlegen
+            if(!pXRow)
+                pXRow = new SwXTextTableRow(pFrmFmt, pLine);
+            uno::Reference< beans::XPropertySet >  xRet =
+                                    (beans::XPropertySet*)pXRow;
+            aRet.setValue(&xRet, ::getCppuType((const uno::Reference*)0));
+        }
+        else
+            throw IndexOutOfBoundsException();
+    }
+    return aRet;
+}
+/*-- 03.02.99 07:37:42---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Type SAL_CALL SwXTableRows::getElementType(void) throw( uno::RuntimeException )
+{
+    return ::getCppuType((const uno::Reference*)0);
+}
+/*-- 03.02.99 07:37:42---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTableRows::hasElements(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwFrmFmt* pFrmFmt = GetFrmFmt();
+    if(!pFrmFmt)
+        throw uno::RuntimeException();
+    //es gibt keine Tabelle ohne Zeilen
+    return sal_True;
+}
+/*-- 03.02.99 07:37:42---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTableRows::insertByIndex(sal_Int32 nIndex, sal_Int32 nCount) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwFrmFmt* pFrmFmt = GetFrmFmt();
+    if(!pFrmFmt || nIndex < 0 || nCount <= 0)
+        throw uno::RuntimeException();
+    else
+    {
+        SwTable* pTable = SwTable::FindTable( pFrmFmt );
+        if(!pTable->IsTblComplex())
+        {
+            String sTLName = lcl_GetCellName(0, nIndex);
+            const SwTableBox* pTLBox = pTable->GetTblBox( sTLName );
+            sal_Bool bAppend = sal_False;
+            if(!pTLBox)
+            {
+                bAppend = sal_True;
+                // am Ende anfuegen, dazu muss der Cursor in die letzte Zeile!
+                SwTableLines& rLines = pTable->GetTabLines();
+                SwTableLine* pLine = rLines.GetObject(rLines.Count() -1);
+                SwTableBoxes& rBoxes = pLine->GetTabBoxes();
+                pTLBox = rBoxes.GetObject(0);
+            }
+            if(pTLBox)
+            {
+                const SwStartNode* pSttNd = pTLBox->GetSttNd();
+                SwPosition aPos(*pSttNd);
+                // Cursor in die obere linke Zelle des Ranges setzen
+                UnoActionContext aAction(pFrmFmt->GetDoc());
+                SwUnoCrsr* pUnoCrsr = pFrmFmt->GetDoc()->CreateUnoCrsr(aPos, sal_True);
+                pUnoCrsr->Move( fnMoveForward, fnGoNode );
+                pFrmFmt->GetDoc()->InsertRow(*pUnoCrsr, nCount, bAppend);
+                delete pUnoCrsr;
+            }
+        }
+    }
+}
+/*-- 03.02.99 07:37:43---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTableRows::removeByIndex(sal_Int32 nIndex, sal_Int32 nCount) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwFrmFmt* pFrmFmt = GetFrmFmt();
+    if(!pFrmFmt || nIndex < 0 || nCount <=0 )
+        throw uno::RuntimeException();
+    else
+    {
+        SwTable* pTable = SwTable::FindTable( pFrmFmt );
+        if(!pTable->IsTblComplex())
+        {
+            String sTLName = lcl_GetCellName(0, nIndex);
+            const SwTableBox* pTLBox = pTable->GetTblBox( sTLName );
+            if(pTLBox)
+            {
+                const SwStartNode* pSttNd = pTLBox->GetSttNd();
+                SwPosition aPos(*pSttNd);
+                SwUnoCrsr* pUnoCrsr = pFrmFmt->GetDoc()->CreateUnoCrsr(aPos, sal_True);
+                pUnoCrsr->Move( fnMoveForward, fnGoNode );
+                {
+                    // Die Klammer ist wichtig!
+                    UnoActionContext aAction(pFrmFmt->GetDoc());
+                    pFrmFmt->GetDoc()->DeleteRow(*pUnoCrsr);
+                    delete pUnoCrsr;
+                }
+                // hier muessen die Actions aufgehoben werden
+                UnoActionRemoveContext aRemoveContext(pFrmFmt->GetDoc());
+            }
+        }
+    }
+}
+/*-- 03.02.99 07:37:43---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTableRows::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew)
+{
+    ClientModify(this, pOld, pNew);
+}
+
+/******************************************************************
+ * SwXTableColumns
+ ******************************************************************/
+/* -----------------------------19.04.00 15:23--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXTableColumns::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXTableColumns");
+}
+/* -----------------------------19.04.00 15:23--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXTableColumns::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.text.TableColumns") == rServiceName;
+}
+/* -----------------------------19.04.00 15:23--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXTableColumns::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.TableColumns");
+    return aRet;
+}
+/*-- 03.02.99 07:37:41---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTableColumns::SwXTableColumns(SwFrmFmt& rFrmFmt) :
+    SwClient(&rFrmFmt)
+{
+}
+/*-- 03.02.99 07:37:41---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXTableColumns::~SwXTableColumns()
+{
+}
+/*-- 03.02.99 07:37:41---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Int32 SwXTableColumns::getCount(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    sal_Int32 nRet = 0;
+    SwFrmFmt* pFrmFmt = GetFrmFmt();
+    if(!pFrmFmt)
+        throw uno::RuntimeException();
+    else
+    {
+        SwTable* pTable = SwTable::FindTable( pFrmFmt );
+        if(!pTable->IsTblComplex())
+        {
+            SwTableLines& rLines = pTable->GetTabLines();
+            SwTableLine* pLine = rLines.GetObject(0);
+            nRet = pLine->GetTabBoxes().Count();
+        }
+    }
+    return nRet;
+}
+/*-- 03.02.99 07:37:41---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SwXTableColumns::getByIndex(sal_Int32 nIndex)
+    throw( IndexOutOfBoundsException, WrappedTargetException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< uno::XInterface >  xRet;
+    SwFrmFmt* pFrmFmt = GetFrmFmt();
+    if(!pFrmFmt)
+        throw uno::RuntimeException();
+    else
+    {
+        USHORT nCount = 0;
+        SwTable* pTable = SwTable::FindTable( pFrmFmt );
+        if(!pTable->IsTblComplex())
+        {
+            SwTableLines& rLines = pTable->GetTabLines();
+            SwTableLine* pLine = rLines.GetObject(0);
+            nCount = pLine->GetTabBoxes().Count();
+        }
+        if(nCount <= nIndex || nIndex < 0)
+            throw IndexOutOfBoundsException();
+        xRet = *new cppu::OWeakObject();
+    }
+    return uno::Any(&xRet, ::getCppuType((const uno::Reference*)0));
+}
+/*-- 03.02.99 07:37:42---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+
+uno::Type SAL_CALL SwXTableColumns::getElementType(void) throw( uno::RuntimeException )
+{
+    return ::getCppuType((uno::Reference*)0);
+}
+/*-- 03.02.99 07:37:42---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Bool SwXTableColumns::hasElements(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwFrmFmt* pFrmFmt = GetFrmFmt();
+    if(!pFrmFmt)
+        throw uno::RuntimeException();
+    return sal_True;
+}
+/*-- 03.02.99 07:37:42---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTableColumns::insertByIndex(sal_Int32 nIndex, sal_Int32 nCount) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwFrmFmt* pFrmFmt = GetFrmFmt();
+    if(!pFrmFmt|| nIndex < 0 || nCount <=0 )
+        throw uno::RuntimeException();
+    else
+    {
+        SwTable* pTable = SwTable::FindTable( pFrmFmt );
+        if(!pTable->IsTblComplex())
+        {
+            String sTLName = lcl_GetCellName(nIndex, 0);
+            const SwTableBox* pTLBox = pTable->GetTblBox( sTLName );
+            sal_Bool bAppend = sal_False;
+            if(!pTLBox)
+            {
+                bAppend = sal_True;
+                // am Ende anfuegen, dazu muss der Cursor in die letzte Spalte!
+                SwTableLines& rLines = pTable->GetTabLines();
+                SwTableLine* pLine = rLines.GetObject(0);
+                SwTableBoxes& rBoxes = pLine->GetTabBoxes();
+                pTLBox = rBoxes.GetObject(0);
+            }
+            if(pTLBox)
+            {
+                const SwStartNode* pSttNd = pTLBox->GetSttNd();
+                SwPosition aPos(*pSttNd);
+                UnoActionContext aAction(pFrmFmt->GetDoc());
+                SwUnoCrsr* pUnoCrsr = pFrmFmt->GetDoc()->CreateUnoCrsr(aPos, sal_True);
+                pUnoCrsr->Move( fnMoveForward, fnGoNode );
+                pFrmFmt->GetDoc()->InsertCol(*pUnoCrsr, nCount, bAppend);
+                delete pUnoCrsr;
+            }
+        }
+    }
+}
+/*-- 03.02.99 07:37:43---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTableColumns::removeByIndex(sal_Int32 nIndex, sal_Int32 nCount) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    SwFrmFmt* pFrmFmt = GetFrmFmt();
+    if(!pFrmFmt|| nIndex < 0 || nCount <=0 )
+        throw uno::RuntimeException();
+    else
+    {
+        SwTable* pTable = SwTable::FindTable( pFrmFmt );
+        if(!pTable->IsTblComplex())
+        {
+            String sTLName = lcl_GetCellName(nIndex, 0);
+            const SwTableBox* pTLBox = pTable->GetTblBox( sTLName );
+            if(pTLBox)
+            {
+                const SwStartNode* pSttNd = pTLBox->GetSttNd();
+                SwPosition aPos(*pSttNd);
+                SwUnoCrsr* pUnoCrsr = pFrmFmt->GetDoc()->CreateUnoCrsr(aPos, sal_True);
+                //TODO: hier wird nur eine Spalte geloescht!
+                pUnoCrsr->Move( fnMoveForward, fnGoNode );
+                {   // Die Klammer ist wichtig
+                    UnoActionContext aAction(pFrmFmt->GetDoc());
+                    pFrmFmt->GetDoc()->DeleteCol(*pUnoCrsr);
+                    delete pUnoCrsr;
+                }
+                // hier muessen die Actions aufgehoben werden
+                UnoActionRemoveContext aRemoveContext(pFrmFmt->GetDoc());
+            }
+        }
+    }
+}
+/*-- 03.02.99 07:37:43---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXTableColumns::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew)
+{
+    ClientModify(this, pOld, pNew);
+}
+/*------------------------------------------------------------------------
+
+    $Log: not supported by cvs2svn $
+    Revision 1.123  2000/09/18 16:04:35  willem.vandorp
+    OpenOffice header added.
+
+    Revision 1.122  2000/09/15 07:24:04  os
+    #78563# survive setPropertyValue with void
+
+    Revision 1.121  2000/09/12 13:03:59  os
+    #78700# types of text content properties corrected
+
+    Revision 1.120  2000/09/05 15:15:18  os
+    string length available again
+
+    Revision 1.119  2000/08/24 11:14:34  mib
+    bug fixes for XML import
+
+    Revision 1.118  2000/08/18 15:01:26  os
+    #77094# getCellRangeByName corrected
+
+    Revision 1.117  2000/08/18 10:25:43  os
+    #77790# obsolete type casts removed
+
+    Revision 1.116  2000/08/15 10:09:19  os
+    throw exception if cell doesn't exist in CreateCursorByCellName
+
+    Revision 1.115  2000/08/09 14:50:16  os
+    create cell objects without SwTableBox*
+
+    Revision 1.114  2000/08/09 13:50:02  os
+    #77094# SwXCellRange: check for illegal parameters
+
+    Revision 1.113  2000/07/19 11:26:27  os
+    #76861# getError - implemented via string compare
+
+    Revision 1.112  2000/07/19 11:01:49  os
+    properties added/renamed
+
+    Revision 1.111  2000/07/11 13:43:44  os
+    #76708# insert/remove paragraphs before/behind tables
+
+    Revision 1.110  2000/07/10 12:32:18  os
+    chg: acquire/release don't throw exceptions
+
+    Revision 1.109  2000/07/03 14:18:36  os
+    #76590# ::getCellByName: reject negative positions
+
+    Revision 1.108  2000/07/03 13:26:34  os
+    #76457# support service TextContent
+
+    Revision 1.107  2000/07/03 10:46:46  os
+    #76404# SwXTableColumns::getByIndex: check index value
+
+    Revision 1.106  2000/06/30 12:45:52  os
+    getByIndex: return type correced
+
+    Revision 1.105  2000/06/27 16:33:57  os
+    #76407# IndexOutOfBoundsException instead of RuntimeException
+
+    Revision 1.104  2000/06/27 12:10:33  os
+    #76423# programmatic style names
+
+    Revision 1.103  2000/06/13 13:42:23  os
+    #75719# special handling of AnchorType of text tables
+
+    Revision 1.102  2000/05/30 11:27:26  os
+    #76028# service CellProperties
+
+    Revision 1.101  2000/05/26 07:21:48  os
+    old SW Basic API Slots removed
+
+    Revision 1.100  2000/05/18 08:36:32  os
+    XInterface - mothods
+
+    Revision 1.99  2000/05/16 17:21:40  jp
+    Changes for Unicode
+
+    Revision 1.98  2000/05/16 09:14:55  os
+    project usr removed
+
+    Revision 1.97  2000/05/04 15:16:37  os
+    reduce size of unoobj.cxx
+
+    Revision 1.96  2000/04/27 10:46:56  os
+    UNICODE
+
+    Revision 1.95  2000/04/26 11:35:20  os
+    GetName() returns String&
+
+    Revision 1.94  2000/04/19 13:35:31  os
+    UNICODE
+
+    Revision 1.93  2000/04/12 13:26:02  os
+    SfxItemPropertyMap/Set use OUString
+
+    Revision 1.92  2000/03/27 10:21:11  os
+    UNO III
+
+    Revision 1.91  2000/03/21 15:42:25  os
+    UNOIII
+
+    Revision 1.90  2000/03/09 21:53:59  jp
+    Changes: SchMemChart in new headerfile
+
+    Revision 1.89  2000/02/17 12:13:55  os
+    #70258# Range corrected
+
+    Revision 1.88  2000/02/11 14:36:00  hr
+    #70473# changes for unicode ( patched by automated patchtool )
+
+    Revision 1.87  2000/01/07 12:56:43  os
+    #67022# SwXTextTable: react to deleted table
+
+    Revision 1.86  1999/11/25 15:43:27  os
+    headers corrected
+
+    Revision 1.85  1999/11/22 10:37:58  os
+    missing headers added
+
+    Revision 1.84  1999/11/19 16:40:19  os
+    modules renamed
+
+    Revision 1.83  1999/10/26 14:35:33  os
+    LinkTargetSupplier
+
+    Revision 1.82  1999/10/13 11:52:34  os
+    #69150# convert Distance in TableBorder
+
+    Revision 1.81  1999/10/11 09:45:01  os
+    #69081# missing break
+
+    Revision 1.80  1999/10/08 11:37:00  os
+    call MakeBoxSels after Merge or Split
+
+    Revision 1.79  1999/10/07 12:54:09  os
+    #69017# call MakeBoxSels before any other operation
+
+    Revision 1.78  1999/10/06 14:12:05  os
+    #69022# GetRangeByName: use a Reference not a pointer
+
+    Revision 1.77  1999/09/23 11:49:30  os
+    #68802# getTableNames - dont include empty boxes
+
+    Revision 1.76  1999/07/19 06:43:46  OS
+    syntax error, SwWait removed
+
+
+      Rev 1.75   19 Jul 1999 08:43:46   OS
+   syntax error, SwWait removed
+
+      Rev 1.74   13 Jul 1999 16:05:24   MA
+   use internal object to toggle wait cursor
+
+      Rev 1.73   08 Jul 1999 11:26:14   OS
+   #67500# cursor handling in protected sections
+
+      Rev 1.72   27 Apr 1999 13:01:02   OS
+   #65400# Formel zuruecksetzen, wenn setString an der Zelle gerufen wird
+
+      Rev 1.71   26 Apr 1999 11:52:02   OS
+   #65199# Tabellenname aus dem Descriptor uebernehmen
+
+      Rev 1.70   23 Apr 1999 08:26:36   OS
+   #65194# Semikolon muss weg
+
+      Rev 1.69   22 Apr 1999 16:13:58   OS
+   #65194# throw -> throw; #65124# not impl. nur noch warning EventListener
+
+      Rev 1.68   31 Mar 1999 06:45:28   OS
+   #63852# AnchorType fuer Tabelle
+
+      Rev 1.67   16 Mar 1999 10:36:52   OS
+   #63310# Tabelle mit den richtigen Flags einfuegen
+
+      Rev 1.66   15 Mar 1999 14:37:56   OS
+   #62845# Makro fuer ServiceInfo jetzt auch fuer OS/2
+
+      Rev 1.65   12 Mar 1999 09:41:34   OS
+   #62845# XServiceInfo impl.
+
+      Rev 1.64   11 Mar 1999 10:14:04   OS
+   #63101# SetValue/Formula: richtiges Format uebergeben
+
+      Rev 1.63   11 Mar 1999 08:33:00   OS
+   #63110# Text-Intefaces fuer XCell im queryInterface
+
+
+      Rev 1.62   09 Mar 1999 12:41:30   OS
+   #62008# Solar-Mutex
+
+      Rev 1.61   08 Mar 1999 13:51:42   OS
+   #62751# XChartDataArray
+
+      Rev 1.60   08 Mar 1999 07:42:42   MH
+   update 515
+
+      Rev 1.59   05 Mar 1999 08:43:10   OS
+   #62191# INT statt UINT
+
+      Rev 1.58   04 Mar 1999 15:01:28   OS
+   #62191# UINT nicht mehr verwenden
+
+      Rev 1.57   25 Feb 1999 13:32:52   OS
+   #62405# richtiges Split fuer Tabellen mit korrektem Namen
+
+      Rev 1.56   19 Feb 1999 17:01:08   OS
+   #62124# ParagraphEnumeration soll sich in Tabellen nicht verlaufen, #62118# eigener TextRange fuer Tabelle
+
+      Rev 1.55   18 Feb 1999 14:25:54   OS
+   #52654# insertTextContent statt attach
+
+      Rev 1.54   11 Feb 1999 16:43:52   OS
+   #52654# fehlendes break
+
+      Rev 1.53   11 Feb 1999 16:16:12   OS
+   #52654# GetProperty ohne const
+
+      Rev 1.52   05 Feb 1999 14:31:14   OS
+   #56371# XCellRange interface veraendert
+
+      Rev 1.51   03 Feb 1999 11:45:12   OS
+   #56371# SwXTableRows/Columns
+
+      Rev 1.50   28 Jan 1999 16:46:26   OS
+   #56371# keine Objekte fuer DEBUG anlegen
+
+      Rev 1.49   27 Jan 1999 12:06:50   OS
+   #56371# TF_ONE51
+
+      Rev 1.48   22 Jan 1999 15:09:24   OS
+   #56371# Draw wieder verfuegbar
+
+      Rev 1.47   14 Jan 1999 16:21:48   OS
+   #56371# TF_ONE51
+
+      Rev 1.46   15 Dec 1998 10:09:56   OS
+   #56371# TF_ONE51 Zwischenstand
+
+      Rev 1.45   10 Dec 1998 15:53:38   OS
+   #56371# TF_ONE51 Zwischenstand
+
+      Rev 1.44   09 Nov 1998 14:47:22   OS
+   #58785# getSelection an der XTextView vollstaendig
+
+      Rev 1.43   04 Nov 1998 13:10:26   OS
+   #58229# Zugriffe auf das Layout von unsichtbaren Tabellen verhindern
+
+      Rev 1.42   15 Oct 1998 12:19:32   OS
+   #52654# Tabellenformatierung mit SetONECalcLowers
+
+      Rev 1.41   02 Oct 1998 16:09:18   OS
+   #52654# CalcLayout fuer Tabelle, Range und TableCursor
+
+      Rev 1.40   30 Sep 1998 10:30:02   OS
+   #52654# Sortable und SortDescriptor eingebaut
+
+      Rev 1.39   15 Sep 1998 16:15:10   OS
+   #52654# Cursor nach setPropertyValue wieder loeschen
+
+      Rev 1.38   29 Jul 1998 13:05:16   OS
+   Height und IsAutoHeight an der TableRow #52654#
+
+      Rev 1.37   24 Jul 1998 10:51:36   OS
+   leere BorderLines muessen mit Null gesetzt werden #52654#
+
+      Rev 1.36   21 Jul 1998 17:03:34   OS
+   ParagraphStyle am Range und am TextTableCursor  #52654#
+
+      Rev 1.35   21 Jul 1998 14:23:30   OS
+   include #52654#
+
+      Rev 1.34   21 Jul 1998 09:15:58   OS
+   beans::XPropertySet fuer TextTableCursor #52654#
+
+      Rev 1.33   20 Jul 1998 17:30:04   OS
+   neu: SwXTextTableCursor; chg: SwXTextTable erwietert #52654#
+
+      Rev 1.32   18 Jul 1998 16:12:18   OS
+   Border und Tabellenspaltenbreiten fuer UNO #54654#
+
+      Rev 1.31   15 Jul 1998 13:18:02   OS
+   XChartData an der Table und am Range unterstuetzen #52656#
+
+      Rev 1.30   10 Jul 1998 18:09:04   OS
+   PropertySetInfo und IdlClass static
+
+      Rev 1.29   09 Jul 1998 09:14:44   OS
+   UnoActionRemoveContext
+
+      Rev 1.28   29 Jun 1998 17:24:10   OS
+   Properties Tabellenzeile
+
+      Rev 1.27   27 Jun 1998 16:22:36   OS
+   SwXTextTableRow angefangen
+
+      Rev 1.26   26 Jun 1998 18:17:54   OS
+   PageDesc setzen
+
+      Rev 1.25   25 Jun 1998 11:14:56   OS
+   PreopertyMaps nur noch vom PropertyMapProvider
+
+      Rev 1.24   23 Jun 1998 09:51:26   TRI
+   ICC brauchte temp. Objekte
+
+      Rev 1.23   18 Jun 1998 08:10:50   OS
+   Property-Namen veraendert
+
+      Rev 1.22   16 Jun 1998 16:53:46   OS
+   Bold/Italic/Underlined ersetzt durch Weight, Posture, Underline
+
+      Rev 1.21   15 Jun 1998 09:08:38   OS
+   setPropertyValue am CellRange berichtigt
+
+      Rev 1.20   12 Jun 1998 09:46:44   OS
+   Tabellenboxen anders suchen
+
+      Rev 1.19   10 Jun 1998 15:57:52   OS
+   SwXCellRange::getColumn/RowCount und ::getSubRange berichtigt
+
+      Rev 1.18   10 Jun 1998 08:20:42   OS
+   get/setFormula/Value eingebaut
+
+      Rev 1.17   08 Jun 1998 16:29:02   OS
+   get/setText korrigiert
+
+      Rev 1.16   08 Jun 1998 10:34:32   OS
+   Map-Reihenfolge
+
+      Rev 1.15   04 Jun 1998 09:40:04   OS
+   getIdlClasses
+
+
+      Rev 1.14   03 Jun 1998 09:53:44   OS
+   ParagraphEnumeratable
+
+      Rev 1.13   02 Jun 1998 10:33:58   JP
+   TabellenAutoFormat: Load/Save ohne Stream - erzeugen diesen selbst
+
+      Rev 1.12   29 May 1998 13:49:18   OS
+   UNO_NAME_REGISTER -> _REGISTER_MODE_ACTIVE
+
+      Rev 1.11   22 May 1998 15:10:38   OS
+   CreateTextCursorAtPos eingebaut
+
+      Rev 1.10   18 May 1998 12:22:54   OS
+   Container fuer Suchergebnis
+
+      Rev 1.9   05 May 1998 10:04:30   OS
+   Actions
+
+      Rev 1.8   04 May 1998 08:55:14   OS
+   Zeilen+Spalten einfuegen und loeschen
+
+      Rev 1.7   29 Apr 1998 08:00:56   OS
+   SwXCellRange
+
+      Rev 1.6   22 Apr 1998 13:43:06   OS
+   Tabellenname nur ohne Space und Punkt
+
+      Rev 1.5   17 Apr 1998 13:35:28   OS
+   Tabellennamen setzen
+
+      Rev 1.4   09 Apr 1998 15:10:52   OS
+   Uno-Umstellung
+
+      Rev 1.3   07 Apr 1998 17:06:22   OS
+   ParagraphEnumerator eingebaut
+
+      Rev 1.2   07 Apr 1998 14:07:38   OS
+   SwXTextTable hierher verschoben
+
+      Rev 1.1   12 Mar 1998 16:44:06   TJ
+   include
+
+      Rev 1.0   10 Mar 1998 12:12:34   OS
+   Initial revision.
+
+
+------------------------------------------------------------------------*/
+
diff --git a/sw/source/core/unocore/unotext.cxx b/sw/source/core/unocore/unotext.cxx
new file mode 100644
index 000000000000..31fac19ac65c
--- /dev/null
+++ b/sw/source/core/unocore/unotext.cxx
@@ -0,0 +1,1534 @@
+/*************************************************************************
+ *
+ *  $RCSfile: unotext.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:29 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _COM_SUN_STAR_DRAWING_XDRAWPAGESUPPLIER_HPP_
+#include 
+#endif
+#ifndef _COM_SUN_STAR_TEXT_CONTROLCHARACTER_HPP_
+#include 
+#endif
+
+#ifndef _VOS_MUTEX_HXX_ //autogen
+#include 
+#endif
+#ifndef _SV_SVAPP_HXX //autogen
+#include 
+#endif
+#ifndef _RTL_UUID_H_
+#include 
+#endif
+#ifndef _UNOOBJ_HXX
+#include 
+#endif
+#ifndef _UNOTBL_HXX
+#include 
+#endif
+#ifndef _UNOIDX_HXX
+#include 
+#endif
+#ifndef _UNOFRAME_HXX
+#include 
+#endif
+#ifndef _UNOFIELD_HXX
+#include 
+#endif
+#ifndef _UNODRAW_HXX
+#include 
+#endif
+#ifndef _SWDOCSH_HXX //autogen
+#include 
+#endif
+#ifndef _DOC_HXX //autogen
+#include 
+#endif
+#ifndef _SECTION_HXX //autogen
+#include 
+#endif
+#ifndef _UNOCRSR_HXX
+#include 
+#endif
+#ifndef _BOOKMRK_HXX //autogen
+#include 
+#endif
+#ifndef _FMTHBSH_HXX //autogen
+#include 
+#endif
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::beans;
+using namespace ::rtl;
+
+#define EXCEPT_ON_PROTECTION(rUnoCrsr)  \
+    if((rUnoCrsr).HasReadonlySel()) \
+        throw uno::RuntimeException();
+
+/******************************************************************
+ * SwXText
+ ******************************************************************/
+/*-- 09.12.98 12:44:07---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XTextCursor >   SwXText::createCursor()
+{
+    uno::Reference< XTextCursor >  xRet;
+    OUString sRet;
+    if(IsValid())
+    {
+        SwNode& rNode = GetDoc()->GetNodes().GetEndOfContent();
+        SwPosition aPos(rNode);
+        xRet =  (XWordCursor*)new SwXTextCursor(this, aPos, GetTextType(), GetDoc());
+        xRet->gotoStart(sal_False);
+    }
+    return xRet;
+}
+/*-- 09.12.98 12:43:55---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXText::~SwXText()
+{
+
+}
+/*-- 09.12.98 12:43:02---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SAL_CALL SwXText::queryInterface( const uno::Type& rType ) throw(uno::RuntimeException)
+{
+    const uno::Type& rXTextType = ::getCppuType((uno::Reference< XText >*)0);
+    const uno::Type& rXTextRangeCompareType = ::getCppuType((uno::Reference< XTextRangeCompare >*)0);
+    const uno::Type& rXSimpleTextType = ::getCppuType((const uno::Reference< XSimpleText >*)0);
+    const uno::Type& rXTextRangeType = ::getCppuType((uno::Reference< XTextRange >*)0);
+    const uno::Type& rXTypeProviderType = ::getCppuType((uno::Reference< lang::XTypeProvider >*)0);
+    const uno::Type& rXTextContentInsert = ::getCppuType((uno::Reference< XRelativeTextContentInsert >*)0);
+    const uno::Type& rXTextContentRemove = ::getCppuType((uno::Reference< XRelativeTextContentRemove >*)0);
+
+    uno::Any aRet;
+    if(rType == rXTextType)
+    {
+        uno::Reference< XText > xRet = this;
+        aRet.setValue(&xRet, rXTextType);
+    }
+    else if(rType == rXSimpleTextType)
+    {
+        uno::Reference< XSimpleText > xRet = this;
+        aRet.setValue(&xRet, rXSimpleTextType);
+    }
+    else if(rType == rXTextRangeType)
+    {
+        uno::Reference< XTextRange > xRet = this;
+        aRet.setValue(&xRet, rXTextRangeType);
+    }
+    else if(rType == rXTextRangeCompareType)
+    {
+        uno::Reference< XTextRangeCompare > xRet = this;
+        aRet.setValue(&xRet, rXTextRangeCompareType);
+    }
+    else if(rType == rXTypeProviderType)
+    {
+        uno::Reference< lang::XTypeProvider > xRet = this;
+        aRet.setValue(&xRet, rXTypeProviderType);
+    }
+    else if(rType == rXTextContentInsert)
+    {
+        uno::Reference< XRelativeTextContentInsert > xRet = this;
+        aRet.setValue(&xRet, rXTextContentInsert);
+    }
+    else if(rType == rXTextContentRemove)
+    {
+        uno::Reference< XRelativeTextContentRemove > xRet = this;
+        aRet.setValue(&xRet, rXTextContentRemove);
+    }
+    return aRet;
+}
+/* -----------------------------15.03.00 17:42--------------------------------
+
+ ---------------------------------------------------------------------------*/
+uno::Sequence< uno::Type > SAL_CALL SwXText::getTypes() throw(uno::RuntimeException)
+{
+    uno::Sequence< uno::Type > aRet(4);
+    uno::Type* pTypes = aRet.getArray();
+    pTypes[0] = ::getCppuType((uno::Reference< XText >*)0);
+    pTypes[1] = ::getCppuType((uno::Reference< XTextRangeCompare >*)0);
+    pTypes[2] = ::getCppuType((uno::Reference< XRelativeTextContentInsert >*)0);
+    pTypes[3] = ::getCppuType((uno::Reference< XRelativeTextContentRemove >*)0);
+
+    return aRet;
+}
+
+/*-- 09.12.98 12:43:14---------------------------------------------------
+    Gehoert der Range in den Text ? - dann einfuegen
+  -----------------------------------------------------------------------*/
+void SwXText::insertString(const uno::Reference< XTextRange > & xTextRange,
+                                const OUString& aString, sal_Bool bAbsorb)
+                                throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(GetDoc() && xTextRange.is())
+    {
+        uno::Reference xRangeTunnel( xTextRange, uno::UNO_QUERY);
+        SwXTextRange* pRange = 0;
+        SwXTextCursor* pCursor = 0;
+        if(xRangeTunnel.is())
+        {
+            pRange = (SwXTextRange*)xRangeTunnel->getSomething(
+                                    SwXTextRange::getUnoTunnelId());
+            pCursor = (SwXTextCursor*)xRangeTunnel->getSomething(
+                                    SwXTextCursor::getUnoTunnelId());
+        }
+
+        if(pRange && pRange->GetDoc()  == GetDoc() ||
+            pCursor && pCursor->GetDoc()  == GetDoc())
+        {
+            uno::Reference< XTextCursor >  xOwnCursor = createCursor();
+            uno::Reference xOwnTunnel( xTextRange, uno::UNO_QUERY);
+            SwXTextCursor* pOwnCursor = (SwXTextCursor*)xOwnTunnel->getSomething(
+                                    SwXTextCursor::getUnoTunnelId());
+
+            const SwStartNode* pOwnStartNode = pOwnCursor->GetCrsr()->GetNode()->FindStartNode();
+            if(pCursor)
+            {
+                const SwStartNode* pTmp = pCursor->GetCrsr()->GetNode()->FindStartNode();
+                while(pOwnStartNode->IsSectionNode())
+                {
+                    pOwnStartNode = pOwnStartNode->FindStartNode();
+                }
+                while(pTmp && pTmp->IsSectionNode())
+                {
+                    pTmp = pTmp->FindStartNode();
+                }
+                if(pOwnStartNode != pTmp)
+                {
+                    throw uno::RuntimeException();
+                }
+            }
+            else //dann pRange
+            {
+                SwBookmark* pBkm = pRange->GetBookmark();
+                const SwStartNode* pTmp = pBkm->GetPos().nNode.GetNode().FindStartNode();
+                while( pTmp && pTmp->IsSectionNode())
+                {
+                    pTmp = pTmp->FindStartNode();
+                }
+                //if the document starts with a section
+                while(pOwnStartNode->IsSectionNode())
+                {
+                    pOwnStartNode = pOwnStartNode->FindStartNode();
+                }
+                if(pOwnStartNode != pTmp)
+                {
+                    throw uno::RuntimeException();
+                }
+            }
+            if(bAbsorb)
+            {
+                xTextRange->setString(aString);
+            }
+            else
+            {
+                //hier wird ein PaM angelegt, der vor dem Parameter-PaM liegt, damit der
+                //Text davor eingefuegt wird
+                const SwPosition* pPos = pCursor ? pCursor->GetCrsr()->Start() : &pRange->GetBookmark()->GetPos();
+                SwPaM aInsertPam(*pPos);
+                sal_Bool bGroupUndo = GetDoc()->DoesGroupUndo();
+                GetDoc()->DoGroupUndo(sal_False);
+                if(!GetDoc()->Insert(aInsertPam, aString ))
+                    DBG_ERROR("Text wurde nicht eingefuegt");
+                GetDoc()->DoGroupUndo(bGroupUndo);
+            }
+        }
+        else
+        {
+            throw uno::RuntimeException();
+        }
+    }
+    else
+    {
+        throw uno::RuntimeException();
+    }
+}
+/*-- 09.12.98 12:43:16---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXText::insertControlCharacter(const uno::Reference< XTextRange > & xTextRange,
+                sal_Int16 nControlCharacter, sal_Bool bAbsorb)
+                throw( lang::IllegalArgumentException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(GetDoc() && xTextRange.is())
+    {
+        SwUnoInternalPaM aPam(*GetDoc());
+        if(SwXTextRange::XTextRangeToSwPaM(aPam, xTextRange))
+        {
+            //Steuerzeichen einfuegen
+            SwPaM aTmp(*aPam.Start());
+            if(bAbsorb && aPam.HasMark())
+                pDoc->DeleteAndJoin(aPam);
+
+            sal_Unicode cIns = 0;
+            switch( nControlCharacter )
+            {
+                case ControlCharacter::PARAGRAPH_BREAK :
+                    // eine Tabellen Zelle wird jetzt zu einer normalen Textzelle!
+                    pDoc->ClearBoxNumAttrs( aTmp.GetPoint()->nNode );
+                    pDoc->SplitNode( *aTmp.GetPoint(), sal_True );
+                    break;
+                case ControlCharacter::APPEND_PARAGRAPH:
+                    pDoc->ClearBoxNumAttrs( aTmp.GetPoint()->nNode );
+                    pDoc->AppendTxtNode( *aTmp.GetPoint() );
+                break;
+                case ControlCharacter::LINE_BREAK:  cIns = 10;      break;
+                case ControlCharacter::SOFT_HYPHEN: cIns = CHAR_SOFTHYPHEN; break;
+                case ControlCharacter::HARD_HYPHEN: cIns = CHAR_HARDHYPHEN; break;
+                case ControlCharacter::HARD_SPACE:  cIns = CHAR_HARDBLANK;  break;
+            }
+            if( cIns )
+                pDoc->Insert( aTmp, cIns );
+
+            if(bAbsorb)
+            {
+                uno::Reference xRangeTunnel( xTextRange, uno::UNO_QUERY);
+                SwXTextRange* pRange = 0;
+                SwXTextCursor* pCursor = 0;
+                if(xRangeTunnel.is())
+                {
+                    pRange = (SwXTextRange*)xRangeTunnel->getSomething(
+                                            SwXTextRange::getUnoTunnelId());
+                    pCursor = (SwXTextCursor*)xRangeTunnel->getSomething(
+                                            SwXTextCursor::getUnoTunnelId());
+                }
+
+                SwCursor aCrsr(*aTmp.GetPoint());
+                SwXTextCursor::SelectPam(aCrsr, sal_True);
+                aCrsr.Left(1);
+                //hier muss der uebergebene PaM umgesetzt werden:
+                if(pRange)
+                    pRange->_CreateNewBookmark(aCrsr);
+                else
+                {
+                    SwUnoCrsr* pUnoCrsr = pCursor->GetCrsr();
+                    *pUnoCrsr->GetPoint() = *aCrsr.GetPoint();
+                    if(aCrsr.HasMark())
+                    {
+                        pUnoCrsr->SetMark();
+                        *pUnoCrsr->GetMark() = *aCrsr.GetMark();
+                    }
+                    else
+                        pUnoCrsr->DeleteMark();
+                }
+            }
+        }
+    }
+    else
+        throw uno::RuntimeException();
+}
+/*-- 09.12.98 12:43:17---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+
+void SwXText::insertTextContent(const uno::Reference< XTextRange > & xRange,
+                const uno::Reference< XTextContent > & xContent, sal_Bool bAbsorb)
+                throw( lang::IllegalArgumentException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    // erstmal testen, ob der Range an der richtigen Stelle ist und dann
+    // am Sw-Content attachToRange aufrufen
+    if(!GetDoc())
+        throw uno::RuntimeException();
+    if(xRange.is() && xContent.is())
+    {
+        SwUnoInternalPaM aPam(*GetDoc());
+        if(SwXTextRange::XTextRangeToSwPaM(aPam, xRange))
+        {
+            uno::Reference xRangeTunnel( xRange, uno::UNO_QUERY);
+            SwXTextRange* pRange = 0;
+            SwXTextCursor* pCursor = 0;
+            if(xRangeTunnel.is())
+            {
+                pRange = (SwXTextRange*)xRangeTunnel->getSomething(
+                                        SwXTextRange::getUnoTunnelId());
+                pCursor = (SwXTextCursor*)xRangeTunnel->getSomething(
+                                        SwXTextCursor::getUnoTunnelId());
+            }
+
+
+            uno::Reference< XTextCursor >  xOwnCursor = createCursor();
+            uno::Reference xOwnTunnel( xOwnCursor, uno::UNO_QUERY);
+            SwXTextCursor* pOwnCursor = (SwXTextCursor*)xOwnTunnel->getSomething(
+                                    SwXTextCursor::getUnoTunnelId());
+
+            const SwStartNode* pOwnStartNode = pOwnCursor->GetCrsr()->GetNode()->FindStartNode();
+            SwStartNodeType eSearchNodeType = SwNormalStartNode;
+            switch(eCrsrType)
+            {
+                case CURSOR_FRAME:      eSearchNodeType = SwFlyStartNode;       break;
+                case CURSOR_TBLTEXT:    eSearchNodeType = SwTableBoxStartNode;  break;
+                case CURSOR_FOOTNOTE:   eSearchNodeType = SwFootnoteStartNode;  break;
+                case CURSOR_HEADER:     eSearchNodeType = SwHeaderStartNode;    break;
+                case CURSOR_FOOTER:     eSearchNodeType = SwFooterStartNode;    break;
+                //case CURSOR_INVALID:
+                //case CURSOR_BODY:
+            }
+
+            const SwNode* pSrcNode;
+            if(pCursor)
+            {
+                pSrcNode = pCursor->GetCrsr()->GetNode();
+            }
+            else //dann pRange
+            {
+                SwBookmark* pBkm = pRange->GetBookmark();
+                pSrcNode = &pBkm->GetPos().nNode.GetNode();
+            }
+            const SwStartNode* pTmp = pSrcNode->FindSttNodeByType(eSearchNodeType);
+
+            //SectionNodes ueberspringen
+            while(pTmp && pTmp->IsSectionNode())
+            {
+                pTmp = pTmp->FindStartNode();
+            }
+            //if the document starts with a section
+            while(pOwnStartNode->IsSectionNode())
+            {
+                pOwnStartNode = pOwnStartNode->FindStartNode();
+            }
+            //this checks if (this) and xRange are in the same XText interface
+            if(pOwnStartNode != pTmp)
+            {
+                throw uno::RuntimeException();
+            }
+            // Sonderbehandlung fuer Contents, die den Range nicht ersetzen, sonder darueber gelegt werden
+            // Bookmarks, IndexEntry
+            sal_Bool bAttribute = sal_False;
+            uno::Reference xContentTunnel( xContent, uno::UNO_QUERY);
+            if(!xContentTunnel.is())
+                throw lang::IllegalArgumentException();
+            SwXDocumentIndexMark* pDocumentIndexMark =
+                (SwXDocumentIndexMark*)xContentTunnel->getSomething(
+                                        SwXDocumentIndexMark::getUnoTunnelId());
+
+
+            SwXTextSection* pSection = (SwXTextSection*)xContentTunnel->getSomething(
+                                        SwXTextSection::getUnoTunnelId());
+
+            SwXBookmark* pBookmark = (SwXBookmark*)xContentTunnel->getSomething(
+                                        SwXBookmark::getUnoTunnelId());
+
+
+            SwXReferenceMark* pReferenceMark = (SwXReferenceMark*)
+                        xContentTunnel->getSomething(
+                                        SwXReferenceMark::getUnoTunnelId());
+
+            bAttribute = pBookmark || pDocumentIndexMark || pSection || pReferenceMark;
+
+            if(bAbsorb && !bAttribute)
+            {
+                xRange->setString(aEmptyStr);
+            }
+            //hier wird tatsaechlich eingefuegt
+            uno::Reference< XTextRange >  xTempRange;
+            if(bAttribute && bAbsorb)
+                xTempRange = xRange;
+            else
+                xTempRange = xRange->getStart();
+            SwXTextTable* pTable = (SwXTextTable*)
+                        xContentTunnel->getSomething(
+                                        SwXTextTable::getUnoTunnelId());
+
+            if(pTable)
+                pTable->attachToRange(xTempRange);
+            else
+            {
+                if(pBookmark)
+                    pBookmark ->attachToRange(xTempRange);
+                else
+                {
+                    if(pSection)
+                        pSection ->attachToRange(xTempRange);
+                    else
+                    {
+                        SwXFootnote* pFootnote = (SwXFootnote*)
+                                xContentTunnel->getSomething(
+                                                SwXFootnote::getUnoTunnelId());
+
+                        if(pFootnote)
+                            pFootnote->attachToRange(xTempRange);
+                        else
+                        {
+                            if(pReferenceMark)
+                                pReferenceMark->attachToRange(xTempRange);
+                            else
+                            {
+                                SwXFrame* pFrame = (SwXFrame*)
+                                    xContentTunnel->getSomething(
+                                                    SwXFrame::getUnoTunnelId());
+
+                                if(pFrame)
+                                    pFrame->attachToRange(xTempRange);
+                                else
+                                {
+                                    SwXDocumentIndex* pDocumentIndex = (SwXDocumentIndex*)
+                                        xContentTunnel->getSomething(
+                                                        SwXDocumentIndex::getUnoTunnelId());
+
+                                    if(pDocumentIndex)
+                                        pDocumentIndex->attachToRange(xTempRange);
+                                    else
+                                    {
+                                        if(pDocumentIndexMark)
+                                            pDocumentIndexMark->attachToRange(xTempRange);
+                                        else
+                                        {
+                                            SwXTextField* pTextField = (SwXTextField*)
+                                                xContentTunnel->getSomething(
+                                                                SwXTextField::getUnoTunnelId());
+
+                                            if(pTextField)
+                                                pTextField->attachToRange(xTempRange);
+                                            else
+                                            {
+                                                uno::Reference xShapeProperties(xContent, uno::UNO_QUERY);
+                                                SwXShape* pShape = 0;
+                                                if(xShapeProperties.is())
+                                                    pShape = (SwXShape*)xContentTunnel->getSomething(
+                                                                            SwXShape::getUnoTunnelId());
+                                                if(pShape)
+                                                {
+                                                    uno::Any aPos(&xRange,
+                                                        ::getCppuType((uno::Reference*)0));
+                                                    pShape->setPropertyValue(C2U("TextRange"), aPos);
+
+                                                    uno::Reference xModel =
+                                                                    pDoc->GetDocShell()->GetBaseModel();
+                                                    uno::Reference xPageSupp(
+                                                                xModel, uno::UNO_QUERY);
+
+                                                    uno::Reference xPage = xPageSupp->getDrawPage();
+
+                                                    uno::Reference xShape((cppu::OWeakObject*)pShape,
+                                                                                                            uno::UNO_QUERY);
+                                                    //nuer die XShapes haengen an der Sw-Drawpage
+                                                    uno::Reference xShps(xPage, uno::UNO_QUERY);
+                                                    xShps->add(xShape);
+                                                }
+                                                else
+                                                {
+                                                    throw lang::IllegalArgumentException();
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        else
+        {
+            throw IllegalArgumentException();
+        }
+    }
+    else
+    {
+        throw IllegalArgumentException();
+    }
+
+}
+/* -----------------------------10.07.00 15:40--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SwXText::insertTextContentBefore(
+    const Reference< XTextContent>& xNewContent,
+    const Reference< XTextContent>& xSuccessor)
+        throw(IllegalArgumentException, RuntimeException)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!GetDoc())
+        throw RuntimeException();
+
+    SwXParagraph* pPara = SwXParagraph::GetImplementation(xNewContent);
+    if(!pPara || !pPara->IsDescriptor() || !xSuccessor.is())
+        throw IllegalArgumentException();
+
+    sal_Bool bRet = FALSE;
+    SwXTextSection* pXSection = SwXTextSection::GetImplementation( xSuccessor );
+    SwXTextTable* pXTable = SwXTextTable::GetImplementation(xSuccessor );
+    SwFrmFmt* pTableFmt = pXTable ? pXTable->GetFrmFmt() : 0;
+    SwUnoCrsr* pUnoCrsr = 0;
+    if(pTableFmt && pTableFmt->GetDoc() == GetDoc())
+    {
+        SwTable* pTable = SwTable::FindTable( pTableFmt );
+        SwTableNode* pTblNode = pTable->GetTableNode();
+        {
+            const SwSectionNode* pSNd = pTblNode->GetSectionNode();
+            if( pSNd && pSNd->GetSection().IsProtectFlag() )
+                throw RuntimeException();
+        }
+        SwNodeIndex aTblIdx(  *pTblNode, -1 );
+        SwPosition aBefore(aTblIdx);
+        bRet = GetDoc()->AppendTxtNode( aBefore );
+        pUnoCrsr = GetDoc()->CreateUnoCrsr( aBefore, FALSE);
+    }
+    else if(pXSection &&
+        pXSection->GetFmt() &&
+            pXSection->GetFmt()->GetDoc() == GetDoc())
+    {
+        SwSectionFmt* pSectFmt = pXSection->GetFmt();
+        SwSectionNode* pSectNode = pSectFmt->GetSectionNode();
+        if( pSectNode->GetSection().IsProtectFlag() )
+            throw RuntimeException();
+
+        SwNodeIndex aSectIdx(  *pSectNode, -1 );
+        SwPosition aBefore(aSectIdx);
+        bRet = GetDoc()->AppendTxtNode( aBefore );
+        pUnoCrsr = GetDoc()->CreateUnoCrsr( aBefore, FALSE);
+    }
+    if(!bRet)
+        throw IllegalArgumentException();
+    else
+    {
+        pPara->attachToText(this, pUnoCrsr);
+    }
+
+}
+/* -----------------------------10.07.00 15:40--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SwXText::insertTextContentAfter(
+    const Reference< XTextContent>& xNewContent,
+    const Reference< XTextContent>& xPredecessor)
+        throw(IllegalArgumentException, RuntimeException)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!GetDoc())
+        throw RuntimeException();
+    SwXParagraph* pPara = SwXParagraph::GetImplementation(xNewContent);
+    if(!pPara || !pPara->IsDescriptor() || !xPredecessor.is())
+        throw IllegalArgumentException();
+
+    SwUnoCrsr* pUnoCrsr = 0;
+    SwXTextSection* pXSection = SwXTextSection::GetImplementation( xPredecessor );
+    SwXTextTable* pXTable = SwXTextTable::GetImplementation(xPredecessor );
+    SwFrmFmt* pTableFmt = pXTable ? pXTable->GetFrmFmt() : 0;
+    sal_Bool bRet = FALSE;
+    if(pTableFmt && pTableFmt->GetDoc() == GetDoc())
+    {
+        SwTable* pTable = SwTable::FindTable( pTableFmt );
+        SwTableNode* pTblNode = pTable->GetTableNode();
+
+        {
+            const SwSectionNode* pSNd = pTblNode->GetSectionNode();
+            if( pSNd && pSNd->GetSection().IsProtectFlag() )
+                throw RuntimeException();
+        }
+
+        SwEndNode* pTableEnd = pTblNode->EndOfSectionNode();
+        SwPosition aTableEnd(*pTableEnd);
+        bRet = GetDoc()->AppendTxtNode( aTableEnd );
+        pUnoCrsr = GetDoc()->CreateUnoCrsr( aTableEnd, FALSE);
+    }
+    else if(pXSection &&
+        pXSection->GetFmt() &&
+            pXSection->GetFmt()->GetDoc() == GetDoc())
+    {
+        SwSectionFmt* pSectFmt = pXSection->GetFmt();
+        SwSectionNode* pSectNode = pSectFmt->GetSectionNode();
+        if( pSectNode->GetSection().IsProtectFlag() )
+            throw RuntimeException();
+        SwEndNode* pEnd = pSectNode->EndOfSectionNode();
+        SwPosition aEnd(*pEnd);
+        bRet = GetDoc()->AppendTxtNode( aEnd );
+        pUnoCrsr = GetDoc()->CreateUnoCrsr( aEnd, FALSE);
+    }
+    if(!bRet)
+        throw IllegalArgumentException();
+    else
+    {
+        pPara->attachToText(this, pUnoCrsr);
+    }
+}
+/* -----------------------------10.07.00 15:40--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SwXText::removeTextContentBefore(
+    const Reference< XTextContent>& xSuccessor)
+        throw(IllegalArgumentException, RuntimeException)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!GetDoc())
+        throw RuntimeException();
+
+    sal_Bool bRet = FALSE;
+    SwXTextSection* pXSection = SwXTextSection::GetImplementation( xSuccessor );
+    SwXTextTable* pXTable = SwXTextTable::GetImplementation( xSuccessor );
+    SwFrmFmt* pTableFmt = pXTable ? pXTable->GetFrmFmt() : 0;
+    if(pTableFmt && pTableFmt->GetDoc() == GetDoc())
+    {
+        SwTable* pTable = SwTable::FindTable( pTableFmt );
+        SwTableNode* pTblNode = pTable->GetTableNode();
+
+        SwNodeIndex aTblIdx(  *pTblNode, -1 );
+        if(aTblIdx.GetNode().IsTxtNode())
+        {
+            SwPaM aBefore(aTblIdx);
+            EXCEPT_ON_PROTECTION(aBefore)
+            bRet = GetDoc()->DelFullPara( aBefore );
+        }
+    }
+    else if(pXSection &&
+        pXSection->GetFmt() &&
+            pXSection->GetFmt()->GetDoc() == GetDoc())
+    {
+        SwSectionFmt* pSectFmt = pXSection->GetFmt();
+        SwSectionNode* pSectNode = pSectFmt->GetSectionNode();
+
+        SwNodeIndex aSectIdx(  *pSectNode, -1 );
+        if(aSectIdx.GetNode().IsTxtNode())
+        {
+            SwPaM aBefore(aSectIdx);
+            EXCEPT_ON_PROTECTION(aBefore)
+            bRet = GetDoc()->DelFullPara( aBefore );
+        }
+    }
+    if(!bRet)
+        throw IllegalArgumentException();
+}
+/* -----------------------------10.07.00 15:40--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SwXText::removeTextContentAfter(const Reference< XTextContent>& xPredecessor)
+        throw(IllegalArgumentException, RuntimeException)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!GetDoc())
+        throw RuntimeException();
+
+    sal_Bool bRet = FALSE;
+    SwXTextSection* pXSection = SwXTextSection::GetImplementation( xPredecessor );
+    SwXTextTable* pXTable = SwXTextTable::GetImplementation(xPredecessor );
+    SwFrmFmt* pTableFmt = pXTable ? pXTable->GetFrmFmt() : 0;
+    if(pTableFmt && pTableFmt->GetDoc() == GetDoc())
+    {
+        SwTable* pTable = SwTable::FindTable( pTableFmt );
+        SwTableNode* pTblNode = pTable->GetTableNode();
+        SwEndNode* pTableEnd = pTblNode->EndOfSectionNode();
+
+        SwNodeIndex aTblIdx(  *pTableEnd, 1 );
+        if(aTblIdx.GetNode().IsTxtNode())
+        {
+            SwPaM aPaM(aTblIdx);
+            EXCEPT_ON_PROTECTION(aPaM)
+            bRet = GetDoc()->DelFullPara( aPaM );
+        }
+    }
+    else if(pXSection &&
+        pXSection->GetFmt() &&
+            pXSection->GetFmt()->GetDoc() == GetDoc())
+    {
+        SwSectionFmt* pSectFmt = pXSection->GetFmt();
+        SwSectionNode* pSectNode = pSectFmt->GetSectionNode();
+        SwEndNode* pEnd = pSectNode->EndOfSectionNode();
+        SwNodeIndex aSectIdx(  *pEnd, 1 );
+        if(aSectIdx.GetNode().IsTxtNode())
+        {
+            SwPaM aAfter(aSectIdx);
+            EXCEPT_ON_PROTECTION(aAfter)
+            bRet = GetDoc()->DelFullPara( aAfter );
+        }
+    }
+    if(!bRet)
+        throw IllegalArgumentException();
+}
+/*-- 09.12.98 12:43:19---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXText::removeTextContent(const uno::Reference< XTextContent > & xContent)
+    throw( container::NoSuchElementException, uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!xContent.is())
+        throw uno::RuntimeException();
+    else
+        xContent->dispose();
+}
+/*-- 09.12.98 12:43:22---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XText >  SwXText::getText(void)
+        throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< XText >  xRet = (SwXText*)this;
+    return xRet;
+
+}
+/*-- 09.12.98 12:43:24---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XTextRange >  SwXText::getStart(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< XTextCursor >  xRef = createCursor();
+    if(!xRef.is())
+    {
+        throw uno::RuntimeException();
+    }
+    xRef->gotoStart(sal_False);
+    uno::Reference< XTextRange >  xRet(xRef, uno::UNO_QUERY);
+    return xRet;
+}
+/*-- 09.12.98 12:43:27---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XTextRange >  SwXText::getEnd(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< XTextCursor >  xRef = createCursor();
+    if(!xRef.is())
+    {
+        throw uno::RuntimeException();
+    }
+    else
+        xRef->gotoEnd(sal_False);
+    uno::Reference< XTextRange >  xRet(xRef, uno::UNO_QUERY);;
+
+    return xRet;
+}
+/*-- 09.12.98 12:43:29---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+OUString SwXText::getString(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< XTextCursor >  xRet = createCursor();
+    if(!xRet.is())
+    {
+        throw uno::RuntimeException();
+    }
+    else
+    {
+        xRet->gotoEnd(sal_True);
+    }
+    return xRet->getString();
+}
+/*-- 09.12.98 12:43:30---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void SwXText::setString(const OUString& aString) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< XTextCursor >  xRet = createCursor();
+    if(!xRet.is())
+    {
+        throw uno::RuntimeException();
+    }
+    else
+    {
+        xRet->gotoEnd(sal_True);
+    }
+    xRet->setString(aString);
+}
+/* -----------------------------28.03.00 11:12--------------------------------
+    Description: Checks if pRange/pCursor are member of the same text interface.
+                Only one of the pointers has to be set!
+ ---------------------------------------------------------------------------*/
+sal_Bool    SwXText::CheckForOwnMember(
+    const SwXTextRange* pRange,
+    const SwXTextCursor* pCursor)
+        throw(IllegalArgumentException, RuntimeException)
+{
+    DBG_ASSERT((!pRange || !pCursor) && (pRange || pCursor), "only one pointer will be checked" )
+    Reference xOwnCursor = createCursor();
+
+    uno::Reference xTunnel( xOwnCursor, uno::UNO_QUERY);
+    SwXTextCursor* pOwnCursor = 0;
+    if(xTunnel.is())
+    {
+        pOwnCursor = (SwXTextCursor*)xTunnel->getSomething(SwXTextCursor::getUnoTunnelId());
+    }
+    DBG_ASSERT(pOwnCursor, "SwXTextCursor::getUnoTunnelId() ??? ")
+    const SwStartNode* pOwnStartNode = pOwnCursor->GetCrsr()->GetNode()->FindStartNode();
+    SwStartNodeType eSearchNodeType = SwNormalStartNode;
+    switch(eCrsrType)
+    {
+        case CURSOR_FRAME:      eSearchNodeType = SwFlyStartNode;       break;
+        case CURSOR_TBLTEXT:    eSearchNodeType = SwTableBoxStartNode;  break;
+        case CURSOR_FOOTNOTE:   eSearchNodeType = SwFootnoteStartNode;  break;
+        case CURSOR_HEADER:     eSearchNodeType = SwHeaderStartNode;    break;
+        case CURSOR_FOOTER:     eSearchNodeType = SwFooterStartNode;    break;
+        //case CURSOR_INVALID:
+        //case CURSOR_BODY:
+    }
+
+    const SwNode* pSrcNode;
+    if(pCursor)
+    {
+        pSrcNode = pCursor->GetCrsr()->GetNode();
+    }
+    else //dann pRange
+    {
+        SwBookmark* pBkm = pRange->GetBookmark();
+        pSrcNode = &pBkm->GetPos().nNode.GetNode();
+    }
+    const SwStartNode* pTmp = pSrcNode->FindSttNodeByType(eSearchNodeType);
+
+    //SectionNodes ueberspringen
+    while(pTmp && pTmp->IsSectionNode())
+    {
+        pTmp = pTmp->FindStartNode();
+    }
+    //if the document starts with a section
+    while(pOwnStartNode->IsSectionNode())
+    {
+        pOwnStartNode = pOwnStartNode->FindStartNode();
+    }
+    //this checks if (this) and xRange are in the same XText interface
+    return(pOwnStartNode == pTmp);
+}
+
+/* -----------------------------28.03.00 11:07--------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Int16 SwXText::ComparePositions(
+    const Reference& xPos1,
+    const Reference& xPos2)
+            throw(IllegalArgumentException, RuntimeException)
+{
+    sal_Int16 nCompare;
+    SwUnoInternalPaM aPam1(*GetDoc());
+    SwUnoInternalPaM aPam2(*GetDoc());
+
+    BOOL bExcept = FALSE;
+    if(SwXTextRange::XTextRangeToSwPaM(aPam1, xPos1) &&
+            SwXTextRange::XTextRangeToSwPaM(aPam2, xPos2))
+    {
+        uno::Reference xRangeTunnel1( xPos1, UNO_QUERY);
+        SwXTextRange* pRange1 = 0;
+        SwXTextCursor* pCursor1 = 0;
+        if(xRangeTunnel1.is())
+        {
+            pRange1 = (SwXTextRange*)xRangeTunnel1->getSomething(
+                                    SwXTextRange::getUnoTunnelId());
+            pCursor1 = (SwXTextCursor*)xRangeTunnel1->getSomething(
+                                    SwXTextCursor::getUnoTunnelId());
+        }
+        uno::Reference xRangeTunnel2( xPos2, UNO_QUERY);
+        SwXTextRange* pRange2 = 0;
+        SwXTextCursor* pCursor2 = 0;
+        if(xRangeTunnel2.is())
+        {
+            pRange2 = (SwXTextRange*)xRangeTunnel2->getSomething(
+                                    SwXTextRange::getUnoTunnelId());
+            pCursor2 = (SwXTextCursor*)xRangeTunnel2->getSomething(
+                                    SwXTextCursor::getUnoTunnelId());
+        }
+
+        if((pRange1||pCursor1) && (pRange2||pCursor2))
+        {
+            if(CheckForOwnMember(pRange1, pCursor1)
+                && CheckForOwnMember( pRange2, pCursor2))
+            {
+                const SwPosition *pStart1 = 0;
+                const SwPosition *pStart2 = 0;
+
+                if(pRange1)
+                    pStart1 = pRange1->GetBookmark() ? &pRange1->GetBookmark()->GetPos() : 0;
+                else
+                    pStart1 = pCursor1->GetPaM() ? pCursor1->GetPaM()->Start() : 0;
+
+                if(pRange2)
+                    pStart2 = pRange2->GetBookmark() ? &pRange2->GetBookmark()->GetPos() : 0;
+                else
+                    pStart2 = pCursor2->GetPaM() ? pCursor2->GetPaM()->Start() : 0;
+
+                if(pStart1 && pStart2)
+                {
+                    if(*pStart1 < *pStart2)
+                        nCompare = 1;
+                    else if(*pStart1 > *pStart2)
+                        nCompare = -1;
+                    else
+                    {
+                        DBG_ASSERT(*pStart1 == *pStart2, "SwPositions should be equal here")
+                        nCompare = 0;
+                    }
+                }
+                else
+                    bExcept = TRUE;
+            }
+            else
+                bExcept = TRUE;
+        }
+        else
+            bExcept = TRUE;
+    }
+    else
+        bExcept = TRUE;
+    if(bExcept)
+        throw IllegalArgumentException();
+
+    return nCompare;
+}
+
+/*-- 28.03.00 10:37:22---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Int16 SwXText::compareRegionStarts(
+    const Reference& xR1,
+    const Reference& xR2)
+            throw(IllegalArgumentException, RuntimeException)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!xR1.is() || !xR2.is())
+        throw IllegalArgumentException();
+    Reference xStart1 = xR1->getStart();
+    Reference xStart2 = xR2->getStart();
+
+    return ComparePositions(xStart1, xStart2);
+}
+/*-- 28.03.00 10:37:25---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+sal_Int16 SwXText::compareRegionEnds(
+    const Reference& xR1,
+    const Reference& xR2)
+                    throw(IllegalArgumentException, RuntimeException)
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(!xR1.is() || !xR2.is())
+        throw IllegalArgumentException();
+    Reference xEnd1 = xR1->getEnd();
+    Reference xEnd2 = xR2->getEnd();
+
+    return ComparePositions(xEnd1, xEnd2);
+}
+/******************************************************************
+ * SwXBodyText
+ ******************************************************************/
+SwXBodyText::SwXBodyText(SwDoc* pDoc) :
+    SwXText(pDoc, CURSOR_BODY)
+{
+}
+
+/*-- 10.12.98 11:17:27---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXBodyText::~SwXBodyText()
+{
+
+}
+/* -----------------------------06.04.00 16:33--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXBodyText::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXBodyText");
+}
+/* -----------------------------06.04.00 16:33--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXBodyText::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.text.Text") == rServiceName;
+}
+/* -----------------------------06.04.00 16:33--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXBodyText::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.Text");
+    return aRet;
+}
+/*-- 10.12.98 11:17:27---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SAL_CALL SwXBodyText::queryAggregation(
+    const uno::Type& rType )
+        throw(::com::sun::star::uno::RuntimeException)
+{
+    uno::Any aRet;
+    const uno::Type& rXEnumerationAccessType = ::getCppuType((uno::Reference< container::XEnumerationAccess >*)0);
+    const uno::Type& rXElementAccessType = ::getCppuType((uno::Reference< container::XElementAccess >*)0);
+    const uno::Type& rXServiceInfoType = ::getCppuType((uno::Reference< lang::XServiceInfo >*)0);
+
+    if(rType == rXEnumerationAccessType)
+    {
+        Reference xRet = this;
+        aRet.setValue(&xRet, rXEnumerationAccessType);
+    }
+    else if(rType == rXElementAccessType)
+    {
+        Reference xRet = this;
+        aRet.setValue(&xRet, rXElementAccessType);
+    }
+    else if(rType == rXServiceInfoType)
+    {
+        Reference xRet = this;
+        aRet.setValue(&xRet, rXServiceInfoType);
+    }
+    else
+    {
+        aRet = SwXText::queryInterface( rType );
+    }
+    if(aRet.getValueType() == ::getCppuVoidType())
+        aRet = OWeakAggObject::queryAggregation( rType );
+    return aRet;
+}
+/*-- 10.12.98 11:17:28---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Sequence< uno::Type > SAL_CALL SwXBodyText::getTypes(  ) throw(uno::RuntimeException)
+{
+    uno::Sequence< uno::Type > aTypes = SwXBodyTextBaseClass::getTypes();
+    uno::Sequence< uno::Type > aTextTypes = SwXText::getTypes();
+    long nIndex = aTypes.getLength();
+    aTypes.realloc(aTypes.getLength() + aTextTypes.getLength());
+    uno::Type* pTypes = aTypes.getArray();
+    const uno::Type* pTextTypes = aTextTypes.getConstArray();
+    for(int i = 0; i < aTextTypes.getLength(); i++)
+        pTypes[nIndex++] = pTextTypes[i];
+    return aTypes;
+}
+/* -----------------------------21.03.00 15:39--------------------------------
+
+ ---------------------------------------------------------------------------*/
+uno::Sequence< sal_Int8 > SAL_CALL SwXBodyText::getImplementationId(  ) throw(uno::RuntimeException)
+{
+    static uno::Sequence< sal_Int8 > aId( 16 );
+    static BOOL bInit = FALSE;
+    if(!bInit)
+        rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
+    return aId;
+}
+/*-- 10.12.98 11:17:28---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Any SAL_CALL
+    SwXBodyText::queryInterface( const uno::Type& rType )
+        throw(uno::RuntimeException)
+{
+      uno::Any aRet = SwXText::queryInterface( rType );
+    if(aRet.getValueType() == ::getCppuVoidType())
+        aRet = SwXBodyTextBaseClass::queryInterface( rType );
+    return aRet;
+}
+/* -----------------------------05.01.00 11:07--------------------------------
+
+ ---------------------------------------------------------------------------*/
+uno::Reference< XTextCursor >  SwXBodyText::CreateTextCursor(sal_Bool bIgnoreTables)
+{
+    uno::Reference< XTextCursor >  xRet;
+    if(IsValid())
+    {
+        SwNode& rNode = GetDoc()->GetNodes().GetEndOfContent();
+        //erstmal sicherstellen, dass wir nicht in einer Tabelle stehen
+        SwPaM aPam(rNode);
+        aPam.Move( fnMoveBackward, fnGoDoc );
+        if(!bIgnoreTables)
+        {
+            SwTableNode* pTblNode = aPam.GetNode()->FindTableNode();
+            SwCntntNode* pCont = 0;
+            while( pTblNode )
+            {
+                aPam.GetPoint()->nNode = *pTblNode->EndOfSectionNode();
+                pCont = GetDoc()->GetNodes().GoNext(&aPam.GetPoint()->nNode);
+                pTblNode = pCont->FindTableNode();
+            }
+            if(pCont)
+                aPam.GetPoint()->nContent.Assign(pCont, 0);
+        }
+        const SwStartNode* pTmp = aPam.GetNode()->FindStartNode();
+        if(pTmp->IsSectionNode())
+        {
+            SwSectionNode* pSectionStartNode = (SwSectionNode*)pTmp;
+            if(pSectionStartNode->GetSection().IsHiddenFlag())
+            {
+                SwCntntNode* pCont = GetDoc()->GetNodes().GoNextSection(
+                            &aPam.GetPoint()->nNode, sal_True, sal_False);
+                if(pCont)
+                    aPam.GetPoint()->nContent.Assign(pCont, 0);
+            }
+        }
+        xRet =  (XWordCursor*)new SwXTextCursor(this, *aPam.GetPoint(), CURSOR_BODY, GetDoc());
+    }
+    return xRet;
+}
+/*-- 10.12.98 11:17:29---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XTextCursor >  SwXBodyText::createTextCursor(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< XTextCursor >  aRef = CreateTextCursor(sal_False);
+    if(!aRef.is())
+        throw uno::RuntimeException();
+    return aRef;
+}
+/*-- 10.12.98 11:17:29---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XTextCursor >  SwXBodyText::createTextCursorByRange(
+            const uno::Reference< XTextRange > & aTextPosition) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< XTextCursor >  aRef;
+    SwUnoInternalPaM aPam(*GetDoc());
+    if(IsValid() && SwXTextRange::XTextRangeToSwPaM(aPam, aTextPosition))
+    {
+        SwNode& rNode = GetDoc()->GetNodes().GetEndOfContent();
+
+        SwStartNode* p1 = aPam.GetNode()->FindStartNode();
+        //document starts with a section?
+        while(p1->IsSectionNode())
+        {
+            p1 = p1->FindStartNode();
+        }
+        SwStartNode* p2 = rNode.FindStartNode();
+
+        if(p1 == p2)
+            aRef =  (XWordCursor*)new SwXTextCursor(this , *aPam.GetPoint(), CURSOR_BODY, GetDoc(), aPam.GetMark());
+    }
+    if(!aRef.is())
+        throw uno::RuntimeException();
+    return aRef;
+}
+/*-- 10.12.98 11:17:30---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< container::XEnumeration >  SwXBodyText::createEnumeration(void)
+                            throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< container::XEnumeration >  aRef;
+    if(IsValid())
+    {
+        SwNode& rNode = GetDoc()->GetNodes().GetEndOfContent();
+        SwPosition aPos(rNode);
+        SwUnoCrsr* pUnoCrsr = GetDoc()->CreateUnoCrsr(aPos, sal_False);
+        pUnoCrsr->Move( fnMoveBackward, fnGoDoc );
+        aRef = new SwXParagraphEnumeration(this, pUnoCrsr, CURSOR_BODY);
+    }
+    else
+        throw uno::RuntimeException();
+    return aRef;
+
+}
+/* -----------------18.12.98 13:36-------------------
+ *
+ * --------------------------------------------------*/
+uno::Type SwXBodyText::getElementType(void) throw( uno::RuntimeException )
+{
+    return ::getCppuType((uno::Reference*)0);
+}
+/* -----------------18.12.98 13:36-------------------
+ *
+ * --------------------------------------------------*/
+sal_Bool SwXBodyText::hasElements(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    if(IsValid())
+        return sal_True;
+    else
+        throw uno::RuntimeException();
+    return sal_False;
+}
+/******************************************************************
+ *  SwXHeadFootText
+ ******************************************************************/
+TYPEINIT1(SwXHeadFootText, SwClient);
+/* -----------------------------06.04.00 16:40--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SwXHeadFootText::getImplementationName(void) throw( RuntimeException )
+{
+    return C2U("SwXHeadFootText");
+}
+/* -----------------------------06.04.00 16:40--------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwXHeadFootText::supportsService(const OUString& rServiceName) throw( RuntimeException )
+{
+    return C2U("com.sun.star.text.Text") == rServiceName;
+}
+/* -----------------------------06.04.00 16:40--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > SwXHeadFootText::getSupportedServiceNames(void) throw( RuntimeException )
+{
+    Sequence< OUString > aRet(1);
+    OUString* pArray = aRet.getArray();
+    pArray[0] = C2U("com.sun.star.text.Text");
+    return aRet;
+}
+/*-- 11.12.98 10:14:48---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXHeadFootText::SwXHeadFootText(SwFrmFmt& rHeadFootFmt, BOOL bHeader) :
+    SwXText(rHeadFootFmt.GetDoc(), bHeader ? CURSOR_HEADER : CURSOR_FOOTER),
+    SwClient(&rHeadFootFmt),
+    bIsHeader(bHeader)
+{
+
+}
+/*-- 11.12.98 10:14:48---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+SwXHeadFootText::~SwXHeadFootText()
+{
+
+}
+/*-- 11.12.98 10:14:49---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XTextCursor >   SwXHeadFootText::createCursor()
+{
+    return createTextCursor();
+}
+/* -----------------------------21.03.00 15:39--------------------------------
+
+ ---------------------------------------------------------------------------*/
+uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL SwXHeadFootText::getTypes(  ) throw(uno::RuntimeException)
+{
+    uno::Sequence< uno::Type > aHFTypes = SwXHeadFootTextBaseClass::getTypes();
+    uno::Sequence< uno::Type > aTextTypes = SwXText::getTypes();
+
+    long nIndex = aHFTypes.getLength();
+    aHFTypes.realloc(
+        aHFTypes.getLength() +
+        aTextTypes.getLength());
+
+    uno::Type* pHFTypes = aHFTypes.getArray();
+    const uno::Type* pTextTypes = aTextTypes.getConstArray();
+    for(long nPos = 0; nPos < aTextTypes.getLength(); nPos++)
+        pHFTypes[nIndex++] = pTextTypes[nPos];
+
+    return aHFTypes;
+}
+
+/* -----------------------------21.03.00 15:39--------------------------------
+
+ ---------------------------------------------------------------------------*/
+uno::Sequence< sal_Int8 > SAL_CALL SwXHeadFootText::getImplementationId(  ) throw(uno::RuntimeException)
+{
+    static uno::Sequence< sal_Int8 > aId( 16 );
+    static BOOL bInit = FALSE;
+    if(!bInit)
+        rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
+    return aId;
+}
+/* -----------------------------21.03.00 15:46--------------------------------
+
+ ---------------------------------------------------------------------------*/
+uno::Any SAL_CALL SwXHeadFootText::queryInterface( const uno::Type& aType ) throw(uno::RuntimeException)
+{
+    uno::Any aRet = SwXHeadFootTextBaseClass::queryInterface(aType);
+    if(aRet.getValueType() == ::getCppuVoidType() )
+        aRet = SwXText::queryInterface(aType);
+    return aRet;
+}
+
+/*-- 11.12.98 10:14:50---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XTextCursor >  SwXHeadFootText::createTextCursor(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< XTextCursor >   xRet;
+    SwFrmFmt* pHeadFootFmt = GetFmt();
+    if(pHeadFootFmt)
+    {
+        const SwFmtCntnt& rFlyCntnt = pHeadFootFmt->GetCntnt();
+        const SwNode& rNode = rFlyCntnt.GetCntntIdx()->GetNode();
+        SwPosition aPos(rNode);
+        SwXTextCursor* pCrsr = new SwXTextCursor(this, aPos, bIsHeader ? CURSOR_HEADER : CURSOR_FOOTER, GetDoc());
+        SwUnoCrsr* pUnoCrsr = pCrsr->GetCrsr();
+        pUnoCrsr->Move(fnMoveForward, fnGoNode);
+
+        //steht hier eine Tabelle?
+        SwTableNode* pTblNode = pUnoCrsr->GetNode()->FindTableNode();
+        SwCntntNode* pCont = 0;
+        while( pTblNode )
+        {
+            pUnoCrsr->GetPoint()->nNode = *pTblNode->EndOfSectionNode();
+            pCont = GetDoc()->GetNodes().GoNext(&pUnoCrsr->GetPoint()->nNode);
+            pTblNode = pCont->FindTableNode();
+        }
+        if(pCont)
+            pUnoCrsr->GetPoint()->nContent.Assign(pCont, 0);
+
+        xRet =  (XWordCursor*)pCrsr;
+    }
+    else
+        throw uno::RuntimeException();
+    return xRet;
+}
+/*-- 11.12.98 10:14:50---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+uno::Reference< XTextCursor >  SwXHeadFootText::createTextCursorByRange(
+                const uno::Reference< XTextRange > & aTextPosition) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< XTextCursor >  xRet;
+    SwFrmFmt* pHeadFootFmt = GetFmt();
+    SwUnoInternalPaM aPam(*GetDoc());
+    if(pHeadFootFmt && SwXTextRange::XTextRangeToSwPaM(aPam, aTextPosition))
+    {
+        SwNode& rNode = pHeadFootFmt->GetCntnt().GetCntntIdx()->GetNode();
+        SwPosition aPos(rNode);
+        SwPaM aHFPam(aPos);
+        aHFPam.Move(fnMoveForward, fnGoNode);
+        SwStartNode* pOwnStartNode = aHFPam.GetNode()->FindSttNodeByType(
+                        bIsHeader ? SwHeaderStartNode : SwFooterStartNode);
+        SwStartNode* p1 = aPam.GetNode()->FindSttNodeByType(
+            bIsHeader ? SwHeaderStartNode : SwFooterStartNode);
+        if(p1 == pOwnStartNode)
+            xRet =  (XWordCursor*)new SwXTextCursor(this, *aPam.GetPoint(),
+                            bIsHeader ? CURSOR_HEADER : CURSOR_FOOTER, GetDoc(), aPam.GetMark());
+    }
+    return xRet;
+}
+/* -----------------19.03.99 15:44-------------------
+ *
+ * --------------------------------------------------*/
+uno::Reference< container::XEnumeration >  SwXHeadFootText::createEnumeration(void) throw( uno::RuntimeException )
+{
+    vos::OGuard aGuard(Application::GetSolarMutex());
+    uno::Reference< container::XEnumeration >  aRef;
+    //wenn this ungueltig ist, dann kommt die uno::Exception aus createTextCursor()
+    uno::Reference< XTextCursor >  xCrsr = createTextCursor();
+    uno::Reference< lang::XUnoTunnel > xTunnel(xCrsr, uno::UNO_QUERY);
+    SwXTextCursor* pxCrsr = (SwXTextCursor*)xTunnel->getSomething(
+                                    SwXTextCursor::getUnoTunnelId());
+    SwUnoCrsr* pUnoCrsr = pxCrsr->GetCrsr();
+    SwUnoCrsr* pNewUnoCrsr = GetDoc()->CreateUnoCrsr(*pUnoCrsr->GetPoint(), sal_False);
+    aRef = new SwXParagraphEnumeration(this, pNewUnoCrsr, bIsHeader ? CURSOR_HEADER : CURSOR_FOOTER);
+    return aRef;
+}
+/* -----------------19.03.99 15:50-------------------
+ *
+ * --------------------------------------------------*/
+uno::Type SAL_CALL SwXHeadFootText::getElementType(void) throw( uno::RuntimeException )
+{
+    return ::getCppuType((uno::Reference*)0);
+}
+/* -----------------19.03.99 15:50-------------------
+ *
+ * --------------------------------------------------*/
+sal_Bool SwXHeadFootText::hasElements(void) throw( uno::RuntimeException )
+{
+    return sal_True;
+}
+
+/*-- 11.12.98 10:14:51---------------------------------------------------
+
+  -----------------------------------------------------------------------*/
+void    SwXHeadFootText::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew)
+{
+    ClientModify( this, pOld, pNew);
+}
+
+/*------------------------------------------------------------------------
+
+    $Log: not supported by cvs2svn $
+    Revision 1.9  2000/09/18 16:04:36  willem.vandorp
+    OpenOffice header added.
+
+    Revision 1.8  2000/09/01 14:23:23  os
+    #78380# Header and footer separated
+
+    Revision 1.7  2000/08/24 15:40:28  os
+    new control character: APPEND_PARAGRAPH
+
+    Revision 1.6  2000/08/04 11:47:56  jp
+    Soft-/HardHyphens & HardBlanks changed from attribute to unicode character
+
+    Revision 1.5  2000/07/11 13:43:44  os
+    #76708# insert/remove paragraphs before/behind tables
+
+    Revision 1.4  2000/07/10 11:37:51  os
+    #76149# throw correct exception
+
+    Revision 1.3  2000/06/29 08:11:05  os
+    SwXText inherits XTypeProvider
+
+    Revision 1.2  2000/05/16 17:21:44  jp
+    Changes for Unicode
+
+    Revision 1.1  2000/05/04 15:15:05  os
+    reduce size of unoobj.cxx
+
+
+------------------------------------------------------------------------*/
+
+
diff --git a/sw/source/core/view/makefile.mk b/sw/source/core/view/makefile.mk
new file mode 100644
index 000000000000..d82555c74548
--- /dev/null
+++ b/sw/source/core/view/makefile.mk
@@ -0,0 +1,111 @@
+#*************************************************************************
+#
+#   $RCSfile: makefile.mk,v $
+#
+#   $Revision: 1.1.1.1 $
+#
+#   last change: $Author: hr $ $Date: 2000-09-19 00:08:29 $
+#
+#   The Contents of this file are made available subject to the terms of
+#   either of the following licenses
+#
+#          - GNU Lesser General Public License Version 2.1
+#          - Sun Industry Standards Source License Version 1.1
+#
+#   Sun Microsystems Inc., October, 2000
+#
+#   GNU Lesser General Public License Version 2.1
+#   =============================================
+#   Copyright 2000 by Sun Microsystems, Inc.
+#   901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+#   This library is free software; you can redistribute it and/or
+#   modify it under the terms of the GNU Lesser General Public
+#   License version 2.1, as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   Lesser General Public License for more details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+#   License along with this library; if not, write to the Free Software
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+#   MA  02111-1307  USA
+#
+#
+#   Sun Industry Standards Source License Version 1.1
+#   =================================================
+#   The contents of this file are subject to the Sun Industry Standards
+#   Source License Version 1.1 (the "License"); You may not use this file
+#   except in compliance with the License. You may obtain a copy of the
+#   License at http://www.openoffice.org/license.html.
+#
+#   Software provided under this License is provided on an "AS IS" basis,
+#   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+#   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+#   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+#   See the License for the specific provisions governing your rights and
+#   obligations concerning the Software.
+#
+#   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+#   Copyright: 2000 by Sun Microsystems, Inc.
+#
+#   All Rights Reserved.
+#
+#   Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sw
+TARGET=view
+
+AUTOSEG=true
+
+# future: DEMO\vprint.obj
+
+PROJECTPCH=core_pch
+PDBTARGET=core_pch
+PROJECTPCHSOURCE=..$/core_1st$/core_pch
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE :  $(PRJ)$/inc$/swpre.mk
+.INCLUDE :  settings.mk
+.INCLUDE :  $(PRJ)$/inc$/sw.mk
+
+.IF "$(GUI)$(COM)" == "WINMSC"
+LIBFLAGS=/NOI /NOE /PAGE:128
+.ENDIF
+
+# --- Files --------------------------------------------------------
+
+CXXFILES = \
+    scrrect.cxx \
+    vdraw.cxx \
+    viewimp.cxx \
+    viewsh.cxx \
+        viewpg.cxx \
+        vnew.cxx \
+    vprint.cxx
+
+
+
+SLOFILES =  \
+    $(SLO)$/scrrect.obj \
+    $(SLO)$/vdraw.obj \
+    $(SLO)$/viewimp.obj \
+    $(SLO)$/viewsh.obj \
+        $(SLO)$/viewpg.obj \
+        $(SLO)$/vnew.obj \
+    $(SLO)$/vprint.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE :  target.mk
+
diff --git a/sw/source/core/view/scrrect.cxx b/sw/source/core/view/scrrect.cxx
new file mode 100644
index 000000000000..353712d6bbfd
--- /dev/null
+++ b/sw/source/core/view/scrrect.cxx
@@ -0,0 +1,934 @@
+/*************************************************************************
+ *
+ *  $RCSfile: scrrect.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:29 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _VIEWIMP_HXX
+#include 
+#endif
+#ifndef _VIEWSH_HXX
+#include 
+#endif
+#ifndef _VIEWOPT_HXX
+#include 
+#endif
+#ifndef _SV_WINDOW_HXX //autogen
+#include 
+#endif
+#ifndef _SCRRECT_HXX
+#include       // SwScrollRect, SwScrollRects
+#endif
+#ifndef _TOOLS_DEBUG_HXX //autogen
+#include 
+#endif
+#ifndef _CURSOR_HXX //autogen
+#include 
+#endif
+#ifndef _SV_VIRDEV_HXX //autogen
+#include 
+#endif
+#ifndef _APP_HXX //autogen
+#include 
+#endif
+#ifndef _TXTFRM_HXX
+#include 
+#endif
+#include "crsrsh.hxx"
+#include "rootfrm.hxx"
+#include "pagefrm.hxx"
+#include "doc.hxx"
+
+DBG_NAME(RefreshTimer);
+
+//TODO: Why BRUSH_SIZE?
+#define SW_SV_BRUSH_SIZE 8
+
+SV_IMPL_VARARR(SwStripeArr,SwStripe);
+SV_IMPL_OP_PTRARR_SORT(SwScrollStripes, SwStripesPtr);
+SV_IMPL_OP_PTRARR_SORT(SScrAreas, SwScrollAreaPtr);
+
+/*****************************************************************************
+|*
+|*  ViewShell::AddScrollRect()
+|*
+|*  Creation            MA 07. Mar. 94
+|*  Last change         AMA 20. July 00
+|*
+|*  Description
+|*  ViewShell::AddScrollRect(..) passes a registration from a scrolling frame or
+|*  rectangle to all ViewShells and SwViewImps respectively.
+|*
+******************************************************************************/
+
+void ViewShell::AddScrollRect( const SwFrm *pFrm, const SwRect &rRect,
+    long nOfs )
+{
+    ASSERT( pFrm, "Where is my friend, the frame?" );
+    BOOL bScrollOn = TRUE;
+
+#ifdef NOSCROLL
+    //Auch im Product per speziellem Compilat abschaltbar.
+    bScrollOn = FALSE;
+#endif
+
+    if( bScrollOn && Imp()->IsScroll() && nOfs <= SHRT_MAX && nOfs >= SHRT_MIN )
+    {
+        ViewShell *pSh = this;
+        do
+        {
+            pSh->Imp()->AddScrollRect( pFrm, rRect, nOfs );
+            pSh = (ViewShell*)pSh->GetNext();
+        } while ( pSh != this );
+    }
+    else
+        AddPaintRect( rRect );
+}
+
+/******************************************************************************
+|*
+|*  ViewShell::Scroll()
+|*
+|*  Ersterstellung      MA 07. Mar. 94
+|*  Last change         AMA 21. July 00
+|*
+|*  Description
+|*  ViewShell::Scroll() scrolls all rectangles in the pScrollRects-list and
+|*  transfers the critical lines by calling SwViewImp::MoveScrollArea(..).
+|*
+******************************************************************************/
+
+void ViewShell::Scroll()
+{
+    SwScrollAreas *pScrollRects = Imp()->GetScrollRects();
+    if ( pScrollRects )
+    {
+        bPaintWorks = FALSE;
+        ASSERT( pScrollRects->Count(), "ScrollRects ohne ScrollRects." );
+
+        //Abgleichen der Region mit den Scroll-Bereichen!!!
+        //Wenn eines der Scroll-Rechtecke ungueltig wird, so muss
+        //der PaintMode wahrscheinlich auf PAINT_BACKGROUND umgeschaltet
+        //werden.
+
+        //Auf die Richtung kommt es an:
+        //- Bei einem pos. Ofst muss von hinten nach vorn gescrollt werden.
+        //- Bei einem neg. Ofst muss von vorn nach hinten gescrollt werden.
+        const BOOL bPositive = (*pScrollRects)[0]->GetOffs() > 0;
+
+        int i = bPositive ? pScrollRects->Count()-1 : 0;
+
+        for ( ; bPositive ? i >= 0 : i < (int)pScrollRects->Count();
+                bPositive ? --i : ++i )
+        {
+            const SwScrollArea &rScroll = *(*pScrollRects)[i];
+            if( rScroll.Count() )
+            {
+                int j = bPositive ? rScroll.Count()-1 : 0;
+                for ( ; bPositive ? j >= 0 : j < (int)rScroll.Count();
+                    bPositive ? --j : ++j )
+                {
+                    const SwStripes& rStripes = *rScroll[j];
+                      Rectangle aRectangle( rStripes.GetMin(),
+                          rStripes.GetY() - rScroll.GetOffs(),
+                          rStripes.GetRight(),
+                          rStripes.GetBottom() - rScroll.GetOffs() );
+                      GetWin()->Scroll( 0, rScroll.GetOffs(), aRectangle,
+                          SCROLL_CHILDREN);
+                      SwRect aRect( aRectangle );
+                      Imp()->ScrolledRect( aRect, rScroll.GetOffs() );
+                      if ( bPositive )
+                          aRect.Bottom( aRect.Top() + rScroll.GetOffs()-1 );
+                      else
+                          aRect.Top( aRect.Bottom() + rScroll.GetOffs() );
+                      Imp()->AddPaintRect( aRect );
+                }
+            }
+        }
+        if ( !Imp()->IsScrolled() )
+            Imp()->SetScrolled();
+
+        Imp()->MoveScrollArea();
+        bPaintWorks = TRUE;
+    }
+}
+
+/******************************************************************************
+|*
+|*  ViewShell::SetNoNextScroll()
+|*
+|*  Ersterstellung      MA 08. Mar. 94
+|*  Letzte Aenderung    MA 08. Mar. 94
+|*
+******************************************************************************/
+
+void ViewShell::SetNoNextScroll()
+{
+    ViewShell *pSh = this;
+    do
+    {   pSh->Imp()->ResetNextScroll();
+        pSh = (ViewShell*)pSh->GetNext();
+
+    } while ( pSh != this );
+}
+
+/******************************************************************************
+|*
+|*  SwViewImp::AddScrollRect()
+|*
+|*  Ersterstellung      MA 07. Mar. 94
+|*  Last change         AMA 21. July 00
+|*
+|*  Adds a scrollable rectangle and his critical lines to the list.
+|*
+******************************************************************************/
+
+void SwViewImp::AddScrollRect( const SwFrm *pFrm, const SwRect &rRect,
+    long nOffs )
+{
+    ASSERT( nOffs != 0, "Scrollen ohne Ofst." );
+    SwRect aRect( rRect );
+    aRect.Pos().Y() -= nOffs;
+    if( aRect.IsOver( pSh->VisArea() ) )
+    {
+        ASSERT( pSh->GetWin(), "Scrolling without outputdevice" );
+        aRect._Intersection( pSh->VisArea() );
+        aRect.Pos().Y() += nOffs;
+        SwStripes *pStripes = new SwStripes( aRect );
+        if( pFrm->IsTxtFrm() )
+            ((SwTxtFrm*)pFrm)->CriticalLines(*pSh->GetWin(), *pStripes, nOffs);
+        else
+            pStripes->Insert( SwStripe( aRect.Top(), aRect.Height() ), 0 );
+        if ( !pScrollRects )
+            pScrollRects = new SwScrollAreas;
+        pScrollRects->InsertCol( SwScrollColumn(pFrm->Frm(),nOffs), pStripes );
+    }
+    else
+        AddPaintRect( rRect );
+}
+
+/******************************************************************************
+|*
+|*  SwViewImp::MoveScrollArea()
+|*
+|*  Creation            AMA 10. July 00
+|*  Last change         AMA 21. July 00
+|*
+|*  Transfers the areas after scrolling to the scrolled list, but only those
+|*  parts with critical lines.
+|*
+******************************************************************************/
+
+void SwViewImp::MoveScrollArea()
+{
+    if( !pScrolledArea )
+        pScrolledArea = new SwScrollAreas;
+    for( long nIdx = 0; nIdx < pScrollRects->Count(); ++nIdx )
+    {
+        SwScrollArea *pScr = (*pScrollRects)[ nIdx ];
+        if( pScr->Compress() )
+            delete pScr;
+        else
+        {
+            USHORT nIdx;
+            if( pScrolledArea->Seek_Entry( pScr, &nIdx ) )
+                pScrolledArea->GetObject(nIdx)->Add( pScr );
+            else
+                pScrolledArea->Insert( pScr );
+        }
+    }
+    delete pScrollRects;
+    pScrollRects = NULL;
+}
+
+/******************************************************************************
+|*
+|*  SwViewImp::FlushScrolledArea()
+|*
+|*  Creation            AMA 10. July 00
+|*  Last change         AMA 21. July 00
+|*
+|*  Flushes the scrolled critical lines, that is transfer them to AddPaintRect()
+|*  and remove them from the list.
+|*
+******************************************************************************/
+
+void SwViewImp::FlushScrolledArea()
+{
+    long nCount = pScrolledArea->Count();
+    while( nCount )
+    {
+        SwScrollArea* pScroll = (*pScrolledArea)[--nCount];
+        long nCnt = pScroll->Count();
+        while( nCnt )
+        {
+            SwStripes* pStripes = (*pScroll)[--nCnt];
+            SwRect aRect( pStripes->GetMin(), 0, pStripes->GetWidth(), 0 );
+            for( long i = 0; i < pStripes->Count(); ++i )
+            {
+                aRect.Top( (*pStripes)[i].GetY() );
+                aRect.Height( (*pStripes)[i].GetHeight() );
+                AddPaintRect( aRect );
+            }
+            pScroll->Remove( nCnt );
+            delete pStripes;
+        }
+        pScrolledArea->Remove( nCount );
+        delete pScroll;
+    }
+    delete pScrolledArea;
+    pScrolledArea = NULL;
+}
+
+/******************************************************************************
+|*
+|*  SwViewImp::_FlushScrolledArea(..)
+|*
+|*  Creation            AMA 10. July 00
+|*  Last change         AMA 21. July 00
+|*
+|*  The critical lines, which overlaps with the given rectangle, will be united
+|*  with the rectangle and removed from the list.
+|*
+******************************************************************************/
+
+BOOL SwViewImp::_FlushScrolledArea( SwRect& rRect )
+{
+    long nCount = pScrolledArea->Count();
+    BOOL bRet = FALSE;
+    for( long i = pScrolledArea->Count(); i; )
+    {
+        SwScrollArea* pScroll = (*pScrolledArea)[--i];
+        for( long j = pScroll->Count(); j; )
+        {
+            SwStripes* pStripes = (*pScroll)[--j];
+            if( pStripes->Count() )
+            {
+                SwRect aRect( pStripes->GetMin(), pStripes->GetY(),
+                    pStripes->GetWidth(), pStripes->GetHeight() );
+                if( rRect.IsOver( aRect ) )
+                {
+                    for( long nI = pStripes->Count(); nI; )
+                    {
+                        aRect.Top( (*pStripes)[--nI].GetY() );
+                        aRect.Height( (*pStripes)[nI].GetHeight() );
+                        if( rRect.IsOver( aRect ) )
+                        {
+                            rRect.Union( aRect );
+                            bRet = TRUE;
+                            pStripes->Remove( nI );
+                            nI = pStripes->Count();
+                        }
+                    }
+                }
+            }
+            if( !pStripes->Count() )
+            {
+                pScroll->Remove( j );
+                delete pStripes;
+            }
+        }
+        if( !pScroll->Count() )
+        {
+            pScrolledArea->Remove( pScroll );
+            delete pScroll;
+        }
+    }
+    if( !pScrolledArea->Count() )
+    {
+        DELETEZ( pScrolledArea );
+        SetNextScroll();
+    }
+    return bRet;
+}
+
+/******************************************************************************
+|*
+|*  SwViewImp::RefreshScrolledHdl(..)
+|*
+|*  Creation            MA 06. Oct. 94
+|*  Last change         AMA 21. July 00
+|*
+|*  Every timerstop one of the critical lines will be painted.
+|*
+******************************************************************************/
+
+IMPL_LINK( SwViewImp, RefreshScrolledHdl, Timer *, EMPTYARG )
+{
+    DBG_PROFSTART( RefreshTimer );
+
+    if ( !IsScrolled() )
+    {   DBG_PROFSTOP( RefreshTimer );
+        return 0;
+    }
+
+    SET_CURR_SHELL( GetShell() );
+
+    //Kein Refresh wenn eine Selektion besteht.
+    if ( GetShell()->IsA( TYPE(SwCrsrShell) ) &&
+         (((SwCrsrShell*)GetShell())->HasSelection() ||
+          ((SwCrsrShell*)GetShell())->GetCrsrCnt() > 1))
+    {
+        DBG_PROFSTOP( RefreshTimer );
+        return 0;
+    }
+
+    if( pScrolledArea )
+    {
+        BOOL bFound = FALSE;
+        const SwRect aRect( GetShell()->VisArea() );
+        BOOL bNoRefresh = GetShell()->IsA( TYPE(SwCrsrShell) ) &&
+            ( ((SwCrsrShell*)GetShell())->HasSelection() ||
+              ((SwCrsrShell*)GetShell())->GetCrsrCnt() > 1 );
+        if( pScrolledArea->Count() )
+        {
+            SwScrollArea* pScroll = pScrolledArea->GetObject(0);
+            ASSERT( pScroll->Count(), "Empty scrollarea" );
+            SwStripes* pStripes = pScroll->GetObject(0);
+            ASSERT( pStripes->Count() > 1, "Empty scrollstripes" );
+            const SwStripe &rStripe = pStripes->GetObject(1);
+            SwRect aTmpRect( pScroll->GetX(), rStripe.GetY(),
+                             pScroll->GetWidth(), rStripe.GetHeight() );
+            if( aTmpRect.IsOver( aRect ) )
+            {
+                SwSaveHdl aSaveHdl( this );
+                 if( !bNoRefresh )
+                    _RefreshScrolledArea( aTmpRect );
+            }
+            pStripes->Remove( 1 );
+            if( pStripes->Count() < 2 )
+            {
+                pScroll->Remove( USHORT(0) );
+                delete pStripes;
+            }
+            if( !pScroll->Count() )
+            {
+                pScrolledArea->Remove( pScroll );
+                delete pScroll;
+            }
+        }
+        if( !pScrolledArea->Count() )
+        {
+            delete pScrolledArea;
+            pScrolledArea = 0;
+        }
+    }
+
+    //All done?
+    if( !pScrolledArea || !pScrolledArea->Count()
+        )
+    {
+        ResetScrolled();
+        SetNextScroll();
+        aScrollTimer.Stop();
+    }
+
+    DBG_PROFSTOP( RefreshTimer );
+    return 0;
+}
+
+/******************************************************************************
+|*
+|*  SwViewImp::_ScrolledRect(..)
+|*
+|*  Creation            AMA 20. July 00
+|*  Last change         AMA 21. July 00
+|*
+|*  handles the problem of scrolled criticals lines, when they are a part of
+|*  a scrolling area again. In this case, their rectangle has to move to the
+|*  right position.
+|*
+******************************************************************************/
+
+void SwViewImp::_ScrolledRect( const SwRect& rRect, long nOffs )
+{
+    for( long i = pScrolledArea->Count(); i; )
+    {
+        SwScrollArea* pScroll = (*pScrolledArea)[--i];
+        ASSERT( pScroll->Count() == 1, "Missing scrollarea compression 1" );
+        SwStripes* pStripes = (*pScroll)[0];
+        if( pStripes->Count() )
+        {
+            SwRect aRect( pStripes->GetMin(), pStripes->GetY(),
+                pStripes->GetWidth(), pStripes->GetHeight() );
+            if( rRect.IsOver( aRect ) )
+            {
+                BOOL bRecalc = FALSE;
+                for( long nI = pStripes->Count(); nI; )
+                {
+                    aRect.Top( (*pStripes)[--nI].GetY() );
+                    aRect.Height( (*pStripes)[nI].GetHeight() );
+                    if( rRect.IsInside( aRect ) )
+                    {
+                        (*pStripes)[nI].Y() += nOffs;
+                        bRecalc = TRUE;
+                    }
+                }
+                if( bRecalc )
+                    pStripes->Recalc();
+            }
+        }
+    }
+}
+
+/******************************************************************************
+|*
+|*  SwViewImp::_RefreshScrolledArea()
+|*
+******************************************************************************/
+
+//Berechnen der Hoehe fuer das virtuelle Device, Breite und maximaler
+//Speicherbedarf sind vorgegeben.
+#define MAXKB 180L
+
+void lcl_CalcVirtHeight( OutputDevice *pOut, Size &rSz )
+{
+    char nBytes;
+    const ULONG nColorCount = pOut->GetColorCount();
+    if( 256 >= nColorCount )                // 2^8
+        nBytes = 1;
+    else
+        if( USHRT_MAX >= nColorCount )      // 2^16
+            nBytes = 2;
+        else
+            if( 16777216 >= nColorCount )   // 2^24
+                nBytes = 3;
+            else
+                nBytes = 4;                 // 2^n
+
+    rSz = pOut->LogicToPixel( rSz );
+
+    long nKB = MAXKB * 1000;
+    nKB /= nBytes;
+    rSz.Height() = nKB / rSz.Width();
+
+    rSz = pOut->PixelToLogic( rSz );
+}
+
+void SwViewImp::_RefreshScrolledArea( const SwRect &rRect )
+{
+    SwRect aScRect( rRect );
+    aScRect.Intersection( GetShell()->VisArea() );
+
+    if( aScRect.IsEmpty() )
+        return;
+
+    BOOL bShowCrsr = FALSE;
+    Window *pWin = GetShell()->GetWin();
+    if ( pWin && pWin->GetCursor() && pWin->GetCursor()->IsVisible() )
+    {
+        bShowCrsr = TRUE;
+        pWin->GetCursor()->Hide();
+    }
+
+    //Virtuelles Device erzeugen und einstellen.
+    OutputDevice *pOld = GetShell()->GetOut();
+    VirtualDevice *pVout = new VirtualDevice( *pOld );
+    MapMode aMapMode( pOld->GetMapMode() );
+    pVout->SetMapMode( aMapMode );
+    Size aSize( aScRect.Width(), 0 );
+    lcl_CalcVirtHeight( pOld, aSize );
+    if ( aSize.Height() > aScRect.Height() )
+        aSize.Height() = aScRect.Height() + 50;
+
+    //unten in der Schleife lassen wir die Rechtecke ein wenig ueberlappen,
+    //das muss auch bei der Groesse beruecksichtigt werden.
+    aSize = pOld->LogicToPixel( aSize );
+    aSize.Width() += SW_SV_BRUSH_SIZE + 4; aSize.Height() += SW_SV_BRUSH_SIZE + 4;
+    aSize = pOld->PixelToLogic( aSize );
+
+    const SwRootFrm* pLayout = GetShell()->GetLayout();
+
+    if( pVout->SetOutputSize( aSize ) )
+    {
+        pVout->SetLineColor( pOld->GetLineColor() );
+        pVout->SetFillColor( pOld->GetFillColor() );
+
+        //Virtuelles Device in die ViewShell 'selektieren'
+        GetShell()->pOut = pVout;
+
+        const SwFrm *pPg = GetFirstVisPage();
+        do
+        {
+            SwRect aRect( pPg->Frm() );
+            if ( aRect.IsOver( aScRect ) )
+            {
+                aRect._Intersection( aScRect );
+                do
+                {   Rectangle aTmp( aRect.SVRect() );
+                    long nTmp = aTmp.Top() + aSize.Height();
+                    if ( aTmp.Bottom() > nTmp )
+                        aTmp.Bottom() = nTmp;
+
+                    aTmp = pOld->LogicToPixel( aTmp );
+                    aTmp.Top()  -= 2; aTmp.Bottom() += 2;
+                    aTmp.Left() -= 2; aTmp.Right()  += 2;
+                    aTmp.Left() -= aTmp.Left() % SW_SV_BRUSH_SIZE;
+                    aTmp.Top()  -= aTmp.Top()  % SW_SV_BRUSH_SIZE;
+                    aTmp = pOld->PixelToLogic( aTmp );
+                    SwRect aTmp2( aTmp );
+
+                    Point aOrigin( aTmp2.Pos() );
+                    aOrigin.X() = -aOrigin.X(); aOrigin.Y() = -aOrigin.Y();
+                    aMapMode.SetOrigin( aOrigin );
+                    pVout->SetMapMode( aMapMode );
+
+                    pLayout->Paint( aTmp2 );
+                    pOld->DrawOutDev( aTmp2.Pos(), aTmp2.SSize(),
+                                      aTmp2.Pos(), aTmp2.SSize(), *pVout );
+
+                    aRect.Top( aRect.Top() + aSize.Height() );
+                    aScRect.Top( aRect.Top() );
+
+                } while ( aRect.Height() > 0 );
+            }
+            pPg = pPg->GetNext();
+
+        } while ( pPg && pPg->Frm().IsOver( GetShell()->VisArea() ) );
+
+        GetShell()->pOut = pOld;
+        delete pVout;
+        if( GetShell()->GetViewOptions()->IsControl() )
+            PaintLayer( GetShell()->GetDoc()->GetControlsId(), aScRect );
+    }
+    else
+    {
+        delete pVout;
+        pLayout->Paint( aScRect );
+    }
+
+    if ( bShowCrsr )
+        pWin->GetCursor()->Show();
+}
+
+/******************************************************************************
+|*
+|*  SwViewImp::RefreshScrolledArea()
+|*
+|*  Ersterstellung      MA 06. Oct. 94
+|*  Letzte Aenderung    MA 19. Apr. 95
+|*
+******************************************************************************/
+
+void SwViewImp::RefreshScrolledArea( SwRect &rRect )
+{
+    //1. Wird auch von der CrsrShell gerufen, um ggf. den Bereich, in den der
+    //Crsr gesetzt wird (Absatz, ganze Zeile bei einer Tabelle) aufzufrischen.
+    //Allerdings kann es dann natuerlich sein, dass das Rechteck ueberhaupt
+    //nicht mit aufzufrischenden Bereichen ueberlappt.
+    //2. Kein Refresh wenn eine Selektion besteht.
+    if( (GetShell()->IsA( TYPE(SwCrsrShell) ) &&
+          (((SwCrsrShell*)GetShell())->HasSelection() ||
+           ((SwCrsrShell*)GetShell())->GetCrsrCnt() > 1)))
+    {
+        return;
+    }
+
+    if( pScrolledArea && pScrolledArea->Count() &&
+        !( ( GetShell()->IsA( TYPE(SwCrsrShell) ) &&
+        ( ((SwCrsrShell*)GetShell())->HasSelection() ||
+          ((SwCrsrShell*)GetShell())->GetCrsrCnt() > 1) ) ) )
+    {
+        for( long i = pScrolledArea->Count(); i; )
+        {
+            SwScrollArea* pScroll = (*pScrolledArea)[--i];
+            for( long j = pScroll->Count(); j; )
+            {
+                SwStripes* pStripes = (*pScroll)[--j];
+                if( pStripes->Count() )
+                {
+                    SwRect aRect( pStripes->GetMin(), pStripes->GetY(),
+                        pStripes->GetWidth(), pStripes->GetHeight() );
+                    if( rRect.IsOver( aRect ) )
+                    {
+                        for( long nI = pStripes->Count(); nI; )
+                        {
+                            aRect.Top( (*pStripes)[--nI].GetY() );
+                            aRect.Height( (*pStripes)[nI].GetHeight() );
+                            if( rRect.IsOver( aRect ) )
+                            {
+                                pStripes->Remove( nI );
+                                _RefreshScrolledArea( aRect );
+                            }
+                        }
+                    }
+                }
+                if( !pStripes->Count() )
+                {
+                    pScroll->Remove( j );
+                    delete pStripes;
+                }
+            }
+            if( !pScroll->Count() )
+            {
+                pScrolledArea->Remove( pScroll );
+                delete pScroll;
+            }
+            //Ist da jemand ungeduldig?
+            //Nur Mouse und Keyboard, weil wir sonst von jeder billigen
+            //Uhr unterbrochen werden.
+            if( GetpApp()->AnyInput( INPUT_MOUSEANDKEYBOARD ) )
+                break;
+        }
+    }
+
+    //All done?
+    if( !pScrolledArea || !pScrolledArea->Count() )
+    {
+        ResetScrolled();
+        SetNextScroll();
+        aScrollTimer.Stop();
+    }
+}
+
+SwStripes& SwStripes::operator+=( const SwStripes& rOther )
+{
+    if( !Count() )
+    {
+        Insert( &rOther, 0 );
+        SetMin( rOther.GetMin() );
+        SetMax( rOther.GetMax() );
+        return *this;
+    }
+
+    long nCnt = rOther.Count();
+    if( nCnt )
+    {
+        ChkMin( rOther.GetMin() );
+        ChkMax( rOther.GetMax() );
+        USHORT nStart = 0;
+        for( long nIdx = 0; nIdx < nCnt; ++nIdx )
+        {
+            const SwStripe& rAdd = rOther[ nIdx ];
+            long nBottom = rAdd.GetY() + rAdd.GetHeight();
+            USHORT nCount = Count();
+            USHORT nY = nStart;
+            while( nY < nCount )
+            {
+                SwStripe& rChk = GetObject( nY );
+                if( rChk.GetY() + rChk.GetHeight() > rAdd.GetY() )
+                    break;
+                else
+                    ++nY;
+            }
+            USHORT nB = nY;
+            while( nB < nCount )
+            {
+                const SwStripe& rChk = GetObject( nB );
+                if( rChk.GetY() >= nBottom )
+                    break;
+                else
+                    ++nB;
+            }
+            nStart = nY;
+            if( nY == nB )
+                Insert( rAdd, nY );
+            else
+            {
+                long nChkBottom = rAdd.GetY() + rAdd.GetHeight();;
+                const SwStripe& rChkB = GetObject( nB - 1 );
+                long nTmp = rChkB.GetY() + rChkB.GetHeight();
+                if( nTmp > nChkBottom )
+                    nChkBottom = nTmp;
+                SwStripe& rChk = GetObject( nY );
+                if( rAdd.GetY() < rChk.GetY() )
+                    rChk.Y() = rAdd.GetY();
+                rChk.Height() = nChkBottom - rChk.GetY();
+                nChkBottom = nB - nY - 1;
+                if( nChkBottom )
+                    Remove( nY + 1, nChkBottom );
+            }
+        }
+    }
+    return *this;
+}
+
+BOOL SwStripes::Recalc()
+{
+    if( !Count() )
+        return TRUE;
+    Y() = GetObject(0).GetY();
+    long nTmpMax = GetObject(0).GetY() + GetObject(0).Height();
+    for( long nIdx = 1; nIdx < Count(); )
+    {
+        const SwStripe& rStr = GetObject(nIdx++);
+        if( GetY() > rStr.GetY() )
+            Y() = rStr.GetY();
+        if( nTmpMax < rStr.GetY() + rStr.GetHeight() )
+            nTmpMax = rStr.GetY() + rStr.GetHeight();
+    }
+    Height() = nTmpMax - GetY();
+    return FALSE;
+}
+
+BOOL SwScrollArea::Compress()
+{
+    if( !Count() )
+        return TRUE;
+    for( long nIdx = Count() - 1; nIdx > 0; --nIdx )
+    {
+        *GetObject(0) += *GetObject(nIdx);
+        delete GetObject( nIdx );
+        Remove( nIdx, 1 );
+    }
+    ClrOffs();
+    return GetObject(0)->Recalc();
+}
+
+void SwScrollArea::Add( SwScrollArea *pScroll )
+{
+    ASSERT( pScroll->Count() == 1, "Missing scrollarea compression 2" );
+    ASSERT( Count() == 1, "Missing scrollarea compression 3" );
+    *GetObject(0) += *pScroll->GetObject(0);
+    GetObject(0)->Recalc();
+    delete pScroll->GetObject( 0 );
+    pScroll->Remove( (USHORT)0, 1 );
+    delete pScroll;
+}
+
+/******************************************************************************
+|*
+|*  SwScrollAreas::Insert(..)
+|*
+******************************************************************************/
+
+void SwScrollAreas::InsertCol( const SwScrollColumn &rCol,
+                            SwStripes *pStripes )
+{
+    SwScrollArea *pTmp = new SwScrollArea( rCol, pStripes );
+    USHORT nIdx;
+    if( Seek_Entry( pTmp, &nIdx ) )
+        GetObject( nIdx )->SmartInsert( pStripes );
+    else
+        Insert( pTmp );
+}
+
+
+void SwScrollArea::SmartInsert( SwStripes* pStripes )
+{
+    ASSERT( pStripes, "Insert empty scrollstripe?" );
+    BOOL bNotInserted = TRUE;
+    for( long nIdx = 0; nIdx < Count() && bNotInserted; )
+    {
+        SwStripes* pTmp = GetObject( nIdx++ );
+        if( pTmp->GetY() + pTmp->GetHeight() == pStripes->GetY() )
+        {
+            pTmp->Height() += pStripes->GetHeight();
+            pTmp->ChkMin( pStripes->GetMin() );
+            pTmp->ChkMax( pStripes->GetMax() );
+            if( pStripes->Count() )
+                pTmp->Insert( (SwStripeArr*)pStripes, pTmp->Count(), 0 );
+            bNotInserted = FALSE;
+        }
+        else if( pTmp->GetY() == pStripes->GetY() + pStripes->GetHeight() )
+        {
+            pTmp->Height() += pStripes->GetHeight();
+            pTmp->Y() = pStripes->GetY();
+            pTmp->ChkMin( pStripes->GetMin() );
+            pTmp->ChkMax( pStripes->GetMax() );
+            if( pStripes->Count() )
+                pTmp->Insert( (SwStripeArr*)pStripes, 0, 0 );
+            bNotInserted = FALSE;
+        }
+    }
+    if( !bNotInserted || !Insert( pStripes ) )
+        delete pStripes;
+}
+
+/************************************************************************
+
+      $Log: not supported by cvs2svn $
+      Revision 1.10  2000/09/18 16:04:37  willem.vandorp
+      OpenOffice header added.
+
+      Revision 1.9  2000/09/05 08:07:52  ama
+      Fix: Wrong insert position
+
+      Revision 1.8  2000/09/04 13:58:17  ama
+      Fix: some paint problems with negative indents
+
+      Revision 1.7  2000/09/01 15:02:04  ama
+      Opt.: Scrolling, paints and negative indents
+
+      Revision 1.6  2000/08/17 11:26:05  ama
+      Fix #77608#: Scrolling bugs
+
+      Revision 1.5  2000/07/21 11:47:53  ama
+      Opt: some comment may be helpful
+
+      Revision 1.4  2000/07/20 15:09:13  ama
+      Fix #77064#: Wrong paintarea
+
+      Revision 1.3  2000/07/18 15:17:13  ama
+      Fix: InsertCol instead insert
+
+      Revision 1.2  2000/07/18 14:37:51  ama
+      Fix: Scrolling of scrolled critical areas
+
+      Revision 1.1  2000/07/17 10:32:09  ama
+      Opt: Smarter scrolling for RVP
+
+
+*************************************************************************/
+
diff --git a/sw/source/core/view/vdraw.cxx b/sw/source/core/view/vdraw.cxx
new file mode 100644
index 000000000000..d20aad611be6
--- /dev/null
+++ b/sw/source/core/view/vdraw.cxx
@@ -0,0 +1,606 @@
+/*************************************************************************
+ *
+ *  $RCSfile: vdraw.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:29 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _SVDMODEL_HXX //autogen
+#include 
+#endif
+#ifndef _SVDPAGE_HXX //autogen
+#include 
+#endif
+#ifndef _XOUTX_HXX //autogen
+#include 
+#endif
+
+#ifndef _SVDPAGV_HXX //autogen
+#include 
+#endif
+
+#ifndef _FMTANCHR_HXX //autogen
+#include 
+#endif
+#ifndef _FRMFMT_HXX //autogen
+#include 
+#endif
+
+#ifndef PRODUCT
+#ifndef _SVX_FMGLOB_HXX
+#include 
+#endif
+#endif
+
+#include "fesh.hxx"
+#include "doc.hxx"
+#include "pagefrm.hxx"
+#include "rootfrm.hxx"
+#include "viewimp.hxx"
+#include "dflyobj.hxx"
+#include "viewopt.hxx"
+#include "dcontact.hxx"
+#include "dview.hxx"
+#include "flyfrm.hxx"
+#include "frmtool.hxx"
+
+
+/*************************************************************************
+|*
+|*  SwSaveHdl
+|*
+|*  Ersterstellung      MA 14. Feb. 95
+|*  Letzte Aenderung    MA 02. Jun. 98
+|*
+|*************************************************************************/
+SwSaveHdl::SwSaveHdl( SwViewImp *pI ) :
+    pImp( pI ),
+    bXorVis( FALSE )
+{
+    if ( pImp->HasDrawView() )
+    {
+        bXorVis = pImp->GetDrawView()->IsShownXorVisible( pImp->GetShell()->GetOut());
+        if ( bXorVis )
+            pImp->GetDrawView()->HideShownXor( pImp->GetShell()->GetOut() );
+    }
+}
+
+
+SwSaveHdl::~SwSaveHdl()
+{
+    if ( bXorVis )
+        pImp->GetDrawView()->ShowShownXor( pImp->GetShell()->GetOut() );
+}
+
+
+/*************************************************************************
+|*
+|*  SwViewImp::StartAction(), EndAction()
+|*
+|*  Ersterstellung      MA 14. Feb. 95
+|*  Letzte Aenderung    MA 14. Sep. 98
+|*
+|*************************************************************************/
+
+
+void SwViewImp::StartAction()
+{
+    if ( HasDrawView() )
+    {
+        SET_CURR_SHELL( GetShell() );
+        if ( pSh->ISA(SwFEShell) )
+            ((SwFEShell*)pSh)->HideChainMarker();   //Kann sich geaendert haben
+        bResetXorVisibility = GetDrawView()->IsShownXorVisible( GetShell()->GetOut());
+        GetDrawView()->HideShownXor( GetShell()->GetOut() );
+    }
+}
+
+
+
+void SwViewImp::EndAction()
+{
+    if ( HasDrawView() )
+    {
+        SET_CURR_SHELL( GetShell() );
+        if ( bResetXorVisibility )
+            GetDrawView()->ShowShownXor( GetShell()->GetOut() );
+        if ( pSh->ISA(SwFEShell) )
+            ((SwFEShell*)pSh)->SetChainMarker();    //Kann sich geaendert haben
+    }
+}
+
+/*************************************************************************
+|*
+|*  SwViewImp::LockPaint(), UnlockPaint()
+|*
+|*  Ersterstellung      MA 11. Jun. 96
+|*  Letzte Aenderung    MA 11. Jun. 96
+|*
+|*************************************************************************/
+
+
+void SwViewImp::LockPaint()
+{
+    if ( HasDrawView() )
+    {
+        bShowHdlPaint = GetDrawView()->IsMarkHdlShown();
+        if ( bShowHdlPaint )
+            GetDrawView()->HideMarkHdl( GetShell()->GetOut() );
+        bResetHdlHiddenPaint = !GetDrawView()->IsMarkHdlHidden();
+        GetDrawView()->SetMarkHdlHidden( TRUE );
+    }
+    else
+    {
+        bShowHdlPaint = FALSE;
+        bResetHdlHiddenPaint = FALSE;
+    }
+}
+
+
+
+void SwViewImp::UnlockPaint()
+{
+    if ( bResetHdlHiddenPaint )
+        GetDrawView()->SetMarkHdlHidden( FALSE );
+    if ( bShowHdlPaint )
+        GetDrawView()->ShowMarkHdl( GetShell()->GetOut() );
+}
+
+
+/*************************************************************************
+|*
+|*  SwViewImp::PaintLayer(), PaintDispatcher()
+|*
+|*  Ersterstellung      MA 20. Dec. 94
+|*  Letzte Aenderung    AMA 04. Jun. 98
+|*
+|*************************************************************************/
+
+
+void SwViewImp::PaintLayer( const BYTE nLayerID, const SwRect &rRect ) const
+{
+    Link aLnk( LINK( this, SwViewImp, PaintDispatcher ) );
+    if ( HasDrawView() )
+    {
+        GetPageView()->RedrawOneLayer( nLayerID, rRect.SVRect(),
+                        GetShell()->GetOut(),
+                        GetShell()->IsPreView() ? SDRPAINTMODE_ANILIKEPRN : 0,
+                        &aLnk );
+    }
+}
+
+
+IMPL_LINK( SwViewImp, PaintDispatcher, SdrPaintProcRec *, pRec )
+{
+    SdrObject *pObj = pRec->pObj;
+
+    //Controls muessen im Control-Layer liegen. Dort duerfen aber auch
+    //Gruppenobjekte oder mit Controls gruppierte Objekte liegen.
+    ASSERT( FmFormInventor != pObj->GetObjInventor() ||
+            GetShell()->GetDoc()->GetControlsId() == pObj->GetLayer(),
+            "PaintDispatcher: Wrong Layer" );
+
+    if ( !SwFlyFrm::IsPaint( pObj, GetShell() ) )
+        return 0;
+
+    const BYTE nHellId = GetShell()->GetDoc()->GetHellId();
+    if ( pObj->IsWriterFlyFrame() )
+    {
+        if( pObj->GetLayer() == nHellId )
+        {
+            //Fuer Rahmen in der Hoelle gelten andere Regeln:
+            //1. Rahmen mit einem Parent werden nie direkt, sondern von ihren
+            //   Parents gepaintet.
+            //1a.Es sei denn, der Parent steht nicht in der Hoelle.
+            //2. Rahmen mit Childs painten zuerst die Childs in
+            //   umgekehrter Z-Order.
+            SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+            const FASTBOOL bInFly = pFly->GetAnchor()->IsInFly();
+            if ( !bInFly ||
+                 (bInFly && pFly->GetAnchor()->FindFlyFrm()->
+                                   GetVirtDrawObj()->GetLayer() != nHellId))
+                PaintFlyChilds( pFly, pRec->rOut, pRec->rInfoRec );
+        }
+        else
+            pObj->Paint( pRec->rOut, pRec->rInfoRec );
+    }
+    else
+    {
+        SwRect aTmp( pRec->rInfoRec.aDirtyRect );
+        ::InvertSizeBorderRect( aTmp, GetShell() );
+
+        OutputDevice *pOut = pRec->rOut.GetOutDev();
+        pOut->Push( PUSH_CLIPREGION );
+        pOut->IntersectClipRegion( aTmp.SVRect() );
+
+        //Um zu verhindern, dass der Dispatcher fr jedes Gruppenobjekt
+        //gerufen wird, muessen wir die Struktur manipulieren
+        //(Absprache mit JOE).
+        const Link *pSave = 0;
+        if ( pObj->IsGroupObject() )
+        {
+            pSave = pRec->rInfoRec.pPaintProc;
+            ((SdrPaintInfoRec&)pRec->rInfoRec).pPaintProc = 0;
+        }
+
+        pObj->Paint( pRec->rOut, pRec->rInfoRec );
+
+        if ( pSave )
+            ((SdrPaintInfoRec&)pRec->rInfoRec).pPaintProc = pSave;
+
+        pOut->Pop();
+    }
+    return 0;
+}
+
+/*************************************************************************
+|*
+|*  SwViewImp::PaintFlyChilds()
+|*
+|*  Ersterstellung      MA ??
+|*  Letzte Aenderung    MA 02. Aug. 95
+|*
+|*************************************************************************/
+
+
+void SwViewImp::PaintFlyChilds( SwFlyFrm *pFly, ExtOutputDevice& rOut,
+                                 const SdrPaintInfoRec& rInfoRec )
+{
+    SdrObject *pFlyObj  = pFly->GetVirtDrawObj();
+    SdrPage   *pPage = pFlyObj->GetPage();
+    OutputDevice *pOut = rOut.GetOutDev();
+
+    //Zuerst den am weitesten oben liegenden Child suchen.
+    ULONG i;
+    for ( i = pFlyObj->GetOrdNumDirect()+1; i < pPage->GetObjCount(); ++i )
+    {
+        SdrObject *pObj = pPage->GetObj( i );
+        SwFlyFrm *pF;
+        if ( pObj->IsWriterFlyFrame() )
+            pF = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+        else
+        {
+            SwFrm *pFrm = ((SwDrawContact*)GetUserCall(pObj))->GetAnchor();
+            pF = pFrm ? pFrm->FindFlyFrm() : 0;
+        }
+        if ( pF && pF != pFly && !pF->IsLowerOf( pFly ) )
+            break;
+    }
+    --i;    //Ich bin auf immer einen zu weit gelaufen.
+    if ( i != pFlyObj->GetOrdNumDirect() )
+    {
+        for ( UINT32 j = i; j > pFlyObj->GetOrdNumDirect(); --j )
+        {
+            SdrObject *pObj = pPage->GetObj( j );
+            if ( pObj->IsWriterFlyFrame() )
+            {
+                SwFlyFrm *pF = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+                if ( pF->GetAnchor()->FindFlyFrm() == pFly )
+                    PaintFlyChilds( pF, rOut, rInfoRec );
+            }
+            else
+            {
+                SwFrm *pFrm = ((SwDrawContact*)GetUserCall(pObj))->GetAnchor();
+                if( pFrm && pFrm->FindFlyFrm() == pFly )
+                {
+                    pOut->Push( PUSH_LINECOLOR );
+                    pObj->Paint( rOut, rInfoRec );
+                    pOut->Pop();
+                }
+            }
+        }
+    }
+    pFlyObj->Paint( rOut, rInfoRec );
+}
+
+/*************************************************************************
+|*
+|*  SwViewImp::IsDragPossible()
+|*
+|*  Ersterstellung      MA 19. Jan. 93
+|*  Letzte Aenderung    MA 16. Jan. 95
+|*
+|*************************************************************************/
+
+
+
+#define WIEDUWILLST 400
+
+BOOL SwViewImp::IsDragPossible( const Point &rPoint )
+{
+    if ( !HasDrawView() )
+        return FALSE;
+
+    const SdrMarkList &rMrkList = GetDrawView()->GetMarkList();
+
+    if( !rMrkList.GetMarkCount() )
+        return FALSE;
+
+    SdrObject *pO = rMrkList.GetMark(rMrkList.GetMarkCount()-1)->GetObj();
+
+    SwRect aRect;
+    if( ::CalcClipRect( pO, aRect, FALSE ) )
+    {
+        SwRect aTmp;
+        ::CalcClipRect( pO, aTmp, TRUE );
+        aRect.Union( aTmp );
+    }
+    else
+        aRect = GetShell()->GetLayout()->Frm();
+
+    aRect.Top(    aRect.Top()    - WIEDUWILLST );
+    aRect.Bottom( aRect.Bottom() + WIEDUWILLST );
+    aRect.Left(   aRect.Left()   - WIEDUWILLST );
+    aRect.Right(  aRect.Right()  + WIEDUWILLST );
+    return aRect.IsInside( rPoint );
+}
+
+/*************************************************************************
+|*
+|*  SwViewImp::NotifySizeChg()
+|*
+|*  Ersterstellung      MA 23. Jun. 93
+|*  Letzte Aenderung    MA 05. Oct. 98
+|*
+|*************************************************************************/
+
+void SwViewImp::NotifySizeChg( const Size &rNewSz )
+{
+    if ( !HasDrawView() )
+        return;
+
+    if ( GetPageView() )
+        GetPageView()->GetPage()->SetSize( rNewSz );
+
+    //Begrenzung des Arbeitsbereiches.
+    Rectangle aRect( Point( DOCUMENTBORDER, DOCUMENTBORDER ), rNewSz );
+    const Rectangle &rOldWork = GetDrawView()->GetWorkArea();
+    BOOL bCheckDrawObjs = FALSE;
+    if ( aRect != rOldWork )
+    {
+        if ( rOldWork.Bottom() > aRect.Bottom() || rOldWork.Right() > aRect.Right())
+            bCheckDrawObjs = TRUE;
+        GetDrawView()->SetWorkArea( aRect );
+    }
+    if ( !bCheckDrawObjs )
+        return;
+
+    ASSERT( pSh->GetDoc()->GetDrawModel(), "NotifySizeChg without DrawModel" );
+    SdrPage* pPage = pSh->GetDoc()->GetDrawModel()->GetPage( 0 );
+    const ULONG nObjs = pPage->GetObjCount();
+    for( ULONG nObj = 0; nObj < nObjs; ++nObj )
+    {
+        SdrObject *pObj = pPage->GetObj( nObj );
+        if( !pObj->IsWriterFlyFrame() )
+        {
+            //Teilfix(26793): Objekte, die in Rahmen verankert sind, brauchen
+            //nicht angepasst werden.
+            const SwDrawContact *pCont = (SwDrawContact*)GetUserCall(pObj);
+            //JP - 16.3.00 Bug 73920: this function might be called by the
+            //              InsertDocument, when a PageDesc-Attribute is
+            //              set on a node. Then the SdrObject must not have
+            //              an UserCall.
+            if( !pCont )
+                continue;
+
+            ASSERT( pCont->ISA(SwDrawContact), "DrawObj, wrong UserCall" );
+            const SwFrm *pAnchor = pCont->GetAnchor();
+            if ( !pAnchor || pAnchor->IsInFly() || !pAnchor->IsValid() ||
+                 !pAnchor->GetUpper() ||
+                 FLY_IN_CNTNT == pCont->GetFmt()->GetAnchor().GetAnchorId() )
+                continue;
+
+            const Rectangle aBound( pObj->GetBoundRect() );
+            if ( !aRect.IsInside( aBound ) )
+            {
+                Size aSz;
+                if ( aBound.Left() > aRect.Right() )
+                    aSz.Width() = (aRect.Right() - aBound.Left()) - MINFLY;
+                if ( aBound.Top() > aRect.Bottom() )
+                    aSz.Height() = (aRect.Bottom() - aBound.Top()) - MINFLY;
+                if ( aSz.Width() || aSz.Height() )
+                    pObj->Move( aSz );
+
+                //Notanker: Grosse Objekte nicht nach oben verschwinden lassen.
+                aSz.Width() = aSz.Height() = 0;
+                if ( aBound.Bottom() < aRect.Top() )
+                    aSz.Width() = (aBound.Bottom() - aRect.Top()) - MINFLY;
+                if ( aBound.Right() < aRect.Left() )
+                    aSz.Height() = (aBound.Right() - aRect.Left()) - MINFLY;
+                if ( aSz.Width() || aSz.Height() )
+                    pObj->Move( aSz );
+            }
+        }
+    }
+}
+
+/****************************************************************************
+
+    $Log: not supported by cvs2svn $
+    Revision 1.117  2000/09/18 16:04:37  willem.vandorp
+    OpenOffice header added.
+
+    Revision 1.116  2000/03/16 21:27:20  jp
+    Bug #73920#: NotifySizeChg - SdrObject UserCall pointer can be zero
+
+    Revision 1.115  1999/09/09 15:04:06  hr
+    #65293#: added missing closing brace
+
+    Revision 1.114  1999/09/06 13:18:48  aw
+    changes due to support of new handles
+
+
+      Rev 1.112   13 Aug 1999 15:11:36   MA
+   adoption to new markers, but still inkomplete
+
+      Rev 1.111   23 Jul 1999 16:19:22   AW
+   changes for new markers
+
+      Rev 1.110   06 Jul 1999 19:11:22   JP
+   Bug #67439#: PaintFlyChilds - check for null pointer
+
+      Rev 1.109   08 Mar 1999 16:59:10   MA
+   #62907# Notify noch ein wenig toleranter
+
+      Rev 1.108   22 Feb 1999 08:35:12   MA
+   1949globale Shell entsorgt, Shells am RootFrm
+
+      Rev 1.107   07 Jan 1999 11:32:32   AMA
+   Fix #60246#: Linienstyle restaurieren
+
+      Rev 1.106   12 Nov 1998 14:17:24   MA
+   #59385# XOR und UserMarker bekommen die nie richtig hin
+
+      Rev 1.105   22 Oct 1998 14:00:14   MA
+   #58316# Assertion richtig formuliert
+
+      Rev 1.104   05 Oct 1998 11:09:18   MA
+   #67489# Keine Objekte clippen wenn der Anker nicht Valid ist
+
+      Rev 1.103   14 Sep 1998 13:49:00   MA
+   #56335# ChainMarker
+
+      Rev 1.102   29 Jun 1998 11:14:56   MA
+   Push/Pop au fVCL umgestellt
+
+      Rev 1.101   15 Jun 1998 11:04:10   AMA
+   Chg: Gruppenobjekte duerfen jetzt bearbeitet werden => GetUserCall-Umbau
+
+      Rev 1.100   10 Jun 1998 17:39:40   AMA
+   New: SdrUnoObj statt VControls
+
+      Rev 1.99   04 Jun 1998 18:21:26   AMA
+   Chg: UNO-Controls jetzt im eigenen Drawing-Layer
+
+      Rev 1.98   03 Jun 1998 09:25:24   MA
+   #50392# Handles und Xor aufgeraeumt
+
+      Rev 1.97   21 Nov 1997 15:59:48   TJ
+   include fuer SdrPageView
+
+      Rev 1.96   20 Nov 1997 12:37:30   MA
+   includes
+
+      Rev 1.95   03 Nov 1997 13:07:32   MA
+   precomp entfernt
+
+      Rev 1.94   29 Oct 1997 11:04:14   MA
+   opt: Link auf Dispatcher bei Gruppenobjekten temporaer entfernen
+
+      Rev 1.93   13 Oct 1997 10:30:36   MA
+   Umbau/Vereinfachung Paint
+
+      Rev 1.92   18 Aug 1997 10:37:06   OS
+   includes
+
+      Rev 1.91   15 Aug 1997 12:24:08   OS
+   charatr/frmatr/txtatr aufgeteilt
+
+      Rev 1.90   14 Apr 1997 11:30:32   MH
+   add: header
+
+      Rev 1.89   04 Apr 1997 16:55:00   MA
+   opt+includes
+
+      Rev 1.88   25 Feb 1997 08:45:44   MA
+   chg: SolidHdl ueberm Berg
+
+      Rev 1.87   16 Jan 1997 17:34:36   MA
+   chg: Paint oder nicht sagt uns jetzt SwFlyFrm::IsPaint
+
+      Rev 1.86   02 Dec 1996 19:38:52   MA
+   #33918#
+
+      Rev 1.85   02 Dec 1996 16:57:32   MA
+   #33630# PaintMode fuer PreView
+
+      Rev 1.84   02 Dec 1996 09:18:38   NF
+   PaintFlyChild() ohne BOOL-Parameter...
+
+      Rev 1.83   25 Nov 1996 12:09:26   MA
+   fix: PaintFlyChilds, keinen auslassen
+
+      Rev 1.82   20 Nov 1996 19:42:38   MA
+   #33447# Paint auf Background schalten wenn Zeichenobjekte im Spiel sind
+
+      Rev 1.81   20 Nov 1996 18:26:50   MA
+   BorderRect wieder herausrechnen fuer Zeichenobj
+
+      Rev 1.80   08 Nov 1996 13:00:14   HJS
+   include w.g. positivdefine
+
+      Rev 1.79   04 Nov 1996 20:01:36   MA
+   #32989#
+
+      Rev 1.78   25 Sep 1996 12:55:04   AMA
+   Opt: ::CalcClipRect-Methode statt aClipMove/aClipStretch-Member
+
+      Rev 1.77   25 Sep 1996 10:07:04   MA
+   fix: CurShell setzen
+
+      Rev 1.76   09 Sep 1996 09:55:56   MA
+   opt: Protect vom DrawObj
+
+**************************************************************************/
+
+
diff --git a/sw/source/core/view/viewimp.cxx b/sw/source/core/view/viewimp.cxx
new file mode 100644
index 000000000000..d8ef959f39b2
--- /dev/null
+++ b/sw/source/core/view/viewimp.cxx
@@ -0,0 +1,478 @@
+/*************************************************************************
+ *
+ *  $RCSfile: viewimp.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:29 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "scrrect.hxx"
+#include "doc.hxx"
+#include "crsrsh.hxx"
+#include "rootfrm.hxx"
+#include "pagefrm.hxx"
+#include "viewimp.hxx"
+#include "errhdl.hxx"
+#include "viewopt.hxx"
+#include "flyfrm.hxx"
+#include "frmfmt.hxx"
+#include "layact.hxx"
+#include "swregion.hxx"
+#include "dflyobj.hxx"
+#include "dview.hxx"
+
+#ifndef _SVDPAGE_HXX //autogen
+#include 
+#endif
+
+/*************************************************************************
+|*
+|*  SwViewImp::Init()
+|*
+|*  Ersterstellung      MA 25. Jul. 94
+|*  Letzte Aenderung    MA 03. Nov. 95
+|*
+|*************************************************************************/
+
+void SwViewImp::Init( const SwViewOption *pNewOpt )
+{
+    ASSERT( pDrawView, "SwViewImp::Init without DrawView" );
+    //Jetzt die PageView erzeugen wenn sie noch nicht existiert.
+    SwRootFrm *pRoot = pSh->GetDoc()->GetRootFrm();
+    if ( !pSdrPageView )
+    {
+        if ( !pRoot->GetDrawPage() )
+            pRoot->SetDrawPage( pSh->GetDoc()->GetDrawModel()->GetPage( 0 ) );
+
+        pRoot->GetDrawPage()->SetSize( pRoot->Frm().SSize() );
+         pSdrPageView = pDrawView->ShowPage( pRoot->GetDrawPage(), Point());
+    }
+    pDrawView->SetDragStripes( pNewOpt->IsCrossHair() );
+    pDrawView->SetGridSnap( pNewOpt->IsSnap() );
+    pDrawView->SetGridVisible( pNewOpt->IsGridVisible() );
+    const Size &rSz = pNewOpt->GetSnapSize();
+    pDrawView->SetGridCoarse( rSz );
+    const Size aFSize
+            ( rSz.Width() ? rSz.Width() /Max(short(1),pNewOpt->GetDivisionX()):0,
+              rSz.Height()? rSz.Height()/Max(short(1),pNewOpt->GetDivisionY()):0);
+     pDrawView->SetGridFine( aFSize );
+     pDrawView->SetSnapGrid( aFSize );
+    Fraction aSnGrWdtX(rSz.Width(), pNewOpt->GetDivisionX() + 1);
+    Fraction aSnGrWdtY(rSz.Height(), pNewOpt->GetDivisionY() + 1);
+    pDrawView->SetSnapGridWidth( aSnGrWdtX, aSnGrWdtY );
+
+    //Ersatzdarstellung
+    FASTBOOL bDraw = !pNewOpt->IsDraw();
+    pDrawView->SetLineDraft( bDraw );
+    pDrawView->SetFillDraft( bDraw );
+    pDrawView->SetGrafDraft( bDraw );
+    pDrawView->SetTextDraft( bDraw );
+
+    if ( pRoot->Frm().HasArea() )
+        pDrawView->SetWorkArea( pRoot->Frm().SVRect() );
+
+    if ( GetShell()->IsPreView() )
+        pDrawView->SetAnimationEnabled( FALSE );
+
+    pDrawView->SetUseIncompatiblePathCreateInterface( FALSE );
+    pDrawView->SetSolidMarkHdl(pNewOpt->IsSolidMarkHdl());
+
+    // it's a JOE interface !
+    pDrawView->SetMarkHdlSizePixel(pNewOpt->IsBigMarkHdl() ? 9 : 7);
+}
+
+/*************************************************************************
+|*
+|*  SwViewImp::SwViewImp()  CTor fuer die Core-Internas
+|*
+|*  Ersterstellung      MA 25. Jul. 94
+|*  Letzte Aenderung    MA 06. Sep. 96
+|*
+|*************************************************************************/
+
+SwViewImp::SwViewImp( ViewShell *pParent ) :
+    pSh( pParent ),
+    pFirstVisPage( 0 ),
+    pRegion( 0 ),
+    pScrollRects( 0 ),
+    pScrolledArea( 0 ),
+    pLayAct( 0 ),
+    pIdleAct( 0 ),
+    pSdrPageView( 0 ),
+    pDrawView( 0 ),
+    nRestoreActions( 0 )
+{
+    bResetXorVisibility = bShowHdlPaint =
+    bResetHdlHiddenPaint = bScrolled =
+    bPaintInScroll = bSmoothUpdate = bStopSmooth = FALSE;
+    bFirstPageInvalid = bScroll = bNextScroll = TRUE;
+
+    aScrollTimer.SetTimeout( 1500 );
+    aScrollTimer.SetTimeoutHdl( LINK( this, SwViewImp, RefreshScrolledHdl));
+    aScrollTimer.Stop();
+}
+
+/******************************************************************************
+|*
+|*  SwViewImp::~SwViewImp()
+|*
+|*  Ersterstellung      MA 25. Jul. 94
+|*  Letzte Aenderung    MA 16. Dec. 94
+|*
+******************************************************************************/
+
+SwViewImp::~SwViewImp()
+{
+    //JP 29.03.96: nach ShowPage muss auch HidePage gemacht werden!!!
+    if( pDrawView )
+         pDrawView->HidePage( pSdrPageView );
+
+    delete pDrawView;
+
+    DelRegions();
+    delete pScrolledArea;
+
+    ASSERT( !pLayAct, "Have action for the rest of your life." );
+    ASSERT( !pIdleAct,"Be idle for the rest of your life." );
+}
+
+/******************************************************************************
+|*
+|*  SwViewImp::DelRegions()
+|*
+|*  Ersterstellung      MA 14. Apr. 94
+|*  Letzte Aenderung    MA 14. Apr. 94
+|*
+******************************************************************************/
+
+void SwViewImp::DelRegions()
+{
+    DELETEZ(pRegion);
+    DELETEZ(pScrollRects);
+}
+
+/******************************************************************************
+|*
+|*  SwViewImp::AddPaintRect()
+|*
+|*  Ersterstellung      MA ??
+|*  Letzte Aenderung    MA 27. Jul. 94
+|*
+******************************************************************************/
+
+BOOL SwViewImp::AddPaintRect( const SwRect &rRect )
+{
+    if ( rRect.IsOver( pSh->VisArea() ) )
+    {
+        if ( !pRegion )
+            pRegion = new SwRegionRects( pSh->VisArea() );
+        (*pRegion) -= rRect;
+        return TRUE;
+    }
+    return FALSE;
+}
+
+
+/******************************************************************************
+|*
+|*  ViewImp::CheckWaitCrsr()
+|*
+|*  Ersterstellung      MA 10. Aug. 94
+|*  Letzte Aenderung    MA 10. Aug. 94
+|*
+******************************************************************************/
+
+void SwViewImp::CheckWaitCrsr()
+{
+    if ( pLayAct )
+        pLayAct->CheckWaitCrsr();
+}
+
+/******************************************************************************
+|*
+|*  ViewImp::IsCalcLayoutProgress()
+|*
+|*  Ersterstellung      MA 12. Aug. 94
+|*  Letzte Aenderung    MA 12. Aug. 94
+|*
+******************************************************************************/
+
+BOOL SwViewImp::IsCalcLayoutProgress() const
+{
+    if ( pLayAct )
+        return pLayAct->IsCalcLayout();
+    return FALSE;
+}
+
+/******************************************************************************
+|*
+|*  ViewImp::IsUpdateExpFlds()
+|*
+|*  Ersterstellung      MA 28. Mar. 96
+|*  Letzte Aenderung    MA 28. Mar. 96
+|*
+******************************************************************************/
+
+BOOL SwViewImp::IsUpdateExpFlds()
+{
+    if ( pLayAct && pLayAct->IsCalcLayout() )
+    {
+        pLayAct->SetUpdateExpFlds();
+        return TRUE;
+    }
+     return FALSE;
+}
+
+
+/******************************************************************************
+|*
+|*  SwViewImp::SetFirstVisPage(), ImplGetFirstVisPage();
+|*
+|*  Ersterstellung      MA 21. Sep. 93
+|*  Letzte Aenderung    MA 08. Mar. 94
+|*
+******************************************************************************/
+
+void SwViewImp::SetFirstVisPage()
+{
+    if ( pSh->bDocSizeChgd && pSh->VisArea().Top() > pSh->GetLayout()->Frm().Height() )
+    {
+        //Wir stecken in einer Action und die VisArea sitzt wegen
+        //Loeschoperationen hinter der erste sichtbaren Seite.
+        //Damit nicht zu heftig Formatiert wird, liefern wir die letzte Seite
+        //zurueck.
+        pFirstVisPage = (SwPageFrm*)pSh->GetLayout()->Lower();
+        while ( pFirstVisPage && pFirstVisPage->GetNext() )
+            pFirstVisPage = (SwPageFrm*)pFirstVisPage->GetNext();
+    }
+    else
+    {
+        SwPageFrm *pPage = (SwPageFrm*)pSh->GetLayout()->Lower();
+        while ( pPage && !pPage->Frm().IsOver( pSh->VisArea() ) )
+            pPage = (SwPageFrm*)pPage->GetNext();
+        pFirstVisPage = pPage ? pPage : (SwPageFrm*)pSh->GetLayout()->Lower();
+    }
+    bFirstPageInvalid = FALSE;
+}
+
+/******************************************************************************
+|*
+|*  SwViewImp::MakeDrawView();
+|*
+|*  Ersterstellung      AMA 01. Nov. 95
+|*  Letzte Aenderung    AMA 01. Nov. 95
+|*
+******************************************************************************/
+
+void SwViewImp::MakeDrawView()
+{
+    if( !GetShell()->GetDoc()->GetDrawModel() )
+        GetShell()->GetDoc()->_MakeDrawModel();
+    else
+    {
+        if ( !pDrawView )
+        {
+            pDrawView = new SwDrawView( *this,
+                        GetShell()->GetDoc()->GetDrawModel(),
+                           GetShell()->GetWin() ?
+                            GetShell()->GetWin() :
+                            (OutputDevice*)GetShell()->GetDoc()->GetPrt() );
+        }
+        GetDrawView()->SetActiveLayer( XubString::CreateFromAscii(
+                            RTL_CONSTASCII_STRINGPARAM( "Heaven" ) ) );
+        Init( GetShell()->GetViewOptions() );
+    }
+}
+
+/******************************************************************************
+|*
+|*  SwViewImp::GetRetoucheColor()
+|*
+|*  Ersterstellung      MA 24. Jun. 98
+|*  Letzte Aenderung    MA 24. Jun. 98
+|*
+******************************************************************************/
+
+Color SwViewImp::GetRetoucheColor() const
+{
+    Color aRet( COL_TRANSPARENT );
+    const ViewShell &rSh = *GetShell();
+    if ( rSh.GetWin() )
+    {
+        if ( rSh.GetDoc()->IsBrowseMode() &&
+             COL_TRANSPARENT != rSh.GetViewOptions()->GetRetoucheColor().GetColor() )
+            aRet = rSh.GetViewOptions()->GetRetoucheColor();
+        else
+            aRet = rSh.GetWin()->GetSettings().GetStyleSettings().GetWindowColor();
+    }
+    return aRet;
+}
+
+/************************************************************************
+
+      $Log: not supported by cvs2svn $
+      Revision 1.96  2000/09/18 16:04:37  willem.vandorp
+      OpenOffice header added.
+
+      Revision 1.95  2000/07/17 10:31:08  ama
+      Opt: Smarter scrolling for RVP
+
+      Revision 1.94  2000/05/09 11:35:43  ama
+      Unicode changes
+
+      Revision 1.93  2000/04/27 07:37:23  os
+      UNICODE
+
+      Revision 1.92  2000/03/03 15:17:22  os
+      StarView remainders removed
+
+      Revision 1.91  2000/02/11 14:36:08  hr
+      #70473# changes for unicode ( patched by automated patchtool )
+
+      Revision 1.90  1999/09/22 12:37:10  os
+      big handles
+
+      Revision 1.89  1999/09/06 13:19:00  aw
+      changes due to support of new handles
+
+
+      Rev 1.85   13 Aug 1999 15:11:32   MA
+   adoption to new markers, but still inkomplete
+
+      Rev 1.84   08 Apr 1999 12:36:28   MA
+   #64467# Complete und Retouche ggf. zuruecksetzen
+
+      Rev 1.83   30 Mar 1999 17:11:30   AW
+   #41275# changed handling of Snap-functionality
+
+      Rev 1.82   16 Jul 1998 18:55:36   AMA
+   Fix #50348#51949#: Controls bei virtuellen Outputdevice extra painten
+
+      Rev 1.81   07 Jul 1998 13:23:02   OS
+   alle Actions fuer layoutabhaengige UNO-Operationen kurzfristig aufheben
+
+      Rev 1.80   24 Jun 1998 18:45:22   MA
+   DataChanged fuer ScrollBar und Retouche, Retouche ganz umgestellt
+
+      Rev 1.79   03 Jun 1998 09:25:20   MA
+   #50392# Handles und Xor aufgeraeumt
+
+      Rev 1.78   27 Apr 1998 15:09:12   MA
+   ein paar sv2vcl
+
+      Rev 1.77   28 Jan 1998 13:40:52   MA
+   ueberfluessiges Hell-Paint vom Text entfernt
+
+      Rev 1.76   28 Nov 1997 09:08:46   MA
+   includes
+
+      Rev 1.75   03 Nov 1997 13:07:30   MA
+   precomp entfernt
+
+      Rev 1.74   21 Oct 1997 14:10:24   MA
+   #44844# VirDev zu klein
+
+      Rev 1.73   13 Oct 1997 10:30:18   MA
+   Umbau/Vereinfachung Paint
+
+      Rev 1.72   15 Aug 1997 12:24:06   OS
+   charatr/frmatr/txtatr aufgeteilt
+
+      Rev 1.71   12 Aug 1997 15:08:52   MH
+   chg: header
+
+      Rev 1.70   07 Jul 1997 16:33:42   OS
+   SnapSize auch im Init auf den gleichen Wert wie SetGridFine setzen #41380#
+
+      Rev 1.69   11 Jun 1997 12:58:40   MH
+   add: include Win16
+
+      Rev 1.68   04 Apr 1997 17:37:12   NF
+   includes
+
+      Rev 1.67   25 Mar 1997 14:46:28   MA
+   Smooth
+
+      Rev 1.66   23 Mar 1997 13:08:42   MA
+   new: bPainInScroll
+
+      Rev 1.65   25 Feb 1997 09:10:54   MA
+   chg: Option fuer SolidHdl
+
+      Rev 1.64   25 Feb 1997 08:45:44   MA
+   chg: SolidHdl ueberm Berg
+
+      Rev 1.63   19 Feb 1997 11:04:04   MA
+   chg: neue huebsche Handles
+
+      Rev 1.62   05 Feb 1997 09:17:14   MA
+   fix: Refresh, virtuelles Device hinreichend gross einstellen
+
+      Rev 1.61   23 Jan 1997 14:21:42   OM
+   Klickverhalten von polygonen geaendert
+
+      Rev 1.60   16 Jan 1997 17:34:34   MA
+   chg: Paint oder nicht sagt uns jetzt SwFlyFrm::IsPaint
+
+*************************************************************************/
+
+
diff --git a/sw/source/core/view/viewpg.cxx b/sw/source/core/view/viewpg.cxx
new file mode 100644
index 000000000000..97eacea36020
--- /dev/null
+++ b/sw/source/core/view/viewpg.cxx
@@ -0,0 +1,1472 @@
+/*************************************************************************
+ *
+ *  $RCSfile: viewpg.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:29 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "hintids.hxx"
+
+
+#ifndef _SV_WINDOW_HXX //autogen
+#include 
+#endif
+#ifndef _SFX_PRINTER_HXX //autogen
+#include 
+#endif
+#ifndef _SFX_PROGRESS_HXX //autogen
+#include 
+#endif
+
+#ifndef _PVPRTDAT_HXX
+#include 
+#endif
+
+#include "doc.hxx"
+#include "viewsh.hxx"
+#include "pagefrm.hxx"
+#include "rootfrm.hxx"
+#include "viewimp.hxx"
+#include "viewopt.hxx"
+#include "swprtopt.hxx" // SwPrtOptions
+#include "statstr.hrc"  // Text fuer SfxProgress
+#include "fldbas.hxx"
+#include "ptqueue.hxx"
+#include "swregion.hxx"
+#include "hints.hxx"
+#include "fntcache.hxx"
+#include "comcore.hrc"
+
+const SwTwips nXFree = 142;     // == 0.25 cm
+const SwTwips nYFree = 142;
+static USHORT nPrevViewXFreePix = 0;
+static USHORT nPrevViewYFreePix = 0;
+
+SwPageFrm* lcl_GetSttPage( BYTE& rRow, BYTE& rCol, USHORT& rSttPage,
+                                const SwRootFrm* pRoot )
+{
+    USHORT nCalcSttPg = rSttPage;
+    if( nCalcSttPg )
+        --nCalcSttPg;
+    if( !rCol )
+        ++rCol;
+    if( !rRow )
+        ++rRow;
+
+    // suche die Start-Seite
+    SwPageFrm *pSttPage = (SwPageFrm*)pRoot->Lower(), *pPrevPage = pSttPage;
+    while( pSttPage && nCalcSttPg )
+    {
+        pPrevPage = pSttPage;
+        pSttPage = (SwPageFrm*)pSttPage->GetNext();
+        --nCalcSttPg;
+    }
+
+    // keine Seiten mehr ??
+    if( !pSttPage )
+    {
+        pSttPage = pPrevPage;
+        rSttPage -= nCalcSttPg;     // das sind die tatsaechlichen
+        if( 1 == (rSttPage & 1 ))   // eine rechte Seite?
+            ++rSttPage;             // dann sorge dafuer das sie rechts steht
+
+        // dann dem Wunsch entsprechend Rueckwaerts
+        for( USHORT n = rRow * rCol; n && pSttPage; --n )
+        {
+            pPrevPage = pSttPage;
+            pSttPage = (SwPageFrm*)pSttPage->GetPrev();
+            --rSttPage;
+        }
+        if( !pSttPage )
+        {
+            pSttPage = pPrevPage;
+            rSttPage = 1;
+        }
+    }
+    return pSttPage;
+}
+
+USHORT ViewShell::CalcPreViewPage(
+        const Size& rWinSize,       // auf diese Size die Scalierung errechnen
+        USHORT& rRowCol,            // Zeilen/Spalten (Row im Hi, Col im LowByte!)
+        USHORT nSttPage,            // Start ab dieser Seite, eine gueltige ??
+        Size& rMaxSize,             // MaxSize einer Seite
+        USHORT& rVirtPageNo )       // virtuelle SeitenNummer
+{
+    const SwRootFrm* pRoot = GetLayout();
+    ASSERT( pRoot, "Wo ist mein Layout?" );
+
+    // ohne Win-Size ist nichts los
+    if( !rWinSize.Width() || !rWinSize.Height() )
+        return 0;
+
+    // von allen Seiten die Size holen. Das Max entscheidet
+    // ueber die Scalierung.  (So macht es WW)
+    register SwTwips nMaxRowSz = 0, nMaxColSz = 0;
+    register USHORT nCalcSttPg = nSttPage;
+    if( nCalcSttPg )
+        --nCalcSttPg;
+
+    BYTE nRow = BYTE(rRowCol >> 8), nCol = BYTE(rRowCol & 0xff);
+    if( !nCol )
+        ++nCol;
+    if( !nRow )
+        ++nRow;
+
+    // suche bestimme die Max-Breite
+    register SwPageFrm *pSttPage = (SwPageFrm*)pRoot->Lower(),
+                        *pPrevPage = pSttPage;
+    while( pSttPage && nCalcSttPg )
+    {
+        pSttPage->Calc();
+        register Size& rSize = pSttPage->Frm().SSize();
+        if( nMaxColSz < rSize.Width() )
+            nMaxColSz = rSize.Width();
+        if( nMaxRowSz < rSize.Height() )
+            nMaxRowSz = rSize.Height();
+        pPrevPage = pSttPage;
+        pSttPage = (SwPageFrm*)pSttPage->GetNext();
+        --nCalcSttPg;
+    }
+
+    // keine Seiten mehr ??
+    if( !pSttPage )
+    {
+        pSttPage = pPrevPage;
+        nSttPage -= nCalcSttPg;     // das sind die tatsaechlichen
+#if OLD
+// hiermit stimmt die Errechnung der vir. PageNo nicht !!
+        if( 1 == (nSttPage & 1 ))   // eine rechte Seite?
+            ++nSttPage;             // dann sorge dafuer das sie rechts steht
+
+        // dann dem Wunsch entsprechend Rueckwaerts
+        for( USHORT n = nRow * nCol; n && pSttPage; --n )
+        {
+            pPrevPage = pSttPage;
+            pSttPage = (SwPageFrm*)pSttPage->GetPrev();
+            --nSttPage;
+        }
+#else
+        USHORT n = nRow * nCol;
+        if( 1 == (nSttPage & 1 ))   // eine rechte Seite?
+            --n;                    // dann sorge dafuer das sie rechts steht
+
+        // dann dem Wunsch entsprechend Rueckwaerts
+        for( ; n && pSttPage; --n )
+        {
+            pPrevPage = pSttPage;
+            pSttPage = (SwPageFrm*)pSttPage->GetPrev();
+            --nSttPage;
+        }
+#endif
+        if( !pSttPage )
+        {
+            pSttPage = pPrevPage;
+            nSttPage = 0;
+        }
+        rVirtPageNo = pPrevPage->GetVirtPageNum();
+    }
+    else    // dann haben wir unsere StartSeite,
+            // also weiter und das Max bestimmen
+    {
+        rVirtPageNo = pSttPage->GetVirtPageNum();
+        while( pSttPage )
+        {
+            pSttPage->Calc();
+            register Size& rSize = pSttPage->Frm().SSize();
+            if( nMaxColSz < rSize.Width() )
+                nMaxColSz = rSize.Width();
+            if( nMaxRowSz < rSize.Height() )
+                nMaxRowSz = rSize.Height();
+            pSttPage = (SwPageFrm*)pSttPage->GetNext();
+        }
+    }
+
+    rMaxSize.Height() = nMaxRowSz;
+    rMaxSize.Width() = nMaxColSz;
+    rRowCol = (nRow << 8) + nCol;       // und wieder returnen
+
+    // Jetzt die Scalierung incl. der gewuenschten Zwischenraueme errechnen
+    nMaxColSz = nCol * nMaxColSz;
+    nMaxRowSz = nRow * nMaxRowSz;
+
+    MapMode aMapMode( MAP_TWIP );
+    // falls die Abstaende zwischen den Seiten noch nicht berechnet wurden
+    if( !nPrevViewXFreePix || !nPrevViewYFreePix )
+    {
+        Size aTmpSz( nXFree, nYFree );
+        aTmpSz = GetOut()->LogicToPixel( aTmpSz, aMapMode );
+        nPrevViewXFreePix = USHORT( aTmpSz.Width() );
+        nPrevViewYFreePix = USHORT( aTmpSz.Height() );
+    }
+    Size aSz( rWinSize.Width() - ((nCol+1) * nPrevViewXFreePix),
+              rWinSize.Height() - ( (nRow+1) * nPrevViewYFreePix ) );
+    aSz = GetOut()->PixelToLogic( aSz, aMapMode );
+    Fraction aScX( aSz.Width(), nMaxColSz );
+    Fraction aScY( aSz.Height(), nMaxRowSz );
+    if( aScX < aScY )
+        aScY = aScX;
+
+    {
+        // fuer Drawing, damit diese ihre Objecte vernuenftig Painten
+        // koennen, auf "glatte" Prozentwerte setzen
+        aScY *= Fraction( 1000, 1 );
+        long nTmp = (long)aScY;
+        if( 1 < nTmp )
+            --nTmp;
+        else
+            nTmp = 1;
+        aScY = Fraction( nTmp, 1000 );
+        if( pOpt )                              // fuer den Font-Cache die
+            pOpt->SetZoom( USHORT(nTmp / 10));  // Options mitpflegen!
+    }
+    aMapMode.SetScaleY( aScY );
+    aMapMode.SetScaleX( aScY );
+
+    // was machen wir, wenn der MapMode unter einer
+    // gewissen Schwelle (z.B. 10% (WW6)) ist ???
+
+    GetOut()->SetMapMode( aMapMode );
+    return nSttPage;
+}
+
+void ViewShell::PreViewPage(
+        const Rectangle& rRect,     // Paint-Rect von Windows
+        USHORT nRowCol,             // Anzahl Zeilen/Spalten
+        USHORT nSttPage,            // Start ab dieser Seite, eine gueltige ??
+        const Size& rPageSize )     // MaxSize einer Seite
+{
+    if( !GetWin() && !GetOut()->GetConnectMetaFile() )
+        return;                     //Fuer den Drucker tun wir hier nix
+
+    SET_CURR_SHELL( this );
+
+    const SwRootFrm* pRoot = GetLayout();
+    ASSERT( pRoot, "Wo ist mein Layout?" );
+
+    BYTE nRow = BYTE(nRowCol >> 8), nCol = BYTE(nRowCol & 0xff);
+    SwPageFrm* pSttPage = ::lcl_GetSttPage( nRow, nCol, nSttPage, pRoot );
+
+    // damit auch die Seiten im Paint angezeigt werden, gleich die richtigen
+    // Werte setzen! (siehe auch Bug 24575)
+    Imp()->bFirstPageInvalid = FALSE;
+    Imp()->pFirstVisPage = pSttPage;
+
+    const Rectangle aPixRect( GetOut()->LogicToPixel( rRect ) );
+
+    MapMode aMapMode( GetOut()->GetMapMode() );
+    MapMode aCalcMapMode( aMapMode );
+    aCalcMapMode.SetOrigin( Point() );
+
+    SwRegionRects aRegion( rRect );//fuer die Wiese
+
+    Point aFreePt( nPrevViewXFreePix, nPrevViewYFreePix );
+    aFreePt = GetOut()->PixelToLogic( aFreePt, aCalcMapMode );
+    Point aCalcPt( aFreePt );
+    long nPageHeight = aFreePt.Y() + rPageSize.Height()+1;
+    SwPageFrm* pPage = pSttPage;
+
+    // erstmal die Wiese
+    // Sonderbehandlung fuer die erste Seite
+    // JP 19.08.98: aber nur wenn sie mehrspaltig angezeigt wird
+    int bFirstPg = !nSttPage && 1 != nCol;
+
+    for( BYTE nCntRow = 0; pPage && nCntRow < nRow; ++nCntRow )
+    {
+        aCalcPt.X() = aFreePt.X();
+        for( BYTE nCntCol = 0; pPage && nCntCol < nCol; ++nCntCol )
+        {
+            pPage->Calc();
+
+            // Sonderbehandlung fuer 1. Seite, ist immer eine rechte
+            if( bFirstPg )
+            {
+                bFirstPg = FALSE;
+                aCalcPt.X() += pPage->Frm().Width()+1 + aFreePt.X();
+                continue;
+            }
+
+            if( pPage->IsEmptyPage() )
+            {
+                aRegion -= SwRect( aCalcPt, rPageSize );
+                aCalcPt.X() += rPageSize.Width()+1 + aFreePt.X();
+            }
+            else
+            {
+                aRegion -= SwRect( aCalcPt, pPage->Frm().SSize() );
+                aCalcPt.X() += pPage->Frm().Width()+1 + aFreePt.X();
+            }
+            pPage = (SwPageFrm*)pPage->GetNext();
+        }
+        aCalcPt.Y() += nPageHeight;
+    }
+    GetOut()->SetMapMode( aCalcMapMode );
+    _PaintDesktop( aRegion );
+
+    // und dann das Dokument
+    bFirstPg = !nSttPage && 1 != nCol;
+    aCalcPt = aFreePt;
+    pPage = pSttPage;
+    Font* pEmptyPgFont = 0;
+
+    for( nCntRow = 0; pPage && nCntRow < nRow; ++nCntRow )
+    {
+        aCalcPt.X() = aFreePt.X();
+        for( BYTE nCntCol = 0; pPage && nCntCol < nCol; ++nCntCol )
+        {
+            // Sonderbehandlung fuer 1. Seite, ist immer eine rechte
+            if( bFirstPg )
+            {
+                bFirstPg = FALSE;
+                aCalcPt.X() += pPage->Frm().Width()+1 + aFreePt.X();
+                continue;
+            }
+
+            if( pPage->IsEmptyPage() )
+            {
+                Rectangle aRect( aCalcPt, rPageSize );
+
+                aMapMode.SetOrigin( Point(0,0) );
+                GetOut()->SetMapMode( aMapMode );
+
+                const Color aRetouche( Imp()->GetRetoucheColor() );
+
+                if( GetOut()->GetFillColor() != aRetouche )
+                    GetOut()->SetFillColor( aRetouche );
+                GetOut()->DrawRect( aRect );
+
+                if( !pEmptyPgFont )
+                {
+                    pEmptyPgFont = new Font;
+                    pEmptyPgFont->SetSize( Size( 0, 80 * 20 )); // == 80 pt
+                    pEmptyPgFont->SetWeight( WEIGHT_BOLD );
+                    pEmptyPgFont->SetStyleName( aEmptyStr );
+                    pEmptyPgFont->SetName( String::CreateFromAscii(
+                            RTL_CONSTASCII_STRINGPARAM( "Helvetica" )) );
+                    pEmptyPgFont->SetFamily( FAMILY_SWISS );
+                    pEmptyPgFont->SetTransparent( TRUE );
+                    pEmptyPgFont->SetColor( COL_GRAY );
+                }
+                Font aOldFont( GetOut()->GetFont() );
+                GetOut()->SetFont( *pEmptyPgFont );
+                GetOut()->DrawText( aRect, SW_RESSTR( STR_EMPTYPAGE ),
+                                    TEXT_DRAW_VCENTER |
+                                    TEXT_DRAW_CENTER |
+                                    TEXT_DRAW_CLIP );
+                GetOut()->SetFont( aOldFont );
+
+                aCalcPt.X() += rPageSize.Width()+1 + aFreePt.X();
+            }
+            else
+            {
+                aVisArea = pPage->Frm();
+
+                Point aPos( aCalcPt );
+                aPos -= aVisArea.Pos();
+
+                aMapMode.SetOrigin( aPos );
+                GetOut()->SetMapMode( aMapMode );
+
+                Rectangle aSVRect( GetOut()->LogicToPixel( aVisArea.SVRect() ) );
+                if( aPixRect.IsOver( aSVRect ) )
+                {
+                    aSVRect.Intersection( aPixRect );
+                    aSVRect = GetOut()->PixelToLogic( aSVRect );
+
+                    Paint( aSVRect );
+                }
+                aCalcPt.X() += pPage->Frm().Width()+1 + aFreePt.X();
+            }
+            pPage = (SwPageFrm*)pPage->GetNext();
+        }
+        aCalcPt.Y() += nPageHeight;
+    }
+
+    delete pEmptyPgFont;
+    GetOut()->SetMapMode( aCalcMapMode );
+    aVisArea.Clear();       // verhinder internes Painten !!
+}
+
+void ViewShell::RepaintCoreRect(
+        const SwRect& rRect,        // Paint-Rect der Core
+        USHORT nRowCol,             // Anzahl Zeilen/Spalten
+        USHORT nSttPage,            // Start ab dieser Seite, eine gueltige ??
+        const Size& rPageSize )     // MaxSize einer Seite
+{
+    if( !GetWin() && !GetOut()->GetConnectMetaFile() )
+        return;                     //Fuer den Drucker tun wir hier nix
+
+    SET_CURR_SHELL( this );
+
+    const SwRootFrm* pRoot = GetLayout();
+    ASSERT( pRoot, "Wo ist mein Layout?" );
+
+    BYTE nRow = BYTE(nRowCol >> 8), nCol = BYTE(nRowCol & 0xff);
+    SwPageFrm* pSttPage = ::lcl_GetSttPage( nRow, nCol, nSttPage, pRoot );
+
+    // damit auch die Seiten im Paint angezeigt werden, gleich die richtigen
+    // Werte setzen! (siehe auch Bug 24575)
+    Imp()->bFirstPageInvalid = FALSE;
+    Imp()->pFirstVisPage = pSttPage;
+
+//    const Rectangle aPixRect( GetOut()->LogicToPixel( rRect ) );
+
+    MapMode aMapMode( GetOut()->GetMapMode() );
+    MapMode aCalcMapMode( aMapMode );
+    aCalcMapMode.SetOrigin( Point() );
+
+    Point aFreePt( nPrevViewXFreePix, nPrevViewYFreePix );
+    aFreePt = GetOut()->PixelToLogic( aFreePt, aCalcMapMode );
+    Point aCalcPt( aFreePt );
+    long nPageHeight = aFreePt.Y() + rPageSize.Height()+1;
+    SwPageFrm* pPage = pSttPage;
+
+    // Sonderbehandlung fuer die erste Seite
+    // JP 19.08.98: aber nur wenn sie mehrspaltig angezeigt wird
+    int bFirstPg = !nSttPage && 1 != nCol;
+    for( BYTE nCntRow = 0; pPage && nCntRow < nRow; ++nCntRow )
+    {
+        aCalcPt.X() = aFreePt.X();
+        for( BYTE nCntCol = 0; pPage && nCntCol < nCol; ++nCntCol )
+        {
+            // Sonderbehandlung fuer 1. Seite, ist immer eine rechte
+            if( bFirstPg )
+            {
+                bFirstPg = FALSE;
+                aCalcPt.X() += pPage->Frm().Width()+1 + aFreePt.X();
+                continue;
+            }
+
+            SwRect aTmpRect( pPage->Frm() );
+            if( rRect.IsOver( aTmpRect ))
+            {
+                Point aPos( aCalcPt );
+                aPos -= aTmpRect.Pos();
+
+                aMapMode.SetOrigin( aPos );
+
+                aTmpRect._Intersection( rRect );
+                Rectangle aSVRect( GetOut()->
+                    LogicToLogic( aTmpRect.SVRect(), &aMapMode, &aCalcMapMode ) );
+                GetWin()->Invalidate( aSVRect );
+            }
+            aCalcPt.X() += pPage->Frm().Width()+1 + aFreePt.X();
+            pPage = (SwPageFrm*)pPage->GetNext();
+        }
+        aCalcPt.Y() += nPageHeight;
+    }
+
+    aVisArea.Clear();       // verhinder internes Painten !!
+}
+
+    // und jetzt mal raus auf den Drucker
+void ViewShell::PrintPreViewPage( SwPrtOptions& rOptions,
+                                  USHORT nRowCol, SfxProgress& rProgress,
+                                  const SwPagePreViewPrtData* pPrtData )
+{
+    if( !rOptions.aMulti.GetSelectCount() )
+        return;
+
+    // wenn kein Drucker vorhanden ist, wird nicht gedruckt
+    SfxPrinter* pPrt = GetPrt();
+    if( !pPrt || !pPrt->GetName().Len() )
+        return;
+
+// schoen waers gewesen !!! const MultiSelection& rMulti = rOptions.aMulti;
+    MultiSelection aMulti( rOptions.aMulti );
+    Range aPages( aMulti.FirstSelected(), aMulti.LastSelected() );
+    if ( aPages.Max() > USHRT_MAX )
+        aPages.Max() = USHRT_MAX;
+
+    ASSERT( aPages.Min() > 0,
+            "Seite 0 Drucken?" );
+    ASSERT( aPages.Min() <= aPages.Max(),
+            "MinSeite groesser MaxSeite." );
+
+    // eine neue Shell fuer den Printer erzeugen
+    ViewShell aShell( this, 0 );
+
+    aShell.pRef = new SfxPrinter( *pPrt );
+
+    SET_CURR_SHELL( &aShell );
+
+    aShell.PrepareForPrint( rOptions );
+
+    // gibt es versteckte Absatzfelder, unnoetig wenn die Absaetze bereits
+    // ausgeblendet sind.
+    int bHiddenFlds = FALSE;
+    SwFieldType* pFldType = 0;
+    if ( GetViewOptions()->IsShowHiddenPara() )
+    {
+        pFldType = GetDoc()->GetSysFldType( RES_HIDDENPARAFLD );
+        bHiddenFlds = 0 != pFldType->GetDepends();
+        if( bHiddenFlds )
+        {
+            SwMsgPoolItem aHnt( RES_HIDDENPARA_PRINT );
+            pFldType->Modify( &aHnt, 0);
+        }
+    }
+
+    // Seiten fuers Drucken formatieren
+    aShell.CalcPagesForPrint( (USHORT)aPages.Max(), &rProgress );
+
+    USHORT nCopyCnt = rOptions.bCollate ? rOptions.nCopyCount : 1;
+    BOOL bStartJob = FALSE;
+
+    for ( USHORT nCnt = 0; nCnt < nCopyCnt; nCnt++ )
+    {
+        if( rOptions.bSinglePrtJobs && rOptions.GetJobName().Len() &&
+            ( bStartJob || rOptions.bJobStartet ) )
+        {
+            pPrt->EndJob();
+            rOptions.bJobStartet = TRUE;
+
+            // Reschedule statt Yield, da Yield keine Events abarbeitet
+            // und es sonst eine Endlosschleife gibt.
+            while( pPrt->IsPrinting() )
+                    rProgress.Reschedule();
+
+            rOptions.MakeNextJobName();
+            bStartJob = pPrt->StartJob( rOptions.GetJobName() );
+        }
+
+        const SwPageFrm *pStPage  = (SwPageFrm*)GetLayout()->Lower();
+        const SwFrm     *pEndPage = pStPage;
+
+        for( USHORT i = 1; pStPage && i < (USHORT)aPages.Min(); ++i )
+            pStPage = (SwPageFrm*)pStPage->GetNext();
+
+        if( !pStPage )          // dann wars das
+        {
+            if( bHiddenFlds )
+            {
+                SwMsgPoolItem aHnt( RES_HIDDENPARA_PRINT );
+                pFldType->Modify( &aHnt, 0);
+                CalcPagesForPrint( (USHORT)aPages.Max() );
+            }
+            return;
+        }
+
+        // unsere SttPage haben wir, dann die EndPage suchen
+        USHORT nFirstPageNo = i;
+        USHORT nLastPageNo  = i;
+        USHORT nPageNo      = 1;
+
+        pEndPage = pStPage;
+
+        if( pStPage->GetNext() && (i != (USHORT)aPages.Max()) )
+        {
+            pEndPage = pEndPage->GetNext();
+            for( ++i,++nLastPageNo;
+                 pEndPage->GetNext() && i < (USHORT)aPages.Max(); ++i )
+            {
+                pEndPage = pEndPage->GetNext();
+                ++nLastPageNo;
+            }
+        }
+
+        if( rOptions.bPrintReverse )
+        {
+            const SwFrm *pTmp = pStPage;
+            pStPage  = (SwPageFrm*)pEndPage;
+            pEndPage = pTmp;
+            nPageNo  = nLastPageNo;
+        }
+        else
+            nPageNo = nFirstPageNo;
+
+
+    /*-----------------01.03.95 13:06-------------------
+
+    // Diese Options nur per Dialog einstellbar
+
+        if( !rOptions.bPaperFromSetup )     // Schacht einstellen.
+            pPrt->SetPaperBin( pStPage->GetFmt()->GetPaperBin().
+                                    GetBin() );
+
+        // Orientation einstellen: Breiter als Hoch -> Landscape,
+        // sonst -> Portrait.
+        if( pStPage->GetPageDesc()->GetLandscape() )
+            pPrt->SetOrientation( ORIENTATION_LANDSCAPE );
+        else
+            pPrt->SetOrientation( ORIENTATION_PORTRAIT );
+
+    --------------------------------------------------*/
+
+        // ein Array fuer die Seiten anlegen, die auf eine Drucker-Seite
+        // gedruckt werden sollen.
+        BYTE nRow = BYTE(nRowCol >> 8), nCol = BYTE(nRowCol & 0xff);
+        USHORT nPages = nRow * nCol;
+        SwPageFrm** aPageArr = new SwPageFrm* [ nPages ];
+        memset( aPageArr, 0, sizeof( SwPageFrm* ) * nPages );
+        USHORT nCntPage = 0;
+
+        SwTwips nCalcW = 0, nCalcH = 0, nMaxRowSz = 0, nMaxColSz = 0;
+
+        MapMode aOld( pPrt->GetMapMode() );
+        MapMode aMapMode( MAP_TWIP );
+        Size aPrtSize( pPrt->PixelToLogic( pPrt->GetPaperSizePixel(), aMapMode ));
+        if( pPrtData )
+        {
+            aPrtSize.Width() -= pPrtData->GetLeftSpace() +
+                                pPrtData->GetRightSpace() +
+                                ( pPrtData->GetHorzSpace() * (nCol - 1));
+            aPrtSize.Height() -= pPrtData->GetTopSpace() +
+                                pPrtData->GetBottomSpace() +
+                                ( pPrtData->GetVertSpace() * (nRow - 1));
+        }
+
+        aMulti.Select( Range( nLastPageNo+1, USHRT_MAX ), FALSE );
+        USHORT nSelCount = USHORT((aMulti.GetSelectCount()+nPages-1) / nPages);
+        nSelCount *= nCopyCnt;
+        USHORT nPrintCount = 1;
+
+        const XubString aTmp( SW_RES( STR_STATSTR_PRINT ) );
+        rProgress.SetText( aTmp );
+        //HACK, damit die Anzeige nicht durcheinander kommt:
+        rProgress.SetState( 1, nSelCount );
+        rProgress.SetText( aTmp );
+        bStartJob = TRUE;
+
+        while( pStPage )
+        {
+            // Mag der Anwender noch ?
+            rProgress.Reschedule();
+
+            if ( !pPrt->IsJobActive() )
+                break;
+
+            if( aMulti.IsSelected( nPageNo ) )
+            {
+                if( rOptions.bPrintReverse )
+                    aPageArr[ nPages - ++nCntPage ] = (SwPageFrm*)pStPage;
+                else
+                    aPageArr[ nCntPage++ ] = (SwPageFrm*)pStPage;
+
+                const Size& rSz = pStPage->Frm().SSize();
+                nCalcW += rSz.Width();
+                if( nCalcH < rSz.Height() )
+                    nCalcH = rSz.Height();
+
+                if( 0 == (nCntPage % nCol ) ||          // neue Zeile
+                    nCntPage == nPages || pStPage == pEndPage )
+                {
+                    // sollte die Seite nicht gefuellt sein, so erweiter
+                    // anhand der letzen Seite. Dadurch hat auch die
+                    // letze Seite die richtigen Spalten/Reihen.
+                    // BUG: 17695
+                    if( pStPage == pEndPage && nCntPage != nPages )
+                    {
+                        // dann Werte mit der letzen Seite auffuellen
+                        if( nCntPage < nCol )
+                            nCalcW += rSz.Width() * (nCol - nCntPage);
+
+                        BYTE nRows = (BYTE) ( nCntPage / nCol + 1 );
+                        if( nRows < nRow )
+                            nCalcH += ( nRow - nRows ) * nCalcH;
+                    }
+
+                    if( nMaxColSz < nCalcW )
+                        nMaxColSz = nCalcW;
+                    nCalcW = 0;
+                    nMaxRowSz += nCalcH;
+                }
+
+                if( nCntPage == nPages || pStPage == pEndPage )
+                {
+                    // den MapMode einstellen
+                    aMapMode.SetOrigin( Point() );
+                    {
+                        Fraction aScX( aPrtSize.Width(), nMaxColSz );
+                        Fraction aScY( aPrtSize.Height(), nMaxRowSz );
+
+// JP 19.08.98: wird zur Zeit nicht ausgewertet, weil
+//              der Font sich nicht enstprechend
+//              stretch laesst.
+#if 0
+                        if( pPrtData && pPrtData->GetStretch() )
+                        {
+                            // fuer Drawing, damit diese ihre Objecte vernuenftig Painten
+                            // koennen, auf "glatte" Prozentwerte setzen
+                            long nTmp = (long)(aScY *= Fraction( 1000, 1 ));
+                            if( 1 < nTmp ) --nTmp; else nTmp = 1;
+                            aScY = Fraction( nTmp, 1000 );
+
+                            nTmp = (long)(aScX *= Fraction( 1000, 1 ));
+                            if( 1 < nTmp ) --nTmp; else nTmp = 1;
+                            aScX = Fraction( nTmp, 1000 );
+                        }
+                        else
+#endif
+                        {
+                            if( aScX < aScY )
+                                aScY = aScX;
+
+                            // fuer Drawing, damit diese ihre Objecte vernuenftig Painten
+                            // koennen, auf "glatte" Prozentwerte setzen
+                            aScY *= Fraction( 1000, 1 );
+                            long nTmp = (long)aScY;
+                            if( 1 < nTmp )
+                                --nTmp;
+                            else
+                                nTmp = 1;
+                            aScY = Fraction( nTmp, 1000 );
+                            aScX = aScY;
+                        }
+
+                        aMapMode.SetScaleY( aScY );
+                        aMapMode.SetScaleX( aScX );
+                    }
+
+                    Point aPrtOff( pPrt->PixelToLogic(
+                                        pPrt->GetPageOffsetPixel(), aMapMode ) );
+                    long nPageHeight = (nMaxRowSz / nRow);
+
+                    // dann kann das drucken losgehen
+                    rProgress.SetState( nPrintCount++, nSelCount );
+
+                    pPrt->StartPage();
+                    Point aCalcPt;
+                    SwPageFrm** ppTmpPg = aPageArr;
+
+                    // ist das Array nicht vollsteandig gefuellt ?
+                    if( rOptions.bPrintReverse && nCntPage != nPages )
+                    {
+                        // beim Rueckwaertsdruck alle Seiten nach vorne
+                        // verschieben!
+                        memmove( ppTmpPg, ppTmpPg + (nPages - nCntPage),
+                                    nCntPage * sizeof( SwPageFrm*) );
+                        aPageArr[ nCntPage ] = 0;       // Endekennung
+                    }
+
+                    long nHOffs = 0, nVOffs = 0, nXStt = 0;
+                    if( pPrtData )
+                    {
+                        const Fraction& rScaleX = aMapMode.GetScaleX();
+                        const Fraction& rScaleY = aMapMode.GetScaleY();
+                        Fraction aF( pPrtData->GetTopSpace(), 1 );
+                        aCalcPt.Y() = aF /= rScaleY;
+                        aF = Fraction( pPrtData->GetLeftSpace(), 1 );
+                        nXStt = aF /= rScaleX;
+                        aF = Fraction( pPrtData->GetVertSpace(), 1 );
+                        nVOffs = aF /= rScaleY;
+                        aF = Fraction( pPrtData->GetHorzSpace(), 1 );
+                        nHOffs = aF /= rScaleX;
+                    }
+
+                    for( BYTE nR = 0; *ppTmpPg && nR < nRow; ++nR )
+                    {
+                        aCalcPt.X() = nXStt;
+                        for( BYTE nC = 0; *ppTmpPg && nC < nCol; ++nC )
+                        {
+                            aShell.Imp()->SetFirstVisPageInvalid();
+                            aShell.aVisArea = (*ppTmpPg)->Frm();
+
+                            Point aPos( aCalcPt );
+                            aPos -= aShell.aVisArea.Pos();
+                            aPos -= aPrtOff;
+                            aMapMode.SetOrigin( aPos );
+                            pPrt->SetMapMode( aMapMode );
+                            (*ppTmpPg)->GetUpper()->Paint( (*ppTmpPg)->Frm() );
+                            aCalcPt.X() += nHOffs + (*ppTmpPg)->Frm().Width();
+                            ++ppTmpPg;
+                        }
+                        aCalcPt.Y() += nVOffs + nPageHeight;
+                    }
+                    pPrt->EndPage();
+                    SwPaintQueue::Repaint();
+
+                    memset( aPageArr, 0, sizeof( SwPageFrm* ) * nPages );
+                    nCntPage = 0;
+                    nMaxRowSz = nMaxColSz = nCalcH = nCalcW = 0;
+                }
+            }
+
+            if( pStPage == pEndPage )
+                pStPage = 0;
+            else if( rOptions.bPrintReverse )
+            {
+                --nPageNo;
+                pStPage = (SwPageFrm*)pStPage->GetPrev();
+            }
+            else
+            {
+                ++nPageNo;
+                pStPage = (SwPageFrm*)pStPage->GetNext();
+            }
+        }
+        pPrt->SetMapMode( aOld );
+
+        if( bHiddenFlds )
+        {
+            SwMsgPoolItem aHnt( RES_HIDDENPARA_PRINT );
+            pFldType->Modify( &aHnt, 0);
+            CalcPagesForPrint( (USHORT)aPages.Max() );
+        }
+        delete aPageArr;
+
+        if( bStartJob )
+            rOptions.bJobStartet = TRUE;
+    }
+    pFntCache->Flush();
+}
+
+    // Prospektdruck
+void ViewShell::PrintProspect( SwPrtOptions& rOptions,
+                               SfxProgress& rProgress )
+{
+    if( !rOptions.aMulti.GetSelectCount() )
+        return;
+
+    // wenn kein Drucker vorhanden ist, wird nicht gedruckt
+    SfxPrinter* pPrt = GetPrt();
+    if( !pPrt || !pPrt->GetName().Len() ||
+        ( !rOptions.bPrintLeftPage && !rOptions.bPrintRightPage ))
+        return;
+
+    MultiSelection aMulti( rOptions.aMulti );
+    Range aPages( aMulti.FirstSelected(), aMulti.LastSelected() );
+    if ( aPages.Max() > USHRT_MAX )
+        aPages.Max() = USHRT_MAX;
+
+    ASSERT( aPages.Min() > 0,
+            "Seite 0 Drucken?" );
+    ASSERT( aPages.Min() <= aPages.Max(),
+            "MinSeite groesser MaxSeite." );
+
+    // eine neue Shell fuer den Printer erzeugen
+    ViewShell aShell( this, 0 );
+    aShell.pRef = new SfxPrinter( *pPrt );
+
+    SET_CURR_SHELL( &aShell );
+
+    aShell.PrepareForPrint( rOptions );
+
+    // gibt es versteckte Absatzfelder, unnoetig wenn die Absaetze bereits
+    // ausgeblendet sind.
+    int bHiddenFlds = FALSE;
+    SwFieldType* pFldType = 0;
+    if ( GetViewOptions()->IsShowHiddenPara() )
+    {
+        pFldType = GetDoc()->GetSysFldType( RES_HIDDENPARAFLD );
+        bHiddenFlds = 0 != pFldType->GetDepends();
+        if( bHiddenFlds )
+        {
+            SwMsgPoolItem aHnt( RES_HIDDENPARA_PRINT );
+            pFldType->Modify( &aHnt, 0);
+        }
+    }
+
+    // Seiten fuers Drucken formatieren
+    aShell.CalcPagesForPrint( (USHORT)aPages.Max(), &rProgress );
+
+    USHORT nCopyCnt = rOptions.bCollate ? rOptions.nCopyCount : 1;
+
+    const SwPageFrm *pStPage  = (SwPageFrm*)GetLayout()->Lower();
+
+    for( USHORT i = 1; pStPage && i < (USHORT)aPages.Min(); ++i )
+        pStPage = (SwPageFrm*)pStPage->GetNext();
+
+    if( !pStPage )          // dann wars das
+    {
+        if( bHiddenFlds )
+        {
+            SwMsgPoolItem aHnt( RES_HIDDENPARA_PRINT );
+            pFldType->Modify( &aHnt, 0);
+            CalcPagesForPrint( (USHORT)aPages.Max() );
+        }
+        return;
+    }
+
+    // unsere SttPage haben wir, dann die EndPage suchen
+    SvPtrarr aArr( 255, 255 );
+    aArr.Insert( (void*)pStPage, aArr.Count() );
+
+    while( pStPage->GetNext() && i < (USHORT)aPages.Max() )
+    {
+        pStPage = (SwPageFrm*)pStPage->GetNext();
+        if( aMulti.IsSelected( ++i ) )
+            aArr.Insert( (void*)pStPage, aArr.Count() );
+    }
+
+    // auf Doppelseiten auffuellen
+    if( 1 == aArr.Count() )     // eine Seite ist ein Sonderfall
+        aArr.Insert( (void*)0, 1 );
+    else
+    {
+        while( aArr.Count() & 3 )
+            aArr.Insert( (void*)0, aArr.Count() );
+
+        if( rOptions.bPrintReverse && 4 < aArr.Count() )
+        {
+            // das Array umsortieren
+            // Array:    1 2 3 4 5 6 7 8
+            // soll:     3 4 1 2 7 8 5 6
+            // Algorhytmus:
+            // vordere Haelfte: Austausch von 2 Pointer von Vorne vor die Haelfte
+            // hintere Haelfte: Austausch von 2 Pointer von der Haelfte nach hinten
+
+            USHORT nHalf = aArr.Count() / 2;
+            USHORT nSwapCount = nHalf / 4;
+
+            VoidPtr* ppArrStt = (VoidPtr*)aArr.GetData();
+            VoidPtr* ppArrHalf = (VoidPtr*)aArr.GetData() + nHalf;
+
+            for( int nLoop = 0; nLoop < 2; ++nLoop )
+            {
+                for( USHORT n = 0; n < nSwapCount; ++n )
+                {
+                    void* pTmp = *ppArrStt;
+                    *ppArrStt++ = *(ppArrHalf-2);
+                    *(ppArrHalf-2) = pTmp;
+
+                    pTmp = *ppArrStt;
+                    *ppArrStt++ = *--ppArrHalf;
+                    *ppArrHalf-- = pTmp;
+                }
+                ppArrStt = (VoidPtr*)aArr.GetData() + nHalf;
+                ppArrHalf = (VoidPtr*)aArr.GetData() + aArr.Count();
+            }
+        }
+    }
+
+    BOOL bStartJob = FALSE;
+
+    for( USHORT nCnt = 0; nCnt < nCopyCnt; nCnt++ )
+    {
+        if( rOptions.bSinglePrtJobs && rOptions.GetJobName().Len() &&
+            ( bStartJob || rOptions.bJobStartet ) )
+        {
+            pPrt->EndJob();
+            rOptions.bJobStartet = TRUE;
+
+            // Reschedule statt Yield, da Yield keine Events abarbeitet
+            // und es sonst eine Endlosschleife gibt.
+            while( pPrt->IsPrinting() )
+                    rProgress.Reschedule();
+
+            rOptions.MakeNextJobName();
+            bStartJob = pPrt->StartJob( rOptions.GetJobName() );
+        }
+
+        // dann sorge mal dafuer, das alle Seiten in der richtigen
+        // Reihenfolge stehen:
+        USHORT nSPg = 0, nEPg = aArr.Count(), nStep = 1;
+        if( 0 == (nEPg & 1 ))      // ungerade gibt es nicht!
+            --nEPg;
+
+        if( !rOptions.bPrintLeftPage )
+            ++nStep;
+        else if( !rOptions.bPrintRightPage )
+        {
+            ++nStep;
+            ++nSPg, --nEPg;
+        }
+
+        USHORT nCntPage = (( nEPg - nSPg ) / ( 2 * nStep )) + 1;
+
+        MapMode aOld( pPrt->GetMapMode() );
+        MapMode aMapMode( MAP_TWIP );
+        Size aPrtSize( pPrt->PixelToLogic( pPrt->GetPaperSizePixel(), aMapMode ) );
+
+        const XubString aTmp( SW_RES( STR_STATSTR_PRINT ) );
+        rProgress.SetText( aTmp );
+        //HACK, damit die Anzeige nicht durcheinander kommt:
+        rProgress.SetState( 1, nCntPage );
+        rProgress.SetText( aTmp );
+
+        for( USHORT nPrintCount = 0; nSPg < nEPg &&
+                nPrintCount < nCntPage; ++nPrintCount )
+        {
+            // Mag der Anwender noch ?
+            rProgress.Reschedule();
+
+            if ( !pPrt->IsJobActive() )
+                break;
+
+            SwTwips nMaxRowSz, nMaxColSz;
+            pStPage = (SwPageFrm*)aArr[ nSPg ];
+            const SwPageFrm* pNxtPage = nEPg < aArr.Count()
+                                ? pNxtPage = (SwPageFrm*)aArr[ nEPg ]
+                                : 0;
+
+            if( !pStPage )
+            {
+                nMaxColSz = 2 * pNxtPage->Frm().SSize().Width();
+                nMaxRowSz = pNxtPage->Frm().SSize().Height();
+            }
+            else if( !pNxtPage )
+            {
+                nMaxColSz = 2 * pStPage->Frm().SSize().Width();
+                nMaxRowSz = pStPage->Frm().SSize().Height();
+            }
+            else
+            {
+                nMaxColSz = pNxtPage->Frm().SSize().Width() +
+                            pStPage->Frm().SSize().Width();
+                nMaxRowSz = Max( pNxtPage->Frm().SSize().Height(),
+                                 pStPage->Frm().SSize().Height() );
+            }
+
+            if( 0 == ( nSPg & 1 ) )     // diese muss gespiegel werden
+            {
+                const SwPageFrm* pTmp = pStPage;
+                pStPage = pNxtPage;
+                pNxtPage = pTmp;
+            }
+
+            // den MapMode einstellen
+            aMapMode.SetOrigin( Point() );
+            {
+                Fraction aScX( aPrtSize.Width(), nMaxColSz );
+                Fraction aScY( aPrtSize.Height(), nMaxRowSz );
+                if( aScX < aScY )
+                    aScY = aScX;
+
+                {
+                    // fuer Drawing, damit diese ihre Objecte vernuenftig Painten
+                    // koennen, auf "glatte" Prozentwerte setzen
+                    aScY *= Fraction( 1000, 1 );
+                    long nTmp = (long)aScY;
+                    if( 1 < nTmp )
+                        --nTmp;
+                    else
+                        nTmp = 1;
+                    aScY = Fraction( nTmp, 1000 );
+                }
+
+                aMapMode.SetScaleY( aScY );
+                aMapMode.SetScaleX( aScY );
+            }
+
+            Point aPrtOff( pPrt->PixelToLogic(
+                                pPrt->GetPageOffsetPixel(), aMapMode ) );
+            Size aTmpPrtSize( pPrt->PixelToLogic(
+                                pPrt->GetPaperSizePixel(), aMapMode ) );
+
+            // dann kann das drucken losgehen
+            bStartJob = TRUE;
+            rProgress.SetState( nPrintCount, nCntPage );
+
+            pPrt->StartPage();
+
+            Point aSttPt;
+            for( int nC = 0; nC < 2; ++nC )
+            {
+                if( pStPage )
+                {
+                    aShell.Imp()->SetFirstVisPageInvalid();
+                    aShell.aVisArea = pStPage->Frm();
+
+                    Point aPos( aSttPt );
+                    aPos -= aShell.aVisArea.Pos();
+                    aPos -= aPrtOff;
+                    aMapMode.SetOrigin( aPos );
+                    pPrt->SetMapMode( aMapMode );
+                    pStPage->GetUpper()->Paint( pStPage->Frm() );
+                }
+
+                pStPage = pNxtPage;
+                aSttPt.X() += aTmpPrtSize.Width() / 2;
+            }
+
+            pPrt->EndPage();
+            SwPaintQueue::Repaint();
+            nSPg += nStep;
+            nEPg -= nStep;
+        }
+        pPrt->SetMapMode( aOld );
+
+        if( bHiddenFlds )
+        {
+            SwMsgPoolItem aHnt( RES_HIDDENPARA_PRINT );
+            pFldType->Modify( &aHnt, 0);
+            CalcPagesForPrint( (USHORT)aPages.Max() );
+        }
+
+        if( bStartJob )
+            rOptions.bJobStartet = TRUE;
+    }
+    pFntCache->Flush();
+}
+
+
+BOOL ViewShell::IsPreViewDocPos(
+        Point& rDocPt,              // DocPos die bestimmt und auf
+                                    // Layout Korrdination einer View umge-
+                                    // rechnet werden soll
+        USHORT nRowCol,             // Zeilen/Spalten (Row im Hi, Col im LowByte!)
+        USHORT nSttPage,            // Start ab dieser Seite, eine gueltige ??
+        const Size& rPageSize       // (Max)Size einer Seite
+        )
+{
+    BOOL bRet = FALSE;
+    SET_CURR_SHELL( this );
+
+    const SwRootFrm* pRoot = GetLayout();
+    ASSERT( pRoot, "Wo ist mein Layout?" );
+
+    BYTE nRow = BYTE(nRowCol >> 8), nCol = BYTE(nRowCol & 0xff);
+    SwPageFrm* pSttPage = ::lcl_GetSttPage( nRow, nCol, nSttPage, pRoot );
+
+    MapMode aMapMode( GetOut()->GetMapMode() );
+    MapMode aCalcMapMode( aMapMode );
+    aCalcMapMode.SetOrigin( Point() );
+
+    Point aFreePt( nPrevViewXFreePix, nPrevViewYFreePix );
+    aFreePt = GetOut()->PixelToLogic( aFreePt, aCalcMapMode );
+    Point aCalcPt( aFreePt );
+    long nPageHeight = aFreePt.Y() + rPageSize.Height()+1;
+    SwPageFrm* pPage = pSttPage;
+
+    // Sonderbehandlung fuer die erste Seite
+    // JP 19.08.98: aber nur wenn sie mehrspaltig angezeigt wird
+    int bFirstPg = !nSttPage && 1 != nCol;
+
+    for( BYTE nCntRow = 0; pPage && nCntRow < nRow; ++nCntRow )
+    {
+        aCalcPt.X() = aFreePt.X();
+        for( BYTE nCntCol = 0; pPage && nCntCol < nCol; ++nCntCol )
+        {
+            // Sonderbehandlung fuer 1. Seite, ist immer eine rechte
+            if( bFirstPg )
+            {
+                bFirstPg = FALSE;
+                aCalcPt.X() += pPage->Frm().Width()+1 + aFreePt.X();
+                continue;
+            }
+
+            if( pPage->IsEmptyPage() )
+                aCalcPt.X() += rPageSize.Width()+1 + aFreePt.X();
+            else
+            {
+                SwRect aPgRect( aCalcPt, pPage->Frm().SSize() );
+                if( aPgRect.IsInside( rDocPt ))
+                {
+                    // dann den richtigen Point errechnen:
+                    Point aOffset( rDocPt );
+                    aOffset -= aCalcPt;
+                    aOffset += pPage->Frm().Pos();
+                    rDocPt = aOffset;
+                    bRet = TRUE;
+                    break;
+                }
+                aCalcPt.X() += pPage->Frm().Width()+1 + aFreePt.X();
+            }
+            pPage = (SwPageFrm*)pPage->GetNext();
+        }
+        if( bRet )
+            break;
+
+        aCalcPt.Y() += nPageHeight;
+    }
+    return bRet;
+}
+
+Size ViewShell::GetPagePreViewPrtMaxSize() const
+{
+    Size aMaxSize;
+    register const SwFrm *pSttPage = GetLayout()->Lower();
+    while( pSttPage )
+    {
+        register const Size& rSize = pSttPage->Frm().SSize();
+        if( aMaxSize.Width() < rSize.Width() )
+            aMaxSize.Width() = rSize.Width();
+        if( aMaxSize.Height() < rSize.Height() )
+            aMaxSize.Height() = rSize.Height();
+        pSttPage = pSttPage->GetNext();
+    }
+    return aMaxSize;
+}
+
+/*************************************************************************
+
+      $Log: not supported by cvs2svn $
+      Revision 1.74  2000/09/18 16:04:37  willem.vandorp
+      OpenOffice header added.
+
+      Revision 1.73  2000/05/09 11:45:55  ama
+      Unicode changes
+
+      Revision 1.72  2000/04/27 07:37:23  os
+      UNICODE
+
+      Revision 1.71  2000/02/11 14:36:11  hr
+      #70473# changes for unicode ( patched by automated patchtool )
+
+      Revision 1.70  1999/12/14 14:28:30  jp
+      Bug #69595#: print can create single Jobs
+
+      Revision 1.69  1999/02/22 07:35:12  MA
+      1949globale Shell entsorgt, Shells am RootFrm
+
+
+      Rev 1.68   22 Feb 1999 08:35:12   MA
+   1949globale Shell entsorgt, Shells am RootFrm
+
+      Rev 1.67   14 Sep 1998 13:06:50   JP
+   Bug #56069#: keine 0 oder negative Scalierung erzeugen
+
+      Rev 1.66   19 Aug 1998 14:10:16   JP
+   Task #55252#: Sonderfall der Einspaltigkeit beachten
+
+      Rev 1.65   19 Aug 1998 11:16:30   JP
+   Task #55252#: optionale PagePreViewPrint-Einstellungen beachten
+
+      Rev 1.64   24 Jun 1998 18:45:24   MA
+   DataChanged fuer ScrollBar und Retouche, Retouche ganz umgestellt
+
+      Rev 1.63   21 Jun 1998 12:43:16   JP
+   Bug #51189#: ScrollHandling umgebaut; ab Seite 0 starten um Seite 1 & 2 nebeneinander zu sehen
+
+      Rev 1.62   19 Jun 1998 16:01:56   JP
+   neu: IsPreViewDocPos - stelle fest, ob der Point innerhalb einer Seite liegt
+
+      Rev 1.61   29 Apr 1998 09:31:28   MA
+   RetoucheBrush -> RetoucheColor
+
+      Rev 1.60   27 Apr 1998 12:28:12   AMA
+   Fix: Prospektdruck einer Selektion: Richtige Seiten drucken!
+
+      Rev 1.59   27 Jan 1998 22:35:42   JP
+   GetNumDepend durch GetDepends ersetzt
+
+      Rev 1.58   20 Nov 1997 12:39:22   MA
+   includes
+
+      Rev 1.57   03 Nov 1997 13:07:30   MA
+   precomp entfernt
+
+      Rev 1.56   29 Oct 1997 15:27:56   JP
+   PreViewPage: Leere Seiten mit anzeigen
+
+      Rev 1.55   13 Oct 1997 10:30:44   MA
+   Umbau/Vereinfachung Paint
+
+      Rev 1.54   01 Jul 1997 15:42:52   JP
+   Bug #41162#: beim drucken die Raender des Drukers herausrechen
+
+      Rev 1.53   18 Jun 1997 16:39:52   AMA
+   Fix #40745#: Formatieren fuer einen Referenzdrucker mit Zoomfaktor 1
+
+      Rev 1.52   06 Jun 1997 12:45:46   MA
+   chg: versteckte Absaetze ausblenden
+
+      Rev 1.51   14 Apr 1997 18:21:24   MA
+   #38806# Options auch fuer Prospect, jetzt mit eigener Methode
+
+      Rev 1.50   09 Feb 1997 20:58:44   JP
+   Bug #35760#: beim Core-Repaint die Bereiche der PagePreView mitteilen
+
+      Rev 1.49   19 Dec 1996 14:32:06   MA
+   #34691# BlackFont-Option uebernehmen
+
+      Rev 1.48   11 Nov 1996 09:57:56   MA
+   ResMgr
+
+      Rev 1.47   24 Aug 1996 17:10:36   JP
+   svdraw.hxx entfernt
+
+      Rev 1.46   26 Jul 1996 16:58:58   JP
+   Bug #29897#: PropectDruck - invers Druck korrekt behandeln
+
+      Rev 1.45   18 Jul 1996 07:18:18   SWG
+   ein include zu wenig
+
+      Rev 1.44   17 Jul 1996 10:53:04   OS
+   svdraw unter OS/2 ausserhalb der PCH
+
+      Rev 1.43   16 Jul 1996 15:52:36   MA
+   new: PrintPageBackground
+
+      Rev 1.42   02 Jul 1996 12:08:52   JP
+   Bug #28965#: Positionierung korrigiert/optimiert
+
+      Rev 1.41   28 Jun 1996 10:59:26   AMA
+   Fix: Kein ASSERT mehr beim Komplettausdruck der Seitenvorschau.
+
+      Rev 1.40   27 Jun 1996 19:12:14   HJS
+   includes
+
+      Rev 1.39   27 Jun 1996 19:08:36   HJS
+   includes
+
+      Rev 1.38   27 Jun 1996 16:24:28   MA
+   includes
+
+      Rev 1.37   24 Jun 1996 20:17:54   HJS
+   include hintids.hxx
+
+      Rev 1.36   11 Jun 1996 19:44:40   JP
+   Bug #27584#: kein ULONG_MAX als Item verschicken -> eigene MessageId definieren
+
+      Rev 1.35   21 Mar 1996 14:04:30   MA
+   svhxx entfernt
+
+      Rev 1.34   20 Mar 1996 11:50:46   MA
+   Warnings
+
+      Rev 1.33   08 Mar 1996 14:19:00   JP
+   kleinere Bugs beim PrintProspect behoben
+
+      Rev 1.32   07 Mar 1996 16:48:24   JP
+   neu: PrintPropect
+
+      Rev 1.31   23 Jan 1996 14:14:46   JP
+   Bug #24575#: an der Imp-Struktur die 1. sichtbare Seite setzen
+
+      Rev 1.30   30 Nov 1995 13:26:20   MA
+   opt: Desktop nicht mehr per Polygon
+
+      Rev 1.29   24 Nov 1995 17:11:46   OM
+   PCH->PRECOMPILED
+
+      Rev 1.28   14 Nov 1995 11:01:48   MA
+   Options nachgepflegt
+
+      Rev 1.27   13 Nov 1995 12:18:36   MA
+   chg: static -> lcl_
+
+      Rev 1.26   08 Nov 1995 12:17:34   AMA
+   Set statt Change (301)
+
+      Rev 1.25   29 Aug 1995 09:59:12   JP
+   Bug 18260: PrintPreView - nicht ueber den Rand hinausdrucken
+
+      Rev 1.24   22 Aug 1995 17:59:08   JP
+   Bug 17695: Print - auf der letzten Seite das Raster beibehalten
+
+      Rev 1.23   11 Aug 1995 18:10:12   JP
+   Print: reverse drucken - nicht den Speicher ueberschreiben, PageFrame-Pointer verschieben
+
+      Rev 1.22   11 Aug 1995 14:48:34   AMA
+   Fix: Kopienanzahl beim Drucken quadriert
+
+      Rev 1.21   09 Aug 1995 22:04:16   ER
+   ! global/static data _vor_ seg_eofglobals
+
+      Rev 1.20   06 Aug 1995 20:28:58   JP
+   Bug17235: erst die Wiese malen; Bug17090: nicht immer alles Painten;  Bundsteg abgeklemmt
+
+      Rev 1.19   19 Jun 1995 09:51:52   KH
+   Anpassung Metrowerks
+
+      Rev 1.18   10 May 1995 14:01:18   MA
+   fix: Painten waehrend des Druckens.
+
+      Rev 1.17   06 May 1995 14:22:32   JP
+   USHORTs als static
+
+      Rev 1.16   06 May 1995 10:08:28   JP
+   ClacPreView: WinSize in Pixel, Abstaende richtig berechnen
+
+      Rev 1.15   05 May 1995 19:35:22   AMA
+   Umbau pProgress; Fix: FontCache+PreView
+
+      Rev 1.14   03 May 1995 20:34:14   AMA
+   Umbau: SfxProgress etc.
+
+      Rev 1.13   20 Apr 1995 18:21:26   JP
+   MapMode: auf glatte Prozentwerte runden, Bugfix fuers Drucken
+
+      Rev 1.12   27 Mar 1995 20:21:28   JP
+   CalcPreView: neuer Parameter - virtuelle Seitennummer returnen (fuer StatusLeiste)
+
+      Rev 1.11   13 Mar 1995 11:38:22   KH
+   Anpassung CFRONT
+
+      Rev 1.10   09 Mar 1995 16:58:26   JP
+   PreViewPage: Visarea am Ende loeschen, dadurch Ausgabe verhindern, wenn in anderer Shell eine Eingabe erfolgt
+
+      Rev 1.9   02 Mar 1995 11:23:34   JP
+   PrintPreView: Seitenhoehe richtig errechnen
+
+      Rev 1.8   01 Mar 1995 22:35:30   JP
+   Drucken noch ein wenig verbessert
+
+      Rev 1.7   01 Mar 1995 21:05:20   JP
+   neu: Drucken (ungetestet)
+
+      Rev 1.6   28 Feb 1995 21:33:10   JP
+   PreViewPage: bei der richtigen Seite den Bundsteg malen
+
+      Rev 1.5   27 Feb 1995 11:11:26   JP
+   kleinere Bugfixes
+
+      Rev 1.4   27 Feb 1995 00:05:22   JP
+   Paint: Current Shell stezen
+
+      Rev 1.3   26 Feb 1995 15:05:18   JP
+   nochmals umgestellt, Max aller Seiten errechnen
+
+      Rev 1.2   24 Feb 1995 21:43:04   JP
+   weitere Teile implementiert
+
+      Rev 1.1   24 Feb 1995 15:46:04   JP
+   1.Seite beachten, Doppelseiten sonderbehandeln
+
+      Rev 1.0   24 Feb 1995 00:13:12   JP
+   Initial revision.
+
+*************************************************************************/
+
diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx
new file mode 100644
index 000000000000..14f2894052d0
--- /dev/null
+++ b/sw/source/core/view/viewsh.cxx
@@ -0,0 +1,2154 @@
+/*************************************************************************
+ *
+ *  $RCSfile: viewsh.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:29 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#define _SVX_PARAITEM_HXX
+#define _SVX_TEXTITEM_HXX
+
+#ifndef _SFX_PROGRESS_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_SRCHDLG_HXX //autogen
+#include 
+#endif
+#ifndef _SVDOBJ_HXX //autogen
+#include 
+#endif
+
+#ifndef _SHL_HXX
+//#include 
+#endif
+#ifndef _SWWAIT_HXX
+#include 
+#endif
+#ifndef _SWMODULE_HXX
+#include 
+#endif
+#ifndef _FESH_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _ROOTFRM_HXX
+#include 
+#endif
+#ifndef _PAGEFRM_HXX
+#include 
+#endif
+#ifndef _CNTFRM_HXX
+#include 
+#endif
+#ifndef _VIEWIMP_HXX
+#include 
+#endif
+#ifndef _FRMTOOL_HXX
+#include 
+#endif
+#ifndef _VIEWOPT_HXX
+#include 
+#endif
+#ifndef _DVIEW_HXX
+#include 
+#endif
+#ifndef _SWREGION_HXX
+#include 
+#endif
+#ifndef _HINTS_HXX
+#include 
+#endif
+#ifndef _FMTFSIZE_HXX
+#include 
+#endif
+#ifndef _DOCUFLD_HXX
+#include 
+#endif
+#ifndef _TXTFRM_HXX
+#include 
+#endif
+#ifndef _LAYACT_HXX
+#include 
+#endif
+#ifndef _MDIEXP_HXX
+#include 
+#endif
+#ifndef _SCRRECT_HXX
+#include       // SwScrollRect, SwScrollRects
+#endif
+#ifndef _FNTCACHE_HXX
+#include 
+#endif
+#ifndef _PTQUEUE_HXX
+#include 
+#endif
+#ifndef _TABFRM_HXX
+#include 
+#endif
+#ifndef _DOCSH_HXX
+#include 
+#endif
+#ifndef _PAGEDESC_HXX
+#include 
+#endif
+#ifndef _DOCUFLD_HXX
+#include 
+#endif
+#ifndef _NDOLE_HXX
+#include 
+#endif
+#ifndef _NDINDEX_HXX
+#include 
+#endif
+
+#ifndef _STATSTR_HRC
+#include 
+#endif
+
+BOOL ViewShell::bLstAct = FALSE;
+ShellResource *ViewShell::pShellRes = 0;
+Window *ViewShell::pCareWindow = 0;
+
+FASTBOOL bInSizeNotify = FALSE;
+
+DBG_NAME(LayoutIdle);
+
+TYPEINIT0(ViewShell);
+
+/******************************************************************************
+|*
+|*  ViewShell::ImplEndAction()
+|*
+|*  Letzte Aenderung    MA 04. Sep. 96
+|*
+******************************************************************************/
+
+void ViewShell::ImplEndAction( const BOOL bIdleEnd )
+{
+    //Fuer den Drucker gibt es hier nichts zu tun.
+    if ( !GetWin() || IsPreView() )
+    {
+        bPaintWorks = TRUE;
+        UISizeNotify();
+        return;
+    }
+
+    bInEndAction = TRUE;
+
+    //Laeuft hiermit das EndAction der Letzten Shell im Ring?
+    ViewShell::bLstAct = TRUE;
+    ViewShell *pSh = (ViewShell*)this->GetNext();
+    while ( pSh != this )
+    {   if ( pSh->ActionPend() )
+        {   ViewShell::bLstAct = FALSE;
+            pSh = this;
+        }
+        else
+            pSh = (ViewShell*)pSh->GetNext();
+    }
+
+    SET_CURR_SHELL( this );
+    if ( Imp()->HasDrawView() && !Imp()->GetDrawView()->IsMarkHdlHidden() )
+        Imp()->StartAction();
+
+    if ( Imp()->GetRegion() && Imp()->GetRegion()->GetOrigin() != VisArea() )
+        Imp()->DelRegions();
+
+    const FASTBOOL bExtraData = ::IsExtraData( GetDoc() );
+
+    if ( !bIdleEnd )
+    {
+        if ( Imp()->IsNextScroll() && !bExtraData )
+            Imp()->SetScroll();
+        else
+        {
+            if ( bExtraData )
+                Imp()->bScroll = FALSE;
+            Imp()->SetNextScroll();
+            Imp()->ResetScroll();
+        }
+        SwLayAction aAction( GetLayout(), Imp() );
+        aAction.SetComplete( FALSE );
+        if ( nLockPaint )
+            aAction.SetPaint( FALSE );
+        aAction.SetInputType( INPUT_KEYBOARD );
+        aAction.Action();
+        Imp()->SetScroll();
+    }
+
+    //Wenn wir selbst keine Paints erzeugen, so warten wir auf das Paint
+    //vom System. Dann ist das Clipping korrekt gesetzt; Beispiel: verschieben
+    //eines DrawObjektes.
+    if ( Imp()->GetRegion()     || Imp()->GetScrollRects() ||
+         aInvalidRect.HasArea() || bExtraData )
+    {
+        if ( !nLockPaint )
+        {
+            FASTBOOL bPaintsFromSystem = aInvalidRect.HasArea();
+            GetWin()->Update();
+            if ( aInvalidRect.HasArea() )
+            {
+                if ( bPaintsFromSystem )
+                    Imp()->AddPaintRect( aInvalidRect );
+
+                // AW 22.09.99: tell DrawView that drawing order will be rearranged
+                // to give it a chance to react with proper IAO updates
+                if (HasDrawView())
+                    GetDrawView()->ForceInvalidateMarkHandles();
+
+                ResetInvalidRect();
+                bPaintsFromSystem = TRUE;
+            }
+            bPaintWorks = TRUE;
+
+            SwRegionRects *pRegion = Imp()->GetRegion();
+
+            //JP 27.11.97: wer die Selection hided, muss sie aber auch
+            //              wieder Showen. Sonst gibt es Paintfehler!
+            //  z.B.: addional Mode, Seite vertikal hab zu sehen, in der
+            // Mitte eine Selektion und mit einem anderen Cursor an linken
+            // rechten Rand springen. Ohne ShowCrsr verschwindet die
+            // Selektion
+            BOOL bShowCrsr = (pRegion || Imp()->GetScrollRects()) &&
+                                IsA( TYPE(SwCrsrShell) );
+            if( bShowCrsr )
+                ((SwCrsrShell*)this)->HideCrsrs();
+
+            Scroll();
+            if ( bPaintsFromSystem && Imp()->pScrolledArea )
+                Imp()->FlushScrolledArea();
+
+            if ( pRegion )
+            {
+                SwRootFrm* pLayout = GetLayout();
+
+                //Erst Invert dann Compress, niemals andersherum!
+                pRegion->Invert();
+
+                const USHORT nCnt = pRegion->Count();
+                pRegion->Compress();
+
+                VirtualDevice *pVout = 0;
+                while ( pRegion->Count() )
+                {
+                    SwRect aRect( (*pRegion)[ pRegion->Count() - 1 ] );
+                    pRegion->Remove( pRegion->Count() - 1 );
+
+                    if ( bPaintsFromSystem )
+                        PaintDesktop( aRect );
+
+                    BOOL bPaint = TRUE;
+                    if ( IsEndActionByVirDev() )
+                    {
+                        //virtuelles device erzeugen und einstellen.
+                        if ( !pVout )
+                            pVout = new VirtualDevice( *GetOut() );
+                        MapMode aMapMode( GetOut()->GetMapMode() );
+                        pVout->SetMapMode( aMapMode );
+
+                        BOOL bSizeOK = TRUE;
+
+                        Rectangle aTmp1( aRect.SVRect() );
+                        aTmp1 = GetOut()->LogicToPixel( aTmp1 );
+                        Rectangle aTmp2( GetOut()->PixelToLogic( aTmp1 ) );
+                        if ( aTmp2.Left() > aRect.Left() )
+                            aTmp1.Left() = Max( 0L, aTmp1.Left() - 1L );
+                        if ( aTmp2.Top() > aRect.Top() )
+                            aTmp1.Top() = Max( 0L, aTmp1.Top() - 1L );
+                        aTmp1.Right() += 1;
+                        aTmp1.Bottom() += 1;
+                        aTmp1 = GetOut()->PixelToLogic( aTmp1 );
+                        aRect = SwRect( aTmp1 );
+
+                        const Size aTmp( pVout->GetOutputSize() );
+                        if ( aTmp.Height() < aRect.Height() ||
+                             aTmp.Width()  < aRect.Width() )
+                        {
+                            bSizeOK = pVout->SetOutputSize( aRect.SSize() );
+                        }
+                        if ( bSizeOK )
+                        {
+                            bPaint = FALSE;
+                            OutputDevice  *pOld = GetOut();
+                            pVout->SetLineColor( pOld->GetLineColor() );
+                            pVout->SetFillColor( pOld->GetFillColor() );
+                            Point aOrigin( aRect.Pos() );
+                            aOrigin.X() = -aOrigin.X(); aOrigin.Y() = -aOrigin.Y();
+                            aMapMode.SetOrigin( aOrigin );
+                            pVout->SetMapMode( aMapMode );
+                            pOut = pVout;
+                            pLayout->Paint( aRect );
+                            pOld->DrawOutDev( aRect.Pos(), aRect.SSize(),
+                                              aRect.Pos(), aRect.SSize(), *pVout );
+                            pOut = pOld;
+
+                            if( !GetViewOptions()->IsReadonly() &&
+                                GetViewOptions()->IsControl() )
+                            {
+                                Imp()->PaintLayer( pDoc->GetControlsId(), VisArea() );
+                            }
+                        }
+                    }
+                    if ( bPaint )
+                        pLayout->Paint( aRect );
+                }
+                delete pVout;
+                Imp()->DelRegions();
+            }
+            if( bShowCrsr )
+                ((SwCrsrShell*)this)->ShowCrsrs( TRUE );
+        }
+        else
+        {
+            Imp()->DelRegions();
+            bPaintWorks =  TRUE;
+        }
+    }
+    else
+        bPaintWorks = TRUE;
+
+    bInEndAction = FALSE;
+    ViewShell::bLstAct = FALSE;
+    Imp()->EndAction();
+
+
+    //Damit sich die automatischen Scrollbars auch richtig anordnen k”nnen
+    //muessen wir die Aktion hier kuenstlich beenden (EndAction loesst ein
+    //Notify aus, und das muss Start-/EndAction rufen um die  Scrollbars
+    //klarzubekommen.
+    --nStartAction;
+    UISizeNotify();
+    ++nStartAction;
+
+#ifndef PRODUCT
+    // No Scroll starts the timer to repair the scrolled area automatically
+    if( GetViewOptions()->IsTest8() )
+#endif
+    if ( Imp()->IsScrolled() )
+        Imp()->RestartScrollTimer();
+
+}
+
+/******************************************************************************
+|*
+|*  ViewShell::ImplStartAction()
+|*
+|*  Ersterstellung      MA 25. Jul. 94
+|*  Letzte Aenderung    MA 25. Jul. 94
+|*
+******************************************************************************/
+
+void ViewShell::ImplStartAction()
+{
+    bPaintWorks = FALSE;
+    Imp()->StartAction();
+}
+
+
+/******************************************************************************
+|*
+|*  ViewShell::ImplLockPaint(), ImplUnlockPaint()
+|*
+|*  Ersterstellung      MA 11. Jun. 96
+|*  Letzte Aenderung    MA 11. Jun. 96
+|*
+******************************************************************************/
+
+void ViewShell::ImplLockPaint()
+{
+    if ( GetWin() && GetWin()->IsVisible() )
+        GetWin()->EnablePaint( FALSE ); //Auch die Controls abklemmen.
+    Imp()->LockPaint();
+}
+
+
+void ViewShell::ImplUnlockPaint( BOOL bVirDev )
+{
+    SET_CURR_SHELL( this );
+    if ( GetWin() && GetWin()->IsVisible() )
+    {
+        if ( (bInSizeNotify || bVirDev ) && VisArea().HasArea() )
+        {
+            //Refresh mit virtuellem Device um das Flackern zu verhindern.
+            VirtualDevice *pVout = new VirtualDevice( *pOut );
+            pVout->SetMapMode( pOut->GetMapMode() );
+            Size aSize( VisArea().SSize() );
+            aSize.Width() += 20;
+            aSize.Height()+= 20;
+            if( pVout->SetOutputSize( aSize ) )
+            {
+                GetWin()->EnablePaint( TRUE );
+                GetWin()->Validate();
+
+                Imp()->UnlockPaint();
+                pVout->SetLineColor( pOut->GetLineColor() );
+                pVout->SetFillColor( pOut->GetFillColor() );
+                OutputDevice *pOld = pOut;
+                pOut = pVout;
+                Paint( VisArea().SVRect() );
+                pOut = pOld;
+                pOut->DrawOutDev( VisArea().Pos(), aSize,
+                                  VisArea().Pos(), aSize, *pVout );
+                if( GetViewOptions()->IsControl() )
+                {
+                    Imp()->PaintLayer( pDoc->GetControlsId(), VisArea() );
+                    GetWin()->Update();//Damit aktive, transparente Controls auch
+                                       //gleich durchkommen
+                }
+            }
+            else
+            {
+                Imp()->UnlockPaint();
+                GetWin()->EnablePaint( TRUE );
+                GetWin()->Invalidate( INVALIDATE_CHILDREN );
+            }
+            delete pVout;
+        }
+        else
+        {
+            Imp()->UnlockPaint();
+            GetWin()->EnablePaint( TRUE );
+            GetWin()->Invalidate( INVALIDATE_CHILDREN );
+        }
+    }
+    else
+        Imp()->UnlockPaint();
+}
+
+/******************************************************************************
+|*
+|*  ViewShell::AddPaintRect()
+|*
+|*  Ersterstellung      MA ??
+|*  Letzte Aenderung    MA 09. Feb. 97
+|*
+******************************************************************************/
+
+BOOL ViewShell::AddPaintRect( const SwRect & rRect )
+{
+    BOOL bRet = FALSE;
+    ViewShell *pSh = this;
+    do
+    {
+        if ( pSh->IsPreView() && pSh->GetWin() )
+//          pSh->GetWin()->Invalidate();
+            ::RepaintPagePreview( pSh, rRect );
+        else
+            bRet |= pSh->Imp()->AddPaintRect( rRect );
+        pSh = (ViewShell*)pSh->GetNext();
+
+    } while ( pSh != this );
+    return bRet;
+}
+
+/******************************************************************************
+|*
+|*  ViewShell::InvalidateWindows()
+|*
+|*  Ersterstellung      MA ??
+|*  Letzte Aenderung    MA 09. Feb. 97
+|*
+******************************************************************************/
+
+void ViewShell::InvalidateWindows( const SwRect &rRect )
+{
+    if ( !Imp()->IsCalcLayoutProgress() )
+    {
+        ViewShell *pSh = this;
+        do
+        {
+            if ( pSh->GetWin() )
+            {
+                if ( pSh->IsPreView() )
+//                  pSh->GetWin()->Invalidate();
+                    ::RepaintPagePreview( pSh, rRect );
+                else if ( pSh->VisArea().IsOver( rRect ) )
+                    pSh->GetWin()->Invalidate( rRect.SVRect() );
+            }
+            pSh = (ViewShell*)pSh->GetNext();
+
+        } while ( pSh != this );
+    }
+}
+
+/******************************************************************************
+|*
+|*  ViewShell::MakeVisible()
+|*
+|*  Ersterstellung      MA ??
+|*  Letzte Aenderung    AMA 10. Okt. 95
+|*
+******************************************************************************/
+
+void ViewShell::MakeVisible( const SwRect &rRect )
+{
+    if ( !VisArea().IsInside( rRect ) || IsScrollMDI( this, rRect ) || GetCareWin() )
+    {
+        if ( !IsViewLocked() )
+        {
+            if( pWin )
+            {
+                StartAction();
+                ScrollMDI( this, rRect, USHRT_MAX, USHRT_MAX );
+                EndAction();
+            }
+#ifndef PRODUCT
+            else
+            {
+                //MA: 04. Nov. 94, braucht doch keiner oder??
+                ASSERT( !this, "MakeVisible fuer Drucker wird doch gebraucht?" );
+        /*
+                aVisArea = rRect;
+                MapMode aMapMode( GetPrt()->GetMapMode() );
+                Point aPt( rRect.Pos() );
+                aPt.X() = -aPt.X(); aPt.Y() = -aPt.Y();
+                aMapMode.SetOrigin( aPt );
+                GetPrt()->SetMapMode( aMapMode );
+                SetFirstVisPageInvalid();
+        */
+            }
+
+#endif
+        }
+    }
+}
+
+/******************************************************************************
+|*
+|*  ViewShell::CareChildWindow()
+|*
+|*  Ersterstellung      AMA 10. Okt. 95
+|*  Letzte Aenderung    AMA 10. Okt. 95
+|*
+******************************************************************************/
+
+Window* ViewShell::CareChildWin()
+{
+    const USHORT nId = SvxSearchDialogWrapper::GetChildWindowId();
+    SfxViewFrame* pVFrame = SfxViewFrame::Current();
+    const SfxChildWindow* pChWin = pVFrame->GetChildWindow( nId );
+    Window *pWin = pChWin ? pChWin->GetWindow() : NULL;
+    if ( pWin && pWin->IsVisible() )
+        return pWin;
+
+    return NULL;
+}
+
+/******************************************************************************
+|*
+|*  ViewShell::GetPagePos()
+|*
+|*  Ersterstellung      MA ??
+|*  Letzte Aenderung    MA 04. Aug. 93
+|*
+******************************************************************************/
+
+Point ViewShell::GetPagePos( USHORT nPageNum ) const
+{
+    return GetLayout()->GetPagePos( nPageNum );
+}
+
+/******************************************************************************
+|*
+|*  ViewShell::GetNumPages()
+|*
+|*  Ersterstellung      MA ??
+|*  Letzte Aenderung    MA 20. Apr. 94
+|*
+******************************************************************************/
+
+USHORT ViewShell::GetNumPages()
+{
+    //Es kann sein, das noch kein Layout existiert weil die Methode vom
+    //Root-Ctor gerufen wird.
+    return GetLayout() ? GetLayout()->GetPageNum() : 0;
+}
+
+/*************************************************************************
+|*
+|*                  ViewShell::UpdateFlds()
+|*
+|*    Ersterstellung    BP 04.05.92
+|*    Beschreibung      erzwingt ein Update fuer jedes Feld
+|*
+|*  UpdateFlds benachrichtigt alle Felder mit pNewHt.
+|*  Wenn pNewHt == 0 ist (default), wird der Feldtyp verschickt.
+|*
+*************************************************************************/
+
+void ViewShell::UpdateFlds(BOOL bCloseDB)
+{
+    SET_CURR_SHELL( this );
+
+    BOOL bCrsr = ISA(SwCrsrShell);
+    if ( bCrsr )
+        ((SwCrsrShell*)this)->StartAction();
+    else
+        StartAction();
+
+    GetDoc()->UpdateFlds(0, bCloseDB);
+
+    if ( bCrsr )
+        ((SwCrsrShell*)this)->EndAction();
+    else
+        EndAction();
+}
+
+// update all charts, for that exists any table
+void ViewShell::UpdateAllCharts()
+{
+    SET_CURR_SHELL( this );
+    // Start-/EndAction handled in the SwDoc-Method!
+    GetDoc()->UpdateAllCharts();
+}
+
+BOOL ViewShell::HasCharts() const
+{
+    BOOL bRet = FALSE;
+    const SwStartNode *pStNd;
+    SwNodeIndex aIdx( *GetDoc()->GetNodes().GetEndOfAutotext().
+                        StartOfSectionNode(), 1 );
+    while ( 0 != (pStNd = aIdx.GetNode().GetStartNode()) )
+    {
+        aIdx++;
+        const SwOLENode *pNd = aIdx.GetNode().GetOLENode();
+        if( pNd && pNd->GetChartTblName().Len() )
+        {
+            bRet = TRUE;
+            break;
+        }
+    }
+    return bRet;
+}
+
+/*************************************************************************
+|*
+|*    ViewShell::LayoutIdle()
+|*
+|*    Ersterstellung    MA 26. May. 92
+|*    Letzte Aenderung  OG 19. Mar. 96
+|*
+*************************************************************************/
+
+void ViewShell::LayoutIdle()
+{
+#ifdef TCOVER
+    //fuer TCV-Version: Ende der Startphase des Programmes
+    TCovCall::Idle();
+#endif
+    if( !pOpt->IsIdle() || !GetWin() ||
+        ( Imp()->HasDrawView() && Imp()->GetDrawView()->IsDragObj() ) )
+        return;
+
+    //Kein Idle wenn gerade gedruckt wird.
+    ViewShell *pSh = this;
+    do
+    {   if ( !pSh->GetWin() )
+            return;
+        pSh = (ViewShell*)pSh->GetNext();
+
+    } while ( pSh != this );
+
+    SET_CURR_SHELL( this );
+
+#ifndef PRODUCT
+    // Wenn Test5 gedrueckt ist, wird der IdleFormatierer abgeknipst.
+    if( pOpt->IsTest5() )
+        return;
+#endif
+
+    {
+        DBG_PROFSTART( LayoutIdle );
+
+        //Cache vorbereiten und restaurieren, damit er nicht versaut wird.
+        SwSaveSetLRUOfst aSave( *SwTxtFrm::GetTxtCache(),
+                             SwTxtFrm::GetTxtCache()->GetCurMax() - 50 );
+        SwLayIdle aIdle( GetLayout(), Imp() );
+        DBG_PROFSTOP( LayoutIdle );
+    }
+}
+
+// Absatzabstaende koennen wahlweise addiert oder maximiert werden
+
+BOOL ViewShell::IsParaSpaceMax() const
+{
+    return GetDoc()->IsParaSpaceMax();
+}
+
+BOOL ViewShell::IsParaSpaceMaxAtPages() const
+{
+    return GetDoc()->IsParaSpaceMaxAtPages();
+}
+
+
+void ViewShell::SetParaSpaceMax( BOOL bNew, BOOL bAtPages )
+{
+    if( GetDoc()->IsParaSpaceMax() != bNew  ||
+    GetDoc()->IsParaSpaceMaxAtPages() != bAtPages )
+    {
+        SwWait aWait( *GetDoc()->GetDocShell(), TRUE );
+        GetDoc()->SetParaSpaceMax( bNew, bAtPages );
+        BOOL bCrsr = ISA(SwCrsrShell);
+        if ( bCrsr )
+            ((SwCrsrShell*)this)->StartAction();
+        else
+            StartAction();
+        GetLayout()->InvalidateAllCntnt( INV_PRTAREA | INV_TABLE | INV_SECTION );
+        if ( bCrsr )
+            ((SwCrsrShell*)this)->EndAction();
+        else
+            EndAction();
+    }
+}
+
+/******************************************************************************
+|*
+|*  ViewShell::Reformat
+|*
+|*  Ersterstellung      BP ???
+|*  Letzte Aenderung    MA 13. Feb. 98
+|*
+******************************************************************************/
+
+void ViewShell::Reformat()
+{
+    SwWait aWait( *GetDoc()->GetDocShell(), TRUE );
+
+    // Wir gehen auf Nummer sicher:
+    // Wir muessen die alten Fontinformationen wegschmeissen,
+    // wenn die Druckeraufloesung oder der Zoomfaktor sich aendert.
+    // Init() und Reformat() sind die sichersten Stellen.
+#ifdef FNTMET
+    aFntMetList.Flush();
+#else
+    pFntCache->Flush( );
+#endif
+
+    StartAction();
+    GetLayout()->InvalidateAllCntnt();
+    EndAction();
+}
+
+/******************************************************************************
+|*
+|*  ViewShell::CalcLayout()
+|*                  Vollstaendige Formatierung von Layout und Inhalt.
+|*
+|*  Ersterstellung      MA 31. Jan. 94
+|*  Letzte Aenderung    MA 08. Oct. 96
+|*
+******************************************************************************/
+
+void ViewShell::CalcLayout()
+{
+    SET_CURR_SHELL( this );
+    SwWait aWait( *GetDoc()->GetDocShell(), TRUE );
+
+    //Cache vorbereiten und restaurieren, damit er nicht versaut wird.
+    SwSaveSetLRUOfst aSaveLRU( *SwTxtFrm::GetTxtCache(),
+                                  SwTxtFrm::GetTxtCache()->GetCurMax() - 50 );
+
+    //Progress einschalten wenn noch keiner Lauft.
+    const BOOL bEndProgress = SfxProgress::GetActiveProgress( GetDoc()->GetDocShell() ) == 0;
+    if ( bEndProgress )
+    {
+        USHORT nEndPage = GetLayout()->GetPageNum();
+        nEndPage += nEndPage * 10 / 100;
+        ::StartProgress( STR_STATSTR_REFORMAT, 0, nEndPage, GetDoc()->GetDocShell() );
+    }
+
+    SwLayAction aAction( GetLayout(), Imp() );
+    aAction.SetPaint( FALSE );
+    aAction.SetStatBar( TRUE );
+    aAction.SetCalcLayout( TRUE );
+    aAction.SetReschedule( TRUE );
+    GetDoc()->LockExpFlds();
+    aAction.Action();
+    GetDoc()->UnlockExpFlds();
+
+    //Das SetNewFldLst() am Doc wurde unterbunden und muss nachgeholt
+    //werden (siehe flowfrm.cxx, txtfld.cxx)
+    if ( aAction.IsExpFlds() )
+    {
+        aAction.Reset();
+        aAction.SetPaint( FALSE );
+        aAction.SetStatBar( TRUE );
+        aAction.SetReschedule( TRUE );
+
+        SwDocPosUpdate aMsgHnt( 0 );
+        GetDoc()->UpdatePageFlds( &aMsgHnt );
+        GetDoc()->UpdateExpFlds();
+
+        aAction.Action();
+    }
+
+    if ( VisArea().HasArea() )
+        InvalidateWindows( VisArea() );
+    if ( bEndProgress )
+        ::EndProgress( GetDoc()->GetDocShell() );
+}
+
+/******************************************************************************
+|*
+|*  ViewShell::SetFirstVisPageInvalid()
+|*
+|*  Ersterstellung      MA 19. May. 94
+|*  Letzte Aenderung    MA 19. May. 94
+|*
+******************************************************************************/
+
+void ViewShell::SetFirstVisPageInvalid()
+{
+    ViewShell *pSh = this;
+    do
+    {   pSh->Imp()->SetFirstVisPageInvalid();
+        pSh = (ViewShell*)pSh->GetNext();
+
+    } while ( pSh != this );
+}
+
+/******************************************************************************
+|*
+|*  ViewShell::SizeChgNotify()
+|*
+|*  Ersterstellung      MA ??
+|*  Letzte Aenderung    MA 17. Sep. 96
+|*
+******************************************************************************/
+
+void ViewShell::SizeChgNotify(const Size &rSize)
+{
+    if ( !pWin )
+        bDocSizeChgd = TRUE;
+    else if( ActionPend() || Imp()->IsCalcLayoutProgress() || bPaintInProgress )
+    {
+        bDocSizeChgd = TRUE;
+
+        if ( !Imp()->IsCalcLayoutProgress() && ISA( SwCrsrShell ) )
+        {
+            const SwFrm *pCnt = ((SwCrsrShell*)this)->GetCurrFrm( FALSE );
+            const SwPageFrm *pPage;
+            if ( pCnt && 0 != (pPage = pCnt->FindPageFrm()) )
+            {
+                USHORT nVirtNum = pPage->GetVirtPageNum();
+                 const SwNumType& rNum = pPage->GetPageDesc()->GetNumType();
+                String sDisplay = rNum.GetNumStr( nVirtNum );
+                PageNumNotify( this, pCnt->GetPhyPageNum(), nVirtNum, sDisplay );
+            }
+        }
+    }
+    else
+    {
+        bDocSizeChgd = FALSE;
+        ::SizeNotify( this, GetLayout()->Frm().SSize() );
+    }
+}
+
+/******************************************************************************
+|*
+|*  ViewShell::VisPortChgd()
+|*
+|*  Ersterstellung      MA ??
+|*  Letzte Aenderung    MA 22. Jul. 96
+|*
+******************************************************************************/
+
+void ViewShell::VisPortChgd( const SwRect &rRect)
+{
+    ASSERT( GetWin(), "VisPortChgd ohne Window." );
+
+    if ( rRect == VisArea() )
+        return;
+
+#ifndef PRODUCT
+    if ( bInEndAction )
+    {
+        //Da Rescheduled doch schon wieder irgendwo einer?
+        ASSERT( !this, "Scroll waehrend einer EndAction." );
+    }
+#endif
+
+    ASSERT( rRect.Top() >= 0 && rRect.Left() >= 0 &&
+            rRect.Bottom() >= 0 && rRect.Right() >= 0,
+            "VisArea in die Wiese?" );
+
+    //Ersteinmal die alte sichtbare Seite holen, dann braucht nacher nicht
+    //lange gesucht werden.
+    const SwFrm *pOldPage = Imp()->GetFirstVisPage();
+
+    const SwRect aPrevArea( VisArea() );
+    const BOOL bFull = aPrevArea.IsEmpty();
+    aVisArea = rRect;
+    SetFirstVisPageInvalid();
+
+    //Wenn noch eine PaintRegion herumsteht und sich die VisArea geaendert hat,
+    //so ist die PaintRegion spaetestens jetzt obsolete. Die PaintRegion kann
+    //vom RootFrm::Paint erzeugt worden sein.
+    if ( !bInEndAction &&
+         Imp()->GetRegion() && Imp()->GetRegion()->GetOrigin() != VisArea() )
+        Imp()->DelRegions();
+
+    SET_CURR_SHELL( this );
+
+    SwSaveHdl aSaveHdl( Imp() );
+
+    if ( bFull )
+        GetWin()->Invalidate();
+    else
+    {
+        // Betrag ausrechnen, um den gescrolled werden muss.
+        const long nXDiff = aPrevArea.Left() - VisArea().Left();
+        const long nYDiff = aPrevArea.Top()  - VisArea().Top();
+
+        if( !nXDiff && !GetDoc()->IsBrowseMode() &&
+            (!Imp()->HasDrawView() || !Imp()->GetDrawView()->IsGridVisible() ) )
+        {
+            //Falls moeglich die Wiese nicht mit Scrollen.
+            //Also linke und rechte Kante des Scrollbereiches auf die
+            //Seiten begrenzen.
+            const SwPageFrm *pPage = (SwPageFrm*)GetDoc()->GetRootFrm()->Lower();
+            if ( pPage->Frm().Top() > pOldPage->Frm().Top() )
+                pPage = (SwPageFrm*)pOldPage;
+            SwRect aBoth( VisArea() );
+            aBoth.Union( aPrevArea );
+            const SwTwips nBottom = aBoth.Bottom();
+            const SwTwips nRight  = aBoth.Right();
+            SwTwips nMinLeft = LONG_MAX;
+            SwTwips nMaxRight= 0;
+            while ( pPage &&
+                    !((pPage->Frm().Top()  > nBottom) ||
+                        (pPage->Frm().Left() > nRight)))
+            {
+                if ( pPage->Frm().IsOver( aBoth ) )
+                {
+                    if( pPage->Frm().Left() < nMinLeft )
+                        nMinLeft = pPage->Frm().Left();
+                    if( pPage->Frm().Right() > nMaxRight )
+                        nMaxRight = pPage->Frm().Right();
+                    //Zus. auf die Zeichenobjekte abgleichen.
+                    //Einen Ofst beruecksichtigen, weil die Objekte u.U.
+                    //selektiert sind und die Henkel dann hinausstehen.
+                    if ( pPage->GetSortedObjs() )
+                    {
+                        const long nOfst = GetOut()->PixelToLogic(
+                            Size(Imp()->GetDrawView()->GetMarkHdlSizePixel()/2,0)).Width();
+                        for ( USHORT i = 0;
+                              i < pPage->GetSortedObjs()->Count(); ++i )
+                        {
+                            SdrObject *pObj = (*pPage->GetSortedObjs())[i];
+//JP 22.12.99: why ignore FlyFrames? The result is Bug 69762 for FlyFrames
+//                          if ( pObj->IsWriterFlyFrame() )
+//                              continue;
+                            const Rectangle &rBound = pObj->GetBoundRect();
+                            USHORT nL = Max( 0L, rBound.Left() - nOfst );
+                            if ( nL < nMinLeft )
+                                nMinLeft = nL;
+                            if( rBound.Right() + nOfst > nMaxRight )
+                                nMaxRight = rBound.Right() + nOfst;
+                        }
+                    }
+                }
+                pPage = (SwPageFrm*)pPage->GetNext();
+            }
+            Rectangle aRect( aPrevArea.SVRect() );
+            aRect.Left()  = nMinLeft;
+            aRect.Right() = nMaxRight;
+            if( VisArea().IsOver( aPrevArea ) && !nLockPaint )
+            {
+                aVisArea.Pos() = aPrevArea.Pos();
+                if ( SmoothScroll( nXDiff, nYDiff, &aRect ) )
+                    return;
+                aVisArea.Pos() = rRect.Pos();
+            }
+            else
+                GetWin()->Invalidate( aRect );
+        }
+        else if ( !nLockPaint ) //Wird im UnLock erledigt
+        {
+            if( VisArea().IsOver( aPrevArea ) )
+            {
+                aVisArea.Pos() = aPrevArea.Pos();
+                if ( SmoothScroll( nXDiff, nYDiff, 0 ) )
+                    return;
+                aVisArea.Pos() = rRect.Pos();
+            }
+            else
+                GetWin()->Invalidate();
+        }
+    }
+
+    Point aPt( VisArea().Pos() );
+    aPt.X() = -aPt.X(); aPt.Y() = -aPt.Y();
+    MapMode aMapMode( GetWin()->GetMapMode() );
+    aMapMode.SetOrigin( aPt );
+    GetWin()->SetMapMode( aMapMode );
+    if ( HasDrawView() )
+    {
+        Imp()->GetDrawView()->VisAreaChanged( GetWin() );
+        Imp()->GetDrawView()->SetActualWin( GetWin() );
+    }
+    Imp()->bPaintInScroll = TRUE;
+    GetWin()->Update();
+    Imp()->bPaintInScroll = FALSE;
+}
+
+/******************************************************************************
+|*
+|*  ViewShell::SmoothScroll()
+|*
+|*  Ersterstellung      MA 04. Jul. 96
+|*  Letzte Aenderung    MA 25. Mar. 97
+|*
+******************************************************************************/
+
+BOOL ViewShell::SmoothScroll( long lXDiff, long lYDiff, const Rectangle *pRect )
+{
+    const ULONG nColCnt = pOut->GetColorCount();
+    long lMult = 1, lMax = LONG_MAX;
+    if ( nColCnt == 65536 )
+    {
+        lMax = 7000;
+        lMult = 2;
+    }
+    if ( nColCnt == 16777216 )
+    {
+        lMax = 5000;
+        lMult = 6;
+    }
+    else if ( nColCnt == 1 )
+    {
+        lMax = 3000;
+        lMult = 12;
+    }
+
+    if ( !lXDiff && bEnableSmooth && Abs(lYDiff) < lMax &&
+         GetViewOptions()->IsSmoothScroll() &&
+         (!ISA( SwCrsrShell ) ||
+          (!((SwCrsrShell*)this)->HasSelection() &&
+           ((SwCrsrShell*)this)->GetCrsrCnt() < 2)) &&
+         GetWin()->GetWindowClipRegionPixel(
+             WINDOW_GETCLIPREGION_NOCHILDREN|WINDOW_GETCLIPREGION_NULL )
+                                                            .IsNull() )
+    {
+        Imp()->bStopSmooth = FALSE;
+
+        const SwRect aOldVis( VisArea() );
+
+        //Virtuelles Device erzeugen und einstellen.
+        const Size aPixSz = GetWin()->PixelToLogic(Size(1,1));
+        VirtualDevice *pVout = new VirtualDevice( *GetWin() );
+        pVout->SetLineColor( GetWin()->GetLineColor() );
+        pVout->SetFillColor( GetWin()->GetFillColor() );
+        MapMode aMapMode( GetWin()->GetMapMode() );
+        pVout->SetMapMode( aMapMode );
+        Size aSize( aVisArea.Width()+2*aPixSz.Width(), Abs(lYDiff)+(2*aPixSz.Height()) );
+        if ( pRect )
+            aSize.Width() = Min(aSize.Width(), pRect->GetWidth()+2*aPixSz.Width());
+        if ( pVout->SetOutputSize( aSize ) )
+        {
+            nLockPaint++;
+
+            //Ersteinmal alles neue in das VirDev Painten.
+            SwRect aRect( VisArea() );
+            aRect.Height( aSize.Height() );
+            if ( pRect )
+            {
+                aRect.Pos().X() = Max(aRect.Left(),pRect->Left()-aPixSz.Width());
+                aRect.Right( Min(aRect.Right()+2*aPixSz.Width(), pRect->Right()+aPixSz.Width()));
+            }
+            else
+                aRect.SSize().Width() += 2*aPixSz.Width();
+            aRect.Pos().Y() = lYDiff < 0 ? aOldVis.Bottom() - aPixSz.Height()
+                                         : aRect.Top() - aSize.Height() + aPixSz.Height();
+            aRect.Pos().X() = Max( 0L, aRect.Left()-aPixSz.Width() );
+            aRect.Pos()  = GetWin()->PixelToLogic( GetWin()->LogicToPixel( aRect.Pos()));
+            aRect.SSize()= GetWin()->PixelToLogic( GetWin()->LogicToPixel( aRect.SSize()));
+            aVisArea = aRect;
+            const Point aPt( -aRect.Left(), -aRect.Top() );
+            aMapMode.SetOrigin( aPt );
+            pVout->SetMapMode( aMapMode );
+            OutputDevice *pOld = pOut;
+            pOut = pVout;
+            PaintDesktop( aRect );
+            ViewShell::bLstAct = TRUE;
+            GetLayout()->Paint( aRect );
+            ViewShell::bLstAct = FALSE;
+            pOut = pOld;
+            aVisArea = aOldVis;
+            BOOL bControls = GetViewOptions()->IsControl();
+
+
+            //Jetzt Stueckchenweise schieben und die neuen Pixel aus dem
+            //VirDev  kopieren.
+
+            // ??????????????????????
+            // or is it better to get the scrollfactor from the User
+            // as option?
+            // ??????????????????????
+            long lMaDelta = aPixSz.Height();
+            if ( Abs(lYDiff) > ( aVisArea.Height() / 3 ) )
+                lMaDelta *= 6;
+            else
+                lMaDelta *= 2;
+
+            lMaDelta *= lMult;
+
+            if ( lYDiff < 0 )
+                lMaDelta = -lMaDelta;
+
+            long lDiff = lYDiff;
+            while ( lDiff )
+            {
+                long lScroll;
+                if ( Imp()->bStopSmooth || Abs(lDiff) <= Abs(lMaDelta) )
+                {
+                    lScroll = lDiff;
+                    lDiff = 0;
+                }
+                else
+                {
+                    lScroll = lMaDelta;
+                    lDiff -= lMaDelta;
+                }
+
+                SwRect aOldVis = VisArea();
+                aVisArea.Pos().Y() -= lScroll;
+                aVisArea.Pos() = GetWin()->PixelToLogic( GetWin()->LogicToPixel( VisArea().Pos()));
+                lScroll = aOldVis.Top() - VisArea().Top();
+                if ( pRect )
+                {
+                    Rectangle aTmp( aOldVis.SVRect() );
+                    aTmp.Left() = pRect->Left();
+                    aTmp.Right()= pRect->Right();
+                    GetWin()->Scroll( 0, lScroll, aTmp, SCROLL_CHILDREN );
+                }
+                else
+                    GetWin()->Scroll( 0, lScroll, SCROLL_CHILDREN );
+                const Point aPt( -VisArea().Left(), -VisArea().Top() );
+                MapMode aMapMode( GetWin()->GetMapMode() );
+                aMapMode.SetOrigin( aPt );
+                GetWin()->SetMapMode( aMapMode );
+
+                if ( Imp()->HasDrawView() )
+                    Imp()->GetDrawView()->VisAreaChanged( GetWin() );
+
+                SetFirstVisPageInvalid();
+                if ( !Imp()->bStopSmooth )
+                {
+                    Imp()->aSmoothRect = VisArea();
+                    if ( lScroll > 0 )
+                        Imp()->aSmoothRect.Bottom( VisArea().Top() +
+                                    lScroll + aPixSz.Height() );
+                    else
+                        Imp()->aSmoothRect.Top( VisArea().Bottom() +
+                                    lScroll + aPixSz.Height() );
+
+                    Imp()->bSmoothUpdate = TRUE;
+                    GetWin()->Update();
+                    Imp()->bSmoothUpdate = FALSE;
+
+                    if ( !Imp()->bStopSmooth )
+                    {
+                        SwRect &rTmp = Imp()->aSmoothRect;
+                        rTmp.Pos().Y() -= aPixSz.Height();
+                        rTmp.Pos().X() -= aPixSz.Width();
+                        rTmp.SSize().Height() += 2*aPixSz.Height();
+                        rTmp.SSize().Width() += 2*aPixSz.Width();
+                        GetWin()->DrawOutDev( rTmp.Pos(), rTmp.SSize(),
+                                                rTmp.Pos(), rTmp.SSize(),
+                                                *pVout );
+                        if( bControls )
+                            Imp()->PaintLayer( pDoc->GetControlsId(), rTmp );
+                    }
+                    else
+                        --nLockPaint;
+                }
+            }
+            delete pVout;
+            GetWin()->Update();
+            if ( !Imp()->bStopSmooth )
+                --nLockPaint;
+            SetFirstVisPageInvalid();
+            return TRUE;
+        }
+        delete pVout;
+    }
+//#endif
+    aVisArea.Pos().X() -= lXDiff;
+    aVisArea.Pos().Y() -= lYDiff;
+    if ( pRect )
+        GetWin()->Scroll( lXDiff, lYDiff, *pRect, SCROLL_CHILDREN );
+    else
+        GetWin()->Scroll( lXDiff, lYDiff, SCROLL_CHILDREN );
+    return FALSE;
+}
+
+/******************************************************************************
+|*
+|*  ViewShell::PaintDesktop()
+|*
+|*  Ersterstellung      MA 16. Dec. 93
+|*  Letzte Aenderung    MA 30. Nov. 95
+|*
+******************************************************************************/
+
+void ViewShell::PaintDesktop( const SwRect &rRect )
+{
+    if ( !GetWin() && !GetOut()->GetConnectMetaFile() )
+        return;                     //Fuer den Drucker tun wir hier nix
+
+    //Sonderfaelle abfangen, damit es nicht gar so ueberraschend aussieht.
+    //Kann z.B. waehrend des Idle'ns zwischenzeitlich auftreten.
+    //Die Rechtecke neben den Seiten muessen wir leider auf jedenfall Painten,
+    //den diese werden spaeter beim VisPortChgd ausgespart.
+    FASTBOOL bBorderOnly = FALSE;
+    const SwRootFrm *pRoot = GetDoc()->GetRootFrm();
+    if ( rRect.Top() > pRoot->Frm().Bottom() )
+    {
+        const SwFrm *pPg = pRoot->Lower();
+        while ( pPg && pPg->GetNext() )
+            pPg = pPg->GetNext();
+        if ( !pPg || !pPg->Frm().IsOver( VisArea() ) )
+            bBorderOnly = TRUE;
+    }
+
+    SwRegionRects aRegion( rRect );
+
+    if ( bBorderOnly )
+    {
+        const SwFrm *pPage = pRoot->Lower();
+        SwRect aLeft( rRect ), aRight( rRect );
+        while ( pPage )
+        {
+            long nTmp = pPage->Frm().Left();
+            if ( nTmp < aLeft.Right() )
+                aLeft.Right( nTmp );
+            nTmp = pPage->Frm().Right();
+            if ( nTmp > aRight.Left() )
+                aRight.Left( nTmp );
+            pPage = pPage->GetNext();
+        }
+        aRegion.Remove( 0, aRegion.Count() );
+        if ( aLeft.HasArea() )
+            aRegion.Insert( aLeft, 0 );
+        if ( aRight.HasArea() )
+            aRegion.Insert( aRight, 1 );
+    }
+    else
+    {
+        const SwFrm *pPage = Imp()->GetFirstVisPage();
+        const SwTwips nBottom = rRect.Bottom();
+        const SwTwips nRight  = rRect.Right();
+        while ( pPage && aRegion.Count() &&
+                !((pPage->Frm().Top() > nBottom) || (pPage->Frm().Left() > nRight)))
+        {
+            if ( pPage->Frm().IsOver( rRect ) )
+                aRegion -= pPage->Frm();
+            pPage = pPage->GetNext();
+        }
+    }
+    if ( aRegion.Count() )
+        _PaintDesktop( aRegion );
+}
+
+
+// PaintDesktop gesplittet, dieser Teil wird auch von PreViewPage benutzt
+void ViewShell::_PaintDesktop( const SwRegionRects &rRegion )
+{
+    GetOut()->Push( PUSH_FILLCOLOR );
+    GetOut()->SetFillColor( Color(RGB_COLORDATA( 0xE0, 0xE0, 0xE0 )) );
+    for ( USHORT i = 0; i < rRegion.Count(); ++i )
+        GetOut()->DrawRect( rRegion[i].SVRect() );
+    GetOut()->Pop();
+}
+
+/******************************************************************************
+|*
+|*  ViewShell::CheckInvalidForPaint()
+|*
+|*  Ersterstellung      MA 19. May. 94
+|*  Letzte Aenderung    MA 09. Jun. 94
+|*
+******************************************************************************/
+
+BOOL ViewShell::CheckInvalidForPaint( const SwRect &rRect )
+{
+    if ( !GetWin() )
+        return FALSE;
+
+    const SwPageFrm *pPage = Imp()->GetFirstVisPage();
+    const SwTwips nBottom = VisArea().Bottom();
+    const SwTwips nRight  = VisArea().Right();
+    BOOL bRet = FALSE;
+    while ( !bRet && pPage && !((pPage->Frm().Top()  > nBottom) ||
+                                   (pPage->Frm().Left() > nRight)))
+    {
+        if ( pPage->IsInvalid() || pPage->IsInvalidFly() )
+            bRet = TRUE;
+        pPage = (SwPageFrm*)pPage->GetNext();
+    }
+
+    if ( bRet )
+    {
+        //Start/EndAction wuerden hier leider nix helfen, weil das Paint vom
+        //GUI 'reinkam und somit ein Clipping gesetzt ist gegen das wir nicht
+        //nicht ankommen.
+        //Ergo: Alles selbst machen (siehe ImplEndAction())
+        if ( Imp()->GetRegion() && Imp()->GetRegion()->GetOrigin() != VisArea())
+             Imp()->DelRegions();
+
+        Imp()->ResetScroll();
+        SwLayAction aAction( GetLayout(), Imp() );
+        aAction.SetComplete( FALSE );
+        aAction.Action();
+
+        SwRegionRects *pRegion = Imp()->GetRegion();
+        if ( pRegion && aAction.IsBrowseActionStop() )
+        {
+            //Nur dann interessant, wenn sich im sichtbaren Bereich etwas
+            //veraendert hat.
+            BOOL bStop = TRUE;
+            for ( USHORT i = 0; i < pRegion->Count(); ++i )
+            {
+                const SwRect &rTmp = (*pRegion)[i];
+                if ( FALSE == (bStop = rTmp.IsOver( VisArea() )) )
+                    break;
+            }
+            if ( bStop )
+            {
+                Imp()->DelRegions();
+                pRegion = 0;
+            }
+        }
+
+        if ( pRegion )
+        {
+            //Erst Invert dann Compress, niemals andersherum!
+            pRegion->Invert();
+            pRegion->Compress();
+            bRet = FALSE;
+            if ( pRegion->Count() )
+            {
+                SwRegionRects aRegion( rRect );
+                for ( USHORT i = 0; i < pRegion->Count(); ++i )
+                {   const SwRect &rTmp = (*pRegion)[i];
+                    if ( !rRect.IsInside( rTmp ) )
+                    {
+                        InvalidateWindows( rTmp );
+                        if ( rTmp.IsOver( VisArea() ) )
+                        {   aRegion -= rTmp;
+                            bRet = TRUE;
+                        }
+                    }
+                }
+                if ( bRet )
+                {
+                    for ( USHORT i = 0; i < aRegion.Count(); ++i )
+                        GetWin()->Invalidate( aRegion[i].SVRect() );
+
+                    if ( rRect != VisArea() )
+                    {
+                        //rRect == VisArea ist der spezialfall fuer neu bzw.
+                        //Shift-Ctrl-R, dafuer sollte es nicht notwendig sein
+                        //das Rechteck nocheinmal in Dokumentkoordinaten v
+                        //vorzuhalten.
+                        if ( aInvalidRect.IsEmpty() )
+                            aInvalidRect = rRect;
+                        else
+                            aInvalidRect.Union( rRect );
+                    }
+                }
+            }
+            else
+                bRet = FALSE;
+            Imp()->DelRegions();
+        }
+        else
+            bRet = FALSE;
+    }
+    return bRet;
+}
+
+/******************************************************************************
+|*
+|*  ViewShell::Paint()
+|*
+|*  Ersterstellung      MA ??
+|*  Letzte Aenderung    MA 17. Sep. 96
+|*
+******************************************************************************/
+
+void ViewShell::Paint(const Rectangle &rRect)
+{
+    if ( nLockPaint )
+    {
+        if ( Imp()->bSmoothUpdate )
+        {
+            SwRect aTmp( rRect );
+            if ( !Imp()->aSmoothRect.IsInside( aTmp ) )
+                Imp()->bStopSmooth = TRUE;
+            else
+            {
+                Imp()->aSmoothRect = aTmp;
+                return;
+            }
+        }
+        else
+            return;
+    }
+
+    if ( SwRootFrm::IsInPaint() )
+    {
+        //Waehrend der Ausgabe einer Seite beim Druckvorgang wird das
+        //Paint gepuffert.
+        SwPaintQueue::Add( this, SwRect( rRect ) );
+        return;
+    }
+
+    //MA 30. Jul. 95: fix(16787): mit !nStartAction versuche ich mal mich gegen
+    //fehlerhaften Code an anderen Stellen zu wehren. Hoffentlich fuehrt das
+    //nicht zu Problemen!?
+    if ( bPaintWorks && !nStartAction )
+    {
+        if( GetWin() && GetWin()->IsVisible() )
+        {
+            //Wenn mit dem Paint ein Bereich betroffen ist, der vorher gescrolled
+            //wurde, so wiederholen wir das Paint mit dem Gesamtbereich. Nur so
+            //koennen wir sicherstellen, das (nicht mal kurzfristig) durch das Paint
+            //keine Alignmentfehler sichtbar werden.
+            SwRect aRect( rRect );
+            if ( Imp()->IsScrolled() && Imp()->FlushScrolledArea( aRect ) )
+            {
+                GetWin()->Invalidate( aRect.SVRect() );
+                return;
+            }
+
+            if ( bPaintInProgress ) //Schutz gegen doppelte Paints!
+            {
+                GetWin()->Invalidate( rRect );
+                return;
+            }
+
+            bPaintInProgress = TRUE;
+            SET_CURR_SHELL( this );
+            SwRootFrm::SetNoVirDev( TRUE );
+
+            //Wir wollen nicht staendig hin und her Clippen, wir verlassen
+            //uns darauf, das sich alle auf das Rechteck beschraeken und
+            //brauchen das Clipping hier nur einmalig einkalkulieren. Das
+            //ClipRect wird hier einmal entfernt und nicht Restauriert, denn
+            //von aussen braucht es sowieso keiner mehr.
+            //Nicht wenn wir ein MetaFile aufzeichnen.
+            if( !GetOut()->GetConnectMetaFile() && GetOut()->IsClipRegion())
+                GetOut()->SetClipRegion();
+
+            if ( IsPreView() )
+            {
+                //Falls sinnvoll gleich das alte InvalidRect verarbeiten bzw.
+                //vernichten.
+                if ( aRect.IsInside( aInvalidRect ) )
+                    ResetInvalidRect();
+                ViewShell::bLstAct = TRUE;
+                GetLayout()->Paint( aRect );
+                ViewShell::bLstAct = FALSE;
+            }
+            else
+            {
+                SwSaveHdl *pSaveHdl = 0;
+                if ( Imp()->HasDrawView() )
+                    pSaveHdl = new SwSaveHdl( Imp() );
+
+                //Wenn eine der sichtbaren Seiten noch irgendetwas zum Repaint
+                //angemeldet hat, so muessen Repaints ausgeloest werden.
+                if ( !CheckInvalidForPaint( aRect ) )
+                {
+                    PaintDesktop( aRect );
+                    //Falls sinnvoll gleich das alte InvalidRect verarbeiten bzw.
+                    //vernichten.
+                    if ( aRect.IsInside( aInvalidRect ) )
+                        ResetInvalidRect();
+                    ViewShell::bLstAct = TRUE;
+                    GetLayout()->Paint( aRect );
+                    ViewShell::bLstAct = FALSE;
+                }
+                delete pSaveHdl;
+            }
+            SwRootFrm::SetNoVirDev( FALSE );
+            bPaintInProgress = FALSE;
+            UISizeNotify();
+        }
+    }
+    else
+    {
+        if ( aInvalidRect.IsEmpty() )
+            aInvalidRect = SwRect( rRect );
+        else
+            aInvalidRect.Union( SwRect( rRect ) );
+
+        if ( bInEndAction && GetWin() )
+        {
+            Region aRegion( GetWin()->GetPaintRegion() );
+            RegionHandle hHdl( aRegion.BeginEnumRects() );
+            Rectangle aRect;
+            while ( aRegion.GetNextEnumRect( hHdl, aRect ) )
+                Imp()->AddPaintRect( aRect );
+            aRegion.EndEnumRects( hHdl );
+        }
+        else if ( SfxProgress::GetActiveProgress( GetDoc()->GetDocShell() ) &&
+                  GetOut() == GetWin() )
+        {
+            pOut->Push( PUSH_FILLCOLOR );
+            pOut->SetFillColor( Imp()->GetRetoucheColor() );
+            pOut->DrawRect( rRect );
+            pOut->Pop();
+        }
+    }
+}
+
+/******************************************************************************
+|*
+|*  ViewShell::SetBrowseBorder()
+|*
+|*  Ersterstellung      AMA 20. Aug. 96
+|*  Letzte Aenderung    AMA 20. Aug. 96
+|*
+******************************************************************************/
+
+void ViewShell::SetBrowseBorder( const Size& rNew )
+{
+    if( rNew != GetBrowseBorder() )
+    {
+        aBrowseBorder = rNew;
+        if ( aVisArea.HasArea() )
+            CheckBrowseView( FALSE );
+    }
+}
+
+/******************************************************************************
+|*
+|*  ViewShell::CheckBrowseView()
+|*
+|*  Ersterstellung      MA 04. Mar. 96
+|*  Letzte Aenderung    MA 04. Jul. 96
+|*
+******************************************************************************/
+
+void ViewShell::CheckBrowseView( FASTBOOL bBrowseChgd )
+{
+    if ( !bBrowseChgd && !GetDoc()->IsBrowseMode() )
+        return;
+
+    SET_CURR_SHELL( this );
+
+    ASSERT( GetLayout(), "Layout not ready" );
+
+    // Wenn das Layout noch nicht einmal eine Hoehe hat,
+    // ist sowieso nichts formatiert.
+    // Dann eruebrigt sich die Invalidierung
+    // Falsch, z.B. beim Anlegen einer neuen View wird der Inhalt eingefügt
+    // und formatiert (trotz einer leeren VisArea). Hier muessen deshalb
+    // die Seiten zur Formatierung angeregt werden.
+    if( !GetLayout()->Frm().Height() )
+    {
+        SwFrm* pPage = GetLayout()->Lower();
+        while( pPage )
+        {
+            pPage->_InvalidateSize();
+            pPage = pPage->GetNext();
+        }
+        return;
+    }
+
+    FASTBOOL bBrowseOn = GetDoc()->IsBrowseMode();
+
+    LockPaint();
+    StartAction();
+
+    SwPageFrm *pPg = (SwPageFrm*)GetLayout()->Lower();
+    do
+    {   pPg->InvalidateSize();
+        pPg->_InvalidatePrt();
+        pPg->InvaPercentLowers();
+        if ( bBrowseChgd )
+        {
+            pPg->PrepareHeader();
+            pPg->PrepareFooter();
+        }
+        pPg = (SwPageFrm*)pPg->GetNext();
+    } while ( pPg );
+
+    // Wenn sich die Groessenverhaeltnise im BrowseModus aendern,
+    // muss die Position und PrtArea der Cntnt- und Tab-Frames invalidiert werden.
+    BYTE nInv = INV_PRTAREA | INV_TABLE | INV_POS;
+    // Beim BrowseModus-Wechsel benoetigen die CntntFrms
+    // wg. der Drucker/Bildschirmformatierung eine Size-Invalidierung
+    if( bBrowseChgd )
+        nInv |= INV_SIZE;
+
+    GetLayout()->InvalidateAllCntnt( nInv );
+
+    SwFrm::CheckPageDescs( (SwPageFrm*)GetLayout()->Lower() );
+
+    EndAction();
+    UnlockPaint();
+}
+
+/******************************************************************************
+|*
+|*  ViewShell::Is/Set[Head|Foot]InBrowse()
+|*
+|*  Ersterstellung      MA 10. Feb. 97
+|*  Letzte Aenderung    MA 10. Feb. 97
+|*
+******************************************************************************/
+
+BOOL ViewShell::IsHeadInBrowse() const
+{
+    return GetDoc()->IsHeadInBrowse();
+}
+
+
+void ViewShell::SetHeadInBrowse( BOOL bOn )
+{
+    if ( GetDoc()->IsHeadInBrowse() != bOn )
+    {
+        BOOL bCrsr = ISA(SwCrsrShell);
+        if ( bCrsr )
+            ((SwCrsrShell*)this)->StartAction();
+        else
+            StartAction();
+        GetDoc()->SetHeadInBrowse( bOn );
+
+        SwPageFrm *pPg = GetLayout() ? (SwPageFrm*)GetLayout()->Lower() : 0;
+        while ( pPg )
+        {
+            if ( bCrsr )
+                ::MA_ParkCrsr( pPg->GetPageDesc(), *(SwCrsrShell*)this );
+            pPg->PrepareHeader();
+            pPg = (SwPageFrm*)pPg->GetNext();
+        }
+        if ( bCrsr )
+            ((SwCrsrShell*)this)->EndAction();
+        else
+            EndAction();
+    }
+}
+
+
+BOOL ViewShell::IsFootInBrowse() const
+{
+    return GetDoc()->IsFootInBrowse();
+}
+
+
+void ViewShell::SetFootInBrowse( BOOL bOn )
+{
+    if ( GetDoc()->IsFootInBrowse() != bOn )
+    {
+        BOOL bCrsr = ISA(SwCrsrShell);
+        if ( bCrsr )
+            ((SwCrsrShell*)this)->StartAction();
+        else
+            StartAction();
+        GetDoc()->SetFootInBrowse( bOn );
+
+        SwPageFrm *pPg = GetLayout() ? (SwPageFrm*)GetLayout()->Lower() : 0;
+        while ( pPg )
+        {
+            if ( bCrsr )
+                ::MA_ParkCrsr( pPg->GetPageDesc(), *(SwCrsrShell*)this );
+            pPg->PrepareFooter();
+            pPg = (SwPageFrm*)pPg->GetNext();
+        }
+        if ( bCrsr )
+            ((SwCrsrShell*)this)->EndAction();
+        else
+            EndAction();
+    }
+}
+
+
+/*************************************************************************
+|*
+|*    ViewShell::GetLayout()
+|*    ViewShell::GetNodes()
+|*
+|*    Ersterstellung    OK 26. May. 92
+|*    Letzte Aenderung  MA 16. Sep. 93
+|*
+*************************************************************************/
+
+SwRootFrm *ViewShell::GetLayout() const
+{
+    return GetDoc()->GetRootFrm();
+}
+
+
+SfxPrinter *ViewShell::GetPrt( BOOL bCreate ) const
+{
+    return GetDoc()->GetPrt( bCreate );
+}
+
+
+const SwNodes& ViewShell::GetNodes() const
+{
+    return pDoc->GetNodes();
+}
+
+
+void ViewShell::DrawSelChanged(SdrView*)
+{
+}
+
+
+Size ViewShell::GetDocSize() const
+{
+    Size aSz;
+    const SwRootFrm* pRoot = GetLayout();
+    if( pRoot )
+        aSz = pRoot->Frm().SSize();
+    return aSz;
+}
+
+
+SfxItemPool& ViewShell::GetAttrPool()
+{
+    return GetDoc()->GetAttrPool();
+}
+
+/*************************************************************************
+|*
+|*    ViewShell::SetSubsLines()
+|*
+|*    Beschreibung      Hilfslinien An-/Abschalten
+|*    Ersterstellung    MA 26. May. 92
+|*    Letzte Aenderung  MA 03. May. 95
+|*
+*************************************************************************/
+
+void ViewShell::SetSubsLines()
+{
+    if( GetWin() )
+        GetWin()->Invalidate();
+}
+
+/******************************************************************************
+|*
+|*  ViewShell::ApplyViewOptions(), ImplApplyViewOptions()
+|*
+|*  Ersterstellung      ??
+|*  Letzte Aenderung    MA 03. Mar. 98
+|*
+******************************************************************************/
+
+void ViewShell::ApplyViewOptions( const SwViewOption &rOpt )
+{
+
+    ViewShell *pSh = this;
+    do
+    {   pSh->StartAction();
+        pSh = (ViewShell*)pSh->GetNext();
+    } while ( pSh != this );
+
+    ImplApplyViewOptions( rOpt );
+
+    //Einige Aenderungen muessen synchronisiert werden.
+    pSh = (ViewShell*)this->GetNext();
+    while ( pSh != this )
+    {
+        SwViewOption aOpt( *pSh->GetViewOptions() );
+        aOpt.SetFldName( rOpt.IsFldName() );
+        aOpt.SetHidden( rOpt.IsHidden() );
+        aOpt.SetShowHiddenPara( rOpt.IsShowHiddenPara() );
+        if ( !(aOpt == *pSh->GetViewOptions()) )
+            pSh->ImplApplyViewOptions( aOpt );
+        pSh = (ViewShell*)pSh->GetNext();
+    }
+
+    pSh = this;
+    do
+    {   pSh->EndAction();
+        pSh = (ViewShell*)pSh->GetNext();
+    } while ( pSh != this );
+
+}
+
+void ViewShell::ImplApplyViewOptions( const SwViewOption &rOpt )
+{
+    ASSERT( !(*pOpt == rOpt), "ViewShell::ApplyViewOptions: ");
+
+    Window *pWin = GetWin();
+    if( !pWin )
+    {
+        ASSERT( pWin, "ViewShell::ApplyViewOptions: no window" );
+        return;
+    }
+
+    SET_CURR_SHELL( this );
+
+    if( pOpt->IsSubsLines() != rOpt.IsSubsLines() ||
+        pOpt->IsSubsTable() != rOpt.IsSubsTable() )
+    {
+        pOpt->SetSubsLines( rOpt.IsSubsLines() ); // Frame-Hilfslinien
+        pOpt->SetSubsTable( rOpt.IsSubsTable() ); // Table-Hilfslinien
+        SetSubsLines();
+        if ( *pOpt == rOpt )
+            return;
+    }
+
+    BOOL bReformat   = FALSE;
+
+    if( pOpt->IsHidden() != rOpt.IsHidden() )
+    {
+        ((SwHiddenTxtFieldType*)pDoc->GetSysFldType( RES_HIDDENTXTFLD ))->
+                                            SetHiddenFlag( !rOpt.IsHidden() );
+        bReformat = TRUE;
+    }
+    if ( pOpt->IsShowHiddenPara() != rOpt.IsShowHiddenPara() )
+    {
+        SwHiddenParaFieldType* pFldType = (SwHiddenParaFieldType*)GetDoc()->
+                                          GetSysFldType(RES_HIDDENPARAFLD);
+        if( pFldType && pFldType->GetDepends() )
+        {
+            SwMsgPoolItem aHnt( RES_HIDDENPARA_PRINT );
+            pFldType->Modify( &aHnt, 0);
+        }
+        bReformat = TRUE;
+    }
+
+    // bReformat wird TRUE, wenn ...
+    // - Feldnamen anzeigen oder nicht ...
+    // ( - SwEndPortion muessen _nicht_ mehr generiert werden. )
+    // - Das Window ist natuerlich was ganz anderes als der Drucker...
+    bReformat = bReformat || pOpt->IsFldName()   != rOpt.IsFldName();
+
+    // Der Mapmode wird veraendert, Minima/Maxima werden von der UI beachtet
+    if( pOpt->GetZoom() != rOpt.GetZoom() && !IsPreView() )
+    {
+        MapMode aMode( pWin->GetMapMode() );
+        Fraction aNewFactor( rOpt.GetZoom(), 100 );
+        aMode.SetScaleX( aNewFactor );
+        aMode.SetScaleY( aNewFactor );
+        pWin->SetMapMode( aMode );
+        // Wenn kein ReferenzDevice (Drucker) zum Formatieren benutzt wird,
+        // sondern der Bildschirm, muss bei Zoomfaktoraenderung neu formatiert
+        // werden.
+        if( IsBrowseMode() || !GetReferenzDevice() )
+            bReformat = TRUE;
+    }
+
+
+    if ( HasDrawView() || rOpt.IsGridVisible() )
+    {
+        if ( !HasDrawView() )
+            MakeDrawView();
+
+        SwDrawView *pDView = Imp()->GetDrawView();
+        if ( pDView->IsDragStripes() != rOpt.IsCrossHair() )
+            pDView->SetDragStripes( rOpt.IsCrossHair() );
+
+        if ( pDView->IsGridSnap() != rOpt.IsSnap() )
+            pDView->SetGridSnap( rOpt.IsSnap() );
+
+        if ( pDView->IsGridVisible() != rOpt.IsGridVisible() )
+            pDView->SetGridVisible( rOpt.IsGridVisible() );
+
+        const Size &rSz = rOpt.GetSnapSize();
+        pDView->SetGridCoarse( rSz );
+
+        const Size aFSize
+            ( rSz.Width() ? rSz.Width() / (rOpt.GetDivisionX()+1) : 0,
+              rSz.Height()? rSz.Height()/ (rOpt.GetDivisionY()+1) : 0);
+        pDView->SetGridFine( aFSize );
+        pDView->SetSnapGrid( aFSize );
+        Fraction aSnGrWdtX(rSz.Width(), rOpt.GetDivisionX() + 1);
+        Fraction aSnGrWdtY(rSz.Height(), rOpt.GetDivisionY() + 1);
+        pDView->SetSnapGridWidth( aSnGrWdtX, aSnGrWdtY );
+
+        if ( pOpt->IsDraw() != rOpt.IsDraw() )
+        {
+            FASTBOOL bDraw = !rOpt.IsDraw();
+            pDView->SetLineDraft( bDraw );
+            pDView->SetFillDraft( bDraw );
+            pDView->SetGrafDraft( bDraw );
+            pDView->SetTextDraft( bDraw );
+        }
+        if ( pOpt->IsSolidMarkHdl() != rOpt.IsSolidMarkHdl() )
+            pDView->SetSolidMarkHdl( rOpt.IsSolidMarkHdl() );
+
+            // it's a JOE interface !
+        if ( pOpt->IsBigMarkHdl() != rOpt.IsBigMarkHdl() )
+            pDView->SetMarkHdlSizePixel(rOpt.IsBigMarkHdl() ? 9 : 7);
+    }
+
+    FASTBOOL bOnlineSpellChgd = pOpt->IsOnlineSpell() != rOpt.IsOnlineSpell();
+
+    *pOpt = rOpt;   // Erst jetzt werden die Options uebernommen.
+    pOpt->SetUIOptions(rOpt);
+
+    pDoc->SetHTMLMode( 0 != ::GetHtmlMode(pDoc->GetDocShell()) );
+
+    pWin->Invalidate();
+    if ( bReformat )
+    {
+        // Es hilft alles nichts, wir muessen an alle CntntFrms ein
+        // Prepare verschicken, wir formatieren neu:
+        StartAction();
+        Reformat();
+        EndAction();
+    }
+
+    if( bOnlineSpellChgd )
+    {
+        ViewShell *pSh = (ViewShell*)this->GetNext();
+        BOOL bOnlineSpl = rOpt.IsOnlineSpell();
+        while( pSh != this )
+        {   pSh->pOpt->SetOnlineSpell( bOnlineSpl );
+            Window *pTmpWin = pSh->GetWin();
+            if( pTmpWin )
+                pTmpWin->Invalidate();
+            pSh = (ViewShell*)pSh->GetNext();
+        }
+    }
+
+}
+
+/******************************************************************************
+|*
+|*  ViewShell::SetUIOptions()
+|*
+|*  Ersterstellung      OS 29.07.96
+|*  Letzte Aenderung    OS 29.07.96
+|*
+******************************************************************************/
+
+void ViewShell::SetUIOptions( const SwViewOption &rOpt )
+{
+    pOpt->SetUIOptions(rOpt);
+    //the API-Flag of the view options is set but never reset
+    //it is required to set scroll bars in readonly documents
+    if(rOpt.IsStarOneSetting())
+        pOpt->SetStarOneSetting(TRUE);
+
+    pOpt->SetSymbolFont(rOpt.GetSymbolFont());
+}
+
+/******************************************************************************
+|*
+|*  ViewShell::SetReadonly()
+|*
+|*  Ersterstellung      OS 05.09.96
+|*  Letzte Aenderung    MA 12. Feb. 97
+|*
+******************************************************************************/
+
+void ViewShell::SetReadonlyOption(BOOL bSet)
+{
+    //JP 01.02.99: bei ReadOnly Flag richtig abfragen und ggfs. neu
+    //              formatieren; Bug 61335
+
+    // Schalten wir gerade von Readonly auf Bearbeiten um?
+    if( bSet != pOpt->IsReadonly() )
+    {
+        // damit die Flags richtig erfragt werden koennen.
+        pOpt->SetReadonly( FALSE );
+
+        BOOL bReformat = pOpt->IsFldName();
+
+        pOpt->SetReadonly( bSet );
+
+        if( bReformat )
+        {
+            StartAction();
+            Reformat();
+            if ( GetWin() )
+                GetWin()->Invalidate();
+            EndAction();
+        }
+        else if ( GetWin() )
+            GetWin()->Invalidate();
+    }
+}
+
+/******************************************************************************
+|*
+|*  ViewShell::SetPrtFormatOption()
+|*
+|*  Ersterstellung      AMA 10. Sep. 97
+|*  Letzte Aenderung    AMA 10. Sep. 97
+|*
+******************************************************************************/
+
+void ViewShell::SetPrtFormatOption( BOOL bSet )
+{
+    pOpt->SetPrtFormat( bSet );
+}
+
+/******************************************************************************
+|*
+|*  ViewShell::UISizeNotify()
+|*
+|*  Ersterstellung      MA 14. Jan. 97
+|*  Letzte Aenderung    MA 14. Jan. 97
+|*
+******************************************************************************/
+
+
+void ViewShell::UISizeNotify()
+{
+    if ( bDocSizeChgd )
+    {
+        bDocSizeChgd = FALSE;
+        FASTBOOL bOld = bInSizeNotify;
+        bInSizeNotify = TRUE;
+        ::SizeNotify( this, GetLayout()->Frm().SSize() );
+        bInSizeNotify = bOld;
+    }
+}
+
+
+BOOL ViewShell::IsBrowseMode() const
+{
+    return GetDoc()->IsBrowseMode();
+}
+
+void    ViewShell::SetRestoreActions(USHORT nSet)
+{
+    DBG_ASSERT(!GetRestoreActions(), "mehrfaches Restore der Actions ?")
+    Imp()->SetRestoreActions(nSet);
+}
+USHORT  ViewShell::GetRestoreActions() const
+{
+    return Imp()->GetRestoreActions();
+}
+
+BOOL ViewShell::IsNewLayout() const
+{
+    return GetLayout()->IsNewLayout();
+}
+
+
+
+/************************************************************************
+
+      $Log: not supported by cvs2svn $
+      Revision 1.384  2000/09/18 16:04:37  willem.vandorp
+      OpenOffice header added.
+
+      Revision 1.383  2000/09/08 08:12:53  os
+      Change: Set/Toggle/Has/Knows/Show/GetChildWindow
+
+      Revision 1.382  2000/07/17 10:30:51  ama
+      Opt: Smarter scrolling for RVP
+
+      Revision 1.381  2000/05/10 13:44:10  ama
+      Unicode changes
+
+      Revision 1.380  2000/04/05 10:02:14  os
+      #67584# scroll bar settings in read-only documents corrected
+
+      Revision 1.379  2000/03/03 15:17:22  os
+      StarView remainders removed
+
+      Revision 1.378  1999/12/22 12:08:47  jp
+      Bug #69762#: VisPortChg - dont ignore FlyFrames
+
+      Revision 1.377  1999/12/06 17:27:18  jp
+      Bug #69762#: VisPortChg - calculate the correct scroll range
+
+      Revision 1.376  1999/10/20 16:42:39  jp
+      Bug #68106#: new slot/interface for update all charts in a document
+
+      Revision 1.375  1999/10/06 13:29:31  jp
+      SmoothScroll: change the calculation of the scrollfactor
+
+      Revision 1.374  1999/09/30 09:46:53  os
+      new compatibility option
+
+      Revision 1.373  1999/09/29 14:31:40  kz
+      Check for Existance of ViewPort before use
+
+      Revision 1.372  1999/09/27 10:22:54  os
+      #68725# smooth scrolling: added missing flag in GetWindowClipRegionPixel()
+
+      Revision 1.371  1999/09/22 12:39:08  aw
+      changes for IAO-Handle handling in SW (AW)
+
+      Revision 1.370  1999/09/22 12:37:10  os
+      big handles
+
+      Revision 1.369  1999/09/06 13:19:24  aw
+      changes due to support of new handles
+
+
+      Rev 1.365   13 Aug 1999 15:11:32   MA
+   adoption to new markers, but still inkomplete
+
+      Rev 1.364   23 Jul 1999 16:23:02   AW
+   changes for new markers
+
+*************************************************************************/
+
+
diff --git a/sw/source/core/view/vnew.cxx b/sw/source/core/view/vnew.cxx
new file mode 100644
index 000000000000..f8339abdbc2b
--- /dev/null
+++ b/sw/source/core/view/vnew.cxx
@@ -0,0 +1,520 @@
+/*************************************************************************
+ *
+ *  $RCSfile: vnew.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:29 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include 
+#ifndef _SFX_PRINTER_HXX //autogen
+#include 
+#endif
+
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _DOCSH_HXX
+#include 
+#endif
+#ifndef _VIEWSH_HXX
+#include 
+#endif
+#ifndef _ROOTFRM_HXX
+#include 
+#endif
+#ifndef _VIEWIMP_HXX
+#include 
+#endif
+#ifndef _VIEWOPT_HXX
+#include 
+#endif
+#ifndef _TXTFRM_HXX
+#include        // Zugriff auf TxtCache
+#endif
+#ifndef _NOTXTFRM_HXX
+#include 
+#endif
+#ifndef _FNTCACHE_HXX
+#include 
+#endif
+#ifndef _DOCUFLD_HXX
+#include 
+#endif
+#ifndef _PTQUEUE_HXX
+#include 
+#endif
+#ifndef _DVIEW_HXX
+#include         // SdrView
+#endif
+#ifndef _CALBCK_HXX
+#include 
+#endif
+#ifndef _NDGRF_HXX
+#include 
+#endif
+#ifndef _NDINDEX_HXX
+#include 
+#endif
+
+//#ifndef _SMART_COM_SUN_STAR_LINGUISTIC_XSPELLALTERNATIVES_HXX_
+//#include 
+//#endif
+//#ifndef _SMART_COM_SUN_STAR_LINGUISTIC_SPELLFAILURE_HXX_
+//#include 
+//#endif
+//#ifndef _SMART_COM_SUN_STAR_LINGUISTIC_XSPELLCHECKER1_HXX_
+//#include 
+//#endif
+//#ifndef _SMART_COM_SUN_STAR_LINGUISTIC_XALTERNATIVESPELLING_HXX_
+//#include 
+//#endif
+//#ifndef _SMART_COM_SUN_STAR_LINGUISTIC_XPOSSIBLEHYPHENSSUPPLIER_HXX_
+//#include 
+//#endif
+//#ifndef _SMART_COM_SUN_STAR_LINGUISTIC_XHYPHENATOR_HXX_
+//#include 
+//#endif
+//#ifndef _SMART_COM_SUN_STAR_LINGUISTIC_XPOSSIBLEHYPHENS_HXX_
+//#include 
+//#endif
+//#ifndef _SMART_COM_SUN_STAR_LINGUISTIC_XHYPHENATEDWORD_HXX_
+//#include 
+//#endif
+
+using namespace ::com::sun::star;
+/*************************************************************************
+|*
+|*  ViewShell::Init()
+|*
+|*  Letzte Aenderung    MA 14. Jun. 96
+|*
+|*************************************************************************/
+
+void ViewShell::Init( const SwViewOption *pNewOpt )
+{
+    bDocSizeChgd = FALSE;
+
+    // Wir gehen auf Nummer sicher:
+    // Wir muessen die alten Fontinformationen wegschmeissen,
+    // wenn die Druckeraufloesung oder der Zoomfaktor sich aendert.
+    // Init() und Reformat() sind die sichersten Stellen.
+    pFntCache->Flush( );
+
+    // ViewOptions werden dynamisch angelegt
+    if( !pOpt )
+    {
+        pOpt = new SwViewOption;
+
+        // Ein ApplyViewOptions braucht nicht gerufen zu werden
+        if( pNewOpt )
+        {
+            *pOpt = *pNewOpt;
+            // Der Zoomfaktor muss eingestellt werden, weil in der CTOR-
+            // phase aus Performancegruenden kein ApplyViewOptions gerufen wird.
+            if( GetWin() && 100 != pOpt->GetZoom() )
+            {
+                MapMode aMode( pWin->GetMapMode() );
+                const Fraction aNewFactor( pOpt->GetZoom(), 100 );
+                aMode.SetScaleX( aNewFactor );
+                aMode.SetScaleY( aNewFactor );
+                pWin->SetMapMode( aMode );
+            }
+        }
+    }
+
+    SwDocShell* pDShell = pDoc->GetDocShell();
+    pDoc->SetHTMLMode( 0 != ::GetHtmlMode( pDShell ) );
+
+    // JP 02.02.99: Bug 61335 - Readonly-Flag an den ViewOptions setzen,
+    //              bevor das Layout angelegt wird. Ansonsten muesste man
+    //              nochmals durchformatieren!!
+    if( pDShell && pDShell->IsReadOnly() )
+        pOpt->SetReadonly( TRUE );
+
+    if( GetPrt( TRUE ^ pDoc->IsBrowseMode() ) )
+        InitPrt( GetPrt() );
+
+    if( GetWin() )
+    {
+        pOpt->Init( GetWin() );
+        GetWin()->SetFillColor();
+        GetWin()->SetBackground();
+        GetWin()->SetLineColor();
+    }
+
+    //Layout erzeugen wenn es noch nicht vorhanden ist.
+    SwRootFrm* pRoot = GetDoc()->GetRootFrm();
+    if( !pRoot )
+        GetDoc()->SetRootFrm( pRoot = new SwRootFrm( pDoc->GetDfltFrmFmt(), this ) );
+
+    SizeChgNotify( pRoot->Frm().SSize() );
+}
+
+/*************************************************************************
+|*
+|*  ViewShell::ViewShell()  CTor fuer die erste Shell.
+|*
+|*  Letzte Aenderung    MA 29. Aug. 95
+|*
+|*************************************************************************/
+
+ViewShell::ViewShell( SwDoc *pDocument,
+           uno::Reference< linguistic::XSpellChecker1> xSpell,
+           uno::Reference< linguistic::XHyphenator> xHyph,
+           Window *pWindow, const SwViewOption *pNewOpt,
+           OutputDevice *pOutput, long nFlags ) :
+    pDoc( pDocument ),
+    xSpell( xSpell ),
+    xHyph ( xHyph ),
+    pOpt( 0 ),
+    pWin( pWindow ),
+    pOut( pOutput ? pOutput
+                  : pWindow ? (OutputDevice*)pWindow
+                            : (OutputDevice*)pDocument->GetPrt(TRUE)),
+    pRef( 0 ),
+    nStartAction( 0 ),
+    nLockPaint( 0 ),
+    pSfxViewShell( 0 ),
+    pImp( new SwViewImp( this ) ),
+    aBrowseBorder()
+{
+    bPaintInProgress = bViewLocked = bInEndAction = bFrameView =
+    bEndActionByVirDev = FALSE;
+    bPaintWorks = bEnableSmooth = TRUE;
+    bPreView = 0 !=( VSHELLFLAG_ISPREVIEW & nFlags );
+
+    pDoc->AddLink();
+    pOutput = pOut;
+    Init( pNewOpt );    //verstellt ggf. das Outdev (InitPrt())
+    pOut = pOutput;
+
+    SET_CURR_SHELL( this );
+
+    ((SwHiddenTxtFieldType*)pDoc->GetSysFldType( RES_HIDDENTXTFLD ))->
+        SetHiddenFlag( !pOpt->IsHidden() );
+
+    //In Init wird ein Standard-FrmFmt angelegt.
+    if( !pDoc->IsUndoNoResetModified() )
+        pDoc->ResetModified();
+
+    //Format-Cache erweitern.
+    if ( SwTxtFrm::GetTxtCache()->GetCurMax() < 2550 )
+        SwTxtFrm::GetTxtCache()->IncreaseMax( 100 );
+    if( GetDoc()->GetDrawModel() || pOpt->IsGridVisible() )
+        Imp()->MakeDrawView();
+}
+
+/*************************************************************************
+|*
+|*  ViewShell::ViewShell()  CTor fuer weitere Shells auf ein Dokument.
+|*
+|*  Letzte Aenderung    MA 29. Aug. 95
+|*
+|*************************************************************************/
+
+ViewShell::ViewShell( ViewShell *pShell, Window *pWindow,
+                    OutputDevice *pOutput, long nFlags ) :
+    Ring( pShell ),
+    pDoc( pShell->GetDoc() ),
+    pWin( pWindow ),
+    pOut( pOutput ? pOutput
+                  : pWindow ? (OutputDevice*)pWindow
+                            : (OutputDevice*)pShell->GetDoc()->GetPrt(TRUE)),
+    pRef( 0 ),
+    xSpell( pShell->GetSpellChecker() ),
+    xHyph( pShell->GetHyphenator() ),
+    pOpt( 0 ),
+    nStartAction( 0 ),
+    nLockPaint( 0 ),
+    pSfxViewShell( 0 ),
+    pImp( new SwViewImp( this ) ),
+    aBrowseBorder( pShell->GetBrowseBorder() )
+{
+    bPaintWorks = bEnableSmooth = TRUE;
+    bPaintInProgress = bViewLocked = bInEndAction = bFrameView =
+    bEndActionByVirDev = FALSE;
+    bPreView = 0 !=( VSHELLFLAG_ISPREVIEW & nFlags );
+
+    SET_CURR_SHELL( this );
+
+    pDoc->AddLink();
+    BOOL bModified = pDoc->IsModified();
+
+    pOutput = pOut;
+    Init( pShell->GetViewOptions() );   //verstellt ggf. das Outdev (InitPrt())
+    pOut = pOutput;
+
+    ((SwHiddenTxtFieldType*)pDoc->GetSysFldType( RES_HIDDENTXTFLD ))->
+            SetHiddenFlag( !pOpt->IsHidden() );
+
+    // in Init wird ein Standard-FrmFmt angelegt
+    if( !bModified && !pDoc->IsUndoNoResetModified() )
+        pDoc->ResetModified();
+
+    //Format-Cache erweitern.
+    if ( SwTxtFrm::GetTxtCache()->GetCurMax() < 2550 )
+        SwTxtFrm::GetTxtCache()->IncreaseMax( 100 );
+    if( GetDoc()->GetDrawModel() || pOpt->IsGridVisible() )
+        Imp()->MakeDrawView();
+}
+
+/******************************************************************************
+|*
+|*  ViewShell::~ViewShell()
+|*
+|*  Ersterstellung      MA ??
+|*  Letzte Aenderung    MA 10. May. 95
+|*
+******************************************************************************/
+
+ViewShell::~ViewShell()
+{
+    {
+        SET_CURR_SHELL( this );
+        bPaintWorks = FALSE;
+
+        //Die Animierten Grafiken abschalten!
+        if( pDoc )
+        {
+            SwNodes& rNds = pDoc->GetNodes();
+            SwGrfNode *pGNd;
+
+            SwStartNode *pStNd;
+            SwNodeIndex aIdx( *rNds.GetEndOfAutotext().StartOfSectionNode(), 1 );
+            while ( 0 != (pStNd = aIdx.GetNode().GetStartNode()) )
+            {
+                aIdx++;
+                if ( 0 != ( pGNd = aIdx.GetNode().GetGrfNode() ) )
+                {
+
+// Code for the new GraphicObject
+#ifdef USE_GRFOBJECT
+                    if( pGNd->IsAnimated() )
+#else
+                    if( pGNd->GetGrf().IsAnimated() )
+#endif
+                    {
+                        SwClientIter aIter( *pGNd );
+                        for( SwFrm* pFrm = (SwFrm*)aIter.First( TYPE(SwFrm) );
+                            pFrm; pFrm = (SwFrm*)aIter.Next() )
+                        {
+                            ASSERT( pFrm->IsNoTxtFrm(), "GraphicNode with Text?" );
+                            ((SwNoTxtFrm*)pFrm)->StopAnimation( pOut );
+                        }
+                    }
+                }
+                aIdx.Assign( *pStNd->EndOfSectionNode(), +1 );
+            }
+
+            GetDoc()->StopNumRuleAnimations( pOut );
+        }
+
+        delete pImp; //Erst loeschen, damit die LayoutViews vernichtet werden.
+
+        if ( pDoc )
+        {
+            if( !pDoc->RemoveLink() )
+                delete pDoc, pDoc = 0;
+            else
+                pDoc->GetRootFrm()->ResetNewLayout();
+        }
+
+        delete pOpt;
+
+        //Format-Cache zurueckschrauben.
+        if ( SwTxtFrm::GetTxtCache()->GetCurMax() > 250 )
+            SwTxtFrm::GetTxtCache()->DecreaseMax( 100 );
+
+        //Ggf. aus der PaintQueue entfernen lassen
+        SwPaintQueue::Remove( this );
+
+        ASSERT( !nStartAction, "EndAction() pending." );
+    }
+
+    if ( pDoc )
+        GetLayout()->DeRegisterShell( this );
+
+    delete pRef;
+}
+
+const BOOL ViewShell::HasDrawView() const
+{
+    return Imp()->HasDrawView();
+}
+
+void ViewShell::MakeDrawView()
+{
+    Imp()->MakeDrawView( );
+}
+
+SdrView* ViewShell::GetDrawView()
+{
+    return Imp()->GetDrawView();
+}
+
+SdrView* ViewShell::GetDrawViewWithValidMarkList()
+{
+    SwDrawView* pDView = Imp()->GetDrawView();
+    pDView->ValidateMarkList();
+    return pDView;
+}
+
+/************************************************************************
+
+      $Log: not supported by cvs2svn $
+      Revision 1.132  2000/09/18 16:04:38  willem.vandorp
+      OpenOffice header added.
+
+      Revision 1.131  2000/07/06 16:57:25  jp
+      DTOR: dont laod the graphic to stop the animation
+
+      Revision 1.130  2000/07/04 15:21:42  tl
+      XHyphenator1 => XHyphenator
+
+      Revision 1.129  2000/03/23 06:48:25  os
+      UNOIII
+
+      Revision 1.128  2000/02/16 20:55:52  tl
+      #72219# Locale Umstellung
+
+      Revision 1.127  1999/11/23 08:21:54  os
+      header corrected
+
+      Revision 1.126  1999/11/19 16:40:19  os
+      modules renamed
+
+      Revision 1.125  1999/10/25 19:08:51  tl
+      ongoing ONE_LINGU implementation
+
+      Revision 1.124  1999/04/09 15:50:26  MA
+      #64467# EndAction und VirDev
+
+
+      Rev 1.123   09 Apr 1999 17:50:26   MA
+   #64467# EndAction und VirDev
+
+      Rev 1.122   02 Mar 1999 16:07:32   AMA
+   Fix #62568#: Invalidierungen so sparsam wie moeglich, so gruendlich wie noetig
+
+      Rev 1.121   22 Feb 1999 08:35:22   MA
+   1949globale Shell entsorgt, Shells am RootFrm
+
+      Rev 1.120   02 Feb 1999 13:15:20   JP
+   Bug #61335#: im Init vorm anlegen des Layouts ReadOnly-Status feststellen
+
+      Rev 1.119   06 Oct 1998 12:44:12   JP
+   Bug #57153#: neu GetDrawViewWithValidMarkList
+
+      Rev 1.118   05 Oct 1998 17:44:00   MA
+   #57380# Reset fuer NewLayout
+
+      Rev 1.117   09 Sep 1998 14:59:22   MA
+   #56106# Array aus im CoreInit initialisieren
+
+      Rev 1.116   09 Sep 1998 11:47:46   MA
+   #56106# CurrShell-Verwaltung aufwendiger
+
+      Rev 1.115   27 Jul 1998 16:56:00   JP
+   Bug #45529#: LoadStyles muss ggfs. das Zuruecksetzen des ModifiedFlags verhindern
+
+      Rev 1.114   19 Jul 1998 17:55:24   JP
+   Bug #52312#: PagePreviewFlag wird im CTOR benoetigt
+
+      Rev 1.113   24 Jun 1998 18:45:20   MA
+   DataChanged fuer ScrollBar und Retouche, Retouche ganz umgestellt
+
+      Rev 1.112   19 May 1998 10:12:40   TJ
+   include wg. ice
+
+      Rev 1.111   29 Apr 1998 09:31:30   MA
+   RetoucheBrush -> RetoucheColor
+
+      Rev 1.110   27 Apr 1998 15:09:10   MA
+   ein paar sv2vcl
+
+      Rev 1.109   23 Apr 1998 09:33:36   MA
+   #49472# Optional ein Outdev durchschleusen
+
+      Rev 1.108   26 Mar 1998 17:58:50   MA
+   Wechsel fuer Drucker/Jobsetup jetzt vollstaendig und am Dokument
+
+      Rev 1.107   20 Nov 1997 12:40:38   MA
+   includes
+
+      Rev 1.106   17 Nov 1997 09:47:28   JP
+   Umstellung Numerierung
+
+      Rev 1.105   03 Nov 1997 13:07:28   MA
+   precomp entfernt
+
+      Rev 1.104   22 Oct 1997 14:28:46   MA
+   fix: Brush mit Style NULL fuer Drucker-Retouche
+
+      Rev 1.103   13 Oct 1997 15:54:28   JP
+   pNext vom Ring wurde privat; zugriff ueber GetNext()
+
+      Rev 1.102   09 Oct 1997 16:05:20   JP
+   Umstellung NodeIndex/-Array/BigPtrArray
+
+*************************************************************************/
+
diff --git a/sw/source/core/view/vprint.cxx b/sw/source/core/view/vprint.cxx
new file mode 100644
index 000000000000..63ca98217796
--- /dev/null
+++ b/sw/source/core/view/vprint.cxx
@@ -0,0 +1,1924 @@
+/*************************************************************************
+ *
+ *  $RCSfile: vprint.cxx,v $
+ *
+ *  $Revision: 1.1.1.1 $
+ *
+ *  last change: $Author: hr $ $Date: 2000-09-19 00:08:29 $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (the "License"); You may not use this file
+ *  except in compliance with the License. You may obtain a copy of the
+ *  License at http://www.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include 
+#endif
+
+#ifndef _SFX_PRINTER_HXX //autogen
+#include 
+#endif
+#ifndef _INTN_HXX //autogen
+#include 
+#endif
+#ifndef _SFX_PROGRESS_HXX //autogen
+#include 
+#endif
+#ifndef _SFXAPP_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_PAPERINF_HXX //autogen
+#include 
+#endif
+#ifndef _SVX_PBINITEM_HXX //autogen
+#include 
+#endif
+#ifndef _SVDVIEW_HXX //autogen
+#include 
+#endif
+#ifndef _EMBOBJ_HXX //autogen
+#include 
+#endif
+
+
+#ifndef _TXTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFLD_HXX //autogen
+#include 
+#endif
+#ifndef _FMTFSIZE_HXX //autogen
+#include 
+#endif
+#ifndef _FRMATR_HXX
+#include 
+#endif
+#ifndef _ROOTFRM_HXX
+#include 
+#endif
+#ifndef _PAGEFRM_HXX
+#include 
+#endif
+#ifndef _CNTFRM_HXX
+#include 
+#endif
+#ifndef _DOC_HXX
+#include 
+#endif
+#ifndef _FESH_HXX
+#include 
+#endif
+#ifndef _PAM_HXX
+#include 
+#endif
+#ifndef _VIEWIMP_HXX
+#include       // Imp->SetFirstVisPageInvalid()
+#endif
+#ifndef _LAYACT_HXX
+#include 
+#endif
+#ifndef _NDTXT_HXX
+#include 
+#endif
+#ifndef _FLDBAS_HXX
+#include 
+#endif
+#ifndef _DOCUFLD_HXX
+#include       // PostItFld /-Type
+#endif
+#ifndef _DOCFLD_HXX
+#include        // _SetGetExpFld
+#endif
+#ifndef _CALBCK_HXX
+#include        // SwModify/SwClientIter
+#endif
+#ifndef _SHELLRES_HXX
+#include 
+#endif
+#ifndef _VIEWOPT_HXX
+#include 
+#endif
+#ifndef _SWPRTOPT_HXX
+#include      // SwPrtOptions
+#endif
+#ifndef _PAGEDESC_HXX
+#include 
+#endif
+#ifndef _POOLFMT_HXX
+#include       // fuer RES_POOLPAGE_JAKET
+#endif
+#ifndef _MDIEXP_HXX
+#include        // Ansteuern der Statusleiste
+#endif
+#ifndef _STATSTR_HRC
+#include       //      -- " --
+#endif
+#ifndef _PTQUEUE_HXX
+#include 
+#endif
+#ifndef _HINTS_HXX
+#include 
+#endif
+#ifndef _TABFRM_HXX
+#include 
+#endif
+#ifndef _TXTFRM_HXX
+#include        // MinPrtLine
+#endif
+#ifndef _VISCRS_HXX
+#include        // SwShellCrsr
+#endif
+#ifndef _FMTPDSC_HXX
+#include       // SwFmtPageDesc
+#endif
+
+#define JOBSET_ERR_DEFAULT          0
+#define JOBSET_ERR_ERROR            1
+#define JOBSET_ERR_ISSTARTET        2
+
+//--------------------------------------------------------------------
+//Klasse zum Puffern von Paints
+class SwQueuedPaint
+{
+public:
+    SwQueuedPaint *pNext;
+    ViewShell      *pSh;
+    SwRect          aRect;
+
+    SwQueuedPaint( ViewShell *pNew, const SwRect &rRect ) :
+        pNext( 0 ),
+        pSh( pNew ),
+        aRect( rRect )
+    {}
+};
+
+SwQueuedPaint *SwPaintQueue::pQueue = 0;
+
+//Klasse zum Speichern einiger Druckereinstellungen
+class SwPrtOptSave
+{
+    Printer *pPrt;
+    Size aSize;
+    Paper ePaper;
+    Orientation eOrientation;
+    USHORT nPaperBin;
+public:
+    SwPrtOptSave( Printer *pPrinter );
+    ~SwPrtOptSave();
+};
+
+
+
+
+void SwPaintQueue::Add( ViewShell *pNew, const SwRect &rNew )
+{
+    SwQueuedPaint *pPt;
+    if ( 0 != (pPt = pQueue) )
+    {
+        while ( pPt->pSh != pNew && pPt->pNext )
+            pPt = pPt->pNext;
+        if ( pPt->pSh == pNew )
+        {
+            pPt->aRect.Union( rNew );
+            return;
+        }
+    }
+    SwQueuedPaint *pNQ = new SwQueuedPaint( pNew, rNew );
+    if ( pPt )
+        pPt->pNext = pNQ;
+    else
+        pQueue = pNQ;
+}
+
+
+
+void SwPaintQueue::Repaint()
+{
+    if ( !SwRootFrm::IsInPaint() && pQueue )
+    {
+        SwQueuedPaint *pPt = pQueue;
+        do
+        {   ViewShell *pSh = pPt->pSh;
+            SET_CURR_SHELL( pSh );
+            if ( pSh->IsPreView() )
+            {
+                if ( pSh->GetWin() )
+                {
+                    //Fuer PreView aussenherum, weil im PaintHdl (UI) die
+                    //Zeilen/Spalten bekannt sind.
+                    pSh->GetWin()->Invalidate();
+                    pSh->GetWin()->Update();
+                }
+            }
+            else
+                pSh->Paint( pPt->aRect.SVRect() );
+            pPt = pPt->pNext;
+        } while ( pPt );
+
+        do
+        {   pPt = pQueue;
+            pQueue = pQueue->pNext;
+            delete pPt;
+        } while ( pQueue );
+    }
+}
+
+
+
+void SwPaintQueue::Remove( ViewShell *pSh )
+{
+    SwQueuedPaint *pPt;
+    if ( 0 != (pPt = pQueue) )
+    {
+        SwQueuedPaint *pPrev = 0;
+        while ( pPt && pPt->pSh != pSh )
+        {
+            pPrev = pPt;
+            pPt = pPt->pNext;
+        }
+        if ( pPt )
+        {
+            if ( pPrev )
+                pPrev->pNext = pPt->pNext;
+            else if ( pPt == pQueue )
+                pQueue = 0;
+            delete pPt;
+        }
+    }
+}
+
+
+const XubString& SwPrtOptions::MakeNextJobName()
+{
+    static char __READONLY_DATA sDelim[] = " - ";
+    USHORT nDelim = sJobName.SearchAscii( sDelim );
+    if( STRING_NOTFOUND == nDelim )
+        sJobName.AppendAscii(sDelim);
+    else
+        sJobName.Erase( nDelim + 3/*Zeichen!*/ );
+
+    return sJobName += XubString::CreateFromInt32( ++nJobNo );
+}
+
+/******************************************************************************
+ *  Methode     :   void SetSwVisArea( ViewShell *pSh, Point aPrtOffset, ...
+ *  Beschreibung:
+ *  Erstellt    :   OK 04.11.94 16:27
+ *  Aenderung   :
+ ******************************************************************************/
+
+void SetSwVisArea( ViewShell *pSh, const SwRect &rRect )
+{
+    ASSERT( !pSh->GetWin(), "Drucken mit Window?" );
+    pSh->aVisArea = rRect;
+    pSh->Imp()->SetFirstVisPageInvalid();
+    Point aPt( rRect.Pos() );
+
+    aPt += pSh->aPrtOffst;
+    aPt.X() = -aPt.X(); aPt.Y() = -aPt.Y();
+
+    MapMode aMapMode( pSh->GetPrt()->GetMapMode() );
+    aMapMode.SetOrigin( aPt );
+    pSh->GetPrt()->SetMapMode( aMapMode );
+}
+
+/******************************************************************************
+ *  Methode     :   struct _PostItFld : public _SetGetExpFld
+ *  Beschreibung:   Update an das PostItFeld
+ *  Erstellt    :   OK 07.11.94 10:18
+ *  Aenderung   :
+ ******************************************************************************/
+struct _PostItFld : public _SetGetExpFld
+{
+    _PostItFld( const SwNodeIndex& rNdIdx, const SwTxtFld* pFld,
+                    const SwIndex* pIdx = 0 )
+        : _SetGetExpFld( rNdIdx, pFld, pIdx ) {}
+
+    USHORT GetPageNo( MultiSelection &rMulti, BOOL bRgt, BOOL bLft,
+                        USHORT& rVirtPgNo, USHORT& rLineNo );
+    SwPostItField* GetPostIt() const
+        { return (SwPostItField*) GetFld()->GetFld().GetFld(); }
+};
+
+
+
+USHORT _PostItFld::GetPageNo( MultiSelection &rMulti, BOOL bRgt, BOOL bLft,
+                                USHORT& rVirtPgNo, USHORT& rLineNo )
+{
+    //Problem: Wenn ein PostItFld in einem Node steht, der von mehr als
+    //einer Layout-Instanz repraesentiert wird, steht die Frage im Raum,
+    //ob das PostIt nur ein- oder n-mal gedruck werden soll.
+    //Wahrscheinlich nur einmal, als Seitennummer soll hier keine Zufaellige
+    //sondern die des ersten Auftretens des PostIts innerhalb des selektierten
+    //Bereichs ermittelt werden.
+    rVirtPgNo = 0;
+    USHORT nPos = GetCntnt();
+    SwClientIter aIter( (SwModify &)GetFld()->GetTxtNode() );
+    for( SwTxtFrm* pFrm = (SwTxtFrm*)aIter.First( TYPE( SwFrm ));
+            pFrm;  pFrm = (SwTxtFrm*)aIter.Next() )
+    {
+        if( pFrm->GetOfst() > nPos ||
+            pFrm->HasFollow() && pFrm->GetFollow()->GetOfst() <= nPos )
+            continue;
+        USHORT nPgNo = pFrm->GetPhyPageNum();
+        USHORT nVirt = pFrm->GetVirtPageNum();
+        if( rMulti.IsSelected( nPgNo ) &&
+            ( ((nVirt % 2) && bRgt) || (!(nVirt % 2) && bLft) ) )
+        {
+            rLineNo = (USHORT)(pFrm->GetLineCount( nPos ) +
+                      pFrm->GetAllLines() - pFrm->GetThisLines());
+            rVirtPgNo = nVirt;
+            return nPgNo;
+        }
+    }
+    return 0;
+}
+
+/******************************************************************************
+ *  Methode     :   void lcl_GetPostIts( SwDoc* pDoc, _SetGetExpFlds& ...
+ *  Beschreibung:
+ *  Erstellt    :   OK 07.11.94 10:20
+ *  Aenderung   :
+ ******************************************************************************/
+
+
+void lcl_GetPostIts( SwDoc* pDoc, _SetGetExpFlds& rSrtLst )
+{
+    SwFieldType* pFldType = pDoc->GetSysFldType( RES_POSTITFLD );
+    ASSERT( pFldType, "kein PostItType ? ");
+
+    if( pFldType->GetDepends() )
+    {
+        // Modify-Object gefunden, trage alle Felder ins Array ein
+        SwClientIter aIter( *pFldType );
+        SwClient* pLast;
+        const SwTxtFld* pTxtFld;
+
+        for( pLast = aIter.First( TYPE(SwFmtFld)); pLast; pLast = aIter.Next() )
+            if( 0 != ( pTxtFld = ((SwFmtFld*)pLast)->GetTxtFld() ) &&
+                pTxtFld->GetTxtNode().GetNodes().IsDocNodes() )
+            {
+                SwNodeIndex aIdx( pTxtFld->GetTxtNode() );
+                _PostItFld* pNew = new _PostItFld( aIdx, pTxtFld );
+                rSrtLst.Insert( pNew );
+            }
+    }
+}
+
+/******************************************************************************
+ *  Methode     :   void lcl_FormatPostIt( SwDoc* pDoc, SwPaM& aPam, ...
+ *  Beschreibung:
+ *  Erstellt    :   OK 07.11.94 10:20
+ *  Aenderung   :
+ ******************************************************************************/
+
+
+void lcl_FormatPostIt( SwDoc* pDoc, SwPaM& aPam, SwPostItField* pField,
+                           USHORT nPageNo, USHORT nLineNo )
+{
+    static char __READONLY_DATA sTmp[] = " : ";
+
+    ASSERT( ViewShell::GetShellRes(), "missing ShellRes" );
+
+    String aStr(    ViewShell::GetShellRes()->aPostItPage   );
+    aStr.AppendAscii(sTmp);
+
+    aStr += XubString::CreateFromInt32( nPageNo );
+    aStr += ' ';
+    if( nLineNo )
+    {
+        aStr += ViewShell::GetShellRes()->aPostItLine;
+        aStr.AppendAscii(sTmp);
+        aStr += XubString::CreateFromInt32( nLineNo );
+        aStr += ' ';
+    }
+    aStr += ViewShell::GetShellRes()->aPostItAuthor;
+    aStr.AppendAscii(sTmp);
+    aStr += pField->GetPar1();
+    aStr += ' ';
+    aStr += GetpApp()->GetAppInternational().GetDate( pField->GetDate() );
+    rtl_TextEncoding eCharSet = gsl_getSystemTextEncoding();
+    pDoc->Insert( aPam, aStr, eCharSet );
+
+    pDoc->SplitNode( *aPam.GetPoint() );
+    aStr = pField->GetPar2();
+#ifdef MAC
+    // Fuer den MAC alle CR durch LF ersetzen
+    for( USHORT n = 0; n < aStr.Len(); ++n )
+        if( aStr[n] == '\r' )
+            aStr[n] = '\n';
+#endif
+#if defined( WIN ) || defined( WNT ) || defined( PM2 )
+    // Bei Windows und Co alle CR rausschmeissen
+    aStr.EraseAllChars( '\r' );
+#endif
+    pDoc->Insert( aPam, aStr, eCharSet );
+    pDoc->SplitNode( *aPam.GetPoint() );
+    pDoc->SplitNode( *aPam.GetPoint() );
+}
+
+/******************************************************************************
+ *  Methode     :   void lcl_PrintPostIts( ViewShell* pPrtShell )
+ *  Beschreibung:
+ *  Erstellt    :   OK 07.11.94 10:21
+ *  Aenderung   :   MA 10. May. 95
+ ******************************************************************************/
+
+
+void lcl_PrintPostIts( ViewShell* pPrtShell, const XubString& rJobName,
+                        BOOL& rStartJob, int& rJobStartError, BOOL bReverse)
+{
+    // Formatieren und Ausdrucken
+    pPrtShell->CalcLayout();
+
+    SfxPrinter* pPrn = pPrtShell->GetPrt();
+
+    //Das Druckdokument ist ein default Dokument, mithin arbeitet es auf der
+    //StandardSeite.
+    SwFrm *pPage = pPrtShell->GetLayout()->Lower();
+
+    SwPrtOptSave aPrtSave( pPrn );
+
+    pPrn->SetOrientation( ORIENTATION_PORTRAIT );
+    pPrn->SetPaperBin( pPage->GetAttrSet()->GetPaperBin().GetValue() );
+
+    if( !rStartJob &&  JOBSET_ERR_DEFAULT == rJobStartError &&
+        rJobName.Len() )
+    {
+        if( !pPrn->IsJobActive() )
+        {
+            rStartJob = pPrn->StartJob( rJobName );
+            if( !rStartJob )
+            {
+                rJobStartError = JOBSET_ERR_ERROR;
+                return;
+            }
+        }
+        pPrtShell->InitPrt( pPrn );
+        rJobStartError = JOBSET_ERR_ISSTARTET;
+    }
+
+    // Wir koennen auch rueckwaerts:
+    if ( bReverse )
+        pPage = pPrtShell->GetLayout()->GetLastPage();
+
+    while( pPage )
+    {
+        //Mag der Anwender noch?, Abbruch erst in Prt()
+        GetpApp()->Reschedule();
+        ::SetSwVisArea( pPrtShell, pPage->Frm() );
+        pPrn->StartPage();
+        pPage->GetUpper()->Paint( pPage->Frm() );
+//      SFX_APP()->SpoilDemoOutput( *pPrtShell->GetOut(), pPage->Frm().SVRect());
+        SwPaintQueue::Repaint();
+        pPrn->EndPage();
+        pPage = bReverse ? pPage->GetPrev() : pPage->GetNext();
+    }
+}
+
+/******************************************************************************
+ *  Methode     :   void lcl_PrintPostItsEndDoc( ViewShell* pPrtShell, ...
+ *  Beschreibung:
+ *  Erstellt    :   OK 07.11.94 10:21
+ *  Aenderung   :   MA 10. May. 95
+ ******************************************************************************/
+
+
+void lcl_PrintPostItsEndDoc( ViewShell* pPrtShell,
+            _SetGetExpFlds& rPostItFields, MultiSelection &rMulti,
+            const XubString& rJobName, BOOL& rStartJob, int& rJobStartError,
+            BOOL bRgt, BOOL bLft, BOOL bRev )
+{
+    USHORT nPostIts = rPostItFields.Count();
+    if( !nPostIts )
+        // Keine Arbeit
+        return;
+
+    SET_CURR_SHELL( pPrtShell );
+
+    SwDoc* pPrtDoc = pPrtShell->GetDoc();
+
+    // Dokument leeren und ans Dokumentende gehen
+    SwPaM aPam( pPrtDoc->GetNodes().GetEndOfContent() );
+    aPam.Move( fnMoveBackward, fnGoDoc );
+    aPam.SetMark();
+    aPam.Move( fnMoveForward, fnGoDoc );
+    pPrtDoc->Delete( aPam );
+
+    for( USHORT i = 0, nVirtPg, nLineNo; i < nPostIts; ++i )
+    {
+        _PostItFld& rPostIt = (_PostItFld&)*rPostItFields[ i ];
+        if( rPostIt.GetPageNo( rMulti, bRgt, bLft, nVirtPg, nLineNo ) )
+            lcl_FormatPostIt( pPrtShell->GetDoc(), aPam,
+                           rPostIt.GetPostIt(), nVirtPg, nLineNo );
+    }
+
+    lcl_PrintPostIts( pPrtShell, rJobName, rStartJob, rJobStartError, bRev );
+}
+
+/******************************************************************************
+ *  Methode     :   void lcl_PrintPostItsEndPage( ViewShell* pPrtShell, ...
+ *  Beschreibung:
+ *  Erstellt    :   OK 07.11.94 10:22
+ *  Aenderung   :
+ ******************************************************************************/
+
+
+void lcl_PrintPostItsEndPage( ViewShell* pPrtShell,
+            _SetGetExpFlds& rPostItFields, USHORT nPageNo, MultiSelection &rMulti,
+            const XubString& rJobName, BOOL& rStartJob, int& rJobStartError,
+            BOOL bRgt, BOOL bLft, BOOL bRev )
+{
+    USHORT nPostIts = rPostItFields.Count();
+    if( !nPostIts )
+        // Keine Arbeit
+        return;
+
+    SET_CURR_SHELL( pPrtShell );
+
+    USHORT i = 0, nVirtPg, nLineNo;
+    while( ( i < nPostIts ) &&
+           ( nPageNo != ((_PostItFld&)*rPostItFields[ i ]).
+                                GetPageNo( rMulti,bRgt, bLft, nVirtPg, nLineNo )))
+        ++i;
+    if(i == nPostIts)
+        // Nix zu drucken
+        return;
+
+    SwDoc* pPrtDoc = pPrtShell->GetDoc();
+
+    // Dokument leeren und ans Dokumentende gehen
+    SwPaM aPam( pPrtDoc->GetNodes().GetEndOfContent() );
+    aPam.Move( fnMoveBackward, fnGoDoc );
+    aPam.SetMark();
+    aPam.Move( fnMoveForward, fnGoDoc );
+    pPrtDoc->Delete( aPam );
+
+    while( i < nPostIts )
+    {
+        _PostItFld& rPostIt = (_PostItFld&)*rPostItFields[ i ];
+        if( nPageNo == rPostIt.GetPageNo( rMulti, bRgt, bLft, nVirtPg, nLineNo ) )
+            lcl_FormatPostIt( pPrtShell->GetDoc(), aPam,
+                                rPostIt.GetPostIt(), nVirtPg, nLineNo );
+        ++i;
+    }
+    lcl_PrintPostIts( pPrtShell, rJobName, rStartJob, rJobStartError, bRev );
+}
+
+/******************************************************************************
+ *  Methode     :   void ViewShell::SetPrt( SfxPrinter *pNew )
+ *  Beschreibung:
+ *  Erstellt    :   OK 07.11.94 10:22
+ *  Aenderung   :
+ ******************************************************************************/
+
+void ViewShell::InitPrt( SfxPrinter *pPrt )
+{
+    //Fuer den Printer merken wir uns einen negativen Offset, der
+    //genau dem Offset de OutputSize entspricht. Das ist notwendig,
+    //weil unser Ursprung der linken ober Ecke der physikalischen
+    //Seite ist, die Ausgaben (SV) aber den Outputoffset als Urstprung
+    //betrachten.
+    if ( pPrt )
+    {
+        aPrtOffst = pPrt->GetPageOffset();
+        aPrtOffst += pPrt->GetMapMode().GetOrigin();
+        MapMode aMapMode( pPrt->GetMapMode() );
+        aMapMode.SetMapUnit( MAP_TWIP );
+        pPrt->SetMapMode( aMapMode );
+        pPrt->SetLineColor();
+        pPrt->SetFillColor();
+    }
+    else
+        aPrtOffst.X() = aPrtOffst.Y() = 0;
+
+    if ( !pWin )
+        pOut = pPrt;    //Oder was sonst?
+}
+
+void ViewShell::SetPrt( SfxPrinter *pNew )
+{
+    GetDoc()->SetPrt( pNew );
+}
+
+/******************************************************************************
+ *  Methode     :   void ViewShell::ChgAllPageOrientation
+ *  Erstellt    :   MA 08. Aug. 95
+ *  Aenderung   :
+ ******************************************************************************/
+
+
+void ViewShell::ChgAllPageOrientation( USHORT eOri )
+{
+    ASSERT( nStartAction, "missing an Action" );
+    SET_CURR_SHELL( this );
+
+    USHORT nAll = GetDoc()->GetPageDescCnt();
+    BOOL bNewOri = Orientation(eOri) == ORIENTATION_PORTRAIT ? FALSE : TRUE;
+
+    for( USHORT i = 0; i < nAll; ++ i )
+    {
+        const SwPageDesc& rOld = GetDoc()->GetPageDesc( i );
+        if( rOld.GetLandscape() != bNewOri )
+        {
+            SwPageDesc aNew( rOld );
+            aNew.SetLandscape( bNewOri );
+            SwFrmFmt& rFmt = aNew.GetMaster();
+            SwFmtFrmSize aSz( rFmt.GetFrmSize() );
+            // Groesse anpassen.
+            // PORTRAIT  -> Hoeher als Breit
+            // LANDSCAPE -> Breiter als Hoch
+            // Hoehe ist die VarSize, Breite ist die FixSize (per Def.)
+            if( bNewOri ? aSz.GetHeight() > aSz.GetWidth()
+                        : aSz.GetHeight() < aSz.GetWidth() )
+            {
+                SwTwips aTmp = aSz.GetHeight();
+                aSz.SetHeight( aSz.GetWidth() );
+                aSz.SetWidth( aTmp );
+                rFmt.SetAttr( aSz );
+            }
+            GetDoc()->ChgPageDesc( i, aNew );
+        }
+    }
+}
+
+/******************************************************************************
+ *  Methode     :   void ViewShell::ChgAllPageOrientation
+ *  Erstellt    :   MA 08. Aug. 95
+ *  Aenderung   :
+ ******************************************************************************/
+
+
+void ViewShell::ChgAllPageSize( Size &rSz )
+{
+    ASSERT( nStartAction, "missing an Action" );
+    SET_CURR_SHELL( this );
+
+    SwDoc* pDoc = GetDoc();
+    USHORT nAll = pDoc->GetPageDescCnt();
+
+    for( USHORT i = 0; i < nAll; ++i )
+    {
+        // Fuer WIN95 als Pointer anlegen! (falsche Optimierung!!)
+        SwPageDesc* pNew = new SwPageDesc( pDoc->GetPageDesc( i ) );
+        SwFrmFmt& rPgFmt = pNew->GetMaster();
+        Size aSz( rSz );
+        const BOOL bOri = pNew->GetLandscape();
+        if( bOri  ? aSz.Height() > aSz.Width()
+                  : aSz.Height() < aSz.Width() )
+        {
+            SwTwips aTmp = aSz.Height();
+            aSz.Height() = aSz.Width();
+            aSz.Width()  = aTmp;
+        }
+
+        SwFmtFrmSize aFrmSz( rPgFmt.GetFrmSize() );
+        aFrmSz.SetSize( aSz );
+        rPgFmt.SetAttr( aFrmSz );
+        pDoc->ChgPageDesc( i, *pNew );
+        delete pNew;
+    }
+}
+
+/******************************************************************************
+ *  Methode     :   void ViewShell::CalcPagesForPrint( short nMax, BOOL ...
+ *  Beschreibung:
+ *  Erstellt    :   OK 04.11.94 15:33
+ *  Aenderung   :   MA 07. Jun. 95
+ ******************************************************************************/
+
+
+
+void lcl_SetState( SfxProgress& rProgress, ULONG nPage, ULONG nMax,
+    const XubString *pStr, ULONG nAct, ULONG nCnt, ULONG nOffs, ULONG nPageNo )
+{
+    XubString aTmp = XubString::CreateFromInt64( nPageNo );
+    if( pStr )
+    {
+        aTmp += ' ';
+        aTmp += *pStr;
+        if( nCnt )
+        {
+            nMax *= 2;
+            rProgress.SetStateText( (nAct-1)*nMax+nPage+nOffs,
+                                        aTmp, nCnt*nMax );
+        }
+        else
+            rProgress.SetStateText( nPage, aTmp, nMax );
+    }
+    else
+    {
+        aTmp += ' '; aTmp += '('; aTmp += XubString::CreateFromInt64( nPage );
+        aTmp += '/'; aTmp += XubString::CreateFromInt64( nMax ); aTmp += ')';
+        rProgress.SetStateText( nPage, aTmp, nMax );
+    }
+}
+
+
+
+void ViewShell::CalcPagesForPrint( USHORT nMax, SfxProgress* pProgress,
+    const XubString* pStr, ULONG nMergeAct, ULONG nMergeCnt )
+{
+    SET_CURR_SHELL( this );
+
+    //Seitenweise durchformatieren, by the way kann die Statusleiste
+    //angetriggert werden, damit der Anwender sieht worauf er wartet.
+    //Damit der Vorgang moeglichst transparent gestaltet werden kann
+    //Versuchen wir mal eine Schaetzung.
+    SfxPrinter* pPrt = GetPrt();
+    BOOL bPrtJob = pPrt ? pPrt->IsJobActive() : FALSE;
+    SwRootFrm* pLayout = GetLayout();
+    ULONG nStatMax = pLayout->GetPageNum();
+
+    const SwFrm *pPage = pLayout->Lower();
+    SwLayAction aAction( pLayout, Imp() );
+
+    if( pProgress )
+    {
+        // HACK, damit die Anzeige sich nicht verschluckt.
+        const XubString aTmp( SW_RES( STR_STATSTR_PRINT ) );
+        pProgress->SetText( aTmp );
+        lcl_SetState( *pProgress, 1, nStatMax, pStr, nMergeAct, nMergeCnt, 0, 1 );
+    }
+
+    pLayout->StartAllAction();
+    for ( USHORT i = 1; pPage && i <= nMax; pPage = pPage->GetNext(), ++i )
+    {
+        if ( bPrtJob && !pPrt->IsJobActive() )
+            break;
+
+        if( pProgress )
+        {
+            //HACK, damit die Anzeige sich nicht verschluckt.
+            if ( i > nStatMax )
+                nStatMax = i;
+            lcl_SetState( *pProgress, i, nStatMax, pStr, nMergeAct, nMergeCnt, 0, i );
+            pProgress->Reschedule(); //Mag der Anwender noch oder hat er genug?
+        }
+
+        if ( bPrtJob && !pPrt->IsJobActive() )
+            break;
+        pPage->Calc();
+        SwRect aOldVis( VisArea() );
+        aVisArea = pPage->Frm();
+        Imp()->SetFirstVisPageInvalid();
+        aAction.Reset();
+        aAction.SetPaint( FALSE );
+        aAction.SetWaitAllowed( FALSE );
+        aAction.SetReschedule( TRUE );
+        aAction.Action();
+        aVisArea = aOldVis;             //Zuruecksetzen wg. der Paints!
+        Imp()->SetFirstVisPageInvalid();
+        SwPaintQueue::Repaint();
+    }
+    pLayout->EndAllAction();
+}
+
+/******************************************************************************
+ *  Methode     :   void ViewShell::Prt( const SwPrtOptions& rOptions )
+ *  Beschreibung:
+ *  Erstellt    :   OK 04.11.94 15:33
+ *  Aenderung   :   MA 10. May. 95
+ ******************************************************************************/
+
+
+BOOL ViewShell::Prt( SwPrtOptions& rOptions, SfxProgress& rProgress )
+{
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+//Immer die Druckroutine in viewpg.cxx (fuer Seitenvorschau) mitpflegen!!
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+    BOOL bStartJob = FALSE;
+
+    BOOL bSelection = rOptions.bPrintSelection;
+    // Damit beim Selektionsdruck nicht mit einer leeren Seite gestartet wird
+    BOOL bIgnoreEmptyPage = bSelection;
+
+    MultiSelection aMulti( rOptions.aMulti );
+
+    if ( !aMulti.GetSelectCount() )
+        return bStartJob;
+
+    Range aPages( aMulti.FirstSelected(), aMulti.LastSelected() );
+    if ( aPages.Max() > USHRT_MAX )
+        aPages.Max() = USHRT_MAX;
+
+    ASSERT( aPages.Min() > 0,
+            "Seite 0 Drucken?" );
+    ASSERT( aPages.Min() <= aPages.Max(),
+            "MinSeite groesser MaxSeite." );
+    // wenn kein Drucker vorhanden ist, wird nicht gedruckt
+    SfxPrinter* pPrt = GetPrt();
+    if( !pPrt || !pPrt->GetName().Len() )
+    {
+        ASSERT( FALSE, "Drucken ohne Drucker?" );
+        return bStartJob;
+    }
+
+    if( !rOptions.GetJobName().Len() && !pPrt->IsJobActive() )
+        return bStartJob;
+
+    // Einstellungen am Drucker merken
+    SwPrtOptSave aPrtSave( pPrt );
+
+    // eine neue Shell fuer den Printer erzeugen
+    ViewShell *pShell;
+    SwDoc *pPrtDoc;
+    SvEmbeddedObjectRef aDocShellRef;
+
+    if ( bSelection )
+    {
+        ASSERT( this->IsA( TYPE(SwFEShell) ),"ViewShell::Prt for FEShell only");
+        SwFEShell* pFESh = (SwFEShell*)this;
+        // Wir bauen uns ein neues Dokument
+        pPrtDoc = new SwDoc;
+        pPrtDoc->AddLink();
+        pPrtDoc->SetRefForDocShell( (SvEmbeddedObjectRef*)&(long&)aDocShellRef );
+        pPrtDoc->LockExpFlds();
+
+        // Der Drucker wird uebernommen
+        pPrtDoc->SetPrt( pPrt );
+
+        const SfxPoolItem* pCpyItem;
+        const SfxItemPool& rPool = GetAttrPool();
+        for( USHORT nWh = POOLATTR_BEGIN; nWh < POOLATTR_END; ++nWh )
+            if( 0 != ( pCpyItem = rPool.GetPoolDefaultItem( nWh ) ) )
+                pPrtDoc->GetAttrPool().SetPoolDefaultItem( *pCpyItem );
+
+        // JP 29.07.99 - Bug 67951 - set all Styles from the SourceDoc into
+        //                              the PrintDoc - will be replaced!
+        pPrtDoc->ReplaceStyles( *GetDoc() );
+
+        SwShellCrsr *pActCrsr = pFESh->_GetCrsr();
+        SwShellCrsr *pFirstCrsr = (SwShellCrsr*)*((SwCursor*)pActCrsr->GetNext());
+        if( !pActCrsr->HasMark() ) // bei Multiselektion kann der aktuelle Cursor leer sein
+            pActCrsr = (SwShellCrsr*)*((SwCursor*)pActCrsr->GetPrev());
+        // Die Y-Position der ersten Selektion
+        long nMinY = pFESh->IsTableMode() ? pFESh->GetTableCrsr()->GetSttPos().Y()
+                                   : pFirstCrsr->GetSttPos().Y();
+        SwPageFrm* pPage = (SwPageFrm*)GetLayout()->Lower();
+        // Suche die zugehoerige Seite
+        while ( pPage->GetNext() && nMinY >= pPage->GetNext()->Frm().Top() )
+            pPage = (SwPageFrm*)pPage->GetNext();
+        // und ihren Seitendescribtor
+        SwPageDesc *pSrc = pPage->GetPageDesc();
+        SwPageDesc* pPageDesc = pPrtDoc->FindPageDescByName(
+                                    pPage->GetPageDesc()->GetName() );
+
+        if( !pFESh->IsTableMode() && pActCrsr->HasMark() )
+        {   // Am letzten Absatz die Absatzattribute richten:
+            SwNodeIndex aNodeIdx( *pPrtDoc->GetNodes().GetEndOfContent().StartOfSectionNode() );
+            SwTxtNode* pTxtNd = pPrtDoc->GetNodes().GoNext( &aNodeIdx )->GetTxtNode();
+            SwCntntNode *pLastNd =
+                pActCrsr->GetCntntNode( (*pActCrsr->GetMark()) <= (*pActCrsr->GetPoint()) );
+            // Hier werden die Absatzattribute des ersten Absatzes uebertragen
+            if( pLastNd && pLastNd->IsTxtNode() )
+                ((SwTxtNode*)pLastNd)->CopyCollFmt( *pTxtNd );
+        }
+
+        // es wurde in der CORE eine neu angelegt (OLE-Objekte kopiert!)
+//      if( aDocShellRef.Is() )
+//          SwDataExchange::InitOle( aDocShellRef, pPrtDoc );
+        // und fuellen es mit dem selektierten Bereich
+        pFESh->Copy( pPrtDoc );
+
+        //Jetzt noch am ersten Absatz die Seitenvorlage setzen
+        {
+            SwNodeIndex aNodeIdx( *pPrtDoc->GetNodes().GetEndOfContent().StartOfSectionNode() );
+            SwCntntNode* pCNd = pPrtDoc->GetNodes().GoNext( &aNodeIdx ); // gehe zum 1. ContentNode
+            if( pFESh->IsTableMode() )
+            {
+                SwTableNode* pTNd = pCNd->FindTableNode();
+                if( pTNd )
+                    pTNd->GetTable().GetFrmFmt()->SetAttr( SwFmtPageDesc( pPageDesc ) );
+            }
+            else
+            {
+                pCNd->SetAttr( SwFmtPageDesc( pPageDesc ) );
+                if( pFirstCrsr->HasMark() )
+                {
+                    SwTxtNode *pTxtNd = pCNd->GetTxtNode();
+                    if( pTxtNd )
+                    {
+                        SwCntntNode *pFirstNd =
+                            pFirstCrsr->GetCntntNode( (*pFirstCrsr->GetMark()) > (*pFirstCrsr->GetPoint()) );
+                        // Hier werden die Absatzattribute des ersten Absatzes uebertragen
+                        if( pFirstNd && pFirstNd->IsTxtNode() )
+                            ((SwTxtNode*)pFirstNd)->CopyCollFmt( *pTxtNd );
+                    }
+                }
+            }
+        }
+
+        // eine ViewShell darauf
+        pShell = new ViewShell( pPrtDoc, ::GetSpellChecker(), ::GetHyphenator(),
+                                0, pOpt );
+        pPrtDoc->SetRefForDocShell( 0 );
+    }
+    else
+    {
+        pPrtDoc = GetDoc();
+        pShell = new ViewShell( this, 0 );
+    }
+
+    {   //Zusaetzlicher Scope, damit die CurrShell vor dem zerstoeren der
+        //Shell zurueckgesetzt wird.
+
+    SET_CURR_SHELL( pShell );
+
+    //JP 01.02.99: das ReadOnly Flag wird NIE mitkopiert; Bug 61335
+    if( pOpt->IsReadonly() )
+        pShell->pOpt->SetReadonly( TRUE );
+
+    pShell->PrepareForPrint( rOptions );
+
+    // gibt es versteckte Absatzfelder, braucht nicht beruecksichtigt werden,
+    // wenn diese bereits ausgeblendet sind
+    BOOL bHiddenFlds = FALSE;
+    SwHiddenParaFieldType* pFldType = 0;
+    if ( GetViewOptions()->IsShowHiddenPara() )
+    {
+        pFldType    = (SwHiddenParaFieldType*)pPrtDoc->
+                                          GetSysFldType(RES_HIDDENPARAFLD);
+        bHiddenFlds = pFldType && pFldType->GetDepends();
+        if( bHiddenFlds )
+        {
+            SwMsgPoolItem aHnt( RES_HIDDENPARA_PRINT );
+            pFldType->Modify( &aHnt, 0);
+        }
+    }
+
+
+    XubString *pStr;
+    ULONG nMergeAct = rOptions.nMergeAct, nMergeCnt = rOptions.nMergeCnt;
+    if( nMergeAct )
+    {
+        pStr = new SW_RESSTR(STR_STATSTR_LETTER);
+        *pStr += ' ';
+        *pStr += XubString::CreateFromInt64( nMergeAct );
+        if( nMergeCnt )
+        {
+            *pStr += '/';
+            *pStr += XubString::CreateFromInt64( nMergeCnt );
+        }
+    }
+    else
+    {
+        pStr = 0;
+        ++nMergeAct;
+    }
+
+    // Seiten fuers Drucken formatieren
+    pShell->CalcPagesForPrint( (USHORT)aPages.Max(), &rProgress, pStr,
+                                nMergeAct, nMergeCnt );
+
+    if( rOptions.GetJobName().Len() || pPrt->IsJobActive() )
+    {
+        BOOL bStop = FALSE;
+        int nJobStartError = JOBSET_ERR_DEFAULT;
+
+        USHORT nCopyCnt = rOptions.bCollate ? rOptions.nCopyCount : 1;
+
+        USHORT nPrintCount = 1;
+        XubString sJobName( rOptions.GetJobName() );
+
+        for ( USHORT nCnt = 0; !bStop && nCnt < nCopyCnt; nCnt++ )
+        {
+            const SwPageFrm *pStPage  = (SwPageFrm*)pShell->GetLayout()->Lower();
+            const SwFrm     *pEndPage = pStPage;
+
+            USHORT nFirstPageNo = 0;
+            USHORT nLastPageNo  = 0;
+            USHORT nPageNo      = 1;
+
+            if( rOptions.bSinglePrtJobs && sJobName.Len() &&
+                ( bStartJob || rOptions.bJobStartet ) )
+            {
+                pPrt->EndJob();
+                bStartJob = FALSE;
+                rOptions.bJobStartet = TRUE;
+
+                // Reschedule statt Yield, da Yield keine Events abarbeitet
+                // und es sonst eine Endlosschleife gibt.
+                while( pPrt->IsPrinting() )
+                        rProgress.Reschedule();
+
+                sJobName = rOptions.MakeNextJobName();
+                nJobStartError = JOBSET_ERR_DEFAULT;
+            }
+
+            for( USHORT i = 1; i <= (USHORT)aPages.Max(); ++i )
+            {
+                if( i < (USHORT)aPages.Min() )
+                {
+                    if( !pStPage->GetNext() )
+                        break;
+                    pStPage = (SwPageFrm*)pStPage->GetNext();
+                    pEndPage= pStPage;
+                }
+                else if( i == (USHORT)aPages.Min() )
+                {
+                    nFirstPageNo = i;
+                    nLastPageNo = nFirstPageNo;
+                    if( !pStPage->GetNext() || (i == (USHORT)aPages.Max()) )
+                        break;
+                    pEndPage = pStPage->GetNext();
+                }
+                else if( i > (USHORT)aPages.Min() )
+                {
+                    nLastPageNo = i;
+                    if( !pEndPage->GetNext() || (i == (USHORT)aPages.Max()) )
+                        break;
+                    pEndPage = pEndPage->GetNext();
+                }
+            }
+
+            if( !nFirstPageNo )
+            {
+                if( bHiddenFlds )
+                {
+                    SwMsgPoolItem aHnt( RES_HIDDENPARA_PRINT );
+                    pFldType->Modify( &aHnt, 0);
+                    CalcPagesForPrint( (USHORT)aPages.Max(), &rProgress, pStr,
+                                        nMergeAct, nMergeCnt );
+                }
+                bStop = TRUE;
+                break;
+            }
+
+// HACK: Hier muss von der MultiSelection noch eine akzeptable Moeglichkeit
+// geschaffen werden, alle Seiten von Seite x an zu deselektieren.
+// Z.B. durch SetTotalRange ....
+
+//          aMulti.Select( Range( nLastPageNo+1, SELECTION_MAX ), FALSE );
+            MultiSelection aTmpMulti( Range( 1, nLastPageNo ) );
+            long nTmpIdx = aMulti.FirstSelected();
+            while ( SFX_ENDOFSELECTION != nTmpIdx && nTmpIdx <= long(nLastPageNo) )
+            {
+                aTmpMulti.Select( nTmpIdx );
+                nTmpIdx = aMulti.NextSelected();
+            }
+            aMulti = aTmpMulti;
+// Ende des HACKs
+
+            const USHORT nSelCount = USHORT(aMulti.GetSelectCount()
+                            /* * nCopyCnt*/);
+
+            rProgress.SetText( SW_RESSTR(STR_STATSTR_PRINT) );
+            lcl_SetState( rProgress, 1, nSelCount, pStr,
+                                nMergeAct, nMergeCnt, nSelCount, 1 );
+
+            if ( rOptions.bPrintReverse )
+            {
+                const SwFrm *pTmp = pStPage;
+                pStPage  = (SwPageFrm*)pEndPage;
+                pEndPage = pTmp;
+                nPageNo  = nLastPageNo;
+            }
+            else
+                nPageNo = nFirstPageNo;
+
+            // PostitListe holen
+            _SetGetExpFlds aPostItFields;
+            SwDoc*     pPostItDoc   = 0;
+            ViewShell* pPostItShell = 0;
+            if( rOptions.nPrintPostIts != POSTITS_NONE )
+            {
+                lcl_GetPostIts( pDoc, aPostItFields );
+                pPostItDoc   = new SwDoc;
+                pPostItDoc->SetPrt( pPrt );
+                pPostItShell = new ViewShell( pPostItDoc,
+                                              pShell->GetSpellChecker(),
+                                              pShell->GetHyphenator(),
+                                              0, pShell->GetViewOptions() );
+                // Wenn PostIts am Dokumentenende gedruckt werden sollen,
+                // die Druckreihenfolge allerdings umgekehrt ist, dann hier
+                if ( ( rOptions.nPrintPostIts == POSTITS_ENDDOC ) &&
+                        rOptions.bPrintReverse )
+                        lcl_PrintPostItsEndDoc( pPostItShell, aPostItFields,
+                        aMulti, sJobName, bStartJob, nJobStartError,
+                        rOptions.bPrintRightPage, rOptions.bPrintLeftPage, TRUE );
+
+            }
+
+            // aOldMapMode wird fuer das Drucken von Umschlaegen gebraucht.
+            MapMode aOldMapMode;
+
+            const SwPageDesc *pLastPageDesc = NULL;
+            const BOOL bSetOrient = pPrt->HasSupport( SUPPORT_SET_ORIENTATION );
+            const BOOL bSetPaperSz = pPrt->HasSupport( SUPPORT_SET_PAPERSIZE );
+            const BOOL bSetPaperBin =  !rOptions.bPaperFromSetup &&
+                                    pPrt->HasSupport( SUPPORT_SET_PAPERBIN );
+            const BOOL bSetPrt = bSetOrient || bSetPaperSz || bSetPaperBin;
+
+            if ( rOptions.nPrintPostIts != POSTITS_ONLY )
+            {
+                while( pStPage && !bStop )
+                {
+                    // Mag der Anwender noch ?
+                    rProgress.Reschedule();
+                    if( ( JOBSET_ERR_ERROR == nJobStartError )
+                        || ( !pPrt->IsJobActive() &&
+                            ( !sJobName.Len() || bStartJob ) ) )
+                    {
+                        if( bHiddenFlds )
+                        {
+                            SwMsgPoolItem aHnt( RES_HIDDENPARA_PRINT );
+                            pFldType->Modify( &aHnt, 0);
+                            CalcPagesForPrint( (USHORT)aPages.Max() );
+                        }
+                        bStop = TRUE;
+                        break;
+                    }
+
+                    ::SetSwVisArea( pShell, pStPage->Frm() );
+
+                    //  wenn wir einen Umschlag drucken wird ein Offset beachtet
+                    if( pStPage->GetFmt()->GetPoolFmtId() == RES_POOLPAGE_JAKET )
+                    {
+                        aOldMapMode = pPrt->GetMapMode();
+                        Point aNewOrigin = pPrt->GetMapMode().GetOrigin();
+                        aNewOrigin += rOptions.aOffset;
+                        MapMode aTmp( pPrt->GetMapMode() );
+                        aTmp.SetOrigin( aNewOrigin );
+                        pPrt->SetMapMode( aTmp );
+                    }
+
+                    USHORT nVirtNo = pStPage->GetVirtPageNum();
+                    if( aMulti.IsSelected( nPageNo ) &&
+                        ( ((nVirtNo % 2) && rOptions.bPrintRightPage) ||
+                            (!(nVirtNo % 2) && rOptions.bPrintLeftPage)    ) )
+                    {
+                        if ( bSetPrt && pLastPageDesc != pStPage->GetPageDesc() )
+                        {
+                            pLastPageDesc = pStPage->GetPageDesc();
+                            BOOL bLandScp = pLastPageDesc->GetLandscape();
+
+                            if( bSetPaperBin )      // Schacht einstellen.
+                                pPrt->SetPaperBin( pStPage->GetFmt()->
+                                                    GetPaperBin().GetValue() );
+                            if ( bSetPaperSz )
+                            {
+                                Size aSize = pStPage->Frm().SSize();
+                                if ( bLandScp && bSetOrient )
+                                {
+                                    long nWidth = aSize.Width();
+                                    aSize.Width() = aSize.Height();
+                                    aSize.Height() = nWidth;
+                                }
+                                Paper ePaper = SvxPaperInfo::GetSvPaper(aSize,MAP_TWIP,TRUE);
+                                if ( PAPER_USER == ePaper )
+                                    pPrt->SetPaperSizeUser( aSize );
+                                else
+                                    pPrt->SetPaper( ePaper );
+                            }
+                            if ( bSetOrient )
+                            {
+                                // Orientation einstellen: Breiter als Hoch
+                                //  -> Landscape, sonst -> Portrait.
+                                if( bLandScp )
+                                    pPrt->SetOrientation(ORIENTATION_LANDSCAPE);
+                                else
+                                    pPrt->SetOrientation(ORIENTATION_PORTRAIT);
+                            }
+                        }
+                        // Wenn PostIts nach Seite gedruckt werden sollen,
+                        // jedoch Reverse eingestellt ist ...
+                        if( rOptions.bPrintReverse &&
+                            rOptions.nPrintPostIts == POSTITS_ENDPAGE )
+                                lcl_PrintPostItsEndPage( pPostItShell, aPostItFields,
+                                    nPageNo, aMulti, sJobName, bStartJob, nJobStartError,
+                                    rOptions.bPrintRightPage, rOptions.bPrintLeftPage,
+                                    rOptions.bPrintReverse );
+
+                        lcl_SetState( rProgress, nPrintCount++, nSelCount,
+                                            pStr, nMergeAct, nMergeCnt,
+                                            nSelCount, nPageNo );
+
+                        if( !bStartJob && JOBSET_ERR_DEFAULT == nJobStartError
+                            && sJobName.Len() )
+                        {
+                            if( !pPrt->IsJobActive() )
+                            {
+                                bStartJob = pPrt->StartJob( sJobName );
+                                if( !bStartJob )
+                                {
+                                    nJobStartError = JOBSET_ERR_ERROR;
+                                    continue;
+                                }
+                            }
+                            pShell->InitPrt( pPrt );
+                            ::SetSwVisArea( pShell, pStPage->Frm() );
+                            nJobStartError = JOBSET_ERR_ISSTARTET;
+                        }
+                        // Bei Selektionsdruck wird ggf. die erste leere Seite ausgelassen
+                        if( !bIgnoreEmptyPage || (0==(bIgnoreEmptyPage=TRUE)) ||
+                            pStPage->Frm().Height() )
+                        {
+                            pPrt->StartPage();
+                            pStPage->GetUpper()->Paint( pStPage->Frm() );
+//                          SFX_APP()->SpoilDemoOutput( *pShell->GetOut(),
+//                                                           pStPage->Frm().SVRect() );
+                            pPrt->EndPage();
+                        }
+                        SwPaintQueue::Repaint();
+
+                        //Wenn eine Tabelle heraushaengt, so wird der Rest der
+                        //Tabelle auf zusaetzliche Seiten verteilt.
+                        const SwFrm *pFrm = pStPage->FindLastBodyCntnt();
+                        if ( pFrm && pFrm->IsInTab() )
+                        {
+                            pFrm = pFrm->FindTabFrm();
+                            const SwFrm *pBody = pStPage->FindBodyCont();
+                            long nBottom = pBody->Prt().Bottom();
+                            nBottom += pBody->Frm().Top();
+                            if ( nBottom < pFrm->Frm().Bottom() )
+                            {
+                                SwRootFrm *pRoot = (SwRootFrm*)pStPage->GetUpper();
+                                long nDiff = pFrm->Frm().Bottom() - nBottom;
+                                SwRect aNewVis( pBody->Prt() );
+                                aNewVis += pBody->Frm().Pos();
+                                SwRect aTmp( pShell->VisArea() );
+                                aTmp.SSize().Height() = LONG_MAX - aTmp.Top();
+                                aTmp.SSize().Width()  = LONG_MAX - aTmp.Left();
+                                ::SetSwVisArea( pShell, aTmp );
+                                while ( nDiff > 0 )
+                                {
+                                    pPrt->StartPage();
+
+                                    //VisArea auf die Tabelle schummeln
+                                    aNewVis.Pos().Y() += aNewVis.Height()+1;
+
+                                    //Offset in den MapMode schummeln.
+                                    MapMode aMap( pPrt->GetMapMode() );
+                                    Point aTmp( aMap.GetOrigin() );
+                                    aTmp.Y() -= aNewVis.Height()+1;
+                                    aMap.SetOrigin( aTmp );
+                                    pPrt->SetMapMode( aMap );
+
+                                    pRoot->HackPrepareLongTblPaint( HACK_TABLEMODE_INIT );
+                                    SwTxtFrm::SetMinPrtLine( aNewVis.Pos().Y() );
+                                    pFrm->PaintBaBo( aNewVis, pStPage, TRUE );
+                                    if ( pShell->Imp()->HasDrawView() )
+                                    {
+                                        pRoot->HackPrepareLongTblPaint( HACK_TABLEMODE_LOCKLINES );
+                                        pShell->Imp()->PaintLayer( pShell->GetDoc()->GetHellId(), aNewVis );
+                                        pRoot->HackPrepareLongTblPaint( HACK_TABLEMODE_PAINTLINES );
+                                        pRoot->HackPrepareLongTblPaint( HACK_TABLEMODE_UNLOCKLINES );
+                                    }
+                                    pFrm->Paint( aNewVis );
+                                    if ( pShell->Imp()->HasDrawView() )
+                                    {
+                                        pShell->Imp()->PaintLayer( pShell->GetDoc()->GetHeavenId(),
+                                                                   aNewVis );
+                                        pShell->Imp()->PaintLayer( pShell->GetDoc()->
+                                                                GetControlsId(), aNewVis );
+                                        pRoot->HackPrepareLongTblPaint( HACK_TABLEMODE_PAINTLINES );
+                                    }
+                                    pRoot->HackPrepareLongTblPaint( HACK_TABLEMODE_EXIT );
+                                    SwTxtFrm::SetMinPrtLine( 0 );
+
+//                                  SFX_APP()->SpoilDemoOutput( *pShell->GetOut(),
+//                                                               aNewVis.SVRect() );
+                                    pPrt->EndPage();
+                                    SwPaintQueue::Repaint();
+                                    nDiff -= pBody->Prt().Height();
+                                }
+                            }
+                        }
+
+                        // Wenn PostIts nach Seite gedruckt werden sollen ...
+                        if( (!rOptions.bPrintReverse) &&
+                            rOptions.nPrintPostIts == POSTITS_ENDPAGE )
+                                lcl_PrintPostItsEndPage( pPostItShell, aPostItFields,
+                                    nPageNo, aMulti, sJobName, bStartJob, nJobStartError,
+                                    rOptions.bPrintRightPage, rOptions.bPrintLeftPage,
+                                    rOptions.bPrintReverse );
+                    }
+
+                    // den eventl. fuer Umschlaege modifizierte OutDevOffset wieder
+                    // zuruecksetzen.
+                    if( pStPage->GetFmt()->GetPoolFmtId() == RES_POOLPAGE_JAKET )
+                        pPrt->SetMapMode( aOldMapMode );
+
+                    if ( pStPage == pEndPage )
+                        pStPage = 0;
+                    else if ( rOptions.bPrintReverse )
+                    {
+                        --nPageNo;
+                        pStPage = (SwPageFrm*)pStPage->GetPrev();
+                    }
+                    else
+                    {   ++nPageNo;
+                        pStPage = (SwPageFrm*)pStPage->GetNext();
+                    }
+                }
+                if ( bStop )
+                    break;
+            }
+
+            // Wenn PostIts am Dokumentenende gedruckt werden sollen, dann hier machen
+            if( ((rOptions.nPrintPostIts == POSTITS_ENDDOC) && !rOptions.bPrintReverse)
+                || (rOptions.nPrintPostIts == POSTITS_ONLY) )
+                    lcl_PrintPostItsEndDoc( pPostItShell, aPostItFields, aMulti,
+                        sJobName, bStartJob, nJobStartError,
+                        rOptions.bPrintRightPage, rOptions.bPrintLeftPage,
+                        rOptions.bPrintReverse );
+
+            if( pPostItShell )
+            {
+                pPostItDoc->_SetPrt( 0 );   //damit am echten DOC der Drucker bleibt
+                delete pPostItShell;        //Nimmt das PostItDoc mit ins Grab.
+            }
+
+            if( bStartJob )
+                rOptions.bJobStartet = TRUE;
+        }
+
+        if( bHiddenFlds && !bStop )
+        {
+            SwMsgPoolItem aHnt( RES_HIDDENPARA_PRINT );
+            pFldType->Modify( &aHnt, 0);
+            CalcPagesForPrint( (USHORT)aPages.Max() );
+        }
+    }
+    delete pStr;
+
+    }  //Zus. Scope wg. CurShell!
+
+    delete pShell;
+
+    if ( bSelection )
+    {
+         // damit das Dokument nicht den Drucker mit ins Grab nimmt
+        pPrtDoc->_SetPrt( NULL );
+
+        if ( !pPrtDoc->RemoveLink() )
+            delete pPrtDoc;
+    }
+    return bStartJob;
+}
+
+/******************************************************************************
+ *  Methode     :   PrtOle2()
+ *  Beschreibung:
+ *  Erstellt    :   PK 07.12.94
+ *  Aenderung   :   MA 16. Feb. 95
+ ******************************************************************************/
+
+
+
+void ViewShell::PrtOle2( SwDoc *pDoc, const SwViewOption *pOpt,
+                         OutputDevice* pOleOut, const Rectangle& rRect )
+{
+    //Wir brauchen eine Shell fuer das Drucken. Entweder hat das Doc schon
+    //eine, dann legen wir uns eine neue Sicht an, oder das Doc hat noch
+    //keine, dann erzeugen wir die erste Sicht.
+    ViewShell *pSh;
+    if ( pDoc->GetRootFrm() && pDoc->GetRootFrm()->GetCurrShell() )
+        pSh = new ViewShell( pDoc->GetRootFrm()->GetCurrShell(), 0, pOleOut );
+    else
+    {
+        pSh = new ViewShell( pDoc, ::GetSpellChecker(), ::GetHyphenator(),
+                             0, pOpt, pOleOut );
+    }
+
+    {
+        SET_CURR_SHELL( pSh );
+        pSh->SetPrtFormatOption( TRUE );
+
+        SwRect aSwRect( rRect );
+        pSh->aVisArea = aSwRect;
+
+        if ( pDoc->IsBrowseMode() && pSh->GetNext() == pSh )
+        {
+            pSh->CheckBrowseView( FALSE );
+            pDoc->GetRootFrm()->Lower()->InvalidateSize();
+        }
+
+        // Seiten fuers Drucken formatieren
+        pSh->CalcPagesForPrint( SHRT_MAX );
+
+        //#39275# jetzt will der Meyer doch ein Clipping
+        pOleOut->Push( PUSH_CLIPREGION );
+        pOleOut->IntersectClipRegion( aSwRect.SVRect() );
+        pSh->GetLayout()->Paint( aSwRect );
+//      SFX_APP()->SpoilDemoOutput( *pOleOut, rRect );
+        pOleOut->Pop();
+
+        // erst muss das CurrShell Object zerstoert werden!!
+    }
+    delete pSh;
+}
+
+/******************************************************************************
+ *  Methode     :   IsAnyFieldInDoc()
+ *  Beschreibung:   Stellt fest, ob im DocNodesArray Felder verankert sind
+ *  Erstellt    :   JP 27.07.95
+ *  Aenderung   :   JP 10.12.97
+ ******************************************************************************/
+
+
+
+BOOL ViewShell::IsAnyFieldInDoc() const
+{
+    const SfxPoolItem* pItem;
+    USHORT nMaxItems = pDoc->GetAttrPool().GetItemCount( RES_TXTATR_FIELD );
+    for( USHORT n = 0; n < nMaxItems; ++n )
+        if( 0 != (pItem = pDoc->GetAttrPool().GetItem( RES_TXTATR_FIELD, n )))
+        {
+            const SwFmtFld* pFmtFld = (SwFmtFld*)pItem;
+            const SwTxtFld* pTxtFld = pFmtFld->GetTxtFld();
+            if( pTxtFld && pTxtFld->GetTxtNode().GetNodes().IsDocNodes() )
+                return TRUE;
+        }
+    return FALSE;
+}
+
+
+
+/******************************************************************************
+ *  Klasse      :   SwPrtOptSave
+ *  Erstellt    :   AMA 12.07.95
+ *  Aenderung   :   AMA 12.07.95
+ *  Holt sich im Ctor folgende Einstellungen des Druckers, die im Dtor dann
+ *  wieder im Drucker gesetzt werden (falls sie sich ueberhaupt geaendert haben)
+ *  - PaperBin - Orientation - PaperSize -
+ ******************************************************************************/
+
+
+
+SwPrtOptSave::SwPrtOptSave( Printer *pPrinter )
+    : pPrt( pPrinter )
+{
+    if ( pPrt )
+    {
+        ePaper = pPrt->GetPaper();
+        if ( PAPER_USER == ePaper )
+            aSize = pPrt->GetPaperSize();
+        eOrientation = pPrt->GetOrientation();
+        nPaperBin = pPrt->GetPaperBin();
+
+    }
+}
+
+
+
+SwPrtOptSave::~SwPrtOptSave()
+{
+    if ( pPrt )
+    {
+        if ( PAPER_USER == ePaper )
+        {
+            if( pPrt->GetPaperSize() != aSize )
+                pPrt->SetPaperSizeUser( aSize );
+        }
+        else if ( pPrt->GetPaper() != ePaper )
+            pPrt->SetPaper( ePaper );
+        if ( pPrt->GetOrientation() != eOrientation)
+            pPrt->SetOrientation( eOrientation );
+        if ( pPrt->GetPaperBin() != nPaperBin )
+            pPrt->SetPaperBin( nPaperBin );
+    }
+}
+
+
+
+void ViewShell::PrepareForPrint(  const SwPrtOptions &rOptions )
+{
+    // Viewoptions fuer den Drucker setzen
+    pOpt->SetGraphic ( TRUE == rOptions.bPrintGraph );
+    pOpt->SetTable   ( TRUE == rOptions.bPrintTable );
+    pOpt->SetDraw    ( TRUE == rOptions.bPrintDraw  );
+    pOpt->SetControl ( TRUE == rOptions.bPrintControl );
+    pOpt->SetPageBack( TRUE == rOptions.bPrintPageBackground );
+    pOpt->SetBlackFont( TRUE == rOptions.bPrintBlackFont );
+
+    if ( HasDrawView() )
+    {
+        SdrView *pDrawView = GetDrawView();
+        FASTBOOL bDraw = rOptions.bPrintDraw;
+        pDrawView->SetLineDraftPrn( !bDraw );
+        pDrawView->SetFillDraftPrn( !bDraw );
+        pDrawView->SetGrafDraftPrn( !bDraw );
+        pDrawView->SetTextDraftPrn( !bDraw );
+    }
+}
+
+/************************************************************************
+
+      $Log: not supported by cvs2svn $
+      Revision 1.193  2000/09/18 16:04:38  willem.vandorp
+      OpenOffice header added.
+
+      Revision 1.192  2000/06/15 19:06:54  jp
+      Prt: don't forget to start the printjob, if sortet, copies and single printjobes are desired
+
+      Revision 1.191  2000/05/23 17:37:30  jp
+      Bugfixes for Unicode
+
+      Revision 1.190  2000/05/10 13:43:09  ama
+      Unicode changes
+
+      Revision 1.189  2000/05/09 11:43:25  ama
+      Unicode changes
+
+      Revision 1.188  2000/04/27 07:37:23  os
+      UNICODE
+
+      Revision 1.187  2000/03/28 20:57:23  jp
+      Bug #74562#: Prt - on the printer can be run a job, its not an error
+
+      Revision 1.186  2000/02/21 16:01:07  ama
+      Fix #73147#: No spoildemo for free versions
+
+      Revision 1.185  2000/02/11 14:36:15  hr
+      #70473# changes for unicode ( patched by automated patchtool )
+
+      Revision 1.184  1999/12/16 14:31:58  hjs
+      #65293# static instead of const - ask jp
+
+      Revision 1.183  1999/12/14 14:28:34  jp
+      Bug #69595#: print can create single Jobs
+
+      Revision 1.182  1999/10/25 19:09:24  tl
+      ongoing ONE_LINGU implementation
+
+      Revision 1.181  1999/08/31 08:45:54  TL
+      #if[n]def ONE_LINGU inserted (for transition of lingu to StarOne)
+
+
+      Rev 1.180   31 Aug 1999 10:45:54   TL
+   #if[n]def ONE_LINGU inserted (for transition of lingu to StarOne)
+
+      Rev 1.179   26 Aug 1999 11:35:14   AMA
+   Fix #68153#: Draft mode for controls
+
+      Rev 1.178   29 Jul 1999 17:13:46   JP
+   Bug #67951#: Prt - replace all templates in dest Doc
+
+      Rev 1.177   08 Mar 1999 15:55:34   AMA
+   Fix #62873#: Vorschau von HTML-Vorlagen
+
+      Rev 1.176   02 Mar 1999 16:07:56   AMA
+   Fix #62568#: Invalidierungen so sparsam wie moeglich, so gruendlich wie noetig
+
+      Rev 1.175   22 Feb 1999 08:35:24   MA
+   1949globale Shell entsorgt, Shells am RootFrm
+
+      Rev 1.174   01 Feb 1999 19:41:16   JP
+   Bug #61335#: ReadOnlyFlag vorm Drucken uebertragen
+
+      Rev 1.173   25 Nov 1998 11:50:20   MA
+   #54599# InitPrt auch mit NULL
+
+      Rev 1.172   28 Oct 1998 14:02:36   AMA
+   Fix #58223#58219#: Seiten/Absatzformate beim Selektionsdruck beachten.
+
+      Rev 1.171   27 Jul 1998 17:35:24   AMA
+   Fix #53934#: Endlosschleife beim Speichern durch selektiertes Objekt
+
+      Rev 1.170   15 Jul 1998 14:05:38   AMA
+   Fix #53012#: Das InitPrt muss nach dem StartJob erfolgen
+
+      Rev 1.169   14 Jul 1998 10:26:28   AMA
+   Fix #52725#: Verzoegerten PrintJobStart beachten beim Formatieren
+
+      Rev 1.168   07 Jul 1998 14:38:24   AMA
+   Chg: DoPrint uebernimmt das Drucken
+
+      Rev 1.167   03 Jul 1998 17:26:24   AMA
+   Chg: DoPrint uebernimmt das Drucken
+
+      Rev 1.166   29 Jun 1998 12:05:20   AMA
+   Feat.: Notizen mit Zeilenangabe ausdrucken
+
+      Rev 1.165   23 Jun 1998 16:05:06   AMA
+   Fix #51465#: Die _virtuelle_ Seitennummer entscheidet ueber rechts/links
+
+      Rev 1.164   17 Jun 1998 22:40:22   JP
+   PostIts: GetPageNo - immer mit der virtuellen abpruefen, aber die virtuelle drucken
+
+      Rev 1.163   04 Jun 1998 18:20:42   AMA
+   Chg: UNO-Controls jetzt im eigenen Drawing-Layer
+
+      Rev 1.162   27 Apr 1998 15:09:08   MA
+   ein paar sv2vcl
+
+      Rev 1.161   24 Apr 1998 11:17:44   AMA
+   Fix #49654#49450#: Selektiondrucken: GPF bei OLE; Sprachverlust wg. Poolattr.
+
+      Rev 1.160   23 Apr 1998 09:33:36   MA
+   #49472# Optional ein Outdev durchschleusen
+
+      Rev 1.159   26 Mar 1998 17:58:52   MA
+   Wechsel fuer Drucker/Jobsetup jetzt vollstaendig und am Dokument
+
+      Rev 1.158   24 Mar 1998 18:20:02   MA
+   #39275# Jetzt will der Meyer doch ein Clipping
+
+      Rev 1.157   27 Jan 1998 22:35:36   JP
+   GetNumDepend durch GetDepends ersetzt
+
+      Rev 1.156   22 Jan 1998 20:08:58   JP
+   CTOR des SwPaM umgestellt
+
+      Rev 1.155   10 Dec 1997 17:05:34   JP
+   IsAnyField: if abfrage gerichtet
+
+      Rev 1.154   28 Nov 1997 09:11:24   MA
+   includes
+
+      Rev 1.153   20 Nov 1997 12:44:20   MA
+   includes
+
+      Rev 1.152   18 Nov 1997 13:39:50   MA
+   #45516# LongTableHack, auch Grafiken drucken
+
+      Rev 1.151   03 Nov 1997 13:07:28   MA
+   precomp entfernt
+
+      Rev 1.150   13 Oct 1997 15:54:26   JP
+   pNext vom Ring wurde privat; zugriff ueber GetNext()
+
+      Rev 1.149   13 Oct 1997 10:30:12   MA
+   Umbau/Vereinfachung Paint
+
+      Rev 1.148   09 Oct 1997 16:05:20   JP
+   Umstellung NodeIndex/-Array/BigPtrArray
+
+      Rev 1.147   10 Sep 1997 15:33:56   AMA
+   Fix #43570#: PrtFormat-Flag formatiert auch im BrowseMode fuer den Drucker
+
+      Rev 1.146   09 Sep 1997 10:53:32   MA
+   pragmas entfernt
+
+      Rev 1.145   15 Aug 1997 12:24:08   OS
+   charatr/frmatr/txtatr aufgeteilt
+
+      Rev 1.144   12 Aug 1997 13:43:16   OS
+   Header-Umstellung
+
+      Rev 1.143   07 Aug 1997 15:01:20   OM
+   Headerfile-Umstellung
+
+      Rev 1.142   18 Jun 1997 09:18:18   MA
+   #40790# VisArea fuer PrtOle und BrowseMode
+
+      Rev 1.141   06 Jun 1997 12:45:42   MA
+   chg: versteckte Absaetze ausblenden
+
+      Rev 1.140   14 Apr 1997 18:21:26   MA
+   #38806# Options auch fuer Prospect, jetzt mit eigener Methode
+
+      Rev 1.139   18 Feb 1997 16:54:12   MA
+   #36138# toleranz fuer GetSvPaper
+
+      Rev 1.138   06 Feb 1997 13:42:48   AMA
+   Fix #34400#: MinPrtLine verhindert doppelten Druck von Tabellenzellenzeilen.
+
+      Rev 1.137   28 Nov 1996 15:43:04   OS
+   neu: schwarz drucken
+
+      Rev 1.136   11 Nov 1996 09:57:56   MA
+   ResMgr
+
+      Rev 1.135   29 Oct 1996 15:40:10   JP
+   am Doc ist das NodesArray nur noch ueber Get..() zugaenglich
+
+      Rev 1.134   27 Sep 1996 13:57:02   MA
+   #29411# lange Tabellenzeilen drucken
+
+      Rev 1.133   24 Aug 1996 17:10:38   JP
+   svdraw.hxx entfernt
+
+      Rev 1.132   17 Jul 1996 10:53:04   OS
+   svdraw unter OS/2 ausserhalb der PCH
+
+      Rev 1.131   16 Jul 1996 15:52:36   MA
+   new: PrintPageBackground
+
+      Rev 1.130   11 Jul 1996 12:51:12   HJS
+   clooks
+
+      Rev 1.129   27 Jun 1996 16:24:26   MA
+   includes
+
+      Rev 1.128   24 Jun 1996 15:47:14   AMA
+   Fix #28641#: Detaillierte Ausgabe im Druckmonitor.
+
+      Rev 1.127   21 Jun 1996 17:11:22   AMA
+   Fix #28641#: Aktuelle Seitennummer beim Druck anzeigen.
+
+      Rev 1.126   20 Jun 1996 16:33:06   MA
+   JAKET-Einstellung erst nach dem SetVisArea
+
+      Rev 1.125   11 Jun 1996 19:44:40   JP
+   Bug #27584#: kein ULONG_MAX als Item verschicken -> eigene MessageId definieren
+
+      Rev 1.124   21 Mar 1996 14:06:50   MA
+   svhxx entfernt
+
+      Rev 1.123   21 Mar 1996 14:04:46   OM
+   Umstellung 311
+
+      Rev 1.122   19 Mar 1996 14:23:32   HJS
+   clooks
+
+      Rev 1.121   07 Mar 1996 16:59:20   AMA
+   New/Opt.: Progress-Anzeige beim Serienbrief
+
+      Rev 1.120   05 Mar 1996 16:57:46   AMA
+   New: SwPrtOptions fuer den Serienbriefdruck-Progress durchreichen
+
+      Rev 1.119   05 Mar 1996 15:31:16   HJS
+   clook-defs nur fuer win16
+
+      Rev 1.118   29 Feb 1996 21:40:24   HJS
+   clooks
+
+      Rev 1.117   19 Jan 1996 09:46:32   OM
+   CLOOKs entfernt
+
+      Rev 1.116   14 Dec 1995 16:58:08   WKC
+   MAC only: aText -> aStr
+
+      Rev 1.115   13 Dec 1995 17:01:08   MA
+   opt: International
+
+      Rev 1.114   05 Dec 1995 14:28:48   MA
+   fix: Repaint beim Druck fuer PreView per Invalidate/Update
+
+      Rev 1.113   28 Nov 1995 21:22:48   JP
+   UiSystem-Klasse aufgehoben, in initui/swtype aufgeteilt
+
+      Rev 1.112   24 Nov 1995 17:11:42   OM
+   PCH->PRECOMPILED
+
+      Rev 1.111   23 Nov 1995 15:41:46   MA
+   fix/opt: blc Warnings
+
+      Rev 1.110   14 Nov 1995 11:01:32   MA
+   kommentar
+
+      Rev 1.109   13 Nov 1995 12:18:44   MA
+   chg: static -> lcl_
+
+      Rev 1.108   09 Nov 1995 14:14:34   AMA
+   Fix 22084(HACK): MultiSelection jetzt mit long-Ranges
+
+      Rev 1.107   08 Nov 1995 12:18:38   AMA
+   Set statt Change (301)
+
+      Rev 1.106   03 Nov 1995 13:19:52   MA
+   chg: Draft des Drawing
+
+      Rev 1.105   01 Nov 1995 09:31:42   MA
+   opt: String
+
+      Rev 1.104   27 Oct 1995 15:06:48   MA
+   new: Demo
+
+      Rev 1.103   12 Oct 1995 12:59:24   JP
+   Bug20370: Code umgestellt
+
+      Rev 1.102   04 Sep 1995 19:13:42   JP
+   ClientIter: spz. Pointer mit First/Next geben lassen
+
+      Rev 1.101   17 Aug 1995 13:28:58   MA
+   fix: Hack fuer Print jetzt richtig
+
+      Rev 1.100   11 Aug 1995 18:53:50   MA
+   Hack: Endlosschleife beim Druck
+
+      Rev 1.99   11 Aug 1995 14:48:48   AMA
+   Fix: Kopienanzahl beim Drucken quadriert
+
+      Rev 1.98   08 Aug 1995 18:30:24   MA
+   chg: USHORT anstelle Orientation uebergeben
+
+      Rev 1.97   08 Aug 1995 14:34:44   MA
+   ChgAllxxx in die ViewShell verlagert.
+
+      Rev 1.96   27 Jul 1995 17:52:38   JP
+   neu: IsAnyFieldInDoc - stelle fest, ob im Doc Felder existieren
+
+      Rev 1.95   12 Jul 1995 14:10:16   AMA
+   Fix: Druckereinstellungen zuruecksetzen
+
+      Rev 1.94   11 Jul 1995 19:15:14   JP
+   _SetGetExpFld: fuer bedingte Bereiche erweitert
+
+      Rev 1.93   11 Jul 1995 08:54:44   AMA
+   New: SetPaper, SetPaperSizeUser am Drucker aufrufen.
+
+      Rev 1.92   06 Jul 1995 12:41:24   AMA
+   New: PrintSelection funktioniert jetzt.
+
+      Rev 1.91   05 Jul 1995 17:09:58   MA
+   new: Flag fuer Controls nicht drucken
+
+      Rev 1.90   04 Jul 1995 13:52:44   AMA
+   New: PrintSelection, noch nicht scharf geschaltet.
+
+      Rev 1.89   30 Jun 1995 16:32:54   AMA
+   FIx 14789: Vor Progress-Status auf Druck-Abbruch reagieren
+
+      Rev 1.88   26 Jun 1995 13:41:40   JP
+   PrtOle2: vorm loeschen der Shell das Stack-Object loeschen
+
+      Rev 1.87   23 Jun 1995 13:32:32   MA
+   Zeichnungen nicht drucken
+
+      Rev 1.86   07 Jun 1995 19:19:36   MA
+   Reschedules bei Progress.
+
+      Rev 1.85   10 May 1995 14:01:26   MA
+   fix: Painten waehrend des Druckens.
+
+      Rev 1.84   05 May 1995 19:36:20   AMA
+   Umbau pProgress;
+
+      Rev 1.83   04 May 1995 19:19:54   AMA
+   Fix: PrtOle2
+
+      Rev 1.82   04 May 1995 18:56:42   AMA
+   Fix: Druckenmonitor
+
+      Rev 1.81   03 May 1995 20:33:56   AMA
+   Umbau: SfxProgress etc.
+
+      Rev 1.80   28 Apr 1995 18:34:36   MA
+   FlowFrm neu, compilierbar aber nicht mehr lauffaehig.
+
+      Rev 1.79   05 Apr 1995 21:36:22   JP
+   PrtOle2: neuen Parameter - Rectangle in dem auszugeben ist
+
+      Rev 1.78   26 Feb 1995 15:04:50   JP
+   auf die richtigen Shells casten
+
+      Rev 1.77   25 Feb 1995 17:37:18   AMA
+   PrintDialog -> MultiSelection
+
+      Rev 1.76   16 Feb 1995 19:27:44   MA
+   fix: Root aber keine Shell.
+
+      Rev 1.75   16 Feb 1995 18:49:54   MA
+   chg: PrtOle2 umgestellt.
+
+*************************************************************************/
+
+
-- 
cgit v1.2.3